Presentation is loading. Please wait.

Presentation is loading. Please wait.

3. 条件式、 データのバリエーション プログラミング論I.

Similar presentations


Presentation on theme: "3. 条件式、 データのバリエーション プログラミング論I."— Presentation transcript:

1 3. 条件式、 データのバリエーション プログラミング論I

2 今日の内容 条件式を使い,条件に応じた計算を行う データのバリエーションとその区別
比較演算 (<,<=,>,>=,=) 条件式のキーワード: cond, else 値の性質の判定(奇数,偶数:odd?, even?) 論理演算 (and, or, not) データのバリエーションとその区別 数値、ブール値、文字列、シンボルおよびその判定

3 条件式

4 条件を判断するプログラム 異なる状況には,異なる方法で処理するプログラム ある条件の成立を判定して処理する道具立てが必要 ゲームプログラム:
物体の速度や位置はある範囲内か? エンジン制御プログラム どういう状況(温度,気圧など)であれば燃料の噴射量を増減するか? ある条件の成立を判定して処理する道具立てが必要 真(true) または偽(false)の値を持つデータのクラス: ブール値(Boolean) (または真偽値、真理値) 条件を評価する式(ブール値を返す) ブール値(真偽)に依存して異なる値を計算する式

5 比較演算 - 比較演算子の例 - 値を比較する演算子: = < > <= >= Scheme式 数式 意味
値を比較する演算子: = < > <= >= Scheme式 数式 意味 (= x y) x = y x は y と等しい (< x y) x < y x は y より小さい (> x y) x > y x は y より大きい (<= x y) x ≦ y x は y 以下 (>= x y) x ≧ y x は y 以上 注意:Schemeでは「≦」,「≧」を使うことはできない キーボードのキーで入力できない

6 C言語の場合 値を比較する演算子: == < > <= >= Cの条件式 数式 意味 x = y
値を比較する演算子: == < > <= >= Cの条件式 数式 意味 (x == y) x = y x は y と等しい (x < y) x < y x は y より小さい (x > y) x > y x は y より大きい (x <= y) x ≦ y x は y 以下 (x >= y) x ≧ y x は y 以上

7 比較演算の実行例 比較演算の結果値は、条件が成り立てば true, 成り立たなければ false となる

8 比較演算の実行例 C言語の場合 比較演算の結果値は、条件が成り立てば 1, 成り立たなければ 0 となる
printf(“%d”,(100==50)); printf(“%d”,(100==100)); 1 printf(“%d”,(5<3)); printf(“%d”,(5<5)); printf(“%d”,(5<7)); 比較演算の結果値は、条件が成り立てば 1, 成り立たなければ 0 となる

9 条件の判断 - 比較演算以外の例 - 例:奇数か(odd?)、偶数か(even?)
条件の判断 - 比較演算以外の例 - 例:奇数か(odd?)、偶数か(even?) odd? の意味:奇数ならば true (さもなければ false) even? の意味:偶数ならば true (さもなければ false) ※ 条件を判断する演算子や関数名の末尾は ? を使うことが多い ;; odd?: number -> T/F (define (odd? n) (= (remainder n 2) 1) ) ;; even?: number ->T/F (define (even? n) (= (remainder n 2) 0) int odd(int n){ return n%2; } int even(int n){ return (n%2==0); }

10 論理演算 単純な真偽判定を組合わせ、より複雑な論理的演算を行う. (and A B) A かつ B
例: (and (= x y) (< y z)) (or A B) A または B 例: (or (= x y) (< x z)) (not A) Aでない 例: (not (= x y)) 計算例: (and (= 5 5) (< 5 6)) =(and true true) = true (and (= 5 5) (< 5 5)) =(and true false) = false A B AかつB AまたはB Aでない T F

11 論理演算(C言語の場合) C言語の場合 (x==y)&&(y<z) (x==y)||(y<z) !(x==y)
単純な真偽判定を組合わせ、より複雑な論理的演算を行う. (and A B) A かつ B 例: (and (= x y) (< y z)) (or A B) A または B 例: (or (= x y) (< x z)) (not A) Aでない 例: (not (= x y)) 計算例: (and (= 5 5) (< 5 6)) =(and true true) = true (and (= 5 5) (< 5 5)) =(and true false) = false C言語の場合 (x==y)&&(y<z) (x==y)||(y<z) !(x==y)

12 条件によって結果を変える式 (define amount 3000) ;; が先に定義されてあると, ;; cond式は,0.045を返す
条件式(Conditional Expression):条件により結果を変える式 例:貯蓄口座~貯蓄残高が高いほど高い利率 (本の4.3節) $1,000以下の預金に対しては4% $5,000までの預金に対しては4.5% $5,000より多額の預金に対しては5%を払う (define amount 3000) ;; が先に定義されてあると,               ;; cond式は,0.045を返す 例: ここで amount は預金額の変数 (cond [(<= amount 1000) 0.040] [(<= amount 5000) 0.045] [(> amount 5000) 0.050])

13 (define amount 3000) ;; amountには、3000という値が割り当てられる (cond [(<= amount 1000) 0.040] ;; (<= ) ? → false [(<= amount 5000) 0.045] ;; (<= ) ? → true 0.045が返る [(> amount 5000) 0.050])

14 条件式 条件式の一般形 ...部分:任意行数のcond行(cond節とも呼ばれる)
[question answer] [question answer] または [question answer]) [else answer]) ...部分:任意行数のcond行(cond節とも呼ばれる) 各cond行: 条件部(question)と結果部(answer)からなる 条件部は変数を含む条件述語である; 結果部は条件述語の成立時に結果を計算する式

15 条件式の例 ① 1つの ② 大きな式 ③ amount の値によって結果値が変わる 複数の cond節の「条件部」は上から順に判定
上の例では①,②,③の順に判定が行われる ①が成り立てば,②,③は判定されない ②が成り立てば,③は判定されない 「条件」の並んだ順序に意味がある

16 条件の判定順序 (cond [(<= amount 1000) 0.040] [(<= amount 5000) 0.045]
一番上の行の条件 の判定から開始 yes no yes no yes この式でこの判定が no になることはあり得ない→他の書き方もある

17 else の使用例 else:「前の条件がどれも成り立たなければ」という意味 (使うときは cond 節 の並びの最後)
[(<= amount 1000) 0.040] [(<= amount 5000) 0.045] [else 0.050]) (cond [(<= amount 1000) 0.040] [(<= amount 5000) 0.045] [(> amount 5000) 0.050]) この2つは同じ計算を行う else:「前の条件がどれも成り立たなければ」という意味 (使うときは cond 節 の並びの最後) ★ else を使う方が分かりやすければそうする

18 C言語の場合 この2つは同じ計算を行う (cond [(<= amount 1000) 0.040]
[else 0.050]) (cond [(<= amount 1000) 0.040] [(<= amount 5000) 0.045] [(> amount 5000) 0.050]) この2つは同じ計算を行う if (amount<=1000) return 0.040; else if (amount<=5000) return 0.045; else return 0.050; if (amount<=1000) return 0.040; else if (amount<=5000) return 0.045; else if (amount > 5000) return 0.050;

19 条件の判定順序 (cond [(<= amount 1000) 0.040] [(<= amount 5000) 0.045]
[else ]) 一番上の行の条件 の判定から開始 yes no yes no else が評価されると必ずその結果部が選択される

20 条件式での「条件」として書けるもの 結果が true か false となるもの。例えば:
比較演算 (<,<=,>,>=,= ) の式 例: (<= amount 1000), (<= amount 5000), (> amount 5000), (= (remainder year 400) 0) 奇数,偶数のような値の性質判定 例: (odd? k), (number? k) 後述 trueまたはfalse を結果値とするような関数 例: (is-child? a) and, or, not を使った条件の組み合わせ 例:(or (= m 1) (= m 2)), (not (= a 0)) など 但し is-child? が例えば次のように定義されていること (define (is-child? age) (< age 12))

21 練習 Scheme式の中では単位は書かない (暗黙に仮定)
距離 (distance) 料金 3km まで 200円 3km 超7kmまで 250円 7km 超11kmまで 290円 11km 超15kmまで 320円 15km 超19kmまで 340円 19km 超20kmまで 360円 福岡市営地下鉄の料金は距離で決まる。距離をあらわす変数が distance だとして、対応する料金を求める cond 式を書け。 (cond [(<= distance 3) 200] .... )

22 条件式を使った条件関数 利率を求める関数:条件関数(Conditional Function)
先の例預金額を受け取りその金額に対する利率を返す。 → 条件式を用い関数定義を定式化 引数の値によって結果が変わる ⇒ 条件関数と呼ばれる (define (interest-rate amount) (cond [(<= amount 1000) 0.040] [(<= amount 5000) 0.045] [(> amount 5000) 0.050])) このような条件関数はどのようにして開発するか? amountの 値は 引数として 与えられる

23 プログラム設計法:条件関数 条件関数の開発法は? 前述のプログラム設計法を拡張 Purpose:プログラムの目的を理解、機能の概要を記述
Contract, Header, Statement: データ解析(Data Analysis)を導入: 問題が異なる状況を扱う場合→それらのすべてを識別する必要 Example:プログラムの振る舞いを「例」で記述. 状況ごとに最低でもひとつの関数例 Definition:プログラムの定義を具体化する 異なる状況の数だけの節をもったcond-式 各状況を特徴づける条件を定式化 適切な区別:あるcond節の条件がtrue →それ以前の条件はfalse 各cond-節に対して関数が何を生成すべきかを決定 Test:検査を通じた誤り(エラー)の発見

24 条件関数の開発 残高 amount から利率を求める関数 interest-rate Purpose
残高が $1000 以下ならば:利率 4% 残高が $5000 以下ならば:利率 4.5% 残高が $5000より多ければ:利率 5% Purpose ;; interest-rate : number -> number ;; 与えられた金額 amount に対する利率を求める (define (interest-rate amount) ...) 複数の状況を扱う → 場合分けのためのデータ解析

25 データ解析 この例での良い方法:数直線上の区間への対応付 利率 0.05 0.045 0.04 1000 5000 残高

26 条件関数の開発:Example 残高 amount から利率を求める関数 interest-rate
残高が $1000 以下ならば: 利率 4% 残高が $5000 以下ならば: 利率 4.5% 残高が $5000より多ければ:利率 5% Example: 状況ごとに少なくともひとつの関数例 (= (interest-rate 1000) .040) (= (interest-rate 5000) .045) (= (interest-rate 8000) .050) 注: を .040 と書いても同じ

27 条件関数の開発:本体式の定義 3つの異なる状況を扱う → 3つの場合を区別するcond節を持つ cond 式
(define (interest-rate amount) (cond [(<= amount 1000) ...] [(<= amount 5000) ...] [(> amount 5000) ...] )) amount ≦ 1000 のとき 1000<amount≦5000のとき 5000 >amount のとき まず3つの条件節内の条件部を考える

28 条件関数の開発:本体式の定義 3つの異なる状況を扱う → 3つの場合を区別するcond節を持つ cond 式
(define (interest-rate amount) (cond [(<= amount 1000) .040] [(<= amount 5000) .045] [(> amount 5000) .050] )) amount ≦ 1000 のとき 1000<amount≦5000のとき 5000 >amount のとき 次に3つの条件節内の結果値を考える

29 (interest-rate 1500) から 0.045 が得られる過程
最初の式 (interest-rate 1500) = (cond [(<= ) .040] [(<= ) .045] [(> ) .050]) [false .040] [true .045] = 0.045 interest-rate の本体 (cond [(<= amount 1000) .040] [(<= amount 5000) .045] [(> amount 5000) .050]) にamount = 1500 の置き換え (<= ) → false [false 0.040] → 消える (<= ) → true コンピュータ内部での計算 実行結果

30 条件関数の開発:Test 定義完成後は事前に考えた関数例でテストすること!
Example として場合ごとに少なくともひとつ関数例を考えた → 少なくとも以下の結果が true となるはず 例1. (= (interest-rate 1000) .040) 例2. (= (interest-rate 5000) .045) 例3. (= (interest-rate 8000) .050) 定義完成後は事前に考えた関数例でテストすること!

31 練習 月の日数 月 month を受け取り(数字)、その日数を求める関数 easy-get-num-of-days を作る。ただし閏年のことは考えない。 まず月ごとに12通りに分けて考えてみよ。 日数は3通りしかない。3つのcond節を持つ cond 式で考えよ。(比較演算と論理演算を組み合わせる)

32 記号情報

33 記号情報 Schemeの記号情報 (データは数値だけではない) シンボル: ' が前置したキーボード文字の並び
'the 'dog 'ate 'a 'chocolate 'cat! 'two^3 など 注:( ) " , などは使えない、' がなければ変数(値を持つ)。 象徴的に何かを表す不可分なデータ 目的は名字や名前、職業的肩書、命令、通知などの記号的表現 文字列: 2つの " で囲まれたキーボード文字の並び "the dog" "isn't" "made of" "chocolate" "two^3"など 文字のならび。シンボルと異なり分割できる複合データ 画像 DrRacketは画像をサポート: テキストの図7は惑星の写真を操作する関数の冒頭の例

34 種々のデータの属性判定、比較演算 データの属性判定 数値同士の比較 シンボル同士の比較 文字列同士の比較
number? boolean? symbol? string? など 数値同士の比較 < <= = >= > など シンボル同士の比較 symbol=? 文字列同士の比較 string<? string<=? string=? string>=? など

35 データの属性判定、比較演算の例 属性判定の例: 比較演算の例: (number? 5) (< 3 4) = true = true
(boolean? false) (symbol? 'hello) (symbol? "hello") = false では以下はどうだろう? (string? 'hello) (string? "hello") 比較演算の例: (< 3 4) = true (= 3 4) = false (symbol=? 'hello 'bye) = false (string=? "hello" "he") (string>? "hello" "bye") = true では以下は? (ヒント:辞書での順番) (string<? "he" "hello") (string<? "hello" "he")

36 練習問題:シンボルの条件関数 次の4種のシンボルに対応した「返答」を返すような関数 reply を作る。 入力シンボル → 答え
'GoodMorning → 'Hi 'HowAreYou → 'Fine 'GoodAfternoon → 'NeedANap 'GoodEvening → 'BoyAmITired 入力シンボル → 答え (これ以外の入力に対しては,実行エラー)

37 C言語の場合,シンボル型がない const int GoodMorning=0; const int HowAreYou=1;
const int GoodAfternoon=2; const int GoodEvening=3; などのように,最初に定義して,入力は,その定義した値にするか,文字列として扱う. #include <string.h> char grt[12]; scanf_s(“%12s”, grt,12);//VisualStudio scanf(“%s”, grt); // 標準C言語処理系 if (strcmp(grt, “GoodMroning”)==0) printf(“Hi\n”);

38 これまでの Scheme 文法:語彙を用いてプログラム(式と定義)を作る規則 Scheme も自然言語同様に語彙と文法を持つ 語彙
変数:関数と値の名前 キーワード:句読点のようなもの define, cond, else (変数には使用不可) 定数 数: 5, -5, 0.5 など ブール値: true, false 記号的:シンボル、文字列 プリミティブ演算:Scheme が最初から提供している基本的な関数 四則演算子:+, -, *, / 比較演算子:<, <=, >, >=, = 奇数か偶数かの判定:odd?, even? 論理演算子:and, or, not その他の演算子:remainder, quotient, max, min, abs, sqrt, expt, log, sin, cos, tan, asin, acos, atanなど 文法:語彙を用いてプログラム(式と定義)を作る規則 定義 関数定義 (define (関数名 変数並び) 式) 変数定義 (define 変数名 式) 変数 定数 プリミティブ演算の適用 定義した関数の適用 条件式

39 発展課題

40 課題1. うるう年の判定 西暦年 year から,うるう年であるかを求める関数 is-leap? を作る うるう年の判定法
4の倍数の年 ならうるう年、 但し, 100の倍数の年で400の倍数でない年は うるう年ではない (4の倍数だが例外) 2005年はうるう年でない(4の倍数でない) 2004年はうるう年(4の倍数) 2000年はうるう年(100の倍数で例外にも当てはまらない) 1900年はうるう年でない(4の倍数で100の倍数だが400の倍数でないので例外に相当) 年がある数の倍数かを調べるため remainderを使う

41 課題2. 曜日を求める 西暦の年,月,日から曜日を求める公式である、ツエラーの公式のプログラム zellar を作る。
課題2. 曜日を求める  西暦の年,月,日から曜日を求める公式である、ツエラーの公式のプログラム zellar を作る。 ツエラーの公式では「1年の起点 を3月とし、月は3月から14月まである」と考えている。(うるう年があるので,1年の起点を3月とする方が計算が簡単) 1月,2月は,前年の13,14月と考え、月は3から14 計算された曜日は「数字」で次の意味になる. 1 2 3 4 5 6 日曜 月曜 火曜 水曜 木曜 金曜 土曜

42 ツエラーの公式(数式表現) [(y+[y/4]+[y/400]-[y/100]+[(13m+8)/5]+d) mod 7]
ここで y: 年、 d: 日、m: 3月を起点とする月で値は3から14(1月,2月は前年の13,14月と考える) この計算の結果値が0なら日曜,1なら月曜・・・ 式中 [...] とあるのは,小数点以下切り捨て 切捨て計算には,quotientを使う modは剰余を計算。例えば mod 4 は 3 C言語では,y, m, dがint型の時, (y+(y/4)+(y/400)-(y/100)+(13*m+8)/5+d) % 7


Download ppt "3. 条件式、 データのバリエーション プログラミング論I."

Similar presentations


Ads by Google