MockDataController.cs 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. using Microsoft.AspNetCore.Mvc;
  2. using System.Text.Json;
  3. using static HTEX.Test.Controllers.LessonRecordController;
  4. using TEAMModelOS.SDK.Extension;
  5. using TEAMModelOS.SDK.Models;
  6. using System;
  7. namespace HTEX.Test.Controllers
  8. {
  9. [ApiController]
  10. [Route("mock-data")]
  11. public class MockDataController : ControllerBase
  12. {
  13. private readonly ILogger<MockDataController> _logger;
  14. public MockDataController(ILogger<MockDataController> logger)
  15. {
  16. _logger = logger;
  17. }
  18. [HttpPost("student-lesson")]
  19. public async Task<IActionResult> StudentLesson(JsonElement json)
  20. {
  21. #region 数据模拟
  22. //学生人数
  23. int scount = Random.Shared.Next(40, 45);
  24. //评测次数
  25. int ecount = Random.Shared.Next(1, 3);
  26. //题目个数
  27. int qcount = Random.Shared.Next(8, 15);
  28. //互动次数
  29. int icount = Random.Shared.Next(3, 20);
  30. //任务次数
  31. int tcount = Random.Shared.Next(1, 4);
  32. //评价次数
  33. int pcount = Random.Shared.Next(2, 4);
  34. //协作次数
  35. int xcount = Random.Shared.Next(3, 4);
  36. List<StudentLessonData> students = new List<StudentLessonData>();
  37. //个人计分,小组计分
  38. List<WeightedItem> gpitems = new List<WeightedItem>
  39. {
  40. new WeightedItem { Value = 0, Weight = 0.3 },
  41. new WeightedItem { Value = 2, Weight = 0.1 },
  42. new WeightedItem { Value = 5, Weight = 0.2 },
  43. new WeightedItem { Value = 8, Weight = 0.1 },
  44. new WeightedItem { Value = 3, Weight = 0.05 },
  45. new WeightedItem { Value = 4, Weight = 0.02 },
  46. new WeightedItem { Value = 6, Weight = 0.03 },
  47. new WeightedItem { Value = 7, Weight = 0.2 }
  48. };
  49. //个人计分,小组计分
  50. List<WeightedItem> titems = new List<WeightedItem>
  51. {
  52. new WeightedItem { Value = 0, Weight = 0.4 },
  53. new WeightedItem { Value = 25, Weight = 0.1 },
  54. new WeightedItem { Value = 15, Weight = 0.1 },
  55. new WeightedItem { Value = 10, Weight = 0.05 },
  56. new WeightedItem { Value = 30, Weight = 0.05 },
  57. new WeightedItem { Value = 20, Weight = 0.02 },
  58. new WeightedItem { Value = 40, Weight = 0.03 },
  59. new WeightedItem { Value = 50, Weight = 0.05 },
  60. new WeightedItem { Value = 5, Weight = 0.05 },
  61. new WeightedItem { Value = 35, Weight = 0.05 },
  62. new WeightedItem { Value = 45, Weight = 0.05 },
  63. new WeightedItem { Value = 55, Weight = 0.05 }
  64. };
  65. //for (var i = 0; i<100; i++)
  66. //{
  67. // int randomValue = GetRandomValueByWeight(items);
  68. // Console.WriteLine(randomValue);
  69. //}
  70. //被评价的目标索引
  71. List<List<int>> cworkDist = new List<List<int>>(xcount);
  72. //被评价目标的次数或分数
  73. // List<List<int>> cworkCount = new List<List<int>>(xcount);
  74. for (int i = 0; i < xcount; i++)
  75. {
  76. //乱序取10-20人作为评价目标
  77. var vt = Enumerable.Range(0, scount).OrderBy(x => Random.Shared.Next()).Take(Random.Shared.Next(10, 21));
  78. cworkDist.Add(vt.ToList());
  79. //var counts = new List<int>();
  80. //foreach (var v in vt)
  81. //{
  82. // counts.Add(0);
  83. //}
  84. //cworkCount.Add(counts);
  85. }
  86. //被评价的目标索引
  87. List<List<int>> rateDist = new List<List<int>>(pcount);
  88. //被评价目标的次数或分数
  89. //List<List<int>> rateCount = new List<List<int>>(pcount);
  90. List<string> types = new List<string>();
  91. for (int i = 0; i < pcount; i++)
  92. {
  93. //乱序取10-20人作为评价目标
  94. var vt = Enumerable.Range(0, scount).OrderBy(x => Random.Shared.Next()).Take(Random.Shared.Next(10, 21));
  95. rateDist.Add(vt.ToList());
  96. // var counts = new List<int>();
  97. //foreach (var v in vt)
  98. //{
  99. // counts.Add(0);
  100. //}
  101. //rateCount.Add(counts);
  102. var t = Random.Shared.Next(0, 1);
  103. switch (true)
  104. {
  105. case bool when i==0:
  106. types.Add("Voting");
  107. break;
  108. case bool when i==1:
  109. types.Add("GrandRating");
  110. break;
  111. case bool when i==2:
  112. types.Add("PeerAssessment");
  113. break;
  114. }
  115. }
  116. for (var s = 0; s<scount; s++)
  117. {
  118. StudentLessonData student = new StudentLessonData()
  119. {
  120. index=s,
  121. seatID=$"{s+1}",
  122. id=$"2024{(s+1).ToString("D3")}",
  123. groupId=$"{Random.Shared.Next(1, 5)}",
  124. attend=1,
  125. gscore= GetRandomValueByWeight(gpitems),
  126. pscore= GetRandomValueByWeight(gpitems),
  127. tscore= GetRandomValueByWeight(titems),
  128. };
  129. for (var p = 0; p<pcount; p++)
  130. {
  131. student.rateingRecord.itemRecords.Add(new ItemRecord());
  132. }
  133. students.Add(student);
  134. }
  135. for (var s = 0; s<scount; s++)
  136. {
  137. var student = students[s];
  138. //互动
  139. for (var i = 0; i<icount; i++)
  140. {
  141. int criterion = 10;
  142. var item = new ItemRecord { criterion=criterion };
  143. var w = Random.Shared.Next(0, 4);
  144. switch (true)
  145. {
  146. //未参与
  147. case bool when w==0:
  148. item.resultWeight= InteractWeight.T0;
  149. item.resultType= InteractReultType.T0;
  150. item.itemScore=0;
  151. break;
  152. //参与了
  153. case bool when w==1:
  154. item.resultWeight= InteractWeight.T1;
  155. item.resultType= InteractReultType.T1;
  156. item.itemScore=0;
  157. break;
  158. //部分正确
  159. case bool when w==2:
  160. var score = Random.Shared.Next(1, criterion);
  161. item.resultWeight= MinMaxNormalization(1, criterion, score, InteractWeight.T1, InteractWeight.TT);
  162. item.resultType= InteractReultType.TP;
  163. item.itemScore=0;
  164. break;
  165. //完全正确
  166. case bool when w==3:
  167. item.resultWeight= InteractWeight.TT;
  168. item.resultType= InteractReultType.TT;
  169. item.itemScore=criterion;
  170. break;
  171. }
  172. student.interactRecord.interactRecords.Add(item);
  173. }
  174. //任务
  175. for (var t = 0; t<tcount; t++)
  176. {
  177. var w = Random.Shared.Next(0, 2);
  178. var item = new ItemRecord { };
  179. switch (true)
  180. {
  181. //未参与
  182. case bool when w==0:
  183. item.resultWeight= InteractWeight.T0;
  184. item.resultType= InteractReultType.T0;
  185. item.itemScore=0;
  186. break;
  187. //参加
  188. case bool when w==1:
  189. item.resultWeight= InteractWeight.TT;
  190. item.resultType= InteractReultType.TT;
  191. item.itemScore=10;
  192. break;
  193. }
  194. student.taskRecord.taskRate= student.taskRecord.itemRecords.Where(x => x.resultWeight>0).Count()*1.0/tcount;
  195. student.taskRecord.itemRecords.Add(item);
  196. }
  197. //评价
  198. for (var p = 0; p<pcount; p++)
  199. {
  200. var item = student.rateingRecord.itemRecords[p];
  201. var subtype = string.Empty;
  202. item.itemType=types[p];
  203. if (types[p].Equals("PeerAssessment"))
  204. {
  205. var sub = Random.Shared.Next(0, 3);
  206. subtype= sub==0 ? "ALL" : sub==1 ? "Two" : "Self";
  207. }
  208. var w = Random.Shared.Next(0, 3);
  209. switch (true)
  210. {
  211. //未参与
  212. case bool when w==0:
  213. item.resultWeight= InteractWeight.T0;
  214. item.resultType= InteractReultType.T0;
  215. item.itemScore=0;
  216. break;
  217. //参与
  218. case bool when w==1||w==2:
  219. item.resultWeight= InteractWeight.T1;
  220. item.resultType= InteractReultType.T1;
  221. if (item.itemType!.Equals("Voting"))
  222. {
  223. var index = Random.Shared.Next(0, rateDist[p].Count);
  224. //rateCount[p][index]+=1;
  225. students[rateDist[p][index]].rateingRecord.itemRecords[p].itemScore+=1;
  226. }
  227. else
  228. {
  229. if (item.itemType.Equals("PeerAssessment"))
  230. {
  231. var index = Random.Shared.Next(0, rateDist[p].Count);
  232. //操作次数
  233. int opt_count = Random.Shared.Next(1, 2);
  234. for (var count = 0; count<opt_count; count++)
  235. {
  236. var score = Random.Shared.Next(3, 10);
  237. // rateCount[p][index]+=score;
  238. students[rateDist[p][index]].rateingRecord.itemRecords[p].itemScore+=score;
  239. item.optCount+= 1;
  240. }
  241. }
  242. else
  243. {
  244. var index = Random.Shared.Next(0, rateDist[p].Count);
  245. var score = Random.Shared.Next(3, 10);
  246. // rateCount[p][index]+=score;
  247. students[rateDist[p][index]].rateingRecord.itemRecords[p].itemScore+=score;
  248. }
  249. }
  250. break;
  251. }
  252. // student.rateingRecord.itemRecords.Add(item);
  253. }
  254. //协作
  255. for (var x = 0; x<xcount; x++)
  256. {
  257. int[] r = new int[] { 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1 };
  258. var w = r[Random.Shared.Next(0, r.Length)];
  259. var item = new ItemRecord { };
  260. switch (true)
  261. {
  262. //未参与
  263. case bool when w==0:
  264. item.resultWeight= InteractWeight.T0;
  265. item.resultType= InteractReultType.T0;
  266. item.itemScore=0;
  267. break;
  268. //
  269. case bool when w==1:
  270. item.resultWeight= InteractWeight.TP;
  271. item.resultType= InteractReultType.TP;
  272. int[] q = new int[] { 10, 5, 5, 20, 30, 10, 25, 10, 15, 15, 30, 5, 10, 20, 15, 25, 10, 5, 15, 20, 20, 25, 5, 5 };
  273. item.itemScore=q[Random.Shared.Next(0, q.Count())];
  274. break;
  275. }
  276. student.coworkRecord.itemRecords.Add(item);
  277. }
  278. //评测
  279. for (var e = 0; e<ecount; e++)
  280. {
  281. StudentExamRecord examRecord = new();
  282. double allocation = 0;
  283. for (var q = 0; q<qcount; q++)
  284. {
  285. var criterion = Random.Shared.Next(5, 10);
  286. allocation+=criterion;
  287. var item = new ItemRecord { criterion =criterion };
  288. var w = Random.Shared.Next(0, 4);
  289. switch (true)
  290. {
  291. //未作答
  292. case bool when w==0:
  293. item.resultWeight= InteractWeight.T0;
  294. item.resultType= InteractReultType.T0;
  295. item.itemScore=0;
  296. break;
  297. //作答错误
  298. case bool when w==1:
  299. item.resultWeight= InteractWeight.T1;
  300. item.resultType= InteractReultType.T1;
  301. item.itemScore=0;
  302. break;
  303. //部分正确
  304. case bool when w==2:
  305. var score = Random.Shared.Next(1, criterion);
  306. item.resultWeight= MinMaxNormalization(1, criterion, score, InteractWeight.T1, InteractWeight.TT); // score * 1.0 / criterion* (InteractWeight.TT-InteractWeight.T1);
  307. item.resultType= InteractReultType.TP;
  308. item.itemScore=score;
  309. break;
  310. //完全正确
  311. case bool when w==3:
  312. item.resultWeight= InteractWeight.TT;
  313. item.resultType= InteractReultType.TT;
  314. item.itemScore=criterion;
  315. break;
  316. }
  317. examRecord.itemRecords.Add(item);
  318. }
  319. examRecord.qcount=qcount;
  320. examRecord.workCount= examRecord.itemRecords.Where(x => x.resultWeight>0).Count();
  321. examRecord.allocation=allocation;
  322. examRecord.score= examRecord.itemRecords.Where(x => x.itemScore>=0).Select(x => x.itemScore).Sum();//得分
  323. examRecord.scoreRate = Math.Round(examRecord.score * 1.0 / allocation, 4);//得分率
  324. examRecord.answerRate= Math.Round(examRecord.itemRecords.Where(x => x.resultWeight>0).Count()*1.0/qcount, 4);//作答率
  325. student.examRecords.Add(examRecord);
  326. }
  327. }
  328. for (var p = 0; p<pcount; p++)
  329. {
  330. var order = students.OrderByDescending(x => x.rateingRecord.itemRecords[p].itemScore);
  331. var maxItems = students.FindAll(x => x.rateingRecord.itemRecords[p].itemScore==order.First().rateingRecord.itemRecords[p].itemScore);
  332. var max = students.FindAll(x => x.rateingRecord.itemRecords[p].itemScore==order.First().rateingRecord.itemRecords[p].itemScore).First().rateingRecord.itemRecords[p].itemScore;
  333. var min = students.FindAll(x => x.rateingRecord.itemRecords[p].itemScore==order.Last().rateingRecord.itemRecords[p].itemScore).First().rateingRecord.itemRecords[p].itemScore;
  334. var sum = students.Sum(x => x.rateingRecord.itemRecords[p].itemScore);
  335. foreach (var student in students)
  336. {
  337. if (student.rateingRecord.itemRecords[p].itemScore>0 && student.rateingRecord.itemRecords[p].optCount>0)
  338. {
  339. student.rateingRecord.itemRecords[p].resultType=InteractReultType.TP;
  340. var data = MinMaxNormalization(min, max, student.rateingRecord.itemRecords[p].itemScore);
  341. student.rateingRecord.itemRecords[p].resultWeight=Math.Round(InteractWeight.T1+ data * 1.0 / 100 * (InteractWeight.TT-InteractWeight.T1), 4);
  342. if (maxItems.Select(x => x.seatID).Contains(student.seatID))
  343. {
  344. student.rateingRecord.itemRecords[p].resultType= InteractReultType.TT;
  345. student.rateingRecord.itemRecords[p].resultWeight= InteractWeight.TT;
  346. }
  347. }
  348. }
  349. }
  350. for (var p = 0; p<xcount; p++)
  351. {
  352. var order = students.OrderByDescending(x => x.coworkRecord.itemRecords[p].itemScore);
  353. var maxItems = students.FindAll(x => x.coworkRecord.itemRecords[p].itemScore==order.First().coworkRecord.itemRecords[p].itemScore);
  354. var max = students.FindAll(x => x.coworkRecord.itemRecords[p].itemScore==order.First().coworkRecord.itemRecords[p].itemScore).First().coworkRecord.itemRecords[p].itemScore;
  355. var min = students.FindAll(x => x.coworkRecord.itemRecords[p].itemScore==order.Last().coworkRecord.itemRecords[p].itemScore).First().coworkRecord.itemRecords[p].itemScore;
  356. var sum = students.Sum(x => x.coworkRecord.itemRecords[p].itemScore);
  357. foreach (var student in students)
  358. {
  359. if (student.coworkRecord.itemRecords[p].itemScore>0)
  360. {
  361. student.coworkRecord.itemRecords[p].resultType=InteractReultType.TP;
  362. var data = MinMaxNormalization(min, max, student.coworkRecord.itemRecords[p].itemScore);
  363. student.coworkRecord.itemRecords[p].resultWeight=Math.Round(InteractWeight.T1+ data * 1.0 / 100 * (InteractWeight.TT-InteractWeight.T1), 4);
  364. if (maxItems.Select(x => x.seatID).Contains(student.seatID))
  365. {
  366. student.coworkRecord.itemRecords[p].resultType= InteractReultType.TT;
  367. student.coworkRecord.itemRecords[p].resultWeight= InteractWeight.TT;
  368. }
  369. }
  370. }
  371. }
  372. #endregion 数据模拟
  373. string jsons = await System.IO.File.ReadAllTextAsync("F:\\lesson-local\\analysis.json");
  374. LessonDataAnalysis lessonDataAnalysis = jsons.ToObject<LessonDataAnalysis>();
  375. ProcessStudentData(students, lessonDataAnalysis, scount, ecount, qcount, icount, tcount, pcount, xcount);
  376. try {
  377. await System.IO.File.WriteAllTextAsync($"F:\\mock-data\\{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}.json", new { scount, ecount, qcount, icount, tcount, pcount, xcount, students }.ToJsonString());
  378. } catch (Exception ex) {
  379. Console.WriteLine(scount);
  380. }
  381. return Ok(new { scount, ecount, qcount, icount, tcount, pcount, xcount, students });
  382. }
  383. private void ProcessStudentData(List<StudentLessonData> studentLessonDatas, LessonDataAnalysis lessonDataAnalysis, int scount, int ecount, int qcount, int icount, int tcount, int pcount, int xcount)
  384. {
  385. //历史记录的个人计分集合,通过“2倍标准差规则”移除异常值后得到的集合
  386. var max_q = lessonDataAnalysis.pscore.Max();
  387. //历史记录的互动计分集合,通过“2倍标准差规则”移除异常值后得到的集合
  388. var max_t = lessonDataAnalysis.tscore.Max();
  389. //历史记录的小组计分集合,通过“2倍标准差规则”移除异常值后得到的集合
  390. var max_h = lessonDataAnalysis.gscore.Max();
  391. var j = InteractWeight.T1;
  392. double t = InteractWeight.TT;
  393. List<StudentLessonItem> lessonItems= new List<StudentLessonItem>();
  394. foreach (var studentLessonData in studentLessonDatas)
  395. {
  396. StudentLessonItem lessonItem = new StudentLessonItem() { studentId= studentLessonData.id! };
  397. double u = 0.0;
  398. if (studentLessonData.attend==1)
  399. {
  400. u=100.0;
  401. }
  402. //c个人计分指数,d互动计分指数,e小组计分指数
  403. double c = 0, d = 0, e = 0;
  404. ////互动
  405. //double hd_cx = 0;//互动成效指数
  406. //double hd_cy = 0;//互动参与指数
  407. //double hd_fqc = 0;//互动发起次数
  408. //double hd_cyc = 0;//互动参与次数
  409. //double hd_zqc = 0;//互动正确次数
  410. //double gr_jf = 0;//个人计分
  411. ////评测
  412. //double pc_df = 0;//评测得分率
  413. //double pc_zd = 0;//评测作答率
  414. ////任务
  415. //double rw_fqc = 0;//任务发起次数
  416. //double rw_cyc = 0;//任务参与次数
  417. //double rw_cx = 0;//任务成效指数
  418. //double rw_cy = 0;//任务参与指数
  419. ////评价
  420. //double pj_nl = 0;//评价能力
  421. //double pj_cs = 0;//评价发起次数
  422. //double pj_vc = 0;//评价-投票发起次数
  423. //double pj_vg = 0;//投票得票数
  424. //double pj_vo = 0;//投票次数
  425. //double pj_gc = 0;//评价-星光发起次数
  426. //double pj_gg = 0;//星光得分数
  427. //double pj_go = 0;//星光评分次数
  428. //double pj_pc = 0;//评价-互评发起次数
  429. //double pj_pg = 0;//互评的分数
  430. //double pj_po = 0;//互评评分次数
  431. ////协作
  432. //double xz_fqc = 0;//协作发起次数
  433. //double xz_cyc = 0;//协作参与次数
  434. //double xz_cgf = 0;//协作成果分数
  435. //double xz_cx = 0;//协作能力指数
  436. //double xz_cy = 0;//协作参与指数
  437. {
  438. //互动相关的计分
  439. //课例互动次数
  440. double n = studentLessonData.interactRecord.interactRecords.Count()*1.0;
  441. //是IES大陆正式站历史课例数据,自2024-03-01至2024-10-08日,互动指数或学法指数黄灯或绿灯,不包含醍摩豆学校及测试学校,课例时长超过5分钟的有效课例(10,680笔数据) 的IRS互动+抢权+挑人的次数集合,
  442. //通过“2倍标准差规则” 移除异常值后得到的集合,再通过K-Means聚类算法得到高低位阶互动频次两个集合,并根据当前课例互动次数位阶的集合的质心值,该值定为m值
  443. var m = n<=lessonDataAnalysis.clustersInteract.First().Value.Max() ? lessonDataAnalysis.clustersInteract.First().Key*1.0 : lessonDataAnalysis.clustersInteract.Last().Key *1.0;
  444. //学生作答次数
  445. var w = studentLessonData.interactRecord.interactRecords.Where(x => x.resultWeight>=InteractWeight.T1).Count()*1.0;
  446. //作答正确数(包括部分正确)
  447. var r = studentLessonData.interactRecord.interactRecords.Where(x => x.resultWeight>InteractWeight.T1).Count()*1.0;
  448. //有参与的权重集合60≤k(x)≤100
  449. var kw = studentLessonData.interactRecord.interactRecords.Where(x => x.resultWeight>=InteractWeight.T1).Sum(x => x.resultWeight*1.0);
  450. //有得分的权重集合60<e(x)≤100
  451. var er = studentLessonData.interactRecord.interactRecords.Where(x => x.resultWeight>InteractWeight.T1).Sum(x => x.resultWeight*1.0);
  452. //本节课的所有互动计分
  453. var i = studentLessonData.interactRecord.interactRecords.Sum(x => x.itemScore*1.0);
  454. //本节课教师手动给学生的个人计分
  455. var s = studentLessonData.pscore;
  456. //个人计分指数
  457. c = s*1.0/max_q;
  458. //互动计分指数
  459. d = i*1.0/max_t;
  460. //互动成效指数
  461. var a = (d+w*kw/(j*m)+r*er/(j*m))*1.0/n;
  462. //互动参与指数
  463. var b = ((w*w)/m+(r*r)/m)*1.0/n;
  464. //c+a= 个人计分指数+ 个人互动成效指数
  465. //学习成效
  466. var f1 = Math.Round(190*1.0/(1+Math.Exp(-(c+a)))-95, 4);
  467. lessonItem.hd_cx=f1;
  468. var f2 = Math.Round(200*1.0/(1+Math.Exp(-(b+u/100)))-100, 4);
  469. lessonItem.hd_cy=f2;
  470. lessonItem.hd_cyc=w;
  471. lessonItem.hd_fqc=n;
  472. lessonItem.hd_zqc=r;
  473. lessonItem.gr_jf=s;
  474. //studentLessonData.achieve=f1;
  475. //studentLessonData.attitude=f2;
  476. // _logger.LogInformation($"{studentLessonData.id}=>学习成效:{f1}\t学习态度:{f2}\t互动次数:{n}\t参与次数:{w}\t正确次数:{r}\t个人计分:{s}\t{Math.Round(c, 2)}\t互动计分:{i}\t{Math.Round(d, 2)}");
  477. }
  478. {
  479. //评测相关指数
  480. double n = studentLessonData.examRecords.Count()*1.0;
  481. //题目数量
  482. double nq = studentLessonData.examRecords.Sum(x => x.qcount)*1.0;
  483. double max_e = lessonDataAnalysis.exam.Max();
  484. //得分率
  485. double sum_s = studentLessonData.examRecords.Sum(x => x.scoreRate);
  486. //作答率
  487. double sum_a = studentLessonData.examRecords.Sum(x => x.answerRate);
  488. double f8 = Math.Round(sum_s/n*100,4);
  489. double f9 = Math.Round(sum_a/n*100, 4);
  490. lessonItem.pc_df=f8;
  491. lessonItem.pc_zd=f9;
  492. // _logger.LogInformation($"{studentLessonData.id}=>评测指数:{f8}\t得分率:{Math.Round(sum_s/n,4)}\t参与指数:{f9}\t作答率:{Math.Round(sum_a/n,4)}");
  493. }
  494. {
  495. //小组相关指数
  496. }
  497. {
  498. //任务相关指数
  499. double n = studentLessonData.taskRecord.itemRecords.Count()*1.0;
  500. double max_m = lessonDataAnalysis.task.Max();
  501. double w= studentLessonData.taskRecord.itemRecords.Where(x => x.resultWeight>0).Count()*1.0;
  502. double y = (10 *w/n+(j/t) *w)/max_m;
  503. double l = max_m*(w*w/n+(j/t) * w )/n;
  504. double f4 = Math.Round(190*1.0/(1+Math.Exp(-(y)))-95, 4);
  505. double f5 = Math.Round(200*1.0/(1+Math.Exp(-(l)))-100, 4);
  506. lessonItem.rw_fqc =n;
  507. lessonItem.rw_cyc =w;
  508. lessonItem.rw_cx =f4;
  509. lessonItem.rw_cy =f5;
  510. // _logger.LogInformation($"{studentLessonData.id}=>任务指数:{f4}\t参与指数:{f5}\t任务次数:{n}\t参与次数:{w}\t");
  511. }
  512. {
  513. //评价相关指数
  514. double n = studentLessonData.rateingRecord.itemRecords.Count()*1.0;
  515. var v = studentLessonData.rateingRecord.itemRecords.Where(x => x.itemType.Equals("Voting"));
  516. double vc= v.Count()*1.0;
  517. var g = studentLessonData.rateingRecord.itemRecords.Where(x => x.itemType.Equals("GrandRating"));
  518. double gc = g.Count()*1.0;
  519. var p = studentLessonData.rateingRecord.itemRecords.Where(x => x.itemType.Equals("PeerAssessment"));
  520. double pc = p.Count()*1.0;
  521. var vg = v.Sum(x => x.itemScore);
  522. var vo = v.Sum(x => x.optCount);
  523. double vs = vc/n* (vg+ vo);
  524. var gg = g.Sum(x => x.itemScore);
  525. var go = g.Sum(x => x.optCount);
  526. double gs = gc/n* (gg+ go);
  527. var pg = p.Sum(x => x.itemScore);
  528. var po = p.Sum(x => x.optCount);
  529. double ps = pc/n* (pg+ po);
  530. double h = vs+ps+gs;
  531. double f3= Math.Round(190*1.0/(1+Math.Exp(-(h)))-95, 4);
  532. studentLessonData.appraise=f3;
  533. _logger.LogInformation($"{studentLessonData.id}=>评价能力:{f3}\t评价次数:{n}\t投票次数:{vc}-{vg}-{vo}\t星光次数:{gc}-{gg}-{go}\t互评次数:{pc}-{pg}-{po}");
  534. lessonItem.pj_nl =f3;
  535. lessonItem.pj_cs =n;
  536. lessonItem.pj_vc =vc;
  537. lessonItem.pj_vg =vg;
  538. lessonItem.pj_vo =vo;
  539. lessonItem.pj_gc =gc;
  540. lessonItem.pj_gg =gg;
  541. lessonItem.pj_go =go;
  542. lessonItem.pj_pc =pc;
  543. lessonItem.pj_pg =pg;
  544. lessonItem.pj_po =po;
  545. }
  546. {
  547. //协作相关指数
  548. var n= studentLessonData.coworkRecord.itemRecords.Count()*1.0;
  549. double max_m = lessonDataAnalysis.cowork.Max();
  550. double max_s = 35;
  551. var w = studentLessonData.coworkRecord.itemRecords.Where(x => x.resultWeight>0);
  552. double ss = w.Sum(x => x.itemScore)*1.0;
  553. double sw =w.Sum(x=>x.resultWeight)*1.0;
  554. double wc = w.Count()*1.0;
  555. double k = ((wc*wc/n+(j/t) * wc))/n+ ss/(10 *n);
  556. double f6 = Math.Round(190*1.0/(1+Math.Exp(-(k)))-95, 4);
  557. double f7 = Math.Round(200*1.0/(1+Math.Exp(-(k)))-100, 4);
  558. lessonItem.xz_fqc =n;
  559. lessonItem.xz_cyc =wc;
  560. lessonItem.xz_cgf =ss;
  561. lessonItem.xz_cx =f6;
  562. lessonItem.xz_cy =f7;
  563. //_logger.LogInformation($"{studentLessonData.id}=>协作指数:{f6}\t参与指数:{f7}\t协作次数:{n}\t参与次数:{wc}\t协作成果分数:{ss}\t{k}");
  564. }
  565. lessonItems.Add(lessonItem);
  566. }
  567. }
  568. private static int GetRandomValueByWeight(List<WeightedItem> items)
  569. {
  570. Random random = new Random();
  571. double randomWeight = random.NextDouble();
  572. double cumulativeWeight = 0.0;
  573. foreach (var item in items)
  574. {
  575. cumulativeWeight += item.Weight;
  576. if (randomWeight <= cumulativeWeight)
  577. {
  578. return item.Value;
  579. }
  580. }
  581. // This should not happen if all weights sum up to 1
  582. return items[items.Count - 1].Value;
  583. }
  584. private static double MinMaxNormalization(double min, double max, double x, double minRank = 1, double maxRank = 100)
  585. {
  586. //排名指数计算=( 当前值分数- 298) / (9992 - 298) * (99 - 60) + 60
  587. //将每个人的积分转化为60-100
  588. //排名 = (积分 - 最低积分) / (最高积分 - 最低积分) * (最大排名 - 最小排名) + 最小排名
  589. return Math.Round(x==0 ? 0 : max-min!=0 ? (x - min)*1.0 / (max - min) * (maxRank - minRank) + minRank : (x)*1.0 / (max) * (maxRank - minRank) + minRank,4);
  590. }
  591. }
  592. class WeightedItem
  593. {
  594. public int Value { get; set; }
  595. public double Weight { get; set; }
  596. }
  597. class StudentLessonItem
  598. {
  599. /// <summary>
  600. /// 学生id
  601. /// </summary>
  602. public string studentId { get; set; }
  603. /// <summary>
  604. /// 互动成效指数
  605. /// </summary>
  606. public double hd_cx { get; set; } = 0;
  607. /// <summary>
  608. /// 互动参与指数
  609. /// </summary>
  610. public double hd_cy { get; set; } = 0;
  611. /// <summary>
  612. /// 互动发起次数
  613. /// </summary>
  614. public double hd_fqc { get; set; } = 0;
  615. /// <summary>
  616. /// 互动参与次数
  617. /// </summary>
  618. public double hd_cyc { get; set; } = 0;
  619. /// <summary>
  620. /// 互动正确次数
  621. /// </summary>
  622. public double hd_zqc { get; set; } = 0;
  623. /// <summary>
  624. /// 个人计分
  625. /// </summary>
  626. public double gr_jf { get; set; } = 0;
  627. /// <summary>
  628. /// 评测得分率
  629. /// </summary>
  630. public double pc_df { get; set; } = 0;
  631. /// <summary>
  632. /// 评测作答率
  633. /// </summary>
  634. public double pc_zd { get; set; } = 0;
  635. /// <summary>
  636. /// 任务发起次数
  637. /// </summary>
  638. public double rw_fqc { get; set; } = 0;
  639. /// <summary>
  640. /// 任务参与次数
  641. /// </summary>
  642. public double rw_cyc { get; set; } = 0;
  643. /// <summary>
  644. /// 任务成效指数
  645. /// </summary>
  646. public double rw_cx { get; set; } = 0;
  647. /// <summary>
  648. /// 任务参与指数
  649. /// </summary>
  650. public double rw_cy { get; set; } = 0;
  651. /// <summary>
  652. /// 评价能力
  653. /// </summary>
  654. public double pj_nl { get; set; } = 0;
  655. /// <summary>
  656. /// 评价发起次数
  657. /// </summary>
  658. public double pj_cs { get; set; } = 0;
  659. /// <summary>
  660. /// 投票发起次数
  661. /// </summary>
  662. public double pj_vc { get; set; } = 0;
  663. /// <summary>
  664. /// 投票得票数
  665. /// </summary>
  666. public double pj_vg { get; set; } = 0;
  667. /// <summary>
  668. /// 投票次数
  669. /// </summary>
  670. public double pj_vo { get; set; } = 0;
  671. /// <summary>
  672. /// 星光发起次数
  673. /// </summary>
  674. public double pj_gc { get; set; } = 0;
  675. /// <summary>
  676. /// 星光得分数
  677. /// </summary>
  678. public double pj_gg { get; set; } = 0;
  679. /// <summary>
  680. /// 星光评分次数
  681. /// </summary>
  682. public double pj_go { get; set; } = 0;
  683. /// <summary>
  684. /// 互评发起次数
  685. /// </summary>
  686. public double pj_pc { get; set; } = 0;
  687. /// <summary>
  688. /// 互评得分数
  689. /// </summary>
  690. public double pj_pg { get; set; } = 0;
  691. /// <summary>
  692. /// 互评评分次数
  693. /// </summary>
  694. public double pj_po { get; set; } = 0;
  695. /// <summary>
  696. /// 协作发起次数
  697. /// </summary>
  698. public double xz_fqc { get; set; } = 0;
  699. /// <summary>
  700. /// 协作参与次数
  701. /// </summary>
  702. public double xz_cyc { get; set; } = 0;
  703. /// <summary>
  704. /// 协作成果分数
  705. /// </summary>
  706. public double xz_cgf { get; set; } = 0;
  707. /// <summary>
  708. /// 协作能力指数
  709. /// </summary>
  710. public double xz_cx { get; set; } = 0;
  711. /// <summary>
  712. /// 协作参与指数
  713. /// </summary>
  714. public double xz_cy { get; set; } = 0;
  715. }
  716. }