]> Skullheadx's Git Forge - ccc-grader.git/commitdiff
everything
authorSkullheadx <704277@pdsb.net>
Wed, 4 Jan 2023 23:18:42 +0000 (18:18 -0500)
committerSkullheadx <704277@pdsb.net>
Wed, 4 Jan 2023 23:18:42 +0000 (18:18 -0500)
.gitignore
capture.py [new file with mode: 0644]
grader.py [new file with mode: 0644]
input/.gitignore [new file with mode: 0644]
runner.py [new file with mode: 0644]

index d9005f2cc7fc4e65f14ed5518276007c08cf2fd0..224e9fb8be716ea7e71cb990232fea3baa028253 100644 (file)
@@ -1,3 +1,6 @@
+.idea/
+
+
 # Byte-compiled / optimized / DLL files
 __pycache__/
 *.py[cod]
diff --git a/capture.py b/capture.py
new file mode 100644 (file)
index 0000000..8c82fef
--- /dev/null
@@ -0,0 +1,14 @@
+import sys
+from io import StringIO
+
+
+class Capturing(list):  # To capture output written to the console using print()
+    def __enter__(self):
+        self._stdout = sys.stdout
+        sys.stdout = self._stringio = StringIO()
+        return self
+
+    def __exit__(self, *args):
+        self.extend(self._stringio.getvalue().splitlines())
+        del self._stringio  # free up some memory
+        sys.stdout = self._stdout
diff --git a/grader.py b/grader.py
new file mode 100644 (file)
index 0000000..c2b5415
--- /dev/null
+++ b/grader.py
@@ -0,0 +1,60 @@
+import os
+import time
+from runner import run
+from capture import Capturing
+
+PATH = "input/"
+PROBLEM = input("Enter the name of the problem: ")  # i.e. S1
+FILENAME = None
+extension = ".py"
+
+for root, dirs, files in os.walk(PATH):
+    for file in files:
+        if file[-file[::-1].index(".") - 1:] == extension:
+            FILENAME = file
+
+if FILENAME is None:
+    raise FileNotFoundError
+
+test_input_path = os.path.join(PATH, f"windows_data/senior/{PROBLEM}/")
+
+test_inputs = []
+test_outputs = []
+for root, dirs, files in os.walk(test_input_path):
+    for i, file in enumerate(files):
+        with open(os.path.join(root, file), "r") as f:
+            if i % 2 == 0:  # CCC test cases alternate between IN and OUT files.
+                test_inputs.append(f.read())
+            else:
+                test_outputs.append(f.read())
+
+total = min(len(test_inputs), len(test_outputs))  # Total number of questions
+correct = 0  # how many are correct answered
+
+print("-" * 30)
+print(f"Evaluating {FILENAME}")
+
+for test_input, test_output in zip(test_inputs, test_outputs):  # loop through each input and output
+    with Capturing() as program_output:  # Capture output from print()
+        start = time.perf_counter()  # getting start time
+        run(os.path.join(PATH, FILENAME), test_input)  # running the program + input
+        end = time.perf_counter()  # getting end time
+
+    program_time = max(round(end - start, 3), 1 * 10 ** -3)  # So the output doesn't say 0.0s
+
+    program_output = "\n".join(program_output)
+    if test_output[-1] == "\n":
+        test_output = test_output[:-1]
+    # Check if the program output is correct.
+    if program_output == test_output:
+        print(f"Test Passed. {program_time}s")
+        correct += 1
+    else:
+        print(f"Test Failed. {program_time}s")
+        print(f"{test_input = }")
+        print(f"{test_output = }")
+        print(f"{program_output = }")
+        print()
+
+print("-" * 30)
+print(f"Tests passed: {correct}/{total}")
diff --git a/input/.gitignore b/input/.gitignore
new file mode 100644 (file)
index 0000000..d6b7ef3
--- /dev/null
@@ -0,0 +1,2 @@
+*
+!.gitignore
diff --git a/runner.py b/runner.py
new file mode 100644 (file)
index 0000000..70e9020
--- /dev/null
+++ b/runner.py
@@ -0,0 +1,7 @@
+from io import StringIO
+import sys
+
+# Running the code in a separate file because there can be variable conflicts in the grader.py file (i.e. output)
+def run(file_path, test_input):
+    sys.stdin = StringIO(test_input)  # Enter the test input
+    exec(open(file_path).read())  # Run the code