// --------------------------------------------------------------------------------------------- public ModuleDTO GetDTOWithQuestions(edumodule module, int userId) { ModuleDTO moduleDTO = ModuleMapper.GetDTO(module); List <TestQuestionDTO> questionDtosOfModule = QuestionDtosForModule(module); List <TestCodeDTO> codeDtosOfModule = CodeDtosForModule(module); // Wersja dla NAUCZYCIELA (do edycji modułów) // ......................................................................... // brak id użytkownika - pytania będą zawierać indeks prawidłowej odpowiedzi // - ta wersja potrzebna jest do edycji modułów if (userId < 0) { moduleDTO.test_questions_DTO = questionDtosOfModule; moduleDTO.test_codes_DTO = codeDtosOfModule; return(moduleDTO); } // Wersja dla STUDENTA // ......................................................................... // Jest id uzytkownika - // - pytania będą zawierały indeks ostatniej odpowiedzi udzielonej przez użytkownika // - kody będą zawierały kody utworzone przez użytkownika // (zamiana indeksów prawidłowych odpowiedzi na ostatnie odpowiedzi podane przez użytkownika // i prawidłowych wyników kodu na kody utworzone przez użytkownika). moduleDTO.test_questions_DTO = SetStudentAnswers(userId, questionDtosOfModule); moduleDTO.test_codes_DTO = SetStudentCodes(userId, codeDtosOfModule); // moduł gotowy do wysłania studentowi return(moduleDTO); }
// --------------------------------------------------------------------------------------------- public static void CopyValues(ModuleDTO source, edumodule target) { target.id = source.id; target.parent = source.parent; target.group_position = source.group_position; target.title = source.title; target.difficulty = source.difficulty; target.content = source.content; target.example = source.example; }
// --------------------------------------------------------------------------------------------- public static ModuleDTO GetSimpleDTO(edumodule entity) { return(new ModuleDTO { id = entity.id, parent = entity.parent, group_position = entity.group_position, title = entity.title, difficulty = entity.difficulty }); }
// --------------------------------------------------------------------------------------------- public static int SortModules(edumodule a, edumodule b) { if (a.group_position != b.group_position) { return(a.group_position > b.group_position ? 1 : -1); } if (a.id == b.id) { return(0); } return(a.id > b.id ? 1 : -1); }
// PUBLIC // ============================================================================================= public static ModuleResultDTO GetModuleResultDTO(edumodule module, bool codes, bool questions, bool unseen) { return(new ModuleResultDTO() { id = module.id, difficulty = module.difficulty, title = module.title, group_position = module.group_position, solvedCodes = codes, solvedQuestions = questions, noQuizCode = unseen }); }
// --------------------------------------------------------------------------------------------- private int countEasiestChildren(edumodule module) { if (module.difficulty == "easy") { return(1); } else { int n = 0; foreach (var child in _moduleService.SelectChildren(module.id)) { n += countEasiestChildren(child); } return(n); } }
// --------------------------------------------------------------------------------------------- private string ChildSeparator(edumodule module, int index, int nthElem, bool code) { string separator; // module 'medium' is being created if (module.difficulty == "easy") { if (code) { separator = "//" + (index + 1).ToString() + ") "; for (var i = separator.Length; i < 54; i++) { separator += '-'; } } else { separator = "______________________________________________________\n"; separator += (index + 1).ToString() + ")"; } if (nthElem > 0) { separator = "\n\n\n" + separator; } } // module 'hard' is being created else { string comment = code ? "// " : ""; separator = comment + module.title.ToUpper() + "\n"; separator += comment + "==================================================="; if (nthElem > 0) { separator = "\n\n\n\n\n" + separator; } } return(separator + "\n"); }
// --------------------------------------------------------------------------------------------- /* Pobiera z bazy wszystkie zadania z kodu dla danego modułu. * Jeżeli to nie jest moduł 'easy' - pobiera w tym celu wszystkie zadania * swoich dzieci (rekurencyjnie). */ public List <test_code> CodesForModule(edumodule module) { List <test_code> codes; // pytania dla modułu 'easy' if (module.difficulty == "easy") { codes = module.test_code.ToList(); } // pytania dla modułów 'medium' i 'hard' - rekurencyjnie else { codes = new List <test_code>(); var children = SelectChildren(module.id); children.ForEach(child => { codes.AddRange(CodesForModule(child)); }); } return(codes); }
// --------------------------------------------------------------------------------------------- // TODO zrzobić porządek z tymi metodami do ModuleResult! private ModuleResultDTO GetModuleResultDTO(edumodule module, user user) { var userQuestions = user.user_question; var passedQuests = userQuestions .Where(uq => uq.last_result == true) .Select(uq => uq.test_question) .ToList(); var userCodes = user.user_code; var passedCodes = userCodes .Where(uc => uc.last_result == true) .Select(uc => uc.test_code) .ToList(); var dto = GetDTOWitResults( userQuestions, passedQuests, userCodes, passedCodes, module); return(ModuleMapper.GetModuleResultDTO(module, dto.solvedCodes, dto.solvedQuestions, false)); }
// --------------------------------------------------------------------------------------------- /* Pobiera z bazy wszystkie pytaniadania dla danego modułu. * Jeżeli to nie jest moduł 'easy' - pobiera w tym celu wszystkie pytania * swoich dzieci (rekurencyjnie). */ public List <test_question> QuestionsForModule(edumodule module) { List <test_question> questions; // pytania dla modułu 'easy' if (module.difficulty == "easy") { //questions = _questionService.SelectQuestionsForModule(module.id).ToList(); questions = module.test_question.ToList(); } // pytania dla modułów 'medium' i 'hard' - rekurencyjnie else { questions = new List <test_question>(); var children = SelectChildren(module.id); children.ForEach(child => { questions.AddRange(QuestionsForModule(child)); }); } return(questions); }
// --------------------------------------------------------------------------------------------- public List <ModuleDTO> DeleteModule(int id) { // usunięcie z grupy dzieci (modułów) usuwanego modułu edumodule mod = _moduleRepository.Get(id); if (mod.difficulty != "easy") { List <edumodule> children = SelectChildren(id); foreach (var child in children) { child.parent = null; } _moduleRepository.SaveChanges(); } // usunięcie z bazy pytań przypisanych do usuwanego modułu, jesli to moduł 'easy' else { //List<test_question> questions = _questionService.SelectQuestionsForModule(id); List <test_question> questions = mod.test_question.ToList(); foreach (var child in questions) { _questionService.DeleteQuestion(child.id); } } // usunięcie modułu _moduleRepository.Delete(id); // odświeżenie sekwencji modułów CreateModuleSequence(); return(GetSimpleModules()); }
// --------------------------------------------------------------------------------------------- /* Pobranie następnego modułu o wymaganym poziomie trudności (ten sam | up | down). * Jeżeli nie da się zmienić poziomu w żądanym kierunku - na tym samym poziomie. * Jeżeli to ostatni moduł materiału - zwraca null. */ private edumodule PickNextModule(int lastModuleId, ChangeDifficulty change, int userId) { edumodule newModule = null; edumodule lastModule = _moduleRepository.Get(lastModuleId); // ustalenie aktualnego poziomu trudności var difficultyNow = lastModule.difficulty; // ustalenie czy można poziom zmienić bool noWayUp = (change == ChangeDifficulty.UP && difficultyNow == "hard"); bool noWayDown = (change == ChangeDifficulty.DOWN && difficultyNow == "easy"); if (noWayUp || noWayDown) { change = ChangeDifficulty.NO_CHANGE; } // TODO: uporządkować przypadek parent == null - nie może występować // pobranie rodzeństwa bieżącego modułu int?parentId = lastModule.parent; var siblings = _moduleService.SelectChildren(parentId); // wykluczenie modułów nie przypisanych do żadnego nadrzędnego, // które powinny mieć rodzica (czyli na poziomie niższym niz "hard") siblings = siblings.Where(s => (s.parent != null || s.difficulty == "hard")).ToList(); ModuleService.SortGroupPosition(ref siblings); // ustalenie czy to ostatnie dziecko int idxChild = siblings.FindIndex(mod => mod.id == lastModuleId); bool lastChild = (idxChild == siblings.Count() - 1); // NIE ZMIENIAMY POZIOMU TRUDNOŚCI if (change == ChangeDifficulty.NO_CHANGE) { // to jeszcze nie ostatnie dziecko - podanie następnego brata if (!lastChild) { newModule = siblings[idxChild + 1]; } // TODO: wyeliminować przypadek gdy nie mamy id rodzica else if (parentId == null || parentId == 0) { newModule = null; } // to ostatnie dziecko - podanie pierwszego kuzyna else { newModule = PickNextModule(parentId ?? 0, ChangeDifficulty.DOWN, userId); } } // OBNIŻENIE POZIOMU TRUDNOŚCI - podanie pierwszego dziecka najbliższego brata else if (change == ChangeDifficulty.DOWN) { // to jeszcze nie ostatnie dziecko - podanie pierwszego dziecka następnego brata if (!lastChild) { var brother = siblings[idxChild + 1]; newModule = _moduleService.SelectChildren(brother.id)[0]; } // nie ma więcej modułów - ten był ostatni else if (lastModule.difficulty == "hard" || parentId == null || parentId == 0) { newModule = null; } // pobranie dziecka najbliższego kuzyna else { var cousin = PickNextModule(parentId ?? 0, ChangeDifficulty.DOWN, userId); newModule = (cousin == null) ? null : _moduleService.SelectChildren(cousin.id)[0]; } } // PODNIESIENIE POZIOMU TRUDNOŚCI - podanie kolejnego modułu w wersji trudniejszej else { // to nie jest ostatnie dziecko - podanie następnego brata bez zmiany trudności if (!lastChild) { newModule = siblings[idxChild + 1]; } // moduł bez rodzica - nie można podnieśc poziomu trudności else if (parentId == null || parentId == 0) { newModule = null; } // to jest ostatnie dziecko - podanie następnego trudniejszego else { newModule = PickNextModule(parentId ?? 0, ChangeDifficulty.NO_CHANGE, userId); } } if (newModule != null) { _logger.Info("User: "******"|" + "Picked " + newModule.title + " as next module"); } else { _logger.Info("User: "******"|" + "No new module picked"); } return(newModule); }
// --------------------------------------------------------------------------------------------- public List <test_code> SelectCodesForModule(edumodule module) { return(module.test_code.ToList()); }
// --------------------------------------------------------------------------------------------- private List <TestCodeDTO> CodeDtosForModule(edumodule module) { return(TestCodeMapper.GetCodeListDTO(CodesForModule(module))); }
// --------------------------------------------------------------------------------------------- private List <TestQuestionDTO> QuestionDtosForModule(edumodule module) { return(TestQuestionMapper.GetQuestionListDTO(QuestionsForModule(module))); }
// --------------------------------------------------------------------------------------------- public ModuleDTO GetModuleLearn(int id, int userId) { edumodule module = _moduleRepository.Get(id); return(GetDTOWithQuestions(module, userId)); }
// PRIVATE // ============================================================================================= private List <ModuleDTO> FillMetaModule(ModuleDTO[] moduleGroup, edumodule newModule) { // sortowanie otrzymanych modułów w kolejności id List <ModuleDTO> moduleList = new List <ModuleDTO>(moduleGroup); moduleList.Sort((a, b) => (a.id > b.id ? 1 : -1)); // przygotowanie modułu do wypełnienia treścią dzieci List <edumodule> children; bool newOne = false; if (newModule == null) { newOne = true; newModule = new edumodule(); children = new List <edumodule>(); } else { children = newModule.edumodule1.ToList(); } // połączenie treści i przykładów dzieci w pojedyncze stringi edumodule child; string content = "", example = "", childContent = "", childExample = ""; int nContents = 0, nExamples = 0; for (var i = 0; i < moduleList.Count; i++) { child = _moduleRepository.Get(moduleList[i].id); childContent = child.content; if (childContent != "") { content += ChildSeparator(child, i, nContents, false) + childContent; nContents++; } childExample = child.example; if (childExample != "") { example += ChildSeparator(child, i, nExamples, true) + childExample; nExamples++; } if (newOne) { children.Add(child); } } // zapisanie nowego lub odświeżenie nadrzędnego modułu w bazie danych newModule.content = content; newModule.example = example; if (newOne) { newModule.difficulty = moduleGroup[0].difficulty == "easy" ? "medium" : "hard"; newModule.title = "<podaj tytuł>"; newModule.group_position = 2000000000; _moduleRepository.Add(newModule); // zmiana parentId wszystkich modułów podrzędnych na id nowo utworzonego modułu foreach (var childReady in children) { childReady.parent = newModule.id; } } _moduleRepository.SaveChanges(); if (newOne) { // odświeżenie sekwencji modułów CreateModuleSequence(); // wysłanie do frontu nowo utworzonego modułu return(GetSimpleModules()); } else { return(null); } }
// --------------------------------------------------------------------------------------------- public ModuleDTO GetModuleEdit(int id) { edumodule module = _moduleRepository.Get(id); return(GetDTOWithQuestions(module, -1)); }
// PRIVATE // ============================================================================================= private ModuleDTO GetDTOWitResults(ICollection <user_question> userQuestions, List <test_question> passedQuests, ICollection <user_code> userCodes, List <test_code> passedCodes, edumodule mod) { ModuleDTO dto = ModuleMapper.GetDTO(mod); IEnumerable <test_question> moduleQuests; IEnumerable <test_code> moduleCodes; moduleQuests = QuestionsForModule(mod); // this module has no questions if (moduleQuests.Count() == 0) { dto.solvedQuestions = true; } // the user has not answered this module's questions yet else if (userQuestions.FirstOrDefault(q => moduleQuests.Contains(q.test_question)) == null) { dto.solvedQuestions = false; } // check the latest user's results with this module question test else { dto.solvedQuestions = moduleQuests.FirstOrDefault(q => !passedQuests.Contains(q)) == null; } // codeTasks for the module moduleCodes = CodesForModule(mod); // this module has no code test if (moduleCodes.Count() == 0) { dto.solvedCodes = true; } // the user has not taken this module's code test yet else if (userCodes.FirstOrDefault(c => moduleCodes.Contains(c.test_code)) == null) { dto.solvedCodes = false; } // check the latest user's results with this module code test else { dto.solvedCodes = moduleCodes.FirstOrDefault(c => !passedCodes.Contains(c)) == null; } return(dto); }
// --------------------------------------------------------------------------------------------- public ModuleDTO UpsertModule(ModuleDTO moduleReceived) { var id = moduleReceived.id; edumodule module; List <test_question> oldQuestions = null; List <test_code> oldCodes = null; // MODUŁ // ............................................................... // utworzenie nowego modułu lub pobranie istniejącego if (id == 0) { module = new edumodule(); ModuleMapper.CopyValues(moduleReceived, module); _moduleRepository.Add(module); } else { module = _moduleRepository.Get(id); _moduleRepository.SetNewValues(moduleReceived, module); oldQuestions = module.test_question.ToList(); oldCodes = module.test_code.ToList(); } // PYTANIA // ............................................................... // usunięcie pytań, których nie ma w tablicy z nowymi pytaniami var newQuestions = moduleReceived.test_questions_DTO; foreach (var oldQ in oldQuestions) { if (newQuestions == null) { _questionService.DeleteQuestion(oldQ.id); } else if (!newQuestions.Exists(newQ => newQ.id == oldQ.id)) { _questionService.DeleteQuestion(oldQ.id); } } // zapisanie nowych i odświeżenie starych pytań przypisanych do modułu if (moduleReceived.test_questions_DTO != null && moduleReceived.difficulty == "easy") { foreach (var new_question in moduleReceived.test_questions_DTO) { _questionService.UpsertQuestion(new_question); } } // CODE TASKS // ............................................................... // usunięcie zadań z kodu, których nie ma w tablicy z nowymi zadaniami var newCodes = moduleReceived.test_codes_DTO; foreach (var oldC in oldCodes) { if (newCodes == null) { _codeService.DeleteCode(oldC.id); } else if (!newCodes.Exists(newC => newC.id == oldC.id)) { _codeService.DeleteCode(oldC.id); } } // zapisanie nowych i odświeżenie starych pytań przypisanych do modułu if (moduleReceived.test_codes_DTO != null && moduleReceived.difficulty == "easy") { foreach (var new_code in moduleReceived.test_codes_DTO) { _codeService.UpsertCode(new_code); } } // RETURN // ............................................................... return(GetDTOWithQuestions(module, -1)); }