# Calculadora prefija
# + 1 3 -> 4
def calcula(opr, op1, op2):
"""Calcula una expresión inmediata, como + 2 4"""
toret = 0
if opr == '+':
toret = op1 + op2
elif opr == '-':
toret = op1 - op2
elif opr == '*':
toret = op1 * op2
elif opr == '/':
toret = op1 / op2
elif opr == '^':
toret = op1 ** op2
else:
raise Exception("operando no reconocido")
return toret
def parse(s):
"""Retorna los operadores y operandos, como una lista de texto."""
def inserta_operando():
nonlocal operando
toret.append(float(operando))
operando = ""
operando = ""
toret = []
operadores = "+-*/^"
pos = 0
for ch in s:
if ch in operadores:
if operando:
inserta_operando()
toret.append(ch)
elif ch.isdigit() or ch =='.':
operando += ch
else:
inserta_operando()
if operando:
inserta_operando()
return toret
def opera(eltos, pos):
"""Función recursiva que calcula una expresión compleja"""
opr = ""
op1 = 0.0
op2 = 0.0
# Leer el operador
elto = eltos[pos]
if isinstance(elto, str):
opr = elto
else:
raise Exception("se esperaba un operador")
# Leer el operando 1
pos += 1
elto = eltos[pos]
if isinstance(elto, str):
# Es un operador
pos, op1 = opera(eltos, pos)
else:
op1 = elto
# Leer el operando 2
pos += 1
elto = eltos[pos]
if isinstance(elto, str):
# Es un operador
pos, op2 = opera(eltos, pos)
else:
op2 = elto
return pos, calcula(opr, op1, op2)
if __name__ == "__main__":
s = input("Dame una expresión prefija: ")
print("\nResultado:", opera(parse(s), 0)[1])
IyBDYWxjdWxhZG9yYSBwcmVmaWphCiMgKyAxIDMgLT4gNAoKCmRlZiBjYWxjdWxhKG9wciwgb3AxLCBvcDIpOgoJIiIiQ2FsY3VsYSB1bmEgZXhwcmVzacOzbiBpbm1lZGlhdGEsIGNvbW8gKyAyIDQiIiIKCXRvcmV0ID0gMAoJCglpZiBvcHIgPT0gJysnOgoJCXRvcmV0ID0gb3AxICsgb3AyCgllbGlmIG9wciA9PSAnLSc6CgkJdG9yZXQgPSBvcDEgLSBvcDIKCWVsaWYgb3ByID09ICcqJzoKCQl0b3JldCA9IG9wMSAqIG9wMgoJZWxpZiBvcHIgPT0gJy8nOgoJCXRvcmV0ID0gb3AxIC8gb3AyCgllbGlmIG9wciA9PSAnXic6CgkJdG9yZXQgPSBvcDEgKiogb3AyCgllbHNlOgoJCXJhaXNlIEV4Y2VwdGlvbigib3BlcmFuZG8gbm8gcmVjb25vY2lkbyIpCgkJCglyZXR1cm4gdG9yZXQKCgpkZWYgcGFyc2Uocyk6CgkiIiJSZXRvcm5hIGxvcyBvcGVyYWRvcmVzIHkgb3BlcmFuZG9zLCBjb21vIHVuYSBsaXN0YSBkZSB0ZXh0by4iIiIKCgoJZGVmIGluc2VydGFfb3BlcmFuZG8oKToKCQlub25sb2NhbCBvcGVyYW5kbwoJCQoJCXRvcmV0LmFwcGVuZChmbG9hdChvcGVyYW5kbykpCgkJb3BlcmFuZG8gPSAiIgoJCglvcGVyYW5kbyA9ICIiCgl0b3JldCA9IFtdCQoJb3BlcmFkb3JlcyA9ICIrLSovXiIKCXBvcyA9IDAKCQoJZm9yIGNoIGluIHM6CgkJaWYgY2ggaW4gb3BlcmFkb3JlczoKCQkJaWYgb3BlcmFuZG86CgkJCQlpbnNlcnRhX29wZXJhbmRvKCkKCQkJdG9yZXQuYXBwZW5kKGNoKQoJCWVsaWYgY2guaXNkaWdpdCgpIG9yIGNoID09Jy4nOgoJCQlvcGVyYW5kbyArPSBjaAoJCWVsc2U6CgkJCWluc2VydGFfb3BlcmFuZG8oKQoJCglpZiBvcGVyYW5kbzoKCQlpbnNlcnRhX29wZXJhbmRvKCkKCQkKCXJldHVybiB0b3JldAoKCmRlZiBvcGVyYShlbHRvcywgcG9zKToJCgkiIiJGdW5jacOzbiByZWN1cnNpdmEgcXVlIGNhbGN1bGEgdW5hIGV4cHJlc2nDs24gY29tcGxlamEiIiIKCQoJb3ByID0gIiIKCW9wMSA9IDAuMAoJb3AyID0gMC4wCgkKCSMgTGVlciBlbCBvcGVyYWRvcgoJZWx0byA9IGVsdG9zW3Bvc10KCWlmIGlzaW5zdGFuY2UoZWx0bywgc3RyKToKCQlvcHIgPSBlbHRvCgllbHNlOgoJCXJhaXNlIEV4Y2VwdGlvbigic2UgZXNwZXJhYmEgdW4gb3BlcmFkb3IiKQoJCgkjIExlZXIgZWwgb3BlcmFuZG8gMQoJcG9zICs9IDEKCWVsdG8gPSBlbHRvc1twb3NdCglpZiBpc2luc3RhbmNlKGVsdG8sIHN0cik6CgkJIyBFcyB1biBvcGVyYWRvcgoJCXBvcywgb3AxID0gb3BlcmEoZWx0b3MsIHBvcykKCWVsc2U6CgkJb3AxID0gZWx0bwoJCQoJIyBMZWVyIGVsIG9wZXJhbmRvIDIKCXBvcyArPSAxCgllbHRvID0gZWx0b3NbcG9zXQoJaWYgaXNpbnN0YW5jZShlbHRvLCBzdHIpOgoJCSMgRXMgdW4gb3BlcmFkb3IKCQlwb3MsIG9wMiA9IG9wZXJhKGVsdG9zLCBwb3MpCgllbHNlOgoJCW9wMiA9IGVsdG8KCQoJcmV0dXJuIHBvcywgY2FsY3VsYShvcHIsIG9wMSwgb3AyKQoKCmlmIF9fbmFtZV9fID09ICJfX21haW5fXyI6CglzID0gaW5wdXQoIkRhbWUgdW5hIGV4cHJlc2nDs24gcHJlZmlqYTogIikKCXByaW50KCJcblJlc3VsdGFkbzoiLCBvcGVyYShwYXJzZShzKSwgMClbMV0pCg==