この授業では、プログラム言語というのがどういうものなのかを なんとなく理解してもらう (そして、様々なソフトの実行ファイルも、 プログラムソースとして書かれたものをコンパイルしてできているんだ ということを 想像くらいはできるようになってもらう) ことなので、 できるだけ(覚えることが少なくて)簡単に使えるプログラム言語 という意味で (私が使えるプログラム言語という訳ではなく) Ruby をやってもらうことにしました。 ちなみに、昨年度までこの授業でやっていたFortran90も 覚えることが少なくて簡単に使えるプログラム言語だと思いますが、 情報処理センターの端末には入ってないので、 情報処理センターのサーバーにログインしてから作業をする必要があり、 そこがややめんどくさいです。 07年度から導入された新システムの端末では、 SUSE LinuxでもWindows XPでもRubyが使えるので、 端末上でプログラムを編集してすぐに実行できるRubyを使って プログラム演習をするのがいいかなと思いました。
ちなみに 最近は、日本語プログラミング言語 ひまわり だの なでしこ といったものもあるようですが、みなさんの環境では使えません。 これで興味を持ってプログラム言語をちゃんと勉強してみたいと 思った人には、 C とか Java とかをお薦めしておきます。
では、まず「あいうえお」と画面に表示させるだけのプログラムを 作ってみましょう。 Rubyのプログラムを書いたファイルの拡張子は.rbとつけるので、 例えば、aiueo.rb という名前のプログラムをgeditで作ってみます。 gedit aiueo.rb& みたいに起動して、
print "あいうえお\n"
と書き込んで保存しましょう。 これは、プログラムを実行したら、 画面に「あいうえお」と表示するという意味で、 「あいうえお」の後に書かれている「\n」は カーソル位置を1行ぶん改行するという意味です。 プログラムを実行するには、
$ruby aiueo.rb
のように打ち込んでEnterキーを押します。 すると、 画面に「あいうえお」と表示されます。 「\n」がない場合とある場合でどう違うのか各自で試してみてください。
プログラムの実行中にプログラムを強制終了させたい場合は、 Cntlキーを押しながら c を押して下さい。
長方形の短辺と長辺を入力すると長方形の面積を表示するプログラムを 作ってみましょう。例えば、
print "長方形の短辺を入力して下さい\n" tanpen=readline.to_f print "長方形の長辺を入力して下さい\n" tyouhen=readline.to_f menseki=tyouhen*tanpen print "長方形の面積は:",menseki,"\n"
プログラムソースはmenseki1.rb.
プログラムの中身を少し説明します。
print "長方形の短辺を入力して下さい\n"
これは、「長方形の短辺を入力して下さい」と画面表示して改行するということです。
tanpen=readline.to_f
これは、キーボードから入力した数字を浮動小数点数として tanpen に入れるという ことです。「長さ」など整数ではない一般的な実数は浮動小数点数で与える と思ってて下さい。
menseki=tyouhen*tanpen
これは、tyouhen と tanpen を掛け算した数値を menseki に代入する ということです。右辺を計算した数値を左辺に代入します。 例えば、x を x+1 と置き換える場合は、x=x+1 のように書きます (x+1=x みたいに逆に書かないように!)。
+ | 足し算 |
- | 引き算 |
* | かけ算 |
/ | 割り算 |
** | べき乗 |
Math::PI | 円周率 |
課題1: menseki1.rb を参考にして、 三角形・台形などの幾何学図形の面積や、 円錐・球などの立体の体積を求めるプログラムを作りなさい (長方形の面積はここに書いてあるのでダメ)。
提出先:メールの表題:ruby1 提出期限:11/6(火) 提出方法:プログラムのテキストをメールに貼り付けて送る。 添付ファイルにしないこと。 提出例: ------------------------------------------ 学籍番号:7501234 氏名:後藤文彦 real :: tanpen, tyouhen, menseki print *,"長方形の短辺を入力して下さい" read *,tanpen print *,"長方形の長辺を入力して下さい" read *,tyouhen menseki=tyouhen*tanpen print *,"長方形の面積は:",menseki end
ただ長方形の面積を求めるだけでは面白くないので、 短辺を長辺より長く入れたら警告を表示して計算してくれないプログラム (menseki2.rb)を作ってみましょう。
print "長方形の短辺を入力して下さい\n" tanpen=readline.to_f print "長方形の長辺を入力して下さい\n" tyouhen=readline.to_f if tanpen > tyouhen then print "短辺が長辺より長いので計算しません\n" else menseki=tyouhen*tanpen print "長方形の面積は:",menseki,"\n" end
プログラムソースはmenseki2.rb.
ここで登場する
if(条件A) then 操作B else 操作C end
という構文は、条件Aを満たす場合は、操作Bを実行し、 満たさない場合は操作Cを実行しなさいということ。
短辺を長辺より長く入れたら計算しないで終わってしまうのでは 今ひとつ面白みがないので、 短辺を長辺より短く入れてくれるまでデータ入力を繰り返す プログラム(menseki3.rb)を作ってみましょう。
tanpen=2; tyouhen=1 while tanpen > tyouhen print "長方形の短辺を入力して下さい\n" tanpen=readline.to_f print "長方形の長辺を入力して下さい\n" tyouhen=readline.to_f print "短辺が長辺より長いの場合は計算しません\n" end menseki=tyouhen*tanpen print "長方形の面積は:",menseki,"\n"
プログラムソースはmenseki3.rb.
ここで登場する
while(条件A) 操作B end
という構文は、 条件A が満たされているうちは何回も操作Bを繰り返すということ。 冒頭でtanpen=2; tyouhen=1と定義してあるのは、 最初にtanpenとtyouhenの変数が適当に定義されていないと 次式のwhile文で比較ができずにエラーが出てしまうから。
a==b | aとbが等しいならば |
a!=b | aとbが等しくないならば |
a > b | aがbより大きいならば |
a >= b | aがb以上ならば |
a < b | aがbより小さいならば |
a <= b | aがb以下ならば |
複数の条件を「かつ」や「または」で組み合わせたいときは、 and や or を使う。 例えば、 「a<x かつ x<b」 なら 「a<x and x<b」と書くし、 「x<a または b<x」 なら 「x<a or b<x」 と書く。
課題2: menseki3.rb を参考にして、 ある条件 (例えば「体積が1000以上になる」とか) を満たすまでデータ入力を繰り返し、 三角形・台形などの幾何学図形の面積や、 円錐・球などの立体の体積を求めるプログラムを作りなさい (長方形の面積はここに書いてあるのでダメ)。
提出先:メールの表題:ruby2 提出期限:11/13(火) 提出方法:プログラムのテキストをメールに貼り付けて送る。 添付ファイルにしないこと。 提出例: ------------------------------------------ 学籍番号:7501234 氏名:後藤文彦 tanpen=2; tyouhen=1 while tanpen > tyouhen print "長方形の短辺を入力して下さい\n" tanpen=readline.to_f print "長方形の長辺を入力して下さい\n" tyouhen=readline.to_f print "短辺が長辺より長いの場合は計算しません\n" end menseki=tyouhen*tanpen print "長方形の面積は:",menseki,"\n"
まあ、1次元配列ぐらいは使ってみましょうか。 クラスの一人一人の試験の点数を読み込んで、 平均点と不合格者(60点未満の人)の番号を出力するプログラムを作ってみましょう。
# データ入力 tensuu=[] #一人一人の点数を入れる配列tensuu[]を定義 ninzuu=readline.to_i #ninzuuに整数をキーボードから入力 for i in 1..ninzuu #iに1からninzuuを順次 入れて繰り返す tensuu[i]=readline.to_f #tensuu[i]にi番目の人の点数を小数で入力 end # 合計点の計算 goukei=0 for i in 1..ninzuu #iに1からninzuuを順次 入れて繰り返す goukei=goukei+tensuu[i] end # 合計点を人数で割って平均点を出す print "平均点は:",goukei/ninzuu,"\n" #goukei/ninzuuを出力 # 不合格者番号の表示 for i in 1..ninzuu #iに1からninzuuを順次 入れて繰り返す if tensuu[i] < 60 then print "不合格者番号:",i,"\n" end #ifに対するend end #forに対するend
プログラムソースはheikin.rb.
まずはプログラムについて少々。
tensuu=[]
これは tensuu[1], tensuu[2], tensuu[3],....といった具合にtensuu[i]に 対して値を取り得る1次元配列(まあ1次元だからベクトルと言ってもいいけど)を 宣言している。
# データ入力
#(半角文字のシャープ記号)を書いたところから改行までは コメントとみなされるので注釈とかを書ける。
ninzuu=readline.to_i
ninzuuにキーボードから整数を入力する。 数を数えたりする場合の数字は整数形にして、 浮動小数点数とは区別して扱う。
for i in 1..ninzuu tensuu[i]=readline.to_f end
for i in 1..ninzuu は、 まずiに1を代入してendの手前の行までの操作を行い、 次にiに2を代入してendの手前の行までの操作を行い、 以下同様に3,4,5,....ninzuuまで繰り返すという意味です。 具体的には、 まず、i=1 のとき tensuu[1] を読み込み、 次に i=2 のとき tensuu[2] を 読み込み……と続けていって、最後に i=ninzuu となり tensuu[ninzuu] を 読み込みます。
goukei=0
goukeiに初期値として浮動小数点数の0を入れておく。
for i in 1..ninzuu goukei=goukei+tensuu[i] end
まず、i=1 のとき goukei=0.+tensuu[1] つまり goukei=tensuu[1] となる。 i=2 のとき goukei=goukei+tensuu[2] つまり goukei=tensuu[1]+tensuu[2] となる。 ……を続けていって、i=ninzuu のとき goukei=goukei+tensuu[ninzuu] つまり goukei=tensuu[1]+tensuu[2]+.....+tensuu[ninzuu] となる。
print "平均点は:",goukei/ninzuu,"\n"
浮動小数点数を整数で割る場合は答えは浮動小数点数になるので、 これで特に問題はないのですが、 例えば、 整数の10を整数の3で割ると、答えが整数の3になったりするので、 浮動小数点数として割られることを期待する変数は浮動小数点数に変換する 必要があります。 逆に x**3 などを計算する場合、3 が整数であれば、 コンピューターは素直に x*x*x を計算してくれますが、 x**3.0 などと書いてしまうと、コンピューターは (x**2.999999999 を計算する場合と同じように対数を取ったりして?) すごく難しい計算をしてしまうので、計算時間の無駄になってしまいます。
さて、このプログラムを実行すると、 最初に人数の入力を求められて、その後、 人数ぶんの点数の入力を求められるが、 これをいちいちキーボードから打ち込むのではめんどくさいし、 間違いが起きやすい。 こういう場合は、入力データをファイルにして入力してみましょう。 まず、geditで、
10 95 20 65 70 50 0 80 100 45 60
みたいな入力データを作ってtensuu.txtに保存しましょう (上の例は、1行目に人数の10人が、2行目から11行目までに 10人ぶんの点数が並んでいる)。 tensuu.txtのデータを読み込んでheikin.rbを実行する場合は、
$ruby heikin.rb tensuu.txt
のように実行します。 画面に表示される実行結果を kekka.txt というファイルに出力 したい場合は、
$ruby heikin.rb tensuu.txt > kekka.txt
のように打ちます。
課題3: heikin.rb を、 最高点の人の番号と最低点の人の番号も出力できるように 改造しなさい。 (標準偏差も出すとか、他にも機能を加えたい人は加えて構いません)。
提出先:メールの表題:ruby3 提出期限:11/27(火) 提出方法:プログラムのテキストをメールに貼り付けて送る。 添付ファイルにしないこと。 提出例: ------------------------------------------ 学籍番号:7501234 氏名:後藤文彦 プログラム本体 ------ここから------- a=[] n=readline.to_i for i in 1..n a[i]=readline.to_f print a[i]**2,"\n" end ------ここまで------- 入力ファイル ------ここから------- 3 1 2 3 ------ここまで------- 出力ファイル ------ここから------- 1.0 4.0 9.0 ------ここまで-------