プログラミング入門II
2025.06.04
関数 その2
今回上のような階乗計算の関数が多く出てきました.教科書 p.250 の List 9-9 や私の Web テキストで紹介した方法と違うものです.別に動作がおかしいわけでは無いのですが,なぜ手元にあるものを参考にしないで,検索結果のようなものを使用するのか.学習したことを積み上げていくことでプログラミング技術を習得していくというプロセスを無視していますね.
print(f'10: {total(10)}') print(f'20: {total(20)}') print(f'30: {total(30)}') print(f'40: {total(40)}') print(f'50: {total(50)}') |
プログラミングで重要なことは反復処理を活用し,処理を自動化することです.自分が手作業で無駄な文字入力をするのはやめましょう.
def factorial(n): if n == 0 or n == 1: return 1 return n * factorial(n - 1) def power(x, n): if n == 0: return 1 return x * power(x, n - 1) def exp_recursive(x, n): if n == 0: return 1 return power(x, n) / factorial(n) + exp_recursive(x, n - 1) x = random.randint(5, 10) #x=8 true_exp = exp_recursive(x, 100) |
べき乗計算までは要求していませんでしたけど.
def approximation(x,n,p): if(p<=n): return (x**p)/math.factorial(p) + approximation(x,n,p+1) else: return 0 |
def exp_recursive(x, n): if n == 0: return 1 else: return exp_recursive(x, n - 1) + (x ** n) / math.factorial(n) |
階乗計算も再帰で作るように指定していましたが?
def euler(x,tm): result=0 for n in range(tm+1): result +=(x**n)/ kai(n) return result |
再帰という指定を無視していますね.
さて,最後は久しぶりの絶対にやっちゃダメ!なやつです.何度も言いますが,こういう面倒な処理を課題として課すことは絶対にありません!
x = random.randint(5,10) lst =[None] * 51 lst2 =[None] * 51 print(f'exp({x}) ={math.exp(x)}') print() print(f'Approximation of exp({x}) by Euler fomula') for n in range(1,51): def factorial(n): if n > 0: return n * factorial(n - 1) else: return 1 lst[n] = factorial(n) lst2[n] =x**n m = 10 def sum_1ton(m): s = 0 while m > 0: s += lst2[m]/lst[m] m -= 1 return s print(f'10: {sum_1ton(m)}') m = 20 def sum_2ton(m): s = 0 while m > 0: s += lst2[m]/lst[m] m -= 1 return s print(f'20: {sum_2ton(m)}') m = 30 def sum_3ton(m): s = 0 while m > 0: s += lst2[m]/lst[m] m -= 1 return s print(f'30: {sum_3ton(m)}') m = 40 def sum_4ton(m): s = 0 while m > 0: s += lst2[m]/lst[m] m -= 1 return s print(f'40: {sum_4ton(m)}') m = 50 def sum_5ton(m): s = 0 while m > 0: s += lst2[m]/lst[m] m -= 1 return s print(f'50: {sum_5ton(m)}') |
関数を定義し,引数のやり取りをおこなうことを実習しました.演習で扱っているような短いプログラムではあまり関数のありがたみを感じることも無いでしょうが,実際に業務や研究で使用するような大掛かりなものであれば,何度か登場する一連の作業をユーザ定義関数として用意しておくことは大きな意味を持ってきます.使えるようになっておくに越したことはありません.
教科書にもあるように,関数の冒頭でその関数の定義や説明,引数仕様やオプションなどを整備してマニュアルのように使用するのが文書化文字列です.この授業では特に扱うことはありませんが,複数人が関わる共同開発などでは重要です.
どこで変数や関数を定義するか,そしてどう使うかについて,教科書に詳しく書いてあります.現時点では,教科書の p.279 の中央やや下にある以下の探索順を知っておけば,プログラムを作成する上で特に問題となることは無いでしょう.
名前の探索順
[3] 局所名前空間 → [2] 広域名前空間 → [1] 組込み名前空間
授業の範囲では,ラムダ式を高階関数に応用する部分について知っておけば当面は問題ないかと思います.今回の演習問題を通してラムダ式の使い方を確認していきましょう.
今回の演習問題です.
いつものようにMoodleを利用します.授業当日の18:00から閲覧可能で,締切りは翌週月曜日の15:00です.
次回も引き続き関数です.これまでやってきたことを再度復習を兼ねてプログラミング作業をします.