From d8847656ba79e51c96c6e3650374aaf616c375dc Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Thu, 30 Apr 2015 11:21:49 +0530 Subject: Code Review: Code Refactoring --- testapp/exam/java_code_evaluator.py | 166 ++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 testapp/exam/java_code_evaluator.py (limited to 'testapp/exam/java_code_evaluator.py') diff --git a/testapp/exam/java_code_evaluator.py b/testapp/exam/java_code_evaluator.py new file mode 100644 index 0000000..4a80acd --- /dev/null +++ b/testapp/exam/java_code_evaluator.py @@ -0,0 +1,166 @@ +#!/usr/bin/env python +import traceback +import pwd +import os +from os.path import join, isfile +import subprocess +import importlib + +# local imports +# from c_code_evaluator import CCodeEvaluator +from code_evaluator import CodeEvaluator +# from language_registry import registry + + +class JavaCodeEvaluator(CodeEvaluator): + """Tests the Java code obtained from Code Server""" + def __init__(self, test_case_data, language, user_answer, + ref_code_path=None, in_dir=None): + super(JavaCodeEvaluator, self).__init__(test_case_data, language, user_answer, + ref_code_path, in_dir) + self.submit_path = self.create_submit_code_file('Test.java') + self.test_case_args = self.setup_code_evaluator() + + # Private Protocol ########## + def setup_code_evaluator(self): + super(JavaCodeEvaluator, self).setup_code_evaluator() + + ref_path, test_case_path = self.set_test_code_file_path(self.ref_code_path) + + # Set file paths + java_student_directory = os.getcwd() + '/' + java_ref_file_name = (ref_path.split('/')[-1]).split('.')[0] + + # Set command variables + compile_command = 'javac {0}'.format(submit_path), + compile_main = ('javac {0} -classpath ' + '{1} -d {2}').format(ref_path, + java_student_directory, + java_student_directory) + run_command_args = "java -cp {0} {1}".format(java_student_directory, + java_ref_file_name) + remove_user_output = "{0}{1}.class".format(java_student_directory, + 'Test') + remove_ref_output = "{0}{1}.class".format(java_student_directory, + java_ref_file_name) + + return ref_path, submit_path, compile_command, compile_main, run_command_args, remove_user_output, remove_ref_output + + def teardown_code_evaluator(self): + # Delete the created file. + super(JavaCodeEvaluator, self).teardown_code_evaluator() + os.remove(self.submit_path) + + + # Public Protocol ########## + # def evaluate_code(self): + # submit_path = self.create_submit_code_file('Test.java') + # ref_path, test_case_path = self.set_test_code_file_path(self.ref_code_path) + # success = False + + # # Set file paths + # java_student_directory = os.getcwd() + '/' + # java_ref_file_name = (ref_path.split('/')[-1]).split('.')[0] + + # # Set command variables + # compile_command = 'javac {0}'.format(submit_path), + # compile_main = ('javac {0} -classpath ' + # '{1} -d {2}').format(ref_path, + # java_student_directory, + # java_student_directory) + # run_command_args = "java -cp {0} {1}".format(java_student_directory, + # java_ref_file_name) + # remove_user_output = "{0}{1}.class".format(java_student_directory, + # 'Test') + # remove_ref_output = "{0}{1}.class".format(java_student_directory, + # java_ref_file_name) + + # success, err = self.check_code(ref_path, submit_path, compile_command, + # compile_main, run_command_args, + # remove_user_output, remove_ref_output) + + # # Delete the created file. + # os.remove(submit_path) + + # return success, err + + def check_code(self, ref_code_path, submit_code_path, compile_command, + compile_main, run_command_args, remove_user_output, + remove_ref_output): + """ Function validates student code using instructor code as + reference.The first argument ref_code_path, is the path to + instructor code, it is assumed to have executable permission. + The second argument submit_code_path, is the path to the student + code, it is assumed to have executable permission. + + Returns + -------- + + returns (True, "Correct answer") : If the student function returns + expected output when called by reference code. + + returns (False, error_msg): If the student function fails to return + expected output when called by reference code. + + Returns (False, error_msg): If mandatory arguments are not files or + if the required permissions are not given to the file(s). + + """ + if not isfile(ref_code_path): + return False, "No file at %s or Incorrect path" % ref_code_path + if not isfile(submit_code_path): + return False, 'No file at %s or Incorrect path' % submit_code_path + + success = False + # output_path = os.getcwd() + '/output' + ret = self.compile_command(compile_command) + proc, stdnt_stderr = ret + # if self.language == "java": + stdnt_stderr = self.remove_null_substitute_char(stdnt_stderr) + + # Only if compilation is successful, the program is executed + # And tested with testcases + if stdnt_stderr == '': + ret = self.compile_command(compile_main) + proc, main_err = ret + # if self.language == "java": + main_err = self.remove_null_substitute_char(main_err) + + if main_err == '': + ret = self.run_command(run_command_args, stdin=None, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + proc, stdout, stderr = ret + if proc.returncode == 0: + success, err = True, "Correct answer" + else: + err = stdout + "\n" + stderr + os.remove(remove_ref_output) + else: + err = "Error:" + try: + error_lines = main_err.splitlines() + for e in error_lines: + if ':' in e: + err = err + "\n" + e.split(":", 1)[1] + else: + err = err + "\n" + e + except: + err = err + "\n" + main_err + os.remove(remove_user_output) + else: + err = "Compilation Error:" + try: + error_lines = stdnt_stderr.splitlines() + for e in error_lines: + if ':' in e: + err = err + "\n" + e.split(":", 1)[1] + else: + err = err + "\n" + e + except: + err = err + "\n" + stdnt_stderr + + return success, err + + +# registry.register('java', EvaluateJavaCode) -- cgit From 3e29dc7f6df7019562b179872b43cb13c7483738 Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Thu, 30 Apr 2015 12:41:17 +0530 Subject: - Seperate testcases, Modify views, models, templates for compatibility - Change functions names in code_evaluator --- testapp/exam/java_code_evaluator.py | 68 ++++++++----------------------------- 1 file changed, 15 insertions(+), 53 deletions(-) (limited to 'testapp/exam/java_code_evaluator.py') diff --git a/testapp/exam/java_code_evaluator.py b/testapp/exam/java_code_evaluator.py index 4a80acd..709a0a1 100644 --- a/testapp/exam/java_code_evaluator.py +++ b/testapp/exam/java_code_evaluator.py @@ -7,23 +7,21 @@ import subprocess import importlib # local imports -# from c_code_evaluator import CCodeEvaluator from code_evaluator import CodeEvaluator -# from language_registry import registry class JavaCodeEvaluator(CodeEvaluator): """Tests the Java code obtained from Code Server""" - def __init__(self, test_case_data, language, user_answer, + def __init__(self, test_case_data, test, language, user_answer, ref_code_path=None, in_dir=None): - super(JavaCodeEvaluator, self).__init__(test_case_data, language, user_answer, + super(JavaCodeEvaluator, self).__init__(test_case_data, test, language, user_answer, ref_code_path, in_dir) self.submit_path = self.create_submit_code_file('Test.java') - self.test_case_args = self.setup_code_evaluator() + self.test_case_args = self._setup() # Private Protocol ########## - def setup_code_evaluator(self): - super(JavaCodeEvaluator, self).setup_code_evaluator() + def _setup(self): + super(JavaCodeEvaluator, self)._setup() ref_path, test_case_path = self.set_test_code_file_path(self.ref_code_path) @@ -32,7 +30,7 @@ class JavaCodeEvaluator(CodeEvaluator): java_ref_file_name = (ref_path.split('/')[-1]).split('.')[0] # Set command variables - compile_command = 'javac {0}'.format(submit_path), + compile_command = 'javac {0}'.format(self.submit_path), compile_main = ('javac {0} -classpath ' '{1} -d {2}').format(ref_path, java_student_directory, @@ -44,47 +42,14 @@ class JavaCodeEvaluator(CodeEvaluator): remove_ref_output = "{0}{1}.class".format(java_student_directory, java_ref_file_name) - return ref_path, submit_path, compile_command, compile_main, run_command_args, remove_user_output, remove_ref_output + return ref_path, self.submit_path, compile_command, compile_main, run_command_args, remove_user_output, remove_ref_output - def teardown_code_evaluator(self): + def _teardown(self): # Delete the created file. - super(JavaCodeEvaluator, self).teardown_code_evaluator() + super(JavaCodeEvaluator, self)._teardown() os.remove(self.submit_path) - - # Public Protocol ########## - # def evaluate_code(self): - # submit_path = self.create_submit_code_file('Test.java') - # ref_path, test_case_path = self.set_test_code_file_path(self.ref_code_path) - # success = False - - # # Set file paths - # java_student_directory = os.getcwd() + '/' - # java_ref_file_name = (ref_path.split('/')[-1]).split('.')[0] - - # # Set command variables - # compile_command = 'javac {0}'.format(submit_path), - # compile_main = ('javac {0} -classpath ' - # '{1} -d {2}').format(ref_path, - # java_student_directory, - # java_student_directory) - # run_command_args = "java -cp {0} {1}".format(java_student_directory, - # java_ref_file_name) - # remove_user_output = "{0}{1}.class".format(java_student_directory, - # 'Test') - # remove_ref_output = "{0}{1}.class".format(java_student_directory, - # java_ref_file_name) - - # success, err = self.check_code(ref_path, submit_path, compile_command, - # compile_main, run_command_args, - # remove_user_output, remove_ref_output) - - # # Delete the created file. - # os.remove(submit_path) - - # return success, err - - def check_code(self, ref_code_path, submit_code_path, compile_command, + def _check_code(self, ref_code_path, submit_code_path, compile_command, compile_main, run_command_args, remove_user_output, remove_ref_output): """ Function validates student code using instructor code as @@ -113,21 +78,21 @@ class JavaCodeEvaluator(CodeEvaluator): success = False # output_path = os.getcwd() + '/output' - ret = self.compile_command(compile_command) + ret = self._compile_command(compile_command) proc, stdnt_stderr = ret # if self.language == "java": - stdnt_stderr = self.remove_null_substitute_char(stdnt_stderr) + stdnt_stderr = self._remove_null_substitute_char(stdnt_stderr) # Only if compilation is successful, the program is executed # And tested with testcases if stdnt_stderr == '': - ret = self.compile_command(compile_main) + ret = self._compile_command(compile_main) proc, main_err = ret # if self.language == "java": - main_err = self.remove_null_substitute_char(main_err) + main_err = self._remove_null_substitute_char(main_err) if main_err == '': - ret = self.run_command(run_command_args, stdin=None, + ret = self._run_command(run_command_args, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc, stdout, stderr = ret @@ -161,6 +126,3 @@ class JavaCodeEvaluator(CodeEvaluator): err = err + "\n" + stdnt_stderr return success, err - - -# registry.register('java', EvaluateJavaCode) -- cgit From 5b23647de575fd90552807260a4b8e0a96ab6afe Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Tue, 12 May 2015 17:35:16 +0530 Subject: Seperated tests into seperate folder, formatting changes --- testapp/exam/java_code_evaluator.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'testapp/exam/java_code_evaluator.py') diff --git a/testapp/exam/java_code_evaluator.py b/testapp/exam/java_code_evaluator.py index 709a0a1..08ae208 100644 --- a/testapp/exam/java_code_evaluator.py +++ b/testapp/exam/java_code_evaluator.py @@ -14,7 +14,8 @@ class JavaCodeEvaluator(CodeEvaluator): """Tests the Java code obtained from Code Server""" def __init__(self, test_case_data, test, language, user_answer, ref_code_path=None, in_dir=None): - super(JavaCodeEvaluator, self).__init__(test_case_data, test, language, user_answer, + super(JavaCodeEvaluator, self).__init__(test_case_data, test, + language, user_answer, ref_code_path, in_dir) self.submit_path = self.create_submit_code_file('Test.java') self.test_case_args = self._setup() @@ -23,7 +24,7 @@ class JavaCodeEvaluator(CodeEvaluator): def _setup(self): super(JavaCodeEvaluator, self)._setup() - ref_path, test_case_path = self.set_test_code_file_path(self.ref_code_path) + ref_path, test_case_path = self._set_test_code_file_path(self.ref_code_path) # Set file paths java_student_directory = os.getcwd() + '/' @@ -42,7 +43,8 @@ class JavaCodeEvaluator(CodeEvaluator): remove_ref_output = "{0}{1}.class".format(java_student_directory, java_ref_file_name) - return ref_path, self.submit_path, compile_command, compile_main, run_command_args, remove_user_output, remove_ref_output + return (ref_path, self.submit_path, compile_command, compile_main, + run_command_args, remove_user_output, remove_ref_output) def _teardown(self): # Delete the created file. @@ -77,10 +79,8 @@ class JavaCodeEvaluator(CodeEvaluator): return False, 'No file at %s or Incorrect path' % submit_code_path success = False - # output_path = os.getcwd() + '/output' ret = self._compile_command(compile_command) proc, stdnt_stderr = ret - # if self.language == "java": stdnt_stderr = self._remove_null_substitute_char(stdnt_stderr) # Only if compilation is successful, the program is executed @@ -88,7 +88,6 @@ class JavaCodeEvaluator(CodeEvaluator): if stdnt_stderr == '': ret = self._compile_command(compile_main) proc, main_err = ret - # if self.language == "java": main_err = self._remove_null_substitute_char(main_err) if main_err == '': -- cgit