1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
#!/usr/bin/env python
from __future__ import unicode_literals
import os
import subprocess
import re
# Local imports
from .base_evaluator import BaseEvaluator
from .file_utils import copy_files, delete_files
from .error_messages import prettify_exceptions
class RCodeEvaluator(BaseEvaluator):
"""Tests the R code obtained from Code Server"""
def __init__(self, metadata, test_case_data):
self.files = []
self.submit_code_path = ""
self.test_code_path = ""
# Set metadata values
self.user_answer = metadata.get('user_answer')
self.file_paths = metadata.get('file_paths')
self.partial_grading = metadata.get('partial_grading')
# Set test case data values
self.test_case = test_case_data.get('test_case')
self.weight = test_case_data.get('weight')
self.hidden = test_case_data.get('hidden')
def teardown(self):
# Delete the created file.
if os.path.exists(self.submit_code_path):
os.remove(self.submit_code_path)
if os.path.exists(self.test_code_path):
os.remove(self.test_code_path)
if self.files:
delete_files(self.files)
def check_code(self):
self.submit_code_path = self.create_submit_code_file('function.r')
self.test_code_path = self.create_submit_code_file('main.r')
if self.file_paths:
self.files = copy_files(self.file_paths)
clean_ref_path = self.test_code_path
self.user_answer, terminate_commands = \
self._remove_r_quit(self.user_answer.lstrip())
success = False
mark_fraction = 0.0
self.write_to_submit_code_file(self.submit_code_path, self.user_answer)
self.write_to_submit_code_file(self.test_code_path, self.test_case)
# Throw message if there are commmands that terminates scilab
add_err = ""
if terminate_commands:
add_err = "Please do not use quit() q() in your code.\
\n Otherwise your code will not be evaluated.\n"
cmd = 'Rscript main.r'
ret = self._run_command(cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
proc, stdout, stderr = ret
if stderr is '':
# Clean output
stdout = self._strip_output(stdout)
if proc.returncode == 31:
success, err = True, None
mark_fraction = 1.0 if self.partial_grading else 0.0
else:
err = stdout + add_err
else:
err = stderr + add_err
if err:
err = re.sub(r'.*?: ', '', err, count=1)
err = prettify_exceptions('Error', err)
return success, err, mark_fraction
def _remove_r_quit(self, string):
"""
Removes quit from the R code
"""
new_string = ""
terminate_commands = False
for line in string.splitlines():
new_line = re.sub(r'quit(.*$)', "", line)
new_line = re.sub(r'q(.*$)', "", new_line)
if line != new_line:
terminate_commands = True
new_string = new_string + '\n' + new_line
return new_string, terminate_commands
def _strip_output(self, out):
"""
Cleans whitespace from the output
"""
strip_out = "Message"
for l in out.split('\n'):
if l.strip():
strip_out = strip_out+"\n"+l.strip()
return strip_out + out
|