sp-4. 条件式
1
金子邦彦
Scheme プログラミング)
URL:https://www.kkaneko.jp/pro/scheme/index.html
トライン
4-1 条件式
4-2 パソコン演習
4-3 課題
2
4-1 条件式
3
条件式を使って,より役に立つプログラムを
作れるよになる.
比較演算 <<=>>==
条件式のキーワード: cond, else
奇数,偶数の判定(odd?, even?
論理演算 and, or, not
4
演算子 意味
より小さい
<= 以下
より大きい
>= 以上
等しい
比較演算
5
比較演算
数式 意味
(= x y) x=y x is equal to y
(< x y) x<y x is less than y
(> x y) x>y x is greater than y
(<= x y)
xyx is less than and equal to y
(>= x y)
xyx is greater than and equal to y
6
比較演算では,条件が成り立て true
成り立たなければ false となる
比較演算を実行してみると
7
8
コンピュータが行っていること
コンピュータ
(Scheme 搭載)
Scheme の式
式の実行結果
例えば:
(=100 50)
を入力する
と・・・
false
が表示される
ここでは,
(define (is-child age)
(< age 12))
とい関数を作ってみた
実行結果として,
true, false の値が
得られている
関数の中で比較演算を行ってみると
9
」,「」を使ことはできない
[(amount 1000) 0.040]
これは間違い
[(<= amount 1000) 0.040]
正しくは
よくある間違い
10
(define (interest-rate amount)
(cond
[(<= amount 1000) 0.040]
[(<= amount 5000) 0.045]
[(> amount 5000) 0.050]))
この部分で
1つの大きな
amount の値によって,結果が変わってくる
条件式と呼ばれる由来
条件式の例
11
(define (interest-rate amount)
(cond
[(<= amount 1000) 0.040]
[(<= amount 5000) 0.045]
[(> amount 5000) 0.050]))
条件の並び
条件式の例
12
(define (interest-rate amount)
(cond
[(<= amount 1000) 0.040]
[(<= amount 5000) 0.045]
[(> amount 5000) 0.050]))
判定順
cond 文に並んだ複数の「条件」は,上から順に判定され
上の例では,の順に判定が行われ,
が成り立てば,は判定されな
が成り立てば,は判定されな
「条件」の並んだ順序に意味がある
条件式での判定順
13
(define (interest-rate amount)
(cond
[(<= amount 1000) 0.040]
[(<= amount 5000) 0.045]
[else 0.050]))
else とは
上記の条件がどれも成り立たなければ」とい意味
else の方が,自分にとって分かりやすければ,else を使
(define (interest-rate amount)
(cond
[(<= amount 1000) 0.040]
[(<= amount 5000) 0.045]
[(> amount 5000) 0.050]))
この2つは,結局は
同じことを行っている
else の使用例
14
15
even?
even? の意味
偶数ならば true (さもなければ false
論理演算
(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))
真,偽に関する論理的な演算を行
16
比較演算 <<=>>==
例: (<= amount 1000), (<= amount 5000), (> amount 5000),
(= (remainder year 400) 0)
奇数,偶数の判定(odd?, even?
例: (odd? k), (is-leap? k)
true, false 値を出力とするよな関数
:(is-child a)
and, or, not による組み合わ
例: (or (= m1) (= m2)), (not (= a0))
など
true, false の値をとるもの」なら,何でも書くこと
ができる
(define (is-child age)
(< age 12))
但し,is-child が例えば
次のよに定義されていること
条件式での「条件」として書けるもの
17
数値:
5, -5, 0.5 など
true, false
true, false
変数名
四則演算子:
+, -, *, /
比較演算子
<, <=, >, >=, =
奇数か偶数かの判定
odd?, even?
論理演算子
and, or, not
その他の演算子:
remainder, quotient, max, min,
abs, sqrt, expt, log, sin, cos, tan
asin, acos, atan など
括弧
(, ), [, ]
関数名
define
cond
Scheme の式の構成要素
18
4-2 パソコン演習
19
資料を見ながら,「例題」を行ってみ
各自,「課題」に挑戦する
自分のペースで先に進んで構いません
パソコン演習の進め方
20
DrScheme の起動
プログラム PLT Scheme → DrScheme
今日の演習では「Intermediate Student
に設定
Language
→ Choose Language
→ Intermediate Student
→ Execute ボタン
DrScheme の使用
21
残高 amount から利率を求める関数 interest-rate
を作り,実行する
残高が $1000 以下ならば: 4%
残高が $5000 以下ならば: 4.5%
残高が $5000より多ければ: 5%
残高を条件とする条件式を使
cond 句が登場
例題1.条件式
22
残高
利率
01000 5000
0.04
0.045
0.05
例題1.条件式
23
1. 次を「定義用インド」で,実行しなさい
入力した後に,Execute ボタンを押す
;; interest-rate: number -> number
;; to determine the interest rate
;; for the given amount
(define (interest-rate amount)
(cond
[(<= amount 1000) 0.040]
[(<= amount 5000) 0.045]
[(> amount 5000) 0.050]))
2. その後,次を「実行用インドで実行しなさい
次は,例題2に進んでください
(interest-rate 1000)
「例題1.条件式」の手順
24
まず,Scheme のプログラムを
コンピュータに読み込ませている
25
ここでは,
(interest-rate 1500)
と書いて,amount の値を
1500 設定しての実行
実行結果である「0.045」が
表示される
26
今度は,
(interest-rate 6000)
と書いて,amount の値を
6000 設定しての実行
実行結果である「0.05」が
表示される 27
interest-rate
1500 0.045
入力 出力
入力と出力
28
(define (interest-rate amount)
(cond
[(<= amount 1000) 0.040]
[(<= amount 5000) 0.045]
[(> amount 5000) 0.050]))
1つの関数
値を1つ受け取る(入力)
関数の名前
「関数である」ことを
示すキーワード
amount の値から
利率を求める(出力
interest-rate 関数
29
(define (interest-rate amount)
(cond
[(<= amount 1000) 0.040]
[(<= amount 5000) 0.045]
[(> amount 5000) 0.050]))
条件式
amount 1000 のとき
1000 amount 5000 のとき
5000 amount のとき
条件式のプログラム
30
(define (interest-rate amount)
(cond
[(<= amount 1000) 0.040]
[(<= amount 5000) 0.045]
[(> amount 5000) 0.050]))
amount 1000の意味
比較演算の例
31
(define (interest-rate amount)
(cond
[(<= amount 1000) 0.040]
[(<= amount 5000) 0.045]
[(> amount 5000) 0.050]))
判定順
cond 文に並べた条件式は,上から順に判定される
上の例では,の順に判定が行われ,
が成り立てば,は判定されない
が成り立てば,は判定されない
条件式の並んだ順序に意味がある
条件式の判定順
32
字下げ
字下げを忘れると
プログラムは動くが,読みづらい
(define (interest-rate amount)
(cond
[(<= amount 1000) 0.040]
[(<= amount 5000) 0.045]
[(> amount 5000) 0.050]))
字下げを忘れないこと
33
関数 interest-rate 例題1)について,実行結果
に至る過程を見る
(interest-rate 1500) から 0.045 に至る過程を見る
DrScheme stepper を使用する
34
例題2.ステップ実行
(define (interest-rate amount)
(cond
[(<= amount 1000) 0.040]
[(<= amount 5000) 0.045]
[(> amount 5000) 0.050]))
(interest-rate 1500)
= (cond
[(<= 1500 1000) 0.040]
[(<= 1500 5000) 0.045]
[(> 1500 5000) 0.050])
= (cond
[false 0.040]
[(<= 1500 5000) 0.045]
[(> 1500 5000) 0.050])
= (cond
[(<= 1500 5000) 0.045]
[(> 1500 5000) 0.050])
= (cond
[true 0.045]
[(> 1500 5000) 0.050])
= 0.045
1. 次を「定義用インド」で,実行しなさい
Intermediate Student で実行すること
入力した後に,Execute ボタンを押す
;; interest-rate: number -> number
;; to determine the interest rate
;; for the given amount
(define (interest-rate amount)
(cond
[(<= amount 1000) 0.040]
[(<= amount 5000) 0.045]
[(> amount 5000) 0.050]))
(interest-rate 1500)
2. DrScheme を使って,ステップ実行の様子を
確認しなさい Step ボタン,Next ボタンを使用)
理解しながら進むこと
次は,例題3に進んでください
例題1に
1行書き加え
例題1と同じ
「例題2.ステップ実行」の手順
35
(interest-rate 1500) から 0.045 が得られる過程
(interest-rate 1500)
= (cond
[(<= 1500 1000) 0.040]
[(<= 1500 5000) 0.045]
[(> 1500 5000) 0.050])
= (cond
[false 0.040]
[(<= 1500 5000) 0.045]
[(> 1500 5000) 0.050])
= (cond
[(<= 1500 5000) 0.045]
[(> 1500 5000) 0.050])
= (cond
[true 0.045]
[(> 1500 5000) 0.050])
= 0.045
最初の式
コンピュータ内部での計算
(cond
[(<= amount 1000) 0.040]
[(<= amount 5000) 0.045]
[(> amount 5000) 0.050])
amount = 1500 が代入される
実行結果
(<= 1500 1000) false
[false 0.040] 消える
(<= 1500 5000) true
36
(interest-rate 1500) から 0.045 が得られる過
(interest-rate 1500)
= (cond
[(<= 1500 1000) 0.040]
[(<= 1500 5000) 0.045]
[(> 1500 5000) 0.050])
= (cond
[false 0.040]
[(<= 1500 5000) 0.045]
[(> 1500 5000) 0.050])
= (cond
[(<= 1500 5000) 0.045]
[(> 1500 5000) 0.050])
= (cond
[true 0.045]
[(> 1500 5000) 0.050])
= 0.045
これは,
(define (interest-rate amount)
(cond
[(<= amount 1000) 0.040]
[(<= amount 5000) 0.045]
[(> amount 5000) 0.050]))
amount 1500 で置き換えたもの
37
month から,日数を求めるプログラ
easy-get-num-of-days を書く.ここ
では、年のことは考えない
比較演算と論理演算を組み合わせる
例題3.月の日数
38
1. 次を「定義用インド」で,実行しなさい
(define (easy-get-num-of-days month)
(cond
[(= month 2) 28]
[(or (= month 4)
(= month 6)
(= month 9)
(= month 11)) 30]
[else 31]))
2. その後,次を「実行用インド」で実行しなさい
次は,例題4に進んでください
(easy-get-num-of-days 1)
(easy-get-num-of-days 2)
(easy-get-num-of-days 3)
(easy-get-num-of-days 4)
「例題3.月の日数」の手順
39
まず,Scheme のプログラムを
コンピュータに読み込ませている
40
ここでは,
(easy-get-num-of-days 1)
と書いて,month の値を 1
に設定しての実行
実行結果である「31」が
表示される
41
easy-get-num-of-days
131
入力 出力
入力は
1つの数値
出力は
1つの数値
入力と出力
42
(define (easy-get-num-of-days month)
(cond
[(= month 2) 28]
[(or (= month 4)
(= month 6)
(= month 9)
(= month 11)) 30]
[else 31])) 値を1つ受け取る(入力)
関数の名前
「関数である」ことを
示すキーワード
easy-get-num-of-days 関数
43
例題4.ステップ実行
関数 easy-get-num-of-days (例題3)につ
いて,実行結果に至る過程を見る
(easy-get-num-of-days 1) から 31 に至る過程を見
DrScheme stepper を使用する
(define (easy-get-num-of-days month)
(cond
[(= month 2) 28]
[(or (= month 4)
(= month 6)
(= month 9)
(= month 11)) 30]
[else 31])) 44
1. 次を「定義用インド」で,実行しなさい
Intermediate Student で実行すること
入力した後に,Execute ボタンを押す
(define (easy-get-num-of-days month)
(cond
[(= month 2) 28]
[(or (= month 4)
(= month 6)
(= month 9)
(= month 11)) 30]
[else 31]))
(easy-get-num-of-days 1)
2. DrScheme を使って,ステップ実行の様子を
確認しなさい Step ボタン,Next ボタンを使用)
理解しながら進むこと
次は,例題5に進んでください
例題3に
1行書き加える
例題3と同じ
「例題4.ステップ実行」の手順
45
(easy-get-num-of-days 1) から 31 が得られる過程 (1/3)
(easy-get-num-of-days 1)
= (cond
[(= 1 2) 28]
[(or (= 1 4)
(= 1 6)
(= 1 9)
(= 1 11)) 30]
[else 31]))
= (cond
[false 28]
[(or (= 1 4)
(= 1 6)
(= 1 9)
(= 1 11)) 30]
[else 31]))
= (cond
[(or (= 1 4)
(= 1 6)
(= 1 9)
(= 1 11)) 30]
[else 31]))
最初の式
コンピュータ内部での計算
(cond
[(= month 2) 28]
[(or (= month 4)
(= month 6)
(= month 9)
(= month 11)) 30]
[else 31]))
month = 1 が代入される
(= 1 2) → false
[false 0.040] 消える
46
(easy-get-num-of-days 1) から 31 が得られる過程 (1/3)
(easy-get-num-of-days 1)
= (cond
[(= 1 2) 28]
[(or (= 1 4)
(= 1 6)
(= 1 9)
(= 1 11)) 30]
[else 31]))
= (cond
[false 28]
[(or (= 1 4)
(= 1 6)
(= 1 9)
(= 1 11)) 30]
[else 31]))
= (cond
[(or (= 1 4)
(= 1 6)
(= 1 9)
(= 1 11)) 30]
[else 31]))
これは,
(define (easy-get-num-of-days month)
(cond
[(= month 2) 28]
[(or (= month 4)
(= month 6)
(= month 9)
(= month 11)) 30]
[else 31]))
month 1 で置き換えたもの 47
(easy-get-num-of-days 1) から 31 が得られる過程 (2/3)
= (cond
[(or false
(= 1 6)
(= 1 9)
(= 1 11)) 30]
[else 31]))
= (cond
[(or (= 1 9)
(= 1 11)) 30]
[else 31]))
= (cond
[(or false
(= 1 11)) 30]
[else 31]))
= (cond
[(or (= 1 11)) 30]
[else 31]))
= (cond
[(or false) 30]
[else 31])) コンピュータ内部での計算
(= 1 4) → false
false → 消える
false → 消える
(= 1 9)false
(= 1 11) → false 48
(easy-get-num-of-days 1) から 31 が得られる過程 (3)
= (cond
[false 30]
[else 31]))
= 31
コンピュータ内部での計算
(or false) → false
出力結果
49
西暦年 year から,年であるかを
求める関数 is-leap? を作り,実行する
年の判定のために,比較演算と論理演算を組み合
わせる
西暦年が 4, 100, 400 の倍数であるかを調べるために
remainder を使
例) 2001 年でない
2004 年である
例題5.年の判定
50
年とは: 2月が29日まである年
年は400年に97回で,1年の平均日数
365.2422
年の判定法
年数が4の倍数の年
但し, 100の倍数の年で400の倍数でない年
年ではない
(4の倍数なのだが例外と
する)
(例) 2008年: 年(4の倍数)
2004年: 年(4の倍数)
2000年: 年(4の倍数)
1900年: 年ではな
(100の倍数だが400の倍数でない
1800年: 年ではない
(100の倍数だが400の倍数でない
グレゴリオ暦での
51
(or (= (remainder year 400) 0) (and (not (= (remainder year 100) 0)) (= (remainder year 4) 0)))
400の倍数である 100の倍数でない 4の倍数である
かつ
または
年の判定式
52
1. 次を「定義用インド」で,実行しなさい
(define (is-leap? year)
(cond
[ (or (= (remainder year 400) 0)
(and (not (= (remainder year 100) 0))
(= (remainder year 4) 0))) true]
[else false]))
2. その後,次を「実行用ンド」で実行しなさい
次は,例題6に進んでください
(is-leap? 2004)
(is-leap? 2005)
「例題5.年の判定」の手順
53
まず,Scheme のプログラムを
コンピュータに読み込ませている
54
ここでは,
(is-leap? 2004)
と書いて,year の値を 2004
に設定しての実行
実行結果である「true」が
表示される
55
今度は,
(is-leap? 2005)
と書いて,year の値を 2005
に設定しての実行
実行結果である「false」が
表示される
56
is-leap?
2004 true
入力 出力
出力は
true あるいは false
入力と出力
57
(define (is-leap? year)
(cond
[(or (= (remainder year 400) 0)
(and (not (= (remainder year 100) 0))
(= (remainder year 4) 0))) true]
[else false]))
値を1つ受け取る(入力)
関数の名前
「関数である」ことを
示すキーワード
year の値から true
あるいは false を求める(出力)
is-leap? 関数
58
59
年の判定
(define (is-leap? year)
(cond
[ (or (= (remainder year 400) 0)
(and (not (= (remainder year 100) 0))
(= (remainder year 4) 0))) true]
[else false]))
1つの条件式
関数 is-leap? 例題5)について,実行結
果に至る過程を見る
(is-leap? 2004) から true に至る過程を見る
DrScheme stepper を使用する
60
例題6.ステップ実行
(define (is-leap? year)
(cond
[ (or (= (remainder year 400) 0)
(and (not (= (remainder year 100) 0))
(= (remainder year 4) 0))) true]
[else false]))
1. 次を「定義用インド」で,実行しなさい
Intermediate Student で実行すること
入力した後に,Execute ボタンを押す
(define (is-leap? year)
(cond
[ (or (= (remainder year 400) 0)
(and (not (= (remainder year 100) 0))
(= (remainder year 4) 0))) true]
[else false]))
(is-leap? 2004)
2. DrScheme を使って,ステップ実行の様子を
確認しなさい Step ボタン,Next ボタンを使用)
理解しながら進むこと
次は,例題7に進んでください
例題5に
1行書き加え
例題5
と同じ
「例題6.ステップ実行」の手順
61
(is-leap? 2004) から true が得られる過程 (1/3)
(is-leap? 2004)
= (cond
[(or (= (remainder 2004 400) 0)
(and (not (= (remainder 2004 100) 0))
(= (remainder 2004 4) 0))) true]
[else false]))
= (cond
[(or (= 4 0)
(and (not (= (remainder 2004 100) 0))
(= (remainder 2004 4) 0))) true]
[else false]))
= (cond
[(or false
(and (not (= (remainder 2004 100) 0))
(= (remainder 2004 4) 0))) true]
[else false]))
最初の式
コンピュータ内部での計算
(cond
[(or (= (remainder year 400) 0)
(and (not (= (remainder year 100) 0))
(= (remainder year 4) 0))) true]
[else false])
year = 2004 が代入される
(remainder 2004 400) → 4
(= 4 0) → false
62
(is-leap? 2004) から true が得られる過程 (1/3)
(is-leap? 2004)
= (cond
[(or (= (remainder 2004 400) 0)
(and (not (= (remainder 2004 100) 0))
(= (remainder 2004 4) 0))) true]
[else false]))
= (cond
[(or (= 4 0)
(and (not (= (remainder 2004 100) 0))
(= (remainder 2004 4) 0))) true]
[else false]))
= (cond
[(or false
(and (not (= (remainder 2004 100) 0))
(= (remainder 2004 4) 0))) true]
[else false]))
これは,
(define (is-leap? year)
(cond
[(or (= (remainder year 400) 0)
(and (not (= (remainder year 100) 0))
(= (remainder year 4) 0))) true]
[else false]))
year 2004 で置き換えたもの 63
(is-leap? 2004) から true が得られる過程 (2/3)
= (cond
[(or (and (not (= (remainder 2004 100) 0))
(= (remainder 2004 4) 0))) true]
[else false]))
= (cond
[(or (and (not (= 4 0))
(= (remainder 2004 4) 0))) true]
[else false]))
= (cond
[(or (and (not false)
(= (remainder 2004 4) 0))) true]
[else false]))
= (cond
[(or (and true
(= (remainder 2004 4) 0))) true]
[else false])) コンピュータ内部での計算
(remainder 2004 100) → 4
(= 4 0) → false
(not false) → true
(or false ) → (or )
64
(is-leap? 2004) から true が得られる過程 (3/3)
= (cond
[(or (and (= (remainder 2004 4) 0))) true]
[else false]))
= (cond
[(or (and (= 0 0))) true]
[else false]))
= (cond
[(or (and true)) true]
[else false]))
= (cond
[(or true) true]
[else false]))
= (cond
[true true]
[else false]))
= true
コンピュータ内部での計算
実行結果
(and true ) → (and )
(remainder 2004 4) → 0
(= 0 0) → true
(and true) → true
(or true) → true
65
ツエラーの公式 zellar を作り,実行する
ツエラーの公式とは: 西暦の年,月,日から曜日を
求める公式
年: 西暦の年
月: 3から14
計算された曜日は「数字」.次の意味になる.
0:日曜日
1:月曜日
2:火曜日
3:水曜日
4:木曜日
5:金曜日
6:土曜日
66
例題7.曜日を求める
ツエラーの公式では,「1年の起点 3
とし、月は3月から14月まである」と考え
ている
1月,2月は,前年の1314月と考える
こと
年があるので,1年の起点を3月とす
る方が計算が簡単
ツエラーの公式での起点
67
[(y+[y/4]+[y/400]-[y/100]+[(13m+8)/5]+d) mod 7]
y:
m: 3月を起点とする月(3から14まで)
1月,2月は,前年1314月と考える
d:
この値が0なら日曜,1なら月曜・・・
[]」とあるのは,小数点以下切り捨て
modとあるのは剰余.例えば 2003 mod 4
ツエラーの公式
68
69
remainder
remainder の意味
割り算の余りを求める
(remainder x y) は,ツエラーの公式の x mod y に対応
70
quotient
quotient の意味
整数の割り算の商を求める
(quotient x y) ,ツエラーの公式の [x / y] に対応
[(y+[y/4]+[y/400]-[y/100]+[(13m+8)/5]+d) mod 7]
(define (zellar_f y m d)
(remainder
(+ y
(quotient y4)
(quotient y400)
(- (quotient y100))
(quotient (+ (* 13 m) 8) 5)
d)
7))
;; zellar : number number number -> number
;; to determine youbi (the day of the week) from year, month, and day.
;; The result is 0 ... 6 meaning 0 is Sunday, 1 Monday, and so on
(define (zellar y m d)
(cond
[(or (= m1) (= m2)) (zellar_f (- y1) (+ m12) d)]
[else (zellar_f y m d)]))
ツエラーの公式のプログラム
71
4-3 課題
72
次のよな関数を作りなさい
cond を使こと
50グラム以下なら 120
75グラム以下なら 140
100グラム以下な 160
150グラム以下な 200
課題1
73
ここにあるのは「間違い」の例です.同じ間
違いをしないこと
(define (decide price w)
... 以下省略
1.関数名の付け方の間違い
decice price」では無く,
decide_price」のよに1単語で書くこと
2.をプログラム中に使ことはできない
代わりに,<=, >= を使こと
課題のヒント
74
ある年 yのある月 m の日数を返す
関数 get-num-of-days を作成し,実
行結果を報告しなさい
easy-get-num-of-days(授業の例題
3)と, is-leap? (授業の例題5)
を利用しなさい
年の2月についても,正しい
日数を求めること
課題2
75
次の値を求める関数 foo2 を書きなさい
X mod 7 は,X 7 で割った時の余り(剰余).
例えば 2003 mod 4 3 である.
define remainder を使いなさい.
[(20x + 8) / 7] mod 10
課題3
76