2. 関数を使ったプログラムの 作成と実行 プログラミング論I.

Slides:



Advertisements
Similar presentations
VBA の基礎 (Visual Basic for Application) 国立教育政策研究所 坂谷内 勝.
Advertisements

情報・知能工学系 山本一公 プログラミング演習Ⅱ 第3回 配列(1) 情報・知能工学系 山本一公
東京工科大学 コンピュータサイエンス学部 亀田弘之
プログラミング演習(1組) 第7回
電子情報工学科5年(前期) 7回目(21/5/2015) 担当:古山彰一
プログラミング基礎I(再) 山元進.
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
プログラミング演習(2組) 第12回
プログラミング言語論 第6回 型 情報工学科 篠埜 功.
2006/10/19 山下 諒蔵 佐藤 春旗 前田 俊行 大山 恵弘 佐藤 秀明 住井英二郎
第6章 2重ループ&配列 2重ループと配列をやります.
構造体.
湘南工科大学 2013年12月10日 プログラミング基礎1 湘南工科大学情報工学科 准教授 小林 学.
ML 演習 第 7 回 新井淳也、中村宇佑、前田俊行 2011/05/31.
関数 関数とスタック.
工学部2018年度 – プログラミング論I – 2018年度前期 (廣川) 工学部第15講義室(月曜1,2限目)
7.プログラム設計法と 種々のエラー.
プログラミング基礎a 第8回 プログラムの設計 アルゴリズムとデータ構造
第6章 連立方程式モデル ー 計量経済学 ー.
プログラミング2 関数
関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題
第10回関数 Ⅱ (ローカル変数とスコープ).
6. リスト処理関数の設計(発展版) プログラミング論 I.
第7回 プログラミングⅡ 第7回
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
地域情報学 C言語プログラミング 第5回 ポインタ、関数、ファイル入出力 2017年11月17日
12.数値微分と数値積分.
6.リストの生成.
情報基礎Ⅱ (第11回) 月曜4限 担当:北川 晃.
ソフトウェア制作論 平成30年9月26日.
プログラミング言語論 第10回 練習問題解答例 情報工学科 篠埜 功.
3.条件式.
プログラミング基礎a 第8回 プログラムの設計 アルゴリズムとデータ構造
4.リスト,シンボル,文字列.
11.再帰と繰り返しの回数.
コンパイラ 2011年10月20日
東京工科大学 コンピュータサイエンス学部 担当 亀田弘之
メモリとメモリアドレス, ポインタ変数,関数へのポインタ渡し
C言語 はじめに 2016年 吉田研究室.
統計ソフトウエアRの基礎.
アルゴリズムとプログラミング (Algorithms and Programming)
情報基礎Ⅱ (第1回) 月曜4限 担当:北川 晃.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
情報工学Ⅱ (第9回) 月曜4限 担当:北川 晃.
計算機プログラミングI 木曜日 1時限・5時限 担当: 増原英彦 第1回 2002年10月10日(木)
プログラミング基礎a 第4回 C言語によるプログラミング入門 条件判断と反復
2.関数の組み合わせ によるプログラム.
PROGRAMMING IN HASKELL
プログラミング言語論 第10回 情報工学科 篠埜 功.
11.1 標準ライブラリ関数 11.2 関数呼び出しのオーバーヘッド 11.3 大域変数 11.4 プロトタイプ宣言 11.5 関数引数
第5回 プログラミングⅡ 第5回
情報処理Ⅱ 第7回 2004年11月16日(火).
1.Scheme の式とプログラム.
PROGRAMMING IN HASKELL
プログラミング基礎a 第3回 C言語によるプログラミング入門 データ入力
オブジェクト指向 プログラミング 第四回 知能情報学部 新田直也.
情報処理Ⅱ 2007年12月3日(月) その1.
コンパイラ 2012年10月11日
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
関数と再帰 教科書13章 電子1(木曜クラス) 2005/06/22(Thu.).
第10回 関数と再帰.
プログラミング基礎a 第3回 C言語によるプログラミング入門 データ入力
4. 合成データ:構造体 プログラミング論I.
計算技術研究会 第5回 C言語勉強会 関数(function)を使う
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
計算機プログラミングI 第2回 2002年10月17日(木) 履習登録 複習 ライブラリの利用 (2.6-7) 式・値・代入 (2.6-8)
アルゴリズム ~すべてのプログラムの基礎~.
Presentation transcript:

2. 関数を使ったプログラムの 作成と実行 プログラミング論I

本日の内容 (前回) Scheme の式と関数の書き方の基礎とその評価結果に至る過程、およびエラー 関数を使ったプログラムの作成法の基礎: 複数の関数から構成する目的や利点など 設計レシピ :プログラム開発のガイドライン

複数の関数を使ったプログラム

仕事の分割 上司 担当者B 担当者A この仕事には△△と○○の結果が必要だ… ○○の仕事を 頼む! △△の仕事を 頼む! ○○の結果 △△の結果 ○○の開始に 必要なデータ △△の開始に 必要なデータ 担当者B 担当者A

プログラムの分割と関数 例えば関数定義に関して: 主関数(Main Function): 補助関数(Auxiliary Function): 通常プログラムは一つだけでなく数多くの定義からなる 例えば関数定義に関して: 主関数(Main Function): 本当に必要な最終結果を生成する関数 補助関数(Auxiliary Function): より容易に解決できるよう分割した部分問題を解く関数 (この部分問題の解を使い,最終結果を求める) 可読性(思考過程の再現性)や再利用性を高める ※プログラムによっては,ある主関数が別プログラムの補助関数になることもあるし, その逆もある 複雑で大きなプログラムに補助関数の使用は必須

プログラムは,しばしば,複数の関数に「分割」される プログラムの分割と関数 Bの処理を頼む! (主)関数A Cの処理を頼む! 結果 結果 呼び出す側 必要なデータ (補助)関数C 必要なデータ (補助)関数B 呼び出される側 呼び出される側 プログラムは,しばしば,複数の関数に「分割」される

例題1. 2乗の和 a と b とから,a2+b2 を求めるプログラムを関数 sum-of-squares として作成し実行 例題1. 2乗の和  a と b とから,a2+b2 を求めるプログラムを関数 sum-of-squares として作成し実行 手順を分けて考える まず2乗について:ある値 x から x2 を求める補助関数 square を考える 主関数では、補助関数 square を2回使い 2乗の値を2つ求め、それらを足す

関数squareの入力と出力 xの値: 4 結果: 16 square 入力は 1つの数値 出力は 1つの数値

関数 square の定義 (define (square x) (* x x)) 1つの関数定義 この関数の名前 を計算(出力) 「(関数の)定義である」 ことを示すキーワード この関数の名前 (define (square x) (* x x)) 1つの関数定義 x の値から (* x x) を計算(出力) 値を1つ受け取る(入力)

関数sum-of-squaresの入力と出力 x, y の値: 2, 4 結果: 20 sum-of-squares 入力は 2つの数値 出力は 1つの数値

関数sum-of-squaresの定義 1つの 関数定義 この関数の名前 (define (sum-of-squares a b) 「(関数の)定義である」 ことを示すキーワード この関数の名前 (define (sum-of-squares a b) (+ (square a) (square b))) 1つの 関数定義 値を2つ受け取る(入力) 「a2 + b2 」 を計算(結果として出力)

2乗の和のプログラム a2+b2 を求める (define (square x) (* x x)) (define (sum-of-squares a b) (+ (square a) (square b))) sum-of-squaresの定義 注: 引数名は各関数内のみ有効。例えば右のsum-of-squares内 の x と square内の x は字面は同じだがそれぞれの関数定義に閉じた異なる変数。 (define (square x) (* x x)) (define (sum-of-squares x y) (+ (square x) (square y)))

関数の間の関係 主関数 sum-of-squares 補助関数 square (define (sum-of-squares a b) (+ (square a) (square b))) 補助関数 square (define (square x) (* x x)) sum-of-squares 関数の中で, square 関数を使っている(2箇所)

データの流れ 主関数 sum-of-squares square関数 (define (sum-of-squares a b) (+ (square a) (square b))) 同様に①(渡すのは yの値), ②, ③を行う ④ これらの結果を使い最終結果を計算 square関数 (define (square x) (* x x)) ① square関数に値aを渡し,aの2乗の計算を依頼 ② 変数xを渡された値aで 置換えて本体式a2を計算 ③実行結果を呼び出しもとの sum-of-squares関数に返す

関数の分割に関して 分割しない例 分割する例 どちらのsum-of-squares も機能的には同一 可読性(思考過程の明示) (define (sum-of-squares x y) (+ (* x x) (* y y))) どちらのsum-of-squares も機能的には同一 分割する例 (define (square x) (* x x)) (define (sum-of-squares a b) (+ (square a) (square b))) 可読性(思考過程の明示) 再利用性などを考慮し、 分割するかを判断

(sum-of-squares 20 30)から1300が得られる過程 最初の式 (sum-of-squares 20 30) = (+ (square 20) (square 30)) = (+ (* 20 20) (square 30)) = (+ 400 (square 30)) = (+ 400 (* 30 30)) = (+ 400 900) = 1300 (sum-of-squares a b) の本体 (+ (square a) (square b)) を呼び出しa=20,b=30の置換を行う (square x) の本体 (* x x) を呼び出し x=20 の置換 (* 20 20) → 4 (square x) の本体 (* x x) に x=30 の置換 (* 30 30) → 900 コンピュータ内部での計算 実行結果

練習問題1 x 円の硬貨 y 枚の金額を求める関数 coins を作れ。 関数 coins を用い、1円硬貨 a 枚、5円硬貨 b 枚、10円硬貨 c 枚、50円硬貨 d 枚、100円硬貨 e 枚、500円硬貨 f 枚の合計を求める関数 total を作れ。 (define (coins x y) (* x y)) (define (total a b c d e f) (+ (coins 1 a) (coins 5 b) (coins 10 c) (coins 50 d) (coins 100 e) (coins 500 f))) ;; test >(total 1 2 3 4 5 6) >(+ (coins 1 1) (coins 5 2) (coins 10 3) (coins 50 4) (coins 100 5) (coins 500 6)) >(+ (* 1 1) (coins 5 2) ... )

設計レシピによるプログラム作成

プログラム設計法 プログラム開発には多くの段階が必要 体系的に秩序正しく開発 → 設計レシピ 問題記述の文中で何が本質で重要(不要,冗長)か 入力に何を受け取りそれを出力にどう関連づけるか 対象データに対する演算をSchemeが提供しているか(なければ対応するプログラムを開発する必要) 作成後、実際に意図した計算を実行するかチェック 体系的に秩序正しく開発 → 設計レシピ 何をすべきかのステップごとの処方箋とその順序 少なくとも4つの活動:purpose,example,definition,test

プログラム設計法 プログラム開発に必要な活動 Purpose プログラムの目的を理解し、機能の概要を記述 Example Contract:関数名とデータ受け渡しに関する約束を記述 Header:関数定義の先頭部(名前や引数)を記述 Statement:何を計算するか自然言語や数式でコメント Example プログラムの振る舞いを「例」で記述. Definition プログラムの定義を具体化する Test 検査を通じた誤り(エラー)の発見

例題2. リングの面積 まず問題をよく分析して理解する 例題2. リングの面積  外径 outer, 内径 inner からリングの面積を求めるプログラム area-of-ring を作り実行する 円の面積を求める関数 area-of-disk を使う まず問題をよく分析して理解する 真ん中に穴のあいた 円板の面積と考える inner outer 求める面積は,外側の円の面積から, 内側の穴の円の面積を引いたもの

リングの面積 外径:outer outer 内径: inner inner リングの面積 = 外側の円の面積 - 内側の円の面積 = 外側の円の面積 - 内側の円の面積 半径 outer の円 半径 inner の円 (外径 outer と内径 inner は実際の計算時に与えられる) 

入力と出力 5, 3 50.24 area-of-ring 入力は 1つの数値 inner, outer 出力は 1つの数値

Purpose - contract & header 問題の解析と目的の把握 関数の名前と取り扱うデータの種類の記述 area-of-ring: number number -> number 関数名(内容を適切に表現) : 入力データの種類の列挙 -> 出力 プログラム中での記述 ;; area-of-ring : number number -> number ここで ; で始まる行は実行されない(人間が読むコメント) 引数名を決めれば関数ヘッダ(先頭部)も書ける ;; area-of-ring : number number -> number (define (area-of-ring outer inner) ...)

プログラムが何をするか,何を計算するかを書いた文章 Purpose - statement - プログラムの振る舞いに関する仕様の明確化 プログラムの仕様,目的など to compute the area of a ring whose radius is outer and whose hole has a radius of inner プログラムが何をするか,何を計算するかを書いた文章 (注:DrScheme では英文で入力) プログラム中での記述 ;; area-of-ring : number number -> number ;; to compute the area of a ring whose radius is ;; outer and whose hole has a radius of inner (define (area-of-ring outer inner) ...)

Purpose での成果 以下順に contract:関数の名前と取り扱うデータの種類 statement:プログラムが何をするかのコメント。headerの引数名をコメント中に盛り込むと,よりわかりやすい header:関数ヘッダ(先頭部)。本体式はまだない ;; area-of-ring : number number -> number ;; to compute the area of a ring whose radius is ;; outer and whose hole has a radius of inner (define (area-of-ring outer inner) ...)

Example 例題を使った,プログラムの振る舞いの例示 入出力関係を特徴づけるような「例」での記述 入力と期待される出力 area-of-ring should produce 50.24 for the inputs 5 and 3 入力と期待される出力 (プログラムの理解の助けになる) プログラム中の記述 ;;area-of-ring : number number -> number ;;to compute the area of a ring whose radius is ;;outer and whose hole has a radius of inner ;;example:(area-of-ring 5 3) should produce 50.24 (define (area-of-ring outer inner) ...)

Example の効用 特定の入力に対する出力の記述 プログラムを正確に理解するための手段(関数の入力と出力の関係や,計算過程など) 論理的なエラーの発見の手段. プログラムの本体を書き下す前に例を作るべき (記述後ではプログラム記述の影響を受ける可能性) 後でプログラムを読み返すときのための「メモ」として (プログラム作成者以外にも有用) prose : 散文

Definition Example まで出来たらプログラム本体の記述を開始. Header において「…」としていた部分を実際に作成 ドーナツ型の面積は外側の円の面積から内側の円の 面積を引いたもの プログラムの振る舞い プログラム中での記述 ;;area-of-ring : number number -> number ;;to compute the area of a ring whose radius is ;;outer and whose hole has a radius of inner ;;example:(area-of-ring 5 3) should produce 50.24 (define (area-of-ring outer inner) (- (area-of-disk outer) (area-of-disk inner)) )

area-of-ring 関数の定義 1つの 関数 定義 関数の名前 (define (area-of-ring outer inner) 「(関数の)定義である」 ことを示すキーワード 関数の名前 1つの 関数 定義 (define (area-of-ring outer inner) (- (area-of-disk outer) (area-of-disk inner))) 「外側の円の面積 - 内側の円の面積」を 計算(出力)する本体式 値を2つ受け取る(入力)

Definition 記述していた「Example」を参考に、与えられた入力から,プログラムがどのように出力を計算するのかを理解した後に行う 基本演算や定義済(予定)のSchemeプログラムを使い,入力引数から答を計算 入出力関係が,数式で与えられていれば, → 直ちにプログラムを書ける 言葉で問題が与えられていれば, → 注意深くプログラムを作る to this end このために

プログラム設計法の例(まとめ) ;;Contract: ;;area-of-ring : number number -> number (define (area-of-ring outer inner) … ) ;;Purpose(statement): ;;to compute the area of a ring whose radius ;;is outer and whose hole has a radius of inner ;;Example: ;;(area-of-ring 5 3) should produce 50.24 ;;Definition: (define (area-of-ring outer inner) (- (area-of-disk outer) (area-of-disk inner))) ;;Tests: (area-of-ring 5 3) ;; expected value 50.24 参考 Web ページ http://www.htdp.org/2003-09-26/Book/curriculum-Z-H-5.html#node_sec_2.5

実行例: (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)) = (- 78.5 (area-of-disk 3)) = (- 78.5 (* 3.14 (* 3 3))) = (- 78.5 (* 3.14 9)) = (- 78.5 28.26) = 50.24 area-of-ring の本体 (- (area-of-disk outer) (area-of-disk inner)) に outer= 5, inner= 3 の置換 コンピュータ内部での計算 area-of-disk 本体 (* 3.14 (* r r)) に r = 5の置換 ※円周率PIは 3.14とする (* 5 5) → 25 (* 3.14 25) → 78.5 area-of-disk 本体 (* 3.14 (* r r)) に r = 3の置換 (* 3 3) → 9 (* 3.14 9) → 28.26 実行結果

ここまでのまとめ Purpose: プログラムの目的を理解し、機能の概要を記述 Contract:関数名,データ受渡しに関する約束を記述 Header:関数定義の先頭部(名前や引数)を記述 Statement:何を計算するか自然言語や式でコメント Example プログラムの振る舞いを「例」で記述. Definition プログラムの定義を具体化する Test 検査を通じた誤り(エラー)の発見

例題3. 映画館の利益計算 テキスト3.1節の例題: 「映画館」の所有者がチケット価格を決める チケット価格から,収入,支出,利益などを見積もりたい (高価格なら入場者減のトレードオフ) チケット価格と平均観客との間の関係 チケットあたり5.00ドルの価格では、120人 10セント(0.10ドル)下げると観客が15人増える しかし観客の増加は支出の増加につながる 上映ごとに180ドルの固定費 各観客ごとに4セント(0.04ドル)の費用 チケット価格と利益の間の正確な関係を知りたい $5 .. 120 $5 - 0.1x .. 120 + 15x y=$4 = $5 -0.1x -> x=10 ->120+15*10=270 cost 270 * 0.04 y=$3 -> x=20 ->120+15*20=420 cost 420 * 0.04 x=($5-y)/0.1 z=120+15*x = 120+(15 * ($5 -y)/0.1)

例題5. 映画館の利益計算 まず目的を理解し機能の概要を記述する Purpose フェーズ 今回はいくつかの数量が互いに依存 → 依存関係を一つずつ分析 (視点:自由に設定できるチケット代をいくらにするか決めたい) 利益は ticket-price に依存 (∵ 収入と支出の双方が依存) ;; profit : number -> number ;; to compute the profit as the difference between ;; revenue and costs at some given ticket-price (define (profit ticket-price) ... ) 収入も ticket-priceに依存 (∵収入を決める観客数もそれに依存) ;; revenue:number → number ;; to compute the revenue, given ticket-price (define (revenue ticket-price) ... )

例題5. 映画館の利益計算 目的を理解し機能の概要を記述する Purpose フェーズ いくつかの数量が互いに依存 → 依存関係を一度に一つずつ分析 (視点:自由に設定できるチケット代をいくらにするか決めたい) 支出もticket-price依存 (∵ 支出の算出に必要な観客数が依存) ;; cost : number -> number ;; to compute the cost, given ticket-price (define (cost ticket-price) ... ) 観客数も ticket-price 依存 ( ticket-price と観客数には相関あり) ;; attendees:number → number ;; to compute the number of attendees, ;; given ticket-price (define (attendees ticket-price) ... )

例題5. 映画館の利益計算 各関係ごとに数量が互いにどう依存するかを分析し定式化 → チケット代 ticket-price から利益(と収入、支出、観客数)を求める関数 profit, revenue, cost, attendees の計算例と本体作成 profit: 利益 = 収入(revenue) - 支出(cost) revenue: 収入 = 観客数(attendees) × チケット代(ticket-price) cost: 支出 = 固定費 + 観客数(attendees) ×観客ごとの費用 固定費: $180, 観客ごとの費用: 観客1人あたり $0.04 attendees: チケット代(ticket-price)と観客数には関係がある チケット代:$5 のとき観客数は120人、 $0.1値下げすると15人増えた

支出の見積もり式 支出= 固定費 + 観客数 × 観客ごとの費用 固定費 今回) 固定費: $180 観客数に比例して かかる部分 固定費 観客がいなくても かかる費用 (会場,設備,宣伝,  出演料その他) 観客数 支出= 固定費 + 観客数 × 観客ごとの費用 今回) 固定費: $180 観客ごとの費用: 観客1人あたり $0.04

観客数の見積もり式 チケット代と観客数には関係がある 観客数 推定された見積もり式 チケット代 チケット代 チケット代と観客数には関係がある 今回) チケット代:$5 のとき,観客数は120人だった チケット代:$0.1値下げすると15人増えた ⇒ 観客数 = -(15/0.1)×(チケット代-$5)+120 と見積もる

例題3. 映画館の利益計算:例 分析結果にもとづき詳細定義の前に example を考える ;; profit : number -> number ;; ... ;; example: (profit 5) should produce 415.2 (define (profit ticket-price) ... ) ;; revenue:number → number ;; example: (revenue 5) should produce 600 (define (revenue ticket-price) ...) ;; cost : number -> number ;; example: (cost 5) should produce 184.8 (define (cost ticket-price) ...) ;; attendees:number → number ;; example: (attendees 5) should produce 120 (define (attendees ticket-price) ...)

例題3. 映画館の利益計算:定義 profit 関数 revenue 関数 cost 関数 attendees 関数 (define (profit ticket-price) (- (revenue ticket-price) (cost ticket-price))) (define (revenue ticket-price) (* (attendees ticket-price) ticket-price)) (define (cost ticket-price) (+ 180 0.04))) (define (attendees ticket-price) (+ 120 (* (/ 15 0.10) (- 5.00 ticket-price)))) profit 関数 (スペースの都合上 ヘッダなどは省略) revenue 関数 cost 関数 attendees 関数

profit関数を起点にした呼出関係 profit 関数 revenue 関数 関数を呼び出し cost 関数 を呼び出し (define (profit ticket-price) (- (revenue ticket-price) (cost ticket-price))) revenue 関数 (define (revenue ticket-price) (* (attendees ticket-price) ticket-price)) revenue,cost 関数を呼び出し cost 関数 attendees 関数 を呼び出し (define (cost ticket-price) (+ 180 (* (attendees ticket-price) 0.04))) attendees 関数 attendees 関数 を呼び出し (define (attendees ticket-price) (+ 120 (* (/ 15 0.10) (- 5.00 ticket-price))))

練習2 関数 profit (授業の例題3)についての練習 チケット代が 3, および 4 の時の関数 profit の実行結果を示せ

(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) =1063.2 コンピュータ内部での計算 実行結果

課題1 関数 profit (授業の例題3)についての問題 ;; cost: number -> number ;; to compute the cost, given ticket-price. ;; The cost per one attendee is $1.5 and constant cost is 0 (define (cost ticket-price) (* (attendees ticket-price) 1.5) ) 課題1 関数 profit (授業の例題3)についての問題 業務内容の変更で固定費が $0 、一人当たりの支出が $1.5 となった。対応するよう例題3 のプログラムを変更しなさい。 この場合のチケット代を 3, 4, 5 としたときの関数 profit の実行結果を報告しなさい cost: 支出=固定費+観客数(attendees) ×観客ごとの費用 固定費: $10, 観客ごとの費用:観客1人あたり $0.5 (define (cost ticket-price) (+ 10 (* (attendees ticket-price) 0.5) ) )

ところで 複数の関数に分割しなかったら, どうなっているだろう?

直接,profitを計算するような式を書いてみる ;; profit : number -> number ;; to compute profit, given ticket-price (define (profit ticket-price) (- (* (+ 120 (* 15 (/ (- 5 ticket-price) 0.1))) ticket-price) (+ 10  (* (+ 120 (* 15 (/ (- 5 ticket-price) 0.1))) 0.5)))) ところで,以下の式のエラーを,すぐに見つけることが できるだろうか? ;; profit : number -> number ;; to compute profit, given ticket-price (define (profit ticket-price) (- (* (+ 120 (* 15 (/ (- 5 ticket-price) 0.1)) ticket-price)) (+ 10  (* (+ 120 (* 15 (/ (- 5 ticket-price) 0.1)) 0.5)))))

せめてattendees関数だけでも利用するprofit関数の式を書いてみる ;; attendees : number -> number ;; to compute the number of attendees, given ticket-price (define (attendees ticket-price) (+ 120 (* 15 (/ (- 5 ticket-price) 0.1)))) ;; profit : number -> number ;; to compute profit, given ticket-price (define (profit ticket-price) (- (* (attendees ticket-price) ticket-price) ;; revenue (+ 10  (* (attendees ticket-price) 0.5)))) ;; cost 少しはすっきりするが, revenueとcostの計算式が 直接,表れている.

課題2 合衆国は以下のように、世界標準とは異なる単位制度を使っている: 以下の関数を作れ:inch->cm, feet->inches, yards->feet, rods->yards, furlongs->rods, miles->furlongs その後に 以下の関数を作れ:feet->cm, yards->cm, rods->inches, miles->feet (ポイント:関数の再利用) 合衆国 世界標準 1 inch = 2.54 cm 1 foot = 12 in. 1 yard = 3 ft. 1 rod = 5.5 yd. 1 furlong = 40 rd. 1 mile = 8 fl.

;;inch->cm:number -> number ;;to convert the unit of length from inches to cm. ;;(inch->cm 1) should produce 2.54 (define (inch->cm inch) (* inch 2.54)) ;;feet->inches:number -> number ;;to convert from feet to inches ;;(feet->inches 1) should produce 12 (define (feet->inches feet) (* feet 12)) ;;yards->feet:number -> number ;;to convert the unit of length from yards to feet. ;;(yards->feet 1) should produce 3 (define (yards->feet yard) (* yard 3)) ;;rods->yards:number -> number ;;to convert from rods to yards ;;(rods->yards 1) should produce 5.5 (define (rods->yards rods) (* rods 5.5)) ;;furlongs->rods:number->number ;;to convert from furlongs to rods ;;(furlongs 1) should produce 40 (define (furlongs->rods furlongs) (* furlongs 40)) ;;miles->furlongs:number->number ;;to convert from miles to furlongs ;;(miles->furlongs 1) should produce 8 (define (miles->furlongs miles) (* miles 8)) ;;feet->cm:number->number ;;to convert from feet to cm ;;(feet->cm 1) should produce 30.48 (define (feet->cm feet) (inch->cm (feet->inches feet))) ;;yards->cm:number->number ;;(yards->cm 1) should produce 91.44 ;;to convert from yards to cm (define (yards->cm yards) (feet->cm (yards->feet yards))) ;;rods->inches:number->number ;;to convert from rods to inches ;;(rods->inches) should produce (* 5.5 3 12)=198 (define (rods->inches rods) (feet->inches (yards->feet (rods->yards rods)))) ;;miles->feet:number->number ;;(miles->feet 1) should return 5280 (define (miles->feet miles) (yards->feet (rods->yards (furlongs->rods (miles->furlongs 1)))))