ためすう
Ruby でファイルを操作する
2019-05-14やったこと
Ruby でファイルの書き込み、読み込み、削除をやってみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
調査
ファイルの書き込み
File.open('test.md', 'w') do |file|
file.puts 'hogehoge'
end
ファイルの読み込み
File.open('test.md', 'r') do |file|
file = file.read
p file
end
ファイルの削除
File.delete('test.md')
ファイルの存在チェック
if File.exist?('test.md')
p 'test.md is exist'
end
参考
Rails5 でコールバックを使う
2019-05-14やったこと
Rails5 で Active Record のコールバックを使ってみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
$ rails --version
Rails 5.2.3
調査
コールバックについて
コールバックとは、オブジェクトのライフサイクル期間における特定の瞬間に呼び出されるメソッドのことです。コールバックを利用することで、Active Recordオブジェクトが作成/保存/更新/削除/検証/データベースからの読み込み、などのイベント発生時に常に実行されるコードを書くことができます。
動作確認
今回は、 after_initialize を使ってみます。
app/controllers/tasks_controller.rb
class TasksController < ApplicationController
def index
@task = Task.new
end
end
app/models/task.rb
class Task < ApplicationRecord
after_initialize :hogehoge
def hogehoge
logger.debug('called hogehoge with after_initialize')
end
end
after_initialize を使えば、initialize をオーバーライドしなくても良くなります。
after_initializeコールバックは、Active Recordオブジェクトが1つインスタンス化されるたびに呼び出されます。インスタンス化は、直接newを実行する他にデータベースからレコードが読み込まれるときにも行われます。これを利用すれば、Active Recordのinitializeメソッドを直接オーバーライドせずに済みます。
参考
第1章 Python ではじめる機械学習 (実践機械学習システム)
2019-05-12メモ
機械学習の目的は、データの裏側に潜むパターンや関係性を学ぶことで、データについてより深い洞察を得ることです。
作業の流れ
- データを読み込み、データを整形する
- 入力データの調査および解釈を行う
- 学習アルゴリズムにどのような形でデータを入力するのが相応しいか分析を行う
- 正しいモデルと学習アルゴリズムを選択する
- 結果に対して正確な評価を行う
改良したデータに対して単純なアルゴリズムを用いるほうが、生データに対して洗練されたアルゴリズムを用いるより、結果が良いことがほとんど です。
データを改良する行為を「特徴エンジニアリング (feature engineering)」と呼ばれます。
機械学習の初心者にとって最も間違いを起こしやすい場所は、性能を評価する段階です。
たとえば、まず全データの数%だけを保持 (ホールドアウト) しておき、残りのデータを使って学習を行うとします。そして保持したデータを用い て誤差を計算するのです。
まとめ
大切なこと
- 機械学習の作業において最も大切なことは、データを理解しデータを扱いやすい形に整形すること。
- 正しい評価を行うこと。正しい評価を行うにあたって、訓練データとテストデータを区別する。
参考
- 実践機械学習システム
Ruby で inject を使う
2019-05-12やったこと
Ruby で inject メソッドについて調べます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
調査
inject は
リストのたたみこみ演算を行います。
$ rails c
irb(main):001:0> [1, 3, 5].inject { |result, item| result + item }
=> 9
irb(main):002:0> [1, 3, 5].inject { |result, item| result + item**2 }
=> 35
irb(main):003:0> [1, 3, 5].inject(10) { |result, item| result + item**2 }
=> 45
irb(main):004:0> [1, 3, 5].inject(:+)
=> 9
ちなみに、同じ処理をするために each を使っても出来ます。
参考
Rails5 で rescue_from を使う
2019-05-12やったこと
Rails5 の rescue_from メソッドについて調べます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
$ rails --version
Rails 5.2.3
調査
app/controllers/tasks_controller.rb
class TasksController < ApplicationController
rescue_from Exception, with: :render_500
def index
raise Exception.new
end
def render_500
logger.debug('render_500')
end
end
※ 任意のコントローラに記述してください
注意点
ApplicationControllerクラスでは一部の例外についてrescueできないものがあります。その理由は、コントローラが初期化されてアクションが実行される前に発生する例外があるからです。
と説明があるので、コントローラが初期化される前に、例外が発生した場合は捕捉できない場合があります。
参考
Ruby でキーワード引数を使う
2019-05-12やったこと
キーワード引数を使ってみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
調査
test.rb
class Sample
def initialize(params)
p params
# a を取りだす
p params[:a]
end
end
Sample.new(a: 111, b: 222)
出力結果
$ ruby test.rb
{:a=>111, :b=>222}
111
情報を探しても見つかりませんでしたが、関数の引数に ** を付きなくても キーワード引数のハッシュとして、扱えるようです。
Rails5 で try を使う
2019-05-12やったこと
try メソッドについて調べます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
$ rails --version
Rails 5.2.3
調査
レシーバーのクラスがnilの場合
$ rails c
irb(main):001:0> @number.try(:nest)
=> nil
irb(main):002:0> @number.try!(:nest)
=> nil
try, try! のどちらを使っても nil が返されました。
レシーバーのクラスが存在する場合
$ rails c
Running via Spring preloader in process 21611
Loading development environment (Rails 5.2.3)
irb(main):001:0> class Sample
irb(main):002:1> def nest
irb(main):003:2> p 3
irb(main):004:2> end
irb(main):005:1> end
=> :nest
irb(main):006:0> @number = Sample.new
=> #<Sample:0x00007f96c024adc0>
irb(main):007:0> @number.try!(:nest)
3
=> 3
irb(main):008:0> @number.try!(:nest_nothing)
Traceback (most recent call last):
1: from (irb):8
NoMethodError (undefined method `nest_nothing' for #<Sample:0x00007f96c024adc0>)
irb(main):009:0> @number.try(:nest)
3
=> 3
irb(main):010:0> @number.try(:nest_nothing)
=> nil
try だと存在しないメソッドを呼び出そうとしても nil が返されることが分かります。
try について
nilでない場合にのみオブジェクトのメソッドを呼び出したい場合、最も単純な方法は条件文を追加することですが、どこか冗長になってしまいます。そこでtryメソッドを使うという手があります。tryはObject#sendと似ていますが、nilに送信された場合にはnilを返す点が異なります。
tryメソッドは、NoMethodErrorを握りつぶして代わりにnilを返す点に注意が必要です。メソッド名の誤りを防ぎたい場合はtry!を使います。
try を使うには、 Active Support を読み込んでおく必要があります。
Rails の場合は、すぐに使えるようです。
Ruby on Railsアプリケーションでは、基本的にすべてのActive Supportを読み込みます。
参考
Ruby での参照渡しについて
2019-05-10やったこと
Ruby での参照渡しについて、調べてみます。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
調査
関数に渡す引数の変数について、object_id を調べてみます。 また変数の代入もしてみます。
test.rb
def test(a, b)
p "a: #{a.object_id} in test"
p "b: #{b.object_id} in test"
end
a = 1
b = 2
c = b
p "a: #{a.object_id}"
p "b: #{b.object_id}"
p "c: #{c.object_id}"
test(a, b)
出力結果
$ ruby test.rb
"a: 3"
"b: 5"
"c: 5"
"a: 3 in test"
"b: 5 in test"
どうやら、引数として渡す前、渡した後のオブジェクトは同じもののようです。
つまり、引数に対して関数内で引数のオブジェクトに直接変更を加えると 関数を抜けた後も影響を受けます。
test.rb
def test2(a, b)
a.upcase!
end
a = 'abc'
b = 'jkl'
test2(a, b)
p a
p b
出力結果
"ABC"
"jkl"
参考
Rails5 でエラーページを表示する
2019-05-09やったこと
Rails5 にて、エラーページを表示する方法を調べました。
静的なページ、動的なページのどちらにするかで方法が変わります。
確認環境
$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]
$ rails --version
Rails 5.2.3
調査
静的なページを表示
すでに用意されているものを利用します。
config/environments/development.rb
config.consider_all_requests_local = false
例えば存在していないページにアクセスした時、 public/404.html が使われます。
動的なページを表示
config/environments/development.rb
config.consider_all_requests_local = false
エラーページの view を用意します。
app/views/errors/error_404.html.erb
404 dayo
例外を制御します。今回は 404エラーの時の振る舞いを定義します
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
rescue_from ActionController::RoutingError, with: :render_404
def render_404
logger.debug(9999)
render template: 'errors/error_404', status: 404, layout: 'application', content_type: 'text/html'
end
end
最後にルーティングの一番下に下記を追加してください
config/routes.rb
get '*path', controller: 'application', action: 'render_404'
参考
Rails5 で日付のバリデーションを行う
2019-05-09やったこと
Rails5 で日付、日時をフォーマットする方法を調べます。
確認環境
$ ruby --version
ruby 2.6.2p47 (2019-03-13 revision 67232) [x86_64-darwin17]
$ rails --version
Rails 5.2.3
調査
やったこと
Rails5 ではデフォルトで日付のバリデーションがないようなので、実装方法を調べました。
task.expire_date という タスクの有効期限について、日付のバリデーションをかけます。
調査
app/models/task.rb
class Task < ApplicationRecord
validate :expire_date_is_valid?
private
def expire_date_is_valid?
begin
Date.parse self.expire_date.to_s if self.expire_date.present?
rescue ArgumentError
errors.add(
:expire_date,
'無効な日付です'
)
end
end
end
Date.parse の挙動も試してみました。
$ rails c
irb(main):001:0> Date.parse(888)
Traceback (most recent call last):
2: from (irb):1
1: from (irb):1:in `parse'
TypeError (no implicit conversion of Integer into String)
irb(main):002:0> Date.parse('20190509')
=> Thu, 09 May 2019
irb(main):003:0> Date.parse('2019-05-09')
=> Thu, 09 May 2019
irb(main):004:0> Date.parse('19-05-09')
=> Thu, 09 May 2019
irb(main):005:0> Date.parse('9919-05-09')
=> Fri, 09 May 9919
irb(main):006:0> Date.parse('11')
=> Sat, 11 May 2019
これをみると、厳密なチェックは出来ていないので、使用するときは注意してください。