OmniAICreator/Qiita-1.07M huggingface dataset:
FastAPIをdockerで動作させ、コードの更新をリアルタイムで反映する方法

# 初めに
ChatGPTに聞いた回答そのままですが完璧だったので掲載
「docker-compose up」が「docker compose up」に変わったようなので反映

# 以下回答
DockerでFastAPIを実行し、コードの変更をリアルタイムで反映させるには、いくつかの方法があります。その一つは、ホストマシン上のファイルシステムをDockerコンテナにマウントし、FastAPIのリローディング機能を使用する方法です。

以下に、その手順を示します。

### 1. FastAPIプロジェクトの構成

まず、基本的なFastAPIプロジェクトを準備します。

#### ディレクトリ構造
```
my_fastapi_project/
├── app/
│   ├── main.py
├── Dockerfile
├── requirements.txt
├── docker-compose.yml
```

#### `app/main.py`
```python
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}
```

#### `requirements.txt`
```
fastapi
uvicorn
```

### 2. Dockerfileの作成

次に、FastAPIアプリケーションを実行するための`Dockerfile`を作成します。
python:3.9-slimは好きなバージョンに変更して大丈夫です。

#### `Dockerfile`
```Dockerfile
FROM python:3.9-slim

# 作業ディレクトリを設定
WORKDIR /app

# 依存関係をインストール
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# アプリケーションのコードをコピー
COPY ./app /app/app

# FastAPIアプリケーションを起動
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
```

`--reload`オプションは、コードの変更を監視し、自動的にリロードするためのものです。

### 3. docker-compose.ymlの作成

開発時にホストマシンのコードをコンテナにマウントするために、`docker-compose.yml`ファイルを作成します。

#### `docker-compose.yml`
```yaml
services:
  web:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - ./app:/app/app
```

### 4. Dockerコンテナのビルドと起動

次に、Dockerコンテナをビルドして起動します。

```sh
docker compose up -d --build 
```

このコマンドは、`Dockerfile`を使用してコンテナをビルドし、`docker-compose.yml`の設定に従ってコンテナを起動します。
-d オプションを指定しない場合はコンソールを閉じるとコンテナが終了してしまいます。

### 5. リアルタイムでのコードの更新

ホストマシン上の`my_fastapi_project/app`ディレクトリ内のファイルを編集すると、変更がリアルタイムでDockerコンテナに反映され、FastAPIが自動的にリロードされます。これにより、変更を即座にテストすることができます。
app/main.pyを更新すると更新内容リアルタイムで反映されます。

### まとめ

この手法を使用すると、FastAPIのコード変更をリアルタイムで反映させることができます。開発中は、ホストマシンのファイルシステムをコンテナにマウントし、FastAPIの自動リロード機能を利用することで、効率的に開発を進めることができます。



# 追記
終了するときは以下のコマンドを使います。

```sh
docker compose down
```
avroファイルをJupyterノートブックで開く

メモ：


```python
import fastavro
import pandas as pd
import cramjam
from io import BytesIO

def read_avro_file(filename):
    records = []
    with open(filename, 'rb') as f:
        reader = fastavro.reader(f)
        for record in reader:
            records.append(record)
    return records

avro_file = './allevents.avro'

# Read
avro_data = read_avro_file(avro_file)

# Dataframe magic!
df = pd.DataFrame(avro_data)

# display as table! 
df
```
既存のChromeブラウザをSeleniumで操作する方法

Seleniumは通常、新しいブラウザインスタンスを起動して自動化を行いますが、既存のChromeブラウザセッションを操作することも可能です。この記事では、その方法について詳しく説明します。

## 前提条件

- Python 3.6以上
- Selenium WebDriver
- Google Chrome
- ChromeDriver（Chromeのバージョンに対応したもの）

## 手順

### 1. Chromeをデバッグモードで起動

まず、Chromeブラウザをリモートデバッグモードで起動する必要があります。以下のコマンドをコマンドプロンプトで実行します：

```
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --user-data-dir="C:\Users\[YourUsername]\AppData\Local\Google\Chrome\User Data" --profile-directory="Profile 5" --no-sandbox --remote-allow-origins=*
```

注意：
- パスは実際のChromeのインストール場所に合わせて調整してください。
- `[YourUsername]`を実際のWindowsユーザー名に置き換えてください。
- `--profile-directory`は使用したいプロファイルに合わせて変更できます。

### 2. Pythonスクリプトの作成

次に、以下のPythonスクリプトを作成します：

```python
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time

# 既存のChromeブラウザに接続するための設定
chrome_options = Options()
chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")

print("Chromeドライバーに接続しています...")
try:
    # WebDriverを初期化
    driver = webdriver.Chrome(options=chrome_options)
    print("Chromeドライバーに接続成功")
except Exception as e:
    print(f"Chromeドライバーへの接続に失敗しました: {e}")
    exit(1)

try:
    print("指定したURLに移動しています...")
    # 指定したURLに移動
    driver.get("https://www.example.com")
    print("URLに移動完了")

    print("ページの読み込みを待機しています...")
    # ページが完全に読み込まれるまで待機（最大10秒）
    WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.TAG_NAME, "body"))
    )
    print("ページの読み込み完了")

    # 現在のページのタイトルを取得して表示
    print(f"現在のページタイトル: {driver.title}")

    # 追加のデバッグ情報
    print(f"現在のURL: {driver.current_url}")
    print(f"ページソースの長さ: {len(driver.page_source)} 文字")

except Exception as e:
    print(f"エラーが発生しました: {e}")

finally:
    print("スクリプトが完了しました。")
    # 3秒待機してからスクリプトを終了（状態を確認するため）
    time.sleep(3)
```

### 3. スクリプトの実行

Chromeをデバッグモードで起動した後、上記のPythonスクリプトを実行します。

## スクリプトの説明

1. **Chromeオプションの設定**:
   `chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")`で、既存のChromeインスタンスに接続するための設定を行います。

2. **WebDriverの初期化**:
   `driver = webdriver.Chrome(options=chrome_options)`で、既存のChromeセッションに接続します。

3. **ページ遷移**:
   `driver.get("https://www.example.com")`で指定したURLに移動します。

4. **ページ読み込みの待機**:
   `WebDriverWait`を使用して、ページが完全に読み込まれるまで待機します。

5. **ページ情報の取得**:
   タイトル、URL、ページソースの長さなどの情報を取得し表示します。

## 注意点

- このメソッドは開発やデバッグ目的で使用することをお勧めします。
- `--no-sandbox`オプションはセキュリティリスクがあるため、本番環境では使用しないでください。
- 既存のブラウザセッションを操作するため、ブラウザ履歴やクッキーが保持されます。

## まとめ

この方法を使用することで、既存のChromeセッションをSeleniumで操作できます。これは特に、ログイン状態を維持したままテストを行いたい場合や、特定のブラウザ設定でテストを実行したい場合に非常に有用です。
【WRO用】ev3rtの環境説明書テンプレ

:::note info
### 2024/08/11更新
アプリケーションの起動方法などについてテンプレート追記しました。
:::

# テンプレート
:::note info
本テンプレートは使用自由です。
**【 】** 内はご自身の環境に合わせ変更してください。
:::

```
プラットフォーム名：TOPPERS/EV3RT（Real-Time platform for EV3）v【使用しているバージョン】
        TOPPERS/HRP3【もしくは"TOPPERS/HRP2"】カーネルをベースとしたEV3用の開発プラットフォーム。
        パッケージは https://dev.toppers.jp/trac_user/ev3pf/wiki/Download からダウンロード可能
        詳細は https://dev.toppers.jp/trac_user/ev3pf/wiki/WhatsEV3RT を参照。
        
開発環境（PC側）
    OS：【使用しているOS："Windows 11"など】
        ・GNU Tools for ARM Embedded Proocessors 5（クロスコンパイラ）使用
        【WindowsでCygwin使用の場合："・Cygwin（UNIXコマンドを使用するための互換レイヤ）使用"】
        【WindowsでWSL1使用の場合："・Windows Subsystem for linux 1（UNIXコマンドを使用するための互換レイヤ）使用"】
        【WindowsでWSL2使用の場合："・Windows Subsystem for linux 2（UNIXコマンドを使用するための仮想環境）使用"】
    テキストエディタ：Visual Studio Code【その他ご使用のテキストエディタ】
    
実行環境（ロボット側）
    インテリジェンスブロック：EV3
        ・MicroSDカードにプラットフォーム パッケージ「sdcard」フォルダのファイル＋プログラムファイル（バイナリ）をコピーし使用
    ・プログラムの起動・確認は
            決定ボタン => 数秒でアプリローダが起動 =>
            そのまま決定ボタン => ロードメニューが表示 =>
            そのまま決定ボタン => ここにプログラム一覧と"Cancel"が表示される =>
            "runWRO"を選び決定ボタン => プログラム実行状態に =>
            決定ボタン => 動作開始
    ・プログラムの停止は
            戻るボタン長押し => 決定ボタン => 戻るボタンを軽く押す
    ・EV3のシャットダウンは
            右ボタン => 画面下部に"ShutDown"が表示 =>
            決定ボタン
            
提出したプログラムファイルについて
    runWRO.zip【WROに提出するプログラムのZIPファイル名】
        ├ app.c（メインのソースコード）
        ├ app.cfg（タスク情報などを定義するファイル）
        ├ app.h（app.cのヘッダファイル）
        ├ 【その他ソースコード："xxx.c（関数を定義するソースコード）"など】
        └ Makefile.inc（コンパイルのルールなどを定義するファイル）
    実行時は開発環境にてコンパイルし、バイナリファイルの状態でMicroSDカードにコピーし使用
    
```
# 使用例
たとえば、Koushiro A（@koushiro）さんの記事シリーズ「もっと!後輩たちのためのEV3rt講座」どおり準備された環境では、次のようになります。

https://qiita.com/koushiro/items/26aca0cb10c1d34c03a1

```
プラットフォーム名：TOPPERS/EV3RT（Real-Time platform for EV3）v1.1
        TOPPERS/HRP3カーネルをベースとしたEV3用の開発プラットフォーム。
        パッケージは　https://dev.toppers.jp/trac_user/ev3pf/wiki/Download　からダウンロード可能
        詳細は　https://dev.toppers.jp/trac_user/ev3pf/wiki/WhatsEV3RT　を参照。
        
開発環境（PC側）
    OS：Windows 10
        ・GNU Tools for ARM Embedded Proocessors 5（クロスコンパイラ）使用
        ・Windows Subsystem for linux 2（UNIXコマンドを使用するための仮想環境）使用
    テキストエディタ：Visual Studio Code
    
実行環境
    インテリジェンスブロック：EV3
        ・MicroSDカードにプラットフォーム パッケージ「sdcard」フォルダのファイル＋プログラムファイル（バイナリ）をコピーし使用
    ・プログラムの起動・確認は
            決定ボタン => 数秒でアプリローダが起動 =>
            そのまま決定ボタン => ロードメニューが表示 =>
            そのまま決定ボタン => ここにプログラム一覧と"Cancel"が表示される =>
            "runWRO"を選び決定ボタン => プログラム実行状態に =>
            決定ボタン => 動作開始
    ・プログラムの停止は
            戻るボタン長押し => 決定ボタン => 戻るボタンを軽く押す
    ・EV3のシャットダウンは
            右ボタン => 画面下部に"ShutDown"が表示 =>
            決定ボタン
            
プログラムファイル
        runWRO.zip
        ├ app.c（メインのソースコード）
        ├ app.cfg（タスク情報などを定義するファイル）
        ├ app.h（app.cのヘッダファイル）
        └ Makefile.inc（コンパイルのルールなどを定義するファイル）
    実行時は開発環境にてコンパイルし、バイナリファイルの状態でMicroSDカードにコピーし使用
```
nRFConnectSDKを基盤としたSesameの暗号通信 #1 開発ボードのチェック

![sesame](https://www.nordicsemi.com/-/media/Images/Products/DevKits/nRF52-Series/nRF52840-Dongle/nRF52840-Dongle-rev2-prod-page.png?h=750&iar=0&mw=350&w=350&hash=994DC726E9F3DBB12056C07F5DC0A802&width=1600)

# 目的
開発ボードのチェック

# 技術
- LED X1
- Button X1
- USB X1



# 雑談

実物の開発ボードを手に入れたら、必ず何度もチェックしてください。どこで購入したのか、どの供給業者なのか、いくらだったのかを詳細に確認することが重要です。会社が偽物を購入する可能性もあります。どうしてそれを知っているのかは聞かないでください。

# 心配
Dongleという言葉には、実際には簡略化されたバージョンの意味が含まれています。そのため、私はDongleが同時に書き込みとシリアルポートの監視の要求を満たすことができるかどうか心配です。現在、開発環境はまだインストールされていないので、インストールが完了したら確認できます。

nRF52840 Dongle HW device together with nRF Connect for Desktop. For other use cases please do note that there is no debug support on the Dongle, only support for programming the device and communicating through USB.


# 心配確認
[nrf52840 dongle not found in "connected devices" in vscode](https://devzone.nordicsemi.com/f/nordic-q-a/85098/nrf52840-dongle-not-found-in-connected-devices-in-vscode)

# 用語
 
- [nRF52840 Dongle](https://www.nordicsemi.com/Products/Development-hardware/nRF52840-Dongle):*開発ボード*

# 関連記事

- [nRFConnectSDKを基盤としたSesameの暗号通信](https://qiita.com/tse123321/items/c0fa105cd5b9f14c2a0c)
Secret of the Polyglot picoCTF writeup for beginner

<h3>記事説明</h3>
CTF初めて一カ月の主がPicoCTFのEasyをbeginnerむけに書いている記事です。CTFのwriteupではCTF常識が前提になっている記事が多く無知すぎてよくわからなかったので書くことにしました。至らぬところ等あると思いますのでご指摘いただけると嬉しいです。
#picoCTFbeginner


<h3>事前知識</h3>

<h4>Polyglot</h4>
複数のプログラミング言語として解釈可能なコンピュータープログラムまたはスクリプト。

<h4>ファイル形式変更方法</h4>
参考

https://jp.easeus.com/partition-manager/change-file-type-windows-10.html

<h3>flag獲得方法</h3>
まずファイルを開くと下記文字列が見つかる。

![スクリーンショット 2024-08-08 153535.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1972935/23a54c74-843f-5eeb-2585-05e59f1ffe36.png)

Polyglotという名前なので、pngファイルやjpgファイルにファイル形式を変えると下記画像になる。

![flag2of2-final.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1972935/4692c6c5-43af-9e0f-9891-28c89e522054.jpeg)

この二つの文字列をつなげ合わせるとフラッグになる。
picoCTF{f1u3n7_1n_pn9_&_pdf_90974127}
PythonでWebサーバを簡易的に立ち上げる。

## 適当なフォルダにindex.htmlを作成する。
以下のようにファイルを用意しておく
```
.
├─index.html
└─page.html
```
```index.html
<!DOCTYPE html>
<html lang="ja">
 <head>
    <meta charset="UTF-8">
    <script src="js/http.js" async></script>
    <title>HTML入門-JavaScriptの基本</title>
 </head>
 <body>
    <h1>文書の主見出し</h1>
    <a href="page.html">サンプルページ</a>
 </body>
</html>
```
```page.html
<!DOCTYPE html>
<html lang="ja">
 <head>
    <meta charset="uft-8">
    <script src="js/sample.js" async></script>
    <title>HTML入門-JavaScriptの基本</title>
 </head>
 <body>
    <h1>Hello, World</h1>
 </body>
</html>
```

## コマンドプロンプトから簡易的にPythonのWebサーバを呼び出す
index.htmlの置いたフォルダでコマンドプロンプトを起動する。
```
py  -m http.server 8080
```

## Webブラウザからサーバにアクセスする
ブラウザから`http://127.0.0.1:8080/`にアクセスする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3850581/f35edb9a-a486-89dd-2d0f-831806d466bc.png)

## 備考1
javascriptでpage.htmlへアクセスする実装を書いたが、HTTPエラーコード400でエラーになった。
URLが間違えていると出てくるエラーであるが、相対パスで置かれているファイルに間違いはない。

* 実装
```javascript
function fetchUserInfo(userId) {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", "https://127.0.0.1:8080/page.html");
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    const body = ""
    xhr.onload = () => {
        if (xhr.readyState == 4 && xhr.status == 201) {
            console.log(JSON.parse(xhr.responseText));
        } else {
            console.log(`Error: ${xhr.status}`);
        }
    };
    xhr.send();
}
```

```エラーメッセージ.
::ffff:127.0.0.1 - - [08/Aug/2024 17:37:15] "GET / HTTP/1.1" 304 -
::ffff:127.0.0.1 - - [08/Aug/2024 17:37:15] "GET /js/http.js HTTP/1.1" 304 -
::ffff:127.0.0.1 - - [08/Aug/2024 17:37:18] code 400, message Bad request version ('\\x02h2\\x08http/1.1\\x00')
::ffff:127.0.0.1 - - [08/Aug/2024 17:37:18] "\x16\x03\x01\x06À\x01\x00\x06¼\x03\x03ÊÓKK\\a÷ÄèP|\x17ç\x09UX\x98zvDºòÀ\x0e\x0d½ó."\x19\x98< ¥Ý\x85(-\x12©x;¼\x8a\x1d\x99\x95D/¡[¯Å=þZ¬\x17Y\x13\x9ceüµÝ\x00 ÊÊ\x13\x01\x13\x02\x13\x03À+À/À,À0Ì©Ì¨À\x13À\x14\x00\x9c\x00\x9d\x00/\x005\x01\x00\x06S\x9a\x9a\x00\x00\x00\x12\x00\x00\x00-\x00\x02\x01\x01\x00+\x00\x07\x06ªª\x03\x04\x03\x03\x00\x10\x00\x0e\x00\x0c\x02h2\x08http/1.1\x00" 400 -
::ffff:127.0.0.1 - - [08/Aug/2024 17:37:18] code 400, message Bad request version ('\\x00\\x12\\x00\\x10\\x04\\x03\\x08\\x04\\x04\\x01\\x05\\x03\\x08\\x05\\x05\\x01\\x08\\x06\\x06\\x01\\x00')
::ffff:127.0.0.1 - - [08/Aug/2024 17:37:18] "\x16\x03\x01\x07\x00\x01\x00\x06ü\x03\x03ZP[Å¤\x89g\x8e!øöc\x80þóu\x9fØR\x9a\x0fdøk 0åüEóW» \x95c¶\x89rÜjûâ-°\x10ÚÞ\x81òS½\x15öEB´'\x08¤k\x94\x90~¬9\x00 jj\x13\x01\x13\x02\x13\x03À+À/À,À0Ì©Ì¨À\x13À\x14\x00\x9c\x00\x9d\x00/\x005\x01\x00\x06\x93**\x00\x00\x00\x10\x00\x0e\x00\x0c\x02h2\x08http/1.1\x00+\x00\x07\x06ÚÚ\x03\x04\x03\x03Di\x00\x05\x00\x03\x02h2\x00#\x00\x00\x00\x0d\x00\x12\x00\x10\x04\x03\x08\x04\x04\x01\x05\x03\x08\x05\x05\x01\x08\x06\x06\x01\x00" 400 -
```

## 備考2
実装を書いてWebサーバを立ち上げる方法も調べていたが記事が少なく、上記の方法で記載しているものが多かった。

ソケット通信の方法を[以前](https://qiita.com/H_T_6221/items/3862cb3ba91f4ab71648)に調べており、実装を少し変更したがブラウザからアクセスが上手くできなかった。

実装を書いてWebサーバを立ち上げてみたい。


## 参考
https://yamapan.tokyo/?p=2542
Openpyxl: Border、値、スタイル、コラム幅のコピー

こちらのプログラムを改造して、値、スタイル、コラム幅もコピーするようにしました。
[Openpyxl: Border のコピー](https://qiita.com/ekzemplaro/items/ba414f899f3324b4ddf5)

## プログラム

```py:copy_borders_value.py
#! /usr/bin/python
# ---------------------------------------------------------------
#	copy_borders_value.py
#
#					Aug/08/2024
# ---------------------------------------------------------------
import sys
import openpyxl
from openpyxl.styles.borders import Border, Side
from openpyxl.utils import get_column_letter
# ---------------------------------------------------------------
def copy_cell_border(row_in,col_src,col_target):
	left_border = ws.cell(column=col_src, row=row_in).border.left.border_style
	right_border = ws.cell(column=col_src, row=row_in).border.right.border_style
	top_border = ws.cell(column=col_src, row=row_in).border.top.border_style
	bottom_border = ws.cell(column=col_src, row=row_in).border.bottom.border_style
#
#
	ws.cell(column=col_target, row=row_in).border = Border(left=Side(style=left_border), right=Side(style=right_border), top=Side(style=top_border), bottom=Side(style=bottom_border))
#
#
# ---------------------------------------------------------------
# [6]:
def copy_single_proc(ws,col_from,col_to):
	for row_in in range(2,ws.max_row):
		for it in range(7):
			no_from = col_from + it
			no_to = col_to + it
			copy_cell_border(row_in,no_from,no_to)
			col_letter_from = get_column_letter(no_from)
			col_letter_to = get_column_letter(no_to)
			column_width_A = ws.column_dimensions[col_letter_from].width
			ws.column_dimensions[col_letter_to].width = column_width_A
#
			cell_source = ws.cell(row=row_in, column=no_from)
			cell_target = ws.cell(row=row_in, column=no_to)
			cell_target.value = cell_source.value
			cell_target._style = cell_source._style
#
# ---------------------------------------------------------------
xlsx_in=sys.argv[1]
nn_in=int(sys.argv[2])
#
sys.stderr.write("xlsx_in = %s\n" % xlsx_in)
sys.stderr.write("nn_in = %d\n" % nn_in)
wb = openpyxl.load_workbook(filename=xlsx_in)
ws = wb.worksheets[0]
print(ws.max_row)
#
col_from = 10
for it in range(1,nn_in):
	jt = it -1
	col_to = 16 + jt * 6
	copy_single_proc(ws,col_from,col_to)
#
wb.save(xlsx_in)
# ---------------------------------------------------------------
```

## 実行コマンド

```bash
./copy_borders_value.py in01.xlsx 4
```
サードパーティCookieについての理解

今更、サードパーティCookieってどんな仕組みなんだっけとふと思ったので調べた。

## Cookieについての理解
サイトにリクエストを送った際に返ってくるデータ、「レスポンス」。
その中にボディ（ページ情報）とかと一緒に混じっているもの。
サーバーが通信した端末（PC,スマホ）を特定するためのもの。
そんなもの使わなくても通信した端末は特定できそうに思うけど、出来ない。（この特性をステートレスと言う）
つまり、このサイトと二度目以降通信する際に「前に通信した者です」という烙印を押された状態で通信をすることになる。
サーバー側は「おぉ、君か。前に入力してくれた情報をもう一回表示するよ」みたいな親切ができる。

## Cookieは危険だ！という話をよく聞くが...
最初は上記の通りの認識で、「そんなに危険かな？」という理解だった。
その理解は合っていた。
上記のCookieは「ファーストパーティーCookie」と呼ばれる善のCookieだった。
危険だとよく言われるのは「サードパーティーCookie」と呼ばれるCookieだった。

## サードパーティーCookie
例えばアクセスしたサイトA(映画サイト)に、サイトBの作った広告枠が埋め込まれていたとする。
すると、ブラウザはその広告を取得するためにサイトBにもリクエストを送る。
当然そこで返ってくるレスポンスの中には、サイトBのCookieが練りこまれている。
サイトA（ファーストパーティー）に用があるのに、無関係な第三者のサイトB（サードパーティー）からのCookieがブラウザに保存されてしまう。
なのでサードパーティーCookie。
真の恐怖はここから始まる。

## アクセスしたサイトがばれる
今、サイトBのCookieを持っている。
ここでサイトC（美容ブログ）にアクセスする。
その中にはサイトBの広告枠が埋め込まれている。
ブラウザはサイトBにリクエストを送る。（ドメインは一緒で、広告の埋め込まれたサイトごとにパラメータが違うんだと思う）
**サイトB「おっ…こいつはサイトA（映画サイト）からうちにアクセスしてるな。じゃあ広告の中身は映画だ！」**
と、こんな感じでアクセスしたサイト履歴がばれていく。
【.NET MAUI】iOSウィジットの署名がおかしいのを修正する

## 何が起きたか

.NET MAUI(iOS)アプリに、iOSのウィジットを組み込んだアプリで、UserDefaultsの情報が共有されない状態になりました。

色々Try-And-Errorで試していたところ、どうやらアプリやウィジットの署名をしなおすと解決するようだったのでそのときの記録を残しておきます。

## 環境

このページの作業は、以下の環境で確認しました。

- macOS Ventura (Intel)
- Xcode 15.2
- Visual Studio Code + MAUIの拡張機能
- .NET SDK 8.0.302
- Visual Studio for Mac (インストールしていますが今回はIDEを使用していません)
  ※当作業時にMac版はすでに提供終了が決まっています

## 何をして解消したか

.NETでビルドの署名後に、手動でアプリやウィジットを再署名するようにして解消しました。

**.csproj**

まず、以下の定義を追加し、.NETによる署名後に任意のスクリプトを実行を割り込ませるようにしました。

```xml
<Target Name="PostBuild" AfterTargets="_CodesignVerify">
    <Exec Command="bash $(MSBuildProjectDirectory)/path/to/resign.sh $(MSBuildProjectDirectory)/$(_AppBundlePath)" />
</Target>
```

**resign.sh**

アプリ本体や、ウィジットに対して再署名をする処理を書きました。
以下はウィジットに対してのみ実施していますが、インストール時に問題が起きる場合もあったため、アプリ本体も再署名したほうが良さそうです。
再署名が必要かどうかは、プロジェクトによってまちまちでした。

```shell
#!/bin/bash
WIDGET_PATH=$1/PlugIns/widget.appex
rm -fr $WIDGET_PATH/_CodeSignature
rm $WIDGET_PATH/embedded.mobileprovision
cp /path/to/widget.mobileprovision $WIDGET_PATH/embedded.mobileprovision
codesign -f -s "certificate name" --entitlements /path/to/widget.entitlements $WIDGET_PATH
```

**widget.entitlements**

再署名の際に使用するEntitlementsファイルを用意しました。
以下は、ウィジットでAppGroupsを使用する場合の例です。適切な内容に書きかえてください。

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>application-identifier</key>
	<string>TEAMID.com.example.app.widget</string>
	<key>com.apple.developer.team-identifier</key>
	<string>TEAMID</string>
	<key>com.apple.security.application-groups</key>
	<array>
		<string>group.com.example</string>
	</array>
	<key>get-task-allow</key>
	<true/>
</dict>
</plist>
```

**widget.mobileprovision**

再署名時に使用するプロビジョニングプロファイルを用意しました。
Apple Developerから適切なものをダウンロードするだけです。

## 最後に

上記の状況から推察すると、.NETビルドによる署名の処理に何かしら問題がある可能性が考えられます。ただし、その証跡を得るまでには至っていません。
読書記録 2024/7/29週

## 本の情報
**タイトル**
メタ思考トレーニング 発想力が飛躍的にアップする34問
**著者**
細谷 功

## 本の内容
メタ思考＝物事を一つ上の視点から考えることが重要。
メタ思考を身に着けることによって以下の効果がもたらされる。
1. 成長するための「気づき」を得られる。
2. 思い込みや思考の癖から脱することができる。
3. 上記2つを基に、創造的な発想ができる。

メタ思考を身に着けるための手段として、「Why型思考」と「アナロジー思考」がある。
##### Why型思考
物事や問題に対して、「なぜ？」と問いかける考え方。
与えられたものにすぐ取り組まず、与えられたものそれ自体について考えること。
→与えられたもの自体は目的ではなく、目的を達するための手段であるはず。
　目的自体を見直すことで、本当の目的は何なのか・目的を達成する手段は他にあるのではないか を考えることができる。
5W1Hの中で、"Why"だけが物事の関係に着目しているうえ、繰り返し問いかけることが可能。
　"Why"を問うことで、メタ思考に進むことができる。

##### アナロジー思考
類似のものから推論する考え方。
単に何かを真似るのではなく、関係性や構造に着目して別の領域に応用すること。
→単に真似るだけでは、自分の頭で考えずに同じことを行っているだけ。
　関係性や構造を理解することで、別の領域に同じ仕組みを適用できたり新しい領域を理解することの助けになったりする。
関係性や構造を見出すためには、物事の共通点を取り出して一般化する「抽象化」が必要。
抽象化の考え方が、メタ思考となる。


## ためになったところ
* 具体的な問題
この本は、「メタ思考」で考えていない人に対して「メタ思考」の考え方をもたらすきっかけとなる本になっている。
そのため、表題にもなっているが具体的な問題が多数設定されている。
この問題を通して、思考が表面的なもので止まっていること / 具体的な事象の世界でしか考えていないこと を認識することができた。

* 弱点の記載
Why型思考とアナロジー思考の内容や価値について本の中で紹介されているが、同時にこれらの弱点も本に記載されている。
→Why型思考：時間を要する / 自他問わず不快感をもたらすことがある
　アナロジー思考：論理性のない飛躍した考えをもたらす
こういった弱点が記載されていることで、この本に書かれている思考法がすべてではなく、あくまで手段の一つである という意識を持つことができた。

## まとめ
思考力の問題を認識しているがどう問題なのか分からない という状態に対して腑に落ちる感覚を得られた本でした。
読み返して理解を深めつつ、実生活に応用していきます。
ありがとうございました。
PostgreSQLでハッシュパーティショニングの作成と、登録先確認

いつも忘れるので、備忘録
後で説明も追加します


# ハッシュパーティショニングの作成

``` :salesテーブルに作成する場合
CREATE TABLE sales (
    id serial primary key,
    value int
) PARTITION BY HASH (id);

-- パーティションテーブルの作成
CREATE TABLE sales_p0 PARTITION OF sales FOR VALUES WITH (MODULUS 1000, REMAINDER 0);
CREATE TABLE sales_p1 PARTITION OF sales FOR VALUES WITH (MODULUS 1000, REMAINDER 1);
-- ...続けて999まで
```

# 登録先確認

```
-- 親テーブルからのデータを確認
SELECT tableoid::regclass AS partition, *
FROM テーブル名;
```

# 消したい時

```
-- 親テーブルを指定すれば、パーティションテーブルもまとめて削除できる
DROP TABLE IF EXISTS sales;
```


# 類似記事

https://qiita.com/Jasmine_teeeeee/items/c781c3366a68143a1921
vbsの作法 その82

# 概要
vbsの作法、調べてみた。
練習問題やってみた。

# 練習問題
ファイルから、一致する文字を表示せよ。

# サンプルコード

```


Dim regEx, Match, Matches
Dim res
Set regEx = New RegExp
regEx.Pattern = "using(.*);"
regEx.IgnoreCase = True
regEx.Global = True

With CreateObject("Scripting.FileSystemObject")
	For Each f In .GetFolder("C:\Users\csc").Files
		if instr(f.Name, "txt") > 1 then
			Dim txt
			Set txt = CreateObject("ADODB.Stream")
			txt.Type = 2
			txt.Charset = "UTF-8"
			txt.Open
			txt.LoadFromFile(f)
			Do While Not txt.EOS
				readString = txt.ReadText(-2)
				res = ""
				Set Matches = regEx.Execute(readString)
				For Each Match in Matches
					res = res & Match.submatches(0) & " : "
					res = res & "一致する文字列が見つかった位置は、"
					res = res & Match.FirstIndex & " です。一致した文字列は、"
					res = res & Match.Value & " です。" & vbCRLF
				Next
				if res <> "" then
					msgbox res
				end if
			Loop
			txt.Close
			Set txt = Nothing
		End if
	Next
End With





```

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/6ae3c5f4-c7d3-b35b-fee7-43e69d915f4d.png)


以上。
VirtualBoxでWindowsVMを立ち上げたら「無人応答ファイルから…」のエラーが発生してしまう…

# はじめに
この記事ではVirtualBoxでWindows 10 VMのセットアップ時に「無人応答ファイルから<ProductKey>設定を読み取れません。」というエラーが発生した経験を基に対処方法をメモとして残しています

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677369/5d7aa39e-4d1a-612c-fb5b-5a3f6e8d74b2.png">

同じような経験で困った人がいたらお試しください

:::note warn
必ず解消される保証はないので参考程度でご覧ください
:::

# 環境
ソフトウェアバージョン：Oracle VM VirtualBox 7.0.18
仮想マシン：Windows 10

# 対処方法
1．一度事象が発生したVMをシャットダウン
2．対象のVMの[設定]>[ストレージ]を開く

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677369/0ff6ba4e-1c41-381b-a998-8866d49f0c8b.png">

3．コントローラー:Floppyにあるディスクを削除 :floppy_disk:

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677369/6c4c9bd6-2878-749a-b405-741e9149dec2.png">

4．OKをクリック
5．再度対象のVMを立ち上げる

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3677369/cfcd4c58-2587-24d8-f9f8-b1ada02efeae.png">

:::note 
Windowsセットアップのウインドウが出たら問題なくセットアップが続けられるはずです
:::

# 事象発生原因
今のところわかっていません…
もし何か情報を掴めたら更新しようと思います

# さいごに
記事を見ていただきありがとうございました
対処方法を試して解決していたら幸いです :tada:
新規構築したRHELのEC2にキーペアを設定せずにセッションマネージャー(SSM)で接続する方法。

## 概要
EC2を作成したが、セッションマネージャーだけで接続予定のためキーペアを設定したくない。
しかし、SSM Agentをインストールしないとセッションマネージャーに接続できない…
そんな場合の回避策です。

## 手順
1. インスタンスを停止
1. [アクション] - [インスタンスの設定] - [ユーザーデータを編集]
1. [ユーザーデータをテキストで変更]にチェックが入っている状態で、[ユーザーデータをここに配置]に以下を入力して保存
    ```bash
    #!/bin/bash
    sudo dnf install -y https://s3.amazonaws.com/ec2-downloads- 
    windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
    sudo systemctl enable amazon-ssm-agent
    sudo systemctl start amazon-ssm-agent
    ```
1. インスタンスを起動
Intellij ホットキー【備忘録】

# Main Topic

|      コマンド       |        動作         |
| :-------------: | :---------------: |
|   `Command ,`   |      設定画面を表示      |
|   `Command 1`   | プロジェクトツールへカーソルを移動 |
|      `esc`      | エディタウィンドウへカーソルを移動 |
|   `Command N`   |     新規ファイル作成      |
|   `Control R`   |      ファイルの実行      |
|   `Control D`   |       デバッグ        |
|      `F8`       |    デバッグのステップ実行    |
|  `Command F8`   |    ブレークポイントの設定    |
| `Option Return` |     `!`を表示・実行     |
| `Command N` | コンストラクタなどをgenerate |

# その他記事
- [今さらだけどIntelliJ IDEAで使えるJavaのブレークポイントあれこれ #Java - Qiita](https://qiita.com/oohira/items/825ef5f252d0fd2e752f)
OSの仕組み

##  OSってなんぞや
`OSとはOperating Systemの略でパソコンの操作やアプリなどを使うために必要なソフトウェアのこと`

現在のOSの仕組みはUNIXに由来する。Windows、MacOS、Linuxも基本的に似たような仕組み。

##  Shellとは
`shellとは、ユーザーとコンピュータのOSをつなぐ役を担う重要なプログラムの一種`
ユーザーが望んでいる動作を受け、OSに伝えた上で具体的なコンピュータの動作に繋げていく。
ユーザーとコンピュータの間に入る「通訳」のような存在である。
##  カーネルとは
`OSの基本機能の役割を担うソフトウェアを指す`
OSの中でも中核的なプログラムであり、HDDやコンピュータの資源管理を行っている。

##  指令伝達の流れ

1.ユーザーからのコマンド
2.Shellがコマンドを受ける
3.Shellがカーネルに指令を送る
4.カーネルが指令を受け取る
5.カーネルが指令の結果をShellに送る
6.Shellが結果を受け取り、ユーザーに結果を表示する

![Shell1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3855927/2f8cdfdb-27bc-990c-5e93-de93e5d7b5fa.png)
ScriptManager.RegisterStartupScriptで登録したアラートがたまに表示されない

サーバーサイドでScriptManager.RegisterStartupScriptで登録したアラートメッセージが表示される時とされない時があった

原因としてはkeyの重複
詳細は下記記事参照
http://chulton.blog58.fc2.com/blog-entry-2.html

共通メソッド側で同じkey指定していたのを見逃していました、、
わかるとそりゃそうだよね、と言った内容でした
AWS-Parameters-and-Secrets-Lambda-Extensionを試す

## 背景
Lambda上でSSMパラメータストアの値を都度取得するのが嫌で調べてたら以下を見つけたので試して見る

https://docs.aws.amazon.com/ja_jp/secretsmanager/latest/userguide/retrieving-secrets_lambda.html#retrieving-secrets_lambda_env-var

* Lambda Layer は以下を指定
`arn:aws:lambda:ap-northeast-1:133490724326:layer:AWS-Parameters-and-Secrets-Lambda-Extension-Arm64:11`

## コード
``` typescript:index.mjs
import {SSMClient, GetParameterCommand} from '@aws-sdk/client-ssm';

export const handler = async () => {
    const path = "/hoge/secure/params";
    let start;
    let end;

    // SDK経由
    start = new Date()
    for (let i = 0; i < 20; i++) {
        await sendGetParameter(path);
    }
    end = new Date() - start;
    console.info('sendGetParameter time: %dms', end)

    // Extention経由
    start = new Date()
    for (let i = 0; i < 20; i++) {
        await sendGetParameterUseExtension(path);
    }
    end = new Date() - start;
    console.info('sendGetParameterUseExtension time: %dms', end)

    return {};
};

const sendGetParameter = async (path) => {
    const ssmClient = new SSMClient();
    return await ssmClient.send(new GetParameterCommand({
        Name: path,
        WithDecryption: true
    }));
}

const sendGetParameterUseExtension = async (path) => {
    const ssmPStore = await fetch(
        `http://localhost:2773/systemsmanager/parameters/get?name=${path}&withDecryption=true`,
        {
            headers: {
                "X-Aws-Parameters-Secrets-Token": process.env.AWS_SESSION_TOKEN,
            }
        }
    )
    return await ssmPStore.json();
}
```

## 結果
20回連続で呼び出してみて比較したところウォームスタートだと圧倒的に速い。
あたりまえか…
* コールドスタート時
```
INFO	sendGetParameter time: 4463ms
INFO	sendGetParameterExtension time: 5714ms
```

* ウォームスタート時
```
INFO	sendGetParameter time: 3404ms
INFO	sendGetParameterExtension time: 694ms
```

今のところパラメータ名はフルパス指定しかなさそうだから、
`GetParametersCommand`とか`GetParametersByPathCommand`みたいな指定の仕方が出来ると嬉しいなー

こんな既出な情報なのに相変わらず自分は見つけるの下手だなーという感じ…

## 参考
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/ps-integration-lambda-extensions.html

https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/ssm/
CloudBuildでgolangci-lintを実行する

## 結論
`cloudbuild.yaml`に以下を追加すれば、実装できます

```yml: cloudbuild.yaml
steps:
  # golangci-lintのDockerイメージを指定する
  - name: 'golangci/golangci-lint'
    # デフォルトの設定でgolangci-lintを実行する
    args: ['golangci-lint', 'run']
```

## golangci-lint[^1]とは
[^1]: https://github.com/golangci/golangci-lint

> `golangci-lint` is a fast Go linters runner.
>It runs linters in parallel, uses caching, supports YAML configuration, integrates with all major IDEs, and includes over a hundred linters.

`golangci-lint`は高速なGoリンターランナーです。 
並列にリンターを実行し、キャッシュを使い、YAML設定をサポートし、すべての主要なIDEと統合し、100以上のリンターを含みます。

> Goの静的解析ツールは本当にたくさん存在するのですが、それらをひとまとめにして実行してくれるツールです。 GoのプロジェクトをGitHub ActionsのようなCIでテストする際にはよく使われます。[^2]
[^2]: mattn. Go言語プログラミングエッセンス エンジニア選書 (p.133). 株式会社技術評論社. Kindle 版. 

## golangci-lintの設定

デフォルトでは、以下のlinterが実行されます[^3]
[^3]: https://golangci-lint.run/usage/linters/

|Name|Description|Presets|
|-|-|-|
|[errcheck](https://golangci-lint.run/usage/linters/#errcheck)|Errcheck is a program for checking for unchecked errors in Go code. These unchecked errors can be critical bugs in some cases.|bugs, error	|
|[gosimple](https://golangci-lint.run/usage/linters/#gosimple)|Linter for Go source code that specializes in simplifying code.|style|
|[govet](https://golangci-lint.run/usage/linters/#govet)|Vet examines Go source code and reports suspicious constructs. It is roughly the same as `go vet` and uses its passes.|bugs, metalinter|
|[ineffassign](https://golangci-lint.run/usage/linters/#ineffassign)|Detects when assignments to existing variables are not used.|unused|
|[staticcheck](https://golangci-lint.run/usage/linters/#staticcheck)|It's a set of rules from staticcheck. It's not the same thing as the staticcheck binary. The author of staticcheck doesn't support or approve the use of staticcheck as a library inside golangci-lint.|bugs, metalinter|
|[unused](https://golangci-lint.run/usage/linters/#unused)|Checks Go code for unused constants, variables, functions and types.|unused|

`.golangci.yml`などの設定ファイルを追加することで、linterの有効/無効の設定ができます[^4]
[^4]: https://golangci-lint.run/usage/configuration/
スプレッドシートチートシート

## ショートカットキー

文字を選択してCtrl + K :リンクを挿入
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1155911/cf383cf3-8d8a-d830-319c-f2e97f8897c0.png)

## 値を参照する

#### 他のファイルの値を参照する
    =IMPORTRANGE("インポート対象のスプレッドURL","参照先のシート名!範囲")

### 端数処理
    =ROUND(値) ---　四捨五入
    =ROUNDDOWN(値)　---　切り捨て
    =ROUNDUP(値)　---　切り上げ

### If文
    =IF(OO=xx,value when true, value when false)
    =IFS(OO=XX,value,condition2,value2,それ以外を指定したい場合：true,value3)
    =SUMIF()
    =SUMIFS()
    =IFERROR()

### 対象の範囲から一意の値だけ抽出したい
    =UNIQUE(対象範囲)

    # よく一緒に使うもの
    =FILTER(データ範囲, 条件)
    # 対象範囲から条件に一致するデータだけ抽出

### 集計
    =vlookup()
    # 対象の範囲から指定した値を持つ行だけ抽出したい時
    =avg()
    # 対象範囲の平均値を求める
    =sum()
    # 対象範囲の合計値を求める
[Xcode] linker command failed with exit code 1 で困ったときはターミナルを使うべし

## 結論

ターミナルから

```
$ xcodebuild -project xxx.xcodeproj -configuration Debug
```

すると、リンカー(`ld`)のエラーメッセージが見れる。

## 解説

Xcodeで、`linker command failed with exit code 1 (use -v to see invocation)` というエラーが出ると、`Reveal in Logs`でも、ビルド履歴（ナビゲータ領域[^1]の一番右のアイコン）からも詳細が見れなくて、どうしたらいいかわからず詰まってしまうことがあります。

そういうときはターミナルから使える、いわゆるCLIコマンドを打つと、より詳細なエラーログが見れることがあります。（Xcodeプロジェクトの場合は上記のとおりですが、場合によっては`cmake`や`make`など、別のビルドコマンドが必要な場合があります。）

さらに、`Build Settings`の`Other Linker Flags`などに`-v`を指定すれば、より詳細なエラーログを見れます。

[^1]: ファイルツリーとか見るところ
ChatGPT部 #47 勉強会イベント参加レビュー

:::note warn
公開したつもりが、下書きのままでした。
イベント自体は7/27に実施されているため、読み替えをお願いします。
:::

## 本日の勉強会
https://chatgptclub.connpass.com/event/325960/

## ChatGPT omni miniがすごいらしい
SearchGPTというAI搭載検索エンジンが出るよ！というので、Googleとガチバトル感出てきた
既にBingAIとかもある中で、どういうポジションに収まるのか気になるところ

## 生成AIを事業に活用するためには？
本(PDF)の執筆状況の共有
まず経営層レベルからAIの採用率が低い。そもそもとして運用方法が確立していないのと、おそらくハルシネーションの問題とかもあるのでtoBに使うにはまだまだ難しいか…
RAG作る方法もあるにはあるけど、プロンプトインジェクションの観点で見ると対策が難しそうだ。

### プロンプトエンジニアリングはオワコンか？
本としてのコンテンツと考えた時に陳腐化が早い。今のやり方がすぐに通用しなくなるようになる。
プロンプトエンジニアリングが不要という事ではなく、本に書くにしては厳しいという判断。

### 印刷・出版を考える
やはり技術書典やZennが話題に。
個人出版で書く場合は技術書典が詳しいので、そちらを使うのが良さそう。印刷費はまぁ、うん。
Amazonでの出版は更にハードルが高い。Amazonで出版する際は別途Amazon用の番号も取得しなければならないとのこと。そもそも個人は対象ではないようだ。
Kindle版はISDN番号はいらないが、通常フォーマットとは勝手が違うらしい。
↑Boothも使えるよ！PDFでOK。ただし、販売力としては微妙なので別の方法で口コミは必要そう。

### 内容の懸念
氏より「特に内容についてのハルシネーション、査読など監修が必要」とのこと。
校正なども。多少の費用で使えるサービスがあるよ

## 所感
主に運営関連の話が多かったかなと。ChatGPT(LLM)の話はありつつ、部活動として見た時に外部向けの実績をそろそろ作っていこうというので執筆・出版の話があった、という流れだった
もう少しで50回記念という事で、なんかやりたい気持ちもある。
JavascriptをHTMLで使う

## JavascriptをHTMLで使う方法
外部のJavascriptファイルをindex.htmlで読み込み動作させる。
* フォルダ構成
```
.
├─js
| └─sample.js
└─index.html
```

* 実装
```index.html
<!DOCTYPE html>
<html lang="ja">
 <head>
    <meta charset="uft-8">
    <script src="js/sample.js" async></script>
    <title>HTML入門-JavaScriptの基本</title>
 </head>
 <body>
    <h1>文書の主見出し</h1>
    <button type="button" onclick="ShowAlert()">ここをクリック</button>
 </body>
</html>
```

```sample.js
function ShowAlert() {
    alert("Hello world!!");
}
```

* 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3850581/e270b50e-e56c-7de4-7d90-261849a9510e.png)

## 参考
https://techplay.jp/column/577
db2の構成を取得する"db2 get dbm cfg"や"db2 get db cfg"の整形が面倒な場合

db2 get db cfgすると構成情報が出力されるけれど、その形式がカンマ区切り、スペース区切り、タブ区切り...のようなものではない。
これを設計書に記載するのは目がチカチカする。

<pre>
       Database Configuration for Database sample

 Database configuration release level                    = 0x1000
 Database release level                                  = 0x1000

 Database territory                                      = US
 Database code page                                      = 1208
 Database code set                                       = UTF-8
 Database country/region code                            = 1
 Database collating sequence                             = IDENTITY
 Alternate collating sequence              (ALT_COLLATE) = 
 Number compatibility                                    = OFF
 Varchar2 compatibility                                  = OFF
 Date compatibility                                      = OFF
 Database page size                                      = 8192

 Statement concentrator                      (STMT_CONC) = OFF

</pre>

これをうまく整形する方法を知っている人は教えてほしい...。

解決策としては
dbmの方は<a https://www.ibm.com/docs/ja/db2/11.5?topic=views-dbcfg-database-configuration-parameter-information>SYSIBMADM.DBMCFG</a>
dbの方は<a https://www.ibm.com/docs/ja/db2/11.5?topic=views-dbmcfg-database-manager-configuration-parameter-information>SYSIBMADM.DBCFG</a>
をselectすればよい。

ただし上記例と左側が異なり、例えば"Database configuration release level"は"release"の値で取得できる。
【ChatGPT＋Code Interpreter】で文字列の色を変えていくアニメGIFです。


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

　今回は、文字列の色を変えていくアニメGIFです

:::note info
本記事は、ChatGPT（有料版）
で行なっております。画像は
あります。　あしからず。
:::

　まずは、ニュース。

　【朗報】
　　ChatGPT MacOSアプリに
　　　便利な機能が実装されました。

　　Option＋Spaceで
　　　小さなWindowが開いて
　　　　ChatGPTが使えるらしい。

　　OpenAIからはこちら。
　　　[OpenAI公式ポスト](https://x.com/OpenAI/status/1820914089612439622?t=bfCJPrMCp7cS-4eAkorxOA&s=19)

　　ほかには
　　　以下のふたつを参照して。
　　　　内容はほぼ同じ。
　　[ChatGPT研究所ポスト](https://x.com/ctgptlb/status/1821016632493535736?t=oEZmbhGcLgsNmQUU7lw8pA&s=19)

　　[チャエンさんポスト](https://x.com/masahirochaen/status/1821022685654348048?t=aid2-6Gl1thOclUQHCzD_g&s=19)

　私はAndroidスマホだから
　　関係ないけどね😸
***
　次のニュース。

　ChatGPT（GPT-4o）の出力も
　　4k→16kトークンに
　　　拡張されたらしい。

　要は
　　“小説、書いて”としたら
　　　今までは、途中までだったが
　　　　少なくとも四倍まで
　　　　　可能になるらしい。

　もともと、新しいモデルが
　　リリースされたことからの
　　　ポストのようです。
　[[IT naviさんポスト](https://x.com/itnavi2022/status/1820941872254312579?t=iGGeyXq6E7dKUQg9dyWr3g&s=19)

　こちらが
　　Web版で確認された
　　　内容のようです。
　[IT naviさんポスト](https://x.com/itnavi2022/status/1821190770730397930?t=j3jdgb-7tMAwWB7rkVeQKQ&s=19)
***
　最後のニュース。

　OpenAIが
　　この秋、開発者会議DevDayを
　　　開催する予定だそうです。

　開催地は、
　　サンフランシスコ
　　ロンドン
　　シンガポール　の３か所。

　申し込みは、
　　8月15日に締め切り。
　　　参加申込する方は、
　　　　早めにしましょう。

　登録料は、
　　450ドル。

　詳しくは
　　[OpenAI開発者アカウントポスト](https://x.com/OpenAIDevs/status/1820542222259073137?t=2QzdsdmLTJzX50l30Tdy1A&s=19)
***
　さて、本題です。

　文字列の色を
　　変えていくアニメGIF。

　出来上がりはこちら。
![color_changing_text.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/ec55a710-0f5e-8f63-b336-ee061ac7f3b4.gif)

　Promptですが、
　　今回から
　　　下記フォーマットで
　　　　お送りします。

　このフォーマットは
　　以前にChatGPTに
　　　出してもらったものに
　　　　加筆修正したものです。

　まぁ、
　　これまでと変わらない、と
　　　言われれば、そうなんですけど😅

　文字列の設定は
　　初期設定のテキストを
　　　変えてください。

　色の順番は
　　ChatGPTに
　　　お任せですが、
　　　　これは指示すれば
　　　　　大丈夫です。

　処理内容の3の[]部分を
　　変えるだけで済みます。

```Text:文字列色変えPrompt
# CodeInterpreterで文字列処理

### 初期設定
1. 画像のサイズ: `width = 512`, `height = 512`
2. 背景色: `bg_color = (255, 255, 255)` （白）
3. テキスト: `text = "I am a ChatGPT."`
4. テキストの色: `text_color = (0, 0, 0)` （黒）
5. フォントサイズ: `font_size = 48`
6. フォントパス: `font_path = "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf"`
7. フレーム数: `frames = 60` （1秒あたり30フレーム）

### 注意事項
コード不要。 
確実に実行せよ。

### 処理内容
1. 白い正方形画像を作成する。
2. 画像中央にテキストを描画する。
3. [テキストが次々と色を変える]アニメーションGIFを作成する。
    - 各フレームにおけるテキストの位置を計算して配置する (`x`, `y`)
4. GIFを保存する (`gif_path`).
```

　それと
　　注意事項を入れないと
　　　コードを書き出すわ
　　　　実行する手順を出してくるわで
　　　　　素直に実行してくれない
　　　　　　場合がありました。

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

　今回は、ここまで。
***
　ちなみに、
　　ダウンロードリンクが
　　　出てこない不具合は
　　　　直っていません。

　なので
　　アプリを使って
　　　やっています。

　早く直って欲しいですわ😭
Julia で配列キャスト

## C言語での配列のキャスト

C言語ではある型の配列を、別の型にキャストすることでアクセスすることができるようになる。


``` c    
double a[] = {1.0, 2.0};
unsigned char *p = (unsigned char *)a;

for (int i = 0; i < sizeof(double) * 2; i++){
    printf("%02x ", *(p + i));
}
printf("\n");
```

```
00 00 00 00 00 00 f0 3f 00 00 00 00 00 00 00 40 
```

## Juliaでもできる
これがJuliaでも同様にできる。`reinterpret`を用いる。

```julia
using Printf

a = [1.0, 2.0]

p = reinterpret(UInt8, a)
for i in 1:sizeof(a)
    @printf("%02x ", p[i])
end
println()
```
```
00 00 00 00 00 00 f0 3f 00 00 00 00 00 00 00 40 
```

`reinterpret`されたものは通常のベクタではなく、特殊な型になっている。

```julia
julia> typeof(p)
Base.ReinterpretArray{UInt8, 1, Float64, Vector{Float64}, false}
```
データがコピーされているのかと思ったがそうではなく、同じ領域を参照しているようだ。
キャスト後の`p`を変更するともとの配列に反映される。

``` julia
julia> p[6] = 10
10
julia> a
2-element Vector{Float64}:
 1.00244140625
 2.0
```
こんな事ができるとは。さすがJulia。
nRFConnectSDKを基盤としたSesameの暗号通信 #0

![sesame](https://jp.candyhouse.co/cdn/shop/files/58.png?v=1681950081&width=1600)


# 目的

量産を前提とした開発には注意すべき点が多く、開発環境は最低限以下の基準を満たす必要があります。

# 基準

- C言語では、すべてのハイパーリンクが適切にジャンプできるようにしてください


# 雑談

実は、退職前に返却した私のコンピュータには、すでに関連するコードの一連のセットがありました。しかし、誰かが私のコンピュータをフォーマットしてしまいました。私のコンピュータには、会社のすべてのコードプラットフォームの開発環境と、大量の開発記録およびツールスクリプトが含まれていました。これは会社にとって重要な資産です。私のコードをフォーマットした人が本当に愚かだと思います。会社で長年開発してきましたが、実は古いコンピュータもあって、その画面が壊れていました。しかし、その中にバックアップもあったかもしれません。それもフォーマットされてしまいました。(=. .='')

Sesameの通信暗号プロトコルの作者として、もちろんもう一度書くことはできます。
# 開発経験
私には、コードを書くときに、会社の誰かに一から教えるという習慣があります。開発環境の設定と変化を体験させることです。

今回の記事は、その教え子が読者だと思って書くつもりです。Sesameをゼロから開発した経験と旅路を感じてもらえればと思います。


# 用語
 
- [Sesame](https://jp.candyhouse.co/products/sesame5):*日本最強のシンプルスマートロック*
- [Sesameアプリ](https://github.com/CANDY-HOUSE)


# 関連記事

- [nRFConnectSDKを基盤としたSesameの暗号通信 #0](https://qiita.com/tse123321/items/c0fa105cd5b9f14c2a0c)
- [nRFConnectSDKを基盤としたSesameの暗号通信 #1 開発ボードのチェック](https://qiita.com/tse123321/items/f1f8795656a65b4643f9)
- [nRFConnectSDKを基盤としたSesameの暗号通信 #2 ノートパソコンの開発環境の確認](https://qiita.com/tse123321/items/529c26669bb07e4866b0)
- [nRFConnectSDKを基盤としたSesameの暗号通信 #3 開発ツールの準備](https://qiita.com/tse123321/items/5c238a91f8c135b11cb4)
- [nRFConnectSDKを基盤としたSesameの暗号通信 #4 Toolchain Manager](https://qiita.com/tse123321/items/23f8759df0fc9f37f378)
- [nRFConnectSDKを基盤としたSesameの暗号通信 #5 Hello World use Dongle](https://qiita.com/tse123321/items/38b328c3bb0035a1275f)
- [nRFConnectSDKを基盤としたSesameの暗号通信 #6 Hello World use DK](https://qiita.com/tse123321/items/4e72b1aa06f7d1c7bdc1)
- [nRFConnectSDKを基盤としたSesameの暗号通信 #7 使い慣れた開発環境-VSCode](https://qiita.com/tse123321/items/7a12e733dc31e24a383b)
- [nRFConnectSDKを基盤としたSesameの暗号通信 #8 使い慣れた開発環境-Clion](https://qiita.com/tse123321/items/7c42ee8f13f3e94271e4)
- [nRFConnectSDKを基盤としたSesameの暗号通信 #9 Kconfig](https://qiita.com/tse123321/items/1057f3a0c1e1a4894579)
- [nRFConnectSDKを基盤としたSesameの暗号通信 #10 Hello_tse without viscode](https://qiita.com/tse123321/items/9a546cc6c78cb601c846)
シンボリックリンクの作成時にいつも悩むのでメモ

# 背景
`ln -s` コマンドの引数の順番をいつも忘れて、一瞬悩むのでメモしておきます。

# コマンド公式

```
ln -s <real file path> <symbolic link name>
```

# 具体例
例えば、 `zozo-id/slo.tf` というリアルファイルが存在するとして、そのファイルへのシンボリックリンクを `zozo-id/prd/slo.tf` として用意したい場合は、以下のコマンドとなります。

```
cd prd/
ln -s ../slo.tf slo.tf
```

![Cursor_と_slo_tf_—_zozo-platform-infra.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221948/921035f9-a63c-21bc-616a-873059faa7d9.png)
【備忘録】Ubuntu 24.04 で日本語入力環境を整える（変換候補のポップアップ位置修正）

# はじめに
日本語入力メソッドとして `fcitx5-mozc` を利用している場合，変換候補のポップアップの表示位置が適当でないことがある．親切な場合，`Input Method Panel` をインストールしてくださいと表示されることがあり，これに従ってみようとすると意外と面倒だったので，以下に手順を記載しておく．

# 手順
1. 日本語入力メソッドをまだ導入していない場合は以下のコマンドを実行：
    ```
    sudo apt update
    sudo apt install fcitx5-mozc # fcitx-mozc のインストール
    im-config -n fcitx5 # デフォルトの im を fcitx5 に変更
    ```
    実行後，再起動．この状態でも一応日本語入力は可能だが，変換候補の表示位置がおかしいので，ここからはInput Method Panel をインストールする
1. まず，以下のパッケージをインストールしてみる
    ```
    sudo apt install gnome-shell-extensions gnome-tweaks
    ```
1. ~~Firefoxを使用している場合，`GNOME Shell Integration` アドオンをインストール~~ ←必要ありません
1. GNOME Extensions website -> [Input Method Panel](https://extensions.gnome.org/extension/261/kimpanel/) をインストール（Install ボタンを押すと， gnome-shell-extensions アプリが開かれます）
1. もう一度，同じサイトにアクセスし，アドオンがオンになっていることを確認
1. GNOME Shell を再起動（`Alt+F2`-> `r` -> `Return`）．うまくいかなければ，再起動するのが楽
1. 入力カーソルを画面の色んな場所に動かして，日本語入力を行い，表示位置が適切であることを確認する
【備忘録】Ubuntu 24.04 向け Logseq (AppImage) の実行方法

# はじめに
日々の業務の日誌に皆さんは何を使用しているだろうか．例えば，本記事で紹介するような備忘録はどのように管理しているだろうか．私は [Logseq](https://logseq.com/) というツールを使って管理している．本記事ではこのツールを Linux (Ubuntu 24.04）にインストールする方法を紹介する．

本記事は Logseq に依らず，AppImage 全般の実行方法を提供することにつながるかもしれない．

# 手順
1. https://logseq.com/downloads にて，linux 版 Logseq (AppImage) をダウンロード
1. https://appimage.org/ にあるように，ダウンロードした AppImage を実行できるようにする．例えば，ホームディレクトリに Logseq の AppImage をおいた場合，`chmod a+x Logseq-linux-x64-xxx.AppImage`
とすればよい．ここで，`xxx`はバージョンを表すので，適当な数字に置き換えること．
1. AppImage の公式サイトによれば，`./Logseq-linux-x64-xxx.AppImage` を実行すれば起動するとのことらしいが，`AppImage require FUSE to run` とのエラーメッセージが出力された場合は以下のことを追加で行う．
    ```
    sudo add-apt-repository universe
    sudo apt install libfuse2t64 # Ubuntu 22.04 以降
    ```
1. ここでもう一度 AppImage を実行しても以下のようなエラーメッセージが出力される場合がある（特に Ubuntu 24.04）．
    ```
    [xxxxx:xxxx/xxxxxx.xxxxx:FATAL:setuid_sandbox_host.cc(158)] The SUID sandbox helper binary wad found, but is not configured correctly. ...
    ```
    この場合は， https://github.com/VOICEVOX/voicevox/issues/2071#issuecomment-2113967598 を参考に，いずれかの回避策を打つ．最も手っ取り早いのは `./Logseq-linux-x64-xxx.AppImage --no-sandbox` とオプションをつけることであろう．
cscの作法 その519

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
フォルダを探索して、ファイルから、一致する文字を表示せよ。

# 環境
windows11

# 方針
- DirectoryInfo使う。
- Regex使う。

# サンプルコード

```

using System;
using System.Text.RegularExpressions;

namespace App
{
	class Program {
		static void getPage(string fname) {
			try
			{
				Regex rgx = new Regex("using(?<group>.*);", RegexOptions.IgnoreCase);
				using (System.IO.StreamReader file = new System.IO.StreamReader(fname, System.Text.Encoding.ASCII))
				{
					string line = "";
					while ((line = file.ReadLine()) != null)
					{
						if (rgx.Match(line).Success)
						{
							Console.WriteLine(rgx.Match(line).Groups["group"].Value);
						}
					}
				}
			}
			catch (Exception e)
			{
				Console.WriteLine(e.Message);
			}
		}
		static void Main(string[] args) {
			string appPath = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
			Console.WriteLine(appPath);
			System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(appPath);
			System.IO.FileInfo[] files = di.GetFiles("*.txt", System.IO.SearchOption.AllDirectories);
			foreach (System.IO.FileInfo f in files)
			{
				getPage(f.FullName);
			}
		}
	}
}





```

# 実行結果

```
>find0

 System
 System.Text.RegularExpressions
 System
 System.Text.RegularExpressions
 System
 System.Text.RegularExpressions
 System
 System.Drawing
 System.Text.RegularExpressions
 System.Runtime.InteropServices
 System.Windows.Forms
 System
 System.Text.RegularExpressions
 System
 System.Text.RegularExpressions
 System.Text.RegularExpressions
 System
 System.IO
 System.Text.RegularExpressions
 System.Web
 System
 System.Text.RegularExpressions
```
- ドキュメントで実行すると、ディフェンダーにウィルス扱いされて、隔離される。
- 調査する気が無い。


以上。
cscの作法 その518

# 概要
cscの作法、調べてみた。
c#見つけたので、cscでコンパイルしてみた。

# 参考にしたページ

https://qiita.com/kob58im/items/4bd061df83212a723be7

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/d2062f52-23aa-1458-ee86-5ea5550be01a.png)


以上。
Azureを使ってみた備忘録

# AWSからAzureへ
転職先でoffice365をメインで使っていたため、プロダクトの開発はazureで行うことにした。
もともとAWSを使っていたため、下記機能がどのツールに互換できるのかを確認しながら開発をしたいと思う。

## LambdaからFunction Appsへ
これすごく調べたんですけど、本当にわかりにくかったです。

### 名前
いや、これ本当に初見じゃわからないでしょ。どうして日本語なのよ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833494/a2eae176-8d36-bd9b-310c-658100e6f1fd.png)

### 料金設定
とりあえず料金プランの選択ができて、Lambdaよりも自由度が高いサーバレスの実行環境を整備できそうです。
個人的には実行時間の制限をお金で解決できるところがよいとおもいました。
まあ、fargateなりec2なりでいいじゃんって思うのもありますが、実行時間が長く、月1回程度しか動かさないシステムなら料金は抑えられるかも。。。？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833494/1c0d46a3-f184-3010-97ff-430458ab20f5.png)

### 基本設定
ここでランタイムとか設定できるみたい。
node,Python,Javaはあったけど他はよくわからない、、、
GoとかはLambdaしか使えないのかな？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833494/a9b921f8-80e8-2fb9-0e0d-a4f069907c1e.png)

### ネットワーク設定
これデフォルトでパブリックになってるみたいですね、すごく危ない。
DBをいじるコードとかなら本当に気を付けないとですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833494/9b5b9fa6-e015-4e3c-c8d3-9268aad27f8a.png)

### 監視
急に英語になるやん、
cloud watchみたいなもののようですね。
とりあえずなしで設定してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833494/87f78d09-bf55-0f5c-8edc-60c981aeb10f.png)

### デプロイ
github actionで対応できるのすごく便利だ！
lambdaだとzipファイルでアップロードかcdkを使っていたけどgithubactionですべて対応できるならコードの管理という面でもやりやすい。
cloud9があった時代よりより効率的にデプロイできますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833494/89a728d6-0381-80ab-b26e-5224b9c8877a.png)

### 完成
これで関数の作成は完了！
cdkみたいだーとか言うてたけどVS codeのプラグインでどうにかできるっぽい。
ちょっと開発して遊んでみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833494/7af4430c-8b3b-10b8-0ad3-6095e6a1eb24.png)
誰も使わなかった奇妙な設定

> こちらは「Ruby on Rails パフォーマンスアポクリファ」のサンプル章です。[日本語での完全版が現在Gumroadで入手可能です](https://nateberk.gumroad.com/l/apocrypha_ja)。


Rails のバックグラウンドジョブの多くには、一般にパフォーマンスの問 題があります。
バックグラウンドジョブでは、しばしば大きなデータセットを処理しま す。そして、その際に User.all.each(&:send_daily_newsletter) のよ うな愚かなことをしてしまいます。

開発環境やテスト環境では、User.all が返すのは、おそらく数行、多くて も十数行でしょう。開発者の多くは、自分のローカルマシン上の seed デー タを極端に限定しています。

しかし、プロダクション環境では、User.all はおそらくかなりの数の行 を返します。開発するアプリケーションによっては、数十万行になるかもし れません。 

10 万行を返す結果セットには、ほんのわずかばかり問題があります。それ は SQL クエリーが返すのに時間がかかるというだけではありません。Ruby アプリケーションにも取り返しのつかない影響を及ぼしてしまいます。

Active Record の大規模な結果セットは、メモリ使用量を増大させる可能 性があります。Ruby のメモリアロケーターは入り組んでいて、Ruby のプ ロセスが大量のメモリを使うと、ガベージコレクションされても OS に返さ ない傾向があります。これは Ruby のせいではなく、アロケーターのせいで す。今後数年のうちに Ruby 側で修正されるかもしれませんが、今のところ は対処せざるを得ません。

このような動作は、しばしば見落とされ、実運用で大失敗する可能性があ ります。さらに悪いことに、ほとんどの人はバックグラウンドジョブで何が 起こっているか、それが動作する限りはあまり気にしません。しかしなが ら、キューが一杯になったり、メモリが足りなくなったりすると文句を言う のです。

大量の結果セットを取得する傾向は、バックグラウンドジョブが遅くなっ たりメモリを大量に消費したりする理由の 1 つに過ぎないものの、よくある ことです。しかし Rails 5.0 以降では、この現象が発生したときに識別しや すくする設定項目が用意されています。その名も warn_on_records_fetc hed_greater_than です。

この設定について最初に書いたとき、GitHub を調べてみたら、この設定 を使っていたアプリケーションはたった 1 つだけでした。

これに整数に設定すると、ActiveRecord::Relation オブジェクトがそ の整数より大きな結果セットを返した場合に、ログに警告を出力します。

この設定は、大きな結果セットを取得する場合は ActiveRecord::Batch es の find_each などのメソッドを使用したほうがよいという注意喚起のた めのものです。

次のコードは、

```ruby
 User.all.each(&:send_daily_newsletter)
```

代わりに次のように書けます。

```ruby
User.find_in_batches do |group| group.each(&:send_daily_newsletter)
end
```

今すぐ config/environments/development.rb にアクセスしてこの警 告を入れるのが合理的だと思います。1500 より大きい結果セットは少な くとも 2 つの完全なバッチで取得されるので、1500 あたりが妥当な値で しょう。

```ruby
config.active_record.warn_on_records_fetched_greater_than = 1500
```

すると、その上限を超えると、ログにこのような警告が表示されます。

```sql 
Query fetched 1501 User records:
SELECT "users". FROM "users" 
ORDER BY "users"."id" ASC LIMIT $1
```

さて、これを application.rb あるいは環境別ファイル production.rb で有効にするかは迷うところです。この設定を行うと ActiveSupport::No tifications.subscribe("sql.active_record") がされます。つまり、 SQL クエリーごとの notification で購読されることになります。ローカル ベンチマークでは、クエリーあたりのオーバーヘッドは非常に小さくなって いますが、「Active Record のリクエストごとにオーバーヘッドを追加する」 というのは、必ずしもやりたいことではありません。

development モードでは常にオンにしつつ、バックグラウンドジョブを実 行するときだけ production モードでもオンにするのが便利でしょう。たと えば、config/initializers に以下のように記述します。

```ruby
if Sidekiq.server? ActiveRecord::Base.
  warn_on_records_fetched_greater_than = 1500
end
```

 一度に読み込むレコード数には注意が必要です。
【Python】抽象メソットの書き方

# 疑問

次のコードがmypyの型チェックでエラーになりました。
`get`メソッドは`MyData`型を返すとしていますが、`None`を返しているためです。

```Python
class MyClass(ABC):
    @abstractmethod
    def get(self) -> MyData:
        return None # 型ヒントと不一致
```

抽象メソッドには実装が存在しないことを示すべきですが、returnを書いてしまうと型チェックに引っかかります。
正しい記述方法を検討してみました。

# 解決方法

抽象メソッドの本体には何も実装しないことが重要です。次の記述が一般的です。

### Ellipsis リテラル

```Python
class MyClass(ABC):
    @abstractmethod
    def get(self) -> MyData:
        ...
```

`…`は、は未実装を示す視覚的なシンプルな記述です。[Ellipsis リテラル](https://docs.python.org/ja/3/library/constants.html#Ellipsis)としてPythonに組み込まれています。


### pass文

```Python
class MyClass(ABC):
    @abstractmethod
    def get(self) -> MyData:
        pass
```

`pass`はPythonの伝統的な記述です。公式ドキュメントでも[pass](https://docs.python.org/ja/3/library/abc.html)がよく用いられています。

### dockstringを書く

```Python
class MyClass(ABC):
    @abstractmethod
    def get(self) -> MyData:
        """Dataを取得するを取得する."""
```

docstringがある場合、mypyエラーは発生しませんが、...を併用して未実装を明示してもよいとおもいます。
docstringと`pass`を併用すると、`ruff check`で```PIE790('Unnecessary `pass` statement')```警告となります。

# どの記述がよいか？

どの記述にするかはプロジェクトのコーディングルール次第ですが、`...`を使う方が最近のトレンドとして増えている気がします。未実装の関数を一目で確認でき、ruffのチェックにも適合しやすいです。

# まとめ

- 抽象メソッドにreturnを書くと型チェックエラーになる
- `...`（Ellipsis）を使うと視覚的に未実装を示せる
- passは従来の方法だが、冗長になる場合もある（ruffで警告）
- docstringを書くだけでもエラーは避けられるが、`...`を追加するのも可（開発のコーディングルール次第）

```Python
class MyClass(ABC):
    @abstractmethod
    def get(self) -> MyData:
        """Dataを取得するを取得する."""
        ...
```

参考
https://tuxtimo.me/posts/2021/11/05/python-pass-vs.-ellipsis/
https://qiita.com/kissy24/items/d9564d1f48a310614e90