OmniAICreator/Qiita-1.07M huggingface dataset:
【備忘録3】Ruby：異なる文字で文字列を分解したい

これまで文字列の分割にはsplitメソッドを用いてきました。

しかし、それは1種類の文字の場合、例えば ”,” のような、だけで、複数の文字で分割しなければならない場合には対処できませんでした。

このような場合の解決策をいろいろ調べたのでメモとして残します。

# 異なる文字で文字列を分解するには、gsubメソッドとsplitメソッドを使う

考え方としては異なる文字を、同じ文字に置換してから分割すればいいらしい。

確かに、同じ文字にしてしまえばsplitメソッドを用いて分割ができますね。なるほどなるほど。

ですが、ここで問題になるのは、どうやって異なる文字を同じ文字に置換するかということです。

この問題の解決のためには、gsubメソッドを用いるといいらしいです。

## gsubメソッドの使い方

gsubは正規表現のパターンにマッチした文字列をすべて置き換えるためのものです。

基本的な構文は以下の通りです。

```ruby
置換対象の文字列.gsub(/置換前の文字列/,置換後の文字列)
```

対象の文字列から置換対象の文字を探し、指定した文字で置換するのがgsubメソッドです。

例えば、以下の文章で「Japanese」を「English」に置換したい場合、gsubメソッドを用いれば。文中全ての「Japanese」を「English」に置換できます。

> 【例文】
I will study Japanese in Japan. Because I like Japanese culture very much. But, I speak Japanese a little. So, I study hard.
> 

```ruby
#gsubの場合
article = "I will study Japanese in Japan. Because I like Japanese culture very much. But, I speak Japanese a little. So, I study hard."
article1 = article.gsub("Japanese", "English")
puts article1
#=> "I will study English in Japan. Because I like English culture very much. But, I speak English a little. So, I study hard."
```

## subメソッドとの違いに注意

gsubメソッドと同じようなものにsubがあります。

ただし、気をつけておきたいのは、gsubメソッドが文中に出てきた全ての文字を置換するのに対し、subメソッドは最初に出てきたものだけが置換されるということです。

先程の例文でsubメソッドを使った場合、処理結果は以下のようになります。

```ruby
#subの場合
article = "I will study Japanese in Japan. Because I like Japanese culture very much. But, I speak Japanese a little. So, I study hard."
article1 = article.sub("Japanese", "English")
puts article1
#=> "I will study English in Japan. Because I like Japanese culture very much. But, I speak Japanase a little. So, I study hard."
```

全てを置き換えるのがgsubメソッド、最初のものだけを置き換えるのがsubメソッドと覚えておくといいかもしれません。

# 異なる文字をgsubメソッドで置換し、splitで分割する

それではgsubとsplit両メソッドを使って、異なる文字がある場合の文字列の分解方法をみていきます。

そこで今回は、本日の日付と時刻を分解し、出力する場合を考えてみましょう。

参考問題は以下のとおりです。

[プログラミング練習問題「日時データの変換その２」](https://paiza.jp/works/mondai/string_primer/advance_step3)

## 入出力値

【入力値】

2022/11/1 19:00

【出力値】

2022
11
1
19
00

## 考え方

まずはデータを受け取ります。Stringで受け取りたいのでto_sを用います。

```ruby
a = gets.to_s
```

受け取ったデータをsplitメソッドを用いて分割していきたいのですが、この受け取ったデータには　”/”、”  “、”:”　の異なる文字が入っているため分割ができません。

そこで、gsubメソッドを用いてこれらを「,」に変換し、splitメソッドで分割します。

```ruby
a = a.gsub("/", ",").gsub(" ", ",").gsub(":", ",") #=> 2022,11,1,19,00
```

これでそれぞれの文字が「,」に変換されました。

それでは、splitメソッドを用いてデータを分割し、それらを出力しましょう。

```ruby
puts a.split(",")
```

これで期待される値が出力できました。

今回記述したデータは以下のとおりです。

```ruby
a = gets.to_s
a = a.gsub("/", ",").gsub(" ", ",").gsub(":", ",") #=> 2022,11,1,19,00
puts a.split(",")
```

# まとめ

- 異なる文字をsplitメソッドで分割したい場合は、gsubメソッドを用いて異なる文字を同じ文字に置換する
- gsubメソッドに似ているものにsubメソッドがあるが、gsubメソッドが全ての文字を置換するのに対し、subメソッドは最初に出てきた文字のみを置換する

他にいい方法がありましたらご教授ください。

また誤っている箇所がありましたらご指摘ください。

# 参考サイト・資料

https://madogiwa0124.hatenablog.com/entry/2017/09/15/194348

https://hataworakuni.net/substitute-in-ruby

https://docs.ruby-lang.org/ja/latest/method/String/i/gsub.html
ソラカメAPI備忘録

# 概要
SORACOM社のソラカメ用APIを使うときに、
困ったり調べたことを備忘のために書き留めています。

※SORACOMのソラカメ用APIのリファレンス
  [https://users.soracom.io/ja-jp/tools/api/reference/#/SoraCam](https://users.soracom.io/ja-jp/tools/api/reference/#/SoraCam)

# メモ

### 動画ダウンロード用URLの有効期限
APIで動画のエクスポートを依頼すると、ダウンロード用のURLが発行されます。
このURLには有効期限があります。

この有効期限、どこにも正確な時間が書いてなさそうだったので、
観測してみたところ、**14分で有効期限が切れていました**。
⇒有効期限が切れると、ダウンロードできません。

### APIの呼び出し制限
SORACOMのAPIには、1分間に呼び出せるリクエスト数の制限があります。
APIグループ単位でリクエスト数の制限を設けているとのこと。
[https://users.soracom.io/ja-jp/tools/api/limitations/](https://users.soracom.io/ja-jp/tools/api/limitations/)

これ、どこにもまとまった情報が無さそう。
もしかしたら、（サーバー側の負荷に応じて）動的に変わるのかな？
実行したらリクエスト数の制限値が取得できるので、
とりあえずそれを書き出してみる。

■カメラ一覧取得（/sora_cam/devices）
　X-Soracom-Ratelimit-Limit : 100

■動画エクスポート用API（/sora_cam/devices/{device_id}/videos/exports）
　X-Soracom-Ratelimit-Limit : 2

■動画エクスポート状況確認用API（/sora_cam/devices/{device_id}/videos/exports/{export_id}）
　X-Soracom-Ratelimit-Limit : 100


これから少しずつ書き溜めていきます。
【Python】四捨五入処理の落とし穴

# 目的
　本記事の目的は筆者自身がPythonの四捨五入に躓き、学習と同時に作成している。
また、Pythonの四捨五入するための構文を控えておくための記事である。


# Pythonの四捨五入はどのように記述すれば良いか
　まずは結論としてPythonにおける四捨五入記述を下に記す。
decimalモジュールを使用して四捨五入を処理している。
```Python:pythonにおける四捨五入の記述例①：小数点以下第1位を四捨五入
from decimal import Decimal, ROUND_HALF_UP    # 「import *」 でも可
a = 2.5
round_a = Decimal(a).quantize(Decimal('0'), rounding=ROUND_HALF_UP)
print(a, round_a)
```
```python
2.5 3
```
```python:pythonにおける四捨五入の記述例②：小数点以下第3位を四捨五入
from decimal import Decimal, ROUND_HALF_UP
b = 1.005
round_b = Decimal(b).quantize(Decimal('0.001'), rounding=ROUND_HALF_UP)
print(b, round_b)
```
```python
1.005 1.01
```
ただし、上記四捨五入結果 `round_a`, `round_b` の型は`decimal.Decimal`となっているため、int型やfloat型と演算する際には注意が必要である。
その場合は`float(round_A)`のように型の変換を組み込む必要がある。


# Pythonのround関数は四捨五入ではない
## 四捨五入について
　Pythonにて数値計算をする際、下記のようなround関数を使用したことがあるのではないだろうか
```python:round関数の記述例
value1 = round(5.4, 0)
value2 = round(5.5, 0)
value3 = round(6.4, 0)
value4 = round(6.5, 0)
```

しかしながら、Pythonのround関数は俗に言う四捨五入と呼ばれる処理ではない。
偶数丸め(銀行丸め)と呼ばれる処理であるため、時には四捨五入を期待して実装したプログラムが意図しない挙動を起こす。

```Python:round関数記述例の出力
print(value1, value2, value3, value4) 
# それぞれ 5.4, 5.5, 6.4, 6.5
```
```Python
5.0 6.0 6.0 6.0
```
上記の出力例では、5.4, 5.5, 6.4は問題なく四捨五入が行われているが、6.5については切り捨て処理が行われている。これは偶数丸めによって偶数になるように切り上げ、切り捨てが選択されているためである。

## decimalモジュールについて
　では、どのように記述すれば四捨五入が可能になるか。最もシンプルな方法は、decimalというモジュールを使用する方法と思われる。

### decimalモジュールとは
　decimalモジュールは十進数計算を正確に表現するために用いられるPythonの標準ライブラリの一種である。

　コンピュータは2進数で計算を実行しているため、出入力の際は人が日常的に用いている10進数から変換、または10進数へ変換する必要がある。
10進数の浮動小数点型から2進数の浮動小数点型へ変換すると、基本的に無理数となってしまうため、正確に表現できないことが多い。そして、無理数を無理数のまま計算に用いることはできないため、ある程度で切った値を用いるが、この切った値を再び10進数に再変換するときにズレが生じる。
`ズレ例：1.1 + 2.2 = 3.3000000000000003`
|10進数 | |2進数 |
|:---:|:---:|:---:|
|1 |⇒ |0001 |
|2 |⇒ |0010 |
|3 |⇒ |0011 |
|123 |⇒ |0111 1011 |
|123.456 |⇒ |0111 1011.0111 0100… |

decimalモジュールはこのズレが発生しないように正確に計算するためのモジュールである。

### decimalモジュールのメソッド
　decimalモジュールのメソッドの一部を下に記す。
|メソッド名 |説明 |
|:---:|:---:|
|quantize() |位を固定して数値を丸め込む。 |
|getcontext() |現在のDecimal型の演算環境設定を出力する。 |
|setcontext() |現在のDecimal型の演算環境設定を書き換える。 |




# 参考記事
https://atmarkit.itmedia.co.jp/ait/articles/2104/06/news022.html

https://dev.classmethod.jp/articles/python_decimal/

https://docs.python.org/ja/3/library/decimal.html

https://marusankakusikaku.jp/python/standard-library/decimal/#decimal%E3%81%AE%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89
Hyper-VのLinuxゲストを別のインスタンスへコピー

# 動機
HyperVで動かしていたVM，なぜか大量のチェックポイントが生成されてしまい，チェックポイントを削除してマージもできなくなった．
そこで，新VM(第2世代)を作成し，旧VM(第1世代)からファイルをコピーすることにした．

# 手順
## 新VM
1. 新VMを準備．このとき世代を第2世代で作成した．セキュアブートはMicrosoft WindowsからMicrosoft UEFI証明機関に変更しておく．LiveCDで起動．こちらもDebianのnetinstで起動．
1. ipを192.168.xxx.yyyに設定
1. ディスクのパーティションを設定する．
   + EFI用にパーティション(sda1)を準備．
   + /用のパーティション(sda2)を用意．このとき元のVMだとext4でフォーマットしていたが，btrfsにした．
   + swap用のパーティション(sda3)を用意．
1. `mkdir /tmp/root`
1. `mount -t btrfs -o compress=lzo /dev/sda2 /tmp/root`
1. `btrfs subvolume create /tmp/root/@rootfs`
1. `umount /tmp/root`
1. `mount -t btrfs -o compress=lzo,subvol=@rootfs /dev/sda2 /tmp/root`
1. これで新VMの準備ができたので，旧VMからファイルを受け取るために以下のコマンドを実行．
`cd /tmp/root; nc -l -p 12345| tar xvpf -`

## 旧VM
1. 旧VMのlinuxをシャットダウン
1. LiveCDで起動．今回はDebianのnetinstを使った．
1. 旧VMからファイルを送る．まずファイルシステムをマウントする．
`mkdir /tmp/root; mount /dev/sda2 /tmp/root; cd /tmp/root`
1. 新VM(192.168.xxx.yyy)へファイルを送信する．netinstではrsyncとかないのでncを使う．
`tar cvf - . | nc 192.168.xxx.yyy 12345`

## 新VMの後処理
1. EFIパーティションをマウント
`mount /dev/sda1 /tmp/root/boot/efi`
1. chroot後に必要なファイルシステムを設定．
`for f in /dev /dev/pts /proc /sys ; do mount -B $f /tmp/root$f; done`
1. `chroot /tmp/root`
1. `modprobe efivarfs`
1. `grub-install --target=x86_64-efi --efi-directory=/boot/efi --recheck /dev/sda`
1. /etc/fstabを修正．blkidでuuidを確認して変更する．また/をext4からbtrfsに変更したのでファイルシステムとオプション`compress=lzo,subvol=@rootfs`などを設定．

# まとめ
LiveCDで起動して，ファイルシステムをtarとncを使ってリモートへ送ってコピーする．今回はHyperVで行なったが，実機でも同じようにできるはず．またイメージではなくファイルのコピーを行なっているので，ext4からbtrfsへファイルシステムの変更も可能．

HyperVのVMを第2世代にしたことで，biosではなくEFIでブートすることになるが，grubの設定を更新することで無事にブートした．

netinstのイメージがあったのでnetinstを利用したが，別のliveCDがあればそれを使うのが便利だとおもう．試してないが[antiX](https://antixlinux.com/)とかを使うと使えるコマンドも増えてよさそう．
USD 22.11 を Windows で C++ 用に mindep ビルドするメモ

## 背景

漢には, Windows で C++ で pxrUSD 使わねばならぬときもある... C++ でコアの機能(UsdGeomMesh とか)が使えればよい. usdImaging とか Hydra とか Python binding はとりあえずはいらない.

pxrUSD の Windows ビルドめんどくさすぎじゃ...

Prebuilt あるけど, 

https://developer.nvidia.com/usd

Python 付き + VS2015(v141) でビルドされているため, C/C++ で pxrUSD の API だけ使いときにいろいろ問題ある(VS2019~ だと v142 なので, boot-python.lib 関連がなくてリンクできないなど)

## 環境

* VS2019 or VS20222
* (mini)conda
* Windows 10 or 11

## 手順

https://github.com/PixarAnimationStudios/USD#windows

の python のビルドスクリプトを使います.

優秀な若人さまにおかれましては, 機械学習で Python 環境は conda で作っているかと思いますので, 今回 conda 使います.

conda インストールして, `conda init` しておくと `PATH` など環境変数設定してくれますのでやっておくとよいでしょう.

Python は 2020/11 時点では 3.8 以上がよいと思いますが, 今後 USD を Python 付きでビルドするかもを想定し, 一応互換性考えて 3.7 環境を作っておきます.
(また古い USD のバージョンだと Python 3.8+ 対応していない)

```
> conda create -n usd-22 python=3.7
```

VS の開発環境に入り(or vcvarsalllbat をよぶ https://stackoverflow.com/questions/43372235/vcvarsall-bat-for-visual-studio-2017), conda で activate しておきます.


あとはいろいろ disable してビルドするだけです!
今回は `--build-monolithic` つけてみました.

```
python USD\build_scripts\build_usd.py --no-python --build-monolithic --no-openvdb --no-materialx --no-ptex --no-embree --no-prman --no-hdf5 --no-alembic --no-draco --no-docs --no-imaging --no-openimageio --no-opencolorio  USD-dist-22_11
```

その他, お好みで調整して. App が Debug ビルドする場合, CRT のデバッグ機能などと合わせるために pxrUSD も `--debug` つけてビルドする必要があると思います.

## usd file format plugin folder

.dll を App フォルダにコピって使っているばあい, USD ファイルを Open しようとしても cannot determine format error というエラーがおきるときがあります.

https://github.com/PixarAnimationStudios/USD/issues/1617

これは pxrUSD が .usda, .usdc でも file format 情報を  plugin JSON `<dist>/lib/usd` にあるファイル群から読み取る必要があるためです!(monolithic build とか dll ビルドのときでも同じ). めんどくさいネ...

`PXR_PLUGINPATH_NAME` で環境変数を設定するか, C++ で PluginRegistory で登録してあげる必要があります.

(Linux だと .so ファイルは通常動かさないので, plugin info ファイルを .so からの相対パスでうまく見つけてくれる模様)
`

## Monolithic build

USD を monolithic にビルドしている場合, リンクするライブラリ名は `usd_ms.lib` になります.
 
## 使うときの注意

TBB が, Debug ビルド時に `TBB_USE_ASSERT` などマクロ定義してあげる必要があるときがあるかもしれません.

https://www.cism.ucl.ac.be/Services/Formations/ICS/ics_2013.0.028/composer_xe_2013/Documentation/en_US/tbb/help/reference/environment/enabling_debugging_features.htm



## Seg fault 問題

ただ, なんかビルド構成によるのか, pxrUSD API 内で exception が起きてしまうときがあります...
どうも Debug build かどうかだったり Unicode/MBCS charset 問題のもよう...
VirtualBoxをMacからアンインストールする方法

# 概要

- VirtualBoxをMacからアンインストールする方法をまとめる。

# 情報

- 筆者のMacはIntel Macである。

# 方法

1. 下記にアクセスする。
    - [https://www.virtualbox.org/wiki/Downloads](https://www.virtualbox.org/wiki/Downloads)

1. 「macOS / Intel hosts」をクリックする。

    ![Downloads_–_Oracle_VM_VirtualBox.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/9e15acfa-f322-e391-8d63-d8651ce4fc37.png)

1. ダウンロードされたインストーラー（VirtualBox-7.0.2-154219-OSX.dmg）を開く。
1. 「VirtualBoninstall.tool」をダブルクリックする。

    ![VirtualBox.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/47d95040-33f0-523d-fcc5-6e228aae7cd1.png)

1. 下記の様な警告が出た場合、一旦OKをクリックし、Mac本体の設定から「セキュリティとプライバシー」をクリックし、2枚目の画像の「このまま開く」をクリックする。

    ![スクリーンショット_2022_11_01_17_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/b4205973-7d35-4f29-310b-a49d245df0b1.png)
    ![セキュリティとプライバシー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/60bd9d4b-c716-0872-b91c-a17eb75b2f9c.png)

1. 下記の様なウインドウが出たら「開く」をクリックする。

    ![スクリーンショット_2022_11_01_17_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/ba7b410a-21d4-eca0-662c-e4fd15234abb.png)

1. ターミナルが開いたら`/Volumes/VirtualBox\ 1/VirtualBox_Uninstall.tool`と入力してEnterを押下する。場合によってYes/Noの入力をこの先で求められる事があるので必要に応じて入力してEnterを押下する。

    ![okawashun_—_bash_—_bash__figterm__▸_bash_—_80×24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/edd1fcfd-3b09-4c73-530e-1d72bb7ea5b8.png)

1. 下記の様にDoneと出力されたアンインストールが完了しているはず。

    ![okawashun_—_bash_—_bash__figterm__▸_bash_—_80×24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/7f976615-ffe1-db07-605c-763015e9d8bb.png)

1. 関連ファイルがまだ残っているので下記をすべて削除する。

    ```shell
    rm -rf ~/Library/VirtualBox
    rm -rf ~/Library/Preferences/org.VirtualBox.app.VirtualBox.plist
    rm -rf ~/Library/Saved Application State/org.VirtualBox.app.VirtualBox.SavedState
    rm -rf ~/Library/LaunchAgents/org.virtualbox.vboxwebsrv.plist
    rm -rf ~/Library/Saved Application State/org.VirtualBox.app.VirtualBox.SavedState
    rm -rf ~/VirtualBox\ VMs/
    ```

# 参考文献

https://www.drbuho.com/jp/how-to/uninstall-virtualbox-mac
SendGridのAPIを作成する

## 概要
- SendGridでAPIを作成する方法を備忘録として残します。


____
↓[公式サイト](https://sendgrid.kke.co.jp/about/)から引用
**SendGridとは**
SendGridは全世界で利用されているメール配信サービスです。
クラウドサービスのためアカウントを作成するだけで即日メールを
送信でき、面倒でコストのかかるメールサーバの構築は不要です。
___

**公式サイト**
[【SendGrid】本家のサイト](https://sendgrid.com/)
※英語です。
  
  
[【SendGrid】構造科学研究所経由](https://sendgrid.kke.co.jp/)
※構造計画研究所はSendGridの正規代理店です。
  
どちらでやってもOKですが、日本語サポートなどが欲しければ構造科学研究所経由の方がいいかもしれません。

## ステップ1/2 - アカウント作成
#### 方法1: 本家のサイト ####
- 『Start for free』をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834744/a2bc462c-ff5f-7512-8549-25667df82b13.png)
  
- ID、パスワードを入力し、『Create Account』をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834744/d2ee657e-87f6-c960-b18c-b79b3b28625b.png)


#### 方法2: 構造科学研究所経由のサイト ####
- 『無料ではじめる』をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834744/e2056cce-b33b-ceaa-61d5-586462b3743a.png)
  
- メールアドレスを入力し、『確認メールを送付する』をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834744/ae771ebe-715a-b3d3-e4c2-b0d398f1e6d1.png)
  
※ここから先は画面キャプチャなしです。
- 確認メールが届くので、指示に従って対応する。
- 個人情報を入力する。
- 仮登録完了。
- 入力に不備がある場合は、構造科学研究所の方から確認メールが届くので、指示に従って対応します。
- 問題なければ、正式登録完了し、ID(＝ユーザー名)が発行されます。
    - ユーザー名：　hogehoge@kke.com
    - パスワード：　登録時に自分で指定したパスワード
  
## ステップ2/2 - API作成
- [【SendGrid】本家のサイト](https://sendgrid.com/)に行きます。
- 『Sign In』をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834744/69980301-9c44-9a97-743c-71986e830104.png)
  
- ID、パスワードを入力し、ログイン。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834744/2af08a29-d2f4-b525-36b2-73bb6232f45b.png)
  
- 2要素認証が求められるので、スマホSMSに届いた番号を入力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834744/2011cbad-31df-6a73-d9e7-a34546d78586.png)
  
- ダッシュボードが表示されます。
- 『Settings → API Keys』をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834744/f45a5c04-9c9c-6818-484c-2f0b977833d5.png)
  
- 『Create API Key』をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834744/053f2b30-08ef-b406-b688-65ec97ac5555.png)
  
- 『API Key Name』に任意のAPIの名前を入力。(例:hogehoge_delivery_info)
- 『API Key Permissions』にAPI Keyに付与するアクセスレベルを設定します。
- 『Create & View』をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834744/9902c76b-f172-2c1c-27fe-51afe263da13.png)
  
- API Keyが発行され、画面に表示されます。
- 忘れずにコピーして保管します。(注意:この画面を閉じると二度と確認できません)
- 『Done』をクリック。(コピーしないとDoneできません)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834744/aae58865-339b-0672-322d-5a137deb6683.png)
  
- API Key一覧画面に作成したAPIが表示されます。
- 『API Key ID』はAPIの一部しか表示されていませんので、この画面からコピーしてもNGです。ご注意ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1834744/0e924539-dffe-b0b4-78f3-bbd1c52a9937.png)


- 以上でAPI取得完了です！
動画・音声変換ツール「FFmpeg」をmacで使う

# 目次
[FFmpegをインストールする](#ffmpegをインストールする)
[FFmpegの使い方](#ffmpegの使い方)
[Operation not permittedが出た場合](#operationnotpermittedが出た場合)

# FFmpegをインストールする
<b>Homebrewを使ってインストールする</b>
[こちらの記事](https://fukatsu.tech/install-ffmpeg)参考

<b>Homebrewを使わずインストールする</b>
[こちらの記事](https://cyber-tenchou.com/tips/20200904/)参考

# FFmpegの使い方
macのターミナルからコマンドを叩くだけ。コマンドは以下に用途別でまとめておく

:::note warn
FFmpegのコマンドはオプションの種類が大量にあるので意味を理解するのに時間がかかる。
[こちらの記事](http://mobilehackerz.jp/archive/wiki/index.php?%BA%C7%BF%B7ffmpeg%A4%CE%A5%AA%A5%D7%A5%B7%A5%E7%A5%F3%A4%DE%A4%C8%A4%E1)にオプションがまとめて解説されていて参考になる
:::

**1. 動画ファイルから音声ファイルを抽出したい場合**
```
ffmpeg -i [抽出対象の動画ファイル] -vn -ab 128 [抽出後の音声ファイル名]
```
具体例
`ffmpeg -i goodbye.mp4 -vn -ab 128 hello.mp3`
<br>

**2. 動画の拡張子をmovからmp4へ変換したい場合**
```
ffmpeg -i [movファイル] [変換後のmp4ファイル名]
```
具体例
`ffmpeg -i goodbye.mov hello.mp4`
<br>

# Operation&nbsp;not&nbsp;permittedが出た場合
ターミナルからffmpegを実行した時に Operation not permitted エラーが出る場合がある。
以下の動画を参考にエラーを解消してね。

https://twitter.com/ChiyoGwan/status/1587348597883826176

**システム環境設定 → セキュリティとプライバシー → フルディスクアクセス → ターミナルを許可してあげる**
git revert の --mainline 2 について検証してみた

# 結論
先に書いておく。**使い所がわからんかった**。

## 発端
複数人で開発中のブランチで下記の事象が起きました。（DEV1とDEV2ブランチが存在するとします）
この時に、先にリリースする予定だった**DEV1より先にDEV2がメインブランチに合流**してしまった。
DEV2での変更がDEV1の変更に影響が有るリスクが高いので、DEV2のマージを取り消したい。

### 当時に採った対応
「マージコミットのリバート」とかでググると、大体以下のコマンドが出てきた。
```
$ git revert -m 1 <マージコミットのハッシュ>
```
ヘルプとかを読んでも問題無さそうなので脳死で入力した。
https://git-scm.com/docs/git-revert#Documentation/git-revert.txt---mainlineparent-number

### 疑問
オプションの`--mainline`を脳死で1を指定したが、`git revert --mainline 2`（マージした側のブランチ）を指定するとどうなるか？と言う訳で検証してみよう。そうしよう。:rolling_eyes:

## Let's 検証

### 準備
こんな感じで簡易的に実験してみる。

##### とりあえずREADMEに初回コミット
```diff:
+ 初回コミット
```
##### `master`から`develop`を派生して追記コミット
```diff:
  初回コミット
+ 開発で追記するよ
```
##### 競合を発生させるために`master`で追記する
```diff:
  初回コミット
+ 本流の追記コミット１行目
+ 本流の追記コミット２行目
```
##### マージするぞ
```
$ git checkout master

-- マージコミット付けとく
$ git merge --no-ff develop
Auto-merging README
CONFLICT (content): Merge conflict in README
Automatic merge failed; fix conflicts and then commit the result.
```
予定調和で衝突したので適当に解消させる。
`$ vi README`
これを、、
```diff:
初回コミット
<<<<<<< HEAD
本流の追記コミット１行目
本流の追記コミット２行目
=======
開発で追記するよ
>>>>>>> develop
```
こうじゃ！
```diff:
初回コミット
開発で追記するよ
本流の追記コミット１行目
本流の追記コミット２行目
```
解消をコミットして下準備が完了。
```
$ git add README
$ git commit

$ git log --oneline --graph
*   409bc75 (HEAD -> master) Merge branch 'develop' <= ★こいつを revert で取り消すぞ
|\
| * d8487d0 (develop) 開発で追記
* | c128797 本流の追加コミット
|/
* 5191404 初回コミット
```

### マージを取り消してみる
まずは、通常で使う**合流ブランチの変更を取り消す**方から、
`$ git revert -n -m 1 409bc75`
READMEの内容は？
```
初回コミット
本流の追記コミット１行目
本流の追記コミット２行目
```
まぁ、当然やな。
次は試したかった、**本流ブランチの変更を取り消す**方やるぞ！
間違えてマージ前まで戻っちゃったのでハッシュ変わっちゃった。
```
$ git log --oneline --graph
*   25a8a33 (HEAD -> master) Merge branch 'develop'
|\
| * d8487d0 (develop) 開発で追記
* | c128797 本流の追加コミット
|/
* 5191404 初回コミット
```
`$ git revert -n -m 2 25a8a33`
`$ less README`
```
初回コミット
開発で追記するよ
```
うん。。まぁ挙動としては理解できるよ。

### どう言うことだってばよ？
まぁあれだ、衝突に対して、**どちらの変更を残すか**って事だよ。
この辺はググればたくさん出てくるが、マージコミットでは **合流先**と**合流元** のハッシュを持ってます。
```
$ git log
commit 25a8a333d07d518eb6938713776755fac6412c2f (HEAD -> master)
Merge: c128797 d8487d0
Author: ****************
Date:   Fri Oct 28 20:11:13 2022 +0900

    Merge branch 'develop'
```
リバートする際は、どちらの変更を正とするか指示しているだけみたい。
チェックアウトコマンドで`--ours`と`--theirs`を指定するみたいな物だね。

検証してないですが、衝突してなかったら単純に差分が消去されるだけになると思うよ。
あと revert の逆の cherry-pick でもやる事は同じだと思うよ。
https://git-scm.com/docs/git-cherry-pick#Documentation/git-cherry-pick.txt---mainlineltparent-numbergt
Netlify のBuild hooksはキャッシュを持っている

## 状況

CMSのサーバーを変更した際に、何度Netlifyのキャッシュをクリアしても古いCMSの情報が読み込まれて困った


## 結論
NetlifyのBuild hooksはキャッシュを持っているようで、新しくhookを作成しなおせば解決！
旧バージョンのVagrantをMacにインストールする方法

# 概要

- 2022/11/01現在、Vagrantの最新バージョンは2.3.2だが旧バージョン（2.2.5）をインストールする方法をまとめる。

# 前提

- すでに筆者のPCにはHomeBrewで2.3.2のVagrantが入っていたので下記コマンドを実行して最新のVagrantをアンインストールする。

    ```shell
    brew uninstall vagrant
    ```

# 方法

1. 下記にアクセスする。
    - [https://developer.hashicorp.com/vagrant/downloads](https://developer.hashicorp.com/vagrant/downloads)

1. バージョン選択プルダウンで「2.2.5」を選択し「Mac」が選択されていることを確認して「Download」をクリックする。!

    ![Install___Vagrant___HashiCorp_Developer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/da864c00-10dd-866f-617f-02e5f13f45c3.png)

1. ダウンロードされた「vagrant_2.2.5_x86_64.dmg」をダブルクリックで開く。
1. 「vagrant.pkg」をダブルクリックする。

    ![Vagrant.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/5f07b172-3259-3bea-41b4-b918b1b9ae0c.png)

1. インストーラーに沿ってインストールしてゆく。

    ![スクリーンショット_2022_11_01_16_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/e9ff1245-3499-df8b-51e7-3422d55e96fe.png)
2022年11月 AIOps 定点観測

# 概要
AIOps の動向や学習のため、Google で AIOps を検索した結果を記録している記事です。

# 2022年11月1日の検索結果 (リスティング広告)

![20221101_AIOps_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345504/182db139-7957-4698-4995-beb57b301083.png)

* IBM
* Dynatrace

今月は広告が表示されたのが 2社だけでした。

先月の結果はこちら --> [2022年10月 AIOps 定点観測](https://qiita.com/mkodera/items/c91398285c491a796734)

# 2022年11月1日の検索結果 (広告以外)

![20221101_AIOps_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345504/cacae681-c3c6-239a-3f17-f631e6ac3121.png)

* Splunk
* ServiceNow
* ITmedia
* JBSVC
* ニフクラ

広告以外だと、Splunk が相変わらずのトップです。5位にニフクラが初登場しました。

先月の結果はこちら --> [2022年10月 AIOps 定点観測](https://qiita.com/mkodera/items/c91398285c491a796734)
Unity Vtuber を作ってみた

https://github.com/aizwellenstan/UnityURPToonLitShaderVRMArKitTemplate

![AliciaPreview.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/62431186-f236-7bca-65b3-64f7a68800a9.gif)

## package
LiveCapture

## app
https://apps.apple.com/us/app/unity-face-capture/id1544159771

Step 1.
サーバー作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/b75f096a-5b05-d364-c7a8-973ea106d71c.png)

Step 2.
FaceMapper作成
モデルPrefab Attach, 左目、右目とHeadRotation設定
-> Add Render 

ARKit 52 BlenShapes設定
https://hinzka.hatenablog.com/entry/2021/12/02/005814

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/711c1e4f-5917-9a5a-69b1-3178e724263a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/6a4a4108-d044-e33d-3d01-b47b50cd09cb.png)

Step 3.
モデルPrefab FacelActor作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/747975e1-12e2-a338-1634-4f70d2827c4c.png)

Step 4.
Take Recorder作成
FaceMapper Attach
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/c2fe113a-47a3-adfe-1b8d-074bbd610782.png)

## VRM モデル
https://3d.nicovideo.jp/alicia/

## シェーダー
https://github.com/ColinLeung-NiloCat/UnityURPToonLitShaderExample
Shopify CLI環境で心地よい開発体験を求めて

# Shopify CLIとは
オンライン ストア 2.0テーマで新しく導入された機能。
わかりやすいものでいえば「Down」なんかがそれにあたりますね。

開発環境をローカルで用意して、ホットリロードしてくれたりと普段GulpやWebpackで開発しているフロントエンドよりの人でなら恩恵を感じられるはずです。

導入方法は、ドキュメントを参照

https://shopify.dev/themes/tools/cli

余談ですが、最近Shpify CLI 3もリリースされたので引き続き情報収集していく必要がありますね；；

https://shopify.dev/themes/tools/cli/migrate

## 好きなパッケージをインストール
Tailwindなど使いたい場合はインストールしてみましょう。
（個人的にはDown Themeからオリジナルテーマにする際Tailwindで調整するのが快適だったのでお勧めです。）

◆例
```bash
npm install -D eslint eslint-config-prettier eslint-plugin-import eslint-plugin-simple-import-sort eslint-plugin-tailwind eslint-plugin-unused-imports npm-run-all prettier prettier-plugin-tailwindcss stylelint stylelint-config-prettier stylelint-config-recess-order stylelint-config-recommended-scss stylelint-prettier stylelint-scss tailwindcss --legacy-peer-deps
```
◆tailwindのみインストールしたい場合
```bash
npm install -D tailwindcss
npx tailwindcss init
```

## Tailwindの設定ファイルカスタマイズしよう
@ver3系からjitモードではなくcontent[]で設定できるようになりました。
Downで開発する場合プレフィックスをつけてください。
既存の`grid`などのclassNameとバッティングする可能性があります。
```js:tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./*.liquid", "./**/*.liquid"],
  prefix: "tw-",
  theme: {
    extend: {},
    screens: {
      sm: "640px",
      md: "750px",
      lg: "990px",
      xl: "1280px",
    },
    fontFamily: {
      notosans: ["Noto Sans JP"],
    },
  },
  plugins: [],
};


```

自分は`package.json`でnpmコマンドを使用したいタイプなので、以下のようにしております。

※並列処理をするためにnpm-run-allを使用しております！
コピペしてもエラーが起きるので、まずはパッケージのインストールをしてください！
https://www.npmjs.com/package/npm-run-all
```json:package.json
     "scripts": {
        "login": "shopify login",
        "pull": "shopify theme pull",
        "dev:css": "tailwindcss -i ./src/css/app.css -o ./assets/tailwind.css",
        "build:css": "tailwindcss -i ./src/css/app.css -o ./assets/tailwind.css --minify",
        "build": "run-s build:css build:shopify",
        "build:shopify": "shopify theme push",
        "watch:css": "tailwindcss -i ./src/css/app.css -o ./assets/tailwind.css --watch",
        "serve:shopify": "shopify theme serve",
        "serve": "run-p serve:shopify watch:css",
        "eslint:fix": "eslint src --ext .js,jsx,.ts,.tsx --fix",
        "stylelint:fix": "stylelint src/**/*.{css,scss} --fix",
        "prettier:fix": "prettier --check --write 'src/**/*.{js,jsx,ts,tsx,css,scss,md,mdx,liquid}'",
        "format": "npm run eslint:fix && npm run stylelint:fix && npm run prettier:fix"
      }
```

## .shopifyignore
TailwindやGsapを使用したいときは `node_modules` をどうしても同じ階層にいれないといけないですよね。
`shopify theme pull`時に `package.json` と `package-lock.json` が消えてしまいます。

そこで.shopifyignoreを作成
以下を追加してあげましょう
これでpull時にファイルが消えることも無くなりました😇

```.shopifyignore
.gitignore

package.json
package-lock.json

postcss.config.js
tailwind.config.js

/node_modules
/src

README.md
```


## 開発環境でサクサク開発しよう！

開発ストアとshopify CLIを繋げたら
`shopify theme serve` で開発環境を立ち上げて
あとはホットリロードでサクサク開発することが可能です！
【テーブルビュアーUF】セル選択イベントでテーブルアクティブ行のビュアーを更新する【ExcelVBA】

## 前置きと説明
久々に社内でVBAの相談を受けたのですが、Accessでやるほどでも無さそうなレベルでこの手の使い道って汎用性高いんじゃないかと思い、簡単ですがまとめてみました。

横に長いテーブルのビュアーとしてユーザーフォームに表示したいそうなのですが、ユーザーフォーム側でプルダウンを作ってそれでフィルタリングしたいとのことですが、「フィルタリングとかは標準機能にしましょう。テーブル＆スライサーという素晴らしい標準機能があります。」と回答しました。

ビュアー用のユーザーフォームを作ったらシートモジュール側でWorksheet_SelectionChangeイベントを作ってユーザーフォーム更新プロシージャを呼べば終わりです。

## 仕上がりイメージ
![221101_uf_01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/3e65aee6-952a-0db1-8b3a-b39877536a13.gif)

## コード
### シートモジュール
``` vb:シートモジュール
Option Explicit


Private Sub Worksheet_SelectionChange(ByVal Target As Range)
  If IsActiveCellがテーブル上である(Target) = False Then: Exit Sub
  Call uf_sample.UF更新(Target.Row)
End Sub

Function IsActiveCellがテーブル上である(ByVal Target As Range) As Boolean
  Dim myListObj As ListObject
  Set myListObj = Target.ListObject
  
  IsActiveCellがテーブル上である = False  '初期値をFalseにしておく

  If myListObj Is Nothing Then
    'そのままFalseのまま
  Else
    If IsActiveCellがテーブルの値範囲である(myListObj, Target.Row) = True Then
      IsActiveCellがテーブル上である = True
    End If
  End If
End Function

Function IsActiveCellがテーブルの値範囲である(myListObj As ListObject, _
                                              TargetRow As Long) As Boolean

  With myListObj
    Dim rタイトル行 As Long
    rタイトル行 = .HeaderRowRange.Row
  End With
  
  If TargetRow = rタイトル行 Then
    IsActiveCellがテーブルの値範囲である = False
  Else
    IsActiveCellがテーブルの値範囲である = True
  End If

End Function

```

### ユーザーフォーム

ShowModalプロパティだけ`False`にしてください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/f30539b5-3ba6-3fb2-e184-ab95c06f93aa.png)

TextBoxのオブジェクト名
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281933/47047d79-466c-4ed5-d83e-34b3c46057a4.png)


`Text`とか`Value`とかは一例です。適宜変更してください。

``` vb:uf_sample

Public Sub UF更新(ByVal r現在行 As Long)
  Dim myListObj As ListObject
  Set myListObj = activecell.ListObject
  
  Call シートの値をユーザーフォームに出力する(myListObj, r現在行)

End Sub

Private Sub シートの値をユーザーフォームに出力する(myListObj As ListObject, _
                                                        行No As Long)
  
  tb_01.Value = Getテーブルの指定セル(myListObj, tbl_c_01, 行No).Text
  tb_02.Value = Getテーブルの指定セル(myListObj, tbl_c_02, 行No).Value
  tb_03.Value = Getテーブルの指定セル(myListObj, tbl_c_03, 行No).Value & "円"
  
End Sub

Private Function Getテーブルの指定セル(myListObj As ListObject, _
                                            列名 As String, _
                                            行No As Long) As Range
  With myListObj
    Dim rタイトル行 As Long
    rタイトル行 = .HeaderRowRange.Row
    
    Dim buf
    Set buf = .ListColumns(列名).DataBodyRange(行No - rタイトル行)
  End With
  
  If buf.Row = rタイトル行 Then: End  'ヘッダ行がアクティブならここでやめる
  Set Getテーブルの指定セル = buf

End Function

```

### 標準モジュール
``` vb:標準モジュール
Option Explicit

Public Const tbl_c_01 = "列1"
Public Const tbl_c_02 = "列2"
Public Const tbl_c_03 = "列3"

Sub ufShow()
  uf_sample.Show
End Sub

```
全人類寝顔晒そう計画【スクショ撮影編】

### お昼過ぎの時間は眠気との戦い。
お昼下がりの時間はお昼ご飯の影響で血糖値が急激に上昇したり、消化にエネルギーが使われ、脳にエネルギーが回らず眠たくなることが多いそうです。かくいう私もその一人で、お昼の時間は眠たい自分と戦うために昼寝の時間を入れてみたり、ガムを噛んでみたり試行錯誤の日々です。

### 一つの野望が生まれた。
そんな眠気と戦う日々の中で1つの野望が湧きました。
**みんながうとうと顔を晒したらもっと世の中は寛容になるんじゃないか。**
「昼過ぎはみんな眠たい」ということが認知されたら、きっと社会はもっと寝ることや居眠りに寛容になるんじゃないかなと思います。日本の多くの企業がシエスタ(お昼の長めの休憩)を導入するかもしれません。
今回はその野望の第一歩として、リモートワークをしている際にうとうとしている様子をスクリーンショットで撮影してくれるものを制作しようと思います。
名付けて **「うとうとウォッチャー」** です。

### 実際の結果がこちら
TeachableMachimeを用いて自分がうとうとして、うつむいている様子をスクショに撮ってくれるようにしました。実際にスクショされたものがこちらです。

https://twitter.com/rencoln1229/status/1587096085704556546?s=20&t=0Mk4VnIwonKjz0Q5EWz-Lw

「自分のうとうと顔も撮ってみたい！」という方がいらっしゃれば以下のリンクからお試しいただけます。

https://codepen.io/lotus1229/full/YzvyQmL

### 制作の流れ
簡単に制作の流れをまとめました。
#### 機械学習で学習パターンを作る
今回は機械学習パターンを作成するためにTeachableMachimeを使用しました。TeachableMachimeの詳しい使い方は以下の記事をご覧ください。
[Teachable Machineの利用方法を紹介します](https://qiita.com/misa_m/items/d8a20d153c8ee7daf0c1)
今回は下を向いている時だけ写真を撮りたいので、プログラム上では使用しませんでしたが判定制度を上げるために、人が映っていない状態や上を向いている状態、電話している様子も学習させました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2775528/55c6ca39-bb61-83fd-078d-95fd4c46f17f.png" width="60%">

最後にちゃんと判定がされるかを試して完成です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2775528/b2158359-0bbf-9548-2700-f591ce73a4d5.png"width="60%">
(髪型の荒ぶり方は置いといて)うまくいってそうです！


#### CodepenでHTML,CSS,Javaを作成する
今回はCodePenを使ってコードを書きました。
CodePenの使い方は以下の記事を参考にしました。
[CodePenの使い方(知らない人向け)](https://qiita.com/fumu238/items/f73274aa1a188eb15794)

スクリーンショットをどうやって撮影するのかわかっていなかったのですが以下のコードだけで実行できることを知り、感動しました。
```javascript
const video = document.getElementById('webcam');
```

### 全体像
以下にCodePenの全体像を掲載しております。
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="YzvyQmL" data-user="lotus1229" 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/lotus1229/pen/YzvyQmL">
  寝顔ウォッチャー</a> by lotus1229 (<a href="https://codepen.io/lotus1229">@lotus1229</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### 使ってもらった感想
今回は友達にうとうとウォッチャーを使ってもらいました。
なかなか撮影が実行されず、原因としてはおそらく機械学習のサンプル数が足りてないからと考えられます。今回は私の顔だけで制作を進めていたので、他の人のサンプルも加えてリベンジできたらなと思います。
また **「うとうとウォッチャーだし、眠気覚ましの方法とか一緒に教えてくれると嬉しい！」** という声をいただきました。みんなの寝顔を晒そうという僕のひねくれた計画とは反対の素敵な意見でした。

### 躓いた点
今回の制作でうとうと写真が撮影されたら自動的にTweetがされる、全自動うとうと顔晒しBotの完成まで進めたかったんですがTwitterAPIを使いこなせず今回は断念しました…
ぜひまたチャレンジして、みんなで自分のうとうと顔をシェアできる世界を目指します。
ソフトウェアの保守

# 保守の種類
## 予防保守
障害の発生を防ぐための保守で、計画的に実施する。

### 日常保守
システムが```稼働した状態```で行う。
システムを構成する```機器の状態や性能を監視```する。
```遠隔保守が利用されることも```ある。

### 定期保守
基本的に```システムを停止```して行う。
定められた```一定期間```ごとに、```機器の検査や部品の交換```を行う。

## 事後保守
障害発生後、または、```発生する可能性が高い```場合に実施する。

### 臨時保守
```通常の稼働状態と異なる状況```が発生した場合に行う。
```臨時的に実施される保守```で、致命的な障害を```未然に防ぐ```ことを目的としている。

### 緊急保守
システム停止など```障害発生時```に実施される保守。
障害の原因となった```機器の切り離し```や```置き換え```、```リカバリ作業```などを行う。

## 保守の外部委託
```外部企業と保守契約を結び、保守作業を委託```する。
* 開発プロセスを外部のソフトウェア企業(ベンダ)に委託した場合
* 自社で保守要員を常時雇用しない場合

### オンサイト保守
```期間を決めて定額```でサービスを行う。
```障害の頻度が多いと見込んだ時に有効```な契約。

### オンコール保守
```依頼ごとのスポット契約```でサービスを行う。
```障害の頻度が少ないと見込んだ時に有効```な契約。一般に```一回のサポートはオンサイト保守より割高```。

## 保守の作業
### 修正作業
プログラムの```バグを修正```する。
業務に支障をきたすため、```緊急を要するものが多い```。

### 変更作業
```税制や法律改正など```により、```税率や計算方法などの変更```を行う。

### 改良作業
```ユーザによる仕様変更や機能追加依頼```などへの対応（バージョンアップ)

## ソフトウェア製品の保守
### 是正保守
```ソフトウェアの引き渡し後```に発見された問題を```訂正する```ための保守。
是正保守実施までのシステム運用を確保するため、```一時的な修正を緊急保守```という。

### 予防保守
ソフトウェアの```潜在的な障害が現れる前に検出・訂正```するための保守

### 適応保守
```ソフトウェアの運用環境が変化した場合に、引き続き使用できるよう```修正を行う保守。
例えば、OSの更新に伴うアプリケーションの対応が該当する。

### 完全か保守
```ソフトウェアの性能または保守性を改善```するた目の修正を行う保守。

# 出典
https://gihyo.jp/book/2022/978-4-297-12375-8
【React】本日の日付をYYYY-MM-DD形式で表示する

new Date()
指定した時刻を表す日付オブジェクトを生成するメソッドです。

引数に日時、時間などを指定することができ、
何も指定されなかった場合は 現在のデバイスに設定されている時刻を取得します。

toLocaleString()メソッド
Dateオブジェクトを文字列に変換するメソッドです。

new Date()と組み合わせて、 new Date().toLocaleString() と書くことができます。

このようにして書くことで、現在時刻を取得し、文字列として表示することができます。

YYYY-MM-DD形式にフォーマットしたい場合

```typescript:sample.tsx
const today = new Date();
const formatted = today
  .toLocaleDateString("ja-JP", {
    year: "numeric",
    month: "2-digit",
    day: "2-digit",
  })
  .split("/")
  .join("-");
```
Headless Chromeを使ってCAPTCHAをバイパス

2CaptchaとPuppeteerを使ってCAPCHA突破を自動化

この内容はYouTubeでも視聴可能です。動画のほうが理解しやすい場合はこちらをチェックしてみてください。
[https://youtu.be/wsDRkAD6lPs](https://youtu.be/wsDRkAD6lPs)
CAPTCHAは10年以上にわたってインターネット上で見てきたと思います。ログイン、登録、またはどこかにコメントを投稿しようとするときに、道を塞ぐ曲がりくねった線、単語、または数字のことです。

![](https://storage.googleapis.com/zenn-user-upload/40af43bdcdfd-20221013.png)

CAPTCHA (またはコンピューターと人間を区別するためのCompletely Automated Public Turing test-完全に自動化された公開チューリング テスト-) は人間を通過させ、ロボット (プログラム) を追い出すゲートとして設計されています。曲がりくねった線や波打つ単語は最近ではあまり見られなくなり、GoogleのreCAPTCHA version 2に置き換えられました。これはあなたの人間性指数が十分に高いと見なされる限り、緑色のチェックマークを付けるCAPTCHAです。

![](https://storage.googleapis.com/zenn-user-upload/e954f633151e-20221013.gif)

スコアが Googleが考える人間性指数の閾値を超えていない場合、reCAPTCHAはパズルのような画像チャレンジをけしかけます。これは、驚くべきことに実際には単語を解読するよりも面倒なものにできています。

![](https://storage.googleapis.com/zenn-user-upload/b9de96db1d44-20221013.png)

CAPTCHAは人間にとって煩わしいものですが、少なくともその役割を果たしていれば許容できますが、CAPTCHAを自動化する方が、人間であることを証明するよりも簡単です。

## 2Captchaの仕組み

2Captchaは、ほぼ同じ2つのAPIエンドポイントを使用して、多数の異なるスタイルのCAPTCHAを突破します。最初のリクエストは、CAPTCHAを解決するために必要なデータを配信し、リクエスト ID を返します。画像ベースのCAPTCHAの場合、データはCAPTCHA 自体のbase64化された画像になります。

![](https://storage.googleapis.com/zenn-user-upload/145a8da1ec9d-20221013.png)

リクエスト ID を取得したら、リクエストを結果のエンドポイントに送信し、ソリューションの準備が整うまでポーリングする必要があります。


![](https://storage.googleapis.com/zenn-user-upload/086275a6cd9d-20221013.png)

reCAPTCHA v2の場合、話は少し異なります。上記と同じ2段階プロセスに引き続き取り組んでいますが、別のデータを送信しています。この場合、iframe がロードされているかどうかに関係なく、含まれている<div>にあるreCAPTCHAサイトキーを送信する必要があります。

![](https://storage.googleapis.com/zenn-user-upload/1d16e76652eb-20221013.png)
	
取得したレスポンスは、フォームと一緒に送信する必要があるトークンであり、g-recaptcha-responseのIDを持つ非表示のテキストフィールドに入力する必要があります。下の画像はその場所を示しており、ページに表示するためだけにdisplay: none cssプロパティを無効にしました。編集可能にすることで、2Captchaのレスポンスを手動で簡単にテストして、統合のテストの変数を減らすことができます。

![](https://storage.googleapis.com/zenn-user-upload/e60b154a7da2-20221013.png)

画像ベースのCAPTCHAの場合、結果はほぼ瞬時に利用できます。 reCAPTCHA v2 の場合、15 ～ 30秒以上かかることがあります。


## Puppeteerを使った自動化

CAPTCHAについて心配する前に、他のすべてを処理する必要があります。そしてその前には使うべき武器を選択する必要があります。この投稿では、次の3つの理由からGoogle Chromeを使用します。

	
Puppeteer API経由で非常に簡単に自動化できる
ヘッドレスでも、操作が簡単でポータブルなGUIを使用しても実行できる
世界で最も一般的なブラウザであるため、ウェブサイトにある他の自動化防止のトリック (Seleniumや PhantomJSのブロックなど) が機能する可能性は低い

## Puppeteerの使用

そうしたくない場合はChromeをインストールする必要はありません。PuppeteerにはChromiumのインストールなど必要なものがすべて付属しています。必要に応じてChromeのローカルインストールを使用することもできますが、それはあなた次第です

```js
$ npm install puppeteer
```
	
プログラムを一走りさせて、すべてがつながっていることを確認してください。この練習では、Redditの登録ページを自動化します。これがたまたまreCAPTCHAを使用した最初のページだったからです。

222222
Azure Fundamentals(AZ-900)：Azure の基礎: Azureの管理とガバナンスについて説明する「料金計算ツールと総保有コスト計算ツール」

Microsoft Learnを用いたMicrosoft Azure Fundamentals(AZ-900)の試験内容をまとめる投稿です。
この投稿ではMicrosoft Learnで学ぶ内容をできるだけ簡潔にまとめております。
Azureの勉強を一から始める方の参考になれば幸いです。

## 今回の学習内容
**◆「料金計算ツールと総保有コスト計算ツール」**
◇対応するMicrosoft Learn ラーニングパス
[Azure の基礎: Azureの管理とガバナンスについて説明する](https://learn.microsoft.com/ja-jp/training/paths/describe-azure-management-governance/)
◇対応するモジュール
[料金計算および総保有コスト計算ツールを比較する](https://learn.microsoft.com/ja-jp/training/modules/describe-cost-management-azure/3-compare-pricing-total-cost-of-ownership-calculators)

※前回の投稿は下記から確認できます。
[Azure Fundamentals(AZ-900)：Azure の基礎: Azureの管理とガバナンスについて説明する「Azure のコストに影響する可能性がある要因」](https://qiita.com/fsd-jume/items/187a36cc0381401586f2)

## 料金計算ツールと総保有コスト計算ツール
**どちらもインターネットからアクセス可能な、Azureの潜在的費用を確認できる計算ツール**

### 料金計算ツール
・Azureでリソースを作成するための見積もりを提供
・個々のリソースの作成やソリューションの構築、シナリオの例を使用した見積もりを確認可能
・リソースの種類やストレージオプションなども考慮可能

### 総保有コスト(TCO：Total Cost of Ownership)計算ツール
・オンプレミスのインフラをAzureに移行した場合の見積もりコストを提供
・現在の構成や前提条件を入力することで、オンプレミスとAzureで同じ環境におけるコスト差の見積もりを確認可能

## 次の学習内容
**◆Azure Cost Managementツール**

https://qiita.com/fsd-jume/items/19b3d30cee710541d25c

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/e4ec76959adb547ac5e8
CUDA on WSL 2のすすめ

## 前置き
個人マシンで3090 Tiが使えるようになり、ウキウキでEfficientNetV2を回してみると…共有マシンの3090よりも遅い。
どうやらWindowsではパフォーマンスが出ないというウワサは本当だったらしい。（他の要素も検証しろ！

「Windowsが許されるのは小学生までだよねー」などとイジられながらも頑なにWindowsで粘ってきたが
そろそろ潮時だろうかと考えていると、CUDA on WSL 2がnear-nativeなパフォーマンスで動くと聞こえてきた。

結果、WSL 2+Docker環境で学習を回すと、Windowsネイティブ環境と比べて実行時間が16%短縮された。
## 導入方法
以下のページで丁寧に解説されています。

https://docs.nvidia.com/cuda/wsl-user-guide/index.html#getting-started-with-cuda-on-wsl

補足: CUDAをDockerから使う場合は「3. CUDA Support for WSL 2」の手順は不要です。

https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker

### 罠1
systemctlが使えないということで、引っかかるかもしれません。

WSL 2をMicrosoft Store版にアップデートした上で
```/etc/wsl.conf
[boot]
systemd=true
```
と書き換えて、WSL 2をシャットダウン。
```
wsl.exe --shutdown
```
WSL 2を立ち上げ直せばsystemctlが使えるようになります。
### 罠2
WSL 2で名前解決ができないという問題が環境によって起こるようです。

私の環境でも何かのアップデートが引き金になって名前解決ができなくなりましたが
ESETがブロックしたことがログに残っていたので、ルールを設定して解消しました。

「WSL 2 名前解決」などと調べると、解決方法がいくつか出てくると思います。
2022年11月何故かベストアンサーをつけてくれない質問



+ [Working on the following module and the (case assignment rule) Field does not exist. Is there a fix or a work around for this?](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000KgDcA)
+ [Error message saying that Mobile Contact Layout is not set to primary on account, but it looks correct to me. Does this look correct?](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000JelDa)

:::note
新しいプレイグランドあるいは、別の組織で試す
Make sure the Account object has no recordType.

Note: To complete this challenge, use a Trailhead Playground that doesn’t have any record types for the Account object.

https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000Eo1MjSAJ
:::

+ [Could not find a waterfall chart on the dashboard with the title 'Current Product Pipeline by Stage'.](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000LIJdu)

:::note
I was getting the error because of the dashboard's name as I was copying and pasting titles from the instructions there was a space added in the dashboard title, therefore, the system could not read the dashboard name, and gave me errors. lesson learned to make sure there should not be any space before or after any title.
:::

+ [Completed all steps but receiving error; Trailhead not able to verify action](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007A3Ap1)

:::note
In order to rectify an issue initially, I created another dashboard with the same title in a different location. The Trailhead challenge kept looking at the first dashboard I created - once I deleted the first dashboard, the challenge looked at the one that was correct, and I passed. 

最初の問題を修正するために、同じタイトルの別のダッシュボードを別の場所に作成しました。 Trailhead チャレンジは、私が作成した最初のダッシュボードを参照し続けました。最初のダッシュボードを削除すると、チャレンジは正しいダッシュボードを参照し、私は合格しました。
:::


+ [設定例がある:大文字小文字にも注意](Creating a Product Pipeline Dashboard Using Tableau CRM + Salesforce)


+ [We couldn't find all of the navigation items. Make sure you've created a navigation item and page for the following: About Me, Experience, Education.](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000Jel65)

# 開発

+ [ Updated design token available SLDS(1) [Ln 3, Col 19] "slds-var-m-around_medium](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000Kgzb7)

# Flow

+ [Update Task with new case in Flow](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000Jedmh)


# その他

+ [Hi guys, I need to create #validation Rule to prevent assigning users other than sales team . and this is not working, could you please guide me?](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000LIK8B)
Selenium + WebDriver + Edge でリモートデバッグポートが開いていないことがある

Selenium + WebDriver で起動済みのブラウザを操作したい場合は、操作対象のブラウザを、予めリモートデバッグ用のポートを開いた状態で起動しておく必要があります。（下記のオプションを付けてブラウザを起動する）

> --remote-debugging-port=9222

これは、Chrome では上手く動作するのですが、Edge では動作しないことがあります。いろいろな要因が考えられますが、個人的にハマったパターンとして、「Edge のプロセスが死んでいない状態で、新規に Edge を起動しても、デバッグポートが開かない」ことがありました。

対処法は主に２つ。

- タスクマネージャーから Edge プロセスを終了させる
- Edge のオプションを開き（Edge のアドレスバーで `edge://settings/system` を入力）、下記２つをオフにして Edge を終了する
    - スタートアップ ブースト
    - Microsoft Edge が終了してもバック グラウンドの拡張機能およびアプリの実行を続行する
 
Chrome はブラウザを終了させた場合にプロセスが残ることが少ない（？）ので、あまりハマる人がいないのかもしれません。ちなみに Chrome の場合も先に起動している Chrome があれば、いったん終了させたほうが良さそうです。
Akamai EdgeWorkersでCDNのキャッシュを活用しつつ動的な処理を実現する

## キャッシュと動的な処理
「オリジンサーバーの負荷が問題になったためCDNでキャッシュするようにして負荷低減に成功した。しかしながら最近、キャッシュしているページに対して動的な処理を入れたいという要件が出てきた」
通常このようなケースでは、Edgeサーバーにおけるキャッシュを無効化してオリジンサーバーで動的な処理を行う必要があります。この場合、Edgeサーバーでキャッシュができずオリジンサーバーの負荷軽減ができないジレンマに陥りますが、AkamaiのEdge ComputingソリューションであるEdgeWorkersを利用すると、CDNのキャッシュを活かしながら同時にEdgeサーバー上で動的な処理を実行できます。

## EdgeWorkersとは
EdgeWorkersでは、AkamaiのEdgeサーバーでリクエスト受信やレスポンス送信などのイベントハンドラで、独自にコーディングしたJavaScriptを実行できます。クライアントの近くのEdgeサーバーで処理を行うためレイテンシが小さく、世界中に数十万台のサーバーが配置され、自動で分散駆動するしくみのためスケーリングを気にしなくて良いというメリットがあります。

参考: [EdgeWorkers:Akamaiのエッジサーバー上でJavascriptで書いたコードが実行可能に](https://www.akamai.com/ja/blog/developers/edgeworker)

## サンプル
ここでは、キャンペーンでの広告表示のためアクセス元の国の言語の情報をCookieに持たせる、という処理を書いてみます。
```javascript
import { SetCookie } from 'cookies'

export function onClientResponse(request, response) {
    let value = 'en'
    if (request.userLocation.country == 'JP') {
        value = 'ja'
    } else if ( request.userLocation.country == 'ES' ||
                request.userLocation.continent == 'SA') {
        if (request.userLocation.country != 'BR') {
            value = 'es'
        }
    }

    const cookie = new SetCookie()
    cookie.name = 'campaign_lang'
    cookie.value = value
    cookie.path = '/'
    cookie.maxAge = 30 * 24 * 60 * 60
    response.setHeader('Set-Cookie', cookie.toHeader())
}
```
## EdgeWorkersを呼び出すよう設定
CDN側の配信設定からEdgeWorkersを呼び出します。
![ew.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2911525/57b27ccd-7fcc-bb3f-8b1e-05f38209ffed.png)


## おわりに
今回のサンプルは非常に簡単なものですが、今まではオリジンサーバーでやっていた処理をCDNキャッシュと同時にEdgeサーバー上で実行することで、オリジンサーバーの負荷軽減・パフォーマンス向上が期待できます。アプリケーションの最適化などの検討時にEdge Computingも選択肢に含めてみてはいかがでしょうか。
esptoolでESP32にファームウェアを書き込む方法

## はじめに
windowsを使っている人だと, 最初使うであろうIDE 「uPyCraft」ですが, いろいろと不調が起こりやすく使いにくい。
なので今回は, esptoolコマンドを使ったESP32のセットアップを説明します。

## 準備
pythonのpipインストールを使い, esptoolコマンドをインストールします。

##### ・pythonのインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728179/5f137a33-2f7c-d5c2-27ba-131ae05d0578.png)

Menuの「Downloads」にホバーし, 「Python3.11.0」をクリック
詳しい手順↓
https://www.python.jp/install/windows/install.html

##### ・esptoolのインストール
```
pip install esptool
``` 

## ESP32にファームウェアをインストール
1. ESP32とPCをシリアル接続します
2. windowsボタンを右クリックし, デバイスマネージャを表示
3. COM<番号>を確認
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2728179/2c35f118-aab2-b3fd-0426-cee921ad5cb1.png)


4. Firmware最新版をダウンロード
https://micropython.org/download/esp32/ 
5. コマンドプロンプトで, firmwareをダウンロードしたフォルダへ移動
6. esptoolコマンドで, firmwareを書き込み
 今回変更する場所は, COM<番号>くらいですね
```
esptool --chip esp32 --port COM<番号> write_flash -z 0x1000 esp32-20220618-v1.19.1.bin
```
　・ --chip ...チップの種類を選択
　・--port ...ポートを選択
　・write_frash ...書き込みを行う 
　・-z 0x1000 ...書き込み場所を選択
7. コマンドを実行
原則, コマンドを実行したらESP32の「Boot」ボタン(ENじゃない方)を押下します。これで書き込みが行われます
【個人開発】画面操作を記録して自動操作するアプリを作ってみた

# はじめに
初めまして。今回、初めて記事を投稿させていただきます。
Qiita初心者の[からくり](https://twitter.com/karakuri0607)です。
仕事で暇な合間を見つけて個人開発をやっています。
今回はPythonでRPAツールを作成してみました。

# 開発したプログラムの紹介
今回開発したプログラム「RPAツール」はこちらです。
![RPAツール.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2944592/529d8918-22fa-7523-c8e9-e108f1c9d561.gif)

画面操作した内容がCSVに記録され、実行時はCSVを読み込んで同じ操作が自動で行われます。
ダウンロードして実行することができます。
良ければ使ってみてください。

https://github.com/karakuri0607/rpa-tool-exe

# 使い道
操作を記録して同じ操作を再現するため、条件によって操作が変化するような作業には向きません。
いつも入力する内容が同じだったり、ボタンクリックする単純な操作、操作手順が固定化されている場合にお勧めです。

# 機能について
今回開発したプログラム「RPAツール」には以下の機能があります。
### １．画面操作の記録機能
　　画面操作をCSVに記録します。
### ２．画面操作の自動実行機能
　　CSVを読み込み、画面操作を自動で行います。
### ３．操作間隔の再現機能
　　記録した操作の間隔を再現することができます。
　　ブラウザ等の表示の読み込みに時間がかかる場合に有効です。
### ４．マウスポインタ移動の再現機能
　　記録したマウスポインタの移動を再現することができます。
　　お絵描き等の細かい動きを再現することができます。
### ５．対応操作
* マウスポインタ移動
* 左クリック
* 右クリック
* ダブルクリック
* ドラッグ
* スクロール
* キー入力
* テンキー入力
* 半角/全角の切替
* ショートカットキー（Ctrl + A, Ctrl + C, Ctrl + V, Ctrl + X, Ctrl + Y, Ctrl + Z, その他）

# 注意点
* 半角/全角の切替は実行時に記録前の状態に合わせる必要があります。
* スクロール量はPCやマウスで異なるため、スクロール量を調整する必要があります。
* ダブルクリックの判定はプログラムで制御しているため、条件に合わなければ正しく実行されない可能性があります。（１回目と２回目のクリック間隔が0.01秒以上0.3秒未満）
* 記録された位置に対して操作を行うため、記録時のディスプレイと画面サイズが異なる場合、フォルダ追加やソートで順番が変わる場合は、変更しないようにするか再度記録し直して下さい。
* OSの仕様により、ブラウザやエクスプローラの表示位置が毎回異なる可能性があるため、拡大表示して位置を統一化することをおすすめします。
* 操作が正しく行われない場合、CSVを編集して実行していただくことも可能です。
* 万が一、実行中に画面が固まる場合や落ちてしまう場合は、タスクが残っている可能性があるため、タスクマネージャーから「RPAツール.exe」を終了してください。

# 使用したライブラリ
* ### PySimpleGUI
   GUIを作成するためのライブラリ
* ### pynput
   キー入力、マウス操作を検知するためのライブラリ
* ### PyAutoGUI
   画面を自動操作するためのライブラリ

# 開発して思ったこと
開発期間は約２週間程度です。
どのレベルまで操作を可能にするかによって開発工数もだいぶ伸びてしまうので妥協するか悩みました。
なんとか、ほとんどの操作を自動化できるレベルに持っていけたのではないかと思います。
いくつか躓いた点がありましたので共有したいと思います。

### pynputでダブルクリックが検知できない。
pynputではダブルクリックがシングルクリック２回として判定されるため、条件を設定してダブルクリックを再現しました。
### pynputで検知した全てのキーが文字列を返してくれるわけではない。
pynputのキー入力検知は、基本的に文字列を返してくれますが、一部の特殊キー、テンキー、ショートカットキーの入力はキーコードで返されたりするため、変換する必要がありました。
### pynputでスクロール量が検知できない。
pynputではスクロール方向は検知できますが、どのくらいスクロールしたのかを数値化することはできないため、画面で設定できるようにしました。
### 半角/全角の入力が難しい
pyautoguiでは半角/全角キー押下することはできます。
ただし、全角文字は全角入力、半角文字は半角入力といった指定はできません。
試行錯誤してみましたが、結局、ユーザー側で記録前と実行前に半角/全角キーを統一するようにしてもらうことで対応しました。
### GUIアプリは画面が固まる
GUIアプリの場合、処理の長いプログラムは画面が固まるため、非同期処理にする必要がありました。
### 表示位置が変わると正しく動作しない
記録された位置に対して操作が行われるため、PCやディスプレイの変更で表示位置が変わったり、ウインドウの表示位置が変わったり、ソートでファイルの位置が変わったりすると正しく操作が行われません。
対策として、PCやディスプレイが異なる度に記録するか、ウインドウサイズを拡大表示して統一するようにしてください。
### 条件による操作
同じ操作を再現するプログラムのため、ポップアップが出たりすると操作が正しく行われない可能性があります。
ポップアップが出たら閉じる等、条件指定できるようになればより自由度の高いツールにできそうです。
（pyautoguiで画像認識しクリックする操作もあります。）

# まとめ
個人開発で作成したプログラム「RPAツール」を紹介させていただきました。
まだまだ課題は残りますが、良いアイディアが浮かべば改良していきたいと思います。
個人開発をし始めて歴が浅いため未熟ではありますが、今後開発したいものがまだまだありますのでアップしていきたいと思います。
また、ブログに個人開発で作成したプログラムや記事を載せていますので、よろしければ閲覧お願いいたします。

https://pg-toybox.com/

不具合や要望などありましたら、コメントもしくはブログのお問い合わせから連絡していただけると幸いです。
【いまさら聞けないKPT】なんとなくやってない？

ふりかえりの代表的フレームワークと言われるKPT
やりかたは知っているけど、なぜかうまくいかない。。


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670908/25c963df-8755-6cb0-a15b-97819ede18aa.png" width="500px">

## 困ってること、知りたいこと
- KPTをとりあえずやってみたけど、あっているのか不安
- Tryがなかなか消化できない
- 毎回同じようなProblemが出てくる
- 実際みんなはどんな粒度のTryをあげてるの！？

よくあるKPTのブログ、肝心のふせん部分にモザイクがかかっている
⇒どんなTryが上がっているのか分からない、良いお手本がなかなか見つからない（泣）

## そもそもなぜふりかえるのか？

1. プロセスの「カイゼン」をするため
    - トヨタ生産方式では作業の「ムリ・ムダ・ムラ」を排除し、効率的に価値を届けることを目指している
    - 漢字の「改善」だと「悪い部分を良くする」というニュアンスが強い
    - カタカナの「カイゼン」には「現状に満足せず、もっとよくする」という意味が込められている

2. VUCAな時代にビジネスを対応させていくため
    - 不確実で変化の速いビジネスに適応していくためには、
    限られた時間で、チームのパフォーマンスを最大限発揮させる必要がある
    ⇒なんとなくうまくいっていること・うまくいっていないことを言語化する！

## KPTとは
著書『カイゼンジャーニー』（市谷 聡啓・新井 剛, 2018）より

### Keep
- 続けたいこと、やってみて良かったことを挙げる
- よかったこと（Good）から挙げて、続けるかどうかを判断する
- Keepが一つもない場合は、ふりかえりができていること自体をKeepとしてもＯＫ！

### Problem
- 問題点を挙げる
- モヤモヤしていることや、気にかかっていることも挙げる
- 断片的な感情（しんどかった等）ではなく、状態を具体的に書く

### Try
- KeepとTryを洗い出したあとに次に試したいことを挙げる
- 実際に取り組むTryは緊急度や重要度を見定めて、数を絞る

### 二回目以降のふりかえり
- 前回のTryを見ることからスタートする
- 続けたいことはKeepに移動し、対応するProblemがカイゼンできているかをチェックする

## KPTをやってみたけど

- いきなりKeepが出ず辛い
- Problemしか出ず、お通夜状態
- 「こんなくだらないことKeepに挙げていいのか？」と遠慮してしまう

## KPTは実は難しい
- KPTはシンプルである一方、下記のプロセスが欠如しているため、
初心者にとっては思考がまとまり辛いフレームワークである可能性がありそう。

1. Keep,Problemの前に、事実(Fact)を出すプロセス
2. Keep,Problemの原因を検討する(掘り下げ) 

## Good,Badから考える
- KPTの派生版で、「GB⇒KPT」や、「お気持ちから始めるKPT」など、
  KとPの前にワンクッションあるフレームワークがオススメ

- 慣れてきたら、KPTにしてみる


## ふりかえりをきわめたい
- とにかく繰り返す！
- 個人でやったふりかえりを持ち寄って参考にしたい（個人ふりかえりイベント）
- ふりかえりを通して自分自身とメンバーのことを理解するきっかけにしたい！

## まとめ、参考リンク
[事象変換がカギ｜GB→KPT法で正しくプロジェクトを振り返ろう](https://sevendex.com/post/15676/)