国境の南

Ruby, Railsメイン

フィボナッチ数アルゴリズム

プロジェクトオイラーのこの問題を解いてみました。 https://projecteuler.net/problem=2

Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

後置whileを使ったらスッキリかけました。

class Hoge
  def self.fibonacci(limit,ary=[1,2])
    ary << ary[-2..-1].inject(:+) while ary[-2..-1].inject(:+) < limit
    return ary.select { |elm| elm % 2 == 0 }.inject(:+)
  end
end

describe Hoge do
  describe '#fibonacci' do
    it 'Correct value' do
      expect(Hoge.fibonacci(4000000)).to eq 4613732
    end
  end
end

一応解説すると、配列に配列の最後2つの数字の和を放り込む、という動作を、limitが超えない限り続けるというもの。 このプロジェクトオイラー、会社の同期でわいわいやっているのですが 大分書き方の違いがみられて面白い。また、自分の癖みたいなものが見えてきます。 例えば自分の場合なら、配列を用意することが多くて、再帰やprocを活かすのに苦手意識があるのか全然使わないなど。

[別解] 友人はSQLで解いた

# with recursive fib(num1, num2) as (
( >     values(1, 2)
( >     union all
( >     select
( >         num2
( >         , num1 + num2
( >     from
( >         fib
( >     where
( >         num1 <= 4000000
( > )
- > select
- >     sum(num1)
- > from
- >     fib
- > where
- >     num1 % 2 = 0
- > ;
   sum   
---------
 4613732
(1 row)

Time: 0.565 ms

@InoHiro

ポリモーフィック関連テーブルでもEager Loadingがしたい(1)

ポリモーフィック関連のおさらい

まず、ポリモーフィック関連のおさらいから。
まずは、「ポリモーフィック関連を使わない」具体的な実装をみてみます

例えば小説サイトで、ユーザーが、小説モデル、ブログモデル、Tweetモデルを持てて、
上の全てのモデルに対して、ユーザーはコメントを付けることが出来る、という場合

class Novel
  has_many :comments
end

class Blog
  has_many :comments
end

class Tweet
  has_many :comments
end

class Comment
  belongs_to :novel
  belongs_to :blog
  belongs_to :tweet
end

このやり方だと
- Commentモデルの使い回しのためにbelongs_toが増えるのが冗長 - コメント可能なモデルを変更する度に、Commentモデルのテーブル構造も変更しなければならない
のが面倒

そこで、ポリモーフィック関連を使うとこういう実装に出来ます

class User
  has_many :novels
  has_many :blogs
  has_many :tweets
  has_many :comments
end

class Novel
  belongs_to :user
  has_many :comments, as: :commentable
end

class Blog
  belongs_to :user
  has_many :comments, as: :commentable
end

class Tweet
  belongs_to :user
  has_many :comments, as: :commentable
end

class Comment
  belongs_to :user
  belongs_to :commentable, polymorphic: :true
end

これを実現する引き換えに、どこに対するコメントなのかを判別するために
Commentモデルは、commentable_idと、commentable_typeを持ちます
詳しくは↓
railsguides.jp

次は、このポリモーフィック関連テーブルをいい感じでjoinするケースについてまとめます

少しプログラミングの景色が変わった気がした写経①

久々のエントリです。

上司「お前全然ブログ書いてないじゃねえか!アウトプットしないと何も身につかないぞ!!」 本当にその通りなので継続的に頑張ります。

初歩的な内容かもしれませんが、写経をしていた中で、表題どおり、こんなことも出来るのか、と世界が広がった気がしたプログラムをいくつか紹介します。

class Yo
  def initialize(select)
    @selector = select
  end

  def yo
    puts(@selector.create_message)
  end
end

class EnglishYo
  def create_message
    "Yo!"
  end
end

class JapaneseYo
  def create_message
    "やあ"
  end
end

Yo.new(EnglishYo.new).yo
Yo.new(JapaneseYo.new).yo

>Yo!
>やあ
(※7.6 間違って、Hello.new(EnglishYo.new).yoとなっていたのを修正しました)

これの利点は - 呼び出しのフォーマットを統一できる - 何かが意図しない動作となったときに、どこを直すべきかを理解しやすい

これはポリモーフィズムというパターンで、ポリモーフィズムとは - 同じ名前のメソッドを呼び出すが、オブジェクトによって振舞いを変えること というパターンのようです。

技術部長に聞いてみたところ、 「きちんとポリモーフィズムを実現するためには、オブジェクトが適切にカプセル化されている必要がある。 要はオブジェクトが、正しい振舞いを知っている、ということで、カプセル化と表裏一体である」 とのコメントをいただきました。

色々アレンジしつつ写経して動かしてみると面白さが分かるかと思います。

コミットログのAuthorとかCommitにまずい情報が入ったら

前のエントリが上司の目に触れて指摘されたのだけど
一番最初のエントリで紹介しているChrome拡張のcommit logに含まれるAuthorとCommitが会社のメールアドレスだった。

そもそも、自分のコンソールではg logとやると

Mon May 18 19:31:22 2015 +0900 089772a (HEAD, origin/user-topics, user-topics) Add topics index show  [fkagami]
Mon May 18 15:24:35 2015 +0900 fae405a (origin/signin-out, signin-out, master) Make current user  [fkagami]
Sat May 16 16:21:27 2015 +0900 5f39bb4 (origin/master) Merge pull request #7 from fumiyasu-kagami/signup  [fkagami]

みたいな表示となるように設定してあったので、コミットログにメールアドレスが含まれるものだということも知らなかった(忘れていた)

g log --pretty=full

と打つと、下のような表示になる

commit 24d729e39564a482aa8d7c769162983412b2b989
Author: <ユーザー名> <登録メアド>
Commit: <ユーザー> <登録メアド>

    Bump gems

commit 7fffd96ee3ee78013d181380c9c395b54cddc4bd
Author: <ユーザー名> <登録メアド>
Commit: <ユーザー名> <登録メアド>

    Add example

ここの登録メアドの部分にバッチリ社名が刻まれていて
拡張の内容が内容なだけに焦った。

調べたところ、以下のようなコマンドで一括してコミットログのユーザー情報を変更できるらしい

git filter-branch -f --env-filter "GIT_AUTHOR_NAME='<登録したい名前>'; GIT_AUTHOR_EMAIL='<登録したいメアド>'; GIT_COMMITTER_NAME='<登録したい名前>'; GIT_COMMITTER_EMAIL='<登録したいメアド>';" HEAD

または、事前にディレクトリの.git/configで登録アドレスを設定しておくことも出来る。 configにはglobalとリポジトリ単位のlocalがあるので、globalを個人メアドにして、仕事用のリポジトリはlocalで社用アドレスに変更しておくみたいなやり方にするのが一番安全かもしれない

しかし、本格的に推測されないようにするためには個人githubに上がっている全てのリポジトリとコミットログに関して過去を改ざんする必要があってかなり面倒 (そもそも社用PCで個人開発をするべきでない or インモラルなツールを公開するべきでない)

Rails Tutorial以前 - Web系エンジニア入門レベルを達成するには -

Webエンジニアになりたいと思って、まずはじめに取り組んだのはRails Tutorialだったのだけれど
エンジニアを志して半年程経ったこのタイミングで色々と思う所があって、
同じ轍を踏む人が少しでも減ればと思い
初学者が効率的にWeb系エンジニアとしての入門レベルを終えるにはどうすればいいのかという形でまとめる

そもそもRails Tutorialとは

ちょっとしたサイトを作ったことがあって(=HTML, CSSを使える) 入力した数字の素数判定が出来る程度のプログラミング能力があれば*、
とりあえず解説を読み下して、TwitterモドキをRailsで作れる丁寧なチュートリアルサイトのこと

railstutorial.jp

*実際どうかしらん、Rails Tutorialに自分が初めて取り組んだ時のレベル感

Rails Tutorial いい点と悪い点

いい点

  • とにかく写経すれば、ログイン機能やフォロー機能のある、ちゃんとしたWebサービスをつくれる
  • デプロイはherokuだけど、サービスの全体感がつかめる
  • (人によると思うけど)「こんな感じなら自分でもいけそうやん!みたいな感じで開発への心理的なハードルが下がる
  • 動くものが出来上がるから楽しい

悪い点

  • プログラミングの基本、オブジェクト指向、データベースの仕組みや操作、Webの基本的な仕組み等は学べない

自分はこの本来学ぶべきことを殆ど全くやらないままに
Webサービスのチーム開発に参加して、雰囲気で表面的なところのコードを書いたりしていた
本質的な理解をしていないから、ググっても出てこない事をやろうとしただけですぐに躓くし
「何が分からないのかも分からない」状態に陥りまくった

こんな極端なのは他にいないと思うけれど、
仕事でちょっとした純rubyスクリプトを書いた時に「classってそもそも何なんや...」となってしまうレベルだった
Railsは雰囲気で動かせてしまうために、Railsから入った人はこの悪い点をこじらせやすいのではないかとも思う...

初学者におすすめの勉強順

「自分一人の力で、自分が作りたい(そんなに複雑じゃない)Webのサービスを作れる」というところをゴールとして
もし自分が過去に戻ったならこういう順番で取り組みたい(最終的にRails使う前提)

Rails Tutorial

  • 最初のモチベーションを上げてくれるという意味ではとても良い

プログラミング

オブジェクト指向とActive Recordパターンをなんとなく理解出来るところまで行くと、Rails Tutorial2周目が多少捗ると思う

DB / SQL

CD付 SQL ゼロからはじめるデータベース操作 (プログラミング学習シリーズ)

CD付 SQL ゼロからはじめるデータベース操作 (プログラミング学習シリーズ)

Javascript

上同様、CodeAcademyとドットインスールの入門レベルに加えて、この教本

JavaScript本格入門 ?モダンスタイルによる基礎からAjax・jQueryまで

JavaScript本格入門 ?モダンスタイルによる基礎からAjax・jQueryまで

再びRails Tutorial

ちなみに教本は読むだけだと無意味で、全部書いてみて動かすべき

まだ入門レベルの自分は、ここに書いてある教本に関しては全てやろうと思っていて、おすすめのものがあれば随時更新するかもしれない
techlife.cookpad.com

追記

Rails Tutorialでも同じことを言っている節がありました

このため、とにかくWebアプリケーションを書けるようになりたい方は、最初にRailsを学び、次にRubyを学んでから再びRailsに戻ってくることをお勧めします。

参考リンク

blog.sumyapp.com

Xvideosを一発でダウンロードするChrome拡張を作った

毎月1つ、何かしらのwebサービスを公開していきたいと思っています。

大きい物を作ろうとして何度も挫折しているので、以下の方針を敷いてみました。

 

方針

  • 自分が欲しい物を作る
  • 週末で作れるものにする。最大でも、丸5日程度
  • 不完全でもいいから公開する

 

何事も最初が肝心。第一弾は、xvideoを一発DLするChrome Extension "Ippatsu"

github.com

 

なぜ作ったか

Xvideosをダウンロードするためのサイトはたくさんあるが、余計なものをDLさせたり、煩わしい広告を表示してくるのが嫌だったから。

 

Ippatsuなら、Chromeに追加すればvideoのページでぽちっと押すだけで快適ダウンロードできます。あっという間に容量がいっぱいになるので、ダウンロード先をDropboxにするのがおすすめ。

 

今後

ボタン一発でダウンロードする機能はそのまま、xpornやxhamsterなどに横展開していきたい。

また、xvideosに関しては、一覧画面の動くサムネでもある程度内容がわかるので、PinterestのChrome拡張よろしく、一覧画面からも個別の動画をダウンロードできるようにしたい。