529 Views
January 26, 22
スライド概要
Scheme プログラミング
URL: https://www.kkaneko.jp/pro/scheme/index.html
金子邦彦研究室
URL: https://www.kkaneko.jp/index.html
金子邦彦(かねこくにひこ) 福山大学・工学部・教授 ホームページ: https://www.kkaneko.jp/index.html 金子邦彦 YouTube チャンネル: https://youtube.com/user/kunihikokaneko
sp-3. 関数の組み合わせ (Scheme プログラミング) URL: https://www.kkaneko.jp/pro/scheme/index.html 金子邦彦 1
3-1 Scheme の関数 2
アウトライン 3-1 Scheme の関数 3-2 パソコン演習 3-3 課題 3
本日の内容 • Scheme の式から出発して,実行結果に至 るステップを読み,理解する • 複数の関数から構成されたプログラムを読 んで,意味を理解できる能力,知識を身に 付ける • 見やすいプログラムを書くために,ブロッ ク単位での字下げを行う 4
実行結果に至る過程 なぜ? コンピュータの振る舞いを理解 するためには Scheme の式から出発して, 実行結果に至るステップを理解する 5
実行結果に至る過程 • 演算子を含む式が計算される • 括弧の内側が優先される 例: (* 4 12) = 48 (* 3.14 (* 5 5)) = (* 3.14 25) = 78.5 • 関数が,その「中身」で置き換わる • 同時に,関数のパラメータは,実際の値で置き換わ る 例: (area-of-disk 5) = (* 3.14 (* 5 5)) = ... (+ (sqr 2) (sqr 4)) = (+ (* 2 2) (sqr 4)) = ... 6
• Scheme 処理系と実行モデルを理解する • 変数と関数の違い 7
Scheme の関数の振る舞い 関数 (procedure arg1 ... argn) に対して • procedure の値を取得する • arg1 から argn の値を取得する • procedure の値に arg1 から argn の値を引き渡す 8
仕事の分割 ○○の仕事を 頼む! △△の仕事を 頼む! 頼む人 担当者A 担当者B 9
関数とは 関数A 呼び出し側 関数C 関数B 呼び出され側 呼び出され側 プログラムは,しばしば,複数の関 数に「分割」される 10
Scheme のプログラムと関数 • Scheme のプログラムは,一般に,複数の関 数の集まり (define (area-of-disk r) (* 3.14 (* r r))) (define (area-of-ring outer inner) (- (area-of-disk outer) (area-of-disk inner))) ⇒ 参照: これらは Scheme の式 例題3、4 11
関数でのデータの流れ 関数A 関数Bで使うための 「データ」の流れ 呼び出し側 関数Aで使うための データの流れ 関数B 呼び出され側 12
3-2 パソコン演習 13
パソコン演習の進め方 • 資料を見ながら,「例題」を行ってみる • 各自,「課題」に挑戦する • 自分のペースで先に進んで構いません 14
DrScheme の使用 • DrScheme の起動 プログラム • → PLT Scheme → DrScheme 今日の演習では「Intermediate Student」 に設定 Language → Choose Language → Intermediate Student → Execute ボタン 15
ステップ実行とは • DrScheme の機能 • プログラム実行の振る舞いを観察するための ツール • 「定義用ウインドウ」のみを使用 ← 普通のプログラム実行とは違う • 「Intermediate Student」に設定する必要あり 16
例題1.実行結果に至る過程 • 次の式について,実行結果「48」に至る過程を見 る • DrScheme の stepper を使用する (* (+ 2 2) (/ (* (+ 3 5) (/ 30 10)) 2)) Scheme の式 「*」とあるのは,「乗算」の意味 17
「例題1.実行結果に至る過程」の手順 1. 次を「定義用ウインドウ」で,実行しなさい • Intermediate Student で実行すること • 入力した後に,Execute ボタンを押す (* (+ 2 2) (/ (* (+ 3 5) (/ 30 10)) 2)) 2. DrScheme を使って,ステップ実行の様子を 確認しなさい (Step ボタン,Next ボタンを使用) • 理解しながら進むこと ☆ 次は,例題2に進んでください 18
例題2.式のステップ実行 定義用ウインドウに入力して, Execute ボタンを押した後,Step ボタンを押すと 19
「(+ 2 2)」は「4」で 置き換わる 20
「(+ 3 5)」は「8」で 置き換わる 21
「(/ 30 10)」は「3」で 置き換わる 22
「(* 8 3)」は「24」で 置き換わる 23
「(/ 24 2)」は「12」で 置き換わる 24
「(* 4 12)」は「48」で 置き換わる 25
実行結果「48」が得られる過程 (* (+ 2 2) (/ (* (+ 3 5) (/ 30 10)) 2)) 最初の式 = (* 4 (/ (* (+ 3 5) (/ 30 10)) 2)) (+ 2 2) → 4 = (* 4 (/ (* 8 (/ 30 10)) 2)) (+ 3 5) → 8 = (* 4 (/ (* 8 3) 2)) (/30 10) → 3 = (* 4 (/ 24 2))(* 8 3) → 2 = (* 4 12)(/24 2) → 12 = コンピュータ内部での計算 48 実行結果 26
実行結果「48」が得られる過程 (* (+ 2 2) (/ (* (+ 3 5) (/ 30 10)) 2)) 最初の式 = (* 4 (/ (* (+ 3 5) (/ 30 10)) 2)) (+ 2 2) → 4 最初の式 = (* 4 (/ (* 8 (/ 30 10)) 2)) (+ 3 5) → 8 (* (+ 2 2) (/ (* (+ 3 5) (/ 30 10)) 2)) = (* 4 (/ (* 8 3) 2)) から始まって,計算を繰り返して,実行結果 (/30 10) → 3 48 = (* 4 (/ 24 2)) (* 8 3) → 2 に至る = (* 4 12) = 48 (/24 2) → 12 実行結果 27
例題2.関数のステップ実行 • 円の半径 r から面積を求める関数 area-of-disk に ついて,実行結果に至る過程を見る • (area-of-disk 5) から 78.5 に至る過程を見る • DrScheme の stepper を使用する (define (area-of-disk r) (* 3.14 (* r r))) (area-of-disk 5) = (* 3.14 (* 5 5)) = (* 3.14 25) = 78.5 28
例題2.関数のステップ実行 1. 次を「定義用ウインドウ」で,実行しなさい • Intermediate Student で実行すること • 入力した後に,Execute ボタンを押す (define (area-of-disk r) (* 3.14 (* r r))) (area-of-disk 5) 例題1と同じ ステップ実行したい ので,入力済みの プログラムは,消さず に残しておく 例題1に 1行書き加える 2. DrScheme を使って,ステップ実行の様子を 確認しなさい (Step ボタン,Next ボタンを使用) • 理解しながら進むこと ☆ 次は,例題3に進んでください 29
例題2.式のステップ実行 定義用ウインドウに入力して, Execute ボタンを押した後,Step ボタンを押すと 30
「(area-of-disk 5)」は 「(* 3.14 (* 5 5))」で置き換わる 注: 「3.14」 は 「157/50」のように表示されている 31
「(* 5 5)」は 「25」で置き換わる 「157/50」とあるのは 3.14 のこと(有理数表示) 32
「(* 3.14 25)」は 「78.5」で置き換わる 「157/2」とあるのは 78.5 のこと(有理数表示) 33
(area-of-disk 5) から 78.5 が得られる過程 (area-of-disk 5) = (* 3.14 (* 5 5)) = (* 3.14 25) = 78.5 最初の式 (* 3.14 (* r r)) に r = 5 が代入される (* 5 5) → 25 コンピュータ内部での計算 実行結果 34
(area-of-disk 5) から 78.5 が得られる過程 (area-of-disk 5) 最初の式 最初の式 = (* 3.14 (* 5 5)) (area-of-disk 5) から始まって,計算を繰り返して,実行結果 =78.5 (* 3.14 25) に至る = 78.5 実行結果 35
(area-of-disk 5) から 78.5 が得られる過程 (area-of-disk 5) = (* 3.14 (* 5 5)) = (* 3.14 25) これは, (define (area-of-disk r) = 78.5 (* 3.14 (* r r))) の r を 5 で置き換えたもの 36
例題3.2乗の和 • x と y とから,x2+y2 を求めるプログラ ム sum-of-squares を作り,実行する • x の値から x2 を求める関数 sqr と組み合 わせる 37
「例題3.2乗の和」の手順 1. 次を「定義用ウインドウ」で,実行しなさい • 入力した後に,Execute ボタンを押す (define (sqr x) (* x x)) (define (sum-of-squares x y) (+ (sqr x) (sqr y))) 2. その後,次を「実行用ウインドウ」で実行しなさい (sum-of-squares 2 4) (sum-of-squares 20 30) ☆ 次は,例題4に進んでください 38
まず,Scheme のプログラムを コンピュータに読み込ませている 39
読み込ませたプログラムを実行 させている. ここでは, (sum-of-squares 2 4) と書いて,x の値を 2, yの値を 4 に設定しての実行 実行結果である「20」が 表示される 40
今度は, (area-of-ring 10 3) と書いて,x の値を 20, y の値を 30 に設定しての実行 実行結果である「1300」が 表示される 41
入力と出力 xの値: 4 16 sqr 入力は 1つの数値 出力は 1つの数値 42
sqr 関数 「関数である」ことを 関数の名前 示すキーワード (define (sqr x) 1つの関数 (* x x)) x の値から「(* x x)」 を計算(出力) 値を1つ受け取る(入力) (x のことを「パラメータ」という) 43
入力と出力 x, y の値 2, 4 20 sum-of-squares 入力は 2つの数値 出力は 1つの数値 44
sum-of-squares 関数 「関数である」ことを 関数の名前 示すキーワード (define (sum-of-squares x y) 1つの関数 (+ (sqr x) (sqr y))) 「x2 + y2 」 値を2つ受け取る(入力) を計算(出力) 45
2乗の和のプログラム • x2+y2 を求める (define (sqr x) (* x x)) sqr の部分 (define (sum-of-squares x y) (+ (sqr x) (sqr y))) sum-of-squares の部分 46
関数の関係 sum-of-squares 関数 (define (sum-of-squares x y) (+ (sqr x) (sqr y))) sum-of-squares 関数の中で, sqr 関数を使っている(2箇所) sqr 関数 (define (sqr x) (* x x)) 47
データの流れ sum-of-squares 関数 (define (sum-of-squares x y) (+ (sqr x) (sqr y))) ① 数値を, sqr 関数に渡す ②渡された値を, 「x」という名前で使う sqr 関数 (define (sqr x) (* x x)) ③実行結果を sum-of-squares 関数に返す 48
関数を分割する理由 分割する場合 分割しない場合 (define (sum-of-squares x y) (+ (* x x) (* y y))) (define (sqr x) (* x x)) (define (sum-of-squares x y) (+ (sqr x) (sqr y))) 「働き」は同じ 自分にとって「分かりやす い」書き方で書くことが重 要 49
例題4.ステップ実行 • 関数 sum-of-squares (例題3)について,実行結 果に至る過程を見る • (sum-of-squares 20 30) から 1300 に至る過程を見る • DrScheme の stepper を使用する (define (sqr x) (* x x)) (define (sum-of-squares x y) (+ (sqr x) (sqr y))) (sum-of-squares 20 30) = (+ (sqr 20) (sqr 30)) = (+ (* 20 20) (sqr 30)) = (+ 400 (sqr 30)) = (+ 400 (* 30 30)) = (+ 400 900) = 1300 50
例題4.ステップ実行 1. 次を「定義用ウインドウ」で,実行しなさい • Intermediate Student で実行すること • 入力した後に,Execute ボタンを押す 例題3と同じ (define (sqr x) ステップ実行したい (* x x)) ので,入力済みの (define (sum-of-squares x y) プログラムは,消さず に残しておく (+ (sqr x) (sqr y))) 例題3に (sum-of-squares 20 30) 1行書き加える 2. DrScheme を使って,ステップ実行の様子を 確認しなさい (Step ボタン,Next ボタンを使用) • 理解しながら進むこと ☆ 次は,例題5に進んでください 51
「(+ (sqr x) (sqr y))」の 「x」は「20」で「y」は「30」で置き換わる 52
「(* x x)」の 「x」は「20」で置き換わる 53
乗算により 「(* 20 20)」は「400」で 置き換わる 54
「(* x x)」の 「x」は「30」で置き換わる 55
乗算により 「(* 30 30)」は「900」で 置き換わる 56
加算により 「(+ 400 900)」は「1300」で 置き換わる 57
(sum-of-squares 20 30) から 1300 が得られる過程 (sum-of-squares 20 30) 最初の式 = (+ (sqr 20) (sqr 30)) (+ (sqr x) (sqr y)) に x = 2, y = 4 が代入される = (+ (* 20 20) (sqr 30)) = (+ 400 (sqr 30)) (* 2 2) → 4 = (+ 400 (* 30 30)) = (+ 400 900) (* x x)) に x = 4 が代入される (* 4 4) → 16 = 1300 実行結果 (* x x)) に x = 2 が代入される コンピュータ内部での計算 58
(sum-of-squares 20 30) から 1300 が得られる過程 (sum-of-squares 20 30) = (+ (sqr 20) (sqr 30)) = (+ (* 20 20) (sqr 30)) これは, = (+ 400 (sqr 30)) (define (sum-of-squares x y) (+ 30 (sqr30)) x) (sqr y))) = (+ 400 (* の x を 20 で,y を 30 で置き換えたもの = (+ 400 900) = 1300 59
例題5.リングの面積 • 外径 outer, 内径 inner からリングの面積を求める プログラム area-of-ring を作り,実行する • 円の面積を求める関数 area-of-disk と組み合わせる 真ん中に穴のあいた 円の面積と考える 60
リングの面積 • 求める面積は,外側の円の面積から, 内側の穴の円の面積を引いたもの 外側の円 内側の円 61
リングの面積 外径:outer 内径: inner inner outer リングの面積 = 外側の円の面積 半径 outer の円 - 内側の円の面積 半径 inner の円 62
「例題5.リングの面積」の手順 1. 次を「定義用ウインドウ」で,実行しなさい • 入力した後に,Execute ボタンを押す (define (area-of-disk r) (* 3.14 (* r r))) (define (area-of-ring outer inner) (- (area-of-disk outer) (area-of-disk inner))) 2. その後,次を「実行用ウインドウ」で実行しなさい (area-of-ring 5 3) ☆ 次は,例題6に進んでください 63
まず,Scheme のプログラムを コンピュータに読み込ませている 64
読み込ませたプログラムを実行 させている. ここでは, (area-of-ring 5 3) と書いて,outer の値を 5, inner の値を 3 に設定しての実行 実行結果である「50.24」が 表示される 65
今度は, (area-of-ring 10 3) と書いて,outer の値を 10, inner の値を 3 に設定しての実行 実行結果である「285.74」が 表示される 66
入力と出力 5 78.5 area-of-disk 入力は 1つの数値 出力は 1つの数値 67
area-of-disk 関数 「関数である」ことを 関数の名前 示すキーワード (define (area-of-disk r) (* 3.14 (* r r))) 1つの関数 値を1つ受け取る(入力) r の値から「(* 3.14 (* r r))」 (r のことを「パラメータ」 を計算(出力) という) 68
入力と出力 5, 3 50.24 area-of-ring 入力は 2つの数値 出力は 1つの数値 69
area-of-ring 関数 「関数である」ことを 示すキーワード 関数の名前 (define (area-of-ring outer inner) (- (area-of-disk outer) (area-of-disk inner))) 「外側の円の面積 -内側の円の面積」 を計算(出力) 1つの関数 値を2つ受け取る(入力) 70
リングの面積のプログラム 外径: outer 内径: inner inner (define (area-of-disk r) (* 3.14 (* r r))) (define (area-of-ring outer inner) (- (area-of-disk outer) (area-of-disk inner))) outer area-of-disk の部分 area-of-ring の部分 71
関数の関係 area-of-ring 関数 (define (area-of-ring outer inner) (- (area-of-disk outer) (area-of-disk inner))) area-of-disk 関数 (define (area-of-disk r) (* 3.14 area-of-ring 関数の中で, (* r r))) area-of-disk 関数を使っている(2箇所) 72
データの流れ area-of-ring 関数 (define (area-of-ring outer inner) (- (area-of-disk outer) (area-of-disk inner))) ① 数値を, area-of-disk 関数に渡す ②渡された値を, 「r」という名前で使う area-of-disk 関数 (define (area-of-disk r) (* 3.14 (* r r))) ③実行結果を area-of-ring 関数に返す 73
関数を分割する理由 分割する場合 (define (area-of-disk r) (* 3.14 (* r r))) (define (area-of-ring outer inner) 分割しない場合 (define (area-of-ring outer inner) (- (* 3.14 (* outer outer)) (* 3.14 (* inner inner)))) (- (area-of-disk outer) 「働き」は同じ (area-of-disk inner))) リングの面積は,「外側の円の 面積」-「内側の円の面積」で あることがひと目で分かる 74
例題6.ステップ実行 • 関数 area-of-ring (例題5)について,実行結果 に至る過程を見る • (area-of-ring 5 3) から 50.24 に至る過程を見る • DrScheme の stepper を使用する (define (area-of-disk r) (* 3.14 (* r r))) (define (area-of-ring outer inner) (- (area-of-disk outer) (area-of-disk inner))) (area-of-ring 5 3) = (- (area-of-disk 5) (area-of-disk 3)) = (- (* 3.14 (* 5 5)) (area-of-disk 3)) = (- (* 3.14 25) (area-of-disk 3)) = (- 78.5 (area-of-disk 3)) = (- 78.5 (* 3.14 (* 3 3))) = (- 78.5 (* 3.14 9)) = (- 78.5 28.26) = 50.24 75
例題6.ステップ実行 1. 次を「定義用ウインドウ」で,実行しなさい • • Intermediate Student で実行すること 入力した後に,Execute ボタンを押す (define (area-of-disk r) 例題5と同じ (* 3.14 ステップ実行したい (* r r))) ので,入力済みの (define (area-of-ring outer inner) プログラムは,消さず (- (area-of-disk outer) に残しておく (area-of-disk inner))) 例題5に (area-of-ring 5 3) 1行書き加える 2. DrScheme を使って,ステップ実行の様子を 確認しなさい (Step ボタン,Next ボタンを使用) • 理解しながら進むこと 76 ☆ 次は,例題7に進んでください
例題6.ステップ実行 定義用ウインドウに入力して, Execute ボタンを押した後,Step ボタンを押すと 77
例題6.ステップ実行 78
例題6.ステップ実行 79
例題6.ステップ実行 80
例題6.ステップ実行 81
例題6.ステップ実行 82
例題6.ステップ実行 83
例題6.ステップ実行 84
例題6.ステップ実行 85
(area-of-ring 5 3) から 50.24 が得られる過程 (area-of-ring 5 3) 最初の式 = (- (area-of-disk 5) (area-of-disk 3)) = (- (* 3.14 (* 5 5)) (area-of-disk 3)) (- (area-of-disk outer) (area-of-disk inner)) に outer = 5, inner = 3 が代入される (* 3.14 (* r r)) に r = 5 が代入される = (- (* 3.14 25) (area-of-disk 3)) (* 5 5) → 25 = (- 78.5 (area-of-disk 3)) (* 3.14 25) → 78.5 = (- 78.5 (* 3.14 (* 3 3))) (* 3.14 (* r r)) に r = 3 が代入される = (- 78.5 (* 3.14 9)) (* 3 3) → 9 = (- 78.5 28.26) (* 3.14 9) → 28.26 = 50.24 実行結果 コンピュータ内部での計算 86
(area-of-ring 5 3) から 50.24 が得られる過程 (area-of-ring 5 3) = (- (area-of-disk 5) (area-of-disk 3)) = (- (* 3.14 (* 5 5)) (area-of-disk 3)) =これは, (- (* 3.14 25) (area-of-disk 3)) (define (area-of-ring = (- 78.5 (area-of-disk 3)) outer inner) (- (*(area-of-disk = (- 78.5 3.14 (* 3 3))) outer) (area-of-disk inner))) =の (- 78.5 (* 3.14 outer を 59)) で,inner を 3 で置き換えたも =の (- 78.5 28.26) = 50.24 87
例題7.利益の計算 • 公演での利益を求めるプログラムを作り,実行する • チケット代 ticket-price から利益、収入、支出、観客数を 求める関数 profit, revenue, cost, attendees の作成 • profit: 利益 = 収入(revenue) - 費用(cost) • revenue: 収入 = 観客数(attendees) × チケット代(ticketprice) • cost: 支出 = 固定費 + 観客数(attendees) × 費用 → 「固定費」と「費用」は公演ごとに異なる • attendees: チケット代(ticket-price)と観客数には関係がある → この「関係」は公演ごとに異なる 88
支出の見積もり式 支出 観客数に比例して かかる部分 固定費 観客がいなくても かかる費用 (会場,設備,宣伝, 出演料その他) 0 観客数 • 支出 = 固定費 + 観客数 × 費用 例) 固定費: $180 費用: 観客1人あたり$0.04 89
観客数の見積もり式 観客数 推定された見積もり式 0 チケット代 • チケット代と観客数には関係がある 例) チケット代:$5 のとき,観客数は120人だった チケット代:$0.1 値下げすると15人増えた ⇒ 観客数 = -(15/0.1)×(チケット代-$5) + 120 と見積 もる 90
利益の計算 • あなたが「劇場」の所有者であるとする • チケット代は,あなたが自由に決める • チケット代から,収入,支出,利益などを見積 もりたい 91
観客数 チケット代を上げると, 観客数が減る 観客数 のグラフ 0 チケット代 支出 チケット代を上げると, 観客数が減り,結果 として支出も減る 支出 のグラフ 0 チケット代 観客数 収入 のグラフ 0 チケット代 収入は, 観客数×チケット代 (これは2次曲線) 92
「例題7.利益の計算」の手順 (1/4) 1. 次を「定義用ウインドウ」で,実行しなさい • 文法的な「間違い」が無いことを確認するため,入力した後 Execute ボタンを押す ;; profit : number -> number ;; to compute the profit as the difference between ;; revenue and costs at some given ticket-price (define (profit ticket-price) ... ) ;; revenue:number number → number ;; to compute the revenue, given ticket-price (define (revenue ticket-price) ... ) ;; cost : number -> number ;; to compute the cost, given ticket-price (define (cost ticket-price) ... ) ;; attendees:number → number ;; to compute the number of attendees, ;; given ticket-price (define (attendees ticket-price) ... ) ☆ 次ページに進んでください 94
「例題7.利益の計算」の手順 (2/4) 2. 「定義用ウインドウ」で,profit 関数の中身を書く. • 文法的な「間違い」が無いことを確認するため,入力した後に, Execute ボタンを押す (define (profit ticket-price) (- (revenue ticket-price) (cost ticket-price))) 3. 「定義用ウインドウ」で,revenue 関数の中身を書く. • 文法的な「間違い」が無いことを確認するため,入力した後に, Execute ボタンを押す (define (revenue ticket-price) (* (attendees ticket-price) ticket-price)) ☆ 次ページに進んでください 95
「例題7.利益の計算」の手順 (3/4) 4. 「定義用ウインドウ」で,cost 関数の中身を書く. • 文法的な「間違い」が無いことを確認するため,入力した後に, Execute ボタンを押す (define (cost ticket-price) (+ 180 (* .04 (attendees ticket-price)))) 5. 「定義用ウインドウ」で,attendees 関数の中身を書く. • 文法的な「間違い」が無いことを確認するため,入力した後に, Execute ボタンを押す (define (attendees ticket-price) (+ 120 (* (/ 15 .10) (- 5.00 ticket-price)))) ☆ 次ページに進んでください 96
「例題7.利益の計算」の手順 (4/4) 6. その後,次を「実行用ウインドウ」で実行しなさい • それぞれの実行結果が,予想通りであることを 確認しながら行うこと (attendees 3) (cost 3) (revenue 3) (profit 3) ☆ 次は,例題8に進んでください 97
まず,Scheme のプログラムを コンピュータに読み込ませている 98
読み込ませたプログラムを実行 させている. ここでは, (attendees 3) と書いて,ticket-price の値を 3 に設定しての実行 実行結果である「420」が 表示される 99
今度は, (cost 3) と書いて,ticket-price の値を 3 に設定しての実行 実行結果である「196.8」が 表示される 100
今度は, (revenue 3) と書いて,ticket-price の値を 3 に設定しての実行 実行結果である「1260」が 表示される 101
今度は, (profit 3) と書いて,ticket-price の値を 3 に設定しての実行 実行結果である「1063.2」が 表示される 102
入力と出力 3 1063.2 profit 入力 出力 103
profit 関数 「関数である」ことを 関数の名前 示すキーワード (define (profit ticket-price) (- (revenue ticket-price) (cost ticket-price))) 費用を計算する 式(出力) 値を1つ受け取る(入力) 104
(define (profit ticket-price) (- (revenue ticket-price) profit 関数 (cost ticket-price))) (define (revenue ticket-price) (* (attendees ticket-price) ticket-price)) revenue 関数 (define (cost ticket-price) (+ 180 cost 関数 (* 0.04 (attendees ticket-price)))) (define (attendees ticket-price) (+ 120 (* (/ 15 0.10) (- 5.00 ticket-price)))) attendees 関数 105
関数の関係 profit 関数 (define (profit ticket-price) (- (revenue ticket-price) (cost ticket-price))) revenue, cost 関数を 使っている revenue 関数 (define (revenue ticket-price) (* (attendees ticket-price) ticket-price)) attendees 関数を使っている cost 関数 (define (cost ticket-price) (+ 180 (* 0.04 (attendees ticket-price)))) attendees 関数を使っている attendees 関数 (define (attendees ticket-price) (+ 120 (* (/ 15 0.10) (- 5.00 ticket-price)))) 106
例題8.ステップ実行 • 関数 profit (例題7)について,実行結果に至る 過程を見る • (profit 3) から 1063.2 に至る過程を見る • DrScheme の stepper を使用する (profit 3) = (- (revenue 3) (cost 3)) = (- (* (attendees 3) 3) (cost 3)) = (- (* (+ 120 (* (/ 15 0.10) (- 5.00 3))) 3) (cost 3)) = (- (* (+ 120 (* 150 (- 5.00 3))) 3) (cost 3)) = (- (* (+ 120 (* 150 2)) 3) (cost 3)) = (- (* (+ 120 300) 3) (cost 3)) = (- (* 420 3) (cost 3)) = (- 1260 (cost 3)) = (- 1260 (+ 180 (* 0.04 (attendees 3)))) = (- 1260 (+ 180 (* 0.04 (+ 120 (* (/ 15 0.10) (- 5.00 3)))))) = (- 1260 (+ 180 (* 0.04 (+ 120 (* 150 (- 5.00 3)))))) = (- 1260 (+ 180 (* 0.04 (+ 120 (* 150 2))))) = (- 1260 (+ 180 (* 0.04 (+ 120 300)))) = (- 1260 (+ 180 (* 0.04 420))) = (- 1260 (+ 180 16.8)) = (- 1260 196.8) =1063.2 107
「例題3.ステップ実行」の手順 1. 次を「定義用ウインドウ」で,実行しなさい • Intermediate Student で実行すること • 入力した後に,Execute ボタンを押す ;; profit: number -> number ;; to compute the profit as the difference between ;; revenue and costs at some given ticket-price (define (cost ticket-price) (+ 180 (* .04 (attendees ticket-price)))) ;; revenue:number number → number ;; to compute the revenue, given ticket-price (define (revenue ticket-price) (* (attendees ticket-price) ticket-price)) ;; cost : number -> number ;; to compute the cost, given ticket-price (define (cost ticket-price) (+ 180 (* .04 (attendees ticket-price)))) ;; attendees:number → number ;; to compute the number of attendees, ;; given ticket-price (define (attendees ticket-price) (+ 120 (* (/ 15 .10) (- 5.00 ticket-price)))) (profit 3) 例題7と同じ ステップ実行したい ので,入力済みの プログラムは,消さず に残しておく 例題7に 1行書き加える 2. DrScheme を使って,ステップ実行の様子を 確認しなさい (Step ボタン,Next ボタンを使用) 108
(profit 3) から 1063.2 が得られる過程 (profit 3) 最初の式 = (- (revenue 3) (cost 3)) = (- (* (attendees 3) 3) (cost 3)) = (- (* (+ 120 (* (/ 15 0.10) (- 5.00 3))) 3) (cost 3)) = (- (* (+ 120 (* 150 (- 5.00 3))) 3) (cost 3)) = (- (* (+ 120 (* 150 2)) 3) (cost 3)) = (- (* (+ 120 300) 3) (cost 3)) = (- (* 420 3) (cost 3)) = (- 1260 (cost 3)) = (- 1260 (+ 180 (* 0.04 (attendees 3)))) = (- 1260 (+ 180 (* 0.04 (+ 120 (* (/ 15 0.10) (- 5.00 3)))))) = (- 1260 (+ 180 (* 0.04 (+ 120 (* 150 (- 5.00 3)))))) = (- 1260 (+ 180 (* 0.04 (+ 120 (* 150 2))))) = (- 1260 (+ 180 (* 0.04 (+ 120 300)))) = (- 1260 (+ 180 (* 0.04 420))) = (- 1260 (+ 180 16.8)) コンピュータ内部での計算 = (- 1260 196.8) 109 =1063.2 実行結果
(profit 3) から 1063.2 が得られる過程 (profit 3) 最初の式 = (- (revenue 3) (cost 3)) = (- (* (attendees 3) 3) (cost 3)) = (- (* (+ 120 (* (/ 15 0.10) (- 5.00 3))) 3) (cost 3)) =これは, (- (* (+ 120 (* 150 (- 5.00 3))) 3) (cost 3)) = (- (* (+ 120 (* 150 2)) 3) (cost 3)) (profit ticket-price) = (- (define (* (+ 120 300) 3) (cost 3)) = (- (*(-420 3) (cost 3))ticket-price) (revenue = (- 1260 (cost 3)) (cost ticket-price))) = (- 1260 (+ 180 (* 0.04 (attendees 3)))) ticket-price を (+ 3 120 で置き換えたもの =の (- 1260 (+ 180 (* 0.04 (* (/ 15 0.10) (- 5.00 3)))))) = (- 1260 (+ 180 (* 0.04 (+ 120 (* 150 (- 5.00 3)))))) = (- 1260 (+ 180 (* 0.04 (+ 120 (* 150 2))))) = (- 1260 (+ 180 (* 0.04 (+ 120 300)))) = (- 1260 (+ 180 (* 0.04 420))) = (- 1260 (+ 180 16.8)) = (- 1260 196.8) =1063.2 実行結果 110
3-3 課題 111
課題1 • 関数 profit (授業の例題7)についての問題 • 関数 profit を実行し,チケット代が 3, 4, 5の時の 実行結果を報告しなさい 112
課題2 • 関数 profit (授業の例題7)についての問題 • 固定費が0になるように例題7のプログラムを変 更しなさい • その後,関数 profit を実行し,チケット代が 3, 4, 5の時の実行結果を報告しなさい 113