プログラミング入門II
2024.05.08
リスト その3

Back to index page



  1. 本日の作業内容

  2. 前回の宿題について

    今回は残念ながら実行時にエラーが出るものがありました.

    実行時エラー: b2363

    原因は以前にも説明した,2バイト文字コード(いわゆる全角文字)のソースへの混入です.ただ,エラーには自分で気づくはずなので,そこは自分で対処してから出してください.

    while True:
        i +=1
        random.shuffle(lst1)
        print(f'{i:3}: ',end='')
        print(*lst1)
        if lst == lst1:
            break
    else:
        print()
    

    上のソースで if の後のスペースがちょっと広いことに気づけばそれでいいのですが,別にそこで気づかなくても実行すればわかります.以下に例を示しますので,今後の参考にしてください.


    図1 ソース

    上のサンプルは変数 i に1を代入する操作ですが,観てわかるように i と = の間に日本語コードのスペースが入っています.これを保存して実行すると,以下のようにちゃんとエラーを出してくれます.


    図2 警告

    簡単な英語なのでこれくらいは辞書なしで理解してほしいですが,無効な印字不能の文字ありと教えてくれています.


    図3 問題部分のハイライト

    さらには元のソースコードのどこに問題があるのかを上のように具体的にハイライトしてくれますので,見つけるのは簡単でしょう.

    他には学生番号の出力に関連して以下のように問題がある人がいました.注意しましょう.

    出力時番号間違い: b2316

    学生番号出力なし: b2353

    以下は例によって問題のあるプログラムの例です.参考にしてください.

        if lst2 == [1,2,3,4]:
    

    元々 lst というリストを用意して,それと一致するかどうかを if で判定するのだから,わざわざ上のようにリストの要素を一つ一つ記述するのは無駄です.

    while lst != ranlst:
        num += 1
        print(f'{num:2}: ', *ranlst)
        random.shuffle(ranlst)
    else:
        print(f'{num + 1}: ', *ranlst)
    

    一致するまで100回以上シャッフルすることもあるので,2桁では文字幅の確保が十分ではありません.

    lst = [1, 2, 3, 4]
    lst1 = copy.copy(lst)
    i = 0
    print(f'{i:3}: ',end = '')
    print(*lst)
    while True:
        i += 1
        random.shuffle(lst1)
        print(f'{i:3}; ', end = '')
        print(*lst)
        if lst == lst1:
            break
    else:
        print()
    

    区切り記号がコロンでなくセミコロンになっているのも問題ですが,それよりもシャッフルしたリスト lst1 ではなく,元のリストを出力しているので,下の出力例のように毎回同じものが出ます.自分でおかしいことはわかるはずなので,何とかしてから提出しましょう.

    0: 1 2 3 4
    1; 1 2 3 4
    2; 1 2 3 4
    3; 1 2 3 4
    4; 1 2 3 4
    5; 1 2 3 4
    6; 1 2 3 4
    7; 1 2 3 4
    8; 1 2 3 4
    9; 1 2 3 4
    

    lst = [1, 2, 3, 4]
    lst2 = copy.copy(lst)
    random.shuffle(lst2)
    kaisu = 0
    
    while lst != lst2:
        kaisu += 1
        print(f'{kaisu:3.0f}: ', *lst2)
        random.shuffle(lst2)
    else:
        kaisu += 1
        print(f'{kaisu:3.0f}: ', *lst2)
    

    シャッフル作業を記述するのはソースの中で1回で十分です.

    while not lst1 == lst2:
         c = c+1
         lst2 = copy.copy(lst1)
         random.shuffle(lst2)
         print(f'{c:3}: ', *lst2)
    

    何人かで見られたのが上のような処理ですが,反復処理の中でコピーするのはおかしいでしょう.毎回元のリストをコピーして1回だけシャッフルするという処理です.

    print(f'{lst[0]} {lst[1]} {lst[2]} {lst[3]}')
    

    もうちょっと簡単なリスト要素の表示法を前回やりましたね.

    while True:
        if lst2 == lst:
            print(f'{i:3}: ',end='')
            print(*lst2)
            break
        else:
            print(f'{i:3}: ',end='')
            print(*lst2)
            i += 1
            random.shuffle(lst2)
    

    条件分岐において,赤字にした部分は if 節の式が真でも偽でも実行されます.だったら条件分岐の式に入れる必要はありません.

    さて,以下の2つは困ったソースです.正しく動作はします.ただし,自分でプログラムしていません.企業などで複数人でプロジェクトを進める際には,関数やモジュールを活用し,お互いの開発部分をマージして最終的なソースにすることは重要でしょう.ただ,今現在は,単純な処理を自分で書けるか,そのための練習をしています.以下のようなソースを書けるのならプログラミング 「入門」の授業を履修する意味はありません.単位が欲しけりゃ上げますので,申告してください.

    import random
    import copy
    
    print('Student number: s******')
    print('')
    
    import random
    
    def random_list():
        original_list = [1, 2, 3, 4]
        current_list = original_list[:] 
        count = 0
       
        print(f"{count:3}:  {current_list[0]} {current_list[1]} {current_list[2]} {current_list[3]}")
        
        while True:
            random.shuffle(current_list)
            count += 1
            print(f"{count:3}:  {current_list[0]} {current_list[1]} {current_list[2]} {current_list[3]}")
            
            if current_list == original_list:
                break
    
    random_list()
    

    import random
    import copy
    
    print('Student number: s******')
    print('')
    
    import random
    
    def main():
        original_list = [1, 2, 3, 4]
        shallow_list = original_list.copy()
        
        print_list(0, shallow_list)
        
        count = 1
        while True:
            random.shuffle(shallow_list)
            print_list(count, shallow_list)
            count += 1
            
        
            if shallow_list == original_list:
                break
    
    def print_list(count, lst):
        print("{:3d}:".format(count), end=" ")
        for i in lst:
            print(i , end=" ")
        print()
    
    if __name__ == "__main__":
        main()
    

    共通しているのは,どっかから丸ごとソースを持ってきているので,import random が重複しているところですね.自分で書けば,普通はそうはなりませんよね.
  3. 前回の復習

    リストについて,特に内包表記を用いたリストの生成や作成したリストの要素の取り扱いについて学習しました.インデックスで要素にアクセスすることで,各種の操作と反復処理が関係していることがわかったかと思います.今後もリストは使用しますので,引き続き活用していきましょう.

  4. リスト

    今回も引き続きリストです.これまでに学習した内容で実現可能な,しかし,より高度で実用的(?)なプログラムに挑戦します.頑張りましょう.

  5. 演習

    今回の演習問題です.

  6. 宿題

    宿題はいつものようにレポート提出システムを使用します.本日の18:00以降に閲覧可能となりますの.来週の水曜日はこの授業がありませんので,提出締め切りは21日(火)の10:00ですので,お間違いなく.

  7. 次回の予習範囲

    次回はリスト以外の配列的なものであるタプル,辞書,集合です.教科書の p.203-240 です.予習をお願いします.


目次ページに戻る