123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518 |
- using Microsoft.AspNetCore.Mvc;
- using System.Text.Json;
-
- using TEAMModelOS.SDK.Extension;
- using TEAMModelOS.SDK.Models;
- using System;
- using OfficeOpenXml;
- using System.Reflection;
- using System.Xml;
- using System.Text.RegularExpressions;
- using HTEX.Lib.ETL.Lesson;
- using OfficeOpenXml.Style;
- using DocumentFormat.OpenXml.Spreadsheet;
- using OpenXmlPowerTools;
- namespace HTEX.Test.Controllers
- {
-
- public static class MockDataController
- {
- public static async Task MockData()
- {
-
-
- #region 数据模拟
- //学生人数
- int scount = Random.Shared.Next(40, 45);
- //互动次数
- int icount = Random.Shared.Next(21,22);
- //评测次数
- int ecount = Random.Shared.Next(1, 3);
- //题目个数
- int qcount = Random.Shared.Next(8, 15);
- //任务次数
- int tcount = Random.Shared.Next(2, 3);
- //评价次数
- int pcount = Random.Shared.Next(3, 4);
- //协作次数
- int xcount = Random.Shared.Next(1, 3);
- //挑人次数
- int kcount = Random.Shared.Next(2, 4);
- string type = "hd";
- int count = 0;
- switch (true)
- {
- case bool when type.Equals("hd"):
- count=icount;
- break;
- case bool when type.Equals("pc"):
- count=ecount;
- break;
- case bool when type.Equals("rw"):
- count=tcount;
- break;
- case bool when type.Equals("pj"):
- count=pcount;
- break;
- case bool when type.Equals("xz"):
- count=xcount;
- break;
- }
- for (var i = 1; i < count; i++)
- {
- await StudentLesson(scount,ecount,qcount,i,tcount,pcount,xcount,kcount);
- }
- }
- //[HttpPost("student-lesson")]
- public static async Task StudentLesson(int scount, int ecount, int qcount, int icount, int tcount, int pcount, int xcount, int kcount)
- {
-
- List<StudentLessonData> students = new List<StudentLessonData>();
- //个人计分,小组计分
- List<WeightedItem> gpitems = new List<WeightedItem>
- {
- new WeightedItem { Value = 0, Weight = 0.1 },
- new WeightedItem { Value = 2, Weight = 0.2 },
- new WeightedItem { Value = 5, Weight = 0.2 },
- new WeightedItem { Value = 8, Weight = 0.02 },
- new WeightedItem { Value = 3, Weight = 0.2 },
- new WeightedItem { Value = 4, Weight = 0.2 },
- new WeightedItem { Value = 6, Weight = 0.04 },
- new WeightedItem { Value = 7, Weight = 0.04 }
- };
- //互动积分
- 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, 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;
- }
- }
- string[] grouppick = new string[] { "PickupNthGrp", "PickupGrp", "PickupEachGrp" };
- string[] pickupAll = new string[] { "PickupNameLst", "PickupOption", "PickupNthGrp", "PickupGrp",
- "PickupRange", "PickupEachGrp", "PickupDiff", "PickupWrong", "PickupNoDiff", "PickupRight",
- "PickupGener", "PickupWtoW", "PickupWtoR", "PickupLSA_WordFreq", "PickupLSA_Classify", "Pickup0_49" };
- 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<kcount; i++)
- {
- var rd= Random.Shared.Next(0, 4);
- if (rd==1)
- {
- student.pickups.Add($"1--{grouppick[Random.Shared.Next(0, grouppick.Length)]}");
- }
- else {
- student.pickups.Add($"1--{pickupAll[Random.Shared.Next(0, pickupAll.Length)]}");
- }
- }
- //互动
- 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, 5);
- var item = new ItemRecord { };
- switch (true)
- {
- //未参与
- case bool when w==0:
- item.resultWeight= InteractWeight.T0;
- item.resultType= InteractReultType.T0;
- item.itemScore=0;
- item.optCount=0;
- break;
- //参加
- case bool when w==1:
- item.resultWeight= InteractWeight.TT;
- item.resultType= InteractReultType.TT;
- item.optCount= Random.Shared.Next(1, 4);
- item.itemScore=item.optCount*10;
- item.isGroup= Random.Shared.Next(0,4)!=1;
- 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);
- }
- }
- //小组协作
- {
- int[] r = new int[] { 1, 1, 1, 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 { };
- double grpcoworkScore = 0;
- switch (true)
- {
- //未参与
- case bool when w==0:
- break;
- //
- case bool when w==1:
-
- 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 };
- grpcoworkScore= q[Random.Shared.Next(0, q.Count())]* Random.Shared.Next(2,4 );
- student.group_coworkScore.Add(grpcoworkScore);
- break;
- }
- }
-
- //评测
- 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(5, 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\\analysis.json");
- long time = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
- LessonDataAnalysisCluster lessonDataAnalysis = jsons.ToObject<LessonDataAnalysisCluster>();
- var lessonItems= LessonETLService. ProcessStudentDataV2(students, lessonDataAnalysis);
- var excleFile = $"F:\\mock-data\\{time}.xlsx";
- var runtimePath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
- XmlDocument xmlDocument = new XmlDocument();
- xmlDocument.Load($"{runtimePath}\\summary.xml");
- List<string> noStujson = new List<string>();
- await LessonETLService.ExportToExcelLocal(lessonItems, excleFile, xmlDocument);
- try {
- await System.IO.File.WriteAllTextAsync($"F:\\mock-data\\{time}.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 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; }
- }
-
- }
|