Beispiel #1
0
 def test_only_printing_variables(self):
     with Execution('a,b=0,1\nprint(a,b)') as e:
         self.assertTrue(only_printing_variables())
     with Execution('print(0,"True", True)') as e:
         self.assertFalse(only_printing_variables())
     with Execution('print(True)') as e:
         self.assertFalse(only_printing_variables())
Beispiel #2
0
    def test_prevent_builtin_usage(self):
        with Execution('sum([1,2,3])') as e:
            self.assertEqual(prevent_builtin_usage(['sum', 'min']), 'sum')
        self.assertEqual(
            e.message, "You cannot use the builtin function "
            "<code>sum</code>.")

        with Execution('max([1,2,3])') as e:
            self.assertIsNone(prevent_builtin_usage(['sum', 'min']))
        self.assertEqual(e.message, "No errors reported.")
Beispiel #3
0
 def test_no_nested_function_definitions(self):
     with Execution('if True:\n  def x():\n    pass\n  x()') as e:
         self.assertFalse(no_nested_function_definitions())
     self.assertEqual(
         e.message, "You have defined a function inside of "
         "another block. For instance, you may have placed it "
         "inside another function definition, or inside of a "
         "loop. Do not nest your function definition!")
     with Execution('if True:\n  pass\ndef x():\n  pass\nx()') as e:
         self.assertTrue(no_nested_function_definitions())
     self.assertEqual(e.message, "No errors reported.")
Beispiel #4
0
 def test_prevent_advanced_iteration(self):
     with Execution('while False:\n  pass') as e:
         prevent_advanced_iteration()
     self.assertEqual(
         e.message, "You should not use a <code>while</code> "
         "loop to solve this problem.")
     with Execution('sum([1,2,3])') as e:
         prevent_advanced_iteration()
     self.assertEqual(
         e.message, "You cannot use the builtin function "
         "<code>sum</code>.")
Beispiel #5
0
 def test_ensure_operation(self):
     with Execution('print(1-1)') as e:
         self.assertFalse(ensure_operation("+"))
     self.assertEqual(e.message, "You are not using the <code>+</code> "
                      "operator.")
     with Execution('print(1+1)') as e:
         self.assertNotEqual(ensure_operation("+"), False)
     self.assertEqual(e.message, "No errors reported.")
     with Execution('print(1!=1)') as e:
         self.assertNotEqual(ensure_operation("!="), False)
     self.assertEqual(e.message, "No errors reported.")
Beispiel #6
0
 def test_find_function_calls(self):
     with Execution('def a(x):\n  print(x,1)\na(1)\nprint("T")') as e:
         prints = find_function_calls('print')
         self.assertEqual(len(prints), 2)
         self.assertEqual(len(prints[0].args), 2)
         self.assertEqual(len(prints[1].args), 1)
     self.assertEqual(e.message, "No errors reported.")
     with Execution('a=[]\na.append(a)\na.pop()\n') as e:
         pops = find_function_calls('pop')
         self.assertEqual(len(pops), 1)
         self.assertEqual(len(pops[0].args), 0)
     self.assertEqual(e.message, "No errors reported.")
Beispiel #7
0
 def test_prevent_operation(self):
     with Execution('print(1+1)') as e:
         self.assertNotEqual(prevent_operation("+"), False)
     self.assertEqual(e.message, "You may not use the <code>+</code> "
                      "operator.")
     with Execution('print(1-1)') as e:
         self.assertFalse(prevent_operation("+"))
     self.assertEqual(e.message, "No errors reported.")
     with Execution('1 < 1') as e:
         self.assertNotEqual(prevent_operation("<"), False)
     self.assertEqual(e.message, "You may not use the <code><</code> "
                      "operator.")
Beispiel #8
0
 def test_function_prints(self):
     # Function prints
     with Execution('def a(x):\n  print(x+1)\na(1)') as e:
         self.assertTrue(function_prints())
     self.assertEqual(e.message, "No errors reported.")
     # Function only returns, no prints
     with Execution('def a(x):\n  return x+1\na(1)') as e:
         self.assertFalse(function_prints())
     self.assertEqual(e.message, "No errors reported.")
     # Function does not print, but prints exist
     with Execution('print("T")\ndef a(x):\n  x\na(1)\nprint("E")') as e:
         self.assertFalse(function_prints())
     self.assertEqual(e.message, "No errors reported.")
Beispiel #9
0
 def test_prevent_literal(self):
     with Execution('a = 5\na') as e:
         self.assertEqual(prevent_literal(3, 4, 5), 5)
     self.assertEqual(
         e.message, "Do not use the literal value "
         "<code>5</code> in your code.")
     with Execution('print("Hello")') as e:
         self.assertEqual(prevent_literal("Hello"), "Hello")
     self.assertEqual(
         e.message, "Do not use the literal value "
         "<code>'Hello'</code> in your code.")
     with Execution('print("Hello", 5)') as e:
         self.assertFalse(prevent_literal("Fire", 3, 4))
     self.assertEqual(e.message, "No errors reported.")
Beispiel #10
0
 def test_ensure_literal(self):
     with Execution('a = 5\na') as e:
         self.assertEqual(ensure_literal(3, 4, 5), 3)
     self.assertEqual(
         e.message, "You need the literal value "
         "<code>3</code> in your code.")
     with Execution('print("Hell")') as e:
         self.assertEqual(ensure_literal("Hello"), "Hello")
     self.assertEqual(
         e.message, "You need the literal value "
         "<code>'Hello'</code> in your code.")
     with Execution('print("Fire", 3, 4)') as e:
         self.assertFalse(ensure_literal("Fire", 3, 4))
     self.assertEqual(e.message, "No errors reported.")
Beispiel #11
0
    def test_output_test(self):
        # All passing
        with Execution('def a(x):\n  print(x+1)\na(1)') as e:
            self.assertIsNotNone(output_test('a', (2, "3")))
        self.assertEqual(e.message, "No errors reported.")

        # All failing
        with Execution('def a(x,y):\n  print(x-y)\na(1,2)') as e:
            self.assertIsNone(output_test('a', (1, 2, "3")))
        self.assertIn("wrong output 1/1 times", e.message)

        # All passing, multiline
        with Execution('def a(x):\n  print(x+1)\n  print(x+2)\na(1)') as e:
            self.assertIsNotNone(output_test('a', (4, ["5", "6"])))
        self.assertEqual(e.message, "No errors reported.")
Beispiel #12
0
 def test_ensure_imports(self):
     with Execution('json = "0"\njson.loads("0")+0') as e:
         self.assertTrue(ensure_imports("json"))
     self.assertEqual(e.message, "You need to import the <code>json</code> "
                      "module.")
     with Execution('from requests import json\njson.loads("0")+0') as e:
         self.assertTrue(ensure_imports("json"))
     self.assertEqual(e.message, "You need to import the <code>json</code> "
                      "module.")
     with Execution('import json\njson.loads("0")+0') as e:
         self.assertFalse(ensure_imports("json"))
     self.assertEqual(e.message, "No errors reported.")
     with Execution('from json import loads\nloads("0")+0') as e:
         self.assertFalse(ensure_imports("json"))
     self.assertEqual(e.message, "No errors reported.")
Beispiel #13
0
    def test_prevent_unused_result(self):
        with Execution('a="H  "\na.strip()') as e:
            prevent_unused_result()
        self.assertEqual(
            e.message, "Remember! You cannot modify a string "
            "directly. Instead, you should assign the result "
            "back to the string variable.")

        with Execution('a="H  "\nb=a.strip()\nb') as e:
            prevent_unused_result()
        self.assertEqual(e.message, "No errors reported.")

        with Execution('a=[]\na.append(1)\na') as e:
            prevent_unused_result()
        self.assertEqual(e.message, "No errors reported.")
Beispiel #14
0
 def test_find_prior_initializations(self):
     with Execution('a=0\na\na=5\na') as e:
         ast = parse_program()
         self.assertEqual(len(ast.body), 4)
         self.assertEqual(ast.body[3].ast_name, "Expr")
         self.assertEqual(ast.body[3].value.ast_name, "Name")
         priors = find_prior_initializations(ast.body[3].value)
         self.assertEqual(len(priors), 2)
Beispiel #15
0
    def test_catches_syntax_errors(self):
        clear_report()
        set_source('a b c')
        feedback = get_all_feedback()
        self.assertTrue(feedback)
        self.assertEqual(feedback[0].label, 'Syntax error')

        with Execution('a=0\nb b b\nc = 0') as e:
            pass
        self.assertFalse(e.success)
        self.assertEqual(e.label, 'Syntax error')
        self.assertEqual(e.message, "Invalid syntax on line 2")
Beispiel #16
0
 def test_ensure_prints(self):
     with Execution('print(1)\nprint(2)') as e:
         self.assertFalse(ensure_prints(1))
     self.assertEqual(e.message, "You are printing too many times!")
     with Execution('print(1)\nprint(2)') as e:
         self.assertFalse(ensure_prints(3))
     self.assertEqual(e.message, "You are not printing enough things!")
     with Execution('a = 0\na') as e:
         self.assertFalse(ensure_prints(1))
     self.assertEqual(e.message, "You are not using the print function!")
     with Execution('def x():\n  print(x)\nx()') as e:
         self.assertFalse(ensure_prints(1))
     self.assertEqual(
         e.message, "You have a print function that is not at "
         "the top level. That is incorrect for "
         "this problem!")
     with Execution('print(1)\nprint(2)') as e:
         prints = ensure_prints(2)
         self.assertNotEqual(prints, False)
         self.assertEqual(len(prints), 2)
     self.assertEqual(e.message, "No errors reported.")
Beispiel #17
0
    def test_prevent_incorrect_plt(self):
        student_code = dedent('''
            import matplotlib.pyplot
            plt.scatter([1,2,3], [4,5,6])
            plt.title("Some actual stuff")
            plt.show()
        ''')
        with Execution(student_code) as e:
            self.assertEqual(prevent_incorrect_plt(), True)
        self.assertEqual(
            e.message, "You have imported the "
            "<code>matplotlib.pyplot</code> module, but you did "
            "not rename it to <code>plt</code> using "
            "<code>import matplotlib.pyplot as plt</code>.")

        student_code = dedent('''
            import matplotlib.pyplot as plt
            scatter([1,2,3], [4,5,6])
            plt.title("Some actual stuff")
            plt.show()
        ''')
        with Execution(student_code) as e:
            self.assertEqual(prevent_incorrect_plt(), True)
        self.assertEqual(
            e.message, "You have attempted to use the MatPlotLib "
            "function named <code>scatter</code>. However, you "
            "imported MatPlotLib in a way that does not "
            "allow you to use the function directly. I "
            "recommend you use <code>plt.scatter</code> instead, "
            "after you use <code>import matplotlib.pyplot as "
            "plt</code>.")
        student_code = dedent('''
            import matplotlib.pyplot as plt
            plt.scatter([1,2,3], [4,5,6])
            plt.title("Some actual stuff")
            plt.show()
        ''')
        with Execution(student_code) as e:
            self.assertEqual(prevent_incorrect_plt(), False)
Beispiel #18
0
 def test_is_top_level(self):
     with Execution('print("Test")\ndef a(x):\n  print(x+1)\na(1)') as e:
         ast = parse_program()
         defs = ast.find_all('FunctionDef')
         self.assertEqual(len(defs), 1)
         self.assertTrue(is_top_level(defs[0]))
         self.assertEqual(len(defs[0].body), 1)
         self.assertFalse(is_top_level(defs[0].body[0]))
         calls = ast.find_all('Call')
         self.assertEqual(len(calls), 3)
         self.assertTrue(is_top_level(calls[0]))
         self.assertFalse(is_top_level(calls[1]))
     self.assertEqual(e.message, "No errors reported.")
Beispiel #19
0
 def test_runtime(self):
     with Execution('0+"A"') as e:
         suppress("analyzer")
     self.assertEqual(
         e.feedback, "TypeError<br><pre>unsupported operand "
         "type(s) for +: 'int' and 'str'</pre>\n"
         "Type errors most often occur when an expression "
         "tries to combine two objects with types that should "
         "not be combined. Like using <code>+</code> to add a "
         "number to a list instead of <code>.append</code>, "
         "or dividing a string by a number."
         "<br><b>Suggestion:</b> To fix a type error you will "
         "most likely need to trace through your code and "
         "make sure the variables have the types you expect "
         "them to have.")
Beispiel #20
0
    def test_unit_test(self):
        # All passing
        with Execution('def a(x,y):\n  return(x+y)\na') as e:
            self.assertIsNotNone(unit_test('a', (1, 2, 3)))
        self.assertEqual(e.message, "No errors reported.")

        # All failing
        with Execution('def a(x,y):\n  return(x-y)\na') as e:
            self.assertIsNone(unit_test('a', (1, 2, 3)))
        self.assertIn("it failed 1/1 tests", e.message)

        # Some passing, some failing
        with Execution('def a(x,y):\n  return(x-y)\na') as e:
            self.assertIsNone(unit_test('a', (1, 2, 3), (0, 0, 0)))
        self.assertIn("it failed 1/2 tests", e.message)

        # Optional tip
        with Execution('def a(x,y):\n  return(x-y)\na') as e:
            self.assertIsNone(unit_test('a', (1, 2, (3, "Try again!"))))
        self.assertIn("it failed 1/1 tests", e.message)
        self.assertIn("Try again!", e.message)

        # Float precision
        with Execution('def a(x,y):\n  return(x+y)\na') as e:
            self.assertIsNotNone(unit_test('a', (1.0, 2.0, 3.0)))
        self.assertEqual(e.message, "No errors reported.")

        # Not a function
        with Execution('a = 5\na') as e:
            self.assertIsNone(unit_test('a', (1, 2, 3)))
        self.assertEqual(
            e.message, "You defined a, but did not define "
            "it as a function.")

        # Not defined
        with Execution('x = 5\nx') as e:
            self.assertIsNone(unit_test('a', (1, 2, 3)))
        self.assertEqual(e.message, "The function <code>a</code> was "
                         "not defined.")
Beispiel #21
0
 def test_find_operation(self):
     with Execution('1+1') as e:
         ast = parse_program()
         self.assertNotEqual(find_operation("+", ast), False)
     with Execution('1>1') as e:
         ast = parse_program()
         self.assertNotEqual(find_operation(">", ast), False)
     with Execution('True and True') as e:
         ast = parse_program()
         self.assertNotEqual(find_operation("and", ast), False)
     with Execution('not True') as e:
         ast = parse_program()
         self.assertNotEqual(find_operation("not", ast), False)
     with Execution('not (1 + 1) and 1 < 1 <= 10') as e:
         ast = parse_program()
         self.assertFalse(find_operation(">", ast))
     with Execution('1 in [1,2,3]') as e:
         ast = parse_program()
         self.assertNotEqual(find_operation("in", ast), False)
Beispiel #22
0
    def test_match_signature(self):
        with Execution('a = 0\na') as e:
            self.assertIsNone(match_signature('a', 0))
        self.assertEqual(e.message, "No function named <code>a</code> "
                         "was found.")

        with Execution('def a():\n  pass\na') as e:
            self.assertIsNotNone(match_signature('a', 0))
        self.assertNotEqual(e.message, "No function named <code>a</code> "
                            "was found.")

        with Execution('def a():\n  pass\na') as e:
            self.assertIsNone(match_signature('a', 1))
        self.assertNotEqual(
            e.message, "The function named <code>a</code> "
            "has fewer parameters (0) than expected (1)")

        with Execution('def a(x, y):\n  pass\na') as e:
            self.assertIsNone(match_signature('a', 1))
        self.assertNotEqual(
            e.message, "The function named <code>a</code> "
            "has fewer parameters (2) than expected (1)")

        with Execution('def a(l, m):\n  pass\na') as e:
            self.assertIsNone(match_signature('a', 2, 'x', 'y'))
        self.assertEqual(
            e.message, "Error in definition of "
            "<code>a</code>. Expected a parameter named "
            "x, instead found l.")

        with Execution('def a(x, y):\n  pass\na') as e:
            self.assertIsNotNone(match_signature('a', 2, 'x', 'y'))
        self.assertNotEqual(
            e.message, "Error in definition of "
            "<code>a</code>. Expected a parameter named "
            "x, instead found l.")
Beispiel #23
0
 def test_no_errors(self):
     with Execution('a=0\na') as e:
         pass
     self.assertEqual(e.feedback, "No errors<br>No errors reported.")
Beispiel #24
0
    def test_check_for_plot(self):
        student_code = dedent('''
            import matplotlib.pyplot as plt
            plt.hist([1,2,3])
            plt.title("My line plot")
            plt.show()
            plt.plot([4,5,6])
            plt.show()
        ''')
        with Execution(student_code) as e:
            self.assertEqual(check_for_plot('hist', [1, 2, 3]), False)
        self.assertEqual(e.message, "No errors reported.")

        with Execution(student_code) as e:
            self.assertEqual(
                check_for_plot('hist', [1, 2, 3, 4]),
                "You have created a histogram, but it does not "
                "have the right data.")

        with Execution(student_code) as e:
            self.assertEqual(check_for_plot('line', [4, 5, 6]), False)
        self.assertEqual(e.message, "No errors reported.")

        with Execution(student_code) as e:
            self.assertEqual(
                check_for_plot('line', [4, 5, 6, 7]),
                "You have created a line plot, but it does not "
                "have the right data.")

        student_code = dedent('''
            import matplotlib.pyplot as plt
            plt.plot([1,2,3])
            plt.title("My line plot")
            plt.show()
        ''')
        with Execution(student_code) as e:
            self.assertEqual(
                check_for_plot('hist', [1, 2, 3]),
                "You have plotted the right data, but you appear "
                "to have not plotted it as a histogram.")

        student_code = dedent('''
            import matplotlib.pyplot as plt
            plt.plot([1,2,3])
            plt.title("Wrong graph with the right data")
            plt.show()
            plt.hist([4,5,6])
            plt.title("Right graph with the wrong data")
            plt.show()
        ''')
        with Execution(student_code) as e:
            self.assertEqual(
                check_for_plot('hist', [1, 2, 3]),
                "You have created a histogram, but it does not "
                "have the right data. That data appears to have "
                "been plotted in another graph.")

        student_code = dedent('''
            import matplotlib.pyplot as plt
            plt.plot([1,2,3])
            plt.title("My line plot")
            plt.show()
        ''')
        with Execution(student_code) as e:
            self.assertEqual(
                check_for_plot('hist', [4, 5, 6]),
                "You have not created a histogram with the "
                "proper data.")

        student_code = dedent('''
            import matplotlib.pyplot as plt
            plt.scatter([], [])
            plt.title("Nothingness and despair")
            plt.show()
        ''')
        with Execution(student_code) as e:
            self.assertEqual(check_for_plot('scatter', []), False)

        student_code = dedent('''
            import matplotlib.pyplot as plt
            plt.scatter([1,2,3], [4,5,6])
            plt.title("Some actual stuff")
            plt.show()
        ''')
        with Execution(student_code) as e:
            self.assertEqual(check_for_plot('scatter', [[1, 2, 3], [4, 5, 6]]),
                             False)
Beispiel #25
0
 def test_tifa(self):
     with Execution('0+"A"') as e:
         pass
     self.assertEqual(
         e.feedback, "TypeError<br><pre>unsupported operand "
         "type(s) for +: 'int' and 'str'</pre>\n")
Beispiel #26
0
    def test_files_not_handled_correctly(self):
        with Execution('open("not opened.txt")') as e:
            self.assertTrue(files_not_handled_correctly(1))
        self.assertEqual(
            e.message, "You have not closed all the files you "
            "were supposed to.")

        with Execution('open("not opened.txt")\nclose()') as e:
            self.assertTrue(files_not_handled_correctly(1))
        self.assertEqual(
            e.message, "You have attempted to call "
            "<code>close</code> as a function, but it is "
            "actually a method of the file object.")

        with Execution('open()') as e:
            self.assertTrue(files_not_handled_correctly(1))
        self.assertEqual(
            e.message, "You have called the <code>open</code> "
            "function without any arguments. It needs a "
            "filename.")

        with Execution('"filename.txt".open()') as e:
            self.assertTrue(files_not_handled_correctly(1))
        self.assertEqual(
            e.message, "You have attempted to call "
            "<code>open</code> as a method, but it is actually a "
            "built-in function.")

        with Execution('a = open("A.txt")\na.close()') as e:
            self.assertTrue(files_not_handled_correctly(2))
        self.assertEqual(
            e.message, "You have not opened all the files you "
            "were supposed to.")

        with Execution('a = open("A.txt")\nb = open("B.txt")'
                       '\na.close()\nb.close()') as e:
            self.assertTrue(files_not_handled_correctly(1))
        self.assertEqual(
            e.message, "You have opened more files than you "
            "were supposed to.")

        with Execution('a = open("A.txt")\n\na.close()\na.close()') as e:
            self.assertTrue(files_not_handled_correctly(1))
        self.assertEqual(
            e.message, "You have closed more files than you "
            "were supposed to.")

        with Execution('with open("A.txt") as out:\n  b = open("B.txt")'
                       '\n  b.close()') as e:
            self.assertTrue(files_not_handled_correctly(1))
        self.assertEqual(
            e.message, "You have opened more files than you "
            "were supposed to.")

        with Execution('with open("A.txt") as out:\n  print(out.read())') as e:
            self.assertTrue(files_not_handled_correctly("X.txt"))
        self.assertEqual(
            e.message, "You need the literal value "
            "<code>'X.txt'</code> in your code.")

        with Execution('with open("A.txt") as out:\n  print(out.read())') as e:
            self.assertFalse(files_not_handled_correctly("A.txt"))
        self.assertEqual(e.message, "No errors reported.")

        with Execution('a = open("filename.txt")\na.close()') as e:
            self.assertFalse(files_not_handled_correctly(1))
Beispiel #27
0
 def test_function_is_called(self):
     with Execution('a=[]\na.append(a)\na.pop()\n') as e:
         self.assertTrue(function_is_called('pop'))
         self.assertFalse(function_is_called('print'))
     self.assertEqual(e.message, "No errors reported.")
Beispiel #28
0
 def test_success(self):
     with Execution('a=0\na') as e:
         set_success()
     self.assertEqual(e.feedback, "Complete<br>Great work!")