MockDataController.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. 
  2. using TEAMModelOS.SDK.Extension;
  3. using TEAMModelOS.SDK.Models;
  4. using System.Xml;
  5. using HTEX.Lib.ETL.Lesson;
  6. using Microsoft.AspNetCore.Mvc;
  7. using System.Text.Json;
  8. namespace HTEX.Test.Controllers
  9. {
  10. [ApiController]
  11. [Route("lesson-record")]
  12. public class MockDataController : ControllerBase
  13. {
  14. public MockDataController()
  15. {
  16. }
  17. [HttpPost("process-local")]
  18. public async Task<IActionResult> MockData(JsonElement json)
  19. {
  20. #region 数据模拟
  21. //学生人数
  22. int scount = Random.Shared.Next(40, 45);
  23. //互动次数
  24. int icount = Random.Shared.Next(21,22);
  25. //评测次数
  26. int ecount = Random.Shared.Next(1, 3);
  27. //题目个数
  28. int qcount = Random.Shared.Next(8, 15);
  29. //任务次数
  30. int tcount = Random.Shared.Next(2, 3);
  31. //评价次数
  32. int pcount = Random.Shared.Next(3, 4);
  33. //协作次数
  34. int xcount = Random.Shared.Next(2, 3);
  35. //挑人次数
  36. int kcount = Random.Shared.Next(2, 4);
  37. string type = "hd";
  38. int count = 0;
  39. switch (true)
  40. {
  41. case bool when type.Equals("hd"):
  42. count=icount;
  43. break;
  44. case bool when type.Equals("pc"):
  45. count=ecount;
  46. break;
  47. case bool when type.Equals("rw"):
  48. count=tcount;
  49. break;
  50. case bool when type.Equals("pj"):
  51. count=pcount;
  52. break;
  53. case bool when type.Equals("xz"):
  54. count=xcount;
  55. break;
  56. }
  57. List<string> s = new List<string>();
  58. for (var i = 1; i < count; i++)
  59. {
  60. var dd = await StudentLesson(scount,ecount,qcount,i,tcount,pcount,xcount,kcount);
  61. s.Add(dd.ToString());
  62. }return Ok(s);
  63. }
  64. /// <summary>
  65. ///
  66. /// </summary>
  67. /// <param name="scount"></param>
  68. /// <param name="ecount"></param>
  69. /// <param name="qcount"></param>
  70. /// <param name="icount"></param>
  71. /// <param name="tcount"></param>
  72. /// <param name="pcount"></param>
  73. /// <param name="xcount"></param>
  74. /// <param name="kcount"></param>
  75. /// <returns></returns>
  76. public async Task<string> StudentLesson(int scount, int ecount, int qcount, int icount, int tcount, int pcount, int xcount, int kcount)
  77. {
  78. List<StudentLessonData> students = new List<StudentLessonData>();
  79. //个人计分,小组计分
  80. List<WeightedItem> gpitems = new List<WeightedItem>
  81. {
  82. new WeightedItem { Value = 0, Weight = 0.1 },
  83. new WeightedItem { Value = 2, Weight = 0.2 },
  84. new WeightedItem { Value = 5, Weight = 0.2 },
  85. new WeightedItem { Value = 8, Weight = 0.02 },
  86. new WeightedItem { Value = 3, Weight = 0.2 },
  87. new WeightedItem { Value = 4, Weight = 0.2 },
  88. new WeightedItem { Value = 6, Weight = 0.04 },
  89. new WeightedItem { Value = 7, Weight = 0.04 }
  90. };
  91. //互动积分
  92. List<WeightedItem> titems = new List<WeightedItem>
  93. {
  94. new WeightedItem { Value = 0, Weight = 0.4 },
  95. new WeightedItem { Value = 25, Weight = 0.1 },
  96. new WeightedItem { Value = 15, Weight = 0.1 },
  97. new WeightedItem { Value = 10, Weight = 0.05 },
  98. new WeightedItem { Value = 30, Weight = 0.05 },
  99. new WeightedItem { Value = 20, Weight = 0.02 },
  100. new WeightedItem { Value = 40, Weight = 0.03 },
  101. new WeightedItem { Value = 50, Weight = 0.05 },
  102. new WeightedItem { Value = 5, Weight = 0.05 },
  103. new WeightedItem { Value = 35, Weight = 0.05 },
  104. new WeightedItem { Value = 45, Weight = 0.05 },
  105. new WeightedItem { Value = 55, Weight = 0.05 }
  106. };
  107. //for (var i = 0; i<100; i++)
  108. //{
  109. // int randomValue = GetRandomValueByWeight(items);
  110. // Console.WriteLine(randomValue);
  111. //}
  112. //被评价的目标索引
  113. List<List<int>> cworkDist = new List<List<int>>(xcount);
  114. //被评价目标的次数或分数
  115. // List<List<int>> cworkCount = new List<List<int>>(xcount);
  116. for (int i = 0; i < xcount; i++)
  117. {
  118. //乱序取10-20人作为评价目标
  119. var vt = Enumerable.Range(0, scount).OrderBy(x => Random.Shared.Next()).Take(Random.Shared.Next(10, 21));
  120. cworkDist.Add(vt.ToList());
  121. //var counts = new List<int>();
  122. //foreach (var v in vt)
  123. //{
  124. // counts.Add(0);
  125. //}
  126. //cworkCount.Add(counts);
  127. }
  128. //被评价的目标索引
  129. List<List<int>> rateDist = new List<List<int>>(pcount);
  130. //被评价目标的次数或分数
  131. //List<List<int>> rateCount = new List<List<int>>(pcount);
  132. List<string> types = new List<string>();
  133. for (int i = 0; i < pcount; i++)
  134. {
  135. //乱序取10-20人作为评价目标
  136. var vt = Enumerable.Range(0, scount).OrderBy(x => Random.Shared.Next()).Take(Random.Shared.Next(10, 21));
  137. rateDist.Add(vt.ToList());
  138. // var counts = new List<int>();
  139. //foreach (var v in vt)
  140. //{
  141. // counts.Add(0);
  142. //}
  143. //rateCount.Add(counts);
  144. var t = Random.Shared.Next(0, 1);
  145. switch (true)
  146. {
  147. case bool when i==0:
  148. types.Add("Voting");
  149. break;
  150. case bool when i==1:
  151. types.Add("GrandRating");
  152. break;
  153. case bool when i==2:
  154. types.Add("PeerAssessment");
  155. break;
  156. }
  157. }
  158. string[] grouppick = new string[] { "PickupNthGrp", "PickupGrp", "PickupEachGrp" };
  159. string[] pickupAll = new string[] { "PickupNameLst", "PickupOption", "PickupNthGrp", "PickupGrp",
  160. "PickupRange", "PickupEachGrp", "PickupDiff", "PickupWrong", "PickupNoDiff", "PickupRight",
  161. "PickupGener", "PickupWtoW", "PickupWtoR", "PickupLSA_WordFreq", "PickupLSA_Classify", "Pickup0_49" };
  162. for (var s = 0; s<scount; s++)
  163. {
  164. StudentLessonData student = new StudentLessonData()
  165. {
  166. index=s,
  167. seatID=$"{s+1}",
  168. id=$"2024{(s+1).ToString("D3")}",
  169. groupId=$"{Random.Shared.Next(1, 5)}",
  170. attend=1,
  171. gscore= LessonETLService.GetRandomValueByWeight(gpitems),
  172. pscore= LessonETLService.GetRandomValueByWeight(gpitems),
  173. tscore= LessonETLService.GetRandomValueByWeight(titems),
  174. };
  175. for (var p = 0; p<pcount; p++)
  176. {
  177. student.rateingRecord.itemRecords.Add(new ItemRecord());
  178. }
  179. students.Add(student);
  180. }
  181. for (var s = 0; s<scount; s++)
  182. {
  183. var student = students[s];
  184. //挑人
  185. for (var i = 0; i<kcount; i++)
  186. {
  187. var rd = Random.Shared.Next(0, 4);
  188. if (rd==1)
  189. {
  190. student.pickups.Add($"1--{grouppick[Random.Shared.Next(0, grouppick.Length)]}");
  191. }
  192. else
  193. {
  194. student.pickups.Add($"0--{pickupAll[Random.Shared.Next(0, pickupAll.Length)]}");
  195. }
  196. }
  197. //互动
  198. for (var i = 0; i<icount; i++)
  199. {
  200. int criterion = 10;
  201. var item = new ItemRecord { criterion=criterion };
  202. var w = Random.Shared.Next(0, 4);
  203. switch (true)
  204. {
  205. //未参与
  206. case bool when w==0:
  207. item.resultWeight= InteractWeight.T0;
  208. item.resultType= InteractReultType.T0;
  209. item.itemScore=0;
  210. break;
  211. //参与了
  212. case bool when w==1:
  213. item.resultWeight= InteractWeight.T1;
  214. item.resultType= InteractReultType.T1;
  215. item.itemScore=0;
  216. break;
  217. //部分正确
  218. case bool when w==2:
  219. var score = Random.Shared.Next(1, criterion);
  220. item.resultWeight= LessonETLService.MinMaxNormalization(1, criterion, score, InteractWeight.T1, InteractWeight.TT);
  221. item.resultType= InteractReultType.TP;
  222. item.itemScore=0;
  223. break;
  224. //完全正确
  225. case bool when w==3:
  226. item.resultWeight= InteractWeight.TT;
  227. item.resultType= InteractReultType.TT;
  228. item.itemScore=criterion;
  229. break;
  230. }
  231. student.interactRecord.interactRecords.Add(item);
  232. }
  233. //任务
  234. for (var t = 0; t<tcount; t++)
  235. {
  236. var w = Random.Shared.Next(0, 5);
  237. var item = new ItemRecord { };
  238. switch (true)
  239. {
  240. //未参与
  241. case bool when w==0:
  242. item.resultWeight= InteractWeight.T0;
  243. item.resultType= InteractReultType.T0;
  244. item.itemScore=0;
  245. item.optCount=0;
  246. break;
  247. //参加
  248. case bool when w==1:
  249. item.resultWeight= InteractWeight.TT;
  250. item.resultType= InteractReultType.TT;
  251. item.optCount= Random.Shared.Next(1, 4);
  252. item.itemScore=item.optCount*10;
  253. item.isGroup= Random.Shared.Next(0, 4)!=1;
  254. break;
  255. }
  256. student.taskRecord.taskRate= student.taskRecord.itemRecords.Where(x => x.resultWeight>0).Count()*1.0/tcount;
  257. student.taskRecord.itemRecords.Add(item);
  258. }
  259. //评价
  260. for (var p = 0; p<pcount; p++)
  261. {
  262. var item = student.rateingRecord.itemRecords[p];
  263. var subtype = string.Empty;
  264. item.itemType=types[p];
  265. if (types[p].Equals("PeerAssessment"))
  266. {
  267. var sub = Random.Shared.Next(0, 3);
  268. subtype= sub==0 ? "ALL" : sub==1 ? "Two" : "Self";
  269. }
  270. var w = Random.Shared.Next(0, 3);
  271. switch (true)
  272. {
  273. //未参与
  274. case bool when w==0:
  275. item.resultWeight= InteractWeight.T0;
  276. item.resultType= InteractReultType.T0;
  277. item.itemScore=0;
  278. break;
  279. //参与
  280. case bool when w==1||w==2:
  281. item.resultWeight= InteractWeight.T1;
  282. item.resultType= InteractReultType.T1;
  283. if (item.itemType!.Equals("Voting"))
  284. {
  285. var index = Random.Shared.Next(0, rateDist[p].Count);
  286. //rateCount[p][index]+=1;
  287. students[rateDist[p][index]].rateingRecord.itemRecords[p].itemScore+=1;
  288. }
  289. else
  290. {
  291. if (item.itemType.Equals("PeerAssessment"))
  292. {
  293. var index = Random.Shared.Next(0, rateDist[p].Count);
  294. //操作次数
  295. int opt_count = Random.Shared.Next(1, 2);
  296. for (var count = 0; count<opt_count; count++)
  297. {
  298. var score = Random.Shared.Next(3, 10);
  299. // rateCount[p][index]+=score;
  300. students[rateDist[p][index]].rateingRecord.itemRecords[p].itemScore+=score;
  301. item.optCount+= 1;
  302. }
  303. }
  304. else
  305. {
  306. var index = Random.Shared.Next(0, rateDist[p].Count);
  307. var score = Random.Shared.Next(3, 10);
  308. // rateCount[p][index]+=score;
  309. students[rateDist[p][index]].rateingRecord.itemRecords[p].itemScore+=score;
  310. }
  311. }
  312. break;
  313. }
  314. // student.rateingRecord.itemRecords.Add(item);
  315. }
  316. //个人协作
  317. {
  318. for (var x = 0; x<xcount; x++)
  319. {
  320. int[] r = new int[] { 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1 };
  321. var w = r[Random.Shared.Next(0, r.Length)];
  322. var item = new ItemRecord { };
  323. switch (true)
  324. {
  325. //未参与
  326. case bool when w==0:
  327. item.resultWeight= InteractWeight.T0;
  328. item.resultType= InteractReultType.T0;
  329. item.itemScore=0;
  330. break;
  331. //
  332. case bool when w==1:
  333. item.resultWeight= InteractWeight.TP;
  334. item.resultType= InteractReultType.TP;
  335. int[] q = new int[] { 10, 5, 5, 20, 30, 10, 25, 70, 75, 15, 30, 75, 10, 20, 15, 25, 70, 5, 75, 20, 20, 25, 5, 5 };
  336. item.itemScore=q[Random.Shared.Next(0, q.Count())];
  337. break;
  338. }
  339. student.coworkRecord.itemRecords.Add(item);
  340. }
  341. }
  342. //小组协作
  343. {
  344. int[] r = new int[] { 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1 };
  345. var w = r[Random.Shared.Next(0, r.Length)];
  346. var item = new ItemRecord { };
  347. double grpcoworkScore = 0;
  348. switch (true)
  349. {
  350. //未参与
  351. case bool when w==0:
  352. break;
  353. //
  354. case bool when w==1:
  355. int[] q = new int[] { 10, 5, 5, 20, 30, 70, 25, 10, 15,75, 30, 75, 10, 20, 75, 25, 10, 5, 75, 20, 20, 25, 5, 5 };
  356. grpcoworkScore= q[Random.Shared.Next(0, q.Count())]* Random.Shared.Next(2, 4);
  357. student.group_coworkScore.Add(grpcoworkScore);
  358. break;
  359. }
  360. }
  361. //评测
  362. for (var e = 0; e<ecount; e++)
  363. {
  364. StudentExamRecord examRecord = new();
  365. double allocation = 0;
  366. for (var q = 0; q<qcount; q++)
  367. {
  368. var criterion = Random.Shared.Next(5, 10);
  369. allocation+=criterion;
  370. var item = new ItemRecord { criterion =criterion };
  371. var w = Random.Shared.Next(0, 4);
  372. switch (true)
  373. {
  374. //未作答
  375. case bool when w==0:
  376. item.resultWeight= InteractWeight.T0;
  377. item.resultType= InteractReultType.T0;
  378. item.itemScore=0;
  379. break;
  380. //作答错误
  381. case bool when w==1:
  382. item.resultWeight= InteractWeight.T1;
  383. item.resultType= InteractReultType.T1;
  384. item.itemScore=0;
  385. break;
  386. //部分正确
  387. case bool when w==2:
  388. var score = Random.Shared.Next(1, criterion);
  389. item.resultWeight= LessonETLService.MinMaxNormalization(1, criterion, score, InteractWeight.T1, InteractWeight.TT); // score * 1.0 / criterion* (InteractWeight.TT-InteractWeight.T1);
  390. item.resultType= InteractReultType.TP;
  391. item.itemScore=score;
  392. break;
  393. //完全正确
  394. case bool when w==3:
  395. item.resultWeight= InteractWeight.TT;
  396. item.resultType= InteractReultType.TT;
  397. item.itemScore=criterion;
  398. break;
  399. }
  400. examRecord.itemRecords.Add(item);
  401. }
  402. examRecord.qcount=qcount;
  403. examRecord.workCount= examRecord.itemRecords.Where(x => x.resultWeight>0).Count();
  404. examRecord.allocation=allocation;
  405. examRecord.score= examRecord.itemRecords.Where(x => x.itemScore>=0).Select(x => x.itemScore).Sum();//得分
  406. examRecord.scoreRate = Math.Round(examRecord.score * 1.0 / allocation, 4);//得分率
  407. examRecord.answerRate= Math.Round(examRecord.itemRecords.Where(x => x.resultWeight>0).Count()*1.0/qcount, 4);//作答率
  408. student.examRecords.Add(examRecord);
  409. }
  410. }
  411. for (var p = 0; p<pcount; p++)
  412. {
  413. var order = students.OrderByDescending(x => x.rateingRecord.itemRecords[p].itemScore);
  414. var maxItems = students.FindAll(x => x.rateingRecord.itemRecords[p].itemScore==order.First().rateingRecord.itemRecords[p].itemScore);
  415. var max = students.FindAll(x => x.rateingRecord.itemRecords[p].itemScore==order.First().rateingRecord.itemRecords[p].itemScore).First().rateingRecord.itemRecords[p].itemScore;
  416. var min = students.FindAll(x => x.rateingRecord.itemRecords[p].itemScore==order.Last().rateingRecord.itemRecords[p].itemScore).First().rateingRecord.itemRecords[p].itemScore;
  417. var sum = students.Sum(x => x.rateingRecord.itemRecords[p].itemScore);
  418. foreach (var student in students)
  419. {
  420. if (student.rateingRecord.itemRecords[p].itemScore>0 && student.rateingRecord.itemRecords[p].optCount>0)
  421. {
  422. student.rateingRecord.itemRecords[p].resultType=InteractReultType.TP;
  423. var data = LessonETLService.MinMaxNormalization(min, max, student.rateingRecord.itemRecords[p].itemScore);
  424. student.rateingRecord.itemRecords[p].resultWeight=Math.Round(InteractWeight.T1+ data * 1.0 / 100 * (InteractWeight.TT-InteractWeight.T1), 4);
  425. if (maxItems.Select(x => x.seatID).Contains(student.seatID))
  426. {
  427. student.rateingRecord.itemRecords[p].resultType= InteractReultType.TT;
  428. student.rateingRecord.itemRecords[p].resultWeight= InteractWeight.TT;
  429. }
  430. }
  431. }
  432. }
  433. //个人协作
  434. for (var p = 0; p<xcount; p++)
  435. {
  436. var order = students.OrderByDescending(x => x.coworkRecord.itemRecords[p].itemScore);
  437. var maxItems = students.FindAll(x => x.coworkRecord.itemRecords[p].itemScore==order.First().coworkRecord.itemRecords[p].itemScore);
  438. var max = students.FindAll(x => x.coworkRecord.itemRecords[p].itemScore==order.First().coworkRecord.itemRecords[p].itemScore).First().coworkRecord.itemRecords[p].itemScore;
  439. var min = students.FindAll(x => x.coworkRecord.itemRecords[p].itemScore==order.Last().coworkRecord.itemRecords[p].itemScore).First().coworkRecord.itemRecords[p].itemScore;
  440. var sum = students.Sum(x => x.coworkRecord.itemRecords[p].itemScore);
  441. foreach (var student in students)
  442. {
  443. if (student.coworkRecord.itemRecords[p].itemScore>0)
  444. {
  445. student.coworkRecord.itemRecords[p].resultType=InteractReultType.TP;
  446. var data = LessonETLService.MinMaxNormalization(min, max, student.coworkRecord.itemRecords[p].itemScore);
  447. student.coworkRecord.itemRecords[p].resultWeight=Math.Round(InteractWeight.T1+ data * 1.0 / 100 * (InteractWeight.TT-InteractWeight.T1), 4);
  448. if (maxItems.Select(x => x.seatID).Contains(student.seatID))
  449. {
  450. student.coworkRecord.itemRecords[p].resultType= InteractReultType.TT;
  451. student.coworkRecord.itemRecords[p].resultWeight= InteractWeight.TT;
  452. }
  453. }
  454. }
  455. }
  456. #endregion 数据模拟
  457. string jsons = await System.IO.File.ReadAllTextAsync("F:\\lesson-local\\analysis\\analysis-model.json");
  458. long time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  459. LessonDataAnalysisModel lessonDataAnalysis = jsons.ToObject<LessonDataAnalysisModel>();
  460. var codeBools = LessonETLService.GetCodeBools(students);
  461. var studentLessons = LessonETLService.ProcessStudentDataV2(students, lessonDataAnalysis, codeBools);
  462. var excleFile = $"F:\\mock-data\\{time}.xlsx";
  463. var runtimePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
  464. XmlDocument xmlDocument = new XmlDocument();
  465. xmlDocument.Load($"{runtimePath}\\summary.xml");
  466. List<string> noStujson = new List<string>();
  467. await LessonETLService.ExportToExcelLocal(studentLessons, excleFile, xmlDocument);
  468. await System.IO.File.WriteAllTextAsync($"F:\\mock-data\\{time}.json", new { scount, ecount, qcount, icount, tcount, pcount, xcount, students }.ToJsonString());
  469. return $"{time}";
  470. }
  471. //return Ok(new { scount, ecount, qcount, icount, tcount, pcount, xcount, students });
  472. }
  473. }