123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657 |
- using Microsoft.Azure.Cosmos;
- using ClouDASLibx;
- using Google.Protobuf.WellKnownTypes;
- using Microsoft.AspNetCore.Authorization;
- using Microsoft.AspNetCore.Mvc;
- using Microsoft.Extensions.Options;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Text.Json;
- using System.Threading.Tasks;
- using TEAMModelOS.Filter;
- using TEAMModelOS.SDK;
- using TEAMModelOS.SDK.DI;
- using TEAMModelOS.SDK.Extension;
- using TEAMModelOS.SDK.Helper.Common.StringHelper;
- using TEAMModelOS.SDK.Models;
- using TEAMModelOS.SDK.Models.Cosmos.Student;
- namespace TEAMModelOS.Controllers.Analysis
- {
- [Route("analysis/art")]
- [ApiController]
- public class ArtAnalysisController : ControllerBase
- {
- private readonly AzureCosmosFactory _azureCosmos;
- private readonly DingDing _dingDing;
- private readonly Option _option;
- private readonly CoreAPIHttpService _coreAPIHttpService;
- private readonly AzureStorageFactory _azureStorage;
- public ArtAnalysisController(AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option, CoreAPIHttpService coreAPIHttpService, AzureStorageFactory azureStorage)
- {
- _azureCosmos = azureCosmos;
- _dingDing = dingDing;
- _option = option?.Value;
- _coreAPIHttpService = coreAPIHttpService;
- _azureStorage = azureStorage;
- }
- /* [ProducesDefaultResponseType]
- [HttpPost("find")]
- //[Authorize(Roles = "IES")]
- //[AuthToken(Roles = "teacher,admin")]
- public async Task<IActionResult> find(JsonElement request)
- {
- if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
- var client = _azureCosmos.GetCosmosClient();
- List<ArtEvaluation> arts = new();
- try {
- await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIteratorSql(queryText: $"SELECT top 1 * FROM c where c.period.id ='{period}' order by c.createTime ",
- requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Art-{code}") }))
- {
- using var json = await JsonDocument.ParseAsync(item.Content);
- foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
- {
- arts.Add(obj.ToObject<ArtEvaluation>());
- }
- }
- } catch (Exception ex) {
- await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-analysis/art,find()\n{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
- }
- }*/
- [ProducesDefaultResponseType]
- [HttpPost("statistics")]
- [Authorize(Roles = "IES")]
- [AuthToken(Roles = "teacher,admin")]
- public async Task<IActionResult> getAnalysis(JsonElement request)
- {
- var client = _azureCosmos.GetCosmosClient();
- if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
- if (!request.TryGetProperty("periodId", out JsonElement periodId)) return BadRequest();
- if (!request.TryGetProperty("subjectId", out JsonElement subjectId)) return BadRequest();
- if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
- if (!request.TryGetProperty("classIds", out JsonElement cIds)) return BadRequest();
- if (!request.TryGetProperty("examId", out JsonElement examId)) return BadRequest();
- try
- {
- /*string url = string.Empty;
- if (!_azureStorage.GetBlobContainerClient($"{code}").GetBlobClient($"/art/{id}/{subjectId}.json").Exists())
- {*/
- List<ArtSubjectScore> As = new();
- List<(List<ArtSubjectScore> scs, string sIds, string cd)> stus = new();
- //List<ArtEvaluation> arts = new();
- string artId = id.GetString();
- List<string> classIds = cIds.ToObject<List<string>>();
- if (!request.TryGetProperty("areaId", out JsonElement _areaId)) return BadRequest();
- ArtSetting setting = await client.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemAsync<ArtSetting>($"{_areaId}", partitionKey: new PartitionKey("ArtSetting"));
- //学校基本信息
- School scInfo = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>($"{code}", partitionKey: new PartitionKey("Base"));
- var perMore = scInfo.period.Where(c => c.id.Equals(periodId.GetString())).FirstOrDefault()?.grades;
- string queryScore = $" select c.studentId,c.classIds,c.totalScore,c.subjectScores,c.results from c ";
- if (classIds.Count == 1)
- {
- queryScore = $" select c.studentId,c.classIds,c.totalScore,c.subjectScores,c.results from c where array_contains(c.classIds,'{classIds[0]}') ";
- }
- //List<(string stu,List<string> cId)> clads = new();
- List<List<ArtQuotaResult>> results = new();
- await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryStreamIteratorSql
- (queryText: queryScore, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"ArtResult-{artId}") }))
- {
- using var json = await JsonDocument.ParseAsync(item.Content);
- if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
- {
- foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
- {
- if (obj.TryGetProperty("subjectScores", out JsonElement subScore))
- {
- string sId = obj.GetProperty("studentId").GetString();
- List<ArtSubjectScore> sc = subScore.ToObject<List<ArtSubjectScore>>();
- string cd = obj.GetProperty("classIds").ToObject<List<string>>()[0];
- //clads.Add((sId,obj.GetProperty("classIds").ToObject<List<string>>()));
- As.AddRange(sc);
- stus.Add((sc, sId, cd));
- }
- else
- {
- As.AddRange(new List<ArtSubjectScore>());
- }
- results.Add(obj.GetProperty("results").ToObject<List<ArtQuotaResult>>());
- }
- }
- }
- var subjectScore = new
- {
- name = As.Where(a => a.subjectId.Equals(subjectId.GetString())).Select(x => x.score).Where(c => c > 0)
- };
- double max = subjectScore.name.Max(s => Math.Abs(s));
- double min = subjectScore.name.Min(s => Math.Abs(s));
- double total = subjectScore.name.Sum();
- double average = Math.Round(total / stus.Count, 2);
- double excellent = Math.Round(subjectScore.name.Where(s => s >= 80).Count() * 1.0 / stus.Count, 2);
- double pass = Math.Round(subjectScore.name.Where(s => s >= 60).Count() * 1.0 / stus.Count, 2);
- double powSum = 0;
- foreach (var sc in subjectScore.name)
- {
- powSum += Math.Pow(sc - average, 2);
- }
- var pow = Math.Round(stus.Count > 0 ? Math.Pow(powSum / stus.Count, 0.5) : 0, 2);
- //获取本次评测所有科目结算结果
- List<ExamResult> examResults = new();
- ExamInfo info = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<ExamInfo>(examId.ToString(), new PartitionKey($"Exam-{code}"));
- (List<RMember> tchList, List<RGroupList> classLists) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, classIds, code.GetString(), null,-1,info.startTime);
- //获取评测ID
- //var examId = arts[0].settings.SelectMany(s => s.task).Where(a => a.type == 1 && a.subject.Equals(subjectId.GetString())).FirstOrDefault().acId;
- //根据科目标识获取科目ID以及知识块和知识点关系TODO 引用不同试卷时 获取知识点得差异
- int index = 0;
- foreach (var pr in info.subjects)
- {
- if (pr.id.Equals(subjectId.GetString()))
- {
- break;
- }
- index++;
- }
- List<(string name, List<string> kno)> knos = new();
- if (string.IsNullOrEmpty(info.papers[index].periodId))
- {
- (string subId, List<(string name, List<string> kno)> values) = await getKnowledge("hbcn", client, subjectId.GetString(), "be32942d-97a9-52ba-45d6-2e5b722583f5");
- knos = values;
- }
- else
- {
- (string subId, List<(string name, List<string> kno)> values) = await getKnowledge(info.papers[index].code, client, subjectId.GetString(), info.papers[index].periodId);
- knos = values;
- }
- var query = $"select c.id,c.name,c.subjectId,c.studentScores,c.studentIds,c.paper,c.classes,c.sRate,c.average,c.standard,c.lostStus,c.record,c.phc,c.plc from c where c.examId = '{examId}' and c.subjectId = '{subjectId}' ";
- await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIteratorSql<ExamResult>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamResult-{examId}") }))
- {
- examResults.Add(item);
- }
- List<KeyValuePair<string, List<(string name, double score, double aver)>>> pointPersent = new();
- List<KeyValuePair<string, List<(string name, double score, double point, string sId)>>> stuPersent = new();
- (KeyValuePair<string, List<string>> key1, KeyValuePair<string, List<string>> key2, KeyValuePair<string, List<(string name, double score, double average)>> key3,
- KeyValuePair<string, List<(string name, double score)>> key4, KeyValuePair<string, List<(string name, double score, double point, string cId)>> key5,
- KeyValuePair<string, List<(string name, double score, double point, string sId)>> key6) = DoKnowledgePoint(examResults[0], info);
- //KeyValuePair<string, List<(string id, double sta, double pass, string stu)>> key = DoSubjectScatter(examResults[0]);
- pointPersent.Add(key3);
- stuPersent.Add(key6);
- List<(string name, double score, double av)> blockScore = new();
- List<(string name, double score, double av, string sId)> stuBlockScore = new();
- List<(string name, double score, double av, string cId)> claBlockScore = new();
- foreach (var block in knos)
- {
- double sc = 0;
- double av = 0;
- foreach (var no in pointPersent)
- {
- foreach (var (name, score, aver) in no.Value)
- {
- if (null != block.kno && block.kno.Contains(name))
- {
- sc += score;
- av += aver;
- }
- }
- }
- foreach (var (name, score, point, sId) in key6.Value)
- {
- double realScore = 0;
- double realPoint = 0;
- if (null != block.kno && block.kno.Contains(name))
- {
- realScore = score;
- realPoint = point;
- }
- stuBlockScore.Add((block.name, realScore, realPoint, sId));
- }
- foreach (var (name, score, point, cId) in key5.Value)
- {
- double realScore = 0;
- double realPoint = 0;
- if (null != block.kno && block.kno.Contains(name))
- {
- realScore = score;
- realPoint = point;
- }
- claBlockScore.Add((block.name, realScore, realPoint, cId));
- }
- blockScore.Add((block.name, sc, av));
- }
- var stuBlock = stuBlockScore.GroupBy(x => x.sId).Select(z => new
- {
- z.Key,
- block = z.ToList().GroupBy(c => c.name).Select(k => new
- {
- k.Key,
- score = k.ToList().Sum(p => p.score),
- point = k.ToList().Sum(p => p.av)
- })
- });
- var claBlock = claBlockScore.GroupBy(x => x.cId).Select(z => new
- {
- z.Key,
- block = z.ToList().GroupBy(c => c.name).Select(k => new
- {
- k.Key,
- score = k.ToList().Sum(p => p.score),
- point = k.ToList().Sum(p => p.av)
- })
- });
- var blk = blockScore.Select(x => new
- {
- x.name,
- x.score,
- persent = Math.Round(x.score > 0 ? x.av / x.score : 0, 2),
- dimension = setting.dimensions.Where(s => s.blocks.Contains(x.name)).Select(x => x.dimension)
- });
- //获取维度得分率
- List<(string stuId, double score, double point, string dim)> stuDims = new();
- List<(string claId, double score, double point, string dim)> claDims = new();
- foreach (var dimm in setting.dimensions)
- {
- double dimScore = 0;
- double dimPoint = 0;
- if (dimm.subjectBind.Equals(subjectId.GetString()))
- {
- foreach (var stuDim in stuBlock)
- {
- foreach (var dd in stuDim.block)
- {
- if (dimm.blocks.Contains(dd.Key))
- {
- dimScore += dd.score;
- dimPoint += dd.point;
- }
- }
- stuDims.Add((stuDim.Key, dimScore, dimPoint, dimm.dimension));
- }
- foreach (var claDim in claBlock)
- {
- foreach (var dd in claDim.block)
- {
- if (dimm.blocks.Contains(dd.Key))
- {
- dimScore += dd.score;
- dimPoint += dd.point;
- }
- }
- claDims.Add((claDim.Key, dimScore, dimPoint, dimm.dimension));
- }
- }
- }
- var dim = setting.dimensions.Where(q => q.subjectBind.Equals(subjectId.GetString())).Select(x => new
- {
- x.dimension,
- persent = Math.Round(x.blocks.Select(c => new
- {
- persent =
- blockScore.Where(z => z.name.Equals(c)).Sum(v => v.score) > 0 ?
- blockScore.Where(z => z.name.Equals(c)).Sum(v => v.av) / blockScore.Where(z => z.name.Equals(c)).Sum(v => v.score) : 0
- }).Sum(o => o.persent) / x.blocks.Count, 2)
- });
- var kno = key4.Value.Select(x => new
- {
- x.name,
- x.score,
- block = knos.Where(v => null != v.kno && v.kno.Contains(x.name)).Select(x => x.name)
- });
- //学生信息
- var students = stus.Select(s => new
- {
- id = s.sIds,
- s.scs.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x.subjectId) && x.subjectId.Equals(subjectId.GetString()))?.score,
- tchList.Where(t => t.id.Equals(s.sIds)).FirstOrDefault()?.name,
- classId = s.cd,
- className = examResults[0].classes.Where(c => c.id.Equals(s.cd)).FirstOrDefault()?.name,
- examResults[0].classes.Where(c => c.id.Equals(s.cd)).FirstOrDefault()?.gradeId,
- //key.Value.Where(c => c.id.Equals(s.sIds))?.FirstOrDefault().sta,
- //key.Value.Where(c => c.id.Equals(s.sIds))?.FirstOrDefault().pass,
- // key.Value.Where(c => c.id.Equals(s.sIds))?.FirstOrDefault().stu,
- kno = key6.Value.Where(c => c.sId.Equals(s.sIds))?.Select(z => new
- {
- z.name,
- persent = z.point > 0 ? Math.Round(z.score / z.point, 2) : 0,
- block = knos.Where(v => null != v.kno && v.kno.Contains(z.name))?.Select(x => x.name)
- }),
- block = stuBlock.Where(c => c.Key.Equals(s.sIds)).FirstOrDefault()?.block.Select(x => new
- {
- name = x.Key,
- persent = x.point > 0 ? Math.Round(x.score / x.point, 2) : 0
- }),
- dim = stuDims.Where(c => c.stuId.Equals(s.sIds))?.Select(z => new
- {
- name = z.dim,
- persent = z.point > 0 ? Math.Round(z.score / z.point, 2) : 0
- })
- });
- List<(string cId, double sc, double max, double min, double excellent, double pass, double count)> clsInfo = new();
- var cInfo = students.GroupBy(c => (c.classId, c.className)).Select(x => new
- {
- id = x.Key.classId,
- name = x.Key.className,
- max = x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Count > 0 ? x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Max(s => Math.Abs((double)s)) : 0,
- min = x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Count > 0 ? x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Min(s => Math.Abs((double)s)) : 0,
- excellent = x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Count > 0 ? Math.Round(x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Where(s => s >= 80).Count() * 1.0 / x.ToList().Count, 2) : 0,
- pass = x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Count > 0 ? Math.Round(x.ToList().Where(p => p.score > 0).Select(z => z.score).ToList().Where(s => s >= 60).Count() * 1.0 / x.ToList().Count, 2) : 0,
- score = x.ToList().Count > 0 ? Math.Round((double)x.ToList().Sum(z => z.score) * 1.0 / x.ToList().Count, 2) : 0,
- kno = key5.Value.Where(c => c.cId.Equals(x.Key.classId)).Select(z => new
- {
- z.name,
- persent = Math.Round(z.point > 0 ? z.score / x.ToList().Count / z.point : 0, 2),
- block = knos.Where(v => null != v.kno && v.kno.Contains(z.name)).Select(x => x.name)
- }),
- block = claBlock.Count() > 0 ? claBlock.Where(c => c.Key.Equals(x.Key.classId))?.FirstOrDefault().block.Select(z => new
- {
- name = z.Key,
- persent = Math.Round(z.point > 0 ? z.score / x.ToList().Count / z.point : 0, 2)
- }) : null,
- dim = claDims.Where(c => c.claId.Equals(x.Key.classId)).Select(z => new
- {
- name = z.dim,
- persent = Math.Round(z.point > 0 ? z.score / x.ToList().Count / z.point : 0, 2)
- }),
- examResults[0].classes.Where(c => c.id.Equals(x.Key.classId))?.FirstOrDefault().gradeId
- });
- //年级信息
- var grades = students.GroupBy(c => c.gradeId).Select(x => new { gradeId = x.Key, list = x.ToList().Select(v => v.score).Where(c => c > 0) });
- var gscore = grades.Select(x => new
- {
- id = x.gradeId,
- name = perMore[int.Parse(x.gradeId)],
- score = x.list.Any() ? Math.Round((double)(x.list.Sum() / x.list.Count()), 2) : 0,
- max = x.list.Any() ? x.list.Max(s => Math.Abs((double)s)) : 0,
- min = x.list.Any() ? x.list.Min(s => Math.Abs((double)s)) : 0,
- excellent = x.list.Any() ? Math.Round(x.list.Where(s => s >= 80).Count() * 1.0 / x.list.Count(), 2) : 0,
- pass = x.list.Any() ? Math.Round(x.list.Where(s => s >= 60).Count() * 1.0 / x.list.Count(), 2) : 0
- });
- //获奖次数
- List<ArtAttachment> artAttachments = new();
- string sqlTask = $"select value(c) from c where c.artId = '{id}' and c.subjectId = '{subjectId}'";
- await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).
- GetItemQueryIteratorSql<ArtAttachment>(queryText: sqlTask, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"ArtAttachment-{code}") }))
- {
- artAttachments.Add(item);
- }
- List<int> level = artAttachments.Where(z => z.level > -1).Select(c => c.level).ToList();
- //List<Dictionary<string, int>> recorde = new List<Dictionary<string, int>>();
- Dictionary<int, int> optCount = new Dictionary<int, int>();
- foreach (var s in level)
- {
- if (optCount.ContainsKey(s))
- {
- optCount[s] = optCount[s] + 1;
- }
- else
- {
- optCount[s] = 1;
- }
- }
- //var Analysis_school = new { count = tchList.Count, scount = stus.Count - info.lostStu.Count, max, min, average, excellent, pass, pow, students, cInfo, blk, kno, dim, optCount, gscore };
- //url = await _azureStorage.GetBlobContainerClient($"{code}").UploadFileByContainer(Analysis_school.ToJsonString(), $"art/{id}", $"{subjectId}.json");
- /* }
- else {
- url = _azureStorage.GetBlobContainerClient($"{code}").GetBlobClient($"/art/{id}/{subjectId}.json").Uri.ToString();
- }*/
- var realCount = stus.Count - info.lostStu.Count;
- /*if (classIds.Count == 1)
- {
- return Ok(new { count = tchList.Count, scount = realCount, max, min, average, excellent, pass, pow, blk, kno, dim, optCount, students, cInfo , gscore });
- }
- else {
- return Ok(new { count = tchList.Count, scount = realCount, max, min, average, excellent, pass, pow, blk, kno, dim, optCount, cInfo });
- }*/
- return Ok(new { count = tchList.Count, scount = realCount, max, min, average, excellent, pass, pow, blk, kno, dim, optCount, students, cInfo, gscore });
- }
- catch (Exception e)
- {
- return Ok(new { code = 500 });
- }
- }
- private static async Task<(string subId, List<(string name, List<string> kno)>)> getKnowledge(string school, CosmosClient client, string subjectBid, string pId)
- {
- try
- {
- var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(school, new PartitionKey($"Base"));
- string subjectId = string.Empty;
- List<Knowledge> knowledges = new();
- List<(string name, List<string> kno)> blocks = new();
- if (response.Status == 200)
- {
- using var json = await JsonDocument.ParseAsync(response.Content);
- School sc = json.ToObject<School>();
- var subjects = sc.period.Where(p => p.id.Equals(pId)).Select(x => x.subjects);
- foreach (var sj in subjects)
- {
- foreach (var s in sj)
- {
- if (!string.IsNullOrWhiteSpace(s.bindId) && s.bindId.Equals(subjectBid))
- {
- subjectId = s.id;
- }
- }
- }
- string code = $"Knowledge-{school}-{subjectId}";
- StringBuilder sql = new StringBuilder($"select value(c) from c");
- if (string.IsNullOrWhiteSpace(pId))
- {
- sql.Append($" where c.periodId = '{pId}'");
- }
- await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIteratorSql<Knowledge>(queryText: sql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
- {
- knowledges.Add(item);
- }
- }
- foreach (var know in knowledges)
- {
- foreach (var block in know.blocks)
- {
- blocks.Add((block.name, block.points));
- }
- }
- return (subjectId, blocks);
- }
- catch (Exception e)
- {
- return (null, null);
- }
- }
- //获取知识点得分率
- private static (KeyValuePair<string, List<string>>, KeyValuePair<string, List<string>>, KeyValuePair<string, List<(string name, double score, double average)>>,
- KeyValuePair<string, List<(string name, double score)>>, KeyValuePair<string, List<(string name, double score, double point, string cId)>>, KeyValuePair<string, List<(string name, double score, double point, string sId)>>) DoKnowledgePoint(ExamResult exam, ExamInfo info)
- {
- HashSet<string> knowledge = new HashSet<string>();
- List<double> point = new List<double>();
- List<List<double>> result = new List<List<double>>();
- List<ClassRange> classes = new List<ClassRange>();
- //求单个知识点所占分数
- List<string> per = new List<string>();
- //定位试卷信息
- int index = 0;
- foreach (ExamSubject subject in info.subjects)
- {
- if (subject.id.Equals(exam.subjectId))
- {
- break;
- }
- else
- {
- index++;
- }
- }
- if (info.papers[index].knowledge != null && info.papers[index].knowledge.Count > 0)
- {
- info.papers[index].knowledge.ForEach(k =>
- {
- k.ForEach(e =>
- {
- knowledge.Add(e);
- });
- });
- }
- else
- {
- return (default, default, default, default, default, default);
- }
- point = info.papers[index].point;
- result = exam.studentScores;
- classes = exam.classes;
- List<string> knowledgeName = new List<string>();
- foreach (string cla in knowledge)
- {
- knowledgeName.Add(cla);
- }
- for (int k = 0; k < knowledgeName.Count; k++)
- {
- if (null == knowledgeName[k])
- {
- knowledgeName.Remove(knowledgeName[k]);
- }
- }
- //初始化年级总分
- double total = 0;
- //处理年级单个知识点得分率
- foreach (List<double> grade in result)
- {
- total += grade.Sum();
- }
- //试卷总分
- double TotalPoint = point.Sum();
- List<double> knowScore = new List<double>();
- //学生得分情况
- List<double> Score = new List<double>();
- List<(string name, double score, double average)> pointScore = new();
- List<(string name, double score, double point, string cId)> classInfo = new();
- List<(string name, double score, double point, string sId)> stuInfo = new();
- List<(string name, double score)> pointTScore = new();
- for (int k = 0; k < knowledgeName.Count; k++)
- {
- double OnePoint = 0;
- List<string> itemNo = new List<string>();
- int n = 0;
- double scores = 0;
- info.papers[index].knowledge.ForEach(kno =>
- {
- if (kno.Contains(knowledgeName[k]))
- {
- var itemPersent = kno.Count > 0 ? 1 / Convert.ToDouble(kno.Count) : 0;
- OnePoint += point[n] * itemPersent;
- foreach (string id in exam.studentIds) {
- scores += exam.studentScores[index][n] * itemPersent;
- }
- }
- n++;
- });
- foreach (string id in exam.studentIds)
- {
- double stuScore = 0;
- int stuIndex = exam.studentIds.IndexOf(id);
- int a = 0;
- info.papers[index].knowledge.ForEach(kno =>
- {
- if (kno.Contains(knowledgeName[k]))
- {
- var itemPersent = kno.Count > 0 ? 1 / Convert.ToDouble(kno.Count) : 0;
- stuScore += exam.studentScores[stuIndex][a] * itemPersent;
-
- }
- a++;
- });
- stuInfo.Add((knowledgeName[k], stuScore, OnePoint, id));
- }
- foreach (var cla in exam.classes)
- {
- double classScores = 0;
- int b = 0;
- info.papers[index].knowledge.ForEach(kno =>
- {
- if (kno.Contains(knowledgeName[k]))
- {
- var itemPersent = kno.Count > 0 ? 1 / Convert.ToDouble(kno.Count) : 0;
- for (int i = cla.range[0]; i <= cla.range[1]; i++)
- {
- classScores += exam.studentScores[i][b] * itemPersent;
- }
- }
- b++;
- });
- classInfo.Add((knowledgeName[k], classScores, OnePoint, cla.id));
- }
- Score.Add(scores);
- //该知识点平均得分
- double sc = exam.studentIds.Count > 0 ? Math.Round(scores * 1.0 / exam.studentIds.Count, 2) : 0;
- //知识点占比 此处为了让结果更好看 乘以了系数1.5
- double average = sc * 1.5;
- if (average > OnePoint)
- {
- average = sc;
- }
- double persent = Math.Round(OnePoint > 0 ? average / OnePoint : 0, 2);
- per.Add(persent.ToString("0.00"));
- //单个知识点所有学生得分率
- pointTScore.Add((knowledgeName[k], persent));
- //单个知识点的配分
- pointScore.Add((knowledgeName[k], OnePoint, average));
- }
- KeyValuePair<string, List<string>> key1 = new(exam.subjectId, knowledgeName);
- KeyValuePair<string, List<string>> key2 = new(exam.subjectId, per);
- KeyValuePair<string, List<(string name, double score, double average)>> key3 = new(exam.subjectId, pointScore);
- KeyValuePair<string, List<(string name, double score)>> key4 = new(exam.subjectId, pointTScore);
- KeyValuePair<string, List<(string name, double score, double point, string cId)>> key5 = new(exam.subjectId, classInfo);
- KeyValuePair<string, List<(string name, double score, double point, string sId)>> key6 = new(exam.subjectId, stuInfo);
- //KeyValuePair<string, List<double>> key3 = new KeyValuePair<string, List<double>>(exam.subjectId, allPer);
- return (key1, key2, key3, key4, key5, key6);
- }
- private KeyValuePair<string, List<(string id, double sta, double pass, string stu)>> DoSubjectScatter(ExamResult e)
- {
- double[] point = StringHelper.ListTodouble(e.paper.point);
- double[,] result = StringHelper.ListToDouble(e.studentScores);
- try
- {
- var cdm = new ClouDASMatrix(result, point);
- //学生通过率
- List<double> pass = cdm.ScoringRate;
- //学生稳定度
- List<double> sta = cdm.StabilityRate;
- //落点区域
- List<string> stu = cdm.StuFallArea;
- int i = 0;
- List<(string id, double sta, double pass, string stu)> stus = new();
- e.studentIds.ForEach(s =>
- {
- var stuSta = sta[i] > 1 ? 1 : sta[i];
- stus.Add((s, stuSta, pass[i] * 0.01, stu[i]));
- i++;
- });
- return new KeyValuePair<string, List<(string id, double sta, double pass, string stu)>>(e.subjectId, stus);
- }
- catch (Exception ex)
- {
- BadRequest(ex.Message + ex.StackTrace);
- }
- return default;
- }
- }
- }
|