|
@@ -0,0 +1,468 @@
|
|
|
+using Microsoft.AspNetCore.Mvc;
|
|
|
+using System.Text.Json;
|
|
|
+using static HTEX.Test.Controllers.LessonRecordController;
|
|
|
+using TEAMModelOS.SDK.Extension;
|
|
|
+using TEAMModelOS.SDK.Models;
|
|
|
+
|
|
|
+namespace HTEX.Test.Controllers
|
|
|
+{
|
|
|
+ [ApiController]
|
|
|
+ [Route("mock-data")]
|
|
|
+ public class MockDataController : ControllerBase
|
|
|
+ {
|
|
|
+ [HttpPost("student-lesson")]
|
|
|
+ public async Task<IActionResult> StudentLesson(JsonElement json)
|
|
|
+ {
|
|
|
+ #region 数据模拟
|
|
|
+ //学生人数
|
|
|
+ int scount = Random.Shared.Next(40, 45);
|
|
|
+ //评测次数
|
|
|
+ int ecount = Random.Shared.Next(1, 3);
|
|
|
+ //题目个数
|
|
|
+ int qcount = Random.Shared.Next(8, 15);
|
|
|
+ //互动次数
|
|
|
+ int icount = Random.Shared.Next(3, 20);
|
|
|
+ //任务次数
|
|
|
+ int tcount = Random.Shared.Next(1, 3);
|
|
|
+ //评价次数
|
|
|
+ int pcount = Random.Shared.Next(1, 3);
|
|
|
+ //协作次数
|
|
|
+ int xcount = Random.Shared.Next(1, 3);
|
|
|
+ List<StudentLessonData> students = new List<StudentLessonData>();
|
|
|
+ //个人计分,小组计分
|
|
|
+ List<WeightedItem> gpitems = new List<WeightedItem>
|
|
|
+ {
|
|
|
+ new WeightedItem { Value = 0, Weight = 0.3 },
|
|
|
+ new WeightedItem { Value = 2, Weight = 0.1 },
|
|
|
+ new WeightedItem { Value = 5, Weight = 0.2 },
|
|
|
+ new WeightedItem { Value = 8, Weight = 0.1 },
|
|
|
+ new WeightedItem { Value = 3, Weight = 0.05 },
|
|
|
+ new WeightedItem { Value = 4, Weight = 0.02 },
|
|
|
+ new WeightedItem { Value = 6, Weight = 0.03 },
|
|
|
+ new WeightedItem { Value = 7, Weight = 0.2 }
|
|
|
+ };
|
|
|
+ //个人计分,小组计分
|
|
|
+ List<WeightedItem> titems = new List<WeightedItem>
|
|
|
+ {
|
|
|
+ new WeightedItem { Value = 0, Weight = 0.4 },
|
|
|
+ new WeightedItem { Value = 25, Weight = 0.1 },
|
|
|
+ new WeightedItem { Value = 15, Weight = 0.1 },
|
|
|
+ new WeightedItem { Value = 10, Weight = 0.05 },
|
|
|
+ new WeightedItem { Value = 30, Weight = 0.05 },
|
|
|
+ new WeightedItem { Value = 20, Weight = 0.02 },
|
|
|
+ new WeightedItem { Value = 40, Weight = 0.03 },
|
|
|
+ new WeightedItem { Value = 50, Weight = 0.05 },
|
|
|
+ new WeightedItem { Value = 5, Weight = 0.05 },
|
|
|
+ new WeightedItem { Value = 35, Weight = 0.05 },
|
|
|
+ new WeightedItem { Value = 45, Weight = 0.05 },
|
|
|
+ new WeightedItem { Value = 55, Weight = 0.05 }
|
|
|
+ };
|
|
|
+ //for (var i = 0; i<100; i++)
|
|
|
+ //{
|
|
|
+ // int randomValue = GetRandomValueByWeight(items);
|
|
|
+ // Console.WriteLine(randomValue);
|
|
|
+ //}
|
|
|
+ //被评价的目标索引
|
|
|
+ List<List<int>> cworkDist = new List<List<int>>(xcount);
|
|
|
+ //被评价目标的次数或分数
|
|
|
+ // List<List<int>> cworkCount = new List<List<int>>(xcount);
|
|
|
+ for (int i = 0; i < xcount; i++)
|
|
|
+ {
|
|
|
+ //乱序取10-20人作为评价目标
|
|
|
+ var vt = Enumerable.Range(0, scount).OrderBy(x => Random.Shared.Next()).Take(Random.Shared.Next(10, 21));
|
|
|
+ cworkDist.Add(vt.ToList());
|
|
|
+ //var counts = new List<int>();
|
|
|
+ //foreach (var v in vt)
|
|
|
+ //{
|
|
|
+ // counts.Add(0);
|
|
|
+ //}
|
|
|
+ //cworkCount.Add(counts);
|
|
|
+ }
|
|
|
+
|
|
|
+ //被评价的目标索引
|
|
|
+ List<List<int>> rateDist = new List<List<int>>(pcount);
|
|
|
+ //被评价目标的次数或分数
|
|
|
+ //List<List<int>> rateCount = new List<List<int>>(pcount);
|
|
|
+ List<string> types = new List<string>();
|
|
|
+ for (int i = 0; i < pcount; i++)
|
|
|
+ {
|
|
|
+ //乱序取10-20人作为评价目标
|
|
|
+ var vt = Enumerable.Range(0, scount).OrderBy(x => Random.Shared.Next()).Take(Random.Shared.Next(10, 21));
|
|
|
+ rateDist.Add(vt.ToList());
|
|
|
+ // var counts = new List<int>();
|
|
|
+ //foreach (var v in vt)
|
|
|
+ //{
|
|
|
+ // counts.Add(0);
|
|
|
+ //}
|
|
|
+ //rateCount.Add(counts);
|
|
|
+
|
|
|
+
|
|
|
+ var t = Random.Shared.Next(0, 3);
|
|
|
+ switch (true)
|
|
|
+ {
|
|
|
+ case bool when t==0:
|
|
|
+ types.Add("Voting");
|
|
|
+ break;
|
|
|
+ case bool when t==1:
|
|
|
+ types.Add("GrandRating");
|
|
|
+ break;
|
|
|
+ case bool when t==2:
|
|
|
+ types.Add("PeerAssessment");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (var s = 0; s<scount; s++)
|
|
|
+ {
|
|
|
+ StudentLessonData student = new StudentLessonData()
|
|
|
+ {
|
|
|
+ index=s,
|
|
|
+ seatID=$"{s+1}",
|
|
|
+ id=$"2024{(s+1).ToString("D3")}",
|
|
|
+ groupId=$"{Random.Shared.Next(1, 5)}",
|
|
|
+ attend=1,
|
|
|
+ gscore= GetRandomValueByWeight(gpitems),
|
|
|
+ pscore= GetRandomValueByWeight(gpitems),
|
|
|
+ tscore= GetRandomValueByWeight(titems),
|
|
|
+ };
|
|
|
+ for (var p = 0; p<pcount; p++)
|
|
|
+ {
|
|
|
+ student.rateingRecord.itemRecords.Add(new ItemRecord());
|
|
|
+ }
|
|
|
+ students.Add(student);
|
|
|
+ }
|
|
|
+ for (var s = 0; s<scount; s++)
|
|
|
+ {
|
|
|
+ var student = students[s];
|
|
|
+ //互动
|
|
|
+ for (var i = 0; i<icount; i++)
|
|
|
+ {
|
|
|
+ int criterion = 10;
|
|
|
+ var item = new ItemRecord { criterion=criterion };
|
|
|
+ var w = Random.Shared.Next(0, 4);
|
|
|
+
|
|
|
+ switch (true)
|
|
|
+ {
|
|
|
+ //未参与
|
|
|
+ case bool when w==0:
|
|
|
+ item.resultWeight= InteractWeight.T0;
|
|
|
+ item.resultType= InteractReultType.T0;
|
|
|
+ item.itemScore=0;
|
|
|
+ break;
|
|
|
+ //参与了
|
|
|
+ case bool when w==1:
|
|
|
+ item.resultWeight= InteractWeight.T1;
|
|
|
+ item.resultType= InteractReultType.T1;
|
|
|
+ item.itemScore=0;
|
|
|
+ break;
|
|
|
+ //部分正确
|
|
|
+ case bool when w==2:
|
|
|
+ var score = Random.Shared.Next(1, criterion);
|
|
|
+ item.resultWeight= MinMaxNormalization(1, criterion, score, InteractWeight.T1, InteractWeight.TT);
|
|
|
+ item.resultType= InteractReultType.TP;
|
|
|
+ item.itemScore=0;
|
|
|
+ break;
|
|
|
+ //完全正确
|
|
|
+ case bool when w==3:
|
|
|
+ item.resultWeight= InteractWeight.TT;
|
|
|
+ item.resultType= InteractReultType.TT;
|
|
|
+ item.itemScore=criterion;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ student.interactRecord.interactRecords.Add(item);
|
|
|
+ }
|
|
|
+ //任务
|
|
|
+ for (var t = 0; t<tcount; t++)
|
|
|
+ {
|
|
|
+ var w = Random.Shared.Next(0, 2);
|
|
|
+ var item = new ItemRecord { };
|
|
|
+ switch (true)
|
|
|
+ {
|
|
|
+ //未参与
|
|
|
+ case bool when w==0:
|
|
|
+ item.resultWeight= InteractWeight.T0;
|
|
|
+ item.resultType= InteractReultType.T0;
|
|
|
+ item.itemScore=0;
|
|
|
+ break;
|
|
|
+ //参加
|
|
|
+ case bool when w==1:
|
|
|
+ item.resultWeight= InteractWeight.TT;
|
|
|
+ item.resultType= InteractReultType.TT;
|
|
|
+ item.itemScore=10;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ student.taskRecord.taskRate= student.taskRecord.itemRecords.Where(x => x.resultWeight>0).Count()*1.0/tcount;
|
|
|
+ student.taskRecord.itemRecords.Add(item);
|
|
|
+ }
|
|
|
+ //评价
|
|
|
+ for (var p = 0; p<pcount; p++)
|
|
|
+ {
|
|
|
+ var item = student.rateingRecord.itemRecords[p];
|
|
|
+ var subtype = string.Empty;
|
|
|
+ item.itemType=types[p];
|
|
|
+ if (types[p].Equals("PeerAssessment"))
|
|
|
+ {
|
|
|
+ var sub = Random.Shared.Next(0, 3);
|
|
|
+ subtype= sub==0 ? "ALL" : sub==1 ? "Two" : "Self";
|
|
|
+ }
|
|
|
+ var w = Random.Shared.Next(0, 3);
|
|
|
+ switch (true)
|
|
|
+ {
|
|
|
+ //未参与
|
|
|
+ case bool when w==0:
|
|
|
+ item.resultWeight= InteractWeight.T0;
|
|
|
+ item.resultType= InteractReultType.T0;
|
|
|
+ item.itemScore=0;
|
|
|
+ break;
|
|
|
+ //参与
|
|
|
+ case bool when w==1||w==2:
|
|
|
+ item.resultWeight= InteractWeight.T1;
|
|
|
+ item.resultType= InteractReultType.T1;
|
|
|
+
|
|
|
+ if (item.itemType!.Equals("Voting"))
|
|
|
+ {
|
|
|
+ var index = Random.Shared.Next(0, rateDist[p].Count);
|
|
|
+ //rateCount[p][index]+=1;
|
|
|
+ students[rateDist[p][index]].rateingRecord.itemRecords[p].itemScore+=1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (item.itemType.Equals("PeerAssessment"))
|
|
|
+ {
|
|
|
+ var index = Random.Shared.Next(0, rateDist[p].Count);
|
|
|
+ //操作次数
|
|
|
+ int opt_count = Random.Shared.Next(1, 2);
|
|
|
+ for (var count = 0; count<opt_count; count++)
|
|
|
+ {
|
|
|
+ var score = Random.Shared.Next(3, 10);
|
|
|
+ // rateCount[p][index]+=score;
|
|
|
+ students[rateDist[p][index]].rateingRecord.itemRecords[p].itemScore+=score;
|
|
|
+ item.optCount+= 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ var index = Random.Shared.Next(0, rateDist[p].Count);
|
|
|
+ var score = Random.Shared.Next(3, 10);
|
|
|
+ // rateCount[p][index]+=score;
|
|
|
+ students[rateDist[p][index]].rateingRecord.itemRecords[p].itemScore+=score;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ // student.rateingRecord.itemRecords.Add(item);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //协作
|
|
|
+ for (var x = 0; x<xcount; x++)
|
|
|
+ {
|
|
|
+ int[] r = new int[] { 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1 };
|
|
|
+ var w = r[Random.Shared.Next(0, r.Length)];
|
|
|
+ var item = new ItemRecord { };
|
|
|
+ switch (true)
|
|
|
+ {
|
|
|
+ //未参与
|
|
|
+ case bool when w==0:
|
|
|
+ item.resultWeight= InteractWeight.T0;
|
|
|
+ item.resultType= InteractReultType.T0;
|
|
|
+ item.itemScore=0;
|
|
|
+ break;
|
|
|
+ //
|
|
|
+ case bool when w==1:
|
|
|
+ item.resultWeight= InteractWeight.TP;
|
|
|
+ item.resultType= InteractReultType.TP;
|
|
|
+ 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 };
|
|
|
+ item.itemScore=q[Random.Shared.Next(0, q.Count())];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ student.coworkRecord.itemRecords.Add(item);
|
|
|
+ }
|
|
|
+ //评测
|
|
|
+ for (var e = 0; e<ecount; e++)
|
|
|
+ {
|
|
|
+ StudentExamRecord examRecord = new();
|
|
|
+ double allocation = 0;
|
|
|
+ for (var q = 0; q<qcount; q++)
|
|
|
+ {
|
|
|
+ var criterion = Random.Shared.Next(2, 10);
|
|
|
+ allocation+=criterion;
|
|
|
+ var item = new ItemRecord { criterion =criterion };
|
|
|
+ var w = Random.Shared.Next(0, 4);
|
|
|
+ switch (true)
|
|
|
+ {
|
|
|
+ //未作答
|
|
|
+ case bool when w==0:
|
|
|
+ item.resultWeight= InteractWeight.T0;
|
|
|
+ item.resultType= InteractReultType.T0;
|
|
|
+ item.itemScore=0;
|
|
|
+ break;
|
|
|
+ //作答错误
|
|
|
+ case bool when w==1:
|
|
|
+ item.resultWeight= InteractWeight.T1;
|
|
|
+ item.resultType= InteractReultType.T1;
|
|
|
+ item.itemScore=0;
|
|
|
+ break;
|
|
|
+ //部分正确
|
|
|
+ case bool when w==2:
|
|
|
+ var score = Random.Shared.Next(1, criterion);
|
|
|
+ item.resultWeight= MinMaxNormalization(1, criterion, score, InteractWeight.T1, InteractWeight.TT); // score * 1.0 / criterion* (InteractWeight.TT-InteractWeight.T1);
|
|
|
+ item.resultType= InteractReultType.TP;
|
|
|
+ item.itemScore=score;
|
|
|
+ break;
|
|
|
+ //完全正确
|
|
|
+ case bool when w==3:
|
|
|
+ item.resultWeight= InteractWeight.TT;
|
|
|
+ item.resultType= InteractReultType.TT;
|
|
|
+ item.itemScore=criterion;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ examRecord.itemRecords.Add(item);
|
|
|
+ }
|
|
|
+ examRecord.qcount=qcount;
|
|
|
+ examRecord.workCount= examRecord.itemRecords.Where(x => x.resultWeight>0).Count();
|
|
|
+ examRecord.allocation=allocation;
|
|
|
+ examRecord.score= examRecord.itemRecords.Where(x => x.itemScore>=0).Select(x => x.itemScore).Sum();//得分
|
|
|
+ examRecord.scoreRate = Math.Round(examRecord.score * 1.0 / allocation, 4);//得分率
|
|
|
+ examRecord.answerRate= Math.Round(examRecord.itemRecords.Where(x => x.resultWeight>0).Count()*1.0/qcount, 4);//作答率
|
|
|
+ student.examRecords.Add(examRecord);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (var p = 0; p<pcount; p++)
|
|
|
+ {
|
|
|
+ var order = students.OrderByDescending(x => x.rateingRecord.itemRecords[p].itemScore);
|
|
|
+ var maxItems = students.FindAll(x => x.rateingRecord.itemRecords[p].itemScore==order.First().rateingRecord.itemRecords[p].itemScore);
|
|
|
+ var max = students.FindAll(x => x.rateingRecord.itemRecords[p].itemScore==order.First().rateingRecord.itemRecords[p].itemScore).First().rateingRecord.itemRecords[p].itemScore;
|
|
|
+ var min = students.FindAll(x => x.rateingRecord.itemRecords[p].itemScore==order.Last().rateingRecord.itemRecords[p].itemScore).First().rateingRecord.itemRecords[p].itemScore;
|
|
|
+ var sum = students.Sum(x => x.rateingRecord.itemRecords[p].itemScore);
|
|
|
+ foreach (var student in students)
|
|
|
+ {
|
|
|
+ if (student.rateingRecord.itemRecords[p].itemScore>0 && student.rateingRecord.itemRecords[p].optCount>0)
|
|
|
+ {
|
|
|
+ student.rateingRecord.itemRecords[p].resultType=InteractReultType.TP;
|
|
|
+ var data = MinMaxNormalization(min, max, student.rateingRecord.itemRecords[p].itemScore);
|
|
|
+ student.rateingRecord.itemRecords[p].resultWeight=Math.Round(InteractWeight.T1+ data * 1.0 / 100 * (InteractWeight.TT-InteractWeight.T1), 4);
|
|
|
+ if (maxItems.Select(x => x.seatID).Contains(student.seatID))
|
|
|
+ {
|
|
|
+ student.rateingRecord.itemRecords[p].resultType= InteractReultType.TT;
|
|
|
+ student.rateingRecord.itemRecords[p].resultWeight= InteractWeight.TT;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (var p = 0; p<xcount; p++)
|
|
|
+ {
|
|
|
+ var order = students.OrderByDescending(x => x.coworkRecord.itemRecords[p].itemScore);
|
|
|
+ var maxItems = students.FindAll(x => x.coworkRecord.itemRecords[p].itemScore==order.First().coworkRecord.itemRecords[p].itemScore);
|
|
|
+ var max = students.FindAll(x => x.coworkRecord.itemRecords[p].itemScore==order.First().coworkRecord.itemRecords[p].itemScore).First().coworkRecord.itemRecords[p].itemScore;
|
|
|
+ var min = students.FindAll(x => x.coworkRecord.itemRecords[p].itemScore==order.Last().coworkRecord.itemRecords[p].itemScore).First().coworkRecord.itemRecords[p].itemScore;
|
|
|
+ var sum = students.Sum(x => x.coworkRecord.itemRecords[p].itemScore);
|
|
|
+ foreach (var student in students)
|
|
|
+ {
|
|
|
+ if (student.coworkRecord.itemRecords[p].itemScore>0)
|
|
|
+ {
|
|
|
+ student.coworkRecord.itemRecords[p].resultType=InteractReultType.TP;
|
|
|
+ var data = MinMaxNormalization(min, max, student.coworkRecord.itemRecords[p].itemScore);
|
|
|
+ student.coworkRecord.itemRecords[p].resultWeight=Math.Round(InteractWeight.T1+ data * 1.0 / 100 * (InteractWeight.TT-InteractWeight.T1), 4);
|
|
|
+ if (maxItems.Select(x => x.seatID).Contains(student.seatID))
|
|
|
+ {
|
|
|
+ student.coworkRecord.itemRecords[p].resultType= InteractReultType.TT;
|
|
|
+ student.coworkRecord.itemRecords[p].resultWeight= InteractWeight.TT;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endregion 数据模拟
|
|
|
+ string jsons = await System.IO.File.ReadAllTextAsync("F:\\lesson-local\\analysis.json");
|
|
|
+ LessonDataAnalysis lessonDataAnalysis = jsons.ToObject<LessonDataAnalysis>();
|
|
|
+ ProcessStudentData(students, lessonDataAnalysis, scount, ecount, qcount, icount, tcount, pcount, xcount);
|
|
|
+ try {
|
|
|
+ await System.IO.File.WriteAllTextAsync($"F:\\mock-data\\{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}.json", new { scount, ecount, qcount, icount, tcount, pcount, xcount, students }.ToJsonString());
|
|
|
+ } catch (Exception ex) {
|
|
|
+ Console.WriteLine(scount);
|
|
|
+ }
|
|
|
+ return Ok(new { scount, ecount, qcount, icount, tcount, pcount, xcount, students });
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private static void ProcessStudentData(List<StudentLessonData> studentLessonDatas, LessonDataAnalysis lessonDataAnalysis, int scount, int ecount, int qcount, int icount, int tcount, int pcount, int xcount)
|
|
|
+ {
|
|
|
+ //历史记录的个人计分集合,通过“2倍标准差规则”移除异常值后得到的集合
|
|
|
+ var max_q = lessonDataAnalysis.pscore.Max();
|
|
|
+ //历史记录的互动计分集合,通过“2倍标准差规则”移除异常值后得到的集合
|
|
|
+ var max_t = lessonDataAnalysis.tscore.Max();
|
|
|
+ //历史记录的小组计分集合,通过“2倍标准差规则”移除异常值后得到的集合
|
|
|
+ var max_h = lessonDataAnalysis.gscore.Max();
|
|
|
+ var j = InteractWeight.T1;
|
|
|
+ foreach (var studentLessonData in studentLessonDatas)
|
|
|
+ {
|
|
|
+ //互动成效指数
|
|
|
+ var a = 0.0;
|
|
|
+ //互动参与指数
|
|
|
+ var b = 0.0;
|
|
|
+ //c个人计分指数,d互动计分指数,e小组计分指数
|
|
|
+ double c = 0, d = 0, e = 0;
|
|
|
+ //课例互动次数
|
|
|
+ double n = studentLessonData.interactRecord.interactRecords.Count()*1.0;
|
|
|
+ //是IES大陆正式站历史课例数据,自2024-03-01至2024-10-08日,互动指数或学法指数黄灯或绿灯,不包含醍摩豆学校及测试学校,课例时长超过5分钟的有效课例(10,680笔数据) 的IRS互动+抢权+挑人的次数集合,
|
|
|
+ //通过“2倍标准差规则” 移除异常值后得到的集合,再通过K-Means聚类算法得到高低位阶互动频次两个集合,并根据当前课例互动次数位阶的集合的质心值,该值定为m值
|
|
|
+ var m = n<=lessonDataAnalysis.clustersInteract.First().Value.Max() ? lessonDataAnalysis.clustersInteract.First().Key*1.0 : lessonDataAnalysis.clustersInteract.Last().Key *1.0;
|
|
|
+ //学生作答次数
|
|
|
+ var w = studentLessonData.interactRecord.interactRecords.Where(x => x.resultWeight>=InteractWeight.T1).Count()*1.0;
|
|
|
+ //作答正确数(包括部分正确)
|
|
|
+ var r = studentLessonData.interactRecord.interactRecords.Where(x => x.resultWeight>InteractWeight.T1).Count()*1.0;
|
|
|
+ //有参与的权重集合60≤k(x)≤100
|
|
|
+ var kw = studentLessonData.interactRecord.interactRecords.Where(x => x.resultWeight>=InteractWeight.T1).Sum(x => x.resultWeight*1.0);
|
|
|
+ //有得分的权重集合60<e(x)≤100
|
|
|
+ var er = studentLessonData.interactRecord.interactRecords.Where(x => x.resultWeight>InteractWeight.T1).Sum(x => x.resultWeight*1.0);
|
|
|
+ //本节课的所有互动计分
|
|
|
+ var i = studentLessonData.interactRecord.interactRecords.Sum(x => x.itemScore*1.0);
|
|
|
+ //本节课教师手动给学生的个人计分
|
|
|
+ var s = studentLessonData.pscore;
|
|
|
+ //个人计分指数
|
|
|
+ c = s*1.0/max_q;
|
|
|
+ //互动计分指数
|
|
|
+ d = i*1.0/max_t;
|
|
|
+ //互动成效指数
|
|
|
+ a = (d+w*kw/(j*m)+r*er/(j*m))*1.0/n;
|
|
|
+ //互动参与指数
|
|
|
+ b = ((w*w)/m+(r*r)/m)*1.0/n;
|
|
|
+ //c+a= 个人计分指数+ 个人互动成效指数
|
|
|
+ var f = Math.Round(190*1.0/(1+Math.Exp(-(c+a)))-95, 4);
|
|
|
+ studentLessonData.achieve=f;
|
|
|
+ Console.WriteLine($"{studentLessonData.id}=>成效:{f}\t互动次数:{n}\t参与次数:{w}\t正确次数:{r}\t个人计分:{s}\t{Math.Round(c,2)}\t互动计分:{i}\t{Math.Round(d,2)},\t学习成效:{Math.Round(a,2)}");// kw:{Math.Round(kw,2)}\t er:{Math.Round(er,2)}
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static int GetRandomValueByWeight(List<WeightedItem> items)
|
|
|
+ {
|
|
|
+ Random random = new Random();
|
|
|
+ double randomWeight = random.NextDouble();
|
|
|
+ double cumulativeWeight = 0.0;
|
|
|
+
|
|
|
+ foreach (var item in items)
|
|
|
+ {
|
|
|
+ cumulativeWeight += item.Weight;
|
|
|
+ if (randomWeight <= cumulativeWeight)
|
|
|
+ {
|
|
|
+ return item.Value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // This should not happen if all weights sum up to 1
|
|
|
+ return items[items.Count - 1].Value;
|
|
|
+ }
|
|
|
+ private static double MinMaxNormalization(double min, double max, double x, double minRank = 1, double maxRank = 100)
|
|
|
+ {
|
|
|
+ //排名指数计算=( 当前值分数- 298) / (9992 - 298) * (99 - 60) + 60
|
|
|
+ //将每个人的积分转化为60-100
|
|
|
+ //排名 = (积分 - 最低积分) / (最高积分 - 最低积分) * (最大排名 - 最小排名) + 最小排名
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ class WeightedItem
|
|
|
+ {
|
|
|
+ public int Value { get; set; }
|
|
|
+ public double Weight { get; set; }
|
|
|
+ }
|
|
|
+}
|