Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby de FizzBuzz

ohto
March 07, 2018

Ruby de FizzBuzz

Introduction to test driven development.
This presentation is based on
https://qiita.com/ohto/items/281d127a7938121556c0

ohto

March 07, 2018
Tweet

More Decks by ohto

Other Decks in Programming

Transcript

  1. Ruby de FizzBuzz
    2018/3/8 おおとや

    View Slide

  2. おおとや
    趣味
    – 数学とか
    – アニメとか
    – LTとか
    最近転職しました!!
    2 / 28

    View Slide

  3. はじめに
    Qiita 記事を元に作成しました
    – FizzBuzz Advent Calendar 2017 12/24
    – Qiita Ruby de FizzBuzz で検索!!
    3 / 28

    View Slide

  4. 質問
    テスト書いてますか?
    4 / 28

    View Slide

  5. 質問
    テスト書いてますか?
    スプレッドシート管理ですか?
    5 / 28

    View Slide

  6. 質問
    テスト書いてますか?
    スプレッドシート管理ですか?
    あかん!
    6 / 28

    View Slide

  7. なんであかんのん?
    ● テスト要員が必要
    ● 時間がかかる
    ● テスト漏れが生じる
    7 / 28

    View Slide

  8. なんであかんのん?
    ● テスト要員が必要
    ● 時間がかかる
    ● テスト漏れが生じる
    ヒトとカネの無駄
    8 / 28

    View Slide

  9. 目的
    テスト書きませう
    9 / 28

    View Slide

  10. 目的
    テスト書きませう
    Pros
    – 動く要求仕様で合意形成
    – 自動テスト/CI
    – すばやいテスト
    – 徐々に改善
    Cons
    – 書くのが面倒...
    10 / 28

    View Slide

  11. 目的
    テスト書きませう
    Pros
    – 動く要求仕様で合意形成
    – 自動テスト/CI
    – すばやいテスト
    – 徐々に改善
    Cons
    – 書くのが面倒...
    (゚Д゚)ハァ?
    11 / 28

    View Slide

  12. 開発フロー
    テストファースト!!
    仕様作成
    合意
    テスト作成
    開発 テスト
    評価
    リファクタリング
    12 / 28

    View Slide

  13. 例題
    13 / 28

    View Slide

  14. 開発対象 -FizzBuzz
    1から順番に数値を出力します。
    ただし、下記の条件をみたすとき、
    数値の代わりに指定した文字列を出力します。

    3で割り切れるとき "Fizz"

    5で割り切れるとき "Buzz"
    ● 3と5で割り切れるとき "FizzBuzz"
    14 / 28

    View Slide

  15. 開発対象 -FizzBuzz 例
    1. 1
    2. 2
    3. Fizz
    4. 4
    5. Buzz
    6. Fizz
    7. 7
    8. 8
    9. Fizz
    10. FizzBuzz
    15 / 28

    View Slide

  16. 使用言語 -Ruby
    Rubyとは…
    – オープンソースの動的なプログラミング言語で、
    シンプルさと高い生産性を備えています。
    – エレガントな文法を持ち、自然に読み書きが
    できます。
    https://www.ruby-lang.org/ja/
    16 / 28

    View Slide

  17. 開発
    ● 仕様
    ● テスト
    ● 実装
    ● 評価
    17 / 28

    View Slide

  18. 開発 -仕様
    1 から n までの数値について FizzBuzz して、
    ファイルに書き込むメソッドを作成
    18 / 28

    View Slide

  19. 開発 -テスト
    テスト作成
    – 1 から 100 までの期待する答えを作成
    spec/fizz_buzz.answer とする
    – テストコード(rspec) を作成
    – rspec spec でテスト実行
    19 / 28

    View Slide

  20. 開発 -テスト
    require_relative '../fizz_buzz.rb'
    describe :FizzBuzz do
    before :all do
    dir = File.expand_path(File.dirname(__FILE__))
    @_read = ->(fn){ File.open(fn).map{ |r| r.chomp }}
    @answer = @_read[File.join(dir, 'fizz_buzz.answer')]
    end
    it 'should be eauql to anser' do
    fn = 'fizz_buzz.result'
    fizzbuzz(100, fn)
    expect(@_read[fn]).to match_array @answer
    end
    end
    20 / 28

    View Slide

  21. 開発 -実装
    1.テストが通るように開発
    2.テストが通るのを維持してリファクタリング
    21 / 28

    View Slide

  22. 開発 -実装(初回: 文字列結合)
    def fizzbuzz(n, fn)
    File.open(fn,'w') do |f|
    1.upto(n) do |i|
    out = ''
    i % 3 == 0 and out << 'Fizz'
    i % 5 == 0 and out << 'Buzz'
    f.puts out.empty?? i : out
    end
    end
    end
    文字列を結合
    22 / 28

    View Slide

  23. 開発 -実装(場合分け)
    def fizzbuzz(n, fn)
    File.open(fn,'w') do |f|
    1.upto(n) do |i|
    f.puts case
    when i % 15 == 0 then 'FizzBuzz'
    when i % 3 == 0 then 'Fizz'
    when i % 5 == 0 then 'Buzz'
    else i
    end
    end
    end
    end
    文字列演算が重いので、
    場合分けに変更
    23 / 28

    View Slide

  24. 開発 -実装(ハッシュを使う)
    class FizzBuzz
    CONDITION = { 0 => 'FizzBuzz' }
    { 3 => 'Fizz',
    5 => 'Buzz',
    }.each do |no, key|
    no.step(14,no){ |i| CONDITION[i] = key }
    end
    def fizzbuzz(n, fn)
    FizzBuzz.fizzbuzz(n, fn)
    end
    class << self
    public
    def fizzbuzz(n, fn)
    File.open(fn,'w') do |f|
    1.upto(n) do |i|
    f.puts CONDITION[i % 15] || i
    end
    end
    end
    end
    end
    24 / 28

    View Slide

  25. 開発 -評価(実行速度の計測)
    require 'benchmark'
    n = 10000000
    fn = 'fizzbuzz.out'
    Benchmark.bm do |r|
    r.report('no 1'){ fizzbuzz1(n, fn) }; File.delete(fn)
    r.report('no 2'){ fizzbuzz2(n, fn) }; File.delete(fn)
    r.report('no 3'){ FizzBuzz.fizzbuzz(n, fn) }; File.delete(fn)
    end
    25 / 28

    View Slide

  26. 開発 -評価(実行速度の計測: 結果)
    user system total real
    no 1 5.810000 0.160000 5.970000 ( 6.045857)
    no 2 5.120000 0.150000 5.270000 ( 5.311798)
    no 3 4.850000 0.130000 4.980000 ( 4.990330)
    ハッシュ版が一番速かった!!
    26 / 28

    View Slide

  27. まとめ
    ● 動く仕様書/テストで合意形成
    ● 小さくスタート
    ● リファクタリングでコードを育成
    ● 作りすぎない
    27 / 28

    View Slide

  28. テストは大切
    28 / 28

    View Slide