プログラムを作る準備

プログラムを作るときに必ず必要なことについてまとめる。

プログラムを作るには

Emacs で Ctrl-x Ctrl-f (Find file) する。 ミニバッファに

Find file:˜/Ruby/プログラム.rb

としリターン。すでに作られたファイルが読みこまれるか、 新しいファイルができる。 Ruby 言語で書くプログラムの先頭には、


#!/usr/koeki/bin/ruby

と書く。

プログラムを実行するには

実行するには Kterm で

%./プログラム.rb[˜/Ruby]

とする。Kterm の右横に [˜/Ruby] が表示されているか確認せよ。 表示されていない場合は

%cdどこか他の directory に移動している場合もありうるので $HOME に戻る
% cd Ruby[˜/]

すること。

%./プログラム.rb 
zsh: アクセス権がありません。: ./プログラム.rb

と表示された場合は、

%chmod +x プログラム.rb

して再度実行してみること。これでも実行されない場合、 プロンプトでインタプリタを指定して実行してみよう。

%ruby プログラム.rb

これで実行できる場合、 始めの一行目のつづりが間違っているか、 あるいは二行目から書きはじめてしまった場合のどちらかである。

反復計算の構造

前回のプログラム while_meta.rb の反復部分を見てみよう。


while waist < waistmax
waist *= 1.04 printf("%d 年後 \t %d [cm] \n", year += 1, waist)
end

このプログラムでは、 ある変数 waist に対して、始めに初期値 waist0 を決め、 ある一定の割合で増やすが、その変数には上限 waistmaxがあり、 計算が止まるようになっている。この反復計算には、 while -- end を使った。


while いつ終えるか
変数をどのように変化させるか
end

であった。 また、変数の値を掛算して増やしたり足算して増やしたりする場合には、


変数 *= 掛ける割合
変数 += 加える数

であった。

入力した値をプログラムで使おう

前回はあらかじめ値を決めた上で、それを計算させ、 限界が来たら止まるプログラムを作った。 今回は、ユーザが値を入力し、終了を知らせ、結果を出力させるプログラムを作る。

入力の読み取り

入力の読み取りには gets method を使う。 gets_parrot.rb


#!/usr/koeki/bin/ruby

STDERR.print("名前を入力すると挨拶します\n")
STDERR.print("名前をどうぞ: ")

name = gets

k = 0
while k < 3

STDERR.printf("ルビオウム: %sさんオハヨウ\n",name) k += 1
end

method の解説は以下のとおり。

gets 入力されたデータをとりこむ method
STDERR.print 標準エラー出力で printf を実行する

printf の前に . がある。これは method が 2 つつながっているという意味である。

ルビオウムの返事は入力した場所に出力させたいので、 Kterm に出力するよう明示した。

chmod し、実行してみると、困ったことが起きている。 結果は次項

文字の取り込まれかた

gets method だけでは入力したときに、 ユーザが入力終了を知らせるために使った改行文字までも取り込んでいるため、 表示も改行つきになってしまっている。

%./gets_parrot.rb
名前を入力すると挨拶します
名前をどうぞ: Rubio
ルビオウム: Rubio
さんオハヨウ
ルビオウム: Rubio
さんオハヨウ
ルビオウム: Rubio
さんオハヨウ

ユーザが入力するとは、どのようなことか、思い出そう。 ユーザは、名前を聞かれたので、 名前プラス改行文字 を入力する。このときプログラムはこのデータを変数 name に代入してしまう。 改行文字を取り除くには、 chomp method を用いる。 gets_parrot.rb


name = gets.chomp

と変更し、実行しなおしてみよう。

%./gets_parrot.rb
名前を入力すると挨拶します
名前をどうぞ: Rubio
ルビオウム: Rubioさんオハヨウ
ルビオウム: Rubioさんオハヨウ
ルビオウム: Rubioさんオハヨウ

ここで意味をまとめておこう。

chomp
改行文字の有無を調べる
.
method 1.method 2 として、いっしょに動作を行うときに用いる
変数 = gets.chomp
ユーザの入力した文字を取ってきて、 改行文字があるかどうか調べ、あれば改行文字を切り取って、 変数に代入する

Method について

何かさせたいときに使うもの

何かさせたいときに使うものを method という。

Object 指向のプログラミング = Method の組み合わせによる計算

Object 指向のプログラミングとは method を組み合わせ、 実行したい計算を変数にしまいながら、計算を実行することである。

目的が最初にありき、 であるため、 Object 指向と呼ばれる。method がいわば単語の集まりであるため、 プログラミングが短くて済む。

Method を自分で作成することもできる。これは後期で学ぶ。 前期は、 いくつかの method を覚えて、 自由にプログラミングできるようになることが、 目標である。

今まで学んだ method を自分の言葉でまとめてみよう。

カロリーメーターを作ろう

変数に整数値を代入して、計算をさせよう to_i_calory.rb。 例えば、カロリーメーターは、摂取した食物のカロリーを変数に代入し、 総摂取カロリーを調べることができる。このプログラムを作ってみよう。

カロリーメーターに必要なしくみ

ユーザがカロリーメータに行うことは、摂取したカロリーを入力すること、 最後に計算した結果を出すように指示を出すことである。 計算機は、入力されたカロリーを受けとり、総カロリーに足しておいて、 計算結果を求められたら総カロリーをいつでも表示できるようにする必要がある。 ユーザが計算した結果を出すよう指示する合い言葉を決めよう。 Quit の q を入力したら、総カロリーを出すようにしたい。

ユーザが入力したカロリーを代入する変数は cal としよう。 総カロリーを計算した結果を代入する変数は total としよう。

カロリーをどんどん加える部分

ユーザに入力を促し、ユーザが入力したカロリーを加える部分を作る。 まず、摂取カロリー cal も総摂取カロリー total も計算前は 0 である。 また、最後に、計算した結果を表示させたい。よって、 次のような構成がまず考えられる。

#!/usr/koeki/bin/ruby
cal = 0 
測定前は摂取カロリーなし
total = 0 
測定前は総摂取カロリーもなし
STDERR.print("摂取したカロリー [kcal]: ") 
カロリーを入力させることを促す
cal = gets.chomp 
入力された文字列を変数 cal にしまう
printf("本日の総摂取カロリーは %d[kcal] でした\n", total)

この動作を永遠に繰り返すには、 while true -- end を用いる。 次へ

何度でも繰り返す場合には

何度も繰り返す場合は、 while true -- end が使える。


while true
	 実行したいこと    
end

行いたいことは、変数を次から次へと取り込むことだから、 while true -- end で挟んでみる。


#!/usr/koeki/bin/ruby

while true
STDERR.print("摂取したカロリー [kcal]: ") # カロリーの入力を促す cal = gets.chomp # 入力された値を変数 cal にしまう
end

実行してみると、変数 cal に数字の文字列を入れるだけで、 総カロリーを出すことはできていない。総カロリーを出すには

total += 数値

という部分が必要であるが、 cal には今のところ文字列が何でも取り込まれるので、 cal に入っている文字列を整数に変換する method が必要である。

また、終わることもできない。終わるには、 q を入力したら結果を出すことにするはずだった。 条件を仮定しする文は if 文 ( 条件文 )といい、 if -- end として使う。 if 文のような method で場合分けをすることを分岐という。

条件文のまとめ

条件をつけ、その場合のみ実行するには、 if -- end を使う。


if 条件
実行したいこと
end

例えば、 「置き傘を持っている。雨が降ったら傘をさす」 という例ならば


置き傘を持っている

if 雨が降る
傘をさす
end

と書く。

比較演算子

条件文を書くときには、何かと比較した結果、 実行するかどうかを決める。このようなときに比較演算子を使う。


if 変数 x == 条件 A x が A に等しいならば
実行する
end

複雑な条件 であっても上記のようにプログラムとして書くことができる。 もし比較演算子ではなく、代入演算子 = を間違って使用していた場合、 警告メッセージがプロンプトに 出る。

結果、次のようにして反復を 止める ことができる。

特定の文字列で反復文を抜けるには

q が入力されたら while 文を抜けるようにしたいので、 変数に文字列が入力されたあとに判断させるようにする。

また、 while 文を抜けるには、 break という実行文を使う。 breakif 文の中に含め、 while 文を抜ける。 また、終了したいときの動作を 知らせるために、入力を促す部分に 操作方法を書いておく。


while true
STDERR.print("摂取したカロリー [kcal]( 入力終了は q ): ") カロリーを入力させることを促す cal = gets.chomp 入力された値を変数 cal にしまう if cal == "q"
break
end
end

もし変数 cal に文字列 q が入っていれば、 break を実行せよ、という実行文を while true -- end に含めることができた。

実行しても、結果は出力されない。なぜならば、変数 cal に入った文字列を総カロリーを変数 total に次々と足し合わせる部分が欠けているためである。 文字列 q 以外は数値となる文字列が変数 cal に代入されることが期待されるから、 変数 cal に入った文字列を整数値に変換し変数 total にしまいたい。


	 end # if 文の end
	 total += cal.to_i

end # while 文の end

結局、カロリーメーターは次のようになる。 次へ

カロリー計算プログラム

実際にカロリー計算プログラムはこのようになる。 while_calory.rb:


#!/usr/koeki/bin/ruby

total = 0
cal = 0

while true
STDERR.printf("摂取したカロリー [kcal] ( 入力終了は q ) : ") cal = gets.chomp if cal == "q"
break
end total += cal.to_i
end printf("本日の総摂取カロリーは %d[kcal] でした\n", total)

生活の中で、次から次へと値を入力し、合計を出すようなしくみを探せ。

より複雑な条件文

if -- end は条件文である。必要に応じて else も使うことができる。


if もしも A であるならば
B をせよ
else さもなければ C をせよ end

A でない場合は 全て C が実行されてしまう。

if -- else -- end を使った文章を考え、プログラム風に書き直せ。

条件を付け加えたい場合は、elsif を使う。


if もしも A であるならば
B をせよ
elsif そうでなくてもし C ならば
D をせよ
end

A でも C でもない場合は、何も実行されない。

if -- elsif -- end を使った文章を考え、プログラム風に書き直せ。

小数点なんて知らないよ

to_i は、入力された値 item を 「数値に変換せよ、その際、小数点があれば切り捨てよ」 という意味である。

それでは to_i method を用いた to_i_compare.rb を作ってみよう。

以下のプログラム to_i_compare.rb に、小数点や x 以外の文字列を入力すると何がおこるか。 それがなぜ発生するのか分かる場合は、根拠をつけて答えよ。


#!/usr/koeki/bin/ruby

STDERR.print("to_i, to_f の性質を調べます\n")
STDERR.print("何か文字列をどうぞ ( 終了は x ) :")

string = gets.chomp
if string == "x"
printf("x が入力されたので中止します\n")
else
printf("整数値化した結果: %d \n", string.to_i) printf("3 で割った結果: %d \n", string.to_i/3) printf("3 で割った結果: %f \n", string.to_f/3)
end

実際に実行してみた結果、 to_i method はどのような計算に適しているだろうか。

そうでないときはずっと 実行したい場合、あるいは、 そうでないかぎりは 実行したい場合などもある。

条件に合わない限り続けたいときには

while -- end は「する限りは」という場合だが、「そうでない限りは」 というときには、 until -- end を使う。 stop_until.rb:


#!/usr/koeki/bin/ruby

ans = "stop"
until false

STDERR.print("誰か止めて!!: ") guess = gets.chomp if guess == ans
break
end
end print("止まった!\n")

until 文を使った例、またはプログラムを考え、解説せよ。

もしそうでない限りは

if A == B -- end は「もし AB に等しければ」 という場合であるが、 「もし AB に等しくなければ」 という場合には unless -- != -- end が使える。


if A == B もし A が B ならば
C を実行せよ
end unless A != B もし A が B とならない限りは
C を実行せよ
end

!= は比較演算子で、「等しくない」という意味である。 stop_until.rb を変更して stop_unless.rb を作り、結果を比べてみよう。

#!/usr/koeki/bin/ruby

ans = "stop"
while true
    STDERR.print("誰か止めて!!: ")
    guess = gets.chomp
    unless guess != ans
        break
    end
end
print("止まった\n")

unless や until を組み合わせた文章を考え、 プログラム風に書き出せ。

使いこなそう

時間を短縮できる方法いろいろについてまとめておく。 以下のことができるものは Trr の練習に進むこと。 分からない学生は隣に聞かず、手を挙げて待っていること。 TA が教える。 講義中は自分に必要なことをする。 理解してからいっしょにレポート作成時に手伝うつもりで講義を聴くこと。

困ったときに助けになるかもしれない操作一覧

Trr の使い方および Trr 試験について

Emacs で M-x trr で開始。5 「日本国憲法」を選ぶ。 Trr 試験時には前期では 150 点以上取る必要がある。

Trr はレポート 1 回分程度の加点であり、 レポート作成を自分で行っていない学生が判別できる試験であるので、 自分で考えてレポートを作成していれば、とくに練習しなくても 通常は合格点が取れるようである。

講義中にプログラムを打ったり、エラーメッセージの英語を解読していれば、 それほど問題のない課題であろう。

変数に入るもの

Method で実行することを教えるが、実行した結果を代入するものを変数と呼ぶ。 変数に入るものは、数値 または 文字列 のどちらかである。

数値変数 = 数値
文字列変数 = "文字列"

とプログラムに書くと変数に代入される。 数字の羅列も文字列である。 gets したものを 計算機はひとまず文字列として判断 する。よって、プログラムで とりこんだ数値列は数値として使う と教える必要がある。

入力した文字列の切替について

文字列では計算されないので、 文字列を整数、小数点、変数に切り替える。 to_i, to_f などの文字列を切替える method を使う。

to_i 文字列を整数へ to integer
to_f 文字列を小数へ to fraction
to_s 文字列(あるいは数値を)文字列へ to string

左クリックを使いこなそう

背景を左クリックすると、ソフトウェアの一覧が出る。 24 は、大きなフォント。

  1. Emacs 24 (Trr の練習)
  2. Kterm 24 (大きな Kterm)
  3. ファイル管理 (% konqueror & でも起動可能)

ファイル管理は Konqueror。 グラフィカルユーザインタフェースのファイルマネージャである。

Konqueror 画像