def resolve(report=None, custom_success_message=None): if report is None: report = MAIN_REPORT print("<|--") success, score, hc, messages_by_group = sectional.resolve(report) last_group = 0 for group, messages in sorted(messages_by_group.items()): if group != last_group: for intermediate_section in range(last_group, group, 2): print("-" + report['source']['sections'][1 + intermediate_section]) printed_first_bad = False for message in messages: if message['priority'] in ('positive', 'instructions'): print(strip_tags(message['message'])) elif not printed_first_bad: print(strip_tags(message['message'])) printed_first_bad = True last_group = group print("-Overall") if success: if custom_success_message is None: print("Complete! Great job!") else: print(custom_success_message) else: print("Incomplete") print("--|>") print("Grade :=>>", round(score))
def resolve(report=None, custom_success_message=None): if report is None: report = MAIN_REPORT print("<|--") success, score, hc, messages_by_group = sectional.resolve(report) last_group = 0 for group, messages in sorted(messages_by_group.items()): if group != last_group: for intermediate_section in range(last_group, group, 2): print("-" + report['source']['sections'][1 + intermediate_section]) printed_first_bad = False for message in messages: if message['priority'] == 'positive': print(strip_tags(message['message'])) elif not printed_first_bad: print(strip_tags(message['message'])) printed_first_bad = True last_group = group print("-Overall") if success: if custom_success_message is None: print("Complete! Great job!") else: print(custom_success_message) else: print("Incomplete") print("--|>") print("Grade :=>>", round(score))
def test_sectional_success(self): clear_report() contextualize_report('a=0\n##### Part 1\nprint("A")\n##### Part 2\nprint("B")') separate_into_sections(independent=True) # Part 0 verify() commands.clear_sandbox() commands.run() # Part 1 next_section() verify() commands.clear_sandbox() commands.run() give_partial(.2) # Part 2 next_section() verify() commands.clear_sandbox() commands.run() give_partial(.2) # Resolve everything finals = sectional.resolve() self.assertEqual("""# Global FeedbackSourceSection Feedback separated into groups # 1 Complete Great work! # 2 Complete Great work!""", "\n".join(f"# {g.section_number if g is not None else 'Global'}\n{f.title}\n{f.message}" for g, f in finals.items()))
def test_sectional_error(self): clear_report() contextualize_report('a=0\n##### Part 1\nprint("A")\n##### Part 2\nsyntax error') separate_into_sections(independent=True) # Part 0 verify() commands.clear_sandbox() commands.run() # Part 1 next_section() verify() commands.clear_sandbox() commands.run() give_partial(.2) # Part 2 next_section() verify() commands.clear_sandbox() commands.run() give_partial(.2) # Resolve everything finals = sectional.resolve() self.assertEqual("""# Global FeedbackSourceSection Feedback separated into groups # 1 Complete Great work! # 2 Syntax Error Bad syntax on line 5 The traceback was: Line 5 of file answer.py syntax error Suggestion: Check line 5, the line before it, and the line after it.""", "\n".join(f"# {g.section_number if g is not None else 'Global'}\n{f.title}\n{f.message}" for g, f in finals.items()))
def test_sections_tifa(self): contextualize_report( dedent(''' ##### Part 1 a = 0 ##### Part 2 print(a) ##### Part 3 print(b) ''')) separate_into_sections(independent=False) # First section has an unused variable next_section() self.assertEqual(len(get_all_feedback()), 2) tifa_analysis() self.assertEqual(len(get_all_feedback()), 3) # Second section uses said variable next_section() self.assertEqual(len(get_all_feedback()), 4) tifa_analysis() self.assertEqual(len(get_all_feedback()), 4) # Third section has a new unused variables next_section() self.assertEqual(len(get_all_feedback()), 5) tifa_analysis() feedback = get_all_feedback() self.assertEqual(len(get_all_feedback()), 6) finals = sectional.resolve() self.assertEqual( """FeedbackSourceSection Feedback separated into groups Unused Variable The variable a was given a value on line 3, but was never used after that. Initialization Problem The variable b was used on line 7, but it was not given a value on a previous line. You cannot use a variable until it has been given a value.""", "\n".join(f.title + "\n" + f.message for f in finals.values()))
def test_exam_progress(self): def test_has_loop(question): ast = parse_program() if not ast.find_all("For"): gently("No for loop yet.") else: question.answer() question_A = Question("QA", "Create a for loop.", [test_has_loop]) question_B = Question("QB", "Create an if statement.", []) pool_1 = Pool("P1", [question_A, question_B]) def test_variable(question): student = run() if assert_has_variable(student, "alpha", value=2): question.answer() question_C = Question("QC", "Create a variable.", [test_variable]) pool_2 = Pool("P2", [question_C]) def test_second_variable(question): student = run() if not assert_has_variable(student, "beta", value=3): question.answer() set_success() question_D = Question("QD", "Create a beta variable.", [test_second_variable]) pool_3 = Pool("P3", [question_D]) def make_exam(code): """ Args: code: """ clear_report() set_seed(0) set_source(code) student = run() pool_1.choose().ask() pool_2.choose().ask() if pool_1.answered and pool_2.answered: pool_3.choose().ask() # Opened a blank file and evaluated make_exam('') finals = sectional.resolve() print(finals) self.assertEqual(finals[0][0]['message'], "Create a for loop.") self.assertEqual(finals[0][1]['message'], "Create a variable.") self.assertEqual(finals[0][2]['message'], "Source code file is blank.") # Tried writing some inadequate code make_exam('if True: pass') finals = sectional.resolve() self.assertEqual(finals[0][0]['message'], "Create a for loop.") # Tried writing some bad code make_exam('1 + ""') finals = sectional.resolve() self.assertEqual(finals[0][0]['message'], "Create a for loop.") self.assertEqual(finals[0][1]['message'], "Create a variable.") self.assertEqual( finals[0][2]['message'], dedent(""" A TypeError occurred: <pre>Unsupported operand type(s) for +: 'int' and 'str'</pre> I ran the file `answer.py`. The traceback was: Line 1 of file answer.py 1 + "" Type errors occur when you use an operator or function on the wrong type of value. For example, using `+` to add to a list (instead of `.append`), or dividing a string by a number. Suggestion: To fix a type error, you should trace through your code. Make sure each expression has the type you expect it to have.""" ).lstrip()) # Tried writing some good code make_exam('for x in []: pass') final_success, final_score, _, finals = sectional.resolve() self.assertEqual(finals[0][0]['message'], "Create a variable.") self.assertFalse(final_success) # Tried writing some 100% correct code make_exam('for x in []: pass\nalpha = 2\nbeta = 3') final_success, final_score, _, finals = sectional.resolve() self.assertEqual(finals[0][0]['message'], "No errors reported.") self.assertTrue(final_success)