El programa se niega a ejecutar la declaración 'si' a pesar de tener un valor válido como entrada
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
casefold
convierte 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.
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
¡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 casefold
dice 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.