OmniAICreator/Qiita-1.07M huggingface dataset:
git stashで作業の一時退避

## はじめに
自分用の学習メモです。
git stashを使うことで、作業中の変更を一時的に退避させ、新しいブランチに切り替えたり、他の作業を行ったりすることができます。

## 使い方
１.変更を一時的に保存する
```
git stash
```
これにより、現在の作業ディレクトリの変更がスタッシュに保存され、作業ディレクトリはクリーンな状態になります。

2.スタッシュを適用する
```
git stash apply
```
これにより、最新のスタッシュが現在の作業ディレクトリに適用されます。スタッシュは残ったままなので、再度適用することができます。

3.スタッシュを適用して削除する
```
git stash pop
```
これにより、最新のスタッシュが適用され、同時にスタッシュから削除されます。

4.スタッシュの一覧を表示する
```
git stash list
```
これにより、保存されたスタッシュのリストが表示されます。

5.特定のスタッシュを適用する
```
git stash apply stash@{2}
```
複数のスタッシュが存在する場合、特定のスタッシュを適用するには、stash@{n}の形式で指定します。
これにより、stash@{2}のスタッシュが適用されます。

6.特定のスタッシュを削除する
```
git stash drop stash@{2}
```
特定のスタッシュを削除するには、以下のコマンドを使用します。
これにより、stash@{2}のスタッシュが削除されます。

7.すべてのスタッシュを削除する
```
git stash clear
```
これにより、すべてのスタッシュが削除されます。



## おわりに
git stashは、作業中の変更を一時的に保存し、他の作業を行ったり、ブランチを切り替えたりする際に便利です。
新しいAWSの認定資格が発表されたぞ

こんにちは。Crane＆I　藤島です。
Qiitaで記事を書き始め、1か月に1個ぐらいは記事をあげよう。と心に決めてから
「やべぇ！もう月末やーん」となっている自分がおります。
さんじゅう〇日まではその月です。大丈夫。間に合う。諦めないぞ、私は。

## 出たぞ、ついに
少し前の話題になってしまうのですが、AWSが新しい認定資格を発表しましたね。

https://xtech.nikkei.com/atcl/nxt/column/18/00001/09425/

具体的には、以下の二つになりますね。
* AWS Certified AI Practitioner（AIF）
* AWS Certified Machine Learning Engineer - Associate（MLA）

## AWS認定資格は4つのカテゴリから
AWSはこれまで公式認定を、以下の4つに分類しています。
「FOUNDATIONAL」
「ASSOCIATE」
「PROFESSIONAL」
「SPECIALTY」

初級の「FOUNDATIONAL」に該当する
2018年にスタートした「AWS 認定クラウドプラクティショナー」は、
沢山の若手エンジニアや、営業さんなどがAWSの基礎を学び、
AWSへの認知が爆発的に上がったきっかけの一つではないかと感じています。

## AWS認定資格に関する最近の傾向
ここ最近では、「SPECIALTY」の資格が少しずつ収縮されている動きが見えており
逆に、基礎系の資格が増えてきている印象です。
「AWS Certified Data Engineer - Associate」等。

そんなAWSが、いきなり「Foundational」レベルと、「Associate」の組み合わせを同時に提供するという。
何とも、意思が見える動きだなと感じます。

## AIとの関係
YouTube等では、生成AI等を活用するに向けた育成系の動画もかなり増えてきていて
市場がかなり動いてきているのが感じ取れます。

良く、仕事がAIに奪われる！なんて話題が良く上がりますが
奪われるのではなく、うまく扱って共存できるよう「どのようにその技術を活かしていけるのか」
という視点で、様々なことを広げていけるようになりたいですね。

恥ずかしながら、Chat GPTなんかは、私よりも弊社のエンジニアのほうがよく扱えていて
教えてもらうことも多々あります…(笑)
こういうニュースを見ると、触発されて学習意欲が増していきますね。ありがたいことです。


## 試験の開始日は
**2024年8月13日** からベータ版が開始するようです。
動向を見ていきたいと思います。
基本は英語版から提供スタートすることが多い中、同時に日本語版の試験提供も入るようなので、AWSとしてもこの力の入れっぷりは間違いないですね…。

きっとQiitaにいらっしゃる先駆者たちが「受けてきたぞ」のレポートが上がると思うので
めちゃめちゃ楽しみにしていようと思います。


##
お読みくださりありがとうございます。
また次の記事で。（次はギリギリにならないようにします）
VSCodeでちょっとだけ生産性を上げる３つのショートカット

## はじめに
今回は、VSCodeを使用して開発をしていく上でちょっとした時短になる便利なショートカットを紹介したいと思います。

## ショートカット① 新しいファイル/ディレクトリを作成
名前の通りの機能を持ちます。デフォルトで`⌘+N`に設定されているものとは異なり、エクスプローラ(サイドバーのディレクトリを見る箇所)にフォーカスが当たっているとき使用できるショートカットです。
任意の箇所に素早く新しいファイル/ディレクトリを作成できます。

このショートカットはデフォルトではキーが割り当てられていないので、設定をする必要があります。
![スクリーンショット 2024-06-30 23.29.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778030/50c7bb5c-fb06-4371-d877-3a8fbdc5b21f.png)

## ショートカット② カーソル右側の文字を削除
個人的にこれを知った後、結構使用する頻度が高かったので選出しました。
`^+K`でカーソル右側の文字を全削除することができます。

## ショートカット③ 全ての差分エディターを閉じる
これはかなり時短になりますし、煩わしさが軽減しました。
Gitのファイルチェンジを見た後、差分を表示したファイルがかなり残ることがあります。
そんな時このショートカットがあれば、全ての差分エディタを1コマンドで全て閉じることができます。

これもデフォルトではキーが割り当てられていないので、設定する必要があります。

![スクリーンショット 2024-06-30 23.39.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778030/13626018-a466-9069-fc43-83179a9955ad.png)

### 終わりに
また便利だと思ったショートカットがあれば、随時追加していきたいと思います。
【新入社員必見】スクリーンショットの種類を学んで、作業効率アップ！

# 概要
WindowsOSには様々なスクリーンショットがありますので、それらの特色を学んで今撮りたいスクリーンショットを適宜使って、作業効率アップを図っていきましょう。

# スクリーンショットの種類
スクリーンショットを撮るアプリもありますので、
今回はWindowsの標準機能のスクリーンショットについて、記載していきます。
（WindowsOS以外のスクリーンショットは別記事で紹介したいと思います。）

![フロー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618971/63c37d38-f6e9-053e-93a8-c63456ee2f06.png)

上記の図のように、用途によって使い分けましょう。

# 各スクリーンショットの詳細
## ➀[PrintScreen]キー
[PrintScreen]キーは全画面を対象にスクリーンショットを撮ることが出来ます。
保存先はクリップボードになります。
ですので、エクセル等でドキュメントを作成している時などはファイルを取り込む手順を省くすることが出来るので、大変重宝します。
しかも、デュアルディスプレイを使用している場合、複数画面を一緒にスクリーンショットすることができます。
更にメリットとして、コンテキストメニューなど、他のキーを押下したら消えてしまうポップアップをスクリーンショットしたい場合はこちらの機能を利用します。


## ➁[Alt]キー　＋　[PrintScreen]キー
『[Alt]キー　＋　[PrintScreen]キー』はアクティブウィンドウを対象にスクリーンショットを撮ることが出来ます。
保存先はクリップボードになります。
ですので、➀と同じくエクセル等でドキュメントを作成している時などはファイルを取り込む手順を省くすることが出来るので、大変重宝します。
アクティブウィンドウを対象とするため、IT業界で、テスト工程のエビデンスを作成する際や、手順書作りに大変重宝しております。
ただし、➀と違い、コンテキストメニューを撮ることはできないのが難点です。


## ➂・➅[Windows]キー　＋[Shift]キー　＋　[S]キー
『[Windows]キー　＋[Shift]キー　＋　[S]キー』は、「切り取り＆スケッチ」というWindowsの標準ツールをショートカットキーで起動させて、スクリーンショットを撮ることが出来ます。
保存先はクリップボードとファイル保存の両方に保存します。

ファイルの保存先は「ピクチャー\スクリーンショット」の配下に自動保存されていきます。
しかも同時にクリップボードにも保存されているので、エクセル等でドキュメントを作成している時『[ctrl]キー ＋ [v]キー』で貼り付けることが出来ます。


## ➃[Windows]キー＋[PrintScreen]キー
『[Windows]キー＋[PrintScreen]キー』は全画面を対象にスクリーンショットを撮ることが出来ます。
保存先はファイル保存となり、「ピクチャー\スクリーンショット」の配下に自動保存されていきます。
しかも、➀と同じく、デュアルディスプレイを使用している場合、複数画面を一緒にスクリーンショットすることができます。
更にメリットとして、➀と同じく、コンテキストメニューなど、他のキーを押下したら消えてしまうポップアップをスクリーンショットしたい場合はこちらの機能を利用します。


## ➄[Windows]キー　＋　[Alt]キー　＋　[PrintScreen]キー
『[Windows]キー　＋　[Alt]キー　＋　[PrintScreen]キー』はアクティブウィンドウを対象にスクリーンショットを撮ることが出来ます。
保存先はファイル保存となり、「C:\Users\[ユーザ名]\Videos\Captures」の配下に自動保存されていきます。※➃、➅の保存先と異なることに注意が必要です。
➁と違いファイルに保存されるため、IT業界で、テスト工程のエビデンスの作成には一度取り込み手順が入る為不向きですが、ファイル出力が必要な場合には大変重宝致します。


# 最後に
はい、ということで色々なスクリーンショットを見てきました。
これらの違いをきちんと把握し使い分けることで、作業効率はアップします。
最初のフロー図をマスターしましょう！！

最後になりますが、この記事が皆さんの成長の少しでも手助けになることを祈って、この記事を閉めたいと思います。
最後までお読みいただきありがとうございました。
Mp3ファイルを再生 [python]

# 概要
デジタルフォトフレームは写真のみ再生ですので、バックグラウンドにMP3ファイルを再生するのもよいかなと思ってネットで調べたものをメモしてみます。

# インストールするパッケージ
①サウンドを出力するパッケージをインストールする

・パッケージインストール

~~~bash
pi@RPI3B:~ $ pip install playsound
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting playsound
  Downloading https://www.piwheels.org/simple/playsound/playsound-1.3.0-py3-none-any.whl (8.0 kB)
Installing collected packages: playsound
Successfully installed playsound-1.3.0
~~~

・サンプルコード

~~~bash
import playsound
playsound.playsound('sample.mp3')
~~~

②PyGameパッケージはキーボード制御、サウンド出力などゲームに必要な機能が含まれているパッケージです。

・パッケージインストール
私は既にインストールされているメッセージが出ていますが、皆さんは確認してみてください。

~~~bash
pi@RPI3B:~ $ pip install pygame
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Requirement already satisfied: pygame in /usr/lib/python3/dist-packages (1.9.6)
~~~

・サンプルコード

~~~bash
import pygame

SCREEN_WIDTH = 400
SCREEN_HEIGHT  = 500

pygame.init()

SCREEN = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("pygame sount test")

clock = pygame.time.Clock()
pygame.mixer.music.load('sample.mp3')

# MP3を無限繰り返し再生
pygame.mixer.music.play(-1)

playing = True
while playing:
    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            playing = False
            pygame.quit()

        if event.type == pygame.KEYDOWN:
            # 「↑」キーを押下するとボリュームを上げることができる
            if event.key == pygame.K_UP:
                v = pygame.mixer.music.get_volume()
                pygame.mixer.music.set_volume(v + 0.1)
                print("volume up")
            # 「↓」キーを押下するとボリュームを下げることができる
            if event.key == pygame.K_DOWN:
                v = pygame.mixer.music.get_volume()
                pygame.mixer.music.set_volume(v - 0.1)
                print("volume down")
            # 「←」キーを押下すると再生されるMP3中止される
            if event.key == pygame.K_LEFT:
                pygame.mixer.music.pause()
                print("stop")
            # 「→」キーを押下するとサンプルファイルが再生できる
            if event.key == pygame.K_RIGHT:
                pygame.mixer.music.unpause()
                print("re-play")
                
    clock.tick(60)
~~~~

# その他
繋げているLCDの中にスピーカーが内蔵されているものの場合、下記のコマンドでHDMIを再指定すると
問題なく音が出るようになりましたので、参考してみてください。

・コマンド

~~~bash
pi@RPI3B:~ $ sudo raspi-conf
~~~

①「System options」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/a5a2c3ff-b0ff-949d-f7c7-90a11c322c87.png)
②「S2 Audio」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/726a97b8-5e61-c24e-bdc7-ac49b69a77bc.png)
③「HDMI 1」を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/52d63165-1fbe-2f18-3deb-915a429f7d92.png)
④「Finish」を選択する


# 終わりに
デジタルフォトフレームに写真が見えて好きなMP3を再生することができるようになりました。
今のソースでは１つのファイルしか再生できないですが、次回に複数のファイルが再生できるように工夫してみます。
今日はここまでです。
ありがとうございます。
pklを使ってみた　その4

個人的「質はともかく継続する」23日目です

## pklを使ってみた　その4

簡単な計算式なども使えるようです。

```pkl
inTax: Float = 1.10
outTax: Float = 1.08
book: Float = 2400.0 * inTax
egg: Float = 180 * outTax
bigMeet: Float = 1000.0
smallMeet: Float = bigMeet / 2
coupon: Float = 200.0
total: Float = (book + egg + smallMeet - coupon) 
```

四則演算はもちろん、各項目を変数のように扱うこともできるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45303/72e8ae15-cf29-1ea7-90e2-6191ec395401.png)

## まとめ
今日はしんどいのでここまで。。
短くてすみません。
【新入社員必見】【Win10まで】ツールバーを使って作業効率アップ！

# 概要
Windows11が発売されて久しいが、Window10まであった機能なのに、Windows11になったことで消えてしまった機能がある。
その一つに、ツールバーという機能です。
知る人ぞ知る機能ではあったのだが、あまりにも認知されなさ過ぎてWindows11では削除されてしまったんだと思われる。
どんな機能かというと、一言で言うと、タスクバーをより便利にする機能で、所定のフォルダを常に表示している様なもの！！


実際のツールバーを見てみましょう！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618971/b8de2d52-be94-54d4-87f6-b997faaedb8b.png)

私はこんな感じで、ショートカットを配置したり、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618971/4c7f8667-79df-6a0b-b497-ce6abae71156.png)

以下の様なよく使うツールをまとめて配置するフォルダを開くようにしている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618971/5302a04a-cbbb-6778-e99d-d9cb40d0a43e.png)

この機能を使うことで、無駄にエクスプローラを立ち上げることなく、よく使うフォルダを開くことが出来るのだ。
勿論設定も簡単なので、早速見ていこう。


# ツールバーの設定
ツールバーの設定は簡単です。

### ➀、タスクバーの何もない所を右クリック
赤枠の通り、タスクバーの何もない所を右クリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618971/4dc802ce-2c4c-f5ac-0330-f785fcbf80bd.png)

### ➁、コンテキストメニューの『ツールバー』をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618971/2a27c76b-77a8-fec6-2210-1455b74f9759.png)

### ➂、設定したいフォルダをダイアログで選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618971/4fbe141a-f0eb-1100-62b3-1e8b9701bf29.png)


### ➃、タスクバーに設定したフォルダの『ツールバー』が表示される。
そうこれだけで、タスクバーに設定したフォルダの『ツールバー』が表示されるんです！！
あとはこれを右クリックすることで、フォルダの中身が表示されるので、とても便利ですよ！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618971/ff393ac8-81c2-2626-b177-860268acf121.png)


# 最後に
最後になりますが、この記事が皆さんの成長の少しでも手助けになることを祈って、この記事を閉めたいと思います。
最後までお読みいただきありがとうございました。
ペアプロ・モブプロあるある

# はじめに

ペアプロ・モブプロ中によくある出来事をまとめてみました。
導入していたり、これから導入しようと検討している方のご参考になればと思います。

<font color="Red">※オンライン版です</font>


過去にペアプロ・モブプロをした所感をまとめていますのでよろしければご覧ください！

https://qiita.com/does_not_exist/items/7a8157a98c756ab12a1f

https://qiita.com/does_not_exist/items/bc9972db22823ce8519f


# かゆいところの指示が難しい

- コンソールを開いてください
「AWSの？」「VS Codeの？」「開発者ツールの？」

同じ動作が続くと主語を省略しがち

- 括弧の数足りないですね、よく分からないので一回元に戻しましょうか

括弧系の操作指示は難しい



# 知らないショートカットが登場すると盛り上がる
- 効率化はみんな常に求めているようです


# 誰かが休憩したらみんな休憩に入る
- 時間を決めて休憩を取るべきなのですが、気づいたらみんな集中していて…ということが多々あります
- 休憩後にミュート芸をする方もちらほら



# 質問はいつも勇気とともに
- やはり時間を止めることに少なからずの抵抗があります

# 時の流れを早く感じる
- 一日中話していると気づいたら夕方になっています。午前中なんてあっという間です


# おわりに
いかがでしょうか。オフラインだとまた違った感じになるのでしょうか。
ノーコードって結局使えないよね～って話

# はじめに
コードを書かずにWebサイト/アプリ/ツール等の制作ができるノーコードツールが最近流行っていますよね。
私自信、半年ほど前からn8nやActivepiecesといったOSSのノーコードツールやPower Automateなど、幾つかのノーコードツールを触っていたですが、ツールとして未成熟であったり自由度が低かったりと、「結局流行らないのでは？」と感じています。~~(GPTのそれと一緒で期待値が高いだけなんですかね)~~

# ノーコードツールの幻想
D&D操作だけで直感的に操作できるノーコードツールは、一見、プログラミング初心者にとって救世主のように映ります。しかし、それは十分な選択肢なのでしょうか？

## 本当に手軽ですか？
多くのノーコードツールでは、よくあるような定型作業のテンプレートとD&D操作で実装できるUIを提供することで、直感的に操作できるよう設計されています。

一見、自由度の高い開発環境のように思えますが、実際には用意されたテンプレートや機能の枠組みを超えることは難しいのが現状です。

ブロックをコピペしようとすると入れ子構造が滅茶苦茶になったり内部パラメータがおかしくなったり、平気でそんな挙動を示します。~~とても癪です。やめてほしい。~~

## 拡張性足りてる？
前述のようにノーコードツールは、テンプレートや部品を組み合わせることで任意の成果物を作ることになります。
しかし、これらの部品はカスタマイズ性に乏しく、細かい調整やデザイン変更が難しい、あるいはできないことが常です。

結局のところ、ツールに既に存在しない機能を実装しようとすると、自前でコードを書く必要が出てきて、「ノーコードのはずが結局コードを書く羽目に...」みたいな展開よくありますよね。

これなら、最初からコード書いてたほうがよくないですか？

## それ、コードを書いたほうが早くない？
ノーコードツールは基本的にGUIでの操作ですが、複雑な処理をGUIでの操作で実現しようとする場合、膨大な作業量が必要で、とても非効率的です。

また、内部的な処理を把握することが厳しく、エラーが発生してもデバッグ作業がとてもつらいです。~~ストレスで禿げそうになります~~

# さいごに
ノーコードツールは、プログラミング知識ゼロでもシステムを作れる便利なツールですが、結局のところ設計についての勉強や経験なしで質の高いシステムを作ることは不可能だと思います。

確かに、コードを書くことはブロックを並べるだけの作業と比較すると難しく、専門的な知識が必要です。
しかし、システム開発にはコード以外にも多くの要素があり、表面的な使いやすさだけで良いシステムを作れるわけではありません。

ノーコードツールで「奇跡的に良いシステム」ができたとしても、担当者が辞めたり、作り変えが発生したりした場合、対応できずに結局スクラッチでの開発が必要になるケースが非常に多く見られます。
手軽さだけを神聖化するべきではないと思います。

結局のところ、そのツールでしか使えないスコープの限られた知識を学ぶより、何かしらのプログラミング言語を習得したほうが明らかに学習に対するコスパは高いかと思います。

それでは。
ABC360の振り返り

[前回の振り返り](https://qiita.com/comet725/items/42431ca7083621c286da)

今日はABC開催日だったので参加した結果を適当に振り返る

https://atcoder.jp/contests/abc360

今回も安心と信頼のABCの3完
- しかしAB問題を雑にコーディングしすぎて2回WAしてしまった

以下でそれぞれ問題についてまとめる

E,F,Gは取り組んですらないが
Dを解き始める前に読んだ感想とかその後の解説の反応をまとめている。

# A

Sの文字の場所を確認してRの位置 < Mの位置だったらOK
Mを指定する箇所を間違えてSにしてしまいWA食らったorz


## ソースコード

```python:main.py
import sys
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
def err(*args): print(*args, file=sys.stderr)

def main():
    S = rS()
    
    d = {s:i for i,s in enumerate(S)}    
    
    ans = d["R"] < d["M"]
    print("Yes" if ans else "No")
    
if __name__ == '__main__':
    main()

```

# B

最初分割をどうするか思いつかなくて適当にやったらWA食らった
そして一旦落ち着いてスライス使うことにしたら解けた。

## ソースコード

```python:main.py
import sys
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
def err(*args): print(*args, file=sys.stderr)

def main():
    S, T = rLS()
    
    N = len(S)

    for w in range(1,N):
        s_lst = [S[i::w] for i in range(w)]
        for s in s_lst:
            if s == T:
                print("Yes")
                break
        else:
            continue
        break
    else:
        print("No")

if __name__ == '__main__':
    main()

```

# C

同じ箱に入っているもののうち、一番重いもの以外のやつを総和する。
`heapq`,`defaultdict`,`Counter`といろんなデータ構造をぶつけてACした

## ソースコード

```python:main.py
import sys
import heapq
from collections import defaultdict,Counter
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
def err(*args): print(*args, file=sys.stderr)

class Minheapq(object):
    def __init__(self):
        self.q = []
    def push(self, v):
        heapq.heappush(self.q, v)

    def pop(self):
        return heapq.heappop(self.q)

def main():
    N = rI()
    A = rLI()
    W = rLI()
    
    d = defaultdict(lambda: Minheapq())
    
    c = Counter(A)
    
    for a,w in zip(A,W):
        d[a].push(w)
    
    ans = 0
    for k,v in c.items():
        if v < 2:
            continue
        for _ in range(v-1):
            w = d[k].pop()
            ans += w
    print(ans)
    
if __name__ == '__main__':
    main()

```

# D

0,1をグループ分けして尺取り法までは分かったが、
しかし前提のすれ違う条件がわからなくて時間切れ

後日解説ACした記事を書く予定

# E
期待値のやつなんてやったことないのでそっ閉じ

# F
順位表で解いてる人少なそうだったので見なかったことにした

# G
最初、1つだけ変更して組み合わせるからもしかしてセグ木でいけるか？
とか思ったけど、よく読んだら最大値さがすならDPじゃんってなって
じゃあどうやって組み合わせるの？と謎が解けず、放置

終わった後に解説みたらDPだけでいいのねこれ

もしD問題を解けていたら取り組んでたけど多分解けなかったと思う。

# まとめ

A,B問題で焦ってしまいそれぞれでWAを喰らってしまった
それぞれは早解きしたい問題ではあるが、落ち着いて取り組まないといけないね。
スクラムマスターが行うファシリテーション（by ChatGPT）

### 🌟 スクラムイベントのファシリテーション
+ スプリントプランニング
    + ✨ 準備：プロダクトオーナーがプロダクトバックログを整理し、優先順位を決定しておく。
    + 🚀 会議進行：チームがスプリントゴールを設定し、スプリントバックログを決定するのをサポート。
    + 📝 タスク分解：チームが大きなユーザーストーリーを小さなタスクに分解するのを支援。
    
+ デイリースクラム
    + ⏰ タイムボックス：15分以内で終了するようにする。
    + 🔄 フォーカス：各メンバーが「昨日やったこと」「今日やること」「障害」を簡潔に報告。
    + 🚫 障害除去：報告された障害をリストアップし、解決を支援。
+ スプリントレビュー
    + 🖥️ デモ：チームがスプリントの成果をデモする場を提供。
    + 🗣️ フィードバック：ステークホルダーからのフィードバックを引き出す。
    + 🔄 次のアクション：フィードバックをもとにプロダクトバックログを更新。
+ スプリントレトロスペクティブ
    + 🌟 ポジティブな点：うまくいったことを確認。
    + 🔍 改善点：改善が必要な点を洗い出す。
    + 💡 アクションプラン：改善策を具体的な行動に落とし込む。

## 📋 その他のファシリテーション活動
+ 障害除去
    + 🌐 コミュニケーション：チームメンバー間のコミュニケーションを促進し、障害を早期に発見。
    + 🛠️ サポート：障害の解決に必要なリソースやサポートを提供。
+ チームの成長促進
    + 📚 トレーニング：必要に応じてトレーニングや教育を提供。
    + 🌱 コーチング：個々のメンバーの成長をサポート。
+ プロセス改善
    + 🔄 継続的改善：レトロスペクティブで得られた改善点を実行し、プロセスを継続的に改善。
+ リーダーシップ
    + 🌟 モチベーション：チームのモチベーションを高める。
    + 👥 コラボレーション：チーム内およびチーム間のコラボレーションを促進。

:::note info
スクラムマスターがこれらのファシリテーションを効果的に行うことで、チームが高いパフォーマンスを発揮し、プロジェクトの成功に貢献することができます。
:::
AtCoder 勉強記録[C++] その6

AtCoderで入茶を目指して勉強しています。
勉強を継続するために投稿を始めました。
もともとアカウントを作成していましたが、今年の4月から本格的に勉強を始めました。
一応自分用に解法を書いていますが雑です、自分で読み返して困ったら修正します。
[私のアカウント](https://atcoder.jp/users/nanami_brother)
[解いた問題](https://kenkoooo.com/atcoder/#/table/nanami_brother)

# 本日解いた問題
## B - Pasta
[B - Pasta](https://atcoder.jp/contests/abc241/score)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll m, n;
  cin >> n >> m;
  vec a(n), b(m);
  vector<bool> jud(n);
  rep(i, n) cin >> a[i];
  rep(i, m) cin >> b[i];
  rep(i, m){
    bool tmp = false;
    rep(j, n){
      if(!jud[j] && a[j] == b[i]){
        tmp = true;
        jud[j] = true;
        break;
      }
    }
    if(!tmp) {
      cout << "No" << endl;
      exit(0);
    }
  }
  cout << "Yes" << endl;
}
```
### 解法
食べたパスタを判定するbool配列を用意して、計画を実行できるか判定する。

## C - Calendar Validator
[C - Calendar Validator](https://atcoder.jp/contests/abc225/tasks/abc225_c)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n, m;
  cin >> n >> m;
  vector<vector<ll>> b(n, vector<ll>(m));
  rep(i,n){
    rep(j,m){
      cin >> b[i][j];
    }
  }
  bool res = true;
  rep(i,n){
    rep(j,m-1){
      if(b[i][j] + 1 != b[i][j+1]) res = false;
    }
  }
  rep(j,m){
    rep(i,n-1){
      if(b[i][j] + 7 != b[i+1][j]) res = false;
    }
  }
  rep(i,n){
    rep(j,m-1){
      if(b[i][j] % 7 == 0) res = false;
    }
  }
  if(res) cout << "Yes" << endl;
  else cout << "No" << endl;
}
```
### 解法
行列Aの成分を考えた時に、右に1つずれると1増加して、下に1つずれると7増加することがわかる。そのことを利用して一致するかどうかを判定しようと考えた。しかし、WAだったため[こちらの記事](https://zenn.dev/fjnkt98/articles/b4c828faaae6f9)を参考にした。7の倍数の要素が右端にしか来ないことを考慮していなかったため、そちらも含めて判定したところACできた。

## A - A Healthy Breakfast
[A - A Healthy Breakfast](https://atcoder.jp/contests/abc360/tasks/abc360_a)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  string s;
  cin >> s;
  if(s[0] == 'M') cout << "No" << endl;
  else if(s[1] == 'M' && s[2] == 'R') cout << "No" << endl;
  else cout << "Yes" << endl;
}
```
### 解法＋メモ
みそ汁がご飯より左にある場合はみそ汁がS[0]の場合と、みそ汁がS[1]かつご飯がS[2]の場合のみなので場合分けして出力する。
今回のABC360はA問題しか解けなかったので結構萎えた。ただ、腐らずに続けようと思う。
SalesforceでUpsertでTodo、行動のWhatID　WhoIDに外部IDを使いたい場合使えるのか？の回答

本橋孝昭です


今回はデータローダを使用してToDoを登録する際に外部キーを使用したい　という人向けの記事です


Salesforceのヘルプにはこのような記載があります（2024年6月30日現在）

>すべての参照項目を外部 ID に対応付けることは不可能かもしれません。たとえば、標準の活動オブジェクトの関連先  (WhatId) 項目や名前 (WhoId) 項目、カスタムオブジェクトの所有者項目などの多態的な項目では、外部 ID への対応付けはできません。次のアイデアがご要望の機能である場合は、投票 (Upvote) を検討してください: 「Enable External Keys on Polymorphic Fields」。アイデアは、将来のリリースで Salesforce に追加される可能性があります。詳細については、「リレーション項目および多態的な項目について」を参照してください。

https://help.salesforce.com/s/articleView?id=000383207&type=1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/6d17fe5c-4f8d-0d2c-87e3-51cae5a887d5.png)


しかしながら最近のSalesforceは変わったようです


具体的にはデータローダのバージョンが最新の場合（60.0.2以降）は標準の活動オブジェクトの関連先  (WhatId) 項目や名前 (WhoId) 項目では外部 ID への対応付けはできるようです

どういうことなのか。
実際に最新のデータローダのUpsert設定画面を見てみましょう


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/bab27833-0872-259a-bbd9-0496b72faaba.png)


このようにWhatIDにカスタム項目の外部ID選択が可能です


もちろんこの項目は外部IDです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/68acbc35-8f8a-9bbf-0629-1d75ec0d67b0.png)


念のため、WhoIDも外部ID項目の選択が可能なことが分かります


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/c58cae4e-202f-0ae8-c23e-0fdb2772f123.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/b9c6fde9-0658-d73e-7bab-3470c382b782.png)


みなさんも標準の活動オブジェクトの関連先  (WhatId) 項目や名前 (WhoId) 項目では外部 ID への対応付けでUpsertを行ってみましょう
RemixをNetlifyでデプロイする！Remixインストール編

# 最初に
RemixにはNetlifyでデプロイできるように設定できます。
手順は簡単でしたが、備忘録のため残しておきます。
今回はRemixをインストールして、開発できるところまでを残しておきます。
具体的なドキュメントは下記を参照しています。

https://docs.netlify.com/frameworks/remix/

# 使用技術
| ライブラリ | バージョン |
|------------|------------|
| Node     　　　　| 20.12.2    |
| pnpm       | 9.4.0      |
| React      | 18.3.3     |
| Remix      | 2.10.0     |
| Vite       | 5.3.2      |

※私の好みでpnpmを使用しています。

# Remixをインストール
下記コマンドで任意の場所でRemixをインストールを行います。
今回はnetlifyにデプロイするため、専用のコマンド担っています。
```
npx create-remix@latest --template netlify/remix-template
```

質問が出てきますが、ここではnetlifyはあまり関係がないため、
任意の回答で大丈夫です。
今回はpnpmを使用したかったので、npmを使用するかに関しては一応NOを選択しています。

インストール後は作成したプロジェクトに移動し、パッケージのインストールを行います。
```
pnpm install
```

これで準備は完了です。

# Remixを動かす
ここまででセットアップできたので、開発フェーズに移りましょう。
ここではローカルにて開発環境の立ち上げまで行います。
```
pnpm dev  
```

このコマンドでRemixの初期化及び、開発環境の立ち上げを行います。
初回のみ下記の質問が表示されます。
```
Run your Remix site with:
│  ● Netlify Functions (A Node-based runtime, running in one region)
│  ○ Netlify Edge Functions
```

この二つの違いは、netlifyをどのように動かすかのようです。
Netlify Edge Functionsを選択すれば、よりカスタマイズした環境でnetlifyを動かすことができるようですが、
今回は小規模であることと、発展した設定を行う予定はないので、
**Netlify Functions (A Node-based runtime, running in one region)**
こちらを選択しました。

そしたらREADME.mdの内容が変更されます。
具体的にはnetlifyを動かすための手順を記載してもらえています。
netlifyに関しては、また別の記事で執筆します。
その後下記コマンドを実行し、
ローカル環境で立ち上がれば終了です。
```
pnpm dev
```
![スクリーンショット 2024-06-30 22.43.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2624605/737b16b2-cc83-b72f-9070-e24cbefd7720.png)

# 最後に
次回はnetlifyへのデプロイ部分を紹介させて頂きます。
公式の方でデプロイ用のセッティングを行ってくれるのは非常に便利ですね！
【Flask】パラメータをプリセットするだけ

Flask による Web アプリケーションにパラメータをプリセットするだけです。
ソースコードは以下です。
[https://github.com/CookieBox26/flask-sample](https://github.com/CookieBox26/flask-sample/tree/133b2d538542082175a4a4f8e3aa55c268901338)

### やったこと
この Web アプリケーションは都道府県と市町村を入力して実行すると「XのYに住みたいです。」と画面に表示してくれます (左)。ただ、都道府県と市町村を入力するのは面倒です。そこで、左上の「入力パラメータ読込」プルダウンから選択すると (中) パラメータをプリセットします (右)。

<img width="33%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177688/563a8311-2f47-b75e-0339-80567be728ab.png">
<img width="31.2%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177688/4d571e2f-9ff1-ed5f-90d6-8c3f9852fcc7.png">
<img width="31.2%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177688/2ccf779e-718b-2319-978d-d64fb54c628a.png">

### 大まかな説明
- 前提として、HTML テンプレートに渡す変数たちの入れ物として Variables というクラスを定義しています。
  - https://github.com/CookieBox26/flask-sample/blob/133b2d538542082175a4a4f8e3aa55c268901338/app.py#L6-L11
- 入れ物クラスのクラス変数にプリセットパラメータたち (それぞれに識別ラベルを付ける) を記述します。
  - https://github.com/CookieBox26/flask-sample/blob/133b2d538542082175a4a4f8e3aa55c268901338/app.py#L25-L34
- HTML テンプレートからプリセットパラメータたちを参照し、プルダウンメニュー (select 要素) を作成します。ただし、onchange 属性に this.form.submit() を設定して、いずれかのプリセットパラメータが選択されたときにフォームデータを送信するようにします。
  - https://github.com/CookieBox26/flask-sample/blob/133b2d538542082175a4a4f8e3aa55c268901338/index.html#L67-L72
- 「実行する」ボタンを押したときもフォームデータは送信されますが、このときは送信データにボタンの名前 btn_exec が含まれるので、この名前の有無で「実行する」を押されたのかプリセットパラメータが選択されたのか識別できます。 
  - https://github.com/CookieBox26/flask-sample/blob/133b2d538542082175a4a4f8e3aa55c268901338/app.py#L57-L60
引き継いだプロジェクトにテスト駆動開発を導入してみて

# はじめに
こちらの記事に関連していますのでよろしければご覧ください！

https://qiita.com/does_not_exist/items/7cf84951129ed3046ccf

https://qiita.com/does_not_exist/items/653a9aa93ec84bdc236d

https://qiita.com/does_not_exist/items/2551bb4c8b7398253368

# コードに手入れしやすくなった
1機能1メソッドにすることで、シンプルな実装になっているため改修しやすくなっています。
改修の際に混乱しにくくなりました。

# 作業の進捗確認がしやすくなった
TODOを作ってテスト駆動開発をしているので、「今日はここまでを目標に進める」「今はここまでできている」などの把握ができるようになりました。デイリーでの報告でも重宝しています。

# 結合テストが書きやすくなった
1つのメソッドがシンプル、単体テストも書けている、ということで結合テストを書きやすい状態になりました。
また、ファイル内で色々なメソッドを呼び出していたり、手続き型な書き方をしていたりするとテストを書きにくいのでその点も意識して実装しています。


# 安心感が出てきた
「テスト通っているのでヨシ！」


# おわりに
時間が経つにつれてこの恩恵は大きくなるので、新たな気づきや実感があれば改めて記事にしたいと思います。
説明変数と説明的メソッド名の重要性と効果について

## はじめに
コードの可読性やメンテナンス性を向上させるためには、説明変数と説明的メソッド名の使用が重要になります
なんてことは一般的によく言われますが、自分自身そのように感じていて、説明的ではない変数名やメソッド名はて理解に数分遅れるイメージです
これが積み重なると多大な時間を浪費してしまいます
今回はそんな説明変数と説明的メソッド名について書き記してみました

## 説明変数とは？
説明変数とは、変数名がその内容や目的を名詞を使って明確に示すものになります

#### 説明変数を使わない例
```php
$a = $b * $c;
$x = $y - $z;
```
上記では変数名が何を意味するのかが分からず、コードの意図や内容を理解するのに時間をかけてしまいます
例えば`$a`、`$b`、`$c`が何を表しているのか、変数の役割を知るためには追加のコメントやドキュメントが必要になります

#### 説明変数を使った例
```php
$totalPrice = $itemPrice * $quantity;
$userAge = $currentYear - $birthYear;
```
`$totalPrice`が商品の総価格であり、`$userAge`がユーザーの年齢であることが理解できます
コードを初めて見る人でも意図を把握しやすくなります

## 説明的メソッド名とは？
メソッド名はアクション指向である必要があり、具体的な動詞で内容や目的を明確に示すものになります

#### 説明的ではないメソッド名の例
```php
function processData($x) {
    // データを処理する処理
}
```

メソッド名が具体的な機能を示していないため、コードの意図や動作がわかりにくくなっています
例えば`processData`というメソッド名では、具体的に何をするのかわかりにくく、コードを理解するのに時間がかかります

## メソッド名が説明的である例
```php

function fetchUserData($userId) {
    // ユーザーデータを取得する処理
}
```
メソッド名だけで何をするのかが明確になっています
`fetchUserData`メソッドはユーザーデータを取得することが分かります。これにより、コードレビューやデバッグ時にメソッドの目的を迅速に理解でき、効率が上がります

## なぜ説明変数と説明的メソッド名が重要なのか？
- コードの可読性向上
    - 他の開発者（あるいは未来の自分）がコードを見たときに変数やメソッドの目的をすぐに理解できるようになります
- メンテナンスの効率化
    - コードの変更やデバッグがしやすくなり、バグの発見が早くなります
- バグの減少
    - 明確な変数名とメソッドによって誤解やミスが減ります
- 責務の明確化
    - `$user`ならユーザーデータ、`fetchAllUser()`なら全ユーザーの取得
    - 上記のように目的と内容を明確化し、それ以外の目的を与えないようになります

## チーム開発における効果
- コミュニケーションの改善
    - コードが明確であれば、チームメンバー間の誤解が減り、コミュニケーションが円滑になります
- コーディング規約の一部として
    - チームで統一した命名規則を設定することで、一貫性のあるコードベースが維持されます
- 新メンバーの迅速なキャッチアップ
    - 説明変数と説明的メソッド名が使われていると、新しいメンバーがプロジェクトに参加しやすくなります

## まとめ
コードの可読性やメンテナンス性を向上させるために説明変数や説明的メソッド名が重要という内容を書き記しました
品質の改善だけでなく、コミュニケーションが円滑になるという人間的な部分も良くなるのではないのかなと思います
（質問すること自体は良いことですが、質問が減ることも良いことなのかと思います）
特にデメリットもないように思えるので積極的に説明変数と説明的メソッド名は使っていきましょう！

## 参考

https://www.oreilly.co.jp/books/9784873115658/

https://dev.to/gervaisamoah/a-guide-to-clean-code-the-power-of-good-names-3f6i
クローンアプリを作ってみたーNetflixクローン③

# はじめに
初めまして！
エンジニアになって数年、今まで本を読むだけでしたが、もっとプライベートで楽しみながら成長したい！自分が学んだ足跡を残していきたい！と思い記事を書きました！
最終的には自在に開発できるようになりたいと思っています。:triumph:
いろいろな記事を参考にさせてもらっています。:bow_tone2:
その中でもこれってどういう意味？とかつまづいたところを念入りに書いていこうかと思います。:fist:

# 今回の目的
nextjsはまだですが、実際のアプリ開発からどう作られていくかを学んでいくためにクローンアプリを開発します。
とは言っても自分で考えることは特になくYoutubeを見てやっていきます。
その中で覚えておきたい部分を分類ごとに記載していきます。なので、その時々に知ったことを小出しにしていく形になります。

前回

https://qiita.com/mr_noppo/items/4dd10edb45d0febd2d77

# 使用したものや事前準備
・Macbook Pro
・Visual Studio Code

# 使用にさせていただいた動画

https://www.youtube.com/watch?v=mqUN4N2q4qY&t=4201s

# Next.jsの知識
### リクエスト処理の基本の書き方
pages/apiディレクトリにtsファイルで書き込む
```ts
export default function handler(
  req: NextApiRequest,
  res: NextApiResponse<Data>,
) {
  res.status(200).json({ name: "John Doe" });
}
```
### [...nextauth].ts
next-authライブラリを使用する時に作成する。APIルートを動的に処理

### bcryptライブラリ
パスワードなどのデータを安全にハッシュ化する

### install -D @types/~
TypeScriuptで使用する型定義を新しく取得

### axios
postなどHTTPリクエストを投げられる
```tsx
await axios.post("/api/register", {
    email,
    name,
    password
});
```

### res.status(XXX).end();
ステータスを設定しレスポンスを終了

### res.status(XXX).json(Object)
ステータスを設定しObjectをjson形式でレスポンス

### ステータスコード
#### 200
HTTPリクエストが正常に処理された
#### 405
リクエストされたリソースが指定されたHTTPメソッドをサポートしていない
#### 400
サーバーがリクエストを理解できないときに返される（データが欠落しているなど）
#### 422
サーバーがリクエストの内容を理解はできたものの、リクエストの指示が実行できない（フォーマットが正しいが論理的に実行できないなど）
今回の場合、userが重複したら発生する
![スクリーンショット 2024-06-30 22.23.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/c993d8c8-b54d-15b1-3456-650e9826860e.png)


### prismadb.user.findUnique
Prismaを使用してuserテーブルから特定の条件に基づいてユニークなレコードを取得する

### prismadb.user.create
新しいレコードの挿入
実行後。userテーブルを確認した結果

![スクリーンショット 2024-06-30 22.23.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/94521f7b-8015-0674-231d-edb44c7366d6.png)


# 次
まだ
Angular 並列コンポーネントへのイベント連係方法

**Angularにおける並列コンポーネントへのイベント連係方法**

ここではSubjectによる状態管理と
Subscriptionによる購読設定を活用する方法を備忘として残します。

**Subjectの振り返り**
RxJS の Subject は Observable , Observer 両方の性質を持つオブジェクトです。
通常、Observable は 生成されたタイミングで(Observable の引数によって)流す値が決まっており、
後から流す値を追加したり変更したりするには、pipe などを利用して、新しい Observable を作成する必要があります。
Subject は subscribe に加えて、 next, error, complete のメソドを利用することが可能であり、
任意のタイミングで 複数の subscriber に自由に値を送信することが可能です。

**Subscriptionの振り返り**
Observable における subscribe の戻り値は Observable ではなく、
Subscription と呼ばれるオブジェクトで、メソドチェーンで subscribe をつなぐことができません。
Subscription は subscribe で登録した関数を、停止させるためのメソッドなどを提供します。

とのこと。

#
*親コンポーネント*
```ts
export class PageComponent {
  clickSubject = new Subject<void>();
}
clickEvent():void{
  this.clickSubject.next();
}
```
*親スタイル*
```html
<app-child [events]="clickSubject.asObservable()"></app-child>
```
*子コンポーネント*
```ts
export class Child {
@Input() events!: Observable<void>;
private priClickSubscription: Subscription = new Subscription;

ngOnInit(){
  this.outputConsole();
  this.priClickSubscription = this.events.subscribe(()=>
    this.outputConsole()
  );}
outputConsole():void{
    console.log("childComponent outputConsole()------------");
  }
}
```
Llama-3-ELYZA-JP-8B 量子化版をGoogle Colab, llama.cppで動かしてみた


つい先日公開されたLLaMAベースの日本語モデルを動かそうと思った。
llama.cppを使用して、LLaMA-3-ELYZA-JP-8B-GGUFの量子化版モデルをGoogle Colab(無料版)上で動かしてみた結果を共有.

Hugging Faceでモデルを参照

[LLaMA-3-ELYZA-JP-8B-GGUF ](https://huggingface.co/elyza/Llama-3-ELYZA-JP-8B-GGUF)


[llama.cpp](https://github.com/ggerganov/llama.cpp) を動かすには, モデルの形式をGGUF形式に変換が必要だが、あらかじめ変換/量子化されたモデルが公開されていた。

Google ColabではCPUのみでも動かせたし、GPU(T4)ランタイムだとかなり早く実行できた。出力も実用十分な結果だった。

Colab リンクから、コードを参照ください。
https://colab.research.google.com/drive/1pxqt8PRSF3cEohL1j4NmxmH7g-g8pcaI?usp=sharing

Little Tips:
- 推論実行時に gpuの力を発揮するには, `-ngl` オプションをつける

## まとめ　
(w/ claude君)

llama.cppを使用してLLaMA-3-ELYZA-JP-8B-GGUFの量子化版モデルをGoogle Colab上で動かしてみた。この方法を使えば、高性能なGPUを持っていなくても、大規模言語モデルを手軽に試すことができる。

環境設定やコードの詳細な説明は省略したが、実際に動かしてみると、モデルの性能や日本語での応答の質の高さを実感できた。

次回は、このモデルをNode.jsで実装し、AWS Lambda上で動かす予定だ。これにより、Webアプリケーションでの実用的な利用方法が見えてくるだろう。
全然パフォーマンスのこととか考えてない擬似 Progressive blur

## この記事の概要

少し前にこんな記事を書きました。

https://qiita.com/xrxoxcxox/items/569a36c802e46eeffef5

他の方法は無いか考えていて（全然良いとは言えませんが）別のものを見つけたので記事にしてみます。

:::note warn
CSS の filter を使うのですが、派手に使うと意外と重くります。
今回試した限りは問題ありませんでしたが、実務レベルで使えるものではないかもしれません。
というか実装がパワー型過ぎるので、面白半分で読んでください。
:::

## 完成形

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/7cd34499-c775-6210-e1e7-64d0fc5e7736.gif)

## HTML

```html
<body>
  <div class="dummy-content">Dummy content for scrolling</div>
  <div class="texts">
    <!-- たくさんのテキスト -->
    <p>...</p>
    <p>...</p>
    <p>...</p>
    <p>...</p>
    <p>...</p>
  </div>
  <div class="dummy-content">Dummy content for scrolling</div>
</body>
```

## `animation-timeline`ですべての要素に`blur`をかける

今回の肝は以下のコードのみです。

```css
@keyframes blur {
  from {
    filter: blur(2rem); /* お好みの量のブラー */
  }
  to {
    filter: blur(0);
  }
}

.texts p {
  animation-name: blur;
  animation-timeline: view();
  animation-range-start: cover 0%;
  animation-range-end: cover 50%; /* お好みのブラー終了位置 */
}
```

画面の外に近くなるほどブラーがかかり、画面の中に入り切るとブラーがなくなる、という仕組みです。
そのため 1 つの大きな要素（ヒーローイメージなど）は Progressive blur の挙動になりませんが、テキストや小さめの画像などであれば割とそれっぽく見えます。

今回は例として分かりやすく画面中央に来るまで要素にブラーをかけていますが、もし実際に使うとなったら 10% や 20% くらいの位置で良いと思います。
Salesforceでフローを作成しよう～日付項目が１年以内ならチェックをつける

Salesforceでフローを作成しましょう

今回は日付項目が１年以内ならチェックをつける　というフローです

チェックボックス
testA__c

日付項目
CloseDate

とします。

フローはこちらです

![フロー01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/bea6e037-ec02-e982-2308-16a53425a25f.png)


起動条件の数式はこちらです

![フロー02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/e1b3f86a-2eaa-2df2-4f4d-2bf9a48026da.png)




AND( ISCHANGED({!$Record.CloseDate}), {!$Record.CloseDate}+365>TODAY(), {!$Record.CloseDate}<TODAY() )


項目の更新はこちらです

![フロー０３.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/2f943d7b-f462-f477-0c4f-d259f21cecd8.png)
AWS CloudWatch Logs Insights を使おう！

# はじめに

AWSのサービスを利用しているとログを確認したい時があると思います。

CloudWatchのログは「CloudWatch ＞ ロググループ ＞ ログストリーム」から見ることができますが、「ログのインサイト」を使うともっと便利に検索することができてます。

# 注意点

:::note warn
CloudWatch Logs Insights クエリには、クエリされるデータの量に基づいて料金が発生します。大量のログをスキャンする場合は注意です！
:::

東京リージョン 2024/06/27時点
分析 (Logs Insights のクエリ) スキャンしたデータ：1 GB あたり USD 0.0076


詳しくはこちら

https://aws.amazon.com/jp/cloudwatch/pricing/


# メニュー

AWSのCloud Watchのサイドメニュー「ロググループ」の少し下にある「ログのインサイト」から見ることができます。

![スクリーンショット 2024-06-26 9.40.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261675/e226ca8e-75dd-81c7-9d0c-5ffc2179ad7a.png)


# 「Logs Insights」の画面

![スクリーンショット 2024-06-27 9.40.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261675/2d9b8c0c-2ec2-eca7-8fd9-708cefa3b494.png)


## １：ロググループを参照

見たいロググループをダイアログから選びます

## ２：ローカルタイムゾーン

デフォルトはUTCになっています。UTCである必要がなければローカルタイムゾーンに変更しましょう

## ３：範囲

:::note info
つまずきポイント！
:::

デフォルトは直近の１時間になっています。見たい範囲を選択しましょう
大量のログがある場合は広げすぎると利用料金に影響するので注意しましょう

## ４：クエリ

クエリを指定することでログを抽出・集計することができます。

## ５：クエリの実行

実行すると下部にクエリの結果が表示されます

## クエリ


```:初期クエリ
fields @timestamp, @message, @logStream, @log
| sort @timestamp desc
| limit 10000
```

コマンド（fieldsやsortなど）を” | ”パイプ文字でつないでクエリを組み立てます。


## 主なコマンド

### filter

条件で抽出します。

### fields

特定のフィールドを表示します。

### sort

結果を昇順（asc）降順（desc）で並べ替えます。

### limit

クエリ結果の最大件数を指定します。

### pattern

パターンを分析します。

### 詳しくは公式サイトを参照ください。

クエリ構文はこちら

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html

# 簡単な条件指定の仕方

クエリの文法が分かっていても、最初はログにどんなフィールドがあって、どんな値が入っているかわからないかもしれません。
そんな場合は、一旦「クエリの実行」ボタンを押してログを一覧表示してみましょう。

**何も表示されない場合は、範囲指定（「Logs Insights」スクショの③）を確認しましょう。**

ログの一覧が表示されたら、適当なログイベント”▶︎”マークをクリックして内容を表示しましょう。フィールドと値が表示されます。
ここに表示されるフィールドは、そのまま「filter」コマンドの条件に使うことができます。

### サンプル
![スクリーンショット 2024-06-30 21.28.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261675/73534c7d-2ff0-7b4e-6b9a-7024cd8acf69.png)


# 条件指定のクエリ例

フィールド：requestContext.eventType
値：DISCONNECT
を抽出条件に指定した例

```
fields @timestamp, @message, @logStream, @log
| sort @timestamp desc
| limit 10000
| filter requestContext.eventType = "DISCONNECT"
```

# ＠messageの中のJSON

大きなJSONでなければ、parseとかせずにそのまま指定することができます。
（filterコマンドの条件など）
階層があるものはドット指定します。

先ほどのサンプル
「requestContext.eventType = "DISCONNECT"」はJSONのキーと値です。

# 最後に

「ログのインサイト」は便利な機能ですが、範囲指定をしないと思うような結果を得られません。
そこさえ気をつければ、後は公式サイトを見ながら試行錯誤して必要な情報を得ることができるようになるでしょう。
みんなMicrosoft認定トレーナーになろうよ

## はじめに
2024年2月ごろにMicrosoft認定トレーナー（以降、MCT）という資格を取得したので、MCTってなに？どんないいことがあるの？を解説していきます。

MCTのバッジ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2475719/45eaed2d-6437-e74b-908b-de392f199329.png)

## MCTとは
Microsoftの公式のトレーナーとしてMicrosoftに関する研修の講師を担当することができる資格です（年に1回更新が必要）。
詳しくは後述しますが、**Azureが毎月$100まで無料**で使えたり、**OfficeやWindows、サーバ系OS（Exchange Server等）のライセンスが無料**で使えたりと、かなりメリットを感じています。

## 取得条件
気になるMCTの取得条件ですが、以下の条件を満たす必要があります。

1. AZ-104などの決められた資格を取得していること
2. Microsoftが認定した会社が開催している研修を受講し、「指導スキルの確認済み証明」を取得すること
私の場合は、[株式会社システムサポート](https://jp.linkedin.com/company/%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88?trk=public_profile_experience-item_profile-section-card_subtitle-click)の研修を2日間受け、最後にプレゼンテーションを行い、見事証明書を取得することができました。
3. [MCT 登録ツール](https://mcp.microsoft.com/Authenticate/MCT)から登録する

以上の3点です。思ったより簡単ですね！

参考

https://learn.microsoft.com/ja-jp/credentials/certifications/mct-enrollment

## MCTのメリット
先ほど解説した通り、MCTにはたくさんの特典があります。
- Azureの$100券/月
- Office、Windows OS、サーバOS、VSCodeなどMicrosoft系のライセンスが無料で使える
- 研修用ハンズオンラボが提供される
- Microsoft系試験割引MCT限定のバウチャー
- MOC（MS公式のカリキュラム資料）が閲覧できる
MCTはLearning Download Center（Lounge）からスライドなどをダウンロードできる。
- MCT Store
MCTしか買えないグッズが買える。私もMCTのTシャツ、自分の名前が書かれたカードなどを購入しましたw
- MOS（Microsoft Office Specialist）用の無料バウチャー

## MCTが教えられるコース

- 資格があるコース（AZ-104やAZ-305など）：その資格を持っていることが教えられる条件
- 資格が特にないコース（DP-080 Transact-SQLなどの「0」から始まる資格）：条件は特になくTSPが認めればだれでも教えられる
- 基礎編のコース（AZ-900など）：その資格を持っているかその上位資格を持っていることが条件

## Notice

- MCTとして年ごとの更新をするために、MTMから年1回以上研修を実施し、受講者からアンケートをもらう必要がある

### MTM（アンケート）
Metrics That Matter。

- 研修終わった後に受講者にやってもらうアンケートにて、トレーナーにつけられたスコアがそのトレーナーの評価になる。それをMTMの画面から確認できる
- まずMTMアカウントを作ってからMCT登録した方がいい
- アンケートのアクセス：Data collection > Classes > クラスを選択する

## 参考

https://learn.microsoft.com/ja-jp/credentials/certifications/mct-certification

https://qiita.com/carol0226/items/1a78d9c09857aa96a9c9
Livebook で API を構築する

## はじめに

Livebook バージョン 0.13.0 からの機能として、 Livebook で API が構築できるようになりました

https://github.com/livebook-dev/livebook/releases/tag/v0.13.0

面白い機能なので紹介していきます

ちなみに、 Web アプリは以前から実装、公開可能になっています



## Kino.Proxy による API 構築

新しいノートブックを開き、 Kino と Plug をインストールします

```elixir
Mix.install([
  {:kino, "~> 0.13"},
  {:plug, "~> 1.16"}
])
```

以下のコードを実行します

```elixir
Kino.Proxy.listen(fn
  %{path_info: ["hello"]} = conn ->

    conn
    |> Plug.Conn.put_resp_header("content-type", "application/text")
    |> Plug.Conn.send_resp(200, "Hello, Livebook")

  conn ->
    conn
    |> Plug.Conn.put_resp_header("content-type", "application/text")
    |> Plug.Conn.send_resp(200, "use /hello to greet")
end)
```

サイドメニューのロケットアイコンをクリックして "APP" パネルを開きます

"Configure" をクリックしてください

![スクリーンショット 2024-06-30 21.54.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/b12c2d15-3a8b-dd86-8fb3-8a5842306c36.png)

"Slug" に任意の値（API の URL の一部になる）を　入力し、 "Save" をクリックします

![スクリーンショット 2024-06-30 21.55.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/588d2cff-32b6-084f-a551-bb65bddc1dde.png)

"APP" パネル最下部の "Launch preview" をクリックします

![スクリーンショット 2024-06-30 21.54.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/b12c2d15-3a8b-dd86-8fb3-8a5842306c36.png)

これにより、ローカルで API が起動した状態になります

![スクリーンショット 2024-06-30 21.56.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/216d7eaf-9bf0-7bc0-197e-ba8406b52ae1.png)

## API の呼び出し

API は以下の URL で起動しています

```
http://<Livebook のルート URL>/proxy/apps/<Slug に入力した値>
```

Livebook をローカルホストの 8080 ポートで起動し、 Slug に `kino-proxy` と入力している場合は以下のようになります

```
http://localhost:8080/proxy/apps/kino-proxy
```

curl では以下のように呼び出すことが可能です

```sh
$ curl http://localhost:8080/proxy/apps/kino-proxy
use /hello to greet
```

API の実装コード内でパスが "hello" の場合を実装していました

呼び出すと、実装通りに動きました

```sh
$ curl http://localhost:8080/proxy/apps/kino-proxy/hello
Hello, Livebook
```

## まとめ

Livebook で API を実装し、呼び出すことができました

「何でもできる」 Livebook は、まだまだ可能性の塊のようです
pyenv + virtualenv で使うコマンド（初心者、大学生向け）

## pyenv + virtualenv で使うコマンド

この記事は普段、pythonを使用しているけど、仮想環境を使ったことがない人、またはpyenvを使うように研究室などで言われたけど、その後の環境管理に苦労している大学生向けの記事です。

まずは`pyenv virtualenv`のinstallについてですが、install方法はたくさんの方が説明されているので、以下リンク先の記事などを参考にインストールしてみてください。
https://qiita.com/ksato9700/items/5d9eba10fe6b8e064178

問題は、これをインストールしてから環境を管理する方法です。

## 普段使うコマンド
```terminal
pyenv install 3.x.x
```
まず、このコマンドはpython 3.x.xの環境をインストールするコマンドで、これを実行しても今使っているバージョンが変わったりしません。pyenvで使えるバージョンに追加されるだけです。

```terminal
pyenv virtualenv 3.x.x ****
```
次に、このコマンドを実行すると、3.x.xというバージョンで****という名前の仮想環境を構築することになります。
ここで初めて、仮想環境が構築されることになります。

```terminal
pyenv local ****
```
最後に、このコマンドによって、現在開いているディレクトリ下に対して、先ほど作成した仮想環境を適用したことになります。
つまり、ここで以下コマンドを打つと、****のpythonバージョンである3.x.xが表示されるというわけです。
```terminal
python --version
```
これでversionが変わっていれば、とりあえず仮想環境の設定は完了です！
```
pip list
```
としてみて、ライブラリが何も入っていないことが確認できるはずです！

:::note warn
## 仮想環境の確認
仮想環境は今開いているディレクトリでのみ有効です。
他のディレクトリを開いた場合は再度、仮想環境を設定する必要があリます。

具体的にいうと、現在いるディレクトリをdir1、その上のディレクトリがdir0とします。
```
cd ..
```
このコマンドでdir0に移動することになるので、ここで以下コマンドを実行すると
```
python --version
```
おそらくdir1のpython versionと変わっているのではないでしょうか。変わっていなくても`pip list`などで確認するとライブラリの中身が変わっているはずです。
このように`pyenv virtualenv`を使用する時は、自分がどの階層のディレクトリにいるか確認した上で仮想環境を作成するようにしましょう。
:::

## 他に使うコマンド

以下コマンドで現在、自分が作っているpyenvの環境全て、現在いる環境を確認することができます。
```terminal
pyenv versions
pyenv version
```

以下コマンドで、pyenvでインストールできる環境の一覧を確認することができます。
```terminal
pyenv install -list
```

以下のコマンドで、作成した環境を削除することができます。
```terminal
pyenv uninstall ****
```

---
以上です。
最近は、dockerを使うことも多くなってきたので、dockerの方法についても解説できたら記載したいと思います。
QiitaとGitHubを連携して記事を投稿してみた


# この記事は？
QiitaとGitHubを連携してから初めての記事投稿です。
ブラウザから編集するのもいいんですが、GitHubで管理してエンジニアっぽさをアップしたい！！
皆さんもQiitaとGitHubを連携してみてくださいー！

# 連携方法
Qiitaの公式ドキュメントを参考にやってみました。
連携～記事投稿・更新までを↓の記事にまとめました！

https://zenn.dev/kuuki/articles/qiita-article-managed-by-github

ご興味ある方はぜひご覧くださいー！！！
Leafletでマーカーアイコンを回転させたい！

## みなさんこんにちは。
さて、あいさつもくそもなく、いきなり本題に入りますね。

## なぜ回転させる必要があったか
これも私の開発している、[アメダス天気Viewer](https://nanka.cloudfree.jp/webapps/amedas/)という<font color="888888">(ウェザ◯ニュ◯スのパクリみたいな)</font>アプリで、観測点の風向風速を表現するときにどうしても風向きアイコンを回転させる必要があったからです。

↓これ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637649/112c35d9-fd31-f5e9-19fb-967908c86f3f.png)

## どうするか。
さて、こうなれば、Leaflet愛好家の愛読書。
[Leaflet公式のDocs](https://leafletjs.com/reference.html)を見てみます。
そして、試しに「rotat」(rotateやrotationなどもヒットさせるため)で検索をかけてみますが…。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637649/cab715c5-a4a2-ccf3-339f-6fea5f7ab6a7.png)
なにこれ。0件。

つまり、バニラのLeafletではアイコンを回転させることはできません。

### CSSで回転させる？
実はLeafletのアイコン、CSSで見た目を変更することもできます。
よって、CSSの`rotate()`で回転させてやれば、回転させられるのですが、まあめんどくさいっすよね。

### ライブラリがあった！

https://github.com/bbecquet/Leaflet.RotatedMarker

実はこんなライブラリがあるんです。
Leaflet Rotated Marker。

使い方はまじで簡単。

**`L.marker([48.8631169, 2.3708919], {rotationAngle: 45}).addTo(map);`**

これだけです。

`icon`とか書いてあるところにぶち込むだけです。

なんて簡単なのかしら。

## 使用例
```javascript
var icon = L.icon({iconUrl: 'source/wind'+getNum_wind(tempJson[element[0]][param_mapDraw][0])+'.png',iconSize: [30, 30], iconAnchor: [15, 15]});
eval("circle"+element[0]+" = L.marker(amedas_latlng, {rotationAngle: tempJson[element[0]]['windDirection'][0] * 22.5, pane: \"amedas\", icon: icon});");
```

使ってますよね。`rotationAngle:`。

tempJson[element[0]]['windDirection'][0]は風の向きを
`{0:"静穏",1:"北北東",2:"北東",3:"東北東",4:"東",5:"東南東",6:"南東",7:"南南東"…`
で表してくれているので、単純に22.5°をかけるだけでいけました。

以上です。

## まとめ
### ①
HTMLのヘッダー部分に
```html
<script src="https://cdn.jsdelivr.net/npm/leaflet-rotatedmarker"></script>
```
をぶちこむ。

### ②
マーカーのオプション(`L.marker(LatLng, {ここ！}`)に
```javascript
L.marker(LatLng, {rotationAngle: 45});
```
といれるだけ！

あら簡単。アイコンが回転しているではありませんか！

## デモ
デモというか、最初とか使用例とかで紹介したやつですけど、

https://nanka.cloudfree.jp/webapps/amedas/

の下の機能切り替えから「**風向風速**」を選んでいただくと実際に動作しているものが見られます。
【Rails】Rails6.0.3の環境構築

# はじめに
## 前提
事前に、Rubyのバージョンを`2.6.6`にしておく。

https://qiita.com/royal_straight_flush/items/f28363e78f20a8f4251f

## 目的
「[パーフェクト Ruby on Rails 【増補改訂版】](https://www.amazon.co.jp/%E3%83%91%E3%83%BC%E3%83%95%E3%82%A7%E3%82%AF%E3%83%88-Ruby-Rails-%E3%80%90%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88%E3%80%91-Perfect/dp/4297114623)」で扱っているものと同じバージョンにする。
※但し、現在は書籍に載っている環境構築通りにはいかない為、本記事に手順を記載する。



# 手順
## 作業ディレクトリ作成&移動
```terminal
mkdir ~/Desktop/rails6
```
```terminal
cd ~/Desktop/rails6
```


## 必要なgemをインストール
```terminal
gem install nokogiri -v 1.13.10 && gem install rails-html-sanitizer -v 1.5.0 && gem install net-imap -v 0.3.7 && gem install rails -v 6.0.3
```

## railsのバージョンを確認
```terminal
rails -v
```

:::note
`Rails 6.0.3`と表示されていること
:::


## プロジェクトの雛形を作成する
```terminal
rails _6.0.3_ new practice --skip-bundle
```

```terminal:実行結果
(base) test@TestnoMBP rails6 % rails _6.0.3_ new practice --skip-bundle

      省略

      create  tmp/storage
      create  tmp/storage/.keep
      remove  config/initializers/cors.rb
      remove  config/initializers/new_framework_defaults_6_0.rb
       rails  webpacker:install
Could not find gem 'rails (~> 6.0.3)' in any of the gem sources listed in your Gemfile.
Run `bundle install` to install missing gems.
```

:::note warn
上記の文が出ますが、次に進んでください。
:::


## Gemfileを編集する
```Gemfile:Gemfile
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '6.0.3' ⭐️
# Use sqlite3 as the database for Active Record
gem 'sqlite3', '1.5.4' ⭐️

省略

# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '5.4.4' ⭐️

省略

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers', '= 5.3.0' ⭐️
end
```

`rails`, `sqlite3`, `webpacker`, `webdrivers`のバージョンを、それぞれ上記の通り指定します。（⭐️は付けないでくださいw）

## アプリケーションディレクトリに移動&`bundle install`
```terminal
cd practice
```
```terminal
bundle install
```

※ 少し時間がかかります。※5分程度

## Webpackerをインストール
```
rails webpacker:install
```

## Railsアプリケーションの動作確認
```
rails s
```
http://localhost:3000 にアクセスし、ウェルカム画面が表示されればOK。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689074/43447f7f-4292-fd1a-19e6-005430908e12.png)



:::note
完了
:::
batファイル


streamlit
```bat
@echo off
REM ネットワークドライブとしてマウント
net use Z: \\LS410D3B6\PrivateDrive\Programming\Python\DevelopingEnv_streamlit

REM ネットワークドライブに移動
cd /d Z:

REM Streamlitアプリケーションを実行
streamlit run myApp.py

REM ネットワークドライブのマウント解除
net use Z: /delete

REM コマンドプロンプトウィンドウを開いたままにする
pause


```

jupyter
```bat
@echo off
REM ネットワークドライブとしてマウント
net use Z: \\LS410D3B6\PrivateDrive\Programming\Python\DevelopingEnv_jupyter

REM ネットワークドライブに移動
cd /d Z:

REM Jupyter Labを起動
jupyter lab

REM ネットワークドライブのマウント解除（この行は実行後に手動でJupyter Labを終了するまで実行されない）
net use Z: /delete

REM コマンドプロンプトウィンドウを開いたままにする
pause

```
SSR対応のNext.jsをAWS環境にデプロイするためのサービス

# はじめに
SSRを考慮したNext.jsアプリケーションをAWSにデプロイする際には、さまざまな選択肢があります。　　
バックエンドでは、ECSやEKSが一般的な選択ですが、フロントエンドの選択はより複雑です。
ここでは、一般的な構成を3つ紹介します。

# 構成図
![スクリーンショット 2024-06-30 21.59.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263017/33f95341-c1fc-35e1-8b35-7494afcd5c55.png)

# 1. ECS Fargate
## メリット:
- 大規模なアプリケーションに適している
- 柔軟性が高く、カスタマイズが容易
- コンテナ技術により、一貫した開発・運用環境を提供

## デメリット:
- セットアップが比較的複雑
- 管理の負担が大きい
- コストが高くなる可能性がある

# 2. (CloudFront+)Amplify
主に、Amplifyのメリットデメリットについて後述してます
CloudFrontは、導入しといたほうが無難で良いです

## メリット:
- セットアップが非常に簡単
- AWSの詳細な知識がなくても使いやすい
- CI/CDが組み込まれている
- 自動スケーリングとパフォーマンス最適化

## デメリット:
- カスタマイズ性に制限がある
- AWSに特化しているため、他のクラウドへの移行が難しい
- 大規模プロジェクトではコストが高くなる可能性がある

# 3. CloudFront + Lambda@Edge + S3
## メリット:
- 高度なカスタマイズが可能
- コスト効率が良い（使用量ベースの課金）
- サーバーレスアーキテクチャによる運用の簡素化

## デメリット:
- セットアップが複雑
- Lambda@Edgeにはサイズ制限がある
- AWSの深い知識が必要

# 4. 選択の指針
- 簡単に始めたい、または開発速度を重視する場合は **(CloudFront+)Amplify**
- 大規模で複雑なアプリケーション、または既存のコンテナ化されたアプリケーションがある場合は **ECS Fargate**
- 細かいカスタマイズが必要で、コスト最適化も行いたい場合は **CloudFront + Lambda@Edge + S3**

# 5. まとめ
これらの選択肢の中から、プロジェクトの規模、チームのスキルセット、開発のスピード、そして長期的な保守性を考慮して、最適なものを選んでいただけたらと思います。
どの方法も一長一短があるので、プロジェクトの要件に最も合うものを選択することが重要です。

# ※補足: CloudFront + Lambda@Edge + S3

## Next.jsアプリケーションコード：
- アプリケーション全体（ページ、コンポーネント、APIルートなど）はLambda@Edge関数にデプロイされます
- これにより、サーバーサイドレンダリングや動的ルーティングが可能になります

## Lambda@Edge:
- CloudFrontからのリクエストを受け取り、Next.jsサーバーを実行します
- getServerSidePropsを含む動的ページをレンダリングします
- APIルートのリクエストを処理します

## S3:
- 静的アセット（.next/staticディレクトリの内容）を保存します。これには、JavaScriptバンドル、CSS、画像などが含まれます
- 静的にレンダリングされたHTMLページ（可能な場合）

## CloudFront:
- ユーザーからのリクエストを受け取り、適切な場所（Lambda@EdgeまたはS3）にルーティングします
- 静的アセットのリクエストはS3に直接転送されます
- 動的ページやAPIリクエストはLambda@Edgeに転送されます

## デプロイプロセス
- Next.jsアプリケーションをビルドします（npm run build）
- 生成された.nextディレクトリとサーバーコードをLambda@Edge関数にパッケージ化します
- .next/staticディレクトリの内容をS3バケットにアップロードします

### この方法の利点:
- サーバーサイドレンダリングと静的アセット配信の両方を効率的に行えます
- getServerSidePropsを使用するページも問題なく機能します
- スケーラビリティが高く、サーバー管理が不要です

### 注意点:
- Lambda@Edgeには制限（関数サイズ、実行時間など）があるため、大規模なアプリケーションでは注意が必要です
- コールドスタート時のレイテンシーが発生する可能性があります

### CI/CD:
- 開発者がコードを変更（getServerSideProps を追加など）
               ↓
- コードを Git リポジトリにプッシュ
               ↓
- CI/CD パイプラインがトリガーされる
               ↓
- アプリケーションのビルド
               ↓
- Lambda@Edge 関数の更新とデプロイ（Lambda@Edgeのコードを直接修正する必要はないが、アプリケーション全体を再ビルドして再デプロイする必要がある）
               ↓
- CloudFront ディストリビューションの更新
TypeScriptのリテラル型・タプル型・ユニオン型の整理

りあクト！で学んだ内容を自分の学習メモ的にまとめます。
内容に間違いがあったり、正確じゃない表現の場合はご指摘いただけると幸いです。



リテラル型：型の定義を一意性のあるものにする（type Kで文字列の'kumazaki'を定義したら、Kの型を適用するオブジェクトはkumazakiと完全一致する必要があるし、再代入もできない）

タプル型：型の定義で複数の型を組み合わせるもの。type Aについて[string,number]と定義したら、Aの型を適用するオブジェクトは「文字列、数値」の順と組み合わせで定義されなくてはならない。

ユニオン型：複数の型のうちどれかを適用するもの。type Bについて string | number と定義したら、Bの型を適用するオブジェクトは文字列か数値のどちらかにする必要がある。

これらを組み合わせることもできる。
リテラル型のユニオン型であれば、一意性のある複数の値のうち、どれかにあてはまればいいものになる。

TypeScriptの構文的には
オブジェクトの定義時にas constを加えればオブジェクトの定義と同時にリテラル型のユニオン型として定義できる。
const A = ['abc', 'def', 'ghi']as const;
とすることで、Aは一意性のある'abc''drf''ghi'のいずれかにあてはまればいいものとなる。

一言でまとめると、
「オブジェクトの値を一意性のある再代入不可なものにしたいときは as const を加える」