roy > naoya > 基礎プログラミングI > (1)プログラミングの基礎

(1) プログラミングの基礎

[1] コンパイル型言語とスクリプト型言語

>>More

[2] emacs操作方法の確認

  • Rubyプログラムの作成はemacsで行い、ktermで実行する
  • emacsの操作方法は1年生のときと同じ
  • 主なコマンドを以下に示すので確認しよう
  • その他のコマンドはemacs操作方法のページを参照すること

emacs操作方法

  • 新規作成:Ctrl+x Ctrl+f
  • ファイルを開く:Ctrl+x Ctrl+f
  • ファイルの保存:Ctrl+x Ctrl+s
  • 日本語入力のオンオフ:Ctrl+o
  • コピー&ペースト:コピーしたい部分をマウスで選択するとコピー完了。貼りつけたい場所でマウスの真ん中ボタンを押すと貼りつけ完了
  • コマンドをうち間違えて変なメッセージが出ている:Ctrl+gでコマンドの中止

[3] 簡単なプログラムの作成と実行

プログラムの作成と保存

まず簡単なプログラムを作成してみよう。emacsでファイルの新規作成を行うコマンドはCtrl+x Ctrl+fなので、これを入力しよう。するとemacs下部のミニバッファに以下のように表示される。

Find file: ~/

次の通り入力しよう(入力する部分を黄色で示す)。

Find file: ~/program/keisan.rb[Return]
  • Rubyプログラムはファイル名に必ず.rbの拡張子をつける
  • ~/program/keisan.rbとなっているが、これはファイルの作成場所をホームディレクトリを起点とした絶対パスで指定している
    • programディレクトリの中にkeisan.rbというファイルを新規作成せよという意味

正しく入力すると、emacsの上部に(keisan.rb)と表示される。

emacs上部にファイル名が表示される

では、プログラムを書いてみよう。まずは余り考えずに以下の通り入力する。

#!/usr/koeki/bin/ruby
# -*- coding: utf-8 -*-
print"計算をします。\n"
x = 10
y = 20
z = x + y
p z
printf("%d足す%dは%dです。\n", x, y, z)

日本語の入力を行う場合はCtrl+oを押す。Ctrl+oを押すごとに日本語入力と英語入力が切り替わる。

半角英数字と日本語入力の切り替えはCtrl+o

入力したら保存をする。保存はCtrl+x Ctrl+sである。保存をしていない場合は-U:の横に**と表示されている。保存をすると**が消えることを確認しよう。

保存していない場合はミニバッファの上のEの右横に**が表示される

プログラム作成に関わるルール

  • emacsでFind File:~/program/プログラム名としてprogramディレクトリの中にプログラムを作成する
  • ファイルの拡張子は.rbとする
  • 1行目には#!/usr/koeki/bin/rubyと書く
  • 2行目には# -*- coding: utf-8 -*-と書く

プログラムの実行

プログラムを作成したら、今度は実行しよう。実行はktermで行うので、Ctrl+2でktermにフォーカスを合わせ、programディレクトリに移動する。

sime{c11xxxx}% cd program[Return] #=>program/に移動  [~]
sime{c11xxxx}% chmod +x keisan.rb[Return]     [~/program]
sime{c11xxxx}% ./keisan.rb[Return]         [~/program]
         #=>keisan.rbの実行
  • cd program[Return]:cdコマンドでprogramディレクトリに移動
  • chmod +x keisan.rb[Return]:chmod +x プログラム名[Return]で指定したファイルを実行可能な状態にする
  • ./keisan.rb[Return]:./プログラム名[Return]で指定したプログラムを実行する

chmodコマンドは、ファイルのアクセス権を変更するコマンドである。ファイルに対しては、r(閲覧する権利)、w(書き換える権利)、x(実行する権利)をそれぞれ個別に指定することができる。「./ファイル名」でプログラムを実行するためには、そのファイルに実行する権利が付与されている必要がある。+xとすることで実行する権利が付与される(-xなら実行する権利がはく奪される)。アクセス権は一度変更するとその後も有効である。このためchmodコマンドを用いたアクセス権の変更は最初に実行する時のみ行えばよい

プログラム実行に関わるルール

  • cdコマンドを用いて、プログラムが保存されたディレクトリに移動する
  • chmod +x プログラム名[Return]で作成したプログラム(ファイル)に実行する権利を付与する(最初に1回だけ必要な作業)
  • ./プログラム名[Return]で作成したプログラム(ファイル)を実行する

実行すると、次のように表示される。

sime{c11xxxx}% chmod +x keisan.rb[Return]
sime{c11xxxx}% ./keisan.rb[Return]
計算をします。
30
10足す20は30です。

keisan.rbは短いが立派なプログラムである。各行についてそれぞれ解説する。

  • 1行目:#!/usr/koeki/bin/rubyはrubyインタプリタのあるディレクトリを指定している。これについてはこのページ内の「2種類の実行方法」の項で詳しく説明する。プログラムの1行目に必ず書くと覚える。
  • 2行目:日本語文字コードがEUC-JPであることを示している。
  • 3行目:「計算をします。」と表示しなさいという命令が書かれている。
  • 4行目:xに10を代入しなさいという命令が書かれている。
  • 5行目:yに20を代入しなさいという命令が書かれている。
  • 6行目:x+yの結果をzに代入しなさいという命令が書かれている。
  • 7行目:zに代入されている値を表示しなさいという命令が書かれている。
  • 8行目:「□足す△は○です。」の□△○の部分にそれぞれxyzに代入された値を入れ込んで表示しなさいという命令が書かれている。

このように、プログラムは実行すると上から順に1行ずつ処理が行われる。

[4] メソッドと変数

ここでは、Rubyプログラムを作成する上で覚えておくべき用語について確認する。

メソッド

今作成したkeisan.rbをktermで実行すると、結果が3行表示された。これらはそれぞれ3行目、7行目、8行目が対応していた。3行目のprint、7行目のp、8行目のprintfはいずれも「表示せよ」という命令であった(若干働きは違うが)。このように、何らかの働きを持つあらかじめ登録された文字列のことをRubyではメソッドと呼ぶ。

では、printメソッド、pメソッド、printfメソッドの働きについて、それぞれの違いを意識しながら確認してみよう。

  • printメソッド:後ろに指定した""内のメッセージを表示する。
  • pメソッド:後ろに指定した変数(後述)に代入された値を表示する。
  • printfメソッド:後ろに指定した""内のメッセージを表示するが、その際に%dの位置に""の後ろで指定した変数(後述)に代入された値を入れ込んで表示する。

printfについてはもう少し複雑な働きをするが、当面は上述の通り理解しておいて問題ない。

変数

keisan.rbで用いられたxyzのように、何らかの値を代入して保管しておく役割を果たすものを変数とよぶ。中学や高校の数学でも登場しているので、それなりに馴染み深い(はずである)。

中学や高校ではxyzが主に用いられてきたが、プログラム中に登場する変数名は1文字である必要はない。例えば、keisan.rbで使用したxappleとしてもよいし、hogehogehogeでも構わない。変数名を決める上での注意点を示す。

  1. 使える文字は英数字とアンダーバー(_)に限られる
  2. 変数の最初の文字は英小文字でなければならない(先頭が大文字の変数は定数扱いとなり、最初に代入した値を変更することができない)
  3. あらかじめメソッドとして登録されている文字列は変数名として利用することはできない

ところで、keisan.rbではx = 10などと書かれていた。この意味は以下のとおりである。

  • × xは10である。
  • ○ xに10を代入する

=は右辺を左辺に代入するという意味を持つ。したがって、z = x + yx+yの結果をzに代入するということになる。ここでは、=や+の前後に半角のスペースをとっているが、スペースはあってもなくてもよい。

  • ○ z = x + y(全てスペースをあけている)
  • ○ z=x+y(全てスペースなし)
  • × z = x +y(一方だけスペースなし)
  • × z = x+ y(一方だけスペースなし)

変数には数字だけでなく文字を代入することもできる。文字を代入する場合には値に""をつける。

  • ○ name = "公益太郎"(文字なので""でくくる)
  • ○ age = 20(数字なので""なし)
  • × name = 公益太郎(文字なのに""がない)

変数名は、代入されている値が想像できるような名称にする。

  • ○ name = "公益太郎"(名前なのでnameという名称にしている)
  • × book = "公益太郎"(名前なのにbookという名称にしている)

同一名称の変数に繰り返し代入すると上書きされる。

  • x = 100 としたあとで
  • x = 200 とすると

xに代入されているのは200となる。最初に入力した100は保持されない。

メソッドと変数のまとめ

  • 何らかの働きを持つ文字列をメソッドという。
  • printメソッドは""内を表示する。
  • pメソッド指定した変数内の値を表示する。
  • printfメソッドは""内のメッセージに変数内の値を入れ込んで表示する。
  • 値を代入して保持するものを変数と呼ぶ。
  • 変数名は何文字でも良い。
  • 変数に文字を代入する時は""をつける。
  • 変数名は代入されている値がわかるような名称にする。
  • =は右辺を左辺に代入するという意味。

[5] \nの働き

\nは「バックスラッシュエヌ」と呼び改行をあらわす。バックスラッシュは環境により円マークとして表示される場合がある。バックスラッシュのないキーボードを使用している場合は円マークで代用する。

\nの有無により、出力結果が変化することを確認しよう。以下のプログラムは\nの有無が異なっている(違いがわかりやすくなるよう\nを黄色で表示している)。最初に上のプログラムを作成保存し、実行結果がどうなるか確認してみよう。

その際は、全て入力するのではなく、コピー&ペーストを使ってみよう。emacsでファイルを新規作成した後で、コピーしたいところをマウスで選択し、emacs上でマウスの真ん中クリックを押す。

greeting.rb

#!/usr/koeki/bin/ruby
# -*- coding: utf-8 -*-
print"はじめまして。\n"
print"私の名前は\n"
print"○○(自分の名前)です。\n" 

実行したら、\nを一部削除して、下のように変更して実行してみよう。

#!/usr/koeki/bin/ruby
# -*- coding: utf-8 -*-
print"はじめまして。"
print"私の名前は"
print"○○(自分の名前)です。\n" 

以下は実行結果である。同じ結果になることを確認しよう。

sime{c11xxxx}% chmod +x greeting.rb[Return]
sime{c11xxxx}% ./greeting.rb[Return]
はじめまして。
私の名前は
公益太郎です。
sime{c11xxxx}% ./greeting.rb[Return]
はじめまして。私の名前は公益太郎です。

実行結果を見ると、最初は途中で改行され3行に分かれて表示されている。改行が行われているのは\nの位置である。2回目の実行ではプログラムでは3行に分割して記述されている内容が、1行で表示されている。

printメソッドやprintfメソッドを使ってメッセージを表示させる場合、\nをつけることで改行させることができる。なお、表示する一連のメッセージの一番最後には必ず\nが必要である。最後の\nがないとうまく表示されない。

ただし表示をさせるメソッドのうち、pメソッドについては\nは不要である。pメソッドは変数内の値を表示して自動的に改行する。""内のメッセージを表示する働きを持つprintメソッド、printfメソッドのみ""内の末尾に必ず\nが必要となる。

\nの働きと用法についてのまとめ

  • \nは改行するという意味をもつ。
  • ""内のメッセージを表示するprintメソッドやprintfメソッドでは""の末尾に必ず\nをつける。
  • ""内の任意の位置に\nをつけることで自由な位置で改行して表示させることができる。
  • pメソッドは自動的に改行するので\nは不要。

[6] 2種類の実行方法

>>More

[7] 入力を受け取るgetsメソッド

もういちど最初の方で取り上げたkeisan.rbを見てみよう。

#!/usr/koeki/bin/ruby
# -*- coding: utf-8 -*-
print"計算をします。\n"
x = 10
y = 20
z = x + y
p z
printf("%d足す%dは%dです。\n", x, y, z)

このプログラムでは4行目と5行目でxyにそれぞれ10と20を代入しており、6行目でzを計算している。4行目と5行目を書き換え、例えばx = 40などとすれば、あらゆる足し算を行うことができる。

ただし、いちいちプログラムを書きなおして保存しなおしてから実行するのは非常に面倒くさい。最初からプログラムの中に数字を書いておくかわりに、プログラムを実行したときに好きな数字を入力し、その値に基づいて計算を行ってくれたほうが便利である。

キーボードからの入力を読み込むメソッドとしてgetsメソッドがある。getsメソッドを使ったプログラムの例を見てみよう。

money.rb

#!/usr/koeki/bin/ruby
# -*- coding: utf-8 -*-
print"商品の金額を入力してください\n"
item = gets.chomp!.to_i
printf("お会計%d円です。いくら支払いますか?\n",item)
money = gets.chomp!.to_i
change = money - item
printf("%d円のお返しになります。\n", change)
sime{c11xxxx}% chmod +x money.rb[Return]
sime{c11xxxx}% ./money.rb[Return]
商品の金額を入力してください
198[Return] #=>入力待ちになる
お会計198円です。いくら支払いますか?
200[Return] #=>入力待ちになる
2円のお返しになります。

実行すると、「商品の金額を入力してください」が表示された後でユーザからの入力待ちになる。ここでは198を入力している。すると「お会計198円です。いくら支払いますか?」が表示される。このメッセージはprintfで表示されているが、%dの位置に入力した198が入れ込まれている。メッセージ表示後、再度ユーザからの入力待ちになる。ここでは200を入力している。すると入力した値に基づいて計算が行われ、その後のメッセージが表示される。

money.rbの1行目と2行目には特に新しいものはない。4行目では

item = gets.chomp!.to_i

が登場している。getsはキーボードからの入力を読み込むメソッドであるが、キーボードから入力した値が数字の場合はchomp!.to_iを後ろにつけて、gets.chomp!.to_iとする必要がある。したがって、この行はキーボードから入力された数字を読み込んでitemに代入している。chomp!やto_iもメソッドであるが、ここでは説明しない(第3回で詳しく取り上げる)。

5行目ではprintfを用いて、たった今入力した数字を表示し、支払い金額の入力を促している。6行目では4行目と同様にgets.chomp!.to_iを用い、入力した数字をmoneyに代入している。7行目ではmoneyに代入された値からitemに代入された値を引き、結果をchangeに代入している。8行目はkeisan.rbと同じで、""内の%dの位置に""の後ろで指定したchangeに代入された値を入れ込んで表示している。

getメソッドについてのまとめ

  • getsメソッドはキーボードからの入力を読み込むメソッドである。
  • キーボードから入力した数字を読み込むためには変数=gets.chomp!.to_iと書く。これで入力された数字が変数に代入される。

[8] エラー発生時の対応

プログラムが最初から動くことはほとんどない。必ず間違いはあるものなので、その間違いを特定し、修正しながら完成へ向かっていくのが一般的な作成方法である。

ここでは、エラーが発生した際のメッセージの読み方について簡単に説明する。詳細は、Rubyプログラムエラー対応のページを参照のこと。

エラーメッセージの読み方

プログラムを実行したら次のエラーメッセージが表示されたとする。これはどのように読み取ればよいだろうか。

hoge.rb:5:in '+': String can't be coerced into Fixnum (TypeError)
       from hoge.rb:5
  • hoge.rb:実行したプログラム名
  • 5:エラーのある行数(5行目にエラーがある)
  • '+': String can't be coerced into Fixnum (TypeError):具体的なエラー内容

このエラーでは5行目にエラーがある。したがってemacsで作業中のプログラムの5行目を見ればよい。なお、emacsではカーソルが何行目にあるか容易に確認できる。emacsの下部に以下の表示がある。このうちL12が行数をあらわす。これを見れば現在12行目にいることがわかる。

-かんな-U:--   hoge.rb      ALL  L12

該当行への移動

短いプログラムであれば、エラーが発生した行への移動は容易であるが、1000行にもおよぶプログラムの850行目にエラーがある場合、カーソルキーの下を押しながら移動するのは大変である。emacsで以下のように入力すると任意の行に移動できる。

[Esc] x goto-line[Return]
850[Return]

これで、850行目に移動できる。

[9] 出席課題

ディスプレイに表示をする役割を持つprintやprintfメソッドに加え、キーボードからの入力を受け取るgetsメソッドを学んだことで、かなりプログラムらしいものが作れるようになってきた。今日のまとめとして、これらのメソッドを駆使したプログラムを何か1つ作ってみよう。プログラムを作成するための要件は以下のとおりである。

キーボードから数字を入力してもらい、その数字を使って何か計算をして結果を出力するプログラム(ruby01.rb)

money.rbのように支払額を入力してお釣を計算するプログラム以外にも例えば以下のようなものが考えられる。以下を参考にしても良いし自分で考えても良い。

  • 既得単位数を入力すると、卒業までに必要な残り単位数を計算して出力する(入力するのは既得単位数のみ)。ただし、卒業に必要な単位数は124単位とする。
  • 朝食代、昼食代、夕食代を入力すると一日の食費を計算して出力する(3回入力する)。

提出要領

  • 提出先:課題提出用メールアドレス
  • Subject:ruby01
  • 提出期限:授業終了時まで

メール本文の構成は以下のとおり。

  1. 1行目に学籍番号と氏名を記載
  2. どんなプログラムを作ったのか(例:既得単位数を入力してもらい卒業までに必要な残り単位数を計算して出力するプログラム)
  3. 作成したプログラムを貼りつける
  4. 実行結果を貼りつける
  5. 感想やプログラムを作って気づいたこと、要望等

採点:本日は出席点のみです

メール本文へのプログラムの挿入(Ctrl+x i)

Mewのメール作成画面で、Ctrl+x iと入力すると、下部のミニバッファに、Insert file:~/と表示される。ここで、メール本文に挿入したいプログラム名を入力[Return]で、プログラムが挿入される。短いプログラムであればマウスで選択⇒真ん中クリックで貼り付けてもよいが、プログラムが長くなるとプログラムを全て選択するのが大変であるため覚えておくとよい。