入力として有効な値があるにもかかわらず、プログラムが「if」ステートメントの実行を拒否する
私はコンピュータープログラミングにとても慣れておらず、現在PyCharm Communityでプログラムを書いています。このプログラムは、私の学校の生徒の名前が与えられると、学校からその生徒の家への道順を印刷します。
すべてが順調に進んでおり、昨夜はその基盤が機能しました。今日、コンピューターを開きましたが、何らかの理由で、プログラムが「if」/「elif」ステートメントの実行を拒否し、「if」/「elif」ステートメントを満たす値が指定されている場合でも、elseステートメントのみを実行します。
プログラムを書き直し、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
文字列を小文字に変換し、参照文字列には大文字が含まれます。
簡単な修正として、「Davidshouse」を「davidshouse」などに変更できます。
長期的には、少し脆弱性の低い比較を実装することをお勧めしますが、これは大きな演習であり、プログラムの使用方法と解析の失敗の結果によって異なります。
タイプミスの修正と、テストに違反することを行うユーザーのサポートについて、文字列の類似性の比較を使用して、入力がユーザーの名前に近いかどうかを判断する例を次に示します。
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':
動作しないような問題が発生したら、既定のデータに関する1つの問題を最小限に抑えます
destination = "david's house"
if not destination.casefold() == "Davids house":
print(repr(destination), "failed")
このプリント
"david's house" failed
のヘルプは、ケースレス比較に適した文字列のバージョンを返すcasefold
と言っています。。ああ、それだけです。両側をケースフォールドする必要があります。そして、その厄介なアポストロフィがあります。アルファベット以外の文字を削除するなど、より正規化する必要があるかもしれません。
最小化することで、コードの適切なテストを作成しました。ケースフォールドやその他の正規化を行う小さな比較関数を作成できます。次に、その関数に対して12個のテストを記述して、すべてのエッジケースをテストできます。