using Microsoft.AspNetCore.Mvc; using System.Text.Json; using static HTEX.Test.Controllers.LessonRecordController; using TEAMModelOS.SDK.Extension; using TEAMModelOS.SDK.Models; using System; namespace HTEX.Test.Controllers { [ApiController] [Route("mock-data")] public class MockDataController : ControllerBase { private readonly ILogger _logger; public MockDataController(ILogger logger) { _logger = logger; } [HttpPost("student-lesson")] public async Task 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, 4); //评价次数 int pcount = Random.Shared.Next(2, 4); //协作次数 int xcount = Random.Shared.Next(3, 4); List students = new List(); //个人计分,小组计分 List gpitems = new List { 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 titems = new List { 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> cworkDist = new List>(xcount); //被评价目标的次数或分数 // List> cworkCount = new List>(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(); //foreach (var v in vt) //{ // counts.Add(0); //} //cworkCount.Add(counts); } //被评价的目标索引 List> rateDist = new List>(pcount); //被评价目标的次数或分数 //List> rateCount = new List>(pcount); List types = new List(); 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(); //foreach (var v in vt) //{ // counts.Add(0); //} //rateCount.Add(counts); var t = Random.Shared.Next(0, 1); switch (true) { case bool when i==0: types.Add("Voting"); break; case bool when i==1: types.Add("GrandRating"); break; case bool when i==2: types.Add("PeerAssessment"); break; } } for (var s = 0; s x.resultWeight>0).Count()*1.0/tcount; student.taskRecord.itemRecords.Add(item); } //评价 for (var p = 0; p 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 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 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(); 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 void ProcessStudentData(List 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; double t = InteractWeight.TT; List lessonItems= new List(); foreach (var studentLessonData in studentLessonDatas) { StudentLessonItem lessonItem = new StudentLessonItem() { studentId= studentLessonData.id! }; double u = 0.0; if (studentLessonData.attend==1) { u=100.0; } //c个人计分指数,d互动计分指数,e小组计分指数 double c = 0, d = 0, e = 0; ////互动 //double hd_cx = 0;//互动成效指数 //double hd_cy = 0;//互动参与指数 //double hd_fqc = 0;//互动发起次数 //double hd_cyc = 0;//互动参与次数 //double hd_zqc = 0;//互动正确次数 //double gr_jf = 0;//个人计分 ////评测 //double pc_df = 0;//评测得分率 //double pc_zd = 0;//评测作答率 ////任务 //double rw_fqc = 0;//任务发起次数 //double rw_cyc = 0;//任务参与次数 //double rw_cx = 0;//任务成效指数 //double rw_cy = 0;//任务参与指数 ////评价 //double pj_nl = 0;//评价能力 //double pj_cs = 0;//评价发起次数 //double pj_vc = 0;//评价-投票发起次数 //double pj_vg = 0;//投票得票数 //double pj_vo = 0;//投票次数 //double pj_gc = 0;//评价-星光发起次数 //double pj_gg = 0;//星光得分数 //double pj_go = 0;//星光评分次数 //double pj_pc = 0;//评价-互评发起次数 //double pj_pg = 0;//互评的分数 //double pj_po = 0;//互评评分次数 ////协作 //double xz_fqc = 0;//协作发起次数 //double xz_cyc = 0;//协作参与次数 //double xz_cgf = 0;//协作成果分数 //double xz_cx = 0;//协作能力指数 //double xz_cy = 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 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; //互动成效指数 var a = (d+w*kw/(j*m)+r*er/(j*m))*1.0/n; //互动参与指数 var b = ((w*w)/m+(r*r)/m)*1.0/n; //c+a= 个人计分指数+ 个人互动成效指数 //学习成效 var f1 = Math.Round(190*1.0/(1+Math.Exp(-(c+a)))-95, 4); lessonItem.hd_cx=f1; var f2 = Math.Round(200*1.0/(1+Math.Exp(-(b+u/100)))-100, 4); lessonItem.hd_cy=f2; lessonItem.hd_cyc=w; lessonItem.hd_fqc=n; lessonItem.hd_zqc=r; lessonItem.gr_jf=s; //studentLessonData.achieve=f1; //studentLessonData.attitude=f2; // _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)}"); } { //评测相关指数 double n = studentLessonData.examRecords.Count()*1.0; //题目数量 double nq = studentLessonData.examRecords.Sum(x => x.qcount)*1.0; double max_e = lessonDataAnalysis.exam.Max(); //得分率 double sum_s = studentLessonData.examRecords.Sum(x => x.scoreRate); //作答率 double sum_a = studentLessonData.examRecords.Sum(x => x.answerRate); double f8 = Math.Round(sum_s/n*100,4); double f9 = Math.Round(sum_a/n*100, 4); lessonItem.pc_df=f8; lessonItem.pc_zd=f9; // _logger.LogInformation($"{studentLessonData.id}=>评测指数:{f8}\t得分率:{Math.Round(sum_s/n,4)}\t参与指数:{f9}\t作答率:{Math.Round(sum_a/n,4)}"); } { //小组相关指数 } { //任务相关指数 double n = studentLessonData.taskRecord.itemRecords.Count()*1.0; double max_m = lessonDataAnalysis.task.Max(); double w= studentLessonData.taskRecord.itemRecords.Where(x => x.resultWeight>0).Count()*1.0; double y = (10 *w/n+(j/t) *w)/max_m; double l = max_m*(w*w/n+(j/t) * w )/n; double f4 = Math.Round(190*1.0/(1+Math.Exp(-(y)))-95, 4); double f5 = Math.Round(200*1.0/(1+Math.Exp(-(l)))-100, 4); lessonItem.rw_fqc =n; lessonItem.rw_cyc =w; lessonItem.rw_cx =f4; lessonItem.rw_cy =f5; // _logger.LogInformation($"{studentLessonData.id}=>任务指数:{f4}\t参与指数:{f5}\t任务次数:{n}\t参与次数:{w}\t"); } { //评价相关指数 double n = studentLessonData.rateingRecord.itemRecords.Count()*1.0; var v = studentLessonData.rateingRecord.itemRecords.Where(x => x.itemType.Equals("Voting")); double vc= v.Count()*1.0; var g = studentLessonData.rateingRecord.itemRecords.Where(x => x.itemType.Equals("GrandRating")); double gc = g.Count()*1.0; var p = studentLessonData.rateingRecord.itemRecords.Where(x => x.itemType.Equals("PeerAssessment")); double pc = p.Count()*1.0; var vg = v.Sum(x => x.itemScore); var vo = v.Sum(x => x.optCount); double vs = vc/n* (vg+ vo); var gg = g.Sum(x => x.itemScore); var go = g.Sum(x => x.optCount); double gs = gc/n* (gg+ go); var pg = p.Sum(x => x.itemScore); var po = p.Sum(x => x.optCount); double ps = pc/n* (pg+ po); double h = vs+ps+gs; double f3= Math.Round(190*1.0/(1+Math.Exp(-(h)))-95, 4); studentLessonData.appraise=f3; _logger.LogInformation($"{studentLessonData.id}=>评价能力:{f3}\t评价次数:{n}\t投票次数:{vc}-{vg}-{vo}\t星光次数:{gc}-{gg}-{go}\t互评次数:{pc}-{pg}-{po}"); lessonItem.pj_nl =f3; lessonItem.pj_cs =n; lessonItem.pj_vc =vc; lessonItem.pj_vg =vg; lessonItem.pj_vo =vo; lessonItem.pj_gc =gc; lessonItem.pj_gg =gg; lessonItem.pj_go =go; lessonItem.pj_pc =pc; lessonItem.pj_pg =pg; lessonItem.pj_po =po; } { //协作相关指数 var n= studentLessonData.coworkRecord.itemRecords.Count()*1.0; double max_m = lessonDataAnalysis.cowork.Max(); double max_s = 35; var w = studentLessonData.coworkRecord.itemRecords.Where(x => x.resultWeight>0); double ss = w.Sum(x => x.itemScore)*1.0; double sw =w.Sum(x=>x.resultWeight)*1.0; double wc = w.Count()*1.0; double k = ((wc*wc/n+(j/t) * wc))/n+ ss/(10 *n); double f6 = Math.Round(190*1.0/(1+Math.Exp(-(k)))-95, 4); double f7 = Math.Round(200*1.0/(1+Math.Exp(-(k)))-100, 4); lessonItem.xz_fqc =n; lessonItem.xz_cyc =wc; lessonItem.xz_cgf =ss; lessonItem.xz_cx =f6; lessonItem.xz_cy =f7; //_logger.LogInformation($"{studentLessonData.id}=>协作指数:{f6}\t参与指数:{f7}\t协作次数:{n}\t参与次数:{wc}\t协作成果分数:{ss}\t{k}"); } lessonItems.Add(lessonItem); } } private static int GetRandomValueByWeight(List 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; } } class StudentLessonItem { /// /// 学生id /// public string studentId { get; set; } /// /// 互动成效指数 /// public double hd_cx { get; set; } = 0; /// /// 互动参与指数 /// public double hd_cy { get; set; } = 0; /// /// 互动发起次数 /// public double hd_fqc { get; set; } = 0; /// /// 互动参与次数 /// public double hd_cyc { get; set; } = 0; /// /// 互动正确次数 /// public double hd_zqc { get; set; } = 0; /// /// 个人计分 /// public double gr_jf { get; set; } = 0; /// /// 评测得分率 /// public double pc_df { get; set; } = 0; /// /// 评测作答率 /// public double pc_zd { get; set; } = 0; /// /// 任务发起次数 /// public double rw_fqc { get; set; } = 0; /// /// 任务参与次数 /// public double rw_cyc { get; set; } = 0; /// /// 任务成效指数 /// public double rw_cx { get; set; } = 0; /// /// 任务参与指数 /// public double rw_cy { get; set; } = 0; /// /// 评价能力 /// public double pj_nl { get; set; } = 0; /// /// 评价发起次数 /// public double pj_cs { get; set; } = 0; /// /// 投票发起次数 /// public double pj_vc { get; set; } = 0; /// /// 投票得票数 /// public double pj_vg { get; set; } = 0; /// /// 投票次数 /// public double pj_vo { get; set; } = 0; /// /// 星光发起次数 /// public double pj_gc { get; set; } = 0; /// /// 星光得分数 /// public double pj_gg { get; set; } = 0; /// /// 星光评分次数 /// public double pj_go { get; set; } = 0; /// /// 互评发起次数 /// public double pj_pc { get; set; } = 0; /// /// 互评得分数 /// public double pj_pg { get; set; } = 0; /// /// 互评评分次数 /// public double pj_po { get; set; } = 0; /// /// 协作发起次数 /// public double xz_fqc { get; set; } = 0; /// /// 协作参与次数 /// public double xz_cyc { get; set; } = 0; /// /// 协作成果分数 /// public double xz_cgf { get; set; } = 0; /// /// 协作能力指数 /// public double xz_cx { get; set; } = 0; /// /// 协作参与指数 /// public double xz_cy { get; set; } = 0; } }