12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195 |
- using Azure.Storage.Blobs.Models;
- using Microsoft.AspNetCore.Mvc;
- using System.Text.Json;
- using TEAMModelOS.SDK;
- using TEAMModelOS.SDK.DI;
- using TEAMModelOS.SDK.Models;
- using TEAMModelOS.SDK.Extension;
- using StackExchange.Redis;
- using System.Text.RegularExpressions;
- using System.Linq;
- using static TEAMModelOS.SDK.Models.Cosmos.Student.StudentAnalysis;
- using static Microsoft.Azure.Amqp.Serialization.SerializableType;
- using Microsoft.AspNetCore.DataProtection.KeyManagement;
- using System.Drawing;
- using TEAMModelOS.SDK.Models.Cosmos.OpenEntity;
- using System.Diagnostics;
- using Microsoft.OData.UriParser;
- using HTEX.Test.Service;
- using System.IO;
- using static Pipelines.Sockets.Unofficial.SocketConnection;
- using static HTEX.Test.Controllers.LessonRecordController;
- namespace HTEX.Test.Controllers
- {
- [ApiController]
- [Route("lesson-record")]
- public class LessonRecordController : ControllerBase
- {
- private readonly ILogger<LessonRecordController> _logger;
- private readonly AzureCosmosFactory _azureCosmos;
- private readonly AzureStorageFactory _azureStorage;
- private readonly List<string> objectiveTypes=new List<string>(){ "single", "multiple", "sortmultiple" , "judge" };
- private readonly double minRank = 1;
- private readonly double maxRank = 100;
- public LessonRecordController(ILogger<LessonRecordController> logger, AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage)
- {
- _logger = logger;
- _azureCosmos = azureCosmos;
- _azureStorage = azureStorage;
- }
- [HttpPost("process-local")]
- public async Task<IActionResult> ProcessLocal(JsonElement json)
- {
- string? id=json.GetProperty("id").GetString();
- if (!string.IsNullOrWhiteSpace(id))
- {
- string path = $"C:\\Users\\CrazyIter\\Downloads\\{id}";
- var files = ListAllFiles(path);
- // var sampleJson =System.IO. File.ReadAllTextAsync(path);
- LessonBase? lessonBase = null;
- List<StudentLessonData> studentLessonDatas = new List<StudentLessonData>();
- List<TaskData> taskDatas = new List<TaskData>();
- List<SmartRatingData> smartRatingDatas = new List<SmartRatingData>();
- List<IRSData> irsDatas = new List<IRSData>();
- List<CoworkData> coworkDatas = new List<CoworkData>();
- List<ExamData> examDatas = new List<ExamData>();
- TimeLineData? timeLineData = null;
- foreach (var item in files)
- {
-
- if (item.Contains("IES\\base.json"))
- {
- string jsons = await System.IO.File.ReadAllTextAsync(item);
- jsons=jsons.Replace("\"Uncall\"", "0").Replace("Uncall", "0");
- lessonBase = jsons.ToObject<LessonBase>();
- var data = GetBaseData( lessonBase);
- studentLessonDatas=data.studentLessonDatas;
- }
- if (item.Contains("IES\\TimeLine.json"))
- {
- string jsons = await System.IO.File.ReadAllTextAsync(item);
- timeLineData = jsons.ToObject<TimeLineData>();
- }
- if (item.Contains("IES\\Task.json"))
- {
- string jsons = await System.IO.File.ReadAllTextAsync(item);
- taskDatas = jsons.ToObject<List<TaskData>>();
- }
-
- if (item.Contains("IES\\SmartRating.json"))
- {
- string jsons = await System.IO.File.ReadAllTextAsync(item);
- smartRatingDatas = jsons.ToObject<List<SmartRatingData>>();
- }
-
- if (item.Contains("IES\\IRS.json"))
- {
- string jsons = await System.IO.File.ReadAllTextAsync(item);
- irsDatas = jsons.ToObject<List<IRSData>>();
- }
- if (item.Contains("IES\\Cowork.json"))
- {
- string jsons = await System.IO.File.ReadAllTextAsync(item);
- coworkDatas = jsons.ToObject<List<CoworkData>>();
- }
- try
- {
- if (item.Contains($"\\{id}\\Exam\\") && item.EndsWith("Exam.json"))
- {
- string examsFile = item;
- if (examsFile.EndsWith("Exam.json"))
- {
- ExamData? examData = null;
- string jsons = await System.IO.File.ReadAllTextAsync(item);
- jsons= jsons.Replace("\"publish\": \"0\"", "\"publish\": 0").Replace("\"publish\": \"1\"", "\"publish\": 1");
- examData = jsons.ToObject<ExamData>();
- if (examData!=null && examData.exam.papers.IsNotEmpty())
- {
- string paperId = examData.exam.papers.First().id;
- string paperPath = $"{path}\\ExamPaper\\{paperId}\\index.json";
- string jsonp = await System.IO.File.ReadAllTextAsync(paperPath);
- LessonPaper lessonPaper = jsonp.ToObject<LessonPaper>();
- examData.paper = lessonPaper;
- examDatas.Add(examData);
- }
- }
- }
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, ex.Message);
- }
-
- }
- if (lessonBase!=null && timeLineData!=null)
- {
- studentLessonDatas = GetIRSData(lessonBase, timeLineData, irsDatas, studentLessonDatas, examDatas);
- studentLessonDatas = GetCoworkData(lessonBase, timeLineData, coworkDatas, studentLessonDatas);
- studentLessonDatas = GetExamData(lessonBase, timeLineData, examDatas, studentLessonDatas);
- studentLessonDatas = GetSmartRatingData(lessonBase, timeLineData, smartRatingDatas, studentLessonDatas);
- studentLessonDatas = GetTaskData(lessonBase, timeLineData, taskDatas, studentLessonDatas);
- }
- return Ok( new { studentLessonDatas });
- }return Ok();
-
- }
-
-
- [HttpPost("process-preview")]
- public async Task<IActionResult> ProcessPreview(JsonElement json)
- {
- string path = $"F:\\lesson-local";
- var files = ListAllFiles(path);
- List<TechCount> techCounts = new List<TechCount>();
- //var files_count = files.Where(x => x.EndsWith("548724334458441728-count.json")).Take(100).ToList();
- /*
- "examCount": 0,
- "taskCount": 0,
- "irsCount": 1,
- "coworkCount": 0,
- "smartRatingCount": 0,
- "timeCount":
- */
- bool loadLocal = true;
- LessonDataAnalysis lessonDataAnalysis = new LessonDataAnalysis();
- var files_anlysis = files.Where(x => x.EndsWith("analysis.json")).Take(1).FirstOrDefault();
- if (files_anlysis!=null) {
- string jsons = await System.IO.File.ReadAllTextAsync(files_anlysis);
- lessonDataAnalysis= jsons.ToObject<LessonDataAnalysis>();
- loadLocal=false;
- }
- if (loadLocal) {
- foreach (var item in files)
- {
- if (item.EndsWith("count.json"))
- {
- string jsons = await System.IO.File.ReadAllTextAsync(item);
- TechCount count = jsons.ToObject<TechCount>();
- var pickupResult = count.timeCount.Where(x => x.code.Equals("PickupResult", StringComparison.OrdinalIgnoreCase));
- int pickCount = 0;
- if (pickupResult!=null && pickupResult.Count()>0)
- {
- pickCount+=pickupResult.Sum(x => (int)x.value);
- }
- count.interactNormalCount=pickCount+ count.irsCount;
- count.lessonId=item.Replace("-count.json", "").Replace(path, "").Replace("\\", "");
- string localjson = await System.IO.File.ReadAllTextAsync($"{path}\\{count.lessonId}-local.json");
- var lessonLocal = localjson.ToObject<LessonLocal>();
- if (lessonLocal?.lessonBase?.summary!=null) {
- count.smartRatingCountBase=lessonLocal.lessonBase.summary.smartRatingCount;
- count.irsCountBase=lessonLocal.lessonBase.summary.interactionCount;
- count.taskCountBase=lessonLocal.lessonBase.summary.collateTaskCount;
- count.coworkCountBase=lessonLocal.lessonBase.summary.coworkTaskCount;
- count.examCountBase=lessonLocal.lessonBase.summary.examCount;
- count.interactNormalCountBase= count.interactNormalCount;
- }
- if (lessonLocal?.lessonBase?.report?.clientSummaryList!=null)
- {
- count.pscore= lessonLocal.lessonBase.report.clientSummaryList.Where(x=>x.score>0).Select(x => x.score);
- count.gscore= lessonLocal.lessonBase.report.clientSummaryList.Where(x => x.groupScore>0).Select(x => x.groupScore);
- count.tscore= lessonLocal.lessonBase.report.clientSummaryList.Where(x => x.interactScore>0).Select(x => x.interactScore);
- }
- await System.IO.File.WriteAllTextAsync(item, count.ToJsonString());
- techCounts.Add(count);
- }
- }
- Console.WriteLine($"techCounts:{techCounts.Count}");
- //标准差偏差N倍,视为异常数据
- int thresholdMultiplier = 2;
- lessonDataAnalysis.pscore = techCounts.SelectMany(x =>x.pscore);
- lessonDataAnalysis.pscore= CleanDataBySDThreshold(lessonDataAnalysis.pscore, thresholdMultiplier).OrderBy(x => x);
- List<KeyValuePair<double, List<double>>> clustersDataPscore = new();
- var clusterPscore = KMeansService.KMeans(lessonDataAnalysis.pscore.Select(x => x).OrderBy(x => x));
- foreach (var item in clusterPscore)
- {
- Console.WriteLine($"dp:{item.Key} ,avg: {item.Value.Average()}, count: {item.Value.Count}, min:{item.Value.Min()}, max:{item.Value.Max()}");
- }
- Console.WriteLine($"avg: {lessonDataAnalysis.pscore.Average()}");
- foreach (var s in clusterPscore.OrderBy(x => x.Key))
- {
- clustersDataPscore.Add(s);
- }
- lessonDataAnalysis.clustersPscore=clustersDataPscore;
- lessonDataAnalysis.gscore = techCounts.SelectMany(x => x.gscore);
- lessonDataAnalysis.gscore= CleanDataBySDThreshold(lessonDataAnalysis.gscore, thresholdMultiplier).OrderBy(x => x);
- List<KeyValuePair<double, List<double>>> clustersDataGscore = new();
- var clusterGscore = KMeansService.KMeans(lessonDataAnalysis.gscore.Select(x => x).OrderBy(x => x));
- foreach (var item in clusterGscore)
- {
- Console.WriteLine($"dp:{item.Key} ,avg: {item.Value.Average()}, count: {item.Value.Count}, min:{item.Value.Min()}, max:{item.Value.Max()}");
- }
- Console.WriteLine($"avg: {lessonDataAnalysis.gscore.Average()}");
- foreach (var s in clusterGscore.OrderBy(x => x.Key))
- {
- clustersDataGscore.Add(s);
- }
- lessonDataAnalysis.clustersGscore=clustersDataGscore;
- lessonDataAnalysis.tscore = techCounts.SelectMany(x => x.tscore);
- lessonDataAnalysis.tscore= CleanDataBySDThreshold(lessonDataAnalysis.tscore, thresholdMultiplier).OrderBy(x => x);
- List<KeyValuePair<double, List<double>>> clustersDataTscore = new();
- var clusterTscore = KMeansService.KMeans(lessonDataAnalysis.tscore.Select(x => x).OrderBy(x => x));
- foreach (var item in clusterTscore)
- {
- Console.WriteLine($"dp:{item.Key} ,avg: {item.Value.Average()}, count: {item.Value.Count}, min:{item.Value.Min()}, max:{item.Value.Max()}");
- }
- Console.WriteLine($"avg: {lessonDataAnalysis.tscore.Average()}");
- foreach (var s in clusterTscore.OrderBy(x => x.Key))
- {
- clustersDataTscore.Add(s);
- }
- lessonDataAnalysis.clustersTscore=clustersDataTscore;
- lessonDataAnalysis.cowork = techCounts.Where(x => x.coworkCount>0).Select(x => (double)x.coworkCount);
- lessonDataAnalysis.cowork= CleanDataBySDThreshold(lessonDataAnalysis.cowork, thresholdMultiplier);
- lessonDataAnalysis.coworkBase = techCounts.Where(x => x.coworkCountBase>0).Select(x => (double)x.coworkCountBase);
- lessonDataAnalysis.coworkBase= CleanDataBySDThreshold(lessonDataAnalysis.coworkBase, thresholdMultiplier);
- lessonDataAnalysis.task = techCounts.Where(x => x.taskCount > 0).Select(x => (double)x.taskCount);
- lessonDataAnalysis.task= CleanDataBySDThreshold(lessonDataAnalysis.task, thresholdMultiplier);
- lessonDataAnalysis.taskBase = techCounts.Where(x => x.taskCountBase > 0).Select(x => (double)x.taskCountBase);
- lessonDataAnalysis.taskBase = CleanDataBySDThreshold(lessonDataAnalysis.taskBase, thresholdMultiplier);
- lessonDataAnalysis.exam = techCounts.Where(x => x.examCount > 0).Select(x => (double)x.examCount);
- lessonDataAnalysis.exam = CleanDataBySDThreshold(lessonDataAnalysis.exam, thresholdMultiplier);
- lessonDataAnalysis.examBase = techCounts.Where(x => x.examCountBase > 0).Select(x => (double)x.examCountBase);
- lessonDataAnalysis.examBase = CleanDataBySDThreshold(lessonDataAnalysis.examBase, thresholdMultiplier);
- lessonDataAnalysis.smartRating = techCounts.Where(x => x.smartRatingCount > 0).Select(x => (double)x.smartRatingCount);
- lessonDataAnalysis.smartRating = CleanDataBySDThreshold(lessonDataAnalysis.smartRating, thresholdMultiplier);
- lessonDataAnalysis.smartRatingBase = techCounts.Where(x => x.smartRatingCountBase > 0).Select(x => (double)x.smartRatingCountBase);
- lessonDataAnalysis.smartRatingBase = CleanDataBySDThreshold(lessonDataAnalysis.smartRatingBase, thresholdMultiplier);
- lessonDataAnalysis.irs = techCounts.Where(x => x.irsCount > 0).Select(x => (double)x.irsCount);
- lessonDataAnalysis.irs = CleanDataBySDThreshold(lessonDataAnalysis.irs, thresholdMultiplier);
- lessonDataAnalysis.interactNormal = techCounts.Where(x => x.interactNormalCount > 0).Select(x => (double)x.interactNormalCount);
-
- Console.WriteLine($"interactNormal{lessonDataAnalysis.interactNormal.Count()}");
- lessonDataAnalysis.interactNormal= CleanDataBySDThreshold(lessonDataAnalysis.interactNormal, thresholdMultiplier).OrderBy(x => x);
- Console.WriteLine($"interactNormal{lessonDataAnalysis.interactNormal.Count()}");
- var tcount = techCounts.Where(x => x.coworkCount > 0 || x.taskCount>0 || x.interactNormalCount>0|| x.examCount>0 || x.smartRatingCount>0);
- double coworkWeight = lessonDataAnalysis.cowork.Count()*1.0/tcount.Count();
- lessonDataAnalysis.coworkWeight=coworkWeight;
- double taskWeight = lessonDataAnalysis.task.Count()*1.0/tcount.Count();
- lessonDataAnalysis.taskWeight=taskWeight;
- double interactWeight = lessonDataAnalysis.interactNormal.Count()*1.0/tcount.Count();
- lessonDataAnalysis.interactWeight=interactWeight;
- double examWeight = lessonDataAnalysis. exam.Count()*1.0/tcount.Count();
- lessonDataAnalysis.examWeight=examWeight;
- double smartRatingWeight = lessonDataAnalysis. smartRating.Count()*1.0/tcount.Count();
- lessonDataAnalysis.smartRatingWeight=smartRatingWeight;
- List<KeyValuePair<double, List<int>>> clustersDataInteract = new();
- var clusterInteract = KMeansService.KMeans(lessonDataAnalysis.interactNormal.Select(x => (int)x).OrderBy(x => x));
- foreach (var item in clusterInteract)
- {
- Console.WriteLine($"dp:{item.Key} ,avg: {item.Value.Average()}, count: {item.Value.Count}, min:{item.Value.Min()}, max:{item.Value.Max()}");
- }
- foreach (var s in clusterInteract.OrderBy(x => x.Key))
- {
- clustersDataInteract.Add(s);
- }
- lessonDataAnalysis.clustersInteract=clustersDataInteract;
- var groups = techCounts.SelectMany(x => x.timeCount).GroupBy(x => x.code).Select(x => new { key = x.Key, list = x.ToList() });
- Dictionary<string, IEnumerable<double>> techDict = new Dictionary<string, IEnumerable<double>>();
- foreach (var group in groups)
- {
- var array = group.list.Where(x => x.value>0).Select(x => (double)x.value);
- array = CleanDataBySDThreshold(array, thresholdMultiplier);
- techDict.Add(group.key, array);
- }
- System.IO. File.WriteAllText(Path.Combine(path, "analysis.json"), lessonDataAnalysis.ToJsonString());
- }
-
-
- List<LessonLocal> lessons = new List<LessonLocal>();
- var files_local = files.Where(x=>x.EndsWith("608942756458532864-local.json")).Take(100).ToList();
- foreach (var item in files_local)
- {
- if (item.EndsWith("local.json"))
- {
- string jsons = await System.IO.File.ReadAllTextAsync(item);
- LessonLocal lesson = jsons.ToObject<LessonLocal>();
- lessons.Add(lesson);
- lesson.studentLessonDatas = GetIRSData(lesson.lessonBase!, lesson.timeLineData!, lesson.irsDatas, lesson.studentLessonDatas, lesson.examDatas);
- lesson.studentLessonDatas = GetCoworkData(lesson.lessonBase!, lesson.timeLineData!, lesson.coworkDatas, lesson.studentLessonDatas);
- lesson.studentLessonDatas = GetExamData(lesson.lessonBase!, lesson.timeLineData!, lesson.examDatas, lesson.studentLessonDatas);
- lesson.studentLessonDatas = GetSmartRatingData(lesson.lessonBase!, lesson.timeLineData!, lesson.smartRatingDatas, lesson.studentLessonDatas);
- lesson.studentLessonDatas = GetTaskData(lesson.lessonBase!, lesson.timeLineData!, lesson.taskDatas, lesson.studentLessonDatas);
- var techCount = techCounts.Find(x => !string.IsNullOrWhiteSpace(x.lessonId) && !string.IsNullOrWhiteSpace(lesson?.lessonRecord?.id) && x.lessonId.Equals(lesson.lessonRecord.id));
- if (techCount != null)
- {
-
- IEnumerable<double> interact = lessonDataAnalysis.interactNormal;
- int interactCount = techCount.interactNormalCount;
- //当前课例的互动次数在互动总列表超过N%;
- //var persent = GetPersent(interact, interactCount);
- foreach (var studentLessonData in lesson.studentLessonDatas)
- {
- //互动的计分相关的
- var x = 0.0;
- //互动参与度相关的
- var y = 0.0;
- //i互动计分,s个人计分
- double i = 0, s = 0;
- if (lesson?.lessonBase?.report?.clientSummaryList!=null)
- {
- var d = lesson?.lessonBase?.report?.clientSummaryList.Find(x => $"{x.seatID}".Equals(studentLessonData.seatID));
- if (d!=null)
- {
- i=d.interactScore;
- s =d.score;
- }
- }
- //个人计分最大值
- var q = lessonDataAnalysis.pscore.Max();
- //互动计分最大值
- var t = lessonDataAnalysis.tscore.Max();
- if (studentLessonData.interactRecord.interactRecords.Count==interactCount && interactCount>0)
- {
- //互动次数
- var n = studentLessonData.interactRecord.interactRecords.Count()*1.0;
- //聚类分数量大和数量小的类群。判断当前出题数在两个类群的最大范围内,再取其质心。
- 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;
- var k = studentLessonData.interactRecord.interactRecords.Where(x => x.resultWeight>=InteractWeight.T1).Sum(x=> x.itemScore*1.0);
- var e = studentLessonData.interactRecord.interactRecords.Where(x => x.resultWeight>InteractWeight.T1).Sum(x => x.itemScore*1.0);
- var j = InteractWeight.T1;
- //学习成效算法
- //x=((i/t) + ((n/m)*(w*(w/n)+(p/j)* (r/n) *r)))/n;
- x=((i/t) +(w*k)/(j*m) +(r*e)/(j*m) )/n;
- y=((n/m)*(w*(w/n)+ (r/n) *r))/n;
- // var rate = w*100.0/interactCount;
- // studentLessonData.interactRecord.interactScore=data;
- // studentLessonData.interactRecord.interactRate=rate;
- }
- else
- {
- if (studentLessonData.interactRecord.interactRecords.Count()!=0)
- {
- Console.WriteLine($"{studentLessonData.id}{lesson?.lessonRecord?.id}的互动次数不匹配。");
- }
- }
- if (studentLessonData.taskRecord.itemRecords.Count>0)
- {
-
- }
- var attend = 0.0;
- if (studentLessonData.attend==1)
- {
- attend= 100/100;
- }
- var achieve = 190.0/(1+Math.Exp(-(s/q+x)))-95.0;
- var attitude= 200 / (1 + Math.Exp(-(s/q + y +attend))) - 100.0;
- studentLessonData.attitude=attitude;
- studentLessonData.achieve=achieve;
- }
- }
- }
- }
- return Ok(new
- {
- lessons,
- interactNormal = lessonDataAnalysis.interactNormal.OrderByDescending(x=>x),
- cowork = lessonDataAnalysis.cowork.OrderByDescending(x => x),
- exam = lessonDataAnalysis.exam.OrderByDescending(x => x),
- smartRating = lessonDataAnalysis.smartRating.OrderByDescending(x => x),
- });
- }
- [HttpPost("process-history")]
- public async Task<IActionResult> ProcessHistory(JsonElement json)
- {
- //1709222400000 2024.3.1
- var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School)
- .GetList<LessonRecord>($"SELECT value c FROM School AS c where c.startTime>1706716800000 and c.expire<=0 and c.status<>404 and c.duration>300 and c.pk='LessonRecord' and c.school<>'hbcn' and c.school<>'habook' and (c.tLevel>0 or c.pLevel>0) ", null);
- if (result.list.IsNotEmpty())
- {
- List<string> ignore = new List<string>() { "PgJump", "PgRcv", "PgAdd" };
- Stopwatch stopwatch = Stopwatch.StartNew();
- //stopwatch.Start();
- //await GetLessData(result, ignore);
- //stopwatch.Stop();
- //Console.WriteLine($"Elapsed Time: {stopwatch.ElapsedMilliseconds} ms");
- //stopwatch.Reset();
- stopwatch.Start();
- string path = "F:\\lesson-local";
- await foreach (var item in GetLessonLocal(result.list))
- {
- if (item.lessonBase!=null && item.lessonBase.student!=null)
- {
- TechCount techCount = new TechCount
- {
- lessonId=item.lessonRecord?.id,
- examCount = item.examDatas.Count,
- taskCount = item.taskDatas.Count,
- irsCount = item.irsDatas.Count,
- coworkCount = item.coworkDatas.Count,
- smartRatingCount =item.smartRatingDatas.Count,
- timeCount=item.sokratesDatas.Where(x => !ignore.Contains(x.Event) && !x.Event.Contains("End", StringComparison.OrdinalIgnoreCase)).GroupBy(x => x.Event).Select(x => new CodeLong() { code=x.Key, value= x.ToList().Count }).ToList()
- };
- await System.IO.File.WriteAllTextAsync($"{path}\\{item.lessonRecord!.id}-local.json", item.ToJsonString());
- await System.IO.File.WriteAllTextAsync($"{path}\\{item.lessonRecord.id}-count.json", techCount.ToJsonString());
- }
- else {
- Console.WriteLine($"没有课例id的数据:{item.lessonRecord?.id}");
- System.IO.File.Delete($"{path}\\{item.lessonRecord!.id}-local.json");
- System.IO.File.Delete($"{path}\\{item.lessonRecord!.id}-count.json");
- }
-
- }
- stopwatch.Stop();
- Console.WriteLine($"Elapsed Time: {stopwatch.ElapsedMilliseconds} ms");
- }
- return Ok("Lesson records");
- }
- public static List<string> ListAllFiles(string directoryPath)
- {
- List<string> filePaths = new List<string>();
- DirectoryInfo dirInfo = new DirectoryInfo(directoryPath);
- // 获取目录下的所有文件(包括子目录中的文件)
- FileInfo[] files = dirInfo.GetFiles("*", SearchOption.AllDirectories);
- foreach (FileInfo file in files)
- {
- filePaths.Add(file.FullName);
- // Console.WriteLine(file.FullName);
- }
- return filePaths;
- }
- public class LessonDataAnalysis
- {
- public long updateTime { get; set; }
- public IEnumerable<double> cowork { get; set; } = new List<double>();
- public IEnumerable<double> coworkBase { get; set; } = new List<double>();
- public IEnumerable<double> task { get; set; } = new List<double>();
- public IEnumerable<double> taskBase { get; set; } = new List<double>();
- public IEnumerable<double> exam { get; set; } = new List<double>();
- public IEnumerable<double> examBase { get; set; } = new List<double>();
- public IEnumerable<double> smartRating { get; set; } = new List<double>();
- public IEnumerable<double> smartRatingBase { get; set; } = new List<double>();
- public IEnumerable<double> irs { get; set; } = new List<double>();
- public IEnumerable<double> interactNormal { get; set; } = new List<double>();
- public List<KeyValuePair<double, List<int>>> clustersInteract { get; set; } = new List<KeyValuePair<double, List<int>>>();
- public List<KeyValuePair<double, List<double>>> clustersPscore { get; set; } = new List<KeyValuePair<double, List<double>>>();
- public List<KeyValuePair<double, List<double>>> clustersTscore { get; set; } = new List<KeyValuePair<double, List<double>>>();
- public List<KeyValuePair<double, List<double>>> clustersGscore { get; set; } = new List<KeyValuePair<double, List<double>>>();
- /// <summary>
- /// 个人计分
- /// </summary>
- public IEnumerable<double> pscore { get; set; } = new List<double>();
- /// <summary>
- /// 小组计分
- /// </summary>
- public IEnumerable<double> gscore { get; set; } = new List<double>();
- /// <summary>
- /// 互动计分
- /// </summary>
- public IEnumerable<double> tscore { get; set; } = new List<double>();
- public double coworkWeight { get; set; }
- public double taskWeight { get; set; }
- public double interactWeight { get; set; }
- public double examWeight { get; set; }
- public double smartRatingWeight { get; set; }
- }
- /// <summary>
- /// 计算当前元素在集合中超过了多少百分比的值
- /// </summary>
- /// <param name="nums"></param>
- /// <param name="curr"></param>
- /// <returns></returns>
- public static double GetPersent(IEnumerable<double> nums, int curr)
- {
- int count = 0;
- foreach (var op in nums.OrderBy(x => x))
- {
- if (op < curr)
- {
- count++;
- }
- else if (op == curr)
- {
- count++;
- }
- else
- {
- break;
- }
- }
- return count *1.0/ nums.Count() * 100;
- }
- /// <summary>
- /// 使用标准差定义异常值。如果一个数字与平均值的偏差超过某个标准差倍数(例如2倍或3倍),则可以认为它是异常的。
- /// </summary>
- /// <param name="array"></param>
- /// <returns></returns>
- public static List<double> CleanDataBySDThreshold(IEnumerable<double> array, double thresholdMultiplier = 2)
- {
- if (array.Count() == 0) return new List<double>();
- double average = Math.Round(array.Sum()*1.0/array.Count(), 4);
- double variance = array.Select(x => Math.Round(Math.Pow(x - average, 2), 4)).Sum()*1.0/array.Count();
- double standardDeviation = Math.Sqrt(Math.Round(variance, 4));
- double threshold = Math.Round(thresholdMultiplier * standardDeviation);
- List<double> datas = new List<double>();
- foreach (double value in array)
- {
- double deviation = Math.Round(Math.Abs(value - average), 4);
- if (deviation <= threshold)
- {
- datas.Add(value);
- }
- }
- return datas;
- }
- private async IAsyncEnumerable<LessonLocal> GetLessonLocal(List<LessonRecord> lessonRecords)
- {
- foreach (var lessonRecord in lessonRecords)
- {
- LessonLocal lessonLocal = new LessonLocal { lessonRecord=lessonRecord };
- if (System.IO.File.Exists($"F:\\lesson-local\\{lessonRecord.id}-local.json"))
- {
- string jsonp = await System.IO.File.ReadAllTextAsync($"F:\\lesson-local\\{lessonRecord.id}-local.json");
- lessonLocal = jsonp.ToObject<LessonLocal>();
- }
- else
- {
- List<string> files = new List<string>()
- {
- $"/records/{lessonRecord.id}/IES/TimeLine.json",
- $"/records/{lessonRecord.id}/IES/base.json",
- $"/records/{lessonRecord.id}/IES/Task.json",
- $"/records/{lessonRecord.id}/IES/SmartRating.json",
- $"/records/{lessonRecord.id}/IES/IRS.json",
- $"/records/{lessonRecord.id}/IES/Cowork.json",
- $"/records/{lessonRecord.id}/Sokrates/SokratesRecords.json",
- };
- lessonLocal = new LessonLocal { lessonRecord=lessonRecord };
- lessonLocal = await GetLessonFiles(lessonLocal, files, lessonRecord.school);
- }
- if (lessonLocal.lessonBase!=null && lessonLocal.lessonBase.student!=null)
- {
- var baseData = GetBaseData(lessonLocal.lessonBase!);
- lessonLocal.studentLessonDatas= baseData.studentLessonDatas;
- List<ExamData> examDatas = await GetExamData(lessonRecord, lessonLocal.timeLineData);
- lessonLocal.examDatas = examDatas;
- lessonLocal.sokratesDatas= lessonLocal.sokratesDatas.IsNotEmpty() ? lessonLocal.sokratesDatas : lessonLocal.timeLineData!=null ? lessonLocal.timeLineData.events : new List<TimeLineEvent>();
- }
- yield return lessonLocal;
- }
- }
- private async Task<LessonLocal> GetLessonFiles(LessonLocal lessonLocal, List<string> files, string school)
- {
- await Parallel.ForEachAsync(files, async (file, _) =>
- {
- try
- {
- BlobDownloadResult blobDownloadResult = await _azureStorage.GetBlobContainerClient(school).GetBlobClient(file).DownloadContentAsync();
- switch (true)
- {
- case bool when file.Contains("IES/TimeLine.json"):
- lessonLocal.timeLineData= blobDownloadResult.Content.ToObjectFromJson<TimeLineData>();
- break;
- case bool when file.Contains("IES/base.json"):
- lessonLocal.lessonBase= blobDownloadResult.Content.ToObjectFromJson<LessonBase>();
- break;
- case bool when file.Contains("IES/Task.json"):
- lessonLocal.taskDatas= blobDownloadResult.Content.ToObjectFromJson<List<TaskData>>();
- break;
- case bool when file.Contains("IES/SmartRating.json"):
- lessonLocal.smartRatingDatas= blobDownloadResult.Content.ToObjectFromJson<List<SmartRatingData>>();
- break;
- case bool when file.Contains("IES/IRS.json"):
- lessonLocal.irsDatas= blobDownloadResult.Content.ToObjectFromJson<List<IRSData>>();
- break;
- case bool when file.Contains("IES/Cowork.json"):
- lessonLocal.coworkDatas= blobDownloadResult.Content.ToObjectFromJson<List<CoworkData>>();
- break;
- case bool when file.Contains("Sokrates/SokratesRecords.json"):
- lessonLocal.sokratesDatas= blobDownloadResult.Content.ToObjectFromJson<List<TimeLineEvent>>();
- break;
- }
- }
- catch (Exception ex)
- {
- //Console.WriteLine($"{file}");
- }
- });
- return lessonLocal;
- }
- private async Task GetLessData(CosmosDBResult<LessonRecord> result, List<string> ignore)
- {
- foreach (var item in result.list)
- {
- //读取TimeLine.json
- TimeLineData? timeLineData = null;
- try
- {
- BlobDownloadResult timeLineBlobDownload = await _azureStorage.GetBlobContainerClient(item.school).GetBlobClient($"/records/{item.id}/IES/TimeLine.json").DownloadContentAsync();
- timeLineData = timeLineBlobDownload.Content.ToObjectFromJson<TimeLineData>();
- }
- catch (Exception ex)
- {
- if (!ex.Message.Contains("The specified blob does not exist"))
- {
- _logger.LogError(ex, $"文件不存在:/records/{item.id}/IES/TimeLine.json");
- }
- }
- //读取基础Base信息
- //base.json
- LessonBase? lessonBase = null;
- List<StudentLessonData> studentLessonDatas = new List<StudentLessonData>();
- //名单出席率低于30%的 不纳入计算。,累计所有课例的科技使用次数及反馈情况,用于做科技分类比例的权重
- try
- {
- BlobDownloadResult baseblobDownload = await _azureStorage.GetBlobContainerClient(item.school).GetBlobClient($"/records/{item.id}/IES/base.json").DownloadContentAsync();
- string basejson = baseblobDownload.Content.ToString().Replace("\"Uncall\"", "0").Replace("Uncall", "0");
- lessonBase = basejson.ToObject<LessonBase>();
- var data = GetBaseData(lessonBase);
- studentLessonDatas=data.studentLessonDatas;
- }
- catch (Exception ex)
- {
- if (!ex.Message.Contains("The specified blob does not exist"))
- {
- _logger.LogError(ex, $"文件不存在:/records/{item.id}/IES/base.json");
- }
- }
- //读取Task.json
- ///Event 过滤类型 : 'WrkSpaceLoad'作品收集, 'WrkCmp' 作品贴上 文件:Task.json 根据clientWorks 中的seatID 匹配base.json 中的 student
- List<TaskData> taskDatas = new List<TaskData>();
- try
- {
- BlobDownloadResult taskBlobDownload = await _azureStorage.GetBlobContainerClient(item.school).GetBlobClient($"/records/{item.id}/IES/Task.json").DownloadContentAsync();
- taskDatas = taskBlobDownload.Content.ToObjectFromJson<List<TaskData>>();
- }
- catch (Exception ex)
- {
- if (!ex.Message.Contains("The specified blob does not exist"))
- {
- _logger.LogError(ex, $"文件不存在:/records/{item.id}/IES/Task.json");
- }
- }
- //读取互评信息
- //Event 过滤类型 'RatingStart'
- //smartRateSummary.mutualSummary.mutualType 互评【All(每人多件评分) Two(随机分配互评) Self(自评)】 smartRateSummary.meteor_VoteSummary 投票
- //读取SmartRating.json
- List<SmartRatingData> smartRatingDatas = new List<SmartRatingData>();
- try
- {
- BlobDownloadResult smartRatingBlobDownload = await _azureStorage.GetBlobContainerClient(item.school).GetBlobClient($"/records/{item.id}/IES/SmartRating.json").DownloadContentAsync();
- smartRatingDatas = smartRatingBlobDownload.Content.ToObjectFromJson<List<SmartRatingData>>();
- }
- catch (Exception ex)
- {
- if (!ex.Message.Contains("The specified blob does not exist"))
- {
- _logger.LogError(ex, $"文件不存在:/records/{item.id}/IES/SmartRating.json");
- }
- }
- //读取互动信息
- //Event 过滤类型 'PopQuesLoad', 'ReAtmpAnsStrt', 'BuzrAns','BuzrLoad'
- //TimeLine.json 中找到对应类型,根据Pgid 去 IRS.json 中找到对应数据,从clientAnswers 的下标对应 base.json 中的 student 找到对应学生信息 clientAnswers.length > 1 则表示有二次作答
- //读取IRS.json
- List<IRSData> irsDatas = new List<IRSData>();
- try
- {
- BlobDownloadResult irsBlobDownload = await _azureStorage.GetBlobContainerClient(item.school).GetBlobClient($"/records/{item.id}/IES/IRS.json").DownloadContentAsync();
- irsDatas = irsBlobDownload.Content.ToObjectFromJson<List<IRSData>>();
- }
- catch (Exception ex)
- {
- if (!ex.Message.Contains("The specified blob does not exist"))
- {
- _logger.LogError(ex, $"文件不存在:/records/{item.id}/IES/IRS.json");
- }
- }
- //读取协作信息
- ///Event 过滤类型 'CoworkLoad', "CoworkType":"CoworkGroup",类型
- //Cowork.json 中找到对应类型,根据Pgid 去 Cowork.json 中找到对应数据
- List<CoworkData> coworkDatas = new List<CoworkData>();
- try
- {
- BlobDownloadResult blobDownload = await _azureStorage.GetBlobContainerClient(item.school).GetBlobClient($"/records/{item.id}/IES/Cowork.json").DownloadContentAsync();
- coworkDatas = blobDownload.Content.ToObjectFromJson<List<CoworkData>>();
- }
- catch (Exception ex)
- {
- if (!ex.Message.Contains("The specified blob does not exist"))
- {
- _logger.LogError(ex, $"文件不存在:/records/{item.id}/IES/Cowork.json");
- }
- }
- //苏格拉底SokratesRecords.json
- List<TimeLineEvent> sokrates = new List<TimeLineEvent>();
- try
- {
- BlobDownloadResult blobDownload = await _azureStorage.GetBlobContainerClient(item.school).GetBlobClient($"/records/{item.id}/Sokrates/SokratesRecords.json").DownloadContentAsync();
- sokrates = blobDownload.Content.ToObjectFromJson<List<TimeLineEvent>>();
- }
- catch (Exception ex)
- {
- if (!ex.Message.Contains("The specified blob does not exist"))
- {
- _logger.LogError(ex, $"文件不存在:/records/{item.id}/Sokrates/SokratesRecords.json");
- }
- }
- List<ExamData> examDatas = await GetExamData(item, timeLineData);
- var lessonLocal = new LessonLocal
- {
- examDatas= examDatas,
- coworkDatas= coworkDatas,
- irsDatas = irsDatas,
- smartRatingDatas = smartRatingDatas,
- taskDatas = taskDatas,
- lessonBase = lessonBase,
- timeLineData = timeLineData,
- studentLessonDatas = studentLessonDatas,
- lessonRecord =item,
- sokratesDatas= sokrates.IsNotEmpty() ? sokrates : timeLineData!=null ? timeLineData.events : new List<TimeLineEvent>()
- };
- TechCount techCount = new TechCount
- {
- examCount = examDatas.Count,
- taskCount = taskDatas.Count,
- irsCount = irsDatas.Count,
- coworkCount = coworkDatas.Count,
- smartRatingCount = smartRatingDatas.Count,
- timeCount= sokrates.Where(x => !ignore.Contains(x.Event) && !x.Event.Contains("End", StringComparison.OrdinalIgnoreCase)).GroupBy(x => x.Event).Select(x => new CodeLong() { code=x.Key, value= x.ToList().Count }).ToList()
- };
- string path = "F:\\lesson-local";
- await System.IO.File.WriteAllTextAsync($"{path}\\{item.id}-local.json", lessonLocal.ToJsonString());
- await System.IO.File.WriteAllTextAsync($"{path}\\{item.id}-count.json", techCount.ToJsonString());
- }
- }
- private async Task<List<ExamData>> GetExamData(LessonRecord item, TimeLineData? timeLineData)
- {
- //读取ExamData
- List<ExamData> examDatas = new List<ExamData>();
- try
- {
- var examPages = timeLineData?.events.Where(x => !string.IsNullOrWhiteSpace(x.Pgid) && !string.IsNullOrWhiteSpace(x.ExamId));
- if (examPages!=null && examPages.Count()>0)
- {
- var examsFiles = await _azureStorage.GetBlobContainerClient(item.school).List($"records/{item.id}/Exam");
- var paperFiles = await _azureStorage.GetBlobContainerClient(item.school).List($"records/{item.id}/ExamPaper");
- foreach (var examsFile in examsFiles)
- {
- if (examsFile.EndsWith("Exam.json"))
- {
- ExamData? examData = null;
- try
- {
- BlobDownloadResult examDataDownload = await _azureStorage.GetBlobContainerClient(item.school).GetBlobClient(examsFile).DownloadContentAsync();
- var str = examDataDownload.Content.ToString().Replace("\r\n","").Replace("\ufeff", "").Replace("\"publish\": \"0\"", "\"publish\": 0").Replace("\"publish\": \"1\"", "\"publish\": 1");
- examData= str.ToObject<ExamData>();
- // examData = examDataDownload.Content.ToObjectFromJson<ExamData>();
- }
- catch (Exception ex)
- {
- if (!ex.Message.Contains("The specified blob does not exist"))
- {
- _logger.LogError(ex, $"文件不存在:{examsFile}");
- }
- }
- if (examData!=null && examData.exam.papers.IsNotEmpty())
- {
- string paperId = examData.exam.papers.First().id;
- if (_azureStorage.GetBlobContainerClient(item.school).GetBlobClient($"/records/{item.id}/ExamPaper/{paperId}/index.json").Exists())
- {
- LessonPaper lessonPaper = null;
- try
- {
- BlobDownloadResult paperblobDownload = await _azureStorage.GetBlobContainerClient(item.school).GetBlobClient($"/records/{item.id}/ExamPaper/{paperId}/index.json").DownloadContentAsync();
- lessonPaper = paperblobDownload.Content.ToObjectFromJson<LessonPaper>();
- examData.paper = lessonPaper;
- }
- catch (Exception ex)
- {
- if (!ex.Message.Contains("The specified blob does not exist"))
- {
- _logger.LogError(ex, $"文件不存在:/records/{item.id}/ExamPaper/{paperId}/index.json");
- }
- }
- }
- examDatas.Add(examData);
- }
- }
- }
- }
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, ex.Message);
- }
- return examDatas;
- }
- public class TechCount
- {
- public string? lessonId { get; set;}
- /// <summary>
- /// 评测数量
- /// </summary>
- public int examCount { get; set;}
- /// <summary>
- /// 任务数量
- /// </summary>
- public int taskCount { get; set;}
- /// <summary>
- /// IRS次数
- /// </summary>
- public int irsCount { get; set; }
- /// <summary>
- /// 互动次数
- /// </summary>
- //public int interactExamCount { get; set; }
- /// <summary>
- /// 互动次数
- /// </summary>
- public int interactNormalCount { get; set; }
- /// <summary>
- /// 协作次数
- /// </summary>
- public int coworkCount { get; set; }
- /// <summary>
- /// 智能评分次数
- /// </summary>
- public int smartRatingCount { get; set; }
- public List<CodeLong> timeCount { get; set; } = new List<CodeLong>();
- public IEnumerable<double> pscore { get; set; } = new List<double>();
- public IEnumerable<double> gscore { get; set; } = new List<double>();
- public IEnumerable<double> tscore { get; set; } = new List<double>();
- /// <summary>
- /// 评测数量
- /// </summary>
- public int examCountBase { get; set; }
- /// <summary>
- /// 任务数量
- /// </summary>
- public int taskCountBase { get; set; }
- /// <summary>
- /// IRS次数
- /// </summary>
- public int irsCountBase { get; set; }
- /// <summary>
- /// 互动次数
- /// </summary>
- //public int interactExamCountBase { get; set; }
- /// <summary>
- /// 互动次数
- /// </summary>
- public int interactNormalCountBase { get; set; }
- /// <summary>
- /// 协作次数
- /// </summary>
- public int coworkCountBase { get; set; }
- /// <summary>
- /// 智能评分次数
- /// </summary>
- public int smartRatingCountBase { get; set; }
- }
- /// <summary>
- /// 处理base.json的数据
- /// </summary>
- /// <param name="lessonRecord"></param>
- /// <param name="lessonBase"></param>
- /// <returns></returns>
- private (LessonBase lessonBase, List<StudentLessonData> studentLessonDatas) GetBaseData( LessonBase lessonBase)
- {
- //处理学生定位数据
- List<StudentLessonData> studentLessonDatas = new List<StudentLessonData>();
- int index = 0;
- try {
- if (lessonBase!=null)
- {
- lessonBase.student.ForEach(x =>
- {
- int attend = 0;
- var client = lessonBase.report.clientSummaryList.Find(y => y.seatID == x.seatID);
- if (client!=null)
- {
- attend=client.attendState;
- }
- studentLessonDatas.Add(new StudentLessonData()
- {
- id = x.id,
- index = index,
- seatID =$"{x.seatID}",
- groupId = x.groupId,
- attend= attend
- });
- index++;
- });
- }
-
- } catch (Exception ex) {
- Console.WriteLine(lessonBase.ToJsonString());
- }
- return (lessonBase, studentLessonDatas);
- }
- /// <summary>
- ///读取互动信息
- ///Event 过滤类型 'PopQuesLoad', 'ReAtmpAnsStrt', 'BuzrAns','BuzrLoad'
- /// 在IRS.json处理 'PopQuesLoad'互动问答 , 'ReAtmpAnsStrt' 二次作答 , 'BuzrAns' 抢权(新), 'BuzrLoad'抢权(旧), PickupResult 挑人算不算互动?? 读取PickupMemberId "[\r\n 35\r\n]"
- ///TimeLine.json 中找到对应类型,根据Pgid 去 IRS.json 中找到对应数据,从clientAnswers 的下标对应 base.json 中的 student 找到对应学生信息 clientAnswers.length > 1 则表示有二次作答
- ///读取IRS.json
- /// </summary>
- /// <param name="lessonRecord"></param>
- /// <param name="lessonBase"></param>
- /// <param name="irsDatas"></param>
- /// <returns></returns>
- private List<StudentLessonData> GetIRSData( LessonBase lessonBase, TimeLineData timeLineData, List<IRSData> irsDatas, List<StudentLessonData> studentLessonDatas,List<ExamData> examDatas)
- {
- List<string> interactTypes = new List<string>() { "PopQuesLoad", "ReAtmpAnsStrt", "BuzrAns", "BuzrLoad", "PickupResult" };
- //去重页面
- var enventsInteract = timeLineData.events.Where(x => !string.IsNullOrWhiteSpace(x.Pgid) && interactTypes.Contains(x.Event)).GroupBy(x => x.Pgid) .Select(x => new { key = x.Key, list = x.ToList() });
- if (enventsInteract!= null && enventsInteract.Count()>0)
- {
- var keys = enventsInteract.Select(x => x.key).ToList();
- foreach (var item in enventsInteract)
- {
- ProcessIRSPageData(irsDatas, studentLessonDatas,examDatas, item);
- }
- //处理其他,评测类型的互动,因为有可能不会记录在TimeLine.json中
- var envents_other = timeLineData.events.Where(x =>!string.IsNullOrWhiteSpace(x.Pgid) && !keys.Contains(x.Pgid)).GroupBy(x => x.Pgid) .Select(x => new { key = x.Key, list = x.ToList() });
- if (envents_other!=null && envents_other.Count()>0)
- {
- foreach (var item in envents_other)
- {
- ProcessIRSPageData(irsDatas, studentLessonDatas,examDatas, item);
- }
- }
- }
- else
- {
- //处理其他,评测类型的互动,因为有可能不会记录在TimeLine.json中
- var envents_other = timeLineData.events.Where(x=> !string.IsNullOrWhiteSpace(x.Pgid)).GroupBy(x => x.Pgid) .Select(x => new { key = x.Key, list = x.ToList() });
- if (envents_other!=null && envents_other.Count()>0)
- {
- foreach (var item in envents_other)
- {
- ProcessIRSPageData(irsDatas, studentLessonDatas,examDatas, item);
- }
- }
- }
- //单独处理挑人的逻辑
- //是否从小组里面挑人。
- //不需要去重页面,直接获取挑人大类 PickupResult
- //小类处理:PickupRight , PickupOption , PickupNthGrp ,PickupEachGrp ,PickupDiff
- var enventsPickup = timeLineData.events.Where(x => !string.IsNullOrWhiteSpace(x.Pgid) && x.Event.Equals("PickupResult"));
- if (enventsPickup.IsNotEmpty())
- {
- foreach (var item in enventsPickup)
- {
- List<int> mbrs = item.PickupMemberId.ToObject<List<int>>();
- // 挑人挑中 TT ,没有挑中 T1
- foreach (var studentLessonData in studentLessonDatas)
- {
- var mbr = mbrs.FindAll(x => studentLessonData.seatID!.Equals($"{x}"));
- if (mbr.IsNotEmpty())
- {
- foreach (var m in mbr)
- {
- studentLessonData.attend=1;
- studentLessonData.interactRecord.interactRecords.Add(new ItemRecord()
- {
- resultWeight = InteractWeight.TT,
- resultType=InteractReultType.TT,
- itemType = string.IsNullOrWhiteSpace(item.PickupType) ? "PickupResult" : item.PickupType
- });
- }
- }
- else {
- //处理未挑中的
- if (studentLessonData.attend==1)
- {
- studentLessonData.interactRecord.interactRecords.Add(new ItemRecord()
- {
- resultWeight = InteractWeight.T1,
- resultType=InteractReultType.T1,
- itemType = string.IsNullOrWhiteSpace(item.PickupType) ? "PickupResult" : item.PickupType
- });
- }
- }
- }
- }
- }
- return studentLessonDatas;
- }
- private static List<StudentLessonData> ProcessIRSPageData(List<IRSData> irsDatas, List<StudentLessonData> studentLessonDatas, List<ExamData> examDatas, dynamic item)
- {
- var irsDataPages = irsDatas.Where(y => item.key.Equals(y.pageID));
- foreach (var irsDataPage in irsDataPages)
- {
- //检查是否设置正确答案。
- var answers_q = irsDataPage.question?["exercise"]?["answer"]?.ToJsonString().ToObject<List<string>>();
- //根据题去找对应的试卷和评测信息
- var question_id = $"{irsDataPage.question?["id"]}";
- var examData = examDatas.Where(x =>x.paper!=null && x.paper.slides.Exists(x =>!string.IsNullOrWhiteSpace(x.url) && x.url.Equals($"{question_id}.json"))).FirstOrDefault();
- List<string> answers = new List<string>();
- answers_q?.ForEach(x => {
- if (!string.IsNullOrWhiteSpace(x))
- {
- answers.Add(x);
- }
- });
- var _objective = irsDataPage.question?["exercise"]?["objective"];
- var scoreNode = irsDataPage.question?["exercise"]?["score"];
- var _type = irsDataPage.question?["exercise"]?["type"];
- var _answerType = irsDataPage.question?["exercise"]?["answerType"];//file,audio,text,image
- double questionScore = 0;
- bool objective = false;
-
- if (_objective!=null) {
- objective = _objective.GetValue<bool>();
- }
- //题型
- string type= string.Empty;
- if (_type!=null)
- {
- //题型
- type = _type.GetValue<string>();
- List<string> types = new List<string>() { "single", "multiple" , "judge" , "sortmultiple" };
- if (types.Contains(type))
- {
- objective = true;
- }
- else {
- objective = false;
- }
- }
- if (_answerType!=null)
- {
- _answerType.GetValue<string>();
- //暂不处理,可能存在依然传文字的情况
- //不是文本作答的处理,题目不是客观题,答案不记录
- //if (!_answerType.Equals("text"))
- //{
- // objective=false;
- // answers=new List<string>();
- //}
- }
- if (scoreNode!=null)
- {
- double.TryParse(scoreNode.ToString(), out questionScore);
- }
- string interactType = string.Empty;
- if (irsDataPage.clientAnswers.IsNotEmpty())
- {
- //第一个list是几轮,一次作答,二次作答, 第二个list是学生的下标, 第三个list是 答案
- List<List<List<string>>> clientAnswers = new List<List<List<string>>>();
- foreach (var key in irsDataPage.clientAnswers.Keys)
- {
- clientAnswers.Add(irsDataPage.clientAnswers[key]);
- }
- // 获取第一个列表的长度作为比较基准
- int firstListLength = clientAnswers.First().Count;
- bool isSameLength = true;
- // 遍历剩余的列表并检查它们的长度是否与第一个列表相同
- foreach (var innerList in clientAnswers.Skip(1))
- {
- if (innerList.Count != firstListLength)
- {
- isSameLength = false;
- break;
- }
- }
- //并检查学生集合的长度是否与第一个列表相同
- if (isSameLength && studentLessonDatas.Count()==firstListLength)
- {
- for (int index = 0; index< clientAnswers[0].Count; index++)
- {
- var student = studentLessonDatas[index];
- double studentScore = 0 ;
- if (examData!=null && examData.examClassResult.IsNotEmpty()) {
- var examResultIndex = examData.examClassResult.First().studentIds.IndexOf(student.id);
- var questionIndex = examData.paper.slides.Select(x => x.url).ToList().IndexOf($"{question_id}.json");
- if (examResultIndex>=0
- && examData.examClassResult.First().studentScores.Count>=(examResultIndex+1) //防止索引越界
- && examData.examClassResult.First().studentScores[examResultIndex].Count>=(questionIndex+1)) //防止索引越界
- {
- //获取index学生在questionIndex题的分数
- studentScore = examData.examClassResult.First().studentScores[examResultIndex][questionIndex];
- }
- }
- //index 代表学生下标
- List<ItemRecord> interactRecords = new List<ItemRecord>();
- if (clientAnswers.Count==1)
- {
- //即问即答
- interactType = "PopQuesLoad";
- var ans0 = clientAnswers[0][index];
- var IS0 = GetInteractResultHasAnswer(answers, ans0, objective,type,questionScore, studentScore);
- interactRecords.Add(new ItemRecord()
- {
- resultWeight = IS0.weight,
- resultType=IS0.reultType,
- itemType= interactType,
- criterion= questionScore,
- itemScore= IS0.interactScore
- });
- }
- if (clientAnswers.Count==2)
- {
- //二次作答
- interactType="ReAtmpAnsStrt";
- var ans1 = clientAnswers[1][index];
- var IS1 = GetInteractResultHasAnswer(answers, ans1, objective,type,questionScore,studentScore);
- interactRecords.Add(new ItemRecord()
- {
- resultWeight = IS1.weight,
- resultType=IS1.reultType,
- itemType= interactType,
- criterion= questionScore,
- itemScore= IS1.interactScore
- });
- }
- if (clientAnswers.Count>2)
- {
- //三次作答
- interactType="TeAtmpAnsStrt";
- var ans2 = clientAnswers[2][index];
- var IS2 = GetInteractResultHasAnswer(answers, ans2, objective, type, questionScore, studentScore);
- interactRecords.Add(new ItemRecord()
- {
- resultWeight = IS2.weight,
- resultType=IS2.reultType,
- itemType= interactType,
- criterion= questionScore,
- itemScore= IS2.interactScore
- });
- }
- if (studentLessonDatas[index].attend==1)
- {
- studentLessonDatas[index].interactRecord.interactRecords.AddRange(interactRecords);
- }
- }
- }
- }
- //是否抢权作答的模式
- if (irsDataPage.isBuzz)
- {
- interactType = "BuzrAns";
- //处理参与抢权的
- Dictionary<string, ItemRecord> buzzParticipants = new Dictionary<string, ItemRecord>();
- foreach (var buzzParticipant in irsDataPage.buzzParticipants)
- {
- var studentData = studentLessonDatas.Find(x => x.seatID!.Equals(buzzParticipant));
- if (studentData != null)
- {
- buzzParticipants[buzzParticipant]=new ItemRecord() { resultWeight = InteractWeight.T1, itemType= interactType, resultType= InteractReultType.T1 };
- }
- }
- //处理抢权成功的
- foreach (var buzzClient in irsDataPage.buzzClients)
- {
- buzzParticipants[buzzClient]=new ItemRecord() { resultWeight = InteractWeight.TT, itemType= interactType, resultType= InteractReultType.TT };
- }
- foreach (var studentLessonData in studentLessonDatas)
- {
- if (buzzParticipants.ContainsKey(studentLessonData.seatID!))
- {
- //处理已经有抢权结果的数据
- studentLessonData.attend=1;
- studentLessonData.interactRecord.interactRecords.Add(buzzParticipants[studentLessonData.seatID!]);
- }
- else
- {
- if (studentLessonData.attend==1) {
- //处理未参与抢权的
- studentLessonData.interactRecord.interactRecords.Add(new ItemRecord() { resultWeight = InteractWeight.T0, itemType = interactType,resultType= InteractReultType.T0 });
- }
- }
- }
- }
-
- }
- return studentLessonDatas;
- }
- private static (double weight,string reultType,double interactScore) GetInteractResultHasAnswer(List<string>? answers, List<string> ans0 , bool objective,string type, double questionScore, double studentScore)
- {
- //List<string> ans0 = new List<string>();
- //ans?.ForEach(x => {
- // if (!string.IsNullOrWhiteSpace(x))
- // {
- // ans0.Add(x);
- // }
- // else { ans.Add("");}
- //});
- double weight = InteractWeight.T0;
- string reultType = InteractReultType.T0;
- double interactScore = 0;
- if (answers.IsNotEmpty())
- {
- if (ans0.IsNotEmpty())
- {
- if (objective) //客观题
- {
- //标准答案等于作答的结果
- if (answers!.Count == ans0.Count)
- {
- if (answers.All(item => ans0.Contains(item)))
- {
- //完全正确
- weight= InteractWeight.TT;
- reultType= InteractReultType.TT;
- interactScore= studentScore==0 ? questionScore : studentScore;
- }
- else
- {
- //作答错误
- weight= InteractWeight.T1;
- reultType = InteractReultType.T1;
- interactScore= studentScore;
- }
- }
- //标准答案比作答的结果多
- else if (answers!.Count > ans0.Count)
- {
- if (ans0.All(item => answers.Contains(item)))
- {
- //部分正确
- weight= InteractWeight.TP;
- reultType = InteractReultType.TP;
- // 2 * 0.3 * 10= 6
- interactScore= studentScore==0 ? 1/(InteractWeight.TT-InteractWeight.T1) * (InteractWeight.TP-InteractWeight.T1) * questionScore : studentScore;
- }
- else
- {
- //作答错误
- weight= InteractWeight.T1;
- reultType = InteractReultType.T1;
- interactScore= studentScore;
- }
- }
- //标准答案比作答结果少
- else
- {
- //作答错误
- weight= InteractWeight.T1;
- reultType = InteractReultType.T1;
- interactScore= studentScore;
- }
- }
- else
- {
- //填空题
- if ("complete".Equals(type) && answers!.Count==ans0.Count)
- {
- bool hasT = false;
- bool hasF = false;
- for (int i = 0; i < answers!.Count; i++)
- {
- if (answers[i].Equals(ans0[i]))
- {
- hasT=true;
- }
- else {
- hasF=true;
- }
- }
- if (hasT && !hasF)
- {
- //完全正确
- weight= InteractWeight.TT;
- reultType = InteractReultType.TT;
- interactScore= studentScore==0 ? questionScore : studentScore;
- }
- else if (hasT && hasF)
- {
- //部分正确
- weight= InteractWeight.TP;
- reultType = InteractReultType.TP;
- // 2 * 0.3 * 10= 6
- interactScore= studentScore==0 ? 1/(InteractWeight.TT-InteractWeight.T1) * (InteractWeight.TP-InteractWeight.T1) * questionScore : studentScore;
- }
- else if (!hasT && hasF)
- {
- //没有正确的,但有错误的,代表参与了
- weight= InteractWeight.T1;
- reultType = InteractReultType.T1;
- interactScore= studentScore;
- }
- else if (!hasT && !hasF)
- {
- //没有正确的,也没有错误的,代表没有作答
- weight= InteractWeight.T0;
- reultType = InteractReultType.T0;
- interactScore= studentScore;
- }
- }
- else
- {
- //主观题,完全匹配的
- if (answers!.All(item => ans0.Contains(item)))
- {
- //完全正确
- weight= InteractWeight.TT;
- reultType = InteractReultType.TT;
- interactScore= studentScore==0 ? questionScore : studentScore;
- }
- else
- { // 使用LINQ查询来判断是否有匹配的答案
- bool hasMatchingAnswer = answers!.Intersect(ans0).Any();
- if (hasMatchingAnswer)
- {
- //主观题回答正确即为完全正确
- weight= InteractWeight.TT;
- reultType = InteractReultType.TT;
- interactScore= studentScore==0 ? questionScore : studentScore;
- }
- else
- {
- //优先根据得分与标准分的占比算出得分率,如果没有得分率,如果是直接从互动,不知道是评测的 需要先去评测找作答得分。,则采用Levenshtein距离来评估两个字符串的相似度
- //没有匹配上答案,则采用Levenshtein距离来评估两个字符串的相似度
- if (questionScore>0)
- {
- if (studentScore>0)
- {
- weight = studentScore * 1.0 / questionScore* (InteractWeight.TT-InteractWeight.T1);
- if (weight==InteractWeight.T1)
- {
- reultType = InteractReultType.T1;
- interactScore=studentScore;
- }
- else if (weight>InteractWeight.TT)
- {
- reultType = InteractReultType.TT;
- interactScore=studentScore==0? questionScore:studentScore;
- }
- else
- {
- reultType = InteractReultType.TP;
- // 2 * 0.3 * 10= 6
- interactScore= studentScore==0 ? 1/(InteractWeight.TT-InteractWeight.T1) * (InteractWeight.TP-InteractWeight.T1) * questionScore : studentScore;
- }
- }
- else
- {
- weight=InteractWeight.T1+(CalculateSimilarity(answers![0], ans0[0]) *(InteractWeight.TT-InteractWeight.T1));
- if (weight==InteractWeight.T1)
- {
- reultType = InteractReultType.T1;
- interactScore=studentScore;
- }
- else if (weight>InteractWeight.TT)
- {
- reultType = InteractReultType.TT;
- interactScore=studentScore==0? questionScore:studentScore;
- }
- else
- {
- reultType = InteractReultType.TP;
- // 2 * 0.3 * 10= 6
- interactScore= studentScore==0 ? 1/(InteractWeight.TT-InteractWeight.T1) * (InteractWeight.TP-InteractWeight.T1) * questionScore : studentScore;
- }
- }
- }
- else {
-
- weight=InteractWeight.T1+(CalculateSimilarity(answers![0], ans0[0]) *(InteractWeight.TT-InteractWeight.T1));
- if (weight==InteractWeight.T1)
- {
- reultType = InteractReultType.T1;
- interactScore=studentScore;
- }
- else if (weight>InteractWeight.TT)
- {
- reultType = InteractReultType.TT;
- interactScore=studentScore==0? questionScore:studentScore;
- }
- else {
- reultType = InteractReultType.TP;
- // 2 * 0.3 * 10= 6
- interactScore= studentScore==0 ? 1/(InteractWeight.TT-InteractWeight.T1) * (InteractWeight.TP-InteractWeight.T1) * questionScore : studentScore;
- }
- }
- }
- }
- }
- }
- }
- else
- {
- //没有作答
- weight= InteractWeight.T0;
- reultType = InteractReultType.T0;
- interactScore=studentScore;
- }
- }
- else
- {
- //没有标准答案的情况
- if (ans0.IsNotEmpty())
- {
- bool hasAns = false;
- ans0.ForEach(x => {
- if (!string.IsNullOrWhiteSpace(x)) {
- hasAns = true;
- }
- });
- if (hasAns)
- {
- //作答了
- weight= InteractWeight.T1;
- reultType = InteractReultType.T1;
- interactScore=studentScore;
- }
- else {
- //没有作答
- weight= InteractWeight.T0;
- reultType = InteractReultType.T0;
- interactScore=studentScore;
- }
- }
- else
- {
- //没有作答
- weight= InteractWeight.T0;
- reultType = InteractReultType.T0;
- interactScore=studentScore;
- }
- //如果教师手动给了分或AI评分
- if (questionScore>0 && studentScore>0)
- {
- weight = studentScore * 1.0 / questionScore* (InteractWeight.TT-InteractWeight.T1);
- if (weight==InteractWeight.T1)
- {
- reultType = InteractReultType.T1;
- interactScore=studentScore;
- }
- else if (weight>InteractWeight.TT)
- {
- reultType = InteractReultType.TT;
- interactScore=studentScore==0 ? questionScore : studentScore;
- }
- else
- {
- reultType = InteractReultType.TP;
- // 2 * 0.3 * 10= 6
- interactScore= studentScore==0 ? 1/(InteractWeight.TT-InteractWeight.T1) * (InteractWeight.TP-InteractWeight.T1) * questionScore : studentScore;
- }
- }
- }
- return (weight,reultType,interactScore);
- }
- #region C# 代码 如何判断两句话是否一个意思,非机器学习的算法。使用Levenshtein距离来评估两个字符串的相似度,但是不能判断它们是否表达了同一个意思,后续借助AI实现
- public static double CalculateSimilarity(string s1, string s2)
- {
- int n = s1.Length;
- int m = s2.Length;
- int[,] d = new int[n + 1, m + 1];
- for (int i = 0; i <= n; i++)
- {
- d[i, 0] = i;
- }
- for (int j = 0; j <= m; j++)
- {
- d[0, j] = j;
- }
- for (int i = 1; i <= n; i++)
- {
- for (int j = 1; j <= m; j++)
- {
- int cost = (s1[i - 1] == s2[j - 1]) ? 0 : 1;
- d[i, j] = Math.Min(Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1), d[i - 1, j - 1] + cost);
- }
- }
- return (1.0 - ((double)d[n, m] / Math.Max(s1.Length, s2.Length))) ;
- }
-
- #endregion
- /// <summary>
- /// 获取课中评测数据
- /// </summary>
- /// <param name="lessonRecord"></param>
- /// <param name="lessonBase"></param>
- /// <param name="timeLineData"></param>
- /// <param name="coworkDatas"></param>
- /// <param name="studentLessonDatas"></param>
- /// <returns></returns>
- private List<StudentLessonData> GetExamData( LessonBase lessonBase, TimeLineData timeLineData, List<ExamData> examDatas, List<StudentLessonData> studentLessonDatas)
- {
- foreach (var examData in examDatas)
- {
- //直接取第一个元素的试卷,因为在HiTeach中,只会是一个试卷(一个科目),一个班参与。
- var allocation= examData?.exam?.papers?.FirstOrDefault()?.point?.Sum();
- var answersStd = examData?.exam?.papers?.FirstOrDefault()?.answers;
- List<List<string>> answers= new List<List<string>>();
- if (answersStd!=null)
- {
- answersStd.ForEach(x => //去除[""]此种类型的标准答案,转为[]
- {
- List<string> ans = new List<string>();
- if (x.Count!=0)
- {
- if (x.Count==1)
- {
- if (string.IsNullOrWhiteSpace(x[0]))
- {
- answers.Add(ans);
- }
- else
- {
- answers.Add(x);
- }
- }
- else
- {
- answers.Add(x);
- }
- }
- else {
- answers.Add(ans);
- }
- });
- }
- examData?.examClassResult?.ForEach(item =>{
- //学生下标
- int index = 0;
- if (item.studentAnswersArray.Count()>0
- && item.studentAnswersArray.Count() == item.studentIds.Count() //学生作答数量和学生id数量一致
- && item.studentScores.Count()==item.studentIds.Count()) //学生分数和学生id数量一致
- {
- item.studentAnswersArray.ForEach(stu => {
- var student = studentLessonDatas.Find(x => x.id!.Equals(item.studentIds[index]));
-
- if (student!=null && student.attend==1)
- {
- //是否要判断主观题或者客观题, 多套试卷,有主观题的
- //,如果没获得结果,
- //主观题有回答的:608942756458532864\Clients\18782481024\Ans\27-4341670635487887360-examExchangeAnswerlist
- //27 从1开始的学生序号-4341670635487887360评测编号,内容qNo 是从1开始的题号。
- if (stu.IsNotEmpty() && answers.Count()==stu.Count && examData.exam.papers[0].type.Count()==answers.Count )
- {
- StudentExamRecord studentExam = new StudentExamRecord();
- var studentScore = item.studentScores[index];
- List<ItemRecord> answerRecords = new List<ItemRecord>();
- //题目下标
- int itemIndex = 0;
- stu.ForEach(ans =>
- {
- bool objective = objectiveTypes.Contains(examData.exam.papers[0].type[itemIndex]);
- var questionScore = examData.exam.papers[0].point[itemIndex];
- string type = examData.exam.papers[0].type[itemIndex];
- var res= GetInteractResultHasAnswer(answers[itemIndex], ans, objective, type, questionScore, studentScore[itemIndex]);
- ItemRecord interactRecord = new ItemRecord()
- {
- itemType="SPQStrt",//类型
- resultType=res.reultType,//作答结果类型
- resultWeight=res.weight,//得分权重
- criterion= questionScore,//标准分
- itemScore= studentScore[itemIndex]//得分
- };
- answerRecords.Add(interactRecord);
- itemIndex++;
- });
- studentExam.score= answerRecords.Where(x => x.itemScore>=0).Select(x => x.itemScore).Sum();//得分
- studentExam.scoreRate= allocation.HasValue && allocation.Value>0 ? studentExam.score * 1.0/allocation.Value : 0;//得分率
- studentExam.answerRate= answerRecords.Where(x => x.resultWeight>0).Count()*1.0/studentScore.Count();//作答率
- studentExam.examId=examData.exam.id;
- studentExam.itemRecords=answerRecords;
- student.examRecords.Add(studentExam);
- }
- }
- index++;
- });
- }
- });
- }
- return studentLessonDatas;
- }
- /// <summary>
- /// 协作参与率 态度计算
- /// </summary>
- /// <param name="lessonRecord"></param>
- /// <param name="lessonBase"></param>
- /// <param name="timeLineData"></param>
- /// <param name="coworkDatas"></param>
- /// <param name="studentLessonDatas"></param>
- /// <returns></returns>
- private List<StudentLessonData> GetCoworkData( LessonBase lessonBase, TimeLineData timeLineData, List<CoworkData> coworkDatas, List<StudentLessonData> studentLessonDatas)
- {
- int p = 0;
- foreach (var coworkData in coworkDatas)
- {
- var keys = coworkData.participateLevelList.Keys;
- foreach (var key in keys)
- {
- var student = studentLessonDatas.Find(x => x.seatID!.Equals(key));
- if (student!=null && student.attend==1)
- {
- var score = coworkData.participateLevelList[key];//协作得分,是否是经过指数计算的
- var itemRecord = new ItemRecord { criterion=-1, itemType= coworkData.coworkType, itemScore=score, isGroup= coworkData.coworkType.Equals("Group") ? true : false };
- //不能完全依赖
- if (score>0)
- {
- itemRecord.resultWeight = InteractWeight.TP;
- itemRecord.resultType = InteractReultType.TP;
- }
- else {
- itemRecord.resultWeight = InteractWeight.T0;
- itemRecord.resultType = InteractReultType.T0;
- }
- student.coworkRecord.itemRecords.Add(itemRecord);
- }
- }
- var order = studentLessonDatas.OrderByDescending(x => x.coworkRecord.itemRecords[p].itemScore);
- var maxItems = studentLessonDatas.FindAll(x => x.coworkRecord.itemRecords[p].itemScore==order.First().coworkRecord.itemRecords[p].itemScore);
- var max = studentLessonDatas.FindAll(x => x.coworkRecord.itemRecords[p].itemScore==order.First().coworkRecord.itemRecords[p].itemScore).First().coworkRecord.itemRecords[p].itemScore;
- var min = studentLessonDatas.FindAll(x => x.coworkRecord.itemRecords[p].itemScore==order.Last().coworkRecord.itemRecords[p].itemScore).First().coworkRecord.itemRecords[p].itemScore;
- var sum = studentLessonDatas.Sum(x => x.coworkRecord.itemRecords[p].itemScore);
- foreach (var student in studentLessonDatas)
- {
- if (student.attend==1 && student.coworkRecord.itemRecords.Count>=p+1 && 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=InteractWeight.T1+ data * 1.0 / 100 * (InteractWeight.TT-InteractWeight.T1);
- if (maxItems.Select(x => x.seatID).Contains(student.seatID))
- {
- student.coworkRecord.itemRecords[p].resultType= InteractReultType.TT;
- student.coworkRecord.itemRecords[p].resultWeight= InteractWeight.TT;
- }
- }
- }
- p++;
- }
-
- return studentLessonDatas;
- }
- /// <summary>
- /// 处理学生回推数据,并将回推纳入学习态度计算。
- /// </summary>
- /// <param name="lessonRecord"></param>
- /// <param name="lessonBase"></param>
- /// <param name="timeLineData"></param>
- /// <param name="taskDatas"></param>
- /// <param name="studentLessonDatas"></param>
- /// <returns></returns>
- private List<StudentLessonData> GetTaskData( LessonBase lessonBase, TimeLineData timeLineData, List<TaskData> taskDatas, List<StudentLessonData> studentLessonDatas)
- {
- //协作也算任务的一种,'WrkSpaceLoad' 作品收集, "isGroupItem": false,
- int indexTask = 0;
- foreach (var taskData in taskDatas)
- {
- //作品收集是全部人员都要参加
- foreach (var student in studentLessonDatas)
- {
- if (student.attend==1)
- {
- var work = taskData.clientWorks.Find(x =>$"{x.seatID}".Equals(student.seatID));
- if (work!= null)
- {
- student.taskRecord.itemRecords.Add(new ItemRecord { itemType="WrkSpaceLoad", itemScore=10, resultWeight=InteractWeight.T1, resultType=InteractReultType.T1, isGroup= work.isGroupItem });
- }
- else
- {
- student.taskRecord.itemRecords.Add(new ItemRecord { itemType="WrkSpaceLoad", itemScore=0, resultWeight=InteractWeight.T0, resultType=InteractReultType.T0, isGroup= false });
- }
- }
- }
- ////////
- ///需要处理小组的情况,当前人员没有提交作品,但是有可能是小组其他人员提交了,需要判断一下。
- ///
- var groupIdsA = studentLessonDatas.FindAll(x => x.attend==1 && x.taskRecord.itemRecords[indexTask].isGroup==true).GroupBy(x=>x.groupId).Select(x=>x.Key);
- foreach (var groupId in groupIdsA)
- {
- var groupStudents= studentLessonDatas.FindAll(x => x.attend==1 && !string.IsNullOrWhiteSpace(x.groupId) && x.groupId.Equals(groupId));
- foreach (var student in groupStudents)
- {
- student.taskRecord.itemRecords[indexTask].isGroup=true;
- }
- }
- var groupIdsB = taskData.clientWorks.FindAll(x => x.seatID==0 && x.isGroupItem).Select(x => x.groupID).Distinct() ;
- foreach (var groupId in groupIdsB)
- {
- var groupStudents = studentLessonDatas.FindAll(x => x.attend==1 && !string.IsNullOrWhiteSpace(x.groupId) && x.groupId.Equals(groupId));
- foreach (var student in groupStudents)
- {
- student.taskRecord.itemRecords[indexTask].isGroup=true;
- }
- }
- indexTask++;
- }
- return studentLessonDatas;
- }
- /// <summary>
- /// 评分参与率 态度计算
- /// //读取互评信息
- /// /// 评分相关 在SmartRating.json 处理 GrandRating 星光大评分, 投票Voting 和 PeerAssessment(All每人多件评分,Two随机分配互评, Self自评)
- //Event 过滤类型 'RatingStart'
- //smartRateSummary.mutualSummary.mutualType 互评【All(每人多件评分) Two(随机分配互评) Self(自评)】 smartRateSummary.meteor_VoteSummary 投票
- //读取SmartRating.json
- /// </summary>
- /// <param name="lessonRecord"></param>
- /// <param name="lessonBase"></param>
- /// <param name="timeLineData"></param>
- /// <param name="smartRatingDatas"></param>
- /// <param name="studentLessonDatas"></param>
- /// <returns></returns>
- private List<StudentLessonData> GetSmartRatingData( LessonBase lessonBase, TimeLineData timeLineData, List<SmartRatingData> smartRatingDatas, List<StudentLessonData> studentLessonDatas)
- {
- int index = 0;
- foreach(var smartRatingData in smartRatingDatas)
- {
- string type = "";
- //投票类型的
- var keys_vote = smartRatingData.smartRateSummary?.meteor_VoteSummary?.Keys?.ToList();
- if (keys_vote.IsNotEmpty())
- {
- type="Voting";
- bool addData=false;
- foreach (var key in keys_vote!)
- {
-
- var voteDetailResults = smartRatingData.smartRateSummary!.voteDetailResult[key];
- foreach (var student in studentLessonDatas)
- {
- if (student.attend==1)
- {
- //投票是全员参与
- var datasS = voteDetailResults.FindAll(x => x.id.Equals(student.seatID));
- if (datasS.IsNotEmpty())
- {
- //T1,只有评论别人,没被别人评论 或者是评论了别人,但是没有被别人评论,
- student.rateingRecord.itemRecords.Add(new ItemRecord { itemType=type, resultType=InteractReultType.T1, resultWeight = InteractWeight.T1 });
- addData=true;
- }
- else
- { //T0 是没有评论别人,也没被别人评论,
- student.rateingRecord.itemRecords.Add(new ItemRecord { itemType=type, resultType=InteractReultType.T0, resultWeight = InteractWeight.T0 });
- addData=true;
- }
- //T0 是没有评论别人,也没被别人评论,
- //T1,只有评论别人,没被别人评论 或者是评论了别人,但是没有被别人评论,
- //TP 有被别人评论,且评论了别人,
- //TT是评论了别人,且被别人评论次数最高,或者分值最高。
- }
- }
- var meteor_VoteSummary = smartRatingData.smartRateSummary!.meteor_VoteSummary[key];
- var order = meteor_VoteSummary.OrderByDescending(x => x.result);
- var maxItems = meteor_VoteSummary.FindAll(x => x.result==order.First().result);
- var max= meteor_VoteSummary.FindAll(x => x.result==order.First().result).First().result;
- var min = meteor_VoteSummary.FindAll(x => x.result==order.Last().result).First().result;
- var sum = meteor_VoteSummary.Sum(x=>x.result);
- //排名指数计算=( 当前值分数- 298) / (9992 - 298) * (99 - 60) + 60
- //将每个人的积分转化为60-100
- //排名 = (积分 - 最低积分) / (最高积分 - 最低积分) * (最大排名 - 最小排名) + 最小排名
- foreach (var datasD in meteor_VoteSummary)
- {
- //有被人评论或投票
- var student = studentLessonDatas.Find(x => x.seatID!.Equals(datasD.id));
- if (student!=null)
- {
- if (index<student.rateingRecord.itemRecords.Count && student.rateingRecord.itemRecords[index].itemType!.Equals(type))
- {
- if (student.rateingRecord.itemRecords[index].resultType!.Equals(InteractReultType.T0))
- {
- //T1,只有评论别人,没被别人评论 或者是评论了别人,但是没有被别人评论,
- student.rateingRecord.itemRecords[index].resultType= InteractReultType.T1;
- student.rateingRecord.itemRecords[index].resultWeight= InteractWeight.T1;
- }
- else if (student.rateingRecord.itemRecords[index].resultType!.Equals(InteractReultType.T1))
- {
- //TP 有被别人评论,且评论了别人,
- student.rateingRecord.itemRecords[index].resultType= InteractReultType.TP;
-
- var data= MinMaxNormalization(min, max, datasD.result);
- //student.rateingRecord.itemRecords[index].resultWeight= InteractWeight.TP;
- student.rateingRecord.itemRecords[index].resultWeight=InteractWeight.T1+ data * 1.0 / maxRank * (InteractWeight.TT-InteractWeight.T1);
- //获得的票数
- student.rateingRecord.itemRecords[index].itemScore=datasD.result;
- //TT是评论了别人,且被别人评论次数最高,或者分值最高。
- if (maxItems.Select(x => x.id).Contains(student.seatID))
- {
- student.rateingRecord.itemRecords[index].resultType= InteractReultType.TT;
- student.rateingRecord.itemRecords[index].resultWeight= InteractWeight.TT;
- }
- }
- }
- }
- }
- if (addData)
- {
- index++;
- }
- }
- }
- //星光大评分,全员评分
- var keys_GrandRating = smartRatingData.smartRateSummary?.scoreDetailResult?.Keys?.ToList();
- if (keys_GrandRating.IsNotEmpty() && smartRatingData.smartRateSummary!=null && smartRatingData.smartRateSummary.meteor_ScoreSummary.IsNotEmpty())
- {
- bool addData = false;
- type="GrandRating";
- foreach (var student in studentLessonDatas)
- {
- if (student.attend==1)
- {
- if (keys_GrandRating!.Contains(student.seatID!))
- {
- //T1,只有评论别人,没被别人评论 或者是评论了别人,但是没有被别人评论,
- student.rateingRecord.itemRecords.Add(new ItemRecord { itemType=type, resultType=InteractReultType.T1, resultWeight = InteractWeight.T1 });
- addData = true;
- }
- else
- {
- //T0 是没有评论别人,也没被别人评论,
- student.rateingRecord.itemRecords.Add(new ItemRecord { itemType=type, resultType=InteractReultType.T0, resultWeight = InteractWeight.T0 });
- addData = true;
- }
- }
- }
- var order = smartRatingData.smartRateSummary.meteor_ScoreSummary.Where(x => x.result>0).OrderByDescending(x => x.result);
- var maxItems = smartRatingData.smartRateSummary.meteor_ScoreSummary.FindAll(x => x.result==order.First().result);
- var max = smartRatingData.smartRateSummary.meteor_ScoreSummary.FindAll(x => x.result==order.First().result).First().result;
- var min = smartRatingData.smartRateSummary.meteor_ScoreSummary.FindAll(x => x.result==order.Last().result).First().result;
- var sum = smartRatingData.smartRateSummary.meteor_ScoreSummary.Sum(x => x.result);
- foreach (var meteor_ScoreSummary in smartRatingData.smartRateSummary.meteor_ScoreSummary)
- {
- var student= studentLessonDatas.Find(x => x.seatID!.Equals(meteor_ScoreSummary.id));
- if (student!=null)
- {
- if (index<student.rateingRecord.itemRecords.Count && student.rateingRecord.itemRecords[index].itemType!.Equals(type))
- {
- if (student.rateingRecord.itemRecords[index].resultType!.Equals(InteractReultType.T0))
- {
- //T1,只有评论别人,没被别人评论 或者是评论了别人,但是没有被别人评论,
- student.rateingRecord.itemRecords[index].resultType= InteractReultType.T1;
- student.rateingRecord.itemRecords[index].resultWeight= InteractWeight.T1;
- }
- else if (student.rateingRecord.itemRecords[index].resultType!.Equals(InteractReultType.T1))
- {
- //TP 有被别人评论,且评论了别人,
- student.rateingRecord.itemRecords[index].resultType= InteractReultType.TP;
- var data = MinMaxNormalization(min, max, meteor_ScoreSummary.result);
- //student.rateingRecord.itemRecords[index].resultWeight= InteractWeight.TP;
- student.rateingRecord.itemRecords[index].resultWeight= InteractWeight.T1+ data * 1.0 / maxRank * (InteractWeight.TT-InteractWeight.T1);
- //被评论次数
- student.rateingRecord.itemRecords[index].itemScore=meteor_ScoreSummary.result;
- //TT是评论了别人,且被别人评论次数最高,或者分值最高。
- if (maxItems.Select(x => x.id).Contains(student.seatID))
- {
- student.rateingRecord.itemRecords[index].resultType= InteractReultType.TT;
- student.rateingRecord.itemRecords[index].resultWeight= InteractWeight.TT;
- }
- }
- }
- }
- }
- if (addData)
- {
- index++;
- }
- }
- // 互评 PeerAssessment(All每人多件评分,Two随机分配互评, Self自评)
- var keys_PeerAssessment = smartRatingData.smartRateSummary?.mutualDetailSummary?.Keys?.ToList();
- if (keys_PeerAssessment.IsNotEmpty() && smartRatingData.smartRateSummary?.mutualSummary!=null
- && smartRatingData.smartRateSummary.mutualSummary.mutualResults.IsNotEmpty()
- && smartRatingData.smartRateSummary.mutualSummary.materialInfos.IsNotEmpty())
- {
- bool addData = false;
- type="PeerAssessment";
- foreach (var student in studentLessonDatas)
- {
- if (student.attend==1)
- {
- if (keys_PeerAssessment!.Contains(student.seatID!))
- {
- //T1,只有评论别人,没被别人评论 或者是评论了别人,但是没有被别人评论,
- student.rateingRecord.itemRecords.Add(new ItemRecord { itemType=type, resultType=InteractReultType.T1, resultWeight = InteractWeight.T1 });
- addData = true;
- }
- else
- {
- //T0 是没有评论别人,也没被别人评论,
- student.rateingRecord.itemRecords.Add(new ItemRecord { itemType=type, resultType=InteractReultType.T0, resultWeight = InteractWeight.T0 });
- addData = true;
- }
- }
- }
- var order = smartRatingData.smartRateSummary.mutualSummary.mutualResults.Where(x => x.result>0).OrderByDescending(x => x.result);
- var maxItems = smartRatingData.smartRateSummary.mutualSummary.mutualResults.FindAll(x => x.result==order.First().result);
- var max = smartRatingData.smartRateSummary.mutualSummary.mutualResults.FindAll(x => x.result==order.First().result).First().result;
- var min = smartRatingData.smartRateSummary.mutualSummary.mutualResults.FindAll(x => x.result==order.Last().result).First().result;
- var sum = smartRatingData.smartRateSummary.mutualSummary.mutualResults.Sum(x => x.result);
- foreach (var mutualResult in smartRatingData.smartRateSummary.mutualSummary.mutualResults)
- {
- var student = studentLessonDatas.Find(x => x.seatID!.Equals(mutualResult.id));
- if (student!=null)
- {
- if (index<student.rateingRecord.itemRecords.Count && student.rateingRecord.itemRecords[index].itemType!.Equals(type))
- {
- if (student.rateingRecord.itemRecords[index].resultType!.Equals(InteractReultType.T0))
- {
- //T1,只有评论别人,没被别人评论 或者是评论了别人,但是没有被别人评论,
- student.rateingRecord.itemRecords[index].resultType= InteractReultType.T1;
- student.rateingRecord.itemRecords[index].resultWeight= InteractWeight.T1;
- }
- else if (student.rateingRecord.itemRecords[index].resultType!.Equals(InteractReultType.T1))
- {
- //TP 有被别人评论,且评论了别人,
- //最高分和最低分,票数最多和票数最少的占比来计算TP的占比
- student.rateingRecord.itemRecords[index].resultType= InteractReultType.TP;
- var data = MinMaxNormalization(min, max, mutualResult.result);
- //student.rateingRecord.itemRecords[index].resultWeight= InteractWeight.TP;
- student.rateingRecord.itemRecords[index].resultWeight= InteractWeight.T1+ data * 1.0 / maxRank * (InteractWeight.TT-InteractWeight.T1);
- student.rateingRecord.itemRecords[index].itemScore=mutualResult.result;
- //TT是评论了别人,且被别人评论次数最高,或者分值最高。
- if (maxItems.Select(x => x.id).Contains(student.seatID))
- {
- student.rateingRecord.itemRecords[index].resultType= InteractReultType.TT;
- student.rateingRecord.itemRecords[index].resultWeight= InteractWeight.TT;
- }
- }
- }
- }
- }
- if (addData)
- {
- index++;
- }
- }
- }
- return studentLessonDatas;
- }
- /// <summary>
- /// 最小-最大归一化(Min-Max Normalization)算法。这种算法通常用于将数据的特征值缩放到一个指定的范围内,通常是0到1之间,或者任何其他指定的范围。
- /// </summary>
- /// <returns></returns>
- public double MinMaxNormalization(double min ,double max,double x )
- {
- //排名指数计算=( 当前值分数- 298) / (9992 - 298) * (99 - 60) + 60
- //将每个人的积分转化为60-100
- //排名 = (积分 - 最低积分) / (最高积分 - 最低积分) * (最大排名 - 最小排名) + 最小排名
- return x==0 ? 0 : max-min!=0 ? (x - min)*1.0 / (max - min) * (maxRank - minRank) + minRank : (x)*1.0 / (max) * (maxRank - minRank) + minRank;
- }
- }
- public class LessonLocal
- {
- public LessonBase? lessonBase { get; set;}
- public TimeLineData? timeLineData { get; set; }
- public LessonRecord? lessonRecord { get; set; }
- public List<StudentLessonData> studentLessonDatas { get; set; } = new List<StudentLessonData>();
- public List<TaskData> taskDatas { get; set; } = new List<TaskData>();
- public List<SmartRatingData> smartRatingDatas { get; set; } = new List<SmartRatingData>();
- public List<IRSData> irsDatas { get; set; } = new List<IRSData>();
- public List<CoworkData> coworkDatas { get; set; } = new List<CoworkData>();
- public List<ExamData> examDatas { get; set; } = new List<ExamData>();
- public List<TimeLineEvent> sokratesDatas { get; set; } = new List<TimeLineEvent>();
- }
-
- /// 互动参与指数(按倍数的权重设计)
- /// 无二次作答的互动,且未设置正确答案:1.未作答0
- /// 2.已作答1
- ///
- /// 无二次作答的互动,且设置了正确答案:3.未作答0
- /// 4.已作答1
- /// 5.不完全正确1.3
- /// 6.作答正确1.5
- ///
- ///
- /// 有二次作答的互动,且未设置正确答案:7.第一次未作答0,第二次未作答0=》0
- /// 8.第一次已作答1,第二次未作答0=》1
- /// 9.第一次未作答0,第二次已作答1=》1
- /// 10.第一次已作答1,第二次已作答1=》2
- ///
- /// 有二次作答的互动,且设置了正确答案:(16种可能)
- /// 11.第一次未作答0,第二次未作答0=》0
- /// 12.第一次已作答,不完全正确1.3,第二次未作答0=》1.3
- /// 13.第一次已作答,作答正确1.5,第二次未作答0=》1.5
- /// 14.第一次已作答,作答错误1,第二次未作答0=》1
- /// 15.第一次未作答0,第二次已作答,不完全正确1.3=》1.3
- /// 16.第一次未作答0,第二次已作答,作答正确1.5=》1.5
- /// 17.第一次未作答0,第二次已作答,作答错误1=》1
- /// 18.第一次已作答,作答错误1,第二次已作答,作答错误1=》2
- /// 19.第一次已作答,不完全正确1.3,第二次已作答,作答错误1=》2.3
- /// 20.第一次已作答,作答正确1.5,第二次已作答,作答错误1=》2.5
- /// 21.第一次已作答,作答错误1,第二次已作答,不完全正确1.3=》2.3
- /// 22.第一次已作答,作答错误1,第二次已作答,作答正确1.5=》2.5
- /// 23.第一次已作答,不完全正确1.3,第二次已作答,不完全正确1.3=》2.6
- /// 24.第一次已作答,不完全正确1.3,第二次已作答,作答正确1.5=》2.8
- /// 25.第一次已作答,作答正确1.5,第二次已作答,不完全正确1.3=》2.8
- /// 26.第一次已作答,作答正确1.5,第二次已作答,作答正确1.5=》3
- ///
- /// 抢权模式: 27.未参与抢权 0
- /// 28.参与抢权 1
- /// 29.抢权成功 1.5
- /// 挑人时被挑到 30.被挑到 1.5
- /// 有三次作答的互动,且设置了正确答案:(64种可能)
- /*
- 1 未作答0 未作答0 未作答0 0
- 2 未作答0 未作答0 不完全正确1.3 1.3
- 3 未作答0 未作答0 作答正确1.5 1.5
- 4 未作答0 未作答0 作答错误1 1
- 5 未作答0 不完全正确1.3 未作答0 1.3
- 6 未作答0 不完全正确1.3 不完全正确1.3 2.6
- 7 未作答0 不完全正确1.3 作答正确1.5 2.8
- 8 未作答0 不完全正确1.3 作答错误1 2.3
- 9 未作答0 作答正确1.5 未作答0 1.5
- 10 未作答0 作答正确1.5 不完全正确1.3 2.8
- 11 未作答0 作答正确1.5 作答正确1.5 3
- 12 未作答0 作答正确1.5 作答错误1 2.5
- 13 未作答0 作答错误1 未作答0 1
- 14 未作答0 作答错误1 不完全正确1.3 2.3
- 15 未作答0 作答错误1 作答正确1.5 2.5
- 16 未作答0 作答错误1 作答错误1 2
- 17 已作答错误1 未作答0 未作答0 1
- 18 已作答错误1 未作答0 不完全正确1.3 2.3
- 19 已作答错误1 未作答0 作答正确1.5 2.5
- 20 已作答错误1 未作答0 作答错误1 2
- 21 已作答错误1 不完全正确1.3 未作答0 2.3
- 22 已作答错误1 不完全正确1.3 不完全正确1.3 3.6
- 23 已作答错误1 不完全正确1.3 作答正确1.5 3.8
- 24 已作答错误1 不完全正确1.3 作答错误1 3.3
- 25 已作答错误1 作答正确1.5 未作答0 2.5
- 26 已作答错误1 作答正确1.5 不完全正确1.3 3.8
- 27 已作答错误1 作答正确1.5 作答正确1.5 4
- 28 已作答错误1 作答正确1.5 作答错误1 3.5
- 29 已作答错误1 作答错误1 未作答0 2
- 30 已作答错误1 作答错误1 不完全正确1.3 3.3
- 31 已作答错误1 作答错误1 作答正确1.5 3.5
- 32 已作答错误1 作答错误1 作答错误1 3
- 33 已作答不完全正确1.3 未作答0 未作答0 1.3
- 34 已作答不完全正确1.3 未作答0 不完全正确1.3 2.6
- 35 已作答不完全正确1.3 未作答0 作答正确1.5 2.8
- 36 已作答不完全正确1.3 未作答0 作答错误1 2.3
- 37 已作答不完全正确1.3 不完全正确1.3 未作答0 2.6
- 38 已作答不完全正确1.3 不完全正确1.3 不完全正确1.3 3.9
- 39 已作答不完全正确1.3 不完全正确1.3 作答正确1.5 4.1
- 40 已作答不完全正确1.3 不完全正确1.3 作答错误1 3.6
- 41 已作答不完全正确1.3 作答正确1.5 未作答0 2.8
- 42 已作答不完全正确1.3 作答正确1.5 不完全正确1.3 4.1
- 43 已作答不完全正确1.3 作答正确1.5 作答正确1.5 4.3
- 44 已作答不完全正确1.3 作答正确1.5 作答错误1 3.8
- 45 已作答不完全正确1.3 作答错误1 未作答0 2.3
- 46 已作答不完全正确1.3 作答错误1 不完全正确1.3 3.6
- 47 已作答不完全正确1.3 作答错误1 作答正确1.5 3.8
- 48 已作答不完全正确1.3 作答错误1 作答错误1 3.3
- 49 已作答正确1.5 未作答0 未作答0 1.5
- 50 已作答正确1.5 未作答0 不完全正确1.3 2.8
- 51 已作答正确1.5 未作答0 作答正确1.5 3
- 52 已作答正确1.5 未作答0 作答错误1 2.5
- 53 已作答正确1.5 不完全正确1.3 未作答0 2.8
- 54 已作答正确1.5 不完全正确1.3 不完全正确1.3 4.1
- 55 已作答正确1.5 不完全正确1.3 作答正确1.5 4.3
- 56 已作答正确1.5 不完全正确1.3 作答错误1 3.8
- 57 已作答正确1.5 作答正确1.5 未作答0 3
- 58 已作答正确1.5 作答正确1.5 不完全正确1.3 4.3
- 59 已作答正确1.5 作答正确1.5作答正确1.5 4.5
- 60 已作答正确1.5 作答正确1.5作答错误1 4
- 61 已作答正确1.5 作答错误1 未作答0 2.5
- 62 已作答正确1.5 作答错误1 不完全正确1.3 3.8
- 63 已作答正确1.5 作答错误1 作答正确1.54
- 64 已作答正确1.5 作答错误1 作答错误1 3.5
- */
- /*
- *
- /// 事件
- /// 推送相关 在Push.json处理 DifObjPush 推送给学生 差异化推送 "PushMemberId":[1,4,8,12,17,18,19,23,24,27,32,36] ,FastPgPush 同一推送
- /// 互动相关 在IRS.json处理 'PopQuesLoad'互动问答 , 'ReAtmpAnsStrt' 二次作答 , 'BuzrAns' 抢权(新), 'BuzrLoad'抢权(旧), PickupResult 挑人算不算互动?? 读取PickupMemberId "[\r\n 35\r\n]"
- /// 测验相关 在IRS.json处理 SPQStrt 测验模式
- /// 任务相关 在Task.json处理 'WrkSpaceLoad' 作品收集, 'WrkCmp' 作品贴上 是什么操作
- /// 评分相关 在SmartRating.json 处理 'SmartRating' 评分模式,分 投票Voting 和 GrandRating 星光大评分(All每人多件评分,Two随机分配互评, Self自评)
- /// 协作相关 在Cowork.json 处理 CoworkLoad 协作类型 coworkType All: '全体协作', Group: '分组协作', 其他的为 : '差异化协作',
- 问题汇总:
- TimeLine.json
- 挑人大类 Event= PickupResult 里面 分小类
- PickupType=PickupRight , PickupOption , PickupNthGrp ,PickupEachGrp ,PickupDiff 五种类型分别是什么意思,是否还有其他类型的。
- ,"PickupCount":1,"PickupOption":2 ,"PickupGroup":2 这三个字段是什么意思。
- "PickupMemberId":"[\r\n 1\r\n]" 里面是学生的座号还是数组下标。
- "Event":"PressGood","TargetClass":0,"MemberId":"[\r\n 1\r\n]","Count":1},
- 是代表什么意思。 MemberId 是座号还说下标。
- 8月27日 17:581. Task.json的 clientWorks.isGroupItem bool 类型 false代表什么意思 true代表什么意思
- 2. Cowork.json 的 coworkType All: '全体协作', Group: '分组协作', : '差异化协作', 差异化协作的简码是什么?
- 3. TimeLine.json 的 类型 PickupResult 挑人算不算互动?? 读取PickupMemberId "[\r\n 35\r\n]"
- 4. 小组任务具体详细信息如何获取? 需要精确到 所有小组任务信息和 某一小组的参与情况 用于计算小组任务参与率
- */
- }
|