summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--yaksh/code_evaluator.py11
-rw-r--r--yaksh/cpp_code_evaluator.py57
-rw-r--r--yaksh/java_code_evaluator.py88
-rw-r--r--yaksh/python_assertion_evaluator.py17
-rw-r--r--yaksh/python_stdout_evaluator.py27
-rw-r--r--yaksh/scilab_code_evaluator.py67
6 files changed, 183 insertions, 84 deletions
diff --git a/yaksh/code_evaluator.py b/yaksh/code_evaluator.py
index 39f0d48..180d719 100644
--- a/yaksh/code_evaluator.py
+++ b/yaksh/code_evaluator.py
@@ -127,6 +127,7 @@ class CodeEvaluator(object):
# success, err = self.check_code(*args)
# success, err = self.check_code(**kwargs) #@@@v2
for test_case in test_case_data:
+ self.compile_user_answer(user_answer, **test_case)
success, err = self.check_code(user_answer, **test_case)
if not success:
break
@@ -149,14 +150,8 @@ class CodeEvaluator(object):
def check_code(self):
raise NotImplementedError("check_code method not implemented")
- # def create_submit_code_file(self, file_name):
- # """ Write the code (`answer`) to a file and set the file path"""
- # submit_f = open(file_name, 'w')
- # submit_f.write(self.user_answer.lstrip())
- # submit_f.close()
- # submit_path = abspath(submit_f.name)
-
- # return submit_path
+ def compile_user_answer(self, user_answer, **kwargs):
+ pass
def create_submit_code_file(self, file_name):
""" Set the file path for code (`answer`)"""
diff --git a/yaksh/cpp_code_evaluator.py b/yaksh/cpp_code_evaluator.py
index 8cdc27c..250de8e 100644
--- a/yaksh/cpp_code_evaluator.py
+++ b/yaksh/cpp_code_evaluator.py
@@ -19,7 +19,7 @@ class CppCodeEvaluator(CodeEvaluator):
def teardown(self):
super(CppCodeEvaluator, self).teardown()
# Delete the created file.
- os.remove(self.submit_code_path)
+ os.remove(self.submit_code_path)
def set_file_paths(self):
user_output_path = os.getcwd() + '/output'
@@ -36,6 +36,24 @@ class CppCodeEvaluator(CodeEvaluator):
ref_output_path)
return compile_command, compile_main
+ def compile_code(self, user_answer, test_case):
+ if hasattr(self, 'compiled_output'):
+ return None
+ else:
+ ref_code_path = test_case
+ clean_ref_code_path, clean_test_case_path = self._set_test_code_file_path(ref_code_path)
+
+ if not isfile(clean_ref_code_path):
+ return False, "No file at %s or Incorrect path" % clean_ref_code_path
+ if not isfile(self.submit_code_path):
+ return False, 'No file at %s or Incorrect path' % self.submit_code_path
+
+ self.write_to_submit_code_file(self.submit_code_path, user_answer)
+ self.user_output_path, self.ref_output_path = self.set_file_paths()
+ self.compile_command, self.compile_main = self.get_commands(clean_ref_code_path, self.user_output_path, self.ref_output_path)
+ self.compiled_output = self._compile_command(self.compile_command)
+ return self.compiled_output
+
def check_code(self, user_answer, test_case):
""" Function validates student code using instructor code as
reference.The first argument ref_code_path, is the path to
@@ -56,31 +74,36 @@ class CppCodeEvaluator(CodeEvaluator):
if the required permissions are not given to the file(s).
"""
- ref_code_path = test_case
- clean_ref_code_path, clean_test_case_path = self._set_test_code_file_path(ref_code_path)
-
- if not isfile(clean_ref_code_path):
- return False, "No file at %s or Incorrect path" % clean_ref_code_path
- if not isfile(self.submit_code_path):
- return False, 'No file at %s or Incorrect path' % self.submit_code_path
+ # ref_code_path = test_case
+ # clean_ref_code_path, clean_test_case_path = self._set_test_code_file_path(ref_code_path)
+
+ # if not isfile(clean_ref_code_path):
+ # return False, "No file at %s or Incorrect path" % clean_ref_code_path
+ # if not isfile(self.submit_code_path):
+ # return False, 'No file at %s or Incorrect path' % self.submit_code_path
+
+ # success = False
+ # self.write_to_submit_code_file(self.submit_code_path, user_answer)
+ # user_output_path, ref_output_path = self.set_file_paths()
+ # compile_command, compile_main = self.get_commands(clean_ref_code_path, user_output_path, ref_output_path)
+ # ret = self._compile_command(compile_command)
+ # proc, stdnt_stderr = ret
+ # stdnt_stderr = self._remove_null_substitute_char(stdnt_stderr)
success = False
- self.write_to_submit_code_file(self.submit_code_path, user_answer)
- user_output_path, ref_output_path = self.set_file_paths()
- compile_command, compile_main = self.get_commands(clean_ref_code_path, user_output_path, ref_output_path)
- ret = self._compile_command(compile_command)
- proc, stdnt_stderr = ret
+ proc, stdnt_stderr = self.compiled_output
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(self.compile_main)
proc, main_err = ret
main_err = self._remove_null_substitute_char(main_err)
if main_err == '':
- ret = self._run_command([ref_output_path], stdin=None,
+ ret = self._run_command([self.ref_output_path], stdin=None,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
proc, stdout, stderr = ret
@@ -88,7 +111,7 @@ class CppCodeEvaluator(CodeEvaluator):
success, err = True, "Correct answer"
else:
err = stdout + "\n" + stderr
- os.remove(ref_output_path)
+ os.remove(self.ref_output_path)
else:
err = "Error:"
try:
@@ -100,7 +123,7 @@ class CppCodeEvaluator(CodeEvaluator):
err = err + "\n" + e
except:
err = err + "\n" + main_err
- os.remove(user_output_path)
+ os.remove(self.user_output_path)
else:
err = "Compilation Error:"
try:
diff --git a/yaksh/java_code_evaluator.py b/yaksh/java_code_evaluator.py
index b325208..167981b 100644
--- a/yaksh/java_code_evaluator.py
+++ b/yaksh/java_code_evaluator.py
@@ -29,6 +29,39 @@ class JavaCodeEvaluator(CodeEvaluator):
user_code_directory)
return compile_command, compile_main
+ def set_file_paths(self, directory, file_name):
+ output_path = "{0}{1}.class".format(directory, file_name)
+ return output_path
+
+ def compile_code(self, user_answer, test_case):
+ if hasattr(self, 'compiled_output'):
+ return None
+ else:
+ ref_code_path = test_case
+ clean_ref_code_path, clean_test_case_path = self._set_test_code_file_path(ref_code_path)
+
+ if not isfile(clean_ref_code_path):
+ return False, "No file at %s or Incorrect path" % clean_ref_code_path
+ if not isfile(self.submit_code_path):
+ return False, 'No file at %s or Incorrect path' % self.submit_code_path
+
+ user_code_directory = os.getcwd() + '/'
+ self.write_to_submit_code_file(self.submit_code_path, user_answer)
+ ref_file_name = (clean_ref_code_path.split('/')[-1]).split('.')[0]
+ # user_output_path = "{0}{1}.class".format(user_code_directory,
+ # 'Test')
+ # ref_output_path = "{0}{1}.class".format(user_code_directory,
+ # ref_file_name)
+ # user_output_path, ref_output_path = self.set_file_paths(user_code_directory, clean_ref_code_path)
+ self.user_output_path = self.set_file_paths(user_code_directory, 'Test')
+ self.ref_output_path = self.set_file_paths(user_code_directory, ref_file_name)
+
+ compile_command, self.compile_main = self.get_commands(clean_ref_code_path, user_code_directory)
+ self.run_command_args = "java -cp {0} {1}".format(user_code_directory,
+ ref_file_name)
+ self.compiled_output = self._compile_command(compile_command)
+ return self.compiled_output
+
def check_code(self, user_answer, test_case):
""" Function validates student code using instructor code as
reference.The first argument ref_code_path, is the path to
@@ -49,39 +82,44 @@ class JavaCodeEvaluator(CodeEvaluator):
if the required permissions are not given to the file(s).
"""
- ref_code_path = test_case
- clean_ref_code_path, clean_test_case_path = self._set_test_code_file_path(ref_code_path)
-
- if not isfile(clean_ref_code_path):
- return False, "No file at %s or Incorrect path" % clean_ref_code_path
- if not isfile(self.submit_code_path):
- return False, 'No file at %s or Incorrect path' % self.submit_code_path
-
+ # ref_code_path = test_case
+ # clean_ref_code_path, clean_test_case_path = self._set_test_code_file_path(ref_code_path)
+
+ # if not isfile(clean_ref_code_path):
+ # return False, "No file at %s or Incorrect path" % clean_ref_code_path
+ # if not isfile(self.submit_code_path):
+ # return False, 'No file at %s or Incorrect path' % self.submit_code_path
+
+ # success = False
+ # user_code_directory = os.getcwd() + '/'
+ # self.write_to_submit_code_file(self.submit_code_path, user_answer)
+ # ref_file_name = (clean_ref_code_path.split('/')[-1]).split('.')[0]
+ # # user_output_path = "{0}{1}.class".format(user_code_directory,
+ # # 'Test')
+ # # ref_output_path = "{0}{1}.class".format(user_code_directory,
+ # # ref_file_name)
+ # # user_output_path, ref_output_path = self.set_file_paths(user_code_directory, clean_ref_code_path)
+ # user_output_path = self.set_file_paths(user_code_directory, 'Test')
+ # ref_output_path = self.set_file_paths(user_code_directory, ref_file_name)
+
+ # compile_command, compile_main = self.get_commands(clean_ref_code_path, user_code_directory)
+ # run_command_args = "java -cp {0} {1}".format(user_code_directory,
+ # ref_file_name)
+ # ret = self._compile_command(compile_command)
+ # proc, stdnt_stderr = ret
success = False
- user_code_directory = os.getcwd() + '/'
- self.write_to_submit_code_file(self.submit_code_path, user_answer)
- ref_file_name = (clean_ref_code_path.split('/')[-1]).split('.')[0]
- user_output_path = "{0}{1}.class".format(user_code_directory,
- 'Test')
- ref_output_path = "{0}{1}.class".format(user_code_directory,
- ref_file_name)
- # user_output_path, ref_output_path = self.set_file_paths(user_code_directory, clean_ref_code_path)
- compile_command, compile_main = self.get_commands(clean_ref_code_path, user_code_directory)
- run_command_args = "java -cp {0} {1}".format(user_code_directory,
- ref_file_name)
- ret = self._compile_command(compile_command)
- proc, stdnt_stderr = ret
+ proc, stdnt_stderr = self.compiled_output
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(self.compile_main)
proc, main_err = ret
main_err = self._remove_null_substitute_char(main_err)
if main_err == '':
- ret = self._run_command(run_command_args, shell=True,
+ ret = self._run_command(self.run_command_args, shell=True,
stdin=None,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
@@ -90,7 +128,7 @@ class JavaCodeEvaluator(CodeEvaluator):
success, err = True, "Correct answer"
else:
err = stdout + "\n" + stderr
- os.remove(ref_output_path)
+ os.remove(self.ref_output_path)
else:
err = "Error:"
try:
@@ -102,7 +140,7 @@ class JavaCodeEvaluator(CodeEvaluator):
err = err + "\n" + e
except:
err = err + "\n" + main_err
- os.remove(user_output_path)
+ os.remove(self.user_output_path)
else:
err = "Compilation Error:"
try:
diff --git a/yaksh/python_assertion_evaluator.py b/yaksh/python_assertion_evaluator.py
index 15ff8fd..c6661d1 100644
--- a/yaksh/python_assertion_evaluator.py
+++ b/yaksh/python_assertion_evaluator.py
@@ -12,17 +12,26 @@ from code_evaluator import CodeEvaluator, TimeoutException
class PythonAssertionEvaluator(CodeEvaluator):
"""Tests the Python code obtained from Code Server"""
+ def compile_code(self, user_answer, test_case):
+ if hasattr(self, 'g'):
+ return None
+ else:
+ submitted = compile(user_answer, '<string>', mode='exec')
+ self.g = {}
+ exec submitted in self.g
+ return self.g
+
# def check_code(self, test, user_answer, ref_code_path):
# def check_code(self, user_answer, test_case_data): #@@@v2
def check_code(self, user_answer, test_case):
success = False
try:
tb = None
- submitted = compile(user_answer, '<string>', mode='exec')
- g = {}
- exec submitted in g
+ # submitted = compile(user_answer, '<string>', mode='exec')
+ # g = {}
+ # exec submitted in g
_tests = compile(test_case, '<string>', mode='exec')
- exec _tests in g
+ exec _tests in self.g
except AssertionError:
type, value, tb = sys.exc_info()
info = traceback.extract_tb(tb)
diff --git a/yaksh/python_stdout_evaluator.py b/yaksh/python_stdout_evaluator.py
index 9443e37..85efa51 100644
--- a/yaksh/python_stdout_evaluator.py
+++ b/yaksh/python_stdout_evaluator.py
@@ -25,22 +25,31 @@ def redirect_stdout():
class PythonStdoutEvaluator(CodeEvaluator):
"""Tests the Python code obtained from Code Server"""
+ def compile_code(self, user_answer, expected_output):
+ if hasattr(self, 'output_value'):
+ return None
+ else:
+ submitted = compile(user_answer, '<string>', mode='exec')
+ with redirect_stdout() as output_buffer:
+ g = {}
+ exec submitted in g
+ self.output_value = output_buffer.getvalue()
+ return self.output_value
+
def check_code(self, user_answer, expected_output):
success = False
tb = None
- # expected_output = test_case_data[0]
- submitted = compile(user_answer, '<string>', mode='exec')
- with redirect_stdout() as output_buffer:
- g = {}
- exec submitted in g
- raw_output_value = output_buffer.getvalue()
- # output_value = raw_output_value.encode('string_escape').strip()
- output_value = raw_output_value.strip()
+ # submitted = compile(user_answer, '<string>', mode='exec')
+ # with redirect_stdout() as output_buffer:
+ # g = {}
+ # exec submitted in g
+ # raw_output_value = output_buffer.getvalue()
+ # output_value = raw_output_value.strip()
if expected_output in user_answer:
success = False
err = "Incorrect Answer: Please avoid printing the expected output directly"
- elif output_value == expected_output:
+ elif self.output_value == expected_output:
success = True
err = "Correct answer"
diff --git a/yaksh/scilab_code_evaluator.py b/yaksh/scilab_code_evaluator.py
index 61642fd..87c0e1e 100644
--- a/yaksh/scilab_code_evaluator.py
+++ b/yaksh/scilab_code_evaluator.py
@@ -33,27 +33,52 @@ class ScilabCodeEvaluator(CodeEvaluator):
# Delete the created file.
os.remove(self.submit_code_path)
- def check_code(self, user_answer, test_case):
- ref_code_path = test_case
- clean_ref_path, clean_test_case_path = self._set_test_code_file_path(ref_code_path)
- user_answer, terminate_commands = self._remove_scilab_exit(user_answer.lstrip())
+ def compile_code(self, user_answer, test_case):
+ if hasattr(self, 'compiled_output'):
+ return None
+ else:
+ ref_code_path = test_case
+ clean_ref_path, clean_test_case_path = self._set_test_code_file_path(ref_code_path)
+ user_answer, terminate_commands = self._remove_scilab_exit(user_answer.lstrip())
+
+ self.write_to_submit_code_file(self.submit_code_path, user_answer)
+ # Throw message if there are commmands that terminates scilab
+ self.add_err = ""
+ if terminate_commands:
+ self.add_err = "Please do not use exit, quit and abort commands in your\
+ code.\n Otherwise your code will not be evaluated\
+ correctly.\n"
+
+ cmd = 'printf "lines(0)\nexec(\'{0}\',2);\nquit();"'.format(clean_ref_path)
+ cmd += ' | timeout 8 scilab-cli -nb'
+ self.compiled_output = self._run_command(cmd,
+ shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ return self.compiled_output
+ def check_code(self, user_answer, test_case):
+ # ref_code_path = test_case
+ # clean_ref_path, clean_test_case_path = self._set_test_code_file_path(ref_code_path)
+ # user_answer, terminate_commands = self._remove_scilab_exit(user_answer.lstrip())
+
+ # success = False
+ # self.write_to_submit_code_file(self.submit_code_path, user_answer)
+ # # Throw message if there are commmands that terminates scilab
+ # add_err = ""
+ # if terminate_commands:
+ # add_err = "Please do not use exit, quit and abort commands in your\
+ # code.\n Otherwise your code will not be evaluated\
+ # correctly.\n"
+
+ # cmd = 'printf "lines(0)\nexec(\'{0}\',2);\nquit();"'.format(clean_ref_path)
+ # cmd += ' | timeout 8 scilab-cli -nb'
+ # ret = self._run_command(cmd,
+ # shell=True,
+ # stdout=subprocess.PIPE,
+ # stderr=subprocess.PIPE)
success = False
- self.write_to_submit_code_file(self.submit_code_path, user_answer)
- # Throw message if there are commmands that terminates scilab
- add_err=""
- if terminate_commands:
- add_err = "Please do not use exit, quit and abort commands in your\
- code.\n Otherwise your code will not be evaluated\
- correctly.\n"
-
- cmd = 'printf "lines(0)\nexec(\'{0}\',2);\nquit();"'.format(clean_ref_path)
- cmd += ' | timeout 8 scilab-cli -nb'
- ret = self._run_command(cmd,
- shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- proc, stdout, stderr = ret
+ proc, stdout, stderr = self.compiled_output
# Get only the error.
stderr = self._get_error(stdout)
@@ -63,9 +88,9 @@ class ScilabCodeEvaluator(CodeEvaluator):
if proc.returncode == 5:
success, err = True, "Correct answer"
else:
- err = add_err + stdout
+ err = self.add_err + stdout
else:
- err = add_err + stderr
+ err = self.add_err + stderr
return success, err