Smart Calculator

Ce script fait partie des projets Python de HyperSkill.

j'ai fait toute la formation python de Hyperskill pendant le Confinement 2020.

# write your code here
from string import ascii_letters, digits
class Calculator:
def __init__(self):
self.variables = {}
while True:
self.user_input = input()
if self.user_input.startswith("/"):
msg = self.command()
elif self.user_input == "":
continue
elif self.user_input[0] in ascii_letters:
msg = self.process()
elif self.user_input[0] not in ascii_letters + digits:
msg = "Invalid expression"
else:
msg = self.calculate
if msg or msg == 0:
print(msg)
def command(self):
if self.user_input == "/exit":
print("Bye!")
exit(0)
elif self.user_input == "/help":
return "This program adds or subtracts numbers."
else:
return f"Unknown command"
@staticmethod
def add(a, b):
return int(a) + int(b)
@staticmethod
def sub(a, b):
return int(a) - int(b)
def split(self):
raw_splitted = list(self.user_input)
operators = ("+", "-")
buffer = []
splitted = []
for i in raw_splitted:
if i in operators and len(splitted) == 0:
buffer.append(i)
if i not in operators and len(splitted) == 0:
splitted.append(i)
elif i not in operators and len(buffer) == 1:
pos = buffer.pop()
splitted.append(f"{pos}{i}")
elif not i.isdigit() and not splitted[-1][-1].isdigit():
splitted[-1] += i
elif i.isdigit() and splitted[-1][-1].isdigit():
splitted[-1] += i
else:
splitted.append(i)
if len(splitted) == 1:
if splitted[0] == "-" and splitted[1].isdigit():
return "".join(splitted), False
elif splitted[0] == "+" and splitted[1].isdigit():
return splitted[1], True
elif len(splitted) == 1 and splitted[0][1:].isdigit():
return splitted[0], True
elif len(splitted) == 1 and splitted[0].isdigit():
return splitted[0], True
return "Invalid expression", True
return splitted, False
@property
def calculate(self):
calc_list, status = self.split()
if status:
return calc_list
if status:
return calc_list[0]
if len(calc_list) < 2:
return "Invalid expression"
calc_list.reverse()
result_list = []
try:
a, method, b = (calc_list.pop() for _ in range(3))
except IndexError:
return "Invalid expression"
if "+" in set(method):
result_list.append(self.add(a, b))
elif "-" in set(method):
if len(method) % 2 == 0:
result_list.append(self.add(a, b))
else:
result_list.append(self.sub(a, b))
while len(calc_list) > 0:
a = result_list.pop()
method, b = (calc_list.pop() for _ in range(2))
if "+" in set(method):
result_list.append(self.add(a, b))
elif "-" in set(method):
if len(method) % 2 == 0:
result_list.append(self.add(a, b))
else:
result_list.append(self.sub(a, b))
return result_list[0]
def process(self):
self.user_input = self.user_input.replace(" ", "")
if "=" in self.user_input:
return self.process_variable()
else:
if len(self.user_input.split()) == 1 and not any(elem in list(self.user_input) for elem in ["+", "-"]):
if self.user_input in self.variables.keys():
return self.print_variable()
else:
return "Unknown variable"
else:
return self.calculate_var()
def process_variable(self):
try:
var, value = self.user_input.split("=")
except ValueError:
return "Invalid assignment"
if not all(elem in list(ascii_letters) for elem in list(var)):
return "Invalid identifier"
else:
if self.is_digit(value):
self.variables[var] = value
elif not all(elem in list(ascii_letters) for elem in list(value)):
return "Invalid assignment"
else:
if value not in self.variables.keys():
return "Unknown variable"
else:
self.variables[var] = self.variables[value]
return
def print_variable(self):
return self.variables[self.user_input]
def calculate_var(self):
calc_list = self.split_var()
variables = [elem for elem in set(calc_list) if elem in ascii_letters]
if not all(elem in self.variables.keys() for elem in variables):
return "Unknown variable"
for elem in range(len(calc_list)):
if calc_list[elem] in self.variables:
calc_list[elem] = self.variables[calc_list[elem]]
self.user_input = "".join(calc_list)
return self.calculate
def split_var(self):
raw_splitted = list(self.user_input)
operators = ("+", "-")
buffer = []
splitted = []
for i in raw_splitted:
if i in operators and len(splitted) == 0:
buffer.append(i)
elif i in operators and all(elem not in list(ascii_letters+digits) for elem in list(splitted[-1][-1])):
splitted[-1] += i
elif i not in operators and len(buffer) == 1:
pos = buffer.pop()
splitted.append(f"{pos}{i}")
else:
splitted.append(i)
return splitted
@staticmethod
def is_digit(value):
try:
int(value)
return True
except ValueError:
return False
Calculator()
view raw calculator.py hosted with ❤ by GitHub

cyvax - 2024