Программа отказывается запускать оператор if, несмотря на то, что на входе имеется допустимое значение.

Aug 20 2020

Я очень новичок в компьютерном программировании и в настоящее время пишу программу в сообществе PyCharm, которая по имени ученика в моей школе будет распечатывать направления к дому этого ученика из школы.

Все шло очень хорошо, и прошлой ночью я убедился, что это работает. Сегодня я открыл свой компьютер, и по какой-то причине моя программа отказывается запускать мои операторы if / elif и будет запускать только оператор else, даже если ему присвоено значение, удовлетворяющее оператору if / elif.

Я попытался переписать программу, перезапустить PyCharm несколько раз, убедившись, что я согласен с пробелами и табуляциями, и убедился, что все мои переменные могут взаимодействовать друг с другом. Я какое-то время копался здесь и на других веб-сайтах, и я просто не вижу причины, почему мой код работал вчера, но теперь отказывается запускать что-либо, кроме оператора else.

Вот мой код, он спросит пользователя: «Куда вы хотите пойти?» а потом получит вход «дом». Как только он получит это, он распечатает их направления. Вместо этого он каждый раз запускает инструкцию else.

# 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

Ответы

2 mattbornski Aug 19 2020 at 23:50

casefold преобразует строку в нижний регистр, а ваши ссылочные строки содержат символы верхнего регистра.

В качестве простого исправления вы можете изменить «Дом Дэвидса» на «Дом Дэвида» и т. Д.

В долгосрочной перспективе вы можете захотеть реализовать немного менее хрупкое сравнение, но это серьезное упражнение, которое зависит от того, как ваша программа будет использоваться, и каковы последствия неудачного анализа.

2 marsnebulasoup Aug 20 2020 at 00:16

Для исправления опечаток и поддержки пользователей, выполняющих действия, нарушающие тесты, вот пример, использующий сравнение схожести строк, чтобы определить, близок ли ввод к имени любого пользователя:

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

Так что, если вы войдете в «Дом Уильяма», «Уильям», «Дом Уильяма», «Уильямм» или что-то близкое к «Уильяму», вы получите направление к дому Уильяма.

Запустите его онлайн: https://repl.it/@marsnebulasoup/UprightMutedSymbol

1 tdelaney Aug 20 2020 at 00:06

Сверните программу и протестируйте! Вы разместили больше кода, чем необходимо для демонстрации проблемы. Как только вы получите что-то вроде if destination.casefold() == 'Davids house':неработающего, сведите к минимуму эту проблему с сохраненными данными.

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

Это печатает

"david's house" failed

В справке по casefoldзапросу « Вернуть версию строки», подходящую для сравнения без регистра. . Ах, вот и все. Вам нужно сложить коробку с обеих сторон. А еще есть этот надоедливый апостроф. Возможно, вам нужна дополнительная нормализация, например, избавление от неалфавитных символов.

Свернув к минимуму, вы написали хороший тест для своего кода. Вы можете написать небольшую функцию сравнения, которая выполняет регистр и другую нормализацию. Затем вы можете написать дюжину тестов для этой функции, чтобы проверить все крайние случаи.