Rubyの問題集に触れるということ / 解法も知識
※今回の問題に対する完成コードはこのページにありません。
こんばんは、NUKEDOです。
オリジナルアプリの新実装はまだひと段落ついていないため
本日も朝にやったドリルについて書いていきます。
今朝の問題は自力での解答を探した結果、
問題集は問題集で重要だという結論になりました。
本日のRubyドリルの問題は
「数字のみで構成された配列内から、指定された数字を特定の方法で検索しろ!」
というものでした。その特定の方法がバイナリーサーチと呼ばれるもので、
与えられた配列が数が小さい順に並んでいるので
配列の中心を見る→その数字との大小関係を見てどちら側にあるかを確認
→存在する側の中心を見て、またどちら側にあるかを確認→…
と繰り返すことでどこにあるかを確認しろというものです。
例を挙げると
[1,3,5,7,9,11,13]から「6」を探せ!
→真ん中は7だからそれより小さい6は左側にある! →[1,3,5]の真ん中を見る
→真ん中は3だから右側にある! →[5]の真ん中は5だから右側にある!
→もう配列がない=存在しない!
という探し方です。
15分ほどで解く問題ですが2時間かけても自力では解けませんでした。
スクールの模範解答を載せることは規約違反になるので省略させていただきます。
自力で解こうとした結果、結局未完成のコードがこちら↓(クリックで拡大)
全体的に読みにくく、特にbinary_searchメソッド内else以下の
21行目以降の部分がグチャグチャですし、
自分でも書いていてわけがわからなくなりました。
これは模範解答でも結構長めのコードでしたが、そちらは読んで意味がわかるので
明らかに自分の書いたものより優れたコードです。
今回言いたいことはいろんな書き方を模索しようということです。
自分のやり方は決して難解な方法ではないんです。
ただ、無理に変数だけで表現してるせいで
すごく読みにくく確認しにくい書き方になってしまっているんです。
例えば、真ん中の数字を見た後にnew_arrayとして左側もしくは右側の該当部分を
新配列として作成して、binary_search(new_array, num)として渡す形に
直すだけで非常に見やすくなるはずです。
そして模範解答はwhile文を用いておりcenter以外に右端左端用の変数を用意しており
配列内にある場合には何番目かを、配列内にない場合には判別用の変数を-1にして返す
というものでした。
やり方を知れば「なんだそれでいいのか」で使えますが、
知らないといつまでも難解な書き方を繰り返すことになるかもしれません。
「ドリルを解いても実力は上がらない」といったことを書いてあるサイトはありますが
知ってるか知らないかで差がつくことは間違いなくあると思います。
また自分は2時間かけて解けずに諦めましたが、
やり方を変えていればもっと早く解けたものだと考えます。
コードの書き方は1つではないので、あるやり方で詰まったなら別の方法を
試してみることにします。
そういうことを考えさせられる2時間でした。
uniqメソッド /車輪の再発明
こんばんは、NUKEDOです。
本日解いたドリルの問題について書こうと思ったのですが
「これそのまま載せるとカリキュラムを転載した扱いになって
スクールの規約違反になるのでは?」
と思ったので、ツイッターで流れてきたメソッド紹介と自分なりのドリル解答、
紹介したメソッドを自分で作ったらどうなるかを書いていこうと思います。
uniqメソッド
Array#uniq (Ruby 2.7.0 リファレンスマニュアル)
配列内で重複してる部分を取り除いた新しい配列を作成するメソッドです。
例を挙げると、
ary = [1, 2, 2, 3, 5, 3]
puts ary.uniq # => [1, 2, 3, 5]
となります。
あれ、このメソッド今日のドリルに使えなくないか?今日のドリルで出た問題は、
「配列内でかぶった数字を除いて合計値を出せ」って問題だったんですが。
同じスクールに同日入校した人がドリル終了のタイミングで
ツイートしてたんで、てっきり使って解答できるのかと思ったんですけど…
まあそれはさておき。
今日の問題を上記の配列で計算すると、2と3はかぶってるので、
1+5で6が出力されることになりますね。
今日の問題の自分の回答がこちら↓
ちょっと冗長だしわかりにくいと思ったので補足コメントも書きました。
ループ文内にループ文が作られているので、リファクタリングして
もっと見やすくするべきですかね。
カリキュラムの模範解答では、aryの要素を一つ取り出し、
ary配列内の全てと比較して2回以上出現していなければchecked配列内に格納する
という書き方でした。
続いてuniqメソッドを自分なりに作って見た場合の解答がこちらになります↓
こちらはドリルの模範解答を参考にしつつ作成しました。
(21行目の線はカーソルです)
書いていて気になったのはbreakでどこまで抜けてしまうのか、ですね。
ループ分から脱出するよう記述しましたが、if文が多いためわかりにくいですね。
7から17行目までを別メソッドにしたほうが読みやすいかもしれません。
もっといい作成方法もあるのかも?
自力でメソッドを作るのはそこそこ考えました。
メソッドを知っていればこんな必要はないので、知識を増やしていきたいと思います。
Rubyの検定試験というものがあるので、そちらを勉強していけば
自然と増えていくのでしょうか?
就職にも有利になりますし資格勉強もしていくつもりです。
参考
rakeって何だ?/ 情報ソースの作成日に気をつけよう
結論だけ言うと、
Ruby on Rails 5.0以降ではもう使わない古いコマンドで、
railsコマンドだと思えばオッケーです。
こんにちは、NUKEDOです。
就職が不安でここのところ集中力がなく、考えた結果
「自分の知識を増やしまくるしかない」との結論に至りました。
Rubyもまだまだ未熟なんですが、他言語も少しずつ覚えていこうと思います 。
増やしまくるための近道として「先達に学ぶ」べきだと思い、
ツイッターでいろんなエンジニアをガンガンフォローすることにしたんですが
その中に気になるツイートがあったので確認しました。
Qiita記事書きました。「その情報、とっくの昔に変わりましたよ?」と言われないように、いつでも公式の情報源を参照しましょう〜。
— Junichi Ito (伊藤淳一) (@jnchito) November 14, 2020
【初心者必見】RailsアプリをHerokuに公開するのにrails_12factorは不要 https://t.co/H55T4q5nRI #Qiita
要約すると
「古い記事はバージョンが違って役に立たなかったり
間違ったコードによって逆にセキュリティの穴になったりするから
日本語の古い記事より英語の最近の記事を確認しろ!」
ということでした。
そこで思い出したのがrakeコマンド。
そういえばrakeコマンドってカリキュラムでは見ないけどqiitaではよく見るなと思い
調べてみることにしました。
調べた結果出てきた公式情報がこちらです。
そもそもrakeコマンドもrailsコマンドも特定の物を作成するときに使うコマンド
なのですが、作成するものによって使い分けられていたみたいです。
rake db:migrateとか、rails db:migrateでしか見ませんもんね。
Rails6どころか5になった頃に使わなくなったコマンドです。
ちなみにqiita内をrakeで検索すると
普通に2020年作成の記事で説明に使われているものを見かけます。
Rails4向けの可能性もありますが、古い情報を参照して学んだ可能性が高いです。
なのでそういった記事は、説明されている文章は参考にしつつ、
説明されているコマンドなどについて別のソースを探す必要がありますね。
検索力も鍛えようという学びでした。
参考
FactoryBotのbuildとcreateの違い
先週ブログを開始してから予想通りというか見事にブログを更新しなかったので
本日より毎日ブログを書いていきます。
FactoryBotについて調べると、インスタンスの作成方法が
カリキュラムではbuildだけど説明サイトではcreateになっていることが多い。
「調べたやり方が実はcreateの場合でしかできなかったらどうしよう」
と思い調べました。
buildの場合はメモリ上にデータを保存し、データベースに保存されない。
なので基本的にはこちらを利用する。
みんながDBにアクセスすると処理が重くなるし、テストデータがDBに残ってしまう。
createの場合はデータベースに保存される。
これはメールアドレスのように一意性があるかどうかをテストしたい時や
保存したデータの個数を数える時などに使う。
しかし調べているうちに気になる記述を発見。
「buildはDB保存しないがアソシエーションはDB保存する」
アソシエーションを保存しない build_stubbedというメソッドも存在することを確認。
buildでググってもアソシエーションについて出てこないので
build_stubbedを用いて検索。
すると
FactoryGirlのbuildとbuild_stubbedって何が違うの? - Qiita
にて、各処理にて何が作成されるのかを確認。ありがたい。
buildするモデルにアソシエーションでUserモデルなどが存在してる時、
buildの場合はアソシエーション先のUserのインスタンスが作成されて保存されてる
という情報。
buildだとアソシエーションがあった場合にDBにアクセスしちゃうんですね。
これを防ぎたい場合にはbuild_stubbedを使う。
勉強になりました。
参考
ブログ開設のあいさつ
TechCamp86期生、30代後半。
2020年9月からプログラミングエンジニアの勉強を始めました。
目指せ年収1千万プレイヤー!
でなれるなら皆がなってるところです。
TechCampに申し込み、受講開始まで約50日ありましたが
まともに勉強したのは実働2日程度です。
プログラミングスクールに入っていなければ全く勉強しないままだったでしょう。
入って本当に良かったです。
TechCampに入ってライフコーチのアドバイスを受けてからは工夫し、
スクール開始前や終了後に勉強するようになり、
土曜日にも平日並みに勉強するようになりました。
日曜日は遊ばせてください。
このブログはエラーに関する備忘録も兼ねてますが、
エラーはQiitaに投稿するようにした方が
同じようなエラーを起こした方の助けになると思うので、
基本的にエラーとその解決方法に関してはQiitaに投稿し、
こちらは自身のTwitterやQiitaの引用をしながら
新しく知ったコーディングの技術やエラーの発生前後の状況を書いたり、
ふつーのブログみたいにコーディングと関係ない
普段思ったことを書いていこうと思います。
似たようなアウトプットに使ってるサイトを載せときます。
Qiita→ https://qiita.com/NUKEDO
余分な情報や冗談まじりや口語体のQiitaは読む方のストレスになるんですね。
「こちとらエラーで苦しんでるんだ!冗談はいいから情報をくれ!」状態です。
なのでQiitaは情報を書くだけの場です。
ツイッター→ https://twitter.com/Techcamp861
アウトプットのメインです。
Twitterは苦しんだエラーについて解決したことをつぶやいたりする簡易備忘録です。
他にも自分の生活リズムを正すための投稿をします。
11月8日時点でのトップツイートにある
「朝7時半までにツイートします」宣言がそれですね。精神的目覚ましです。
このブログを書くこともTwitterで宣言したから書いてます。
とりあえず最終課題完成後に自分で作成するオリジナルアプリは
ダイエットアプリを作ろうと思います。自分が太ってますんでね。
うまいものを食べるってのは幸せですね。
このブログに関してですが「週に2回程度投稿しようと思います。」
で投稿できるなら苦労しないんですよ。今現在は勉強時間の方が大事ですから。
週に1回だと1記事1時間でQiitaと合わせてざっくり2時間かー。めんどそうだなー。
減らす?月に1回?更新どころかブログの存在も忘れるに決まってます。
どどどどうしよう???
と、とりあえず試行錯誤します。以上、あいさつでした。