氏名: long 学籍番号: c111116 クラス: 英語6 ・どの問題を選択したか 今回は3番を選びました。 前回の課題データをもとにそれぞれの本が価格順、発行年順、 発行部数順に表示することができるようにしました。 しかし、発行部数のみ調べることができなかったので あくまでもイメージで表示させました。 ・作成したプログラム本体 #!/usr/koeki/bin/ruby # coding: euc-jp novel = Hash.new print "今読みたい本を選ぶ参考にしてください♪\n" print "価格の高い順か発行年の新しい順、発行部数が多い順に表示されます。\n" while true STDERR.print "0か1か3を選択して下さい。\n" puts "0.価格" puts "1.発行年" puts "2.発行部数" n = STDIN.gets.chomp!.to_i if n == 0 || n == 1 || n == 2 then break end end while line = gets if /(\S+)\s+(\d+)\s+(\d+)\s+(\d)/ =~ line novel[$1] = [$2.to_i, $3.to_i, $4.to_i] end end print "--作品名-------------+-価格-+-発行年-+-発行部数--\n" for books in novel.keys.sort {|x, y| novel[x][n] <=> novel[y][n]}.reverse kakaku = novel[books][0] hakkounen = novel[books][1] busu = novel[books][2] printf("%-17s %5d円 %5d年 %5d万部\n", books, kakaku, hakkounen, busu) end puts "-"*40 ・プログラムの説明(データ処理の部分の詳説) 各行の並びは「作品名、価格、発行年、発行部数」となっており、 今回のプログラムは各行のデータを全て読み込み、それぞれ数値が大きい順に 並べられるようにするというものである まず、任意の値に任意の値を結びつけることが出来るように novel の変数に { 作品名 => [価格, 発行年,発行部数] } というハッシュを格納するプログラムを作成し、 while line = gets if /(\S+)\s+(\d+)\s+(\d+)\s+(\d)/ =~ line novel[$1] = [$2.to_i, $3.to_i, $4.to_i] end end と入力する。 ここで $1 は作品名、$2,$3,$4 はそれぞれ価格、発行年、発行部数を示し、 数値なので .to_i を付ける。 「価格」を例に挙げて説明すると、 point = { "カラスの親指" => [780, 2011, 80], "悪の教典" => [1785, 2011, 150], "ツナグ" => [661, 2012, 100], "ハング" => [720, 2009, 65], "告白" => [649, 2010, 200], } これを価格の高い順に並べ換えるため、 各ハッシュの要素の key だけを取り出した上でsort メソッドを扱う。 sort メソッドは配列の内容を並べ換えるメソッドであり、 各要素を、演算子 <=> で比較し並べ換える。 並べる基準を変えたい場合は引数を2つ取るブロックを指定し、 key の値(作品名)で並び変えるわけではなく、 価格どうしで比較するので keys.sort {|x, y| novel[x][n] <=> novel[y][n]} のように打ち込む。(変数 x,y には、比較対象となる作品名が入る。) しかし、このままでは価格の小さい順に並び換えられた 作品名が得られてしまう。 そこで配列のすべてを逆順に並べた配列を返すことができる reverse メソッドと、用いて novel.keys.sort {|x, y| novel[x][n] <=> novel[y][n]}.reverse と打てば、価格の高い順に並べることができる。 これは、発行年、発行部数にも同様にして言うことができる。 そして前回習ったように 1つ1つずつ要素を取り出す for メソッドを用いてループを作成し 価格(kakaku)、発行年(hakkounen)、発行部数(busu)と打ち込み、 for books in novel.keys.sort {|x, y| novel[x][n] <=> novel[y][n]}.reverse kakaku = novel[books][0] hakkounen = novel[books][1] busu = novel[books][2] printf("%-17s %5d円 %5d年 %5d万部\n", books, kakaku, hakkounen, busu) end となる。 この過程で結果が出力される。 ・実行結果 pan{NAGAHASHI Manami}% ./total-rank3.rb figure.txt [~/Ruby] 今読みたい本を選ぶ参考にしてください♪ 価格の高い順か発行年の新しい順、発行部数が多い順に表示されます。 0か1か3を選択して下さい。 0.価格 1.発行年 2.発行部数 0 --作品名-------------+-価格-+-発行年-+-発行部数-- 悪の教典 1785円 2011年 1万部 カラスの親指 780円 2011年 8万部 ハング 720円 2009年 6万部 ツナグ 661円 2012年 1万部 告白 649円 2010年 2万部 ---------------------------------------- pan{c111116}% ./total-rank3.rb figure.txt [~/Ruby] 今読みたい本を選ぶ参考にしてください♪ 価格の高い順か発行年の新しい順、発行部数が多い順に表示されます。 0か1か3を選択して下さい。 0.価格 1.発行年 2.発行部数 1 --作品名-------------+-価格-+-発行年-+-発行部数-- ツナグ 661円 2012年 1万部 カラスの親指 780円 2011年 8万部 悪の教典 1785円 2011年 1万部 告白 649円 2010年 2万部 ハング 720円 2009年 6万部 ---------------------------------------- pan{NAGAHASHI Manami}% ./total-rank3.rb figure.txt [~/Ruby] 今読みたい本を選ぶ参考にしてください♪ 価格の高い順か発行年の新しい順、発行部数が多い順に表示されます。 0か1か3を選択して下さい。 0.価格 1.発行年 2.発行部数 0 --作品名-------------+-価格-+-発行年-+-発行部数-- 悪の教典 1785円 2011年 1万部 カラスの親指 780円 2011年 8万部 ハング 720円 2009年 6万部 ツナグ 661円 2012年 1万部 告白 649円 2010年 2万部 ---------------------------------------- pan{c111116}% ./total-rank3.rb figure.txt [~/Ruby] 今読みたい本を選ぶ参考にしてください♪ 価格の高い順か発行年の新しい順、発行部数が多い順に表示されます。 0か1か3を選択して下さい。 0.価格 1.発行年 2.発行部数 1 --作品名-------------+-価格-+-発行年-+-発行部数-- ツナグ 661円 2012年 1万部 カラスの親指 780円 2011年 8万部 悪の教典 1785円 2011年 1万部 告白 649円 2010年 2万部 ハング 720円 2009年 6万部 ---------------------------------------- pan{c111116}% ./total-rank3.rb figure.txt [~/Ruby] 今読みたい本を選ぶ参考にしてください♪ 価格の高い順か発行年の新しい順、発行部数が多い順に表示されます。 0か1か3を選択して下さい。 0.価格 1.発行年 2.発行部数 2 --作品名-------------+-価格-+-発行年-+-発行部数-- カラスの親指 780円 2011年 8万部 ハング 720円 2009年 6万部 告白 649円 2010年 2万部 悪の教典 1785円 2011年 1万部 ツナグ 661円 2012年 1万部 -------------------------------------------------- 参考文献 株式会社 紀伊國屋書店. "紀伊國屋書店週間ベストセラー". 本の「今」がわかる紀伊國屋書店. http://www.kinokuniya.co.jp/ranking/pocketbook.html , (参照 2012-10-21) 広瀬雄二. "配列処理メソッド". 2012年度 基礎プログラミングII. http://roy/~yuuji/2012/pf2/05/arraymethod.html , (参照 2012-10-22) 広瀬雄二. "ハッシュ". 2012年度 基礎プログラミングII. http://roy/~yuuji/2012/pf2/04/hash.html , (参照 2012-10-22) 広瀬雄二. "本格的なデータ処理". 2012年度 基礎プログラミングII. http://roy/~yuuji/2012/pf2/05/dataproc.html , (参照 2012-10-22) 広瀬雄二. "ファイル入出力". 2012年度 基礎プログラミングI. http://roy/~yuuji/2012/pf1/07/file-io.html , (参照 2012-10-22) ・感想 今回は公翔祭の準備で調べる時間がなく発行部数を調べることができなかった。 次回からは時間に余裕をもって データも正確なプログラミングを作っていきたい。