OmniAICreator/Qiita-1.07M huggingface dataset:
Kubernetes Serviceに定義された権限

# はじめに
こちらの記事は下記Advent Calendar 2024で紹介しているIBM Cloud権限設定における `Kubernetes Service` になります。

https://qiita.com/katahiro/items/274bec5ad4a9e2604dcf

Kubernetes Serviceとありますが、IBM CloudではKubernetes、OpenShiftの両方に対しての権限設定になります。

# 共通権限は割愛
こちらの記事に記載しているように、プラットフォーム・アクセス、サービス・アクセスの権限でそれぞれどのようなものが共通して設定されているかを紹介させて頂きました。

https://qiita.com/katahiro/items/b5e367666fe984944d4b

こちらの記事では共通部分で出現する権限を除いた各サービス毎の権限設定を紹介します。

# Kubernetes Serviceで指定可能な権限のアクセス範囲
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/dead2fe9-4fc2-02f0-a4b7-116ce5abf03d.png)
- リソース・グループ
- Region
- Cluster
- Namespace

## リソース・グループの指定
これは指定されたリソース・グループに所属するKubernetes Serviceのみに対してアクセス権限を適用します。異なるリソース・グループのKubernetes Serviceに対しては別途権限を設定する必要があります。

## Regionの指定
これは `jp-tok` といったKubernetes Serviceの存在するRegionを指定することで、その指定されたRegionのみの権限を与えることが可能になります。

## Clusterの指定
これは、指定されたKubernetes Serviceのクラスターのみに対して権限を与えることが可能です。

## Namespaceの指定
これはクラスター内のNamespaceを指定して権限付与が可能です。Namespaceを分けてPod管理している場合かつ、その運用担当が異なる場合はこちらを指定して権限を厳密にする必要があります。

# Kubernetes Serviceに設定された権限
## プラットフォーム・アクセスの権限
※Admin : Administrator, KM : Key Manager, SCR : Service Configuration Reader
|権限|Viewer|Operator|Editor|Admin|KM|SCR|
|:---|:---:|:---:|:---:|:---:|:---:|:---:|
|containers-kubernetes.cluster.read|〇|〇|〇|〇|||
|containers-kubernetes.cluster.operate||〇||〇|||
|containers-kubernetes.cluster.update|||〇|〇|||
|containers-kubernetes.cluster.create||||〇|||

Kubernetes Serviceのサービス固有権限はreadやoperateといった各権限に集約されすぎてこれを見てもよくわからない部分があります。。。
### containers-kubernetes.cluster.read
クラスターの詳細をIBM Cloudコンソール上で確認可能ですが、インフラストラクチャーの変更、つまりWorker Poolの追加変更等を実施することができません。

### containers-kubernetes.cluster.operate
こちらはエンジニア向け、ということでWorker Nodeが追加可能で、Worker Nodeの再ロードといったアクションの実施が可能になります。ただ、資格情報の作成やクラスター全体に対する設定変更等は実施できません。

### containers-kubernetes.cluster.update
クラスターに対して他のサービスのバインドや、Ingressの操作、Cloud Logsといったサービスへのログ転送の設定といったことが可能になります。

### containers-kubernetes.cluster.create
クラスター作成や削除、クラスター全体に関わる設定、アドオンの追加といった操作が可能になります。

ただし、クラスターの作成には権限設定に注意が必要です。

下記リンク先に記載されていますが、Kubernetes Serviceでクラスターを作成する際には他のサービスの権限も必要になります。インフラストラクチャーのサービス上に構成されるので、その権限や他のコンテナ関連サービスの権限も必要と記載されているのでよくご確認ください。
https://cloud.ibm.com/docs/containers?topic=containers-iam-platform-access-roles&locale=ja#cluster-create-permissions



## サービス・アクセスの権限
|権限|Reader|Writer|Manager|
|:---|:---:|:---:|:---:|
|containers-kubernetes.kube.read|〇|||
|containers-kubernetes.kube.write||〇||
|ontainers-kubernetes.kube.manage|||〇|

権限の名称が役割と一緒なだけで何ができる権限か全然わからないですね。

こちらはKubernetesが提供しているRBAC(Role Based Access Control)と紐づく形になっています。

https://kubernetes.io/ja/docs/reference/access-authn-authz/rbac/#%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E5%90%91%E3%81%91role

上記を確認して頂き、下記のマッピングで対応しています。
`read` : ユーザー向けRoleの`View`に相当
`write` : ユーザー向けRoleの`Edit`に相当
`manage` : ユーザー向けRoleの`Cluster-Admin`に相当

もしこれだと与える権限が広い、実行可能なkubectlコマンドが多いといったものがあれば、下記ドキュメントを参考にカスタムRBACを作成して、それをユーザーやサービスIDに権限として割り当てることも可能なので、こちらも参考にして頂ければと思います。

https://cloud.ibm.com/docs/containers?topic=containers-understand-rbac#rbac

# さいごに
Kubernetes Serviceは権限は抽象化というかまとめられすぎていてよくわからないですよね。RBACの説明も細かく何ができるか全て説明しているわけではないので、与えた権限が相応しいものかはよく検討するようにして頂ければ幸いです。
進捗報告 (2024-12-12 17:04:18)

# 介護音声記録アプリの開発進捗報告

## 概要
本記事では、介護記録音声アプリの開発進捗を報告します。音声入力による記録の効率化を図るための実装や改善点について詳しく述べます。

## 現在の進捗
本日、介護音声記録アプリの開発が一旦完了しました。主な機能として、音声で文字起こししたデータをデータベースに保存する仕組みを構築しました。具体的には、オープンエアAPIを利用し、シート名とカラム名を指定してデータを保存しています。

### 問題点と改善策
以前の実装では、参照する表からのデータを表示することはできても、編集ができないという問題がありました。このため、以下の改善を行いました。

- **ABCトの廃止**: 直接お客様の日報にデータを入力する方式に変更しました。これにより、オープンエアAPIの呼び出し回数が1回に減り、音声入力から編集モードへの遷移が半分の時間で実行できるようになりました。

- **JSONパースの改善**: オープンAPIからのレスポンスに含まれるバックテーションを除去する処理を追加しました。これにより、パースの際のエラーを防ぎ、スムーズなデータ取得が可能になりました。

### 機能実装
アプリには以下の機能を実装しました：

- **食事の記録**: 朝食、昼食、夕食それぞれに対して主食と副菜の摂取量を数値で入力できるようにしました。食事のカテゴリと服薬のカテゴリーを設け、それぞれの編集モードでは自動選択される時間をプルダウン形式で表示し、ユーザーが編集可能です。

- **保存機能**: 最後に保存ボタンを押すことで、入力した内容が確認できる完了モードを展開します。

### 運用方法
- **日付形式のシート管理**: 日付ごとにデータが蓄積されるため、古いシートをドライブ直下の添付ファイルに保存し、不要なシートを削除するスクリプトを作成しました。このスクリプトを実行することで、データの整理が容易になります。

## 今後の予定
明日、現場で職員の皆さんにアプリを試していただく予定です。フィードバックを受けて、今後の改善点を検討します。また、個人情報のマスキングについても再考する必要があり、全国展開に向けた適切なマスキング方法を模索します。

## その他の展望
次のステップとして、アフィリエイトに関する調査を行い、自分自身で収益を得るためのボット作成やアカウント運用に挑戦したいと考えています。

以上が現在の進捗状況と今後の計画です。引き続き改善と機能追加に努めていきます。
MySQL → データ基盤連携のために MySQL のスキーマ情報をサクッと取得する

MySQL で「どのテーブルがどんな型のなんのカラムを持つのか」というスキーマ情報を取得したい場合のメモ。  
ユースケースとしては、MySQL のテーブルデータを BigQuery に連携する際に、MySQL テーブルのスキーマ情報を元に BigQuery テーブルの DDL を作成する時など。  
`mysqldump` や `SHOW CREATE TABLE` 文で DDL を取得することもできるが、スキーマ情報のみの取得で良い場合は、`INFORMATION_SCHEMA.COLUMNS` テーブルに対してクエリを実行するだけで取得することができる。  

https://dev.mysql.com/doc/refman/8.0/ja/information-schema-columns-table.html:title


## 検証用のテーブルを準備

以下のように `docker-compose.yml` を作成

```yaml
version: '3'
services:
  mysql:
    image: mysql
    tty: true
    container_name: mysql
    restart: always
    ports:
      - 3306:3306
    environment:
      - MYSQL_ROOT_PASSWORD=password
    volumes:
      - .:/work
    working_dir: /work
```

Docker 起動

```
$ docker-compose up -d
# 確認
$ docker ps
# mysql という名前のコンテナが立っていればOK
```

MySQL テーブル(`test_database.test_table`)を作成

```
CREATE DATABASE IF NOT EXISTS test_database;
CREATE TABLE IF NOT EXISTS  test_database.test_table (
  id INT,
  num tinyint,
  flag tinyint(1),
  short_msg varchar(10),
  long_msg varchar(255),
  dt datetime
);
```

DDL 実行

```
$ docker exec -it mysql bash
# コンテナ内部
$ mysql -uroot -p < ddl.sql
# パスワード求められるので docker-compose.yml に記載のパスワードを入力
```

## スキーマ情報を取得してみる

以下のように `INFORMATION_SCHEMA.COLUMNS` テーブルに対してクエリを実行することでスキーマ情報を取得することができる。

```
SELECT
  TABLE_NAME,
  COLUMN_NAME,
  DATA_TYPE,
  COLUMN_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'test_database'
AND TABLE_NAME = 'test_table';
```

実際の出力

```
mysql> SELECT
    ->   TABLE_NAME,
    ->   COLUMN_NAME,
    ->   DATA_TYPE,
    ->   COLUMN_TYPE
    -> FROM INFORMATION_SCHEMA.COLUMNS
    -> WHERE TABLE_SCHEMA = 'test_database'
    -> AND TABLE_NAME = 'test_table';
+------------+-------------+-----------+--------------+
| TABLE_NAME | COLUMN_NAME | DATA_TYPE | COLUMN_TYPE  |
+------------+-------------+-----------+--------------+
| test_table | id          | int       | int          |
| test_table | num         | tinyint   | tinyint      |
| test_table | flag        | tinyint   | tinyint(1)   |
| test_table | short_msg   | varchar   | varchar(10)  |
| test_table | long_msg    | varchar   | varchar(255) |
| test_table | dt          | datetime  | datetime     |
+------------+-------------+-----------+--------------+
6 rows in set (0.01 sec)
```

気を付けるべき点としては `DATA_TYPE` と `COLUMN_TYPE` の違い。  
`DATA_TYPE` の値は型の名前のみで他の情報は付与されないのに対して、COLUMN_TYPE の値は、型名と、精度や長さなどのその他の情報が含まれる。  
この違いが重要になってくるのは **`tinyint` と `tinyint(1)` の違い** で、MySQL の `tinyint(1)` 型は他の DB でいう `Boolean型` として振る舞う。  

参考にさせていただいた記事:

https://blog.s-giken.net/29.html


そのため `DATA_TYPE` だけでは `tinyint` と `tinyint(1)`(実質 `Boolean`) の違いを見分けることができないため、`COLUMN_TYPE` を見る必要がある。  
ただ、`DATA_TYPE` が `varchar` の場合に `COLUMN_TYPE` を確認するべきかと言うと必ずしもそうではなくて、例えば MySQL 上の型を BigQuery の型に変換したい場合は、「`DATA_TYPE` だけ確認して `varchar` なら全部 `STRING`」といったことになると思う。  
そのため、`DATA_TYPE` と `COLUMN_TYPE` は両方取得しておいて、必要に応じてどちらを確認するか選択するのが個人的にはオススメ。
【Linux】curlでグローバルIPを確認　（まとめ）

# ifconfig.io ifconfig.me

```shell-session
$ curl ifconfig.io
92.203.52.140
$ curl ifconfig.me
92.203.52.140
IPv4 固定
$ curl ifconfig.io -4
92.203.52.140
$ curl ifconfig.me -4
92.203.52.140

$ curl ifconfig.io/all.json
{
 "country_code": "JP",
 "encoding": "gzip",
 "forwarded": "92.203.52.140",
 "ifconfig_hostname": "ifconfig.io",
 "ip": "92.203.52.140",
 "lang": "",
 "method": "GET",
 "mime": "*/*",
 "port": 2538,
 "referer": "",
 "ua": "curl/7.64.1"
}
```

# ipinfo.io

```shell-session
$ curl ipinfo.io
{
 "ip": "92.203.52.140",
 "hostname": "fp5ccb348c.fkol216.ap.nuro.jp",
 "city": "Tokyo",
 "region": "Tokyo",
 "country": "JP",
 "loc": "35.6910,139.7679",
 "org": "AS2527 Sony Network Communications Inc.",
 "postal": "101-0047",
 "timezone": "Asia/Tokyo",
 "readme": "https://ipinfo.io/missingauth"
}
```

# inet-ip.info

```shell-session
$ curl inet-ip.info
92.203.52.140

$ curl inet-ip.info/ip
92.203.52.140

$ curl inet-ip.info/json
{
 "IP": "92.203.52.140",
 "Hostname": "[fp5ccb348c.fkol216.ap.nuro.jp.]",
 "CountryCode": "DE",
 "CountryName": "Germany",
 "Accept": ["*/*"],
 "AcceptEncoding": null,
 "AcceptLanguage": null,
 "UserAgent": ["curl/7.64.1"],
 "Via": null,
 "XForwardedFor": ["92.203.52.140"],
 "XForwardedPort": null,
 "XForwardedProto": ["http"],
 "RequestURI": "/json"
}
```

# ip-api.com

```shell-session
$ curl ip-api.com
{
 "status" : "success",
 "continent" : "Asia",
 "continentCode": "AS",
 "country" : "Japan",
 "countryCode" : "JP",
 "region" : "40",
 "regionName" : "Fukuoka",
 "city" : "Fukuoka",
 "district" : "",
 "zip" : "819-0001",
 "lat" : 33.5895,
 "lon" : 130.3197,
 "timezone" : "Asia/Tokyo",
 "offset" : 32400,
 "currency" : "JPY",
 "isp" : "Sony Network Communications Inc",
 "org" : "Sony Network Communications Inc.",
 "as" : "AS2527 Sony Network Communications Inc.",
 "asname" : "SO-NET",
 "mobile" : false,
 "proxy" : false,
 "hosting" : false,
 "query" : "92.203.52.140"
}
```

# httpbin.org

```shell-session
$ curl httpbin.org/ip
{
 "origin": "92.203.52.140"
}
```

# 余談
digコマンドの場合

```shell-session
$ dig o-o.myaddr.l.google.com @ns1.google.com txt +short
"92.203.52.140"

$ dig myip.opendns.com @resolver1.opendns.com +short
92.203.52.140
```
Gitでクローンができない問題と解決までの手順

間違っているところもあると思いますが、現時点での理解。
## そもそも
### クローンとフォークの違い
フォーク：Github上でチームのリモートリポジトリを自分のリモートリポジトリにコピーすること
クローン：フォーク後にネット上のリモートから手元PCのローカルに持ってくる

フォークの後にクローン

ミス
リモート：間違えても影響なし
ローカル：自分が困る

## クローンできない
### 行ったこと
(正しい順序という訳ではなくGit大初心者の私が試したことです)

1.sourcetreeでGutに紐付けアカウント作成
認証タイプ：OAuth
プロトコル：SSH

2.アカウントのSSHキーからGitでSSHキーを作成
SSHキーが無いと読み取りしかできずプッシュができないらしい

3.Github上でチームのリモートリポジトリを自分のリモートリポジトリにフォーク

4.sourcetreeのブックマーク画面で「リモート」を選択。制作したアカウントはあるが、フォークしたリポジトリが無い

5.ターミナルでデスクトップに移動し、「git clone SSHキー」を実行するも、下記エラー
```
ERROR: Repository not found.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```
「リポジトリが無い。リモートリポジトリを読み込めない。作ってからクローンして。」
と言ってきた

1.ここで忘れたので、一応sourcetree内に空のリポジトリを置く
6.Gitユーザー名とパスワードを入力して「git clone HTTPSキー」を実行するも、下記エラー
```
remote: Support for password authentication was removed on August xx, 2021.
remote: Please see https://docs.github.com/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'HTTPSキー'
```
「パスワードは消されてる。この[リンク](https://docs.github.com/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls)見てね。」とのこと

##  リンク内まとめ
- 開発時のプッシュ対象
リモートリポジトリのHTTPS URLかSSH URLに対してプッシュする
URLは名前(origin等)がつく

- SSH(Secure Shell)とは
ネットワークを介して別端末と通信するためのプロトコル。
Shell(Macではターミナル)：コンピューターへの入力を受け付けるもの。カーネルと人間の仲介

- リモートURLとURLの名前を一致させる
```
git remote add URL名 <URL>
```

- リモートURLの変更
```
git remote set-url URL名 <URL>
```
- HTTPS URLでのクローン
ファイアウォールまたはプロキシの内側にいる場合でも機能する
Gitコマンド実行時、ユーザーIDとパスワードを入力
ここで気づきました。

:::note warn
パスワードはGitアカウントのパスワードではなく、作成した「personal access token」のこと
:::
Gitでpersonal access tokenを作り、実行。
デスクトップ上にクローンしたリポジトリを確認できました。

-SSH URLでのクローン
安全なプロトコルでクローンする。
sourcetreeにSSHキーペアを生成し、GitHubのアカウントに公開鍵を追加する(これはやった)
Gitコマンド実行時、ユーザーIDとパスワードを入力

:::note warn
ここでのパスワードとは、SSHキーのパスフレーズのこと
:::

## 最後に
クローンには認証が大事なことが分かった。大事であることがsourcetreeでもGitコマンドでもかなり分かりにくいが。
sourcetreeでクローンできない→Gitコマンドでもエラー
で困っていた訳だが、sourcetreeだとどこでおかしいのか分かりにくいが、コマンドだとエラー文で原因の特定に近づくと思ったので、必ずしも初心者だからといってGitクライアントを使えばよいという訳でもないと思ったりした。

はじめてGitを使うため分からなすぎたが、わからないことを潰していくように調べ続けたら治るし、調べる過程が学習なので逃げずに1つづつ行っていきたい。

Gitの公式ドキュメントには感謝しています。
入社して1ヶ月経ったので、入社エントリ書いてみた

# はじめに
株式会社CBcloud にてエンジニアをしている anakano です。
2024/11 月に入社して、一ヶ月経った頃にアドベントカレンダーの件をお聞きしてやることになりました。

## どんな人なのか
色々な会社を転々としてきて、最長が新卒時代の 3 年という変わった人だと思います笑
ここ数年はリーダークラスとして、チームの管理やPJの進捗管理などをしつつ、コードを実装する人になってました。

そんな大きな武器は「コミュニケーション力」と「周りを巻き込む力」だと定義してます。

## 転職を考えたきっかけ
自分の中でマネージメントをもっと極めたいし、もっとPJ単位ではなくチーム全体に効果を訴求できるような会社に行きたいと思うようになりました。
前職でも同様のポジションを目標にしていたのですが、色々な問題があったり支持していた人が退職されたりしたりと色々なイベントが重なっため転職を考えるようになりました。

## CBcloudに決めたきっかけ
自分は以下の３点に惹かれて入社を決めました。

1. これからの配送問題をITの力で解決しようと考える姿勢
1. まだまだ若い開発組織だが、実力のあるメンバーが揃っていること
1. 自分の今後のキャリアで伸ばすべき点と、会社の課題感が一致したこと

１、２だけ軽く説明します

### 1. これからの配送問題をITの力で解決しようと考える姿勢
社長自身が、配送問題をITの力で解決するという点に重きをおき、社員もその思想を達成するために動きができて位いるとすごく感じました。
入社する前にも社長や他の方からも熱意を感じてましたが、中にはいってみると本当にユーザーファーストを実現していることを感じます。
（毎日感じているので、別の考え方からのアプローチも入れつつ貢献できるように日々模索中です）

ユーザであるドライバーさんのことを考えてエンジニアも発言しているため、ワンチームでより良いものをユーザに届ける意識が高くかなりモチベーション高く開発できています。

### 2. まだまだ若い開発組織だが、実力のあるメンバーが揃っていること

あまり技術会議には出席しないメンバーが多いです。
ただSTIの設計がめちゃめちゃ綺麗に描けるメンバーや、沖縄でも技術イベントを立ち上げるメンバーもいてかなりユニークな現場になっています。
マネージャーや、リーダークラスの方になると技術的にもかなりすごい方ばかりで、人柄もめちゃめちゃいいため本当に尊敬できます。
（自分もPJへの考え方やメンバーとの接し方は、色々勉強させていただいてます）
個人的には全メンバーの能力をさらに伸ばせると、今後社外イベントにも出席するメンバーが出てくると信じてます笑

## 最後に
自分自身もこの会社にJOINして、次の目標に向けて頑張っている途中です。
ただすごく裁量を持って仕事ができ、開発チームのレベルアップに少しでも貢献できているように感じられています。
ぜひ興味を持った方はカジュアル面談でも良いので、来ていただけると嬉しいです！
今後仲間の輪を増やしていきたいので、ぜひお会いしましょう

採用サイト：https://recruit.cb-cloud.com/
【Goで学ぶコンピューターサイエンス】ハッシュテーブル

## ハッシュテーブル

データをキーと値のペアで管理し、高速なデータの格納・検索を可能にするデータ構造です。  
内部では **ハッシュ関数** を使用してキーを特定のインデックス（ハッシュ値）に変換し、そのインデックスを使ってデータを効率よく格納します。

### 特徴
- **時間計算量**
    - 平均的には、検索、挿入、削除の操作を $O(1)$ で行えます。（ただし、最悪 $O(n)$ になることもあります）
- **キーと値のペア**
    - データは「キー」を使ってアクセスします
- **ハッシュ関数**
    - キーをインデックスに変換するための関数で、ハッシュテーブルの効率性に大きく影響します。

## ハッシュテーブルの仕組み

- ハッシュ関数
    - キーを入力として受け取り、一定範囲の整数（ハッシュ値）を出力します

- バケット
    - ハッシュ値によってデータが格納される配列の各要素を指します
    - 配列のように直接インデックスにアクセスすることで、高速な検索が可能です

- 衝突  
    - 異なるキーが同じハッシュ値になる場合です
    - 衝突を解決する方法として以下の手法があります
         - チェイニング
             - バケットにリストを格納して複数の値を保持
         - オープンアドレス法
             - 空いている別のバケットを探して格納

## ハッシュテーブルの利点
- 高速なデータ操作
    - 配列と同様、インデックスで直接アクセスするため効率的
- 柔軟なキー管理
    - 数値や文字列など、さまざまなキーを使用可能
- 動的サイズ変更
    - ハッシュテーブルのサイズを動的に変更して効率性を維持できます

## ハッシュテーブルの欠点
- メモリ使用量
    - バケットの数を多く用意する必要があるため、メモリ消費が多くなる場合があります
- データ順序非保持
    - データはハッシュ値の順序で格納されるため、挿入順序を保持しません

## ハッシュテーブルのGoサンプルコード

```go
package main

import "fmt"

type KeyValuePair struct {
	key   string
	value string
}

type HashTable struct {
	size    int
	buckets [][]KeyValuePair
}

func NewHashTable(size int) *HashTable {
	return &HashTable{
		size:    size,
		buckets: make([][]KeyValuePair, size),
	}
}

func (ht *HashTable) Hash(key string) int {
	hash := 0
	for _, char := range key {
		hash += int(char)
	}
	return hash % ht.size
}

func (ht *HashTable) Insert(key, value string) {
	index := ht.Hash(key)
	ht.buckets[index] = append(ht.buckets[index], KeyValuePair{key: key, value: value})
}

func (ht *HashTable) Search(key string) (string, bool) {
	index := ht.Hash(key)
	for _, pair := range ht.buckets[index] {
		if pair.key == key {
			return pair.value, true
		}
	}
	return "", false
}

func (ht *HashTable) Delete(key string) {
	index := ht.Hash(key)
	for i, pair := range ht.buckets[index] {
		if pair.key == key {
			ht.buckets[index] = append(ht.buckets[index][:i], ht.buckets[index][i+1:]...)
			return
		}
	}
}

func main() {
	ht := NewHashTable(10)

	ht.Insert("apple", "red")
	ht.Insert("banana", "yellow")
	ht.Insert("grape", "purple")

	fmt.Printf("%+v\n", ht)

	value, found := ht.Search("apple")
	if found {
		fmt.Println("Found:", value)
	} else {
		fmt.Println("Not Found")
	}

	ht.Delete("banana")
	fmt.Printf("%+v\n", ht)

	value, found = ht.Search("banana")
	if found {
		fmt.Println("Found:", value)
	} else {
		fmt.Println("Not Found")
	}
}
```

```
&{size:10 buckets:[[{key:apple value:red}] [] [] [] [] [] [] [{key:grape value:purple}] [] [{key:banana value:yellow}]]}
Found: red
&{size:10 buckets:[[{key:apple value:red}] [] [] [] [] [] [] [{key:grape value:purple}] [] []]}
Not Found
```
【パフォーマンス】ab コマンドの使い方

abコマンドとは　Apache Bench　です。
Apache Bench　とは　WEBサーバの性能確認ツールです。

# 使い方
一般 -n -c -p -H がわかれば問題ないです。
- `-n` リクエスト数
- `-c` クライアント数
- `-p` ポストファイル
- `-H` ヘッダー

# GET

```bash
ab -c 10 -n 1000 http://localhost
```

同時10クライアントで1000リクエストをGETします。

# POST

```bash
ab -c 100 -n 10000 -p data.json -H ‘Content-Type:application/json’ http://localhost
```

同時100クライアント・10000リクエストでdata.jsonをPostします。
VSCodeを全力でかわいくする

# こんな感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79151/4f0bb1f4-fd14-9bd4-bfcd-6b99334021f5.png)

# 使った拡張機能

- BackGround
  - エディタの背景を設定できる。ブラウザで適当に「壁紙　かわいい」とかで検索するだけでよし。
- VSCode Pets
  - 右下にペットを表示できる。頭が疲れたときに横に広げてぼけーっと眺めるだけで多少気分転換になる。
- Fluffy Theme
  - さいかわテーマ. デフォルトの文字色がピンクなのだけ見辛い。

# おわり

おれの方がかわいいって人は教えて！
UnrialEngine5：プロトタイプへの道１

# 今回はプロトタイプ作成に向けてやっていきます
- [前回](https://qiita.com/akulsto/items/958b8106a7f1af010539)はUE5の雰囲気を知ってもらう形でしたが、今回からはプロトタイプ作成へ向けてうごきます
- 簡単なゲームを作成してみようと思います
- UE5のinstall及び初期設定は他の参考サイトをご覧ください

## プロトタイプ作成開始
- 新規でプロジェクトを作成
- 画面左下「コンテンツドロワー」Clickし、フォルダ階層の「コンテンツ」を選択
    - そこの階層で右クリックから「新規フォルダ作成(名前自由)」、そのフォルダの中に「BP_MovingBoard」でフォルダを作成します
    - 「BP_MovingBoard」をダブルクリック
- 次に続く
## ブループリントでは、配置するオブジェクトのサイズ、Materialなどの情報が変更可能
- こんな画面が出ると思われます
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310502/60bc9f05-3164-00e7-8e60-d5b3565bdbb0.png)
- この画面で操作します。左上「追加」よりキューブを追加しますトランスフォームでスケール変更で「2.0,2.0,0.2」とします(ぱっと見は厚みのある平たい床です)
- またこのcubeの名前をわかりやすいよう「MovingBoard」とします
- 次に作成したMovingBoardを使ってイベントを作ります
- 右クリックして・・・とあるように中央画面周辺で右クリックするとノードが出てきます
- timelineと検索欄へ入力して下スクロールで「Add time line」を選択する
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310502/09d3f87b-af06-5ff1-a1b4-c849f54f3451.png)
- このようにクリックしつつ引っ張ってくっつけます
- タイムラインノードを編集します（タイムラインノードをダブルクリック）

## タイムラインの編集
- 以下のような画面がでてきます
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310502/102625be-5b12-7d00-cc42-73eeb01f965b.png)
- 「トラック」から「フロートトラックを追加」し、「MovementRange」とします
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310502/d5fc1721-5e9b-96af-8e98-e0ad0b41ab18.png)
- [次回へつづく](https://qiita.com/akulsto/items/cb6e77082eba64961851)
imgタグとpictureタグの使い分け

画像表示の際、今まではCSSやJS等で切替を行ってましたが、
近年はHTMLのみで完結できるように進化してます。

大きく「imgタグ」と「pictureタグ」を使う方法があり、
ざっくりと下記のような「違う画像」or「解像度」によって使い分けると良さそうです。

<ul>
<li><b>「違う画像に切り替える」場合</b> : pictureタグ + sourceタグ</li>
<li><b>「解像度を切り替える」場合</b> : imgタグ + srcset属性</li>
</ul>

このあたり、毎回すぐに思い出せず調べてしまうので、備忘録かねて残します。
M5StackでMeshtasticを試す

# Meshtasticとは

[Meshtastic](https://meshtastic.org) はLoRaの無線を利用した分散型の通信です。LoRaWANなどではゲートウェイがありますが、Meshtasticではゲートウェイのないピアツーピアで通信を行います。

![Meshtastic](https://meshtastic.org/assets/images/lora-topology-2-c80684f1eafdf2a71fbaf26e494fb26d.webp)

# ノード

デバイスはスマートフォン経由等で設定を行うことができ、ノードがどのような役割として動作するかもそこで設定できるようになっています。

| デバイスロール | 概要 |
| --- | --- |
| CLIENT | アプリ接続またはスタンドアロンのメッセージング デバイス。 |
| CLIENT_MUTE | 他のデバイスからのパケットを転送しないデバイス。 |
| CLIENT_HIDDEN | ステルスまたは電力節約のために必要な場合にのみブロードキャストするデバイス。 |
| TRACKER | GPS 位置パケットを優先的にブロードキャストします。 |
| LOST_AND_FOUND | デバイスの回復を支援するために、位置情報をメッセージとして定期的にデフォルト チャネルにブロードキャストします。 |
| SENSOR | テレメトリ パケットを優先的にブロードキャストします。 |
| TAK | ATAK システム通信用に最適化されており、定期的なブロードキャストを削減します。 |
| TAK_TRACKER | 自動 TAK PLI ブロードキャストを有効にし、定期的なブロードキャストを削減します。 |
| REPEATER | 最小限のオーバーヘッドでメッセージを中継することにより、ネットワーク範囲を拡張するためのインフラストラクチャ ノード。ノード リストには表示されません。 | 
| ROUTER | メッセージを中継してネットワーク範囲を拡張するためのインフラストラクチャ ノード。ノード リストに表示されます。 |


# 対応デバイス

サイトを見ると多くのデバイスを対応しているようですが、国内で技適を取得しているデバイスがないようなので、以前使用したこちらの Grove-Wio-E5 を使ってみます。今回も M5Stack の Port A をシリアルポートとして使ってみます。

https://www.seeedstudio.com/Grove-LoRa-E5-STM32WLE5JC-p-4867.html


![withM5Stack](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F555397%2Fc7077382-7d3d-e803-25d6-a4914d33599e.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&w=1400&fit=max&s=f138c295d906b6c2ce86edf8d136e8a7)

# コード

コードは [こちら](https://github.com/fukuen/meshtastic-firmware) をご覧ください。

ソースコードをクローンし、Visual Studio Code の PlatformIO でディレクトリを開きます。

ビルド方法の詳細はこちら https://meshtastic.org/docs/development/firmware/build/

概要は、

ソースコードのクローン

```
git clone https://github.com/fukuen/meshtastic-firmware.git
cd meshtastic-firmware && git submodule update --init
```

コマンドパレットでプロジェクト環境を選択（env:m5stack-core-WioE5）

```
PlatformIO: Pick Project Environment
```

コマンドパレットからビルド

```
PlatformIO: Build
```

コマンドパレットからアップロード

```
PlatformIO: Upload
```


# 設定

ファームウェアを書き込んでデバイスを起動すると、設定待ちの状態で起動します。スマートフォンを使いBluetoothで接続します。接続したら最初にリージョンコード「JP」を設定します。

詳細はこちらの初期設定方法 https://meshtastic.org/docs/getting-started/initial-config/

# その他

その他詳細はこちらのMeshtasticサイトをご覧ください https://meshtastic.org/
3Dスキャナー購入前に知っておきたいポイント

3Dスキャナーは、デザイナー、製造業の専門家、クリエイターにとって欠かせないツールとなりつつあります。しかし、市場には多種多様な製品があり、その仕様やパラメーターに戸惑う方も多いのではないでしょうか。適切な製品を選ぶためには、スキャナーの重要な性能を理解することが必要です。この記事では、3Dスキャナーを選ぶ際に注目すべきポイントをわかりやすく解説します。  

---

### 1. **精度と解像度：モデルのディテールを決める要素**  
簡単に言えば、精度はスキャンされたモデルの誤差の小ささを示し、解像度はデバイスが細かいディテールをどれだけキャプチャできるかを表します。  
- 工業部品をスキャンする場合は、精度が0.05mm以上のスキャナーを選ぶのがおすすめです。  
![acb5739789367cbfa0a4a1b1c4f9bd3a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824290/f1ab8a87-3151-ab5d-42d6-ef87b10d1ac6.png)

- 創作活動や個人のDIYプロジェクトには、0.1mm程度の精度で十分な場合が多いです。  
![83b195905a6a08d0b2b0735693168d09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824290/7a25e1be-fa9d-a455-3d65-9348a0f581bc.png)

> **ワンポイント**：高精度のスキャナーは高価になりがちですが、複雑なプロジェクトには投資の価値があります！  

---

### 2. **スキャン方式：用途に合った技術を選ぶ**  
用途によって適切なスキャン方式を選びましょう：  
- **レーザースキャン**：複雑な表面を得意としますが、光沢や透明な素材には対応しづらい場合があります。  
![7d7f1cdb406930421ad9762cb435acdb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824290/2171a424-86aa-c634-072f-e9f454a498f5.png)

https://www.revopoint3d.com/products/3d-laser-scanner-metrox

https://www.revopoint3d.com/products/3d-laser-scanner-metrox

- **構造光スキャン**：スキャン速度が速く、静止した物体に適しており、環境光に影響を受けやすいのが特徴です。  
- **写真測量**：カメラとソフトウェアだけで利用可能。コストを抑えたい方に最適ですが、ディテールの再現力は限られます。  

> 様々な素材を扱う場合は、複数のスキャン方式に対応したデバイスを選ぶと便利です。  

---

### 3. **スキャン範囲と用途のニーズ**  
まず自分に問いかけてみましょう：主にどんな物体をスキャンしますか？  
![1c0fad1742115b8273ed9edd78b02875.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824290/f3a713e7-6a16-f0fc-ee3f-d533559c5a76.png)

- 小型アイテム（例：ジュエリー）：高精度な小範囲スキャナーを優先。  
- 大型物体（例：自動車や彫刻）：スキャン範囲が広いデバイスが必要。  
- 混合的な用途：モード切替が可能なハンドヘルドスキャナーが適しています。  

---

### 4. **素材対応力：見落としがちな重要ポイント**  
光沢のある表面や透明な素材は、多くのスキャナーが苦手とする分野です。これらを扱う場合、表面スプレーの使用を検討するか、素材対応力の高いデバイスを選びましょう。  

---

### 5. **ファイル形式と互換性：データ管理をスムーズに**  
ほとんどのスキャナーは、OBJ、STL、PLYなどの標準3Dファイル形式を出力します。購入前に、これらの形式が使用している3Dモデリングやプリンターソフトに対応しているか確認してください。  

> **効率化のポイント**：便利な専用ソフトウェア付きのスキャナーは、後処理を大幅に簡略化できます！  

---

### 6. **携帯性と使用感：スキャナーが日常にフィットするか**  
- **固定式スキャナー**：スタジオやラボに適しており、性能は安定しているものの、持ち運びには不向き。  
- **ハンドヘルドスキャナー**：軽量で持ち運びが簡単。現場での作業が多い方に最適です。  
また、操作性や学習のしやすさも日常的な使用体験を大きく左右します。  

---

### 結論  
3Dスキャナー選びに「万能なデバイス」は存在しません。用途や予算に応じた選択が重要です。工業レベルの精度を必要とする場合も、クリエイティブなプロジェクトをサポートする場合も、各パラメーターをしっかり確認すれば、より賢明な決断ができます。このガイドがあなたの購入計画に役立ち、3Dクリエイティブの旅が素晴らしいものとなることを願っています！
VLAN間ルーティングについて勉強してみた

# はじめに
前回勉強したVLANはL2層の機器で論理的にネットワークを分割する技術です。
VLAN毎にネットワークが区切られていますので、異なるVLANに所属するホスト同士で通信を行う際は、ルーティング機能をもったネットワーク機器(L3スイッチ、ルータ)が必要となります。
今回はVLAN間のルーティングについて勉強していきたいと思います。

# 1.VLAN間ルーティングの概要
VLAN間で通信を行うには、ルータやL3機器を使用して相互に接続する必要があります。
また、ルーティングはIPアドレスを基に通信を行いますので、VLANにネットワークアドレスを設定してあげる必要もあります。
(L2層はMACアドレスを基に、L3層はIPアドレスを基に通信)
VLAN間ルーティングを実現するには、ルータを使用する方法とL3スイッチを使用する方法の2つがあります。

# 2.ルーターを使用したVLAN間ルーティング
### [2-1]ルータとL2スイッチのアクセスポートを接続した場合
ルータのインターフェイスとL2スイッチのアクセスポートを接続する構成にした場合、VLANの数と同じ数だけルーターの物理インターフェイスが必要になってしまいます。

下の図では、ルータのFa0/0とVlan10のアクセスポート、ルータのFa0/1とVlan20のアクセスポートをそれぞれ接続しています。

また、各ネットワークのホストは、異なるネットワークのホストと通信を行うためにデフォルトゲートウェイを指定します。
デフォルトゲートウェイは、自身のネットワークを接続しているルータインターフェイスに割り当てられているIPアドレスとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950373/04f0864b-576d-e158-a618-f264bee305ce.png)
<br>

### [2-2]ルータとL2スイッチのトランクポートを接続した場合
ルータのインターフェイスとL2スイッチのトランクポートを接続する構成にした場合、ルータの一つの物理インターフェイスをVLANの数だけ分割し、仮想的な複数のインターフェイスを作成して各VLANで使用します。
そのため、必要なルーターの物理インターフェイスはVLANの数に関係なく1つだけです。
アクセスポートを使用した構成とは違って、スケーラブル(性能や機能の拡張性が高いこと)な構成と言えます。
ただ、一つの物理回線を複数のVLAN達で共有しているので、輻輳(アクセスが集中して処理しきれなくなること)が発生する可能性があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950373/e0fce0cf-cc77-3953-f2cb-bd55f335786f.png)

#### ・サブインターフェイスとは
一つの物理インターフェイスを論理的に分割した仮想的なインターフェイスのことです。
VLANの数だけサブインターフェイスを作成したら、それぞれのサブインターフェイスにVLAN IDとIPアドレス(このアドレスが対象VLANに所属するホストのデフォルトゲートウェイとなる)の設定を行います。

# 3.L3スイッチを使用したVLAN間ルーティング
### [3-1]L3スイッチを使用することのメリット
L3スイッチはスイッチング機能(VLAN分割)とルーティング機能(VLAN間ルーティング)の両方を有しているので、機器単体でVLAN間を相互接続することができます。
また、VLAN間の通信をより高速に行うことができます。(L3スイッチは価格が高い分性能もよく、高速処理が可能＋機器をまたがないのでデータ転送が高速)
<br>

### [3-2]L3スイッチを使用したVLAN間ルーティングについて
L3スイッチのスイッチポートに割り当てられているVLAN同士で通信を行うためには、各VLANがSVI(Switch Virtual Interface)という仮想的なインターフェイスを使用してL3スイッチの内部ルータと接続する必要があります。
SVIにIPアドレスを割り当てて有効化することによって、内部ルータは直接接続されているネットワーク(L3スイッチで作成した各VLAN)をルーティングテーブルに登録します。
このルーティングテーブルを基にルーティングを行うことで、L3スイッチ内部のVLAN間通信が可能になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950373/cb0d6664-d62f-afff-b612-cfda3e6cd2ce.png)
<br>

# おわり
Mysql データ量確認

メモ用
mysqlでコピペして動作

```
SELECT 
    table_schema, sum(data_length) /1024/1024 AS mb 
FROM 
    information_schema.tables  
GROUP BY 
    table_schema 
ORDER BY       
    sum(data_length+index_length) DESC;
```

---
https://qiita.com/ikenji/items/b868877492fee60d85ce
それぞれの例が含める

```rb
RSpec.configure do |rspec|
  # This config option will be enabled by default on RSpec 4,
  # but for reasons of backwards compatibility, you have to
  # set it on RSpec 3.
  #
  # It causes the host group and examples to inherit metadata
  # from the shared context.
  rspec.shared_context_metadata_behavior = :apply_to_host_groups
end

RSpec.shared_context "shared stuff", :shared_context => :metadata do
  before { @some_var = :some_value }
  def shared_method
    "it works"
  end
  let(:shared_let) { {'arbitrary' => 'object'} }
  subject do
    'this is the subject'
  end
end

RSpec.configure do |rspec|
  rspec.include_context "shared stuff", :include_shared => true
end

```

### 共有コンテキストを宣言し、それを個々の例のメタデータに含める。
>### Declare a shared context and include it with metadata of an individual example
>Given a file named “sharedcontextexample.rb” with:
```rb
require "./shared_stuff.rb"

RSpec.describe "group that does not include the shared context" do
  it "does not have access to shared methods normally" do
    expect(self).not_to respond_to(:shared_method)
  end

  it "has access to shared methods from examples with matching metadata", :include_shared => true do
    expect(shared_method).to eq("it works")
  end

  it "inherits metadata from the included context due to the matching metadata", :include_shared => true do |ex|
    expect(ex.metadata).to include(:shared_context => :metadata)
  end
end
```
>When I run rspec shared_context_example.rb
>
>Then the examples should all pass.


https://rspec.info/features/3-13/rspec-core/example-groups/shared-context/#:~:text=Declare%20a%20shared%20context%20and%20include%20it%20with%20metadata%20of,Then%20the%20examples%20should%20all%20pass

* respond_toとは？
* not_toとは？
* :include_shared => trueとすることで呼べるらしい

### :include_shared => falseにしてみた
```rb
it "inherits metadata from the included context due to the matching metadata", :include_shared => false do |ex|
    expect(ex.metadata).to include(:shared_context => :metadata)
  end
```

#### エラー
```
group that does not include the shared context inherits metadata from the included context due to the matching metadata
```
共有コンテキストを含まないグループは、メタデータが一致するため、含まれるコンテキストからメタデータを継承する。


```rb
RSpec.configure do |rspec|
  rspec.include_context "shared stuff", :include_shared => true
end
```
のおかげでメタデータによる含みができるからこの意味を知りたい

#### メタデータによって含めることができる、各々のexapleで含めることができる
>When implicitly including shared contexts via matching metadata, the normal way is to define matching metadata on an example group, in which case the context is included in the entire group. 

>However, you also have the option to include it in an individual example instead. RSpec treats every example as having a singleton example group (analogous to Ruby’s singleton classes) containing just the one example.

上のコードのメタデータを定義して、それぞれ呼び出すことができるのかな
ボタンをホバーした時に、ボタン内の文字の色を変化させる方法

railsで個人開発を行なっております。
その中で実装に躓いた時に知ることができた情報を、備忘録のような形で残せれば良いなと思い始めました。
# 達成したいこと
[実装要件]
ボタンをホバーした時、ボタンだけでなく、ボタンの中の文字の色も変化するようにしたいと思いました。

具体的には、以下のような挙動です。

初期状態
![スクリーンショット 2024-12-12 15.55.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959678/8c53116b-61bf-3f50-0b32-3406562fb998.png)
　　↓
　　↓
ホバーした状態
![スクリーンショット 2024-12-12 15.55.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959678/8b6b6cca-5749-683a-e5cc-9ba91d782c79.png)

# 今までの実装
今までの実装では、
```
<div class="a">
  <%= link_to "パス", class="btn btn-primary b" %>
</div>
```
のような形でrailsのコードを書き、
クラスaとクラスbにそれぞれCSSを当て、それぞれがホバーされた際、CSSが変化されるよう実装していました。

具体的には以下のような感じの実装です。

例: 今までの実装(.scssファイル)
```
.a{
 クラスaのもとの状態
}
.b{
　クラスbのもとの状態
}
.a:hover{
 クラスaをホバーした時の状態
}
.b:hover{
 クラスbをホバーした時の状態
}
```
ただ、このような場合だと、ボタンのふちをホバーしてもボタンの文字まで触れなければ、ボタンの文字色は変化しません。
そこで、これを解決できるよう実装を変更しました。

# 改善した実装
Qiitaで調べていたところ、別の記事で別の要素をホバーした時に、スタイリングを行うといった記事が出できましたのでこちらを参考にさせていただきました。[1]

例: 改善した実装(.scssファイル)
```
.a{
 クラスaのもとの状態
}
.b{
　クラスbのもとの状態
}
.a:hover{
 クラスaをホバーした時の状態
}
.a:hover .b{
 クラスbをホバーした時の状態
}
```
最後部分のみ実装を変化させました。
このようにコードを変化させるでボタンにホバーしたタイミングでボタン内の文字の色(情報)を変更することができます。




# 参考文献
[1]https://qiita.com/Jinta/items/01cd35ba35c7e00aef47
新チームの管理対応で発生した問題点とその解決策について


## はじめに
こんにちは！	
私はゲーム関連のQA業務を行っているテスターです。
最近はテスト実行以外に、管理分野の業務も行うようになりました。

今年は管理業務の一環として、新しく出来た検証スタジオのチームリーダー対応を行ったので、そこで得た知見や反省点などを振り返っていけたらと思います。
## チームリーダー対応の背景説明

去年の10月に私が担当していたタイトルのサービスが終了し、別タイトルへ移動することになりました。
その後、2か月で新スタジオの検証チームが発足され、私が新チームの管理対応を行うことになりました。
行った管理対応の詳細は下記となります。

### 対応の詳細
* 検証業務のリード対応、進捗管理
* 新チームの生産性/稼働率の管理、業務課題への対応
* 対プロダクト / 別スタジオの連携補助
* 隔週の面談
<br>
当時の私はチーム管理の経験がなく、上記の対応をがむしゃらに進めていましたが、困ることが多々ありました。

その問題点について、下記で説明していきます。


## チーム管理を行う上で発生した問題
新チームを導入するタイトルは運営が長く、検証対応を行っていたスタジオも固定されていました。
このようなタイトルで、新チームを導入するにあたり、以下の問題がありました。

#### ナレッジの偏在化
対応スタジオが固定化されていたため、検証に必要なナレッジなどが資料に残っていなかった。
使用するテストケースでは、各項目で専門用語が使われていたり、確認手順が省かれたものが使用されており、新チームが検証を行うには難しい状況だった。

#### 検証資料の不足
ナレッジが偏在していたことにより、引き継ぎの資料も少なく、新たに用意する必要があった。
また、あったとしても、資料の場所がそれぞれ異なったり、資料自体が古かったりなど、そのまま使うには難しい状況だった。
<br>
当時の私は以上の問題点を認識できておらず、チームの導入が始まってから対応することとなりました。
チームの管理対応と資料の更新を同時に行うのは、無駄が多く、新人さんも困らせてしまいます。
その反省を踏まえ、最低限用意できていた方が良い資料と、あると便利な資料を記載していきます。

## 用意しておくと良い資料

### 業務マニュアル
<b>概要：</b>
検証に使用するテストケース、課金検証の手順や準備方法を記載した資料

<b>用意する理由：</b>
新規タイトルであれば、新しく用意する必要があると思いますが、既存タイトルであればすでに用意されている場合もあります。
その場合、資料が新チームにとって適切なものか確認しておくと良いです。
不足点や改善点などあれば事前に修正しておきましょう。

### 用語集
<b>概要：</b>
ゲーム内での用語や、業務で使用する用語などをまとめたもの

<b>用意する理由：</b>
専門用語が多いとテストケースの消化や、仕様把握にも一苦労です。
簡単にでもあるとお互いの認識相違などもなくなり、助かると思います。

### 作業スケジュール(全体用)
<b>概要：</b>
検証スケジュールや当日の業務内容がわかる資料

<b>用意する理由：</b>
作業をお願いするだけだと本人にも今がどのような状況なのか、どのぐらい重要な依頼をお願いされているのかイメージがつかないと思います。
全体のタスクを振り返れる作業スケジュール表を作成しておくとチームの一員としての作業イメージを付けてもらえると思います。

### 関係各所メンバーリスト
<b>概要：</b>
	エンジニアやプランナーなど、業種ごとに分けたメンバーリスト
 
<b>用意する理由：</b>
新人さんが各連絡を行う際、宛先が合っているのか不安だと思います。
こちらとしても間違った方に連絡を送らないようにしてほしいので、メンバーリストを用意しておくとお互いの不安を解消できると思います。
ただし、業務によっては担当がコロコロ変わることがあるため、どのように用意するかはタイトル毎に変わると思います。

## チーム管理に役立つ資料

### 業務外のマニュアル
<b>概要：</b>
	勤怠や管理対応などで使用する資料
 
<b>用意する理由：</b>
管理周りやコミュニケーションツールなど、業務に直接関係しないものでも、事前に用意しておくと良いと思います。
使用頻度が多いため、後から質問されることもあり、後の工数を減らすことができます。

### 質疑応答シート
<b>概要：</b>
	新人さんの質問とその回答を管理するためのシート
 
<b>用意する理由：</b>
疑問点が発生した時点で連絡してほしいのですが、こちらが忙しそうだと新人さんが連絡しにくいなど、色々と問題が出てくると思います。
質疑シートを用意しておけば、新人さんの質問へのハードルが下がりますし、こちらもあとで対応することができるので、一石二鳥です。

## チーム管理でもっとも重要だと思うこと
私としては、<b>「いかにチームでの業務が進めやすいか」</b>が重要だと思います。
資料や業務手順書など、重要なことは色々あると思いますが、何よりもチームでの連携が重要です。
5 ~ 10分でもいいので、定期的に話す時間を作ったり、毎日交換メモみたいなものを作るのでもよいかもしれません。
雑談もしづらい環境では業務も円滑に進められないと思います。

理想としては何でも相談できる上司。
それぐらいの信頼関係を築けていれば、働く環境の不安点や業務中の疑問点などの解決、業務のモチベーション維持など様々な点でプラスに働くと思います。

また、コミュニケーションに関しては<b>最初が肝心</b>だと思います。
時間が経つと、新人さんも身構えてしまうので、関係性を築くのが難しくなります。
私は忙しいからとおざなりにしてしまって、後悔しました。

## 最後に

いかがでしたか？
チーム導入前の準備であったり、コミュニケーションであったり。
なんとなくで進めていくとチームのみんなにとっても自分にとっても良くないことばかりです。

綺麗事を並べている自覚もありますが、チームのリーダーをする以上、居心地の良いチームにして業務の進めやすい環境を整えてあげたいですよね。
最初のうちは手厚く管理してあげて、慣れてきたら少しずつメンバーに任せていくとチーム管理も楽になっていくかもしれません。

以上が、1年のチームリーダーを経験した感想/反省でした。
もし記事に対しての感想や意見などありましたら、ぜひコメントいただけるとうれしいです。

今年も残りわずかですが、最後まで頑張っていきましょう！
MVCモデルとは(Servlet・JSP編)


↓動画で解説
[![Web開発者に必要な知識](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680113/014e2979-9823-b604-b89f-b2ebf7da772f.jpeg)](https://youtu.be/xiow0iyampU)

# MVCモデルとは
- Webアプリケーションなどのシステムを構築する時の設計手法

- **Model（モデル）・View（ビュー）・Controller（コントローラー）**
という役割を決め、分担して処理を行います。

## 流れ
![](https://storage.googleapis.com/zenn-user-upload/ff7f66eb2e22-20241212.png)

1.	クライアントが商品の詳細を見たいので、いちごのリンクをクリックする(リクエスト)
2.	ControllerがModelに「データベースから商品詳細のデータを取得して来て」とお願いする
3.	Modelはデータベースにいちごのデータをくださいとお願いする
4.	データベースはいちごのデータをModelに返す
5.	ModelはいちごのデータをControllerに返す
6.	ControllerはViewにいちごのデータを渡す
7.	ViewはControllerからもらったいちごのデータを使用して画面を作成、表示される(レスポンス)

## Model
ビジネスロジック(実際のお仕事をする部分)を担当する部分です。
データベースとデータの取得・登録・更新・削除なども行います。

## View
画面まわりを担当する部分です。

## Controller
ModelやViewに指示をしたり、管理する役目を担います。


# メリット
- 役割が分担されているので、独立して開発・テスト・保守が出来ます。
- 各部分を別々の人が担当できるので、チーム全員が同時に作業出来るので効率が良い側面があります。

# デメリット
- MVCモデルの考え方や使い方を覚えるには時間がかかります。特に、初めての人にはハードルが高いかもしれません。
- 小規模のアプリでは、役割分担が逆に手間になってしまうことがあります。
- チームで作る時には各部分を担当する人たちの間でしっかりと情報を共有することが重要です。そうしないと、全体の整合性が取れなくなることがあるかもしれません。

新入社員研修向け！JDBC・Servlet/JSP・ソフトウェアテスト・Webアプリケーション開発講座
https://www.udemy.com/course/jdbcservletjsp/?referralCode=88203EF7B00BDA28198C

---
Youtube
https://youtube.com/@codek2_studio

Twitter
[https://twitter.com/kunchan2_](https://twitter.com/kunchan2_)

note
https://note.com/codek2

Zenn
https://zenn.dev/codek2
AAAACCC

```

program_file_path = "main.cpp"
result_file_path = "result.txt"
with open(program_file_path,mode="r") as f:
    lines = f.readlines()

kadai_list = []
data_list = []

kadai = None
loop = None
size = None

kadai_flag = "	//課題"
for i,line in enumerate(lines):
    try:
        line = line.replace("\n","")
        
        if(len(line) > len(kadai_flag) and kadai_flag == line[:len(kadai_flag)]):
            _kadai = line[len(kadai_flag):]
            try:
                float(_kadai)
            except:
                continue
            if(kadai is not None):
                kadai_list.append(kadai)
                data_list.append(
                    (loop,size)
                )
            kadai = _kadai
        elif("const int default_loop" in line):
            _loop = line.split("=")[-1].replace(";","")
            try:
                float(_loop)
            except:
                continue
            loop = _loop
        elif("const int default_size" in line):
            _size = line.split("=")[-1].replace(";","")
            try:
                float(_size)
            except:
                continue
            size = _size
    except Exception as e:
        print(f"raised exception at line{i} : {line}")
        print()
        print(e)
        quit()


if(kadai is not None):
    kadai_list.append(kadai)
    data_list.append(
        (loop,size)
    )

with open(result_file_path,mode="w") as f:
    for i in range(len(kadai_list)):
        kadai = kadai_list[i]
        loop,size = data_list[i]
        
        f.write(f"\nexercise {kadai}: loop = {loop}, size = {size}\n")

```
AWS Amplifyで動かすNext.jsの限界


## はじめに

この記事は[ディップ Advent Calendar 2024](https://qiita.com/advent-calendar/2024/dip-dev)の12日目の投稿です。

2023年にディップへ新卒入社しました、[@ryotaneko827](https://x.com/ryotaneko827) と申します。
総合求人情報サイト「[はたらこねっと](https://www.hatarako.net/)」のフロントエンド開発を中心に行っており、
2024年5月からは新規メディア「[はたらこマガジン](https://www.hatarako.net/magazine/)」の開発も兼任しています。

## 背景

Next.jsで開発したアプリケーションをAmplifyにデプロイした際に、
いくつかの制約と不具合に直面したので、その内容を共有します。

これからNext.jsで開発を行う方や、Amplifyを検討している方にとって参考になれば幸いです。

## この記事のターゲット

- Next.js (App Router)で開発を行っている方
- AWS上にデプロイを検討している方

## はたらこマガジンの技術スタック

はたらこマガジンは、以下の技術スタックで開発を行っています。

### フロントエンド

- Next.js v14 (App Router)
- Node.js v22

### バックエンド

- microCMS

### インフラ

- AWS Amplify Hosting

## 限界1: SSRモードデプロイする際のビルドサイズに制限がある

Next.jsは通常、SSRアプリケーションとして動作します。
しかし、AmplifyがSSRアプリでサポートしているビルドの最大出力サイズは**220MB**です。

https://docs.aws.amazon.com/ja_jp/amplify/latest/userguide/troubleshooting-SSR.html#build-output-too-large

この制限を超えると、ビルドが失敗してしまいます。
`generateStaticParams`などを利用して、ビルド時に静的生成させたい場面があるかも
しれませんが、220MBを超えないように注意が必要です。

### 実際に発生した問題

#### `generateStaticParams`を利用したらビルドサイズが大きくなった

ビルド時にmicroCMSからデータを取得し、全ての記事を静的生成するように設定しました。
しかし、記事数が増えるにつれてビルドサイズが大きくなり、リリース前の時点で既に220MBを超えてしまいました。

検索ページや、記事のプレビューページではSSRを利用したいため、SSGアプリには移行できませんでした。

## 限界2: App Routerのキャッシュが正しく機能しない

Next.jsには、オンデマンドでキャッシュを再検証できる機能があります。

https://nextjs.org/docs/14/app/building-your-application/caching

しかし、Amplify Hostingではこの機能が正しく機能しません。

https://docs.aws.amazon.com/ja_jp/amplify/latest/userguide/troubleshooting-SSR.html#on-demand-isr-not-supported

### 実際に発生した問題

#### `revalidatePath`が効かない

Route Handlerを利用して、`revalidatePath('/', 'layout')`を実行できるエンドポイントを作成しました。

https://nextjs.org/docs/14/app/api-reference/functions/revalidatePath#revalidating-all-data

しかし、エンドポイントを叩くとキャッシュが消去されるのですが、数分後に再度キャッシュが復活してしまう現象が発生しました。

## 対処法

### キャッシュを無効化する

Next.js v14のApp Routerで開発したアプリケーションをAmplifyにデプロイする際は、
layout.tsxに以下のコードを追加して、キャッシュを無効化することをおすすめします。

:::note
Next.js v15以降では、`fetch()`はデフォルトでキャッシュを無効化するようになりました。
https://nextjs.org/blog/our-journey-with-caching
:::

```tsx:app/layout.tsx
export const fetchCache = 'force-no-store'
export const dynamic = 'force-dynamic'
```

https://nextjs.org/docs/14/app/api-reference/file-conventions/route-segment-config#dynamic

https://nextjs.org/docs/14/app/api-reference/file-conventions/route-segment-config#fetchcache

### SSGアプリとしてデプロイする

ビルド時に全てのデータを取得できる場合は、Static Exportsを利用して、SSGアプリとしてデプロイすることも検討してみてください。

```ts:next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  ...
}
```

https://nextjs.org/docs/14/app/building-your-application/deploying/static-exports

以下の記事が参考になります。

https://developers.play.jp/entry/2023/11/06/085943

## はたらこマガジンにおける今後の課題

現在は[キャッシュを無効化する](#キャッシュを無効化する)方法を採用しているため、ページの表示速度が遅くなってしまっています。

改善策として、以下の方法を検討しています。

- 脱Amplify Hosting
  - ECSもしくはS3 + CloudFrontで運用する
- SSGアプリとしてAmplify Hostingにデプロイする
  - ビルド時に静的生成できないページは、API GatewayもしくはCSRで対応する

## まとめ

Amplify Hostingは、インフラ環境の構築やデプロイの簡便さが魅力ですが、
実運用レベルでNext.jsを利用する際には、いくつかの制約があることを理解しておく必要があります。

SSRアプリにおけるビルドの最大出力サイズは、もう少し大きくしてほしいです...。
PhpStorm プロジェクトの複製

## 手順

1. `OLD_PROJECT` ディレクトリを `NEW_PROJECT` ディレクトリにコピー
2. `NEW_PROJECT/.idea/OLD_PROJECT_NAME.iml` を `NEW_PROJECT/.idea/NEW_PROJECT_NAME.iml` にリネーム
3. `NEW_PROJECT/.idea/modules.xml` の中の `OLD_PROJECT_NAME.iml` を `NEW_PROJECT_NAME.iml` に変更（2箇所）
4. `phpstorm NEW_PROJECT` で開く

Fin !
P1P2片持ち梁の複数荷重(2/4) ひずみエネルギとそれを使った材料力学 基本例題8.33 P289 「材料力学演習(20221021)」で、AI先生に私のコードを解説してもらいました。

・(2024-12-14)タイトルの修正済み。
・ver0.4の　Castigliano's second theorem　だけです。

:::note info
前　 [(1/4)sympyでやってみたい。
](https://qiita.com/mrrclb48z/items/f2ffdeba7c5d4058c8ea)次　 [(3/4)はりのたわみの エネルギー法のsympyのコードを 微分方程式の直接解法のsympyのコードへ 変換して下さい。
](https://qiita.com/mrrclb48z/items/5677d05a2861aa3a2ef1)
:::
```python
# ver0.4
from sympy import *
EI,P1,P2,a,b,x =symbols('EI,P1,P2,a,b,x')
M01_str="-(P1*(a-x)+P2*(a+b-x))"                               #;print("#",M01_str)
M12_str=          "-P2*(a+b-x) "                               #;print("#",M12_str)
U      = "1/(2*EI)*integrate((" + M01_str+")**2,(x,0,a)) +" \
        +"1/(2*EI)*integrate((" + M12_str+")**2,(x,a,a+b))"    #;print("#,U)
δ1=collect((diff(sympify(U),P1).expand()),[P1,P2])              ;print("#",δ1)
δ2=collect((diff(sympify(U),P2).expand()),[P1,P2])              ;print("#",δ2)
# P2*(a**3/(3*EI) + a**2*b/(2*EI)) + P1*a**3/(3*EI)
# P1*(a**3/(3*EI) + a**2*b/(2*EI)) + P2*(a**3/(3*EI) + a**2*b/EI + a*b**2/EI + b**3/(3*EI))
```
```
上記のコードを日本語で説明して下さい。
```
# Gemini先生へ
Gemini
1.5 Flash
Gemini との会話
(補足)「日本語で」 がないと、回答が英語になります。
回答
```
コードの説明
概要
このPythonコードは、構造力学において、はりのたわみをエネルギー法を用いて求める問題を解くためのものです。具体的には、両端が単純支持のばりに集中荷重P1とP2が作用する場合の、荷重点1と2におけるたわみδ1とδ2を計算しています。

具体的な処理
ライブラリのインポート:
sympy: 数式処理ライブラリをインポートし、シンボル変数や微分、積分などの操作を可能にします。
シンボルの定義:
EI, P1, P2, a, b, x: それぞれ、曲げ剛性、荷重、スパン長、変数を表すシンボルを定義します。
モーメント関数の定義:
M01_str, M12_str: 文字列として、各区間における曲げモーメントを定義します。
ひずみエネルギーの定義:
U: ひずみエネルギーを積分を用いて表します。曲げモーメントの二乗を積分することで、ひずみエネルギーが計算されます。
たわみの計算:
δ1, δ2: ひずみエネルギーを荷重P1, P2でそれぞれ偏微分することで、荷重点1, 2におけるたわみを計算します。collect関数を使って、結果をP1, P2について整理しています。
各行の解説
M01_strとM12_strは、それぞれ区間0~aとa~a+bにおける曲げモーメントを表す式です。
Uは、Castiglianoの第2定理に基づいて、ひずみエネルギーを計算しています。ひずみエネルギーは、外力が仮想変位をしたときに生じる仕事に等しいという原理が利用されています。
δ1とδ2は、Castiglianoの第1定理に基づいて、たわみを計算しています。たわみは、ひずみエネルギーを荷重で偏微分することで得られます。
全体的な流れ
問題を数学モデル化し、曲げモーメントの式を立てる。
ひずみエネルギーを積分により求める。
Castiglianoの定理を用いて、たわみを計算する。
Pythonのsympyライブラリを使って、数式を処理し、数値計算を行う。
コードの出力
このコードを実行すると、δ1とδ2に、それぞれ荷重点1と2におけるたわみの式が代入されます。これらの式をさらに数値計算に用いることで、具体的なたわみの値を求めることができます。

注意点
このコードは、単純支持のばりという特定の条件下での計算です。他の支持条件や荷重条件の場合には、曲げモーメントの式やひずみエネルギーの式が異なるため、修正が必要です。
sympyライブラリは強力な数式処理ライブラリですが、複雑な計算になると計算時間がかかることがあります。
その他
このコードをさらに拡張することで、より複雑な構造物の解析を行うことができます。例えば、連続ばりやラーメン構造などの解析も可能です。
sympyライブラリには、数値計算だけでなく、数式の変形や可視化などの機能も備わっています。
このコードについてのより詳しい質問があれば、お気軽にご質問ください。

補足:

このコードは、構造力学の基礎的な概念を理解している方を対象としています。
構造力学の教科書や参考書を参照しながら、このコードを理解することをおすすめします。
もし構造力学の基礎的な知識が不足している場合は、以下のキーワードで検索することをおすすめします。

構造力学
はりのたわみ
エネルギー法
Castiglianoの定理
sympy
これらのキーワードで検索すると、多くの参考資料が見つかるはずです。

Gemini は不正確な情報を表示することがあるため、生成された回答を再確認するようにしてください。
```
【勉強記録】Qiita毎日投稿してから2カ月がたちました

# はじめに
こんにちは！アメリカの大学で語学を学びながら、独学でソフトウェアエンジニアを目指している者です。
今回は10/6からQiitaを毎日投稿して2か月たったので、振り返りを兼ねて記事にしていきます
なお、毎日投稿に関する内容についてはこちらの記事で書いているのでそこで書いてない内容または補足をしていきたいと思います

https://qiita.com/Taira0222/items/3003cc7ab09aaf4ea877

# 2カ月続けてみてどうだった？
* そこまでしんどくなくなってきたが、書く内容がない場合があるのでその時はちょっと困る時もある
傍から見ると、記事を投稿するのは大事だけど毎日でなくてよくない？と思うかもしれませんが、自分に何かしらのハードルを課すことで例え休日だとしても1日に1回以上はプログラミングについて思い出すことで、定着を図る目的があります。
* 公式リファレンスマニュアルを見る癖がついてきた
すべてに関して探し切れているわけではないが、chatgptに聞くだけではなくリファレンスマニュアルではどのように定義されているかを見る癖がつきました。正直リファレンスマニュアルをみて、課題をすべて解決できていないのでAIのサポートをもらい、記事を書くことで理解を深めています
* 旅行の時は記事を作り置いておく必要があった
そこまでして続ける必要ある？と思われるかもしれませんが、自分の中で続けると決めているので交通事故にあってPCが触れないとか病気でPCを見ると頭が痛いなどの緊急事態以外は基本的に書くようにしています。
アメリカではサンクスギビングという休みがあり、そこで3泊4日の旅行に行ってきたので4本の記事をためておきました。

# 投稿を続けるコツ
* 習慣化する
この記事投稿は最重要優先にしています。それが効率重視で考えると正解だとは思いませんが、私の中では正解だと思っています。
というのも、現在独学で勉強しているのですが、モチベーションの上下が少なからずあり継続できているという証としても習慣化して毎日継続しています。
* 効率云々を考えない
これについては習慣化で書いた内容にリンクしますが、効率的か否かを考えてしまうと記事を書かない理由(いいわけ)を考えてしまいます。
そんな時間と精神状態を考えたら毎日継続した方がよくないかな？と思い継続している次第です。

上記のように偉そうに話している私ですが、最近モチベーションが低下しています。
私の場合は英語の勉強とプログラミングに時間を使って筋トレがあまりできていないのでそれが原因だと思います。大学が終わったらスケジュールを再調整して筋トレの時間を1日に1時間は作ろうと思います。

モチベーションを下げることが悪いのではありません。全然恥ずかしいことでもないですし、主観ですが超優秀な起業家でも私たち同様にモチベーションが低下することはあると思います。
彼らはそれに気づくスピード、そもそもモチベーションを下がりにくくするには、対処方法などを知っているから優秀なのだと思います。

# 今後の予定
1カ月の時も書きましたが、短期の目標は3カ月を目指したいと思います。
実は今週で大学が終了するので、勉強時間が一気に増える予定です。
大学が終わってから考える予定ですが、時間が増えるのでQiita投稿に絡めて何か発信できたらと思います。
社内パッケージの運用で苦労したところ


## はじめに

[レバウェル開発部アドベントカレンダー](https://qiita.com/advent-calendar/2024/levwell)15日目です

レバウェルでは現在50近いサービスを運用していますが、そのうち20を超えるサービスをLaravelを利用した共通基盤で実装しています

このため多くの共通機能を社内向けのプライベートなLaravelパッケージとして実装していますが、今回は運用中苦労した点をから社内パッケージを運用・保守する際に意識するポイントを紹介したいと思います


## 1. テストを実装する

ユニットテスト実装しましょう！
当たり前といえば当たり前なんですが、とても重要なポイントです

### テストなくて苦労したところ

レバウェルで初めてLaravelのアップグレード対応を行った当時、30近くあったパッケージのうち、行カバー率で90%以上のパッケージが5パッケージしかなく、必要なユーザテストが膨大ですぐに着手出来ない状態でした

この問題に対し当時ユニットテストのカバー率を上げる対応を行い、行カバー率90%以上で10パッケージ、全体のユニットテスト自体も増やすことでなんとかアップグレード自体は遂行できました

ただ現状も十分なテストが実装出来ていないためバージョンアップ対応するたびに苦労してます

### テストのことまとめ

バージョンアップ時のことだけ意識する場合、PHPUnitであれば行カバー率を上げることを進めると良いです

パッケージ全体で平均的に上げていくよりモジュール単位で100%に近づけることを目指したほうが、実際のバージョンアップ対応時にラクになります

## 2. 依存関係を小さく、シンプルに

パッケージを実装していると他のパッケージを利用して実装する事があると思います

特にLaravelパッケージを作る場合Laravelの機能に依存することが多いと思いますが、その際の依存関係が無駄に大きくならないようにしましょう

### 依存関係苦労したところ

運用している中で目にしたのは、初期開発時に広めに依存関係を指定しその後もそのままになっているケースや、不要になった際にcomposer removeしていないケースでした

これらに気づいた経緯が、不具合対応でパッケージを調査した際なのですが、これによって無駄な調査と対応で結構な時間を使うことになってしまいました

同時に社内パッケージ同士の循環的な依存も発生しており、この対応がさらに大変でした

### 依存関係のことまとめ

単純なコードだけじゃなく依存パッケージなども小まめに整理する意識をしておくのが良いでしょう

チームによっては外部パッケージへの依存度を減らすために自社で再開発する方針のところもあると思いますが、その辺はチームで判断すればよいかと思います

## 3. アプリケーション側のアップデート対応を後回しにしない

言語やFWのバージョンアップについての話ですが、社内パッケージを利用しているアプリケーションが増えると、アプリケーション毎のアップデート対応の進捗にズレが出てくることがあります

あるアプリケーションの利用している言語バージョンが古すぎるとき、公開パッケージであればサポート対象から外すという判断が可能なケースでも、社内パッケージの場合サポートしなくてはいけないとなることがままあります

### アップデート遅れで苦労したところ

レバウェルでは現在PHP/Laravelともに複数バージョンのサポートが必要なため、ユニットテストを実行する際はそれらをカバーするよう環境を変えつつ複数回実行する必要があります

また、3つのパッケージではPHP8系の3.xと7系の2.xのように複数バージョンを保守している状態で、こちらも変更の度に複数のPRを作成する必要があり大変です

### アップデートのことまとめ

アプリケーション側のアップデート対応は足並み揃えつつしっかり対応し続けることをおすすめします

## おわりに

社内パッケージの場合、非公開かつ自社で利用していることから公開パッケージとは違った苦労も出てきますが、健全に運用されてる他社さんの話も多く聞こえてきます

これから社内パッケージの開発をしようという方が、同じ様な苦労をしないですむことをお祈りしています
Vision ProのPersonaをLooking Glass Goで召喚してみた

Apple Vision Pro には Persona という、自分のリアルアバターを作成・使用する機能があります。
これを使うことによって、Vision Proを被っている状態でも、あたかも被っていない状態の自分の顔でWebミーティングに参加することなどができます。
ただ、この Persona は相手側も Vision Pro でないと立体で見ることができません。また、現状はAppleもPersonaの3D情報を直接取得するAPIを公開していません。
そこで今回はかなり無理矢理ではありますが、Vision ProのPersonaを裸眼立体視することが可能なLooking Glass Goを使って表示させてみました。
ちなみに、こちらの実演は先日行われた国内HCI系カンファレンスである[WISS2024](https://www.wiss.org/WISS2024/)のスポンサー（[フューチャ株式会社](https://www.future.co.jp/)）ブースにてデモしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21380/51b381dc-d194-9bee-8517-b6d70d8279ae.png)
今回の検証の全体構成

## [Apple Vision Pro](https://www.apple.com/jp/apple-vision-pro/)
#### 事前準備
まず、Vision Proで自分のPersonaを作成しておきます。
#### 実行時
FaceTimeを起動して、下記のMacBook Pro側のユーザーに対して通話開始します。

## [Apple MacBook Pro](https://www.apple.com/jp/macbook-pro/)
#### 事前準備
[OBS](https://obsproject.com/ja/)を導入しておきます。
[Depth Anything V2のCoreMLサンプル](https://github.com/huggingface/coreml-examples/tree/main/depth-anything-example)をcloneし、入力元をOBSのVirtual Cameraへ修正しておきます。これは、入力元の2D動画情報からリアルタイムに深度情報を推論するものになります。
#### 実行時
OBSを起動し、FaceTimeの画面が中央に来るように配置し、Virtual Cameraを起動します。
修正済のDepth Anything V2のCoreMLサンプルを起動し、全画面で表示します。
NucBox G5へScreen Mirroringで繋ぎます。（NucBox G5側の「実行時」を行った後）

## [GMKtec NucBox G5](https://www.gmktec.com/products/intel-alder-lake-n97-mini-pc-nucbox-g5)
超コンパクトなPCです。ほぼiPhoneに隠れるサイズです。
#### 事前準備
[AirServer](https://www.airserver.com/WindowsDesktop)を導入しておきます。これは、AirPlayサーバの機能があるものです。
[Refract](https://github.com/SolerSoft/Refract)を導入しておきます。これは、RGBDでPCに表示されているものをLooking Glassへ立体で表示させるためのものです。
[Looking Glass Bridge](https://lookingglassfactory.com/software/looking-glass-bridge)を導入しておきます。これは、Looking Glassに接続するためのものです。
#### 実行時
AirServer、Refract、Looking Glass Bridgeを起動します。

## [Looking Glass Go](https://lookingglassfactory.com/looking-glass-go-spatial-photo-frame)
#### 事前準備
NucBox G5とLooking Glass Goを[HDMI→USB Type-C変換アダプタ](https://www.sanwa.co.jp/product/syohin?code=AD-HD26TC)経由でUSBケーブル(Looking Glass Goに付属のUSB Type-Cケーブル)で繋いでおきます。

## まとめ
元となるFaceTimeで受信した画像の品質が良い場合はかなり立体的に表示されることが確認できました。
WISS2024の会場でデモした際には、自社で持ち込んだWiFiルーターを使ったため、FaceTimeでかなり画像がガビガビになってしまい、残念ながら品質は良くありませんでした。
VSCodeにContinueを入れて無料で生成AIを使ったコーディングをする方法

# Continueとは
ContinueとはGitHub CopilotやCursorなど、生成AIでコーディングするシステムをオープンソースで提供している拡張機能です。

# インストール方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561175/a0d5606b-2334-83da-0303-c54b760553b7.png)
VScodeの拡張機能→検索で「continue」と入れて、インストールします。
※上記はインストール済みです。

# 操作方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561175/f60197b8-c73b-6b89-a36a-31dbee30fecb.png)
Continueのマーク![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561175/610f5f74-dc70-c905-f384-5e14a55656c7.png)
を押すと、メニューが出てきます。
まだ設定をしていない場合は、設定を行います。

### QuickStart
→Continueの50回お試しAPIを使う方法。GitHubで登録すると使える
### Best
→今おすすめの構成で使う(Claude3.5 Sonnet, Codestralを使うのでAnthropic API keyとCodestral API keyが必要になります。)
### Local
→Ollamaを入れて、ローカルで生成AIモデルを使うようにします。

### その他のモデル
continueの検索ボックスのモデル名(今はollama_auto_bge-mとなっているモデル名)を押すと、現在登録しているモデルを選べるのですが、この一番下に「Add Chat model」というのがあり、ここからさらに別のベンダーのモデルを追加できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561175/54f5195b-80a6-6e8e-a4fc-3c8be5e321fa.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561175/085c26f8-294b-c258-df15-57d1b8d41e5b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561175/2de81d07-eb12-743b-871f-e65d7d0b9c34.png)

Providerを選ぶと色々なベンダーを選べます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561175/a1aa57f8-c07f-1340-a83f-c580df6c4a53.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561175/2c86748a-074e-ce10-3b45-9abc18f0f141.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561175/e25f7ffc-dda1-f540-bea1-ed51213f6be8.png)
このベンダーのAPIキーを取得して設定すれば利用できるようになります。