OmniAICreator/Qiita-1.07M huggingface dataset:
G検定 やったことまとめ

## はじめに

G検定2023#3(7/8)に合格したのでその記録を残しておきます。
受験勉強のの参考になればと。

## 進め方
基本はシラバスのキーワードをまとめることで、AI関連知識を整理してカンペを作る方向で進めました。
進め方はKEIさんの動画を参考にしています。
(究極のカンペまでは作れてないです。)
問題の傾向が説明されているので一番初めに見るとよいです。

https://www.youtube.com/watch?v=f8_2tfKsCVg

## 勉強内容
まずは白本を一通り読み、あまり理解できなかった箇所や白本に載っていないシラバスのキーワードを調べて資料にまとめていきました。
特にCNNでなぜ画像分類ができるのかについてはAIciaさんのCNN回がとても分かりやすかったです。
参考書に載せてほしい。

https://www.youtube.com/watch?v=vU-JfZNBdYU&list=PLhDAH9aTfnxKXf__soUoAEOrbLAOnVHCP&index=5

ディープラーニングの世界 シリーズはG検定で出てくるモデルが紹介されているので、時間があればすべて見ておくとよいかと。
シラバスに出てくるモデルについてはNNCさんの動画もみて勉強しました。

https://www.youtube.com/@NeuralNetworkConsole/

---
自然言語処理についてはもともと ゆる言語学ラジオ を見てたので、言語学的な知識についてはあまり調べてはいませんが、モデルは一通り調べました。
赤ちゃんの言語習得 シリーズはとても面白くて自然言語処理につながる内容なので、一度みてみるのもよいかも。

https://www.youtube.com/watch?v=AMIaheSRVew

---
ほかにも人物をまとめたり、略語のリストをつくったり、同じようなキーワード（○○学習とか)をまとめたり、ILSVRCに出てくるモデルのリストを作ったりしました。

## 模擬試験
JDRAのサイトから飛べる模擬試験を1週間前に実施しました。(確か75%だったと思います。)
3日前にもう一つの模擬試験を実施しましたがサイト忘れました。。。

## 勉強しておけばよかったこと
各国の法整備の話などは情報を入れておくと確実に点が取れる問題が増えたかなと感じました。
受験後に実施している社内のAIコンテストで役に立たなさそうだったのであまり勉強してませんでしたが…
GDPRはいまだに把握してません…

## あまり勉強しなかった箇所
特許と著作権については会社のe-Leaningである程度知識があるのであまり勉強しませんでした。
(特許については新規性とかのキーワードがわかってれば飛ばしてよいかと。)

## 最後に
現在、社内のAIコンテストに参加していますが、論文が読めたりモデルを探せたりできるようになっていたので、結構有効な検定なんだと思います。
(論文に書いてあるモデルやその精度が読み取れるようになったのは大きいです。)
東京都のデジタルツイン

# メモ
昨日は，関東大震災100年の節目の日だったようですが，
東京都デジタルツイン実現プロジェクトで，点群データが公開されたみたい。
https://info.tokyo-digitaltwin.metro.tokyo.lg.jp


その他，3Dビューアーで，河川水位も表示できるようになったもよう。
- 水防災総合情報システム
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601976/c6d58254-eb41-6bf3-0d2f-0d92f054e605.png)

- 多摩・島しょ地域LP点群データ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601976/dfaac66c-c527-ae2a-2396-dcecdb243c9f.png)

とりあえず，点群データを使ってみようかなと。
【React】現在のウィンドウやダブを閉じる方法

以下のようにするとボタンをクリックすると現在のウィンドウやタブを閉じることができます。

```js
  <button
    type="button"
    onClick={() => window.close()}
  >
    現在のタブを閉じる
  </button>
```
現在見てるページをそのまま共有してみる


# 現在見ているページをそのまま共有してみる

Boxには、あまり知られていない裏機能として、資料内の指定のページを共有する機能があるのをご存知でしたか？

[いくつ知ってる？Boxの隠れ便利機能5選 - Qiita](https://qiita.com/natsumib/items/516782b527d1a8269a50)

上記から抜粋：
```
ページ指定の場合
共有リンクのURL＋#p=XX
XXに指定のページ番号を入れてください。
例えば、10ページ目を共有したい場合はリンクの末尾に#p=10と記載
```


共有リンクの後ろに\#p=ページ番号　を付けて共有するとリンクを開いた相手はファイルの指定のページが直接開く仕組みになっています。



ただしBoxのUI上から直接ページ番号の指定できず、自分で共有リンクの後ろに付け加える必要がある。
UI上からもページ番号指定できるようになるよと言われて何月年経ったどうか。。。実装される気配がない。


そしたら自分で実装してしまえということで、今見ているページの共有リンクを作成できるChrome拡張機能作ってみました。

画像：
![CleanShotiQ5XRQvb.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227518/4f807278-4da6-c384-25e9-ef3543f98f1a.gif)



よかったら使ってみてね。

[Chrome ウェブストア - 拡張機能 (google.com)](https://chrome.google.com/webstore/detail/share-page-number/oiglgnpdmicmcbolibbjkmdancpbogdp)



いきおいで作ったのであまりきれいな作りじゃないけど、バグや機能改善などあればこちらにご連絡ください。

https://github.com/Band-Aid/share-box-page/tree/main
python2 が壊れてた

もう数週間前から Raspberry Pi3B+ の apt upgrade が途中でクラッシュ。やっと原因を突き止めた。python2.7 自体が segfault を起こしている。

対処は、python2 を使っている pycompile と pyclean をそれぞれ py3compile と py3clean へのシムリンクで置き換えた。

apt upgrade したらドンと 98個くらいの詰まっていたアップグレードが通った。
WSL で syslinux のビルドをする

## 背景

普段自分が使っている NixOS だと素直には行けず、しかし急ぎだったので仕方なく別 Windows 端末の WSL でビルドした。  
ちなみに NixPkgs にも一応 syslinux はあるが、自分の欲しかった `/usr/lib/syslinux` にあたるものが含まれていなそうだった。

## 手順

空っぽに近い Ubuntu だったので、必要パッケージのインストールなども含みます。

```
curl -O https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/Testing/6.04/syslinux-6.04-pre1.tar.gz
tar xvzf ./syslinux-6.04-pre1.tar.gz
cd syslinux-6.04-pre1
apt update && apt install gcc uuid uuid-dev
vim extlinux/main.c
```

vim で以下のように `include` を追加する

```extlinux/main.c
// L40
#include <sys/types.h>
#include <sys/mount.h>
#include <sys/vfs.h>
#include <sys/sysmacros.h> // これを追加
```

いよいよビルドできる。

```
make installer
```

おわり。
Vuetifyにおける v-container と v-layoutの違いは？

`v-container`と`v-layout`は、Vuetify内でレイアウトを構築するためのコンポーネントですが、それぞれ異なる目的を持っています。

### v-container

v-containerは、アプリケーション全体のコンテンツを包むためのコンテナコンポーネントです。このコンテナは、レスポンシブデザインをサポートするために使用され、ウィンドウの幅に応じてコンテンツの幅を自動的に調整します。また、v-containerはBootstrapのcontainerクラスに似た役割を果たし、アプリケーションの主要なコンテンツを中央に配置するのに便利です。

```javascript
<template>
  <v-container>
    <!-- アプリケーションの主要なコンテンツ -->
  </v-container>
</template>
```

‌

### v-layout

v-layoutは、アプリケーション内のコンテンツをグリッドまたはフレキシブボックスレイアウトで配置するためのコンポーネントです。v-layoutを使用することで、コンテンツを横方向や縦方向に配置し、カラムとしてグループ化することができます。v-layoutは、Bootstrapのrowクラスに似た機能を持っています。

```javascript
<template>
  <v-layout row>
    <v-flex>
      <!-- 左側のコンテンツ -->
    </v-flex>
    <v-flex>
      <!-- 右側のコンテンツ -->
    </v-flex>
  </v-layout>
</template>
```

要するに、`v-container`はアプリケーション全体のコンテンツを包むためのコンテナであり、`v-layout`はコンテンツをグリッドやフレキシブボックスレイアウトで配置するためのコンポーネントです。これらのコンポーネントを組み合わせて、Vuetifyアプリケーションのレイアウトを効果的に構築できます。
Pyvolをgoogle colaboratoryで動作させてみた

Pyvolはpymolを用いてタンパク質のポケットを検出するためのプラグインです。

https://github.com/schlessinger-lab/pyvol

macでは動作に制約がある場合があるようですので、試しにGoogle Colaboratoryでも実行できるか検証した。

<h1>必要なツールのインストール</h1>

pyvol自身はpipでインストールできるようである。
```
!pip install bio-pyvol
```

また、動作させるためにはmsmsのインストールが必要なようです。
msmsはcondaをインストール必要がありますので、mincondaのインストールと併せて行います。
```
%%bash
#mincondaのインストール
MINICONDA_INSTALLER_SCRIPT=Miniconda3-latest-Linux-x86_64.sh
MINICONDA_PREFIX=/usr/local
wget https://repo.continuum.io/miniconda/$MINICONDA_INSTALLER_SCRIPT
chmod +x $MINICONDA_INSTALLER_SCRIPT
./$MINICONDA_INSTALLER_SCRIPT -b -f -p $MINICONDA_PREFIX

#msmsのインストール
conda install -y -c bioconda msms
conda install -y -c "bioconda/label/cf201901" msms
```

<h1>confingファイルの準備</h1>

以下のコマンドでconfig用のファイルを出力します。

```
!pyvol -t output_template.cfg
```
この処理により「output_template.cfg」というファイルが出力されます。
実行するときはconfigファイルに必要情報を記入して実行します。
configファイルの中身は以下のようになっています。
このファイルを編集したのちに実行を行います。

```
[General]
prot_file
lig_file
min_rad = 1.4
max_rad = 3.4
constrain_radii = True

[Specification]
mode = largest
coordinates
resid
lig_excl_rad
lig_incl_rad
min_volume = 200

[Partitioning]
subdivide = False
max_clusters
min_subpocket_rad = 1.7
max_subpocket_rad = 3.4
min_subpocket_surf_rad = 1.0
radial_sampling = 0.1
inclusion_radius_buffer = 1.0
min_cluster_size = 50

[Output]
project_dir
prefix
logger_stream_level = INFO
logger_file_level = DEBUG

[PyMOL]
protein
ligand
protein_only = False
display_mode = solid
palette
alpha = 0.85

```

<h1>configファイルの設定</h1>

解析に用いるpdbファイルをアップロードし、適切にconfigファイルを編集します。
今回はpdb1.pdbというファイルをアップロードし、以下のように「output_template.cfg」の中身を編集しました。
不要なパラメーターは削除すると良いようです。

```
[General]
prot_file = pdb1.pdb
min_rad = 1.4
max_rad = 3.4
constrain_radii = True

[Specification]
mode = largest
min_volume = 200

[Partitioning]
subdivide = False
min_subpocket_rad = 1.7
max_subpocket_rad = 3.4
min_subpocket_surf_rad = 1.0
radial_sampling = 0.1
inclusion_radius_buffer = 1.0
min_cluster_size = 50

[Output]
logger_stream_level = INFO
logger_file_level = DEBUG

[PyMOL]
protein_only = False
display_mode = solid
alpha = 0.85

```

その後、以下のコマンドを実行します。

```
!pyvol output_template.cfg
```

プログラムが動作し、以下のような結果が出力されます。

```
pyvol.identify:   	INFO    	Largest pocket identified
pyvol.identify:   	INFO    	Report written to: /content/132716-592971_pdb1.pyvol/132716-592971_pdb1.rept
pyvol.configuration:   	INFO    	Configuration file written to /content/132716-592971_pdb1.pyvol/132716-592971_pdb1.cfg
```

結果がサブフォルダに出力され、以下のようなデータが出力されます。

```
132716-592971_pdb1.cfg
132716-592971_pdb1.log
132716-592971_pdb1.rept
132716-592971_pdb1_p0.obj
132716-592971_pdb1_p0.xyzrg
pdb1.pdb
```

.cfgは入力に使ったファイルのコピーです。
.logは解析のlogが入っています。
.reptには検出されたポケットの名前と大きさが格納されているようです。
objとxyzrgがポケットの情報のようです。

pdb1.pdbと132716-592971_pdb1_p0.objをChimeraXで開くとポケットの範囲を見ることができました。
132716-592971_pdb1_p0.objはそのままではpymolで開くことができませんでした。この問題は今後解決したいと思います。

![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1825372/d056b743-e745-8ab4-32ee-43a88c9b694e.png)
[Xcode] コマンドのみでGitと連携する方法

## はじめに
日本語でコマンドのみでXcodeをGitに連携する方法が書いてある記事が見当たらなかったので残しておきます。(あったらごめんなさい)

### Githubサイトにて新しいレポジトリを生成
[Github](http://github.com)
まずはGithubサイトに移動して、New repositoryを押します
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3536354/61b9d6fa-1ab1-59e4-41ce-5d57849be11f.png" width="400px">

次に以下の画面が出てくると思います

PublicかPrivateかはお好みで大丈夫です(今回はPrivateにしておきます)
また、画面のファイルに関する下の３つはいじらなくて大丈夫です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3536354/10cffbff-ac65-c308-5fc9-c73942c3849b.png" width="400px">

### ディレクトリに移動
続いてmacOSでターミナルアプリを開き、プロジェクトを作成したディレクトリに移動します。
僕の場合はデスクトップに置いていたので次のように書きます
(プロジェクトファイルを直接マウスで持ってくることも可能です)
```
cd /Desktop/YourAppName
```
### READMEファイルを作成
次にREADMEファイルを作成します。
これは、誰かがリポジトリにアクセスしたときにGitHubに表示されるものです。
```
echo "# YourAppName" >> README.md
```
これによりREADME.mdに# YourAppName"がコピーされます


### Gitリポジトリを作成
次にローカルフォルダーにGitリポジトリを作成します。これにより、Gitは作業の追跡を開始するように指示されますが、最初はローカルでのみ行われます。これを行うには、次のコマンドを実行します。
```
git init
```
この時点で、Git はファイルを監視しています。積極的に監視するわけではなく、要求に応じて変更を探します。

### Gitに変更を追加
現時点ではすべてが新しいため、Gitにすべてを追加してもらうために次のコマンドを打ちます。
```
git add .
```
### ソース管理にコミットして保存
続いて、それらの変更をソース管理にコミットし、保存します。
これはコマンド「git commit」を使用して実行されますが、「-m」を使用してメッセージを追加し、次にテキストを追加することで、変更を加えた理由を述べることができ、コミット履歴を確認する必要がある場合に「修正」よりも「検索アルゴリズムの変更」を見つけやすくなるため、時間が経つにつれて役立ちます。

下のコマンドを実行して、すべての変更をコミットします
```
git commit -m "Initial commit."
```
これにより、ステージングした内容がすべて保存されるため、Git 内で安全になります

### GitHubにリモートで保存できるようにする
そして最後に下記の3つのコマンドでGitHubにリモートで保存できるようにします。

まず、これを実行してコードの「メイン」ブランチを作成します。
```
git branch -M main
```
次に以下のコマンドを実行してGitHubをコードのオリジンにしたいことをGitに伝えます
```
git remote add origin https://github.com/〜 ←githubのURL
```
最後に、これを実行します。
```
git push -u origin main
```
これは、「コードを GitHub に送信しますが、同時にメイン ブランチを GitHub 上のオリジンと一致させます。」という意味です。

以上でGithubサイトにあなたのアプリが連携できているかと思います。
お疲れ様でした🐈
LeetCode (easy) Two Sum 解き方(C#)

### LeetCode easy <Two Sum> 解き方(C#)

LeetCodeのEasy問題。自分の備忘録も兼ねて。

### 問題について

まずは問題。Two Sumは、int型の配列numsとint型の整数targetを引数に、
二つの数値の和がtargetの値となる配列を返すメソッドである。

```
Example 1:
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].

Example 2:
Input: nums = [3,2,4], target = 6
Output: [1,2]

Example 3:
Input: nums = [3,3], target = 6
Output: [0,1]

```

一見簡単？と思ったが難しい。
for文はメモリの使用上、あまり良くないそうなので使わないようにしたが、
それだと全然他に方法が思い浮かばなかった。
以下の回答は、他の方の回答を自分なりにまとめたものになります。


### 回答

```　
public class Solution 
{
    public int[] TwoSum(int[] nums, int target) 
    {
        var pairs = new Dictionary<int, int>();
        for(int i = 0; i < nums.Length; i++)
            if(pairs.ContainsKey(target - nums[i]))
                //該当する回答を配列で返す
                return new int[] { pairs[target - nums[i]], i };
            else
                //ディクショナリに Key:nums[i], Value:i を追加
                pairs.TryAdd(nums[i], i);
        
        return default;
    }
}
```

7行目の　if(pairs.ContainsKey(target - nums[i])　)で、
作成したディクショナリのキーとして、 target から 配列の数値nums[i] を引いた数値があるか判定し、
あれば返り値として探索済みの該当の数値をディクショナリのKeyとしてその要素番号となる数値・ペアになる数値の要素番号iを配列で返す。
ない場合は、ディクショナリ内に nums[i](探索済みの配列内数値)・i(配列の要素番号)を追加。

```
if(pairs.ContainsKey(target - nums[i]))
                //該当する回答を配列で返す
                return new int[] { pairs[target - nums[i]], i };
            else
                //ディクショナリに Key:nums[i], Value:i を追加
                pairs.TryAdd(nums[i], i);
```

サンプルの１を参考に追ってみるとわかりやすい。


```
Example 1:
Input: nums = [2,7,11,15], target = 9
Output: [0,1]
```

＜１週目＞
まず、for文１週目は i=0
Dictionary pairsは宣言したてなので何も入っておらず、当然else文へ。
pairsに(2,0)が追加される。
＜２週目＞
i = 1
pairsには(2,0)が入っており、ConstainsKey(9-7=2)が該当する。
配列[pairs[9-7]=0, 1]が返り値として返ってくる。
一つ目の要素([0])は0,二つ目の要素([1])は2。
回答のOutput: [0,1]と合致する。



Dictionaryはlistより圧倒的に早くて効率がいいので、どの回答を見ても
１番効率的な回答として選ばれていることが多かった。

ちなみに、2年ほどC＃を使用しているけれど、return defaultという返し方があったのは初めて知った。
もっとちゃんと基礎から勉強し直さなければ、と思った。

自分ではわかったつもりになっても、こうして文章にするとちょっとわかりにくいな、と感じる。
あとは回数を重ねて、解決、解説ともに慣れていきたい。
APIのレスポンスデータの内部構造について

APIのレスポンスデータの構造について、オライリーさんの書籍「[Web API The Good Parts](https://amzn.asia/d/ar8FnEG)」を読みながらまとめました。

:::note info
レスポンスデータを決定する際に考えべきポイントは、APIのアクセス回数がなるべく減るようにすること。そのために、APIのユースケースをきちんと考えることが重要。
:::

例えば以下のようなAPIを考える、、、
```bash:
{
    "friends": [
        12394,
        23954,
        98034,
          :
          :
    ]
}
```

**友達のユーザーIDだけを配列で返している。データのサイズは小さくなるが、ID情報しか取得できない。。。**

:::note warn
クライアント側のユースケースを考えると、
「**APIの情報をもとに友人一覧を画面に表示する**」など、ID一覧だけで足りるはずがない。
その他にも、
・名前
・プロフィールアイコン
・性別
などある程度の属性情報も必要なはず。もしクライアント側がID情報をもとにユーザ情報を取得するために、もう一度APIにアクセスする場合、**最低2回**のアクセスが必要になってしまう。
:::

以上から単にIDのリストを返すのではなく、以下のようなユーザー情報が入ったリストの方が使用しやすい。
```bash:
{
    "friends": [
        {
            "id": 12394,
            "name": "Tetsuto Yamada",
            "profile_icon": "http://image.exaple.com/....",
                :
                :
        },
        {
            "id": 23954,
            "name": "Munetaka Murakami",
            "profile_icon": "http://image.exaple.com/....",
                :
                :
        },
          :
          :
    ]
}
```

1つの作業を完結するために複数回のアクセスが必要とするようなAPIの設計は”Chatty（おしゃべり）なAPI”と呼ばれる。APIを作成した人が思いもよらない使われ方を利用者がする可能性もありますが、ある程度のユースケースが想定できるはず。そのユースケースに沿った形であれば、**できる限り少ないアクセス回数ですむAPI設計**を心がけることが重要。


:::note info
WebAPIは単なるデータベースのアクセスインターフェースではなく、**アプリケーションのインターフェース**であるので、そのアプリケーションの特性を踏まえた上で利用者が使いやすい構造を検討する。
:::
PostgreSQLでautovaccumを有効化する

## 環境

PostgreSQL12.4
Ubuntu20.4

## はじめに

PostgreSQLの運用を開始すれば、日々運用管理を行う必要が出てきます。特に重要なのが、VACUUMとANALYZEです。公式情報によると、自動バキュームは強く推奨されているもようです。

## VACUUM

テーブルの更新/削除が何回も繰り返されると、タプルと呼ばれる空になった無駄領域が残り続けることになります。PostgreSQLが無駄に所有してしまったディスク領域をクリアにして、ディスク容量を圧迫させないようにする機能がVACCUMです。PostgreSQLは多版同時性制御（MVCC）と呼ばれるアーキテクチャを採用しており、構造上どうしてもタプルが発生してしまいます。


テーブルの更新/削除が多ければ多いほど、タプルの容量は雪だるま式に増えていきます。タプルの容量が大きくなるとデータベースへのRead/Writeの速度に影響が出てきてしまいます。

どこかのタイミングで定期的にVACUUMを実行して、肥大化したデータベースの容量を、実際の容量に戻してあげる必要が出てきます。機能としてはMS-Accessのデータベースの最適化に似ています。

VACCUMを実行してもテーブルに対して排他ロックはかからないようになっています。ユーザーのアクセスに影響がないように、深夜にこっそりと実行しなくてはいけないといったことはありません。日中に堂々と実行してOKです。

vaccumコマンドに似たコマンドに、vaccum fullコマンドがあります。vaccumコマンドでは排他ロックはかからないが、vaccum fullコマンドでは排他ロックがかかることになります。手動でvaccum fullコマンドを実行すれば、ユーザーのアクセスに影響が出てしまうため、業務時間を避けて実行しないといけないことになります。自動バキュームでは、vaccum fullコマンドではなく、vaccumコマンドの方が流れるようになっています。ご安心を。vaccum fullコマンドは手動でしか流すことはできません。

## ANALYZE

各テーブルが持っている統計情報を最新の状態に更新するのがANALYZEです。テーブル参照のレスポンスを早くするために、インデックスが付けられますが、統計情報が古いと折角インデックスを付けても、それに見合ったパフォーマンスが得られなくなることになります。

テーブルの更新/削除が頻繁に行われれば行われる程、統計情報の状態は、実体とどんどんとかけ離れていくことになります。統計情報を最新にすることで、Select文のレスポンスを早くすることができるようになります。「最近、レスポンス遅くね？」と思ったら、ANALYZEを実行するべきです。

ANALYZEが実行されると、テーブルに対して一時的に読み取りロックがかかるが、排他ロックはかかりません。ANALYZEが実行されることでユーザーのレスポンスが低下することはないのため、日中に堂々と実行してOKです。

## 設定

VACUUMとANAZYZEはコマンドから手動で実行することはできますが、PostgreSQL側で自動化することもできます。自動化させるには、postgresql.confでつぎの２行のパラメータを設定すればOKです。デフォルトでは２行ともコメントアウトされているため、外せばいいだけです。
```postgresql.conf
autovaccum = on
track_counts = on
```

自動バキュームを有効化すると、ANALYZEも自動で実行されるようになります。自動バキュームのデーモンが統計情報を参照するようになっており、必然的にANALYZEも流れるためです。

自動バキュームデーモンを有効にすれば、デーモンが常駐するようになります。そして、タプスの閾値が超えれば、VACCUMEが自動で実行されるようになります。


## パラメータ

公式マニュアルによると、VACCUMが実行されると、ディスクに対し割と相当数のI/Oが走るようです。ディスク領域に余裕があるのであれば、VACCUMが走る間隔は、極力少なくしておいた方がレスポンスへの影響を少なくすることができます。自動バキュームを有効化するにあたり、考慮しておくべきパラメーターについて、いくつかピックアップします。

autovacuumの実行チェックが行われる間隔です。デフォルトでは1分です。使い方にもよりますが、1分は流石に短すぎだと思ったら、ここの設定はもっと延ばしてください。
```postgresql.conf
autovacuum_naptime = 1min
```

VACCUMが実行される閾値の設定です。閾値は次の式で計算されます。
「autovacuum_vacuum_threshold ＋ autovacuum_vacuum_scale_factor × レコード数」

テーブルにデータが100件あった場合、デフォルト値の設定であれば
50 ＋ 0.2 × 100 ＝ 70となります。
データが70件、更新/削除されればVACCUMが流れることになります。

テーブルにデータが1000件あった場合、デフォルト値の設定であれば
50 ＋ 0.2 × 1000 ＝ 250となります。
データが250件、更新/削除されればVACCUMが流れることになります。

ここの設定はデフォルト値で妥当だろうと個人的には思います。しかし、状況によってはカスタマイズしてくださいということになります。

```postgresql.conf
autovacuum_vacuum_threshold     = 50
autovacuum_vacuum_scale_factor  = 0.2
```

## 参考情報

https://www.postgresql.jp/document/12/html/sql-vacuum.html

https://www.postgresql.jp/document/12/html/sql-analyze.html

https://www.fujitsu.com/jp/products/software/resources/feature-stories/postgres/article-index/tuningrule9-base/
ChatGPTより！？Perplexity AIのすすめ

# ChatGPTも良いけれど・・・  
世の中的にChatGPTが主流だが、情報が最新でなかったり信憑性が疑わしかったりと、
調べものをするのに適しているのか？と思うことがある。  

そこで調べたところ、「Perplexity AIという対話型のAIと出会った。  

# Perplexity AIとは？ChatGPTとの違いは？    
折角なので直接そのまま聞いてみた。  
※2023年9月時点の情報です。
※前の質問や聞き方により、回答が変わる可能性があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3472185/73b3f53f-3143-c486-b1f6-8d9c47320c0a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3472185/bcaf328c-440c-b024-4bde-6e5f9e32d15c.png)

ソースが含まれていると安心する。
思っていた答えが返ってこなかったとしても、ソースのページに飛ぶことで
自分の欲しかった情報に出会える、なんてこともありそうだ。


# Perplexity AIとChatGPTの強みは？  
こちらもまたまた直接そのまま聞いてみた。  
※2023年9月時点の情報です。
※前の質問や聞き方により、回答が変わる可能性があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3472185/02451f0b-8e18-68e5-8445-00f8f07f93bc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3472185/1d6844ce-3cd9-f5e2-1851-d58af486f712.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3472185/880b2605-e03c-6bfc-f6ba-44f053adaf9d.png)

ちなみにPerplexity AIが公開されたのは2022年12月。
一方でChatGPTは、2021年9月までの情報に基づいて対話をしている。
つまり、ChatGPTに聞いても「Perplexity AI」の(固有名詞としての)情報は返ってこない。  

# ハンズオン  
新幹線の名古屋駅のおすすめランチを質問してみた。
ChatGPTで質問すると存在しないお店を回答されることがあるが、
今回Perplexity AIで質問したところ、どのお店もあった。

※大規模な駅に構えているお店だと、○○店のような支店名表記が
　少し違っている場合もあるようだ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3472185/2f83e401-914f-609d-c4d9-30fac34a88b7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3472185/6b4db7fc-1740-f613-2227-4f705941038d.png)


# まとめ  
ChatGPTにもPerplexity AIにも、それぞれ向き不向きや強みがあるように診られる。  
用途に合わせて使い分けてみてはどうだろうか。
データ活用基盤を作ってみたその２(要件定義)


# はじめに
こんにちは。NTTデータ先端技術の亀井（@kamein）です。
本記事はデータ活用基盤を作ってみた連載記事のその２(要件定義)です。
本シリーズの取り組みの内容については[その１(構成シナリオ)](https://qiita.com/kamein/items/81df29ef9d32bf0a0810)をご覧ください。
本記事では、データ活用基盤の要件定義の考え方・進め方についてご紹介します。

# 目次
+ 要件定義の考え方
+ 要件定義で実施したこと
+ 要件定義で注意したこと

# 要件定義の考え方
要件定義では、システム化で実現する仕様（必要な機能や非機能目標）を定義付けします。定義付けを行うことで、使用する製品・技術選定や開発工数を具体的に見積ることができるようになります。そのため、要件定義は「様々な観点からから仕様を検討すること」、「責任分界点を明確化し、システム化範囲を定めること」が重要です。

要件定義が曖昧なまま後続工程に進むと、想定外のシステム開発を求められたり、低品質なシステム納品を迎えて顧客満足度下がる事態となります。
システム開発はどの工程も重要なタスクですが、要件定義工程はシステム全体の品質(Q)・コスト(C)・納期(D)に大きな影響を及ぼすところなので、特に重要な工程だと考えます。

# 要件定義で実施したこと
今回のPJは学習目的で顧客はおらず、要件定義の曖昧さが後々問題となっても自分たちでQCDをコントロールできるので、"えいや"で要件定義付けして後続工程に進みました。
> 〇実案件での要件定義について
> 実案件では顧客ヒアリングを重ねて実現すべき仕様を明確化する必要がありますが、限られた打ち合わせ時間の中で全ての仕様をヒアリングのみで仕様定義付けを行うことは現実的ではありません。
システム目的からシステム開発者側である程度は"えいや"で仮定してから、顧客と具体的な仕様を定める方が良いです。要件定義の抜け漏れを防いだり、効率的に進めることに繋がります。
顧客側と開発側が一体となって定義付けを進めていくんだという意識を持つことが大切です。

# 要件定義で注意したこと
要件定義は抜け漏れなく仕様を決定することが難しいです。
それは、検討範囲が多岐にわたる上に案件ごとに実現するシステムが異なるため、それぞれ独自の要件定義項目を検討して成果物を作成するためです。

今回のPJでは、ユースケースから整理することおよび活用できる他ドキュメントを流用することを意識して作成しました。参考にできそうなドキュメントにNTTDATAが提供している[ビッグデータ活用基盤リファレンスアーキテクチャ](https://oss.nttdata.com/bigdata-reference/)がありましたので、こちらを活用しつつ、ユースケース整理を意識して以下の成果物を作成しました。

|成果物|概要|参考|
|-|-|-|
|観点一覧.xlsx|分析要件の文書化|ビッグデータ活用基盤リファレンスアーキテクチャを引用|
|ビッグデータ活用基盤_検討項目表_非機能編.xlsx|非機能要件の文書化|ビッグデータ活用基盤リファレンスアーキテクチャを引用|
|アクター定義一覧.txt|アクター一覧表|-|
|業務フロー図.xlsx|ユースケース一覧図|-|
|システム構成図.xlsx|システム構成図|-|

# 最後に
機能要件はシステムごとに大きくことなるので検討が難しいですが、非機能要件は[IPA(情報処理推進機構)](https://www.ipa.go.jp/archive/digital/iot-en-ci/jyouryuu/hikinou/ent03-b.html)が提供する非機能要求グレード表が基盤構成検討に必要な観点がほとんど盛り込まれており強力です。これまで基盤構成を検討してことが無い方は、一度は目を通しておいた方が良いと思います。（今回はNTTDATA資料を活用しましたが、こちらもベースはIPAの非機能要求グレード表です。）

次の記事は、[データ活用基盤を作ってみたその３(基本設計)](https://qiita.com/shiraki_ils/items/86c40a8c4676572650ab)です。
最後までお読み頂きありがとうございました。
PNGテキスト情報取得ツール：TkinterとPILを使って簡単にPNGメタデータを表示する(Python)(ChatGPTによる生成記事)

## はじめに

PNG（Portable Network Graphics）ファイルは、画像データだけでなくテキスト情報やメタデータも持っています。
この記事では、TkinterとPIL（Pillow）ライブラリを使用して、ドラッグアンドドロップでPNGファイルからテキスト情報を取得し、表示するシンプルなPythonスクリプトを紹介します。

## 必要なライブラリ

このツールを動かすためには以下のPythonライブラリが必要です。

- Tkinter (標準ライブラリなのでインストール不要)
- tkinterdnd2
- PIL (Pillow)
- pyperclip

インストールは以下のように行います。

```
pip install tkinterdnd2 Pillow pyperclip
```

コード
以下が主なコードです。

```png_metadata.py
Copy code
import tkinter as tk
from tkinterdnd2 import DND_FILES, TkinterDnD
from PIL import Image
import pyperclip
import os

def get_png_text_data(file_path):
    safe_file_path = os.path.normpath(file_path)
    image = Image.open(safe_file_path)
    return image.info

def on_drop(event):
    file_path = event.data.strip().strip('"').strip('{}')
    
    text_info = get_png_text_data(file_path)
    text_str = "\n".join([f"{k}: {v}" for k, v in text_info.items()])
    
    pyperclip.copy(text_str)
    
    text_widget.delete(1.0, tk.END)
    text_widget.insert(tk.END, text_str)
    
    label.config(text="PNGのテキスト情報:")

root = TkinterDnD.Tk()
root.title("PNGテキスト情報取得ツール")
root.geometry("600x400")

label = tk.Label(root, text="PNGファイルをここにドラッグ&ドロップしてください。")
label.pack(pady=10)

text_widget = tk.Text(root, wrap=tk.WORD)
text_widget.pack(padx=10, pady=10, expand=True, fill=tk.BOTH)

root.drop_target_register(DND_FILES)
root.dnd_bind('<<Drop>>', on_drop)

root.mainloop()
```

## 使い方
スクリプトを実行します。
```
python png_metadata.py
```

GUIウィンドウが表示されます。
PNGファイルをウィンドウにドラッグ&ドロップします。
テキストボックスにPNGファイル内のテキスト情報が表示されます。
このテキスト情報は自動的にクリップボードにもコピーされます。

## まとめ
このスクリプトは、TkinterとPILを使って非常に簡単にPNGファイルのテキスト情報を取得できるツールです。
ドラッグ&ドロップで手軽に情報を得られるため、画像のメタデータを簡単に調べたい場合に非常に便利です。
【SwiftUI】シンプルなカスタムローディングを作成する

# はじめに
最近SwiftUIでのアニメーションの勉強してるので簡単なローディング画面を作ってみました。

# こんな感じ
![Simulator Screen Recording - iPhone 14 Pro - 2023-09-01 at 22.14.54.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/51cf66ba-6023-95f7-af57-fbb0c875a430.gif)

# 実装
```swift
import SwiftUI

struct ContentView: View {
    @State private var isLoading = false

    var body: some View {
        Circle()
            .trim(from: 0, to: 0.7)
            .stroke(.black, lineWidth: 5)
            .frame(width: 30, height: 30)
            .rotationEffect(.degrees(isLoading ? 360 : 0))
            .animation(.linear(duration: 1).repeatForever(autoreverses: false), value: isLoading)
            .onAppear {
                isLoading = true
            }
    }
}
```

# おわり
いい感じですね
自宅の回線速度を継続的に計測する方法


自宅の回線速度が遅く、APEXをまともにプレイできていません。

最近ではとうとう東京サーバへの接続を回線速度が遅すぎるため拒否されてしまいます。
（PS4、PC両方で同じ現象のためネット回線が原因のはず。もちろんチートBANなどはされてません。）

おそらく深夜以降は回線速度に強制的な制限がかかっていそうなので調べたい。

だけど毎回計測サイトをぽちぽちしたくない。

ということで継続的に回線速度を計測する方法です。

### Speedtest CLIを使用して回線速度を計測する

https://www.speedtest.net/ja/apps/cli

コマンドラインで回線速度を計測することができるツールです。

ありがたく使わせてもらいましょう。

Mac, Linux, Windows全てで動きます。

インストール方法については公式にありますので割愛させていただきます。

私の場合はMacなのでHomebrewから公式に書いてあるコマンドでインストールしました。

### Speedtest CLIのオプションを調べる

ただ単にspeedtestと打つだけで自動的に回線速度を測ってくれるようなのですが、今回はきちんとデータとして持っていたかったのでオプションを調べます。

幸いなことに公式のmanが提供されています。

``` man
man speedtest
```
ここで使えそうなオプションを調べます。

こんな感じにカスタムしました。

``` Linuxコマンド
speedtest --server-id=28910 -f csv --output-header >> result.csv

# --server-id=28910
# speedtest -Lで近くのサーバ一覧が出るため適当に選択。

# -f csv
# csvで吐き出してもらう

# --output-header
# 見出しをつける（ダウンロード速度など。手打ち実行の最初の一回のみ実行）
```

これで計測するたびにresult.csvに追記されていくコマンドになりました。

### cronに定期的に実行させる

cronに10分おきに実行してもらうようにしこみます。

まずspeedtestコマンドがどこにあるか知りたいので、whichコマンドで探ります。

``` which
which speedtest
```
私のMacだと/usr/local/bin/speedtestにありました。
ターミナルで/usr/local/bin/speedtestと打つとspeedtestコマンドが実行されたため間違っていないことを確認。

``` cron
crontab -e
```
viか何かが立ち上がるので、条件を入力。

``` cron
*/10  * * * * /usr/local/bin/speedtest --server-id=28910 -f csv >> /Users/あなたのユーザ名/Desktop/result.csv
```
result.csvがあるディレクトリなどはお好みで変更してください。

### 続々と追加されてくる計測結果を眺める

tailコマンドのfオプションでログが追記されても継続的に観測することができます。

``` tail
tail -f result.csv
```

ちなみにフィールドの情報は下記です。

``` field
"server name","server id","idle latency","idle jitter","packet loss","download","upload","download bytes","upload bytes","share url","download server count","download latency","download latency jitter","download latency low","download latency high","upload latency","upload latency jitter","upload latency low","upload latency high","idle latency low","idle latency high"
```
このままだと見にくいから加工してダウンロード速度だけ取り出したい。
と、いうのはまた今度記事にしたいと思います。

今回は自宅の回線速度を継続的に計測する方法を紹介いたしました。

こういうことを継続的にやるために超消費電力ミニPCやラズパイが欲しくなりますね〜！

参考サイト様
発見したときに、こんな面白そうな事はやるしかないと思いました。
ありがとうございます。

https://eng-blog.iij.ad.jp/archives/16720

https://zenn.dev/tomioka/articles/497077a2a4688e
GPTファインチューニングしたモデル一覧の表示方法 Fine-tuning 

# GPT-3.5がファインチューニング対応可能に

2023年8月23日、OpenAIはGPTのファインチューニングへの対応を発表
まだgpt-3.5に限ってですがAPIで独自にカスタマイズしたモデルが利用できるようになりました！
（gpt-4も今後対応予定とのこと）

https://openai.com/blog/gpt-3-5-turbo-fine-tuning-and-api-updates?utm_source=pocket_saves

色んな方の解説がとても参考になります
（こちらの方の記事がとても分かりやすいです）
https://qiita.com/shinichi1729/items/da1d1635cf393291c069

私も色々試行錯誤試しており、いつかまとめて記事にしたいですが
今回は単にファインチューニングしたモデルがわからなくなったときのために
モデルの一覧を表示する方法紹介したいと思います！

# モデル一覧取得
モデル一覧の取得にはopenai.Model.list()を利用します。
※openaiはインストール済の設定（Version: 0.28.0）
```python
import openai

openai.api_key = 'ここはopenaiキー'

response = openai.Model.list()
print(response)
```
```python:出力結果
{
  "object": "list",
  "data": [
    {
      "id": "davinci",
      "object": "model",
      "created": 1649359874,
      "owned_by": "openai",
      "permission": [
        {
          "id": "modelperm-uJaD4C9nXA6tPNoBII9hcYF4",
          "object": "model_permission",
          "created": 1692634268,
          "allow_create_engine": false,
          "allow_sampling": true,
          "allow_logprobs": true,
          "allow_search_indices": false,
          "allow_view": true,
          "allow_fine_tuning": false,
          "organization": "*",
          "group": null,
          "is_blocking": false
        }
      ],
      "root": "davinci",
      "parent": null
    },

…　以下モデルの数だけ続きます
```

# ファインチューニングモデルのみ抽出
これですと通常のモデル（"owned_by"が"openai"など）も表示されますので
ファインチューニングであるもの（"owned_by"の頭が"user-"）で絞り
またいつ作成したかがわかる"created"をUNIX時間（エポック秒）から変換します。

```python
import datetime

response = openai.Model.list()

# "owned_by"の最初が"user-"で始まるものだけ抽出
user_models = [i for i in response.data if i.owned_by.startswith("user-")]

for model in user_models:

  # UNIX時間からdatetimeに変換
  dt = datetime.datetime.fromtimestamp(model.created)

  # 日本時間に直す
  dt_jp = dt + datetime.timedelta(hours=9)

  print(model.id,dt_jp)
```
```python:出力結果
# モデルID                               # 作成した日付
ft:gpt-3.5-turbo-0613:personal::7rfjMVD4 2023-08-26 14:02:32
ft:gpt-3.5-turbo-0613:personal::7rhfOxQt 2023-08-26 16:06:34
ft:gpt-3.5-turbo-0613:personal::7tc15W83 2023-08-31 22:28:51
```

こんな感じです。もし
「最後に学習したデータがわかると思ってた…」

など期待をしていた方はすいません。
（わかりましたら是非教えてください。）

ファインチューニングモデル管理のご参考までに！
Matplotlibでf-stringとLaTexの表示

Matplotlibで、f-stringの値を下付き又は上付きにしたいときに、どうすればよいか？
調べたところ以下のサイトに回答がありました。
覚えとしてここに乗せておきます。

[How to display LaTeX f-strings in matplotlib](https://stackoverflow.com/questions/60150031/how-to-display-latex-f-strings-in-matplotlib)

結論として
変数を{{{}}} 3重かっこでくくればよいようです。


Latexで
下付きは、`a_{123}`
上付きは、`a^{123}`
と書きます。

f-stringでは、
変数　xyz = 123とすると
`f'{xyz}'`と書きます。

Matplotlibでこの二つを合わせると
`f'$a_{{{xyz}}}$'`
なおMatplotlibでLaTexを使うときには$$で囲う必要があります。

### いろいろと書いてみた例

```Python
import matplotlib.pyplot as plt
import numpy as np
plt.figure()
plt.plot([1,2,3], [3,4,5])
a = 123.56789
var = 123
bp=555
plt.text(1, 4,f'text$_{{{var}}}$')
plt.xlabel(f'Intensity$^{{1/{a:.0f}}}$')
# plt.xlabel(r"$\theta$")
# plt.ylabel(r"$\sin \, \theta, ln{x}$")
# r"を使わない場合\\を2つ入れる
plt.ylabel(f"$sin\\theta\\psi, ln{{x}}$")
plt.title(f"$R^2$, $R^{2}_{{{bp}}}$, $ln{{x}}$")

print(f'$intensity_{{{a:.2f}}}$')
print(f'text$_{{{a}}}$')
print(f'Intensity$^{{1/{a:.0f}}}$')
```
![fig0.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165987/1a65504a-2a57-dafd-acf7-f45223b80cb9.jpeg)
画面遷移ボタン作成

勉強中のため間違っていましたら訂正お願いします。

検証環境は以下
・Xcode 14.3.1


#**画面遷移ボタン作成方法**

```swift
NavigationStack{
            VStack{
                Text("画面")
            }
            .toolbar{
                ToolbarItem(placement: .navigationBarTrailing){
                    NavigationLink{
                        //画面遷移した時にとぶページ
                        SettingView()
                    }label:{
                        //ボタンの名前
                        Text("ボタン")
                    }
                }
```

*完成品がこちら！！*
![スクリーンショット 2023-09-01 21.27.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1238764/9d4749c1-0624-5c31-5783-0f74dc01b0e1.png)

『.toolber』は『NavigationStack』でのボタン配置を指示するモディファイアです。
『ToolbarItem』でボタンとボタンの配置を指示します。
『ToolbarItem』の引数であるplacementにボタンを配置する位置を指定します。
>placement=配置


＃**色々なボタン配置**
```swift
.toolber{
    ToolberItem(placement: ①配置するアイテム){
        ②配置するアイテム
    }
}
```

①配置するアイテには自分が配置したいボタンの場所を記入します。

**.bottomBer**...アイテムを下部のツールバーに配置
![スクリーンショット 2023-09-01 21.42.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1238764/8bfae7d8-3d59-d885-7155-6215082bd074.png)


**.navigationBarLeading**...アイテムを左端のツールバーに配置
![スクリーンショット 2023-09-01 21.45.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1238764/d1dfb435-bb33-202d-6357-49e2363e1884.png)

**.automatic**...周囲のコンテンツの状況からアイテムを自動的に配置
**.navigation**...ユーザーがコンテキスト間を移動できるナビゲーションアクションを配置
新卒が基本情報技術者試験に合格した方法


先日、基本情報技術者試験に合格してきたので、自分なりの勉強方法、雑感を書いてみようと思います。

勉強時間は空き時間に参考書読み(3ヶ月位?)とか問題演習を少々です。

#### 勉強方法
基本的にはキタミ式のテキスト読み & 過去問道場を数年分解く
でこと足りました。ざっと流し読みしやすい装丁と文体で良かったです

##### 1. 科目A対策(暗記、一部計算問題)
学習には定番のキタミ式を使用しました。

https://amzn.to/3Z502de

空き時間を利用して暗記系の知識を頭に入れつつ、章末問題を解いて計算問題の対策をしました。

個人的に注意すべきは計算問題かなと思います。
計算問題はなかなか初見だと厳しいかなという印象でした。

画像ファイルの画素数と容量の関係がどうとか、音声データのサンプリング数が～、みたいな計算問題は、過去問なりで対策しておくのが良さそう。初見だとめっちゃ難しそうに見えます
(実際に解き方追ってみると計算自体は小学校高学年くらいの難易度なんですが...)

個人的には教科書の章末問題をしっかり解けるようにしておくのが大切かなと思います。
そしたら過去問道場で数年分の問題を解いて、問題形式に慣れておけば科目Aの合格点は超えられました

##### 2. 科目B対策(アルゴリズムがメイン)

多少PythonとC#を触ったことがあったため、特に対策をせずとも合格できました。
擬似言語は関数を型付きで変数を宣言して使用していく感じなので、C#などの静的型付け言語を触るのが一番手っ取り早いんじゃないかなと思います～。

おそらくpaizaのB問題くらい解ければ合格点は取れそう。
1次元、2次元の配列にどんなデータが入っているかを追えればなんとかなると思います

https://paiza.jp/




##### 雑感
情報系の大学出身ではないため、ITの基礎知識を補強するのに丁度いい試験でした。
技術書を読むのに前提となる知識はある程度身についた気がします。
次は応用情報も取ってみようかなと思います～。

何かしら手当が出ればいいのにな...出る会社羨ましい(小声)
C/C++言語コンパイラ　MinGW-w64のインストーラーが使えない件

#  Windows 11でC/C++言語の環境構築
WindowsでC言語をプログラミングしたいと考えたら，まず一番最初にすることはgccコンパイラとg++コンパイラを入れる事だと思います．
WindowsのC言語コンパイラの一つとしてMinGW-w64が挙げられます．
コンパイラのインストーラーは[公式サイト](https://www.mingw-w64.org/)に載っている以下のリンクからダウンロード出来ます．分かりにくいですが，下の方にスクロールすると```MinGW-W64-install.exe ```ファイルがあります．
https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/

ここから入手出来るインストーラーを使おうとすると上手く行きません．
このようにエラーが発生します．
![スクリーンショット 2023-09-01 205609.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531123/59bf2254-b6e1-0742-4919-c9e526103062.png)


インストーラーの設定はこんな感じです．他の設定も試してみましたが全て上のようなエラーが発生しました．
設定の仕方はこの記事を参照してみてください．
https://qiita.com/yut-nagase/items/9bb65481685f6b8002de
![スクリーンショット 2023-09-01 205135.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531123/9b5f89bc-7565-1f6b-6058-a0eefafd6b33.png)

調べて見たところ，何年もこのバグが直されていないようです．

## 解決策
先程のインストーラーをダウンロード出来るサイトに戻ります．
そこでインストーラーの下に直接MinGW-w64のパッケージをダウンロード出来るリンクがバージョン毎に用意されています．この時点での最新バージョンは```8.1.0```でした．
![スクリーンショット 2023-09-01 205135.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531123/2a94c2e7-2470-471c-de88-fd24ee713ec1.png)
ここで適当なものを選んでダウンロードします．
私の場合は```x86_64-posix-sjlj```を選択しました．
ダウンロードしたらファイルを解凍します．zipファイルではないので，7-Zipなどの解凍ソフトを使うと解凍出来ます．
解凍したらCドライブにある```Program Files(x86)```のフォルダに，解凍したフォルダ```mingw64```を移動します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531123/cbd1e41f-0fdb-cffb-c10e-b1b673e09b95.png)

そしたら移動させた```mingw64```フォルダを選択してファイルのパスをコピーします．
右クリックをすると```パスのコピー```を選択出来ると思います．

次に設定アプリを開き，システム ＞ バージョン情報 > システムの詳細設定を開きます．
これはスタートメニューで「システムの詳細設定の表示」を検索してEnterキーを押しても開けます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531123/9f1f3637-4a2c-8d2d-2d09-1e711fed8cbf.png)
次に「環境変数(N)」を選択して，自分のユーザー環境変数(U)の場所で```PATH```という変数を探します．
```PATH```を選択したら，下にある「編集」を選択します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531123/07177b88-939f-4c91-b197-9e816413a5f7.png)
次に「新規」を選択して，先程コピーしたファイルのパスをペースト(Ctrl + V)します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531123/81b87417-7248-1738-e6e6-65b20e1e8d13.png)
上の写真のようにペースト出来たら成功です．「OK」を押して終了です！


##  コンパイラが入っているか確認する．
ターミナル(PowerShellかコマンドプロンプトか)を開いて，```gcc -v```もしくは```g++ -v```と入力して以下のようになれば成功です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531123/5bf1a145-7b57-0c11-55f2-ffcc59450713.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531123/6f35ed25-9b94-a474-041c-003ae2eb04ae.png)

##  動作環境
OS: Windows 11 Home
CPU: AMD Ryzen 7 5800H
【解決】ビルドパス絶対合ってるのにNo suitable driver found forが発生して詰んだ

SQLServerへの接続で発生したけど、他のDBでも起こるらしい

# No suitable driver found for
ドライバーがないのでDBに接続できない。

ググってもChat GPTに聞いても「ビルドパスを見直せ」「jarが追加されているか確認しろ」「接続文字列は合っているか」としか聞かれない。

ちゃんとbuild.gradleは設定してるし、手動でjarも追加してみたし、ビルドパスの設定も見直したし、**なんならローカルでEclipse上で動かしたらちゃんと動く[^1]のにリモートサーバーにデプロイした時だけ発生する**から接続文字列も絶対バッチリあってるんですけど？？？

# 対処 application.propertiesにドライバ名を設定する

```diff
spring.datasource.url=jdbc:sqlserver://localhost:1433;databaseName=testdb
spring.datasource.username=sa
spring.datasource.password=sqladmin
+ spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
```

# または
driverを初期化する時にClassNameを追加するのでも動いた


# 参考

https://stackoverflow.com/questions/52019724/why-we-do-not-mentioned-driver-name-in-application-properties-in-spring-boot-whe

https://amateur-engineer.com/postgreslq-class-forname/



[^1]:両方ダメな場合もあるっぽい。なんでローカルで動いたのかは不明（参考リンク1つめに答えがある気がする）。
未経験のプログラミング言語でも安心！ChatGPT4の活用法

どうもこんにちは、たくびー(@takubii)です。

未経験のプログラミング言語で仕事をふられた場合に対応するための個人的なベストプラクティスを紹介します。
最近、業務でこれまで全く経験がなかった分野を担当することになりました。
一体どこから手をつければいいのか分からなかったのですが、幸いなことに強力な味方であるChatGPT4先生がいたのでどのように進めたかを共有したいと思います。

## ChatGPTにコードの概要を説明させる
まず、修正したいコードをChatGPTに教えて、どのようなコードなのか概要を説明させてみます。
そうすると、各部分でどのような処理を行なっているのか丁寧に解説してくれます。
大抵の場合は番号も振ってくれるので、さらに詳しく知りたいときは番号を指定したり、関数を指定して深掘りしていきます。

## どの関数が言語特有か理解する
このようにまずは今書いてある言語でどの関数が言語特有であるのかを探すことが重要です。
自作関数の場合はコード内に書いてあるのでそちらを確認すれば問題ないですが、言語特有の関数はドキュメントを見る必要があるのでそこの切り分けができます。
ある程度書いてあるファイルや関数の内容が分かったら次のステップに進みます。

## ChatGPTに修正を指示する
次に、ChatGPTに対して修正したい箇所について指示を出してみます。
最初の指示は曖昧な指示で大丈夫です。
ある程度理解ができているとはいえ、未経験の言語で具体的な指示をするとかえって難解な答えが返ってきます。
最初は結果としてどうなって欲しいかを問いかけます。

この時点でも大体80点くらいの回答が返ってきます。
この回答を元に指示を具体化していきます。

## 実装と確認を繰り返す
その後は実装と確認の繰り返しです。
ただし、ChatGPTは2021年までの情報しか持っていないので、最新の情報は公式ドキュメントを参考にすることをお勧めします。
ChatGPTであたりをつけて公式ドキュメントを見るということを繰り返してください。

## 終わりに
以上のような手順を行えば、未経験の言語で実装を依頼されてもなんとか形になるものが出来上がると思います。
最終的にはPull Requestなどで他人のフィードバックを得て、さらに改善していきましょう。
ChatGPTのおかげで知らない言語も怖くないです。
頑張って対応していきましょう。

それでは今回はこのあたりで締めたいと思います。
ここまで読んでいただきありがとうございます。
また機会があればお会いしましょう。
田舎の自社開発企業に勤めて半年に突入した話。（初めてのQiita）

# はじめに
自己紹介を少し。田舎生まれ、田舎育ちの高卒21歳です。
大学に行くお金がなかったため、職業訓練校で情報処理について学び、今年4月に地元の自社開発企業に就職。現在、入社後６ヶ月目に突入。
都会の方達には見えない、リアルな田舎IT企業についてお話ししようと思います。
# 給料ってこんなもんなんだな…
世の中の辛さを、認識できていませんでした。
締日の関係もありますが、初任給は、なんと`10万円`でした。手取りは`9.5万円`です。
初月に、健康保険、厚生年金がなくてよかったです。
給料ってこんなもんなのかー。と悩み続け、気付けば、もう半年に差し掛かっていました…
５ヶ月目での現在の給料はというと…
# 残業無しで、手取り○○.○万円
他の会社について詳しくないので、知りませんが、私の会社では、チームによって残業時間が大幅に違います。リリースを控えているなら分かりますが、そんなことがないチームで、毎月**40h**を超えているチームもあります。
毎月**10h**以下のチーム（私）もあるので、月平均を誤魔化すためにバランスを取っているんですかね…新人ということもあり、残業がない、言葉の通り残業**0h**の私の手取りですが、`13.5万円`です。そもそも基本給が、`16.5万`円程度です。社会常識もなかったので、税金の存在の大きさに驚きました。新人ですが、8月にはボーナスも貰えました。額面で`7万円`です。やったー。（棒）
時代はIT業界。という安易な考えで入社した自分の甘さと、世の中の辛さに心が折れそうです…
# 見込み年収
4 〜 12 月の9ヶ月間で、1年目の今年はいくらもらえるのか考えてみた結果…
10 + 16.5 * 8 で 142、、、不穏な気配が…そこに、ボーナス1.5ヶ月だとすると、夏ボーナスが7、冬ボーナスが14。**年収160万!?** ちょっと、いや、かなり精神的にくるものがあります…
手取りは……これ以上は、考えるのをやめます！！！！
# これからどうするのか
今回、Qiitaへの投稿を始めることで、アウトプットによる自身のスキルアップと、履歴書に書けることが整理できるかなと。現在の会社には2年はいるつもりです。お金はありませんが、時間がたくさんあるので、転職活動に向けた準備をゆっくりしていければいいなと思います。
その他にも、続けていれば、エンジニア目線で何かしらのフィードバックがもらえるかもしれない。可能性は低いですが、誰かの役に立つかもしれない。田舎暮らしを夢見て、田舎のIT企業事情に興味がある人など…
これからは、転職活動の日記や、仕事で学んだこと、自宅学習したことについて毎週1つ投稿しようと思います。
# 終わりに
世の中色々と大変なことばかりですが、屈することなく、頑張って生きたいですね。
私を雇ってくれた会社に感謝。世の中のみんなの人生に幸あれ。

```:いつものやつで遊んでみた
いつもお世話になっているこれですよ。使う日が来るとは。これだけでも感慨深いですね。
                                                        Qiitaありがとう。
【AWS ANS-C01】ゲートウェイ、インターフェイス、エンドポイント、などなど、わからないのでまとめた

# 0. ANS-C01 むずかしすぎる
こんにちは、yuzu_juiceです🥂

ANS-C01を勉強しているのですが、すごくむずかしいです。
特に難しいのが、ゲートウェイ、インターフェイス、エンドポイント、プライベート、パブリックなど似た用語がたくさんできてて、こんがらがってしまうところです。
本記事では、前述した用語を整理したいのでまとめてみます。

※本記事は、2023年9月1日時点の情報になります。最新の情報はAWSの公式ドキュメントを参照ください！また、私はプロではないので記事に誤りがある可能性があります！記事の内容については自己責任で活用をおねがいします🙏

## 0.1. この記事に書いてあるもの
- Gateway（Internet, NAT, Egress-only, Virtual Private, Transit）
- VPCエンドポイント（インターフェイス型、ゲートウェイ型）
- 仮想インターフェイス（パブリック、プライベート）
- ※上記ですべてを網羅しているわけではありません。例えば、仮想インターフェイスにはトランジットもありますが、ここでは取り扱っていません。

# 1. Gateway
## 1.1. Internet Gateway(インターネットゲートウェイ)
**VPC⇔インターネット**
VPCとインターネットで接続するために使う。

## 1.2. NAT Gateway
**VPC⇒インターネット**
パブリックIPを持っていないインスタンスが、IPをNAT変換するために使う。

## 1.3. Egress-only Internet Gateway
**VPC⇒インターネット**
NAT GatewayはIPv4をNATするが、Egress-onlyはIPv6をNATする。

## 1.4. Virtual Private Gateway(仮想プライベートゲートウェイ)
**VPC⇔ユーザ拠点**
VPNやDirect Connectを利用して、ユーザ拠点とVPCをつなぐ際のVPC側の出入口。

## 1.5. Transit Gateway
**VPC⇔VPC⇔ユーザ拠点**
複数のVPCや、VPCとユーザ拠点を接続するときに使う。

---

# 2. VPCエンドポイント
VPCエンドポイントを利用することで、インターネットに出ることなくVPC内のリソースとAWSの各サービスが通信できるようになる。
VPCエンドポイントにはインターフェイス型とゲートウェイ型の2種類がある。

## 2.1. インターフェイス型
プライベートIPアドレスでAWSのサービスに接続できるようになる。
ENIがプライベートIPアドレスを持っていて、そこにアクセスする感じ。
お金がかかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3086592/4732a0f7-8c94-b00a-fe3f-c9f5c8cecd89.png)

## 2.2.ゲートウェイ型
パブリックIPアドレスでAWSのサービスに接続できるようになる。
VPCのルートテーブルが書き換えられることで、インターネットに出ないでサービスに接続できるようになる。
VPC内のリソースから、S3とDynamoDBに接続するときにだけ使える。
無料。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3086592/eeedf954-6de3-3724-2095-e19b486ceb29.png)

---

# 3. 仮想インターフェイス（VIF）
Direct Connect接続を開始するために必要。

## 3.1. パブリック仮想インターフェイス
ユーザ拠点とAWSが、パブリックIPアドレスでつながります。VPC外のサービスを専用線経由で使いたいときに使う。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3086592/681b93aa-cf23-e088-16c8-4c1c5f3c8843.png)

パブリック仮想インターフェイス単体では、VPCとの接続はできません。しかし、VPNを利用すると接続が可能になる。
また、Direct Connectでの通信は暗号化されません。こちらも、VPNを利用することで暗号化することができる。
Amazon Site-to-Site VPNサービスを利用することで、IPsec VPNを張ることができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3086592/f7491a0d-3bb3-e4cd-b105-0c6b2e4ecee4.png)

## 3.2. プライベート仮想インターフェイス
ユーザ拠点とAWSが、プライベートIPアドレスでつながる。VPC内のサービスを専用線経由で使いたいときに使う。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3086592/05368093-1cec-d7ad-55bf-4f18d2779fb7.png)

---

# 4. まとめ
めちゃくちゃ種類が多いのかなと思っていましたが、あらためて整理してみるとそうでもないかも？
この記事を書いたおかげで少し理解が深まりました。引き続き、ANS-C01の勉強を頑張っていきます。


※追記：試験受けましたが、707点で落ちました；；
　　　　この試験むずかしすぎる！またリベンジします💪💪
gem deviseにてログイン後の遷移先をログイン前にいた画面にする【rails】

# 経緯
rails のgem devise使用時にログイン後の遷移先をどこにするみたいな記事はよく見られます。
**指定したpathにリダイレクトする**という記事はよく見るのですが、
**ログイン前のページを保持してログイン後に戻ってくる。** って言うのは見つけられなかったので書いてみました。（多分検索力不足or需要がない）


爆速で書いたので、綺麗なコードではないかもしれません。悪しからず。
あくまで備忘録です（保険かけとく）
# 実装
めんどくさくて全てApplicationControllerぶち込んでいます。
```ruby:ApplicationController 
class ApplicationController < ActionController::Base
  before_action :store_user_location!, if: :storable_location?

  private

  def storable_location?
    request.get? && !devise_controller? && !request.xhr? # 必要に応じて条件を調整してください。
  end

  def store_user_location!
    session[:user_return_to] = request.fullpath
  end

  def after_sign_in_path_for(resource)
      stored_location = session[:user_return_to]
      session[:user_return_to] = nil # リダイレクト後はセッションから削除
      stored_location || root_path # リダイレクト先がない場合はデフォルトのパスを使用
  end
end

```

恐らくこれでいけるかと思います。

ではお疲れ様でした。
[個人開発]賞金が貰えるLINEチャット｜ワードハンターをリリースしました！！[Python✖️LINEbot]

2023年6/24(土)に、「チームで挑戦！ ChatGPTサービス開発ハッカソン」というエンジニアTypeさん主催のハッカソンに出場し、エンジニアType賞を受賞したワードハンターをリリースしました！！

以下がハッカソンの概要と受賞サービスの紹介になります！
ハッカソンの記事：

https://type.jp/et/feature/23174/

友達追加お願い致します！！

https://liff.line.me/1645278921-kWRPP32q/?accountId=961zpbwz

<h1> 目次</h1>
<p>1.ハッカソンの概要</p>
<p>2.本サービスの概要</p>
<p>3.最後に</p>

<h2>1.ハッカソンの概要</h2>
<p>私は2名のインターン生チームとして参加することになったのですが、審査員はメディアアーティストの落合陽一さん、Rubyの生みの親であるまつもとゆきひろさん、AtCoderの代表取締役の高橋直大さん、Yazawa Ventures CEOの矢澤麻里子さんの豪華4人でした！</p>
<p>
今回のハッカソンのテーマは「ChatGPT APIを用いたサービスの開発」ということで、(1)イノベーション性, (2)事業としての成長可能性, (3)完成度, の以上3つの評価基準で入賞チームを決めるものとなっていました。
</p>


<h2>2.本サービスの概要</h2>
<p>
私たちは、“賞金が貰えるLINEチャット”「ワードハンター」を開発しました。このサービスは、毎日ある豆知識に関する「フレーズ」を提供して、ユーザーがAIにその「フレーズ」を言わせることができたらチャレンジ成功となるもので、成功すればポイントを獲得することができます。月間で多くのチャレンジに成功された方には、さらに賞金を獲得するチャンスが待っています！チャレンジに成功すると、そのフレーズに関連した豆知識を共有するというものです。
</p>

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445338/0d9d6b58-9014-fbb3-0e80-a4fd6d9fc4e5.png)

![チャット数修正版.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445338/e145fe57-df86-cbd7-b7c9-ce043accd3bd.png)

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445338/74c3f380-3ae8-93f7-d2f3-372027bb3aaa.png)

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445338/0f574c6e-d8cf-340b-6758-327334b99051.png)


<p>
以下は公式HPになります！是非ご覧ください！
</p>

https://shoma0321.github.io/word_hunter_hp/




<p>
そして本日9/1よりリリース記念として公式Twitter上の固定ツイートのいいね、リツイート、フォローをして頂くとチャット制限を無限にリセットする秘密のパスワードをDMに教えています！！是非ゲットしてください！また初月の友達追加数によって賞金総額がUPするキャンペーンも実施中です！ぜひ友達追加して遊んでみてください！
</p>

<p>Twitterはこちら</p>

https://twitter.com/Wordhunter0624

![S__13950978.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3445338/0b2557a0-fa97-5b0e-41fc-f27cc947c413.jpeg)


<h2>3.最後に</h2>
<p>
このワードハンターは私自身初めて正式にリリースしたサービスです。今後どのような運用になっていくか分かりませんが、たくさんのユーザーに使ってもらえるようなサービスになっていけるように日々試行錯誤して頑張っていきたいと思います。この記事を読んでいただいた皆さんも是非友達追加をして遊んでみてください！！
</p>

友達追加お願い致します！！

https://liff.line.me/1645278921-kWRPP32q/?accountId=961zpbwz
【Swift】親Viewから子Viewに自作クラスのインスタンスを渡す方法

## はじめに
備忘録
View間での「自作クラスのメンバ変数」の受け渡しでつまずいたので書き残します。
自作クラスのインスタンスごと子Viewに渡すことができます。
どなたかのお役に立てれば幸いです。

## 解決方法
クラスの定義は以下のようになっています。
`ObservableObject`として定義することで値の受け渡しができるようにしています。
```swift
class SampleClass: ObservableObject {
    @Published var str = "hoge"
            :  // 他の処理
}
```

Viewの定義は以下です。
まず親Viewでクラスのインスタンスを`@ObservedObject`として作成し、`SubView`の引数としてインスタンスを渡します。
子Viewでも`@ObservedObject`として渡された変数を定義することでインスタンスを受け取ります。
```swift
struct ContentView: View {
    @ObservedObject var sampleClass = SampleClass()
    @State private var isPressed: Bool = false

    var body: some View {
        if isPressed {
            SubView(sampleClass: sampleClass)
        } else {
            Button {
                isPressed.toggle()
            } label: {
                Text("button")
            }
        }
    }
}

struct SubView: View {
    @ObservedObject var sampleClass: SampleClass
    
    var body: some View {
        Text(sampleClass.str)
    }
}
```

:::note
この方法では、インスタンスを初期化することなく複数のViewで共有できます。
そのため、例えばメンバ変数に更新があった時などに、最新の値を子Viewに反映させることができます。
:::
【Xcode】DeviceActivityMonitorExtensionが機能しない時の対処法

XcodeでDeviceActivityMonitorExtensionが機能しない時の対処法。


・`AuthorizationCenter.shared.requestAuthorization(for: .individual)`でファミリーコントロールを認証
・`ファミリーコントロール機能`を拡張機能のターゲットに追加
・アップルドキュメント通りに`startMonitoring`を記述

上記のことを行なっているにもかかわらず機能せず、悪戦苦闘したので残しておきます。


## 試したこと

・`AuthorizationCenter.shared.requestAuthorization(for: .individual)`が機能しているか確認
・Xcode再起動
・`Clean Build Folder`
・`DeviceActivityMonitorExtension`の再生成
・`Target Membership`にアプリ拡張機能にチェックがしてあるか確認

これらの施策を行うも変わらず。

## 解決策
アプリの`TARGET`の`Build Phases`の`Embed Foundation Extensions`の`Copy only when installing`のチェックを外すことで解決しました。
![スクリーンショット 2023-09-01 午後6.58.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3536354/17bfb449-521b-9e83-4b84-001e28f40b94.png)

以前、ビルドエラーが発生した際にチェックをしてしまっていたみたいです、、
Istio IngressGatewayが「X-Forwarded-Proto:https」を「http」に書き換えてしまう対策

# はまった事象
「Client(https) -> ALB(https終端) -> IngressGateway(http) -> WebPod(http)」の構成で、SpringBootで作ったWebApplicationでリダイレクトをすると、Locationが「http://example.com:443/hoge」 のようになってしまう事象にはまった。

ALBは、XFFヘッダを付加する設定（XFF Append Mode）になっており以下のヘッダが付加されている。
- X-Forwarded-For
- X-Forwarded-Port
- X-Forwarded-Proto

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/x-forwarded-headers.html

このヘッダが適切に設定されていれば、リダイレクトLocationを正しく組み立てられるはず。


# 調査
調べてみると、上記のようなALBでSSL終端するような構成の時、Istio IngressGatewayが「X-Forwarded-Proto」をhttps -> httpに書き換えてしまうらしい。

https://cloud.google.com/knowledge/kb/x-forwarded-proto-header-is-rewritten-from-https-to-http-on-an-istio-ingress-gateway-000004842

ということで、ドキュメントに従って設定を入れてみる。

# 対応策

対応策は２つ。

- EnvoyFilterを使う
- Istio Operatorの設定を変更する

弊社の基盤では、Istio 1.15系。
案2の設定オプションが1.15系対応していたので、こちらを採用することにした。

```
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  meshConfig:
    defaultConfig:
      gatewayTopology:
        numTrustedProxies: 2 # Change as needed.
```

実際には、複数のIngressGatewayのうち特定のIngressGatwayにのみ設定を入れたいので、基盤メンバーとも相談して「meshConfig」ではなく「podAnnotations: proxy.istio.io/config」を書いて設定を注入するようにした。

```
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
  components:
    ingressGateways:
    - name: web-app-istio-ingressgateway
      ~ 中略
      k8s:
        ~ 中略
        podAnnotations:
          proxy.istio.io/config: '{ "gatewayTopology": {"numTrustedProxies": 2} }'
        ~ 中略
```

# 結果
Istio IngressGatewayが「X-Forwarded-Proto」をhttps -> httpに書き変えなくなり、ちゃんと期待通りにリダイレクトが動くようになった。
【プラクティス紹介】1分でさらっと分かる「トラックナンバー」

## プラクティス名（別名）
トラックナンバー　（トラック係数、バス係数、ハネムーンナンバー）

## プラクティスの目的・狙い
* 属人化領域の可視化（リスク低減）

## どんな時に使うか
* チームの弱点（ボトルネックや手薄な箇所）を知りたい時
* メンバー変更/離脱に伴いどこを補強する必要があるかを知りたい時

## 実施手順
1. チームにとって必須のスキルや作業をリストアップする
1. それを1人でできる人数をカウントして、書き入れる（この数字をトラックナンバーと呼ぶ）
1. トラックナンバー＝1の領域は高リスクのため、何らかの属人化解消策を検討する

トラックナンバーという言葉は、仮にチームメンバーのうち何人がトラックに轢かれてしまうと開発継続ができなくなるか、というのが由来。不吉なのでハネムーンナンバー（＝長期離脱者）という呼び方もある。

## アレンジ例
* チームで星取表（スキルマップ）を作成している場合は最下行に「1人でできる人数」を追記する

## アンチパターン
* 「そんなにすぐに教えられるものじゃありません」　（→だからこそ、です）
* 「私が継続してやるから大丈夫です」　（→そのあなたがいなくなったら？という話です）

## 参考情報
アレンジ例に記載した星取表にトラックナンバーを併記するというやり方はこの書籍で知りました。他にもトラックナンバーの取り扱いについて詳しい解説が載っています。

https://www.shoeisha.co.jp/book/detail/9784798176826

## こぼれ話（私的コメント）
そもそもスクラムチームにおいてはPOとSMは単一障害点です。これはスクラムの構造上どうしようもありません。SMはチームのことを熟知していないと務まらないのですぐに替えが効く存在ではありませんが、幸い開発作業を直接実施するわけではないので、まだ何とかなるかもしれません。
問題はPOです。マルチチームスクラムでPOがチーム化（複数のエリアプロダクトオーナーに分割）している場合でも影響は免れないでしょう。スクラムの原則には反しますが、普段からPPO（プロキシプロダクトオーナー：POを補佐し作業の一部を代行する人）を立てておけば、少しマシかもしれません。
DEVがPOのプロダクトビジョンを真に理解し、あのPOだったらこう判断しただろう、と思考をトレースできるほど意思疎通が図れている状態であれば、あるいは・・・。
そもそも交通事故に遭わない方法を考えた方がいいのかもしれません。

　[アジャイルプラクティス一覧へ戻る](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)
CodeIgniter4.4.0にて、DBの数値型が数値で取得できるようになったぞ

# 数値型が文字列型になっちゃう問題

Codeigniterを使っていてたまに問題になるのが、**DBの数値型が文字列型として取得される** ということ。
これは MySQL の `MYSQLI_OPT_INT_AND_FLOAT_NATIVE` が `False` になっているせいだが、レンサバなどではこの値をいじれなかったりするのでカスタマイズしたり、エンティティを利用しなければならなかった。

DBから取得した値を比較しようとして 

```php
if($table["field"] === 1) {
    //　ここ通らないよ
}
```

となってしまうため、止む無く `==` を使っているケースもある。

## Codeigniter 4.4.0 が来た！（8月25日）

https://codeigniter4.github.io/userguide/changelogs/v4.4.0.html

地味にBreaking Changeがいっぱいあって戸惑うが、対象の関数を使っていることは多くない（私の利用ケースでは何もなかった）ので、移行に躓くことはあまりないと思われる。
ちなみにDeprecationsも結構ある

この中にひっそりと書いてあるのが Enhancements → Database の `numberNative` である。

## app/Config/Database.phpにnumberNativeが追加されている

https://codeigniter4.github.io/userguide/database/configuration.html#database-config-explanation-of-values

つまりこれが、`MYSQLI_OPT_INT_AND_FLOAT_NATIVE` の有効無効フラグということ。
なお、`.env`には記載がない。

```php
public array $default = [
    'DSN'          => '',
    'hostname'     => 'localhost',
    'username'     => '',
    'password'     => '',
    'database'     => '',
    'DBDriver'     => 'MySQLi',
    'DBPrefix'     => '',
    'pConnect'     => false,
    'DBDebug'      => true,
    'charset'      => 'utf8',
    'DBCollat'     => 'utf8_general_ci',
    'swapPre'      => '',
    'encrypt'      => false,
    'compress'     => false,
    'strictOn'     => false,
    'failover'     => [],
    'port'         => 3306,
    'numberNative' => false,  // ← ココ
];
```

## 大分助かる（新規開発なら）

**でも、falseが前提で作っちゃってるシステムを移行するのしんどいんだわ**

やった方がいいのはわかるんだけど、最初の例でいうと

```php
if($table["field"] === "1") {
    //　文字列型で比較しちゃってる
}
```

こうやってしまっているので、これらを全部探して書き換えるのが・・・むーりー

**つぎからがんばる**

----

全然関係ないけど、`charset`と`DBCollat`のデフォルトを `utf8mb4` にしてくれないかな・・・
たまに忘れて化けることがあるんだよねぇ・・・
PassKeyについて調べてみた

## 概要

パスワードレス認証で知られる
PassKeyについて調べてみました。

パスワードマネージャーとして有名な「１Password」も、
PassKeyの生成や保存を可能にするアップデートを行なっている様です。

## 主要なもの

### Hanko (OSS project)
https://github.com/teamhanko/hanko

https://www.youtube.com/watch?v=FXYZNQMHS7Q

### Corbado (German startup)
https://www.corbado.com/



### w3c web authentication specification
https://www.w3.org/TR/webauthn-2/


### swiftui (+ Web Authenticator)
https://github.com/rayriffy/juri

### android
https://android-developers-jp.googleblog.com/2023/03/bringing-together-sign-in-solutions-and-passkeys-android-new-credential-manager.html