第6回 目的に応じて使ってみよう レポート課題 氏名 : 余語結佳 学籍番号 : c1101974 語学クラス : 英語2 コース : 地域共創コース ---------------------------------------------------------------------- 1. 筆記問題 ---------------------------------------------------------------------- 配列は1から数えるのではなく0から数えるので以下のようになる。 a = 0 b = 1 c = 2 d = 3 e = 4 f = 5 g = 6 h = 7 i = 8 j = 9 k = 10 l = 11 m = 12 n = 13 o = 14 p = 15 q = 16 r = 17 s = 18 t = 19 u = 20 v = 21 w = 22 z = 23 y = 24 z = 25 上の考え方で問題を考える。 ●alphabet = [18] 最初から数えていくとsになる。 r でないのは、配列の数えかたは0、1、2、3…と、0から数えるからである。 ●alphabet = [40] アルファベットは全部で26個で、配列的に数えても一番上の数の Z は25である。 よって26以上のアルファベットは存在しない。 ちなみにこの問題は筆記問題だが、これをプログラムにすると以下のようになる。 alphabet.rb ●プログラム #!/usr/koeki/bin/ruby alphabet = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"] # アルファベットは文字列なので""を忘れないよう注意 print"◯番目のアルファベットを出力します。\n" print"◯ = " number = gets.to_i # 入力してもらった値をnumberに代入 printf("%d番目のアルファベットは%sです\n",number,alphabet[number]) # alphabet[number]で、alphabet配列の中に入っているnumber番目のアルファベットを出力する ●実行結果 pan{YOGO Yuka}% ./alphabet.rb [~/Ruby] ◯番目のアルファベットを出力します。 ◯ = 18 18番目のアルファベットはsです pan{c110197}% ./alphabet.rb [~/Ruby] ◯番目のアルファベットを出力します。 ◯ = 40 40番目のアルファベットはです ---------------------------------------------------------------------- 2.プログラム問題 ---------------------------------------------------------------------- ********************************************************************** 作成したプログラム : A のdef_statistic.rb ****************************** 考えた設定 **************************** 「公益ドリンク」の売れている状況を調べるプログラムです。 ただ流れに沿って平均や分散を出力するのでは面白みに欠けるため、売り上げ一 覧を入力してもらったあと何をしたいかを問いそれにしたがってそれぞれの計算 をしてその結果を返すプログラムという設定にしました。 また、これは点数を求めるプログラムではないので、計算結果が小数になっても 切り捨てにして結果を出力しています。 *************************** 作成したプログラム *********************** #!/usr/koeki/bin/ruby def average(kosuu) # kosuu = uriagekosuu(各日付の売り上げ個数) sum = 0 # 平均の値を足して行く為の変数。 for kazu in kosuu # 配列の要素が代入されているkosuuの要素をkazuに代入 sum += kazu # 平均を求めるために配列の要素全てを合計している end # for-end sum / kosuu.length # 平均 = 合計/個数 kazu.lengthで要素の数を数えている end # def average-end def bunsan(kosuu) # kosuu = uriagekosuu(各日付の売り上げ個数) goukei = 0 # 繰り返しの度0になっては合計にならないのでここで設定 for kosu in kosuu # 繰り返しをすることで1日づつの計算ができる sum = 0 # forの中にないと繰り返しの度初期値が0でなくなってしまう sum += kosu # kosuに代入されていた売り上げ個数をsumに加算代入 sum -= average(kosuu) # 売り上げ個数 - 平均個数 sum **= 2 # 差を2乗 goukei += sum # 繰り返しの度2乗した値をひとつづつ足していく end # for-end goukei / kosuu.length # 各日の計算合計 / 要素の数(つまり日数) end # def bunsan-end print"今週の当店の商品「公益ドリンク」の売れている状況をみます。\n" print"(入力してもらった回数 = ◯日間という表記になります。)\n" uriagekosuu = Array.new # uriagekosuu を配列としてあつかいます print"まず、売り上げ個数を入力して下さい。\n" print"入力終了は ctrl-d です。\n" day = 1 # 日数を数えるための初期値 while true STDERR.printf("%d日目の売り上げ個数を入力して下さい :",day) number = gets # ctrl-Dが整数変換されないようここではto_iはしない if number == nil # nil = ctrl-d break # breakしてwhileを抜ける end # if-end uriagekosuu << number.to_i # << は「配列の最後にnumber要素を追加」という意味。 # 配列につけ足す段階で整数変換 day += 1 # 日にちを数える end # while-end day -= 1 #dayから1引いてるのは、ctrl-dの一日分 #------------------------------------------------------- while true # 何をするか繰り返し選んでもらうためwhlie print"\n\n何を調べますか?\n" print"1 平均\n" print"2 分散\n" print"3 終わる \n" print"値を入力してください : " sentaku = gets.to_i # 選択してもらったものをsentakuに代入 if sentaku == 1 # もし1(平均なら) printf("\n\n %d日間の売り上げ個数平均は%d個\n",day,average(uriagekosuu)) #average(uriagekosuu)…averageメソッドに売り上げ個数配列の要素を代入 end #if-end if sentaku == 2 # もし2なら(分散) printf("\n\n分散は%dです\n",bunsan(uriagekosuu)) #bunsan(uriagekosuu)…bunsanメソッドに売り上げ個数配列の要素を代入 end # if-end if sentaku == 3 # もし3なら(終わり) print"終了します。\n" exit # 強制終了 end # if-end end # whlie-end *********************** 元にしたプログラム ************************* 元にしたのは授業で使用した def_ary_movie.rb です。 平均を求める箇所ではとても参考になりました。 ですがただ参考にするだけでなく変数をひとつひとつ今回のプログラムに合うよ うに変更したことと、変更しながらどのような動きをしているかをその都度確認 しました。 また、平均に加え分散の文章やif文などを付け加えました。 元のプログラムではsumの段階で小数点に対応できるようにしていましたが、私 のプログラムは小数点以下は切り捨てなのでsum=0に変更しています。 ******************************* 実行結果 ***************************** pan{c110197}% ./def_statistic.rb 今週の当店の商品「公益ドリンク」の売れている状況をみます。 (入力してもらった回数 = ◯日間という表記になります。) まず、売り上げ個数を入力して下さい。 入力終了は ctrl-d です。 1日目の売り上げ個数を入力して下さい :40 2日目の売り上げ個数を入力して下さい :70 3日目の売り上げ個数を入力して下さい :110 4日目の売り上げ個数を入力して下さい :30 5日目の売り上げ個数を入力して下さい :^D 何を調べますか? 1 平均 2 分散 3 終わる 値を入力してください : 1 4日間の売り上げ個数平均は62個 何を調べますか? 1 平均 2 分散 3 終わる 値を入力してください : 2 分散は969です 何を調べますか? 1 平均 2 分散 3 終わる 値を入力してください : 3 終了します。 ******************************** 考察 ******************************** def average と def bunsan の仮引数が kosuu とおなじになっていて一見「分 かりにくい」と思われるかもしれません。 ですがこれは、どちらも配列の uriagekosuu を代入しているものなのであえて おなじ仮引数を設定しました。 分散とは何かがわからなかったので分散の公式を調べることから始めました。 ●分散とは 参考文献にもあるように、分散とはそれぞれのデータが平均からそれぞれどれく らいはなれているか、その距離の2乗した値というものです。 ●公式 たとえば入力回数が4日分あったと考えると 各日付の売り上げ個数から平均個数を引く その差をそれぞれ2乗する 2乗した値を4日分合計する 合計を4日で割る これにあてはめて分散のプログラムを組んだ。 実行結果のデータで分散の繰り返しの計算内容をp文で 1 sum = 0 2 sum += kosu 3 sum -= average(kosuu) 4 sum **= 2 5 goukei += sum のようにすると以下のように出力される。 0 40 -22 484 484 0 70 8 64 548 0 110 48 2304 2852 0 30 -32 1024 3876 実行した時にデータは40、70、110、30の4つ入力されているのだから上の実行結 果は4つ分の繰り返しがなされている。 要素ごとにくぎると、p文で出力されている計算は毎回sumを0に設定し直してい るので、上の数字の羅列は0から次の0のひとつ上までが入力されたデータの一つ 分ということがわかる。 以上のことをふまえて、上の1から5に当てはめて一つ一つ bc -l で確かめ算を していくと pan{c110197}% bc -l [~/Ruby] 40-62 …個数 - 平均 -22 -22^2 …差の2乗 484 … ★ 70-62 …個数 - 平均 8 8^2 …差の2乗 64 … ★ 110-62 …個数 - 平均 48 48^2 …差の2乗 2304 … ★ 30-62 …個数 - 平均 -32 -32^2 …差の2乗 1024 … ★ 484+64+2304+1024 …★の総和 3876 …合計 繰り返し部分の確かめ算は以上。 pan{c110197}% bc -l [~/Ruby] 3876/4 969.00000000000000000000 …合計 / 日数。 969で、プログラムの結果と合致しているので正しく動いている。 ●平均 順番は前後してしまったが平均も考察してみる。 実行結果は 4日間の売り上げ個数平均は62個 で、構文は sum / kosuu.lengthなので、 売り上げ総個数 /日数ということ。 これにあてはめると pan{c110197}% bc -l [~/Ruby] 40+70+110+30 250 250/4 62.50000000000000000000 、62.5という計算結果で一致してないように見えますがこのプログラムは「個数」 を調べるものなので小数点以下は切り捨てで計算しているので正しいと言えます。 参考文献 平均と分散(1) http://www.kwansei.ac.jp/hs/z90010/sugakuc/toukei/avgvar0/avgvar0.htm 偏差値と標準偏差の公式をそれぞれ教えて下さい。 - 数学 - 教えて!goo http://oshiete.goo.ne.jp/qa/6140035.html ********************************************************************** 作成したプログラム : B def_rollplaying_a.rb ****************************** 考えた設定 **************************** 花を育てるプログラムを作成しました。 花はしゃべることができる魔法の花なので、意思疏通をしながら育てて行くこと ができます。 *************************** 作成したプログラム *********************** #!/usr/koeki/bin/ruby def care print"\e[32m\n今日は何をする?\n" print"1 水をあげる \n" print"2 褒めてあげる \n" print"3 歌を歌ってあげる \n" print"番号を選択してください。: \e[m" end #水を与える場合 def water(na) # na=name srand #乱数の種 mizu = rand(2) #2つのmizuからランダムなものを返す if mizu == 0 #もし乱数で0だったら(乱数は配列と同じで0から数える) print"\n「たくさん水のんで大きくなるんだよー」\n" printf("%sは生き生きしています!!\n",na) printf("%s「おみずおいしい!!」\n",na) else #それ以外(乱数で1だったら) print"\n「おみずだよー!」\n" printf("%s「おみずいっぱい飲んだ!!褒めて褒めて!」\n",na) end #if-end end #def water-end #褒める場合 def home(na) #na=name srand #乱数の種 praise = rand(2) #2つのpraiseからランダムなものを返す if praise == 0 #もし乱数で0だったら(乱数は配列と同じで0から数える) printf("\n「%sはかわいいねぇ」\n",na) printf("%s「えへへ!そうかな!!」\n",na) printf("%sはとっても嬉しそうです\n",na) else #それ以外(乱数で1だったら) printf("\n「%sにはいつも元気をもらうよ」\n",na) printf("%s「ほんと?%s嬉しい!」\n",na,na) printf("%sとの絆があがったような気がします。\n",na) end #if-end end #def home-end #歌ってあげる場合 def sing(na) # na=name srand #乱数の種 utau = rand(2) #2つのutauからランダムなものを返す if utau == 0 #もし乱数で0だったら(乱数は配列と同じで0から数える) printf("\n「〜〜♪」\n",na) printf("%s「その歌すごく好き!」\n",na) printf("%sは聞き惚れています!\n",na) else #それ以外(乱数で1だったら) printf("\n「〜〜♪」\n",na) printf("%s「こんなにすばらしい歌を聞いたのは始めてだ!」\n",na) printf("%sは感動で涙を流しています!\n",na) end #if-end end #def home-end print"しゃべる花を育てることにしました。\n" print"名前をつけてあげましょう" name = gets.chomp #名前をnameに代入 if name == "" #もしnameが空欄なら name = "ルビ子" #ルビ子と名付ける end #if-end printf("名前は%sとしよう!\n",name) body = 0 #水をあげるとkaradaにプラス gentle = 0 #褒めるとgentleにプラス song = 0 #歌ってあげるとsongにプラス while true care #選択肢のdefを呼ぶ sentaku = gets.to_i #defで選んでもらったものを代入 if sentaku == 1 #もし1(水をあげる)なら water(name) #waterメソッドへ body +=2 #bodyに2点加算代入 end #if-end if sentaku == 2 #もし2(褒めてあげる)なら home(name) #homeメソッドへ gentle += 2 #gentleに2点加算代入 end #if-end if sentaku == 3 #もし3(歌ってあげる)なら sing(name) #singメソッドへ song += 2 #songに2点加算代入 end #if-end if body >= 6 #もしbodyが6点以上になったら break #breakしてwhileを抜ける end #if-end if gentle >= 6 #もしgentleが6点以上になったら break #breakしてwhileを抜ける end #if-end if song >= 6 #もしsongが6点以上になったら break #breakしてwhileを抜ける end #if-end end #while-end printf("%sは\n",name) if body >= 6 print"ちょっとふくよかに\n" end if gentle >= 6 print"優しく\n" end if song >= 6 print"歌がとても上手に\n" end print"育ちましたね!\n" *********************** 元にしたプログラム ************************* 「るびおっち」 def_rubiocci.rbを元にしました。 変数などはこのプログラムに合うように変更しています。 また、defの中で乱数をつかい、同じ世話をしてもいろんなパターンの反応がか えって来るように変更しています。 名前決定の際にリターンキーを押されてしまった場合は、今まではwhileをして 再入力を求めると言う5、6行ほどかかるプログラムをしようしていたのですが、 def_rubiocci.rbを見るとたった3行で終わっているのに感動したので、私のプロ グラムでも使ってみました。 ******************************* 実行結果 ***************************** pan{c110197}% ./def_rollplaying_a.rb [~/Ruby] ちょっと不思議な、しゃべる魔法の花を育てることになりました。 名前をつけてあげましょう : はなこ 名前ははなことしよう! 今日は何をする? 1 水をあげる 2 褒めてあげる 3 歌を歌ってあげる 番号を選択してください。: 1 「たくさん水のんで大きくなるんだよー」 はなこは生き生きしています!! はなこ「おみずおいしい!!」 今日は何をする? 1 水をあげる 2 褒めてあげる 3 歌を歌ってあげる 番号を選択してください。: 2 「はなこにはいつも元気をもらうよ」 はなこ「ほんと?はなこ嬉しい!」 はなことの絆があがったような気がします。 今日は何をする? 1 水をあげる 2 褒めてあげる 3 歌を歌ってあげる 番号を選択してください。: 3 「〜〜♪」 はなこ「その歌すごく好き!」 はなこは聞き惚れています! 今日は何をする? 1 水をあげる 2 褒めてあげる 3 歌を歌ってあげる 番号を選択してください。: 1 「たくさん水のんで大きくなるんだよー」 はなこは生き生きしています!! はなこ「おみずおいしい!!」 今日は何をする? 1 水をあげる 2 褒めてあげる 3 歌を歌ってあげる 番号を選択してください。: 1 「たくさん水のんで大きくなるんだよー」 はなこは生き生きしています!! はなこ「おみずおいしい!!」 はなこは ちょっとふくよかに 育ちましたね! ******************************** 考察 ******************************** このプログラムは各選択肢が2点配点で、どれかの項目で6点以上を取ると繰り返 しが終了し答えが変わって来ます。 結論から言えば、1の水をあげるで6点以上獲得すると花はふくよかに育ち 2の褒めてあげるを6点以上獲得すると花は優しい性格になります。 3の歌を歌ってあげるを6点以上獲得すると花は歌の上手な花になります。 今回の実行結果では1の水をあげるを3回×2点=6点獲得したので、最終的には少 しふくよかな花へと成長しています。 点数配分をする際に、最所はdefの中で点数を配分していました。ですがそうす るといつまでもdefの外の配列に点数が加算されなく、なぜだろうと考察した結 果、defは最後の値を返すがprintをしようした際はそれは無効だということを思 い出しました。 だからdefの外の変数に点数がかえって行かなかったということを思い出しまし た。前にこれは学習していたのですが忘れてしまっていたので、今回のこのミス で思い出すことができました。 また、defの中で一回ずつ点数を加算していてはプログラムがむだに長くなって しまうということも考え、defで加算するということはやめてdefの外(defを呼ん だ後)に点数を加算する型式にしました。 今のようなうっかりしたミスはもう一つしていて、名前変数をdefの際にそのま まnameで代入していました。 そこでnameだったものを仮因数ではnaにするとしっかりと名前の代入が行われた のでdefの仮因数の指定の大切さを再度確認することができました。 このようなうっかりとしたミスは時間のロスにも繋がるので以後気を付けたいと 思います。 実行結果を見てもわかりますが、同じ選択肢を選んでも 今日は何をする? 1 水をあげる 2 褒めてあげる 3 歌を歌ってあげる 番号を選択してください。: 1 「おみずだよー!」 1「おみずいっぱい飲んだ!!褒めて褒めて!」 今日は何をする? 1 水をあげる 2 褒めてあげる 3 歌を歌ってあげる 番号を選択してください。: 1 「たくさん水のんで大きくなるんだよー」 1は生き生きしています!! 1「おみずおいしい!!」 のように違う結果が帰って来ていることから乱数は成功していると言えます。 (※ランダムなので同じ結果がえってくることもありますが、何度かすると違う 答えが帰って来るのでちゃんと動作がとれていると言えます) ---------------------------------------------------------------------- 3. 感想 ---------------------------------------------------------------------- 毎日繰り返しする車の運転であれば、ドアをあける、カギを差しこみエンジンを かける、サイドブレーキをはずす、ギアをかえる、という一連の動作をメソッ ドにすることができると思います。 運転だけでなく、洗顔やお風呂にはいる動作などにも言えると思います。 今回はうっかりしたミスを連発してしまいましたが、おかげでしっかりとこれは だめで、あれはだいじょうぶというのを再確認して覚えることができたのでよかっ たと思います。Bの課題は前期に作成した育成プログラムに似ていたので楽しん で作成することができました。Aは分散の公式がわからなくて調べたことでだい ぶ時間のロスにはなってしまいましたが今回の学習で分散とは何か知ることがで きたので勉強になりました。 --------------------------------------------------------------------- 4.参考文献 ---------------------------------------------------------------------- 基礎プログラミング II 第 6 回 「目的に応じて使ってみよう」 西村まどか http://roy/~madoka/2011/r2/06/ 基礎プログラミング I 第6回 神田直弥 http://roy/~naoya/ruby/6.html 基礎プログラミング I 第11回 神田直弥 http://roy/~naoya/ruby/11.html 逆引きRuby 配列 たけうちひとし http://www.namaraii.com/rubytips/?%C7%DB%CE%F3 他はその項目ごとに参考文献を書いているので、その欄を参照してください。 ---------------------------------------------------------------------- 5. 添付 ---------------------------------------------------------------------- 1つめ 筆記問題でためしにつくってみた入力された番号に一致するalphabetを 出力するプログラム alphabet.rb 2つめ プログラム問題のA def_statistic.rb 3つめ プログラム問題のB def_rollplaying_a.rb ======================== 余語結佳 Yogo Yuka 東北公益文科大学 2年 c110197@f.koeki-u.ac.jp ========================