プログラミング入門II
2024.06.05
関数 その2
今回の課題ですが,問題文のところに再帰を使用するよう指示していたにもかかわらず再帰を使用していない人が多くみられました.残念です.すべての処理を関数の中に入れようとしたことが原因かと推測していますが,再帰を使うところとそれ以外に処理をするところを考えてプログラムを作ってほしかったです. 再帰は漸化式で表される関係をプログラミングに取り入れたもので,以下のような漸化式を使用するのが前提です. an = f(an-1) 上のように示される漸化式を含む関数を作ることが今回の課題でした.関数で処理できない部分については本体のプログラムの方で実行するようにするだけでした. さて,今回は無限ループが出てきました.採点できませんので,そうならないように処理を書きましょう. 無限ループ: b2311 解答用紙の番号と名前の間違い: b2333 出力時番号間違い: b23233 以下は例によって問題のあるプログラムの例です.参考にしてください.
print(f'Intival amount of bacteria: {num1}')
相変わらず綴りの間違いが出ています.しっかりと綴りを確認するか,コピペをちゃんとやりましょう.
def generate_initial_bacteria(): return random.randint(1, 12000) def generate_D_value(): return random.randint(3, 5) |
別にこんなものまで関数にする必要はありません.
def amount(n): s = 0 while n > 10 ** -6: s += 1 n /= 10 return s |
今回実に多く見られた例です.全く再帰を使っていません.
def time(bacteria, D_num, compl=10**-6): if bacteria <= compl: return 0 else: return D_num +time(bacteria / 10, D_num) |
再帰っぽい形にはなっていますが,本来の漸化式は作れていないようです.
def main(o): m = 1 D = random.randint(3,5) o = random.randint(1,12000) while o >= o * ((1/10) ** 6): o = o * ((1/10 ) ** m) return m+1 return m D = random.randint(3,5) n = random.randint(1,12000) |
せっかく用意した D と n の値があるのに,なぜ関数の中でまた乱数を作るのでしょうかねえ.
def progression(n): if n == 6: return num + 6 else: return 1 n = 6 print(f'D value: {D} min') print(f'Time to sterilize: {D * progression(n)} min') |
一見関数に見えるのですが,この処理では変数 n は必ず 6 なので,意味ないです.
def amount(n): if n > 0.000001: return amount(n * 0.1) else: return n |
こちらも再帰っぽいですが,漸化式としてはどうですかねえ.
def sterilize(n): for i in range(0,n): if n > 0.1 ** 6: n = n / 10 else: return i |
再帰を使うように指示しているのに,反復処理を使っています.
def sterilize_time(initial_bacteria, D_value, current_time=0): if initial_bacteria == 0: return current_time else: return sterilize_time(initial_bacteria // 2, D_value, current_time + D_value) |
なんで 2 で割っているのでしょうかね.当然答えは間違っているのですが.
関数を定義し,引数のやり取りをおこなうことを実習しました.演習で扱っているような短いプログラムではあまり関数のありがたみを感じることも無いでしょうが,実際に業務や研究で使用するような大掛かりなものであれば,何度か登場する一連の作業をユーザ定義関数として用意しておくことは大きな意味を持ってきます.使えるようになっておくに越したことはありません.
教科書にもあるように,関数の冒頭でその関数の定義や説明,引数仕様やオプションなどを整備してマニュアルのように使用するのが文書化文字列です.この授業では特に扱うことはありませんが,複数人が関わる共同開発などでは重要です.
どこで変数や関数を定義するか,そしてどう使うかについて,教科書に詳しく書いてあります.現時点では,教科書の p.279 の中央やや下にある以下の探索順を知っておけば,プログラムを作成する上で特に問題となることは無いでしょう.
名前の探索順
[3] 局所名前空間 → [2] 広域名前空間 → [1] 組込み名前空間
授業の範囲では,ラムダ式を高階関数に応用する部分について知っておけば当面は問題ないかと思います.今回の演習問題を通してラムダ式の使い方を確認していきましょう.
今回の演習問題です.
いつものようにレポート提出システムを利用します.授業当日の18:00から閲覧可能で,締切りは翌週火曜日の10:00です.
次回も引き続き関数です.これまでやってきたことを再度復習を兼ねてプログラミング作業をします.