OmniAICreator/Qiita-1.07M huggingface dataset:
imagick php laravel 画像に文字を合成

画像に文字を合成する。
たったそれだけ。

・フォント azuki.ttf はググって拾ってくる

```

$bg = new \Imagick(public_path('/img/lasthako.png'));//背景画像
$str = '恋に恋焦がれ恋に泣く';

$text = new \ImagickDraw();
$text->setFont(resource_path("/any/font/azuki.ttf"));//フォント
$text->setFontSize(32);
$text->setStrokeColor('#000'); // black

//テキスト描画設定を含む ImagickDraw オブジェクト。x,y,角度,描画するテキスト
$bg->annotateImage($text, 10, 200, 0, $str);

$bg->writeImage(public_path('new_sample2.png'));


```
久しぶりにRaspberry Pi Imagerを使ってみたらとても便利になっていた

Raspberry Pi Zero 2を購入して久しぶりにRaspberry Pi Imagerを使ってみたら、とっても便利になっていたので覚書。

# 日本語になっていた
最初に嬉しかったのは、起動したら日本語になっていた事でしょうか。
英語でも使えなきゃとは思いますが、英語だと細かい点で不安になることは多々あるので、日本語になっているととてもありがたい。

![スクリーンショット 2022-06-25 17.10.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/53162e20-22d9-f22a-814c-ab5e9a49a17d.png)

# インストール前にある程度の設定を指定できるようになっていた
OSを選ぶと右下に歯車のアイコンで設定するためのボタンが出てきました。
このボタンを押すと、ホスト名やユーザ名、パスワード、Wifiの設定が先にできるようになっていました。

![スクリーンショット 2022-06-25 17.06.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/30d40cd7-bd6e-558e-39cc-3c05fb7f2528.png)

## 設定の保持を指定
ここで変更した設定を保持するかどうかを選択します。
![スクリーンショット 2022-06-25 17.41.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/fbcce91a-abd3-5141-f1e6-d396ebf21c52.png)


## ホスト名とSSHの有効化を設定
ホスト名の変更とSSHの有効化、SSHを有効化したときの認証方法を設定できます。
![スクリーンショット 2022-06-25 17.41.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/c870e45c-2c15-07e5-1fb2-937e91154ff2.png)


## ユーザ名とパスワードの設定
ユーザ名とパスワードの設定を変更できます。
個人的にはpiアカウントは使わないので、最初から自分が普段使っているユーザ名を設定しておいてインストール直後にログインできるのは便利です。
![スクリーンショット 2022-06-25 17.08.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/26b9117a-8d77-7c90-4aee-a3ea6b3123a7.png)

## Wifiの設定
WifiのSSDとパスワードなどを設定できます。
![スクリーンショット 2022-06-25 17.27.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/4b8a9865-ecbc-77c9-c8a2-0ea603844bfe.png)

## ロケールの設定
タイムゾーンとキーボードの配列が設定できるようになっていました。
もちろん、US配列を指定してインストールしました。
今回はZero2へのインストールだったので、ほぼssh経由で使うことになるとは思うのですが。w
![スクリーンショット 2022-06-25 17.08.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/347c8714-7d9b-27f6-1978-901a78bfee43.png)

## その他
インストールが終わった時などの設定をできます。
![スクリーンショット 2022-06-25 17.08.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/e888ddb2-5e3f-9952-3ffb-cd9815c53615.png)

全て設定して「保存」ボタンを押します。
Wifiの設定などを指定した場合は、「いつも使う設定にする」とするとインストールのたびにSSDやパスワードを設定する必要がないので便利なのではないかと思います。

この設定ができるようになる前は、インストールメディアにsshファイルを置いたり、Wifiの設定ファイルを置いたり、キーボードの指定などは最初だけディスプレイ・キーボード・マウスをつなげてインストールして設定していたことを考えるととても便利になったと思います。

このRaspberry Pi Imagerの改善で今までよりもラズパイを使うハードルが下がったのではないかなと思います。
[Firestore]transactionで悲観ロックできない

複数の処理が連続して行われる場合にtransactionの排他制御を用いることは多くあると思います。
今回firestoreのtransaction中で悲観ロックを用いたのですがなぜかうまくいかない事象(分離レベル勘違いしていただけ)が起きたので解決法をまとめます。

[firebaseのトランザクションの使い方](https://zenn.dev/yucatio/articles/7c4ba0d0138ca9)

# 問題
簡潔に言うと次の処理をしていた。
1. tokenを取得
1. apiを叩く(token)
1. tokenが更新されるので保存
```js
admin.firestore().runTransaction(async (transaction) => {
  const token = await transaction.get(...)
  const res = await postApi(token)
  transaction.set(res.token)
})
```

ここでtransaction A,Bが連続して実行された時、transaction.getの時点でロックされ、transactionの終了まで待機する想定であった。
```
1. [A] 開始
1. [B] 開始
1. [A] get
1. [B] getを待機
1. [A] postApi
1. [A] 終了
1. [B] get完了
1. [B] postApi
1. [B] 終了
```
実際は以下のようになりロックできていなかった？
```
1. [A] 開始
1. [B] 開始
1. [A] get
1. [B] get
1. [A] postApi
1. [B] postApi
1. [B] エラー
1. [A] 終了
```

# 解決法
普通にtransaction自体は正しく動いていたので任意の回数retryさせた。
```js
admin.firestore().runTransaction(async (transaction) => {
  const token = await transaction.get(...)
  const res = (await postApi(token)).catch((e) => 再度実行)
  transaction.set(res.token)
})
```

原因としては分離レベルの理解が甘かった。
firestoreの分離レベルが"READ COMMITTED"であり、更新を検知した時に再度getするみたい。
🔽詳細

https://qiita.com/1amageek/items/2eff436fb69bea5875ea
EC2の起動テンプレートってどういうときに使うの？

## 勉強前イメージ

AutoScalingとかに使われる系？

## 調査

### EC2の起動テンプレート とは

EC2からインスタンスを作成する際に、
インスタンスを作成するときに設定する項目をあらかじめ指定しておいて作成する手間を省くことが出来ます。


### 設定する内容

- 起動テンプレートに関する名前や説明

![1起動テンプレートを作成 _ EC2 Management Console - Google Chro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/cca49213-3d2c-b780-1475-e152d404a2f5.png)


- 起動するEC2のインスタンスタイプやキーペアの指定

![2起動テンプレートを作成 _ EC2 Management Console - Google Chro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/0208bd01-b80c-e03c-4f92-7cba62e31331.png)


- ネットワークやボリューム、タグに関する設定

![3起動テンプレートを作成 _ EC2 Management Console - Google Chro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/64de966a-c117-2b09-e71d-7661fa84de07.png)


- その他

他にも設定できる項目は色々ありますが、
スポットインスタンスを指定して費用を抑えることが出来たり
ユーザーデータ という項目にスクリプトを記載しておくと、EC2を起動した際に記載したスクリプトが実行されます。

## 勉強後イメージ

今まで何も考えてなくて、項目にあるけど見えてないようなやつだったけど
例えば、「週に1回○○スクリプト回すために起動して実行してインスタンスを落とす」 というのが自動化できるんだね。
ユーザデータが結構便利そう
ちなみにユーザデータ初めて知ったけど、普通にEC2起動するときにも使えるのね。

## 参考

- [起動テンプレートを使ってお手軽にスポットインスタンスを起動する](https://dev.classmethod.jp/articles/spotinstances-launch-templates/)
- [AWS EC2起動テンプレートについて](https://www.guri2o1667.work/entry/2020/05/13/AWS_EC2%E8%B5%B7%E5%8B%95%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)
Emacsでcopilotってみた

# copilotとは

[copilot](https://github.com/features/copilot/)はAIがコードを提案して生産性を上げてくれるツールで、最近プレビュー版での公開から一般公開に変わりました。
VSCodeやNeovim、JetBrains IDEsなどに対応していますが、Emacsでも利用できそうだったので、実際に導入してみました。

# copilotに申込む
まず[こちら](https://docs.github.com/ja/copilot/quickstart)を参考にcopilotに申し込みます。
初回60日は無料となります。
学生など一部の条件を満たせば無料で使用できますが、基本的には月額10ドルまたは年間100ドルとなります。

# Emacsの設定

Emacsでは[copilot.el](https://github.com/zerolfx/copilot.el)を導入して、copilotを利用します。

## 準備
copilot.elではnode.jsが必要ですが、バージョンが12.xから17.xでないといけません。
私は18.1でしたので、[nvm](https://github.com/nvm-sh/nvm)を使用して、17をダウンロードしました。

```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
```

```
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
```

```
nvm install 17
```

## init.el

私は`straight.el`でパッケージ管理をしているので、init.elは下記のようになりました。

```init.el
(straight-use-package
 '(copilot :type git :host github :repo "zerolfx/copilot.el" :files ("dist" "*.el")))

;; 使用するnode.jsを指定
(setq copilot-node-executable "~/.nvm/versions/node/v17.9.1/bin/node")

;; プログラムモードの場合、copilot-modeを実行
(add-hook 'prog-mode-hook 'copilot-mode)

;; copilot用にキーバインドを設定
(defun my-tab ()
  (interactive)
  (or (copilot-accept-completion)
      (company-indent-or-complete-common nil)))

(global-set-key (kbd "C-TAB") #'my-tab)
(global-set-key (kbd "C-<tab>") #'my-tab)

(with-eval-after-load 'company
  (define-key company-active-map (kbd "C-TAB") #'my-tab)
  (define-key company-active-map (kbd "C-<tab>") #'my-tab)
  (define-key company-mode-map (kbd "C-TAB") #'my-tab)
  (define-key company-mode-map (kbd "C-<tab>") #'my-tab))

```
インストール後、`copilot-mode`を起動して、`M-x copilot-login`を実行します。

ミニバッファー上に6桁のワンタイムパスワードが表示されるので、パスワードをメモしてEnterを押下します。
するとGithubのリンクに飛ぶので、先程のパスワードを入力し、githubのアカウントを認証します。
認証が完了するとcopilotが利用できるようになります。

# 実際に使ってみた

関数名から補完したり、コメントから補完したりするだけでなく、日本語も補完してくれます。
また、下の動画は`javascript`ですが、`init.el`等の`emacs lisp`でもいい感じに補完してくれました。

![copilot](https://user-images.githubusercontent.com/76552003/175764410-73b78f7b-9643-446e-be36-1fde319ede45.gif)

# 感想

無料期間があるとはいえ月10ドル…と思っていましたが、実際に使ってみるとこれはお金を払ってもいいかなと思えるくらいよくできていました。
法人向けプランがまだ出ていませんが、職場でも使えるようにしたい…
WineのレジストリにRetinaModeの項目がなかったときにしたこと

# 概要
Zennの記事を参考にWineをインストールした。

https://zenn.dev/okojyo21/articles/76f23cd8b45487

記事通りに進んで行き、RetinaModeを有効にしたいのだが、なぜか存在しなかった。
なぜ；；
![スクリーンショット 2022-06-25 16.22.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505050/5f8a8963-4038-af03-5c37-53fecb4d462e.png)

# 解決策
Wineのレジストリは、.regファイルという単なるテキストで動いている。
`~/.wine/user.reg`をお好みのエディタで開いて、一番下の行に記述する。
今回は手っ取り早くvimで編集した。
```
$ vim ~/.wine/user.reg
```
vimを開いたら、`:$`コマンドでファイルの最下部に追加する。
`a`を押して挿入モードにし、以下を追記。
```
[Software\\Wine\\Mac Driver]
"RetinaMode"="Y"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505050/37a61843-5d84-94ad-3f89-92252cb798ad.png)
無事追加されたので、`$ winecfg`で解像度を適切なものに変更する。
168が推奨らしいが、個人的には250くらいが丁度よかった、お好みで。

[追記]
250はデカすぎて表示がおかしくなったりします。
168に戻しました。

画面 -> 画面の解像度 -> 250dpi
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2505050/a2648766-eb54-42b5-647a-6f56cf0bfddc.png)
お疲れ様でした。
コロナ期で自粛が増えた結果、体はpaddingが増え、周りの人とはmarginが増えた

## はじめに

プログラミング学習をはじめて多くの人が最初につまずくであろう箇所が「**marginとpaddingの違い**」だと思います。

自分もプログラミング学習当初は、

「h1, h2タグ余裕や！！」
「imgタグを使えば画像が配置できるのか！簡単簡単」
「floatを使えば要素を横並びにできるのか！」

と「**プログラミング余裕やっ！**」と調子に乗っていた矢先に「marginとpadding」が登場し苦しみました。

一般的な解説では「**要素の外側に余白を取りたいときはmargin、内側に余白を取りたい時はpadding**」という説明されていましたが、当時の自分にはこれだけでは全く理解できませんでした。

そもそも「**要素の内側と外側ってなんやねん**」と何度思ったことやら...

またTwitterを眺めていると自分だけでなく、多くの初学者が「marginとpaddingの違い」を苦しんでいました。

今回はそんな初学者の敵である「marginとpaddingの違い」について例えを用いて解説をします。

## この記事の対象者

- プログラミング初心者
- marginとpaddingの違いがあやふやな人
- marginとpaddingの違いを後輩に説明する時に苦戦している人

## この記事の目標

- marginとpaddingの違いをイメージで理解できるようになる

それでは早速、例えを用いた解説をします。

## コロナ期にまつわる例え

「**コロナ期で自粛が増えた結果、体はpaddingが増え、周りの人とはmarginが増えた**」

自分自身も後輩にpaddingとmarginの違いを説明する際はこの例えで説明をしています。

### コロナ期で自粛が増えた結果、体はpaddingが増えた

まずは前半部分の「コロナ期で自粛が増えた結果、体はpaddingが増えた」のイメージを紹介します。

![korona.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2695521/ad761176-8f17-9bc1-84f0-8b119addb876.png)

今回は体脂肪をpaddingと比喩していますが「**自分の体の内側の領域(余白)が増える**」というイメージです。

### コロナ期で、周りの人とはmarginが増えた

これに関しては「**ソーシャルディスタンス**」という言葉がすべでを表します。

![okku.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2695521/c514171e-28e4-4eb7-9bcd-27fcd5339397.png)

これはイメージはしやすいかと思います。

「自分の外側の領域(余白)が増えている」といったイメージです。


## 最後に

いかがだったでしょうか。

今回はmarginとpaddingの違いをコロナ期だからこそ使える例えを利用して解説をしました。

marginとpaddingの違いについては使っていく内に徐々に理解できるものでもあるので、今回紹介したイメージを持ちながら実際に使ってみて理解を深めていただければと思います。

他にもいろいろな記事を出しているので合わせて読んでいただけると嬉しいです。

https://qiita.com/SMAC/items/e50c981e0518141be28f

https://qiita.com/SMAC/items/af433f1013221c5ed529
Firebase Authenticationへの接続エラー

FirebaseAdminSDKを使用し、Firebase Authenticationを操作した際に　下記エラーが出た。
```
Error fetching user data: FirebaseAppError: Error while making request: connect ECONNREFUSED 127.0.0.1:9099. Error code: ECONNREFUSED
```

## 理由
>FIREBASE_AUTH_EMULATOR_HOST環境変数が設定されている場合、FirebaseAdminSDKは自動的に認証エミュレータに接続します。

FIREBASE_AUTH_EMULATOR_HOSTが設定されているため

## 解決法

```
unset FIREBASE_AUTH_EMULATOR_HOST
```
FIREBASE_AUTH_EMULATOR_HOST環境変数を削除する
## 資料
https://firebase.google.com/docs/emulator-suite/connect_auth#admin_sdks
SalesforceのActivity(活動)Task(ToDo)Event(行動)に関連するメモ

▼活動: ToDo、行動、カレンダー
https://help.salesforce.com/articleView?id=activities.htm&type=5
  ▽▽https://note.com/koji_matae/n/n43c42db4abfb
    ・活動：Activity。「行動」と「ToDo」は「活動」の表現方法である。カスタム項目は活動にしか追加出来ない。追加したら、ToDoと行動に使用出来る。
    ・ToDo：Task。任命先と期日、関連先は色んなオブジェクトへ設定出来る。
    ・行動：Event。タブがない。カレンダーに新規レコード出来る。登録したレコードはカレンダーで確認。
  ▽▽https://www.circlace.com/blog/salesforce/todo_activities201901.html
    ・Todo、行動の作成例
言語処理100本ノック解いてみた 6

```python
str1 = "paraparaparadise"
str2 = "paragraph"
def bigram(string):
  return [string[i:i+2] for i in range(len(string)-1)]
X = bigram(str1)
Y = bigram(str2)
print(X+Y)
dup = [_ for _ in X if _ in Y]
print([_ for _ in X if _ not in dup],[_ for _ in Y if _ not in dup])
print([[_,__]for _ in X for __ in Y])
if "se" in X: print("X") 
elif "se" in Y: print("Y") 
else: print("None")
"""
['pa', 'ar', 'ra', 'ap', 'pa', 'ar', 'ra', 'ap', 'pa', 'ar', 'ra', 'ad', 'di', 'is', 'se', 'pa', 'ar', 'ra', 'ag', 'gr', 'ra', 'ap', 'ph']
['ad', 'di', 'is', 'se'] ['ag', 'gr', 'ph']
[['pa', 'pa'], ['pa', 'ar'], ['pa', 'ra'], ['pa', 'ag'], ['pa', 'gr'], ['pa', 'ra'], ['pa', 'ap'], ['pa', 'ph'], ['ar', 'pa'], ['ar', 'ar'], ['ar', 'ra'], ['ar', 'ag'], ['ar', 'gr'], ['ar', 'ra'], ['ar', 'ap'], ['ar', 'ph'], ['ra', 'pa'], ['ra', 'ar'], ['ra', 'ra'], ['ra', 'ag'], ['ra', 'gr'], ['ra', 'ra'], ['ra', 'ap'], ['ra', 'ph'], ['ap', 'pa'], ['ap', 'ar'], ['ap', 'ra'], ['ap', 'ag'], ['ap', 'gr'], ['ap', 'ra'], ['ap', 'ap'], ['ap', 'ph'], ['pa', 'pa'], ['pa', 'ar'], ['pa', 'ra'], ['pa', 'ag'], ['pa', 'gr'], ['pa', 'ra'], ['pa', 'ap'], ['pa', 'ph'], ['ar', 'pa'], ['ar', 'ar'], ['ar', 'ra'], ['ar', 'ag'], ['ar', 'gr'], ['ar', 'ra'], ['ar', 'ap'], ['ar', 'ph'], ['ra', 'pa'], ['ra', 'ar'], ['ra', 'ra'], ['ra', 'ag'], ['ra', 'gr'], ['ra', 'ra'], ['ra', 'ap'], ['ra', 'ph'], ['ap', 'pa'], ['ap', 'ar'], ['ap', 'ra'], ['ap', 'ag'], ['ap', 'gr'], ['ap', 'ra'], ['ap', 'ap'], ['ap', 'ph'], ['pa', 'pa'], ['pa', 'ar'], ['pa', 'ra'], ['pa', 'ag'], ['pa', 'gr'], ['pa', 'ra'], ['pa', 'ap'], ['pa', 'ph'], ['ar', 'pa'], ['ar', 'ar'], ['ar', 'ra'], ['ar', 'ag'], ['ar', 'gr'], ['ar', 'ra'], ['ar', 'ap'], ['ar', 'ph'], ['ra', 'pa'], ['ra', 'ar'], ['ra', 'ra'], ['ra', 'ag'], ['ra', 'gr'], ['ra', 'ra'], ['ra', 'ap'], ['ra', 'ph'], ['ad', 'pa'], ['ad', 'ar'], ['ad', 'ra'], ['ad', 'ag'], ['ad', 'gr'], ['ad', 'ra'], ['ad', 'ap'], ['ad', 'ph'], ['di', 'pa'], ['di', 'ar'], ['di', 'ra'], ['di', 'ag'], ['di', 'gr'], ['di', 'ra'], ['di', 'ap'], ['di', 'ph'], ['is', 'pa'], ['is', 'ar'], ['is', 'ra'], ['is', 'ag'], ['is', 'gr'], ['is', 'ra'], ['is', 'ap'], ['is', 'ph'], ['se', 'pa'], ['se', 'ar'], ['se', 'ra'], ['se', 'ag'], ['se', 'gr'], ['se', 'ra'], ['se', 'ap'], ['se', 'ph']]
X
"""
```
反論期待してます。
しかし本当に解くわけがわからないので機械学習にジャンプします。
PowerApps アプリ所有者の変更

# はじめに
組織で利用するアプリにおいて、異動などによりPowerAppsのアプリ所有者が不在となってしまった場合、管理者権限により所有者を変更することで対応する。
本件について勉強したことを忘れないようメモするもの。

# 所有者変更の流れ
1. 新所有者の「ObjectID」確認
2. 対象アプリの詳細情報確認
3. アプリの所有者変更


# 1.新所有者の「ObjectID」確認
1. PowerShellでAzureAD管理センターへ接続する。
   ```powershell
      Import-Module -Name AzureAD
      Connect-AzureAD
   ```
2. 新所有者の「ObjectID」を出力する
   ```powershell
      Get-AzureADUser -ObjectID "新所有者のアカウント名" 
   ```
3. 「ObjectID」を控えておく。
![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671918/73402a41-fd6b-918d-c927-4e349db1f029.png)

# 2.対象アプリの詳細情報確認
1. PowerShellでPowerApps管理センターへ接続する。
   ```powershell
      Import-Module Microsoft.PowerApps.Administration.PowerShell
      Add-PowerAppsAccount
   ```
2. アプリの詳詳細情報一覧を出力する。
   ```powershell
      Get-AdminPowerApp
   ```
3. 以下の情報を控えておく。
    * AppName
    * EnvironmentName

# 3.アプリの所有者変更
1. PowerShellでPowerApps管理センターへ接続する。
   ```powershell
      Import-Module Microsoft.PowerApps.Administration.PowerShell
      Add-PowerAppsAccount
   ```
2. 以下のコマンドで所有を変更する。
   ```powershell
      Set-AdminPowerAppOwner -AppName "所有者を変更したいアプリの「AppName」" -EnvironmentName "所有者を変更したいアプリの「EnvironmentName」" -AppOwner "新所有者のObjectID"
   ```
3. Microsoft365管理センターから所有者が変更されていることを確認
Gitを使ってソースを管理する基本的な流れ

## ローカルリポジトリとリモートリポジトリ
Gitのファイル管理には、自分のPC内で管理する場所（ローカルリポジトリ）と、複数人が共有する場所（リモートリポジトリ）がある。
ローカルリポジトリで作成したファイルをリモートリポジトリにアップする。

| 種類 | 内容 | ツール | 
|:-----|:-----|:-----|
|ローカルリポジトリ   |自分のPC内でファイルの履歴を管理する場所|Git for Winows|
|リモートリポジトリ   |複数人でファイルの履歴を共有して管理する場所|GitHub<br>GitLab|


## Gitローカル内の構成
自分のPC内で管理するローカルリポジトリは、以下の構成となっている。

| 種類 | 内容 | 操作|
|:-----|:-----|:-----|
|ワークツリー   |   自分のPCでのファイルを変更する作業場|
| ステージ 　　 | コミットする変更を準備する場所　　　  | addコマンドであげる
|  ローカルリポジトリ | 自分のPC上での履歴データの置き場所<br>  | commitコマンドであげる


## ローカルリポジトリの作成
まず、自分のPC内でファイルを管理する領域（ローカルリポジトリ）を作成する。

+ プロジェクトのディレクトリに移動する。

+ 次のコマンドを実行する。
~~~
 git init
~~~

+ .git　ディレクトリが作成され、その中に各種ファイルが作成される。

## 変更をステージに追加
　新たに作成したファイル、または変更したファイルをGitに登録するには、まずステージに追加する。

+ 次のコマンドを実行すると、プロジェクト内で作成・変更されたファイルが、ステージに追加される。
~~~
 git add
~~~

## 変更をローカルリポジトリに記録
　次に、ステージからローカルリポジトリに変更を記録する。これがcommit。

+ 次のコマンドを実行する。
~~~
 git commit
~~~

+ コミット時、あらかじめ登録しておいたエディタが立ち上がるので、コミットのコメントを記入する。
（コメントの記入は必須）

  -mオプションで、コメントとともにコミットすることができる。

~~~
 git commit -m　”コメント”
~~~

コミットする際、ファイルの変更内容を確認したい場合は、-vオプションをつける。

~~~
 git commit -v　
~~~

## 現在の変更状況を確認

addまたはcommitされていない変更したファイルを確認することができる。
－addされていない・・ワークツリー上で変更されているが、ステージに登録していない。
－commitされていない・・・ステージには登録されているが、リポジトリに登録していない。

~~~
 git status
~~~

差分がない場合は、以下のように表示される。
~~~
On branch master
nothing to commit, working tree clean
~~~

ステージに追加されていない変更がある場合は、以下のように表示される。
~~~
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   index.html
~~~
リポジトリに追加されていない変更がある場合は、以下のように表示される。
~~~
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   index.html
~~~

## 変更差分を確認する

## EclipsでGitを利用する
　EclipseでGitを使うにはプラグイン「EGit」を導入する

　Eclipseから「ヘルプ」→「Install New Software…」を選択します

　リポジトリの追加で、以下の情報入力
　Name：Egit（任意の名称でOK）
ローケーション：http://download.eclipse.org/egit/updates

インストール可能なプラグインが表示されますので、全て選択して「次へ」ボタンをクリックします。
php artisan serveを使わずにブラウザでLaravelアプリを起動する

毎回`php artisan serve`を使用するのが面倒だったのでメモ

やること
- httpd.confの編集
- 権限の付与
- SELinuxの設定

参考サイト
https://engineers.weddingpark.co.jp/apache-403-forbidden/

## httpd.confの編集
`/etc/httpd/conf/httpd.conf`の以下の部分を編集
```httpd.conf

//編集
 LoadModule rewrite_module modules/mod_rewrite.so //コメントアウト解除　＆　rewrite_moduleの設定

//追記
<Directory "/var/www/html/作成したlaravelプロジェクト名/public" >
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>
```
Directoryに関しては`/var/www/html`を同様に編集にしてもOK

## 権限の付与
作成したlaravelアプリフォルダの下にある`storage`と`bootstrap/cache`への編集権限を与える
```/laravel/
$ chmod -R 777 storage/ //権限は適宜変更
$ chmod -R 777 bootstrap/cache/ //権限は適宜変更
```

## SELinuxの設定
SELinuxの状態確認
```
$ getenforce
Enforcing //有効になっている場合
Disabled //無効になっている場合
```

SELinuxを無効にする
```
$ sudo vi /etc/selinux/config
~
SELINUX=disabled //変更
```

最後にサーバーの再起動をして確認

URLは`http://IPアドレス/プロジェクト名/public`
例：`http://192.168.0.1/laravel/public`
Firebase Authenticationの操作

ドキュメントやネット記事を読んで、Firebase Authenticatioを操作するコードが違うと疑問を持ったあなたに送ります。
## そもそも
Firebase Authenticationへの操作は2種類あります。

### Firebase SDK 
- ログインしているユーザーに対しての操作を行う。
    - ログインしてから操作を行う
    - ログインしている自分のみ操作可能
- エンドユーザー向け
    - ユーザーサイト
## Firebase Admin SDK
- 管理者権限でそれぞれのユーザーに対して操作を行う。
    - 複数のユーザーに対して操作ができる
- 管理者向け
    - 管理サイト


## ユーザー情報取得方法
### Firebase SDK（ Web バージョン 9 ）
```
import { initializeApp } from 'firebase/app'
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth'

const firebaseConfig = {
  //...
}
const app = initializeApp(firebaseConfig)
const getUser =  async(email, password) => {
  const auth = getAuth()
  await signInWithEmailAndPassword(auth, email, password)
  .then((userCredential) => {
    console.log('ログイン成功')
  })
  .catch((error) => {
    console.log('ログイン失敗')
  })
  const user = auth.currentUser
  console.log(user)
  if (user !== null) {
    console.log(user)
  }
}
getUsers('該当のメールアドレス', '該当のパスワード')
```

### Firebase Admin SDK（v10）
```
import { initializeApp, cert } from 'firebase-admin/app'
import { getAuth } from 'firebase-admin/auth'

const serviceAccountKey = require('../serviceAccountKey.json')
initializeApp({
  credential: cert(serviceAccountKey)),
  databaseURL: '指定されたURL',
})

const getUser = async (uid) => {
  const auth = getAuth()
  await auth.getUser(uid)
　　　　.then((userRecord) => {
    console.log(userRecord)
  })
  .catch((error) => {
    console.log('Error fetching user data:', error)
  })
}
getUser('該当のuid')
```
初心者による初心者のためのSpringBoot

# 環境構築
Eclipseをダウンロード
以下のURLへアクセス
URL：https://mergedoc.osdn.jp/

- Eclipseの最新版を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676412/c105bb94-9ff3-5113-8646-fe1891266a71.png)

- JavaのFull Editionをdownload
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676412/27fffb92-4a87-2007-bcd4-905c8f9715aa.png)

あとは解凍してEclipseを起動してください

:::note info
これで環境構築は完了になります!!
Spring Tool Suite (STS)などはFull Editionにすでに入っているのでDownLoadは不要です。
:::

# HelloWordを表示しよう
## controllerを作成
- com.example.demoのパッケージを右クリック→新規(W)→パッケージ
　名前(M)：に「com.example.demo」→「com.example.demo.controller」に変更
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676412/60bfb5fd-c26d-d9f5-1962-b0a7fab040e7.png)

- 作成したパッケージを右クリック→新規(W)→クラス
　名前(M)：に「IndexController」を入力して完了(F)ボタンを押下する
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676412/0a928846-f48d-b42a-ad6e-ce84c4f9d702.png)

- IndexController.javaを修正
```
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;


@Controller
public class IndexController {
	@RequestMapping("/")
	public String open(Model model) {
	    String str = "Hello World";
	    model.addAttribute("value", str);
	    return "index";
	  }
}

```
## controllerの説明
:::note warn
以降の説明はあくまでざっくりと簡単な説明になります
詳細が気になる場合は自身でお調べください
:::
- 「@Controller」について
  - URLがたたかれた際に呼び出されるクラスであることを表します
- 「@RequestMapping」
  - 呼び出されるURLを指定します。
  - 今回の例の場合は「http://localhost:8080/」を実行するとopenメソッドが呼び出されます
  - 仮に```@RequestMapping("/index")```の場合は「```http://localhost:8080/index```」をたたく必要があります
- 「model.addAttribute("value", str);」
  - 表示したい値を変数にセットします。
  - 遷移先の「value」という変数に表示したい値をセットします。
- 「return "index";」について
  - returnに記載するものは遷移するhtmlファイル名を記載します
  - 遷移先の「index.html」はこの後作成します・
## viewを作成
- templatesのパッケージを右クリック→新規(W)→HTMLファイル
- 名前(M)に「index.html」を入力→完了(F)ボタンを押下する

- index.htmlを修正
```
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
  <h1 th:text="${value}"></h1>
</body>
</html>
```
# 実行
- 対象のプロジェクトを右クリックして実行(R)→9 Spring Boot アプリケーションを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676412/68635850-902f-4a43-298b-a3e2a8ae3f45.png)
- consoleに以下が表示されれば完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676412/d02d42fa-f7e1-e0bc-5936-6d151370c710.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2676412/9a74c436-f035-a476-0706-e97dc4aa1014.png)
【AWS】 ELB

# ELBとは？
Elastic Load Balancingのこと。
単一のEC2インスタンスのみでもスケールアップにより需要の拡大にある程度は対応可能。
ただし限界があるため、冗長化させることが必要となる。
以下図の左側のような状態だと、万一EC2が止まってしまった場合にサービス自体が停止してしまう。
このように「ある特定の部分が止まると全体が止まってしまう」箇所のことを単一障害点（Single Point Of Failure, SPOF）という。
設計する時には単一障害点をいかに作らないようにするかが大切となる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665477/4aaa7aba-2ac8-ac08-8e9b-26fce8cbdf76.png)

で、高負荷に耐えられるような設計にするにはどうしたら良いのだろうか？
図の右側のようにEC2インスタンスを並列に並べて、その上にロードバランサーを乗せる方法（スケールアウト）が一般的に取られる手法となる。
ロードバランサはBIG-IPといった製品を導入することも可能だが、ロードバランサのマネージドサービスであるElastic Load Balancing(ELB)を使用することが推奨されている。


## 1. Classic Load Balancer (CLB)
L4/L7レイヤーでの負荷分散を行う。

## 2. Application Load Balancer (ALB)
L7レイヤーでの負荷分散を行う。CLBよりも後に登場し、機能も豊富に提供されている。

## 3. Network Load Balancer (NLB)
L4レイヤーでの負荷分散をおkなう。HTTP以外のプロトコル通信の負荷分散をしたい時に利用する。


# レイヤーごとでload balancingするって何よ？？
レイヤー4とレイヤー7のロードバランシングの違い
>レイヤー4ロードバランシングは、中間のトランスポートレイヤーで動作します。このレイヤーは、メッセージの内容に関係なくメッセージのデリバリーを処理します。TCP（Transmission Control Protocol）は、インターネット上のHTTP（Hypertext Transfer Protocol）トラフィック向けのレイヤー4プロトコルです。レイヤー4のロードバランサーは、パケットの内容は検査せず、上流のサーバとの間で単純にネットワークパケットの転送を実行します。また、TCPストリームの最初の数パケットを検査し、限定的にルーティングを決定できます。
レイヤー7ロードバランシングは、さらに上位のアプリケーションレイヤーで動作します。このレイヤーでは、各メッセージの実際の内容が処理されます。HTTPは、インターネット上のWebサイトのトラフィックに使用される主要なレイヤー7プロトコルです。レイヤー7のロードバランサーは、レイヤー4のロードバランサーに比べて、はるかに高度な方法でネットワークトラフィックをルーティングします。特に、HTTPなどのTCPベースのトラフィックを対象とします。レイヤー7のロードバランサーは、ネットワークトラフィックを終端し、中のメッセージを読み取ります。メッセージの内容（URLやCookieなど）に基づいて、ロードバランシングの判断を行うことができます。続いて、選択した上流サーバに新しいTCP接続を実行（または、HTTPキープアライブによって既存の接続を再利用）して、サーバにリクエストを書き込みます。




レイヤー7ロードバランシングの一例
要はURLの中身を見て負荷分散を実行したりすることができる。

>トラフィックの多いWebサイトにユーザがアクセスするという簡単な例で考えてみましょう。セッション期間中に、ユーザは画像や動画などの静的コンテンツ、ニュースフィードなどの動的コンテンツや、注文状況などのトランザクション情報を要求する可能性があります。レイヤー7ロードバランサーは、どのようなコンテンツがリクエストされているかなど、リクエスト自体の情報に基づいてリクエストをルーティングできます。したがって、画像や動画のリクエストは、その画像や動画を格納するサーバにルーティングされ、マルチメディアコンテンツを提供するために高度に最適化されます。また、割引価格などのトランザクション情報のリクエストであれば、価格管理用アプリケーションサーバにルーティングされます。レイヤー7ロードバランシングにより、ネットワークやアプリケーションのアーキテクトは、高度に調整され最適化されたサーバインフラストラクチャを構築できます。または、信頼性が高く、需要に応じて効率的に拡張できる、アプリケーションデリバリーネットワークも構築できます。

https://www.nginx.co.jp/resources/glossary/layer-7-load-balancing/


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665477/4245a402-5739-2c18-a9e4-fee035534e57.png)
画像引用：[OSI参照モデルとTCP/IPの違いを比較](https://www.itmanage.co.jp/column/osi-reference-model/)


# Auto Scaling
利用状況に応じて自動的にインスタンスのスケールアウト/スケールインを実現するもの。
例：CPU使用率が80%を超えたら2台追加/CPU使用率が40%を割ったら2台減らす

# ヘルスチェック
ELBと対象サーバが正常に接続されているかを自動的に確認してくれる機能。ELBから各EC2にヘルスチェックリクエストたるものを送信し、正しいレスポンスが帰ってきたインスタンスは正常、そうでなければ異常な状態と見做される。このヘルスチェックを通過した正常なインスタンスのみELBに紐づくことになる。

ヘルスチェックの審査基準は設定することが可能。何回失敗したらELBから切り離すか/何回成功したらELBに紐付けるか。ヘルスチェックリクエストの間隔の設定も可能。
ELBの紐付きに時間がかかってサーバーが重くなる時は、ヘルスチェックの設定の見直しも有効。



# 参考
・[疎結合と単一障害点(Single Point Of Failure)について](https://toshioshimo.hatenablog.com/entry/2019/11/02/235318#:~:text=%E3%81%AF%E4%BD%95%E3%81%8B-,%E5%8D%98%E4%B8%80%E9%9A%9C%E5%AE%B3%E7%82%B9(Single%20Point%20Of%20Failure)%E3%81%A8%E3%81%AF,%E3%81%AB%E3%81%AF%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82)

https://www.ithack.info/aws-elb-helth/
Google Apps Script を使って自動化に挑戦

みなさんこんにちは、グリドンです。

しばらくブログを書いていなかっとのですが、今回はGoogle Apps Scriptを利用して、日々行なっている行動を自動化してみました。

# Google Apps Script とは
Google Apps Script の説明は下記のように公式のドキュメントに記載があります。

>"Google Apps Script is a rapid application development platform that makes it fast and easy to create business applications that integrate with Google Workspace."

https://developers.google.com/apps-script/overview

つまり、Google Workspaceを利用したビジネスアプリケーションを迅速にそして簡単に作成することができるプラットフォームだよ、ということです。Google WorkspaceはGmailやCalenderのようなGoogleの提供しているサービスのことです。

プログラミング言語はJavaScriptを使用します。ですので、JSを以前から利用している方は、すぐにコードを書き始めることができます。
環境構築なども行う必要がなくすぐ始められるところは、便利なポイントの一つだと思います。

# 何を自動化したのか

今回私が自動化した日々のルーティーンは下記。

海外にもうすぐ行くので、目標の貯金額はspreadsheetで管理しており、毎朝目標の貯金額を確認しています。

この目標の貯金額ですが、最近円安で毎日のように目標の貯金額が大きく変わります。ですので、毎日のようにこの金額を確かめる、という行動をおこなっています。

このルーティン、毎日確認しているとめんどくさくなって、自動にメールで通知できないかな〜と思ったのがきっかけで今回Google Apps Scriptで自動化に挑戦してみました。

# 実装内容

実際の実装方法などは公式ドキュメントをご覧になられる事をお勧めします。

作成する時ですが、利用したいspreadsheetのextensionsタブから、Apps Scriptを選ぶと、エディターページに飛びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764190/c84f022e-e06f-31bd-88e9-365005c216e4.png)


まずは下記のコードを記載して該当のspreadsheetを取得。
```
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getActiveSheet();
```

実際に作成する時に気ずくと思いますが、myFunctionというファンクションがすでに作成されています。
これがmainメソッドのように動作します。

```
function myFunction() {
  //ここにコードを書く
}
```

具体的なコードを載せてもあまり意味がないので、セルの値を取得するメソッドだけ
```
var range = sheet.getRange("ターゲットのセル（例：A1）");
var value = range.getValue();
```
valueに該当のセルの値が返ってきます。



Google Apps Scriptのすごいところは、このコードを時間を指定して呼び出すことができます。
左のメニューバーにtriggersという欄があります。そこで、add triggerをし、作成したメソッドを呼び出すように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764190/7e54b8da-f48c-6ab3-68da-3ffe7d4f8fc1.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764190/9d9e5b7a-81d0-aca8-c296-1255872bd980.png)

実行すると、こんな感じでメールが届きました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764190/11460b9e-b747-643c-9910-7d79d7caff29.png)

まだまだ目標貯金額まで先がながそう・・・w


以上。次は何を自動化させようかな〜
鑑行・鏡行（かがみぎょう）ってご存知ですか？


数年前です。
とあるシステム開発で、連携相手のシステム屋さんの設計で「鏡行」という言葉が出てきました。

「きょうぎょう」？
頭は疑問符だらけです。

一番キャリアのあるエンジニア（社長なんですけど）に聞いてみたところ、多分これじゃないかということで言われたのが、「かがみページ」と呼ばれるものでした。

経理の世界では当たり前？なんでしょうか。
長年ウェブのシステム屋やってて初めてしりました。
相手はフィールドは違うけど昔からシステムやっている人だったので、その世界では当たり前だったのでしょうか。

- [鏡（かがみ）｜経理用語解説 | みんなの仕事Lab-シゴ・ラボ-](https://lab.pasona.co.jp/accounting/word/301/)
- [請求書に添付する「かがみ」とはどういうもの？ | 経営者から担当者にまで役立つバックオフィス基礎知識 | クラウド会計ソフト freee](https://www.freee.co.jp/kb/kb-invoice/invoice-cover-letter/)

これが元になっているかどうかはわからないんですけどね。
実際どういうものだったかというと、データを1行1行記録していくのですが、区切りとなる要約・集計された行を鏡行（かがみぎょう、同じ読みで「鑑行」とも書く）というのだそうです。

ざっくり簡単な受注データで表すと以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131218/048b4c74-ca30-10ef-3cec-3b2c92d04139.png)


DBの正規化とかだと、私の場合はヘッダとボディ（デティール）と命名したりするんですけどね。
EC-CUBEだと`dtb_order`（注文）、`dtb_order_item`（注文商品の個別明細）ってなってますね。

- [EC-CUBE4開発リファレンス](http://ec4.umebius.com/)

事情を推察してみると、どうもファイルでデータ管理をしていた時代のシステムにありがち？な感じらしいとのことで、その名残ではないかとのことでした。
DBの正規形で言うと、どれに該当するんでしょうね。。。

DBで正規化してデータ管理するのが当たり前だと思っていた私は完全に面食らいました。
あまりにも当たり前のように資料に書いていたので。
ちなみにこのデータはDBで管理されていて、受注番号に当たる部分は別のテーブルで管理されていました。

馴染みがない言葉に誰に聞いてもわからないし、ウェブ検索しても出てこないしという状況だったのを思い出したので、ここで共有しようと思いました。
見る人が見たら、「あいつか」ってなりそうですが。プロフィール画像顔写真にしてるし。

という思い出話の共有です。
参考になればと思います。
jestでswcを使うようにしたらエラー文に出てくる行数と実際のソースの行数が合わなくなったので解消させた

日本語の記事が見つからなかったので投稿

## 概要

swcを使いだしてからエラー文のstackに出てくるソースコードの行数がずれる様になりました。
sourceMapは有効化しているはずなので何かがおかしいと思い調べてみました。

## 状況

- sourceMapは有効化している

```
{
  "sourceMaps": true
}
```

## 解決方法

```
{
  "sourceMaps": "inline"
}
```

## または（未検証）

```
{
  "sourceMaps": true,
  "inlineSourcesContent": true
}
```

## 参考

https://github.com/swc-project/swc/issues/1581
https://github.com/swc-project/swc/issues/2194
『スタンフォード ベクトル・行列からはじめる最適化数学』4章章末問題の解答

[スタンフォード ベクトル・行列からはじめる最適化数学](https://amzn.to/3LbI555)
<a href="https://www.amazon.co.jp/%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%95%E3%82%A9%E3%83%BC%E3%83%89-%E3%83%99%E3%82%AF%E3%83%88%E3%83%AB%E3%83%BB%E8%A1%8C%E5%88%97%E3%81%8B%E3%82%89%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E6%9C%80%E9%81%A9%E5%8C%96%E6%95%B0%E5%AD%A6-KS%E6%83%85%E5%A0%B1%E7%A7%91%E5%AD%A6%E5%B0%82%E9%96%80%E6%9B%B8-%E3%82%B9%E3%83%86%E3%83%95%E3%82%A1%E3%83%B3%E3%83%BB%E3%83%9C%E3%82%A4%E3%83%89/dp/4065161967?&linkCode=li2&tag=aokikenichi-22&linkId=ac095d386d0cfe3a604a7fe59e4dfefe&language=ja_JP&ref_=as_li_ss_il" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=4065161967&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=aokikenichi-22&language=ja_JP" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=aokikenichi-22&language=ja_JP&l=li2&o=9&a=4065161967" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />

の演習問題を解いているが解答が本書内にもネット上にもない模様。自分の解答を晒して間違いにツッコミをいただき理解を深めようという試み。

# 第4章

- 問4.1
    - (a)

```math
\begin{align} 
\rm{J}(z)&=\|x_1-z\|^2+\cdots+\|x_L-z\|^2\\
&=\Sigma_{i=1}^L{\|x_i-z\|^2}\\
&=\Sigma_{i=1}^L{\|x_i-\bar{x}-(z-\bar{x})\|^2}\\
&=\Sigma_{i=1}^L{(\|x_i-\bar{x}\|^2-2(x_i-\bar{x})^\top(z-\bar{x})+\|z-\bar{x}\|^2)}\\
&=\Sigma_{i=1}^L{(\|x_i-\bar{x}\|^2-2(x_i-\bar{x})^\top(z-\bar{x}))+L\|z-\bar{x}\|^2}
\end{align}
```

-    - (b)

```math 
\begin{align}
\Sigma_{i=1}^L{(x_i-\bar{x})^\top(z-\bar{x})}&=(\Sigma_{i=1}^L{(x_i-\bar{x}}))^\top(z-\bar{x})\\
\Sigma(x_i-\bar{x})&=0より与式は成り立つ
\end{align}
```

-    - (c)

```math 
\begin{align}
&(a), (b)より、\\
\rm{J}(z)&=\Sigma_{i=1}^L{\|x_i-\bar{x}\|^2}+L\|z-\bar{x}\|^2\\
&z\ne \bar{x}のとき\\
\rm{J}(z)&=\Sigma_{i=1}^L{\|x_i-\bar{x}\|^2}より\\
\rm{J}(z)&\gt\rm{J}(\bar{x})
\end{align}
```

- 問4.2
    - (a)
```math 
\|x_i-z_{c_i}\|\\
z_jが負であるとすると、\\
\|x_i-z_j\|よりも\|x_i-\mathbf{0}\|の方が小さくなるのでz_jが負であることは矛盾\\
よってz_jは非負
```

-   - (b)

```math 
\begin{align}
代表は&元のベクトルの平均であるので、\\
z_j&=\Sigma_{i=1}^N{\frac{x_i}{N}}\\
xを&j=1, \cdots, Mクラスに分けたとすると\\
\Sigma_{j=1}^M{z_j}&=\Sigma_{j=1}^M{(\Sigma_{i=1}^N{\frac{x_i}{N}})}\\
&=1\\
また、&(a)からz_jは非負。\\
よって、&z_jは要素が全て非負で、総和が１
\end{align}
```

-   - (c)

```math 
x_i=(0, 0, 1, 0, 1, 1, 0, \cdots)\\
jクラスの要素ベクトルのi番目の要素の平均値。（自信なし）
```

- 問4.3

```math 
\begin{align}
クラス1に属するベクトルをx_i\{i\in G_1\}\\
クラス２に属するベクトルをx_j\{j\in G_2\}とする。\\
\|x_i-z_1\|^2-\|x_i-z_2\|^2&\le0\\
\|x_j-z_1\|^2-\|x_j-z_2\|^2&\ge0\\
\|x_i\|^2-2z_ix_i+\|z\|^2-\|x_i\|^2+2z_2x_i-\|z\|^2&\le0\\
-2(z_1-z_2)x_i+\|z_1\|^2-\|z_2\|^2&\le0\\
同様に
-2(z_1-z_2)x_j+\|z_1\|^2-\|z_2\|^2&\ge0\\
2(z_1-z_2)&=w\\
-\|z_1\|^2+\|z_2\|^2&=vとおくと\\
w^\top x_i+v\ge0\\
w^\top x_j+v\le0\\
\end{align}
```

- 問4.4

```math 
例示を用いると、x_{27}をグループ５の代表ベクトルとする。\\
患者のn個の特徴から疾患が特定できるような場合。

```

----
- [『スタンフォード ベクトル・行列からはじめる最適化数学』3章章末問題の解答](https://qiita.com/aokikenichi/items/36c03a2a694feca7edf4)
- [『スタンフォード ベクトル・行列からはじめる最適化数学』5章章末問題の解答](https://qiita.com/aokikenichi/items/81a2d9685167ddf32dad)
C++お嬢様が足し算の語順を変えましたわ～

# 発端
こちらのお嬢様がとても楽しそうなことをしてらしたの
わたくしもご一緒したいですわ
https://twitter.com/yaito3014/status/1539110456753025025

# 背景
`a + b`や`a * b * c`を口に出しますと、「aとbの和」や「aとbとcの積」になるのが普通ですわ

ですので、最後の数を書いた後から四則を選べたなら、わたくしとても便利だと思っておりますの
執事に調べてもらったところ、計算式には日本語語順ライブラリがないようですので、
わたくしが１番ですわね（もしあったのでしたら申し訳ありませんわ）

関数で作るのはみなさまにお任せして、わたくしは演算子のオーバーロードで作りますわ
普段C++は使っておりませんので、ご容赦くださいまし

# コード
```C++:Kuso.h
#define 和 1
#define 差 2
#define 積 3
#define 商 4

int mode = 0;

class KusoClass {
private:
    double value;
public:
    KusoClass operator |(const auto n) const {
        // <<=より強い、2項間演算子
        // mode変更
        mode = n;
        return *this;
    }
    KusoClass operator <<=(const KusoClass right) const {
        // |より弱い、>>と同じか強い、右から左、2項間演算子
        // modeによる四則演算
        KusoClass tmp;
        switch (mode){
            case 和:
                tmp.set(this->value + right.get());
                break;
            case 差:
                tmp.set(this->value - right.get());
                break;
            case 積:
                tmp.set(this->value * right.get());
                break;
            case 商:
                tmp.set(this->value / right.get());
                break;
            default:
                tmp.set(this->value);
        }
        return tmp;
    }
    KusoClass operator ,(KusoClass * const right) const {
        // <<=と同じか弱い、左から右、2項間演算子
        // 左辺を右辺に代入
        right->set(this->value);
        return *this;
    }
    KusoClass(double x = 0) {this->value = x;}
    double get() const {return this->value;}
    void set(const double x) {this->value = x;}
};
```

```C++:Main.cpp
#include "Kuso.h"
#include <iostream>

/*
#define 様
#define に
#define を
#define 収めます
#define です
#define こちらは KusoClass
#define は .set(
#define ですの );
#define と <<=
#define の |
#define 合計 和
#define ひとまず , &
#define わ ;
#define こちらの auto
#define へ =
#define の結果 .get()
#define 画面に std::cout <<
#define をお見せします << std::endl
#define 数字の KusoClass)(
*/

int main(void){
    KusoClass x(2), y(3), z(4), a;
    x <<= y <<= z | 和, &a;
    std::cout << a.get() << std::endl;
    /*
    こちらは xx 様 です わ xx 様 は 2 ですの
    こちらは yy 様 です わ yy 様 は 3 ですの
    こちらは zz 様 です わ zz 様 は 4 ですの
    こちらは aa 様 です わ
    xx 様 と yy 様 と zz 様 の 合計 を ひとまず aa 様 に 収めます わ
    画面に aa 様 の結果 をお見せします わ
    */

    auto b = (x <<= y <<= z | 和).get();
    std::cout << b << std::endl;
    /*
    こちらの bb 様 へ (xx 様 と yy 様 と zz 様 の 合計)の結果 を 収めます わ
    画面に bb 様 をお見せします わ
    */

    std::cout << (KusoClass(2) <<= KusoClass(3) | 和).get() << std::endl;
    /*
    画面に((数字の 2)と(数字の 3)の 合計)の結果 をお見せします わ
    */

    return 0;
}
```

一度貼り付けたら、山ほど赤線が出ましたの。致し方ありませんわね
日本語文はコメントアウトしておきますわ

数式を右から計算しておりますわ。ですので、差と商は2値でしか使えませんわ
それと、日本語文の括弧は目をつぶってくださいましね

# 感想
オーバーロードを使ったのは、わたくしこれが初めてですの
C++はとても自由ですのね。わたくし気に入りましたわ

それと、「様」にコードを割り当てられませんでしたわ
プログラミングに敬称は要らないと言われているようで、少し哀しくなりましたわ

# 追記
「C++にはGCがありませんので、一時オブジェクトをnewで生成するのはお控えくださいませ」とのお声をいただきましたの
ご指摘大変感謝いたしますわ。次回作はdelete忘れに目をかけて投稿いたしますわ

ご指南いただけることで、わたくしの視点を増やす良き機会になりましたわ
定期的に異言語交流するのはよいものですわね
ブラウザで1行JSONをストリーミングする

ブラウザで1行JSONをストリーミングするライブラリを作ったので、紹介したいと思います。

## 使い方

このライブラリは https://deno.land/ から配信されているため、`https://deno.land/x/jsonlines@v1.2.1/js/mod.js`というURLをインポートするだけで使えます。

以下のような1行JSONがあったとします。

```json
{"id": 1, "data": ["xxxxx", "yyyyyyyy"]}
{"id": 2, "data": ["bbb", "aaaaaa"]}
...（以下無限に流れてくる）
```

これを1行ずつ読み取って、JSONとしてパースして順次読み込むには、以下のようにします。

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <script type="module">
      import { JSONLinesParseStream } from "https://deno.land/x/jsonlines@v1.2.1/js/mod.js";

      // ①サンプル用の1行JSONをfetch
      const { body } = await fetch("https://deno.land/x/jsonlines@v1.2.1/testdata/json-lines.jsonl");

      // ②pipeThroughで、ストリーミングされてくるデータを変換
      const readable = body
        .pipeThrough(new TextDecoderStream())
        .pipeThrough(new JSONLinesParseStream());

      // ③ for-await-of文でデータを読み出し
      for await (const data of readable) {
        console.log(data); // 変数dataの中にパース結果のJSONが入っている
      }
    </script>
  </head>
  <body></body>
</html>
```

使い方としては、

⓪ ライブラリをimport
① `fetch(url)`を使ってデータを読み込み
② `body.pipeThrough(変換関数)`でデータを変換（ここでJSONをパース）
③ `for-await-of`文を使ってデータを読み込み

という形になります。

## どうやって実装されているか

#### TransformStream

JavaScriptでデータをストリーミングする際は[Web Stream API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)を使用します。

`fetch()`の返り値なども、このWeb Stream APIに対応しています。

さて、Web Stream APIには**ストリーミングしている途中にデータを書き換えるTransformStream**というものがあります。今回は、TransformStreamをカスタムして任意の変換処理ができるようにしていきました。

```ts:（TypeScriptで実装）（雰囲気）
export class JSONLinesParseStream implements TransformStream<string, JSONValue> {
  readonly writable: WritableStream<string>;
  readonly readable: ReadableStream<JSONValue>;

  constructor(options: ParseStreamOptions = {}) {
    this.writable = ...;
    this.readable = ...;
  }
}
```

なお、このTransformStreamですが、**現時点ではFireFox非対応**です。

https://caniuse.com/mdn-api_transformstream

https://caniuse.com/mdn-api_readablestream_pipethrough

今後のバージョンでサポートが追加されるようなので、このライブラリが全モダンブラウザで使えるようになるのはちょっと先になりそうです。

余談ですが、最近Firefoxのサポートを切って話題になったサービスは動画系サービスが多いような気がします。ストリーミングAPIの対応状況の悪さがサポートを切る一因になったのではと邪推しているのですが……
Spring Boot＋Thymeleafでjs・cssのキャッシュを無効にする (2022年版)

# 1. 概要

Spring Bootでアプリケーションを開発している時に、css・jsファイルのキャッシュを無効にして、ブラウザをリロードするだけで確認をしやすくしたい場面があります。そういった時の設定方法を紹介します。

なお、今回の設定はSpring Boot 2.6で確認しています。

# 2. 設定内容

非常に簡単で、以下のプロパティを設定するだけで良いです。

``` application.properties
spring.web.resources.cache.cachecontrol.no-cache=false
```

``` application.yml
spring:
  web:
    resources:
      cache:
        cachecontrol:
          no-cache: false
```

# 3.　おまけ

Thymeleaf自体のキャッシュを無効にするには、以下のように設定します。

``` application.properties
spring.thymeleaf.cache=false
```

``` application.yml
spring:
  thymeleaf:
    cache: false
```

# 4. 参考

- [アプリケーションプロパティ設定一覧](https://spring.pleiades.io/spring-boot/docs/current/reference/html/application-properties.html)
【2022年】ログイン認証情報の不足でリジェクトされてから、Google Play Consoleで再審査提出まで

# はじめに
Google Play Consoleでどこをどう操作すれば良いのかわからんかったので、ここに記録します！

# ログイン認証情報の不足でリジェクト食らった
![Screen Shot 2022-06-25 at 13.24.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/78c4f715-9bc7-f2e6-a332-1d9e12b4cce1.png)

https://support.google.com/googleplay/android-developer/answer/9859455#app_access

**審査するためにログインが必要だが、ログインのための情報がないよ〜！！！**

みたいな理由です。

初回リリースというわけじゃないので、、、逆に今まではなぜ審査に通っていたのかが謎なんですがね、、、:joy_cat:
いつからログイン認証情報必要になったんや・・・？

# Google Play Consoleでログイン認証情報を追加
`アプリのコンテンツ＞アプリのアクセス権`
![Screen Shot 2022-06-24 at 20.38.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/900bbb97-29f1-4236-3ead-d87386d24344.png)

最初開いた状態では、👆のようにアクセス権なしで全てにアクセスできることになってます。
（元々ログインしないと全てにアクセスできないアプリやったんですがね・・:joy_cat:）

「全てまたは一部を制限」を選択し、ログインID（ユーザー名や電話番号、emialなど）とパスワードを入力して「適応」

![Screen Shot 2022-06-24 at 20.37.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/2d04f3b2-62b7-6dd8-899a-c90f03e5ef98.png)

# 再度審査に出す
![Screen Shot 2022-06-25 at 15.21.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/f7b1cbc4-74c0-b18d-5e81-f10a43f8d085.png)

リジェクトメールから「公開の概要」へ入る。

アプリを選択し「審査に送信」

![Screen Shot 2022-06-24 at 20.36.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/85ec74bb-a3d8-dcf6-d95d-4b4f65c5ebff.png)

これで再審査への提出は完了！
good luck:clap:
PHPのforeachで参照渡しを使った後は、unset()しておこう！


|[../](https://qiita.com/taconana/items/3f5424f9abfc755772c2) |
|---|

@tadsanさんの投稿「[PHPのリファレンス(参照&)の傾向と対策、あるいはさよなら](https://qiita.com/tadsan/items/74f992dcc48216b571bd)」の中に「foreachでの参照渡しは、unset()しないと危険である」との内容があったので、私も動作確認してみた。サンプルコードをより簡潔にして、やっと理解できた。
※PHP経験の長い方には、常識なのかもしれませんが、初心者には新鮮！

たとえば、
```php
$speach = ["おはよう", "ありがと", "さよなら"];
foreach ($speach as &$s) {
  echo $s, PHP_EOL;
}
foreach ($speach as $s) {
  echo $s, PHP_EOL;
}
var_dump($speach);
```
では、2つ目のforeachの実行時に、`$speach`の配列が["おはよう", "ありがと", "ありがと"]に壊れてしまうのだ。1つ目のforeachで壊れるのではなく、2つ目のforeachで壊れるのである。以下の結果になる。
```
おはよう
ありがと
さよなら
おはよう
ありがと
ありがと
array(3) {
  [0] =>
  string(12) "おはよう"
  [1] =>
  string(12) "ありがと"
  [2] =>
  string(12) "ありがと"
}
```
上記のコードは、以下のように展開されるそうだ。2つ目のforeachで同じ変数`$s`を使うと、`$s`に`&$speach[2]`（2番目の要素のアドレス）が残っていて、そのアドレスに対して値をセットしにいく。実際には、C言語のような直接的なアドレスではなく、参照のための構造体を介したアドレスになる。この現象は、foreachに限らず、同じブロックのスコープ内で、同じ変数名で参照渡しを使用すると起こりえることが分かる。
```php
$speach = ["おはよう", "ありがと", "さよなら"];
$s = &$speach[0];   // $sに&$speach[0]がセットされる
$s = &$speach[1];   // $sに&$speach[1]がセットされる
$s = &$speach[2];   // $sに&$speach[2]がセットされる

$s = $speach[0];    // &$speach[2]に0番目の要素「おはよう」がセット => ["おはよう", "ありがと", "おはよう"]
echo $s, PHP_EOL;   // 0番目の要素は「おはよう」
$s = $speach[1];    // &$speach[2]に1番目の要素「ありがと」がセット => ["おはよう", "ありがと", "ありがと"]
echo $s, PHP_EOL;   // 1番目の要素は「ありがと」
$s = $speach[2];    // &$speach[2]に2番目の要素「ありがと」がセット => ["おはよう", "ありがと", "ありがと"]
echo $s, PHP_EOL;   // 2番目の要素は「ありがと」
var_dump($speach);
```
`foreach ($speach as &$s)`や`foreach ($speach as $s)`の`$s`は、foreach のブロック内のローカル変数のように見えるが、そうではない。参照渡しにして、foreach のブロックを抜けた後で同じ変数名を使用すると、オリジナルの配列（例では`$speach`）を壊してしまう。通常、最後の要素を書き換えてしまう。使用には注意が必要である。

foreachで参照渡しにしたときは、foreachの直後にunset()しないと危険だ。これは徹底しないと確かにバグを生みそう。変数名を変えれば問題ないのだが、同じ変数名で使う可能性もある。unset()を徹底した方がよさそうだ。もちろん、不要な場面で参照渡しを使わないようにするのがいいのだが。

unset()は、以下の感じで入れておこう。
```php
$speach = ["おはよう", "ありがと", "さよなら"];
foreach ($speach as &$s) {
  echo $s, PHP_EOL;
}
unset($s); // foreachで参照渡しを使った場合、同じ変数名を使うと危険であるため
foreach ($speach as $s) {
  echo $s, PHP_EOL;
}
var_dump($speach);
```
理解のための、4つの要素でも復習しておこう。
```php
$speach = ["おはよう", "ありがと", "さよなら", "ごめんね"];
foreach ($speach as &$s) {
  echo $s, PHP_EOL;
}
foreach ($speach as $s) {
  echo $s, PHP_EOL;
}
var_dump($speach);
```
次のように展開される。
```php
$speach = ["おはよう", "ありがと", "さよなら", "ごめんね"];
$s = &$speach[0];   // $sに&$speach[0]がセットされる
$s = &$speach[1];   // $sに&$speach[1]がセットされる
$s = &$speach[2];   // $sに&$speach[2]がセットされる
$s = &$speach[3];   // $sに&$speach[3]がセットされる

$s = $speach[0];    // &$speach[3]に0番目の要素「おはよう」がセット => ["おはよう", "ありがと", "さよなら", "おはよう"]
echo $s, PHP_EOL;   // 0番目の要素は「おはよう」
$s = $speach[1];    // &$speach[3]に1番目の要素「ありがと」がセット => ["おはよう", "ありがと", "さよなら", "ありがと"]
echo $s, PHP_EOL;   // 1番目の要素は「ありがと」
$s = $speach[2];    // &$speach[3]に2番目の要素「さよなら」がセット => ["おはよう", "ありがと", "さよなら", "さよなら"]
echo $s, PHP_EOL;   // 2番目の要素は「さよなら」
$s = $speach[3];    // &$speach[3]に3番目の要素「さよなら」がセット => ["おはよう", "ありがと", "さよなら", "さよなら"]
echo $s, PHP_EOL;   // 3番目の要素は「さよなら」
var_dump($speach);
```

|[../](https://qiita.com/taconana/items/3f5424f9abfc755772c2) |
|---|
Kotlin1.7.0: 型引数のアンダースコア演算子﻿とは？

# はじめに
Kotlin1.7.0が6月7日にリリースされましたが、リリース内容の中に型引数にアンダースコア演算子が導入されたとの記載があります。
これについて理解を深めるために簡単にまとめておこうと思います。

# 型引数のアンダースコア演算子﻿とは？
公式には以下実装を例に解説が載っています。

```
abstract class SomeClass<T> {
    abstract fun execute(): T
}

class SomeImplementation : SomeClass<String>() {
    override fun execute(): String = "Test"
}

class OtherImplementation : SomeClass<Int>() {
    override fun execute(): Int = 42
}

object Runner {
    inline fun <reified S: SomeClass<T>, T> run(): T {
        return S::class.java.getDeclaredConstructor().newInstance().execute()
    }
}

fun main() {
    // TはSomeImplementationがSomeClass<String>から継承されているため、Stringと推論される
    val s = Runner.run<SomeImplementation, _>()
    assert(s == "Test")

    // TはOtherImplementationがSomeClass<Int>から継承されいているため、Intと推論される
    val n = Runner.run<OtherImplementation, _>()
    assert(n == 42)
}
```
アンダースコア演算子は、現状だと使ってない引数等に警告が出て、警告に則り修正すると、＿に変換されるアレですね。
それが今回の対応で少し便利になり、元の親クラスで指定されている型までちゃんと推測してくれるようになったようです。

推測してくれる点は便利だと感じましたが、そこまで利便性が跳ね上がるような対応ではない認識ですね。
ジェネリックを多用している汎用的な機能に関しては、多少便利かなといった印象です。

# さいごに
kotlinもアップデートを重ね、もう1.7なのですね。
言語も日々進化し続けているので、私も最新から遅れないよう、こういった新しい機能にはなるべく目を通しておこうと思います。
【ちょっとアレンジ】Spring bootのControllerクラスで定義したパスを一覧として取得する


## やりたいこと

APIの本数が増えてきたので、実装済みのAPIのURIの一覧を出力したい

→[Spring bootのControllerクラスで定義したパスを一覧として取得する](https://qiita.com/shigeshibu44/items/886efb44c8c573c3ba6b)の内容の踏襲でほぼいけたのですが、PJの実装ルール的に少し考慮が必要な部分があったので、その部分を書き記しておきます

## アレンジした部分

クラスに＠RequestMappingを付与して基幹部分のパスを、メソッドにリクエストメソッドに応じたアノテーションを付与して相対パスを定義するルールなので、以下2点実現できるように手を加えました。

* リクエストメソッドに応じたアノテーションからリクエストメソッドと相対パスを出力する
* クラスに定義された親パスとメソッドに定義された相対パスの関係性が分かるように出力する

```参考記事のControllerクラスをループする部分改変.java
        // 略
        for (BeanDefinition def : beanSet) {
            Class<?> clazz = Class.forName(def.getBeanClassName());
            RequestMapping requestMappingClazz = clazz.getAnnotation(RequestMapping.class);
            // Controllerクラスに設定されているパスを出力
            System.out.println(requestMappingClazz.value()[0]);
            // Controllerメソッドに設定されているパスを出力
            Arrays.stream(clazz.getDeclaredMethods()).forEach(a -> writeUri(a));
        }
        // 略
```
```Controllerメソッドに設定されているリクエストメソッドとパスを出力（詳細）.java
    private static void writeUri(Method method) {
        GetMapping getMapping = method.getAnnotation(GetMapping.class);
        if (Objects.nonNull(getMapping)) {
            writeValue("GET", getMapping.value());
        }
        PostMapping postMapping = method.getAnnotation(PostMapping.class);
        if (Objects.nonNull(postMapping)) {
            writeValue("POST", postMapping.value());
        }
        PutMapping putMapping = method.getAnnotation(PutMapping.class);
        if (Objects.nonNull(putMapping)) {
            writeValue("PUT", putMapping.value());
        }
        DeleteMapping deleteMapping = method.getAnnotation(DeleteMapping.class);
        if (Objects.nonNull(deleteMapping)) {
            writeValue("DELETE", deleteMapping.value());
        }
    }

    private static void writeValue(String methodType, String[] value) {
        System.out.println("\t" + methodType + "\t" + (value.length == 0 ? "/" : value[0]));
    }
```

（余談ですが、アノテーションのvalueってなんとなくStringと思い込んでいましたが、String配列でした。ひとつのクラス・メソッドに対して複数のパスをマッピングできるみたいですが、需要あります…？）

## 最後に

出力イメージはこんな感じです。超便利！

```
/hoge1/fuga1
    GET    /
    POST   /piyo1
/hoge2/fuga2
    PUT    /piyo2
    DELETE /piyo3
```

今回は質よりスピード重視だったので妥協してしまいましたが、
調べる中で、＠{リクエストメソッド}Mappingクラスは＠RequestMappingのエイリアス的な位置付けであることが分かりました。
＠AliasForあたりの詳細が解析出来たらwriteUri()に記載しているアノテーション毎の処理は共通化出来そうな気がしています。
（余力があったらチャレンジしてみます）

```GetMapping.java
package org.springframework.web.bind.annotation
// 略
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
// @RequestMappingのメソッドを指定
@RequestMapping(
    method = {RequestMethod.GET}
)
public @interface GetMapping {
    // @RequestMappingの同名設定値のエイリアスであることを示す？
    @AliasFor(
        annotation = RequestMapping.class
    )
    String name() default "";
    // 略
```
Jetpack Composeタップ領域にPaddingを含める方法・含めない方法

Jetpack Composeで描いていて、タップ領域にPaddingを含まれてなく、どうしたら含められるのかが、分かった為今後のために記載していきます。

# タップ領域にPaddingを含める方法

```MainActivity.kt
Row(Modifier.clickable(onClick = { isExpanded = !isExpanded })
            .padding(8.dp)
   )
```

# タップ領域にPaddingを含めない方法

```MainActivity.kt
Row(Modifier.padding(8.dp)
            .clickable(onClick = { isExpanded = !isExpanded })
   )
```

# 結論
Modifierの設定する順番が関係してました。
初めにクリック処理を設定すると、全体がクリック領域になるみたいです。なのでpaddingはレイアウトの見た目に反映され、クリック処理の領域には反映されない。

Modifierの設定する順番で動作が変わるのでそこを気をつけて実装していきたいですね。