OmniAICreator/Qiita-1.07M huggingface dataset:
基本情報技術者試験　受験計画

# はじめに
こんにちは、水野です。


自分の友人が内定先から基本情報技術者試験を受験するように言われているという話を聞き
丁度いいので、自分も資格取得のために勉強を進めていこうかなと思った次第です。

こちらに自分の計画を掲載し、結果は後日感想と合わせて報告させていただこうと考えています。

## ざっくり計画
受験日：2025年1月17日(金) 
基本情報技術者試験(FE)科目A・科目B
※こちら記入時に並行して申し込みを済ませました。

１２月から勉強を始めると１か月半猶予があるため、
習慣化を念頭に置き、以下の教材を用いて勉強を進めていこうと思います。

【自分が確実に確保できる時間】
・出勤時間（往復で約３時間）
・土日の数時間


【使用する教材】
・YouTube　[【基本情報技術者試験YouTuber】すーさん](https://www.youtube.com/@kihonzyouhou)
・過去問　[過去問道場](https://www.fe-siken.com/fekakomon.php)
・参考書　[キタミ式イラストIT塾 基本情報技術者 令和06年](https://www.amazon.co.jp/dp/4297138077?tag=nokonokonoko0-22&linkCode=ogi&th=1&psc=1
)

## 少し具体的に
勉強の段階を３段階に分けようと思います。



### ①ざっくりインプット期（～12/13）
まずは勉強の習慣づけ目指して、完璧を目指すというよりは
試験に出てくる単語に慣れていく。
YouTubeの流し聴きでまずは意味を理解していく。

### ②科目A　インプット＋アウトプット期(~12/27)
教材によって説明が異なることは珍しくないと思うので、
この時期から参考書も読み込み、過去問を活用してインプットの質を高めていきつつ
「こんな形で問題出てくるんだな～」と基本情報技術者試験自体の対策も進めていきます。

### ③科目B　インプット＋アウトプット期(~1/8)
科目Bの内とアルゴリズム問題はひたすら問題を解くことを重視して
考え方や問題自体に慣れていきます。

移動中での勉強が難しいので、年末年始の休みが多い時期に一気に済ませようと思います。

### ④アウトプット期（～試験当日まで）
今までやった過去問を周回して、「あ～この問題ね」みたいな状態になることを目標に周回していきます。

# 最後に
ヘルプデスク業務のためユーザから理不尽に当たられたりすることもあり、
「今日は疲れたから勉強しないでおこう…」、みたいな未来の自分が容易に想像がつきます。
なので、帰宅後に勉強時間を設ける等はあえてしませんでした。

この計画をもとに勉強を進めていき、途中で修正したこと、
進めていくことで分かったことを結果を踏まえて
投稿させていただければと思います。

資格取得を検討されている方がいれば一緒に頑張っていきましょう。

以上、水野でした。
変数や関数の命名について

# はじめに
こんにちはプログラマー2年目の塚田と申します。
今回はプログラミングをするにあたっての変数や関数の命名について書いてみようと思います。

プロジェクトによるかもしれませんが、設計の段階である程度はすでに決まっているものかとは思います。
ただ、即席で作るとなったときにいざ考えてみると意外と難しいものです。

# 初めて見る人でもわかるように
まず、自分が書いているコードは自分だけが見るものではないということ。
後々ほかの方がコードをいじるとなったときに、どんな理由で定義しているのか。わかりづらいと相手にとっても自分にとってもデメリットしかありません。
get,fetch,create,deleteなどの**動詞**から始めることを意識すると、より明確になるかもしれません。

# コメントをつける
コメントはとても効果的かと思います。
もちろん変数名だけでわかるならそれに越したことはないですが、
関数では一言で表すのは難しいかと思います。
必要な引数は？結果何が行われるのかコメントをつけるだけで読み手側からするととても楽になると考えます。


# おわりに
私も開発の段階ではレビューの指摘で何度か注意された経験があるので、今後気を付けるためにも今回このような記事を書きました。
今後も体験談などを書いていこうと考えているのでぜひ見ていただけると幸いです。

以上、塚田でした。
Entity Framework CoreでSQL Serverに接続する【準備編】

# 【はじめに】
こんにちは。藤原です。

最近は .NET Webアプリケーション開発でDBフレームワークである EntityFrameWorkCore(以下、EFCoreと記載)を使用していました。

今回は勉強中の初学者の方やこれから開発で使うぞ～という方に向けて、実際にプログラムからDBへ接続するまでの過程を記していこうと思います。(何Partかに分けて記載します)
まずは【環境構築-DB準備編】から\:memo:

:::note info
本記事は以下を満たしている方向けです。
・簡単なプログラミング経験
・SQLの基本概念を把握
・SSMS(SQL Server Management Studio)の使用経験
・VisualStudioの使用経験
:::

# 「EntityFrameWorkCore」とは
ざっくりいうと...
「データベースを取り扱うためのフレームワーク」です。

.NETアプリケーションにおいて、データベースとのやり取りをシンプルにしてくれるフレームワークで、採用することで開発者がよりビジネスロジックに集中して開発できるように手助けしてくれます。

簡単に説明しましたが、より詳しく知りたい方は公式の説明を読むことが一番の理解になります。

[Entity Framework Core Microsoft公式ページ](https://learn.microsoft.com/ja-jp/ef/core/)

# 今回の目標
・DB接続の前準備
・ローカルDB作成
・SqlClientのインストール

# DB接続の前準備

それではEFCoreの接続を試すために、まずはDB接続の前準備からです。

:::note info
前提：
今回はお試し用でプロジェクトテンプレート「Windowsフォームアプリ」を作成してあります。
:::

・SQL Server オブジェクト エクスプローラーからサーバマークを選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/2bdccc69-ea15-37a4-a19a-b14ecfc24a6b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/3f09e1cd-4d40-97fb-2654-682689ca6f2d.png)

・ローカルDBを選択し「接続」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/44633fe5-6bd0-85f1-1501-5bed900c2c1a.png)

ここまでやるとオブジェクトエクスプローラーにローカルDBが表示されるはずです！
これでローカルDBへ接続する準備が1つ完了です。

# ローカルDB作成

次に接続先DBの準備です。
といってもUIをポチポチしていくだけで簡単なので身構えなくてOKです！

・新しいデータベースを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/2dccf667-5a02-0752-66d8-cacec80c85eb.png)

・データベース名を入力
今回は検証なので何でもいいですが、きちんと開発する際は拘っていきましょう🫠
※「TestDB」としました。
DB名を入力したらOKボタンを押してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/758487f4-dd77-4205-d8c7-39efb2e8b7c5.png)

・DB作成完了
はい。これだけです！
実際に開発をするときには容量、権限、照合順序...etc もっと詳細な設定が必要ですが、今回の目的としては十分ですね。

# SqlClientのインストール

では次に、プロジェクトに「SqlClient」をインストールします。

「SqlClient」は、SQL ServerとEFCoreを通じての接続・やり取りを行うための必要なドライバ（プロバイダー）です。

EF Coreはデータベースとの接続を管理するために「プロバイダー」を使用します。
SqlClientは、SQL Server用のプロバイダーとして機能し、EF Coreを介してSQL Serverデータベースにアクセス出来るように仲介してくれます。

・Nugetパッケージ管理より「SqlClient」と検索するとライブラリがヒットすると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/bf922745-5e4c-a2cb-8537-b292a48f9211.png)

インストール済みを実行し、インストール済みに表示されていれば無事にプロジェクトに導入成功です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/3ab8d976-f856-ada3-1792-0ed71ec3d26e.png)

# 【まとめ】
今回はEFCoreを使ってC#コードでDBを取り扱うための【環境構築-DB準備編】でした。
次回は実際にソースコード上からDBへ接続を試してみようかと思います！

ここまで読んでくださりありがとうございました！

以上、藤原でした。
【AWS資格】AWS Certified Advanced Networking（ANS）を2回受けて合格した話

# はじめに
aws AWS Certified Advanced Networking(ANS)を2024/9に1回落ちて、
2024/10に2回目を受けてなんとか合格しました。

これからANSに合格したい！というかたに向けて勉強方法を残しておきます。

# 私のスペック
ANS以外に資格として持っているのは以下だけです。
- aws AWS Certified Solutions Architect 2024/4月取得
- 応用情報

IT業界は丸々3年経過した感じで、この1年はaws周りの設計とかをしてます。
（正直、1年やっていたところで、試験にそれほど強くなるかと言われると、関係ないと思います）


# 合格した勉強方法
1回目に落ちた時の点数は711点だったので、目標の750点に2~3問足りませんでした。
その時は以下1と2を勉強をして臨みました。

> 1. Udemyの講座：Practice Exam - AWS Certified Advanced Networking Specialty
     すべての選択肢を読み込み、なぜ不正解か？を理解するまでやり込み
> 2. blackbeltの資料の以下２週ほどさっと読み込み
    [Elastic Load Balancing](https://pages.awscloud.com/rs/112-TZM-766/images/AWS-Black-Belt_2023_Elastic-Load-Balancing_0525_v1.pdf "Elastic Load Balancing")
    [cloudWan](https://pages.awscloud.com/rs/112-TZM-766/images/AWS-Black-Belt_2022_AWS_Cloud_WAN_Part01_1125_v1.pdf)
    [netwokFirewall](https://pages.awscloud.com/rs/112-TZM-766/images/BlackBelt202106_AWS_Network_Firewall_Basic.pdf)
    [cloudwan](https://pages.awscloud.com/rs/112-TZM-766/images/20190730_AWS-BlackBelt_Amazon_CloudFront.pdf)   
> 3. [awsホワイトペーパ（network接続）](https://docs.aws.amazon.com/ja_jp/whitepapers/latest/aws-vpc-connectivity-options/welcome.html)
＃左章立ての全てを読み込み、各構成を頭に叩き込みました。

1.2をやって臨んだ結果、惜しくも不合格になってしまった際の振り返りとして
> - こんなサービスは知らない。ということはなかった（1回目の勉強範囲で網羅性はOKだった）
> - transitGatewayやNLB・ALB周りのベストプラクティスが頭に入りきっていない

ということで、今一度ベストプラクティスを頭に叩き込むため、3.のネットワークに関するホワイトペーパを2週ほど読みました。

結果、780点となんとか合格することができました。

# 勉強に費やした時間
大体100時間くらい？は勉強したかなと思います。
- 1のUdemyに約50時間
- 2のblacbeltに約10時間
- 3のホワイトペーパに20時間

# 最後にアドバイス
アドバイスというと偉そうですが、まとめると勉強方法としては、以下がいいかなと思いました。
- 問題集は一つで良い
- aws公式が出しているホワイトペーパやblacbeltの構成を頭に叩き込むことが大事

<br>
この記事がANSを受ける方の参考に少しでもなればと思います。
何か質問とかありましたら、コメントください。
挫折しない習慣の作り方

## はじめに
:::note info
この記事はLITALICO Engineers Advent Calendar 2024 カレンダー1の1日目の記事です
:::

2022年に新卒で入社したエンジニアの @taka-fujita です。
日々継続して何かを行うことが苦手ではなく（日記・読書・筋トレを年単位で続けています）、同僚から「どうして挫折せずに色々続けられるのか」と聞かれたことをきっかけに、自分なりに習慣の作り方を整理してみたので、今回記事にしてみようと思います。

習慣を身につけるのに才能や適性は必要ないと感じているので、習慣作りに挫折した経験がある方も、ぜひ本記事に書いてあることを試してもらえたら嬉しいです。


## 本記事の内容

- 習慣はどのようにして身につくのか
- 挫折せずに続けるためのポイント
    - 成果を出すことと、習慣を身につけることは分けて考える
    - 時間ではなく、行動をトリガーにする
    - ハードルを下げ切る

## 習慣はどのようにして身につくのか

習慣が身についている状態とは、「その行動をストレスなく処理できている状態」だと考えています。
例えば、「朝起きる → シャワーを浴びる → ドライヤーで髪を乾かす」といった、深く考えずとも自然に行える行動は、習慣が身についている分かりやすい例です。

習慣を身につけるには、その行動を無意識に行える（または、行わないことに違和感を感じる）状態を作ることが必要です。
この状態は短期間で作れるものではなく、数週間かけて脳に「毎日繰り返し行うべき動き」として刷り込むことで作られるものになります。

そのため、習慣を身につけるには「継続」が重要になってきます。
ただ、重要なのは繰り返し行うべき動きだと脳に刷り込むための継続であり、定量的な目標（マイルストーン）を達成し続ける継続ではありません。

「毎日1時間の運動」「毎日50ページの読書」といった具体的な目標を掲げると、達成の困難さからモチベーションが落ちてしまい、いつからか「1分も運動しない」「1ページも本を読まない」となるリスクが高まります。
こうなってしまうと、脳に刷り込みが完了できず、挫折に繋がってしまいます。

習慣を身につけるには、「100%でなくても良いから、0にはしないように」と、ハードルを下げて負担を感じない範囲で続けるのが良いです。
数週間経った時には、習慣化したかった行動を自然な流れで行うことが出来るようになっています。

## 挫折せずに続けるためのポイント

小さくとも続けることが大事であることを伝えたので、次はどのようにしたら続けられるのかについてまとめます。
続けていく上で大切となるポイントは以下の3つです。

- 成果を出すことと、習慣を身につけることは分けて考える
- 時間ではなく、行動をトリガーにする
- ハードルを下げ切る

### 成果を出すことと、習慣を身につけることは分けて考える

習慣を身につけたいと思った時、成果を出すことが目的であり動機となることは多いと思います。
例えば、「読書の習慣を通して仕事で成果を上げたい」であったり「筋トレの習慣を通して理想の身体になりたい」などです。

しかし、習慣が身に付いていない状態で、成果を出すことを意識すると挫折する可能性が高まります。
なぜなら、求めている成果までのギャップを測り、埋めるための手段として、定量的な目標を設けることが有効的だからです。
定量的な目標を設定するリスクについては、先にまとめたように達成の困難さからモチベーションを下げてしまうことが挙げられます。

また、習慣を身につけることは簡単ではないため、最初は「習慣を身につけること」そのものを目的とする方が良いです。
まずはしっかりと習慣を身につけ、その後に成果を出すための具体的な定量目標を設けるという流れが良いと思います。


### 時間をトリガーにせず、行動をトリガーにする

脳に刷り込みを行う上で、時間をトリガーとするのは難しいと感じています。
これは、仕事や友人との予定が入ったり、電車の遅延や交通渋滞に巻き込まれたりと、日々同じスケジュールで動くことが難しいであろうためです。
同じ時間に決まった動きをしようと思っても、日々異なるスケジュールにより、取り組む機会そのものがなくなってしまっては継続は困難になります。

一方で、行動をトリガーとするのは、自身の意思決定のみに影響されることが多いので、継続することの障害が少ないように思います。

また、既存の習慣をトリガーとして新たな習慣を作れるのもメリットです。
例えば、「シャワーを浴びる → ドライヤーで髪を乾かす」という既存の習慣に「本を読む」を加えて、「シャワーを浴びる → ドライヤーで髪を乾かす → 本を読む」とするイメージです。
既存の習慣は日々行うものになるため、これらをトリガーにすれば、習慣にしたい取り組みの機会がなくなることは滅多にありません。

外的な要因による阻害を受けにくく、取り組む機会を安定して得られるという観点から、時間ではなく行動をトリガーとするのが良いと考えています。

### ハードルを下げ切る

ハードルはとことん下げ切ってしまって良いです。
『習慣はどのようにして身につくのか』でも書きましたが、0にはしないようにするのが一番大切なことになります。
そのため、習慣にしたい取り組みの「最初の動き」までハードルを下げて良いです。

最初の動きとは具体的にどういったものか、読書を例に説明します。

「今この瞬間に本を読んでください」と言われたとき、皆さんはどのような動きを取りますか？
読みたい本を考えるといった、思考的な部分ではなく、具体的な動きについてです。

個人的には、本を読むための最初の動きは「本を持つこと」だと考えています。
そのため、読書を習慣としたいとき、まずは毎日本を持つことだけしてみると良いです。
本を持った上で、本を読みたい気分であれば読めば良いですし、気分でなければ読まなくても大丈夫です。

読みたい気分の時だけでも読むようにすることで、本を持つ習慣が身についたときには、本を持つことをトリガーに本を読むことの抵抗が少なくなっているはずです。
その流れで、本を読むことを継続すると、読書の習慣が身に付くようになります。

いくらか時間はかかるかもしれませんが、ハードルを下げ切って0にせずに継続していくことで、習慣は身に付きます。
自分に甘くて全く問題ないので、長い目で続けていくようにしてみてください。


## おわりに
今回、習慣を身につける上で大事となるポイントを整理しつつ、挫折しないで習慣を作る方法についてまとめてみました。

習慣を身につけることは時間はかかりますが、決して才能や適正が必要なわけではないと感じています。
本記事が、今までに習慣作りに挫折してしまった経験のある方の役に立てば嬉しく思います。

自分に優しく、ゆるゆる習慣作りを楽しんで行きましょう〜！

明日は @yuichirofujita さんの記事になります！
是非明日の記事も楽しんでいってください〜
セルビア語係り受け解析モデルgpt2-large-serbian-uposリリース

Tanja Samardžić, Mirjana Starović, Željko Agić, Nikola Ljubešić[『Universal Dependencies for Serbian in Comparison with Croatian and Other Slavic Languages』](https://doi.org/10.18653/v1/W17-1407)を横目に、セルビア語係り受け解析モデル[gpt2-large-serbian-upos](https://huggingface.co/KoichiYasuoka/gpt2-large-serbian-upos)を試作してみた。Google Colaboratoryで動かしてみよう。

```
!pip install esupar
import esupar
nlp=esupar.load("KoichiYasuoka/gpt2-large-serbian-upos")
doc=nlp("Обожаваоци из региона клицали су Ролинг Стоунсима у понедељак у Црној Гори")
import deplacy
deplacy.serve(doc,port=None)
```

「Обожаваоци из региона клицали су Ролинг Стоунсима у понедељак у Црној Гори」を係り受け解析してみたところ、私(安岡孝一)の手元では以下の結果が出力された。

```
1	Обожаваоци	_	NOUN	_	Case=Nom|Gender=Masc|Number=Plur	4	nsubj	_	_
2	из	_	ADP	_	Case=Gen	3	case	_	_
3	региона	_	NOUN	_	Case=Gen|Gender=Masc|Number=Sing	1	nmod	_	_
4	клицали	_	VERB	_	Gender=Masc|Number=Plur|Tense=Past|VerbForm=Part|Voice=Act	0	root	_	_
5	су	_	AUX	_	Mood=Ind|Number=Plur|Person=3|Tense=Pres|VerbForm=Fin	4	aux	_	_
6	Ролинг	_	PROPN	_	Case=Dat|Gender=Masc|Number=Sing	4	obj	_	_
7	Стонсима	_	PROPN	_	Case=Dat|Gender=Masc|Number=Plur	6	flat	_	_
8	у	_	ADP	_	Case=Acc	9	case	_	_
9	понедељак	_	NOUN	_	Animacy=Inan|Case=Acc|Gender=Masc|Number=Sing	4	obl	_	_
10	у	_	ADP	_	Case=Loc	12	case	_	_
11	Црној	_	ADJ	_	Case=Loc|Definite=Def|Degree=Pos|Gender=Fem|Number=Sing	12	amod	_	_
12	Гори	_	PROPN	_	Case=Loc|Gender=Fem|Number=Sing	4	obl	_	SpaceAfter=No
```

![sr-ec.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428317/396ca3f9-0dab-ad4f-9972-eed4492ae57a.png)

「Црној」の品詞はPROPNの方が適切な気がするが、まあ元々が形容詞なので仕方ないだろう。「клицати」は本来は自動詞なので、複数与格の「Ролинг Стоунсима」をobjとみなしていいかどうかは議論の余地がある。同じ文のラテン文字表記「Obožavaoci iz regiona klicali su Roling Stounsima u ponedeljak u Crnoj Gori」も、係り受け解析してみよう。

```
doc=nlp("Obožavaoci iz regiona klicali su Roling Stounsima u ponedeljak u Crnoj Gori")
deplacy.serve(doc,port=None)
```

私の手元では、以下の結果が出力された。

```
1	Obožavaoci	_	NOUN	_	Case=Nom|Gender=Masc|Number=Plur	4	nsubj	_	_
2	iz	_	ADP	_	Case=Gen	3	case	_	_
3	regiona	_	NOUN	_	Case=Gen|Gender=Masc|Number=Sing	1	nmod	_	_
4	klicali	_	VERB	_	Gender=Masc|Number=Plur|Tense=Past|VerbForm=Part|Voice=Act	0	root	_	_
5	su	_	AUX	_	Mood=Ind|Number=Plur|Person=3|Tense=Pres|VerbForm=Fin	4	aux	_	_
6	Roling	_	PROPN	_	Case=Dat|Gender=Masc|Number=Sing	4	obj	_	_
7	Stounsima	_	PROPN	_	Case=Dat|Gender=Masc|Number=Plur	6	flat	_	_
8	u	_	ADP	_	Case=Acc	9	case	_	_
9	ponedeljak	_	NOUN	_	Animacy=Inan|Case=Acc|Gender=Masc|Number=Sing	4	obl	_	_
10	u	_	ADP	_	Case=Loc	12	case	_	_
11	Crnoj	_	ADJ	_	Case=Loc|Definite=Def|Degree=Pos|Gender=Fem|Number=Sing	12	amod	_	_
12	Gori	_	PROPN	_	Case=Loc|Gender=Fem|Number=Sing	4	obl	_	SpaceAfter=No
```

![sr-el.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428317/31468d69-bc49-86eb-ab6e-56d89566ef34.png)

キリル文字とラテン文字とで、全く同じ係り受け構造になっている。まあ、同じになるようトークナイザを頑張って作り込んだので、ある意味うまくいったと言えるだろう。
Windowsの仮想メモリ（ページングファイル）無効化

#### PowerShell 版
```PowerShell:PowerShell：管理者
# ページングファイルが自動管理されているか確認（ True なら自動管理）
(Get-WmiObject -Class Win32_ComputerSystem).AutomaticManagedPagefile

# WMI からは不可・CIM を使う
# CIM インスタンスを取得
$cimInstance = Get-CimInstance -ClassName Win32_ComputerSystem
# プロパティを変更（システムによる自動管理を無効に）
$cimInstance.AutomaticManagedPagefile = $false
# 設定を反映
$cimInstance | Set-CimInstance

# 現状のページングファイルを確認
Get-WmiObject -Class Win32_PageFileSetting
# すでに作成されたページングファイルを削除
(Get-WmiObject -Class Win32_PageFileSetting).Delete()

# 詳細設定タブの「仮想メモリ」枠内を確認する
# ページングファイルなし になっていればОK
SystemPropertiesPerformance.exe
```

#### CMD 版
　wmic がプレインストールされなくなったのは 24H2 以降なのかな？
```cmd:CMD：管理者
:: wmic をインストール（うまくいかない場合は PowerShell から実行してください）
PowerShell DISM.exe /Online /Add-Capability /CapabilityName:WMIC
:: DISM.exe /Online /Add-Capability /CapabilityName:WMIC~~~~

:: ページファイル無効化
wmic pagefileset list
wmic computersystem set AutomaticManagedPagefile=false
wmic pagefileset DELETE
wmic pagefileset list full
```

#### 参考
・[利用可能なオンデマンド機能](https://learn.microsoft.com/ja-jp/windows-hardware/manufacture/desktop/features-on-demand-non-language-fod?view=windows-11#wmic)
・[[Full Guide] How to Get Back the Wmic Feature on Windows 11](https://www.partitionwizard.com/news/get-back-the-wmic-feature-on-demand-on-windows-11.html)
・[Windows 設定のコマンド起動](http://wingsan.web.fc2.com/WinCom/index.html)
AWS VPC NATゲートウェイとNATインスタンスの違いは

**NATゲートウェイとNATインスタンスの違いについて解説します：**

### 1. **NATゲートウェイ**
AWSが提供する**マネージドサービス**で、プライベートサブネット内のリソースがインターネットにアクセスするために使用されます。  

https://qiita.com/SMZPP/items/289713bdd2d5124767a6

#### 特徴：
- **可用性**: 高可用性が自動で設計されており、AWSがバックエンドで管理します。
- **パフォーマンス**: スケーラブルで、高いスループット（5Gbps～45Gbps）。
- **管理負担**: 管理不要。ソフトウェアやOSの更新が不要です。
- **コスト**: 使用量に基づいた従量課金。利用コストはNATインスタンスより高い場合があります。
- **IPアドレス**: Elastic IPが割り当てられ、動的にスケーリング。

#### 適用ケース：
- 高いパフォーマンスと可用性が必要な場合。
- 管理負担を最小限に抑えたい場合。

---

### 2. **NATインスタンス**
Amazon EC2インスタンスを使って、プライベートサブネット内のリソースにインターネットアクセスを提供します。
#### 特徴：
- **可用性**: 高可用性は設計次第で、ユーザーが冗長化を設定する必要があります。
- **パフォーマンス**: インスタンスのタイプに依存。大きなトラフィックがあるとスループットがボトルネックになる可能性があります。
- **管理負担**: OSやソフトウェアの更新を自分で管理する必要があります。
- **コスト**: EC2インスタンス料金が発生するため、小規模なトラフィックでは安価に済むことがあります。
- **IPアドレス**: Elastic IPまたはパブリックIPを割り当てて使用します。

#### 適用ケース：
- コストを抑えたい場合（小規模なトラフィック）。
- 高度なカスタマイズが必要な場合（特定のルールやスクリプトを設定するなど）。

---

### 3. **比較まとめ**

| 特徴                      | NATゲートウェイ             | NATインスタンス              |
|---------------------------|---------------------------|-----------------------------|
| **可用性**                | 高可用性（AWS管理）       | 冗長化を自分で設定           |
| **スループット**          | 高スループット（最大45Gbps）| インスタンスのスペックに依存 |
| **スケーラビリティ**      | 自動スケーリング          | 手動でインスタンスを増加      |
| **管理負担**              | 少ない                    | 高い                         |
| **コスト**                | 使用量に比例              | 小規模トラフィックで安価      |
| **用途**                  | 標準的なケース            | カスタマイズが必要な場合      |

---

### 4. **選択のポイント**
- **シンプルさとパフォーマンス**を求める場合 → **NATゲートウェイ**  
- **コスト削減やカスタマイズ**が必要な場合 → **NATインスタンス**  

どちらを選択するかは、トラフィックの規模、可用性要件、管理負担の許容度、コストなどに依存します。
Alacritty+OrbStack+NixOSで再現性の高いMac環境を!

こんにちはnyahahanohaです。
私は学校から指定のPCがMacなので4年ほどMacを使っているのですが、Linux信者のためMacの環境に四苦八苦していました。
そしてNixOSに出会ってからはbrewの滅茶苦茶な環境に嫌気がさしていました。
MacにもNixをinstallできるのでNixでの環境整備を行ったりしてみたのですが、Mac対応のpackageの少なさにほとんど移行できないこと気づきました。

そこでOrbStackを利用してNixOSをMac内に軽量VMとして導入して、そちらに本環境を移行することにしました。

# Version
|soft|version|
|-|-|
|Alacritty|0.14.0|
|OrbStack|1.8.2|
|NixOS|25.05|

# OrbStackの構築
brewでOrbStackをinstallしてください。
`% brew install orbstack`
軽量VMを構築します。
`% orbctl create -a arm64 nixos ${MACHINE_NAME}`
このVMが1台目でなければ作成したVMをdefaultに設定する必要があります。
`% orbctl set-default ${MACHINE_NAME}`

# Alacirttyの設定
alacritty.tomlの一部を抜粋します。
```toml
[terminal.shell]
program = "/opt/homebrew/bin/orb"
#program = "/bin/zsh
```
通常shellのPATHを入力する箇所に`orb`commandのPATHを入力します。

するとAlacritty起動時にNixOSが起動するようになります。

# NixOSの設定
NixOSの解説は別のもっと詳しく書いた記事を読んでください。
ここでは`$HOME/.config/nixos`にflake.nixを配置した後の、shellのconfigのみ解説します。

ちなみにconfigは下記で公開しています。
https://github.com/nyahahanoha/orbstack-nix

## shellの設定
zshの設定のみ特徴的なので解説します。
zshの設定は下記です。
```nix
{ config, pkgs, ... }:
{
  programs.zsh = {
    enable = true;
    shellAliases = {
      docker = "mac docker";
      kubectl = "mac kubectl";
      brew = "mac brew";
      home = "cd /Users/\${USER}";
      ls = "ls -1 --color";
      la = "ls -a";
      ll = "ls -l";
      lla= "ls -la";
      orb= "mac";
      update = "sudo nixos-rebuild switch --flake /home/\${USER}/.config/nixos#\${USER}";
    };
    initExtraFirst = ''
      if [ -z $TMUX ]; then
        tmux new-session -A -s default; exit
      fi
    '';
    initExtra = ''
      function keyscan() {
        host=$1
        echo "delete $host from known_hosts"
        ssh-keygen -R $host
        echo "add $host to known_hosts"
        ssh-keyscan -H $host >> "$HOME"/.ssh/known_hosts
      }
      
      precmd() {
        if [[ "$PWD" == /Users/* ]]; then
          fs_os="macos"
          color="blue"
        else
          fs_os="nixos"
          color="green"
        fi
        PROMPT="%F{"$color"}%B"$fs_os" >%b %f"
      }
      
      eval "$(gh completion -s zsh)"
      
      export LC_CTYPE="en_US.UTF-8"
    '';
    syntaxHighlighting = {
      enable = true;
      highlighters = [
        "main"
        "brackets"
      ];
    };
  };
}
```
aliasで`mac`というcommandを`docker`や`kubectl`の先頭につけていますが、これをすることでVM環境でなくMacの環境で`docker`や`kubectl`を使えるようになります。
また、aliasで`orb`commandを`mac`に変更していますが、VM環境で`orb`commandを実行するとバグってVMがフリーズするためこのようにしています。

他の設定はconfiguration.nix配下以外は何ら通常のNixOSと変わりないため、是非利用してみてください。

# 追記
brewの中身がこんなに綺麗になります。
```nix
==> Formulae
arp-scan

==> Casks
alacritty               discord                 google-chrome           microsoft-teams         utm
balenaetcher            drawio                  hammerspoon             notion                  visual-studio-code
chatgpt                 firefox                 microsoft-auto-update   orbstack                wireshark
cloudflare-warp         font-meslo-lg-nerd-font microsoft-office        slack
```
VM環境に入れられないGUI以外はほとんど入らなくなるのでとてもスッキリとします。
【Ruby】OpenSSLで「Neither PUB key nor PRIV key」エラーが出たときの対処法

## はじめに

暗号についての知識が乏しい状態でプログラムを実装していて、エラーが出たので原因と解決方法を調べました。

備忘録としてまとめます。

## 公開鍵とは何か？

公開鍵は、データを安全にやりとりするために使う暗号技術の一部です。

主な特徴は次のとおりです。

- 公開鍵: 誰でも使える鍵で、データを暗号化するために使います
- 秘密鍵: 公開鍵とペアになっている鍵で、暗号化されたデータを復号するために使います

たとえば、誰かに秘密のメッセージを送りたいとき、その相手の公開鍵を使って暗号化し、相手だけが持つ秘密鍵で復号する仕組みです。


## 問題

以下の公開鍵ファイル（SSH形式）がありました。

```public_key.ssh
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD34RFfMhjKd9RtGqYPwLzxXksv4rTUHl2cVwPqK7GyhnVfN3pkWA7X89JovKQy3RTr9gXNz2QsM8xP1G6n7L4oz3WzT7CLYMKH7dkRf56JoXhR9UvAZ8wzK1YoLdVg6TPZf2kYsmXr8g3NXYr6JQu9uH6p97cKsGzXL2L5I8vTjDZnRyMH3WpYrBLoXqJZKf4W8NzvLkpM2R6PYmWFoNzLd9ZY3XaGrqLTrKVyRP9jM7Bgp9CRf7JopMqcKMYWTLn3XJw9T89WPoLDkQM7Rf39YWKsl9Xk3JPMXNv9p3ZkRuQ3KzLpRYfg5TXmQ1LvJ9PsX8DjZ7CkW3NkMJz3
```

これをRubyで読み込もうとすると、エラーが発生しました。

```ruby
$ irb
irb(main):001> require 'openssl'
=> true
irb(main):002> public_key = OpenSSL::PKey::RSA.new(File.read('public_key.ssh'))
/Users/hogehoge/benv/versions/3.3.4/lib/ruby/3.3.0/openssl/pkey.rb:356:in `initialize': Neither PUB key nor PRIV key (OpenSSL::PKey::RSAError)
        from /Users/hogehoge/.rbenv/versions/3.3.4/lib/ruby/3.3.0/openssl/pkey.rb:356:in `new'
        from /Users/hogehoge/.rbenv/versions/3.3.4/lib/ruby/3.3.0/openssl/pkey.rb:356:in `new'
        from (irb):2:in `<main>'
        from <internal:kernel>:187:in `loop'
        from /Users/hogehoge/.rbenv/versions/3.3.4/lib/ruby/gems/3.3.0/gems/irb-1.14.1/exe/irb:9:in `<top (required)>'
        from /Users/hogehoge/.rbenv/versions/3.3.4/bin/irb:25:in `load'
        from /Users/hogehoge/.rbenv/versions/3.3.4/bin/irb:25:in `<main>'
```

これは公開鍵の形式がRubyのOpenSSLライブラリに対応していなかったために起こったエラーです。

OpenSSLは暗号化に必要な機能を提供するライブラリです。

`OpenSSL::PKey::RSA.new`メソッドはPEM形式もしくはDER形式のデータを受け取ることが想定されています。

## 解決策

エラーを解消するには、公開鍵をSSH形式からPEM形式に変換する必要があります。

### SSH形式とPEM形式の違い

- SSH形式: SSH接続で使うための鍵の形式、`ssh-rsa`などの文字列が先頭に含まれています
- PEM形式: OpenSSLで扱うための鍵の形式、鍵全体が`-----BEGIN RSA PUBLIC KEY-----`と`-----END RSA PUBLIC KEY-----`で囲まれています

### 形式の変換

以下のコマンドを使うと、SSH形式の公開鍵をPEM形式に変換できます。

```bash
ssh-keygen -f public_key.ssh -e -m PEM > public_key.pem
```

生成された`public_key.pem`ファイルを使って再度読み込んでみます。

```ruby
$ irb
irb(main):001> require 'openssl'
=> true
irb(main):002> public_key = OpenSSL::PKey::RSA.new(File.read('public_key.pem'))
=> #<OpenSSL::PKey::RSA:0x00000001287e8bb8 oid=rsaEncryption>
```

無事にオブジェクトが生成されました！

## おわりに

暗号の分野には苦手意識を持っているため、少しずつ知識とアウトプットを積み重ねていきます。

### 参考資料

https://docs.ruby-lang.org/ja/latest/library/openssl.html
AWS VPCの範囲についての基本的な理解

AWSのVPC（Virtual Private Cloud）は、AWSクラウド上で仮想的なネットワーク環境を構築するためのサービスです。その範囲について説明します。

---

### **1. VPCの範囲**
VPCの範囲は、**1つのAWSリージョン内**に限定されます。  
具体的には、以下のポイントに分けて考えると分かりやすいです。

#### **1-1. リージョン内に限定**
- **VPCはリージョンに依存**して作成されるため、1つのVPCは特定のリージョン内だけで有効です。
- 例えば、東京リージョン（`ap-northeast-1`）に作成したVPCは、オレゴンリージョン（`us-west-2`）では利用できません。
- 異なるリージョンにまたがるVPCを直接作成することはできませんが、**異なるリージョンのVPC間通信**は後述の方法で可能です。

#### **1-2. 複数のアベイラビリティゾーン（AZ）をサポート**
- VPCは、リージョン内の複数のアベイラビリティゾーン（Availability Zone）にまたがってネットワークを構築することができます。
- アベイラビリティゾーンごとにサブネットを作成し、リソース（EC2インスタンスなど）を分散配置することで、高可用性を確保できます。

---

### **2. 他のVPCやネットワークとの接続範囲**
VPC単体の範囲はリージョン内に限定されますが、他のVPCやネットワークとの接続によって範囲を広げることができます。

#### **2-1. 同じリージョン内のVPC間通信**
- **VPCピアリング**を利用することで、同じリージョン内の複数のVPC間を接続可能です。
- 例えば、東京リージョン内にある2つのVPC（VPC-AとVPC-B）をピアリングで接続し、相互に通信させることができます。
- 注意点として、VPCピアリングはリソースが多くなると管理が煩雑になるため、スケールが必要な場合は**Transit Gateway**の使用が推奨されます。

#### **2-2. 異なるリージョン間のVPC通信**
- 異なるリージョン間で通信する場合は、以下の手法を利用します：
  - **リージョン間VPCピアリング**：異なるリージョンのVPCを直接接続可能。
  - **Transit Gateway**：複数リージョンにまたがる複雑なネットワークを効率的に管理可能。
  - **AWS Global Accelerator**：レイテンシを最適化したグローバル通信を実現。
  - **Direct Connect（DX）やVPN**：オンプレミスネットワークとの接続に加えて、VPC間接続の補完として利用。

---

### **3. グローバル通信の範囲**
VPCそのものはリージョンに限定されますが、AWS全体のグローバルなネットワーク構造を利用して広域通信を実現できます。

- **VPC Lattice**：
  - サービス間の通信を簡略化し、異なるVPCやリージョンをまたいで通信可能にする新しいマネージドサービス。
  
- **AWSのグローバルネットワーク**：
  - AWSのグローバルバックボーンネットワークを活用することで、高速かつ安全に通信できます。

---

### **4. サブネットとCIDRブロックの範囲**
VPC内部では、IPアドレスの範囲をCIDR（Classless Inter-Domain Routing）で指定します。
- 例: `10.0.0.0/16`
- 1つのVPC内では、このCIDRブロック範囲でIPアドレスを管理します。
- CIDRブロックをサブネットに分割して、アベイラビリティゾーンごとに割り当てます。

---

### **5. よくある疑問と注意点**
- **VPCはAWSアカウントの外には直接影響を及ぼしません。**  
  他のアカウントのVPCと通信する場合は、VPCピアリングやTransit Gatewayの設定が必要です。

- **VPCの設定はアカウント内で独立しています。**  
  同じアカウント内でも、異なるリージョンに作成されたVPCは完全に独立しており、IPアドレスやCIDRブロックの競合は発生しません。

---

### **まとめ**
- **VPCの範囲はリージョン内**に限定されます。
- 他のリージョンやネットワークと通信する場合は、適切な接続手法（VPCピアリング、Transit Gateway、DX/VPNなど）を利用します。
- リージョン内の複数のアベイラビリティゾーンにまたがる構成が可能で、高可用性を実現できます。

https://qiita.com/SMZPP/items/91a9dd984d56fb2e7d7f
ダメパターン

# はじめに

これまで自身が作った、遭遇したダメパターンのコード集を今年も書きたいと思います。

# ネストが深くて何がしたいかわからない

[以前の手続きが長い](https://qiita.com/jun2/items/86be2f17bd52677fe152)にも似ていますが、ネストが深くなるパターンです。

頭の中にあるものを整理せず書くとこれが出てきます。

```
function procData(data) { 
  if (data.items) {
    if (data.items.length > 0) { 
      for (var i = 0; i < data.items.length; i++) { 
        if (data.items[i].value) { 
          console.log(data.items[i].value);
     ・・・
```

# 列名を頑張って英訳しすぎる

論理名を定めるとすべて英訳したくなるものではありますが、全てを英訳して長くなりすぎるパターンで 
購入履歴詳細→detailed_purchase_historyですが、テーブルの構成にもよりますが、 detailed やhistoryでも十分伝わる場合が多いと思います。

正確に書きたくなる気持ちはわかりますが、最短で伝わる言葉を選択することが重要かなと思います。

データベースの列名も同じなのですが、フレーズに対して単語表を作ってルール化しよう！と思うのですが、心の中では「形骸化するんだろうなぁ。。。」と思ってます。
レビューをしっかりしている組織であればこの辺チェックしているでしょうが、組織毎の事情はあるでしょう。
そういった場合は何回も使って慣れさせる！実効支配する！というのもありだと思います。
私も含め英語を使われるとわからない人もいるでしょう。
間違っていようがなんだろうが良いと思います。
例えば(ひどい例で)、
  郵便番号→jpCode
普通はzipCodeでしょうが、これも使い続けると良くも悪くも浸透してしまいます。

# 命名が統一されてない

同じ意味を示す言葉でも例えばファイルが異なる、担当が異なると変わってしまうというのはよくあるのではないでしょうか？

* ユーザー情報: userData, userInfo
* 商品情報を表す変数: itemInfo, goodsInfo
* 状態を表すフラグ: flag, status

そりゃ大企業様はこのあたりの開発規定がしっかりあるでしょう。
が、この辺り整理できていない組織はおおいのではないでしょうか？

なんなら自分単独でもやりかねないので、このあたりをAIなり、ソースコードレビューなりで統一化したほうがいいでしょう。

# エラー時スタックトレースをユーザに見せるだけ

try-catheしてエラーオブジェクトなどが、そのまま出る！というパターンです。
デバッグ段階ではいいですが、概ねスタックトレースなり、技術的なメッセージなりユーザからしたら壊れた！と思わせるようなものが表示されることになります。
ちゃんと起こり得るエラーパターンを検討して、それぞれユーザに何を求めるべきなのかを示すべきでしょう。

# 終わりに

コーディングそのものをする機会が少なくなりクソコードを排出する事が少なくなってきました。
ただダメなコードを書いた後に、自分でだめだったなと思えること。それが大事だと思います。
コードを提出される側もすべてが完璧！ではなく自分で振り返ることができる余地も残すようにしないとなと最近は思うようになりました。
【Python】エラー「cannot import name '_mysql' from partially initialized module 'MySQLdb'」の原因

# 概要
AWS LambdaでPythonプログラムを実装していたら以下のエラーに遭遇。
原因と解決方法を紹介します。

> [ERROR] Runtime.ImportModuleError: Unable to import module 'xxx.main': cannot import name '_mysql' from partially initialized module 'MySQLdb' (most likely due to a circular import) (/opt/python/lib/python3.12/site-packages/MySQLdb/__init__.py)

Lambda環境はarm64のPython3.12です。

# 原因
エラーメッセージに「`most likely due to a circular import`」とあるように、多くの場合は循環インポートが原因らしいです。互いに参照しちゃってるパターンですね。

ただ、今回私は自分の書いたコードの中にそのようなものは見当たらず。
メッセージにもmysqlのことが書いてあるのでモジュールのインポートでエラーが起きているらしいことがわかります。

調べてみると、SQLAlchemyとMySQLdbを使っていると、MySQLdbモジュールの初期化中に循環インポートが発生してエラーになることがあるらしい。

## 解決方法
ということで、MySQLdbではなくPyMySQLを使用するように変更してみました。
修正内容は以下です。

```py
# 元々のコード
url = (f'mysql://{self.db_user}:{self.db_password}@{self.db_host}:'
       f'{self.db_port}/{self.db_dbname}')

# pymysqlを使用したコード
url = (f'mysql+pymysql://{self.db_user}:{self.db_password}@{self.db_host}:'
       f'{self.db_port}/{self.db_dbname}')
```

これでもう一度実装すると、エラーがなくなりました。

SQLAlchemyがPyMySQLドライバを使用してMySQLデータベースに接続するようになったのでしょう。
以上です！
期間検索で矛盾した期間が入力された時の対処してみた

# 期間検索でありえない入力された時の対処してみた
ニュースとか通知で期間を指定して検索かけるときありますよね？
そのとき終了日時が開始日時以前で検索かけても絶対にヒットはしないですが、現実あり得ないのでそのまま処理が走らないようにしてみました。
かなり簡単なので記事にしやすいことと、使う頻度高そうと思ったので書いてみます。
## 日時の入れ替え
実際に実装したものは終了日時が開始日時以前の入力になり、検索が押された場合開始と終了日時を入れ替えて検索をかける処理です。
聞いたとき難しそうと思っていたのですが、かなり簡単でした！

**コード例**
```
public function search(Request $request)
{
    $searchDate = $request->filled('search_date') ? $request->search_date : now()->toDateString();

    $news = News::where(function ($query) use ($searchDate) {
        $query->whereNull('publish_start_date')
              ->orWhere('publish_start_date', '<=', $searchDate);
    })->where(function ($query) use ($searchDate) {
        $query->whereNull('publish_end_date')
              ->orWhere('publish_end_date', '>=', $searchDate);
    })->get();

    return view('news.index', compact('news', 'searchDate'));
}

```
この状態だと日時の入力形式さえ合っていればあり得ない期間検索でも処理自体は走ってしまいます。(ヒットはしないですが…)

ここで日時を入れ替える処理を入れることで開始日時以前が入力されても日時を入れ替えて適切な期間で検索することができます。
```
//日時の入れ替え処理
if($publish_end_date < $publish_start_date){
    $evacuation_date = $publish_end_date;
        $publish_end_date = $publish_start_date;
        $publish_start_date = $evacuation_date;
    }
    
$news = News::where(function ($query) use ($searchDate) {
        $query->whereNull('publish_start_date')
              ->orWhere('publish_start_date', '<=', $searchDate);
    })->where(function ($query) use ($searchDate) {
        $query->whereNull('publish_end_date')
              ->orWhere('publish_end_date', '>=', $searchDate);
    })->get();
```
## コード説明
開始日時を別変数に移すｰ>終了日時を開始日時に移すｰ>別変数を終了日時に移す
**これだけなんです！笑**
ぶっちゃけなくてもいいのかも知れないですが、使う側からするとほんの少しありがたいと感じるかも知れないので機会があればぜひ実装してみてください！

変数名を変えればいいだけなので楽々使いまわせますよ！！
## 終わりに
初めて技術記事書いてみましたがまだまだ拙いところもたくさんありますがそこはご愛嬌ということでお願いします。
Track CLIが使えない問題

## 問題
コマンドラインでtrack runなどのTrack CLIのコマンドが使えなかった。調べるとプロキシサーバを介しているとできないなどあったが、プロキシサーバは使っていない。

## 解決策
#### 実行ポリシーの変更
まず現在の設定を確認
```
$Get-ExecutionPolicy
```
次に設定の変更
```
$Set-ExecutionPolicy RemoteSigned
```
restricted ⇒　RemoteSignedに変更したらできた。
単純パーセプトロン

## 単純パーセプトロンとは
複数の入力$(1,x_1,x_2)$に対して、単一の出力$z$を与える仕組み。
アルゴリズムは以下のようになる。

```math

\begin{cases}
u = w_1x_1 + w_2 x_2 + w_3 \\ 
z = f(u) 
\end{cases}
```
$f(u)$は活性化関数と言って、非線形な関数である。
今回はステップ関数を用いる。
```math
\begin{equation}
f(u)=
\begin{cases}
0 & \text{if} & u<0  \\ 
1 & \text{if} & u \geq0
\end{cases}
\end{equation}
```

## 視覚化してみる
今回はステップ関数にしたことで、二値分類の問題として使うことができる。
つまり、$0 = w_1x_1 + w_2x_2 + w_3$で表される直線の上下で各点を分類できることになる。
| 図1 | 
| :--: | 
| ![スクリーンショット 2024-11-29 19.27.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3933005/fc377fd6-3e5c-a37e-44b3-0b231e479f3f.png) |
|  $0 = w_1x_1 + w_2x_2 + w_3$で紫が上側領域、緑が下側領域に分類された。 |

もちろん、初めからこのように分類できることは少ない。
最初は$w_1, w_2, w_3$の初期値を適当に決めて、学習させる必要がある。

## 学習方法

1であるはずが0の場合、

```math
\begin{cases}
w_1 \leftarrow w_1+ ηw_1  \\ 
w_2 \leftarrow w_2+ ηw_2  \\
w_3 \leftarrow w_3+ ηw_3  \\
\end{cases}　
```
このように傾きと切片を調整することで学習させることができる。調整に使う定数として学習効率$\eta$(イータ)を定める。
図示すると図2のようになる：
| 図2 |
| :--: |
| ![スクリーンショット 2024-11-29 20.43.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3933005/4940eaa0-8e85-860a-b89b-19410da29e38.png) |
| 紫の点が正しく分類されるようになった。 |


なお、0であるはずが1の場合は

```math
\begin{cases}
w_1 \leftarrow w_1- ηw_1  \\ 
w_2 \leftarrow w_2- ηw_2  \\
w_3 \leftarrow w_3- ηw_3  \\
\end{cases}
```

のように学習効率の符号が負になる。

## 課題とディープラーニングとの関係性
現状だと線形分離の問題しか扱えない。つまり、直線でしか分類することができない。

解決策としては以下が考えられる。
・多層パーセプトロン（MLP）:隠れ層を追加することで、非線形問題にも対応する。
・活性化関数の改良:ステップ関数の代わりに、シグモイド関数やReLUを使用する
以上を応用すると、線形分離以外の問題も解けるようになる。

これに付随して、学習方法を改良すると今日ディープラーニングで使われるニューラルネットに繋がっていく。

|単純パーセプトロン|Reluを用いた多層パーセプトロン|
|:--:|:--:|
|![スクリーンショット 2024-11-29 21.32.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3933005/098a064e-48bd-be55-e01d-d49189d08bba.png)|![スクリーンショット 2024-11-29 21.31.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3933005/81fca46f-aa65-18cd-6449-9011140a765b.png)|
|![スクリーンショット 2024-11-29 22.18.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3933005/deb0c5b2-72f1-1cdc-e7b3-0ee8f509e4ee.png)|![スクリーンショット 2024-11-29 22.13.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3933005/3be390c3-d174-5ed5-c85b-3f4ce4100708.png)|
|`linear_model = LogisticRegression()`|`mlp_model = MLPClassifier()`|


## 補足:ReLUとシグモイドについて
|ReLU|シグモイド|
|:--:|:--:|
|![スクリーンショット 2024-12-02 16.11.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3933005/14e05b15-6f72-07f9-56d1-dae63b6d06a7.png)|![スクリーンショット 2024-12-02 16.11.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3933005/9ed29d1c-e26e-b44c-416e-f30dc9509c32.png)
|$　ReLU(x) =\begin{cases} x & \text{if } x \geq 0 \\\\ 0 & \text{if } x < 0 \end{cases}$|$\text{Sigmoid}(x) = \frac{1}{1 + e^{-x}}$|
|シグモイドなどの非線形関数よりも計算効率が良く、学習に適している。人体のニューロン発火からインスピレーションを受けている。|$[0, 1]$の範囲に圧縮することができるので、出力層に使われる。|
バッチのコマンドについて２　条件分岐

去年と同様にバッチを使用する際に覚えておくと便利なコマンドをご紹介させていただきます。

今回は「errorlevel」を用いて条件分岐のやり方について記述していきたいと思います。

1　errorlevelについて
　そもそも「errorlevel」とはどういったコマンドなのか、
 このコマンドを用いることによって「前のコマンドが正常終了したかを確認」することができます。
　前のコマンドの成功の可否で後の処理を変更したい場合に便利なコマンドとなります。

errorlevelコマンドの基本情報(処理の挙動)
　直前のコマンドが成功　→　errorlevel変数に「0」が入ります
　直前のコマンドが失敗　→　errorlevel変数に「1」が入ります
　コマンド自体がない場合はerrorlevel変数に「9009」が入ります

 ※使用例※
 OSのビルド番号を確認しバージョンを特定し、指定のビルド番号(今回はWin11の23H2のビルド番号が22631)未満の場合はバージョンアップが必須とコマンドで出す場合。

 systeminfo | findstr /B :"OS バージョン:"|findstr "22631"
if %errorlevel% == 0 (
	echo 【事後判定_OK】バージョンアップ済み
) else (
	echo 【事後判定_NG】バージョンアップが必要
)
exit /b

解説
systeminfo　→　PCのシステム情報を表示させる。
findstr /B　→　文字列の検索　/Bのオプションをつけることで行の先頭が”　”内から始まるものに指定する。(今回の場合、OSバージョン)
OSバージョン内を検索し、なおかつ”22631”があった場合errorleveの変数は「0」となる。
”22631”がない場合は失敗したという扱いのため、errorleveの変数は「1」となる。

if %errorlevel% == 0 (
	echo 【事後判定_OK】バージョンアップ済み
) else (
	echo 【事後判定_NG】バージョンアップが必要

　→　%errorlevel%で変数を参照し「0」であれば、【事後判定_OK】バージョンアップ済み
 　　　eleseで条件を満たしていなければ、　　　　【事後判定_NG】バージョンアップが必要　と表示させる。

　今回使用した例はほんの一部ではありますが、これらを応用することで役に立つものができるはずです。まずは実際に試してみて試行錯誤することがこういったコマンドを習得する一歩なのかなと思います。
AtCoderのDFSでREが一生取れない問題

## 背景
AtCoderの競技プログラミングの鉄則、[A62 - Depth First Search](https://atcoder.jp/contests/tessoku-book/tasks/math_and_algorithm_am "問題へ")を解いていたところ、RE(実行時エラー)が出続けていた。

### 実際のコード
```
N,M = map(int, input().split())
G = [[] for _ in range(N)]
for _ in range(M):
    a,b = [int(i)-1 for i in input().split()]
    G[a].append(b)
    G[b].append(a)

visited = [False for _ in range(N)]

def dfs(node):
    visited[node] = True
    for nex in G[node]:
        if visited[nex]==False:
            dfs(nex)


dfs(0)
for i in range(N):
    if visited[i] == False:
        print("The graph is not connected.")
        exit()

print("The graph is connected.")
```

## 解決策
ほかの方のソースコードを見ていると、
```
import sys
sys.setrecursionlimit(10**9)
```
なる普段見ないものがあった。これは再帰関数の上限回数を設定するものらしいが、こんなもので変わるのか？と疑いながらも提出してみると、ものの見事にACできた。

どうやらAtCoderでは再帰の深さが1000(?)ぐらいを超えるとREになってしまうようだ。これから再帰をするときは忘れずにつけよう！  (覚えてるかな...)


## 最後に
これを見つけるまでに１時間半ほど試行錯誤しました。こういう特有の仕様みたいなやつあれば、ぜひ教えてください！
Git \Github使い方まとめ

## **Git/GitHub操作メモ**

最近やっとのことGit/Githubを使い始めたので、覚えた操作方法等をメモ代わりに書き記すとします。

---

### **1. Git操作フロー**
#### **初回セットアップ**
1. **ローカルリポジトリを初期化**:
   ```bash
   git init
   ```
2. **リモートリポジトリを登録**:
   ```bash
   git remote add origin リモートURL
   ```

#### **登録済みリモートリポジトリの確認・変更**
1. **登録済みのリモートリポジトリを確認**:
   ```bash
   git remote -v
   ```
   - 登録済みリポジトリの一覧とそれぞれのURLが表示される（`fetch`用と`push`用）

2. **リモートリポジトリのURLを変更**:
   - 新しいURLに更新:
     ```bash
     git remote set-url origin 新しいリモートURL
     ```

3. **リモートリポジトリを削除**:
   - 必要がなくなった場合:
     ```bash
     git remote remove origin
     ```
#### **ブランチの操作**

1. **新しいブランチの作成**:
    ```bash
    git branch ブランチ名
    ```
    * このコマンドはブランチを作成するだけで、チェックアウト（切り替え）は行わない

2. **新しいブランチに切り替える**:
    ```bash
    git checkout ブランチ名
    ```

3. **作成と同時に切り替える**:
    ```bash
    git checkout -b ブランチ名
    ```

4. **現在のブランチを確認**:
    ```bash
    git branch
    ```
    * 現在のブランチには`*`が付いて表示される
---

### **2. 変更をリモートリポジトリに反映する手順**
#### **初回プッシュ**
- 初回は`-u`オプションを使い、リモートリポジトリとローカルブランチを紐付ける:
  ```bash
  git add .
  git commit -m "初回コミット"
  git push -u origin main
  ```

#### **初回以降の操作**
1. **変更をステージングしてコミット**:
   ```bash
   git add .
   git commit -m "変更内容を記述"
   ```

2. **リモートにプッシュ**:
   ```bash
   git push
   ```

3. **リモートの変更をローカルに取得（必要に応じて）**:
   ```bash
   git pull origin ブランチ名
   ```

---

### **3. その他確認等**
#### **ステータス確認と変更内容の確認**
- 作業状況の確認:
  ```bash
  git status
  ```
- コミット前に差分を確認:
  ```bash
  git diff
  ```

#### **ログと履歴の活用**
- 簡潔な履歴を確認:
  ```bash
  git log --oneline
  ```
- フルログを確認:
  ```bash
  git log
  ```

#### **不要なブランチやリモートの整理**
- ローカルブランチの削除:
  ```bash
  git branch -d ブランチ名
  ```
- リモートブランチの削除:
  ```bash
  git push origin --delete ブランチ名
  ```

---

これを覚えきれたらある程度実用的になるのではないかなーと。
【Flutter】投稿したものテキストだけでなく画像もシェアできるようにする

![スクリーンショット 2024-11-29 22.13.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/d743b57b-07f5-3799-e541-b5b87a91d03d.png)

# 初めに
個人開発でぼちぼちと進めていく中でいくつかの実装の一つをご紹介します。


# やりたいこと
- 投稿したものテキストだけでなく画像もシェアできるようにする

| 共有前 | Twitter（Xへの共有） | 共有後 |
|:-----------:|:------------:|:------------:|
| ![IMG_8751.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/72ae91ef-46c1-9df0-f40a-377ca3ba8ce7.png)    | ![IMG_8752.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/41d1faa9-4a40-e7af-f920-b826daefdb48.png)    | ![IMG_8750.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/57261ca1-a8ae-dd18-1ed4-27bf07cdb56e.png) |


# 実装までの流れ
1. シェアしたいWidgetを作成する
1. ScreenShotControllerを定義し、`captureFromWidget`を使用する
1. スクリーンショットしたものを一時ディレクトリに保存をする
1. シェアに必要な画像を試行錯誤をして変換する
1. `shareXFiles`を使用して画像とテキストをシェアできるようにする


# 実装に必要なPackagesたち
https://pub.dev/packages/screenshot

https://pub.dev/packages/path_provider

https://pub.dev/packages/share_plus




# 実装していく

```dart
/// ScreenShotControllerを定義し、`captureFromWidget`を使用する
final screenshotController = ScreenshotController();
/// 今回は、Textのみをスクリーンショットする
final screenshotBytes = await screenshotController.captureFromWidget(
  Text("シェアしたいよおお")
);
/// 一時ディレクトリに保存
final tempDir = await getTemporaryDirectory();
final filePath = '${tempDir.path}/shared_image.png';

/// シェアに必要な画像を試行錯誤をして変換する
final file = File(filePath);
await file.writeAsBytes(screenshotBytes);
/// shareXFilesを使用して画像とテキストをシェアできるようにする
await Share.shareXFiles(
    [XFile(file.path)],
    text: '${posts.foodName} in ${posts.restaurant} \n\n#FoodGram',
  );
);
```

ぜひ、色々なWidgetをシェアしてみてね。

## 実装していたPR

https://github.com/iseruuuuu/food_gram_app/pull/411


# 最後に
MapLibreを使用したアプリを個人で開発しています･:*+.\(( °ω° ))/.:+

![Group 93.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/318bb611-4e87-6c02-6a2c-2c5bb93c392a.png)



https://apps.apple.com/jp/app/foodgram/id6474065183


- 「FoodGram」は、フードシェアアプリとなっており、あなたの好きなレストランの食事をぜひこのアプリで共有していただけると嬉しいです!!

<b>このアプリのセールスポイント
- このアプリだけのレストランマップをユーザー全員で作成できる⭐️
- 自分だけのフードアルバムを構築できる⭐️
- 世界中の人たちの投稿を自由に閲覧できる⭐️
基本情報技術者試験 アウトプット Lesson02-05

## AI(人工知能)
**基本情報技術者試験では、ここ数年でAIに関する用語が頻出している**
### AI関連の重要用語
#### AI(人工知能)
人間の**知的な振る舞い**を、コンピュータ上に再現する技術。
#### 機械学習
人間が持つ**学習能力**をコンピュータ上に再現する技術。AI技術の一つ。コンピュータに**学習用のデータ**を与えることで、コンピュータ自身が将来予測や意思決定を行うことができるようになる。
「教師あり学習」と「教師なし学習」の大きく二つに分類される
##### 教師あり学習
入力データと正解データのセットをコンピュータに与える。
ex)正解のデータを提示させ、データが誤りであることを指摘することによって正誤の判断ができるようになる。
##### 教師なし学習
入力データのみをコンピュータに与える。
ex)入力データを与え続けることで、統計的性質やある種の条件によってパターンの判別・クラス分けを行う。

#### ニューラルネットワーク
人間の脳内にある「**神経回路がしんごうをやりとりする仕組み**」（＝ニューロン）をコンピュータ上に再現する。
#### ディープラーニング
ニューラルネットワークを何重にも重ねた構造を持つ機械学習

### 終わりに
参考資料：いちばんやさしい基本情報技術者　絶対合格の教科書＋出る順問題集
【JavaScript】Bunって何？基本的なコマンド紹介

# 簡単な紹介
BunはJavaScriptのAll-in-Oneなツールキットです。

以下のような特徴があります。

- ランタイムが**非常に高速**
- TypeScriptをサポート
- 高速なパッケージマネージャが付属している
- テストランナーなど、ほかにも便利なものが付属している
- Node.js互換

公式サイトはこちらです。

https://bun.sh

# インストール

Linux & MacOSでは、コマンド一つでインストールできます。

```bash:ターミナル
curl -fsSL https://bun.sh/install | bash
```

詳しくは[こちら](https://bun.sh/docs/installation)。

## Homebrewを使う場合

[BunはHomebrewでも公開されている](https://github.com/oven-sh/homebrew-bun)ので、Macユーザーならここからインストールできます。
```bash:ターミナル
brew install oven-sh/bun
```


## Hello World!

まずはコードを用意します。
```index.js
console.log("Hello World!");
```

これを実行するには`bun`コマンドを使います。
`bun ファイルへのパス`で実行できます。

```bash:ターミナル
bun index.js
# Hello World!
```

# 基本的なコマンド
私的によく使うと思うコマンドをざっくり紹介します。

## 確認

### バージョン
バージョンは`bun -v` or `bun --version`で見れます。

### ヘルプ
`--help`オプションをつけると、コマンドのヘルプを見ることができます。
`bun --help`からコマンド一覧も見れます。

## 実行
JavaScriptのコードの実行は、`bun`もしくは`bun run`コマンドでできます。

### ファイルパスを指定して実行

```bash:ターミナル
bun パス
# or
bun run パス
```

### タスクを実行
タスク=`package.json`の`script`に書かれているコマンドも、先ほどと同じ方法で実行できます。

例えば`package.json`を以下のように定義します。
```jsonc:package.json
{
  // ...
  "scripts": {
    "dev": "bun src/index.js"
  }
}
```

この`dev`は、ファイルパスを指定するときと同じコマンドで実行できます。

```bash:ターミナル
bun run dev
# or
bun dev
```


## 初期化

### 初期化
[`bun init`コマンド](https://bun.sh/docs/cli/init)を使うと簡単にプロジェクトを初期化できます。

```sh:ターミナル
bun init
```

ちなみに、私はそんなに使ってません。
**ただJavaScriptを実行するだけなら初期化する必要はなく**、ファイルを作ってそのまま実行できます。
必要になるのは外部のライブラリを使う時でしょうか。

しかし、フレームワークなどに乗っかって開発する場合、すでにテンプレートが用意されていることが多いです。
そのため後述の`bun create`のほうが使う場面は多そうです。

### テンプレートから初期化

初期化の方法には、ほかにも[`create`コマンド](https://bun.sh/docs/cli/bun-create)があります。
これはNPMやGitHub、ローカルにあるテンプレートからプロジェクトを作成するコマンドです。

```sh:ターミナル
bun create テンプレート
```

もしあなたが[Vite](https://ja.vite.dev)のプロジェクトを初期化するなら、`bun create vite`コマンドが使えます。

## パッケージ
Bunは**パッケージマネージャ**を兼ね備えています。
これは非常に高速なので、1からプロジェクトを作るなら、速度目的でYarnなどを導入する必要はないかもしれません。

### add

プロジェクトにパッケージ（NPMパッケージ or ローカル）を追加します。

例えば`react`パッケージを追加してみます。
```sh:ターミナル
bun add --dev react
```

このコマンドでは以下のことをやってくれます。

- `package.json`の`dependencies`にパッケージを追加
    - `--dev`オプション: パッケージを`devDependencies`に追加
- 実際の`node_modules`にパッケージを追加
- ロックファイル（`bun.lockb`）にパッケージを追加

### install
`package.json`に書かれているパッケージをインストールします。

```sh:ターミナル
bun install
```

これは非常に高速です。
それを示すベンチマークは[こちら](https://bun.sh/docs/cli/install)で公開されています。

## テスト
Bunには[テストランナー](https://bun.sh/docs/cli/test)が付属しています。

テストコードは`bun:test`パッケージの関数を使うことで書けます。
以下は[ドキュメント](https://bun.sh/docs/cli/test)から引用したテストコードのサンプルです。
```js:math.test.ts
import { expect, test } from "bun:test";

test("2 + 2", () => {
  expect(2 + 2).toBe(4);
});
```

:::note warn
テストをTypeScriptで書く場合、型定義（`@types/bun`パッケージ）をインストールする必要があります。

追加は以下のコマンドでできます。
```sh:ターミナル
bun add --dev @types/bun
```
:::

全てのテストはこちらのコマンドで実行できます。

```sh:ターミナル
bun test
```

なお、Bunにテストランナーが付属しているからといって、他のテストランナーが使えないというわけではありません。
BunにはNode.js互換があるので、JestやVitestなども動くと思います。たぶん。
（Bunはたまに未実装な機能がある）
フィーチャーフラグの悲喜交々

この記事は [ソフトウェアテストの小ネタ Advent Calendar 2024](https://qiita.com/advent-calendar/2024/software-testing-koneta) 14日目 の記事です。

# はじめに
みなさんこんにちわ！ @afracs  です！
今回はフィーチャーフラグを使ってQAコントロールがしやすくなった話を書こうと思います。
フィーチャーフラグの詳細については、検索すればいろいろな有識者の方の記事がヒットするので、詳しく知りたい方はそちらでご確認ください。
ここでは、フィーチャーフラグを使い始めたことで、弊社の環境がどう変わっていったのか？という話を書いていきたいと思います。


# 使う前と後でどう変わったの？
今までは、ブランチにマージされたらすぐにリリース対象になってしまうため、急いでQAしなければいけない世界線でした。

ですが、フィーチャーフラグを導入した後は、安全にリリースを行える環境になりました。

### メリット1：QAコントロールがしやすい
弊社の場合、元々リリース頻度が高かったためQA頻度も多かったのですが、ここ1年くらい急速に開発ボリュームが増えていきており、さすがに対応しきれなくなってきてました。。。

検証に時間のかかる機能や検証規模が大きものについては、一旦検証のために検証用ブランチにマージするのですが、リリース物件からはリバートする、という運用で回していました。

さすがにずっとその方法だと厳しいので、まずは一部のプロダクトにフィーチャーフラグを導入し、お試し運用を開始しました。

その結果、
* リリースブランチへの出し入れがなくなった
* フィーチャーフラグ付きの機能については、周りのリリースを気にせずにQAが可能
* 並行してさまざまな機能のQAが可能
    * 即時出したいものとの共存OK
    * 複数フラグを同時にON、組み合わせてONなどの形で調整可能
* リリースタイミングごとに機能ON/OFFしてのQAが容易

と、いろいろな恩恵がありました。

### メリット2：リリース調整がしやすい
機能実装やQAの進捗次第でリリース予定が前後してしまう場合、先にQA完了しているフィーチャーフラグ付きの機能をリリースする（リリース順番を入れ替える）ということが容易となりました。

## ただしデメリットもある
三方良しとはなかなかうまくいかないもので、、、
フィーチャーフラグを導入した場合のデメリットも存在します。

### デメリット1：フラグの数が多すぎると管理が大変
メリットでもあるのですが、フラグの数が多すぎると、どの組み合わせでQAを進めないといけないのか？といったテスト戦略をしっかり考える必要が出てきます。
例えば、フラグが2つくらいであれば、1つずつONにして、2つONにした時もちゃんと正しく動くよね、という確認が取れればOKです。

でも、それが10個とかになったらどうでしょう？
- リリースの順番
- QAの順番
- どのフィーチャーフラグの組み合わせまでテストするのか？

といった計画を立てて緻密に管理していかなければならなくなります。

### デメリット2：フラグのお掃除が大変
これは主に実装担当者側の苦労になるのですが、本質的に必要なものではない（実現したい機能上必要なものではない）ため、使い終わったフィーチャーフラグを削除していく必要があります。
このリファクタリング作業が意外と大変で、全員がよく触る機能に入れいたりするとフラグ削除のコードマージの際に、神経を使います。
また、面倒だからといってそのまま放置しすぎるとスパゲッティになりがち、、、など、、、、、

弊社内のチームでもこのあたりは悩見どころですし、世の中でも同様に悩みの種になっているようです。。。

# 最後に
メリット・デメリット双方ありますが、今の弊社としては「フィーチャーフラグを導入してよかった！」という状態なので、このメリットを最大限活用しつつ、今後はデメリットの軽減を模索していけたらなぁと考えています。

フィーチャーフラグをまだ導入してなくて、QAやリリースが大変なチームの皆様は利用を一考してみてはどうでしょうか？

<br><br>
本記事が何かのお役に立てたのならば幸いです。
最後までお読みいただきありがとうございました。
Databricksアドベントカレンダーの傾向分析

入社した年からスタートして、かれこれ4年目に突入しています。

https://qiita.com/advent-calendar/2024/databricks

Data & AIカンパニーを謳う会社にいるものとして、過去のデータを振り返ってみたいと思います。

| 年 | 参加者 | 購読者 | お気に入り | 投稿数合計 | Databricksによる投稿 |Databricks外の方の投稿|Databricksの投稿比率 |
|:--|:--|:--|:--|:--|:--|:--|:--|
| 2021  | 9  |  7 |  28 | 25  | 20  | 5  |80|
|2022	|18	|14|	76	|65	|43	|22|	66.2|
|2023	|19	|14	|69|	53|	39	|14|	73.6|
|2024	|30|22	|	|	38|	8|	30|	21.1|

可視化します。Databricksで。

![Screenshot 2024-11-30 at 9.26.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/2af075b3-908c-c965-555f-140f1e4bfc3c.png)


特筆すべきは、Databrikcsの中の人の比率が今年は劇的に減少していることです。正直これまでは私が相当な割合で執筆していました(完走賞狙ってましたが)。

今年は多くのお客様に執筆いただけて嬉しいです！引き続き参加をお待ちしています！

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
supertestを利用してnodeのintegrationテストを実装する

## はじめに
nodeでintegrationテストの実装をする際にテスト用サーバーを立ち上げたり、準備がいろいろと大変だったりします。
そんな面倒に感じるintegrationテストをなるべく低コスト？で実装できる物があると嬉しいですよね

## なぜsupertestが良いのか
- supertestを利用すると比較的容易にAPIにrequestを投げるようなコードがかけるため、テストコードの可読性が向上する
- サーバーを立ち上げることなくシミュレートしてくれるため、テスト用にサーバーを立てるような実装をしなくてもよい

### supertestについて
https://www.npmjs.com/package/supertest

## 実装方法
supertestを使うとどんなテストを実装する必要があるのかを見ていきます。
アプリケーションサイドのロジックとテストの実装それぞれ見ていきましょう

### アプリケーション側の実装
``` js
import express, { Request, Response } from "express";

export const app = express();
const PORT = process.env.PORT;

/**
 * =========================
 * 今回テストの対象となるエンドポイント
 * =========================
 */
app.get("/api/v1/sample", (request: Request, response: Response) => { 
  response.status(200).json({
    message: "This endpoint is get",
  });
}); 

app.listen(PORT, () => { 
  console.log("Server running at PORT: ", PORT); 
}).on("error", (error) => {
  // gracefully handle error
  throw new Error(error.message);
});
```

### テストの実装
``` js
import request from 'supertest';
import { app } from '..';

describe('index', () => {
	it('/api/v1/sampleからレスポンスが返ること', async () => {
		const response = await request(app).get('/api/v1/sample');

		// ステータスコードの確認
		expect(response.status).toBe(200);
		// ステータスコードの確認
		expect(response.body).toEqual({ message: 'This endpoint is get' });
	});
})
```

動かしてみるとテストがpassしているかと思います

## 最後に
今回はsupertestを使ったexpressのテストについて取り上げました
1つのエンドポイントのみだとあまりピンとこないかもしれませんが、エンドポイントが増えていったときにこうしたサーバーを立ち上げずにテストができることは、とても便利に感じると思います。

今後もこうしたテストなどの書き方について発信できたらと思っています。
よかったら使ってみてください！
分離して橋渡し！Bridgeパターン


## はじめに 

こんにちは！今回はデザインパターンの一つであるBridgeパターンについて学んだことをまとめたいと思います。

## Bridgeパターン

Bridgeパターンは抽象部分、実装部分というように二つの部分に分離させるパターンです。

例えばレポートの内容(人、お金、仕事など...10種類)、そのレポートの対象期間(年ごと、月ごと、日ごと)をそれぞれ組み合わせたレポートを作成するプログラムを作る必要があるとします。

何も考えずに総当たりでそれぞれのレポートのクラスを作ることはできます。しかし10×3という多大な数のクラスを用意する必要がでてきてしまうでしょう。さらにレポートの内容の種類が追加されるたびにそれに対応する対象期間の3クラスずつ増やす必要がでてきます。


そういうときに活躍するのがBridgeパターンです！
ここでいうレポートの内容を表すクラス群と、対象期間を表すクラス群とを分離することで数の爆発を防ぐことができます。具体的には10+3=13クラスとなります。Bridgeパターンを使わない場合の30クラスと比較すると大きな違いですね！
またレポートの内容の種類が増えた際も上の例のように3クラス増えるのではなく独立しているためレポートの種類を表す1つのクラスを増やすだけでよくなります。


上の例を踏まえるとBridgeパターンを適用するメリットは
- 組み合わせによってクラス数が膨大になることの防止
- 拡張性の向上

が挙げられます。

## 設計

![2024-11-29_21h40_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629646/912c8bdc-713d-ca83-12b5-5757a0686cf4.png)
レポートの種類は省略していますが単純ですね


## おわりに

最近はテスト実施を行うことが多いため、コードに触れたく思い出しがてらまとめてみました。
学んだ当初は経験が少なく思いませんでしたが他のデザインパターンもそうですが自然とパターンを使ってることって多いですよね。

どのような工程の中でも学べることを積極的に学んでいきます！お読みいただきありがとうございました！
Advent of code 2015 Day 17 Part 1 & Part 2 を Livebook で楽しむ

## はじめに

Advent of code 2024 の準備として、過去回の Advent of code 2015 を Livebook で楽しみます

本記事では Day 17 の Part 1 と Part 2 を解きます

問題文はこちら

https://adventofcode.com/2015/day/17

実装したノートブックはこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/aoc/2015/2015_day17_part1.livemd

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/aoc/2015/2015_day17_part2.livemd

## セットアップ

Kino AOC をインストールします

```elixir
Mix.install([
  {:kino_aoc, "~> 0.1"}
])
```

Kino AOC の使い方はこちらを参照

https://qiita.com/RyoWakabayashi/items/3d3abcf9134cee4dff05

## 入力の取得

"Advent of Code Helper" スマートセルを追加し、 Day 17 の入力を取得します

![スクリーンショット 2024-11-29 21.43.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/c4caec65-5b69-c0cf-6a23-eec345b34a53.png)

## 私の答え

私の答えです。
折りたたんでおきます。
▶を押して開いてください。

### Part 1

<details><summary>回答</summary>

入力を数値の配列に変換します

```elixir
containers =
  puzzle_input
  |> String.split("\n")
  |> Enum.map(&String.to_integer(&1))
  |> Enum.sort(:desc)
```

実行結果

```elixir
[50, 48, 45, 44, 42, 41, 35, 35, 33, 30, 24, 20, 18, 18, 16, 14, 13, 13, 6, 1]
```

配列から指定数の全ての組み合わせを取得するモジュールを用意します

```elixir
defmodule Combinations do
  def all(_, 0), do: [[]]
  def all([], _), do: []
  def all(list, n) when length(list) == n, do: [list]

  def all([head | tail], n) do
    with_head = for combo <- all(tail, n - 1), do: [head | combo]
    without_head = all(tail, n)
    with_head ++ without_head
  end
end
```

コンテナの数を 1 個から 20 個まで順に増やしながら、合計が 150 になる組み合わせの数を足していきます

```elixir
1..20
|> Enum.map(fn length ->
  containers
  |> Combinations.get(length)
  |> Enum.count(fn combination -> Enum.sum(combination) == 150 end)
end)
|> Enum.sum()
```

</details>

### Part 2

<details><summary>回答</summary>

コンテナの数を 1 個から 20 個まで順に増やしながら、合計が 150 になる組み合わせが 1 つでもあれば、そのときの組み合わせ数を取得します

```elixir
1..20
|> Enum.reduce_while(nil, fn length, _acc ->
  num =
    containers
    |> Combinations.get(length)
    |> Enum.count(fn combination -> Enum.sum(combination) == 150 end)

  if num > 0 do
    {:halt, num}
  else
    {:cont, nil}
  end
end)
```

</details>

## まとめ

問題文から ChatGPT に画像を生成してもらいました

![eggnog.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/10f7e18e-eb6f-153c-f207-833f23c7b6fa.jpeg)

全ての組み合わせさえ取得できれば、そのまま答えに辿り着ける問題でした