dry, black, basic type hints, catch ctrl-d and ctrl-c
This commit is contained in:
parent
26aaabe6a7
commit
f512069fc7
89
fifth.py
89
fifth.py
@ -1,29 +1,27 @@
|
|||||||
import operator
|
import operator
|
||||||
import readline
|
import readline
|
||||||
|
from typing import Callable
|
||||||
|
|
||||||
|
|
||||||
class FifthStack:
|
class FifthStack:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.stack = []
|
self.stack: list[int] = []
|
||||||
self.commands = {
|
self.commands: dict[str, Callable] = {
|
||||||
'push': self.push,
|
"push": self.push,
|
||||||
'pop': self.pop,
|
"pop": self.pop,
|
||||||
'swap': self.swap,
|
"swap": self.swap,
|
||||||
'dup': self.dup,
|
"dup": self.dup,
|
||||||
'+': self.add,
|
|
||||||
'-': self.sub,
|
|
||||||
'*': self.mul,
|
|
||||||
'/': self.div,
|
|
||||||
}
|
}
|
||||||
self.binary_ops = {
|
self.binary_ops: dict[str, Callable[[int, int], int]] = {
|
||||||
'+': operator.add,
|
"+": operator.add,
|
||||||
'-': operator.sub,
|
"-": operator.sub,
|
||||||
'*': operator.mul,
|
"*": operator.mul,
|
||||||
'/': operator.floordiv,
|
"/": operator.floordiv,
|
||||||
}
|
}
|
||||||
|
|
||||||
def _require(self, number, message):
|
def _require(self, number, message):
|
||||||
if len(self.stack) < number:
|
if len(self.stack) < number:
|
||||||
print(message)
|
print(f"ERROR: {message}")
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -33,11 +31,11 @@ class FifthStack:
|
|||||||
def _binary_op(self, operator):
|
def _binary_op(self, operator):
|
||||||
if not self._require(2, "two numbers required"):
|
if not self._require(2, "two numbers required"):
|
||||||
return
|
return
|
||||||
a, b = self.stack.pop(), self.stack.pop()
|
b, a = self.stack.pop(), self.stack.pop()
|
||||||
try:
|
try:
|
||||||
self.stack.append(operator(a, b))
|
self.stack.append(operator(a, b))
|
||||||
except Exception as e:
|
except ZeroDivisionError as e:
|
||||||
print(f"ERROR: {e}")
|
print(f"ERROR: division by zero")
|
||||||
self.stack.extend([a, b])
|
self.stack.extend([a, b])
|
||||||
|
|
||||||
def push(self, value):
|
def push(self, value):
|
||||||
@ -46,34 +44,22 @@ class FifthStack:
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
print("ERROR: integer required")
|
print("ERROR: integer required")
|
||||||
|
|
||||||
def pop(self, _value):
|
def pop(self):
|
||||||
if not self.stack:
|
if not self.stack:
|
||||||
print("ERROR: stack empty")
|
print("ERROR: stack empty")
|
||||||
return
|
return
|
||||||
self.stack.pop()
|
self.stack.pop()
|
||||||
|
|
||||||
def swap(self, _value):
|
def swap(self):
|
||||||
if not self._require(2, 'two numbers required'):
|
if not self._require(2, "two numbers required"):
|
||||||
return
|
return
|
||||||
self.stack[-1], self.stack[-2] = self.stack[-2], self.stack[-1]
|
self.stack[-1], self.stack[-2] = self.stack[-2], self.stack[-1]
|
||||||
|
|
||||||
def dup(self, _value):
|
def dup(self):
|
||||||
if self._require(1, 'stack empty'):
|
if self._require(1, "stack empty"):
|
||||||
self.stack.append(self.stack[-1])
|
self.stack.append(self.stack[-1])
|
||||||
|
|
||||||
def add(self, _value):
|
def execute(self, command: str):
|
||||||
self._binary_op(self._get_binary_op('+'))
|
|
||||||
|
|
||||||
def sub(self, _value):
|
|
||||||
self._binary_op(self._get_binary_op('-'))
|
|
||||||
|
|
||||||
def mul(self, _value):
|
|
||||||
self._binary_op(self._get_binary_op('*'))
|
|
||||||
|
|
||||||
def div(self, _value):
|
|
||||||
self._binary_op(self._get_binary_op('/'))
|
|
||||||
|
|
||||||
def execute(self, command):
|
|
||||||
tokens = command.lower().strip().split()
|
tokens = command.lower().strip().split()
|
||||||
if not tokens:
|
if not tokens:
|
||||||
return
|
return
|
||||||
@ -81,21 +67,30 @@ class FifthStack:
|
|||||||
command, argument = tokens[0], tokens[1] if len(tokens) > 1 else None
|
command, argument = tokens[0], tokens[1] if len(tokens) > 1 else None
|
||||||
function = self.commands.get(command)
|
function = self.commands.get(command)
|
||||||
|
|
||||||
try:
|
if function:
|
||||||
if function: function(argument)
|
if command == "push":
|
||||||
else: print("ERROR: unknown command")
|
function(argument)
|
||||||
except:
|
else:
|
||||||
print("ERROR: invalid command")
|
function()
|
||||||
|
elif command in self.binary_ops:
|
||||||
|
self._binary_op(self._get_binary_op(command))
|
||||||
|
else:
|
||||||
|
print("ERROR: unknown command")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
fifth = FifthStack()
|
fifth = FifthStack()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
print(f'stack is: {fifth.stack}')
|
print(f"stack is: {fifth.stack}")
|
||||||
command = input()
|
try:
|
||||||
if command.lower() == 'exit':
|
if command := input().strip().lower() == "exit":
|
||||||
|
break
|
||||||
|
if command:
|
||||||
|
fifth.execute(command)
|
||||||
|
except (EOFError, KeyboardInterrupt):
|
||||||
break
|
break
|
||||||
fifth.execute(command)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user