OmniAICreator/Qiita-1.07M huggingface dataset:
Apache HttpClient を使って Transfer-Encoding: chunked を指定してデータを送信

Apache HttpClient を使って Transfer-Encoding: chunked を指定してデータを送信するには、HttpEntity をチャンク転送可能なものとして設定すれば実現できます。以下は、Apache HttpClient 4.x を使った例です。

## 例：チャンク転送で POST する Java コード

```java
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class ChunkedPostExample {
    public static void main(String[] args) throws IOException {
        String url = "http://example.com/upload";

        // データをチャンクで送信するための InputStream
        String data = "これはチャンク転送で送られるデータです。";
        ByteArrayInputStream inputStream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));

        // InputStreamEntity を使い、chunked 転送を有効化
        InputStreamEntity entity = new InputStreamEntity(inputStream, -1); // -1 は長さ不明 → チャンク扱い
        entity.setChunked(true); // 明示的にチャンク転送を有効に

        HttpPost httpPost = new HttpPost(url);
        httpPost.setEntity(entity);

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpResponse response = httpClient.execute(httpPost);
            System.out.println("レスポンスコード: " + response.getStatusLine().getStatusCode());
        }
    }
}
```

### 補足

InputStreamEntity の第二引数に -1 を指定すると、コンテンツ長が不明として扱われ、チャンク転送が使用されます。

setChunked(true) を明示的に呼ぶことで Transfer-Encoding: chunked が付きます。

Apache HttpClient が自動的に Transfer-Encoding: chunked を設定してくれます。

## ポイントまとめ

#### 小さい固定データ（String など）

1チャンクで送られることが多い

#### InputStream で段階的に提供

複数チャンクに分かれて送信される

#### setChunked(true) + 長さ不明（-1）

Transfer-Encoding: chunked が使われる

#### チャンクサイズ制御（HttpClient 側）

明示的には不可（内部バッファサイズに依存）

## 大きい固定データは複数チャンクになる？

#### 数KB 程度

1チャンクになることが多い

#### 数MB以上

複数チャンクに分割される
Grokに代わってファクトチェックできるアプリを作った

## はじめに

```
みなさんGrokにファクトチェックさせてますか！
Xのおすすめに流れてくるポストのほぼ全てに「ファクトチェック」が付いてるの何なんでしょうね
挙げ句、「回答は長すぎず要約して」とか「いきった感じで」とか色々注文つけてGrokだって大変なんだぞ！
一回自分でファクトチェックして少しはGrokの気持ちを味わえ！
```
って文章がお風呂に浸かりながら浮かんできたのでそういうアプリを作りました。

「Grokの気持ち」というジョークアプリをご紹介します。

https://in-grok-mind.shaba.dev

## 概要
XのAIアシスタント「Grok」になりきって、ちょっと調べたらわかりそうな情報のファクトチェックを体験できるWebアプリです。

ちゃんと回答すると、GrokじゃなくてGeminiが正確性となりきり度合いを評価してくれます。
え？だってAPI無料枠あるんだもん。

![スクリーンショット 2025-05-15 0.13.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1505764/a5723fee-ec2b-4837-a8e0-51545ec576a1.png)

## 作り方

ClaudeCodeに要件だけ伝えて放置してたら2時間くらいで大枠ができてました。
見た目とかの細かい調整は発生したものの、片手までやって2日くらいで物はできました。

ただ公開までもう2日かかってしまいました。
OGP設定がうまくできてなかったりビルドが落ちる不具合をClaudeに修正させると不具合の堂々巡りに陥って、最終的にデザインを一新して出力させてきたり、機能をすべて落として静的ページだけ出力してきたりと、2~3回くらい作り直させたのが原因です。

サクッと作らせられるかと思ったけど、ちょっと細かいツッコミを入れるならちゃんとプロジェクト化してmust要件伝えないと駄目ですね。


## おわりに

3分もあれば遊べると思うので、ぜひ触ってみていただけると嬉しいです！
Gemini音声で字幕生成＆課金機能実装進捗報告

# 個人開発進捗報告（字幕生成＆ユーザー管理機能の実装状況）

こんにちは。今回も個人開発の進捗をまとめて共有します。

---

## 1. 音声認識＆字幕生成機能の改良

- 既存の自動カットリポジトリを改造し、Gemini 2.5 の音声機能を使って字幕（SRTファイル）を生成できるようにテストしました。
- ハラスメントレスポンスも問題なく返ってきて一安心。
- 現状、素材を変えて実行したところ、エラーが出たり出なかったりと不安定な部分があります。
- セーフティ情報を使わない設定にできないか検討中。

## 2. モデルやデプロイ計画の検討

- モデルを変えて動作検証を進めています。
- デプロイ先を Render と S3 に絞りました。
- プラン内容も決定し、次はデザインをモダンに刷新する予定です。

## 3. ユーザー管理＆課金機能の実装

- ユーザー追加・削除が任意にできる管理機能をローカルで動作確認済み。
- 多重リクエストにも耐えられるかテストしました。
- Stripe を使った課金機能もローカルとFlash環境で動作確認。
- 今後はSupabaseのDBとStripeラッパーを活用して実装予定です。

## 4. サービス運用の方針

- まずは無料・招待制でユーザー100人限定公開し、広告収益のみで運営してみます。
- そのため、字幕の質を高める必要があり、XML・SRTファイルの完全互換も確認中。

## 5. UI改善＆制限対応

- 字幕生成中に進行状況がわかるUIを実装予定。生成時間の目安表示も検討中。
- トークン制限解除とユーザー100人制限の管理も進めています。

## 6. データベース移行＆AWSデプロイ準備

- PostgreSQLへの移行作業を開始。テーブル作成や接続、ローカル動作確認まで完了。
- A5:SQL Mk-2を導入し、ユーザーテーブルやログイン用テーブルを作成済み。
- 現在psqlコマンドの使い方でつまづきつつも、徐々に理解が進んでいます。
- 並列処理ができない問題を解決するためGunicornの導入も計画中。
- Dockerfile作成も開始しました。

## 7. ファイル管理＆バグ修正

- 字幕ファイルは現状ローカル保存ですが、S3に保存してどこからでもアクセス可能にする予定。
- ファイル名の重複はUUIDで回避中。
- 字幕生成後に編集を再開すると無限リロードになるバグが発生しており、修正が必要です。

---

以上、現在の開発状況でした。次回はUIの改善やAWSへのデプロイ、広告実装などを中心に進めていきます。

引き続き頑張ります！もし似たような課題や技術的なアドバイスがあれば、ぜひコメントで教えていただけると嬉しいです。

よろしくお願いします！
Mac mini で ローカルLLM： Ollama で「REST API」とライブラリ「ollama-js」を試す（モデルは Gemma 3）

## はじめに

[過去にローカルLLM を試していた際](https://qiita.com/search?sort=created&q=MLX+%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%ABLLM+user%3Ayoutoy)には、[MLX LM](https://github.com/ml-explore/mlx-lm)、[MLX-VLM](https://github.com/Blaizzy/mlx-vlm) ばかり使っていましたが、最近、以下の記事に書いた Ollama ＋ Mac mini の組み合わせを試しました。

●M4 の Mac mini で ローカルLLM： Ollama で Gemma 3 を軽く試す（テキスト入力、画像も入力するマルチモーダル） - Qiita
　https://qiita.com/youtoy/items/d921bfa19794e328c7e1

今回の内容はその続きで、「REST API」と「ollama-js」を試した話です。

### REST API

https://github.com/ollama/ollama?tab=readme-ov-file#rest-api
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/fe4a5c20-8697-43e5-b4af-539e57f04907.png)

### ollama-js

https://github.com/ollama/ollama?tab=readme-ov-file#libraries
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/1b33be93-e344-4e50-a4b0-05433f0542ac.png)

●ollama/ollama-js: Ollama JavaScript library
　https://github.com/ollama/ollama-js


### お試し1： REST API を使う

まずは REST API を使った話です。


#### 試したコマンドと実行結果

Ollama が起動している状態だと、HTTPリクエストでレスポンスを得られる状態に既になっているようです。

以下に、公式の情報を参考にして試したコマンドと、その実行結果を掲載します（※ 2通り試しています）。

```zsh
curl http://localhost:11434/api/generate -d '{
  "model": "gemma3:12b-it-q8_0",
  "prompt":"なぜ空は青い？"
}'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/4f54062c-57b0-4ab9-97dd-053231172ccf.png)



```zsh
curl http://localhost:11434/api/chat -d '{
  "model": "gemma3:12b-it-q8_0",
  "messages": [
    { "role": "user", "content": "なぜ空は青い？" }
  ]
}'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/f7513495-d289-4272-9221-27e6732e6ac7.png)


どちらもストリーミングで結果を得ることができました（付加情報ごと出てきているので、かなり見づらいですが...）。



### お試し2： ollama-js を使う

次に ollama-js を使った話です。

●ollama/ollama-js: Ollama JavaScript library
　https://github.com/ollama/ollama-js

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/1a292c7f-550e-4515-bb0c-f9a8d576d90c.png)


#### 試した手順などと実行結果

以下、試した手順などと実行結果です。


まずはライブラリのインストールです。

```zsh
npm i ollama
```

そして、以下の内容を実装して、nodeコマンドで実行しました。

```javascript
import ollama from "ollama";

const message = { role: "user", content: "なぜ空は青い？" };
const response = await ollama.chat({
  model: "gemma3:12b-it-q8_0",
  messages: [message],
  stream: true,
});
for await (const part of response) {
  process.stdout.write(part.message.content);
}
```


以下が実行結果です（※ 途中を省略してます）。

<iframe width="560" height="315" src="https://www.youtube.com/embed/Cyh-HPWMgfo?si=Dz1xT2Mv243YREou" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>


前回の記事と同様に、ストリーミングの応答を得ることができました。


## おわりに

引き続き Ollama を使ったローカルLLM のお試しをやっていこうと思います。
VSCode の拡張機能  Marp に CSSファイルをあてる

## 気づいたら4時間くらい時間を溶かしていた
Markdown でスライドとか作れたらなんか便利そうだなと思い、やってみました。ChatGPTとCopilotに聞いてもまったくエラーが解消できず、さらにこちらの記事を参考にしながら試行錯誤してもなぜかCSSが反映されませんでした。

https://qiita.com/fu-a-sak/items/8d16ff8c02ebd3d02f7b

https://qiita.com/atw0_0w/items/ca0699010600db169b55


## 結局
できた。
なにが原因でできなかったのか、なにをしてできるようになったのかは不明です。

このページのコードをやけくそでコピーしてたらなぜか反映されました。

https://marpit.marp.app/theme-css

## CSSのコード
```css

/* @theme test */

@import 'base';

section {
  /*背景色をオレンジにする*/
  background-color: #f80;
  /*文字色を白にする*/
  color: #fff;
}
```
最初はどうでもいいと思っていましたが、このコメントが重要らしいです。
コメントで、"@theme テーマ名" を最初の行に書く必要があるということだけは理解できました。
```css
/* @theme test */
```
## md のコード
```
---
marp: true
theme: test
---

## 見出し
* test
```

## スクリーンショット
### プレビュー
背景がオレンジになっている！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812230/ffbad88b-9cb7-40fd-bb78-66a6299ad3d7.png)


### ワークスペースの settings.json
白紙です。これで反映されているから不思議です。
今までの苦労はなんだったのか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812230/96a02f2d-88ea-4665-b6a5-2eb86d02e38b.png)

### VSCode の Settings
あらゆるページで、Add Item にcssのファイルパスを入力するように書かれていますが、ここも白紙です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812230/e007cfb7-e537-45f5-9017-de135ce15b36.png)

## とりあえずはOK
原因は不明ですが、解決したのでメモ代わりと情報共有のため記事にしました。同じ問題で躓いている方にとっては、この記事の情報だけでは不十分だと思いますので、質問があればどうぞ。
Geminiでカスタネットを使う魔法少女を描いてみた。

# 概要

Geminiでカスタネットを使う魔法少女を描いてみました。

# 実装

プロンプトと実行結果は以下の通りでした。

```
光のカスタネットを使う魔法少女を描いてください。
```

![光のカスタネットを使う魔法少女_20250515.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/589e00a3-f476-49ec-92bd-6856d999bdb5.png)


```
闇のカスタネットを使う魔法少女を描いてください。
```

![闇のカスタネットを使う魔法少女_20250515.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/cbfc7abc-b115-4628-99ac-05f66a6ea211.png)


```
聖なるカスタネットを使う魔法少女を描いてください。
```

![聖なるカスタネットを使う魔法少女_20250515.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/dd40f106-0f6b-4247-8d70-d903b4bb942b.png)


# まとめ

光の子が可愛いかも。
何かの役に立てばと。
【Mac】スクリーンショットのファイル形式を変更する方法


## JPEGに変更

以下のコマンドを実行するとスクリーンショットのファイル形式を`JPEG`に変更できます。

```terminal
defaults write com.apple.screencapture "type" -string "jpg"
```

## PNGに変更

以下のコマンドを実行すると`PNG`に変更できます。

```terminal
defaults write com.apple.screencapture "type" -string "png"
```
Databricks Genieのフォローアップ質問を試してみた

## 前提
・利用環境：Databricks

https://www.databricks.com/jp/try-databricks?scid=7018Y000001Fi15QAC&utm_medium=paid+search&utm_source=google&utm_campaign=17377047998&utm_adgroup=138148229998&utm_content=trial&utm_offer=try-databricks&utm_ad=732035937815&utm_term=databricks%20%E3%83%88%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%AB&gad_source=1&gclid=CjwKCAiA8Lu9BhA8EiwAag16b8b3zbkIb3V7gp-8VUwKukXnhtVZRQ-1RY8SbETmGVgNT4bQramYmRoCX5wQAvD_BwE#account

## 参考ドキュメント

https://www.databricks.com/jp/blog/whats-new-aibi-april-2025-roundup

## 操作手順（動画）
<iframe width="560" height="315" src="https://www.youtube.com/embed/njGdKbtLrSk?si=L4ijsoMesfSof2ru" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
■ PowerShellで自動マウス操作 ～多分これが一番簡単だと思います～

![PowerShell_banner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4049822/2fd4db5e-14e9-42b3-9e38-a3728ed83c5b.png)
<br>

こんにちは★
好奇心過多なコーダー 零壱(ゼロイチ)テクトです。

<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4049822/ec08f703-4a5c-46d9-8c78-a7527b229e57.png">

僕の所属する会社のPCでは、10分でスクリーンセーバが動いてしまうため
複数のPCで作業していると、すぐにPCがパス入力画面になってしまいます。

その解除が面倒で、以前VBSでマウスを自動で動かすマクロを作った事がありますが
VBSが廃止になるという事(いつだろう)で、今更勉強でPowerShellで組んでみました。

先人の100番煎じですが、思いのほかコンパクトに作れたので公開させて下さい。

# １．概要/仕様
・マウスを指定時間ごとに一定に動かす
・業務効率を考えて動くマウスは1px（操作の邪魔しない
・極力シンプルに単機能に
・Ctrl＋Cでコードを止めたい

# ２．コード

```Powershell:MouseJiggler.ps1
Add-Type @"
using System;
using System.Runtime.InteropServices;

public class MouseJiggler {
    [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
    public static extern void mouse_event(uint dwFlags, int dx, int dy, uint dwData, IntPtr dwExtraInfo);
    public const uint MOUSEEVENTF_MOVE = 0x0001;
}
"@

$stoptimeSec = 5 # xx秒ごとに動作
write-host "CTRL + C で止まります"

# ▼ループ (CTRL + C で停止)
while ($true) {
    # ▼1pxマウス動かす
    [MouseJiggler]::mouse_event(0x0001, 1, 0, 0, [IntPtr]::Zero)
    Start-Sleep -Milliseconds 100
    [MouseJiggler]::mouse_event(0x0001, -1, 0, 0, [IntPtr]::Zero)

    # ▼指定時間待機
    Start-Sleep -Seconds $stoptimeSec
}
```

# ３．備考
・特に大したものではいので、使いたい方はどうぞお使いください。

・ポイントはマウスを指定の場所に移動したりせず
　現行のマウスカーソル位置から1pxだけずらして戻るため
　コードを実行させながら
　PCを触っていても触っていなくても影響がない事です。


<br>

　　　　　　　　　　　どこかの誰かの何かの足しになれば幸いです。
　　　　　　　　　　　　　　　　　　　　　　　　　　01000010 01011001 01000101
自作PCはいいぞ

# 自作PCって知ってますか？
自作PCって聞くと難しそうと思われる方もいるのではないでしょうか？
自作PCとはその名の通り，マザーボードといわれるPCの基盤からCPU，メモリ等自分でパーツを選び組み立てていく作業になります．
基本さえ覚えてしまえばあとは，ぽこぽこパーツをはめていくだけ．
ほぼレゴです．はい．
この記事を読んで少しでも自作PC興味ある方に刺さればなと思います．

# 自作PCに興味を持ったきっかけ
私の居た研究室は一人一台研究を共にするPCを自分でマザボから組み立て，環境構築していく文化がありました．また，マイコン(ちっちゃいパソコンのようなもの)も研究柄使うことがあったので，自然とパソコンの構成や環境構築に慣れました．

自分で組み立ててみると愛着も沸くもので，パーツは引継ぎ引継ぎなので動かなくなるとパーツ特定して取り換えつつ大事に使ってました．
あと，パソコンには一台一台，科学者の名前がついていたのですが(教授が決めてたルールだったのですが，マジでセンスありますよねw)，私は数学者のオイラーが好きすぎてオイラーの名前を勝ち取りました．

# ここがいいよ！自作PC
そんな自作楽しいを広めたい私が，自作PCのおすすめポイントをまとめてみました！
- 多種多様なケースのデザイン！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867423/c49948ab-ef57-4e52-acf3-dc17b6eb666f.png)
https://www.amazon.co.jp/MSI-GUNGNIR-300R-AIRFLOW-WHITE/dp/B0CJ2CJT2Q/ref=asc_df_B0CJ2CJT2Q?mcid=976ef61935b230f792d7a880548e371d&th=1&tag=jpgo-22&linkCode=df0&hvadid=707562003722&hvpos=&hvnetw=g&hvrand=17929308470019308690&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009260&hvtargid=pla-2206766778718&gad_source=1
→こんな感じでかわいいケースがたくさんあります！
クリアな側面から見えるファンがたまりませんね！

- 虹色に光るファン
自作PCといえば虹色．きらきら光るファンは少年心を刺激します．
虹色に限らず，ファンの色はたくさんあるのでケースと合わせて決めてもいいかもですね！
- スペック思いのまま
パーツの組み合わせ自由自在！メモリをめちゃくちゃ拡張して，
サクサク動くようにもできるし，GPUたくさん積んでゲームやunityであそんでもよし！
- 調子が悪くなってきたら，パーツを取り換えて自分で修理できる
基本的にパーツ全部死ぬなんてことは，水没や衝撃を与えない限りはあまりないと思います．パーツを取り換えつつ，長く使えるのでお勧めです！取り替えたパーツは中古で売ることもできますし．．．

# でも．．．お高いんでしょ？
２０万くらいあれば余裕という印象です．
キーボードなどの周辺機器もそろえるとこのくらいかかるかもですが，優先順位つけて少しづつそろえる＆中古なども活用で安く抑えられます！GPUは今かなり高いので，グラフィック負荷高い作業をたくさんするなどしなければつけなくてもOKだと思います．

また，ただ作ってみたい！なんて人には
ラズパイがおすすめです！3万くらいで色々そろうとおもいます．
ラズパイはマイコンの一種で，行っちゃえばちっちゃいパソコンです．これまたちっちゃいマザボにパーツが乗っていてかわいいです．
AIも動かして，エッジAI！なんてこともできるので，
安価に現場にAI入れてみよなんてケースにいいかもですね．
農業×AIなど夢が広がりますね！
子供向けの教育にもおすすめですよ！

# 注意
- マザボとCPUの組み合わせ
最高パフォーマンスが出るマザボとCPUの組み合わせがある程度決まっているので，事前に調べてから購入したほうがいいです．
よほどマザボにこだわりが無ければCPUのスペックや価格を軸に，周辺パーツを決めていくといいと思います．
- マザボのOS対応について
中古でマザボを取りそろえる際，あまり古すぎるものを選ぶと最新windowsのOSが動かないこともあります．確認してから買いましょう！
- メモリ問題
自作PCって数字がたくさん出てきます，何ギガがいいとか，何テラがいいとか・・・悪いこと言わん！メモリは16GBくらいを選ぶとノンストレスです．最低でも8GBは欲しいですね．
- SSDっているの？
最悪HDDだけでもいいよ！SSDやHDDなどの記憶領域はいくらあっても損ではないので，後から買い足せばよし．
- OSってどうなるの？
自作PCは中身のOSも自分で入れる必要有ります．USBとかに起動するOSを入れておいて，BIOSといわれるマザボに紐づくソフトウェアを操作して，起動します．この部分についてはまた今度記事にまとめます～！
- 興味持ったからもっと詳しいこと知りたいんだけど！！
自作PC虎の巻をメルカリなどで買ってみてください．すぐ作れます．

# 最後に・・・
意外と簡単にチャレンジできるので皆さんも自作してみてはどうでしょうか？自分が選んだパーツで構成したかわいいデバイスに囲まれるだけでも日常が豊かになります．
またどこかのタイミングで今度は環境構築周りの話をまとめられたらと思います！
ではでは．
[toc] を使ったら WordPress 投稿が『返答が正しい JSON レスポンスではありません』で保存できなくなった話

## ― Table of Contents Plus × Gutenberg × REST API 地雷の正体と対処法

### 発生するエラーの状況
 - WordPressのブロックエディタ(Gutenberg)で投稿を保存しようとすると
 - 「更新に失敗しました。返答が正しい JSON レスポンスではありません」
 - Table of Contents Plus (TOC+)プラグインを使用している

### 再現条件と環境
- WordPress 8.1.2
- テーマ: オリジナルテーマ
- Gutenbergエディタ使用
- TOC+ バージョン: 2411.1
- 仮ドメイン + 非SSL

### エラーの技術的原因
- GutenbergはREST APIで投稿を保存する
- REST APIの`rendered`フィールドにHTMLが含まれる
- `[toc]`は`<!--TOC-->`に置き換われ、`the_content()`フィルターでHTMLに変換される
- そのHTMLの中に置き換符号の欠如やJSONと互換性のない文字列があると`JSON.parse()`が爆死

### やった対策一覧
#### プラグイン側
- TOC+ の設定画面で「REST APIに直接含める」を OFFにする

#### テーマ側
- `rest_prepare_post`フィルターでREST APIの`rendered`だけTOC+を取り除いて再生成

**5. 最終的な回避コード**
```php
add_filter( 'rest_prepare_post', function( \$response, \$post, \$request ) {
  remove_filter( 'the_content', [ \$GLOBALS['toc_plus'], 'the_content' ], 100 );
  \$response->data['content']['rendered'] = apply_filters( 'the_content', \$post->post_content );
  add_filter( 'the_content', [ \$GLOBALS['toc_plus'], 'the_content' ], 100 );
  return \$response;
}, 10, 3 );
```
これを`functions.php`に追記することで、
- 投稿本文に`[toc]`は残せる
- 表示もそのまま
- でもREST APIレスポンスだけTOCを削除でき、JSON.parse()エラーを防げる

### 補足: SSL環境での違い、Classic Editorとの関係
- SSLでない場合:`SameSite=Lax`のCookieがRESTで送れず、未認証として返答が戻り、Gutenbergが爆死することがある
- Classic EditorならRESTを通らず、そもそもこの問題が起こらない

### まとめと教訓
- 表示に問題がなくても、REST APIの`rendered`が正式でないとJSONエラーは起きる
- TOC+ の出力はちょっと前のタイミングでREST系には向いてない
- 「入力は売る、出力はメンテする」の大事さを思い知らされた
- いずれ直したのも、分析してコード書いたのも、しんどかったのも、結局ずっと現場にいた自分だった

使う側はわけもわからん。説明もない。でも実際には、たったこれだけで？ってなる1行のフィルターで、WordPress保存エラーは消える。
「保存失敗」を、少なくともこの現場からは消したい。
pythonのfoliumパッケージをオフライン仕様に改造し、インタラクティブな地図をオフライン環境で使えるようにする方法

# 1.モチベーション
基本的にインターネット接続ができず、インターネット接続できる端末は物理的に他の端末と切り離されている、というセキュリティ意識が（異常に）高い環境の人に、ニッチなメリットがあると思って書いています。
とりあえずここにコード類はおきました。

https://github.com/igel7/jpn_map_pointer

# 2.趣旨
Pythonで地図を使うとき、インタラクティブな操作（google mapライクな地図操作）を実現する一番メジャーな方法はFoliumパッケージだと思います。しかし、残念ながらFoliumはオンライン環境を前提に作られており、動かすたびにオンライン上のリソース（jsonファイルやcssファイル）を参照しに行くようになっているので、完全オフライン環境だと全然動きません😢

もちろん、単に「オフラインで地図を使いたい！」というだけの場合、Pythonにこだわりがなければ、QGISを使って一旦オンライン環境で必要な地図レイヤーを全部ダウンロードしておいて、そのデータをそのままオフライン環境でも使う、というのが一番手っ取り早い方法だと思います。しかしここでは、あくまでWebアプリみたいなものを作るために、「PythonでFoliumパッケージを使いたい...しかもオフラインで...」というかなりニッチなニーズに向けて方法を解説してみたいと思います。


実は同じ発想で作られた（と思われる）コード↓がgithubにあるのですが、少なくとも私の環境ではうまく動きませんでした。なんか古いし、メンテナンスもされてなさそうです。

https://github.com/robintw/offline_folium


# コード解説
単純化すると、以下2ステップに集約されます。
- ①Foliumパッケージが参照しにいっているオンライン上のリソース（Jsonファイル、CSSファイル）をすべてローカルにDLしてきて、foliumパッケージを改変してそのローカルファイルを毎回参照するように改造する
- ②地図レイヤーは、QGISを使ってOpen Street MapのXYZタイルを必要な倍率のものだけ全部画像としてダウンロードしてローカルに持ってしまう*

※ 私の作った上記githubのリポジトリには、既にOpen Street Mapの2種類の地図の一定の倍率のデータを画像データとして格納してあるので、これを流用すればQGISを使った地図タイルのDL作業は不要。





（詳しい説明を今後加筆予定）
【GitHubActions】指定した時間にバッチ実行したい

# はじめに
指定した時間にバッチ実行できる仕組みを習得しました。今後困らないように備忘録としてまとめました。

# cronとは
UNIX系OS（Linuxなど）に標準で搭載されている**定期的な自動実行を行うための仕組み**

# GithubActionsでcronを使う

**公式ドキュメントより引用**
>schedule イベントを使うと、スケジュールした時刻にワークフローをトリガーできます。

https://docs.github.com/ja/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#schedule

# cronの基本的な書き方

cron: "`分` `時間` `日` `月` `曜日（[0,6]、0は日曜日）` "

```yml:delete-data-auto.yml
name: delete-data-auto

on:
  schedule:
    - cron: "0 21 * * *"
  workflow_dispatch:

jobs:
  delete_data:
    runs-on: ubuntu-latest
    steps:
      - run: echo "cron追加したよ"
```

# 他にもこんな設定ができる

#### X分ごとに1回実行する
最短5分毎にスケジュール実行することが可能

**公式ドキュメントより引用**

>スケジュールされたワークフローを実行できる最短の間隔は、5 分ごとに 1 回です。

```yml
on:
  schedule:
    - cron: "*/5 * * * *" # 5分ごとに実行
```

#### `,`区切りで複数時間設定可能
```yml
on:
  schedule:
    - cron: "0 21,17 * * *" # 21時と17時に実行
  workflow_dispatch:
```

#### 毎時間XX:00に実行する
```yml
on:
  schedule:
    - cron: "0 * * * *" 
  workflow_dispatch:
```
# 注意点
## スケジュール時間はUTC
:::note warn
スケジュール時間は (UTC) で設定される。
**UTC：協定世界時、世界で標準時として使っている時間**
:::

UTCは日本時間(JST)から9時間引いた値
例えば、午前6時に起動したい場合、06:00から9時間引いた21:00を設定
```
日本時間 6:00 → UTC 21:00（前日）
計算：6 - 9 = -3 → 24 + (-3) = 21
```

## scheduleトリガーは遅延しがち
**公式ドキュメントより引用**
>GitHub Actions のワークフローの実行によって高い負荷がかかっている間、schedule イベントが遅延する可能性があります。 高負荷の時間帯には、毎時の開始時点が含まれます。

今後は、`repository_dispatch`を使うようにしたい。

https://zenn.dev/no4_dev/articles/14b295b8dafbfd

https://docs.github.com/ja/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#repository_dispatch

# おわりに
cronって聞いたことあるなあくらいの認識だったのですが、使いこなせるようになったことは大変嬉しいです。
日本時間とUTCを考慮しないといけないのは盲点でした。

# 参考
https://zenn.dev/kisukeyas/articles/6d50c1d015d066

https://docs.github.com/ja/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#schedule

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/crontab.html#tag_20_25_07

https://wa3.i-3-i.info/word11831.html

https://zenn.dev/no4_dev/articles/14b295b8dafbfd
Databricksにデータをアップロードしてみた

## 前提
・利用環境：Databricks

https://www.databricks.com/jp/try-databricks?scid=7018Y000001Fi15QAC&utm_medium=paid+search&utm_source=google&utm_campaign=17377047998&utm_adgroup=138148229998&utm_content=trial&utm_offer=try-databricks&utm_ad=732035937815&utm_term=databricks%20%E3%83%88%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%AB&gad_source=1&gclid=CjwKCAiA8Lu9BhA8EiwAag16b8b3zbkIb3V7gp-8VUwKukXnhtVZRQ-1RY8SbETmGVgNT4bQramYmRoCX5wQAvD_BwE#account

## 参考ドキュメント

https://docs.databricks.com/aws/ja/ingestion/file-upload/

## 操作手順（動画）

<iframe width="560" height="315" src="https://www.youtube.com/embed/tChzJQY_pF0?si=hRHK1PzQosuyO_Zq" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
「手探りでCUI OS作成に挑む」処理説明篇　関数呼び出し時に PUSHA / POPA を使う理由

## 「手探りでCUI OS作成に挑む」連載

この記事は「手探りでCUI OS作成に挑む」連載の一部です。
全体の目次は[「手探りでCUI OS作成に挑む」連載目次](https://qiita.com/earthen94/items/b5d77f98f0cf85a13346)を御覧下さい。

## なぜレジスタを退避する必要があるのか？
関数を呼び出すと、呼び出し元（caller）と呼び出された関数（callee）が同じレジスタを使う。
レジスタの値を上書きしてしまうと、呼び出し元に戻ったときにデータが壊れてしまう。
```
; 呼び出し元
mov ax, 0x1234
call my_func
; ここで ax を使いたい → でも関数が ax を書き換えていたら値が消える
```
## PUSHA / POPAの検証コード
```boot.asm
org 0x7C00

start:
    ; レジスタに値を入れる
    mov ax, 'A'
    mov bx, 'B'
    mov cx, 'C'
    mov dx, 'D'
    call print_regs  ; レジスタの値を画面出力（A B C D）

    ; レジスタの値保存（pusha）
    pusha

    ; レジスタの値を変更（X）
    mov ax, 'X'
    mov bx, 'X'
    mov cx, 'X'
    mov dx, 'X'
    call print_regs  ; 変更後の値を画面出力（X X X X）

    ; レジスタの値復元（popa）
    popa
    call print_regs  ; A B C Dに戻っている

    jmp $  ; CPU停止

;-------------------------------
print_regs:
    ; AX 低 8 ビット（al）
    mov ah, 0x0E
    mov al, ah  ; ax='A'（0x0041），ah=0x00，al=0x41（'A'）
    int 0x10

    ; 空白出力
    mov al, ' '
    int 0x10

    ; BX 低 8 ビット（bl）
    mov al, bl  ; bx='B'（0x0042），bl=0x42（'B'）
    int 0x10

    mov al, ' '
    int 0x10

    ; CX 低 8 ビット（cl）
    mov al, cl  ; cx='C'（0x0043），cl=0x43（'C'）
    int 0x10

    mov al, ' '
    int 0x10

    ; DX 的低 8 ビット（dl）
    mov al, dl  ; dx='D'（0x0044），dl=0x44（'D'）
    int 0x10

    ; 改行
    mov al, 13
    int 0x10
    mov al, 10
    int 0x10
    ret

;-------------------------------
times 510-($-$$) db 0
dw 0xAA55
```

## 動作結果
```
ubuntu@ubuntu:~/kaihatsu/test2$ nasm -f bin boot.asm -o boot.bin
ubuntu@ubuntu:~/kaihatsu/test2$ qemu-system-i386 -fda boot.bin
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054974/1e18dce7-85ef-48b1-a3ea-b80d2377de4b.png)
度分秒めくりキー、ゲーム搭載の小学生計算器、人教社PEP-190

ドットマトリクスタイプの算数学習用電卓、続いては人教社PEP-190と天雁TY-190ESを取り上げる。

## 両者の機能は同一
人教社PEP-190（右）と天雁TY-190ES（左）を並べると、色が違うだけでサイズからキー形状に至るまで同一であることがわかる。機能やバグも同一。
![pep190-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/f214cdec-88e2-4658-ba78-565e5c91cc3c.png)
よって、以下の機能紹介は人教社の画面のみ紹介する。

## 分数入力
deli DL-1726と同様、[a]が帯分数キー、[$\frac{b}{c}$]が真分数・仮分数キー。
入力は分母→分子の順。
先に整数部や分母を入力しておくことはできず、分数のテンプレートを出すキーなので、前者は[$a\frac{c}{b}$]と表記すべきキーであることも同じである。

なお、7セグ小学生計算器の仕様を引きずっているのか、帯分数の整数部・分母・分子はそれぞれ4桁までしか入力できない。

そしてこの検証中、$1234\frac{9012}{5678}$と入力したところ、なぜか$-1234\frac{9012}{5678}$と表示され、さらに×2したところ$3\frac{495}{2839}$となるバグを発見した。
帯分数の整数部・分母・分子のいずれかを3桁にした際には発生しないことから、全て4桁で入力した場合に起きるバグのようだ。
![pep190-6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/f902fbe2-7093-457a-8d7e-48a8bf88c59e.jpeg)

## 手動約分
入力した分数は[=]キーを押しても自動約分はされない（計算後の分数は自動約分される）。
可約分数であれば分数の右側に白抜き下矢印が表示され、約分可能であることを示す。
[SIMP]キーを押すたびに F=割った数； 約分後の分数 が表示され、さらに約分できる場合は白抜き下矢印が表示される（結果表示に関してはfx-55 PLUSや手動約分可能なカシオ関数電卓と同様の表示）。
なお、既約分数になる直前の F=割った数； がなぜか小さい文字で表示される。
![pep190-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/b45074d1-fcc4-46ce-9a48-4b3f58b11d3e.jpeg)

## 余り計算
[÷R]キーで余り計算。
Q=商;R=余り で表示される。
![pep190-7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/42952665-64f7-48bb-bcd7-c825758b47e9.jpeg)
商が6桁まで表示可能。

## 度分秒入力・計算
[HMS]キーはめくり方式となっている。押すたびに °→′→″ と記号が変化するため、15′のように分のみ・秒のみの入力も度（時）など上位部分を省略して直接行える。関数電卓にも取り入れてほしい方式である。
![pep190-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/e8d230b5-eaec-432e-a336-cf9181605eba.jpeg)

なお、度分秒計算は式を直接入力した場合は問題なく行えるが、直前の答に続けて計算させた場合、ラストアンサーの度分秒が全て ° に化けてしまうためエラーが発生してしまう（裏技的に、結果を[HMS]で小数に変換したのち演算子を入力してラストアンサー取り込み→続きの度分秒を入力→結果が小数で表示されるので[HMS]で度分秒に戻す、という方法もあるが…）。
![pep190-8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/2440a72a-b8b3-4be7-a567-2f89ae2ef41c.jpeg)


## ゲーム
シャープの一部関数電卓にはドリル機能が搭載されているが、本機にもゲーム機能が搭載されている。

[GAME]キーを押すと、INT（整数）、Frac（分数）、Float（小数）を選択するメニューが出てくる。
最初は足し算のみ出題されるが、[-][×][÷]で他の四則演算の出題に変更可能。
3～4桁の問題が出るなど、手強い出題もある。
正答であればチェックマーク、誤答であれば×が表示される（既約分数で答えないと×）。
![pep190-4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/ea681af5-2988-41a7-b9bc-a787d0c52c99.jpeg)
この電卓には[ANS]キーが付いているが、ゲームでの答表示に使われるだけで、関数電卓にあるアンサーメモリーキーとしては使えない。

## 小数点以下桁数固定
[FIX]キーで指定できるが、なせが0桁～4桁しか指定できない。
桁数固定解除は[.]キーではなく、桁数指定画面でもう一度[FIX]キーを押す。
![pep190-5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/ddb526c4-2e2f-42a8-9a6b-a01bc067862d.jpeg)

## 使いものにならないストップウォッチ機能
DL-1726と同様のストップウォッチ機能を搭載しているが、オートパワーオフで計時が打ち切られる。
定期的にキーを押さない限り約6分で消えてしまうのでほとんど使いものにならない。

## バグがあるので注意が必要
人教社の名前が付いていることから教科書の例示機種になっていると思われるが、一部着目すべき機能があるものの、全体に作り込みが甘い。

分数や度分秒計算にバグがあることから、おすすめできない機種と言わざるを得ない。
【2025/05/14】AWS学習メモ：サービス・セキュリティ・データ転送編

# # 【2025/05/14】AWS学習メモ：サービス・セキュリティ・データ転送編

## はじめに

本記事では、AWSにおけるアクセス管理、データ転送、セキュリティ、分散処理などについて学んだ内容をまとめました。クラウドアーキテクトや開発者の方に役立つトピックをピックアップしています。

---

## 🔐 アクセス管理

### 1. 異なるAWSアカウントにSQSキューへのアクセスを許可

- SQSアクセスポリシーを利用して、他のAWSアカウントにキューへのアクセス権限を付与可能。
- アカウントIDを指定して、メッセージの送信・受信を制御できる。

---

## 🌍 CDN・ネットワーク高速化

### 2. CloudFrontによるファイル圧縮

- 各エッジロケーションでファイルを自動的に圧縮。
- レスポンスサイズの削減によって、配信速度と帯域使用量を最適化。

### 3. Accelerated サイト間VPN

- AWS Global Accelerator を活用した高性能な VPN。
- 通信は AWS のグローバルネットワーク経由で行われるため、**高い可用性と低レイテンシ**を実現。

---

## 🔄 データ転送・統合

### 4. Amazon AppFlow

- サードパーティSaaS（例：Salesforce, Slack など）と AWS サービス（S3など）間のデータ転送を自動化。
- GUIベースでノーコードに近い操作が可能。
- Software as a Service (SaaS) アプリケーションとAWSサービス間のデータ転送を自動化するフローを作成できる。

### 5. AWS DataSync

- オンプレミス⇔AWS間での大容量データ転送を簡素化・自動化。
- NFS、SMB、Amazon S3、EFS、FSx などをサポート。
- 高スループット・暗号化対応・整合性チェック機能もあり。

---

## ⚡ 分散処理とリアルタイム分析

### 6. Amazon EMR + Apache Spark

- EMR上でSparkを実行し、**大規模データのリアルタイム処理**を実現。
- スケーラブルなデータ処理パイプラインやバッチ処理に最適。

---

## 💾 データベース

### 7. Amazon DynamoDB

- サーバーレス・NoSQLデータベース。
- 高速・スケーラブルな処理が可能で、**社員証スキャンのような高頻度アクセス系**にも適している。
- 自動スケーリング、マルチリージョン対応。

---

## 🛡️ セキュリティ

### 8. AWS Shield Response Team (SRT)

- AWS Shield Advanced の利用者向けに、専門家がDDoS攻撃対応を支援。
- 攻撃発生時には24時間365日対応のサポートを提供。

---

## おわりに

今回は、アクセス管理、データ転送、セキュリティ、リアルタイム分析など、実務や試験において重要なAWSの機能を紹介しました。特に他アカウントとの連携やデータの自動フロー構築は現場で役立つ知識です。

---

## 🏷️ 推奨タグ



## はじめに

本記事では、AWSにおけるアクセス管理、データ転送、セキュリティ、分散処理などについて学んだ内容をまとめました。クラウドアーキテクトや開発者の方に役立つトピックをピックアップしています。

---

## 🔐 アクセス管理

### 1. 異なるAWSアカウントにSQSキューへのアクセスを許可

- SQSアクセスポリシーを利用して、他のAWSアカウントにキューへのアクセス権限を付与可能。
- アカウントIDを指定して、メッセージの送信・受信を制御できる。

---

## 🌍 CDN・ネットワーク高速化

### 2. CloudFrontによるファイル圧縮

- 各エッジロケーションでファイルを自動的に圧縮。
- レスポンスサイズの削減によって、配信速度と帯域使用量を最適化。

### 3. Accelerated サイト間VPN

- AWS Global Accelerator を活用した高性能な VPN。
- 通信は AWS のグローバルネットワーク経由で行われるため、**高い可用性と低レイテンシ**を実現。

---

## 🔄 データ転送・統合

### 4. Amazon AppFlow

- サードパーティSaaS（例：Salesforce, Slack など）と AWS サービス（S3など）間のデータ転送を自動化。
- GUIベースでノーコードに近い操作が可能。
- Software as a Service (SaaS) アプリケーションとAWSサービス間のデータ転送を自動化するフローを作成できる。

### 5. AWS DataSync

- オンプレミス⇔AWS間での大容量データ転送を簡素化・自動化。
- NFS、SMB、Amazon S3、EFS、FSx などをサポート。
- 高スループット・暗号化対応・整合性チェック機能もあり。

---

## ⚡ 分散処理とリアルタイム分析

### 6. Amazon EMR + Apache Spark

- EMR上でSparkを実行し、**大規模データのリアルタイム処理**を実現。
- スケーラブルなデータ処理パイプラインやバッチ処理に最適。

---

## 💾 データベース

### 7. Amazon DynamoDB

- サーバーレス・NoSQLデータベース。
- 高速・スケーラブルな処理が可能で、**社員証スキャンのような高頻度アクセス系**にも適している。
- 自動スケーリング、マルチリージョン対応。

---

## 🛡️ セキュリティ

### 8. AWS Shield Response Team (SRT)

- AWS Shield Advanced の利用者向けに、専門家がDDoS攻撃対応を支援。
- 攻撃発生時には24時間365日対応のサポートを提供。

---

## おわりに

今回は、アクセス管理、データ転送、セキュリティ、リアルタイム分析など、実務や試験において重要なAWSの機能を紹介しました。特に他アカウントとの連携やデータの自動フロー構築は現場で役立つ知識です。

---

## 🏷️ 推奨タグ
【2025/05/14】基本情報技術者試験 用語メモ

# 【2025/05/14】基本情報技術者試験 用語メモ

## ✅ PDPC（Process Decision Program Chart）

- **意味**：問題を前もって考えて、どうするか決めておく方法。
- **用途**：トラブルが起こる可能性に備えて、対策をあらかじめ決めておく計画手法。

---

## ✅ デルファイ法（Delphi Method）

- **意味**：いろんな専門家にこっそりアンケートして、何回かくり返しながら意見をまとめていく方法。
- **ポイント**：匿名性を保ちつつ、複数回のフィードバックで合意形成を図る。

---

## ✅ イテレーション（Iteration）

- **意味**：同じ作業をくり返すこと。
- **用途**：アジャイル開発などで、試行錯誤を繰り返して完成度を高める際に使われる。

---

## ✅ RSA暗号

- **意味**：みんなに見せる「公開鍵」と、自分だけが持ってる「秘密鍵」で成り立つ暗号方式。
- **特徴**：非対称鍵暗号の代表。公開鍵で暗号化し、秘密鍵で復号する。

---

## ✅ 可用性（Availability）

- **意味**：コンピューターやサービスがちゃんと使える状態になっていること。
- **関連用語**：信頼性・耐障害性・冗長構成などとセットで考える。

---

## ✅ ゲーム理論（Game Theory）

- **意味**：みんながどう動くかを考えて、いちばん良い作戦を考える方法。
- **例**：囚人のジレンマやナッシュ均衡など。

---

## ✅ リエントランス（Reentrancy）

- **意味**：コンピュータープログラムの中で、途中でよび出されても、もう一度ちゃんと動くようになっているしくみ。
- **用途**：マルチスレッド環境での安全な関数設計に重要。

---

## ✅ フラグメンテーション（Fragmentation）

- **意味**：データがバラバラになってしまうこと。
- **種類**：
  - 外部フラグメンテーション：空き領域が細かく分かれて使いづらくなる
  - 内部フラグメンテーション：割り当てた領域の中で未使用部分がある

---
## ✅ IPアドレス

- **意味**：機器や端末の「インターネット上の住所」となる識別番号。
- **特徴**：
  - ネットワーク上の住所（識別番号）
  - 数字で構成される（IPv4の例：`192.168.1.1`）
  - `0〜255`の数字が4つ、ドットで区切られる形式
  - **プライベートIPアドレス**：内部ネットワーク専用（例：家庭内LANなど）
  - **パブリックIPアドレス**：インターネットに接続するためのグローバルなアドレス
リーダブルコード（第8章）の学び

## はじめに

昨日に続き、今日も学習時間がほとんど取れなかった。
他の予定があったとはいえ、時間を確保しようと思えばできたはずで、そこは自分に甘えがあったと感じる。

とはいえ、「何かひとつでも学んで1日を終える」というスタンスを大切にしたい。
今日は、リーダブルコードの第8章の冒頭だけを読み、その中で得た学びを整理してみる。

## 要約変数とは？

第8章の鍵となる考え方は、

> 「巨大な式は飲み込みやすい大きさに分割する」

というものだった。
ただし、巨大な式でなくとも「要約」のために変数を使うというアプローチが紹介されており、非常に参考になった。

### 具体例

たとえば、以下のようなコードがあるとする。

```java
if (request.user.id == document.owner_id) {
    // ユーザーはこの文書を編集できる
}
```

この式はそれほど長くはないが、「request」「user」「id」「document」「owner\_id」といった5つの要素が関係しており、少しだけ読むのに時間がかかる。

ここで、「要約変数」を使って次のように書き換える。

```java
final boolean user_owns_document = (request.user.id == document.owner_id);

if (user_owns_document) {
    // ユーザーはこの文書を編集できる
}
```

このように変数に意味を持たせることで、条件の意図がより明確になる。

## おわりに

今回学んだ「要約変数」という考え方は、今まであまり意識したことがなかった。
短い式でも、他人が読みやすくなるような変数名を使って要約することで、コードの可読性が上がることを実感できた。

今後、自分のコードでも積極的に取り入れていきたい。
楽天・AmazonのAPI取得方法

今回せどりのリサーチアプリ開発を進めるということで、Amazonと楽天のAPIの取得を実施いたしまして、わかりやすい記事を参考に概要がわかるようにまとめてみました。

# 手に入れたいキー

- NEXT_PUBLIC_RAKUTEN_APPLICATION_ID
- NEXT_PUBLIC_AMAZON_ACCESS_KEY
- NEXT_PUBLIC_AMAZON_SECRET_KEY
- NEXT_PUBLIC_AMAZON_PARTNER_TAG

# 準備するアカウントとそれぞれのキーの用途一覧
| APIキー名                                     | 必要なアカウント           | API名                            | 用途                        |
| ------------------------------------------ | ------------------ | ------------------------------- | ------------------------- |
| **NEXT\_PUBLIC\_RAKUTEN\_APPLICATION\_ID** | 楽天デベロッパーアカウント      | **楽天市場API（Rakuten Developers）** | 楽天市場の商品情報検索、ランキング取得       |
| **NEXT\_PUBLIC\_AMAZON\_ACCESS\_KEY**      | AWSアカウント + IAMユーザー + 出品用アカウント | **Amazon SP-API**               | Amazonの商品情報取得（販売者API）     |
| **NEXT\_PUBLIC\_AMAZON\_SECRET\_KEY**      | AWSアカウント + IAMユーザー + 出品用アカウント | **Amazon SP-API**               | SP-APIの認証（署名）             |
| **NEXT\_PUBLIC\_AMAZON\_PARTNER\_TAG**     | Amazonアソシエイトアカウント  | **Amazon PA-API**               | Amazonの商品情報取得（アフィリエイトAPI） |


# API取得方法

## 楽天市場API

https://wp-ap.net/help/rakuten-appli-id-affili-id/

## Amazon SP-API

1.AWSアカウント作成

https://qiita.com/ti_and6id/items/7aaf34074346c7e5c7cc
    
2.IAMユーザー作成 + SP-API取得

https://qiita.com/yamasakk/items/3060d22faeed8e05ebe4
    
3.Amazon出品用アカウント作成

https://bxo.co.jp/magazine/137

## **Amazon PA-API**

1. Amazonアソシエイトアカウント作成
    
https://qiita.com/ti_and6id/items/7aaf34074346c7e5c7cc
    
2. PA-API取得
- 注意点
    - トラッキングID＝PA-API　なのでトラッキングIDの取得をします。
- 手順
    - アソシエイト画面のメニューバー→ アカウント→ アカウントの管理→ トラッキングIDの管理→ トラッキングIDを追加する→ 任意の名前設定→ 作成　完了！

# ファイルにキー入力

プロジェクトに.env.localファイルを作成し、それぞれ下記のようにキーを入力する。

```jsx
NEXT_PUBLIC_RAKUTEN_APPLICATION_ID=取得したキー
NEXT_PUBLIC_AMAZON_ACCESS_KEY=取得したキー
NEXT_PUBLIC_AMAZON_SECRET_KEY=取得したキー
NEXT_PUBLIC_AMAZON_PARTNER_TAG=取得したキー
```

以上！！！
参考にさせていただいた方、ありがとうございました。
ジェネリック型のタイプ情報を取得する

任意型のデータをその実際の型情報を元に処理を行う場合、型情報としてTypeのインスタンスが必要になることがあります。
例えば、Stringクラスを表す`Type<String>`のインスタンスは

```kotlin
String::class.java
```

とすることで`Class<String>`を取得することができます。（ClassクラスはTypeインターフェースを実装しています）しかし、ジェネリクス型のタイプパラメータを含めたTypeのインスタンスは、直接取得する手段が提供されていません。

例えば、`List<String>`のType`Type<List<String>>`が必要な場合、

```kotlin
List<String>::class.java
```

という記述はコンパイルエラーとなります。
このタイプパラメータを含めたType情報はParameterizedTypeとなります。

どうやって取得すれば良いでしょうか？

# アブストラクトクラスを実装して取得する

ParameterizedTypeを返すメソッドとして、Classクラスの、`getGenericSuperclass()`があります。
これはそのクラスの親クラスの情報となりますので、`Hoge<T>`を継承した`Fuga`から呼び出した場合に、`Type<Hoge<T>>`を得ることができます。
そして、ParameterizedTypeは`getActualTypeArguments()`というメソッドを持っており、そのジェネリクス型の型パラメータのTypeを取得することができ、この型引数もジェネリクス型の場合、ParameterizedTypeが返却されます。

そこで、型引数を持つabstractクラスを作成し、その型引数に取得したいジェネリクス型を指定して継承を行い、`getGenericSuperclass()`でParameterizedTypeを取得し、`getActualTypeArguments()[0]`で一つ目の型引数のTypeを取得する。という手順を踏むことで、ジェネリクス型の`Type`を取得することができます。

以下のような、abstractクラスを作成し

```kotlin
abstract class TypeToken<T> {
    fun getType(): Type =
        (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0]
}
```

以下のように、インライン実装して`getType()`を呼び出すことで取得できます。

```kotlin
object : TypeToken<List<String>>() {}.getType()
```

Kotlinではインライン関数を使って、以下のように、`actualTypeOf()`メソッドを作成すると

```kotlin
inline fun <reified T: Any> actualTypeOf(): Type = object : TypeToken<T>() {}.getType()

abstract class TypeToken<T> {
    fun getType(): Type =
        (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0]
}
```

```kotlin
actualTypeOf<List<String>>()
```

と、よりスマートに取得できます。

# KTypeから変換する

Javaの範囲ではややこしい実装が必要ですが、現在のKotlinでは、`typeOf()`という`KType`を取得するメソッドが用意されています。KTypeからTypeを取得することができるので

```kotlin
@OptIn(ExperimentalStdlibApi::class)
typeOf<List<String>>().javaType
```

とすることで、`Type<List<String>>`のインスタンスを取得することができます。`javaType`はまだ実験段階のため、`@OptIn(ExperimentalStdlibApi::class)`をつけて利用する必要があります。

Experimentalが外れれば、この方法でよさそうです

---

以上です。
Macで複数バージョンのPythonの開発環境を構築

（ターミナルを起動して、以下のコマンドを順に実行）
# パッケージマネージャーHomebrewをインストール

```
% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

- パスを通す
```
% echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zshrc
% source ~/.zshrc
```
- バージョンが表示されるか確認
```
% brew --version  
Homebrew 4.5.2
```

# Pythonのバージョン管理ツールpyenvと必要ライブラリをインストール
```
% brew install pyenv zlib xz
```

- バージョンが表示されるか確認
```
% pyenv --version 
pyenv 2.5.7
```

- 1行ずつ実行してパスを通す
```

% echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
% echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
% echo 'eval "$(pyenv init -)"' >> ~/.zshrc
% source ~/.zshrc
```
- 環境変数を確認
```
% env  
PYENV_ROOT=/Users/minghuajin/.pyenv
...
```

- インストール可能pythonバージョン確認
例：3.13(現時点AmazonのLambdaで使用できる最新バージョン)
```
% pyenv install --list | grep -E '^\s*3\.1(2|3)\.'
  3.12.0
  3.12.1
  3.12.2
  3.12.3
  3.12.4
  3.12.5
  3.12.6
  3.12.7
  3.12.8
  3.12.9
  3.12.10
  3.13.0
  3.13.0t
  3.13.1
  3.13.1t
  3.13.2
  3.13.2t
  3.13.3
  3.13.3t
```
- pythonの指定バージョンのインストール&Pythonバージョン適用
```
% pyenv install 3.13.3
% pyenv install 3.12.10
% pyenv global 3.13.3
```
- インストールバージョンの確認
```
% pyenv versions
  system
  3.12.10
* 3.13.3
```
- グローバル設定したPythonのバージョンを確認
```
% python --version                                         
Python 3.13.3
```
数学における単純性から生まれる複雑性

現在、コンビネータ理論の問題を解いて勉強している。そこで不思議に思うのが、概念が簡単なのになぜか複雑な式が生まれてしまうということだ。

例えば、次の式だ。
$$D\equiv[x,y,z].zxy$$
この$D$は変数$x,y,z$を受け取って変数$z,x,y$を返す関数だ。つまり、変数の内容を変えずに順序のみを変更しているだけのコンビネータだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3734194/0b766bd1-d01a-4cf3-aed7-7716ee070aaf.png)

### I,K,Sコンビネータ
コンビネータ理論とは少数のコンビネータ$I,K,S$のみで計算をしようとする試みだ。
各コンビネータの特徴は以下の通り：
$Ix\rightarrow x$
$Kxy\rightarrow x$
$Sxyz\rightarrow xz(yz)$

実際$D$コンビネータの計算については、[この記事](https://qiita.com/Trubetzkoy/items/f5370c885e5f16da43b3)を参考にしてほしい。

結論のみを示すと、$D$は次のように$I,K,S$のみで表される。
$$D\equiv[x,y,z].zxy\equiv[x].([y].([z].zxy)))$$

$$\equiv S(S(KS)(S(KK)(S(KS)(S(K(SI))K)))) (KK)$$となる。これはまるで呪文だ。

### 複雑さについての考察
単に３つの変数を巡回的に入れ替えているだけなのに、コンビネータの式がこんなに複雑になるとは非常に不思議だ。この複雑性は、どこから来るのだろうか。コンビネータの数を少なくしすぎたせいであろうか。それとも本質的にコンビネータの組み合わせ式は複雑になってしまうのだろうか。

考えたところ以下の点が挙げられる。
(1)本質的に入れ替え操作は難しいので、式が複雑になる。
(2)コンビネータを$S,K,I$に絞りすぎのため、式が複雑になる。
(3)ラムダ計算にもとづくコンビネータ理論は、内部状態を持たない。途中経過の値を維持できないので、式の形として保存しなけらばならないので複雑になる。チューリング機械に基づくvon Neumann型機械は値を対比するために記憶領域（メモリー）があるので、計算途中の値の一時保持には問題がない。
確かに、von Neumann型に基づく手続き型プログラミング言語であれば、以下のように記憶レジスターを使って書ける。
```
a := x;
x := z;
z := y;
y := a;
```
(4)自然言語でこの操作を表現するときに「ずらす」や「巡回させる」などの語彙で説明することができる。しかし、このことが可能なのは言語での高度な抽象化が条件となっている。アメリカ・インディアンの言語などにはそのような表現がない場合もある（漢語よ、ありがとう）。いかに我々が抽象的な言葉を意識せずに使っているか思い知らされる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3734194/e538ac08-54bf-4313-badb-42ca2c6bbf1c.png)
読書記録：良いコード/悪いコードで学ぶ設計入門


https://www.amazon.co.jp/改訂新版-良いコード%EF%BC%8F悪いコードで学ぶ設計入門-―保守しやすい-成長し続けるコードの書き方-仙塲-大也/dp/4297146223

私は主にVBA、いわゆるエクセルマクロで業務改善ツールを作っている、非エンジニアです。
VBAという言語使用や、独学・非エンジニアという生い立ちも相まって、あれをしろこれをしろという手続き型のプログラミングをしております。
一応、オブジェクト指向という考え方があるらしきことは見聞きしているので、プロシージャを分割してみたり、クラスモジュールを使ってオブジェクト指向の真似事をしてみたり、自分なりの努力はしてきました。
しかしながら、今回読んだこの本、目が醒めるような衝撃を受けたので紹介させていただきます。

この本は、クラスをどう設計すべきか？変化に対応できる柔軟で強固なプログラムをどう構築するか？ということを、親しみやすいRPGなどを例に解説しています。
特に感銘を受けたのが、「ライブラリの内部実装がどうなっているかについて、いちいち気になるものでしょうか。」というところ。
本書では、細かく緻密にクラスを設計するよう説いているので、「そうではなく、挙動を一挙に書き連ねてしまった方が読みやすいのでは？」と思ってしまいがちなのですが、そもそも内部実装を検証しなくても良いくらい信頼度の高いクラスを設計すべし、という思想に感嘆しました。

きっと本職のエンジニア、プログラマーの方々にも有益だと思いますので、ぜひチェックしてみてください！
私ももう一度読み直して、非エンジニアとはいえ、設計についての理解を深めていきたいです！
Conformとshadcn-uiのSelectコンポーネントで起きた動作不良を解決！

## 発生した問題

conformの`useForm`を用いてフォームを管理する際、セレクトコンポーネント（Shadcn UI/Radix UIベース）の選択状態が正しく反映されない問題が発生しました。具体的には次のような状況です：

1. セレクトボックスで値を選択する
2. 別の値を選択しようとする
3. UIには最初に選択した値が表示されたままになる

## 原因

調べてみた感じ、以下の問題っぽかったです。

1. **イベント発火の問題**：
   - Conformはネイティブフォームイベント（input、change、blur）を監視して状態を管理している
   - カスタムUIコンポーネントはこれらのイベントを自動的に発火しない
  
## 解決策
（例）：

```tsx
export const ExampleSelect: React.FC<ExampleSelectProps> = ({
  options,
  placeholder = "選択してください",
  label,
  meta,
}) => {
  const control = useInputControl(meta);
  const id = useId();

  const handleValueChange = (selectedValue: string) => {
    if (selectedValue === "_blank" || selectedValue === "") {
      control.change(undefined);
    } else {
      control.change(selectedValue);
    }
    // フォーカスとブラーイベントを明示的に発火
    control.focus();
    control.blur();
  };

  // control.valueを使用して現在の値を取得
  const currentValue = control.value ?? "";

  return (
    <div className="flex items-center gap-2">
      {/* ... */}
      <Select
        name={meta.name}
        value={currentValue}
        onValueChange={handleValueChange}
      >
        {/* ... */}
      </Select>
    </div>
  );
};
```

## 重要なポイント

1. **`useInputControl`フックの活用**：
   - Conformが提供する`useInputControl`フックを使用して入力制御を行う
   - `control.value`を参照することで常に最新の値を取得

2. **イベントの明示的な発火**：
   - `control.change()`：値を更新し、changeとinputイベントを発火
   - `control.focus()`：focusとfocusinイベントを発火
   - `control.blur()`：blurとfocusoutイベントを発火

3. **イベントの順序**：
   - 値の変更後に`focus()`→`blur()`の順で呼び出すことで、Conformに状態変更を確実に通知

## なぜこれで解決したのか

shadcn-uiはネイティブHTML要素とは異なり、ブラウザの標準的なフォームイベントを自動的にしないみたいです。

Conformはこれらのイベントを監視して状態を管理しているため、明示的にイベントを発火させる必要があります。

`control.focus()`と`control.blur()`を連続して呼び出すことで、Conformに「このフィールドにフォーカスが当たり、その後フォーカスが外れた」ことを通知します。これにより、Conformは内部状態を更新し、UIに反映させることができます。

## 参考資料

- Conformの公式ドキュメント「UI Librariesとの統合」
  https://conform.guide/integration/ui-libraries
- useInputControlのAPIリファレンス
  https://conform.guide/api/react/useInputControl

## まとめ

shadcn-uiとConformを統合する際は、以下の点に注意する必要がありそうです：

1. `useInputControl`フックを使用して入力制御を行う
2. 値の変更時にイベントを明示的に発火させる
3. 値の参照には`control.value`を使用する
Docker環境でのコンテナ間通信とHTTPベースのマルチサービス連携構成を理解する

## 🧩 概要

この記事では、**複数のコンテナを連携させるWebアプリケーション構成**において、**サービス間通信をHTTPで行う仕組み**を整理し、**なぜ1つのAPIエンドポイントだけでデータのやりとりが成立するのか**を具体的に解説します。

* コンテナ間の通信はどうなっているの？
* なぜ `POST /generate_something` だけで成立するの？
* Dockerネットワーク上での名前解決やCORSはどう処理するの？

といった疑問に答える内容です。

---

## 🧱 システム構成（抽象化）

```
[Browser]
   ↓ HTTP (Fetch)
[Frontend: React+Vite] (port:5173)
   ↓ HTTP (POST)
[AI API: FastAPI + LLM] (port:8005)
   ↓ SDK
[LLM Provider API (e.g. Bedrock)]
```

* フロントエンド：ユーザー入力の収集とUI表示
* AI API：HTTPリクエストを受け、AI処理を行って結果を返却
* LLM Provider：生成AIの実行基盤（外部API）

---

## 🔁 通信フローの解説

### 📤 フロントエンド → AI API（HTTP POST）

```ts
await fetch("http://localhost:8005/generate_something", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    answers: {
      "1": "週末に山に登った",
      "2": "リフレッシュできた"
    }
  })
});
```

* ブラウザ上のReactアプリが、HTTP POSTでAPIを呼び出します
* JSON形式の入力を、AI APIに一括送信します

---

### 🧠 AI API → LLMプロバイダ（SDK経由）

* FastAPIがPOSTされたデータを受け取ります
* SDK（例：LangChainやboto3など）を通じて、外部のLLM APIを呼び出します
* プロンプトとして渡し、生成結果（テキストやMarkdown）を取得します

---

### 📥 結果の返却と表示

* AI APIは、生成された結果をJSONで返却します
* フロントエンドはそれを受け取り、画面にレンダリングして表示します

---

## ❓ なぜ `POST /generate_something` だけで成り立つのか？

### ✅ ステートレスなAPI設計

* AI APIは、**状態（履歴・ユーザー情報）を一切保持しない**
* ユーザーの入力内容すべてを、**フロントエンド側が持ち、まとめてPOST**している
* サーバー側は「入力 → 生成 → 返却」を一発で処理するだけのシンプル構造

### ✅ フロントエンド主導の状態管理

* チャットや回答の履歴は、すべてクライアント側で `useState` や `Zustand` などで保持
* サーバーに「履歴を問い合わせる」必要がないため、GET APIは不要

---

## 🌐 Docker環境での通信の仕組み

### 🐳 サービス名で通信できる

Docker Composeの内部ネットワークでは、サービス名がDNSのように解決されます：

```yaml
services:
  frontend:
    build: ./frontend
    ports:
      - "5173:5173"

  ai:
    build: ./ai
    ports:
      - "8005:8005"
```

→ `frontend` から `http://ai:8000/generate_something` にアクセスできる

### 🔓 CORSの許可

FastAPIでは以下のように `CORSMiddleware` を設定することで、ブラウザからのアクセスを許可します：

```python
from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:5173"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
```

---

## 🔐 AWS認証情報の管理（参考）

AI APIが外部のLLMプロバイダ（例：AWS Bedrock）とやりとりする際、認証情報は `.env` で管理され、Dockerに以下のように渡されます：

```yaml
services:
  ai:
    env_file:
      - .env
```

---

## 🧩 補足：将来的に必要になるかもしれないエンドポイント

| メソッド                  | エンドポイント      | 用途 |
| --------------------- | ------------ | -- |
| `GET /history`        | チャット履歴を取得    |    |
| `POST /chat`          | メッセージを1つずつ送る |    |
| `DELETE /history`     | 履歴をリセットする    |    |
| `POST /session/reset` | セッションを初期化する  |    |

今はフロントが全ての状態を持っているので不要ですが、拡張時には検討価値ありです。

---

## ✅ まとめ

* コンテナ間通信は HTTP が基本で、Docker内ではサービス名で名前解決できる
* シンプルな POST API だけで成り立つのは「状態をサーバーに持たせない設計」だから
* フロントエンドがチャットや履歴の状態を完全に管理しているため、サーバーは stateless に単発処理だけで済む
* 本構成は拡張・疎結合にも強く、マルチリポジトリ・マイクロサービスとの親和性が高い

---

## ✍️ おまけ

このような構成は、AI処理を含むプロダクトのPoCやMVP段階で非常に相性が良く、最初の設計としておすすめです。将来的に認証・ログ保存・セッション管理などが必要になったら、APIを段階的に増やしていくことで、柔軟にスケールできます。
ChatGPTとgit diffでコミットメッセージを自動生成するワークフロー（Copilotなし）

Copilotの無料枠が上限に達したときや、より柔軟な表現でコミットメッセージを作成したいとき、**ChatGPTにgit diffを渡してコミットメッセージを生成する**のが便利です。ここではその手順を紹介します。

---

## 想定環境

- VSCode（またはターミナル）
- Git 管理されているプロジェクト
- ChatGPT Plus（GPT-4）
- Copilotは使わない

---

## 手順

### 1. ステージ済みの差分を取得

```bash
git diff --cached > diff.txt
```

> --cached を付けることで git add 済みの変更だけを対象にします。

---

### 2. diff.txt を VSCode で開く

```bash
code diff.txt
```

---

### 3. ChatGPT に貼って依頼する

```
このdiffに対するコミットメッセージを conventional commits 形式で書いて
```

> GPT-4 は文脈に応じた自然なメッセージや複数行の説明付きも返してくれます。

---

### 4. 生成されたメッセージでコミット

```bash
git commit -m "feat: OCR検証用の画像と出力結果を追加"
```

---

### ワンライナー Tip（macOS）

```bash
git diff --cached | pbcopy
```

これで diff をそのままクリップボードにコピーできます。

---

## この方法のメリット
- Copilotのチャット上限を気にしなくていい
- 日本語／英語の自由なトーンで出力可能
- Conventional Commits に柔軟に対応
- チームの文体に合わせた調整もしやすい

---

## 補足
- 差分が大きいと ChatGPT のトークン制限に引っかかることがあるため、git add -p などで対象を絞るのがおすすめ
- よく使う依頼文（プロンプト）を Notion やスニペットとして保存しておくと効率的

---

## まとめ

ChatGPTはコミットメッセージ生成にも十分活用できます。
特に Copilot の無料枠を使い切った月の後半などには、git diff と ChatGPT を組み合わせたこの方法が実用的です。
PostgreSQLのmulti rangeを利用する

## はじめに
今回はPostgreSQLのmulti rangeを利用してみます。カレンダーのデータを登録する時に便利と聞いたので、まずは触ってみるところから始めます！！
今回は、PostgreSQL16で動かしています。

## Hands-on
今回のHans-onは下記Stepで学んでいきます！
| ステップ | 内容                                                                 |
|----------|----------------------------------------------------------------------|
| Step 1   | イベントに複数の時間帯を登録する（Insert）                          |
| Step 2   | 特定の日時が含まれているかどうかを検索する（@>）                    |
| Step 3   | 時間帯の追加とマージの動作を見る（`||`）                             |
| Step 4   | 指定時間帯と **重なっていない** イベントだけを取得する（`NOT &&`）  |

### Step1 イベントに複数の時間帯を登録する（Insert）

TBLの準備
```shell:
CREATE TABLE public.event_multirange_test (
    id SERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    time_ranges TSMULTIRANGE NOT NULL,
    all_day BOOLEAN NOT NULL DEFAULT FALSE
);
```

```sql:データのinsert
INSERT INTO public.event_multirange_test (title, time_ranges, all_day)
VALUES (
    '午前・午後の打ち合わせ',
    '{[2025-05-16 09:00, 2025-05-16 11:00), [2025-05-16 14:00, 2025-05-16 15:30)}'::tsmultirange,
    FALSE
);
```

```sql:
SELECT * FROM public.event_multirange_test;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/3e1d3bf3-4b99-4ba5-9dda-add6f7727632.png)

:::note info
ここだけだと全然良さがわからないですね。次に行きましょう！
:::

### Step2 特定の日時が含まれているかどうかを検索する（@>）

2025-05-16 09:30」が時間範囲に 含まれているイベントを取得する。

```sql:
SELECT *
FROM public.event_multirange_test
WHERE time_ranges @> TIMESTAMP '2025-05-16 09:30';
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/54bb8f8b-6766-4b28-a04e-abbaafd12a7d.png)
→確かにデータが取得できていますね。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/d61a87b3-c17f-4f55-9047-bbc0b57a8335.png)
→'2025-05-16 08:30'の場合だと、取得はできないですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/3f7d3477-d679-40ce-92dc-38ba219e3836.png)
→開始の9:00は取得できますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/e945ac1f-0ed1-4f7b-974f-b633c37cc636.png)
→開始の11:00は取得できない。
この処理の場合、<strong>左閉・右開区間 [start, end)</strong>で実施しています。
ここ大事なところですね！！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/f31d19da-1438-4d67-9489-1751146e2a5b.png)


## Step3 時間帯の追加とマージの動作を見る（||）
現在の状態
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/5ab4afc5-e903-449b-aa11-0b952df80460.png)



```sql
UPDATE public.event_multirange_test
SET    time_ranges =
       time_ranges
       +
       ('[2025-05-16 11:00,2025-05-16 12:00)'::tsrange)::tsmultirange
WHERE  id = 1;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/7b228081-615d-41d4-b1d0-7867bd562c92.png)
→確かに11:00~12:00が増えていますね。

## Step 4：重なっていないイベントを取得する

```sql:
SELECT *
FROM public.event_multirange_test
WHERE NOT (
  time_ranges && '[2025-05-16 11:30:00, 2025-05-16 12:30:00)'::tsrange
);
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/e80a47ed-6489-496b-9141-81d49a0203db.png)
確かに取得できていないですね。

## 最後に
multi rangeは初めて触りましたが、意外といいですね。幅があるものを検索する場合、2つカラムを持つよりも1つのカラム内で定義できるとSQLがいけるのはいいですね！！
型も関数なの？？【Haskell入門】気になるポイント

## この記事の問い

    Haskellにおいて、「型」や「型の定義」も関数である、と解釈できる？

この記事では、Haskell初心者が地味に嬉しいようなポイントを解説します。
扱うテーマは、上記の問いです。



## 答えから

Haskellにおいて「型」や「型の定義」そのものを「関数」とみなすことは厳密にはできない。

ただし、ある文脈においては「型は関数のように振る舞う」または「関数と似た性質を持つ」と解釈することは可能。


## 型定義は「関数定義」とは異なる構文

```haskell
data Maybe a = Nothing | Just a
```

これは型 Maybe を定義している。ここでの Maybe は 型コンストラクタ と呼ばれ、型を生成する関数のように振る舞う。

関数的な解釈：
Maybe は型を受け取って型を返す、「型レベルの関数」 のように扱える。
→ つまり「型コンストラクタ = 型レベルの関数」という類推が成り立つ。

ただし「関数」そのものではない：
Maybe は「値」を返す関数ではない。

Maybe は型レベルの存在であり、実行時に評価される値の関数とは別の次元である。
（= 型レベル vs 値レベル）。

## 型ファミリーやType Functions（より関数的な型）

Haskellでは型レベルの計算を行う「型ファミリー（type families）」という仕組みがあり、これはより明確に「型レベルの関数」である。

```haskell
type family F a

type instance F Int = Bool
type instance F Bool = Char

```
ここでは `F` は「型を受け取って型を返す関数」そのものとして振る舞っている。


## 型と関数の「カリー化的性質」
関数と同様に、型コンストラクタも部分適用ができる。この点でも関数と似た性質を持つ。
```haskell
Either a b  -- 通常の2引数型コンストラクタ
Either String  -- 1つだけ適用された状態（これは型コンストラクタ `Either String` を得る）
```

## より正確な答え
型、型の定義そのものは関数ではないが、Haskellでは「型コンストラクタ」や「型ファミリー」が関数的に振る舞うため、型を“関数のようなもの”として捉えることができる、というのがより正確な表現となる。


## 補足　やや専門的な「関数」の定義
Haskellにおける「関数」という概念の定義について、やや専門的な立場からまとめておく。

> Haskell における関数とは、型 `a -> b` を持つ式であり、入力 `a` に対して出力 `b` を対応させる写像である。Haskell の関数はカリー化され、純粋で、`first-class citizen` であり、遅延評価・型付きラムダ計算・モナドによる副作用管理といった理論的基盤の上に成り立っている。