def checkStack(q,correct): stack=getStack(input.get_input(q)) response = "" errors = 0 grade = 0 if(stack == correct): grade=100 feedback.set_problem_result("success", q) feedback.set_problem_feedback(response, q) return grade else: if not (stack.startswith( correct[0:1] ) ): response += "The top-label of your stack is incorrect.\n" if not (stack.endswith( correct[-2:] ) ): response += "The bottom label of your stack is incorrect.\n" clist=correct.split(':') slist=stack.split(':') if len(slist) > len(clist): response += "Your answer contains more labels in its stack than the correct one.\n" if len(slist) < len(clist): response += "Your answer contains fewer labels in its stack than the correct one.\n" feedback.set_problem_result("failed", q) response += "Your answer to this question is incorrect.\n" feedback.set_problem_feedback(response, q) return grade
def checkSinglePath(q, correct): path = getPath(input.get_input(q)) response = "" errors = 0 grade = 0 if (path == correct): grade = 100 feedback.set_problem_result("success", q) feedback.set_problem_feedback(response, q) return grade else: if not (path.startswith(correct[0:1])): response += "Your answer does not start with {}\n".format( correct[0:1]) if not (path.endswith(correct[-2:])): response += "Your answer does not end with {}\n".format( correct[-2:]) if (',' in path): response += "There is only one path from this router.\n" feedback.set_problem_result("failed", q) response += "Your answer to this question is incorrect. There is only one path from this router to the destination.\n" feedback.set_problem_feedback(response, q) return grade
def handle_verification(feedback_settings): result = helper.statement_verification(feedback_settings) # If not empty, there is error(s) in student code if result: msg = feedback_settings["status_message"].get(2, "Uncommon Failure") feedback.set_global_feedback(msg) # Add message(s) to tell student where are his/her errors for (check, problem_id) in result: message = check.capitalize() + " statement(s) " \ + (" found " if check == "prohibited" else " missing ") + "HERE" feedback.set_problem_feedback(message, problem_id, True) feedback.set_global_result("failed") feedback.set_grade(0.0) sys.exit(0)
def checkNPaths(q, correct): path = getPath(input.get_input(q)) list = path.split(',') clist = correct.split(',') errors = 0 grade = 0 response = "" if (len(list) != len(clist)): feedback.set_problem_result("failed", q) response += "Your answer to this question is incorrect. There are {} paths from this router.\n".format( len(clist)) feedback.set_problem_feedback(response, q) return 0 for l in clist: if not (l in list): feedback.set_problem_result("failed", q) response += "Your answer to this question is incorrect.\n" feedback.set_problem_feedback(response, q) return 0 feedback.set_problem_result("success", q) feedback.set_problem_feedback(response, "q1") return 100
simp_answer += el simp_answer += ")" return simp_answer == correction answer = input.get_input( "q1") #Remplacez tous les 'q1' par l'ID du sous-problème grade = 0 check = is_coordinates(answer) if check != True: #Renvoie un feedback personnalisé en fonction des erreurs rencontrées feedback.set_problem_result("failed", "q1") #Ici if check == "parenthese": feedback.set_problem_feedback( "Votre réponse doit contenir des parenthèses pour délimiter le point", "q1") #Ici if check == "lettre": feedback.set_problem_feedback( "Votre réponse ne doit contenir que des chiffres", "q1") #Ici if check == "separateur": feedback.set_problem_feedback( "Les coordonnées doivent être séparées par une virgule", "q1") #Ici elif check == True: if is_correct( answer, "(2,2)" ) == False: #Remplacez '(2,2)' par la réponse correcte, si la réponse à la question est (5,6), écrivez "(5,6)" feedback.set_problem_result("failed", "q1") #Ici feedback.set_problem_feedback("Votre réponse est incorrect",
True) score = 0 total = 0 tests_result = {} for test in results: total += test['weight'] for tag in test['tags']: if tag != "": feedback.set_tag(tag, True) if test['code'] == 'SUCCESS': score += test['weight'] feedback.set_problem_feedback( "* {desc}\n\n => réussi ({weight}/{weight}) pts)\n\n".format( **test) + (" Info: {}\n\n".format(" — ".join( test['info_msgs'])) if test['info_msgs'] else '\n'), test['pid'], True) tests_result[test['pid']] = True if tests_result.get( test['pid'], True) else False else: feedback.set_problem_feedback( "* {desc}\n\n => échoué (0/{weight}) pts)\n\n".format(**test) + (" Info: {}\n\n".format(" — ".join(test['info_msgs'])) if test['info_msgs'] else '\n'), test['pid'], True) tests_result[test['pid']] = False for pid, result in tests_result.items(): if result: feedback.set_problem_result("success", pid) else:
def run(exercice, customscript, corr, execcustom, nexercices, javac_args, java_args, code_litteral): run_custom(customscript=customscript, execcustom=execcustom) outother, output = compile_files(javac_args) outcorr = "" if corr != 0: outcorr = compile_corr(javac_args) erreur_enseignant = 0 message_enseignant = "" if outcorr != "": outcorr = add_indentation_level(outcorr) erreur_enseignant = 1 message_enseignant = outcorr if outother != "": # On indente le message pour le faire passer dans le code-block rst outother = add_indentation_level(outother) erreur_enseignant = 1 message_enseignant = message_enseignant + "\n" + outother if erreur_enseignant != 0: feedback.set_result('failed') feedback.set_global_feedback("Le programme ne compile pas: \n " + code_litteral + message_enseignant + "\n") sys.exit(0) error = 0 # Si output est vide et qu'il n'y a donc pas d'erreur de compilation if output == "": with open('err.txt', 'w+') as f: # On lance l'exercice 1 resproc = subprocess.Popen(java_args + ['student/' + exercice], universal_newlines=True, stderr=f, stdout=subprocess.PIPE) resproc.communicate() resultat = resproc.returncode f.flush() f.seek(0) outerr = f.read() # Si les tests se sont bien passés (valeur de retour = 127) if resultat == 127: if nexercices == 1: feedback.set_result('success') feedback.set_problem_feedback("Bravo, votre code est correct !", "q1") else: j = 1 while j <= nexercices: # On fait un feedback positif par question feedback.set_result('success') feedback.set_problem_feedback("Vous avez bien répondu à cette question", "q" + str(j)) j += 1 elif resultat == 252: feedback.set_result('failed') feedback.set_global_feedback("La limite de mémoire de votre programme est dépassée") sys.exit(0) elif resultat == 253: feedback.set_result('timeout') feedback.set_global_feedback("La limite de temps d'exécution de votre programme est dépassée") exit() else: # Sinon c'est que les tests ont échoué, le programme possède des erreurs. if nexercices == 1: outerr = add_indentation_level(outerr).replace('%', '%%') feedback.set_result('failed') feedback.set_problem_feedback("Il semble que vous ayiez fait des erreurs dans votre code...\n " + code_litteral + outerr + "\n", "q1") error = 1 else: i = 1 while i <= nexercices: # On récupère un feedback par question dans le System.err, en suivant le format imposé par convention with open('question.out', 'w+') as f2: proc = subprocess.Popen(['sed', '-e', "/Question " + str(i) + " :/,/Question [^\D1] :/!d"], universal_newlines=True, stdout=f2, stdin=f) proc.communicate() f2.seek(0) regex_question = re.findall('^Question ' + str(i) + ' :\n(.*?)^Question [^\D1] :', outerr, re.DOTALL | re.MULTILINE) if len(regex_question) == 0: feedback.set_result('success') feedback.set_problem_feedback("Vous avez bien répondu à cette question", "q" + str(i)) else: # On joint les matchs de la regex dans un seul string outerr_question = ''.join(regex_question) outerr_question = add_indentation_level(outerr_question).replace('%', '%%') feed = "Il semble que vous ayiez fait des erreurs dans votre code...\n " + code_litteral + outerr_question + "\n" feedback.set_result('failed') feedback.set_problem_feedback(feed, "q" + str(i)) i += 1 error = 1 # On vérifie si la tâche s'est bien déroulée ou s'il y a eu un souci, et on fait un feedback de la tâche complète if error == 0: feedback.set_result('success') feedback.set_global_feedback("Bravo, votre code est correct !") else: feedback.set_result('failed') feedback.set_global_feedback("Vous n'avez pas réussi tous les exercices") # erreur de compilation else: with open('outputglobal.out', 'w+') as f: output = add_indentation_level(output) feed = "Votre programme ne compile pas: \n " + code_litteral + output + "\n" feedback.set_result('failed') feedback.set_global_feedback(feed)
answer = expandInterval(answer) expected = expandInterval(expected) answer = answer.split("U") expected = expected.split("U") for e in answer: if not e in expected: return False, "{} ne fait pas partie de la réponse".format(e) for e in expected: if not e in answer: return False, "Il vous manque des intervalles dans la réponse" return True, "correct" result = compareDomains(answer, correct) if result[0]: feedback.set_problem_result("success", "q1") feedback.set_problem_feedback("Bravo!", "q1") grade += 100 else: feedback.set_problem_result("failed", "q1") feedback.set_problem_feedback(result[1], "q1") feedback.set_grade(grade) if grade == 100: feedback.set_global_result("success") else: feedback.set_global_result("failed")
def set_problem_result(problem_id, result, fb): """Set the result and the feedback to a problem.""" feedback.set_problem_result(result, problem_id) feedback.set_problem_feedback(fb, problem_id)
def run(customscript, execcustom, nexercices, tests=[], runner='Runner'): """ Parse les réponse des étudiant, compile et lance les tests et donne le feedback aux étudiant Keyword arguments: customscript -- nom d'un script personnalisé execcustom -- Si oui (valeur != 0) ou non (0) il faut exécuter le script personnalisé customscript nexercices -- la nombre d'exercice dans la tâche tests -- Fichiers de test à lancer runner -- Fichier runner (default 'Runner') """ #Récupération des fichiers de tests si jamais il ne sont pas fournis à l'appel de la méthode if not tests: tests = get_test_files(runner) code_litteral = ".. code-block::\n\n" parsetemplate() # Parse les réponses de l'étudiant if execcustom != 0: # On doit exécuter le script personnalsé # If this is a python script we call the main() method with the _() function to transmit the translation mechanism if (customscript == "custom_translatable.py"): from custom_translatable import main outcustom = main(_) else: outcustom = subprocess.call(['./' + customscript], universal_newlines=True) if outcustom != 0: # Le script a renvoyé une erreur exit() # On compile les fichier. La fonction map applique une fonction (argument 1) sur une liste (argument 2) # L'expression lambda définit une fonction anonyme qui ajoute le dossiers src et l'extension .java aux nom de fichier tests anonymous_fun = lambda file: './src/' + file + '.java' # Create anonymous funcntion Log = compile_files([anonymous_fun(file) for file in tests + [runner]]) if Log == "": # La compilation a réussie with open('err.txt', 'w+', encoding="utf-8") as f: # On lance le runner os.chdir('./student') java_cmd = "run_student java -ea -cp " + librairies() # On passe comme argument au fichier runner les fichier de tests (Voir documentation runner) resproc = subprocess.Popen(shlex.split(java_cmd) + ['src/' + runner] + tests, universal_newlines=True, stderr=f, stdout=subprocess.PIPE) resproc.communicate() resultat = resproc.returncode f.flush() f.seek(0) outerr = f.read() print( outerr ) # On affiche la sortie de stderr dans les informations de debug if resultat == 127: # Les tests ont réussis feedback.set_global_result('success') elif resultat == 252: # Limite de mémoire dépassée feedback.set_global_result('failed') feedback.set_global_feedback( _("La limite de mémoire de votre programme est dépassée")) elif resultat == 253: # timeout feedback.set_global_result('failed') feedback.set_global_feedback( _("La limite de temps d'exécution de votre programme est dépassée" )) else: # Les tests ont échouées if nexercices == 1: outerr = add_indentation_level( outerr ) # On ajoute de l'indentation pour que ça s'affiche dans un cadre gris pour les étudiants feedback.set_global_result('failed') feedback.set_global_feedback( _("Il semble que vous ayiez fait des erreurs dans votre code…\n\n" ) + code_litteral + outerr + "\n") else: i = 1 while i <= nexercices: """ Cette regex va matcher tout ce qui se trouve entre - @i (avec i le numéro du sous-problème que l'on considère - @<un ou plusieurs chiffre> et donc matcher tout les feedback associés au sous-problème que l'on considère """ regex = '@' + str(i) + ' :\n(.*?)(?=@\d+ :|$)' regex_question = re.findall(regex, outerr, re.DOTALL) if len( regex_question ) == 0: # Il n'y a pas de match pour la regex, le sous-problème est bien répondu feedback.set_problem_feedback( _("Vous avez bien répondu à cette question"), "q" + str(i)) else: outerr_question = ''.join( regex_question ) # On remet tout les feedback trouvé en un seul outerr_question = add_indentation_level( outerr_question) # on l'indente feed = _( "Il semble que vous ayiez fait des erreurs dans votre code…\n\n" ) + code_litteral + outerr_question + "\n" feedback.set_problem_feedback(feed, "q" + str(i)) i += 1 else: # La compilation a raté Log = add_indentation_level(Log) feed = _( "Le programme ne compile pas : \n\n") + code_litteral + Log + "\n" feedback.set_global_result('failed') feedback.set_global_feedback(feed)