Il programma si rifiuta di eseguire l'istruzione "if" nonostante abbia un valore valido come input

Aug 20 2020

Sono molto nuovo nella programmazione per computer e attualmente sto scrivendo un programma in PyCharm Community che, quando viene dato il nome di uno studente della mia scuola, stamperà le indicazioni per raggiungere la casa di detto studente dalla scuola.

Tutto sta andando molto bene, e ieri sera ho fatto funzionare la base. Oggi ho aperto il mio computer e per qualche motivo il mio programma si rifiuta di eseguire le mie istruzioni 'if'/'elif' e eseguirà solo l'istruzione else anche quando gli viene assegnato un valore che soddisfa l'istruzione 'if'/'elif'.

Ho provato a riscrivere il programma, riavviando PyCharm più volte, assicurandomi di essere coerente con spazi e tabulazioni e assicurandomi che le mie variabili possano comunicare tra loro. Ho scavato per un po 'qui e su altri siti Web e non riesco proprio a vedere un motivo per cui il mio codice funzionava ieri, ma ora si rifiuta di eseguire qualsiasi cosa tranne l'istruzione else.

Ecco il mio codice, chiederà all'utente "Dove vorresti andare?" e quindi riceverà un input di "casa". Una volta ricevuto questo, stamperà le loro indicazioni. Invece di questo, esegue l'istruzione 'else' ogni volta.

# 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

Risposte

2 mattbornski Aug 19 2020 at 23:50

casefoldconverte la stringa in lettere minuscole e le stringhe di riferimento includono caratteri maiuscoli.

Come semplice soluzione, potresti cambiare "casa di David" in "casa di David", ecc.

A lungo termine, potresti voler implementare un confronto leggermente meno fragile, ma questo è un grande esercizio e dipende da come verrà utilizzato il tuo programma e quali sono le conseguenze dell'errore di analisi.

2 marsnebulasoup Aug 20 2020 at 00:16

Per la correzione degli errori di battitura e il supporto per gli utenti che fanno cose che interrompono i test, ecco un esempio che utilizza il confronto della somiglianza delle stringhe per determinare se l'input è vicino al nome di qualsiasi utente:

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

Quindi, se inserisci 'William's house', 'William', 'William's house', 'Williamm' o qualcosa di simile a 'William', otterrai le indicazioni per la casa di William.

Eseguilo online:https://repl.it/@marsnebulasoup/UprightMutedSymbol

1 tdelaney Aug 20 2020 at 00:06

Minimizza il programma e prova! Hai pubblicato più codice del necessario per dimostrare il problema. Una volta che ottieni qualcosa come if destination.casefold() == 'Davids house':non funzionare, riduci al minimo quell'unico problema con i dati in scatola

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

Questo stampa

"david's house" failed

L'help per casefolddice Restituisci una versione della stringa adatta per confronti senza maiuscole e minuscole. . Ah, questo è tutto. Devi piegare entrambi i lati. E poi c'è quel fastidioso apostrofo. Forse hai bisogno di più normalizzazione come eliminare i caratteri non alfabetici.

Riducendo a icona, hai scritto un buon test per il tuo codice. Potresti scrivere una piccola funzione di confronto che esegua il casefold e altre normalizzazioni. Potresti quindi scrivere una dozzina di test su quella funzione per testare tutti i casi limite.