14歳の自分に衝撃の事実を告げてください

親子でpythonの学習中です。
下記のようなじゃんけんプログラムを作成しています。
結果が「あいこ」の場合にはエラーが出ませんが、それ以外のときにエラーとなります。

30行目でエラーとの事ですが、「あいこ」の時にはエラーにならないので、この30行目じゃなくて条件分岐に問題が有るのではないかと考えております。

色々と試してみましたが手詰まりとなりました。
お知恵を頂けたら幸いです。

<エラーメッセージから抜粋>
print('あなたは' + str(hand) + 'を出したので' + result + 'です')
NameError: name 'result' is not defined


<現在のプログラムソース>
# coding: UTF-8
print('じゃんけんを始めます')
print('0=goo1=chok=paa')
#自分の手
hand = input('0:goo 1:chok 2:paa を入力?')
print('あなたの選んだ手は' + str(hand) + 'です.')
#cpのて
import random
comH = random.randint(0,2)
print('cpのては' + str(comH) + 'です')
if hand == comH:
result = 'あいこ'
elif hand == '0':
if comH == '1':
result = '勝ち'
elif comH == '2':
result = '負け'
elif hand == '1':
if comH == '2':
result = '勝ち'
elif comH == '0':
result = '負け'
elif hand == '2':
if comH == '0':
result = '勝ち'
elif comH == '1':
result = '負け'

print('コンピューターは' + str(comH) + 'を出しました')
print('あなたは' + str(hand) + 'を出したので' + result + 'です')

A 回答 (5件)

多分、


comHが数値(int)で定義されているため
comH == '0'などの部分が「数値と文字の比較」となり評価されず、そのままif文を抜けています。
そのためresultが未定義扱い(一度も値が代入されていない)となり、そのエラーが出ています。

9行目の
comH = random.randint(0,2)

comH = str(random.randint(0,2))
にしてみてください。
    • good
    • 1
この回答へのお礼

早々のご回答、ありがとうございます。
「数値と文字の比較」ですね!
ご指摘頂いたように修正したら正常に動作しました。
最初に変数のデータ型を使用していないので、どの形で使われているのかを注意深く意識するように努めてみます。
この度は有難うございました!

お礼日時:2024/01/23 23:45

pythonはJavascriptとかと違って、文字列と数値が「等しい」と判定されることは決して無い。

    • good
    • 1
この回答へのお礼

ご回答、ありがとうございます!
文字列と数値を比較できない・・・そうですよね!
そもそも、そこがエラーの原因だとすら気が付きませんでした・・・。
変数の宣言(データの形式を指定?)を必要としないからこそ、いいかげんに認識していたのだと思います。
(当方、VBAは少々暑かったことが有るのですが、その時には逐一変数のデータ型を宣言していたので)
今後、同様のエラーが出た時には、変数の形式についても注意してみます。

お礼日時:2024/01/24 22:26

直接の問題は No.2 の回答のとおりですが、その背景として


if 条件により変数定義が有ったり無かったり不安定
があると思います。

以下のように書くことをお勧めします

案1) 冒頭で無難な値で変数定義をして後で上書きする
result = '判定不可'
if 条件A: result = '条件Aの値'
if 条件B: result = '条件Bの値'

案2) 想定外に備えて else を省略せずに変数定義
if 条件A:
_ result = '条件Aの値'
elif 条件B:
_ result = '条件Bの値'
else:
_ result = '判定不可'

案3) 変数定義を一か所だけにする
result = '条件Aの値' if 条件A else '条件Bの値' if 条件B else '判定不可'
    • good
    • 0
この回答へのお礼

今回は変数の定義が曖昧なのがいけなかったんですね。
resultを”判定不能”としておくのは思いつきませんでした。
変数に何らかのデータ(今回だと”判定不能”)を仮に入れておき、後から書き換えをするという考え、了解しました。
同じ結果を得るプログラムでも、多くの書き方が有るのは大変参考になります。
まだまだ初学者ですべてを理解できませんが、様々な選択肢として少しでも理解を深められたらと思います。

お礼日時:2024/01/24 22:21

こういう風に書く。



実装例:
https://www.ideone.com/BiiDtM
    • good
    • 0
この回答へのお礼

様々のご指導、ありがとうございます!
頂いたサンプル、まだまだ当方の理解の範疇を超えております。
より高度かつ上質なプログラムを見て、今後の学習に活用できたらと考えております。


「メッセージは本体から分けておく」について。
まだまだ知らない(未知の)書き方です。
特にカッコとかの使い方・・・。
今後、学習を深めつつ、理解できるように努めてみます。


「構造体、関数(?)の使い方」について。
defというのは、何らかの数値等を与え、その結果を出力する関数のように認識しております。
長々とプログラムを記載するのではなく、シンプルな「流れ」を踏まえて、要所で関数を用いると良いのだろうと思います。
可読性が高く、将来的な修正にも対応できるように最初から準備できると素晴らしいですね。

「じゃんけんのアルゴリズム」(my_hand - comH + 3) % 3)について。
この計算方法(アルゴリズム?)については、ネット上の情報でも把握しております。
同じ結果を出力するプログラムでも、様々な方法が有るのだと学びました。
スマートに、改変がしやすい、誰が見てもわかりやすい記載をするのが最上なんでしょうね。

お礼日時:2024/01/24 22:18

Pythonでは、 「変数=〜」を実行したら「変数」という「名前(name)」が「定義(define)」されます。


そうでなければ「定義されません(not defined)」

NameError: name 'result' is not defined
というエラーになるということは、 resultが定義されない(result=〜が実行されない)まま、resultを使おうとした、ということになります。

あいこで無い場合に result=〜を実行しない場合があるということになります。

教えてGooにはスペースすがまとめて消去されてしまう、というPythonには致命的な問題があります。
おそらくインデントを間違えていてあなたが思う判定アルゴリズムとは違うものになっているのではないか、と予想はできます。
が、肝心のインデントが消えてしまっている以上、判断はできません。
    • good
    • 0
この回答へのお礼

早々のご回答ありがとうございます。
確かに!インデントが消えていますね・・・。
「教えてGoo」の仕様ならばやむを得ないですね。
今後、ここで質問する時には気をつけます。
ご指摘、有難うございました!

お礼日時:2024/01/23 23:43

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報