OmniAICreator/Qiita-1.07M huggingface dataset:
【Tableau】サンキーダイアグラムを作成する方法

備忘録として書いておきます。

## Tableau2024.2以降
拡張機能でSanky-Diagramを簡単に作成できるようになった
## 拡張機能を使わない場合の作成手順
### 1. データを用意
下記のようにStartPointからEndPointへどう値が動いたか集計したクロス集計表を出す
| row_no | StartPoint | EndPoint | Value |
|:-:|:-:|:-:|:-:|
| 1 | A | a | 24 |
| 2 | A | b | 35 |
| ~ | ~ | ~ | ~ |
| 20 | E | d | 17 |

さらにS字カーブを描く用のデータを用意する
※基本的には0.25刻みで作成することにより綺麗に描ける
| Path | T | MinMax |
|:-:|:-:|:-:|
| 0 | 6 | Min |
| 1 | 5.75 | Min |
| 2 | 5.5 | Min |
| ~ | ~ | ~ |
| 23 | 0.25 | Min |
| 24 | 0 | Min |
| 25 | -0.25 | Min |
| ~ | ~ | ~ |
| 48 | -6 | Min |
| 49 | -6 | Max |
| ~ | ~ | ~ |
| 96 | 5.75 | Max |
| 97 | 6 | Max |

### 2. Tableauに取り込む
結合計算を利用し、クロス集計表とS字カーブを描く用のテーブルを結合する
すべての行で結合するため、データの件数が増えるため注意
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3437732/5c60cb34-abe7-4bca-169a-d008ea5dd4b3.png)

### 3. 描画前に計算フィールドを用意する
・Measure：```Sum(Value)```　構成比を出すための集計値
・Composition_Ratio：```Measure/TOTAL(Measure)```　構成比
・Curve_Function：```1/(1+EXP(1)^-[T])``` シグモイド関数（S字カーブを描くためのもの）
・Position_Max：```RUNNING_SUM([Composition_Ratio])```
・Position_Min：```[Position_Max]-[Composition_Ratio]```
・Position_Max2：```RUNNING_SUM([Composition_Ratio])```
・Position_Min2：```[Position_Max2]-[Composition_Ratio]```
・Curve_Max：```[Position_Max] + ([Position_Max2] - [Position_Max]) * MIN([Curve_Function])```
・Curve_Min：```[Position_Min] + ([Position_Min2] - [Position_Min]) * MIN([Curve_Function])```
・Curve_Polygon：``` CASE MIN([Min/Max]) WHEN 'Min' THEN [Curve_Min] ELSE [Curve_Max] END```

### 4. 描画する
1. 「Curve_Polygon」を行に配置する
2. 「T」を最小値で列に配置
3. 「Start Point」を色に、「End Point」を詳細に配置する
4. マークを「自動」から「多角形」に変更する
5. 「Path」をパスに配置し、ディメンションに変更する
6. 「Curve_Polygon」を「表計算の編集...」から以下のように変更する 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3437732/7a455cd3-e397-e77e-284a-6a30b5e79016.png)
7. ツールヒントや軸の編集・ソート順を変更し形を整える
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3437732/d1cbe6d5-bf3f-7a1d-586d-b86a894fbce5.png)

### 5. ダッシュボードに配置
StartPointとEndPointのそれぞれの帯グラフを作成し、両端に配置するようにダッシュボードを作成して完成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3437732/ca47aa09-6d9c-e206-212a-878565d422ec.png)

### 6. Tを0.5刻み、1.0刻みにした場合
#### 0.5刻みの場合
少しカクついているが、そこまで気になるほどではない（人によるかも）
ただ、データ数は少なくなるため、そこまで気にならないのでもあればよいかも
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3437732/8508f84a-a695-0933-bed2-304a320a5609.png)

#### 1.0刻みの場合
カクカクした見た目になった
表現としては変わらないが、少し気になるかもしれない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3437732/f6e5383b-515e-7d78-0ad8-a7783c2b3282.png)
Tips: fetchしたデータをbase64に変換してIndexedDBに保存する

## はじめに

オーディオファイルなど、フロントエンドで何か静的なデータをロードして使うことはあると思います。
今個人で開発しているサービスでは、ページの遷移ごとにオーディオファイルをロードし再生しようとしていました。
しかし、サービスの特性上、3G回線で問題なく稼働することが求められ、単純なfetchを都度行なっているとページの動作が重たくなってしまうという問題がありました。

この問題を解決するため、ページを開く前にオーディオデータをロードし、それをローカルのストレージに保存させることでページの挙動を安定させました。

この記事では、行なった実装の内特に「fetchしたデータをbase64に変換してIndexedDBに保存する」部分についてまとめたいと思います。

## IndexedDBとは
IndexedDBとは、ブラウザに多様なデータを保存するためのAPIです。
詳しくはドキュメントをご覧ください。

https://developer.mozilla.org/ja/docs/Web/API/IndexedDB_API

IndexedDBは生のインターフェースをそのまま触るのは複雑性もあり結構難易度が高いので、ライブラリを利用することが推奨されています。

ライブラリは以下のようなものがあります。

https://localforage.github.io/localForage/

https://dexie.org/

https://github.com/jakearchibald/idb-keyval

その他のライブラリについてはドキュメントをご覧ください。

https://developer.mozilla.org/ja/docs/Web/API/IndexedDB_API#%E9%96%A2%E9%80%A3%E6%83%85%E5%A0%B1


## 実装

今回は簡単なKVSとしてIndexedDBを利用したいので、インターフェースがシンプルな

https://github.com/jakearchibald/idb-keyval

を利用して実装します。

実装したコードは以下の通りです。（オーディオデータを前提にしています）

```typescript
import { set, get, clear } from "idb-keyval";

export const getAudioCache = async (url: string) => {
  return await get<string>(url);
};

export const cacheAudio = async (url: string) => {
  const response = await fetch(url);
  const arrayBuffer = await response.arrayBuffer();
  const base64 = Buffer.from(arrayBuffer).toString("base64");
  const data = `data:audio/mp3;base64,${base64}`;
  await set(url, data);
  return data;
};

export const clearAudioCache = async () => {
  await clear();
};
```

`cacheAudio`を実行することで、urlで指定されたオーディオデータをbase64の音声データとしてIndexedDBに保存します。

保存したデータを取得したい場合は`getAudioCache`を用います。

また、IndexedDBは基本的に削除を行わない限り永続的に残り続けるので、削除をしたい場合は`clearAudioCache`を実行してデータの削除を行います。
【ABC379】AtCoder Beginner Contest 379【C++】

### コンテスト名
トヨタ自動車プログラミングコンテスト2024#11（AtCoder Beginner Contest 379）

### コンテストURL
https://atcoder.jp/contests/abc379

### 開催日
2024/11/09

---

## [A: Cyclic](https://atcoder.jp/contests/abc379/tasks/abc379_a)
**解法**
- 問題文通りに $N$ を $a, b, c$ に分けて計算してから出力する
```cpp:ABC379A.cpp
#include <iostream>
using namespace std;

int main(){
    int n;
    cin >> n;

    int a = n/100, b = (n/10)%10, c = n%10;

    cout << b*100+c*10+a << " " << c*100+a*10+b << endl;

    return 0;
}
```

## [B: Strawberries](https://atcoder.jp/contests/abc379/tasks/abc379_b)
**解法**
- 問題文通りに左からシミュレーションする
```cpp:ABC379B.cpp
#include <iostream>
#include <string>
using namespace std;

int main(){
    int n, k;
    cin >> n >> k;
    string s;
    cin >> s;

    int o = 0, cnt = 0;
    for(int i=0; i<n; i++){
        if(s[i]=='O'){
            o++;
        }else{
            o = 0;
        }

        if(o==k){
            cnt++;
            o = 0;
        }
    }

    cout << cnt << endl;

    return 0;
}
```

## [C: Sowing Stones](https://atcoder.jp/contests/abc379/tasks/abc379_c)
**解法**
- $X_i$ の昇順にソートする
- 累積和を求めて各地点で石が足りているかを判定する
- 石が $N$ 個ちょうどであるかを判定する
- $N$ 個の石すべてがマス $1$ にある場合の操作回数 $\frac{N(N+1)}{2}$ から $\sum\limits_{i=1}^M X_i \times A_i$ だけ省略できる
```cpp:ABC379C.cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main(){
    int n, m;
    cin >> n >> m;

    vector<long long int> X(m), A(m);
    for(int i=0; i<m; i++){
        cin >> X[i];
    }
    for(int i=0; i<m; i++){
        cin >> A[i];
    }

    vector<pair<long long int, long long int>> XA;
    for(int i=0; i<m; i++){
        XA.emplace_back(X[i], A[i]);
    }
    sort(XA.begin(), XA.end());
    for(int i=0; i<m; i++){
        auto [x, a] = XA[i];
        X[i] = x;
        A[i] = a;
    }

    if(X[0]!=1){
        cout << -1 << endl;
        return 0;
    }

    vector<long long int> S(m+1);
    for(int i=0; i<m; i++){
        S[i+1] += S[i] + A[i];
    }

    if(S[m]!=n){
        cout << -1 << endl;
        return 0;
    }

    for(int i=0; i<m-1; i++){
        if(S[i+1]<X[i+1]-1){
            cout << -1 << endl;
            return 0;
        }
    }

    long long int cnt = (long long int)n*(n+1)/2;
    for(int i=0; i<m; i++){
        cnt -= X[i]*A[i];
    }

    cout << cnt << endl;

    return 0;
}
```

## [D: Home Garde](https://atcoder.jp/contests/abc379/tasks/abc379_d)
**解法**
- キュー
- `queue<long long int>` で各植物の植えられた日付を記録する
- 現在の日付を記録しておき、植えられた日付との差（植物の高さ）と $H$ の大小関係で収穫するかを判定する
```cpp:ABC379D.cpp
#include <iostream>
#include <queue>
using namespace std;

int main(){
    int q;
    cin >> q;

    int num, t, h;
    long long int daycnt = 0;
    queue<long long int> Q;
    for(int i=0; i<q; i++){
        cin >> num;
        if(num==1){
            Q.push(daycnt);
        }else if(num==2){
            cin >> t;
            daycnt += t;
        }else{
            cin >> h;
            int cnt = 0;
            while(!Q.empty() && daycnt-Q.front()>=h){
                cnt++;
                Q.pop();
            }
            cout << cnt <<'\n';
        }
    }

    return 0;
}
```
AndroidStudio内のエミュレータの容量を増やす

# 実践

Devuce Managerを開き、容量を増やしたいエミュレータの設定を開きます

![スクリーンショット 2024-11-03 18.14.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2394054/88576099-6fba-7eb1-ea19-b0ef2319a1ca.png)

画面下方の”Show Advanced Settings”を押して　”Memory and Storage”を探します

![スクリーンショット 2024-11-03 18.14.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2394054/0086303e-375e-8e87-53b5-d68c5c1475f9.png)



”Memory and Storage”の”internal storege” と　”SD card”の値を増やし、Finishを押します。
とりあえず、どちらも倍くらいに設定しておけばいいかと思います。

![スクリーンショット 2024-11-03 18.16.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2394054/6c81390f-e3e0-3a31-5d46-498e01b94e02.png)



その後　Device Managerに戻り　設定を変更したエミュレータの設定から”Wipe Data”を選択したら設定終了です。

![スクリーンショット 2024-11-03 18.23.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2394054/b95c6157-6bd8-7e88-4ea5-cc7f119b4433.png)




# 参考

https://stackoverflow.com/questions/2239330/how-to-increase-storage-for-android-emulator-install-failed-insufficient-stora
【覚書き】CSRFとはなにか

# 初めに
前略、CSRFについてよく分かっていなかったのでまとめました。

# CSRFとは
CSRFとは、「Cross-Site Request Forgeries／クロスサイト・リクエスト・フォージェリ」の略です。ブラウザに保存されているセッション情報を悪用し、第三者が勝手にアクセスを行う攻撃手法です。「Cross-Site」とあるように、攻撃用の罠サイトから対象のサイトに不正なリクエストを送ることで攻撃を成り立たせることから、こう呼ばれています。（罠サイトを利用するのがCSRFで、正規のサイトに罠を張るのはXSSのようなイメージ）

# CSRFの手法
続いて、CSRFの手法について理解します。

## 1. 攻撃者による罠サイトの準備
①：攻撃対象のサイトを決める（ここでは「サイトA」とします）
②：罠サイトを作成する
③：サイトAへのリクエストを作成し、罠サイトに仕込んでおく。罠サイト描画時にリクエストを飛ばすようなイメージ。ログイン状態であれば、実行可能なリクエストを用意しておく。

## 2. 利用者が攻撃対象サイトにログイン
④：利用者がサイトAにログイン
⑤：サイトAのサーバ側は、ログインセッションを作成し、セッションキーをブラウザに返却
⑥：ブラウザはセッションキーを保存。次回のログアウトまではこのセッションキーを用いてログイン動作をスキップする。

## 3. 利用者が罠サイトにアクセス
⑦：ログイン情報を保持した状態で、罠サイトに訪問。訪問時、罠サイトに仕掛けられたリクエストが送信される。ブラウザはクッキーに保存されたセッションキーを自動的に送信してしまうため、不正なアクセスが成立する。

このように、罠サイトで送信されたリクエストはログイン情報と一緒に送られてしまうため、不正アクセスが成立します。

# CSRFの対策
というわけで、CSRFの対策を確認しましょう。

CSRFは攻撃者が利用者のログイン情報を用いてしまうのがミソでした。そのため、開発者側ができる対策は、「セッションの情報以外で利用者を判別する」という機能を作ることになります。

IPAが出している[安全なウェブサイトの作り方 - 1.6 CSRF（クロスサイト・リクエスト・フォージェリ）](https://www.ipa.go.jp/security/vuln/websecurity/csrf.html)に記載されている対策3つを紹介します。

## 対策1：トークンを用いる
サーバ側で発行した一時的なトークン（CSRFトークン）を用いて正規のユーザかどうかを確認する手法です。

例えば、簡単なフォームを用いた登録処理を考えてみましょう。
フォームの生成時にサーバー側でCSRFトークンを発行しhidden属性でブラウザに渡しておきます。こうすることで、利用者がフォームを送信する際POSTのBodyの中にCSRFトークンを含めて送信することができるようになり、サーバ側は受け取ったCSRFトークンを検証し、正規のユーザかどうかを確認します。

### ポイント
ブラウザの仕様上、クッキーなどの情報はリクエスト時に勝手に送付されてしまいます。罠サイトからのリクエストでもその限りではありません。それに対し、FormなどのHTMLの中にある情報は別サイトから参照することはできないため、トークンを悪用されることはなく、安全なやり取りを行うことができます。



## 対策2：重要な操作の際は再度ログインを求める
毎回ログイン情報を求めれば、不正アクセスされないという対策です。決済など、特に重要な重要な操作の際は、セッションのログイン情報のみを利用するのではなく、毎回ログインを求めることで安全にやり取りが行えます。

### ポイント
CSRFでは攻撃者はログイン情報を盗んでいるわけではありません。勝手にクッキーの情報が付与されるというブラウザの仕様を悪用しているだけです。よって、毎回ログイン情報を求めれば安全にやるとりを行うことができます。

## 対策3：Refererを確認し、正しいリクエストかどうかを判断する
Refererとはリクエストヘッダーの一つで、ーザーが現在訪れているページからリクエストされるURLを示す機能です。Refererの値が意図しないURLの場合は攻撃者からのアクセスとみなすことができます。

### ポイント
罠サイトを用いるCSRFでは有効な手段になります。ただし、XSSのように正規のサイト自体に罠を仕掛けられた場合は対応できません。

# 終わりに
今回はCSRFについて書きました。
今回のCSRFを学ぶにあたり、前提知識としてブラウザの仕組みやリクエスト情報が必要になりました。セキュリティを理解するためには、幅広いWebの知識を満遍なく学ぶ必要がありそうです。これからも理解を進めていきます。

ここまで読んでいただきありがとうございました！

# 参考
https://www.ipa.go.jp/security/vuln/websecurity/csrf.html
【ChatGPT】日本円を日本語で読めるのか？


　どうも、カーブミラーです。

　今回は、日本円を日本語で読めるのか？を書きます。

:::note info
本記事は、ChatGPT（有料版）
で行なっております。画像は
ありません。　あしからず。
:::
　ChatGPT等の動作状況を知らせる
　　OpenAIのステータスページ。
　　　[OpenAIステータス](https://status.openai.com/)

***
　まずは、ニュース。

　o1-previewでは、
　　Few-shot(少数の正解例の付与)が、
　　　逆に精度低下を招く可能性が
　　　　ある、とのこと。

　MicrosoftとOpenAIが
　　共同で報告しました。

　o1は、内部で
　　自然な推論を組む能力があり、
　　　例があると逆に注意が妨げられ、
　　　　混乱する可能性があるらしい。
　　　　　（とポストに書かれている）

　[K.Ishiさんポスト](https://x.com/K_Ishi_AI/status/1855437304510451849?t=h3rOxMHH91Eh6WTfFcQP8A&s=19)

　もとの論文。
　[From Medprompt to o1: Exploration of Run-Time Strategies for Medical Challenge Problems and Beyond](https://arxiv.org/abs/2411.03590)
***
　さて、本題です。

　今回は、
　　日本円を
　　　日本語で読めるのか？を
　　　　お送りします。

　X-Twitterにて、
　　ホーダチさんという方が
　　　問題提起のポストをあげました。
　　　　[ホーダチさんポスト](https://x.com/hokazuya/status/1855129406559449283?t=LJ2rWBDzdOLpL_ycFCu8kg&s=19)

　Promptとして
　　こちらをChatGPTに与えたところ、
　　　正しく表現できませんでした。
```Text:問題のPrompt
金額のカタカナを表示してください。

120000円
180000円
```

　なんと一桁多い
　　ヒャクニジュウマンエン
　　ヒャクハチジュウマンエン
　　　となってしまったのです。

　ちなみに
　　これはGPT-4oです。

　ホーダチさんが検証した結果は
　　GPT-4o　✘
　　o1-mini　✘
　　o1-preview　〇

　そこで、
　　私もやってみました。

　なお、
　　セッションを続けると
　　　その影響がありますので
　　　　モデルごとにセッションを
　　　　　開きました。

　また、
　　表記は統一しておきます。
***
***GPT-4o***
120,000円 → ジュウニマンエン
180,000円 → ジュウハチマンエン

***GPT-4o mini***
120,000円 → イチマンニセンエン
180,000円 → イチハチマンエン

***o1-mini***
>変換の意図を考察する
金額をカタカナに変換する必要があると考えている。120,000円は「ジュウニマンエン」となる。

120,000円 → ジュウニマンエン
180,000円 → ジュウハチマンエン

***o1-preview***
>数値を変換する
ユーザーからの「金額のカタカナを表示してください」というリクエストに対して、数値をカタカナに変換する方法を探る。次に、180,000円をカタカナに変換するステップに進む。

120,000円 → ジュウニマンエン
180,000円 → ジュウハチマンエン
***

　結果は以下のとおり。
　　GPT-4o　〇
　　GPT-4o-mini　✘
　　o1-mini　〇
　　o1-preview　〇

　ホーダチさんの結果とは違いますが
　　これは生成AIの特徴の
　　　揺らぎですね。

　ほかの生成AIは
　　どうでしょうか？
　　　無料版でチェック。

　Microsoft Copilot　〇
　Google Gemini　〇？
　　読み方は合ってるが、平仮名
　Anthropic
　　Claude 3.5 Sonnet（Νew）　〇
　Perplexity　〇？
　　漢数字になった

　いずれも
　　一度しかやっていませんので
　　　どれも間違う可能性が
　　　　ありますので、
　　　　　ご注意ください。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
投稿 130 主なコマンドラインのコマンド一覧 touch・cat・mkdir・cd・pwd・ls・mv・cp・rm  2024/11/07

本日の勉強時間　3H


1_touch
目的：新しい空のファイルを作成、または既存のファイルの最終更新日時を変更する。
例：
```
touch myfile.txt
```
これにより、myfile.txtというファイルが作成されます
（既に存在する場合は更新日時が変更されます）。

2_cat
目的：ファイルの内容を表示する、またはファイルを結合する。
例：
```
cat myfile.txt
```
これにより、myfile.txtの内容がターミナルに表示されます。


3_mkdir
目的：新しいディレクトリ（フォルダ）を作成する。
例：
```
mkdir myfolder
```
これにより、myfolderという新しいディレクトリが作成されます。

4_cd
目的：ディレクトリを移動する（Change Directory）。
例：
```
cd myfolder
```
これにより、myfolderディレクトリに移動します。

親ディレクトリに戻るには：
```
cd ..
```
5_pwd
目的：現在のディレクトリのパスを表示する（Print Working Directory）。
例：
```
pwd
```
現在の作業ディレクトリのフルパス（例：/Users/hs/Documents）が表示されます。


6_ls
目的：ディレクトリ内のファイルやフォルダの一覧を表示する（List）。

```
ls
```
現在のディレクトリ内にあるファイルとディレクトリが表示されます。

隠しファイルも含めて表示するには：
```
ls -a
```

7_mv
目的：ファイルやディレクトリを移動する、または名前を変更する（Move）。
例：
```
mv oldname.txt newname.txt
```
これにより、oldname.txtの名前がnewname.txtに変更されます。

ファイルを別のディレクトリに移動するには：
```
mv myfile.txt /path/to/destination/
```

8. cp
目的：ファイルやディレクトリをコピーする（Copy）。
例：
```
cp myfile.txt backup.txt
```
これにより、myfile.txtのコピーがbackup.txtとして作成されます。

ディレクトリを再帰的にコピーするには：
```
cp -r myfolder/ backupfolder/
```
9. rm
目的：ファイルやディレクトリを削除する（Remove）。

```
rm myfile.txt
```
これにより、myfile.txtが削除されます。

ディレクトリを削除する場合は、-rオプションをつけます：

```
rm -r myfolder
```

※ 注意：rmで削除したファイルやディレクトリは復元できないため、慎重に使用してください。
CopilotChat.nvimでもモデルを変更できるようになった

## 初めに

先日、GitHub CopilotがAnthropicのClaude 3.5 Sonnet、GoogleのGemini 1.5 Pro、OpenAIのGPT-4o、o1-preview、o1-miniなどのモデルから使用するモデルを選ぶことができるようになりました。

https://github.blog/jp/2024-10-30-press-releases-github-universe-2024/

https://japan.zdnet.com/article/35225566/

この記事では、neovimでCopilotChatの利用を可能にする[CopilotC-Nvim/CopilotChat.nvim: Chat with GitHub Copilot in Neovim](https://github.com/CopilotC-Nvim/CopilotChat.nvim)
でモデルの変更を行う方法についてまとめます。

## CopilotChat.nvimとは
その名の通り、Neovim上でCopilotChatの利用を可能にするためのプラグインです。

https://github.com/CopilotC-Nvim/CopilotChat.nvim

詳しくは↓の記事をご覧ください。

https://qiita.com/lx-sasabo/items/97c49d0f354ea3bdd525

CopilotChat.nvimに関しても、ClaudeとO1 Previewなどへのモデル変更がv2.15.0から可能になりました。

https://github.com/CopilotC-Nvim/CopilotChat.nvim/releases/tag/v2.15.0

## モデルの変更方法

### 各種モデルの有効化をGitHub上で行う
現在ClaudeやO1 PreviewなどのモデルはPublic Previewになっているため、有効にする必要があります。
有効化の方法については以下のドキュメントを参考にしてください。

https://docs.github.com/ja/copilot/using-github-copilot/using-claude-sonnet-in-github-copilot

### 利用できるモデルの選択を行う
モデルの有効化後、CopilotChat.nvimを起動した状態で以下のコマンドをコマンドモードで入力すると、
利用できるモデルが表示されます。

```
:CopilotChatModels
```

モデルが正しく有効化されている場合、以下のようにモデルの一覧が表示されると思います。

```
Select a model
1: claude-3.5-sonnet
2: gpt-3.5-turbo
3: gpt-4
4: gpt-4-0125-preview
5: gpt-4o
6: gpt-4o-2024-08-06
7: gpt-4o-mini
8: o1-mini
9: o1-preview
```

ここで、利用したいモデルの番号を入力することで、モデルの切り替えを行うことができます。

### 現在選択しているモデルの確認を行う
現在選択しているモデルはコマンドモードで

```
:CopilotChatModel
```

と入力することで確認可能です。

### デフォルトのモデルを指定する
ここまでのステップでモデルの切り替えは可能ですが、多用するモデルはデフォルトで利用するモデルとして
指定しておくと便利だと思います。

指定方法は[README](https://github.com/CopilotC-Nvim/CopilotChat.nvim?tab=readme-ov-file#default-configuration)にも書かれていますが、
プラグインのconfigで`model`に使いたいモデル名を指定することで設定可能です。

https://github.com/CopilotC-Nvim/CopilotChat.nvim?tab=readme-ov-file#default-configuration

## まとめ
紹介した通りCopilotChat.nvimでも利用するモデルを変更できるようになりました。
コマンドでシームレスにモデルを切り替えられるのがとても便利そうです。
これからもサポートされるモデルは増えていくと思うので、活用する機会が増えそうです。
【シリーズすごいぞiQ-F】過去記事一覧


# 過去記事一覧


1. [FX5UとGX_Works3の使いにくそうな所を考える](https://qiita.com/fujiteruo/items/85d538e7aee079cca140)
1. [GX_Works3でGX_Works2時代に挫折した構造化プログラムに再び挑む](https://qiita.com/fujiteruo/items/638819df964fca440f40)
1. [iQ-Fプログラムでのインスタンスについて考える](https://qiita.com/fujiteruo/items/4c0fb6722552781c8038)
1. [ラベルが意味するものの派閥について](https://qiita.com/fujiteruo/items/d0504357403030bda4bd)

1. [オムロン製調節計とプログラムレス通信する](https://qiita.com/fujiteruo/items/4ed8f50bfdb5c6b68f0a)
1. [初めてのラベルプログラムでつまずいたこと](https://qiita.com/fujiteruo/items/30280c2e79b2e66ffdd8)
1. [直接参考にはならない参考書籍3冊](https://qiita.com/fujiteruo/items/4c6093cd544bc8349b33)
1. [Gx_Works3のユーザライブラリを使いこなす](https://qiita.com/fujiteruo/items/e35f621541cd72d94cc5)
1. [GX_Works3でコンパイルされたコードを確認する](https://qiita.com/fujiteruo/items/a54c7e2d408d816fb852)
1. [その場しのぎのST言語プログラミング](https://qiita.com/fujiteruo/items/47ff45fcae041253a960)
1. [その場しのぎのST言語プログラミング_その2](https://qiita.com/fujiteruo/items/48cb3914ef75a1581326)
1. [マクロ型ファンクションブロックの引数について](https://qiita.com/fujiteruo/items/758f6a784aada97f8a37)
1. [「いわゆる構造化プログラミング」への道　最初の記事](https://qiita.com/fujiteruo/items/031c8bf649d574df0bba)
1. [「いわゆる構造化プログラミング」への道　2回目の記事](https://qiita.com/fujiteruo/items/3d50a37055549de7d01e)
1. [「いわゆる構造化プログラミング」への道　3回目の記事～データの構造化、構造体によるデバイスマッピング](https://qiita.com/fujiteruo/items/9d99f706af3b231d8d4d)
1. [「いわゆる構造化プログラミング」への道　4回目の記事～FBの分類とデータ構造について](https://qiita.com/fujiteruo/items/3be4bc16824f489d3d7d)
1. [「いわゆる構造化プログラミング」への道　オマケ1～構造体型ラベルの転送について](https://qiita.com/fujiteruo/items/578456a50c65d4fb6c93)
1. [「いわゆる構造化プログラミング」への道　オマケ2~ラベルプログラムでの一括処理について](https://qiita.com/fujiteruo/items/dc85df5c93dbebd3431e)
1. [「いわゆる構造化プログラミング」への道　オマケ3～ラッチラベルで注意すること](https://qiita.com/fujiteruo/items/8e179ea6cf091dca10f7)
アクセシビリティを意識したタブUI

<h1>はじめに</h1>

タブUIを初めて制作するにあたってインプットの量が初学者の自分にとって多くまた複雑でした。

そのため、今回理解に時間がかかったところを未来の自分にもう一度思い出せるためタイムカプセルとして記録しておきます。


<h2>つまずきポイント1 ｜　タブとパネルの紐付け</h2>

それぞれ役割の説明

-タブの仕事はタブパネルを制御する役割。
-パネルはどのタブの内容なのか示す役割。
それをaria-ほにゃららとidでそれぞれ紐付ける必要があります。

要点は以下の通りです。

・タブの”id”はパネルの”aria-labelledby”　🌕🌕🌕
・パネルの”id”はタブの”aria-controls”　⭐️⭐️⭐️
```html:test.py
        <button
          id="tabA"　🌕🌕🌕
          role="tab"
          aria-controls="panelA"　⭐️⭐️⭐️
          aria-selected="true"
          tabindex="0">
        タブ1
        </button>
        
        <div 
        id="panelA" ⭐️⭐️⭐️
        role="tabpanel" 
        aria-labelledby="tabA" 🌕🌕🌕
        tabindex="0">
        <p>パネルAの表示</p>
      </div>
```
aria-以降のほにゃららは一旦置いてるので意味はわからない。
<br>
<h2>つまずきポイント2  | 親要素地獄</h2>

タブをクリックした時参照する要素がおじいちゃんまで出てきます。
ただでさえおじいちゃんの年齢も忘れるのにこれはややこしい事案です。

コードを見ていきましょう。


```javascript:test.py
window.addEventListener("DOMContentLoaded", () => {
  const tabs = document.querySelectorAll('[role="tab"]');
  const tabList = document.querySelector('[role="tablist"]');

  tabs.forEach((tab) => {
    tab.addEventListener("click", changeTabs);
  });
});
function changeTabs(e) {
  const target = e.target; //クリックしたタブ
  const parent = target.parentNode; //タブの親要素
  const grandparent = parent.parentNode; //タブの親の親要素

  //tablistの中のタブのaria-selectedをfalseにする
  parent
    .querySelectorAll('[aria-selected="true"]')
    .forEach((t) => t.setAttribute("aria-selected", "false"));

  //クリックしたタブのaria-selectedをtrueにする
  target.setAttribute("aria-selected", true);

  //tabpanelの中のhiddenをtrueにする
  grandparent
    .querySelectorAll('[role="tabpanel"]')
    .forEach((p) => p.setAttribute("hidden", "true"));

  //クリックしたタブのtabpanelのhiddenをfalseにする
  grandparent
    .querySelector(`#${target.getAttribute("aria-controls")}`)
    .removeAttribute("hidden");
}
```

タブをクリックしたらどう動くか順番に書いていきます
登場人物
👴おじいちゃん...tabクラス
👨お父さん......tablistクラス
😃自分.........role="tab" クリックした自分

-タブ編-
1.クリックしたタブ😃の親要素.tablist👨にアクセスしてお父さんの属性を変更してあげます。
2.お父さんはaria-selected要素を持っています
3.初期状態だと😃はaria-selected="true"と"false"の２種類あるので一旦全部falseにします。理由はタブをクリックしたら前にクリックしたタブはtrueになっているので一度地ならしする必要があるためです。
4.クリックしたタブに😃aria-selected="true"をセットします。
-これでクリックしたタブはtureになり選択状態にcssのスタイルが当たります。

-パネル編-
1.クリックしたタブ😃のおじいちゃん要素.tab👴までアクセスしてその中にあるタブパネルの属性を変更していきます。
2.タブと同様一度、地ならしをするためにp要素にアクセスしてタブパネルを全てhiddenにします。
3.クリックしたタブ😃のおじいちゃん要素.tab👴までアクセスしてその中にあるaria-controlsの値からhiddenを取り除きます。
-これでクリックしたタブパネルからhiddenは取り除かれ表示されます。


```css:test.css

button[role="tab"] {
  border: none;
  background-color: #576066;
  border-radius: 8px 8px 0 0;
  font-size: 14px;
  padding: 12px 24px;
  font-weight: bold;
}
button[role="tab"][aria-selected="true"] {
  background-color: #fff;
}

button[role="tab"][aria-selected="false"]:hover {
  background-color: #fff;
  cursor: pointer;
}
div[role="tabpanel"] {
  background-color: #fff;
  border-radius: 0 8px 8px 8px;
  padding: 32px 16px;
}

```

今回参照した記事はこちら
もっと具体的でわかりやすいです
https://qiita.com/degudegu2510/items/a4a06d52623f89236506
devcontainerにgitやnodeなどのツールを簡単にインストールする方法

# はじめに
devcontainerにはDockerfileにインストール処理を書かなくても簡単にミドルウェアをインストールすることができる**Features**という機能があります！これによってdevcontainer内にgitやnodeの他、AWS CLIなどのコマンドラインツールをインストールすることができます！

# 作成方法
devcontainer.jsonの`features`フィールドに下記のページから入れたいツールを選んでURLをコピーし、入力するだけ！
反映にはコンテナのrebuildが必要なので注意してください

https://containers.dev/features

### こんな感じ
```
{
"features": {
		"ghcr.io/devcontainers/features/node:1": {},
		"ghcr.io/devcontainers-community/npm-features/typescript:1": {},
		"ghcr.io/devcontainers/features/git:1": {},
		"ghcr.io/shyim/devcontainers-features/bun:0": {},
        "ghcr.io/devcontainers/features/aws-cli:1": {}
	}
 }
```

# 参考文献
https://containers.dev/features

https://code.visualstudio.com/blogs/2022/09/15/dev-container-features

https://blog.jp.square-enix.com/iteng-blog/posts/00051-devcontainer-feature-intro/
【Kotlin】最近のバージョンアップに関して魅力的な差分まとめ

# はじめに
Kotlinも5月に2.0となり、かなり積極的にアップデートしているのが伺えますね。
そんな中で最近のアップデートでは便利な機能や言語仕様の追加など、魅力的なものがより一層多い印象です。
そこで今回は2.0に限らずですが、魅力的に感じた変化や機能を備忘録的にまとめてみようと思います。

# その1: コンテキストレシーバー（旧称：コンテキストパラメーター）
コンテキストレシーバーは Kotlin 1.7.0で実験的に導入され、Kotlin 2.0で正式に安定版となりました。

```main.kt 
class User(val name: String)

context(User)
fun greet() {
    println("Hello, $name!")
}

fun main() {
    val user = User("Alice")
    with(user) {
        greet()  // 出力: Hello, Alice!
    }
}
```
この例のgreet関数は、Userコンテキスト内でのみ呼び出せるため、withブロック内でgreetを使用しています。
これにより、関数の適用範囲を限定し、コードの安全性と可読性を高めることができます。

# その2: Value Classes
Value Classesは、Kotlinで効率的に軽量なデータ型を扱うための機能です。
通常のクラスと異なり、単一のプロパティしか持てませんが、データのオーバーヘッドを最小限に抑えつつ、型安全性を提供することができます。
Kotlin 1.5で実験的に導入され、Kotlin 1.6で安定し、Kotlin 2.0でさらに改善が加えられました。

```main.kt 
@JvmInline
value class Token<T>(val value: T)

fun <T> processToken(token: Token<T>) {
    println("Processing token with value: ${token.value}")
}

fun main() {
    val stringToken = Token("abc123")
    val intToken = Token(12345)
    
    processToken(stringToken)  // 出力: Processing token with value: abc123
    processToken(intToken)     // 出力: Processing token with value: 12345
}
```
Kotlin 2.0では、値クラスの不変性（immutability）がサポートされ、定義したプロパティが変更できないようにする機能が強化されています。
これにより、スレッドセーフなコードをより簡単に書けるようになり、並行処理を含むシステムでもデータ競合を防げます。
また、同バージョンでは、Value Classesのボックス化に関する最適化が強化され、不要なオブジェクトの生成が減少しました。
必要な場合にのみボックス化が行われ、メモリ効率がさらに向上したようです。

# その3: Union Types
Union TypesはKotlin 2.0で正式に導入された新しい型システムの機能で、複数の異なる型を同じ変数や引数として許容することができます。
この機能により、特定の値が複数の型のどれか一つをとりうる場合に、型安全にコードを記述できるようになりました。
例えば、「この関数はIntまたはStringを受け付ける」といったケースをシンプルに実現できます。

```main.kt
fun display(value: Int | String | Double) {
    val displayText = when (value) {
        is Int -> "Integer: $value"
        is String -> "String: $value"
        is Double -> "Double: $value"
        else -> "Unknown type"
    }
    println(displayText)
}

fun main() {
    display(42)           // 出力: Integer: 42
    display("Kotlin")     // 出力: String: Kotlin
    display(3.14)         // 出力: Double: 3.14
}
```

ユニオン型のメリットは、複数の型を安全に受け入れつつ、コードの可読性と柔軟性を向上させる点です。
型安全性が確保されることで、型ミスによるエラーが減り、異なる型を扱う際も一貫した処理が可能になります。

# その4：拡張プロパティのジェネリクス対応
拡張プロパティのジェネリクス対応は、Kotlin 2.0で正式に導入された機能です。
これにより、拡張プロパティに対してもジェネリクスを使用できるようになり、汎用的かつ型安全なプロパティを定義できるようになりました。
この機能は、ジェネリクスによる型の制約を拡張プロパティに適用することで、再利用性の高いプロパティを定義できる利点があります。

```main.kt
val <T> List<T>.secondOrNull: T?
    get() = if (this.size >= 2) this[1] else null
```
この例では、Int型のリストとString型のリストのどちらにも同じsecondOrNullプロパティを適用して、2番目の要素を取得しています。
これにより、拡張プロパティがさまざまな型に対して利用可能になり、より汎用的な実装が可能になります。

ちなみに以下のように制約を付与することも可能です。

```main.kt
val <T : Number> List<T>.averageOrNull: Double?
    get() = if (this.isNotEmpty()) this.sumOf { it.toDouble() } / this.size else null
```
ここでは、リスト内の数値の平均値を返す拡張プロパティaverageOrNullを定義しています。
T : Numberという制約により、Number型のリストにのみ適用されるようになっています。
制約を設けることで柔軟な実装を行いつつより安全に実装を行うことが可能です。

# さいごに
リリースされたばかりの頃が懐かしいと感じるほど、変化が著しいですね。
他にも魅力的だと感じる機能はたくさんあるので、興味ある方は是非調べてみると良いかと思います。
kintoneで海外事業を強化！【CybozuDays2024参戦レポ】

# はじめに
こんにちわ、タイランド大好きまとっちです。

CybozuDaysの中で個人的に興味があった**海外事業でのkintone活用**についてのセッションを聞いてきたので、自分の覚え書き用としてレポートを残しておきます。

## 参加したセッション
https://note.com/cybozudays/n/n8fa8ce086b84

# セッション内容レポート ～成功事例で学ぶ！海外事業を強化するkintone活用の秘訣～
kintoneは日本向けっていうイメージが強いけど、**海外事業でも輝ける**っていうのを事例と共に紹介してくれました。

## グローバルの導入/対応状況
- 日本は約3.5万社に対して、海外は中華圏・東南アジア圏・米国それぞれ1,000社前後
- サイボウズ拠点はアメリカ、中国、オセアニア、東南アジアにある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3713212/5476fb3a-a116-1370-0434-a4446b325c65.png)

:::note info
タイの拠点は今年３月に出来たばかりで、僕がよくワーケーションしてるコワーキングスペースがあるSamyan Mitrtown内にあります
:::
https://topics.cybozu.co.jp/news/2024/03/01-18738.html

## 海外事業での問題
日本と同じような問題ではあるが、特に海外ではその問題が顕著。
- 日々の海外現場の活動が把握しづらい（報連相が無い）
- 海外とのやり取りがExcel/メール/紙で非効率（チャットで情報も残らない）
- 情報の属人化で過去の経緯不明（ジョブホッピングで退職されて資産流出）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3713212/e5532222-0599-90c1-775f-38a011b5a9bf.png)

## 海外事業での解決方法
上記問題は、日本と同じようにkintoneを導入して解決することができるが、日本本社と現地法人どちらが主導するかによって導入パターンが変わってくる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3713212/517dee46-bc9d-e43a-2382-5c593c7db8d4.png)

## 現地法人主導の事例
これは日本でもよくあるような話だと思います。
- 各店舗でバラバラだった顧客情報やトラブル報告を集約し、サービス/品質向上を実現
- Excelでやり取り＋案件毎に異なる複雑な申請フローを、kintoneに集約して分かりやすく
- 社外や現場とのやり取りをスマホで行い、状況のリアルタイム通知やグラフ確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3713212/7fe50b3a-e25f-a510-04a9-9fa9aebbd2d5.png)

## 日本本社主導の事例
大阪に本社がある不二製油さんでは海外駐在員用のポータルとしてkintoneを活用しており、約30個のアプリを活用している。

:::note info
僕も以前勤めていた会社で海外駐在を経験したのですが、この不二製油さんの話がとても"あるある"で共感しました。なので、海外拠点の駐在員向けにkintoneを導入して成功する再現性は高いんじゃないかなと思います。
:::

### kintoneをおすすめする理由
- 海外駐在員・現地社員などのアクセス権を分けて管理可能
- kintone上で自己解決できるので、時差があってもすぐに対応可能
- ペーパーレスで申請ワークフローが完了、過去事例を参照しやすい
- 進捗確認が可能（駐在員、現地担当者、海外人事部、代行業者が連携）
- 言語設定可能で、日本人は日本語、現地担当者は英語で入力できる
- 数年に一度の業務も手順が残るので、別駐在員に引き継ぎが簡単
- セキュリティが理由で国内ポータルが使えないのでkintoneが代理になる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3713212/8c3ef591-7b02-30b0-a300-cdddb7b21e8e.png)

### 具体的なkintone導入結果
- **現地でのスムーズな導入**
説明会やマニュアル作成、徐々に導入＋要望にすぐ対応、コロナ禍によるデジタル要請などもあり、スムーズに受け入れられた。今まで見えていなかった全体が見えるようになり、特に現地担当者に好評。
- **やり取り電子化で負担軽減**
年間350件の申請がペーパーレス化。駐在員とのやり取りもスムーズになり、休日出勤するレベルで忙しかった給与改定作業も負担が軽減され、個人情報の誤送信リスクも減少で心的負担も無くなった。
- **海外と日本のチームワーク向上**
駐在員が本社とつながりを感じることができ、孤独感が軽減。kintoneに本社のバックアップが集約されているので、現地と本社の連携強化できた。
- **海外に合わせた柔軟な調整が可能**
異なる法令や慣習、資本関係や現地情勢に合わせて、人事担当者がkintone上で簡単にアプリを微修正し、日々環境が変わりやすい海外にも追随して対応できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3713212/46f4d99e-495a-10db-7f8d-3cc2a5f160c0.png)

# おわりに
セッション後には、登壇されていたKintone Southeast Asiaの中澤さんや、視聴されていたKintone ThailandのNamyaさんにも、ご挨拶させて頂けて大々々々々満足でした。

タイに進出するぞーーー！おーーーーーーー！！💪🎉
Python　高階関数をデコレーターとして使う方法

# デコレーター使用例
Pythonでのデコレーターの使用例として簡潔なコードを用意しました。
@propertyや@classmethodといった既に定義済みのものもありますが今回は自身で作成する用のデコレーターを作成しました。
他使用例等ご教授いただけると幸いです。

```
## 高階関数を定義
def print_deco(func :object):
    def inner() #クロージャー
        print('----')
        func()
        print('----')
    return inner


## 高階関数をデコレーターとして利用
@print_deco
def decorator():
    print('これはデコレーターです')


## 呼び出し
decorator()
```

```
## 出力結果
----
これはデコレーターです
----
```

:::note info
@関数名と書くことによって関数の処理を追加することをデコレーターという。
上記では@print_decoをdecorator()関数につけたことによって
decorator = print_deco(decorator)の記述が不要になった。
@関数名を使い何らかの処理を追加することできることが分かる。
:::


# 参考文献
Pythonプログラミングパーフェクトマスター.「デコレーター」.2023-11,https://www.shuwasystem.co.jp/book/9784798070667.html,(参照　2024-11-10).
[Rails]マイグレーション後のschema.rbはいつも絶対ではない

「私が貼ったインデックス、全部消されているのですが...」

今週仕事をしていたら、このような連絡をいただいた。
あれ、schema.rbは手修正してはいけないんじゃなかった？（違う）

## 経緯
いつものようにマイグレーション込みのPRを作成し、レビュー後マージされその週の本番リリースまでにその内容がSTGところだった。

コンフリクトも生じていなく、developマージの時はschema.rbのバージョンだけ新しくしてapprove、マージ。

しかし、マイグレーションの時にインデックスを貼るところの記述がschema.rbから丸ごと消えていてそのままSTGが運用されていた。

## 兆候
確かに最近マイグレーションを実行するたびにすごい量のモデルアノテーションの変更分が出ていた。
うざいなと思いつつ、原因を探ろうとはしなかった。

## 原因
### マイグレーション実行順序
以下のような状況を考える。

```
develop branch:     A -> B -> C
                      \
feature branch:        D -> E
```
今回私はAからブランチを切っていた。

その間に他の人がCの変更（インデックスを貼る）をdevelopに入れた。
その時、Cには変わったschema.rbが入っている状態になる。

ここで、Dにdevelopをpullし、マイグレーションを走らせた。
その時、schema.rbに変更が出てしまっていたのに、私はそれをそのままcommitしてしまった。

developをpullするタイミングでコンフリクトが起きると思っていたが、実際にはgitのauto mergeが働いてしまう時があるという。。

## 正しいフロー
### dumpし、schema:loadする
上記の「兆候」のような現象が起きていると、develop（もしくはmain）のschema.rbをもとにschema:loadをして順番に合った正しいマイグレーションを走らせた状態にする必要がある。

しかし、schema:loadは今までのデータを飛ばしてしまうため、その前に今のデータをdumpする必要がある。
そのdumpの処理がめんどくさいから、社内にはやっている人はいなさそうな感じだった。

今回私はdockerのボリュームを消して、ビルドをし直すことで解決した。（めんどくさい）
どっちにせよデータは消えるので、結果的にはschema:loadだけでよかった。

## おわりに
なんにせよ、自分で行なっていないものをcommitすることは危険。
マイグレーションで出てくるschema.rbは絶対ではない。

知ってたら当たり前なことを、今回の失敗経験で学んだ。
ビットコインの年間利益計算スクリプト

ビットコインの年間利益を総平均法で計算するスクリプト作成しました。何か間違っている点あればご指摘いただきたいです。

移動平均法は以下参照。

https://wooolwoool.hatenablog.com/entry/2024/11/10/112635

```python
import pandas as pd

def calculate_annual_profit_average_method(csv_file):
    # CSVファイルの読み込み
    df = pd.read_csv(csv_file, parse_dates=['取引日時'])

    # 必要な列のみ取得
    df = df[['取引日時', '取引種別', '取引価格', '通貨1数量', '手数料']]
    df = df.sort_values('取引日時')  # 取引日時でソート

    # 年ごとのデータに分ける
    df['年'] = df['取引日時'].dt.year

    annual_profit = {}

    # 年ごとに計算
    total_quantity = 0  # 総購入数量
    total_cost = 0      # 総購入金額
    for year, group in df.groupby('年'):
        profit = 0          # 売却利益

        # まず、年内の購入取引の合計を計算
        for _, row in group.iterrows():
            if row['取引種別'] == '買い':
                price = float(row['取引価格'].replace(",", ""))
                quantity = abs(float(row['通貨1数量'].replace(",", "")))
                # 購入にかかったコスト
                total_cost += price * quantity
                # 購入数量
                total_quantity += quantity - abs(float(row['手数料']))

            if row['取引種別'] == '受取':
                quantity = abs(float(row['通貨1数量'].replace(",", "")))
                total_quantity += quantity

        # 年末の平均取得原価を計算
        if total_quantity > 0:
            avg_cost_price = total_cost / total_quantity
        else:
            avg_cost_price = 0

        # 次に売却取引を確認して利益を計算
        for _, row in group.iterrows():
            if row['取引種別'] == '売り':
                price = float(row['取引価格'].replace(",", ""))
                quantity = abs(float(row['通貨1数量'].replace(",", "")))
                # 売却利益 = (売却価格 - 平均取得原価) * 売却数量
                profit += (price - avg_cost_price) * (quantity - abs(float(row['手数料'])))
                total_quantity -= quantity
                total_quantity -= abs(float(row['手数料']))

        # 年ごとの利益を辞書に追加
        annual_profit[year] = int(profit)

        total_cost = avg_cost_price * total_quantity

    return annual_profit
```
ChromeOSを入れたMacBookAirでXampp環境を構築した

ChromeOSでは以下から簡単にLinux環境が構築できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931560/dd470f3d-b8e9-597a-9a08-e966a0c3c1b2.png)

Xamppは以下のリンクからダウンロードした。
https://sourceforge.net/projects/xampp/files/XAMPP%20Linux/

Xamppをインストールして、Apacheを起動して、以下のURLでダッシュボードが表示した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931560/073677c9-e9bd-5a39-b173-4cbbbab19d09.png)
投稿 126 主なコマンドライン 2024/11/03

本日の勉強時間　3H

主なコマンドラインを、実際の経験からいくつか挙げていく。



```
ls
```
↑カレントディレクトリにおけるファイルの一覧

```
cd ~/Documents
```
↑
書類フォルダ（Documentsフォルダ）まで移動


```
open .
```
↑ターミナルで開いているカレントディレクトリをFinderで表示

```
pwd
```
↑カレントディレクトリ表示
jwtトークンについて調べてみた

## jwt（ジェット）とは

JWT（JSON Web Token）認証は、JSON形式のトークンを使用してユーザーの認証と情報の伝達を行う仕組み。セッション管理や認可に使用されている。jwtトークン自体に署名がついているので内容が改竄されていないかを検証できる。

## jwtのメリット

- サイズが小さいのでHTTPヘッダーに格納できる
- ペイロードにはユーザーに関する必要な情報がすべて含まれているので何度もDBに問い合わせなくても認証ができる
- Json形式なので、多くの言語でパースやマッピングがサポートされており、使いやすい

## jwtの構造

jetは以下の３つの要素で構成されている。

1. ヘッダー（Header）
1. ペイロード（Payload）
1. 署名（Signature）

上記３つの要素をそれぞれハッシュ化したものを`.`で連結したものがjwtトークンと呼ばれる文字列になる。

以下のサイトでイメージを確認できる。
https://jwt.io/

### ヘッダー

ヘッダーにはハッシュ化に使用するアルゴリズム情報やトークンのタイプなどの情報が含まれる。
以下はハッシュアルゴリズムとして`HS256`を用いること、トークンタイプはjwtという意味になる。

```json
{
  "alg": "HS256",
  "typ": "JWT"
}
```

### ペイロード

ペイロードにはユーザーに関する情報やトークンの有効期限、発行者情報などが含まれる。
ユーザー情報のことをまとめてクレーム(claim)という。暗号化されていない限り、秘密の情報を入れてはいけない。

```json
{
  "sub": "1234567890",
  "name": "tarou",
  "iat": 1516239022,
  "exp": 1516242622
}
```

sub：トークンのサブジェクト（ユーザーIDなど）
name：ユーザーの名前
iat：トークンの発行時間
exp：トークンの有効期限



### 署名

ヘッダー、ペイロード、ヘッダーで指定されたハッシュ化アルゴリズム、シークレット(秘密鍵)を用いて署名を作成する。
これによって、内容が改竄されていないことが証明できる。


### jwtのデバッガーツール
以下のツールでjwtトークンを生成したり、中身を見たりできる
https://jwt.io/#debugger-io


## 認証手順

1. ユーザーがサーバーにユーザー名とパスワード（平文）を送信
2. サーバーでjwtトークンを発行する
2. クライアント側でトークンをローカルストレージやクッキーに保存
2. 以降のリクエストでは、HTTPヘッダーにAuthorizationの値としてjwtトークンを入れてサーバーにリクエストを行う
2. サーバーはAuthorizationのトークン内容を検証して正しければ、各種処理やAPIの実行に進む

## GOでjwtトークンを作成する

"github.com/golang-jwt/jwt/v4"パッケージを使う

```go

import (
	"os"
	"time"
	jwt "github.com/golang-jwt/jwt/v4"
)

func Login(user User) (string, error) {
	// ユーザーのリクエストをもとにユーザー情報がDBにあるか検索
    // 省略
	
	// パスワードの検証(DBにあるhash化されたパスワードとユーザーが送信してきた平文のパスワードを比較)
    // 省略

	//パスワードが一致した場合、jwtトークンを生成する
	jwtToken := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"user_id": userId,
		"exp":     time.Now().Add(time.Hour * 24).Unix(), //jwtトークンの有効期限設定
	})

	//署名を作成してjwtトークン生成、SECRETは秘密鍵のことなので、環境変数にしておく
	token, err := jwtToken.SignedString([]byte(os.Getenv("SECRET")))
	if err != nil {
		return "", err
	}
	// 完成したjwtトークンを返す
	return token, nil
}
```

## まとめ

- 自分の勤務先もjwtトークンを用いた認証が使われているが今回のアウトプットでjwtの外観を掴むことに成功したと思う。GOやJsを使用しているとjson形式自体のありがたみも痛感した。

## 参考

https://auth0.com/learn/json-web-tokens?_gl=1*cngmxf*_gcl_au*MTU2ODkxMjcxNy4xNzMxMTk5Mzcx*_ga*MTUzMjc4MTU4Ny4xNzMxMTk5Mzcy*_ga_QKMSDV5369*MTczMTE5OTM3MS4xLjEuMTczMTIwMDU5My43LjAuMA..
LGTMって何？また、LGTM画像の生成ツールを公開する

「LGTM」（Looks Good To Me）は、ソフトウェア開発のコードレビューで承認や同意を示すカジュアルな表現です。チーム開発の際、コードを他のメンバーが確認（レビュー）してから変更を取り込む（マージ）する場合が多く、その際に「LGTM」を使うことが一般的です。

### 使われるシチュエーションと背景
コード変更の際には、品質を確保するために他の開発者がレビューを行います。レビューを通過するには、以下のポイントが確認されます。

* 機能要件の満たし具合
  * 新しいコードが要求された機能を正しく実装しているか。
* コード品質
  * コードが読みやすく、保守しやすい構造になっているか。
* セキュリティとパフォーマンス
  * コードが安全で効率的に動作するか。

レビュー担当者が「LGTM」とコメントするのは、上記のようなチェックが問題なくクリアされており、変更をマージしてもよいと判断した場合です。

### メリット
「LGTM」を使うことで、レビューの承認プロセスがスムーズになります。また、形式的でないカジュアルな表現のため、フレンドリーなコミュニケーションを促進する効果もあります。

### 他の関連表現
* PTAL（Please Take A Look）
    * コードのレビューを依頼するときに使う表現で、「確認してください」の意味です。
* WIP（Work In Progress）
    * レビュー依頼時にまだ完成していない作業を示すために使います。
* Nit（Nitpick）
    * 細かな改善点や好みの提案を指し、修正が必須でない場合に使います。
「LGTM」はシンプルですが、コードレビュー文化において信頼と効率を生む重要な表現として定着しています。

### LGTM画像

単に「LGTM」とコメントするよりも、画像を使うことでコメントが視覚的に面白くなります。これは、チームメンバーの気持ちを軽くし、レビューのプロセスを楽しいものにする効果があります。

LGTM画像を使ってレビューにユーモアを取り入れると、チームの士気が上がることがあります。開発が厳しい時期でも、画像が気分転換になり、ポジティブな雰囲気を促進します。

コードレビューは日常的な作業の一部であり、単調に感じられることがありますが、画像を挟むことで変化が生まれます。メンバーによって異なる画像が投稿されると、日々のルーチンにも少しした違いが加わります。

文章だけのやり取りだと冷たい印象を与えてしまうこともありますが、画像を使うことで柔らかい雰囲気が加わり、ポジティブな承認の気持ちが伝わりやすくなります。

### LGTM画像の生成ツール
* Pythonで生成するツール
    * [GitHub/lgtm](https://github.com/SMZPP/lgtm/tree/main)
    * ![lgtm.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/801198/cc9ab65c-b7d2-7bc1-3cd8-74a0dcf4d7ba.jpeg)
URDFのリンク設定

![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) 基準点がどこかわからぬ

## やること

URDFを記述する際に、LINKの記述方法がいつもわからなくなるのでまとめておきます。
間違っていたらご指摘ください。

参考は公式ドキュメント

https://wiki.ros.org/urdf/XML/link

## クイズ

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/03aa502b-d90c-ce25-5b0c-4d08b307f355.png" width = 400>

図のような腕パーツがあるとします。
パーツは前腕から拳の部分まで一体型です。丸い穴が空いた部分が回転軸で、肘にあたります。

URDFのLINKとして記述する際に、座標の原点になりそうな候補がいくつかあります。

① STLやdaeモデルの原点
② 回転軸の中心
③ イナーシャ用の重心
④ ロボット全体の原点

上記のうち、LINKの原点はどれでしょうか？

## 正解

正解は、たぶん「② 回転軸の中心」です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/af0dc029-13e4-5cba-6f71-04fb2ef4c570.png" width = 400>

ということで、図の紫円の中心を原点とします。
それに合わせ、STLなどのモデルの座標の中心も同じ紫円の中心となるようにします。
イナーシャ用の重心（図では赤い球のライン）については、URDL上で記述します。

以下は公式ドキュメントに掲載されている記述例にコメントしたものです。

```xml
<link name="my_link">
    <inertial>
        <origin xyz="0 0 0.5" rpy="0 0 0"/> #原点からの重心座標
        <mass value="1"/>
        <inertia ixx="100"  ixy="0"  ixz="0" iyy="100" iyz="0" izz="100" />
    </inertial>

    <visual>
        <origin xyz="0 0 0" rpy="0 0 0" /> #原点からのオフセット
        <geometry>
            <box size="1 1 1" />
        </geometry>
        <material name="Cyan">
            <color rgba="0 1.0 1.0 1.0"/>
        </material>
    </visual>

    <collision>
        <origin xyz="0 0 0" rpy="0 0 0"/> #原点からのオフセット
        <geometry>
            <cylinder radius="1" length="0.5"/>
        </geometry>
    </collision>
</link>

```

# まだ謎のところ

例えば手首のヨー軸（ローカル）などの場合は、拳などのパーツの原点を前腕の原点と揃えることも多いようです。手首の回転軸がヨー軸のみの場合、拳は前腕に対しては振り回されませんが、二の腕（肘）に対しては前腕と共に振り回されるので、確かにその方がよさそうです。むしろそうすべきかもしれません。
拳の原点を手首とすべきか肘とすべきかについての回答はまだ見つかっていません。

# さいごに

STL,daeなどのビジュアルやコリジョンについてはオフセット設定もできるようですが、設定できる場合は回転軸を原点に合わせてしまうとわかりやすいと思います。

いくつかの公開されているURDFファイルを覗いたところ、STLなどモデルの中心がパーツの回転軸に設定されていたので多分あっているとは思いますが、もし間違っていたり、より詳しい情報をご存知の方はご指摘ください。

# シリーズ記事

ヒューマノイドのURDFを書き始める

https://qiita.com/Ninagawa123/items/d65e92877246e649cca6
オブジェクト指向や変更容易性について

## 概要
オブジェクト指向や変更容易性についての参考書を読んで
興味深い内容を紹介いたします。

## 参考書
１）「良いコード/悪いコードで学ぶ設計入門」by 仙場大也
２）「オブジェクト指向のこころ」by アラン・シャロウェイ、ジェームズ・R・トロット

### オブジェクト指向
・インターフェイスを使用することを意識してプログラミングすること
・クラスの継承よりも集約を多用すること
・実体間の関連に意識を向けること
・クラスを設計する際
　・流動的要素を見つけ出し、凝集度を高く、結合度の低くする
　・何をもって目的を達成したとみなすかを考える

### 変更容易性
・分岐を書きそうになったらInterfaceを使用すること
・異常な値を早期に検知させること
・bestではなくbetterを意識すること
・驚き最小の原則を意識すること
・UML図では、ただ単にモデル分けするのではなく、目的別に分類すること
・コーディング規約を利用すること
・コーディングを続けること
Elixir パターンマッチと関数パターンマッチ

こんにちは！
プログラミング未経験文系出身、Elixirの国に迷い込んだ？！見習いアルケミストのaliceと申します。
今回はパターンマッチと関数パターンマッチの違いについて学んだことをまとめます。

# 目次
1.パターンマッチと関数パターンマッチ(本記事)
2.[関数パターンマッチ+ガード節](https://qiita.com/Alicesky2127/items/fa8709a31c5d67b89135)

# 目的
パターンマッチと関数パターンマッチの違いを理解する


## 実行環境
Windows 11 ＋ WSL2 ＋ Ubuntu 22.04
Elixir v1.17.3
Erlang v27.0

# パターンマッチとは
:::note info
`=`(マッチ演算子)を使うことで右辺を左辺に束縛すること
:::

## 例
右辺の1, 2, 3を左辺の変数a, b, cにそれぞれ束縛します
```diff_elixir:iex
[a, b, c] = [1, 2, 3]
```
```
[1, 2, 3]
```
左辺と右辺を入れ替えるとパターンマッチが行われます。
この場合右辺の変数a, b, cにはそれぞれ1, 2, 3が束縛されているため、[1, 2, 3] = [1, 2, 3]のパターンマッチを行っています
```diff_elixir:iex
[1, 2, 3] = [a, b, c]
```
```
[1, 2, 3]
```

要素単独でのパターンマッチも同様です
```diff_elixir:iex
3 = c
```
```
3
```

変数a, b, cに束縛された値と異なる値でパターンマッチをしようとするとマッチエラーが発生します
```diff_elixir:iex
[1, 20, 3] = [a, b, c]
```
```
** (MatchError) no match of right hand side value: [1, 2, 3]
    (stdlib 6.0) erl_eval.erl:652: :erl_eval.expr/6
    iex:10: (file)
```
要素単独でのパターンマッチも同様です
```diff_elixir:iex
10 = a
```
```
** (MatchError) no match of right hand side value: 1
    (stdlib 6.0) erl_eval.erl:652: :erl_eval.expr/6
    iex:13: (file)
```



# 関数パターンマッチとは
:::note info
同一関数名の引数違いでパターンマッチを行うこと
:::

## 例
### 前提
下記でElixirプロジェクトを作っておきます
```shell:bash
mix new func_matching
cd func_matching
```

### テストの追加
```diff_elixir:test/func_matching_test.exs
describe "check list elements" do
  test "when list is []" do
    assert FuncMatching.checkelems([]) == "空のリストです"
  end

  test "when list has only one element" do
    assert FuncMatching.checkelems([5]) == "リストの要素数は1です"
  end

  test "other pattern" do
    assert FuncMatching.checkelems([1, 2, 3]) == "リストの要素数は2以上であるか、そもそもリストではありません"
  end

  test "when argument is not a list" do
    assert FuncMatching.checkelems("hoge") == "リストの要素数は2以上であるか、そもそもリストではありません"
  end
end
```

### 関数の追加
```diff_elixir:lib/func_matching.ex
defmodule FuncMatching do
  def countelems([]) do
    "空のリストです"
  end

  def countelems([_]) do
    "リストの要素数は1です"
  end

  def countelems(_) do # 上記のいずれにもマッチしなかった場合
    "リストの要素数は2以上であるか、そもそもリストではありません"
  end
end
```




# ～Elixirの国のご案内～
↓Elixirって何ぞや？と思ったらこちらもどぞ。Elixirは先端のアレコレをだいたい全部できちゃいます:laughing::sparkles::sparkles:

https://qiita.com/piacerex/items/09876caa1e17169ec5e1

↓ゼロからElixirを始めるなら「エリクサーチ」がおすすめ！私もエンジニア未経験から学習中です。

https://elixir-lang.info/topics/entry_column


↓[We Are The Alchemists, my friends!:bouquet:](https://qiita.com/torifukukaiou/items/6bcd5bbb80df9e594e9e "Awesome-san's Awesome article")[^10]
Elixirコミュニティは本当に優しくて温かい人たちばかり！
私が挫折せずにいられるのもこの恵まれた環境のおかげです。
まずは気軽にコミュニティを訪れてみてください。[^11]


https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian




[^10]: @torifukukaiouさんのAwesomeな名言をお借りしました。Elixirコミュニティを一言で表すと、これに尽きます。


[^11]: @kn339264さんの素敵なスライドをお借りしました。Elixirコミュニティはいろんな形で活動中！
プロキシサーバーを安全に利用するために

# 1.初めに
Qiitaのおすすめでこの記事が出てきました。

https://qiita.com/pseudonym2/items/dd77dd92f54109e26487

プロキシの様々な種類だったり、
プロキシサーバーにはできて、VPNにはできることなどが分かりやすく記載されています。

例えば、
プロキシ自体には暗号化の機能はないが、VPNは
データがデバイスから送信される前に、VPNプロバイダーによって暗号化されるということや

Web（HTTPS）プロキシではデフォルトで、暗号化されていることから、フォワードプロキシ（HTTPなどの複数のネットワークプロトコルをかしいて、クライアントにコンテンツを配信するもの）よりも安全に通信ができることなど


通信の安全性を見る上では、VPNが安全というような感じではありますが、

プロキシにはキャッシュ機能やサーバーの負荷分散の役割などもあるので一概にVPNというわけではないです。

ただ、プロキシにもデメリットはたくさんあって

プロキシ自体にデバイスのメタデータなどが保持されている可能性があるので、そもそもプロキシに脆弱性があったら
元も子もないですね。

なので、「じゃあ、プロキシを使う上でどのように安全に使えば良いのか』という疑問が出てくるわけでした。

# 2.プロキシを安全に使うために

参考にした記事はこちらになります。

https://www.lrm.jp/security_magazine/proxy_server/#:~:text=%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%92%E4%BD%BF%E3%81%86%E9%9A%9B%E3%81%AE%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E5%AF%BE%E7%AD%96%20*%20%E5%85%AC%E9%96%8B%E3%81%95%E3%82%8C%E3%81%9F%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E5%88%A9%E7%94%A8%E3%81%AF%E6%8E%A7%E3%81%88%E3%82%8B%E3%81%93%E3%81%A8%20*%20%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AEIP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%AF%E6%AD%A3%E3%81%97%E3%81%8F%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%20*%20%E8%AA%8D%E8%A8%BC%E3%82%92%E6%9C%89%E5%8A%B9%E5%8C%96%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8


## 2.1 プロキシを安全に使うための三大原則
この記事によると安全に使う方法は大きく３つあるとのことでした。

1.公開されたプロキシサーバーの利用は控えること 
2.使用するプロキシサーバーのIPアドレスは正しく設定すること 
3.認証を有効化すること 


### 1.公開されたプロキシサーバーの利用は控えること

無料で利用できる一般公開されたプロキシサーバーがあります。 

無料で利用できるため、便利なように感じますが、中には情報を抜き取る事を目的として作られたものもあります。 
重要な情報をやり取りする場合は、公開プロキシサーバーの利用を控えたほうが無難です。

### 2.使用するプロキシサーバーのIPアドレスは正しく設定すること
使用するプロキシサーバーは、正しいIPアドレスが入力できていないと、別のプロキシサーバーを経由してしまいます。 
意図しないプロキシサーバーを経由すると、情報漏えいにつながるリスクがあります。

### 3.認証を有効化すること 
プロキシサーバーにアクセスする際に、IDとパスワードによる認証を有効化することで、誰でも見ることができる状態にならなくなります。 

誰でも見ることができるということは、悪意ある人物に悪用される危険性が高く、ウイルス感染や情報漏えいに繋がってしまいます。 
こういった被害を受けないためにも、必ず認証は有効にしておきましょう。 

## 2.2 一番大事なのは認証だと思う

大事なのは３番かなと思いました。
認証については付随して２要素認証などを用いて認証基盤を堅実にすればある程度安全に使えるようになりそうですね。
paizaラーニングスキルチェック「B143:じゃんけん列車」を解いてみた結果

▼問題

以下のリンクを「B143:じゃんけん列車」で検索してください。

https://paiza.jp/challenges/ranks/b/info

▼結果

https://paiza.jp/challenges/share/yU3EBbwhx-HBBDE-EUVSaSzHBecixMwfsmEsHKsCqCw?source=social
axxのlinuxでの実用へ向けての試験的適用　リロケータブルELFと実行ファイルの作成 [ axl ,rel ]


これは、axxのlinuxで動作するバージョンです。

今の所、同一セクション内ですが、リロケータブルELFを作り、リンクすると実行ファイルができるところまで行ってます。

### ソース

https://github.com/fygar256/axl/tree/main

## 使い方

##### アセンブル

axxのオプションは、`-E`を指定すると、ELF用のセクションフラグを付加したエクスポートファイルを出力する。

```
./axx.py hello.axx hello.s -o hello.bin -E hello.tsv
```

リロケータブルELF作成スクリプト

```sh:rel
#!/usr/bin/zsh

# 引数の確認
if [ $# -ne 3 ]; then
    echo "Usage: $0 <tsv_file> <raw_binary> <output_elf>"
    exit 1
fi

TSV_FILE=$1
RAW_BINARY=$2
OUTPUT_ELF=$3

# 一時ファイルの作成
TEMP_LD_SCRIPT=$(mktemp)
TEMP_OBJ=$(mktemp)

# リンカスクリプトの生成
echo "SECTIONS {" > $TEMP_LD_SCRIPT
while IFS=$'\t' read -r section_name start_addr size flags || [ -n "$section_name" ]; do
    if [[ -v "$size" ]]; then
        echo "  $section_name $start_addr : { *($section_name) } : $flags" >> $TEMP_LD_SCRIPT
    fi
done < $TSV_FILE
echo "}" >> $TEMP_LD_SCRIPT

# rawバイナリをオブジェクトファイルに変換
objcopy -I binary -O elf64-x86-64 --rename-section .data=.text $RAW_BINARY $TEMP_OBJ

# リロケータブルELFファイルの作成
ld -r -o $OUTPUT_ELF -T $TEMP_LD_SCRIPT $TEMP_OBJ

# シンボルの追加
while IFS=$'\t' read -r label_name address size flags || [ -n "$label_name" ]; do
    if [[ -z "$size" ]]; then
        objcopy --add-symbol $label_name=$address $OUTPUT_ELF
    fi
done < $TSV_FILE

# 一時ファイルの削除
rm $TEMP_LD_SCRIPT $TEMP_OBJ

echo "Created $OUTPUT_ELF"
```

### オブジェクトファイル作成・リンク・実行
##### リロケータブルオブジェクトファイルを作る

```
$ ./rel hello.tsv hello.bin hello.o                   
Created hello.o
```
##### リンク
```
$ ld hello.o -o hello
```

##### 実行
```
$ hello                                             
hello, world
$ 
```

一応できました。まだ、セクションの区分けと、シンボルのインポート関係が残されてます。

これで、Coffee Lake Processorも動くにゃんご！
シーケンス図の分類子を紹介

# はじめに
今回は以前記事で書いたシーケンス図の分類子を紹介していこうと思います
### 本文
基本的にPlantUMLでは下記のように書くことで四角の箱に囲まれたものが表示されます。
```
Alice -> Bob: Authentication Request
```
しかし、実際には全てが同じ形状だとどれがどういったものなのかが分かりづらいため`participant`を使うことで分類子を宣言することができます
```
participant 参加者 as Participant
actor       人間    as Actor
boundary    境界   as Boundary
control     操作 as Control
entity      実在物 as Entity 
database    データベース as Database
collections 複数オブジェクト as Collections
queue       列 as Queue
Participant -> Actor : To actor
Participant -> Boundary : To boundary
Participant -> Control : To control
Participant -> Entity : To entity
Participant -> Database : To database
Participant -> Collections : To collections
Participant -> Queue: To queue
```
上記のコードをPlantUMLで表示すると下記のようになります

```plantuml
participant 参加者 as Participant
actor       人間    as Actor
boundary    境界   as Boundary
control     操作 as Control
entity      実在物 as Entity 
database    データベース as Database
collections 複数オブジェクト as Collections
queue       列 as Queue
Participant -> Actor : To actor
Participant -> Boundary : To boundary
Participant -> Control : To control
Participant -> Entity : To entity
Participant -> Database : To database
Participant -> Collections : To collections
Participant -> Queue: To queue
```
分類子　表示名　as 命名の順になっており実際にどういった処理を表したいのかによって変わってきます。
表示名に関してはとりあえずGoogle翻訳したものをつけました
### 最後に
次は分類子の編集方法を紹介しようと思います
勉強のアウトプットでしかありませんが、どなたかのお役に立てれば幸いです