Le programme refuse d'exécuter l'instruction 'if' bien qu'il ait une valeur valide comme entrée

Aug 20 2020

Je suis très nouveau dans la programmation informatique et j'écris actuellement un programme dans la communauté PyCharm qui, lorsqu'on lui donne le nom d'un élève de mon école, imprimera les directions vers la maison dudit élève depuis l'école.

Tout s'est très bien passé, et j'ai fait fonctionner la base hier soir. Aujourd'hui, j'ai ouvert mon ordinateur et pour une raison quelconque, mon programme refuse d'exécuter mes instructions 'if'/'elif' et n'exécutera que l'instruction else même si une valeur qui satisfait l'instruction 'if'/'elif' lui est donnée.

J'ai essayé de réécrire le programme, de redémarrer PyCharm plusieurs fois, de m'assurer que je suis cohérent avec les espaces et les tabulations, et de m'assurer que mes variables peuvent toutes communiquer entre elles. J'ai creusé pendant un certain temps ici et sur d'autres sites Web et je ne vois tout simplement pas pourquoi mon code fonctionnait hier mais refuse maintenant d'exécuter autre chose que l'instruction else.

Voici mon code, il demandera à l'utilisateur "Où voudriez-vous aller?" et recevra ensuite une entrée de "maison". Une fois qu'il l'aura reçu, il imprimera ses instructions. Au lieu de cela, il exécute l'instruction 'else' à chaque fois.

# 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

Réponses

2 mattbornski Aug 19 2020 at 23:50

casefoldconvertit la chaîne en minuscules et vos chaînes de référence incluent des caractères majuscules.

En tant que solution simple, vous pouvez remplacer "Davids house" par "davids house", etc.

À long terme, vous voudrez peut-être implémenter une comparaison légèrement moins fragile, mais c'est un gros exercice et cela dépend de la façon dont votre programme va être utilisé et des conséquences d'un échec d'analyse.

2 marsnebulasoup Aug 20 2020 at 00:16

Pour la correction des fautes de frappe et la prise en charge des utilisateurs faisant des choses qui cassent les tests, voici un exemple utilisant la comparaison de similarité de chaînes pour déterminer si l'entrée est proche du nom d'un utilisateur :

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")

Donc, si vous entrez « William's house », « William », « William's house », « Williamm » ou quelque chose de proche de « William », vous obtiendrez les directions vers la maison de William.

Exécutez-le en ligne :https://repl.it/@marsnebulasoup/UprightMutedSymbol

1 tdelaney Aug 20 2020 at 00:06

Minimisez le programme et testez ! Vous avez posté plus de code que nécessaire pour illustrer le problème. Une fois que vous obtenez quelque chose comme if destination.casefold() == 'Davids house':ne pas fonctionner, réduisez à ce seul problème avec les données prédéfinies

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

Cela imprime

"david's house" failed

L'aide de casefoldindique Renvoyez une version de la chaîne adaptée aux comparaisons sans casse. . Ah, c'est ça. Vous devez plier les deux côtés. Et puis il y a cette apostrophe embêtante. Peut-être avez-vous besoin de plus de normalisation, comme vous débarrasser des caractères non alphabétiques.

En minimisant, vous avez écrit un bon test pour votre code. Vous pouvez écrire une petite fonction de comparaison qui effectue le casier et d'autres normalisations. Vous pouvez ensuite écrire une douzaine de tests sur cette fonction pour tester tous les cas extrêmes.