OmniAICreator/Qiita-1.07M huggingface dataset:
git備忘録

# ローカルからリモート

## 1番目
```
git push する前にリモートとの変更点を見る
上記のコマンドは、こんな感じで逆にもできます。

git diff リモート名/ブランチ名..HEAD
.. の右側が時系列的に最新とみなされるので、この場合は git commit した後にリモートリポジトリとそのこれから push したい箇所を表示したい場合に使えます。

```

## 2番目

```
git addコマンドで、インデックスにコミットしたいファイルを登録する。
```

## 3ばんめ

````
git commitコマンドで、インデックスにあるファイルを更新する。
````

## 4ばんめ

~~~
git pushコマンドで、ローカルリポジトリの内容をリモートリポジトリに送信する
~~~

sannsyou
[git addとcommit、pushの関係をわかりやすく説明する【Gitコマンド解説①】]{https://qiita.com/atsushi101011/items/96054ebbd876e378cac4}

push no error ni tuite
git push時のerror: src refspec master does not match anyについて[]{https://blog.deepblue-ts.co.jp/git/git-push-error/}
pingがどこにも通らなくなった

# 環境
OCN - ルーター(WSR-1166DHPL2/N) - PC

# 何が起こった
PCを再起動したら、どこにも繋がらない。

# やったこと
固定IPの割り当て
PCの再起動
LANケーブルを抜いてさす
など

# 解決した方法
ルーターの再起動
OUPC2022 C「Clock」解説


# はじめに
「Clock」writerのshinchanです。
問題文が短く、行列累乗で解ける問題を作りたいと思ってたら思いつきました。

# 解法1 (行列累乗を用いた解法)
$t$ 秒後の針の先端の座標を $(x_t, y_t)$ とします。
```math
\begin{pmatrix}
x_{t+1} \\
y_{t+1} \\
\end{pmatrix}
=
A
\begin{pmatrix}
x_t \\
y_t \\
\end{pmatrix}
```
となるような $A$ を考えます。$A$ をさらに、$\sqrt{2}$ 倍の拡大と $45$ 度の回転操作に分解すると、前者は実数で、後者は回転行列で表すことができ、$A$ はそれらの積です。つまり、以下のようになります。
```math
A=\sqrt{2}
\begin{pmatrix}
\cos(45°) & -\sin(45°)\\
\sin(45°) & \cos(45°)\\
\end{pmatrix}
=\sqrt{2}
\begin{pmatrix}
\frac{1}{\sqrt{2}} & -\frac{1}{\sqrt{2}}\\
\frac{1}{\sqrt{2}} & \frac{1}{\sqrt{2}}\\
\end{pmatrix}
=
\begin{pmatrix}
1 & -1\\
1 & 1\\
\end{pmatrix}
```
したがって、$(x_T, y_T)$ は次式で求めることができます。
```math
\begin{pmatrix}
x_{T} \\
y_{T} \\
\end{pmatrix}
=
\begin{pmatrix}
1 & -1\\
1 & 1\\
\end{pmatrix}^T
\begin{pmatrix}
x_0 \\
y_0 \\
\end{pmatrix}
=
\begin{pmatrix}
1 & -1\\
1 & 1\\
\end{pmatrix}^T
\begin{pmatrix}
X \\
Y \\
\end{pmatrix}
```
$A^T$ は行列累乗で mod を考慮しながら計算することができます。
以上のようにして、問題が解けました。
# 解法2 (複素数を用いた解法)
$t$ 秒後の針の先端の座標 $(x_t, y_t)$ を、複素数を用いて、 $z_t = x_t + y_t i$ と表します。
$z_{t+1} = C z_t$ となる複素数 $C$ を考えると、$C = \sqrt{2} e^{i \frac{\pi}{4}} = 1 + i$ となります。
したがって、$z_T = C^T z_0 = C^T (X + Y i)$ は、 $C^T$ を繰り返し二乗法を用いて求めることで、mod を考慮しながら計算することができます。
以上のようにして、問題が解けました。
# 解法3 (T の mod 4 や mod 8 に注目する解法)
本問題は行列累乗や複素数を知らなくても解くことができます。
$45$ 度の回転のみに注目します。すると、例えば $4$ 秒後は原点対称の位置に移動するだけであり、$8$ 秒後には元に戻ります。このように、$T\mod 4$ や $T\mod 8$ に注目することで、繰り返し二乗法を用いる箇所は、針の長さの変化だけとなります。この操作をすると、$0$ 秒以上 $8$ 秒未満の範囲の計算だけが残り、mod さえ考慮すれば愚直に計算することができます。

いずれの解法でも時間計算量は $O(\log T)$ となります。
DDDがわからない～名前が縛り付けるもの～

# 「名前はこの世で一番短い呪」
夢枕獏さんの小説『陰陽師』というものに、出てくる言葉だそうです。
安倍晴明「眼に見えぬものさえ名という呪で縛ることができる」

この呪いですが、ものが名前で縛り付けられているだけでなく、人間が名前によりその物に対する考えや意味を縛り付けられるという呪いもあるんじゃないかと思っています。

# 美味しいお雑煮
「皆さんの、**美味しいお雑煮**の条件を教えてください。」
この質問をするとおそらく、家庭によって全然違う条件が出てくるかと思います。これは、お雑煮というものが地域や家庭によって違いがあるからです。(醤油か味噌か、角餅か丸餅か、など)

どれも名前は「お雑煮」ですが、みなさんそれぞれの認識に縛り付けられた「お雑煮の意味」によって全然別物のイメージとなってしまっているのです。

# 物の名前だけではない
先ほどは名詞であるお雑煮でしたが、名前がついている以上は動詞にも助動詞にも同じことが言えます。

# 呪いを利用する
みんなが同じ呪いにかかれば、名前という力で話し合いを円滑に進められます。有効活用するためにも名前の共有は常に行っていくようにしましょう。
ANS-C01試験対策（３回目）

# はじめに
本記事は、３回目のANS-C01を受けるにあたっての勉強内容をアウトプットする記事の第１回目です。
2022年11月15日現在、ANS-C01のオンライン上の情報タスクないので、

- ANS-C01を二回受けた、という経験
- 3回目に向けた試験対策内容

を記事としてアウトプットすることで誰かの役に立つと考えました。

# 簡単なプロフィール
現在、都内の金融系IT会社に勤める28歳男性です。
業務内でAWSを扱っている関係で今年度中にAWS全資格取得を目指して勉強をしています。
### 今まで取得したAWS資格一覧
- DBS-C01	
- SCS-C01	
- DOP-C01	
- DVA-C01	
- SOA-C02	
- SAP-C01	
- SAA-C02


# ２回目までのテスト結果
２回目までのテスト結果ですが、以下の通りです。

- １回目
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2725423/13009e9f-971f-618e-cdf1-461b993e2371.png)

- ２回目
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2725423/4c280d92-3825-3572-e3ec-940710e083c0.png)

ううう、目から汗が出てきますね、、、

# ２回目の試験まででやったこと

- [Tech Stock（旧：koiwa lab）](https://techstock.jp/)
    - ANS-C01非対応ですが、今までの資格勉強の延長で2周行いました。あまり試験には関係なかったです。
- [Specialty Official Practice Question Set (ANS-C01 - English)](https://explore.skillbuilder.aws/learn/course/12676/aws-certified-advanced-networking-specialty-official-practice-question-set-ans-c01-english)
    - 公式の試験問題集ということもあり、実際の試験に一番近いですが、問題数が20問のみ
- [Whizlabs](https://www.whizlabs.com/aws-advanced-networking-speciality/) 
    - 非公式の問題集だとこれが一番実践向きと思います。無料版の問題が20問あり、2回目まではそれのみ解きました。

# ３回目受験に向けてやること
- [Whizlabs](https://www.whizlabs.com/aws-advanced-networking-speciality/) を解く
    - 有料版を購入してこちらを解きます。
    - 全部で試験5回分の問題が3000円程度で手に入るため、問題集はこちらを解いていくことが中心になりそうです。
- 2回目までの試験で頻出だったAWSサービスの再整理とアウトプット
    - 2回目までの試験問題まででよく出てきた以下のサービスについてBlackBeltなどを読み漁り、Qiita記事としてアウトプットします。s項目ごとに記事を分けて公開予定です。
        1.  [Route53-名前解決](https://qiita.com/the13-HK/items/c074922b4c9b0c5f7345)
        1.  [Route53-ルーティング機能](https://qiita.com/the13-HK/items/4b605f62957fa788d81f)
        1.  [Transit Gateway](https://qiita.com/the13-HK/items/64cdff4772d968f95101)
        1.  [Global AcceleratorとCloud Front](https://qiita.com/the13-HK/items/8b95e63438f1f7f89272)
        1.  [Direct Connect](https://qiita.com/the13-HK/items/4dd300b902a4e52a1532)
        1.  [VPNサービスについて](https://qiita.com/the13-HK/items/3e4a2c9bd5fa50c67bb2)
        1.  [Resource Manager](https://qiita.com/the13-HK/items/3a2cd32426a23cce85df)
        1.  [ELB(GWLB以外)](https://qiita.com/the13-HK/items/5bc44c6a21c665109853)
        1.  [Glateway Load Balancer](https://qiita.com/the13-HK/items/e199767b25aae7c129c1)
    - サービスの特徴だけでなく、類似サービスとの特長の差異をとらえる必要があると感じたため、そこを重点的にアウトプットしていきます。

# 最後に
あくまで勉強がメインなのでアウトプットに時間をかけ過ぎずに作成していくのでやや雑になってしまうと思います。
Twitterも作成しているので、気になったり、質問があればお気軽にご連絡くださいませ。
[Ruby] Enumerable#chunk{,_while}、Enumerable#slice_{before,after,when} の違い

<!--# ruby の Enumerable#chunk{,_while}、Enumerable#slice_{before,after,when} の違い-->

:::note info
これは2016年くらいに **るりま**[^rurema]を見て書いたメモです。今のるりまは充実していて、嬉しいです。下記の内容は現在の Ruby でも変わっていないので自分用に投稿します。
:::

[^rurema]: https://docs.ruby-lang.org/ja/latest/class/Enumerable.html

ruby の Enumerable モジュールには、似たようなメソッド

* chunk
* chunk_while
* slice_before
* slice_after
* slice_when

があります。

このうち、chunk_while、slice_after、slice_when は Ruby 2.3 から使用可能です。

## 形式

* `chunk {|elt| key } -> Enumerator<key, chunk>`
* `chunk_while {|elt_before, elt_after| bool } -> Enumerator<chunk>`
* `slice_before {|elt| bool } -> Enumerator<chunk>`
* `slice_before(pattern) -> Enumerator<chunk>`
* `slice_after {|elt| bool } -> Enumerator<chunk>`
* `slice_after(pattern) -> Enumerator<chunk>`
* `slice_when {|elt_before, elt_after| bool } -> Enumerator<chunk>`

## 説明

* chunk
  * ブロックの評価値が同じ値が続くものを一つのチャンクにする
  * （評価値が異なる値になるところで区切る）
* chunk_while
  * 隣り合う要素を引数にしてブロックの評価値が真なら一つのチャンクにする
  * （偽になるところで区切る）
* slice_before
  * ブロックの評価値が真になった要素の直前で区切る
  * （その要素をチャンクの先頭とみなす）
* slice_after
  * ブロックの評価値が真になった要素の直後で区切る
  * （その要素をチャンクの末尾とみなす）
* slice_when
  * 隣り合う要素を引数にしてブロックの評価値が真になるところで区切る
  * （偽なら一つのチャンクにする）

返される Enumerator の `chunk` は配列。

Enumerable#chunk だけ、返される Enumerator の形式が違います。

Enumerable#chunk はブロックの特別な評価値として `nil` もしくは `:_separator` と `:_alone` があります。**るりま** を参照[^chunk]してください。

[^chunk]: https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/chunk.html

Enumerable#slice_before は最初の要素もブロックを呼び出すが評価値は無視されます。

Enumerable#slice_after は最後の要素もブロックを呼び出すが評価値は無視されます。

Enumerable#slice_before と Enumerable#slice_after の `pattern` は  `{|elt| pattern === elt }` の代わりです。

引数 `initial_state` を渡す形式は deprecated なため除外しています。

## ブロックを呼ぶ回数

メソッド|ブロックを呼ぶ回数
-|-
chunk | length
chunk_while | length - 1
slice_before | length
slice_after | length
slice_when | length - 1

## 要素がブロックパラメータになる回数

メソッド|要素がブロックパラメータになる回数
-|-
chunk | 1*
chunk_while | 1 2* 1
slice_before | 1*
slice_after | 1*
slice_when | 1 2* 1

### Enumerable#slice_before と Enumerable#slice_after の関係

```rb
ary = [0, 2, 4, 1, 2, 4, 5, 3, 1, 4, 2]

p ary.slice_before(&:even?).to_a
p ary.slice_when {|_prev, curr| curr.even? }.to_a
p ary.chunk_while {|_prev, curr| curr.odd? }.to_a
#>> [[0], [2], [4, 1], [2], [4, 5, 3, 1], [4], [2]]

p ary.slice_before(&:odd?).to_a
p ary.slice_when {|_prev, curr| curr.odd? }.to_a
p ary.chunk_while {|_prev, curr| curr.even? }.to_a
#>> [[0, 2, 4], [1, 2, 4], [5], [3], [1, 4, 2]]

p ary.slice_after(&:even?).to_a
p ary.slice_when {|curr, _next| curr.even? }.to_a
p ary.chunk_while {|curr, _next| curr.odd? }.to_a
#>> [[0], [2], [4], [1, 2], [4], [5, 3, 1, 4], [2]]

p ary.slice_after(&:odd?).to_a
p ary.slice_when {|curr, _next| curr.odd? }.to_a
p ary.chunk_while {|curr, _next| curr.even? }.to_a
#>> [[0, 2, 4, 1], [2, 4, 5], [3], [1], [4, 2]]
```
PodmanはPVC定義だけで永続化できそうな件を調べてみた

# はじめに

Podmanで以前生成したPodのManifestを使ってminikubeに持って行った時に、PersistentVolumeがみつからないと怒られる事象に遭遇しました。実際に作成していないのでそりゃあその通りなのですが、じゃあPodmanの時ってなんで動いてたんだろう。というのを調べてみました。

　
　こちらが前回の話

https://qiita.com/toomori/items/d461e607897aa8229166



# 目次
<!-- タイトルとアンカー名を編集 -->
1. [現状確認](#Chapter1)
1. [何がおきてたのか](#Chapter2)
1. [まとめ](#Chapter3)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# 現状確認

PodmanDesktopで現状を確認すると、作った覚えのないVolumeが、、ある。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2608370/9cf418b2-174b-ab33-ac94-c8afb1c7437b.png)

PodのManifest定義を確認すると、こちらもPVCの記載はありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2608370/283f2347-d809-34aa-cc3b-9d5f29e5c553.png)

Volumes関連で記載したのは下記だけなので、ここからどうやら自動的にPVがMountsされている模様

```yaml
  volumes:
  - name: wordpress_wordpress-pvc
    persistentVolumeClaim:
      claimName: wordpress_wordpress
  - name: wordpress_db-pvc
    persistentVolumeClaim:
      claimName: wordpress_db
```

コンテナ側のMounts情報を参照すると、こちらにもVolumeMount確かにありました。
ちゃんとマウントされています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2608370/03b12a68-3916-39ac-c4fb-74ab8cb3a017.png)

つまりPodmanはpersistentVolumeClaimの記載だけあればPodman側で永続データに配慮してくれるという仕様のようです（Podman　v4.3.0時点）。

<a id="#Chapter2"></a>
# 何が起きてたのか？

GitHubの中を漁ってみた感じ、結構前から使えるように動いていたみたいです。知らんかった。。


https://github.com/containers/podman/pull/9935

https://github.com/containers/podman/pull/8497

このコマンドを打った時に勝手に作ってくれたみたいですね。

```bash
podman play kube kubernetes-hybrid.yml
```

これらを参考にリリースノートも参考にしましたが正確な追加の時期はわかりませんでした。
IssueNoからたぶん３系の途中で使えるようになったのかな。。（正しい探し方教えてください）

https://github.com/containers/podman/blob/main/RELEASE_NOTES.md

リリースノートを見ると毎回かなりのバグ修正を機能追加が行われており、現在も非常に活発なコミュニティとなっています。Dockerよりもアクティブなのではないでしょうか。今後のPodmanの利便化に期待したいです。

<a id="#Chapter3"></a>
# まとめ

Podmanの新設機能でPVは意識しなくても勝手によくやってくれるということ。
PodのManifestだけあれば、どの開発端末つかっても暗黙的にPVを作ってくれるので環境を頻繁に更新する開発などの場合は非常に楽です。コンテナ、Pod入門者に優しいのかと言われると少し悩ましいところでもあります。Podmanのシェアはまだまだ低いとおもうので、k８s側やminikubeなど環境の異なるユーザとの意思疎通には注意が必要な点だけ考慮して利用するのがよさげだ思います。

Dockerもこの便利機能今はあるのだろうか。。たしかdocker-composeは似た挙動になった記憶はあるようなーー

今回はPodmanDesktopを使って調べましたが手っ取り早く状況を確認するのにはとても便利でした。

<a id="#reference"></a>
# 参考文献
- [Podmanのコンテナからマウントされた匿名ボリュームのマウントポイントを調べるには](https://denor.jp/podman%E3%81%AE%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%8B%E3%82%89%E3%83%9E%E3%82%A6%E3%83%B3%E3%83%88%E3%81%95%E3%82%8C%E3%81%9F%E5%8C%BF%E5%90%8D%E3%83%9C%E3%83%AA%E3%83%A5%E3%83%BC%E3%83%A0)
●複数の自動スケールプロファイルが構成されている場合

●複数の自動スケールプロファイルが構成されている場合
自動スケールエンジンは、「指定日プロファイル」、「定期的プロファイル」、「規定のプロファイル」の順にプロファイルを確認して実行する。

■指定日プロファイル
特定の開始日時と終了日時によって指定されたプロファイル

■定期的プロファイル
特定の曜日とその開始時刻及び終了時刻で指定されたプロファイル

■規定のプロファイル
規定で作成されるプロファイルで、標準プロファイルとも呼ばれる。その他の種類のプロファイルが存在しない場合や、いずれのプロファイルにも一致しなかった場合に使用される。
FutureBuilder A value of type 'Object?' can't be assigned to a variable of type 'List<T?>'.

# 背景
Flutterにて、`FutureBuilder`Widgetを使っている際に出たエラーの対応メモです！
このエラーだけで1時間は余裕で浪費したので残します、、、🔥


## エラー Snapshotの型が合わない
```diff_dart:top_page.dart
// ScaffoldのAppbar部分まで省略
    body: StreamBuilder<QuerySnapshot>(
          stream: RoomFirestore.joinedRoomSnapshot,
          builder: (context, streamSnapshot) {
            if (streamSnapshot.hasData) {
              return FutureBuilder(
                  future: RoomFirestore.fetchJoinedRooms(streamSnapshot.data!),
                  builder: (context, futureSnapshot) {
                    if (futureSnapshot.hasData) {
-                      List<TalkRoom?> talkRooms = futureSnapshot.data;
                      return ListView.builder(
                          // listの表示数
                          itemCount: talkRooms.length,
// 残りの重要でないWidget情報は省略
```
エラーが出た箇所にDiffで赤色のマーカーをつけています。

`
A value of type 'Object?' can't be assigned to a variable of type 'List<TalkRoom?>'.
`
型が合わないぞ、と言われます。
このエラーを見た結果、FutureBuilder自体に型をつければ
`future`プロパティを介してSnapshotの型を変えることができるので
型をつけてみますと、次のエラーになりました。

## エラー futureの型が合わない

```diff_dart:top_page.dart
body: StreamBuilder<QuerySnapshot>(
          stream: RoomFirestore.joinedRoomSnapshot,
          builder: (context, streamSnapshot) {
            if (streamSnapshot.hasData) {
              return FutureBuilder<List<TalkRoom?>>(
-                  future: RoomFirestore.fetchJoinedRooms(streamSnapshot.data!),
                  builder: (context, futureSnapshot) {
                    if (futureSnapshot.hasData) {
                      List<TalkRoom?> talkRooms = futureSnapshot.data!;
                      return ListView.builder(
                          // listの表示数
                          itemCount: talkRooms.length,
```

今度は、以下のようなエラーが出ました。
`
The argument type 'Future<List<TalkRoom>?>' can't be assigned to the parameter type 'Future<List<TalkRoom>?>?'.
`
`future`プロパティが謎の余計な`?`をつけ、型が合わなくなりました。
また、メソッド側の型を`Future<List<TalkRoom>?>?`に合わせると

`
The argument type 'Future<List<TalkRoom>?>? (where TalkRoom is defined in /Users/chat_firebase_app/lib/model/talk_room.dart)' can't be assigned to the parameter type 'Future<List<TalkRoom>?>? (where TalkRoom is defined in /Users/chat_firebase_app/lib/pages/talk_room.dart)'.
`
もっとえぐいエラーが出ました。

## 解決策
今回はWidgetの仕様として回避できる気がしないエラーなので、
静的型付き言語としてはあるまじき`dynamic`(TSのAny的な型)を使います。
（APIなど非同期に動く場合に使うことが多いのですが、型付き言語の意義を失いそうです）

```diff_dart:top_page.dart
body: StreamBuilder<QuerySnapshot>(
          stream: RoomFirestore.joinedRoomSnapshot,
          builder: (context, streamSnapshot) {
            if (streamSnapshot.hasData) {
              // FutureBuilder<List<TalkRoom?>>ではfutureプロパティが変な解釈してバグる
              return FutureBuilder(
                  future: RoomFirestore.fetchJoinedRooms(streamSnapshot.data!),
                  builder: (context, futureSnapshot) {
                    if (futureSnapshot.hasData) {
+                      dynamic talkRooms = futureSnapshot.data;
```
諦めにはなりますが、これで動作はしたので、一時的な解決策としましょう、、、🙏
（腑に落ちないので、別の解決策をお持ちの方がいらっしゃれば
教えていただきたいです🙇）

## 参考文献

https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
TailwindCSSで指定した背景色が変わらない問題への対処法


タイトルの件で少しハマったので備忘録として残しておきます。

# バージョン

```tailwindcss 3.1.8```

# 対応策

例えばこのようなコードあるとします。

```react
<text className="bg-red-400">必須</text>
```

bg-red-400で背景色を指定しているのですが、以下の画像のように
なぜか背景色が変わらないことがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392337/823c879f-b8dd-91d1-7103-f4430b2fc627.png)

色が変わらない場合、tailwind.config.jsの定義を確認します。

>tailwind.config.js の theme.extend.colors に設定を記述することでデフォルトのカラーパレットを追加することができます。 もちろんtailwindcssが提供しているカラーパレットをインポートして使用することもできます。

```javascript
  white: {
    300: "#F8F8F8",
    500: "#fff",
  },
  gray: {
    100: "#EEEFF2",
    400: "#AFB5C0",
    500: "#DDDDDD",
  },
  red: {
    500: "#ef4444",
  },
```

bg-red-400が定義されていないので、ここにbg-red-400の内容を追加します。
カラーコードで指定する必要があるので、
TailWindCSSのBackground Colorを確認しましょう。

### 2022/11/24追記
こちらですぐに確認できます。

https://tailwindcss.com/docs/customizing-colors


~~https://tailwindcss.com/docs/background-color#:~:text=bg%2Dred%2D400,113%20113)%3B~~

~~bg-red-400は```rgb(248 113 113)```なので、
以下のようなサイトでカラーコードを調べます。~~

~~https://tech-unlimited.com/color.html~~


```rgb(248 113 113)```はカラーコード```#f87171```なので、
redの400として追加します。
※#を忘れずに！

```javascript
  red: {
    400: "#f87171",
    500: "#ef4444",
  },
```

サーバーを再起動して確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392337/78f83987-5f6f-6fdd-98e4-388d78e49f23.png)

無事に色が反映されました。

# 参考

https://www.luku.work/tailwindcss-customize-color
SPMでマルチモジュール化したプロジェクトでLocalizationを設定する手順

SPMでマルチマルチモジュール化したプロジェクトにおいて、`Localizable.strings`を使って文言管理したいときがあるので、メモとして残しておくためにもこちらの記事にまとめました。

公式Docにも詳しい方法が書かれておりますので、公式を見ていただくのも良い（英語に抵抗がなければその方がいい）と思います。

https://developer.apple.com/documentation/xcode/localizing-package-resources

## 達成したいこと
* packageに切り出したResourceモジュールの中に`Localizable.strings`を定義したい
* 多言語対応もしたい
* SwiftGenを使ってファイルをジェネレートしたい（コマンドを叩くのは手動）

## Package.swiftの設定
こちらでやることは1つだけです。
`defaultLocalization`の設定が必要で、` defaultLocalization: "ja",`を設定してください。
jaの部分はenとかでも大丈夫です。

```swift
let package = Package(
    name: "AppCommon",
    defaultLocalization: "ja",
    platforms: [
        .iOS(.v15)
    ],
    products: [
        // Products define the executables and libraries a package produces, and make them visible to other packages.
    ],
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        // .package(url: /* package url */, from: "1.0.0"),
    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages this package depends on.
    ]
)
```

## 各言語のディレクトリを作りLocalizable.swiftを配置する
公式Docを日本語翻訳すると、
> .lprojで終わるディレクトリにパッケージリソースを配置し、ISO639言語コードを使用することで、Xcodeは自動的に言語を推測できます。

と書かれている通り、`ISO639言語コード.lproj`形式のディレクトリをPackage内に作成します。
![スクリーンショット 2022-11-06 16.29.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/580445/1f18d6ad-e077-5eab-f6e7-9bb77557b8a6.png)
さらにその中に、`Localizable.strings`を追加するだけでOKです。

画像は日本語と英語の多言語化対応をする場合のサンプルになります。

`Localizable.strings`の中身ですが、
```swift
"home.title" = "Home";
```
のように記述し、各言語のKeyは同一になる必要があります。

## プロジェクト内のViewなどから参照する
実際にResourceモジュールと異なるモジュールから参照されることが多いと思いますが、以下のように書くことでResourcePackageにある、各言語の`Localizable.strings`を参照することが可能です。

```swift
NSLocalizedString("home.title", bundle: Bundle.module, comment: "ホーム")
```

## SwiftGenを使ってStringファイルを自動生成する
上記の`NSLocalizedString`を利用する書き方をViewに直接書いてしまうのは冗長になりますし、タイポなどによるミスの可能性も増えることから`SwiftGen`を利用します。

SwiftGenについてこの記事では詳しく紹介しませんが、日本語でまとまっている記事が多数出てくるので、ググっていただければいい記事が見つかると思います。

SPMでパッケージ化されたモジュールからファイルをジェネレートしたい場合は、以下のように書いてあげればOKです。
```yaml
 strings:
  inputs:
    - Resources/Sources/Resources/Strings/ja.lproj
  filter: .*\.strings$
  outputs:
    - templateName: structured-swift5
      params:
        publicAccess: true
      output: Resources/Sources/Resources/Strings/Strings+Generated.swift
```
ポイントは下記です。

1. 多言語化されていたとしても`inputs`に入れるディレクトリは、1つの言語のディレクトリを含めれば大丈夫そう
1. `parms`で`publicAccess: true`を設定すること ← これをやらないと別モジュールから自動ジェネレートされる`enum`を参照できないため

あとは、文言を追加したときにプロジェクトルートで
```
Pods/SwiftGen/bin/swiftgen
```
を叩いてあげるだけで、`Strings+Generated.swift`が勝手に生成されます。

使う時はこんな感じです。
```swift
L10n.Home.title
```

## おわりに
これで以上です。
意外とステップが少ないので、短時間で終わる作業ということがわかりました。
Go Package 命名法

# Go Packageの命名方法

公式[GoのBlog Pacakge names](https://go.dev/blog/package-names?utm_source=dlvr.it&utm_medium=twitter)の（一部）和訳、まとめになります。


## 導入
いいパッケージの名前はパッケージの内容を示唆し、そのユーザーが内容や使い方を理解するのに役立つ。[Effective Go](https://go.dev/doc/effective_go#names)にパッケージ、タイプ、関数など名前の付け方のガイドラインがあり、それらをさらに拡張して議論します。悪い名前の付け方、その直し方も議論します。

## パッケージの命名

### いいパッケージの名前は短くて簡単なもの
Lower case (小文字) のみ
under_scores, mixedCaps がないもの

いい例
- time
- list
- http

悪い例
- computeServiceClient
mixedCapsは使うべきではない
- priority_queue
under_scoresは使うべきではない


### 慎重な省略(Abbreviation Judiciously)

パッケージの名前をただ省略するだけでは、ただ曖昧になるだけ。
また、別のユーザーからいい名前を盗むべきではない。

いい例
- strconv (string conversion)
- syscall (system call)
- fmt (formatted I/O)


- bufio (buffered I/O)
buffered I/O は buf とは略すべきではない。buf は buffer に使われるべき。

## パッケージのコンテンツの命名
関数や変数の命名法
パッケージの名前をプレフィックス（接頭語）として使うことになる。

### 反復をさける
パッケージの名前とセットで考える

いい例
- time.Now()
- http.Server()

悪い例
- time.TimeNow()
- http.HTTPServer()

### 単純な関数の名前

pkg.New() は pkg.Pkg または *pkg.Pkg　を返す

例
```go
q := list.New() // q は *list.List
```

```go
d, err := time.ParseDuration("10s") // d は time.Duration
ticker := time.NewTicker(d)         // ticker は *time.Ticker
```

もしプレフィックスとしてのパッケージの名前が思いつかないのであれば、パッケージの境界が間違っているかもしれない。


## 悪い命名例

### 意味のないパッケージネームは避ける

- util
- common
- misc

はユーザー側になにも情報を提供しない。
汎用的な名前だからほかのパッケージとも衝突しやすい

悪い例
```go
package util
func NewStringSet(...string) map[string]bool {...}
func SortStringSet(map[string]bool) []string {...}
```

いい例
utilから抽出してパッケージに分ける
```go
package stringset
func New(...string) map[string]bool {...}
func Sort(map[string]bool) []string {...}
```

### API をひとつにまとめない

API（interface）をひとつのapiというパッケージにまとめようとするのは間違ったアプローチ際限なく大きくなり、ユーザーにガイダンスを提示せず、依存が混雑し、importが複雑になる。

### 不必要な名前の衝突を避ける

異なるディレクトリのパッケージが同じ名前がついたとき、それらがよく一緒に使われるのであれば、明確に異なるパッケージの名前に変えるべき。
また、ioやhttpといった有名な名前と一緒にすべきでもない。

## References

https://go.dev/blog/package-names?utm_source=dlvr.it&utm_medium=twitter

https://go.dev/doc/effective_go.html

https://go.dev/doc/code.html

https://blog.golang.org/organizing-go-code
テストスライスアノテーションを使う場合 @SpringBootApplication 付与クラスに直接DIしない方が良い

# 概要

`@SpringBootApplication`を付与したクラスに直接DIをした場合、`@DataJpaTest`や`@WebMvcTest`といったテストスライスアノテーションを利用したテストの実施時に、`NoSuchBeanDefinitionException`が出て失敗することがある。
なぜそうなるのか調査したので、そのメモを残す。

# どういう事象なの？

下記のような`@SpringBootApplication`を付与したクラスがあるとする。

```java
@SpringBootApplication
public class SlicetestApplication {
	
	private final HelloService helloService;

	public SlicetestApplication(HelloService helloService) {
		this.helloService = helloService;
	}

	public static void main(String[] args) {
		SpringApplication.run(SlicetestApplication.class, args);
	}

}
```

このクラスは`HelloService`をコンストラクタインジェクションしている。
`HelloService`は下記のよう。
```java:HelloService.java
@Service
public class HelloService {

    public void hello() {
        System.out.println("hello");
    }
}
```

このようなクラスがある前提で、テストスライスアノテーションの1つである`@DataJpaTest`を利用したテストを実行したとする。

```java
@DataJpaTest
class DataJpaSampleTest {

    @Test
    void test() {...
```

**このとき、`@DataJpaTest`は`NoSuchBeanDefinitionException` が出力されて、正しくテストが実行されない。**

# 何が原因なの？

原因を端的に書くと、
**`@SpringBootApplication`は`@Component`を内包しているが、テストスライスアノテーションでは基本的に各種コンポーネント定義を無視する** 
ためである。

## ＠SpringBootApplicationについて

`@SpringBootApplication`の実装は下記のようになっている。

```java:SpringBootAppication.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
```

また、`@SpringBootConfiguration`は下記のよう。
```java:SpringBootConfiguration.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {
```

そして、`@Configuration`に`@Component`が含まれている。

```java:Configuration.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
```

`@Component`が付与されているクラスは、DIコンテナ(アプリケーションコンテキスト)に管理させたいBeanであることを示す。
よって、上記の例でいくと`SlicetestApplication`はDIコンテナに管理されるBeanとなる。

## テストスライスアノテーションについて

まず、テストスライスアノテーションについては、[この記事](https://qiita.com/nannany_hey/items/94f0d1bf0eca77c4d4f7)でその内実を記した。

テストスライスアノテーションに内包される`@BootstrapWith(~~~)`によって、`@SpringBootApplication`を起点としてDIコンテナを構築していくが、これまたテストスライスアノテーションに内包される`@TypeExcludeFilters(~~~)`によって、**概ね全てのBean定義がDIコンテナに読み込まれなくなる**。
御多分に洩れず、`@Service`もDIコンテナには読み込まれなくなるため、テストスライスアノテーションを用いてテスト起動した時には、上記の`HelloService`はDIコンテナに登録されない。

## まとめ

`@SpringBootApplication`付与クラスに直接何かDIされている状況で、テストスライスアノテーションを利用したテストを実施したら失敗する。
なぜなら、`@SpringBootApplication`は`@Component`を内包しているが、テストスライスアノテーションでは基本的に各種コンポーネント定義を無視するため。

# 参考

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.testing.spring-boot-applications.detecting-configuration
上記公式ページにガッツリと下記のように記述してある。

```
If you use a test annotation to test a more specific slice of your application, 
you should avoid adding configuration settings that are specific to a particular area on the main method’s application class.
```
VS Codeの拡張機能 Export/Import をもっと手軽に

# 🫣TL;DR
みんな大好きVS Code。
拡張機能も豊富にあり非常に便利ですが、一番困るのがPCを新調したとき。
これまで折角たくさん入れてきたのに全て消えてしまい、何を入れていたかも忘れてしまい、悲しくなりますよね。
また、他人に「この設定便利だよ！」と教えるのも拡張機能一覧を見せてこれを全部入れて～はちょっとイケてません。。。
そんなときにこの記事を読んでください。

# `code`コマンドを準備
Windowsであれば、VS Codeのインストールと同時に `code` コマンドを使えるようになります。
macOSはPATHを通す必要があります。
詳しくは以下の記事を参考にしてください。

https://zenn.dev/ryuu/articles/what-vscodecommand

# 📤インストール済み拡張機能をExport
`code --list-extensions`でインストール済みの拡張機能一覧を出力します。

```shell
出力例）
PS C:\Users\pitao> code --list-extensions
formulahendry.dotnet-test-explorer
Fudge.auto-using
jmrog.vscode-nuget-package-manager
k--kato.docomment
kreativ-software.csharpextensions
MS-CEINTL.vscode-language-pack-ja
ms-dotnettools.csharp
patcx.vscode-nuget-gallery
```

# 📥新しいVS Codeに拡張機能をImport
`code --install-extension {拡張機能}`で対象の拡張機能をインストールできます。
先ほどのリストの行頭に追記したらいいのですが、これも一括で行いたいと思います。コマンドラインだと環境により微妙に書き方が変わるので、VS Codeでやってしまうのが丸いでしょう。

VS Codeの置換機能で正規表現(`.*`)モードを有効にし、行頭(`^`)に`code --install-extension `を追記しましょう。
![s.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252806/f5054803-5485-1665-957d-f726c7e5ba94.png)
↓
![ダウンロード (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252806/5cecf2a0-abe9-b99b-435c-786ee4da1929.png)

あとはこれをコピーしてメモに残し、新しい環境で実行しましょう！
Javaで何か作ってみる(2022/11/14 Day25)

## 今日やった事
- Javaの動画教材の演習問題である、Jihanプログラムの作成を行った。  
&rarr;コミットした内容は[こちら](https://github.com/takamatsuryota3/Java/commit/2ead947186b9f5a81c699bc1246d17898448e6cc)
## 参考にしたもの
- [【超絶丁寧解説】Javaプログラミングをゼロから学ぶ！絶対挫折させない「基礎入門」講座【講師評価4.3】](https://www.udemy.com/course/uz-java-kiso/)  
&rarr;今回取り組んだのは、この動画教材の中の、**J1-EX1_総合演習（アルゴリズム）** の**総合演習（Jihanプログラムの作成）** になる。
- [[Java]Integer.parseIntメソッドの使い方とは？parseIntメソッドやparseUnsignedIntメソッドの使い方・例外の発生するケース・配列の変換Javaコラム](https://www.fenet.jp/java/column/java_tips/6643/)  
&rarr;演習問題では触れられていないが、Integer.parseIntメソッドは、数字じゃない文字列（ex. aaaとか、あああ等）を変換しようとすると、例外発生する為、  
どういう対策がいいか参考にした。
## 所感
- アルゴリズムの演習問題なので、プログラムの考え方が決まってくれば実装はすぐだなと思った。
- Javaのお作法はあるものの、日々の業務経験が勉強に活きているなと感じる。
## 明日の予定
- Jihanプログラムを完成まで進めたい。
ワーケーションのノウハウ

## 予定を立てる

### 行きたい場所を決める

せっかくのワーケーションですので、まずは行きたい場所から決めましょう。
せっかく良い環境で仕事ができるので、行きたい場所・やりたい環境で仕事をすることが大切です。
ここでは観光地や予てから行きたかった場所などで選ぶので良いでしょう。ワーケーションしてる感を味わうことが大切です。

### 時期を決める

行きたい場所と同時に時期も決めると良いでしょう。
当然、お盆や正月、夏休みや冬休みなど、祝日や学生さんの長期休みには旅費が高くなる傾向にあります。
もし可能であれば、それらの予定とずらして予定を立てるのが良いでしょう。

一方で繁忙期とずれているために休みをとっている観光地・お店もあるので、事前に調べていくのが良さそうです。

### 仕事ができる場所を探す

ワーケーションは言葉の通り、work + vacation の造語です。
仕事も休むも両方できなければなりません。
ワーケーションといえば自然環境や観光地、仕事後のお酒に目が行きがちですが、行きたい場所が決まったならば次は仕事が快適にできる場所を探しましょう。

「wifi」「カフェ」「コワーキングスペース」などで検索すると現地で作業するスペースを探しやすかったです。wifiの速度のクチコミや駅からの距離など、細かく調べておくとさらに良いでしょう。ここの満足感がワーケーション全体の満足度を左右すると言っても過言ではないかもしれません。
また、営業時間が自分の作業時間とマッチしているかを調べておきましょう。

一般的なカフェだと一般のお客さんも多くいるためミーティングなどで不便することがあるかもしれません。
個人的には、少し値段がするとしてもコワーキングスペースを利用したいと感じました。
もしくは社内制度などで契約しているコワーキングスペースがあれば積極的に利用するのが良いでしょう。

### ホテルを選ぶ

Airbnb に代表されるように個人経営で安く泊まれる宿泊施設が人気ですが、観光業の繁忙期とずらして行けばホテルでも安く泊まれるところは結構あります。
ロケーション・清潔感・安さ・ワーケーション感などさまざまあるかと思いますが、ご自身が納得する場所を選ぶことが大切です。

## 現地を楽しむ

### 仕事の時間をコントロールする

もし始業時間や就業時間を自由に選べるのであれば、街へ出かける時間を考えて仕事を始められると良いかもしれません。
私は早い時間に仕事を終えるためにいつもより早起きて仕事してましたが、結局いつもの時間まで仕事してしまうことは割とありました（笑）仕事もプライベートも計画的に進められるようになりたいですね。

### 現地感を味わう

言うまでもないかもしれませんが、その地でしか出来ないことを体験するのが良いでしょう。後で振り返ったときにパッと思い出せる記憶があると、ワーケーションから帰ってきてからも良い記憶として残りやすいと思います。

### 平日の夜を狙う

観光地の平日の夜は素晴らしいです。土日なら人が多くゆっくり見られない所でも平日の夜ならかなり自由に見て回ることができます。
実際、私は平日の夜に水族館に行ったのですが、他にお客さんが１家族しかおらず大きな水槽を独占してしまいました。振り返ってみてもここの満足度は非常に高かったです。
ただし、平日の夜営業していないところもあるかと思うので、やっているかどうかは下調べが必要かと思います。

## あるとちょっと便利なもの

### iPad

普段デュアルディスプレイでの作業に慣れている人は、ノートPCのみの画面で作業することに少し窮屈さを感じることがあるかもしれません。
iPadがあればどこでもデュアルディスプレイを実現できるのでオススメです。

### 割り勘ツール

複数人でワーケーションに行く場合、各種支払いをどうするかという課題があるかと思います。
現金しか使えないお店や、事前にホテルなどをとる必要があったりするかもしれません。
そんな時に使えそうなツールをいくつか列挙してみました↓

#### Walica

グループを作成してURLを共有することで支払いを記録することができます。
支払いのたびに誰が何円払ったかを記録していき、旅の終わったら誰から誰にいくら支払えば良いのか自動的に計算してくれます。
UIもスマホ用になっていてとても使いやすいです。

https://walica.jp/

#### PayPay

PayPayの割り勘機能も使いやすいです。やはり最近はPayPayのアカウントを持っている人が多く、誰とでもサクッと割り勘できるイメージがあります。また、そもそも支払い機能が備わっているので、割り勘金額を計算するだけでなく、支払いもできるのが良いですね。

https://paypay.ne.jp/guide/warikan/

#### Kyash

Kyashの共有口座を使えば、共通の口座にあらかじめ入金し支払いを行うことができるようです。（実際に利用したことはないので参考程度に。。。）
共通口座にしておけば、そもそも割り勘ということを考えなくてすみそうですし、Kyashはデビットカードのように使えるのでVISAやタッチ決済できるのが良いポイントですね。

https://www.kyash.co/information/20210511

## 振り返り

### KPTを実施する

エンジニアの友人とワーケーションしに行ったので、振り返りとしてKPTを実施しました。
これがとても良かったです。何が良くて悪かったのか、次回以降のワーケーションをより良くできそうなアイデアがたくさん出てきました。
この記事を読んでワーケーションに行かれる方は、帰ってきたらぜひ実施してほしいです。

## おわりに

以上が私が持っているワーケーションのノウハウ（？）の全体像です。
お役に立ちましたら幸いです。
ここまで読んでいただきありがとうございました。
【Android_java】AndroidStdioでアクションボタンを追加する方法

- 基本的にスクリーンショットが多い記事になりますのであらかじめご了承ください。
※この記事はあくまでも勉強を始めたばかりの自分メモになります。

# アクションボタンの追加方法



Androidアプリでよく使用される右上のボタン(**アクションボタン**)の実装方法になります。
![3.アクションボタン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962146/01fc4e16-da2e-b637-b526-a652b6a9b005.png)


## xmlファイルの準備
### メニューxmlファイルを用意する

1. プロジェクトを立ち上げる。
2. オレンジ枠で囲まれている`res`フォルダの中に`新規`で`Androidリソース・ファイル`を選択。
![1.新規メニューxmlを作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962146/7ef305c8-6f87-88e3-9d66-3823b3841c65.png)

3. ファイル名を自由に記載する。今回はmenuという名前にする。
4. リソース・タイプには`メニュー`を選択してOKをクリック。
5. これで「resフォルダ>menuフォルダ>menu.xmlファイル」となっている。
※menuフォルダの中にxmlファイルがなければ、menuフォルダの中に「Menuリソース・ファイル」を新規作成 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962146/79820c62-be38-be6a-2ebc-99f43d301523.png)

### Menuリソース・ファイルの中身を記述する

1. menu.xmlファイルを開く
2. 下記コード記述する
※今回は最もシンプルに記述しています。

~~~xml
    <item
        android:id="@+id/menu"
        android:title="設定"
    />
~~~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962146/904e3eec-35ef-911a-43ba-15a211eb0db1.png)
上記が正常に記述できていれば下図のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962146/f6a0a3c2-839b-e085-64a0-922f310c01b9.png)

これでxmlファイルの準備が完了しました。

# MainActivityにてメニューを実装する
### onCreateOptionsMenu
- メニューは`onCreateOptionsMenu`をオーバーライドすることで実装できる。

1. 下記プログラムを`MainActivity.java`に記述する
1.  inflater.inflate(R.menu.menu,menu);
1.    ↑   inflater.inflate(`R.menu`.`Menuリソース・ファイル名`,`itemのid`);
~~~java
    //事前にimportしておく
    //import android.view.Menu;
    //import android.view.MenuInflater;
    @Override
    public boolean onCreateOptionsMenu(Menu menu){
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu,menu);
        return true;
    }
~~~

# 実機での表示
- 実際に実機にてデバッグすると下記画像のように表示されます。
![実画面３.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962146/79778098-4d21-7b77-739d-0b5a7be62589.png)


---
### 関連Qiitaサイト
- 【Android_java】関連まとめ記事
https://qiita.com/PONchan9848/items/1a507c6be4e7071bef45
【検証】Spreadsheetの新機能、「タイムライン」は私が欲していたガントチャートなのか？~その２~

## はじめに
この記事はこちらの記事（[【検証】Spreadsheetの新機能、「タイムライン」は私が欲していたガントチャートなのか？](https://qiita.com/yoh_n/items/4897a79918186eb4d0a9)）の続きです。

11月2日にGoogleのSpreadsheetに Timeline view なるものが追加されました。これはSpreadsheetに入力されたタスクの一覧をガントチャート風に表示するものです。
前回の記事では一通りの機能を触ってみて感想を書きました。
今回は前回の記事で気づいた問題などをさらに掘り下げてみます。

### 24時間戦えますか？問題
最近新卒で入社してきた世代にはこのフレーズでピンとくる人が少ないです。
余談はさておき[こちら](https://qiita.com/yoh_n/items/4897a79918186eb4d0a9#2-%E3%82%BF%E3%82%B9%E3%82%AF%E3%81%AE%E6%89%80%E8%A6%81%E6%99%82%E9%96%93%E3%81%A7%E8%A8%98%E8%BC%89%E3%81%99%E3%82%8B)に書いたように、タスクの開始日と所要時間（HH:MM:SS）を指定してカードを描画する場合、タスクは1日24時間進むものとして計算されます（下図のタスク2）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/220881/02a6e03c-334b-213f-4bf6-a03254f1468e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/220881/fd2ee445-f6aa-083f-95a7-dad00410595d.png)

1日の実働時間が8時間の場合タスクの所要時間が `24:00:00（24時間）` のタスクは3日かかりますが、タイムライン上では1日分の長さのカードになってしまいます。

実は、終了日については設定の注釈に以下のように記載されていますが
> 終了日はタスクの最終日を表します。期間は、タスクの長さを表す日数（整数値）、または (HH:MM:SS) の形式です。

日数は少数でも指定できます。
例えば上記の例でタスク1は4時間なので、実働8時間の場合は0.5日とします。
同様に24時間のタスクは3になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/220881/d9d75a4f-beb4-eba4-6c60-a42fbe15196f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/220881/5a6f23f0-ad19-9be5-720d-7e786fa3078c.png)
ちゃんとタスク2で3日分確保されていますね。
また、このタスク一覧表では開始日（B列）を `=1つ前のタスクの開始日 + 1つ前のタスクの期間` という式で導出し、分かり易いように時間まで表示しています。
実際には午前0時から働きませんが、こうしておいた方がタイムラインに余計な空白ができないので見やすいと思います。

:::note info
カードの終了日を開始日時からの期間（日数）で入力する場合、小数点を使うことで時間を表現できる
:::

### 開始日休日問題
先ほどの例では`=1つ前のタスクの開始日 + 1つ前のタスクの期間`という計算で求めた開始日と、疑似的な日数の少数でカードを描画しました。
この場合タイムラインの「週末を含める」チェックボックスを外すと土日はタスクが進まないものとしてカードの長さが計算されますが、開始日が休日だった場合はその日はタスクが進むものとして扱われます（下図のタスク2、タスク3）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/220881/42cff8e0-6b66-811f-113a-f5bed5e6fec8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/220881/84f0cf99-3d4a-1384-d0a5-ffa59c83cd93.png)
そのため、開始日を表計算や[カスタム関数](https://qiita.com/yoh_n/items/0104984f1d3bdae81e82)などで導出する場合にはこの点に注意しなければなりません。
表計算でいいところまで頑張った残骸を置いていきます（ちょっとバグってます）。素直にGASを書けばよかった。
`=IF(DAY(B2)=DAY(B2+C2),B2+C2,WORKDAY(B2,DAY(B2+C2)-DAY(B2),'祝日'!$A:$A)+C2-(DATE(YEAR(B2),MONTH(B2),DAY(B2)+1)-B2))`

### 祝日は休めるのか
ここまでやってふと気になったのですが、祝日をまたぐタスクはどうなるのでしょうか？
週末を含めるチェックを外したときのように良い感じに扱ってくれるのでしょうか？
ワールドワイドなGoogle先生が日本の祝日を考慮しているとは思えないので嫌な予感しかしません。
というわけで最後にこのようなタスク一覧を試してみます。11月23日は勤労感謝の日です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/220881/88b49dc8-8912-0d27-2333-73e0c225e1bf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/220881/fa381a7c-da08-90f3-eb77-6dbcfff861fd.png)
やはりだめでした。
現状だと、祝日をまたぐタスクの場合期間に下駄をはかせる必要がありそうです。

### まとめ
2回にわたってSpreadsheetのタイムラインがどの程度使えそうか検証しました。
シートさえ用意すれば描画してくれるシンプルなところや、これまでのGAS資産を活かせそうなところは良いなと思いました。
一方で休日、祝日周りでは課題も有ることが分かりました。GASなどで頑張れない範囲ではありませんが、使うときにはこの点を踏まえて実装する必要がありそうです。
【Android_java】関連まとめ記事

# 【Android_java】関連まとめ記事
- アンドロイド開発の勉強として自分メモの代わりに作成した記事のまとめになります。
- 順不同で掲載していきますので、記事を探さす際は`Ctrl+F`で検索することをお勧めします。

## 記事
- 【Android_java】AndroidStdioでアクションボタンを追加する方法
https://qiita.com/PONchan9848/items/6a2dec1b3173659dc123
Javascript(React)内でタグ補完がされない

<h1>結論:Emmetをいじろう</h1>
前提:拡張機能からJavascript ES6 code snippがダウンロード済

Ctrl+「,」で設定を開き、検索欄にemmetと入力
Emmet: Include Languagesを選択して項目に「javascript」値に「javascriptreact」を入力する。
SHA256フィンガープリントとは何か

## SHA-2とは
Secure Hash Algorithmシリーズの暗号学的ハッシュ関数。SHA-1の改良となるアルゴリズム。

ちなみに読み方はシャーツー

## ダイジェストとは
元データから、ハッシュ関数を使って計算によって求められた値の事。

よってハッシュ値と同じ意味になる。

## SHA256とは
SHA-2に分類されるハッシュ関数。
ダイジェストの長さが256ビットの暗号化ハッシュ。

```bash
# sha256sumコマンドにてハッシュ化
echo "test" | sha256sum | cut -f 1 -d " "
# f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2
```
上の例のように、基本的にはどんな長さの文字列からでも固定長のダイジェストを作成可能、とのこと。(0文字からでも可)

また、文字列は16進数の形式をとっており、常に64文字が出力される。(256bit / 4bit = 64)


## フィンガープリントとは
公開鍵を識別するための短いバイト列のこと。
SSHサーバを識別するために利用される。

```bash
# 公開鍵のフィンガープリントを表示
ssh-keygen -l -f ~/.ssh/id_rsa.pub
```
ソフトによってはknow hostsに保存されている公開鍵と取得した公開鍵が一致していない場合には警告が表示されることがある。

目視で公開鍵を比較するのは大変のため、短い文字列に変換するとのこと。


## RandomArtとは
人間がハッシュ値を目視で比較するのをより楽にするための構造化された画像の事。

テキストではなく画像の形式にすることでより公開鍵を目視で比較しやすくなる。

```bash
#
# *Sample*
#
# $(echo test | sha256sum | cut -f 1 -d ' ') のrandomart
+--[ RandomArt ]--+
|                 |
|                 |
|       . = . .   |
|      o X + o    |
|      .*S* o     |
|       o* . o . .|
|      oo.E . + ++|
|     o +O = o o=B|
|      =*oo .  +B*|
+-----------------+
```
ちなみに参考文献としては下記があるようです。

[https://users.ece.cmu.edu/~adrian/projects/validation/validation.pdf
](https://users.ece.cmu.edu/~adrian/projects/validation/validation.pdf)

<br>
以上
Reactの第一歩。renderって何なの？(メモ)

個人的なメモ帳代わり。自分と同様の疑問を持った方は参考にどうぞ。Qiitaの記事を書く練習も兼ねて。理解が深くなれば追記予定。

# Q.そもそもレンダリングとは何ぞや？

調べる。

## A.要するに指定したリソースをブラウザ画面に表示すること。
レンダリングの仕組みなどについては以下の参考URLから。

https://zenn.dev/oreo2990/articles/280d39a45c203e




参考URL

https://mabui.org/react-render-description/

# ・Reactには二種類のrenderメソッドがある。

### 1.ReactDOM.render()
Reactエレメントをドキュメント(生成されるhtml等の文書)にレンダリングするもの。

### 2.Reactコンポーネントのクラスで呼び出されているrender
JSXなどで定義されたReactエレメントを返す処理を行っている。

# 両メソッドとも、複数のコンポーネントを返すことは出来ない。
レンダリングが目的のメソッドなので、その他の処理を持たせないようする。
文字列の出力(echo)、変数について

### 命令(echo)

「**echo**」は文字列を出力するための命令。
出力したい文字列は'(シングルクォーテーション)か
"(ダブルクォーテーション)で囲む。

例 コード：\<?PHP **echo** 'SPW財団';?>
   結果：SPW財団

### echoを用いた計算

「echo」の後の文字列を入れる部分に計算を入れることも出来る。

例 コード：\<?PHP **echo** 1 + 1;?>
&emsp;&thinsp;&thinsp;結果：2

### データの種類

PHPに使用するデータには文字出来る列(例 'SPW財団')や
数値(例　1+1)など様々な種類がある。
同じ1+1でもそのまま「echo」の後に入れた場合は数値の計算結果が、
シングルクォーテーションやダブルクォーテーションで囲むと
1+1がそのまま文字列として出力される。

### 変数の定義

「echo」で命令を行う前に**変数**(**$name**)を定義することで
同じ値を1つのタグのなかで複数使いまわしたり、
コードを簡潔に記載することが出来る。

変数は　$変数名='値'でコード上に定義することが出来る。

例 コード：\<?PHP **$color** = 'Red';
&thinsp;&thinsp;&emsp;&emsp;&emsp;&emsp;&emsp;echo **$color**;
&emsp;&emsp;&emsp;&emsp;&emsp;?>
  　&thinsp; 結果：定義した変数\(**$color**)を出力するよう命令\(echo)した
変数``($color)``の値\(Red)が表示される。 

### 変数のルール

変数名を付けるときはローマ字、日本語を使用したり
変数名が数字から始まったりしないようにする。
変数名には英単語を用いて、2語以上の英単語が入る際には大文字で区切る。

### 変数の値の変更

変数は、中に入っている値を変更することも出来る。
一度定義した変数に再び値を代入することで変数の値が上書きされる。

例 コード：\$num = 3;
&thinsp;&thinsp;&emsp;&emsp;&emsp;&emsp;&emsp;echo ``$num``;　→3と出力される
&thinsp;&nbsp;&thinsp;&thinsp;&thinsp;&thinsp;&emsp;&emsp;&emsp;&emsp;``$num`` = 5;\
&thinsp;&thinsp;&emsp;&emsp;&emsp;&emsp;&emsp;echo ``$num``　→5と出力される
　 結果：最初に定義した変数(num)には元々値(3)が代入されていたが
&thinsp;&thinsp;&thinsp;&thinsp;&thinsp;&thinsp;&thinsp;&ensp;&ensp;&emsp;&emsp;再度同じ変数(num)に値(5)を代入したため最終的には
&thinsp;&thinsp;&thinsp;&thinsp;&thinsp;&thinsp;&thinsp;&ensp;&ensp;&emsp;&emsp;あとから代入した5が出力される

### 変数の値に数字を足す

変数の値に計算式を入れて、変数の値を更新することが出来る。

例 コード：\$x``=``1
&thinsp;&thinsp;&emsp;&emsp;&emsp;&emsp;&emsp;\$x ``=`` \$x`` + ``5;
&thinsp;&thinsp;&thinsp;&thinsp;&thinsp;&thinsp;&thinsp;&emsp;&emsp;&emsp;&emsp;echo \$``x``;
　 結果：変数(\$x``=``1)の値(1)に5が足されているため6と表示される。

変数の値に計算式を入れる際、省略形を使うことも出来る。

\$x ``=``\$x ``+``10;&emsp;→&emsp;\$x``+``= 10;

省略形の+の部分を-、*、/、％にすることで足し算以外の計算も行うことが出来る。
また、値が1の時だけ、さらに省略した書き方が出来る。

\$x ``+``=1;
→\$x``+``+;

省略形の+の部分を-、*、/、％にすることで足し算以外の計算も行うことが出来る。
Seleniumをローカルで動かす (python)

記載日：2022/11/14
pythonでseleniumを実行してみます。


#### 目標（7分）
pythonでSeleniumを実行し、Webサイトの画面を開く。

#### 環境
OS : Ubuntu22.04
Chrome：107.0.5304.110。インストール済。
Chrome Driver：107.0.5304.62。
VSCodeインストール済。
pythonインストール済。
（私の環境ではpyenvをインストールしたので、python使える状況。）
※pyenvのインストール方法は[こちら](https://qiita.com/middle_aged_rookie_programmer/items/0eb574e92a52c923e7ec)


#### 作業
#### 0.プロジェクト作成（1分）
プロジェクトフォルダへ移動し、プロジェクトファイルを作成する。
VSCodeを開く。
~~~command
cd ~/Desktop
mkdir python-test
cd python-test
touch main.py
code .
~~~

#### 1.Chrome Driverダウンロード（1分）
[Webサイト](https://chromedriver.chromium.org/downloads)から、自分のChromeバージョンに一致するドライバーをダウンロードする。私の環境では、Chromeが107.0.5304.～だったので、107.0.5304.62のChrome Driverをダウンロードした。
ダウンロードファイルを解凍し、chromedriver（実行ファイル）をプロジェクトフォルダ内へ移動する。

　python-test
　　|
　　|-main.py
　　|-chromedriver


#### 2.コード記述（5分）
VSCodeでmain.pyに以下を記述。
今回はoptionsを特に設定してないが、headlessなどの設定をここにすることになる。

~~~python
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options as OptionsC

def main():
    DriverPath="./chromedriver"
    optionsC=OptionsC()
    driver=webdriver.Chrome(DriverPath, options=optionsC)
    driver.get("https://[ドメインやURL]")

    time.sleep(10) #10秒待ち
    driver.close()
    driver.quit()

if __name__=="__main__":
    main()
~~~

pipを使ってSeleniumをインストール後、pythonコマンドで本プログラムを実行する。設定したWebサイトが開き、うまく動いたことが分かる。
~~~command
pip install selenium
python main.py
~~~
UnityとCRMの連携（その２）

## 事前チャットフォーム

Salesforce Chatでは、ウエブページ閲覧者に対し、チャット開始前に事前チャットフォーム(Pre-chat form)を表示することで個人情報の入力を促しています。また、閲覧者が必須のフィールドへデータ入力しないと、チャットを開始出来ない仕様になっています。

以下の事前チャットフォーム例では、赤い星印のフィールドが入力必須となっています（この例では、全てのフィールドが必須）。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194351/0afaee96-3b3a-c2c5-2917-1da8dbe699bd.jpeg" width=300>

これらフィールドからのデータは、チャット開始時、チャットのトランスクリプト(LiveChatTranscript)、ケース(Case)や取引先責任者(Contact)のレコードを自動作成したり自動検索する為に利用されます。上の事前チャットフォームの例では、氏名と電話番号のデータよりContactレコードを自動生成したり自動検索（既に氏名や電話番号が登録済みの場合）します。また、件名(Subject)よりCaseレコードを自動生成ないし自動検索します。

エージェントがサービスコンソール上でチャット要求受付時には、これらレコード（LiveChatTranscript, Contact, Case)がサービスコンソール画面に自動表示されます。

## Salesforce Chat REST APIにおける事前チャットフォームデータの送信

今回、この事前チャットフォームをUnityのuGUIを使って自作してみます。件名のフィールドは除いてあります。なぜなら、FirstPersonが歩き回っている物件情報を件名(Subject)とたいので、あえて、ユーザへ入力を促す必要がないと考えたからです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194351/57cab6c3-a70c-44a4-c34c-4634f2dda8d7.jpeg" width=500>

さて、この事前チャットフォームから得たデータをどうやってSalesforce PlatformへREST APIで送信するのか。ネット上の文献が乏しい中、以下の情報より、送信の方法を得ました。

[Create a case with Live Agent REST API](https://help.salesforce.com/s/articleView?id=000388107&type=1)

この部分のREST API処理を実装し、uGUIで自作した事前チャットフォームからSalesforce Platformへデータ送信してみました。サービスコンソールで、ContactとCaseが自動生成/自動検索されているのを確認出来ました。

![ServiceConsole.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194351/3537b0b0-c3c2-9588-ed75-e2fc9f268be1.jpeg)

これで、UntiyとSalesforceのCRM連携を実現出来ました。

## その３へ続く

次は、RaycastがヒットしたGameObjectの名前を、エージェントへチャットで自動送信するような実験をやってみたいです。y軸負の方向へRaycastし、ヒットした床GameObjectの名前（居間とかダイニングとか）を送信するとか、ユーザが画面上をタッチした方向でRaycastし、ヒットしたGameObjectの名前を送信するとか。
Powershell シングルクォーテーションやダブルクォーテーションのANSIコードを取得する

# 参考文献
[06.指定した文字のANSI文字コードを取得するには - HIRO'sNET](https://hiros-dot.net/PowerShell/string/string06.htm)

## 単純なようだが

```powershell
[byte][string]"a"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/dfa5dda2-410f-eed0-be53-23bca12a588f.png)

これはエラーです。CharとStringはあまり違いが意識されないのですが、この場合Stringではエラーになります。
これは記事の中に書いてあります。

> ANSIコードはバイト値として取得する必要がありますが、String型を直接バイト値に変換することはできません。
そこで Char型にキャストをしてから、バイト値に変換（キャスト）する必要があります。

```powershell
[byte][char]'a'
[byte][string]"a"
```

どちらも97です。
# それではシングルクォーテーションやダブルクォーテーションはどう書くか

前回のトリビアでも参考にしましたが、
[about_Quoting_Rules](https://social.technet.microsoft.com/Forums/windowsserver/en-US/93bfa2fe-6c78-4e58-a000-cc2ef929636e/how-to-express-the-dollar-sign-in-string?forum=winserverpowershell)
[How to express the dollar sign in string](https://social.technet.microsoft.com/Forums/windowsserver/en-US/93bfa2fe-6c78-4e58-a000-cc2ef929636e/how-to-express-the-dollar-sign-in-string?forum=winserverpowershell)

## 答え

```powershell
[byte][char]'"'  # Double Quotation
[byte][char]'''' # Single Quotation
[byte][char]'`'  # Backquote
```

### 曲者はシングルクォーテーション
これは4回必要になります。
このため

```powershell
'Don't'
```
は

```powershell
'Don''t'
```

このように書きます。ここからシングルクォーテーションを4つというのがわかります。

# Powershellがマイナーな理由がなんとなく
　しかし、この結論はかなり変です。英文では、Don'tのような表現は普通にあります。にも関わらず、Powershellでは毎回エスケープする必要があります。普通の英文を気軽にコピペして文字列に代入することもできません。HIRO's NET も HIRO\``sNETと書くことになります。
　このようにユーザーに負担をかけるような言語は普通は使い物になりません。なにか回避方法があるのでしょうか。
中途半端な導入は後で痛い目見ることになるで！CSS設計を導入する時のBadケースと回避方法

私が入社した当時弊社サービスは10周年を迎えようとした時で、CSS設計は導入されてませんでした。
その後SMACSSを導入し、6年程が経ちました。

CSS設計の導入によって社員のリテラシーや技術は向上したことは間違いなく、CSS設計の運用ノウハウやメリットも得られたと考えています。

:::note warn
**一方でCSS設計は長い年月運用していると反省すべき点が多くあります。**
:::

導入にはコストが掛かりますし、新しくメンバーをアサインしようとした時のハードルも上がります。

これまでの運用によって得られた知見をBadケースとしてまとめてみました。
導入を検討している方にとって何か1つでもお役に立てることがあれば幸いです！

## CSS設計とは？
一般的にコードのメンテナンス性や作業効率を上げるために、CSSコードの管理の方法や命名規則の考え方のことです。
良いCSS設計の条件として「予測しやすい」「保守しやすい」「拡張性がある」の3つがあります。

一般的によく耳にするCSS設計は3下記の3つだと思います。
- BEM
- SMACSS
- FLOCSS

https://getbem.com/

http://smacss.com/ja

https://github.com/hiloki/flocss

ちなみに、私が関わるサービスでは、SMACSSとFLOCSSを利用しております。

- CSS設計導入することで生産性が上がりそう！
- CSS設計ってすごいやん！

となっているところ恐縮ですが、主題の「CSS設計を導入する時のBadケース」に話題を移します。

## CSS設計を導入する時のBadケースって？
冒頭でも書きましたがCSS設計は非常に難しいです。
その上でこれだけはやってはいけない！ってことが1つだけあるとすれば…

それは、『導入を中途半端に終わらせてしまうこと』です。
つまり、中途半端な導入によって**サイト全体のCSSの記述や管理ルールから一貫性を失ってしまうことがBadケース**になると考えています。

CSSの記述や管理ルールに一貫性がなくなった場合にどのような問題が発生するか詳しく説明していきます。

## CSSの記述や管理ルールに一貫性がなくなった場合発生する問題
大きく分けて下記の2つだと考えています。

- 教育・採用コストの増加
- 開発工数の増加

### 教育・採用コストの増加
大前提としてCSS設計に関する知識を持っている人材を探さないといけません。
加えて古くからあるCSSと新しいCSSが共存している状態なので、コードを見ても正しいCSSの記述方法の**予測がつかない常態**のため問い合わせやサービス固有のローカルルールを教えるのに多くの工数を必要とするでしょう。

### 開発工数の増加
導入が中途半端になるとさまざまな命名ルールが入り乱れることになります。
また、古くからあるスタイルはidで指定してあるとするとCSSの詳細度があがることによって新しく定義したCSSが上手く当たらない事態が発生します。

命名が難しくなるだけでなく、CSSのオーバーライドによって試行錯誤や調査など**CSSの見通しが悪くなり多くのメンテナンス工数がかかる**ことで開発工数が増加します。

:::note alert
どこか一部だけでなく、サイト全てに導入する計画を立てて実施に踏み切ってほしいと切に願います。
導入して間もない頃は良いですが、**5年も経たないうちに運用に無理が出てくることは間違いないと断言します**。
:::

## 導入後にBadケースにならないための対策
とはいえすでにCSS設計で運用している、今まさに導入途中だという方のために…
**やっておけばBadケースを回避できるかもしれない**と思う方法を紹介しておきます!

### 1つのモジュールに対してバリエーション数の上限を決めておく
サービス改善が行われる限り一定のルールを設けないとパターンは無限に増えていきます。

- ちょっとpaddingが広い
- 文字が大きい
- キャプション付き
- コンテンツに枠線がある

という具合です。

例えば、モジュールのパターンは3つまでと決めておけば4つ目を作ろうとしたときに…
「4つ目になるけど、他にいらないパターンはある？今あるデザインとほとんど一緒なら統合したい」という相談の機会ができます。

:::note info
**モジュールが増える分断捨する**ことをルールに設け、実施することでCSSの平和が保てるのではないかと考えています！
:::

### なんでも好きに記述していいようなsassファイルを1つだけ作っておく
サービスの改善スピードが速いサービスなどには有効だと思います。
ABテストで成果が出たとき実際にサイトに組み込んでいきます。
開発スピードを優先して、**パフォーマンスやコードの奇麗さは二の次になることがしばしばあります**。

そんな時はいったん設計は無視していいと割り切って記述できるようなCSSファイルを用意し記述。
落ち着いたタイミングでリファクタリングしながら実装するタイミングを設ければCSSの見通しがよくなると考えます。

### 新しいモジュールの追加にはとにかく慎重に
モジュールを拡充する時は神経質になることが多いかと思いますが、新しく作る時は**全く新しい命名でモジュールが作れるので意識が緩みます…。**

もっというとネームスペースが確保されているためだと考えています。
長年運用するときにまず考えたいことがネームスペースをどうするか？ということです。

ネームスペースを確保するためにはできるだけモジュールを増やさないほうがいいのです。

:::note info
似たようなモジュール等があった場合はデザインされた方に導入の意図や利用用途を聞いた上でじっくり話し合ってから追加を決定してもらうのがいいと考えます。
:::

## まとめ
CSS設計は奥が深く、これが正解というのはないと考えています。
それぞれのサービスにあったそれぞれの設計手法があると考えています。

また、**CSS設計はあくまでも1つの概念なのでそのまま利用するのではなく、それぞれのCSS設計ルールの中で自社のサービスに合う形で変形させていけ**るといいのでは？と感じます。

CSSの見通しが良く保守性に優れたCSS設計の運用ができることを願っています。
仮想マシンとは

# はじめに
毎週1本様々な技術に関する記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiita.com/7_inai_)
# 仮想マシンとは
仮想マシンとは、仮想化技術を用いてコンピュータ内にもう1つのコンピュータを再現する技術のことです。

# そもそも仮想化とは？
仮想化とは、物理的な環境に捉われることなく、HWに含まれるCPU、メモリ等のリソースを論理的に分割、統合する技術のことを言います。仮想マシンは、サーバー仮想化と同義です。

# 仮想マシンで何ができる？
仮想マシンでは、先ほども記載した通り、通常は物理的に存在しているコンピュータを仮想的に作り出して作動させることができます。例えば、WindowsPCでMacOSやLinuxOSを動かす。というようなことができるようになります。

また、それにより以下のようなメリットが生まれます。
- コスト削減
- 1台のコンピュータでも、複数のOSで確認できる

# 仮想マシンの仕組み
仮想マシンはその構造の違いから主に以下の3種類に分けられます。
### ①ホスト型
物理マシンにホストOSとなるLinuxやWindowsをインストールして、その上に仮想マシンを動かす方式です。
### ②ハイパーバイザー型
サーバーに直接仮想マシンをインストールし、動作させる方式です。そのためホストOSを必要としません。

### ③コンテナ
仮想マシンではありませんが、仮想マシンと似たことができる仕組みとして __コンテナ__ があります。
コンテナでは1つのOS(ホストOS)で、それぞれの区分された環境(コンテナ)を動かすことができます。
コンテナの代表格としては[Docker](https://qiita.com/7_inai_/items/b01f8545abb1c350fe87)が挙げられます。


# 終わりに
筆者も以前、LinuxOSのPC上でMacOSでしか動かせないソフトを使用するために、VMWareという仮想化ソフトを使用したことがあります。仮想化がなければ、LinuxOS上で動作するソフトで代用するか、MacOSのPCを用意する必要があったため、非常に助かった経験があります。
DDDがわからない～小さなズレが招く崩壊～

# 顧客が本当に必要だったもの

「顧客が本当に必要だったもの」と呼ばれる風刺画があります。同じシステムを作っているはずなのにみんな見えているものが**ズレ**ていることを揶揄したものです。

実際のプロジェクトでも、**ズレ**てしまう話はよく聞きますが、これこそがシステムの崩壊の始まりなんじゃないかと考えています。

最初は小さな**ズレ**だったかもしれません。その小さな**ズレ**同士ががさらなる**ズレ**を生み出してしまいどんどん崩壊していってしまったのです。

# 何がズレているのか
**ズレ**ていたものは何なのか？要求でしょうか？設計書でしょうか？それともコードでしょうか？
確かにどれも**ズレ**ていたと思います。しかし本当に**ズレ**ていたのは、顧客や開発者などの人の考えです。人間の考えが同じであれば要求も設計もコードも**ズレ**ることはなかったはずです。

※著作権がわからないので画像を見たい方は、[Googlee検索](http://www.google.com/search?q=%E9%A1%A7%E5%AE%A2%E3%81%8C%E6%9C%AC%E5%BD%93%E3%81%AB%E5%BF%85%E8%A6%81%E3%81%A0%E3%81%A3%E3%81%9F%E3%82%82%E3%81%AE&um=1&ie=UTF-8&hl=ja&tbm=isch&source=og&sa=N&tab=wi)で探してみてください。
OUPC2022 E「WA_TLE's Bless」解説

# はじめに
「WA_TLE's Bless」writerのKowerKointです。
ゲーム形式にすることで少しひねった期待値DPの行列累乗問題でしたが、正しく行列を構築できたでしょうか。
# 解法
## DPを定義する
状態が順に遷移して、状態に紐付けられたスコアを求める問題なので、動的計画法を考えるのが自然です。

$i$回サイコロが振られたあと、次にサイコロを振るプレイヤーをA、そうでない方をBとしたとき、BがAの$j$マス($0\leq j<N$)マス先にいるとし、AにWA_TLEが宿っているとき$k=1$、ついていないとき$k=0$とすると、状態は$(i,j,k)$の組で表されます。
BのAに対する相対的な位置さえわかれば円の中にどこにいるかは区別しなくても問題ありません。
このような状態にある確率を`p[i][j][k]`、その時の「Aのレーティング - Bのレーティング」の期待値を`e[i][j][k]`としておきます。

状態$(i,j,k)$から、Aが出したサイコロの目を$x$であるときの次の状態を$(i+1,j',k')$とすると、
```math
j'=\{N-(j+k)\}\bmod N \\
k'=(\lfloor\dfrac{j+k}{2}\rfloor+1)\bmod 2
```
というようになります。
このとき、
```
p[i+1][j'][k']+=p[i][j][k]*(1/M)
e[i+1][j'][k']+=-(e[i][j][k]+j'*p[i][j][k])*(1/M)
```
というようにDPが遷移します(上記は疑似コードです)。

$O(NMK)$のDPが構築されました。
## 行列累乗に落とす
上で示したDPは、回数$i$によらない遷移であることから行列累乗を行うことができます。
$i$回の遷移で$(j,k)$状態から$(j',k')$に遷移する確率を$P_i[j][k][j'][k']$として
を$i$回の遷移での「次にサイコロを振るプレイヤーのレーティング - そうでないプレイヤーのレーティング」の増加量の期待値のうち、$(j,k)$状態から$(j',k')$に遷移する場合の占める部分を$E_i[j][k][j'][k']$として$2N\times2N$行列$P_i$、$E_i$を定義します。

$P_i$は線形性を持っていて、
```math
P_{i_1+i_2}[j][k][j''][k'']=\sum_{(j',k')}P_{ i_1}[j][k][j'][k']\cdot P_{i_2}[j'][k'][j''][k'']
```
が成り立ちます。

これを行列積とみなしてダブリングによる高速計算を行うのが通常の行列累乗のセオリーでした。

実は、無理に行列積の形に落とせなくても似たようなダブリングは可能なことがあります。
$E_i$については
```math
E_{i_1+i_2}[j][k][j''][k'']=\sum_{(j',k')}\{(-1)^{i_1}P_{i_1}[j][k][j'][k']E_{i_2}[j'][k'][j][k]+(-1)^{i_2}E_{i_1}[j][k][j'][k']P_{i_2}[j'][k'][j''][k'']\}
```
と書けます。

以上でダブリングを行えば、行列累乗と本質的に変わらないアルゴリズムが実践でき、計算量は行列の作成に$O(N^2+NM)$時間、行列累乗の実践に$O(N^3\log{K})$時間の合わせて$O(NM+N^3\log{K})$時間となります。

なお、確率と期待値を両方とも行列の成分に持った$4N\times 4N$の行列を用意して通常の行列累乗で計算することもできます(実はwriter解はこっち)。