BroCode氏のYoutubeでPythonを学んでいます。
氏の動画の中で、クイズゲームを作ってみようというのがありました。
動画の中で作ったコードは、以下のとおりです。
────────────────
# Python quiz game questions = ("How many elements are in the periodic table?: ", "Which animal lays the largest eggs?: ", "What is the most abundant gas in Earth's atmosphere?: ", "How many bones are in the human body?: ", "Which planet in the solar system is the hottest?: ") options = (("A. 116","B. 117","C. 118","D. 119"), ("A. Whale","B. Crocodile","C. Elephant","D. Ostrich"), ("A. Nitrogen","B. Oxygen","C. Carbon-Dioxide","D. Hydrogen"), ("A. 206","B. 207","C. 208","D. 209"), ("A. Mercury","B. Venus","C. Earth","D. Mars")) answers = ("C","D","A","A","B") guesses = [] score = 0 question_num = 0 for question in questions: print("---------------------") print(question) for option in options[question_num]: print(option) guess = input("Enter (A, B, C, D): ").upper() guesses.append(guess) if guess == answers[question_num]: score += 1 print("Correct!") else: print("Incorrect!") print(f"{answers[question_num]} is the correct answer!") question_num += 1 print("---------------------") print("RESULT") print("---------------------") print("answers: ", end="") for answer in answers: print(answer, end=" ") print() print("guesses: ", end="") for guess in guesses: print(guess, end=" ") print() score = int(score / len(questions) * 100) print(f"Your score is: {score}%")
────────────────
こういうエキササイズをやるたびに、「どうやったら、よりよいコードになるのかな」ということを考えるようにしています。
自分で改善点を考えて、それを実装できるようにしていけば、プログラミング能力が上がっていくんじゃないかな〜という算段です。
で、今回は以下の点を改善したいなと思いました。
・打ち間違いに対する処理(選択肢がA~Dなのに、GとかPとか、空白を入力した場合の処理)
・クイズを途中でやめる選択肢も提示する(途中でやめた場合は、その時点までの点数を計算する)
・optionsの中身を、(“A. “,”B. “,”C. “,”D. “)だけにして、選択肢を別のリストで用意する(イメージとしては、optionsから”A. “を引っ張ってきて、選択肢を”116″、”117″…と引っ張ってくる)
まずは打ち間違いに対する処理を組んでみたいと思います。
Try-Exceptを使うのかな…?
で、最初に組んでみたコード。うまく動きません。
────────────────
while True: try: guess = input("Enter (A, B, C, D): ").upper() if guess == "A" or "B" or "C" or "D": guesses.append(guess) break else: print("Type A, B, C, or D. Other letters are not valid.") guess = input("Enter again (A, B, C, D): ").upper() guesses.append(guess) break except ValueError: print("Did you make a typo? Then try again.") ────────────────
調べてみた結果。
────────────────
while True: guess = input("Enter (A, B, C, D): ").upper() if guess in ["A","B","C","D"]: guesses.append(guess) break else: print("Invalid input. Please type A, B, C, or D.")
────────────────
Try-Exceptは使わなくてもよかった。
つまり、入力したのがA, B, C, D以外であれば、再度入力を促すようにしてあげればよかった。
while文でループさせてあげるだけでよかったっぽいですね。。。
ここはまだまだ使い方をうまくマスターできていない証なので、使い方をより深めていけたらと思います。
で、一旦打ち間違い時の処理はできるようになったので、つぎは、途中でやめる選択肢を作っていきたいと思います。
先程のA~Dを入力して〜の部分に、Qを押したらプログラムを終了する、というオプションをつければよさそう。
ということでやってみます……といいつつも、そもそもプログラムを終了するにはどーしたらいいんだ?と思ったので、調べました。
exit()でプログラムを終了することができるっぽいので、組み込んでみます。
────────────────
while True: guess = input("Enter (A, B, C, D, enter Q to quit): ").upper() if guess in ["A","B","C","D"]: guesses.append(guess) break elif guess == "Q": exit() else: print("Invalid input. Please type A, B, C, or D.") ────────────────
これで、qまたはQを入力すると、プログラムを終了することができるようになりました。
ちなみに、quit()でもプログラムを終了することができる。両者は非常に似ているそうです。
import sysからsys.exit()を使うことでもプログラムの終了は可能だそうで、こちらはプロダクトレベル環境でよく使われる〜みたいに書いてありました。
まあ、一旦はexit()を使ってコードを書いていこうと思います。
では、最後の
・optionsの中身を、(“A. “,”B. “,”C. “,”D. “)だけにして、選択肢を別のリストで用意する(イメージとしては、optionsから”A. “を引っ張ってきて、選択肢を”116″、”117″…と引っ張ってくる)
について。
まずはoptionsから、A. , B. ,….という部分を削って、新たにprefixes = (“A. “, “B. “,”C. “,”D. “)というタプルを作ります。
で──……どうしたらいいんだ……ここでまたつまづきました。
最初は、optionとprefixを組み合わせればいいのか?と思って、以下のようなコードを書きましたが、syntax errorになります。
for option in options[question_num] and prefix in prefixes[question_num]: print(option) + print(prefix)
はて。。。
ChatGPT大先生に聞いてみました。すると、以下のようなコードを返してくれました。
────────────────
# Use zip() to pair prefixes and options for prefix, option in zip(prefixes, options[question_num]): print(f"{prefix}{option}", end=", ") print() # New line after printing all options
────────────────
zip()で複数のリストやタプルをまとめて、それをインデックス順にしてペアにしてくれている、って認識でしょうか。
で、最終的にA~Dの選択肢を表示する。
これで、一応やりたかったことはすべて達成できたと思います。
完成したコードが以下のもの。
────────────────
# Python quiz game questions = ("How many elements are in the periodic table?: ", "Which animal lays the largest eggs?: ", "What is the most abundant gas in Earth's atmosphere?: ", "How many bones are in the human body?: ", "Which planet in the solar system is the hottest?: ") prefixes = ("A. ", "B. ","C. ","D. ") options = (("116","117","118","119"), ("Whale","Crocodile","Elephant","Ostrich"), ("Nitrogen","Oxygen","Carbon-Dioxide","Hydrogen"), ("206","207","208","209"), ("Mercury","Venus","Earth","Mars")) answers = ("C","D","A","A","B") guesses = [] score = 0 question_num = 0 for question in questions: print("---------------------") print(question) # Use zip() to pair prefixes and options for prefix, option in zip(prefixes, options[question_num]): print(f"{prefix}{option}", end=", ") print() # New line after printing all options #ここから改善トライ while True: guess = input("Enter (A, B, C, D, enter Q to quit): ").upper() if guess in ["A","B","C","D"]: guesses.append(guess) break elif guess == "Q": quit() else: print("Invalid input. Please type A, B, C, or D.") if guess == answers[question_num]: score += 1 print("Correct!") else: print("Incorrect!") print(f"{answers[question_num]} is the correct answer!") question_num += 1 #Show result print("---------------------") print("RESULT") print("---------------------") print("answers: ", end="") for answer in answers: print(answer, end=" ") print() print("guesses: ", end="") for guess in guesses: print(guess, end=" ") print() score = int(score / len(questions) * 100) print(f"Your score is: {score}%")
────────────────
あとはまあ、n回打ち間違えたら、プログラムを強制終了する、みたいなオプションをつけてもいいかと思ったけれど、
一旦はこれで完成ってことで。
今回は、
・while文で選択肢以外の文字列が入力された場合、再度入力を促すようにループさせる
・exit()/quit()/sys.exit()でプログラムを終了する
・zip()で、リストなどをまとめてペアにする
ということを学びました。
とはいえ、まだまだwhileループやzip()の使い方についてはまだまだ理解が深まっていないので、今後も使ってみて身につけていきたいと思った。
おわり