- 投稿日:2020-08-17T23:49:07+09:00
【初心者向け】「return」がイマイチ分からない2年前の自分に向けての記事(if-elseの話も少し)
この記事を読んで習得できること
・プログラミングを初めてまだ「return」の使い方が分からない方々
・3年前の私経緯
大学院でプログラムを書いていた3年前のボク。
大学の研究で実験の解析で必要だったため、必死で書いていたのをなんとなく覚えている。ひとまず、自分の行いたい解析プログラムは動くようになり、
喜びながらそのプログラムを使って解析を行っていた。ひと段落してから、プログラムを見てみると、
「結構ソース汚いな…」と思い、修正しようと試みた。しかし、ソースのスパゲッティ感*が半端なく、
なかなか修正が出来ずに、前回と同じようなソースなのに、
一から書き直したのを覚えている。3年前のソースで何が起こっていたのか
おおよそのイメージだが、こんな感じ。
sample.swiftfunc yabaiCode() { if 条件1 { 処理1(15行以上) 処理A(10行以上) 処理4(10行以上) } else if 条件2 { 処理2(15行以上) 処理A`(10行以上) 処理5(10行以上) } if 条件3 { 処理3(15行以上) 処理A``(10行以上) 処理6(10行以上) } else { 処理7(20行以上) } }何が言いたいかって、条件分岐の中の処理がとんでもなく長いのだ。
しかし、処理を分けたいのだが、分け方がイマイチ分からない。
どうやら、メソッドで分割していけば、もっと簡単に処理ができるとのことだ。でも、メソッドで分けることが出来なかった。
メソッド間での、値の受け渡しが分からなかったのだ…んで、結局分からないまま、このままのコードを残して卒業してしまったわけだが(後輩ちゃんごめん)、
今になって(流石に)return文がある程度分かった自分が、過去の自分にreturnを教えるために、この記事を書いたってわけです。returnの主な使い方は2つ
1.メソッドを終了させる
sample.swiftfunc return1() { num = 5 // 好きな数値を入れる if num == 4 { print("4です") return } else if num == 5 { print("5です") return // このメソッドはここで終了するはず // これ以降は処理されない } if num == 6 { print("6です") return } else { print("分からない") return } }このreturnは、無駄な処理を省くことができる。
途中で答えが出たら、その時点で処理を終了させればいいし、
また、returnがあるおかげで、if-else
を使わなくてよくなる。if-elseは、処理が多くなる上に、ifとelseが同時でいることが前提になるため、
1メソッドあたりの処理が多くなることがある。
読みにくくなったりもする。
職場によっては、「if-else
禁止!」なんてところもあるだろう。
(自分の部署はそうでした)どんだけif-elseがないとコードが読みやすくなるか。
FizzBuzz文を参考にしてみたいと思う。まずは、if-else文を使用したもの。
FizzBuzz.swiftfunc fizzBuzz() { for i in 1...30 { judgeFizzBuzz(num: i) } } func judgeFizzBuzz(num : Int) { if num % 15 == 0 { print("FizzBuzz") } else if num % 3 == 0 { print("Fizz") } else if num % 5 == 0 { print("Buzz") } else { print(num) } }めっちゃ悪いわけではないが、もし仮に、7の倍数の時の処理を入れるなんて時は、
気をつけないと、全ての処理がぶっ壊れてしまう。
(return使うときももちろん気をつける必要があるが)では、return文を使ってみる。
FizzBuzz.swiftfunc fizzBuzz() { for i in 1...30 { judgeFizzBuzz(num: i) } } func judgeFizzBuzz(num : Int) { if num % 15 == 0 { print("FizzBuzz") return } if num % 3 == 0 { print("Fizz") return } if num % 5 == 0 { print("Buzz") return } print(num) }if文がパーツ化されるので、実に見やすい。本当に素晴らしい。
何もなければnumがprintされるってことも一目瞭然だ。2.値を返してくれる
ここでは、数値を返してくれるメソッドを使用する
sample.swiftfunc say() { num = 5 doubleNum = doubleNum(num) // 10が返ってくる } // 2倍した数値を返してくれる関数 func doubleNum(num :Int) -> Int { return num * 2 //数値を返す }別のメソッドで計算して、処理結果を返してもらうってことも容易になる。
FizzBuzz使うとさらにお分りいただけるかもしれない。
FizzBuzz.swiftfunc fizzBuzz() { for i in 1...30 { print(judgeFizzBuzz(num: i)) } } func judgeFizzBuzz(num : Int) -> String { if num % 15 == 0 { return "FizzBuzz" } if num % 3 == 0 { return "Fizz" } if num % 5 == 0 { return "Buzz" } return String(num) }1で書いたものよりも、さらに見やすくなったと思う。
judgeFizzBuzz
がStringを返すようになったということで、全体としてのコード量も減った(print)まとめ
returnをうまく使わないとメソッドが盛り盛りになってしまうので、もし使っていない方がいたら是非使って欲しい。
これを知らないで、よく大学卒業できたな、俺…
- 投稿日:2020-08-17T22:37:24+09:00
コラッツ数、フィボナッチ数、三角数 色んな数列のプログラム作ってみた
何かQiitaに投稿できそうなネタは無いかなーーとフォルダを漁っていると、
6年以上前にProjectEulerちょっとやってみてた時のスクリプトを掘り起こしたので、
それを書きます(第2段)実行環境は下記になります。
ruby 2.6.3p62
macOS Catalina 10.15.6
zshコラッツ数を生成する
・偶数の場合、2で割る。
・奇数の場合、3を掛け1を足す。
のようにして進む数列。
数が大きいからと言って数列が長くなるとも限らず、なんとも不思議。
詳細で正確な解説は下記参照。
https://ja.wikipedia.org/wiki/コラッツの問題collatz_number.rbdef get_collatz_next_number(num) if num.even? then return num / 2 elsif num == 1 then return nil else return (num * 3) + 1 end end def create_collatz_sequence(num) cltz_ary = Array.new new_num = num cltz_ary.push new_num new_num = get_collatz_next_number(new_num) while !(new_num.nil?) do cltz_ary.push new_num new_num = get_collatz_next_number(new_num) end return cltz_ary end p create_collatz_sequence (26) p "====" p create_collatz_sequence (27) p "====" p create_collatz_sequence (28) p "====" p create_collatz_sequence (1652)下記実行結果になります。
% ruby collatz_number.rb [26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1] "====" [27, 82, 41, 124, 62, 31, 94, 47, 142, 71, 214, 107, 322, 161, 484, 242, 121, 364, 182, 91, 274, 137, 412, 206, 103, 310, 155, 466, 233, 700, 350, 175, 526, 263, 790, 395, 1186, 593, 1780, 890, 445, 1336, 668, 334, 167, 502, 251, 754, 377, 1132, 566, 283, 850, 425, 1276, 638, 319, 958, 479, 1438, 719, 2158, 1079, 3238, 1619, 4858, 2429, 7288, 3644, 1822, 911, 2734, 1367, 4102, 2051, 6154, 3077, 9232, 4616, 2308, 1154, 577, 1732, 866, 433, 1300, 650, 325, 976, 488, 244, 122, 61, 184, 92, 46, 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1] "====" [28, 14, 7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1] "====" [1652, 826, 413, 1240, 620, 310, 155, 466, 233, 700, 350, 175, 526, 263, 790, 395, 1186, 593, 1780, 890, 445, 1336, 668, 334, 167, 502, 251, 754, 377, 1132, 566, 283, 850, 425, 1276, 638, 319, 958, 479, 1438, 719, 2158, 1079, 3238, 1619, 4858, 2429, 7288, 3644, 1822, 911, 2734, 1367, 4102, 2051, 6154, 3077, 9232, 4616, 2308, 1154, 577, 1732, 866, 433, 1300, 650, 325, 976, 488, 244, 122, 61, 184, 92, 46, 23, 70, 35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1]フィボナッチ数列を生成する
任意の数がその前の数と前の前の数の和になっている数列のこと。
fizz,buzzの次くらいにプログラムの問題として良く出てくる印象。
詳細で正確な解説は下記参照。
https://ja.wikipedia.org/wiki/フィボナッチ数fibonacci_sequence.rbdef create_fibonacci_sequence( term1, term2, max_term) fibo_ary = Array.new fibo_ary.push term1 fibo_ary.push term2 new_num = 0 i = 2 new_num = fibo_ary[i-1] + fibo_ary[i-2] while new_num <= max_term do fibo_ary.push new_num i += 1 new_num = fibo_ary[i-1] + fibo_ary[i-2] end return fibo_ary end p create_fibonacci_sequence(0,1,10946)実行結果は下記になります。
% ruby fibonacci_sequence.rb [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946]三角数を生成する
+2,+3,+4,+5,...と増加していく数列のことです。
点の数とすると正三角形に並べられるから三角数と呼ぶみたいです。洒落てますね。
詳細で正確な解説は下記参照。
https://ja.wikipedia.org/wiki/三角数triangle_number.rbdef create_triangle_number (max_number) terms = Array.new i = 0 current_number = 1 while current_number <= max_number do terms.push current_number i += 1 current_number = terms[i - 1] + i + 1 end return terms end p create_triangle_number (1000)実行結果は下記になります。
ruby triangle_number.rb [1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120, 136, 153, 171, 190, 210, 231, 253, 276, 300, 325, 351, 378, 406, 435, 465, 496, 528, 561, 595, 630, 666, 703, 741, 780, 820, 861, 903, 946, 990]以上です。
- 投稿日:2020-08-17T21:45:22+09:00
[Ruby]2重ハッシュの中身の取り出し方
概要
2重ハッシュの取り出し方について、備忘録としてまとめます。
環境
Ruby 2.6.5
内容
例えば、配列の内部に複数のハッシュをもつ変数user_dateがあるとします。
user_data = [ { user: { profile: { name: 'Taro' } } }, { user: { profile: { name: 'Jiro' } } }, { user: { profile: { name: 'Saburo' } } } ]ハッシュの持っている値の取得には、その値に対応するキーを指定します。
ハッシュ[取得する値のキー]また、二重ハッシュから特定のデータを取得する場合は、[取得する値のキー]を取得するデータまで連続して指定します。
したがって。全てのユーザーの名前だけを出力しようとすると以下の記述になります。user_data.each do |user| puts user[:user][:profile][:name] end以上
- 投稿日:2020-08-17T21:44:04+09:00
【パス指定】ネストしたリソースのパス指定
概要
ネストしたリソースのパス指定方法について、一瞬戸惑ってしまったので備忘録として記録します。
環境
・ruby '2.5.7'
・rails '5.2.3'
・rspec-rails '4.0.0.beta2'指定方法
結論:
rails routes
してルーティングを一覧表示して確認する!(例) Rspecのリクエストテストでパス指定をする
次のような、ルーティングを宣言していたとします。
routes.rbresources :datespots do resources :comments, only: [:create, :destroy] endターミナルで
rails routes
すると、ルーティングが一覧表示される。Prefix Verb URI Pattern Controller#Action (省略) datespot_comments POST /datespots/:datespot_id/comments(.:format) comments#create datespot_comment DELETE /datespots/:datespot_id/comments/:id(.:format) comments#destroy (省略)これを元に、パス指定すればOK!
comments_spec.rb(省略) it "有効な内容のコメントが登録できること" do expect { post "/datespots/#{datespot.id}/comments", params: { datespot_id: datespot.id, comment: { content: "オシャレですね!" } } }.to change(datespot.comments, :count).by(1) end (省略)参考
- 投稿日:2020-08-17T20:53:30+09:00
数字版のinclude? はないのか?
メモがてらのアウトプットです。
今回想定したのはよくあるお買い物ポイントを計算するプログラムを組みました。
下記コードqiita.rbn = gets.to_i d_1,p_1 = Array.new(n){gets.chomp.split(' ').map{|i| i.to_i}}.transpose p = 0 c = 0 while n > 0 do if d_1[c].to_s.include?("3") p += (p_1[c] * 0.03).floor elsif d_1[c].to_s.include?("5") p += (p_1[c] * 0.05).floor else p += (p_1[c] * 0.01).floor end c = c + 1 n = n - 1 end puts p困ったのは1点 include?の使い方です。
結果的にto_sで文字列に返して参照しましたが
数字を直接参照するメソッドはないのかな?と
思いました。探した限り見つからなかったのですが何かあるんですかね。。。
- 投稿日:2020-08-17T19:20:21+09:00
[初心者]Vagrantで構築した仮想環境にログインする手順
1、ターミナルを起動
まずは下記のように出てくる
ユーザー名$
2、現在のディレクトリから移動する
今回はhome/MyVagrant/MyCentOS 内に"Vagrantfile"があるのでそこまで移動する。~$ cd //ホームディレクトリに戻る(場所の確認) ~$ cd MyVagrant ~$ cd MyCentOS //MyCentOSまで移動 pc名:MyCentOS ユーザー名$ //←と出てくればOK
3、仮想環境を起動、ログインする~$ vagrant up ~$ vagrant sshこの2つを実行後下記のように表示されていればログイン完了!
[vagrant@localhost ~]$
- 投稿日:2020-08-17T19:17:02+09:00
Rails enum 都道府県をプルダウン方式で選択
はじめに
個人開発アプリでGoogle APIと連携して地図情報を取得できる様にしたのですが、
住所を全て手入力するのは面倒なので都道府県をプルダウン方式で選択できるようにしようと思います。
new.html.erb<%= form_for @ride, method: :post do |f| %> <%= f.select :prefecture, ['北海道', '青森県', '秋田県', '岩手県' 以下略], { include_blank: '選択してください' } %> <% end %>コードの可読性を無視して実装するならこんな感じで入力していくだけなのですが、
このようにview側に47都道府県全てを入力すると非常に見苦しいと思ったのでスマートにできる方法を探してみました。
enum
enumというものがあるようでこれによってviewではなくmodelに記述することができ、
view側のコードをかなりスッキリさせることができます!
class CreateRides < ActiveRecord::Migration[5.2] def change create_table :Rides do |t| t.integer :ride_area, null: false, default: 0 end endまずはintegerでカラムを作成します。
ride.rbclass Ride < ApplicationRecord enum ride_area:{ "---":0, 北海道:1,青森県:2,岩手県:3,宮城県:4,秋田県:5,山形県:6,福島県:7, 茨城県:8,栃木県:9,群馬県:10,埼玉県:11,千葉県:12,東京都:13,神奈川県:14, 新潟県:15,富山県:16,石川県:17,福井県:18,山梨県:19,長野県:20, 岐阜県:21,静岡県:22,愛知県:23,三重県:24, 滋賀県:25,京都府:26,大阪府:27,兵庫県:28,奈良県:29,和歌山県:30, 鳥取県:31,島根県:32,岡山県:33,広島県:34,山口県:35, 徳島県:36,香川県:37,愛媛県:38,高知県:39, 福岡県:40,佐賀県:41,長崎県:42,熊本県:43,大分県:44,宮崎県:45,鹿児島県:46, 沖縄県:47 } endモデル側にはこんな感じで都道府県を書いておきます。
ハッシュのキーがセレクトボックスに表示されます。
new.html.erb<%= form_for @ride, method: :post do |f| %> <%= f.select :prefecture, Ride.ride_areas.keys, {} %> <% end %>冒頭で書いたコードをこのように書き換えてあげましょう。
Ride.ride_areas.keys, {}
と書く事でモデルに書いている都道府県全てを順番に処理してくれるのでブラウザ上ではプルダウン方式で都道府県が選択できるようになっています!以上です。
- 投稿日:2020-08-17T18:02:53+09:00
配列のパターン計算、摘出のプログラム
練習でプログラムしてたのでアウトプットです。
今回は個人的にスッキリしたコードになりました。qiita.rbnumber = gets.chomp.split(' ').map{|i| i .to_i} total = [] number.permutation(4) do |n| total.push((n[0]*10+n[1]) + (n[2]*10 + n[3])) end puts total.max・入力した4つの数字を2つに切り分けて、それぞれに10の位、1の位を与える。
・できた2けたの数字を加算する。
・それを予め入力した4つの数字のならび全てに適用する
・その合計値が一番大きいものを出力しました。わかりにいくいと思うので下記処理内容です。
qiita.rb#入力した値 1 2 3 4 #パターン出力 46 ←12+ 34 55 ←34+ 21 37 以下全パターン 55 37 46 55 64 37 64 37 55 55 73 46 73 46 55 64 73 55 73 55 64 #最大値 73※実際はパターン出力も省略してます。
これをやるにあたり、何となく処理の流れは思い浮かんだのですが
配列の並びのパターンをどう抽出するか、、、とひたすら調べまくってたら
permutation を見つけました。参考記事 https://qiita.com/shshimamo/items/5a458ecc88e7c24d5112
もっと時間をかけずに出来るようになりたいですねえ、、
何かアドバイスがあれば是非コメントお待ちしております!
- 投稿日:2020-08-17T18:01:06+09:00
プログラミング言語を学ぶ時には、はじめにプログラミング言語の家系図を見ておくとよいよ、という話
プログラミミング言語の家系図ってなに
あるプログラミングがいつ、どのような言語に影響を受けて誕生したかを表す系譜のことです。
プログラミミング言語の家系図はここにある
プログラミング家系図を載せているサイトはいくつかあるのですが、今回はこちらのサイトを紹介します。
diagram & history of programming languages (プログラミング言語の系譜)
主要言語のみものと、150以上の言語を載せているバージョンの2種類が記載されています。
2020年8月時点で、2018年の分まで記載されています。いくつかの言語をピックアップ
主要言語の図から、いくつかの言語をピックアップしてみましょう。
C言語(K&R)
- 誕生: 1978年
- 影響を受けた言語: Algol 60
- 影響を与えた言語: C++, Python (他、子孫多数)
注)
C言語の誕生は1972年であるが、リンク先の図では、『プログラミング言語C』(原題:The C Programming Language、通称 K&R)が出版された年を採用している。(参考: C言語 - Wikipedia, プログラミング言語C - Wikipedia)Python
- 誕生: 1991年
- 影響を受けた言語: C, C++, Pascal
- 影響を与えた言語: Ruby
Ruby
- 誕生: 1995年
- 影響を受けた言語: Perl, Eiffel, Python
- 影響を与えた言語: Swift
Java
- 誕生: 1995年
- 影響を受けた言語: C++
- 影響を与えた言語: JavaScript, C#, Kotlin
JavaScript
- 誕生: 1995年
- 影響を受けた言語: Java
- 影響を与えた言語: Kotlin
プログラミング言語(2言語目以降)を学ぶ時には、はじめにプログラミング言語の家系図を見ておくとよいよ
さて表題の件ですが、2言語目以降のプログラミング言語を学ぶときにはこの家系図を最初に確認することをおすすめします。
理由は
- 自分がすでに知っているプログラミング言語と、新しく学ぶ言語がどのくらい離れているかによって習得難易度を把握することができるから
- 自分がすでに知っているプログラミング言語より新しい場合、新しくて便利な構文があることを期待しながら学習を進められるから
- 自分がすでに知っているプログラミング言語より古い場合、便利な機能がないことを覚悟しながら学習を進めることができるから
です。
自分の場合は、Java歴5年、Perlはバッチ程度ならで少し書ける程度のときに、Rubyを習得しようとしました。
そのときに、RubyはPerlから影響を受けていることを知ったので構文の理解に役立ちました。
一方、関数型言語の知識はほぼ無かったのでその部分は苦労しましたが、そのことを事前に予測できたのはよかったと思います。あとがき
『はじめてのRuby』(著: Yugui) にRubyに関係する部分のプログラミング言語家系図が記載されていました。この図はRubyの理解に大変役に立ちました。
ほかの言語の図も探していたところリンク先のものが見つかりました。
プログラミング言語はここ数十年で大幅に進化しているのだなあ。
- 投稿日:2020-08-17T17:39:51+09:00
Railsのコントローラーについて
概要
Railsアプリケーションのコントローラーについて解説してみたいと思います。
今回のゴール
『MVCモデルについて知る』・『コントローラーの役割について』・『実践的な使い方』をついて確認することです。
1. MVCモデルとは
アプリケーションを作成する時に、コードを上手に管理するための考え方のひとつです。
あくまで考え方のひとつなので、絶対的に正しいというものではありません。
Railsアプリケーションは、このMVCフレームワークを取り入れています。MVCの3要素
『Model』・『View』・『Controller』になります。
・Model
・・・ システムの中でビジネスロジックを担当する・
View
・・・ 表示や入出力といった処理をする・
Controller
・・・ ユーザーの入力に基づき,ModelとViewを制御するRailsにおけるMVCの処理の流れ
クライアントからのリクエストを『Controller』が受け取る
『Controller』は『Model』にデータ処理をお願いする
『Model』はデータベースからデータを処理し、『Controller』にデータを返す
『Controller』は『View』に受け取ったデータの処理をお願いする
『View』はクライアントが見るのに適した形(HTML文書)を作成し『Controller』に返す
『Controller』はクライアントにHTML文章をレスポンスとして返す
1〜6を繰り返すことにより、Webアプリケーションとして成り立っています。
2. コントローラーの役割について
結論
・ルーティングから送られた情報をもとに、指定されたコントローラーのアクションメソッドを実行すること
・Model・Viewと連携して、クライアントにレスポンスを返すことアクションメソッド
ルーティングから指定されたアクションの具体的な処理内容を記述したメソッドです。
アクションメソッドのイメージclass SamplesController < ApplicationController def index # 具体的な処理内容 ...... ...... end end今回の例ですと...
ルーティングでsamplesコントローラーのindexアクションが指定された時、実行するアクションメソッドをdef index...end
という形で記述します。Modelとの連携について
目的
モデルを介して、データベースの新規作成や変更や取得をすることです。
方法
モデルが継承しているActiveRecord クラスのメソッドを使い、モデルに指示を出します。
下記はメソッドの一部の例になります。
メソッド 内容 all データベースの全てのデータを取得する find データベース内の、ある1つのデータを取得する new データの新規作成を生成する save データベースにデータを保存する メソッドのイメージ(モデルクラス名).[メソッド] Sample.allViewとの連携について
目的
モデルから受け取ったデータをビューに渡し、クライアントに返すレスポンスデータを作成することです。
方法
モデルからのデータをインスタンス変数を代入します。
@samples = Sample.allこれにより、ビューファイルでデータを使えるようになります。
3. 実践的な使い方
コントローラーの設定場所
app/controllers
ディレクトリ内に
コントローラー名_controller.rb
ファイルを設定します。コントローラーの命名規制
基本的に『複数形』にします。
理由は、Railsが使用するファイルなどを名前によって自動的に推測するからです。
仮に単数形にもできますが、開発者自身で明示的にコード記述しなければいけなかったり、予期せぬエラーのもとになってしまいます。
名称 例 備考 コントローラー名 samples コントローラークラス名 SamplesController キャメルケース コントローラーファイル名 samples_controller.rb スネークケース コントローラーファイルの構造
コントローラーファイルの中身は、このようになっています。
app/controllers/samples_controller.rbclass SamplesController < ApplicationController def index # 具体的な処理内容 ...... ...... end end作成したコントローラーファイルは『ApplicationControllerクラス』を継承します。
ApplicationControllerクラスとは
app/controllers/application_controller.rbclass ApplicationController < ActionController::Base end
app/controllers/application_controller.rb
ファイルに定義されたクラスです。
ActionController::Baseクラスを継承しただけの、(ほとんど)空のクラスになります。原則、各コントローラーは、ApplicationControllerクラス継承しているので
アプリケーション共通の機能(ログイン・ログアウトなど)が必要な場合に使用します。
ActionController::Baseクラスとは
コントローラーの基本的な機能を提供するクラスです。
リクエスト/レスポンス処理に関わる基盤部分を担っています。HTTPリクエストのパラメータの処理
コントローラーでは、クライアントからのHTTPリクエストのパラメータを『paramsメソッド』を経由して取得しています。
paramsメソッド
Railsが暗黙的にリクエストパラメータを処理して、ハッシュ形式でデータをparamsに格納してくれるメソッドです。
GETリクエスト・POSTリクエストによるアクセスでも、データの受け取り方に違いはありません。GETリクエストによるアクセス
HTTPリクエストのリクエストラインの『リクエストURI』にパラメータを含め、Webサーバにアクセスします。
『URL形式』と『クエリ形式』でパラメータを渡すことができます。
URL形式
下記のルーティング設定があった時に
Prefix Verb URI Pattern Controller#Action user GET /users/:id(.:format) users#show
http://sample.com/users/7
というURLでアクセスすると
リクエストの:id
のパラメータは7
という意味になり
Rails内ではparamsに格納されparams[:id]
の値は"7"
となります。app/controllers/users_controller.rbclass UsersController < ApplicationController def show params[:id] # "7" end end
クエリ形式
URLの最後に「?」に続けて「パラメータ名=値」を記述します。
複数のパラメータがある場合は「&」でつなげて記述します。
上記の例の同じルーティングを利用し
http://sample.com/users/7?keyword=query&num=10
というURLでアクセスすると
params[:keyword]
の値は"query"
、params[:num]
は"10"
となります。app/controllers/users_controller.rbclass UsersController < ApplicationController def show params[:keyword] # "query" params[:num] # "10" end end
POSTリクエストによるアクセス
クライアントがフォームからの入力で「送信」ボタンを押した場合などに発生するリクエストです。
HTTPリクエストの『ボディ』にパラメータを含め、Webサーバにアクセスします。またGETリクエストに比べて、多くのパラメータを送信することができます。
paramsを保存する時の注意点
『params』をデータベースに保存する時は、『Strong Parameters』という仕組みを使います。
Strong Parametersとは
Rails3系まで使われていた『Mass Assignment』の脆弱性を解消するための仕組みです。
『Mass Assignment』では、モデルに保存に関するparamsの情報を記述していましたが
『Strong Parameters』では、コントローラーに保存するparamsの情報を記述します。Strong_Parametersのイメージclass UsersController < ApplicationController def create @user = User.new(user_params) # user_paramsメソッドを使って、データの新規作成 @user.save # モデルを介して、データベースに保存する end # Strong Parametersはクラス外部から呼び出さないので、privateメソッドに記述する private def user_params params.require(:user).permit(:name, :age) end end今回の例ですと
user_params
メソッドで、保存するパラメータを:user
の:name
と:age
に指定しています。requireメソッド
データベースに保存するテーブル名を指定します。
permitメソッド
データベースのテーブルに保存するカラム名を指定します。
コントローラーの解説は以上になります。
ありがとうございました。
- 投稿日:2020-08-17T13:58:06+09:00
【超入門レベル】Rubyの基本シート
Rubyの基本チートシート
キノコードさんのYouTubeを参考にしています。
目次
- Rubyの特徴
- 環境構築
- プログラミングの基本構造
- プログラミングの実行
- 変数
- オブジェクト
- 配列
- 演算子
- 条件分岐
- 繰り返し
- メソッド
- クラス
- 総まとめ
Rubyの特徴
- 1995年
- まつもとゆきひろさん
- 日本語リファレンスが豊富
- Webアプリケーションが得意
- スクリプト言語→プログラムの記述や実行が簡単
- フレームワークRails→効率よく開発できる
環境構築
- Ruby本体→Macに標準でインストールされている
- VSCode本体と拡張機能→公式サイトからインストール→日本語、Rubyエクステンションパック
基本構造
- 順次進行→上から順に処理がされていく
- 条件分岐→条件によって処理が分かれる
- 繰り返し→決まった回数もしくは条件まで処理を繰り返す
プログラミングの実行
- ファイルの拡張子→「.rb」
- ソースコードの記述→半角スペースに気をつける
- ソースコードの保存→⌘+Sで保存
- ソースコードの実行→「表示」>「ターミナル」、「ruby ファイル名」
※putsは改行あり、printは改行なし
変数
- 変数とは?→文字や数字などのデータを入れたり、取り出したりできる。
変数の宣言
num = 1 puts num変数名のルール
- アルファベット、数字、アンダースコアが使える
- 数字から始めることができない
- 大文字と小文字は区別される
- 予約語は使えない(returnやclass、for、whileなど)
コメントアウト
「#」を先頭につける。
⌘+/がショートカットキーオブジェクト
オブジェクトとは
- 文字列や数値、変数、配列やハッシュなど
- メソッドで操作
- クラスに所属する→数値はintegerクラス所属、文字列はstringクラスに所属
- class()メソッド→所属しているクラスを調べる
数値オブジェクト
- 整数のintegerオブジェクト
- 少数のfloatオブジェクト
- div()メソッド→割り算
- remainder()メソッド→剰余算
文字列オブジェクト
- " "で囲む
- index()メソッド→文字列を探す
- lengthメソッド→文字列の長さを調べる
TrueとFalse
- TrueはTrueクラスに所属
- FalseはFalseクラスに所属
puts (10 > 1) puts (10 > 1).class => true => True配列
- 複数のデータを格納することができる。
- 一次元配列、多次元配列
- 添字は「順番 - 1」
配列の作り方
- 変数 = Array.new(要素数)
a = Array.new(3) a[0] = "sato" a[1] = "suzuki" a[2] = "takahashi"
- 変数 = [データ1,データ2,……]
a = ["sato","suzuki","takahashi"]配列の要素の変更
a[1] = "tanaka"多次元配列
arr = [["sato","suzuki"],["takahashi","tanaka"]] puts arr[0][0] puts arr[0][1] puts arr[1][0] puts arr[1][1]演算子
算術演算子→+,-,*,/,%
関係演算子→>,<,>=,<=,==,!=
論理演算子→&&,||
代入演算子→=
複合代入演算子→+=,-=,*=,/=
条件分岐
if文
age = 22 if age >= 20 puts "adult" elsif age == 0 puts "baby" else puts "child" end繰り返し
for文
for i in 0 .. 4 do puts i endbreak文→処理を終了
for i in 0 .. 4 if i == 3 break end puts i end 0 1 2next文→処理をスキップ
for i in 0 .. 4 if i == 3 next end puts i end 0 1 2 4ネスト
for i in 0 .. 2 for j in 0 .. 2 puts i.to_s + "-" + j.to_s end end "0-0" "0-1" "0-2" "1-0" "1-1" "1-2" "2-0" "2-1" "2-2"配列の繰り返し
arr = [2,4,6,8,10] sum = 0 for i in arr sum += i end puts sum =>30メソッド
- 同じものを2度書く必要がない
- 同じものを他の場面で使える
- 他の人も使うことができる
- 自分で作るメソッド、Rubyが用意してくれているメソッド
メソッドの定義
def sayHello(greeting) puts greeting end sayHello("Good evening")def add(num1,num2) puts num1 + num2 end add(6,2) =>8def add(num1,num2) return num1 + num2 end puts add(6,2) =>8def add(num1,num2) return num1 + num2 end add_result = add(6,2) puts add_result =>8クラス
- すべての値がオブジェクト
- オブジェクトはクラスから作ることができる
- オブジェクトがなにかしらのクラスに所属している
インスタンス
- オブジェクトとインスタンスはほぼ同義
- データのことをインスタンス変数という
- 処理のことをメソッドという
- インスタンス変数はクラスの中でしか使えない変数
- インスタンスメソッドはクラスの中に書かれたメソッド
クラスの定義方法
class Student def avg() puts (80 + 70) / 2 end endクラスの使い方(インスタンス生成)
a001 = Studet.new a001.avgメソッドに引数を渡す
class Student def avg(math, english) puts (math + english) / 2 end end a001 = Studet.new a001.avg(30,70)インスタンス変数
class Student def initialize @name = "sato" end def avg(math, english) puts @name,(math + english) / 2 end end a001 = Studet.new a001.avg(30,70)class Student def initialize(name) @name = name end def avg(math, english) puts @name,(math + english) / 2 end end a001 = Studet.new("sato") a001.avg(30,70)class Student def initialize(name) @name = name end def avg(math, english) return @name,(math + english) / 2 end end a001 = Studet.new("sato") puts a001.avg(30,70)アクセサ
インスタンス変数をオブジェクトの外から参照できる。
→クラスの外部からインスタンス変数を参照しようと思ったときに必要。class Student def initialize(name) @name = name end def avg(math, english) return (math + english) / 2 end attr_accessor :name end a001 = Studet.new("sato") puts a001.name,a001.avg(30,70)使いまわし
class Student def initialize(name) @name = name end def avg(math, english) return @name,(math + english) / 2 end end a001 = Studet.new("sato") puts a001.avg(30,70) a002 = Studet.new("tanaka") puts a002.avg(50,90)クラスの便利なところ
- 一度定義すればあとからインスタンスを作ることができる
- 車の設計図、たい焼きの金型、コピペみたいなもの→効率よくできる
総まとめ
- クラスを定義
- インスタンス変数を定義
- 平均を計算するメソッドを定義
- テスト結果を判定するメソッドを定義
- アクセサを記述する
- オブジェクト(インスタンス)を生成する
- 配列に点数を格納
- 変数に平均点を代入
- 変数に判定結果を代入
- それぞれを表示させる
class Student def initialize(name) @name = name end def cal_avg(data) sum = 0 for score in data do sum += score end avg = sum / data.length return avg end def judge(avg) result = '' if 60 <= avg result = "passed" else result = "failed" end return result end attr_accessor :name end a001 = Student.new("sato") data = [70, 65, 50, 90, 30] avg = a001.cal_avg(data) result = a001.judge(avg) p a001.name p avg p resultまとめ
Rubyを総まとめだ学習しましたが、こういう仕組みなのかと改めて理解できました。
キノコードさんの動画を見て、色々な言語をかじってみることでプログラミング言語の雰囲気を味わえるのかと思いました。
他の言語も少しかじってみよう!
次はPythonかな?
- 投稿日:2020-08-17T11:57:46+09:00
CSV出力の0落ち対応
- 投稿日:2020-08-17T10:56:52+09:00
【Ruby】複数の文字を置換したい場合
gsubメソッド
複数の文字を置換したいときは
gsub
を使えば、指定した通りに置換する事が出来ます。
@scivolaさんからコメントを頂いて記事を修正させて頂きました。@scivolaさんご丁寧にありがとうございます!gsub【置換したい部分をすべて置換】
以下例
x = "TOKYO" y = x.gsub(/[TOKY]/, "T" => "5", "O" => "3", "K" => "6", "Y" => "1") puts y => 53613該当したものを一字ずつ置換してくれます
また、置換時には文字列化されるので、5と書いても"5"と書いても結果は変わりません。String#trメソッド
また、1 文字を 1 文字に置き換える「換え字」なら,gsub を使うより専用メソッド String#tr を使ったほうが簡潔で高速みたいです!
y = x.tr("TOKY", "5361")
- 投稿日:2020-08-17T00:50:41+09:00
オブジェクト指向についての論理的な考え方をまとめてみました。
オブジェクト指向について
これから説明する中で使われる用語を簡単にまとめました。
オブジェクト = 全てのデータのこと、物、 オブジェクト指向 = 一言で言うと「抽象的な概念」=それぞれの持つ共通の情報をまとめたものから個別の情報を持った物を作る メソッド = プログラミングにおける何らかの処理をすること。例えば print("hello world") "hello world"と言うのが**オブジェクト**。これを出力するための処理が**print**になります。つまりprintメソッド) クラス = 設計図のこと インスタンス = 設計図(クラス)で作られた実体のことはじめに
RubyやPython(オブジェクト指向言語は他にもあります。)と言うのは全てをオブジェクトとして扱っています。オブジェクトと言うのはそれぞれが固有の性質、固有の動作を使って返り値を返します。
例えば、現実世界で例えると、人間一人一人(Aさんと言う人間、Bさんと言う人間。)と言うのは別々のオブジェクトになります。一人の人間に「Aさん」と言うオブジェクトがあります。人間ですので固有の名前、性別、年齢、趣味をもち、話したり、歩いたりといった動作(メソッド)ができます。なぜオブジェクトを使うのか?(その理由を説明します。)
例えば、車で説明すると車の外見は変えることはないが車のスペックを変えたい時にまとめらた資料があるからその資料だけ変えれば全部の車のスペックをいちいち変える必要性はない=コードの記述量をコンパクトにすることができる。=もう少し深堀りすると、実際にエンジニアの現場では仕様変更に伴うコードを書き換えることがよく起こることから変更に強いメリットがあります。
(少し説明しづらいのですが、わからなければご自身でも少しわかりやすい記事を調べてください。)クラスとインスタンスについて
クラスとインスタンスの関係性を車で説明したいと思います。例えば車を作る前に設計図を作りますよね?それがクラスになります。設計図を元に実際に作られた車(実体)と言うのがインスタンスになります。もう少し深堀りのある説明をします。
クラスとは、共通の属性(プロパティ)と処理(メソッド)をまとめたオブジェクトのことです。クラスを使うことでゲームで例えると、デフォルトの設定(共通の情報)動く、走る、戦うと言うのを安易に分けることができる。
インスタンスとは、その動く、走る、戦うといった抽象的な動作のクラスの細かな設定をする役割があります。それをインスタンス変数と呼ぶのですが。(例えば、戦うの中でAさんは魔法が使えて、その魔法の威力は50ダメージがあります。Bさんは、ハンマーが使えて、そのハンマーの威力は80ダメージあります。とか)クラス = 抽象的なこと(概念、共通)
インスタンス = 具体的なこと(具現、特有の)クラスメソッドとインスタンメソッド(インスタンス変数)について
先ほどでは、クラスとインスタンスの考え方を学びました。次は、これらのクラスとインスタンスに情報を追加して扱い方を学んでいきたいと思います。
ーーーーーーーーーーーーーーインスタンスメソッド
python ①print(len("hello world")) #出力 11 ②print(len("Good bye")) #出力 8pythonのLenメソッドを使って文字列の値を確認しました。①と②は同じメソッドを用いていますが、出力値が異なっていいます。これらをインスタンスメソッドと呼びます。
インスタンス変数
オブジェクトが持つ性質は属性と呼び、その値を属性値と呼びます。例えば、色は属性で赤色と言うのが属性値と呼びます。これをインスタンス変数と呼びます。
インスタンス変数とは、オブジェクトが個別に持つ属性値が入り、そのオブジェクトの全ての動作に使用できる変数のことです。
ーーーーーーーーーーーーーーーー
クラスメソッド
クラスメソッドはクラスが使用できるメソッドのことです。もう少しわかりやすく説明しますとクラスで共通の情報を使った処理のことです。
すみません、クラスメソッドはまだ勉強中なので今回はここまでにします。またわかり次第修正します。
- 投稿日:2020-08-17T00:49:46+09:00
友愛数、完全数、過剰数、不足数、回文数 色んな数のプログラムを作ってみた
何かQiitaに投稿できそうなネタは無いかなーーとフォルダを漁っていると、
6年以上前にProjectEulerちょっとやってみてた時のスクリプトを掘り起こしたので、
それを書きます実行環境は下記になります。
ruby 2.6.3p62
macOS Catalina 10.15.6
zsh
約数を生成する
約数なんだったけという方は下記を参照下さい。
https://ja.wikipedia.org/wiki/約数divisor.rbdef create_divisor (num) divisor_ary = Array.new partner_divisor_ary = Array.new if num < 1 then return nil elsif num == 1 then divisor_ary.push 1 else i = 1 partner_divisor = 0 until i == partner_divisor do if num % i == 0 then divisor_ary.push i partner_divisor = num / i if partner_divisor != i then partner_divisor_ary.unshift partner_divisor else break end end i += 1 end divisor_ary += partner_divisor_ary end return divisor_ary end class Integer def divisor return create_divisor(self) end end p 8.divisor p 128.divisor p 12345.divisor実行結果は下記になります。
% ruby divisor.rb [1, 2, 4, 8] [1, 2, 4, 8, 16, 32, 64, 128] [1, 3, 5, 15, 823, 2469, 4115, 12345]※ 以下のコードで、
約数生成するcreate_divisor関数の定義は省略してます。友愛数を生成する
友愛数...リア充な良い名前だと思います。
自然数a,bとして、
・aの約数の和-a = b
かつ、
・bの約数の和-b = a
となる時、a, bを友愛数というみたいです。
詳細で正確な解説は下記参照。
https://ja.wikipedia.org/wiki/友愛数number_amicable.rbclass Integer def divisor return create_divisor(self) end def amicable amicable_number = nil if self < 1 then return amicable_number end divisor_ary = self.divisor divisor_ary.pop unless divisor_ary.empty? then partner_number = divisor_ary.inject(:+) if partner_number != self then partner_divisor_ary = partner_number.divisor partner_divisor_ary.pop if partner_divisor_ary.inject(:+) == self then amicable_number = partner_number end end end return amicable_number end end p 220.amicable p 284.amicable p 17296.amicable p 18416.amicable p 200.amicable実行結果は下記になります。
% ruby number_amicable.rb 284 220 18416 17296 nil完全数か過剰数か不足数かを判定する
自然数aとして、
(1) 約数の総和 = a*2 の場合、 aは完全数[perfect number]。
(2) 約数の総和 > a*2 の場合、 aは過剰数[abundant number]。
(3) 約数の総和 < a*2 の場合、 aは不足数[deficient number]。
みたいです。
詳細で正確な解説は下記参照。
https://ja.wikipedia.org/wiki/完全数
https://ja.wikipedia.org/wiki/過剰数
https://ja.wikipedia.org/wiki/不足数number_p_a_d.rbclass Integer def divisor return create_divisor(self) end def compare_divisor_total sum_divisor = self.divisor.inject(:+) sum_divisor -= self if sum_divisor > self then return "abundant number" elsif sum_divisor == self then return "perfect number" else return "deficient number" end end end p 496.compare_divisor_total p 20.compare_divisor_total p 15.compare_divisor_total p 1.compare_divisor_total実行結果は下記になります。
% ruby number_p_a_d.rb "perfect number" "abundant number" "deficient number" "deficient number"回文数かどうかを判定する
回文数とは、上から読んでも下から読んでも同じ数になる数のことです。
詳細で正確な解説は下記参照。
https://ja.wikipedia.org/wiki/回文数number_palindrome.rbclass Integer def palindrome? str = self.to_s if str[0, (str.length / 2).floor] == str.reverse[0, (str.length / 2).floor] return true else return false end end end p 341.palindrome? p 121.palindrome? p 3456543.palindrome?実行結果は下記になります。
% ruby number_palindrome.rb false true true以上です。
- 投稿日:2020-08-17T00:44:45+09:00
Rails Tutorialを咀嚼する【第3章 ほぼ静的なページの作成】
3.1 セットアップ
【演習】
1.BitbucketがMarkdown記法のREADME (リスト 3.3) をHTMLとして正しく描画しているか、確認してみてください。
2.本番環境 (Heroku) のルートURLにアクセスして、デプロイが成功したかどうか確かめてみてください。⇒そのままやってみてください。
3.2 静的ページ
■コントローラ
コントローラとは (基本的に動的な) Webページの集合を束ねるコンテナのこと。
→ちょっと意味が分からない。■rails generate controller StaticPages home help
コントローラーにstatic_pages_controller.rbが生成される。
routes.rbに
・static_pages/home
・static_pages/help
が生成される。この時点でアドレスバーに「static_pages/home」と入力すれば移動する。
異動する先はビューの「home.html.erb」。
※helpも同様。■HTTPメソッド
GET、POST、PATCH、DELETEの4つがある。
GET:ページを呼び出す
POST:ユーザーが何かを入力して送信するときに使う。
PATCH:おそらく更新に使う。
DELETE:削除に使う【演習】
1.Fooというコントローラを生成し、その中にbarとbazアクションを追加してみてください。
→コントローラーを生成するのでrails generateを使います。
rails generate controller Foo bar baz2.コラム 3.1で紹介したテクニックを駆使して、Fooコントローラとそれに関連するアクションを削除してみてください。
コラムを参照
→rails destroy controller Foo bar baz3.3 テストから始める
■テストケース、テストスイート
1つのテストのことをテストケースと呼ぶ。
テストケースが集まったものをテストスイートと呼ぶ。■テスト駆動設計
テストコードを書いてから開発を進める手法■static_pages_controller_test.rb
rails gと同時に生成されている。test/controllers/static_pages_controller_test.rbtest "should get home" do get static_pages_home_url assert_response :success endこのファイルは既にActionDispatch::IntegrationTestを継承しているので、
そういうものなのだと理解する。
「should get home」というテストを新しく生成。
「get static_pages_home_url」でアクセス。
「assert_response :success」で成功か否か判断。■touch app/views/static_pages/about.html.erb
touch app/views/static_pagesのディレクトリに
about.html.erbのファイルを生成する。右クリックからの「ファイルを作成」でもいける。
■about.html.erb
とかはいらない。
3.4 少しだけ動的なページ
→リファクタリングを行っているページなので、最悪後回しでも大丈夫。
■mv app/views/layouts/application.html.erb layout_file
application.html.erb を layout_fileに移動する。■assert_select "title", "Home | Ruby on Rails Tutorial Sample App"
移動した先のページのタイトルタグの中身が「"Home | Ruby on Rails Tutorial Sample App"」かどうか確認する。【演習】
1.StaticPagesコントローラのテスト (リスト 3.24) には、いくつか繰り返しがあったことにお気づきでしょうか? 特に「Ruby on Rails Tutorial Sample App」という基本タイトルは、各テストで毎回同じ内容を書いてしまっています。そこで、setupという特別なメソッド (各テストが実行される直前で実行されるメソッド) を使って、この問題を解決したいと思います。まずは、リスト 3.30のテストが green になることを確認してみてください (リスト 3.30では、2.2.2で少し触れたインスタンス変数や文字列の式展開というテクニックを使っています。それぞれ4.4.5と4.2.2で詳しく解説するので、今はわからなくても問題ありません)。
→「Ruby on Rails Tutorial Sample App」という文字ががたくさん出てきて面倒だよね?という話です。@base_titleにRuby on Rails Tutorial Sample Appという文字列を代入し、
それぞれで展開をしている。■Provideメソッド
タグの中身以外が同じになるようにしている。
provideメソッドでパラメータを引き渡し、yieldメソッドで受け取る。
タイトルを統一させることで、■app/views/layouts/application.html.erb
デザインの根幹をなしているもの。【演習】
1.サンプルアプリケーションにContact (問い合わせ先) ページを作成してください17 (ヒント: まずはリスト 3.15を参考にして、/static_pages/contactというURLのページに「Contact | Ruby on Rails Tutorial Sample App」というタイトルが存在するかどうかを確認するテストを最初に作成しましょう。次に、3.3.3でAboutページを作ったときのと同じように、Contactページにもリスト 3.40のコンテンツを表示してみましょう。)。1.static_pages/にcontact.html.erbというファイルを作る。
routes.rb<% provide(:title, "Contact") %> <h1>Contact</h1> <p> Contact the Ruby on Rails Tutorial about the sample app at the <a href="https://railstutorial.jp/contact">contact page</a>. </p>2.テストを作る。名前をcontactに変えるだけ
static_pages_controller_test.rbtest "should get contact" do get static_pages_contact_url assert_response :success assert_select "title", "contact | #{@base_title}" end3.routesを設定する
routes.rbget 'static_pages/contact'4.コントローラーにパスを通す。
static_pages_controller.rbdef contact end【演習】
1.リスト 3.41にrootルーティングを追加したことで、root_urlというRailsヘルパーが使えるようになりました (以前、static_pages_home_urlが使えるようになったときと同じです)。リスト 3.42のFILL_INと記された部分を置き換えて、rootルーティングのテストを書いてみてください。rootはどこのディレクトリにも属していないのでstatc_pagesは不要
static_pages_controller_test.rbtest "should get root" do get root_url assert_response :success end3.5 最後に
3.6 高度なセットアップ