OmniAICreator/Qiita-1.07M huggingface dataset:
【Next.js】Server Actionsからのリクエストにcookieをセットする方法

## すべてのCookie

`fetch`の`headers`に`Cookie: cookieStore.toString()`を記述するとブラウザに設定されているすべてのCookieをセットできます。

```js
'use server'

// ...

export async function sample() {
  const cookieStore = await cookies()
  const res = await fetch(
    `http://example.com/sample`,
    {
      method: 'POST',
      headers: {
        // ...
        Cookie: cookieStore.toString(),
      },
      // ...
    },
  )

  // ...
}

```

## 特定のCookie

特定のCookieのみセットする場合には以下のようにします。

```js
'use server'

// ...

export async function sample() {
  const cookieStore = await cookies()
  const sampleCookie = cookieStore.get('sample')
  const res = await fetch(
    `http://example.com/sample`,
    {
      method: 'POST',
      headers: {
        // ...
        Cookie: `${sampleCookie?.name}=${sampleCookie?.value}`,
      },
      // ...
    },
  )

  // ...
}

```
ユーザーとのコミュニケーションについて

# はじめに
こんにちは、小林と申します。
運用保守の業務を務めて3年目になります。
以前「ユーザーとのコミュニケーションで気をつけていること」という記事を書かせていいただきました。
今回はその続きになります。
普段ユーザー(お客様)とのコミニケーションでもITリテラシーの高い方からそうでない方まで幅広く対応しています。知識のある方の場合はある程度の情報お伝えしただけで理解してくださいますが、すべての人がそういう訳ではありません。
知識があまりない人とのコミニケションについてどういった部分を気を付けていくと円滑にコミュニケーションできるのかまとめていこうと思います。

# コミュニケーションで気をつけている3つの事
まずコミュニケーションにおいて共通して大事な事は以下の３つだと思います。
### ①相手が何を伝えようとしているかを正確に聞き取る
単に相手の会話を「聞く」だけでは不十分で、相手の意図を正しく把握することができなければ、意思疎通が難しくなり立ち行かなくなります。
### ②会話の中での不明点や疑問点について深掘りする。
どういった作業が出来ていないのか、どうなれば良いのかなど相手の状況を正確に把握し、適切な判断や提案を行っていくことが重要です。
### ③自分が伝えたい内容を明確にし、話の筋道を作ってロジカルに伝える
自分の意見や考えを相手に伝える力です。伝達スキルが未熟だと意思疎通がうまくいきません。

# 知識があまりない方とのコミュニケーションについて
ここからは実際にそういった方とのコミュニケーションについてどのような事を意識して取組むを円滑に進むかまとめてみようと思います。

### ①専門用語を避ける
### ②具体例を用いる
### ③視覚的な資料を活用
### ④質問を受け付ける
### ⑤確認する
### ⑥相手のペースに合わせる

上記の事を気を付けていくと円滑にコミュニケーションが進むのではないかと思います。
実際に私自身もこういった事を意識して取組んでいます。特に大切ではないかと思う事は⑥で挙げた「相手のペースに合わせる」事だと考えでいます。相手ペースに合わせる事で 相手の理解度や進行ペースに合わせて説明することで、より良いコミュニケーションが図れると思います。この部分の意識がないと一方的に話しているだけで相手が説明中に不明な事があっても進められてしまうので相手側としては結局何を言われているのか分からない状態になり、コミュニケーションが一方通行になってしまいます。

# 終わりに
今回、コミュニケーションで気を付けている事の中でも知識があまりない方向けへのコミュニケーションについてまとめてみましたが、私自身入社した当時はITリテラシーが低くいつも質問ばかりしておりました。
今回気をつける事で挙げた内容は入社したばかりの時に自身が感じた事をまとめました。
３年目を迎え、ある程度理解できるようになってきましたが、まだまだ勉強が足りていないのが現実です。
これからも勉強を怠らず、少しでもユーザーから問い合わせに対応出来るように努めていきます。

コミュニケーションについて興味があれば過去の記事も見てみてください。
・ユーザーとのコミュニケーションで気をつけていること
https://qiita.com/pesysyon/items/70b19f39dbd3adc959d8


以上、小林でした。
VPNを経由した場合、共有フォルダにアクセスできない

# はじめに
こんにちは、小林と申します。
今回はユーザーのPCをセットップした際、VPN接続した後に共有フォルダにアクセス出来なくなったという事象が発生しました。
その際にどのように対処すれば良いか自身の経験から対処法をまとめていきたいと思います。

# VPNとは
VPNとはそもそも”Virtual Private Network”の略称で、日本語にすると「仮想専用通信網」を意味します。VPNでインターネットに接続することをVPN接続と言いますが、この場合、専用ネットワークとは言いつつも物理的な専用回線を用いるのではありません。「仮想」専用通信網というように、共用の回線を諸々の技術によって仮想的に独立した専用回線であるかのように扱うのがVPN接続というものになります。

# VPNを経由した場合、共有フォルダにアクセスできない。
今回がセットアップをしていく中でここの部分にとても頭を悩ませました。
共有フォルダを見に行けない場合にはデバイス設定が原因の場合とネットワークが原因の場合、ファイルサーバー自体が原因でアクセスできない場合があります。

## デバイス設定が原因の場合に確認する内容
- デバイスの原因
- ネットワークの原因
- ファイルサーバーそのものの原因
- 資格情報を確認する
- ネットワーク探索とファイルの共有を確認する
- SMB機能について確認する

## ネットワークが原因の場合に確認する内容
- IPアドレスの確認（pingが通らない）
- VPNの接続を確認する

## ファイルサーバー自体が原因の場合に確認する内容
- フォルダのアクセス許可を確認する
- 同時接続制限に達していないか確認する
- 匿名アクセス（guest）・パスワード無しアクセスの有効化

# まとめ
共有フォルダを見に行けない場合にはいくつもの原因が考えられます。
私が対応した際は資格情報の追加で解決する事が出来ました。
同じような事で困った場合に原因の切り分けとして参考になったらと思います。
以上、小林でした。
エンジニアとのコミュニケーションについて

# はじめに
こんにちは、小林と申します。
運用保守の業務を務めて3年目になります。
以前、ユーザー様とのコミュニケーションについて投稿した事があり、その繋がりで
今回はエンジニアとのコミュニケーションについて私なりに気を付けいる事を書いていこうと思います。
非エンジニアとエンジニアとのコミュニケーションでは下記のような事が発生する可能性があります。
- できることできないことの認識が合っていない
- 作業の重さの認識が合っていない
- 言葉のニュアンスが合っていない

このような事が発生しないようにエンジニアの方々がやっている事をなんとなくでも理解する又は理解しようとする事が大切なのではないかと思います。

# 1.エンジニアの思考プロセスについて
私自身運用保守の業務をしており、不具合や動作確認などユーザーから１番最初に話を聞く立場にあります。
問合せ内容からシステム内部にかかわる事であればヒヤリングの後エンジニアへ調査依頼を出します。
ここでエンジニアの方々と話す際に大切になってくる事は、エンジニアの考え方、思考プロセスをなんとなくでも
理解しているとお客様からのヒヤリング～エンジニアへの調査依頼までの間に必要な情報を集められるのではないかと思います。
例えば、アプリの新機能をリリースした後予期せぬバグが発生した際、エンジニアが最初に行うのは原因の特定、ログや最近の変更点を確認したり、どういう状況下で発生しているのかを調査します。
非エンジニアの私たちも、このようなアプローチが行われていることを理解していれば、端末やOSのバージョン、ブラウザなど必要な情報をヒヤリングすることが可能です。

# 2.エンジニアが作るシステム処理について
なんとなくでもシステム全体や機能などがどのような処理が行われている事について理解していれば、不具合発生した際にこの動かし方をしていればエラーになるかもしれないといった事が分かります。それにより具体的にエンジニアの方へ調査依頼ができると思いますし「これ直して」「この機能追加してほしい」といった無茶ぶりにならず、エンジニアの方とのできることできないことの認識を合わせる事ができよりよい関係を築けると思います。
私自身、入社した当初は不具合による調査依頼やお問い合わせがあった際に、問い合わせ内容を丸ごと引用する形で調査お願いしますみたいに雑に聞いていた事がよくありました。
その結果エンジニアの方々からは「どういう環境で起こってる？」「その人のPCだけ」「使用しているブラウザは？」みたいな質問をもらっていました。
実際にシステム内部について、なんとなくでも理解していればヒヤリングなどをする際にそのあたり確認したうえでエンジニアに渡す事が出来ます。

# 終わりに
非エンジニアとエンジニアのコミュニケーションについて書いてきましたが本質的にはどちらも最終的なゴールは同じ所へ向かっていると思います。
Qiitaの記事にもありましたが、お互いがお互いのことをなんとなくでもわかる事が大切だと思います。
1～10まで理解する必要はありませんが、どういったプロセスで物事が進んでいくのかなど理解しあっていれば円滑に業務を行えていけるのではないかと思います。

コミュニケーションについて過去に記事にしたので良かった見てください。
https://qiita.com/pesysyon/items/70b19f39dbd3adc959d8

以上小林でした。
ドメイン参加について

# はじめに
こんにちは、小林と申します。
最近ユーザー様のパソコンへドメイン参加の設定を行いました。
今までドメイン参加についてあまり理解していたなかった部分があったので記事にまとめようと思います。

# ドメイン参加とは
ドメイン参加とは、ActiveDirectoryドメインにノードを参加させ、大規模なWindowsネットワークで導入される管理システムで、Windows Server上の「ドメインコントローラ」（domain controller）と呼ばれる管理機能を用いてドメイン内のWindowsシステムの利用者アカウントやネットワーク上の資源（各コンピュータ内のファイルや周辺機器など）のアクセス権などを一元管理する時に設定します。
ドメイン参加したコンピュータは他のコンピュータと共通のアカウントやセキュリティ設定などを利用するようになる。一度のログオン手続きで、ドメイン内の他のコンピュータの管理する資源にも、管理者の設定した権限の範囲内でアクセスできるようになります。

# ドメイン参加の役割とメリットについて
1 IDとパスワードの一元管理
2 ドメイン上のリソース管理
3 イベントログの閲覧と管理

上記の事がドメイン参加をする事で可能になります。
こういった事を出来るようになる事で、階層ごとに独自のIDとパスワードを設定して管理する必要がなくなったり、イベントログを管理する事でアカウントの不正利用やサイバー攻撃などが発生した場合には、イベントログを確認することで詳細な情報を把握する事が出来す。
また、管理者の負荷削減をする事が出来ますしユーザー側もシステムごとのID、パスワードを管理する必要がなくなるのはもちろん、端末アップデートを手動で行う必要がなくなったり、ネットワーク上のプリンターなどの機器が使いやすくなったりとオフィスでの煩わしい作業が軽減されます。

# ドメイン参加のデメリットについて
ここではドメイン参加をする事のデメリットについて説明していこうと思います。
Active Directoryを利用するのに初期設定に多少手間がかかるのがデメリットです。ドメインごとの権限を決めてしまえば、あとはユーザーを追加して運用するだけですが、どこまでどの権限を持たせるか等、運用上またセキュリティ上、非常に重要になってきます。一度決めたポリシーを変更するのは影響が大きくなりますので、慎重に検討する必要があります。
ユーザーはドメインの権限から逸脱することはできません。そのため、ソフトを一つインストールするだけだとしても、管理者の承認が必要となります。状況によっては業務を煩雑化してしまう可能性もあるのです。 セキュリティ上権限制御は必要ですが、厳しすぎても円滑な業務を妨げるため、使用する環境に応じてバランスがとれるポイントを探す必要があります。



# 終わりに
ドメイン参加についてまとめてきましたが、調べていく中で最初は参加する事で多くのメリットがあると感じましたが、メリットだけでなくデメリットとなる部分も少なからず存在するので導入する際はしっかりとメリット、デメリットを考えて導入していく必要があるようです。
以上、小林でした。
Macで辞書が勝手に起動するショートカットをオフにする

# はじめに
こんにちは、ユーゴです。今回は、Mac自体の設定についてをご紹介します。

# 問題
テキストを編集したり、ドラッグしようとしたりすると、勝手に辞書が起動して面倒です。

![dictionary.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/f39f4c2c-e385-66d8-7480-687ab2baaa18.png)


# やりたいこと
- 3D Touch？( = 強めのクリック)をオフ
- 辞書のショートカットをオフ

# 方法
「システム環境設定 > トラックパッド」を開きます。

3D Touch (強めのクリック)をオフにしたい場合は、「強めのクリックと触覚フィードバック」をオフにします。

辞書のショートカットをオフにしたい場合は、「調べる＆データ検出」をオフにします。

![settings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/3b6746dc-3a8f-881a-bd6d-b4a7bfdeb71d.png)


# まとめ
いかがだったでしょうか。今回は、Mac自体の基礎的な使い方を紹介しました。Mac歴5年目の私でしたが、OSのアップデートでシステム環境設定など様々なレイアウトが変わって、未だに苦戦することがあります。
このように、基礎的なMacの使い方から、Unity, AWS, GAS, 量子コンピュータなど、様々な情報を紹介しております。お役に立てましたら、いいね, フォローなどよろしくお願いします！
Cisco機器からIOSを吸い出す方法

# CiscoルータからIOSを吸い出す
GNS3 (https://www.gns3.com/) では実際のCiscoルータのOSをダウンロードして適応させてNWのシュミレーションができます。
今回はGNS3で自前のルータのIOSを使うために書いた備忘録です。
# 環境と用意するもの
環境
PC: Windows 11 Home 23H2
Router: Cisco 1812-J

用意するもの
Tera Term
LANケーブル(ストレートでもクロスオーバーでも)
コンソールケーブル

# 手順① PCでTFTPの設定をしよう
IOSを受け取るPCをTFTPクライアントとして設定します。
Windows 11 ではデフォルトでTFTPクライアントのソフトウェアが入っていますが、有効化とファイアウォールの設定をしないと使えません。

### コントロールパネルを開く
コントロールパネル → プログラム
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674199/6031c555-d70f-b98c-04de-adc98e302e27.png)

Windows の機能の有効化または無効化 → TFTPクライアントにチェックを入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674199/5fe31db3-8738-61d9-61ae-09d323c14fdf.png)

コントロールパネル → システムとセキュリティ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674199/9ec9c09f-aa3c-0988-9e2f-855733ef59f0.png)

Windows Defender ファイアウォールをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674199/ccc4a8ba-3a54-4efc-1f05-7a5594ce1931.png)

Windows Defender ファイアウォールを介したアプリまたは機能を許可をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674199/bb47e017-9f11-2b86-c15e-9b21db7469e9.png)

設定の変更 → 別のアプリの許可... → 参照 → "C:\Winsows\System32\TFTP.EXE" を選択 → 追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674199/39fb0183-99f8-0a08-97d2-a4f38cb7d9d5.png)

簡易ファイル転送プロトコルアプリケーションが追加されていれば成功
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674199/94d5c7ed-cad3-7a63-52ed-c7c890683789.png)


# 手順② 配線とコマンドを設定しよう
### 配線
下の図では緑色がコンソールケーブル、青がLANケーブルです。
コンソールケーブルはConsoleポート
LANケーブルはFastEthernet 0ポート
に配線しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674199/2999324f-99ea-0b04-2527-698eb3cde880.png)

### TFTPサーバの設定をする
Tera Termからシリアル → 該当するシリアルポートを選択 → OK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674199/cee2c920-e6c3-9aee-0a08-d5b61850dfec.png)

投入するコマンドは以下のようにしました。

    enable
    configure terminal
    interface fastEthernet 0
    ip address 192.168.1.1 255.255.255.0
    no shutdown
    exit
    tftp flash:c181x-advipservicesk9-mz.151-4.M12a.bin

特筆する箇所は、tftpコマンドです。
tftpコマンドで送信するバイナリファイルを選択します。
バイナリファイルファイルを選択しないと、PCのコマンドプロンプト上で接続要求に失敗してしまいます。
選択するIOSのバイナリファイルが複数ある場合があります。
詳しくは下記の記事を参照されてみてください。

https://qiita.com/h_tyokinuhata/items/defa2b98529cc57edb03

### PCでIPアドレスを設定する
設定 → ネットワークとインターネット → イーサネット → IP 設定の編集 → 保存

    IPv4 オン
    IPアドレス 192.168.1.100
    サブネットマスク 255.255.255.0
    ゲートウェイ 192.168.1.1
    優先DNS 8.8.8.8

# 手順③ コマンドプロンプトでIOSをダウンロードする
コマンドプロンプトを起動し、以下のコマンドを入力します。

    tftp -i 192.168.1.1 get c181x-advipservicesk9-mz.151-4.M12a.bin

"-i" はバイナリファイルをダウンロードするときに付加するオプションです。
設定に不備がなければ、1分弱でダウンロードが可能です。
Ansible Tips: shellモジュールのリアルタイムログ出力をファイルに書き出し、かつshellモジュールにもstdout, stderrをきちんと返す

備忘

# 要件
以下を満たしてAnsible Shellモジュールを使用したい
- Ansible Shellモジュールにstdout, stderrを正しく戻す
- かつ、途中経過を確認できる様にログファイルにもstdout, stderrを書き出す
- かつ、AIX環境(ksh)でも使える(汎用的)

exec で出力先をログフィルにするとShellモジュールに結果が戻せない。
全体に対して| teeを用いる対応では、stdoutとstderrを個別に扱うことが困難。
しかし、名前付きパイプを利用すれば要件を満たすことが可能。

# ソリューション
名前付きパイプを使用する

## task例

```yaml
- name: "STDOUT, STDERRをリアルタイムでログに書き出すshellモジュール例"
  shell: |-
    LOGFILE="/tmp/logfile.log"
    STDOUT_PIPE="/tmp/stdout_pipe.$$"
    STDERR_PIPE="/tmp/stderr_pipe.$$"
    mkfifo "$STDOUT_PIPE" "$STDERR_PIPE"
    trap "rm -f '$STDOUT_PIPE' '$STDERR_PIPE'" EXIT
    cat /dev/null > "$LOGFILE"
    tee -a "$LOGFILE" < "$STDOUT_PIPE" &
    tee -a "$LOGFILE" < "$STDERR_PIPE" >&2 &
    exec > "$STDOUT_PIPE" 2> "$STDERR_PIPE"
    set -x
    処理本体
    ...
```
- 少し長いので複数行の変数としてどこかにまとめておいても良いでしょう。
- mkfifoコマンドで名前付きパイプを作成、execでstdout, stderrと接続、teeコマンドにてファイルに分岐させた上で、stdout, stderrに戻すといった流れ。
- trapを用いてスクリプト終了時に名前付きパイプも削除。
- 最新のshellの状況さえ分かれば良いだけならLOGFILEをつどnullクリアすればハウスキープもほぼ不要。
- set -xのデバックモード指定は、処理本体に影響がないことを確認の上、必要に応じて。
chakra ui v3 で注意すべきこと

# はじめに

 chakra ui を使って画面を作成しているときにドキュメントが古く、混乱することが多くあったので忘備録です。

 # モーダルなくなった

 モーダルがなくなりました。本当です。v2 までは `Modal` や `ModalOverlay` を import を使ってコンポーネントを追加していましたが v3 ではこれらのコンポーネントはすべてありません。

 ```react
 // v2 ONLY
 import {
  Modal,
  ModalOverlay,
  ModalContent,
  ModalHeader,
  ModalFooter,
  ModalBody,
  ModalCloseButton,
} from '@chakra-ui/react
 ```

 代替は `Dialog` を使うようです。ナンテコッタ。

 URL: https://github.com/chakra-ui/chakra-ui/issues/8987

 # モーダルの開閉は useDisclosure を使わない 

 モーダルを開くには `<DialogTrigger></DialogTrigger>` でボタンを囲う必要があります。モーダルを閉じるには `<DialogActionTrigger></DialogActionTrigger>` でボタンを囲う必要があります。

 # ChakraProvider はなくなった

 正確には `Provider` の内部で `ChakraProvider` を呼び出すようになりました。

```react
import { Provider } from "@/components/ui/provider"
import { defaultSystem } from "@chakra-ui/react"

export const App = ({ Component }) => (
  <Provider value={defaultSystem}>
    <Component />
  </Provider>
)
```

# スニペット

プレビルドしたスニペットが `src/components/ui` ディレクトリに配置されます。`@/components` とドキュメントにあるのですが、一寸よくわからず「サンプルだから適当なパスなんだろうなー」と思ってしまいます。

:::note
スニペットは

```
npx @chakra-ui/cli snippet add
```

を実行すことで追加できます。パスは `src/components` です。
:::

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

https://projisou.jp
Postman 練習環境でApiキー認証を試してみた

## はじめに
日々の活動、ご苦労様です!!
先日、__Postmanオンラインワークショップ - API認証__ に参加しました!

前回参加後にはテストスクリプトの練習環境を構築しましたが、本記事ではこの環境に、認証ハンズオンの内容を取り入れていきたいと思います！:fist:

- 前回記事

https://qiita.com/K-yokosu/private/4e60790d476e823d084e

#### やること
- 復習を兼ねたApiキー認証の練習
- 前回環境にApiキー認証を適用

## Apiキー認証の練習準備
ワークショップでフォークした以外のコレクションで練習してみたいなぁと思っていたところ、ちょうど良いAPIを見つけたので利用します!

1\. [THE CAT API のPostmanをフォーク](https://documenter.getpostman.com/view/5578104/RWgqUxxh#99d84a91-d4e5-42af-b965-596a5da4d491)
2\. [認証キーを取得](https://thecatapi.com/)


## 練習開始
1\. 用意されている環境変数の現在値に先ほど取得した認証キーを入力します ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606316/d2fd91e7-83be-310d-fe59-62be7a2503d4.png)

2\. コレクショントップの認可を画像のように設定します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606316/ac4a3a7d-cfd1-b0fd-b8ce-754ca0abf9cd.png)

3\. imagesで画像を取得しそのidをfavouritesでpostします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606316/370870fc-170a-4f39-89c1-08f980f609f4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606316/ee5583bb-3457-cc1c-04ca-df9bffed5232.png)

4\. postのレスポンスにあるidを使用してお気に入り登録できているか確認します![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606316/373264e9-bf06-d74f-f765-d256a086c7d7.png)

5\. 認証キーを削る
方法はなんでも良いと思いますが、正しい認証キーでなければ401となることが確認できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606316/5aae80f3-3eab-1067-b350-b0d422a9dec1.png)

ワークショップで行ったApiキー認証ハンズオンの範囲はこんな感じだったと思いますので練習には最適でした！

次はApiキー認証自体を自作します

## Apiキー認証が必要なApiを作ってみる
### 前章で構築した環境にApiキー認証を追加する
既に実装済みのコードとPostman json は用意しているので下記ブランチに移動して、環境とワークショップをimportして下さい。（import方法などは前章を参考にして下さい）

対象リポジトリ：[postman_practice repository](https://github.com/K-yokosu/postman-practice/tree/main)
対象ブランチ：postman_auth_apikey
Postman json: utils/postman/auth

### 環境変数を追加する
```.env
API_KEY=123456789
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606316/5e206ed1-83b4-02c0-7565-c3c8399fbd5e.png)

### Apiキーによる認証を試す
認証エラーになるかを見たいので、先ほど設定したどちらかの環境変数を適当なものに変更してリクエストを投げてみて下さい。
リクエストヘッダーにx-api-keyが付与され、401エラーの返却が確認できますね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606316/c6c4237f-3dd3-46fa-1078-6d4efd13e721.png)



## 今後の課題
業務で活用する認証方法やハンズオン内で触れられていたOAuthでのテストも練習したいので、時間を見つけて試行してみたいです。





## 終わりに
最後までお読みいただきありがとうございます!!
業務ではApiDogを使用してきたので、これまでPostmanを利用する機会はなかったのですが、ワークショップを通じてある程度触れるようになれました！
まだ今年中に2回ワークショップがあるのでどちらも参加して、さらに使いこなせるようになります:sunglasses:

### 追伸
アドカレ5記事目終わり〜
まだ1/5 :joy:
きちぃのは間違い無いですが、他にも頑張っている方々がいるので団体スポーツだと思って走ります!!

:santa_tone1::santa_tone1::santa_tone1::santa_tone1::santa_tone1:
【Markdown AI】AIを味方にして海の魅力を伝えてみた

こんにちは！今回は、Markdown AIを使っていきます。
Markdown AIは誰でも簡単にwebサイトが作れるツールです！

## 目次
- [Markdown AIとは](#markdown-aiとは)
- [やり方](#やり方)
- [10分で完成したwebサイト](#10分で完成したwebサイト)
- [最後に](#最後に)

# MarkdownAIとは
- ブログを制作したいけど初心者でわからない
- webサイトは難しそうで手がでない

などの悩みを解決したのが**Markdown AI**です！！

しかも、サイト内にAIを実装できちゃいます。

# やり方
- 公式にやり方が書いてあるので参考にしてみてください！
https://mdown.ai/content/88413ec2-3b29-4db4-a4ff-2ddf1a67f34b

# 10分で完成したwebサイト
趣味であるダイビングを題材に取り上げてブログを書いてみました🤿
盛り込んだ要素は、以下になります！

- Markdown
- 画像を挿入する
- AIをサイトに盛り込み、検索できるようにする


↓↓↓実際にできたサイト↓↓↓
https://mdown.ai/content/f85ca980-54bc-4771-975d-74e4b71730f7

![FireShot Capture 024 - MarkdownAI β - mdown.ai.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/69a18261-afdb-6ced-8760-19b632d312d9.png)


# 最後に
本当に簡単にwebサイトができて驚きました！
しかも、ボタンクリックするだけでAIも搭載できるなんて魅力的すぎる〜！！
皆さんも是非試してみてください:clap:

ここまで読んでいただきありがとうございました:relaxed:
小ネタ　Windows11でDNSサーバのアドレスを自動取得にしても再起動すると以前の値が残留してる件withマクドのFree Wi-Fiにつながらない

## タイトルが長いのはご勘弁ください。

発端はマクドのフリーWi-Fiに繋がらないことだった。
ログイン画面が出ねえ。

たぶんDNSサーバー周りなんだろうなと思って自動取得にしたり、DNSキャッシュを削除してみたりしてみたが埒が明かない。

ふと考えたのだが、再起動するとなぜかDNSサーバーを自動取得にしたのにもかかわらず、ClaudflareのDNSサーバー　1.1.1.3　が設定されているのである。（これ自体は自宅でそのように設定しているので誤りではない）

ははーん、原因はこれか？

調べてみたら同じ症状で困っておられる方がおられるようである。

https://blog.jbs.co.jp/entry/2022/09/26/140000

結論から言うと、下記のレジストリに登録されているDNSサーバー情報を持ってる値を削除削除。

\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\


これで無事ログイン画面に到達……というわけにはいかず。ここからは余談。


Chromeでログインしようとすると警告が出て先に進めない。
仕組みを考えるとそういうこともあるのかもしれない。

ということで、ipconfigを叩いてデフォルトゲートウェイのIPアドレスを手打ちする。

`http://10.0.0.254`（アドレスは架空のものです:httpなところに注意）

無事繋がるようになった。

###### 余談の余談ですが、セキュリティ対策は万全に。Free Wi-Fi使ってて何言ってんだって思われそうですが。

あんまり関係ないですけど、IT企業の面接で面接担当者に「LINE教えて」って言われて教えると（使ってるというと）その場でセキュリティ意識なし、よって失格、という話を耳にしたんですがそんな怖い業界なんですか。
HostedZoneNotEmpty 400: The specified hosted zone contains non-required resource record sets and so cannot be deleted.の対処法

<h2>症状</h2>
Route53のホストゾーンを削除しようとしたとき、下記のエラーが発生しました

```terminal:error
エラーが発生しました
ホストゾーンを削除するには、最初に Zone Apex の NS および SOA リソースレコードセット以外のすべてのリソースレコードセットを削除する必要があります。
(HostedZoneNotEmpty 400: The specified hosted zone contains non-required resource record sets and so cannot be deleted.)
```

<h2>解決策</h2>
エラーメッセージ通り、ホストゾーンのレコードを削除したら、ホストゾーンが削除できました
AccessDenied 403: The resource hostedzone/hoge can only be managed through AWS Cloud Map の対処法

<h2>症状</h2>
Route53でホストゾーンを削除しようとしたとき以下のエラーが発生しました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/8587b1b3-1148-170d-97b7-7e3eec29a7f4.png)

```terminal:翻訳
(アクセス拒否 403: リソース hostedzone/11111111 は、AWS Cloud Map (arn:aws:servicediscovery:ap-northeast-1:hoge) を通じてのみ管理できます)
```

<h2>解決策</h2>
CloudMapコンソール画面に移動して、削除ボタンを押したら削除できました

<h2>参考</h2>

https://repost.aws/ja/knowledge-center/route-53-service-discovery-delete-zone
目的もしくは原因を表す言葉「〜の為（ため）に」についての留意点

こんにちは。
日本語で、「〜の為（ため）に」は、目的もしくは原因（理由）を表す言葉ですが[^1]、文脈を見てどちらの意味なのかがすぐに理解できる場合は良いのですが、そうではない場合も技術文書などで見かけました。

そのような場合に、用いる際には慎重のため下記のように補うと良いかと思います（英語などからの翻訳の際にも）。

* 「〜の目的の為に」
* 「〜の原因（理由）の為に」

[^1]: 中国語でもそのようです。
SAA合格体験記　2024/11/1 受験

# 1.受験を決めた理由
現在私はデータエンジニアという立ち位置でITエンジニアをやらせていただいています。
使ってる技術スタックとしてはSnowflakeがメインであります。

Snowflakeのアーキテクチャの裏側ではS3を使っていたり、
AWSのコンピューティング様様な訳です。

直近の業務でゴリゴリにアーキテクトな仕事はしていないのですが、

インフラ基盤のAWSをセキュリティからサーバーレスのサービスまで幅広く知りたくなったということが受験の経緯です。

それとSIer業務にも興味があるので、将来の幅も広げたいなと感じたのも理由の一つです。

# 2.受験方法

私はPerson Vueを使ってテストを受験しました。
当日10時30分から試験開始だったので、30分前にログインして
諸々受付を済ませて、開始したのは大体10時15分くらいだったかなと思います。

## 2.1 事前にアプリケーションはインストールすべし
当たり前ですが、ネットワークが適合なのか、アプリケーションが正常に稼働するのかは必ず試しておく必要はあります。（公式から事前チェックはしてねという通知はありました。）

## 2.2 勉強期間
およそ２ヶ月半でした
Udemyの模擬試験が解けなくて、長引いてしまいました。
後々に書いてますが、Udemyの模擬試験を重要視せず、Ping-tを網羅した方がいいです。



# 2.3 データセンターよりも自宅受験が断然おすすめ
これは人によるかなとは思いますが、慣れてる自宅での環境で他の人のため息や行動が気にならずにできるのでとてもおすすめです。

# 3.テストの所感
１０問くらいは難しい問題で、聞いたことのない詳細なオプションの問題などがありました。
他５０問くらいは意外と準備しっかりしていればすんなりと解ける問題が多かったと思います。

## 3.1 受けてみての勉強の反省・これやって正解だったなと思うこと。
Udemyの模擬試験で、EKSの問題がやたらと多くて、「こんなにEKSの問題は出ないだろっ」
とは思っていたのですが、試験当日、意外にも出題数が多かった印象でした。

後は基本的にPing-tの『試験レベル』を解説、他の設問がなぜダメなのかを理解できればOKだと思います。

一番良くないのは他の設問が理解できずに終わらせることかなと思います。
今回といた問題がたまたまその手法が間違っているだけで、それが正しいケースもあるからです。

# 3.2 Udemyの模擬試験は難しい
問題の難易度は明らか難しいです。
これができないからと言って、思い詰めないで欲しいです。（過去の自分へ）
各サービスの細かいオプションが模擬問題に多く、覚えきれなかった部分もありました。

何回か受験すれば80~90にはなるとは思いますが、
初見で80%くらいいく人は逆にどんな勉強をしていたのか気になります。笑

# 3.3 試験結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/00009ad8-ccee-60d8-120b-d4d9806ec2a1.png)

見事合格できました。

# 4.大事なのかこれから
ある程度、サービスの知見は得ることはできました。
試験勉強していく中で、「これ実際のケースを想像して個人で構築してみたいな」と思った次第です。
SQSのメッセージングとかすごい面白そうですよね。
経営視点で、Organaizationsの設計とかも面白そうです。

これから様々な知見を業務で得られたら嬉しいです。

実際にSAAの試験で学習したサービスを使って、構築してみたシリーズもやっていきたいなとは思います。
tsxでError [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'

# 本記事について
tsxでTypeScriptを実行しようとして出たエラーがデバッグできず、ググっても対処法が出てこなかったので、同様の症状を経験する方のために記事に残そうと思いました。

# 結論
表題のエラーが出たらNode.jsをアップデートすると直るケースがある。

# 症状

```package.json
{
  "name": "***",
  "type": "module",
  "scripts": {
    "dev": "tsx src/index.local.ts"
  },
  "devDependencies": {
  },
  "dependencies": {
  }
}
```
からの
```
npm run dev
```
で出たエラー
```

> dev
> tsx src/index.local.ts

node:internal/errors:496
    ErrorCaptureStackTrace(err);
    ^

Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'
    at __node_internal_captureLargerStackTrace (node:internal/errors:496:5)
    at new NodeError (node:internal/errors:405:5)
    at throwIfUnsupportedURLScheme (node:internal/modules/esm/load:136:11)
    at defaultLoad (node:internal/modules/esm/load:87:3)
    at nextLoad (node:internal/modules/esm/loader:163:28)
    at load (file:///C:/Users/****/node_modules/tsx/dist/esm/index.mjs:2:1768)
    at nextLoad (node:internal/modules/esm/loader:163:28)
    at ESMLoader.load (node:internal/modules/esm/loader:603:26)
    at ESMLoader.moduleProvider (node:internal/modules/esm/loader:457:22)
    at new ModuleJob (node:internal/modules/esm/module_job:64:26)
    at #createModuleJob (node:internal/modules/esm/loader:480:17)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:434:34) {
  code: 'ERR_UNSUPPORTED_ESM_URL_SCHEME'
}

Node.js v18.18.0
```

# 対処経緯

node_modulesフォルダを削除；
```
del /s /q node_modules > NUL
```
からのWindowsエクスプローラーでフォルダを削除
からの
```
npm install
npm run dev
```
で症状再現。
筆者の環境ではnvmを使っているので、以下コマンドでNode.jsをアップデート
```
> nvm list

    20.9.0
  * 18.18.0 (Currently using 64-bit executable)
    16.16.0
    12.13.0
> nvm install 18
Downloading node.js version 18.20.4 (64-bit)... 
Extracting node and npm...
Complete
npm v10.7.0 installed successfully.


Installation complete. If you want to use this version, type

nvm use 18.20.4
> node --version
v18.18.0
> nvm use 18.20.4
Now using node v18.20.4 (64-bit)
> node --version
v18.20.4
```

これでnpm run devしたら意図したとおりにindex.local.tsを実行できた！！
BotユーザーからのPRにレビューリクエストを送らないCODEOWNERSの設定方法

# 概要

GitHubの[CODEOWNERS](https://docs.github.com/ja/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners)は、特定のファイルやディレクトリに変更が加わった場合に、指定のメンバーに自動でレビューリクエストが送られる便利な仕組みです。

しかし、dependabotやrenovateなどの依存関係アップデートの仕組みを導入している場合、Botユーザーが出したPRは必ずしもレビューが必要でない場合もあります。自動マージの設定を有効にしているリポジトリだと、レビューリクエストがノイズになることも多々あります。

そこで、以下のようにCODEOWNERSを設定します。

### npmの場合
```codeowners
* @some-team
package.json
package-lock.json
```

### goの場合
```codeowners
* @some-team
go.mod
go.sum
```

### php composerの場合
```codeowners
* @some-team
composer.json
composer.lock
```

CODEOWNERSは最後にマッチしたルールが適用される仕様です。つまり、例えばBotユーザーが出したPRの差分がpackage.jsonとpackage-lock.jsonのみしかない場合は、それぞれCODEOWNERSが空で上書きされるため、結果的にレビュワーのアサインが空になるという仕組みです。

このテクニックは、以下のStackOverflowの記事から引用したのですが、あまり知られていなさそうだったので、記事として残しておきました。
https://stackoverflow.com/questions/75531641/exclude-codeowners-from-dependabot-pr

なお、注意点として、この方法では通常の人間によるPRでも同じルールが適用されてしまいますが、依存関係アップデートの仕組みを導入しているリポジトリで、依存関係のみアップデートするPRを出す機会はそう多くないでしょうし、問題になるケースは稀かと思われます。
【Laravel】定数ファイルの作成と参照

## 概要
Laravelにて可読性を上げるために定数ファイルを設けようと思った際に、
どのように定数ファイルを読み込ませるかわからなかったので調べました

どうやら手法としては3つあるようです
1. config配下を使う
2. Modelファイルを使う
3. 定数用ディレクトリを作る

configファイルは定数が増えた際に肥大化しそうなので却下、Modelファイルも本来の用途とずれてる気がするので、管理しやすそうな定数用ディレクトリを作る方法を取りました
他の手法については割愛させてください

## 実装
### 1. 定数用フォルダを作成
Constsフォルダを作成します
場所は特に縛りはありませんが、app配下が一般的のようです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480378/4ac76d77-b301-151e-b2e8-a8533cb66eb8.png)

### 2. 定数ファイルを作成し、定数を定義
作成したフォルダにConsts.phpを作成
自分が使用したい定数を定義します
```
<?php
namespace App\Consts;

class Consts
{
    const CSV_FILE_NAME = 'hoge.csv';
    const ZIP_FILE_NAME = 'hoge.zip';
}
```
### 3. 定数を参照
定数を参照する場合は、以下のようにすれば参照できます
```
use App\Consts\Consts;

class Hoge
{
    // 定数を参照
    $fileName = Consts::CSV_FILE_NAME
```
Spring Boot学習後の備忘録

# はじめに
Spirngbootの学習を行うために、書籍を購入し最後まで学習完了したので備忘録としてQiitaに残しておきます。

学習時期：2024/9～2024/10末(約2ヶ月)
学習時間：平日1~2h 休日2~3h程度
使用した書籍：【Spring Bootが丸わかり Sprin解体新書　第2版】

目次
1章：Springの概要 
2章：開発環境の構築 
3章：HelloWorld･･･簡単なサンプル 
4章：Webアプリケーションの概要 
5章：Dependency Injection(依存性の注入) 
6章：バインド＆バリデーション(入力チェック) 
7章：画面レイアウト 
8章：MyBatis 
9章：AOP 
10章：エラー処理 
11章：Springセキュリティ 
12章：REST 
13章：Spring Data JPA

# 苦戦した章
6章：バインド＆バリデーション(入力チェック) 
8章：MyBatis 
11章：Springセキュリティ 

# 疑問点解決方法

・Qiitaにて問題点の投稿
・エラー文を参考にネットで解消方法検索
・チャットGPTを利用してエラー解消方を模索

ほぼQiitaにて投稿して回答、アドバイスを頂いたおかげで進めることが出来ました。投稿の内容のアドバイス等も頂きとても参考になりました。
また、綴りミス等や単純ミスも多く、そこの部分は自分自身作業の精度を高める必要があると反省しました。

# 書籍の内容との差異
Spring securityの設定の書き方が大幅に変更になっていたりし、書籍のサンプルソースだと上手く動かない部分が多々存在していました。
その部分はQiitaにて、聞いて、調べることで進めていきました。
後ほどGitにて完成ソースを展開する予定です。

# 学習完了後のソース


# 学習後の感想
私は今SESで現場で仕事をしています。Javaを使用しているもののフレームワークがSpringではないため研修ぶりの学習でした。
便利な機能も多く現場で実際にSpringを使用してみたいなと思いました。
JavaScript等が全然かけないのでそこの学習もやっていきたいなと思います。
地図アプリの作り方 --Geohash--

## なぜGeohashが必要なのか
地図上で検索してピンを立てる機能を作るのに必要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776243/38cb611e-968c-f2bd-219b-bd9283502433.png)

## Geohash超概要

Geo: 地理情報（緯度経度）
Hash: 文字列に変換

つまり、緯度経度を文字列に変換したもの

## 検索システムの愚直な実装
愚直に検索システムを実装することを考える。
このような構成のテーブルを想定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776243/6b146422-679e-c0f6-150a-c45bbad9af5e.png)

地図の表示地点に近い店舗をSQLで検索する。
* 地図表示地点の緯度経度は map_center_lat, map_center_lng とする
* 表示領域は -Δlat ~ Δlat, -Δlng ~ Δlng とする

```SQL

SELECT * FROM RESTAURANT
WHERE
    map_center_lat > (lat - delta_lat) -- 緯度絞り込み1
    AND map_center_lat < (lat + delta_lat) -- 緯度絞り込み2
    AND map_center_lng > (lng - delta_lng) -- 経度絞り込み1
    AND map_center_lng < (lng + delta_lng) -- 緯度絞り込み2
    -- 今回は地理情報処理の話なので店舗の検索は省略
```
課題
* 条件式が4つ必要
* 範囲を絞り込むΔlat, Δlngが感覚的にわかりにくい


## Geohashを使って検索システムを実装する
このような構成のテーブルを想定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776243/31a4058a-706e-819b-99af-833d63267b5d.png)

地図の表示地点に近い店舗をSQLで検索する。

* 地図表示地点の緯度経度をエンコードしたものを map_geohash とする

```sql
SELECT * RESTAURANT
WHERE geohash = map_geohash
```

これだけで地図に表示されている座標のGeohashと同じ、つまり近い場所にあるものを検索することができる。
Geohashの桁数を落として検索すれば検索範囲を広げることができる。

実装して動かしてみる。

![mappp.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776243/823bcbad-e4f5-18b9-5a6a-caea07e89ce2.gif)




## Geohash 計算方法
### 1. 緯度経度を二進数に変換
緯度は -90 ~ 90 のレンジがあるので、このレンジを二分探索する。
-90 ~ 90 の中間は0, ターゲットの値が右にあるので1桁目は 1 -- ①
0 ~ 90 の中間は45, ターゲットの値が左にあるので2桁目は 0 -- ②
必要な桁数まで繰り返す

![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776243/c6cbb71c-8654-1b21-b3d6-b4870d186c17.png)

つまり、桁が増えるごとに精度が倍々になる。
経度も同様の方法で算出する。

### 2. 二進数の緯度経度をミックス
二進数緯度と二進数経度をミックスして一つにする。
緯度は奇数ビット、経度は偶数ビット

![タイトルなし2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776243/493ccc66-21f0-3ae9-02b2-9aaa71f8dfdb.png)

### 3. Base32 でエンコーディング
2でミックスした二進数を5ビットずつに区切ってBase32でエンコーディングする

011100001011010
↓
01110 / 00010 / 11010
↓
OC2

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776243/f442e7dc-053f-3e7c-0314-8144abf4b375.png)
ref: RFC3548 https://datatracker.ietf.org/doc/html/rfc3548


## Geohash のエレガントさ
* 「ある座標に近いものを検索する」という複雑な問題を「同じ文字列を検索する」という単純な問題に置き換えることができる
* 検索文字列を短くすれば広範囲、長くすれば狭い範囲の検索ができる
    * 感覚的にわかりやすい
* Geohashにインデックスを貼ることで検索の高速化ができる
* 緯度経度表現より桁数が短くなる
    * 東京都庁
    * 35.6896068,139.6891424
    * xn7749ke



ちなみに、GoogleではPlus codeというジオエンコーディングが用いられており、これはGeohashと似たような性質を持つ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776243/03c5b6c9-d7e8-b381-fd07-2d6b00531fc9.png)
Pythonでsocketを使ったタスク間通信

# Pythonのタスク間でデータを共有する方法
FlaskやFletのようなフレームワークを使っていると、インポートしたライブラリがうまく動かないものがある。
win32com.clientで起動した、DAOオブジェクトやExcelオブジェクトはFletで起動できなかったため、１対１で動作するタスクとしてDAOとExcelを制御する部分を起動しSocketでタスク間通信を行った。

# サーバー側
今回は、低水準ソケットを使ってTCPで通信する

``` python
import socket

def aeServ():
    HOST=''
    PORT=5000
    BLEN=1024
    skt=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    #
    def cnloop():
        skt.listen()
        conn, addr = skt.accept()
        cmd = '-'
        while cmd != "close":
            cmdb=conn.recv(BLEN)
            cmd=cmdb.decode()
            if cmd=='cmd':
                # コマンド処理
                # 正常なら
                conn.sendall(b'OK')
            #
            if cmd=='close':
                # 後処理
                # 正常なら
                conn.sendall(b'OK')
    #
    cnloop()
```
ポート番号は、元来Linuxの/etc/servicesで定義されていないものを使い、WindowsではC:\windows\system32\drivers\etcにservicesがあり記載されていないポートを使います。HOSTにIPアドレスやホスト名がなければlocalhost(127.0.0.1)になります。
このプログラムではコマンドとしてcloseを受信すると待受ループから抜けます。

# クライアント側
クライアント側は、
``` python
import socket
import json

HOST = '127.0.0.1'  # サーバーのホスト名
PORT = 5000         # サーバーのポート番号

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.sendall(b'cmd')
    data = s.recv(1024)
    print('Received', data.decode())
    s.sendall('close'.encode())
    data = s.recv(1024)
    print('Received', data.decode())
    #
```
cmdを送り、サーバー側のレスポンスを受けてclose命令で終了します。
アウトラインは概ねこんな感じです。
collectionとmember 検索機能　【備忘録】

## はじめに
これからオリジナルアプリを作るので、付けたい機能の勉強に記録します。
まずは検索機能を付けたいので`collection`と`member`について復習していきます。

viewファイルは既に作った状態。
searchアクションのルーティングをこれから記述する段階。

```ruby
    collection do
      get 'search'
    end
```
collectionのルーティングは`id`がついていない。
```
Prefix           Verb    URI                                Pattern
search_comments   GET    /comments/search(.:format)         comments#search
```
これに対してmemberは`id`がつく。
```ruby
    member do
      get 'search'
    end
```
```
Prefix           Verb    URI                                Pattern
search_comment    GET    /comments/:id/search(.:format)     comments#search
```
検索機能の場合、詳細ページのような:idを指定して特定のページにいく必要がないから
collectionを使用してルーティングを設定する。

これからconfigにsearchアクションを記述する。
```config/routes.rb
    collection do
      get 'search'
    end
```

## おわりに
これで検索ボタンが表示されるので明日はモデル、コントローラーに実装していきます！
【Next.js + Laravel】野球の試合結果を記録するアプリケーションの開発 #1

## 概要
自分自身小学校から今現在までずっと野球をやっていまして、そんな中で手軽に試合結果を記録できたらいいな〜と思ったのでタイトルのようなアプリケーションを作ってみることにしました。野球のスコアってつけるの意外と難しいです笑　あとアプリ名はBaselogと名付けました。これから何回かにわたってその開発工程をシェアしつつその内容が誰かの開発の役に立てればと思っています。

## 機能
- 試合結果の記録：スコア、ヒット数、エラー数（スコアボードのような感じ）
- 試合一覧の表示：過去の試合結果の一覧を表示
- 試合詳細の表示：試合の詳細を確認
- 編集・削除機能：試合データの修正や削除
- 認証機能：ログインしたユーザーのみがアクセスできるように管理

## 開発環境
- フロントエンド：Next.js, TypeScript
- バックエンド：Laravel
- データベース：PostgreSQL(Heroku), MySQL（ローカル）
- ホスティング：フロントエンドはVercel, バックエンドはHerokuにデプロイ

### その他
- Node.js：Next.jsの開発に必要なランタイム環境
- Composer：Laravelの依存管理ツール
- MySQL（ローカル開発用）：MAMPを利用
- PostgreSQL（Heroku）：本番環境のデータベース

## 開発の流れ
1 環境構築
2 バックエンド開発（APIの実装、認証機能の実装）
3 フロントエンド開発　（画面構築、API連携、認証）
4 デプロイ

ざっくりこのような流れで開発を行ったので、Qiita記事でもこの順番で書いていければと思います。
LangChain v0.3　その２~LCEL（LangChain Expression Language）~

# きっかけ
ま、前の続きっす
ほんと、あのライトニングトークは素晴らしかった。
うん。
紹介し忘れてましたね。じゃ、ご本人のnoteをば。

https://note.com/hs294/n/naf4968b38250


# バージョン関連
Python 3.10.8
langchain==0.3.7
python-dotenv
langchain-openai==0.2.5
langgraph>0.2.27
langchain-core

※LLMのAPIはAzureOpenAIの`gpt-4o-mini`を使いました

# 準備
`.env`ファイルに以下を用意しましょうね
END_POINT="https://<<ほにゃらら>>.openai.azure.com/"
API_KEY="<<ほにゃらら>>"
API_VERSION="2023-05-15"
LANG_SMITH = "<<ほにゃらら>>"

# 今日の目的
LCEL（Langchain Expression Langage）使う


#### ライブラリのインポート
```Python
import os
from dotenv import load_dotenv
# from openai import AzureOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import AzureChatOpenAI
from langchain_core.output_parsers import StrOutputParser
```

#### `.env`からAPI_KEYやらなにやらを取ってくる準備
```python
load_dotenv(dotenv_path='.env')
```

#### その１でやった`ChatPromptTemplate`
```python
prompt_template = ChatPromptTemplate([
    ('system', 'あなたは偉大な漫才師です'),
    ('user', '{topic}について大喜利してください'),
])
```

#### モデルの準備
```python
model = AzureChatOpenAI(
    model='gpt-4o-mini',
    azure_endpoint=os.getenv("END_POINT"),
    api_version=os.getenv("API_VERSION"),
    api_key=os.getenv("API_KEY")
)
```

#### 出力の準備
これでテキストで出力ができる
```python
output_parser = StrOutputParser()
```

## LCEL（LangChain Expression Language）の設定
今日のキモっす
上で設定した`prompt_template`と`model`と`output_parser`を連結させるんです。

```python
chain = prompt_template | model | output_parser
```

## chainに入れて出力させます
```python
response3 = chain.invoke({'topic': '靴下'})
print(response3)
```

```output:output
'もちろん！靴下についての大喜利、いきますよ！\n\n1. 靴下が「お前、今日もいい匂いだな！」と言われた理由は？\n   - 洗濯したのを忘れて、靴の中で大宴会してたから！\n\n2. 靴下がデートに行くとき、何を気をつける？\n   - 相手の靴と色を合わせること！靴下の恋愛は「足元」から！\n\n3. 靴下が自分の存在意義を悩んでいるとき、どうする？\n   - 「私はただの布じゃない、あなたの足を守るヒーローだ！」と自己啓発セミナーに参加！\n\n4. 靴下が友達に「どうしていつも片方だけ無くなるの？」と聞かれたら？\n   - 「それは、片方が夢を追いかけて旅に出るからさ！」\n\n5. 靴下が流行を追いかけているとしたら、どんなスタイルを提案する？\n   - 「今季のトレンドは、足元に“スニーカー”と“サンダル”のハイブリッド！通気性抜群！」\n\nどうでしたか？靴下も意外と面白いネタになるんですね！'
```

あら面白い。そして簡単。
今日はLCELが中心なんですが、御覧の通り、パイプ（|）で繋げるだけなんですよね。
これで順に処理をしてくれちゃいます。
また次々回くらいでLCELを使いますのでお楽しみに

今日はココまで。
データ構造 - 連結リストについて

## はじめに
コンピュータプログラムにおいて、データを効率的に扱うことは非常に重要です。そのためには、適切なデータ構造を選択することが不可欠です。
今回は、その中でも特に連結リストというデータ構造について詳しく解説していきます。

## データ構造とは
データ構造とは、コンピュータ上でデータを効率的に格納し、組織化するための手法や方法のことです。
データを効率的に操作し、必要な情報を素早く取り出すためには、適切なデータ構造を選択する必要があります。

## 連結リストとは
多くのプログラマーが馴染みのある配列は、リスト内のすべての要素をインデックスを使って管理するデータ構造です。
一方、連結リストは、データがメモリ上の連続したブロックに格納されないという点が特徴です。

連結リストでは、各要素をノードと呼び、ノードにはデータと次のノードへの参照が格納されています。
この参照をたどることで、あるノードから次のノードへと順々にアクセスすることができます。

### 片方向リスト
連結リストの中でも最も基本的な形態の一つです。
各ノードはデータを格納する変数と、次のノードを指すポインタ変数から構成されています。
次のノードを指すポインタは、リストの最後尾に達した場合には null 値を格納するか、空のリストを指すこともあります。
以下に簡単な画像とソースコード(TypeScript)を記します。

![片方向リスト.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3893766/b72131cf-f9ab-cfd8-f627-3cea2d64216b.jpeg)

```
class Item {
    data: number;
    next: Item | null;

    constructor(data: number) {
        this.data = data;
        this.next = null;
    }
}

class SinglyLinkedList {
    head: Item;

    constructor(item: Item) {
        this.head = item;
    }
}

let item1: Item = new Item(7);
let item2: Item = new Item(99);
let item3: Item = new Item(45);

item1.next = item2;
item1.next.next = item3;

let numList: SinglyLinkedList = new SinglyLinkedList(item1);

let currentItem: Item | null = numList.head;
while(currentItem !== null) {
    console.log(currentItem.data);
    currentItem = currentItem.next;
}
```

### 双方向リスト
連結リストの一つで、双方向の走査を可能にするものです。
双方向リストでは、各ノードはデータを格納する変数と、次のノードを指すポインタ変数だけでなく、前のノードを指すポインタ変数も含んでいます。
このため、リストを順方向と逆方向の両方で走査することができます。
片方向リストと同じく、次のノードを指すポインタは、リストの最後尾に達した場合には null 値を格納するか、空のリストを指すこともあります。
以下に簡単な画像とソースコード(TypeScript)を記します。

![双方向リスト.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3893766/94369580-231f-d65c-33f0-af41e3e9133b.jpeg)

```
class Item {
    data: number;
    next: Item | null;
    prev: Item | null;

    constructor(data: number) {
        this.data = data;
        this.next = null;
        this.prev = null;
    }
}

class DoublyLinkedList {
    head: Item;

    constructor(item: Item) {
        this.head = item;
    }
}

let item1: Item = new Item(7);
let item2: Item = new Item(99);
let item3: Item = new Item(45);

item1.next = item2;
item2.prev = item1;
item2.next = item3;
item3.prev = item2;

let numList: DoublyLinkedList = new DoublyLinkedList(item1);

let currentItem: Item | null = numList.head;
while(currentItem !== null) {
    console.log(currentItem.data);
    currentItem = currentItem.next;
}
```


## まとめ
| 特徴 | 片方向リスト | 双方向リスト |
|:-:|:-:|:-:|
| メモリ消費  | 少ない  | 多い  |
| 参照  | 一方向  | 両方向  |
| 挿入・削除  | 特定のノードの前への挿入は効率が悪い  | 特定のノードの前後への挿入・削除が効率的  |

今回は、データ構造の一つである連結リストについて簡単に解説しました。
連結リストは、配列とは異なる特徴を持つデータ構造であり、適切な場面で活用することで、より効率的なプログラムを作成することができます。
【Ruby】シングルクオート、ダブルクオートの使い分け

# はじめに
Rubyでは文字列を作る際に、シングルクオート（'）、またはダブルクオート（"）で囲む方法が存在します。ちらっと調べると、「どちらでも良い」と書かれており、「どちらでも良い」が一番柔軟かつ困ることだなあと思ったので、調べてみようと思いました。

## 明確に異なる点
### ```\n``` 改行文字など（バックスラッシュ記法）を使用する場合
```ruby
puts 'りんご\nゴリラ\nらっぱ'
#=> りんご\nゴリラ\nらっぱ

puts "りんご\nゴリラ\nらっぱ"
#=> りんご
#   ゴリラ
#   らっぱ
```
他にも```\s``` 空白文字や、```\t``` タブ文字もよく使用するが、シングルクオーテの場合そのまま文字列と見なされてしまう。

### ```#{変数}``` 式展開を使用する場合
```ruby
name = 'パンダ'

puts "しりとりの続きは#{name}です"
#=> しりとりの続きはパンダです

puts 'しりとりの続きは#{name}です'
#=>　しりとりの続きは#{name}です

# シングルクオーテを使用したい場合このように書ける
puts 'しりとりの続きは' + name + 'です'
#=>　しりとりの続きはパンダです

```
この場合もシングルクオーテではそのまま文字列とみなされてしまう。
+演算子を使用する書き方は、記号が多く登場してしまうのでダブルクオーテでの式展開の書き方の方が読み書きしやすい。

## その他の記述
### 逆に機能を打ち消したい場合
```ruby
puts "りんご\\nゴリラ\\nらっぱ"
#=> りんご\nゴリラ\nらっぱ
```
```ruby
name = 'パンダ'

puts "しりとりの続きは\#{name}です"
#=> しりとりの続きは#{name}です
```
バックスラッシュ記法や、式展開の手前に ```\``` バックスラッシュをつける

### 文字列の中でシングルクオーテやダブルクオーテを使用したい場合
```ruby
puts 'He can\'t say, "Hello, World."'
#=> He can't say, "Hello, World."

puts "He can't say, \"Hello, World.\""
#=> He can't say, "Hello, World."
```
シングルクオーテやダブルクオーテの手前に ```\``` バックスラッシュをつける

## 最後に
私の現在の開発現場では、文字列の中に ”式展開が記述されている” がわかりやすいからという理由で「ダブルクオートを使う必然性がない場合は、シングルクオートを使おう」というコーディング規約です。皆さんの考え方や捉え方など教えていただけると嬉しいです！
ご指摘や、その他ご意見などあれば是非コメントお待ちしております！

## 参考文献
https://ruby-book.jnito.com/

https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%92%E7%9B%AE%E6%8C%87%E3%81%99%E4%BA%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AERuby%E5%85%A5%E9%96%80-%E8%A8%80%E8%AA%9E%E4%BB%95%E6%A7%98%E3%81%8B%E3%82%89%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA%E3%83%BB%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E6%8A%80%E6%B3%95%E3%81%BE%E3%81%A7-Software-Design-plus%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4774193976
Qiita Advent Calendar完走のコツ！初心者でも大丈夫！🎉

こんにちは！

Qiita Advent Calendar、参加したいけど完走できるか不安…🤔

そんなあなたも、絶対大丈夫！
2023年のQiita Advent Calendar、そして2024年のQiita Engineer Festaを完走した私が、完走のコツを伝授します！🎁

完走後は思ってる以上にスキルアップするので、一緒にがんばりましょう！🎅

## なぜAdvent Calendarに参加したのか？

きっかけは、会社の取り組みの一環として、仲間と参加することになったからです。
2023年は22名で参加して、非常に盛り上がりました！🎄

毎日、誰がどんな記事を書いたかチェックしたり、お互いにコメントし合ったりと、とても刺激的でした。

一人で黙々と作業するよりも、仲間と一緒だとモチベーションも維持しやすいですね🙂

## 完走を目指した理由

「エンジニアとしてもっと成長したい！」というのが一番大きいです🚀

Advent Calendarは、まさにうってつけの機会。
完走という目標を立てることで、自分を成長させる絶好のチャンスだと考えました👍

## 完走して感じたメリット

大変なこともありましたが、完走したことで得られたものは計り知れません✨

* スキルアップ：毎日アウトプットすることで、技術理解が深まり、新しい技術にも挑戦できました
* 自信：やり遂げたという達成感は、大きな自信に繋がります。「自分にもできた！」という成功体験は、今後の活動の原動力になります
* 仲間との繋がり：社内やQiitaコミュニティでの交流が活発になり、新たな繋がりもできました
* アウトプット習慣の定着：毎日書く習慣が身につくことで、ブログ執筆や情報発信のスキルが身に付きます

## 完走までの道のりと乗り越え方

正直、楽な道のりではありませんでした。特に辛かったのは以下の３点です。

* **ネタ切れの壁:** 
書き始めはアイデアがあっても、すぐにネタが尽きてくる…😱
* **時間との戦い:**
仕事やプライベートで忙しい中、毎日記事を書く時間を捻出するのは至難の業…😫  私も1記事あたり最大3時間しか確保できない日々でした
* **Qiitaからの通知プレッシャー:**
毎日の投稿リマインダーメールがプレッシャーに感じることも…😰

でも大丈夫！これらの困難は、以下の方法で乗り越えられます！

1. **新しい技術にチャレンジ✨**
大きな成長に繋がるチャンス！特に今は、AIがどんどん高性能になってます。アシスタントとして、どんどん活用しましょう！
※ちゃんと理解して、動作確認する前提です。
2. **得意分野を深堀り✨**
普段使っている技術でも、深く掘り下げてみると新しい発見があります。読者にも役立つ情報を提供できます
3. **知識の棚卸し✨**
自分がどんな技術を知っているかリストアップしてみましょう。意外と忘れていた知識や、掘り下げていない分野が見つかるはず

## 今後の目標

完走賞を2回獲得したので、あと3回、計5回を目指して挑戦を続けます！🔥
この記事の執筆時点で80記事書いているので、ネタ探しは大変ですが…😂  乗り越えた先に、大きな成長が待っているはず💪

## さいごに

Advent Calendar完走は、決して簡単なことではありません。
しかし、得られるものは非常に大きいです。

この記事が、皆さんの挑戦の後押しになれば幸いです！😊

一緒に盛り上げていきましょう！🎉
作業進んでる時の気持ち_備忘録_0

(新しい日付順)
---
## 2024-12-20
嫉妬。https://www.youtube.com/watch?v=0zXxxgPCPKY&list=PLyGjs39YnmCNmJybhH_dm34VHtcmAapiy&index=1
好きなのに。半分悔しい気持ちで観てる。
だから、それを力にしている。
一旦抜いて、落ち着かせて取り組んだ。


## 2024-11-15
はぁ！？💢💢大嫌いなホロライブがVtuber1人あたりの年収が4億円！？ぶち○してやる！！！！ぁぁああああああああああああああ"！！！！！！！
- ワタクシより頑張らないでかねかせーでる○んだ方がいい人間のかたまりホロライブの集団ができるんだったら、ワタクシのプロジェクトが完成すればそれより儲けられるはずだ。私は地球上全ての人間をを幸せにする目標があるんだ。ホロライブのようなクズ集団はすぐ○べ！！！！💢💢

## 2024-11-14
- アニメを観なくても手を付けられる気がしてきたので、作業用のPC、遊び用のPCの２つを用意した。
今後はこの２つを行き来するようにして作業をする。
作業用として流して良いものは
https://www.youtube.com/watch?v=2N0AbG4jegA&t=s
のみ許可をする。

## 2024-11-11
- 首からタイマーをぶら下げ、アニメを見ながら作業をする。
    - 作業に取り掛かるときは5分計る。タイマーが鳴ったら、作また5分はかる。セルフ的インターバルです。タイマーが嫌になったら、休憩してもOK。とにかく、作業をしたくなったら5分はかる。
    - 作業が少しでも進んたら、感動です。「良かった」と、安心します。
    - 「作業が辛い」と感じた時は、あともう1分、辛いけど作業を続ける(タイマー)
    - 途中でアニメが鬱陶しくなったら、アニメを一時停止(10秒でも5分でも)して、作業を進めてOK

## 2024-11-06
(2年前に考えたことの振り返り)
何かを成し遂げるには

・必要になったものを勉強する
大抵これで楽に突破できる。

・とりあえずここの分野を片っ端から勉強する
凄い人はこれで突破する。

後者は難しいが、前者も行き詰まった時にメンタル的に実行出来る事柄です

辛い時は後者になれ
楽な時は前者になれ

これでフローに入れるだろうか。

## 2024-11-04
「タイマーをもって、1分確認するだけ。」
Windows Form を作成する PowerShell コードを見やすくする

PowerShell で、System.Windows.Forms のアセンブリを利用して、Windows Form を作成するとき、例えば `Label` なら
```powershell
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(10,20)
$label.Size = New-Object System.Drawing.Size(250,20)
$label.Text = "Example of code to display labels"
```
のように書くところを、`Property` とハッシュテーブルを用いて
```powershell
$label = New-Object System.Windows.Forms.Label -Property @{
    Location = New-Object System.Drawing.Point(10,20)
    Size = New-Object System.Drawing.Size(250,20)
    Text = "Example of code to display labels"
}
```
と書くことによって、見やすくできます。

また、`Location` と `Size` は
```powershell
$label = New-Object System.Windows.Forms.Label -Property @{
    Location = "10, 20"
    Size = "250, 20"
    Text = "Example of code to display labels"
}
```
と書くことによって、もっと見やすくできます。

なんなら、`Size` は `AutoSize = $true` に置き換えると、サイズをいくつにしようか悩まなくてすみます。
```powershell
$label = New-Object System.Windows.Forms.Label -Property @{
    Location = "10, 20"
    AutoSize = $true
    Text = "Example of code to display labels"
}
```
【ポエム】私が考える技術イベントの楽しみ方

いつも記事を読んでいただきありがとうございます！
モブエンジニア（[@mob-engineer](https://qiita.com/mob_engineer))です！

今回は、**私が考える技術イベントの楽しみ方**について、個人的に考えていることをつらつらと記事に書き起こしてみたいと思います。

:::note info
あくまで一個人の意見ですので、参考レベルでとどめていただければ幸いです
:::

# 目次
1. 読んでもらいたい読者層
1. 技術イベントへ参加する理由
1. 個人的に考える楽しみ方
1. 技術イベントは参加後こそ重要
1. まとめ

## 読んでもらいたい読者層
今回の記事は、**技術イベント**をテーマにした記事ですので、少なくとも「技術イベントに対して何かしらの悩みを抱えている方」の役に立てればと思っています。より具体的にお伝えすると、

- 技術イベントに参加してみたいけど、いまいち乗り気になれない方
- 技術イベントに参加して楽しめるか不安だと思っている方
- なんとなく技術イベントへの参加がめんどくさいと思っている方

になります。

もちろん、**技術イベントに参加している方**もぜひ読んでいただければと思います。そのうえで、ディスカッションの意味でお気軽に質問やあなたの考えをお伝えいただければ幸いです。

## 技術イベントへ参加する理由
ふと、技術イベントへ参加する理由を考えると意外と思いつかないですが、要素分化していくと次のことがあげられるのではないかなぁと考えています。

- 先端技術・守備範囲外の技術情報を収集できる
- 今まで触れ合ったことがない方とのネットワーキングを構築できる
- 知人が技術イベントに参加しているから流れで参加している
- 有名人が技術イベントに参加している

などなど

個人的に、技術イベントへ参加する理由は人それぞれで自由でいいと思います。そのうえで、技術イベントに**ただ参加する**でなく、**自身の知識としてインプット→アウトプットしていく**といったモチベーションで参加することで、より技術イベントを楽しめるのかなぁと思っています。

## 個人的に考える楽しみ方
個人的に考える楽しみ方としていくつかありますが、次のことがあるかなぁと思っています。

- （技術イベントの会場が普段いかない場所であれば）小旅行感覚で参加してみる
- オフラインイベントであれば参加者とのコミュニケーションをを積極的に図ってみる
- 運営側で参加されている方がいれば、イベントに関する雑談を行ってみる
- （もし、あれば）イベント後の懇親会に参加してみる
- 得た知識を定着させるために、**技術ブログとして形に残しておく**

あくまで、個人的な意見なので人それぞれですが、**技術ブログとして参加レポートを残しておく**モチベーションで参加してみると、**よりモチベーション高く参加できる**のかなぁと思っています。

## 技術イベントは参加後こそ重要
記事内でも何度か触れていますが、**インプット→アウトプットさせていく**ことが知識・経験の定着に一番効果的だと考えています。

もちろん、**技術ブログを通じたアウトプット**に対してハードルが高い方もいらっしゃると思いますので、知人や同僚に**技術イベントを通じた発見を共有する**でもいいと思います。その一環として、技術ブログとしてアウトプットしていくことを続けると、おのずと**技術ブログへのハードル**を下げることができるのかなぁと個人の景観から感じています。

## まとめ
簡単ですが、私が考える技術イベントの楽しみ方をまとめてみました。技術イベントの楽しみ方は人それぞれだと思いますので、どのような観点で楽しんでもいいと思います。

そのうえで、**技術イベント参加後のアウトプット**こそ、一番面白く、自身の知識・経験の定着につながると考えています。本記事を読み終わった後に、一人でも多く**アウトプット活動に興味関心を持つ方**が増えてくだされば、記事を執筆してよかったと感じます。

最後に、技術イベントの探し方ですが、

**技術系イベントはconnpass**、
**ビジネス系イベントはPeatix**

といった使い分けを私は行っています。

https://connpass.com/

https://peatix.com/?lang=ja

最後まで、記事を読んでくださいありがとうございます。
Service type: ExternalName が便利なシーンを解説してみる

k8sを勉強してます。Service の ExternalName を何に使うかわからなかったので [Tech Rock Festivial](https://github.com/jyoshise/tech-rock-festival) にも参加している同僚に教えてもらいました。

# Dev, Prod で API の向き先を変えたいシーン

例えば、betaでは社内のｍock、prodでは api.slack.com の API を使うみたいなシーンです。（同僚が教えてくれた例そのまんま）

## applicationの実装

podで動くapplication側は、ダミーのドメインにアクセスします。ここでは `slack` とします。

```py
requests.get("https://slack")
or
requests.get("https://slack.default.svc.cluster.local")
```

## ExternalName でドメインを置き換える
### Overview

簡単にいうとこういうことです。`metadata.name` に指定した名前に対して、podは `slack` または `slack.<namespace>.svc.cluster.local` で名前解決ができるようになります。

```yml
apiVersion: v1
kind: Service
metadata:
  name: slack    # <-- pod がアクセスするのはこっち。externalName宛のaliasみたいなもの
  namespace: default
spec:
  type: ExternalName
  externalName: api.slack.com  # <--- 実際の名前解決先はこっち
```

実際に pod から名前解決をしてみた例

```rb
# host slack
slack.default.svc.cluster.local is an alias for api.slack.com.

# host slack.default.svc.cluster.local
slack.default.svc.cluster.local is an alias for api.slack.com.
```

### Beta 環境 の例
Beta環境では `https://slack` 宛のリクエストが `mock.internal.example.com` に行くようにします。

```yml
apiVersion: v1
kind: Service
metadata:
  name: slack 
  namespace: default
spec:
  type: ExternalName
  externalName: mock.internal.example.com   # <-- 
```

### Production 環境 の例
productionでは `https://slack` 宛のリクエストが本当のslack APIに行くようにします。

```yml
apiVersion: v1
kind: Service
metadata:
  name: slack 
  namespace: default
spec:
  type: ExternalName
  externalName: api.slack.com   # <-- 
```

このようにすれば、beta/prod どちらも共通のapplicationコードで、違う API にアクセスさせることができます。便利！

# ExternalName って使った方がいいの？
この利用シーンであれば、個人的には使わない方がいいと思います。同僚も production で使っている例は知らないそうです。

Pros
1. beta/prod で向き先間違えてました！てへっ。がなくなる

Cons
1. application log の debug が困難（どこに名前解決したかわからない）
1. HTTP request の Host header がおかしくなる

特に後者が気になります。TLS であれば SNI である程度は proxy なども反応してくれますが、相手の実装次第でルーティングされなくなることも大いに考えられます。動いているシステムをわざわざ ExternalName に変更する利点は少ないでしょう。

# もっと便利なシーンを知りたい

もちろん、これ以外の用途で便利なシーンがあると思います。ご存知の方はぜひコメントなりで教えてください！

----

追伸

同僚さん Thank you!
論文紹介：GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers

# 紹介する論文[^1]

https://arxiv.org/abs/2210.17323

タイトル: GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers
学会: ICLR2023

GPTQは大規模言語モデル向けの量子化方法です。
Llama2-13bのような、パラメータ数が数十Billionクラスのモデルの4bit量子化や3bit量子化に使われているPost-trainingの量子化方法です。
数百Billion級のモデルを3、4bit量子化する方法は初と主張しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/18cfa05b-153a-36a1-5dae-1a2f77c7ac94.png)

[^1]: 画像や数式は論文から引用しています。


# LLMにOptimal Brain Quantiationを適用する

GPTQの基本的なアイデアは、LLMに[Optimal Brain Quantization (OBQ)](https://qiita.com/kyad/items/da3e2b9059ccaa221795)による量子化を適用するというものです。
しかし、パラメータ数が数Billionクラスになると、単にOBQを適用するだけでは精度が落ちると指摘しています。OBQの終盤で大きな誤差を補正する必要があるため、補正が困難になります。反復計算で得られるヘッセ行列の逆行列が正定値でなくなり、数値的に不安定になるそうです。
本論文では、LLMにOBQを適用する際の数値不安定性を解決しつつ、高速化する方法を提案しています。


# パラメータの更新順序

OBSやOBQでは、量子化誤差が最小になるパラメータから貪欲に更新パラメータを選択していました。しかしこの順序であることは必ずしも必須ではないです。GPTQではパラメータを添え字の小さい方から順に量子化しています。


#  バッチ化

Lazy Batch-Update (遅延バッチ化) ではメモリボトルネックを解消することで高速化します。ヘッセ行列の逆行列や重み行列の補正を1列ずつ行うのではなく、$B=128$個まとめて行うことによってメモリ効率を上げます。


# Cholesky  Reformulation

一般に、正定値行列$A$は、下三角行列$L$を用いて$A=LL^T$と分解することができます。これを[コレスキー(Cholesky)分解](https://ja.wikipedia.org/wiki/コレスキー分解)と呼びます。

GPTQの話に戻ります、GPTQでは、精度劣化の問題に対して、Cholesky Reformulationで数値不安定性を解決することを提案しています。
**OBSのヘッセ行列の逆行列の更新式は、よく見ると[コレスキー分解の更新式](https://ja.wikipedia.org/wiki/コレスキー分解#アルゴリズムの例)と似ています**。これを用いると、コレスキー分解のソルバーを使ってヘッセ行列の逆行列を更新できます。[LAPACKのコレスキー分解ルーチン](https://www.netlib.org/lapack/explore-html-3.6.1/d1/d7a/group__double_p_ocomputational_ga2f55f604a6003d03b5cd4a0adcfb74d6.html)などを使って計算すれば、数値安定に計算できるという訳です。


# 評価

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/2c67f699-9d2d-f877-d3e8-de08eafe067f.png)

Table 1 はResNetによる画像認識タスクで評価しています。GPTQがAdaRoundやAdaQuantといった量子化方法と同程度であることが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/9b9803a3-d027-fbd5-5d11-5d0bb64c7b36.png)


Table 3ではLLMによる言語処理タスクで比較しています。GPTQは3bitや4bitでも数十〜数百Billionパラメータのモデルを量子化しても精度劣化が小さいことが確認できます。
LaravelのBladeでTailwindCSSのクラス名を動的に変更できるようにしたらCSSが効かない

タイトルがかなり長くなってしまいましたが...

TailwindCSSのクラス名をBladeの変数で動的に出し分けしたときに、クラス名のCSSが効いてない！ということがあったので、解消方法をメモします。

結論からお話すると、tailwind.config.jsにsafelistとして該当のクラス名を追加するだけです。

```javascript:tailwind.config.js
module.exports = {

    // 他の設定
    
    safelist: [
        'bg-red-500',
        'bg-yellow-500',
        'bg-gray-400',
    ],
}
```

bladeではcontrollerから`$statusBgColors`という変数を渡してもらって、動的にクラス名が変わるようにしてます。
下記の`{{$statusBgColors[$key]}}`の部分です。

```php
<td class="px-6 py-4 whitespace-nowrap text-center">
    <div class="text-sm text-gray-50 max-w-full w-20 py-1 {{$statusBgColors[$key]}}">
        {{ config('constants.billingStatus')[$invoice->status] }}
    </div>
</td>
```

これで無事に表示されるようになりました。