Skip to content

Instantly share code, notes, and snippets.

@musabkilic
Last active July 27, 2022 18:11
Show Gist options
  • Save musabkilic/7a3a928e7165f2268dd66f25e7a9a508 to your computer and use it in GitHub Desktop.
Save musabkilic/7a3a928e7165f2268dd66f25e7a9a508 to your computer and use it in GitHub Desktop.
Nand2Tetris Testing Script
# 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