OmniAICreator/Qiita-1.07M huggingface dataset:
横取り！ユニバーサル参照君

# クイズ

私は C++ で次のようなクラスを作りました。

```c++
#include <iostream>

struct hoge {
    hoge() = default;
    hoge(const hoge&) {
        std::cout << "コピー構築\n";
    }
    hoge(hoge&&) {
        std::cout << "ムーブ構築\n";
    }

    template <class T>
    hoge(T&&) {
        std::cout << "ほかのクラスから構築\n";
    }
};
```

ここで、以下のコードを実行すると何が出力されるでしょう？

```c++
int main() {
    const hoge x;
    hoge y;
    hoge z;

    hoge h1 = x;
    hoge h2 = std::move(y);
    hoge h3 = 42;
    hoge h4 = z;
}
```

<details>
  <summary><strong>正解は……</strong></summary>
  <div>

```
コピー構築
ムーブ構築
ほかのクラスから構築
ほかのクラスから構築
```

です！

  </div>
</details>


# ゆるい解説

（ちゃんとしたことは規格書を読むか、C++ ﾁｮｯﾄﾜｶﾙ人に聞いてください。）

```c++
hoge h1 = x;
```

`x` は `const hoge` 型の lvalue です。
よって、`const hoge&` を受け取るコピーコンストラクタが呼び出されます。

`T = const hoge&` のとき、`hoge::hoge(T&&)` も `const hoge&` を受け取るコンストラクタになりますが、ここではテンプレートでないほうが優先されます。

```c++
hoge h2 = std::move(y);
```

`std::move(y)` の型は `hoge&&` です。
よって、`hoge&&` を受け取るムーブコンストラクタが呼び出されます。

`hoge::hoge(T&&)` では `T = hoge` と推論され、これも `hoge&&` を受け取りますが、上のケースと同様にテンプレートでないほうが優先されます。

```c++
hoge h3 = 42;
```

`42` は `int` の rvalue です。
ここでは、`hoge::hoge(T&&)` の `T` が `int` に推論され、これが呼び出されます。

```c++
hoge h4 = z;
```

`z` は `hoge` 型の lvalue です。
ここで、`hoge::hoge(T&&)` の `T` は `hoge&` に推論されます。

オーバーロード解決では、cv 修飾を付け足さなくてよいほうを優先します。
`z` は `const hoge&` としても受け取れますが、`hoge&` を受け取るコンストラクタがあるならそれが優先されます。
よって、ここでは **`hoge::hoge(T&&)` が呼び出されます**。


# おしまい

ユニバーサル参照を受け取る（？）関数テンプレートのオーバーロードにはこういう罠があるので、気を付けましょう。

今回のケースでは、`hoge::hoge(T&&)` のテンプレートパラメータに対して「 `std::remove_cvref_t<T>` が `hoge` でない」という要件を足してやればよいです。

```c++
#include <iostream>
#include <concepts>
#include <type_traits>

struct hoge {
    hoge() = default;
    hoge(const hoge&) {
        std::cout << "コピー構築\n";
    }
    hoge(hoge&&) {
        std::cout << "ムーブ構築\n";
    }

    template <class T>
        requires (not std::same_as<std::remove_cvref_t<T>, hoge>)
    hoge(T&&) {
        std::cout << "ほかのクラスから構築\n";
    }
};
```
Locust 使ってみた

### はじめに
2024年1月に FLINTERS が設立10周年を迎えるにあたり、FLINTERS 連結社員全員でブログリレーを開催しております。本ブログはブログリレー全133回のうちの14回目で、最近使用した「Locust」というツールについて書いてみたいと思います。
### Locust とは
- 負荷テストツール
- Python でテストシナリオを作成できる
- Web ベースの UI がある
- 名前の由来は、「群がる」習性を持つ昆虫のイナゴから
等
### 実際に触ってみる（簡単な動作確認）
#### 1. インストール
- Locust をインストールします。
  - `pip3 install locust`
#### 2. locustfile.py の準備
- ここでは、helloWorld.html に何回もリクエストを行うよう記載します。
  - ```Python
    from locust import HttpUser, task

    class HelloWorldUser(HttpUser):
        @task
        def hello_world(self):
            self.client.get("/helloWorld.html")
    ```
#### 3. ローカルで Web サーバ起動
- helloWorld.html の用意（以下は一例）。
  - /tmp 直下に mypage というディレクトリを作成します。
  - 「Hello World!」 を表示する helloWorld.html を mypage に格納します。
- Web サーバの立ち上げ（以下は一例）
  - httpd という docker image を pull します。
  - コンテナを作成して起動する際、/tmp/mypage をマウントします。
    - `docker run -d -p 8080:80 -v /tmp/mypage/:/usr/local/apache2/htdocs/ httpd:latest`
  - `http://localhost:8080/helloWorld.html` にアクセスして、「Hello World!」が表示されれば OK です。
#### 4. locust 起動
- locustfile.py が存在するディレクトリに移動し、locust を実行（locust と入力し、enter 押下）します。
- `http://localhost:8089` にアクセスし、Web UI（以下）が表示されたら OK です。
  ![スクリーンショット 2023-09-19 11.16.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557580/449a0605-637e-4320-8394-2cfe0d617471.png)
#### 5. 負荷テスト実行
- Web UI の Host に `http://localhost:8080` を入力し、Start swarming ボタンを押下します。
- 実行状況画面（以下）が表示され、helloWorld.html に大量にリクエストが送られていることがわかります。
  ![スクリーンショット 2023-09-19 11.50.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557580/a8435900-719a-c14e-439e-793d588610d7.png)
- 負荷テストを終了させたいときは、右上の STOP ボタンを押下します。
  - 例えば、環境変数 `LOCUST_RUN_TIME=300s` をエクスポートしておけば、300秒で負荷テストは自動的に終了します。
#### 6. 結果確認
負荷テストを終了させ、Statistics タブ上に表示された結果を確認してみます。
![スクリーンショット 2023-09-19 12.05.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3557580/1aabaf14-9388-ce6f-1385-273bc961f8bf.png)
- Requests【総リクエスト数】：24940
- Fails【fail したリクエスト数】：0
- Median(ms)【レスポンス速度（リクエスト数/ミリ秒）の中間値】：2
- 90%ile(ms)【レスポンス速度（リクエスト数/ミリ秒）の 90 パーセンタイル】：2
- 99%ile(ms)【レスポンス速度（リクエスト数/ミリ秒）の 99 パーセンタイル】：3
- Average(ms)【レスポンス速度（リクエスト数/ミリ秒）の平均値】：2
- Min(ms)【レスポンス速度（リクエスト数/ミリ秒）の最小値】：2
- Max(ms)【レスポンス速度（リクエスト数/ミリ秒）の最大値】：1007
- Average size (bytes)【平均レスポンスサイズ（byte）】：13
- Current RPS【（実行中の最新の）秒間リクエスト数】：414.9
- Current Failures/s【（実行中の最新の）秒間 fail リクエスト数】：0

以上で、簡単な動作確認は終了です。他（自分が独断と偏見で）注目した特徴は以下（その他にも）に記載しました。
### その他にも
- Web UI の `Spawn rate` には、1秒毎に増えるユーザ数（並列実行数）を設定でき、例えば、`Number of users` に10、`Spawn rate` に2を設定すれば、2ユーザで負荷テストが開始され、さらに1秒毎に2ユーザ増加し、最終的に10ユーザによる負荷テストが実行されます。
- Web UI の Download Data タブから、より詳細な結果（CSV）をダウンロードできます。
- 環境変数 `LOCUST_HOST=http://localhost:8080`、`LOCUST_HEADLESS=true` をエクスポートすれば、Web UI を使わなくても負荷テストできます。
- タスク開始時に1回だけ呼ばれる `on_start` メソッドがあり、以下のようにログインや、前もって負荷テスト用の JSON を生成するといった時に使えます。
  - ```Python
    from locust import HttpUser, task

    class HelloWorldUser(HttpUser):
        @task
        def hello_world(self):
            self.client.get("/helloWorld.html")

        def on_start(self):
            self.client.post("/login", json={"username":"foo", "password":"bar"})
    ```
### まとめ
- コードも複雑ではなく、Web UI の使い方も難しくはないので、API の負荷テストを行う際には、この使用のツールを検討しても良いと思いました。
PythonプログラムでExcelとCSVの間で変換する

## はじめに
ExcelファイルをCSV形式に変換することは、スプレッドシートデータをコンマ区切りの純テキスト形式に変換することです。ほとんどのテキストエディタやデータ処理ソフトウェアは、この形式を読み取ることができますので、データ分析やデータ転送が簡単かつ迅速に行えます。必要に応じて、CSVをExcelに変換してデータをより効果的に保存・処理することもできます。
## ツール
* Visual Studio Code
* [Spire.XLS for Python](https://www.e-iceblue.com/Introduce/xls-for-python.html)
このライブラリは、[Excel から PDF への変換](https://www.e-iceblue.com/Tutorials/Python/Spire.XLS-for-Python/Program-Guide/Conversion/Python-Convert-Excel-to-PDF.html)、[Excel の作成と読み取り](https://www.e-iceblue.com/Tutorials/Python/Spire.XLS-for-Python/Program-Guide/Document-Operation/Python-Create-Read-or-Update-Excel-Documents.html)もサポートしています。
## インストール方法
* VS Code で「Extensions」をクリックし、「Python」を検索してインストールします。
* 「Explorer」-「NO FOLRDER OPENED」-「Open Folder」をクリックします。
* 既存のフォルダーをワークスペースとして選択するか、新しいフォルダーを作成することもできます。
* そのフォルダーに「.py」 ファイルを追加し、任意の名前を付けます。
* 「Terminal」-「New Terminal」をクリックします。
* 次のコマンドを入力して、Spire.XLS for Python と plum-dispatch v1.7.4 をインストールします。
```python
pip install Spire.XLS-for-Python
pip install plum-dispatch==1.7.4
```
## コード：
### ExcelからCSVへの変換
```python
from spire.xls import *
from spire.common import *

#Workbookオブジェクトを作成する
workbook = Workbook()

#Excelドキュメントをロードする
workbook.LoadFromFile("sample.xlsx")

#最初のシートを取得する
sheet = workbook.Worksheets[0]

#CSVファイルに変換する
sheet.SaveToFile("ExcelToCSV.csv", ",", Encoding.get_UTF8())
workbook.Dispose()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/198ac7ba-16a0-53df-29eb-0a5a5c8bb671.png)
### CSVからExcelへの変換
```python
from spire.xls import *
from spire.common import *

#Workbookオブジェクトを作成する
workbook = Workbook()

#CSVファイルをロードする
workbook.LoadFromFile("sample.csv", ",", 1, 1)

#最初のシートを取得する
sheet = workbook.Worksheets[0]

#数値をテキストとして表示する
sheet.AllocatedRange.IgnoreErrorOptions = IgnoreErrorType.NumberAsText

#列幅の自動調整
sheet.AllocatedRange.AutoFitColumns()

# Excelファイルに保存する
workbook.SaveToFile("CSVToExcel.xlsx", ExcelVersion.Version2013)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/18daf7f6-5442-31a9-e590-bfc5eaa0942f.png)
【XCode15/Firebase】Info.plist Error Unable to process Info.plist at path ...

# 発生した問題
## 環境
- XCode15（XCode14では再現しない）
- Swift Package Managerでfirebase-ios-sdk(9.0.0)を利用
## 操作
XCodeからReleaseビルドを行う。（Debugビルドでは再現しない）
## 結果
以下のエラーが出力されて、ビルドができない問題が起きました。
```
Info.plist Error Unable to process Info.plist at path /Users.../Info.plist
```
# 解決方法
私の環境では2つの方法で解決することができました。
## 解決方法1： Crashlytics/runの[Input Files]の入力
解決方法はFirebaseのドキュメントに記載されてました。

https://firebase.google.com/docs/crashlytics/get-deobfuscated-reports?hl=ja&platform=ios
```
Crashlytics 実行スクリプトの構成が Xcode 15 以降の新しい要件に対応していることを確認します。構成が最新でない場合、次のエラーが発生する可能性があります。
error: Info.plist Error Unable to process Info.plist at path ...
具体的には、Xcode 15 以降では、より完全なファイルの場所のセットを指定する必要があります。Crashlytics 実行スクリプト（firebase-ios-sdk/Crashlytics/run）が次のように設定されていることを確認します。
1. [Build Phases] タブをクリックし、[Run Script] セクションを開きます。
2. [Input Files] セクションで、次のファイルの場所のパスが設定されていることを確認します。
${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}
${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${PRODUCT_NAME}
${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist
$(BUILT_PRODUCTS_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/GoogleService-Info.plist
$(BUILT_PRODUCTS_DIR)/$(EXECUTABLE_PATH)
```
上記の対応を行ったところ表題のエラーは消えました。
しかし、私の場合は新しく以下のエラーが出力されるようになりました。
```
Cycle inside ...; building could produce unreliable results.
```
このエラーは以下のURLに解決策がありました。

https://developer.apple.com/forums/thread/730974
```
Update: we managed to fix the issue on our end by moving the 'Embed Frameworks' build phase above the 'Run script' build phase(s).
```
Forumに記載の通り、[Build Phases]の[Embed Frameworks]を他の[Run Script]より上の順番にすることでエラーが消えました。
## 解決方法2： [Run Script]を最後尾に移動
以下の方法でもエラーが消えました。

https://developer.apple.com/forums/thread/731059
```
after upgrading to Xcode 15, I had the same error when building. however, after checking my build phase, it turned out the run script was not the last step. so I move the run script to the bottom, then it compiles successfully. it might not suit your situation, post so it may be helpful for others.
```
Forumに記載の通り、XCodeの[Build Phases]でFirebaseの[Run Script]を最後尾に移動させることでエラーが消えビルドが可能になりました。
# おわりに
いずれにしても、[Build Phases]の[Embed Frameworks]と[Run Script]の順番？が関係してるように見えました。
常に最新NVIDIAドライバをダウンロードするスクリプト

# 最新ドライバを知る
NVIDIAが下記のページで常に最新バージョンをアナウンスしてくれている。
ここを利用させてもらいます。
https://download.nvidia.com/XFree86/Linux-x86_64/latest.txt

# 最新ドライバの場所
https://download.nvidia.com/XFree86/Linux-x86_64/
ここからダウンロードできる。

# 上記を踏まえて
```
#!/bin/bash

#wgetをinstall 
#apt,dnf,yumのパッケージ管理には対応
#それ以外は手動でwgetインストールしてください。
apt install -y wget||dnf install -y wget ||yum install wget -y

#最新版情報の取得
ver=$(wget  -O - https://download.nvidia.com/XFree86/Linux-x86_64/latest.txt -q |awk -F " " '{print $1}')
echo $ver

mkdir -p /root/install
#ファイルパスなど指定
URL="https://download.nvidia.com/XFree86/"$(uname -s)"-"$(uname -p)"/"$ver"/"
FILENAME="NVIDIA-"$(uname -s)"-"$(uname -m)"-"$ver".run"
FILEPATH="/root/install/"

#wgetで落とす
wget $URL$FILENAME -O $FILEPATH$FILENAME

#実行権限つけておく
chmod +x $FILEPATH$FILENAME

```
# Pre or Post download
この作業の前後にblacklistやinitramfs updateの実行など必要な操作をしてrebootかけておくと良いです。自分はblacklist登録->initramfs update->ダウンロード->再起動をスクリプトで実行しています。
VanJSでクリックカウンターを作ってみた

## はじめに

先日Youtubeを見ていたら16連射でお馴染みの高橋名人が出てたので、私も連射に挑戦してみたいと思いクリックカウンターのアプリを作ってみました。１０秒の制限時間でクリック数を計測して、１秒間にクリックした回数の平均値が表示されるようにしました。リポジトリは公開しているので、VanJS初学者の方などは参考にしてみてください。

## デモ

ちなみに私の最高記録は8.60です😢

https://vanjs-click-counter.vercel.app/

## リポジトリ

https://github.com/mori-goq/vanjs-click-counter

## コード

```typescript:src/main.ts
import van from 'vanjs-core'

import { useTimeLeft } from './useTimeLeft'

const TIME_LEFT = 10

function App() {
  const { h1, div, p, button } = van.tags

  // クリック数
  const count = van.state(0)
  // 残り時間、アクティブかどうか、スタートとリセットの関数オブジェクト
  const [timeLeft, isActiveInterval, handler] = useTimeLeft(TIME_LEFT)

  // 一秒間にクリックした回数の平均値
  const clicksPerSecond = van.derive(() => {
    return timeLeft.val === 0 ? count.val / TIME_LEFT : 0
  })

  // クリック数と残り時間をリセット
  const handleReset = () => {
    count.val = 0
    handler.reset()
  }

  return div(
    { class: 'click-counter' },
    h1({ class: 'title' }, 'VanJS Click Counter'),
    p({ class: 'text' }, 'Clicks: ', count),
    p({ class: 'text' }, 'Time Left: ', timeLeft, ' seconds'),
    p({ class: 'text' }, 'Average Clicks Per Second: ', () =>
      timeLeft.val === 0 ? clicksPerSecond.val.toFixed(2) : '',
    ),
    div(() =>
      isActiveInterval.val
        ? // アクティブの時はクリックでカウントを増やせるように
          button(
            {
              class: 'action-button',
              onclick: () => count.val++,
            },
            'Click',
          )
        : // アクティブでない時は計測スタートできるように
          button(
            {
              class: 'action-button',
              onclick: () => handler.start(),
              disabled: () => timeLeft.val === 0,
            },
            'Start',
          ),
    ),
    button(
      {
        class: 'reset-button',
        disabled: isActiveInterval,
        onclick: () => handleReset(),
      },
      'Reset',
    ),
  )
}

van.add(document.getElementById('app')!, App())

```

`useTimeLeft.ts`はReactのカスタムフックのようなものです。以前VanJSでカスタムフックを作った記事を投稿したので気になる方は参考にしてください。

https://qiita.com/mori_goq/items/099093d85c4fc71eba20

```typescript:src/useTimeLeft.ts
import van from 'vanjs-core'

export const useTimeLeft = (initialNumber: number) => {
  const intervalId = van.state(0)
  // 残り時間
  const timeLeft = van.state(initialNumber)
  // アクティブかどうか
  const isActiveInterval = van.state(false)

  // 残り時間が0になったら、setIntervalを止める
  van.derive(() => {
    if (timeLeft.val === 0) {
      clearInterval(intervalId.val)
      isActiveInterval.val = false
    }
  })

  // スタート
  const start = () => {
    isActiveInterval.val = true

    // １秒毎に残り時間を減らす
    intervalId.val = setInterval(() => {
      timeLeft.val--
    }, 1000)
  }

  // リセット
  const reset = () => {
    timeLeft.val = initialNumber
    isActiveInterval.val = false
  }

  return [
    timeLeft,
    isActiveInterval,
    {
      start,
      reset,
    },
  ] as const
}
```

## まとめ

VanJSでクリックカウンターのアプリを作ってみました。カスタムフックを作ることで、メインの処理がスッキリしてコードの可読性が上がるのでおすすめです。

## 最後に

### GoQSystemでは一緒に働いてくれる仲間を募集中です！

ご興味がある方は以下リンクよりご確認ください。

https://goqsystem.recruit.site?qiita=6294380a3c66599b195e
インデックス設定でSQLを爆速にしよう

# 始めに
リリースから2年ほど経つシステムのパフォーマンスが悪いという声が入った。
正直、弊社は完全に人員不足で自分が複数の案件を見てるのでそこまで見る余力は無かった
色々調査したらSQLが超絶遅くなってるのが原因でした。

なので今回は自分がSQLを爆速にした時に調べた内容や実際にやったことを共有してみる

何か間違えがあればガンガンご指摘頂けると助かります！


# インデックスとは
タイトルにあると通りインデックスとは何でしょう？
簡単にいうと本の索引です。
私たちが本を読む際に裏面にある目次などを参考にしながら読みたい部分を探すと思う。

こんな感じの
```
オブジェクト思考 ......... 10~20
カプセル化  ............ 21
抽象化 ................ 30
継承 .................. 40
ポリモーフィズム
```
最初から1ページずつ探してたら日が暮れる
SQLも同じで特定のデータを探す際に1から順に探して行ったら効率が悪い
これが数十、数百件ぐらいであれば問題ないけど、数千、数万のデータがあったら話が変わってくる。
私が遭遇したのもまさにこれで、2年が経ち当初想定したデータを上回るデータ量になってた

実はインデックスには複数の種類があり、
- B-treeインデックス
- ビットマップインデックス
- ハッシュインデックス

などのインデックスがある。
今回は実際の実務でSQLを爆速にしたB-treeインデックスについてフォーカスしてみる(B-treeが最も有名なインデックス)


# B-treeインデックス
B-treeインデックスは名前の通り木構造でできていて、リーフノードに実データへのポインタがある。
なので実データが直接木構造で並べられている訳ではない。
この木構造を二分探索のようにしていけば検索データに辿り着くことができそう
さらにB-treeの計算量はO(log n)と非常に高速です。

これについては後ほどどれくらい早いのか説明します

### 二分探索って何？
木構造の頂点から始まり、現在のノードの値と検索対象を比べ、検索対象の方が大きければ右へ進み
小さければ左へ進むというアルゴリズム。これを繰り返すことでお目当ての値に辿り着ける訳だ
例えば30という値を検索する場合、
1. 30は15より大きいので25(右)へ
2. 30は25より大きいので30(右)へ

2回の計算で辿り着くことができた
もちろん10や25であれば1回で辿り着ける
```
        15
       /  \
     10    25
    /  \   / \
   8   12 20  30

```

### B-treeを使わないとどうなる？
では上記の木構造を横並びにしてみるとこんな感じ。
30を探すには15->10->25->8,->12,->20->30とたどる必要があり、6回の計算が必要になる。
これを線形探索と言い計算量はO(n)となり、Nが増えれば増えるほど計算量は増えていく

```
15, 10, 25, 8, 12, 20, 30
```

### O(n)とO(log n)の比較
線形探索はnの大きさに比例して計算量が増えているのに対して、B-treeの計算量の増加数はごくわずかです。
これだけでもB-treeの凄さがわかる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754295/444dcd0d-0567-3397-270e-601a540d4b97.png)


# どこにインデックスを貼るべきか？
インデックスを貼ると処理が高速になることは分かったがどのテーブルのカラムに設定すれば良いのか？それは
**カーディナリティの高い要素**です
一般的には、カーディナリティが高いフィールドにインデックスを設定することで、データベースのクエリのパフォーマンスが向上するといわれている。

例えば
性別が持つ値は男性、女性、その他でカーディナリティは3ということになる。
これはカーディナリティが低いのでインデックスの設定をしても効果が薄いと言える。

逆に顧客の電話番号や口座番号などはかなりの数があることが分かります。
そのようなカラムにインデックスを設定することで効果が爆上がりする


# インデックスを貼ってみる
実際にインデックスを貼るカラムが見つかったら設定する訳だけどとても簡単。
例として、employeesというテーブルはemployee_idというカーディナリティが高いフィールドが存在すると仮定
employee_idにインデックスを貼るためのSQL文は以下の通り
```sql
CREATE INDEX idx_employee_id ON employees (employee_id);
```

また、複数のフィールドを組み合わせてインデックスを作成することもできる。
例えば、last_nameとfirst_nameのフィールドの組み合わせでインデックスを作成したい場合は以下のようなSQL文を発行する
```sql
CREATE INDEX idx_name ON employees (last_name, first_name);
```
上記は**複合インデックス**といって複数のカラムを紐付けたインデックスも設定することができる

これだけでSQLのパフォーマンスは驚くほど向上する。


# 気を付けること
インデックスはやたらに設定しすぎるとかえってパフォーマンス低下リスクがあるので効果的なカラムにインデックスを貼ることを心がける必要がある。
また、B-treeインデックスは追加・削除などの更新作業のパフォーマンスが落ちる。
データが更新されれば、インデックスの値も更新する必要があるからです。


# 感想
実務でもなんとなくSQLを書いて、なんとなく運用していたがそれでは顧客に価値は提供できない。
DBMSはどんな構造なのか？どうやって検索してるのか？計算量は多いのか？少ないのか？
多くのことを熟考し、最適な状態を保ってこそ長く愛されるプロダクトになるんだと思った。
もっと知識を深めて実務で価値提供していきたい
AWS Terraform –  Cloud Watch  Logs のサブスクリプションフィルタ + Lambda連携を Terraform管理

# 概要

Cloud Watch Logs のサブスクリプションフィルタを使うと
ログのパターンを検出してLambdaを起動できる

AWSコンソールからの作り方はCloudWatchのロググループを選んで「アクション」から設定できる

<img width="632" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/f40dd57a-4ab2-4611-bab8-1c959e28dcc8">

これをTerraform管理する

# Terraformのコード例

```tf
resource "aws_cloudwatch_log_subscription_filter" "xxx" {
  name            = "xxx"
  log_group_name  = "/path/to/log_group"
  filter_pattern  = "<フィルタパターン>"
  destination_arn = <LAMBDA関数のARN>
}
```

# エラー

## 不要な指定

> Error: putting CloudWatch Logs Subscription Filter (***********): 
> InvalidParameterException: destinationArn for vendor lambda cannot be used with roleArn

Lambdaを使う場合は role_arn の指定は不要のようだ

```
role_arn        = <ロールのARN>
```

## 権限不足

ログがLambdaを実行できるようにしておく必要がありそう

>Error: putting CloudWatch Logs Subscription Filter (*****************): InvalidParameterException: Could not execute the lambda function. Make sure you have given CloudWatch Logs permission to execute your function.

```tf
resource "aws_lambda_permission" "yyy" {
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.some_lambda.function_name
  principal     = "logs.<REGION>.amazonaws.com"
}
```

# 公式

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_log_subscription_filter#destination_arn


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
react-sortablejsとreact-hook-formで並び替え

# 入力フォームの並び替え

ドラッグ&ドロップで並び替えできるreact-sortablejsとreact-hook-formsを組み合わせた並び替えできる入力フォームの備忘録

サンプルソース

```tsx
import { ReactSortable } from 'react-sortablejs'
import { useFormContext, useFieldArray } from 'react-hook-form'
import Forms from './forms'

const sortableInputs = ()=>{
    const {
        control,
        formState: { errors },
    } = useFormContext()
    
    const { fields, swap } = useFieldArray({
        name: 'contents',
        control,
    })

    const onEnd = (evt:any)=>{
        swap(evt.oldIndex, evt.newIndex)
    }

    return <>
        <ReactSortable list={fields} setList={()=>{}} onEnd={onEnd}>
          {fields &&
            fields?.map?.((field: any) => {
              return (
                <Forms
                  key={field?.id}
                  field={field}
                />
              )
            })
        }
        </ReactSortable>
    </>
}
```

`ReactSortable`ではsetListではなくonEndを使う。onEndではoldIndexとnewIndexがあるので、`useFieldArray`にそもそも備わっているswap()で処理ができる。
elasticacheの更新

# 背景
- elasitcacheのupdateの連絡がAWSからきた
- 重要度が、criticalなので早めに実施したい

# 注意点
- ノードごとにアップデートされるため基本的にはなし
- ただし更新時間中は接続が不安定になりエラーレートが上昇する可能性が高い
# バックアップの作成
- AWS Management Console にサインイン
- ナビゲーションペインで、[Redis] を選択します。
- [Redis clusters] 画面が表示されます。
- バックアップする Redis クラスターの名前の左にあるチェックボックスをオンにします。
- アクション内の[バックアップ] を選択します。
- [バックアップを作成する] ダイアログで、クラスター名に以下を選択する
- [バックアップ名] ボックスにバックアップの名前入力します。バックアップなので日付を入れておくとわかりやすい
- [暗号化キー]はデフォルトを選択
- タグは空欄で問題ない
- [バックアップ] を選択します。
- クラスターのステータスが snapshotting に変わり、ステータスが [available] に戻ることを確認

# updateの実施
- ナビゲーションペインで、[Redis] を選択します。
- [Redis clusters] 画面が表示されます。
- 手動F/Oする 更新するクラスターの名前をクリックします。
- アクション内の[プライマリーをフェイルオーバー] を選択します。
- プライマリのフェイルオーバーのダイアログが表示されるので、プライマリを変更したいノード名か確認して、問題なかった場合「次へ」をクリックします。	
- 「現在のロール」項目にて、入れ替わっていれば完了
	※十数秒で変更完了
MVCについて

## M Model(モデル)
データベース操作に関わる処理を作る

目的：「データ操作をするためのプログラム」を作ること

・データを取得する処理


## V View(ビュー)
画面を表示する処理を作る

目的：画面を表示するプログラムを作る

・取得したデータを表示する
・画面の元となる素材を作る


## C Controller(コントローラー)
目的：ModelとViewの処理をコントローラーが制御して表示させる

1.　Modelに指示を出してデータベースからデータを取得
2.　取得したデータをViewに渡して画面を作成
3.　パソコンの画面にViewで作成した画面を表示する


### MVCを使用するメリット
・役割によってどこに何のプログラムを書くか、ルール化された開発方法の一つ
・役割に分けて管理し、「開発のしやすさ」＋「コード確認のわかりやすさ」を両立できる


### MVCを使用しないデメリット
・一つのプログラムに、すべての処理を書いてします可能性がある
・追加機能を開発するときに変更箇所を調べることに時間がかかる
[001] RC回路のステップ応答~ラプラス変換(積分形)~

tex記法とMarkdown記法の練習を兼ねて，図1のRC回路のステップ応答を求めてみる．

```plantuml
@startuml
<style>
root {
  Padding 0
  Margin 0
}
title {
  FontStyle normal
  FontColor black
  FontSize 20
}
</style>
title
<img:https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615014/6cb7dffb-d65f-cb9d-4fea-8eec094afcff.png>
図１ RC回路
end title
@enduml
```

キルヒホッフの電圧則より，
$$E=Ri(t)+\frac{1}{C}\int i(t) dt$$

$\mathcal{L}[i(t)]=I(s)$として，両辺をラプラス変換すると，

$$\frac{E}{s}=RI(s)+\frac{1}{C}\left [ \frac{I(s)+q(0)}{s} \right ]$$

コンデンサの初期電荷はないものとして（すなわち$q(0)=0$として），$I(s)$について式を整理すると，

$$I(s)=\frac{E}{s} \cdot \frac{1}{R+\frac{1}{sC}}=\frac{E}{R} \cdot \frac{1}{s+\frac{1}{RC}}$$
逆ラプラス変換で$i(t)$を求めると，

$$\therefore i(t)=\mathcal{L}^{-1}[I(s)]=\frac{E}{R}e^{-\frac{1}{RC}t}$$

コンデンサCの電圧$v_o(t)$は，
$$v_o(t)=\frac{1}{C}\int i(t)dt=-Ee^{-\frac{1}{RC}t}+C$$
$v_o(0)=0$であるから，積分定数$C$は，

$$v_o(0)=-Ee^{-0}+C=0 \to C=E$$
<!-- コメントアウトしたい内容 -->
<!-- 
$$v_o(0)=-Ee^{-0}+C=0 \to C=E$$
-->

したがって，
$$\therefore v_o(t)=E\left(1-e^{-\frac{1}{RC}t}\right)$$

電流$i(t)$と電圧$v_o(t)$を再掲すると，

```math
\begin{align}
i(t)&=\frac{E}{R}e^{-\frac{1}{RC}t} \\
v_o(t)&=E\left(1-e^{-\frac{1}{RC}t}\right)
\end{align}
```
JavaScriptのmapメソッドは、オブジェクトの複数のkeyを指定して、valueにアクセスできる

分かる人には当たり前ですが、mapメソッドはオブジェクト型のデータもループを回すことができます

```js
const kvArray = [
  { key: 1, value: 10 },
  { key: 2, value: 20 },
  { key: 3, value: 30 },
];

const reformattedArray = kvArray.map(({ key, value }) => ({ [key]: value }));
```
結果
![スクリーンショット 2023-09-19 15.55.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492674/e890afd5-a3b6-b2e7-e547-c817fdf1ab23.png)

このように、オブジェクトの複数のkeyを指定して、valueにアクセスする事ができます。

よく使うやつはこれです。
![スクリーンショット 2023-09-19 15.59.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492674/aa0df2e2-ac6c-3615-0240-f95d2dec5d58.png)

単純に配列の中であるデータを一つずつ取り出すやつです。

配列そのものや、index番号も引数で取れます。
![スクリーンショット 2023-09-19 16.00.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492674/7aab8b1e-6d75-5545-b81f-6e3ca88d1012.png)
【vba】お手軽だけど実践的なpingの使い方を公開してみた！

## 結
クラスCの全てのIPアドレス（192.168.255.1～192.168.255.255）にpingをし、どの端末が接続しているか確認しました。
![p1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332884/60134ef2-9033-1fdd-2f76-724912aa7275.png)

## 起
確認したいネットワークがクラスCって所まで分かっているけど、
どの端末が接続しているか分からない場合、皆さんならどうしますか？

## 承転
私の場合コードで解決する事にしました。
```
Sub main()
Call stop_display
Call try_ping
Call start_display
End Sub
```

```
Sub try_ping()
    ' セルからIPアドレスを順に取得してping送信
    For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row
        Application.StatusBar = "*** 処理中...(" & i & "/255) ***"    
        Dim wsh As Object: Set wsh = CreateObject("Wscript.Shell")
        Dim host As String: host = Cells(i, 1).Value
        
        Const sendCount As Long = 1 '実施回数
        Const timeOut As Long = 100 'タイムアウトまでの秒数
         
        Dim cmd As String: cmd = "ping -n " & sendCount & " -w " & timeOut & " " & host
        Call_CheckPing = wsh.Run(cmd, 7, True) = 0
            
        'Pingが届いたらTrue/届かなければFalse
        If Call_CheckPing = False Then
            Cells(i, 2).Value = "失敗"
        Else
            Cells(i, 2).Value = "成功"
        End If
    Next
    Application.StatusBar = False
End Sub
```

```
Sub stop_display()
    Application.ScreenUpdating = False '画面更新をOFF
    Application.Calculation = xlManual '自動計算をOFF
    Application.EnableEvents = False 'イベントをOFF
End Sub
```

```
Sub start_display()
    Application.ScreenUpdating = True '画面更新をON
    Application.Calculation = xlAutomatic '自動計算をON
    Application.EnableEvents = True 'イベントをON
End Sub
```
## 結
今回のポイントは以下の3点です。
- 画面の更新を停止させ、処理を高速化している点
- ステータスバーに現在何行目を処理しているか表示させている点
- 条件書式で「成功」が見やすい点

## 備考（条件書式）
B列選択後、
ホーム→条件書式→セル強調→文字列
![p2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332884/a37123c1-8180-53dd-cdf2-b9f5d30a8c7e.png)
Open-interpreter（Code-Llama）をDockerで構築し、GPU(NVIDIAのCUDA)で動かす方法。

Open-interpreterは便利だが、GPT4のAPIを叩きまくったらとんでもねー金額になったずら。

ということあると思います。

せっかくGPU（グラボ）持っているなら、ローカルでサクサクと無料で動かせる、Code-LlamaでOpen-interpreterを動かしたい。


ということあると思います。

でも、ローカルでOpen-interpreterを動かしたら、手の施しようがないくらい環境がぐちゃぐちゃになってしまった。

ということあると思います。


そこで今回はDocker（コンテナ型の仮想環境）をつかって、ぐちゃらない方法を模索します。


→流れ

1.Dockerのインストール

2.Dockerfileの作成

3.Dockerイメージの作成

4.Dockerコンテナの作成

5.DcokerでGPU処理できる環境の構築　←いまここ

6.Open-interpreterをインストール

7.やったぜ！お金を気にせずコーディング


という妄想をしたのですが、私にはよくわからなかったので頭のいいひとはコメントください。

■いまの環境

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473778/ea307de6-251d-ab50-92de-3536885e87da.png)

GPU RTX3080

（コンテナの中身）
anaconda version 1.11.3
Python 3.11.3

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473778/91d567c4-4990-8059-725d-c23fc9d311bc.png)

まぁ、よくわからないけど動くプログラムがあふれる時代が来るのでしょうきっと。しらんけど。


English

Open-interpreter is useful, but I got a ton of money when I started hitting all the GPT4 APIs.

I'm sure there are times when this is the case.

If you have a GPU, you want to run Open-interpreter with Code-Llama, which can be run locally.

But if you run Open-interpreter locally, the environment is so messed up that you can't do anything about it.

I'm sure there are times when you want to run Open-interpreter locally.


This time, we will use Docker (containerized virtual environment) to find a way to avoid messy environment.


→Flow

Install Docker

Creating Dockerfile

Creating a Docker image

4. Create Docker container

5.Create GPU processing environment with Dcoker ←here we are now

6.Install Open-interpreter

7. We did it! Coding without worrying about money


Current environment

img

GPU RTX3080

(Container contents)
anaconda version 1.11.3
Python 3.11.3

Well, there will probably come a time when there will be a lot of programs that work even though we don't know what they are. I don't know.
基本情報対策：小学生でもわかる？有向グラフとトポロジカルソート

基本情報の勉強をしていますが、有向グラフとトポロジカルソートの処理が全くわかりませんでした。

そのため、GPTさんに説明してもらいました。

## いきなり結論

自分に向かう矢印が0の文字から処理をして、配列に代入したらその文字を消します。

すると、また0になる文字ができるのでそれをマタ代入することを続けます。

いまいちわかっていませんが、

今回は
`CABDEF`

となりましたが

`ACBDEF`

ともなるようです。

～～～追記～～～
もっとありました
以下は可能なトポロジカルソートの結果です：

Aから始める場合:

A, C, B, D, F, E
A, C, B, F, D, E
A, C, B, F, E, D
など
Cから始める場合:

C, A, B, D, F, E
C, A, B, F, D, E
C, A, B, F, E, D
など
～～～～～～～～

### 有向グラフ:下記の関係性を持つグラフとする。

```python
A -> B -> F -> E
     |    
     v
     D -> E
     ^
     |
     C
```

### 処理順

**入次数の初期状態**

```makefile
A: 0
B: 1 (Aから)
C: 0
D: 2 (BとCから)
F: 1 (Bから)
E: 2 (DとFから)
```

**初期キューの作成:**

入次数が0のノードをキューに入れます。この場合、ノードAとノードCが入次数0です。

```less

キュー: [C, A]
```

**トポロジカルソートの実行:**

1. キューからノードCを取り出し、結果のリストに追加します。

```less

ソート結果: [C]
キュー: [A]
```

ノードCから出ている辺を探し、その辺の目的地の入次数を1減らします。ノードCからはノードDへの辺がありますので、ノードDの入次数を1減らします。

```makefile

Dの入次数: 1 (2から1に減少)
```

1. キューからノードAを取り出し、ソート結果のリストに追加します。

```less

ソート結果: [C, A]
キュー: []
```

ノードAから出ている辺を探し、その辺の目的地の入次数を1減らします。ノードAからはノードBへの辺がありますので、ノードBの入次数を1減らします。

```css

Bの入次数: 0 (1から0に減少)
```

入次数が0になったノードBをキューに追加します。

```less

キュー: [B]
```

1. キューからノードBを取り出し、ソート結果のリストに追加します。

```less

ソート結果: [C, A, B]
キュー: []
```

ノードBから出ている辺を探し、その辺の目的地の入次数を1減らします。ノードBからはノードDとノードFへの辺がありますので、これらのノードの入次数をそれぞれ1減らします。

```makefile

Dの入次数: 0 (1から0に減少)
Fの入次数: 0 (1から0に減少)
```

入次数が0になったノードDとノードFをキューに追加します。

```less

キュー: [D, F]
```

1. キューからノードDを取り出し、ソート結果のリストに追加します。

```less

ソート結果: [C, A, B, D]
キュー: [F]
```

ノードDから出ている辺を探し、その辺の目的地の入次数を1減らします。ノードDからはノードEへの辺がありますので、ノードEの入次数を1減らします。

```makefile

Eの入次数: 1 (2から1に減少)
```

1. キューからノードFを取り出し、ソート結果のリストに追加します。

```less

ソート結果: [C, A, B, D, F]
キュー: []
```

ノードFから出ている辺を探し、その辺の目的地の入次数を1減らします。ノードFからはノードEへの辺がありますので、ノードEの入次数を1減らします。

```makefile

Eの入次数: 0 (1から0に減少)
```

入次数が0になったノードEをキューに追加します。

```less
lessCopy code
キュー: [E]
```

1. キューからノードEを取り出し、ソート結果のリストに追加します。

```mathematica

ソート結果: [C, A, B, D, F, E]
キュー: []
```

ノードEから出ている辺はありませんので、入次数の処理は行いません。キューは空になり、ソートされていないノードもなくなりましたので、トポロジカルソートは完了です。

**最終結果**:

```mathematica

[C, A, B, D, F, E]
```

この手順を通じて、与えられた有向グラフに対してトポロジカルソートを行い、結果として**`CABDEF`**の順序を得ることができました。

くそめんどい。
Express+EJS備忘録

node.jsがインストールされている前提としています。

# Express使い方の例

プロジェクト用のフォルダを作成し、そのフォルダに移動して、にてプロジェクトを作成します。
```terminal
npm init -y
```

Expressをインストールします。
~~~terminal
npm install express
~~~


プロジェクトのルートフォルダに以下のようなindex.jsファイルを作成します。
~~~index.js
let port = 3000;    //ポート番号
let express = require("express");
let app = express();
let ht = "<html><body>Express練習<body></html>";

// localhost:3000にアクセスした場合
app.get("/",function(req,res){
    //HTTPヘッダーを指定する場合
    res.append("Content-Type", "text/html");
    res.send(ht);
});

let js = {"name":"名前","type":"タイプ"};
// localhost:3000/json にアクセスした場合
app.get("/json",function(req,res){
    res.append("Content-type", "application/json");
    res.send(js);
});

let listener = app.listen(port,function(){
    console.log("port:" + port);
});

~~~
コマンドラインにてサーバー起動します。
~~~terminal
node index.js
~~~
ブラウザにて
localhost:3000
localhost:3000/json
にそれぞれアクセスします。以下のように出力されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3536745/41e3dfbd-2e6e-2345-edc2-c6c9490922df.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3536745/161e3af9-dd04-e5c2-8e11-5881558a9902.png)

# EJSを使って変数出力の例
新たにプロジェクト用のフォルダを作成し、そのフォルダに移動して、にてプロジェクトを作成します。
プロジェクトの初期化、expressパッケージ、ejsパッケージをインストールします。
```terminal
npm init -y
npm install express
npm install ejs
```
プロジェクトのルートフォルダにindex.jsを以下のように作成します。
```index.js
let port = 3000;    //ポート番号
let express = require("express");
let app = express();
app.set("view engine", "ejs");  //テンプレートエンジンの指定

let toEjs = {asa : "うどん",
             hiru : "そば",
             ban : "ラーメン",
             html : "<b>太文字</b>",
             num : 2,
             sakana:["アジ","鯖","ハマチ"],
            };

app.get("/",function(req,res){
    res.render("index.ejs",toEjs); 
});

let listener = app.listen(port,function(){
    console.log("ブラウザにてlocalhost:" + port + "にアクセスしてください");
});
```
ejsファイルをプロジェクト内のviewsという名前のフォルダ内に作成します（デフォルトでviewsフォルダを参照します）。ここではindex.ejsというファイル名で作成しています。

~~~　配置について.
・ プロジェクトフォルダ
・ index.js
・ viewsフォルダ
    ・index.ejs
~~~

~~~index.ejs
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <h1>パラメータの出力</h1>
        <%# このタグでコメントアウト%>
        <%= asa %><br>
        <%= hiru %><br>
        <%= ban %><br>
        <%= num %><br>
        <%= sakana %><br>
        <br>
        <h1>エスケープ処理なしでの出力</h1>
        <p><%- html %></p>
        <br>
        <h1>条件分岐の例</h1>
        <% if(num % 2){ %>
            <p>numは奇数</p>
        <% } else { %>
            <p>numは偶数</p>
        <% } %>
        <br>
        <h1>繰り返しの例</h1>
        <ul>
        <% for(let e of sakana){ %>
            <li><%= e %></li>
        <% } %>
        </ui>
    </body>
</html>

~~~

サーバー起動して、ブラウザにてlocalhost:3000にアクセスします。
~~~terminal
node index.js
~~~

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3536745/12dc6bed-24ae-d6c5-61da-73bbdbddfe6b.png)
エキサイトの Booost!!! 5daysインターンシップに参加してきた話

エキサイトの Booost!!! 5daysインターンシップに参加してきました！

![PXL_20230906_004634411.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3143089/d720fe2c-d163-20a8-d0ed-6dd6731bb49f.jpeg)

インターンの内容を振り返りつつ、行ったことや感想などを記事にします！

# インターン概要

Booost!!!はエキサイトがリリース する/している サービスが抱える課題に対して、インターン生でチームを組んで5日間で解決していくというインターンでした。

私がアサインされた課題は、経営管理クラウドサービスに実装されているChatGPTを活用したAIアシスタント機能の精度向上が主題でした。

# インターン詳細

AIアシスタント機能は、

1. ユーザーが質問文を送信
2. Lambda上で動くPythonアプリケーションが質問文を受け取り、その内容とDB情報をOpenAIのAPIに送信する
3. OpenAIのAPIにあるGPTモデルからクエリ文が返却される
4. そのクエリを元にDBへ計算を依頼する
5. DBから計算結果が返却される
6. 得られた結果をユーザーへ出力する

という流れになっていました。

AIアシスタント機能の流れ↓
![mermaid-diagram-2023-09-19-112355.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3143089/fcb45bb5-b82a-ce6a-b238-87643f828162.png)

実際はもっと複雑なプロセスがありますが記事では省略しています。

GPTは計算が苦手なので、クエリ文を出力してもらいDBで計算を行っていました。

予めインターンの課題として、ユーザーから想定される6つの質問文が用意されていました。
例: 2022年度のXXXの広告収入の前月比を月ごとに教えてください

これらの質問文に対する正答率を基準に精度向上を行いました。

## プロンプトエンジニアリング

基本的にインターンでは、精度向上のためにプロンプトエンジニアリングを行いました。

### Few-Shot Learning

複雑な計算をさせるクエリ文を出力させることは難しく、それを解決するためにFew-Shot LearningとしてSQLのテンプレートをプロンプトに記述するようにしました。

その結果、安定してテンプレートに沿ったクエリ文を出力するようになりました。

### システムプロンプトの導入

既存の実装でユーザープロンプトに書いてあるいくつかの条件を、システムプロンプトに移行しました。

ある質問文の正答率がどうしても改善せず、ユーザープロンプトに条件を追記しても不安定だったため、システムプロンプトに移行した結果、安定して指示通りのクエリ文を出力できるようになりました。

システムプロンプトは最初に読み込まれて、人格や役割を与える重要なプロンプトであり、そこに条件を書くことでユーザープロンプトで記入するよりも、条件の重要度が上がっているのではないかと考えています。

また、トークン消費量を考えた際に、ユーザプロンプトで毎回条件を書いていると、その分のトークンが消費されてしまいます。
しかしシステムプロンプトであれば最初の文章だけなので、会話が増えても同じ記述が発生しなくなり、トークン数を節約できるという副次効果を得ることができました。

注意点として、システムプロンプトによくある人格を与えるプロンプト（例：「あなたはSQLに精通したDBAです」）は誤った内容が返される傾向にありました。そのため、「問い合わせに対して最適なSQLを提示することができます」といった、役割のみを明確にするプロンプトのみを採用しました。

6つの質問文に対して各10回ずつテストを実施した結果、97%の精度で正しい内容が返却されるようになりました。

## シェルスクリプト

ローカル環境を整えていた際に、デバッグ実行で時間がかかっていることに若干のストレスを抱えていました。
既存の実装ではPythonコード内にて、質問文の箇所を一回一回変更してテストしなくてはいけませんでした。

そこで質問文をコマンドライン引数からも受け取れるようにして、簡単に質問文を変更できるようにしました。

コマンドライン引数が使用できるようになったことで、
シェルスクリプトから質問文を配列にしてforループ実行ができるようになりました。

ですが、ただforループ実行してしまうとGPT4のレスポンスが遅いため、何分も待つ羽目になりました。
この問題を解決するために、プロセス毎にバックグラウンドで実行して並列処理を行うようにしました。

一つの質問に対する繰り返し実行数も定義できるように実装していましたが、あまりにも大きい数字だとGPTの Rate limits エラーになってしまうため、Rate limitsに届かないように計算を行ってからから並列処理を行うように実装しなおしました。

結果的に並列処理を用いて大体3.86倍の高速化に成功しました(core数が4だったから？)。
またログファイルを作成するようにしたことで実行結果を簡単に比較できるようになりました。

## 他に

他にも以下のような内容をチームで行いました。

- 計算結果の出力をマークダウンで表形式にして描画
- 過去のトークン使用量を元にあと何回分会話ができるか計算して描画
- テンプレートを使わない汎用的なシステムプロンプトの考案
- ユーザーからの質問文にてEmbeddingを活用した部門名のあいまい検索

# 苦労した点

プロンプトエンジニアリングでは、正解が決まっておらず、少し言い回しを変えるだけで全く違った結果になるので中々苦労しました。

仮説・検証・考察のサイクルを回したかったですが、一流の研究者ですらLLMの完璧な仕様がわからないため、はたして仮説や考察が正しいのかわからず、ずっとモヤモヤしていました。

最終的にはあまり深く考えることをやめて、少しずつプロンプトを変更してひたすら実験回数を増やすことにしました:innocent:

# 感想

チームメンバーがとっても面白い方々で、5日間ずっとおもしろおかしく課題に取り組むことができました！

最終日になんとメッセージ付きの修了証をいただけました。
形に残るものが頂けたのはとても嬉しかったです！飾ります！

![PXL_20230909_005409172.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3143089/7227d1eb-99e7-5fd3-acae-d0976ea1b6a7.jpeg)
※個人情報が入っている部分は黒塗りしてます

# おわりに

チームメンバーが多様なバックグラウンドで面白く優秀な人ばかりで楽しく様々な学びを得ることができました。
一緒に開発していただいたお三方、ありがとう！

チームメンターさんをはじめ、他のサポーターのみなさま、人事のみなさまには大変お世話になりました！
ありがとうございました！！
Power Appsで縦横両方スクロールできるようにした

# はじめに
本記事は、以下の記事を参考にしています。
個人的に難しかったところがあったので、記録として残そうと思います。
執筆者さん、ありがとうございました！おかげでなんとか実装できました。

https://qiita.com/taku_maru/items/3cc86cab108ad7f32826

# やりたいこと
- PowerAppsのギャラリーで縦スクロールはできるけど横にもスクロールしたい
- 項目名も一緒にスクロールさせたい

# こまったこと
- スクロールバーが正しく表示されない(一番端までいってもバーの終わりが見えない)
- 表示させたい項目が多くあるのに、正しい位置における項目が少ない
- そもそもギャラリーとコンテナーのサイズをどうしたらいいのかわからない



# 結論
垂直コンテナーの中に、水平コンテナーと空の垂直ギャラリーを入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2217543/85e79160-110a-1e47-b44f-16fd27eb94f4.png)

## 垂直コンテナー
水平方向のオーバフローを「スクロール」に変更。
幅は後述の水平コンテナーとギャラリーより小さくなるように。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2217543/b902ed64-4877-2b75-36d5-16aac998c158.png)

## 水平コンテナー
各項目の見出しを格納しています。
幅は好きなところまで。結構大きい数字でも大丈夫でした。
コンテナー内に配置を「カスタム」に変更。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2217543/99b4fd26-7299-0770-c23e-47f835a65322.png)

## 空の垂直ギャラリー
データソースはSharePointリストから選択。
幅は<b>水平コンテナーと同じ</b>にします。
コンテナー内に配置を「カスタム」に変更。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2217543/a32f27cb-a163-f782-c067-0cae9c9fe45f.png)

テンプレートの高さはTemplateSizeで変更可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2217543/93249742-b7df-a880-8a77-6c05fcdbf3b2.png)

PowerApps(タブレットサイズ)の縦幅は768(たぶん)です。
そこからいろいろ計算して、見出しを入れたいコンテナーとギャラリーの高さを決めると良さそうです。




# 細かい設定



各項目の位置は1つ前の項目のX座標+幅で書いた方がいいです。
もちろん手で移動させることもできるのですが、途中で移動できなくなります。(X=1366が限度？)

↓見えない壁に阻まれている様子
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2217543/7099b513-6253-0667-cd2f-65c459918699.png)

関数で書くと突破できちゃう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2217543/64d18493-ad32-5c6d-ef79-a6076ff23601.png)

かなり小ネタですが、罫線を引きたい場合は四角形を選択し、ギャラリーの中に貼り付け、
高さを1、幅をギャラリー幅にすればいい感じになります。
貼り付けるときはギャラリー内のなにか(コメント、馬名など)の3点リーダを選択して貼り付けをすると上手くいきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2217543/17d9ae87-9890-0a70-b3ea-3b9a06dfeb1d.png)



実際に動かすとこんな感じになります。
![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2217543/4c2ae7af-c190-3bb3-805e-878b923ae69c.gif)
GA-H81M-D3V-JP の Secure Boot を Enable/Disable にする

　GIGABYTE の M/B である GA-H81M-D3V-JP の Secure Boot を Enable / Disable に変更するには、BIOS が少し困った仕様になっています。知らないと、変更できないのではないかと思ってしまいます。しかし、Driver のインストール時などに、"Secure Boot" を 有効 / 無効 にしなければならないなど、必須の設定です。ネットを調べてみても「色々いじっている内に、項目が増えた」などと、ヒントとなる情報しか見当たらないので、正確なところを残しておこうと思います。

::: note info
この GA-H81M-D3V-**JP** という M/B は、GIGABYTE の GA-H81M-D3V の Mouse Computer 向け OEM 品です。Dual Bios や、USB3.0 の端子数など、機能を犠牲にせずに、コスト削減につながるような改変がさせています。
:::

### 1.Secure Boot 項目を表示する

　BIOS の "Windows 8 Features" を、"Other OS" 以外に設定すると、"Secure Boot" の設定項目が現れます。

※画面一番下の項目

![GA_H81M_D3V_JP_SECUREBOOT_ENB.jpg.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1486355/7276a14c-40c4-8224-49a5-6ac28e0a01a1.jpeg)

### 2.Secure Boot 項目を非表示にする

　なぜ設定項目を消さなければならないのか、有意な理由は見いだせませんでしたが、BIOS の "Windows 8 Features" を、"Other OS" に設定することで、"Secure Boot" の設定項目を非表示にすることができます。

![GA_H81M_D3V_JP_SECUREBOOT_DIS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1486355/88ed8d0f-197f-a70b-548c-78697b6e4114.jpeg)

**以上**

<BR>
<BR>
<BR>
<BR>
<BR>
<BR>
【体験記】株式会社エイチームの5daysインターンに参加した話

## 記事の概要

本日、5daysインターンが終了したので、5日間という短い期間の中で何をしたのか、どのようなことを学んだのか、エイチームに向いていそうな人について書きました。

https://www.a-tm.co.jp/recruit/news/39388/

![DSC_1700.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2989040/5f11869b-caa9-b26d-8880-81028cb91c5f.jpeg)

## なぜエイチームのインターンに？

サポーターズの`エンジニアサマーインターンExpo`にエイチームが出展していたことや、私自身、生まれも育ちも名古屋であり、エイチームという名前はよく見聞きしていたことがきっかけです。

また愛知県の特徴としてTOYOTAをはじめとした製造業が強いため、組み込み系の就職先で埋め尽くされていることもあり、東海地区で一番大きいWeb系で働くことができるのは、ここ以外にほぼないことも挙げられます。

最後に **「エイチームに向いている人」** にもありますが、`Ateam People`という内容が現在取り組んでいることと鑑みると、私に合っている企業かなと感じたことも一因です。

## エイチームライフデザインで何をしてた？

以下は、最初に書いてあった内容ですが目安だと思ってください。（day2~day4までは1日で終わったり、色々します）

- **day 1**:「ビジネス・組織・プロダクトの理解を深めよう」
    - オリエン
    - 環境構築
    - ゴール設定
- **day 2**:「issueを作ってみよう」
    - 調査をしたり、関係者にヒアリングをして課題設定・仮説立てをしてみよう
- **day 3**:「設計」
    - issueを実現するためのアプローチと具体的な変更内容を設計しよう
- **day 4**:「開発」
    - 設計に合わせて開発してみよう
- **day 5**:「ふりかえり」
    - インターン全体の振り返りと設定したゴールに対して自己評価を記載
    - メンターとのFB面談
    - お片付け


今回は、Webデザイン＆フロントとして、issueに上がっていた課題について、ヒアリングをしたり、コードを追加修正しながら、最後にメンターさんやチームの人にレビューをしてもらう流れでした。

自分が実装したいことについて、調べて出てこなかったからchatGPTに出力してもらったやつ↓↓↓

https://qiita.com/mabupro/items/7b629601eab59cf0ac3d

Gitコマンド編、実際にインターンに参加する前に遊んでみるのをオススメします！↓↓↓

https://qiita.com/mabupro/items/d1d1be303004fd8151e3

## 学んだこと

#### Windows選択するのはやめとけ

ここに関しては、インターン初日に思いました。エイチームに限らずMacで開発をしていることが多いです。Windowsで環境構築するとCRLF（よく文字化け起こすやつ）などが起き、WSLを導入しないといけなくなるので、触ったことなくても**Mac**を選択することをお勧めします。（選択は、面接などの期間中にメールできます。）

**ここに実際に行った対応を載せておきます。↓↓↓**

https://qiita.com/mabupro/items/c10974df2bae7cc78bde

#### 自身の意見（責任）をもって開発すること

私は今まで、開発といえば顧客⇔エンジニア（顧客が選ぶ）のような受託開発的なイメージを持っていました。
そのようなイメージで、今回は、カスタマーサービス部で上がっていた問題に対しても、解決策を5つ出してメンターさんに相談した時に、「確かに、いい案だと思うけど（私の名前）君にとって一番推したい案はどれかな？」と言われました。
私は、その時に「自分で決めていいの？！」と思いました。私の考え的には、カスタマーサービス部の代表の人に選んでもらったり、組み合わせて貰う予定だったので、驚きました。
メンターさんによると、エイチームのエンジニアの働き方は提案ベースでも「自分がこのように実装します！」など **「自分の意見を１つ持っておく」** ことが必要だと言われました。相手に判断を委ねるのではなく、自分がこうしたいんだ！という考えを持つことが大事ということですね。
その後は、私がこのように実装したいですbefore-afterやその理由も添えてメンターさんに相談したりしました。

自分自身で決めるということは、ハッカソンの内輪のチームだけの話だと考えていたので、このような働き方ができるのは、エイチームの魅力うちの１つかなとも思いました。

#### 未知のバグとの遭遇と解決策

未知との遭遇系のタイトルですが、つよつよ系のエンジニアでもない限り、入ってすぐの会社やアプリのシステムというのは難しいものです。実際にバグや修正部分として挙げられている、該当コードを探す所から始まります。正直ここが一番きつい所ではあった。頑張って検索機能を使って探したり、メンターさんの手が空いてそうだったら頼んで一緒に探してみましょう！

そして該当コードを見つけた時に、自分が分かる範囲なら修正してみましょう。分からなければ、調べてみて同じような問題が発生しているサイトや、**公式ドキュメント**を検索しましょう。

それでも解決策が載っていない場合もあります。そういう時は、課題のどこが実際の問題点なのか（多分ロジカルシンキングというやつ）を考えてみましょう。これで意外と解決できることが多いです。（そもそも論）

#### レビューしてもらって、リリースされるのはうれしいね(><)!

今まで、個人開発や友達との2人での開発が主な開発経験だったので、レビューされるということがドキドキしたし、リリースされて実際に使える状態になっているのは、自分がやったことが反映された～という嬉しい気持ちです。

また内定者アルバイトの方が同じチームにいて、様子をみるとまたレベルが上がっていたので、そのような業務やコードを書くと、レビューは厳しくなったりするのかなぁとも思ったりします。

## どのような人がエイチームに向いてそうだと思ったか

- 自分でやりたいことをどんどん言える人
- 業界知識も知りながら開発したい人
- 他業種の人と混ざって開発したい人

詳しくは`Ateam People`を読んでみてください。

https://www.a-tm.co.jp/about/philosophy/


## 最後に

私にとって初めてのインターンでしたので、学ぶことがとても多い経験（ここに書いていないことを含む）になりました。その中でも開発以外の能力でソフトスキルと呼ばれる能力を高めることが、新卒として働く上でとても重要になることは、身に染みてよく分かった。

また、他のインターンにも参加できたらまた、エイチームの働き方の魅力が更にわかってくると思うので、自分に本当に合っている働き方や企業風土なのかを考えながら、就職先を検討したいと思います。

**P.S** インターンに来た人は、ぜひ滑り台を滑ってみてください（笑）結構スピードでます。
VisualStudio.Extensibilityを用いて拡張機能を作ってみた

# VisualStudio.Extensibilityを用いて拡張機能を作ってみた

## はじめに

[前回記事](https://qiita.com/mngreen/items/d712930b5894aa6ea17f)でVisualStudio.Extensibilityという作り方の導入を紹介しました。
その後もちょくちょく触り、最低限元々やりたかったことは形になってきましたので、成果の共有も含めてご紹介しようと思います。

ただ、配布方法などもわかっておらず、デバッグでしか動かせないです。。。公式ドキュメントにも紹介されていないのですが、詳しい方がもしいらっしゃれば教えていただけると幸いです。

## やりたいこと

デバッグ中のアプリがあったら強制終了→ビルド→デバッグ実行をワンクリック・ワンコマンドで実行、です。

WPF開発をしているとデバッグ中に見た目やロジックをいじったりした後に、デバッグを停止→ビルドして実行、ということをよくします。実質2ステップではあるのですが、それが一発でできたら楽だな～と思ったのがきっかけです。
あと、デバッグなし実行で動かしているのを忘れてビルドしようとしたら裏でプロセスを掴んでいてビルドに失敗することもあります。
アプリの規模が大きくなるほどビルドに時間がかかるので、一発で確実に動かせるのは個人的にかなり助かります。

## 試作中の拡張機能

以下が作成中の拡張機能です。
<https://github.com/niimima/MySampleExtension/tree/main>

[Force Debug]コマンドを実行することで、やりたいことの一連の動きをやってくれます。ただ、かなり穴だらけのプログラムなので思わぬ挙動になる可能性もありますのでご注意ください。
![Animation5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452291/8ce808a0-6087-446f-ac72-f5a8980fd2e8.gif)

## 拡張機能を作るにあたり学んだこと

### ショートカットキーを利用する

上記のGIF画像ではメニューから実行していましたが、ショートカットキーからも実行できます。既存のショートカットキーと重複すると動かないようでしたので、自分は[LeftAlt]+[F5]キーで動かせるようにしました。

以下のURLに示す通り、CommandConfiguration の Shortcuts プロパティに設定することでショートカットキーを設定できました。
<https://github.com/niimima/MySampleExtension/blob/main/src/MySampleExtension/MySampleExtension/ForceDebugCommand.cs#L39>

### プロジェクトから情報を取得する

VisualStudio.Extensibility ではクエリを用いてプロジェクトから取得したいパラメータを指定します。プロジェクト名やパス、ファイル名などなどいろんな情報が取得できるようです。
<https://github.com/niimima/MySampleExtension/blob/main/src/MySampleExtension/MySampleExtension/ForceDebugCommand.cs#L55>

APIでできることには以下に整理されています。が、正直自分にはいまいち理解しきれていないです。。
<https://learn.microsoft.com/ja-jp/visualstudio/extensibility/visualstudio.extensibility/project/project-concepts?view=vs-2022>
<https://learn.microsoft.com/ja-jp/visualstudio/extensibility/visualstudio.extensibility/project/project?view=vs-2022>

### ソリューションから情報取得・コマンド実行

以下ではプロジェクトから情報を取得するのと同様の方法で、ソリューションからも情報を取得できます。
<https://github.com/niimima/MySampleExtension/blob/main/src/MySampleExtension/MySampleExtension/ForceDebugCommand.cs#L85>

また、ビルドやデバッグの実行なども実行できます。ただ、コマンドを実行するにはQueryableに変換する必要があるようなのですが、そこの使い分けが自分にはまだわかっていないです。
自分の理解で伝えると、一度情報を取得するとその時点の情報はとれるがプロセス間のやり取りが切れてしまっている状態なので、もう一度つなぎ直すためにQueryableに変換しているイメージです。
<https://github.com/niimima/MySampleExtension/blob/main/src/MySampleExtension/MySampleExtension/ForceDebugCommand.cs#L96-L97>

## おわりに

色々と手探りではありますが、とりあえずひとつ拡張機能を作ることができました。
ただ、プレビュー機能で配布することもできないので、公式な Visual Studio でも動作するようになることを楽しみにしています！
【アパレル】サイズ(規格分類)互換表

# サイズ(規格分類)互換表
|------------|------------|------------|
|:----------|:----------|:----------|
| SS        | XS        |           |
| WS        | GS        | G-S       |
| WM        | GM        | G-M       |
| WL        | GL        | G-L       |
| ２L        | LL        | XL        |
| ３L        | XXL       | ２XL       |
| 4L        | XXXL      | 3XL       |
| 5L        | XXXXL     | 4XL       |
| 6L        | XXXXXL    | 5XL       |
| 7L        | XXXXXXL   | 6XL       |
| 8L        | XXXXXXXL  | 7XL       |

:::note warn
JIS規格では、メンズウェアは平成８年に「S」「M」「L」表記から、「SA」「MA」「LA」等の表記に変わりました。
[JISL4004:2001 成人男子用衣料のサイズ](https://kikakurui.com/l/L4004-2001-01.html)
:::

:::note warn
同じサイズ表記でも、メーカーやブランドによってサイズ感は異なります。
:::
geospatial 位置合わせ



◇ツール
緯度経度から平面９番
https://vldb.gsi.go.jp/sokuchi/surveycalc/surveycalc/bl2xyf.html

緯度経度からジオイド高
https://vldb.gsi.go.jp/sokuchi/surveycalc/geoid/calcgh/calcframe.html

◇PLATEAUとGeospatial APIを連携させる
https://zenn.dev/ekito_station/scraps/7e656718c0ed4a
AddAnchorの子供にする方法
データはFBXの事前DL、InspectorでConvert Unitsのチェックを外す→モデルのサイズが実寸大になる

◇　PlateauCityGmlSharpを使う方法( @mikuminp )
https://github.com/ksasao/PlateauCityGmlSharp

https://gaprot.jp/2022/08/22/geospatial-api/
　-> v1.37以降は対応していない。

１．新しい原点にしたい場所の緯度経度をGoogleマップで取得
緯度経度　
35.766657365151026 
139.78289655657773

-25887.1992
-4560.4739
37.2682
Positionを(x, y, z) = (-平面直角座標系でのY座標, 0, -平面直角座標系でのX座標)


２．　緯度経度から平面9番に変換


1次メッシュは　　1辺は約 80km

2次メッシュの幅は
経度（東西）が7分30秒（0.125度）
緯度（南北）が5分（0.083度）です。 
距離にするとおよそ10km×10kmになります


メッシュコード,メッシュタイプ,左下X座標,左下Y座標,右上X座標,右上Y座標
533956,2,139.75,35.75,139.875,35.833333333333  // 足立区
533946,2,139.75,35.666666666667,139.875,35.75  // 銀座　
533936,2,139.75,35.583333333333,139.875,35.666666666667　//中央区
533926,2,139.75,35.5,139.875,35.583333333333　//　江東区
Matplotlibを用いた図の作成

## はじめに
私は現在，実験研究をしている修士1年生です． 実験データを可視化際に使用している Matplotlib のコードをメモします．
初めての投稿になりますので，わかりにくい箇所や間違っている箇所がございましたらご指摘ください．

## 図の設定
- 1枚だけグラフを表示する時
>```Python:
>fig, ax = plt.subplots(figsize = (7, 7))
>```

- 2枚以上グラフを表示する時
>```python:
>fig = plt.figure(figsize = (7, 7))
>ax = fig.add_subplot(2, 1, 1)
>ax2 = fig.add_subplot(2, 1, 2)
>```
> - 例
>![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3089106/4bbbdc2f-a203-2232-b401-6e941b4e311f.png)



## プロット
```python:
ax.plot(x, y, label = "label name")
```

## 凡例表示
- 右上に表示させる場合
```Python:
ax.legend("label name", loc = "upper right", fontsize = 16)
```

## グリッドの表示
```python:
ax.grid()
```

## 軸設定
- 軸の範囲

>```python:
>ax.set_xlim(0, 10)
>```
>始点 or 終点だけ設定も可
>```python:
>ax.set_ylim(1e-5, )
>```

- Log表記
>```python:
>ax.set_yscale("log")
>```

## 書式
- 軸ラベル
>```python:
>ax.set_xlabel("label name", fontsize = 16)
>```

- タイトル
>```python:
>ax.set_title("Title", fontsize =20)
>```

- メモリ
>    - フォント
>    >```python:Tick font
>    >plt.rcParams["font.family"] = "Arial"
>    >```
>
>    - サイズ
>    >```python:Tick size
>    >ax.tick_params(labelsize = 16)
>    >```

## 保存方法
- 拡張子をPDFにする場合
>```python:
>fig.savefig(pathname + "/figure_1.pdf")
>```

- 図の保存サイズ(余白をカット)
>```python:
>fig.savefig("figure.pdf", bbox_inches = 'tight', pad_inches = 0.1)
>```
> - 余白あり
>
>![Figure_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3089106/99e8c096-4a84-f79c-d735-88518c69a5c1.png)
>

> - 余白無し
>
>![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3089106/e7f03965-fd3a-b267-c1f5-6f2515cbfb95.png)
matplotlibで日付のメモリの幅を変える

# はじめに
データの可視化のためにmatplolibでグラフを作成した時に問題発生
![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/ad964172-6f15-8174-cc72-20f52800bd3a.png)


X軸が日付を表しています
2023-01-01、2023-01-02、2023-01-03、、、と日付が続き、黒く塗りつぶされたように表示されました。

# 問題のコード
```python
import pandas as pd
import matplotlib.pyplot as plt

list = [('2023-01-01', 100), ('2023-01-02', 110), ('2023-01-03', 120), ...]
df = pd.DataFrame(list, columns=['date', 'price'])

plt.figure()
plt.show()
```

X軸の日付を設定しているので、このまま表示すると1日ずつの日付がX軸に表示されて、
前述の画像のように黒く塗りつぶされたような表示になりました。

# 改善したコード
X軸の日付形式は2023-01-01のように、yyyy-mm-dd形式なので、
yyyy-mm形式で1ヶ月ごとに表示されるようにします。

日付の値が含まれているDataFrameの'date'の型はstr型に入っていると問題の表示になるようです

なので、str型からdatetime型に変換します

```python
import pandas as pd
import matplotlib.pyplot as plt

list = [('2023-01-01', 100), ('2023-01-02', 110), ('2023-01-03', 120), ...]
df = pd.DataFrame(list, columns=['date', 'price'])

plt.figure()
# str型からdatetime型に変換
df['date'] = pd.to_datetime(df['date'])
plt.show()
```

実行してみると
![Figure_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/115beefe-b28c-897e-3ad2-5ef635155419.png)


X軸の塗りつぶしがなくなり、yyyy-mm形式で見た目よく表示されています

# おわりに
matplotlibでグラフ化する時には、str型だと綺麗に表示されないので注意が必要です
Visual Studio Code(vscode) 「更新の確認」が出現しない場合のアップデート方法

備忘録として、Visual Studio Code(vscode) のアップデート方法について記載します。

### まず試したこと

- 以下の方法でアップデートを試したものの、「更新の確認」が出現せず更新できなかった。

1. vscodeを起動し、Windowsの場合はメニューバーの「ヘルプ」をクリックする。Macの場合はメニューバーの「ヘルプ」をクリックする。
1. 「更新の確認」をクリックする。
1. 「更新して再起動」を行う。

実際の画面に「更新の確認」はないため、この方法でバージョンアップを行うことができない。
![l_206430673_9715_69cd0c372752029807d8d1a630ae649f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3507443/1598b50c-fb28-bf7a-9ded-690262f4214f.png)

### 解決策

- 以下のリンクから最新のvscodeを再度インストールすることで、バージョンアップできた。
    - https://code.visualstudio.com/download
    - 拡張機能の再設定や環境構築の必要はなく、現在も問題なく使い続けることができている。
    - 「更新の確認」は相変わらず出現していない。