学習項目です。
注意:whileを使って間違ったプログラムを作ってしまうとプログラムが 止まらなくなってしまうことがあります。 そのような時、Ctrlキーを押しながら C のキーを押すと、 プログラムは途中で強制的に終了します。
次の配列の中から、偶数をとり出し、表示するプログラムを作成しなさい。
numbers = [4,12,45,21,18,7,20,5,51,16,10] #この後の部分を作る
出力は以下のようになる。
4 12 18 20 16 10[偶数の判定]
ある数が偶数かどうかは、2で割って余りが0となるかどうかで決定される。 ちなみに余りが1となるのは奇数という。
次の配列の中から、3の剰余が奇数となる数をとり出し、表示するプログラムを作成しなさい。
numbers = [4,12,45,21,18,7,20,5,51,16,10] #この後の部分を作る
出力は以下のようになる。
4 7 16 10[3の剰余が奇数]
「剰余」とは「割った余り」のこと。3の剰余は、必ず0、1,2のいずれか。 だから、3の剰余が奇数ということは、3で割って余りが1となることと同じ。
次の配列の中から、5の剰余が1または2となる偶数を取り出し、表示するプログラムを作成しなさい。
numbers = [4,12,45,21,18,7,20,5,51,16,10] #この後の部分を作る
出力は以下のようになる。
12 16[5の剰余が1または2となる偶数]
「5の剰余が1または2の偶数」というのは、「5の剰余が1または2」かつ 「偶数」という2つの条件を満たす数のこと。
この2つの条件を「かつ」(and)で結んだ条件を書けば良いのです。 ここで「かつ」は && で表現されます。
なお、「5の剰余が1または2」という条件は「5の剰余が1」と「5の剰余が2」 という2つの条件を「または」(or)で結んだ条件です。「または」は || で表されます。
data1 = ["日曜","月曜","火曜","水曜","木曜","金曜","土曜"] data2 = [] data2 << data1[3] data2 << data1[0] p data2このプログラムの実行結果は、次のようになります。
["水曜","日曜"]つまり「配列 << 要素」とは、配列に要素を付け加える (配列の長さがひとつ長くなり、付け加えられた要素はその配列の最後の要素として加わる) という命令です。
$KCODE = "s" data = ["日曜","月曜","火曜","水曜","木曜","金曜","土曜"] data2 = [] i = 0 while(i < data.size) data2 << data[i] print "no=", i, " " p data2 sleep(1) i = i + 1 end
作った逆順の配列をpで出力すること。
$KCODE = "s" data = ["日曜","月曜","火曜","水曜","木曜","金曜","土曜"] data2 = [] #... #ここを作ること #... p data2このプログラムの実行結果は、次のようになります。
["土曜", "金曜", "木曜", "水曜", "火曜", "月曜", "日曜"]
newary = [] numbers = [4,12,45,21,18,7,20,5,51,16,10] #... #ここを作ること #... p newary
[12,18,20,16,10]
numbers = [4,12,45,21,18,7,20,5,51,16,10] axis = 15 lower = [] higher = [] #... #ここを作ること #... print "higher = " p higher print "lower = " p lower
higher = [45, 21, 18, 20, 51, 16] lower = [4, 12, 7, 5, 10]
ary = [15,32,[100,320,170],403,["こねこ",32]]
ary = [15,32,[100,320,170],403,["こねこ",32]] #no1 p ary.size #no2 p ary[2] p ary[2].size配列の要素に配列が入っているような複雑な配列でも、その扱いはこれまでと同じです。 これまでの規則を順番に一歩一歩適用していきます。例えば、次のような形で、配列の中にある配列の要素を取り出すことができます。
ary = [15,32,[100,320,170],403,["こねこ",32]] p ary[4][0]結果はもちろん、次のようになります。
"こねこ"
data = [["日曜",0],["月曜",1],["火曜",2],["水曜",2],["木曜",4],["金曜",5],["土曜",6]] #以下の部分を作る
日曜=>0 月曜=>1 火曜=>2 水曜=>3 木曜=>4 金曜=>5 土曜=>6
data = ["a","b","c"] for i in 1..3 print "data[",-i,"]=",data[-i],"\n" endこの結果は次のようになります。
data[-1]=c data[-2]=b data[-3]=a
data = ["a","b","c"] for i in 0..5 print "data[",i,"]=",data[i],"\n" end[nilについて]
nil は「何もない状態」を示すのに用いられるものです。この課題の場合、
指標で指定された配列の要素には「何もない」ので、意味がぴったりあっていますね。
なお、nil は変数のように見えますが、これは特殊な存在のオブジェクトです。
あとで学ぶクラスとインスタンス、という用語を使うと、NilClassのインスタンスなのです。
そして nil = 1 のようにnilに代入しようとするとエラーが起こります。
obj = "みけねこ" p obj.class.name
"String"
"みけねこ" 200 31.5 500000000000000000 [23,15,8]
"みけねこ" => String 200 => #ここを報告 31.5 => #ここを報告 500000000000000000 => #ここを報告 [23,15,8] => #ここを報告
aray = [1200, 23, "ばけねこ","こねこ","こねこ",11,10,"みけねこ",25,"うみねこ","こねこ"] #この後の部分を作るここで、出力の形式は以下のようなものとします。
ばけねこ こねこ こねこ みけねこ うみねこ こねこ
ここではファイルについて学びます。 ファイルは、現代のコンピュータシステムの基本要素の一つです。 ワードプロセッサーや表計算ソフトのように、どんなアプリケーションプログラムでもファイルを使います。
実際、実用的なプログラムを作る上で、ファイルをプログラムの中から扱かえるようにすることは不可欠です。 ファイルから情報を読み込んで処理したり、その結果をファイルの中に書き込んだりすることが必要になります。
実は、ファイルをプログラムで扱うこと自体はそれほど難しいことではありません。 以下で、プログラムの中からファイルを扱う方法を学びましょう。
ary = ["中京太郎", "豊田次郎", "八事花子"] for name in ary print "名前:",name , "\n" end
名前:中京太郎 名前:豊田次郎 名前:八事花子この結果を、ファイルにとっておくためには、少し準備が必要です。 結果をとっておくファイル名を"names.txt"にすることにします。
fo = open("names.txt", "w")
特定の名前のファイルを開いて(openして)、そのファイルを扱うための仕掛け(ファイルオブジェクトと呼びます)を、 適当な変数(上の場合はfo)に代入しておきます。 プログラムの中では、そのファイルオブジェクトに対して、書いたり読んだりする操作をしていきます。
openという命令の、ファイル名の次にある"w"は、ファイルを書き出し(Write)の形にするためのものです。(ここでその名前のファイルがある場合には、 その中身が消去されることに注意してください。 なお、中身を消去せずに「追加書き」するものや、 ファイルから読み込みするものは後で述べます。) ファイル名も書き出しの"w"も、どちらも文字列で表します。 二重引用符(ダブルクォート)を忘れないように気を付けましょう。
fo = open("ファイル名", "w")これだけ準備しておけば、後は簡単です。
ary = ["中京太郎", "豊田次郎", "八事花子"] fo = open("names.txt", "w") for name in ary fo.print "名前:",name, "\n" end fo.closeこのプログラムを実行すると、names.txtというファイルが作られ、print文の出力が書き込まれます (既にファイルがある場合は上書きされます)。 print文の前に fo. と付け加えられていることに注意してください。 これまでのprint文と違い、この場合は、 変数foの中のファイルオブジェクトに対して書き出すという操作を行います。
ary = ["名古屋政美", "愛知京子", "中部喜朗"] fo = open("names.txt", "a") for name in ary fo.print "名前:",name, "\n" end fo.closeこのプログラムを実行すると、すでにあるnames.txtというファイルの中身は 消されずに、その後ろに、print文の出力が書き込まれます。 これを「追加書き」(Append)といいます。
今度は、プログラムでファイルの中身を読み込む方法を学びます。
ファイルを読み込むためには、読み込む対象となるファイルが存在している必要があります。
上で作ったnames.txtの中身を読み込むことにしましょう。 names.txtという名前のファイルが存在し、その中身が次のようなものであることをTerapadなどで確認しておいてください。
名前:中京太郎 名前:豊田次郎 名前:八事花子
まず、ファイルを扱えるようにしなければならないところは、ファイルの書き出しとほとんど同じです。 書き出しと同様、特定の名前のファイルを開いて(open)して、それを扱うための仕掛け(ファイルオブジェクト)を、 適当な変数(以下の場合はfo)に入れておき、それに対して、読む操作をしていきます。
fo = open("names.txt", "r")
ちなみに、今回はファイルから文字列の「読み込み」を行うので、 右辺の括弧の中の二つ目の文字列が読み込み(Read)を指定する"r"になっています。 (書き出しの場合は"w"でした。)
この準備をしておき、getsを使うと、ファイルの内容を1行だけ読み込みます。 これまでの、キイボードから文字列を入力する(読み込む)ときに使ったgetsと同じです。
$KCODE = "s" #pを使って日本語を表示するときに必要です。 fo = open("names.txt", "r") line1 = fo.gets #1行目の読み込み。 line2 = fo.gets #2行目の読み込み。 line3 = fo.gets #3行目の読み込み。 line4 = fo.gets #4行目の読み込み。 fo.close p line1 p line2 p line3 p line4
"名前:中京太郎\n" "名前:豊田次郎\n" "名前:八事花子\n" nil
getsで読み込まれた1行分の文字列には、改行文字("\n")もついていることに注意してください。
最後のnilというのは、「無」を表す値です。
names.txtには、4行目以降何も書かれていませんので、文字列ではなく、nilが表示れます。
次のプログラムはnames.txtのファイルの内容を、getsによって読み込んでは、すぐに出力することを繰り返し、ファイルの内容をすべて表示するプログラムです。
fo = open("names.txt", "r") while(line = fo.gets) #nilを読み込むまで繰り返す。 print line end fo.close
ファイルからの読み込みは、whileの条件式のところで行っています。 実はwhileは、条件式の値がfalseかnilになるまで繰り返しを続けます。 この場合は、ファイルからの読み込みの値がnilになるまで、読み込みと出力を繰り返します。
この準備をしておき、readlinesを使うと、ファイルの内容を全体として 配列の中に読み込めます。 内容は配列の中に、一行が一つの配列の要素として格納されます。 次のプログラムはnames.txtのファイルの内容をreadlinesを使って aryという配列の中に読み込み、その配列の内容をpによって、 見えるようにしたものです。
$KCODE = "s" ary = [] fo = open("names.txt", "r") ary = fo.readlines p ary fo.close
str = "こねこ おやねこ こねこ こねこ うみねこ こねこ のらねこ みけねこ こねこ" ary = str.split p ary実行結果は次のようになります。
["こねこ", "おやねこ", "こねこ", "こねこ", "うみねこ", "こねこ", "のらねこ", "みけねこ", "こねこ"]
str = "こねこ おやねこ こねこ こねこ うみねこ こねこ のらねこ みけねこ こねこ" #この後の部分を作る
「こねこ」の数は全部で5匹です。
しろねこ みけねこ みけねこ しろねこ しろねこ みけねこ しろねこ しろねこ みけねこ みけねこ しろねこ みけねこ しろねこ みけねこ みけねこ しろねこ くろねこ くろねこ しろねこ みけねこ みけねこ しろねこ くろねこ くろねこ しろねこ みけねこ みけねこ しろねこ みけねこ くろねこ しろねこ みけねこ しろねこ みけねこ しろねこ ばけねこ ... ...省略 ... しろねこ しろねこ くろねこ しろねこ くろねこ しろねこ くろねこ しろねこ しろねこ しろねこ しろねこ しろねこ みけねこ みけねこ しろねこ くろねこ しろねこ くろねこ みけねこ みけねこ しろねこ みけねこ みけねこ しろねこ くろねこ しろねこ くろねこ くろねこ くろねこ みけねこ しろねこ みけねこ みけねこ みけねこ
[ヒント1]
課題3-7では、ファイルの内容を1行ずつ読み込むプログラムを作成しました。 読み込んだ行は、次のような文字列として扱うことができます。
#1行目 "しろねこ みけねこ みけねこ しろねこ しろねこ みけねこ しろねこ しろねこ みけねこ" #2行目 "みけねこ しろねこ みけねこ しろねこ みけねこ みけねこ しろねこ" #3行目 ...
課題3-7では読み込んだ文字列をそのまま出力していましたが、今度は「とらねこ」の数を数えなければいけません。 ねこの数を数えるのは、課題3-6のプログラムが参考になりそうですね。
[ヒント2]
ファイルから1行読み込むたびに、「とらねこ」の数を数え、合計に加算していく必要があります。
合計は最初は0匹。 while... #ファイルから1行ずつ読み込む。 「とらねこ」の数を数える。 合計に「とらねこ」の数を加算する。 end
「とらねこ」の数を数える所は、課題3-4で作成した通りですので、おそらく次のような形になるでしょう。
str = 1行分の文字列 ねこの文字列を分割する。 「とらねこ」は最初0匹。 while... #ねこを1匹ずつチェックする。(for文を使ってもよい。) 「とらねこ」なら1匹加算する。 end
このプログラムを、上の合計を数えるプログラムに組み込む必要がありますので、完成すると次のような形になるはずです。
合計は最初は0匹。 while... #ファイルから1行ずつ読み込む。 str = 1行分の文字列 ねこの文字列を分割する。 「とらねこ」は最初0匹。 while... #ねこを1匹ずつチェックする。(for文を使ってもよい。) 「とらねこ」なら1加算する。 end 合計に「とらねこ」の数を加算する。 end
ファイルから1行ずつ読み込む繰り返しの中で、ねこを1匹ずつチェックする繰り返しを行います。 (while文の中にwhile文が入ります。)