第7回 基礎プログラミング I レポート課題 金田麻美 C1090466 英語3 政策マネジメント 1-A 2進数から16進数への変換には、変換したい2進数を後ろから4桁ずつに区切り、 それを16進数の変換表に当てはめるという方法がある。 11110110 は、 1111 と 0110 に区切られる。 この4桁の数字を変換表に当てはめる。 1111 = f 0110 = 6 よって、0b11110110 = 0xf6 1-B 10進数から16進数への変換は、変換したい10進数を2進数へ変換し、 その2進数を16進数へ変換するという方法をとっても可能である。 まず256を2進数へ変換する。10進数から2進数への変換は、10進数を商が0になる まで割っていき、それまでに生じた余りを最後から並べる方法でおこなう。 256 / 2 = 128 余り 0 128 / 2 = 64 0 64 / 2 = 32 0 32 / 2 = 16 0 16 / 2 = 8 0 8 / 2 = 4 0 4 / 2 = 2 0 2 / 2 = 1 0 1 / 2 = 0 1 下から読むと100000000 0d256 = 0b100000000 この 0b100000000 は、 0001 , 0000 , 0000 に区切られる。 この4桁の数字を変換表に当てはめる。 0001 = 1 0000 = 0 0000 = 0 よって、0d256 = 0x100 参考文献 「生活と情報(2009)」講義レジュメ 「第2回 情報のデジタル化[1] 2進数」 神田直弥 p4 「2進数によるデータ表現」,「10進数から2進数へ」, 「2進数←→16進数の相互変換」 ------------------------------------------------------------------------- 2. Aを選択した。 a) 授業で作成した write_ticket.rb も open -- end でデータを読み込んで 配列にしまい、あとの while文で結果を出すものだったので、これを土台にした。 しかし設問に合ったプログラムにするには多くの変更が必要であった。 設問や参考ページの Lecture_notes から、まず各配列の合計を積み上げ、 そこから「全体の合計 = 1日の売上げ」 を出し、それを客数で割ることから 客単価を出すプログラムが考えられた。 なので各行の += で合計を積み上げ、 [客単価の変数] = [合計の変数]/[列の変数].length のようにして 客単価を出す文を、配列にしまう文のあとに作るような構成を考えた。 しかし設問には、タイプで値段が異なるというポイントがあり、これに対しては if文を使い、タイプ別に変数を設け、違う値段だと設定する形が考えられた。 このような考えから、全体として 1 準備部分: データを配列にしまう、 open -- end文。 2 実際の演算部分: while -- end文の中にif文を入れて値段設定をし、 各行の合計を += で合計の変数に積み上げていく。 3 結果表示: 客単価の変数を設け、 xx = xx/xx.length のようにして客単価を出し、 1日の売上げと客単価を表示させる printf文。 このような構成の open_battery.rb を作成した。 なお、1日の客数は、売上げ伝票の行数と考えた。 1人が1タイプを買っていったということになる。 b) 1 作成したデータ C 4 B 2 B 1 A 1 B 3 A 10 -------------------- 2 プログラム #!/usr/koeki/bin/ruby $KCODE = 'e' # コンピュータへの漢字コードを扱ってくれという指示 type = Array.new # type という変数に電池のタイプの配列をしまう set = Array.new # set という変数に売上げセット数の配列をしまう i = 0 # 売上げの回数(行数) open("battery.dat","r") do |den| # open-end でデータを指定、"r"で読み込ませている。 そして読み込んだデータを 変数den に一時的に代入しておく。 while sale = den.gets # 変数sale に、gets でデータを入れる。sale に battery.datが入った。 ここからは条件付けを使った、データの処理。 if /(\S+)\s+(\d+)/ =~ sale # sale すなわち battery.dat のつくりが、 "文字、空白、数字"と、全く同じだったら(=~) # print sale # ちゃんと sale にデータが入ってるかの確認。問題なかったので消した。 type[i] = $1 # 1列目は type という変数に代入される。[i]で一行一行処理される。 set[i] = $2.to_i # 2列目は set に代入。こっちはセット数なので、整数で表示させるために.to_i # p type, set # それぞれの変数に代入されているかの確認。これも消した。 i += 1 # 回数(行数)が一つずつ増える(まわる)ので、全ての行を配列にしまう。 end # if の end end # while の end end # open の end #p type # 確認に使った #p set # 同上 k = 0 # 表示回数。最初は0 total = 0 # 1日の売上げ。演算が始まっていないので0 while k < type.length # 表示回数は type の個数。すなわち6 if type[k] == "A" # その行の type が A だったら a = set[k] * 400 # この行の set に400(値段)をかける。 これがこの行の合計(売上げ)だから、変数a に代入。 printf("%s タイプ:\t%d円の売り上げ\n", type[k],a) # printf文で、この行のタイプ、この行の合計(売上げ)が代入されて表示 total += a # 全体の合計(1日の売上げ)はこの a を足していくことで求められる。 elsif type[k] == "B" # その行の type が Bだったら b = set[k] * 300 # この行の set に300(値段)をかける。 これがこの行の合計(売上げ)だから、変数b に代入 printf("%s タイプ:\t%d円の売り上げ\n", type[k],b) # printf文で、この行のタイプ、この行の合計(売上げ)が代入されて表示 total += b # 全体の合計(1日の売上げ)はこの b も足していくことで求められる elsif type[k] == "C" # その行の type が Cだったら c = set[k] * 50 # この行の set に50(値段)をかける これがこの行の合計(売上げ)だから、変数c に代入 printf("%s タイプ:\t%d円の売り上げ\n", type[k],c) # printf文で、この行のタイプ、この行の合計(売上げ)が代入されて表示 total += c # 全体の合計(1日の売上げ)はこの c も足していくことで求められる end # if の end k += 1 # 表示回数は1つずつまわっていく end # while の end avg = total / type.length # 客単価 avg は、1日の売上げ total を type の行数(type.length)で 割ることによって求められる変数である。 printf("本日の売上:\t%d 円\n",total) # 1日の売上げ total はまず整数なので %d で代入させる。\t は間を空ける。 printf("本日の客単価:\t%9.1f 円\n",avg) # 客単価 avg は小数点になりやすいので %f で代入する。 1000万円買う客はまずいないと考えて 9.1 c) 最初の open -- end文 の部分はプログラム名や変数名の変更のみである。 write_ticket.rb はユーザーに入力を促し、そこから演算して結果を出す プログラムであって、私が考えている形とは違う。 なので3ブロック目からのユーザーの入力を代入して演算する部分は省き、 逆にデータファイルの内容を表示させる2ブロック目の while文に、 各行の合計を出すように計算式を追加した。 また、1日の売上げの変数を演算前に、客単価の変数を演算後に配置した。 タイプによって値段が違うという設問から、if文にあわせて 各々の合計を代入する変数も設け、合計の変数に足していくという方法をとった。 そして、最後に printf文で結果を表示するような形に変更した。 d) pan{c109046}% ./open_battery.rb [~/Ruby] C タイプ: 200円の売り上げ B タイプ: 600円の売り上げ B タイプ: 300円の売り上げ A タイプ: 400円の売り上げ B タイプ: 900円の売り上げ A タイプ: 4000円の売り上げ 本日の売上: 6400 円 本日の客単価: 1066.0 円 ----- タイプの順番は合っており、表示も想定通りである。 計算が合っているかは、次項で確かめる。 e) pan{c109046}% bc -l [~/Ruby] 50 * 4 # 各行の合計 200 300 * 2 600 300 * 1 300 400 * 1 400 300 * 3 900 400 * 10 4000 200 + 600 + 300 + 400 + 900 + 4000 # 1日の売上げ 6400 6400 / 6 # 客単価 1066.66666666666666666666 quit 売上げまでは正しいのだが客単価がおかしい。 プログラムの結果は 1066.0 となっているが、確かめ算の結果は 1066.666 ... である。確かめ算の方が正しいのでプログラムが間違っていることになる。 小数点以下が切り捨てになっているのかと思うのだが、はっきりとはわからない。 調べてみたが解決できなかったので、不完全ではあるがこのまま提出する。 f) 参考文献 基礎プログラミング I 第5回 配列の構造 「配列 Array」 http://roy/~madoka/2010/r1/05/05_03_theme_02_array.html 基礎プログラミング I 第7回 正規表現と Ruby 言語でのプログラミング 「データを読み込むようにするには」 http://roy/~madoka/2010/r1/07/07_09_theme_08_fileread.html 基礎プログラミング I 第7回 正規表現と Ruby 言語でのプログラミング 「候補駅を選べるようにするには」 http://roy/~madoka/2010/r1/07/07_11_theme_09_candidate.html 基礎プログラミング I 第7回 正規表現と Ruby 言語でのプログラミング 「券売機のしくみ」 http://roy/~madoka/2010/r1/07/07_13_theme_11_vendingmachine.html 以上 全て著者は 西村まどか 3 感想 今回はデータを自動的に読み込む open -- end文を学んだ。 それに合わせて、これまで学んできた、空白の利用や配列のしくみも活用した。 空白の利用はようやく自分で使えるようになったが、配列のしくみの理解が 足りていなかったことが今回のレポート課題を通してわかった。 平日の時間を全然活用しないでしまっているので、平日に頑張って打ち込み、 ついていけるように、プログラミングにもっと慣れて楽しくなるようにしたい。 今回は自分の、すぐ思考がこんがらがる面がよく実感できたので、 今の時期から克服するようがんばりたい。 今回、一番頑張って書いたのは2ブロック目の実行結果に表示される部分だが、 本当はその前の、どんなプログラムになるのか考える段階が一番力が要った。 if文を使ってタイプ別に計算式を書くのは頭にあったが、変な形で、 合計の変数を設けるのも忘れていて、先輩に大部分を教わった。 その上完成したプログラムは客単価の不備があったりと、 至らないところは多いが、これから頑張れば出来るようになると希望を持って、 気合をいれて取り組んでいきたい。 共同学習者: 笹原千珠子 協力してくれた先輩: 齊藤啓司 さん