OmniAICreator/Qiita-1.07M huggingface dataset:
5分でローカルPCでVLLMを使ってRakuten/RakutenAI-2.0-mini-instructを高速起動する方法



## はじめに

**VLLM** は、効率的で軽量な大規模言語モデル（LLM）サーバーです。この記事では、ローカルPCでVLLMを使用して **Rakuten/RakutenAI-2.0-mini-instruct** という高性能な言語モデルを高速に起動する方法を紹介します。この記事の手順に従えば、5分以内にモデルを起動できます。

## 環境準備

### 必要なツール
以下のツールがインストールされていることを確認してください：
- **conda**：Python仮想環境を管理するために使用します。
- **pip**：Pythonパッケージをインストールするために使用します。
- **VLLM**：LLMを効率的に実行するためのサーバーです。
- **flash-attn**：モデルの推論を高速化するためのライブラリです。

### 仮想環境の作成
まず、Python 3.11の仮想環境を作成し、有効化します。
```bash
conda create -n vllm_v0.7.2 python=3.11 -y
conda activate vllm_v0.7.2
```

### VLLMと依存ライブラリのインストール
以下のコマンドを実行して、VLLMと`flash-attn`をインストールします。
```bash
pip install vllm
pip install flash-attn --no-build-isolation
```

---

## モデルのダウンロード

### Hugging Face CLIのインストール
モデルをダウンロードするために、まずHugging Face CLIをインストールします。
```bash
pip install "huggingface_hub[hf_transfer]"
```

### RakutenAI-2.0-mini-instructのダウンロード
以下のコマンドを使用して、**RakutenAI-2.0-mini-instruct** モデルをダウンロードします。
```bash
HF_HUB_ENABLE_HF_TRANSFER=1 \
huggingface-cli download Rakuten/RakutenAI-2.0-mini-instruct
```

---

## モデルの起動

### 起動コマンド
以下のコマンドを使用してモデルを起動します。  
（`CUDA_VISIBLE_DEVICES`で使用するGPUを指定し、`--tensor-parallel-size`でGPUの数を指定します。）
```bash
CUDA_VISIBLE_DEVICES=0 \
VLLM_USE_V1=1 \
VLLM_WORKER_MULTIPROC_METHOD=spawn \
vllm serve Rakuten/RakutenAI-2.0-mini-instruct \
--trust-remote-code --served-model-name gpt-4 \
--gpu-memory-utilization 0.98 --tensor-parallel-size 1 \
--port 8000 --max-model-len 2048 \
--disable-sliding-window
```

### 起動確認
起動に成功すると、以下のメッセージが表示されます：
```
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
```

---

## モデルの検証

### APIリクエストの送信
以下のコマンドを使用して、起動したモデルにAPIリクエストを送信し、正常に動作しているか確認します。
```bash
invoke_url='http://localhost:8000/v1/chat/completions'

authorization_header='Authorization: Bearer sk-dummy'
accept_header='Accept: application/json'
content_type_header='Content-Type: application/json'

data=$'{
  "messages": [
    {
      "role": "user",
      "content": "Which number is larger, 9.11 or 9.8?"
    }
  ],
  "stream": false,
  "model": "gpt-4",
  "max_tokens": 2048,
  "presence_penalty": 0,
  "frequency_penalty": 0,
  "top_p": 0.7,
  "temperature": 0.6
}'

response=$(curl --silent -i -w "\n%{http_code}" --request POST \
  --url "$invoke_url" \
  --header "$authorization_header" \
  --header "$accept_header" \
  --header "$content_type_header" \
  --data "$data"
)

echo "$response"
```

---

## 注意事項

- **GPUメモリ設定**：`--gpu-memory-utilization 0.98`はGPUメモリの使用率を設定します。環境に応じて調整してください。
- **テンソル並列処理**：`--tensor-parallel-size 1`は使用するGPUの数に応じて調整してください。
- **ポート番号**：`--port 8000`はAPIのポート番号です。他のアプリケーションと競合する場合は変更してください。

---

## 参考リンク
- [VLLM公式ドキュメント](https://vllm.readthedocs.io/)
- [Rakuten/RakutenAI-2.0-mini-instruct（Hugging Face）](https://huggingface.co/Rakuten/RakutenAI-2.0-mini-instruct)

---

以上の手順に従えば、ローカルPCで **Rakuten/RakutenAI-2.0-mini-instruct** モデルを高速に起動できます。ぜひ試してみてください！
Raspberry Pi 4 で Psychtoolboxを動かす (2)：動作確認編

# はじめに
　[前の記事](https://qiita.com/dylab/items/1061640d28160b3fd43e)でRaspberry Pi 4 (Raspi4)にGNU Octave上でPsychtoolbox (PTB)を動作させるための準備をしました。この記事では Raspi4 + Octave + PTBの環境で心理実験のために最低限の動作をするか確認します。

 # 基本的な動作確認
 ## ScreenのOpen
 　まずはPTBで最も重要なScreen関数の動作確認です。下記のスクリプトを実行し、真っ白な実験画面がフルスクリーンで5秒間表示されたあと、自動的に実験画面が閉じれば成功です。

```matlab:openScreen.m
clear;
clc;

scrnNum = max(Screen('Screens'));
mainWindow = Screen('OpenWindow', scrnNum, [255 255 255]);

WaitSecs(5);

Screen('CloseAll');
```

## 画像の表示
　画像素材サイト「[いらすとや](https://www.irasutoya.com/)」の画像をjpgに変換した画像が画面中央に5秒間表するプログラムです。下記の画像をseikou_banzai_man.jpgとしてダウンロードし、displayJapaneseCharacter.mと同じ階層に置かれている想定で作成したプログラムです。

```matlab:displayImage.m
clear;
clc;

scrnNum = max(Screen('Screens'));
mainWindow = Screen('OpenWindow', scrnNum, [255 255 255]);

img = imread('./seikou_banzai_man.jpg');
tex = Screen('MakeTexture', mainWindow, img);
Screen('DrawTexture', mainWindow, tex);
Screen('Flip', mainWindow);

WaitSecs(5);

Screen('CloseAll');

```

<img width = "300" src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1138705/62430d0f-83b4-45a5-95c5-0e761cdd704f.jpeg">

フルスクリーンの白背景に目的の画像が5秒間表示され、その後に自動的に実験画面が閉じれば成功です。

## 音声の再生
　YouTube等でもよく聞く無料音声ファイルを再生してみます。音源ファイルは下記のURLからダウンロードしました。

https://dova-s.jp/bgm/play4154.html

　playSound.mと同じ階層にeye-catch.mp3が置かれている想定で作成されたプログラムです。真っ白の画面で音楽（約15秒）が再生されれば成功です。

```matlab:playSound.m
clear;
clc;
InitializePsychSound;
pahandle = PsychPortAudio('Open', [], [], 0, [], 2);

scrnNum = max(Screen('Screens'));
mainWindow = Screen('OpenWindow', scrnNum, [255 255 255]);

snd = './eye-catch.mp3';
[sndData, ~] = audioread(snd);
sndData = transpose(sndData);
PsychPortAudio('FillBuffer', pahandle, sndData);

Screen('Flip', mainWindow);
PsychPortAudio('Start', pahandle, 1);
PsychPortAudio('Stop', pahandle, 1);

PsychPortAudio('Close', pahandle);
Screen('CloseAll');
```

## 動画の再生
　次は動画の再生です。著作権フリーのビデオクリップがダウンロードできる[Pixabay](https://pixabay.com/ja/videos/)から素材を入手しました。10から1へのカウントダウンの動画（約10秒）です。

 https://pixabay.com/ja/videos/秒読み-十-九-八-時間-558/
 上記URLからダウンロードした「558-137190717_medium.mp4」がplayMovie.mと同じ階層にある想定で作成したプログラムです。
 
```matlab:playMovie.m
clear;
clc;
InitializePsychSound;
pahandle = PsychPortAudio('Open', [], [], 0, [], 2);

scrnNum = max(Screen('Screens'));
mainWindow = Screen('OpenWindow', scrnNum, [255 255 255]);

movie = '558-137190717_medium.mp4';
moviePath = strcat(pwd,'/', movie);
moviePtr = Screen('OpenMovie', mainWindow, moviePath);

Screen('PlayMovie', moviePtr, 1, 0, 1);
while true
    tex = Screen('GetMovieImage', mainWindow, moviePtr);
        if tex <= 0
            break;
        end
    Screen('DrawTexture', mainWindow, tex);
    Screen('Flip', mainWindow);
    Screen('Close', tex);
end

Screen('PlayMovie', moviePtr, 0);
Screen('CloseMovie', moviePtr);
Screen('CloseAll')
```

## 日本語文字の表示は？
　私の研究分野ではPTBを使って日本語文字を表示する必要があり、過去には[Ubuntu上でのOctave + PTBで日本語文字を表示する方法についての記事](https://qiita.com/dylab/items/721ecbab5921be710b8a)も書きました。しかし、当該記事の内容はRaspi + Octave + PTBの環境ではまったくうまく動きませんでした・・・。色々と苦労して何とか日本語文字を表示する方法を整えたので[次の記事](https://qiita.com/dylab/items/013a0bb7c6adcbea7218)で紹介します。
【図と表】仮想化まとめ_LinuC201試験対策

## この記事は何の記事？
Linux の仮想化についてまとめました
LinuC201 の試験対策に使えます

## 集合関係
仮想化には「ホスト型」と「ハイパーバイザー型」があります
（コンテナは今回省略です...）
また，ハイパーバイザー型には「完全仮想化」と「準仮想化」があります
言葉だとわかりにくいので図でまとめるとこうです
![集合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/c20748a9-2d09-434c-9fce-2531ad5c5aee.png)

## ホストvsハイパーバイザー
![ホスト_ハイパーバイザー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/fa9f4685-358a-454c-a73c-2d85a559632c.png)

## 完全仮想化vs準仮想化
![完全仮想化_準仮想化.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/275f5a70-2d0a-4796-8fac-8ddf43cc86f8.png)

## 用語
![用語.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/f04cfceb-b05c-4c86-a252-456245b57d4f.png)

## libvirt
![libvirt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/b8094dd0-9981-4e58-9deb-65c78997a65f.png)

## 仮想化支援機能
![仮想化支援機能.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/98539068-1ae2-4772-8daa-f489cc7680c9.png)

## KVMとQEMU
![KVM_QEMU.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294646/03880d55-2176-470c-b60f-56e5beff4cee.png)
🧼✨ クリーンなコードで未来を変える！『Clean Code』がエンジニアに必須な理由 💡📖

![スクリーンショット 2025-02-14 22.44.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637864/012f63c2-64e3-4621-a52c-d70a2dafb4f7.png)

## エンジニアが最初に読むべき本  
### 『Clean Code: A Handbook of Agile Software Craftsmanship』

エンジニアのキャリアをスタートする際、基礎となる考え方や原則をしっかり学ぶことは非常に大切です。その中でも、Robert C. Martin（通称 Uncle Bob）による『Clean Code』は、読みやすく保守しやすいコードを書くための具体的なルールや実践例が豊富に掲載されており、初心者だけでなくキャリアのあらゆる段階のエンジニアに大いに役立ちます。📚✨

---

## 本書の概要

- **著者**: Robert C. Martin  
- **テーマ**:  
  - コードの可読性・保守性を向上させるためのルール  
  - チーム全体でコードを理解しやすくし、拡張性を確保する手法  
  - リファクタリングの重要性と、コードの改善に向けた具体的な実践方法  

たとえば、検索結果でも紹介されている「Clean Code」の考え方では、コードがクリーンであるということは「チームの誰もが理解でき、容易に改善できる状態」であると定義されています。これにより、開発チーム全体の生産性向上やバグの減少につながります。

---

## なぜ『Clean Code』を読むべきなのか？

### 1. 読みやすいコードは未来への投資

- **理解しやすさ**:  
  明確な命名規則や関数の設計により、他のメンバーがコードを容易に読めるようになります。  
- **保守性と拡張性の向上**:  
  将来的に新しい機能を追加したり、不具合の修正を行う際にも、しっかりとした土台の上にあるコードは大きなアドバンテージとなります。

### 2. コードレビューとリファクタリングの基本原則

- **コードレビューの際に意識すべきポイント**:  
  一貫したスタイル、シンプルな構造、そして再利用性が求められます。
- **リファクタリングの実践例**:  
  重複コードの排除や、複雑なロジックの単純化を行うことで、コードの品質を向上させる方法が具体的に示されています[3][4]。

### 3. 実践的な原則と開発効率の向上

- **Boy Scout Rule**:  
  「キャンプ場は自分が来たときよりきれいにして帰る」という考え方で、どんな小さな変更もコードの改善につながると説いています。
- **DRY（Don't Repeat Yourself）**:  
  重複を避けることで、バグの発生を抑え、保守性を高める原則です。

---

## 『Clean Code』で学べる具体的なポイント

- **読みやすいコードを書くためのルール**
  - コードは「誰が読んでも」理解できる状態であるべき
  - 意味のある変数名、適切な関数の分割、充実したコメントなどが重要
- **コードレビューで意識すべきポイント**
  - コードが意図した通りに動いているか？
  - 冗長な記述がないか？
  - 保守や拡張が容易な設計になっているか？
- **リファクタリングの重要性と方法**
  - コードを改善するリファクタリングのプロセスを通じ、よりシンプルで明確な構造にする
  - 小さな改善を積み重ねることで、長期的なシステムの品質向上に寄与

---

## 『Clean Code』の考え方を視覚化する

以下のフローチャートは、クリーンなコードを目指すための基本プロセスを簡単に示しています：

```mermaid
flowchart TD
    A[コードを書く] --> B[エラーやコードの重複を発見]
    B --> C[リファクタリングで改善]
    C --> D[読みやすさ・保守性の向上]
    D --> E[チーム全体で共有・レビュー]
```

このプロセスを意識することで、日々の開発作業において「クリーンなコード」がどれほど重要かが実感できます。💡

---

## 実践例：悪いコード vs. 良いコード

以下は、シンプルなPythonのコード例です。まずは、改善前のコード（悪いコード）から見てみましょう。

```python
# 悪いコード例
def calc(n):
    if n > 0:
         return n * 2
    else:
         return 0
```

次に、意味のある変数名とシンプルなロジックに改善したバージョンです。

```python
# 良いコード例
def double_positive_number(number):
    """
    :param number: 整数
    :return: 正の数の場合は2倍、負の数は0を返す
    """
    if number > 0:
        return number * 2
    return 0
```

このように、関数名やコメントを工夫するだけで、コードの可読性は大きく向上します。

---

## 最後に

『Clean Code』は、単なるコーディングテクニックに留まらず、エンジニアとしての基礎的な考え方を学ぶための最良の一冊です。読みやすいコードは、チーム全体の協力やプロジェクトの持続的な成功に直結します。あなたが初めてコードを書くとき、この本で学んだ原則を意識することで、より高品質なソフトウェア開発のスタートが切れるはずです。

さあ、今日から「クリーンなコード」を意識してコーディングに取り組み、次のレベルへステップアップしましょう！🚀

---

読者の皆さんが『Clean Code』を手に取り、その実践的な知識を日々の開発に活かせるよう、この記事が少しでも役立つことを願っています。
dataclassでdictの初期値を設定する方法

Pythonの`dataclass`でdictに `{}`で初期化すると default_factory エラーが発生します。

```python
@dataclass
class Record:
    """
    結果クラス
    """
    name: str = ''
    result_dict: dict[str, float] = {}

```

実行結果

```
ValueError: mutable default <class 'dict'> for field result_dict is not allowed: use default_factory
```

エラーメッセージの通り、filedをimportとしてdefault_factoryで設定します。

```python
import pandas as pd
import numpy as np
from dataclasses import dataclass, field

@dataclass
class Record:
    """
    結果クラス
    """
    name: str = ''
    result_dict: dict[str, float] = field(default_factory=dict)

def main():
    record = Record()
    record.name = 'test'
    record.result_dict['test'] = 1.0
    print(record)

    record2 = Record()
    record2.name = 'test'
    print(record2)

if __name__ == '__main__':
    main()
```

実行結果
```
Record(name='test', result_dict={'test': 1.0})
Record(name='test', result_dict={})
```
autocomplete="new-password"が適用されなかった

# はじめに
autocomplete="new-password"を設定しても適用されなかったので原因と対処を書きます

# 問題
こんな感じでautocompleteを設定しても、パスワードが提案されなかった
```html
<input type="password" autocomplete="new-password"/>
```

# 対処
Chromeを使っていたのですが、Googleパスワードマネージャーの設定の箇所でサイトが不承認のサイト扱いになっていたのが原因でした。不承認のサイトから削除するとパスワードが提案されるようになりました。

# おわりに
autocompleteを無効にする系の記事は結構あったのですが、autocompleteが適用されない系の記事があまりなかったので解決に時間がかかってしまいました。
これは困った！ node_modulesの暴走！

# あらまし
息抜きに、Next.jsでポートフォリオ(転職する気はないけど)を作っていた深夜１時。
ようやくいい感じになってきたなとシャワーを浴びる。
風呂上がりに開発サーバーを立ち上げると...。

```
Error: Cannot find module 'styled-jsx/package.json'
```

これは、もう一度 npm install しないといけないやつだと悟る...。
すでに 25:30...。このまま寝るか...。でも気になる。

意気揚々と、node_modulesを rm -rf する。
いつまで経っても削除が終わらない...。
ディレクトリを確認してみると...。

### こんなのがいっぱい！！！

```
drwx------  65535 hoge  staff  2097120 Feb 13 00:40 @eslint-community 2
```

## 事象
node_modules に、"2" の文字列が付く容量のおおきいディレクトリがたくさん生成される。

## 結論
rm -rf を回して寝よう！
```
sudo rm -rf node_modules
```

起きたらこれで、解決です。
```
rm -rf package-lock.json
npm install
```


# 考えられる要因
多分開発サーバを実行しながら、ブランチの切り替えやマージなどしすぎたことが要因かと推察。
実際の要因は掴めていない。

# 対応
以下手順で実施。
1. node_modulesの 削除
2. package-lock.json 削除
3. npm install

# 作業の流れ
1 の作業を行うにあたって、以下の方法を試したが、***いずれも短時間では完了しなかった***。

a. findコマンドを使った方法
```
find node_modules -name "* 2" -exec rm -rf {} +
```

b. rsyncを使った方法
```
rsync -a --delete empty_dir/ node_modules/
```

c. incode番号を指定して削除
```
ls -li node_modules | grep " 2" | awk '{print $1}' | xargs -I {} find node_modules -inum {} -exec rm -rf {} +
```

結局うまく行ったのは、***一晩中 rm -rf を回し続けること***。
```
sudo rm -rf node_modules
```

そのあとは、これで元通りでした。
```
rm -rf package-lock.json
npm install
```

# 最後に
ここまでご覧いただきありがとうございます。
要因が気になるし、かなり付け焼き刃な解決方法な気がしますので、もし何かお気づきの方は、教えてください！
それでは、いい夢を！
【備忘録】array_mergeはキーが数値の時は再採番される

# 初めに
配列を結合する`array_merge`ですが、配列のキーが数値の時と文字列の時とで動作が少し異なります。
**array_mergeはキーが数値の場合、ゼロから始まる連続した数値に置き換えられてしまいます**。

https://www.php.net/manual/ja/function.array-merge.php

以下公式ドキュメントの抜粋。
> 入力配列の中にある数値添字要素の添字の数値は、 結果の配列ではゼロから始まる連続した数値に置き換えられます


# 試してみる
例えば、キーが文字列の配列を結合してもキーは変わりません。
```php
<?php
$array1 = ['key1' => 'one', 'key2' => 'two'];
$array2 = ['key4' => 'four', 'key7' => 'seven'];

var_dump(array_merge($array1, $array2));
```

```php: 結果
array(4) {
    ["key1"] => string(3) "one"
    ["key2"] => string(3) "two"
    ["key4"] => string(4) "four"
    ["key7"] => string(5) "seven"
}
```

しかし、キーが数値の配列を結合すると、キーが変わってしまいます。
```php
<?php
$array1 = [1 => 'one', 2 => 'two'];
$array2 = [4 => 'four', 7 => 'seven'];

var_dump(array_merge($array1, $array2));
```
```php: 結果
array(4) {
    [0] => string(3) "one"
    [1] => string(3) "two"
    [2] => string(4) "four"
    [3] => string(5) "seven"
}

```

ちなみに、シングルクォーテーションで囲んでも数値扱いでキーが変わります。
```php
<?php
$array1 = ['1' => 'one', '2' => 'two'];
$array2 = ['4' => 'four', '7' => 'seven'];

var_dump(array_merge($array1, $array2));
```
```php: 結果
array(4) {
    [0] => string(3) "one"
    [1] => string(3) "two"
    [2] => string(4) "four"
    [3] => string(5) "seven"
}
```


# キーを変えたくない場合はどうするべきか
`array_merge`は使わずに`+`を使うことでキーを保つことができました。

```php
<?php
$array1 = [1 => 'one', 2 => 'two'];
$array2 = [4 => 'four', 7 => 'seven'];

// var_dump(array_merge($array1, $array2));
var_dump($array1 + $array2);
```
```php: 結果
array(4) {
    [1] => string(3) "one"
    [2] => string(3) "two"
    [4] => string(4) "four"
    [7] => string(5) "seven"
}
```
1週間でAWS ANSに合格した勉強法

# はじめに
2025 Japan AWS All Certifications Engineers申し込み期限まで残り1ヶ月と迫る中、ラストスパートをかけている方も多いのではないでしょうか。筆者は先日、AWS Certified Advanced Networking - Specialtyに合格して、全12冠を達成することができました。数あるAWS試験の中でも難しいと言われているANS-C01ですが、これから受験する方の参考になればと思い、筆者が実践した勉強法を共有します。

# 筆者のステータス
情報系大学院卒、社会人1年目のシステムエンジニア
| 合格日     | 試験名                                           | スコア          | 
| ---------- | ------------------------------------------------ | --------------- | 
| 2024/09/29 | AWS Certified Solutions Architect – Associate   | 820             | 
| 2024/11/09 | AWS Certified Sysops Administer – Associate     | 753             | 
| 2024/11/16 | AWS Certified Cloud Practitioner                 | 776             | 
| 2024/11/16 | AWS Certified AI Practitioner                    | 719             | 
| 2024/11/17 | AWS Certified Developer – Associate             | 808             | 
| 2024/11/24 | AWS Certified Data Engineer – Associate         | 859             | 
| 2024/12/01 | AWS Certified DevOps Engineer – Professional    | 803             | 
| 2024/12/09 | AWS Certified Solution Architect – Professional | 781             | 
| 2024/12/28 | AWS Machine Learning Engineering – Associate    | 768             | 
| 2025/01/18 | AWS Certified Machine Learning – Specialty      | 833             | 
| 2025/01/26 | AWS Certified Security – Specialty              | 794             | 
| 2025/02/11 | AWS Certified Advanced Networking – Specialty   | 819←今回はここ | 

# 実践した試験対策
ANS-C01取得に向けた勉強時間は25時間（1週間）です。
※筆者はANS-C01以外の11資格は全て取得している状態です。

## Cloudtechを2周
以前はCloudlisenceやUdemy問題集と併用しないと難しいと言われていましたが、2025年1月末に大幅アップデートがあり、より本番試験レベルに近い演習が可能となりました。筆者は1周目は正答率40%、2周目は正答率70%程度でした。筆者が使用した問題集はCloudtechのみです
https://kws-cloud-tech.com/

## Blackbelt
筆者はDirect Connectのみ参照しましたが、頻出のRoute53やTransit Gatewayにも目を通すと良いと思います。
- Direct Connect
https://pages.awscloud.com/rs/112-TZM-766/images/20210209-AWS-Blackbelt-DirectConnect.pdf

- Transit Gateway
https://pages.awscloud.com/rs/112-TZM-766/images/20191113_AWS-BlackBelt_Transit_Gateway.pdf

- Route53
【導入編】
https://pages.awscloud.com/rs/112-TZM-766/images/AWS-Black-Belt_2023_Amazon-Route53-Intro_0530_v1.pdf
【Resolver編】
https://pages.awscloud.com/rs/112-TZM-766/images/AWS-Black-Belt_2023_Amazon-Route53-Resolver_0530_v1.pdf
【Hosted zone編】
https://pages.awscloud.com/rs/112-TZM-766/images/AWS-Black-Belt_2023_AmazonRoute53-hostedZone_0531_V1.pdf


# 試験結果
Cloudtechの模擬問題集だけで合格しました。
![スクリーンショット 2025-02-14 22.13.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967327/7c9b609f-d2de-4b6f-a00b-d4554397166f.png)

# 最後に
AWS ANSで頻出のDirect ConnectやRoute53は筆者自身これまで触れたことがなかったので、仕組みを理解するのに苦労しましたが、CloudtechやBlackbeltを使用して、なんとか合格することができました。
これから受験する方のお役に立てると幸いです！
🔥 プログラミングの本質！エンジニアが最初に覚えるべき問題解決の極意🔰

![スクリーンショット 2025-02-14 22.16.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637864/9ceb7098-262e-4d4a-b845-97fa4517c5b9.png)


# エンジニアが最初に覚えるべきたった一つのこと ― 「問題解決の思考法」 🧠💡

エンジニアとしてのキャリアをスタートするにあたり、覚えておくべきたった一つの本質があります。それは「問題を正しく捉え、解決する思考法」です。技術やプログラミング言語は日々進化します。しかし、その根底にある共通のスキル―問題解決力は、一生モノの武器となります。

---

## なぜ「問題解決の思考法」なのか？

エンジニアリングの世界は、日々予期せぬ問題やバグに直面します。その度に新しい技術を学び直すのも大切ですが、最も重要なのは「どうやって問題に向き合うか」です。

- **抽象化:** 複雑な現象をシンプルに捉える技術
- **分解:** 大きな問題を小さなパーツに分解し、一つずつ解決するプロセス
- **検証:** 解決策が妥当かどうか実際に試し、フィードバックを得る

これらのスキルは、具体的なプログラミングスキルやツールを超えた、「生きた知識」としてあなたのエンジニア人生を支える基盤となります。

---

## 問題解決の思考法の基本ステップ 📝

以下は、問題解決の思考法を実践するための基本的なステップです。以下のフローチャートを参考にしてください。

```
[問題の認識]
       │
       ▼
[問題の明確化]
       │
       ▼
[仮説の立案]
       │
       ▼
[検証の実行]
       │
       ▼
[解決]
       │
       ▼
[振り返り]
```

### 1. 問題の認識
まずは、何が問題なのかを正確に把握します。ログやエラーメッセージを確認し、現象から原因を推測することが始まりです。

### 2. 問題の明確化
「なぜこの現象が発生しているのか？」という根本原因を考え、問題を細分化します。疑問点をリストアップするなど、論理的に整理しましょう。

### 3. 仮説の立案
考えられる原因に対して、どのような対策で解決できるか仮説を立てます。ここでできるだけ多くの視点を持つことが大切です。

### 4. 検証の実行
実際にコードを修正したり、変更を加えて結果を観察します。小さな実験を繰り返して、仮説を検証します。

### 5. 解決
検証で得た結果を元に、問題を解決します。最終的な解決策を決定し、コードやシステムに反映します。

### 6. 振り返り
解決策がうまく機能しているか、また同じ問題が再発しないように振り返りを行います。学びをノートにまとめるのも効果的です。

---

## 実際のコードで見る「問題解決の思考法」

ここでは、簡単なPythonの例を使って、上記のプロセスをどのようにコードに落とし込むかを考えます。例えば、与えられた数値リストから特定の条件に合致する値を抽出する問題を解決する場合：

```python
# 問題: 数値リストから偶数だけを抽出する

def extract_even_numbers(numbers):
    # 仮説: 偶数は2で割り切れるので、それを利用する
    try:
        even_numbers = [num for num in numbers if num % 2 == 0]
        return even_numbers
    except Exception as e:
        print(f"エラーが発生しました: {e}")
        return []

if __name__ == "__main__":
    numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    result = extract_even_numbers(numbers)
    print("抽出された偶数:", result)
```

このコードの中で：

- **問題の認識:** リストから偶数だけ抽出したい
- **仮説の立案:** 偶数は「num % 2 == 0」で判定できる
- **検証:** リスト内包表記を使い正しく抽出できるか確認
- **解決 & 振り返り:** 出力結果を確認し、期待通りかチェック

---

## 問題解決の思考法を身につけるために 🔍

以下のポイントを意識して、日々の学習や実践に取り入れてみましょう。

- **疑問を持ち続ける:** バグやエラーに遭遇したら、「なぜこうなるのか？」と根本原因を探る習慣を持つ。
- **小さな実験を繰り返す:** 大きな変更をする前に、まずは小さなコード断片で試行錯誤する。
- **アウトプットする:** 学んだことをブログやメモにまとめることで、知識を整理し、次に活かす。

また、オンラインコミュニティ（例：[Stack Overflow](https://stackoverflow.com) や [Qiita](https://qiita.com)）を活用することで、他人の問題解決のプロセスに触れ、視野を拡げましょう。🌐

---

## 最後に

エンジニアリングの世界は、技術が変化しても「問題解決の思考法」は常に価値あるスキルです。プログラミングの文法やライブラリは覚えるにしても、どんな問題にもアプローチできる柔軟な思考こそ、真のエンジニアに必要な力です。

この「たった一つのこと」を忘れずに、日々のコードや実践で少しずつ磨きをかけていきましょう。あなたの探求心と好奇心が、未来の大きな技術革新を生む原動力になるはずです。🚀

Happy Coding! 💻✨
データセットを作成する②　（続：NetSuiteでピボットテーブルを作ってみる）

今回はデータセットの作り方の続き、計算式について説明します。
前回までの記事は以下リンクをご参照ください。

https://qiita.com/NaotoKashimura/items/6fc470e28f87a3b61aa3

https://qiita.com/NaotoKashimura/items/1eb2a31567fd1cc138e6

## 計算式を作成する
計算式はデータセット設定画面の右上にあります。
![rapture_20250214161342.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3954306/ef906072-5cfd-4866-b4c0-567fd1f76d95.jpeg)

新しい計算式をクリックします。
![rapture_20250214162448.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3954306/f4b5bbcd-53dd-47b1-acae-c6eb166f1640.jpeg)

ポップアップウインドウが開いて計算式が定義できるようになります。
![rapture_20250214162659.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3954306/73942151-07d0-455c-aee8-6e8c6ce74bc6.jpeg)
<dl>
  <dt>計算式フィールド名</dt>
  <dd>項目名を入力します</dd>
  <dt>出力の種類を選択</dt>
  <dd>数値や文字列などデータの型を選択します</dd>
  <dt>計算式</dt>
  <dd>実際の計算式を入力します</dd>
  <dd>下のフィールドや関数から選択が可能です</dd>
</dl>

:::note info
計算式は保存検索でも作成可能ですが、SuiteAnalytics Workbookでは計算式の項目でフィルタリング（データの絞込）が可能です。
※保存検索では条件に計算式が使用可能ですが、フィルターに計算式のフィールドは追加できません。
計算式を使用して表示するフィールドで、エンドユーザーが自由にフィルタリングをする場合、この機能は有力な選択肢となります。
:::

## さいごに
次回は、SuiteAnalytics Workbookの最終回、ワークブックでグラフを作るを説明します。
【備忘録】スマートコントラクト開発準備②

今更ですが、スマートコントラクト開発についての備忘録としてまとめます。

:::note info
はじめに
この備忘録はブロックチェーン、イーサリアムの基本的な性質を理解している前提で書いています。
:::

今回は開発フレームワークについてまとめます。

## 開発フレームワークとは
ソフトウェアやアプリケーションを効率的に開発するためのテンプレートやライブラリ、ツールの集まりのことです。
これにより、開発者は1からすべてを作成する必要はなく、共通の機能やパターンを再利用して、生産性を高めたり、コードの品質を高めたりできます。

私はプログラミングを始めた当初、プログラミング言語とフレームワークの違いがよく分かりませんでした。

・プログラミング言語の目的：コンピュータに命令を伝えること
・開発フレームワークの目的：開発の効率化、コードの品質向上、保守性の確保

つまり、開発フレームワークはプログラミング言語を補強してくれる存在です。

各プログラミング言語に対応する代表的なフレームワークが存在します。

<table>
  <thead>
    <tr>
      <th>プログラミング言語名</th> <th>開発フレームワーク名</th>
    </tr>
  </thead>
  <tr>
    <td>Java</td> <td>Spring</td>
  </tr>
  <tr>
    <td>Python</td>  <td>Django、Flask</td>
  </tr>
    <tr>
    <td>JavaScript</td> <td>React、Vue.js</td>
  </tr>
  <tr>
    <td>Solidity</td>  <td>Hardhat、Foundry</td>
  </tr>
</table>

:::note warn
Solidityの推奨フレームワークは上記の通りですが、2023年9月までは最も使われていたフレームワークTruffleを使用します。
現在は開発を停止しているので、テスト開発以外の目的には使用しないでください。
:::

## Truffleインストール
TruffleのインストールにはNode.jsのインストールが必要です。

Node.jsとはサーバサイドのJavaScript実行環境の一つです。

Truffleは前述の通り、開発停止されているので最新のNode.jsをインストールしてしまうと互換性がないため、インストールできません。

Node.jsのバージョンはv18をインストールしてください。

MacOSでHomebrewをインストールしている場合は以下コマンドでインストールできます。
```
brew install node@18
echo 'export PATH="/opt/homebrew/opt/node@18/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
```
インストールした後に、環境変数にインストールしたNode.js 18をシステムパスに追加することで、`node`コマンドを使えるようになります。
実際に確認します。
```
node -v
```
`v18.20.6`とバージョンが表示されていればOKです。

Truffleと互換性のあるバージョンのNode.jsをインストールできたら
次はTruffleをインストールします。

```
npm install -g truffle  
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3964004/cf4bf1d7-dd1a-439f-ae40-dba7a7197b68.png)

これはインストールした時の画面スクショです。このように大量の文字が出てきます。
`npm warn deprecated`と怒られますが、古いバージョンのnpmパッケージを使っているからです。
今回は無視して大丈夫です。

では、インストールが成功したか以下コマンドで確認します。
```
truffle version
```

成功した場合はインストールされたもののバージョンが出ます。
フレームワークなので色々入っていることがわかると思います。
```
Truffle v5.11.5 (core: 5.11.5)
Ganache v7.9.1
Solidity v0.5.16 (solc-js)
Node v18.20.6
Web3.js v1.10.0
```
各ツールの説明を簡単にします。
<table>
  <thead>
    <tr>
      <th>ツール</th> </th><th>説明</th>
    </tr>
  </thead>
  <tr>
    <td>Truffle</td> <td>開発フレームワーク。コンパイル、デプロイ、テストを管理</td>
  </tr>
  <tr>
    <td>Ganache</td>  <td>開発用のプライベートチェーンを提供</td>
  </tr>
    <tr>
    <td>Solidity</td> <td>スマートコントラクト開発言語（最新は0.8.29）</td>
  </tr>
  <tr>
    <td>Node.js</td>  <td>JavaScript実行環境。Truffle, Ganacheを動かすのに必要</td>
  </tr>
    <tr>
    <td>Web3.js</td>  <td>EthereumとJavaScriptの通信ライブラリ</td>
  </tr>
</table>


[Solidityの最新版は公式サイトからインストールできます](https://docs.soliditylang.org/en/latest/installing-solidity.html#installing-solidity)

これで準備完了です。
スマートコントラクト開発スタートです。

Let's start coding!!
機械学習におけるMLOpsの重要性

こんにちは。2024年9月にDataikuに入社してから5ヶ月経ち、AI分析やMLの分野においてもインプットが増えてきたので、アウトプットも始めていこうと思います。(ブログ投稿自体、かなり久しぶりです)

Dataikuでは、ブログやソーシャルでアウトプットしていくことを推奨してもらっているので、これを機にQiitaだけではなく[Medium](https://medium.com/@akikobannai_87167)も再開しようかなあ、と思っています。

本日は、標題の通りMLOpsについて語りたいと思います。

そもそもMLOpsとはなんぞや、という点ですが、DevOpsを機械学習システムに当てはめた考え方です。

私は現在Dataikuにおいてカスタマーサクセスの責務を持っており、MLを含めたAIを活用してビジネスへの貢献をミッションとしています。その中で、MLOpsはカスタマーサクセスの立場でも非常に重要と考えております。

いうまでもなく、AIやMLツールは導入や構築が目的ではなく、活用してROIを向上していく、ビジネスで役立つ状態を継続的に作っていくことがゴールです。

その観点において、MLOpsは重要であり、Dataikuのは以下のような機能を網羅しております。

　1.機械学習モデルを構築するためのデータの統合、データの正規化をスムーズに行うことができる
　2.ビジネスユーザやデータサイエンティスト、コーダー及びノンコーダーがコラボレーションし、一元化されたプラットフォームでモデルの構築ができる
　3. モデルの評価や比較が簡単に行える
　4. 構築したモデルを、ダウンタイムを最小限にしつつ、本番環境にデプロイできる
　5. デプロイ後、モデルの精度をトラッキングでき、再学習をかけられる
　6. バージョン管理やロールバックも容易
　7. 再学習したモデルを再度デプロイし、上記のサイクルを回すことができる

つまり、MLモデルを作って、評価して、デプロイして、モニタリングして、再学習をかけていく、という一連のサイクルが自動化され、効率化されていくという機能です。
もしMLOpsがないと、構築したモデル分、メンテナンス工数が莫大にかかります。

具体的なイメージについてはDataikuのSEがデモを含めた動画を公開しています。
<iframe width="560" height="315" src="https://www.youtube.com/embed/g5MM8sX_CC0?si=dlqjys0PWW6LjmfQ" 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>

とてもわかりやすいです。モデル比較/評価編もあります。

<iframe width="560" height="315" src="https://www.youtube.com/embed/T5i5l2J6ghs?si=ljVdAOZw_lT_ijnp" 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>

繰り返しになりますが、MLモデルは定期的なチューニングが不可欠なので、MLOpsは継続的にROIを向上させるためには非常に重要と考えています。

イギリス本社のオンラインファッション販売企業であるMandM Direct社では、CLTVを分析し、マーケティングの最適化と個別化を実現するために Dataiku を活用し、収益向上やコスト削減を達成しました。このプロセスにおいて、MLOpsを活用し数百のモデルを運用しています。
*引用： MandM - Using Customer Lifetime Value Scores to Understand Inherent Future Value and Deliver Persona


https://community.dataiku.com/discussion/36326/mandm-using-customer-lifetime-value-scores-to-understand-inherent-future-value-and-deliver-persona

また、アメリカの大手HDDメーカーであるWestern Digital は Dataiku の NLP および MLOps を活用し、電子メール分類とウェーハテストを自動化し、毎月100時間を節約、製品品質と業務効率を向上させました。

*引用： Western Digital: Smarter Email Categorization and Quality Control

https://community.dataiku.com/discussion/44696/western-digital-smarter-email-categorization-and-quality-control

今回ご紹介した事例はいずれも海外のものですが、国内でも機械学習が業務に欠かせないものになっていくにつれて、MLOpsの重要性は高まっていくものと思います。

実際に、MLOpsはDataikuユーザ様から関心いただいている内容であり、すでに実装しているお客様も多くいらっしゃいます。

機械学習を活用し、継続的なビジネスの活用を進めていきたい方は、ぜひDataikuをご検討いただければと思います。:thumbsup:
【Liquid】商品タグで表示を切り替え

商品タグをトリガーにして表示の切り替えを行います。

# テーマ
Dawn
※何も手を付けていない状態

# タグ「タグ表示テスト」を商品に追加
![スクリーンショット 2025-02-14-1185.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680582/0e4548e8-0120-4434-a43f-f3739278a1e5.png)


# 以下コードを任意の場所に追加
main-product.liquid の200行目あたりに追加しました。
```:sections/main-product.liquid
<!-- タグの出力 -->
{% if product.tags contains 'タグ表示テスト' %}
タグで表示しています。
{% endif %}
```

## 表示結果
![スクリーンショット 2025-02-14-1186.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680582/6e7fb701-a68a-4f9d-bd7a-4bc0ac6ea229.png)


# 表示の調整（HTMLで記載）
```:Code
<!-- タグの出力 -->
{% if product.tags contains 'タグ表示テスト' %}
 <ul>
  <li>タグで表示しています1</li>
  <li>タグで表示しています2</li>
  <li>タグで表示しています3</li>
 </ul>
{% endif %}
```

## 表示結果
![スクリーンショット 2025-02-14-1187.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680582/ec5f127a-246d-4ea8-b8aa-0f93a7cd3c3c.png)

# 条件分岐
・「タグ表示テスト」があり「タグ表示テストじゃない」がない場合は、「タグ表示テストのみです。」を表示。
・「タグ表示テスト」と「タグ表示テストじゃない」がある場合は「タグ表示テストじゃないが含まれています。」を表示。
・「タグ表示テストじゃない」のみの場合は表示なし。

```:Code
{% if product.tags contains 'タグ表示テスト' %}
 {% unless product.tags contains 'タグ表示テストじゃない' %}
  <p>タグ表示テストのみです。</p>
 {% else %}
  <p>タグ表示テストじゃないが含まれています。</p>
 {% endunless %}
{% endif %}
```
# タグ表示テストのみの場合
![スクリーンショット 2025-02-14-1185.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680582/927bdeb0-5a9d-43e2-81e2-f88fdab64ae4.png)

## タグ表示テストのみの場合の表示結果
![スクリーンショット 2025-02-14-1188.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680582/a248dd9f-0660-42f2-9ee2-e9e86adf4fb5.png)

# タグ表示テストじゃないを追加した場合
![スクリーンショット 2025-02-14-1189.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680582/92dcc601-4499-4022-a70d-0a135ef842ed.png)

## タグ表示テストじゃないを追加した場合の表示結果
![スクリーンショット 2025-02-14-1192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680582/a6e9f7db-d849-45e2-9704-0777dc2a74d4.png)

<br><br>
以上となります。
ufw 

```sh
sudo ufw allow 22 comment 'Allow SSH access'
sudo ufw allow 1000:2000/tcp
sudo ufw allow from 1.1.1.1 to any port 80

sudo ufw allow out 4000/udp comment 'gateway'

sudo ufw status
sudo ufw status verbose
```

```
sudo ufw allow "OpenSSH"
```

```
sudo ufw delete allow 3000
sudo ufw delete deny 3000

sudo ufw delete deny 3000/tcp
```

```
sudo ufw enable # 啟用
sudo ufw disable # 停用
sudo ufw reset # 重設
```

```sh
sudo ufw status numbered

[17] 8001/tcp (v6)              ALLOW IN    Anywhere (v6)
[18] 8001/udp (v6)              ALLOW IN    Anywhere (v6)
[19] 8000:8020/udp (v6)         ALLOW IN    Anywhere (v6)
[20] 3000/tcp (v6)              ALLOW IN    Anywhere (v6)

```

```
sudo ufw delete 17
```
フリーWI-FIの危険性

# フリーWI-FIの危険性
フリーWi-Fiは便利ですが、セキュリティリスクも存在します。しかし、適切な対策を講じることで、安全に利用することができます。

## セキュリティ上の懸念点
### 1. 通信の盗聴
フリーWi-Fiでは、暗号化されていない通信が第三者に傍受される可能性があります。特に、パスワードが公開されているフリーWi-Fiの場合、暗号化されていても盗聴のリスクがあります。
### 2. 偽アクセスポイント
攻撃者が正規のフリーWi-Fiを模した偽のアクセスポイントを設置し、ユーザーの通信を傍受する「悪魔の双子（Evil Twin）」攻撃のリスクがあります。
### 3. 中間者攻撃
偽アクセスポイントを利用した中間者攻撃により、通信内容の改ざんや個人情報の窃取が行われる可能性があります。

## 安全な利用のための対策
### 1. VPNの使用
VPN（Virtual Private Network）を使用することで、通信を暗号化し、第三者による盗聴や改ざんのリスクを低減できます。
### 2. HTTPSの確認
重要な情報を送信する際は、必ずHTTPS接続を確認しましょう。ブラウザのアドレスバーに鍵マークが表示されていることを確認してください。
### 3. 機密情報の取り扱い注意
フリーWi-Fi利用時は、インターネットバンキングなど重要な個人情報を扱うサービスの利用を避けましょう。

### 4. 信頼できるネットワークの利用
可能な限り、信頼できる提供元のフリーWi-Fiを利用しましょう。不審なネットワークには接続しないようにしましょう。

## 最新の見解

近年のウェブサイトやアプリケーションのHTTPS化の進展により、フリーWi-Fiの危険性は以前ほど高くないという見方もあります。正しくスマートフォンやPCを使用する限り、フリーWi-Fiは比較的安全に利用できるとされています。

## まとめ

フリーWi-Fiには潜在的なセキュリティリスクがありますが、適切な対策を講じることで安全に利用することができます。VPNの使用、HTTPS接続の確認、機密情報の取り扱いに注意するなど、基本的なセキュリティ対策を心がけることが重要です。最後まで読んでくださり、ありがとうございました。もし改善点や質問があれば、ぜひコメントしてください！

# 参考文献

https://qiita.com/nucoyuyu/items/68adfb6482daf5b8fd3d

https://qiita.com/ockeghem/items/c6a3602d2c2409f89fbb

https://qiita.com/ngkwtys/items/3756edcd690d5b6221cb

https://qiita.com/Katu_any/items/8ab8cb87f74f7c2cf8da

https://qiita.com/uturned0/items/1b1fd8f35d266a810344

https://qiita.com/miyuki_samitani/items/bc157d8b3d5d16eae15c

https://qiita.com/tosiooooooo/items/d0e2f4fd9012239a4db9

https://qiita.com/mindwood/items/1427bd20d22f583ed9d5

https://qiita.com/nucomiya/items/c30c8de57eba7ccdfbe3

https://qiita.com/tags/%E5%8D%B1%E9%99%BA%E6%80%A7
Flutter WebでGoogleMapAPIなどを動的に渡したい

## 今回使用するパッケージ
https://pub.dev/packages/google_maps_flutter

https://pub.dev/packages/google_maps_flutter_web

## パッケージインストール
```zsh
$ flutter pub add google_maps_flutter
```
```pubspec.yaml
dependencies:
  google_maps_flutter: ^2.10.0
```
## 通常の導入
- GoogleMapApiをindex.htmlの`<head>`タグに埋め込む
```diff_html
<html>
    <!-- 省略 -->
    <head>
+     <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
    </head>
    <body>
        <script src="flutter_bootstrap.js" async></script>
    </body>
</html>
```
## 動的に渡す場合
- index.htmlではAPIKeyの設定をしない
```diff_html
<html>
    <!-- 省略 -->
    <head>
- <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
+ 
    </head>
    <body>
        <script src="flutter_bootstrap.js" async></script>
    </body>
</html>
```
- APIの設定はFlutter側で設定をする
下記警告が出るので`&loading=async&callback=initMap`を追加しています
```
Google Maps JavaScript API has been loaded directly without loading=async. This can result in suboptimal performance. For best-practice loading patterns please see https://goo.gle/js-api-loading
```
```main.dart
import 'package:js/js_util.dart' as js_util;
import 'package:flutter/foundation.dart';

void main(){
 if (kIsWeb) {
  const googleMapApiKey = String.fromEnvironment('GOOGLE_MAP_API_KEY_WEB');
  // documentを取得
  final document = js_util.getProperty(js_util.globalThis, 'document');
  // <script> 要素を作成
  final script = js_util.callMethod(document, 'createElement', ['script']);
  // <script> 要素のsrc属性にGoogle Maps APIのURLを設定
  // loading=async と callback=initMap を追加
  final googleMapUrl =
     "https://maps.googleapis.com/maps/api/js?key=$googleMapApiKey&libraries=drawing,visualization,places&loading=async&callback=initMap";
     
  // <script>要素の設定
  js_util.setProperty(script, 'src', googleMapUrl);
  js_util.setProperty(script, 'async', true); // 要らないかもです
  js_util.setProperty(script, 'defer', true);
  
  // <head>に <script> 要素を挿入
  final head = js_util.callMethod(document, 'querySelector', ['head']);
  js_util.callMethod(head, 'appendChild', [script]);
  
  // コールバック関数を設定する
  js_util.setProperty(js_util.globalThis, 'initMap', js_util.allowInterop(() {
   print('Google Maps API loaded successfully!');
   // 地図の描画などの処理を開始
  }));
 }
 runApp(const MyApp());
}
```
## 起動時のコマンド
```zsh
$ flutter run --dart-define=GOOGLE_MAP_API_KEY_WEB=XXXXXXXXXXXXXXXXXXX
```
## ビルド時のコマンド
```zsh
$ flutter build web --dart-define=GOOGLE_MAP_API_KEY_WEB=XXXXXXXXXXXXXXXXXXX
```
Dockerで使う研究ツール

## Gnuplot

```
FROM alpine
RUN apk update && apk upgrade
RUN apk add --update gnuplot fontconfig msttcorefonts-installer
RUN update-ms-fonts
RUN fc-cache -f
RUN rm -rf /var/cache/apk/*
```

```
docker build -t gnuplot -f ~/Dropbox/settings/docker/Dockerfile-gnuplot ~/Dropbox/settings/docker    
cd プロットファイルの場所
docker run --rm -it -v "$(pwd):/temp" gnuplot sh -c "cd /temp;gnuplot ファイル名.plt;exit"
```
## pdfをpngに変換

Dockerファイル(Dockerfile-poppler)
```
FROM alpine
RUN apk update && apk upgrade
RUN apk add --update poppler-utils
```

```
docker build -t poppler -f Dockerfile-poppler .
docker run --rm -it -v $(pwd):/temp poppler sh -c 'cd /temp; pdftoppm -r 150 -png Fig1.pdf image; mv image-1.png Fig1.png ;exit'
```

ディレクトリ内のFig*pdfすべて変換する．
```
for f in Fig*.pdf; do docker run --rm -it -v "$(pwd)":/temp poppler sh -c "cd /temp; pdftoppm -png \"$f\" image; mv image-1.png \"${f%.pdf}.png\""; done
```

## pdfをepsに変換

poppler-utilsを使う．
```
docker run --rm -it -v $(pwd):/temp poppler sh -c 'cd /temp; pdftops -eps Fig1.pdf Fig1.eps'
```

ディレクトリ内のFig*pdfすべて変換する．
```
for f in Fig*.pdf; do docker run --rm -it -v "$(pwd)":/temp poppler sh -c "cd /temp; pdftops -eps \"$f\" \"${f%.pdf}.eps\""; done
```

## latexをtextに変換

```
docker run --rm --volume "$(pwd):/data" --user $(id -u):$(id -g) pandoc/core ファイル名.tex -o ファイル名.txt
```

## ウェブサイト生成

```
FROM ruby

RUN gem install nanoc kramdown
WORKDIR /temp
```

```
cd サイトのデータが有る場所
docker run --rm -it -v "$(pwd):/temp" nanoc bash -c "cd /temp;nanoc;exit"
```
set -e中のwaitにはpidを1つ書こう

シェルスクリプトを書いていたところ、`wait`の思わぬ仕様に面食らってしまいました。

## 問題の発覚

Webアプリケーションのデプロイ処理で、多数のコマンドを呼び出す必要があったので、シェルスクリプトを書いてそれらをつなぎ合わせていました。そして、デプロイ処理を行うマシンのスペックに余裕があったので、並列でコマンドを実行させるようにしました。

```sh
#!/bin/sh

set -e

some_container_build_command &
some_database_seed_command &
wait
some_javascript_bundle_command
some_container_push_command
```

ところがある日のこと、DBのシードに失敗したにもかかわらず、`set -e`でスクリプト全体が失敗することもないままコンテナのプッシュまで進行してしまったことが判明しました。

## 何が起きた？

調べてみると、`wait`の挙動は以下のようなものでした（[POSIX.1-2017](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/wait.html)）。

`wait`（引数なし）→ **自身は0で終了する**
`wait [1個以上のpid...]` → `wait`自体の終了コードは、最後に与えた`pid`のプロセスの終了コード（仮に最後の`pid`が適切でなかった場合は127）

## 対策法

ということで、問答無用に成功する`wait`オンリーはいうまでもなく、最後の1つの失敗しか検知できない複数表記というのも微妙なので、原始的に`wait pid`を個数だけ連ねて対応することにしました。

```sh
#!/bin/sh

set -e

some_container_build_command &
container_build_pid=$!
some_database_seed_command &
seed_pid=$!
wait $container_build_pid
wait $seed_pid
some_javascript_bundle_command
some_container_push_command
```

## 終わりに

日常的に使っているコマンドにすら、想定しないような仕様があることも珍しくない。
Next.JS vs Remix: Which One to Choose in 2025?

<b>What’s common in <b><a href="https://www.ongraph.com/nextjs-vs-remix-which-is-better/">next js vs remix</a></b>?</b>

Both are popular frameworks built on React. When choosing the right framework for building dynamic websites, Remix and Next.js are the popular choices. They both extend React’s capabilities to build high-performance and SEO-friendly web applications.

Both are React-based frameworks offering different approaches for web app development, meeting modern-age web development needs. Learn how NextJS vs Remix differentiates to help you decide which framework to choose in 2025.

<b>Key Differences: Remix vs. Next.js</b>

•	Remix is as fast as Next.js for serving static content, ensuring a smooth user experience.
•	Remix is faster than Next.js at serving dynamic content, avoiding slow loading indicators.
•	Remix performs better on slow networks, loading faster on a 3G connection than Next.js.
•	Remix automatically handles errors, interruptions, and race conditions, while Next.js does not.
•	Next.js encourages client-side JavaScript for dynamic content, whereas Remix doesn’t rely as much on it.

<b>Which React Framework to Choose- NextJS vs Remix?</b>

In the end, the Next.js vs Remix comparison shows that both frameworks are powerful, but each has its own strengths. Next.js is great for developers who want a more structured setup with strong community support and a focus on static and server-side rendering. It’s perfect if you want something that just works out of the box.

On the other hand, Remix is ideal for developers who want more control over things like routing and data loading. It focuses on performance, reliability, and making sure your app works well even in tough conditions (like offline).

By understanding the differences between Next.js and Remix in terms of performance, features, and use cases, you can make a better decision for your project. Both frameworks have clear benefits, and which one you choose depends on what you need and what you’re trying to build.

<b>Original Source of Content</b>: <b><a href="https://www.ongraph.com/nextjs-vs-remix-which-is-better/">Click Here</a></b>
Discord ボットのチャンネル別権限を制限する方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/e062f6e3-8db0-4f0e-93cd-45ed7cbcb091.png)

# 公開チャンネル (ボットを削除)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/e8c3646f-6868-408c-853b-28a4f37b3cee.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/3b8a33e1-a949-4e39-8e0e-fa1e757deefc.png)

# プライベートチャンネル (ボットを追加)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/345cdcd5-5864-4cb3-a4e4-6c9f5f47a7c3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/785318a8-5dbc-4c51-adf7-e850353df3db.png)
ESXi仮想マシン起動時にブートメニューが出せない...

ESXi上仮想マシンを起動するときに、
BIOS画面を表示(F2キー)したり、ブートメニューを表示(ESCキー)したいことがあります。

でも、入力可能な時間が短すぎて、何度もトライしてしまうことがあります。

そんな時にオススメな設定はこちら。

ESXi Host Client画面を表示して、
仮想マシンの設定編集画面を表示します。

仮想マシンオプション > 起動オプション の順に表示して、
[起動遅延時間]に仮想マシンのパワーオンまたはリセット時に、
起動を遅延させる時間を設定できます。

デフォルトは 0 ミリ秒のため、
例えば 5000 ミリ秒に設定すれば
5秒間のボタン押下ちゃんすが生まれます。

これは、vmxファイルの
BIOS.BootDelay = "5000" を設定することを意味します。
2 年以上前に Multilogin の開発を始めたとき、それはユーザーのコンピューターにすでにインストールされているブラウザーのランチャーに過ぎませんでし

https://multilogin.com/antidetect/antidetect-browser/
た。そもそもなぜこのような方法に決めたのでしょうか。まず第一に、より複雑なソリューションを開発するためのコミュニティの信頼がありませんでした。たとえば、無名の会社が高度にカスタム コーディングされたブラウザーを提供しているとしたら、ある程度の疑念を抱かれる可能性があります。

同時に、ブラウザー フィンガープリンティングに対抗しようとしていた他のすべての人は、ブラウザー アドオンを使用して対抗していました。当時、Multilogin は起動時にブラウザーに高度なアドオンを挿入するように設計されていました。ブラウザーは Multilogin からブラウザー プロファイルを作成するための特定のパラメーターを受け取り、その場で構成します。

確立された標準に従うことに何か問題があったのでしょうか。そうではありません。結局のところ、誰もが同じことをしていたのです。私たちが知らなかったこと、そして後になって気づいたことは、Web サイトがアドオンによって書き換えられた後でも、ブラウザーの実際のフィンガープリントを明らかにする方法が複数あるということです。コンテンツ セキュリティ ポリシーに関する記事など、これらの方法のいくつかについては以前にも取り上げましたが、実際には、Web サイトがプライバシー アドオンを使用するブラウザーから実際のフィンガープリントを抽出できる方法は複数あります。

私たちが遭遇したもう 1 つの大きな問題は、JavaScript で記述されたインジェクション メカニズムが、一部の Web サイトで使用されているスクリプトに干渉することです。その結果、一部のユーザーのブラウジング エクスペリエンスが制限され、他のユーザーは特定の Web サイトをまったく使用できなくなりました。これらのケースの一部では、ユーザーは特定のマルチログイン機能を無効にできましたが、プライバシーが低下しました。

唯一の現実的な解決策は、すべてを破棄して独自の Chromium ベースのブラウザーの開発を開始することだったので、私たちはそうしました。数か月の懸命な作業の後、ロゴも名前もないこの Web ブラウザーのアルファ バージョンをリリースしましたが、その結果はテスト チームを驚かせました。

このブラウザーは、ほとんどの人が使用している Chrome と見た目は同じですが、中身は芸術作品でした。では、その中身を詳しく見てみましょう…

Mimic ブラウザの紹介
Mimic ブラウザ (または単に Mimic) は、プライバシーを強化し、ブラウザ フィンガープリントを制御できる Chromium ベースのブラウザです。このブラウザは、ほとんどの人が毎日使用している Chrome とほとんど同じに見えますが、現在使用されている最も効果的なタイプのブラウザ フィンガープリントに効果的に対抗できるようにカスタマイズされています。

Mimic では、複数のブラウザ フィンガープリント メカニズムに対抗するさまざまな方法を導入しています。たとえば、当社の調査によると、多くの主要な Web サイトが AudioContext オブジェクトに基づくフィンガープリント手法を実装し始めています。このフィンガープリントは、いわゆる Uber-cookie フィンガープリント テストによって普及しました。このテストは Cookie とはまったく関係ありません。代わりに、システム ボリュームが 0 であっても、JavaScript 関数で読み取り可能なサウンドを生成します。

Web サイトは、結果に基づいてハッシュを生成し、さまざまなバリエーションを比較してユーザーを識別できます。Mimic は、AudioContext オブジェクトの結果値をマスクし、最終的に Multilogin で作成した各ブラウザ プロファイルのフィンガープリントを歪めることができます。

Mimic に実装したもう 1 つの機能は、WebGL フィンガープリントを制御する機能です。WebGL は「ハードウェア フィンガープリント」の一種で、2 つの異なる方法で機能します。最初の方法は Canvas フィンガープリントに似ており、Web サイトに画像を描画するタスクが与えられます。画像は、使用する OS、ハードウェア、およびドライバーに基づいてさまざまなバリエーションがあり、これらを使用して特定のフィンガープリントを作成できます。

2 番目の方法は、WebGL レンダラー エンジンの機能とサポートされている拡張機能を一覧表示する WebGL ブラウザー レポート テーブル全体のハッシュを生成することに依存しています。ハッシュは、サポートされている最高の WebGL コンテキスト ダンプから取得され、異なるブラウザーを簡単に区別するために使用できます。Mimic は、両方のフィンガープリントをマスクし、Multilogin で作成したプロファイルを通じてそれらを制御するための実行可能なソリューションを提供します。

Mimic ブラウザーは、自動タイムゾーン選択の問題に対するソリューションも提供します。Multilogin では、タイムゾーンはプロキシの場所に基づいて自動的に選択されていました。Linux と Windows では異なるタイムゾーン変数が使用されるため、これが問題を引き起こしました。さらに、Windows のタイムゾーン変数は、他のすべてのオペレーティング システムやアプリケーションが使用する IANA 標準と一致しません。Mimic は、タイムゾーンの選択が問題にならないように、この状況を自動的に処理するように設計されています。

一部のサイトでは、システム フォントの列挙などの高度なブラウザー フィンガープリンティング メカニズムが採用されています。Mimic は、作成するブラウザー プロファイルごとに完全に一意のフォント リストを作成できる唯一のブラウザーです。異なるプロファイルを作成するだけで、ブラウザーが他のすべてを自動的に処理します。

最後に、Mimic ブラウザーは Chromium エンジンに基づいているため、問題が発生する可能性が低く、Web サイトが Mimic を精査する可能性が低くなります。
Win11 24H2 に RSAT をインストール

運用環境で Win11 に RSAT（RemoteServerAdministrationTool/リモートサーバ管理ツール） をインストールしていたのですが、24H2 に更新したらRSATが消えてしまいました。
RSATは24H2（それ以前から）から　オンデマンドインストールになっていますが、インストールプロセスが途中で止まってしまいました。
弊社のプロキシは厳しめなので、通信がフィルタされているのかもしれません。
通信先の切り分けて、通信許可をもらうのが大変なのですが、「言語及びオプション機能ISO」はダウンロードできたので、ISOを使ってインストールしました。

参考：https://techcommunity.microsoft.com/discussions/windows11/24h2-uninstalled-my-rsat-they-fail-to-reinstall/4264758

1. Windows_11_languages_and_optional_features_x64_dvd_dbe9044b.iso をダウンロードする（ISOはこちらの「前提条件」より → https://learn.microsoft.com/ja-jp/azure/virtual-desktop/windows-11-language-packs#prerequisites）
2. ISOファイルをエクスプローラで開いて　DVDドライブとしてマウントする
3. PowerShellを管理者で実行する
4. 以下のコマンドを実行 
```
#ISOをFドライブにマウントしたときの例
#
#RSATのインストール状況確認 StateがFalseならインストールしましょう
#インストールする機能の Name はここでチェックしましょう
Get-WindowsCapability -name RSAT* -online -Source 'F:\LanguagesAndOptionalFeatures' | select name,state
#
#機能の追加 ‐ 上で見つけた名前で機能を指定しましょう
Add-WindowsCapability -Name 'Rsat.ServerManager.Tools~~~~0.0.1.0' -Online -Source 'F:\LanguagesAndOptionalFeatures'
Add-WindowsCapability -Name 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0' -Online -Source 'F:\LanguagesAndOptionalFeatures'
Add-WindowsCapability -Name 'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0' -Online -Source 'F:\LanguagesAndOptionalFeatures'
IPアドレスが変動してもBrawl Stars APIからデータを取得する方法

1.はじめに
私はIDNectというゲームのIDを共有できるアプリを制作・運営しています。アプリのユーザーをいかに増やすかと考えた際に、スマホゲームで人気のありAPIを公開しているブロスタのプロフィールカードを作成する機能があれば、ユーザーが増えるのではという考えに至りました（この機能は今後公開予定）。その際に、サンプルとしてGoogle Colabでコードを実行しようとしましたが、Google colabは毎回IPアドレスが変動するため、APIキーを登録したIPアドレスと一致しないためデータのエラーが発生していました。この問題を解消した方法を以下に書き記します。

2.実装
・Brawl Stars APIに登録 (https://developer.brawlstars.com/#/)
まずAPIに登録する必要があります。ここで躓くことはないと思うので、割愛させていただきます。


・ログインが完了するとキーの発行をします。右上の自分のユーザー名の部分をタップすると、My Accountが選択できると思います。
![Screenshot 2025-02-14 at 7.00.58 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791320/e854a59f-7b9e-41cf-a491-f65486234b3e.png)


My Accountを選択し、右下にあるcreate new keyを表示してください ![Screenshot 2025-02-14 at 7.03.41 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791320/005e49e6-e43a-4cee-9af1-933dcceb8d27.png)
そうするとこのようにキーを作成できる部分があると思います。Key NameとDescription（説明）の部分は適当に入力しておいて問題ありません。
![Screenshot 2025-02-14 at 7.07.04 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791320/5e18a4fc-c475-4eb5-87aa-addec41d64ef.png)
Allowed IP Address←ここに45.79.218.79を入力してください
今回使用するのはRoyale APIが提供するProxyです。（Proxyというのはどういうものなのかはご自身で調べてください）
そしてapiを取得する際には本来のURL、https://api.brawlstars.com にアクセスする必要がありますが、今回は固定IPアドレスにするためhttps://bsproxy.royaleapi.dev を使用してください。
Royale APIについては以下の画像を参照してください。
![Screenshot 2025-02-14 at 7.10.19 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791320/c5145d6a-04f2-423d-926b-85ae5832ae3b.png)

![Screenshot 2025-02-14 at 7.10.28 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3791320/6841fa72-acb6-425e-b245-77660bba672a.png)


そしてgoogle colabで以下のコードを実行すれば指定したユーザーのデータを取得できます
``` python
import requests

BASE_URL = "https://bsproxy.royaleapi.dev"
API_TOKEN = "あなたのAPIキー"

HEADERS = {
    "Authorization": f"Bearer {API_TOKEN}",
    "Accept": "application/json"
}

player_tag = "#PLAYER_TAG"

def get_player_data(player_tag):
    encoded_tag = player_tag.replace("#", "%23")
    url = f"{BASE_URL}/players/{encoded_tag}"
    response = requests.get(url, headers=HEADERS)
    if response.status_code == 200:
        return response.json()
    else:
        print(f"Error: {response.status_code}, {response.text}")
        return None

player_data = get_player_data(player_tag)

if player_data:
    print("プレイヤーデータを取得しました:")
    print(player_data)
else:
    print("プレイヤーデータの取得に失敗しました。")


```

3.おわりに
特に書くことはありませんが、固定IPアドレスがなくてもBrawl stars apiからデータを取得できます。ぜひデータ分析などでご利用ください。
自分のIPアドレスを知るには以下のコードを使用することで取得することもできます。
```python
import requests

ip = requests.get('https://api.ipify.org').text
print(f'Current IP Address: {ip}')
```
ちょっと不思議なSemantic UI Reactのバグ

## 経緯

テスト環境でいろいろ触っていたところ、`<Select />`の初期値に設定していた`"Select..."`の選択肢がどんどん増えていく現象に遭遇。

最初はこうですが、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495159/79edcbe7-e5ce-4243-b5e1-2613853f08f1.png)

"s"と入力し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495159/577de511-d3ba-4c80-8540-2cfaf0637738.png)

"p"も入力し、（この時点でちょっとおかしい、、）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495159/26d7ab68-25cc-4bdc-8ada-0f1bad518135.png)

"p"を削除するとあら不思議！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495159/84eb80ef-45c3-487b-bf8a-e3646b05af7f.png)

`"Select..."`が増えました！！（なんで？？）
ちなみに、"s"と"sp"を行ったり来たりする度に一つずつ増えます。（なんでさ、、）

## 環境

- node.js: 20.12.0
- その他パッケージ
  ```json: package.json(抜粋)
  "dependencies": {
    "react": "^18.0.0",
    "react-dom": "^18.0.0",
    "react-scripts": "^5.0.0",
    "semantic-ui-css": "2.5.0",
    "semantic-ui-react": "2.1.5"
  }
  ```

## 原因

きっちりとした原因はわかりませんが、特殊な条件が上手いこと組み合わさった結果、こういった不具合が発生するようです。

再現可能なコードが以下です。

```jsx: App.jsx
import { Select } from "semantic-ui-react";

const dataList = [
    { id: "0", name: "ALL STARS" },
    { id: "1", name: "Special Team No.1" },
    { id: "2", name: "Team No.2" },
    { id: "3", name: "Team No.3" },
];

export default function App() {
    const options = dataList.map(x => {
        return { key: x.id, value: x.id, text: x.name };
    });
    options.unshift({ key: 0, value: 0, text: "Select..." });

    return (
        <Select search options={options} defaultValue={0} />
    );
}
```

これをもとに、いろいろ動かして、原因っぽいものを列挙すると以下になります。

### 1. `key`や`value`に型が違うだけの同じ値がある

`"Select..."`の値を`-1`とかに変えると再現しないので

```js
options[0] = { key: 0, value: 0, text: "Select..." };
options[1] = { key: "0", value: "0", text: "ALL STARS" };
```
   
### 2. 1の2つと、それ以外を合わせた3つ以上に同じ文字が含まれている

今回は`"S"`や`"T"`です。
`"A"`や`"O"`などはでは再現しません。

```js: "s"で紐づくもの
options[0] = { key: 0, value: 0, text: "Select..." };
options[1] = { key: "0", value: "0", text: "ALL STARS" };
options[2] = { key: "1", value: "1", text: "Special Team No.1" };
```

```js: "t"で紐づくもの
options[0] = { key: 0, value: 0, text: "Select..." };
options[1] = { key: "0", value: "0", text: "ALL STARS" };
options[2] = { key: "1", value: "1", text: "Special Team No.1" };
options[2] = { key: "2", value: "2", text: "Team No.2" };
options[2] = { key: "3", value: "3", text: "Team No.3" };
```

:::note warn
`"L"`では再現しないため、もう少し条件がありそうです。
`"Special Team No.1"`の`l`の後ろに入っているのが半角スペース（記号）なところが怪しいです。
:::

### 3. `search`属性を使っている

値の検索で起きているので、条件には必須かなと。


## 対策

一番簡単なのは、`key`や`value`に、型変換した場合に同じ値が入らないようにすることです。

```diff_jsx
- options.unshift({ key: 0, value: 0, text: "select..." });
+ options.unshift({ key: "-1", value: "-1", text: "select..." });
```

とりあえず今回はこれで回避しました。
LINUX - Linux Is Not UniX!

再帰的頭文字

LINUX = Linux Is Not UniX

GNU = GNU's Not Unix!
it is pronuanced g-noo , as one syllable with no vowel sound between the g and the n.

MNU = Mount is Not Umount
MIPS = Microprocessor without Interlocked Pipeline Stages
ELF = Executable and Linkable Format

ELFファイルを調べるのに[Capa]というのを使うようです
PS2(ゲーム機)だけでなくLinuxでよく見かけるファイル形式

[*]はすべてを意味して

[?]は１文字だけを意味している
*.elf　全ての.elf
*.ELF　全ての.ELF

?Launch.elf=uLaunch.elf/wLaunch.elf

u?aunch.elf uL?un?h.elf
大文字と小文字は区別され大文字が重要ファイルに使われる。

mc?:/*/BOOT.ELF PLAYSTATION2のどちらのmcでも認識できて全てのパス(path)のBOOT.ELFという意味です...

sudo mount -t vfat /dev/sd?1 /media/usb0
だと変動するsda1 sdb1 sdc1などを意識せずマウントができます。
自分もこれを.bashrcに書いて使用しています。 

便利だと思いますが普通か...(笑)