Last active
July 27, 2022 18:11
-
-
Save musabkilic/7a3a928e7165f2268dd66f25e7a9a508 to your computer and use it in GitHub Desktop.
Nand2Tetris Testing Script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Copyright Musab Kilic 2018 | |
# Special thanks to Noam Nisan and Shimon Schocken | |
# Course page: https://www.coursera.org/learn/build-a-computer/ | |
# | |
# Usage: python submit.py [folder(0-6)/full] | |
# Example: python submit.py 0 | |
# python submit.py full | |
from __future__ import division | |
import os | |
import sys | |
import platform | |
from shutil import copyfile, rmtree | |
from subprocess import Popen, PIPE | |
system = platform.system() | |
sl = "\\" if system == "Windows" else "/" | |
ext = ".bat" if system == "Windows" else ".sh" | |
msg_end = b"\r\n" if system == "Windows" else b"\n" | |
success_msg = b"End of script - Comparison ended successfully" + msg_end | |
hs, cpu, asm = ("HardwareSimulator", "CPUEmulator", "Assembler") | |
hs, cpu, asm = map(lambda x: "..{0}tools{0}{1}".format(sl, x), (hs, cpu, asm)) | |
hs, cpu, asm = map(lambda x: x + ext, (hs, cpu, asm)) | |
USAGE = """ | |
Usage: python submit.py [folder(0-6)/full] | |
Example: python submit.py 0 | |
python submit.py full | |
""".strip() | |
def areSame(file1, file2): | |
r1 = open(file1, "r").read().strip().replace("\r", "").replace("\n", "") | |
r2 = open(file2, "r").read().strip().replace("\r", "").replace("\n", "") | |
return r1 == r2 | |
def getFilepaths(directory): | |
file_paths = [] | |
for root, directories, files in os.walk(directory): | |
for file_name in files: | |
file_path = os.path.join(root, file_name) | |
if file_name.endswith(".tst"): | |
if file_name[:-4]+".cmp" in files: | |
file_paths.append(file_path) | |
elif file_name.endswith(".asm"): | |
if file_name[:-4]+".hack" in files: | |
file_paths.append(file_path) | |
return file_paths | |
def testFile(file): | |
file_name = file.split(sl)[-1] | |
file_ext = file.split(".")[-1] | |
if file_name == "Memory.tst": | |
print( | |
"[INFO] Can't test Memory automatically, please test it manually") | |
return True | |
if file_ext == "tst": | |
f = Popen([hs, file], stdout=PIPE, stderr=PIPE).communicate()[0] | |
f1 = Popen([cpu, file], stdout=PIPE, stderr=PIPE).communicate()[0] | |
return success_msg in [f, f1] | |
elif file_ext == "asm": | |
if not "tmp" in os.listdir(os.getcwd()): | |
os.mkdir("tmp") | |
new_file = os.getcwd()+sl+"tmp"+sl+file_name | |
copyfile(file, new_file) | |
f = Popen([asm, new_file], | |
stdout=PIPE, stderr=PIPE).communicate()[0] | |
return areSame(new_file[:-3]+"hack", file[:-3]+"hack") | |
def testFolder(folder): | |
print("[INFO] Testing Folder #0{}".format(folder)) | |
full_file_paths = getFilepaths(os.getcwd()+sl+"0"+folder) | |
successful = 0 | |
for i in full_file_paths: | |
result = testFile(i) | |
successful += int(result) | |
print(("[{}] " + i.split(sl)[-1]).format( | |
"CORRECT" if result else "WRONG")) | |
if folder == "0": | |
grade = 100 | |
else: | |
grade = 100*successful/len(full_file_paths) | |
print("[INFO] #0{} Grade: {}".format(folder, grade)) | |
if "tmp" in os.listdir(os.getcwd()): | |
rmtree(os.getcwd()+sl+"tmp") | |
return grade | |
def calcCourseGrade(grades): | |
course_grade = 0 | |
for folder, grade in enumerate(grades): | |
if folder == 0: | |
pass | |
elif 1 <= folder <= 2: | |
course_grade += grade * (16 / 100) | |
else: | |
course_grade += grade * (17 / 100) | |
return course_grade | |
if __name__ == "__main__": | |
if len(sys.argv) < 2: | |
print(USAGE) | |
else: | |
arg = sys.argv[1].strip() | |
if len(arg) == 1 and "0" <= arg <= "6": | |
testFolder(arg) | |
elif arg.lower() == "full": | |
grades = [] | |
for week in range(7): | |
grades.append(testFolder(str(week))) | |
course_grade = calcCourseGrade(grades) | |
print("[INFO] Course Grade: {}".format(course_grade)) | |
else: | |
print(USAGE) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment