371 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-5. リスト,シンボル,文字 列 (Scheme プログラミング) URL: https://www.kkaneko.jp/pro/scheme/index.html 金子邦彦 1
アウトライン 5-1 リストとは 5-2 Scheme プログラムでのリストの記法 list 句 5-3 リストに関する演算子 first, rest, empty?, length, list-ref, append 5-4 数字,シンボル,文字列を含むリスト 5-5 パソコン演習 5-6 課題 2
5-1 リストとは 3
リストとは 15 8 6 32 23 データの並び データに順序がある 4
5-2 Scheme でのリストの表記 5
Scheme でのリストの記法 リストであることを 本体の部分 示すキーワード (list 15 8 6 32 23) これ自体が1つの式 6
first と rest 15 first 8 6 32 23 rest • first • 先頭のこと • rest • 先頭を取り除いた残り • rest もまたリスト 例) 上のリストの rest の rest の rest の first は: 2 3 7
empty • empty は「空リスト」を表す特別な記号 • rest との関係 • リストの長さが1の時には,empty 例) (rest (list 15)) = empty 8
first, rest に関する実行エラー • 要するに,「空でないリスト」だけ,first, rest が実行できる 空で無い 空リス 数値 リスト ト first OK 実行エ 実行エ ラー ラー rest OK 実行エ 実行エ ラー ラー 9
first, rest に関する実行エラーの例 DrScheme の実行画面 10
empty? • empty? は,リストが空リストであるかを調べる • empty? の意味: – 「空リスト」ならば true (さもなければ false) 11
リストに関するキーワード • リストに関する演算子 • first リストの先頭の要素 (例) (first (rest (rest a-list))) • rest リストから先頭の要素を除いた残り (例) (rest a-list) • empty? リストが空リストであるか調べる (例) (empty? a-list) • list • list リストを記述するためのキーワード (例) (list 15 8 6 32 23) 12
5-3 リストに関する演算子 13
リストに関する演算子 • length リストの要素の個数 • list-ref リストのn番目の要素(先頭は0番目) • append リストの連結 14
length リストで無い場合には 実行エラーとなる • length の意味: – リストの要素の個数 15
list-ref 指定した番号が大きすぎる と実行エラーとなる リストで無い場合には 実行エラーとなる • list-ref の意味: – リストのn番目の要素(先頭は0番目) 16
append リストで無い場合には 実行エラーとなる • append の意味: – リストの連結 17
5-4 数字,シンボル,文字列を含むリ スト 18
シンボル • 「記号」や「単語」を表す • カッコ、ダブルクオーテーションマーク,空白,コン マはシンボルとして使えない (例) 'the 'a 'cat! 'tow^3 'and%so%on • 「'」が無いと,変数名の意味になる 19
symbol=? の意味 • symbolの比較演算子 (symbol=? 'Hello 'Hello) → true (symbol=? 'Hello 'Hallo) → false 20
よくある間違い • 本当は「symbol=?」と書くべき. しかし,「=」と書いている. • 実行すると,エラー メッセージが出る 21
文字列 • 文字列: 「"」で囲む "This is a string" • 空白文字なども「文字列」として使え る 22
さまざまな比較演算 • 数値同士の比較 <, <=, =, >=, > など • シンボル同士の比較 symbol=? など • 文字列同士の比較 string<?, string<=?, string=?, string>=?, string>? など 23
Schemeの式 • atomic 式 • 数値 • true, false 値 • 変数名 • シンボル • 文字列 • empty, など • 括弧の入った式 (compound) (演算子 式の並び) (関数名 式の並び) (cond [(条件式) 式] ... ) (list 式の並び) • 関数の定義式 (define (関数名 変数の並び) 式) など のパターン のパターン 24
Scheme の式 • 数値: • 括弧 • (, ), [, ] • 関数名 • • • • • • • • • 5, -5, 0.5 など true, false 値 true, false シンボル,文字列 変数名 empty 四則演算子: +, -, *, / 比較演算子 <, <=, >, >=, = 奇数か偶数かの判定 odd?, even? 論理演算子 and, or, not リストに関する演算子 first, rest, empty?, length, list-ref, append その他の演算子: remainder, quotient, max, min, abs, sqrt, expt, log, sin, cos, tan asin, acos, atan など • define • cond • list 25
5-5 パソコン演習 26
パソコン演習の進め方 • 資料を見ながら,「例題」を行ってみる • 各自,「課題」に挑戦する • 各自で自習 + 巡回指導 • 自分のペースで先に進んで構いません 27
DrScheme の使用 • DrScheme の起動 プログラム • → PLT Scheme → DrScheme 今日の演習では「Intermediate Student」 に設定 Language → Choose Language → Intermediate Student → Execute ボタン 28
例題1.リストの式 • リストの式を書く • リストの式を書くために 「list」 を使う 15 8 6 32 23 29
「例題1.リストの式」の手順 1. 次の式を「実行用ウインドウ」で, 実行しなさい (list 15 8 6 32 23) ☆ 次は,例題2に進んでください 30
実行結果の例 「(list 15 8 6 32 23)」 を入力すると 「(list 15 8 6 32 23)」 と表示される 31
コンピュータが行っていること Scheme の式 (list 15 8 6 32 23) を入力する と・・・ コンピュータ (Scheme 搭載) 式の実行結果 (list 15 8 6 32 23) がそのまま表示される 32
例題2.リストの first と rest • リスト (list 15 8 6 32 23) に対して, first と rest を実行する 例) 15 first 8 6 32 23 rest 33
「例題2.リストの first と rest」の手 順 1. 次の式を「実行用ウインドウ」で,実行し なさい (first (list 15 8 6 32 23)) (rest (list 15 8 6 32 23)) ☆ 次は,例題3に進んでください 34
実行結果の例 first の実行結果 restの実行結果 35
first Scheme の式 (first (list 15 8 6 32 23)) を入力すると・・・ コンピュータ (Scheme 搭載) 式の実行結果 15 が表示される リストの先頭の要素 36
rest Scheme の式 (rest (list 15 8 6 32 23)) を入力すると・・・ コンピュータ (Scheme 搭載) 式の実行結果 (list 8 6 32 23) が表示される リストから先頭の要素を 37 除いた残り
例題3.リストの first と rest • 要素が1つしか無いリスト (list 15) に対して,first と rest を実行する 例) 15 empty first rest 38
「例題3.リストの first と rest」の手 順 1. 次の式を「実行用ウインドウ」で,実行 しなさい (first (list 15)) (rest (list 15)) ☆ 次は,例題4に進んでください 39
実行結果の例 first の実行結果 restの実行結果 40
first Scheme の式 (first (list 15)) を入力すると・・・ コンピュータ (Scheme 搭載) 式の実行結果 15 が表示される リストの先頭の要素 41
rest Scheme の式 (rest (list 15)) を入力すると・・・ コンピュータ (Scheme 搭載) 式の実行結果 empty が表示される リストから先頭の要素を 42 除いた残り
例題4.append • リストをつなげる関数 append を使ってみる • append は Scheme が備えている関数 43
「例題4.append 」の手順 1. 次の式を「実行用ウインドウ」で,実行 しなさい (append (list 1 2) (list 3 4)) (append (list 1 2) (list 3 4) (list 5 6)) (append (list 1 2) 3 (list 4 5)) ☆ 次は,例題5に進んでください 44
2つのリストを併合 3つのリストを併合 リストでないものは 併合できない 45
例題5.リストの基本操作 • リストの3番目の要素を得る関数 element3 を作り,実行する • first, rest の組み合わせ 例) 15 8 6 3番目 32 23 46
リストの基本操作 • リストの3番目 = リストの rest の rest の first 例) 15 8 rest 6 32 23 first rest 47
「例題5.リストの基本操作」の手順 1. 次を「定義用ウインドウ」で,実行しなさい • 入力した後に,Execute ボタンを押す (define (element3 a-list) (first (rest (rest a-list)))) 2. その後,次を「実行用ウインドウ」で実行しなさい (element3 (list 1 2 3 4)) (element3 (list 15 8 6 32 23)) ☆ 次は,例題6に進んでください 48
まず,Scheme のプログラムを コンピュータに読み込ませている 49
これは, (element3 (list 15 8 6 32 23)) と書いて,a-list の値を (list 15 8 6 32 23) に設定しての実行 実行結果である「6」が 表示される 50
入力と出力 (list 15 8 6 32 23) 6 element3 入力 出力 51
element3 関数 「関数である」ことを 示すキーワード 関数の名前 (define (element3 a-list) (first (rest (rest a-list)))) 値を1つ受け取る(入力) a-list の値から 3番目の要素を求める(出力) 52
(element3 (list 15 8 6 32 23)) から6が得られる過程 (element3 (list 15 8 6 32 23)) 最初の式 = (first (rest (rest (list 15 8 6 32 23)))) (first (rest (rest a-list))) に a-list = (list 15 8 6 32 23) が 代入される = (first (rest (list 8 6 32 23))) = (first (list 6 32 23)) =6 (rest (list 15 8 6 32 23)) → (list 8 6 32 23) (rest (list 8 6 32 23)) → (list 6 32 23) コンピュータ内部での計算 実行結果 53
(element3 (list 15 8 6 32 23)) から6が得られる過程 (element3 (list 15 8 6 32 23)) = (first (rest (rest (list 15 8 6 32 23)))) = (first (rest (list 8 6 32 23))) これは, (define (element3 a-list) = (first (list 6 32 23)) (first (rest (rest a-list)))) = 6 の a-list を (list 15 8 6 32 23) で置き換えたも の 54
関数 element3 について • リストの長さが2以下の時には,「エラーメッ セージ」が表示される 例) (element3 (list 1 2)) → エラーメッセージが表示される 55
これは, (element3 (list 1 2)) と書いて,a-list の値を (list 1 2) に設定しての実行 エラーメッセージが 表示される 56
(element3 (list 1 2)) から 実行エラーに至る過程 (element3 (list 1 2)) 最初の式 = (first (rest (rest (list 1 2))) (first (rest (rest a-list))) に a-list = (list 1 2) が 代入される = (first (rest (list 2))) (rest (list 1 2)) → (list 2) = (first empty) (rest (list 1)) → empty コンピュータ内部での計算 → 「空リスト empty に対して first を実行できない」 という決まりがあるので,実行エラー 57
例題6.シンボル • x の値から,3種類のシンボル('Cold, 'Warm, 'Hot)のどれかを出力する関数 judge を作り,実 行する x ≦ 20 → 'Cold 20 < x ≦ 30 → 'Warm 30 < x → 'Hot シンボル 58
「例題6.シンボル」の手順
1. 次を「定義用ウインドウ」で,実行しなさい
•
入力した後に,Execute ボタンを押す
;;judge: number -> symbol
(define (judge x)
(cond
[(<= x 20) 'Cold]
[(and (< 20 x) (<= x 30)) 'Warm]
[(< 30 x) 'Hot]))
2. その後,次を「実行用ウインドウ」で実行しなさい
(judge 15)
(judge 20)
(judge 25)
☆
次は,例題7に進んでください
59
まず,Scheme のプログラムを コンピュータに読み込ませている 60
ここでは, (judge 15) と書いて,x の値を 15 に設定しての実行 実行結果である「'Cold」が 表示される 61
入力と出力 x の値: 15 'Cold judge 入力 入力は 1つの数値 出力 出力は 1つのシンボル 62
judge 関数 「関数である」ことを 関数の名前 示すキーワード ;; judge: number -> symbol (define (judge x) (cond [(<= x 20) 'Cold] [(and (< 20 x) (<= x 30)) 'Warm] [(< 30 x) 'Hot])) 値を1つ受け取る(入力) 63
例題7.数字かシンボルを出力 • x の値から,数字あるいはシンボルを出力する関 数 ast を作り,実行する • x > 0 ならば: x の値を出力する • x ≦ 0 ならば: 「'*」を出力する 64
「例題7.数値かシンボルを出力」の手順 1. 次を「定義用ウインドウ」で,実行しなさい • 入力した後に,Execute ボタンを押す (define (ast x) (cond [(> x 0) x] [else '*])) 2. その後,次を「実行用ウインドウ」で実行しなさい (ast 10) (ast 0) (ast -10) ☆ 次は,例題8に進んでください 65
まず,Scheme のプログラムを コンピュータに読み込ませている 66
ここでは, (ast 10) と書いて,x の値を 10 に設定しての実行 実行結果である「10」が 表示される 67
入力と出力 x の値: 10 15 ast 入力 入力は 1つの数値 出力 出力は 1つの数値 あるいはシンボル 68
ast 関数 「関数である」ことを 関数の名前 示すキーワード (define (ast x) (cond [(> x 0) x] [else '*])) 値を1つ受け取る(入力) 69
例題8.シンボル • 次の4種のシンボルから,「答え」を返すような 関数 reply を作り,実行する 'GoodMorning → 'HowAreYou → 'GoodAfternoon → 'GoodEvening → 答え 'Hi 'Fine 'NeedANap 'BoyAmITired これ以外の入力に対しては,実行エラー 70
「例題8.シンボル」の手順 1. 次を「定義用ウインドウ」で,実行しなさい • 入力した後に,Execute ボタンを押す ;;reply: symbol -> symbol ;;to determine a reply for the greeting s (define (reply s) (cond [(symbol=? 'GoodMorning s) 'Hi] [(symbol=? 'HowAreYou s) 'Fine] [(symbol=? 'GoodAfternoon s) 'NeedANap] [(symbol=? 'GoodEvening s) 'BoyAmITired])) 2. その後,次を「実行用ウインドウ」で実行しなさい (reply 'GoodMorning) (reply 'Hello) ☆ 次は,課題に進んでください 71
まず,Scheme のプログラムを コンピュータに読み込ませている 72
ここでは, (reply 'GoodMorning) と書いて,x の値を 'GoodMorning に設定しての実行 実行結果である「'Hi」が 表示される 73
ここでは, (reply 'Hello) と書いて,x の値を 'Hello に設定しての実行 実行エラーが 発生する 74
入力と出力 x の値: 'GoodMorning 'Hi reply 入力 入力はシンボル 出力 出力はシンボル 75
reply 関数 ;; reply: symbol -> symbol ;; to determine a reply for the greeting s (define (reply s) (cond [(symbol=? 'GoodMorning s) 'Hi] [(symbol=? 'HowAreYou s) 'Fine] [(symbol=? 'GoodAfternoon s) 'NeedANap] [(symbol=? 'GoodEvening s) 'BoyAmITired])) 76
よくある間違い • 本当は「symbol=?」と書くべき. しかし,「=」と書いている. • 実行すると,エラー メッセージが出る 77
条件式の判定順 (define (reply s) 判定順 (cond ① [(symbol=? 'GoodMorning s) 'Hi] ② [(symbol=? 'HowAreYou s) 'Fine] ③ [(symbol=? 'GoodAfternoon s) 'NeedANap] ④ [(symbol=? 'GoodEvening s) 'BoyAmITired])) • cond 文に並べた条件式は,上から順に判定され る 上の例では,①,②,③,④の順に判定が行われ, ①が成り立てば,②,③,④は判定されない • 条件式の並べ方に意味がある 78
(reply 'GoodMorning) から 'Hi が得られる過程 (reply 'GoodMorning) = (cond [(symbol=? 'GoodMorning 'GoodMorning) 'Hi] [(symbol=? 'HowAreYou 'GoodMorning) 'Fine] [(symbol=? 'GoodAfternoon 'GoodMorning) 'NeedANap] [(symbol=? 'GoodEvening 'GoodMorning) 'BoyAmITired]) = (cond [true 'Hi] [(symbol=? 'HowAreYou 'GoodMorning) 'Fine] [(symbol=? 'GoodAfternoon 'GoodMorning) 'NeedANap] [(symbol=? 'GoodEvening 'GoodMorning) 'BoyAmITired]) = 'Hi 79
(reply 'GoodMorning) から 'Hi が得られる過程 (reply 'GoodMorning) = (cond [(symbol=? 'GoodMorning 'GoodMorning) 'Hi] [(symbol=? 'HowAreYou 'GoodMorning) 'Fine] [(symbol=? 'GoodAfternoon 'GoodMorning) 'NeedANap] [(symbol=? 'GoodEvening 'GoodMorning) 'BoyAmITired]) = (cond これは, [true 'Hi] (cond [(symbol=? 'HowAreYou 'GoodMorning) 'Fine] [(symbol=? 'GoodMorning s) 'Hi] [(symbol=? 'GoodMorning) 'NeedANap] [(symbol=?'GoodAfternoon 'HowAreYou s) 'Fine] [(symbol=? 'GoodMorning) 'BoyAmITired]) = [(symbol=?'GoodEvening 'GoodAfternoon s) 'NeedANap] 'Hi [(symbol=? 'GoodEvening s) 'BoyAmITired]) の s を 'GoodMorning で置き換えたもの 80
5-6 課題 81
課題1 実行結果を報告しなさい • • • 「DrScheme の実行用ウインドウ」で実行して, 実行結果を報告しなさい 「エラー」が出た場合には,「エラー」と記入 すること (list 1) (list 1 2) (list 1 2 3) (first (list ...)) の実行結果 (rest (list ...)) の実行結果 (first (rest (list ...))) の実 行結果 (first (rest (rest(list ...)))) の実行結果 82
課題2 • 最高気温 high と最低気温 low から,真夏日, 夏日,冬日,真冬日を判定する関数 summerwinter-day を作成し,実行結果を報告しなさ い • "Tropical Day" (真夏日,1日の最高気温が30度以上の日) • "Summer Day" (夏日,1日の最高気温が25度以上の日) • "Frost Day" (冬日,1日の最低気温が0度未満の日) • "Ice Day" (真冬日,1日の最高気温が0度未満の日) 83
課題3 • ある年 y のある月 m のある日 d が 存在するかを調べ,存在すれば d を,存在しなければシンボル「'*」 を返す関数を作成し,実行結果を 報告しなさい • 例えば, 2004 10 10 ⇒ 10 を出力 2004 10 0 ⇒ '* を出力 2004 10 32 ⇒ '* を出力 84