Login
Immutable PageDiscussionInfoAttachments
alstamber/2013FreshmanRubySeminar

MMA

なにこれ

以下のような人を対象とした資料です。

Rubyというプログラミング言語を使って、プログラミングのいろはの「い」あたりを学びます。

プログラミングとはそもそも何なのか

プログラミングという行為に憧れてMMAに入ってきた人が割といるかもしれません。
なんか傍から見てるとかっこ良く見えますよね。
プログラミングというのは端的に言ってしまえばプログラムを作る行為です。
コンピュータの世界で言うところのプログラムというのはコンピュータに与える命令を並べたものです。
60年ちょい前にコンピュータが生まれてから今までコンピュータは驚異的な発展を遂げましたが、
基本的な部分は何も変わっていません。
つまりコンピュータは人間が与えた命令を忠実に実行する機械でしかありません。
あなたが使っているパソコンも、家で動いている電化製品も、大学に来るまでに通った人も多いだろう自動改札機もみなコンピュータで動いています。
そしてそれは一見自律して動いてるように見えますが、実際には人間が予め与えた命令を実行しているだけなのです。

コンピュータにどんな仕事をさせたいのか、それを書くのがプログラミングという行為の本質です。
言い方を変えれば、何か仕事をさせるためにプログラミングをするのであって、プログラミングするためにプログラミングしているわけではないということです。
(競技プログラミングはプログラミングという行為そのものを競っているのでちょっと例外かもしれないです)
プログラミングはコンピュータを使いこなすための道具だという認識を改めてしてもらえればと思います。

とはいえプログラミングという道具を使いこなすためには、やはりいろいろなことを学ぶ必要があります。
学ぶといっても椅子に座って本を読むだけではなく、実際にプログラムを書いてみる、ということが大事になってきます。
いくら本やWebページを見てわかったつもりになっても、実際になにかを作ろうとしてプログラムを書き始めると全然書けないということはありがちです。
僕もそういった経験を幾度と無くしてきました。
なのでこの講習でもできるだけ実際に問題をプログラムを書いて解いてもらう、ということを主にしたいと思っています。
実際にプログラムを書いてみる事で、プログラミングをする時特有の考え方というものが身についてきて、自分がコンピュータにさせたいことを
プログラムに起こす能力がついてくるようになります。

プログラミングができるために必要なもの

個人的にプログラミングを上手にするために必要な物は3つあると思っています。

道具の習熟

ここで言う道具というのは割と広い意味を持っています。
道具の最たるものがプログラミング言語です。
○○という動きをするプログラムを作りたい、となった時にそれを自分が使おうとしているプログラミング言語ではどのように書けばよいのか、
ということを知っているかどうかが重要になります。

今回の講習ではRubyという言語を取り上げて、この第一歩を踏み出してもらおう、という趣旨です。

道具はなにもプログラミング言語だけではなくて、プログラムを書くために使うテキストエディタや
IDE(プログラムを作るときに便利なツールを詰め込んだお徳用パックみたいなソフト)などへの習熟も効率のよいプログラミングに役立ちます。

アルゴリズムの理解

アルゴリズムというのはプログラムを使って何か仕事をしたいときに、その仕事の手順を定式化したものです。
プログラムに仕事をさせるとき、やり方はたくさんあることが多いですが、やり方によって時間がかかったりそうでなかったりと性質が異なります。
もちろんできればプログラムの実行に時間がかからないに越したことはないわけです。
そこでアルゴリズムの中でも効率のよいものについて知っておき、それを使えるようにしておくことが大事になってくるというわけです。

合理的設計の能力

合理的設計というのはなにかプログラムを使ってある程度複雑なものを作りたいとなった時に必要になるものです。

プログラムにかぎらず複雑なものを作るとき、対象を小さいものに分けて考えるということをします。
プログラムにおいても複雑なものを適切に小さく分割して、その小さなものを組み合わせるという作り方をすることになります。
このように複雑で手の負えないものを小さくして人間の手の負える範囲に持ってくる力というのが非常に大事になってきます。
小さな問題に出来れば、あとは知っているアルゴリズムの知識などを使ってプログラムに書き出していくことが簡単になるからです。

こういったプログラムの作り方をプログラミング言語の立場から助けてくれるような言語もあります。
例えばオブジェクト指向と呼ばれる概念はその一つです。オブジェクト指向はプログラムをオブジェクトと呼ばれるものの組み合わせと捉えて
そのオブジェクトをいろいろいじることでプログラムとしての仕事をさせるという考え方です。
Rubyはオブジェクト指向の考え方に沿って作られています。

プログラミング言語とRuby

プログラムを書くときには、ある程度の決まりに従って書く必要があります。
好き勝手に人間が書いてしまうと、コンピュータの側が何をすればいいのか理解できなくなってしまうからです。
これはちょうど人間が文章を書くときの状況に似ています。
人間が文章を書くときも単語の並べ方などある程度の決まりがあって、それにしたがって文章を書きます。
この決まりのことを「言語」とよんでいて、人間の世界にはたくさんの言語があります。
日本語とか英語とかドイツ語とかです。

コンピュータの世界にもやっぱりたくさんの言語があって、それらは人間世界の言語と区別するために「プログラミング言語」と呼ばれています。

プログラミング言語がたくさん存在するのには一応訳があります。例えばそれぞれの言語に得意不得意のジャンルがあったりします。
あるいは言語を作った人の趣味が反映されていたりします(こういう書き方は嫌いだから俺の言語に入れねえ!とか)。

Rubyはそういったプログラミング言語のうちのひとつです。今回この講習にRubyを選んだのは

と言った理由です。

とりあえずRubyでプログラムを書いてみる

ここから先はRubyがインストールされていることを前提とした話になります。

プログラムを書くときにはテキストエディタと呼ばれるソフトを使います。
Windowsで最初から入っているテキストエディタとしては「メモ帳」があります。
ただこれはプログラムを書くには使いづらいので、notepad++あたりを入れると良いと思います。

MacやLinuxであればemacsやvimなどを使うと良いと思います。ターミナルを起動して

$ vim

とか

$ emacs

とかやると起動します。

ちなみにSublimetext2というエディタが私のお気に入りです。Windows, Mac, Linuxで動くようです。

エディタを起動したら次のようなテキストファイルを作りましょう。ファイル名は「hello.rb」にします。

   1 puts "Hello, World"

ファイルを保存したらターミナル(Windowsならコマンドプロンプト)を起動して、保存したディレクトリに移動します。
そして次のように入力します。

ruby hello.rb

なにが起きたでしょうか。

変数

変数というのはプログラミングを勉強する上で絶対に必要となる考え方なので、ここでしっかりやっていくことにしましょう。
変数というのは簡単にいえばデータに付けられた名前です。

   1 a = "Hello"

上のプログラムは"Hello"という文字列(文字が並んでいるので文字列と言います)にaという名前をつけています。この時のaが変数です。
またこの手続を「aに"Hello"を代入する」という言い方をします。 こう書くことによって"Hello"という文字列の代わりにaというものをプログラムの中で使うことができるようになります。

演習1

次のプログラムを実行しましょう。
(strというのはstringの略です。stringは文字列の英語での呼び名です。)

   1 str = "Takatsuki Yayoi"
   2 puts str

変数はなにも文字列だけではなくて、数値にも紐づけることができます。

   1 a = 1
   2 b = 3.141592653589

出力と入力

Windowsの場合プログラムの先頭に次のように書かないとエラーが出るようです。

# coding: utf-8

今までプログラムの中で何気なくputsというものを使って来ましたがこれは一体何でしょうか。
putsというのは「画面に出力をする」という仕事をするメソッドです。メソッドというのを今正確に説明するのは難しいのですが
ここでは「プログラムで命令をするためのもの」ということにしておきます。

putsの後ろに出力したい文字列や数値を書くことによってそれを出力することができます。putsはメソッドで、その後ろに与えたいデータを与えるという形になっています。
メソッド名の後ろに書く与えたいデータを並べたものを「引数(ひきすう)」といいます。

   1 puts "芽兎めう"
   2 puts 4545

putsは正確には与えられた文字列や数値を出力したあと改行をします。改行が要らないときはprintというメソッドがあって、こっちは出力だけを
やって改行をしません。

画面に出力をするばかりではなくてこっちから入力をしたい、と思うこともあるかもしれません。そのためにgetsというメソッドがあります。
getsメソッドを使うとキーボードから入力を受け付けて、入力された結果の文字列を手に入れることができます。

例えば

   1 str = gets

とやれば、strにキーボードからの入力の文字列が代入されます。
ただしgetsは最後にEnterキーを押した時の改行も一緒に読み込んでしまうので、実際には改行を取り除くために次のように使うことが多いです。

   1 str = gets.chomp

getsはキーボードから入力された文字列でした。これの後ろに.chompをつけるとそこから改行を取り除くことができます。その結果をstrに代入しているので
結果として改行が取り除かれたキーボードからの入力文字列がstrに代入されたことになります。

getsはキーボードからの入力を文字列として扱うので、数値として扱いたいときはそのままではうまくいきません。そのようなときは次のように書きます。

   1 number = gets.to_i
   2 float = gets.to_f

getsの後ろに.to_iとかくと、整数に変換してくれます。.to_fと書くと小数に変換してくれます。

getsを使うときはprintメソッドを使って何を入力するべきかを一緒に示すようにするとよいです。

   1 print "文字列を入力せよ"
   2 str = gets.chomp

演算子

数値に対する演算

算術演算とか書くと難しい響きですが、要するにRubyに足し算とか引き算とかやらせてみようというわけです。

   1 sum = 1 + 2
   2 subst = 1 - 2
   3 mul = 4 * 2
   4 div = 4 / 2
   5 mod = 5 % 3

掛け算と割り算の記号が普通に使われているものとは違うことに注意が必要です。
%は見慣れないかもしれないですが、あまりを計算するためのものです。こうした足し算や引き算の記号を演算子といいます。

文字列に対する演算

演算子は数値だけではなく文字列に対しても適用することができます。

   1 str = "Kisaragi" + "Chihaya"
   2 puts str

   1 str = "めう" * 2
   2 puts str

演習2

次のプログラムを実行してみましょう。

   1 str = 2 * "めう"
   2 puts str

これまでプログラムを書いてきてなんとなく感づいている人もいるかもしれないですが、変数はそれと紐付いているデータによっていくつかの種類
に分けることができそうです。これを「型」と言います。具体的には文字列の型や整数の型、小数の型などがありそうです。

演習2のプログラムがエラーになったのは、*という演算子が右側に数値以外の型のデータを許さないように決まっているからです。

条件分岐

if式

今までのプログラムはすべて上から下に順番に実行するだけでした。今からはプログラムにもう少し複雑な順番で
実行する方法を学ぶことにしましょう。

ここではif式という新しいものを学びます。if式は次のように書きます。

   1 if 条件
   2     条件が成立している時に実行したいもの
   3 end 

条件というのは何でしょうか。条件は一般的に成立しているか成立していないかが判別できるようなものを言います。たとえば

   1 4 < 3 #4が3より小さい→成立していない
   2 a >= 3 #aが3以上
   3 b <= -1.4 #bが-1.4以下
   4 a == b #aがbと等しい
   5 a != b #aがbと等しい
   6 "Akaza Akari" == "Akaza Akari" #左の"Akaza Akari"と右の"Akaza Akari"が等しい→成立している

これを使えば

   1 if a > 0
   2     puts "aは0より大きい" #aが0より大きい時だけ実行される
   3 end

   1 if name == "Akari"
   2     puts name + "は空気"  # nameが示す文字列が"Akari"の時に実行される
   3 end

else

条件が成立していないときに実行したいこともあると思います。そういう時はelseという物を使います。

   1 if 条件
   2     条件が成立している時に実行されるもの
   3 else
   4     条件が成立していないときに実行されるもの
   5 end

elsif

elsifを使うとある条件が成立していないときに更に別の条件について調べることができるようになります。

   1 if 条件1
   2     条件1が成立している時に実行されるもの
   3 elsif 条件2
   4     条件1が成立していなくて条件2が成立している時に実行されるもの
   5 elsif 条件3
   6     条件1と条件2が成立していなくて条件3が成立している時に実行されるもの
   7 else
   8     条件123も成立していないときに実行されるもの
   9 end

配列

配列というのはいくつかのデータを順に並べたものです。 配列に突っ込みたいものをずらずらと並べてコンマで区切り、[]で囲めば配列に出来ます。

   1 ["Toshino", "Kyoko"]
   2 ["Takatsuki", "Yayoi", 4545]
   3 ["panda", ["usagi", "koala"]]

配列の要素には0番から順番に番号が付いている。その番号を使って配列の要素を取り出すことができる。

   1 a = ["Takatsuki, "Yayoi"]
   2 a[0] #=> "Takatsuki"
   3 a[1] #=> "Yayoi"
   4 

代入することもできます。
nilというのはなにもないことを表す記号です。

   1 a = [1, 2]
   2 a[0] = 3 #=> [3, 2]
   3 a[4] = "Nyaruko" #=> [3, 2, nil, nil, "Nyaruko"]

ループ

条件分岐と並んで実行の流れを変える方法としてループがあります。
ループは対象となるデータを変えながら同じ処理を繰り返すことをいいます。

この部分はC言語とはかなり性質が違うので参考程度にお願いします。

for式

for式は次のように記述します。

   1 for 変数 in 配列
   2    繰り返す手続き
   3 end

まずfor式が実行されると配列の先頭の要素が取り出されてinの前にある変数に代入されます。
その変数はfor式の中の繰り返す手続きで使うことができます。
手続きが終わると配列の2つ目の要素が取り出され、同じ事が繰り返されます。これが配列の最後まで繰り返されます。

   1 for str in ["akari", "kyoko", "yui", "chinatsu"]
   2     puts str
   3 end

イテレータ

イテレータというものを使って繰り返しを実現することもできる。
イテレータの代表的なものがeachメソッドというものである。例えば配列にeachメソッドを使ってみる。

   1 (配列).each do |変数|
   2    繰り返したい処理
   3 end

こう書くと配列から1つずつ要素をとってきて| |で囲まれた変数に代入される。この変数はdoとendで囲まれている部分の処理で使うことができる。
勘の良い人は気づくかもしれないが、このプログラムと先ほどのfor式のプログラムはほとんど同じ挙動をする。

   1 ["akari", "kyoko", "yui", "chinatsu"].each do |elem|
   2     puts elem
   3 end

実際for式は内部的にeachメソッドに書きかえられている。
こういったある処理を別の記法で書けるようにしたものをsyntax sugar(構文糖)と呼ぶ。

配列だけではなく文字列にもイテレータを適用することができる。each_charというメソッドを使うと文字列から一文字ずつ取り出すことができる。

   1 "Takatsuki Yayoi".each_char do |c|
   2    puts c
   3 end

練習

演習3

3つの数を入力させて、それを足し算した結果を表示するプログラムを作りましょう。

演習4

文字列と整数を入力させて、文字列を指定された整数回繰りかえして表示するプログラムを作りましょう。

演習5

1以上の整数nを引数として取り、1からnまでを画面に表示してください。正しい以下の条件があります。

演習6

BMIを計算して太りすぎか痩せ過ぎかを判定するプログラムを作りましょう。
BMI = 体重(kg) / 身長(m)^2 です。

また太りすぎか痩せ過ぎかの判定は次の基準で行うことにします。

低体重(痩せ型)

18.5未満

普通体重

18.5以上、25未満

肥満(1度)

25以上、30未満

肥満(2度)

30以上、35未満

肥満(3度)

35以上、40未満

肥満(4度)

40以上

演習7

数値の配列が与えられた時、その中で最も大きい要素を調べて出力するプログラムを書いてください。

演習8

数値の配列が与えられた時、その中で2番目に大きい要素を調べて出力するプログラムを書いてください。

演習9

数値の配列が与えられた時、その数値の平均を求めるプログラムを書いてください。

演習10

文字列を引数にとって、それをひっくり返したものを戻り値とするメソッドを作ってください。

演習11

数値の配列が与えられた時、それを逆順に出力するプログラムを作ってください。

演習12

2つの整数を入力された時、その整数の最大公約数を求めるプログラムを作ってください。

演習13

小数xと整数nを入力された時、xのn乗を求めるプログラムを作ってください。

演習14

1つの単語 W と文章 T が与えられます。T の中にある W の数を出力するプログラムを作成して下さい。

文章 T に含まれるスペースまたは改行で区切られた文字列を単語 Ti とします。すべての Ti において単語 W と同じになるものを数えて下さい。

演習15

1 からnまでの数の中から、重複無しで3つの数を選びそれらの合計がxとなる組み合わせの数を求めるプログラムを作成して下さい。
nとxはキーボードから入力されたものを使うこととします。

演習番外

1から100の間、3の時だけアホになるプログラムを作ってください。
ここでは「アホになる」とは数の後ろにビックリマークが1つだけ付いている状態とします。

   1 1
   2 2
   3 3!
   4 4
   5 5
   6 6!
   7 ...
   8 29
   9 30!
  10 31!
  11 32!
  12 ...

番外

すすんだイテレータの話

times

単純にn回繰り返したいという時はtimesというメソッドを使える。

   1 sum = 0
   2 
   3 5.times do
   4     sum = sum + 1
   5 end
   6 
   7 puts sum

timesメソッドにも| |で囲まれた変数を導入することができます。

   1 5.times do |hoge|
   2     puts hoge
   3 end

とやると

0
1
2
3
4

と出力されます。

range

ある数値の範囲で繰り返しをしたいときはrangeという特殊な書き方を使うことができる。
たとえば

   1 (1..10) #1から10の整数の並びという意味

rangeにはeachメソッドが使える。

   1 (1..10).each do | i |
   2    puts i
   3 end

alstamber/2013FreshmanRubySeminar (last edited 2013-07-04 23:39:00 by alstamber)