OmniAICreator/Qiita-1.07M huggingface dataset:
教え方の話　その①

## 前置き
今回は後輩や新人に向けての教育について書いていきたいと思います。
とはいえ目下に対することに限らないと思います。

人に何かを教えるときに、飲み込みの早さというのはどうしても現れると思います。
今の自分の教え方ではどうも上手くいかないと思ったときに役立つかもしれないノウハウを共有したいと思います。
私自身、かなりフィーリングでやってることなので上手く文章化できているかはわかりませんが・・・

先にお話しすると、こういった問題を解決するのに近道はないと思っています。
飲み込みが早くないのであればどうしても時間がかかってしまうのが道理です。
ですが、対処の仕方を知っておくことで、不要な衝突を避けたりコストを少なくすることはできます。

## 教え方の話① なかなか理解してもらえないとき
なぜこの仕事をやっているのか、なぜこの手順なのか、どう手を動かしたらいいか。
やる気・覚える気はあるのになかなか理解してもらえないことがあると思います。
こんなときは、前提知識が備わっていないことを考慮してみると良いでしょう。

### 例題
例えばですが、化学のとある問題を例にしてみます。
```
圧力がP1、体積がV1、温度がT1の状態の気体がある。
この気体の圧力をP2、温度をT2に変化させた。このときの体積を求めよ。
```
化学の知識がないとパッと解ける問題ではないと思います。
なので、解けない場合は前提となる知識をどんどん掘り下げていきます。

◆第一段階
この問題を解くのに必要な公式は以下のものです。
```
ボイル・シャルルの法則
P1×V1/T1 = P2×V2/T2
```
この公式を見れば、化学の知識がなくとも計算のセオリーを理解している人であれば解けると思います。

◆第二段階
公式(道具)だけ教えられても、計算のセオリー(使い方)がわからなければどう扱うのかわかりません。
というわけで、この公式が何者で、どう使うかという話ですが、
気体は「圧力×体積÷温度」の計算結果が必ず一定になるという法則があります。
ということは、例えば圧力を大きくする(気体を強く押し付ける)と、体積が小さくなったり、温度が上がったりして「圧力×体積÷温度」が気体を押し付ける前と同じになるということです。

これを踏まえて先ほどのボイル・シャルルの法則`P1×V1/T1 = P2×V2/T2`を見ると、
少し情報が増えたのではないでしょうか。
問題文で、気体の変化前のP1、V1、T1、そして変化後のP2、T2が分かっています。
つまり最終的に欲しい情報は、「体積を求めよ」とあるように、公式の体積にあたるV2だということがわかります。

◆第三段階
ここまでで、やりたいことと必要な道具を説明してきました。
(分かりにくかったら申し訳ない)

ここまでで進め方がピンときていないならば、おそらく
「じゃあ、体積V2を求めるって具体的にどうするの？」という疑問が湧いていると思います。
ここではさらに考え方の補足と手の動かし方の1ステップ目を説明します。
文字がたくさん出てくる式が与えられて、その中の1つだけがわかっていない。
これは数学で習った方程式にあたる計算です。

ということは、V2=～～の形になればV2の正体がわかったことになります。

◆第四段階
ここまでで、例題は実はただの方程式だったということがわかりました。
化学の前提知識としてはこれまでの情報で十分です。
つまりこれ以上前提を掘り下げるならば、化学の知識ではなく数学の方程式の説明になるわけです。

## つまり・・・
例題を解くのは本題ではないので以降はすみませんが割愛します。
ここまでで書いた通り、最終的に目的を達成するのに必要な前提を掘り下げていくと、
直接的な知識だけでなく遠いと思っていた分野の知識も必要になることもあります。
そして、最初に仕事を投げてもちんぷんかんぷんだった人が、
前提を理解してしまえば見方が変わり、すぐ仕事をこなせるようになるということもあり得ます。
(実は私もそういう傾向があります・・・)

飲み込みが遅いので使えない・・・もっと要領の良い人材が欲しいと思ってしまうこともあると思います。
しかし、まずは根本から知識や見方を見直してみて、教え方で解決できないかを探ってみてはどうでしょうか。

個人的な意見になってしまいますが、「使えない」と切り捨ててしまう人材の中には、将来輝く原石があるのかもしれませんし、
なにより、1人も解決しようと動く人がいなければ、一生「使えない」人間のまま切り捨てられ続けてしまうことになり、それは悲しいことだと思います。
共感していただける方がいたら嬉しく思います。

他の例については後日余力があれば書きます。
サイコロ・シュミレータ （CASIO fx-5800P BASIC用ソースコード）



## １．はじめに

サイコロ・シュミレータは３個までのサイコロを振るためのプログラムです。「あ！しまった！サイコロがないじゃん…」というときに（あるのか？）使っていただけます。
<iframe width="479" height="851" src="https://www.youtube.com/embed/iPdBQg1N5q0" title="サイコロ・シミュレータ（CASIO fx-5800P用BASICプログラム）" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## ２．プログラムの使い方

![DICE - 1 (1).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27292/96e3af83-b669-2fb6-3a1a-b854000e1d3b.jpeg)


- 実行するとHOW MANY DICE(1-3)?と聞いてくるので、サイコロの個数（最大3つまで）をテンキーで入力しEXEを押してください。画面は３と入力したところ

![DICE - 2 (1).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27292/8ba82150-7438-a69d-e4df-5d5d667fac86.jpeg)

- 指定した数のサイコロが振られ左詰めで表示されます <h1>⚃⚅⚅</h1>
- 右下（ ）には総てのサイコロの目の合計を表示します
- 2個以上サイコロを振った場合、3行目の右端にはそれぞれのサイコロの出目を数字で表示します
- なにかキーを押せば、続けてサイコロを振ります（以下続く）
- 終了したい場合（Quit▶）はマイナスキー「ー」を押してください

![DICE - 3 (1).jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27292/82093c6e-9f27-ce03-74b1-5e14a32be594.jpeg)
- 画面がクリアされDoneと表示された終了画面です
- ACボタンで強制終了もできますが、プログラム編集モードに入ってしまうので、プログラムを壊すリスクを避けるためマイナスキーで終了することをお勧めします

## ３．ソースコード ※fx-5800P BASIC用です
**注意:** ソースは可読性UPのため<font color=red>**字下げして//でコメントを書いていますが、いずれもCASIO　BASICではエラーになります**</font>ので、実際にご利用される際には除去して下さい。
- GetKeyのキーコードだけ差し替えればfx-9750GIIIやfx-CG50などでも動作可能です（試していません）
- プログラムで使用する変数　
    - N：サイコロの数（１〜３で任意に入力）
    - I：ループ索引（サイコロの個数分表示のため）
    - D：サイコロの乱数を格納
    - K：キー入力判定用
    - T：サイの目の合計を格納


```
Do                    // サイコロの個数を入力（３個まで）
	"HOW MANY DICE"
	"(1-3)?→N
LpWhile N<1 Or N>3
Int(N)→N

While 1
	0→T:CLS                 // サイコロの目の合計Tをクリア
	Locate 1,4,"---+---+---+(  )"
	For 1→I To N            // サイコロN個を振って表示する
		RanInt#(1,6)→D
		N>1⇒Locate 13+I,3,D  // サイ２個以上：目をアラビア数字でも表示
		T+D→T
		If D=1:Then
			Locate (I-1)x4-1,2," 0 "
		Else If D=2:Then
			Locate (I-1)x4-1,1,"0  "
			Locate (I-1)x4-1,3,"  0"
		Else If D=3:Then
			Locate (I-1)x4-1,1,"0  "
			Locate (I-1)x4-1,2," 0 "
			Locate (I-1)x4-1,3,"  0"
		Else If D=4:Then
			Locate (I-1)x4-1,1,"0 0"
			Locate (I-1)x4-1,3,"0 0"
		Else If D=5:Then
			Locate (I-1)x4-1,1,"0 0"
			Locate (I-1)x4-1,2," 0 "
			Locate (I-1)x4-1,3,"0 0"
		Else                         // サイの目６
			Locate (I-1)x4-1,1,"0 0"
			Locate (I-1)x4-1,2,"0 0"
			Locate (I-1)x4-1,3,"0 0"
		IfEnD:IfEnD:IfEnD:IfEnD:IfEnD
	Next
	Locate 14,4,T        // N個のサイの目を合計して（ ）内に表示
	Locate 14,2,"Q▶r∠θ”：Locate 16,2,"-  "  // "Q▶-"と表示
	
	GetKey→K
	Do:GetKey→K:LpWhile Not(K)
	If K=67:Then:CLS:Break:IfEnd    // "-"キーでプログラム終了
				         // AC以外のキーなら無限ループ
WhileEnd
```
英語学習を支援するChrome拡張機能 "ClipLex" を開発した話

## TL;DR

ソースコードは、以下のリポジトリで公開しています。

https://github.com/makinzm/cliplex/tree/main

本拡張機能ClipLexを使うことで、文字列選択をするだけで単語を保存し、後で復習することができます。また、保存した単語には優先度やメモを追加でき、学習効率を向上させることができます。

## 背景

英語を日々の仕事や学習で使うエンジニアにとって、語彙力の向上は重要です。しかし、公式ドキュメントやブログ記事で出会う新しい単語をいちいちメモして復習するのは、時間がかかり面倒な作業です。

その課題を楽しく解決するために開発したのが、今回紹介するChrome拡張機能 "ClipLex" です。このツールを使えば、ウェブページ上で選択した単語を簡単に保存し、後で復習することができます。

## 解決したい課題

- **公式ドキュメントで出会う単語の整理:**
  市販の単語帳にある単語も多いですが、それよりレベルの高いような語彙がたくさん出てくるため、それらを効率的に管理したいです。
- **記録・復習の手間を軽減:**
  手書きのメモやスプレッドシートで管理する代わりに、手軽に保存・管理したいです。

## "ClipLex" の機能

"ClipLex" は以下のような特徴を備えています:

1. **ワンクリックで単語を保存:**
   ウェブページ上で単語を選択すると、ボタンが表示され、それをクリックするだけで保存可能です。

2. **辞書リンク付き:**
   保存した単語には主要な辞書サイト（Oxford、Weblioなど）へのリンクがついており、発音や使われ方、意味を確認できます。

3. **優先度とメモの管理:**
   保存した単語に優先度を設定し、メモを追加して学習効率を向上させることができます。

4. **絞り込みとソート:**
   追加日や優先度で保存した単語をフィルタリングし、ソートすることができます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417525/c9ff47a4-ca32-a9ec-07ee-c4286848514d.png)


## 開発の詳細

### 技術スタック
- **言語:** TypeScript
- **拡張機能:** Chrome Extension (Manifest v3)
- **ビルドツール:** Webpack

### UI の工夫
設定ページでは、ユーザーが保存した単語を簡単に管理できるようにしました。

このテーブルには、保存された単語や優先度を動的にレンダリングされるため、英単語学習の効率を上げてくれます。

また、発音や例文、意味の確認を行いやすいような便利リンクが配置されているため、すぐに使われ方などを確認することができます。

![ClipLex Option Screen](https://raw.githubusercontent.com/makinzm/cliplex/refs/heads/main/docs/screenshots/cliplex_options_v1.0.0.png)

## 今後の展望

- 保存した単語をクラウドで同期する機能の追加
- モバイルブラウザ向けのサポート
- 学習進捗を可視化するダッシュボード機能

## おわりに

"ClipLex" は、英語学習の課題を解決することを目指して開発されました。このツールが、読者の皆さんの学習に役立ち、少しでも楽しい英語学習のお手伝いができれば幸いです。

ぜひ、「いいね」やストックで応援していただけると励みになります！
ProtonPassをパスワードマネージャーに使い始めた話

# はじめに

この記事は、Qiita Advent Calendar 12日目の記事です。
以下の記事より、すべての記事をご覧になれます。

https://qiita.com/0_terarin_0/items/2b60d47a2d0e64a273c3

# 本編

iCloud Keychainを使っていたのですが最近WindowsやAndroid、Linuxを使い始めたので少しパスワードの管理状況について考えてみることにしました。

## iCloud Keychainのメリットとデメリット

:::note info
メリット
- Appleの端末では特に何も考えなくてもパスワードを管理できる
- 割と安全にパスワードを管理できる
- Passkeyの管理も楽
:::

:::note warn
デメリット
- Appleの環境以外では少し面倒
- Firefoxとの相性が悪い
:::

## 他の選択肢

- 1Password
- Proton Pass
- Bitwarden

このなかで、1Passwordは有料ということで除き、Bitwardenは以前使ったことがありましたので、今回は初めてのProton Passを使ってみることにしました。

## Proton Passのメリットとデメリット

:::note info
メリット
- オープンソース
- Apple製品以外の端末やブラウザでもまあまあ使える
- 外部サービスなのにPasskeyも使える
:::

:::note warn
デメリット
- 一部の機能が有料
:::

こんな感じです。とりあえずProton Passを使ってみましょう。アカウントの登録は公式ホームページからです。

https://proton.me/pass

つづいて、設定が終わったらブラウザに拡張機能をインストールしましょう。

https://chromewebstore.google.com/detail/proton-pass-free-password/ghmbeldphafepmbegfdlkpapadhbakde

https://addons.mozilla.org/ja/firefox/addon/proton-pass/

もちろん、iPhoneとAndroidへのインストールも忘れずに！

https://apps.apple.com/us/app/proton-pass-password-manager/id6443490629

https://play.google.com/store/apps/details?id=proton.android.pass

あとはどんどん使っていくだけです！

## 使った所感

個人的にはとても使いやすいものです。クロスプラットフォーム、Passkey対応。個人的には今後おそらくパスワード管理でメインになるものですね。プロファイルに分けれるのも一つ魅力ですね！今後はProtonの他のサービスも使っていきたいと思います。

# 最後に

今回の記事は薄すぎる気もしますが、もうちょっとしたらTailscale扱ったりでかいのくるのでどうか多めに見てくださいませ。
【UE5】Nav Mesh Bouds Voulumeに入ったActorを検出する

# 0. 最初
こちらの記事は
「UnrealEngine Advent Calendar 2024 シリーズ2　15日目」
の記事になります！

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

# 1. 概要
UEでAIを制作する際に使用する「Nav Mesh Bouds Voulume」に侵入した
Actorを検出する方法をまとめます

今回は「Third Person Template」で検証を行います

# 2. 完成
以下が最終形の完成になります
![無題の動画-‐-Clipchampで作成-_4_.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/6f6a94ea-5fc2-b8fd-26a8-72095425c5b4.gif)

※今回はUIに関しては説明はしません

# 3. NavMesh管理のクラスを実装する

「BP_EnemyTerritoryManager」とBPを作りレベルに配置します

「NavMeshBoudsVoulume型」で変数を定義して「NavMesh」と名前をつけ
侵入の判定を取りたい「NavMeshBoudsVoulume」と「NavMesh」を結びつけます

![スクリーンショット 2024-12-15 184201.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/39f78f51-68e8-1a9f-cf4d-a16a6a5d1f8e.png)


「NavMesh」からDelegateで
「Event to OnActor Begin Overlap」と「Event to OnActor End Overlap」
を以下の用に繋げると判定が取れます

![スクリーンショット 2024-12-15 184724.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/77d6dea4-b2d0-5284-6c69-2ee2e8fd4560.png)


# 4. 終わり
見てくれてありがとうございます！
各種AIにプレイヤーの侵入に伝達したりなど使い方があるかもしれません！
少しでも参考になれば幸いです！！
LILYGO T-Deck Plus　③：搭載キーボードからのREPL入力を可能にする

# キーボード入力ができるようになるか

[前回](https://qiita.com/inachi/private/1e9b5361935c4200c650)で T-Deck PlusにCircuitPythonを入れたわけですが、LCDにREPLが表示されるものの、搭載キーボードからの入力でできないという状況。

keypad API はサポートされているので、頑張れば実現できそうであるが、Adafruitとしては自社ボードではないので、キーボードサポートは優先順位がかなり低いであろう。

# tdeck_repl

同じように、キーボードサポートを待望している人はいるようで、[PyDOS](https://github.com/RetiredWizard/PyDOS)の入力処理を参考に、キーボード入力部分を作成したものがありました。

https://github.com/RetiredWizard/tdeck_repl

T-Deck Plus を USB ケーブルで繋いで電源を入れた後、PC上で次の操作を行う。

```bash
$ git clone https://github.com/RetiredWizard/tdeck_repl
$ cd tdeck_repl
$ cp tdeck_repl.py <CIRCUIYPYフォルダのパス>/lib
$ cp code.py <CIRCUIYPYフォルダのパス>
$ cp virtcode.py <CIRCUIYPYフォルダのパス>
```

リセットボタンを押して、CircuitPython を再起動する。

![IMG_1767.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106817/d1f9f632-33f1-d05f-9c4d-4bde4eab1e2f.jpeg)

REPL のプロンプトが `=>>` に変わっていて、T-Deck のキーボードから入力が可能になっている。左右のカーソル移動や入力履歴をたどるのはトラックボールから行える。

キーボード上に無い文字についてはマルチキー入力で可能になっている。

| マルチキー入力 | 入力文字 |
|-------------|---------|
| _-          | = |
| (+          | [ |
| +)          | ] |
| (-          | < |
| -)          | > |
| _#          | ^ |
| _/          | \ |
| -/          | % |
| _!          | & |

この tdeck_repl を抜けるには `exit` を実行する。通常の REPL 表示に戻る。

# 使ってみた感想

キーボード入力ができるようになるのは、非常にありがたい。

しかし、入力処理は独自の input() 関数で実現されているため、REPL 操作のすべてがサポートされているわけではない。たとえば TAB による補完や、Ctrl キー操作、ペーストモードが使えない。

cardputerあたりの実装を見てみると、キー入力を直接 REPL に伝える方法はありそうである。いずれできるようにしてみたい。
データ分析がもたらす価値を考えてみた

**データ分析**
それは収集した大量の情報から、
人間が解読可能なよう情報を要約する行為だ。

![16C39CB7-1531-4C25-BAEE-F6D18AD8712E.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397581/d4b1c2a3-0519-1559-7a6b-fc0fc4908fce.jpeg)

## 思い込みを捨てて事実を見よう
私は現在、データ分析を生業にしている。
正確にはデータサイエンティストという職業になるので、システム周りを担当することもある。

この仕事を志したきっかけに「**FACTFULNESS**」という本が大きく影響している。

この本のタイトル、ファクトフルネスとは「先入観や思い込みを捨てて、事実(データ)に基づいて世界を見よう」と言う意味で、
著者のハンス・ロスリング氏が作った造語だ。

話が少し脱線するが、このハンス氏は本当に愉快でおもしろいひとだ。彼の[TEDトークの演説](https://youtu.be/hVimVzgtD6w?si=-WZ_yKN0QH9hgoq9)は最高なのでぜひ見てみてほしい。

たとえ高学歴な人でも先入観があり、世界の真実に関する簡単なクイズに対して**チンパンジー以下**の正答率だと笑って語るシーンが私のお気に入りだ。

この本からは本当に多くを学んだ。
特に以下の2点は常に私の心に残っている。

•**データを基に事実を捉えることの重要性**
•**先入観や思い込みで物事を捉えることの危険性**

人間が抱える思い込みは、ときに本能からきてしまうことがあり非常に厄介だ。

## 世界人口のうち極度の貧困にある人は何割か？
ここで１つ具体例をあげよう。

<質問>
世界の人口のうち、極度の貧困にある人の割合は、過去20年間でどう変わっただろうか？

A. 約2倍になった
B. あまり変わっていない
C. 半分になった

この問いの答えは、本ブログの1番下に書いた。
ここでは人間のネガティブ本能がかき立てられ、不正解者が多く見られる。

それはまさにテレビ番組でショッキングなトピックを扱うと視聴率が良くなるので、そのような内容ばかり報道するこの世の中が証明している。

それらのニュースや記事やテレビ番組を視聴することで、我々人間はいとも簡単に**世界は悪くなっている**と勘違いしてしまうのだ。

## データが真実を教えてくれる
データ分析をしていると、しばしばよく期待を裏切られる。
もちろんそれは良いことだ。

絶対にこれが原因だ！って思っていたのだが、データはそれを物語っていない。
むしろ別の(本来の)原因を教えてくれたりする。

その瞬間、私は「またやられた！」と楽しくなってしまう。なぜならそれは自分の思い込みに気づくことができた証拠だから。

この思想には、知ったかぶりもプライドも忖度も何も役に立たない。

だからこそ「**曇りなき眼**」で見定めることができるのだ。
※曇りなき眼はもののけ姫に出てくる言葉です。

## 数字は嘘をつかないが嘘つきは数字を使う
データ分析には注意点がある。
それは都合の良いデータだけを選んだり、グラフの目盛りを操作して過大評価を得ようとする輩がいると言うことだ。

時には無知がゆえに、悪気なくやってしまう人もいるのでさらに注意が必要だ。

![IMG_7700.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397581/ace9c5e6-fe8e-5d36-faae-357732517d20.jpeg)
[こちら](![image.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397581/72c4f9da-a76c-2ae4-e7f1-ba6a9832cb0e.jpeg)
)の記事の画像です。

このグラフは典型的なNGパターンだ。
グラフの原点は原則、0でなければならない。
しかしこれは差を誇張させるために、故意に原点がいじられている。

このように嘘つきが数字を悪用するパターンを知っておくと、騙されにくくなる。

データ分析の素養があると、武器になるだけでなくこのように**盾**にもなりうるのだ。


## データ分析がもたらす価値をまとめる
最後にタイトルに記載した**データ分析がもたらす価値**をまとめておこう。

①主観ではなく事実を基に物事を捉えられる
②根拠が明確になり、他者への説明が楽になる
③今まで思いつかなかった視点が得られる
④人間の本能を悪用するメディアから身を守れる
⑤数字を悪用する嘘つきから身を守れる

■とりわけビジネスの場で生きる価値
⑥最も効率よく意思決定できる
⑦パーソナルデータを活用して個別化した施策をうてる
⑧施策の効果検証ができる
⑨過去のデータを活用して未来を予測できる
⑩データドリブンな経営で競争優位性を得られる


おそらく全部は挙げられていないと思うが、
こんなところだろうか。

後半の⑥〜⑩は説明足らずでイメージが湧かないと思うが、1つ1つ解説すると長くなってしまうので今回は省略させていただく。

データ分析は適切な活用によって、多くの分野で**大きな価値**を生み出すことは間違いない。

---

私はこのデータの価値を「自然と人間の共存」に生かしていくのが人生のテーマだ。
国境を越えてグローバルな取り組みを促す。
そんな仕事ができるよう邁進していきたい。

---

質問の答えは以下です。
C. 半分になった

---
Reactで初めてのアプリ制作

ReactとモダンJavaScriptの基礎を学んだので、アウトプットとして簡易な学習記録アプリの制作を行いました。

![LeaningRecordApp.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3941608/f57ef241-192a-1969-2ef2-f425d72a97c8.gif)

## 制作開始から完成まで
最初はAIコードエディタを使用して制作を始めたのですが、なんでもかんでもAIがやってくれるので **これでは勉強にならない！** と気付いてVSCodeに戻って一からやり直しました。
が、まず何から書き始めればいいのかわからず、インプット教材として使用したUdemy動画や、そのさいに書いたコードを見直しながら書き始めました。
[ハマったところもありましたが、](https://qiita.com/IchidaU/items/3a233b1cd236bfa59f07)何とか形になるものが出来上がりました。
しかし、理屈がよくわからないままコードを継ぎ接ぎした感がどうしても否めず、コードを見直しながら理解の弱い点についてはUdemyを見返して復習しました。

## 気付き・学び
気付きというかほぼ反省ですが……
- 初学者はAI頼み、ダメゼッタイ。使用するにしても検索の補助程度にすべし。
- 「どんな動作・機能を実現したいのか？」を分解して考えないと一からコードは書けない。
- インプットはかなり意識しないと右から左に抜けてしまう。
- アウトプットも復習の面を意識しないとただの写経に終わる。

## 苦労した点
- 当初はState周りがなかなか理解できず、データの受け渡しが全くイメージできなかった。
- そのせいか、時間を積算するために使用した`parseInt`を入れる場所がわからない、というようなことが起きた。
- 2つあるフォームのいずれかが未入力の場合、エラーメッセージが表示されるようにしたが、一度表示されたメッセージを消す方法がわからず、かなり時間を費やした。詳細は下記記事。

https://qiita.com/IchidaU/items/3a233b1cd236bfa59f07

## 成長を感じた点
- Stateの理解がかなり進んだ。元々Javaを学習していた頃からデータの扱い方は苦手だったのだが、今回の制作を通じてプログラミングにおけるデータの扱い方についてようやくわかってきた。
- 実際に手を動かし、復習を重ねることで「なんとなくわかった」から脱することができた。
- 自分で試行錯誤して一つのものを作ったことで、自信につながった。

## おわりに
正確な時間は計っていないのですが、トータルで8時間くらいはかかったのではないでしょうか。

制作中はずっとうんうん唸っていましたが、振り返るとなんだかんだで楽しかったです。

なにより、独学でJavaScriptやReactを勉強して挫折したときに全く理解できなかったことがわかるようになったことは嬉しいですね。

再レンダリングなどまだ理解ができていない部分がまだまだあるので、これからも学習を続けていきたいと思います！

# JISOUのメンバー募集中！
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
興味のある方は、ぜひホームページをのぞいてみてください！
▼▼▼

https://projisou.jp
vscode-pokemonを導入してみた

## 背景
おすすめの記事にvscode-pokemonの紹介があり、とってもかわいかったので我が家の環境にも導入することにしました。

https://qiita.com/miyarappo/items/3b80cb359966e9a7ecf7

## vscode-pokemonとは？
VSCodeの拡張機能で、左下にポケモンが召喚されます。
それ以外の機能は特になく、癒され拡張機能です。
![vscode-pokemon-light.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931306/159ed833-5b6f-a851-cd5b-f8bb9d1fdb4d.gif)

https://marketplace.visualstudio.com/items?itemName=jakobhoeg.vscode-pokemon


## さっそく導入
### インストール
拡張機能のところで`vscode-pokemon`と検索するとでてきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931306/faeb1081-e0fb-4b4c-d687-7333419580aa.png)

### スタート
ただしインストールするだけではだめのようで、コマンドパレットを開いてスタートする必要があるようです。

1. `Ctrl+Shift+P`でコマンドパレットを開く
2. `pokemon`と入力し、`Start Pokemon coding session`を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931306/a9f5dfa0-7960-4322-f9eb-9dc1cb31002f.png)

フシギダネがでてきました。
ちょこちょこ歩いていてかわいいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931306/d98413c0-8dd1-4a90-096b-2806553f99a7.png)


## 増やし方
シャッフルボタンでポケモンガチャが引けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931306/0db0dbdf-f30f-8222-3469-c3208895c3eb.png)

ウパーでした。かわいい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931306/9baa9be2-9f1e-e33f-416f-89a67a48d7c4.png)

プラスボタンで好きなポケモンを追加できますが、英語なのでちょっとわかりずらいかも。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931306/54bfcc56-6ac4-621a-ff89-f5e73a86ed51.png)
ちなみに、プラスボタンで追加すると名前を付けることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931306/94e2086f-a134-c7a0-9653-ca15323a60ef.png)


## サヨナラの仕方
お察しの通り、削除ボタンでサヨナラします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931306/b402bff3-25b3-ab97-0b91-69d7edf987c8.png)

ただ、上記のやり方だと1匹ずつしかサヨナラでできません。
下の画像のようにポケモンがいっぱいだと大変です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931306/c7c0a595-8d5d-a9ce-b09f-bd0a7150a3a5.png)

個人的には賑やかで好きですが、まとめてサヨナラしたい場合は下記手順で可能です。
1. `Ctrl+Shift+P`でコマンドパレットを開く
2. `pokemon`と入力し`Remove All Pokemon`を選択

みんないなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931306/4a6f8579-58ed-be8b-95ad-090d6d78ef2e.png)



## その他
下記手順でポケモンの大きさや背景、表示箇所をカスタマイズできます。お好みの飼育環境にしてください。
1. `Ctrl+,`でSettingsを開く
1. vscode-pokemonと入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931306/165703dc-ed26-812a-dcfd-0e4d1eb3e4b5.png)


## 感想
普段の作業環境に癒しが訪れました。
導入してからまだ長くないのでこれから意見が変わるかもしれませんが、少なくとも短時間作業した感じでは気になりませんでした。

:::note info
こういうのでいいんだよこういうので
:::

これからよろしく、我がポケモンたち。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931306/b1460613-a566-2614-2ffb-c42c1be9fd3f.png)
Nerves: NervesTime で時間管理


## はじめに

組み込みシステムや IoT アプリケーションでは、正確な時間管理が非常に重要です。ログの記録、イベントのスケジュール、データの整合性など、多くのシステム機能が正確なタイムスタンプに依存しています。しかし、リアルタイムクロック (RTC) がないデバイスや、ネットワークにアクセスできない環境では、正しい時刻を維持することが課題となります。

本記事では、Elixir ベースの組み込みシステム向けフレームワーク [Nerves] における時間管理の課題と、それを解決するための強力なツールである [NervesTime] パッケージについて公式 README に基づいて簡単に説明します。

## Nerves とは？

[Nerves] は、IoT や組み込みシステムを効率的に開発できるオープンソースのフレームワークです。
Elixir 言語の堅牢性と Erlang エコシステムの信頼性を活用することで、柔軟でスケーラブルなアプリケーションを簡単に構築できます。

## 時間管理の課題

組み込みシステムでは、RTC がない場合、デバイスが起動するとデフォルトで `1970-01-01 00:00:00 UTC` に設定されます。
この問題に対処する方法として、以下が一般的です。

1. **NTP サーバーを利用**
   - ネットワーク接続がある場合に有効ですが、接続が途切れると同期が取れなくなります。
2. **RTC を追加**
   - 正確な時間管理が可能ですが、追加のハードウェアとバッテリーが必要です。
3. **スクリプトで対応**
   - システムの起動時にスクリプトで時刻を設定しますが、メンテナンスの手間が増えます。

これらの解決策は一長一短であり、特に IoT プロジェクトではコストや実装の複雑さが課題となることがあります。

## NervesTime とは？

[NervesTime] は、Nerves プロジェクト向けに設計された時間管理パッケージで、以下の特徴があります。

- **RTC がなくても時刻を推定可能**: デバイスが最後に使用された時刻を基に、`NervesTime.FileTime` を利用して、`~/.nerves_time` の最終更新時刻を基に現在時刻を推定します。
- **NTP サーバーとの統合**: ネットワーク接続がある場合に自動的に同期を実行します。デフォルトでは [ntp.pool.org](https://www.ntppool.org/) の NTP サーバーが使用されますが、`config.exs` で代替サーバーを指定することも可能です。
- **時間範囲のカスタマイズ**: 指定した時間範囲外のタイムスタンプを防止できます。
- **RTC との統合**: 必要に応じて RTC を使用して精度を向上。

これにより、複雑な時間管理を簡略化し、組み込みシステムに適した信頼性の高いソリューションを提供します。

:::note
[NervesTime] はほとんどの Nerves システムに対応しており、簡単な設定で利用可能です。
:::

## IoT 環境での実用例

[NervesTime] を使用することで、次のようなシナリオで時間管理が簡単になります。また、時間範囲のカスタマイズを行うことで、指定した範囲外のタイムスタンプを防ぎ、RTC やインターネット接続がないデバイスでも信頼性の高い時間管理を実現できます。

- **リモート環境でのデータ収集**: ネットワーク接続がない環境でも、適切なタイムスタンプでデータを記録。
- **断続的なネットワーク接続**: NTP サーバーと自動同期することで、接続時に時刻を修正。
- **RTC 未搭載デバイス**: 最後の使用時刻を基に起動時の時刻を推定。

## NervesTime の導入方法

### インストール

`mix.exs` ファイルに以下を追加してください。

```elixir
def deps do
  [
    {:nerves_time, "~> 0.4.8"}
  ]
end
```

その後、以下のコマンドを実行して依存関係をインストールします。

```bash
mix deps.get
```

### 設定

[NervesTime] を使用するには、`vm.args` ファイルに以下の設定を追加します。
この設定は[Time Warp](https://www.erlang.org/doc/apps/erts/time_correction.html#time-warp-modes)を有効にするために必要です。

```elixir
+C multi_time_warp
```

さらに、プロジェクトの設定ファイル (`config.exs`) に初期化待機時間を指定します。この設定は、アプリケーションが有効な時刻が設定される前に起動するのを防ぐためのものです。

```elixir
config :nerves_time, await_initialization_timeout: :timer.seconds(5)
```

## まとめ

[NervesTime] は、組み込みシステムや IoT プロジェクトにおける時間管理の課題を解決する強力なツールです。その簡潔な設定、柔軟な機能、信頼性の高さから、Nerves プロジェクトにおいて欠かせない存在と言えるでしょう。

興味のある方は[公式ドキュメント][NervesTime]でさらに詳しい情報をチェックしてみてください。

![toukon-qiita-macbook_20230912_091808.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82804/fd5c55ec-4fe0-8af6-59bc-bab1ef3d182b.jpeg)

[Nerves]: https://hexdocs.pm/nerves
[NervesTime]: https://hexdocs.pm/nerves_time
MacでGit接続時のURL注意点

# はじめに
MacからSSHでGitHUBからプルする際に、サーバが見つからないだとか、権限がないだとか言われてなかなか繋がらなかった。
MacからSSHで接続する際のURLとして省略形式と完全形式があり、それぞれ指定方法が異なる。
SourceTreeを使っている時など「SSHに変換する」など選択しようものなら繋がらなくなったりする。
そこを調査したためメモとして残す。

:::note
SSHの設定（GitHUBへの登録）は完了しているものとする
:::

## 大まかな手順
1. 省略形式のURL
1. 完全形式のURL

:::note
リポジトリをブラウザで見た時のURLが`https://github.com/xxxx/yyyy`であった時での解説。
:::



## 省略形式のURL
```
git@github.com:<organization>/<リポジトリ名>.git
```

- `git@github.com` ここまでは固定
- `<organization>` コロンで区切って`xxxx`
- `<リポジトリ名>` `yyyy`の部分

よって指定方法は以下となる。


```
git@github.com:xxxx/yyyy.git
```


## 完全形式のURL
```
ssh://git@github.com/<organization>/<リポジトリ名>.git
```

- `git@github.com` ここまでは固定
- `<organization>` スラッシュで区切って`xxxx`
- `<リポジトリ名>` `yyyy`の部分

よって指定方法は以下となる。
```
ssh://git@github.com/xxxx/yyyy.git
```


## まとめ：省略形式と完全形式でどこが違うのか

| 項目 | 省略形式 | 完全形式 |
|-----|---------|---------|
| プロトコルの明示 | 明示なし | 明示あり<br>先頭に`ssh://`が付く |
| organaizationの区切り | コロン「:」 | スラッシュ「/」 |
kotlin 文字の始まりと終わりにある半角全角スペースを取り除く方法

文字の始まりと終わりにある半角全角スペースを取り除く方法です

```.kt
val sampleString = "　sample String " 
println("${sampleString.trim()}") 
```
結果
`sample　String`

`trim()`を使用することで文字の始まりと終わりにある半角全角の空白を取り除くことができます。
JUnitの日本語Wrapperを作ってみた

この記事は [Java Advent Calendar 2024](https://qiita.com/advent-calendar/2024/java) 18日目の記事です。

みなさん割と言語仕様について書かれているので毛色が違うものになりますが、ご容赦ください。

今回はだらだら作ったJUnitの日本語Wrapperの紹介です。なお全然メソッド網羅できてません。

コードはGistに上げています。

https://gist.github.com/h-kono-it/8ad08c3fc3c510ea3215e2998f30d825

## 作った理由など

端的に言うと、日本語話者には`expecteds`と`actuals`がわかりにくいと思ったからです。

チームメンバーから上がってきたプルリクですべて逆になっているものもありましたし、私だけではないと思っています。

### JUnitの引数がわかりにくいと思った理由

まず単純に英語が苦手だからですね。`expecteds`と`actuals`でいつもどちらが期待する値でどちらが実際の値か迷います。

2つ目の理由として、なんとなく検証対象の値を先に書きたいと考えるからです。

語順的に「何が」「どうである」のほうが自然ですし、関数の重要度的にも`actuals`のほうが第一引数にふさわしいように思えます。

一貫性という意味でも引数を1つしか取らない`assertNull`などが存在するため、`actuals`が第一引数のほうが自然に思えます。

ということでなぜ`expecteds`が第一引数なのか調べようと思ったんですが、先人がいましたのでリンクのみ貼ります。

https://qiita.com/jnchito/items/a8a16a8242889b41d8ec

結論としては「`expecteds`のほうがリテラルを入れることが多く、短くなりやすいため可読性が高いから」ということらしいです。

私は書くことに重きを置いていたので、読むときの視点は抜けていました。

## このWrapperがどのように解決するか（あるいは簡単な使い方）

`assertEquals`をサンプルに使い方を簡単に紹介します。

まずは通常のJUnit5を使う場合のコード例は次のようになりますね？

```java
assertEquals(5, calculator.add(2, 3));
```

一方、今回のWrapperでは次のように書けます。

```java
実行結果.の(calculator.add(2, 3)).は期待値の(5).と同じです();
```

日本語話者には圧倒的にわかりやすいですね。（まるで[なでしこ](https://nadesi.com/)）

次に引数が1つのパターンのサンプルです。

```java
assertNull(hoge.stringOrNull()); // サンプルなのでOptional使えとか言わないでください＞＜
```

コード書かなくてもわかりそうな気がしますがWrapperで書き換えると次のような感じです。

```java
実行結果.の(hoge.stringOrNull()).はnullです();
```

## 終わりに

これで毎回`expecteds`と`actuals`でどっちがどっちだっけって迷わなくて済むようになりました。

今後の展望としては次のようなことを考えています。

- ジェネリクスあたりが怪しいので修正する
- 全メソッドを網羅する

JJUG CCC 2024 Fallでも「今日から始めよう🚀日本語🇯🇵プログラミング🧑🏻‍💻」という内容の発表がありました。

今回はJUnitのWrapperを作りましたが、「可読性の高い」コードを書くために、日本語でのプログラミングを進めてみてはいかがでしょうか？

#### 修正
2024/12/18 Gist：引数も日本語を使うように修正
【React Hook Form】useFormとuseFormContextの使い分け

# はじめに
業務で`React Hook Form`を使用している際に、`useForm`と`useFormContext`の2つの違いについて疑問を感じたため、整理して記事にしました。名前が似ているため混乱しやすいですが、それぞれの使い方には違いがあります。

:::note warn
***この記事は<font color="Red">個人的なアウトプット</font>を目的として作成したものです。そのため、誤った情報や不足している内容が含まれている可能性があります。もし間違いや気になる点がございましたら、ぜひご指摘いただけますと幸いです***。
:::

# `useForm`と`useFormContext`について
## `useForm`とは

>useFormは、フォームを簡単に管理するためのカスタム フックです。オプションの引数として 1 つのオブジェクトを受け取ります。

https://react-hook-form.com/docs/useform

+ 役割:`useForm`は***フォームの状態の管理***
+ 使い所:単一のフォームを管理する場合

## `useFormContext`とは
>このカスタム フックを使用すると、フォーム コンテキストにアクセスできます。useFormContextこれは、コンテキストをプロパティとして渡すことが不便になるような、深くネストされた構造で使用することを目的としています。

+ 役割:`useFormContext`は作成済みのフォーム状態を`Context`を通じて取得する
+ 使い所:ネストされたコンポーネントでフォーム状態にアクセスする場合

https://react-hook-form.com/docs/useformcontext

# 使いわけ
***`useForm`を使う場合***

`useForm`はフォームの状態管理を行う基本的なフックです。単一のフォームを管理する場合は`useForm`だけで十分です。

```react
import { useForm } from "react-hook-form";

const Form = () => {
  const { register, handleSubmit, reset } = useForm();

  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("name")} />
      <button type="submit">Submit</button>
    </form>
  );
};

```
***`useFormContext`を使う場合***

`useFormContext`は、`FormProvider`で提供されたフォームの状態にアクセスするためのフックです。フォームが複数のコンポーネントで構成されていたり、フォーム状態を共有する必要がある場合に使用します。

```react
import { useForm, FormProvider, useFormContext } from "react-hook-form";

const InputField = ({ name }) => {
  const { register } = useFormContext(); // useFormContextでフォーム状態にアクセス
  return <input {...register(name)} />;
};

const MyForm = () => {
  const methods = useForm();

  const onSubmit = (data) => {
    console.log(data);
  };

  return (
    <FormProvider {...methods}>
      <form onSubmit={methods.handleSubmit(onSubmit)}>
        <InputField name="firstName" />
        <InputField name="lastName" />
        <button type="submit">Submit</button>
      </form>
    </FormProvider>
  );
};

```

# 終わりに
`useForm`と`useFormContext`は名前が似ているものの、それぞれ異なる役割を持っています。この違いを意識することで、`React Hook Form`をより効率的に活用できるようしていきたいです。

# 参考
『react-hook-formのuseFormとuseFormContextの違い』Qiita

https://qiita.com/yoshinyan/items/e2252305b9fb83e7cac2

https://react-hook-form.com/docs/useform

https://react-hook-form.com/docs/useformcontext
レガシー言語エンジニアがJavaに挑戦してみた感想

今回はJava未経験の私が急にJavaに挑戦することになり約1年、大変だと思ったこと、いいなと思ったことなど率直にJavaに対する思いを語りたいと思う。これから初めてプログラミングにチャレンジしたい方、オープン系言語開発にキャリアチェンジしたい方の後押しになれば幸いだ。

## 筆者の経歴
* 新卒でIT企業に入社
非常にマイナーなレガシー言語を駆使して金融機関のシステム保守を行う。
* 紆余曲折あり、退職
* プログラミングスクールを受講
2ヶ月だけRubyを学習してみる。(いわゆる「さわった」程度。)
* 事業会社のIT部門に転職
1年程前、急にJavaを駆使して新システムを作れと任命される。

## 感想1：Javaって難しい！
どんなプログラミング言語でも違うポイントで簡単or難しいと感じることはあるが、Javaは率直に、習得まで時間のかかる言語だと思った。特に私が個人的に難しいと感じる点はやはりJavaの根幹となる考え方、オブジェクト指向。今まで手続き型でしかコードを書いてこなかった(というか手続き型でしか書けない言語で書いてきた)ため、頭では理解できても自分でアウトプットすることに困難を感じている。その理由は、まだオブジェクト指向で整理されたサンプルコードを見て、美しい・良いと思えず、良いと思えないから自分に取り入れられないのではないかと分析している。

この価値観や考え方の転換は**もはや改宗に近い。**
まだまだ悩むことも多いが、オブジェクト指向カンファレンスのセッション資料を見てみたり、先輩社員の書いたコードを参考にするなどして、少しずつオブジェクト指向を自分に染み込ませてみている。
​
## 感想2：Javaって意外と処理が重たい！
レガシー言語にもいいところがあって、処理自体がシンプルなので大量のデータを高速に処理できる言語が多い。私がこれまで開発に使用してきた言語は少なくともそうであり、コードを書いているときに処理の負荷や速度を気にしたことなどほぼなかった。
​
しかしJavaはできることが多くて複雑な処理もできてしまう分、気をつけないとメモリを過剰に使うコードになってしまい、大量のデータを扱う際とても実運用できるような処理時間に収まらなかった、ということがあった。Java自体コンパイラ型言語と呼ばれる、Python・Rubyといったインタープリタ型言語と比較して圧倒的に速いと言われている言語であるにもかかわらず、だ。もちろん、適切な書き方であれば問題はない。
**コーディング担当者の腕で性能まで変化してしまう言語なのだと痛感した。**
現在はコーディング段階でメモリの使用に気を配ったり、開発の早い段階で実際の稼働環境で性能をチェックするなどの工夫をしている。
​
## 感想3：Javaって世の中に情報がたくさんある！
これはとてもいいことだ。世の中にはどんどんと新しいプログラミング言語が出てきているが、それでもこれまで長年多くの現場で選択されてきたJavaには、多くの参考書・技術記事が存在している。また、ライブラリも無料で使えるものが多数公開されていて、ちょっと複雑だけどこんなことしたいな、は大体どこかのライブラリをインストールすればできちゃったりする。長年レガシー言語をやっていて、わからないことは誰に聞いても知らない・わからない、図書館にも本屋にもネットの渦の中にもどこにも情報がない、という環境にいたため、この点に関しては非常にJavaのメリットを感じている。

ただ注意すべきこともあって、歴史が長い分、参考にしたサンプルコードが古いverのベストプラクティスであって、最新verでは動かなかったり適切ではなかった、といったケースもあった。
何か技術記事を参考にする際には、**verや公開された年に注意するようになった。**
​
## 感想 4：Javaって面白い！
**単純に、書いていて面白いと思う。**
こんな処理にしたいなと思ったとき、レガシー言語で何行にも渡って書いていたことが1行でできてしまったり、同じ処理でも(前述の通り、処理負荷等は考慮しなければならないものの)様々なアプローチや書き方があって、答えは1つではないということに奥深さを感じている。一方で型に非常に厳しかったりと、白黒はっきりしている部分もあり、気持ちのいい言語だと思った。
​
## 最後に
よりJavaと仲良くなるために(?)、Javaの資格にも挑戦中だ。今年の6月にはいわゆるJava Silver資格を取得した。より上位の資格取得も目指したいと思う。
【初心者向け】Djangoでローカルサーバーを立ち上げるまで

Djangoを勉強するにあたって記録をつけています。
他の方の参考になれば幸いです。

開発環境
　Visual Studio Code

  
### 1. Djangoをインストールする

ターミナルを開き、Djangoをインストールします。

```terminal
pip install django
```

インストールの成功を確認してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1386677/d195373f-3e91-2323-8b7a-b0f37dfa3853.png)

### 2. Djangoのプロジェクトを作成する

ターミナルを開き、プロジェクトを作成したい任意のディレクトリに移動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1386677/fe4c8755-8c13-e2ce-5f70-2645cd737f79.png)

コマンドを打ち込み、プロジェクトを作成します。(yourprojectは任意のプロジェクト名)

```terminal Console
django-admin startproject yourproject
```

画像のようにフォルダ、ファイルが作成されていることを確認してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1386677/ae1dfdd7-8510-b588-a258-cdcf83eb0288.png)


### 3. Djangoアプリケーションを作成する

terminalに下のコマンドを打ち込み、作成したプロジェクトに移動します。

```
cd yourproject
```

### 4. プロジェクトが作成できたことを確認する

terminalに以下のコマンドを打ち込み、ローカルサーバーを立ち上げます。

```
python manage.py runserver
```

成功すると下のようなメッセージが表示される

```
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
December 15, 2024 - 18:07:18
Django version 5.1.4, using settings 'yourproject.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.

[15/Dec/2024 18:07:30] "GET / HTTP/1.1" 200 12068

```
http\://127.0.0.1:8000/にカーソルを合わせると画像のように表示されるので、指示に従いキーボードのcontrolキーを押しながら、クリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1386677/3cdf408b-6170-bd51-345f-9608ba56d649.png)

プロジェクトの作成が成功していれば、下のようなロケットの画像が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1386677/53f71496-ee35-9e00-c3a4-ee0a85ada6fb.png)

---
次の作業

https://qiita.com/ruruchan_nanodesu/items/c8077a0d32a2768b5684
複数のGitHubの切り替えを行う


私の場合、会社用のGitHubアカウントと個人開発用のGitHubアカウント、その他用のGitHubアカウントなど複数アカウントが必要になってくるケースが増えてきました。

そのため、今回はその複数アカウントの設定方法や切り替え方法を説明します。

## GitHubのSSH and GPG keysのページにアクセスする
下記のリンクからアクセスします。
[SSH and GPG keys](https://github.com/settings/keys)

![Screenshot 2024-12-15 at 17.42.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318755/d417b902-81e9-e56f-fc24-9ab013d69459.png)
アカウント名と、SSH keysを確認します。
複数アカウントがある場合は、シークレットブラウザを開いてそこからアクセスするなどやってみてください。

## 基本SSH keysディレクトリは決めておく
![Screenshot 2024-12-15 at 17.51.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318755/7ddac48b-b1a4-00d7-5525-06cde9ce38e7.png)
私の場合は、`~/.ssh`に一元管理しています。どのアカウントで何を使っているかはご自身で確認してください。

## 現在のSSHキーを確認する
```
ssh-add -l
```
上記のコマンドを打って、現在使っているSSHキーを確認しましょう。

## SSHエージェントの状態をリセットする
```
ssh-add -D
```
全てのSSHキーを削除します。このコマンドはSSHエージェントから一時的に全ての秘密鍵を削除するだけで、実際のSSHキーファイルは削除しません。
```
ssh-add ~/.ssh/id_ed25519
```
使用したいSSHキーを追加します。
```
ssh-add -l
```
再度、SSHキーを確認します。

## SSH configファイルを確認する
```
cat ~/.ssh/config
```
configファイルで内容を確認します。
![Screenshot 2024-12-15 at 18.06.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318755/8f83490f-af47-797d-32f9-a9477e9f2162.png)
私は写真のように、複数設定しています。
もしconfigファイルを編集したい場合は以下のコマンドで編集することが可能です。
```
nano config
```

## 複数のアカウントで接続テストをする
```
ssh -T git@<your-account-name-A>
```
configのHostで設定した名前を`your-account-name-A`に入力して、接続テストをしてみましょう。

`Hi <your-account-name-A>! You've successfully authenticated`のメッセージが表示されれば、無事に接続ができたことになります。

```
ssh -T git@<your-account-name-B>
```
別途で設定していた他のアカウントでも試して、接続テストを行います。同じように`Hi <your-account-name-B>! YOu've successfully authenticated`のメッセージが表示されれば、アカウントの切り替えができたことになります。

## まとめ
複数での、SSH設定やGitHubアカウント管理は大変ですが、どのアカウントで何のSSH keysを使用しているのかを把握しましょう。
画像がうまく読み込みできなかった時にNoImageを表示させたい

# はじめに

こんにちは、エンジニアのkeitaMaxです。

画像がうまく読み込みできなかった時にNoImageを表示させ方を調べたので記事にします。

Reactを使用しています。

# 結論

以下のようにすると画像が読み込めなかった時にNoImageを出すことができます。

```ts
<img
    src={url}
    onError={(event) => {
        const target = event.currentTarget
        target.src = "/imgs/unnamed.jpg" 
    }}
/>
```

`onError`を使用することで、エラーになった時に`unnamed`を出しています


# おわりに

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

最後まで読んでいただきありがとうございました！
基礎理論:n進数の計算

# はじめに
基本情報技術者試験の学習中なので、学んだことをメモします
誤り等ございましたらご教示いただけますと幸いです🙇

# n進数
n進数とは、1桁の数をn個の記号で数値を表現する方法のことです。

# n進数の足し算

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782860/8a0e538d-5afd-34fa-e233-616d02e0f755.jpeg">

# n進数の引き算
コンピューターは引き算ができない為、負の数の足し算を行う
負の数はnの補数で表現することができる

#### 補数
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782860/d99e5547-1f88-d762-f4f5-5a2be3b75e56.jpeg">

#### 2進数で2の補数を表現
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782860/67923058-9d57-acf0-ad68-2fdece9b9f62.jpeg"></br>
⚠️2の補数は再度ビット反転して1足せば元々の数値になる

#### 2進数2の補数を利用して引き算
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782860/e5d12140-cc09-b54a-cca5-a32c075985a8.jpeg">

# 符号ビット
-(マイナス)を表現する場合に、符号ビットを利用することがあります。
先頭ビットを符号ビットとして代用します。
見た目では符号ビットを利用しているかわからないため、
利用している場合は、「符号ビットを利用している旨の」前置きが必ずあります。
```
1:負の数
0:正の数
```

# シフト演算
2進数を表すビット列を左右にずらすこと

#### 10進数の場合
**615** 左にずらす(*10)← **61.5** →右にずらす(*1/10) **6.15**

桁がズレると10倍となる(基数)

#### 2進数の場合
10進数と同様、左にn個ズレると元の数値の2ⁿ倍になる
　　　　　　　右にn個ズレると下の数値の2⁻ⁿ倍になる

桁をズラすシフト演算は、**論理シフト**と**算術シフト**がある

### 論理シフト(左シフト：かけ算)
符号を考慮せずに単純に桁をずらすことを論理シフトという
論理シフトのやり方は、nビット左シフトし、溢れた数値は無視、空いたスペースに0を格納します

例)8ビット2進数の数値を左に2ビット論理シフトする


![JPEG画像-4B69-85CC-96-0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782860/cf466b7d-5080-5424-5f19-e0a2eeaec465.jpeg)

#### 8ビットで表せる範囲の数値は計算できない！
例)8ビット2進数の数値を左に3ビット論理シフトする
![JPEG画像-46F2-A846-3E-0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782860/4543eb2a-292d-0159-b3a1-10a73ed828ad.jpeg)

272になるはずが、16になってしまいました。。
これは、8ビットで表せる0~255を超えてしまっているからです！
こういった現象を**オーバーフロー**と言います

### 論理シフト(右シフト：割り算)
例)8ビット2進数の数値を右に2ビット論理シフトする

![JPEG画像-4D33-90DA-37-0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782860/0665fa8e-ec3c-afeb-9c8b-48e5d148341a.jpeg)

### 算術シフト(左シフト：かけ算)

![JPEG画像-48D0-AEBB-77-0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782860/6a68f318-e27e-14a2-1d34-42bc9fd84426.jpeg)

算術シフトでは、符号付き8ビット2進数で表せる-128~127を超えると
論理シフト同様**オーバーフロー**を起こします

![JPEG画像-470D-BF4E-04-0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782860/36117a9b-7f5b-69be-b26a-531c37d43af9.jpeg)

### 算術シフト(右シフト：割り算)

![JPEG画像-4BF1-B5AF-1F-0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782860/121a0dfc-6935-d9dc-9e12-23f9dfb843d7.jpeg)

## 論理シフト・算術シフトまとめ
|                 |論理シフト(符号を考慮しない)|算術シフト(符号を考慮する)|
|-----------------|------------------------------|-------------------------------|
| 左シフト(かけ算)  |・空いたスペースに0を入れる<br>・1がはみ出るとオーバーフロー|・空いたスペースに0を入れる<br>・符号ビットと異なる数字がはみ出るとオーバーフロー |
| 右シフト (割り算) |・空いたスペースに0を入れる<br>・はみ出た分は割り算の余り|・空いたスペースに符号ビットを入れる<br>・はみ出た分は割り算の余り   |
ReactでほぼリアルタイムDB反映(firebase)

## はじめに
React強くないです。
いろいろ気づいたことあればコメントいただけると学びになりますしうれしく思います。

## 概要
Reactでローカルストレージに保存する際には、特に何も考えずonChengeでリアルタイムに保存できます。
ただ今回の場合はDBに保存するということで一工夫ふつようになります。
その理由としては、DBに保存するという処理は軽い処理ではないためリアルタイムで処理するのが難しくなります。

:::note warn
結果的にはリアルタイムではありません
:::

ローカルストレージの保存のやり方でfirebaseに保存するようなロジックを組むと
日本語入力の際、「か」と打つ場合、「k」で保存されてしまい「kかあ」と保存されてしまいます汗
 　
  
#### このことからわかるように子音と母音からなるローマ字をどう保存するかにかかっています。

## 結論
Reactライブラリlodashのdebounceを使い、入力文字から一定時間経過してからＤＢにする記述に変えます。
さらに気を付けたいのがＤＢに保存しているデータをinputフィールドに表示している場合
入力しているのに入力の文字が出てこないという現象になります。

なので
・useStateで表示用
・一定時間経過したらＤＢに保存する用
２つの格納場所が必要になる。
 　
※個人開発の１部抜粋
```jsx
import React, { useEffect, useState, useCallback } from 'react'
//...略
const [localEnglish, setLocalEnglish] = useState(activeNote?.english || "");

// 500ms入力がないときonUpdateが発火
const saveToFirebase = useCallback(
  debounce((updatedNote) => {
     onUpdateNote(updatedNote);
  }, 500)
,[onUpdateNote]);

// ローカル表示用のuseStateとfirebase保存用関数に値をセット
const handleEnglishChange = (e) => {
  const newValue = e.target.value;
    setLocalEnglish(newValue);  // ローカルステートは即時更新
    saveToFirebase({           // Firebaseへの保存は遅延
      ...activeNote,
      english: newValue,
      modDate: Date.now()
    });
  };

//...略
<div className='english_field'>
    <strong>英語：</strong>
    <textarea
        id='english-textarea'
        type="text"
        placeholder='英語を記入'
        value={localEnglish}
        onChange={handleEnglishChange}
    />
</div>
```

親コンポ―ネントにifrebase更新する関数のロジック
```jsx
const onUpdateNote = async (updatedNote) => {
    const noteRef = doc(db, "English_words", updatedNote.id);
    await updateDoc(noteRef, {
      english: updatedNote.english,
      japanese: updatedNote.japanese,
      modDate: updatedNote.modDate
    });
  };
```
### 処理手順
①文字を入力するとhandleEnglishChangeが発火

【handleEnglishChange内容】
②入力した文字をsetLocalEnglishでLocalEnglishに格納し、inputフィールドのvalue属性で表示、saveToFirebaseが発火

【saveToFirebase内容】
③debounceを使って500ms秒入力がなかった時onUpdateNoteが発火

【onUpdateNote内容】
④idを特定してfirebaseの更新処理




## 最後に
上であげたコードだけ見ても初学者にはわからないと思うが、、、（見づらくてすみません。）
どう残していいものか悩んだがこんなかんじで書いてみた。

DBにリアルタイムで保存する必要もそこまでないし、サーバーに過負荷がかかるから
ユーザーの数や入力機会ですぐキャパがきそうｗ

ローカルストレージで妥協するか
登録ボタン押下で登録、更新処理するようにしDBのアクセス回数を減らすか
した方がよさそう。





## 自分にしかわからないであろう備忘録

上記の処理に行きつくまでにすごく時間を要した。
その際に考えていたことはuseStateで表示用を保持して、
別のデータを押下したタイミングでDBに書き込むような仕様を検討しコードを書いていた。

編集が終わったかどうかの判定をクリックにしたということ。

ただこの際に更新対象のデータも切り替わる。
その際にDBへの更新処理よりも画面の切り替わりやuseEffectの方が動作が早く、
切り替わったデータに上書きで保存されるということが起きた。

切り替わる前の更新対象のデータは更新されずに。。。
ここではまり4時間ほど止まってしまった。

DBに保存をする際は処理が重くなっているので、少し時間差を設けるか（今回）
登録ボタン、更新ボタンなどDBにアクセスするタイミングをもっとわかりやすくすることが重要だと思った。
次はハマらないように意識する。
React Hook Form、ChakraUIのダイアログでバリデーション、Saveを両立させる方法


# 問題
ダイアログを閉じる動作、データを保存する動作、バリデーションエラーを表示する動作を両立できなかった。

(1) DialogActionTriggerを使う場合
React Hook Formを使用していて、バリデーションが通らないはずなのに、Saveボタンを押せてしまう。 
（学習内容や学習時間を空白にするとエラーになるはずが押せる）

ダイアログ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881019/c165ee2a-6290-fd62-3612-b65b5164b759.png)

```src/App.tsx
<div>
    <label htmlFor="studyContent">学習内容</label>
    <input
        id="studyContent"
        type="text"
        {...register('studyContent', {
            required: '内容の入力は必須です',
        })}
    />
    {errors['studyContent'] && (
        <p>{errors['studyContent'].message}</p>
    )}
</div>

<DialogActionTrigger asChild>
    <button type="submit" disabled={true}>Save</button>
</DialogActionTrigger>
```

ChakraUIのトリガーを使っているため、保存ボタンを押すとダイアログが閉じてしまう。 
再度、登録ボタンを押すとエラーが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881019/378de1ce-6f21-b562-4b93-9d184c7275c6.png)


(2) DialogActionTriggerを使わない場合
```src/App.tsx
// <DialogActionTrigger asChild>
    <button type="submit" disabled={true}>Save</button>
// </DialogActionTrigger>
```

Saveボタンを押すとダイアログが閉じずにエラーを表示できる。 
しかし、正しく入力すると、登録はできるがダイアログが開いたままになる。

(テスト 2時間が登録できたが、ダイアログが開いたまま)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881019/4a3cccee-a70f-c040-4190-01f35254634f.png)

# 解決方法
watchでstudyHourの状態を監視し、バリデーションが通る場合はDialogActionTriggerを使ってダイアログを閉じ、バリデーションが通らない場合はDialogActionTriggerを外してダイアログを閉じないようにした。

```src/App.tsx
const { register, handleSubmit, formState: { errors }, reset, watch } = useForm<FormValues>();

// 監視用のwatchを定義
const studyContent = watch('studyContent', '');
const studyHour = watch('studyHour', null);

{studyContent && studyHour && studyHour >= 0 ? (
    <DialogActionTrigger asChild>
        <button type="submit">Save</button>
    </DialogActionTrigger>
) : (
    <button type="submit">Save</button>
)}
```

# おわりに
終わってみれば複雑ではなさそうですが、解決するのに3、4日かかってしまいました。
NextAuth(Auth.js)v5betaでのgoogle認証に苦戦した

## 認証が難しすぎる
Nextjsでの認証機能の実装にNextAuthが良いと聞き、Youtubeや公式ドキュメント等でもv5betaでのgoogle認証について詳しく説明されたものは見つけられず...(Github認証はちらほらあった)。GPTも古い情報を投げてくるばかりで5時間近く苦戦したので、流れだけでも書き留めておく。

## 1.Auth.js公式ドキュメントで環境構築

https://authjs.dev/getting-started/installation?framework=Next.js

Next.jsでのセットアップはここで済ませる。

1. RouteHandler
1. auth.ts(ルートで説明されてるけどsrc/lib配下が見通し良さそう)
1. middleware.ts(ルート)

ここで、2のauth.ts内のProviders配列にGoogle設定

```typescript:src/lib/auth.ts
import NextAuth from "next-auth";
import Google from "next-auth/providers/google";

export const { handlers, signIn, signOut, auth } = NextAuth({
  providers: [Google],
  pages: {
    signIn: "/signin",
    error: "/auth/error",
  },
  ...
  ```

v4以前のNextAuthでは、ここでclientIDやcallbackURL等設定しないといけなかったが、v5ではよしなにやってくれるみたい。
pagesプロパティには、ルーティングを記述。

続いて公式ドキュメントのOauth　ProvidersからGoogleの説明を参照

https://authjs.dev/getting-started/authentication/oauth

CallbackURLは[origin]をドメインに書き換えて保存
_例:http://localhost:3000/api/auth/callback/google_

GCPの設定で必要(最後までできてなかったところ)

.envファイルにClientID,ClientSecretをそれぞれ追加（あとでそれぞれ入力するので空でOK）
```typescript:.env
AUTH_GOOGLE_ID=
AUTH_GOOGLE_SECRET=
```
Signin画面への遷移は、formのactionに、ServerActionでsignIn("Google")を非同期で渡すだけで実装できる(SeverActionだからClientComponentでは(Client)のタブを参照)
→まあClientComponentは切り分けて最下層で実装するだろうから基本RSCでいいかな

### 2.GCPでの設定
GCPコンソール画面までは割愛。
サイドバーから’APIとサービス’→’OAuth同意画面’と続き、初期設定を済ませる
→(キャッシュの関係なのか、反映に時間がかかった。待てば大丈夫)

クライアントタブからプロジェクトを選択、ClientID、ClientSecretを前述の.envに記入

__＊重要＊　ここで'承認済みのリダイレクトURI'にコールバックURLを、'承認済みのJavaScript生成元'にドメインを入力して保存。__

_テストアカウントの追加もここで行う_
### 3.遷移の確認

これで初期設定は済んだので、UIを整えてsignIn,signOutメソッドで遷移処理の実装。
_P.S.)  auth()からsession情報を取り出せる。_
【For noobs】Pythonちょっとテクニック

# 1.インデントの後に「...」をつける
```python
hoge = True
if hoge:
else:
```
if文の内容を書く途中、中が空だとエラーになります。
そんな時は'...'と書きましょう！
```python
hoge = True
if hoge:
    ...
else:
    ...
```
# 2.関数に説明を書く
関数の最初に「""" """」を書くと関数の説明ができます！
```python
def hoge() -> None:
    """
    This is sample define for qiita
    """
    print("huga")
    return None
```

# 3.for文省略
```python
fruits = ["apple","banana","orange"]
fruits_2 = []
fruits_3 = []

for i in fruits:
   fruits_2.append(i.replace("a",""))

fruits_3 = [i.replace("a","") for i in fruits]
```
```fruits_2```と```fruits_3```は同じです！省略できると便利ですよ！


:::note warn
## 注意
使いすぎると、コードが読みづらくなります。
そのときは普通にfor文を書きましょう！
:::

# 読んでくれてありがとうございます
コメント、いいねもよろしくお願いします:cheese::cake:
ゆるっと振り返る、Webエンジニア1年目の奮闘記

## 概要
今年1年、WEBエンジニア（主にバックエンド）としてHP制作に携わる中で学んだことや、できるようになったことを振り返ります。

## HPといえばSEO
「SEOって上位表示させるやつだよね」くらいのふわっとしすぎた認識だった年始。
知らないSEO用語が出てくるたびに調べ、実装方法も学んでいきました。

#### メタタグや構造化データの活用
ページのタイトルや説明文（ディスクリプション）を適切に設定すること、構造化データを用いて検索エンジンに情報を正確に伝える技術。
タイトルやディスクリプションにサイトのキーワードを含め、検索エンジンにどのような情報が書かれているサイトなのかを伝えます。

#### ページ読み込み速度を意識した開発
ページの読み込み速度もSEO対策の大きなポイント。大体読み込みに一番時間がかかるのは画像のため、画像の読み込み速度を意識する。
##### ①画像やアセットの最適化
画像の遅延読み込み（Lazy Loading）を導入することで、ページの軽量化を実現。
通常は画像がすべて読み込まれてからページが表示されるが、Lazy Loadingを利用すると、画像の読み込みを待たずにページが表示されるため、ページが表示されるまでの体感時間が短くなります。

##### ②CDNの活用
CDN（Content Delivery Network）を用いることで、レスポンスを高速化。
世界中の複数の場所に設置されているサーバーにコンテンツがキャッシュされ、ユーザーの一番近いサーバーからデータを受け取れるため、ページ表示速度が速くなります。

## サーバー側の知識
証明書の発行や更新を行ったり、サイトへのアクセスログやエラーログを確認したり、Linuxコマンドを使ったサーバー操作は初めての経験でした。

##### ①Linuxコマンドの基礎
sudo, ls, cd, grep などの基本的なコマンドの使い方を習得。

##### ②AWSの操作
EC2でインスタンスの操作、CloudFrontでのCDNの設定、WAFでIPの制限など。
業務上必要な操作はできるようになりましたが、他のAWSのサービスにはどのようなものがあるのか、何ができるのかを勉強する余裕はありませんでした。

## 終わりに
この一年で学んだことはどれも基本的な知識で、先輩からの指示を「ただやる」ではなく「理解してやる」というレベルまでの成長でした。
来年は今年得た知識をもとに、自らより良いサービスの在り方を提案するステップを目指します。

最後まで読んでいただき、ありがとうございました！
NEXT.JSのPage RouterとApp RouterのAPIの実装方法の違い



### Page Router (pages/api)

```typescript
// pages/api/repo.ts
import type { NextApiRequest, NextApiResponse } from 'next'
import { fetchRepoData } from '@/utils/api'

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  if (req.method !== 'GET') {
    return res.status(405).json({ message: 'Method not allowed' })
  }

  try {
    const repoUrl = req.query.url as string
    const data = await fetchRepoData(repoUrl)
    res.status(200).json(data)
  } catch (error) {
    res.status(500).json({ message: 'Error fetching repo data' })
  }
}
```

### App Router (app/api)

```typescript
// app/api/repo/route.ts
import { NextResponse } from 'next/server'
import { fetchRepoData } from '@/utils/api'

export async function GET(request: Request) {
  try {
    const { searchParams } = new URL(request.url)
    const repoUrl = searchParams.get('url')
    
    if (!repoUrl) {
      return NextResponse.json(
        { message: 'Repository URL is required' },
        { status: 400 }
      )
    }

    const data = await fetchRepoData(repoUrl)
    return NextResponse.json(data)
  } catch (error) {
    return NextResponse.json(
      { message: 'Error fetching repo data' },
      { status: 500 }
    )
  }
}
```

主な違いは以下の通りです

1. **ファイル構造**
   - Page Router: `/pages/api/` ディレクトリ内にAPIルートを配置
   - App Router: `/app/api/` ディレクトリ内に `route.ts` ファイルとして配置

2. **リクエスト/レスポンスの扱い**
   - Page Router: `NextApiRequest` と `NextApiResponse` オブジェクトを使用
   - App Router: Web標準の `Request` オブジェクトと `NextResponse` を使用

3. **HTTPメソッドの定義**
   - Page Router: 単一のハンドラー関数内でメソッドを分岐
   - App Router: HTTPメソッドごとに別々の関数をエクスポート（GET, POST, PUT, DELETE等）

4. **クエリパラメータの取得**
   - Page Router: `req.query` から直接取得
   - App Router: `URL` オブジェクトの `searchParams` を使用

5. **レスポンスの返し方**
   - Page Router: `res.status().json()` メソッドを使用
   - App Router: `NextResponse.json()` を使用



これらのAPIエンドポイントは、以下のように呼び出すことができます

```typescript
// クライアントサイドでの呼び出し
const response = await fetch('/api/repo?url=https://github.com/user/repo')
const data = await response.json()
```
【Flutter】riverpod_lintの変換アシストとリントが効かない（2024年12月15日時点）

## Flutterのバージョンの問題

Flutterのバージョンを**3.27.0**にアップデートしたことで、効かなくなった模様です。

![スクリーンショット 2024-12-15 17.31.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3058346/bce3248e-3a17-5127-cebc-cc80cd5f8a8b.png)

fvmを使って同じプロジェクトをFlutterバージョン**3.24.5**に戻したら、再び変換できるようになりました。
また、リントも効くようになりました。

![スクリーンショット 2024-12-15 17.32.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3058346/dfc51b6d-c73d-ec3b-249f-736bbf58a2ec.png)

## custom_lintの問題

さらにcustom_lintのバージョンが**0.7.0**になると効かないようです。
私は以前使っていた**0.6.5**に戻したところ、変換とリントが復活しました。

## 対策
riverpod_lint、またはcustom_lintの対応が完了するまでは以下を使用する。
- Flutter 3.24.5
- custom_lint 0.6.5

riverpod関連のコーディングを重視する、または特にFlutter3.27.0に変更する理由がなければ、
上記の２点を維持した方が良さそうです。
Notionとkintoneの使い分けについて考えてみた

私は、日々、Notionとkintoneを使っているエンジニアです。おそらく、私と同じように複数のSaaSを横断して利用しているエンジニアは少なくないと思います。

私としては、ぜんぶNotionでよくない？と思っていたのですが、kintoneとNotionでは、そもそも得意なことが違うわけで、使い分け、および連携させることでより強力なツールになるように最近では感じています。

そんなわけで今回はNotionとkintoneの使い分けについて考えてみました。

# データの扱いによる違い
Notionもkintoneは、両者ともに情報の蓄積において非常に強力なツールですが、データの扱いに違いがあります。

- Notionの場合
基本的に各ページごとに独立して情報を保持していますが、データベースというテーブルを作成することができ、各テーブルにリレーションを張ることが可能です。

- kintoneの場合
カード型データベースを採用しており、現時点では、標準機能でリレーションを張ることはできません。

大きな違いとしては、上記のポイントが挙げられます。一見するとNotionの方がリレーションを張れるので便利な気がするのですが、実際の業務で運用すると、問題になることがたくさんあります。

ひとつは学習コストの問題です。エンジニアの方でしたら特に問題ないと思いますが非エンジニアの方がテーブル設計しリレーションを張れるようになるには、学習コストがかかるかと思います。そんなことよりも必要なアプリを作成しささっと使いたいという人の方が多いのではないでしょうか？kintoneはそんなニーズにばしっとはまるように設計されておりターゲットが明瞭です。

kintoneが日本の中小企業で支持されているのは、何でもできるというよりもシンプルな機能にフォーカスし設計されているからだと思います。

それでは、実際の業務フローによる使い分けを考えてみたいと思います。

# 業務フローによる使い分け
具体的な業務フローを考えると、Notionとkintoneをどのように使い分けるかが見えてきます。

## Notionが得意な場面
- チームのドキュメント管理やアイデアの共有
- プロジェクトマネジメント（ガントチャートやタスク管理など）
- 個人用の情報整理やリサーチの蓄積

Notionは自由度が高く、テンプレートも豊富なため、クリエイティブな作業や多用途なタスク管理に向いています。例えば、開発プロジェクトで仕様書を管理し、進捗を共有するといった用途に適しているように思います。

## kintoneが得意な場面
- データ入力の簡易化が必要な場面
- 業務に即したカスタムアプリを簡単に作成する必要がある場合
- 複数人が同時に扱うデータベース（注文、在庫、顧客情報など）

kintoneは業務プロセスの効率化に特化しており、特に業務フローが明確な場合に力を発揮します。例えば、営業チームが顧客データを登録し、それに基づいて自動でレポートを生成するといった業務にはkintoneが向いていると思います。「いわゆる『脱Excel』を実現するイメージです。

# 実際の連携シナリオ
あくまで一例ですがフォームとしてkintoneを使いAPI連携などで、Notionに情報を蓄積するが、今のところ私としては強みを最大限に活かせるのかなと感じています。

理由は、kintoneをインターフェースとし適宜バリデーションすることによってデータを汚さずに蓄積できるので、例えば自前で1から画面を作成するよりkintoneでアプリを作成し、これを入力画面です、とした方が工数をかなり削減できると思います。

# まとめ
Notionとkintoneは、それぞれ異なる強みを持つツールです。業務内容やチームのスキルレベルに応じて、適切に使い分けたり連携させることで、より効率的な業務フローを構築できると思います。

みなさんはNotionとkintoneでどんな連携シナリオが思い浮かびますか？

ぜひコメントなどで意見をお聞かせください！
（初心者）仮想マシンにおけるブリッジ接続設定の示す意味の自分用まとめ

## 経緯
勉強中初心者ワイ、ブリッジ接続とかワケワカメ。ネットで調べてなんとかそれっぽく接続できたけどどういうこっちゃこれ状態。ちょっと調べてみよ。IPアドレスが関連してる事だけわかる。
　　↓
なんとなくイメージ付いたから忘れんうちに文字で残しとこ！
<br><br>

## ブリッジ接続前のNAT接続はどういう状態なの？
- まず、NATというのは「IPアドレスを変換している」という事。
- じゃあ、「どういう状態のアドレスをどういう風に変換してるの？」という話。
<br>
今回はWindowsホストOS内でLinux仮想サーバーを建てている為、その前提でのお話になります。まぁあんまりOSは関係ないかもしれないけど・・・。
<br><br>

### 仮想マシンはインターネットに出ていくまでに2回IPアドレスが変化している。
#### 〈1回目〉
仮想マシン内で独自に仮想ホストに割り振られているプライベートIPアドレスを、**自分が動いている物理マシンのIPアドレスに変換**してもらっている。

##### 理由：
- 仮想マシンがインターネットと通信する為には、仮想マシンが動いている物理マシンがインターネットと通信する為に使用しているデフォルトゲートウェイを使用しなければいけない。
- その為、必然的に物理マシンが接続されているネットワークにパケットを乗せなければいけない。
- その為、**仮想マシンからのパケットの送信元アドレスを物理マシンのIPアドレスに変換（代理）して貰って**、あたかも「物理マシンからのパケット」のようにネットワークに流してもらっている。　<font color="red">**←だからNAT接続**</font>
#### 〈2回目〉
物理マシンの所属ネットワークからデフォルトゲートウェイ（ルーター）を通してインターネットに出ていく時にプライベートIPアドレスからグローバルIPアドレスに変換。
これはまぁ普通にそう。
<br><br>
 
## ブリッジ接続したらどうなるの？
- ブリッジとはその名の如く「橋渡し」ということ。多分。
- じゃあ、NAT接続時から物理ホストの役割はどう変化したの？
<br>

### ブリッジ接続は「仮想マシンに物理ホストと同じネットワーク内のプライベートIPアドレスをルーターから直接割り振ってもらう」事で、ネットワーク内に列記とした1台のホストとして仲間入りしてもらう事。

#### NAT接続時：
<font color="red">**「仮想マシン」→「物理ホスト」→「ローカルネットワーク」** </font>→「デフォルトゲートウェイ」→『インターネット』

#### ブリッジ接続時：
<font color="red">**「仮想マシン」→「ローカルネットワーク」** </font>→「デフォルトゲートウェイ」→『インターネット』
<br><br>
### ブリッジ接続時の仮想マシンの位置付け
ブリッジ接続を行っている状態における仮想マシンには、**現実のローカルネットワークのDHCPサーバーから列記とした一台のホストとしてプライベートIPアドレスが割り振られます。**
つまり、IPアドレスを確認してみた時に、もしそのローカルネットワークアドレスが/24プレフィックスだった場合は、IPv4アドレスの第3オクテットまでが、ネットワークアドレスと共有されている筈です。そして同時に、その仮想サーバーが立ち上がっている物理ホストに割り振られたプライベートIPアドレスともネットワーク部を共有する形で違うアドレスが割り振られた状態にもなっている筈です。
<br>

#### ブリッジ接続時の仮想マシンを立ち上げている物理ホストの役割
NAT接続時における物理ホストの役割はNAT処理を行って仮想マシンからの通信を代理してネットワークに流す事でした。ブリッジ接続になった時、物理ホストはこうした処理を行う必要がなくなります。
つまり、この時の物理サーバーは正に <font color="red">**「物理的なネットワークアダプターを持っていない仮想マシンの為にネットワークアダプターを貸してあげてるだけの橋渡し役（ブリッジ）」**</font> でしかなくなるという事です！

正にブリッジ（橋）接続。
<br><br>

## まとめ
- NAT接続からブリッジ接続に切り替えている。
- NAT接続時は仮想マシンを立ち上げている物理ホストが仮想マシン内のIPアドレスを自分のプライベートIPアドレスに変換してローカルネットワークに流してくれていた。だからNAT接続。
- ブリッジ接続を行うと、仮想マシンがローカルネットワークのDHCPサーバーから列記としたホストとして個別のプライベートIPアドレスを割り振ってくれる。
- ブリッジ接続後の仮想マシンを立ち上げている物理ホストは、ハードウェアの実体を持たない、つまりネットワークアダプターを持っていない仮想マシンの為に自分のネットワークアダプターを貸してあげるだけの橋（ブリッジ）になる。
- 最終的な状態としては、物理マシン、仮想マシンそれぞれのプライベートIPアドレスは、ネットワーク部を共有したそれぞれ独立のホスト部を保持した状態になる。

## 最後に、物凄くざっくりブリッジ接続を説明すると・・・？
ローカルネットワーク内で2台のパソコンが1枚のネットワークアダプター（NIC）を一緒に使っている状態。