OmniAICreator/Qiita-1.07M huggingface dataset:
スクリプト・プログラミング言語の種類についてまとめてみた

# 前置き

エンジニア初学者や、プログラミングに触り始めた方向けの記事になります！
本記事では、**「スクリプト言語・プログラミング言語(インタープリタ型/コンパイル型)
についての記事です。

言語が持つ種類として「そうやって動いてるんだー」っとイメージできるところを目指します。

# スクリプト

Q.スクリプトって何？
A.コンピュータが実行する命令やコマンドを記述したプログラム

機械語(2進数)に翻訳せず、プログラムを直接実行できる言語

:::note info 
**前提知識**
Q.プログラムってどう動いているのか？
A.下記動作をする
```
1.コンピュータにやりたいことを書く
2.コンピュータが理解できるように翻訳する(2進数化)
3.コンピュータが実行する
```
```
詳細は下記項番で説明

翻訳作業を実行する方式=コンパイラ言語
翻訳作業を実行しない方式=インタープリタ言語 ≒ スクリプト言語
```

:::


Linuxを触っている時によく耳にする言葉 →シェルスクリプト
コマンドラインインターフェース(CLI)上で実行されるスクリプトです。
シェルがスクリプト内のコマンドを1行ずつ解釈し、その都度実行します。
インタープリタ型と動きが似てます。

```
特徴
・習得難度: 1行完結、文書のような直感的コード

・柔軟性: コンパイルの作業がなく、すぐに実行できる

・処理速度が遅い: 1行ごとに解釈が必要、コード全体の最適化が難しい

・メモリ使用量: 使用量が多い、インタープリタが使用する
```


# インタープリタ言語

インタープリタ型について説明します。

Q.インタープリタ型言語って何？
A. インタープリタ型言語は、ソースコードを実行時に逐次解釈して実行する言語です。

インタープリタがソースコードを1行ずつ読み取り、直接実行します。
つまり、機械語(2進数)に翻訳せず、プログラムを直接実行できる言語。

※蛇足：インタープリタとは日本語直訳で"通訳者"って意味※

Q.どんな特徴なの？
A.下記特徴を持つ。
```
特徴:
逐次解釈: 実行時に1行ずつ解釈しながら実行されます。

柔軟性: 実行中にコードを変更しやすく、デバッグが容易です。

比較的遅い実行速度: 逐次解釈されるため、コンパイル型言語よりも実行速度が遅いことがあります。
例: Python、JavaScript、Ruby、Perl
```


# コンパイラ
インタープリタ型について説明します。

Q.コンパイラ型言語って何？

A.コンパイル型言語は、プログラムのソースコードを実行する前に、コンパイラによって機械語に変換（コンパイル）されるもの。
つまり、機械語(2進数)に翻訳してから実行されるもの。

この変換された機械語のファイル（バイナリファイル）は、コンピュータが直接実行できます。
```
特徴:

事前にコンパイル: 実行前にソースコードを一度にすべてコンパイルします。

高速な実行: コンパイル後は直接機械語で実行されるため、実行速度が速いです。

エラーチェック: コンパイル時にエラーチェックが行われるため、実行前に多くのエラーを発見できます。
例: Java、C、C++、Go、Rust
```

# 動作イメージ

下記図を参考にしてください。

コンピュータは2進数で決められた数字を使って処理を判断しています。
よって、プログラム言語で書かれたテキスト文字や記号を機械語(2進数)に変換して動かしています。

**<動作説明図>**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596363/57eed2f7-5627-5fec-ed3b-72b223c6fda6.png)

:::note warn
**ハイブリッド動作**
Java Script(JS)言語は少し特殊です
この言語は**Just-In-Timeコンパイラ**といった動作が行われます！

これは、プログラムの実行中にコンパイルして機械語に翻訳する技術です。
頻繁に実行されるコードを見つけて翻訳しておくことで処理速度が向上します！

**結論**
言語によっては両方の性質を兼ねようとしているものもある
:::

# まとめ

・シェルスクリプトはインタープリタ型言語に属し、システム管理や自動化タスクなどに広く使われている。

・インタープリタ型、コンパイル型それぞれはプログラムの実行方法が異なる。
・それぞれにメリットとデメリットがある。
・開発環境やアプリケーションの要件に応じて使い分けが必要。

ただし、注意点として、一部の言語はインタープリタ型でありながらも、実行時にバイトコードへコンパイルされるハイブリッドな動作をすることもある。

以上で終了です。
学習の手助けになれば幸いです！
PythonでAtCoder（ABC368D問題）解いてみた

# はじめに
問題は[こちら](https://atcoder.jp/contests/abc368/tasks)
初心者（灰色〜茶色）向けです。
# 伝えたいこと
Pythonで再帰を使うときは、
- PyPyを使わない！
- pypyjitライブラリが必要！
    ```python
    import pypyjit
    pypyjit.set_param('max_unroll_recursion=-1')
    ```
# D - Minimum Steiner Tree
https://atcoder.jp/contests/abc368/tasks/abc368_d
## 考え方
### 大枠の方針
指定された頂点たち（$V_1,...,V_k$)を一つ固定します。（ここでは$V_1$とします。）
不要な頂点を削除していき、求めたい状況の木になるのは、$V_1$を根とした時、葉が全て$V_1,...,V_k$たちのみで構成されているときです。[^1]
これは、各ノードについて、子孫ノードに$V_1,...,V_k$が存在しなければそのノードを取り除いていき、残った頂点数を数えあげれば良いです。
具体的には、$V_1$を起点とした再帰関数を用いたDFSを行い、削除対象のノードを記録して数え上げることで計算可能です。

### 詳細
次のような再帰関数dfsを作成します。
1. 自分が（$V_1,...,V_k$)である場合はTrueを返す
2. 1.がFalseの場合は自分の頂点が（$V_1,...,V_k$)を子孫ノードに持つかどうかを返す
    - 自分と隣接する未探索の頂点全てで関数dfsを実行し、自分の子孫ノード全てが（$V_1,...,V_k$)を子孫ノードに持たない場合は削除対象のSetに保存する

$V_1$についてdfsを実行し、削除対象のSetの頂点数をnからひく。
### 注意
PyPyの場合、DFSは遅くなるらしいのです。。。
PyPyを使わずに提出するか、参考文献のように、pypyjitライブラリを用いる必要があります。
3種類提出し、実行時間を比較してみました。
- 一番上　PyPy かつ pypyjit利用あり AC
- 真ん中　CPython AC
- 一番下　PyPy かつ pypyjit利用なし TLE

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3577449/2bf99905-3ef6-3586-7684-ce0f902c5263.png)

## 解答例
```Python3:私の解答
#!/usr/bin/env python3
import sys
import pypyjit
from collections import defaultdict

sys.setrecursionlimit(10**6)
pypyjit.set_param('max_unroll_recursion=-1')

def dfs(v):
    visited[v-1] = True
    hasV_kChildNode = v in v_k_set
    for neighbor in tree[v]:
        if not visited[neighbor-1]:
            if dfs(neighbor):
                hasV_kChildNode = True
    if not hasV_kChildNode:
        removed.add(v)
    return hasV_kChildNode

# 入力の読み込み
n, k = map(int, input().split())
tree = defaultdict(set)
for _ in range(n - 1):
    a, b = map(int, input().split())
    tree[a].add(b)
    tree[b].add(a)
v_k = list(map(int, input().split()))

# 初期化
visited = [False] * n
removed = set()
v_k_set = set(v_k)

# DFS開始
dfs(v_k[0])

# 残ったノード数の出力
print(n - len(removed))
```

# 感想
アルゴリズムそんなに違和感がないのになぜ間に合わないのか、、、と数時間頭を悩ませたのですが、pypyjitライブラリの利用でACになりました。そもそもギリギリ間に合ってなかったのでそれほど悔しくなかったのですが、大きな学びでした。
先輩Yさんに教えていただきました。ありがとうございました。

# 参考

https://x.com/ehekatlact/status/1490667240609382404?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1490667240609382404%7Ctwgr%5E0c88ba0ecc8c85bb137e32b5b5bf07161d1f8e8d%7Ctwcon%5Es1_&ref_url=https%3A%2F%2Ftoriidao.hateblo.jp%2Fentry%2F2023%2F01%2F24%2F121216

https://qiita.com/shoji9x9/items/e7d19bd6f54e960f46be

[^1]: もし最小にならないと仮定すると、最小の木について、$V_1,...,V_k$のいずれでもない葉$L_0$が存在することになりますが、$L_0$を取り除いた木は、さらに小さい頂点数で$V_1,...,V_k$を全て含むため、取り除く前の木が最小であることに反します。
ローカルの既存プロジェクトを、GitHubにアップロードする手順

# はじめに
通常、GitHubからプロジェクトをクローンして作業を開始しますが、既存のローカルプロジェクトをGitHubにアップロードすることもあります。

この記事では、ローカルで作成したプロジェクトをGitHubにアップロードする手順を詳しく説明します。

# 手順
### 1. Gitリポジトリを初期化する
作成したプロジェクトのディレクトリに移動し、Gitリポジトリとして初期化します：
```bash
cd /path/to/your/project
git init
```

### 2. GitHubリポジトリを作成する
1. GitHubにログインし、新しいリポジトリを作成します
1. リポジトリ名を入力し、必要に応じて説明を追加します
1. 「Initialize this repository with a README」のチェックを外します
1. 「Add .gitignore」と「Add a license」も選択しません
1. 「Create repository」をクリックします

:::note warn
このとき、README、.gitignore、ライセンスファイルなどは作成しないでください（これらはローカルで作成します）。
:::

リポジトリ作成後、GitHubが提供するリポジトリのURLをコピーします。

### 3. GitHubに接続する
ターミナルで、プロジェクトディレクトリ内から次のコマンドを使用して、GitHubリポジトリをリモートとして追加します:
```bash
git remote add origin <repository-url>
```
:::note warn
repository-urlには、GitHubからコピーしたURLを貼り付けてください。
:::

### 4. ファイルを追加してコミットする
必要なファイルを作成します：
```bash
echo "# プロジェクト名" > README.md
echo "# ライセンス情報" > LICENSE
```

.gitignore ファイルを作成し、必要な除外パターンを追加します。
```bash:.gitignore
# Environment variables
.env
```
ファイルをステージングします:
```
git add .
```
ファイルをコミットします:
```
git commit -m "初回コミット"
```

### 5.GitHubにプッシュする
ローカルリポジトリをGitHubのリモートリポジトリにプッシュします:
```
git push -u origin main
```

:::note warn
Git 2.28.0以降のバージョンでは、デフォルトブランチ名が master から main に変更されています。古いバージョンのGitを使用している場合は、main の代わりに master を使用してください。
:::

# まとめ
これらの手順に従うことで、ローカルで作成したプロジェクトをGitHubにアップロードできます。この方法は、プロジェクトの構造を整えてからGitHubで共有したい場合や、既存のローカルプロジェクトをバージョン管理下に置きたい場合に特に有用です。
Chrome128(stable)で利用可能になったGemini Nanoを試してみる

Chrome126 stableにはGemini miniが含まれると報道されていましたが、実際には含まれずにリリースされました

いつリリースされるかと、待っていたところChrome128で搭載されたようなので試してみます

https://docs.google.com/document/d/1VG8HIyz361zGduWgNG7R_R8Xkv0OOJ8b5C9QKeCjU0c/edit#heading=h.dzyszww8ys0d
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276579/6b503d2b-fd12-2c0b-bea9-853535b17430.png)


## 有効化手順

アドレスバーに`chrome://flags`と入力して、下記2つのフラグを有効化後、Chromeを再起動する

|                                      |                               |
| ------------------------------------ | ----------------------------- |
| Enables optimization guide on device | Enabled BypassPerfRequirement |
| Prompt API for Gemini Nano           | Enabled                       |


* Enables optimization guide on device
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276579/45c1c0c8-549c-8fdc-f03d-8f1da1f93ba1.png)


* Prompt API for Gemini Nano
![image-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276579/2d5f32da-527a-6e46-801f-1febf233fc0c.png)


### Gemini nanoモデルのダウンロード


* Chrome DevToolのコンソールで`await window.ai.createTextSession()`を実行する（エラーが出るが無視して次へ）
```
> await window.ai.createTextSession()
21:04:13.254 Uncaught InvalidStateError: The session cannot be created.
```

* アドレスバーに`chrome://components`と入力して`Optimization Guide On Device Model`の「アップデートを確認」をクリック

アップデートを確認をクリックし、ステータスが「コンポーネント更新完了」になるまで待つ
![image-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276579/c64b9c8e-d96d-4b8f-15e1-0b0babb6b56d.png)

※先にcreateTextSession()を実行しないと、`Optimization Guide On Device Model`が表示されない場合があるようなので

https://github.com/lightning-joyce/chromeai/issues/6#issuecomment-2253741737

## コンソールで動作確認

こんな感じでGeminiに質問することができました（ちょっと回答が怪しい場合もあった）
```javascript
const session = await window.ai.createTextSession();
const stream = session.promptStreaming('Chromeに組み込まれたGemini nanoは何ができる機能ですか?');
let response = '';
for await (const chunk of stream) {response = chunk;}
console.log(response);

Google Chromeに組み込まれたGemini nanoは、テキストや画像の検索、翻訳、リッチプレゼンテーションの
プレビューなどをサポートする拡張機能です。また、オンライン上の活動を追跡したり、オンライン上の
個人情報を保護したりするためのセキュリティ機能も備えています
```
Jetpack ComposeでPreview用データを作成する

# 初めに
今回は、JetpackComposeで実装しているとよくある複雑なデータクラスを表示するためのUIで望みどおりの表示ができてるかを確認するための実装方法を紹介していきます
### 本文
まず、表示したいPreviewの引数に対して下記を追加します
```kotlin
@PreviewParameter(HogeProvider::class) info: Hoge,
```
次に別クラスとして下記を定義します
`sequenceof`のカッコ内に表示したいデータクラスを呼び出します
```kotlin
internal class HogeProvider : PreviewParameterProvider<Hoge> {

    override val values = sequenceof()
}
```
後はプレビュー部分でCompose関数に先ほどのinfoを渡すだけです
### 最後に
今回は複雑なプレビュー用データの実装方法を紹介しました
どなたかのお役に立てれば幸いです
Javaあれこれ

<h3>1. Javaのバージョンを取得</h3>

```
System.getProperty("java.version"); 
```

<h3>2. OSの種類を取得</h3>

```
System.getProperty("os.name"); 
```


<h3>3. データ型を取得</h3>

```
オブジェクト.getClass();
オブジェクト.getClass().getSimpleName();

```

<h3>4. ヒープサイズ</h3>

```
Runtime.getRuntime().totalMemory();
Runtime.getRuntime().freeMemory();
Runtime.getRuntime().maxMemory();

java -Xms1m -Xmx3m クラス名　// 実行時にヒープサイズを指定

```
ラズパイのROM化とサービスの設定など

# ROM化

有効化
```
sudo raspi-config nonint enable_overlayfs
sudo reboot
```

無効化
```
sudo raspi-config nonint disable_overlayfs
sudo mount -o remount,rw /boot
sudo reboot
```

確認
```
df -h
```

# サービスの登録 (oFのアプリ)
```
nano /home/pi/your_app_directory/start_app.sh
```

```                                     
#!/bin/bash
export DISPLAY=:0 #必要に応じて
cd アプリのパス
make run
```
実行権限を与える
```
chmod +x /home/pi/your_app_directory/start_app.sh
```
systemdサービスファイルの作成
```
sudo nano /etc/systemd/system/your_app.service
```
```
[Unit]
Description=My App Service
After=multi-user.target
Wants=multi-user.target

[Service]
ExecStartPre=/bin/sleep 60
Environment="DISPLAY=:0"
ExecStart=/home/pi/your_app_directory/start_app.sh
WorkingDirectory=/home/pi/of_v0.12.0_linuxarmv6l_release/apps/project/name/
Restart=always
User=pi

[Install]
WantedBy=multi-user.target
```


# サービスのコマンド
 サービスの登録と起動
```
sudo systemctl daemon-reload
sudo systemctl enable your_app.service
sudo systemctl start your_app.service
```

サービスの停止
```
sudo systemctl stop your_app.service
```

サービスの自動起動
```
sudo systemctl enable your_app.service
```

サービスの自動起動停止
```
sudo systemctl disable your_app.service
```

サービスの再起動
```
sudo systemctl restart your_app.service
```

サービスの状態確認
```
sudo systemctl status your_app.service
```

# ネットワーク
固定IP
```
sudo nano /etc/dhcpcd.conf
```

# HDMI
HDMIの固定出力
```
sudo nano /boot/config.txt
```
```
hdmi_force_hotplug=1

hdmi_group=1
hdmi_mode=16

```

# CPU温度確認
```
vcgencmd measure_temp
```
【React】100本ノック #01 Hello World

## はじめに
フロントエンドスキル向上のため書籍やudemyでインプットを行っていますが、アウトプットも並行して進めるべく[@Sicut_study](https://qiita.com/Sicut_study "Sicut_study")さんのReact100本ノックを始めることにしました。

https://qiita.com/Sicut_study/items/3c5cd798313854a471a0

## ルール
- 主要なライブラリやフレームワークはReactである必要がありますが、その他のツールやライブラリ（例: Redux, Next.js, Styled Componentsなど）を組み合わせて使用することは自由
- TypeScriptを利用する
## 今回作るもの
画面上に「Hello World」を表示するReact コンポーネントの作成
## 条件
1\. Reactの新しいプロジェクトが正しくセットアップされていること。
2\. 画面に"Hello World"というテキストが中央に表示されていること。
## 成果物

https://github.com/okido-yukinari/01-helloworld.git

### 使用技術

- React
- TypeScript
- Emotion

スタイルに関しては、以前MUI（Material-UI）は何度か使用経験があったので、今回は全く別の方法で実装しようと思い、[@Sicut_study](https://qiita.com/Sicut_study "Sicut_study")さんと同様にEmotionを使ってみることにしました。
### PC
![01_helloworld_pc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453680/c2e60644-ad24-4d0e-74c1-302c90ecc180.png)

### SP
![01_helloworld_sp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453680/4e9db201-10a5-fdc1-0026-9a9bdaa15356.png)

## 感想
プロジェクト作成、アプリ作成、デプロイの大まかな流れを掴むことができました。
Reactについて、より理解を深めるために引き続き100本ノックを継続していきたいです。
コスト効率が高いクラウドの選び方: Hetzner vs AWS vs Digital Ocean

## はじめに

クラウドホスティングの選択は、そのコストがプロジェクトの成功に大きな影響を与えます。本記事では、コスト効率の高いHetzner Cloudを中心に、業界標準のAWS、そして代替選択肢としてのDigital Oceanを比較します。特に、2 vCPU, 4GB RAMのスペックを基準に、各サービスの特徴と価格を詳細に分析します。

## Hetznerの歴史

1997年: ドイツでHetzner Onlineとして創業
2018年: Hetzner Cloudサービスを開始

## 基本的な価格比較

まずは、同等スペック（2 vCPU, 4GB RAM）の月額料金を比較してみましょう。
| プロバイダ    | インスタンスタイプ  | 月額料金 | ストレージ | 無料通信量/月 |
|---------------|---------------------|-----------|------------|---------------|
| Hetzner       | CX21 (ドイツ)       | $5.78     | 40 GB NVMe | 20 TB         |
| AWS           | t3.medium (US-East) | $33.41    | 20 GB EBS  | 1 GB          |
| Digital Ocean | Basic Droplet       | $20       | 80 GB SSD  | 1 TB          |

（参考）
| プロバイダ           | インスタンスタイプ  | 月額料金     | ストレージ | 無料通信量 |
|----------------------|---------------------|--------------|------------|------------|
| さくらインターネット | VPS 4Gプラン (石狩) | $25 (￥3,520)|100 GB SSD  | 無制限     |
|                      | SSD 20GB (石狩第1)  | $36 (￥5,060)|20 GB SSD   | 無制限     |

Hetznerは月額料金、ストレージ性能、無料通信量のすべてにおいて圧倒的に優位です。

### ストレージと通信料金の詳細

| プロバイダ    | 追加ストレージ料金 | 超過通信料金 (1TB当たり) |
|---------------|---------------------|-------------------------|
| Hetzner       | $0.0525/GB/月       | 約$1.3                  |
| AWS           | $0.10/GB/月         | $92.16                  |
| Digital Ocean | $0.10/GB/月         | $10.24                  |

注意事項：
- AWSは730時間/月として計算
- 換算レート: `1€ ≈ $1.09`, `$1 ≈ ￥140.5`

※ 2024年8月の価格

## Hetznerの優位性

1. **圧倒的なコスト効率**
   - AWSの約1/6、Digital Oceanの約1/3の価格で同等スペックを提供
   - 長期的なプロジェクトで大幅なコスト削減が可能

2. **高性能ハードウェア**
   - 全てのプランでNVMe SSDを標準採用
   - 最新のIntel/AMDプロセッサを使用

3. **シンプルな料金体系**
   - 追加料金が少なく、予算管理が容易
   - 20TB/月までの無料データ転送量

## AWSとの詳細比較

1. **コスト構造**
   - AWS: 複雑な料金体系、多数の追加料金（データ転送、EBS、Elastic IPなど）
   - Hetzner: シンプルな料金体系、ほとんどの機能が基本料金に含まれる

2. **スケーラビリティ**
   - AWS: 非常に高度なスケーラビリティ、多様なサービス連携
   - Hetzner: 基本的なスケーリングオプション、必要十分な機能を提供

3. **グローバル展開**
   - AWS: 世界中にデータセンターを保有、グローバル展開に強み
   - Hetzner: 主に欧州にフォーカス、一部の米国、シンガポール拠点

4. **サポートとエコシステム**
   - AWS: 豊富なドキュメント、大規模なコミュニティ、多様な管理ツール
   - Hetzner: 基本的なサポート、直感的な管理コンソール

5. **ストレージと通信料金**
   - AWS: 柔軟性が高いが、コストが急激に上昇する可能性がある
   - Hetzner: 大容量の高性能ストレージと無料通信量を標準で提供

## 使用シナリオ別比較

1. **スタートアップ/小規模プロジェクト**
   - 推奨: Hetzner（コスト効率が圧倒的に高い）

2. **中規模Webアプリケーション**
   - 推奨: Hetzner（性能と価格のバランスが優れている）

3. **大規模/グローバルプロジェクト**
   - 推奨: AWS（高度なスケーラビリティとグローバル展開に強み）

4. **開発/テスト環境**
   - 推奨: Hetzner（コスト効率が高く、迅速な展開が可能）

5. **高トラフィックサイト**
   - 推奨: Hetzner（大容量の無料データ転送が有利）

6. **データ集約型アプリケーション**
   - 推奨: Hetzner（大容量NVMe SSDと低コストの追加ストレージが魅力的）

## まとめ

Hetzner Cloudは、特にコスト効率を重視するプロジェクトや、高性能なストレージと大容量の通信量を必要とするアプリケーションに最適な選択肢です。AWSと比較して大幅なコスト削減が可能であり、多くの用途で十分な性能と機能を提供します。

最終的な選択は、プロジェクトの具体的な要件、予算、そして将来の成長計画に基づいて行うことをお勧めします。Hetznerは多くの場合、最もコスト効率の高い選択肢となるでしょう。

## 参考リンク

- [Hetzner Cloud公式サイト](https://www.hetzner.com/cloud)
- [HetznerでDockerを使ってWordPressを構築する方法 - Qiita](https://qiita.com/seigo/items/afcaa9fc3fea1c021f76)
javascript web worker の基本

## はしがき

プログラミングをしながら、ふいと気づきました。
「javascript は single thread だ、しかし、multi thread のように動いている」
「本当に thread が必要になったら、どうすればいい？」
とか...考えが浮き出した。

それで、javascript も multi thread ができるか？がきになって、検索しました。

## javascript の multi thread っぽい single thread とは？

確かに、javascript は single thread です。javascript の main thread の event loop が single thread なので、single thread です。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Event_loop

が、非同期もあるので、multi thread のように動かせることです。

https://developer.mozilla.org/en-US/docs/Glossary/Asynchronous

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

https://developer.mozilla.org/en-US/docs/Glossary/Callback_function

## web worker

https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API

「非同期があるので、multi thread はいらない？」かもしれませんが、web worker は実行難しいことを background で実行するためのことです。

## 使い方

まず、基本的な `A × B` の calculator を作ります。

```html
<!-- 省略 -->
<div>hello, world</div>
<input id="number1" class="number1" type="number">
<input id="number2" type="number">
<div class="result">3</div>
<!-- 省略 -->
```

ここから、`<input>` から入力すれば、`<input>` のことを掛け算する function を実行して、`result` に入力します。

```javascript
// index.js
const first = document.querySelector('#number1')
const second = document.querySelector('#number2')

const result = document.querySelector('.result')

[first, second].forEach(input => {
  input.onchange = function() {
    result.textContent = first.value * second.value
  }
})
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582489/6394e858-7796-ed96-3f79-08b67972ea6e.png)

このような感覚です。うまくできました。

------
今回は掛け算なので、すぐできますが、もし、時間が結構かかるときがあります。
それのために、web worker をつかって、background から実行できるようにしましょう。

```javascript
// index.js
const first = document.querySelector('#number1')
const second = document.querySelector('#number2')

const result = document.querySelector('.result')

if (window.Worker) {
  const myWorker = new Worker('worker.js') // file name

  [first, second].forEach(input => {
    input.onchange = function() {
      myWorker.postMessage([first.value, second.value])
      console.log('Message posted to worker')
    }
  })

  myWorker.onmessage = function(e) {
    result.textContent = e.data
    console.log('Message received from worker')
  }
} else {
  console.log('Your browser doesn\'t support web workers.')
}

// worker.js
onmessage = function(e) {
    const data = e.data
    this.setTimeout(() => {
        postMessage(data[0] * data[1])
        console.log('after 5 seconds')
    }, 5000)
}

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3582489/3742506d-406e-febf-2115-8ba003a7cc45.png)

今回もうまくできました。
5秒もかかることでしたが、worker を別の thread に分かれて、実行できました。
取れといわれた過去問がない徳丸試験を省エネで合格するたった一つのさえたやり方

# はじめに
「たった一つのさえたやり方」は恥ずかしながらまだ読んだことありません。

やれといわれた勉強ほどやりたくないものです。学生時代を思い出してください。勉強しなさいといわれれば言われるほど勉強のやる気がなくなったことありましたね？**私は勉強があまり苦ではなかった質なので、言われる前に自分で勉強したのでその気持ちはわかりません。**

てめぇ喧嘩売ってんのかといわれそうです。とりあえず何が言いたいかと言いますと、学生時代はよくわからなかった「やれといわれるとやる気がなくなる」現象をキチンと自分のこととして昨日初めて理解したということでございます。

先日会社の研修を受けていると、「徳丸試験を8月までに受けてね」といわれました。心の底から思いました。「だりぃ！！！」多くの人が思ったでしょう。私だけじゃないことを望んでいます。弊社を擁護しますが、たぶん取らなくてもあんまり何も言われないと思います。

研修自体を受けたのは6月くらいだったと思いますが、言い訳に言い訳を重ねているうちに8月は半ばになってしまいました。これはいかんと思い、とりあえず日付だけ決めてやる気を出そうと思ったものの、前日くらいまで何もやりません。これはいかんと思い、頑張って何とか合格したので、本記事では省エネで何とか合格する方法を伝授したいと思います。

あと「やれといわれるとやる気がでなくなるよね」ってことを共有したくて書きました。

# どれくらいの勉強量で受かったん？
勉強に値するものはおそらく3つあったと思います。
- セキュリティの学部に在学してた時の勉強
- 一か月かけて一回通して読んだ
- 前日と当日にきちんと勉強した

とりあえず他の人にはないアドバンテージとして**セキュリティの学部出身**というクソデカアドバンテージはありますが、ほとんど覚えてなくて、XSSとかCSRFの名前は覚えているくらいだったので、あんまりアドバンテージではないような気もしてきています。

とりあえず一か月くらいかけて、一回読みましたが、読んだ後に覚えていることは**ほぼゼロ**でした。寝る前20分くらい毎日読んでて細切れだったので、これはやらなくてもほぼ変わらないですね多分。

ので、結局ちゃんと勉強したのは前日と当日の午前中くらいだと思います。時間にすると**多分4時間**くらいですかね？もっと短いかもしれません。これはほぼ一夜漬けに近いので、きちんと理解するという試験の存在意義的にはあんまりよくないとは思います。

なのでしぶしぶとるくらいのメンタリティの人がどうやったら合格するかに焦点を当ててみます。きちんと理解する必要がある人はきちんと理解して、望んでくださいね。（あたりまえ体操）

# 何をすればいいか
この記事を参考にすればいいと思います（丸投げ）

https://dev.icare.jpn.com/dev_cat/web_security

全部あってますので、参考にすれば多分間違いないです。

僭越ながら、私が試験受けてすべきだなと思ったことは、以下です。
- 4章,5章だけ対策で何とかなる
- 各脆弱性の原因、攻撃方法、対策、影響範囲を言えるようにする

4章,5章だけで**33問**出題されるそうです。**40問あるうちの7割を取ればいいので**、33問正解できれば十分合格できます。他の分野はなんとなくわかるような問題もあったりしますので、省エネで行くなら**4,5章だけで十分でしょう。**

4章,5章だけ？余裕やん！と思うかもしれませんが、こいつらが本の半分は言い過ぎまでも1/3は間違いなく占めています。結構大変なので、勉強する場所を絞りたいです。あんまり言いすぎると、中身言っちゃいけない制約に引っかかるのが嫌なので詳細にいうことは避けますし、今から言うことは一般論です。

一般的に重要だからこそ**名前が付く**のです。名前がつかないものはあまり重要な脅威とみなされていない可能性は十分考えられます。そして7割強が受かる試験は難しい問題があまり出ないと考えられます。すると**一般的**にどういう問題が出るかは考えられると思います。

この指針に沿った脆弱性などは必ず攻撃方法、原因、対策、影響範囲を暗で言えるようになれば合格は近いと思います。

5章の勉強方法は知りません！というか私自身解いている中でどれが5章の問題なのかよくわかりませんでした。馬鹿なので。なので頑張ってください。

# まとめ
とりあえずまとめとしては

### 4章の内容を原因、攻撃方法、対策、影響範囲を言えるようにし、5章を頑張って勉強する

こんな所じゃないでしょうか。言うのを忘れていましたが、800/1000で筆者は受かりました。

重ねることになりますが、あんまり褒められたことじゃありません。きちんと全部理解して、100点を目指すべきです。ただその重要性と同じくらい、面倒なことに時間を取られるよりやりたいことをやったほうが人生全体を通しての幸福度は高いという自論があるので、本記事を執筆するに至りました。

自分で受けようと思っている人はこんな意見参考にしないで100点取ってください。きちんとやれば全然取れると思います。

まとめでいうことではないですが、**この記事の対象者は別にやりたかないけど徳丸試験とっとけと言われたから取るくらいのモチベーションの人です。** いう必要はないと思いますが、それ以外の人はちゃんとやったほうが健全だと思いますよ。

浮いた時間を是非人生を幸福にするための時間にしていただければ、私の幸せです。
Apple SiliconのMacでGPUをTensorflowで用いる方法

:::note warn
注意
こちらの記事は公式の情報源に依っているものではなく、確認が必要な内容を含みます。
詳しい方の指摘・補足をお待ちしております。
:::
## 結論
Apple自身が作っているtensorflow-metalを使う。
```python
pip install tensorflow-macos
pip install tensorflow-metal
```
## 今はもうやらなくて良さそうなこと
Conda経由でのtensorflow-depsのインストール
https://anaconda.org/apple/tensorflow-deps
Anaconda上は、2年前から更新がなされていない
```python
conda install apple tensorflow-deps
```
## もう少し調べたいこと
Apple SiliconのMac上のDockerで、Ubuntu環境を立ち上げた際にもGPUを動かせるか。
→試したらインストールできないとエラーが出た。tensorflow-metalがOS依存しているか、OS判定に引っかかったか。
Atcoder解いてみた ABC 088 C - Takahashi's Information

# ABC 088 C - Takahashi's Information 解いてみた
問題は[こちら](https://atcoder.jp/contests/abc088/tasks/abc088_c)

## 回答
元リンクは[こちら](https://blog.hamayanhamayan.com/entry/2018/02/18/224509)
```C++
int C[3][3];
int A[3], B[3];
//---------------------------------------------------------------------------------------------------
void _main() {
    rep(i, 0, 3) rep(j, 0, 3) cin >> C[i][j];
 
    rep(a1, 0, 101) rep(a2, 0, 101) rep(a3, 0, 101) {
        int b1 = C[0][0] - a1;
        int b2 = C[0][1] - a1;
        int b3 = C[0][2] - a1;
 
        A[0] = a1;
        A[1] = a2;
        A[2] = a3;
        B[0] = b1;
        B[1] = b2;
        B[2] = b3;
 
        int ok = 1;
        rep(i, 0, 3) rep(j, 0, 3) if (A[i] + B[j] != C[i][j]) ok = 0;
        if (ok) {
            printf("Yes\n");
            return;
        }
    }
 
    printf("No\n");
}
```

## 別解(上記とほぼ同じだが、、、)
```C++
#include <iostream>
using namespace std;

int main() {

    // 簡単に考えよう

    int C[3][3];
    int B[3][3]; //今回、Cの各要素に対応するbを求め、j方向で見ていった時にbが一定かどうか判定しているため、このような形でBの配列を確保している

    for (int j = 0; j < 3; j++) {
        for (int i = 0; i < 3; i++) {
            cin >> C[j][i];
        }
    }

    // aが決まれば、c-aでbも決まる
    // aとbの取りうる値すべてのループは効率悪い
    
    // aの添え字：i方向　(a1,a2, a3はj方向に一定であることが前提)
    for (int a1 = 0; a1 <= 100; a1++) {
        for (int a2 = 0; a2 <= 100; a2++) {
            for (int a3 = 0; a3 <= 100; a3++) {

                for (int j = 0; j < 3; j++) {
                    B[j][0] = C[j][0] - a1;
                    B[j][1] = C[j][1] - a2;
                    B[j][2] = C[j][2] - a3;
                }

                bool can = true;
                for (int j = 0; j < 3; j++) {
                    if (B[j][0] != B[j][1] || B[j][1] != B[j][2] || B[j][2] != B[j][0]) {
                        can = false;
                    }
                }
                if (can == true)
                {
                    cout << "Yes" << endl;
                    return 0;
                }

            }
        }
    }

    cout << "No" << endl;
    return 0;
}
```
Azure, AWS, Googleで利用可能な量子コンピュータ-2024年夏版

# 各社のサービス
比較対象のサービスはMicrosoft Azure, AWS, Googleです。
各社ともオリジナルの量子コンピュータを研究開発しつつも、主にユーザー向けに提供しているのは別の他社のハードウェアで、それを自社サービスに統合してサービス提供しています。

## Azure Quantum
https://learn.microsoft.com/en-us/azure/quantum/

## AWS Bracket
https://aws.amazon.com/jp/braket/

## Google Quantum AI
https://quantumai.google/

Azure、AWSとは違い、Google上では明示的にサービス提供してないのがGoogleの特徴。
Googleは[Cirq](https://quantumai.google/software)というOSSフレームワーク経由で複数社のバックエンドサービス（ハードウェア）に接続します。
現状は、Cirqを使って、[Google Quantum Engine API](https://quantumai.google/cirq/google/engine)を呼び出すしか方法がないです。

# サポートマトリクス
プロバイダー | 方式 | Azure | AWS | Google Cirq
---|---|---|---|---
[Quantinuum](https://www.quantinuum.com/)| イオントラップ|o|-|-
[IonQ](https://ionq.com/)|イオントラップ|o|o|o
[Alpine Quantum Technologies (AQT)](https://www.aqt.eu/)|イオントラップ|-|-|o
[Rigetti](https://www.rigetti.com/)|超伝導|o|o|o
[Quantum Circuits, Inc](https://quantumcircuits.com/)|超伝導|o|-|-
[IQM](https://aws.amazon.com/jp/braket/quantum-computers/iqm/)|超伝導|-|o|-
~~[Oxford Quantum Circuits (OQC)](https://oxfordquantumcircuits.com/)~~|超伝導|-|△|-
[Google Sycamore](https://quantumai.google/cirq)|超伝導|-|-|o
[Pasqal](https://pasqal.io/)|中性原子|o|-|o
[QuEra](https://www.quera.com/)|中性原子|-|o|-
~~[Xanadu](https://www.xanadu.ai/)~~|光|-|△|-
~~[D-Wave](https://www.dwavesys.com/)~~|量子アニーリング|-|△|-

**凡例**
- o: サービスに直接組み込まれて提供
- -: サービスに直接組み込まれてない
- △: 過去はサービスに直接組み込まれていたが、現在はサポート対象外となってしまった

# 2023春からの変更点
[Azure, AWS, Googleで利用可能な量子コンピュータ-2023年版](https://qiita.com/HrsUed/items/9189443dd5840942d203)からの変化点です。

## Azure
なし

## AWS
- Oxford Quantum Circuits(OQC)が削除。[AWSサイト](https://aws.amazon.com/jp/braket/quantum-computers/oqc/?sc_channel=sm&sc_campaign=Support&sc_publisher=TWITTER&sc_country=global&sc_geo=GLOBAL&sc_outcome=AWS%20Support&sc_content=Support&trk=Support&linkId=570121616)上で2024-06-28以降は利用不可と記載あり。
- Xanaduが削除
- IQMが追加

## Google
- 3rd partyによるハードウェア接続にはキリがないので、PennyLane提供の各社SDKプラグインによるハードウェア接続は本記事のマトリクスから削除しました。これに伴い、以下のハードウェア表記をGoogle Cirqから削除しました。
  - Quantum Inspire
  - Honnywell
API叩きすぎ？ 200なのにCORSが返る

# 起きたエラー
チーム開発中、郵便番号検索APIを利用して、データの取得を行っていたが、
急にデータを取得出来なくなった。

ステータス200が返っているのに、CORSが表示され正常レスポンスで取得できるデータが取れない...:dizzy_face:



# 解消法
__これまでのコード__
```
const res = await fetch('https://example.com/api/json');
```

<br></br>
【間違い】
~~__headerを追記したコード__~~
【正解】
サーバーの応答時に Access-Control-Allow-Origin を含めることを認識させる


```diff
- const res = await fetch('https://example.com/api/json');

+  const res = await fetch('https://example.com/api/json', {
+   header: {
+     'Access-Control-Allow-Origin': '*',
+  },
+})
```

# 原因
>異なるオリジンAPIを叩いたから

色々検索して記事読んでみたけど、難しい..
クライアント側だったりサーバー側だったりっていうのをきちんと理解していない今。
(その辺の根本の理解足りてない。。)

おまえ敵か！？って疑われたって認識で合ってるかな？


https://zenn.dev/yarai/articles/6e3c5b017a5b8d


# 参考サイト

https://developer.mozilla.org/ja/docs/Web/HTTP/Headers

https://future-architect.github.io/articles/20220222a/

https://zenn.dev/wizard/articles/26c7a4c4a08c77

<br></br><br></br><br></br>
### エラーになったから得られる知識でした
AWS認定ソリューションアーキテクト・プロフェッショナル受験談&学習法

## 概要
2024年9月1日にAWS認定ソリューションアーキテクト・プロフェッショナルの試験を受けて合格しましたので、学習したこと等を情報共有として書いていきます。
合格基準750点のところ752点でした〜今回こそ落ちたかと思っていましたが、ギリギリ首の皮一枚のところで合格でした:sweat_smile:

## 前提の知識と経験
アソシエイトの3つとセキュリティのスペシャリティ、DevOpsプロフェッショナルに合格している状態で、この試験を受けました。
DirectConnectやマルチリージョンやDRについての問題が多い中、直近の案件でその辺りの設計に関わっていたので、とっつきやすい感じがしていました、、、でも、ギリギリ。

## 学習期間
今回も大体1ヶ月くらいで、平日は1日2〜3時間、休日は5〜6時間くらいです。ここも、これまでと変わらず。

## 学習教材
### 1. AWS Skill Builder
今回もAWS Skill Builderの有料プランも実践してみました。前の記事と同じ内容ですが、本番模試は有料、他の20問模試やサンプル模試は無料です。
合計で100問近くありますが、90％くらいできるまでやりました、、、けど、ギリギリ。

https://skillbuilder.aws/jp

### 2. AWS認定 ソリューションアーキテクト プロフェッショナル 模擬問題集＋詳解
Udemyの日本語の模試問題集で、解説付き。やはりレベルが高めで、できないことを前提にして、サービスの内容や解説を読む感じで取り組みました。一通り回答して間違っていたところを重点的に復習です。

https://www.udemy.com/course/sap-c02aws-2024

### 3. Ultimate AWS Certified Solutions Architect Professional 2024
Udemyの動画教材で、日本語字幕付き。試験範囲のサービス概要が把握できるので、一通り見ました。
ただ、一回一通り見て終わりました。

https://www.udemy.com/course/aws-solutions-architect-professional

### 4. AWS認定資格試験テキスト＆問題集　AWS認定ソリューションアーキテクト - プロフェッショナル　改訂第2版

こちらは書籍で、買おうか迷いましたが、買ってみました。こちらも動画同様に試験範囲のサービス概要が把握できるのですが、これも一回一通り見て終わりました。
Udemyの動画か、こちらの書籍かどちらかで良かったですね〜

## 本番試験
180分の試験時間で、今回も180分フルで使いました。ギリギリまで粘ったので、ギリギリ合格できたのかなぁと。諦めなくて良かったです:grinning:
マルチリージョン、DX、DRについての問題が多く、問題文や選択肢の文の長さはこれまでのAWS試験で一番でしたね。ザックリとキーワードをすくい上げて、そこから正解を導いていかないと時間がなくなりますね〜私はじっくりと文章を読んでいたので、読み返す時間がほぼなくなっていました。ある種の直感も必要かなと。
AWS Skill Builderの有料の本番模試に近い問題もありましたが、それほど多くなく、覚えた知識をフル活用していましたね〜
あと、得点除外の問題が分かりにくかったので、DevOpsプロフェッショナル試験の時のように、問題を捨てられなかったのも、時間がかかった要因かも。

## 最後に
AWS SAPに合格したことで、目標としていたプロフェッショナルの2つを取得することができました:raised_hands:
そこで分かったのが、「AWSワカラナイ」ということ。AWSの試験はサービスの内容と使い方を問うもの。エンジニアとしては、サーバやネットワーク仕組みの理解を深めないと、実務でAWSは使いこなせない。

結果、「AWSワカラナイ」となる。

AWS SAPがスタート地点として、これらも仕組みの理解や試験、仕事を頑張ろう:muscle:
初心者向け：WSL2とVSCodeを使った簡単C/C++言語プログラミング環境設定

# はじめに

この記事では、Windows上でWSL2（Ubuntu）とVSCodeをインストールし、言語の開発環境を構築する手順をわかりやすく説明します。個人的な備忘録としてまとめましたが、同様の環境を構築したい方の参考にもなると思います。

# WSL2のインストール

1. **Windows PowerShellを管理者として実行**
    - まず、Windows PowerShellを管理者権限で起動します。スタートメニューから「Windows PowerShell」を検索し、アイコンを右クリックして「管理者として実行」を選択します。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311228/8ff84ef3-8868-37f1-1b38-92a107b423be.png)

2. **WSL2のインストール**
    - 次に、以下のコマンドをPowerShellに入力し、WSL2をインストールします。この作業には少し時間がかかることがありますので、完了するまで待ちましょう。
    ```
    wsl --install
    ```

    - インストールが完了すると、再起動が求められる場合があります。その場合は指示に従ってPCを再起動してください。

# C/C++の環境設定

## Ubuntuのアップデート

WSL2上でUbuntuを初めて起動した後は、まずシステムのアップデートを行います。最新の状態にしておくことで、後々の作業がスムーズになります。以下のコマンドを順に実行してください。

```
sudo apt update
```
```
sudo apt upgrade
```

- 途中でパスワードの入力が求められることがありますので、インストール時に設定したパスワードを入力してください。また、「Do you want to continue? [Y/n]」と表示された場合は、[Y]キーを押して進めてください。

## build-essentialのインストール

1. **build-essentialのインストール**
    - C/C++プログラムのコンパイルに必要なツールを一括でインストールするため、以下のコマンドを実行します。これにより、`gcc` や `g++`、`make` などのツールが自動的にインストールされます。
    ```
    sudo apt install build-essential
    ```

2. **gccのインストール確認**
    - インストールが完了したら、以下のコマンドで `gcc` が正しくインストールされているかを確認します。バージョン情報（例: `gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0`）が表示されれば成功です。
    ```
    gcc --version
    ```

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311228/aa74d646-e497-da70-2c82-815dbab9d52b.png)

## C/C++プログラムの実行

### Cプログラムの実行

1. **作業ディレクトリの作成**
    - まず、C言語のプログラムを保存するディレクトリを以下のコマンドで作成します。
    ```
    mkdir workspace
    ```

2. **ディレクトリに移動**
    - 作成したディレクトリに移動します。
    ```
    cd workspace
    ```

3. **Cファイルの作成**
    - 以下のコマンドで、Cプログラムを保存するためのファイルを作成します。
    ```
    touch test.c
    ```

4. **プログラムの編集**
    - `vi test.c` コマンドでファイルを開き、以下のコードを入力します。このプログラムは、`Hello, World!` と表示する簡単なCプログラムです。
    ```c
    #include <stdio.h>
    
    int main() {
        printf("Hello, World!\n");
    }
    ```

    - `vi` コマンドの代わりに、VSCodeで編集することも可能です（後述のVSCodeとの連携を参照）。

5. **コンパイル**
    - 以下のコマンドでプログラムをコンパイルします。成功すると、`test.c` と同じディレクトリに `a.out` という実行ファイルが生成されます。
    ```
    gcc test.c
    ```

6. **プログラムの実行**
    - 最後に、以下のコマンドでプログラムを実行します。ターミナルに `Hello, World!` と表示されれば成功です。
    ```
    ./a.out
    ```

# VSCodeとの連携

## Ubuntu上からのVSCode起動

Ubuntu上で任意のディレクトリを開いた状態で、以下のコマンドを実行すると、VSCodeがそのディレクトリを開きます。

```
code .
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311228/e41307ed-f1cf-44d4-a586-7a43ff326035.png)

- VSCode上でターミナルを起動するには、表示タブから「ターミナル」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311228/d2c6a4b6-daa7-2ee2-1deb-04ec56c126e0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311228/3bce621b-6bbc-7e7e-c4bf-c3ece85af80c.png)


# まとめ
この記事では、Windows上でWSL2（Ubuntu）とVSCodeを使用してC言語の開発環境を構築する手順を説明しました。これにより、Windows環境でもLinuxの利便性を活かしたCプログラミングが可能になります。WSL2とVSCodeの組み合わせは、軽量で効率的な開発環境を提供し、さまざまなプログラミング言語やツールの学習にも適しています。

これからの開発に役立てていただければ幸いです。
AtCoder ABC369 E - Sightseeing TourをbitDPで解く: dp[bit][last][side]

https://atcoder.jp/contests/abc369/tasks/abc369_e

をbitDPで考えます。解説を読んでいることが前提です。

`dp[pat][last][side]`: 橋の集合`pat`を訪れていて、最後に橋`last`を渡って`side`側にいる時の最短距離とします。`side`は`last`を渡り終わったときに、`0: u側`,`1: v側`にいることを示すとします。考慮すべき点は以下の2つです。

- 1: `0から最初の橋に向かうとき`と`最後の橋からn-1に向かうとき`に考慮する必要があります。
- 2: 各集合の遷移で`side`を考慮する必要があります。

以下のように遷移を行います。`dist[a][b]`は解説の通り$a$から$b$に向かう最小コストでワーシャルフロイドなどで求めた全始点全終点の最小コストです。
- `0から最初の橋に向かうとき`は`最初に計算しておきます。pat=0`の状態からある橋$i$に移動するとき向かうべき橋の両端をu,v渡る時間をtとします。例えば`last`を渡り終わったときに`u`にいるとは`v`に移動するコストに`t`をかけて`u`に移動したというように示せます。つまり`dp[1<<i][i][0] = dist[0][v] + t` ,`dp[1<<i][i][1] = dist[0][u] + t`です。
- `最後の橋からn-1に向かうとき`は集合の遷移では行わず`pat[1<<2-1]`(つまりすべての走り終わった状態)について計算しましょう。すべての橋を渡ってから`n-1`に移動する総コストは最後の橋`i`橋、その両端をu,vとすれば、`dp[(1<<k)-1][i][0] + dist[u][n-1]`と`dp[(1<<k)-1][i][1] + dist[v][n-1]`を考えれば良いです。
- bitDPの遷移は一般的なbitDPの遷移を考えればよく、各`pat`について次に`k`を訪問したいとするとは`pat | 1<<k`への遷移であるため上記のように`side`を意識しながら遷移していけば良いです。

# 実装
クエリ部分だけを抜き出したコードは以下の通りです。
```Python
# クエリ
q = int(input())
for _ in range(q):
    k = int(input())
    buf = list(map(lambda x: int(x) - 1, input().split()))
    # bitDPu,v[pat][last]: patに訪問済みで最後にいるのがlastのu or v
    bitDP = [[[INF] * 2 for _ in range(k)] for _ in range(1<<k)] 
    # 初期値処理。最初の1拠点というのはbitDP[1<<i][i] = dist[0][iのu or v] + tとなる
    for i in range(k):
        u, v, t = bridge[buf[i]] # iの橋の位置
        bitDP[1 << i][i][0] = dist[0][v] + t # 0からvにいって橋を渡るとuにいる
        bitDP[1 << i][i][1] = dist[0][u] + t # 0からuにいって橋を渡るとvにいる
    for pat in range(1 << k): # bitDP。いまいる位置
        if pat & (1 << k) != 0: continue # 訪問済みなら処理しない
        for nxtind in range(k): # 次はkに行きたい
            nxtpat = pat | (1 << nxtind) # 次の状態
            for lastind in range(k): # 最後にいたのがlastindとする
                lastu, lastv, _ = bridge[buf[lastind]] # 次の橋の位置を知った上で
                u, v, t = bridge[buf[nxtind]] # 次の橋の位置を知った上で
                # 注意: ここで、INFを超えたコストは考慮しないことにする。
                # 今の点lastindのu or vから次の点nxtindのu or vに行くことを考える。
                bitDP[nxtpat][nxtind][0] = min(bitDP[nxtpat][nxtind][0], bitDP[pat][lastind][0] + dist[lastu][v] + t)
                bitDP[nxtpat][nxtind][0] = min(bitDP[nxtpat][nxtind][0], bitDP[pat][lastind][1] + dist[lastv][v] + t)
                bitDP[nxtpat][nxtind][1] = min(bitDP[nxtpat][nxtind][1], bitDP[pat][lastind][0] + dist[lastu][u] + t)
                bitDP[nxtpat][nxtind][1] = min(bitDP[nxtpat][nxtind][1], bitDP[pat][lastind][1] + dist[lastv][u] + t)
    ans  = INF
    # 最後の処理: 全ての条件を満たしているとき、最後の状態からn-1に移動するコストを考える
    for i in range(k):
        u, v, t = bridge[buf[i]] # iの橋の位置
        ans = min(ans, bitDP[(1<<k)-1][i][0] + dist[u][n-1])
        ans = min(ans, bitDP[(1<<k)-1][i][1] + dist[v][n-1])
    print(ans)
```

https://atcoder.jp/contests/abc369/submissions/57357617
Laravelデプロイしてみた

今回はLaravelで作成したプロジェクトをAWSを用いてデプロイしてみました。


## 環境
php 8.2.0
Laravel Framework:11.11.1
apache2.4.39
RDS

## インフラ構成図
![スクリーンショット 2024-09-01 201125.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3774215/3d357ddd-467f-b077-86ce-887b4329976b.png)

このように作成しました。

改善点もあるかと思うので、今後も修正していきます。
投稿アプリで本人以外が記事を削除できなくする (Laravel)

## はじめに
Laravel学習の一環でBreezeを利用した簡単な記事投稿アプリを作成しました。
その際、投稿した本人以外が記事を編集・削除できないようにする機能を実装してみたので、備忘のため記事に残します。

## 完成イメージ
投稿した本人の場合 → 編集・削除ボタンが表示される
![スクリーンショット 2024-09-01 19.17.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3362317/93182f55-f314-b928-a983-3545a0367a58.png)

投稿した本人**以外**の場合 → ボタンが表示されない
![スクリーンショット 2024-09-01 19.19.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3362317/e37fb7a5-5de7-9d3e-3985-30f83564ccd5.png)

## 実装フロー
1. ビューに記事の投稿者を確認するロジックを追加
1. コントローラーに記事の投稿者を確認するロジックを追加

## 1. ビューに記事の投稿者を確認するロジックを追加
投稿の編集・削除ボタンが表示される条件として、ログインユーザーがその記事の投稿者であるかどうかを確認するコードを追加します。

```php
@if(Auth::id() === $post->user_id)
    <div class="text-right flex">
        <a href="{{ route('post.edit', $post)}}" class="flex-1">
            <x-primary-button>
                編集
            </x-primary-button>
        </a>
        <x-primary-button id="js-delete-button" class="bg-red-700 ml-2 flex-2">
            削除
        </x-primary-button>
    </div>
@endif
```

## 2. コントローラーに記事の投稿者を確認するロジックを追加
対象のコントローラーのeditメソッドやdestroyメソッドに、ログインユーザーがその記事の投稿者であるかどうかを確認するコードを追加します。
これにより、他者がURLを直接操作して編集や削除を試みた場合でも、その操作が制限されます。
今回は、ログインユーザーが記事の投稿者でない場合は、投稿一覧画面にリダイレクトして警告を表示するようにしました。

```php
public function edit(Request $request, Post $post)
{
    if (Auth::id() !== $post->user_id) {
        $request->session()->flash('error', '不正なアクセスです');
        return redirect()->route('post.index');
    }
    
    return view('post.edit', compact('post'));
}

public function destroy(Request $request, Post $post)
{
    if (Auth::id() !== $post->user_id) {
        $request->session()->flash('error', '不正なアクセスです');
        return redirect()->route('post.index');
    }
    
    $post->delete();
    $request->session()->flash('message', '削除しました');
    return redirect()->route('post.index');
}
```

## おわりに
自分で考えて機能を実装する中で、Laravelの各機能への理解が少しずつ深まってきたように思えます。
【豆知識】Tailwind背景色が何かおかしかった

# はじめに
自分でページを作成してく中で、知らぬ間に自分自身でいつ入れたのかわからなくなってしまったコードや、設定をそもそも間違えていたのか、原因がはっきりとしないけど無事解決したかな？というお話。
今回は背景色についてやっと私が正常だと思う状態になったので、一連の流れをまとめてみます。

## 環境
- Windows, WSL
- Docker
- Ruby 3.2.3
- Rails 7.1.3


## 背景色を真っ白にしたい！
`rails new`をして、初めてトップページを作成したとき、背景色が次のような状態になっていました。あわい黒？

![Image](https://i.gyazo.com/96b5e74318a04bd074624f881857b4aa.png)


当時はとりあえずそのままにして作成してきましたが、改めて背景色を真っ白にしたいと思いました。

### 1：はじめに試したこと
`・tailwind.config.js` にカスタムカラー設定を追加して、背景色を白色に変更する方法を行ってみました
```ruby
（  theme～pluginsの前までの｝のコードを追加）
module.exports = {
  content: [
    './app/views/**/*.html.erb',
    './app/helpers/**/*.rb',
    './app/assets/stylesheets/**/*.css',
    './app/javascript/**/*.js'
  ],
  theme: {
    extend: {
      colors: {
        'custom-white': '#ffffff', // 白色を追加
      },
    },
  },
  plugins: [require("daisyui")],
};
```

そしてコンテナに入り`npm run build:css`でビルド再実行しましたが、背景色は改善されず😢

### 2：もう少し調べて、試してみる
app/views/layouts/application.html.erbファイルでbodyクラスがどうなっているか確認してみると・・・
```ruby
<!DOCTYPE html>
<html>
  <head>
    <title>タイトル</title>
    省略
  </head>
  <body class="min-h-screen bg-natural relative font-main">
```

このbodyクラスがナチュラルを変更することで改善が期待できる。という事で次のように変更しました

```ruby
  <body class="min-h-screen bg-white relative font-main">
```
whiteに変えることで背景色が白に！無事解決。


# さいごに
背景色がおかしいとき、どこを見に行けばいいのかを知ることができました。
ナチュラルは当然白という謎の思考が「ここを修正してみても意味ないでしょ」という状態に。
実際に修正してみて、初めて気づくことが多いなとかんじています。
今回の記事が何か参考になれば幸いです。
[ODC]Timer実行中のWake Timer Actionの効果を確認する

Timer全体については、以下の記事で、OutSystems 11と比較しながら見た。

https://qiita.com/jyunji_watanabe/items/68c652ae3515c45c14ef

その中で、ODCのTimerについては、Timer毎に個別のコンテナが作られ、コンテナ内でスケジュールを管理するという記述があった (cronを使っているらしい）。

次回実行管理の仕組みが（O11から）変わっていることから、実行中にWake Timer Actionを使った場合の動作がどうなるかを確認しておきたい。

# 環境情報
ODC Studio(Version 1.4.21)

# 先に結論（確認結果）
- Timer実行中にWake Timerを呼ぶと、Timer終了後、再び動き始める
- このときNext runには何も設定されない（ODC Portalから、未実行のTimer実行リクエストが溜まっていることは判断できない）
- Timer実行中にWake TimerをN (> 1) 回呼んでも、その後実行されるTimerは1回だけ（リクエスト全部がキューされるわけでなく、次回実行予定があるか、のフラグ管理に見える）

# テスト用セットアップ
## テストシナリオ
- 実行に時間がかかるTimerを準備する
- そのTimerをWake Timerで起動する画面を用意する
- 画面からWake Timerを数秒おきに実行し、以下の点を確認する
    - Timerは何回実行されるか
    - Next runを始めとするTimerのプロパティはどう変化するか

## テスト用実装
### Timerを用意
実行時間が1分になるように実装するので、わかりやすくOneMinuteTimerという名前で作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/15b10560-352a-f477-f1dd-256a687e7a60.png)

### TimerのActionを用意
OneMinuteTimerに対応するActionの実装。
今回の検証に中身は必要ないため、(System)/Sleep Actionで1分間止めるだけにしておいた。前後でLogMessageを出力し、処理開始と終了をODC PortalのLogsで追えるようにしてある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/eac93dac-8cbc-e51d-eb89-ec656ac7b6ee.png)

### ScreenとWake TimerするButtonを用意
UIはScreen上にButtonを配置するだけなので省略。
Buttonのイベントハンドラーは、以下のServer Actionを呼ぶ（LogMessageはLogsで追えるように配置。Wake Timerを呼ぶ）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/69b3a9af-c495-03af-eee3-274cc77110ed.png)

# 動作確認
## Wake Timer Actionを三回呼んだ場合
1回目のWake TimerでServer Actionの実行開始を確認後、Wake Timerを2回呼んだ後でODC Portalを確認。
Next runは設定されず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/a19bdf95-bc97-6823-826f-12bc25e833e3.png)

以下はODC PortalのLogsのスクリーンショット。Message末尾が
- Start: TimerのAction開始
- End: TimerのAction終了
- Wake: Wake Timer Action呼び出し

を示す。

吹き出しに書いたように、
- 1回目のWakeによってTimerが開始されたのを、Startのログで確認してから、さらにWake Timerを2回呼んでいる
- Timer実行中のWake Timer呼び出しは空振りにはならず、実行中のTimerが終わるともう一度実行開始する
- ただし、このWake Timer呼び出しが複数あったとしてもTimerが実行されるのは一度（スクリーンショットではTimer実行中に2回Wakeされているのに、End後にTimerは一回だけ実行された）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/15605c7e-1e5f-60fa-0cdb-8be98ca41a7c.png)


## Timerが開始する前に2回目以降のWake Timerを呼んだ場合
Timerは1回しか実行されない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/d1dd1f88-6813-5a98-3252-a13758312648.png)
テスト113

```vb

Sub SQL_Proc()
'-----------------------------
'参照設定
'Microsoft ActiveX Data Objects 6.1 Library
'Excel内で4つのシートを元にクロス集計を使ったSQLサンプル
'クロス集計で得意先別商品別売上集計表を作る....〆('ω' )
'-----------------------------
Dim CN As ADODB.Connection
Dim RS As ADODB.Recordset
Dim i As Long
Dim Output_Sh As Worksheet
Dim str_SQL As String
Dim Field_Name As Variant

Set Output_Sh = ThisWorkbook.Sheets("出力先")
Set CN = New ADODB.Connection
Set RS = New ADODB.Recordset

CN.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
               "Data Source=" & ThisWorkbook.FullName & ";" & _
               "Extended Properties='Excel 12.0;HDR=YES' "

str_SQL = "TRANSFORM Sum([単価]*[数量]) AS 金額 " & _
                 "SELECT A.商品名 " & _
                 "FROM [T_商品マスター$] AS A INNER JOIN " & _
                     "([T_得意先マスター$] AS B INNER JOIN ([Ｔ_売上伝票$] AS C INNER JOIN " & _
                                                          "[T_売上明細$] AS D " & _
                                                          "ON C.伝票番号 = D.伝票番号) " & _
                     "ON B.得意先コード = C.得意先コード) " & _
                 "ON A.商品コード = D.商品コード " & _
                 "GROUP BY A.商品名 " & _
                 "PIVOT B.得意先名; "

'クロス集計を実行
Set RS = CN.Execute(str_SQL)

i = 1

'集計結果を[出力先]シートへ出力する
With Output_Sh

    .Cells.Clear
    
    For Each Field_Name In RS.Fields
    
        .Cells(1, i).Value = Field_Name.Name
        i = i + 1
    
    Next Field_Name
    
    .Range("A2").CopyFromRecordset RS

    .Columns.AutoFit
    
End With

Set RS = Nothing
Set CN = Nothing

MsgBox "処理が終了しました。", vbInformation

'○完成イメージ
'            得意先名1   得意先名2   得意先名3   得意先名4   得意先名5
'商品名1
'商品名2
'商品名3
'商品名4
'商品名5
'商品名6
'商品名7

End Sub
RecyclerView.ViewHolderのライフサイクル

通常は意識する必要は無いと思いますが、RecyclerViewのViewごとに表示状態のログを取ったり、非同期処理の後片付けを行いたいなどの理由で、正確なライフサイクルを知りたい場合もあるかと思います。
まあ、そういう状況になったので調べましたというエントリーです。

# ViewHolderのライフサイクルイベント

ViewHolder自身にはイベントを受け取る仕組みはありませんが、RecyclerView.Adapterがそれぞれのイベント受け取っているため、必要に応じてViewHolderへ伝えるように実装できます。

# スクロール

RecyclerViewをスクロールしていった時に発生するイベントは以下のようになります。

### セルの表示

**onCreateViewHolder**
ViewHolderを作成する。この時点ではViewTypeのみ確定でどのデータを表示するかは決まっていない。名前の通りリサイクルされるため、表示に必要な数＋キャッシュ分しか作られず、作成済みのインスタンスが使い回される。

**onBindViewHolder**
ここで表示位置が確定し、その位置に対応するデータと紐付けて表示などを変更する

**onViewAttachedToWindow**
実際に表示される

### セルが画面外に出る

**onViewDetachedFromWindow**
非表示になる

### 再利用開始

**onViewRecycled**
Detachされて即座にリサイクルされるわけではありません、再表示のためにしばらく保留されます。
画面外に出て十分に離れた場所までスクロールしたときに、リサイクルが行われます。

### 別のセルへの再利用

**onBindViewHolder**
リサイクルが行われ、別のセルの表示のために利用されます。表示する位置が指定され、そのデータを紐付け、表示を変更します。

**onAttachedToWindow**
新しいデータでViewが表示される

----

上記のような順序でライフサイクルイベントが発生します


# データの変更

RecyclerViewでデータの変更が伴う場合、Viewすべての作り直しでは無く、更新されるポイントに絞って更新を行うのが通常です。操作が限定的な場合以外は、notifyItemXXXメソッドを使うのではなく、DiffUtilsやListAdapterを使うことが多いでしょう。この状況でデータ列に変更を加えた場合にどうなるかを調べました。

なお、ItemAdapterにて、アニメーションを行うために新しいViewHolderが作られてしまう場合があります。デフォルトの`SimpleItemAnimator`の場合、以下のようにすることで、この挙動を抑制することができます。この状態で検証してみます。

```kotlin
(recyclerView.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
```

### 並べ替え

個々のデータは変化せず、順序が入れ替わった場合です。

（並べ替えの結果表示される要素が変化しない場合）何も呼び出されません。
ViewHolderが保持するViewの表示位置が変更されただけですから何も呼び出されません

### 要素の削除

データ列から要素を削除した場合です。

**onViewDetachedFromWindow**
**onViewRecycled**
削除されたデータに対応するViewが表示されている場合、onViewDetachedFromWindowとonViewRecycledがコールされます。

### 要素の追加

データ列に新しい要素を追加した場合です。

**onCreateViewHolder**
**onBindViewHolder**
**onViewAttachedToWindow**

ViewHolderが作成済みのキャッシュから使われる場合は、onCreateViewHolderが呼ばれないですが、
新規要素が表示された場合と同様です。追加されたことで画面外にで多要素がある場合は、スクロールと同様です。

### コンテンツの変更

同一のデータであるが、内容が異なると判定される変化があった場合です。

**onBindViewHolder**
対象のViewHolderに対してonBindViewHolderが呼び出されますので、ここで表示コンテンツを書き換えます。

### 別データとの入れ替え

一部のデータが別のデータであると判定される内容に変化した場合です。

旧要素について
**onViewDetachedFromWindow**
**onViewRecycled**

新要素について
**onCreateViewHolder**
**onBindViewHolder**
**onViewAttachedToWindow**

扱いとしては、要素が削除されて別の要素が追加された、という扱いになるので削除と追加の挙動が発生します。

### ViewTypeが異なるデータとの入れ替え

異なるViewHolderと入れ替えられる言うだけで、別データとの入れ替えと全く同じなので省略

# まとめ

まとめると以下のようなライフサイクルになっています。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/b05fa41b-b554-db6a-1bd9-bef5bec0d436.png)

具体的な例で言えば、

表示の開始、終了をロギングする場合は、
onViewAttachedToWindow、onViewDetachedFromWindowを監視する

表示データが画像のURLでそのダウンロードを非同期に行う場合、
onBindViewHolderで開始
onViewRecycledか、次のonBindViewHolderでそのタスクのキャンセルを実行する

といった使い方になりそうですね。
AWS AIF Beta合格記(2024/9/1投稿)

## :beginner:はじめに
この度AWS Certified AI Practitioner(AIF-C01)を受験してきましたので、勉強した内容と受験した感想を書いておきます。
※試験内容には言及できないので、本記事では勉強方法や受験した感想が中心となります


## :sun_with_face: 試験概要
少し前に当試験に合格された@handy-dd18さんの記事がとても分かりやすくまとめられていたのでそちらのリンクを張らせていただきます。

https://qiita.com/handy-dd18/items/724c67c7b2fa63e2ea89


## :pencil2:学習内容
https://www.udemy.com/course/aws-ai-practitioner-certified

こちらはAI基礎の解説と各種サービスの説明/ハンズオン開設の動画になります。
私はハンズオンはスキップして不安なサービスやAIの概念の部分を中心に学習いたしました。

https://www.udemy.com/course/practice-exams-aws-certified-ai-practitioner/

こちらは問題をひたすら解いて解説を見るを繰り返す感じですね。
私は2周して、2回目は80~85%程度くらいの理解度で試験に挑みました。

## :nerd:受験した感想
まず...難しかったです:confounded:
プラクティショナーレベルと舐めてかかると痛い目に合うかもしれません:skull:
私の理解度が浅かっただけの可能性は大いにございますが、
AI基本用語の理解/サービス概要レベル＋もう一歩踏み込んだ知識と理解度があった方が安定して合格が狙えるかなと感じました。


日本語がちょこちょこおかしかった感じがしました:joy:
ふだん英名で覚えてる用語等が無理やり日本語になっていたので、
ちょこちょこEnglishモードにしながら問題を解いていきました。

時間的には私は全問見直しまでして15分程度残しで終わりました。
時間が足りなくなる心配はあまりないかなーという印象です。

## :page_facing_up:受験結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2933489/9e102048-366c-89da-0028-5e0a5ac5ac6a.png)
余裕はないですが…合格は合格です:stuck_out_tongue::v:
MLS-C01を一応保持している為、その知識が役に立ったのが大きかったように感じます。

## :ramen:締め
https://qiita.com/kikuziro/items/9591b5dd9425acf04144

こちらの投稿で私の勉強内容はまとめているのですが、この記載内容レベルの理解度では安定した合格は少し厳しいと感じました:confounded:こちらの内容である程度の概要レベルの理解をした上で、もう少し広く/深く学習する必要があるかもしれません。

次は AWS Certified Machine Learning Engineer - Associate に向けて頑張りたいと思います:muscle:

今後試験受けられる方に幸あれ:pray:
PostmanでNotionAPI使ってみた

# はじめに
本記事では、API初心者の僕がNotion APIを使おうとした際に、
APIを簡単に実行できるPostmanというツールを使用して
NotionAPIを使ったので紹介していきます。

# Notion
Notionとは、メモ、タスク管理、データベース、Wikiなどのさまざまな機能を
1つのツールに集約した「オールインワンオールインワンワークスペース」といわれるツールです。

https://www.notion.so/ja

web版、デスクトップ版、IOS、AndroidOSに対応しています。

# APIについて
APIとは、Application Programming Interfaceの略で、
ソフトウェア同士が情報をやり取りするための窓口のようなものです。
面白そうなAPIが多くあるので、
ぜひ調べて使ってみてください。

# Postmanってどんなツール？
Postmanは、APIの開発・テストを効率的に行うためのツールです。

https://www.postman.com/

HTTPリクエストを送信し、APIのレスポンスを確認することで、APIの動作を検証できます。

こちらで紹介されていたので今回使用させていただきました。

https://qiita.com/ulxsth/items/3434471ac91f8fa311cf


# 実際に使用してみた

## インストール
下記リンクにてダウンロード・インストールを行ってください。

https://www.postman.com/downloads/

## リクエストを作成
### 新規追加
こちらのプラスボタンから作成ができます。
![Screenshot_create_request.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301530/6252b8f5-5b13-d17a-f8f5-7a863b4473bc.png)

### URL設定
送信先のURLを設定します。
今回は`https://api.notion.com/v1/pages`です。
また、**GET**を**POST**に変更しておいてください。
![Screenshot_url_setup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301530/83ee63ee-f3fc-fc18-c32c-289301838f1f.png)


### APIトークンの設定
APIトークンを設定します。
ここには、取得したトークンを入力します。
![Screenshot_authorization_setup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301530/dde4d2d7-eeb1-fa67-3502-1472457dbd75.png)


トークンのはこちらから取得できます。

https://www.notion.so/profile/integrations

### ヘッダの設定
バージョンをヘッダに設定します。
記事作成時は、`2022-06-28` です。
![Screenshot_parameter_setup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301530/02827cbf-2611-d646-0b84-d68005397827.png)


現在のバージョンは以下から確認できます。

https://developers.notion.com/reference/versioning


### ボディの記述
最後にボディに送信する内容を記述します。
今回は、対象のデータベースに追加するものです。
ボディタブから**Row**を選択
種類をJsonに変更してボディに記述します。
![Screenshot_body_setup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301530/126af4c5-a89c-bbc5-85be-660b282d6f66.png)


ボディの内容です。
`database_id`やプロパティ名は各自の値を入力してください。

```json
{
    "parent": {
        "database_id": "xxxxxxxxx"
    },
    "properties": {
        "タイトル": {
            "title": [
                {
                    "text": {
                        "content": "test001"
                    }
                }
            ]
        },
        "Date": {
            "date":{
                "start":"2024-04-01"
            }
        }
    }
}
```


こちらが今回参考にした記述です。

https://chuqk.com/post/fastest-notion-memo-ios-shortcut 

APIリファレンス

https://developers.notion.com/reference/intro

## 実行結果
送信ボタンを押すと、実行します。
結果は以下のようになります。
![Screenshot_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3301530/7f8225a1-7c29-be4d-b062-8ddc3d33b5e2.png)



# おわりに
APIにあまり触れて来なかったので、新しい世界が一つ開けたような感じです。
これを機に色々なAPIにも触れていけたらなと思います。
CURLでMQTTテストクライアントpubするときのエラー

TLS1.2 で接続確認のために、このようなコマンド
```curl
curl --tlsv1.2 \
--cacert AmazonRootCA1.pem \
--cert client.pem.crt \
--key private.pem.key \
--request POST \
--data "{\"Temperature\": 77, \"Humidity\": 88, \"Time\": 12349876}" \
"https://<INSERT-YOUR-IOT-DATA-ENDPOINT-HERE>:8443/topics/outTopic?qos=1"
```
を
コマンドプロンプト、GitBash、PowerShellで試してみたが、
```
curl: (58) schannel: Failed to import cert file client.pem.crt, last error is 0x80092002
```
のエラーになった。

# 解決方法
WSLを使用する。

Windowsのcurlは通常schannel（WindowsのSSL/TLSライブラリ）を使用するが、opensslを使用するバージョンに切り替えると、証明書関連の問題を回避できることがある？
→　 curl のバイナリをopensslサポートのあるバージョンに置き換えるか、WSL (Windows Subsystem for Linux) でcurlを実行して、opensslを利用する方法がある、とのこと

以上