講評: 近いところまできました。単語登録には Hash 配列を使う部分が必要です。 ---- 10 月 10 日 第 2 回レポート 「Hash 配列」 学籍番号: C106XXXXX 氏名: XXXXXXXX 語学クラス: XXXX語 XX 系: XXXX系 [1] 漫画「ドラゴンボール」のキャラクターの特徴を hash 配列 anime としました。 anime の key と value はそれぞれキャラクター名とその必殺技にとりました。 その 1: key 「悟空」に対して value は「かめはめ波」 その 2: key 「ベジータ」に対して value は「ギャリック砲」 その 3: key 「クリリン」に対して value は「気円斬」 その 4: key 「悟飯」に対して value は「魔閃光」 その 5: key 「ピッコロ」に対して value は「魔貫光殺砲」 ■ 1行に 1つの組み合わせ、後ろに次々に対を足していく方法 ■ anime["悟空"] = かめはめ波 anime["ベジータ"] = ギャリック砲 anime["クリリン"] = 気円斬 anime["悟飯"] = 魔閃光 anime["ピッコロ"] = 魔貫光殺砲 ■ いくつも 1行で書き込む方法 ■ anime = {"悟空"=>かめはめ波, "ベジータ"=>ギャリック砲, "クリリン"=>気円 斬, "悟飯"=>魔閃光, "ピッコロ"=>魔貫光殺砲} [2] A. ■ 0d 1022 = 0x ?? ■ 0x は 16進数なので一度2進数に変換する。 2で割っていきその値を下から読んで答えを求める。 1022 / 2 = 511 ... 0 511 / 2 = 255 ... 1 255 / 2 = 127 ... 1 127 / 2 = 63 ... 1 63 / 2 = 31 ... 1 31 / 2 = 15 ... 1 15 / 2 = 7 ... 1 7 / 2 = 3 ... 1 3 / 2 = 1 ... 1 0b = 1111111110 変換した2進数を4桁に区切り、16進数に変換する。 1111111110 1110 = e 1111 = f 0011 = 3 答え: 0x = 3fe B. ■ 0d 1022 = 0b ?? ■ 0b は2進数なので、2で割っていきその値を下から読んで答えを求める。 1022 / 2 = 511 ... 0 511 / 2 = 255 ... 1 255 / 2 = 127 ... 1 127 / 2 = 63 ... 1 63 / 2 = 31 ... 1 31 / 2 = 15 ... 1 15 / 2 = 7 ... 1 7 / 2 = 3 ... 1 3 / 2 = 1 ... 1 答え、0b = 1111111110 今回はAの確認の意味も込めて16進数に変換する。 2進数を4桁に区切り、16進数に変換する。 1111111110 1110 = e 1111 = f 0011 = 3 0x = 3fe よって、Aの問題は正解である。 さらに問題と同じ 0d = 1022 になるか計算してみることにする。 10進数に変換するには、2進数の1がつく桁に2の乗数をかけて足算をする。 0b = 1111111110 0 ... 0 1 ... 2^1 = 2 1 ... 2^2 = 4 1 ... 2^3 = 8 1 ... 2^4 = 16 1 ... 2^5 = 32 1 ... 2^6 = 64 1 ... 2^7 = 128 1 ... 2^8 = 256 1 ... 2^9 = 512 2 + 4 + 8 + 16 + 32 + 64 + 128 + 256 + 512 = 1022 0b = 1022 よってこの問題はA、Bの答えは正解である。 [3] あらかじめプログラムに登録してある対を表示する。 データから読み込むようにしたプログラムへ変更する。 ユーザが知りたい情報だけを表示するプログラムへ変更する。 hash-for.rb ■ 考えた設定 ■ hash配列を用いてプログラムを作る。その後に上記のように変更する。 ■ プログラム ■ #!/usr/koeki/bin/ruby 1 : $KCODE = 'e' 2 : sekiyu = Hash.new("非取扱い商品") 3 : sekiyu["レギュラー"] = 140 3 : sekiyu["ハイオク"] = 150 3 : sekiyu["軽油"] = 110 3 : sekiyu["灯油"] = 100 4 : for item, price in sekiyu 4 : printf("%-20s\t%10d円\n", item, price) 4 : end 5 : STDERR.print("\n購入する品物: ") 5 : shouhin = gets.chomp 6 : STDERR.print("購入する重量: ") 6 : litter = gets.chomp.to_f 7 : if sekiyu.key?(item) == false 7 : printf("%sは%sです\n",shouhin, sekiyu[item]) 8 : else 8 : printf("\n%-20s(%1.0fリッター)\t%10.0f円\n",shouhin, litter, sekiyu[item] * litter) 8 : end ■ プログラムの解説 ■ 上記より 1 : 漢字コードは EUC でという意味のプログラムである。 2 : Hash 配列を sekiyu と定義する。 3 : Hash 配列に key と value を当てはめていく。 key レギュラー に value 140 key ハイオク に value 150 key 軽油 に value 110 key 灯油 に value 100 4 : 全ての Hash の対をきれいに出力。 5 : 購入する品物を入力させ、gets.chomp により 変数shouhin に当てはめる。 6 : 購入する重量を入力させ、gets.chomp により 変数litter に当てはめる 7 : 該当しないキーが呼び出されたときのプログラムである。 「非商品である」と表示される。 8 : 該当するキーが呼び出されたときは print により、 商品名 と リッター数 と値段 が表示される。 ■ 実行結果 ■ irsv{c106089}% ./hash-for.rb [~/Ruby] 灯油 100円 軽油 110円 ハイオク 150円 レギュラー 140円 購入する品物: レギュラー 購入する重量: 20 レギュラー (20リッター) 2800円 ■ 実行結果の考察 ■ 最初にレギュラーを選択し、重量は20リッターを選択。 手計算 140 × 20 = 2800 よってこのプログラムの計算は正常に行なわれている。 プログラムで対を登録し、表示させるプログラム。 登録した情報をファイルデータとして出力するプログラムに変更する。 hash-register.rb ■ 考えた設定 ■ hash配列を用いてプログラムを作る。その後に上記のように変更する。 ■ プログラム ■ #!/usr/koeki/bin/ruby 1 : shouhin = Hash.new 2 : print("商品を登録します。\n") 2 : print("終了は Ctrl-D です。\n") 3 : while true 4 : STDERR.print("\n商品名を登録して下さい。\n") 4 : item = gets 5 : if item == nil 5 : then break 5 : else 5 : item = item.chomp 5 : end 6 : STDERR.print("\n価格を登録して下さい。\n") 6 : price = gets.chomp.to_i 6 : shouhin[item] = price 3 : end 7 : STDERR.print("\n\n登録を終了しました。\n") 8 : $KCODE = 'e' 9 : for item, price in shouhin do 9 : printf("%-20s\t%10d円\n", item, price) 9 : end 10 : print("\n高いもの順に並べ替えます。\n") 11 : shouhin.keys.sort{ 11 : |prim,sorted| 11 : shouhin[prim] <=> shouhin[sorted] 11 : }.reverse.each{ 11 : |item| 11 : printf("%-20s\t%10d円\n", item, shouhin[item]) 11 : } ■ プログラムの解説 ■ 上記より 1 : Hash 配列を shouhin と定義する。 2 : printにより表示される。 3 : endまで繰り返し 4 : 商品名を入力させ、変数itemに当てはめる。 5 : Ctrl-D が押されたら修了するプログラムである。 5 : Ctrl-D 以外の文字列はここに進む 6 : 商品名を入力させ、gets.chomp により 変数item に当てはめる。 7 : 価格を入力させ、gets.chomp により 変数price に当てはめる。 8 : 漢字コードは EUC でという意味のプログラムである。 9 : 全ての Hash の対をに出力する。 10 : printにより表示される。 11 : 高いもの順に並べ替えて表示するプログラムである。 ■ 実行結果 ■ irsv{c106089}% ./hash-register.rb [~/Ruby] 商品を登録します。 終了は Ctrl-D です。 商品名を登録して下さい。 ステーキ 価格を登録して下さい。 1000 商品名を登録して下さい。 ハンバーグ 価格を登録して下さい。 700 商品名を登録して下さい。 サラダ 価格を登録して下さい。 300 商品名を登録して下さい。 ドリンクバー 価格を登録して下さい。 250 商品名を登録して下さい。 ^D 登録を終了しました。 ハンバーグ 700円 ステーキ 1000円 ドリンクバー 250円 サラダ 300円 高いもの順に並べ替えます。 ステーキ 1000円 ハンバーグ 700円 サラダ 300円 ドリンクバー 250円 ■ 実行結果の考察 ■ 入力したものが表示され、高いもの順に並べかえられた。 [4] ■ 考えた設定 ■ 単語帳を作成するプログラムを作り、そのデータからクイズを出題 するプログラムも作成する。 wordbook.rb words.dat wordquiz.rb ■ 単語帳を作成するプログラム ■ #!/usr/koeki/bin/ruby 1 : open("words.dat","w") do |words| 1 : end 2 : print("単語登録\n") 3 : while true 4 : STDERR.print("単語を入力して下さい。\n") 4 : kuizu = gets.chomp 5 : if kuizu == "a" then 5 : break 5 : end 6 : open("words.dat","a") do |words| 6 : words.print("",kuizu) 6 : words.print("\t") 6 : end 7 : STDERR.print("読み方を入力して下さい。終了は a です。\n") 7 : yomikata = gets.chomp 8 : open("words.dat","a") do |words| 8 : words.print("",yomikata) 8 : words.print("\n") 8 : end 3 : end ■ プログラムの解説 ■ 上記より 1 : words.datに新規書き込みするプログラムである。 2 : print により表示される。 3 : endまで繰り返し 4 : 単語を入力させ、変数kuizuに当てはめる。 5 : a が押されたら修了するプログラムである。 6 : words.datに単語を書き込むプログラムである。 7 : 読み方を入力させ、変数yomikataに当てはある。 8 : words.datに読み方を書き込むプログラムである。 ■ 実行結果 ■ irsv{c106089}% ./wordbook.rb [~/Ruby] 単語登録 単語を入力して下さい。 弘武 読み方を入力して下さい。終了は a です。 ひろむ 単語を入力して下さい。 押切 読み方を入力して下さい。終了は a です。 おしきり 単語を入力して下さい。 押切弘武 読み方を入力して下さい。終了は a です。 おしきりひろむ 単語を入力して下さい。 a ■ words.dat ■ 弘武 ひろむ 押切 おしきり 押切弘武 おしきりひろむ ■ 実行結果の考察 ■ datファイルの1列目に漢字、2列目に読み方を書き込んだ。 ■ クイズを出題するプログラム ■ #!/usr/koeki/bin/ruby 1 : woo = Array.new 2 : while words_data = gets 3 : if /(\S+)\s+(\S+)/ =~words_data 4 : woo[1] = $1 4 : woo[2] = $2 3 : end 5 : printf("%s\n",woo[1]) 5 : print("この読み方は何??\n\n") 5 : printf("答え、%s\n\n",woo[2]) 2 : end ■ プログラムの解説 ■ 1 : 配列を新規につくるプログラム。 2 : endまで繰り返し gets により変数words_data にデータが取り込まれる。 3 : 変数words_data に入っているデータを分解するプログラム。 4 : woo[1] は $1 つまりデータファイルの1列目のデータをしまう変数 woo[2] は $2 つまりデータファイルの2列目のデータをしまう変数 5 : print により表示される。 ■ 実行結果 ■ irsv{c106089}% ./wordquiz.rb words.dat [~/Ruby] 弘武 この読み方は何?? 答え、ひろむ 押切 この読み方は何?? 答え、おしきり 押切弘武 この読み方は何?? 答え、おしきりひろむ ■ 実行結果の考察 ■ 最初に一列目に保存した漢字を出力して、「読み方は何?」 と表示させる。その5秒に答えを表示された。 [5] 今回はhash配列について学んだ。 単語帳に書き込むプログラムに関しては、前期のグループで作った レジのプログラムが参考になった。open - endを用いてdatに書き込みをした。 hash配列 はまだわからない点があるかもしれないのでもっと勉強していきたい。