OmniAICreator/Qiita-1.07M huggingface dataset:
HTML Emmetでエレガントなhtmlライフを、、、

# HTMLをもっと簡単に早く書きたい！
htmlのタグを書くのってめんどいですよね。。。
そんな時に使うのが！！！今回紹介するHTML Emmetです！

## HTML Emmetとは
htmlを効率よく書くために作られた**ショートカットキー**のようなもの
直感的な操作で素早くhtmlの構造を作成できます。
 
## 例1
htmlを書くとき、最初```<!DOCTYPE html>```って書くと思うんですけどvsCode上で以下のように!を入力してEnter押すと
```Demo.html
!
```
こんな感じでhtmlの基本形が出てきますよね！これがまさにEmmetです！
```Demo.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

</body>
</html>
```
## 例2
例えば以下のようにコマンドを打つと、、、
```Demo.html
<body>
    div>p>a
</body>
```
こんな感じで一気にタグを作ってくれるんです！便利ですねぇ
```Demo.html
<body>
    <div>
        <p><a href=""></a></p>
    </div>
</body>
```
## 例3
次はこんな感じでコマンドを打ってみると、、、　お分かりですかね？
```Demo.html
<body>
    <div>
        <p><a href=""></a></p>
        ul>li*3
    </div>
</body>
```
こーんな感じになっちゃいます！
```Demo.html
<body>
    <body>
    <div>
        <p><a href=""></a></p>
        <ul>
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </div>
</body>
</body>
```

余計な説明はしません。皆さんなら直感で書けるはずです！w
なんとなく概要はわかったと思うので、気になる方は

https://docs.emmet.io/cheat-sheet/

このページまで飛んでみてください！色んな記法に出会えると思います！

僕も勉強頑張ります！
それでは！
【AWS】ワイルドカードを活用して、ARN変更によってIAMロール更新が発生しないようにする

# 概要

CloudWatchEventsがAWS Batchのジョブを発行するためにIAMロールを作成しました。
ただし、書き方によってはAWS Batchのジョブ定義を変更するたびにIAMロールも更新されてしまい面倒だったので、ワイルドカードを活用して影響範囲を限定する方法を紹介します。

# IAMロールへの影響
以下Cloudformationが、（別で定義済みの）`BatchJobDefinition`と`BatchJobQueue`のジョブをサブミットする権限を与えるIAMロール。最初、私は以下で良いのだと思っていました。

```yaml
  CloudWatchEventsRoleForBatch:
      Type: AWS::IAM::Role
      Properties:
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
            - 
              Effect: Allow
              Principal:
                Service:
                  - events.amazonaws.com
              Action: 'sts:AssumeRole'
        Path: "/"
        RoleName: CloudWatchEventsRoleForBatch
        Policies:
          - PolicyName: DeleteBatchJobSubmitPolicy
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
                - Effect: Allow
                  Action: 'batch:SubmitJob'
                  Resource: 
                    - !Sub ${BatchJobDefinition}
                    - !Sub ${BatchJobQueue}

  BatchJobDefinition:
    Type: 'AWS::Batch::JobDefinition'
    Properties:
    ## 省略 ##

  BatchJobQueue:
    Type: 'AWS::Batch::JobQueue'
    Properties:   
    ## 省略 ##
```

ただし、上記だと`BatchJobDefinition`や`BatchJobQueue`が変更されるたびにIAMロールにも影響がある書き方です。

例えば、`BatchJobDefinition`の中身を少し変えるとバージョン番号が変わりますが、リソースのARNが変更されてしまうのでその時にIAMロールも更新されます。IAMユーザーの権限次第でIAMロールを更新できない、ということもありますので、依存関係にあるのを修正します。

# ワイルドカードを利用する
修正内容は以下。

```yaml
  CloudWatchEventsRoleForBatch:
      Type: AWS::IAM::Role
      Properties:
        AssumeRolePolicyDocument:
          Version: '2012-10-17'
          Statement:
            - 
              Effect: Allow
              Principal:
                Service:
                  - events.amazonaws.com
              Action: 'sts:AssumeRole'
        Path: "/"
        RoleName: CloudWatchEventsRoleForBatch
        Policies:
          - PolicyName: DeleteBatchJobSubmitPolicy
            PolicyDocument:
              Version: '2012-10-17'
              Statement:
                - Effect: Allow
                  Action: 'batch:SubmitJob'
                  Resource: 
                    - !Sub arn:aws:batch:${AWS::Region}:${AWS::AccountId}:job-definition/*
                    - !Sub arn:aws:batch:${AWS::Region}:${AWS::AccountId}:job-queue/*
```

上記のようにワイルドカードを活用します。
これにより、特定のパターンに一致するすべてのリソースに対してアクセス権限を付与することができ、かつ、ジョブ定義側の変更だけではIAMロールに影響を与えないようにできました。
LLMへの擬似的攻撃と脆弱性を徹底分析してくれる NVIDIA Garakツールとは？

LLMの脆弱性とセキュリティについて、意識していますか？

LLMを利用したアプリケーション開発の依頼もエンジニアにとって身近になってきていますが、LLMへの攻撃やセキュリティ、LLMのテストについては疑問が生じながらも、どうして良いか分からず、実際にはLLMメーカー任せにしているのが実情だと思います。

言語モデル（LLM）とそのセキュリティ対策は日々改善され進化していますが、その一方で、さまざまな攻撃に対する脆弱性は依然として存在します。

LLM自体にも悪意のある攻撃手法が存在します。代表的な手法としては、ジェイルブレイク（脱獄）やプロンプトインジェクションがあり、これらを用いてLLMを誤作動させることで、機密情報を引き出したり、LLMに悪意のある発言をさせたりすることが可能です。このような攻撃は、最終的に訴訟に持ち込まれるリスクを伴います。

そこで注目されるのが、NVIDIAが提供するオープンソースツール「Garak」です。本記事では、Garakの機能や脆弱性スキャンの仕組みについて詳しく紹介します。

## Garakとは？

Garakは、LLMの脆弱性をスキャンするためのツールで、ネットワークセキュリティスキャナーのLLM版とも言える存在です。具体的には、LLMに対して擬似的な攻撃を行い、その脆弱性を評価することができます。Garakを使用することで、開発者は自分のモデルがどのようなリスクにさらされているのかを把握し、適切な対策を講じることが可能になります。

## 脆弱性評価のカテゴリ

Garakは、脆弱性を以下の12のカテゴリに分けて評価します。

1. **モジュール継続 (Module Continuation)**: モデルが会話を続ける能力に関連する脆弱性。
2. **モジュールダン (Module Dan)**: 特定の攻撃手法や悪意のある入力に対する脆弱性。
3. **モジュールエンコーディング (Module Encoding)**: 入力データのエンコーディングに関連する脆弱性。
4. **モジュールグッドサイド (Module Goodside)**: モデルが望ましい応答を生成する能力に関連する脆弱性。
5. **モジュール既知の悪意ある署名 (Module Known Bad Signatures)**: 既知の悪意のある入力やパターンに対する脆弱性。
6. **モジュールリークリプレイ (Module Leak Replay)**: 過去の入力を再利用することに関連する脆弱性。
7. **モジュールLMRC (Module LMRC)**: 特定のリスクや脅威に対するモデルの応答を評価します。
8. **モジュールマルウェア生成 (Module Malware Gen)**: モデルが悪意のあるコンテンツを生成するリスクを評価します。
9. **モジュールパッケージ幻覚 (Module Package Hallucination)**: モデルが誤った情報や虚偽のデータを生成するリスクを評価します。
10. **モジュール実際の公的プロンプト (Module Real Publicity Prompts)**: 公的な情報やプロンプトに対するモデルの応答を評価します。
11. **モジュールスノーボール (Module Snowball)**: 複数の要因が重なり合うことで生じる脆弱性を評価します。
12. **モジュールXSS (Module XSS)**: クロスサイトスクリプティング（XSS）攻撃に対する脆弱性を評価します。

これらの評価を通じて、開発者は自分のモデルがどのような攻撃に対して脆弱であるかを理解し、必要な対策を講じることができます。

## Garakの利点

Garakを使用することで、以下のような利点があります。

- **脆弱性の可視化**: 脆弱性を明確にリスト化し、どの部分が危険であるかを把握できる。
- **セキュリティ対策の強化**: 脆弱性を特定することで、適切な対策を講じることが可能になる。
- **オープンソースの利便性**: 誰でも利用できるため、広く普及しやすい。

## GitHub上のGarakソースについて

GarakのソースコードはGitHubで公開されており、誰でもアクセスして利用することができます。

- NVIDIA Garak: https://github.com/NVIDIA/garak

## Garakの使用方法

Garakは主にPythonで書かれており、使いやすいインターフェースを提供しています。以下は、Garakの使い方の基本的な流れです。

1. **リポジトリのクローン**: GitHubからGarakのリポジトリをクローンします。
   ```bash
   git clone https://github.com/NVIDIA/garak.git
   ```

2. **依存関係のインストール**: 必要なライブラリや依存関係をインストールします。通常、`requirements.txt`ファイルが用意されているので、以下のコマンドでインストールできます。
   ```bash
   pip install -r requirements.txt
   ```

   参考）`requirements.txt`については、私の過去記事で要点を紹介していますので、ご参照ください。

3. **スキャンの実行**: Garakを使用してLLMの脆弱性スキャンを実行します。コマンドラインから簡単に実行できるように設計されています。具体的なコマンドはリポジトリのREADMEに記載されていますので、そちらを参照してください。今後、使い方についてもご紹介する予定です。

4. **結果の分析**: スキャンが完了すると、脆弱性の評価結果が出力されます。これをもとに、どの部分に対策が必要かを検討します。

GarakのGitHubリポジトリには、詳細なドキュメントや使用例も掲載されているため、そちらも一読することをお勧めします。

## 最後に

NVIDIA Garakは、LLMの脆弱性を評価するための強力なツールです。開発者はこのツールを活用することで、自分のモデルの安全性を高め、悪意のある攻撃から守ることができます。GitHub上で公開されているソースコードを利用すれば、誰でも手軽に導入し、脆弱性スキャンを行うことが可能です。今後もLLMの進化とともに、Garakのようなツールの重要性は増していくことでしょう。興味のある方は、ぜひGarakのGitHubページを訪れてみてください。
VMware NSX-T CLIコマンド

現場にて使用したNSXのコマンドを備忘録として残しておきたいと思います。

・ESXiホストにインストールされているVIBをリストで表示する
```
esxcli software vib list
```

・ロードされているシステムモジュールを表示する
```
esxcli system module list
```

・物理NICと詳細を表示する
```
esxcli network nic list
esxcli network nic get -n vmnic#
```

・論理スイッチを表示する
```
show logical-switch list all
```

・Edgeのルーティングテーブルを表示する
```
show edge edgeID ip route
```

・ルーティングログを表示する
```
show log routing [follow | reverse]
```
windows11でCドライブのバックアップをDドライブに保存する

# やりたいこと
CドライブにはOS関係とかドライバとか重要そうなやつだけ残して、アプリとかは全部Dドライブに入れておく。
(CドライブにはDドライブへのシンボリックリンクを置いておく)

こうすればDドライブの内容をまるまるHDDにコピーして**最強のバックアップ環境**を構成できる!!!

![名称未設定ファイル.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820975/0d448bff-9b4b-67a8-833b-2043d13cb0c4.png)

# 事前準備
## Link Shell Extesionダウンロードする
(シンボリックリンク作成するために必要)

https://schinagl.priv.at/nt/hardlinkshellext/hardlinkshellext.html#download

## Dドライブには「C」という名前のフォルダを作成しておく
結構パスがややこしくなるので、Cドライブの中身とおんなじになるようにしておく
![{AD38EA6D-CF94-4A16-B5DD-6CC0F04DF26E}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820975/7bcd209b-9223-a492-8a44-fe76769d8970.png)

# バックアップ作成
1. CドライブからバックアップしたいファイルをDドライブにコピー
![{870F24A2-5092-4A24-91A3-C792A341B59A}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820975/b33bd298-0197-fb9b-d7a0-fcec84f05f58.png)

2. コピーしてきたフォルダを右クリックして一番下の「その他のオプション」を選択
![{355EB9D6-8CF3-4935-8ACE-27F468C83026}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820975/6552e166-be69-2d61-37f8-4672b8d8dc88.png)

2. 「リンク元として選択」をクリック
![{D7739D57-75CA-4083-92F0-CFD53541CAE8}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820975/cc847104-2d64-4191-d57f-0241b2a995fc.png)

3. Cドライブにもともとあったフォルダを削除して、右クリックから「その他のオプション」を選択し、「リンクを作成」の中の「シンボリックリンク」を選択

![{3F61BBDA-BE4C-4DD2-84B8-E0FB0D5FF641}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820975/71f43054-4622-61b7-6347-43803f172373.png)

5.完成
これでシンボリックリンクの作成ができた！！！
![{9DB50939-0243-4735-BFCB-584A197FB993}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820975/59e44c31-6b29-f963-d50a-e4b441941410.png)


# 完成後
「Unity」というシンボリックリンクをクリックすると、CドライブからはあたかもCドライブの中にあるかのように見えている！

![{775A9DC8-E0BD-4FD2-8300-07EC4D651597}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820975/d3c613a5-8ead-fa92-c1f0-922a44464984.png)

ファイルパスも完璧だね！

# これから新たにアプリをインストールするとき
これから新たにインストールするアプリはできるだけDドライブに入れるようにする


# 最後に
研究用PCなどの**絶対に中身が消えてほしくないとき**にご活用ください
100Gbit NIC E810-CQDA2 でハマった話

## 背景
100Gbit Ethernet がデータセンターネットワーク（NW機器）では当たり前に使われるようになり、旬な AI 機械学習基盤では 400G から早くも 800G に移行しつつある昨今ですが、今回初めて 100G NIC（Intel [E810-CQDA2](https://www.intel.co.jp/content/www/jp/ja/products/sku/192558/intel-ethernet-network-adapter-e810cqda2/specifications.html)）を搭載したサーバをセットアップしたら色々ハマったのでメモとして残しておきます。
私の理解が間違っているところがあるかもしれません。ご容赦を。

### いつも通り Ubuntu を入れたら速度が出ない
いつも通り Ubuntu20.04 を入れて iperf で速度試験をしたら 40Gbps 弱ぐらいしか出ない・・・
`MTU を 9000 にしろ` 的なことはいろいろなところで書かれているがどうやらそれだけではなさそう。
データシートを見る限りショートパケットでも 100G 出ることになっている。
なぜだろう。

## 対応ポイントはいくつも
以下順を追って簡単に。
- OS (Kernel)の選択
- ドライバ
- NIC 設定
- トランシーバー
- ベンチマーク（iperf）
- NIC 選定

### OS (Kernel)の選択
結論から言うと Ubuntu20.04 LTS をいつも通り入れたが、まずコレがよくなかった。
Ubuntu22.04 LTS 以降を使うべき。
更に細かく言うと標準カーネルを使うべき。（low latency ではない方が良い）
これは後の ドライバ、 NIC 設定に関連する。

### ドライバ
Ubuntu に含まれている標準 ICE ドライバはNG。
パフォーマンスが悪く、パケットドロップが発生する。
NIC ベンダー純正（Intel）のドライバが必要で、コンパイルしてインストールする。
https://www.intel.co.jp/content/www/jp/ja/download/19630/intel-network-adapter-driver-for-e810-series-devices-under-linux.html

Ansible で構築を自動化する場合これがちょっと面倒。
自分で dkms 対応のパッケージを作るか、都度コンパイルするように Playbook を書くか。

### NIC 設定
上記の OS 選択と Intel 純正 ICE ドライバのインストールができたらようやく環境が整う。
NIC の設定で `割り込みの統合` を設定する。
この設定が Ubuntu20.04 だと出来ない。
また low latency kernel も選択しがちだ。これは高スループットの通信よりもリアルタイム性が高い（高頻度の割り込みが必要な）場合に使用する。100G NIC の場合はむしろ速度低下につながる。
```
ethtool -C eth0 adaptive-rx on adaptive-tx on
ethtool -C eth1 adaptive-rx on adaptive-tx on
```

### トランシーバー
これは未だ未解決。
速度というよりはパケットドロップの話。
Intel 純正の SR4 トランシーバーなのに E810-CQDA2 との組み合わせでドロップが発生する。
ベンダーサポートで交換してもらっても再発する。
他のトランシーバーに替えると直るので闇深そう？


### ベンチマーク（iperf）
iperf 自体がボトルネックになるので注意が必要。
いろいろなところで MTU 9000 とか、iperf を並列実行（-P オプションではなく）とか書かれているが -Z, --zerocopy オプションが重要。CPU 負荷が下がりスループットが上がる。
iperf3 を使った試験では iperf3 自体の並列実行、 -P オプションによる同時コネクション数設定、 -Z オプションの３つ併用で 100G を計測できた。 MTU 9000 は使っていない。


### NIC 選定
E810-CQDA2 は 100G x2 port だが、2ポート合計（カード全体）で 100G しか出ない。
2ポート合計 200G のモデルは E810-2CQDA2 というのが存在する。
この点は気がつかなかったし、データシートをしっかり読まないとわからない。（英語で数千ページある）

## 最後に
まだ未解決のトランシーバー問題があるが、とりあえず 100G は出た。
速度でてないなーと思ったらとりあえずこの辺を確認するのがよさそう。
【Vite × React × TypeScript】Chakra UI v3でグローバルなCSSをあてる方法

# はじめに

お疲れ様です、りつです。

今回はChakra UIのv3でグローバルCSSを適用する方法を調べたので、備忘録も兼ねて残しておこうと思います。

# 前提

Viteで作成したReact × TypeScriptのプロジェクトで実装しています。

また、Chakra UIのインストールは終わっている前提で記載しております。

※ Vite × React環境へのChakra UI v3のインストール方法については以下の記事もご参照ください。

https://qiita.com/ritsu21ctws/items/8035044a11ab6b235ac0

# 方法

## 手順1：テーマ設定用の新規ファイルを追加

https://next.chakra-ui.com/docs/theming/overview#globalcss

> `globalCss` is used to apply global styles to the system.

```react:src/theme/theme.ts
import { createSystem, defaultConfig } from "@chakra-ui/react"

const theme = createSystem(defaultConfig, {
  globalCss: {
    "html, body": {
      backgroundColor: "gray.200",
      color: "gray.500",
    },
  },
})

export default theme;
```

## 手順2：ChakraProviderに作成したテーマを指定

https://next.chakra-ui.com/docs/get-started/migration#update-chakraprovider

> If you have a custom theme, replace `defaultSystem` with the custom `system`

:::note warn
公式ドキュメントのサンプルコードだと`<Provider>`に対して`value`属性を指定していますが、同じ書き方をするとエラーになってしまいました。
以下のページを参考に`<Provider>`内部の`<ChakraProvider>`の`value`属性を修正することで対応しています。
:::

https://www.chakra-ui.com/docs/theming/customization/overview#customization

> update the `ChakraProvider` to use the custom system.

```diff_tsx:src/components/ui/provider.tsx
"use client"

- import { ChakraProvider, defaultSystem } from "@chakra-ui/react"
+ import { ChakraProvider } from "@chakra-ui/react" // defaultSystemのインポートを削除
+ import theme from "@/theme/theme" // 作成したテーマをインポート
import {
  ColorModeProvider,
  type ColorModeProviderProps,
} from "./color-mode"

export function Provider(props: ColorModeProviderProps) {
  return (
-   <ChakraProvider value={defaultSystem}>
+   <ChakraProvider value={theme}> {/* 作成したテーマでdefaultSystemを置き換える */}
      <ColorModeProvider {...props} />
    </ChakraProvider>
  )
}
```

## 補足：App.tsxの内容

```react:src/App.tsx
import { Button } from "@/components/ui/button"
import { HStack } from "@chakra-ui/react"

function App() {
  return (
    <HStack>
      <Button>Click me</Button>
      <Button>Click me</Button>
      <p>テスト文字</p>
    </HStack>
  )
}

export default App
```

# 変更前後の画面

## 変更前

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3911933/f975917e-fbdc-6873-eda7-68a04b96422e.png)

## 変更後

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3911933/6f32a8a1-b733-df4f-3a50-c88212beeb7f.png)

# おわりに

現在参考にしている学習動画がChakra UIのv1を使用していたので、v3でどうやって記述するかを調べました。

バージョンの違いによって他にも書き方が変わっている部分が多いようなので、気をつけながら学習を進めていこうと思います。

# 参考

https://next.chakra-ui.com/docs/theming/overview#globalcss

https://next.chakra-ui.com/docs/get-started/migration#update-chakraprovider

https://www.chakra-ui.com/docs/theming/customization/overview#customization
【AWS】変数設定を使用したステートマシン実装【StepFunctions】

## はじめに
最近のアップデートでステートマシンに変数設定ができるようになりました
これまでのステートマシンの実装ではより上流のステップで出力された値を下流のステップで使用するにはその中間のステップで入力と出力に含めて中継するようなことが必要でしたが
今回の変数を使用することでプログラミングのグローバル変数を使用するように、上流のステップで変数に設定した値は下流のステップで任意のタイミングで入力や出力で使用できるようになります
今回の記事ではその使い方をまとめてみました

↓こんな感じで変数をステップの外部で保持できるイメージ（AWSドキュメントより）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/6234b71f-1209-6e2e-1d90-069cb675c26d.png)

## 設定できる変数の種類
変数は以下のように1つの変数に1つの値を設定するものや、配列、Json形式のような構造体をはじめとしてJson形式で表現できる形で定義できます
`
{
  "foo": 123,
  "bar": ["a", "b", "c"],
  "car": {
      "cdr": true
  }
}
`
【StepFunctionsのビジュアルワークフローで設定した画面】
↓変数を設定したいステップを選択して「変数」タブを選択して変数を設定する
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/93b0ea07-6294-b4b1-6bde-dbe9383fd7be.png)


## 変数の呼び出し方
呼び出すときはJsonPathであれば下記のような構文で呼び出します
`
"【キー】": "{% $【呼び出したい変数名】%}"
`
固定値設定の変数呼び出し例(設定例では「123」が参照される）
`
{
  "data": "{% $foo  %}"
}
`
配列設定の変数呼び出し例(配列の2番目の値(設定例では「b」)が参照される）
`
{
  "data": "{% $bar[1]   %}"
}
`
構造体定の変数呼び出し例(設定例では「true」が参照される）
`
{
  "data": "{% car.cdr  %}"
}
`
## 実際に動かしてみた①上流ステップの変数を下流ステップの出力で呼び出す
### 設定①上流ステップで変数の設定
※この例では1ステップ目で変数を設定
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/31407d94-f14c-b744-29e0-769d9d5d884d.png)

### 設定②最終ステップで変数の内容出力
※この例ではLambdaの出力と一緒に、最終ステップの出力で配列変数の2番目の値を呼び出す
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/abead2f5-931f-de10-5ae9-493b1c137a46.png)


### 設定③ステートマシンの実行結果を確認
Lambdaの処理結果「result」と一緒に、設定したキー「data」の値として変数の値「b」が出力された
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/2a3fad3c-fd11-6dfd-2ec9-66a481a8c74c.png)


## 変数を途中で変更するには
ステートマシンのあるステップの出力結果を使って値を更新したい場合
例：2番目のステップの結果の値を変数に設定する
###  ①2番目のステップのLambda(12345を結果として返す)
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/8505943f-fdcf-355f-2454-98ff3c840ac3.png)


### ②ステートマシンの編集画面にて、2番目のステップの変数設定で結果を設定する
`
{
  "foo": "{% $states.result.Payload.body.valueToPass %}"
}
`
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/92e5dcb9-6bdf-8c9b-adb0-dd941fb1cb55.png)
### ③最後のステップの出力結果を設定した変数にする

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/a9260819-c30f-1c4c-48bc-efd0431b5567.png)

### ④結果：2番目のステップで設定した値が出力されることを確認

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/470de7cc-6b23-556e-b275-e5289e1dd6ca.png)

### 余談：2番目のステップの結果なのに2番目のステップで変数設定する理由は？
AWSドキュメントに記載がありましたが、変数の設定が該当のステップの処理の最後になるため、
2番目のステップの結果を変数に設定したいときは2番目のステップの中で設定します

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192949/1b277f5b-99a9-04cf-a7b1-3f0e59b7bbf4.png)

## 思いつくユースケース 
思い付きレベルですが、応用できるユースケースを記載しておきます。
他に良い使い方があれば教えて下さい

【思い付きユースケース例】
・エラーなどのメッセージをDBではなく変数として上流で設定しておき、ステートマシンの中で必要な時に適宜呼び出す
・データの種類ごとに変数を用意しておき、ステートマシン中の計算結果を変数に積み上げる
など

## さいごに
昔ステートマシンの実装の際に上流の結果を下流に流すときにかなり苦労した気がします
上流で設定した変数を下流のどこでも呼び出せる今回のアップデートは、ステートマシン実装の簡略化やプログラムの可読性を向上させるのに嬉しいアップデートだと思います


## 参考URL

AWSドキュメント
https://docs.aws.amazon.com/step-functions/latest/dg/workflow-variables.html
クラメソさんの記事
https://dev.classmethod.jp/articles/step-functions-variables/
BevyEngineのスケジュール種類まとめ(0.14)

## add_systems(ScheduleLabel, IntoSystemConfigs<M>)
- ScheduleLabel
実行するタイミングを指定する
- IntoSystemConfigs<M>
指定したタイミングで実行する処理
とりあえず関数入れればよし

## ScheduleLabel種類
参考：https://docs.rs/bevy/latest/bevy/app/struct.Main.html

- 最初に一度だけ呼ばれる
    1. PreStartup
    2. Startup
    3. PostStartup
- ゲームループ
    1. First
    2. PreUpdate
    3. Update
    4. PostUpdate
    5. Last
- 固定フレーム(デフォルトは64Hzでループする)
    1. FixedFirst
    2. FixedPreUpdate
    3. FixedUpdate
    4. FixedPostUpdate
    5. FixedLast

# 固定フレームの更新頻度を変更する方法
Appに`insert_resource(Time::<Fixed>::from_seconds(0.5))`で0.5の箇所を変更すればよい
```
use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .insert_resource(Time::<Fixed>::from_seconds(0.5))
        .run();
}
```
Linux Mint wi-fi 接続

AC650を購入したのですが、makeで失敗しました。
UGREEN Wi-Fi 無線LAN 子機 AC650です。
1599円　どぶに捨てました。
再度　KIMWOOD wifi usb 1300Mbps USB3.0 無線lan 子機 2.4G/5G デュアルバンド 5dBi超高速通信 wifi 子機 360°回転アンテナ
1899円で購入してチャレンジ。

参考サイトです。

https://take6shin-tech-diary.com/ubuntu-wifi/

子機は以下
https://amzn.to/3B9RcR1

それでは以下を実行

```
sudo apt update
sudo apt install dkms build-essential git
git clone https://github.com/RinCat/RTL88x2BU-Linux-Driver.git
cd RTL88x2BU-Linux-Driver
make
sudo make install
```

問題なし、再起動でいけた。明日からは　無線ＬＡＮの構築だ。
ラズパイの電源いれてやるぞ。
Rを学びたい Step14 共分散,相関係数

## はじめに
Rを学びたい Step14です！今回は共分散、相関係数を学んでいきます！！

## 共分散とは？
2つの変数がどのように一緒に変動するかを測る指標です。

```math:
\text{Cov}(X, Y) = \frac{1}{n} \sum_{i=1}^n \left( X_i - \bar{X} \right) \left( Y_i - \bar{Y} \right)

```

```math
\begin{align*}
&\bullet \ X \text{ と } Y: \text{2つの変数} \\
&\bullet \ X_i, Y_i: X \text{ と } Y \text{ のそれぞれのデータ点} \\
&\bullet \ \bar{X}, \bar{Y}: X \text{ と } Y \text{ の平均値} \\
&\bullet \ n: \text{データの個数}
\end{align*}
```

→共分散だけだと結局何を示しているのかよくわからんですね。相関係数のための値なので、相関係数も一緒に学びます。

## 相関係数
2つの変数の間にどのような関係があるか（強さと方向性）を示す指標です。値は **-1から1の間**をとり、次のように解釈します。


1. 相関係数の範囲と意味

	•	r = 1
→ 完全な正の相関。
例: X が増えると Y も比例して増える。
	•	r = -1
→ 完全な負の相関。
例: X が増えると Y は比例して減る。
	•	r = 0
→ 相関なし。
例: X と Y は独立しており、関係がない。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/6be79013-22f5-dfa2-e907-9cd40fc46dec.png)


```math
r = \frac{\text{Cov}(X, Y)}{\sigma_X \cdot \sigma_Y}
```

```math
\begin{align*}
&\bullet \text{Cov}(X, Y): X と Y の共分散（2つの変数がどれだけ一緒に動くか）。 \\
&\bullet \sigma_X, \sigma_Y: X と Y の標準偏差（それぞれの変数のばらつき）。 \\
\end{align*}
```

## 結局なんなの？？共分散と相関係数
共分散、相関係数は公式としては理解できるのですが、結局なんなの？？🤔という感じでした。
そもそも相関係数がなぜ必要なのかという事を想像してみるといいかもしれません。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/41bc53d4-9d15-fba4-b276-76541ec0c6ac.png)

例えば、上記のような散布図があった場合、これはHeightに対してWeightは相関関係があるのか？と言われた時に、どうでしょうか？？
なんとなく、左下から右下に伸びているので相関関係がありそうですね。ただ、これがどれくらい相関関係があるのかは判定できないです。言葉で伝える事はできないので、**この図を見てください！！**って言うしかないですが、毎回**この図を見てください**はちょっと辛いですね。😅
そこで評価しやすい指標が必要であり、それが　**相関係数**です！
　相関関係は**向き**と**大きさ**を示しております。

次にどうやって相関関係を示すのか？？
Xが大きくなるとYも大きくなり、Xが小さくなればYも小さくなります。第1象限、第3象限にあれば正の相関があり、第2象限、第4象限にあれば負の相関があると言えます。

第1象限~第4象限の値の総和を点の総数で割った物が**共分散**、共分散を標準化して-1~1の間に収めたものが**相関係数**です！！

これを下記のような図に表します。
![スクリーンショット 2024-11-25 19.38.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/cdb74ffc-2137-3840-63b2-6d9c728e9794.png)

## ソースコード
では実際にRで共分散、相関係数を算出したいと思います。

問題
ある夏、アイスクリーム屋さんの店長さんが、売上と気温の関係を示してください。次のようなデータを1週間分集めました：
	•	気温（°C）: 25, 27, 30, 32, 35, 37, 40
	•	売上（個数）: 100, 120, 140, 150, 170, 180, 200

```R:
# 気温（X）と売上（Y）のデータ
temperature <- c(25, 27, 30, 32, 35, 37, 40)  # 気温
sales <- c(100, 120, 140, 150, 170, 180, 200)  # 売上個数

# 共分散の計算
covariance <- cov(temperature, sales)
print(paste("Covariance:", covariance))

# 相関係数の計算
correlation <- cor(temperature, sales)
print(paste("Correlation coefficient:", correlation))

# プロットして可視化
plot(temperature, sales, main = "Relationship between Temperature and Ice Cream Sales",
     xlab = "Temperature (°C)", ylab = "Sales (Units)", pch = 16, col = "blue")
abline(lm(sales ~ temperature), col = "red")  # 回帰直線
```
```shell:実行結果
[1] "Covariance: 187.857142857143"
[1] "Correlation coefficient: 0.996994429431045"
```

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/c02897de-95a5-24bb-5585-6db3ae3e64a9.png)
[Unity] MasterMemory で FormatterNotRegisteredException が出たときの対応

Unity で [Master Memory](https://github.com/Cysharp/MasterMemory) を使用したときに以下のエラーが発生

```
FormatterNotRegisteredException: 名前空間.XxxData is not registered in resolver:
MessagePack.Resolvers.StandardResolver
MessagePack.FormatterResolverExtensions.Throw (System.Type t, MessagePack.IFormatterResolver resolver) (at Assets/Scripts/MessagePack/IFormatterResolver.cs:73)
```

## 結論

以下のコード追加が必要だった

```c#
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static async UniTask Initialize()
{
    var messagePackResolvers = CompositeResolver.Create(
        MasterMemoryResolver.Instance,
        GeneratedResolver.Instance,
        StandardResolver.Instance
    );
    var options = MessagePackSerializerOptions.Standard.WithResolver(messagePackResolvers);
    MessagePackSerializer.DefaultOptions = options;
```

しかし <code>GeneratedResolver.Instance,</code> の行でエラーになる
この Resolver を作成するのに以下の実行も

```
mpc -i Assembly-CSharp.csproj -o [出力先フォルダパス]
```

これで <code>GeneratedResolver.Instance,</code> が通るようになる

### 補足

mpc が実行できるのは MessagePack.Generator をインストールしているため
```
dotnet tool install --global MessagePack.Generator

dotnet tool list -g
パッケージ ID                    バージョン        コマンド
-----------------------------------------------------
mastermemory.generator      2.4.4        dotnet-mmgen
messagepack.generator       2.5.192      mpc
```

この辺りの手順は [Master Memory](https://github.com/Cysharp/MasterMemory) に書かれている
MELSEC 制御ネットワークの種類 CC-Link IE

# CC-Link IE

Ethernetベースの通信規格でありコネクタやケーブルは汎用品が使用可能です。
CC-Link IEのIEとはIndustrial Ethernetの略です。
他のEthernetプロトコルと混在利用可能なのはCC-Link IE TSNとCC-Link IE Field Basicのみでその他は混在不可です。
CC-Linkという名前ですが従来のRS-485ベースのCC-Linkとは互換性はありません。
規格が複数あるがホームページの説明がわかりにくいと私は思います。

https://www.cc-link.org/ja/cclink/cclinkie/index.html


CC-Link IE対応のユニットも何がどの規格に対応してるかわかりずらいので表にしました。
こうしてみると三菱型式命名ルールの法則性が見えてくるような…

|  | CC IE<br>TSN<br>(E) | CC IE<br>TSN<br>(光) | CC IE<br>Control<br>(E) | CC IE<br>Control<br>(光) | CC IE<br>Field<br>(E) | 備考 |
| - | :-: | :-: | :-: | :-: | :-: | - |
| RJ71GN11-T2 | ○ |  |  |  |  |  |
| RJ71GN11-SX |  | ○ |  |  |  |  |
| RJ71GN11-EIP | ○ |  |  |  |  | EtherNet/IP<br>対応 |
| RJ71EN71 |  |  | ○ |  | ○ |  |
| RnENCPU |  |  | ○ |  | ○ |  |
| RJ71GP21-SX |  |  |  | ○ |  |  |
| RJ71GP21S-SX |  |  |  | ○ |  | 外部供給<br>電源機能 |
| RJ71GF11-T2 |  |  |  |  | ○ |  |
| RJ72GF15-T2 |  |  |  |  | ○ | リモートヘッド<br>ユニット |
| FX5-CCLGN-MS | ○ |  |  |  |  |  |
| FX5-CCLIEF |  |  |  |  | ○ | ローカル局のみ |
| QJ71GP21-SX |  |  |  | ○ |  |  |
| QJ71GP21S-SX |  |  |  | ○ |  | 外部供給<br>電源機能 |
| QJ71GF11-T2 |  |  |  |  | ○ |  |
| LJ71GF11-T2 |  |  |  |  | ○ |  |
| LJ72GF15-T2 |  |  |  |  | ○ | リモートヘッド<br>ユニット |
| KV-XLE02 |  |  |  |  | ○ | ローカル局のみ |

(E)=Ethernetケーブル仕様
(光)=光ファイバー仕様(1000BASE-SX)
CC IE=CC-Link IE

プロセスCPUなどはCC IE TSNやCC IE Control(E)が使えなかったりします。
詳しくはMELSEC iQ-R ユニット構成マニュアルを参照してください。(SH-081222)

## CC-Link IE TSN
TSN(Time-Sensitive Networking)はEthernetの拡張規格であり、リアルタイム通信,高精度同期通信,プロトコル混在,通信帯域制御を実現する機能です。
CC-Link IE TSN以外にもPROFINET over TSNやOPC UA over TSNといった通信規格も存在します。
他のTSNとは混在通信が可能ではあるが互換性はありません。
従来のCC-Link IE Fieldに比べモーション制御の高速化が可能です。三菱としてはEtherCATの対抗として普及させたいようです。
ファームウエアアップデートにより追加された、LB/LW点数拡張機能によりリンク点数を増やすことも可能です。
ライン型、スター型、リング型の接続が可能です。(光ファイバーはリング型のみ)

https://www.cc-link.org/ja/cclink/cclinkie/cclinkie_tsn.html

<iframe width="560" height="315" src="https://www.youtube.com/embed/mT72G8xo6Nk?si=HCcbdvqnv1ikEzyq" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## CC-Link IE Control
MELSECNET/HのEthernet仕様でありリンクの設定方法は似たような内容です。旧名称はMELSECNET/Gらしい
(LB,LW,LX,LYの割り付けと各局送信範囲の設定)
ローカル局間でもサイクリック通信でデータ送受信が可能です。
当初は光ファイバー仕様のみでしたがRJ71EN71でEthernetケーブル仕様も追加されました。
ライン型、スター型、リング型の接続が可能です。(光ファイバーはリング型のみ)

https://www.cc-link.org/ja/cclink/cclinkie/cclinkie_c.html

## CC-Link IE Field
CC-LinkのEthernet仕様でありリンクの設定方法は似たような内容です
(RX,RWr,RY,RWwの割り付けと各局送信範囲の設定)
ライン型、スター型、リング型の接続が可能です。

ControlとFieldの違いは以下のように感じました
・Control PLC間接続しかできない。1ネットワークあたりの最大リンク点数が多い。ユニット価格高。
・Field 接続可能な機器が多い。1ネットワークあたりの最大リンク点数が少ない。ユニット価格安。

https://www.cc-link.org/ja/cclink/cclinkie/cclinkie_f.html

## CC-Link IE Field Basic
汎用EthernetのUDPベースで作られており安価でネットワークが組めます。
良い規格ではあるのですが問題は対応製品が少ない事です。
対応製品が多いとCC-Link IE Fieldが売れないからという理由でしょうか。
残念ながらPLC同士の通信には使えません。
MELSEC iQ-RでもR120PCPUなどのプロセスCPUではCC-Link IE Field Basicのロゴがついてなく使用不可能です。

https://www.cc-link.org/ja/cclink/cclinkie/cclinkie_f_b.html
型ガード（Type Guard）の基礎

TypeScriptの学習メモ。
Type Guardの基本的な手法をまとめる。

## Type Guardとは？
端的に説明すると、型の絞り込み。
型が複数考えられる場合、型を特定したいときに行う。

# typeofを使用した型ガード
typeopfで型を判別し、早期リターンすることで絞り込む。

```typescript
export const foo = (value: string | number) => {
  if(typeof value === 'string'){
    return value // string
  }
  return value // number
}
```

## JSのメソッドで型ガード
```typescript
export const foo = (value: string | string[]) => {
  if(Array.isArray(value)){ // Array.isArrayで引数が配列かどうかを判断
    return value // string[]
  }
  return value // string
}
```

## 論理否定演算子を使用
```typescript
export const foo = (value?: string) => { // string | undefined
  if(!value){ // 論理否定演算子を使用することで、valueがfalsyな値の場合にtrueになる
    return
  }
  return value
}
```
※falsyな値
・false
・0, -0
・空文字
・null
・undefined
・NaN
・0n

## in演算子
```typescript
type UserA = { name: string }
type UserB = { name: string, age: number }

export const foo = (value: UserA | UserB) => {
  if('age' in value){ // valueの中に'age'があるかを検証
    return value // userB
  }
  return value // userA
}
```

## タグ付きUniton Types
・別名で「Discriminated Union」「Tagged Union」とも呼ばれる。
・in演算子はプロパティをもとに型を検証するので、検証対象の型定義が同じプロパティの時は使えない。
```typescript
type UserA = { name: string, type: 'customer' }
type UserB = { name: string, type: 'admin' }

export const foo = (value: UserA | UserB) => {
  if(value.type === 'admin'){
    return value // UserB
  }
  return value // UserA
}
```
Switch文でも使える。
```typescript
type UserA = { name: string, lang: 'ja' }
type UserB = { name: string, lang: 'en' }
type UserC = { name: string, lang: 'fr' }

export const foo = (value: UserA | UserB | UserC) => {
  switch (value.lang){
    case 'ja': {
      return value // UserA
    }
    case 'en': {
      return value // UserB
    }
    case 'fr': {
      return value // UserC
    }
    default: {
      throw Error('lang is not defiend') // いずれの型にも当てはまらない場合はエラーを出す
    }
  }
}
```
CONDAでROOTを利用する方法と原因(apple silicon MAC向け)

## 動機
この記事を書こうとしたきっかけとして、anacondaで
```bash:bash
conda install conda-forge::root 
```
とインストールしたROOTを動かした際に、clangとcilingでエラーが起きたため、その回避方法を探してもどこにもなかったからです。私の目的として、検出機解析用にROOTと天体解析ようにHEASOFTをダウンロードする必要があり、その際にAnaconda環境が必要でした。(このような特殊な状況でもない限り、避けた方がいいです)
## 環境
以下の環境をpyenvで一括管理しています。(やり方は追記に書きました)
|アプリケーション|versions|
|:-:|:-:|
|Python|3.13.0|
|ROOT|6.32.08|
|Anaconda|Anaconda3-2024.10-1|

ROOTはhomebrewでインストールしました。Pythonはanaconda環境のもので、ROOTに対応させるため、3.13.0を選択しました。
※Clangをanacondaに入れますが、Clang++を入れてはいけません。

## AnacondaでROOTを利用する方法
### 1. homebrewでROOTを用意します
```bash:bash
brew install ROOT
```
以下でPATHを繋げます
```bash:bash
export ROOTSYS=$(root-config --prefix)
source $(root-config --prefix)/bin/thisroot.sh
```

### 1. 以下の設定で環境を設置
```bash:bash
conda create -n <env name> python=3.13 clang llvm -c conda-forge
conda activate <env name>
```
### 2. condaの環境で用いているclangをデフォルトにする
以下をシェルに書くことで設定する
```bash:bash
export CC=/path/.../pyenv/versions/anaconda3-2024.10-1/envs/heasoft/bin/clang
```
### 3. import ROOTしてみる
以下のようにactivateした後の環境でROOTのパスを再び繋げ直す
```bash:bash
export ROOTSYS=$(root-config --prefix)
source $(root-config --prefix)/bin/thisroot.sh
```

その後、pythonを開いてimport ROOTをするとうまくいきます

## 原因

なぜconda-forgeでインストールしてもうまくいかないのでしょうか。一言で言うと、conda-forgeでは入るROOTはx86-64用のものしか提供されていないため、この方法でダウンロードしてもうまくいきません。しかし、実際にダウンロードした方はわかると思いますが、ROOT単体では実行できます。これはなぜでしょう?

conda-forgeは内部でx86-64アーキテクチャで統一されており、そのパッケージはx86-64プラットフォーム専用にビルドされているため、ARMやM1/M2チップなど他のアーキテクチャでは正常に動作しない場合があります。このため、異なるアーキテクチャ向けにはパッケージの互換性がなく、conda-forge経由でインストールしてもうまくいかないことがあります。

### ROOT単体とPyROOTの違い

ROOTはC++で作成された高性能のデータ解析ライブラリで、グラフィカルインターフェースやコマンドラインで動作します。これに対して、**PyROOT**はPythonからROOTのC++コードにアクセスできるインターフェースを提供するライブラリですが、PyROOTがうまく動作しない場合もあります。

#### 1. **ROOT単体は動作するがPyROOTが動作しない理由**
- **依存関係の違い**: ROOT単体はC++ベースで動作しており、コンパイル時にアーキテクチャに合わせたバイナリが生成されます。これに対して、PyROOTはROOTのC++ライブラリをPythonから操作するため、**Pythonの依存関係やPythonバージョンによって動作に不整合が生じる**ことがあります。特に、PythonとC++のライブラリのリンクの問題や、必要なパッケージが不足している場合にエラーが発生します。


- **アーキテクチャの不一致**: `conda-forge`でインストールしたPyROOTは、x86-64アーキテクチャ専用のバージョンが提供されており、ARMやM1チップなど、異なるアーキテクチャではPyROOTが正しく動作しないことがあります。これは、PyROOTが依存しているC++ライブラリがアーキテクチャに依存しているためです。

#### 2. **ROOT単体が動作する理由**
ROOT単体はC++のネイティブコードで動作しており、依存関係も直接的にC++ライブラリにリンクされます。このため、必要なライブラリや依存関係が正しく満たされている限り、ROOT自体はその環境で問題なく動作します。特に、**x86-64アーキテクチャ用にビルドされたROOTのバイナリ**は、コンパイルされたアーキテクチャに最適化されているため、問題なく動作することが多いです。


### 3. **まとめ**
conda-forgeでROOTやPyROOTをインストールする際の問題は、主に提供されるパッケージがx86-64アーキテクチャ向けに特化しているため、異なるアーキテクチャに対するサポートが不足していることが原因です。また、PyROOTが動作しない理由は、Pythonのバージョンや依存関係の不整合、アーキテクチャの違いによる問題が考えられます。


## 追記
### Anacondaを入れたPythonの環境作成
とりあえず、pyenvをhomebrewでインストールします
```bash:bash
brew install pyenv
```

次にpyenvでAnacondaをインストールします。
```bash:bash
pyenv install anaconda3-2024.10-1
```

globalに設定した後、condaをデフォルトにするようにシェルに書きます。
```bash:bash
pyenv global anaconda3-2024.10-1
pyenv init [shellの名前(zshとかbashとか)]
```
シェルを再起動し、上記の方法で進めてください
エイリアスメソッドの定義

# lengthとsizeはエイリアスのメソッド
```rb
irb(main):001> s = "Hello"
=> "Hello"
irb(main):002> s.length
=> 5
irb(main):003> s.size
=> 5
```
# エイリアスメソッドの定義法
`alias 新しい名前 元の名前`

```rb
irb(main):004* class User
irb(main):005*   def hello
irb(main):006*     'Hello!'
irb(main):007*   end
irb(main):008*
irb(main):009*   alias greeting hello
irb(main):010> end
=> nil
irb(main):011> user = User.new
=> #<User:0x00000001109b05d0>
irb(main):012> user.hello
=> "Hello!"
irb(main):013> user.greeting
=> "Hello!"
```
上の例では`hello`と`greeting`がエイリアスメソッドに設定されている

https://gihyo.jp/book/2017/978-4-7741-9397-7
グローバル変数

# グローバル変数は書き変わってしまうからあまり使わない
```rb
irb(main):001> $program_name = "Awesome program"
=> "Awesome program"
irb(main):002>
irb(main):003* class Program
irb(main):004*   def initialize(name)
irb(main):005*     $program_name = name
irb(main):006*   end
irb(main):007*
irb(main):008*   def self.name
irb(main):009*     $program_name
irb(main):010*   end
irb(main):011*
irb(main):012*   def name
irb(main):013*     $program_name
irb(main):014*   end
irb(main):015> end
=> :name
irb(main):016> Program.name
=> "Awesome program"
irb(main):017> program = Program.new("Super program")
=> #<Program:0x000000010d0ce1b8>
irb(main):018> program.name
=> "Super program"
irb(main):019> Program.name
=> "Super program"
irb(main):020> $program_name
=> "Super program"
```

>プログラミング経験がある程度の人はご存知だと思いますが、グローバル変数の濫用は理解しづらいプログラムの原因になります。何かと特別な理由がない限り、グローバル変数に依存するようなプログラムを書くことは避けるべきです。

https://gihyo.jp/book/2017/978-4-7741-9397-7
ポートフォリオ作成時メモ　part8 ~Google Maps API~

## はじめに
こんにちは、未経験からエンジニア転職を目指しているものです。
オンラインスクールで本格的に学習して6ヶ月目に入りました。PHP,Laravelを学習しポートフォリオを作成中です。ポートフォリオ作成手順及び、エラー内容を中心に記録していこうと思います。今回は投稿画面にGoogle Maps APIを埋め込む手続きを行いました。

## 概要
Laravel Sailを使った開発環境で、Google Maps APIを利用して地図を描画しようとした際に、いくつかの問題に直面しました。

- `google.maps.Marker`を使用した際に問題が発生、その原因
- `AdvancedMarkerElement`で地図描画に成功
- Laravel Sail環境でnpmを使ったモジュール管理の導入、その効果
- 環境変数`VITE_GOOGLE_MAPS_API_KEY`の必要性


## 経緯と問題点

### 1. `google.maps.Marker`使用時に問題が発生
初めは、`google.maps.Marker`を使って地図上にピンを立てようとしました。しかし、以下のような問題に直面しました：

- **エラーメッセージ**：「`InvalidValueError: initMap is not a function`」や`REQUEST_DENIED`が表示される
- **原因**：最新のGoogle Maps APIでは、`AdvancedMarkerElement`が推奨されており、古い`google.maps.Marker`は非推奨になりつつあることが判明。

これを解決するために、公式ドキュメントに従い、`AdvancedMarkerElement`を使用することにしました。

---

### 2. `AdvancedMarkerElement`で解決
`AdvancedMarkerElement`を使用することで以下の問題を解決できました：

- 非推奨APIではなく、最新のAPIに対応
- エラーメッセージが解消され、地図描画とピンの設置が期待通りに動作

#### コード例

```javascript
import { Loader } from "@googlemaps/js-api-loader";

const loader = new Loader({
    apiKey: import.meta.env.VITE_GOOGLE_MAPS_API_KEY, // Google Maps APIキー
    libraries: ["places"], // 必要なライブラリ
});

loader.load().then(() => {
    const initialPosition = { lat: 35.6895, lng: 139.6917 }; // 東京
    const map = new google.maps.Map(document.getElementById("map"), {
        center: initialPosition,
        zoom: 15,
    });

    new google.maps.marker.AdvancedMarkerElement({
        position: initialPosition,
        map: map,
        title: "選択した場所",
    });
});
```

---

### 3. Viteを使用してJSをビルドする仕組み
今回のプロジェクトでは、laravel-vite-pluginを導入してGoogle Maps APIの@googlemaps/js-api-loaderを管理しました。npm installで簡単にモジュールを追加し、Viteを使用してJavaScriptをビルドする仕組みにしました。

- **関連ファイルの設定**
vite.config.js
```JS
import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";
import dotenv from "dotenv";

dotenv.config();

export default defineConfig({
    plugins: [
        laravel({
            input: ["resources/css/app.css", "resources/js/app.js"],
            refresh: true,
        }),
    ],
});
```

.env
```php
VITE_GOOGLE_MAPS_API_KEY=your_api_key_here
```

---

### 4. 環境変数VITE_GOOGLE_MAPS_API_KEYの必要性
Google Maps APIキーを直接コードに記述するのはセキュリティリスクがあります。そのため、.envファイルを使用してAPIキーを環境変数として設定し、import.meta.envで参照する方法を採用しました。

**ポイント**
- .envファイルにVITE_GOOGLE_MAPS_API_KEYを記載
- vite.config.jsでdotenvを使用して環境変数を読み込む
- JavaScript内でimport.meta.env.VITE_GOOGLE_MAPS_API_KEYとして参照

## 最終的な成果
以下のことが実現できました：

- 最新のAdvancedMarkerElementを使用して地図を正しく描画
- Laravel Sail環境でnpmモジュール管理を導入し、Viteを使ってモダンなフロントエンドビルドを実現
- セキュアなAPIキー管理方法を採用



## まとめ
今回のプロジェクトでは、Google Maps APIとLaravel Sailの組み合わせに関するいくつかの課題を解決しました。AdvancedMarkerElementを使用し、npmモジュール管理を適切に導入することで、開発体験が大幅に向上しました。

最後まで、ご視聴頂きありがとうございます。
環境変数の設定をしたくてもできない

## 環境変数のトラブルシューティング

ソフトウェアをインストールしたのちに

パスを通す必要がある時ってあるじゃないですか。

Rubyをインストールして、Vimを入れたんですけど

パスが通ってなかったので環境を整えようとしたんです。



パスを「編集」するボタンを押しても反応しなくなっています。

どこをいじればいいのか見当もつきません。

コマンドプロンプトやPowerShellにおまじないを入力しても



一時的に編集ができるのでそれでもよかったんですがね。

## システム環境変数と入力して順番にダイアログを開く
「環境変数」と入力して
環境変数の画面が出力されて、その画面に「編集ボタン」
ついてますけど、一向に押しても反映しないように。
だから「システム環境変数」と違う用語で検索します。
「編集ボタン」が押せるように正常に戻りました。

Windowsの検索フォームには「環境変数」と入力せず

「システム環境変数」と省略しないで入力しましょう。
クラス変数

# インスタンスメソッド、スーパークラス、サブクラスでも共有されるクラス変数
```rb
irb(main):001* class Product
irb(main):002*   @@name = 'Product'
irb(main):003*
irb(main):004*   def self.name
irb(main):005*     @@name
irb(main):006*   end
irb(main):007*
irb(main):008*   def initialize(name)
irb(main):009*     @@name = name
irb(main):010*   end
irb(main):011*
irb(main):012*   def name
irb(main):013*     @@name
irb(main):014*   end
irb(main):015> end
=> :name
irb(main):016* class DVD < Product
irb(main):017*   @@name = 'DVD'
irb(main):018*
irb(main):019*   def self.name
irb(main):020*     @@name
irb(main):021*   end
irb(main):022*
irb(main):023*   def upcase_name
irb(main):024*     @@name.upcase
irb(main):025*   end
irb(main):026> end
=> :upcase_name
irb(main):027> Product.name
=> "DVD"
irb(main):028> DVD.name
=> "DVD"
irb(main):029> product = Product.new("A great movie")
=> #<Product:0x0000000108cfff68>
irb(main):030> product.name
=> "A great movie"
irb(main):031> Product.name
=> "A great movie"
irb(main):032> dvd = DVD.new("An awesome film")
=> #<DVD:0x000000010926de78>
irb(main):033> dvd.upcase_name
=> "AN AWESOME FILM"
irb(main):034> product.name
=> "An awesome film"
irb(main):035> Product.name
=> "An awesome film"
irb(main):036> DVD.name
=> "An awesome film"
```

>クラス変数は小さなプログラムでは必要になることは少ないですが、ライブラリ（gem)の設定情報（config値）を格納する場合などに使われることがあります。

# 感想
共有し放題の変数は危なそうだ。
railsのgemにも使われるらしい。大変そうだ。
まず最初に慣れるべきRubyMineのショートカット3選

## はじめに

僕はこれまで手元の作業の効率化に注力していませんでした。
<br>

操作のスピードを上げて秒単位の生産性を追い求めるより、ビジネス価値の最大化のために機能要件やスコープを絞る方が、比べ物にならないくらい効率的だと感じていたからです。
<br>

しかし最近になって、手元の作業の効率化には1秒単位のスピードアップというよりも、思考を妨げないことに価値があると思い始めました。
<br>

集中して考えている時に画面遷移でもたついたりコマンド操作でタイポするのは気が散り、思考の妨げになるからです。
<br>

そこでまずは僕が普段の業務で使っているRubyMineの作業効率を上げていきたいと考えました。
<br>

この記事では最近覚えたてのRubyMineのショートカットをまとめます。
<br>

もっとたくさんありますが、いま手に馴染んできたものだけに絞ります。

## RubyMineのショートカット

1. 検索: Shiftキーを2回押す
2. コードジャンプ: ⌘ + B
3. 自動整形: ⌘ + ⌥ + L
<br>

順番にまとめます。
<br>

### 1. 検索: Shiftキーを2回押す

Shiftキーを2回押すことで検索用のパネルを立ち上げられます。
<br>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325281/56b48d10-c56c-75d9-b2ad-3989c2096289.png)

<br>

クラス名・ファイル名・コードなど様々な粒度で検索可能です。
<br>

選択すると該当箇所へ飛べます。

### 2. コードジャンプ: ⌘ + B

クラスやメソッドにカーソルを合わせ`⌘ + B`を押すことで、その定義元へジャンプできます。
<br>

これを使うとコードリーディングが圧倒的に楽になります。
<br>

またコードジャンプの良い点は gem のソースまで追えることです。
<br>

たとえば下記の`has_many`の部分にカーソルを当てて`⌘ + B`を押します。
<br>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325281/879c51af-1d99-4d78-024e-8139a9baa4b9.png)

<br>

すると次のように、Railsの`has_many`メソッドの定義までジャンプできるのです。
<br>


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325281/036fabe6-3bfd-aca4-92f6-85aec4e7fc43.png)

<br>

このように自分たちのプロジェクトだけでなく gem のコードまでジャンプできるのがとても強力です。
<br>

OSS活動も捗ります。
<br>

また`⌘ + ⌥ + ←`でジャンプ先からジャンプ前の位置へ戻ることも可能です。

### 3. 自動整形: ⌘ + ⌥ + L

`⌘ + ⌥ + L`キーを押すことでインデント崩れなどを自動整形してくれます。
<br>

たとえば下記のようなインデントや改行が崩れているコードがあったとします（ファイルの中身は別の検証で使ったものなので気にしないでください）。
<br>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325281/d54f8156-f287-1523-ba37-61ee75211a35.png)

<br>

この状況で`⌘ + ⌥ + L`キーを押すと綺麗にフォーマットされるのです。
<br>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2325281/a43e179b-e75b-c490-f59d-6db90e2a81d0.png)

<br>

また、コードの一部だけを範囲指定して実行すると、その範囲だけを自動整形してくれます。

## おわりに

ショートカットなどの作業効率化を定着させるのは時間がかかりますし、慣れるまでは逆に生産性が下がることもあるはずです。
<br>

そのため、一気にマスターしようとせず少しずつ手に馴染ませていくことが重要だと考えます。
<br>

この記事で書いたもの以外にもショートカットはたくさんあるため、RubyMineに習熟してきたら改めてまとめていきます。
【LaTeX】理系レポートの書き方に悩む人向けのテンプレート紹介

## はじめに
　この記事ではLaTeX初心者の大学生向けに、レポートを書き始めるときのテンプレートを紹介します。
　見た目に凝りすぎず、コードも複雑すぎず、シンプルな記法を意識しているので、見た目に凝りたい方は自力で色々勉強すると良いと思います。しかし、だいたいの大学生はそんなにレポートに手間をかけたくないのではないでしょうか。
　いちいち余白だとか、細かい体裁だとかを気にせず中身だけを重視すべきだと私は思います。シンプルイズベスト。

::: note 
私は普段表紙を作らないので、表紙が欲しい人は別途自分で改造してください。
:::

## テンプレコード

~~~latex:template.tex
%プリアンブル
%ドキュメントクラス
\documentclass[dvipdfmx]{jlreq}    %このオプションで.pngや.jpgが使えるようになる

%箇条書きの拡張
\usepackage{enumerate}

%数学系
\usepackage{amsmath}
\usepackage{mathtools}
\usepackage{empheq}
\usepackage{amssymb}

%tableを指定した場所に確実に描画する
\usepackage{here}
\usepackage{booktabs}
\usepackage{array}

%画像を挿入
\usepackage{graphicx}

%URLに使われた記号でコンパイルに詰まる事態の回避
\usepackage{url}

%本体
\begin{document}
    %subの数はお好み
    \subsection*{科目名}

    %必要に応じてレポートタイトルや\begin{center}

    %箇条書きで書いた方が良さそうなことを列挙
    \begin{description}
        \item[学籍番号] xxxxxxxx
        \item[氏名] your name
        \item[日付] 2024年11月25日
    \end{description}

    %問題
    \begin{enumerate}[問1.\space]
        \item 標本平均$\bar{X}$を求めよ。 
        \item 行列Aの$rank$を求めよ。
    \end{enumerate}

    %写真
    \begin{figure}[H]    %[H]=here　絶対にこの位置に描画しろという命令
        \centering
        \includegraphics[width=100mm]{sample.png}
    \end{figure}

    %表
    \begin{table}[H]
        \begin{tabular}{c|c c c c}
            \hline
            a & b & c & d & e \\
            1 & 2 & 3 & 4 & 5
        \end{tabular}
    \end{table}

    %参考文献
    \subsection*{参考文献}
    
    \begin{itemize}
        \item 文献a, \url{https://google.com}
        \item 文献b, \url{https://google.com}
    \end{itemize}

    %または

    \begin{enumerate}[i.\space]
        \item 文献a, \url{https://google.com}
        \item 文献b, \url{https://google.com}
    \end{enumerate}
    
\end{document}
~~~

![スクリーンショット 2024-11-25 18.32.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3850890/6cc22211-172c-257b-ae94-2e671f8179b6.png)

## おわりに
　ここではシンプルなコードを紹介しましたが、LaTeXの世界には数多くのパッケージが存在し、時たま「こんなのあんの！？」となる時すらあります。
　ただ理系大生の生活を過ごすだけならここにあるコードに加えてプログラムの添付や数式の環境（この二つにはさまざまな方法があり、好みが分かれる上トラブルシューティングでusepackageがカオスになるので紹介はしません）が書ければ問題ないでしょう。
　しかし、ちょっとでも凝りたいと思い出したらネットの世界に転がるパッケージを探し求める亡者になります。それはそれで楽しいですけど。
　長くなりましたが、LaTeXは使いこなせるようになるとちょっとした書き物でも数式が綺麗に描けるので重宝します。是非使いこなしていってくださいね！
Raspberry Pi Picoで始める組み込み開発入門

# はじめに
リンクラフト株式会社でエンジニアとして働いている芳崎です。
リンクラフトアドベントカレンダーの12日目を担当します。

普段からWebアプリやスマホアプリを開発しているエンジニアにとって
「組み込み開発」という単語について難しいイメージを持っているかもしれません。  
そんな方に向けて`Raspberry Pi Pico`というマインコンボードを紹介させてもらいます。

# Raspberry Pi Picoって？
ラズベリーパイ財団によって開発されたSoc[^1] RP2040を搭載したマイコンボードです[^2]。  
Raspberry Pi Picoは個人から業務レベルでも使用されています。

と言われても分からないとは思うので
`Raspberry Pi`を知ってる方向けではあるのですが  
両者の最新機を比較しながら下記に特徴を記載します。

|-|Raspberry Pi 5|Raspberry Pi Pico 2| 
|-|-|-|
|OS|Raspberry Pi OS(Unix)|なし|
|価格|約10000円～15000円|約1000円|
|CPUクロック|1.5GHz|150 MHz|
|メモリ|8GB|520KB|
|できること|PCで出来る事ならほとんど|書き込んだプログラムのみ|
|主な対応言語|実質PCなので環境に依存しない|主にC++やPython、Rust|

[^1]:System on Chip
[^2]:Raspberry Pi Pico 2ならRP2350

# MicroPythonを使ってLチカ
対応言語にも記載しましたがPythonを使って今回プログラムを作成します。 
Pythonと言っても組み込み開発向けのMicroPythonを使います。

## 1.MicroPythonのファームウェアをRaspberry Pi Picoにインストール
下記のURLから最新のファームウェア[^3]をダウンロードします。
https://micropython.org/download/RPI_PICO/

Raspberry Pi PicoをUSBでPCに接続するとリムーバブルディスクとして認識されるので  
ダウンロードしたファームウェアをドラッグアンドドロップすることでインストール完了になります。
![スクリーンショット 2024-11-25 164056.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3941347/f4be3ef6-5070-b99a-1657-3743408791e7.png)

インストール完了後、一旦Raspberry Pi Picoの接続を切っておきます。

[^3]:執筆時の最新版は`v1.24.0(2024-10-25).uf2`

## 2.VSCodeの拡張機能「Micro Pico」をインストールする。
VSCodeで開発完結させるため  
拡張機能であるMicro Picoをインストールします。[^4]  
![スクリーンショット 2024-11-25 164020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3941347/396e6177-6244-8a33-3e9e-e68ba440e87e.png)

[^4]:前提環境でPython 3.10以上が指定されているので気を付けてください 

## 3.プロジェクトの作成
作業用のディレクトリを作成、VSCodeでそのディレクトリを開いてください。  
プロジェクトを開いた後コマンドパレットで下記のコマンドを入力しプロジェクトを初期化します。
```
> MicroPico:Setup MicroPico project
```
エクスプローラーが下記の画像のような配置になっていればOKです。
![スクリーンショット 2024-11-25 164716.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3941347/b3f703ac-54d4-3174-262f-5a6942e72270.png)


## 4.プログラムの作成
プロジェクト内に`led_test.py`というファイルを作成します。  
プログラムの内容は下記の通りで0.25秒ごとにLEDを点滅させるというものです。
```Python 
from machine import Pin
from time import sleep

led = Pin("LED", Pin.OUT)

while True:
    led.toggle()
    sleep(0.25)
```

## 5.プログラムの実行
Raspberry Pi Picoを再度接続します。  
接続後、VSCode下部に`Pico Connected`の表記が出れば認識されています。  

プログラムの実行をするにはVSCode下部の`Run`をクリックします。  
![スクリーンショット 2024-11-25 164853.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3941347/63c848f8-5176-2bae-b813-d1983968badf.png)

Raspberry Pi PicoのLEDが点滅していれば成功です。
![LChika.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3941347/c5053ed6-9f5c-f86d-81a3-99f1a6c3bdbe.gif)

# さいごに
今回は簡単なLチカのプログラムを紹介しましたが  

キーボードやゲームのコントローラー、何かに特化した左手デバイスなどPC周りのデバイスを自作したり  
別途センサー等をつなげてIoT的な使い方をするといったりなどで、出来ることはたくさんあります。  

価格も手ごろなので触っていただけたら嬉しいです。


-----------


一緒に働く仲間を募集中です！

リンクラフト株式会社では、組織拡大に伴い積極的な採用活動を行っています。
少しでも興味がある方はぜひご連絡ください。

▽会社ホームページ
https://lincraft.co.jp/
▽Instagram
https://www.instagram.com/lincraft.inc/
▽ご応募はこちらより
https://lincraft.co.jp/recruit

※カジュアル面談も受付中です。ご希望の方はHPのお問い合わせフォームよりご連絡ください。
初めて既存のWebアプリをDocker化してみた

# はじめに
今回はホストで作成して、GitHub上にあるWebアプリをDockerのコンテナ上で動かすまでのステップを解説します。

### 各種バージョン
- Docker 24.0.6
- Ruby: 3.2.2
- Ruby on Rails: 7.0.6
- Postgres: 12

### 開発環境
- CPU: Apple M1
- OS: macOS Sonoma バージョン14.6
※Windowsなど他のOSやCPUでの動作確認は行なっていません。

:::note warn
- GitHubアカウントの作成
- Docker Desctopのインストール
上記2点は済ませてあるという前提で進めます。
:::

## Docker化の手順
### 1. リモートリポジトリからリポジトリをクローン
ローカル環境の任意の位置でgit cloneをしましょう
```
git clone https://github.com/<ユーザ名>/<リポジトリ名>.git
```

### 2. 必要なファイルを新規作成と編集
- **Dockerfile**と**docker-compose.yml**を作成

```Dockerfile:Dockerfile
FROM ruby:3.2.2

RUN apt-get update -qq && apt-get install -y \
    build-essential \
    libpq-dev \
    nodejs \
    postgresql-client

COPY . /rails-docker
ENV APP_HOME /rails-docker
WORKDIR $APP_HOME
RUN bundle install
```
Dockerfileで書かれている**命令文**が分からなかったので、以下の表にまとめました。
| 命令 | 内容 |
|:-:|:-:|
|  FROM |  コンテナのベースのイメージを指定 |
|  RUN | ビルド時に実行するコマンド |
|  COPY | ソースコードや設定ファイルを<br>ローカルからDocker imageにコピー |
|  ENV |  環境変数を設定 |
|  WORKDIR |  コンテナ内の作業ディレクトリを指定 |


```yml:docker-compose.yml
# バージョンを選定
version: '3'

services:
# dbコンテナ
  db:
    image: postgres:12
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    volumes:
      - postgresql-data:/var/lib/postgresql/data

# webコンテナ
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    ports:
      - '3000:3000'
    volumes:
      - '.:/rails-docker'
    depends_on:
      - db
volumes:
  postgresql-data:
    driver: local
```

- **config/database.yml**を編集
```yml:database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: postgres
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
```

### 3. 動作確認
1. イメージの作成
    
    ```
    docker-compose build
    ```
1. DB作成
    ```
    docker-compose run web rake db:create
    docker-compose run web rails db:migrate
    ```
1. コンテナ作成&起動
    ```
    docker-compose up
    ```
1. 出力確認
    [http://localhost:3000](http://localhost:3000)にアクセス
3Dスキャンの技術は何ですか?

3Dスキャンでは、無特徴の物体、小さな物体のスキャン、モデルの結合など、特定の課題に直面することがよくあります。より正確なスキャン結果を得るために、以下にこれらの問題に対処する具体的な解決策と最適化テクニックをご紹介します。

---

#### **1. 無特徴な表面への対応**  
平滑で特徴が少ない表面（単色や均一な質感の物体）は、スキャナーが詳細や位置合わせを把握しにくい場合があります。以下の方法を試してみてください：  
- **マーカーを追加する**：物体の表面に高コントラストのマーカーステッカー（黒白の点など）を貼り、スキャナーが参照点を認識できるようにします。  
- **マット処理**：透明、光沢、単色の表面には、マットスプレーや粉末コーティングを施し、認識性を向上させます。  
- **光環境の最適化**：均一な光を確保し、反射や影による干渉を避けます。

 ![375117c4004ae79d61620814f4e060cb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824290/14931957-2199-bff0-f877-9458963e88fa.png)


---

#### **2. 小型物体のスキャンテクニック**  
小さな物体（アクセサリーや部品など）をスキャンする際は、高い精度と安定性が求められます。次の方法を試してみてください：  
- **高精度スキャナーを使用する**：卓上型レーザースキャナーなど、小さなディテールを捉えることができるデバイスを選択します。  
- **物体を固定する**：スキャン台の上で小物を安定させ、振動や移動を防ぎます。接着剤や粘着性のある台座を使用すると効果的です。  
- **多角度スキャン**：異なる角度からデータを取得し、特にくぼみや死角を補完します。

![59d2f1770ffbb4d374bd880e3b148eb5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824290/38412553-9ffe-e17a-cc4d-90fecf6600af.png)

---

#### **3. モデルの結合と統合**  
大きな物体や複雑な形状の物体をスキャンする場合、複数のスキャンデータを結合して完全なモデルを作成する必要があります。次のテクニックを活用してください：  
- **点群データの位置合わせ**：MeshLabやGeomagicなどのソフトウェアを使用し、自動または手動で一致点を設定して複数スキャンデータを結合します。  
- **重複領域の最適化**：結合時に重複部分を細かく調整し、余分なデータを除去し、滑らかな接続を実現します。  
- **スケールの調整**：スキャンデータのスケールが一致するように調整し、必要に応じて拡大または縮小を行います。

![cbfdef9d55a562239ab7c86481780613.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824290/ca06e0aa-32ef-7a55-5d2a-f3cec6d7370c.png)

---

#### **4. ノイズの削減とモデルの最適化**  
スキャン中に余計なノイズが発生することがありますが、これは結果に影響を与える可能性があります。以下の方法で対処してください：  
- **ノイズをクリーニングする**：専用ソフトウェアでノイズ点を自動または手動で削除します。  
- **欠損部分の修復**：アルゴリズムを使用して小さな穴や欠損部分を補完し、モデルの完全性を確保します。  
- **ポリゴンメッシュの簡略化**：3Dプリントやレンダリング用途に応じてモデルのポリゴン密度を調整し、ファイルサイズと詳細のバランスを取ります。

---

#### **5. スキャンの死角を避ける**  
複雑な構造や隠れた部分は、スキャン中にデータが失われることがあります。このような場合は次の手法を試してください：  
- **スキャン経路の調整**：多角度スキャンパスを選択し、特に隠れた領域を重点的にカバーします。  
- **物体の回転**：物体を回転または再配置して、より多くの表面を露出させます。  
- **補助光源を使用する**：隠れた部分に均一な光を当てることで、キャプチャ性能を向上させます。

---

これらのテクニックを活用すれば、様々なスキャン課題に対応し、スキャン品質と効率を向上させることができます。小型物体の精密なスキャンから複雑なモデルの結合や最適化まで、これらの方法を実践することで、より高い精度とプロフェッショナルな結果を実現できます。

推奨される 3D スキャン機器:

https://www.revopoint3d.com/collections/3d-scanners

https://www.revopoint3d.jp/collections/3d-scanners