はじめに
2014年7月8日の晩に、ソニックガーデンのweb勉強会であるSonicGarden Studyで、「CodeIQ ベストコード発表会 ~最もエレガントにカラオケマシン問題を解いた挑戦者は誰だ!?~」を放送しました。
http://sonicgarden.doorkeeper.jp/events/12901
今回のエントリはこの放送の内容を簡単にまとめておきます。
放送の録画
放送内容は録画してYouTubeにアップしました。
1時間20分ぐらいあるのでちょっと長めです。
CodeIQ ベストコード発表会 ~最もエレガントにカラオケマシン問題を解いた挑戦者は誰だ!?~
「カラオケマシン問題」ってどんな問題?
カラオケマシン問題は文字列で与えられたメロディのキーを上げたり下げたりして、新しいメロディ(=移調したメロディ)の文字列を作成する問題です。
RSpecで表現するとこんな感じになります。
it "2上げる" do melody = "C D E F |E D C " answer = "D E F# G |F# E D " expect(KaraokeMachine.new(melody).transpose(2)).to eq answer end
「ドレミファソラシド」は「CDEFGABC」になります。
空白は休符を、縦棒(|)は小節の区切りを表します。
詳しくは以前書いたこちらのエントリを参照してください。
CodeIQに「カラオケマシン問題」を出題しました。みんなチャレンジしてね! - give IT a try
http://mids-player.net/_src/sc219/7208CAE94D589B98AK955C.jpg
解答テンプレートはこちらにあります
この問題は予めこちらで決めたテストパターンを全てパスする必要があります。
クラス名やメソッド名も全員共通にしています。
このルールを適用しやすくするため、解答テンプレートを用意してありました。
この解答テンプレートはgistに置いています。
https://gist.github.com/JunichiIto/c548e39fed60bf4bd36a
優秀者の解答
50名の挑戦者の中からこちらで3名の方を優秀賞として選ばせてもらいました。
それぞれこんな解答になっていました。
Muさん
class KaraokeMachine KEY = ['A','A#','B','C','C#','D','D#','E','F','F#','G','G#'] def initialize(melody) @MELODY = melody end def transpose(amount) @MELODY.gsub(/[ACDFG]#|[A-G]/){|k| KEY[ (KEY.index(k)+amount) % 12] } end end
ttakuru88さん
class KaraokeMachine TONES = %w(A A# B C C# D D# E F F# G G#) * 2 def initialize(melody) @melody = melody end def transpose(amount) amount %= 12 @melody.gsub(/([A-G]#?)/) { TONES[TONES.index($1) + amount] } end end
hitokunさん
class KaraokeMachine @@tmpl = ["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"] @@conv_ptn = Regexp.union(@@tmpl.collect{|item|Regexp.new(item + "(?!#)")}) def initialize(melody) @melody = melody end def transpose(amount) @melody.gsub(@@conv_ptn, Hash[@@tmpl.zip @@tmpl.rotate(amount)]) end end
これらの解答については、最初に紹介した動画の13:00あたりから解説しています。
僕の模範解答
僕はこんな模範解答を紹介しました。
class KaraokeMachine SCALE = %w(C C# D D# E F F# G G# A A# B).freeze def initialize(melody) @melody = melody end def transpose(amount) converter = [SCALE, SCALE.rotate(amount)].transpose.to_h @melody.gsub(/[A-G]#?/, converter) end end
模範解答のポイントは以下の通りです。
- 定数的な値は定数として定義する
- 標準APIを活用し変換用ハッシュを作成
- 標準API = rotate, transpose, to_h
- 正規表現を使って音符のみを抽出
- gsubにハッシュを渡してコード量削減
模範解答については動画の32:20あたりから解説しています。
余談: RubyMineの便利機能が意外と好評でした
コードの解説ではRubyMineを使ってコードをリファクタリングしたり、デバッグ実行したりしていました。
こうしたRubyMineの機能が新鮮に映った人も多かったようで、Twitterには「RubyMineすげー!」的なリアクションが結構ありました。
え、今一瞬で変わった?#sg_study
— sousk (@sousk333) July 8, 2014
Rubymineがすごい。。。 #sg_study
— ゆさばな (@yusabana) July 8, 2014
RubyMineの変換機能すげえ #sg_study
— Toru KAWAMURA (@tkawa) July 8, 2014
このあたりの動きが気になる方は動画の13:10あたりからチェックしてみてください!
良いコードの境界線
今回、この問題の解答を採点しながら、「こういうことができている人は結構わかりやすいな」と感じたポイントをまとめると次のようになります。
- 正規表現の活用
- Array, Hash, String等の標準APIの活用
- 定数やインスタンス変数の使い分け
- for/while/break/next等を避ける
- YAGNIなシンプル設計
このあたりは動画の39:20あたりから解説しています。
参考資料: 正規表現を学ぶならこちら
僕もこの本で正規表現を勉強しました。
分厚くて難しそうに見えますが、正規表現を全く知らない人でも大丈夫なように丁寧に教えてくれるので、実はとてもわかりやすい本です。
- 作者: Jeffrey E.F. Friedl,株式会社ロングテール,長尾高弘
- 出版社/メーカー: オライリージャパン
- 発売日: 2008/04/26
- メディア: 大型本
- 購入: 24人 クリック: 754回
- この商品を含むブログ (86件) を見る
参考資料: 標準APIを学ぶならこちら
自分でロジックを書く前に、Rubyの標準APIで同じ機能が提供されていないか確認しましょう。
僕はruby-doc.orgをよく見ます。
「Dash + Alfred + Dash Workflow」を使うともっと便利
ちなみに、ソニックガーデンの西見さん(@mah_lab)いわく、「MacユーザーならDash + Alfred + Dash Workflowを使うともっと便利だよ!」とのことです。
詳しくはこちらの記事を参考にしてみてください。
標準APIを使いこなすことが重要なのであれば、いつでも標準APIを検索できる状態にしておくことが大事ですよね | mah365
参考資料: Rubyらしさを学ぶならこちら
Rubyを始めたばかりの方や、他の言語での経験が長い方はなかなか「Rubyらしい良い書き方」に移行できなかったりします。
そんな方はこちらの記事を読んで、自分が書いたコードに問題が無いかチェックしてみると良いかもしれません。
[初心者向け] RubyやRailsでリファクタリングに使えそうなイディオムとか便利メソッドとか
「良いコード、悪いコードとは」、「コードレビューの効果」といったテーマについてもお話ししました
カラオケマシン問題の解答例を発表するだけでなく、後半はもうちょっと議論を一般化して、「良いコード、悪いコードとは」や、「コードレビューの効果」等についても話してみました。
最初は69行もあったRuby初心者さんのコードが、コードレビューとリファクタリングによって13行まで削減できた、という具体例も紹介しています。
このあたりの内容は動画の46:30ぐらいから解説しています。
大事なことは「コードを書く」「コードを読む」「コードを読んでもらう」
良いコードを書けるようになるためには、コードを書く、コードを読む、コードを読んでもらう、ということが重要です。
そのためにもチームや組織でコードレビューする文化を育てる必要があります。
また、チームや組織以外でも、CodeIQの問題に挑戦してフィードバックをもらったり、勉強会に参加したり、社外の教育プログラムを履修したり、といったこともできます。
ちなみにソニックガーデンでは現在企業向けの教育プログラムを準備中です。
この教育プログラムでは僕たちがやっているように「コードレビューできる人材」を育成します。
詳しくはソニックガーデンのwebサイトからお問い合わせください。
http://www.sonicgarden.jp/inquiry
参考資料: 良いコード、良い設計を個人で学ぶならこちら
良いコードや良い設計を個人レベルで学びたい、という方はこちらの2冊(3冊?)がオススメです。
CODE COMPLETE 第2版 上 完全なプログラミングを目指して
- 作者: スティーブマコネル,Steve McConnell,クイープ
- 出版社/メーカー: 日経BP社
- 発売日: 2005/03/26
- メディア: 単行本
- 購入: 44人 クリック: 1,166回
- この商品を含むブログ (288件) を見る
CODE COMPLETE 第2版 下 完全なプログラミングを目指して
- 作者: スティーブマコネル,Steve McConnell,クイープ
- 出版社/メーカー: 日経BP社
- 発売日: 2005/03/26
- メディア: 単行本
- 購入: 16人 クリック: 193回
- この商品を含むブログ (164件) を見る
リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)
- 作者: Dustin Boswell,Trevor Foucher,須藤功平,角征典
- 出版社/メーカー: オライリージャパン
- 発売日: 2012/06/23
- メディア: 単行本(ソフトカバー)
- 購入: 68人 クリック: 1,802回
- この商品を含むブログ (140件) を見る
放送終了後にオフィスで追加コードレビューを実施しました
さらに特別企画として、希望者の方をオフィスに招待し、持ち込んでもらった解答例をソニックガーデンメンバーでコードレビューしました。
今回は3名の方が渋谷のソニックガーデンオフィスにやってきてくれました。
僕はSkypeでビデオ会議方式でコードレビューに参加しました。
僕一人の意見だけでなく、他のメンバーからもコードの良し悪しに関する意見が出て、なかなか興味深い議論が巻き起こりました。
参加してくれた方にも満足してもらえたようで良かったです。
次回のSonicGarden Studyについて
次回のSonicGarden Studyの内容は以下の通りです。
- タイトル
- 「いつまでクソコードを 書き続けるの? ~デキるプログラマだけが知っている コードレビュー7つの秘訣~」
- 内容
- 優れたプログラマだけが優れたソースコードを書くことができます。では優れたプログラマになるにはどうすれば良いでしょうか。
自分の書いたコードを、優れたプログラマに指摘してもらうことが一番の近道です。それがコードレビューです。
たった一人でコードレビューも受けずに、ただ書き続けてもクソコードはクソコードなのです。
この放送では、良いコードが書けるプログラマになるための、コードレビューを上手に実践するための秘訣を話します。 - 講師
- 西見公宏(@mah_lab)
- 放送予定日
- 8/11(月)
今回の僕の放送でも「コードレビューは大事」ということをお話ししましたが、次回の放送ではコードレビューについてもっと掘り下げた内容になる予定です。
どうぞお楽しみに!
なお、開催通知を受け取りたい方は、Doorkeeperのコミュニティサイトから開催通知の受け取りを申し込むことができます。こちらもぜひ登録してください♪
SonicGarden Study | Doorkeeper
まとめ
というわけで今回は7月8日に放送したweb勉強会、「CodeIQ ベストコード発表会 ~最もエレガントにカラオケマシン問題を解いた挑戦者は誰だ!?~」の内容を一通り紹介しました。
今回は結構盛りだくさんの内容でお届けしたので、放送時間もちょっと長くなってしまいました。
最後まで見てくださったみなさんは、どうもありがとうございます!
都合が合わなくて見られなかった、という人は時間のあるときにスライドや動画をチェックしてみてくださいね。
予告: 次回のCodeIQへの出題は8月頃の予定です
次回のCodeIQへの出題は8月ぐらいを予定しています。
出題したらまたこのブログ等でお知らせしますので、みなさんぜひチャレンジしてください!
PR: みなさんもCodeIQの問題に挑戦&出題してみませんか?
CodeIQでは様々な言語、様々なレベルのプログラミング問題が出題されています。
解答すれば出題者の方からのフィードバックがもらえたり、転職を考えている方には企業からのスカウトが来たりします。
ちょっとした自分の腕試しとして面白そうな問題を探して挑戦してみましょう!
また、挑戦者だけでなく、問題の出題者も募集しています。
「出題に興味がある」という方はぜひCodeIQのお問い合せなどからご連絡ください。