summaryrefslogtreecommitdiff
path: root/python/problems/introduction/fahrenheit_to_celsius/common.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/problems/introduction/fahrenheit_to_celsius/common.py')
-rw-r--r--python/problems/introduction/fahrenheit_to_celsius/common.py41
1 files changed, 21 insertions, 20 deletions
diff --git a/python/problems/introduction/fahrenheit_to_celsius/common.py b/python/problems/introduction/fahrenheit_to_celsius/common.py
index 2e6c9b7..2962c55 100644
--- a/python/problems/introduction/fahrenheit_to_celsius/common.py
+++ b/python/problems/introduction/fahrenheit_to_celsius/common.py
@@ -1,6 +1,7 @@
# coding=utf-8
-from python.util import has_token_sequence
+from python.util import has_token_sequence, string_almost_equal, \
+ string_contains_number, get_tokens, get_numbers, get_exception_desc
from server.hints import Hint, HintSequence
id = 180
@@ -46,19 +47,28 @@ def test(python, code):
outputs = [ans[1] for ans in answers]
n_correct = 0
- for output, correct in zip(outputs, test_out):
+ tin = None
+ for i, (output, correct) in enumerate(zip(outputs, test_out)):
if correct in output:
n_correct += 1
+ else:
+ tin = test_in[i][1]
+ tout = correct
passed = n_correct == len(test_in)
hints = [{'id': 'test_results', 'args': {'passed': n_correct, 'total': len(test_in)}}]
+ if tin:
+ hints.append({'id': 'problematic_test_case', 'args': {'testin': str(tin), 'testout': str(tout)}})
return passed, hints
def hint(python, code):
+ tokens = get_tokens(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!
+ answer = python(code=code, inputs=test_in, timeout=1.0)
+ exc = answer[0][3]
+ exc_hint = get_exception_desc(answer[0][3])
if exc:
if 'NameError' in exc:
return [{'id':'name_error', 'args': {'message': exc}}]
@@ -68,31 +78,22 @@ def hint(python, code):
return [{'id':'unsupported_operand', 'args': {'message': exc}}]
elif 'TypeError' in exc:
return [{'id':'unsupported_operand', 'args': {'message': exc}}]
-
-
- # 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.
- if len(code.strip()) < 5 or (not has_token_sequence(code, ['input']) and
- (has_token_sequence(code, ['32']) or
- has_token_sequence(code, ['=', '5']) or
- has_token_sequence(code, ['print']))):
- return [{'id': 'plan'}]
-
+ else:
+ return exc_hint
# 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(tokens, ['input']):
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, ['='])):
+ if (not has_token_sequence(tokens, ['/']) or
+ not has_token_sequence(tokens, ['*']) or
+ not has_token_sequence(tokens, ['='])):
return [{'id' : 'expressions_python'}]
# student is not using print function
- if not has_token_sequence(code, ['print']):
+ if not has_token_sequence(tokens, ['print']):
return [{'id' : 'printing'}]
return None