OmniAICreator/Qiita-1.07M huggingface dataset:
[AWS Q&A 365][StepFunctions]Daily Five Common Questions #79

# 1. What are the error names mentioned in the AWS Step Functions Developer Guide? 
Answer: The error names mentioned in the guide are Retry, Timeout, Heartbeat Timeout, Task Failed, States Timeout, and States Runtime. 

# 2. How can you retry after an error in AWS Step Functions? 
Answer: AWS Step Functions allows you to retry after an error by configuring a retry field in the state machine definition. You can set the number of times to retry and the interval between each retry. 

# 3. What are fallback states in AWS Step Functions? 
Answer: Fallback states are states that are executed when an error occurs during the execution of a state machine. They are used to handle errors and perform recovery operations. 

# 4. How can you catch errors in AWS Step Functions? 
Answer: AWS Step Functions allows you to catch errors by configuring a catch field in the state machine definition. You can specify the error names to catch and the states to execute when an error occurs. 

# 5. What is the difference between Retry and Catch in AWS Step Functions? 
Answer: Retry is used to retry a state when it fails, while Catch is used to handle errors that occur during the execution of a state machine. Retry is configured in the state definition, while Catch is configured in the catch field of the state machine definition.
時系列データでAutoAIによる異常検出を行う

## 概要
IBM Cloud Pak for Data as a Service（CP4DaaS）のWatson Machine Learningには自動機械学習のサービスとしてAutoAIがありますが、少し前から時系列データにも対応していました。2023/6に新たに「異常検出」にも対応しました（2023/6現在、ベータ機能)ので、今回試してみてわかったことを記述します。
## マニュアル
日本語のマニュアルがありますが、翻訳したものなので実際の画面上の表記とマニュアルでの表記が違っていたり、一長一短あります。<br>https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/autoai-ts-ad.html
原文の英語で見たい場合は、URLの最後に **?locale=en** を付ければよいです。私は日本語のマニュアルを見た後で、個別に英語の方を見てやっと理解できたところがありました・・<br>https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/autoai-ts-ad.html?locale=en
## やってみた
上記のマニュアルを見ると、電力使用量の異常検出を題材としたサンプルデータが提供されていることがわかります。データをダウンロードしてWatson Studio内で可視化してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745658/e32b13df-2203-d86f-ee69-d48981d93ee7.png)
ふむふむ。どこが異常なのか、の教師ラベルは要らないのですね。トレンドなどからの異常をモデル化するようです。日本語よりも英語マニュアルの方がわかりやすかったので参考にすると、こんな感じです。

| 異常タイプ | 説明 | AutoAIでの画面表示* |
|---|---|---|
|局所的な異常 | 局所的に、周辺のデータポイントから激しく外れている | ローカライズされた極値 |
|レベルシフトの異常 | 一部分の平均値が外れている | レベル・シフト |
|トレンドの異常 | 一部分が、それよりも前の部分と比べて傾向が変わっている | トレンド |
|変動の異常 | 一部分が、変動の様子が変わっている | 分散 |

*これは、AutoAIでモデルをトレーニングしたときのモデル評価の画面表示に対応しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745658/1fb4e5f7-3722-2f63-8d81-20f8fd0e2db9.png)
さて、マニュアルの手順にしたがってAutoAIでの異常検出モデルはできましたが、これを使って異常の予測をしてみようとして気付きました。予測では、将来の日付における電力使用量を入力として、それが異常か、異常ではないかを出力するということに・・・将来の日付分にあたるデータがないので、いったんここまで。

## では済まないので
こちらの[記事](https://www.ibm.com/blogs/solutions/jp-ja/life-spss-09/)で投稿した「北京の交通量のオープンデータ」を流用して、交通量の異常を検証してみました。
### トレーニングデータ
上記の記事にも書かれている通り、2015/6~2018/7をトレーニング用、2018/8~2018/9をテスト用としました。データは記事から[リンク](https://github.com/hfujioka/shared/tree/master/%E6%99%82%E7%B3%BB%E5%88%97AutoAI/data)されているところから取得できます。
### AutoAIでのトレーニング
これまでと異なるのは、「異常の予測」を選ぶところのみ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745658/ac2ad7ab-8944-8465-9704-dad4aec89d6b.png)
予測する内容として、フィーチャー列（ターゲット列）としてtraffic_volume、日付/時刻列としてdateを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745658/342c5fc1-fe53-3608-da30-1fe97aeea8db.png)
さて、モデルができたらデプロイメント・スペースに送って、オンラインデプロイを起動する・・・このあたりは、[こちら](https://qiita.com/Asuka_Saito/items/814b17acb7f8357bdfab)の手順の通りです。
最後に、予測してみます。入力として必要なのは、後続する2018/8~2018/9のテストデータのうち、traffic_volume列のみを取り出したもの。これを「テスト」のタブから、「ローカルファイルの参照」でアップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745658/fc15fb37-fe15-155e-4598-879b9ffca995.png)
さて、予測結果はというと・・・1日だけ異常で、残りは正常と出ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745658/dc20c6ac-b141-8b97-4550-b6e882cd7367.png)
せっかくなので、これをグラフ化してみると・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745658/9716749e-608f-9b93-5abc-e42a9dde3078.png)
まあ、そりゃそうですよねという結果ではありました。
## まとめ
教師ラベルのない時系列データから、異常検出を行う機械学習をAutoAIの新機能を使って自動化することができました。
【初投稿】昨日解いた問題の解説

# 昨日解いた競プロの問題の解説/感想などを書いていきます
## 書いてる人について
atcoderで競技プログラミングをやっています。一年半くらいのキャリアです。青タッチも経験しましたが、現在は水コーダーです。

https://atcoder.jp/users/aplysia

## 解いた問題
https://atcoder.jp/contests/abc250/tasks/abc250_g

最近は背伸びして黄diff精進をやってます。

:::note warn
注意
以下この問題のネタバレを含みます。
:::

## 典型
* 計算量悪いdpを考えて高速化
* 実験エスパー

## 問題概要
株価の配列が与えらえる。__一日にたかだか単位株しか売買できないという制約のもとで__ 売買を最適に指定したときの利益の最大値を求める。O(n^2)ではだめ。


## 考えたこと
1.  ソートして順に処理する
    例えば一番高い時には、それより安い時がその前に一瞬でもあれば売るのが最適になる。こういうのをrange queryとして処理できないかを考えた。でも無理そう。
2. 計算量悪いdpを考える
__dp[i][j] = (i日目にj株持ってる時の損益の最大値)__
とすれば遷移は、 
__dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] - p[i], dp[i - 1][j + 1] + p[i])__
みたいになり、O(n^2)で解くことができる。これを高速化しようとしたけど無理。ここでgive up。

## 解法
考えたことの2が結構惜しくて、実はこの遷移を単純化することができる。
__階差数列に注目すると、__(←どうやって思いつくん笑)実は単調増加列になっており、毎回p[i]を二つinsertしたあと最少の要素を消すような遷移になっている。これはmultisetで実現できる。

## 学んだこと
こんなのどうやって思いつくのかわからないが、少なくとも階差数列に注目することさえ何とか思いつけば、実験エスパーは可能と思われる。めんどくさがらず実験エスパーをしよう。また、階差数列をとるみたいなのはダメもとで試してみるのが大事なのかな...

## 感想
未来予知できるなら一日に複数株売買してもよくない？

## 提出コード
https://atcoder.jp/contests/abc250/submissions/42263358

マクロ部分が多くて申し訳ない...

## 最後に
記事を書くの初めてなので、何か意見や要望があればお知らせください。
ではでは
EC2上のRHEL8にWordPressを構築する

# WordPressの構築が完了した後
トップページのURLまでのルートの変更が必要でした。

## Document Rootの設定
```/etc/httpd/conf/httpd.conf
/etc/www/html を /etc/www/html/wp に変更
```

## テーマファイルを配置しようとしたらエラーになる
今回はswellのテーマを使用しました。
swellを配置するのにzipファイルをアップロードすると
**php.iniの限界を超えています**的なメッセージが出ました。

### エラー処置
```php.ini
memory_limit = 128M
post_max_size = 128M
upload_max_filesize = 100M
```
``systemctl restart httpd``
``systemctl restart php-fpm``

### 結果

無事にテーマファイルのアップロードが完了しました。

## その他
+ サーバIPアドレス/wp-admin/でWordpressログインページが表示される


## まとめ
初めてAWS EC2でRHEL8上にWordPressのwebサイトを構築しました。
引き続き勉強を進めていきます。
生産性を上げるプルリクエスト分割！の前にやるべきこと

# 生産性を上げるプルリクエスト分割！の前にやるべきこと

先日弊チームのメンバー@d510が[開発生産性 Meetup #1】開発生産性可視化による変化~事例LTから学ぶベストプラクティス~](https://findy.connpass.com/event/279894/)にて登壇発表した内容の裏側について書きます。
（発表スライドは[コチラ](https://speakerdeck.com/daiki510/yamerarenai-tomaranai-pururikuesutofen-ge)）

「生産性を上げる手段として注目されているプルリクエスト分割取り組みたいけど、すぐできるものなの？まず何からしたらいいの？」について僕らが実際に行ったことについて説明できれば、と。

## 目次

- コーディング規約
- CI/CDの整備
- 設計の共通認識
- Gitのルール

## コーディング規約

弊チームではTypeScriptを利用していますが、そのコーディング規約として[Google TypeScript Style Guide](https://google.github.io/styleguide/tsguide.html)を元に若干のアレンジを加えて設定しました。

アレンジした内容は命名規則が中心で、
`xxx.service.ts`や`xxx.utils.ts`などのファイル名周りや、
混在しやすい`fetchXxx`,`getXxx`,`extractXxx`などのメソッド/関数名の統一など、です。

また、修正が早くなれば、ソースコードとコメントの不一致が起こる可能性も高くなるため、
コメントは原則JSDocのみにするようにしました。

「そもそもコメントを書かないと理解できないって仕様・設計から見直したほうがいいサインなんじゃない？」という話もありました。
とはいえ、どうしても書きたいシチュエーションがあるので、全くコメントがないわけではないですが、、、。

```typescript:JSDocサンプル
/**
 * リクエスト
 * @see https://docs.google.com/spreadsheets/xxx
 * @template T - リクエストボディの型
 * @template R - レスポンスの型
 * @param {string} uri - URI
 * @param {T} body - リクエストボディ
 * @param {object | undefined} config? - リクエストコンフィグ
 * @throws {ApiError} APIエラー
 * @returns {Promise<R>} レスポンス
 */
async request<T, R>(uri: string, body: T, config?: object): Promise<R> {
  // 略
}
```

## CI/CDの整備

プルリクエスト分割により生産性が上がったとしても、デグレや不具合を起こしては身も蓋もありません。
各プルリクエストでビルドやテストがしっかり通るのか自動で確認できるように整備しました。デプロイに関しても然り。

ただ、利用しているCIサービスによってはアクション数や実行時間の上限の設定がされている場合があると思います。
実際我々もGitHubActionsの実行時間が爆増してしまいました。

どの程度のジョブ数・実行時間になるのかを観測しながら、状況に応じて実行時間の最適化やジョブの並列化、あるいはそもそもこのブランチで実行すべきジョブなのか、などなど対策を検討するといいと思います。

```yml:特定ディレクトリ配下の変更時のみ実行サンプル(GitHubActions)
on:
  workflow_dispatch:
  pull_request:
    branches:
      - develop
    paths:
      - 'src/deploy/**'
# 略
```

参考：[GitHub Actionsの課金について](https://docs.github.com/ja/billing/managing-billing-for-github-actions/about-billing-for-github-actions)

## 設計の共通認識

実装時はもちろんレビュー時の迷いを減らすために、どのクラスには何の責務を持たせるべきか、という共通認識を取りました。（実際には議論し続けているものにはなりますが）

指摘をする/される際にも「この処理は○○という意味だからxxxに持たせるべきじゃない？」と根拠のあるコメントをすることができるため、個人的には、上述のコーディング規約も合わさって、レビューが非常にスムーズになったと感じています。

また、設計の認識が深まれば深まるほど、どの粒度でプルリクエストを分割するかの悩みも解決するのではないかと思います。
「Xという機能を実装するには、クラスAに処理追加して、クラスBのメソッド直して・・・」と分けて考えられるようになります。

## Gitのルール

プルリクエストを分割した分コミット履歴が膨らむのは容易に想定しうるかと思います。
その分、何かしらの不具合が発生した際に問題点の特定/切り分けが難しくなります。

この対応策として、我々は"1プルリクエスト1コミット"のルールを設定しました。
コミット自体を制限するわけではなく、プルリクエスト作成前に`git rebase -i hash値`を用いてコミットを一つにまとめようということです。

また、上記のルールとは別に、コミットメッセージも`[チケットID]内容`で統一を行いました。

参考：[サル先生のGit入門：5. rebase -i でコミットをまとめる](https://backlog.com/ja/git-tutorial/stepup/32/)

## 最後に

いずれもプルリクエスト分割に限らず活かせるものがあると思います。
プルリクエスト分割を始めようと思っている方々だけでなく、生産性をあげたいと思っている方々に何かしら得られるものがあれば幸いです。
また、「こんなアクションやるといいですよー」などのアイデアがありましたら教えていただけると嬉しいです！
Windows Admin Center サーバー証明書更新する

# Windows Admin Center サーバー証明書更新される方へ
サーバー証明書のみを更新するだけでなく、再度Windowws Admin Center(以下WAC)に明示的に更新したサーバー証明書を指定する必要があります。

# コンパネのインストール一覧からまさかの変更！？
スタートメニューやすべてのプログラム一覧からWACを探したのですが、一向にみつりません、、ネットで情報収集してみるとなんとコントロールパネルにある「プログラムのアンインストール」画面より変更メニューを出せるとのことでした、、そりゃ見つからないわけです😭
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320647/58235465-05e1-06fc-b2d4-f02f6e41771b.png)

# 新しいサーバー証明書の拇印を指定
コンピュータの証明書ストア（certlm.msc）より新しいサーバー証明書を開き
拇印をコピーして以下項目にペーストでOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320647/6f34b06e-1ae5-4887-9c76-05ad8011331e.png)

これまで通りWebコンソールにアクセスできるようになりました🤗
(リンクだけです)数学入試問題を掲載している。おすすめ網羅系?サイト(大学入試、高校入試)

おすすめ中学入試サイトを教えて下さい。

# 「大学入試数学問題集成」様サイト
https://mathexamtest.web.fc2.com/index.html
＞問題掲載大学一覧MathJax
https://mathexamtest.web.fc2.com/daigakubetumj/index.html
＞大学入試数学問題集成掲示板
https://mathexamtest.bbs.fc2.com/

# 「数学苦手な中学生応援します」様サイト
＞全国公立全問PDFあり
http://homepage1.canvas.ne.jp/ynaka/index.html#top
＞(姉妹ページ)数学得意な中学生応援します 様 ポータル(発展問題・難問題あり)
http://ynaka.html.xdomain.jp/
ViTにCNNをたくさん組み込んだモデル【CMT】






**原論文**
CMT: Convolutional Neural Networks Meet Vision Transformers
https://arxiv.org/abs/2107.06263

**日本語解説**
ViTとCNNを組み合わて精度と速度を向上させたCMTを詳細解説！
https://deepsquare.jp/2021/07/cmt/

# 関連研究

Vison Transformerの解説
https://qiita.com/wakanomi/items/55bba80338615c7cce73

CNN+ViTモデルの傾向【サーベイ】
https://qiita.com/wakayama_90b/items/96bf5d32b09cb0041c39



# 結論
ViTにCNNアーキテクチャをたくさん組み込んで，局所的な認識と計算量の削減の補助をする．

# 概要
ViTの問題点として，局所的な認識が苦手である問題点がある．物体検出やセグメンテーションタスクでは，物体の細かな認識を必要としているため，ViTをそれらのタスクに応用するには，局所的な認識を補助する構造を組み込む必要がある．そこで，局所的な認識が得意な畳み込み（LPU）を組み込んで，畳み込みとSAを交互に行い精度向上を期待する．また，FNNを畳み込みに置き換える．さらに，計算量削減のために，キーとバリューをダウンサンプリングする．また，FNNを畳み込みに置き換える．




# モデル構造
CMTは4ステージの階層型モデル構造を採用する．初めの処理として，パッチ特徴量変換で畳み込み層を採用し，畳み込み層の出力をViTの入力としている．これにより，ViTの苦手な局所的な認識の補助をする．また，ここの畳み込み層で特徴量をダウンサンプリングすることでViTの計算量を削減する．
CMT Block内の処理には以下の3つの処理が組み込まれており，特徴抽出を行う．

- 局所的な空間認識（Local Perception Unit）
- 大局的な空間認識（Lightweight Multi-head Self-attention）
- チャンネル方向の認識（Inverted Residual Feed-forward Network）

![スクリーンショット 2023-06-15 17.34.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/f0de5c74-6745-89f0-0adf-5bb14f72b798.png)







## Local Perception Unit（LPU）
ViTの問題点として，局所的な認識が苦手である．それは，パッチに分割してパッチ間の類似度計算（SA）を行うので，パッチ内の認識ができないことにある．局所的な認識を補助するために，畳み込み層をSAの前に追加する．これによって，局所的な認識の畳み込みと，大局的な認識のSAを交互に処理することによって性能向上を目指す．Local Perception UnitにはDWConv（Depthwise Separable Convolution）とスキップ接続で構成されている．DWConvは空間方向の畳み込み．


~~~math
LPU(x) = DWConv（x） + x
~~~

## Lightweight Multi-head Self-attention（LMSA）
ViTの問題点として，計算量が膨大なことがある．これを解決するために，キーとバリューをダウンサンプリングする．ダウンサンプリング方法にDWConvを採用する．（他モデルでも同じようにダウンサンプリングする手法がある．畳み込みの他に線形射影や，プーリングを使用している場合もある．）また，位置情報を保存する，相対的位置バイアス（B）を追加する．



クエリ，キー，バリューの変換（キー，バリューはダウンサンプリング）
~~~math

Q = xW_q \\
K=DWConv(x)W_k \\
V=DWConv(x)W_v 

~~~

ダウンサンプリングされたSA（LMS）の計算
~~~math

LMSA(Q,K,V) = softmax(\frac{QK^T}{\sqrt{d}}+B)V

~~~





## Inverted Residual Feed-forward Network（IRFFN）
ViTは通常，FNNにMLPが採用されていた．


~~~math

MLP(x) = GELU(XW_1 + b_1)XW_2 + b_2

~~~

IRFFNは3x3DWConvを1x1Convに挟まれるような構造である．また，スキップ接続の位置を変更している．

~~~math

IRFFN(x) = Conv(F(Conv(x))) \\
F(x) = DWConv(x) + x

~~~



![スクリーンショット 2023-06-15 17.34.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/903fe873-0513-ba54-5799-063590d6eab0.png)



# 実験結果

画像分類，物体検出，セグメンテーションで良い結果．

![スクリーンショット 2023-06-15 17.34.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/3883e39e-96e7-2f02-536c-f01e54ce6045.png)



# 考察
ViTにCNNアーキテクチャを組み込む派生モデルは多くあり，CMTは組み込める場所のほぼ全てに組み込んでいる．畳み込みとSAを交互に特徴抽出することは良い傾向である．
ViTの構造に畳み込みを入れすぎても大丈夫なんだなと感じました．



# まとめ
今回は，ViTにCNNをたくさん組み込んだモデル【CMT】について解説した．ViTにたくさん畳み込みを組み込むと性能が向上することが分かった．
【Pytorch】便利なやつら

# はじめに

Pytorchで知らない関数があったので備忘録として残します。

# 拡散モデルでよくつかうやつら
## torch.cumprod

$y=x_1\times x_2\times\cdots x_N$

```python
>> import torch
>> a = torch.tensor([1,2,3])
>> torch.cumprod(a,dim=0)
tensor([1,2,6])
```

https://pytorch.org/docs/stable/generated/torch.cumprod.html

## self.register_buffer

パラメータ$a$は最適化されるが、パラメータ$b$は固定される。

```python
import torch

class MyModule(nn.Module):
    def __init__(self):
        super().__init__()
        self.a = nn.Parameter(torch.randn(10))
        self.register_buffer('b', torch.randn(10))

    def forward(self, x):
        return self.a*x + b
```

## torch.clamp

```python
>> import torch
>> a = torch.randn(4)
>> a
tensor([-1.7120,  0.1734, -0.0478, -0.0922])
>> torch.clamp(a, min=-0.5, max=0.5)
tensor([-0.5000,  0.1734, -0.0478, -0.0922])
```

https://pytorch.org/docs/stable/generated/torch.clamp.html

## torch.rand_like

```python
>> import torch
>> noise = torch.randn_like(x)
```

https://pytorch.org/docs/stable/generated/torch.randn_like.html

## torch.from_numpy

```python
>> import torch
>> import numpy as np
>> a = np.array([1, 2, 3])
>> t = torch.from_numpy(a).float()
tensor([1.,2.,3.])
```

https://pytorch.org/docs/stable/generated/torch.from_numpy.html

## ニューラルネットワークのパラメータの更新

```python
def soft_update_from_to(source, target, tau):
    for target_param, param in zip(target.parameters(), source.parameters()):
        target_param.data.copy_(
            target_param.data * (1.0 - tau) + param.data * tau
        )
```
line-bot-sdk-goのv7.14で追加されたFlexMessageの動画コンポーネントのインポート方法

## TL;DR

2023年6月15日時点では、`go get github.com/line/line-bot-sdk-go`を実行すると、7.8がモジュールの管理対象になる。
v7.14でサポートされたFlex Messageの動画コンポーネントを使用するには、最新のモジュールをgetしてきて、import方法を変更する。

```bash
# go get github.com/line/line-bot-sdk-go/v7/linebot

go get github.com/line/line-bot-sdk-go/v7@7.14
#or
go get github.com/line/line-bot-sdk-go/v7@latest
```

```diff_go:line.go
import (
- "github.com/line/line-bot-sdk-go/linebot"
+ "github.com/line/line-bot-sdk-go/v7/linebot"
)
```

## Ver7.14でFlex Message V3に対応した!!

FlexMessageの動画メッセージを作成している時のこと。
画像コンポーネントのFlexMessageはできたので、同じように作成できるだろと思って作っていると`FlexComponentTypeVideo`が存在しないと言われた。

対応してないのかな〜と思っていると、2023年3月にv7.14が出ていて、そこでサポートされたと記載されていました。(ライブラリをぽちぽち使ってる身として、サポートしていただけることに頭が上がりません...)

https://github.com/line/line-bot-sdk-go/releases/tag/v7.14.0

が、go.modで管理されているのは7.8まででどうすれば良いのだろうと調査した結果、上記の対応で行けました。

## 実際の実装

Messaging APIのドキュメントにもありますが、FlexMessageの動画コンポーネントには色々制約があるので注意が必要です。

抜粋すると

> * 再生可能なファイルであることかつ、範囲リクエストができること
> * アスペクト比がプレビューと一致しない場合、予期せぬレイアウトになること
> * 動画コンポーネントを使うには、以下の条件をすべて満たす必要があります。
>   * 動画コンポーネントをヒーローのブロック直下に指定する
>   * バブルのsizeプロパティに`kilo` `mega` `giga`のいずれかを指定する
>   * バブルがカルーセルの子要素ではない

以下、ドキュメントです。

https://developers.line.biz/ja/reference/messaging-api/#f-video

```go:line.go
package line

import(
    "github.com/line/line-bot-sdk-go/v7/linebot"
)

func NewFlexVideoMessage(videoUrl string, previewUrl string) linebot.SendingMessage {
return linebot.NewFlexMessage(
			"Video Flex Message",
			&linebot.BubbleContainer{
				Type: linebot.FlexContainerTypeBubble,
				Size: linebot.FlexBubbleSizeTypeMega,
				Hero: &linebot.VideoComponent{
					Type:        linebot.FlexComponentTypeVideo,
					URL:         videoUrl,
					PreviewURL:  previewUrl,
					AspectRatio: linebot.FlexVideoAspectRatioType1to1,
                    AltContent: &linebot.ImageComponent{
						Type:        linebot.FlexComponentTypeImage,
						URL:         preview,
						Size:        linebot.FlexImageSizeTypeFull,
						AspectRatio: linebot.FlexImageAspectRatioType1to1,
					},
				},
			},
		)
}
```

## 後書き

こちらの記事の中でも書かれていますが、JSON -> FlexContainerに変換できる関数が実装されていますので簡単な実装であれば、JSONをぶん投げてもらうのもありかもしれません。

https://engineering.linecorp.com/ja/blog/flex-message-line-bot-sdk-go

ライブラリを作成していただいる方々には頭が上がりません :bow:
プロになるためのWeb技術入門を読んで

# プロになるためのWeb技術入門

[プロになるためのweb技術入門](https://www.amazon.co.jp/dp/4774142352)を読んだのでアウトプットしていきます。


#### ステートフル
ログイン状態などの状態を持つもの。
サーバーが以前のリクエストを記録することで、それを踏まえたリクエストを実行できる。

#### ステートレス
リクエストやレスポンスなど、クライアントとサーバーが通信するときの手順やデータ形式にはルールがある。このルールはHTTPという。HTTPに則った通信には、ステートレス性という性質がある。ステートレス性とは、サーバーがクライアントの状態を保持しないという性質のこと。
#### リクエスト
サーバーとクライアントとの情報のやり取りは、クライアントの要求を元にサーバーが応答するという流れになっている。クライアントの要求を リクエスト(request)という。



#### レスポンス
サーバーの応答をレスポンス(response)という。カフェに例えると、クライアントがお客さんでサーバーが店員さん。お客さんが注文して、店員さんが対応する流れと同じイメージ。

#### クッキー
クライアント、サーバー間で情報を保持する仕組み。
必要に応じてサーバーがクライアントからクッキーを取得することでクライアントの状態を確認する。通信するサーバーごとにクッキーが存在する。
#### プロトコル
インターネットには様々な種類のコンピューターが繋がっている。WebサーバーとWebクライアントが通信を行うには、どのように情報をやり取りするかという取り決めが必要。この取り決めを、「通信プロトコル（Communications　protocol)」と呼ぶ。主に「情報の伝達方法」と「情報の意味づけ」を規定する。
#### ポート番号
どのプログラムに通信するかを示した番号。よく使われているプロトコルには共通のポート番号が割り振られている。

# 終わりに
Progateで一通り学習を終えた後だったので、各用語は割とすんなりと理解することができました。この本では何年先も通じるWebアプリケーションの基礎技術を網羅できるので、これからも学習前や時間がある時に繰り返し読んだりアウトプットしていき、基礎的な知識をつけていきたいです。
networkxの頂点を一様に配置する関数

Pythonのネットワーク計算用パッケージnetworkxのグラフの頂点を一様に配置する関数を作りました。以下の図のように各頂点が互いに重ならないような配置が出てきます。

![uniform_layout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2787764/a8055a4c-44f8-01d7-d3b2-b6650bb86507.png)

比較用にバネモデルの場合を載せます。パラメータkで多少は調節出来ますが限界があります。
![spring_layout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2787764/4759bd08-5400-e248-4c76-60b36540610d.png)

以下が最小限のソースコードです。
```python3
import numpy as np
import networkx as nx
from scipy.cluster.hierarchy import distance

def uniform_layout(G, alpha=0.1, n_iter=None, seed=None, **kwargs):
  pos = nx.spring_layout(G, seed=seed, **kwargs)
  X = np.array(list(pos.values()))
  if n_iter == None:
    n_iter = 10 * len(G)
  for _ in range(n_iter):
    D = distance.squareform(distance.pdist(X))
    np.fill_diagonal(D, None)
    X += alpha * (X - X[np.nanargmin(D, axis=0)])
    X = X.clip(-1,1)
  return dict(zip(pos.keys(), X))
```

Gistに説明付きバージョンも置きました。
https://gist.github.com/okumakito/3c0f8166a99e6b617dca2c5556a6ebfa

使い方は他のnetowrkxのレイアウト関数と同様です。
```
>>> pos = uniform_layout(G)
>>> nx.draw_networkx(G, pos=pos)
```

## 円形バージョン (2024/04/28追記)

描画領域を正方形でなく円形にしたバージョンも用意しました。上記の最小限のコードで
```
X = X.clip(-1,1)
```
の部分を以下に変えるだけです。
```
X = (X.T / np.linalg.norm(X,axis=1).clip(1,None)).T
```
Gist版の方はオプションで切り替えられるようにしました。
```
>>> pos = uniform_layout(G, circle=True)
>>> nx.draw_networkx(G, pos=pos)
```

見た目は以下のようになります。

![tmp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2787764/2934390a-8846-a1bb-d3db-f04e70861790.png)
なぜ26歳男性は、結婚直後に実務未経験で完全自社内受託のWeb開発企業に転職したのか

こんにちは！Tomaです。

2023年6月から
私は完全受託のWeb開発企業に転職しています。

私のこれまでのキャリアは
ーーーーーーーーーーーーーーーーーーーーーー
・法人営業1年（テレ・対面、無形・有形）
・ネットワークエンジニア3年（PM、要件定義）
ーーーーーーーーーーーーーーーーーーーーーー
と、比較的顧客折衝をするポジションでの
仕事が多かったです。

そんな中で、今回フロントエンドエンジニアとして
UI/UXの部門に特化する部署に身を置くことにしました。



まず、なぜウェブ開発企業への就職
ひいてはフロントエンドエンジニアを目指したか
というところについてお話ししています。

理由は３つです。
ーーーーーーーーーーーーーーーーーーーーーー
①場所や時間を選ばずに仕事できる（可能性がある）
②会社員、フリーランス、副業、独立など
　様々な手段をとることができる
③顕在的・潜在的ニーズが高い
ーーーーーーーーーーーーーーーーーーーーーー


①【場所や時間を選ばずに仕事できる（可能性がある）】

これについては
エンジニアを志す人であれば
誰もが一度は憧れたことだと思います。

そして何よりも私が感じていたことは
現代はVUCAと呼ばれる予測不可能な時代で
どうすれば生き残ることができるか
すごく考えていました。

考えた中で最も最悪のシナリオは
「もしかしたら、経済が悪化して
日本で将来、仕事ができなくなるかもしれない」
というものでした。

そして行き着いた結論が
IT業界に身を置き、エンジニアになることでした。

ITは、もはや現代で必要不可欠なツール・概念の
一つになっていると思います。

加えて、開発ともなれば
コーディングで基本的に英語を使用するので
最低英語ができればどうにかなる
という汎用性の高さも考えました。


こうして、VUCA時代に生き残るには
少なくともITの経験や知識があれば
手法や手段は変わるかもしれないが
軸のブレは少ないと考え、エンジニアを目指しました。

そして最初にIT業界で踏み入れた領域が
NWエンジニアだった、というわけです。

元々、フロントエンドエンジニアを目指していましたが
遠い将来においては、少し遠回りした方が
最終的には近道になると考えて、NWエンジニアになりました。


そして、この約１年間で経験した
引っ越しや結婚のタイミングで
NWエンジニアとしてのキャリアUPではなく
フロントエンドエンジニアへの
キャリアチェンジを選択しました。

その理由は、コロナ禍でテレワークが推奨されたが
コロナ解禁後に徐々に出社の頻度が増えていったこと
そして少ない頻度ではあったものの
日中以外の時間帯での仕事を強いられることがあったため
結婚後に子どもを育てるということを考えると
NWエンジニアとしての未来は明るくないな
と感じたことが要因です。



②【会社員、フリーランス、副業、独立など様々な手段をとることができる】

世の中には色々な職種がありますが
ーーーーーーーーーーーーーーーーーーーーーー
・場所や時間に支配されず
・かつスキルさえあれば
・会社員でもフリーランスでもいい
・副業でもいいし独立もできる
ーーーーーーーーーーーーーーーーーーーーーー
そんな贅沢な職業を考えましたが
私にはエンジニアくらいしか想像できませんでした。

さらにWebエンジニアともなると
基本的には結果主義というか成果主義というか
最悪ものさえできていれば
いつ働いても、どこで働いてもいい
という働き方がある雰囲気を感じたため
もうこれしかないと思いました。

インフラエンジニア（私の場合はNWエンジニア）の場合
商用回線等に影響を及ぼさないように
利用者の稼動が少ない平日日中帯以外の時間帯で
仕事をすることが多かったので
この部分は特に大きな違いだったのかなと思います。

加えてやっぱり魅力的なのが
スキルがつけば個人でも仕事を請け負える
稼ぎ口や収入が増やせる可能性がある
というところです。

NWエンジニアでそれを叶えようとすると
スキルがあっても割と若いうちは足元を見られてしまい
請け負えないことが多いみたいです。

こういった稼ぎ方の可動性を考えても
Webエンジニアになることのメリットは大きいと思いました。



③【顕在的・潜在的ニーズが高い】

Webエンジニアの中でも
なぜフロントエンドエンジニア（UI/UX）
という職種を選んだのかについて、お話しします。

結論「人は見た目を重視する生き物だから」です。

例えば異性と付き合うシーンにおいても
内面や性格が大事と表面的には言いつつも
やっぱり心のどこかでは「外見の良さ」を
放っておくことはできないと思います。

服や食事のメニューなどを選ぶ時も
見た目が可愛いとかシックとか
最初の印象が良くなければ
素材がどうとか、は水性がどうとか
オーガニックを使っているかとか
そういう選び方はしていないはずです。

つまり、それほど見た目が与える影響は
大きいわけです。


これはエンジニアリングおいても同様だと考え
見えないバックエンドやクラウドではなく
フロントその中でもUI/UXという職種を選びました。

※
UI／UXは、利用者の体験による満足度や
ストレスを感じなさせない点において、
またサービス提供側の目線としては
離脱率を下げるという点で重要になります。


私が持っている志は
ーーーーーーーーーーーーーーーーーーーーーー
世の中にあるまだそれほど日を浴びていない
素晴らしい商品やサービスを
フロントエンドエンジニアリングの技術で
少しでも世の中に触れる機会を増やすこと
ーーーーーーーーーーーーーーーーーーーーーー
です。

いわゆる「ニッチ」なものを
いかに多くの人に知ってもらい
商品・サービスを使用・利用してもらうか
これが私の中で目指している
将来の私の姿です。


この考え方は、世界で日本が戦っていくためには
という考え方や戦略においても大きく役立つと思います。

ーーーーーーーーーーーーーーーーーーーーーー
人口では中国に敵うはずもなく
EUのような広い経済圏があるわけでもなく
アメリカのような最新技術に明るいわけでもない
東南アジアのような成長率があるわけでもなく
アフリカのようにビジネスニーズがあるわけでもない
ーーーーーーーーーーーーーーーーーーーーーー

そんな日本が世界で戦っていくためには
「日本にはこんなにいいものがある」
というのを世界に知ってもらう他ないと思います。

その上で大事なことが
「アレンジによってさらに質を高めていくこと」
だと思っています。

日本が極東の小さな島国であるにもかかわらず
GDPが世界3位と未だTOP３にいられるのは
この「アレンジ力の高さ」だと私は感じています。

例えば料理、日本で食べる食事を
外国の方々のほとんどが美味しいと言ってくれますね。

その美味しいという感想は
例えばインド人が日本でインド料理を食べても言いますし
中国人に中華料理を振る舞っても言ってくれます。

つまりモノやサービスのカテゴリーは同じでも
日本というフィルターを通すことによって
少し違った、しかしながらより良い質となって
再度世界に行き渡ることは、歴史的にも多いように思います。


少し話がずれましたが
見た目の重要性が今後増す中で
もちろんそのモノの本質も高い必要がある
ということが伝わっていれば嬉しいです。
日米の1人当たりGDPの長期時系列（Maddison project）

# はじめに
Maddison Project Database 2020を使って、日米の1人当たりGDPの長期時系列のグラフを実数スケールと対数スケールで描いてみることにした。
Maddison Project Database自体は、countrycode，country，year,gdppc（1人当たりGDP）、pop（人口）だけのデータなので、Excelファイルのまま処理しても大したことはないが、とりあえずプログラムにしてみた。

# データ
Maddison Project Database 2020のExcelデータ（ 'https://www.rug.nl/ggdc/historicaldevelopment/maddison/data/mpd2020.xlsx' ）をダウンロードして、人口データが継続して得られている年からのデータを利用した（アメリカの場合1820年以降、日本の場合1885年以降）。

# コード
```Python
import pandas as pd
import matplotlib.pyplot as plt

# Excelファイルの読み込み
df = pd.read_excel('https://www.rug.nl/ggdc/historicaldevelopment/maddison/data/mpd2020.xlsx', sheet_name='Full data')

def plot_gdp_per_capita(df, country_codes, start_year):
    plt.figure(figsize=(10, 5))

    for country_code in country_codes:
        # 指定した国のデータのみをフィルタ
        country_data = df[df['countrycode'] == country_code]

        # 指定した年以降のデータに限定
        country_data = country_data[country_data['year'] >= start_year]
        
        # 終了年を取得
        end_year = country_data['year'].max()

        # グラフを描画（実数で表示）
        plt.plot(country_data['year'], country_data['gdppc'], label=country_code)

    plt.title(f'GDP per capita ({start_year}-{end_year})')
    plt.xlabel('Year')
    plt.ylabel('GDP per capita (real scale)')
    plt.legend()
    plt.grid(True)
    plt.show()

    plt.figure(figsize=(10, 5))

    for country_code in country_codes:
        # 指定した国のデータのみをフィルタ
        country_data = df[df['countrycode'] == country_code]

        # 指定した年以降のデータに限定
        country_data = country_data[country_data['year'] >= start_year]

        # グラフを描画（対数目盛で表示）
        plt.plot(country_data['year'], country_data['gdppc'], label=country_code)

    plt.yscale('log')
    plt.title(f'GDP per capita ({start_year}-{end_year})')
    plt.xlabel('Year')
    plt.ylabel('GDP per capita (log scale)')
    plt.yticks([500, 2500, 12500, 62500], ['500', '2500', '12500', '62500'])
    plt.legend()
    plt.grid(True)
    plt.show()

# アメリカと日本の1820年以降のデータを表示
plot_gdp_per_capita(df, ['USA', 'JPN'], 1820)
```
# 出力
* 実数スケール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3305624/9b8f7f1b-1b29-1c66-730f-168044ef4bfd.png)


* 対数スケール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3305624/5f7f52cd-1314-3809-0fa0-288d93f47e94.png)

# 改善点
対数スケールのグラフの目盛りを自動化したかったが、自動化するとあまりいい表示にならなかったので、米国データに合わせて今回は手動入力。他の国について描く場合を想定するとよくないが、10^4だけしか表示されないのでは面白くなかったので、今回はこれで諦めた。
BigQuery: 値を生成する関数を利用して適当なデータを作成する

中身はどうでもいいデータを好きな行数だけほしいという事がありました。
値を生成する関数を利用して、指定した行数分データを作成する SQL を作成したので置いておきます。
from 句のコメントを切り替え、GENERATE 関数の引数を変更する事で、数値、日付、Timestamp を基準に任意の行数のデータを作成できます。

```
select
n as array_value,
ROW_NUMBER() OVER () as ROW_NUMBER,
GENERATE_UUID() as GENERATE_UUID,
RAND() as RAND,
SHA512(CAST(n as string)) as SHA512,
FARM_FINGERPRINT(GENERATE_UUID()) as FARM_FINGERPRINT,
CODE_POINTS_TO_BYTES(GENERATE_ARRAY(33,126,CAST(RAND()*10+1 as INT64))) as CODE_POINTS_TO_BYTES,
CODE_POINTS_TO_STRING(GENERATE_ARRAY(33,126,CAST(RAND()*10+1 as INT64))) as CODE_POINTS_TO_STRING,
DATE_ADD(CURRENT_DATE('Asia/Tokyo'), INTERVAL CAST(RAND()*10 as INT64) DAY) as DATE_ADD,
-- from UNNEST(GENERATE_TIMESTAMP_ARRAY('2020-06-01 00:00:01', '2020-06-01 00:00:03', INTERVAL 1 SECOND)) as n
-- from UNNEST(GENERATE_DATE_ARRAY('2020-06-01', '2020-06-03', INTERVAL 1 DAY)) as n
from UNNEST(GENERATE_ARRAY(1, 3)) as n
```
Z世代がよく使っている絵文字、おじさんが使ってるEmojiの共通点と考察。‼️ ❗️ ⁉️ ❓ ❤️ 💦 😅 😁 😀❤️‍🔥 💗 🤍 🫶 ♡ ✌️  🧸😈🍓🍒👶🏻🍼  🥳 😚 🤭 🥰

# おじさんが使いがちなEmoji

‼️ ❗️ ⁉️ ❓ ❤️

💦 

😅 😁 😀

Youtuber、テレビ、記事によると、

* **現実のおじさんを連想させるもの**
    歯が見えている絵文字はキモいので冷める
    汗をかいている絵文字は不快

* **ガラケー時代の原色表現を連想させるもの**
    真っ赤
    真っ黄色

さらに、

* **絵文字を文章の代替えとして利用する行為**
    Z世代は絵文字を、飾りや映えとして使うことが多いため、絵文字自体に強烈な意味を持たせない方が良い。
    女性のネイルと同じなのかも。

# Z世代がよく使う絵文字

❤️‍🔥 💗 🤍 🫶 ♡ ✌️

🧸😈🍓🍒👶🏻🍼

🥳 😚 🤭 🥰

iPhoneでの表示の時、映えてるものが多い印象。

日韓の Instagram、TikTok、などで調べた。欧州はまた違うと思う。

# 後書き
ターゲットに合わせた絵文字を使おう。
AWS Cloud9作成時のエラー（Cloud9 could not connect to the EC2 instance）

# 問題事象
AWSマネジメントコンソールでCloud9を作成後、少し待った後にエラーメッセージが表示される

エラーメッセージ
Cloud9 could not connect to the EC2 instance. Please check your VPC configuration and network settings to troubleshoot the issue. CloudFormation に移動

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741587/c30c1bdb-a9a1-8a3c-7074-6f5881dfe67d.png)

※エラーメッセージリンク先のCloudFormationに飛んでも正常に作成されているように見えるので原因がわからない


# 原因
パブリックIPの自動割り当てが「いいえ」になっている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741587/5da41112-a754-a42f-8234-ef5a6a984bf9.png)

AWS Cloud9構築におけるVPC要件：[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/vpc-settings.html)


# 対応
パブリックサブネットに作成する場合は、サブネット設定の「パブリックIPv4アドレスを自動割り当て」を「はい」に変更する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741587/2443084b-c337-7ce9-8113-c1d799fad91b.png)
-default-character-setを指定してと言われたら【WindowsでMySQL】

# どういうこと？
情報工学の学生である私が、とある企業様からデータを頂き、MySQL内にデータをコピーする必要がありました。

「エラーが出たら、-default-character-set=utf8を指定してください」
とは書いてあるものの、それってどこで設定すればいいの？？


その企業様のデータを使ってる学生さんはきっと多くいるので、未来の学生さん達がより円滑に作業を進められるといいなと思い執筆しました。

# 結論
Windowsの場合は、```my.ini```、Macの場合は```my.cnf```を編集する。

# my.iniの場所
```C:\ProgramData\MySQL\MySQL Server 8.0\```の中にファイルがあり、そちらを編集しました。


ファイルの置き場所はCドライブの直下でもいいみたいです。

# 参考になったサイト
https://www.javadrive.jp/mysql/myini/index5.html
正規化と標準化

## ITエンジニアになりたいなって思ったので、とり合えずブログに書いてみようと始めます。

## 正規化、標準化をしらべたきっかけ
MNISTの手書き文字認識のモデルを作っていて、ピクセルのデータを255で割っているのを見てなんでやろって思って調べてみた

## 画像のデータをなんで正規化するのか
正直あんまわからんかった

一言でいうとデータが扱いやすくなる

学習コストを下げてくれるらしい。。
勾配の伝播にも有効なのだとか


## その他特徴量が複数あることきの正規化、標準化
これはわかった！
例えば、身長と体重をインプットとするモデルを作るとき、
そのままの値を入れると、それぞれの特徴量の範囲や大きさが異なるので、
一方の特徴量の影響が大きくなったりする
これだと、身長がでかいからその影響が大きくなる

### 正規化、標準化のやり方
正規化
最大値で割る

デメリットとして、外れ値でバカでかい値とかがあると、データが狂う

標準化
分散１、平均０となるようにする
→ー１～１の間に約７割のデータがあるようにする

とりま標準化しとけば安パイ
最大値が決まっているような、画像データとかは正規化が使われる
【Ruby】配列から偶数だけ抽出して新たな配列を作る方法は？


学習の備忘録として残します。:pray:


## 方法①Rubyコード
```ruby
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = numbers.select { |num| num.even? }
puts even_numbers
```

## 出力結果
```
[2, 4, 6, 8, 10]
```

上記のコードでは、
`select`メソッドを使用して配列から偶数だけを抽出。
selectメソッドは、ブロック内の条件式が真になる要素だけを含む新しい配列を返す。
　　　↓
条件式`num.even?`は、要素が偶数かどうかを判定するために使用。
選択された偶数だけの配列が生成され、それを今回はeven_numbersに代入。
　　　↓
even_numbersを出力。

## 方法② Ruby コード
```ruby
array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
array.filter { |n| n.even? }
```

## 出力結果
```
[2, 4, 6, 8, 10]
```
CloudfrontとWAFを組み合わせたIP制限の落とし穴


## 概要

シングルページアプリケーションのホスティング先として Cloudfront + S3 を選択した場合、WAFでのIP制限に意図しない落とし穴があるので共有

![9692f346dc5ebc9be0ce6332096ee286.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141487/8078878b-c058-4ab4-7d2a-ea7b349a87ce.png)

---

## Cloudfrontのカスタムレスポンスによるシングルページアプリケーションの実装

シングルページアプリケーションのルーティングは仮想的なページ遷移なので、例えば `/users` などのURLでアクセスされた時、そのURLのhtmlファイルがないため `403 Forbidden` になる

[参考](https://shiimanblog.com/engineering/s3-cloudfront-spa-waf/#toc3)

それを回避するため、Cloudfrontのカスタムレスポンス設定で `403 Forbidden` の場合に `200 OK` で `/` にリダイレクトさせる設定をしてシングルページアプリケーションを実現できる

[参考](https://shiimanblog.com/engineering/s3-cloudfront-spa-waf/#toc4)

---

## IP制限のためにWAFをCloudfrontにアタッチした時の問題

CloudfrontにIP制限をかけたい場合、WAFを利用して制限できる

が、今回のカスタムレスポンス設定により、WAFでブロックされている(ログにもブロックされたと出る)ものの、アプリケーションのhtmlが見れる結果になる

[参考](https://shiimanblog.com/engineering/s3-cloudfront-spa-waf/#toc6)

これは、WAFがブロックした後のレスポンスをCloudfrontのカスタムレスポンスが評価され、`200 OK` で `/` にリダイレクトされたため

---

## 解決方法としてWAFのカスタムレスポンスを設定

サポートで定時された対処法としては、Cloudfrontのカスタムレスポンス設定を変更してとのことでしたが、これではシングルページアプリケーションを構築できないことになる

AWSサポートの方に共有されたドキュメントを読んだところ、

https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/cloudfront-features.html#cloudfront-features-custom-error-pages
> AWS WAF ルールを使用してカスタマイズした応答は、CloudFront カスタムエラーページで定義した応答の仕様よりも優先されます。

の記載があり、WAFのブロック時のカスタムレスポンス設定でstauts: 403と適当なbodyを設定したところ、ステータスを403のままそのWAFのカスタムレスポンスが返り、CloudFront 側のカスタムエラーレスポンスを変更せずに想定している挙動になった

---

## Cloudfront+WAFのカスタムレスポンス評価順

CloudfrontとWAF、両方にカスタムレスポンス設定があり、その時々の設定により評価順が異なる

AWSサポートに問い合わせて確認したCloudfront+WAFのカスタムレスポンス評価順が以下

1. WAFのブロック時のカスタムレスポンス設定 (Cloudfrontに接続したオリジンを通ることなくWAFのカスタムレスポンスを返す)
2. Cloudfrontのカスタムレスポンス設定 (今回の例のようにエラーコードとレスポンスパス設定によってはCloudfrontに接続したオリジンにアクセスされる可能性がある)
3. 上記どちらも一致しない場合 WAFのデフォルトメッセージ403 Forbidden


---

## まとめ

- WAFで制限しログでもブロックを確認できても後続の設定(Cloudfrontなど紐づけるリソース)によっては安心はできない
- WAFがCloudfrontより前でブロックしてくれている認識は危ない

![9692f346dc5ebc9be0ce6332096ee286.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141487/8078878b-c058-4ab4-7d2a-ea7b349a87ce.png)


---

## その他プロジェクトによっては残る問題

- Cloudfrontは社内限定やIPを制限したサービスにはメリットは薄い
- WAFによるCloudfrontのIP制限はルールによってクリティカル
- CloudfrontとALBに別々のドメインをつける必要がある
- CloudfrontにバックエンドとしてALBを紐づけた場合、APIの403 Forbiddenもカスタムレスポンスに吸われる
- CloudfrontからALBのアクセスはインターネット経由であり、セキュリティグループで制限できない
  - 参考 https://dev.classmethod.jp/articles/setalb_access_to_be_allowed_only_from_cloudfront/
  - マネージドプレフィックスを利用して、ALBの直接アクセスを禁止、Cloudfrontからのみに制限する
  - 上記では別のCloudfrontからALBにアクセスはできるので、カスタムヘッダで制限する
  - 上記でもセキュリティ的にはIP制限より弱い
今更GitHub

個人開発でGit，いらんくない？と思っていたけど，TSUBAMEとかとのやりとりがめんどくさすぎたのでGitHubを通じて同期することが閣議決定しました．

以下，すでにgitアカウントがある前提

# リモートリポジトリを作る
github上で Create a new repositoryを押してぽちぽちしてくだけ
git@github.comから始まるURLをコピーしておく


# すでに存在するローカル①上のディレクトリをローカルリポジトリに昇華
```
cd github上で運用していきたいディレクトリ
git init
git remote add origin git@github.com:hoge/fuga　　（←さっきコピーしたやつ）
git branch -M main
git add .
git commit -m "first commit"
```

# ローカル②とリモートリポジトリを同期する
```
mkdir hoge　　（←同期させたい場所を作る）
cd hoge
git init

## ここはすでに設定してある人はいらない．設定済みかどうかは"git config user.name"とか"git config user.email"とか打った時にちゃんとなんか出てくるかどうかで見分ければok
# git config --global user.name "多分GitHubアカウントのユーザ名"
# git config --global user.email "多分GitHubアカウントのメールアドレス"
# git config --global credential.helper store

git remote add origin git@github.com:hoge/fuga　　（←さっきコピーしたやつ）
git pull origin main

```

ここまでくるとユーザ名とパスワードが求められる．
ユーザ名はそのままでいいが，パスワードというのがAuth token?みたいなやつなので，持ってない場合は発行が必要
[この記事](https://note.kiriukun.com/entry/20210904-github-password-authentication-was-removed)を参考に取得してコピーして貼り付ければちゃんとpullできる
【rails】お気に入り機能一覧作成

※※自分用メモ※※

お気に入り機能を`favoritsコントローラー`で作成した為、`favoritesコントローラー`の`showアクション`で作成予定。
⇒`usersコントローラー`での作成に変更。

しかし、`usersコントローラー`の`showアクション`はもうユーザーのプロフィールページで使用中なので、
`usersコントローラー`に`favoritesアクション`を作成して、ネストを定義

# ①ルーティング


~~~route.rb
  resources :users, only: [:show] do
    get :favorites, on: :member
  end
~~~

これで、`/users/:id/favorites`のルーティングを設定することができる。

# ②コントローラー
~~~users_controller.rb
   def favorites
      @user = User.find(params[:id])
      @favorites = current_user.favorites
    end
~~~
`User.find(params[:id])`でユーザーidの取得⇒@userに代入
`current_user.favorites`でログイン中のユーザーのお気に入りを取得⇒@favoritesに代入


# ③HTML
~~~favorites.html.erb
<% @favorites.each do |favorite| %>
    <p>投稿者:<%= favorite.user.name %></p>
    <p><%= image_tag favorite.photo.image.url if favorite.photo.image.present? %></p>
    <p><%= favorite.photo.content %></p>
    
<% end %>
~~~
②で取得した値をeach文を使い、表示させる。
`<p><%= image_tag favorite.photo.image.url if favorite.photo.image.present? %></p>`
`if favorite.photo.image.present?`でif文にすることでもし画像があればという条件分岐を行える。
「Command PhaseScriptExecution failed with a nonzero exit code」と遭遇した時にPodfileに書くアレの正しい書き方

以下の参考記事

##### 【Xcode】ビルド時に「Command PhaseScriptExecution failed with a nonzero exit code」エラーが発生する
https://cpoint-lab.co.jp/article/202203/22239/

の

上記を追加したら、次に Podfile に下記を追加します。
```
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
    end
  end
end
```

を読んでいて疑問に思いました。

```
post_install do |installer|
```
は
```
target 'プロジェクト名' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!
  
  # Pods for VocaBuilNikki
  pod 'ライブラリ名'
  
end
```
の「end」の「中に」書くのか？　それとも、　「外に」書くのか？

先輩エンジニアの方に聞いて疑問を解決したのですが結論、「外に」書くようです。
下に「誤った書き方」と「正しい書き方」の両方を記載しておきます。

# 誤った書き方
```
# Uncomment the next line to define a global platform for your project
platform :ios, '13.0'

target 'VocaBuilNikki' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!
  
  # Pods for VocaBuilNikki
  pod 'Firebase'
  pod 'Firebase/Firestore'
  pod 'Firebase/Auth'
  pod 'EMAlertController'
  
  post_install do |installer|
    installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        if `uname -m`.strip == 'arm64'
          config.build_settings['EXCLUDED_ARCHS'] = ''
        else
          config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
        end
      end
    end
  end
  
end
```

# 正しい書き方
```
# Uncomment the next line to define a global platform for your project
platform :ios, '13.0'

target 'VocaBuilNikki' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!
  
  # Pods for VocaBuilNikki
  pod 'Firebase'
  pod 'Firebase/Firestore'
  pod 'Firebase/Auth'
  pod 'EMAlertController'
  
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      if `uname -m`.strip == 'arm64'
        config.build_settings['EXCLUDED_ARCHS'] = ''
      else
        config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
      end
    end
  end
end
```
私の数値計算遍歴

## なぜこの記事を書いたか？
Twitterのタイムラインに数値計算云々という話が流れており，Twitterでお気持ち表明しても意味ないので文章に残そうと思った．

## 自己紹介
学年：博士課程１年の大学院生
専攻：物理学（素粒子・ハドロンの基礎理論）

## 遍歴
あくまで個人遍歴の紹介であることを念頭に置いて読んでください．こうすればよいとかこうするべきとかそういう意図の記事ではないです．

* __学部１年__
    １年の後期，理論系の先生(A先生と呼びます)の部屋に突撃し「数値計算したいです．何かないですか？」と頼みに行きました．このとき2+1次元の偏微分方程式を解く数値計算コードを譲ってもらい「自分でいじってみな」と言われました．これをきっかけにC言語＋数値計算の勉強を始めました．この時点では，数値計算の経験はゼロです．
* __学部２年__
    学部の講義と並行してA先生からもらったコードをいじって計算してました．また，講義でルンゲクッタ法とかを学びはじめたので，いろんな方程式を片っ端から数値的に解いて遊んでいました（いろんな力による古典運動方程式，惑星の運動方程式，拡散方程式，移流拡散方程式，レーンエムデン方程式，etc.）．
* __学部３年__
    A先生からもらったコードを自分で改良していろいろ試していました．並行して数値積分（Simpson法），非線形最適化手法（Levenberg-Marqardt法）をC言語で実装して遊んでいました．
* __学部４年__
    卒業研究はA先生の研究室に進みました．コロナが始まったので研究室の活動もなく，家で「Numerical Recipes in C」を片っ端から実装して遊んでいました．このときに数値的な高速フーリエ変換とかも勉強しました．
* __修士１年__
    外部の院に進み，心機一転，新しい言語（Julia言語）を勉強し始めました．研究テーマ的にモンテカルロ法を扱う必要があったのでこちらも勉強しました．このときMCMCの勉強を始めました．現在はそれを使って数値シミュレーションをしてます．
* __修士２年__
    特に新しい計算手法に手を出していませんが，読みやすいコードの書き方などを書籍を読んで勉強しました．大学院の講義でPythonを使った機械学習をかじりました．
* __博士１年（現在）__
    現在は修士のときに書いたシミュレーションコードで得られた計算結果の解析をしています．
    

## 数値計算を始めるにあたり重要だと思うこと
振り返ってみて，数値計算を学んでいくにあたり重要と思うのは以下の点です．
1. __一番最初のハードルをいかして下げるか__
1. __小さい目標を自分で設定してクリアしていけるか__
1. __困ったときに相談できる存在がいるか__


1.をなすハードルは「数値計算を実際に行うパソコン環境の構築」と「数値計算を行う言語に対する知識」という２つの要因に分けられます．前者は自分の周りで数値計算をやっている人を頼ることで解決できる可能性が高いです．後者は初歩の初歩のような入門書を買って「読む」のではなく「実際にコードを書く」ことで解決できるように思います．

2.ですが，初めから「超大型スパコンでガンガン格子QCDシミュレーション回すぞ！！！」なんて意気込んでいたら挫折するに決まってます（これができるような天才はブラウザバックしてもらって，，，）．古典力学の運動方程式，量子力学の１次元シュレーディンガー方程式，２次元の拡散方程式，など簡単な問題を解いて達成感を得ることが重要です．数値計算の習得はこの積み重ねだと思います．小さい問題を設定し，それを積み重ねるのが良いと自分は思います．

3.はどのような物事を修得する場合でも重要です．数値計算においてももちろん重要です．研究室の先輩などに気軽に聞ける人がいればよいですが，Twitterに適当に質問しても誰かが返してくれると思います．ただ，この質問をするときに，自分は~~がしたくて，~~のように考えて，~~という実装をしたが，~~という結果になっていて困っている，というレベルで具体的に質問する方が，的確な回答をもらえる可能性が高いです．

## まとめ
見ての通り自分はかなり長い時間を数値計算に費やしてきました．数値計算はパッと始めちゃうのがよいと思います．困ったときは誰かを頼ればいいし，誰かが助けてくれます． 

何か質問や困りごとがあったとき，連絡いただければ力になれるかもしれません．人は頼りましょう．
NCMBの管理画面をGoogle Chrome機能拡張で便利にする（ポインターのプレビュー）

NCMBでは管理画面を提供していますが、時々物足りないことがあります。この機能があったらもっと便利なのに…と思いつつ、使っている方もいることでしょう。

そこで、その足りない機能を補足するGoogle Chrome機能拡張を開発しはじめました。今回は1.4で追加したポインターのプレビュー機能です。

## 動作について

実際の動作は以下のようになります。データストアでポインターを見るの上にマウスを当てると、リレーション先のデータがテーブル表示されます。

![tooltip.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/962c71a7-32a8-9755-d117-977db260bb5b.gif)


通常は以下のようにポインターのデータ（オブジェクト）が出るだけなので、どういった内容なのかは分かりづらいです。プレビューできるようになれば、都度リレーション先のデータを確認しにいかずに済みます。

![1331 console.mbaas.nifcloud.com - 0615155320.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/f3121cc9-c8db-61ae-e6e9-5c6a3e781811.jpeg)

## インストール

[Chrome機能拡張のページからインストール](https://chrome.google.com/webstore/detail/ncmb-extension/dglkhlplcpmnbgodhbngcmdfpojkbdnc?hl=ja&authuser=0)してください。

## 利用法

任意のデータストアのクラスで「ポインターを見る」の上にマウスポインターを当ててください。クリックすると、該当データに飛ぶ仕様は変わっていません。

## 制限

この機能拡張は [https://console.mbaas.nifcloud.com](https://console.mbaas.nifcloud.com/) 以下でのみ動作します。また、この機能は管理画面のAPIを使っていますので、APIコール数を消費しません。また、ACLは無視して処理されます。

DLされるファイルはCSVのみです。JSONをそのままCSVにしているので、行は長めかも知れません。

## コードについて

機能拡張のコードは[NCMBMania/chrome-extension](https://github.com/NCMBMania/chrome-extension)にアップロードしてあります。ライセンスはMIT Licenseです。依存ライブラリとして[URL.js](https://github.com/duzun/URL.js)とjQueryを使っています（どちらもMIT Licenseです）。

## まとめ

機能的にはまだ多くありませんが、徐々に機能を追加していきます。Google ChromeでmBaaSの管理画面を利用されている方はぜひお使いください。
Unityの新Input SystemのActionが反応しない問題

# 原因と解決策から言うと

原因はControl Schemeのデバイスリストが空だったのです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/996080/9d9c7dcc-6a0e-1937-e0c8-f6f622a9c6da.png)

「+」ボタンを押して必要なデバイスを追加することで、作成したActionは反応できるようになりました。

![スクリーンショット 2023-06-15 13.54.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/996080/53f64848-fe73-05e1-fd26-30f23fcc0ffb.png)

同じ問題同じ原因に遭った人は私一人だけではありません。

https://forum.unity.com/threads/playerinput-component-not-working-with-control-schemes.795213/

Control Schemeを作成しない（既存のすべてのControl Schemeを削除する）のも解決策になります。下記のチュートリアル動画の「Create New Input Action Asset」の節を詳しく見ると、Input Actionを作る時にControl Schemeは作られなかったです。

https://youtu.be/Yjee_e4fICc?t=167

# 環境

- Unity 2022.3.2f1
- Input System 1.6.1
- macOS Ventura

# 問題の現象（経緯）

ネットで検索した記事を参考にし

1. Input Systemパッケージを導入しました。
1. Input Actionアセットを作成し、キーボードのスペースキーをJumpアクションに紐つけました。ただ、それらの記事に書いていない操作として、Input ActionアセットにControl Schemeを追加しました。
1. Player Inputをキューブに追加しました。
1. Actionが起こる時に実行する`OnJump`イベントメソッドを書きました。
1. 自作のスクリプトをPlayer Inputと同じキューブに追加しました。

しかし、シーンをプレイする時に、スペースキーを押しても`OnJump`メソッドは呼び出されなかったです。Player InputのBehaviorを

- Send Messages
- Broadcast Messages
- Invoke Unity Events
- Invoke C Sharp Events

のいずれに変えても問題は依然のままです。

下図は作成したInput Actionアセットです。

![スクリーンショット 2023-06-15 15.37.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/996080/a1d82991-b6fa-f986-d74b-f2b014317fab.png)

下図はシーンの構造と追加したPlayer Inputです。

![スクリーンショット 2023-06-15 15.40.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/996080/2211417d-8697-98aa-ada8-0ea8a9fc17c7.png)

Player InputのBehaviorがSend Messagesの時に書いた自作のソースコードは下記です。Invoke Unity EventsとInvoke C Sharp Eventsの時に書いた`OnJump`メソッドの宣言とアクションとの紐つけ方はまた多少異なります。

```C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

namespace FamilyDayGame2023
{
    public class Obake : MonoBehaviour
    {
        private void OnJump()
        {
            Debug.Log("Obake Jump");
        }
    }
}
```

アクションに紐付けたメソッドは呼び出されないですが、`Keyboard.current.spaceKey.wasPressedThisFrame`はちゃんと`true`を返してくれます。

```C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

namespace FamilyDayGame2023
{
    public class Obake : MonoBehaviour
    {
        private void Update()
        {
            if (Keyboard.current.spaceKey.wasPressedThisFrame)
                Debug.Log("Obake Jump");
        }
    }
}
```

# 参考したInput Systemのチュートリアル記事

https://nekojara.city/unity-input-system-intro

https://hiramame-gclab.com/unity_inputsystem_entry/#toc1

https://logmi.jp/tech/articles/326468
Javaで日時変換に詰まった件

<p>Javaで日時の文字列から24時間表記のyyyy/MM/dd HH<span>:<span/>mm:ssへの変換につまったため備忘録。<p/>

```:NG1: Unsupported field: HourOfDay
String inputDateTime = "20230818 083000";
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyyMMdd hhmmss");
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
LocalDate date1 = LocalDate.parse(inputDateTime, inputFormatter);
String result = date1.parse(outputFormatter);
```

```:NG2: Unsupported field: ClockHourOfAmPm
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyyMMdd HHmmss");
```
→どちらもDateTimeFormatter.ofPatternがHHを変換できないため。

結論：LocalDateではなくLocalDateTimeを使いましょう。
```:OK
LocalDateTime date1 = LocalDateTime.parse(s, DateTimeFormatter.ofPattern("yyyyMMdd HHmmss"));
String result = date1.parse(outputFormatter);
```
RubyでAtCoder ABC242(A, B, C)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC242のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。

# A - T-shirt
https://atcoder.jp/contests/abc242/tasks/abc242_a
```ruby:a-242.rb
a, b, c, x = gets.split.map(&:to_f)
puts x <= a ? 1.000000 : x <= b ? c / (b - a) : 0.000000
```
## 解説
XがA以下の場合は、必ずTシャツがもらえるので確率は1です。また、XがB以下の場合は、Tシャツをもらえる確率は`C / (B - A)`となります。XがBより大きい場合は、Tシャツはもらえないので確率は0となります。

# B - Minimize Ordering
https://atcoder.jp/contests/abc242/tasks/abc242_b
```ruby:b-242.rb
puts gets.chomp.chars.sort.join
```

# C - 1111gal password
https://atcoder.jp/contests/abc242/tasks/abc242_c
```ruby:c-242.rb
n = gets.to_i

mod = 998244353
dp = Array.new(n + 1) { Array.new(11, 0) }
[*1..9].each{ dp[1][_1] = 1}

1.upto(n - 1) do |i|
  1.upto(9) do |j|
    dp[i + 1][j] = (dp[i][j - 1] + dp[i][j] + dp[i][j + 1]) % mod
  end
end
puts dp[-1].sum % mod
```
## 解説
（[公式解説](https://atcoder.jp/contests/abc242/editorial/3515)を参考にしました）

動的計画法を使って解くことができます。`dp[4][7] = f(7???)`のとき、`dp[4][7] = dp[3][6] + dp[3][7] + dp[3][8]`のような漸化式が成り立ちます。

1桁のときはそれぞれの数値について1通りなので、1で初期化します。後は、与えられた整数の桁数に応じて`dp`の値を更新していきます。答えは、条件を満たす場合の総和を`998244353`で割った余りとなります。


https://qiita.com/shoya15/items/50fd17e37d7c64f2b166
Python によるスレッド版command pattern (車輪の再開発)

# 動機
pyOpenGLがメインスレッドでなくても動きそうなので、
バックエンドとしてスレッドで動くcommandパターンがないかなと思って、
探したけど、実用的なのがすぐ見つからなかったので、作りました。
たぶん、だれか作ってると思うんだけど。

# 実装
```python:Woker.py
from __future__ import annotations
from abc import ABC, abstractmethod
from threading import Thread
from queue import Queue


class Command(ABC):
    """
    The Command interface declares a method for executing a command.
    """

    @abstractmethod
    def execute(self) -> None:
        pass

class QuitCommand(Command):
    def execute(self) -> None:
        pass

class CallbackCommand(Command):
    def __init__(self, func, *args, **kwargs):
        self.func = func
        self.args = args
        self.kwargs = kwargs
    def execute(self):
        self.func(*self.args, **self.kwargs)
    

class Worker:
    def __init__(self):
        self.queue = Queue()
        self.is_done = False
        self.thread = Thread(target=self.run)
    
    def run(self):
        while True:
            item = self.queue.get()
            if isinstance(item, QuitCommand):
                break
            item.execute()
        self.is_done = True
        
    
    def start(self):
        self.thread.start()
    
    def join(self):
        self.thread.join()
    
    def put(self, cmd):
        self.queue.put(cmd)
    
    def putQuitCommand(self):
        self.put(QuitCommand())
    
    def putCallback(self, func, *args, **kwargs):
        self.put(CallbackCommand(func, *args, **kwargs))
        
        
if __name__ == "__main__":
    import time

    w = Worker()
    w.start()

    w.putCallback(print, "hogehoge")
    w.putCallback(time.sleep, 1)
    w.putCallback(print, "fugafuga")
    w.putQuitCommand()

    w.join()

```

# コメント
本来は、Commandクラスを色々派生させて、commandは作るべきだろうけど、
実用上実行したい関数をコールバックしてもらうほうが多いかなと思って、
コールバック出来るものを追加。

Quitのやり方はもっといい方法ありそうだけど、一旦は今のやり方でやってます。
また見直すかも。
【失敗談】LaravelのログをCloudWatchに吐き出す時にまとめようとしてみたが、うまくいかなかった話

# はじめに

AWS ECSでLaravelを動作させています
ログについては、`awslogs`ドライバーを利用してCloudWatchに出力しています
その際に、CloudWatch上でLaravelのログが1行ずつ細かく出力されていて見づらかったので、ある程度纏めてみるという方法を試してみました

結論から言うと、検証時にはうまくいったのですが、実際に運用してみると、CloudWatch上でログが表示されなくなってしまいました

# 実際のCloudWatchから見た時のログ
## まとめる前のログ

CloudWatch上でLaravelのログを確認すると、以下のように1行ずつ出力されていました

![log_before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266407/76ee9332-0740-f6bc-005a-3b6623f9add8.png)

## まとめた後のログ

ログの表示が出来なかったため、キャプチャはありません

# まとめる方法

TerraformでECSのタスク定義を作成しているので、そこで設定を追加しました

```terraform
#ContainerDefinitions
ContainerDefinitions:
  - Name: "php"
    Image: !Ref ECSImageLaravelRepositoryName
    LogConfiguration:
      LogDriver: awslogs
      Options:
        awslogs-group: !Ref ECSLogGroup
        awslogs-region: !Ref "AWS::Region"
        awslogs-stream-prefix: !Ref ProjectName
        awslogs-multiline-pattern: "^(INFO|DEBUG|WARN|ERROR|CRITICAL)" < #この行を追加
```

## awslogs-multiline-pattern について

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/using_awslogs.html

> このオプションでは、正規表現を使用する複数行起動パターンを定義します。ログメッセージは、パターンに一致する 1 行と、それに続くパターンに一致しない行で構成されます。一致する 1 行とは、ログメッセージ間の区切りです。
>
> 注記
> 複数行のログ記録は、すべてのログメッセージの正規表現の解析とマッチングを実行します。これによりログ記録のパフォーマンスに悪影響が及ぶ可能性があります。

Laravelから出力されるログには、先頭にLogレベルが出力されます
それを利用して一区切りにするための設定を行いました

# なぜ失敗したか

ドキュメントにもあるように、パフォーマンスに悪影響がでたんだと思われます

- 後追いで調査できるように、詳細なログまで出力するようにしていたので、ログの行が膨大になっていたこと
- 秒間で2アクセス以上はあるサービスだったこと

# さいごに

`awslogs-datetime-format：%Y-%m-%d %H:%M:%S"`の設定も試してみたのですが、思ったように機能しませんでした
こうすると上手くいくという情報をお持ちの方がいらっしゃいましたら、教えていただけると幸いです
M1 MacのParallels上のUbuntuにdocker-composeをインストール

レアケースなんだとは思いますが…
### 環境
CPU:Apple M1
ホストOS:macOS Ventura(13.4)
Parallels Desktop:18.3.1
ゲストOS:Ubuntu Linux 22.04 LTS Server

### Dockerのインストール
ここを参考にDocker本体は問題なくインストールできた。
https://www.kagoya.jp/howto/cloud/container/dockerubuntu/
```sh:
$ docker -v
Docker version 24.0.2, build cb74dfc
```
## docker-composeのインストール
通常linuxでのdocker-composeは以下でインストールできる。
(2023/06/15時点ではdocker-composeは2.18.1)
```sh:
sudo curl -L "https://github.com/docker/compose/releases/download/v2.18.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
```
### 注意点
+ aptでインストールすると１.**系が入るので避ける
+ docker-composeのインストールでググるとコマンドのバージョンに"v"がついていない場合があるので注意
```sh:
#バージョンのところにvがない、このままバージョンの数字を変えてもNG
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
```
+ unameはシステム情報を表示するコマンド -s :Linux, -m :aarch64
+ シンボリックリンクを張り直せというのも見かけるが、やらなくてよい