OmniAICreator/Qiita-1.07M huggingface dataset:
GitHub 保存

 Gitリポジトリの初期設定を自動でやってくれるコマンド
```bash
git init
```
修正したファイルの状態を見る
```bash
git status 
```
下書き保存
```bash
git add .
```
メッセージ付きでローカルのgitに保存する
```bash
git commit -m "feat"
```

https://github.com/yukimarupi?tab=repositories

![スクリーンショット 2024-09-27 23.22.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3892264/d7dd76c0-74b5-6f3e-f181-b973bff8426f.png)


![スクリーンショット 2024-09-27 23.23.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3892264/6920153c-7dbc-cb5d-43bc-c45c5672d1b6.png)

![スクリーンショット 2024-09-27 23.24.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3892264/b84a708b-ae41-ac20-1f6c-5185dafb0086.png)

```bash
remote add origin https://github.com/yukimarupi/my-app.git
yuumiiida@Mac my-app % git remote -v                                                 
origin  https://github.com/yukimarupi/my-app.git (fetch)
origin  https://github.com/yukimarupi/my-app.git (push)
```

GitHubにローカルのGitの内容をアップロードする
```bash
git push origin main
```

```bash
git push origin main   

Enumerating objects: 22, done.
Counting objects: 100% (22/22), done.
Delta compression using up to 8 threads
Compressing objects: 100% (20/20), done.
Writing objects: 100% (22/22), 167.80 KiB | 1.10 MiB/s, done.
Total 22 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (2/2), done.
To github.com:yukimarupi/my-app.git
 * [new branch]      main -> main
```

done!

![スクリーンショット 2024-09-27 23.32.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3892264/c23c5938-863a-d3e6-6d36-1fa8446e34f0.png)
Pydanticの`from_attributes`とは？

## 概要

Pydanticのオブジェクトは、キーワード引数を使ってクラスから作成できます。
また、クラスの`model_validate()`を使うと、辞書やオブジェクトから作成できます。

このとき、クラスの`model_config`に`from_attributes=True`があるかないかで、変換元に使えるオブジェクトが変わります。

## 説明

2種類のクラスを考えましょう。

| クラス | 特徴                                |
| :----- | :---------------------------------- |
| User   | from_attributes=False（デフォルト） |
| UserFA | from_attributes=True                |

これらのクラスは、次のようにオブジェクトを作成できます。

| 構築方法 ＼ 引数          | 自クラスのオブジェクト | 他クラスのオブジェクト | 辞書  | キーワード引数 |
| :------------------------ | :--------------------: | :--------------------: | :---: | :------------: |
| `User() / UserFA()`       |           x            |           x            |   x   |       ◯        |
| `User.model_validate()`   |           ◯            |           x            |   ◯   |       ×        |
| `UserFA.model_validate()` |           ◯            |           ◯            |   ◯   |       ×        |

## サンプルコード

具体的にコードで確認してみましょう。

```python
from pydantic import BaseModel, ConfigDict

class BaseModelFA(BaseModel):
    model_config = ConfigDict(from_attributes=True)

class User(BaseModel):
    name: str
    age: int

class UserFA(BaseModelFA):
    name: str
    age: int

user = User(name="Alice", age=30)
user_fa = UserFA(name="Alice", age=30)
user_fa_dict = user_fa.model_dump()  # {'name': 'Alice', 'age': 30}

print(User.model_validate(user_fa_dict))  # OK
# print(User.model_validate(user_fa))  # NG
print(UserFA.model_validate(user))  # OK
```

このように、`UserFA.model_validate()`は、他クラスのオブジェクトから作成できます。
一方、`User.model_validate()`は、他クラスのオブジェクトを渡すとValidationErrorになります。

## 補足

* 変換元に余計な情報があっても無視されます
* 変換先にデフォルト値があれば、変換元になくてもOKです

以上
【備忘録】Udemy講座まとめ JavaScript vol.3 スコープ

# 関数の外からアクセスできない

```JavaScript:JavaScript
function add(num1, num2) {
  const value = num1 + num2;
  return value;
}
console.log(value);

const returnedValue = add(2, 3);
```
コンソールにはエラーが出る
【value is not defined】
定数valueは、関数の外からはアクセスできない


# 定数・変数は関数の中から呼び出せる
```JavaScript:JavaScript
const newValue = 'Hello';
function add(num1, num2) {
  console.log(newValue);
  const value = num1 + num2;
  return value;
}

const returnedValue = add(2, 3);
```
逆に関数の中で、外で宣言したnewValueを呼び出せる


# スコープ
```JavaScript:JavaScript
const newValue = 'Hello';
function add(num1, num2) {
  console.log(newValue);
  const value = num1 + num2;
  return value;
}

const returnedValue = add(2, 3);
```
スコープは、関数を呼びさせる範囲のこと

newValueは、どこからでも呼び出せる（グローバルスコープ）
newValueは、addといy関数の中でだけ呼び出せる（ローカルスコープ）


# スコープ：シャドーイング
```JavaScript:JavaScript
const value = 'Hello';
function add(num1, num2) {
  console.log(newValue);
  const value = num1 + num2;
  return value;
}

const returnedValue = add(2, 3);
```
同じ変数名が、関数の外と中の両方に宣言されていた場合
関数の中の変数が呼び出される。
コンソールには、5と表示される
Celebrating Success: How I Achieved the ASQ CRE Certification with ProcessExam's Support

ASQ認定信頼性エンジニア（CRE）試験に合格したことは、私のプロフェッショナルな旅の中で重要なマイルストーンでした。問題解決と信頼性テストに情熱を持つ品質エンジニアとして、私は自分のスキルを証明し、キャリアの展望を広げたいと考えていました。数ヶ月の準備の後、ProcessExamの優れたリソースと模擬試験のおかげで、ASQ CRE試験を見事に合格した私のストーリーを共有できることに興奮しています。

ASQ CRE認定を取得する決断
品質保証分野で数年働いている中で、さらなる専門性を求める必要を感じました。信頼性工学は、故障を防ぎ、プロセスを改善し、高い基準を満たす製品を確保することに焦点を当てているため、私を引きつけました。さまざまな認定について調査した結果、ASQ CREはその信頼性と業界での認知度で際立っていました。

しかし、ASQ CRE試験が簡単ではないことにもすぐに気づきました。信頼性の概念、統計分析の深い理解、理論を実践的なシナリオに応用する能力が求められます。このような厳しい試験に挑戦することは daunting でしたが、正しい準備戦略が成功の鍵であることは分かっていました。

信頼できる学習リソースを見つける挑戦
準備を始めると、すべての学習資料が満足のいくものではないことに気づきました。技術的すぎるものや、包括的なカバーが欠けているものもありました。理論を教えるだけでなく、概念の実践的な応用の準備をするリソースを探していました。そんな時、ProcessExamに出会いました。

ProcessExamに惹かれたのは、成功した受験者たちからの高評価です。彼らは、このプラットフォームの模擬試験が実際の試験環境を反映し、改善すべき領域を特定するのに役立ったと強調していました。ウェブサイトを探索し、サンプル問題を見た後、ProcessExamが私に必要な構造的アプローチを提供できると確信しました。

私の学習戦略：ProcessExamのリソースを最大限に活用
ProcessExamのCRE試験パッケージに登録すると、コンテンツの広がりに pleasantly surprised されました。このプラットフォームは以下を提供しました：

リアルな模擬試験: 模擬試験はASQ CREの全シラバスをカバーし、信頼性と保守性、リスク管理、データ分析などのコア領域に焦点を当てています。各テストは実際の試験の複雑さと形式を模倣するように設計されており、何を期待すべきかを明確に理解できました。
詳細な説明: 各質問には説明が付いており、特定の選択肢が正しい理由や、他の選択肢がどこで不足しているかを分解して示していました。この機能は、難しいトピックの理解を強化するのに非常に価値がありました。
進捗トラッキング: 自分の進捗を追跡し、スコアが低かった領域を再訪する能力が、復習セッションの優先順位を決めるのに役立ちました。
ProcessExamの模擬試験が私の自信を高めた理由
模擬試験は私の準備においてゲームチェンジャーとなりました。最初は、一部の高度な概念に苦しみ、膨大な資料に圧倒されていました。しかし、練習試験を受けるうちに、理解力と自信が大きく向上していることに気づきました。

模擬試験は単なる知識テストではなく、学習のためのツールでした。試験の難易度が徐々に上がり、私が批判的に考え、概念を新しい方法で適用するよう促されるのを楽しみました。すべての模擬試験を完了する頃には、20回以上のフルレングスの練習試験を受け、それぞれを徹底的に分析しました。

課題を克服し、モチベーションを維持
他の試験準備の旅と同様、行き詰ったり、自分の能力に疑問を抱いたりする日もありました。そのような時、私はProcessExamのウェブサイトにあるコミュニティフォーラムや成功事例を利用しました。同じような課題に直面しながらも成功した他の人たちの話を読むことで、前進し続ける意欲が湧きました。

また、定期的な休憩を取り、ストレスを管理することが重要だと実感しました。そのため、数日間集中的に学習し、その後リチャージのために休むというバランスの取れたアプローチを採用しました。この戦略は、燃え尽きるのを防ぎ、準備期間を通じて集中力を維持するのに役立ちました。

試験当日：準備を試す
ついに試験当日がやってきました。緊張しましたが、ProcessExamの模擬試験のおかげで準備ができていると感じました。実際の試験は難しかったですが、問題を解くにつれて、私の準備の直接的な影響を実感しました。かつては複雑に感じた概念が身近に感じられ、自信を持って問題に取り組むことができました。

模擬試験は、時間をうまく管理する準備をさせてくれました。おかげで、見直しのために数分間余裕を持って試験を終えることができました。「合格」というメッセージを画面で見たとき、純粋な喜びと安堵の瞬間でした。すべての努力、献身、そしてProcessExamのプラットフォームに費やした数えきれない時間が実を結びました。

ASQ CRE志望者にProcessExamをお勧めする理由
ASQ CRE試験に合格することは小さな成果ではなく、私はProcessExamに大きく依存しました。ここに、私がこの認定を準備している誰にでもお勧めする理由があります：

リアルな試験体験: 模擬試験は、実際の試験で直面する難易度と質問の種類を正確に反映しています。
徹底的な説明: 各質問は学習の機会であり、混乱を解消するための詳細な説明があります。
適応型学習: プラットフォームは、自分の強みと弱みを特定するのに役立ち、改善が必要な領域に集中することができます。
自信の向上: 模擬試験を完了する頃には、自信を持って試験に臨むことができるでしょう。
最後の考え
ASQ CRE試験を準備しているすべての方に、ProcessExamを学習計画に取り入れることを強くお勧めします。構造化された学習、リアルな模擬試験、洞察に満ちた説明が、最も難しいトピックを乗り越える手助けをしてくれるでしょう。忘れないでください、一貫性と忍耐が重要です—プロセスを信じ、適切なリソースを活用すれば、成功はついてきます。

ProcessExamに感謝します。私の認定の旅の重要な一部となってくれました。私はASQ認定信頼性エンジニアとして新たな挑戦に立ち向かい、品質エンジニアリングの分野に貢献できることを誇りに思います。

すべての志望CREに幸運を祈ります！私ができたのだから、あなたもできます。
https://www.processexam.com/blog/achieving-asq-cre-certification-practice-tests-and-exam-strategies
【コピペでできる】JSのcanvasで画像合成

# はじめに
アップロードした画像を事前に入力したテキストと合成し、その結果をダウンロードしたい場合、以下のようにするとよいです

## ソースコード
以下のHTMLをコピーすると、入力したテキストがアップロードした画像の右下に合成されます
合成された画像はダウンロードすることも可能です

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>画像にテキストを追加して保存</title>
</head>
<body>
    <h1>画像にテキストを追加して保存</h1>

    <!-- 画像アップロード -->
    <input type="file" id="imageUpload" accept="image/*"><br><br>

    <!-- テキスト入力 -->
    <label for="textInput">追加するテキスト:</label>
    <input type="text" id="textInput" placeholder="テキストを入力してください"><br><br>

    <!-- キャンバス -->
    <canvas id="imageCanvas" style="border:1px solid black;"></canvas><br>

    <!-- 保存ボタン -->
    <button id="saveButton" disabled>画像として保存</button>

    <script>
        const canvas = document.getElementById('imageCanvas');
        const ctx = canvas.getContext('2d');
        const imageUpload = document.getElementById('imageUpload');
        const textInput = document.getElementById('textInput');
        const saveButton = document.getElementById('saveButton');

        let uploadedImage = null;

        // 画像がアップロードされたときの処理
        imageUpload.addEventListener('change', function(event) {
            const file = event.target.files[0];
            const reader = new FileReader();

            reader.onload = function(e) {
                const img = new Image();
                img.onload = function() {
                    // キャンバスのサイズを画像に合わせる
                    canvas.width = img.width;
                    canvas.height = img.height;
                    // 画像をキャンバスに描画
                    ctx.drawImage(img, 0, 0);
                    uploadedImage = img;
                    saveButton.disabled = false;
                };
                img.src = e.target.result;
            };

            if (file) {
                reader.readAsDataURL(file);
            }
        });

        // テキストをキャンバスに追加する関数
        function addTextToCanvas() {
            if (!uploadedImage) return;

            // 再度画像を描画（テキスト追加前にクリアしてリセット）
            ctx.drawImage(uploadedImage, 0, 0);

            const text = textInput.value;

            // テキストのスタイルを設定
            ctx.font = '30px Arial';
            ctx.fillStyle = 'white'; // テキストの色
            ctx.textAlign = 'right'; // 右揃え
            ctx.textBaseline = 'bottom'; // 下揃え

            // テキストを画像の右下に描画
            const x = canvas.width - 10; // 右から10px内側
            const y = canvas.height - 10; // 下から10px上
            ctx.fillText(text, x, y);
        }

        // テキストが入力されたら即時キャンバスに反映
        textInput.addEventListener('input', addTextToCanvas);

        // 保存ボタンを押したときの処理
        saveButton.addEventListener('click', function() {
            // テキストを追加してから保存
            addTextToCanvas();

            // キャンバスの内容を画像に変換してダウンロード
            const link = document.createElement('a');
            link.href = canvas.toDataURL('image/png');
            link.download = 'image_with_text.png';
            link.click();
        });
    </script>
</body>
</html>
```
【HTML】time要素の使用方法

## `<time>`要素とは

`<time>`要素は日付や時刻、経過時間などを表します。
画面に表示される日時情報は人間が読みやすいようにしつつ、`datetime`という属性を使用して正確な日時を機械に対して伝えられます。


## 使用方法
`<time>`要素は、以下のように使用します。

```html
<time datetime="2023-10-01T14:30:00">2023年10月1日 14:30</time>
```

### `datetime`属性
`datetime`属性は、機械が理解できる形式で情報を提供します。
以下のような書式でなければなりません。

**有効な年の文字列**
- `2011`

**有効な月の文字列**
- `2011-11`

**有効な日付の文字列**
- `2011-11-18`

**年のない有効な日付の文字列**
- `11-18`

**有効な週の文字列**
- `2011-W47`

**有効な時刻の文字列**
- `14:54`
- `14:54:39`
- `14:54:39.929`

**有効なローカル日時の文字列**
- `2011-11-18T14:54:39.929`
- `2011-11-18 14:54:39.929`

**有効なグローバル日時の文字列**
- `2011-11-18T14:54:39.929Z`
- `2011-11-18T14:54:39.929-0400`
- `2011-11-18T14:54:39.929-04:00`
- `2011-11-18 14:54:39.929Z`
- `2011-11-18 14:54:39.929-0400`
- `2011-11-18 14:54:39.929-04:00`

**有効な期間の文字列**
- `PT4H18M3S`

## 具体例

### 記事の公開日

```html
<article>
  <h2>新しい技術のトレンド</h2>
  <p>この記事は、<time datetime="2023-10-01">2023年10月1日</time>に公開されました。</p>
</article>
```

### イベントの日付

```html
<section>
  <h2>カンファレンスのお知らせ</h2>
  <p>次回のカンファレンスは、<time datetime="2023-11-15T09:00">2023年11月15日 09:00</time>に開催されます。</p>
</section>
```

### 過去の出来事

```html
<aside>
  <h2>歴史的な出来事</h2>
  <p>月面着陸は、<time datetime="1969-07-20">1969年7月20日</time>に行われました。</p>
</aside>
```

## 参考

https://developer.mozilla.org/ja/docs/Web/HTML/Element/time
iOSショートカットアプリでPythonを実行する

# 概要

iOSのショートカットアプリ単体でPythonを実行するショートカットを作成した。

## 完成したショートカット

結論以下のショートカットを実装した。

![IMG_0269.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57640/778ccc72-9b8a-a12d-89f8-f9b3a9dd7a6f.png)

# 背景

翌朝出すべきゴミの種類を、夜にHomePodからアナウンスさせる仕組みを作成しようと考えた。最初はChatGPTのショートカットを使って自動化を試みたが、バージョンによって回答が不安定だったり、スマホがロック中にショートカットを実行できないという問題があった。これらの課題を解決するために、ショートカットアプリ内でChatGPTの処理をPythonに置き換える方法を検討した。

# 実装

## 方針

ショートカットアプリでPythonコードを実行する方法はいくつか考えられたが、すでにインストール済みの[a-shell](https://github.com/holzschu/a-shell)がショートカットから直接実行できるため、これを利用することにした。a-shellのショートカットからは任意のシェルコマンドを実行でき、a-shell経由でPythonも実行可能である。

「外部にPythonスクリプトを置き、SSH経由で実行する」という方法も考えたが、スクリプトを設置するサーバのメンテナンスが面倒であるため、この方法は採用しなかった。

## 手順

ショートカットアプリ上でPythonスクリプトを編集・確認したいので、以下の流れで処理を実装した。

1. テキストとしてPythonのコードを定義
2. PythonのコードをBase64でエンコード
3. a-shellから以下のコマンドを実行
    3.1. 2. で生成したBase64コードをデコード( `echo {base64でエンコードされたコード} | base64 -d` )
    3.2. そのコードをPythonにパイプで実行させる( `python -` )

## 結論

これでショートカットから任意のPythonスクリプトを編集・実行することが可能になった。これをもとに「ゴミの日チェックショートカット」を作成して、その実行内容をインターコムで HomePod からオートメーションで通知させることに成功した。
エラー：　Missing script: "start"　解決方法


### 概要
vscodeのターミナルで `npm start` コマンドを実行して、ローカルのサーバを起動することがあると思います。
その際、 **Missing script: "start"** というエラーが出て先に進まない、、、
そんな悩みを解決するために調べた原因と解決法を、共有できればと思います。
いったん先に進めたい人は、試してみてください。
私は2つ目が原因でエラーがでました。
始めたばかりだと見落としがちです。 <-私もその１人
<br>
***
### 原因

1. package.jsonファイルに **start** コマンドが定義されていない。
<br><br>
2. コマンドを実行したときのディレクトリが違う。　<--私はこれが原因でした。。
<br><br>
3. 依存関係が正しくインストールされていない。

***
### 解決方法
1.　package.jsonファイルに以下の定義を追加する。
 `{
   "scripts": {
     "start": "react-scripts start"
   }
  }`

<ちょこっと説明>
定義を書くことで、ターミナルで `npm start` コマンドを実行可能になる。
通常ターミナルで `create-react-app` コマンドを実行すると、Reactプロジェクトのひな型が作成されます。作成されたプロジェクトに package.jsonファイルは自動的に作られ、その中にstartコマンドの定義もされるはずです。
<br>

2.　ディレクトリを確認する。
　vscodeのターミナルで、 `npm start` を実行する際のディレクトリを確認しましょう。
  `npm start` を **実行しているディレクトが、package.jsonが存在するプロジェクトのルートディレクトリである必要があります。**
自分が今どこの階層にいるかを確認し、適切な階層に移動して`npm start`コマンドを実行してみてください。
※ルートディレクトリについては、下記のリンクを参考にしてください。
https://26gram.com/directory-meaning
<br>

3.　依存関係を再インストールする。
 下記のコマンドを実行してする。
 `npm install`
 その後`npm start`コマンドを実行してみる。

***

### 備考
これを書いている私もプログラミングを学習し始めたばかりの初学者です。
解説不足や、誤りがあるかもしれませんが、参考になればと思い書きました。
私と同じうように躓いている人の役に立てれば嬉しいです。
知識グラフ入門：Neo4jとオントロジーの関係性を理解する

## はじめに
こんにちは。この記事は、私が知識グラフ、Neo4j、そしてオントロジーについて学び始めたときの備忘録です。これから知識グラフを学ぼうとしている方の参考になれば幸いです。

## 1. 知識グラフとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/84baac1e-1336-3d60-7648-4714e6cb7181.png)

知識グラフは、実世界の情報を構造化して表現するデータモデルです。学び始めて気づいた主な特徴は：

- エンティティ（ノード）と関係（エッジ）で構成される
- 複雑な関係性を直感的に表現できる
- 機械学習や自然言語処理などのAI技術と相性が良い

## 2. Neo4jについて

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/fd3ea246-aad2-7087-6696-8386257ee4f4.png)

Neo4jは、知識グラフを実装するためによく使われるグラフデータベース管理システムです。以下の点が印象的でした：

- グラフ形式でデータを格納・管理する
- Cypher言語というグラフに特化したクエリ言語を使用する
- 視覚的にデータを表現できるので、関係性を理解しやすい

## 3. オントロジーとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/24b9314e-3536-1695-127c-ba3fdd3a968e.png)

オントロジーは、特定の分野における概念とその関係性を形式的に表現したものです。学んでいて重要だと感じた点：

- 概念の階層構造や関係性を明確に定義する
- データの意味や文脈を表現できる
- 異なるシステム間でのデータ統合を容易にする

## 4. Neo4jとオントロジーの関係

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/05955b2b-11d9-8bf2-3b86-a22abcafc932.png)

Neo4jとオントロジーは、知識グラフの構築と利用において相互に補完し合う関係にあります：

1. オントロジーによる構造化：
   - オントロジーを用いてドメインの概念と関係性を定義
   - Neo4jでのデータモデリングの指針となる

2. Neo4jでの実装：
   - 定義されたオントロジーに基づいて、Neo4jでグラフ構造を作成
   - オントロジーの概念をノードとして、関係性をエッジとして表現

3. データの整合性維持：
   - オントロジーの規則に従ってデータを入力・更新することで、一貫性を保つ

4. 推論と知識発見：
   - オントロジーの論理規則を用いて、Neo4j上のデータから新たな知識を導出

## 5. 知識グラフを学び始めて気づいたこと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/5798f593-714b-a964-9954-2051a240cd41.png)

1. グラフ理論の基礎が重要：
   - ノード、エッジ、プロパティなどの基本概念を理解することが大切

2. Neo4jとCypher言語の学習曲線：
   - 最初は難しく感じるが、基本を押さえれば徐々に理解できる

3. オントロジー設計の奥深さ：
   - OWL (Web Ontology Language) やRDF (Resource Description Framework) の概念を理解するのに時間がかかる
   - 既存のオントロジー（例：Schema.org）を参考にすると理解が深まる

4. 応用分野の広さ：
   - 推薦システム、質問応答システム、データ統合など、様々な分野で活用されている

5. コミュニティの重要性：
   - Neo4jやSemantic Web関連のフォーラムやイベントに参加すると、最新情報や実践的なアドバイスを得られる

## まとめ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/14f16d32-36bc-bebc-e325-56e6b69bce51.png)

知識グラフ、Neo4j、オントロジーの学習を始めてみて、データの表現と利用に関する新しい視点を得ることができました。これらの技術は、複雑な情報を構造化し、効率的に利用するための強力なツールです。

特に、Neo4jとオントロジーの組み合わせにより、より柔軟で意味豊かなデータモデリングが可能になることが分かりました。これらの技術を習得することで、AIやビッグデータ分野での可能性が大きく広がると感じています。

これから知識グラフを学ぶ方々も、ぜひ粘り強く取り組んでみてください。理解が深まるにつれて、データの見方が変わっていくはずです。
【QiitaAPI】Qiita記事を集計してホスティングサービスのランキングを作成してみた(https://hosting-rnk.com/)



## 概要

ホスティングサービス選びに迷ったことはないでしょうか？世の中には無数のサービスがありますが、実際にどれが人気で、どのように使われているかを把握するのは難しいものです。

そこで、QiitaのAPIを使って、Qiitaに投稿された記事をもとにホスティングサービスの人気度を集計し、リアルタイムなランキングを作成してみました。

[ホスティングサービスランキング](https://hosting-rnk.com/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790048/1f54e91c-1ce7-4b81-d4d9-2d99b9bec709.png)

---

## 目的と背景

ホスティングサービスを選ぶ際、多くの人は比較サイトやレビューを参考にしますが、これらはどうしても主観的な意見が含まれがちです。また、各サービスがどれくらい使われているかについてのデータが、はっきりと示されているわけでもありません。「AWS」「GCP」「Heroku」といった大手の名前はよく聞きますが、どのサービスがどんな用途でよく使われているのか、エンジニアがどれくらいの頻度でそれらを利用しているのかを知るには、実際の使用データが役立ちます。

そこで注目したのが「QiitaAPI」です。Qiitaは、エンジニアに広く利用されており、毎日多くの記事が投稿されています。このAPIを活用することで、ホスティングサービスに関する記事の数や内容を集計し、各サービスの人気度を測定できると考えました。


---

## 使用技術と手順

### Qiita APIを使ったデータ収集

まず、Qiita APIを使用して投稿記事を取得する仕組みを実装しました。Qiitaには、特定のキーワードで記事を検索できる記事検索APIが提供されています。今回は「ホスティングサービス」に関連するキーワードを使用して検索を行いました。

```
GET /api/v2/items?page=1&per_page=20&query=qiita+user%3AQiita HTTP/1.1
Host: api.example.com
```

APIを通じて取得したデータには、記事の投稿日時やタグ、いいね数などの情報も含まれているため、単なる言及数だけでなく、どれだけ多くのエンジニアに支持されているかも分析できるようにしました。

[ホスティングサービスランキングを確認する](https://hosting-rnk.com/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790048/6dfb7149-d685-b275-a7a2-14d57b526412.png)

### データの集計とランキング化

収集したデータを整理し、各ホスティングサービスごとの記事数や「いいね」の数をもとにランキングを作成しました。記事数が多いからといって必ずしも人気があるわけではないため、記事の評価（いいね数）も考慮し、総合的なスコアを算出しました。これにより、単に投稿数だけでなく、エンジニアにとって価値ある記事が多いサービスがランキング上位に来るよう工夫しています。

---

## 苦労した点

### サーバーが定期的にダウンする問題

開発を進める中で、いくつかの技術的な問題に直面しました。特に、サーバーが定期的にダウンしてしまう問題に悩まされました。原因を調査したところ、メモリ不足によってMySQLがクラッシュしていることがわかりました。この問題は、データベースのキャッシュ設定を見直し、メモリの割り当てを調整することで解決しました。

▼参考にした記事
[MySQLが勝手に落ちるのを解決する](https://qiita.com/satodayo/items/8d8d6f37314e5703becd)

### APIリクエストの403エラー

また、Qiita APIを使用している最中に、突然APIから403エラーが返される事態が発生しました。エラーメッセージから、APIリクエストが拒否されていることがわかり、調査した結果、リクエストが過剰だったためにアクセス制限がかかっていたことが原因でした。Qiita APIにはリクエスト数の制限があり、短時間に大量のリクエストを送るとアクセスが制限される仕組みです。これを回避するため、リクエスト間に1秒のインターバルを設けることで、APIの過負荷を防ぎ、安定したデータ収集を実現しました。
```
Thread.sleep(SLEEP_TIME); //1000ミリ秒スリープ
con.connect(); // WebAPIへ接続
```

---

## 最終成果

完成したランキングサイトでは、リアルタイムでホスティングサービスに関する記事を集計し、ランキング形式で表示できるようになりました。利用者は、どのホスティングサービスが現在のトレンドなのか、どのくらいのエンジニアに支持されているのかを一目で確認できます。また、各サービスに関する詳細な分析も提供しており、例えば「AWSはインフラ構築に関する記事が多いが、Firebaseはモバイルアプリ開発で人気がある」といった具体的な傾向も見えてきます。

今後は、データをさらに深掘りして、特定のホスティングサービスに関連する技術的なトピック（例：セキュリティ、スケーラビリティ、料金プラン）についての分析も行っていきたいと考えています。また、集計対象となるホスティングサービスの種類も増やし、より包括的なランキングを提供する予定です。

---

## まとめ

Qiita APIを活用したホスティングサービスのランキングサイトを構築することで、実際のエンジニアの利用状況を反映した、信頼性の高い情報源を提供することができました。ホスティングサービスの選定に悩んでいるエンジニアにとって、リアルタイムデータに基づくこのランキングは非常に有益なツールとなるでしょう。今後はさらなるデータ分析やサービス対象の拡充を図り、エンジニアコミュニティにとって一層価値のある情報を提供していきます。

[ホスティングサービスランキング](https://hosting-rnk.com/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790048/1f54e91c-1ce7-4b81-d4d9-2d99b9bec709.png)
圧縮形式について

## はじめに
Linuxを全く扱ったことがないので、何かしら学んでみようと思い、LPICの資格勉強中です。
今まではzipしか知らず、いろいろな圧縮方式が出てきて戸惑ったので、すごく簡単にまとめました。

## 圧縮ツールの比較①
Ping-tというサイトで勉強中で、そこで出てきた圧縮ツール4つ（gzip、bzip2、xz、zip）についてのメモです。
1. gzip（GNU Zip）
    * 概要：標準的な圧縮コマンドで、主に単一ファイルの圧縮に使用される
    * 圧縮率：一般的（bzip2やxzと比較すると低め）
    * 速度：圧縮が早く、展開も早い
    * 拡張子：.gz
    * 使用例：
    ```
    【圧縮】
    gzip ファイル名
    元のファイルも自動的に削除される。
    -k　元のファイルを残して圧縮

    【展開】
    gunzip ファイル名　または　gzip -d ファイル名

    【複数のファイルやディレクトリ】
    tar -czvf archive.tar.gz /path/to/directory
    -c　新しいアーカイブを作成する
    -z　gzip形式
    -v　処理したファイルを詳しく出力
    -f　アーカイブファイル名を指定
    ```
    <br>

2. bzip2
    * 概要：gzipよりも高圧縮率
    * 圧縮率：gzipよりは高いが、圧縮速度は遅い
    * 速度：圧縮は遅いが、展開は比較的早い
    * 拡張子：.bz2
    * 使用例：
    ```
    【圧縮】
    bzip2 ファイル名
    元のファイルも自動的に削除される。
    -k　元のファイルを残して圧縮

    【展開】
    bunzip2 ファイル名　または　bzip2 -d ファイル名

    【複数のファイルやディレクトリ】
    tar -cjvf archive.tar.bz2 /path/to/directory
    -c　新しいアーカイブを作成する
    -j　bzip2形式
    -v　処理したファイルを詳しく出力
    -f　アーカイブファイル名を指定
    ```
    <br>

3. xz
    * 概要：gzipやbzip2よりも高圧縮率
    * 圧縮率：gzipやbzip2よりも高いが、圧縮速度は非常に遅い
    * 速度：圧縮は遅いが、展開は非常に速い
    * 拡張子：.xz
    * 使用例：
    ```
    【圧縮】
    xz ファイル名
    元のファイルも自動的に削除される。
    -k　元のファイルを残して圧縮

    【展開】
    unxz ファイル名　または　xz -d ファイル名

    【複数のファイルやディレクトリ】
    tar -cJvf archive.tar.gz /path/to/directory
    -c　新しいアーカイブを作成する
    -J　xz形式
    -v　処理したファイルを詳しく出力
    -f　アーカイブファイル名を指定
    ```
    <br>
    
4. zip
    * 概要：複数のファイルやディレクトリを同時に圧縮できる
    * 圧縮率：gzipやbzip2よりも低いことが多いが、ファイル数が多い場合に便利
    * 速度：圧縮と展開の速度は比較的早い
    * 拡張子：.zip
    * 使用例：
    ```
    【圧縮】
    zip -r archive.zip /path/to/directory

    -r　サブディレクトリも含めて再帰的に圧縮する

    【展開】
    unzip ファイル名

    【複数のファイルやディレクトリ】
    tarコマンドを使わなくてもそのままできる
    ```
    <br>

## 圧縮ツールの比較②
一般的な傾向で並びかえ

* 圧縮率（高い順）
    .xz→.bzip2→.gzip→.zip
    <br>

* 圧縮速度（早い順）
    .zip→.gzip→.bzip2→.xz
    <br>

* tarコマンドでのオプションの違い
    .gzip　-z
    .bzip2　-j
    .xz　-J
    <br>
* そもそも「tarコマンド」について
    .tarファイルを作成するもの。
    オプションがなければ圧縮を行わずに、ファイルをまとめるために使用される。
    圧縮をしたいときに上記のオプションを使用して圧縮ツールを組み合わせて使用する。
    .zipファイルはファイルをまとめると同時に圧縮も行う形式なので、zipコマンドで作成する。
YouTubeライブの配信でやること にマサカリを投げる記事

## この記事の目的
YouTubeライブの配信でやること　③配信のセッティング・音声など 
URL:https://note.com/studiok_tokyo/n/n58fff355110d
この記事にマサカリを投げます。
あまりにも怪文書過ぎて笑ってしまうので一読したほうがいいです。

### お前誰よ
元スタジオエンジニア（システムインテグレーター）です。某放送局のスタジオなどを手掛けていました。また気まぐれでYoutube配信とかもやってます。

## 目次ごとにツッコミます。

### よんばち？よんよんいち？
>これは音声の映像に乗せるためのサンプルレートです。現在のCDなどはこのサンプルレートは48khzで高音質。Apple Musicのロスレス音源やハイレゾ音源にいたっては192khz以上。

ロスレス音源とハイレゾ音源の定義は違うものです。
ロスレス音源は **”mp3やAACなどの非可逆圧縮がされていない”** ことを指します。32KHz 8bitの音源でもWAVやFLACなどの形式であればロスレス音源ということができます。
あと、CDは48KHzではありません。 **44.1KHz** です。
また、ハイレゾ音源のサンプリング周波数は96KHz/24bit以上のデータレートがあれば名乗ることができます。
>だからロスレス音源はコンプレッサーを使って・・・とか言うと詳しい人に怒られそうだからやめておきます。ただ言えるのはロスレス音源は再現性が高いので・・・

詳しい人に怒られそう、と言っていますがすでに意味不明です。コンプレッサーとロスレス音源の直接的な関係性はありません。
めんどくさいのでAIでコンプレッサーの説明の文章を考えてもらいました。
```
コンプレッサーは、音声信号の音量を自動で調整する機器です。
音が大きくなりすぎる部分を抑え、小さい音を持ち上げることで、全体の音量バランスを整えます。
スレッショルドやレシオなどの設定で効果を調整でき、音楽制作や放送、録音など幅広い場面で使用されます。
例えば、ボーカルの音量が急に大きくなったり小さくなったりする場合に、コンプレッサーを使うことで滑らかな音質にすることができます。
```
つまり音声のダイナミックレンジを均一化する装置のことで、コップレッサーの使用の有無はロスレス音源の有無とは全く関係ありません。
ロスレス音源は再現性が高いのはまあその通りですかね・・・

>ライブ配信の映像は基本44.1khzです。いわゆるヨンヨンイチです。多分ビデオテープの音声規格の古のものはデジタルになった今でも残っています。

初期のビデオテープの音声規格はアナログです。44.1KHzとは何ら関係がありません。
44.1KHzの由来はソニーとフィリップスのデジタルレコーディングの仕様策定が起源になります。その後CDなどに同様のサンプリングレートが採用されています。

>もちろん４K・８Kやダイナミクスレンジの映像や5.1chなどは192khzでもいいと思います。でもライブ配信です。基本データは軽くやります。
ので44.1KHzがいいと思います。

ダイナミクスレンジの映像ってなんでしょうか？HDRのことを言ってるんでしょうか？
また4K・8K（つまりスーパーハイビジョン）は当初の仕様では48KHzのマルチチャンネルです。（ハイレゾもあとからやるって話だったのだがどうなったかは不明）
どちらにせよHDRや4K・8Kだからといって192KHzというわけでもないです。

また散々44.1KHzがいいと主張しておりますが、個人的見解からすると大抵の再生環境では48KHzが標準なのでリサンプルの必要がない48KHzにすることをおすすめします。

後述のビットレートの設定で44.1KHzでも48KHzでもデータ量は変わりません。

もうすでにお腹いっぱい感がありますが次いきましょう。

### 音声のビットレートは可聴域のようなもの。160bitもいらないです。
タイトルから意味不明です、160bitってなんでしょう？
160Kbpsですか？
>本来は32でもいいと思っていますが・・・これはおそらくソフトの下限値が作れなかったのかもしれません。ので64にします。トラックと音声レイヤーの関係がまだつかめてないので・・・不安だったらすべて64にします。
1bite＝6dbなのだが160bitとなると720dbなんて飛行機のエンジン並み・・・多分そんな意味合いではないと思いますが・・・そこまで大きくなくていいです。

この文章から見るに **ビットレートと量子化精度を混同している** のでしょう。
ビットレートは1秒間に使用される音声のデータ量です。OBSでは非可逆圧縮されたあとの数値です。
量子化精度は1サンプルあたりの精度です。通常は16bitや24bitを使用します。
ところで1biteってなんでしょうタイポ？

ちなみにAACに限らずビットレートは100Kbpsはないと十分な品質は得られません。標準設定の160Kbpsから変更する必要はありません。ビットレートを節約したいときは128Kbpsが下限です。

このスタジオでは64Kbpsが主流なんですね・・・
かなりスカスカな音声でしょうね・・・

### 録画は一緒にできるのでぜひやっておきましょう
>配信とともに録画もできます。これも高ビットレートになるとPCへの負荷が大きくなりますが・・・合成などの完成映像がアップするならここで録画は必須です。

録画・録音は高ビットレートになってもそれほど、PCの負荷は上がりません。PCの負荷に影響するのはOBSで言う **「CPU使用のプリセット」や「エンコーダーの選択」** です。高ビットレートになって辛くなるのはストレージ容量ぐらいでしょう。

>注意する点は・・・.mkvなどというわけのわからない拡張子がスタンダードセッティングになっているのでそこをMOV、もしくはmp4にしてください。
これで一回適用してOBSを再起動させます。

**mkvをしらない・・・だと・・・！？**
mkvが標準的なコンテナなのかという議論は置いておいて、mkvは大抵の動画編集ソフトで読み込めるはずです。
というか、コンテナとコーデックの関係も知ってるかどうか怪しいですねこのレベルだと・・・

### 配信のスケールとフレームレート
>サイズです。一般的には・・・
1920x1080　30fps/60fps
1280x720      60fps
が主流です。PALはヨーロッパなどの映像規格。日本にある稼働しているカメラの9割9分はNTSCなので60fpsがいいと思います。ドロップフレーム・ノンドロップフレームの話で59.94fpsなどもありますがこの話はそのうちします。

どこにPAL要素があった！？PALは **25FPS/50FPS** です。
30FPSをPALだと思ってるんでしょうか？この文章からではわからないですね・・・

## まとめ
いやー面白かったですね。
配信スタジオKの次回作にご期待ください！

## 謝罪
酔った勢いで書いてしまった、反省はしている。
010 AI屋さんの　gradioと200万トークン全文入力　追加学習済み　LLMの　gradioでWebアプリをクラウドデプロイ　実践編


AI屋さんの　gradioと200万トークン全文入力　追加学習済み　LLMの　gradioでWebアプリをクラウドデプロイ　実践編



大規模言語モデルの　プロンプトに
「吾輩は猫である」を全文入力した専門分野特化の
追加学習済みのＬＬＭを安価に共有する方法です。
完成ずみのwebapiを使って、
既にある、皆様のポータルサイトで呼び出したり
別途、独立サイトで運用したり　色々できます。



目次

https://qiita.com/bono0/items/dc1d000c98af7e07c9a7


今回は、学習済みLLMを　gradioでクラウドデプロイする
サンプルです。
簡単な　文字列入力の文字列出力の　gradioアプリです。
webAPIの呼び出しも、既知のコードのままです。
第一回参照

https://bono0-grd-ghc4uieygq-an.a.run.app



![スクリーンショット 2024-09-27 20.07.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/5e2e1f4d-2539-0b59-180a-af5353d9f7f3.png)



唯一の特記事項は、
外部からポートを利用するように
開放する点です。




![スクリーンショット 2024-09-27 19.07.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/723a093d-448a-057d-0a33-5d6aa890f4c7.png)




そして、gradioをdocker で実行する場合、
docker run でポートを開放して起動してあげます。
dockerfileの
pip install と python gradio.py　などコマンドを調整します。
ローカルでdockerのテスト実施。

okならば、クラウドのサーバーレスにデプロイです。
後は、コマンド一発

　gcloud run deploy

で完成です。
詳細は、streamlitのクラウドデプロイと同等です。第八回参照　

　gcpコマンド、
　docker コマンド、
　dockerfileの内容は、

下記リンク参照。


https://bono0-ghc4uieygq-an.a.run.app


![スクリーンショット 2024-09-27 20.13.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/7c019e53-a454-52ab-39f5-5e62bd35b3a8.png)



![スクリーンショット 2024-09-27 20.15.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/b8cfb765-93f1-156a-c7c0-b47195f040e9.png)





pythonのwebアプリ　streamlit も　gradio　も
dockerで　イメージに固めると
クラウドのサーバーレスと相性が抜群でした。
覚えることは、
　docker,streamlit,gradio,
　cloud run,
　html,css,app engine,gcp,flask,
　webapi,cloud functions,
　python,LLM
どれもサクッと済ませましょう。
さらに
　DB,sql,Nosql,CRUD,
　Mysql,PostgreSQL,sqlServer,MongoDB,ほか
　ストレージ,認証,
なども繋げて、AI屋さんならでは　
逐次動的　AIモデル更新システムも作れます。
ブログも作れます。
それ以外の事は、サーバーレスにお任せです。


google製のサーバーレスも　全制覇です。

　app engine
　　サーバーレスの基本型（アプリ毎）
　　万能flaskを使い倒そう、これ一つマスタすれば
　　flaskで　アプリもAPIも全部いける。
     
　cloud run
　　ドッカー使って安定型（ＯＳ毎）
　　dockerに固めたWebアプリをデプロイ
　　streamlit　も　gradioも　全部いける
   
　cloud functions
　　webapiの特化型（関数毎）
　　雛形に関数追記で、ブラウザ押しボタンで、クラウドデプロイはお任せ
　　追加学習ずみLLMをデプロイ！！

どれも、特徴があり適材適所で選べますし、
少し頑張ると、サーバーレスの利便性を享受できます。


今回も無事に
　AI屋さんの　gradioと200万トークン全文入力　追加学習済み　LLMの　gradioでWebアプリをクラウドデプロイ　実践編
完成です。おめでとうございます。




ー完ー
VSCodeでM5の開発環境構築する方法(超簡潔)

# 始めに
本記事では、VSCodeを使用しM5の開発環境を整える方法を発信いたします。

# 開発環境Setup Flow

1\. [Arduino IDE](https://www.arduino.cc/en/software)

2\. [PlatformIO](https://www.arduino.cc/en/software)

3\. [ドライバインストール](https://docs.m5stack.com/en/download)

# Arduino IDE
M5の基礎として使われているオープンソースハードウェアです。こちらを動かすために、Arduino IDE(オープンソースソフトウェアを公式URLより[ダウンロード](https://www.arduino.cc/en/software)します。

# PlatformIO

組み込み開発に特化した統合開発環境であり、開発を効率化してくれるVSCodeの拡張機能です。VSCodeの拡張機能欄からの検索してダウンロードします。
![スクリーンショット 2024-09-27 20.58.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3814349/df14f61a-f600-26f4-e44b-37c65841aaaa.png)

# ドライバインストール

M5Stack公式より提供されているドライバをインストールし、PCにM5を認識してもらいます。[公式サイト](https://docs.m5stack.com/en/download)より該当するドライバをインストールしてください。
(CH9102ドライバの中より選ぶことを推奨します。)
![スクリーンショット 2024-09-27 21.06.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3814349/577adab6-9ba2-2de5-97d7-6c113efd0dbd.png)

## PlatformIOで新しいプロジェクトを作成する手順

1. **PlatformIOアイコンをクリック**  
   VSCodeの左側にあるサイドバーに、PlatformIOのアイコン（アリのアイコン）が表示されているので、これをクリックします。

2. **Quick Accessトグルを開く**  
   PlatformIOのメニューが表示されるので、その中にある「Quick Access」の項目をクリックします。

3. **New Projectを選択**  
   「Quick Access」メニュー内にある「Open」をクリックし、次に「New Project」を選択します。

4. **プロジェクトの設定**  
   「New Project」ウィザードが表示されるので、以下の項目を入力します:
   - **Project Name**: プロジェクト名を入力します。
   - **Board**: 使用するボード（例: Arduino, ESP32など）の種類を選択します。
   - **Framework**: 開発するフレームワークを選択します（例: Arduino、ESP-IDFなど）。

5. **プロジェクトの作成**  
   設定が完了したら、「Finish」ボタンを押します。これにより、指定したディレクトリ（デフォルトでは `/Documents/PlatformIO` フォルダ内）にプロジェクト用のフォルダが自動的に作成されます。
![PIO.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3814349/7493e2cd-2c1c-fc40-9c08-f9c0152f09d1.png)
Scratch ライブラリ（カルーセル・セレクタ/縦）

# Scratch ライブラリ（カルーセル・セレクタ/縦）

[横版](https://qiita.com/Kray-G/items/8a82fada4eb6912c270a) に引き続き、縦版のグルグル回るカルーセル方式のセレクタです。こちらもコスチュームを用意するだけで自動的に色々ケアしてくれる、ノーコード方式です。

# カルーセル・セレクタ/縦

## プロジェクト

ここです。

https://scratch.mit.edu/projects/1067092584/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579271/94e4e76a-c04f-b651-4ae1-46bcd2ee90ac.png)

## ライブラリ概要

コスチュームを決まった命名ルールに従って用意するだけで、以下の事をしてくれます。

> [横版](https://qiita.com/Kray-G/items/8a82fada4eb6912c270a)と同じです。

* パラメータ数やパラメータごとの項目数を自動判別、自動レイアウト
* アニメーションの自動判別、自動アニメーション

最終的な選択番号は、**「Settings Parameter Values」** という名のリストに格納されるため、それを参照して選択された項目に従った動作をさせる、というのが基本的な利用方法です。

## 使い方

### 基本

以下の命名ルールに従ってコスチュームを用意します。

1. パラメータ名は **1-T** のような名前にする必要があります。 1 はパラメータ ID 番号を意味し、T はタイトルを意味します。パラメータID番号は、パラメータが複数ある場合にパラメータを区別するために使用されます。

2. 項目には、パラメータ ID 1 に対して **1-1**、**1-2**、...、**1-n** のような名前を付ける必要があります。項目に 6 つの選択肢がある場合、n は 6 になります。 2 番目のパラメータに対してパラメーター ID は 2 となり、ID 2 のオプションは **2-1**、**2-2**、...、**2-m** となります。 m はパラメータ ID 2 のオプションの数を意味します。この場合、n は m と異なっていても構いません。

3. オプションでアニメーションさせたい場合は、**1-1-0** などの名前でコスチュームを用意します。アニメーションはコスチューム名 0～7 で行われますが、この個数は固定（8 個）です。例えばID/オプションが 1-1 のアニメを作りたい場合、**1-1-0** から **1-1-7** までの計 8 つのコスチュームを用意する必要があります。

以下のプロジェクト（再掲）内の実際のコスチュームを参照すると、より理解が深まるでしょう。

https://scratch.mit.edu/projects/1067092584/

## 各種情報

### 変数・リスト
> In: 他スプライト管理の値を参照／Out: 本スプライトで設定

| リスト名 | In/Out |        概要        |
| ------ | :----: | ------------------ |
| `Settings Parameter Values` | Out | パラメータごとの選択項目番号 |

### イベント

特になし。

### コスチューム

パラメータ名や項目のコスチュームを用意すること。

## 拡張ポイント

特になし。

---

Burning Heart というシューティング（これは別途...）の設定変更画面で使ってます。が、ちょっと修正しています。最後の確認画面は削除して、タイトル画面と行ったり来たりできるようにしています。

https://scratch.mit.edu/projects/1062238584/

そんな感じで状況に合わせて修正して使うのもアリです。

---

> [Scratch ライブラリと Scratch Tips 目次へ戻る](https://qiita.com/Kray-G/items/e1900d5b6c6dcfbe5321/)
【AtCoder】islower関数, isupper関数の注意点

`islower()`, `isupper()` の戻り値はint型である（bool型ではないので注意）

```C++
int main() {
  cout << isupper('A') << endl; // -> 256
  
  // isupper を問題なく使えるケース
  if (isupper('A')) cout << "true" << endl; // -> true
  else cout << "false" << endl;
  
  // isupper を使うと想定外の挙動をするケース
  if (isupper('A') == true) cout << "true" << endl; // -> false
  else cout << "false" << endl;
}

```
SourcetreeでXserverの本番環境にプッシュしようして失敗した時の備忘録

### 結論　ssh-add [秘密鍵のパス] を実行
先に結論から言ってしまうと、ローカル環境で以下のコマンドを実行すれば解決できました。
```
ssh-add [秘密鍵のパス]
```

### 元々できていた本番環境へのpushができなくなる

Sourcetreeから本番環境であるxserverへ、ローカルの変更内容をプッシュしようとしていたところでした。
元々は問題無くできていたのが突然できなくなり、以下のエラーが表示されるようになりました。

```
Pushing to ssh://XXXX.xserver.jp:10022/home/XXXX/git/example.git
XXXX@XXXX.xserver.jp: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
fatal: Could not read from remote repository.
```

### SSH接続の際に公開鍵認証に失敗し、アクセス拒否される

エラーの内容を読んでみると公開鍵認証に失敗し、アクセス拒否されているようでした。
しかし、公開鍵と秘密鍵は作成済みで、ターミナルからxserverへのログインは問題無く行えました。

### ssh-add [秘密鍵のパス] で解決

どうやらssh接続して作業するには秘密鍵をssh-agentに登録する必要があるようでした。
なので登録のコマンド
```
ssh-add [秘密鍵のパス]
```
を実行する必要があったようです。

### 最後に
ターミナルから本番環境のサーバーにアクセスできるのに、gitを本番環境にプッシュできなかった時の対処法でした。
似たような場面で困っている方のお役に立てれば幸いです。
HTTPS通信とサーバー証明書について

## 目的
HTTPSとHTTPの違いが、暗号化されるかどうかくらいしか理解していなかったのでHTTPS通信について調べてみた。汗
<br>
一部表現が曖昧になっている箇所もあリますがご容赦ください。
間違いを見つけた場合は是非コメントお願いいたします。

## 対象者
* サーバー、クライアント、プロトコル、リクエスト、レスポンスの意味が理解できること
* 公開鍵暗号方式（公開鍵で暗号化したものは、秘密鍵で復号する。秘密鍵で暗号化したものは、公開鍵で復号する仕組み）を理解していること
* 共通鍵暗号方式を理解していること


## HTTPSとは（端的に）
* サーバーとクライアント間の通信を暗号化してやりとりするためのプロトコル
* 通信を暗号化することで、悪質なハッカーに傍受されても暗号文なので解読できない状態にできる
* HTTPS通信をするためには、サーバー証明書（後述）が必要になる [^1] 


## HTTPS通信で起きる暗号化の流れを具体的に
1. クライアントからサーバーに、HTTPSリクエストが行われる
1. サーバーからクライアントに、サーバー証明書（後述）を返却する
1. サーバー証明書を受け取ったクライアントは、サーバー証明書が妥当なものであるか検証（詳細は後述） 。検証の結果問題なければ、次に進む
1. クライアントが、共通鍵の元となる乱数を生成し、これをサーバー証明書の公開鍵を使って暗号化し、サーバーに送る
1. サーバーは、送られてきた暗号化された乱数を秘密鍵を使って復号し、これを元に共通鍵を作成。クライアント側も同じアルゴリズムで共通鍵を作成
1. サーバー側、クライアント側でそれぞれ生成された共通鍵を用いて暗号・復号をすることで、暗号化通信（HTTPS通信）をする


##  サーバー証明書とは
* サーバーがドメインに対して本物であることを証明する証明書
* サーバーが作成するが、自分自身だけで「本物だ！！」と言い張っても信用に値しないので、CA（認証局）からサーバー証明書に署名をもらうことで機能するようになる
* 署名は、CAの秘密鍵を使って暗号化されている
* HTTPS通信には必須


## ルート証明書とは
* サーバー証明書を検証するために必要なもので、CAの公開鍵が含まれている
* あらかじめ、クライアント(PCやスマホ)にインストールされている
* こちらもCA（認証局）から配布されている


## クライアントで行う「サーバー証明書の検証」とは

クライアントには、事前にCAから配布された「ルート証明書」がインストールされている。
ルート証明書にはCAの公開鍵が含まれている。

そしてサーバー証明書には、CAが本物のサーバーと認めた署名が含まれている。
この署名は、CAの秘密鍵を使って暗号化されている。

サーバーから受け取ったサーバー証明書を、クライアントでCAの公開鍵を使って復号することで署名が改竄されていないか検証することができる。





## 参考
かなり参考にしました。ありがとうございます。
[HTTPS(SSL/TLS)図解で分かる！](https://www.youtube.com/watch?v=nH70Ph3RxZg)


[^1]:ちなみにHTTPS通信で使用する暗号化する仕組みをSSL/TSLという
【学習メモ】Railsの「""」と「''」の違い


## Rails（Ruby）で使う`""`（ダブルクォート）と`''`（シングルクォート）の違い

ChatGPTに聞いた内容と検索した内容を統合してメモします。


### ダブルクォート `""`

変数や特殊な文字（改行など）を文字列の中に埋め込むことができる

#### 例1: 変数の埋め込み

```ruby
name = "ねこ"
greeting = "こんにちは、#{name}さん"
puts greeting  # => こんにちは、ねこさん
```



#### 例2: 特殊文字の使用

```ruby
message = "こんにちは\nさようなら"
puts message
# => こんにちは
#    さようなら
```



### シングルクォート `''`

文字列の中に書かれたものがそのままの形で扱われる
※式展開時に動的な値が入ると困る場合、シングルクウォートを使用すると良い

#### 例1: 変数の埋め込みができない

```ruby
name = '太郎'
greeting = 'こんにちは、#{name}さん！'
puts greeting  # => こんにちは、#{name}さん！
```



#### 例2: 特殊文字がそのまま表示される

```ruby
message = 'こんにちは\nさようなら'
puts message
# => こんにちは\nさようなら
```


参考：

https://zenn.dev/yukito0616/articles/6d7c65aed02920

https://tyoshikawa1106.hatenablog.com/entry/2015/07/16/223031
streamlitをAzure App Serviceにデプロイしたら失敗した。その原因は

# VS Codeでデプロイ
AzureのApp ServiceにWebアプリを作成し、VS CodeでAzureにつなげて、デプロイをしました(Azure拡張機能使用)。
アプリケーションはstreamlitを使ったpythonでした。特に複雑なコードもなく、まずは簡単なものを・・・と思っていたのですが。

# デプロイに失敗...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956246/85b2cdbf-9582-de45-f243-9e4246901e7a.png)
ログを見てみるとこんなことが書いてありました。
> ERROR: Could not find a version that satisfies the requirement pywin32==306 (from versions: none)
ERROR: No matching distribution found for pywin32==306

なにこれ？と思って調べてみると、このエラーは、pywin32パッケージがWindows専用であるため、Linux環境（Azure App ServiceはLinuxベース）ではインストールできないとのこと。

https://discuss.streamlit.io/t/error-could-not-find-a-version-that-satisfies-the-requirement-pywin32/15343

# requirements.txtの修正
pywin32を条件付きでインストールするように設定します。
```
pywin32==306; sys_platform == 'win32'
```
これでWindows環境でのみpywin32がインストールされるようになります。

# 再度デプロイ
requirements.txtを修正してもう一度デプロイしたところ、うまく動くようになりました。
ログはやっぱりちゃんと見ないといけないですね💦
ポケモンで学ぶデータサイエンス データ正規化編

# 前書き
さて、皆さんポケモンはご存じでしょうか
ポケットモンスターは現在700以上たくさんの種類のポケモンが存在し、
それぞれのポケモンが個性を持ったとても面白い作品です

アニメ、映画などだけではなく、ゲームとしても人気の作品です
ポケモンそれぞれに様々な特徴が与えられ、日々ポケモンバトルが繰り広げられています。
トレーナーが自分の好きなポケモンや強いポケモンを使い、最強のポケモントレーナーになるのが最近の主流となっています。

ゲーム上のポケモンのデータを使用し、データ分析を行います

# データ分析の手順

1. **目的の設定**:
   - 分析の目的を明確にします。何を知りたいのか、どのような問題を解決したいのかを定義します。

2. **データ収集**:
   - 必要なデータを集めます。データベース、ウェブスクレイピング、アンケートなど、さまざまな方法でデータを収集します

3. **データの前処理**:
   - データのクリーニング（欠損値の処理、異常値の除去など）を行います。また、必要に応じてデータの変換や標準化も行います

4. **データの探索**:
   - データの基本的な統計量を計算し、分布や相関関係を確認します。可視化ツールを使ってデータのパターンやトレンドを見つけます

5. **モデルの選択と構築**:
   - 分析の目的に応じて適切なモデルを選びます。例えば、回帰分析、分類、クラスタリングなどがあります。選んだモデルを使ってデータを分析します

6. **モデルの評価**:
   - モデルの性能を評価します。精度、再現率、F値などの評価指標を使ってモデルの有効性を確認します

7. **結果の解釈と報告**:
   - 分析結果を解釈し、目的に対する洞察を得ます。結果を分かりやすく報告書やプレゼンテーションにまとめます

8. **意思決定とアクション**:
   - 分析結果に基づいて意思決定を行い、具体的なアクションを取ります


# 1.目的設定
今回は、「ポケモンを自分の会社の従業員と考えて、優秀な人材を見つけること」とします

# 2. **データ収集**:
以下のサイトから引用させていただきました
ポケモンSVまでのポケモン合計902種類存在しま。（アローラの種類などもあり）
https://rikapoke.hatenablog.jp/entry/pokemon_datasheet_gne7
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3296700/cbcb2903-e580-5da2-c9d3-b84ec67dc0be.png)

# 3. **データの前処理3-1　データクリーニング**
このCSVファイルを加工する際にどのような点が気になりましたか。
今回のデータは**正規化**されていない状態です
・**図鑑番号が統一されていない**
・**一つのポケモンにタイプが2つ存在していることがある**
・**ポケモンは通常一つしか特性を持っていないが、複数の特性が付与されている**
今回はRDB(リレーショナルデータベース）にデータを格納したいため、
このデータを第三正規化していきたいと思います

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3296700/6a1b6a7f-60f5-a758-1e8b-36c1e2d458dc.png)
<font color="red">赤色</font>：IDが非統一化
<font color="blue">青色</font>：NULLの状態
<font color="green">緑色</font>:特性の重複



 **1.図鑑番号の削除、PokemonIdの追加**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3296700/3edd98a6-1ace-fb76-4a8b-71a2a2f35d80.png)



 **2.タイプテーブルの作成** 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3296700/f08b077d-48ac-52cd-8288-b60ccd4d82be.png)


 **3.特性テーブルの作成** 
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3296700/dfe65e6f-e641-cb25-7db3-0069f2286f24.png)
 

 **4.通常特性ID1,2,夢特性IDの作成**
 正規化完了
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3296700/d3471418-186e-ee45-edcd-c363b04774ef.png)
 
 **データのクリーニングは簡単そうに見えるが、意外とミスの原因となる**

 - 置換を多用することによって、元データが改ざんされてしまうこと
- データに半角スペースの混在により、VLOOKUP関数などがうまく作用しない

**感想**
 今回の簡単なクリーニングですらも、1時間ほどかかってしまった。
 現在は、練習もかねて、スクラッチでやっているが、AIなどを使うともっと効率が良いのかもしれない。
仮想スレッドのスレッドダンプ採取方法

# 仮想スレッドのスレッドダンプ採取方法

JDK21で仮想スレッドが導入されました。
この仮想スレッドのスレッドダンプを採取するには jcmd の  Thread.dump_to_file コマンドを使用します。
Thread.dump_to_file コマンドは以下の形式で指定します。
```
jcmd <プロセスID> Thread.dump_to_file [-overwrite] [-format={text,json}]  <ファイルパス> 
```

オプション -overwrite は出力ファイルを上書きします。
このオプションをつけない場合、出力ファイルが存在するとエラーになります。
オプション -format は出力形式をテキスト形式(text)、またはJSON形式(json)にします。デフォルトは text です。

従来のスレッドダンプ採取方法である kill -QUIT や jcmd <pid> Thread.print では採取できません。スレッドダンプは出力されますが、仮想スレッドに関する情報は出力されません。

## 出力例
テキスト形式での出力例(抜粋)
```
orange >> jcmd 4442  Thread.dump_to_file -format=text -overwrite thread.log
4442:
Created /root/thread.log
orange >> more thread.log
....
#18 "" virtual
      java.base/java.lang.VirtualThread.parkNanos(VirtualThread.java:640)
      java.base/java.lang.VirtualThread.sleepNanos(VirtualThread.java:817)
.....
#29 "" virtual
      java.base/java.lang.VirtualThread.parkNanos(VirtualThread.java:640)
      java.base/java.lang.VirtualThread.sleepNanos(VirtualThread.java:817)
.....
```
JSON形式での出力例(抜粋)
```
orange >> jcmd 4504  Thread.dump_to_file -format=json -overwrite thread2.log
4504:
Created /root/thread2.log
orange >> more thread2.log
.....
      {
        "container": "java.util.concurrent.ThreadPerTaskExecutor@521b83de",
        "parent": "<root>",
        "owner": null,
        "threads": [
         {
           "tid": "18",
           "name": "",
           "stack": [
              "java.base\/java.lang.VirtualThread.parkNanos(VirtualThread.java:640)",
              "java.base\/java.lang.VirtualThread.sleepNanos(VirtualThread.java:817)",
              "java.base\/java.lang.Thread.sleepNanos(Thread.java:494)",
              "java.base\/java.lang.Thread.sleep(Thread.java:527)",
              "vthread7.lambda$main$0(vthread7.java:12)",
              "java.base\/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)",
              "java.base\/java.util.concurrent.FutureTask.run(FutureTask.java:317)",
              "java.base\/java.lang.VirtualThread.run(VirtualThread.java:329)"
           ]
         },
         {
           "tid": "20",
           "name": "",
           "stack": [
              "java.base\/java.lang.VirtualThread.parkNanos(VirtualThread.java:640)",
              "java.base\/java.lang.VirtualThread.sleepNanos(VirtualThread.java:817)",
....
```
openjdk version "23" で確認

## 参考
JEP 444: Virtual Threads  https://openjdk.org/jeps/444
jcmdコマンド https://docs.oracle.com/javase/jp/22/docs/specs/man/jcmd.html
Next.jsとSupabaseの個人開発スタートアップ

## 記事の趣旨

自分が個人開発するときの備忘録

## 1. プロジェクトの初期化

```
npx create-next-app . --eslint --app
```

## 2. githubにリポジトリ追加

1. githubでリポジトリ作成
2. 以下のコマンド実行

```
git init
git add .
git commit -m "initial commit"
git remote add origin git@github.com:hoge/fuga-project.git
git push -u origin master
```

## 3. error, loading, not-found ページの作成

該当の`app/***.tsx`ファイルの作成

## 4. Supabaseの設定

1. Supabaseでプロジェクトの作成
2. 初期設定
    1. `.env.local`ファイルの作成
        1. Project Settings > API (`https://supabase.com/dashboard/project/<project_id>/settings/api`)に遷移
    2. `NEXT_PUBLIC_SUPABASE_URL`と`NEXT_PUBLIC_SUPABASE_ANON_KEY`を追加
  2. `npx supabase login`
  3. `npx supabase init`
      1. `supabase/`ディレクトリに`.gitignore`, `config.toml`, `seed.sql`ファイルが作成される
3. ローカル用の設定
    1. `npx supabase link --project-ref <Reference ID>`
        1. Project Settings > General
4. CI/CD (github action)用の設定
    1. github secrets(リポジトリ > Settings > Secrets and variables > ActionsN)に遷移
    2. `SUPABASE_ACCESS_TOKEN`, `SUPABASE_REFERENCE_ID`, `SUPABASE_DB_PASSWORD`を追加
        1. `SUPABASE_ACCESS_TOKEN`: Dashboard(Home) > Access Tokens
    3. `.github/workflows/supabase-migrate.yml`にファイルを追加
5. ライブラリのインストール
    1. `npm i @supabase/ssr @supabase/supabase-js`
    2. `utils/supabase/`に`client.ts`と`server.ts`ファイルを追加する
5. Testファイルの追加
    1. `npx supabase migration new <migration name>`

## 5. Vercelのデプロイ

1. `.env.local`にある環境変数を"Environment Variables"に追加したうえでdeployする

## 6. ESLintの設定

1. `npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin`
2. `.eslintrc.json`の設定 <- いずれESLint v9用に移行する

## 7. Prettierの設定

```
npm install --save-dev --save-exact prettier
node --eval "fs.writeFileSync('.prettierrc','{}\n')"
node --eval "fs.writeFileSync('.prettierignore','# Ignore artifacts:\nbuild\ncoverage\n')"
npx prettier . --write
```

## 8. faviconの設定

1. [Favicon Generator for perfect icons on all browsers | RealFaviconGenerator](https://realfavicongenerator.net/)でsvgファイルをinputして、favicon packageをダウンロードする
2. `app/`配下に`favicon.ico`、`icon.svg`、`apple-icon.png`をペーストする(必要に応じてファイル名を変える)
【備忘録】Udemy講座まとめ JavaScript vol.2

# オブジェクトという型

```JavaScript:JavaScript
const coffee = {
  name: 'late',
  size:350,
  isHot:true,
  toppings:['Cinnamon','Caramel'],
  nut:{
    calories: 430,
    sugars: 53,
  }
};

console.log(coffee.toppings[0]);
```
オブジェクトは、関数名 = {}で囲み、〇〇: 〇〇,が基本の型でデータを格納していく。
オブジェクトの中に、更に{}で囲う事も可能。


# 関数の宣言の仕方
```JavaScript:JavaScript
function add(){}
```
関数を宣言するには
function 関数名(){}
が基本の型になる。


# 関数の呼び出し方
```JavaScript:JavaScript
function add(){
  console.log(1 + 1);
}
add();
```
関数を実行するには、指示するだけではダメで
関数名();
が必要


# パラメーターと引数
```JavaScript:JavaScript
function add(num1,num2){
  console.log(num1 + num2);
}
add(3, 3);
```
コンソールには、6が出力される

add(num1,num2)で、パラメーター（受け口）を宣言

値を入れる時は、関数を呼び出す時

```JavaScript:JavaScript
function add(num1,num2){
  console.log(num1 + num2);
}
add(3, 3);

add(4, 3);

add(4, 5);
```
としたらコンソールには
6
7
9
が順に出力される。



# return文
```JavaScript:JavaScript
function add(num1,num2){
  return num1 + num2;
  console.log('hello');
}

console.log(add(2, 3));
```
この場合、コンソールにhelloは出力されない
return文にあたった時点で、その関数の処理が終わる
よくif文の条件分岐で使われる
【Python】挿入ソート

## 概要
挿入ソートは、効率的なソートアルゴリズムの一つで、小規模なデータセットや既にほぼ整列されているリストに対しては非常に効果的です。未ソートの部分から1つの要素を取り出し、適切な位置に挿入していくことで、リスト全体をソートします。
計算量は O(n^2) で、バブルソートや選択ソートと同等のパフォーマンスですが、ほぼ整列済みのリストに対しては高速です。

この記事では、Pythonでの挿入ソート実装方法について説明します。

## コード
以下がPythonでの挿入ソートの実装例です。

```python
def insertion_sort(arr):
    n = len(arr)
    # 1つ目の要素はすでにソート済みとして処理開始
    for i in range(1, n):
        key = arr[i]
        j = i - 1
        # keyがソート済み部分の適切な位置に入るまで移動
        while j >= 0 and arr[j] > key:
            arr[j + 1] = arr[j]
            j -= 1
        arr[j + 1] = key
    return arr

# サンプルの使用例
if __name__ == "__main__":
    sample_data = [12, 11, 13, 5, 6]
    print("ソート前:", sample_data)
    sorted_data = insertion_sort(sample_data)
    print("ソート後:", sorted_data)
```

### 実行結果
上記のコードを実行すると、次のような結果が得られます。

```
ソート前: [12, 11, 13, 5, 6]
ソート後: [5, 6, 11, 12, 13]
```

### 詳細
insertion_sort関数は、リストarrを入力として受け取り、挿入ソートの手法を使ってソートされたリストを返します。
外側のforループでは、リストの未ソート部分から1つの要素（key）を取り出し、それをソート済み部分の適切な位置に挿入します。
内側のwhileループでは、ソート済み部分の要素を順次比較し、keyより大きい要素を右にシフトさせることで、keyの挿入位置を確保します。

## 参考
https://www.udemy.com/course/python-algo/?couponCode=KEEPLEARNING
[VSCode] ファイルの最終更新をカレンダーで確認できる拡張機能のご紹介

# ファイルカレンダー拡張機能

## 概要
この拡張機能は、Visual Studio Code内でファイルの更新をカレンダー形式で表示するためのものです。更新されたファイルを視覚的に管理できるため、作業の効率が向上します。

https://marketplace.visualstudio.com/items?itemName=pab.file-update-calendar

## 特徴
- カレンダー形式でファイルの更新を表示
- 更新日時に基づいてファイルを整理
- 簡単にファイルを開くことが可能

## インストール方法
1. Visual Studio Code を開く
2. 拡張機能のマーケットプレイスから「File Update Calender」を検索し、インストールします

## 使用方法
1. コマンドパレットを開く（`Ctrl+Shift+P`）
2. `Show Calendar` を選択するとカレンダーが表示されます。
3. 更新されたファイルをクリックすると、そのファイルが開きます。

![スクリーンショット 2024-09-27 19.30.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862120/d4290067-ab11-d57c-9759-98faa81df3b7.png)

この拡張機能を使って、ファイルの更新管理を効率的に行いましょう！
MacにHomebrewをインストールしてGitもインストールしてGit設定するまで

# はじめに
新しいMacを購入すると、いろいろと設定を忘れてしまうので、改めて設定してそれを残します。

# やりたいこと
- SHELLの確認
- MacにHomebrewをインストールする
- Homebrewを使ってGitをインストールする
- GithubからCloneや、GithubにPushできるように設定する

# 環境
- Mac OS:14.6.1
- SHELL: Zsh

# SHELLの確認
一応確認する

    $ echo $SHELL
    /bin/zsh
    $ zsh --version
    zsh 5.9 (x86_64-apple-darwin23.0)

# MacにHomebrewをインストールする
[ここ](https://brew.sh/ja/)に書いてあるようにやる

    $ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    $ brew --version
    Homebrew 4.3.18
    $ (echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> /Users/(user)/.zprofile
    $ eval "$(/opt/homebrew/bin/brew shellenv)"


# Homebrewを使ってGitをインストールする
    
    $ brew install git
    $ git version
    git version 2.45.2

# GithubからCloneや、GithubにPushできるように設定する

公開鍵を作成し、githbuに登録

    $ mkdir .ssh
    $ cd .ssh
    # 公開鍵の作成
    $ ssh-keygen -t rsa
    $ cat id_rsa.pub
    # 公開鍵のコピー
    $ pbcopy < id_rsa.pub
    # githubに登録後、確認
    $ ssh -T github
    $ ssh -T git@github.com
Ubuntu 22.04 LTS で Symbol サーバーをビルド

Ubuntu 22.04 LTS で Symbol サーバー(catapult v1.0.3.7)をビルドします。

## 環境

- Ubuntu 22.04 LTS

## 必要なパッケージをインストール

ビルドに必要なコンパイラ等をインストールします。

```bash
sudo apt -y install git gcc g++ curl libssl-dev libgtest-dev ninja-build pkg-config python3-pip
```

```bash
pip install pyyaml
```

### CMake インストール

Ubuntu 22.04 の CMake のバージョンが古いので、新しいバージョンをインストールします。

署名鍵のコピー

```bash
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /usr/share/keyrings/kitware-archive-keyring.gpg >/dev/null
```

リポジトリの追加

```bash
echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ jammy main' | sudo tee /etc/apt/sources.list.d/kitware.list >/dev/null
```

パッケージ更新＆インストール

```bash
sudo apt update
sudo apt install cmake
```

## ソースをクローン

現在メインネットで動いているバージョンを取得します。  
ホームディレクトリにクローンしました。

```bash
git clone https://github.com/symbol/symbol.git -b client/catapult/v1.0.3.7
```

## 依存パッケージのビルド

Symbol サーバーをビルドするのに必要な依存パッケージをビルドするため、`symbol/client/catapult`に入ります。

```bash
cd symbol/client/catapult
```

下記コマンドでビルドします。  
ビルド中にエラー出たら解消して、再実行してください。再実行時は`--download`オプション不要です。

```bash
PYTHONPATH="../../jenkins/catapult/" \
 python3 "../../jenkins/catapult/installDepsLocal.py" \
 --target "./deps" \
 --versions "../../jenkins/catapult/versions.properties" \
 --build \
 --download
```

## Symbol サーバーをビルド

ビルド用のディレクトリを作って中に入る。

```bash
mkdir -p build && cd build
```

cmake します。時間が掛かるのでテスト無効にしてビルドする。ちなみに、`-DENABLE_TESTS=OFF`を削除すればテストしてビルドします。

```bash
BOOST_ROOT="$(realpath ../deps/boost)" cmake .. \
 -DENABLE_TESTS=OFF \
 -DCMAKE_BUILD_TYPE=RelWithDebInfo \
 -DCMAKE_PREFIX_PATH="$(realpath ../deps/facebook);$(realpath ../deps/google);$(realpath ../deps/mongodb);$(realpath ../deps/zeromq);$(realpath ../deps/openssl)" \
 -GNinja
```

publish します。これを忘れるとビルド最後の方でエラーが出ます。

```bash
ninja publish
```

ビルド開始。

```bash
ninja
```

エラーが出てやり直す場合は、キャッシュが残ってるので `build` ディレクトリ内を全て削除する。

## 動作確認

### ライブラリ移動

ライブラリが`bin`ディレクトリ内にあるので、`lib`ディレクトリにコピーします。

```bash
cp bin/*.so lib
```

### パスを通す

```bash
vi ~/.bashrc
```

以下を末行に追加。

```~/.bashrc
export LD_LIBRARY_PATH=~/symbol/client/catapult/deps/facebook/lib:~/symbol/client/catapult/deps/boost/lib
```

`.bashrc`を再読込。

```bash
source ~/.bashrc
```

### 実行

下記コマンドを実行してヘルプが表示されれば、ビルド成功です。

```bash
./bin/catapult.tools.address --help
```