Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ gui/__pycache__/
pyspim/\.DS_Store

\.DS_Store

pyspim/__pycache__/
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,19 @@

We are working to create an educational program that will be used to help students learn how to program in MIPS code. We are using the pyspim code base to run spim through python.

ZenHub: https://app.zenhub.com/workspaces/smip-5c5dd5323547567638dbb48a/boards?repos=169785349
# OS REQUIREMENTS:
-Linux
-MacOS
(Windows unsupported at this time).

# IDE REQUIREMENTS:
Pycharm Community 2018 (Highly Recommended unless serious CLI experience):
https://www.jetbrains.com/pycharm/
Python Interpreter 3.5+

# INSTRUCTIONS:
- Open forked repo in IDE.
- Run Main.py found in /gui/Main.py.

# ASSOCIATED SCRUMBOARD:
ZenHub: https://app.zenhub.com/workspaces/smip-5c5dd5323547567638dbb48a/boards?repos=169785349
560 changes: 520 additions & 40 deletions gui/Drawer.py

Large diffs are not rendered by default.

55 changes: 41 additions & 14 deletions gui/LessonPage.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,62 @@
import tkinter as tk
from lessons.Submission import run_MIPS
from lessons.Lesson_Transition import write_completed
from gui.Utilities import get_path
"""
Draws a lesson to the frame
root: tkinter root to draw to
ttk: tkinter ttk used for styling
lesson: the lesson to be drawn to the screen
"""

practice_filename = get_path('/lesson_files/Submissions/(Practice).s')

def submit_code(user_input, register_labels, lesson):
f = open('input.s', 'w')

def get_submission_file(lesson):
return get_path('/lesson_files/Submissions/'+lesson.lesson_title + '(Submission).s')


def submit_code(user_input, register_labels, lesson=None, is_practice=False):
if is_practice:
filename = practice_filename
else:
filename = get_submission_file(lesson)

f = open(filename, 'w')
f.write(user_input.get("1.0", tk.END))
f.close()

results = run_MIPS('input.s')
results = run_MIPS(filename)
update_registers(results, register_labels)

if lesson.check_solution(results):
print('Passed!!')
else:
print('Failed!!')
if not is_practice:
if lesson.check_solution(results):
lesson.lesson_completed = True
write_completed(lesson.lesson_title, True)
print('Passed!!')
else:
lesson.lesson_completed = False
write_completed(lesson.lesson_title, False)
print('Failed!!')
pass


def get_text():
f = open('Sample1.s', 'r')
output = ""
for x in f.readlines():
output += x
def get_text(lesson=None, is_practice=False):
if is_practice:
try:
f = open(practice_filename)
except FileNotFoundError:
return '# Welcome to Practice! Write some code!!'
else:
try:
filename = get_submission_file(lesson)
f = open(filename, 'r')
except FileNotFoundError:
try:
f = open(get_path(lesson.code_base), 'r')
except FileNotFoundError:
return "# No base code"
output = ''.join(line for line in f.readlines())
f.close()
return output

Expand All @@ -36,5 +65,3 @@ def update_registers(answers, register_labels):
for register, value in answers.items():
register_labels[register].config(text=value)
pass


42 changes: 19 additions & 23 deletions gui/Main.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
import tkinter as tk
from tkinter import ttk
from gui.Drawer import draw_menu
from gui.LessonPage import get_text
from lessons.Lesson import Lesson

root = tk.Tk()
root.title("SMIP: The Student MIPS Instruction Program")
if __name__ == '__main__':
root = tk.Tk()
root.title("SMIP: The Student MIPS Instruction Program")
# Turning off pack propagate to prevent widgets from determining window size.
# Max and Min window sizes may change.
root.pack_propagate(0)
# Max size of window is the dimensions of their screen.
their_width = root.winfo_screenwidth()
their_height = root.winfo_screenheight()
root.maxsize(their_width, their_height)
# Buttons need room, so we need max height.
root.minsize(700, their_height)
# Put app at the center of the screen.
x = (their_width / 2) - (700 / 2)
y = (their_height / 2) - (800 / 2)
root.geometry("%dx%d+%d+%d" % (700, 800, x, y))
root.configure(background='medium blue')
draw_menu(root, ttk)

sample_lesson = Lesson('Lesson 1: Register Addition'," Use the \'add\' instruction to set\n $t0 to 3,$t1 to 5,\n and then their sum in $t2.",
{8: 3, 9: 5, 10: 8}, " The add instruction expects a destination register followed by two source registers,"
" which are comma separated.", get_text())

# Turning off pack propagate to prevent widgets from determining window size.
# Max and Min window sizes may change.
root.pack_propagate(0)
# Max size of window is the dimensions of their screen.
their_width = root.winfo_screenwidth()
their_height = root.winfo_screenheight()
root.maxsize(their_width, their_height)
root.minsize(700, 800)
# Put app at the center of the screen.
x = (their_width / 2) - (700 / 2)
y = (their_height / 2) - (800 / 2)
root.geometry("%dx%d+%d+%d" % (700, 800, x, y))

draw_menu(root, ttk, sample_lesson)
root.mainloop()
root.mainloop()
29 changes: 21 additions & 8 deletions gui/ReferenceWindow.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
import os, sys, subprocess
import os, sys, subprocess, webbrowser, enum
from gui.Utilities import get_path

def draw_reference():

dirname = os.path.dirname(__file__)
class Reference(enum.Enum):
web_link = 'web_link'
local_file = 'local_file'

#Removing gui folder from the absolute path
dirname = dirname[:-3]

filename = os.path.join(dirname,'References','MIPS_Green_Sheet.pdf')

def draw_reference_path(file_path):
filename = get_path(file_path)

if sys.platform == "win32":
os.startfile(filename)
else:
opener = "open" if sys.platform == "darwin" else "xdg-open"
subprocess.call([opener, filename])

pass
pass


def draw_reference_link(file_link):
webbrowser.open(file_link)


def draw_reference(type, path):
if Reference[type].value == Reference.local_file.value:
draw_reference_path(file_path = path)
elif Reference[type].value == Reference.web_link.value:
draw_reference_link(file_link = path)

18 changes: 18 additions & 0 deletions gui/Utilities.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
from os.path import relpath
from tkinter.filedialog import askopenfilename
from pathlib import Path


top_path = str(Path().absolute())[:str(Path().absolute()).rfind('SMIP')+len('SMIP')]


"""
Destroys all content inside of the given frame
frame: frame who's content will be destroyed
Expand All @@ -10,6 +18,16 @@ def destroy_content(frame):
pass


def get_relative_file_path(filetypes):
try:
s = askopenfilename(filetypes=filetypes)
return '/'+relpath(s, top_path)
except ValueError:
return 'None Set'


def get_path(relpath):
return top_path + relpath

"""
Destroys the given frames content and then draws new content to that frame using the given function
Expand Down
Binary file added lesson_files/Another One.xlsx
Binary file not shown.
Binary file added lesson_files/Another Sample.xlsx
Binary file not shown.
File renamed without changes.
Binary file added lesson_files/Sample Lesson.xlsx
Binary file not shown.
58 changes: 58 additions & 0 deletions lesson_files/Submissions/(Practice).s
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Welcome to Practice! Write some code!!
.globl main
.globl init_values
.globl end_program
.globl print_value

# $t0 = $s5
# $s5 += $t0
# $s5 += $t0
# $s5 += $t0
# $s5 += $t0
# $s5 += $t0
#
# $s4 = $s5 + $s3
# $s4 -= $s2

.text
init_values:
addi $s4, $0, 4
addi $s5, $0, 4
addi $s3, $0, 4
addi $s2, $0, 4
jr $ra
add $0, $0, $0

main:
jal init_values
add $0, $0, $0

add $t0, $s5, $0
add $s5, $s5, $t0
add $s5, $s5, $t0
add $s5, $s5, $t0
add $s5, $s5, $t0
add $s5, $s5, $t0

add $s4, $s5, $s3

sub $s4, $s4, $s2

jal print_value
add $0, $0, $0
j end_program
add $0, $0, $0

print_value:
addi $v0, $0, 1
add $a0, $s4, $0
syscall
jr $ra
add $0, $0, $0

end_program:
addi $v0, $0, 10
syscall



9 changes: 5 additions & 4 deletions gui/input.s → .../Submissions/Another Sample(Submission).s
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
main:

# your code here
addi $t0, $0, 3
addi $t1, $0, 5
add $t4, $t0, $t1

addi $s0, $0, 0

# All memory structures are placed after the
# .data assembler directive
.data




23 changes: 23 additions & 0 deletions lesson_files/Submissions/Sample Lesson(Submission).s
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# "Hello World" in MIPS assembly
# From: http://labs.cs.upt.ro/labs/so2/html/resources/nachos-doc/mipsf.html

# All program code is placed after the
# .text assembler directive
.text

# Declare main as a global function
.globl main

# The label 'main' represents the starting point
main:

# your code here
addi $a3, $0, 5

# All memory structures are placed after the
# .data assembler directive
.data




Binary file added lesson_files/Submissions/profile.pickle
Binary file not shown.
4 changes: 3 additions & 1 deletion lessons/Lesson.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ class Lesson:
answer: Dict that stores the necessary registers as keys
and the correct final values as their value mapping
"""
def __init__(self, title, prompt, answer, hint, base_code):
def __init__(self, title, prompt, answer, hint, reference, base_code, completed):
self.lesson_prompt = prompt
self.lesson_hint = hint
self.lesson_reference = reference
self.lesson_title = title
self.lesson_answer = answer
self.code_base = base_code
self.lesson_completed = completed
pass

"""
Expand Down
Loading