summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--yaksh/cpp_stdio_evaluator.py105
-rw-r--r--yaksh/evaluator_tests/test_c_cpp_evaluation.py262
-rw-r--r--yaksh/evaluator_tests/test_java_evaluation.py125
-rw-r--r--yaksh/java_stdio_evaluator.py77
-rw-r--r--yaksh/models.py12
-rw-r--r--yaksh/settings.py11
-rw-r--r--yaksh/stdio_evaluator.py23
7 files changed, 606 insertions, 9 deletions
diff --git a/yaksh/cpp_stdio_evaluator.py b/yaksh/cpp_stdio_evaluator.py
new file mode 100644
index 0000000..28b0a0b
--- /dev/null
+++ b/yaksh/cpp_stdio_evaluator.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+import subprocess
+import os
+from os.path import isfile
+
+#local imports
+from code_evaluator import CodeEvaluator
+from stdio_evaluator import Evaluator
+
+
+class CppStdioEvaluator(CodeEvaluator):
+ """Evaluates C StdIO based code"""
+
+ def setup(self):
+ super(CppStdioEvaluator, self).setup()
+ self.submit_code_path = self.create_submit_code_file('main.c')
+
+ def teardown(self):
+ super(CppStdioEvaluator, self).teardown()
+ os.remove(self.submit_code_path)
+
+ def set_file_paths(self):
+ user_output_path = os.getcwd() + '/output'
+ ref_output_path = os.getcwd() + '/executable'
+
+ return user_output_path, ref_output_path
+
+ def get_commands(self, user_output_path, ref_output_path):
+ compile_command = 'g++ {0} -c -o {1}'.format(self.submit_code_path,
+ user_output_path)
+ compile_main = 'g++ {0} -o {1}'.format(user_output_path,
+ ref_output_path)
+
+ return compile_command, compile_main
+
+ def compile_code(self, user_answer, expected_input, expected_output):
+
+ if not isfile(self.submit_code_path):
+ msg = "No file at %s or Incorrect path" % self.submit_code_path
+ return False, msg
+ 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(
+ self.user_output_path,
+ self.ref_output_path
+ )
+ self.compiled_user_answer = self._run_command(self.compile_command,
+ shell=True,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
+ self.compiled_test_code = self._run_command(self.compile_main,
+ shell=True,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
+ return self.compiled_user_answer, self.compiled_test_code
+
+ def check_code(self, user_answer, expected_input, expected_output):
+ success = False
+ proc, stdnt_out, stdnt_stderr = self.compiled_user_answer
+ stdnt_stderr = self._remove_null_substitute_char(stdnt_stderr)
+ if stdnt_stderr == '':
+ proc, main_out, main_err = self.compiled_test_code
+ main_err = self._remove_null_substitute_char(main_err)
+ if main_err == '':
+ proc = subprocess.Popen("./executable",
+ shell=True,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
+ evaluator = Evaluator()
+ success, err = evaluator.evaluate(user_answer, proc,
+ expected_input,
+ expected_output
+ )
+ os.remove(self.ref_output_path)
+ 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(self.user_output_path)
+ 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
diff --git a/yaksh/evaluator_tests/test_c_cpp_evaluation.py b/yaksh/evaluator_tests/test_c_cpp_evaluation.py
index 71fb843..7a87d87 100644
--- a/yaksh/evaluator_tests/test_c_cpp_evaluation.py
+++ b/yaksh/evaluator_tests/test_c_cpp_evaluation.py
@@ -1,7 +1,10 @@
import unittest
import os
from yaksh.cpp_code_evaluator import CppCodeEvaluator
+from yaksh.cpp_stdio_evaluator import CppStdioEvaluator
from yaksh.settings import SERVER_TIMEOUT
+from textwrap import dedent
+
class CEvaluationTestCases(unittest.TestCase):
def setUp(self):
@@ -52,5 +55,264 @@ class CEvaluationTestCases(unittest.TestCase):
self.assertFalse(result.get("success"))
self.assertEquals(result.get("error"), self.timeout_msg)
+
+class CStdioEvaluationTestCases(unittest.TestCase):
+
+ def setUp(self):
+ self.test_case_data = [{'expected_output': '11', 'expected_input': '5\n6'}]
+ self.timeout_msg = ("Code took more than {0} seconds to run. "
+ "You probably have an infinite loop in"
+ " your code.").format(SERVER_TIMEOUT)
+
+ def test_correct_answer(self):
+ user_answer = dedent("""
+ #include<stdio.h>
+ int main(void){
+ int a,b;
+ scanf("%d%d",&a,&b);
+ printf("%d",a+b);
+ }""")
+ get_class = CppStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertEquals(result.get('error'), "Correct Answer")
+ self.assertTrue(result.get('success'))
+
+ def test_array_input(self):
+ self.test_case_data = [{'expected_output': '561',
+ 'expected_input': '5,6,1'}]
+ user_answer = dedent("""
+ #include<stdio.h>
+ int main(void){
+ int a[3],i;
+ for(i=0;i<3;i++){
+ scanf("%d",&a[i]);}
+ for(i=0;i<3;i++){
+ printf("%d",a[i]);}
+ }""")
+ get_class = CppStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertEquals(result.get('error'), "Correct Answer")
+ self.assertTrue(result.get('success'))
+
+ def test_string_input(self):
+ self.test_case_data = [{'expected_output': 'abc',
+ 'expected_input': 'abc'}]
+ user_answer = dedent("""
+ #include<stdio.h>
+ int main(void){
+ char a[4];
+ scanf("%s",a);
+ printf("%s",a);
+ }""")
+ get_class = CppStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertEquals(result.get('error'), "Correct Answer")
+ self.assertTrue(result.get('success'))
+
+ def test_incorrect_answer(self):
+ user_answer = dedent("""
+ #include<stdio.h>
+ int main(void){
+ int a=10;
+ printf("%d",a);
+ }""")
+ get_class = CppStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertFalse(result.get('success'))
+ self.assertIn("Incorrect", result.get('error'))
+ self.assertTrue(result.get('error').splitlines > 1)
+
+ def test_error(self):
+ user_answer = dedent("""
+ #include<stdio.h>
+ int main(void){
+ int a=10;
+ printf("%d",a)
+ }""")
+ get_class = CppStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertFalse(result.get("success"))
+ self.assertTrue("Compilation Error" in result.get("error"))
+
+ def test_infinite_loop(self):
+ user_answer = dedent("""
+ #include<stdio.h>
+ int main(void){
+ while(0==0){
+ printf("abc");}
+ }""")
+ get_class = CppStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertFalse(result.get("success"))
+ self.assertEquals(result.get("error"), self.timeout_msg)
+
+ def test_only_stdout(self):
+ self.test_case_data = [{'expected_output': '11',
+ 'expected_input': ''}]
+ user_answer = dedent("""
+ #include<stdio.h>
+ int main(void){
+ int a=5,b=6;
+ printf("%d",a+b);
+ }""")
+ get_class = CppStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertEquals(result.get('error'), "Correct Answer")
+ self.assertTrue(result.get('success'))
+
+
+class CppStdioEvaluationTestCases(unittest.TestCase):
+
+ def setUp(self):
+ self.test_case_data = [{'expected_output': '11', 'expected_input': '5\n6'}]
+ self.timeout_msg = ("Code took more than {0} seconds to run. "
+ "You probably have an infinite loop in"
+ " your code.").format(SERVER_TIMEOUT)
+
+ def test_correct_answer(self):
+ user_answer = dedent("""
+ #include<iostream>
+ using namespace std;
+ int main(void){
+ int a,b;
+ cin>>a>>b;
+ cout<<a+b;
+ }""")
+ get_class = CppStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertEquals(result.get('error'), "Correct Answer")
+ self.assertTrue(result.get('success'))
+
+ def test_array_input(self):
+ self.test_case_data = [{'expected_output': '561',
+ 'expected_input': '5,6,1'}]
+ user_answer = dedent("""
+ #include<iostream>
+ using namespace std;
+ int main(void){
+ int a[3],i;
+ for(i=0;i<3;i++){
+ cin>>a[i];}
+ for(i=0;i<3;i++){
+ cout<<a[i];}
+ }""")
+ get_class = CppStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertEquals(result.get('error'), "Correct Answer")
+ self.assertTrue(result.get('success'))
+
+ def test_string_input(self):
+ self.test_case_data = [{'expected_output': 'abc',
+ 'expected_input': 'abc'}]
+ user_answer = dedent("""
+ #include<iostream>
+ using namespace std;
+ int main(void){
+ char a[4];
+ cin>>a;
+ cout<<a;
+ }""")
+ get_class = CppStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertEquals(result.get('error'), "Correct Answer")
+ self.assertTrue(result.get('success'))
+
+ def test_incorrect_answer(self):
+ user_answer = dedent("""
+ #include<iostream>
+ using namespace std;
+ int main(void){
+ int a=10;
+ cout<<a;
+ }""")
+ get_class = CppStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertFalse(result.get('success'))
+ self.assertIn("Incorrect", result.get('error'))
+ self.assertTrue(result.get('error').splitlines > 1)
+
+ def test_error(self):
+ user_answer = dedent("""
+ #include<iostream>
+ using namespace std;
+ int main(void){
+ int a=10;
+ cout<<a
+ }""")
+ get_class = CppStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertFalse(result.get("success"))
+ self.assertTrue("Compilation Error" in result.get("error"))
+
+ def test_infinite_loop(self):
+ user_answer = dedent("""
+ #include<iostream>
+ using namespace std;
+ int main(void){
+ while(0==0){
+ cout<<"abc";}
+ }""")
+ get_class = CppStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertFalse(result.get("success"))
+ self.assertEquals(result.get("error"), self.timeout_msg)
+
+ def test_only_stdout(self):
+ self.test_case_data = [{'expected_output': '11',
+ 'expected_input': ''}]
+ user_answer = dedent("""
+ #include<iostream>
+ using namespace std;
+ int main(void){
+ int a=5,b=6;
+ cout<<a+b;
+ }""")
+ get_class = CppStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertEquals(result.get('error'), "Correct Answer")
+ self.assertTrue(result.get('success'))
+
if __name__ == '__main__':
unittest.main()
diff --git a/yaksh/evaluator_tests/test_java_evaluation.py b/yaksh/evaluator_tests/test_java_evaluation.py
index 801277f..8cfccb9 100644
--- a/yaksh/evaluator_tests/test_java_evaluation.py
+++ b/yaksh/evaluator_tests/test_java_evaluation.py
@@ -2,7 +2,9 @@ import unittest
import os
from yaksh import code_evaluator as evaluator
from yaksh.java_code_evaluator import JavaCodeEvaluator
+from yaksh.java_stdio_evaluator import JavaStdioEvaluator
from yaksh.settings import SERVER_TIMEOUT
+from textwrap import dedent
class JavaEvaluationTestCases(unittest.TestCase):
@@ -61,5 +63,128 @@ class JavaEvaluationTestCases(unittest.TestCase):
self.assertEquals(result.get("error"), self.timeout_msg)
+class JavaStdioEvaluationTestCases(unittest.TestCase):
+
+ def setUp(self):
+ self.test_case_data = [{'expected_output': '11',
+ 'expected_input': '5\n6'}]
+ evaluator.SERVER_TIMEOUT = 9
+ self.timeout_msg = ("Code took more than {0} seconds to run. "
+ "You probably have an infinite loop in"
+ " your code.").format(evaluator.SERVER_TIMEOUT)
+
+ def teardown(self):
+ evaluator.SERVER_TIMEOUT = 2
+
+ def test_correct_answer(self):
+ user_answer = dedent("""
+ import java.util.Scanner;
+ class Test
+ {public static void main(String[] args){
+ Scanner s = new Scanner(System.in);
+ int a = s.nextInt();
+ int b = s.nextInt();
+ System.out.print(a+b);
+ }}""")
+ get_class = JavaStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertEquals(result.get('error'), "Correct Answer")
+ self.assertTrue(result.get('success'))
+
+ def test_array_input(self):
+
+ self.test_case_data = [{'expected_output': '561',
+ 'expected_input': '5,6,1'}]
+ user_answer = dedent("""
+ import java.util.Scanner;
+ class Test
+ {public static void main(String[] args){
+ Scanner s = new Scanner(System.in);
+ int a[] = new int[3];
+ for (int i=0;i<3;i++){
+ a[i] = s.nextInt();
+ System.out.print(a[i]);}
+ }}""")
+ get_class = JavaStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertEquals(result.get('error'), "Correct Answer")
+ self.assertTrue(result.get('success'))
+
+ def test_incorrect_answer(self):
+
+ user_answer = dedent("""
+ import java.util.Scanner;
+ class Test
+ {public static void main(String[] args){
+ Scanner s = new Scanner(System.in);
+ int a = s.nextInt();
+ int b = s.nextInt();
+ System.out.print(a);
+ }}""")
+ get_class = JavaStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertFalse(result.get('success'))
+ self.assertIn("Incorrect", result.get('error'))
+ self.assertTrue(result.get('error').splitlines > 1)
+
+ def test_error(self):
+
+ user_answer = dedent("""
+ class Test
+ {
+ System.out.print("a");
+ }""")
+ get_class = JavaStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertFalse(result.get("success"))
+ self.assertTrue("Compilation Error" in result.get("error"))
+
+ def test_infinite_loop(self):
+
+ user_answer = dedent("""
+ class Test
+ {public static void main(String[] args){
+ while(0==0)
+ {
+ System.out.print("a");}
+ }}""")
+ get_class = JavaStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertFalse(result.get("success"))
+ self.assertEquals(result.get("error"), self.timeout_msg)
+
+ def test_only_stdout(self):
+ self.test_case_data = [{'expected_output': '11',
+ 'expected_input': ''}]
+ user_answer = dedent("""
+ class Test
+ {public static void main(String[] args){
+ int a = 5;
+ int b = 6;
+ System.out.print(a+b);
+ }}""")
+ get_class = JavaStdioEvaluator()
+ kwargs = {'user_answer': user_answer,
+ 'test_case_data': self.test_case_data
+ }
+ result = get_class.evaluate(**kwargs)
+ self.assertEquals(result.get('error'), "Correct Answer")
+ self.assertTrue(result.get('success'))
+
if __name__ == '__main__':
unittest.main()
diff --git a/yaksh/java_stdio_evaluator.py b/yaksh/java_stdio_evaluator.py
new file mode 100644
index 0000000..2f6ef40
--- /dev/null
+++ b/yaksh/java_stdio_evaluator.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+import subprocess
+import os
+from os.path import isfile
+
+#local imports
+from code_evaluator import CodeEvaluator
+from stdio_evaluator import Evaluator
+
+
+class JavaStdioEvaluator(CodeEvaluator):
+ """Evaluates Java StdIO based code"""
+
+ def setup(self):
+ super(JavaStdioEvaluator, self).setup()
+ self.submit_code_path = self.create_submit_code_file('Test.java')
+
+ def teardown(self):
+ super(JavaStdioEvaluator, self).teardown()
+ os.remove(self.submit_code_path)
+
+ def set_file_paths(self, directory, file_name):
+ output_path = "{0}{1}.class".format(directory, file_name)
+ return output_path
+
+ def get_commands(self):
+ compile_command = 'javac {0}'.format(self.submit_code_path)
+
+ return compile_command
+
+ def compile_code(self, user_answer, expected_input, expected_output):
+ if not isfile(self.submit_code_path):
+ msg = "No file at %s or Incorrect path" % self.submit_code_path
+ return False, msg
+ user_code_directory = os.getcwd() + '/'
+ self.write_to_submit_code_file(self.submit_code_path, user_answer)
+ self.user_output_path = self.set_file_paths(user_code_directory,
+ 'Test'
+ )
+ self.compile_command = self.get_commands()
+ self.compiled_user_answer = self._run_command(self.compile_command,
+ shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
+ return self.compiled_user_answer
+
+ def check_code(self, user_answer, expected_input, expected_output):
+ success = False
+ proc, stdnt_out, stdnt_stderr = self.compiled_user_answer
+ stdnt_stderr = self._remove_null_substitute_char(stdnt_stderr)
+ if stdnt_stderr == '' or "error" not in stdnt_stderr:
+ proc = subprocess.Popen("java Test",
+ shell=True,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE
+ )
+ evaluator = Evaluator()
+ success, err = evaluator.evaluate(user_answer, proc,
+ expected_input,
+ expected_output
+ )
+ os.remove(self.user_output_path)
+ 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
diff --git a/yaksh/models.py b/yaksh/models.py
index 4ee6141..e7ae52f 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -36,7 +36,7 @@ enrollment_methods = (
test_case_types = (
("standardtestcase", "Standard Testcase"),
- ("stdoutbasedtestcase", "Stdout Based Testcase"),
+ ("stdiobasedtestcase", "StdIO Based Testcase"),
("mcqtestcase", "MCQ Testcase"),
)
@@ -888,15 +888,17 @@ class StandardTestCase(TestCase):
)
-class StdoutBasedTestCase(TestCase):
+class StdIOBasedTestCase(TestCase):
+ expected_input = models.TextField(blank=True)
expected_output = models.TextField(blank=True)
def get_field_value(self):
- return {"expected_output": self.expected_output}
+ return {"expected_output": self.expected_output,
+ "expected_input": self.expected_input}
def __unicode__(self):
- return u'Question: {0} | Exp. Output: {1}'.format(self.question,
- self.expected_output
+ return u'Question: {0} | Exp. Output: {1} | Exp. Input: {2}'.format(self.question,
+ self.expected_output, self.expected_input
)
diff --git a/yaksh/settings.py b/yaksh/settings.py
index 70e5471..13860b6 100644
--- a/yaksh/settings.py
+++ b/yaksh/settings.py
@@ -11,7 +11,7 @@ SERVER_PORTS = [8001] # range(8001, 8026)
SERVER_POOL_PORT = 53579
# Timeout for the code to run in seconds. This is an integer!
-SERVER_TIMEOUT = 2
+SERVER_TIMEOUT = 4
# The root of the URL, for example you might be in the situation where you
# are not hosted as host.org/exam/ but as host.org/foo/exam/ for whatever
@@ -23,9 +23,12 @@ code_evaluators = {
"python": {"standardtestcase": "python_assertion_evaluator.PythonAssertionEvaluator",
"stdoutbasedtestcase": "python_stdout_evaluator.PythonStdoutEvaluator"
},
- "c": {"standardtestcase": "cpp_code_evaluator.CppCodeEvaluator"},
- "cpp": {"standardtestcase": "cpp_code_evaluator.CppCodeEvaluator"},
- "java": {"standardtestcase": "java_code_evaluator.JavaCodeEvaluator"},
+ "c": {"standardtestcase": "cpp_code_evaluator.CppCodeEvaluator",
+ "stdiobasedtestcase": "cpp_stdio_evaluator.CppStdioEvaluator"},
+ "cpp": {"standardtestcase": "cpp_code_evaluator.CppCodeEvaluator",
+ "stdiobasedtestcase": "cpp_stdio_evaluator.CppStdioEvaluator"},
+ "java": {"standardtestcase": "java_code_evaluator.JavaCodeEvaluator",
+ "stdiobasedtestcase": "java_stdio_evaluator.JavaStdioEvaluator"},
"bash": {"standardtestcase": "bash_code_evaluator.BashCodeEvaluator"},
"scilab": {"standardtestcase": "scilab_code_evaluator.ScilabCodeEvaluator"},
}
diff --git a/yaksh/stdio_evaluator.py b/yaksh/stdio_evaluator.py
new file mode 100644
index 0000000..037ad3d
--- /dev/null
+++ b/yaksh/stdio_evaluator.py
@@ -0,0 +1,23 @@
+class Evaluator(object):
+
+ def evaluate(self, user_answer, proc, expected_input, expected_output):
+ success = False
+ if expected_input:
+ ip = expected_input.replace(",", " ")
+ proc.stdin.write('{0}\n'.format(ip))
+ error_msg = " Given Input is {0} \n Expected Output is {1} ".\
+ format(expected_input, expected_output)
+ else:
+ error_msg = "Expected output is {0}".format(expected_output)
+ output_err = proc.stderr.read()
+ user_output = proc.stdout.read()
+ expected_output = expected_output.replace("\r", "")
+ if output_err == '':
+ if user_output == expected_output:
+ success, err = True, "Correct Answer"
+ else:
+ err = " Incorrect Answer\n" + error_msg +\
+ "\n Your output is {0}".format(user_output)
+ else:
+ err = "Error:"+"\n"+output_err
+ return success, err