Photoruction工事中!

Photoructionの開発ブログです!

PyMuPDFでPDFを操作する①

はじめに

こんにちは、株式会社フォトラクションでエンジニアをしています酒井です。

自分のチームではPDFを扱うことが多く、これらを PyMuPDF と呼ばれるPythonのライブラリを用いて操作しています。

Pythonには他にも PyPDF2PDFminer など様々なPDF操作用のライブラリがありますが、日本語への対応や実装されている関数の多さ、ドキュメントの読みやすさ等をふまえ、弊社では PyMuPDFを使用しています。(参考: PyMuPDFドキュメント

今回はPyMuPDFで可能となる操作をいくつか紹介したいと思います。

1. 画像変換(pdf ⇒ ndarray)

import io

import cv2
import fitz
import numpy as np
from PIL import Image

# PDFファイルパスの読み込み
pdf_path = input()

# 1ページ目の要素を取得
document = fitz.open(pdf_path)
page = document[0]

# 拡大度を指定
zoom = 3.0

# pixmapを取得
matrix = fitz.Matrix(zoom, zoom)
pixmap = page.get_pixmap(matrix=matrix)

# pillowでpng形式のバイトオブジェクトを取得
byte = pixmap.pil_tobytes("png")

# PIL画像を取得
binary = io.BytesIO(byte)
pil_img = Image.open(binary)

# PIL画像をNumPy配列の画像に変換
ndarray_img = np.array(pil_img)

# BGR -> RGB
ndarray_img = cv2.cvtColor(ndarray_img, cv2.COLOR_BGR2RGB)

2. 注釈取得

# PDFファイルパスの読み込み
pdf_path = input()

# 1ページ目の要素を取得
document = fitz.open(pdf_path)
page = document[0]

# 注釈情報を取得
annotations = page.annots()

3. PDFサイズの取得

# PDFファイルパスの読み込み
pdf_path = input()

# 1ページ目の要素を取得
document = fitz.open(pdf_path)
page = document[0]

pdf_width, pdf_height = page.rect.width, page.rect.height

最後に

PyMuPDFを使えば、他にも「ページの分割」や「注釈の設定」等様々な操作が可能となります。

よかったら使ってみてください。

参考

Introduction - PyMuPDF 1.21.0 documentation

株式会社フォトラクションでは一緒に働く仲間を募集しています

google driveで管理するファイルのIDを取得する方法

目次

  1. はじめに
  2. IDの取得方法
  3. 最後に

1. はじめに


時が過ぎるのは早いもので、AIエンジニアとしてキャリアをスタートしてから、早3年経とうとしています。

最近drive APIを使用して google driveのファイルを操作する機会があったのですが、その時に基本的にパスではなく、IDを使用して操作するような設計になっているようでしたので、ファイルの操作になかなか苦戦しました。

そこで、今回はパスからIDを取得するライブラリを発見したので、それを今回は紹介したいと思います。

2. IDの取得方法


手順として、まずkoraというライブラリをインストールします。

!pip install kora==0.9.20

そして、以下のように使用する事で、ファイルのパスからIDを取得する事ができます。

from kora.xattr import get_id
file_path = "./hogehoge/hogehoge.gsheet"
spreadsheet_id = get_id(file_path)

これで、ファイルのIDを取得する事ができました!

3. 最後に


これ以外にも、drive apiやsheets apiを使用する上で、例えばGCPのサービスアカウントに権限を渡す必要があるなど、ややこしい事が多々ありますが、IDの取得さえできれば他は結構簡単に解決していけると思うので、今回はdrive apiを使用する上で欠かせないIDの取得方法について解説しました。最後まで読んで頂きありがとうございました。

株式会社フォトラクションでは一緒に働く仲間を募集しています

Androidアプリのアーキテクチャの現状 ver.2022年

Androidアプリ開発者の久木田です。

この記事はPhotoruction Advent Calendar2022の日目です。

去年のアドベントカレンダーAndroidアプリのアーキテクチャの現状 という記事を書きました。

今回はここから1年でどういう進捗があったのかをお話しします。

TL;DR

目を見張るほどのものはないかもしれないが、着実に良くなっていっている。

新しいことも始めていきたいな〜。。。

計測と所感

去年と同じ内容でデータを取ってみました。

色々改善が進んでいるのがわかるんじゃないないかなと思います。

ファイル数からわかること

種類 条件 コマンド
Activity 62 ファイル名にActivityがついている find . -name "*Activity.java" -o -name "*Activity.kt" | wc -l
Fragment 80 ファイル名にFragmentがついている find . -name "*Fragment.java" -o -name "*Fragment.kt" | wc -l
ViewModel 87 ファイル名にViewModelがついている find . -name "*ViewModel.java" -o -name "*ViewModel.kt" | wc -l
69 ↑のうち、ViewModelもしくはAndroidViewModelを継承しているクラスのあるファイル find . -name "*ViewModel.java" -o -name "*ViewModel.kt" | xargs grep -l AndroidViewModel | wc -l
Repository 82 ファイル名にRepositoryがついている find . -name "*Repository.java" -o -name "*Repository.kt" | wc -l
Realm 49 RealmObjectを継承しているクラスのあるファイル rg -l "extends RealmObject" . | wc -l
Room 31 @Entityが付いているクラスのあるファイル rg -l "@Entity" . | wc -l
Test 36 ファイル名にTestがついている find . -name "*Test.java" -o -name "*Test.kt" | wc -l

去年と比べての改善点

  • Activityがあまり変わらないけどFragmentが大幅に増えた → FragmentでViewが作られている
  • ViewModelの数が大幅に増えた
  • Repositoryが大幅に増えた

→ ViewModel、Repository経由でのDBアクセスへの書き換えが進んでいる

  • Realmは変わらないがRoomが増えている → 新規のテーブルがRoomで作られている

逆に、改悪した点は特に見受けられないかなと思います。

ステップ数からわかること

種類 条件 コマンド
平均 202 拡張子が.javaのファイルの行数の平均 wc -l /*.java | sort | sed '$d' | awk '{n += $1}{i +=1 }; END{print int(n/i) }'
80 拡張子が.ktのファイルの行数の平均 wc -l /*.kt | sort | sed '$d' | awk '{n += $1}{i +=1 }; END{print int(n/i) }'
中央値 90 拡張子が.javaのファイルの行数の中央値
35 拡張子が.ktのファイルの行数の中央値
長大ファイル 20 拡張子が.javaのファイルの1000行を超えているファイル数
0 拡張子が.ktのファイルの1000行を超えているファイル数

去年と比べての改善点

  • Javaファイルの行数が減少傾向
  • Kotlinは平均が少し上がっている

  • Kotlinで書いているViewModelでロジックが詰め込まれているファイルがあるためかなと予想している

  • 1000行越えのファイルが増えた

  • Realmのマイグレーションファイルが1000行を超えてしまったので+1になった

  • これをやってて気づいたのでこれから分割する予定

この1年での改善点

  1. packageの移動

  2. 設計方針で合意していた場所へほとんどのファイルを移動した。

  3. モジュール分割を始めた

  4. 修正による副作用の低減などを求めてモジュール分割をし始めた。
    まだまだやり始めで、3モジュールを切り出した程度ですが1歩前進といった感じ。

  5. 業務委託の方にガンガンリファクタリングをしてもらう体制になった

  6. 設計方針に沿ったMVVMの形にするために、釘宮さんをはじめ業務委託の方にリファクタリングをお願いすることにした。

  7. テストコードが大幅に増えた

  8. 新しいロジックに関しては基本的にテストを書いているのでどんどん増えています。

来年のやっていきたいこと

  1. リファクタリングの大幅な進捗

できれば、ほぼ全てのActivity/FragmentがMVVMな形になってるといいなと思いますがそれはちょっと夢を見過ぎかな…

  1. Crashlyticsの改善

現状が改善する価値があるくらいの数値なので、ここもテコ入れしていきたい

  1. 新しいことを始めたい

Jetpack ComposeやCameraXなど新しい技術の導入を進められればなと思っている

PS.

今回の記事を書くのにgrepの代わりにripgrepを使ってみましたが、すごい速くて快適だったのでおすすめです!

株式会社フォトラクションでは一緒に働く仲間を募集しています

【初学者向け】はじめての公開鍵認証を用いたSSH接続

0. はじめに

フォトラクションでWEBエンジニアを担当している桑畑です。

初学者の方向けに、公開鍵認証を利用したSSH接続について記述していきます。既に理解されてる方には、新しい知見は無いかと思います。

こちらのテーマ選定をした背景は、私自身が曖昧な理解で何とな〜く利用していたため、、、理解向上のために調べたことや、AWSのEC2を利用して実験したことを記事にしております。SSH接続や公開鍵認証に対して少しでもイメージが掴んで頂ける情報になっていれば嬉しいです。

理解が間違っている箇所、説明に不備がある点などがあればご指摘頂けたらと思います。

1. SSH

1-1. SSHとは

SSHとは、リモートのサーバー・PCに対してセキュアに遠隔操作を可能にする通信プロトコルです。「サーバー → サーバー」や「ローカルPC → サーバー」などといった遠隔にあるサーバーに対して、SSH接続を用いることで安全にアクセスし、操作することが可能となります。

1-2. SSHの利用用途

SSH接続の利用用途は様々あるかと思います。

私がよく利用する機会は、ローカルPCからAWS-EC2インスタンスに対して接続する際に用います。SSH接続をしてEC2インスタンスのサーバー内を操作したり、scpコマンドでファイル転送をしたりしています。

1-3. SSHサーバー、SSHクライアント

SSH接続する側とSSH接続される側で、呼称が異なります。SSH接続をリクエストする側をSSHクライアントと言います。逆に、リクエストされる側をSSHサーバーと言います。ローカルPCからAWS-EC2インスタンスに対して接続する際には、ローカルPCがSSHクライアントであり、EC2インスタンスSSHサーバーです。

2. 公開鍵認証

2-1. 公開鍵認証とは

公開鍵認証とは、鍵(key)を利用して、通信の内容を秘匿にする仕組み・方法のことを指します。公開鍵認証でも幾つか手法があるようですが、一般的に用いられるのは鍵(key)は、公開鍵と秘密鍵の2種類のペアを用いることによって外部からの盗聴を防ぐ仕組みです。

2-2. 秘密鍵と公開鍵

秘密鍵と公開鍵とは何でしょうか。2つの鍵を理解するための概念として、情報を秘匿にして通信をするために『暗号化』と『復号化』という処理が存在します。文字通りではありますが、暗号化は、情報を外部から読み解け無い情報に変換します。 復号化は、暗号化された情報を複号して読み解ける状態にします。2種類の鍵を利用して外部から盗聴されることを防ぎます。

image_01

公開鍵 平文(暗号化されていない情報)を暗号化する際に用います。公開鍵は秘密鍵を利用して作成されます。通信対象であれば、公開鍵を複数人でも持つことが可能です。極端な話、公開鍵はばら撒いても問題にはなりません。 秘密鍵 暗号化された情報を平文へ複号する際に用います。秘密鍵は他人に公開するのはNGです。 暗号化の方式は複数存在するようです。「RSA」「DSA」「ECDSA」など、色々な方法があるようです。

3. 公開鍵認証を用いたSSH接続の実験 ~ 秘密鍵を発行していないサーバーへSSH接続 ~

最後に、EC2インスタンスで公開鍵認証を用いたSSH接続を試みます。

理解を深めるために、EC2インスタンスが発行していない秘密鍵を利用してSSH接続をします。

EC2-01、EC2-02という2つのインスタンスを用意し、それぞれのインスタンスから別々のキーペアを作成します。(別の秘密鍵をダウンロードします。)最終的には、EC2-01の秘密鍵を用いて、EC2-02にSSH接続をしてみます。※添付画像参照

3-1. EC2インスタンスが発行した秘密鍵を用いてSSH接続

まず、それぞれのEC2にSSH接続が可能かを確認します。 EC2-01が発行した秘密鍵-01を利用してSSH接続 (コマンドの解説は省略)

// コマンド例
ssh -i ~/.ssh/ec2_01.pem ec2-user@{EC2-01のIP}

次に、EC2-02が発行した秘密鍵-02を利用すれば、EC2-02へSSH接続は可能です。

// コマンド例
ssh -i ~/.ssh/ec2_02.pem ec2-user@{EC2-02のIP}

3-2. 他のEC2インスタンスが発行した秘密鍵を用いてSSH接続 (失敗を確認)

最終的に実行したいコマンドを試しに実行します。EC2-01が発行した秘密鍵-01を利用して、EC2-02へSSH接続

// コマンド例
ssh -i ~/.ssh/ec2_01.pem ec2-user@{EC2-02のIP}

現時点では、EC2-01が発行した秘密鍵-01を利用して、EC2-02へSSH接続すると接続不可となってしまいます。失敗を確認できました。

3-3. 他のEC2インスタンスが発行した秘密鍵を用いてSSH接続を成功させる

公開鍵認証を正しく実行するためには、秘密鍵-01が発行した公開鍵-01がSSHサーバー側に存在する必要があります。この仕組みを利用して、EC2-01の公開鍵01をEC2-02へ配置します。

公開鍵のファイルは、SSHサーバーの~/.ssh/authorized_keys に存在します。今回のSSH接続でいうと、EC2インスタンス~/.ssh/authorized_keys のファイルに記述されています。

下記のような文字列です。

// EC2−01インスタンス  ~/.ssh/authorized_keysファイル内
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCERdTPh2CG81cdU67g0sSxc8ghvbGH4Agjk63BsaPh+07X0u+xcXL5WwXxkcqdmacU7FCij+HOyrkzflEpjzILs4QHzcayQAUuHqIsB80X/IB416qyRNau3pBfwUrB3oeRY47rq3moeY6jiXKOoZt1qPhe4Jr3f+cd5qbtpCvkMc3XnPuJEtlqrvLxWWR2N3KCfXdSiV6SRPtTSrQaouybayWKXKOqXoXGKtn6gvdhwQYD+4dImYL0CDEWIlIyB6JS5XhtSwh8hScr77BdAp2lqECearIh+9xI1hx0pe5CDmnV9hI0ASUJSGtlXPM EC2-01

EC-01の公開鍵を、EC2-02の~/.ssh/authorized_keys に追加します。

// EC2−02インスタンス  ~/.ssh/authorized_keysファイル内
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCERdTPh2CG81cdU67g0sSxc8ghvbGH4Agjk63BsaPh+07X0u+xcXL5WwXxkcqdmacU7FCij+HOyrkzflEpjzILs4QHzcayQAUuHqIsB80X/IB416qyRNau3pBfwUrB3oeRY47rq3moeY6jiXKOoZt1qPhe4Jr3f+cd5qbtpCvkMc3XnPuJEtlqrvLxWWR2N3KCfXdSiV6SRPtTSrQaouybayWKXKOqXoXGKtn6htSwh8hScr77BdAp2lqECearIh+9xI1hx0pe5CDmnV9hI0A EC2-01
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD4gm2J7iXdRpHaIuLFenSNyC+Qc72ZJeNwsg8QKsrvFuo4tWiHWLH3hS199gKFq4QXlf8aaC3c3n6MD6i6hBm1xkHjfM1suSAQX7vL6QyW75G/D+uC/cQf8RRM/fClELMtY/CQqGqyaaFjHt1tMqJYOvzi3jl9jBGQ87PVEyiRnHdOX9jmyKTAW86FyRlhFY708ZTySry9c8DiPVbuNTllWVX+GoHDwI/heINoL97q7VlYCuYPHPE6+BIYxWqrAUwGqj/8IvcuLr8q1ZAaKh8 EC2-02

3-2. 他のEC2インスタンスが発行した秘密鍵を用いてSSH接続 (失敗を確認)で失敗したコマンドを再度実行します。

// コマンド例
ssh -i ~/.ssh/ec2_01.pem ec2-user@{EC2-02のIP}

これで、EC2-01が発行した秘密鍵を用いて、EC2-02へと公開鍵認証を利用したSSH接続が確認できました。

4. おわりに

如何でしょうか。説明を省略した部分や、理解の浅い部分もあったかと思いますが、SSH接続や公開鍵認証について少しでもイメージを湧いて頂けたのであれば嬉しく思います。

AWS APIgateway + Lambda を環境ごとに切り分けるTips

こんにちは!株式会社フォトラクションでWEB開発をしている下川原です。

Photoruction Advent Calendar 2022の7日目の記事になります。

はじめに

どんな人がこの記事を読むと幸せになるか。

AWS APIgateway + Lambdaを環境ごとに分ける!

1. 下準備

API Gatewayを既に作成済みで、1つ以上のメソッドがあることが重要!

検証用、本番用のLambda関数ができていることが重要!

AWSLambdaを環境ごとにわける方法は、前回の記事を参考に

AWS Lambdaで効率よく本番・検証環境をわける!

2. AWSLambdaをエイリアスで呼び出す

Lastateを使用する
arn:aws:lambda:ap-northeast-1:000000000:function:myTestsFunctions

エイリアスstagingを使用する
arn:aws:lambda:ap-northeast-1:000000000:function:myTestsFunctions:staging

Lambdaを呼び出す際に末尾に:{alias}をつけることで、エイリアスを呼び出すことが可能である

そのため、APIGatewayに設定Lambda名を工夫する必要がある

統合リクエストから、Lambda関数末尾に以下のように追加する

関数名:${stageVariables.alias}

追加を行うと、エイリアス関数に権限を追加するコマンドが表示されるので、AWS CLIでコピーして実行する

コピーしてそのまま実行はできないので注意

${stageVariables.alias}

かならずエイリアス関数名に置換してから実行すること ※すでに存在するエイリアス関数すべて実行しておくと良い

3. ステージを作成する

リソースのアクションからAPIのデプロイを選択すると、新しいステージを作ることができる

  • デプロイされるステージ
    • [新しいステージ]を選択
  • ステージ名
    • 検証用や本番用のものとわかりやすいのが望ましい
  • ステージの説明
    • 用途を記載
  • デプロイメントの説明

    • デプロイ時の更新内容などあるとわかりやすい
  • ステージ変数を設定する

    ステージ変数を設定することで、Lambda関数を呼び出す際にエイリアスで実行することができる。

  • 名前
    • 今回は、手順.2で${stageVariables.alias}を設定しているので、alias を入力
  • APIを更新するとき

    APIを更新したいときは、手順3のようにアクションからAPIのデプロイを行うことで

    作成したステージにAPI更新を反映することができる

6.APIGatewayステージを利用した運用方法

上記までの手順で、APIGatewayをステージごとにわけることができた。

実際に運用する際は、カスタムドメインから開発用、検証用、本番用のドメインを選択し

カスタムドメインAPIマッピングで、作成したそれぞれのAPIGatewayステージを紐づけることができる

参考:REST API の API マッピングの使用

さいごに

APIGatewayで、環境をわけてLambdaを使うことで

柔軟なAPI開発を行うことができる。

ぜひ、煩雑な環境管理から開放されて、

開発に集中できるよう活用してほしい

参考

AWS Lambda関数のエイリアス使用

株式会社フォトラクションでは一緒に働く仲間を募集しています

プロダクトバックログアイテムリファインメントのご紹介

こんにちは!フォトラクションでプロダクトマネージャーの黒田です!

Photoruction Advent Calendar 2022の6日目の記事になります。

今回はプロダクトをより良いものにするために、個人ではなくチームとしてやるべきことを全員が理解・把握し、同じ目線で開発を進めるために私のグループが行なっているプロダクトバックログアイテム(以下、PBI)リファインメントをご紹介させていただきます。

はじめに

私が管掌している開発グループの構成は1PO(私)、2チーム(WEBチーム、Mobileチームそれぞれエンジニア5名)のスクラム体制で構成しています。

この体制は10月からスタートさせた新しいグループなのですが、まず第一に目指した形としては、俗人的な開発体験ではなくチーム力で課題解決やプロダクトを最速でブラッシュアップできるよう『俗人開発』→『チーム開発』にシフトするというものでした。

過去の体制ではどうしても開発案件と開発者個人が密接に紐づいてしまい、仕様や開発ノウハウがそこで閉じてしまい個人の負担もそうですが、チームの開発体験としても決して満足できる状態とは言えない状況でした。

まずはチームとしてやるべきことを全員が理解し、各自が自走して気持ちよく開発が進められる取り組みの一環としてPBIリファインメントを実施しています。

課題管理について

私たちのグループでは以下のルールに基づいて課題を分類しており、Jira Softwareにて課題管理を行なっています。

Epic

顧客のニーズやリクエスト、課題に基づいて特定のタスクに細分化できるまとまった作業。

POが作成及び管理を行う。

Story

Epicに紐づく要件またはリクエストをエンドユーザーの観点から簡潔にまとめたもの。

POが作成し、リファインメントでエンジニアと認識の擦り合わせ、調整を行う。

Task

Storyに紐づく実作業タスクを大きくても1日以内に収まる粒度で完結にまとめたもの。

リファインメントにて整理、洗い出しを行う。

リファインメントのゴール

  • Epicごとに受け入れ要件をチームエンジニア全員が理解・把握する
  • PBIを具体化することでエンジニアが、迷わず作業が進められる状態にする
  • Taskの優先順位をつける
  • Taskのストーリーポイントを見積る

リファインメントの流れ

前提として以下の中で進めています。

  • リファインメントにかける時間は1スプリント(1週間)に1〜2時間
  • 参加者はPOとチームエンジニア
  • その回に実施するEpic対象はPOが決める
  • Miroボードにてエンジニア全員で共同作業する

流れ

  1. POからエンジニアに対して事前に用意していたEpicとそれに紐づくStoryの詳細を共有する
  2. エンジニア目線でStoryの補足・調整を行う
  3. Story単位でTaskの洗い出しを行う
  4. Task単位でストーリーポイントの見積りを行う

リファインメント後

洗い出したTaskをPOがJiraのバックログに起票し、次のスプリントプランニング以降で計画していく

工夫している点


リファインメント時はMiro上にCardをどんどん並べてTaskの洗い出しを行います。

TaskのストーリーポイントはMiroのプランニングポーカー機能(Estimation)を利用することでスムーズに見積もりを実施しています。

MiroとJiraを連携(Jira Card)しておくことで、Miro上のCardをJiraチケットに変換したり、Jiraのチケットを呼び出してCardとして並べたりすることができます。

Miroカード→Jiraチケットへの変換

もちろんJira側でチケットの状態等を変更した場合はMiro側にもその内容が自動で反映されるので、副産物としてではありますが案件全体を俯瞰して開発進捗が見れたりとこの運用の仕方を重宝しています(笑)

まとめ

やっていることとしては一般的な部分が多いとか思いますが、チーム全員が同じ目線でこの一連の作業に取り組むことに意義があると思っています。

リファインメントの場で企画に対してPO⇄エンジニアまたはエンジニア同士で議論や認識合わせを密に行うことで、後の開発や出来に大きく影響してくる大切なイベントの一つなので一部ではありますがご紹介させていただきました。

メンバーからも、以前と比べて日常でのチーム内のコミュニケーションも全員が同じレベルで理解・把握しているので意思疎通が取れてより開発がスムーズになったと声もあがっていたりするので、継続しつつ一丸となってより良いプロダクトを開発していけたらと思います!

株式会社フォトラクションでは一緒に働く仲間を募集しています

知識0から約半年間ほどスクラム開発をやってみた結果

はじめに


Photoruction Advent Calendar 2022の5日目の記事です!

アドカレ運営委員長こと、CREチームの田中です!

現在、CRE(Customer Reliability Engineering)のリーダーをやっていますが、

少し前まで、スクラムチームでスクラムマスターをやっていました。

せっかく、認定スクラムマスターを取得して、スクラム開発を取り組んでいたので、いい機会なので、その時の棚卸をしようと思います。(認定スクラムマスターも取得したしね。。)

スクラム開発ってなに?


スクラムとはアジャイル開発の考え方の手法の1つです。

その中でも、スクラム開発は導入のしやすさから、おそらく一番ポピュラーな手法です。

大元のアジャイル(Agile)は俊敏性を意味するワードで、

スクラムは、ラグビー用語で、肩を組んで押し込んでいくプレーのことです。

イメージはこんな感じ。

スクラム開発」という文脈では、チームワーク、コミュニケーションを重視し、

シンプルなロールやルールに基づいて、アジャイル開発の理念の実現を達成しようとするフレームワークを意味します。

アジャイル開発の理念については、アジャイルソフトウェア宣言が有名なので、気になる方は、一読してみるといいかもしれません。

https://agilemanifesto.org/iso/ja/manifesto.html

なんでアジャイル(スクラム)開発ってできたの?


アジャイル開発という考え方が生まれたのは、約20年前(2001年がアジャイル元年らしい)。

それまでは、

と、一定の開発期間を設けて、一度にまとめてドン!とリリースまで突き進むウォーターフォール開発が主流でした(もちろん今でも全然採用されている)。

ウォーターフォール開発は、開発に入る前段階で、完璧に要件定義や仕様が固まった状態であることが前提となる開発なのですが、

これだと、どこかの工程で問題発生した際に、軌道修正がしづらく、リリース計画の大幅な見直しが発生しやすいです。

VUCA(Volatility: 変動性, Uncertainty: 不確実性, Complexity: 複雑性, Ambiguity: 曖昧性 の頭文字をとった言葉)という言葉が巷に広がって久しい昨今、ビジネス環境は予測不可能な状況になり、不確実性を極めています。

アジャイル開発は、こうした不確実性というリスクを、「小さく」開発フローを回すことで、そのリスクに対応していこうという考えから生ました。

つまり、アジャイル開発とは、

大きな「分からない」から、小さな「分かる」を短期間の積み上げていくことで、

小さな「分からない」に限定していくことを目指す開発です。

上記はあくまで、私の解釈を言葉にしたものですが、こう捉えていくと、

エンジニアリング以外のビジネスシーンにも、有用で、何かしらのエッセンスになりうるテーマかもしれません。

認定スクラムマスター研修で学んだこと


認定スクラムマスターの講習で、個人的に面白いと思ったことがいくつかあります。

スクラムの具体的な仕組みに関して知りたい方は、スクラムガイドブック(日本語版)を見てもらうのがいいかと思いますので、そちらをチェックしてみてください。ここでは長くなるので割愛させていただきますmm

スクラムは楽しんだもん勝ち

大前提として、スクラムはゲームだ。

スクラムは開発チームとステークホルダーの幸福度を追求するゲームでシンプルなフレームワークだよ。

というのが、講習の際、講師の方が仰っていました。

(研修の資料の一部から抜粋)

チームとしてワークさせ、チームメンバーが楽しんで開発に臨める組織状態にするよう、サポートするのが、スクラムマスターの役割ということです。

その際、心理的安全性」を高めることが重要であると、述べられていました。

ハーバードビジネスレビューでは、なんでも言い合えるチーム作りをするために、心理的安全性の重要性が説かれています。

高い心理的安全性であれば、イノベーションを生み出すような高いパフォーマンスを引き出しますが、

低い心理的安全性の状態では、自己防衛を目的とする恐怖反応を引き出してしまいます。

具体的には、チームメンバーが質問をしたり、間違いを認めたり、アイデアを模索したり、現状に挑戦するようなことをやめてしまいます。それは、アジャイルではないです。

スクラムはイベントがたくさんあり、必然的にコミュニケーション量が多くなります。

その際、心理的安全性を担保するように、特に初期では、気をつける必要があります。

スクラムの前提のお話

次に、日本でスクラム開発を行う際、日本と欧米のエンジニアのスキルの前提の違いについて念頭におかないといけないな〜と

講習中に感じた事柄です。

スクラム開発の目標に、「自己組織化」というワードがあります。

自己組織化とは、誰かからの指示に従う形ではなく、チームメンバーがチームとして最適な方法を判断し行動していく状態です。

何か問題にぶち当たった時に、チームで解決できるスキルがある(あるいは、スキルを獲得できる方法を知っている)。

欧米のエンジニアはフルスタックが前提(フロントサイドもサーバーサイドもアプリ側も対応できる)で、 職能が分化されている日本のエンジニアとは前提が異なります。

実際、研修中、質問で、どうそのギャップを超えていけるかと質問があり、その回答としては、

Mob(モブプロプログラミング)がおすすめだとの話でした。

ここで、あえてこの話題に触れたのは、前提が異なるから、スクラムが実現できないという話ではなく、

スクラムの体現するために、前提の違いを念頭に置くべきという考えからです。

実際、そのギャップを乗り越え、「自己組織化」できている組織を作るのはめちゃくちゃハードなことだと思われます(どうやるんですかね。。)

衝撃の事実

海外事例のお話を聞いていると、海外の先進的なアジャイル企業では最早スクラムが使われていないらしい。。

具体的には、今話題のイーロンマスクがCEOを務める、テスラやスペースXなどです。

スクラム開発を極めた結果、スクラムチームは、自己組織化ができており、スクラムマスターが必要なくなります(1人1人がスクラムマスターになっている)。AIに代替されているようです。

Twitterで、リモートワークを撤廃することだったり、小規模チームを作っていくみたいなことを宣言しているのは、

テスラやスペースXのスクラム開発の経験からなんだろうな〜と邪推してます。

スクラム開発で試したこと


半年と少しほど、スクラムマスターとして、スクラムに取り組みました。

施策は色々行いましたが、チームとして大きく意思決定したのは3点かなと。

試したこと

  • モブプロをやってみた
  • ベロシティの算出
  • リファインメントカフェの実施

モブプロに関して

チームの自己組織化を目指すに当たって、Mobしかない!ということを講習で聞いたので、すぐに取り入れてみました。

ただ、チームは、Webエンジニアだけでなく、iOSエンジニア、Androidエンジニア含めて、やってみよう!みたいな導入の仕方をしてしまい、そこは現実的ではなかったよねってことで、そこは諦めました。

適宜問題に当たったら、Google Meetやslackのハドルを繋げて、コミュニケーションを取るような形で進めていきました。

コミュニケーションの促進や心理的安全性の向上という意味では、上手くいった。

自己組織化を目指すという意味では、成果不十分みたいな総括かなと思います。

ベロシティの算出

複雑性に対して対応するために、チームとしての生産性を見える化する必要があります。

ベロシティとは、チームが作業を進めるための生産性を意味します。

ベロシティは、開発完了見込みの予測や、チームの成長を把握するために役立ちます。

プロジェクトに対し、ストーリーポイント(作業完了に必要な見積もりの尺度)を振り、ベロシティの算出してみようと試みました。

結論から言うと、これは上手く回りそうになく、やらないという意思決定をしました。

というのも、スクラムチームが9名で、Webエンジニア、iOSエンジニア、Androidエンジニアが入り混じっており、1つのプロジェクトの開発というより、それぞれのエンジニアが異なる案件を抱えるという状況でした。

となると、ベロシティ(チームとしての生産性)を算出したとして、その値にそれほどの価値が生まれないだろうということ。

プロジェクトごとにチームとして、ストーリーポイントを振るわけですが、技術領域が異なると、多く見積もってしまうという問題がありました。

まぁ、WebならWebのエンジニアだけで割り振ればいいのはいいのですが、ベロシティという値に集約されることを考えると、歪な数値になるということで、諦めました。今振り返ってみても、前提条件的に難しい気がします。

リファインメントカフェ

リファインメント(洗練という意味)スクラム内のイベントではなく、アクティビティ(必要であれば実施する)であると、講習で聞いたので、こちらもすぐに取り入れました。

これはすごく良かったです。

デイリースクラムを朝やっていて、その直後に、仕様のすり合わせや確認が必要であれば、開催みたいな感じで頻繁に行っていました。

効果としては、仕様の変更や出戻りのコストは減ったと思います。

また、リファインメントカフェのおかげかは微妙ですが、リファインメントカフェを始めてから、ちょっとした確認を取る機会が増えた気がします。

まとめ


透明性→検査→適応のサイクルを最大化するという観点から見たら、ベロシティ計測を捨てているので、正しいスクラムの運用ではなかったかもしれないです。

ただ、総括としては、雰囲気良く開発ができたので、悪くはなかったと思います。

むしろ、チームビルディングの観点では、うまく機能していました。

チーム再編の際には、メンバーみんな別れを惜しんだくらいですし(別に社内にいるんですけどねw)。

スクラムマスターとして、どこまで貢献できたかと問われると自信はないですが、一定の成功体験は積めたので、

これを糧に今のチームでもスクラムのエッセンスを取り入れていきます!(次はそんな記事を書きます!!)

株式会社フォトラクションでは一緒に働く仲間を募集しています