20211202のRubyに関する記事は11件です。

【Ruby のまずいコード】回文数を表示

お題 3 桁の回文素数をすべて表示してください。 回文素数とは,回文数になっている素数のことです。 回文数とは,数字列で書いたときにそれが回文になっている数のことです。 一般の $N$ について,$N$ 進法の回文数を考えることができますが,ここでは 10 進法で表記した場合のこととします。 たとえば,101 という数は回文になっていて,しかも素数なので回文素数です。 121 は回文数ですが,合成数なので($11^2 = 121$)回文素数ではありません。 コード require "prime" def put_palindromic_prime_number(num) str = num.to_s puts str if num.prime? && str == str.reverse end (100..999).each do |num| put_palindromic_prime_number(num) end 問題点 コードは合っています。101 から 929 まで,15 個の回文素数が表示されます。 素数かどうかの判定は,自分でアルゴリズムを実装するより,このコードのように標準添付ライブラリーの prime を使うほうがいいですね。 回文かどうかの判定も str == str.reverse でいいでしょう。 また,機能の一部をメソッドに切り出したことも悪くないと思います。 まずいのは,メソッド内で puts している点です。 こういうコードを Qiita の記事で非常によく見かけます。 何がまずいのでしょうか。 つぶしが効かない このメソッドは柔軟性に欠けます。 標準出力でなくファイルに書き出したくなったらどうするのでしょうか? 回文素数ごとに改行するのではなく,空白で区切って表示したくなったら? そのたびにメソッドを書き換えるか,新設することになります。 一つのプログラムで複数の出力方法に対応したければ,メソッドをいくつも作るか,出力方法を指定する引数を設ける,といったことになります。 スジの悪いやり方です1。 一つのメソッドに, 回文素数かどうかを判定する機能 回文素数だった場合にそれを表示する機能 という異質なものを詰め込んだ設計が失敗なのでした。 前者は普遍的であり,したがって安定しています。 後者は普遍性があまりなく,上で見たように多様で変わりやすいものです。 テストしづらい 回文素数のような,判定が単純なものならまだいいのですが,もう少し複雑になってくると,アルゴリズムやその実装が本当に合っているか組織的に検証する必要があります。 そのためにソフトウエアテストを行います。プログラムでプログラムをテストするのです。 たとえば,101 や 121 を与えて,正しく動作するかどうかを検証するプログラムを書くのです。 しかし,我らが put_palindromic_prime_number メソッドは,テストに向いていません。 標準出力に何が表示されたかをプログラムで拾うのは面倒なのです。 改善 問題点が理解できたら,改善は容易ですね。 要するに,メソッドの役目を「回文素数かどうか判定する」ことに留めればいいのです。 require "prime" def palindromic_prime?(num) str = num.to_s num.prime? && str == str.reverse end (100..999).each do |num| puts num if palindromic_prime?(num) end 出力方式を変えたくなってもメソッドには手をつけなくてすみます。 また,この palindromic_prime? メソッドは容易にテストできます。 標準添付ライブラリーの test-unit を使うと,以下のようなテストコードが書けます2。 require "prime" require "test/unit" def palindromic_prime?(num) str = num.to_s num.prime? && str == str.reverse end class TestPalindromic_prime < Test::Unit::TestCase test "回文素数" do assert palindromic_prime?(2) assert palindromic_prime?(7) assert palindromic_prime?(101) assert palindromic_prime?(15451) end test "回文数だが素数でない" do refute palindromic_prime?(9) refute palindromic_prime?(22) refute palindromic_prime?(121) refute palindromic_prime?(12321) end test "素数だが回文数でない" do refute palindromic_prime?(13) refute palindromic_prime?(97) refute palindromic_prime?(1987) end test "回文数でも素数でもない" do refute palindromic_prime?(24) refute palindromic_prime?(9876) end end 簡単のためテスト対象とテストコードを一つのファイルにまとめて示しましたが,ふつうは別ファイルにします。 テストコードがしっかり書けていれば,メソッドをリファクタリングするときにバグの混入が防げます。 機能の一部をメソッドに括り出す際,「そのメソッドはテストしやすいか?」という観点も持つとよいでしょう。 引数によって出力方法を分けること自体は悪くありませんが,多様な用途に対応しようとすると設計が複雑になる恐れがあります。 ↩ 同じく標準添付ライブラリーの minitest を使っても,これと似たコードでテストできます。 ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rubocopまとめ

Rubocopとは Rubyのコーディングチェックツールです。 Rubocopを使うことで、誰でも一定の品質のコードを書くことができます。 一部のルールについては、自動修正にも対応しているため自分で修正する手間も省くことができます。 またRubocopではCopという単位でルールを管理しています。 導入方法 rubocopはgemのため、インストールします。 group :development do gem 'rubocop', require: false gem 'rubocop-rails', require: false end ここでrubocopはアプリ側で呼び出す必要がないため、require: falseをつけています。 ファイル .rubocop.yml Rubocopの設定ファイルです。 ここで、修正するcopを設定することができます。 .rubocop_todo.yml ここに今すぐ修正できないcopを退避させて置くことで、警告が出ないようになります。 (以下のコマンドのおかげ) .rubocop.yml inherit_from: .rubocop_todo.yml --auto-gen-configをつけることでcopを退避させることができます。 修正できたら消していって、徐々に解消できるようにしましょう。 使い方 カレントディレクトリの全てのRubyファイルをチェックする場合 $ rubocop 特定のファイルをチェックする場合 $ rubocop hoge.rb 自動修正して欲しい時 $ rubocop -a 参考 Rubocop公式(https://docs.rubocop.org/rubocop/1.23/index.html)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

フリーターからエンジニアになってみて

今回、「エンジニアになったきっかけ」に関しての記事の作成依頼があったため、記事を書かせて頂こうと思います! 「自己紹介」 「エンジニアになろうと思ったきっかけ」 「エンジニアとして働いてみた感想」 「今後はどんなエンジニアを目指したいか」 という項目で記事を書かせてもらいます。 自己紹介 2019年3月に慶応義塾大学環境情報学部を卒業し、2019年4月からポテパンキャンプというプログラミングスクールで、RORを勉強し、2020年1月からWebエンジニアとして働いています。そのため、今はエンジニア2年目となります! 主な業務としては、ECの基幹システムの内製化や新規機能の要件定義・仕様策定・実装等を担当しています。 新しい人が入ってきた際は、育成等も担当したりしています。 また、ご縁があり、つい先日から副業も始めさせて頂きました! 副業の方は、まだjoinさせて頂いて1ヶ月も経たないような状態で、1日でも早く力にならなくてはと思い、日々開発させて頂いております! エンジニアになろうと思ったきっかけ 大学4年時に、企画から実装までを3人一組のメンバと共に実装するというものがありました。 その時、私はプランナーとしてjoinさせて頂き、初めて自分が企画したものが形になりました。 嬉しい気持ちの反面、もっとプロダクトの作成に関わっていきたいという気持ちが強くなりました。 この時、私は、エンジニアになる事を決意しました。 私は、プロダクトにエンジニアとして関わり、プロダクトをグロースさせていく事やユーザーにとって良いものとは何なのかという事を考え、実装していく事がやりたいと思いました。 そのため、自社開発企業でエンジニアとして働きたいと考え、行動に移していきました! エンジニアとして働いてみた感想 コーディングするという事に関しては、意外となんとかなった所が「エンジニアとして働いてみて」最も意外な点でした。 難しい内容をいきなり振られるという事はまずないですし、ある程度コーディングができれば、「未経験での入社」としてはいいのではないかと思います。 ※学習を継続していく事は必須ですし、入社してからどんどん吸収していく姿勢というものは必要になってきます。 そして、私が最も苦労した点としては、「お作法的な部分」です。 変数・メソッド等の命名、冗長な処理の添削等、実装とは直接的には関係ないが、綺麗なコードを書くために必要な事の習得が最も苦労しました。。。 ※今も習得出来てはいない。。。 「細かい所に意識を向ける」というのは、エンジニアとして最も必要な素養のように最近感じています。 これができれば、「お作法的な部分」で、レビューで指摘される事も減るのではないのかなと思います。 私自身、もともと大雑把な性格であった事もあり、細かい所に意識を向けるという事が苦手です。 しかし、エンジニアとして働いていく中で、少しずつですが、細かい所に意識を向け、気づく事ができるようになってきていると思います。 今後のエンジニア人生においても、大きな課題になってくる事は間違いないかなと思います。 エンジニアになる前から、意識をし、生活においても細かい所に意識を配るなど、できる事は多々あったと思います。今からエンジニアを目指すのであれば、コーディングだけではなく、そのような所も意識してみると良いかもしれないですね。 今後はどんなエンジニアを目指したいか 「自分の作りたいものが作れるエンジニア」です。 こういうものが作りたいと思った時に、パパッと作成し、世の中に出す事ができるようになれると良いなと考えています!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby のまずいコード】ID として可能な文字列か判定

お題 あるシステムでは,ログインに使う ID をユーザーが自分で決めることになっています。 ただし,その ID は以下の条件をすべて満たさなければなりません。 ASCII の範囲の英数字(アルファベットと数字)のみからなる 8 文字以上,12 文字以内 では,引数として与えられた文字列が ID として認められるものかどうかを true/false で返すメソッドを書いてください。 ※文字列処理の練習問題なので,既存の ID と重複していないかは考えなくてよいことにします。 なお,「ASCII の範囲の」と書いたのは,要するに全角の「G」とか「7」とかは認めない,ということです。 以下では,記述を簡潔にするために「ASCII の範囲の英数字」を単に「英数字」と略して書くことにします。 コード コード 1 def valid_id?(str) str.match?(/[a-zA-Z\d]{8,12}/) end コード 2 def valid_id?(str) str.match?(/^[a-zA-Z\d]{8,12}$/) end 問題点 コード 1 も 2 も間違っています。どちらもよく見かける間違いです。 コード 1 コード 1 で使われている正規表現は,「英数字列」を表す文字クラス [a-zA-Z\d] の書き方も,「8 回以上,12 回以下の繰り返し」を表す量指定子 {8,12} の書き方も合っています。 この正規表現は確かに「8 文字以上,12 文字以下の英数字列」を意味するのです。 しかし,String#match? の動作を誤解しています。 このメソッドは「文字列の中に,正規表現にマッチする部分文字列が存在するか」を返すものです。 ただし,「部分文字列」といっても,全体の場合もあります1。日常語では「部分」といえば全体より小さいものですが,数学における部分集合などと同様に,全体と一致する場合も含めて考えます。 したがって,「8 文字以上,12 文字以下の英数字列」を含んでさえいれば true を返してしまうのです: p "あABCDEFGHう".match?(/[a-zA-Z\d]{8,12}/) # => true これでは役に立ちません。 なお,String#match? の代わりに String#match を使うと返り値が「MatchData オブジェクトまたは nil」となりますが,その点を除いて同様の結果になります: p "あABCDEFGHう".match(/[a-zA-Z\d]{8,12}/) # => #<MatchData "ABCDEFGH"> それから,String#=~ に変えると返り値が「見つかった部分文字列の開始位置または nil」になりますが,やはりその点を除いて同様の結果になります: p "あABCDEFGHう" =~ /[a-zA-Z\d]{8,12}/ # => 1 さらに,文字列と正規表現をひっくり返しても同様です: p /[a-zA-Z\d]{8,12}/.match?("あABCDEFGHう") # => true p /[a-zA-Z\d]{8,12}/.match("あABCDEFGHう") # => #<MatchData "ABCDEFGH"> p /[a-zA-Z\d]{8,12}/ =~ "あABCDEFGHう" # => 1 似たようなメソッドがいくつもあるわけですが,この記事のお題のように,「正規表現にマッチする部分文字列の有無だけ」が知りたい場合2,match? を用いるのが定石です。高速でメモリー消費が少なく,$& などの値を変更しないからです。 コード 2 コード 2 は上記のような失敗を避けようと,アンカーを使っています。 正規表現のアンカー(anchor,錨いかり)とは,平たく言えば位置を指定するものの総称です。 コード 2 を再掲します: def valid_id?(str) str.match?(/^[a-zA-Z\d]{8,12}$/) end コード 1 との違いは,^ と $ という二種類のアンカーを置いたことです。 この正規表現を書いた人は,「文字列の先頭から『8 文字以上,12 文字以下の英数字列』が続き,そのあとが文字列末尾になっている」というつもりだったのでしょう。 この正規表現がそういう意味なのであれば合っています。match? が部分文字列の存在を確認するものだといっても,両端をアンカーで押さえているので,全体にマッチするかどこにもマッチしないかのどちらかだからです。 しかし,残念ながら ^ と $ は文字列の先頭・末尾を意味しません。よく誤解されるところです。 ^ は文字列の先頭ではなく「行頭」です。 $ は文字列の末尾ではなく「行末」です。 そのため,以下のようなことが起こります。 p "あ\nABCDEFGH\nう".match?(/^[a-zA-Z\d]{8,12}$/) # => true 要するに A の前が行頭,H のあとが行末になっているわけですね。 なお,正規表現における行頭・行末は正規表現エンジンによって微妙に仕様が異なります。Ruby の正規表現がある程度ちゃんと分かっている人の中でも,^ と $ を完璧に把握している人は少ないのではないかと思います。私は完璧に把握してないほうの人です(すぐ忘れる)。 この点に興味のある方は以下の拙記事をどうぞ。 Rubyの行末 - Qiita 改善 改善というよりバグフィクスとなります。 コード 2 は,使うアンカーが間違っていただけで,考え方は合っていました。 正しい「文字列先頭」「文字列末尾」のアンカーはそれぞれ \A,\z です(A が大文字であるのに対し z が小文字であることに注意!)。 よって,正しいコードは def valid_id?(str) str.match?(/\A[a-zA-Z\d]{8,12}\z/) end となります。 Ruby の正規表現の仕様は公式リファレンスで確認しましょう。 正規表現 (Ruby 3.0.0 リファレンスマニュアル) アンカーについては アンカー の節を。 余談 JavaScript の正規表現では,^ と $ はそれぞれ文字列の先頭・末尾を意味します。 参考:言明 - JavaScript | MDN そういう意味では Ruby の \A と \z に相当します。 ただし,/ /m のように m オプションを付けると,行頭・行末になります。 ここで Rubyist が気をつけなければならないのは,Ruby にも m オプションがあるものの,JavaScript のそれとは全く意味が違う,ということです。 Ruby の m オプションはメタ文字 . の意味を変えるものです。m を付けないと . は改行にマッチしませんが,付けるとマッチします。 どちらの言語の m オプションも multiline の頭文字を取ったようです。ややこしい。 また,「部分文字列」は長さ 0 の文字列(つまり空文字列)の場合もあります。/^/ という正規表現は「行頭にある空文字列」という部分文字列にマッチします。 ↩ つまり,見出した部分文字列の位置とかキャプチャー文字列などが必要ない場合。 ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby 多重継承 Mix-in

はじめに pythonからrubyに移植する話がありまして、ソースを見ていたところpythonに多重継承がありました。 どうしたものか。 競技プログラミング atcoder さんには大変お世話になっているものの、classどころかdefもほとんど書きませんので、クラス・モジュール・継承となると再勉強が必要。 Ruby Gold も使わなければ忘れるだけですね。 Perl to Ruby ところで、PerlユーザーのためのRuby入門 という本がございまして、例によって20年位前の本になりますが、第5章に5-2 Perl多重継承v.s. Ruby Mix-inという興味深い記載が載っておりました。 class Staff def initialize(hash) p :Staff_initialize @name = hash[:name] end end module TradeStaff def initialize(hash) p :TradeStaff_initialize super(hash) @sales = hash[:sales] @trade_skill = 10 end end module AdminStaff def initialize(hash) p :AdminStaff_initialize super(hash) @rooms = hash[:rooms] @admin_skill = 10 end end class TradeAdminStaff < Staff include TradeStaff include AdminStaff def initialize(hash) p :TradeAdminStaff_initialize super(hash) end end p staff = TradeAdminStaff.new( :name => "Tom", :sales => 13000, :rooms => ["room_001", "room_003"]) p staff = TradeAdminStaff.ancestors [TradeAdminStaff, AdminStaff, TradeStaff, Staff, Object, Kernel, BasicObject] ancestorsすると継承リストが見られますが、superでひとつ前の継承されたメソッドが呼ばれることに少し感動しました。 まとめ 少し感動した ゆくRuby くRuby
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Macにおけるファイルエンコーディングの確認方法

はじめに プロを目指す人にためのRuby入門に取り組んでいたところ、ファイルエンコーディングを確認する機会があったため、忘れないようにメモとして残しておこうと思います。 ファイルエンコーディングの確認方法 ファイルエンコーディングを確認する際はfileコマンドを使用します。--mime-encodingをオプションとして加えることによって、ファイルエンコーディングのみ出力されます。 コンソール file --mime-encoding sample.rb sample.rb: utf-8 出力結果から、ファイルエンコーディングはUTF-8だとわかりました。 UTF-8 (文字コードとファイルエンコーディングの違いで混乱した時に読んだ記事です)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】目的地の日没時刻がわかるだけのシンプルなアプリを作った

はじめに タイトル通り、目的地の日没時刻がわかるだけのシンプルなアプリを作りました。 シンプルマジックアワーというアプリです。 開発の過程などを記していきます。 アプリの説明 日付と都市を選択すると日没の時刻を表示します。 それだけだとあまりに味気なかったので、マジックアワーの時刻も付け足しました。 なぜ作ろうと思ったか 一眼レフカメラで夕焼けの写真を撮るのが趣味なのですが、綺麗な夕焼けを撮るには日没の時間を知っておく必要があります。 日没の時間が分かるアプリはごまんとあるのですが、その多くは日没時刻以外の情報もたくさん表示されます。(日の出の時刻や太陽の位置など) また、地点についても詳細な位置を取得するためにGoogleマップを利用したり、とにかく選択肢が多かったりします。 日没時間だけを知りたい私にとってはこうした情報は必要ではなく、地点の選択肢も最小限だけあれば足りると考えました。 そこで練習も兼ねて、自分にとって使いやすいシンプルなアプリを作ろうと思い立ちました。 シンプルにこだわる とにかくシンプルで分かりやすいアプリを目指しました。 はじめはGoogleマップのAPIを使って詳細な位置を取得しようと考えましたが、 操作数が多くなる点や、画面の大部分を地図が占めてしまう点を考慮してセレクトボックスにしました。 都市の選択肢についても、全国天気予報の地点を参考に最小限にとどめ、選びやすさを意識しました。 デザインに関しても、紺を基調としたシンプルなデザインにしました。 初期のデザインはとにかく単調で白と黒しか使っていませんでしたが、友人たちから「夕焼けをイメージしたデザインの方がいい」とのアドバイスを受け、己のセンスのなさを一通り痛感したのちにすぐ修正しました。 主にスマホで利用することを想定しているので、小さな画面でもはっきり見えるように情報量を制限しました。 また、スクショした時に日時と都市、時刻といった必要な情報が一つの画面に収まるようにデザインしました。 使用した技術 Rails 5.2.6 Heroku CloudFlare 日没時刻の取得はAPIおはこん番地は!?を使用。 都市の緯度経度はGeocoderというgemを使用。 コントローラ def sunset_time # 入力された値を分かりやすいようにそれぞれ変数へ year = params["date(1i)"].to_i month = params["date(2i)"].to_i day = params["date(3i)"].to_i # 都市名から緯度経度を取得して変数へ geocode = Geocoder.search(params[:city]) lat = geocode.first.coordinates[0] lng = geocode.first.coordinates[1] # それぞれの値をURIの形式に変換し、変数rise_set_paramsへ @rise_set_params= URI.encode_www_form( { mode: "sun_moon_rise_set", year: year, month: month, day: day, lat: lat, lng: lng } ) # APIを叩き、結果を受け取り変数へ rise_set_uri = URI.parse("https://labs.bitmeister.jp/ohakon/json/?#{@rise_set_params}") rise_set_json = Net::HTTP.get_response(rise_set_uri) rise_set_result = JSON.parse(rise_set_json.body @sunset_hm = rise_set_result["rise_and_set"]["sunset_hm"] end デプロイ Herokuを使ってデプロイしました。 Herokuを選んだ理由は、とにかく簡単にデプロイできるからです。 AWSという選択肢もありましたが、すでに他のアプリで使っており、EC2の稼働時間が無料枠の上限を超えてしまうため却下となりました。 また、せっかくなのでお名前.comで独自ドメインを取得しました。 ちょうどアプリ名のドメインに空きがあって良かったのですが、次からは先にドメインを決めておいたほうが良さそうです。 Googleサーチコンソールに登録 デプロイできたので意気揚々に検索をしても、アプリが出てきませんでした。 色々調べるとURLがGoogleに登録されていなかったみたいです。 この辺りはこちらの記事で解説しています。 おわりに これが2作目のアプリ開発でしたが、よかった点と改善すべき点がありました。 よかった点 「シンプルな日没時間がわかるアプリ」というコンセプトを明確にしていたことです。 これによって寄り道しすぎず、集中して開発することができました。 学習ではなく利用を目的に開発できたのもよかったです。 1作目のアプリはかなりポートフォリオ的で、学習を目的に開発していました。 Railsの基本は学べましたが、結果的に「本当に利用してもらえるのか」が不明なアプリでした。 今作はあくまで「利用してもらうこと」が目的だったので、違った目線で開発できたのはいい経験になりました。 ユーザーに投稿してもらってはじめて価値が出るアプリではなく、Webツール型のアプリなので一定の需要はあるのではと思います。 マネタイズについても期待していましたが、シンプルすぎるのかGoogleアドセンスの審査になかなか通りません。 改善すべき点 シンプルすぎる機能には改善の余地があると考えます。 例えば太陽の高度を表示できる機能や、日没時間をツイートできる機能があればもっと使いやすいと思います。 開発過程にも改善すべき点があったと思います。 出勤前の時間を使って開発していましたが、前日に30分かけて作ったデザインを翌日に1時間かけて修正するといった、大変非効率な事態がたびたび起きていました。 原因は、明確な期限を設定していなかったことにあったと思います。 色々遠回りもしましたが、自分が使いたいアプリを作れたのはとても楽しい経験でした。 また何か作ろうと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ruby biz Grand prix 2021のファイナリストに選ばれた

Catallaxy Advent Calendar 1日目を担当します、エンジニア1号です。 Ruby biz Grand prix 2021(Ruby bizグランプリ2021)へエントリーして、ファイナリストに選ばれましたので、今日はそのことに触れてみたいと思います。 Catallaxyとは 金属加工プラットフォームを提供する2015年創業スタートアップになります。2018年に現在の業態にピボットしたのち、2021年3月にはシリーズAとして約4.1億円を調達しており、現在までに累計約8億円の資金調達をしております。従業員数26名のうち、エンジニア10名、デザイナー1名、エンジニアの業務委託・インターン数名のメンバー構成になっており(2021年9月応募時点)、約半数がプロダクトに関わる業務に携わっています。 Ruby biz Grand prix 2015年からRuby bizグランプリ実行委員会が開催するRubyを活用したビジネスを表彰するもので、『Rubyを使った自社商品・サービスなどで、Rubyの特徴を活かし、「新規性」「独創性」「市場性」「将来性」に富んでおり、今後継続的に発展が期待できるビジネス事例』として、当社は金属加工プラットフォームMitsuriとその周辺プロダクトで応募しました。 過去多くのpre-IPO/post-IPOのスタートアップが受賞されていますので、その名誉ある賞を受賞したい。その一心で応募しました。 応募までのみちのり 要綱に書かれた通り、Wordベースの所定応募書式があり、そのページ数は10ページに及びました。それ以外に補足資料として追加提出できました。 Ruby 100%でRuby biz Grand prixの存在を知っているメンバーはいましたが、会社としてこのグランプリに応募するかは検討委員会を立ち上げて検討を進めました。デイリーで組織全体のことを話すようにしているため、応募するかどうかの検討するまでの意思決定は即座にできたようです。 今回の2021が初めての応募だったのですが、実は主催事務局から2020年にも郵送で案内いただいていました。その際は社内のエンジニアリソースが枯渇しており、応募に向けて進められることはなかったようです。 COVID-19の影響で2020年4月からフルリモートとなっていた当社ではエンジニアは全員リモートワークしており、気付いた人がSlackに写真を上げた時の社内のリアクションです。 書類の記載 A4 10枚にもわたる所定の応募書式を埋めていく作業は大変でした。特に、アーキテクチャ図や、株主・株主候補以外に開示するビジネスの指標はまだ整っておらず、ビジネスの指標に至っては収集・整理・開示確認を行う必要がありました。 技術面の十分な深さを説明するだけでなく、Rubyをはじめとする技術を利用してビジネスとして成り立たせることをも説明的に記載する必要があり、緊張のある取り組みでしたが、時間的な制約も多く、集中して取り組めたのはよかったかなと思います。 技術的な深堀 今日の記事ではRuby biz Grand prix 2021への応募そのものについて記述しましたが、やはりRubyを含めた技術が他社の応募との差別化要因と理解しています。そのあたりもCatallaxy Advent Calendar 2021の中で他の執筆者が触れていってもらえるといいなぁと期待しています。 最終結果 RubyWorld Conference 2021に併設されて行われる、12月15日の表彰式でなんらかの賞にCatallaxyが表彰されるかもしれません。受賞した際はCatallaxy Advent Calendarでもお知らせしますので、定期的にチェックいただければと思います。 未来の工場をつくるCatallaxyではRubyを含む幅広い技術経験のあるエンジニア採用を強化しております。 https://open.talentio.com/r/1/c/catallaxy/homes/2947
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【オブジェクト指向】コンストラクタ

コンストラクタとは Rubyのようなオブジェクト指向のプログラミング言語で使われる機能の1つで、オブジェクトを生成した際に1度だけ実行される機能を指す名称。 initialize という名前のメソッドは自動的に private に設定される。 initialize 「new」メソッドが実行された際に自動的に呼び出される class Sample def initialize p '初期化処理' end end s = Sample.new "初期化処理" => #<Sample:0x0000557ab2005168> インスタンスを生成するnewメソッドで引数を指定することで、その値をインスタンス変数に設定することが可能 class Sample def initialize(name) @name = name end def execute() p @name + ' hello' end end sample1 = Sample.new('kato') => #<Sample:0x0000557ab2595ec0 @name="kato"> sample2 = Sample.new('takagi') => #<Sample:0x0000557ab25bd740 @name="takagi"> sample1.execute => "kato hello" sample2.execute => "takagi hello" initializeを実行しない場合はクラスをnewして、インスタンスメソッドへ引数を引き渡してという処理を、各処理毎に毎回設定しなければいけない。 class Sample def name=(name) @name = name end def hello p @name + ' hello' end end s = Sample.new s.name = 'kato' p s.execute => "kato hello" 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

BioconductorのAnnotationDbiパッケージの中身のsqliteデータベース取り出してをRubyなど他の言語で利用することを考える

はじめに  生命科学のコンピュータによる解析では、R言語が広く使われています。Bioconductorプロジェクトが、品質の高いパッケージ群を支えています。Bioconductorでは、基本的なデータ構造について共通のものを利用することで、一貫したシステムを作り上げています。たとえば、ゲノム範囲を扱うパッケージでGenomicRangesというものがあり、これがBioconductorで最も利用されるパッケージの一つになっています。しかし、他の言語でバイオインフォマティックスを行おうと考えている場合、こういった基盤となるパッケージやライブラリが存在しなくて苦労することがあります。 Bioconductor Top75 - もっとも利用されているパッケージ75種類。  Bioconductorを構成するパッケージの中にはデータベースを扱うカテゴリーがあります。これらはAnnotationDataという分類になっています。 AnnotationDbi  R言語のことはあまりよくわかっていないので詳しく調査できていませんが、これらのデータベースを扱うパッケージはAnnotationDbiに依存しています。ここでは一例としてorg.Hs.eg.dbを他の言語(ここではRuby言語)から利用することを考えていきます。 org.Hs.eg.dbの中にはsqlite形式のファイルが梱包されている まず、パッケージをBioconductorのページからダウンロードします。ページの一番最後にリンクがあります。 これらを展開します。すると、 . ├── DESCRIPTION ├── inst │ └── extdata │ └── org.Hs.eg.sqlite ├── man │ ├── org.Hs.eg_dbconn.Rd --中略--- ├── NAMESPACE ├── R │ └── zzz.R └── tests ├── runalltests.R └── unit └── test.R 薄い階層のディレクトリに少数のファイルしかありません。(manはマニュアルですので一旦は無視して良いでしょう。)  ここで注目するべきは、inst/extdata/org.Hs.eg.sqlite です。つまりsqlite形式のデータベースが、直接パッケージの中に組み込まれているのです。sqliteは軽量データベースであり、プログラミング言語には依存しません。そのため、このsqlite形式のデータベースをR以外の言語で呼び出すことによって、他の言語でもR言語の利便性を享受することができそうです。  注意が必要なのはライセンスです。プログラムのライセンスはArtistic-2.0となっています。Artistic-2.0というのはPerl界隈でよく使われるライセンスのようで、GPLに近いライセンスとのことです。しかし、これがデータベースにおいても適応されるものなのかはよくわかりませんでした。道義的には、Bioconductorのチームの方がコストをかけてメンテナンスしているものを、おいそれと他の言語のパッケージに組み込んで配布することははばかられる気がします。たとえば、PythonでBioconductorのsqlite形式のファイルを転用するパッケージがないか探してみましたが、Githubを適当なキーワードで検索した程度では見つかりませんでした。なので、現時点では、あくまで個人でR言語のパッケージを解凍して、その中のsqlite形式のファイルの利用するにとどめた方がよいかもしれません。 RubyからSqlite形式のファイルを呼び出す  さて、データベースを呼び出して、オブジェクトとして利用するのはRuby言語の得意分野であると言われています。Active Recoredが有名です。私は使い方をよく知らないのですが、設定をせずにすぐに利用するためにはActive Recordは規約に従ったsqlite形式のファイルを使う必要があったような気がしました。Rのsqlite形式のファイルは必ずしもRailsの規約に従っているわけではないと思うし、こういったデータベースの利用は主に読み込み専用で、自分でレコードを追加することはまずないと思うので、Active RecoredではなくSequelを利用します。Sequelは、Rubyのコミッターとしても高名なJeremy Evansさんの作成しているRuby向けのデータベースツールキットです。 次のようにしてSqlite形式のファイルを、読み込んで、検索することができます。 require 'sequal' db = Sequel.sqlite('org.Hs.eg.sqlite') db.class # Sequel::SQLite::Database db.tables # テーブル一覧が表示される db[:alias].first # => {:_id=>1, :alias_symbol=>"A1B"} db[:alias].take(10) db[:alias].where(alias_symbol: "HBA1").all # => [{:_id=>2473, :alias_symbol=>"HBA1"}] db[:alias].join(:gene_info, _id: :_id).where(alias_symbol: "HBA1").first # {:_id=>2473, # :alias_symbol=>"HBA1", # :gene_name=>"hemoglobin subunit alpha 1", # :symbol=>"HBA1"} db[:alias].join(:genes, _id: :_id).where(alias_symbol: "HBA1").all # => [{:_id=>2473, :alias_symbol=>"HBA1", :gene_id=>"3039"}] ご覧のように非常にシンプルな記法でやりたいことが実現できそうです。 遺伝子IDの変換 たとえば、遺伝子IDの変換のようなことはjoin構文を使えば比較的簡単に行うことができます。 entrez_id = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] entrez_id.map do |id| db[:genes].join(:ensembl, _id: :_id).where(gene_id: id).all end # => # [[{:_id=>1, :gene_id=>"1", :ensembl_id=>"ENSG00000121410"}], # [{:_id=>2, :gene_id=>"2", :ensembl_id=>"ENSG00000175899"}], # [{:_id=>3, :gene_id=>"3", :ensembl_id=>"ENSG00000256069"}], # [], # [], # [], # [], # [], # [{:_id=>4, :gene_id=>"9", :ensembl_id=>"ENSG00000171428"}], # [{:_id=>5, :gene_id=>"10", :ensembl_id=>"ENSG00000156006"}]] 少々冗長(_id: :_id のあたり)な気もしますが、Ruby言語に慣れた人にとっては許容できる範囲だと思います。(Sequelはバイオインフォ用のライブラリではなく、汎用のツールなので仕方がないと思います。) しかし、上のようなことを必要になる都度行うのは面倒なので、配布用ではなく、自分用にGem化してみることにしました。 (その結果、sqliteを含むRubyのGEMの作成には非常に時間がかかることが判明しました。理由は調査できていません。) Ruby以外の言語でもできるはず… 上記のようにRuby言語で、RのBioconductorのパッケージを利用しましたが、Sqlite形式のファイルはRuby言語ではなく他の言語でも利用できるはずです。なので、バイオインフォマティックス用のパッケージが発達していないマイナーな言語でバイオインフォマティックスをやろうとしている方がいましたら、参考になるはずです。ただし、ライセンスの問題には十分注意する必要があります。 この記事は以上です。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Rails】モデルとテーブルの関係について【初学者の疑問点を】【本当に簡潔に】

はじめに  本記事は、Railsの学習を始めて1ヶ月の初学者が、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。  そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。  間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。 今回の疑問点  今回の疑問点は、   ・モデルとテーブルの関係    です。   現在、Twitterクローンを作成しており、フォロー/フォロワー機能の実装の際にアソシエーションの上記について疑問を抱きました。   疑問点についての解説 モデルとテーブルの関係について 結論:  モデルとは  モデルとは、コントローラとテーブルとの繋ぎ役です。コントローラから指示を受けてデータベースとの間で情報のやり取りを行います。簡単に表すと以下の通りです。      コントローラ ⇄ モデル ⇄ データーベース       データベースとは  データーベースとは、データを格納する保存先です。さまざまなデータを整理して格納したテーブルが複数保管されています。           テーブルについて  テーブルには、データを整理するために、表計算ソフトのような表形式でデータが格納されています。  データベースとテーブルの関係は以下の通りです。    データベース        ・テーブルa       ・テーブルb       ・テーブルc          :                     
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む