diff --git a/calculator.py b/calculator.py
new file mode 100644
index 0000000000000000000000000000000000000000..693a2de3e028fdbb164f27f8d0e8f726b93c5f78
--- /dev/null
+++ b/calculator.py
@@ -0,0 +1,24 @@
+import keyboardClass
+import stackClass
+import time
+
+
+keypad = keyboardClass.Keypad()
+stack = stackClass.stack()
+
+lastPressed = []
+
+while 1:
+    pressed = keypad.pressed()
+
+    for key in pressed:
+        if len(lastPressed) == 0:
+            stack.push(key)
+        else:
+            for lastKey in lastPressed:
+                if lastKey != key:
+                    stack.push(key)
+
+    lastPressed = pressed
+    print(stack.stack)
+    time.sleep(.5)
\ No newline at end of file
diff --git a/keyboard.py b/keyboard.py
new file mode 100644
index 0000000000000000000000000000000000000000..3f70d5c9f71453bd5e2e75ccc7c144a41aaff666
--- /dev/null
+++ b/keyboard.py
@@ -0,0 +1,33 @@
+import RPi.GPIO as GPIO
+import time
+
+COL1 = 6
+COL2 = 13
+COL3 = 19
+COL4 = 26
+ROW1 = 16
+ROW2 = 20
+ROW3 = 21
+ROW4 = 5
+
+GPIO.setmode(GPIO.BCM)
+#setup rows
+# set row1 as input and pullup (i.e. set HIGH)
+GPIO.setup(ROW1, GPIO.IN, pull_up_down=GPIO.PUD_UP)
+# other columnds go here
+# setup columns
+GPIO.setup(COL1, GPIO.OUT)
+# other rows go here
+# loop forever
+while True:
+ # output LOW to col1
+ GPIO.output(COL1, GPIO.LOW)
+ # read the state of row1
+ # if [ROW1, COL1] (which is key 1) pressed
+ # then it will be 0 otherwise 1
+ row1_state = GPIO.input(ROW1)
+ print(row1_state)
+ print('#######')
+ time.sleep(1)
+# reset GPIOs before exiting
+GPIO.cleanup()
diff --git a/keyboardClass.py b/keyboardClass.py
new file mode 100644
index 0000000000000000000000000000000000000000..1979b1d27f802d1b1478b1712ef611ebe2a3eb7e
--- /dev/null
+++ b/keyboardClass.py
@@ -0,0 +1,83 @@
+import RPi.GPIO as GPIO
+import time
+
+class Keypad:
+
+    def __init__(self):
+        self.COL1 = 6
+        self.COL2 = 13
+        self.COL3 = 19
+        self.COL4 = 26
+        self.ROW1 = 16
+        self.ROW2 = 20
+        self.ROW3 = 21
+        self.ROW4 = 5
+        self.cols = [self.COL1, self.COL2 , self.COL3, self.COL4]
+        self.rows = [self.ROW1, self.ROW2, self.ROW3, self.ROW4]
+        GPIO.setmode(GPIO.BCM)
+        for row in self.rows:
+            GPIO.setup(row, GPIO.IN, pull_up_down=GPIO.PUD_UP)
+        for col in self.cols:
+            GPIO.setup(col, GPIO.OUT)
+            GPIO.output(col, GPIO.HIGH)
+
+    def isPressed(self, row, col):
+        GPIO.output(col, GPIO.LOW)
+        state = GPIO.input(row)
+        GPIO.output(col, GPIO.HIGH)
+        print("state: " + str(state))
+        if state == 1:
+            return False
+        else:
+            return True
+        
+    def pressed(self):
+        pressed = []
+        for row in range(0,len(self.rows)):
+            for col in range(0,len(self.cols)):
+                if self.isPressed(self.rows[row],self.cols[col]) == True:
+                    pressed.append(self.keyConverter(row,col))
+                    print("pressed detected ########################")
+                    print("appended"+ str(self.keyConverter(row,col)))
+        return pressed
+    
+    def keyConverter(self,row,col):
+        print("row: " + str(row) + " col: " + str(col))
+        if row == 0 and col == 0:
+            return 1
+        elif row == 0 and col == 1:
+            return 2
+        elif row == 0 and col == 2:
+            return 3
+        elif row == 0 and col == 3:
+            return "A"
+        elif row == 1 and col == 0:
+            return 4
+        elif row == 1 and col == 1:
+            return 5
+        elif row == 1 and col == 2:
+            return 6
+        elif row == 1 and col == 3:
+            return "B"
+        elif row == 2 and col == 0:
+            return 7
+        elif row == 2 and col == 1:
+            return 8
+        elif row == 2 and col == 2:
+            return 9
+        elif row == 2 and col == 3:
+            return "C"
+        elif row == 3 and col == 0:
+            return "*"
+        elif row == 3 and col == 1:
+            return 0
+        elif row == 3 and col == 2:
+            return "#"
+        elif row == 3 and col == 3:
+            return "D"
+    
+# input = Keypad()
+
+# while(1):
+#     print(input.isPressed(1,1))
+#     time.sleep(.5)
\ No newline at end of file
diff --git a/stackClass.py b/stackClass.py
new file mode 100644
index 0000000000000000000000000000000000000000..ef1f94e455edc42d6ec194ecd090588e01ec7fd3
--- /dev/null
+++ b/stackClass.py
@@ -0,0 +1,32 @@
+class stack:
+    def __init__ (self,size = 32): 
+        self.stack = []
+        self.maxSize = size
+
+    def push(self,plate):
+        if self.isFull() == False:
+            self.stack.append(plate)
+            return True
+        else:
+            return False
+    
+    def pop(self):
+        if self.isEmpty() == False:
+            return self.stack.pop()
+        else:
+            return False
+    
+    def size(self):
+        return len(self.stack)
+    
+    def isEmpty(self):
+        if len(self.stack) == 0:
+            return True
+        else:
+            return False
+
+    def isFull(self):
+        if len(self.stack) >= self.maxSize:
+            return True
+        else:
+            return False
\ No newline at end of file
diff --git a/sy.py b/sy.py
new file mode 100644
index 0000000000000000000000000000000000000000..adf27af46a80c4865ed188814d77302563f7c655
--- /dev/null
+++ b/sy.py
@@ -0,0 +1,143 @@
+# Shunting-yard Algorithm implemented in Python.
+# Takes a string using infix notation and outputs it in postfix.
+# For example: (5+4)*8 -> 5 4 + 8 *
+# This is reproduced from the Gist: https://gist.github.com/ollybritton/3ecdd2b28344b0b25c547cbfcb807ddc
+# Details of the algorithm can be found here: https://en.wikipedia.org/wiki/Shunting_yard_algorithm
+
+import re
+from collections import namedtuple
+
+opinfo = namedtuple('Operator', 'precedence associativity')
+operator_info = {
+    "+": opinfo(0, "L"),
+    "-": opinfo(0, "L"),
+    "/": opinfo(1, "L"),
+    "*": opinfo(1, "L"),
+    "!": opinfo(2, "L"),
+    "^": opinfo(2, "R"),
+}
+
+
+def tokenize(input_string):
+    cleaned = re.sub(r'\s+', "", input_string)
+    chars = list(cleaned)
+
+    output = []
+    state = ""
+    buf = ""
+
+    while len(chars) != 0:
+        char = chars.pop(0)
+
+        if char.isdigit():
+            if state != "num":
+                output.append(buf) if buf != "" else False
+                buf = ""
+
+            state = "num"
+            buf += char
+
+        elif char in operator_info.keys() or char in ["(", ")"]:
+            output.append(buf) if buf != "" else False
+            buf = ""
+
+            output.append(char)
+
+        else:
+            if state != "func":
+                output.append(buf) if buf != "" else False
+                buf = ""
+
+            state = "func"
+            buf += char
+
+    output.append(buf) if buf != "" else False
+    return output
+
+
+def shunt(tokens, debug=False):
+    tokens += ['end']
+    operators = []
+    output = []
+
+    while len(tokens) != 1:
+        current_token = tokens.pop(0)
+
+        if current_token.isdigit():
+            # Is a number
+            if debug:
+                print("number", current_token)
+            output.append(current_token)
+
+        elif current_token in operator_info.keys():
+            # Is an operator
+            if debug:
+                print("op", current_token)
+
+            while True:
+                if len(operators) == 0:
+                    break
+
+                satisfied = False
+
+                if operators[-1].isalpha():
+                    # is a function
+                    satisfied = True
+
+                if operators[-1] not in ["(", ")"]:
+                    if operator_info[operators[-1]].precedence > operator_info[current_token].precedence:
+                        # operator at top has greater precedence
+                        satisfied = True
+
+                    elif operator_info[operators[-1]].precedence == operator_info[current_token].precedence:
+                        if operator_info[operators[-1]].associativity == "left":
+                            # equal precedence and has left associativity
+                            satisfied = True
+
+                satisfied = satisfied and operators[-1] != "("
+
+                if not satisfied:
+                    break
+
+                output.append(operators.pop())
+
+            operators.append(current_token)
+
+        elif current_token == "(":
+            # Is left bracket
+            if debug:
+                print("left", current_token)
+            operators.append(current_token)
+
+        elif current_token == ")":
+            # Is right bracket
+            if debug:
+                print("right", current_token)
+
+            while True:
+                if len(operators) == 0:
+                    break
+
+                if operators[-1] == "(":
+                    break
+
+                output.append(operators.pop())
+
+            if len(operators) != 0 and operators[-1] == "(":
+                operators.pop()
+
+        else:
+            # Is a function name
+            if debug:
+                print("func", current_token)
+            operators.append(current_token)
+
+    output.extend(operators[::-1])
+
+    return output
+
+
+
+
+tokens = tokenize("3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3")
+print(" ".join(shunt(tokens)))