OmniAICreator/Qiita-1.07M huggingface dataset:
おっさん、他社体験がしてみたくなった

# いきさつ

「トイレの水がちょろちょろー」

娘の一言から始まった

とりあえず、タンク開けてみたけれど・・・・・さっぱりわからん :unamused: 
しょうがないので水道屋さんに来てもらった

ものの15分で、え？こんなに水出てたっけ？ってぐらいに回復

その際、互いに冗談半分で以下のような会話をした

自分「やっぱり、経験ってすごいですね！一度視点変える為にも、一週間ほど弟子入りできませんか？」
相手「いいですね～、どうぞどうぞ」

早速会社で相談、二つ返事で OK :laughing: 

ただ、冷静になって考えたところ、
- 配管工事って、今の業務に活きるのか？？

との疑問が・・

ということで・・閑話休題

# ソフトウェア開発関連で、他社体験がしたい

数日から一週間、インターン的に受け入れてもらえるとこはないものか？ :sweat_smile: 

まずは、相互にどんな利点があるのか？を考えてみる

## 受け入れ側の利点
- 新しい視点と知識の獲得:

自分の会社にはない新しい視点や知識をもたらす筈。これにより、現在の業務プロセスや戦略を見直す機会や、転職者に対する教育施策の確認ができる・・？

- 人材の育成とモチベーション向上:

業務体験者を指導することで、自分たちのスキルや知識の再確認ができ、社員の成長とモチベーション向上にも繋がるかも

- ネットワークの拡大:

共創のきっかけになるかもしれない

## 受け入れてもらう側の利点
- スキルと知識の習得:

他社の業務プロセスやノウハウを直接体験することで、新しい発見や、視点が得られる

- 適応力と柔軟性の向上:

新しい環境に飛び込むことで、適応力や柔軟性が磨かれる？

- 人脈の構築:

人の繋がりは大切

# あとがき

ん－、やりたい！って思ったけれど、受け入れ側の利点が薄い気がしてしまった :(

研修でいいじゃんって話もあるんだけど、そうじゃないんだよね
ハッカソンに参加して、他社の人材と交流するのが一番近いイメージ

ただ・・娘との大切な土日を潰したくはないので、
「糞じじー」って言われてから、改めて、ですかね :laughing: 

いや、もしうちに遊びに来ませんか？って方いたら連絡ください。
割とまじめに考えたいです。 :bow:
Raspberry PiでMP3を再生したい！playsoundでエラーが出た時の解決方法

## aplayだとwavしか再生できない

Google TTSで生成したmp3形式の音声ファイルをデフォルトでファイルを再生できるaplayを使って再生しようとしたら、なんと雑音しか聞こえませんでした。

調べたところaplayではwavファイルしか再生できないもよう、かといってGoogle TTSでもwavは作成できなさそうなので、一旦mp3のまま再生することにしました。

なるべく余分なものはインストールしたくなかったので今回はpygameではなく、pysoundを使って再生することにしました。

とはいったもののRaspberry PiでMP3ファイルをPythonから再生しようとして`playsound`を使ったらエラーが出た…！ということで忘備録として解決方法を記録しときます。

### playsoundのインストール

`playsound`を仮想環境（myenvなど）にインストールします。
```bash
pip install playsound
```

インストールしたところ以下が表示されてしまいました。

```
playsound is relying  on another python subprosecc. please use pip install pygobject to un more efficiently
```

このメッセージはどうやら、playsoundモジュールが別のPythonプロセスに依存してMP3を再生しているため、効率が落ちる可能性があると伝えています。より効率的に再生するために、pygobjectというライブラリをインストールするよう提案してくれているみたいです。

そこでpygobjectも同じ要領でpip installしてみる。。

とりあえず無事に完了したので、対話モードで以下のコードをテストしてみる。

```python
import playsound

playsound.playsound('output.mp3')
```

ところが、これを実行したらエラーが出ました！

## 発生したエラー
実行すると、こんなエラーメッセージが出ました。
いろいろ書かれてるけど、どうやらこれらしい。
```
ValueError: Namespace Gst not available
```

これは、playsoundが依存している「GStreamer」というライブラリがRaspberry Piにインストールされていないことが原因で発生します。要するに、「GStreamerがないから音声を再生できないよ」ということですね。

## 解決方法：GStreamerをインストールしよう
Raspberry PiにGStreamerをインストールすることで、この問題を解決できます。以下のコマンドを使って必要なパッケージをインストールします。

```bash
sudo apt-get update
sudo apt-get install -y python3-gi gir1.2-gstreamer-1.0 gstreamer1.0-tools gstreamer1.0-plugins-base gstreamer1.0-plugins-good
```

これでGStreamerがインストールされ、同じ要領でテストしてみると、無事にplaysoundがMP3を再生できるようになりました！

## まとめ
Raspberry PiでPythonからMP3を再生するためには、playsoundと一緒にGStreamerをインストールする必要があることがわかりました。

Raspberry Piは便利なデバイスですが、デフォルトでMP3再生のための環境が整っていないこともあるので、事前に必要なライブラリをインストールしておくと安心です。
nginxで特定のIPからのアクセスを禁止する方法

nginxで特定のIPアドレスからのアクセスを禁止するには、`nginx`の設定ファイルに以下のような設定を追加します。この設定は通常、nginxのメイン設定ファイル（`nginx.conf`）やサイトごとの設定ファイルに追加します。

### 手順

1. **設定ファイルを開く**
   `nginx.conf` または対象のサーバブロックがある設定ファイルを編集します。
   通常は、次のように設定ファイルを編集します。
   ```shell
   sudo nano /etc/nginx/nginx.conf
   ```
   ‌
2. **設定を追加する**
   `server`ブロックの中に、以下のように `deny`ディレクティブを追加します。
   ```shell
   server {
     listen 80;
     server_name example.com;
     # 特定のIPアドレスからのアクセスを禁止
     deny 192.168.1.100; # 禁止したいIPアドレス
     deny 203.0.113.0/24; # サブネット全体を禁止する場合
     # 許可するIPアドレスがある場合はallowを使用
     allow 192.168.1.0/24;
     # 他のIPアドレスからのアクセスを許可
     allow all;
     location / {
       # 通常の設定
       proxy_pass http://localhost:3000;
     }
   }


   ```
   ‌
   **設定をテストする**
   設定ファイルにエラーがないか確認するため、以下のコマンドを実行します。
   ```
   sudo nginx -t
   ```
   ‌
3. **nginxを再起動する**
   設定ファイルが正しい場合、nginxを再起動して設定を反映させます。
   ```
   sudo systemctl restart nginx
   ```

### 補足

- `deny`ディレクティブに指定されたIPアドレスは、403 Forbiddenエラーが返されます。
- 特定のIPだけを許可する場合は、`allow`ディレクティブを使用し、許可したいIP以外のアクセスを禁止するように設定することもできます。

この設定により、指定したIPアドレスやサブネットからのアクセスを制限することができます。
ローカル環境でngrokを使ってWebhookを受信する方法

## はじめに
Webhookを使った開発を行う際、通常、外部からのリクエストをローカルで受信するのは難しいです。ngrokを利用することで、ローカル環境でも簡単にWebhookの受信テストが可能になります。本記事では、ngrokを使ってローカルでWebhookを受け取る方法を解説します。

## ngrokとは
ngrokは、ローカル環境で動作しているWebサーバーに一時的なパブリックURLを割り当て、外部からのアクセスを可能にするツールです。このため、Webhookを用いたテストや、クライアントに対してローカル環境を共有したい場合などに便利です。

## ngrokのインストール
ngrokを使用するため、公式サイトからインストールを行います。
https://ngrok.com/download

## Webhook受信プログラムの作成・起動
Webhookの受信をテストするため、まずはローカルで簡単なWebサーバーを立ち上げます。今回はNode.jsを使って実装します

1. コードの準備：index.jsとして以下のコードを作成します。
```javascript:index.js
const express = require("express");
const bodyParser = require("body-parser");

const app = express();
const PORT = process.env.PORT || 3000;

app.use(bodyParser.json());

app.post("/WebHook", (req, res) => {
  const payload = req.body;
  console.log("Received WebHook:", payload);

  res.status(200).send("WebHook received successfully");
});

app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});
```

2. ライブラリのインストール
`npm install express body-parser`

3. サーバーの起動
`node .\index.js`

これで、ポート3000でサーバーが起動します。
## ngrokでローカルサーバーにトンネルを作成

次に、ngrokを使ってローカルサーバーにパブリックURLを割り当てます。以下のコマンドでトンネルを作成し、外部からアクセスできるURLを発行します。ます。

`ngrok http 3000 `

実行後に表示される出力から、外部アクセス用のURLを確認します。このURLは、後でWebhookの設定時に使用します。

```
Forwarding     https://3818-240b-10-9161-de00-6166-4d6a-ad40-6467.ngrok-free.app -> http://localhost:3000  
```
## 動作確認
ここではGitHubのWebhook設定を利用して、ngrok経由でローカルサーバーにリクエストを送る手順を紹介します。

1. GitHubのリポジトリ設定画面から、Webhookの追加を選択します。
2. Payload URLに、ngrokで発行したパブリックURLを入力し、末尾に/webHookを追加します。
3. Webhook設定を保存し、リポジトリのイベント（例：pushイベントなど）をトリガーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273779/bc68e6dd-83b3-4694-540b-69ae5623b64f.png)

## ログの確認
サーバーのコンソールに、GitHubから送られたWebhookの内容が表示されていれば、Webhookの受信に成功しています。

```
Received WebHook: {
  zen: 'Keep it logically awesome.',
  hook_id: 478387677,
  hook: {
    type: 'Repository',
    id: 478387677,
    name: 'web',
    active: true,
    events: [ 'push' ],
    config: {
      content_type: 'json',
      insecure_ssl: '0',
      url: 'https://3818-240b-10-9161-de00-6166-4d6a-ad40-6467.ngrok-free.app/webhook'
    },
    updated_at: '2024-05-15T11:54:52Z',
    created_at: '2024-05-15T11:54:52Z',
    last_response: { code: null, status: 'unused', message: null }
  },
  ・
  ・
  ・
  ・
}
```

また、GitHub上でもローカルサーバーからのレスポンスが帰ってきていることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273779/ebbd445f-3780-8bd6-e9a8-5cdf4dae2a74.png)

## まとめ
ngrokを使うと、簡単にローカルでのWebhook開発やテストが可能になります。ぜひ、ngrokを活用して、効率的な開発環境を構築してください。
Power Automateでチームの特定のチャネルIDを取得する

# 方法1. Microsoft Graph APIで取得する
［Microsoft Graph HTTP 要求を送信する］アクションで、以下のようなURIを設定する。また、ODataシステムのクエリパラメーターを使用する。今回はfilterクエリで結果をチャネル名でフィルターします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640497/9b997eeb-1814-d494-5552-d7d2c71bb356.png)

ODataシステムのクエリパラメーターの詳細は以下記事をご確認ください。

https://learn.microsoft.com/ja-jp/graph/query-parameters?tabs=http

# 方法2. チャネルの一覧表示から配列フィルターで取得する
［チャネルの一覧表示］アクションで、チャネルの一覧を取得した後、［アレイのフィルター処理］アクションで結果をチャネル名でフィルターします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640497/4e979f8c-d8bd-bc65-b2d0-a5f2660237e8.png)
Flutterの学習 - 開発環境の構築

こんにちは！

普段は主にWebサービスを開発してます。
独学で簡単なiOSアプリを開発した経験はありますが、Flutterも使えた方がいいので、学習することにしました。

まずは環境構築から。

# 環境構築
まずは公式サイトの[Get Started](https://docs.flutter.dev/get-started/install)にアクセスします。
![スクリーンショット 2024-11-13 20.16.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/8ee38b1f-5130-f401-9f52-ec183e1d0a22.png)

筆者は macOS なので、アイコンをクリック

![スクリーンショット 2024-11-13 20.18.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/35995d30-30a0-86a4-8945-80c049073210.png)

普段使ってる端末が Android なので、今回は Android を選択してみます。

![スクリーンショット 2024-11-13 20.22.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/aa5be704-0f88-b00c-7548-e56ba5581dc9.png)

ハードウェア要件はギリギリクリアしていたので、そのまま下にスクロール。
ビルドには Android Studio が必要とのことで、リンクをクリックして公式サイトを訪問。インストールします。

![スクリーンショット 2024-11-13 20.28.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/d4246651-a757-96c2-ffd8-f40600342d72.png)

こちらは Android Studio の公式サイト。

![スクリーンショット 2024-11-13 20.30.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/dca60eff-18ee-a575-0366-912aa4f48a75.png)

[Gemini in Android Studio](https://developer.android.com/gemini-in-android?hl=ja) というのがあったので、せっかくなのでこちらをインストールしてみます。

![スクリーンショット 2024-11-13 20.39.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/00cfad12-1cdb-2c3b-46fa-60d79018c04d.png)

![スクリーンショット 2024-11-13 20.40.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/66b0245b-1451-9b7f-7956-183263794379.png)

ダウンロードした dmgファイル を起動し、Applications に追加します。

![スクリーンショット 2024-11-13 20.46.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/408e2ac2-5d40-da4a-e103-6562621f7b5a.png)

起動しました！
最初に幾つかのファイルを自動でダウンロードしたのと、最新版が通知されたのでアップデートしました。

![スクリーンショット 2024-11-13 21.00.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/cd5c504a-1186-681c-6c3f-4a8d20245a79.png)

サンプルがあるようなので、見てみます。

![スクリーンショット 2024-11-13 21.04.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/4ed276e3-edac-d166-2e63-e45de101e42f.png)

どれを選べばいいか分かりませんが、とりあえず睡眠追跡アプリのサンプルをインポートしてみます。

![スクリーンショット 2024-11-13 21.23.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/3d6872fa-a476-1aeb-effe-01cefc254a71.png)

サンプルコードをインポートしました！

![スクリーンショット 2024-11-13 21.27.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/3b8f5268-db6a-e937-aaa0-e44c41f11111.png)

バックグラウンドで色々インポートしているようで、少し時間がかかります。
（テザリングだったので、20分くらいかかりました）

![スクリーンショット 2024-11-13 21.32.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/58b1ae7b-f44a-c9b6-582e-63b0d2092404.png)

席を外している間に完了したようです。

![スクリーンショット 2024-11-13 21.54.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/c94257f7-2fec-cbca-5c1b-c7c3919618a0.png)

▷ボタンで起動してみましたが、ビルドに失敗したようです。
再度、ビルドしてみましょう。

![スクリーンショット 2024-11-13 21.59.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/14c5cfad-6cca-1875-eb70-1411c1c96db2.png)

再度、ビルドしてみましたが、失敗。。

とりあえず開発環境は整ったので、別途エラーの対処を行います。

# おわりに
アプリの起動はできませんでしたが、開発環境は整いました。

次回は、簡単なアプリを作ってみようと思います。
Geminiも気になるので、使ったらレポートしますね。
運営目線から見たメッセージングセキュリティのいま＠JPAAWG 7th General Meeting

# はじめに

今年(2024年)もJPAAWG 7th General Meeting (2024年11月11日〜12日の2日間)が無事に終わり、翌日(11月13日)に新千歳空港で東京へ戻る飛行機を待ちながら記事を書いています。

https://meetings.jpaawg.org/

# 今年(2024年)のトピック

2023年10月にアナウンスされたGoogleと米国Yahoo!メールで実施する迷惑メール対策強化(4月に送信ドメイン認証の適用、6月に迷惑メール率による受信規制)が行われ、大量メール送信事業者に求められる対策の実施(適用)が行われました。

JANOG54で登壇発表した資料はこちら。

https://www.janog.gr.jp/meeting/janog54/phishing/

迷惑メール率を把握する目的でGoogle Postmaster Tools APIの使い方を紹介した記事はこちら。

https://qiita.com/kitazaki/items/21ca88c833a510fc1b80

業界としてDMARCの普及が一気に進みました。

# プログラムのメモ

セッションの内容で気になったことのメモです。

## A1-2 Keynote

GoogleのGmail SecurityチームのEmil Gustafssonがリモート登壇しました。
講演終了後に2点、質疑応答がありました。
Feedback IDに関して、将来Postmaster ToolsにFeedback IDのテスト機能が実装される可能性が示されました。
迷惑メール率(スパムレート)の計算方法に関して、ユーザを識別して悪意あるユーザがスパムレートを悪化させようとかしているどうかを判定して、正当なユーザだけでスパムレポートを計算していると回答がありました。ユーザに多少の誤差(あるユーザにとっては正当なメールだが、別のユーザにとってはスパムメール)は含まれているが、計算結果に大きな影響を及ぼしていないとのことでした。

## A2-1

大規模メールシステムの移行の苦労話はネタに困りません。

## A1-3、B1-7、A2-2、C2-3、B2-4

SPAMやフィッシングのトレンドの変化は目まぐるしく、精度が高く手口も巧妙化し、細心の注意を払う必要があることを再認識しました。フィッシングサイトに使われるドメイン名だけでハントが難しくなっている実情が語られました。

## B1-5、B2-3

DMARCポリシーをnoneからquarantine、または、rejectに変える時が既に来ています。noneが狙われている実情が報告されました。

## B2-5

ドメイン名の廃止(破棄)時のリスク(オークション出品、ドロップキャッチ問題)について報告されました。実際に発生した問題とその対処経緯は生々しく、明日は我が身(自分事)として捉えました。

## A1-6、B1-6、A2-6、B2-6

毎回恒例の完全オフレコ、現場発のメールサービス(システム)運用者による話(実際にあった怖い内容や苦労した話)は面白かったです。

# メッセージングセキュリティのいま

一部のオンラインセッションを除き、現地のみのセッションが最大3セッション同時に進行しました。
どれを聴講するか、かなり迷った時間帯もあったと思います。
セッションとセッションの間の休憩時間でも登壇者と直接会話したり、ひさびさに会った人と雑談する時間も貴重で、楽しんでいただけたら幸いです。

![スクリーンショット 2024-11-13 22.18.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/5baaea1d-e022-c6b4-f67e-897a5ca6302b.png)

次回(来年)も開催できたらいいな、と考えています。

![スクリーンショット 2024-11-13 22.26.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/b14fcfda-39cf-7b10-e129-aab37bb25705.png)
UNPROTECTED PRIVATE KEY FILE! というメッセージが出て、SSHプライベートキーにアクセスできない時にファイルパーミッションを許可した時のメモ

# これなに

EC2インスタンスにアクセスしようとした時に、`UNPROTECTED PRIVATE KEY FILE!` と出て、どうしようかな…と思った時のお話。
超初心者すぎるのですが、戒めのためにメモ。


# なにが起きた？

キーペアも作成してインスタンスもできた。
さあ ssh してみようと思ったら ssh に失敗した。
（ホスト名とか Public IP アドレスとかは config に書いてあるのですがここでは割愛）

```zsh
su3@macbook ~ % ssh Test-EC2
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/Users/su3/.ssh/test-ec2.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/Users/su3/.ssh/test-ec2.pem": bad permissions
ec2-user@xxx.xxx.xxx.xxx: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
su3@macbook ~ % 
```

なるほど、ファイルにアクセスできないんですね。


# 解決方法

ファイル所有者に読み取りと書き込みの権限を与えればOKですね

```zsh
chmod 600 ~/.ssh/test-ec2.pem
```

そうして無事に ssh 成功

```zsh
su3@macbook ~ % ssh Test-EC2
   ,     #_
   ~\_  ####_        Amazon Linux 2023
  ~~  \_#####\
  ~~     \###|
  ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
   ~~       V~' '->
    ~~~         /
      ~~._.   _/
         _/ _/
       _/m/'
Last login: Wed Nov 13 13:10:54 2024 from 999.999.999.999
[ec2-user@ip-999-999-999-999 ~]$ 
```

# 備考

ついでに他にも使いそうなコマンドをザッとメモ

### 所有者に読み取り権限を付与する

```zsh
chmod u+r ファイルパス
```

### 所有者に実行権限を付与する

```zsh
chmod u+x ファイルパス
```

### 該当のフォルダ配下に対して書き込み権限を付与する

```zsh
chmod -R 755 ディレクトリパス
```

### 該当のフォルダ配下に対して書き込み権限を削除する

```zsh
chmod -R a-w ディレクトリパス
```

### 該当のフォルダ配下に対して実行権限を削除する

```zsh
chmod -R a-x ディレクトリパス
```
バイト先のレジシステムを改良した話

# はじめに
## バイト先について
個人営業で厳選された食品や雑貨等を販売しているセレクトショップです。この店では、ExcelとVBAで構築されたレジ・在庫管理システムを使用しています。

## きっかけ
接客・レジ・納品など包括的に業務を担当するスタッフとして2022年12月から働き始めました。
業務を行なっていく中で非効率な部分を改善したいと思い、オーナーに提案し改良していきました。

# 具体的な改良事例をご紹介します
## 発注書作成の半自動化
### 概要
レジ内の商品情報を活用し、商品を選択するだけで発注書を自動作成・PDF化し、取引先にメール送信するシステムです。

### 使用技術
* VBA
* Excel関数
* Outlook

### 従来の方法と問題点
従来は手作業でWordに商品情報や取引先情報を入力し、PDFに変換してメールで取引先に送信していました。さらに、金額も手計算で行っていたため、計算ミスが発生していました。

### 改良点
* 商品を選択し個数を入力するだけで、テンプレートに商品情報を自動入力し、手作業を大幅に削減しました
* PDF化およびメール送信のプロセスを自動化し、送信作業を効率化しました
* 発注した商品を納品待機リストに登録し、納品時の作業を減らしました


## QRコードシール発行の全自動化
### 概要
納品時の商品に貼るQRコードシールの発行作業をPythonで全自動化するプログラムです。

### 使用技術
* VBA
* Python(PyAutoGUI)

### 従来の方法と問題点
1. レジ・在庫管理システムで納品する商品の情報をCSVファイルとして作成
2. 作成したCSVファイルをP-touch（シール発行ソフト）にインポート
3. 各種設定を手動で行い、シールを発行

この方法では、選択・入力する項目が多く、作業に時間がかかっていました。また、納品作業を迅速に完了する必要があったため、時間短縮が求められていました。

:::note alert
従来方法での発行の様子
youtube: https://youtu.be/14i7qR1KSv0
:::

### 改良点
* CSVファイルの作成ステップを実行すると、残りの2〜3ステップを全自動で行うように改善しました
* 手作業で約3分かかっていたシール発行作業を、30秒に短縮し、作業効率を大幅に向上させました

:::note info
改良後の発注書作成と納品の様子
youtube: https://youtu.be/pbCaKHtNEvE
:::

## BASE在庫数更新の自動化
### 概要
レジ・在庫システムの在庫情報をネットショップ「BASE」へ自動的に反映するシステムです。

### 使用技術
* VBA
* Excel関数
* BASEAPI
* python

### 従来の方法と問題点
従来は在庫数に余裕のある商品のみを出品していました。しかし、全商品を販売して売上をアップさせるためには、確実に販売できる在庫数をBASEに正確に設定する必要がありました。このプロセスには多くの手作業が伴い、時間がかかる上に計算ミスのリスクもありました。

### 改良点
* BASEのCSV出力・入力機能を利用し、商品IDと賞味期限に基づいて適切な在庫数を自動更新するロジックを構築しました。これにより、手動でのデータ入力を大幅に削減しました
* 賞味期限が10日以内の商品の販売停止や割引フラグの管理を自動化しました。これにより、在庫管理の精度が向上し、期限切れ商品の販売を防止しました

### 現在の課題
複雑な条件分岐をExcel関数とVBAで組み合わせて実現したため、コードが読みにくく保守が困難となっています。また、在庫情報のCSVアップロードは手動で行っており、実行に時間がかかるため、現在は1日に1回しか更新できていません。そのため、1日に大量の商品が売れた場合、BASEで購入された際に在庫が不足するという事態が発生してしまいました。

### 今後の展望
現在、BASE APIを活用した完全自動化システムの構築を進めています。これにより、在庫情報のリアルタイム反映とさらなる業務効率化を図り、在庫不足のリスクを最小限に抑えることを目指しています。また、コードの整理と最適化を行い、保守性の向上にも取り組んでいます。

### 追記(2024/12/18)
今後の展望に記載した内容を実現し、BASE APIとPythonを活用した自動化在庫管理システムの構築を行いました。

## 賞味期限管理画面の作成・自動割引適用
### 概要
賞味期限管理画面を作成し、割引設定している商品の可視化と割引処理を自動化するシステムです。

![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3907021/281ce8b4-b6b8-2c9f-0d77-b9468a5d0cb7.jpeg)
(図3 賞味期限管理画面)

### 使用技術
* VBA

### 従来の方法と問題点
従来は、在庫画面から賞味期限列でフィルターをかけて期限の近い商品を手動でチェックしていました。この方法では、以下の問題が発生していました。
1. チェック漏れ: 手動作業により、一部の商品を見落とす可能性が高かった
2. 割引処理の不透明さ: 割引シールを貼っているかどうかがシステム上でわからず、レジ時に割引処理を手動で行う必要があった
3. 割引処理の漏れや期限切れ商品の回収忘れ: 手動作業によるエラーが頻発し、割引処理の漏れや期限切れ商品の適切な処理が行われないことがあった

### 改良点
* 各商品の割引開始期間をあらかじめ設定し、毎日一回その情報に基づいて割引開始商品を自動的に洗い出し、一覧で表示する画面を作成しました
* レジでの割引処理を自動で適用するようにシステムを修正しました。これにより、手動での割引処理が不要となり、作業時間の短縮とエラーの減少を実現しました
【パタパタ】遊戯王ライフ表示器作ってみた

遊戯王はライフポイント（LP）の計算をしなくてはいけないので、子供のころ苦労しました。今回は Web API が公開されているパタパタ表示器 [AfterAI Flaps](https://shop.afterai.dev) を使って、遊戯王のライフを計算・表示してみようと思います。

動画

<iframe width="560" height="315" src="https://www.youtube.com/embed/Sd2KLeK7nvY?si=IBRsYt2wo1wwnusX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

ソースコード

https://github.com/AfterAILab/Yu_Gi_Oh_Life_Counter

# AfterAI Flaps とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151166/3ca673eb-f0af-30ec-44eb-2ef1f076f3a7.png)

- エンジニアのためのパタパタ表示器です。僕が作りました。
- ここで買えます: https://shop.afterai.dev
- ワークショップやります: https://www.street-academy.com/myclass/185682?sessiondetailid=15206829&trigger=browse-history_top

# デプロイメント図

![YGODeploymentDiagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151166/18953f14-3ffc-06be-fb91-529fddcfc922.png)

- ターン表示器: AfterAI Flaps 5 文字分
- ライフポイント表示器: AfterAI Flaps 9 文字分
    - 実装段階で、 4 文字分を２つ使用することにしました
- 計算機: MacBook Pro (M2)

# 計算機
MacBook Pro (M2) には潤沢なコンピューティングリソースがあるので、計算処理は全てローカルで動かす方針にしました。 Speech-to-Text には [Vosk](https://alphacephei.com/vosk) を、 テキストからコマンドを抽出するためには [Ollama](https://ollama.com) 経由で llama3.2 を使用しました。
*しかし、llama3.2 (3B) では誤った答えが返ってくることが多すぎたので、結局 OpenAI 社の gpt-4o-mini を使うことになりました。*

# フローチャート
![YGOFlowChart.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151166/a0f5b56c-a121-080a-538c-d7d2b6cb9c5c.png)
『相手にXXXダメージを与える』という意味のことが発言されたら、相手のライフポイントをディスプレイから GET リクエストで取ってきます。ダメージ計算のあと、 ディスプレイ POST リクエストして表示されている数字を更新します。
簡単のため『俺のターン』についてはフローチャートに描いていないですが、同様の処理をしています。詳しくはコードを見てください。

https://github.com/AfterAILab/Yu_Gi_Oh_Life_Counter

# プロンプト
以下タスクを llama3.2 (3B) にやらせようとしました。

> 入力: 『現在どちらのターンなのかという情報』と『発言を文字化した情報』
出力: ゲームの状態変化の情報（ダメージや回復、次のターンなど）

しかし相手を回復してしまったり、意外と苦しみました。他の AI にプロンプトを改善してもらったりしましたが、それでもダメでした。

https://www.perplexity.ai/search/i-m-making-a-yu-gi-oh-judge-sy-4z0gbd_dRJemel4s2EU2vw

結局、同じプロンプトを OpenAI 社の gpt-4o-mini に食わせたらうまくいきました。

# まとめ

- パタパタ表示器 (AfterAI Flaps) は DIY プロジェクトの一部としてちゃんと使える
	- 出荷時点ではバージョン 1.1。必要に応じて GitHub から最新のファームウェアをダウンロードして焼くと良い
	- https://github.com/AfterAILab/flaps-esp
- リアルタイム性を上げるためには、音声エンジンの発言完了イベントを待たずに途中で割って入ると良さそう
	- 発言完了イベント発生までのタイムラグが、エンジンのパラメータとしていじれるならそれで良い
- このような小さな課題でも、モデルによってかなり性能に差がある
	- llama は有名なモデルだが、この課題で躓いたのは意外だった
	- llama 3.2 には 3B よりもパラメータ数が多いバージョンもあるので、それならうまくいくのかもしれない
	- gpt-4o-mini のパラメータ数はざっとインターネットをさらったが見つけられなかった
eas build を行うときに求められるApple IDを間違って記入した時の対処

# はじめに

```
eas build --platform ios
```

を行った際に、以下のようにApple IDが求められます。

```
Do you want to log in to your Apple account? … yes

› Log in to your Apple Developer account to continue

 Apple ID: …
```


この際に一度誤ったIDを登録してしまうと、そのIDが記憶されてしまい、次の入力時にも強制的にそのIDが入力された状態になってしまいます。

異なるIDを入力したい場合には、それをリセットする必要があるのですが、解決に手こずったので解決法を共有します。

# 解決法

[こちら](https://github.com/expo/eas-cli/issues/2254)を参考に解決することができました。

具体的には、***.app-store/auth/username.json***というファイルを削除する必要があります。

保存先は上記で紹介したissueと、私の保存先が異なっていたので、人によって違うのかも知れません。

私の場合は以下のコマンドを実行して、ファイルの場所を見つけました。

```
find .app-store 
```

そして見つけた ***username.json*** を
```
rm username.json
```

でも行って削除してください。

その後に、eas buildを再度行うと、Apple IDの入力を求められているようになっています。


# 終わりに

急に入力できなくなって困っていたのですが、ちょうどいいissueが見つかって良かったです。
参考になると幸いです。
【git】ブランチとマージ基本[初級編]

# はじめに
<!-- 発端や概要を記載 -->
本記事ではgitのブランチとマージの基本をまとめた記事になります。
この記事を書いている時点でお察しかと思われますが、投稿主はgitの操作に慣れておりません汗
※gitは既にインストールしている想定で進めています

# 目次
<!-- タイトルとアンカー名を編集 -->
1. ブランチの基本操作
2. マージの基本操作
3. コンフリクトの解消
4. まとめ

<!-- 各チャプター -->
# ブランチの基本操作

ブランチで使うコマンドを書く前に、前提知識を書いておきます。

- トランク(main)：プロジェクトのメインとなるブランチで、常にリソースできる状態にしておく
- トピックブランチ：機能追加やバグ修正など、あるトピックに関する作業を行うために作成するブランチ

２つのブランチがあることを意識して、よく使うコマンドを書いていきます。

#### 既存のブランチを一覧表示する

```git
git branch
```

#### 新規ブランチを作成する

```git
git branch ブランチ名
```

#### ブランチを切り替える

```git
git checkout ブランチ名
```

#### ブランチを削除する

```git
git branch -d ブランチ名
```

#### ブランチ名を変更する

```git
git branch -m 既存ブランチ名 新規ブランチ名
```

#### ブランチを新規作成して、作成したブランチに切り替える

```git
git checkout -b ブランチ名
```

# マージの基本祖操作

トピックブランチの内容をトランクへ反映させる作業になります。

#### マージする

```git
git merge 取り込むブランチ名
```

git branchで現在しているブランチを確認しておきましょう。

#### 

# コンフリクトの解消
コンフリクトとは
複数の変更が同じ部分のコードに対して行われ、それをマージする際にどの変更を採用すべきか自動的に決定できない状況のことを指します。

コンフリクトを解消するには、

1. コンフリクト部分を新たに編集して変更内容を統合する
2. 編集した内容をステージングエリアに追加し、コミットする
3. マージする

```git
git add "ファイル名"
```

```git
git commit -m "コメント"
```


```git
git merge 取り込むブランチ名
```

これで解決になります。

# まとめ
今回はブランチとマージの基本操作についてまとめました！
業務で使わないこともありgitに慣れてはいませんが、今後のチーム開発などに向けて使えるようになっておきたいですね〜！

では、またノシ
x510-28GTX　ファンコン

## やりたいこと
スイッチがうるさいので静音化したい

### activate *.shでファンをpwm制御

#### 1\. 制御コマンド
・fan-summer.sh
#夏用
```
#!/bin/sh

echo 1000 > /sys/class/hwmon/hwmon0/device/fan1_min

echo 64 > /sys/class/hwmon/hwmon0/device/pwm1_auto_point1_pwm
echo 64 > /sys/class/hwmon/hwmon0/device/pwm1_auto_point2_pwm


#cat /sys/class/hwmon/hwmon0/device/pwm1_auto_channels_temp
#cat /sys/class/hwmon/hwmon0/device/pwm1_auto_point1_pwm
#cat /sys/class/hwmon/hwmon0/device/pwm1_auto_point2_pwm
#cat /sys/class/hwmon/hwmon0/device/pwm1_enable
#cat /sys/class/hwmon/hwmon0/device/pwm1_freq
#cat /sys/class/hwmon/hwmon0/device/pwm1

```
・fan-winter.sh
#冬用
```
#!/bin/sh

echo 1000 > /sys/class/hwmon/hwmon0/device/fan1_min

echo 48 > /sys/class/hwmon/hwmon0/device/pwm1_auto_point1_pwm
echo 48 > /sys/class/hwmon/hwmon0/device/pwm1_auto_point2_pwm


#cat /sys/class/hwmon/hwmon0/device/pwm1_auto_channels_temp
#cat /sys/class/hwmon/hwmon0/device/pwm1_auto_point1_pwm
#cat /sys/class/hwmon/hwmon0/device/pwm1_auto_point2_pwm
#cat /sys/class/hwmon/hwmon0/device/pwm1_enable
#cat /sys/class/hwmon/hwmon0/device/pwm1_freq
#cat /sys/class/hwmon/hwmon0/device/pwm1

```
#### 2\. pwm制御範囲
```
echo N > /sys/class...
```
のNを変更してファン回転数を制御できる（0~255）
最低でも40くらいにしておいた方がいいと思われ

#### 3\. show sys env
```
#show system environment
```
でファン回転数を確認

電源を切ると制御が切れるので
trigger コマンドで自動的に適用されるようにすると楽

#### 4\. 自動でファンコンを適用しよう
```
conf t
trigger N
type reboot
script N *.sh
active
```

##### コマンドリファレンス
```
https://www.allied-telesis.co.jp/support/list/switch/x510/rel/5.4.2a-0.1/001763a/docs/index.html
```

##### もっと詳しい説明があった
```
https://nofu.jp/wiki/network/at-x510-28gtx_tips
```
画像ファイルの拡張子一覧と特徴

# 画像ファイルの拡張子一覧と特徴

画像ファイルにはさまざまな拡張子があります。それぞれの拡張子には特徴があり、使用目的に応じて選択することが重要です。以下に代表的な画像ファイルの拡張子とその特徴をまとめます。

## 1. JPEG (.jpg, .jpeg)
- **特徴**: 圧縮率が高く、ファイルサイズが小さい。
- **用途**: 写真や多色の画像に適しており、ウェブページやデジタルカメラでよく使われる。
- **長所**: ファイルサイズが小さく、ウェブ表示に向いている。
- **短所**: 圧縮による画質劣化がある。透過をサポートしない。

## 2. PNG (.png)
- **特徴**: 可逆圧縮方式で、画質を劣化させずに圧縮可能。透過をサポート。
- **用途**: ロゴやアイコン、背景透過が必要な画像に適している。
- **長所**: 高画質で透明背景が可能。
- **短所**: JPEGと比べるとファイルサイズが大きい。

## 3. GIF (.gif)
- **特徴**: 256色までの色しか扱えないが、アニメーションが可能。
- **用途**: アニメーション画像やシンプルなイラスト、アイコンに適している。
- **長所**: アニメーションが可能。
- **短所**: 色数が少なく、写真など多色画像には不向き。

## 4. BMP (.bmp)
- **特徴**: 非圧縮のビットマップ形式。画質は高いがファイルサイズが非常に大きい。
- **用途**: 高画質が求められる場面や、加工・編集前の画像保存。
- **長所**: 非圧縮で画質が高い。
- **短所**: ファイルサイズが大きく、インターネットには不向き。

## 5. TIFF (.tiff)
- **特徴**: 高解像度を維持したまま保存可能で、可逆圧縮にも対応。
- **用途**: 印刷やスキャン画像の保存に適している。
- **長所**: 高画質で細部まで保存可能。
- **短所**: ファイルサイズが大きく、一般的なウェブ用途には適していない。

## 6. SVG (.svg)
- **特徴**: ベクターフォーマットで、拡大しても画質が劣化しない。
- **用途**: ロゴやアイコン、イラストに適している。
- **長所**: ベクター形式のため、解像度に依存しない。
- **短所**: 複雑な画像や写真には不向き。

## 7. WebP (.webp)
- **特徴**: Googleが開発した形式で、画像圧縮率が高い。
- **用途**: ウェブサイトの画像最適化に適している。
- **長所**: 高圧縮率でありながら画質が良い。JPEGやPNGよりも小さなファイルサイズで保存可能。
- **短所**: 古いブラウザではサポートされていない場合がある。

## まとめ
画像の拡張子は、利用目的に応じて適切に選ぶ必要があります。例えば、ウェブサイトには`JPEG`や`WebP`が適しており、印刷物には`TIFF`が推奨されます。シンプルなロゴには`PNG`や`SVG`が適しています。このガイドを参考にして、最適な画像形式を選択してください。
Google Cloud SDKで「AttributeError: module 'google._upb._message' has no attribute 'MessageMapContainer'」エラーが出た時の解決法

## ラズパイにGoogle Cloud SDKを使おうとしたら...
今回は、**Raspberry Pi上のPython仮想環境**（Python 3.11）でGoogle TTSを使用するために、Google Cloud SDKを使おうとしたところ、謎のエラーに遭遇しました。このエラーは、Google Cloud SDKのアップデート中に発生しました。

Raspberry Piなどの限られたリソースのデバイスでSDKを動かす場合や、特定のバージョンのPythonで開発を進める場合に、同様の問題に出くわすかもしれません。以下にその解決方法をまとめておきます。

### どんなエラーが出たの？

Google Cloud SDKをインストールして、アップデートしようとしたときにこんなエラーが出ました。

```bash
ERROR: gcloud crashed (AttributeError): module 'google._upb._message' has no attribute 'MessageMapContainer'
```

「MessageMapContainerがない」と言われても、なんのことやら…

### なぜこのエラーが起こるの？
調べてみると、このエラーは Google Cloud SDKの内部で使っているライブラリ（protobufとか）にバージョンの不一致がある せいで発生するらしい。
簡単に言えば、SDKの部品たちが「お前、ちょっと古くない？」って喧嘩してる ような感じです。

### 解決方法
解決方法は簡単！SDKで使っているライブラリのバージョンを調整してあげればOKです。

### 手順
1. 問題のあるライブラリを入れ直す
まずは、proto-plusってライブラリのバージョンを調整します。

```
pip install proto-plus==1.24.0.dev1
```

でも、これだけだと次にまた別の依存関係で怒られることがあります。なので、protobufというライブラリもインストールし直しましょう。

```
pip install protobuf==5.26.1
```

2. SDKを再アップデート！
ここまでできたら、もう一度Google Cloud SDKをアップデートします。

```
gcloud components update
```
ちゃんとアップデートできれば、エラー解決です！👍


### エラーの原因を避けるためのヒント
Google Cloud SDKやPythonのライブラリたちは、たまに「お前古すぎ！」みたいに言い合うので、重要なプロジェクトをやる前にはライブラリのバージョン確認をすると安心です。

### まとめ
Google Cloud SDKで「MessageMapContainerがない！」と言われても慌てないで、ライブラリを入れ直せばOK！って感じです。
HDL6-H12にOpenMediVaultをインストールしてみる


:::note alert
書きかけです。
不正確な情報が記載されているかもしれません。
ご了承ください。
:::

### やりたいこと
LANDISKにOpenMediaVault(以下OMV)をインストールしてbtrfsを使ってファイルサーバの構築

### なんでOMV?
導入が簡単、お金かからない、ドライブ容量がバラバラだけどいい感じに使いたい
のでbtrfs（バターエフエス）が使えてなおかつGUIでそこそこconfigをいじれるOMVを導入します。
OMVの導入方法自体はありふれているのでそんなに詳しく記述しません。詳しい導入方法を知りたい人は別の人の記事を読んでね。


### 導入
```
https://sourceforge.net/projects/openmediavault/
```
からOMVの6.0.24-amd64.isoをダウンロード

:::note warn
※2024/11/13現在
LANDISK　HDL6-H12には最新版の7.4.11はインストールできなかった。
原因は不明だが大方UEFIとかのファームが古くてインストールの時にコケるんだろう。
しらんけど。
なのでHDL4-H8EXで構築実績のあったと思われるvarを使用
:::
### 1\. rufusなどを使ってリムーバブルメディアにisoを焼く

### 2\. 筐体裏のUSBポートにリムーバブルメディア挿入
　本体の電源を入れF10、F11、delを連打
 　※HDDエラーのビープ音がする時は筐体前部のFUNKを押下

### 3\. OMVのインストーラーに沿って設定を進める
　NICの設定で数字が大きいインターフェースがNIC1に割り当てられていた。30分くらいハマった。

 
### 4\. bootloaderのインストールでコケた
openmediavault_7.0-32-amd64.iso
 をインストールした時と症状変わらず
 grubをインストールするときにコケるらしい
原因として考えられるのは
・インストール先のディスクがSSD
・BIOS（UEFI）の設定が不適
・
### 5\. 

とりあえずわからんし備忘録として途中まで記録する
TerraformでGCP BigQueryのテーブルにtagをつける

## Overview

タグを定義してResourceにつけることで、Billing上でTagごとに見たり、Tagで権限を管理したりすることができる。

今回はProject内でTagを作成する（OrgやFolderなどでもTagを作成することができる）

## Terraformの定義

### Project data resource

```hcl
data "google_project" "project" {
  project_id = var.project
}
```

### Tag key定義

```hcl
resource "google_tags_tag_key" "pii" {
  parent     = "projects/${data.google_project.project.project_id}"
  short_name = "pii"
}
```

### Tag Value定義

```hcl
# https://cloud.google.com/resource-manager/docs/tags/tags-creating-and-managing#tag-values
resource "google_tags_tag_value" "pii_confidential" {
  parent     = "tagKeys/${google_tags_tag_key.pii.name}"
  short_name = "confidential"
}

resource "google_tags_tag_value" "pii_strictly_confidential" {
  parent     = "tagKeys/${google_tags_tag_key.pii.name}"
  short_name = "strictly_confidential"
}

resource "google_tags_tag_value" "pii_topsecret" {
  parent     = "tagKeys/${google_tags_tag_key.pii.name}"
  short_name = "topsecret"
}
```

### BQのdatasetの定義

```hcl
resource "google_bigquery_dataset" "dataset" {
  dataset_id = "test_dataset"
  project    = var.project
  location   = var.region

  description = "Test iam deny policy"
}

```

### BQのtableの定義

```hcl

resource "google_bigquery_table" "confidential" {
  dataset_id = google_bigquery_dataset.dataset.dataset_id
  table_id   = "confidential"
  project    = var.project

  schema = jsonencode([
    {
      name = "id"
      type = "INTEGER"
      mode = "REQUIRED"
    },
    {
      name = "name"
      type = "STRING"
      mode = "NULLABLE"
    }
  ])

  description = "confidential"
  #   https://cloud.google.com/bigquery/docs/tags#terraform
  resource_tags = {
    (google_tags_tag_key.pii.namespaced_name) : google_tags_tag_value.pii_confidential.short_name,
  }
}
```

## 必要な権限

https://cloud.google.com/bigquery/docs/tags#required_permissions

- roles/resourcemanager.tagUser <- `resourcemanager.tagValueBindings.create` このPermissionが含まれている
- roles/bigtable.admin <- bigquery instanceにタグ付けするときには必要
- roles/bigquery.dataOwner

> To attach tags to Bigtable instances, you need the Bigtable Admin role https://cloud.google.com/bigtable/docs/tags

## Ref

- タグの作成、更新、削除、割当: https://cloud.google.com/resource-manager/docs/tags/tags-creating-and-managing

- タグアクセス管理: https://cloud.google.com/iam/docs/tags-access-control
- タグがサポートされているサービス: https://cloud.google.com/resource-manager/docs/tags/tags-supported-services


## Appendix


### gcloudで確認

まずはProjectとProject numberを環境変数に設定しておく

```
PROJECT=<your project>
PROJECT_NUMBER=$(gcloud projects describe $PROJECT --format="value(projectNumber)")
```

キーのリスト

```
gcloud resource-manager tags keys list --parent=projects/$PROJECT_NUMBER
```
```
NAME                     SHORT_NAME  DESCRIPTION
tagKeys/xxxxxxx          test
```

キーにたいするValueのリスト

上で取得したKeyのNAMEをparentにいれることでkeyがtestのvaluesをリストすることができる

```
gcloud resource-manager tags values list --parent=tagKeys/xxxxxxx
```

```
NAME                       SHORT_NAME             DESCRIPTION
tagValues/xxxxxxxxxxxxxxx  a
tagValues/yyyyyyyyyyyyyyy  b
tagValues/zzzzzzzzzzzzzzz  c
```
Windows Terminal 上の Git Bash で誤キー入力時のフラッシュを止める方法

## 事象
Windows Terminal 上の Git Bash で、カーソルが左端にある時に Backspace や 左矢印キー、右端にある時に 右矢印キー を押す度にターミナル画面がフラッシュ（白く点滅）する。

## 解決法
下記のコマンドを実行して bell-style の設定を none に変更する。

```bash
echo set bell-style none >> ~/.inputrc
```
VSCodeのクリップボードとの比較をNeovimで実装する

# はじめに
VSCodeからNeovimに移行して2週間ほど経ちました。設定も煮詰まってきて、VSCodeと比べてNeovimのここが使いにくいという箇所も大分減ってきました。
しかし、VSCodeでよく使っていたクリップボードの比較機能がNeovimに無いことが不満だったので、それを再現してみました。
Vim初心者なので、お手柔らかにお願いします。

# クリップボードとの比較とは
VSCodeのコマンドパレットから使えるあの機能のことです。
正式なコマンド名は`File: Compare active file with clipboard.`
日本語だと、クリップボードとアクティブファイルの比較。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3245561/53e82128-cb78-24a4-a9c7-1a82c64edb80.png)

このような感じで、新しいファイルを作らずともファイルの比較ができます。また、差分も強調表示されます。

# できたもの
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3245561/8b999d70-3a45-f0e6-a2cf-7e431a21c7b3.png)
`スペース(リーダーキー) b c`でこの画面が表示されます。

# 設定方法
以下のコードをお好きなところに貼ってください。
私は`Lazyvim`を使っているので、`nvim/lua/config/keymaps.lua`に書きました。

```lua
local function compare_to_clipboard()
  local ftype = vim.api.nvim_eval("&filetype")
  vim.cmd(string.format(
    [[
    vsplit
    wincmd l
    enew
    setlocal buftype=nofile | set filetype=%s
    normal! P
    diffthis
    wincmd h | diffthis
  ]],
    ftype
  ))
end

vim.keymap.set("n", "<leader>bc", compare_to_clipboard, { desc = "Compare to clipboard" })
```
このコードは元ネタがあります。

https://github.com/LazyVim/LazyVim/discussions/3300

こちらの方は予めビジュアルモードで選択したテキストと、クリップボードを比較するものであり、また比較中にファイルを編集できないので、合わないなと感じ、改良しました。
VSCodeに近い操作感に近づけられたと思います。

# 比較画面の閉じ方

:::note info
`ctrl + l`で右側のウインドウに移動後、`スペース(リーダーキー) b D`で閉じられます。
:::

元ネタのコードは`q`を押すだけで、比較画面を閉じられます。
簡単に閉じられる方法を実装しても良かったのですが、私は実装しませんでした。

# 心残り
VSCodeはクリップボードの方の右側のウインドウを編集しようとしても、編集できなくなっているのですが、私のNeovim設定だと右側のウインドウも編集できてしまいます。
右側のウインドウの方だけ、readonlyにして、左側は編集可能にするにはどうしたらよいのでしょう。
どなたかご教授お願い致します。

# おまけ
私のNeovimとWeztermの設定貼っておきます。

https://github.com/boxfish-jp/nvim-setting

https://github.com/boxfish-jp/wezterm-setting

# 宣伝
ほぼ毎日ライブコーディングとかしてます。
最近はAI Vtuber作ってます。

https://www.nicovideo.jp/user/98746932/live_programs

https://twitter.com/boxfish_jp
Lean 4の環境構築

# Leanプログラミング

Leanは数学の証明を行うための定理証明支援系システムであるが
同様のシステムであるCoqと異なり **純粋関数型プログラミング言語** でもある。

## 環境

以下の環境でインストール、及び動作確認を行った。

- OS : `Mac M1 Sonoma 14.7`
- lean : `Lean (version 4.13.0, arm64-apple-darwin23.6.0, commit 6d22e0e5cc5a, Release)`

## インストール

以下のインストールを行う。

- rustup : rust管理マネージャ
- elan : leanバージョンマネージャ
- lake : leanパッケージマネージャ
- lean : lean本体

### rustup

まず`rustup`をインストールする。

```sh
brew install rustup-init
rustup-init
```

`~/.zhrc`や`~/.bashrc`などに以下を追記して、パスを通す。

```sh
export PAH=$PARH:"$HOME/.cargo/env"
```

### elan, lean, lake

次にlean関連のコマンド群をインストールする。

以下のコマンドを実行して `elan` をインストールする

```sh
cargo install --git https://github.com/leanprover/elan.git
elan-init
```

`~/.zhrc`や`~/.bashrc`などに以下を追記して、パスを通す。

```sh
export PATH=$PATH:$HOME/.elan/bin
```

elanリポジトリを最新にした後、lean 4系をインストールする

```sh
elan self update
elan default leanprover/lean4:stable
```

以下のコマンドを実行して、インストールできていることを確認する

```sh
lean --version
lake --version
```

以下のファイルを `hello.lean` として保存する

```lean
def main : IO Unit :=
  IO.println "Hello, World"
```

以下のコマンドを実行すると、"Hello, World"が出力される

```sh
lean --run hello.lean
```

## 開発環境

### vim

以下のパッケージを利用する

- [Julian/lean.nvim](https://github.com/Julian/lean.nvim/)

ファイルのフォーマットは、NeoVim, coc.nvim でのみ対応しているとのこと

### VSCode

以下の拡張機能を導入する

- [Lean 4](https://marketplace.visualstudio.com/items?itemName=leanprover.lean4)

ファイルのフォーマットは設定しても利かないっぽい。  
また、デバッグ実行も対応していないので、printデバッグになる模様。

結局、コンソールから `lean --run`を叩くことになるので、vimで良いような気もする。

## Leanプロジェクト

以下のコマンドでlakeを利用してLeanのプロジェクトを作成できる。

```sh
lake new my-project
```

実行すると、以下のファイルやフォルダが作成される

```
.
├── Main.lean
├── MyProject
│   └── Basic.lean
├── MyProject.lean
├── README.md
├── lake-manifest.json
├── lakefile.toml
└── lean-toolchain
```

`lake build`を実行すると、以下のパスにバイナリが作成される

```sh
.lake/build/bin/my_project
```

実行すると `Hello, world!` が表示される。


### tomlファイル以外の設定方法

以下のlakeのREADMEを参照すると、`lakefile.lean`を利用すると書いてある

- https://github.com/leanprover/lake

`lakefile.lean`を利用する場合は、`lakefile.toml`は不要なので削除しておく
`lakefile.lean`の中身を以下ように書き換え、再度 `lake build` を実行すると、先ほどと同様にバイナリが作成される

```lean
import Lake
open Lake DSL

package my_project {
  -- add package configuration options here
}

lean_lib MyProject {
  -- add library configuration options here
}

@[default_target]
lean_exe my_project {
  root := `Main
}
```

### スクリプト

バイナリを作成するだけの用途では `lakefile.lean` を新規に作成する必要は無いが、
以下のようにスクリプトを追加して、実行することができる。

`lakefile.lean`に以下の`hello`スクリプトを追加する。

```lean
...
-- hello スクリプト
script hello do
  IO.println "Script!"
  return 0

@[default_target]
lean_exe my_project {
...
```

`lake run hello`と実行すると `Script!` と表示される。

## GUIについて

未対応。  
やりたい場合は、Webのバックエンドとして利用する感じになると思う。

## 関数型言語としての利用

以下のサイトに文法がまとまっているので、参考にすること

- https://lean-lang.org/functional_programming_in_lean/

## 参考

- https://ja.wikipedia.org/wiki/Lean_(%E8%A8%BC%E6%98%8E%E3%82%A2%E3%82%B7%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%88)
- https://aconite-ac.github.io/theorem_proving_in_lean4_ja/
- https://leanprover-community.github.io/install/macos.html
TanStack React Table デフォルト列表示使用時の便利なTips

TanStack Table (旧React Table) は非常に強力で柔軟なReactテーブルライブラリですが、使用する際にいくつかのTipsを知っておくと便利です。
今回はcolumn visibilityの設定に関する3つのポイントを紹介します。

### デフォルトの列表示設定

columnVisibilityの初期状態は、useStateを定義する際に同時に設定できます。

```typescript
const [columnVisibility, setColumnVisibility] = useState({
  id: true,
  name: true,
  age: false, // ageカラムはデフォルトで非表示
});

const table = useReactTable({
  // ...
  state: {
    columnVisibility,
  },
  onColumnVisibilityChange: setColumnVisibility,
});
```

この方法で、テーブルの初期表示時に特定のカラムを非表示にすることができます[6]。

### カラム表示切替プルダウンの注意点

columnVisibilityのプルダウンメニューの項目には、通常カラムのヘッダーが使用されます。
しかし、ヘッダーにソート機能を追加したり、カスタムコンポーネントを使用している場合、そのまま項目として表示されてしまい、使いづらくなる可能性があります。

### metaフィールドを使用した対応

この問題に対処するため、ColumnDefのmetaフィールドを活用できます。
metaフィールドに表示用のラベルを追加することで、プルダウンメニューに適切な項目名を表示させることができます。

```typescript
const columns: ColumnDef<YourDataType>[] = [
  {
    accessorKey: 'name',
    header: () => <SortableHeader>Name</SortableHeader>,
    meta: {
      label: 'Name' // プルダウンメニューに表示されるラベル
    }
  },
  // 他のカラム定義...
];
```

### TypeScriptでのmeta定義

TypeScriptを使用している場合、追加したmetaフィールドの型を定義する必要があります。
これは通常、プロジェクトのどこかに以下のような型定義ファイルを作成することで対応できます:

```typescript
// types/react-table-config.d.ts
import '@tanstack/react-table'

declare module '@tanstack/table-core' {
  interface ColumnMeta<TData extends RowData, TValue> {
    label?: string
  }
}
```


以上のTipsを活用することで、TanStack React Tableをより効果的に使用できるでしょう。
カラムの表示/非表示の制御が簡単になり、ユーザーにとって使いやすいインターフェースを提供することができます。
Storage Accountをファイルサーバとしてマウントする

## 結論
接続先がLinuxの場合、Azure Portalから以下を選択
* 対象SA → データストレージ → ファイル共有 → <対象ファイル>の右の「…」 → 接続 → Linuxを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606568/8fbbae07-5679-316f-7c77-7ff564837f16.png)

* 以下のようなコマンドが取得できるためそのまま対象のLinux環境に貼り付け

```
sudo mkdir /mnt/share-file
if [ ! -d "/etc/smbcredentials" ]; then
sudo mkdir /etc/smbcredentials
fi
if [ ! -f "/etc/smbcredentials/testmount0001.cred" ]; then
    sudo bash -c 'echo "username=testmount0001" >> /etc/smbcredentials/testmount0001.cred'
    sudo bash -c 'echo "password=<password>" >> /etc/smbcredentials/testmount0001.cred'
fi
sudo chmod 600 /etc/smbcredentials/testmount0001.cred

sudo bash -c 'echo "//testmount0001.file.core.windows.net/share-file /mnt/share-file cifs nofail,credentials=/etc/smbcredentials/testmount0001.cred,dir_mode=0777,file_mode=0777,serverino,nosharesock,actimeo=30" >> /etc/fstab'
sudo mount -t cifs //testmount0001.file.core.windows.net/share-file /mnt/share-file -o credentials=/etc/smbcredentials/testmount0001.cred,dir_mode=0777,file_mode=0777,serverino,nosharesock,actimeo=30
```

* 動作確認
```
touch /mnt/share-file/test.txt
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606568/74f8aae6-ba42-c356-c553-b553f884abe4.png)

## 実行コマンドの補足

* 「/mnt/share-file」にマウントするように設定している
* /etc/fstabにもマウント設定をするため、OS立ち上げ時にマウントするようになる

## おわりに
探しても意外と出てこなかったので議事にしました。
とりあえずマウントしたい場合には使えるかと思います。
以上です。
興味があるからexpressを触ってみる

# はじめに
私は主にフロントエンドを開発しているエンジニアでバックエンドはあまり詳しくわないです。（APIサーバーを軽く開発したことがある程度）
ただ興味がありexpressを触ってみようと思っただけで公式ドキュメント通りに触ってみようと思った日記になります。

# 初期設定
まず、APIの作成ができればいいと思っているので、dockerなどを使わずに、PCに入っているnode.jsを使おうと思います。DB接続などする時などはdockerなど使えばいいかなと思っていますが、まだそこまでは考えていないです。

### プロジェクトの作成
まずはプロジェクトの作成を行い、移動します。
```
$ mkdir express-api
$ cd express-api
```

### package.jsonの作成
`npm init`コマンドを使用して、アプリケーション用のpackage.jsonファイルを作成する
```
$ npm init
```
色々質問がされますが、enter連打しました。（ちゃんとやる時はちゃんと見よう）

### express.jsのインストール
expressのインストールを下記のコマンドで行います
```
$ npm install express
```

### index.jsの作成
index.jsは自分で作成しないといけないみたいなので、作成します
```
$ touch index.js
```

これで、expressのインストールは完了しました。

### HelloWorldを出力する

こちらは公式ドキュメントからそのままコピペします
``` js
    const express = require('express')
    const app = express()
    const port = 3000
    
    app.get('/', (req, res) => {
      res.send('Hello World!')
    })
    
    app.listen(port, () => {
      console.log(`Example app listening on port ${port}`)
    })
```
こちらのコードをコピペしたら、作業ディレクトリで以下のコマンドを使用してアプリケーションを実行します。

```
$ node index.js
```

ブラウザーにて以下のURLをロードしてHello worldと表示できれば完成です。
[http://localhost:3000/](URL "http://localhost:3000/")


# おわりに
今回はブラウザーでHello worldと表示しただけなので次はもっともうちょっと踏み込んでみようかなと思います。
ITエンジニアに（楽がしたくて）転職したいと思っている限界29歳のあなたに向けた記事。第五章

# 第五章.開発経験を積んだSESエンジニアのこれから。
前章で突然現場終了してしまった訳なのだが、これからはその後について書いて行こうと思う。
結論から言うと、開発経験を積むと、現場面談自体は楽勝になった。基本的には受かる自身が着いた。
サクッとその時のリアルをお送りしよう。
合計3社受けて現場が決定した感じだ。
A社：既存システムのカスタマイズ案件だった。これまでの経験もマッチしており、言語的にも業務をこなせる自信もあった。
先方からの受けも非常によく、採用のでほぼ固まっていたのだが・・・落ちた。
理由としては、この案件の商流的には、元請け→SES元会社→弊社の商流だったのだ。元請けまでの面談を済ませ、さあ採用決定！
といった時に、SES元会社内で案件に炙れた人（欠員がでた。）結果、SES元会社「メンゴ！！やっぱこっちのあぶれた人をこの案件にアサインするわ！！」
となり、落ちたのである。
※この件は、相手の会社から正式に謝罪が来たそうで、私としても納得はしている。それはそうだ。自社の社員を入れた方がうちに余計な金を払わずに
済むのだから誰だってそうする。弊社内でもしゃーないね。の雰囲気が出来たから非常に誠実な対応をしていただき感謝している。
Ｂ社：詳しく書くのがめんどいので省くが、たぶん行けたと思うが、後述のＣ社が良かったので結果を待たずに辞退した。
Ｃ社：とあるシステムの開発案件。未経験言語だが、Java系の言語の経験を評価されて採用となった。なんなら面談当日にアサインの打診があった。

どうだろうか？入社時の面談と比べるとはるかにスムーズに次案件が決まった。やはりSESエンジニアにとって重要なのは経験と経歴なのである。
もう一つ面談時に重要だと思ったのが、コミュ力である。
このコミュ力とは何なのか？それは自分がこれまで経験してきた案件・技術をいかに丁寧にわかりやすく担当者の説明できるかである。
ただ説明するだけではなく、今回の案件にで自分の経験したこの案件がマッチしているのでこの案件で自分が担当した事、どう今回の案件に生かせるかといった
事を説明するのだ。
これだけでよっぽどスキルがアンマッチしていなければ大体面談通ると思われる。
なぜ、私がこの思考に至ったか。それは今回の現場面談ですべての担当者から「君しゃべるの上手いね」と言われたのである。
正直これには面食らった。私自身、普通に普通に話をしているだけだったからだ。
前職が営業だったというのもあるのだろうが、おそらくエンジニア系の人は相手の目をみて、大きな声で、ゆっくり話をするという
当たり前のことができていない人が多いのだろうと感じた。
この事から我々のような限界エンジニアは、開発経験+コミュ力を武器に渡り合うしかないのではないのではかと思うのだ。
要するに、みんな自分の経験をはきはき、大きな声でしゃべろうね！ということである。
という事でこれから新しい現場で新規一転頑張っていこう！

ってなるかボケェ！！！

元々私は人生舐めているのである。
そもそもSESという働き方が非常に嫌いだ。なんやねん、この搾取構造は。クソオブクソである。
じゃあ、フリーランスになればいいじゃん！という声もあるのだがそれはもっともだ。
だが、正社員という立場を失うのは嫌だし、正社員という立場をしゃぶっていきたい。
そんなふざけた人間なのだ。
という訳でいつものアレだよ。アレ。開発経験も積んだしやっちゃおうぜ。
転職活動。
ぶっちゃけ給料上がるだろ。どうせ搾取されるなら給与あがるならこの際SESでもいいし、受託開発の会社にもいきてぇなぁ。
次章でその後に関して書いていきます。
ITエンジニアに（楽がしたくて）転職したいと思っている限界29歳のあなたに向けた記事。第一章

# ITエンジニアに（楽がしたくて）転職したいと思っている限界29歳のあなたに向けた記事。
今ここで記事を書いているのは、自分が営業職からIT業界へエンジニアでキャリアチェンジを行った際に、他人の体験談が少なく、少なからず苦労した経験があった。
そこで、私と似たような境遇の方へ現実を伝え、キャリアチェンジへのある程度に指標になればと思い書き下ろす事にした。
※注意してほしいのだが、私の記事では、他の素晴らしい記事を書いている方のような自己学習をして～などといった記載は一切ない。
単純に現職が嫌で逃げるような人に向けた記事なので意識はと～っても低いので、いわゆる真面目系クズにむけた記事である事を留意していただきたい。
自分と似た境遇の方や、30歳以上の方のITエンジニアへのキャリアチェンジの参考になればと思う。
あと、筆者の生息域が関東ではなく、地方（政令指定都市です。）である事を留意してほしい。

筆者について。
現在の年齢は32歳になる。
エンジニアに転職したのは29歳になり、IT業界自体は3年経験。2025年で4年目に突入という形。
経験業務に関しては大きく以下の様になっている。
1.金融システムの保守・改修業務
2.企業の基幹システム開発業務
使用技術：
バックエンド言語系　：Java/PHP
フロントエンド言語系：JavaScript/HTML/CSS
フレームワーク　　　：SpringBoot/Node.Js
DB言語　　　　　　　：MySQL/PstgrySQL/DB2
その他　　　　　　　：VABを使用したツール作成。
参画フェーズは詳細設計→製造→単体テスト→結合テストまでだ。
ここから営業→ITエンジニアへの転職の動機と流れについて書いていく。


## 第一章.なぜITエンジニアになろうとしたのか。
これに関しては前職の営業という職業が個人的に苦痛だったからである。
その理由としてはもちろん、”営業ノルマ！！”だ。
しかし、営業マンとしては、会社の商品を売って会社へ利益を上げなければ価値などないのだからあるのは当たり前である。
営業時代の会社はバリバリの営業（ノルマ未達だとバリバリ詰められる）といった会社ではなく、緩いルート営業だった。
もちろん、その中でもノルマは必ずあり、未達だと大なり小なり詰められる。
まぁ、営業回り中に昼寝などしてサボれるといった職業特権もあるのだが・・・
そんな中で、同じ社内の技術職の方は、そういったノルマ等は無く、社内で1日中仕事を行えており、とても楽そうに
見えたのである。
（今思うと、とんでもない馬鹿垂れ思考である。）
そういった事で自身の中で、ノルマに怯えずに社内でゆっくり働ける技術職っていいな・・・という憧れが募っていく毎日を送っていた。

そして、時はコロナ過。例のあの広告が大量に飛ぶことになる。
”エンジニアになれば、フルリモート！！高収入ではたらけるぞ！！”等のプログラミングスクールの広告だ。
この悪魔の広告を見て、自分もエンジニアに！！なんて考えた情弱が（もちろん私も含めてだ）大量に沸いたのは言うまでもない。
あと、エンジニアだと出張とか1日中営業回りせずに社内居れて楽そうだし、私服勤務でスタバ片手に楽に仕事をできそうといったアホな理由もたくさんある。
そうして、色々あり私は地元に戻るタイミングで営業職→ＩＴエンジニアへなろうと決意したのである。
心拍数の計測

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/1cae85db-d2e4-5ac8-2adb-6ca13b87379a.png)

# はじめに
心拍数のログを取りたいけど、いいアプリがない。
30分ぐらい記録したい。
心拍センサ動かない。
画像解析（頬の緑）にも失敗。
無料で。

ということがあったので、メモ。

「カイジごっこ」ができる。

# 環境
iPhone 12 mini(ライトとカメラが近ければ、なんでもよい)
Processing 4.2
Video Library GStreamer 1.20.3
エクセル

# 動画撮影
スマホのカメラの設定で、1280x720 30fpsなど、一番小さいフォーマットを選択。
HDRで撮影すると面倒なので、互換性優先のmp4フォーマットを選択。
スマホのライトを付けた状態で、指でカメラを塞いで、撮影。

# 動画からCSVへ
プログラム保存場所の下にdataフォルダを作って、動画ファイルをいれる。

```java
import processing.video.*;

PrintWriter output;

Movie mov;

void setup() {
  size(160, 90);
  output = createWriter("out.csv");
  mov = new Movie(this, "heartbeat.mov");//data folderにいれる
  mov.play();
}

void movieEvent(Movie m) { 
  m.read();
}

void draw() {    
  image(mov, 0, 0, width, height);
  float r = red(get(80,45));
  output.println(millis()+","+r);
  
  if(mov.isPlaying()==false){
    output.flush();
    output.close();
    exit();
  }
}
```

# CSVからグラフ作成
CSVをエクセルで開き、挿入＞グラフ＞散布図をいれると、本投稿の頭にあるグラフが得られる。

# ファイル容量
変化の少ない動画のせいか、30秒で2MBだったので、30分はいける気がする。
コミュニケーションロボット開発ゆるゆる記録 No.1

## 簡単な自己紹介
　はじめましてへっぽこプログラマーのババです。2年ほどRailsエンジニアの仕事をちょろっと経験した後に、頭が悪いためやっぱり個人でゆるゆる開発したいと思い退職し子ども部屋おじさんに戻りました。

 　それでは子ども部屋おじさんに戻ってまで何を作りたいかと言えば、重度障害者用のコミュニケーションロボットなわけです。

## ロボットに相手をしてもらいたい
　なんでまたそんなソーシャルグッドなものをと言われそうですが、まぁシンプルに身内に言葉も使えず家族の介助がないと、何一つ生活ができない兄妹のためです。

   取り立て家族思いとかそういうわけではないのですが、周りに家族がいない場合、ただテレビを見ている生活はあまりにもつまらないだろうと思い、相手をしてもらえるロボットを作ってみようと考えています。

## とりあえず簡単なモノから作ります
   とはいうものの対して開発経験もないし、頭も悪いし、集中力もないし、根気もないし、金もないの無い無いずくしない愛嬌だけが取り柄の人間です。

　システム構成とか、先にいろいろ考えて開発するなんて到底できません。そのため、まずは何も考えず、最低機能からステップバイステップで開発していこうと思っています。
 
## ということでとりあえずここ最近やっと手を動かしたこと
　というRaspberry piを使って簡単な会話BOTを作ろうと思いました。
 まず考えたのは以下の機能で考えました。

> 1. スピーカから音を出す。
> 2. 文字ベースでGPTのチャットボットを作成する。
> 3. 文字入力に対して音声で返答する。
> 4. 文字入力を音声入力に変更する。

　一応現状は3番まで一旦作り終えました。ただOpenJtlakで初音ミクの声でしゃべらせたのですが、ちょっと遅くってカタコトの中国人みたいになってしまったので、Voice boxかGoogle TTSで作り直そうと思っています。

 ## とりあえずここまでの開発記録
　開発記録といいましたが、ほぼ参考記事を見ながら作っているので、まずは忘備録的に参考記事のみ記載していきます。

 ### ステップ1 ラズパイのセットアップ
 これはいろんな人が記事を書いてくれているから助かります。

 ### ラズパイからスピーカー経由で音声再生
 スピーカーからの音声再生を以下の記事を参考にして実装しました。
 スピーカーは昔にかった100均かAmazonで購入したやっすいジャック付きのスピーカーです。

 一応こだわった点は、再生ファイルにはっぴいえんどのしんしんしんって曲をwavファイルで再生したことです(厳密にいうとキセルがカバーしたバージョンです、どっちでもいいですよね(*´Д｀))

 [Raspberry Pi と Python を使ったブラウザ設定【目覚まし時計】](https://canmakewakuwaku.com/rasppi_alarm/#toc3)

### GPTのチャットボット
無事、この寒い季節にちょうどよい音楽ながれたので、次のフェーズに移ります。
さぁチャットボットを開発するぞ！ということですが、またまたちょうど良い記事がありました。
もうまるパクリです。

[PythonでGPT-4 Turboを使用したシンプルな対話型AIチャットボットの構築](https://qiita.com/YokohamaHori/items/5063ba4c6737ac930850)

 ### 音声でチャットの応答結果を再生
 さてここまでの段階で、ゆうに5日くらい経過してます。振り返ると、秒で終わりそうなのに、ラズパイセットアップしたり、部屋のガジェットを整理したり、ウクレレ引いたり、友達と飲んでいたら、あっという間でした。

 どうやら開発における最大の障害は、僕の心のやばいやつなのかもしれません。

それはさておき音声再生は以下の記事を参考にしました。

[OpenJtalkでおしゃべりする](https://zenn.dev/kotaproj/books/raspberrypi-tips/viewer/038_kiso_openj)

上記記事を参考にまずはラズパイでOpenJtalkでテキストを再生できるようにしました。

そこでふとOpenJtalkに初音ミクの音声で喋らせている人がいましたので、そちらを参考にしました。

[Open JTalkで初音ミクの声でおしゃべりさせる on Mac/Linux/Raspberry Pi](https://karaage.hatenadiary.jp/entry/2016/07/22/073000)

ただこの記事にのっている初音ミクの音響モデルをhtsvoiceへ変換するプログラムのオリジナルのリンク先が無くなっていたので、以下の記事を参考に変換プログラムをゲットしました。

[ゆかりねっとで初音ミクの声を使う](https://qiita.com/akaharaimori555/items/a7d95e682bbd7381e273)

### テキストto音声まで完成( ｀ー´)ノ
とまぁこんな感じですが、実際ラズパイ4で動かしてみると、音響モデルの処理がめっちゃ遅い、カタコトの中国人みたいな喋りになってしまいました。。。

これはちょっと改善しないといけないです。
Google TTSの利用か、Voice Boxをwindowsで動かしてAPIで利用する方向のどちらかを検討しています。

まぁ拙者の性質上、なかなか迅速に行動できないので引き続き開発しようと思っています。
AWS Secrets Manager でシークレットを即削除したいときは CLI を使う

SSIA ですが、Secrets Manager でシークレットを削除しようとすると、スケジュールによる削除となる旨の表示がでます。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2080620/89300eb1-321d-744a-a69b-899cb4ecc476.png)


削除スケジュールを実行すると削除予定(待機期間)である旨の表示になります。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2080620/f50faa72-153a-9e3a-59ec-7f44c309303e.png)

:::note
画面上では、待機期間(7~30日)を設定の上削除するしか方法はありません。Terraform でも同様です。
待機期間中はもちろん同名での再作成も出来ません。
:::

**即時削除したい場合は CLI で可能です。**

`aws secretsmanager delete-secret` に `--force-delete-without-recovery` オプションを付けて実行します。

```
$ aws secretsmanager delete-secret --secret-id test-secret-2 --force-delete-without-recovery
```
[AWS CLI Command Reference - delete-secret](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/secretsmanager/delete-secret.html)

結果
```
{
    "ARN": "arn:aws:secretsmanager:ap-northeast-1:999999999999:secret:test-secret-2-xVYjjZ",
    "Name": "test-secret-2",
    "DeletionDate": "2024-11-13T19:20:21.737000+09:00"
}
```


## ref
- [AWS CLI Command Reference - delete-secret](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/secretsmanager/delete-secret.html)
- [AWS Secrets Manager シークレットを削除する](https://docs.aws.amazon.com/ja_jp/secretsmanager/latest/userguide/manage_delete-secret.html)
androidアプリ canta カウンターアプリ

# androidアプリ「canta」紹介
私たちは、日常生活の中でいろいろなことを数えておきたいと思っています。
たとえば、食べたパンの数や人に優しくできた回数です。
「canta」はユーザーがカウントする項目を自由に登録して、カウントすべき時にカウントを入力して記録しておけます。
また、記録したものをリスト表示したり、月間の集計を表示したりできます。

## カウント画面
![count_page.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663059/5cdb2df2-7294-65b8-11f9-f7149a4005b6.png)
カウントする項目を登録したり、カウント入力を行うことができます。


## レコード画面(リスト表示)
![record_list_page.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663059/29a5e33c-305f-792f-8146-19d2f68dcf99.png)
記録したカウントを一覧で表示することができます。

## レコード画面(月間表示)
![record_monthly_page.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663059/14175bc2-3101-fee8-ce0c-dd1ab3c0a841.png)
月間の集計をすることができます。

## プライバシーポリシー
このアプリでは
ユーザーの個人情報を収集しません。
データを使用端末以外へ送信する通信機能はありません。
課金機能はありません。

## 最後に
まだまだ荒い部分があるからブラッシュアップしていくんだ。
洗練させて人の役に立つものを作るんだ。
Macでzshからbashへ切り替え後にHomebrewとnvmが動作しない問題の解決方法

## はじめに

こんにちは、未経験からエンジニア転職を目指しているものです。

オンラインスクールで本格的に学習して6ヶ月目に入りました。PokeAPIを使用してAPIの学習をしていたところ、シェル環境の切り替えによってHomebrewやnvmが反映されなくなり、その対処方法を調べた内容をまとめました。

## 経緯

Node.jsとviteを使用してプロジェクトを作成しようとしましたが、以下のコマンドを入力しても反応がありませんでした。

```bash
npm create vite@latest
```

以前はHomebrewとnvmをインストール済みで、Node.jsもインストールしていましたが、Laravel Sailを利用する際にzshからbashに切り替えたことが影響しているようでした。

## bashに切り替えたことで発生した問題
シェルをzshからbashに変更したため、zsh用の設定（~/.zshrcに記載していたHomebrewやnvmの設定）が読み込まれなくなりました。このため、bash用の設定ファイルである~/.bashrcに同様の設定を追加する必要がありました。

## シェルの確認方法
まず、自分の現在のシェルを確認するために、以下のコマンドを実行します。

```bash
echo $SHELL
``` 

**設定方法**
**1. bashでnvmを使用するための手順**
- ~/.bashrcにnvmの設定を追加
- ~/.bashrcに以下の内容を追加します。これは、nvmのインストール時に~/.zshrcに追加した内容と同じです。

```bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
```

**設定を反映**
以下のコマンドで設定をすぐに反映させます。

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

**設定確認**
bashで以下のコマンドを実行し、nvmが正しくインストールされているか確認します。

```bash
nvm --version
```

**2. npm create vite@latestの再試行**
設定が完了したら、以下のコマンドを実行して、プロジェクトが作成できることを確認します。

```bash
npm create vite@latest
```

## まとめ
シェルの切り替えに伴ってHomebrewやnvmが動作しなくなる問題に対して、bashでも同様に設定する方法を説明しました。未経験から学習している中で、シェルの切り替えが意外なところで影響することを学びました。この記事が同様の問題を抱える方の参考になれば幸いです。

最後までご視聴頂きありがとうございます。