summaryrefslogtreecommitdiff
path: root/testapp/exam/scilab_code_evaluator.py
blob: 073fbcb512dae9d0b38d2850ecd7a90f7dfbd7b0 (plain)
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env python
import traceback
import os
from os.path import join, isfile
import subprocess
import re
import importlib

# local imports
from code_evaluator import CodeEvaluator
# from language_registry import registry


class ScilabCodeEvaluator(CodeEvaluator):
    """Tests the Scilab code obtained from Code Server"""
    def __init__(self, test_case_data, language, user_answer,
                     ref_code_path=None, in_dir=None):
        super(ScilabCodeEvaluator, self).__init__(test_case_data, language, user_answer, 
                                                 ref_code_path, in_dir)
        self.submit_path = self.create_submit_code_file('function.sci')
        self.test_case_args = self.setup_code_evaluator()

    # Private Protocol ##########
    def setup_code_evaluator(self):
        super(ScilabCodeEvaluator, self).setup_code_evaluator()

        ref_path, test_case_path = self.set_test_code_file_path(self.ref_code_path)

        return ref_path, # Return as a tuple

    def teardown_code_evaluator(self):
        # Delete the created file.
        super(ScilabCodeEvaluator, self).teardown_code_evaluator()
        os.remove(self.submit_path)

    def check_code(self, ref_path):
        success = False

        cmd = 'printf "lines(0)\nexec(\'{0}\',2);\nquit();"'.format(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

        # Get only the error.
        stderr = self._get_error(stdout)
        if stderr is None:
            # Clean output
            stdout = self._strip_output(stdout)
            if proc.returncode == 5:
                success, err = True, "Correct answer"
            else:
                err = add_err + stdout
        else:
            err = add_err + stderr

        return success, err

    # # Public Protocol ##########
    # def evaluate_code(self):
    #     submit_path = self.create_submit_code_file('function.sci')
    #     ref_path, test_case_path = self.set_test_code_file_path()
    #     success = False

    #     cmd = 'printf "lines(0)\nexec(\'{0}\',2);\nquit();"'.format(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

    #     # Get only the error.
    #     stderr = self._get_error(stdout)
    #     if stderr is None:
    #         # Clean output
    #         stdout = self._strip_output(stdout)
    #         if proc.returncode == 5:
    #             success, err = True, "Correct answer"
    #         else:
    #             err = add_err + stdout
    #     else:
    #         err = add_err + stderr

    #     # Delete the created file.
    #     os.remove(submit_path)

    #     return success, err

    # Private Protocol ##########
    def _remove_scilab_exit(self, string):
        """
            Removes exit, quit and abort from the scilab code
        """
        new_string = ""
        i = 0
        for line in string.splitlines():
            new_line = re.sub(r"exit.*$", "", line)
            new_line = re.sub(r"quit.*$", "", new_line)
            new_line = re.sub(r"abort.*$", "", new_line)
            if line != new_line:
                i = i + 1
            new_string = new_string + '\n' + new_line
        return new_string, i

    # Private Protocol ##########
    def _get_error(self, string):
        """
            Fetches only the error from the string.
            Returns None if no error.
        """
        obj = re.search("!.+\n.+", string)
        if obj:
            return obj.group()
        return None

    # Private Protocol ##########
    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


# registry.register('scilab', EvaluateScilabCode)