OmniAICreator/Qiita-1.07M huggingface dataset:
Test runnerを使用してStorybookのテストをGitHub Actionsで実行する

# はじめに

こんにちは、エンジニアのkeitaMaxです。

Test runnerを使用してStorybookのテストをGitHub Actionsで実行してみようと思います。

# インストール

以下コマンドでTest runnerをインストールします。

```
npm install @storybook/test-runner --save-dev
```

# GitHub Actionsの設定

ymlファイルを以下のように設定しました。

```yml
name: unitTest

on: [pull_request]

jobs:
  phpunit:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    defaults:
      run:
        working-directory: ./src
    steps:
      - uses: actions/checkout@v2
      - name: npm
        run: npm ci
      - name: Build Storybook 
        run: npm run build-storybook
      - name: Serve Storybook
        run: npx serve storybook-static -l 6006 &
      - name: Install Playwright with dependencies
        run: npx playwright install --with-deps
      - name: storybookTest
        run: npm run test-storybook

```

LaravelとInertiaとReactとDockerで開発していたソースなので`working-directory: ./src`って感じになってます。

package.json２つあって、以下のように設定しています。

```json:package.json
  "scripts": {
    "prepare": "husky",
    "ci": "npm --prefix ./src ci",
    "lint": "npm --prefix ./src run lint",
    "build": "npm --prefix ./src run build",
    "type-check": "npm --prefix ./src run type-check",
    "test-storybook": "npm --prefix ./src run test-storybook"
  }
```

```json:src/package.json
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "storybook": "storybook dev -p 6006",
    "lint": "eslint ./resources/js",
    "lint:fix": "eslint --fix ./resources/js",
    "type-check": "tsc --noEmit",
    "build-storybook": "storybook build",
    "test-storybook": "storybook dev -p 6006 & wait-on http://localhost:6006 && test-storybook"
  },
```

これを実際にPRを作成しGitHub上で実行してみると、ちゃんと動いていることがわかります。
# おわりに

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

最後まで読んでいただきありがとうございました！

# 参考

https://storybook.js.org/docs/writing-tests/test-runner
【合格体験記】情報セキュリティマネジメント試験に合格しました！

2024年12月に情報セキュリティマネジメント試験に合格したため、合格体験たるものを記載します。
今後、受験を考えている方に参考になる部分があればと思っています。

### 受験の動機
筆者が本試験を受験した理由は下記になります。

・現場でセキュリティに関する話は絶えないので、学んでおきたい思った
・別の社員で合格した方の合格体験を聞いて、自身も取得できそうだと思った

### 試験結果
下記キャプチャの通り、7割超の点数で合格することができました。
試験終了後、約3時間後にはipaのマイページにてスコアを確認することはできました。正式な合格発表は翌月に回されました。

![合格.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2745850/38f31d0a-e180-1103-a3c3-3bfccfeab674.png)


### 学習方法
学習方法は下記2つです。
学習期間は、計3週間で20時間くらいでした。

①サンプル問題・過去問題

・新制度サンプル問題
・令和6年度
・令和5年度
を2周しました。間違っているところは、再度解きました。

1周目は4～5割くらい、2周目は8割くらいの正答率でした。

＜サンプル問題・過去問題URL＞
https://www.sg-siken.com/s/

②過去問道場
①が終わってからは、ひたすら過去問道場で模擬試験を解きました。
全年度に設定して、試験当日まで解いていました。

最初は5割くらいだった正答率が、試験受けるころには、
8～9割くらいに安定してとれるようになりました。

＜過去問道場URL＞
https://www.sg-siken.com/s/sgkakomon.php

### 受験してみての感想
合格することができて安心しました。
基本情報や応用情報は取得していたので、重複している問題もあり、とても勉強しやすかったです。
ただ、科目Bの長文は苦戦しました。単純に全文読むことに体力が必要だったのが大変でした。試験当日は120分間の試験時間ほぼフルで活用しました。
とはいえ、科目Bは落ち着いて読めば、答えを出せるものが多かったので、慌てないことがポイントかなと思いました。

### 今後の目標
ドキュメント作成力に課題があると、一緒に働いている方から教えていただいたので、
直近はその課題に対する対応を進めています。
まずは、「三行で撃つ 〈善く、生きる〉ための文章塾」「超・箇条書き」という本で、体系的な学びを始めています。
テクニック的なところは、e-learningで学習予定です。
それらの対策を通して、ドキュメント作成力を高めていきたいです。
【イベントレポート】OCIjp #58 Oracle Cloud Infrastructure ユーザーグループ #OCIjp

いつも記事を読んでいただきありがとうございます！
モブエンジニア（[@mob-engineer](https://qiita.com/mob_engineer))です！

今回は2025.01.21（火）に開催した**OCIjp #58 Oracle Cloud Infrastructure ユーザーグループ**へ参加したので、アウトプットとしてイベントレポートを執筆しました。

初学者でもサクッと読めるように平易な表現で執筆しておりますので、お気軽に読んでいただければ幸いです。

:::note info
誤字脱字、わかりやすい表現を心がけていますが、リアルタイムで執筆しているため誤字脱字があるかもしれません。
:::

#### イベントページ

https://fullenergy-oci.connpass.com/event/340527/

#### アドベントカレンダー

https://qiita.com/advent-calendar/2024/oci

# 目次
- アドベントカレンダー振り返り
    - Oracle Database関連
    - CD3 Automation TookitでOCIリソースをExcelから爆速構築（リソース構築削除編）
    - NEC印西データセンター接続を振り返ろう
    - OCI ADVENT CALENDER 2024からの振り返り
    - Cloudiiブログでアーキテクチャを作ってみる
- まとめ

## アドベントカレンダー振り返り

### Oracle Database関連
- Microsoft Azureとの統合（Database）
    - ざっくりいえば、Azure環境でOracle環境が利用できる
- Exadata Databaseとは
- Google Cloudで設定可能
    - Database>Oracle Databaseで設定可能
    - マニュアル類もそろっているため設定可能
    - 日本リージョンでは未提供（ムンバイでは提供可能）
- Azureの設定の場合
    - 検索ボックスでOracle Databaseと検索すれば出てくる
- AWSの場合
    - Database Migration Serviceを用いてマイグレーションを行う
- まとめ
    - Exadata Databaseはどのクラウドサービスでも利用可能
    - Autonomous Databaseもどのクラウドサービスでも利用可能
    - Azureのみ日本での利用可能、それ以外は海外のみ
    - OCI GoldenGateはどのクラウドでもサポートしていない
    - Zero Downtime MigrationはAzure、Google Gloudはサポートしている
- AWSは一歩遅れている印象

### CD3 Automation TookitでOCIリソースをExcelから爆速構築（リソース構築削除編）

#### 参考サイト

https://github.com/oracle-devrel/cd3-automation-toolkit

https://docs.oracle.com/ja/learn/oci-cd3-greenfield/index.html#introduction

- 自己紹介
    - フルエナジー社のクラウドアーキテクト
- CD3 Automation Tookitとは
    - ざっくりいえばExcelでリソース構築削除できるもの
    - バックボーンはTerraformを使っている
- 使ってみた感想
    - ドキュメント類は英語なためリサーチが難しい
    - ToolKitで構築できるリソースはそろっている 
    - 前提知識はある程度必要だが、マネコンポチポチよりは楽な印象
    - ドキュメントに記載されていないリソースも設定できる場合もある
- リソース更新削除について
    - Excel経由でリソース更新削除は可能だが手動作成したものは更新削除できない

### NEC印西データセンター接続を振り返ろう
- 自己紹介
    - フルエナジー社のエンジニアの方
- 印西データセンターの接続状況
    - Oracle Databaseは外側にある
- AWS TGW経由でOCI接続してみた
    - そこまで早くならない

### OCI ADVENT CALENDER 2024からの振り返り
- 免責事項
    - 個人的な見解があるためご留意ください
- 自己紹介
    - フルエナジー社の方
    - 次回はExadata Databaseについて登壇される
- Autonomous Databaseについて
    - S3バケットにある複数のPDFファイルをテキストに変換してOCI Object Storageに格納する
    - 機械学習関連で使えそうだと思ったので使ってみたいと思いました

### Cloudiiブログでアーキテクチャを作ってみる
- 自己紹介
    - Cloudii所属のエンジニアの方
    - 今年は13記事をアップされた方
- アーキテクチャ構成
    - DRGを利用してネットワークを構築してみた
        - ルーティング制御を行うことができるためネットワークつよつよ民はお得
    - Private Endpoint
        - プロキシサーバを経由せずにオブジェクトストレージにアクセスできるようになった
    - バケットのライフサイクルポリシーについて
        - （個人的考察）Amazon S3のライフサイクルポリシーのようなイメージ
    - Base DBバックアップ失敗を通知する
        - メール通知される内容はきれいではないのでファンクション機能を使って整形が必要
    - OCIモニタリングによるカスタム・ログ監視
        - ロギング機能を使ってログ分析ができる
    - 今後ほしいサービス
        - CDNがほしい
        - AWS Fargateみたいなサービス
        - DRG強化してもらいたい

## まとめ

OCI関連はキャッチアップがあまりできていなかったですが、凄く興味深い発表が多くて有意義でした。最後まで記事を読んでいただきありがとうございました👍

PS：
私の登壇資料は以下です（突貫作成なので誤字脱字があるかもしれません...)

https://speakerdeck.com/masakiokuda/xiao-neta-ge-kuraudosabisunototupuhua-mian-datusiyubodo-wobi-jiao-sitemiyou-number-ocijp-14946c3d-4462-4064-9e06-27091bbac1dc

ブログ記事

https://qiita.com/mob_engineer/items/c87097bf202fb46b5045
2025-01-20 海岸線データを作る試み

天気図の海岸線データを作りたいのだが、知財的にクリアされたデータでやりたい。

「coastline data」とかで雑にぐぐると Natural Earth のパブリックドメインデータがみつかる。
https://www.naturalearthdata.com/downloads/50m-physical-vectors/50m-coastline/

とにかくダウンロードしてみる。
https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/50m/physical/ne_50m_coastline.zip

中はshapefileである。PRJファイルをみると普通に経緯度座標であるらしい。
```ne_50m_coastline.prj
GEOGCS["GCS_WGS_1984",
 DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],
 PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
```

shapefileを何らかのテキストファイル、たとえばGeoJSONに変換したいと思ってぐぐる。
https://zenn.dev/yuichiyazaki/articles/b70da4bb63ea02
GDALのogr2ogrを使うらしい。

```
# apt install gdal-bin
$ ogr2ogr -f GeoJSON ne_50m_coastline.geojson ne_50m_coastline.shp
$ wc ne_50m_coastline.geojson 
   1434  271663 2769871 ne_50m_coastline.geojson
```

中を見るとまっとうな GeoJSON ぽい。属性は min_zoom というのがあって、0.0〜4.0の範囲である。天気図としてはズームレベル6くらいを想定しているので、小さい島を捨てる処理は要らないかな。

とりあえずマトモに読めることと、構造を確認する。マトモに読めるとは、JSONであるからメモリを食いすぎてサーバが落ちる事態がありえるので先にあたりをつける趣旨。構造とは、GeoJSONには多様な図形種類がありえて、そのどれを使っているかである。
```ruby:testgjlns.rb
#!/usr/bin/ruby

require 'json'
j=JSON.parse(File.read(ARGV.shift))
n=0
raise unless j['type']=='FeatureCollection'
j['features'].each{|f|
 raise f['type'] unless f['type']=='Feature'
 g = f['geometry']
 mz=f['properties']['min_zoom']
 case g['type']
 when 'LineString' then
   cs=g['coordinates'].size
 when 'MultiLineString' then
   cs=g['coordinates'].sum{|ls| ls.size}
 else
   raise g['type']
 end
 printf "%3u\t%3.1f\t%3u\n", n, mz, cs
 n+=1
}
```
最初はもうちょっとかんたんなプログラムで、主に各オブジェクトの type メンバを assertion（想定外なら raise で落とす）しながら落ちないようにプログラムを育てていった結果が上記。何故かは知らんが単純LineStringとMultiLineStringが混在していた。
出力。
```
$ ruby testgjlns.rb ne_50m_coastline.geojson | head
  0	 1.5	 56
  1	 4.0	  8
  2	 4.0	  8
  3	 3.0	  9
  4	 4.0	  7
  5	 4.0	  5
  6	  0.0	1154
  7	  0.5	 46
  8	 1.0	 65
  9	 1.0	101
```

CやFortranで読みやすいように整形出力する。
```ruby:lnsgjtx.rb
#!/usr/bin/ruby

require 'json'
j=JSON.parse(File.read(ARGV.shift))

n=0
raise unless j['type']=='FeatureCollection'
j['features'].each{|f|
 raise f['type'] unless f['type']=='Feature'
 g = f['geometry']
 case g['type']
 when 'LineString' then
  n+=1
 when 'MultiLineString' then
  n+=g['coordinates'].size
 else
  raise g['type']
 end
}
printf("LINES %10u\n", n)

def show ls, i
  printf("%10u %10u\n", i, ls.size)
  ls.each{|x, y|
    printf("%+8.3f %+7.3f\n", x, y)
  }
end

i=0
j['features'].each{|f|
 g = f['geometry']
 case g['type']
 when 'LineString' then
  show(g['coordinates'], i)
  i+=1
 when 'MultiLineString' then
  g['coordinates'].each{|ls| show(ls, i); i+=1}
 end
}

```

次はこれを図化して確認する。プログラムを書こう。
https://github.com/etoyoda/grib2png/issues/48

素朴に全球プロットしてみるとまっとうに見える。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229017/0797ca39-b523-fe6a-b901-70600c20ca6b.png)

メルカトル図法に変更
![plot (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229017/c9f42d4c-725e-7fe9-7733-ac3372047770.png)
【Vue】Webpackに頼らない自力ビルド環境の構築（npm）

# めんどくさい

Webpack使うのもいいけどなんというか暗記できるような小さい環境でビルドしたい。いちいちWebpackの設定をググるのもめんどくさい。自分の持ってる知識だけでビルドしたい。

## 必要なパッケージ

* javascript-obfuscator ... ビルドファイルの難読化を行う
* nodemon ... ソースファイルを監視してビルドを走らせる
* vue ... Vue3

## スクリプト

### copy

`npm_test/src`にソースファイルがあるという前提。それを`../path/to/app/js/main.js`にビルドする。
ビルド方法は簡単で`cat`コマンドでコードを連結して出力するだけ。

```
{
  "scripts": {
    "copy": "cat node_modules/vue/dist/vue.global.js src/main.js > ../path/to/app/js/main.js"
  },
}
```

取り込みたいライブラリが増えたら編集して`cat`とするファイルを増やす。

### watch

`nodemon`で`npm_test/src`以下のファイルを監視し、編集があったら自動でビルドする。ビルドには`copy`スクリプトを使う。

```
{
  "scripts": {
    "watch": "nodemon -L --watch src --watch --ext js --exec \"npm run copy\""
  }
}
```

### build

`javascript-obfuscator`でソースコードを難読化するスクリプト。`npm run build`で本チャンビルドができる。

```
{
  "scripts": {
    "build": "cat node_modules/vue/dist/vue.global.js src/main.js | node build.js > ../path/to/app/js/main.js"
  }
}
```

```js:build.js
process.stdin.setEncoding('utf8');

let data = ""

process.stdin.on('data', (chunk) => {
    data += chunk
});

process.stdin.on('end', () => {
    var JavaScriptObfuscator = require('javascript-obfuscator');
    var obfuscationResult = JavaScriptObfuscator.obfuscate(
        data,
        {
            compact: false,
            controlFlowFlattening: true,
            controlFlowFlatteningThreshold: 1,
            numbersToExpressions: true,
            simplify: true,
            stringArrayShuffle: true,
            splitStrings: true,
            stringArrayThreshold: 1
        }
    );
    const code = obfuscationResult.getObfuscatedCode()
    process.stdout.write(code)
});
```

## あとはこれをコマンド一発で初期化できるスクリプトを作る

あとはこれらの環境をコマンド一発で初期化できるスクリプトを作り、新しいアプリを作るときはそのスクリプトで環境を用意する。たぶんラクだと思う。
Next.js + Prismaで作成したTodoアプリのデバッグ: 予期しないAPIレスポンスの処理


## はじめに

Next.jsとPrismaを使用してTodoアプリを作成し、Vercelにデプロイした際に遭遇したエラーとその解決方法について共有する。この記事は、地震の備忘録とすること、また同様の問題に直面している開発者の助けになることを目的としている。

## 問題

デプロイ後、タスクのチェックボックスをクリックすると、タスクの表示が消えてエラーが発生した。エラーの内容は以下の通り：
[Each child in a list should have a unique "key" prop.]

## 原因

デバッグの結果、以下の問題が明らかになった：

1. APIレスポンスに予期しないデータ（`{count: 1}`）が含まれていた
2. フロントエンドでのAPIレスポンスの処理が不適切だった
3. エラーハンドリングが不十分だった
4. 更新操作後のデータ管理が適切でなかった

## 解決方法

### 1. APIレスポンスの修正

`app/api/user-todos/route.ts`ファイルを以下のように修正しました：

```typescript
export async function PUT(request: Request) {
  try {
    const userId = await getUserId(request)
    const { id, title, completed } = await request.json()
    await prisma.userTodo.updateMany({
      where: { id, userId },
      data: { title, completed },
    })
    //return NextResponse.json(userTodo); //削除
    // 更新後のTodoを返す
    const updatedTodo = await prisma.userTodo.findUnique({ where: { id } })
    return NextResponse.json(updatedTodo)
  } catch (error) {
    return NextResponse.json({ error: 'Not authenticated' }, { status: 401 })
  }
}

const fetchUserTodos = async () => {
  try {
    const response = await fetch('/api/user-todos', {
      headers: {
        'Authorization': `Bearer ${localStorage.getItem('token')}`
      }
    })
    const data = await response.json()
    if (Array.isArray(data)) {
      setUserTodos(data)
    } else {
      console.error('Unexpected API response:', data)
      setUserTodos([])
    }
  } catch (error) {
    console.error('Error fetching todos:', error)
    setUserTodos([])
  }
}
```
### 2. フロントエンドでのデータ処理の改善

`app/page.tsx`ファイルを以下のように修正した：

```typescript

const toggleUserTodo = async (id: string) => {
  const userTodo = userTodos.find(t => t.id === id)
  if (!userTodo) return
  try {
    const response = await fetch('/api/user-todos', {
      method: 'PUT',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${localStorage.getItem('token')}`
      },
      body: JSON.stringify({ ...userTodo, completed: !userTodo.completed }),
    })
    const updatedTodo = await response.json()
    if (updatedTodo && updatedTodo.id) {
      setUserTodos(userTodos.map(t => t.id === id ? updatedTodo : t))
    } else {
      console.error('Unexpected API response:', updatedTodo)
    }
  } catch (error) {
    console.error('Error updating todo:', error)
  }
}
```

## 結論

### 実現した改善点

これらの修正により、以下の改善が実現した：

1. **APIレスポンスの適切な検証**
2. **エラーハンドリングの強化**
3. **更新操作後の適切なデータ管理**
4. **予期しないデータの除外**

### 得られた教訓

この経験から、以下の重要な教訓を得た：

- **APIレスポンスの形式を常に検証する**
  - 予期しないデータ構造に対して堅牢なコードを書く
- **適切なエラーハンドリングを行う**
  - ユーザー体験を損なわないよう、エラーを適切に処理する
- **サーバー側とクライアント側のデータの一貫性を保つ**
  - 更新操作後は最新のデータを取得し、状態を同期させる
- **予期しないデータやエラーに対して、適切なフォールバック処理を実装する**
  - エッジケースを考慮し、アプリケーションの安定性を高める

正直、[1. APIレスポンスの修正](#1-apiレスポンスの修正)によってエラーは解消した。
しかし、これらの原則を守ることで、より安定したアプリケーションを維持できる。
Next.jsとPrismaを使用したアプリケーション開発において、これらの点に注意を払うことで、多くの潜在的な問題を事前に防ぐことができる。
英語翻訳）Async Rustは性能問題ではなく並行プログラミングに関するものである。

# Source
https://kobzol.github.io/rust/2025/01/15/async-rust-is-about-concurrency.html 


# Too Long; Didn't Read.(ざっくり言うと）

> async/await の主な利点は、複雑な同時実行性を簡潔に表現できることだと思います。 (潜在的な) パフォーマンスの向上は二次的な効果にすぎません。したがって、コードがどのように高速化されるか (または高速化されるかどうか) ではなく、主にコードがどのように簡素化されるかに基づいて非同期を判断する必要があります。
AIの力でゼロからウェブアプリケーションを開発できるようになった話

昨年からAIを活用したプログラミングに挑戦し、これまでに約10個のウェブアプリケーションを作成しました。

## これまでに作成したアプリケーション（一部紹介）
　
3月: [NPCシェア](https://npc-share.com/)

5月: [画像販売用サンプルサイト](https://sfp-sample5.com/)

7月: [アフィリエイトサービスシステム](https://sl.as-sfplan.com/)

8月: [郵便番号から電力エリアを判定するプログラム](https://npc-share.com/power-area.html)

9月: [独自コンテンツ販売用ファイル](https://note.com/sfp_note/n/n8dd27f9ce657)

10月: [ペットのうた](https://petsongs.jp/)

　
   　
これらのアプリケーションを開発したことは、以前の自分には到底考えられないことでした。

というのも、私は今でもHTML、CSS、JavaScriptを一行も自分で書くことができないからです。

## AIを活用した開発の魅力

AIに質問しながら、必要なコードを作成してもらうことで、自分が思い描いたウェブアプリケーションを実現することができました。

今は素晴らしい時代ですね。

生成AIを活用したアプリケーションも、アイデアさえあれば、AIに相談しながら作成できます。
　
- 「どのようなコードを書けばよいか？」と質問すれば、具体的なコードが提示される
　
- 「このコードに問題点や改善すべき点はあるか？」と聞けば、より良い修正案を提案してくれる
　
- セキュリティ面についても、「セキュリティの問題点は？」と尋ねると、適切な対策が示される

## AIを使う上での注意点
　
ただし、AIに頼りっぱなしではなく、コードの意味をある程度は理解しながら進めていくことが重要だと思います。

出力されたコードをそのままコピーペーストするだけでは、わりとすぐに壁にぶつかるはずです。

ですから、AIに「各コードに分かりやすい注釈を付けてください」と依頼すると、理解を深めながら進められます。

 　
認証やセキュリティ対策（例：2段階認証）は特に複雑です。

私の場合、5つほどアプリを作成してようやく基礎的な理解ができた程度です。

アプリを作成・改良する際には、「セキュリティ面で問題点は？」と繰り返しAIに質問し、提案をもらいながら、試行錯誤を繰り返すことが大切です。

## 実際に起きた問題と解決方法
　
アプリを運用していると、問題が発生することもあります。例えば、

### 事例：LINEログインの問題

- AndroidやPCからは正常に動作するが、iPhoneではログインに失敗する現象が発生
　
- AIに問題点を尋ね、様々な提案を試しても解決しなかった
　
- 最終的にセッション管理の設定を sameSite: 'Lax' に変更し、
さらに redis-cli FLUSHALL でRedisセッションをクリアしたことで解決

 　
この経験から学んだことは、AIの提案を鵜呑みにするだけでなく、自分で仮説を立て、試行錯誤しながら検証することが重要だという点です。

sameSite: 'none'　と sameSite: 'None' 
同じような記述でも、iPhoneの場合はその微妙な違いで結果が変わることもあるようです。

# まとめ

　
AIを活用すれば、プログラミング初心者でもウェブアプリを作成できます。しかし、

- コードの基本的な意味を理解する努力は必要
　
- AIの提案を頼りにしつつも、自分で仮説を立てて試行錯誤する姿勢が重要

 　
やはり「AIに任せればラクチン」というわけではありません。
適切に活用しながら、学びを深めていきたいですね
Drizzle ORM で特定のテーブルを管理対象外にする

## 環境

以下の環境で確認しました。

- drizzle-orm: 0.38.4
- drizzle-kit: 0.30.2

## 状況

特定のテーブルを Drizzle ORM の管理対象から外す方法を調べました。

具体的には PostgreSQL の pgvector を利用してる状況で、LangChain の `PGVector` が作成した `langchain_pg_collection` テーブルと `langchain_pg_embedding` テーブルが、Drizzle ORM の管理してるデータベースの同じスキーマに存在していました。

その状況で `npm drizzle-kit push` を実行すると、Drizzle ORM の schema ファイルに上記テーブルが存在しないため、このテーブルを削除しようとします。

## `drizzle.config.ts` の設定

`drizzle.config.ts` で、`tablesFilter` にテーブル名を指定する際、テーブル名の前に `!` を付けることで、そのテーブルを Drizzle ORM の管理対象から除外することができます。

具体的には、以下のように設定します。

:::note info
ワイルドカードを使用できるので `langchain_pg_*` とすることで、`langchain_pg_collection` と `langchain_pg_embedding` を管理対象から外すこともできます。
::::

```ts:drizzle.config.ts
import "dotenv/config";

import { defineConfig } from "drizzle-kit";

import { env } from "./src/env";

export default defineConfig({
  out: "./drizzle",
  schema: "./src/db/schema.ts",
  dialect: "postgresql",
  dbCredentials: {
    url: env.DATABASE_URL,
  },
  tablesFilter: ["!langchain_pg_collection", "!langchain_pg_embedding"],
});
```

drizzle の公式ドキュメントには、`tablesFilter` についての記載はありますが、`!` をつけることで、管理対象から外すことができるという記載は見つけられませんでした。

https://orm.drizzle.team/docs/drizzle-config-file#tablesfilter


GitHub の Discussions で、この方法を書いている方がいましたので参考にしました。

https://github.com/drizzle-team/drizzle-orm/discussions/2410

## そのほかの方法

Drizzle ORM 管理したくないテーブルは、別のスキーマに配置するという方法もあります。
UnityとMadMapperの連携【Unityの出力 (映像) をMadMapperに取り込む】

# ■ 概要
本記事では「Unity」で制作したアプリの出力 (映像)を「MadMapper」に取り込む手順を紹介します。

# ■ 環境
動作環境：Windows 11 Pro
Windowsバージョン：23HS

MadMapperバージョン：5.6.6 Demo

Unityバージョン：Unity2022.3.44f1
プロジェクトテンプレート：Universal 3D


**Unityは「URP」レンダリングパイプラインのプロジェクトを使用しています。**
<font color="#4d4d4d">**（こちらの[プラグインの仕様](https://github.com/keijiro/KlakSpout?tab=readme-ov-file#spout-sender-component)として「URP」もしくは「HDRP」レンダリングパイプラインのプロジェクトである必要があります。）**</font>

:::note info
※ビルトインのレンダリングパイプラインでも、パッケージを後からインストールして変更することが可能です。
[その手順はこちらの記事が参考になります。](https://kingmo.jp/kumonos/unity-urp-in-middle-of-the-project/#google_vignette)
:::

# ■ MadMapper
プロジェクションマッピングやLEDマッピング、ライブビジュアルパフォーマンスのために設計されたソフトウェアです。

```
- プロジェクションマッピング (建築物やランドマークへの映像投影)
- ライブコンサート (映像と照明のタイミング同期)
- ライブパフォーマンス (VJによるリアルタイムビジュアル制御)
- ステージデザイン (舞台背景への映像マッピング)
- インスタレーションアート (不規則な形状の対象物や空間への正確な映像投影)
```

主な用途としてはこれらの目的で使用され、機能も幅広くて品質も高いです。
クロスプラットフォーム対応（macOSとWindowsの両方で使用可能）しており、またMIDI、OSC、Artnet/DMX、NDI、Syphon/Spoutなど、幅広いプロトコルをサポートしているので、他のソフトウェアやハードウェアとの連携がスムーズです。

https://madmapper.com/

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/4490220c-4701-1918-c3bc-ee8709a41296.png" width="">


## ・ インストール

こちらの方の[YouTube動画](https://youtu.be/Weytak8Mbik?si=ftolkxqVwJjncoHs)がとても参考になります。今回はUnityとの連携部分のみの紹介なのでお試し無料版の「Demo Version」をインストールします。
<font color="#4d4d4d">**（無料のデモ版は作業プロジェクトの保存ができなかったり、出力する映像にウォーターマークが付いたりするので業務で使用するには不向き過ぎます…。ただある程度の機能は利用することができるのでお試しやお遊びで利用する分には◎）**</font>

現在の[MapMapperの公式サイト](https://madmapper.com/)とは多少見た目が異なりますがインストールの手順自体は同じなため、動画を見ながら作業を進めれば問題なくインストールできるかと思います。またこちらの動画はインストール手順のみではなくツールの使い方などの初歩的な操作方法も解説してくれています。

# ■ KlakSpout / KlakSyphon
「Spout」とはWindows環境で動作するリアルタイムビデオを共有するOSSです。複数のアプリケーション間でGPUメモリを介して高解像度のビデオデータを直接共有することができます。

[「KlakSpout」](https://github.com/keijiro/KlakSpout)はUnity上で「Spout」を利用してビデオストリームを送受信できるようにするUnityプラグインですので、そちらをインストールしてプロジェクトに適用します。
<font color="#4d4d4d">**（macOSでは[「KlakSyphon」](https://github.com/keijiro/KlakSyphon)を使用します。）**</font>

## ・ インストール

Unityでのセットアップ手順は[プラグインのドキュメント](https://github.com/keijiro/KlakSpout?tab=readme-ov-file#spout-sender-component)に全て記載がありますので、手順通りに実行してインストールします。

# ■ UnityとMadMapperの連携
手順はとても簡単です。

## ① Unityアプリの実行
まずはUnityで作成したアプリ、もしくはUnity Editorを実行します。

## ② 対象のQuadを選択
Unityの映像を反映させたいQuadを選択（①枠内）し、右側インスペクター上のタブ（②枠内）を選択する。

![スクリーンショット 2025-01-21 183901.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/3f33565d-c612-1594-4697-fa411e39d5c5.png)

## ③ 該当の「Spout Sender」を選択
右側インスペクターをスクロールし「Spout」の項目にある該当のSpout Senderを選択する。この手順だけでUnityの映像をMadMapperに取り込むことができます。

![スクリーンショット 2025-01-21 184019.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/cde7f250-cd44-ff19-4e4e-2102f3e245e7.png)

あとはこんな感じでメッシュをいじって、Outの映像をプロジェクター等で投影すればプロジェクションマッピングなどで利用できます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/6f10c195-9223-dcfc-aff3-856dc8b49dbe.gif" width="">

# ■ 最後に （感想）

今回はシンプルにUnityとMadMapperの連携部分にフォーカスして紹介してみました。私自身まだMadMapperは全然扱えきれていないのですが色々マスターすれば様々な用途で活用できそうだと感じました。有料版使いたいです…。笑

最後までご覧いただきありがとうございました。
なぜシングルクオートを使用するのか

# なぜシングルクオートを使用するのか
この記事に至った経緯からだらだらと説明させていただきますが、
コーディング規約上でシングルクオートをメインに使用することの記載が多く、
なぜわざわざ打ちづらい上に、ダブルクオート1つなのかシングルクオート2つなのか分かりづらい、シングルクオートを使うのか?と考えていました。
入れ子にして使用する際など、どちらも使用しないと行けない場面での使用は理解できるのですが、単独での使用に疑問を持っていました。

証言する記事や記載を見つけたわけではないのですが、以下個人的に考え納得した理由を記載します。

## 理由
シングルクオートのほうがダブルクオートよりうちやすいから

前述の打ちにくい位置にあるという話の流れで、???となるかと思いますが、打ちづらい位置にあるのは日本語配列のキーボード入力であって英語配列の入力では打ちやすい場所にあるためです。
英語配列では右下側に位置し、シングルとダブルクオートは同じキーです。
シングルはShiftなしで打てるのに対しダブルはShiftありなので、Shiftなしで打てるシングルのほうが使いやすいよねということで勝手に納得しました。

キーボードの配列は同じとしか思っていなかったため、違いが存在していることにすら気づかず、まったく見えていませんでした。
US配列のキーボードを買ったことにより気が付きましたが、同じように常識だと思っていたこと、間違っていないと思っていたことに違いがあることに気づくだけで、見える世界が変わると感じた今日この頃でした。
簡単コマンドライン(pytest, docker, git)

# はじめに
pytest, docker, gitの備忘録です。
（わすれたらココ見ろ俺。）

## pytest optinon
標準出力: 
```
pytest - s ./test_hoge.py
```
-----------------------------------------------------------
## docker 系コマンドチートシート
```
// dockerデーモン起動
sudo service docker start
```
```
// dockerデーモンステータス確認
sudo service docker status
```
```
// イメージからコンテナの起動＋接続
docker run -it イメージ名 bash
```
```
// 起動済みコンテナへ接続
docker exec -it コンテナ名 bash  
```
```
//Current Directory内のDockerfileをビルドしてイメージ作成
docker build ./
```
```
// コンテナの停止
docker stop コンテナID 
```
```
// コンテナの再起動
docker restart コンテナ名
```
------------------------
## git 系コマンドチートシート
[忘れがちなGitチートシート](https://qiita.com/kurogoma939/items/232e73c905ebe11345ac)
```
// ローカルに存在するブランチの一覧を表示
git branch
```
```
// 指定したブランチに切り替える。
git branch {ブランチ名}
```
```
// 新しいブランチを作成して、そのブランチに切り替える。
git checkout -b {ブランチ名}
```
```
//  指定したブランチを現在のブランチにマージする。
git merge {ブランチ名}
```
```
// リモートリポジトリから変更を取得してマージする。
git pull {リモート名} {ブランチ名}
```
```
// . ローカルのブランチをリモートへの登録
git push -u origin {作成するリモートブランチ名}
```
```
// コミットにまとめたいファイルをステージングエリアへ
git add [ファイル名/ディレクトリ名/--all/-A]
```
```
// ファイルステータス確認(コミットの対象を確認)
git status
```
```
// コミット
git commit -m "[コミットコメント]"
```
```
//  ローカルのブランチをリモートリポジトリにプッシュする。
git push {リモート名} {ブランチ名}
```


```
// プルリクエストの内容をローカルに落とす
git fetch origin pull/｛PR_ID}/head:{BRANCHNAME}
```
たとえば、`git fetch origin pull/20/head:PR-20`

```
// リモートに反映されているbranchをローカルにおとｓ
git pull origin {REMOTE-BRANCH-NAME}:{LOCAL-BRANCH-NAME}
```
個人的な備忘録：git add -p コマンドの基本的な使い方を簡単にまとめて、実際に試してみた

## はじめに
`git add -p` は、コードレビューやコミットの粒度を細かく制御したい場合に非常に便利なツールです。**部分的に変更をステージングすることで、より整理されたコミット履歴を作成できます。**

:::note warn
***ただし、思った以上にプロンプトに表示される選択肢が多かったため、1つの記事として整理したほうが良いと考え、今回投稿してみました。***
:::

なお、この記事は自分用の備忘録としてまとめたものです。**あらかじめその点をご理解いただければ幸いです。**

## 書こうと思ったきっかけ
これまで Git コマンドは、基本的なリポジトリ作成時に表示されるコマンド程度しか使っていませんでした。

:::note info
**しかし、便利なオプションが数多く存在することを知り、こういったツールを積極的に活用したいと思うようになりました。**
:::

そのため、今後自分自身が `git add -p` を使いこなせるよう、記事として体系的にまとめてアウトプットしていきます。

## `git add -p` コマンドについて

`git add -p` コマンドは、Git でステージング（インデックスに追加）する際に、変更を部分的に選択してステージングするためのコマンドです。

このコマンドを使うと、ファイル全体ではなく、変更内容の一部（ハンク）を選んで追加することができます。

## 基本的な使い方

`git add -p` を実行すると、変更内容が「ハンク（hunk）」という小さな単位に分割されて表示されます。

```bash
git add -p
```

各ハンクに対して、以下のような操作を選択するプロンプトが表示されます。

## プロンプトの選択肢について
プロンプトで表示される選択肢が多いと感じたため、それぞれを表形式で整理してみました。必要に応じて参考にしてください。

| キー | 説明                                                                                      |
|------|-------------------------------------------------------------------------------------------|
| `y`  | この削除をステージングに追加する（変更を適用する）                                         |
| `n`  | この削除をステージングに追加しない（変更をスキップする）                                   |
| `q`  | それ以上のハンクの確認を中断する                                                          |
| `a`  | すべての残りの削除をステージングに追加する                                                |
| `d`  | すべての残りの削除をステージングに追加しない                                              |
| `p`  | 削除の一部を選択する（削除に細分化が適用できる場合）                                      |
| `?`  | 使用可能なコマンドのヘルプを表示                                                          |

## 具体的な例について
以下は、削除に関する変更をステージングする場合の例です。

```bash
➜  hello-world git:(main) ✗ git add -p
diff --git a/aa b/aa
deleted file mode 100644
index 72943a1..0000000
--- a/aa
+++ /dev/null
@@ -1 +0,0 @@
-aaa
(1/1) Stage deletion [y,n,q,a,d,p,?]? 
```

このプロンプトは、ファイル `aa` が削除される変更をステージングするかどうかを尋ねています。

- `y` を押すと、この変更がステージングされます。  
- `n` を押すと、この変更はスキップされ、次のハンクに進みます。  
- `s` を押すと、このハンクをさらに分割して、細かくステージングできます。

## まとめ
ここまでお読みいただき、ありがとうございました。***今回は、自分の備忘録としての簡単な内容でしたが、まとめることで知識を体系的に整理することができました。***

:::note info
**こうした基礎的な内容を継続的にアウトプットすることで、自分の知識を深めるだけでなく、必要なときに振り返るための良いきっかけを作りたいと考えています。**
:::

この記事が少しでも皆さんの参考になれば幸いです！
Elementorのメモリ消費をSwapfileで対策する

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417736/1233e736-20fe-eb52-4fe0-20e3286e2827.png" alt="lightsail" width="144">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417736/8e90c4ab-b78f-78b3-58aa-1bfcd987c1b4.png" alt="elementor" width="80">

LightsailのWordPress@BitnamiインスタンスでElementorを入れて固定ページを組んでいるとメモリ消費量が著しく、いつの間にかElementor編集画面を開くだけで数百MBとか、編集画面を保存するとGB単位でメモリを消費するようになっていてインスタンスがハングアップするようになった。

当初、最も小さいインスタンスで十分だったが、メモリだけきつくてだましだましで10USDコースまで引き上げたがまだまだ足りない。この調子ではいくらスケールアップしても安心できない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417736/2798e8b9-47b8-5181-b508-eda4665ff90f.png)
[料金 - Amazon Lightsail | AWS](https://aws.amazon.com/jp/lightsail/pricing/)


Elementorがメモリ食いというのは検索すると情報はあるものの、セーフモードとか再起動とか根本的な対策を探し当てることができず、自力でも何に喰っているのか分からずお茶を濁したロードマップ。

## 試してみたこと

メモリを食いそうな要因についてダイエットを試したがいずれも芯を食ってない。

- 画像のサイズ縮小、圧縮、パララックス解除 → 効果小
- 投稿一覧ウィジェットを削除 → 効果小
- js実装削除 → 効果なし
- 未使用のプラグインをお掃除 => 効果なし

## 結論
[Linuxでスワップ領域を作成する方法](https://qiita.com/youareyouya/items/1f76fd8de74346130395)

メモリがスパイクするのはElementor編集している時だけなので、編集時のスパイクをSwapfileで凌ぐ。

通常のページ閲覧は物理メモリで十分賄えているのでパフォーマンスに影響はない。

```sh:sh
# Swap領域がない状態
free
               total        used        free      shared  buff/cache   available
Mem:         1994048     1204604      625100       56884      164344      603616
Swap:              0           0           0

# 2GBのswapfileを作成して0埋め
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048

# パーミッション設定
sudo chmod 600 /swapfile

# スワップ領域として設定
sudo mkswap /swapfile

# スワップファイルを有効化(マウント)する
sudo swapon /swapfile

# 起動時にswapfileを自動的にマウント
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# swapfileとして認識されたこと
free
               total        used        free      shared  buff/cache   available
Mem:         1994048     1204604      625100       56884      164344      603616
Swap:        2097148      214272     1882876
```
(その5).構造体で遊ぶ。(浮動小数点を含む構造体)(最終章)


x 過去ログを見よ!!!
x M5NanoC6での予定は、未定

目的
浮動小数点数も含む時

いろいろ
浮動小数点数「警察」が　いるらしい
特に、計算誤差や
比較には、うるさいらしい
= は、　ほぼ、禁止らしい
ゲームとかドローンとかは、なぜかアナログデータ(ADCした)
そのまま(浮動小数点)で送っているような気がする?

```c++


#include <iostream>
#include <string.h>  //memcpy
using namespace std;
int main(void){
    // Your code here!
    printf("START\n");
    
    unsigned char ac[256+1];
    
    struct {
        float x;
        float y;
    } X_Y;
    
    X_Y.x = 2.5 * 2.5 * 2.5; //15.625
    X_Y.y = 2.5 * 2.5 * 2.5 * 2.5; //39.0625
    
    unsigned char *c;
    c = (unsigned char *)(&X_Y);

    memcpy(ac, c, (sizeof(float)) * 2); 

    printf("[%x][%x][%x][%x]\n",ac[0],ac[1],ac[2],ac[3]);
    printf("[%x][%x][%x][%x]\n",ac[4],ac[5],ac[6],ac[7]);

    unsigned char *p;
    p = (unsigned char *)(&X_Y);
    
    memcpy(p, ac, (sizeof(float)) * 2); 

    printf("\n");
    printf("[%f],[%f]\n", X_Y.x, X_Y.y);
    
}//main



```


```

START
[0][0][7a][41]
[0][40][1c][42]

[15.625000],[39.062500]

```
【電脳少女プログラミング2088-壊レタ君を再構築-】しました。

# 【電脳少女プログラミング2088-壊レタ君を再構築-】しました。

コーディングでかわいいキャラクターを作りませんか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3981722/dfe831d6-e888-6d13-8c61-bf1d9d071f2e.png)

#### リンクはごちら
https://ppg.paiza.jp/denno2088?dynamic_ogp_image_uid=ecd78072-c6b1-4b33-9216-e9345ad892e6&from=equ




## SRank 問題 (思い出の屋上)

#### 1目の挑戦 : 全探索 (Brute-Force Search / Exhaustive Search)



:::note alert
40/100
失敗
:::

#### 2目の挑戦 : 二分探索 (Binary Search)


:::note info
100/100
成功
:::

#### ps.
BFSも挑戦したが失敗しました。:fearful:


#### 問題リンクはごちら
https://ppg.paiza.jp/denno2088/challenges/denno2088_c_s_01


## CRank 問題 (会員制ジム)
#### SQL
簡単なSQLの問題です。

:::note info
100/100
成功
:::

#### 問題リンクはごちら
https://ppg.paiza.jp/denno2088/challenges/denno2088_s_c_02

## CRank 問題 (ネオン街のクラブ)
重複をなくした文字列の個数出力問題

#### 1目の挑戦 : set()



:::note info
100/100
成功
:::

#### 問題リンクはごちら
https://ppg.paiza.jp/denno2088/challenges/denno2088_c_c_01






## 後記
問題が少ないのと可愛い装飾がいないところが残念だ。
アナリティクスと、ファネルについて

最近個人で Youtubeを始めたので、
「Youtubeアナリティクス」を見ているのですが

・何が課題なのか？
・どう解決するのか？

を考えるためには、アナリティクスで分析するのが
大事だなと思ったので、共有します。

![ファネル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/3acae467-5eb0-eab4-5a6d-e3ce9a92723d.png)

最近、チャンネル登録者が2人増えました。



視聴回数はあるのですが、チャンネル登録者が伸びていません。
理由を調べたいので、個別に課題を見ていきましょう。

### インプレッション数 1.8万回
誰かの画面に私の動画のサムネが表示された回数です。
まったくの新人にしては、1ヶ月に1.8万回もオススメされているのであれば、問題ないと思いますし、努力で増やせるものではないと思います。

### クリック率3.1%
これは100人がオススメに表示された私の動画を見たとして
3人くらいはクリック（タップ）している、ということです。
平均が「5%」ということなので、ややサムネイルは改善が必要です。

これのクリック率が「5%」になれば、視聴回数は556回 → 1000回になります。
これは努力によって変えられる部分です。画像の改善を繰り返せば良いです。


### コンバージョン率0.0036%
平均的な、再生回数に対するチャンネル登録率は
0.1~0.3% ですので、平均に対して大きな乖離があります。

あと30倍はこれを改善するように対策をしないと
チャンネル登録者は増えません。

せめて「チャンネル登録よろしく」と常時表示しておくくらい
施策はやっておかないと平均の 0.1% に到達しないかもしれません。


### 配信の再生時間
自分でアーカイブを見てるから「23分」になっていますが、
ご新規は「5分未満」です。

![新規の離脱.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216132/6022178f-b017-f995-78b6-a7064e6f1567.png)

ライブ配信に来たご新規ユーザーは、5分程度で去っています。
5分単位で面白い配信にしないと、ユーザーが去ってしまう、ということです。
ここも配信に改善の余地ありです。

#### このファネルの分解は仕事にも通じる

何が言いたいのかと言うと、仕事においても
この考え方は、大事にするべきだと思っています。

# （例）「自社サービス内にバナーを置くと → 受注が増える」
というようなアイデアを持ち込む方はいらっしゃいますが、
よく数字で考えてみて下さい。

#### そのバナーは「何万インプレッション」するのか？

ご契約の商談をするとして、商談成約率10％の営業マンを配置して
待っているとして「1成約」を出すためには「10申し込み」が必要です。

お問い合わせのLPから仮に「1％」が申し込みに進むとしたら、
バナーが1000回クリックされる必要があります。

CTR 3%のバナーが作れたとして、これが
33333回【表示】される必要があります。

--
・アクティブユーザーが1人なら、1日1666回表示
・アクティブユーザーが10人なら、1日166回表示
・アクティブユーザーが100人なら、1日16回表示
・アクティブユーザーが1000人なら、1日1.6回表示
・アクティブユーザーが10000人なら、1日0.1回表示

--

で、やっと月1回、成約が発生する計算です。

また月1回のご成約に対してアクティブユーザーは
目標のインプレッション数に届くようにバナーを見せられるので、相当邪魔です。

#### 大前提として
「自社サービス」というのは、
自社サービスをご契約しているユーザーがログインできる「クローズドな場所」
でありますので、限られたアクセスしかありません。


Youtubeで言うと「メンバー限定動画」のような存在です。
売りたいものが「メン限にマッチする」という特性があれば別ですが、
広く一般に売りたい物であれば、バナーを「メン限」に置く必要はありません。

メンバーは、ファンだから、メンバー限定グッズを買ってくれるわけです。

自社サービスのファンだから！と言って別のサービスの直接的なバナーは押さないと思うんですよ。

金の匂いがするYouTuberは嫌われますよ。
メン限に石油王が居るとしたらDMしましょう。

#### つまり？
自社サービスにバナーを置いて、月に1回の受注が発生するか？どうか？
というような、インパクトの薄い施策を考えるくらいなら、

Youtubeや、ブログ、Twitterで発信して、
「3万インプレッション」を稼いだ方が、施策のインパクト高いと思いますし、
クローズドなサービスに置くよりも、施策インパクトが計算として成り立つはずです。

というような事を「データ・ドリブン」で話せると良いですね。
PowerApps コレクション内の重複レコードを省く

# 重複レコードを存在しているコレクション
```
//Create a collection
ClearCollect(myTrucks2,
    {Year: 2020, Make: "Ford", Model: "F150"},
    {Year: 2018, Make: "Chevy", Model: "Silverado" },
    {Year: 2020, Make: "Ford", Model: "F150" },
    {Year: 2020, Make: "Ford", Model: "F150"},
    {Year: 2017, Make: "Nissan", Model: "Frontier"},
    {Year: 2016, Make: "GM", Model: "Yukon"},
    {Year: 2016, Make: "GM", Model: "Yukon"}
);
```
# 重複レコードを省く
```
ClearCollect(mySolution2,ForAll(Distinct(myTrucks2, ThisRecord),ThisRecord.Value));
```
# 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/dc641cb6-20bb-2397-bf16-4f1d80d39415.png)


# 参考サイト
https://www.matthewdevaney.com/powerapps-collections-cookbook/unique-records-in-a-collection/
統計検定2級に出題される検定手法と具体例

統計検定2級では、統計学の基礎的な概念と実務でよく使用される検定手法が出題されます。本記事では、2級の試験範囲に含まれる検定手法を具体例を交えてわかりやすく解説します。
※この記事は、ChatGPTの出力を基に作成しています。

---

## **1. t検定**
t検定は、平均値の差が統計的に有意であるかを確認するための手法です。

### **種類と具体例**
1. **1標本t検定**  
   - **目的**: 標本平均と既知の母集団平均を比較。  
   - **例**: ある学校の平均テスト点数（72点）が全国平均（70点）と異なるかを調べる。

2. **対応のあるt検定**  
   - **目的**: 同じ対象の前後比較を行う。  
   - **例**: ダイエットプログラムの前後で体重に差があるかを確認。

3. **対応のないt検定**  
   - **目的**: 2つの独立したグループの平均を比較。  
   - **例**: 男性と女性の月間ランニング距離に違いがあるかを検証。

---

## **2. z検定**
z検定は、母集団の標準偏差が分かっている場合に使用されます。

### **種類と具体例**
1. **標本平均のz検定**  
   - **目的**: 標本平均と母集団平均の差を調べる。  
   - **例**: 新しい電池の平均寿命（105時間）が既存製品（100時間）と異なるかを検証。

2. **比率のz検定**  
   - **目的**: 2つの割合が有意に異なるかを確認。  
   - **例**: 地域Aの禁煙率が全国平均（30%）と異なるかを調べる。

---

## **3. カイ二乗検定**
カイ二乗検定は、カテゴリデータに関する検定手法です。

### **種類と具体例**
1. **独立性の検定**  
   - **目的**: 2つのカテゴリデータの独立性を調べる。  
   - **例**: 性別と喫煙習慣に関連性があるかを確認。

2. **適合度検定**  
   - **目的**: 観測データが理論分布に適合しているかを検証。  
   - **例**: サイコロが均等に振られるか（1~6が同じ確率か）を調べる。

---

## **4. F検定**
F検定は、2つの母集団の分散が等しいかどうかを確認するために使われます。

### **具体例**
- **分散の比較**: 2つの工場で製造された製品の品質（ばらつき）が等しいかを調べる。

---

## **5. 分散分析（ANOVA）**
分散分析は、3つ以上のグループの平均を比較する手法です。

### **種類と具体例**
1. **1元配置分散分析**  
   - **目的**: 1つの要因によるグループ間の差を調べる。  
   - **例**: 3種類の肥料（A, B, C）が作物収穫量に与える影響を比較。

2. **2元配置分散分析**  
   - **目的**: 2つの要因の主効果と交互作用を調べる。  
   - **例**: 授業形式（オンライン/対面）と性別が試験成績に与える影響を確認。

---
## **6. ノンパラメトリック検定**
データが正規分布に従わない場合に使う手法です。

### **種類と具体例**
1. **ウィルコクソン順位和検定**  
   - **目的**: 2群の中央値を比較。  
   - **例**: 小規模サンプルの満足度スコアを比較。

2. **マン・ホイットニーU検定**  
   - **目的**: 非正規分布のデータで2群の差を比較。  
   - **例**: 2種類の広告効果を小規模サンプルで検証。

---

## **まとめ**
統計検定2級で扱われる主な検定手法とユースケースを以下に整理します：

| 検定手法                | 主な目的                               | 具体例                                       |
|-------------------------|---------------------------------------|---------------------------------------------|
| t検定                  | 平均値の比較                           | ダイエット効果、性別による違い               |
| z検定                  | 平均値や比率の比較                     | 新製品の寿命、地域差の検証                   |
| カイ二乗検定           | カテゴリデータの独立性や適合性の検証   | 性別と喫煙の関連性、公平なサイコロかどうか   |
| F検定                  | 分散の比較                             | 工場間の品質のばらつき                       |
| 分散分析（ANOVA）       | 3群以上の平均値の比較                  | 肥料の効果、授業形式と性別の影響             |
| ノンパラメトリック検定  | 非正規分布データの中央値の比較         | 広告効果、小規模サンプルの違い               |

統計検定2級では、これらの手法の理論だけでなく、実際のデータに基づいた分析や結果の解釈が求められます。過去問やサンプル問題を活用して実践的に理解を深めていきましょう！
【RSpec】クラスでマッチさせようとした場合の注意点

# はじめに
* 特定のタグ、CSS (tailwincss) 要素、特定の文字列が表示されているか否かを検証する capybara の system テストを行った際のミス

# tailwindcss を使用している場合は **`/`** に注意
## 結論
:::note info
* スラッシュ (`/`) をクラスで使用している場合はエスケープする必要がある
```ruby:例) spec/system/XXX_spec.rb
expect(page).to have_css '.w-1\/2'
```

:::

## えらーについ
* 以下のように、特定のタグ、CSS (tailwincss) 要素、特定の文字列が表示されているか否かを検証するで検証しようとした際になぜかエラーが出てしまう

```ruby:修正前
expect(page).to have_css 'button[name="button"][type="submit"].w-1/2.p-2.border.rounded-md.bg-gray-800.text-white', text: '検索'
```

```bash:エラー文
Failure/Error: expect(page).to have_css 'button[name="button"][type="submit"].w-1/2.p-2.border.rounded-md.bg-gray-800.text-white', text: '検索'

     Selenium::WebDriver::Error::InvalidSelectorError:
       invalid selector
       from javascript error: {"status":32,"value":"An invalid or illegal selector was specified"}
         (Session info: chrome=131.0.6778.108); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#invalid-selector-exception
```

## 修正後
* エラー文で `invalid selector` とあるように「CSSセレクタが無効だ」と言われているので、tailwindcss の記述が誤っているであろうと察しがつきます
* 先に結論でも書きましたが『 `/` は別の意味を持つためエスケープする必要がある』という事になります

:::note info
* 以下のリンクで分かりやすく説明されていますが、『background のオプションの区切りを示すために必要となる "/"』『URL における "/"』『除算における "/"』といった意味を持っているためエスケープが必要となる

https://csshtml.work/css-symbol/#i-39

:::

```ruby:修正後
expect(page).to have_css 'button[name="button"][type="submit"].w-1\/2.p-2.border.rounded-md.bg-gray-800.text-white', text: '検索'
```


---
### 参考資料

https://qiita.com/jnchito/items/607f956263c38a5fec24#%E7%94%BB%E9%9D%A2%E3%82%84%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%81%AE%E6%A4%9C%E8%A8%BC

https://qiita.com/kenzan100/items/9642615badc3e1cf160a

https://csshtml.work/css-symbol/#i-39
🌐 NoSQL vs RDBMS: 最適なデータベースの選び方

## 🔍 はじめに
データベースを選ぶとき、「NoSQLとRDBMS、どっちを使えばいいの？」と悩んだことはありませんか？

結論から言うと、
- **データの一貫性**が最優先なら **RDBMS**
- **スケーラビリティと柔軟性**が必要なら **NoSQL**

でも、それぞれの違いや使いどころを知らないと適切な選択はできません。
この記事では、両者の違いを楽しく、分かりやすく解説します！

---

## 📚 1️⃣ RDBMSとは？
### ✅ 特徴
- **データを表（テーブル）で管理**
- **ACID特性（Atomicity, Consistency, Isolation, Durability）を保証**
- **SQLによる強力なクエリ機能**
- **スキーマが厳密に定義される**

### 👉 こんなときに使おう！
| ケース | 例 |
|--------|-----|
| **トランザクションが重要** | 銀行、ECサイト |
| **データの整合性を厳密に保ちたい** | 在庫管理システム |
| **複雑なクエリを実行したい** | 分析・レポート |

**💡 ポイント：データの正確さが命ならRDBMS！**

---

## 📂 2️⃣ NoSQLとは？
### ✅ 特徴
- **スキーマレス（柔軟なデータ構造）**
- **大規模データを水平分散（スケールアウト）しやすい**
- **種類が多い（ドキュメント型、キー・バリュー型、カラム指向型、グラフ型）**
- **ACIDよりもスケーラビリティを重視（BASE原則）**

### 👉 NoSQLの種類と使用用途
| 種類 | 特徴 | 使用用途 | 適したシナリオ |
|------|------|----------|-----------------|
| **キー・バリュー型** | シンプルなキーと値のペアで管理 | キャッシュ、セッション管理（Redis, DynamoDB） | 高速なデータアクセスが求められるセッション情報や設定データの保存 |
| **ドキュメント型** | JSONやBSONなどの構造化データを保存 | CMS、ユーザープロフィール（MongoDB, CouchDB） | ユーザー生成コンテンツや頻繁に構造が変わるデータ管理 |
| **カラム指向型** | 行ではなくカラム単位でデータを管理 | 分析、ビッグデータ処理（Cassandra, HBase） | 大量のデータを並列に処理し、クエリパフォーマンスを最適化するデータ分析システム |
| **グラフ型** | ノードとエッジで関係性を管理 | SNS、レコメンドシステム（Neo4j, ArangoDB） | ソーシャルネットワークやレコメンドエンジン、ネットワーク分析 |

### 👉 こんなときに使おう！
| ケース | 例 |
|--------|-----|
| **大量のデータを高速に処理したい** | ログデータ、センサーデータ |
| **データ構造が頻繁に変わる** | SNSの投稿データ |
| **高可用性が求められる** | 分散システム、キャッシュ |

**💡 ポイント：スケールの大きさと柔軟性ならNoSQL！**

---

## ⚖️ 3️⃣ どちらを選ぶべき？

| 項目 | RDBMS | NoSQL |
|------|-------|-------|
| **データ構造** | 厳密なスキーマ | 柔軟なスキーマ |
| **トランザクション** | 強い | 弱い（種類による） |
| **クエリ性能** | 複雑なクエリに強い | シンプルな検索に最適 |
| **拡張性** | 垂直スケールが基本 | 水平スケールが得意 |
| **ユースケース** | 銀行、EC、在庫管理 | SNS、ログ、分析 |

---

## 🔄 4️⃣ 具体的な選定フロー

1. **データの一貫性が最重要** → 🔹 **RDBMS**
2. **スケールアウトが必要** → 🔹 **NoSQL**
3. **柔軟なデータ構造が求められる** → 🔹 **NoSQL**
4. **トランザクションと整合性が不可欠** → 🔹 **RDBMS**
5. **両方の特性を活かしたい** → 🔹 **ハイブリッド構成も検討**

**🌟 迷ったら、まずは要件を整理しよう！**

---

## 🎯 5️⃣ まとめ
✅ **RDBMSは「整合性とトランザクション」が強み**
✅ **NoSQLは「スケーラビリティと柔軟性」が強み**
✅ **要件に応じて最適なデータベースを選ぶことが重要！**

**💡 迷ったら、要件リストを作成し、最適な選択をしよう！**
【Unity初心者】Unityでネットゲームを作りたい【9】スクリプトの順番～苦手なレイアウトとか

https://qiita.com/ysyss5500/items/4aeb23639a8cf3d67376
### スクリプトの順番
なんか名前の表示がおかしい
前にログインしてた名前になる
毎回新規ログインで試してて気が付いた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/52431918-e12a-422b-143b-9718cadcdc0d.png)
こんな感じで先にJsonから名前を読み込んでるから、変更する前の名前で表示される（何もなければエラー）
どうにかならんかな～と調べました

Namehyouji.cs
```
using UnityEngine;
using UnityEngine.UI;
using static PlayFabLogin;
public class Namehyouji : MonoBehaviour
{
    public new GameObject name = null;
    
    void Start()
    {
        Invoke("Name", 3f);
    }
    
    void Name()
    {
        string inputString = Resources.Load<TextAsset>("playerdata").ToString();
        Pdata playerdata = JsonUtility.FromJson<Pdata>(inputString);
        Debug.Log(playerdata.pdata[0].name);

        // オブジェクトからTextコンポーネントを取得
        Text name_text = name.GetComponent<Text>();
        // テキストの表示を入れ替える
        name_text.text = playerdata.pdata[0].name;
    }

}
```
このように書き換えたら、Json更新してから取得することに成功
3ｆ（３秒）は長いかな？機種の処理速度に依存しそうだから、とりあえずこれで
Invoke　で動き出す時間を指定できるんだね～ﾒﾓﾒﾓ

___
### そして苦手なレイアウトとかデザインとかグラフィックとか

背景がなんかさみしいから動かしてみたい
そういえば最初のほうで勉強した[ちくわ](https://nn-hokuson.hatenablog.com/entry/2016/07/04/213231)さんのブログのところで背景動かしたよな
参照してみた
勉強した時は縦移動だったけど、今回は横に移動させたい
```
using UnityEngine;
using System.Collections;

public class BackgroundController : MonoBehaviour
{
    void Update()
    {
        transform.Translate(-0.001f,0, 0);
        if (transform.position.x < -11f)
        {
            transform.position = new Vector3(11f,0,0);
        }
    }
}
```
でYだったのをXに変えて、動く数字もXの所（X,Y,Z）に入れて、動かしながら数字いじってこんな感じ
![My project - SampleScene - Android - Unity 6 (6000.0.32f1) _DX11_ 2025-01-21 15-34-23.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/2a6fe2aa-2637-cfdb-8c10-d43a5a0bfedd.gif)
ｳﾝｳﾝｲｲｶﾝｼﾞ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/7a9808a2-ddf4-a93a-3dfb-eb7078a93101.png)
これをゆっくり左に移動させてます

ちなみに2つのPCで動作確認した結果、スクロールのスピードが違ってた
んだからスマホで表示した場合。機種によってスクロールのスピード違うかもだ

___
### アイコンとかボタンとか
なんか良いのないかな～とﾁｸﾁｸ
あ、これすごい使えそう
[ヌー@ドット絵素材置き場](http://damagedgold.wp.xdomain.jp/)これすごい！

利用規約(フリー素材版/Free.ver)

基本事項
これらの素材を作者詐称しない(「自分が作った」と言わない)こと
(素材著作権は@damagedgoldにあります)
加工：○
改変：○
配布：加工後・改変後を含め素材だけを主要にするのは×
ゲーム以外での使用：○

金銭授受が発生しない場合(フリーゲーム等の場合)
基本事項を遵守してご自由にお使いください
素材作者名の記載は任意です(載せてくれたらとても助かります)

金銭授受が発生する場合(有料ゲーム・広告等による収入が発生する場合)
基本事項を遵守した上、素材作者名をどこかに明記してください

とのこと
はい！守ります！ありがたく使わせてもらいます！

絵が描けない私には神に見える

←前  [【Unity初心者】Unityでネットゲームを作りたい【8】ビューーの表示を直す～画像ボタンを設置してシーンを切り替えてみた](https://qiita.com/ysyss5500/items/785892928c854f3aa19a)

[【Unity初心者】Unityでネットゲームを作りたい【10】UIのスライダーを使ったスタミナ表示～とりあえずメイン画面に物を置いてみた](https://qiita.com/ysyss5500/items/d07e96027ad50fec198f)　次→

https://qiita.com/ysyss5500/items/4aeb23639a8cf3d67376
文系未経験者の独学日記　＃６

継続力を身につけるのは難しい。

毎日書いていくはずだったQiitaの記事ですが、お正月をまたいですっかり習慣にならない現状です。
記事を書くどころか、勉強さえも手が付けれていないです。反省。

とりあえずやるのが一番効率が良いことも理解しているのですが、だらけてしまいます。

最近はやっとSpringの勉強に突入したので、アプリを作ってみたいですね。
Learning Through Experience

From the rigid realities of a landscape to the shifting motion of the horizon, a collection of symbolic systems shapes our cognition as we navigate and create existence.However, while confronting issues inside the sometimes-stagnating educational system, we neglect our participatory improvisational processes and become oblivious to our spontaneous awareness. We often yield to the intricate dynamics of conventional academic institutions.

Recently, I asked an older student, “Are shapes intrinsic?” She began to provide classifications for shapes, such as round, triangular, spherical, etc. Furthermore, She elaborated on her knowledge of shape-changing interfaces, which transform digital data into physical shapes, enabling users to manipulate and feel the data with their hands and bodies.I was slightly dismayed that she could not comprehend that touch is essential to our identity and activities. There is a lot of information we are still learning and should know.

Current attempts to improve machines with human-like physical senses, such as a study using deep learning to visually represent sounds and a model that forecasts objects’ reactions to physical stimuli, rely on extensive datasets inaccessible for understanding the interplay between vision and touch.What if we strive to establish a novel educational awareness rooted in the landscapes of experiences and utilize a novel aesthetic akin to a choreographic practice that transmits emotion and is reminiscent of solar energy?

What lessons can we glean from Derrida in the present day? Is it possible to condense and elucidate his thoughts into novel instructional practices? Could we develop innovative educational analytical methodologies that allow us to analyze and theorize education with greater accuracy, precision, and authenticity?

I intend to retain these inquiries until I can experience knowledge as a tangible, perceptual, and transforming choreographic practice.
oracleではLIMIT句が使えない

# はじめに
プログラマになり日々の仕事にあっぷあっぷですが
メモがてら書きます。

最近SQLを読むことが増えました！
見慣れない`ROWNUM`という記載を見つけました👀

# oracleってLIMIT句使えない
学習中ずっとMySQLを使用していたので、
oracleで`LIMIT`句が使えないことを初めて知りました！
LIMIT句の代わりに使用するのが、`ROWNUM`だそうです。
2025/2/1追記
Oracle 12c以降では、FETCH FIRST句が使用可能だそうです！


# MySQLのLIMIT句
`LIMIT`句を使用すると、取得する行数を制限できます。

```sql
SELECT * 
FROM employees
ORDER BY hire_date DESC
LIMIT 10;

/*並び替えて、上から10件取得*/
```
```sql
SELECT * 
FROM employees
ORDER BY hire_date DESC
LIMIT 5, 10;

/*並び替えて、6番目から10件取得*/
```

# oracleのROWNUM
Oracleでは ROWNUM を使用して、行番号を取得できます。
ただし、`ROWNUM`は取得する順序に従って番号が振られます。
そのため`ORDER BY`を使用する場合は、サブクエリを使用して`ROWNUM`を適用するのが一般的です。

```sql
SELECT id, name, hire_date 
FROM (
    SELECT id, name, hire_date 
    FROM employees
    ORDER BY hire_date DESC
) 
WHERE ROWNUM <= 10;

/*並び替えて、上から10件取得*/
```

また、オフセットを指定する場合は`ROWNUM`の代わりに`ROW_NUMBER()`を使用します。
```sql
SELECT id, name, hire_date 
FROM (
    SELECT id, name, hire_date, ROW_NUMBER() OVER (ORDER BY hire_date DESC) rn 
    FROM employees
) 
WHERE rn BETWEEN 6 AND 15;

/*並び替えて、6番目から10件取得*/
```

# 2025/2/1追記
Oracle 12c以降では、FETCH FIRST句が使用可能になったことをコメントで教えていただきました！ありがとうございます！
```sql
SELECT *
FROM テーブル名
ORDER BY 列名
FETCH FIRST 10 ROWS ONLY;
```
https://docs.oracle.com/cd/E57425_01/121/LNPLS/release_changes.htm#GUID-7A5871F0-6487-4F06-8F25-118425B88301

https://oracle.programmer-reference.com/oracle-fetch-first/

# おわりに
設計書と睨めっこな毎日です。。
oracle特有なことは、都度調べて引き続き頑張ります！

# 参考

https://sql-oracle.com/?p=1423

https://sql-oracle.com/sqlserver/?p=1234

https://techmania.jp/blog/sql-limit/
テストスイートとは

# 実行したテストの間のこと

常に読み込まれていることを与えましょう。このファイルをできるだけ軽量に保ち続けることを推奨します。
このファイルからひどい依存を要求することはすべてのテスト上のテストスイートのブート時間が長くなるだろう。
例え読み込まれた全てを必要としないかもしれない個々のファイルでも。その代わりこの一つを要求する別々のヘルパーを作成し、実際に必要とするspecsだけ使うことができる
>Given that it is always loaded, you are encouraged to keep this file as
light-weight as possible. Requiring heavyweight dependencies from this file
will add to the boot time of your test suite on EVERY test run, even for an
individual file that may not need all of that loaded. Instead, make a
separate helper file that requires this one and then use it only in the specs
that actually need it.

https://gist.github.com/TiuTalk/551378d3451361be0212#file-spec_helper-rb-L6:~:text=Given%20that%20it,actually%20need%20it

RSpecでrubyアプリケーションをテストする録画した映像はCLIカードゲームの開発を通してrspecライブラリを紹介する。RSpecの技術面をカバーに加えて、使用に対するベストプラクティスをカバーすることでテストの異なるタイプ、テストの内容、さまざまなスタイルの適切な場合のテストスイートの最大限活用についても紹介します。

>The Testing Ruby Applications with RSpec screencast introduces the core RSpec libraries through the development of a small CLI card game. In addition to covering the technical aspects of using RSpec, it also covers best practices for using them so you get the most out of your test suite: different types of tests, what kinds of things to test, when different styles are appropriate.

https://rspec.info/#:~:text=The%20Testing%20Ruby,styles%20are%20appropriate

>before/after blocks defined in configuration are run in order
```rb
require "rspec/expectations"

RSpec.configure do |config|
  config.before(:suite) do
    puts "before suite"
  end

  config.before(:context) do
    puts "before context"
  end

  config.before(:example) do
    puts "before example"
  end

  config.after(:example) do
    puts "after example"
  end

  config.after(:context) do
    puts "after context"
  end

  config.after(:suite) do
    puts "after suite"
  end
end

RSpec.describe "ignore" do
  example "ignore" do
  end
end
```
```
before suite　　↓ここからテストスイートの範囲
before context
before example
after example
.after context
after suite　　　↑
```
https://rspec.info/features/3-13/rspec-core/hooks/before-and-after-hooks/#:~:text=before/after%20blocks%20defined,example%0A.after%20context%0Aafter%20suite

>特定のテストサイクルで実行されるテストケースやテスト手順のセット

https://q-media.jp/test-suite/#:~:text=%E7%89%B9%E5%AE%9A%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88%E3%82%B5%E3%82%A4%E3%82%AF%E3%83%AB%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%95%E3%82%8C%E3%82%8B%E3%83%86%E3%82%B9%E3%83%88%E3%82%B1%E3%83%BC%E3%82%B9%E3%82%84%E3%83%86%E3%82%B9%E3%83%88%E6%89%8B%E9%A0%86%E3%81%AE%E3%82%BB%E3%83%83%E3%83%88

# 感想
英語難しい。
spec_helperは軽くしてなければならないこともわかった
VertiTab 2.15.0 上線：全新ツリー型タブ管理と効率的な作業環境スナップショット切り替え

VertiTabユーザーの皆様へ

VertiTab 2.15.0がリリースされましたことをお知らせいたします！今回のアップデートでは、ブラウザのタブ管理をより効率的にする実用的な機能を多数追加しました：

【主要な機能更新】

###  ツリー型タブ管理
- ドラッグ＆ドロップで簡単にタブの階層を整理
- 親子タブの構造が明確で、ワンクリックで展開/折りたたみ
- グループ間のドラッグ＆ドロップに対応し、タブの所属を簡単に調整
- ホバーメニューでクイックアクションを提供し、整理の効率を向上

![group_tabs_as_tree.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836968/8c48c867-187b-3e3a-21b2-90c4cbf0a562.gif)


###  新しいタブスナップショットシステム
- ワンクリックで現在の作業環境を保存し、サイドバーで異なる作業環境をすばやく切り替え
- スナップショット、ウィンドウ、グループ単位での復元に対応
- 新しいウィンドウで開くか、現在のウィンドウを置き換えることが可能
- スマートなスナップショット管理：
     - 重要なタブの変更を自動保存
     -  プライバシー保護のためのスナップショット暗号化に対応
     -  スナップショットの検索、フィルタリング、並べ替えで素早くアクセス
     - スナップショットのインポート/エクスポートで簡単に移行
     - 
![snapshot_restore.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836968/744c70d9-55c2-1bac-3221-819ba1eea1a3.gif)



###  複数選択と一括操作
- ボックス選択、Shift/Ctrl選択など複数の選択方法
- 一括移動、閉じる、エクスポートなどの操作に対応
- キーボードショートカットで効率的な操作が可能
- 選択数のカウント表示で操作が明確

![tab_selections.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836968/b9f596c2-ed8d-f540-d9f2-dfbeded0aeca.gif)


###  新しいビジュアル体験
- フロストガラス効果でモダンでミニマルな視覚体験を実現
- 背景のぼかし具合を調整して、独自のスタイルを作成
- アイコンとグループスタイルを最適化し、インターフェースをすっきりと
- タブアイコンを非表示にしてより簡潔なインターフェースに
- 
###  パフォーマンスの最適化
- 多数のタブがある場合のパフォーマンスを最適化
- ドラッグと切り替えの動作をよりスムーズに
- 操作フィードバックを改善し、より使いやすく
【新バージョンの入手方法】

[VertiTab - サイドパネルの縦型タブ](https://chromewebstore.google.com/detail/chejfhdknideagdnddjpgamkchefjhoi)

すでにVertiTabをインストールされている場合、ブラウザは自動的に最新バージョンに更新されます。以前にVertiTabをアンインストールされた場合は、上記のリンクから再インストールして新バージョンをお試しください。

日頃からVertiTabをご支援いただき、ありがとうございます！

VertiTabチーム