プログラミング入門II
2024.05.22
タプル,辞書,集合

Back to index page



  1. 本日の作業内容

  2. 前回の宿題について

    基本的にはほとんどの人が問題なくできていました.安心しました.ちょっとしたミスには以下のようなものがありました.

    解答用紙番号間違い: b2316

    末尾のハイフンラインなし: b2335

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

    まずは,以下のように表示が適切でないものがそこそこ見られました.

    Day 269 of this year is Wednesday ,25 of September
    Day 42 of this year is Sunday , 11 of February.
    Day 166 of this year is Friday,14 of June
    Day120 of this year is Monday,29 of April.
    

    昨年度のプログラミング入門Iの時から言っているのですが,この授業はほんのちょっとだけ英語の学習も含んでいます.英語などのヨーロッパ系の言語はアルファベットという表音文字をスペースで区切る分かち書きで文を構成します.スペースは非常に重要です.また,句読点の . と , はその右側にスペースを入れるのが基本です.そこんとこ,今後は気をつけてください.

    print(f'Day 365 of this year is {week[w]}, {d} of {month[i]}.')
    

    以前にも別のケースで指摘した問題が再度出てきました.課題の実行例の Day 365 というのは乱数で365日目が出たらその日は12月30日だよ,ということを示すサンプルです.なんで,ちゃんと読まないかなあ?

    最近は映画などでも重要な事案が発生したときなんかは,その何日目ということで Day 1 とか使っていると思いますが.

    month = ['Jmuary', 'February', 'March', 'April,' 'May',\
             'June', 'July', 'August', 'September',\
             'October', 'November', 'December']
    

    こちらで張り付けるだけでよいリストを用意していたのに,なんでいじるかなあ?しかも,1月は綴りが間違っているし,4月と5月のところはリストの要素区切りの , を間違えて文字列の中に入れてしまったので,以下の実行例のように,2つの文字列が続けて出力されます.さらに,リストの要素数が1個減っちゃったので,12月を参照するときにはレンジエラーが発生します.やはり,自分で何度も実行したり,数値を意図的に入れたりして,きちんと動作するかを確認するようにしてください.

    Day 119 of this year is Sunday, 28 of April,May
    

    month = ['january', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
    

    こっちもリストを用意してあるのに,自分で入れて間違えてるし.1月が小文字で始まっていますよ

    week = ['Sunday','Monday','Thuesday','Wedesday',\
            'Thursday','Friday','Saturday']
    

    上のものもまた曜日のリストで間違っているし.火曜と水曜の綴り,ちゃんとチェックしようよ.

    total = 0
    for i in range(0, 12):
        total += (days[i])
        if num > total and num - total < days[i]:
            print(f'{num - total}',end=' ')
            print(month[i + 1])
            break
    else:
        print()
    

    さて,上のものは if 文の式の比較演算子に=が無いので,動作がおかしくなります.例えば,乱数で num が 31 になったとすると,左側の条件式は偽なので,for 文による反復処理を最後までやっても両方の条件が真になるときが無いので,print を実行しません.これも,自分で適当な数を入れてみて,ちゃんと動作するかの確認が不十分でした.

    day = random.randint(1, 366)
    
    start_weekday_index = (week.index('Monday') - (365 % 7)) % 7
    
    month_index = 0
    
    while day > days[month_index]:
        day = days[month_index]
        month_index += 1
    
    weekday_index = (start_weekday_index + (day - 1)) % 7
    print(f'Day {day} of this year is {month[month_index]} {day}, {week[weekday_index]}')
    

    上の例では,乱数により変数 day に日数を代入したものの, while 文の2行目で day に各月の日数を代入してしまっているので,ちゃんと何日目かを保存していません.そして,2月の 29 を代入した後,3月が31日あるので,そこで必ず while 文の条件式が偽になり,while 文が終わります.そのため,下の実行例のように,必ず Day 29 になり,月が3月になります.これも自分で実行しておかしいことはわかるでしょうから,対処してください.

    Day 29 of this year is March 29, Sunday
    

    最後の2つは絶対やっちゃダメ!なやつです.ちゃんと考えましょう.

    if 1<=num<=31:
        print(f'{num} of {month[0]}')
    elif 32<=num<=60:
        print(f'{num-31} of {month[1]}')
    elif 61<=num<=91:
        print(f'{num-60} of {month[2]}')
    elif 92<=num<=121:
        print(f'{num-91} of {month[3]}')
    elif 122<=num<=152:
        print(f'{num-121} of {month[4]}')
    elif 153<=num<=182:
        print(f'{num-152} of {month[5]}')
    elif 183<=num<=213:
        print(f'{num-182} of {month[6]}')
    elif 214<=num<=244:
        print(f'{num-213} of {month[7]}')
    elif 245<=num<=274:
        print(f'{num-244} of {month[8]}')
    elif 275<=num<=305:
        print(f'{num-274} of {month[9]}')
    elif 306<=num<=335:
        print(f'{num-305} of {month[10]}')
    else:
        print(f'{num-335} of {month[11]}')
    

    if day_num % 7 == 0:
        print(f'{week[0]},',end='')
        
    elif day_num % 7 == 1:
        print(f'{week[1]},',end='')
        
    elif day_num % 7 == 2:
        print(f'{week[2]},',end='')
        
    elif day_num % 7 == 3:
        print(f'{week[3]},',end='')
        
    elif day_num % 7 == 4:
        print(f'{week[4]},',end='')
        
    elif day_num % 7 == 5:
        print(f'{week[5]},',end='')
        
    else:
        print(f'{week[6]},',end='')
    

  3. 前回の復習

    リストを使った実用的な処理を前回は考えました.ちょっと難しいものが多かったのですが,実際に自分で何か処理を考えるときはたいてい厄介な処理に取り組むことになりますので,その辺り慣れておくことも必要じゃないでしょうか.

  4. タプル

    今回扱うのは,タプル,辞書,集合というリストとはまた異るオブジェクトです.新しい言語では,だいたい似たようなものが用意されています.何故かというと,データを扱う際に便利になるからで,Python は諸般の事情によりデータ処理の目的で使用されることが多くなっていますので,扱うデータの種類によってそれぞれ便利なものが準備されています.それらを順に見ていきましょう.

    まずタプルですが,数学では「複数の構成要素からなる組を総称する一般的な概念」と Wikipedia には書いてあります.では,リストと同じようなものかというと,見かけはほぼ同じですが,大きな違いが教科書にも書かれている「タプルは要素の変更ができない」ということです.別の言い方をすると,要素を変更する必要の無い場合には,リストよりタプルを使うべきということです.間違って中身を変えてしまったりする危険性がなくなります.

    たとえば,前回使用したじゃんけんやトランプなどで特定の文字列をリストで用意することで,if 文を使用しなくても種々の操作ができましたが,中身を変更することが無いので,実はタプルとして用意する方が適切です.今後は,変更の必要がなければタプルで準備することになります.

  5. 辞書

    辞書とは,教科書にもあるように数値としてのインデックスではなく名前でアクセスしたい場合に使用するオブジェクトです.リストやタプルは for 文などの反復処理と組み合わせてインデックスを利用して要素にアクセスするものですが,辞書は使い方が違います.おそらくこの授業で役に立つようなプログラムは作らないと思いますが,実際にユーザが画面を操作するようなものを作るのであれば,重要になります.他の言語でも「ハッシュ」などとして用意されています.

    例えば,中国地方の都道府県を選択してそれに関連した値を参照したいとき,リストなどでは番号を振って,数字で関連付けさせますが,辞書を使うとそのような数字に変換することなく,名前のままで紐づけできますので,ボタンのラベルなどと合わせると直感的に関連付けができたりします.

  6. 集合

    リストやタプルでは要素の値に同じものがあっても構いません.ただ,事情によっては重複を避けたい場合もあります.そこで用意されているのがこの「集合」で,リストから重複を無くすような処理に使ったりできます.

  7. 演習

    今回の演習問題です.

  8. 宿題

    いつものようにレポート提出システムを利用します.授業当日の18:00から閲覧可能で,締切りは翌週月曜日の10:00です.

  9. 次回の予習範囲

    次回は教科書のp.240-265の範囲を学習しますので,予習をしてきてください.


目次ページに戻る