2019/05/12
ひきつづき。
アウトプットのネタに困ったらこれ!?Ruby初心者向けのプログラミング問題を集めてみた(全10問) - give IT a try
カラオケマシン問題
やってみた
- できた!と思ったらテストふたつNGだった!テストすごいな。
- 直した。テストも通ったけど、ゴミみたいな出来だな、、泣ける。
- 1文字ずつ見るより良い書き方ありそう。
class KaraokeMachine def initialize(melody) @code = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'] @melody = melody end def transpose(amount) code = @code.rotate(amount) ans = '' @melody.chars.each_with_index do |m, i| next if m == '#' if m.include?(' ') || m.include?('|') ans += m else ans += @melody[i + 1] == '#' ? code[@code.index(m) + 1] : code[@code.index(m)] end end ans end end
こたえあわせ
- これ。 「CodeIQ ベストコード発表会 ~最もエレガントにカラオケマシン問題を解いた挑戦者は誰だ!?~」を放送しました #sg_study - give IT a try
- ぎゃあ。全然だめだったあ。
- よくないとされている
next
使っているし、定数を定数として定義していない。rotate
は使えたが、transpose
,to_h
使いどころある?という感じだし。 - 音符の抽出は正規表現で行えばよかった。1文字ずつ見て、シャープ切り離してというのはいけてない。
gsub
にハッシュを渡す、、、?
読んでみる
SCALE = %w(C C# D D#[中略] A A# B).freeze
- 定数は定数として定義する。配列の定義の仕方も忘れてた。
- `%w: 配列を作る。式展開はされない。
freeze
: オブジェクトを凍結する。変更不可にする。
def initialize( melody) @melody = melody end
- これはクラスの中で使えるように@で定義してるんだよね。クラス変数とインスタンス変数わからんまま来てしまった。
- 【まとめ】インスタンス変数、クラス変数、クラスインスタンス変数 - Qiita
インスタンス変数
- アクセスできるのがinitializeメソッドとインスタンスメソッドだけ。
- initializeメソッドで初期化されて、その後各インスタンスメソッドから参照される使い方が多い。→今回のはまさにこれかな
- 変数名の前に
@
を付けて定義する
クラス変数
def transepose(amount) converter = [SCALE, SCALE.rotate(amount)].transpose.to_h @melody.gsub(//),converter)
- ……簡単にしてみる。
SCALE = %w(a b c d e).freeze => ["a", "b", "c", "d", "e"]
[SCALE, SCALE.rotate(3)] => [["a", "b", "c", "d", "e"], ["d", "e", "a", "b", "c"]]
[SCALE, SCALE.rotate(3)].transpose => [["a", "d"], ["b", "e"], ["c", "a"], ["d", "b"], ["e", "c"]]
[SCALE, SCALE.rotate(3)].transpose.to_h => {"a"=>"d", "b"=>"e", "c"=>"a", "d"=>"b", "e"=>"c"}
- ふむ、理解。
- この形になるのはわかったけど、この形にするとどう都合がいいのか?
melody='a | b| ||c ||d|e' #適当に => "a | b| ||c ||d|e" melody.gsub(/[a-e]#?/,converter) => "d | e| ||a ||b|c"
- おお!!!
- gsubの置換方法(
gsub(pattern, replacement)
のreplacement
)にはいろいろな方法が指定できる。単純な文字列、ハッシュ、ブロック。今回はハッシュを使っている。 - ハッシュを用いた方法は、
{ マッチした文字列 => 置換文字列}
で指定できる。 - ブロックを用いた方法は、文字列中の該当語を取り出してブロックを実行する。
s.gsub(/\w+/) { |word| word.capitalize }
これは英単語の先頭を大文字にしている。 - 正規表現の
\w+
で英単語(アルファベット数字_がつながっているもの)を取り出して、capitalize
で先頭を大文字にしている。
感想
- 正規表現を使えば
A#
みたいなシャープ付きをまとめて変換できたのか。 - 変換用のハッシュを作るという発想は、自分じゃ絶対出てこなかったな。こうやって知れるのも本当にうれしいけど、普段からこういう方にレビューしてもらえたらしあわせだよなあ……。
関連記事よんだ
- [初心者向け] RubyやRailsでリファクタリングに使えそうなイディオムとか便利メソッドとか - Qiita
- 結構知っているし使っているメソッドが増えていて嬉しい……!
tap
tap
しらなかった。最後にreturnするためだけに変数書く必要がないらしい。スマート。
配列の連結に*(splat)
を使う
- 見たことある!!!
numbers = [1, 2, 3] numbers_new = [0] + numbers +[100] # => [0, 1, 2, 3, 100]
- まずそもそもこうやって配列連結できるんだ。本題はこれじゃなく、以下のように書けるってこと。
numbers = [1, 2, 3] numbers_new = [0, *numbers, *100]
- 変数に入れた配列をフラットに展開できるということだよね。
*
を入れないと展開されない。↓ [0, numbers, 100] # => [0, [1, 2, 3], 100]
ハッシュのキーにシンボルを使う理由
- 簡潔に書ける(だよね)
- 文字列よりも速い。
- 文字列よりもメモリの使用効率がいい。
内部的にはintegerか何かでうごいてるんだっけ。あらためて使うべきと認識。
一度に全部は読み切れない
- 一気によめる文量じゃないのでまたこんど
- こういうのをためておくいい場所が未だに見つからない。いつもためっぱなし。
標準APIを使いこなす
標準APIを使いこなすことが重要なのであれば、いつでも標準APIを検索できる状態にしておくことが大事ですよね | mah365
- ruby-doc.orgを繰り返し読む。
- そうだよね…………
- →読むのめんどくさいなら、Alfredでできるとのこと。課金するとalfred workflowなるものが使えて、それがあればローカルで確認できるらしい。
ダイアログデザイン
キャンセルのダイアログについて。かなりわかりやすい。