Программа отказывается запускать оператор if, несмотря на то, что на входе имеется допустимое значение.
Я очень новичок в компьютерном программировании и в настоящее время пишу программу в сообществе 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
Ответы
casefold
преобразует строку в нижний регистр, а ваши ссылочные строки содержат символы верхнего регистра.
В качестве простого исправления вы можете изменить «Дом Дэвидса» на «Дом Дэвида» и т. Д.
В долгосрочной перспективе вы можете захотеть реализовать немного менее хрупкое сравнение, но это серьезное упражнение, которое зависит от того, как ваша программа будет использоваться, и каковы последствия неудачного анализа.
Для исправления опечаток и поддержки пользователей, выполняющих действия, нарушающие тесты, вот пример, использующий сравнение схожести строк, чтобы определить, близок ли ввод к имени любого пользователя:
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
Сверните программу и протестируйте! Вы разместили больше кода, чем необходимо для демонстрации проблемы. Как только вы получите что-то вроде if destination.casefold() == 'Davids house':
неработающего, сведите к минимуму эту проблему с сохраненными данными.
destination = "david's house"
if not destination.casefold() == "Davids house":
print(repr(destination), "failed")
Это печатает
"david's house" failed
В справке по casefold
запросу « Вернуть версию строки», подходящую для сравнения без регистра. . Ах, вот и все. Вам нужно сложить коробку с обеих сторон. А еще есть этот надоедливый апостроф. Возможно, вам нужна дополнительная нормализация, например, избавление от неалфавитных символов.
Свернув к минимуму, вы написали хороший тест для своего кода. Вы можете написать небольшую функцию сравнения, которая выполняет регистр и другую нормализацию. Затем вы можете написать дюжину тестов для этой функции, чтобы проверить все крайние случаи.