プログラミング入門II
2025.05.28
関数 その1

Back to index page



  1. 本日の作業内容

  2. 前回の確認テストについて

    以下のような問題が出ています.提出前にエラー回避を行っておくことと,提出時にはきちんとファイル名を確認することを心がけてください.

    実行時エラー: 24_23 24_38 24_47

    間違ったファイルの提出: 24_28

  3. 前回の宿題について

    久しぶりに解答用紙を使用していない人が出てきました.ぼちぼち中盤を迎えて慣れてきたためか,不注意が原因と思われるものがあります.注意しましょう.

    解答用紙不使用: 24_55

    出力時番号間違い: 24_32

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

    set1 = set(random.sample(range(1, 101), 50))
    set2 = set(random.sample(range(1, 101), 50))
    

    set1 = set(random.randint(1, 100) for _ in range(50))
    set2 = set(random.randint(1, 100) for _ in range(50))
    

    上の2つは課題の条件である,まずリストを作成し,それを集合にするという手順を踏んでいません.

    print('A:', len(A), '--', list(A))
    print('B:', len(B), '--', list(B))
    print('C:', len(C), '--', list(C))
    print('D:', len(D), '--', list(D))
    

    only_1=set(lst1_1)-set(lst2_2)
    only_2=set(lst2_2)-set(lst1_1)
    both=set(lst1_1)&set(lst2_2)
    union=set(lst1_1)|set(lst2_2)
    
    print(f'A:{len(only_1)}--{only_1}')
    print(f'B:{len(only_2)}--{only_2}')
    print(f'C:{len(both)}--{both}')
    print(f'D:{len(union)}--{union}')
    

    上の2つは画面への出力時にアンパックしていないので,カッコつきの数値の列にになってしまいます.

    print(f'A: {len(set0-(set1|set2))} --',*set0-(set1|set2))
    print(f'B: {len(set1-set2)} --',*set1-set2)
    print(f'C: {len(set1&set2)} --',*set1&set2)
    print(f'D: {len(set2-set1)} --',*set2-set1)
    

    集合1と2の積集合(C の領域)の要素がソートされてないので,結果の表示は下のようになります.チェックが大変です.

    Set 1
    6 8 9 10 12 21 22 30 31 32 42 43 45 46 51 54 55 56 57 61 62 63 64 65 67 68 72 73 80 82 85 86 87 90 95 96 97
    
    Set 2
    3 7 9 11 12 16 17 19 22 23 25 26 28 29 31 34 38 39 41 51 58 59 61 62 63 69 71 75 77 80 82 83 84 88 89 90 92 93 95 97 98
    
    A: 35 -- 1 2 4 5 13 14 15 18 20 24 27 33 35 36 37 40 44 47 48 49 50 52 53 60 66 70 74 76 78 79 81 91 94 99 100
    B: 24 -- 6 8 10 21 30 32 42 43 45 46 54 55 56 57 64 65 67 68 72 73 85 86 87 96
    C: 13 -- 97 9 12 80 63 51 82 22 95 90 61 62 31
    D: 28 -- 3 7 11 16 17 19 23 25 26 28 29 34 38 39 41 58 59 69 71 75 77 83 84 88 89 92 93 98
    

  4. 前回の復習

    リストとは異るタプルや辞書,集合について学習しました.実際にそれらが有用な場面にならないと意義を理解するのは難かしいかと思います.今回実習する関数では複数の戻り値を受け取る際にタプルが使われていますので,関数の学習を通してさらに勉強していきましょう.

  5. 関数

    これまでプログラムの中で print() や randint() などの関数を使ってきましたが,そのように何かの一連の作業をさせる関数を今回は自分で作ってみることになります.自分で作るので,「ユーザ定義関数」と言います.関数の定義,引数仕様,戻り値などいくつか重要な項目がありますので,それらについて学習しましょう.

    1. 引数

      関数には引数が必要なものと不要なものがありますが,引数を呼び出し時に与えるときに,実際に与える引数を「実引数」,関数が受け取る引数を「仮引数」と言います.実引数と仮引数は変数名が違っていても,呼び出しの際の記述位置で把握しますので問題ありません.

    2. 複数の戻り値

      複数個の戻り値の場合にはタプルを使うのが基本と教科書の p.247 にあります.実際にこの後の演習問題で試してみましょう.

    3. 再帰

      関数を学習する際に必ず例題として出てくるのが「再帰」です.漸化式で表現できる反復処理を実行する際に使用されます.ただし,動作は遅いので,反復処理の代わりに使用するものではなく,あくまでも漸化式表現の処理の実行に使用します.

      教科書の p.250 の List 9-9 にある階乗計算を for 文のものと比較してみましょう.この程度の数値では体感的な差は無いと思いますが.

      import time
      
      def factorial(n):
          if n > 0:
              return n * factorial(n - 1)
          else:
              return 1
      
      start = time.time()
      
      n = 900
      
      print(f'The factorial of {n} is {factorial(n)}.')
      
      duration = time.time() - start
      
      print()
      print(f'The time needed to calculate: {duration} [s]')
      
      import time
      
      start = time.time()
      
      n = 900
      fact = 1
      
      for i in range(1,901):
          fact *= i
      
      print(f'The factorial of {n} is {fact}.')
      
      duration = time.time() - start
      
      print()
      print(f'The time needed to calculate: {duration} [s]')
      
      再帰版 for 文版

  6. 演習

    今回の演習問題です.

  7. 宿題

    いつものようにMoodleを利用します.授業当日の18:00から閲覧可能で,締切りは翌週月曜日の15:00です.

  8. 次回の予習範囲

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


目次ページに戻る