Soy nuevo en Python y en la programación en general. He estado escribiendo un convertidor de temperatura como una forma de practicar algunos conceptos que he aprendido. Lo que escribí hasta ahora funciona bien en general, pero he golpeado una pared de ladrillos en un objetivo específico que estoy tratando de lograr:

Cuando el usuario realiza una primera elección aceptable ("F a C" o "C a F", en lugar de cualquier otra cosa), recibe la siguiente pregunta, que es la temperatura que desea convertir. Aquí también me he asegurado de que el programa no muestre un mensaje de error y se detenga cuando la persona ingrese algo que no sea un número entero o flotante, pero si eso sucede, no quiero que el programa se repita completamente el comienzo, pero solo al comienzo de esa rama particular del árbol de decisión.

En otras palabras, cuando alguien dice que quiere convertir un valor Fahrenheit a Celsius pero luego escribe "jambalaya" en lugar de "78", quiero que el programa les pida que "ingresen un valor" nuevamente dentro del mismo "Fahrenheit a Celsius". "rama de selección, en lugar de preguntarles si quieren convertir F a C o C a F, que es lo que el programa está haciendo actualmente.

(Solo una nota rápida: QUIERO que el programa siga preguntando si la persona quiere convertir de F a C o C a F, SI la persona ha obtenido con éxito un valor convertido).

Aquí está el código que he escrito:

def temperature():
while True:
    selection = input ('Choose your conversion ("F to C" or "C to F"): ')
    if selection == 'F to C':
        num = input ('Enter a temperature in °F: ')
        try:
            float(num)
            r = round(float(num))
            s = (r-32)*(5/9)
            print (r,'°F is ',round(s),'°C')
            if s > 30:
                print ('A little hot out there!')
            elif s < 5:
                print ('Make sure to wear a jacket!')
            else:
                print ('Have a nice day!')
        except:
            print ('Please enter only numbers') 
    elif selection == 'C to F':
        num = input ('Enter a temperature in °C: ')
        try:
            float(num)
            r = round(float(num))
            s = (r*9/5)+32
            print (r,'°C is ',round(s),'°F')
            if s > 86:
                print ('A little hot out there!')
            elif s < 41:
                print ('Make sure to wear a jacket!')
            else:
                print ('Have a nice day!')
        except:
            print ('Please enter only numbers')
    else:
        print ('Please make a valid selection')
temperature()

¿Cómo enmendaría este código para lograr el resultado que he descrito anteriormente?

0
Seeing what the fuss is about 29 oct. 2017 a las 07:14

3 respuestas

La mejor respuesta

La forma más fácil de hacer esto es simplemente agregar otro ciclo a su programa que seguirá pidiéndole a su usuario que ingrese un valor correcto. Una vez que el usuario ingresa un valor correcto, sale del bucle usando break.

def temperature():
while True:
    selection = input ('Choose your conversion ("F to C" or "C to F"): ')
    if selection == 'F to C':
        while True: # *** Wrap this code in a loop
            num = input ('Enter a temperature in °F: ')
            try:
                float(num)
                r = round(float(num))
                s = (r-32)*(5/9)
                print (r,'°F is ',round(s),'°C')
                if s > 30:
                    print ('A little hot out there!')
                elif s < 5:
                    print ('Make sure to wear a jacket!')
                else:
                    print ('Have a nice day!')

                break # *** Break out of the loop after a success
            except:
                print ('Please enter only numbers') 
    elif selection == 'C to F':
        while True:
            num = input ('Enter a temperature in °C: ')
            try:
                float(num)
                r = round(float(num))
                s = (r*9/5)+32
                print (r,'°C is ',round(s),'°F')
                if s > 86:
                    print ('A little hot out there!')
                elif s < 41:
                    print ('Make sure to wear a jacket!')
                else:
                    print ('Have a nice day!')

                break
            except:
                print ('Please enter only numbers')
    else:
        print ('Please make a valid selection')
temperature()

Como probablemente sea fácil de decir, esto comienza a complicar las cosas. Probablemente sea una buena idea tomar el código de F a C y C a F y moverlo a su propia función.

0
Jesse 29 oct. 2017 a las 04:27

Una cosa que podría hacer aquí es combinar su bucle while con un try. La idea quizás nueva es probar el tipo de objeto.

num = ''
while not type(num) == float:
    try:
        num = float(num)
    except:
        num = input('Enter a temperature in °F: ')
0
bjdduck 29 oct. 2017 a las 04:27

Para su propósito, le sugiero que escriba una función separada para calcular la conversión para que pueda llamarla recursivamente

# first of all let's define how many invalid attempt you want to allow to user.
MAX_INCORRECT_ATTEMPT = 5

def f_to_c(attempt=0):
    """
    convert °F to °C
    """
    try:
        num = float(input ('Enter a temperature in °F: ')) # take input and convert it to float if exception occurs it will be handled
        r = round(num)
        s = (r-32)*(5/9)
        print (r,'°F is ',round(s),'°C')
        if s > 30:
            print ('A little hot out there!')
        elif s < 5:
            print ('Make sure to wear a jacket!')
        else:
            print ('Have a nice day!')
        return True # returns True if act of user is valid as expected
    except ValueError: # to only handle valueerror caused only if user enters invalid input like string or any special character
        # it is good habit to precise which exception you are handling so I have specified ValueError arise in python3 when conversion of input is not possible
        attempt += 1 # well here we increse invalid attempt count
        print ('Please enter only numbers..')
        if attempt > MAX_INCORRECT_ATTEMPT:
            return False
        else:
            return f_to_c(attempt) # pass the invalid attempt count to function argument


def c_to_f(attempt=0):
    """
    convert °C to °F
    """
    try:
        num = float(input('Enter a temperature in °C: '))
        r = round(num)
        s = (r*9/5)+32
        print("{} °C is {} °F".format(r, round(s)))
        if s > 86:
            print ('A little hot out there!')
        elif s < 41:
            print ('Make sure to wear a jacket!')
        else:
            print ('Have a nice day!')
        return True
    except ValueError:
        attempt += 1 # calculating attempt so we can end the program if user exceeds allowed limit of faults
        print ('Please enter only numbers..')
        if attempt > MAX_INCORRECT_ATTEMPT:
            return False
        else:
            return c_to_f(attempt)


def temperature_converter():
    while True:
        selection = input ('\nChoose your conversion \n1- "F to C" \n2- "C to F"\n3- Quit\n> ')
        if selection == '1':
            status = f_to_c() # store the value returned by function in status
            if not status: # the block only executes if function return False
                print("too many incorrect attempt... bye...")
                break
        elif selection == '2':
            stat = c_to_f()
            if not stat:
                print("too many incorrect attempt... bye...")
                print("bye...")
                break
        elif selection == "3":
            print("bye...")
            break
        else:
            print ('Please make a valid selection.')

temperature_converter()

Salida:

Choose your conversion
1- "F to C"
2- "C to F"
3- Quit
> 1
Enter a temperature in °F: sd
Please enter only numbers..
Enter a temperature in °F: 25
25 °F is  -4 °C
Make sure to wear a jacket!

Choose your conversion
1- "F to C"
2- "C to F"
3- Quit
> 3
bye...
0
Gahan 6 nov. 2017 a las 08:04