よちよちpython

独習 python/Qpython/Pydroid3/termux/Linux

【Python】whileとifで何か作ってみる

プログラミングでは、私のようなド素人であっても上級者の書いたものを写経いわゆるコピペするだけで、簡単にWebスクレイピングで画像をかき集め、更に画像処理し、深層学習で分析や分類といった高度な事が出来てしまう。
数学も物理もアルゴリズムも何も使っていない。カメラを買ってきて写すように、または模型店で買ったプラモデルのキットを組み立てるが如く上等な作品が出来てしまう。

ところが、いざ「プラ板と粘土とパテでモデルを作ってみろ」と言われたら、素人には全く手足がだせないのと同様にプログラミングも、算数も理科も社会も国語も、何でも、単純そうで基礎的なことほど実は難しいではないか。



ということで、作ろうとするものがことごとくエラーばかり吐くのでw、超初歩的なことに戻り、 whileifで何か作ってみる。



メニュー画面的なもの


ファミコンを起動するとスタート終了のメニュー画面が出る。
ターミナルを起動すると$>で入力待ちの状態になる。
そんなときにこれを使うだろう、知らんけど。
endを入力すると終了します。

while True:
    print("何か入力してください。\n")
    a = input(">>")
    print("入力された値:", a)
    print("値の型:",type(a))
    print("~~~~~~~~~~~~~~~~")
    
    if a == "end":
        print("終了します。")
        break
何か入力してください。

>>あ
入力された値: あ
値の型: <class 'str'>
~~~~~~~~~~~~~~~~
何か入力してください。

>>t
入力された値: t
値の型: <class 'str'>
~~~~~~~~~~~~~~~~
何か入力してください。

>>4
入力された値: 4
値の型: <class 'str'>
~~~~~~~~~~~~~~~~
何か入力してください。

>>%
入力された値: %
値の型: <class 'str'>
~~~~~~~~~~~~~~~~
何か入力してください。

>>end
入力された値: end
値の型: <class 'str'>
~~~~~~~~~~~~~~~~
終了します。

input()関数で入力した値は全てstr型になる。

  • 1:継続
  • 2:終了

というメニューを作って、入力で場合分けしたいとする。
このときを意識しないと思うように動かない。何しろPythonをあまり意識しない。変数の型を定義しなくとも書けるし動くからこその罠かな。

breakはループ文中に書く。出会うとループから抜ける。輪廻転生の解脱か



終了しないぽんこつプログラム


ifの合否判定で、input関数の入力値の型をintと照合してしまった為に終了しない例。

while True:
    print("###############")
    print("メニュー\n")
    print("1 : 継続")
    print("2 : 終了")   
    print("###############")
    print("メニュー番号を入力してね")
    num = input(">>")
    
    # 1なら継続
    if num == 1:
        print("継続します。")
        pass
    
    elif num == 2:
        print("終了します。")
        break
###############
メニュー

1 : 継続
2 : 終了
###############
メニュー番号を入力してね
>>1
###############
メニュー

1 : 継続
2 : 終了
###############
メニュー番号を入力してね
>>2
###############
メニュー

1 : 継続
2 : 終了
###############
メニュー番号を入力してね
>>なにー!?
###############
メニュー

1 : 継続
2 : 終了
###############
メニュー番号を入力してね



--------------------------------------------
KeyboardInterruptTraceback (most recent call last)

    ~/python3.7/lib/python3.7/site-packages/ipykernel/kernelbase.py in 
    
~~ 中略 ~~

KeyboardInterrupt: 

終了しないのでプログラムを無理やり止めた。
elifの行をelse:にしていたら、何を入力しても終了するコードになっていた。
inputstr型"1""2"とすればまともに動くはず…



passは何もしない。何もしないのだから書く必要もなさそうだが。涅槃か



何を入力しても終了するぽんこつプログラム


上のプログラムのelifelse:に変えただけ。

while True:
    print("###############")
    print("メニュー\n")
    print("1 : 継続")
    print("2 : 終了")   
    print("###############")
    print("メニュー番号を入力してね")
    num = input(">>")
    
    # 1なら継続
    if num == 1:
        print("継続します。")
        pass
    
    else:
        print("終了します。")
        break
###############
メニュー

1 : 継続
2 : 終了
###############
メニュー番号を入力してね
>>1
終了します。

継続するメニュー番号1を入力しても終了してしまった。反抗期でしょうか。



今度はまともに従うやつ


if文のところをstr型に変えた。ちゃんと動くはず…

while True:
    print("\n###############")
    print("メニュー\n")
    print("1 : 継続")
    print("2 : 終了")   
    print("###############")
    print("メニュー番号を入力してね")
    num = input(">>")
    
    # 1なら継続
    if num == "1":
        print("継続します。")
        pass
    
    elif num == "2":
        print("終了します。")
        break
###############
メニュー

1 : 継続
2 : 終了
###############
メニュー番号を入力してね
>>1
継続します。

###############
メニュー

1 : 継続
2 : 終了
###############
メニュー番号を入力してね
>>あ

###############
メニュー

1 : 継続
2 : 終了
###############
メニュー番号を入力してね
>>2
終了します。

メニューにない入力のは無視されてループに戻りました。
メニュー外の入力があったときの為にelse:を加えた方がコードを読む人にはよかろうか。



同じ入力を2回繰り返すと終了するコード


無駄にリストやカウント用の変数など作った。
2回入力するとリストがリセットされる。
入力の1度目と2度目の比較をして、等しければ終了する。

import sys

List = []
counter = 0

while True:
    # 入力
    print("何か入力してください。\n")
    a = input()
    
    # 入力内容の出力
    print("入力された値:", a)
    print("値の型:",type(a))
    List.append(a)
    print("入力リスト:",List)
    
    # カウンター
    counter = counter + 1
    print("カウンター:", counter)
    print("###############")
    
    # リストの要素数が2個なら
    if len(List) == 2:
        
        # 等しければ終了
        if List[0] == List[1] :
            print("終了")
            
            sys.exit()
        
        # 違えばループに戻る
        else:
            List = []
            continue
            
何か入力してください。

あ
入力された値: あ
値の型: <class 'str'>
入力リスト: ['あ']
カウンター: 1
###############
何か入力してください。

h
入力された値: h
値の型: <class 'str'>
入力リスト: ['あ', 'h']
カウンター: 2
###############
何か入力してください。

5
入力された値: 5
値の型: <class 'str'>
入力リスト: ['5']
カウンター: 3
###############
何か入力してください。

$
入力された値: $
値の型: <class 'str'>
入力リスト: ['5', '$']
カウンター: 4
###############
何か入力してください。

1
入力された値: 1
値の型: <class 'str'>
入力リスト: ['1']
カウンター: 5
###############
何か入力してください。

1
入力された値: 1
値の型: <class 'str'>
入力リスト: ['1', '1']
カウンター: 6
###############
終了



An exception has occurred, use %tb to see the full traceback.


SystemExit

パスワードを2回入力させるとか、3回入力ミスると暫くアクセスできなくなるとかいった機能はこんな風になっているんだろうか。

continueはループ文の中に書く。continueに出会うとその後の予定をすっ飛ばして、ループの続きの先頭に戻る。



2個のサイコロがゾロ目になれば終了するやつ


import random
import sys

counter = 0
while True:
    dice1 = random.randrange(1,7,1) 
    dice2 = random.randrange(1,7,1)
    
    print("【サイコロ1】",dice1)
    print("【サイコロ2】",dice2)
    
    counter += 1
    print("《カウンター》",counter)
    print("###############")
    
    if dice1 == dice2:
        print("終了します。")
        sys.exit()
    else:
        pass
        
【サイコロ1】 4
【サイコロ2】 2
《カウンター》 1
###############
【サイコロ1】 2
【サイコロ2】 3
《カウンター》 2
###############
【サイコロ1】 1
【サイコロ2】 4
《カウンター》 3
###############
【サイコロ1】 6
【サイコロ2】 4
《カウンター》 4
###############
【サイコロ1】 3
【サイコロ2】 3
《カウンター》 5
###############
終了します。



An exception has occurred, use %tb to see the full traceback.


SystemExit

randomを使っているので、試行するたびに出目が変わります。



2個のサイコロがゾロ目になる回数をカウントし、それを指定回数繰り返すやつ


turn_times=10の数字を変えると試行回数が変えられる。
1万回でも10万回でもできるが、出力が膨大に増えるのでprint()コメントアウトして実行する。

import random
import sys

counter = 0
S_counter = []
S_List = []
turn_times = 10
while True:
    if len(S_counter) < turn_times:
        dice1 = random.randrange(1,7,1) 
        dice2 = random.randrange(1,7,1)
    
        print("【サイコロ1】",dice1)
        print("【サイコロ2】",dice2)
    
        counter += 1
        print("《カウンター》",counter)
        print("###############")
    
        if dice1 == dice2:
            print("揃いました。")
            
            S_counter.append(counter)
            counter = 0 # カウンターリセット
            print(S_counter)
            print("~~~~~~~~~~~~~~~~~~~~")
            
        else:
            pass
        
    else:
        print("{}回試行しましたので終了します。".format(turn_times))       
        print(S_counter)        
        sys.exit()
【サイコロ1】 3
【サイコロ2】 6
《カウンター》 1
###############
【サイコロ1】 1
【サイコロ2】 5
《カウンター》 2
###############
【サイコロ1】 2
【サイコロ2】 4
《カウンター》 3
###############
【サイコロ1】 3
【サイコロ2】 5
《カウンター》 4
###############
【サイコロ1】 1
【サイコロ2】 5
《カウンター》 5
###############
【サイコロ1】 5
【サイコロ2】 1
《カウンター》 6
###############
【サイコロ1】 1
【サイコロ2】 4
《カウンター》 7
###############
【サイコロ1】 2
【サイコロ2】 2
《カウンター》 8
###############
揃いました。
[8]
~~~~~~~~~~~~~~~~~~~~
【サイコロ1】 4
【サイコロ2】 5
《カウンター》 1
###############
【サイコロ1】 6
【サイコロ2】 2
《カウンター》 2
###############
【サイコロ1】 1
【サイコロ2】 6
《カウンター》 3
###############
【サイコロ1】 3
【サイコロ2】 2
《カウンター》 4
###############
【サイコロ1】 2
【サイコロ2】 4
《カウンター》 5
###############
【サイコロ1】 3
【サイコロ2】 5
《カウンター》 6
###############
【サイコロ1】 2
【サイコロ2】 1
《カウンター》 7
###############
【サイコロ1】 4
【サイコロ2】 4
《カウンター》 8
###############
揃いました。
[8, 8]
~~~~~~~~~~~~~~~~~~~~
【サイコロ1】 3
【サイコロ2】 3
《カウンター》 1
###############
揃いました。
[8, 8, 1]
~~~~~~~~~~~~~~~~~~~~
【サイコロ1】 4
【サイコロ2】 2
《カウンター》 1
###############
【サイコロ1】 4
【サイコロ2】 4
《カウンター》 2
###############
揃いました。
[8, 8, 1, 2]
~~~~~~~~~~~~~~~~~~~~
【サイコロ1】 1
【サイコロ2】 1
《カウンター》 1
###############
揃いました。
[8, 8, 1, 2, 1]
~~~~~~~~~~~~~~~~~~~~
【サイコロ1】 3
【サイコロ2】 4
《カウンター》 1
###############
【サイコロ1】 4
【サイコロ2】 4
《カウンター》 2
###############
揃いました。
[8, 8, 1, 2, 1, 2]
~~~~~~~~~~~~~~~~~~~~
【サイコロ1】 4
【サイコロ2】 5
《カウンター》 1
###############
【サイコロ1】 5
【サイコロ2】 2
《カウンター》 2
###############
【サイコロ1】 6
【サイコロ2】 4
《カウンター》 3
###############
【サイコロ1】 2
【サイコロ2】 3
《カウンター》 4
###############
【サイコロ1】 5
【サイコロ2】 3
《カウンター》 5
###############
【サイコロ1】 3
【サイコロ2】 5
《カウンター》 6
###############
【サイコロ1】 1
【サイコロ2】 2
《カウンター》 7
###############
【サイコロ1】 5
【サイコロ2】 3
《カウンター》 8
###############
【サイコロ1】 3
【サイコロ2】 1
《カウンター》 9
###############
【サイコロ1】 1
【サイコロ2】 4
《カウンター》 10
###############
【サイコロ1】 5
【サイコロ2】 1
《カウンター》 11
###############
【サイコロ1】 5
【サイコロ2】 2
《カウンター》 12
###############
【サイコロ1】 2
【サイコロ2】 1
《カウンター》 13
###############
【サイコロ1】 6
【サイコロ2】 5
《カウンター》 14
###############
【サイコロ1】 2
【サイコロ2】 5
《カウンター》 15
###############
【サイコロ1】 4
【サイコロ2】 6
《カウンター》 16
###############
【サイコロ1】 1
【サイコロ2】 5
《カウンター》 17
###############
【サイコロ1】 4
【サイコロ2】 6
《カウンター》 18
###############
【サイコロ1】 6
【サイコロ2】 2
《カウンター》 19
###############
【サイコロ1】 4
【サイコロ2】 4
《カウンター》 20
###############
揃いました。
[8, 8, 1, 2, 1, 2, 20]
~~~~~~~~~~~~~~~~~~~~
【サイコロ1】 6
【サイコロ2】 5
《カウンター》 1
###############
【サイコロ1】 4
【サイコロ2】 4
《カウンター》 2
###############
揃いました。
[8, 8, 1, 2, 1, 2, 20, 2]
~~~~~~~~~~~~~~~~~~~~
【サイコロ1】 4
【サイコロ2】 3
《カウンター》 1
###############
【サイコロ1】 1
【サイコロ2】 5
《カウンター》 2
###############
【サイコロ1】 1
【サイコロ2】 1
《カウンター》 3
###############
揃いました。
[8, 8, 1, 2, 1, 2, 20, 2, 3]
~~~~~~~~~~~~~~~~~~~~
【サイコロ1】 3
【サイコロ2】 2
《カウンター》 1
###############
【サイコロ1】 1
【サイコロ2】 6
《カウンター》 2
###############
【サイコロ1】 2
【サイコロ2】 3
《カウンター》 3
###############
【サイコロ1】 2
【サイコロ2】 6
《カウンター》 4
###############
【サイコロ1】 4
【サイコロ2】 2
《カウンター》 5
###############
【サイコロ1】 4
【サイコロ2】 2
《カウンター》 6
###############
【サイコロ1】 3
【サイコロ2】 6
《カウンター》 7
###############
【サイコロ1】 5
【サイコロ2】 6
《カウンター》 8
###############
【サイコロ1】 5
【サイコロ2】 1
《カウンター》 9
###############
【サイコロ1】 1
【サイコロ2】 6
《カウンター》 10
###############
【サイコロ1】 4
【サイコロ2】 3
《カウンター》 11
###############
【サイコロ1】 6
【サイコロ2】 3
《カウンター》 12
###############
【サイコロ1】 1
【サイコロ2】 6
《カウンター》 13
###############
【サイコロ1】 2
【サイコロ2】 2
《カウンター》 14
###############
揃いました。
[8, 8, 1, 2, 1, 2, 20, 2, 3, 14]
~~~~~~~~~~~~~~~~~~~~
10回試行しましたので終了します。
[8, 8, 1, 2, 1, 2, 20, 2, 3, 14]



An exception has occurred, use %tb to see the full traceback.


SystemExit

備考


サイコロのゾロ目が出る確率
https://mathwords.net/zorome#n



サイコロ2個を振ったときのゾロ目のでる確率は約17%だそうです。そうなっているかな?



今回はこのへんで。