El programa se niega a ejecutar la declaración 'si' a pesar de tener un valor válido como entrada

Aug 20 2020

Soy muy nuevo en la programación de computadoras y actualmente estoy escribiendo un programa en PyCharm Community que, cuando se le da el nombre de un estudiante en mi escuela, imprimirá direcciones a la casa de dicho estudiante desde la escuela.

Todo ha ido muy bien, y la base funcionó anoche. Hoy abrí mi computadora y por alguna razón mi programa se niega a ejecutar mis declaraciones 'if'/'elif' y solo ejecutará la declaración else incluso cuando se le da un valor que satisface la declaración 'if'/'elif'.

Intenté reescribir el programa, reiniciando PyCharm varias veces, asegurándome de ser coherente con los espacios y tabulaciones, y me aseguré de que todas mis variables puedan comunicarse entre sí. He investigado durante un tiempo aquí y en otros sitios web y simplemente no puedo ver una razón de por qué mi código funcionaba ayer, pero ahora se niega a ejecutar cualquier cosa que no sea la instrucción else.

Aquí está mi código, le preguntará al usuario "¿A dónde te gustaría ir?" y luego recibirá una entrada de "casa". Una vez que reciba esto, imprimirá sus instrucciones. En lugar de esto, ejecuta la declaración 'else' cada vez.

# Storing the names and directions of users:
David = "Directions to David's home from T... \n East on X, \n South on Y.," \
            " \n West on Z., \n South on A., \n first white house on the right."

Caroline = "Directions to Caroline's home from T... \n East on x, \n South on y.," \
        " \n East on z., \n South on p., \n East on q," \
        " \n West on t., \n last brick house in the cul-de-sac."

William = "Directions to Will's home from T... \n East on x, \n South on y.," \
        " \n West on z., \n South on Fa., \n West on b., \n first house on the right."

Bannon = "<Insert directions to Bannon's house>"

# User gives a specific name and then receives a location:
while True:
    destination = input("Where would you like to go? ")

    if destination.casefold() == 'Davids house':
        print(David)
        continue

    elif destination.casefold() == 'Carolines house':
        print(Caroline)
        continue

    elif destination.casefold() == 'Wills house':
        print(William)
        continue

    elif destination.casefold() == 'Bannons house':
        print(Bannon)
        continue

    # If an invalid location is given, this code will run:
    else:
        print("Sorry, that location wasn't found! Please try again.")
        continue

Respuestas

2 mattbornski Aug 19 2020 at 23:50

casefoldconvierte la cadena a minúsculas y sus cadenas de referencia incluyen caracteres en mayúsculas.

Como una solución simple, puede cambiar 'Casa de David' a 'Casa de David', etc.

A largo plazo, es posible que desee implementar una comparación un poco menos frágil, pero ese es un gran ejercicio y depende de cómo se utilizará su programa y cuáles son las consecuencias de la falta de análisis.

2 marsnebulasoup Aug 20 2020 at 00:16

Para la corrección de errores tipográficos y soporte para usuarios que hacen cosas que rompen las pruebas, aquí hay un ejemplo que usa la comparación de similitud de cadenas para determinar si la entrada está cerca del nombre de cualquier usuario:

import difflib
# Storing the names and directions of users: 
#This is called a dictionary. More info here https://www.w3schools.com/python/python_dictionaries.asp
directions= {
    "David": "Directions to David's home from T... \n East on X, \n South on Y.," \
            " \n West on Z., \n South on A., \n first white house on the right.",

    "Caroline": "Directions to Caroline's home from T... \n East on x, \n South on y.," \
        " \n East on z., \n South on p., \n East on q," \
        " \n West on t., \n last brick house in the cul-de-sac.",

    "William":"Directions to Will's home from T... \n East on x, \n South on y.," \
        " \n West on z., \n South on Fa., \n West on b., \n first house on the right.",

    "Bannon":"<Insert directions to Bannon's house>"
}

# User gives a specific name and then receives a location:
while True:
    destination = input("Where would you like to go? ")

    highest = 0 #highest score between the user name and input
    user_key = "" #name of the user who most closely matches the input
    for user in directions: #iterate through all the user's names in the directions dictionary
      similarity = difflib.SequenceMatcher( #for each user's name, compare it to the input
          None, destination, user).ratio()
      if(similarity > highest): #if the similarity score is greater than the highest recorded score, update the score
        highest = similarity
        user_key = user
    
    #Code that runs if a match is too low are not found
    if(highest < 0.5): #adjust this based on how close you want the match to be. highest will always be between 0.0 and 1.0
      print("Sorry, that location wasn't found! Please try again.")
      continue

    #Print user's directions
    else:
      print('\n\nGetting directions to ' + user_key + '\'s house\n\n')
      print(directions[user_key] + "\n\n\n")

Entonces, si ingresa 'William's house', 'William', 'William's house', 'William' o algo parecido a 'William', obtendrá las indicaciones para llegar a la casa de William.

Ejecutarlo en línea:https://repl.it/@marsnebulasoup/UprightMutedSymbol

1 tdelaney Aug 20 2020 at 00:06

¡Minimiza el programa y prueba! Publicó más código del necesario para demostrar el problema. Una vez que obtenga algo como que if destination.casefold() == 'Davids house':no funciona, minimice ese problema con datos enlatados

destination = "david's house"
if not destination.casefold() == "Davids house":
    print(repr(destination), "failed")

esto imprime

"david's house" failed

La ayuda para casefolddice Devuelve una versión de la cadena adecuada para comparaciones sin mayúsculas y minúsculas. . Ah, eso es todo. Necesitas plegar ambos lados. Y luego está ese molesto apóstrofe. Tal vez necesite más normalización, como deshacerse de los caracteres no alfabéticos.

Al minimizar, escribió una buena prueba para su código. Podría escribir una pequeña función de comparación que realice el pliegue de casos y otras normalizaciones. Luego podría escribir una docena de pruebas en esa función para probar todos los casos extremos.