第4回 繰り返しは引っ張り出そう レポート課題 氏名 : 余語結佳 学籍番号 : c1101974 語学クラス : 英語2 コース : 地域共創コース ---------------------------------------------------------------------- 1. 筆記問題 ---------------------------------------------------------------------- **************************** A **************************** 女心と解きまして、プログラミングと解く その心は どちらも難しいからです。 ************************** B - 1*************************** 西村菓子店では、ハロウィン向けに商品をいくつか用意しました。 用意したものは以下の通りです。 おばけかぼちゃ型のアメ1つ 500円 黒ネコチョコレート1つ 300円 魔女の家を型どったケーキ 2500円 おかし詰め合わせ 600円 こうもり型クッキー1枚 50円 1人目のお客さんは、 おかし詰め合わせ2つとクッキーを10枚購入して行きました。 ( 600 * 2 ) + ( 50 * 10 ) = 1700 円 確認 pan{YOGO Yuka}% bc -l [~] 600*2+50*10 1700 quit 以上から、1人目のお客さんの会計は1700円でした。 2人目のお客さんは チョコレートを5つ、ケーキを2つ購入していきました。 ( 300 * 5 ) + ( 2500 * 2 ) = 6500 円 確認 pan{c110197}% bc -l [~] 300*5+2500*2 6500 quit 以上から、2人目のお客算の会計は6500円でした。 ************************** B - 2*************************** 公益食堂では食券を販売しています。 メニューは以下の通りです ◯食べ物 ラーメン 800円 塩ラーメン 850円 うどん 650円 カレーうどん 700円 炒飯 850円 ハンバーグ定食 1200円 お魚定食 1200円 ◯飲み物 オレンジジュース 100円 コーラ 120円 エスプレッソ 300円 ミルクティー 250円 まるこちゃんはラーメンとオレンジジュースをたのんで行きました。 800 + 100 = 900円 確認 pan{c110197}% bc -l [~/Ruby] 800+100 900 quit 以上から、まるこちゃんの合計は900円です ひろし君はカレーうどんとエスプレッソの食券のボタンを押しました。 700 + 300 = 1000円 確認 pan{c110197}% bc -l [~/Ruby] 700+300 1000 quit 以上から、ひろしくんの合計は1000円です。 --------------------------------------------------------------------- 2. プログラム問題 ---------------------------------------------------------------------- ********************************************************************** 作成したプログラム : A の def_twoparam.rb ****************************** 考えた設定 **************************** 1のB-2で考えたような、お客さんが食券のボタンを押して合計金額が出力される という、従業員のいないレジ機能をつくろうと思いました。 例では商品の個数を入力する物になっていましたが、このプログラムは商品番号 を押してもらうと自動的に計算できるようになっています。 また、筆記問題の段階では御飯と飲み物だけですがこのプログラムにするにあたっ てデザートもつけたしています。 *************************** 作成したプログラム *********************** #!/usr/koeki/bin/ruby #goukeiメソッドで使う引数は(x,y,z)なので3つあることがわかる #def-end以下でgoukeiメソッドを呼ばれたときにこのdef-endの中のプログラムが動く。 def goukei(x,y,z) #食べ物if if x == 1 #ラーメン x = 800 elsif x == 2 #塩ラーメン x = 850 elsif x == 3 #うどん x = 650 elsif x == 4 #カレーうどん x = 700 elsif x == 5 #炒飯 x = 850 elsif x == 6 || 7 #ハンバーグ定食またはお魚定食。||は「または」の意味 x = 1200 elsif x == 8 #いらない x = 0 end #食べ物if-end #飲み物if if y == 1 #オレンジジュース y = 100 elsif y == 2 #コーラ y = 120 elsif y == 3 #エスプレッソ y = 300 elsif y == 4 #ミルクティー y = 250 elsif y == 5 #いらない y = 0 end #飲み物if-end #デザートif if z == 1 #杏仁豆腐 z = 500 elsif z == 2 #ゼリー z = 350 elsif z == 3 #アイスクリーム z = 200 elsif z == 4 #チョコレートパフェ z = 650 elsif z == 5 #あんみつ z = 400 elsif z == 6 #いらない z == 0 end #デザートif-end gohan = x + y + z #それぞれの引数にはifで代入した値段が入っているからここで加算すれば自動的に合計が算出される printf("\e[41;30m 合計で %d 円になります\e[m \n",gohan) end #def-end #\e[数字m で色付き文字開始 #\e[m で色付き文字終了 STDERR.print"\n \e[35m 御希望の食べ物は何ですか?\e[m \n" STDERR.print" 1 ラーメン 800円 2 塩ラーメン 850円 3 うどん 650円 4 カレーうどん 700円 5 炒飯 850円 6 ハンバーグ定食 1200円 7 お魚定食 1200円 8 いらない\n" STDERR.print"\n番号を入力してください。: " food = gets.to_i STDERR.print"\n \e[35m 飲み物はいかがですか?\e[m \n" STDERR.print" 1 オレンジジュース 100円 2 コーラ 120円 3 エスプレッソ 300円 4 ミルクティー 250円 5 いらない\n" STDERR.print"\n番号を入力してください。: " drink = gets.to_i STDERR.print"\n \e[35m デザートはいかがですか?\e[m \n" STDERR.print" 1 杏仁豆腐 500円 2 ゼリー 350円 3 アイスクリーム 200円 4 チョコレートパフェ 650円 5 あんみつ 400円 6 いらない\n" STDERR.print"\n番号を入力してください。: " dessert = gets.to_i goukei(food,drink,dessert) #ここでgoukeiメソッドを呼び出して、それぞれの引数にあたるのはfood,drink,dessertですよと教えている。 *********************** 参考にしたプログラム ************************* 参考にしたのは授業で作ったdet_funk.rbと、自分でためしに作ったdet_test.rb です。参考にしただけなので変更点はありません。 このdef_test.rbでためしたことは、def内の定義は一番最後の行の定義が返され ることの確認と、p文などの場合でも最後の行しか返されないのか?ということで す。 ◯一番最後の行が返される det_test.rbの一部を貼ると以下のようになります。実行結果もプログラムの中 にコメントで書いていましたのでそのまま貼らせていただきます。 def yuka (x) x + 2 x + 10 end printf("答えは%d\n",yuka(5)) #実行結果 #pan{YOGO Yuka}% ./def_test.rb [~/Ruby] #答えは15 #という出力結果により、dafで定義されたものは一番下のみが有効だということ がわかった ◯p文,printf,print def plus (x) anser = x + 10 print"aaaaa\n" p anser printf("こたえ %d\n",anser) printf("答え %d\n",anser) end plus(10) printf("答えは%d\n",plus(10)) #実行結果 #pan{YOGO Yuka}% ./def_test.rb [~/Ruby] #aaaaa #20 #こたえ 20 #答え 20 #以上の結果から、print,printf,p,などには一番下のみが有効というわけではないということがわかる。 #つまり「一番下のみが有効」というのは定義付けのときのみの話だということがわかる。 ******************************* 実行結果 ***************************** ●選んだものがラーメン、コーラ、アイスクリームだった場合 pan{c110197}% ./def_twoparam.rb [~/Ruby] 御希望の食べ物は何ですか? 1 ラーメン 800円 2 塩ラーメン 850円 3 うどん 650円 4 カレーうどん 700円 5 炒飯 850円 6 ハンバーグ定食 1200円 7 お魚定食 1200円 8 いらない 番号を入力してください。: 1 飲み物はいかがですか? 1 オレンジジュース 100円 2 コーラ 120円 3 エスプレッソ 300円 4 ミルクティー 250円 5 いらない 番号を入力してください。: 2 デザートはいかがですか? 1 杏仁豆腐 500円 2 ゼリー 350円 3 アイスクリーム 200円 4 チョコレートパフェ 650円 5 あんみつ 400円 6 いらない 番号を入力してください。: 3 合計で 1120 円になります ◯確認 pan{c110197}% bc -l [~/Ruby] 800+120+200 1120 ●選んだものがお魚定食、飲み物はいらない、あんみつだった場合 pan{c110197}% ./def_twoparam.rb [~/Ruby] 御希望の食べ物は何ですか? 1 ラーメン 800円 2 塩ラーメン 850円 3 うどん 650円 4 カレーうどん 700円 5 炒飯 850円 6 ハンバーグ定食 1200円 7 お魚定食 1200円 8 いらない 番号を入力してください。: 7 飲み物はいかがですか? 1 オレンジジュース 100円 2 コーラ 120円 3 エスプレッソ 300円 4 ミルクティー 250円 5 いらない 番号を入力してください。: 5 デザートはいかがですか? 1 杏仁豆腐 500円 2 ゼリー 350円 3 アイスクリーム 200円 4 チョコレートパフェ 650円 5 あんみつ 400円 6 いらない 番号を入力してください。: 5 合計で 1600 円になります ◯確認 pan{c110197}% bc -l [~/Ruby] 1200+0+400 1600 quit ******************************** 考察 ******************************** 最初は、レジと同じ機能を作ろうと思いましたが、最終的には食券販売のプログ ラムを組みました。 理由は2つあります。 ◯理由1 レジプログラムだと、実行した人が数字を打たなければならない。 パソコンのキーボードはレジと違うのできっと打ち間違える人がいると思ったた め。 ◯理由2 数字を入力して計算するだけならbc -lの電卓機能とかわらないと思ったため。 実際に食堂で食券販売方式をつかうことを考えても、最初の固定費は多少掛かる でしょうが人件費を削減できるという面ではメリットだと考えられます。 また、オーダーを聞く仕事はアルバイトだと予想できます。アルバイトの人件費 は変動費ですので、その面でも不安定な変動費よりなら固定費、と考えたのも理 由の一つです。 具体的にはどうしたかと言うと、 定義付けにはif文を使って 「もし、x(defの外ではfood)のとき1と入力されたら、xは800(円)」 というようにひとつひとつdefから引っ張りだして値段計算に役立てています。 引数3つは x が 食べ物 (food) y が 飲み物 (drink) z が デザート (dessert) にして、選んでもらった番号をifで値段代入に変えて、それを引数に代入して計 算へとつなげています。 ********************************************************************** 作成したプログラム : B の def_oneparam_a.rb ****************************** 考えた設定 **************************** この食堂では、新商品で日変わりケーキセットを作った設定です。 お客様はすでに「日変わりケーキセット」のボタンを押しているので、あとは飲 み物を選んでもらうのみです。 プログラム的にはケーキの値段は固定、飲み物の値段はそれぞれで違うので合計 の値が変わるような設定にしました。 固定されているケーキの値段は300円です。 また、ケーキは日変わりなので種類は選択の必要はありません。 *************************** 作成したプログラム *********************** #!/usr/koeki/bin/ruby #goukeiメソッドで使う引数は(y)なので1つあることがわかる def goukei(y) #y=drink変数 #飲み物if #ユーザーが値段を打つ変わりにここで値段を代入している。 if y == 1 #オレンジジュース y = 100 elsif y == 2 #コーラ y = 120 elsif y == 3 #エスプレッソ y = 300 elsif y == 4 #ミルクティー y = 250 elsif y == 5 #いらない y = 0 end #飲み物if-end y + 300 #選ばれた商品の値段+ケーキ代の300円 #defは最後の行が返されるので、この計算の答えが一番下のprintfに返される。 end #def-end #\e[数字m で色付き文字開始 #\e[m で色付き文字終了 STDERR.print"\n\e[41;30m日変わりケーキセットのケーキは300円です\e[m\n" STDERR.print"\n ケーキセットのお飲み物を選んでいただくことができます。\n" STDERR.print" \e[35m飲み物は何になさいますか?\e[m \n" STDERR.print" 1 オレンジジュース 100円 2 コーラ 120円 3 エスプレッソ 300円 4 ミルクティー 250円 5 いらない\n" STDERR.print"\n番号を入力してください。: " drink = gets.to_i #drinkに選んでもらった商品番号が代入されている STDERR.printf("\e[41;30m合計で%d円になります。\e[m\n",goukei(drink)) #goukeiメソッドでdefを呼び出して計算している。 #このプログラムは値段ではなく商品番号がdrinkに代入されていて、値段はdef内のif中で求められるので関数はdrink変数をいれている。 ****************** 元にしたプログラムからの変更箇所 ***************** Aで作ったdef_twoparam.rbをもとにしています。 ケーキセットのプログラムになっているので、食べ物とデザートの項目は消して います。 defの仮引数設定も1つでいいので、x引数を消して(y)の1つに減らしています。 ******************************* 実行結果 ***************************** ●選んだものがオレンジジュース pan{c110197}% ./def_oneparam_a.rb [~/Ruby] 日変わりケーキセットのケーキは300円です ケーキセットのお飲み物を選んでいただくことができます。 飲み物は何になさいますか? 1 オレンジジュース 100円 2 コーラ 120円 3 エスプレッソ 300円 4 ミルクティー 250円 5 いらない 番号を入力してください。: 1 合計で400円になります。 ●確認 pan{c110197}% bc -l [~/Ruby] 300+100 400 quit ●選んだものがエスプレッソ pan{c110197}% ./def_oneparam_a.rb [~/Ruby] 日変わりケーキセットのケーキは300円です ケーキセットのお飲み物を選んでいただくことができます。 飲み物は何になさいますか? 1 オレンジジュース 100円 2 コーラ 120円 3 エスプレッソ 300円 4 ミルクティー 250円 5 いらない 番号を入力してください。: 3 合計で600円になります。 ●確認 pan{c110197}% bc -l [~/Ruby] 300+300 600 quit ******************************** 考察 ******************************** Aではdef内でprintfを作って最後の行をdef内で表示させました。ですがこのプ ログラムでは計算式の y + 300 を最後の行にして、defの外にあるprintfに値が帰ることを実践しています。 また、Aの参考にしたプログラムで def_test.rb のプログラムでわかった最後の 行が返されるということを実際に使ってみて、計算の結果がprintfの中に帰って 来るという仕組みを利用しました。 ********************************************************************** 作成したプログラム : C の def_oneparam_bar.rb ****************************** 考えた設定 **************************** Bのプログラムを応用して、ケーキセットではどの飲み物が人気か視覚的に把握 するために、項目の一日の売上金額を入力するとグラフが出力されるプログラム を作ることにしました。ですので、Bはお客様に聞くタイプの食券販売のプログ ラムでしたが、Cは売り手の売上業績を見るプログラムになっています。 金額を入力すると自動的にグラフと、売上個数も出力されるので一度で二度おい しいプログラムになっています。 実用的に使用することを想定して作ったので、 売上金額 = 各セット商品の単価(ケーキ+飲み物) × 売上個数 という計算式にあてはまります。 ですので各売上金額はそれぞれのセット商品の倍数になっていて当たり前なので すが、このプログラムを実行する人は売上金額を入力するとき適当に入力しない ように注意していただく必要があります。 *************************** 作成したプログラム *********************** #!/usr/koeki/bin/ruby #barplotメソッドで使う引数は(w,x,y,z)なので4つあることがわかる def barplot(w,x,y,z) #orange=w,cola=x,coffee=y,milk=z #割っている数は各セットの単価。売上/単価で売上個数を計算している。 ora = w / 400 printf("\nオレンジジュースとのセットは\e[35m %d \e[m個売れました\n",ora) col = x / 420 printf("コーラとのセットは\e[35m %d \e[m個売れました\n",col) cof = y / 600 printf("エスプレッソとのセットは\e[35m %d \e[m個売れました\n",cof) mil = z / 550 printf("ミルクティーとのセットは\e[35m %d \e[m個売れました\n",mil) deta = ora,col,cof,mil #それぞれの売上個数をdataに代入 print"\n売上個数対比グラフ\n" for a in deta #dataの中身をひとつづつaに代入しながらグラフを作りなさい printf("%d個\t|",a) print"*" * a #aの数だけ * を出力しなさい print"\n" end #for-end end #def-end #\e[数字m で色付き文字開始 #\e[m で色付き文字終了 STDERR.print"このプログラムを実行する人は \e[41;30m 売上金額=各セット商品の単価(ケーキ+飲み物) × 売上個数 \e[m であることに注意して売上金額を入力してください。\n\n" STDERR.print"本日のケーキセットの売上を飲み物別で入力してください。\n" STDERR.print"ケーキとオレンジジュースセットの売上はいくらですか?\n" STDERR.print"(※単価 = 400円)\n" orange = gets.to_i STDERR.print"ケーキとコーラセットの売上はいくらですか?\n" STDERR.print"(※単価 = 420円)\n" cola = gets.to_i STDERR.print"ケーキとエスプレッソセットの売上はいくらですか?\n" STDERR.print"(※単価 = 600円)\n" coffee = gets.to_i STDERR.print"ケーキとミルクティーセットの売上はいくらですか?\n" STDERR.print"(※単価 = 550円)\n" milk = gets.to_i #各売上をorange,cola,coffee,milkに代入している barplot(orange,cola,coffee,milk) #barplotメソッドを呼ぶ ***************** 元にしたプログラムからの変更箇所 ******************** もとにしたのはBのdef_oneparam_a.rbです。 Bではお客様向けのプログラムだったのに対し、Cは売り手の販売業績実態をみる プログラムになっているので、内容も売上金額を聞くものに変更になっています。 それぞれの売上金額をdef以下で聞き、変数に代入しています。 変数はbarplotメソッドではw,x,y,zの引数に変換しています。 Bのプログラムでは引数はひとつだけでよかったのに対しCでは4つに増えている ことがわかります。 また、def_funk.rbをfor部分の参考にしました。 変数指定とdetaを使った点、各グラフの行頭に売上個数を表示させたことが変更 点です。 ******************************* 実行結果 ***************************** ● オレンジジュースセットは3200円 コーラセットは3780円 エスプレッソセットは3600円 ミルクティーセットは2750円だった時 pan{c110197}% ./def_oneparam_bar.rb [~/Ruby] このプログラムを実行する人は 売上金額=各セット商品の単価(ケーキ+飲み物) × 売上個数 であることに注意して売上金額を入力してください。 本日のケーキセットの売上を飲み物別で入力してください。 ケーキとオレンジジュースセットの売上はいくらですか? (※単価 = 400円) 3200 ケーキとコーラセットの売上はいくらですか? (※単価 = 420円) 3780 ケーキとエスプレッソセットの売上はいくらですか? (※単価 = 600円) 3600 ケーキとミルクティーセットの売上はいくらですか? (※単価 = 550円) 2750 オレンジジュースとのセットは 8 個売れました コーラとのセットは 9 個売れました エスプレッソとのセットは 6 個売れました ミルクティーとのセットは 5 個売れました 売上個数対比グラフ 8個 |******** 9個 |********* 6個 |****** 5個 |***** ●販売個数確認 (公式は 販売個数 = 売上 / 単価 ) pan{YOGO Yuka}% bc -l [~/Ruby] 3200/400 8.00000000000000000000 3780/420 9.00000000000000000000 3600/600 6.00000000000000000000 2750/550 5.00000000000000000000 quit ● オレンジジュースセットは6800円 コーラセットは2520円 エスプレッソセットは17400円 ミルクティーセットは18150円だった時 pan{c110197}% ./def_oneparam_bar.rb [~/Ruby] このプログラムを実行する人は 売上金額=各セット商品の単価(ケーキ+飲み物) × 売上個数 であることに注意して売上金額を入力してください。 本日のケーキセットの売上を飲み物別で入力してください。 ケーキとオレンジジュースセットの売上はいくらですか? (※単価 = 400円) 6800 ケーキとコーラセットの売上はいくらですか? (※単価 = 420円) 2520 ケーキとエスプレッソセットの売上はいくらですか? (※単価 = 600円) 17400 ケーキとミルクティーセットの売上はいくらですか? (※単価 = 550円) 18150 オレンジジュースとのセットは 17 個売れました コーラとのセットは 6 個売れました エスプレッソとのセットは 29 個売れました ミルクティーとのセットは 33 個売れました 売上個数対比グラフ 17個 |***************** 6個 |****** 29個 |***************************** 33個 |********************************* ●販売個数確認 (公式は 販売個数 = 売上 / 単価 ) pan{c110197}% bc -l [~/Ruby] 6800/400 17.00000000000000000000 2520/420 6.00000000000000000000 17400/600 29.00000000000000000000 18150/550 33.00000000000000000000 quit ******************************** 考察 ******************************** 最初に売上金額を聞くのではなく販売個数を聞くプログラムにすれば、実行した 際の入力の手間が少し楽になりますし、プログラムを作る私も計算式を作らず引 数をそのまま使えて楽だったのですが、今回は「実際に企業で使うとしたら」を コンセプトにプログラムを作成したのでこのような形に完成しました。 defの外で取得した各売上金額をdef内ではw,x,y,zに置き換えて、更にそれぞれ を販売個数をだして新たな変数に代入しています。 それをまとめてdeta変数にいれることでfor繰り返しでグラフ出力をさせること ができています。 forでグラフを表示する際、「◯個」と表示するようにしたのですが、 たとえば オレンジジュースとのセットは 10 個 コーラとのセットは 9 個 エスプレッソとのセットは 8 個 ミルクティーとのセットは 3 個 の売上だったとき 10個|********** 9個|********* 8個|******** 3個|*** のように、オレンジジュースだけグラフがずれてしまったので\tで揃うようにし ました。 販売個数は1桁の場合も想定できるので割り算をしてグラフ出力ということはし ませんでした。 ---------------------------------------------------------------------- 3. 感想 ---------------------------------------------------------------------- 今回のプログラムでは、実際に企業で使うとしたら、ということをコンセプトに作 成してみました。 ですのでレジプログラムにするか食券プログラムにするかでだいぶ時間をかけて 悩みましたが、defの仕組みを def_test.rb で復習したのと、実際に値段を打つ と間違いやすいということに気付いたので食券のプログラムへ変えました。 def_test.rbで復習したことでだいぶ理解が深まったと思います。先生のページ をただながめるのではなく自分で試しにひとつひとつ実験していくように理解し ていくと、更に理解が深まりました。 defは、何度も出てくる計算式を一番最初でまとめて定義づけてしまえば後から 自分の労力がとても減りますし、とても便利な機能だと思います。 私が今回作った食券機能はもちろん、レジで自動的に消費税をかけるプログラム なども作れます。歌詞カードで同じフレーズを何度も書かなくてもdefで一度設 定すればいいというプログラムも作れます。 以上のように実際に使える場が日常の中でもたくさんあると思いました。 今回の内容は楽しんでプログラムを組むことができたので、自分の実になった手 ごたえを感じることができたのでよかったです。 ---------------------------------------------------------------------- 4.参考文献 ---------------------------------------------------------------------- 基礎プログラミング II 第 4 回 「繰り返しは引っ張りだそう」 西村まどか http://roy/~madoka/2011/r2/04/ 基礎プログラミングII 第6回 神田直弥 http://roy/~naoya/rubyII/6.html 基礎プログラミングI 第11回 神田直弥 http://roy/~naoya/ruby/11.html ---------------------------------------------------------------------- 5. 添付 ---------------------------------------------------------------------- 1つめ A の def_twoparam.rb 2つめ B の def_oneparam_a.rb 3つめ C の def_oneparam_bar.rb 4つめ 復習用に作成した def_test.rb