OmniAICreator/Qiita-1.07M huggingface dataset:
Former2でのセキュリティリスクを避けるために。


## はじめに

以前、社内のAWSのリソースをIac化しようとしてCloudFormationで使用したいなと思った時がありました。

その時にFormer2を使用し実際にIac形式に変換を行ってみました。

Former2は、既存のAWSリソースをInfrastructure as Code（IaC）形式に変換するためのツールです。このツールは以下の2つの方法で利用できます：

1. Webサイト版（https://former2.com)
2. ローカル環境での実行（GitHubからクローン）

## 利用可能な機能（公式情報）

### 対応出力形式(代表的なもの）
- CloudFormation（JSON/YAML）
- Terraform（HCL）
- AWS CDK　etc..


### 認証方法
Former2では以下の認証方法が利用可能です：
- AWS CLI認証情報
- AWS SSO
- AWS Access KeyとSecret Key

### 必要なIAM権限
スキャンするAWSリソースに対する読み取り権限（Describe/List/Get）が必要です。
※個人的な経験に基づきます。

**実際に触る際の諸注意**

- **ローカル環境のセットアップ**:（ローカルホスト以外では外部公開になるため）
- 
    - Githubからリポジトリをローカル環境にクローンし、`Docker-compose`で立ち上げて`localhost`で表示させてください。**注意**: `https`でアクセスすると、内部環境が外部に公開されるリスクがあるため、必ず`localhost`でのみアクセスしてください。※情報を漏洩防止の為
    
    コマンドはFormer2のディレクトリ配下に移動し
    `docker-compose up -d`で立ち上がります。
    
    - `Docker-compose`使用時にポート競合が発生する場合があります（デフォルトで80番ポートを使用）。その際、`docker-compose.yml`ファイルのポート番号を`8080`に変更してください。これにより、競合を回避し、環境が正常に立ち上がります。
    -
- **ローカル環境のイメージ**:
    - 下記のスクリーンショットは、ローカル環境が正常に動作している際の参考イメージです。

## ローカル環境での実行方法（ローカル環境で行う時にDockerにソースコードをcloneしました。）

```bash
git clone https://github.com/iann0036/former2.git
```

クローン後、`localhost`をブラウザで開いて使用しました。

## 個人の経験に基づく注意点

以下は、実際のユーザーの経験に基づく注意点です：

### 経験した課題
- 最初、間違えそうになり　ウェブサイト版（former2.com）でAWS認証情報を入力しようとして、セキュリティ上の懸念を感じた
- ローカル環境での実行方法を知らずに、不要なセキュリティリスクを負うところだった

### 学んだ教訓
- 本番環境の認証情報を扱う場合は、ローカル環境での実行を検討する
- AWS認証情報の取り扱いには十分な注意が必要

## リソースのスキャン手順

1. 実行環境の選択
   - ウェブサイト版、またはローカル環境（状況によります。）

2. 認証情報の設定
   - 利用可能な認証方法から選択

3. スキャンの実行
   - リージョンの選択
   - スキャンするリソースタイプの選択
   - スキャンの実行
   - 生成コードの確認

## 制限事項（公式情報）

- 一部のAWSリソースタイプはサポート外
- リソース間の依存関係は手動での確認が必要
- 生成されたコードは必ずレビューが必要

## リソーススキャン時の確認事項

1. スキャン前
   - 対象リソースの特定
   - 必要なIAM権限の確認
   - 実行環境の選択

2. スキャン後
   - 生成されたコードの確認
   - リソース間の依存関係の確認
   - 必要に応じたコードの修正

## まとめ

Former2は、既存のAWSリソースをコード化するための有用なツールです。利用の際は、特に以下の点に注意が必要です：

1. もし、使用するにしてもプライベートで使用するか、会社で使用する場合は会社の方針によってなので要相談になると思います。(基本的にはプライベートでの使用をお勧めしたいと思いました。）
2. AWS認証情報の適切な管理
3. 生成されたコードの確認とレビューしないと不要なコードも実際に含まれてました。
※不要なコードは手動で消す必要がありました。

## 参考情報
- Former2公式リポジトリ: https://github.com/iann0036/former2
- Former2ウェブサイト: https://former2.com/
【VB.Netの要注意点】DateAddの年(y)指定

VB6でも同じだったのですが、例えば 2020/1/1 の１年前の日付計算：

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim d1 As Date

        d1 = DateAdd("y", -1, #2020/1/1#)
        MsgBox("2000/1/1 -> " & d1.ToString, vbOKOnly)
        d1 = DateAdd("m", -12, #2020/1/1#)
        MsgBox("2000/1/1 -> " & d1.ToString, vbOKOnly)
    End Sub

下は、2019/01/01 ですが
上は、そうではありません。
きっちり１年間とするなら、"m"で 12 とし、
"y"は使うべきでないです。
知財のあれこれをPythonで何とかする

### クリップボードから必要な情報だけを抜き出してペーストする
例としてJ-platpatのOPDのページからJP,USの登録番号だけを抜き出してみます。
### (準備）
ライブラリをインストールする（pip install pyperclip）。
後述のProgram1をファイル名program1.pyで保存。

### (操作方法)
手順１．J-platpatで何かの特許番号を入力し「OPD」ボタンをクリックしOPDのファミリ表示ページを開く。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831931/a3488a82-376f-12bc-478c-dc0c37994e0e.png)
手順２．Ctrl+A(全選択)→Ctrl+C（コピー）でファミリ表示ページ内の全文字情報をクリップボードにとりこむ。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831931/1ade4ef6-0b98-c7bf-c4e5-ddea6995519a.png)

手順３．準備のステップで作成したProgram1.pyをダブルクリックして実行する。
（実行する前にクリップボードをクリアしないでください）
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831931/a1cb437d-bb0b-ebff-5dfe-77a7f76bc35c.png)

手順４．所望のアプリケーション（メモ帳やExcel）にペースト（Ctrl+V）する。

手順１．～４．を行うと、OPDのファミリ表示ページ内の文字列の内、JPとUSの登録番号だけがペーストできます。

(メモ帳にペーストした例)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831931/59f7c0d5-e666-9519-9a6f-71d8a8243f77.png)

プログラムは以下のようになります。
```python:Program1.py
import pyperclip
import re

# クリップボードから文字列を変数textに取り込む
text = pyperclip.paste()

# 不用な文字(改行、■）を削除
text = text.replace('\n', '').replace('\r', '').replace('■', '')

# JPとUSの登録番号を抽出
idg1='\r\n'.join(re.findall("JP.[0-9]{7}.B[1-2]", text))
idg2='\r\n'.join(re.findall("US.[0-9]{7,8}.B[1-2]", text))
idg3='\r\n'.join(re.findall("US.RE[0-9]{5}.E", text))

# 不用な文字（.）を削除する
text2=""
for idg in [idg1, idg2, idg3]:
    idg = idg.replace('.', '')
    text2=text2+idg+'\r\n'

# クリップボードにはりつけ
pyperclip.copy(text2)
```
### プログラムのポイント
今回のプログラムではpythonの機能のうち
クリップボードから文字列を取り込む→　`text = pyperclip.paste()`
文字列をクリップボードにはりつける→　`pyperclip.copy(text2)`
を利用しています。


### 応用
EPやCNを抽出したい場合以下のコマンドを追加してください。
```python:Program2.py
idg4='\r\n'.join(re.findall("EP.[0-9]{7}.B[1-2]", text))
idg5='\r\n'.join(re.findall("CN.[0-9]{9}.[BC]", text))
```
以下の行は書き換えが必要です
`for idg in [idg1, idg2, idg3]:`→`for idg in [idg1, idg2, idg3, idg4, idg5]:`

### 最後に
知財業務の省力化にあたりPythonとVBAのどちらでも実現できることは多いと思います。PythonにできてVBAでできないことは何だろう？と考えていたら、キー操作に関する部分はPythonしかできないのでは思い、コピペ作業の省力化を思いつきました。
（後で調べたらVBAでも可能なようですがかなり手順が多い模様。）
今回の記事が何らかの助けになれば幸いです。
[writeup] Crate-CTF (OSINTカテゴリ)

# はじめに
ITソルーション室 Advent Calendar 2024　8日目の投稿です。
静岡大学情報学部のITソルーション室で2024年度副室長を務めているaraakiです。よろしくお願いします。
今回は、11/16に開催された、FOI(スウェーデン国防研究所)主催の「Crate-CTF」に、teappというチームとして参加してきましたので、OSINTカテゴリで自分が解いた問題のwriteupを書かせていただきます。チームとしての順位は13位で、個人としてもOSINTカテゴリを全完答する事ができました。
<img src= "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824089/9531ba69-e8a4-5e93-2ea4-975d6a50aa6e.png" width=300>

# 1問目 HittaHit1
geosintですね、リンク先のWebページにある写真があるので、その写真が撮られた場所を見つけます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824089/7ba672b2-d690-147d-f0a5-6cc6ffa0b0e5.png
">
写真には、現在地から各都市への距離が書いてある看板が書いてあるので、左に行ったらBRASTAD、右に行けばLYSEKILに行けるような交差点をgoogle mapsなどで探します。
そして、見つけたらそこの十進法座標をサイトのフォームに入力すると、画像のようにアウトプットが返ってくるのでそれがflagです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824089/dcc5c786-9585-09f2-ebd3-f5afedfb771e.png">

# 2問目 HittaHit2
1問目にて見つけた家の前の所有者に関係する自動車関連会社を見つけるというものです。こちら、土地の売買に関して扱っている記事から、前の所有者については比較的すぐ見つける事ができたのですが、その人物が関係している自動車関連会社をなかなか見つける事ができませんでした。少し諦めかけていた中、気分転換のつもりで検索エンジンをGoogleからYandexに変更したところ、すぐに見つける事ができました。すごいなYandex。東欧の情報の検索に関しては重宝していましたが、北欧についてもこれからはYandexを使うようにしていきたいと思いました。

# 3問目 intern2
ossian wallengrenという人物の名前が与えられ、その人物のWebサーバーにアクセスし、Flagを取ってくるという問題です。まず見つけられたのが[LinkedInアカウント](https://www.linkedin.com/in/ossian-wallengren/?originalSubdomain=se)、それなりに運用された形跡はありましたが、クリティカルな情報は見つかりませんでした。
もう少し探してみると、[GitHubアカウント](https://github.com/ossianwallengren)がありました。そこにWebページのリポジトリがあったので、そこのdeploy.ymlなどからアドレスを特定し、Webページにアクセスしました。そこにブログがあったので一通り読んでいると、どうやら間違えてWebサーバーの秘密鍵をGitHubにpushしてしまったので、force pushで履歴を書き換えたようです。そのコミットのハッシュ値はそのブログの画像に載っていたので、GitHubのreflogを見たところ、秘密鍵を見つける事ができました。そしてこの秘密鍵と、これもリポジトリにあったホスト名とドメインを使ってSSHすることでWebサーバーへの接続に成功し、そこにあったflag.txtがflagでした。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824089/d618a1fd-818e-6386-25a8-228668c8836c.png
">

# 最後に
今回が4回目のCTFで、writeupを書くのはこれが初めてなので、少し読みにくい部分もあったと思います。最後までお読みいただきありがとうございました。
Development Tools

[Previous << Snapshot Save](https://qiita.com/flowcadence/items/520a80cf91f305407954)
[Next >> Dependency Manager](https://qiita.com/flowcadence/items/9195f9872874baab611e)

https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a#flow-cli-と-fcl

Flow CLIは、さまざまな開発ツールを統合し、それらを1つの場所から簡単に起動および管理できるようにしています。

現在、CLIは以下の起動をサポートしています。
* [Flow Development Wallet](https://github.com/onflow/fcl-dev-wallet)

<h1>Flow Development Wallet</h1>

Flow Dev Walletは、シミュレートされたユーザーアカウントに代わって、Flowブロックチェーンとやりとりするために、FCLによって使用されるプロトコルをシミュレートするFlowのモックウォレットです。

**このコマンドを実行する前に、エミュレーターが起動していることを確認してください。** *エミュレータは`flow emulator`コマンドを使用して起動できます。*
```ruby
flow dev-wallet
```
*⚠️ このプロジェクトはFCL対応インターフェースを実装していますが、実稼働環境のウォレットを構築する際の参考として使用すべきではありません。*

dev-walletを起動した後、以下のようにfcl configを設定することでこれを使用することができます。

```ruby
import * as fcl from "@onflow/fcl"

fcl.config()
  /* Point App at Emulator */
  .put("accessNode.api", "http://localhost:8080") 
  /* Point FCL at dev-wallet (default port) */
  .put("discovery.wallet", "http://localhost:8701/fcl/authn")
```
dev-walletの設定については、[Flow Dev Wallet Project](https://github.com/onflow/fcl-dev-wallet)で詳しく説明されています。

<h1>Flags</h1>

<h3>Port</h3>

* Flag: `--port`
* Valid inputs: Number
* Default: `8701`

dev walletのサーバーがリッスンするポート。

<h3>Emulator Host</h3>

* Flag: `--emulator-host`
* Valid inputs: a hostname
* Default: `http://localhost:8080`

dev wallet用のホストの設定を指定します。

<h3>Configuration</h3>

* Flag: `--config-path`
* Short Flag: `-f`
* Valid inputs: valid filename

設定ファイルのファイル名を指定します。`-f` フラグを複数回使用して複数のコンフィグレーションファイルをマージすることもできます。

<h3>Version Check</h3>

* Flag: `--skip-version-check`
* Default: `false`

低速な接続を避けて処理を高速化するために、起動時のバージョンチェックをスキップします。

*Last updated on **Nov 26, 2024** by **Giovanni Sanchez***

翻訳元

https://developers.flow.com/tools/flow-cli/utils/tools

***
<b>[Previous << Snapshot Save](https://qiita.com/flowcadence/items/520a80cf91f305407954)
</b>

[Flow blockchain / Cadence version1.0ドキュメント](https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a) (Development Tools)

<b>[Next >> Dependency Manager](https://qiita.com/flowcadence/items/9195f9872874baab611e)</b>
8番出口の赤い水の制作事例

# はじめに
[Unreal Engine (UE) Advent Calendar](https://qiita.com/advent-calendar/2024/ue) 2024の10日目の記事です。

KOTAKE CREATEという名義で「8番出口」などをリリースしているコタケと申します。
今回の記事は「8番出口」の通路の奥から流れてくる、赤い水のような異変の制作事例です。
すべて解説するのが難しかったり、忘れている所もあった為、
一部割愛しています。あらかじめご了承ください。
UEのバージョンはUE5.3です。

### 赤い水について
・触れるとゲームオーバーになる
・通路の奥から流れてくる

参考動画
![Exit8 - Unreal Editor 2024-12-08 11-48-16 - Trim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925809/ad2eba1a-d7d3-121f-ddf6-cbf3fd115109.gif)


# 作り方
現在のUE5にはNiagara Fluidsなどのリアルな流体の描写の出来る物があったりしますが、
扱うのが難しそうだったのと、そこまでリアルな表現が必要という訳ではなかったので
今回はスタティックメッシュをマテリアルで変形させるシンプルな方法を選択しました。



# スタティックメッシュの作成
水が流れてくるように見せる為に、メッシュの始点から終点まで、0から1の値を持ったスタティックメッシュが必要になります。

マテリアルで使うための値を持たせるには、UV、頂点カラー、テクスチャなどがありますが、今回はUVの値を使用します。


メッシュの作成にはUEの機能の1つであるGeometry Scriptを使用しました。
Append Sweep Polylineというノードが、
Polyline Verticesを伸ばすような形で、Sweep Pathに沿ってメッシュを作成してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925809/33c5918c-0b4b-d6e4-5076-c312e1831c12.png)



Append Sweep PolylineとPolyline Verticesのノード
Polyline Verticesは分割数のパラメータ(Division)に応じてSplineのTransformを取得しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925809/40d79208-8144-851a-87ed-e83ce42578be.png)



Append Sweep Polylineで作成したメッシュは
最初からUVのグラデーションが始点から終点まで出来ていたのでこのまま使用しました。
(曲がり角でメッシュが重なっていますが、今回は許容しました)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925809/e23fed2a-6e1b-080a-e3ab-cfbbadb961a7.png)





# マテリアルの作成
一から水のマテリアルを作るのは時間がかかりそうだったので、マケプレ(現在はFab)にあったマテリアルを改造しました。

#### Water Materials
https://www.fab.com/ja/listings/063155ea-d9d2-4f29-b09f-33270b0bc861


#### 改造
ワールドポジションオフセットで最初は通路の下にメッシュを隠しておき、
奥の部分からメッシュが元の位置に戻るようなノードを組みます。

![Exit8 - Unreal Editor 2024-12-08 12-41-37 - Trim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925809/0ec689b3-0bfb-49ba-39ac-e5c3c5ac11d4.gif)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925809/dc53ee8b-14b0-47c7-04fd-21bb892787e2.png)



また、PixelDepthOffsetを使って床との接触部分があまり目立たないようにしていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925809/640b6551-a038-1528-dd63-9d929b5b08e2.png)


# コリジョン、マテリアルパラメーターの制御
水に触れるとゲームオーバーにさせるため、
マテリアルの動きと合わせてコリジョンも移動させています。
(Timeline Lerp Floatは自作マクロです。普通のタイムラインでも可能だと思います。)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925809/1090c01d-30c5-233e-4771-77965ae4c24e.png)




# カメラシェイク
水に流されてるように見せるため、カメラシェイクを付けています。
また、より流されたように見せるために
プレイヤーをコリジョンにアタッチしてそのまま移動させたりもしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925809/4ce3e5c3-5f89-17e6-2341-f01fa6eab3b4.png)

カメラシェイクのパラメータ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925809/6cc0de7c-3fa0-1d4f-500e-93b5fa3e2d40.png)




# おわりに
今回の通路のような限定的な状況でしか使えない手法な為、あまり他に活かせたいかもしれませんが、何かの参考になれば幸いです。

実は今年のIndie Developers Conferenceで講演させていただいた時も赤い水の製作事例について少し触れたのですが、こういった特殊表現に関する記事や講演が好きなので、もう少し詳しく解説した物を書きたくなりました。
新作をリリースした時などにでも、また別の表現の記事が書ければなと思います。
最後までお読みいただきありがとうございました。
wlx202でRADIUS認証設定

〇やりたいこと
wlx202でRADIUS認証設定

以下の通りに実施。すごい簡単だった。
https://www.rtpro.yamaha.co.jp/AP/docs/wlx202/radiusd/
ただし、簡易設定なので証明書で認証しない。
引用----------------------
注意事項
接続時に本機能の提示するサーバー証明書を無線端末側では検証することができません。
無線端末側ではサーバー証明書を検証しないよう設定して運用してください
引用----------------------
ユーザー証明書発行して端末にインストールしてとかやらなくていい。
会社の従業員用の無線なら、RADIUS認証あると無線の管理らくだよね。
無線接続させたくない端末の認証情報けすだけでいいし。
引用----------------------
複数のアクセスポイントを使う構成でも、無線端末の認証設定をRADIUSサーバーに集中することができる
同じく無線端末の接続/切断履歴をRADIUSサーバーに集中することができる
PSKを用いる認証方式に比べ、ユーザーID毎の細かい接続管理ができる
特定のユーザーIDに対する端末 MACアドレスを限定することができる
特定のユーザーIDに対する接続先SSIDを限定することができる
引用----------------------

WLX222などは簡易じゃない認証ができるらしい
https://www.rtpro.yamaha.co.jp/AP/docs/wlx222/radiusd.html#%E6%80%A7%E8%83%BD
NetAtTestとかいらなくなるね。
でもYNO使ってるとRADIUS認証使えない。
引用----------------------
クラウドを使用して管理している場合、証明書発行機能は利用できません。
引用----------------------
Twitter投稿とQiitaの記事、いいね数に相関はあるのか？──検証の結果、ほぼナシ


## はじめに

Qiitaで記事を投稿すると、Twitterでもシェアすることが多いです。では、「Qiitaでのいいね数」と「Twitterでのいいね数」には、どれほどの相関があるのでしょうか？

本記事では、2024年12月03日時点で取得したデータを用いて、Qiita記事のいいね数と、同記事をシェアしたTwitter投稿のいいね数を比較し、相関分析を行います。

**留意事項：**

- 記事によって公開からの経過日数が異なり、同条件での比較は困難です。
- 本記事で扱うのは「いいね数」のみであり、Twitterのリツイート数やQiitaのストック数などは対象外です。

## 使用データと手順

### データ概要

- `tweets.csv`:  
  Twitterでシェアした記事タイトルと、その際のツイートいいね数が記録されたCSV。

https://qiita.com/Isaka-code/items/8872740c13e8fc4156dc


- `qiita_articles.csv`:  
  Qiita上での記事タイトルといいね数が記録されたCSV。

https://qiita.com/Isaka-code/items/9e52767e85c2247570b5


これら2つのCSVを「記事タイトル」で紐付け、対応する記事ごとに「Qiitaいいね数」と「Twitterいいね数」を取得します。

### データ分析に用いたソースコード

```python
import pandas as pd
import plotly.express as px

# データ読み込み（サンプル）
qiita_df = pd.read_csv('qiita_articles.csv')
tweets_df = pd.read_csv('tweets.csv')

qiita_df = qiita_df[['タイトル','いいね数']].rename(columns={'いいね数': 'Qiita_likes'})
tweets_df = tweets_df[['記事タイトル','いいね数']].rename(columns={'いいね数': 'Twitter_likes'})

merged_df = pd.merge(qiita_df, tweets_df, left_on='タイトル', right_on='記事タイトル', how='inner')

fig = px.scatter(
    merged_df,
    x='Twitter_likes',
    y='Qiita_likes',
    hover_data=['タイトル'],
    title='Twitter Likes vs Qiita Likes'
)

# Annotationsを追加
for i, row in merged_df.iterrows():
    fig.add_annotation(
        x=row['Twitter_likes'],
        y=row['Qiita_likes'],
        text=row['タイトル'],
        showarrow=False,
        textangle=-45,        # テキストを45度回転
        xanchor='left',      # 配置調整は適宜
        yanchor='bottom',
        xshift=5,            # 点から少しずらすなど微調整
        yshift=5,
    )

fig.update_layout(
    xaxis_title='Twitterいいね数',
    yaxis_title='Qiitaいいね数',
    hovermode='closest'
)

fig.show()

# 相関係数の計算
corr = merged_df['Twitter_likes'].corr(merged_df['Qiita_likes'], method='pearson')
print(f"ピアソンの相関係数: {corr:.2f}")
```

上記コードを実行すると、  
- 散布図が表示され、Qiitaいいね数(y軸)とTwitterいいね数(x軸)の分布が可視化されます。
- `corr`で相関係数(ピアソン相関)が算出されます。

## 結果と考察

![tweet-qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627015/169c9634-c047-c2c0-c001-3847a4ed0753.png)


```bash
ピアソンの相関係数: 0.04
```

- 算出された相関係数は約0.04で、「ほぼ相関がない」ことが分かります。つまり、Twitterで多数のいいねが得られた記事が、必ずしもQiitaでも同程度に評価されるわけではなく、その逆も成立しません。

**プラットフォーム間の差異について**

- **読者層の違い**：Qiitaは幅広いITエンジニアを対象としており、技術的に汎用的なテーマが受けやすい傾向があります。たとえば[「ポケポケに登場する確率分布」](https://qiita.com/Isaka-code/items/bbca509d857925c3669a)はQiitaで非常に高い反響を得ましたが、Twitter上では相対的に控えめとなりました。
- **関心分野の偏り**：筆者のTwitterアカウント（[@ねぼすけAI](https://x.com/AInebosuke)）はAI分野に関心を持つフォロワーさんが多く、AI関連の記事（例：[Optunaを用いたプロンプトエンジニアリング](https://qiita.com/Isaka-code/items/7c13652b416d9ee56585)、[LLMコンペの取り組み方など](https://qiita.com/Isaka-code/items/82e73fb6e77ac62a2287)）がTwitterでいいねが多い傾向があります。しかし、これらのAI関連記事はQiita上で必ずしも同様の評価につながるとは限りません。
- **その他の要因**：記事の公開時期や拡散チャネルの違い、Qiitaアカウント未ログインでいいねが押せない仕様なども、両プラットフォーム間での評価差に影響していると考えられます。

## まとめ

今回の分析から言えることは、「Twitterいいね数」と「Qiitaいいね数」の間に相関は見られず、ほぼ独立していると言えます。これは、プラットフォームごとに読者層や関心分野が異なることが大きな要因と考えられます。

いいね数はあくまで参考指標の一つであり、それ自体に一喜一憂する必要はありません。今後も、読者の方にとって価値ある記事を投稿できるように心がけたいと思います。
俺流、新しいライブラリのキャッチアップ手順

# はじめに
研究室に配属されて3年目になり，教える立場になることが増えてきました．その中で，どのように技術的なキャッチアップをしているか，ということを聞かれたのですが，無意識にできるようになってきた部分も大きく，うまく言語化できませんでした．
少し時間ができたので，この部分を言語化してまとめてみようと思います．

今回は，ライブラリのキャッチアップ手順に焦点を当てたいと思います．技術的なキャッチアップにはいくつかのフェーズがあると思いますが，それら全てについて述べようとすると中途半端になると考えられるためです．

また，私の普段利用している言語はPython & 他の言語も必要に応じて使うといった感じなので，言語によっては状況が異なるかもしれません．


# 対象
本記事では以下の人に向けた記事となります．

:::note
- 実現したいことが決まっている
- ライブラリの仕様を理解して比較検討したい
:::

翻って，以下の人には向かない記事です．

:::note alert
- 何か便利なライブラリを知りたい
- とにかく動くことを目指して実装したい
:::

また，「はじめに」にもあったように，「もし後輩にどのようにすればライブラリを使いこなせるようになるか，と訊かれたら」という前提で書いており，あくまで個人的な意見であることはご承知おき下さい．


# 1. 公式ドキュメントを確認する
まずは何と言ってもこれです．公式ドキュメントです．ただし，もちろん技術ブログにも良い点があるのは断っておきます．（後ほど言及します）

しつこく言いますが「ライブラリを使いこなせるようになりたい！」と考えるのであれば，絶対に公式ドキュメントを読んで下さい．
何故ここまでおススメするかというと，「最新の」「正確な」情報を手に入れるのに最適だからです．（もちろん，最新で正確でない公式ドキュメントもありますが，その数は少ないと思います）
ライブラリの中には指定通りの使い方をしなければ，一見動いているように見えて意図した動作に実はなっていないというものもあります．
そうした事態を避けるためにも1次情報を参照するべきです．

公式ドキュメント読むように言うと，こんな意見も耳にします．

- 公式ドキュメントを読むにはスキルが足りないから
  + その言語を読むことができれば十分です
  + 心理的なハードルを超えさえすれば簡単に読めます
- 公式ドキュメントは長くて……
  + 昔はどうだったか分かりませんが，少なくとも最近はQuick Startやそれに類する項目が用意されています
  + 文章量だけで見ればブログよりも短いことも多いです
- 英語が……
  + 翻訳ツールを使って下さい
  + （私の場合は）段々と英語のまま読めるようになります

1つ1つクリアしていけば，思っているほどは難しくないはずです．

最後に，公式ドキュメントを読む時のちょっとした注意点ですが，自身で利用している環境でのライブラリのバージョンはしっかり確認しておきたいです．（n敗）


# 2. 実装してみる
ドキュメントやブログを読むだけで満足する人も多いですが，使いこなしたければ実装しながら理解を進めるべきだと考えています．
というのも，理解が間違っていた場合に修正が容易であるだけでなく，環境依存のエラーが発生した場合の対処ができるようになるという利点もあります．

また，ライブラリ自体が抱えるバグに気づくこともあります．ある機能が達成したいことに必要なのに，そのライブラリではバグを解決できていない……（これにある程度実装を進めてから気付くと悲惨なことに……）


# 3. 実装例を確認する
先に公式ドキュメントがどうとか強調をしていましたが，実装例を確認するのは同様に重要な作業です．
ブログやLLMを活用することで，公式ドキュメントだけでは分からなかった活用方法や効率的な実装方法を知ることができます．

英語の学習に例えるなら，公式ドキュメントは単語や英文法を学び，ブログは英会話を学ぶという感じでしょうか．どちらが欠けても上手くはならない，そんな感じで捉えています．


# 4. アウトプットする
最後に，アウトプットの機会を作って下さい．本当にどんなものでも良いです．
例えば，チームメンバに学んだことを共有するであったり，ブログを書いてみるであったり，何か動くものを作ってみるであったり．ハードルは少し高いかもしれませんが，アウトプットをした後の理解度は，しない場合と比べて大きく変わっているはずです．


# 最後に
いかがでしたでしょうか？
考えているところをそのままに書き出してみましたが，共感いただけるところもあれば，そうでないところも多かったと思います．
あくまで，一個人の意見と思って頂ければ．
【ChatGPT】逆算的未来思考と戦略的思考を組み合わせたPromptの紹介です。


　どうも、カーブミラーです。

　今回は、逆算的未来思考と戦略的思考を組み合わせたPromptの紹介です。

:::note info
本記事は、ChatGPT（Plus版）
で行なっております。画像は
ありません。　あしからず。
:::
　ChatGPT等の動作状況を知らせる
　　OpenAIのステータスページ。
　　　[OpenAIステータス](https://status.openai.com/)

***
　最初に

　今日明日は、
　　OpenAIのクリスマスイベントが
　　　お休みです。

　OpenAIのクリスマスイベントの
　　第三日目は、月曜日10時になります
　　　これ、アメリカ時間でです。
　　　　日本時間、火曜日3時です。

　なお、初日（2024/12/06）と
　　昨日（2024/12/07）の
　　　ライブ録画映像がTikTokに
　　　　アップされています。

　[一日目](https://vt.tiktok.com/ZSj37TMuJ/)
　　主に、OpenAI o1の実演。

　[二日目](https://vt.tiktok.com/ZSj37tWPa/)
　　強化ファインチューニングの実演。

　あと、新しいSora映像も。
　　[Sora映像](https://vt.tiktok.com/ZSj37sTtQ/)

　　　これ、昔の原宿みたい😅
***
　では、ニュース。

　先日、お知らせしました
　　X-TwitterでGrokが
　　　無料版ユーザーに
　　　　開放された件ですが、
　　　　　制限があるようです。
　　　　　　当然ですね😅

　Taiyoさんのポストから
　　そのまま、引用します。
　　　[Taiyoさんポスト](https://x.com/taiyo_ai_gakuse/status/1865291190666694729?t=V1EQVQM53Bvlz7QGI-12Jg&s=19)
>アカウントの条件がいくつかある模様👇️
>
>アカウント条件:
>・Xアカウントが1週間以上経過している必要がある。
>・電話番号の登録が必要。
>
>チャット制限:
>・2時間で10メッセージまで。
>
>画像分析の制限:
>・1日に3回まで。

　また、画像生成にも
　　制限があるようです。

　それから
　　こちらはニュースです。

　X-TwitterのGrokに、
　　最新鋭のAI画像生成機能
　　　「Aurora」を組み込んだと発表。
　　　　[XenoSpectrum記事](https://xenospectrum.com/x-integrates-aurora-its-latest-ai-image-generator-into-the-grok-assistant/)

　無料版利用者である私も
　　ちょっと画像生成できました。
　　　女性を描いてもらったんですが、
　　　　きれいでした。
　　　　　スクショもダウンロードも
　　　　　　してませんでした😅

　残念ながら、
　　現在はFlux (Beta)に
　　　なっています。
　　　　あれ、Flux .1だったよね？
***
　OpenAIのクリスマスイベントの
　　第三日目は火曜日になります。
　　　まぁ、日・月くらいは
　　　　休みましょう。

　ということで、
　　OpenAI o1を使った感想を、と
　　　言いたいところですが、
　　　　まわりはみんなo1 Proの
　　　　　ことに夢中です😅

　まぁ、
　　o1（無印）を試した感じは、
　　　思考時間が短くなったのと
　　　　ハルシネーションは
　　　　　やっぱり起こるということ。
　　　　　　くらいかなぁ😸

　　o1 Proは、
　　　ハルシネーション減ってる
　　　　そうですよ。
***
　ChatGPTスマホアプリですが、
　　o1の思考過程が見れなかったのが
　　　見れるようになりました。
　　　　ただし、1秒レベルだと
　　　　　見るものがないようで
　　　　　　見れません。

　スマホでのWeb版は、
　　ブラウザ設定を
　　　PC版サイトにすれば
　　　　見れます。
***
　それからこちらも
　　ChatGPTスマホアプリですが、
　　　入力枠での入力に
　　　　Canvasウィンドウが出るように
　　　　　なっていましたが、
　　　　　　編集ではダメでした。

　　それが編集時も
　　　Canvasウィンドウが
　　　　出てくるようになりました👍
***
　さて、【本題】です。

　今回は、
　　逆算的未来思考と戦略的思考を
　　　組み合わせたPromptの紹介です。

　ポストされた木内翔大さんによると
　　これにより、
　　　計画立案能力が飛躍的に向上し、
　　　　日々の課題解決や
　　　　　プロジェクト計画にも
　　　　　　応用可能になるそうです。
　　　　　　　[木内翔大さんポスト](https://x.com/shota7180/status/1865539745599599034?t=6Pji-r91-rT_p978W-bwDg&s=19)

　提示されたPromptがこちら。
　　＊＊＊に考えて欲しいことを
　　　記述して送信してください。
```Text:逆算的未来思考と戦略的思考Prompt
逆算的未来思考と戦略的思考を用いて「＊＊＊」について考えて
```

　これを実行すると

　・目標の設定
　・目標から逆算
　・戦略的思考
　・今後の拡張性

　という感じの出力が得られます。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
[Next.js15][Mac]npmを使ってnext.js15をインストールする方法とローカルサーバーを立ち上げる方法[超初心者向け]

## 内容

npmを使った、Next.js（最新版）のインストール方法とローカルサーバーを立ち上げる方法

## 対象
- 初めてNext.jsを触る人
- プログラミング初心者さん

## 得られる知識
- Next.jsをインストールして、パッケージファイルを作成できるようになる。
- Next.jsのローカルサーバーを立ち上げることができる。

## 筆者の環境仕様
'24/12/7 現在
|カテゴリ|技術|
|----|----|
|PC|Mac M1|
|OS|macOS Sequoia 15.1.1|
|node.js|version 10.8.2|
|next.js|version 15.0.4|
|Text editor|Wind Surf|

## 手順
1. node.jsをインストール
2. ターミナルでディレクトリを作成する
3. next.jsをインストールする
4. エディタを立ち上げる
5. ローカルホストを立ち上げる
6. 表示されるので、ローカルホストを閉じる。
7. 結論

### 1. node.jsをインストール
主にJavascript周りを初めて触る方だと思いますが、過去にnode.jsを使ったことない方はインストールから始めてください。

インストールできているかの確認の方法

```
$ npm -v //ここを入力
10.8.2　//結果
```

https://nodejs.org/en/

### 2. ターミナルでディレクトリを作成
デスクトップ上などで作ってもらっても構いませんが、慣れるとターミナルの方が早いのでこちらを採用しています。

```
$ mkdir sampledev
$ cd sampledev
```

### 3. next.jsをインストールする

ここでは、先ほど作成した、sampledevというファイルの中にnext.jsをインストールしていきたいと思います。

```
$ sampledev % npx create-next-app@latest　　//ここを入力
Need to install the following packages:
create-next-app@15.0.4
Ok to proceed? (y) y //Yesという意味のyを入力

✔ What is your project named? … .　//"."と入力することでディレクトリ直下に作成できます
✔ Would you like to use TypeScript? … Yes
✔ Would you like to use ESLint? … Yes
✔ Would you like to use Tailwind CSS? … Yes
✔ Would you like your code inside a `src/` directory? … Yes
✔ Would you like to use App Router? (recommended) … Yes
✔ Would you like to use Turbopack for next dev? … Yes
✔ Would you like to customize the import alias (@/* by default)? … Yes
✔ What import alias would you like configured? … @/*

```

質問を数点聞かれますが、細かい仕様のカスタマイズなので、今回のは説明を割愛します。
とりあえず全部yesでもnoでも大丈夫です。（そのうち別記事で書くかもしれません。）

ここでよくあるミスは、npxをnpmと書きまちがるところです。確認してみてください。

### 4.エディタで立ち上げる
コマンド設定がしてある方はターミナルからそのまま立ち上げてもらっても構いません。

例:Wind Surfで立ち上げる場合

```
$ sampledev % windsurf .
```

設定していない方は通常通り、VScodeやCursorなどのテキストエディタをデスクトップ等から開いてください。

立ち上がったら、上のバーから"ターミナル"を選択して、ターミナルを立ち上げてください。

### 5.ローカルホストを立ち上げる

![](https://storage.googleapis.com/zenn-user-upload/7d401fe03129-20241208.png)

そのあと、ターミナルで`npm run dev`と入力してもらうと、ローカルサーバーが立ち上がります。

```
$ sampledev % npm run dev
```

自分の場合ですと、ローカルホスト3000番に立ち上がったようなので、Chromeで開いていきます。

![](https://storage.googleapis.com/zenn-user-upload/16a4e5bc15c2-20241208.png)

このように、デフォルトでNext.jsのページが開けば完了です。

### 6.表示されるので、ローカルホストを閉じる。

基本的には、動作確認をしたらローカルホストは閉じた方がいいです。

理由としては、動作でメモリを食うので、他の作業に支障が出る場合があるからです。

今後Dockerでクラウド上のコンテナを生成したり、動画をアップロードしたりなど、メモリをシビアに使う状況で生きてくることがありますので、癖にしておくことをオススメします。

閉じ方としては、ターミナルを落とすか、`control+c`で落とすことができます。

## 結論
Next.jsのファイルをインストールして、ローカルサーバーを立ち上げることができた。

Next.jsのプログラミングやデバックをする際は必ず触るルーティンになりますので、覚えておきましょう。
【Python】nameとvalueからEnumを取得する

## 概要
Pythonにて指定した値でEnumを取得する場合、nameとvalueの双方から可能です。基本的には[Convert string to Enum in Python](https://stackoverflow.com/questions/41407414/convert-string-to-enum-in-python/76834370#76834370)のstackoverflowの回答に書いてある通りですが、実際に動かしてみたのでメモ書きを残しておきます。

## 前提
* 使用したPythonのバージョンは`3.13.0`です。

## 実装サンプル
まずは以下の通り、Enumを用意します。

```python
from enum import Enum


class SampleEnum(Enum):
    Key1 = "value1"
    Key2 = "value2"
    Key3 = "value3"
```

nameから取得する際の実装です。以下の通り`[]`で取得したいnameを指定します。なお、存在しないnameを指定した場合は`KeyError`が発生します。

```python
# nameからenumを取得
enum = SampleEnum["Key1"]

# これはKeyError
# enum = SampleEnum["Key4"]
```

次にvalueから取得する際の実装です。以下の通り`()`で取得したいnameを指定します。なお、存在しないvalueを指定した場合は`ValueError`が発生します。

```python
# valueからenumを取得
enum = SampleEnum("value2")

# これはValueError
# enum = SampleEnum("value4")
```
GitのRebaseやStashを活用

## はじめに
Gitは開発チームが協力してコードを管理するための必須ツールです。基本的な操作（コミット、プッシュ、プルなど）はすぐに覚えることができますが、効率的な作業フローを実現するためには、RebaseやStashなどの高度なGit機能を理解することが重要です。本記事では、これらの高度なGitの使い方とその実際の使いどころについて解説します。

## 1. Git Rebaseの使い方とメリット

### Rebaseとは
**Rebase**は、ブランチの基点を変更することで、複数のコミットを他のブランチに適用するGitの操作です。特に、`git merge`と同様にブランチを統合するための方法ですが、異なる点は、`rebase`はマージコミットを作らずに、ブランチの履歴をきれいに保つことができます。

### Rebaseのメリット
- **きれいな履歴を保つ**: マージコミットを作らないため、Gitログが直線的になり、履歴が簡潔になります
- **コンフリクトの解決**: Rebase中にコンフリクトが発生した場合、順番に解決できるため、細かく問題を特定して修正できます
- **他のブランチとの統合が簡単**: 変更が積み重なった場合でも、Rebaseを使って最新の変更を統合できます

### 使い方の例
他のブランチに追いつくためにRebaseを使用します。以下のコマンドで、`feature`ブランチを最新の`main`ブランチにリベースします。

```bash
git checkout feature
git fetch origin
git rebase origin/main
```

もしコンフリクトが発生した場合、Gitはそのことを知らせてくれます。コンフリクトを解決し、以下のコマンドでRebaseを続行します。

```bash
git add .
git rebase --continue
```
Rebaseを取り消すには、以下のコマンドを使用します。

```bash
git rebase --abort
```

## 2. Git Stashの使い方と活用シーン

### Stashとは
**Stash**は、作業中の変更を一時的に保存しておき、後で元の状態に戻せる機能です。例えば、作業中のコードが未完成の状態で、急ぎのタスクが入った場合などに便利です。

### Stashのメリット
- **中途半端な作業を保存**: 途中で作業を中断する必要がある場合でも、変更を一時的に退避させて後で再開できます
- **クリーンな作業環境**: 作業中に別の作業を行う場合に、変更を退避させてから作業を開始でき、クリーンな状態を保てます

### 使い方の例
作業中の変更をスタッシュするには、以下のコマンドを使用します。
```bash
git stash
```
スタッシュした変更を確認するには、以下のコマンドを使用します。

```bash
git stash list
```
特定のスタッシュを適用するには、以下のコマンドを使用します。

```bash
git stash apply stash@{0}
```
スタッシュを適用し、削除するには以下のコマンドを使用します。
```bash
git stash drop stash@{0}
```
## 3. Git Cherry-pickの使い方
### Cherry-pickとは
**Cherry-pick**は、特定のコミットを他のブランチに適用する操作です。例えば、featureブランチで修正した1つのコミットをmainブランチに反映させる場合に便利です。

### Cherry-pickのメリット
- **特定の変更だけを適用**: 複数のコミットの中から、必要な変更だけを選んで別のブランチに適用できます
- **柔軟な変更の移動**: 他のブランチの履歴を大きく変更することなく、特定のコミットのみを取り込むことができます

### 使い方の例
featureブランチで行った変更をmainブランチに反映させたい場合、以下の手順で実行できます。
```bash
git checkout main
git cherry-pick <commit-hash>
```
Cherry-pickを取り消すには、以下のコマンドを使用します。

```bash
git cherry-pick --abort
```
## 4. 効率的なブランチ運用とGitフロー
### Gitフローの概要
Gitフローは、Gitを利用したブランチ運用の戦略の一つで、主に複数人での開発において効果的です。基本的なブランチとしては、master（またはmain）とdevelop、およびfeature、release、hotfixブランチがあります。

### Gitフローのメリット
- **チーム開発でのスムーズな進行**: 各ブランチの目的が明確になり、バグ修正や新機能の開発が効率よく行えます
- **安定したリリース管理**: リリースブランチを活用することで、本番環境に安定したコードをデプロイできます

### Gitフローの基本操作
新しい機能を開発する際、featureブランチを作成して作業を進めます。
```bash
git checkout develop
git checkout -b feature/your-feature
```
作業が完了したら、featureブランチをdevelopブランチにマージします。

```bash
git checkout develop
git merge feature/your-feature
```

## 5. まとめ
Rebaseを使うことで、Gitの履歴がきれいに保たれ、後から作業を見直しやすくなります。特に、複数の開発者が関わる大規模なプロジェクトでは、履歴をきれいに保つことが重要です。
Stashは、作業を中断したり、異なる作業に切り替えたりする際に非常に便利です。中途半端な変更を一時的に保存できるので、フローを中断することなく別のタスクに取り組めます。
Cherry-pickは、特定のコミットを選んで他のブランチに適用するため、柔軟に変更を反映させたい場面で重宝します。
最後に、Gitフローを採用することで、チーム開発がより効率的に進みます。プロジェクトの規模や性質に応じて、Gitの使い方を最適化しましょう。
TouchDesigner でのタイムコードの扱いについて

# TimeCode(タイムコード)について
タイムコードという存在をご存じでしょうか？映像や音声を扱う現場では、使い所を決める時や映像、音声にタイミングを合わせる時などにタイムコードを使います。

種類もいくつかあり、LTC, VITC, MTC, ArtNet TC などが一般的に使用されています。

|略称|名称|
|---|---|
|LTC|Longtudinal(Linear) Time Code|
|VITC|Vertical Interval Time Code|
|MTC|MIDI Time Code|
|ArtNet TC|ArtNet Time Code|

LTC は LTC In/Out CHOP があるので知っている方も多いと思いますが、実際に使った事がある方は少ないのではないでしょうか。また VITC, MTC, ArtNet TC については「名前すら聞いたことないし、そもそも CHOP にもそんなのないじゃん！」って思うかもしれません。
しかし、これらの TC ファミリーは、映像とTouchDesigner のシーンをリンクさせるためにとても便利な情報だと思うので、覚えて頂けたら嬉しいです。

## LTC
まず最初に、<font color="DeepPink">**LTC は音声データ**</font>です！
なので、LTC をもらってヘッドフォンで聞くとピロピロした音を聞くことができます。暇があったら LTC の音を聞いてタイムコードを聴き当てることにもチャレンジしてみてくださいw

そんな事はさておき、LTC は XLR（3ピン） でもらうことが多いので 3.5mm 変換や USB オーディオ IF などを使ってオーディオ（音声データ）として入力します。そして、Audio Device In CHOP で入力したオーディオ IF を選択し、Auido Device In CHOP ノードからの出力を LTC CHOP につなげば完成です。超簡単ですね。
（例ではライン入力を使用しています）

![LTC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308950/af24ca6b-a31a-23f0-0e60-a4718a7829bf.png)

## VITC

つづいて VITC です。これは映像の各フレームに付加データとして記録されています。
映像を扱う現場では SDI や HDMI を使う事が多いのですが、その映像データに VITC は隠れて存在しています。

映像に付加されているため、TouchDesigner  では TOP に入力されている映像から VITC を抜き出します。具体的にはカメラやプレーヤーからの映像を Video Device In TOP で受け、Info CHOP の Operator に TOP のオペレーター（ Video Device In TOP ）を指定します。
その後、Info Type を Time Code に変えると映像から VITC を抜くことができちゃいます。

![VITC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308950/73c6610c-27e0-2da3-c15d-17b1181c8ac2.png)

図は Blackmagic Design の Video Assist の出力を TouchDesigner に入力し、その映像から VITC を抜き出した例です。

VITC は使用する機材（カメラやプレーヤー）によっては付加されない場合もあります。業務で使う場合は事前にチェックしてください。

## MTC
時間ができたら追記します

## ArtNet TC
時間ができたら追記します

## さいごに
タイムコードの存在（特に VITC ）を知らない方が多いかもと思ってこの記事を書きました。
映像にタイムコードがのっているのにわざわざ LTC を引いていたり、Blackmagic DeckLink 8K Pro や Duo/Quad シリーズでは LTC 入力がないので、どのようにすれば TC を得る方法について悩む事もあるのではないかと思います。
そんな時、VITC が来てるなら楽勝じゃん！って気付いて頂けたたら幸いです。
また、ライン入力から LTC を入力するの便利な方法です。厳密に言うとオーディオとビデオのインターフェースが違うためタイミングは微妙ズレていますが、まぁ大体の現場ではOKですし、ズレは CHOP を使って吸収する事も出来ると思いますので、必要であれば調整して下さい。

ちなみに、AJA KONA シリーズでは LTC 入力があるのに TouchDesigner では受けられる方法がないんですよね。改善リクエスト出しとくか…
【Go】REST Clientを使ってリクエストを送信してみる

# はじめに
最近、Goに触れる機会が多くなり文法などの勉強を進めています。そこで、今回は`REST Client`を使ってサーバーにHTTPリクエストを送る簡易的なプログラムを作成、実行していきます。とても初歩的な内容ですが少しでも参考になれば幸いです。

では、始めていきます。

# REST Clientとは？
そもそも`REST Client`について簡単に説明すると、**VSCode上で直接HTTPリクエストを送信し、レスポンスを表示できる拡張機能**です。
`Postman`のような外部ツールを使用する必要がなくなり、APIテストを便利で効率的なものにすることができます。

他の主要な特徴、使い方などはページ末のリンク先（１つ目）にある`README`を参照してください。

# コード
今回はサーバー用の`server.go`とリクエスト送信用の`request.http`を作成します。
なお、ユースケースはリクエストから送信された「ユーザー名」と「パスワード」を受け取り、これがサーバーにあらかじめ設定された認証情報と一致するかを検証します。

```go:server.go
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
)

//データ構造を定義
type LoginRequest struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

//リクエストがPOSTメソッドかどうか確認し、不正なメソッドの場合はエラーを返す
func loginHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == http.MethodPost {
		var loginReq LoginRequest
		decoder := json.NewDecoder(r.Body)
		if err := decoder.Decode(&loginReq); err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		// ユーザー名とパスワードの確認
		if loginReq.Username == "user" && loginReq.Password == "password123" {
			w.WriteHeader(http.StatusOK)
			w.Write([]byte("Login successful"))
		} else {
			w.WriteHeader(http.StatusUnauthorized)
			w.Write([]byte("Invalid credentials"))
		}
	} else {
		http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
	}
}

func main() {
	http.HandleFunc("/login", loginHandler)
	fmt.Println("Server is running on port 8080")
	log.Fatal(http.ListenAndServe(":8080", nil))
}

```

```http:request.http
POST http://localhost:8080/login
Content-Type: application/json

{
  "username": "user",
  "password": "password123"
}

```
２つのコードを記述することができたら、ターミナルで`go mod init server.go`、`go run server.go`を実行します。
次に、request.httpの画面を開いてください。`REST Client`がインストールされている場合、`POST http://localhost:8080/login`の上部に`Send Request`が表示されているはずなのでそこをクリックします。

すると、以下のようにレスポンスがくるはずです。

```:Response
HTTP/1.1 200 OK
Date: Sun, 08 Dec 2024 02:59:24 GMT
Content-Length: 16
Content-Type: text/plain; charset=utf-8
Connection: close

Login successful
```

もちろん、`request.http`を書き換える（`user`→`use`に変更など）するとしたように`Unauthorized`が返ります。

```:Response
HTTP/1.1 401 Unauthorized
Date: Sun, 08 Dec 2024 02:59:55 GMT
Content-Length: 19
Content-Type: text/plain; charset=utf-8
Connection: close

Invalid credentials
```

:::note info
`Date`部分はレスポンスの時間を表します。
`GMT`はイギリスのグリニッジ天文台を基準とした時間（**グリニッジ標準時**）なので日本と比較すると-９時間差が生まれます。
今回は2024/12/08(Sun) 11:59ごろに実行したので上のように表示されます。
ちなみにですが、`UTC`は精度の高い原子時計と天体観測に基づいて決められた時間（**協定世界時**）です。
:::

# おわりに
今回の記事では`REST Client`を利用してリクエストを送信してみました。
また、今回は認証情報があらかじめ決められているという形でしたが、次はデータベースを導入してみようと思います。また読んでいただけると嬉しいです。

では、今回の記事はこれで終わりです。最後までお読みいただきありがとうございました。

# 参考
https://github.com/Huachao/vscode-restclient

https://hrd-web.com/apps/note/feature/world_time/#:~:text=%E5%85%B7%E4%BD%93%E7%9A%84%E3%81%AB%E8%A8%80%E3%81%86%E3%81%A8,%E7%9A%84%E3%81%AA%E6%99%82%E9%96%93%E5%9F%BA%E6%BA%96%E3%81%A7%E3%81%99%E3%80%82
[GitHub Actionsエラー] An import path can only end with a '.tsx' extension when 'allowImportingTsExtensions' is enabled.

```
error TS5097: An import path can only end with a '.tsx' extension when 'allowImportingTsExtensions' is enabled.
```
GitHub ActionsでCICDが実行された際に上記のエラーが発生しましたので解決法を紹介します。

## 原因
tsxファイルをインポート時に.tsxを記述していたのが原因でした。

```diff
- import Component from "./Component.tsx"; // 拡張子が付いているのが原因
+ import Component from "./Component";
```

## まとめ
GitHub Copilotの予測変換を使っているとたまに余計な記述で失敗することがあったりします。

コーディングしている際の警告はしっかり読んでいきたいと思います。
Rust × Docker環境でGitフックによる任意コマンド実行を行う方法

この記事は [DENSOアドベントカレンダー2024](https://qiita.com/advent-calendar/2024/denso) の9日目の記事です。

## 背景

JavaScript界隈では`husky`を用いて`pre-commit`や`pre-push`などのGitフックを簡単に設定できます。
これにより、コミットやプッシュ時に自動でテストやリント、
フォーマットチェックを実行する運用が一般的です。

一方、Rustプロジェクトでも同様のことを行いたい場合があります。
ただし、`npm`や`python`といった他言語ツールに依存せず、
Cargoエコシステム内で同様のフローを構築したいケースです。
そのような場面で役立つのが`cargo-husky`になります。

本記事では`cargo-husky`を使用してRustプロジェクトでGitフックを管理する方法を紹介します。
`pre-commit`や`pre-push`などのフックで任意コマンドを実行する手順と、
Docker環境下でコンテナ内コマンドを実行する際のポイントを示します。

## `cargo-husky`とは

`cargo-husky`は`cargo test`実行時に`.git/hooks`配下へフックファイルを自動生成するツールです。
`Cargo.toml`の`dev-dependencies`に`cargo-husky`を追加し、
`cargo test`を行うだけでデフォルトで`pre-push`フックが設定されます。

### インストール例

`Cargo.toml`に以下を記述します。

```toml
[dev-dependencies]
cargo-husky = "1"
```

この状態で`cargo test`を実行すると、
`git push`時に`cargo test`が自動的に実行される`pre-push`フックが`.git/hooks/pre-push`へ生成されます。

## 独自コマンドを実行したい場合

標準設定では`push`時に`cargo test`を実行します。
しかし、他のコマンド（ビルドツールやコード整形ツールなど）を使いたい場合や、
`pre-commit`フックで独自の処理を行いたい場合もあります。

そのようなときは`cargo-husky`が提供する`features`フラグや`user-hooks`機能を利用するとよいです。

### `user-hooks`機能を使ったカスタムフック設定

`user-hooks`機能を有効にすると、`cargo-husky`が自動生成するフックを抑制できます。
代わりに、`.cargo-husky/hooks`ディレクトリへユーザー独自のフックスクリプトを配置して、
任意のコマンドを実行可能になります。

**手順:**

1. `Cargo.toml`を以下のように変更します。

    ```toml
    [dev-dependencies.cargo-husky]
    version = "1"
    default-features = false
    features = ["user-hooks"]
    ```

    この設定により、`cargo test`を実行した際に、
    デフォルトの`pre-push`フック（`cargo test`実行）は生成されなくなります。

2. `.cargo-husky/hooks`ディレクトリを作成します。

    ```bash
    mkdir -p .cargo-husky/hooks
    ```

3. たとえば`pre-commit`フックで独自コマンド`my_custom_command`を実行したい場合、
   以下のようなスクリプトを用意します。

    ```bash
    echo '#!/bin/sh
    set -e
    my_custom_command
    ' > .cargo-husky/hooks/pre-commit
    chmod +x .cargo-husky/hooks/pre-commit
    ```

4. `cargo test`を実行すると、ビルドスクリプトが発動します。
   これにより`.cargo-husky/hooks`下のスクリプトが`.git/hooks/pre-commit`へコピーされます。

    ```bash
    cargo test
    ```

以上で`git commit`時に`my_custom_command`が実行されるようになります。

### Docker環境での実行例

Docker環境で開発する場合、フックスクリプト内で`docker compose exec`を利用すると、
コンテナ内で任意のコマンドを実行可能です。

```bash
echo '#!/bin/sh
set -e
docker compose exec -T my_container_name my_custom_command
' > .cargo-husky/hooks/pre-commit
chmod +x .cargo-husky/hooks/pre-commit
```

この設定により、`git commit`時にコンテナ内で`my_custom_command`が実行されます。
これによって外部ツールへの依存を減らし、
統合的なワークフローを実現できます。

## よくある質問

### `git push`時に`cargo test --all`が実行される理由

`cargo-husky`は標準で`pre-push`フックを生成し、`cargo test`を実行します。
別のコマンドを利用したい場合は`default-features = false`を指定し、`user-hooks`機能を有効化してください。
これで独自のフックが定義できるようになります。

### `package.metadata.husky.hooks`は使えるか

`cargo-husky`は`npm`版`husky`とは異なる仕組みで動作します。
`package.metadata.husky.hooks`はサポートされていません。
代わりに`[dev-dependencies.cargo-husky]`や`user-hooks`ディレクトリを用いてカスタマイズします。

## まとめ

- `cargo-husky`によりRustプロジェクトのGitフック管理が容易になります。
- `user-hooks`機能を使うことで任意コマンドやコンテナ内コマンドの実行が可能です。
- `npm`や`python`に依存しないCargoネイティブなフック管理により、開発効率が向上します。
「考えることを減らす工夫」レポジトリ操作の時間を最小にする例（zsh, fzf, vscode）

## 下準備
まずは、下記の記事のとおりに`ghq`と`fzf`をセットアップしておきます。

zshはこちらがおすすめ。

https://ohmyz.sh/

> さらに使いやすく : zshのキーバインディング
さらにzshのキーバインディングに登録することで、プロジェクトを選択後にプロジェクト直下に移動できます。
以下の場合、 Ctrl+] を押すと、プロジェクト選択画面が開きます。

**Ctrl+] を押すと、プロジェクト選択画面が開く**ところまでできる状態にしておきます。

https://qiita.com/tomoyamachi/items/e51d2906a5bb24cf1684


## レポジトリの新規作成、first commit、プッシュまでを最小手数でおこなう

```terminal
# 新規レポジトリ作成
ghq create MyApp

# Ctrl+] を押し、ターミナルで MyAppを検索してEnter

# vscodeを開く
code .
```

`README.md`を追加して `first commit`。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883/c3d26312-f296-2287-71ed-3f743fb96d94.png)

`Branchの発行`を押して、レポジトリをリモートにpush。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883/51fa4de6-3e0c-289f-7c83-2d213f6a9ce0.png)

## 手数比較
```diff
- cd path/your/repos
- git init MyApp
- code . 

+ ghq create MyApp
+ 「Ctrl+]」で移動
+ code .
```

書くとほぼ同じコストに見えますね（笑）
大きな違いは、
1. ディレクトリのパスを覚えなくていい
2. ディレクトリのパスを打ち込まなくていい

です。
`Ctrl+]`を押して、ディレクトリ名を打ちながら移動先を選ぶだけでよくなるので考えることが減ります。

この「考えることを減らす」努力は積極的にしていくと、可処分時間が少しずつ増えていき本当に大事なことに時間が使えるようになります。

## まとめ

- 1回の操作が5秒短縮されると
- それが毎日10回発生すると50秒短くなり
- 1週間で5*50=250秒節約できる

毎日の小さいストレスにおもう作業を取り除く方法を探そう。
小さければ小さいほど変えやすく取り組みやすいので、どんどん試しましょう。
JavaScriptで動的に値を設定すると開発者ツールにvalue属性が反映されない場合がある

## はじめに
タイトルの通りですが
JavaScriptで動的に値を設定すると開発者ツールにvalue属性が反映されない場合がある
ということを知ったので共有です。

どこが間違っているのか全然わからなく、JavaScriptとサーバーサイドとを見つつひたすらデバッグしていました。もうお手上げだ、と思って試しに先の処理をしてみると、なぜかうまくいったのです。

！！！！？？？？と思ってChatGPTさんに聞いてみました。
「valueって検証ツールには反映されてないけど値を持っているっていうことある？」

## ChatGPTさんの回答

![IMG_0613.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900848/96864f98-0307-b00b-a3ac-89e6fe2e7c63.jpeg)

<details><summary>なんでこうなるかも聞いてみました</summary>

## **現象の概要**
1. `<input>`要素に`value`属性がHTMLとして表示されていない。
2. しかし、JavaScriptで`value`を取得すると値が確認できる。
3. フォーム送信時にも、値がサーバーに正しく送信されている。

---

## **原因の詳細**
この現象は以下の3つの要因が絡み合って発生しています。

---

### **1. HTML仕様：`value`属性と`value`プロパティの違い**
HTMLフォーム要素は以下の2つの値を管理しています：

- **`value`属性**  
  初期値をHTMLコードに記述することで設定され、開発者ツールでは主にこの属性が表示されます。

- **`value`プロパティ**  
  JavaScriptやサーバーサイドで動的に設定された値を保持し、DOM（Document Object Model）上で管理されます。  
  `document.getElementById('xxx').value`のように、JavaScriptで取得できます。

これらの2つは独立して動作し、**動的に値を変更した場合、`value`属性には反映されない**ことがあります。そのため、開発者ツールでは`value`属性が空に見える場合でも、`value`プロパティには値が設定されている可能性があります。

---

### **2. ASP.NETの仕様：動的な値の管理**
ASP.NETでは、サーバーサイドでフォーム要素の値を管理し、HTMLを動的に生成します。そのため、次のような挙動が発生することがあります：

1. **値がHTMLの`value`属性に直接出力されない**  
   サーバー側で`Text`プロパティに値が設定されていても、HTML上の`<input>`タグにその値が反映されないことがあります。

2. **値の管理はViewStateで行われる**  
   ASP.NETでは、`ViewState`や`PostBack`機能によってフォーム要素の値がサーバーとクライアント間で管理されます。そのため、HTMLに`value`属性が表示されていなくても、サーバー側で値を受け取ることができます。

---

### **3. ブラウザの挙動**
ブラウザがこの現象に与える影響もあります：

- **開発者ツールの制限**  
  開発者ツールでは、HTMLの`value`属性しか表示されません。`value`プロパティに動的に設定された値はツール上で見えない場合があります。

- **フォーム送信時の動作**  
  `<input>`要素が非表示（例：`style="display:none;"`）でも、`value`プロパティに値が設定されていれば、フォーム送信時にその値が含まれます。

---

## **なぜASP.NETで目立つのか**
この現象は他のフレームワークでも発生しますが、ASP.NET特有の以下の要素が影響を目立たせています：

1. **HTMLの生成がサーバー側で行われる**  
   ASP.NETでは、HTMLはサーバーサイドで動的に生成されます。その際、値をViewStateや内部プロパティで管理するため、HTMLの`value`属性に値を出力しないことがあります。

2. **`style="display:none;"`の利用**  
   ASP.NETでフォーム値を一時的に非表示にするために`display:none`が利用されることがあり、この場合も`value`プロパティに値が保持されます。

---

## **対策**
この現象を正しく理解しつつ、以下の対応策を検討してください：

1. **`type="hidden"`の使用**  
   `style="display:none;"`の代わりに`type="hidden"`を使用することで、値が意図した形で扱われることを保証できます。

2. **サーバー側で値を確認**  
   ASP.NETでは`TextBox.Text`プロパティで値を取得できるため、サーバー側で適切に管理する。

3. **JavaScriptで値を確認**  
   開発者ツールやスクリプトで`value`プロパティを直接確認する方法も有効です。

---

## **結論**
この現象はHTML、ASP.NETの仕様、そしてブラウザの挙動が絡み合った結果であり、**ASP.NET特有の問題ではありません**。ASP.NETでは`ViewState`やサーバーサイド管理があるため、HTMLに`value`属性が表示されないケースが多いですが、適切な方法で値が管理されています。

追加のご質問がございましたら、どうぞお気軽にお聞きくださいませ！


</details>



## おわりに
頭が凝り固まっているとよくないですね
とりあえずやってみる、ってすごく大切
.github/workflowsの作成場所を間違ったためGitHub Actionsが実行されない

.github/workflows配下にGitHub Actionsで実行するテストファイルを作成し、mainブランチへpushしたのですがGitHub Actionsが実行されないという事象が起きたので紹介します。

## 状況

![スクリーンショット 2024-12-08 11.43.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3289947/0703538f-2d01-0b87-8cba-dd661c5b236a.png)

テストファイルをpushしたのにGitHubのActionsをクリックしても初期画面しか表示されない

## 原因
.github/workflowsの作成場所が間違っていました。

今回リポジトリ配下に更にReactのプロジェクトのディレクトリを作成しており、そのディレクトリ内で.github/workflowsを作成してしまっていました。

.github/workflowsはリポジトリの直下に作成しないといけません。

今回は.github/workflowsをリポジトリ直下まで移動させ再度pushすることで解決しました。

## まとめ
問題自体は単純なものでしたが、まだテストの経験が浅いためどこかで別の設定を間違ったのかと疑心暗鬼になってしまいました。

エラー時は落ち着いて問題解決に取り組んでいきたいです。
【自作アプリ：メルカリスクレイピングツール】Web上の商品情報を取得してExcel出力！

## 開発したツールについて
この度、「Web版メルカリの情報を自動収集して、Excel形式で出力するパッケージツール」を開発しました！

![スライド26.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311150/80beb811-d593-f41b-7f44-047768705bb8.jpeg)

## ツール構成
①クライアントアプリと、②サーバー処理、に分かれた構成となっています。
- ①クライアント側：exe形式です。自動でChromeを操作して自動的に商品情報を収集します。
- ②サーバー側：ユーザー認証をおこないます。

## 技術的な説明
- クライアント側は、PythonのSeleniumを使っています。
- サーバー側は、Pythonでユーザー認証用のWebAPIを立てています。

クライアント側のアプリを起動後、まずはユーザー認証用のWebAPIを呼び出します。
WebAPI側は、ユーザーIDや日時情報を読み取り、そのユーザーが本サービスを利用できるかどうかを判定して結果を返します。

クライアント側は、その認証結果を受け取ります。
認証結果がOKであればツールがそのまま動作し、NGであればツールが中断する仕組みになっています。

## 技術的な工夫点
- SeleniumでChromeを自動操作すると、ものすごくマシンパワーをとります。これを全てサーバー側で処理すると、マシンパワーが足りない点がネックでした…。
- そこで、Seleniumの動作はクライアントPC（＝ユーザーPC）に任せる形式にしました！
- サーバー側の処理は主に認証APIに特化することで、サーバーの負荷を軽減した状態で、不正利用の防止などをおこなうようにしています。
- この構成は汎用的に使えるため、今後も色々なサービスに展開できるのがメリットかと思っています！

## 取得できるデータ
以下のような情報を表形式で取得します！

1. 商品URL
1. 販売状態
1. 商品名
1. 価格
1. 商品の説明
1. カテゴリー
1. 商品の状態
1. 配送料の負担
1. 配送の方法
1. 発送元の地域
1. 発送までの日数
1. 出品日時
1. 更新日時
1. 出品者名
1. 出品者の高評価数
1. 出品者の低評価数
1. 商品画像URL

## 

## より詳しい情報
より詳しい情報は下記に記載しています！
少しでも興味があれば、ぜひお気軽にご連絡ください。

https://ffzzyy.memberpay.jp/service/item/1gyhstj

最後まで読んでいただき、ありがとうございました。
ライフワークバランスを確認するツールを作った話 - 2

:::note info
この記事は[LITALICO Engineers Advent Calendar 2024](https://qiita.com/advent-calendar/2024/litalico) カレンダー3 の 12日目の記事です
:::

# はじめに

[前日の記事](https://qiita.com/nonikeno/private/8b271ee327f421db2976)の続きとなります

さて、家事の予定を組み合わせ最適化によって、自動的に登録できるようになりました
ただし、それだけでは、業務の予定を考慮できていないので、今回は、仕事のカレンダーからのデータの取り込みと、仕事のカレンダーの更新に、対応する話を書きたいと思います

# 仕事のカレンダーのデータの読み込み

googleは多くのAPIを公開してくれております、Google カレンダーもAPIが多く、とても便利です
業務の予定を、Googleカレンダーで管理されている場合は、google カレンダーAPIで、予定を一括取得できます

- [予定の取得API（Events: List）](https://developers.google.com/calendar/api/v3/reference/events/list?hl=ja)

今回の場合は、1ヶ月毎に、家事の予定を登録する作りにしておりますので、timeMinとtimeMaxの[リクエストパラメータ](https://developers.google.com/calendar/api/v3/reference/events/list?hl=ja#parameters)を活用して、関連のある仕事の予定を取得します

また、改めて、解説の必要がないくらい、セットアップ手順についても詳細にドキュメントが用意されています
今回は、Lambdaのnodeで連携するので、[Node.jsでのセットアップ手順](https://developers.google.com/calendar/api/quickstart/nodejs?hl=ja)を参考にしました

ほぼ、全てのドキュメントが多言語対応されているのも嬉しいですよね

### 業務の予定をカレンダーから取得するのが難しい場合

多くのカレンダーでは、ファイルでの出力が用意されているので、そちらを取り込むことを検討する形でしょうか
ただし、その場合、この記事の以降で検討するような、リアルタイムでの連携は難しくなります

# 仕事のカレンダーのデータが更新されたときの対応

Google カレンダー APIの[PUSH通知](https://developers.google.com/calendar/api/guides/push?hl=ja)の機能を利用します

上記、確認いただくと分かる通り、受信URL（Webhook）を設定できるので、そこで、仕事のカレンダーが更新された際に、家事の予定をリセットし、再度、家事予定の自動登録を行います

## 更新差分を取得する

上記のPUSH通知は、更新があったことはわかるものの具体的にどの予定が更新されたかまではわかりません。通知を受け取ったら、これも前述の予定の取得APIで、予定の詳細を取得し、通知前の予定と比較して、差分を計算する必要があります

ちなみに、予定の削除も更新としての検知になりますので、更新の通知があった際に、元々設定されていた予定が存在しない場合は、削除されたと考える必要があります

## 差分更新が必要か？

さて、更新されたことはわかるのだから、更新のPUSH通知の度にリセット&自動登録を行なっても良いのではないかと考える方もいますよね、ケースバイケースですが、それでも良い場合もあるでしょう

ただ、今回の場合、予定の自動登録はかなりの計算を伴う処理です、諸々頑張ってみましたが、それでも、長いときで、1分〜10分程度の時間がかかります

仕事の予定の更新の度に、1分〜10分程度処理が実行されるのは、UX的にもランニングコスト的にもいただけないですよね

ケースバイケースというのは、元々やりたかったこと、つまり、要求の実現のために、そのコストが必要になることもあるからです。今回の場合はどうでしょうか

業務の影響によって、家事予定を調整する必要があるか、知りたいのはここだけですよね。そのため、想定していた業務時間の開始と終了が変更になり、家事予定と重なってしまう場合のみ、予定のリセット＆自動登録を実行するようにしております

![名称未設定ファイル.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2277180/cd201dab-8c74-9ab5-c9c4-6db37468c9f3.png)
Redux の使い方

## Redux の使い方

### 1. Redux の基本的な概念

Redux を使うためには、まず以下の基本的な概念を理解することが重要です：

- **Store（ストア）**：アプリケーションの状態が格納される場所。すべてのデータが一元管理されます。
- **Action（アクション）**：状態を変更したいときに発行するオブジェクトで、`type` プロパティと必要に応じて他のデータを含んでいます。
- **Reducer（リデューサー）**：アクションが発行されると、リデューサーが新しい状態を生成します。これは純粋な関数で、前の状態とアクションを受け取り、新しい状態を返します。
- **Dispatch（ディスパッチ）**：アクションをストアに送る関数。これを使って状態を更新します。

### 2. Redux のインストール

まず、React プロジェクトに Redux をインストールします：

```bash
npm install redux react-redux
```

- `redux` は状態管理のためのライブラリです。
- `react-redux` は React と Redux を接続するためのライブラリです。

### 3. Redux ストアの作成

まず、ストアを作成します。ストアは、アプリケーションの状態を管理する中心的な役割を果たします。

```js
// store.js
import { createStore } from 'redux';

// 初期状態
const initialState = {
  count: 0
};

// リデューサー関数
const counterReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 };
    case 'DECREMENT':
      return { count: state.count - 1 };
    default:
      return state;
  }
};

// ストアを作成
const store = createStore(counterReducer);

export default store;
```

### 4. Action の定義

アクションは、状態の更新を表すオブジェクトです。アクションには少なくとも `type` プロパティを含める必要があります。

```js
// actions.js
export const increment = () => ({
  type: 'INCREMENT'
});

export const decrement = () => ({
  type: 'DECREMENT'
});
```

### 5. React コンポーネントで Redux ストアを使用する

React アプリケーションで Redux のストアを使うために、`Provider` コンポーネントでストアをラップし、アプリ全体にストアを提供します。

```js
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
```

### 6. Redux ステートをコンポーネントで接続

React コンポーネントで Redux のステートを使うためには、`useSelector` を使ってストアからデータを取得し、`useDispatch` を使ってアクションをディスパッチします。

```js
// App.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './actions';

const App = () => {
  // Redux ストアから state を取得
  const count = useSelector(state => state.count);

  // アクションをディスパッチする関数
  const dispatch = useDispatch();

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => dispatch(increment())}>Increment</button>
      <button onClick={() => dispatch(decrement())}>Decrement</button>
    </div>
  );
};

export default App;
```

### 7. Redux の使い方のまとめ

- **Store**：状態を格納する場所。`createStore` を使って作成します。
- **Action**：状態を変更するためにディスパッチされるオブジェクト。`type` プロパティを含みます。
- **Reducer**：状態変更のためのロジック。アクションを受け取り、新しい状態を返します。
- **useSelector**：React コンポーネント内で Redux の状態を取得するフック。
- **useDispatch**：アクションをストアにディスパッチするフック。

これで、Redux を使
からあげの味付けをChatGPTに評価してもらった

この記事は[からあげ帝国アドベントカレンダー](https://qiita.com/advent-calendar/2024/karaage)
8日目の記事です。

## はじめに
家でから揚げを食べる時に作るタレを、ChatGPTに評価してもらいます。
また、タレの改善案をなども提案してもらおうと思います。
なお、このアドベントカレンダーの[からあげ帝国](https://karaage.hatenadiary.jp/entry/2022/11/30/073000)は、からあげにレモンをかける行為が禁止されていますので、この点についても評価してもらいます。

### タレの準備
まず、評価してもらうタレを準備します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594551/64a77799-d894-98fe-2197-fb1f70b679ef.png)
タレは以下の材料を用意して混ぜるだけです。
・白だし（七福の白だしが個人的に気に入っています）
・おろしにんにく
・醤油
・レモン果汁
・刻み葱

タレはこんな感じになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594551/1ce1f4be-30a0-05a0-148b-0c1de21acb48.png)

タレの味が濃い目なので、からあげの下味は薄めに作ります。

食べる時はこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594551/fdbdfc1d-d754-7e2d-aeec-65b602d24af6.png)


### ChatGPTにタレの評価をしてもらう
それでは、ChatGPTにこのタレを評価してもらってみます。
```
から揚げにかけるためのソースを作成しました。
タレは、醤油、白だし、おろしにんにく、ネギのみじん切り、レモン果汁を混ぜたソースです。
このソースの評価をしてくれますか？
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594551/0f75f78f-d25a-20f8-d954-752d2cfab322.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594551/1965f8a5-ff68-2b5c-cc59-7e538c6b6757.png)

ChatGPTさんは割と質問者を甘やかす感じがしますがいきなり満点出してきました。
ここから改善点などを聞いてみたりしようとしたのですが…。
特に評価の方法を指定しなかったのですが、材料ごとの効果を列挙してくれたりしているので、味の調整とかの参考になりそうですね。
から揚げ用に作ったソースなのですが、他の用途もおすすめしてくれたので今度試してみようと思います。
（にんにくと魚はどうかなとちょっとどうかなという気もしますがｗ）


### ソースの改善点を考えてもらう。
調整次第でオリジナリティを出すことも可能。との部分についても聞いてみると以下の解答でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594551/16068720-55b6-ecd7-7342-bb78575b832e.png)
甘辛い感じにしてみるのもよさそうですね。味醂と唐辛子を今度試してみよう。

### からあげ帝国でこのタレを使うことへのリスク評価
さて、からあげ帝国においてこのソースを使う事へのリスクを考えてもらいます。まずはからあげ帝国の情報をお知らせします。

```
からあげ帝国では、からあげにレモンをかける行為が犯罪とされます
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594551/7553f6d7-5c40-db91-43f2-268da37074c0.png)
すんなり受け入れてくれました。次に、帝国でタレを使用するリスクについ評価してもらいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594551/18301a85-0bcd-9975-43ea-2a0e1a763295.png)
成分に含まれているのでグレー扱いですね。
別の材料にするか、かける行為を変えるかオススメしてきました。独自ルールに適切に対応してくれているので凄いぞChatGPT。

折角なので、ライム版を作成してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594551/56deff99-6059-7d4a-51ef-fe53969e8c17.png)

### ライムを使用したからあげ帝国版ソースの所感
ライムはどうかなと思ったのですが、思いのほか結構いけます。香りがかなりいいのですが、ジンなどの洋酒と相性がいいですね。

ご飯のおかずにはあまりなりませんでしたが。（白米と合せるには香りがよすぎる…）


## 最後に
以上、自作のからあげ用のソースをChatGPTに評価してもらいました。
・要素毎の評価をしてくれる。（点数の付け方が甘め）
・味のカスタマイズを提案してくれる。
・違う用途を提示してくれる。
・追加した突飛なルールにも対応してくれる。
上記のように、色々と指示していない情報も出してくれたり、また追加ルールを設定すればそれに対応してくれたりとChatGPTの汎用性の高さを再認識したところです。

最期に、いきなり満点評価だったので、辛口で再評価をするようにお願いしてみたら色々と指摘が出てきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594551/ee20f8c5-8bf2-3c67-6959-c85e51e534ca.png)

うーん、スタンダート過ぎるのかぁ。
今度はソース作る前にChatGPTと相談しながら作るのも面白そうだなと思いました。