OmniAICreator/Qiita-1.07M huggingface dataset:
failed to initialize database, got error dial tcp 127.0.0.1:3306: connect: connection refusedの対処法[Go,MySQL,Docker]

Go＋MySQLをDockerで立ち上げようとしたら下のようなエラーが出ました。

```
failed to initialize database, got error dial tcp 127.0.0.1:3306: connect: connection refused
```
これはdatabaseの初期化がうまくいかず、コネクションができなかったというエラーです。

# 解決方法
## dsnを確認する
dsnは、`Data Source Name`の略称で、データベースの識別子のことです。

例えばMySQLだと以下のようなdsnになります。

```
[user]:[password]@tcp([IPアドレス]:3306)/[database_name]?charset=utf8mb4&parseTime=True
```

まず上手くいかなかった例を紹介します。

私は、ymlファイルにMySQLの設定を下のように記述していました。

```docker-compose.yml
services:
  server:
    build:
      context: .
      dockerfile: ./docker/go/Dockerfile
    tty: true
    depends_on:
      - db
    ports:
      - 8080:8080
  db:
    image: mysql:8.0
    container_name: db
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: db
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      TZ: Asia/Tokyo
      LANG: ja_JP.UTF-8
    ports:
      - 3306:3306
    volumes:
      - db-volume:/var/lib/mysql

volumes:
  db-volume:
```

この場合、dsnは下のようになると思っていましたが、そうではありませんでした。

```
user:password@tcp(127.0.0.1:3306)/db?charset=utf8mb4&parseTime=True
```

このdsnがうまくいかなかった理由は、dockerで作成されたネットワークでは、mysqlのコンテナは必ずしも`127.0.0.1`にはならず、動的にIPアドレスが変更されていってしまうからでした。

実際には下のようにすると、接続できました。

```
user:password@tcp(db:3306)/db?charset=utf8mb4&parseTime=True
```

docker composeを使用すると、プロジェクト毎にブリッジネットワークが自動作成され、<font color="red">同一ymlファイルに書かれている</font>サービス同士はコンテナ名でIPアドレス解決ができるようになります。

もし、同一ymlファイルに書かれていない場合にコンテナ名解決をしたい場合は、`docker network create`でネットワークを定義する必要があります。

↓この記事で同じymlに書いていないコンテナ同士の通信の仕方を書いています。

https://qiita.com/maooz4426/items/b578fac2385b7e344eb5


なので、実際にGoでは下のような実装でdb接続しました。
```go
func ConnectDB() (*gorm.DB, error) {
	var db *gorm.DB
	var err error

	dsn := "user:password@tcp(db:3306)/db?charset=utf8mb4&parseTime=True"

	return db, nil
}
```

## リトライ処理をつける
ymlファイルで、dbのコンテナを依存関係として明示していても、起動した後にサーバーアプリケーションのコンテナが立ち上がるので、dbが接続できるようになる前に接続動作が行われ、アプリケーションが接続できない場合もあります。

その場合は下のようなリトライ接続ができる仕組みを作成します。

```go
func ConnectDB() (*gorm.DB, error) {
	var db *gorm.DB
	var err error

	dsn := "user:password@tcp(db:3306)/db?charset=utf8mb4&parseTime=True"

	count := 5

	for count > 1 {
		if db, err = gorm.Open(mysql.Open(dsn)); err != nil {
			time.Sleep(2 * time.Second)
			count--
			log.Printf("retry... count:%v\n", count)
			continue
		}
		break
	}

	return db, nil
}
```

こうすることで5回まで接続動作をリトライしてくれます。
背景から切り離され、色褪せた単語。

言葉は単独では必ずしも意味を正確に伝えられるわけではありません。
その背景や文脈が重要です。

## 専門用語の多義性
私が最近困っている言葉があります。
それは「デザイン」です。
IT業界では「デザイン」という言葉が、UI/UXデザインやシステム設計を指すことがあります。

特にDXの文脈で「デザイン」の話が出てくると、どっちのことも言ってるような気がしてきます。
よく分からないので調べました。
IPAが出してる[デジタルスキル標準](https://www.ipa.go.jp/jinzai/skill-standard/dss/ps6vr700000083ki-att/000106872.pdf)にも「デザイン」という言葉が出てきますが、
どうやら **顧客に対する理解を背景に、ユーザー体験向上を目指した「UI/UXデザイン」** として使っているっぽいです。

## テキストベースの非同期コミュニケーション
特にコロナ以降、多くの企業においてテキストベースの非同期コミュニケーションを取る機会が増えています。
「非同期コミュニケーション」とは、メールやチャットなどのように、相手から即座に返事が来ることを前提としないコミュニケーション形式のことを指します。
このようなコミュニケーション形式は、時間や場所に制約されず、自分のペースで情報を整理し、相手に伝えることができるという利点があります。

一方で、（ファイル添付もできますが）言葉だけで情報を伝えるため、相手の理解を確認することが難しいという欠点もあります。
特に技術的な内容や専門用語を含む場合、相手の知識レベルや文脈によって誤解が生じやすいため、注意が必要です。
このようなリスクを軽減するためには、抽象的な専門用語にとどめず、具体例を交えて説明を補足するなど、相手の理解を助ける工夫が求められます。
よく言われている「具体⇔抽象」ってやつですね。

## 専門性の違いによる誤解
[リーンキャンバス](https://www.utokyo-ipc.co.jp/column/lean-canvas/)は、ビジネスモデルを構築するためのフレームワークとして有名です。
リーンキャンバスの細かい説明は抜きますが、私が参画した直近の0→1のプロジェクトでも使われました。諸事情あって、厳密にはリーンキャンバスではないんですが。

しかし、そのプロジェクトのリーンキャンバスは、ほとんど単語だけを箇条書きにしたものでした。
説明の機会もありましたが、私を含めた技術的な知識があるメンバーの間では、「これは酷い」という声が上がっていました。
私は「特に技術的な知識が無いのに、技術的なHowまで書いている」という印象を持っていました。

でも、私はそのままにせず、プロダクトマネジメントの考えに則って、背景となるWhyやWhatを訊こうとしました。
リーンキャンバスを作った方は丁寧な方で、WhyやWhatについてしっかりと説明していただけました。
加えて、こう返ってきました。「あそこにはHowを書いたのではなく、Whatを書いたつもりだった。」
ああ、私も思い込みをしていたんだなと気づかされました。

## ハイコンテクスト文化とローコンテクスト文化
オフショア開発ではもっと気をつけるべきです。相手のメンタルモデルが大きく異なるからです。
たまたま、最近ベトナムとオフショア開発をしている会社のEM兼テックリードの方とお話する機会がありました。
ベトナムはローコンテクスト文化なのでちゃんと要件を整理して伝えないといけない、という話を聞きました。

いろんな50代以降の方々とも話すことがありますが、傾向としてそういった方々はハイコンテクスト文化に慣れ過ぎているように感じます。
このVUCAの時代において、日本であってもハイコンテクスト文化に頼るのは危険だと感じます。
難しいことではありますが、誤解を避けるために、相手のメンタルモデルを推察し、より明確で具体的な伝達方法を採用することが重要だと思います。
matplotlibで縦積みパネルチャートを作成

各種センサーの情報を扱っていると、情報の種類ごとのグラフ(チャート)を同じ時間軸で縦に積み上げて表示したくなります。
例えば、ロータリーエンコーダーの信号なら、エッジごとにパルス周期が測定され、その逆数からスピードを求めることができます。またパルス数カウントから移動距離が分かります。
Excelではこのようなパネルチャートを作ることはできませんが、matplotlibでは下記のように簡単できます。

```python
import numpy as np
import matplotlib.pyplot as plt

def smpl_data_make(bs, pr, ph, va, len):
    res = []
    t = 0
    for i in range(len):
        sp = bs + (np.sin((2 * np.pi * t / pr) + ph) * va)
        pp = 1 / sp
        res.append([t, sp, pp, i])
        t += pp
    return list(zip(*res))

dat = [smpl_data_make(200, 0.1, i * (np.pi/3), 50, 21) for i in range(3)]
n_ax = 3
ttl = ['speed', 'interval', 'count']

fig, ax = plt.subplots(n_ax, 1, sharex='all', gridspec_kw={'hspace':0})
[[ax[c].plot(da[0], da[c+1], '-o') for da in dat] for c in range(n_ax)]
[a.set_ylim(bottom=0) for a in ax]
[a.set_title(t, x=-0.1, y=0.1, loc='right', rotation=90) for a,t in zip(ax, ttl)]
plt.show()
```

![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1923193/8fbe1a3b-52ab-a204-4848-c92d02312342.png)


matplotlibでも記述方法がいくつかありますが、このようにsubplotsを使うのが一番少ない記述で済みそうです。
```python
fig, ax = plt.subplots(n_ax, 1, sharex='all', gridspec_kw={'hspace':0})
```
Visual Studioの保存ボタンで「オブジェクト参照がオブジェクトインスタンスに設定されていません」のエラー対応

# 現象
Visual Studio 2022でプロジェクトを開いてソースコードを編集して保存しようとすると「オブジェクト参照がオブジェクトインスタンスに設定されていません」のエラーになり保存ができない。
保存させるには編集したファイルのタブを閉じることで保存させている。

# 対応
Visual Studio 2022の対応方法を例にします。

1. Visual Studio 2022を閉じる
2. C:\Users{ユーザー名}\AppData\Local\Microsoft\VisualStudio\ フォルダを開きます
3. 17.0_9cac6ada フォルダ(Versionによって変わる)の名前を変更する
4. Visual Studio 2022を起動します

https://stackoverflow.com/questions/34084003/visual-studio-error-object-reference-not-set-to-an-instance-of-an-object-after
VSCodeをインストールして最初にすること

## ファイルの最後に自動で改行する設定

1. Macは`command(⌘) + ,`、Windowsは`ctrl + ,`を押して設定画面を開く
1. `files.insertFinalNewline`で検索してチェックを入れる

![スクリーンショット 2024-09-23 23.48.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/246438bb-eb4a-29f3-ae1e-2e12b6aab6a1.png)

## 最終行以降の余分な改行を削除する設定

1. 設定画面を開く
1. `trimFinalNewlines`で検索してチェックを入れる

![スクリーンショット 2024-09-23 23.56.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/fd8e6bd4-c278-b8ef-9161-d18b5b6cb13f.png)


## 行末の不要なスペースを自動で削除する設定

1. 設定画面を開く
1. `files.trimTrailingWhitespace`で検索してチェックをいれる

![スクリーンショット 2024-09-23 23.58.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/5b239f8b-ab27-10e7-81a0-8a877f364e5a.png)

## Codeiumをインストールする ※無料のGithub Copilot的なやつ

1. 拡張機能で`Codeium`をインストールする

![スクリーンショット 2024-09-24 0.01.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836454/0455cb78-2c98-ba44-7d9a-878b1311f4c4.png)


## 参考記事

- [VScodeでファイル末尾に自動で改行を入れたり、行末の余分な空行を消す設定方法](https://k-koh.hatenablog.com/entry/2020/01/28/194905#%E8%A1%8C%E6%9C%AB%E3%81%AE%E7%A9%BA%E8%A1%8C%E3%82%92%E8%87%AA%E5%8B%95%E3%81%A7%E6%B6%88%E3%81%99)
【技術書紹介】AWS運用入門

## 書籍情報
書籍名：AWS運用入門
著作者名：Ravi Mishra
翻訳者名：ねこやま のりこ

https://book.mynavi.jp/ec/products/detail/id=142721


## 本書を選んだ背景
IaCでの環境構築に興味があったことと、以前参加した勉強会で本書が紹介されており興味を持ったことがきっかけです。

## 本書について
Terraformアソシエイト試験を受験しようとしている人のために作られたとのことですが、IaCやTerraformを学びたい人にも向いている内容になっています。
IaCとTerraformの説明に始まり、AWS、Azure、Google Cloudと連携した構築方法について紹介されています。

## 本書の内容
以下、個人的なメモを残します。

### 1章 IaCを知る
- IaCのメリットの1つは、属人化を防ぐこと
- Terraformの構成ファイルはHCLで書かれており、JSONやYAMLと比べて読みやすい
- 他のIaCサービスと比較しても、エラーメッセージの読みやすさ、クロスプラットフォームであるなどTerraformには優れた点がある

### 2章 Terraformのインストール
Terraformのインストール方法について書かれています。Windowsだけでなく、LinuxとmacOSへのインストールにも触れられています。

### 3章 Terraformをはじめよう
プロバイダとは、AWSなどのクラウドプラットフォームのリソースを制御する。ベストプラクティスに従い、ファイル名はproviders.tfまたはrequired_providers.tfにすると良い

### 4章 Terraformへのディープダイブ
- プロピジョナとは、作成されたリソースに追加でセットアップを行う
- terraformはプロピジョナの詳細をステートファイルに保存しない。そのためトラブルシュートが難しくなる
プロビジョナには次のような種類がある
    - file Terraformが実行されているマシンから新しく作成されたリソースにファイルやディレクトリをコピーする
    - local-exec Terraformの構成コードをローカルで実行し、いくつかの情報を取り出す
    - remote-exec　リモートリソースが作成されると、リモートリソース上でスクリプトを実行できる
- terraformのループとデバッグ

### 5章 Terraform CLI
- メインコマンドに-hオプションでサブコマンドを見る
- クラウドプラットフォームとの連携方法について
    - ※どのプラットフォームにも共通して言えるが、認証周りに不備がないよう設定する。例えばAWSにおいてIAMユーザを作成し、適切なポリシーを割り当てないとapply時にエラーとなる
- main.tfを含め、構成ファイルはディレクトリ構成で置かれる。その例は以下の通り
    ```
    $ tree
    .
    ├── main.tf
    ├── providers.tf
    ├── terraform.tfstate
    ├── terraform.tfvars
    └── variables.tf
    ```

- Terraform CLIのその他のオプション

### 6章 Terraformのワークフロー
- Terraformのライフサイクルは、init→plan→apply→destroy
    - terraform initによりプラグインやモジュールをダウンロード（初期化）
    - terraform validateはterraform構成コードにシンタックスエラーがあるか教えてくれる
    - terraform planはコマンド実行によるクラウドリソースへの挙動を確認する
    - terraform applyはステートファイルを作ってクラウドリソースに反映する
    - terraform destroyはプロビジョニングしたリソースを削除する
- Azure DevOpsはCI/CDツール。リポジトリにローカルからソースコードをアップロードする際にクレデンシャルを発行しないとエラーになる
- Azure Pipelinesを無料で利用するには申請が必要　https://learn.microsoft.com/ja-jp/azure/devops/release-notes/2021/sprint-184-update

### 7章 Terraformのモジュール
- Terraformのモジュールについて
- source 必須。モジュール構成ファイルがあるローカルパスか、ダウンロードされるべきリモートの参照URL（Uniform Resource Locator）のどちらかを参照する
- version オプション。特定のバージョンのモジュールをダウンロードしたい場合に定義する
- depends_on オプション。明示的な依存関係を定義する必要がある場合に定義する
- 各クラウドプラットフォーム用のモジュール

### 8章 Terraformによるインフラストラクチャの管理
- 各クラウドプラットフォーム用を含む、構成ファイルの書き方について
- providers.tfはクレデンシャルファイルについて言及し、ファイル名やファイルパスを指定できる
入力の変数名をterraform.tfvarsから渡すと、Terraformが実行中に変数値を認識して値を取得しやすくなる
outputs.tfファイルで出力を定義する
- 構成ファイルを書く場合のベストプラクティス

### 9章　Terraformスタックを理解する
レジストリ内の複数のモジュールをまとめて、スタックを形成する、これにより環境やバージョンごとにインフラの管理が可能となる。
本書では各クラウドプラットフォーム用のスタックを作成し、main.tf内で引数に指定したモジュールをプロビジョニングする。

### 10章 Terraform CloudとTerraform Enterprise
Terraform CloudとTerraform Enterpriseの紹介

## 本書の感想
- Terraformの基礎からインフラの構築・管理が学べる1冊となっており、学習の導入として良いのではと思います
- 翻訳された書籍であるため、やや読み進めづらいところがあります
- クラウドプラットフォームとの連携でつまづく箇所がいくつかあり、その点については公式のドキュメントなどを調べながらハンズオンを進める必要があります
ユドナリウム1.17.2をローカルで動かしてみたメモ

# 概要
[前回](https://qiita.com/hibohiboo/items/27c19d42ef4d7c069d3c)はデプロイを試した。
今回はローカルでの稼働を確認する。

# バックエンドをローカルで動かす
## 環境変数の設定
`packages/backend/nodejs/.env`ファイルを.env.sampleファイルをコピーして作成し、環境変数を設定する。
設定値は[前回](https://qiita.com/hibohiboo/items/27c19d42ef4d7c069d3c)参照。
さらに、`packages/backend/nodejs/.env.local`ファイルを.envファイルをコピーして作成する。ファイル内容は同じでよい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/49d4cbab-d29e-44b5-3ed8-d3d28ab7525e.png)

## ローカルで起動

下記コマンドで起動。 `http://localhost:3000`で動作する。

```
npm run nodejs:dev
```

# フロントエンドをローカルで動かす。
バックエンドをローカルで動かしている状態を前提とする。

## 設定ファイルの記載
`src/assets/config.yaml`ファイルにバックエンドの`http://localhost:3000`を記載する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/a664754a-5a89-bf5f-41c6-829bad9c4005.png)

## httpで起動
Readmeには必ずSSLオプションをつけると書いてあったが、起動自体はsslオプションがなくてもできる。 ロビー一覧からのチャットも可能だった。

```
npm run start
```

`http://localhost:4200/`で起動するのでブラウザでアクセスして確認する。

http://localhost:4200/

## httpsで起動
httpsで起動するときの注意点も記載しておく

```
npm run start -- --ssl
```

https://localhost:4200/ 

ローカルで認証局なしのSSL起動になるので、ブラウザが警告を発してくる。
詳細設定を開いて、先に進めるようにする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/3d180ae5-eb73-81f0-cbe4-ca1545b018b2.png)

今回は安全であることは自分が知っているため、無視してlocalhostに進む。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/d8f60849-11a9-ddc1-a5cc-877cd0bd51b8.png)


警告は出るがhttpsでユドナリウムをローカルで確認することができた。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/6b3f5f7a-8063-03a3-bbcd-a2a2289486b3.png)
laravelでtailwind が動作しない原因とその解決法【PostCSS設定の問題を解消】

<br>

・参考サイト：http://blog.livedoor.jp/nnmy/archives/55088059.html

##  【結論から言うと】

**PostCSSの設定ファイルがプロジェクトに存在しなかったこと、さらにESモジュールとCommonJSの形式の違いが原因でエラーが発生していたことが、Tailwind CSSが正常にビルドされなかった理由です。**

具体的には次の2つのポイントが問題でした:
1. `postcss.config.js` が最初から存在していなかった。
2. `postcss.config.js` を追加したが、`.js` のままだったためESモジュールのエラーが発生。

---

##  【解決の流れ】

### 1. **`postcss.config.js` ファイルの追加**
Tailwind CSS公式ドキュメントに従い、`postcss.config.js` ファイルを手動で作成しました。しかし、`module.exports` という形式を使っていたため、ESモジュール環境ではエラーが続きました。

### 2. **`postcss.config.cjs` ファイルへの変更**
最終的に、`postcss.config.js` を `postcss.config.cjs` にリネームし、CommonJS形式でPostCSSを設定することで、無事反映されました。

エラーメッセージで「**ESモジュールとCommonJSの違い**」について言及されていた通り、`package.json` に `"type": "module"` が指定されていたため、`postcss.config.js` がESモジュールとして解釈されていました。これにより、`module.exports` が無効となり、エラーが発生していたのです。

解決策として、`postcss.config.js` を `postcss.config.cjs` にリネームし、CommonJSとしてPostCSSの設定を定義しました。この変更により、PostCSSの設定が正しく読み込まれ、Tailwind CSSのビルドが正常に動作しました。

---
投稿 85 MVP 2024/09/23

本日の勉強時間　3H


MVPとは、必要最低限の機能を備えたプロダクトのこと。

デジタルプロダクト開発のプロセスの中で重要視されているのが、短い期間で素早くMVPを作成し、実際にユーザーに使用してもらうMVP検証です。
LB概要

いまさらのロードバランサ

ロードバランサとロードバランシング違い
--
ロードバランサは、その機能を実現するサービスで、ロードバランシングはプロセスという区分け

英語で「er」でサービスを指し、「ing」は進行中のプロセスを指す

使用する目的
--
サーバの負荷を分散するので、複数のサーバへの負荷(トラフィック)を片方に集中しないように、振り分ける

DNSラウンドロビンとロードバランサの違い
--
・DNSラウンドロビンは、サーバの状態を考慮しない
・ロードバランサはサーバの健康状態や負荷を考慮しながらトラフィックを動的に分配できる。よって、高可用とパフォーマンス向上を実現できる

ロードバランサとは
--
ロードバランサの役割として、サーバからの応答速度の遅延とシステムダウンを回避できる

応答速度の遅延を防ぐ仕組み
--
1.トラフィックを複数のサーバへ分配し、サーバ1台に対する過負荷を防ぎ、パフォーマンスを維持する

2.ヘルスチェック
各サーバをヘルスチェックし、正常なサーバへトラフィックを分配する

3.セッション維持
同じクライアントからのリクエストを特定のサーバに分配することで、セッション情報を維持することで、遅延を低減する

4.トラフィックの調整
ロードバランサが動的にトラフィックを動的に調整する

他には、地理的な負荷分散、オードスケーリング機能がありトラフィックに対して、柔軟にサーバが稼働できるようなサービスが提供される

参照リンク
https://www.infraexpert.com/study/loadbalancer1.html

ロードバランサの機能の深掘り
--
・ロードバランサシング
・パーシステンス
・モニター

ロードバランシングの振り分け方法
--
大きく分けて、`静的`と`動的`に分かれる
`静的`
あらかじめ定義したパラメータに応じてトラフィックをサーバへ均等に転送できるが、柔軟性にかける
※パラメータは、重み,リクエストの数など

`動的`
リクエスト、コネクション数、リソースに応じて動的にトラフィックを振り分ける

詳細は、以下を参照
https://www.infraexpert.com/study/loadbalancer4.html#google_vignette


パーシステンス
--
同一クライアントからのリクエストに応じて、セッション情報があるサーバへ振り分ける機能

パーシステンスの設定をしていない場合、別のサーバへセッションを張り直す必要があるため、サーバへ負荷がかかる
かといって、セッション情報を保持し続けると、XSS攻撃の的になるため、適当に設定する必要がある

パーシステンスの種類
--
・送信元IPアドレスを保持ロードバランサーが保持する
・Cookie情報をWebサーバが作成し、ロードバランサーが読み取るまたは更新をする

詳細は以下
https://www.infraexpert.com/study/loadbalancer5.html

モニター
--
サーバが正常に稼働してサービスを提供できる状態かチェックする。よって、正常に稼働しているサーバのみにリクエストが振り分けられる。

モニターの種類
--
ロードバランサーのモニターは、L3～L7ごとにチェックする
例えば、IPパケットが正常にサーバへ転送し、でサーバが正常か判断し、リクエストを振り分ける

詳細は以下
https://www.infraexpert.com/study/loadbalancer6.html

備考
--
基本を押さえたうえで、次はAzure Application Gatewayについてまとめようと思います
react 開発で使った有用サイトまとめ

react開発を行うにあたって有用なサイトなどを記載しておきます

1．シャドウジェネレーター
https://hiroyuki-n.github.io/boxShadow_generator/
    影をcssであてる際にサイドバーで簡単に操作してコードを出せる
    ![uploading...0]()
JestでSupabaseのAPIモック化：実践的なコードと解説

JestでSupabaseをモック化で詰まったので記事にしました。

### やりたいこと
Supabaseからデータを取得するメソッドをモック化してSupabase本体に依存しないテストを書きたい。

実際のコード
以下はsupabaseClientを初期化して返すメソッドです。
```import { createClient } from "@supabase/supabase-js"
import { Database } from "../database.types"

export const useSupabaseClient = () => {

  const supabaseClient = createClient<Database>(
    process.env.VITE_SUPABASE_URL!,
    process.env.VITE_SUPABASE_KEY!
  )

  return { supabaseClient }
}
```


以下はtestファイルです。先ほどのsupabaseClientが呼ばれた時に、select時の挙動を返します。
```
jest.mock("../hooks/useSupabaseClient.ts", () => {
  return {
    useSupabaseClient: () => ({
      supabaseClient: {
        from: jest.fn().mockReturnValue({
          select: jest.fn().mockResolvedValue({
            data: [
              {
                id: "1",
                name: "test1",
              }
            ]
          })
        })
      }
    })
  }
})
```

### 解説
まずテストファイルのuseSupabaseClientが、実装のsupabaseClientのメソッドをモックします。
`useSupabaseClient: () => ({`

useSupabaseClientはsupabaseClientを返すので、supabaseClientのオブジェクトを定義します。
このオブジェクトはSupabaseに関連するメソッドを持つオブジェクトです。
なのでfrom.select("table")とSupabaseへリクエストを送るときの挙動はこのオブジェクトの中に定義します。
```
from: jest.fn().mockReturnValue({
  select: jest.fn().mockResolvedValue({
```

from.select...とメソッドチェーンで実装するので、モックでは上記のようにfromメソッドの中にselectメソッドを定義します。

Supabaseのモックは以上です。

### 最後に
from.select...とメソッドチェーンで実装するので、fromメソッドの中にselectメソッドがあると考えるところの理解が足らず、今回は本モックの実装で時間がかかってしまいました。

あとselectはselectnのみで他のメソッドに切り出した方がもっと簡単でシンプルかと思いました。
本テストと実装に伸びしろがありますが、勉強になったので残しておきます。

以上です。
最後までご拝読ありがとうございました。
【ネタ記事?】コラッツ予想の反例を見つけて100万ドルをGETしよう！

# 作成したwebサイト
![画面収録 2024-09-16 23.22.35.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1373131/1df465bd-fa02-11d8-9932-c49a69ed71ca.gif)

# はじめに
みなさんはコラッツ予想を知っていますか？
コラッツ予想とは、どんな自然数であっても、決まった操作を行うと必ず1になるという予想です。
決まった操作とは
- 偶数であれば2で割る
- 奇数であれば3倍して1を足す

これだけです。
この操作を繰り返すと全ての自然数は1になるという予想です。

:::note info
例えば6であれば
6→3→10→5→16→8→4→2→1
という処理によって1になります。
:::

概ね正しいであろうと言われているこの予想ですが、完全な証明には至っていません。
その難しさから、**予想を証明できたら100万ドル(約1億4000万円)あげるよ**という企業も現れています。
今回はこれを検証するためのWEBサイトを作ってみました。

# 証明方法

## 予想が正しい立場

この予想の証明方法についてお話します。
予想が正しいと証明するためには全ての自然数において正しいと証明する必要があります。

しかし、自然数は無限にあります。
どんなに高性能なコンピュータで1から順に正しいことを証明したとしても、それは有限個の自然数の検証にしかならないため、証明できたとは言えません。

## 予想が間違っている立場

それでは「この予想が間違っているのでは？」という立場に立ってみます。
こうなると、証明自体は非常に簡単です。
「自然数1234でコラッツ予想は成り立たなかったよ」と示すことが出来たらそれで終わりだからです。

つまり！**予想が成り立たない自然数を、たった1つ見つけることが出来たら100万ドルGETなわけです！**

**そしてこのことを検証するWEBサイト、[Let's Collatz!](https://lets-collatz.com/)を作成しました** 🎉


使い方は簡単で、
- 好きな数字を入力して検証
- LUCKYボタンをクリックして100桁までのランダムな数字で検証

これだけです。
機能として以下を実装しています。
- その自然数が1になるまでに何回操作を行ったか
- 操作によって出力された最初と最後の5つの数を表示
- みんなが何回コラッツ予想にチャレンジしたか

みんなで反例を見つけて100万ドルをGETしよう！
幸運を祈ります！
https://lets-collatz.com/
ExcelでQiitaのAPIを使っていいね数・ストック数・ビュー数等をコーディングなしで一瞬で取得する

Qiitaのビュー数集計したいな…でもAPI叩くのにPython書くのめんどいな、ということで大好きなExcelで出力！
標準機能を使って所要時間2分くらいで出せます。

こちらの記事を参考にさせていただきました。

https://qiita.com/PowerBIxyz/items/1fc385fdd3727b312bdb

## Qiita APIのトークンの取得
まずはAPIのトークンを取得します。

設定＞アプリケーション＞個人用アクセストークン＞「新しくトークンを発行する」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/7a835313-2e50-e262-7171-5f0ee54c1cd4.png)

適当に名前を付けて、読み取りにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/cf8b7ae3-e471-36de-a7dd-91340105e36a.png)

この後、アクセストークンが発行されるので、なくさないように保存しておきます。

参考までにAPIの公式ドキュメントはこちらです。

https://qiita.com/api/v2/docs#%E6%A6%82%E8%A6%81

## Excelを開きAPI情報を記載
データタブ＞Webから＞詳細画面　で詳細設定を開き、以下入力します。
私の記事数は100に満たないため、このクエリ一つのみで取得できます。

```URL部分.txt
https://qiita.com/api/v2/authenticated_user/items?page=1&per_page=100
```

```HTTP要求ヘッダー.txt
左側：Authorization
右側：Bearer {$先ほど取得したtoken}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/ab3c8b5c-c67e-a02f-1d60-db653a4213fd.png)

## PowerQueryエディタで編集
### テーブルに変換
いきなりすべてのレコードがリストで出てくるので左上の「テーブルに変換」を押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/f3f406ce-a7f0-61e1-e5a7-c4f9ad939b2d.png)

### 展開して好きな項目を選択
テーブルに変換されたら、展開ボタンを押下し、出力したい項目を出します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/52de84c4-fb88-914c-cee9-4eb5af0a6534.png)


今回は以下を出力します。
* created_at    
データが作成された日時
Example: "2000-01-01T00:00:00+00:00"

* likes_count
この記事への「いいね」の数（Qiitaでのみ有効）
Example: 100

* stocks_count
この記事がストックされた数
Example: 100

* title
記事のタイトル
Example: "Example title"

* url
記事のURL
Example: "https://qiita.com/Qiita/items/c686397e4a0f4f11683d"

* page_views_count
閲覧数
Example: 100

項目についてはこちらの「投稿」に説明がございます。

https://qiita.com/api/v2/docs#%E6%8A%95%E7%A8%BF

### シートに読み込む
左上の閉じて読み込むを押すと…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/da2c099c-deb4-e1f7-c1dd-e84baff9230b.png)

簡単に出力することができました。
データを取り直したいときはデータの更新で簡単に更新できます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3629241/73a09df4-b6bc-048e-96e4-e186d82afb7f.png)

むっちゃ簡単！
【AWS】S3のアクセス制御【SAA-C03】

# はじめに
AWS ソリューションアーキテクト - アソシエイト(SAA-C03)を受験するにあたって、S3のアクセス制御についての選択肢を間違えがちだったので軽く整理をしてみました。

# バケットポリシー
・バケット単位でアクセス権限を設定するリソースベースのポリシー
・自AWSアカウントのIAMユーザーや他のAWSアカウントのユーザーにS3やそのオブジェクトへのアクセス権限を設定することが可能
・アクセス元のIPアドレスやドメイン単位でのアクセス制御が可能

# IAMポリシー
・IAMユーザー単位でアクセス権限を設定するIDベースのポリシー
・自AWSアカウントのIAMユーザーやグループ、ロールにS3リソースへのアクセス権限を設定することが可能
・他AWSアカウントにはアクセス制限を設定できない
・アクセス元のIPアドレスやドメイン単位でのアクセス制御が可能

# ACL(アクセスコントロールリスト)
・AWSアカウント単位でアクセス権限を設定する
・基本的な読み取り/書き込み許可を他のAWSアカウントに付与できる(自アカウントのユーザーには付与できない)

# まとめ
ソリューションアーキテクトの練習問題を解いている際は自分の中でアクセス制御についての理解が進んでいませんでした。しかし、自分なりに表に落とし込んでみたことで思ったより単純で、権限の設定単位をもとにどのアクセス制御方法が適切か選択できることが分かりました。

|            | バケットポリシー | IAMポリシー |    ACL        |
|:-----------|:-----------:|:------------:|:------------:|
| 権限の設定単位 | バケット  | IAMユーザー |AWSアカウント  |
| アクセス元のIPアドレスやドメイン単位でのアクセス制御  | 〇  | 〇 |✕  |
| 他のAWSアカウントのアクセス権限設定 | 〇 | ✕ | 〇 |

# 参考
https://www.ctc-g.co.jp/solutions/cloud/column/article/16.html

https://mondai.ping-t.com/g#content-large_category_2
【Ruby】文字列と数値を変換する方法

## 文字列を数値に変換する

文字列を数値に変換するには`.to_i`メソッドを使用します。

```ruby
value = "123"
integer_value = value.to_i
puts integer_value  
# 123
```

文字列が整数に変換可能な場合にはその整数値が返されます。
変換できない場合には、`0`が返されます。

```ruby
value = "abc"
integer_value = value.to_i
puts integer_value  
# 0
```

## 数値を文字列に変換する

数値を文字列に変換するには`.to_s`を使用します。

```ruby
number = 123
string_value = number.to_s
puts string_value  
# "123"
```

すべてのオブジェクトは`.to_s`メソッドを持っており、呼び出すことでそのオブジェクトの文字列表現を取得できます。

```ruby
array = [1, 2, 3]
string_value = array.to_s
puts string_value  # 出力: "[1, 2, 3]"
```
GitHubプルリクエストをローカルにcheckoutする手順

## 背景
背景としては他の開発メンバーのプルリクをこちらで修正するためにローカル環境へ内容を落とす必要があったためRequest(プルリクエスト)をローカルへcheckoutする必要がありました。

この記事では、GitHubのプルリクエストをローカル環境に取り込むための具体的な手順について説明します。

## 1. 対象リポジトリをclone
まず、対象リポジトリをローカルにcloneします。以下のコマンドを使用してください。

```
git clone git@github.com:GitHubアカウント名/test.git
```
testリポジトリを例としてcloneしています。

## 2. fetchを実行
次に、プルリクエストのIDと新しく作成するブランチ名を指定して、git fetchコマンドを実行
```
git fetch origin pull/1/head:develop
```
ここで、1はプルリクエストのIDで、developは作成するブランチ名です。プルリクエストのIDはGitHubのプルリクエスト画面から確認できます。

## 3. 作成されたbranchをcheckout
最後に、作成されたdevelopブランチをcheckoutします。
```
git checkout develop
```
この手順でローカル環境にプルリクエストの内容が反映され、修正や確認ができるようになります。

## まとめ
他の開発メンバーのプルリクエストをローカルにcheckoutする手順を紹介しました。複数人での開発時に、レビューや修正が必要な際に便利な操作です。この手順を活用することで、効率的にプルリクエストを確認・編集できるようになります。
Make it a Quote画像を生成するAPIと使用方法

こんにちは、りょうです。
今回はMake it a Quote画像の生成APIと使用方法の紹介です。

## Make it a Quoteとはなんぞや
こんなかんじの画像作れるやつです(語彙力)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/628c49f7-ac63-f18f-a886-c13230b45cb0.png)


## API
僕はこれを使ったDiscordBOTのコンテキストメニューを実装しました。
こいつ使います↓

https://api.voids.top/fakequote

こうなってるのでそれぞれ対応するのを入れてリクエスト送ります。
今回はリクエストにaxios使ってます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/072e8422-115e-aab4-cd2f-6b0edd33b3c4.png)

```miq.js
const axios = require('axios');

async function generateImage() {
    const requestData = {
        username: 'ユーザー名',             
        display_name: '表示名', 
        text: 'メッセージ',     
        avatar: 'DiscordのアバターURL', 
        color: false, // falseで白黒、trueでカラーになります                 
    };

    try {
        const response = await axios.post('https://api.voids.top/fakequote', requestData, {
            headers: { 'Content-Type': 'application/json' },
        });

        const imageUrl = response.data.url;
        console.log('生成完了:', imageUrl);
    } catch (error) {
        console.error('生成失敗:', error);
    }
}

generateImage();
```

成功するとこのように画像URLが返ってきます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/fa4a2141-21ae-2a6a-7775-ca642ae212ad.png)

## まとめ
これは公式のじゃないので若干本家と違う部分はありますがこれを活用してDiscordBOTにMake it a Quoteの機能を実装することができるので使ってみてください。

わからないことあったら書いてくれれば答えていきます。

**Discordにいる荒らしの情報や対策方法の共有をしている自鯖です**
ぜひ参加お願いします↓↓↓↓

https://discord.com/invite/ESRGwGQhxc
Supabaseでauth.usersテーブルとpublicスキーマ内のテーブルとをリレーションさせてはダメだった話

:::note
解決策から見たい方は[こちら](#解決策)を参照。
:::

# 背景

Supabaseを利用中、`public`スキーマ内に作成したテーブルに、Supbase Authで認証したユーザの情報を保持したいと考えていた。

Supabaseのダッシュボードを見ていたら、Supbaseの認証で利用しているテーブル`auth.users`のidを紐づけられそうだった。

そこで自身が作成した`user_id`と`auth.users`の`id`を紐づけてリレーションを作成した。

![dashboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163680/3dd15cfd-7e57-0dd7-3559-1c996ef7406d.png)

上記の設定をER図にすると、以下のイメージ。

```mermaid
erDiagram
    "auth.users" ||--o{ "public.some_tables" : has
```

リレーションが作成でき、アプリケーションからデータのinsertができた。

しかし登録したデータをユーザ情報と共にselect文で取得をしようとしたところ、以下のエラーが表示され取得に失敗した。

```
{
    "code": "PGRST100",
    "details": "unexpected "u" expecting "sum", "avg", "count", "max" or "min"",
    "hint": null,
    "message": ""failed to parse select parameter (auth.users(*))" (line 1, column 33)"
}
```

# 原因

Supabaseの仕様として、Supabaseで自動生成される`auth.users`等のテーブルに対し、クライアントからアクセス可能な権限を提供していない。
それにより、selectなどで`auth.users`テーブルのデータを取得しようとするとクエリが失敗してしまう。

解決策を探すと、権限を付与する方法と、`public`内に同期するテーブルを作り`trigger`で同期する手順の2つがあった。

- 同期テーブルを作る方法

https://stackoverflow.com/questions/77751173/getting-auth-users-table-data-in-supabase

- 権限を付与する方法

https://qiita.com/suin/items/f26cf3f3928c6c9eef35

今回は以下の理由より、同期テーブルを作る方法で対応した。

- 同期テーブルを作る方法は[公式ドキュメント](https://supabase.com/docs/guides/auth/managing-user-data)で公開されている方法
- `auth.users`の権限を触るのはSupbaseの推奨設定を変更する為、あまりよくなさそう


# 解決策

Supabaseの公式ドキュメントに手順を参考に進める。

https://supabase.com/docs/guides/auth/managing-user-data

具体的な手順は以下の通り。

1. `auth.users`テーブルの情報と同期する`profiles`テーブルを新規作成
2. `atuh.users`にデータが作成されたら、そのデータを`profiles`に同期するトリガー作成

## 1. `auth.users`テーブルの情報と同期する`profiles`テーブルを新規作成

はじめに`auth.users`テーブルとユーザ情報を同期する、`profiles`テーブルを新規作成する。


```sql
create table public.profiles (
  id uuid not null references auth.users on delete cascade, # auth.usersのユーザが削除されたら、このテーブルのデータも削除する
  first_name text,
  last_name text,

  primary key (id)
);

alter table public.profiles enable row level security;
```

`id`カラムは、`auth.users`テーブルのユーザ情報と同期する必要があるため、`auth.users`のデータが削除された時に`prfiles`のデータも削除する参照制約を付与している。

## 2. `atuh.users`にデータが作成されたら、そのデータを`profiles`に同期するトリガー作成

次に`auth.users`テーブルにデータが作成されたら、`profiles`テーブルにユーザ情報を同期する`function`を作成する。

```sql
create function public.handle_new_user()
returns trigger
language plpgsql
security definer set search_path = ''
as $$
begin
  insert into public.profiles (id, first_name, last_name)
  values (new.id, new.raw_user_meta_data ->> 'first_name', new.raw_user_meta_data ->> 'last_name');
  return new;
end;
$$;
```

具体的な処理は、ユーザが追加されたら`auth.users`テーブルの`id`と、`raw_user_meta_data`テーブルの`first_name`と`last_name`を、`profiles`テーブルにインサートするというものである。

最後に上記の`function`を呼び出す`trigger`を作成する。

```sql
create trigger on_auth_user_created
  after insert on auth.users
  for each row execute procedure public.handle_new_user();
```

こちらで設定は完了。

Supbase認証で新しくユーザが追加されるたびに、`profiles`にそのユーザが追加されるようになる。
JWT認証とDeviseによるセッションベース認証の違いとは？

## はじめに
現代のウェブアプリケーションでは、セキュリティとスケーラビリティを考慮した認証方式が不可欠です。本記事では、よく使用される認証方式である **JWT認証** と **Deviseによるセッションベース認証** の違いを比較し、それぞれのメリットと適用シーンについて解説します。

## 1. JWT認証とは？
- **仕組み**:  
  サーバーでユーザーを認証後、署名付きのJWTトークンを発行します。このトークンはクライアント側で保存され、以降のリクエストでサーバーに送信されます。トークンにはユーザー情報がエンコードされ、サーバー側でセッションを保持しない**ステートレスな認証方式**です。
  
- **メリット**:
  - サーバーでセッション情報を保持しないため、スケーラビリティに優れている。
  - 分散システムやモバイルアプリなど、サーバーロードが高くなる環境で有効。
  - クライアント側に保存されるため、複数のデバイス間での認証が簡単に行える。
  
- **デメリット**:
  - トークンが漏洩した場合、取り消しが難しい（ブラックリスト方式などで対応可能だが複雑）。
  - 有効期限を過ぎるまでトークンは有効であり、手動でのログアウトやトークンの無効化が難しい。

## 2. Deviseによるセッションベース認証とは？
- **仕組み**:  
  ユーザーがログインすると、サーバー側でセッションが生成され、ユーザー情報が保存されます。クライアント側にはセッションIDがCookieに保存され、リクエストごとにこのIDをサーバーに送信して認証を行います。

- **メリット**:
  - サーバー側でセッションを管理するため、セッションの制御が簡単（ログアウトやセッションの無効化が容易）。
  - 通常、HTTPSとともに使われるため、セキュリティが高い。
  - 一般的なウェブアプリケーションで広く使われている。

- **デメリット**:
  - サーバー側でセッション管理を行うため、スケーラビリティが低くなる可能性がある（特に大規模アプリケーションではセッション管理の負荷が増える）。
  - モバイルアプリや分散システムでは使用が複雑になる。

## 3. JWT認証とDevise認証の比較

| 比較項目         | JWT認証                       | Devise（セッションベース認証）  |
|------------------|-------------------------------|-------------------------------|
| **スケーラビリティ** | 高い（ステートレス）            | 低い（セッション管理が必要）   |
| **セキュリティ**    | トークン管理が必要              | HTTPSとCookieで保護           |
| **ログアウト管理**  | トークン失効が難しい            | サーバー側で簡単にセッション無効化 |
| **使用ケース**     | モバイルアプリ、APIベースのシステム | 一般的なウェブアプリケーション |

## 4. どちらを選ぶべきか？
- **JWT認証**: モバイルアプリやSPA（シングルページアプリケーション）、マイクロサービスなど、スケーラビリティが重要な場合に適しています。
- **Deviseセッション認証**: 標準的なウェブアプリケーションや小規模システムにおいては、実装が容易で管理がしやすいセッションベース認証が適しています。

## 結論
アプリケーションの性質や規模に応じて、適切な認証方式を選ぶことが重要です。JWTはスケーラブルで、特にAPIベースのアプリケーションに向いています。一方、Deviseによるセッションベース認証は、シンプルで扱いやすく、小規模なアプリケーションに適しています。
[Machine Learning]

# Image
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/ae68b547-0d88-4214-08d7-fcf039e4fbbb.png)

# 一覧
||活用事例|詳細|
|:--|:--|:--|
|教師あり|回帰分析|変数の値から他の変数の値を予測して、データがもつ変数間の関連性を確認する方法|
|教師なし|クラスタリング|変数の値が互いに類似するものを集めることによって、データを分類する方法|
|教師なし|主成分分析(次元削減)|変数を統合した新たな変数を使用して、データをもつ変数の数を減らす方法|
|教師なし|因子分析|変数に共通して影響を与える新たな変数を計算して、データの背後にある構造を取得する方法|
|強化|モンテカルロ法|数式で解を求めるのが難しい際に、乱数を使って擬似データを作り、数値計算によって解を推定する方法|


# 参考リンク
- [令和元秋4](https://www.ap-siken.com/kakomon/01_aki/q4.html)
VTuberサプーさんPython本を読んでみた。

# 「VTuberサプーが教える！ Python 初心者のコード／プロのコード」書籍レビュー

YouTubeで下記の動画が流れてきて
※独学クソリーマンの逆襲さんの動画、サムネ無断転載ごめんなさい

[![maxresdefault.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40177/a4f8b693-57c5-7cc5-51b5-1c63d7d32e2f.jpeg)](https://www.youtube.com/watch?v=9vvNLLWzO-8)

気になったので「[VTuberサプーが教える！ Python 初心者のコード／プロのコード]((https://amzn.to/4ebAIJj))」というサプーさんの本を読んで見ました。

<a href="https://amzn.to/4ebAIJj"><img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40177/f7f6a2bb-14dd-08de-01eb-131e02e8b54a.jpeg"></a>

骨太本は完読できてない日々を過ごしていますが、
逆にこういう表紙の本で良い本だった経験も少ない中、今回は結構な骨太本で良い本だったので記事を書いてみました。

## 本の概要
VTuberサプーさんがPythonのコードの書き方について初心者からプロレベルまでの知識とテクニックを解説するというコンセプトの本です。
コードの見た目の整え方から、読みやすさ、シンプルさ、安全性などを意識した「プロ」の視点でのコーディング手法がまとめられています。

## 予想外の骨太さ
正直に言うと表紙を見たときは「YouTuberの本か…」と思ってしまいました（ごめんなさい）。
ただ、見た目に反して結構な骨太本でした。
パラパラ読み流せる本じゃなくて、じっくり腰を据えて読むべき本でした。
半日くらいで読めるかなーと思ったら完全に騙され三連休の半分くらい溶けました…

本の構成は8章立てで、Pythonコーディングの基本から高度なテクニックまでカバーするコンセプトです。

1. コードの質の重要性
2. コードの見た目の整え方
3. 読みやすいコードへの改善テクニック
4. Python便利機能の活用
5. 安全性の高いコードの書き方
6. クラスとオブジェクト指向プログラミング
7. テストコードの作成
8. エラー解決のテクニック

## 個人的に刺さったポイント
正直10年くらいPythonで個人開発をしているので全く知らなかったという内容はなかったですが、もっと早くに出会えていれば、試行錯誤とか骨太本に手を出す時間とか短縮できたかもなーという感じでタイパ良い骨太本でした。

特に刺さったのは以下の2点です。

### イミュータブルなオブジェクトの扱い
第5章の「5-2 ミュータブル／イミュータブルの違いに要注意」はPythonでのオブジェクトの変更可能性の違いが引き起こす問題について。

**これにハマってバグ取りに時間を溶かした時間は、この本を読んだ時間より長そう…**
特にJupyter Notebookで事故る率が高い気が…

```python
# mutableオブジェクトなの忘れてる実装
def func(L=[]):
    return L

X = func()
X.append(1)
Y = func()

print(Y) #=>[1]　お前マジ何処から来たんだよ…😭
```

```python
# とりあえずデフォルト引数で配列・辞書・集合は避けよう
def func(L=None):
    if L is None:
        L = []
    return L

X = func()
X.append(1)
Y = func()

print(Y) #=>[]　若干めんどい、copy.deepcopy()を何も考えずやっちゃいそう
```

### テストのフィクスチャ、自作関数をモックに置き換える
第7章の「7-2-2 fixtureを使って事前処理・事後処理を追加」もっと早く知りたかった…！
「7-2-3 自作関数をモックに置き換える」、普段はKaggleとかの機械学習なNotebookとか外部APIを叩く系のコードが多いのでテストコード書いてなかったけどモック関数が手軽に書けるなら書いても良いかなと思いました（本当に書くかは…）。

## もう少し掘り下げて欲しかった

### クラス定義すべき？
前書きとかでも触れてたような気がする、どこからクラス定義にするかは正解ないけど…なところ、もう少し掘り下げて欲しかった。
クラス定義の例が動物なのもレガシー感が若干ありました。

### 生成AIの活用関連
第8章「エラー解決のテクニック」でChatGPTとかチラッと出てきたけど、個人的に最近はClaude 3.5 Sonetにエラーメッセージとソースコードを突っ込めば概ね解決するし、リファクタも結構できてるので、もう少し触れてほしかった。
ただ自分が初学者の頃に生成AIあったら絶対生成AIガチャやり続けて何も身に付かなかった自信があるし、バランス難しそう。

## まとめ
予想外の良書です。プロというよりは脱・初心者で中級者へって感じでしょうか。
あと個人開発で適当コードは書いてたけど今後仕事で使う方の第一歩にはなるかも。

「もっと早くこの本に出会いたかった」というのが正直な感想です。
Pythonのこと体系的に学びたいけど骨太本はなーっていう人は先にこれ読んでから骨太本を読むのが良いと思います。
【備忘録】Windows再インストール時の注意点

## はじめに
問題を解決するためにWindowsをクリーンインストールする必要があったので、また再インストールする時のためにメモを残しておきます。

## OSインストール
### 今回の問題
複数のドライバが読み込めず外付けキーボードやマウス、Windows Helloや指紋認証が使えなくなった。

### 環境
- Lenovo Yoga 7 2-in-1 14インチ (2024)
- Windows11 Home 23H2

### インストール方法
既にWindows11がインストールされているなら、起動時のメニューからOSを再インストールできる。
その際3つのパターンがある。
　①個人設定を維持したまま実行
　②まっさらな状態にして実行
　③USBメモリなどにリカバリメディアを作成して、外部からまっさらな状態にして実行

私の場合①と②を順に試したがドライバの問題は解決せず、③で解決した。

### インストール時の注意点
③のリカバリメディアからのクリーンインストールを行うと、今インストールされている各種ドライバも削除される。
Wi-fiのドライバも削除されたのでインストール時ネットワークに接続できず詰みかけた。（おそらく有線LANのUSBアダプタを使えば通過できていたとは思う） 

今回は以下の記事を参考に、Wi-fiを探す画面で`Shift` + `F10`でコマンドプロンプトを表示して以下コマンドを実行した。
```cmd:
oobe\BypassNRO.cmd
```
[参考：Windows11初回セットアップをオフライン環境でもできるようにする方法！](https://note.com/ictlink/n/n1092116ee9ba)

→結果ネット接続の要求をスキップして無事インストールを完了できた。

OSインストール後もネットに繋げない状態だったので、外部SSDにバックアップしていたドライバを使ってWi-fiのドライバをインストールし直した。
バックアップがない場合、別PCからメーカー公式HPのドライバをDLしてきてオフラインでコピーしてもOK。
あとのドライバ群はWindowsUpdateから自動で取得してひとまず完了。

ローカルアカウントで初回セットアップができたことで、ユーザーフォルダの名前を任意に決められたのでかえって良かった。（前はoutlookのメールアドレスの先頭5文字を強制されていて地味に困っていたので）


## おわりに
今回はOSが起動する状態での再インストールだったので、事前バックアップが自由にとれました。
突発で起動できなくなるシチュエーションではOS再インストールのハードルも上がるので、大事なデータは普段からバックアップしておかないといけませんね。
Basics of CTF Reverse Engineering

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812041/c7dc55ed-8e2f-0ce0-a90d-075495313b4c.png)

Hey, what’s up! I’m Keita. I work as a beginner C# programmer.

I am not involved in security at work, but I am learning.I often attend CTF because I am a regular student of security. However, it is not easy to solve the problems. Therefore, I will briefly summarize reverse engineering.

# Reverse Engineering
Reverse engineering is the process of analyzing existing software or systems to understand their internal structure and operating principles.

Although it may be a different story when it comes to CTFs, reverse engineering is usually done in the following steps.

### Target Selection

Select the software or system you wish to analyze. For example, a specific application or device firmware.

### Information Gathering

Gather documentation and specifications for the software or system of interest. This includes official manuals and publicly available technical information.

### Prepare Analysis Tools

Prepare tools to be used for reverse engineering. Typical tools include debuggers, disassemblers, and decompilers.

### Analyze Code

Analyze the actual software code. Read the binary code and understand how the program works.

### Documentation

Document the results of your analysis. This makes it easier to reuse later or share with others.


# Available Commands

### file Commands
The file command is used to determine the type of a given file. It analyzes the contents of the file and displays what format the file is in. For example, it can determine if a file is a text file, a binary file, or an image file.

#### example below
```
$ file exec_me
exec_me: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=663a3e0e5a079fddd0de92474688cd6812d3b550, not stripped
```

The output in the example indicates that the file is a 64-bit executable in ELF (Executable and Linkable Format) format and in LSB (Least Significant Byte) format.

### Chmod Commands
The chmod command is used to change file and directory access permissions. Note that it is quite possible to get stuck in a situation where the file to be investigated simply does not have execution permissions, so be careful!
#### example below
```
$ chmod +x exec_me
```
The basic idea is to use rwx to manage read/write execution, and the example grants execution rights.

### Strings Commands
The strings command is used to extract readable strings from binary and other non-text files. It is often used to verify textual information in binary files during reverse engineering.
#### example below
```
$ strings exec_me
/lib64/ld-linux-x86-64.so.2
libc.so.6
putchar
__libc_start_main
__gmon_start__
GLIBC_2.2.5
UH-@
UH-@
[]A\A]A^A_
・・・
```

# summary
I summarized the above.
It is not possible to solve really basic and difficult problems with this, but it is possible to solve easy problems and to get hints, so we want to make sure to use it well.

# remarks
The file used in the sample was answered by running it.
ベクトル検索とは

##背景
今回、ベクトル検索についてまとめようと思って理由としては、検索機能をアプリで作成していく中で、上司から最近はベクトル検索というのが主流になっているというのを聞き、自分自身全くベクトル検索について全く知らなかったため、今回まとめることにしました

###概要
ベクトル検索とは、データを高次元のベクトル空間にマッピングし、類似性に基づいて情報を検索する技術です。
一般的なベクトル検索の方法は、ユーザーの検索クエリをベクトル化し、同じベクトル空間にマッピングされた商品データとの類似度を計算します。類似度が高い商品から順番に検索結果を表示します。

以下の図において商品Aは商品Bより確度が小さく、類似度が高いため、検索結果では商品Aの方が上位に表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3765220/88651480-be1d-a7ef-791f-fcf5d925d080.png)

####メリット
①検索速度
ベクトル検索の距離の計算は単純な数学的な計算であるため、とても処理速度が速くなる。

②意味で検索できる
ベクトル検索では意味が近いものが検索される。そのため、通常の検索（全文検索）では引っかかることがないものが引っかかるため、検索のクオリティが上がります。

③画像・音声・動画も検索できる
ベクトル検索は埋め込みデータのコサイン類似度を計算しているだけなので、画像や動画から埋め込みデータを作成すれば類似の動画を検索するっことも可能になります。

#####最後に
今回簡単にベクトル検索についてまとめてみました。ただ、まだ自分自身勉強できていないことも多いので、これからもベクトル検索について学んでいきます
「言語化」はうまくできなくて良い

## 本の情報
**タイトル**
頭の回転が速い人の言語化のコツ

**著者**
金山拓夢

## 本の内容
言語化することは、相手に自分の思いや考えを伝えること。
相手が内容を正しく理解できるように伝えられることが、言語化がうまいことと言える。

言語化は意識を向けないと上達していかない。
インプットとアウトプットの機会を作っていくことが上達への道となる。

* インプット
コツの1つとして、「多くの答えを知ること」が挙げられる。
自分以外の答えを知ることで、これまで自分になかった視点が加わり、言語化する手段が増えていく。
また、過去の経験を整理することも重要である。
何らかの経験から得られる気付きを整理しておくことで、他の要素に紐づけて言語化の助けとすることができる。
また、日々の当たり前 / なんとなく を見直す ことも、新たな答えを知って整理することにつながる。

* アウトプット
アウトプットの回数を増やすこと自体が言語化上達につながる。
相手の反応により自分の言葉が伝わったか / どのような視点があるか のフィードバックが得られるほか、アウトプットして初めて自分の考え方に気付けることもある。
アウトプットを行えていない場合は、言葉のリミッターがかかっている / うまく伝えようとしすぎている といったことが考えられる。
→状況や伝え方に意識が向きすぎてしまうせいでどう伝えるかに比重を置いてしまい、自分の思ったことと実際に伝えたい内容が異なってしまう という状態
大事な状況では状況や伝え方に意識を払うことは重要なので、身近な人との会話などで思ったことを言う訓練をしてみると良い。

今後の時代では、いかに自分の経験や考えを基にして発信 / 行動できるかが求められる。
まずは、言語化への意識を変えて、自分が大事ではないと思っていることを疑ってみる好奇心を持って、言語化力の向上につなげていきたい。

## ためになった点
* 言語化の目的
言語化は、「相手に伝わる」ための技術であるという記載があった。
どうしても「自分が伝える」ことに意識が向きがちであるため、言語化の目的の一つとしてこの視点が得られたことは、これからアウトプットする際にも効果があると感じた。

* 言い切ることの価値
自分の意見を伝える際に言い切ることは、魅力を引き立てるとともに、自身や信念の表れである という記載があった。
この部分は感情に対する内容ではあるが、自分が言いきれないことも併せて納得の行く意見だった。
また、言い切れないのは確信がないからだ という記載もあり、自分の仕事の姿勢を振り返る視点にもなると感じた。

## まとめ
言語化に関して、平易な内容 / 伝え方 で記載されている印象を受けた本でした。
そのおかげで、言語化力を磨くことへのハードルは少し下がったように感じています。
シチュエーションに応じたアウトプットを始めるためのコツ の記載などもありましたので、日々の日常に絡められるかというところからこの本の内容に取り組んでいきます。
ありがとうございました。
エンジニアの思考整理を身につける①【世界一流エンジニアの思考法】Part2・Part3

# Part2:情報整理

## 要点
1. コードリーディングのコツはコードを読まないこと
1. マルチタスクは生産性が低い(それはそう)
1. 説明可能な状態にするにはブログを書くことが有効

## 概要
### 1. コードリーディングのコツはコードを読まないこと
自分も人が書いたコードを読むことが多々あるが、コードを一目見るだけで頭が痛くなるぐらいコードリーディングは苦手である。

なので、この本の「極力コードは読まないようにして、インターフェイスと構造を理解出来るようにする」という考え方は目からウロコだった。コードリーディングだからコードを読まなければならないと勝手に思っていたが、よくよく考えてみると1からすべてを見ていくのは、確かに疲れるし効率が悪い。

なので、コードを読む際はどういう目的でこのコードは構成されているのか、そして最終的にどの辺りを見ないといけないのかを吟味しながらコードリーディングをしていくことを心がけていく。

### 2.マルチタスクは生産性が低い
これは割と分かりきっていることというか、正直マルチタスクをしたくてしている人はあまりいないと思う。

仕事上マルチタスクをしなければならないことがあるが、その場合は一旦片方の作業を中断してもう片方の作業を終えてから再び作業を再開するのが良いだろう。ただ、その時にさっきまでやっていた作業のことを忘れてしまうことがあると思うので、あらかじめ取り決めを決めておくべきだろう。

･･･と、ここまで書いてきて何だが、自分はマルチタスクをしなければならない状況になったことがない。どちらかというと、自分でマルチタスクの状況を作っているというかあれもこれも手を出して、結果的にマルチタスクになってしまうことが多い。

もちろん生産性は低いので、自分なりにあらかじめ取り決めを決めて実行し、マルチタスクをしないように心がけていく。

### 3.説明可能な状態にするにはブログを書くことが有効

この内容は他の書籍か動画などの媒体で同じ意見を聞いたことがある。

確かにこの意見は割と正当性があると考えており、自分は今JavaScriptの配列を使用して色々している。

その際に配列を操作する関数が数多くあるのだが、公式のページっぽい「MDN Web Docs」というサイトを見ても良くわからないことが多い。それとmapやforEachという非常に似ている処理があるのだが、色々なWebサイトを見ても漠然としか理解ができない。

そこで、分からないことやもっと詳しく知りたい概念はどこかにメモをとっておき、休日にブログを書いて整理してアウトプットすることがより効率的に技術を身につけられる手法だと考えた。

なので、自分が考えた全体の流れは次のとおりである。

:::note info
#### ①分からないことがあったらメモを取る→②ブログを書いたりして整理しながら理解する→③実際にコードを書いて理解できているかを確認する
:::

# Part3:心構え(マインドセット)

## 要点
1. リスクや間違いは快く受け入れる(失敗に寛容になる)
1. 定時を過ぎてもダラダラ働かない
1. 意見が対立しても否定しない(否定されて嬉しい人間はいない)

### 1. リスクや間違いは快く受け入れる(失敗に寛容になる)

人間は失敗する生き物である。そして、その失敗から何かしらの教訓や改善点を得て改善し、今まで発展をしてきたんだろうと考えている。

『世界一流エンジニアの思考法』では、開発者系のデカいイベントで著者が大分致命的な失敗をして同僚や上司から『そんなに気にするなよ』と言われたという話が印象に残った。

日本ではまずない対応だろう。同じような言葉をかけることはあると思うが、「尻拭いをしないといけないな･･･」等と思ったりして、その内面は決して穏やかではないだろう。

だからといって日本の企業が全体的に悪いという話ではないが、どちらかというと失敗に寛容な職場の方が働くのが楽しいし、成果を出そうとする意欲も上がるだろう。

特にエンジニア系の仕事はよくわからないことのオンパレードかつ、非常に技術の変遷が早いので、失敗に寛容ではない職場だと気が滅入ることになるだろう。

### 2. 定時を過ぎてもダラダラ働かない
巷でよく言われていると思うが、日本人は基本的に働き過ぎだと思う。
自分も少し前に身をもって知ったが、人間は8時間も働くとすごく疲れてしまう。

この本の著者もアメリカに行ってから2年ほど猛烈に働いていたみたいだが、限界が来て途中で仕事を定時上がりにする手法に切り替えたらしい。定時で切り上げたあとに生産性を上げるための学習を行うことで、エンジニアとしてより成長できたみたいだ。

自分も仕事は定時を過ぎたらなるべく早めに切り上げて、JavaScriptや他の技術についての学習に時間をかけている。

ただ、今のところ効果はそんなにないため、改善が必要である。

### 3. 意見が対立しても否定しない

基本的に自分の意見が否定されることは気分が悪いだろう。
でも、人の意見を受け取って改善できないと製品を生み出すことはできない。

そうなると、どうすれば良いのか?その答えと言える考えは、

 :::note info
#### 相手の意見やアイデアを否定せず、自分の考えとして意見を言う
:::
である。

この鉄則を遵守すれば、お互いの意見を尊重することができ、円滑なコミュニケーションが取れるようになるだろう。

この考え方は、個人的に凄く腑に落ちた内容で、自分の周りにも自分の意見だけを押し付けて人の話を聞かない人が存在する。なので、そういう人達は反面教師として取り扱って自分は自分の道を進むことを心がけようと思う。


## おわりに
『世界一流エンジニアの思考法』は自分が今まで読んできた思考法の中で特にお気に入りの本であり、自分とは違う世界的なエンジニアがどういう風に働いているのかも知ることができた。エンジニア・プログラマー関連の職に就く人達には特におすすめできる本である。

また、サーバントリーダーについての内容など、まだ読み解けていない箇所があり、もうちょっと成長してから改めて読んでも新たな学びを得られるだろうと考えている。

これからもより生産性の高いエンジニアに成ることを目指して、書籍や動画を参考して検証と改善を行っていく。
データ分析系の学会スケジュール（日本）

最近、データ分析関連の研究活動で学会発表が増えてきたため、発表機会を失念しないようまとめました。
私の研究分野上GISや環境リスクなどの分析関連が中心です。（日本のみ）

|開催月 | 学会名 |URL |備考 |
|:-|:-|:-|:-|
|2月 |データ工学と情報マネジメントに関するフォーラム（DEIM）　|https://www.ipsj-dbs.org/events/ | |
|3月 |日本オペレーションズ・リサーチ学会　春季研究発表会　|https://orsj.org/conference | |
|5月 |日本地球惑星科学連合大会　|https://www.jpgu.org/ | |
|5月 |日本気象学会・春季大会　|https://www.metsoc.jp/meetings | |
|5月 |土木計画学研究発表会・春大会　|https://jsce-ip.org/home/biannual-conference/ | |
|5月 |人工知能学会全国大会　|https://www.ai-gakkai.or.jp/event/national-convention/ | |
|8月 |交通工学研究発表会　|https://www.jste.or.jp/research_activities/conferences/ | |
|9月 |統計関連学会連合大会　|http://www.jfssa.jp/meeting/ | |
|9月 |日本オペレーションズ・リサーチ学会　秋季研究発表会　|https://orsj.org/conference | |
|9月 |地震工学研究発表会　|https://committees.jsce.or.jp/eec231/ | |
|10月 |地理情報システム学会学術研究発表大会 |https://www.gisa-japan.org/conferences/ | |
|11月 |土木学会 構造工学委員会　AI・データサイエンスシンポジウム |https://committees.jsce.or.jp/struct1002/node/8 | |
|11月 |情報論的学習理論ワークショップ（IBIS）　|https://ibisml.org/ibis/history| |
|11月 |日本気象学会・秋季大会　|https://www.metsoc.jp/meetings | |
|11月 |応用地域学会研究発表大会　|https://arsc.org/jp/index.html | |
|12月 |人工知能学会　合同研究会　|https://www.ai-gakkai.or.jp/event/sigconf5/ | |
AWS Kinesis系サービスについて

## AWS Kinesis
ざっと以下のサービスがある
①Kinesis Data Stream：ストリームデータを __リアルタイムに処理__ 

シャードという単位でデータを取り込み・処理でき、取り込み・処理後の配信では１つのシャードに対して複数のリソースを指定できる（同じデータに対して複数の処理を同時並行で実行可能）

②Kinesis Data Firehose：ストリームデータを __変換・配信__ 

サーバのログ等をs3等のデータ保存サービスに流すことができる。流す際には容量圧迫を見越してデータを圧縮したり予めデータ加工して置いたりすることが可能。
S3にログをファイルとして出力することが可能であり、YYYY/MM/DD/TT:TTの粒度までオブジェクト構造を決めることができる

③Kinesis Data Analytics：ストリームデータを __分析__ 

使ったことないので触ったらまた追記する・・・

アーキの例としては、
①データインプット対象　→　Kinesis data stream　→　Lambda/kinesis data analytics/EC2等
③データインプット対象　→　Kinesis data firehose　
→　S3/Redshift等

2024/10/12追記
Kinesis Data StreamとKinesis Data Firehoseとの大きな違いとしては「リアルタイムに」処理できるか否か

Kinesis Data Stream　：リアルタイムに処理可能
Kinesis Data Firehose：数分のラグが発生

#### ストリームデータ
システムログやゲーミングアプリのデータなどの連続して現れ続けるデータのことであり、この場合はパッチ処理などのある一定時間経過後にまとめて処理するのではなく、リアルタイムに処理を実行し続ける（ログを解析してダッシュボード化する・ゲームの情報をリアルタイムに更新しSNSでユーザに訴えかける等）ことが求められます。
Tomcatで永遠に404が出て困った（解決せず）

新米も新米のJava練習生です。
結果が単純なものなので、読むほどのものでもないかと思いますのでご容赦ください。
解決せずプロジェクトを最初から作り直しています。それまでのいきさつとなります。

EclipsからTomcatを使用してウェルカムファイルを作成しようとしていました。

ところがコピペしたはずのweb.xmlファイルと、index.htmlファイルを設定しても
ウェルカムファイルを開けず。。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3892844/430de436-6a89-bc1c-60cc-8988faa9fe90.png)

web.xmlファイルのコードはこの通りです。（htmlファイルは割愛します。）

```java:web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
		  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  		  xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
                      https://jakarta.ee/xml/ns/jakartaee/web-app_4_0.xsd"
  		version="4.0"
  		metadata-complete="true">

    <!-- ウェルカムファイルの設定 -->
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>
```

ここからTomCatのバージョンを新しくしますが、状況は変わりませんでした。

```java:web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
		  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  		  xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
                      https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
  		version="6.0"
  		metadata-complete="true">

    <!-- ウェルカムファイルの設定 -->
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>
```

なんと2時間ほど悩んだ結果は、
プロジェクト名の誤字でした。

"servlet_jsp"の"r"が抜け落ちていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3892844/f23c0d43-1aa9-b37a-bf49-84867e95f5d4.png)

sevlet_jspを入力してアクセスしたところ、問題なくアクセスできました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3892844/39aae141-d000-f345-a54f-3fbe152540f5.png)

プロジェクト名を変化して、、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3892844/e311a31d-d17a-1046-07e8-a234865d520f.png)

治ったか！と思えばまたアクセスできず…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3892844/430de436-6a89-bc1c-60cc-8988faa9fe90.png)

次はhtmlファイルが見つけられなくなった模様。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3892844/7bac9e0b-a790-3f99-656e-a3d60125df4f.png)

eclipseからhtmlファイルを一度削除し、再度作り直すも、404エラーのままです。

どうやら、プロジェクト名を変更すると、コンテキスト名が変わることによるエラーが生じるようです。

プロパティからTomCatのコンテキスト名を変えることで対応できるようでしたが、
TomCatの設定にもアクセスできず、いろいろ対処したことにより、Tomcatも起動できなくなりました。

プロジェクトをいったん削除し、
初めから作り直したところ、問題なくアクセスできたため、私にはわからないエラーとなってしまいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3892844/cf7f9fd3-f383-ba81-e10a-f5443eaafc77.png)

わからないことばかりですが、すこしずつ進んでいこうと思います。
VScodeで自作の言語拡張をカスタマイズ！ 狙った色でコードをハイライトする方法

# 課題
VSCodeの言語拡張を作成中に、TextMateで指定するハイライト色をどうすれば自分好みに設定できるか悩みました。
自作のカラーテーマを作るという手もありますが、それはあまり魅力的に感じなかったため、普段使っているGitHubテーマ「GitHub Dark」の色を直接活用する方法を試してみます。

# これってどうやるの？
目標は、GitHub Darkのテーマで使用されている色をカスタマイズして、狙った色でコードをハイライトすること。テーマ全体を作り直すのではなく、既存の色から選び出して適用するだけなので、簡単かつ効果的です。

# 色の探し方と設定方法
色を見つけるには、GitHubテーマのソースコードを確認しましょう。たとえば、tokenColorsセクション（246行目あたり）から、お好みの色を選んでみてください。

" 実際に試してみる
以下は、実際にハイライトをさせてみて確認した例です。自分が欲しい色っぽいものを抽出してみました。

```json
{
  "name": "support.constant.gcode",
  "match": "supportconstant-blue"
},
{
  "name": "source.regexp.gcode",
  "match": "sourceregexp-lightblue"
},
{
  "name": "entity.name.tag.gcode",
  "match": "entitynametag-green"
},
{
  "name": "variable.gcode",
  "match": "variable-orange"
},
{
  "name": "message.error.gcode",
  "match": "messageerror-pink"
},
{
  "name": "brackethighlighter.tag.gcode",
  "match": "brackethighlighter-gray"
},
{
  "name": "markup.heading.gcode",
  "match": "markupheading-blue-bold"
},
{
  "name": "invalid.broken.gcode",
  "match": "invalidbroken-pink-italic"
},
{
  "name": "markup.changed.gcode",
  "match": "markupchanged-orange"
},
{
  "name": "markup.ignored.gcode",
  "match": "ignored-dark"
},
{
  "name": "meta.diff.range.gcode",
  "match": "diffrange-purple-bold"
},
{
  "name": "string.other.link.gcode",
  "match": "stringother-liteblue-under"
},
{
  "name": "entity.gcode",
  "match": "entity-purple"
},
{
  "name": "keyword.gcode",
  "match": "keyword-red"
}
```
このコードの中の、 `match` のみ含んだファイルを登録して実行してみると、実際画面でどのように表現されるのかを確認することができます。

# 結果
![color-variation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651937/578b8877-ae01-dcda-0db0-c207481e3ff5.png)

使いにくそうな色も混ざっていますね。

# まとめ
最終的に、いくつか理想的な色を見つけて適用することができました。拡張機能のカスタマイズに色の名前や意味にはこだわらず、見た目だけを採用して作業を進めました。これで、開発環境がより自分好みのものに仕上がります！
【POCO Tips】C++ POCOライブラリでISO8601拡張形式のローカル時刻を取得する方法

# はじめに
　C++の[POCOライブラリ](https://pocoproject.org/)を使って、ISO8601拡張形式のローカル時刻を取得する方法を紹介する。

# 動作確認環境
* Ubuntu 20.04
* POCO 1.9.2

# 方法

2024/9/25追記：　本記事のコメントで簡潔な方法を教えて頂いたので方法1として追記修正します。

## 方法1 (推奨)

```cpp
#include <iostream>
#include <string>
#include <Poco/Timestamp.h>
#include <Poco/DateTimeFormat.h>
#include <Poco/DateTimeFormatter.h>
int main() {
    using namespace Poco;
    using namespace std;
    Timestamp now;
    string s = DateTimeFormatter::format(LocalDateTime(now), DateTimeFormat::ISO8601_FORMAT);
    cout << "Local time ISO 8601 extended = " << s << endl;
    return 0;
}
```

## 方法2

方法1の方が簡潔なので推奨。方法2は記録として残しておく。結果は同じになる。

```cpp
#include <string>
#include <Poco/Timestamp.h>
#include <Poco/Timezone.h>
#include <Poco/LocalDateTime.h>
#include <Poco/DateTimeFormatter.h>

int main()
{
    // ローカル時刻とUTCとのオフセット時間を取得
    // ※ローカル時刻は、ホストPCのタイムゾーンに従う (Ubuntuの場合は、echo $TZで確認可能)
    int time_zone_offset_seconds = Poco::Timezone::utcOffset();

    // オフセット時刻のフォーマット取得
    std::string offset = Poco::DateTimeFormatter::tzdISO(time_zone_offset_seconds);
    
    // 現時刻をローカル時刻に変換
    // ※ローカル時刻は、ホストPCのタイムゾーンに従う (Ubuntuの場合は、echo $TZで確認可能)
    Poco::Timestamp now;
    Poco::LocalDateTime local_datetime{Poco::DateTime{now}};

    // ローカル時刻をISO8601拡張形式に変換（例:2024-09-22T07:24:50+09:00)
    std::string local_time_iso_extended = Poco::DateTimeFormatter::format(local_datetime, "%Y-%m-%dT%H:%M:%S") + offset;

    std::cout << "Local time ISO 8601 extended = " << local_time_iso_extended << std::endl;

    return 0;
}

```

結果例
```bash
Local time ISO 8601 extended = 2024-09-22T07:24:50+09:00
```

# まとめ
　C++の[POCOライブラリ](https://pocoproject.org/)を使って、ISO8601拡張形式のローカル時刻を取得する方法を紹介した。POCOライブラリを活用することで、少ないコードで時刻変換を実現できた。

# 参考

https://docs.pocoproject.org/1.9.3/

https://docs.pocoproject.org/current/Poco.Timezone.html

https://ja.wikipedia.org/wiki/ISO_8601