diff options
author | Prabhu Ramachandran | 2016-09-29 12:33:08 +0530 |
---|---|---|
committer | GitHub | 2016-09-29 12:33:08 +0530 |
commit | 8b410d3764b8f0e5c7a14e292a5583ef93c4257e (patch) | |
tree | 18b9ca9a9dd202c61a83244337859fb4ba8b4e6c | |
parent | 8e4ead8ab4caa9366e5357840e1912cbfb8cdb85 (diff) | |
parent | 086620367c481009c9caed68660865ca127a9520 (diff) | |
download | online_test-8b410d3764b8f0e5c7a14e292a5583ef93c4257e.tar.gz online_test-8b410d3764b8f0e5c7a14e292a5583ef93c4257e.tar.bz2 online_test-8b410d3764b8f0e5c7a14e292a5583ef93c4257e.zip |
Merge pull request #141 from maheshgudi/refactor_stdio
Refactor stdio
-rw-r--r-- | yaksh/bash_stdio_evaluator.py | 17 | ||||
-rw-r--r-- | yaksh/cpp_stdio_evaluator.py | 15 | ||||
-rw-r--r-- | yaksh/documentation/moderator_docs/creating_question.rst | 10 | ||||
-rwxr-xr-x[-rw-r--r--] | yaksh/evaluator_tests/test_bash_evaluation.py | 6 | ||||
-rwxr-xr-x[-rw-r--r--] | yaksh/evaluator_tests/test_c_cpp_evaluation.py | 17 | ||||
-rwxr-xr-x[-rw-r--r--] | yaksh/evaluator_tests/test_java_evaluation.py | 8 | ||||
-rwxr-xr-x[-rw-r--r--] | yaksh/evaluator_tests/test_python_evaluation.py | 14 | ||||
-rw-r--r-- | yaksh/java_stdio_evaluator.py | 14 | ||||
-rw-r--r-- | yaksh/python_stdio_evaluator.py | 4 | ||||
-rw-r--r-- | yaksh/python_stdout_evaluator.py | 65 | ||||
-rw-r--r-- | yaksh/stdio_evaluator.py | 20 |
11 files changed, 68 insertions, 122 deletions
diff --git a/yaksh/bash_stdio_evaluator.py b/yaksh/bash_stdio_evaluator.py index 56f2e35..8ff0743 100644 --- a/yaksh/bash_stdio_evaluator.py +++ b/yaksh/bash_stdio_evaluator.py @@ -3,12 +3,12 @@ import subprocess import os from os.path import isfile -#local imports -from code_evaluator import CodeEvaluator -from stdio_evaluator import Evaluator +# local imports +from stdio_evaluator import StdIOEvaluator from file_utils import copy_files, delete_files -class BashStdioEvaluator(CodeEvaluator): + +class BashStdioEvaluator(StdIOEvaluator): """Evaluates Bash StdIO based code""" def setup(self): @@ -41,9 +41,8 @@ class BashStdioEvaluator(CodeEvaluator): stdout=subprocess.PIPE, stderr=subprocess.PIPE ) - evaluator = Evaluator() - success, err = evaluator.evaluate(user_answer, proc, - expected_input, - expected_output - ) + success, err = self.evaluate_stdio(user_answer, proc, + expected_input, + expected_output + ) return success, err diff --git a/yaksh/cpp_stdio_evaluator.py b/yaksh/cpp_stdio_evaluator.py index 4ea1bbf..720ed0f 100644 --- a/yaksh/cpp_stdio_evaluator.py +++ b/yaksh/cpp_stdio_evaluator.py @@ -4,12 +4,12 @@ import os from os.path import isfile #local imports -from code_evaluator import CodeEvaluator -from stdio_evaluator import Evaluator + +from stdio_evaluator import StdIOEvaluator from file_utils import copy_files, delete_files -class CppStdioEvaluator(CodeEvaluator): +class CppStdioEvaluator(StdIOEvaluator): """Evaluates C StdIO based code""" def setup(self): @@ -76,11 +76,10 @@ class CppStdioEvaluator(CodeEvaluator): stdout=subprocess.PIPE, stderr=subprocess.PIPE ) - evaluator = Evaluator() - success, err = evaluator.evaluate(user_answer, proc, - expected_input, - expected_output - ) + success, err = self.evaluate_stdio(user_answer, proc, + expected_input, + expected_output + ) os.remove(self.ref_output_path) else: err = "Error:" diff --git a/yaksh/documentation/moderator_docs/creating_question.rst b/yaksh/documentation/moderator_docs/creating_question.rst index d80b437..cdb20ef 100644 --- a/yaksh/documentation/moderator_docs/creating_question.rst +++ b/yaksh/documentation/moderator_docs/creating_question.rst @@ -62,11 +62,15 @@ How to write Test cases Finally click on Save & Add Testcase Button to save the test case. - * **Create Standard out Based Test Case** + * **Create Standard Input/Output Based Test Case** - Select Stdout Based TestCase from Test Case Type field and click on Save & Add Testcase button to save the question. + Select StdIO Based TestCase from Test Case Type field and click on Save & Add Testcase button to save the question. - In Expected Output Field type the expected output for a particular question. For e.g type 6 if the output of the user code is 6. + In Expected input field, enter the value(s) that will be passed to the students' code through a standard I/O stream. + + .. note:: If there are multiple input values in a test case, enter the values in new line. + + In Expected Output Field, enter the expected output for that test case. For e.g type 6 if the output of the user code is 6. * **Create MCQ Based Test Case** diff --git a/yaksh/evaluator_tests/test_bash_evaluation.py b/yaksh/evaluator_tests/test_bash_evaluation.py index addc5e6..084e5e4 100644..100755 --- a/yaksh/evaluator_tests/test_bash_evaluation.py +++ b/yaksh/evaluator_tests/test_bash_evaluation.py @@ -88,7 +88,7 @@ class BashStdioEvaluationTestCases(unittest.TestCase): "test_case_data": test_case_data } result = get_class.evaluate(**kwargs) - self.assertEquals(result.get('error'), "Correct Answer") + self.assertEquals(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) def test_array_input(self): @@ -108,7 +108,7 @@ class BashStdioEvaluationTestCases(unittest.TestCase): "test_case_data": test_case_data } result = get_class.evaluate(**kwargs) - self.assertEquals(result.get('error'), "Correct Answer") + self.assertEquals(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) def test_incorrect_answer(self): @@ -142,7 +142,7 @@ class BashStdioEvaluationTestCases(unittest.TestCase): "test_case_data": test_case_data } result = get_class.evaluate(**kwargs) - self.assertEquals(result.get('error'), "Correct Answer") + self.assertEquals(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) if __name__ == '__main__': diff --git a/yaksh/evaluator_tests/test_c_cpp_evaluation.py b/yaksh/evaluator_tests/test_c_cpp_evaluation.py index 0042d0f..c6994f6 100644..100755 --- a/yaksh/evaluator_tests/test_c_cpp_evaluation.py +++ b/yaksh/evaluator_tests/test_c_cpp_evaluation.py @@ -84,7 +84,6 @@ class CAssertionEvaluationTestCases(unittest.TestCase): self.assertTrue(result.get('success')) self.assertEquals(result.get('error'), "Correct answer") - class CppStdioEvaluationTestCases(unittest.TestCase): def setUp(self): @@ -107,7 +106,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase): 'test_case_data': self.test_case_data } result = get_class.evaluate(**kwargs) - self.assertEquals(result.get('error'), "Correct Answer") + self.assertEquals(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) def test_array_input(self): @@ -127,7 +126,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase): 'test_case_data': self.test_case_data } result = get_class.evaluate(**kwargs) - self.assertEquals(result.get('error'), "Correct Answer") + self.assertEquals(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) def test_string_input(self): @@ -145,7 +144,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase): 'test_case_data': self.test_case_data } result = get_class.evaluate(**kwargs) - self.assertEquals(result.get('error'), "Correct Answer") + self.assertEquals(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) def test_incorrect_answer(self): @@ -208,7 +207,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase): 'test_case_data': self.test_case_data } result = get_class.evaluate(**kwargs) - self.assertEquals(result.get('error'), "Correct Answer") + self.assertEquals(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) def test_cpp_correct_answer(self): @@ -225,7 +224,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase): 'test_case_data': self.test_case_data } result = get_class.evaluate(**kwargs) - self.assertEquals(result.get('error'), "Correct Answer") + self.assertEquals(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) def test_cpp_array_input(self): @@ -246,7 +245,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase): 'test_case_data': self.test_case_data } result = get_class.evaluate(**kwargs) - self.assertEquals(result.get('error'), "Correct Answer") + self.assertEquals(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) def test_cpp_string_input(self): @@ -265,7 +264,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase): 'test_case_data': self.test_case_data } result = get_class.evaluate(**kwargs) - self.assertEquals(result.get('error'), "Correct Answer") + self.assertEquals(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) def test_cpp_incorrect_answer(self): @@ -332,7 +331,7 @@ class CppStdioEvaluationTestCases(unittest.TestCase): 'test_case_data': self.test_case_data } result = get_class.evaluate(**kwargs) - self.assertEquals(result.get('error'), "Correct Answer") + self.assertEquals(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) if __name__ == '__main__': diff --git a/yaksh/evaluator_tests/test_java_evaluation.py b/yaksh/evaluator_tests/test_java_evaluation.py index 74ac677..60afb3b 100644..100755 --- a/yaksh/evaluator_tests/test_java_evaluation.py +++ b/yaksh/evaluator_tests/test_java_evaluation.py @@ -127,7 +127,7 @@ class JavaStdioEvaluationTestCases(unittest.TestCase): 'test_case_data': self.test_case_data } result = get_class.evaluate(**kwargs) - self.assertEquals(result.get('error'), "Correct Answer") + self.assertEquals(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) def test_array_input(self): @@ -149,7 +149,7 @@ class JavaStdioEvaluationTestCases(unittest.TestCase): 'test_case_data': self.test_case_data } result = get_class.evaluate(**kwargs) - self.assertEquals(result.get('error'), "Correct Answer") + self.assertEquals(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) def test_incorrect_answer(self): @@ -219,7 +219,7 @@ class JavaStdioEvaluationTestCases(unittest.TestCase): 'test_case_data': self.test_case_data } result = get_class.evaluate(**kwargs) - self.assertEquals(result.get('error'), "Correct Answer") + self.assertEquals(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) def test_string_input(self): @@ -239,7 +239,7 @@ class JavaStdioEvaluationTestCases(unittest.TestCase): 'test_case_data': self.test_case_data } result = get_class.evaluate(**kwargs) - self.assertEquals(result.get('error'), "Correct Answer") + self.assertEquals(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) if __name__ == '__main__': diff --git a/yaksh/evaluator_tests/test_python_evaluation.py b/yaksh/evaluator_tests/test_python_evaluation.py index 2a109d5..b72d26b 100644..100755 --- a/yaksh/evaluator_tests/test_python_evaluation.py +++ b/yaksh/evaluator_tests/test_python_evaluation.py @@ -344,7 +344,7 @@ class PythonStdoutEvaluationTestCases(unittest.TestCase): result = evaluator.evaluate(**kwargs) # Then - self.assertEqual(result.get('error'), "Correct Answer") + self.assertEqual(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) def test_incorrect_answer(self): @@ -360,7 +360,7 @@ class PythonStdoutEvaluationTestCases(unittest.TestCase): # Then self.assertFalse(result.get('success')) - self.assertIn("Incorrect Answer", result.get('error')) + self.assertIn("Incorrect answer", result.get('error')) def test_infinite_loop(self): # Given @@ -404,7 +404,7 @@ class PythonStdIOEvaluationTestCases(unittest.TestCase): # Then self.assertTrue(result.get('success')) - self.assertIn("Correct Answer", result.get('error')) + self.assertIn("Correct answer", result.get('error')) def test_correct_answer_list(self): # Given @@ -427,7 +427,7 @@ class PythonStdIOEvaluationTestCases(unittest.TestCase): # Then self.assertTrue(result.get('success')) - self.assertIn("Correct Answer", result.get('error')) + self.assertIn("Correct answer", result.get('error')) def test_correct_answer_string(self): # Given @@ -451,7 +451,7 @@ class PythonStdIOEvaluationTestCases(unittest.TestCase): # Then self.assertTrue(result.get('success')) - self.assertIn("Correct Answer", result.get('error')) + self.assertIn("Correct answer", result.get('error')) def test_incorrect_answer_integer(self): # Given @@ -474,7 +474,7 @@ class PythonStdIOEvaluationTestCases(unittest.TestCase): # Then self.assertFalse(result.get('success')) - self.assertIn("Incorrect Answer", result.get('error')) + self.assertIn("Incorrect answer", result.get('error')) def test_file_based_answer(self): # Given @@ -497,7 +497,7 @@ class PythonStdIOEvaluationTestCases(unittest.TestCase): result = evaluator.evaluate(**kwargs) # Then - self.assertEqual(result.get('error'), "Correct Answer") + self.assertEqual(result.get('error'), "Correct answer") self.assertTrue(result.get('success')) if __name__ == '__main__': diff --git a/yaksh/java_stdio_evaluator.py b/yaksh/java_stdio_evaluator.py index 27dd4a9..f4b8773 100644 --- a/yaksh/java_stdio_evaluator.py +++ b/yaksh/java_stdio_evaluator.py @@ -4,12 +4,11 @@ import os from os.path import isfile #local imports -from code_evaluator import CodeEvaluator -from stdio_evaluator import Evaluator +from stdio_evaluator import StdIOEvaluator from file_utils import copy_files, delete_files -class JavaStdioEvaluator(CodeEvaluator): +class JavaStdioEvaluator(StdIOEvaluator): """Evaluates Java StdIO based code""" def setup(self): @@ -61,11 +60,10 @@ class JavaStdioEvaluator(CodeEvaluator): stdout=subprocess.PIPE, stderr=subprocess.PIPE ) - evaluator = Evaluator() - success, err = evaluator.evaluate(user_answer, proc, - expected_input, - expected_output - ) + success, err = self.evaluate_stdio(user_answer, proc, + expected_input, + expected_output + ) os.remove(self.user_output_path) else: err = "Compilation Error:" diff --git a/yaksh/python_stdio_evaluator.py b/yaksh/python_stdio_evaluator.py index 4a02267..2cfd9c8 100644 --- a/yaksh/python_stdio_evaluator.py +++ b/yaksh/python_stdio_evaluator.py @@ -53,11 +53,11 @@ class PythonStdioEvaluator(CodeEvaluator): tb = None if self.output_value == expected_output: success = True - err = "Correct Answer" + err = "Correct answer" else: success = False err = dedent(""" - Incorrect Answer: + Incorrect answer: Given input - {0} Expected output - {1} Your output - {2} diff --git a/yaksh/python_stdout_evaluator.py b/yaksh/python_stdout_evaluator.py deleted file mode 100644 index 8f69b24..0000000 --- a/yaksh/python_stdout_evaluator.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python -import sys -import traceback -import os -from os.path import join -import importlib -from contextlib import contextmanager - -# local imports -from code_evaluator import CodeEvaluator -from file_utils import copy_files, delete_files - - -@contextmanager -def redirect_stdout(): - from StringIO import StringIO - new_target = StringIO() - - old_target, sys.stdout = sys.stdout, new_target # replace sys.stdout - try: - yield new_target # run some code with the replaced stdout - finally: - sys.stdout = old_target # restore to the previous value - - -class PythonStdoutEvaluator(CodeEvaluator): - """Tests the Python code obtained from Code Server""" - - def teardown(self): - super(PythonStdoutEvaluator, self).teardown() - # Delete the created file. - if self.files: - delete_files(self.files) - - def compile_code(self, user_answer, file_paths, expected_output): - self.files = [] - if file_paths: - self.files = copy_files(file_paths) - if hasattr(self, 'output_value'): - return None - else: - submitted = compile(user_answer, '<string>', mode='exec') - with redirect_stdout() as output_buffer: - exec_scope = {} - exec submitted in exec_scope - self.output_value = output_buffer.getvalue() - return self.output_value - - def check_code(self, user_answer, file_paths, expected_output): - success = False - tb = None - if expected_output in user_answer: - success = False - err = ("Incorrect Answer: Please avoid " - "printing the expected output directly" - ) - elif self.output_value == expected_output: - success = True - err = "Correct answer" - - else: - success = False - err = "Incorrect Answer" - del tb - return success, err diff --git a/yaksh/stdio_evaluator.py b/yaksh/stdio_evaluator.py index 4f5cfaf..efb2ae5 100644 --- a/yaksh/stdio_evaluator.py +++ b/yaksh/stdio_evaluator.py @@ -1,6 +1,18 @@ -class Evaluator(object): +# Local imports +from code_evaluator import CodeEvaluator - def evaluate(self, user_answer, proc, expected_input, expected_output): + +class StdIOEvaluator(CodeEvaluator): + + def setup(self): + super(StdIOEvaluator, self).setup() + pass + + def teardown(self): + super(StdIOEvaluator, self).teardown() + pass + + def evaluate_stdio(self, user_answer, proc, expected_input, expected_output): success = False ip = expected_input.replace(",", " ") user_output, output_err = proc.communicate(input='{0}\n'.format(ip)) @@ -13,9 +25,9 @@ class Evaluator(object): format(expected_input, repr(expected_output)) if output_err == '': if user_output == expected_output: - success, err = True, "Correct Answer" + success, err = True, "Correct answer" else: - err = " Incorrect Answer\n" + error_msg +\ + err = " Incorrect answer\n" + error_msg +\ "\n Your output is {0}".format(repr(user_output)) else: err = "Error:"+"\n"+output_err |