From 70a35ac2a001bd9638d9db5ed645d00f94ae4666 Mon Sep 17 00:00:00 2001 From: maheshgudi Date: Mon, 6 Nov 2017 16:34:37 +0530 Subject: Change module compare_stdio to error_messages --- yaksh/compare_stdio.py | 44 --------------------------- yaksh/error_messages.py | 60 +++++++++++++++++++++++++++++++++++++ yaksh/grader.py | 16 +++++++--- yaksh/python_assertion_evaluator.py | 21 ++++--------- yaksh/python_stdio_evaluator.py | 2 +- yaksh/stdio_evaluator.py | 2 +- yaksh/templates/exam.html | 15 ++++------ 7 files changed, 85 insertions(+), 75 deletions(-) delete mode 100644 yaksh/compare_stdio.py create mode 100644 yaksh/error_messages.py (limited to 'yaksh') diff --git a/yaksh/compare_stdio.py b/yaksh/compare_stdio.py deleted file mode 100644 index 9c13a98..0000000 --- a/yaksh/compare_stdio.py +++ /dev/null @@ -1,44 +0,0 @@ -try: - from itertools import zip_longest -except ImportError: - from itertools import izip_longest as zip_longest - - -def _get_incorrect_user_lines(exp_lines, user_lines): - err_line_numbers = [] - for line_no, (expected_line, user_line) in \ - enumerate(zip_longest(exp_lines, user_lines)): - if not user_line or not expected_line or \ - user_line.strip() != expected_line.strip(): - err_line_numbers.append(line_no) - return err_line_numbers - -def compare_outputs(expected_output, user_output, given_input=None): - given_lines = user_output.splitlines() - exp_lines = expected_output.splitlines() - msg = {"given_input":given_input, - "expected_output": exp_lines, - "user_output":given_lines, - "type": "stdio" - } - ng = len(given_lines) - ne = len(exp_lines) - err_line_numbers = _get_incorrect_user_lines(exp_lines, given_lines) - msg["error_line_numbers"] = err_line_numbers - if ng != ne: - msg["error_msg"] = ("Incorrect Answer: " - + "We had expected {} number of lines. ".format(ne) - + "We got {} number of lines.".format(ng) - ) - return False, msg - else: - if err_line_numbers: - msg["error_msg"] = ("Incorrect Answer: " - + "Line number(s) {0} did not match." - .format(", ".join(map( - str,[x+1 for x in err_line_numbers] - )))) - return False, msg - else: - msg["error_msg"] = "Correct Answer" - return True, msg diff --git a/yaksh/error_messages.py b/yaksh/error_messages.py new file mode 100644 index 0000000..5453edd --- /dev/null +++ b/yaksh/error_messages.py @@ -0,0 +1,60 @@ +try: + from itertools import zip_longest +except ImportError: + from itertools import izip_longest as zip_longest + +def prettify_exceptions(exception, message, traceback=None, testcase=None): + err = {"type": "assertion", + "exception": exception, + "traceback": traceback, + "message": message + } + + if exception == 'AssertionError': + value = ("Expected answer from the" + + " test case did not match the output") + err["message"] = value + err["traceback"] = None + if testcase: + err["test_case"] = testcase + return err + +def _get_incorrect_user_lines(exp_lines, user_lines): + err_line_numbers = [] + for line_no, (expected_line, user_line) in \ + enumerate(zip_longest(exp_lines, user_lines)): + if not user_line or not expected_line or \ + user_line.strip() != expected_line.strip(): + err_line_numbers.append(line_no) + return err_line_numbers + +def compare_outputs(expected_output, user_output, given_input=None): + given_lines = user_output.splitlines() + exp_lines = expected_output.splitlines() + msg = {"given_input":given_input, + "expected_output": exp_lines, + "user_output":given_lines, + "type": "stdio" + } + ng = len(given_lines) + ne = len(exp_lines) + err_line_numbers = _get_incorrect_user_lines(exp_lines, given_lines) + msg["error_line_numbers"] = err_line_numbers + if ng != ne: + msg["error_msg"] = ("Incorrect Answer: " + + "We had expected {} number of lines. "\ + .format(ne) + + "We got {} number of lines.".format(ng) + ) + return False, msg + else: + if err_line_numbers: + msg["error_msg"] = ("Incorrect Answer: " + + "Line number(s) {0} did not match." + .format(", ".join(map( + str,[x+1 for x in err_line_numbers] + )))) + return False, msg + else: + msg["error_msg"] = "Correct Answer" + return True, msg diff --git a/yaksh/grader.py b/yaksh/grader.py index a9a3738..4b4c892 100644 --- a/yaksh/grader.py +++ b/yaksh/grader.py @@ -21,7 +21,7 @@ except ImportError: # Local imports from .settings import SERVER_TIMEOUT from .language_registry import create_evaluator_instance - +from .error_messages import prettify_exceptions MY_DIR = abspath(dirname(__file__)) registry = None @@ -141,7 +141,8 @@ class Grader(object): for idx, test_case_instance in enumerate(test_case_instances): test_case_success = False test_case_instance.compile_code() - test_case_success, err, mark_fraction = test_case_instance.check_code() + eval_result = test_case_instance.check_code() + test_case_success, err, mark_fraction = eval_result if test_case_success: weight += mark_fraction * test_case_instance.weight else: @@ -154,7 +155,10 @@ class Grader(object): test_case_instance.teardown() except TimeoutException: - error.append(self.timeout_msg) + error.append(prettify_exceptions("TimeoutException", + self.timeout_msg + ) + ) except OSError: msg = traceback.format_exc(limit=0) error.append("Error: {0}".format(msg)) @@ -163,7 +167,11 @@ class Grader(object): tb_list = traceback.format_exception(exc_type, exc_value, exc_tb) if len(tb_list) > 2: del tb_list[1:3] - error.append("Error: {0}".format("".join(tb_list))) + error.append(prettify_exceptions(exc_type.__name__, + str(exc_value), + "".join(tb_list), + ) + ) finally: # Set back any original signal handler. set_original_signal_handler(prev_handler) diff --git a/yaksh/python_assertion_evaluator.py b/yaksh/python_assertion_evaluator.py index af89fc3..8c24e24 100644 --- a/yaksh/python_assertion_evaluator.py +++ b/yaksh/python_assertion_evaluator.py @@ -11,6 +11,7 @@ import importlib from .file_utils import copy_files, delete_files from .base_evaluator import BaseEvaluator from .grader import TimeoutException +from .error_messages import prettify_exceptions class PythonAssertionEvaluator(BaseEvaluator): @@ -74,26 +75,16 @@ class PythonAssertionEvaluator(BaseEvaluator): exec(_tests, self.exec_scope) except TimeoutException: raise - except AssertionError: - exc_type, exc_value, exc_tb = sys.exc_info() - value = "Expected answer from the test case didnt match the output" - err = {"type": "assertion", - "test_case": self.test_case, - "exception": exc_type.__name__, - "message": value, - } except Exception: exc_type, exc_value, exc_tb = sys.exc_info() tb_list = traceback.format_exception(exc_type, exc_value, exc_tb) if len(tb_list) > 2: del tb_list[1:3] - - err = {"type": "assertion", - "traceback": "".join(tb_list), - "exception": exc_type.__name__, - "message": str(exc_value) - } - + err = prettify_exceptions(exc_type.__name__, + str(exc_value), + "".join(tb_list), + self.test_case + ) else: success = True err = None diff --git a/yaksh/python_stdio_evaluator.py b/yaksh/python_stdio_evaluator.py index 2b443a7..b08103a 100644 --- a/yaksh/python_stdio_evaluator.py +++ b/yaksh/python_stdio_evaluator.py @@ -9,7 +9,7 @@ except ImportError: # Local imports from .file_utils import copy_files, delete_files from .base_evaluator import BaseEvaluator -from .compare_stdio import compare_outputs +from .error_messages import compare_outputs @contextmanager diff --git a/yaksh/stdio_evaluator.py b/yaksh/stdio_evaluator.py index 5e4ce18..55adb5c 100644 --- a/yaksh/stdio_evaluator.py +++ b/yaksh/stdio_evaluator.py @@ -5,7 +5,7 @@ import signal # Local imports from .base_evaluator import BaseEvaluator from .grader import TimeoutException -from .compare_stdio import compare_outputs +from .error_messages import compare_outputs class StdIOEvaluator(BaseEvaluator): diff --git a/yaksh/templates/exam.html b/yaksh/templates/exam.html index 8b573d4..1d7af9c 100644 --- a/yaksh/templates/exam.html +++ b/yaksh/templates/exam.html @@ -80,6 +80,7 @@ {% block main %} {% endblock %} +
{% if question.type == 'code' or question.type == 'upload' %} {% if error_message %}
@@ -92,28 +93,22 @@
 {{error|safe}} 
{% elif error.type == 'assertion' %} {% if error.test_case %} - - - - - - -
We tried calling your function with the following test case:{{error.test_case}}
+ We tried you code with the following test case:

+
{{error.test_case}}
{% endif %}

The following error took place:

- + {% if error.traceback %} - + {% endif %} -- cgit
Exception Name: {{error.exception}} - {{error.exception}}
Exception Message: {{error.message}}
Full exception: Full Traceback:
{{error.traceback}}