First commit
This commit is contained in:
		
							
								
								
									
										91
									
								
								calculator.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								calculator.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					import re
 | 
				
			||||||
 | 
					from parse import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Regular expression that checks for valid characters in an expression
 | 
				
			||||||
 | 
					valid_chars = '[0-9.\(\)+-\/*]'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def raise_error(error_code):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# List of error codes:
 | 
				
			||||||
 | 
						# 0 - Invalid characters found in expression
 | 
				
			||||||
 | 
						# 1 - Unclosed parantheses
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						match error_code:
 | 
				
			||||||
 | 
							case 0:
 | 
				
			||||||
 | 
								print("You have invalid characters in your expression.")
 | 
				
			||||||
 | 
							case 1:
 | 
				
			||||||
 | 
								print("You have an unclosed parantheses in your expression.")
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						main() # Re-enter main loop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def check_errors(expr):
 | 
				
			||||||
 | 
						# Check if number of opening parantheses is equal to number of closing parantheses
 | 
				
			||||||
 | 
						num_open_pars = 0
 | 
				
			||||||
 | 
						num_close_pars = 0
 | 
				
			||||||
 | 
						for val in expr:
 | 
				
			||||||
 | 
							num_open_pars += 1 if val == '('
 | 
				
			||||||
 | 
							num_close_pars += 1 if val == ')'
 | 
				
			||||||
 | 
							if num_open_pars != num_close_pars:
 | 
				
			||||||
 | 
								raise_error(2) 
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def evaluate(subexpr): # Evaluate a tokenized expression, that contains no parantheses
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						subexpr = [element for element in subexpr if element != ''] # Remove empty characters in the expression
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						print(subexpr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (len(subexpr) == 1):
 | 
				
			||||||
 | 
							return float(subexpr[0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if '/' in subexpr:
 | 
				
			||||||
 | 
							index = subexpr.index('/')
 | 
				
			||||||
 | 
							subexpr[index] = float(subexpr[index-1]) / float(subexpr[index+1])
 | 
				
			||||||
 | 
							subexpr[index-1] = ''
 | 
				
			||||||
 | 
							subexpr[index+1] = ''
 | 
				
			||||||
 | 
						elif '*' in subexpr:
 | 
				
			||||||
 | 
							index = subexpr.index('*')
 | 
				
			||||||
 | 
							subexpr[index] = float(subexpr[index-1]) * float(subexpr[index+1])
 | 
				
			||||||
 | 
							subexpr[index-1] = ''
 | 
				
			||||||
 | 
							subexpr[index+1] = ''
 | 
				
			||||||
 | 
						elif '+' in subexpr:
 | 
				
			||||||
 | 
							index = subexpr.index('+')
 | 
				
			||||||
 | 
							subexpr[index] = float(subexpr[index-1]) + float(subexpr[index+1])
 | 
				
			||||||
 | 
							subexpr[index-1] = ''
 | 
				
			||||||
 | 
							subexpr[index+1] = ''
 | 
				
			||||||
 | 
						elif '-' in subexpr:
 | 
				
			||||||
 | 
							index = subexpr.index('-')
 | 
				
			||||||
 | 
							subexpr[index] = float(subexpr[index-1]) - float(subexpr[index+1])
 | 
				
			||||||
 | 
							subexpr[index-1] = ''
 | 
				
			||||||
 | 
							subexpr[index+1] = ''
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
						print(subexpr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return evaluate(subexpr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def find_inner(subexpr):
 | 
				
			||||||
 | 
						print("expr: "  + subexpr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						subexpr = parse(subexpr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for index,val in enumerate(subexpr):
 | 
				
			||||||
 | 
							if '(' in val or ')' in val:
 | 
				
			||||||
 | 
								subexpr[index] = find_inner(val[1:len(val)-1])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						subexpr_string = ''.join(subexpr)
 | 
				
			||||||
 | 
						print("New expr: " + subexpr_string)
 | 
				
			||||||
 | 
						if not '(' in subexpr_string and not ')' in subexpr_string:
 | 
				
			||||||
 | 
							return str(evaluate(subexpr))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def main():
 | 
				
			||||||
 | 
						while True:
 | 
				
			||||||
 | 
							expr = input()
 | 
				
			||||||
 | 
							check_for_errors(expr)
 | 
				
			||||||
 | 
							expr = find_inner(expr)
 | 
				
			||||||
 | 
							print(expr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					main()
 | 
				
			||||||
							
								
								
									
										38
									
								
								parse.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								parse.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					def parse(expr):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						opers = ['+', '-', '*', '/']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						num_par = 0
 | 
				
			||||||
 | 
						tokenized = []
 | 
				
			||||||
 | 
						temp_string = ""
 | 
				
			||||||
 | 
						index = 0
 | 
				
			||||||
 | 
						while index < len(expr):
 | 
				
			||||||
 | 
							if expr[index] in opers:
 | 
				
			||||||
 | 
								tokenized.append(expr[index])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							elif expr[index].isdigit() or expr[index] == '.':
 | 
				
			||||||
 | 
								while (index < len(expr)) and (expr[index].isdigit() or expr[index] == '.'):
 | 
				
			||||||
 | 
									temp_string += expr[index]
 | 
				
			||||||
 | 
									index += 1
 | 
				
			||||||
 | 
								tokenized.append(temp_string)
 | 
				
			||||||
 | 
								temp_string = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							elif expr[index] == '(':
 | 
				
			||||||
 | 
								num_par = 1
 | 
				
			||||||
 | 
								temp_string += expr[index]
 | 
				
			||||||
 | 
								index += 1
 | 
				
			||||||
 | 
								while num_par != 0 and index < len(expr):
 | 
				
			||||||
 | 
									temp_string += expr[index]
 | 
				
			||||||
 | 
									if expr[index] == '(':
 | 
				
			||||||
 | 
										num_par += 1
 | 
				
			||||||
 | 
									if expr[index] == ')':
 | 
				
			||||||
 | 
										num_par -= 1
 | 
				
			||||||
 | 
									index += 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								tokenized.append(temp_string)
 | 
				
			||||||
 | 
								temp_string = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							index += 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return tokenized
 | 
				
			||||||
		Reference in New Issue
	
	Block a user