1

Ok, I've been trying to mess with the code, and that is what I get. I've been for a long time trying to make an advanced calculator for (no particular reason, just practice). Until then OK. Also tried to make an exception zone, mainly for the ValueError for the coma instead of period on input.

Ok still ok 'till here. Also, after the error happens I added a loop, why? So after the exception, you can automatically start again at the calculator and the "app" does not just close. And it works! But now starts the issue with one feature.

If you see, inside the code there is an "exit" feature. So if you type exit, you can close the app. The issue is that the loop (While True) I made to keep the app running after an exception, is what now denies closing the app. So if you type "exit", the app restarts and go back to start the loop.

I've tried many things, most of them actually stupid, with dead-ends... So not worth describing.

I am really green not only at Python, but coding in general (this is my first code). So I don't know if I don't have knowledge enough to do what I want to achieve or if I am just missing something.

Thank you in advance!

from rich import print
from rich.table import Table

# Con este bucle consigo que si sale algún "Excption", con el "continue", vuelva a iniciar el Loop y no se corte la calculadora.
while True:
    try:
        # Configuración de la Tabla a modo de ayuda
        leyenda = Table("Comando", "Operador")
        leyenda.add_row("+", "Suma")
        leyenda.add_row("-", "Resta")
        leyenda.add_row("*", "Multiplicación")
        leyenda.add_row("/", "División decimal")
        leyenda.add_row("help", "Imprime leyenda")
        leyenda.add_row("exit", "Cerrar la app")

        print("Calculadora de dos valores\n")
        print(leyenda)

        # Bucle de la calculadora para que esté siempre abierta
        while True:

            # Teclado de la calculadora
            dig1 = input("Introduce el primer número a calcular: ")
            if dig1 == "exit":
                print("¡Hasta pronto!")
                break
            elif dig1 == "help":
                print(leyenda)
                continue # Con el continue forzamos a que el bucle vuelva a comenzar

            operator = input("Introduce el operador: ")
            if operator == "exit":
                print("¡Hasta pronto!")
                break
            elif operator == "help":
                print(leyenda)
                continue

            dig2 = input("Introduce el segundo número a calcular: ")
            if dig2 == "exit":
                print("¡Hasta pronto!")
                break
            elif dig2 == "help":
                print(leyenda)
                continue

            # Conversor de valores de string (input) a float
            num1 = float(dig1)
            num2 = float(dig2)

            # Zona de cálculo (el motor de la calculadora)
            if operator == "+":
                print(f"{dig1} más {dig2} es igual a {num1 + num2}.\n")
            
            if operator == "-":
                print(f"{dig1} menos {dig2} es igual a {num1 - num2}.\n")

            if operator == "*":
                print(f"{dig1} multiplicado por {dig2} es igual a {num1 * num2}.\n")

            if operator == "/":
                print(f"{dig1} dividido entre {dig2} es igual a {num1 / num2}.\n")

    except TypeError as error_tipo:
        print("Error de tipo.\nDetalles del error:", error_tipo,".\n")
        continue

    except ValueError as error_valor:
        print("Error de valor.\nDetalles del error:", error_valor)
        print("Posible solución: Si para los decimales has usado la coma (,), usa el punto(.).\n")
        continue

    except SyntaxError as error_sintaxis:
        print("Error de sintáxis.\nDetalles del error:", error_sintaxis,".\n")
        continue

    except:
        print("Error general.\n")
        continue

    finally:
        print("Reiniciando aplicación.\n")

Lorak
  • 33
  • 6
  • 1
    Does this answer your question? [How to break out of nested loops in python?](https://stackoverflow.com/questions/40602620/how-to-break-out-of-nested-loops-in-python) – Ignatius Reilly Mar 26 '23 at 23:23
  • One possibility here is to `raise` an exception rather than `break`ing. That would get you to a corresponding `except` in your outer loop; you could raise a custom exception that would result in exiting rather than printing an error message. – Samwise Mar 26 '23 at 23:24
  • https://stackoverflow.com/questions/189645/how-can-i-break-out-of-multiple-loops – Ignatius Reilly Mar 26 '23 at 23:24
  • About the `raise`ing exception, that is something I don't know about. I don't know what it is, so I will learn about it. Thanks! – Lorak Mar 26 '23 at 23:44

3 Answers3

0

An option is the use of a flag, at the start of your code you define: exited = False And before the "Hasta Pronto you define

exited = True

So in the finally you can add:

finally:
    if exited:
        break
    print("Reiniciando aplicación.\n")
Pablo Estevez
  • 186
  • 1
  • 8
0

You could avoid having to do this in the first place by changing up the design a bit to avoid a nested while loop. For example, your initialization doesn't have to happen more than once. The outer-most while loop is therefore unnecessary and exception handling can be moved to the inner loop.

Of course, you can use a flag to break the outter loop from within the inner loop like what Pablo described, or you could simply shut down the program from inside the inner loop eg. using sys.exit, but it's best to instead try to simplify the design and flatten out the structure to not have to deal with this issue in the first place.

DMSBrian
  • 26
  • 5
0

Ok finally found the solution in the link How can I break out of multiple loops? provided by https://stackoverflow.com/users/15032126/ignatius-reilly

breaker = False #our mighty loop exiter!
while True:
    while True:
        if conditionMet:
            #insert code here...
            breaker = True 
            break
    if breaker: # the interesting part!
        break   # <--- !
Lorak
  • 33
  • 6