OmniAICreator/Qiita-1.07M huggingface dataset:
【Minecraft】マルチプレイでプロモーションビデオを制作する

# はじめに
小学生の頃Minecraftに出会った私は、高校時代に映像制作を学び、大学時代にはそれらを掛け合わせた、Minecraftのマルチプレイでプロモーションビデオを制作するに至った。本記事は、Minecraft初心者歴10年と齧った程度の映像制作スキルを持つ筆者が、所属するMinecraftサークルにおいて様々な人の協力を得ながら制作したサークルのプロモーションビデオの、制作過程とそこから得た気づきを記すものである。

# Minecraftとの出会いと映像作品への憧れ
筆者がMinecraftに出会ったのは今から12年程前の事である。小学生だった筆者がニコニコ動画でMAD動画見る中で偶然Minecraft実況プレイ動画を発見し、そこから派生してMinecraftストーリーリンク、所謂茶番系動画にのめり込む様になった。
その頃視聴した映像作品への憧れから、自身もMinecraftを使って動画を作ってみようとしたが、当時の自分のセンスと理解力の無さに絶望して早々に挫折していた記憶が残っている。それ以来、筆者がMinecraftをプレイする頻度も低くなっていた。

# 高校時代の修行と大学時代の実践へ
高校生になった筆者は、映像制作を行う部活動に所属し、顧問の指導の下で撮影と編集の知識、スキルを学んだ。特に学びがあったのは、高校紹介映像の制作だった。当時の顧問による、「毎年作られる同じような映像を改めよう」、「大学のプロモーションビデオを参考にしてみよう」という提案から、筆者と同期の2人が中心となって制作を行った。筆者の制作スタイルはこの時に形作られたと思われる。
大学入学後、ゲームサークルに入会し、そこではMinecraftも扱っていたのでより広いコミュニティでマルチプレイをする様になった。当時は運営に積極的に関与するつもりは無かったのだが、いろいろあって途中からコミュニティの運営と広報を引き受けることになった。その過程で、プロモーションビデオを制作する機会があったのである。

# プロモーションビデオの企画と映像の構成
まず、企画段階で、目的やメッセージを決め、それを基にどの様な映像にするかを考える。その際に、使用する音楽も決めて、その音楽に合わせたシーン構成を練っていく。本記事の基になった映像では、サークルの活動を伝えるという目的で、マルチプレイワールド内の建築物や過去のイベントの様子を紹介した。音楽に合わせたシーン構成にするのは、その方が気持ち良いからという理由である。ただし、そのせいでシーンの一つ一つに割り当てられる時間が少なく、後述の撮影と編集の過程で苦労する事になった。

# 使用する音楽の再現
企画段階で使用する音楽を決定し、その音楽をMinecraft内の音符ブロックを用いて再現する。音楽をMinecraft内で再現する事で、映像内のMinecraftの要素を増やす事が出来るだけでなく、演奏扱いになる為、JASRACと許諾契約を締結しているYouTubeにおける投稿がしやすくなる。尚、筆者には音楽系のスキルが無かったので、サークル内の他のメンバーに依頼した。

# マルチプレイでの動画撮影
事前に決めた構成に基づいて、Minecraftのマルチプレイ画面を撮影する。筆者がカメラ役となり、他のプレイヤーが動いたり、建築したりする様子を、定点、あるいは移動しながら撮影を行った。Minecraft内での撮影の為、プレイヤーの操作ミスで撮り直しになる事もあれば、予想していなかった挙動やメンバーの思い付きからその場での内容の改善がされる事もあった。
また、一つ一つのシーンの割り当て時間が1～2秒程度しかない為、プレイヤーが上手く操作出来たとしても、割り当てに収まらず撮り直しになる事もあった。短い時間で全てのプレイヤーが操作をしなければならない為、撮影の難易度は更に高まる事になった。
Minecraftプレイヤーなら分かるかもしれないが、あるプレイヤーがエリトラで飛行しつつ、別のプレイヤーはエンダーパールを使って瞬間移動する。その他にも複数のプレイヤーがわちゃわちゃと何かしら動作していて、更にカメラ役の筆者も動いている。その様子を約4秒の中に収めるシーンがあった。そこで、少しでも撮影の難易度を低くする為に、筆者の画面を他のメンバーにも共有する事で、他のメンバーが操作をしやすくなるようにした。

# 編集
撮影した映像を、構成を基にカットし、シーンを繋げる。筆者の編集技術は高くないので、ここでの作業は単純である。それ故に、撮影段階において編集で使える映像を作る事の重要性が高い。また、この過程で他のメンバーに依頼していた音楽と映像を合わせる。

# おわりに
高校時代に現実での映像制作を行った筆者が、Minecraftでのプロモーションビデオの制作を通じて気づいた事は、現実でもMinecraft内でも、やる事はある程度共通しているという事である。特に撮影においては、カメラ役も、そこに映るキャラクターも操作するのは人間で、ミスも人の手によって生じる。一方で、Minecraft内だからこそ、様々な位置や角度から撮影が出来たし、撮り直しもやりやすかったと思う。今後は、Minecraftだからこそ出来る方法を模索したり、ワンカットやより長尺の映像にも挑戦したりしてみたい。
進捗報告 (2024-12-03 00:33:30)

# 進捗報告 (2023年12月2日)

## 概要
現在の進捗状況について、音声入力を活用したメモの記録と、自動投稿アプリの開発が進んでいる。

## 音声メモ自動投稿アプリの開発
- **使用技術**: OpenAI API, Google Apps Script
- **機能**: 音声で進捗を記録し、それを自動的に投稿するアプリを開発。
- **動作確認**: アプリはうまく動作しており、音声メモを取ることができている。

## 音声入力の効用
- 音声でのメモ取りは、言語化の練習や振り返りに非常に有効。
- 学んだことをその日のうちに脳に定着させる手段として、今後も継続していく予定。

## Twitter自動投稿MODの進捗
- **プラットフォーム**: AWS
- **進捗**: 自動投稿機能の作成が成功し、動作確認も完了。
- **定期実行スクリプト**: 問題なく動作している。

## 今後の予定
- 引き続き音声入力での進捗記録を行い、自動投稿アプリの改善を図る。
GROUP BYとCASEの使い分け

書籍の中でCASE文のメリットを書いている部分があり、GROUP BYのメリットも気になったため調べてみました。

元のテーブル
| pref_name | sex | population |
|-----------|-----|------------|
| 北海道      | 1   | 2000       |
| 北海道      | 2   | 2200       |
| 北海道      | 1   | 3000       |
| 北海道      | 2   | 3000       |
| 青森県      | 1   | 1500       |
| 青森県      | 2   | 1600       |
| 青森県      | 1   | 1500       |
| 青森県      | 2   | 1500       |
| 東京        | 1   | 4000       |
| 東京        | 2   | 4500       |
| 東京        | 1   | 4000       |
| 東京        | 2   | 4000       |

# CASE 文を使ったSQL
書籍に書かれていたSQL文は下記でした。
```sql
SELECT 
    pref_name,
    -- 男性の人口
    SUM(CASE WHEN sex = '1' THEN population ELSE 0 END) AS cnt_m,
    -- 女性の人口
    SUM(CASE WHEN sex = '2' THEN population ELSE 0 END) AS cnt_f
FROM PopTbl2
GROUP BY pref_name;
```

出力例
| pref_name | cnt_m | cnt_f |
|-----------|-------|-------|
| 北海道      | 5000  | 5200  |
| 青森県      | 3000  | 3100  |
| 東京        | 8000  | 8500  |

解説:
この形式では、各都道府県の男性人口と女性人口がそれぞれのカラムに出力されます。
データがクロス表形式（横方向に集約）となるため、1行で都道府県ごとの人口分布が確認でき、可読性が高いです。
集計条件を柔軟に指定できるのが CASE 文の強みです（例: 特定の年齢層を条件に加えるなど）。

# CASE 文を使わず、GROUP BY だけを使用したSQL
先ほどのSQLをGROUP BYを使って書き換えてみます。
```sql
SELECT 
    pref_name,
    sex,
    SUM(population) AS cnt
FROM PopTbl2
GROUP BY pref_name, sex;
```
出力例
| pref_name | sex | cnt   |
|-----------|-----|-------|
| 北海道      | 1   | 5000  |
| 北海道      | 2   | 5200  |
| 青森県      | 1   | 3000  |
| 青森県      | 2   | 3100  |
| 東京        | 1   | 8000  |
| 東京        | 2   | 8500  |

解説:
この形式では、都道府県ごとに性別でレコードが分かれる（縦方向に集約）ため、データが冗長になります。
男性人口と女性人口をそれぞれ確認したい場合は、フィルタリングや加工が別途必要です。

# 両者の違いと用途
| 比較点       | `CASE` を使う場合                         | `GROUP BY` だけの場合                  |
|--------------|------------------------------------------|---------------------------------------|
| **出力形式**  | 横方向（クロス表形式）                   | 縦方向（性別ごとに分かれる）            |
| **可読性**    | 一目で男性と女性の人口が分かる            | 性別ごとに確認する必要がある             |
| **柔軟性**    | 条件をカラムごとにカスタマイズ可能         | シンプルな集計には適している             |
| **用途**      | ダッシュボードやレポートで使いやすい      | 明細レベルでのデータ分析に向いている     |
AWS Certified AI Practitioner (AIF-C01) 勉強アウトプット①　～AL/ML用語編～

# 概要
インフラ屋さんがAI Practitionerを勉強してみたアウトプット

# わからなかったワード　-AI/ML用語-
- 学習率
    - １回の学習でどのくらいパラメータを修正するのかの値。大きいと最適解にならず、低いと学習が遅くなる。
- エポック数
    - モデルが訓練データの学習を繰り返す回数
- サポートベクターマシン
    - 学習アルゴリズム。分類問題で使う。境界線を設けて分類する。
- 埋込(エンベディング)
    - 単語やカテゴリを数値ベクトルにする手法。これにおりモデルが理解できる形式になる。
- 過学習
    - モデルが訓練データに適合しすぎて、訓練データ以外に対して不安定な予測をする現象。
    - 類義：オーバーフィット、バリアンス
    - 対義：未学習、アンダーフィット、バイアス
- セマンティックセグメンテーション
    - 画像のピクセル単位に対して意味のあるラベルをつけること
    - 類義：インスタンスセグメンテーション
        - 同じ画像の中でインスタンスをわけて複数の対象にラベルをつけること
- DeepLab V3
    - セマンティックセグメンテーションを行うモデル。畳み込みニューラルネットワークを使う。
- パラメータ数
    - モデルが学習する重みやバイアスの数のこと。多いと過学習のリスクがある。
- 重み
    - 入力データの重要度を示す値。
- ROC曲線下面積（AUC）
    - 分類モデルの性能を評価する指標。１が良い。
- MXNet
    - 深層学習のOSSフレームワーク。Apacheシリーズ。
- BERT
    - 自然言語処理のモデル。文脈を前後方向から理解する。
- BERTScore
    - BERTを用いて評価してモデルの品質を評価する指標。
- ハイパープレーン（境界線）
    - 分類問題で異なる分類を分けるための境界線
- XGBoost
    - 回帰や分類問題で使うアルゴリズム。複数の決定木を使う。学習する事に予測が修正
- コンテキスト
    - 情報の背景のこと。自然言語処理では重要であり、判断材料に前後の文脈を考慮する。
- 平均二乗誤差（MSE）
    - モデル精度を評価する値。予測値、実値の差を二乗して平均した値。
- 主成分分析（PCA）
    - 少ない次元に圧縮して重要な情報を抽出する手法。

- 潜在的ディリクレ配分法
    - 文書中のトピックを見つけ出すための確率的モデル
- 因数分解機
    - 機械学習における行列因数分解技術を指し、特に推薦システムで利用されるモデル？
- 決定係数 R²
    - 回帰においてモデルの適合度を評価する指標の一つ。
    - 総平方和に対する誤差平方和の割合を使って計算され、値が1に近いほど良い
- 適合率
    - 分類モデルが「陽性と予測したデータの中で実際に陽性であった割合」を示す指標
    - 「偽陽性」を最小化したい場合に重要
- ROUGE
　　- 生成AIにおけるテキスト生成モデルの評価指標
　　- 生成されたテキストと参照テキストとの類似度を計測
- Shapley 値
    - 各特徴量の貢献度を公平に評価するための指標
    - 特徴量の順番をランダムに変えて予測への影響を平均化することでどれだけ貢献しているかを計算
- 平均絶対パーセント誤差(MAPE)
    - 回帰分析や予測モデルの評価に広く使用される指標
    - 予測値と実際の値の誤差をパーセントで表示し、その平均を求める。小さいほどいい。
- コンテキストウィンドウ
    - 自然言語処理（NLP）や時系列データの分析などで広く使用される概念
    - データや単語の周囲にある情報（バックグラウンド）を考慮するための範囲を定義
- プロンプトテンプレート
    - 成AIモデルに適切な入力を提供するための「ひな型」
    - 生成するコンテンツの形式や内容を効率的に管理し、安定した結果を得ることが目的
Google検索からAI概要を常に取り除く方法（Vivaldiブラウザ限定）

# ほしい情報はそれじゃない！

この記事を読んでいる方はこう思う方が多いかもしれません。

**Google検索のAI結果イラネ**

生成AIの力は確かに画期的です。自分もエンジニアとしてお世話になることも多くあります。

一方でその結果はまだまだ信用に値するかというと怪しいところがあります。

一例ですが、[こんな結果](https://x.com/kino31100991/status/1860882810023903321)を言われるのはネタとしてならまだしも、必要なときに本当の情報が得られないのは困ります。

生成AIの結果を検証するために調べるようでは本末転倒ですよね？しかも画面の結構な範囲を占領するので煩わしいことこの上ない。

ということで、検索結果の更に上位に出てくるAIの回答を消す方法について。

# 共通の方法

検索時に`＜検索ワード -ai＞`を付けるだけ。

使わない人はあまり使わないであろう、検索除外を意味する`-`オプションがここで役に立つ。

## Before

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181488/49ed0c44-722b-c134-0585-da87fba7e372.png)

## After

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181488/035cf8fe-fcbd-4b52-8f47-b596a025f031.png)

# Vivaldiを利用して検索結果から常に除外する

個人的におすすめしている高機能ブラウザ[Vivaldi](https://vivaldi.com/ja/download/)ですが、これをカスタマイズすることでGoogle検索からAIの回答を常に除外することができます。

しかも方法は簡単！

`設定`⇒`検索`⇒`検索エンジン`⇒`Google`のURLを以下のように設定するだけ。

`https://www.google.com/search?q=-ai+%s`

上記URLの意味は簡単。検索文字列のクエリの戦闘に`-ai`を付けているだけ。

結果は以下のように表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181488/83221097-c5c3-021e-f673-e65e04f8d5ec.png)

# サマリ

一人のエンジニアとしてこういうことしないといけないのは心苦しいところではありますが、精度が保証できない以上、この方法をとるのはやむを得ないところ。

今回は検索結果からAIを除外する方法でしたが、検索機能やVivaldiブラウザの使い方を工夫すればより快適なネットライフが送られる、というお話でした。
【iOS/バグ解決】Plug-in ended with uncaught signal: 5

# 事象

以下のようなビルドエラーが発生

```
Plug-in ended with uncaught signal: 5
```

# 解決方法

以下のコマンドを実行後、Xcodeを再起動。

```terminal
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
```

# 参考

https://forums.developer.apple.com/forums/thread/740567
[Unity] Unity 6でUnityちゃんを動かす (ピンク問題対処法)

## 概要
Unity 6でUnity asset storeからインポートしたUnityちゃんを動かす際に正しく表示できず。公式サイトのデータ(1.4.0)を使用することで解決。

## 環境
- Unity 6 (6000.0.29f1)
- Universal 3D テンプレート


## 問題

### 導入直後
Unity 6 で、Unity asset store の[Unity-Chan! Model](https://assetstore.unity.com/packages/3d/characters/unity-chan-model-18705)(1.2.2)をそのまま導入した状態だとピンク色になる。 (使用モデル: unitychan_dynamic)

![スクリーンショット 2024-12-02 233041.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335144/b17ae204-4c4b-d935-0ee6-1aa8c96917e9.png)


### Shader変更
次に、様々なサイトで書かれているように、Unity-toon shaderを導入してみた。

https://docs.unity3d.com/ja/Packages/com.unity.toonshader@0.9/manual/installation.html

AssetsのArt/Materialsのファイルについて、InspectorのShaderからToonを選択し変更を行う。

しかし、↓のように正しく表示されない。

![スクリーンショット 2024-12-02 233347.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335144/9267e807-81f2-b8f3-9b5a-ccade5568e5e.png)


## 対処法

Unity asset store ではなく、[ユニティちゃん公式サイト](https://unity-chan.com/)から、ユニティちゃん 3Dモデルデータ(1.4.0)をダウンロードして導入する。

### 手順

- 未導入の場合はUnity-toon shaderを導入(上述)
- UnityChan_v1.4.0.unitypackageをダウンロード
- 画面下の「Assets」欄で右クリックし、「Import Package」→「Custom Package」から、ダウンロードしたunitypackageをインポートする (画像)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335144/9c67137c-a079-7cd4-3082-cd780c010f4c.png)

### 対処後
正しく表示された。

![スクリーンショット 2024-12-02 235930.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335144/d7179a43-d3d8-7fd0-2e9c-2185724fabe9.png)

##  投稿経緯
過去のUnity×PLATEAUのTutorialを見ながら遊んでいたら、環境を合わせなかったせいもあり、正常に表示できず困っていた。Unity超初心者だったので悪戦苦闘しながらも一応解決。同じハマり方する人もいるかもしれないので念のため備忘録 (Qiita初投稿)。
Google Geminiにさまざまなファイルをお渡しする方法

# Google Gemini
言わずと知れた、Googleによる生成AIになります。

Googleアカウントがあれば、だれでも無料でも使えますが、
Google WorkSpaceを利用していると、エンタープライズ版(Advanced)が利用できます。

下の画像のように、
画面下のプロンプト入力欄の左側に、盾のようなアイコンの表示があれば、
入力した内容は学習に利用されないので、業務情報など投入しても大丈夫(なはず)です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/5ae16310-c60c-8eb1-2267-948e5b188a8d.png)

# 使い方
基本的にはプロンプト入力による対話形式で回答を求めていきますが、
マイクアイコンがあるとおり、音声入力も可能です。
(ただし、リアルタイム会話はまだ未対応)

また、プラスアイコンをクリックで、
ファイルをアップロードして渡すことができます。

ただし、拡張子の指定があるので、
どのようなファイルでも渡せるわけではありません。

今回、ExcelのVBAを解析したかったので、アップロードしようとしましたが、
対応している拡張子ではないのでNGでした。

どうにか渡す方法はないかなーと、そのままGeminiさんにお尋ねすると、
「ドライブに上げて、リンクを教えろ」とのことでしたので、
言われるがままに、Googleドライブに上げて、共有リンクをGeminiさんに入力すると、
光の速さで該当ファイルを解析してくれました。

小ネタですが、単純に感動したので、記事にしました。
すげえぇな、Gemini。
UE5　ローカリゼーションダッシュボード　メモ

# 翻訳する

## テキストを集める　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/f5eaaac3-4e62-488b-9b84-6067fd227b73.png)


## 英語のpoファイルを出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/dc2d3def-4ae8-4516-af08-f5639a3d5f4e.png)

## Poedit
でpoファイルを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/c45eec31-a73a-4aeb-bb6e-8c50303feb08.png)

## 翻訳
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/33b60164-817a-49c7-b04a-c6e77463f02d.png)
翻訳完了したら、保存してUE側でImportを行う

## コンパイル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/3e6ce899-9031-402d-8110-0c6a32ae2607.png)

## ゲームでの切り替え
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/c7107829-b777-4ef6-a762-1f55d7d24920.png)


# FTextのデータの設定を確認
個別での設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249684/35b1c74a-dfa8-24e9-8b20-b43120b4bb9c.png)


FTextのデータを入力する際にチェックを選択する箇所がある

# FTextなのにテキストが収集されない
下部のPackage、keyが入っていないのが原因
FNameやFString→FTextに変更したテキストがこうなっているっぽい

一度Localizeのチェックを外して再度チェックを入れるとPakage、keyが設定される


# 翻訳したテキストが切り替わらない

コンパイルをしてProjectに反映する必要がある
VMWare Workstation Pro を久しぶりに触る③

## 前回のおさらい
5年ぶりぐらいに触る人間が、何分で構築できるのか、
というテーマで環境構築を進めてまいります。
前回はすんなりインストールに成功したところまで。

### 3.ゲストOSのインストール
VM上で動かすOSをインストールしていきます。

今回チャレンジするのは、「Alma Linux」になります。
業務では今までCentOSばかり使ってきましたので、慣れの都合上
RedHat系ディストリビューションになってしまいます。

公式サイト経由で、ミラーリングサイトに飛び、ISOイメージ(boot版)をダウンロード。
https://ftp.riken.jp/Linux/almalinux/9.5/isos/x86_64/
AlmaLinux-9.5-x86_64-boot.iso

サイズが小さいので、すぐにダウンロード完了します。
さっそく、VMWare上で動かしたいと思います。


ホームタブで、「新規仮想マシンの作成」を押下。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/6432b53d-5437-c36c-e7f8-a19b92a0bc50.png)


新しい仮想マシンのウィザードで、「標準」を選択、「次へ」。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/de64c64b-c0a8-202b-8167-f88c494e2a7a.png)


デフォルトの「後でOSをインストール」のまま、「次へ」。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/380fdefa-81ae-42af-45ef-baa5ac728ca2.png)


ゲストOSの選択では、「Linux」、バージョンは「AlmaLinux」を選択し、「次へ」。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/399d38f9-7a20-fddb-00e7-ad3c5f89f848.png)


任意の名前、ディレクトリを指定し、「次へ」。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/9d7b067b-67d2-e6f7-3abd-3956882e2423.png)


ディスク容量の設定もデフォルトのまま、「次へ」。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/34498a8c-a639-8509-5789-8c6352607f3e.png)


確認画面で「完了」を押下。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/e72a2428-85aa-10eb-0222-ed0d6d3b7435.png)


すると、ホームタブに作成した仮想マシンが表示されるので、
「仮想マシンの設定を編集する」を押下。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/929c8a88-52ae-b5cd-31b6-a75b5ed8bf44.png)


変更する設定は、
- メモリ(2GB→4GB)
- CD/DVD(最初にダウンロードしたISOを設定)
- ネットワーク(NAT→ブリッジ)
の3点。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/0b3a6ad9-9740-d9cc-d12f-610b096f6a70.png)


設定も終わったので、いよいよ起動したいと思います。
「このマシンをパワーオンする」を押下。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/54579cc8-323d-011b-3a81-5da43e364b0b.png)


メニューが立ち上がるので、「Install AlmaLinux 9.5」を選び、Enter
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/ccf2c5eb-7540-5861-6bfe-92b10bd3299c.png)


言語設定を「日本語」にし、管理ユーザを作成。
インストール先を仮想マシンのドライブにして「インストールの開始」を押下(必要項目以外はデフォルト)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/7b4d1727-729f-ecc7-7940-4b2be0767e0d.png)


インストール後に再起動を求められるので、そのまま再起動。
再起動後にログイン画面が表示されたら、これでインストール完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/3793ba59-0c66-1a1b-eeca-0d012dd0e3b9.png)



記事を書きながら、ということもありますが、ここまでで1時間弱。
ハマりポイントはないものの、結構時間がかかりました。

次回は、ゲストOSへホストOSから接続してみたいと思います。
技術書におけるキャプチャの貼り方

## はじめに
こちらは、技術同人誌/技術を取り巻く様々な執筆 Advent Calendar 2024 12/3分の記事になります。

こんばんは、かーでぃです。
Qiita記事、2つ目👏

本記事は、下記のnote記事の簡易版になります。

https://note.com/kerdy/n/nb29c521d0cd4

## キャプチャ問題

ブログ等では特に気にならないのですが、こと技術書に関しては改ページ処理が走ることから、どうしても縦長の画像の扱いが難しくなってしまいます。
特に、私が主戦場としているノーコード/ローコード界隈は、コード（フローとかシナリオなど）の全体をキャプチャしようとすると、どうしても縦長になってしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952925/547863ca-4f8b-479c-ad37-6f267db36e8c.png)

上の画像をそのまま技術書に貼り付けると、1ページまるまる画像だけになるばかりか、画像が小さくなり、文字が読めなくなりそうです。さらに、左右には無駄な余白が広がってしまいます…。

また、ページ数が増えれば、その分印刷代も高くなります。自費出版ということを考えれば、印刷代もできるだけ抑えたいところです。

## 解決策

自分は縦長になってしまう画像は、切り貼りして横長にしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952925/dbe986cc-3a57-d0ba-1bb1-6451ef58c22b.png)

こうするだけで、縦長の画像を横長にすることができました。横長になった分、余白を抑えることもできれば、その分ページ数の節約にもなりました。

ちょっとした手間を加えるだけで、本としての質も上がります。本の質が上がれば、読者もファンになってくれるかもしれません。

手間を惜しまず、質を上げていきたいですね。
バッテリー残量みえるくん


本記事は[クラスター Advent Calendar 2024](https://qiita.com/advent-calendar/2024/cluster) 3日目の記事です。
前日は @uzzu さんの[「消費可能な値」を導入した](https://uzzu.co/post/introduce-consumable.html) でした！


## 今日はスタジオチームが何か組んだお話
こんにちは、スタジオチームのn_mattun（まっつん）です。

普段の仕事は、スタジオ内外問わずでイベントで体験者がVR機材等を着けた際に、人間側とcluster側の両面が本来のパフォーマンスを充分発揮できるように様々な環境準備やケアをする仕事※を中心に、ハード、ソフト両面でスタジオ起点でお助けになれるようなことは技術領域を問わず色々何でもやってるマンです。

※外のイベントでは東京ゲームショウの体験ブース周辺の現場統括もやったりしました
　https://x.com/n_mattun/status/1705220851447251180

今回はそんな仕事の中で作った「バッテリー残量みえるくん」について紹介します！


## 背景

社内スタジオ稼働のイベントで使われるバッテリー式のVRデバイスのバッテリー管理について、基本的には満充電状態から初めて、そこからイベント進行の合間に充電をしているのですが、朝に集合して丁寧にリハーサルを行って諸々あって夜遅くに終わる・・というような丸一日稼働が想定されるイベントでは「バッテリーの持ちは大丈夫かな？」と心配になるケースがあるわけです。少し以前の、トラッカーが3.0ではなく2.0が主戦力だった頃などはかなり不安なポイントでしたね。


## 課題

で、その残容量の確認方法なんですが、特に対策を打たない限りは出演者が操作しているPC内のSteamVRのパネル上から確認することになるわけなのですが、

- マウスオーバーしないと目盛りが出てこない
- しかもざっくりとした残容量しか出てない
- なので「あとどれくらい持つのか？」という具体的な残り時間がわからない
- 本番進行中にPCを触ってカジュアルに確認をするワケにもいかない

という、イベント進行中には相当使いづらいものでした。

![image (73).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58402/7744f1ea-770f-b3ab-562f-0cf2ba089b36.png)
SteamVR上の表示はこんな感じ、
デバイスのアイコンにマウスをもってかないと残容量は見れない


そんな中、別口で [VIVEBatteryInfo](https://booth.pm/ja/items/969809) のような残容量を見れるアプリが存在していたことは知ってはいたので、残容量の表示をスタジオ特化でいい感じに確認できる状態さえあればいいだろうということで作りました。


## バッテリー残量みえるくん

実際に動いてるアプリの画面はこんな感じです。

![image (74).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58402/8c45eeea-899e-78d0-4fc3-399950a85211.png)
▼ラベルの文字列は[スタジオ内の部屋の呼称](https://note.com/cluster_official/n/n8f784db15377)を出すようにしてます


### 具体的にわかる

SteamVRから残容量値をもらってくると0～100%の値が返ってくるのですが、**イベントスタッフが脳直で欲しい情報はバッテリー割合ではなく「リハや本番中もバッテリーが持つかどうか？」** なので、アプリ側で時間経過による%の減り具合を計算し、それを元に「あとx分」という具体的な残容量時間を表示しています。また、イベント進行の隙間にちゃんと充電がされているかの確認もしたいので、充電中の場合はステータスも「充電中」と表示されているようになっています。


### 手軽に一覧で見れる

この残容量を一番知りたいのは出演者PCが置いてある部屋の中の人たちではなく、イベントの進行を監理、監視している技術やディレクター勢なので、その人たちに対して**稼働中の端末の状態がぜんぶ見れる**ようにしないといけません。

そこで残量表示機能に加えて、設定ファイル監視対象のPC情報を入力すると、指定したPC内で稼働している同アプリの残量を取得表示する機能も追加しました。

実運用上では、稼働している出演者の各PCでアプリを動かしておきつつ、それとは別にイベント進行管理を担う技術やディレクターが居る場所付近にあるPC内でもアプリを動かしておき、そちらでは一覧確認ができる状態を作っています。

これだけの台数のVRデバイスのバッテリーの残容量を、各部屋を巡って手作業で確認することと比較して考えると、地味だけどかなり嬉しいことが伝わると思います。


## おわりに

現実でもメタバースでも、こと「イベント」と呼称される催し物は当日進行の１分１秒がとても大事です。このように当日進行の確認の手数を減らすことにより、その瞬間に必要な他タスクの処理ができたり、進行上の少し先にある別タスクの下準備ができたりと、イベントの品質向上にも寄与できるわけですね。

引き続き、メタバースイベントの盛り上がりのために、現実側とメタバース側の両面を見つつ的確なサポートをしていきたいですね！

明日は引き続き @n_mattun から「ClusterScript覚えるなら今がちょうどいい的な話（仮題）」をします！まだ仮原稿でしかも進捗6割くらいです！やばい！！
3日目: UnionFindを実装する

[競プロ用ライブラリを作る Advent Calendar 2024](https://qiita.com/advent-calendar/2024/yukkku-ribitol)の3日目です.

https://qiita.com/advent-calendar/2024/yukkku-ribitol

# UnionFind って?
要素をグループ分けするのに便利なデータ構造です. グラフの連結成分の管理とかに使えます.

- 2つのグループを指定して, そのグループをまとめて1つの大きなグループにする (`union`)
- 2つの要素を指定して, その2つの要素が同じグループに属しているか判定する (`find`)

という操作が$O(\alpha(N))$みたいな計算量でできます. ($\alpha$はアッカーマン関数の逆関数で, 実用上は定数です)
注意点として, 2つのグループを1つにまとめることはできても, 1つのグループを2つに分けたりはできません.

# 仕組み

各グループを根付き木で表現して, 根の要素を見てグループを判別する, という方針です.

以下, ある要素$x$について, その親を$P(x)$と書くことにします. $x$が根のときは$P(x)$は未定義です.

## `find`

ある要素が属しているグループがどれか, というのを考える時は $x, P(x), P(P(x)), ...$ と根にたどり着くまで探していけばいいです.

## `union`

2つの要素$a$, $b$が属するグループを1つの大きなグループにまとめます. それぞれの根を探して片方の根をもう片方の根の親にしてしまえばいいです.

例えば
```mermaid
flowchart BT
  1((1))
  2((2)) --> 1
  3((3)) --> 1
  4((4)) --> 2
  5((5))
  6((6)) --> 5
  7((7)) --> 5
```
こういう木で表現された2つのグループをマージするときは
```mermaid
flowchart BT
  subgraph " "
    1((1))
    2((2)) --> 1
    3((3)) --> 1
    4((4)) --> 2
  end
  subgraph " "
    5((5))
    6((6)) --> 5
    7((7)) --> 5
  end
  5 --> 1
```
こういうふうにします. 根の情報しか書き換えなくて良いので愚直な2次元配列での管理にくらべて高速です.

## 工夫

これだけだと遅い(親まで辿るのに最悪で全部の要素を見る必要がある)ですが, 工夫をすると速くなります.

### マージテク

グループをマージするとき, 要素数が大きいほうの根を新しいグループの根にするようにします.

```mermaid
flowchart BT
  subgraph " "
    1((1))
    2((2)) --> 1
    3((3)) --> 1
    4((4)) --> 1
    5((5)) --> 2
  end
  subgraph " "
    6((6))
    7((7)) --> 6
  end
  1 --> 6
```
こうじゃなくて
```mermaid
flowchart BT
  subgraph " "
    1((1))
    2((2)) --> 1
    3((3)) --> 1
    4((4)) --> 1
    5((5)) --> 2
  end
  subgraph " "
    6((6))
    7((7)) --> 6
  end
  6 --> 1
```
こうするということです
小さい方のグループの要素は全部根から1の距離が1つずつ大きくなります. これは`find`にかかるコストが増える, ということで, `find`のコストが増える要素をできるだけ少なくしたいからどちらのグループが大きいかを考えたわけです.

ただの定数倍高速化と思いきやこれだけで最悪計算量が$O(N)$から$O(\log N)$になります.

### 経路圧縮

```mermaid
flowchart RL
  1((1))
  2((2)) --> 1
  3((3)) --> 2
  4((4)) --> 3
```
こういう状態があって, $4$の根を探すと, $1$を見つけます.
このとき, 途中に通った$2$, $3$と$4$の根は$1$だと分かったのだから, 直接$1$に繋ぎ直してやると良いです.
```mermaid
flowchart RL
  1((1))
  2((2)) --> 1
  3((3)) --> 1
  4((4)) --> 1
```
こういう風な工夫をすると同じ探索を2回以上しなくなるので, わかりやすく高速化に繋がります.

# 実装

- [`unionfind.rs`](https://github.com/Yukkku/ribitol/blob/main/src/unionfind.rs)

実装するときは要素ごとに符号付き整数型で持って管理すると良いです.

- 根なら, グループの要素数 × (-1)
- 根じゃないなら, 親の番号

として管理すると別々に値を持つ必要がなくなるので, メモリ量の削減になります. ([ac-libraryの実装](https://github.com/atcoder/ac-library/blob/master/atcoder/dsu.hpp)が参考になります)

それと, 連結成分の数を数えたくなる場面は割と多いのでこの値も管理しておきましょう.

Rustでは値がデフォルトで不変なので, 経路圧縮をしたくてもできないときがあります. 値が不変でもクエリを処理できるように, 経路圧縮しなくても$O(\log N)$でクエリを処理できるので, 妥協して経路圧縮を行わない版のメソッドも作りましょう.

# まとめ

いかがでしたか?
明日はこのUnionFindに付加情報を載せる話をやります.
クラウドセキュリティのヒヤリ体験：Streamlitアプリの公開ミス

## まえがき

クラウド環境では、便利さの裏に思わぬセキュリティリスクが潜んでいます。これは、私自身がN年前に体験した小さな「ヒヤリ・ハット」事例のお話です。この経験を通じて、予防策や対応策の重要性を改めて実感しました。

## 体験談：思わぬアクセスの波

私は以前、[Streamlit](https://streamlit.io/)を使って簡易的なアプリを作成しました。個人的な用途での利用を目的としたアプリであり、特に秘匿性が高い情報を扱うものではなかったため、「まあ、Publicで公開しても問題ないだろう」と軽く考えてしまったのです。

しかし、アプリを公開して数分後、Streamlitのアクセスログにアクセスが集まり始めているのを発見しました。私の想定を超える早さで、見知らぬ人々がアプリにアクセスしていたのです。

さらに後日、海外の方（ヘッドハンター的な方）から突然こんなメール（実際は英語）を受け取りました：

> "[アプリのGitHubレポジトリ名]が素晴らしいですね！"

一瞬公開しただけにもかかわらず、見知らぬ誰かが私のGitHubレポジトリを確認していたことが明らかになりました。この時点で、たとえ公開期間が短時間でも、世界中の誰かがアクセスする可能性があるという現実を思い知らされました。

## 背景：Streamlitの仕様と盲点

Streamlitは無料プランでは、1つのレポジトリしかPrivate設定にできないという制限があります。そのため、他のアプリを公開する際にはPublic設定を余儀なくされることがあります。この仕様に対して十分なリスク意識がなかった私は、結果的に意図しない形でアプリを公開してしまいました。


## 対策：ヒヤリ体験から学んだこと

この経験を踏まえて、以下の対策を取るようにしました：

1. **アプリの秘匿性を再評価する**
   - 公開前に、アプリが取り扱うデータや機能に秘匿性がないかを再確認。

2. **適切な公開範囲を設定する**
   - 秘匿性が少しでもある場合はPrivateレポジトリを選択。どうしてもPublicにせざるを得ない場合は、利用制限をかける仕組みを導入。

3. **アクセス状況を常に監視する**
   - Streamlitや他のツールが提供するアクセスログをこまめに確認し、異常なアクセスを早期に発見。

4. **不要な情報の公開を避ける**
   - レポジトリ名や説明文などにも、個人情報や特定される可能性のある情報を記載しない。


## 教訓：一瞬の公開でも甘く見ない

今回の体験で、クラウド環境におけるセキュリティの重要性を痛感しました。たとえ短時間の公開であっても、インターネット上では常に誰かに見られるリスクがあることを忘れてはなりません。

この教訓が、皆さんのクラウド環境でのセキュリティ対策に役立てば幸いです。そして、私のような小さなミスを防ぐための一助になればと願っています。
Advent of code 2015 Day 19 Part 2 を Livebook で楽しむ

## はじめに

Advent of code 2024 の準備として、過去回の Advent of code 2015 を Livebook で楽しみます

本記事では Day 19 の Part 2 を解きます

:::note info
Part 1 と Part 2 の解き方が全く違ったので分けています
:::

問題文はこちら

https://adventofcode.com/2015/day/19

実装したノートブックはこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/aoc/2015/2015_day19_part2.livemd

Part 1 はこちら

https://qiita.com/RyoWakabayashi/private/4b06d66480b336000dc4

## セットアップ

Kino AOC をインストールします

```elixir
Mix.install([
  {:kino_aoc, "~> 0.1"}
])
```

Kino AOC の使い方はこちらを参照

https://qiita.com/RyoWakabayashi/items/3d3abcf9134cee4dff05

## 入力の取得

"Advent of Code Helper" スマートセルを追加し、 Day 19 の入力を取得します

![スクリーンショット 2024-12-02 23.25.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/4539f101-de2b-ef2d-d1ba-df0ad20edac7.png)

## 私の答え

私の答えです。
折りたたんでおきます。
▶を押して開いてください。

<details><summary>回答</summary>

貪欲法などの探索を試してみましたがうまくいかず、 Reddit のスレッドを見てようやく解きました

https://www.reddit.com/r/adventofcode/comments/3xflz8/day_19_solutions/

置換のルールを見ると、実は規則的になっており、以下のように読み替えることができます

- Rn: `(`
- Ar: `)`
- Y: `,`

例えば `SiRnFYFAr` は `Si(F,F)` を表しています

また、元素記号のように、 `Si` などの大文字+小文字は一つの分子を表しています

`CRnFYFYFArCaF` が入力とすると、前出の置換ルールを適用すれば `C(F,F,F)CaF` となります

置換の数 = 全ての分子の数 - 1回の置換でついでに消すことができる分子の数なので、

全ての大文字の数 - `(` の数 - `)` の数 - `,` の数 * 2 - 1 が答えです

```elixir
molecules =
  puzzle_input
  |> String.split("\n")
  |> Enum.reverse()
  |> hd()
```

```elixir
count_str = fn molecules, str ->
  Regex.scan(~r/#{str}/, molecules)
  |> length()
end
```

```elixir
Regex.scan(~r/[A-Z]/, molecules)
|> length()
|> Kernel.-(count_str.(molecules, "Rn"))
|> Kernel.-(count_str.(molecules, "Ar"))
|> Kernel.-(2 * count_str.(molecules, "Y"))
|> Kernel.-(1)
```

</details>

## まとめ

Part 1 は単純でしたが、、、

Part 2 は入力を見て洞察しないと解けない問題でした
24/12/02 読書記録 ~ソフトウェアテストの教科書~

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

# 書籍を読む目的

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

## Chap07. 組合せテスト技法

### 学び 📝

#### 組合せテスト
複数の条件を組み合わせてソフトウェアの動作を確認するテスト

#### 2因子間網羅
- 因子：テスト対象の機能名や設定項目など
- 水準：因子が持つ選択肢や設定値など

2因子間網羅の組合せを全てテストするのは現実的でない。
効率的にテストする方法はないか？
→ 直交表、All-Pairs法

#### 品質への影響は？（2因子間網羅に絞ることでテストは少なくなるが）
「多くのバグは2因子間までで見つかる」説。

#### All-Pairs法とは？
2因子間網羅に特化する形で、因子水準表から組合せ表を作成する。
今はツールで容易に作成できるとのこと。


### Chap7 感想 :writing_hand_tone5:

今の現場で用いる組合せテスト技法は「All-Pairs法」だと思う。
スピード感が必要とされる環境だからだ。
直交表の用いた組合せテスト技法は、準備、習得まで時間がかかる印象。

全てのケースを網羅したい機会があれば、手間削減のために本章を思い出したい。
.gitの中身を見てみる2(git add)

Gitでバージョン管理されたプロジェクトを扱うと、必ず `.git` というディレクトリがあります。

このディレクトリを使ってGitがバージョン管理をしているらしい、ということはなんとなく知っています。でも、具体的になにが入っていて、どう管理されているんだろう？

このアドベントカレンダーは、そんな疑問からGitを深堀りしていきます。

# `.git` の中身を見てみる2(`git add`)

昨日は `git init` だけしたときの `.git` ディレクトリの中身を確認しました。

本日は、差分を作ってみます。

## ファイルを作るとどうなるか？

まず、作業前後でディレクトリの中身を比較したいので、作業前にディレクトリごとコピーを取ります。

```bash
$ cp -pr ../git-study ../git-study-before-create-file # 作業前ディレクトリをコピー(カレントディレクトリは `git-study` 直下)
$ ls -ld ../git-study* # コピー後確認
drwxr-xr-x 1 user group 18 12月  2 22:13 ../git-study
drwxr-xr-x 1 user group  8 12月  1 15:38 ../git-study-before-create-file
$ 
```

新規ファイルを作成します。

```bash
$ ls -l # ファイル作成前確認
合計 0
$ touch a.txt # ファイル作成
$ ls -l # ファイル作成後確認
合計 0
-rw-r--r-- 1 user group 0 12月  2 22:13 a.txt
$ git status # ステータスを確認する
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        a.txt

nothing added to commit but untracked files present (use "git add" to track)
$ 
```

`.git` ディレクトリ内を比較してみます。すると、差分はありませんでした。

```
$ diff .git ../git-study-before-create-file/.git
共通のサブディレクトリー: .git/branches と ../git-study-before-create-file/.git/branches
共通のサブディレクトリー: .git/gitweb と ../git-study-before-create-file/.git/gitweb
共通のサブディレクトリー: .git/hooks と ../git-study-before-create-file/.git/hooks
共通のサブディレクトリー: .git/info と ../git-study-before-create-file/.git/info
共通のサブディレクトリー: .git/objects と ../git-study-before-create-file/.git/objects
共通のサブディレクトリー: .git/refs と ../git-study-before-create-file/.git/refs
$ 
```

## `git add` するとどうなるか？

では、先ほどを同じように作業前にディレクトリごとコピーを取ります。

```bash
$ cp -pr ../git-study ../git-study-before-add # 作業前ディレクトリをコピー(カレントディレクトリは `git-study` 直下)
$ ls -ld ../git-study* # コピー後確認
drwxr-xr-x 1 user group 18 12月  2 22:13 ../git-study
drwxr-xr-x 1 user group 18 12月  2 22:13 ../git-study-before-add
drwxr-xr-x 1 user group  8 12月  1 15:38 ../git-study-before-create-file
$ 
```

差分になっていた `a.txt` をGitのインデックスに追加する。

```bash
$ git add a.txt # インデックスに差分を追加する
$ git status # ステータスを確認する
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   a.txt

$ 
```

比較すると差分が発生しました。

```bash
$ diff .git ../git-study-before-add/.git
共通のサブディレクトリー: .git/branches と ../git-study-before-add/.git/branches
共通のサブディレクトリー: .git/gitweb と ../git-study-before-add/.git/gitweb
共通のサブディレクトリー: .git/hooks と ../git-study-before-add/.git/hooks
.git のみに存在: index
共通のサブディレクトリー: .git/info と ../git-study-before-add/.git/info
共通のサブディレクトリー: .git/objects と ../git-study-before-add/.git/objects
共通のサブディレクトリー: .git/refs と ../git-study-before-add/.git/refs
$ cat .git/index
DIRCgMf
       `gMf
           `5%EI⛲CK)wZSa.txtsT}ss:YE$ 
```

ちょっと人がよめないタイプのログが出てきました。


今日はここまで。

# 参考書籍・参考資料

- エンジニアのためのGitの教科書［上級編］ Git内部の仕組みを理解する
    - https://amzn.asia/d/2PJeklb
- git 公式ドキュメント
    - https://git-scm.com/book/ja/v2
Proxmox VE Training Courses （Proxmox VE Advanced）を受講しました。


## TL;DR

- 今年こそ公式トレーニングを受講しました！
  - 本家ではなく、トレーニングパートナー主催のものを受講。
- トレーニングの概要
  - 本家記載の内容とちょっと違う。
- 感想
  - 英語苦手でも大丈夫。
  - 世界中のみんな考えること一緒。
  - 技術的なことを解説するための流れに感心。

## Proxmox VE Training Courses とは？

`Proxmox VE Training Courses `とは、`Proxmox Server Solutions GmbH (AT)`あるいは認定パートナーによるトレーニングです。
それについて記載したは去年のアドベントカレンダー以下の記事。

https://qiita.com/oishi-d/items/4180fcd08ab60c9cef82

この時は受講しようか検討して、その時は受講しませんでした。
ですが今年は受講したので、記事にします。
ちなみに受講した理由は金のアレの条件だからです。
※アレが何かは近いうちに言えるようになります。

## コース概要

### 実際に受講したコース
三種類あるうちの、`Proxmox VE Advanced`を受講しました。
はじめは本家のトレーニングを受講しようと思い連絡したのですが、9月時点で「年内はもう埋まってるから、トレーニングパートナー開催のものを受講してみてね」と回答あり。
それで案内されたのがこちら。

https://weehooey.com/products/course-101-proxmox-ve-advanced

Weehooey Inc. はカナダにある北米初のゴールドパートナー（リセラーパートナー兼トレーニングパートナー）とのこと。
こちらもだいぶ埋まっていて、9月に連絡した時点で10月分は埋まっていて、11月開催のものに申込できました。



### 手続き関連

本家と比べると申し込みはWebだけで完結するので簡単。値段もJPY表示。
※本家はPDFを作成してメール送付。

なのですが申込後、1週間前になるまで連絡特になし。
※不安になって2週間前ぐらいにメールするも返答なし。

1週間前にZoom URLが送付され、前日になってドキュメントやハンズオン環境情報がようやく送付されてくる。

正直、この期間が一番ドキドキしました。


### コースの内容
ざっくりと以下。
※実際の目次はもう少し細かいです。

- イントロ
- PVEクラスタ構築
- PBS構築
- Ceph構築
- マイグレーション
- VXLAN
- ZFS レプリケーション
- HA
- REST API
- Proxmox コミュニティに参加しよう！

この目次だけ見ると「この値段で3日使ってこれだけ？」と思うかもしれませんが、技術的な解説（Corosync・PBSのチャンク・Cephの仕組みetc）、QA（ベストプラクティス・構築中環境のお悩み相談・VMware製品との違いetc）、トラブルシュート（pmxcfsのDBを直接触るetc）など多く時間を割くので、時間的にもかなりギリギリいっぱいでした。
また、ハンズオン形式で、この辺りを自分で初めて構築・操作するような人もそこそこおり、そのトラブルシュートというか支援でも時間を取りました。


ちなみに本家の目次と比べると違うところがちょっとあります。
※PBSなど。
ちゃんと証明書は本家認定のものなので安心してください。

https://www.proxmox.com/en/services/training#detail-advanced-training



### 実施時間・時差

EST（米国東部標準時）で11:00～17:00、日本時間だと1:00～7:00。
1項目ごとに50分実施＋10分の休憩があり、お昼に45分休憩あり。そのため1日5項目ぐらい。
それを3日間。
※他のスケジュールを見ると、5日間で1日の時間が短い場合もありそう。

でも実際にはQAが盛り上がったり、ハンズオンがうまくいかなかったりで休憩は結構スキップされてました。

### 参加者・環境など。

Zoomでオンライン実施。
ハンズオン環境はLinux Mintを経由してアクセス。
※英字キーボードに気が付かず、ログインできずにちょっとパニックでした。
PonPだったが、かなりリッチな構成でハンズオンもサクサク動く。

参加者は15人＋トレーナー2人。
世界中のいろいろな地域から参加しているが、英語が怪しい人は自分だけでした。
トレーナーは本家フォーラムにもStaff扱い（Proxmoxロゴのアカウント）でいるようです。



## 感想
### 英語苦手でも大丈夫。

Zoomに参加してネイティブじゃない旨、トレーナーにチャットしたら、「Zoomの字幕機能をONにして！」「質問はチャットでOK！」となり、かなり楽ができました。
Zoom字幕の翻訳は初めて使ったのですが、精度が結構高いので安心でした。
一番初めに自己紹介があり、焦っていたのですが、そこも「チャットでOK！」と言われてほっとしました。

本家はBigBlueButtonなようで、こっちにどれだけ翻訳機能があるかわからないのですが、Zoomほどに精度が高いということもないと思うので、本家じゃなくてよかったかもしれません。



ただし、VXLANで他参加者のPVEクラスタをPeerとして設定して疎通を取るというのがあります。
そこでは他の人とペアになりIPなどの設定をやり取りするのですが、「貴方は日本人？私は米国の日本企業ではたらしているんだよ」と話しかけれ、なんと回答していいかとても悩みました…


### 世界中のみんな考えること一緒。

- 「V社がB社に買収されてこのトレーニングに参加しました」
- 「B社の製品と比較すると？」
- 「ベストプラクティスは？」
- 「3Tier構成は？」
- 「現行資産のクソデカストレージがあるんだけど…」
- 「2ノードや偶数クラスタは？」

等々、日本のみんなと同じこと考えていて安心しました。



### 技術的なことを解説するための流れに感心。

- 4ノードでPVEクラスタを構築
  - Corosyncについて解説（偶数だとスプリットブレインが云々）
- 偶数なのでPBSをQデバイスとして追加。
  - Qデバイス・PBSのNWについて解説（Qデバイスは別セグメントでOK・PBSはPVEと同じNWに置くべきではない云々）
- Cephのモニターを3ノードに作成
  - Cephについて解説（モニターは奇数・PVEクラスタとは別云々）
  

といった具合に、技術的な解説をするための流れになっており、とても関心しました。
自分がハンズオンを作った時には「3ノードでPVEクラスタ構築できました！完！」となり、技術的な解説は別途になってしまったので。



## まとめ

時間的にも費用的にもハードルは高いですが、満足度が高い内容でした。
特に、ドキュメントやフォーラム、実機の動作を見る限りそうだと思っているけども確証がなかった部分が、認定トレーナーによるお墨付きをもらえたのが大きいと思います。
これで自信をもって人に説明できるなーと思いました。
【Ruby】文字列を数値に変換する方法

文字列を数値に変換するには`.to_i`メソッドを使用します。

```ruby
value = "123"
integer_value = value.to_i
puts integer_value  
# 123
```

文字列が整数に変換可能な場合にはその整数値が返されます。
変換できない場合には、`0`が返されます。

```ruby
value = "abc"
integer_value = value.to_i
puts integer_value  
# 0
```
Cline（クライン）というAIエージェントを知っていますか？

# Clineとは

`Cline`（クライン）は、作成から修正、テスト、Git操作まで自律的に行うことができます。

AIの進化は早いもので、とうとう自律型のアプリ制作ツールが登場してきています。

ちょうど1年前、`Cursor`や`GitHub Copilot`の登場により、AIによるコード生成が実用的になったのですが、
結局のところ、それを使用する人間の力量（AIを使うスキル）を求められる部分が多くありました。

最近まで`Cline`（クライン）というツールを知らなかったのですが、AIに関するYouTube動画を見ていたらアプリが簡単につくれる、ということを知りました。

AIエージェント自体は2年前くらいから存在していました。
しかし、当時はそこまで賢くなく、ほとんど使い物になりませんでしたが、
ここ最近になって、一気に実用性が高まり、ちょっと面白いことになりそうな予感です。

ただ、正直なところ、自律的なバグ修正について、まだちょっと弱い面があって
修正とテストを無限に繰り返してしまうことがあり、まだ人間のフォローが必要とされる部分が残っている感じです。

# 今後の予定

`GitHub Copilot`や`Cline`を使って、簡単なツールやサンプルアプリなら、確かに自動で作成できます。
しかし、業務アプリの制作でどこまで通用するのか、またどのように使えば製品レベルの品質まで持っていけるのか検証していきます。

毎日更新できればよいのですが、無理そうなので、不定期にアップします。

今日のところは、所信表明まで。
イベントとイベントリスナー

## はじめに
ブラウザ上でクリックやキーの入力などの操作が行われたときに特定の動作をさせたいとき、イベントと呼ばれるものを介して動作を規定できます。

本記事ではこのイベントと動作を規定するイベントリスナーについてみていきます。
## イベントとは
イベントとは動作や出来事の通知のことです。

イベントには、クリックという動作を表す`click`イベントやページの読み込みが完了したことを表す`load`イベントなどがあります。
動作や出来事が起きたときにブラウザはこれらのイベントを生成します。
## イベントの伝播
ブラウザによって生成されたイベントは、イベントの発生要因となった要素（イベントトリガー）へとDOMツリーに沿って伝播していきます。

イベントの伝播には「キャプチャフェーズ」「ターゲットフェーズ」「バブリングフェーズ」があります。

「キャプチャフェーズ」はWindowオブジェクトからイベントターゲットまでの伝播が、
「ターゲットフェーズ」ではイベントターゲットでの処理が、
「バブリングフェーズ」ではイベントターゲットからWindowオブジェクトへの伝播が行われます。
（詳しくは別記事で取り扱いたいと思います）

イベントリスナーと呼ばれるイベントの監視機構を設定することで、特定のイベントが特定のイベントターゲットで発生したときに、設定しておいた動作を行わせることができます。
## イベントリスナー
`addEventListener`という関数でイベントリスナーを設定することができます。
第1引数にはイベントを表す文字列を、第2引数には設定したい動作を行う関数を渡します。
```js
const btn = document.getElementById("btn");
    btn.addEventListener("click", () => {
      console.log("clicked!");
    });
```
上の例では、ドキュメント内にある`btn`というidをもつ要素のオブジェクトを`getElementById`によって取得し、そのオブジェクトについている`addEventListener`を使用することでイベントの監視設定をしています。

イベントリスナーが設定されたあとでボタンがクリックされると、コンソール上に`clicked!`と表示されるようになります。

### イベントリスナーの重複登録
イベントリスナーは1つの要素に対して複数登録することも可能です。
```js
const btn = document.getElementById("btn");
    btn.addEventListener("click", () => {
      console.log("clicked!");
    });
    btn.addEventListener("click", () => {
      console.log("clicked!");
    });
```
この例ではボタンを1回クリックすると、コンソール上に`clicked!`が2つ表示されます。

<br/>

イベントリスナーは複数登録が可能ですが、同じ関数が重複して登録されることはありません。
```js
    const btn = document.getElementById("btn");
    const clickHandler = () => {
      console.log("clicked!");
    };
    btn.addEventListener("click", clickHandler);
    btn.addEventListener("click", clickHandler);
```
この例ではボタンを1回クリックすると、コンソール上に`clicked!`が1つだけ表示されます。

`clickHandler`という変数には関数の参照値が格納されており、おなじ参照値が`addEventListener`に渡されています。

参照値が同じ関数を複数回設定しても、実際に登録されるのは1つのみとなります。

誤って複数回同じ関数を設定してしまっても、複数回同じ動作が起こらないようになっているわけですね。
package-lock.jsonって何のためにあるの？

# はじめに

Web開発をしているとき、ふと「`package-lock.json`って何のためにあるんだろう？」と思うことがありませんか？
`package.json`はインストールしたパッケージを管理してくれているのはなんとなくわかりますが、`package-lock.json`の役割は少し分かりづらいですよね。
そこで今回は、`package.json`と`package-lock.json`の役割や違いについて解説します。


# 両者の違い

簡単に言えば、`package.json`は**依存パッケージの「概要」を管理するファイル**であり、`package-lock.json`は**実際にインストールされた「具体的なバージョン」を記録するファイル**です。

`package.json`については比較的わかりやすいですが、`package-lock.json`が「具体的なバージョン」を記録するとはどういうことなのか、イメージがつかない方も多いと思います。

# package-lock.jsonがないとどうなる？

`package-lock.json`の役割をイメージしやすくするために、もしこれが存在しなかった場合の問題について説明します。

たとえば、あなたが`qiitan`というパッケージをインストールしたとします。

```
$ npm i qiitan
```

すると、`package.json`には以下のように記載されます。

```json:package-json
{
  "dependencies": {
    "qiitan": "^4.17.20"
  }
}
```
この時点では、互換性のある最新バージョン（例えば`4.17.21`）がインストールされ、`node_modules`に保存されます。

その後、このプロジェクトをGitHubにアップロードし、しばらく経った後に別の開発者がコードをクローンして`$ npm i`を実行したとしましょう。このとき、最新の互換バージョン（例えば`4.18.0`）がインストールされ、動作に不具合が発生する可能性があります。

これは、`package.json`の`^4.17.20`という記述がセマンティックバージョニングに基づいており、`4.x.x`の範囲内で最新のバージョンをインストールする仕様だからです。

このような問題を防ぐため、「その時点でインストールされた正確なバージョン」を記録する`package-lock.json`が必要になるのです。

```json:package-lock.json
{
  "dependencies": {
    "qiitan": {
      "version": "4.17.21",
      "resolved": "https://registry.npmjs.org/qiitan/-/qiitan-4.17.21.tgz",
      "integrity": "sha512-..."
    }
  }
}
```
これにより、他の開発者が同じリポジトリをクローンして`$ npm i`を実行しても、確実に`4.17.21`がインストールされます。

# package.jsonはいらないのでは？

ここまで読んで、「それなら最初から正確なバージョンを記録すればいいのでは？」と疑問に思ったかもしれません。

しかし、`package.json`には「概要」の管理という重要な役割があります。これにより、必要なライブラリやプロジェクトの基本情報を他の開発者やツールが把握しやすくなります。また、`package-lock.json`は情報量が多く、簡単に人間が読むには適していません。

さらに、セマンティックバージョニングのおかげで、適切なアップデートを管理しやすいという利点もあります。加えて、`npm run dev`のようなスクリプトの定義にも`package.json`が使用されるため、プロジェクト全体の管理に欠かせない存在です。

# まとめ
今回は、`package.json`と`package-lock.json`の違いについて解説しました。普段意識せずに使っているこれらのファイルが、開発を快適に進めるために重要な役割を果たしているのは驚きですね。これからも、開発に役立つ知識を発信していければと思います。
内製AIにコミットしてチームの業務を効率化しよう！

## 概要・経緯

LIFULLでは、keelaiというプロダクト名で、内製のGAIアプリ群を実装しています。

https://www.lifull.blog/entry/2023/11/16/170000

また、最近はkeelextという内製Chrome拡張との連携機能も整備されてきています。「[LLMを利用したPlatform Engineering](https://www.lifull.blog/entry/2024/08/29/173000)」にもあるようなGrafanaのログ要約に加えて、

> 当初はGrafanaのユーザ体験を補完するなどプラットフォームの利用補助が主なスコープでしたが、汎用AI(仮)の開発に伴いそのスコープが拡大してきています。

メーラーソフトでの自動メール文提案や、営業日報の入力補助なども行えるようになりました。

これらのツールでは、[インナーソース](https://about.gitlab.com/ja-jp/topics/version-control/what-is-innersource/)の考え方が採用されており、誰でも機能提案やPRが送れる状態になってはいます。これを使って本当は各部署で必要な機能をみんなで実装する流れを作りたいのですが、今のところはたまにある程度です。

そんな折に[創民祭](https://www.lifull.blog/entry/2024/03/18/170000)（社内エンジニア向けイベント）でLTを発表する機会がありました。そこで「**keelaiでチームの業務を効率化しよう！**」というタイトルで発表した内容をQiitaにも記載します。

## ①keelaiを使ってみよう！

まず、こういうチャットAIが使える状態になっても、「そもそもどこから使えばいいの？」という声が挙がると思います。例えばこのLTのタイトルを決める際にも「アイデア案を10個出して」という質問をしました。

特にGoogleなどの検索エンジンや、Slackや社内Wiki(Confluence)を探す代わりに質問してみるのをおすすめします。例えば、この間の社内の質問用Slackチャンネルで「（海外子会社とやり取りしたいから）英語の部署名や組織図が欲しい」という質問があったのですが、実はこの質問はkeelaiでもカバーできます。

keelaiは社内のFAQページのデータを[RAG](https://www.nri.com/jp/knowledge/glossary/lst/alphabet/rag)で参照できるようにしています。

![スクリーンショット 2024-12-02 23.02.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127762/6d783ff9-c72d-aad8-df91-51910cc3da80.png)

まず「何から業務効率化すればいいか分からない」という方は、まずなんでもkeelaiに聞いてみて、足りない社内情報は、FAQページや社内用語集のページに追加してもらえると嬉しいです。

FAQや用語集以外にも、ConfluenceやGitHub、Slackなども簡単な設定ファイルだけで取り込めるようになっています。直接PRを出してもらってもいいし、スプレッドシートから簡単に追加依頼を出せる仕組みも整備されています。

こうするとkeelaiがだんだん質問をカバーできる範囲が増えていきます。


## ②自動化してみよう！

次にトライしてほしいのがSlack Automationです。例えば「[海外の開発拠点メンバーと、受託先ではなくチームメンバーとして協働するための取り組み](https://www.lifull.blog/entry/2024/03/01/190000)」で興津さんが書いているように、絵文字リアクションで翻訳プロンプトを起動するものは、社内で広く使われていると思います。

> このkeelaiとSlackワークフロービルダーを掛け合わせることで、自動翻訳を行うこともあります。
>
> たとえば、Slackで任意の投稿に特定のリアクションをつけた時、keelaiにその投稿を翻訳するように指示をする、というワークフローを作成します。

![スクリーンショット 2024-12-02 23.19.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127762/53d78134-c1c8-5317-2f71-f1fa80bd4d78.png)

よくあるプロンプトをbotで自動入力しているだけではあるんですが、意外と便利でいろいろな使い方ができます。他にも「URLの記事を要約する」とか「フォーム入力で箇条書きから営業日報を作成する」とかが使われています。

また、更に一歩進んで、自部署や関連部署が使うツールの自動化を効率したいとき、Chrome拡張機能に組み込むと更に楽になるかもしれません。ちょうど今朝、営業メンバーが使っていた日報用プロンプトを元に、Chrome拡張機能をリリースしました。

自由入力欄にメモ書きを書いていると、それを構造的に整理してくれるようなシンプルなもので、実はほぼメーラーソフト向けの返信文提案実装の使いまわしです。ただ実際に使うと、画面遷移せずにそのまま使えるのがけっこう便利らしくて、その営業の方から

> 商談メモがワンクリックで整理された日報になるのでは感動しております、、、！！！

というコメントをいただけたのがめちゃめちゃ嬉しかったです。

## ③keelaiプロジェクトにコミットしてみよう！

さらに一歩進んで、keelaiプロジェクト自体にコミットできる機会を作ってもらえると嬉しいです。自部署業務で役に立つのは、次の3つだと思います。

1. RAGのデータソースの追加
1. 外部ツールの入力補助をChrome拡張（keelext）に実装する
1. keelai本体への機能追加

1と2はこれまでの話とも被っています。

「RAGのデータソースの追加」は、ConfluenceやGitHubのドキュメント追加がまず嬉しいです。更に部署によってはJiraにある過去の依頼内容や、Google Driveの発表資料をkeelaiが検索できたら便利かもしれません。認証機能の実装はしているものの、これらのRAG機能への取り込みは未対応です。

「外部ツールの入力補助をChrome拡張（keelext）に実装する」は先程説明した通りです。最近メーラーソフトの機能拡張や、Salesforceに対応しました。

「keelai本体への機能追加」は、例えばkeelaiの連携できるツールが増えたら便利かもしれません。例えば（詳細は私も思いついてないですが）社内の物件情報検索APIと連携して開発を効率化したり、Googleカレンダーの予定が空いているか参照したりすると、自部署の業務効率化できる幅が増えるし、それは他の社員にとっても便利な機能かもしれません。

こうしたポイントで業務やツールを見直していいアイデアを探して、相談チャンネルで話しかけてもらえると嬉しいです。自部署の業務効率化もして、GAI基盤の機能整備もするような、みんなHAPPYになれる道を探っていきましょう！
初めてデータベーススペシャリスト試験を受けてきた 午後I試験のまとめ

## はじめに

今日は、午後I試験についてまとめます。

## 本文

### 午後I試験のまとめ

- **試験情報**
    - **実施日**: 2024年10月13日
    - **問題**: [IPA公式サイト](https://www.ipa.go.jp/shiken/mondai-kaiotu/2024r06.html)

### 午後I試験の傾向

午後I試験は3問構成で、その中から2問を選択して解答します。私は問1のデータベース設計と問2のデータベース実装を選びました。

- **問1**: 教育事業者のオンライン学習プラットフォームのデータベース設計に関する問題。現行業務の概念データモデルにおけるリレーションシップの記入や関係スキーマの穴埋め、受講者からの要望に応じた設計変更が問われました
- **問2**: 総合商社の労務管理システムのデータベース実装に関する問題。SQLの穴埋め、デッドロック発生時のロック状況と回避策、監査機能の処理の実装が問われました

### 間違えた問題とその分析

午後問題の解答例は12月24日に発表されるため、正確な間違いは分かりませんが、私の印象では問1の問題文を読み解くのに苦戦しました。特に、企業向けサービスの追加に伴う設計変更に多くの時間を費やしてしまいました。一方、問2の内容は理解しやすかったものの、問1に時間をかけ過ぎたため、問2の解答時間が不足してしまいました。（解答例が公開されたら追記します。）

また、午後の試験では昼食後ということもあり、集中力を維持するのが難しかったです。眠気を防ぐためにカフェインを多めに摂取した結果、トイレが近くなってしまい、そのことが試験中ずっと気になってしまったのも反省点です。

### 来年に向けて

まずは、昼食の取り方や時間配分に注意したいと思います。また、同様の問題を徹底的に解くことで対策を進める必要があります。

- **データベース設計**: エンティティタイプ名の穴埋め、リレーションシップの記入、関係スキーマの穴埋めなどが重要
- **データベース実装**: SQLの穴埋め、デッドロックの回避、ページ数の見積もりなどへの対策が必要

## まとめ

今回の試験を通じて、自分の弱点や改善すべき点が明確になりました。午前試験では基本的な知識の確認不足、午後試験では時間配分と集中力の維持が課題です。また、試験当日の体調管理や食事にも注意が必要だと感じました。来年の試験に向けて、これらの反省点を踏まえ、計画的な学習と実践的な問題演習を重ねていきたいと思います。
素人がGarageBandでundertaleのBGMっぽい曲を作る


## おはよおおおおおおおおおお〜〜
さて、元気の良い挨拶が出たところで、どうもこんにちは。　
挨拶は昼でも夜でもおはようの、あるところでは「 **ペンギン** 」、あるところでは「 **冷凍ご飯** 」こと、 _**『ライス』**_ です。（あるいはレンジ）
「レンジ教祖」と人は呼びます。(|)

こういう記事とか書いたこと無いので、色々おかしいところがあるかもしれませんが、大目に見てくださいね。

:::note alert
書き出し×
おお、こんなことができるのですね。🐧
:::

# 本題に入ろう
この記事の内容はズバリ、 GarageBandで **「っぽい曲」** を作ることです。

つまり、似たような曲ということ。噛み砕いて人聞きの悪いように言うと、**意図してパクる**ってことです。そう、特徴を捉えて、その人が作ったような曲を作るってことなんですね。
今回は私が結構好きなゲーム、 **「undertale」** 風の曲を作ってみます。クオリティは、求めないでね。
もし、GarageBandで曲作りたいよ〜って人が居たら、ぜひ見てってください。

参考になったら良いですね。（なるかよ）


　
※決して悪意を持って作っているわけではありません
## まずはそれっぽくやってみよう
**戦闘曲** つくります。まず特徴を把握しよう。

・ドラム結構激しめ
・ガチャガチャしてる（昔のゲームみたいな音）
・ふわ～って感じある（？）
・染み込んでくるかっこよさ
・神
・静かな所ある（ここはちょっと省きます。曲は全体的に短くなりますm(_ _)m）

**_なるほどね、完全に理解した。（理解してない）_**

よし、まずはドラムでしょう！

![IMG_4452.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3946492/a512d23f-a1b8-ead4-2593-4da99002f13a.png)

ほいほいほい（低音を入れていくぞ）


![IMG_4451.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3946492/866bf9aa-478a-8e7b-bffe-833b8e55f276.png)

~~え？これ動画入れられないんですか？~~
~~あ、youtubeから行けばできるんですか？！~~
よし、こうやってURL置けば多分、きっと見てくれるはず！！

https://youtu.be/hs2CTpY9YCE?si=h47yuwg4HCuaQBDK

↑これでドラムとベースの基礎が組み上がりました。あとで仕上げます。
次はメロディを入れていきましょうか。戦闘から気が散らないように何回かの繰り返しが多そうです。

https://youtu.be/SH-QLy8Z7GA?si=Y4ZfP0mlNOpzLCyx

↑苦戦してる人
ここから一体どうやってかっこよくしていけば.......
**作曲たるもの料理と同じですから！！** 焼いたり煮たり、調味料を入れたり味見したり。そういうとこ結構似通ってますからね。

え？私ですか？料理苦手ですけど（）

https://youtu.be/9Lkk0JYUu-I?si=qrlstCBeBRYHLwBw

↑アクセントにピコピコ鳴る楽器入れてみました。undertale感が増しましたね！

https://youtu.be/jBHu5WwLiIc?si=lJV-rqUfZNt8KHkM

↑楽器を漁っていたら、自動でガシャガシャ言ってくれる、とても便利でかっこいいものを見つけました。君には、 **冷凍ご飯をレンジで解凍したときに、少しまだ端っこに固まって解け残ってて、食べたらジャリジャリ言う米粒程度** には食感を引き立ててもらいましょう。

https://youtu.be/P2MkplERTIc?si=0U8neSTOg1RBI-BR

↑どこかのサイトで学びましたが、シンバルの音を **結合** で音声ファイル化してから逆再生すると、よくある **ｼｭﾜｱｱｯ** てのができます。
今回の記事の中で唯一の役立ち情報（GarageBandやってる人限定）

## これらを全部合わせると...?
　　
### こうなります。

https://youtu.be/7-0kAo2-p0M?si=aopOXryiKhDM7xPs


実は結構いい感じに仕上がったと思ってます。普通に敵と戦うときこれ流れるでしょ（）
しっかりおまけ程度に静かなゾーンも入れちゃって、弦楽器らしきものも下に入れちゃいました。


## 最後に
案外時間はそれほどかかってません。**曲を作る分には。**
この記事を書くことの方にむしろ時間かかってます。
ブログとか記事作ってる人に今だいぶ感謝と尊敬の念が湧き上がってきました。すごいですね。

もうすぐクリスマス、私は独り没っ血です。
どうでもいいですが、最近風邪気味です。
体調管理気をつけてください。（そんな終わり方が許されるのか）
mayaのwindowの中央にwindowを表示させる

mayaでpyside(2 or 6)を使ってツール等々を作成してるのですがー

デュアルディスプレイ環境だと、予期せぬ位置にウィンドウが生成されてしまって
うーんってなることがあります。

従来の方法としては、QtWidgets.QMainWindowを作った後に、move()で移動させていました。

```python
from PySide2 import QtWidgets,QtGui,QtCore

def getTopLevelWidget(name):
    for widget in QtWidgets.QApplication.topLevelWidgets():    
        if widget.objectName() == name:
            return widget
    return None

class MainGUI(QtWidgets.QMainWindow):
    def __init__(self,*args, **kwargs):
        super(MainGUI,self).__init__(*args,**kwargs)
        
        self.setWindowFlags(QtCore.Qt.Tool)
        
        self.mainWidget = QtWidgets.QWidget(self)
        mainLayout = QtWidgets.QHBoxLayout(self.mainWidget)
        btn = QtWidgets.QPushButton("hogeeeeeeee")
        mainLayout.addWidget(btn)
        self.setCentralWidget(self.mainWidget)
        
def main():    
    mayaMainWindow = getTopLevelWidget('MayaWindow')            
    mainGUI = MainGUI(mayaMainWindow)    
    mainGUI.show()
    mainGUI.move(100,100)
```

ただこのmove()で決める位置が、デュアルディスプレイだとプライマリのデスクトップの左上を0，0としたもので、
mayaのwindowがセカンダリのデスクトップにあったとしても、プライマリの座標(100,100) に作られてしまうので
一瞬　あれどこいった？　ってなるんですね。

改修
--

mayaのwindowの中央にwindowを表示させるにはどうしたら・・・？

今回参考にさせて頂きました。

https://redglasses67.jimdofree.com/maya-windows-move-center/

処理の順序としては

- mayaのwindowが表示されているデスクトップのindexを取得
- indexのデスクトップの左上のglobal座標？を取得
- mayaのwindowの現在のデスクトップにおける左上の座標を取得
- mayaのwindwo上の中心座標を取得
- 色々合算

という感じで。


```python
from PySide2 import QtWidgets,QtGui,QtCore

def getTopLevelWidget(name):
    for widget in QtWidgets.QApplication.topLevelWidgets():    
        if widget.objectName() == name:
            return widget
    return None

class MainGUI(QtWidgets.QMainWindow):
    def __init__(self,*args, **kwargs):
        super(MainGUI,self).__init__(*args,**kwargs)
        
        self.setWindowFlags(QtCore.Qt.Tool)
        
        self.mainWidget = QtWidgets.QWidget(self)
        mainLayout = QtWidgets.QHBoxLayout(self.mainWidget)
        btn = QtWidgets.QPushButton("hogeeeeeeee")
        mainLayout.addWidget(btn)
        self.setCentralWidget(self.mainWidget)

def main():
    desktop       = QtWidgets.QApplication.desktop()
    mayaMainWindow = getTopLevelWidget('MayaWindow')
    activeScreen  = desktop.screenNumber(mayaMainWindow)
    desktopRect = desktop.screenGeometry(activeScreen)
        
    windowCenter = mayaMainWindow.rect().center()
    windowCheck(objectName,mayaMainWindow)

    mainGUI = MainGUI(mayaMainWindow)    
    mainGUI.resize(50,50)

    mainGUI.show()
    mainGUI.move(desktopRect.topLeft() + mayaMainWindow.rect().topLeft() + windowCenter)
    
```

中央に生成されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/9c53f539-af86-55a4-e3e7-f35ebec56dff.png)

これでwindowを見失うことが減りそうです。
インスピレーションと気づきの一日：情報発信の重要性を考える

今日は、何気ない日常の中で大きなインスピレーションを得た一日でした。そのきっかけは、なんとお風呂に入っているとき。湯船の中でふと、 「日記を書くことで頭の整理ができる」 というシンプルながら重要な気づきを得たのです。

現代社会は情報過多の時代です。その中で、頭の中を整理し、自分なりの視点を持つことは、一種の才能ともいえるでしょう。さらに、この「整理された情報」を発信することで、他者に貢献できるという可能性にも思い至りました。たとえば、情報を求めている人に対して、わかりやすい形で知識を提供すること。それは、自分の学びを深めながら他者を助ける、まさに 「Win-Winの関係」 です。

学びを形にする：アウトプットの力

特に印象的だったのは、学びをそのまま形にしていくという発想。例えば、Web開発を学んだら、実際にWebサイトを作り、そのサイトでWeb開発のノウハウを発信する。これがただの「学び」ではなく、「学びを活用した実践」と「知識の共有」という、一石三鳥、いやそれ以上の価値を生む行動になるのです。

ここで鍵となるのが、アウトプットを 習慣化 すること。そのためには、日記やメモを「下書き」とし、ブログなどで清書するという考え方が役立つと感じました。また、アウトプットの障害となる「インプット過多」を防ぐために、Woopの法則やイフゼンプランニング（例：インプットしたらすぐアウトプットする）を取り入れることが有効だと気づきました。

日常の中の小さな行動

今日のもう一つの発見は、友人との会話で相手の話に興味を持つ大切さです。たとえば、「どうだった？」と自然に聞くことで、相手が答えやすくなり、会話がスムーズに進むことを実感しました。この小さな工夫が、良い人間関係を築く第一歩になるのかもしれません。

メンタルケアの工夫

また、メンタルを強くするための行動として、人と会うことや、心がざわついたときに呼吸に集中することを実践しました。このシンプルな方法が、意外にも心を落ち着ける効果があると感じています。

こうして振り返ってみると、今日の経験は、ただの日常の一コマではなく、自分の成長や人とのつながりを深めるための重要なヒントに満ちていました。これからも日記を通じて、日々の気づきを大切にし、アウトプットを続けていきたいと思います。
GRAPH QLとREST APIを浅く理解する

## そもそもGraph QLとREST APIって？？

webから情報を取ってくるためのアーキテクチャ。
それぞれ考え方が違う

## REST API
今までの一般的な考え方。

RESTはRepresentational State Transferの略で、HTTPを使ってアクセスすることでデータの送受信をする

決まったURIにリクエストを飛ばすと、決まったデータが返ってくるような考え方で、GET, PUT, POST, DELETEを指定する。

**RESTful**
REST APIの設計原則。

- ステートレス性
    - サーバー側にユーザーのセッション情報を保持しない→ 拡張性に優れる
    
    　　https://yohei-y.blogspot.com/2007/10/blog-post.html　が分かりやすかった
    
- リソースの識別
    - それぞれのページや画像は一意なURLを持っていて、そこにアクセスすることで情報を取ってこれる
- 統一インターフェース
    - 情報の操作はすべてhttpメソッド(get, put, post, delete)を使うこと
    - httpメソッドでpostしてjsonで帰ってくるみたいな感じで、あらかじめ、定義・共有された方法でやり取りされる
- 接続性
    - APIのレスポンスがリンクを含めるべきであるという考え方。リンクをレスポンスに含めることで、次にアクセスすべきページが分かりやすくなる
- キャッシュ可能
    - データが変わらない限り、キャッシュされた情報を利用することができるので、負荷軽減できる

## Graph QL

APIのクエリ言語。
誤解を恐れずに言うとSQLのクエリをフロントエンドから叩くイメージ

**メリット**
- 指定したデータのみ取得するので、余計なデータを取得せずに済む
    - ネットの帯域を圧迫せず、パフォーマンス向上が見込まれる
- エンドポイントを何個も作る必要が無く、1つだけでいい。
- 型指定をするのでデータが明確になる

**デメリット**
- リクエストが柔軟なので、セキュリティ上の注意が必要。
- レスポンスに含める要素をユーザーが指定してしまうので、キャッシュしにくい
- バックエンド側の処理が複雑になり、レスポンスにかかる時間が長くなりがち