zdogma's diary

徒然なるエンジニアな日々。

Github Pages + Jekyll でハマったこと

はじまりは Processing の成果物を蓄積する場所としてのシンプルな Github Pages を想定していたが、 Github Pages が Jekyll を推奨していたこともあり、久々に触ってみることにした。

そうしたら思いの外ハマってしまったので、そのログを残しておく。

問題1: _layouts が見つからない

概要

いつもの調子で下記のように打ってみたのだが、

bundle install --path=vendor/bundle --jobs=4
bundle exec jekyll new .

下記のようなエラーが出てビルドできない。

$ bundle exec jekyll build
Configuration file: /Users/tomohiro.zoda/git/github.com/zdogma/zdogma.github.io/_config.yml
            Source: /Users/tomohiro.zoda/git/github.com/zdogma/zdogma.github.io
       Destination: /Users/tomohiro.zoda/git/github.com/zdogma/zdogma.github.io/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
     Build Warning: Layout 'post' requested in _posts/2016-08-07-welcome-to-jekyll.markdown does not exist.
  Liquid Exception: The included file '/Users/tomohiro.zoda/git/github.com/zdogma/zdogma.github.io/_includes/icon-github.html' should exist and should not be a symlink in about.md

jekyll new した時に作られるべき _layouts が存在しない...? 前に jekyll 使った時はこんなところでハマらなかったような...泣

解決方法

Github Pages 側の公式ドキュメントに導入方法があったので読んでみる。(最初から読んでおけという話)
Setting up your GitHub Pages site locally with Jekyll - User Documentation

bundle exec jekyll new . --force
New jekyll site installed in /Users/octocat/my-site.

force オプションが必要だったらしい。
すでに存在するディレクトリに jekyll の初期設定を展開する時には必須なのだそうだ。

If the existing directory isn’t empty, you’ll also have to pass the --force option like so jekyll new . --force.

jekyllrb.com

問題2: Invalid date でフォーマットエラー

概要

またもビルドで落ちる。

$ bundle exec jekyll serve
Configuration file: /Users/tomohiro.zoda/git/github.com/zdogma/zdogma.github.io/_config.yml
            Source: /Users/tomohiro.zoda/git/github.com/zdogma/zdogma.github.io
       Destination: /Users/tomohiro.zoda/git/github.com/zdogma/zdogma.github.io/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
             ERROR: YOUR SITE COULD NOT BE BUILT:
                    ------------------------------------
                    Invalid date '<%= Time.now.strftime('%Y-%m-%d %H:%M:%S %z') %>': Document 'vendor/bundle/ruby/2.3.0/gems/jekyll-3.1.6/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb' does not have a valid date in the YAML front matter.

なにか余計なものを見に行って落ちているようで、これはすぐに解決策が浮かんだ。

解決方法

_config.yml に下記を追記する。

exclude: [vendor]

vendor/bundle 以下に gem を入れている場合、ビルド時にそこを読まないように除外してやる必要がある。 除外含めた _config.yml の書き方は下記に詳しい。

Exclude Exclude directories and/or files from the conversion. These exclusions are relative to the site's source directory and cannot be outside the source directory.

jekyllrb.com

ビルド成功

なんとか上記を踏まえて、ビルドできるようになった。

$ bundle exec jekyll serve --watch
Configuration file: /Users/tomohiro.zoda/git/github.com/zdogma/zdogma.github.io/_config.yml
            Source: /Users/tomohiro.zoda/git/github.com/zdogma/zdogma.github.io
       Destination: /Users/tomohiro.zoda/git/github.com/zdogma/zdogma.github.io/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
                    done in 0.273 seconds.
 Auto-regeneration: enabled for '/Users/tomohiro.zoda/git/github.com/zdogma/zdogma.github.io'
Configuration file: /Users/tomohiro.zoda/git/github.com/zdogma/zdogma.github.io/_config.yml
    Server address: http://127.0.0.1:4000/
  Server running... press ctrl-c to stop.

これでこちらの Github Pages も使えるようになったが、こちらでも記事を書くとこのはてなダイアリーと重複するため、 基本的に Github Pages は Processing など動くものを載せるところにしようと思う。

Kindle の Highlight を Evernote に同期するスクリプトを書いた

ことはじめ

Kindle の Highlight 機能、便利ですよね!
特にビジネス書や小説などで、後で振り返りたい内容・表現に対してラインマーカーの如く Highlight を残している方も多いと思います。
かくいう私自身も Highlight をたくさん残しているのですが、せっかく残したものの「これ、いつ見返せばよいのだろう...」という根本的な疑問がありました。

これまで読んだ本の中には積極的に読み返したい本もあればそうでない本もあるわけで、アプリでいちいち Highlight を確認するのは辛いし、 一応 Web にも自分の Highlight をまとめてくれている場所はあるのですが、毎回アクセスするには認証もあったりで大変です。

https://kindle.amazon.co.jp/your_highlights

f:id:z_dogma:20160626222158p:plain

ということで、「自分の Kindle の Highlight を Evernote にバッチで保存するようなスクリプトを書けばいいじゃん!」ということで、書きました。

github.com

実行すると、Evernote にこんな感じのノートブックが作られます。
(タイトルの先頭の★は、その本の中での Highlight 箇所の数です)

f:id:z_dogma:20160626221456p:plain

これで電車の中でも Highlight を読み返しやすいですね!

本題

使い方

1.README の Install を読み、必要なミドルウェアをインストールします。

需要がどれくらいあるかわからなかったので、 Web アプリケーションにはしていません。
Ruby で書いたスクリプトをそのまま叩く(バッチの場合は cron などはお任せ)という不親切仕様ですがご勘弁を...。

2.env ファイルを用意します。

env ファイルとは、環境変数を定義するための設定ファイルで、 dotenv という gem を使って読み込みを行っています。
今回動かすスクリプトで必要な設定は下記3つです。

# kindle で登録している amazon アカウントのメールアドレス
AMAZON_MAIL_ADDRESS=xxx@xxx.xxx
# kindle で登録している amazon アカウントのパスワード
AMAZON_PASSWORD=xxxxxxx
# Evernote のデベロッパートークン
EVERNOTE_DEVELOPER_TOKEN=xxxxxxxxxxxxxxx

上2つの amazon 系は特に説明は不要かと思いますが、いちばん下の Evernote の developer token に関しては、下記の URL にアクセスして取得してください。

https://www.evernote.com/api/DeveloperToken.action

これらを .env というファイルに書き込んで、下記の階層に置いてください。 下記のようになっていたら OK です!

$ tree -a
.
├── .bundle
│   └── config
├── .git
│   ├─ /* 省略 */
├── lib
│   ├── evernote.rb
│   └── kindle.rb
├── log
│   └── .gitkeep
├── .env
├── .gitignore
├── Gemfile
├── Gemfile.lock
├── README.md
└── kindle_evernote.rb
3.Evernote 側で受け口となるノートブックを作成します。

KindleHighlights というノートブックを Evernote 側で作成してください。
ちなみにノートブック名はスクリプトの中で決めうちで指定していますので、変えていただいても OK です。 (ノートブック作成部分もコードで書いとけよというツッコミは受け付けません←)

4.rubyスクリプトを叩きます。

README の Usage にある通りです。

bundle exec ruby kindle_evernote.rb

log/ 以下に進捗含めたログを吐くようにしているので、下記のような感じで別のウインドウで確認しながらやっていただくと捗るかもしれません。

less +F log/xxxxxxxx

解説

Kindle の情報を取得する部分

下記のサイト様の情報を参考にさせていただきました。
基本的に処理の流れは同じで、違いといえば追加で「Highlight の(本の中での)場所」も取得していることくらいです。
あと、タイトルなどでノイズが紛れ込んでいた場合に除く処理もちょこっと足しています。 qiita.com

ただ、やはりスクレイピングということで、HTML の構造が変わると取得できなくなるなどの脆弱さを孕んでいるので、しれっと動かなくなったらすみません。

def highlights_for(asin)
  sleep 0.3

  page = @mechanize_agent.get("https://kindle.amazon.co.jp/your_highlights_and_notes/#{asin}")

  highlights = page.xpath('//div[@class="highlightRow yourHighlight"]').map do |e|
    {
      text: e.xpath('span[@class="highlight"]')&.inner_text || '',
      location_href: e.css('a')&.attribute('href')&.value   || ''
    }
  end

  {
    title:  page.search('span.title').text.gsub(/\(Japanese Edition\)|\n.*\z/, ''),
    author: page.search('span.author').text.gsub(/\A by /, '').strip,
    highlights:  highlights
  }
end

Evernote でノートを作成する部分

こちらは本家のドキュメントに則って書きました。

ノートの作成 - Evernote Developers

機能要件として、スクリプトを打つたびに新しくノートが作られるのは嫌だったので、 すでにノートが存在すれば update、まだノートが無ければ create という形で処理を分けています。
ノートの存在確認のために一度 findNotes をするのですが、その時に一意に検索できるように ASIN をキーワードにしています。

コードとしてはこのあたりです。

kindle-highlights/evernote.rb at master · zdogma/kindle-highlights · GitHub

おわりに

ざーっと書いたため、いろいろ不親切な部分があると思いますが、もしよかったら使ってみてください!
ドキュメントの不備などあればコメントいただけると助かりますー!

ではでは!

1からNまでの素数の数を数える標準ライブラリ Prime を読んでみる

ことはじめ

とある機会に「1からNまでの素数の数を数えよ」という問題を解こうとした時に、最初に下記のように書いた。

(2..number).each_with_object([]) { |num, primes|
  sqrt_primes = primes.select { |prime| prime < Math.sqrt(number) }
  primes << num if sqrt_primes.none? { |prime| num % prime == 0 }
}.count

ベンチマークを取れば歴然だが、下記のように N が大きくなると処理時間が大きくなる。 結果、テストケースを所定の時間内にクリアできないという状態に。。。

                       user     system      total        real
number = 10             0.000000   0.000000   0.000000 (  0.000045)
number = 100            0.000000   0.000000   0.000000 (  0.000342)
number = 1000           0.010000   0.000000   0.010000 (  0.012887)
number = 10000          0.660000   0.000000   0.660000 (  0.671416)

ぱっとチューニングのアイデアが思い浮かばなかったので、素数判定のロジックを調べていると、どうやら標準ライブラリに Prime というものがあるらしい。 下記のようなコードを書いてベンチマークを取ってみると...

require 'prime'
numbers.each { |number| Prime.each(number).count }
                       user     system      total        real
number = 10             0.000000   0.000000   0.000000 (  0.003707)
number = 100            0.000000   0.000000   0.000000 (  0.003185)
number = 1000           0.010000   0.000000   0.010000 (  0.002970)
number = 10000          0.000000   0.000000   0.000000 (  0.002980)

こちらだと余裕でテストケースをクリア。 なんとも悔しい気持ちになったので、Prime の実装を読んでみることにした。

本題

Prime の実装は下記にある。

ruby/prime.rb at trunk · ruby/ruby · GitHub

Prime では、下記のように each の引数に与えた数字までの素数を返す。

[56] pry(main)> Prime.each(100).to_a
=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

[57] pry(main)> Prime.each(100).class
=> Prime::EratosthenesGenerator

素数の判別方法にはいろいろなやり方があるが、Prime でデフォルトで採用されているのは「エラトステネスの篩(ふるい)」と呼ばれているアルゴリズムである。 wikipedia によると、下記のように実装されるらしい。

  • ステップ 1
    • 探索リストに2からxまでの整数を昇順で入れる。
  • ステップ 2
    • 探索リストの先頭の数を素数リストに移動し、その倍数を探索リストから篩い落とす。
  • ステップ 3
    • 上記の篩い落とし操作を探索リストの先頭値がxの平方根に達するまで行う。
  • ステップ 4
    • 探索リストに残った数を素数リストに移動して処理終了。

エラトステネスの篩 - Wikipedia

詳細な説明は省くが、実際に該当のアルゴリズムを実装しているのは下記の部分。

def compute_primes
  # max_segment_size must be an even number
  max_segment_size = 1e6.to_i
  max_cached_prime = @primes.last
  # do not double count primes if #compute_primes is interrupted
  # by Timeout.timeout
  @max_checked = max_cached_prime + 1 if max_cached_prime > @max_checked

  segment_min = @max_checked
  segment_max = [segment_min + max_segment_size, max_cached_prime * 2].min
  root = Integer(Math.sqrt(segment_max).floor)

  segment = ((segment_min + 1) .. segment_max).step(2).to_a

  (1..Float::INFINITY).each do |sieving|
    prime = @primes[sieving]
    break if prime > root
    composite_index = (-(segment_min + 1 + prime) / 2) % prime
    while composite_index < segment.size do
      segment[composite_index] = nil
      composite_index += prime
    end
  end

  @primes.concat(segment.compact!)

  @max_checked = segment_max
end

おわりに

最近競技プログラミングの勉強を始めているが、やはり数学への理解がかなり重要で、直感で消費メモリ・処理時間がイメージできるまで頭を慣らしたい。
今回はとりあえずアルゴリズムの内容がわかったので、次回、自分のアルゴリズムとの差分と処理時間の差が生まれた要因をもう少し突き詰めてみようと思う。

ruby で継承と委譲の使い分けを考える

ことはじめ

継承と委譲に関して、それぞれなんとなく理解はしているものの、どう使い分けるのがよいのか、イマイチ実感が湧いていなかったので、整理がてらブログに書いてみます。

それぞれの定義

継承

既存の親クラスの構造(属性や振る舞い含む)をまるごと受け継ぎ、新しいクラスとして再定義する。

委譲

特定の振る舞いを別のクラスのメソッドに委ねる。

具体例で考える

継承、委譲の使い分けを、具体例を使いながら検討していきます。 ここでは、下記のようなエンジニアマネージャのクラスを考えます。

class EngineerManager
  def initialize
  end

  # エンジニアに共通する振る舞い
  def code
  end

  def debug
  end

  def test
  end

  # マネージャに共通する振る舞い(ただし assign は許可しない)
  def coach
  end

  def motivate
  end

  # 社員に共通する振る舞い
  def eat(type = 'lunch')
  end

  def attend(meeting_type)
  end
end

ここで想定するエンジニアマネージャは、下記のようなロールだとします。

  1. エンジニアとしての振る舞いをする
  2. マネージャとしての振る舞いをする
    ※ただし、他のマネージャ職のメンバーとは異なり、アサイン組み替えの権限はない
  3. 社員としての振る舞いをする

基本的な方針としては、下記の記事にもあるように、「is-a」の関係が綺麗に成り立つ場合は継承を使うのが良いと僕も思います。

osa.hatenablog.com

継承は安易に用いると容易に複雑化し、バグの温床になりえるものの、その系において "よく" 抽象化された親クラスのもとで継承関係を作ることができれば、とても強力に機能すると思います。

例えば今回の例だと、エンジニアマネージャは社員の部分集合であるため、継承を用いてよいケースだと考えます。 社員に対して認められる振る舞いや属性は、漏れなくエンジニアマネージャも備えるべきです。

逆にエンジニアやマネージャに対してはそうではなく、それぞれの一部の振る舞いがエンジニアマネージャにも備わっているという状態であるため、まるごと受け継ぐ継承は不向きです。 エンジニアマネージャは "(エンジニアやマネージャが担う振る舞いのうち)どの振る舞いができるか" にのみ焦点を当て、その処理の具体的な内容は関知しない、という状態にします。

上記の思想のもと、下記のように実装してみました。

class EngineerManager < Worker
  extend Forwardable
  def_delegators :@engineer, *%i( code debug test )
  def_delegators :@manager, *%i( coach motivate )

  def initialize(name)
    @engineer = Engineer.new # Engineer.find(name: name)
    @manager = Manager.new # Manager.find(name: name)
  end
end


class Worker
  def initialize
  end

  def eat(type = 'lunch')
    puts "#{type} を食べました"
  end

  def attend(meeting_type)
    puts "#{meeting_type} に出席しました"
  end
end


class Engineer
  def initialize
  end

  def code
    puts 'code を書きました'
  end

  def debug
    puts 'debug をしました'
  end

  def test
    puts 'test をしました'
  end
end


class Manager
  def initialize
  end

  def coach
    puts 'コーチングしました'
  end

  def motivate
    puts 'モチベートしました'
  end

  def assign
    puts 'アサイン組み換えしました'
  end
end
bob = EngineerManager.new('Bob')
puts bob.code # => code を書きました
puts bob.attend('朝会') # => 朝会 に出席しました
puts bob.coach # => コーチングしました
puts bob.assign # =>  undefined method `assign' for #<EngineerManager:0x007fe6ec8e3a70>

おわりに

なんとなく具体例を考えてみると思考が整理された気がします。
まだまだ思考実験の域を出ていないので、ツッコミなどありましたらぜひお願いします!

参考サイト

gsub! sub! でパターンにマッチしなかった場合 nil が返る

ことはじめ

AtomPub で引っ張ってきたブログテキストに手を加えて別のアプリケーションで表示させようとしていた時に、表題の件でややハマりました。
ハマり時間は数分だったものの、割と想定外な内容だったので備忘も兼ねてメモしておきます。

本題

パターンにヒットする場合

[1] pry(main)> "abc".gsub(/a/, "")
"bc"
[2] pry(main)> "abc".gsub!(/a/, "")
"bc"

いずれもレシーバ自身に対して置換を行った処理後の文字列を返しています。
これは想定通り。

パターンにヒットしない場合

[3] pry(main)> "abc".gsub(/d/, "")
"abc"
[4] pry(main)> "abc".gsub!(/d/, "")
nil

gsub! もレシーバ自身を返してくれるかと思いきや、ここは nil が返ります。
AtomPub から返却されるのが本文全体の String なので、特定のタグがあったら変換、などをしていたのですが、 たまたまそのタグが使われていない記事があって、すっからかんになってしまい、焦りました。

おわりに

ドキュメントを読めば書いてあるので、ちゃんと読んどけよ、という話ではあるのですが、 他の select, select! とかの関係性からの推測で判断すると結構ハマるような...。
組み込みの関数とかで勘違いして前提を見誤ると、テストの漏れ等にもつながってしまうので、 ちゃんとドキュメントを読んでコードを書きましょう、ということですね。

参考ドキュメント

ref.xaio.jp ref.xaio.jp

画像形式 [ JPEG, PNG, GIF, BMP, WebP ] について調べてみた

ことはじめ

サイト高速化のための手段をいろいろと考えていたのですが、 今自分が関わっているサイトだと、画像をいっぱい使っているということもあり、画像圧縮が一つの選択肢になりそうでした。

とはいえ画像の種類もそんなに知らないし特徴の理解も怪しいので、まずは基本的な画像形式について調べてみよう、というのがこの記事の趣旨です。

意外と画像形式を横並びに見る機会って少ない気がするので、よかったら見てみてください。

目次

各形式の紹介

JPEG

名称

  • JPEG(ジェイペグ)
    • Joint Photograph Experts Group
      • この規格を作った組織の名前
      • 画像符号化の標準化を行なう事を目的として設立された組織らしい

拡張子

.jpg/.jpeg

特徴

  • 圧縮画像(不可逆)のため、画質が劣化する
  • 比較的データが軽い

  • 1677万色対応

    • 圧縮方法の観点から、色種類の多い画像に適している
    • デジカメの写真のほとんどはこのファイル形式

PNG

名称

  • PNG(ピング)
    • Portable Network Graphics
      • 特許使用の解釈に不安のあったGIFに替わるライセンス・フリーの画像形式として開発

拡張子

.png

特徴

GIF

名称

  • GIF(ジフ)
    • Graphics Interchange Format
      • 以前 Unisys 社が特許を持っていたことにより、ライセンス権などの特許問題があったが、現在では特許の有効期限は切れている

拡張子

.gif

特徴

BMP

名称

  • BMP(ビットマップ)
    • ピクセルを用いた画像表現広汎を指す
    • より狭義な技術用語としては、「ビットマップ」の用法をモノクロ2値画像に限定し、カラーやグレースケール階調画像を含める場合はピクセルマップ、ピクスマップ(pixmap)と呼ぶこともある。

拡張子

.bmp

特徴

  • 非圧縮画像のため、画質が劣化しない
  • データが重い
    • 古典的かつ単純なデータ圧縮を用いているため、圧縮率はそれほど期待できない
  • 1677万色対応で高画質
  • Windows標準の画像形式

WebP

名称

拡張子

.webp

特徴

おわりに

圧縮方法の可逆/非可逆の違いくらいは知っていましたが、その方法により向き不向きな画像があるとか、カバーしている色の数が違うなどは初耳で新鮮でした。

上記は本当に基本的なもの+αですが、他にも JPEGmini など新しいフォーマットも普及しつつあるらしいので、また別の機会で整理してみたいと思います。

参考サイト

追記 2015/07/09

拡張フォーマットとかで、可逆圧縮JPEG とかもあったりするらしいです。
あとは PNG をあえて非可逆圧縮したりとか...いろいろあるんですね。

スクラム実践入門 を読んでみた

ことはじめ

今自分が所属している開発チームでは、発足当初から「スクラム」に則った開発を進めています。
当初は極めて少人数のチームだったこともあり、導入後も特に困難なく開発を続けていたのですが、チームの規模や事業の状況が変わるにつれて、だんだんとうまくいかないケースが増えてきました。
そんなこんなで悶々としていたところ、下記の書籍を会社の先輩に紹介してもらいました。

スクラム実践入門 ── 成果を生み出すアジャイルな開発プロセス (WEB+DB PRESS plus)

スクラム実践入門 ── 成果を生み出すアジャイルな開発プロセス (WEB+DB PRESS plus)

読んでみると、目からウロコな情報が詰まっていて、正直感動しました。
特に自分のような「スクラムやってるけど、ちゃんと体系立てては知らない」「他のチームだとどのように取り組んでいるのか知りたい」という方にはとてもオススメです。

今回は、その中でも自分的に「へぇ〜」と思った箇所について、ネタバレにならない程度に簡単に紹介します。

なぜ「スクラム」と呼ばれるの?

そもそもスクラムとは、「スクラムガイド」と呼ばれるドキュメントにより下記のように定義された、ソフトウェアの開発プロセスを指します。

スクラム(名詞):複雑で変化の激しい問題に対応するためのフレームワークであり、可能な限り 価値の高いプロダクトを生産的かつ創造的に届けるためのものである。

出典: スクラムガイド
http://www.scrumguides.org/docs/scrumguide/v1/Scrum-Guide-JA.pdf

スクラムとは読んで字の如く、ラグビースクラムのことですが、なぜそのような名前になったのでしょうか?
現在スクラムと呼ばれているその開発手法は、1986年に「ハーバード・ビジネス・レビュー」誌に寄せられた竹内・野中論文に由来しており、その論文の中では、新製品開発の方法は大きく下記2つに分類されていました。

  • リレー競走型
    • バトンを渡していくように、各生産工程が交わる事なく順番に進んでいく
  • ラグビー

スピードと柔軟性を求められる現代の新製品開発の現場では、従来のリレー競走型の開発プロセスよりも、ラグビー型のアプローチを採用すべきだ、という趣旨で、ホンダの製品開発スタイルがベストな事例として紹介されているとか。

興味ある方は下記のWebサイトで原文が読めるそうなので、ぜひどうぞ。

hbr.org

なぜ作業を「時間」で区切るの?

いわゆるウォーターフォール型の開発だと、「Aという機能を◯月△日までに作る」など、成果物ベースでスケジュールを立てるのが基本だと思いますが、スクラムだと Sprint という期間、つまり時間で区切ります。
これはなぜなのでしょう?

スクラムによる問題解決の思想の原点は「経験主義」にあります。

スクラムは、経験的プロセス制御の理論(経験主義)を基本にしている。経験主義とは、実際の経験と既知に基づく判断によって知識が獲得できるというものである。スクラムでは、反復的かつ漸進的な手法を用いて、予測可能性の最適化とリスクの管理を行う。

出典: スクラムガイド
http://www.scrumguides.org/docs/scrumguide/v1/Scrum-Guide-JA.pdf

スクラムでは、解決すべき複雑で変化の激しい問題に関して、事前に万全な計画を立てて取り組もうとはしません。
時間によって作業を区切り、時に方向を修正しながら少しずつ成果物を積み上げ、最終的な成果物に近づけていく、というアプローチを取ります。
それがスクラムガイドにある「反復的かつ漸進的な手法」ということなのですね。

スクラムのキーワード

本書の中で紹介されているスクラム系のキーワードを並べてみました。
興味あるものについては本書を手に取って確認してみてください。

ロール

  • プロダクトオーナー
  • 開発チーム
  • スクラムマスター

成果物

イベント

  • スプリントプランニング
  • リファインメント
  • デイリースクラム
  • スプリントレビュー
  • スプリントレトロスペクティブ

プラクティス

  • インセプションデッキ
  • リーンキャンバス
  • ユーザーストーリー
  • ユーザストーリーマップ
  • プランニングポーカー
  • スパイク
  • バーンダウンチャート
  • パーキングロット
  • KPT

おわりに

スクラムという手法が広く取り入れられるようになってからしばらく経ち、導入している企業も増えていると思います。
ただ、スクラムを実際に取り入れてみるとしみじみと感じるのですが、スクラム自体はとてもよくできた手法ではあるものの、どんなチームにも紋切り型で当てはめるだけでベストな成果が出る魔法のような手法というわけではなく、それをきちんとワークさせるためには、しっかりと各 Sprint を振り返り、改善を重ねていく根気と実行力が必要です。
そんな時にとても助けになるのは、実際にチームに適用したときの経験談や対処法だったりして、そのあたりもこちらの本にしっかりまとまっています。
どんなチームでも悩みどころはだいたい似通っているようで、結構ドンピシャな内容が載ってたりしますので、ぜひご一読をおすすめします。

参考にしたページ