Python creando una calculadora

Soy bastante nuevo en Python.

Se me ha pedido que cree una calculadora utilizando solo comandos de cadena, conversiones entre int / string / float etc. (si es necesario), y el uso de funciones es un requisito. mientras que y para bucles también se pueden utilizar.

El progtwig necesita tomar una entrada de la forma x / y o x / y / z, donde xyz es cualquier número positivo o negativo. Donde “/” puede ser reemplazado por la sum de la multiplicación y la resta también. Y donde cualquier número de espacios en blanco puede existir entre operandos y operadores. Esta es una idea de lo que tengo hasta ahora.

Tendría una definición única para +, -, /, y *. Me gustaría crear una función para lo que el usuario ingresa. Usaría “.lstrip” y “.rstrip” para deshacerme de los espacios en blanco.

Ahora, con lo que estoy teniendo problemas es creando la función de entrada. Soy muy nuevo en funciones y esto es básicamente lo que tengo. Sé que no hay mucho con lo que trabajar, pero estoy realmente atascado en cómo ingresar correctamente a la función.

def multiplication(x,a,y,b,z): if (a== "*"): return x*y if (b== "*"): return y*z def division(x,a,y,b,z): if (a== "/"): return x/y if (b== "/"): return y/z def addition(x,a,y,b,z): if (a== "+"): return x+y if (b== "+"): return y+z def subtraction(x,a,y,b,z): if (a== "-"): return xy if (b== "-"): return yz def (x,y,z): x=0 y=0 z=0 zxc=int(input()):# this is where I get stuck and I don't know how to implement x,y,z into the input. 

Toda la ayuda es apreciada. Si no está seguro de si el código que proporciona es demasiado intenso para mis necesidades, pregunte antes de perder su tiempo para mí, haciendo un código que posiblemente no pueda usar. Prometo responder lo antes posible.

Básicamente, estoy tratando de encontrar una manera de dividir la cadena ingresada Y ENTONCES comenzar los cálculos con ella.

Aquí es un posible esquema de solución utilizando expresiones regulares. Error al comprobar a la izquierda como ejercicio. Si esto no es tarea y le gustaría ver la solución completa, véala aquí

 import re # input is a list of tokens (token is a number or operator) tokens = raw_input() # remove whitespace tokens = re.sub('\s+', '', tokens) # split by addition/subtraction operators tokens = re.split('(-|\+)', tokens) # takes in a string of numbers, *s, and /s. returns the result def solve_term(tokens): tokens = re.split('(/|\*)', tokens) ret = float(tokens[0]) for op, num in : #  return ret # initialize final result to the first term's value result = solve_term(tokens[0]) # calculate the final result by adding/subtracting terms for op, num in : result += solve_term(num) * (1 if op == '+' else -1) print result 

Dado que se parece a la tarea, dudo que se permita al OP usar las formas típicas de resolver el problema. Creo que este es un ejercicio de validación de entrada y manipulación de cadenas; seguido por el flujo del progtwig y la función de comprensión devuelve valores

Hay dos cosas que debes hacer aquí:

  1. Averigüe cuáles serían las entradas válidas para su progtwig.
  2. Siga preguntando al usuario hasta que él o ella ingrese una entrada que sea válida para su progtwig.

Para el # 1, sabemos que las entradas válidas son números (enteros positivos o negativos), y deben tener la forma de una expresión. Entonces, esto significa que la longitud mínima de la entrada será de tres (dos números y un símbolo matemático) y los caracteres (cadenas) en la entrada no serán válidos.

Este es nuestro bucle básico para obtener la entrada del usuario:

 expression = raw_input('Please enter the expression: ') expression_result = check_input(expression) while not expression_result: print 'You did not enter a valid expression' expression = raw_input('Please enter the expression: ') expression_result = check_input(expression) 

El método check_input validará todo lo que el usuario ingresó es exacto según nuestras reglas:

 def check_input(input_string): # Check the basics if len(input_string) < 3: return False # Check if we are getting passed correct characters for character in input_string: if character not in '1234567890' or character not in '/*+-': return False # Things like /23 are not valid if input_string[0] in '/*+': return False return input_string 

Una vez que tenga la entrada correcta, el siguiente paso es dividir la entrada en las distintas partes que necesita para alimentar sus funciones matemáticas. Te dejaré esa parte a ti.


Suponiendo que tiene la cadena correcta (es decir, es una entrada válida para su progtwig), ahora necesita dividirla en dos partes.

  1. El operador (el símbolo matemático)
  2. Los operandos (los números que rodean el símbolo matemático)

Así que sabemos que tenemos un conjunto limitado de operadores +,-,/,* , por lo que una idea es usar el método split() de cadenas. Esto funciona bien:

 >>> s = '4+5' >>> s.split('+') ['4', '5'] 

Intentaría dividir la cadena con todos sus operadores y luego verificar los resultados. Tenga en cuenta que dividir una cadena con un carácter que no existe no generará ningún error, pero la cadena volverá a aparecer:

 >>> s = '4+5' >>> s.split('/') ['4+5'] 

Entonces, un enfoque es: dividir la cadena en los operadores, si la lista resultante tiene una longitud> 2, usted sabe que el primer miembro de la lista resultante es el lado izquierdo del operador, y el segundo miembro de la lista es lo que sea al lado derecho.

Esto funciona bien con números positivos, sin embargo con números negativos:

 >>> s = '-4+3' >>> s.split('-') ['', '4+3'] 

La buena noticia es que no somos los primeros en llegar a este problema. Hay otra forma de evaluar ecuaciones, llamada notación polaca (también llamada notación de prefijo). Aquí está el algoritmo de la página de wikipedia:

 Scan the given prefix expression from right to left for each symbol { if operand then push onto stack if operator then { operand1=pop stack operand2=pop stack compute operand1 operator operand2 push result onto stack } } return top of stack as result 

Para obtener una expresión normal (llamada infijo) al sabor del esmalte, use el algoritmo shunting yard , que es mi algoritmo favorito basado en trenes en informática.

Usa el patio de derivación para convertir tu expresión a notación polaca, luego usa el pseudo código para resolver la ecuación. Puedes usar listas como tu "stack".

Tenga en cuenta que todas sus entradas están en cadenas, así que asegúrese de convertirlas a números enteros cuando esté haciendo los cálculos reales.

Si está haciendo solo una calculadora de juguete, eval() acepta variables locales y globales, por lo que podría usar algo como esto:

 def calculate(x=0, y=0, z=0): expression = raw_input('Enter an expression: ') return eval(expression, None, locals()) 

Aquí hay una sesión de consola de muestra:

 >>> calculate() Enter an expression: x + 5 - y 5 

Tenga en cuenta que eval() no es seguro. Si quieres hacer algo serio, tendrás que analizar la expresión.

Además, como sus expresiones son simples, puede usar una expresión regular para validar la entrada antes de eval :

 def validate(expression): operator = r'\s*[+\-/*]\s*' return bool(re.match(r'^\s*(?:x{o}y|x{o}y{o}z)$'.format(o=operator), expression)) 

Tengo una alternativa a tu código. El usuario puede ingresar cosas como: 8 * 6 / 4-3 + 3 y esto seguirá funcionando. Tampoco se bloqueará si se ingresa una letra (d, a, s). Muy compacta.

Código (Python v3.3.0):

 valid_chars = "0123456789-+/* \n"; while True: x = "x=" y = input(" >> ") x += y if False in [c in valid_chars for c in y]: print("WARNING: Invalid Equation"); continue; if(y == "end"): break exec(x) print(x)