もちこに勉強部屋(仮)

プログラミング初心者がPython × Streamlitでアプリ開発目指して学習過程を記録したりライティングの勉強したりする部屋

プログラミング初心者がChatGPTと一緒にPython独学する:⑤四則演算アプリの作成(つづき)

前回に引き続き、GPTが出してくれたコードを丸々コピペして作った四則演算アプリの内容を確認していきます。

はてなブログ無料民は頭に画像をつけないと「続きを読む」が有効にならないみたいなのですが、癖のGPTに告白してスルーされたスクショくらいしかなかった。

本当になんの関係もないスクショ

本当に一切の関係もないのですが、GPTの人間との距離の測り方と安全設計について「難しい課題なんだろうな~おもしろ~い」って最近思ってます。(日常の感想すぎる)

GPTについての気づきも今後いろいろ書けたらいいなって思ってます。思ってるだけ。

前回のおさらい

足し算・引き算・掛け算・割り算の4つの選択肢を作り、それによって計算の結果が分岐する四則演算アプリを作っていました。

mochiconi.hatenablog.com

完成したアプリ自体はシンプルなものでありながら、初心者には内容が盛りだくさんすぎてまとめきれなかったため、取りこぼした以下の要素を確認していきます。

  • st.error( )
  • # 結果表示(割り算の0除算以外)の中身

これだけならすぐまとめ終わるかなと思ったら全然そんなことなかった。
普通に苦戦しました。

四則演算アプリのコード詳細

さっそく取りこぼした2つの要素を見ていきましょう。

1. st.error( )

これはわかりやすく、エラーメッセージを表示させてますよね。

    elif op == "÷":
        if b == 0:
            st.error("0で割ることはできません!💥")

上のコードの結果はこうなります。↓

赤字でエラーメッセージを表示している

elif と if で指定した条件式に合致すると、赤い背景に赤い文字でメッセージが表示されます。

GPTいわく、

st.error は何をしていないか(重要)

ここ、勘違いしやすいから先に言う。

  • プログラムを止める 
  • エラーを発生させる 
  • if を抜ける 

st.errorは上記をしていない。
ただのエラーっぽい「表示」。

st.write("エラーです")

と同じレベルで、画面に文字を出してるだけ。

 

st.write と st.error の違いは

  • st.write
    →標準テキストとして表示される
  • st.error
    →エラーっぽいUI(赤字・赤背景)で表示される

のみだそうです。

Streamlitのメッセージ系コード
  • st.error
    /エラー・失敗
  • st.success
    /正常・成功
  • st.warning
    /注意・警告
  • st.info
    /補足・情報

…………
……つまり、実際に「エラーかどうか」は関係ないってこと?

そう。
st.error は「システムのエラー」じゃなくて、ただの表示スタイル。

「じゃあ、本当に処理を止めたいときはどうするの?」
……が知りたいなら、最小限だけ教える。
深入りはしない。

なんと。

というわけで、最小限だけ教えてもらいました。

「本当に処理を止めたい」ときの基本3パターン(最小限)

「これより下は実行しない」という意味の3パターンを、見るだけ。今回は深掘りしません!!

  • return
    関数の中でのみ使う。関数の外の処理は続く。
  • st.stop( )
    →Streamlit専用。とりあえず全部止まる。
  • raise Exception
    →エラー履歴が表示されてプログラムを本当に落とす。
     「想定外です。想定外を無視して進むくらいなら、死にます」って感じ。

はい。

関数ってなに!?!?
履修前の言葉をさも知っていて当然かのように出すんじゃないよ。

関数についてはまたの機会に

いや、知っていて当然なんだっけ……? と思っておそるおそる聞いたらしっかり知らない概念が飛び出してきました。今回は割愛します。 

そんなわけで、ニセエラーの st.error( ) と本当のアプリエラーについて(この理解が合ってるかどうかも今は不明)は、以上。

2. # 結果表示(割り算の0除算以外)の中身

中身はこんな感じでした。

if op != "÷" or b != 0:
    st.write("結果:", result)

ここが結構……
「???」になるところがあったので、記録を書くまでに時間がかかってしまいました。

これはどういう意味? とGPTに聞いてみると↓

「割り算で、かつ、b が 0 のとき以外は、結果を表示する」って意味。

表示しないのは、「÷ を選んでいて、b が 0 のとき」の1ケースだけ。
それ以外は全部表示するって書いてある。

はい、そんな感じに見えます。

 a != b → a ≠ b ってことでしたね。

「いや知らん」という方はこの記事のまとめに比較コード一覧を置いているのでご参照ください。

or と and の使い分け

で、こちらがわたしを大混乱させたGPTの言葉。

or は、
どちらか一方でも True なら True

だから「÷ かつ 0」だけが弾かれる。

たとえば論理を逆にして、

if not (op == "÷" and b == 0):
    st.write("結果:", result)

こういう別の書き方もできる。

 

???

意味わかんなくなっちゃった。

  • or もあるし、 and もある。
  • or は「どちらか一方でもTrueならTrue」。
  • and は「どちらもTrueならTrue」。
  • if not ( ) は、どうやら「条件式に対してFalseならTrue」という意味っぽい。

ここまでは汲み取れた。情報量が多すぎる。

でも、

if op != "÷" or b != 0

↑これは or を使ってるのに、
「割り算で、かつ、b が 0 のとき以外は~」とは……?

「かつ」なら「and」じゃないの……???

わたしが考えたのはこれ↓

if op != "÷" and b != 0:
    st.write("結果:", result)

※正しくないコードなので覚えなくてよし

でも、これではダメだそうな。

op="÷"以外の b=0 だったときを想定していなかった

わたしの考えたコードは
割り算じゃなくて、かつ、b が 0 じゃないときは、結果を表示する

つまり、足し算だろうが引き算だろうが掛け算だろうが
b が 0 のときは結果が表示されなくなってしまいます。

if op != "÷" or b != 0 の直訳

ここで、もう一度最初のコードを見てみましょう。(3回目)

if op != "÷" or b != 0

これを、自然な日本語訳にすると確かに
「割り算で、かつ、b が 0 のとき以外は、結果を表示する」。

だけど、ちゃんと読み直すと
「割り算じゃないとき(+/-/×)、または、
『割り算であっても』
bが0じゃないときは、結果を表示する」

おお……

まず、
or の左右は決して繋がっているわけではないんですね。

or の前の op != "÷" 「割り算じゃない」という意味ですが、
or の後ろの b != 0 はもう割り算だろうが割り算じゃなかろうが関係ない。
「とにかく b が 0 じゃないとき」という意味だ。

そして、
完全にGPTのミスリードに引っかかっていました。

「かつ」という接続詞から頭が「and」に引っ張られていました。
結果を簡潔に述べた日本語訳では理解が不十分になりますね。

ひとつひとつの要素を分解することでやっと意味がわかるんですね……

…………

疲れました。

まとめ

1. 比較コード一覧

if の条件式に使える比較コードは以下の通り。

  • x == 0 → 等しい
    ※ x = 0 は比較ではなく代入のため、条件式には使用不可。
  • x != 0 → 等しくない
  • x > 0    → 0より大きい
  • x < 0    → 0より小さい
  • x >= 0   → 0以上
  • x <= 0   → 0以下

2. st.selectbox( )

セレクトボックス(=ドロップダウンリスト)を作成する。

st.selectbox("△△△", ["+", "-", "×", "÷"])

→ "△△△"はボックスの上にラベルとして表示される。

  [ ]内で選択肢を設定できる。
  例の場合だと「+」「-」「×」「÷」の
  4つの選択肢がドロップダウンリストに表示される。

3. else/elif

どちらも直近の if 条件に対しての False の場合の処理を記述する。

else 
→ if の条件に対して False の場合の処理(True/Falseのみの分岐で使用)

if ○○○ : ●●●
else : △△△
→ ○○○が True のとき●●●し、False のとき△△△する。

elif(= else + if)
→ if の条件に対してFalse だった場合、さらに確認する条件(複数分岐で使用)

if ○○○ : ●●●
elif □□□ : ■■■
else : ×××
→ ○○○が True のとき、●●●する。
  ○○○が False 、□□□が True のとき、■■■する。
  ○○○が False 、□□□が False のとき、×××する。

4. st.error( )

エラーっぽいUIでテキストを表示する。

st.error("△△△")
→ 赤字・赤背景で"△△△"と表示される。

あくまで表示スタイルであり、エラーとは無関係。

5. 初心者は条件式を直訳しようね

これはコードの意味や詳細というより、

「実際の挙動の簡潔な説明」≠「コードの直訳」

という……わたしが「???」になった部分ですね。

  1. 「Aではない または Bではない」はOK

  2. 「A かつ B」はNG

 → 1 と 2 どちらにせよ、

  • 「AでもBでもない」
  • 「AだけどBではない」
  • 「AではないけどB」

 は、全部OK

このように、記述の仕方が違っても結果的には同じになる場合があります。

※この現象には「ド・モルガンの法則」なる素敵な名前がついているそうな。

経験者の方であれば当たり前だろって感じだと思うのですが、初心者すぎて数日間混乱しました。
というか、経験者の方はわたしの理解が間違えている箇所がありましたらぜひご指摘いただけましたら嬉しいです。

 

「関数」とか「エラー処理」とか、「それはまだいい!」ということも芋づる式で出てきてしまいましたが、一旦埋め直してまた登場したときに改めて覚えることにします。

今はまだいい。

では、また次回。