From cbaf0d84a06a2b3389042c4c4e1c3eb820815bb3 Mon Sep 17 00:00:00 2001 From: Jack Holdsworth <Dooster12@Hotmail.co.uk> Date: Thu, 16 Mar 2023 18:10:19 +0000 Subject: [PATCH] stack keyboard --- calculator.py | 24 ++++++++ keyboard.py | 33 +++++++++++ keyboardClass.py | 83 +++++++++++++++++++++++++++ stackClass.py | 32 +++++++++++ sy.py | 143 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 315 insertions(+) create mode 100644 calculator.py create mode 100644 keyboard.py create mode 100644 keyboardClass.py create mode 100644 stackClass.py create mode 100644 sy.py diff --git a/calculator.py b/calculator.py new file mode 100644 index 0000000..693a2de --- /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 0000000..3f70d5c --- /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 0000000..1979b1d --- /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 0000000..ef1f94e --- /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 0000000..adf27af --- /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))) -- GitLab