OmniAICreator/Qiita-1.07M huggingface dataset:
Amazon DynamoDBのキャパシティユニット消費パターンを整理してみた

AWS DVA（AWS Certified Developer - Associate）試験の勉強をするなかで、Amazon DynamoDBのキャパシティユニットの消費パターンがややこしかったので整理してみます。

というか公式ドキュメントがテキストの羅列で非常に見づらかったため、表形式にまとめました。


### 公式ドキュメント

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html


### 読み込みリクエストの場合

整合性レベルが上がるたび、ユニット数が倍になっていくイメージです。

| リクエストの種類 | 基準サイズ | 必要ユニット数 |
|:-:|:-:|:-:|
| 結果整合性 | 4KB以下 | 0.5 RCU |
| 強力な整合性  | 4KB以下 | 1 RCU |
| トランザクション | 4KB以下 | 2 RCU |


### 書き込みリクエストの場合

| リクエストの種類 | 基準サイズ | 必要ユニット数 |
|:-:|:-:|:-:|
| 通常 | 1KB以下 | 1 WCU |
| トランザクション | 1KB以下 | 2 WCU |


### 補足

「トランザクション」というのは、通常の単発のDBへの読み書きだけでなく、アプリケーションが行う一連のトランザクション動作のあいだ一貫性を保証してくれるモードとなります。トランザクションの失敗時は読み込みもキャンセルされます。

つまり、「強力な整合性」よりもさらに要求が高いので倍のキャパシティユニットが必要ということですね。
Okta - AD->Oktaの同期をOkta->ADに切り替えた話

# はじめに

1年半くらい前になりますがそれまでオンプレのActive DirectoryからOkta含む各種サービスにユーザーを同期していたものを、Oktaから同期するように変更しました。

その時どんなことやったかなどを簡単に記載できればと思います。


# 当時の構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350435/e7ae83d9-7043-19c5-95c3-1295a788144d.png)

Windows Server上に構築した Active Directory から図に記載のツールを使用してユーザーを同期していました。


# 変更後の構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350435/b00c2966-bd17-e82f-9ca0-ee251d0f79b6.png)

ADやLDAPにはOktaのエージェントを使用し、SaaSに対してはSCIMでプロビジョニングしています。

# 移行による一般ユーザーへの影響

基本的には裏側の同期の仕組みの変更になりますが、どうしても1つだけ一般スタッフに対応してもらわないといけないことがありました。

それはOktaでのパスワード設定です。

AD->Oktaへの同期ではAD Agentを利用しており、かつDelegated Authenticationを有効にしていました。
この構成の場合 AD -> Oktaにはパスワードが同期されないため、Oktaではユーザーのパスワードを保持していない状態になっています。

そのため、すべての移行が完了した後、すべての一般ユーザーにはパスワードを再登録してもらう必要がありました。


# 移行によるシステム担当者への影響

準備と影響の関係でLDAPのプロバイダサーバーを新規で構築しなおしました。
そのため、各LDAPコンシューマを管理しているシステムの担当者にはLDAPの再起動をしてもらう必要がありました。

# 切り替え当日までの準備

各種切り替えに向けて当日までに以下のようなことをしました。
（検証とかは別でやってます）

1. 新規LDAPサーバーの構築及びAgentインストール
1. OktaユーザープロファイルにAttributeを追加及び値設定
    - OktaがソースとなることでAttributeやグループルールを使っていろいろできそうだったので追加しました。
1. ADのOU構成変更
    - 変更するならこのタイミングしかない！ということで変えました。
1. その他スタッフへの案内など


# 切り替え当日

1. AD -> LDAP 同期の停止
1. Azure Active Directory Connect の停止
1. Google Cloiud Directory Sync の停止
1. AD -> Okta へのインポートの停止
    - Delegated Authentication の無効化もこのタイミングでした。
    - この時点でOktaにはパスワードが存在しないため、ユーザーは誰もOktaにログインすることができなくなります。
1. Okta -> AD へのプロビジョニングの開始
1. Okta -> Google Workspace へのプロビジョニング設定
1. Okta -> Microsoft Entra ID へのプロビジョニング設定
1. Okta -> LDAP へのプロビジョニング開始
1. APIを使用してユーザーの初期パスワードを指定＆パスワードを期限切れに設定
    - 初期パスワードを期限切れにすることで、ユーザーが翌日ログインした際に必ず自分のパスワードを設定させるようにしています。
1. プロビジョニング設定のうちSync passswordを有効化
1. LDAPプロバイダのDNS設定変更
    - 新規構築しているためコンシューマが参照する先のLDAPプロバイダをDNSで切り替えました。

# 切り替え翌日

- 一般ユーザーによる初回ログイン＆パスワード設定
- システム管理者によるLDAPの再起動

# ディレクトリ同期の切り替えについて

裏側の仕組みのため一般ユーザーからはほぼ見えない部分です。
しかし、同期の切り替えの順番を間違えるとパスワードが正しく同期されなかったり、ユーザーがログインできなくなってしまうなど業務に直結する影響が発生する可能性があります。

そのため、切り替えの計画では、
- どのタイミングでどの切り替えを実施すべきか
- その時、誰がどこにどのパスワードでログインすることができるのか

といったことにとても注意しました。
その甲斐があってか、本番切替では特段想定外の影響もなく完了することができました。


# さいごに

今回ざっくりとこんなことをしたという内容を記載しました。
もし機会があればもう少し詳しめに記載できたらなと思います。

また、今回アドベントカレンダーでOktaに関するいろいろなことを記載してきました。
記載する中で改めて、自身の理解が足りていない部分が見つかったり、試したい機能が見つかったりと新しい発見がありました。
数年間のOktaの管理者としての経験を振り返るよい機会だったと思います。
ここまで記事をお読みいただいた皆様ありがとうございました。
LeetCode備忘録_その3_Arrays & Hashing_Valid Anagram

# 概要
- LeetCodeを始めました。１テーマごとに解法と学びをメモします
- 今回テーマは「Arrays & Hashing_Valid Anagram」

# テーマ詳細
### 原文
Given two strings s and t, return true if t is an anagram of s, and false otherwise.

An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

Example 1:

Input: s = "anagram", t = "nagaram"
Output: true
Example 2:

Input: s = "rat", t = "car"
Output: false

### 日本語訳
※G翻訳
2 つの文字列 s と t を指定すると、t が s のアナグラムである場合は true を返し、そうでない場合は false を返します。 アナグラムは、通常は元の文字をすべて 1 回だけ使用して、別の単語またはフレーズの文字を再配置することによって形成された単語またはフレーズです。 例 1: 入力: s = "anagram"、t = "nagaram" 出力: true 例 2: 入力: s = "rat"、t = "car" 出力: false

# 解法
```
class Solution(object):
    def isAnagram(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        if len(s) != len(t):
            return False
        elif set(s) != set(t):
            return False
        else:
            for chr in set(s):
                if s.count(chr) != t.count(chr):
                    return False
                else:
                    pass
        return True
```
https://leetcode.com/problems/valid-anagram/submissions/1115855825
# 結果
- Runtime:21ms  
- Beats 95.11% of users with Python 　※投稿日時点

# 思想
- アナグラムかどうかを判定できる条件として以下を始めに思いついた
    1. 文字数が同じ
    1. 含まれるアルファベットの種類が同じ

- 上記２つはfor文を用いなくても計算負荷少なく判定できるので、まず初めにこれらのフィルターを設けることにした
- 上記２つでは"aabb", "abbbのようなケースに対応できないことに気づく。これらが生じるケースは割合的に少なさそうなのでfor文を用いることにした
    3. 1単語目が含むアルファベットのユニークを取って、１文字ごとのcount数が2単語目と一致すること

# 学び
- 判定条件が複数ある場合は、処理が少ない条件から適用して判定できない場合は後続の判定条件に落としていくほうが効率が良い
- 上記の優先度は、基本的には処理量で良いと思うが、該当ケースが生じる確率も考慮に加えるとなお良い

# 感想
- 単語のユニークな文字を取ってくる方法は[以前の投稿](https://qiita.com/iCO22/items/58d069aa9c6628c1f298#%E6%A6%82%E8%A6%81)で学んだsetを使った方法で実施した
- LeetCodeで学んだ知識を早速使えて嬉しかった
- 実施時間が上位5%を取れて嬉しかった
Conduit備忘録 -フォーク編-

Conduit備忘録 -フォーク編-
ApprenticeにてCounduitというクローンサイトを Railsで実装しました。その手順についての備忘録です💡


## [RealWorld Starter Kit](https://github.com/gothinkster/realworld-starter-kit) をフォークした手順


1. **GitHubにアクセス**: まず、GitHubアカウントにログインする。
2. **RealWorld Starter Kitのリポジトリに行く**: 次に、[RealWorld Starter Kitのリポジトリ](https://github.com/gothinkster/realworld-starter-kit)にアクセス。
3. **フォークする**: リポジトリページの右上にある「Fork」ボタンをクリックします。
4. これにより、GitHubアカウントにリポジトリのコピーが作成される。
5. **ローカルにクローン**: フォークしたリポジトリをあなたのローカルにクローンする。
    
    ターミナルにて、下記のコマンドを打つ
    

```bash
git clone [自分のフォークしたリポジトリのURL]
```

### 

## フォークとは？

「フォーク（Fork）」は、ソフトウェア開発においてよく使われる用語で、特にGitHubなどのバージョン管理システムで重要

### **フォークの意味**

- **リポジトリのコピーを作成**: フォークは、GitHub上の既存のリポジトリ（プロジェクトのファイルと履歴が含まれるストレージ場所）の完全なコピーが自分のGitHubアカウント下に作成される。
- **独立した開発**: フォークしたリポジトリは、オリジナルのリポジトリから独立していて、フォークしたユーザーが自由に変更できます。これにより、元のリポジトリに影響を与えることなく、新しい機能の追加やバグの修正などが可能になる。
- **オープンソースプロジェクトへの貢献**: オープンソースプロジェクトでは、誰でもリポジトリをフォークしてプロジェクトに貢献できます。開発者は自分の変更をオリジナルのリポジトリに統合するために「プルリクエスト」を送ることが一般的。
- 

### **フォークのプロセス**

1. **GitHubリポジトリへのアクセス**: まず、フォークしたいGitHubリポジトリにアクセスします。
2. **フォークボタンのクリック**: リポジトリページの右上にある「Fork」ボタンをクリックします。
3. **自分のアカウントにコピーが作成される**: これにより、そのリポジトリのコピーが自分のGitHubアカウントに作成される。💡これが「フォーク」
    
    - フォークは、オープンソースプロジェクトに貢献する際によく使われる。自分のアカウントにコピーしたリポジトリで変更を加えた後、それをオリジナルのリポジトリに「プルリクエスト」として提案することができる。
    - フォークは、オリジナルのリポジトリとの関連を保ちつつ、独自の変更を加えるために使用される。
    
    ## **クローン (Clone)とは？**
    
    - クローンはリポジトリの完全なコピーをローカルコンピュータに作成する行為。
    - これにより、オフラインで作業を行い、後で変更をリモートリポジトリ（GitHub上のリポジトリ）にプッシュする事ができる。
    - クローンは開発作業をローカルで行うために使われ、フォークしたリポジトリやオリジナルのリポジトリを含む、任意のGitHubリポジトリをクローンすることができる。
    - クローンは、リポジトリとそのすべての履歴をローカルに持ってくることを意味する！

### フォークはGitHub上でのリポジトリのコピー（主に協力や貢献のため）

### クローンはリポジトリのローカルコピー（開発作業のため）
みなさんKotlin Scriptingつかってます？


この記事は[株式会社ヘンリーAdvent Calendar 2023](https://qiita.com/advent-calendar/2023/henry)の18日目の記事です。昨日は[@u-ichi](https://qiita.com/u-ichi)による[ヘンリーに入社しました(8ヶ月前に)](https://u1.hatenablog.com/entry/2023/12/17/133902)でした。

みなさん、こんにちは。株式会社ヘンリーで開発者としてはたらいてるわくわくです。今日は Kotlin Scripting についてご紹介となぜ使うのかということについて軽くご紹介させていただきたいです。

## Kotlin Scripting
[kotlinlang.org](https://kotlinlang.org/)の説明によると以下のように書かれております。

>_Kotlin scripting_ is the technology that enables executing Kotlin code as scripts without prior compilation or packaging into executables.

事前にコンパイルしたりしなくてもKotlinコードをスクリプトとして実行できますよーって話ですね。

なるほどなるほど。サクッとスクリプト書きたいな～みたいなときに使えそうですね。

### 複数のプログラミング言語を扱うということ
ちょっと話はずれますが、みなさんはいくつのプログラミング言語を書くことができますか？レベルの差はあれど、複数の言語を読み書きできるよという方も少なくはないと思います。

たとえばヘンリー社内では、Kotlin, TypeScriptが多く書かれておりますが、簡単なスクリプトについてはRubyやPythonを利用する方もいます。

しかし私は、頭を切り替えることが苦手なのですぐにほかの言語に頭を切り替えてささっと書くことが苦手です。バックエンド(Kotlin)とフロントエンド(TypeScript)を行き来しているときなんかは TypeScript のコードに `val` と書き、Kotlinのコードには `const` と書いてしまうポンコツっぷりです。

そんな私がサクッとスクリプトをRubyやほかの言語で書くのはできれば避けたく、Kotlin Scriptingのようなものが提供されていることはすごくうれしく思います。

## ミニマムサンプル
話を戻しましょう。必要なものをインストールしてミニマムサンプルを実行してみます。

### 必要なこと
- Kotlinのインストール
	- SDKMAN! でも Homebrew でもなんでもかまいませんが Kotlin をインストールしてください。

### Hello, World! する
`.kts` という拡張子でファイルを保存します。ここでは `hello.kts` としましょう
```kotlin
println("Hello, World!")
```

以下のように実行する
```
> kotlin hello.kts
Hello, World!
```

Hello, Worldできました。便利！ほかには何もいりません。

## ライブラリを使おう
単純に Kotlin を使ってサクッとスクリプトを作れるだけでも便利ですが、使い慣れたライブラリを利用することも簡単です。

今度はファイル名を `.main.kts` という拡張子で保存しましょう。ここでは `script.main.kts` としましょう。

OkHttpを使って適当なGETリクエストをなげてみます。`https://httpbin.org/anything` はリクエストの内容をそっくりそのままJson形式で返してくれます。
```kotlin
@file:Repository("https://repo1.maven.org/maven2/")
@file:DependsOn("com.squareup.okhttp3:okhttp:4.11.0")

import okhttp3.OkHttpClient
import okhttp3.Request

val client = OkHttpClient()
        .newBuilder()
        .build()
val request = Request.Builder().url("https://httpbin.org/anything")
        .get()
        .build()
val response = client.newCall(request).execute()

println(response.body?.string())
```

```
> kotlin script.main.kts
たぶんここになんか知らのJsonが帰ってきます。
```

## あとほんの少し便利にする
どうでしょうか？以上で「お、なかなかいけるやん Kotlin Scripting」って思ってくれたかと思います。でも

いや～毎回 `kotlin xxx.kts` ってするのめんどくさいな～って人いらっしゃいますよね。はい、shebang を指定しましょう。いい感じに実行できます。

前述の script.main.kts に shebang を追加しましょう。
追加する shebang は `#!/usr/bin/env kotlin` です。

```kotlin
#!/usr/bin/env kotlin // 今回追加したshebang

@file:Repository("https://repo1.maven.org/maven2/")
@file:DependsOn("com.squareup.okhttp3:okhttp:4.11.0")

import okhttp3.OkHttpClient
import okhttp3.Request

val client = OkHttpClient()
        .newBuilder()
        .build()
val request = Request.Builder().url("https://httpbin.org/anything")
        .get()
        .build()
val response = client.newCall(request).execute()

println(response.body?.string())
```

```
> chmod +x script.main.kts
> ./script.main.kts

さっきと同じ結果が表示されるはず。
```

どうですか？結構便利じゃないですか？知らなかった人はぜひ使ってみてくださいね。

## おわりに
これで良い感じにスクリプトをかけるようになりました。難点としてはエディタがやっぱりIntellijがないとしんどいなというところですね。気軽にスクリプトかくぞ～の気持ちでIntellijを立ち上げるのはちょっと重い。。けどまぁ受け入れましょう。

以上！この後のアドベントカレンダーもお楽しみください。
text-wrap: balance;試してみた

## これはなに

CSSの `text-wrap` プロパティは、テキストの折返しを制御します。
この `text-wrap` プロバティで、Chrome114以降で `text-wrap: balance;` がサポートされました。 

日本語だけの場合、よしなに調整できることが多いですが、海外に向けた言語対応も行っているサービスの場合、このCSSプロパティが活躍するイメージが持てました。

この記事では、`text-wrap: balance;`の挙動を確かめてみたいと思います。

## `text-wrap: balance;` とは

複数行のテキストがある場合、1行あたりの文字数を同じ文字数になるようにバランスを取ります。

## デモ

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="oNmrOMr" data-user="gilly135" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/gilly135/pen/oNmrOMr">
  text-wrap: balance</a> by gilly135 (<a href="https://codepen.io/gilly135">@gilly135</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## サポートブラウザ

2023年12月現在では、Can I useを見ると、Safariのサポートが追いついていないようです。
Safariでこの記事を読んでいる方は、きっと上記のデモの `text-wrap: balance;` がうまく動作せずに、そのまま文字が流れていると思います。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215239/58d4f09f-5c22-2be7-1d9d-7073a279f520.png)


## 注意点

### 6行の制限

[text-wrap - CSS: Cascading Style Sheets | MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/text-wrap) を見てみると、行数について記述がありました。

>the Chromium implementation uses six wrapped lines or less

どうやら計算コストが高いようです。
Chromiumでは6行以下の折返しがある行に対しのみ使えるようなので、例えば見出し要素 `h1, h2, h3, h4, h5, h6` など、一部で利用する方が良さそうです。

### バランスを調整しても要素のインラインサイズは変わらない

`text-wrap: balance;` で調整されて、見た目上はwidthが縮んでいますが、DevToolsなどのインスペクタで見ると、要素の幅は変わっていません。

[CSS テキストの折り返し: バランス  |  CSS and UI  |  Chrome for Developers](https://developer.chrome.com/blog/css-text-wrap-balance/?hl=ja) でAdam Argyle氏は、カード内の見出し（または枠線やシャドウが付いたコンテナ）内の見出しでの利用は良くないと言及しています。

### white-spaceと競合する

6行の制限でも触れましたが、6行以下の折返しがある行に対しのみ使えます。
なので、 `white-space: nowrap;` で文字が折返しが制限されている場合、 `text-wrap: balance;` は使えません。

`white-space: unset;` などで、折返しの制限を解除する必要があります。

## 参考

- [CSS text-wrap: balance | Can I use... Support tables for HTML5, CSS3, etc](https://caniuse.com/css-text-wrap-balance)
- [CSS テキストの折り返し: バランス  |  CSS and UI  |  Chrome for Developers](https://developer.chrome.com/blog/css-text-wrap-balance/?hl=ja)
- [text-wrap - CSS: Cascading Style Sheets | MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/text-wrap)
楽しい毎月のチームビンゴ

# はじめに
今年のカレンダーはとある会社のとあるチームで活動した1年間を振り返っていきます

## 登場人物

### ちいかわトミカさん：
先輩で頼りになる方。疲れたらちいかわトミカで遊んでいる？よくダジャレを言う。得意なダジャレは「今日言う共有事項はないです」

### ミュートさん：
先輩で頼りになる方。zoomを繋いでいる際、高確率でミュートのまま話す。よくシステムを自作している。

### かがやく筋肉さん：
筋肉ですべて解決してくれるチームの裏ボス的存在。

### 画面芸人さん：
zoomの画面でネタを仕込むのが得意。個人的にはドライブ映像がお気に入り。

### シャッツォさん：
ちいかわトミカさんに呼ばれているあだ名がシャッツォに似ているのでシャッツォにしました。
デスクにかわいいものを置きたいらしい。

# 楽しい毎月のチームビンゴ

かがやく筋肉さん「それではチームMTGを始めます！」

いつものように画面共有が行われる。週に1度のビンゴタイムの時間だ！
転職された元メンバーの提案で始めたチームビンゴですが、これが楽しい。

かがやく筋肉さん「今月の目標どうしますか？」

ミュートさん「今作っているシステムの改修をやろうかな」

画面芸人さん「私はAWS試験の会場に辿りつくにしますｗ」

ちいかわトミカさん「会場に辿りつけない人多いですからねｗ」

ちいかわトミカさん「私は牡蠣を買いに行くにします」

私「いいですねー、私はサーバレスデプロイをするにします」

ミュート「おー」

かがやく筋肉さん「私はRuby Goldを取得するでいきます」

シャッツォさん「私はデスクにかわいいものを置くにします」

---

このように月初は各々で目標を立ててそれをビンゴにしています。

そして毎週進捗を確認し合い、達成できた目標でビンゴになるかを楽しんでいます。

ビンゴになったら何かあるわけではないですがちょっと切磋琢磨できたり、息抜きになっています。

チーム内で雑談する機会にもなっているためか、この取り組みは1年以上続いています。

# おわりに
私たちのチームは全員で一つの案件を担当したことがないですが、チームビンゴなどで全員が集まって雑談をして親睦を深めています。
毎月好きに目標を立てることで頑張るきっかけにもなっているので、ぜひお試しください。
Box for Microsoft Office（共同編集機能）で何ができるのか？

## Box for Microsoft Officeとは
今年、ユーザーの方の待望の機能のBoxからOffice製品（Word,Excel,PowerPoint)利用時にデスクトップアプリで共同編集ができる機能がリリースされました！


### Box for Microsoft Officeの概要
Box for Microsoft Officeの共同編集機能により、Boxに保存されているOfficeファイルでのリアルタイムコラボレーションが可能になり、すべての編集内容がBoxに自動保存されます。ユーザーは、デスクトップ、ウェブ、モバイルのいずれで作業している場合でも、Box内のMicrosoft Word、Excel、PowerPointドキュメントを開いたり、作成、編集、コラボレーションする柔軟性があります。
[Box for Microsoft Office（Box Supportページ）](https://support.box.com/hc/ja/sections/21356627124627-Box-for-Microsoft-Office)

### どうやって使うの？？
チームメンバーと共同編集する場合は、以下の手順で実施します。
1. Boxウェブアプリまたはデスクトップファイルフォルダから [ファイル] に移動します。
2. 目的のOfficeファイル (.docx、.xlsx、.pptx) を開きます。
ウェブアプリの場合は、右上にある [開く] から「Despktopアプリ」をクリックします。
![Open Office file Preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626297/f9fc2ac4-cd5a-1501-5e01-0d9a80968ea2.png)
3. 編集を開始します。同時に作業しているメンバーがわかります。
![Multiple user session.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626297/1c18abac-5563-d807-d95f-21827eb11ea1.png)

4. 編集が完了したら、ファイルを閉じます。ファイルは、正常に保存されるまで開いたままになります。

:::note info
なんと、BoxDriveでファイルを開いても共同編集で開くことが可能です！！

:::

### どうやったら使えるようになるの？？
**利用するためには、管理コンソールでの設定利用ユーザーでの設定が必要です。**

#### 管理コンソールでの設定方法
1. 管理コンソールの左側のサイドバーで、[アプリ] をクリックします。
2. [Box for Microsoft Office] まで下にスクロールします。
![mceclip0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626297/5b8af6cb-1e5b-5120-389f-e9bfcc4bfb3e.png)
3. [構成の編集] をクリックします。
4. 以下より利用するユーザー範囲を選択します。
    - [すべての管理対象ユーザーに対して有効にする] 
    - [選択したユーザーに対して有効にする] 
5. [保存] をクリックします。

詳細は[こちらのSupportサイト](https://support.box.com/hc/ja/articles/17956056014995-Box-for-Microsoft-Office共同編集機能の有効化に関する管理者向けガイド)をご確認ください。

#### 利用ユーザー毎での設定方法
共同編集を開始するには、Microsoft Officeデスクトップアプリでオンラインの保存場所としてBoxを追加します。ご利用のオペレーティングシステムに応じて以下の手順を実行します。

1. Microsoft Word/Excel/PowerPointで、[ファイル] メニューオプションをクリックします。
2. 左側のナビゲーションペインで、[開く] をクリックします。
3. [場所の追加] をクリックします。
4. [Box] を選択します。
![Windows Gif - CoAuth Enablement-103 (dragged).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626297/54802c06-6628-878c-fe14-d9cc33459663.png)

5. Boxの資格情報を使用してサインインします。 
![Windows Gif - CoAuth Enablement-122 (dragged).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3626297/07b1e7d0-23e8-009c-0a06-a80f77e0e14b.png)

詳細は[こちらのSupportサイト](https://support.box.com/hc/ja/articles/5954058378899-Box-for-Microsoft-Office共同編集機能の有効化ガイド)をご確認ください。


### 注意事項
以下の既知の制限事項がありますのでご注意ください。
- Microsoftライセンスの互換性: Officeの永続ライセンス (例: Office 2016、2019) は、Boxファイルの共同編集をサポートしていません。
- Boxで、フォルダのコラボレータを非表示にするオプションのチェックボックスがオンになっている場合は、そのフォルダ内のファイルを共同編集できません。
- Excel内の外部リンクは、Boxに保存されているファイルを共同編集する場合、完全にはサポートされていません。 


## まとめ
Box for Microsoft Officeのことお分かりいただけたでしょうか？
Share Point OnlineやTeamsで利用されている共同編集機能がBoxでも活用できる非常にすばらしい機能です。ぜひBox for Microsoft Officeを利用してより効率的な業務を実現してください。
まだこの機能を利用していない方は、是非活用してみましょう！！
いま考える、ITサービスマネージャーの価値

はじめまして。
「ITサービスマネージャー」というと、単なるシステムの維持、オペレーションをするひと、というイメージを持たれている方もいらっしゃるかもしれません。
私自身は、そんなITサービスマネージャーの仕事を始めて気づけば丸10年が経ちました。

運用保守ってつまらなそう…そして地味そう…
と思われている方向けに、ITサービスマネージャーに少しでもポジティブな印象をもってもらえればと思い、記事を書いてみたいと思います:sparkles:

# 実は、クリエイティブ？！
まず、ITサービスマネージャーの大きな特徴のひとつは、システムのライフサイクルをつうじてお客様との接点が多いことです。
お客様との接点が多いということは、お客様の課題やニーズに一番近い位置にいるということ。

運用保守をつうじて得られた改善ネタや提案ネタを取り入れてシステムにフィードバックしていくDevops的な発想が求められます。
案件によっては運用保守部隊から営業や開発部隊に連携すること、さらには運用保守起点で新規事業に繋がることもあります。

ITサービスマネージャーの仕事は、お客様との密な連携を通じて、新しいアイデアや改善点を見つけ出しシステムの進化に貢献できる可能性が広がっているのです。

# お客様に投資対効果を実感してもらうことが最大のミッション
システムの運用保守は、お客様にとってはコンサルティングや開発に投資した費用が効果を発揮しているかどうかを測定するフェーズです。

つまり、ITサービスマネージャーの最も重要なミッションは、運用保守をつうじてお客様事業への貢献価値を最大化することなのです:ring:

運用保守界隈ではシステム安定稼動が命。
実際、泥臭く現場をまわしていくことも重要ですが、ITサービスマネージャーは現場に閉じた思考ではなく、よりお客様志向でいることが大切です。

# システムの屋台骨、絶え間なく改善をまわすプロフェッショナル集団
そして、システムトラブルが発生したときにこそ、最後の砦として運用保守の現場を統制するのがITサービスマネージャーの役割です。

お客様に怒られることもあります…
早期復旧（ゴール）に最短距離でいくにはどうしたらよいかを必死に考えるシチュエーションも少なくありません…

ですが、システムを利用するユーザのすみずみにまでサービスを届けられているのは、我々ITサービスマネージャーがいるからこそなのです。

継続的な問題解決と改善をつうじ、お客様との信頼関係を築き、お客様の事業に寄り添うこと、これらの取り組みがITサービスマネージャーの成長に繋がります。

# まとめ
ITサービスマネージャーや運用保守の仕事に対して、少しでもプラスのイメージを持っていただくことを目標にこの記事を書きました。

ITサービスマネージャー職と女性の親和性についても触れたいですが、それはまた次の機会に。。
アクセシビリティ対応、もっと褒め称えようよ

## はじめに

altに文字を入れているあなた、偉いです！`<label>`タグに`for`をいれて`<input>`と紐づけているあなた、偉いです。eslintに[eslint-plugin-jsx-a11y](https://www.npmjs.com/package/eslint-plugin-jsx-a11y)をいれて静的にアクセシビリティの解析をしているあなた、ほんとに偉いです。[axe DevTools](https://chromewebstore.google.com/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd)をいれて解析してる人、めっちゃくちゃ偉いです！フロントエンドのテストのためにアクセシビリティ良くしたあなた、なんて偉いんでしょうか！

ちょっとずつでもいいから、小さいことからアクセシビリティ対応始めましょうよ！やってない人よりやっている、やり始めている人のほうがすごく偉いんですから

## なぜこの記事書いたか

https://qiita.com/mu_tomoya/items/8bd2696c1ce79db53b3c

こちらの記事でも少々反響あったんですが、

>先日自分が参加してアクセシビリティの勉強会の懇親会で、普段広報をしていらっしゃる非エンジニアの方が
「アクセシビリティを勧めてくる人ってみんな威圧的なんだよね」と愚痴っていました。

アクセシビリティ対応を進めているエンジニアの方って、確かに口調が強めな方の意見も聞きます。「WCAGに対応しているだけがアクセシビリティではない」。本当にその通りだと思います。それだけがアクセシビリティだけではありません。そもそもアクセシビリティって、「誰でも問題なく使える」ということです。この「誰でも」というのが非常にむずかしいところです。アクセシビリティのゴールはかなり遠いところにあると思います。

ただ、**目くじら立てまくるとみんな嫌になりませんか**？「WCAGに対応しているだけがアクセシビリティではない」というのは確かにそうですが、WCAGに対応し始めたことってまずすごいって自分は思います。むちゃくちゃ言えば、全部`<div>`タグでもWebの見た目って作れます。でもそんな見た目だけってところから、ちゃんとHTMLとして意味のある通じるものに、マシンリーダビリティ的にちゃんと読み取れる文書構造に進化させたわけです。見た目だけ作ればいいと言うところからちゃんと卒業できたんですから。

## ゴールは適宜設定すればいいと思う

「アクセシビリティ対応にゴールなんてない」
確かにそうです。「全ての人」が使いやすいWebを目指すのであれば、あれやこれや対応しなくてはいけません。ハンデを持ってる方も、目が見えない方だけでなく、色弱な方、老眼、腕が不自由な方、字がうまく読めない方など。範囲はめちゃくちゃ広いです。

しかし、ゴールを無限大まで遠くしたら息切れしませんか？私は正直きついと感じてしまいます。そのゴールまで目指すのがいやだからアクセシビリティ対応は難しそうだから何もしないとなると本末転倒です。

そこで、とりあえずのゴールを設定してあげることがいいと思います。
「画像は絶対にaltをつける」、そんな小さいことから始めるだけでいいと思います。それだけだったら簡単にできそうだと思いませんか？次にもっと範囲を広げて、静的解析でチェックツールでチェックする、合格率をあげる。そこまでできたらすごくすばらしいと思います。

でも、それだけがアクセシビリティ対応のすべてではないということは、頭の隅に入れておくことは大事です。あなたのサイトを見るユーザーはどんな人でしょうか？どんな方が利用しますか？例えば文章メインのサイトだったら、識字障害（ディスレクシア）の方向けに読みやすいフォントにしてみるなどしてみるといいかもしれません。

ここから大事なことは、**思いやること**です。思いやること、そのことがアクセシビリティでとても大切だと思います。最終ゴールの見えない中で唯一ゴールに近づく方法は、思いやることだと思います。どんな人が使うのか、そのためには何が必要か。またはユーザーの声を聞き、どういうことに困っているのか、その声をとりあげてどんなことをしてあげられるかがとても大切だと思います。

## 入り口はなんだっていい、対応し始めたその姿勢がほんと偉い

フロントエンドのテストのためだとか、altいれたほうがいいらしいとか、いいことをしている気分になるとか、理由はなんだっていいと思います。対応し始めたことがほんとに偉いです。

そして先進的にアクセシビリティに対応しているエンジニアの方々、こういう方達をもっとほめて伸ばしていきましょうよ。減点方式であれができていない、これができていないより、加点方式であれができている、これができているで褒めて伸ばしていきましょうよ。1人でもアクセシビリティ対応やりたいなと思うエンジニアを増やすためにも。

以上
CSS, SCSSのスコープに関するメモ

メモ書き程度に記す。
CSS, SCSSを利用する上で気を付けておくべき記法。


# 1. 配下すべてに適用
parent要素以下のelement要素すべてに適用させる。子も孫もひ孫も。

```plantuml
@startuml
rectangle "class="parent""{
    rectangle "class="element"" #palegreen;line:green;text:green{
        rectangle "class="element"" #palegreen;line:green;text:green{
        }
    }
}
@enduml
```

``` scss:style1.scss
.parent{
    .element{
        hoge: 100;
    }
/* もしくは */
    & .element{
        hoge: 100;
    }
}
```
↓コンパイル結果

```css:style1.css
.parent .element{
    hoge: 100;
}
```



# 2. 子のみに適用
 CSS, SCSSで＞をつけると子のelement要素のみに適用される。孫のelement要素には適用されない。
 ```plantuml
@startuml
rectangle "class="parent""{
    rectangle "class="element"" #palegreen;line:green;text:green{
        rectangle "class="element"" #white{
        }
    }
}
@enduml
```
```scss:style2.scss
.parent{
    > .element{
        hoge: 100;
    }
/* もしくは */
.parent{
    & > .element{
        hoge: 100;
    }
}
```
↓コンパイル結果
```css:style2.css
.parent > .element{
    hoge: 100;
}
```

# 3. 複数クラスを持つクラスの一部に適用
CSSでピリオドで続けて記載すると、複数クラスを持つクラスの一部に適用できる。SCSSでは、アンパサンドを使ってスペースを入れずに記載する。
 ```plantuml
@startuml
rectangle class="parent"{
    rectangle class="element　first-child" #white{
    }
    -[hidden]->
    rectangle class="element　second-child" #palegreen;line:green;text:green{
    }
    rectangle class="element　third-child" #white{
    }
}
@enduml
```

```scss:style3.scss
.parent{
    .element{
        &.second-child{
            hoge: 100;
        }
    }
}
```
↓コンパイル結果

```css:style3.css
.parent .element.second-child{
    hoge: 100;
}
```
某社風のGoogleスライドテンプレートを作った

# はじめに
LTなどで登壇する度にテーマがばらける[にわのわ](https://twitter.com/niwa_nowa)です。

今回はLTで使うスライドテンプレートを作ったので共有します。

# 作ったもの
今回作ったものはこちらです。
https://docs.google.com/presentation/d/1D-uMomV1N4TePRDX0_E3X63VYtBEhupjvDJdcEdzHfk/edit?usp=sharing

ちなみにスライドタイトルで使っている画像はDALLE-3に作ってもらったものなので著作権フリーです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590707/b948b23a-d000-baff-1425-e2965d5830d1.png)

# こだわり
## ガイド
スライドのガイドを丹精込めて手作業で作りました。
これにより、各オブジェクトの配置場所に困ることが少なくなると思います。
既存のテーマだと、画面中央に縦横のガイドが引かれているだけなので、オブジェクトの配置場所に困ることが多いかったです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590707/27d6b039-850a-cb8a-4445-6ccd627ac28e.png)

## フォント
フォントは全てBIZ DUPGothicをで統一しています。
これはエクスポートした際に崩れないフォントであること、かつ見やすい日本語フォントであることを重視して選びました。

詳しくはこちらを参照してください。

https://zenn.dev/unsoluble_sugar/articles/cade53a073157df0b687

## テーマカラー
テーマカラーは緑を中心にしています。
緑は割と強調表示に向いている色だと思っています。
ちなみにかなり参考元の配色にに近い色を使っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590707/32e14c76-37ed-3476-7fed-428f3e856d7a.png)

# ちなみに
アイコンを使う場合はこちらがおすすめです。
24pくらいにマテリアルアイコンがたくさん詰まっているのでGCP以外でも使える場面がきます
https://docs.google.com/presentation/d/1fD1AwQo4E9Un6012zyPEb7NvUAGlzF6L-vo5DbUe4NQ/edit#slide=id.ga472c7d3d1_3_834

# おわりに
今回は某社風のGoogleスライドテンプレートを作ったというお話でした。
某社はどこかは知りません。きっと。

明日魂のスライドテーマに出会えたらいいね、にわのわでした。
Playwright で Page Object Model を使用するときのちょっとした工夫

## はじめに

本記事は、[株式会社ACCESS Advent Calendar 2023](https://qiita.com/advent-calendar/2023/access) の22日目の記事です。
Playwright における Page Object Model の使用方法が公式ドキュメントに[ガイド](https://playwright.dev/docs/pom)として、紹介されている。
本記事ではさらに Playwright で Page Object Model を使用するときのちょっとした工夫について紹介する。

## コード

### 対象の HTML

対象の HTML は以下のものとする。一般的なログインフォームを想定している。

```HTML
<form action="/login" method="POST" enctype="application/json">
  <div>
    <label for="username-field">username</label>
    <input type="text" id="username-field" required/>
  </div>
  <div>
    <label for="password-field">password</label>
    <input type="password" id="password-field" required/>
  </div>
  <button id="login">Login</button>
</form>
```

### Page Object Model

上記の対象の HTML に対して、以下のような Page Object Model を作成する。

```typescript
import { expect, type Locator, type Page } from '@playwright/test';

export class LoginPage {
  readonly page: Page;
  readonly usernameTextBox: Locator;
  readonly passwordTextBox: Locator;
  readonly loginButton: Locator;

  constructor(page: Page) {
    this.page = page;
    this.usernameTextBox = page.getByRole(
      "textarea",
      {
        name: "username"
      }
    );
    this.passwordTextBox = page.getByRole(
      "textarea",
      {
        name: "password"
      }
    );
    this.loginButton = page.getByRole(
      "button",
      {
        name: "Login"
      }
    );
  }

  async login(username: string, password: string) {
    await this.usernameTextBox.fill(username);
    await this.passwordTextBox.fill(password);
    await this.loginButton.click();
  }
}
```

## ちょっとした工夫

冒頭でも参照した[ガイド](https://playwright.dev/docs/pom)では Page Object を定義したクラスのインスタンスを [`test`](https://playwright.dev/docs/api/class-test#test-call) のコールバック関数内で生成している。

```typescript
test('should be able to login', async ({ page }) => {
  const loginPage = new LoginPage(page);
  await loginPage.login('user', 'pass');
});
```

しかし、この方法では、テストケースを定義するたびに、インスタンスを生成するコードを各必要がある。たった一行だけれど、毎回記述するのは個人的には鬱陶しい。そこで、ちょっとした工夫として紹介するのが [Fixture](https://playwright.dev/docs/test-fixtures) のなかでインスタンスを生成するものである。

```typescript
import { test as base, Page } from "@playwright/test";

type TestFixtures = {
  loginPage: LoginPage;
};

const test = base.extend<TestFixtures>({
  loginPage: async ({ page }, use) => {
    const loginPage: = new LoginPage(page);
    await use(loginPage);
  },
});

test('should be able to login', async ({ loginPage }) => {
  await loginPage.login('user', 'pass');
});
```

Fixture を使用することで Fixture を呼び出すたびに Page Object のクラスのインスタンスの生成が実行される。
実はこの実装方法は、公式ドキュメントの [Fixtures](https://playwright.dev/docs/test-fixtures#creating-a-fixture) にしれっと記載されている...。

## さいごに

Playwright で Page Object Model を使用する際のちょっとした工夫について紹介した。結局のところ、この記事の味噌は Fixture の使用方法についての紹介となったが、テストケースの前後の処理などにも使用できるため、ぜひ活用してみてほしい。
明日は @Momijinn さんの記事です。お楽しみに！


<!-- zenn article id: 70698527ec7bf0 -->
JavaScriptで配列の最後の要素を取得するにはatメソッドがいい

JavaScriptで配列の最後の要素を取得する方法はいろいろありますが、一番いい方法はどれでしょうか？
書きやすさや可読性の観点から比較したいと思います。

今回やりたいことは配列の最後の要素を取得したいだけで、配列に変更は加えません。そのため [popメソッド](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/pop) は使用できません。

## 1. atメソッド（推奨）
先に結論を言うと `atメソッド` がいいです。

```js
const colors = ["red", "green", "blue"];

const last = colors.at(-1); 

console.log(last);
// "blue"
```

Pythonなどでは負の数で後ろからアクセスできますが、JavaScriptではPythonのようにブランケット記法で負の数は扱えません。

```js
const colors = ["red", "green", "blue"];

const last = colors[-1];

console.log(last);
// undefined
```

そこで使用するのがES2022で導入された [atメソッド](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/at) です。`atメソッド` は負の数が扱える以外は基本ブランケット記法と同じ処理になります。（あとで注意として記載していますが、完全に同じではありません）

一番シンプルで可読性の高い書き方です。

## 2. lengthプロパティ

```js
const colors = ["red", "green", "blue"];

const last = colors[colors.length - 1]; 

console.log(last);
// "blue"
```

配列の長さから1を引くことで最後の要素のインデックスを取得する方法です。個人的には一番よく見かける方法かなと思います。

## 3. sliceメソッド
```js
const colors = ["red", "green", "blue"];

const last = colors.slice(-1)[0];

console.log(last);
// "blue"
```

`slice(-1)` で配列の最後の要素を含む新しい配列を作成します。その後、`[0]` でその要素を取得します。

JavaScriptをある程度理解している人であれば、それほど難しくありませんが、ぱっと見分かりづらいのが難点です。

## 注意

シンプルで使用しやすい `atメソッド` ですが、注意点があります。
それは整数以外を使用した時です。実際にどうなるか試してみます。

```js
const colors = ["red", "green", "blue"];

console.log(colors.at("foo")); // red
console.log(colors.at(undefined)); // red
console.log(colors.at(NaN)); // red
console.log(colors.at(1.5)); // green
```

文字列やundefiendなどは `0` として扱われ、小数点以下は切り捨てとなります。
ブランケット記法とは違って `undefined` は返しませんので、注意してください。

**参考**
https://qiita.com/petamoriken/items/da03f55cb626617c1958

## おまけ

3つの方法を紹介しましたが、どれが一番早いのでしょうか？計測してみました。

**測定方法**
node: v20.10.0
配列の要素数は1000。10回実行しそれぞれ平均値を求める。

**結果**
```
1. At methodの平均実行時間    : 約0.00297秒
2. lengthの平均実行時間       : 約0.0115秒
3. Slice methodの平均実行時間 : 約0.00277秒
```

lengthプロパティを使用する方法が他と比べて遅く、`sliceメソッド` を使用する方法が `atメソッド` と比べて若干早いという結果になりました。

ただどれを使用してもパフォーマンスに大きな影響はないと思いますので、それほど気にしなくてよいと思います。
privateなcrateの扱いについて

# privateなcrateどうしてます？

Rustで開発しているとき、crate分割したり、社内用のライブラリを整備したりすると複数のprivateなcrateを扱う必要が出てきます。
publicだったらcrates.ioを使ってしまえばいいのですが、privateなcrateを管理する場合のcrateの扱いはどうしていますでしょうか？
以下使える選択肢をあげて比較してみたいと思います。

## crateが同一レポジトリにある場合

単純にpathを使えば参照できるので簡単ですね。
```toml
[dependencies]
sample-crate = { path = "../sample-crate" }
```

## crateがレポジトリをまたがる場合

この時は割と悩ましいです。

###  気にせずpathを使う

全部の開発環境で複数のレポジトリを展開する構造が一致させて運用させます。

#### pros
- 先ほどと同様で簡単。

#### cons
- 同じ位置にcloneされると期待しないといけない(社内ツールなど？)
- CI/CDでは使いずらい(元のレポジトリも調達する必要がある)
- コミットごとにライブラリが変わってしまう…。
    - どのコミットがライブラリ側のどのコミットを参照していたかわからない
    - 作業するレポジトリごとに参照元のレポジトリの状態を管理しないといけない

### git submoduleを使う

pathを使うものの亜種で、cargoの機能を使わずに管理します。

#### pros
- 割と枯れている方法なので導入しやすい。

#### cons
- git submoduleの管理自体が面倒くさい…。
- ライブラリのバージョンがいくつであるかを追いにくい
    - tagで管理すれば問題はないか？
        - .gitmodules見ないといけないのは微妙そう

### ファイルをコピペする

管理とは呼べない代物ですね。最悪です。

#### pros
- 最初だけ楽。最初だけ

#### cons

- 管理できない
- 無秩序に変更がかかり始め、ライブラリとは一体何だったのだろうか状態になる。

### dependenciesでgitを使う

以下のようにgitで依存関係を設定できます。

```toml
[dependencies]
sample-crate = { git = "https://github.com/sample-org/sample-crate.git" }
```
#### pros

- cargoで管理してくれるので楽
- gitのcommitで指定できるので開発中でも変更しやすい
- tag指定ならどのバージョンに依存しているかが明確

#### cons

- gitの認証が若干面倒
- commitで頻繁に対象を変えるとcargoのcacheが肥大化しがち
    - いずれ解消しそう https://blog.rust-lang.org/2023/12/11/cargo-cache-cleaning.html
- 巨大なレポジトリなら容量を圧迫する
- gitで対象のcommitやbranch,tagが消えるとそのバージョンが使えなくなる
    - tagが消えることはないでしょうが…

### Alternate Registryを使う

crates.ioの代わりとなるregistryを用意して、そこから落とす方法です。
既存の3rd-partyなものを使ってもいいし、自前で管理することもできます。

https://github.com/rust-lang/cargo/wiki/Third-party-registries

サードパーティーのレジストリのリストがあるのでそこのものを使うか自前で用意してもいいです。

```toml
[dependencies]
sample-crate = { version = "0.1", registry = "sample-registry" }
```



#### pros
- cargoの仕組みで管理されるので楽
- バージョン管理もcrates.ioのcrateと同じように使える
- 依存関係のバージョンの解決などを行ってくれる

#### cons
- レジストリのコスト(管理コストまたがサービス利用料)が掛かる
- 認証の手間がある

# まとめ

dependenciesでgitを使うのが一番手っ取り早くて楽だと思います。余計なインフラなしに簡単に導入できます。
ただ扱うライブラリが増えてくるならAlternate Registryを使うのがいいと思います。
Registryについての別記事も書いたのでそちらも参照してみてください。

https://qiita.com/aobat/items/d3a015c284910bfcc662

（ちなみに自分は時間がなくて「ファイルをコピペする」の禁じ手をやってしまったものがあるので直したい…。CIで認証がうまくいかなったのだ…。）
ガジェット紹介：XREAL AIR 2 Pro 

この記事は、[大阪工業大学 Advent Calendar 2023](https://adventar.org/calendars/9108)の17日目の記事です．
以前から気になっていた[XREAL AIR 2 Pro](https://www.xreal.com/jp/air2/)のレビューになります．
# ARグラスとは？
「AR（エーアール）グラス」、「MR（エムアール）グラス」とは、メガネ型のデジタルデバイスで、グラス越しに見える現実世界にデジタルの情報を重ねる機能を持ったものです。
引用：[BLOGブログ，「ARグラス/MRグラス」とは？初心者にも分かりやすく機能や操作方法、活用例について解説，2023/12/14](https://berise.co.jp/topics/ar-mr-glass/)

# XREAL AIR 2 Pro
見た目は，マットな感じでスタイリッシュでいい感じです．小さいので鞄に入れて持ち運び可能です．接続はType-cでつなぐことができて，繋ぐとすぐにに反映されるため，眼鏡型のモニターという感じです．また，右側に，明るさ調節と音量調節ボタンがあり，環境に応じた操作が可能です．

![IMG_1115.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3070318/51ded2ad-9cc9-7788-f586-8af692aad00e.jpeg)

レンズ内はこのような感じ

![IMG_1114.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3070318/11bd9991-78cb-45cb-b96b-5b5e8034a57d.jpeg)

解像度もそこそこ高いです．

# XREAL Beam
グラスだけだと，明るさ調整や音量調整しかできませんが，別売りのXREAL Beamを買うと，空間に画面を固定したり，ブレ補正や，サイドビュー機能，またウィンドウサイズの調整機能を使えるようになります．また，Beamと他デバイスを同一のWi-Fiに設定することで，ミラーリングすることもできます．

![IMG_1112.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3070318/a4274153-b1c6-b1e8-3d48-bc646dcefa65.jpeg)

# 感想
近未来的で楽しいですが，グラス単体だと１画面しか共有することができないため．複数モニターで作業する方が楽ですね．ただ，専用のソフトNebura for Macを使用すると最大３画面まで拡張できるとか・・・ただ自分はwindownsユーザなので順次対応されるのを待つしかないですね．
WhisperXを用いた映画字幕へのタイムスタンプ付与

## はじめに
こんにちは、GlobeeでCTOをやっています上赤です。
[Globee Advent Calendar](https://qiita.com/advent-calendar/2023/globee)16日目の記事です。

今回はWhisperXを用いて、映画字幕へのタイムスタンプ付与を行った際の記録を残します。

## 発端
弊社が作っているサービス[abceed](https://www.abceed.com/)では、**映画を使った英語学習**を行うことが出来ます。
学習機能の中には**フレーズ単位でのシーク/リピート機能**があり、これを実現するために、各フレーズの開始秒数/終了秒数を0.01秒単位で正確に付与する必要があります。

![スクリーンショット 2023-12-16 22.31.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49019/f8543660-9317-c77e-72fc-6b6679922277.png)

秒数付与は当初弊社オリジナルコンテンツチームが手動で行っていたのですが、作業効率化のため、**エンジニアチーム側で何かサポートが出来ないか**という話になってきました。

ちなみに、他にも映画字幕への語注作成についても記事を書いています。良かったら合わせてご覧ください。
[こちら](https://qiita.com/yskazuma/items/e9caacea8b2cc8540a43)

## 問題の定義
入力: 映画の一部分のオーディオ（任意の形式）と字幕リスト
出力: 字幕リスト内の各文に対する開始時間
が定義です。

オーディオデータを使って下記のような字幕データに開始秒数/終了秒数を付与するというイメージですね。

![スクリーンショット 2023-12-16 22.37.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49019/547d395a-a0e3-d457-dd0c-c0b3398545c6.png)


また、映画は**背景音や話し言葉の速度が含まれるため、声を検出するのが他のメディアより困難**です。
それにより、単語を全て検出するのは難しいので、ある程度曖昧なマッチングを行う必要があります。


## やったこと
### データ変換
AIによる音声検出アルゴリズムは16kHz 16ビットの単一チャネルwavファイルで訓練されているため、変換が必要です。.mp3ファイルの場合はffmpeg、.wavファイルの場合はsoxを使用します。

```
ffmpeg -i "input.mp3" -vn -ac 1 -ar 16000 -acodec pcm_s16le -f wav 'output.wav'
```

```
sox "input.wav" -b 16 -r 16000 -c 1 "output.wav"
```

### データ分割
同様に、AIアルゴリズムが30秒以下のセグメントしか処理できないため、事前に分割が必要です。会話が中断しないように、会話がないと思われるポイントでのみ、webrtcvadライブラリを用いて分割を行います。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49019/b979c4fa-64ae-d6ab-4d42-1c68385c8531.png" width=300>

### WhisperXによる文字起こしとタイムスタンプ取得
文字起こしとタイムスタンプ取得には[WhisperX](https://github.com/m-bain/whisperX)を利用します。
WhisperXは、METAのwav2vec2とOpenAIのWhisperの2つの音声認識技術が組み合わされており、正確な文字起こしとタイムスタンプの両方を得ることができます。

wav2vec2とWhisperには様々な訓練済みモデルがありますが、今回は
`large-v2` + `facebook/wav2vec2-large-960h-lv60-self`
の組み合わせで行いました。

実行すると、以下のような結果が得られます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49019/dcb954cb-bdc4-e12b-fadc-b448ee69f3c3.png" width=500>

### 単語レベルのマッピング
ここが一番面倒なところです。上で取得した単語単位のタイムスタンプを元に、字幕各行の開始秒数/終了秒数を作成します。

単語リストをスキャンし、字幕の行と一致する文字列のシーケンスを探す、というのが最もシンプルですが、それだけでは精度が低かったので、複数のロジックを組み合わせて結果を生成し、問題有りそうな箇所を修正していく、というような泥臭い方法で実現しました。

ロジックの中に、ChatGPTによる判定を挟んでみると精度が上がったのは面白かったです。

## 結果
最初はタイムスタンプ付与の精度が低かったのですが、改善を続けた結果、オリジナルコンテンツチームの**作業時間を数十%削減**することが出来ました！
自動付与はやはり完璧ではないので、自動付与されたタイムスタンプは初期値として使うだけにとどめ、人の耳で聞いて0.01秒単位で最終調整を行う必要があります。
将来的には自動付与されたタイムスタンプがほぼ修正の必要なくなるようにできれば良いなと思っています。引き続き改善中です。

## まとめ
WhisperXを使うことで、映画字幕へのタイムスタンプ付与を自動化し、作業効率を改善することが出来ました！
今後も様々な領域で、業務改善をしていけたらと思います。

弊社では、現在アプリ/Web/サーバーエンジニア/PjMなど、ほぼすべての開発ポジションを募集中です！
ちょっとでも興味持った人は以下からカジュアル面談をご検討ください。色々お話します！
[採用ページ](https://globee.notion.site/Globee-d184eefc3561480292481299c64b04bc)
ABC333をPythonで（A~E）

トヨタ自動車プログラミングコンテスト2023#8（AtCoder Beginner Contest 333）

https://atcoder.jp/contests/abc333

# A問題
```python:A
n = input()
print(n * int(n))
```
# B問題
距離のパターンが2パターンだけだから、
それぞれどちらのパターンか調べればいい
```python:B
s = input()
t = input()
def near(s):
    s1, s2 = s
    return {s1, s2} == {"A", "E"} or abs(ord(s1) - ord(s2)) == 1

print("Yes" if near(s) == near(t) else "No")
```
# C問題
解答例の最後が最大値なので、それ以下を全部出力して$N$番目を出力すればいい
```python:C
n = int(input())

lst = set()
for i in range(1, 13):
    for j in range(i, 13):
        for k in range(j, 13):
            lst.add(int("1" * i) + int("1" * j) + int("1" * k))

ans = sorted(lst)
print(ans[n - 1])
```
# D問題
$1$と他をつないでいる辺を除いたグラフの中で1つの木以外を取り除いたときに$1$が葉になる
よって答えは$N-max($各木のサイズ$)$となる
```python:D
from sys import setrecursionlimit

setrecursionlimit(10 ** 7)
from collections import defaultdict

class UnionFind:
    """
    URL : https://note.nkmk.me/python-union-find/
    """
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]


n = int(input())
UF = UnionFind(n)
child = []
for _ in range(n - 1):
    u, v = map(lambda x:int(x) - 1, input().split())
    if u == 0:
        child.append(v)
    else:
        UF.union(u, v)

ans = n + 1
if len(child) <= 1:
    print(1)
else:
    for i in child:
        ans = min(ans, n - UF.size(i))
    print(ans)
```

# E問題
各ポーション獲得時にそれを取らないと倒せないモンスターが出てくる時だけ拾えばいい
それを調べるために出来事を逆順に見ていって
1. ポーションの時は、それを使って倒すべきモンスターがいるときだけ拾い、必要ポーション数を$-1$する
1. モンスターの時は、それを倒すのに必要ポーション数を$+1$する

```python:E
n = int(input())
query = [list(map(int, input().split())) for _ in range(n)]
d = {0:0}
lst = []
for t, x in query[::-1]:
    if t == 1:
        if x in d and d[x] > 0:
            lst.append(1)
            d[x] -= 1
        else:
            lst.append(0)
    else:
        if x not in d:
            d[x] = 0
        d[x] += 1

if max(d.values()) > 0:
    print(-1)
else:
    lst = lst[::-1]
    ans = cnt = ind = 0
    for t, _ in query:
        if t == 1:
            if lst[ind] == 1:
                cnt += 1
            ind += 1
        else:
            cnt -= 1
        ans = max(ans, cnt)

    print(ans)
    print(*lst)
```
Raspberry Pi 3B+ に Emby をインストールした

&emsp;手元の  [Raspberry Pi 3B+](https://raspida.com/orign-3bplus) は 5 年前に IoT の小手調べのために購入したものであるが、その後、使途が定まらないまま放置されていた。
&emsp;これを有効活用するため、メディアサーバーである [Emby](https://en.wikipedia.org/wiki/Emby) をインストールして、宅内のどこからでも PC やスマートフォン の web ブラウザで音楽鑑賞できる環境を構築した。
&emsp;追加のコストは 128GB の [MicroSD カード](https://www.amazon.co.jp/dp/B09378JC6B?ref=ppx_yo2ov_dt_b_product_details&th=1) &yen;1,280 と [(バター) ケース](https://jp.daisonet.com/products/4560219034570) &yen;110 の &yen;1,390 である。
&emsp;運用を開始して二週間ほど経過したが何の支障もなく稼働している。

![raspi.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233450/e9ca489a-bdba-82b6-d9e6-2c082ecdfd8f.jpeg)

![screenShot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233450/8445da46-521f-3a33-4579-4cab31cadf92.png)

# Raspberry Pi OS・オーディオファイル

&emsp;Raspberry Pi OS (Legacy, 64-bit) を[インストール](https://www.indoorcorgielec.com/resources/raspberry-pi/raspberry-pi-os%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/)した。
&emsp;オーディオファイルは老朽 PC 上の [Rhyrmbox](https://gihyo.jp/admin/serial/01/ubuntu-recipe/0079) で利用していたもの（CD 約 300 枚分）をホームディレクトリ直下に作成した **Music** ディレクトリにコピーした。

# Emby

&emsp;下記の記事通りで全く問題なくインストールできた。

* [Installing and Running the Emby Media Server on the Raspberry Pi](https://pimylifeup.com/raspberry-pi-emby-media-server/)

&emsp;ただし、次の画面の 1. では上記の **/home/_user_/Music** を入力した。

<div align="center">
<img src="https://pimylifeup.com/wp-content/uploads/2023/09/Raspberry-Pi-Emby-Media-Server-05-Set-the-Library-Folder.jpg" width="
%">
</div>

## メタデータの編集

&emsp;オーディオ・ファイルのタグはアルバム／楽曲のページの鉛筆アイコン（Edit Metadata）またはホーム画面左上隅の <span style="font-size: large;">≡</span> をクリックして表示される「メタデータマネージャ」から GUI で変更することができる。
&emsp;さらに、タグを一括変更する場合は次のように **mutagen** という外部ライブラリを用いた Python スクリプトで作業を省力できる。

```python
# Pythonでmp3などのID3タグを編集するmutagenの使い方
#   https://note.nkmk.me/python-mutagen-mp3-id3/

# PythonでFLACファイルのタグを扱う方法
#   https://tranphonic.hatenablog.com/entry/2014/11/09/225201

from mutagen.flac import FLAC
import glob
import re

wild = "./source/*.flac"
reg_obj = re.compile("(.*Disc )([1-6])(\].*)")

for f in glob.glob(wild):
    audio = FLAC(f)
    print(audio["title"])
    # audio["album"] = "BEETHOVEN SYMPHONIES"
    # audio["artist"] = "Royal Philharmonic Orchestra"
    # audio["albumartist"] = "Royal Philharmonic Orchestra"
    # audio["discnumber"] = reg_obj.split(f)[2]
    audio["genre"] = "Pop" # "Classical;Beethoven"
    audio.pprint()
    audio.save()
```
年末のMac大整理/その2：ドットファイル整理


# はじめに

この記事は、Qiita Advent Calendar 16日目の記事です。
以下の記事より、すべての記事をご覧になれます。

https://qiita.com/0_terarin_0/items/0f367210e2465f7772c9

# 筆者について

- 現在高校２年生
- 水泳部マネージャー
- 生徒会長
- とある団体の代表

# 本編

本日はドットファイル系を整理したいと思います。

とりあえず、何があるか調べましょうか。

```zsh:shell
~$% ls -a | grep .
.
..
.CFUserTextEncoding
.DS_Store
.IdentityService
.ServiceHub
.Trash
.alacritty.yml
.anaconda
.anaconda_backup
.android
.anyenv
.bash_history
.bash_profile
.bash_profile.backup
.bash_sessions
.bashprofile
.bashrc
.bashsrc
.boto
.bun
.cache
.clasprc.json
.cocoapods
.conda
.config
.continuum
.cups
.dart
.dart-tool
.dartServer
.docker
.dotnet
.dropbox
.emulator_console_auth_token
.esets
.firebase
.firebaserc
.flutter
.flutter-devtools
.gcloudignore
.gem
.gitconfig
.gitignore
.gradle
.grass7
.gsutil
.hawtjni
.hushlogin
.ipython
.kube
.lesshst
.lldb
.local
.m2
.minikube
.modular
.mono
.ms_eclipsetemurinjdk_config
.ms_openjdk_config
.mysql_history
.node_repl_history
.nodenv
.npm
.npmrc
.nswitch
.nuget
.openvpn-connect.json
.pub-cache
.pyenv
.python_history
.rbenv
.redhat
.ssh
.swiftpm
.switch_proxy
.tcshrc
.templateengine
.terminfo
.thumbnails
.tor
.vim
.viminfo
.vpython-root
.vpython_cipd_cache
.vs-kubernetes
.vscode
.vscode-insiders
.wget-hsts
.xonshrc
.zcompdump
.zprofile
.zprofile~
.zsh_history
.zsh_sessions
.zshrc
Applications
Desktop
Development
Documents
Downloads
Dropbox
Library
Minecraft
Movies
Music
OneDrive
Pictures
Public
UTM
Users
Wallpaper

```

ここでいくらかファイルの解説をします。

### ```~/.CFUserTextEncoding```

個人設定が記録されているファイルになっているようです。逆に、これを削除したら全部なくなるっぽいです。

### ```~/.IdentityService```

不明（分かり次第追記）

### ```~/.ServiceHub```

不明（分かり次第追記）

ここでどう見てもいらないファイルたちを削除したいと思います。

- ```~/.lesshst```
- ```~/.anaconda```
- ```~/.anaconda_backup```
- ```~/.conda```

あれ、全然整理の必要がなかった、、、:(

これ、なぜかというと、結構忘れていたのですが、僕自身がほとんどをHomebrewで管理しているっていうのもあって、実はこれほとんどここを調整する必要がないのです。なので、他の方々たちはホームディレクトリを調べないといけないといけないかもしれないですが、Homebrewで管理するとかなり楽ですので、ぜひ皆さんもトライ！（結構色々してます）

# 最後に

ネタになるかと思いきやほとんど何もすることなくちょっとで終わってしまいました。ただ、わからないファイルがいくつかありますので、わかる方は是非教えていただけるとありがたいです。ということで、今後のアドカレ 23 の記事をお楽しみにしてください。

https://qiita.com/0_terarin_0/items/0f367210e2465f7772c9
M5Stack Basic, ESP32無印をやっててハマったエラーたち

M5Stack Basic, ESP32無印をやっててハマったエラーたちを紹介するぜ！！！

## Stack smashing protect failure!
ローカル変数で文字列をparseしてまくってstack領域を確保しまくってたら発生して、勝手に再起動するやつ
文字列の領域をグローバル変数にして回避した
- https://twitter.com/takuzirra/status/1730266673624838560

## Guru Meditation Error: Core  1 panic'ed (LoadStoreError). Exception was unhandled.
処理が間に合わないときにとかにでて、勝手に再起動するやつ
処理を整理して回避した
- ESP32 ( ESP-WROOM-32 , M5Stack )自分的 トラブルシューティング まとめ | ページ 5 | mgo-tec電子工作
  - https://www.mgo-tec.com/blog-entry-trouble-shooting-esp32-wroom.html/5
- https://twitter.com/takuzirra/status/1331295121208270848

## A fatal error occurred: Timed out waiting for packet content
書き込み時のエラー
Upload speedを「921600 -> 115200」に変えると通る
- コンパイルは成功するのに書き込みが失敗する | dotstudio
  - https://dotstud.io/docs/nefrybt-error-handling-2/
- https://twitter.com/takuzirra/status/1302206956795432961

## おわりに
M5Stack Advent Calendar 2023、ありがとうございます。
M5Stack Core S3, ESP32-S3ではまた違うエラーに会えるでしょうか。
Spring Boot のデータアクセスにDBFluteを使う

# 目的

Springと親和性の高いOSS DBFluteですが、公式ドキュメントでSpring Boot固有の説明があまりないためアドベントカレンダーで世に出します。


# 環境

2023/12/15時点。下記のバージョンで動作確認して記事を書きました

- JDK 17
- DBFlute 1.2.7
- Spring Boot 3.2

# DBFluteを導入してみよう

## Spring Bootプロジェクトを作る

Spring Initializrで Spring Bootプロジェクトを作成します。

### ポイント
    
1. DBFluteのセットアップがMavenベースなのでMavenを選択。Gradleを使いたい場合、実行時はGradleを使うことも可能です
2. コンパイルと実行に必要な、JDBC と JDBCドライバも選択しておきます


## DBFluteをセットアップする

https://dbflute.seasar.org/ja/environment/setup/maven.html の通りです。

Spring Bootでは下記を追加で行います。

1. Spring BootはMaven Wrapperを利用しているので、DBFlute公式ドキュメントで `mvn` は `mvnw` に読み替えて実行します
1. 後述しますが、Spring BootのConfigurationをします
1. JDBCドライバのセットアップはSpring initializeで済ませることができます

### pomにDBFlute プラグインとランタイムを追加

https://dbflute.seasar.org/ja/environment/setup/runtime.html

https://dbflute.seasar.org/ja/manual/function/helper/maven/index.html

ここまでできたら、mvnwでDBFluteエンジンをダウンロードします。

```
./mvnw -e dbflute:download
```

これで自分のSpring Bootプロジェクトの配下にmydbfluteという名前のディレクトリができ、DBFluteエンジンがダウンロードされます。

## DBFluteクライアントの作成

引き続き、DBFluteクライアントを作成します。

```
mvnw -e dbflute:create-client
```
これで自分のSpring Bootプロジェクトの配下にdbflute_`pomで設定した名称` という名前のディレクトリができ、DBFluteに必要な設定類が生成されています。


## DBFluteプロパティの基本設定
ひとまずは最低限2つを設定します。それ以外は必要に応じて修正すれば良いので、この記事では扱いません。
1. basicInfoMap.dfprop
1. databaseInfoMap.dfprop

### basicInfoMap.dfprop

標準でDIコンテナにSpringを利用するようになっていますので、Spring Bootを利用する場合修正不要です。

### databaseInfoMap.dfprop

https://dbflute.seasar.org/ja/manual/reference/dfprop/basicinfo/index.html#targetcontainer

利用したいデータベースに応じて書き換えます。

## クラスの自動生成

DDL, DMLの類を用意して自動生成します

https://dbflute.seasar.org/ja/environment/setup/generate.html

## Spring BootのDataSourceを設定する

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#data.sql.datasource.configuration

基本的にはdatabaseInfoMap.dfpropに追加した接続情報と同じになると思いますが、アプリケーション動作専用のデータベースユーザに変更することがあるかもしれません。

# セットアップ後

コードとテストを書いていきます。

Spring Boot 3.1/JDK 17/DBFlute 1.2.6でexampleを作成しています。

一部未完成ですが、参考にどうぞ。
https://github.com/dbflute-example/dbflute-example-on-springboot


# 導入後に必要な運用

## DBFluteのバージョンアップ

`manage.sh 94` を起動して、出力されるメッセージを参照してください。

## スキーマの変更やデータの投入

ReplaceSchemaを利用できます。

# 課題 
## DBFluteとSpring Bootで冗長化複数DBを実現したい

2023/12時点でdbflute-example-on-springbootには未実装ですが、SpringのAbstractRoutingDataSourceを利用できます。

## スキーママイグレーションでDBFluteのReplaceSchemaを使うか

DBFluteにもReplaceSchemaがあります。一方Spring BootでもFlywayとLiquibaseがサポートされています。

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.data-initialization.migration-tool

DBFluteをORマッパとしてのみ使い、flywayでスキーママイグレーションすることも可能です。Spring Bootの機能をどこまで使うか、DBFluteの機能をどこまで使うか決めておくと実装運用しやすいでしょう。

## DBFluteとTestcontainersをどう組みあわせて使うか

作者が試せていません。試した方いらしたらぜひ教えてください。

# 最後に

この記事への質問などは作者までお願いします。

DBFluteへのご意見、ご感想、質問などありましたら、SlackやGoogle Groupで質問するとコミュニティで答えられます。

https://dbflute.seasar.org/ja/manual/topic/office/feedback.html

最後まで読んでいただきありがとうございます。
VSM（バリュー・ストリーム・マッピング）って何？

# VSM（バリュー・ストリーム・マッピング）とは
VSMとはプロセス改善に用いる手法で、リーン（無駄をなくす）生産方式手法のことです。
この手法により「バリューストリームマップ」という図を作成し、
対象としたプロセスの全体像をチームで共有・分析し、改善に取り組みます。

## バリューストリームマップでは、こんな図を書きます

![](https://image.slidesharecdn.com/app013-171221061546/75/app013-22-2048.jpg?cb=1665809764)

※参考にさせて頂きました、[こちらのサイト](https://www.slideshare.net/TechSummit2016/app013)より。

上記の図では「DB準備」から始まり、「デプロイ後処理」までの一連のプロセスをVSM（バリュー・ストリーム・マップ）で表現しています。

## どう見たらいいのか？
VSMで知るべき関心事は、ざっくり2つあります。

### プロセスの全体像を知る
1つはプロセスの全体をチームで共有することにあります。
複数人で一連のプロセスを実施している場合、担当する作業・その前後しか知らず、全体は誰も知らない、なんてこともあるかと思います。

また、プロセスの上部には、それぞれのプロセスで使用しているサービス・ツール、さらに上部ではクラウド等の環境情報も記載します。

VSMを通して、
どんなプロセスがあり、
どの環境でどんなサービス・ツールを使って、
どの順番でプロセスが進んでいくのか、
全体を図で表現し、チームで共有しましょう。

### 各プロセスの数字を知る
もう1つは各プロセスのリソース、各種時間を知ることです。

| 項目  | 説明  |
|-----|-----|
|  人数   |  プロセスを担当している人数   |
|  リードタイム(LT)   |  プロセス完了までの所要時間   |
|  プロセスタイム(PT)   |  プロセス中の作業時間   |
|  待ち時間(WT)   |  プロセス完了までで作業以外に消費されている時間   |

これらをもとに人数、所要時間の適正を評価します。
特に各時間の項目は、以下の関係にあります。
```
リードタイム(LT) ＝ プロセスタイム(PT) ＋ 待ち時間(WT)
```

つまり、待ち時間(WT)が無駄な箇所と言うことになり、
一番、待ち時間(WT)が多いところはどこか？
待ち時間(WT)をなくすためにはどうすれば良いか？

と言った議論に繋がるようになります。

# VSMをどう使えば、プロセスを改善できるのか？
VSMを使ってプロセスを改善する場合、以下の段取りで進めていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569086/98a279e1-adde-4917-b01b-18dabd97ee11.png)

## 1. 改善したいプロセスを決める
まず、改善したいプロセスを決めます。
誰に何を届けるプロセスを改善したいのか？
そのプロセスはどこから始まるのか？
VSMに取り組むメンバー、取り組んだ結果を共有するメンバーとで、共通認識を持つためにもプロセスの範囲を決めることは重要です。

## 2. 現行VSMを作る
改善対象のプロセスが決まったら一連の作業をVSMと言う手法で図に示し、可視化します。
ここで作られた図を現行VSMと呼びます。

## 3. 現行VSMを分析し改善
現行VSMをメンバーで共有して分析、ボトルネックとなる部分を探します。
ボトルネックを見つけたら、それに対する改善案を検討します。

## 4. 改善を施した次期VSMを作成
改善案を検討出来たら、それらを盛り込んだ新しいVSMを作ります。
これが次期VSMとなります。

## 5. 次期VSMに従い、プロセスを実施
次期VSMを作成出来たら、メンバーと共有してプロセスを実施します。

## 6. 次期プロセスを評価する
次期プロセスを実施し始めたら、今度はそのプロセスが良かったか評価しましょう。
この場合、「2. 現行VSMを作る」に戻りましょう。

作成した次期プロセスを再度計測し、検討した通り出来ているか？
実務のプロセスとして何回も実施する上で他に問題となるポイントは出ていないか？
など確認していきます。

# 参考文献

https://www.atlassian.com/ja/continuous-delivery/principles/value-stream-mapping

https://blog.shibayu36.org/entry/2021/08/10/173000

https://www.slideshare.net/TechSummit2016/app013

https://dev.classmethod.jp/articles/value-stream-mapping/

https://qiita.com/i35_267/items/1c2d75861b55c537f1e0