OmniAICreator/Qiita-1.07M huggingface dataset:
OpenWeatherMapのAPIを使用してみて

## 初めてのAPI導入

入道雲が出現したらそれをお知らせしてくれるアプリケーションを作成しようとした時に、APIを使用して気象情報を持ってくる必要がありました。APIを使ったアプリケーションを作成するのは初めてだったので、次回使用するまでに忘れないようにここに記録しようと思います。

## 使用したAPI
今回はOpenWeaherMapAPIを使用しました。

理由
- 無料で使用できる機能が多い
- 他と比べて使用制限などが少ない
- 欲しい情報が全て取得できる
　

参考資料
[人気の天気APIをまとめてみた](https://qiita.com/cnakano/items/ff3fd90f685f4ca363cc)
##  リクエスト
``` 
https://api.openweathermap.org/data/2.5/weather?q=$cityName&appid=$apiKey&units=metric
```
$cityName：観測する都市の名前を入力する。今回は岩手県滝沢市(Takizawa)を入力した
$apiKey：APIキーを入力する
## レスポンス
```
{
    "coord": {
        "lon": 141.0736,
        "lat": 39.7662
    },
    "weather": [
        {
            "id": 501,
            "main": "Rain",
            "description": "moderate rain",
            "icon": "10n"
        }
    ],
    "base": "stations",
    "main": {
        "temp": 284.52,
        "feels_like": 284.17,
        "temp_min": 284.52,
        "temp_max": 284.52,
        "pressure": 1009,
        "humidity": 94,
        "sea_level": 1009,
        "grnd_level": 966
    },
    "visibility": 3121,
    "wind": {
        "speed": 6.1,
        "deg": 174,
        "gust": 19.22
    },
    "rain": {
        "1h": 3.95
    },
    "clouds": {
        "all": 100
    },
    "dt": 1732628804,
    "sys": {
        "country": "JP",
        "sunrise": 1732570357,
        "sunset": 1732605225
    },
    "timezone": 32400,
    "id": 2111834,
    "name": "Takizawa",
    "cod": 200
}
```
　
## 使用してみての感想
APIを使ったことで、アプリの可能性が大きく広がることを実感しました。これまでは、自分が作ったデータやロジックだけで完結するアプリを作っていましたが、外部データを取り入れることで、ユーザーにとってもっと便利でリアルタイム性のあるアプリを提供できることがわかりました。また、天気データを表示する機能を実装したとき、『これは自分だけでなく、誰もが役立つアプリにできる！』という気持ちが湧きました。
add_indexとは何か

## indexとは
データベースの「索引」のようなものです。
例えば、図書館で本を探すとして、
・indexあり → 本棚を1冊ずつ探す (遅い)
・indexなし → 索引で位置がわかる (早い)

## 基本的な使い方
```
# 書き方
add_index :テーブル名, :カラム名, オプション
# 例
add_index :books, :title, unique: true
```

## メリット・デメリット
メリット:
・検索が速くなる

デメリット: 
・データの追加、更新が遅くなる
・データベースの容量を使う

大量のデータがある場合には有効、少量のデータには良くない。よく探すものには付けておく。
取得する内容を指定できるWeb APIの実装

## はじめに
APIを設計する際、ユースケースに応じて適切なデータを返すことが大切です。しかし、ユースケースが多い場合、専用のエンドポイントを都度作成するのは非効率で、使いづらいAPIになってしまいます。また、一括取得のAPIだけに頼っていては、シンプルではありますが、不必要な大量のデータも送信してしまいます。

１つの解決策としては、1つのエンドポイントで多くのデータを返しつつ、レスポンスの内容をユーザが選択可能するというものです。

## fieldsパラメータを使った実装例

クエリパラメータを使用する事で、ユーザが取得したいデータを指定できます。Userの中からid,名前が欲しい場合は以下のように書きます。

```GET http://localhost:3000/users?fields=id,name```

これを実現すべく、RailsでAPIを書いてみます

### 実装例（Rails API）

`User`モデルの情報を取得するAPIにfieldsパラメータを追加しています。
```ruby
class UsersController < ApplicationController
  def index
    users = User.all
    fields = params[:fields]&.split(',')  

    if fields.present?
      users = users.select(fields.map(&:to_sym))
    end
    
    render json: { users: users }, status: :ok
  end
end
```

## リクエスト例
***100人のUser情報が登録されています。（レスポンス内容は途中省略）***

全てのデータを取得する場合： ```GET http://localhost:3000/users```
レスポンス：
```json
{
    "users": [
        {
            "id": 1,
            "name": "SampleTaro",
            "email": "taro@example.com",
            "created_at": "2024-10-09T11:54:52.242Z",
            "updated_at": "2024-11-25T09:29:41.242Z",
        },
        {
            "id": 2,
            "name": "Hanako",
            "email": "hanako@example.com",
            "created_at": "2024-10-09T12:43:58.409Z",
            "updated_at": "2024-11-11T02:04:17.931Z",
        },
        ...
        {
            "id": 100,
            "name": "miyagi masamune",
            "email": "masamune@example.com",
            "created_at": "2024-11-26T13:33:13.520Z",
            "updated_at": "2024-11-26T13:33:13.537Z",
        }
    ]
}
```
特定のデータだけを取得する場合：```GET http://localhost:3000/users?fields=id,name```
レスポンス：
```json
{
    "users": [
        {
            "id": 1,
            "name": "SampleTaro"
        },
        {
            "id": 2,
            "name": "Hanako"
        },
        ...
        {
            "id": 100,
            "name": "miyagi masamune"
        }
    ]
}
```

## 比較
全てのデータを取得する場合：
![スクリーンショット 2024-11-26 224119.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798823/d07fa1dc-6c38-9d9a-a509-68216552efe8.png)


特定のデータだけを取得する場合：
![スクリーンショット 2024-11-26 224101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798823/7128d799-b361-53c8-589b-a5f0ccb5fd08.png)

通信コスト、データサイズが削減出来るのは勿論ですが、クライアント側で不要なデータを無視するロジックを書く手間も省けます。

## まとめ
fieldsパラメータを利用することで、APIの柔軟性、効率性を向上出来ます。
API設計を始めたばかりの人にとって、少しでも参考になれれば幸いです

## 参考資料
[Web API: The Good Parts] https://www.oreilly.co.jp/books/9784873116860/

[RESTful のウェブ API 設計で避けるべき 6 つのよくあるミス] https://cloud.google.com/blog/ja/products/api-management/restful-web-api-design-best-practices/
24/11/26 読書記録 ~ソフトウェアテストの教科書~

# 書籍
[【この1冊でよくわかる】 ソフトウェアテストの教科書](https://amzn.asia/d/6jSYRVM)

# 書籍を読む目的

 - [ ] 「品質」を理解する
 - [ ] 品質を担保できるテストを理解する


# Part1. ソフトウェアテストの基本

## Chap01. ソフトウェアテストとは？

### 学び 📝

#### ソフトウェアテストの目的
誤動作を起こさず、ユーザの欲求を満たすソフトウェアを作るため。

テストをする目的はバグを防止するだけではない。
**ユーザのやりたいこと（要求）を実現するためにも必要である。**

#### ソフトウェア品質とは？
ISO/IEC 25010は、システムやソフトウェアの品質を評価するための国際規格。
以下のソフトウェアの品質特性に分類。

1. 機能適合性：ユーザが満足する機能の提供ができているか？
2. 性能効率性：限られたリソースの中で、どれだけ高いパフォーマンスを維持できるか？
3. 互換性：他のシステムやプラットフォームとどれだけスムーズに連携できるか？
4. 使用性：ユーザが使用しやすいシステムか？
5. 信頼性：システムが安定して動作するか？エラーや障害を最小限に留められるか？
6. セキュリティ：不正アクセス、データ漏洩等から、どれだけユーザを保護できるか？
7. 保守性：ソフトウェアの変更が容易か？
8. 移植性：ソフトウェアが異なるプラットフォームや環境に移行する際の適応できるか？

また、以上の特性の中には様々な副特性が存在する。
どれも大事な印象。品質への解像度が上がり、非常に良き。

## 参考資料

- [ソフトウェア品質特性の具体例と活用方法：ISO/IEC 25010に基づく解説](https://clane.co.jp/blog/%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E9%96%8B%E7%99%BA/software-quality-characteristics-examples/)
自動売買Botを作る前に知っておくべき5つのこと

 

## 概要  
本記事では、TradingViewおよび[PineScript](https://www.tradingview.com/pine-script-reference/v6/?aff_id=112991&source=qtba-tradingview)を活用して自動売買Botを構築する前に理解すべき重要なポイントについて解説する。アルゴリズムトレードやシステムトレードを検討する際、基礎知識の欠如は思わぬ損失を招く恐れがある。以下の5つの要点を把握することで、堅実な自動売買環境の構築を目指していただきたい。  

## 対象読者  
本記事は以下の読者を念頭に執筆されている。  
- TradingViewの自動売買Botに興味がある方  
- アルゴリズムトレード初心者  
- 自動化によるトレード効率化を模索している方  

---

## 1. **バックテストの重要性**  
自動売買Botを設計する際、バックテストを行うことは極めて重要である。過去の市場データに基づき戦略を検証することで、以下の利点が得られる。  

- **戦略の有効性を確認できる**  
  戦略が過去のデータにおいてどの程度の収益を上げたかを検証することで、実運用における期待値を算出できる。  
- **リスクを評価できる**  
  ドローダウン（最大損失）やリスク・リワード比率を把握することで、リスク許容度を明確化できる。  

ただし、バックテスト結果が良好であるからといって、必ずしも将来のパフォーマンスを保証するものではない点に留意されたい。  

---

## 2. **過剰最適化の危険性**  
バックテストの際に過剰最適化（Overfitting）を行うと、実運用における戦略の信頼性が大幅に低下する恐れがある。特定の過去データに対してのみ適応した戦略は、予測不能な市場環境では機能しない場合が多い。  

### 過剰最適化を避けるための指針  
- **シンプルなルールを用いる**  
  複雑すぎる戦略は過剰最適化のリスクを高める。簡潔で効果的なロジックを優先すべきである。  
- **アウトサンプルテストを実施する**  
  過去データの一部をバックテストに使用せず、そのデータで戦略を検証することで過剰最適化の影響を評価する。  

---

## 3. **アラートとトレードシステムの連携**  
TradingViewではアラート機能を利用してトレードシステムとの連携が可能である。これを活用することで、売買指示を自動的にトリガーするBotを構築できる。  

### 連携の基本的な手順  
1. **PineScriptでアラート条件を定義**  
   例として、以下のコードで条件を指定する。  

   ```pinescript
   alertcondition(crossover(close, ta.sma(close, 20)), title="Buy Signal", message="Price crossed above SMA20")
   ```  
2. **Webhookを設定する**  
   TradingViewのアラート通知先をWebhook URLに設定することで、自動売買Botと通信可能となる。  

3. **Bot側で通知を受信し注文を処理する**  
   Webhook通知を受けたBotがAPIを用いて取引所に注文を送信する設計が一般的である。  

---

## 4. **取引コストとスリッページの考慮**  
バックテストでは取引コストやスリッページ（注文価格と実際の約定価格の差）が考慮されない場合が多い。しかし、これらは実運用において無視できない要素である。  

- **取引コスト**  
  取引手数料は収益率に直接影響を与えるため、バックテスト時に計算式に含めるべきである。  
- **スリッページ**  
  特に流動性の低い市場ではスリッページの影響が顕著となる。このリスクを軽減するため、ロットサイズを適切に調整する必要がある。  

---

## 5. **法規制および取引所ルールの確認**  
自動売買Botを運用する際、法規制および取引所のルールに準拠することは不可欠である。違反が発覚した場合、取引停止や法的責任を負う可能性がある。  

- **国や地域ごとの規制**  
  自動売買が合法か否かを確認する必要がある。  
- **取引所のAPI利用規約**  
  取引所ごとに異なるAPIの使用制限（例：リクエスト数の上限）を把握することが重要である。  

---

## 結論  
自動売買Botの構築は、適切な知識と準備があればトレード効率を大幅に向上させ得る。しかしながら、事前に注意すべき事項を無視すると、予期せぬ損失を被る可能性が高まる。本記事で述べた5つのポイントを念頭に置き、安全かつ効率的なBot運用を目指していただきたい。  

TradingViewおよびPineScriptを用いたシステムトレードが、読者の皆様のトレードライフをより良いものとする一助となれば幸いである。  

---

APIドキュメント：

https://www.tradingview.com/pine-script-reference/v6/?aff_id=112991&source=qtbb-tradingview

---

## 免責事項  

本記事に記載されている内容は、筆者がTradingViewおよびPineScriptを用いて学び得た知識と経験を基に執筆したものである。内容の正確性および完全性については可能な限り配慮しているが、必ずしもその保証をするものではない。  

自動売買Botの構築や運用、またそれに関連する投資活動は読者自身の判断と責任に基づいて行われるべきであり、筆者および本記事を掲載するプラットフォーム（Qiita）は、それによって生じたいかなる損失や損害に対しても一切の責任を負わないものとする。  

特に、トレードに関する意思決定は市場リスクを伴うため、実運用前に十分な検証とリスク評価を行い、必要に応じて専門家への相談を推奨する。  

読者各位の責任において本記事をご活用いただければ幸いである。
objectSetを下へ下へ

mayaのobjectSetは階層化できますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/540844e6-c0f8-831e-ac54-69274d1acffd.png)

この階層構造を取得したいんですけども、さてさて

試す
--

階層なのでとりあえず listRelativesを試してみる。

```python
cmds.listRelatives("set3",ad =True)
```

なにも返ってきませんでした。

sets コマンドの説明を眺めてみてもー

https://help.autodesk.com/cloudhelp/2022/JPN/Maya-Tech-Docs/CommandsPython/sets.html

うーん、なさそうですね。


再帰処理で下ってく
--

今回はAPIを眺める事はせず、pythonで再帰処理させて下へ下へと掘り進んでみます。


```python

def getSetsHierarchy(setName,parentSets,setNameList):

    ## setName に属しているobjectSetの取得
    setMembers = cmds.sets(setName,q=True) or []
    setMembers = cmds.ls(setMembers, type = "objectSet") or []

    ## 次に掘り進む用リスト。　スタートから現在掘り進んでるとこまで
    tmpParentSets = list(parentSets)
    tmpParentSets.append(setName)
    
    ## setName に属しているobjectSetをリストに追加    
    for setMember in setMembers:
        setLongName = "|".join(tmpParentSets)+ "|" + setMember
        setNameList.append(setLongName)
        
        ##自身を呼び出して掘り進む
        setNameList = getSetsHierarchy(setMember,tmpParentSets,setNameList)
           
    return setNameList
```

さて実行してみると

```python
getSetsHierarchy("set3",[],[])
# Result: ['set3|set7', 'set3|set7|set8', 'set3|set4', 'set3|set4|set5', 'set3|set4|set5|set6', 'set3|set2', 'set3|set2|set1'] # 
```

を取れましたね。


階層が取得できれば、これをもとに再構築するのも出来そうですね。
react-timer-hookを使った話

react-timer-hookでカウンターを作るとき、「second」の値は60秒を超えることがないので、以下のようなコードで60秒を超過した表現ができる

const totalSeconds(のような変数) = minutes * 60 + seconds;


また、カウントをリセットするとき、カウントを停止しておくには、以下のようなコードで簡単にできる。

restart(****, false);

このようにrestartをfalseにするだけ。

誰かの役に立ちますように。
Webサービスの認証方式のFIDO、WebAuthn、Passkeyの整理

# 概要
パスワードレス認証にFIDO、WebAuthn、Passkeyというのがあるのは何となく知っていたのですが、ごちゃごちゃになっていたので、調べて整理してみました。

# 結果
![図１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3870537/a7c48e39-c697-a69f-bcbb-7ca5397c31a9.png)

## FIDO/FIDO2
パスワードに代わる本人認証技術やその規格
生体認証や公開鍵認証方式などの技術を組み合わせパスワードレス認証を実現する
※ FIDO1.0を踏襲した新しい規格としてFIDO2が2018年に公開
※ FIDO2が主流

## CTAP
クライアントとオーセンティケーター間の通信を定めた規格（プロトコル）

## WebAuthn
Webアプリでの認証のためのAPI仕様（プロトコル）

## Passkey
FIDO2の秘密鍵をクラウド経由で同期する仕組み
ubuntu20.04 今更のphp7.3とpearの利用

今更ですが、過去のシステムでのpear利用を出来るだけ既存のubuntuで設定してみた覚書。
phpの普及と共に付加されたクラスライブラリのpearは今後利用を利用は考えられないが、現存しているシステムからの移行の為の環境構築としての記載です。
ubuntu20.40での標準構成では、pearが問題なく使えるphp7.3を強制的にインストールし、その環境下にpearをインストールするものです。
今回はkagoya.jpのKAGOYA CLOUD VPSを利用して、ubuntu20.40を選択し構築しました。
一般的なapache及びphpパッケージをインストール。
```
apt -y install apache2 php7.3 php7.3-common php7.3-cli php7.3-fpm php7.3-mysql php7.3-pgsql php7.3-dev php7.3-mbstring php7.3-zip
```

```
update-alternatives --config php
There are 2 choices for the alternative php (providing /usr/bin/php).

  Selection    Path             Priority   Status
------------------------------------------------------------
  0            /usr/bin/php8.4   84        auto mode
* 1            /usr/bin/php7.3   73        manual mode
  2            /usr/bin/php8.4   84        manual mode

Press <enter> to keep the current choice[*], or type selection number: 

```
php7.3に適合するphpmyadminをインストール下記サイトよりwgetする。
https://www.phpmyadmin.net/files/
今回は、Admin-5.2.1-all-languages.tar.gzを指定。
設置場所/usr/shareへ移動。
```
cd /usr/share
wget https://files.phpmyadmin.net/phpMyAdmin/5.2.1/phpMyAdmin-5.2.1-all-languages.tar.gz
tar -zxvf phpMyAdmin-5.2.1-all-languages.tar.gz
mv phpMyAdmin-5.2.1-all-languages phpmyadmin
chmod -R 0755 phpmyadmin
cp -p ./phpmyadmin/config.sample.inc.php ./phpmyadmin/config.inc.php
cd /etc/apache2/sites-available/
vi phpmyadmin.conf

Alias /phpmyadmin "/usr/share/phpmyadmin/"
<Directory "/usr/share/phpmyadmin/">
    Order allow,deny
    Allow from all
    Require all granted
</Directory>

a2ensite phpmyadmin.conf
systemctl reload apache2
```
【ZABBIX7.0LTS】"Template App Zabbix Server"にアイテム追加

## はじめに
「ZABBIX 7.0」では、pollerプロセスの非同期実行による監視効率化のため、以下のプロセスが追加されました。これらのプロセスを使用するにあたり、使用率を確認しようとしましたが、デフォルトの「Template App Zabbix Server」にはこれらのプロセスの使用率を確認するためのアイテムが存在していませんでした。そこで、今回はアイテムを追加し、これらのプロセスの使用率を確認できるようにしたいと思います。

　【agent poller】
　　Zabbix Agent（パッシブ）のデータ取得を非同期で行う poller プロセス
 
　【http agent poller】
　　Web監視（パッシブ）のデータ取得を非同期で行う poller プロセス
 
　【snmp poller】
　　SNMP（パッシブ）のデータ取得を非同期で行う poller プロセス


【テンプレート：Template App Zabbix Server】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727351/aab892c3-9bfb-6136-73e2-a8c865b9283a.png)

【Template App Zabbix Serverの「pollerプロセス」使用率アイテム】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727351/8e94b0e7-4016-bc2b-ea11-0236cccc391e.png)

## agent poller 用のアイテム作成
既存の「Utilization of poller data collector processes, in %」アイテムなどを複製し、「agent poller」用の使用率アイテムを作成します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727351/371b81ec-b243-3aa0-5d6b-66339d94f736.png)

:::note info
使用するキー：
【zabbix[process,\<type\>,\<mode\>,\<state\>]】
特定のZabbixのプロセスもしくはプロセスグループ（\<type\>や\<mode\>で特定できるもの）が\<state\>で消費している時間のパーセントテージ

[**【\[ZABBIX 7.0\] 8. Internal checks】**](https://www.zabbix.com/documentation/7.0/en/manual/config/items/itemtypes/internal#process)
<img width=600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727351/e9693293-e6f0-8cda-eb2d-4855fc6ca632.png">
以下でもどういったタイプがあるか把握することができる。
[**【\[ZABBIX 7.0\] Server process types and threads】**](https://www.zabbix.com/documentation/current/en/manual/concepts/server#server-process-types-and-threads)
<img width=600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727351/3a6ccd6e-78f6-d67b-4944-6625d0deaf0b.png">


:::
作成した「Utilization of agent poller data collector processes, in %」アイテム

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727351/be7e1ce9-85cc-cf07-1fdd-d5c93fd764c4.png)

## agent poller 用のトリガー作成
既存の「Zabbix poller processes more than 75% busy」トリガーなどを複製し、「agent poller」用のトリガーを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727351/b0ac021d-21c2-e88c-7a36-13b5d9913753.png)

作成した「Zabbix agent poller processes more than 75% busy」トリガー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727351/1ee292d4-80b5-5ade-848f-8a478cf134c6.png)

## agent poller 用のアイテムをグラフに追加
既存の「Zabbix data gathering process busy %」グラフに、作成した「Utilization of agent poller data collector processes, in %」アイテムを追加します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727351/202838d8-f827-3350-0aae-be2794020e95.png)

既存の「Zabbix data gathering process busy %」グラフに作成した「Utilization of agent poller data collector processes, in %」アイテムが追加された。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727351/e77804a0-74fa-3782-bcee-a9994992db99.png)

同様に残り２つのプロセスも作成する。

## 参考資料
・[Zabbix 7.0 の紹介 - poller プロセスの非同期実行による監視の効率化](https://www.sraoss.co.jp/tech-blog/zabbix/zabbix70-newfeature-latest/)
スワップ領域をまだディスク領域使って作成してます？メモリを使った zram の紹介

# はじめに
界隈では AWS re:Invent 2024 でざわつき始めている中、少し Tips 的な内容も投稿していこうかなと思い始めた [@\_\_\_nix___](https://twitter.com/___nix___)  です。

# 背景
古くからサーバーを OOM Killer（Out Of Memory Killer） で停止させられないようスワップ領域を作成しておくことで、一時的なメモリ不足を補ってきました。

```shell
# スワップ領域作成
dd if=/dev/zero of=/swapfile bs=1M count=4096
chmod 0600 /swapfile
mkswap /swapfile
swapon /swapfile

# 起動時の設定
/etc/fstab
/swapfile    none    swap    sw    0   0
```

※ちなみにスワップ領域の目安も示されたりしていました。
[Red Hat Enterprise Linux](https://docs.redhat.com/ja/documentation/red_hat_enterprise_linux/6/html/storage_administration_guide/ch-swapspace#ch-swapspace)

ディスクによるスワップはやはりパフォーマンスに激しく影響が出ることと、特にクラウド環境でスペックが変動できるような環境だと設定変更が面倒だったりもしました。


# 概要
そこで登場したのがzramです。（以前は compcache と呼ばれていたそうです）
zramは、RAM内に圧縮されたスワップ領域を作成し、ディスクI/Oを削減しながらメモリの使用効率を向上させる技術です。

zramは、従来のスワップファイルとは異なり、メモリ上に圧縮ブロックデバイスを作成します。これにより、高速なデータアクセスが可能となり、ディスクベースのスワップファイルによる遅延を回避できます。また、zramは動的にサイズを調整できるため、一時的なメモリ不足にも柔軟に対応できます。

# 導入

## 導入環境
zramは以下のOSとバージョンで利用可能です。

* Ubuntu: 22.04以降
* Amazon Linux: 2023以降
* ...

## 導入手順
今回は Ubuntu22.04 の手順を紹介します。

```shell
# インストール
sudo apt install systemd-zram-generator

# 設定
vi /etc/systemd/zram-generator.conf

## 設定内容
grep -v '#' /etc/systemd/zram-generator.conf
[zram0]
host-memory-limit = none
zram-fraction = 0.5
compression-algorithm = zstd

# デーモン設定
sudo systemctl daemon-reload
sudo systemctl start systemd-zram-setup@zram0.service

# 確認（以下のどれでも確認可能）
zramctl
swapon --show
free -m
```

# 設定

## 設定ファイル zram-generator.conf
zram-generator.confは、zramの設定を行うための主要なファイルです。このファイルでは、zramデバイスのサイズや使用する圧縮アルゴリズムなどを指定します。

|Key|Value|Sample|
|---|---|---|
|host-memory-limit|ホストシステムが持つメモリの最大量を制限します。|none|
|zram-fraction|zramとして割り当てるメモリの割合を設定します。|0.5|
|compression-algorithm|使用する圧縮アルゴリズムを指定します。（後述）|zstd|


## 圧縮アルゴリズム
zramでは複数の圧縮アルゴリズムが利用可能であり、それぞれに特徴があります。

|アルゴリズム|圧縮率|圧縮速度|解凍速度|特徴|
|---|---|---|---|---|
|LZ4|低|非常に高速|非常に高速|高速性重視で一般的な用途に適している|
|Zstandard (ZSTD)|中〜高|高速|高速|圧縮率と速度のバランスが良く調整可能|
|ZLIB|高|中|中|高い圧縮率で互換性が高い|
|Snappy|低|高速|高速|Google開発、高速性重視|
|RLE (Run-length encoding)|可変|高速|高速|連続した同じデータに効果的|
|DEFLATE|中〜高|中|高速|ZLIBの基盤で広く使用されている|
|LZW|中|高速|高速|GIFやZIPで使用されており特許切れ|

これらのアルゴリズムから選択する際は、システムの特性や使用状況に応じて最適なものを選ぶことが重要です。例えば、高速性が求められる場合はLZ4やSnappyが適しており、高い圧縮率が必要な場合はZLIBやZstandardが有効です。 このように、zramはメモリ管理の新しいアプローチとして注目されており、その設定や使用する圧縮アルゴリズムによってシステムパフォーマンスを大きく改善することが可能です。

# 終わりに

マシンリソースを有効に使うというより、私の発想は背景にも書いた通り変更が面倒だから何とかならないかと思い、最近になってスワップについて調査したところ、zram に行き付きました。

やはりITエンジニアは「怠惰を求めて勤勉に行き着く」のだと改めて実感させられました。

# 一言

最近は kubernetes にもどっぷりなのですが、k8s クラスタではスワップメモリは設定しないことが奨励されているのでこの zram の出番はありませんでした。（残念）

この記事良かったと少しでも思って頂けたら是非 [@\_\_\_nix___](https://twitter.com/___nix___) をフォローしてあげてください。或いは記事に対してリアクションをお願い致します。
Pythonでの欠損値の扱い方

## 背景
pythonでの欠損値の扱い方を良く間違えるので、備忘録的にまとめておきたい

## None
- NoneType型の唯一の値

### Noneの判定方法
- XXX is None

## numpy.nan
- float型における非数を表す値

### NaN(Not A Number)の判定方法
- pandas.DataFrame.isna
- pandas.DataFrame.isnull
- pandas.Series.isna
- pandas.Series.isnull
- numpy.isnan

## 参照
- https://docs.python.org/3/library/constants.html
- https://numpy.org/doc/stable/reference/constants.html#numpy.nan
技術力強化のため、Qiita投稿習慣化を開始

## 現状

フロント
- React
    - 文法をなんとなく覚えた状態
- NEXT.js　CI/CD　デプロイ
    - x

バックエンド
- ASP.NETの開発経験

ASP.NET以外でUIの開発ができない状態。

## 学習のきっかけ

「新しい技術を知ることが好きなのに、新しい技術の話についていけない」ことにヤキモキし続けていたので、本格的な学習を決意。

## 目標

短期：上記の習得
中期：自分用のタスク管理アプリの作成
長期：副業案件の取得

## JISOUのメンバー募集中！
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
実践的なカリキュラムで、あなたのエンジニアとしてのキャリアを最短で飛躍させましょう！
興味のある方は、ぜひホームページからお気軽にカウンセリングをお申し込みください！
▼▼▼

https://projisou.jp/
Azure DevOps で Basic Process で、Iteration を生成する

# 背景

Basci Plan において、Iteration を作る際に powershell で作りたかったので調査した備忘録

https://learn.microsoft.com/ja-jp/azure/devops/organizations/settings/work/inheritance-process-model?view=azure-devops&tabs=basic-process

# スクリプト

- start to end で月曜日から日曜日までの一週間後との iteration を作成

```powershell: create iteration on basic process
# 設定
$organization = "https://dev.azure.com/organization"
$project = "Project"
$rootIteration = "\Project\Iteration\Sprint 1"
$startDate = [datetime]::Parse("2024-11-01")
$endDate = [datetime]::Parse("2024-11-30")

# devops config
az devops configure --defaults organization=$organization project=$project

# create iteration
$currentDate = $startDate
while ($currentDate -le $endDate) {
    $iterationName = "Iteration " + $currentDate.ToString("yyyy-MM-dd")
    $iterationPath = $rootIteration 
    $iterationStartDate = $currentDate
    $iterationEndDate = $currentDate.AddDays(6) # 日曜日まで
    if ($iterationEndDate -gt $endDate) {
        $iterationEndDate = $endDate
    }

    Write-Host "Creating iteration: $iterationName at $iterationPath from $iterationStartDate to $iterationEndDate"

    az boards iteration project create `
        --name "$iterationName" `
        --path "$iterationPath" `
        --start-date "$iterationStartDate" `
        --finish-date "$iterationEndDate"

    $currentDate = $currentDate.AddDays(7)
}
```

# あとがき

agile とかの他のプロセスでもいけそうよね
【Mac】curlを使用してファイルをダウンロードする方法

## ファイルをダウンロードする

`curl`を使用してファイルをダウンロードするには`-O`を使用して以下のようにします。

```terminal
curl -O [URL]
```

`[URL]`はダウンロードしたいファイルのURLです。
`-O`オプションは、URLの最後の部分をファイル名として使用して保存することを意味します。

例えば、以下のURLから画像ファイルをダウンロードしたいとします。

```text
https://example.com/image.jpg
```

この場合、ターミナルを開いて次のコマンドを入力します。

```terminal
curl -O https://example.com/image.jpg
```

このコマンドを実行すると、カレントディレクトリに`image.jpg`という名前でファイルが保存されます。

ダウンロードしたファイルに特定の名前を付けたい場合は、`-o`オプションを使用します。

```terminal
curl -o my_image.jpg https://example.com/image.jpg
```

このコマンドを実行すると、`my_image.jpg`という名前でファイルが保存されます。

## 参考

https://curl.se/docs/manpage.html
IAMロールを除却したらgithub actionsが使えなくなった件

# GitHub ActionsとAWS連携の設定手順（OIDC利用）

GitHub ActionsでAWSと連携する際に、OIDCを使用してIAMロールを引き受ける設定を行います。本記事では、Terraformで設定したIAMロールを削除してしまった場合に、AWSコンソールから再作成する手順を説明します。

## エラーの状況

GitHub Actionsで以下のエラーが発生しました：

```
Error: Could not assume role with OIDC: Not authorized to perform sts:AssumeRoleWithWebIdentity
```

このエラーは、GitHub ActionsがIAMロールを引き受けるための設定が正しく行われていない場合に発生します。具体的には、OIDCプロバイダーやIAMロールの設定に問題がある可能性があります。

## 解決手順

### 1. IAMロールをAWSコンソールから作成

#### **信頼関係の設定**

1. AWSマネジメントコンソールで **IAM** にアクセスします。
2. 左メニューから「ロール」を選択し、「ロールを作成」をクリックします。
3. **信頼されたエンティティの種類** として「Web ID プロバイダー」を選択します。
4. **OIDCプロバイダー** に `token.actions.githubusercontent.com` を選択。
   - **クライアントID（aud）** は `sts.amazonaws.com` を指定。
5. **条件** を設定：
   - 条件キー: `token.actions.githubusercontent.com:sub`
   - 演算子: `StringLike`
   - 値: `repo:cynaps-inc/ba-cloud-infrastructure:*`

#### **権限の設定**

1. 必要なポリシーをIAMロールにアタッチします。今回は管理者権限を付与する例を示します：
   - **AWS 管理ポリシー** から **AdministratorAccess** を選択。
2. 設定が完了したら「次へ」をクリック。

#### **ロールの詳細設定**

1. ロール名を入力します（例: `github-actions-cicd-role`）。
2. 必要に応じて説明を追加。
3. 「ロールを作成」をクリック。



### 2. 信頼関係ポリシーの確認

作成したIAMロールの「信頼関係」タブを開き、以下の内容が設定されていることを確認します。

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<AWSアカウントID>:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:cynaps-inc/ba-cloud-infrastructure:*"
        }
      }
    }
  ]
}
```

- `<AWSアカウントID>` を自分のAWSアカウントIDに置き換えてください。



### 3. GitHub Actionsの設定

`.github/workflows/<workflow>.yml` ファイルで、`aws-actions/configure-aws-credentials` の設定を以下のように変更します。

```
- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v4
  with:
    role-to-assume: arn:aws:iam::<AWSアカウントID>:role/github-actions-cicd-role
    aws-region: <AWSリージョン>
```

### 4. GitHubリポジトリの設定

1. リポジトリの「Settings」 → 「Actions」 → 「General」を開きます。
2. 「Workflow permissions」で「Read and write permissions」を有効にします。

### 5. ワークフローの確認

GitHub Actionsで再度ワークフローを実行し、正常に動作することを確認します。

## まとめ

IAMロールの設定を削除してしまっても、AWSコンソールから簡単に再作成できます。本手順を参考に、GitHub ActionsとAWSのOIDC連携を正しく構成してください。
【手軽に脆弱性診断】Dockerを利用したOpenVASインストール方法

# 概要

こんにちわ。<a href="https://www.z.fore-co.ltd/" target="_blank">株式会社フォアーゼット</a>にてペンテスターをしている<a href="https://x.com/AyatoShitomi" target="_blank">Ayato</a>です。弊社は主に脆弱性診断やペネトレーションテストを国内外の各種企業及び政府機関に提供しており、<a href="https://www.z.fore-co.ltd/bugbounty" target="_blank">バグバウンティプラットフォーム「ZoneZero」</a>の運営も行っております。

本記事では、脆弱性スキャンツールの「OpenVAS」のセットアップ方法について書き記そうと思います。

## OpenVASとは

OpenVASとはオープンソースの脆弱性診断ツールです。

できること：

- 脆弱性の検出
- 脆弱性の一括管理
- NASL（Nessus Attack Scripting Language）を利用したプラグイン

イメージとしてはNessusの無料版みたいなとらえ方をすると分かり易いかも知れません。

# セットアップ

Dockerを利用して手軽に構築を進めます。

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

```bash
mkdir OpenVAS && cd OpenVAS && curl -f -O https://greenbone.github.io/docs/latest/_static/setup-and-start-greenbone-community-edition.sh && chmod u+x setup-and-start-greenbone-community-edition.sh && ./setup-and-start-greenbone-community-edition.sh
```

以下の画面が出たら、設定したいパスワードを入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1523062/f91ec404-cc86-094b-f71e-46a4dc895940.png)

```
Password for admin user: 設定したいパスワードを入力してエンターを押下
```

その後、セットアップが完了します。

## ログインの実行

以下のURLへアクセスを行います。


`http://127.0.0.1:9392/`

http://127.0.0.1:9392/

ログイン画面が出てくるので、以下のクレデンシャル情報でログインを行います。

```text
admin
設定したいパスワード
```

ログインが完了しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1523062/dd93e3a1-f75a-4400-bbb1-b87fab5a4828.png)

これにてセットアップが完了です。


# 参考

https://www.kali.org/tools/gvm/

https://tex2e.github.io/blog/linux/openvas-installation

https://medium.com/@hotakoma/running-openvas-in-a-wsl-kali-linux-environment-993ebe4ff0

https://qiita.com/komajo/items/48f02beac6a31187288d

https://qiita.com/UTDoi/items/7b2c054dcc85bc2285ca

https://greenbone.github.io/docs/latest/22.4/container/index.html
[Unity] InspectorからProjectSettingsを開く

例えばInspectorに```ProjectSettings/Graphics```を開くボタンを追加する場合、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/e090e3f2-b6bf-c215-5477-3f36a243755b.png)

こんな感じになります。

```
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

#if UNITY_EDITOR
[CustomEditor(typeof(Foo))]
public class CoreUrpChangeEditor : Editor
{
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        if (GUILayout.Button("Open ProjectSettings/Graphics"))
        {
            SettingsService.OpenProjectSettings("Project/Graphics");
        }
    }
}
#endif

public class Foo : MonoBehaviour
{
    void Start()
    {
    }
    void Update()
    {
    }
}

```

[SettingsService.OpenProjectSettings](https://docs.unity3d.com/ja/2019.4/ScriptReference/SettingsService.OpenProjectSettings.html)
機械学習のモデルファイルをDocker環境に保持する方法

Docker環境を使って機械学習の推論をする場合、モデルファイルをどのように保持するのかという問題に付きあたる。

モデルファイルのダウンロード、モデルファイルの最適化 optimizeなどの処理をDocker環境の構築 docker build あるいは　Docker環境の中で 毎回行うのは、時間がかかりすぎてもったいない。
「ねえ、動いているのを見せてよ」となったときに、docker run の直後にすぐに実行してみせたい。


## 選択肢１：Dockerfileの中に手順を記述する。
例： wget, gdown などを使って、指定のURLからダウンロードする。
RUN wget -o {保存するファイル名} ${URL}

## 選択肢２：保存先のディレクトリを、host環境のフォルダとする。
pretrained モデルをダウンロードするのが、推論時に実行するスクリプトの中で行われている場合もある。

#### 標準時の状況
この場合には、ダウンロードが、guest環境内のディスク領域に保存される。
`docker run --rm` のオプションが指定されているときには
guest環境内のディスク領域は、基本毎回再構築される。

```
docker run -it --rm --net=host --runtime nvidia -e DISPLAY=$DISPLAY \
	-v ${GIT_ROOT}/depth-anything-zed/weights:/root/depth-anything-zed/weights \
```
この例では、weightsのフォルダをhost環境をマウントしておくことで永続化させている。

こうすれば、既にダウンロード済みのファイルがあるときには、再度のダウンロードをしなくて済む。

## 選択肢３：docker run 時の --rm オプションを付けない。
こうすると、docker runを実行するたびに、前のディスクの状況が引き継がれるようになる。
利点：　これだけで、dockerのguest環境のディスクの状況が保持される。
欠点：　毎回の動作が、それまでの動作結果のディスクの状況で影響受ける。
発生しやすくなるトラブル：
　今の環境では、たまたまあるファイルがディスクにあるので動作している。
　しかし、別の環境ではそのファイルがないので動作しない。
　そういうことが起こりやすくなる。

基本、おすすめしない。

## 追記:　ZED SDK のDEPTH_MODE.NEURAL_PLUSを利用の場合
上記のモードでは、実行時にモデルをダウンロードし、optimizeを実行している。
実行後に以下のファイルが作られている。
このファイルはzed_sdk のインストーラーの実行では、生成されない。
/usr/local/zed/resouces/neural_depth_3.6.model
選択肢３のやり方では対処できなかった。
選択肢２のやり方を応用して対処するのがいいだろう。
USER_WEIGHT_CACHE のようなところを永続化の領域とする。
1. /usr/local/zed/resouces/neural_depth_3.6.model がなくて、USER_WEIGHT_CACHEにあれば、
    USER_WEIGHT_CACHEのを/usr/local/zed/resouces/neural_depth_3.6.modelにコピーする。
1. どちらにもなければ、何もしない。
1. python3 スクリプト.py
1. USER_WEIGHT_CACHEになければ、/usr/local/zed/resouces/neural_depth_3.6.modelをUSER_WEIGHT_CACHEにコピーする。
1. docker環境を終了する。

こんな手順になるだろうか。
Salesfroce コピーについて

Salesforceで通常のコピー方法を確認します


# 通常のコピー方法
通常の場合コピーボタンを配置することによりコピーが可能です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/620b23c7-8959-511b-d0c3-72a522c9a9a7.png)


通常コピーボタンの場合、以下のような制約があります

・コピー画面の配置の制約
コピー画面はページレイアウトの画面となります

・コピー時の項目
ページレイアウトの配置の項目が表示されるは必ずデフォルトで設定されている
（特定の項目のみ空欄　という設定はできない）

また、ページレイアウトに表示されない項目はコピーされない
（ページレイアウトには表示されない裏持ち項目はコピーできない）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/0b1f9275-dfc4-7f7b-8385-62624bea6551.png)


なお、コピーの項目を指定する場合、別途アクションの作成が必要です


# アクションでのコピー方法

アクションの作成はこのようになります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/b7c3ce95-837a-7008-d3e6-61ccb8460cc0.png)

数式はこのようになります

/lightning/o/Opportunity/new?defaultFieldValues=
Name={!Opportunity.Name},
CloseDate={!TEXT(Opportunity.CloseDate)}

この数式の場合、商談名と完了予定日が空欄ではない状態でコピーすることが可能です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/df288348-e022-bcd9-d92c-393292cce487.png)
DevToys Extension を作ろう！ (今ならブルーオーシャンかも)

# DevToys？
- Microsoftが作った  [DevToys](https://devtoys.app/ "DevToys - A Swiss Army knife for developers") というアプリ、開発者向けの便利ツールを集めたもので、コンバーターやらエンコーダーやらUUIDやら、よく(たまに？)使いがちで作るの面倒だから適当なツールを探しがちなものが揃ってる。

- 1.~の頃は、GUIでWindowsのみで便利だけどイマイチな感じだったものが、2.0になるにあたり、全面的に書き直されたようで、GUIとCUIの両対応で、更にMacやLinuxもサポートされるということでなかなか面白そうな展開になりそうだけど、いまいち盛り上がってない界隈っぽい
- CUIがサポートされたということであれば、Power Shellとかからスクリプトに組み込めるよね。

## Extension ？
- DevToys 2.0で、Extensionの仕組みが用意されて、自分で拡張機能を作ったり公開したりできるようになった。2.0が出たのが、2024年の6月

[開発者向け万能ナイフの次期版「DevToys 2.0」がプレビュー、Mac/Linuxにも対応](https://forest.watch.impress.co.jp/docs/news/1600061.html)

それから、5ヶ月くらい経つのにExtension 全然増えてない！ (204/11/26 現在で 29個)

https://www.nuget.org/packages?q=Tags%3A%22devtoys-app%22

## ブルーオーシャン では？

 - そう、今ならDevToysのExtension作って公開すれば、目立てるチャンスですぜ？

 - なんか作って公開したいなぁと思っても既にコミッターがたくさんいたり、ある程度揃ってたりして、モチベーション沸かないものが多いですからね

## チュートリアルから

こちらのページで、作り方の解説があります。

https://devtoys.app/doc/articles/introduction.html

- ページは英語ですが、Google翻訳で頑張れば画面出せる・・・かな？
私は最初うまくできなくて、時間のあるときにぼちぼちといじってたら出せるようになりました。

- 今のところ説明も少なめだし複雑な画面遷移とかも作れないのでシンプルで理解しやすいかもです。

- 近いうちにサンプルプロジェクトをGitHubにコミットしたい、できたらいいなぁ。そのまま書いても動かないサンプルもあるからね

## NuGetパッケージ
- Visual Studio とか使ってるとお世話になるNuGetの形式の配布です。
- これで配布とかやってみたいよねぇの練習になるのでは？

## こんなの作りたい
- 全角半角変換 (ありがちだけど)
- 郵便番号とか、全国地方公共団体コード変換 (複雑なロジックなさそうだし)
- HTMLからテキスト抽出 (全体じゃなくて、Select~option から選択肢だけ抜きたいとかよくやるので)
- CSVデータに自動的にシングル、またはダブルクオーテーションつけるやつ (たまに必要になるけど地味に面倒な作業だよね)
- [banner](https://ja.wikipedia.org/wiki/Banner_(UNIX)) Unixのコマンドにあるやつ、文字でっかく#で表示するやつ (意外と面倒かも)
- なんかくだらないやつ・・・まだ思いついてないけど

###### 8年ぶり位の記事だ
- 10年くらい前に作ったQiitaのアカウントに書く8年ぶり位の記事です。
- まだ何もできてないけど作りたい・・・といつも思ってできないけど
- あー、これくらいなら自分にもと思った方、オープンソースでなんか作りません？
中学生だけどスマホないから友人と冬休み中に雑談できないからIRCを構築した話

# 中学生だけどスマホないから友人と冬休み中に雑談できないからIRCを構築した話
.
.
.
.
「は？」#多くの人は、こうなると思います.

### ことの成り行き旅
1.友人宅にて数人遊ぶ予定があり雨天決行と言われたため、待ち合わせ場所で待つ。
.
.>>>3 hours later<<<
.
.
.
2.誰も来ない。(雨の中3時間待ったおかげで近くを通ったおまわりに白い目で見られた)

3.ワイ;「理由を答えよ。」(友人にKIKU) 友人:「うちの家で遊べなくなったから」
友人B: 「ごめん! kkは、LINEやってないから連絡できんかった 」
ワイ:「.....それなら....うん(?)」

---3 weeks later---

## ワイ；「そや、IRC作れば　スマホなくても雑談できるやんっ(LINEもbotで)」
ということで、始まったIRC制作
古の技術は、今も引き継がれる。　過去があるから未来がある。　
そういう感じです。
[Ubontuの公式サイトの記事](https://ubuntu.com/tutorials/irc-server#1-overview)これを参考にgithub codespace上で構築を始めました。(後でdockerにしてrender.comでホストします。)
と、うにゃうにゃしてて[工程.7](https://ubuntu.com/tutorials/irc-server#7-run-the-server)で詰まりました。
えー、
```bash
ERROR: Cannot open config file: /workspaces/IRC/inspircd-2.0.25/run/conf/inspircd.conf Exiting...
```
なんか、エラーが出ました。
```bash
./inspircd start
```
これができないと進めません。
うん、オワタ　ワイは、苦手だしー
ということで、ubontu ASKで質問しました(qiitaにも書いた。)
[実際の質問](https://askubuntu.com/questions/1533937/i-would-love-to-build-an-irc-but-cant)
そこには、githubのURLも貼っときました。
誰か、教えてくれる。　そう願って...
ワイは、年明けの初詣で世界平和を願ってみたら、　
災害が起きました。戦争が起きました。　
どうなるのでしょうか、、、、
【I2Localization】中国語設定

# 端末のシステム言語にゲーム内言語を設定する

:::note info
みたいな感じで端末のシステム言語は簡単に取得できます。
:::

```c#:
// 端末のシステム言語を取得
var systemLanguage = Application.systemLanguage;
```

# 端末言語  !=  I2Localization初期言語
I2Localizationで中国語を設定する際、I2 Languagesのプレハブから言語を追加すると思うのですが、
### `中国語の初期設定がシステム言語と一致していないので注意。`

:::note info
### `Android,iOSのシステム言語`
中国語(簡体) → ChineseSimplified
中国語(繁体) → ChineseTraditional
:::

:::note info
### `I2Localizationの初期言語設定`
中国語(簡体) → Chinese (Simplified)
中国語(繁体) → Chinese (Traditional)
:::

となっており、
```c#:
void Start()
{
    // 端末のシステム言語を取得
    var systemLanguage = Application.systemLanguage;

    // システム言語に対応する文字列を用意
    string language = systemLanguage.ToString();

    // システム言語がI2ローカライズで使用可能か確認
    if (LocalizationManager.HasLanguage(language))
    {
        // 現在のUIテキスト言語をシステム言語に設定
        LocalizationManager.CurrentLanguage = language;
    }
    else
    {
        // ローカライズ不可なものは英語に設定
        LocalizationManager.CurrentLanguage = "English";
    }
}
```

とした際、

システム言語が仮に中国語(簡体)だった時

LocalizationManager.CurrentLanguage = language;
は`language == ChineseSimplified`
なのですが、I2Localization的には
`language == Chinese (Simplified)`
でないといけないのでこのコードだと英語にローカライズされてしまう。

# 対応
:::note info
I2Localizationのプレハブを変更する
:::

![スクリーンショット 2024-11-21 124206.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3847430/e09e08d6-e733-e6bd-6a49-ef828c4183b9.png)

:::note info
Languagesから`Chinese (Simplified)`になっている個所を`ChineseSimplified`にしたら終了
:::
![スクリーンショット 2024-11-21 124214.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3847430/ca2d0aea-b691-64d7-a1cc-d5e278ec028f.png)

設定ボタンなどで言語を切り替えたい際も、
```c#:
 // このボタンが押されたら言語変更
 simplifiedChineseButton.onClick.AddListener(() => LocalizationManager.CurrentLanguage = "ChineseSimplified");
```

:::note info
I2Localizationに設定した文字列と同じものをLocalizationManager.CurrentLanguageに入れてやると、中国語対応できました。
テスト自動化エンジニアシラバス：テスト自動化ソリューションの検証

# はじめに

テスト自動化エンジニアのシラバスを再度読み直し、各章をDailyで読めるようにしてみた

https://www.istqb.org/certifications/test-automation-engineer

7 Verifying the Test Automation Solution  を今回は翻訳・解説する

# テスト自動化環境の検証計画（テストツールのセットアップを含む）

当たり前のことですが、テスト自動化を実行させる前に、テスト自動化環境およびTASの他のすべてのコンポーネントが期待通りに動くことを検証する必要がある。
各ステップは次のとおりです

## テストツールのインストール、セットアップ、構成、カスタマイズ

TASは多くのコンポーネントで構成され、信頼性と再現性のあるパフォーマンスを保証するために必要です。
自動化されたインストールスクリプトや手動配置があり、定期的なサービスパックやアドインで互換性を確保します。
自動インストールやリポジトリからのコピーにより、異なるSUTで同じバージョンと構成のTASを保証できます。アップグレードもリポジトリを通じて行われ、標準的な開発ツールと同様のプロセスが適用されます。

## テスト環境のセットアップ/ティアダウンの再現性

TASは、さまざまなシステム、サーバー、およびCI/CDパイプラインをサポートするために使われる。
TASがどのテスト環境でもうまく動くようにするためには、TASをテスト環境にロードしたりアンロードしたりするための計画が必要です。
TASの構築や再構築が、どのテスト環境でも同じように動くことが重要です。

TASの設定管理を行うことで、特定の設定を確実に作成できます。
これが終わったら、TASの各部分を文書化します。
これにより、テスト環境が変わったときに、TASのどの部分が影響を受けるか、または変更が必要になるかを理解しやすくなる。

## 内部および外部のシステム/インターフェースとの接続性

TASを特定のSUT環境にインストールした後、SUTを使う前にいくつかのチェックを行う必要がある。
これには、内部システムや外部システム、インターフェースへの接続が利用可能かどうかを確認することが含まれる。

具体的例
1. サーバーにログインする。
2. テスト自動化ツールを起動する。
3. テスト自動化ツールがSUTにアクセスできることを確認する。
4. 設定を確認する。
5. システム間のテストログとテストレポートの権限が適切に設定されていることを確認する。

これらの前提条件を確立することで、TASが正しくインストールされ、構成されていることを確認できる。

## TAFコンポーネントのテスト

TAFコンポーネントもアプリケーションと同様に、個別にテストおよび検証する必要がある。機能テストと非機能テストです。
また、テストログとテストレポートは、テスト自動化とSUTの動作の状態に関する正確な情報を生成する必要がある。
非機能テストの例としては、TAFのパフォーマンス低下、メモリリークなどの欠陥を示す可能性のあるシステムリソースの利用、およびTAF内および/またはTAF外のコンポーネントの相互運用性の欠如の理解などが挙げられます。

# テスト自動化スクリプト、スイートの期待通りの動作

自動テストスイートは、完全性、一貫性、および正しい動作についてテストする必要がある。
さまざまな種類の検証チェックを使って、自動テストスイートがいつでも使用可能であるか、使用に適しているかを確認する。

## テストスイートの構成をチェック

完全性をチェックします（たとえば、すべてのテストケースに期待される結果があり、テストデータが存在すること）。
また、TAFとSUTの正しいバージョンを確認します。

## TAFの新しい機能に焦点を当てた新しいテストを検証

TAFの新しい機能が初めてテストケースで使用される場合、その機能が正しく動作することを確認する。

## テストの再現性を考慮

テストを繰り返す場合、一貫性を持ってテスト結果は常に同じである必要がある。
レースコンディションなどにより信頼できるテスト結果が得られないテストケースは、一旦アクティブな自動化テストスイートから外し、原因特定の分析する必要がある。
そうでなければ、これらのテストの実行を繰り返し分析するのに時間がかかってしまう。

## 自動化テストツールの侵入性を考慮

TASは多くの場合、SUTと密接に結合されます。
これは、相互作用のレベルに関してより良い互換性があるように設計されている。
しかし、この緊密な統合は、悪影響をもたらす可能性もあります。
たとえば、TASがSUT環境内に配置されている場合、SUTの機能は、手動でテストを実行する場合と異なる可能性があり、パフォーマンスにも影響を与える可能性がある。

高いレベルの侵入は、本番環境では明らかではないテスト中に失敗を示す可能性があります。
これが自動テストで失敗を引き起こす場合、TASに対する信頼が大幅に低下する可能性があります。
開発者は、テスト自動化によって特定された障害を可能であれば手動で再現し、分析を支援する必要がある場合があります。

# テスト自動化による予期しない結果の特定

テストスクリプトが予期せず失敗または成功した場合、根本原因分析が必要です。
これには、テストログ、パフォーマンスデータ、セットアップ、テストスクリプトのティアダウンの検査が含まれます。
断続的な障害は分析が難しく、欠陥はテストケース、SUT、TAF、ハードウェア、ネットワークに存在する可能性があります。
システムリソースの監視やテストログの分析が役立ちます。
必要に応じて、テストアナリストや開発者のサポートを受けることも重要です。
また、すべてのアサーションが適切に配置されているか確認することも必要です。

# 静的解析によるテスト自動化コード品質の向上

静的コード解析は、プログラムコードの脆弱性や欠陥を発見するのに役立つ。
自動スキャンにより、SUTの欠陥をレビューし、コード品質基準を満たすことができます。
これは、DevSecOps実装において重要な役割を果たします。
スキャン結果は重大度で分類され、開発チームは優先順位を設定できます。
静的解析ツールは、コードの修正提案や品質向上のためのアドバイスを提供します。
テスト自動化コードもスキャン対象に含めることで、セキュリティリスクを軽減できます。
Oracle Analytics Cloud：セマンティック・モデルの読み込みを高速化にまつわるシステム設定

はじめに
---
2024/3 アップデートでセマンティック・モデルの読み込みをパラレルで実行できるようなパラメータが追加されました。大規模なデータセットの読み込みが遅く、システムの処理時間に影響を与える場合は、このオプションを有効にするとパフォーマンスが向上する可能性があります
設定を試してみます。

![g1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/46816cb3-cab9-4ba8-678c-c8b5063cefec.jpeg)

前提
---
・OACの管理者権限をもっている

設定
---
コンソールを開き、システム設定をクリックします
![g2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/740121a6-5952-1cb2-4669-6d288e4eb167.jpeg)

左部で、"Perfomance and Compatibility"をクリックします
![g3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/e93aa070-0649-aa9b-b109-c6e73451f57f.jpeg)

少しスクロールダウンし、"Load Semantic Models Using Multiple Threads"のツマミを右に移動します。オンにします。
![g4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/6d10a602-d84d-a6cb-c996-46f4f9fc92af.jpeg)

上部右、"Apply"をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516153/08ab2d0a-106c-b722-785c-e62d5f7071dc.png)

有効化されるまで暫くかかります。のメッセージが表示され、その後、有効化されます。

以上
Discordのアクティビティに好きなものを表示するアプリを作ってみた【動作説明】

# Duck-tivity Now 動作説明

## 1. メイン画面の概要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591292/e3d254b9-6465-62c7-4395-bed0e0347b2d.png)

メイン画面は以下の3つの主要な部分で構成：
1. Discordアプリ選択ドロップダウン
2. サブカテゴリ選択ドロップダウン
3. 操作ボタン群

## 2. 基本操作

### 2.1 Discordアプリの管理
1. メイン画面の「Discordアプリ管理」ボタンから遷移
2. 新規アプリの追加：
   - Discord Developer Portalから自身のアプリのクライアントIDをコピー
     ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591292/60911986-ece2-b43c-e1e1-472396689efd.png)

   - クライアントIDを入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591292/cc45dfc6-a462-d467-f4bd-a45626a10006.png)

   - 「追加」ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591292/f1a2b4d5-d98e-e6f4-d48b-33e59ee2abdc.png)
3. アプリの削除：
   - 各アプリの右側にある「削除」ボタンをクリック

### 2.2 サブカテゴリの管理

1. メイン画面でアプリケーションを選択した状態で「サブカテゴリの管理」ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591292/1ea607c3-7cd8-d8fe-ecef-c158fea03480.png)

2. 新規サブカテゴリの追加：
   - テキストボックスに表示したい内容を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591292/37f2b0df-d4b6-0cfe-4eeb-3439be5c0bc8.png)

   - 「追加」ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591292/ec6d8693-0893-72f2-a3ed-b568de06d8d3.png)

3. サブカテゴリの編集：
   - 「編集」ボタンをクリック![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591292/149928c4-43e5-f77a-25f5-d06857e7a5e5.png)

   - 内容を変更![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591292/a9f62bbb-ab27-85b3-b946-475525397afc.png)

   - 「確定」ボタンをクリック
   - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591292/2573ad78-082a-49df-679c-f597151c7854.png)

4. サブカテゴリの削除：
   - 「削除」ボタンをクリック

### 2.3 アクティビティの表示

1. メイン画面でDiscordアプリとサブカテゴリを選択
1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591292/180791e4-5e1e-5529-118e-103ef1962453.png)

2. 「開始」ボタンをクリック
2. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591292/26441380-5400-5f10-8b6d-46f2780ea621.png)

   - Discordのステータスに選択した内容が表示される
   - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591292/2a6b040f-e64d-34d8-0e3d-f3b362ee7098.png)

   - 表示を停止する場合は「終了」ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591292/0a2bb6ee-9159-9741-7092-51481592db20.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3591292/db7def01-fe39-2b78-2855-f1013eee854a.png)
created


# created

createdフックは、Vueインスタンスの初期化後に実行されるライフサイクルフックです。このフックでは、dataプロパティにアクセスできますが、DOMにはまだアクセスできません。<br />
この記事では、createdフックの使い方を確認し、業務でよく使うケースも紹介します。

### createdフックでdataにアクセス
まずは、createdフックでdataプロパティにアクセスできることを確認します。以下のコードでは、createdフック内でcolorプロパティを更新し、コンソールに出力します。
```vue
<template>
  <div id="app">
    <h1 ref="title">Hello Vue!</h1>
    <button @click="changeColor">Change Color</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      color: 'blue',
    };
  },
  methods: {
    // this.$el を使ってルート要素にアクセス
    changeColor() {
      // ルート要素の背景色を変更
      this.$el.style.backgroundColor = 'lightyellow';

      // $refs を使って特定の要素にアクセス
      this.$refs.title.style.color = this.color;

      // 色をトグル
      this.color = this.color === 'blue' ? 'green' : 'blue';
    },
  },
  created () {
    this.color = 'red'
    console.log(this.color)
  }
};
</script>
```
出力結果
```bash
red
```
createdフック内でcolorの値をredに変更し、コンソールに出力できました。期待どおりですね！

### createdフックでDOMにアクセスできないことを確認
次に、createdフックではDOMにアクセスできないことを確認します。以下のコードでは、createdフック内で$refs.titleを使用してDOM要素にアクセスしようとしています。

```vue
<template>
  <div id="app">
    <h1 ref="title">Hello Vue!</h1>
    <button>Change Color</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      color: 'blue',
    };
  },
  methods: {
  },
  created () {
    console.log(this.$refs.title.style.color)
  }
}
</script>
```
出力結果
```bash
TypeError: Cannot read properties of undefined (reading 'style')
```
$refs.titleがundefinedになり、エラーが発生しました。これは、createdフックの段階ではまだDOMが生成されていないためです。

### 業務でのcreatedフックの活用例
業務でよく使うパターンとして、propsを受け取り、その値をもとにdataを初期化するケースがあります。以下の例では、propsで受け取ったstatusを判定し、is_displayを更新しています。
```vue
<template>
  <div>
    <h1>{{ message }}</h1>
  </div>
</template>

<script>
export default {
  props: {
    message: {
      type: Number,
      required: true,
    },
    status: {
      type: Integer,
      required: true,
    }
  },
  data() {
    return {
      is_display: 'false',
    };
  },
  created() {
    // createdフック内でpropsを参照
    if (status) {
      this.is_display = true
    }
  },
};
</script>
```
このように、propsを使った条件分岐はcreatedフックでよく利用される実装の1つです。

### まとめ
createdフックは、Vueインスタンスの初期化後に実行され、以下の特徴があります：

dataやpropsにアクセス可能。
DOMにはアクセスできない（エラーになります）。
業務では、propsを元にdataを初期化するのに便利。
この記事でcreatedフックの基本的な使い方と注意点を理解していただけたら幸いです。ぜひ、あなたのプロジェクトでもcreatedフックを活用してみてください！
Pyxelの画像の回転、拡大縮小を使って雪の結晶を降らす

# Pyxelのバージョン
Pyxelのバージョン 2.2.0 (2024年8月リリース) から画像の回転、拡大縮小ができるようになりました(2024年11月現在の最新バージョンは2.2.7)
# 雪の結晶画像
（拡大表示）
![snowflake_image_big.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447010/cad28d0f-e0d2-c30e-45ae-ef378f8ce839.png)
実際のファイル "snowflake_image.png"
1つの雪の結晶の大きさは 48 x 49 ドット
![snowflake_image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447010/1e9aa528-2af7-1f3e-553e-bed799865466.png)
# 実行結果
キラキラしているのはドットが荒いため、縮小した時にドットが欠けたりするから
![snowflake_20241129.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447010/5c529454-cbfc-a440-c812-533b48f53528.gif)
# プログラムについて
 上記画像ファイルを読み込み、雪の結晶3種類をランダムに生成し回転しながら落ちてくるプログラム。Snowクラスと複数の雪の結晶を生成して落ちてくるところは ChatGPT に作ってもらいました。ただし、ChatGPT はバージョン2.1.0 までしか把握していないので rotate や scale パラメーターを加えるとエラー扱いしてきます。
__ChatGPT　いわく__
「Pyxelは積極的に更新されているため、将来的に回転やスケールが公式機能として追加される可能性があります。最新のアップデート情報をGitHubのリリースノートで確認してください。」とのこと

https://github.com/kitao/pyxel/blob/main/docs/README.ja.md
```py
# ランダムな大きさの３種類の雪の結晶が回転しながら落ちてくるプログラム

import pyxel

# 雪の結晶を表現するクラス
class Snow:
    def __init__(self, x, y, size, type, rotate_speed, fall_speed, scale):
        self.x = x
        self.y = y
        self.size = size
        self.type  = type
        self.rotate_speed = rotate_speed
        self.fall_speed = fall_speed   
        self.scale  = scale
        self.rotate = 0      
        
    # 雪の結晶を動かす
    def update(self):
        self.rotate += self.rotate_speed
        self.y += self.fall_speed
        if self.y > 256:            # 画面外に出たら上に戻る        
            self.x = pyxel.rndi(-self.size//8, 256//8) * 8
            #self.y = pyxel.rndi(-256//8, 0) * 8
            self.y = -self.size

    # 雪の結晶を描画
    def draw(self):
        pyxel.blt(
            self.x, self.y,
            # 対応するイメージバンクの番号、x座標、y座標、横サイズ、縦サイズ、透明色
            0, self.type * self.size, 0, self.size, self.size+1, 0,
            # 回転角度(ラジアンでなく度:Degree)、拡大率(1より小さいときは縮小)
            self.rotate, self.scale)

class App:
    def __init__(self):
        pyxel.init(256, 256, title="SNOWFLAKE", capture_scale=1)
        self.snow_size = 48

        # イメージバンク0の座標 (0, 0)に画像ファイルを読み込む
        pyxel.images[0].load(0, 0, "snowflake_image.png")

        # 複数の雪の結晶を初期化
        self.snowflakes = [
            Snow(
                x = pyxel.rndi(-self.snow_size//4, 256//4) * 4,
                y = pyxel.rndi(-256//8, 0) * 8,
                size = self.snow_size,
                type  = pyxel.rndi(0, 2),   # 3種類ある結晶のどれか
                fall_speed = pyxel.rndf(0.6, 1.0),
                rotate_speed = pyxel.rndf(-3, 3),
                scale  = pyxel.rndf(0.5, 0.8)   # 画像の表示倍率
            )
            for _ in range(24)
        ]
        
        pyxel.run(self.update, self.draw)

    def update(self):
        # 全ての雪の結晶を更新
        for flake in self.snowflakes:
            flake.update()

    def draw(self):
        pyxel.cls(5)
        # 全ての雪の結晶を描画
        for flake in self.snowflakes:
            flake.draw()

App()
```
Vue.jsにおけるOptions APIとComposition APIの違い

# Vue.jsにおけるOptions APIとComposition APIの違い

Vue 3の登場により、Vueには新しい記述方法であるComposition APIが追加されました。これまで使われてきたOptions APIと比較して、どのように違うのかを解説します。

## Options API

- **dataオプション内でデータを定義**  
  データは`data`オプションでまとめて管理し、初期値を設定します。
  
- **オプションごとに役割が分かれる**  
  `methods`、`computed`、`watch`、`created`、`mounted`などのオプションを用意し、それぞれの役割に応じた処理を記述します。各オプションで`data`で定義した変数を参照・更新できます。
  
- **コードが機能ごとに分離される**  
  データ、メソッド、ライフサイクルフック（`created`、`mounted`など）がオブジェクト形式で分かれて記述されるため、ある程度の規則性があり、Vueに慣れていれば読みやすい構成になっています。

### サンプルコード (Options API)

```vue
<template>
  <div>
    <h1>{{ title }}</h1>
    <p>Current Count: {{ count }}</p>
    <button @click="increment">Increment</button>
    <button @click="decrement">Decrement</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      title: 'Vue 2 Options API Counter',
      count: 0
    };
  },
  methods: {
    increment() {
      this.count += 1;
    },
    decrement() {
      this.count -= 1;
    }
  },
  created() {
    // 初期化時に実行するロジックを記述
  },
  mounted() {
    // DOMがマウントされた後に実行するロジックを記述
  }
};
</script>
```

### 説明
このように、**`data`オプションで定義したデータを`methods`やライフサイクルフック（`created`や`mounted`）で更新**できます。各要素が独立してオブジェクト内に記述されるのが特徴です。

## Composition APIの特徴

- **`setup`内でデータと関数を定義**  
  `setup`関数はコンポーネントが初期化される際に一度だけ呼び出され、ここでリアクティブなデータや関数を定義します。データとロジックを1つの場所に集約でき、柔軟に管理できます。

- **リアクティブなデータの定義**  
  `ref`や`reactive`を使ってリアクティブなデータを設定します。例えば、プリミティブな値には`ref`を、オブジェクトには`reactive`を使うのが一般的です。

- **関連するロジックをまとめて管理**  
  Options APIとは異なり、データとそれに関連するメソッドを同じスコープで管理できるため、特に複雑なコンポーネントでは見通しが良くなります。

### サンプルコード (Composition API)

```vue
<template>
  <div>
    <h1>{{ title }}</h1>
    <p>Current Count: {{ count }}</p>
    <button @click="increment">Increment</button>
    <button @click="decrement">Decrement</button>
  </div>
</template>

<script>
import { ref } from 'vue';

export default {
  setup() {
    // リアクティブデータの初期化
    const title = ref('Vue 3 Composition API Counter');
    const count = ref(0);

    // メソッドの定義
    const increment = () => {
      count.value += 1;
    };

    const decrement = () => {
      count.value -= 1;
    };

    // `setup`で定義した変数を返すことで、テンプレートからアクセス可能に
    return {
      title,
      count,
      increment,
      decrement
    };
  }
};
</script>
```
### 説明
Composition APIでは、`setup`関数内でデータとメソッドを定義し、テンプレートから直接利用可能にします。`ref`や`reactive`を使ってリアクティブデータを定義し、柔軟に構成できるのが特徴です。

## Options APIとComposition APIの違いまとめ

- **Options API**: データとロジックがオプションごとに分かれて記述され、コードが機能別に整理される。
- **Composition API**: 関連するデータとロジックを1つの`setup`関数内に集約し、より柔軟なコード設計が可能。

### まとめ
Options APIは分かりやすく、Composition APIは柔軟です。用途やプロジェクトの規模に応じて適切なAPIを選択しましょう。
beforeMountについて

# beforeMount

beforeMountは、コンポーネントがマウントされる直前に呼び出されるライフサイクルフックです。
「ん？それじゃあcreatedと何が違うの？」と思ったので、GPTさんに聞いてみました。

## createdとbeforeMountの違い
| 特徴 | created | beforeMount |
|-----------|-----------|-----------|
| 呼び出しタイミング | インスタンス作成後、テンプレートがレンダリングされる前 |仮想DOMが実際のDOMにリンクされる直前|
| DOMアクセス |DOMにアクセスできない|$elや$refsでDOM要素にアクセス可能|
| 主な用途 | データの初期化、非同期処理の開始 |DOMが作成される直前の処理（特殊な場合）|

らしいです。
一番の違いはcreatedDOMにアクセスできないが、beforeMountはDOMにアクセスできる点ですね。

### 実際に検証してみよう
以下のコードでbeforeMountフックの挙動を確認してみました。

```vue
<template>
  <div id="app">
    <h1>Hello, Vue.js!</h1>
  </div>
</template>

<script>
export default {
  data() {
    return {
      color: "red",
    };
  },
  beforeMount() {
    console.log("beforeMountフック: ", this.$el); // DOMのルート要素にアクセス可能
    console.log("beforeMountフックでrefs: ", this.$refs.title); // undefinedになる
  },
};
</script>
```
出力結果
```bash
beforeMountフック:  null
beforeMountフックでrefs:  undefined
```

## 検証結果と考察

beforeMountフックでは、this.$elでDOM要素にアクセスできるはずなのに、nullが返ってきてしまいました。
this.$refs.titleは想定通りundefindになる

## 考えられる原因
実行環境の問題
今回使用している環境は、ブラウザで簡易的にVueを動かしているだけのもの（CDNなど）。この環境ではbeforeMountの挙動が正しく動作しない可能性があると考えられる。

設定ミスやプロジェクト構成の問題
Vue.jsのバージョンやテンプレート構造に依存して、期待通りに動作しないことも考えられます。

## まとめ
今回の検証では、beforeMountフックの正しい挙動を確認できませんでしたが、以下のポイントがわかりました：

beforeMountフックは仮想DOMが実際のDOMにリンクされる直前に呼び出される
this.$refsは初期化される前に参照するとundefinedになる
正しい環境での検証をリベンジします！次回の記事で結果をお届けするので、ぜひお楽しみに。