summaryrefslogtreecommitdiff
path: root/python/problems/introduction/pythagorean_theorem/common.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/problems/introduction/pythagorean_theorem/common.py')
-rw-r--r--python/problems/introduction/pythagorean_theorem/common.py89
1 files changed, 55 insertions, 34 deletions
diff --git a/python/problems/introduction/pythagorean_theorem/common.py b/python/problems/introduction/pythagorean_theorem/common.py
index b2ae10c..5f59588 100644
--- a/python/problems/introduction/pythagorean_theorem/common.py
+++ b/python/problems/introduction/pythagorean_theorem/common.py
@@ -18,10 +18,38 @@ razdalja = v ** 2 * sin(2 * kot_rad) / g
print("Kroglo bo odneslo", razdalja, "metrov.")
'''
-#hint_type = {
-# 'plan': Hint('plan'),
-# 'no_input_call': Hint('no_input_call'),
-#}
+hint_type = {
+ 'plan': Hint('plan'),
+ 'name_error': HintSequence('name_error'),
+ 'unsupported_operand': HintSequence('unsupported_operand'),
+ 'syntax_error' : HintSequence('syntax_error'),
+ 'indentation_error': HintSequence('indentation_error'),
+ 'no_input_call' : Hint('no_input_call'),
+ 'radians': HintSequence('radians'),
+ 'printing': Hint('printing'),
+ 'math_functions': Hint('math_functions')
+}
+
+
+def almostEqual(a, b, prec=1):
+ """ Compares values a and b using at most <code>prec</code> decimal values. """
+ return int(a*10**prec) == int(b*10**prec)
+
+def stringAlmostEqual(s, a):
+ """ Searches string s for a value that is almost equal to a.
+
+ Args:
+ s (str): string to search
+ a (float): value to find in string
+
+ Returns:
+ bool: True if successful, else False
+ """
+ for v in s.split():
+ try:
+ if almostEqual(float(v), a):
+ return True
+ return False
def test(python, code):
# List of inputs: (expression to eval, stdin).
@@ -32,43 +60,35 @@ def test(python, code):
(None, '0\n100\n'),
(None, '90\n100\n'),
(None, '32\n747\n'),
- #(None, '212\n'),
- #(None, '-459.4\n'),
- #(None, '98.6\n'),
- #(None, '1832\n'),
]
test_out = [
'1000',
- '999.39'
- '999.39'
- #'100',
- #'-273',
- #'37',
- #'1000'
+ '999.39',
+ '999.39',
+ '0.0',
+ '0.0',
+ '50153.5'
]
# List of outputs: (expression result, stdout, stderr, exception).
answers = python(code=code, inputs=test_in, timeout=1.0)
outputs = [ans[1] for ans in answers]
- print (answers)
-
n_correct = 0
for output, correct in zip(outputs, test_out):
- if correct in output:
+ if stringAlmostEqual(output, correct):
n_correct += 1
return n_correct, len(test_in)
def hint(python, code):
# run one test first to see if there are any exceptions
- test_in = [(None, '212\n')]
- exc = python(code=code, inputs=test_in, timeout=1.0)[0][3]
- # have an exception!
+ test_in = [(None, '45\n')]
+ answer = python(code=code, inputs=test_in, timeout=1.0)
+ exc = answer[0][3]
+ # if have an exception!
if exc:
if 'NameError' in exc:
return [{'id':'name_error'}]
- if 'not callable' in exc:
- return [{'id':'not_callable'}]
if 'unsupported operand' in exc:
return [{'id':'unsupported_operand'}]
if 'SyntaxError' in exc:
@@ -76,27 +96,28 @@ def hint(python, code):
if 'IndentationError' in exc:
return [{'id':'indentation_error'}]
+ # if result if 893.996, angle is not converted to radians
+ if stringAlmostEqual(answer[0][1], 893.996):
+ return [{'id': 'radians'}]
- # the trick is to decide when to show the plan and when the first hint.
- # I implemented a simple idea: show plan, when code contains something from the
- # solution, but not input.
+ # show plan if student is lost
if not code or (not has_token_sequence(code, ['input']) and
- (has_token_sequence(code, ['32']) or
- has_token_sequence(code, ['=', '5']) or
+ (has_token_sequence(code, ['pi']) or
+ has_token_sequence(code, ['sin']) or
has_token_sequence(code, ['print']))):
return [{'id': 'plan'}]
# if input is not present in code, student needs to learn about input
- if not has_token_sequence(code, ['input']):
+ if not has_token_sequence(code, ['input']) or \
+ not has_token_sequence(code, ['float']):
return [{'id': 'no_input_call'}]
- # if tokens * or / or = are not in code, we have to teach them how to
- # evaluate expressions.
- if (not has_token_sequence(code, ['/']) or
- not has_token_sequence(code, ['*']) or
- not has_token_sequence(code, ['='])):
- return [{'id' : 'expressions_python'}]
+ # if tokens sqrt or ** are not in code, we have to teach them how to
+ # use math functions.
+ if (not has_token_sequence(code, ['sqrt']) or
+ not has_token_sequence(code, ['**']):
+ return [{'id' : 'math_functions'}]
# student is not using print function
if not has_token_sequence(code, ['print']):