OmniAICreator/Qiita-1.07M huggingface dataset:
stimulus-railsのChartjsでエラーが出たときの対処法

`importmap-rails`ってちょっと難しい。

- Rails: 7.1.4
- Ruby: 3.2.4
- stimulus-rails: 1.3.4

`importmap`で`Chart.js`を追加する方法が記載してある。

https://www.stimulus-components.com/docs/stimulus-chartjs

しかし、この通り進めていくとブラウザのConsoleでエラーが出た。

```console
GET http://localhost:3000/_/BgY37SKS.js net::ERR_ABORTED 404 (Not Found)
```

何かしらのファイルを見つけられていない。
同じ様なエラーに遭遇した人がIssueを建てて対応された様だが

https://github.com/stimulus-components/stimulus-components/issues/97

多分、まだ`stimulus-rails`が対応できてない🤔

```zsh
:/app# bundle update --conservative stimulus-rails
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Bundler attempted to update stimulus-rails but its version stayed the same
Bundle updated!
```

色々調べると、`Chart.js`をCDNで取得するとエラーが起きないと回答する記事を見つける。

https://stackoverflow.com/a/78657266

これで動いたが、`stimulus-rails`を使用したい。
`stimulus-rails`はラッパーなので
生の`Chart.js`の取得先をCDNに変更すればいいのでは⇩（バージョンも合わせる）

```diff:config/importmap.rb
pin "@stimulus-components/chartjs", to: "@stimulus-components--chartjs.js" # @6.0.1
pin "@kurkle/color", to: "@kurkle--color.js" # @0.3.2
- pin "chart.js" # @4.4.6
+ pin 'chart.js', to: 'https://ga.jspm.io/npm:chart.js@4.4.6/dist/chart.js' # @4.4.6
```

これでひとまず解決（？）した。
AWS AppStream 2.0とAmazon WorkSpacesの違いのまとめ

# まとめ表
|特徴|AWS AppStream 2.0|Amazon WorkSpaces|
|:-|:-|:-|
|主な用途|アプリケーションストリーミング、特定のアプリケーション（例えば、CAD ソフトウェア、デザインツール、開発環境など）をリモートで利用することが目的|仮想デスクトップ環境の提供、デスクトップ環境をクラウド上で提供し、Windows や Linux のフルデスクトップをリモートで利用することが目的|
|ユーザー体験|アプリケーションのみ、ブラウザまたはクライアント経由|フルデスクトップ環境、PC のように使用可能|
|リソース提供|アプリケーション単位で提供|完全なデスクトップ環境|
|ストレージ|外部ストレージやローカルストレージ利用（S3のようなイメージ）|永続的な仮想デスクトップストレージ（EBSのようなイメージ）|
|スケーリング|動的にスケーリング、アプリケーション単位|固定のデスクトップインスタンス|
|コスト|従量課金制、アプリケーション単位|月額制、デスクトップインスタンス単位|

# 参考サイト
弊社ブログをぜひご覧ください～

https://www.beex-inc.com/blog/what-is-appstream

https://qiita.com/Masayuki-Goto/items/8a8320fdfaf1058baf66
Python2系を使いたくなった時、WSL2のDebianで叩いた呪文


自分用にメモ
BurpのExtension開発環境が欲しくなった時などに使用。

``` WSL Debian
sudo apt install --yes make zlib1g-dev gcc wget
curl -LO https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz
tar xf Python-2.7.18.tgz
cd Python-2.7.18
./configure
sudo make & make install
```
タスクバーのウィジェットを消したい！

## 前提
- Windows11を使っている方（もしかしたら10でも同じかも）
- Windows PC Managerを使っている方↓

https://apps.microsoft.com/detail/9pm860492szd?launch=true&mode=full&hl=ja-jp&gl=jp&ocid=bingwebsearch
- ウィジェットを消す派の方
## 前置き
パソコンで作業をしているとメモリ使用量が多くなって悩むことがあると思います。そんな時にメモリ開放アプリを使っている方もおられるのではないでしょうか。

私はWindows PC Managerを使っています。使い方も簡単で、Microsoftが開発したアプリなので安心して使えるといえるのではないでしょうか。

現在では日本語にも対応し、必要な機能が揃っており快適に使用しています。

https://pcmanager.microsoft.com/ja-jp

## タスクバーのウィジェットを消したい
タスクバーの左下にウィジェットってありますよね。タスクバーのピン止めが増えてくると、ウィジェットでスペースがとられてしまうと嫌じゃないですか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3871342/d88fc6b8-e848-00d1-1554-de35f975d8bc.png)
なので私はいつも個人用設定＞タスクバーでウィジェットの表示をオフにしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3871342/0a7e4500-ba4e-af28-ea1a-c6c1dc88ccc5.png)

### 問題発生
しかし、この設定が毎回リセットされており、ストレスを感じていました。そのたびにオフにしますが、設定アプリを立ち上げたりと作業が中断され、どうにかならないものかと考えていました。

### 早速解決策発見
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3871342/a4cd7d1d-444c-e9d0-f76a-28f7a50a1cf7.png)

原因はこのWindowsの規定値＞タスクバーのリセットにチェックが入っているからでした！

このチェックが入ったまま右上の続行を押すと、タスクバーのリセットが行われ、ウィジェットの設定が規定値のオンに代わり、ウィジェットが表示されるということです。

このチェックを外し、続行することでタスクバーのリセットは行われず、解決ということです。かなりニッチなケースですが、同じ悩みを持った方に届けば幸いです。

## 最後に
Windows PC Managerを使わなくていいくらいメモリの多いパソコンを買いたいです。
コーディングに関連するワードをまとめる

# はじめに
自分がメモしたいなと思ったワードを書いていきます
(気が向いたら更新していくスタイル)
この記事は、新卒エンジニア(2024年時点)が書いています。
解釈違いがあるかもしれないので記事の内容を参考にする前にセカンドオピニオンは必須としてください。
記事内に貼り付けるソースコードは全てpythonとします。

# アンチパターン系

## ハードコーディング（Hard Coding）
>ハードコーディングとは、本来分離して管理すべきデータや設定値を、ソースコード内に直接埋め込むことを指します。例えば、認証情報やAPIキー、データベース接続情報などをコードに直接書き込むケースです。こうした方法は一時的には便利ですが、コードの変更や管理が難しくなり、特に大規模なシステムでは管理が複雑化することがある。

### 参照元
QiitaTeam
https://teams.qiita.com/hard-coding-meaning-avoidance-beginner-guide/

### アクション

#### envファイルを使用する
https://qiita.com/shown_it/items/2b85434e4e2658c484f4
``` python
pip install python-dotenv
```
``` python
from dotenv import load_dotenv
import os

# .envファイルを読み込む
load_dotenv()

api_key = os.getenv("API_KEY")

if not api_key:
    raise ValueError("APIキーが設定されていません")

```

#### Docker Secretsを利用する
https://qiita.com/myabu/items/89797cddfa7225ff2b5d

#### クラウドサービスのSecrets Managerを利用する
https://qiita.com/hp-Genqiita/items/f93285a6058c64b39f23

# 原則法則系
この項目は自分用にチューニングしていることが多いと予測されるので参考にするのは非推奨

■原則の意味
>一般の現象に共通な法則。特別の例外が起こり得ることを念頭において、一般に適用されるものとする基本的な考え方。


## YAGNI(You Ain't Gonna Need It)の法則 (ヤグニのほうそく)
https://zenn.dev/miya_tech/articles/d53057f50e53ff

予測による実装が実際に役立つことは少ないという経験則から生まれた原則
- 関数に将来使いそうなオプションを実装するとか？
- プロジェクトの状況は刻一刻と変化するため、予測に基づく実装が修正なしに役立つことが少ない
- 優先順位や費用対効果意識って感じかな
- 業務なら、レビューやリーディングといった自分以外のアクションも想定しないとね

## DRY (Don't Repeat Yoursel)原則
>DRY原則を破るということは、同じ知識を２箇所以上に記述することです。この場合、片方を変更するのであれば、もう片方も変更しなければならない

- これ自体はごもっともと感じる
- じゃあ何でもかんでも思考停止して重複を消そうとすると問題が発生するのが難しいところ

■参考記事

https://qiita.com/yatmsu/items/b4a84c4ae78fd67a364c

■ 「コードに早まってDRY原則を適用しないこと」とGoogleが呼びかけ
- 異なる責務を持つ予定なのに、初期の段階では完全重複してるからと1つにまとめると変更を加えるときに大変になる

https://gigazine.net/news/20240605-google-not-dry-prematurely/#:~:text=DRY%E3%81%AF%E3%80%8CDon't%20Repeat,%E5%8D%B1%E9%99%BA%E6%80%A7%E3%81%8C%E9%AB%98%E3%81%BE%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82

■ DRYかどうかの前に単一責務かどうかを考える
- 責務が違うのに安易に共通化すると最初は良くても後々負債になる

https://speakerdeck.com/leveragestech/dryyuan-ze-wowu-tutajie-guo-sheng-maretaji-shu-de-fu-zhai
welcome.confについて[Apache]

みなさまごきげんよう。

今までAacheのドキュメントルート以下にサイトで表示させたいファイルを持ってくるものだと思っていたが若干知識が足りてなかったのでメモとして残します。

## やってみて詰まったこと
まず初めにApacheをインストールしてドキュメントルート以下にファイルを作成した。
```
# 作成したファイル
/var/www/html/test.html

# ファイルの中身
You don't like it huh?
```

そしてApacheを開いてみると。。。

![スクリーンショット 2024-11-23 11.19.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704144/35c31446-43f8-ddac-dece-7c456c3c2ae3.png)

ちゃうねん、、、It works! じゃなくて、作ったファイルを表示させたいのよ、、、、


## 調べてみてわかったこと
Apacheを起動してサーバーのIPアドレスで検索したのですが、ここに理由が詰まってました。
```
http://XXX.XXX.XXX.XXX/
```

上記で検索するとルートディレクトリを表示させてしまうので、以下のファイルが動いてくれてAiliasしてくれてるみたい。
```
/etc/httpd/conf.d/welcome.conf
```
中身はこんな感じ

```
#
# This configuration file enables the default "Welcome" page if there
# is no default index page present for the root URL.  To disable the
# Welcome page, comment out all the lines below.
#
# NOTE: if this file is removed, it will be restored on upgrades.
#
<LocationMatch "^/+$">
    Options -Indexes
    ErrorDocument 403 /.noindex.html
</LocationMatch>

<Directory /usr/share/httpd/noindex>
    AllowOverride None
    Require all granted
</Directory>

Alias /.noindex.html /usr/share/httpd/noindex/index.html
Alias /poweredby.png /usr/share/httpd/icons/apache_pb3.png
Alias /system_noindex_logo.png /usr/share/httpd/icons/system_noindex_logo.png
```

LocationMatchディレクティブが囲まれた設定は、ルートディレクトリ（/）にアクセスされた場合、ルートディレクトリを表示させないようにし（Options -Indexes）、代わりに、/.noindex.html を表示するという設定されてます。

そんでAilias先のファイルを見てみると、It works!って書いてありました。

つまりIP/で検索するとRoot directoryが出てきちゃうわけね。。。

## 自分の認識の相違
ドキュメントルート以下にファイルを作成してIP/で検索すれば作成したファイルが出てくると思っていたこと。これが認識が違っていた。
ちゃんと以下のように指定しなければいけない。
```
http://XXX.XXX.XXX.XXX/test.html
```
そうすれば作成したファイルが表示されました。。

## 所感
エンジニア始めてから2年以上経ちましたが今更かよって感じがしました。。。
ちゃんと勉強しないとな、、、、、
atcoder練習(2024.11.23)

# キーワード

# 問題
https://atcoder.jp/contests/abc381/tasks/abc381_a

文字列 T が以下の条件を全て満たすとき、T を 11/22 文字列と呼びます。

|T| は奇数である。ここで、|T| は T の長さを表す。

1 文字目から (|T|+1)/2 - 1 文字目までが "1" である。

(|T|+1)/2 文字目が "/" である。

(|T|+1)/2 + 1 文字目から |T| 文字目までが "2" である。

例えば "11/22", "111/222", "/" は 11/22 文字列ですが、"1122", "1/22", "11/2222", "22/11", "//2/2/211" はそうではありません。

1, 2, / からなる長さ N の文字列 S が与えられます。S が 11/22 文字列であるか判定してください。

制約

1 ≤ N ≤ 100

S は "1", "2", "/" からなる長さ N の文字列

入力

入力は以下の形式で標準入力から与えられます。

N
S

出力

S が 11/22 文字列であれば Yes を、そうでなければ No を出力せよ。

入力例 1

5
11/22

出力例 1

Yes

"11/22" は問題文の 11/22 文字列の条件を満たします。

入力例 2

1
/

出力例 2

Yes

"/" は問題文の 11/22 文字列の条件を満たします。

入力例 3

4
1/22

出力例 3

No

"1/22" は問題文の 11/22 文字列の条件を満たしません。

入力例 4

5
22/11

出力例 4

No

"22/11" は問題文の 11/22 文字列の条件を満たしません。


# 回答
```Python
N = int(input())
S = input()

if N % 2 == 0:
  print("No")
  exit()

K = int((N+1)/2)
A = "1" * (K-1)
B = "2" * (N-K)

if S.startswith(A) and S.endswith(B) and S[K-1] == "/":
  print("Yes")
else:
  print("No")

```

# 参考

# 備考
- `A = "1" * (K-1)`これできるの！ずっとfor文で書いてた。
- 比較的簡単にサンプルの問題はすべてクリアできた。一方で、テストはずっと3問ぐらい間違えていて、その特殊な状況に対処できなかった（今でも結局よくわかってない）。
- if文でandが2つ重複しているのは若干気に入らない。まぁでも動いたからよし
初心者プログラミングバイト18日目【勉強を定石化できた】

あるシーンのコードを見て、それを書き写しながら、時に我流で書いたりする中で、いろんな関数、文法を吸収して、コメントアウトで書いていく。

今の所これが、結構自分にはハマってる。
Express＆React(vite)を使用したWebアプリ作成用の環境構築その１

## はじめに
参照：https://ralacode.com/blog/post/create-nodejs-react-app-with-typescript/
下記の環境を構築する
- バックエンドをExpress
- フロントエンドをReact(vite)
- バックエンドとフロントエンドはTypescriptを使用する

## node.jsの環境構築
### node.jsインストール
node.jsのバージョン管理をするためにnvmを使用したい
下記の記事を参考にインストール
https://qiita.com/akipon0821/items/eaeffe79221cfcd4d258

メモ
nvm version　：バージョン確認
nvm list　:インストールしてあるnodeのリスト確認
nvm install バージョン番号　:指定したバージョンのインストール
nvm use バージョン番号　:指定したバージョンを使用可能にする　
node -v ：node.jsのバージョン確認

### プロジェクトフォルダを作成
任意の場所にプロジェクトフォルダを作成する
その配下にバックエンド用とフロントエンド用のフォルダも作成する

### バックエンドのpackage.json作成
cmdでバックエンドフォルダに移動して以下のコマンドを実施する
`npm init -y`

### Typescriptを使用するための準備
次にTypeScriptを使う準備をします。
2つのパッケージをインストールします。
- typescript
- @types/node

バックエンドフォルダで下記コマンドを実行
```
npm install -D typescript @types/node
npx tsc --init
```
実行後、「backend」の中に「tsconfig.json」が作られます。
「tsconfig.json」はTypeScriptに関する設定を書くところです。

tsconfig.jsonの内容を書き換える
`"target": "es2022"`
コメントアウトされているmoduleResolutionを有効化し下記ような設定にする
`"moduleResolution": "node"`


node.jsのバージョンで記載する内容が変わるため調べる
以下を参照
https://gist.github.com/azu/56a0411d69e2fc333d545bfe57933d07

### Expressを使用する準備
ReactとNode.jsが接続をするのに必要
Expressをインストール
ターミナルで以下のコマンドを実行
```
npm install express
npm install -D @types/express
```
バックエンドフォルダに「server.ts」というファイルを作る
※名前はなんでもいい
```
/* server.ts */

import express from "express";

const app: express.Express = express();

app.listen(3000);
```

package.jsonのmainの部分に「server.js」と記載
cmdで下記コマンドを実行する
tsファイルの変更を監視し、jsファイルを更新する
```
npx tsc -w
```

上記とは違うcmdを立ち上げ下記コマンドを実行する
```
node --watch-path=./dist server.js
```


nodemonを使用しないでnode --watchを使用する
https://zenn.dev/morinokami/articles/npm-uninstall
【プロダクトマネジメント】Howはプレイヤーに任せよう！

## はじめに
私は、ここ2年ほどQiitaのPdMとして働いてきました。
そんな中で、私が感じたのは、「Howはプレイヤーに任せよう！」ということです。

具体的には、PdMはWhy（なぜやるのか）やWhat（何をやるのか）、When（いつやるのか）を考え、プレイヤーにHow（どのようにやるのか）を任せるということです。

そのため、この記事では、「Howはプレイヤーに任せよう！」と思った理由、Howをプレイヤーに任せることで何がいいのかを紹介しようと思います。

## 「Howはプレイヤーに任せよう！」と思った理由
私は、3年ほど、プレイヤーとして、UIやUX・フロントエンドを中心に働いていました。
その後、PdMになったため、1年くらいHowもざっくり考えながら、プロダクトマネジメントを行っていました。

そんな中で、「Howはプレイヤーに任せよう！」と思った理由は、以下の3つです。

+ プレイヤーのほうが仕様について詳しいと感じたため
+ What（何をやるのか）に時間を使いたいと思ったため
+ Howまでちゃんと考える時間がなくなったため

### プレイヤーのほうが仕様について詳しいと感じたため
1年以上、ちゃんとプロダクトをデザイン・開発していないと細かい部分への理解度は下がっていくものです。
時間が経過すると忘れるのはしょうがないことですが..

具体的には、ビジネスメンバーから仕様についての質問を受けた時に、「こういう仕様です」と自信を持って答えられなくなっており、「論理的に考えればこうなっているはずです。ちょっとコード確認しますね」みたいな回答が多くなっていました。

このような人がHow（どのように開発するか）を決めるには、プロダクトの理解が足りないと感じたことが理由です。

またそれだけではなく、プレイヤーが同じ問に対して、自信を持って、すぐに回答しているのを横で見て、任せられると感じたため、決心ができました。


### What（何をやるのか）に時間を使いたいと思ったため
プロダクトマネジメントをやっていると、Why（なぜやるのか）、What（何をやるのか）、When（いつやるのか）を考え、できるだけ成果を出すことを求められます。

そのため、限られた時間の中で、最大の成果を出すためにより正確にWhat（何をやるか）に時間を使うべきだと感じ、任せられる部分は、プレイヤーに任せようとなりました。

また、プレイヤーにHow（どのように開発するか）を任せることで、彼らの専門性や創造力を活かしつつ、自分自身はより戦略的な部分に集中することができそうだと考えました。

### Howまでちゃんと考える時間がなくなったため
「What（何をやるのか）に時間を使いたい」と似ていますが、多分これが、大きな理由の一つです。

複数のパイプラインでデザイン・開発を進めていく中で、全てのパイプラインでHowまでPdMが考えるのは、時間的に無理があったためです。

また、複数のパイプラインだけでなくても、他にもやりたいことがあり、それらが後回しになっていたという現状でもありました。

そのため、複数のパイプラインや他のやりたいことをやれるようにするため、Howをプレイヤーに任せるようになりました。

## Howをプレイヤーに任せるメリット

Howをプレイヤーに任せるメリットは以下の3点だと思います。

1. プレイヤーが最適な方法を考えることで、創造性や柔軟性が向上すること
1. プレイヤーの主体性が高まり、モチベーションが向上する
1. チーム全体のスキル向上につながること

### プレイヤーが最適な方法を考えることで、創造性や柔軟性が向上すること

プレイヤーにHowを任せると、自分たちの専門知識や経験を活かして、より効果的で創造的なアプローチを模索することができます。

PdMがHowを細かく決めてしまうと、解決策が固定化され、最適な結果が得られない場合があります。
しかし、プレイヤーに裁量を与えることで、柔軟な発想や新しい視点が生まれ、チーム全体でより良い成果を追求することができます。

たとえば、新しいUIコンポーネントの実装においても、プレイヤーがその時点での最新の技術やライブラリを提案することで、より優れたユーザー体験を提供できることがあります。
PdMがHowを細かく指示していた場合、これらの可能性を見逃してしまうこともあるため、任せることで得られる柔軟性は非常に大きなメリットとなります。

### プレイヤーの主体性が高まり、モチベーションが向上すること
1. プレイヤーが自らの方法で問題解決を行うことで、責任感と達成感が得られる

Howを任せることは、プレイヤーに「自分たちがプロジェクトの重要な一部である」と感じさせる絶好の機会でもあります。
自分たちの意見やアイデアがプロジェクトに直接影響を与えることが分かると、責任感が芽生え、仕事へのモチベーションが大きく向上します。

また、プレイヤーが自分でHowを考え、それが実際に成果として現れた場合や大変な中やり切ることができれば、大きな達成感も感じることができます。
この達成感は次のプロジェクトへのモチベーションにもつながり、チーム全体の士気を高める効果があると思います。

### チーム全体のスキル向上につながること
プレイヤーがHowを考える機会を持つことで、自ら調査を行い、新しい技術や手法を学ぶ習慣が自然と身につきます。このプロセスは、個々のスキル向上だけでなく、チーム全体の知識の底上げにもつながります。

また、プレイヤー同士がHowについて議論を交わすことで、知見の共有が進み、結果としてより強いチームが形成されます。


## まとめ

Howをプレイヤーに任せることは、PdMにとっての時間的・戦略的なメリットだけでなく、チーム全体の成長と成功にもつながります。
PdMはWhyやWhatに集中し、プレイヤーに創造性と自由を与えることで、より良いプロダクトを生み出すサイクルを作ることができるのです。

この記事を通して、「Howはプレイヤーに任せよう！」という考え方が、チーム全体の成功を目指す上でどれだけ重要かを共有できれば幸いです。あなたのチームにおいても、このアプローチが役立つことを願っています。

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaで記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510
VercelでCORS【Access-Control-Allow-Origin: *】

すべてのapiでCORSが有効になります。POSTメソッドを使う場合は、OPTIONSも追加必要かもです

```vercel.json
{
  "headers": [
      {
        "source": "/(.*)",
        "headers": [
          { "key": "Access-Control-Allow-Origin", "value": "*" },
          { "key": "Access-Control-Allow-Methods", "value": "*" },
          { "key": "Access-Control-Allow-Headers", "value": "*" }
        ]
      }
  ]
}
```

```hello.js
export async function POST(request) {
    return new Response()
}

export async function OPTIONS() {
    return new Response()
}
```
【Nerves】M5Stack Core MP135にポーティングしてみた(準備編)


[準備編](https://qiita.com/GeekMasahiro/items/dd214725bc1849b355ef)　←いまココ
[設定ファイル作成編](https://qiita.com/GeekMasahiro/items/17242bf1f030de91ed75)
[KernelのBuild編](https://qiita.com/GeekMasahiro/items/e1bb049144b314e0c413)
[試行錯誤編](https://qiita.com/GeekMasahiro/items/e26a185bf858b0b149df)

# はじめに

この記事では、M5Stack CoreMP135へのNervesのポーティング作業で試行錯誤した内容を共有したいと思います。
ポーティングに関する情報は、Nervesのドキュメントにかなり詳細に書かれていて、これを見ていただくのが良いと思います。私もその内容で作業を進めました。

ポーティングを行ってみて、ポーティングの手順は、Nervesの仕組みを理解している人にとっては、それほど難しくないものではないと感じました。

しかし、Nervesの仕組みをわかっていなかった私には、何が原因で動かないのかわからない状況の繰り返しで、大変苦労しました。
私のこの一回目の経験を見ていただく事で、Nervesのポーティング作業を勧める大まかな工程や、検討しないといけない部分を理解していただくことで、ポーティング作業を進める際の参考になればと思います。

最近は様々なSBCが登場しています。このような新しいハードウエアにNervesを移植することで、新しいIoT製品の開発が進むことを期待しています。

# M5Stack CoreMP135

ポーティングの対象とした、M5Stack CoreMP135について簡単に紹介します。
M5Stack社は、IoTや組み込み開発向けの小型モジュール製品を多く手掛ける企業で、ユニークな製品群を展開しています。その中で、2024年5月にリリースされた「CoreMP135」は、特に注目に値する製品です。このCoreMP135は、従来のM5Stack社の他のCoreシリーズとは異なり、Linuxが動作するのが特徴です。

製品ページ[M5Stack CoreMP135](https://shop.m5stack.com/products/m5stack-coremp135-w-stm32mp135d)にも情報が掲載されていますが、Linuxの動作環境を備えていることで、通常のマイコンボードよりも高度な操作や処理が可能です。

# ポーティングの進め方

[公式のドキュメント](https://github.com/nerves-project/nerves_system_br/blob/0229532e3843bc3b4e534807636c767c380ae4b4/README.md)には、以下のように書かれています。

以下は、日本語への翻訳です。
```
私たちは公式には入手しやすいハードウェアのみをサポートしていますが、これはNervesがこれらのボードでしか動作しないという意味ではありません。もしBuildrootを使用してあなたのハードウェア用のLinuxルートファイルシステムを作成できるのであれば、Nervesを実行できる可能性があります。新しいボードをサポートするための一般的な手順は以下の通りです：

1. ボード上で起動して動作する最小限のBuildroot `defconfig` を作成します。これはNervesを一切使用しません。
2. `defconfig` に書き込み可能なルートファイルシステムが必要な場合、それを読み取り専用にする方法を見つけます。`systemd` を使用していない限り、これは比較的簡単です。Nervesは独自の初期化システムを使用しているため、後で手動で実行する必要がある初期化が `systemd` によって行われている可能性があることを覚えておいてください。
3. フラッシュメモリのレイアウトを確認し、サポートされているシステムのレイアウトと比較します。イメージを作成するために `fwup` を使用しています。フラッシュメモリのレイアウト方法やフェイルバック処理には多くのバリエーションがあります。この時点では、まず `fwup` を使ってイメージを作成できるかを確認してください。
4. あなたのボードに近い公式のシステムをクローンします。動作するBuildrootの `defconfig` に基づいて `nerves_defconfig` を更新します。
5. `mix` を使用するか、`create-build.sh` スクリプトを実行してシステムをビルドします。
```

# buildrootでのビルド

公式ドキュメントにもあるように、まずは、buildrootでlinuxが動作するファームウエアを作ってみます。
buildrootについては[こちら](https://buildroot.org/)を参考にしてください。

M5Stack社の公式サイトに、CoreMP135のLinuxのビルド方法が書かれているので、それを参考にして、buildrootでビルドしてみました。

```
git clone https://github.com/m5stack/CoreMP135_buildroot.git
git clone https://github.com/m5stack/CoreMP135_buildroot-external-st.git
cd CoreMP135_buildroot
make BR2_EXTERNAL=../CoreMP135_buildroot-external-st/ m5stack_coremp135_defconfig
make -j4
```

```/output/images/sdcard.img```に、SDカードのイメージが作成されます。


実際に、SDカードに書き込んで、起動できる事を確認しておきます。

この先、想定通り起動できない事が何度がありましたが、この起動するSDカードと比較する事で、どこに問題があるのかを特定する事に役立ちました。
君もVimmerにならないか

## はじめに
リンクラフト株式会社の大平と申します。
リンクラフトアドベントカレンダーの6日目を担当します。

エンジニアをやってますが、最新の技術で俺TUEEEEEEEできるわけでもないので
社内では数少ない特徴のVimmerというところで記事を書かせてもらいます。

## vimって使いづらくね？
いきなりのdisです。

初めてLinuxなどでvimやviに触れた方々の9割は感じるであろうこの想い。
僕も最初はそうでした。

* なんでカーソルが最初から上書きモードになってんの？！
* 文字入力しようとしたらカーソルがどっかに旅立ったんだけど！
* 保存の仕方わかんねぇ！
* Escキーなんて使ったことねーよ！

その他諸々、数々の壁にぶつかりました。
これならメモ帳の方が使いやすいよ・・・そう思ってた時代が僕にもありました。

## なんでvimを使い始めたのか
そんな人間がVimmerへの一歩を踏み出した理由は
**「なんかかっこいい」**
ただそれだけです。
先輩がvimを使いこなしてる姿に憧れを抱いてしまいました。

でも大体動機ってそんなもんですよね！
思い立ったが吉日、使用しているIDEにVimの拡張を入れて強制的にVimmerへ転身しました。

Vimmerになって最初の数か月は生まれたての小鹿のようなキーボード操作になりましたが・・・
そんな小鹿が気が付いたらそれっぽくvimを使えるようになったので
超入門として簡単ですが書き連ねていきます！

## これだけ知っておけばなんとかなる
* 大量のコマンドを覚えるぞ！
* モードの特性も理解するぞ！

そんなことを最初から考えてるとめっちゃツライです。
なので最初はとりあえず操作が出来る（文字が打てる）を目標に
最低限のコマンドに慣れることを目指すことをお勧めします！
そうなればvimもメモ帳も大差はありません！

メモ帳と同程度に操作できるようになってしまえば
あとは利便性を追い求めて少しずつ覚えていけばいいんです！
なので最初の一歩はもうこれだけでいい！

### モード
| 名称 | 変更方法 |挙動|
|---|---|---|
| ノーマルモード | ノーマルモード以外でEscキー押す |カーソルキーの移動をするモード|
| 挿入モード | ノーマルモード中にiキー押す|文字入力ができるモード|

### コマンド

| モード | コマンド | 挙動 |
|---|---|---|
| ノーマルモード | h | カーソルを左に移動 |
|| j|カーソルを下に移動|
|| k|カーソルを上に移動|
|| l|カーソルを右に移動|
|| i|カーソルの現在位置で挿入モードに移行|
|挿入モード| Esc | ノーマルモードに移行 |

もちろんこれを覚えただけでは、モード切替の手間が増えただけで
使い慣れてるエディタの劣化でしかないと思います。

でもvimを動かせるようにはなるはず！

## 動かせるようにはなったけど不便すぎる
紹介しているコマンドを使えるようになっただけでは
まだまだvimに不便さを感じると思います。

* ファイルの先頭に移動したいからkキー長押しで一番上に移動してる
* 行末に文字追加したいからlキー長押しで移動してからi押して→押してる
* ファイル内の文字列検索したいのにCtrl+f押すとなんか画面が動くだけで検索の仕方がわからない

などなど・・・

でも不便さを感じるのはvimを使う上では、すごく大事なことだと思います！
漠然とvimコマンドのチートシートを見ていても
何が自分にとって便利で、何が頻繁に使われるコマンドなのかはイメージしづらいです。

「不便だな、解消したいな」という思いからコマンドを見つけて
「めっちゃ便利だな！」と実感すると自然とそのコマンドを体が覚えていきます。

不便さを感じるのはVimmerとしての伸びしろがある証です。
どんどん不便さを感じましょう！

## さいごに
vimはスルメです。
最初は「なんだこれ！」って思うかもしれません。
でも、噛めば噛むほど、その奥深さとか便利さにじわじわ気づいてきます。
気づいたら、無限に噛み続けてる自分がいるかもしれませんよ。
僕も10年ほど噛み続けてますが、まだ味わい切れてないです！

この記事を見て、「ちょっと噛んでみるか」と思ってくれる方が少しでもいてくれたら嬉しいです！
大体のIDEにはvim化するための拡張があります、是非入れて小鹿体験から始めてみてください！

---
一緒に働く仲間を募集中です！

リンクラフト株式会社では、組織拡大に伴い積極的な採用活動を行っています。
少しでも興味がある方はぜひご連絡ください。

▽会社ホームページ
https://lincraft.co.jp/
▽Instagram
https://www.instagram.com/lincraft.inc/
▽ご応募はこちらより
https://lincraft.co.jp/recruit

※カジュアル面談も受付中です。ご希望の方はHPのお問い合わせフォームよりご連絡ください。
浮動小数点の89.51を文字列に変換して遊ぶ。(チェックと丸め有り)


参考

https://ameblo.jp/yumop/entry-12587172037.html


x 過去ログを見よ!!
x M5NanoC6での予定は、未定
x 一番下のコメントも見てください。コメントの内容を反映させました11/26


仕様
99.99　より　大きい場合は、99.99
-99.99 より　小さい場合は、-99.99

丸め

符号を外す
89.51 を　100倍する
8951.??? に　0.5を足す
8951.???　を　整数9851にし、小数点以下を丸める
符号を付ける

オンラインコンパイラ

```c++



#include <iostream>
using namespace std;


void ch_conv(char *buf,float f){
    
    int n; //変換元
    int a; //一時変数

    //符号を外す
    buf[0]=' ';
    if(f < 0.0f) {f = 0.0f - f;buf[0]='-';}

    n = (int)(f * 100.0f + 0.5f);

    if(n > 9999 ){n = 9999;}

    // 0123456
    // -12.34_

    buf[3]='.';
    buf[6]=0;

    buf[5] = '0' + n % 10;

    n = n / 10;
    buf[4] = '0' + n % 10;

    n = n / 10;
    buf[2] = '0' + n % 10;
    
    n = n / 10;
    buf[1] = '0' + n;
    //n = a;

}//ch_conv


int main(void){
    // Your code here!

    char str1[32];

    ch_conv(str1,89.51);
    
    printf("%s\n",str1);

    ch_conv(str1,39.51);
    
    printf("%s\n",str1);

}




```


```

 89.51
 39.51

```



-----------------

●修正前
-----------------


オンラインコンパイラ


```c++


#include <iostream>
using namespace std;


void ch_conv(char *buf,float f){
    
    int n; //変換元
    int a; //一時変数

    //符号を外す
    buf[0]=' ';
    if(f < 0.0) {f = 0.0 - f;buf[0]='-';}

    n = (int)(f * 100.0 + 0.5);

    if(n > 9999 ){n = 9999;}

    // 0123456
    // -12.34_

    buf[3]='.';
    buf[6]=0;

    a = (n * 52429) >> 19; // n / 10;
    buf[5] = '0' + n - (a * 10);
    n = a;

    a = (n * 52429) >> 19; // n / 10;
    buf[4] = '0' + n - (a * 10);
    n = a;

    a = (n * 52429) >> 19; // n / 10;
    buf[2] = '0' + n - (a * 10);
    n = a;

    a = (n * 52429) >> 19; // n / 10;
    buf[1] = '0' + n - (a * 10);
    //n = a;

}//ch_conv


int main(void){
    // Your code here!

    char str1[32];

    ch_conv(str1,89.51);
    
    printf("%s\n",str1);

    ch_conv(str1,39.51);
    
    printf("%s\n",str1);

    
}



```


```

 89.51
 39.51


```
VS Code - Run on Save

# はじめに
MH ソフトウェア & サービスが開発・公開しているアプリケーションは、Microsoft社のVisual Studio Code(以後、VS Code)でコーディングされています。  
以前は、有名な日本のテキストエディタを使用していましたが、Pythonと出会い、VS Codeと出会って、全てがVS Codeになりました。  
報告書PDFもVS Code(Markdown PDF)。電気配線図・系統図もVS Code(Draw.io)。CSV編集もVS Code(Rainbaow CSV)。Markdown、Qiitaの投稿はもちろん、VS Codeです。  
***
そんな中で、特に思い入れが強い拡張機能は、Run on Saveです。  
ファイルを保存した時に、実行するプログラムを指定できます。  
.py保存時は、.pyi(スタブファイル)を作成し、.js保存時は、.d.ts(TypeScript型定義ファイル)を作成します。  
開発時のソースコードが、とても分かりやすくなります。

:::note
WindowsでのVS Codeの設定です。
:::
Run on Saveの設定です。  
settings.json内の"emeraldwalk.runonsave"の設定です。
```json
    "emeraldwalk.runonsave": {
        "autoClearConsole": true,
        "commands": [
            {
                "match": "\\.py$",
                "cmd": "pygenstub.bat \"${fileDirname}\" ${fileBasenameNoExt}"
            },
            {
                "isAsync": false,
                "match": "\\.ts$",
                "cmd": "tsc ${file}"
            },
            {
                "isAsync": false,
                "match": "\\.js$",
                "cmd": "python js_to_interface.py \"${fileDirname}\" ${fileBasenameNoExt}"
            },
        ],
    },
```
Pythonスタブファイルを作成するpygenstub.batのコード
```
@echo off
chcp 65001
cd /d %1
pygenstub.exe --generic %2.py
```

.d.tsファイルを作成するjs_to_interface.pyのコード
tsc.cmdが必要です。

```Python
"""
d.ts file support script
========================
"""
import os
import shutil
import subprocess
import sys
import time


folder = f"{sys.argv[1]}\\"
temp_foplder = f"{os.environ['temp']}\\"

BASENAME = sys.argv[2]
js_file_name = f"{folder}{BASENAME}.js"
d_ts_file_name = f"{folder}{BASENAME}.d.ts"

temp_js_file_name = f"{temp_foplder}{BASENAME}~temp.js"
temp_d_ts_file_name = f"{temp_foplder}{BASENAME}~temp.d.ts"

shutil.copy2(js_file_name, temp_js_file_name)
command = (
    f'tsc "{temp_js_file_name}" '
    "--declaration --emitDeclarationOnly --allowJS "
)
subprocess.run(command, check=False, shell=True)

time.sleep(1)
body: str = ""
with open(temp_d_ts_file_name, encoding="utf-8", mode="r") as wrapper:
    body = wrapper.read()
    body = body.replace("export class ", "interface I")
    # JavaScriptファイルがexport class MyClass {}の場合、
    # export class MyClass がファイル先頭になります。
    # "export class "を"nterface I"に変更して、interface IMyClassにします。

    body = body.replace("    #private;\n", "")
    #　"    #private;\n"も不要なので、削除します。

with open(d_ts_file_name, encoding="utf-8", mode="w") as wrapper:
    wrapper.write(body)

os.remove(temp_js_file_name)
os.remove(temp_d_ts_file_name)
```
* [VS Code - .d.tsファイル(型定義ファイル)の効用](https://qiita.com/MH-SS/items/e71ed24ca5283756494d)
***
[Webアプリケーションサーバ AiR](https://qiita.com/MH-SS/items/7a99e799e4988fdad2cc)
***
[弊社webページ: AiR](https://mhss.server-on.net/?f401c=Index&ae504=air)
ソフトウェア定義ネットワークの概要

>トラフィック管理とトラフィック・エンジニアリングは、歴史的に非常に困難な作業である。ネットワーク・オペレータは、ルーティング・プロトコルの設定パラメータを調整し、経路を再計算する必要がある。トラフィックは新しい経路に沿って流れ、その結果、トラフィックのバランス調整が再度行われる。

>これらのプロトコルは予測不可能な方法で相互作用する可能性がある。SDN(ソフトウェア定義ネットワーク）はこれらの問題を多くを解決することを目的としている。

# ルーターにはすでにソフトウェアが入っている
>ルーター上で設定可能ソフトウェアがパケット内の情報を検索し、転送先の決定を行うという意味で、ある意味でネットワークは常に「ソフトウェア定義」されたものであると言える。

>シスコやjuniperのルーターを購入したオペレータは、ある意味、ベンダーがハードウェアと一緒に出荷したソフトウェア技術に縛られていたのである。

# SDNの主なコンセプト
>ルートを選択し、トラフィックを転送する際の処理を決定するソフトウェアとロジックであるコントロール・プレーン(control plane)をソフトウェアで動作させ、パケットに対して実際に検索を実行し、その処理を決定するハードウェアベースのテクノロジーであるデータ・プレーン(data plane)と完全に分離して動作できることを示すのであった。

# SDNで使われる言語
>論理的に集中制御されたプログラムがあり、しばしば高級言語（例えばPython, Java, Golang, C)で書かれていて、転送に関する論理的な決定を行い、その決定をネットワーク上の全ての転送デバイスに伝えている。

# データプレーンとコントロールコントロールプレーンの考え方は変わっていない
>SDNのテクノロジーは急速に進化し続けているが、データ・プレーンとコントロール・プレーンの分離という中心的な考え方は変わっていない。SDNテクノロジーは何年もかけて進化してきた。

# 感想
SDNに関して何も理解していないので、難しそうだ。
VSCode new Date('text') を 'text'に変換する正規表現

new Date('2014-11-25') -> '2014-11-25'
new Date\('([^']*)'\) -> '$1'

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399596/a01fd33f-4eed-dd71-8518-ee803ce4e07b.png)
“上司がめんどくさい”と感じた時、転職前に試すべきの対応策

記事を読む前に、もし、職場文化や上司の問題が深刻で、自分の成長や心身の健康を阻害していると感じる場合、**転職を真剣に検討する**ことが最適な選択肢になることもあります。以下のような状況に心当たりがあるなら、無理に適応しようとするよりも、新しい環境を探す方が未来に繋がります。

- **旧い職場文化に疲れている場合**  
  - 年功序列や上下関係が強調され、意見が言いにくい。  
  - 無駄な会議や形式的な慣習が多い。  
  - 残業が美徳とされる。  

- **圧が強い上司に苦しんでいる場合**  
  - 過度な指示出しや細かすぎる干渉がある。  
  - 感情的な叱責や、パワハラ的な言動が続いている。  
  - 努力や成果を正当に評価してもらえない。  

こうした問題が「職場全体の風土」である場合、個人の力で状況を改善するのは困難です。最近では、こういった文化を排除した**フラットで自由な職場環境を提供する企業**が増えているため、転職市場を視野に入れるのも現実的な選択です。


本編
---


上司が細かい点にこだわり、「めんどくさい」と感じる場合の対処方法は、状況や自分の考え方によります。上司を変えるのは難しいですが、自分の対応や考え方を工夫することでストレスを軽減する方法があります。以下にいくつかの視点を提案します。

---

### **1. 上司の意図を理解する**
上司が細かい指摘をする背景には、何か理由があるかもしれません。
- **細かさの目的を考える**  
  - 「品質を保ちたい」「ミスを減らしたい」といった意図がある可能性があります。
  - なぜそのように言うのか、背景を理解しようと努めます。
- **率直に確認する**  
  - 「このように進める理由は何ですか？」と丁寧に聞くことで、上司の考えを理解できることもあります。

---

### **2. 自分の対応を工夫する**
上司に合わせるのではなく、上手に対応することで状況を改善できます。
- **先回りして準備する**  
  上司が何を気にするかを事前に想定し、準備することで指摘を減らす。
  - 例: 上司がフォーマットや手順にこだわる場合、指摘される前にその通りに進める。
- **フィードバックを効率化する**  
  指摘が多い場合、一度にまとめて確認を求める。
  - 例: 「次のステップに進む前に、ここまでの内容を確認していただけますか？」

---

### **3. 感情をコントロールする**
上司が「めんどくさい」と感じるときは、感情的にならないことが重要です。
- **ストレスの原因を分ける**  
  - 「本当に困っていること」と「感情的に嫌だと思うだけのこと」を切り分けます。
  - 感情の部分を切り離すことで、冷静に対応しやすくなります。
- **深呼吸して落ち着く**  
  イライラしたら少し時間を置き、冷静さを取り戻してから話し合う。

---

### **4. 上司との関係を見直す**
上司とのコミュニケーションが原因なら、関係性の改善を目指します。
- **小さな成果を見せる**  
  「言われなくても対応できる」と認めてもらうことで、指摘が減る場合もあります。
- **信頼を築く**  
  上司との信頼関係が強まると、細かい指示が減る可能性があります。

---

### **5. それでも解決しない場合**
状況が改善しない場合、長期的な視点で他の選択肢を考える必要があるかもしれません。
- **転職を考える**  
  - 上司の性格や職場環境が原因で自分の成長や健康が損なわれる場合、転職も選択肢の一つです。
  - ただし、転職先でも同じような問題が起こる可能性があるため、自分の対応力を高めておくことが大切です。
- **社内の異動を検討する**  
  - 他の部署で自分のスキルを活かせるかを探る。

---

### **6. 上司に改善を求めるのは難しい**
上司自身が「自分が正しい」と信じている場合、直接反省を促すのは難しいことが多いです。そのため、次のように間接的な方法を取ります。
- **客観的な意見を求める**  
  他の同僚や信頼できる第三者に相談し、解決策を探る。
- **自分の意見を伝える**  
  上司に直接話す場合は、「もっと効率的に進めるために、こうしてみるのはどうでしょう？」と提案する形にすると受け入れられやすいです。

---

### **結論**
「めんどくさい」と感じる上司に対しては、まず自分の対応を改善し、ストレスを軽減する方法を試してみましょう。それでも解決しない場合、転職や異動を考えるのも一つの選択肢です。ただし、どの環境でも「嫌な上司」に出会う可能性があるため、自分の対応力を高めておくことが重要です。
PythonでLINEに通知する

# 目的
LINEでbotを作り、Pythonからbotを通して通知する
※月額0円のコミュニケーションプランだと、月に200通までの制限がある
https://www.lycbiz.com/jp/news/line-official-account/20230601/

# 背景
時間のかかる処理をさせる際に、終わったらスマホに知らせてほしいと思うことが多々あったので、AIさんに聞いて作ってみた。

# 環境

- Windows11 バージョン24H2(OSビルド26100.2454)
 - Python3.12.4
 - line-bot-sdk 3.9.0

# 作り方
1. （無ければ）LINE Developersアカウントを作る
1. ログインする
1. （無ければ）プロバイダーを作る
1. （無ければ）チャネルを作る
1. チャンネルシークレットを取得する
1. アクセストークンを取得する
1. LINE通知するユーザーIDを調べる
1. PythonのLINE通知クラスを作成する
1. line-bot-sdkをインストールする
 
## （無ければ）LINE Developersアカウントを作る
[LINEデベロッパーコンソール](https://developers.line.biz/console/)で、アカウントが無なければ作る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201344/6a116ed7-3826-5b20-9587-d454533d391d.png)

## ログインする
[LINEデベロッパーコンソール](https://developers.line.biz/console/)にログインする

## （無ければ）プロバイダーを作る
プロバイダーが無ければ作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201344/f456b80d-167f-5251-f7aa-f3002ca4ffdc.png)

## （無ければ）チャネルを作る
プロバイダーに入って、新規チャネル作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201344/a5664db0-49f8-9b6d-65bc-35457361e6ee.png)

## チャンネルシークレットを取得する
チャネルのチャネル基本設定を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201344/062992f4-6e24-3942-8086-4802ac4abda9.png)
チャネルシークレットの発行ボタンをクリックする
表示されたチャネルシークレットを控えてく

## アクセストークンを取得する
チャネルのMessaging API設定を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201344/b52f18de-9777-1f21-4c37-2dae964c3bc8.png)
チャンネルアクセストークン（長期）の発行ボタンをクリックする
表示されたチャネルアクセストークンを控えておく

## LINE通知するユーザーIDを調べる
チャネルのチャネル基本設定を開く
あなたのユーザーIDを控えておく

## PythonのLINE通知クラスを作成する
例えば、AIさんに以下を質問して
```
python言語で、LINEメッセージAPIを使ってLINEに通知を送るクラスを作ってください。
そのクラスはvalueobjectパターンで作ります。
アクセストークンとチャンネルシークレットは引数で与えてインスタンスを作ります。
アクセストークンとチャンネルシークレットはファイルに保存します。
引数が与えられずファイルに保存されている時はファイルから読み込んでインスタンスを作ります。
```
回答のコードを、自分好みに直して使います。
- [line_message_api.py](https://github.com/igaponr/training/blob/1.10.0/python/Web_scraping/line_message_api.py)

## line-bot-sdkをインストールする
コマンドラインで以下を入力する
```
pip install line-bot-sdk
```

# 使い方
LineMessageAPIクラスの[docstring](https://github.com/igaponr/training/blob/90542252f5d01281e0b979862b54ccc11c05790c/python/Web_scraping/line_message_api.py#L16C1-L22C8)を見てもらえばわかりますが、引数access_tokeにアクセストークンを、channel_secretにチャンネルシークレットを指定して、LineMessageAPIクラスのインスタンスを作り、引数user_idで送るユーザーのIDと、messageで送るメッセージを指定して、send_messageメソッドを呼び出せば通知できます。
初回は、以下のコマンドで通知を送ります。line_message_api_config.jsonファイルにアクセストークンやチャンネルシークレットが保存されます。
```
python line_message_api.py -a <アクセストークン> -c <チャンネルシークレット> -u <通知を送るユーザーID> -m <メッセージ>
```
次回からは、アクセストークンとチャンネルシークレットをline_message_api_config.jsonから読み込むので、以下の通り省略できます。
```
python line_message_api.py -u <通知を送るユーザーID> -m <メッセージ>
```

# おわりに
無料だと200通までなので、何を通知するかよく考えて利用したい。
slackなら無料で何通でも通知できると思うので、次回はそちらを試したい。

# 関連リンク
## 参考サイト
- [【原因紹介】急にLINE botの投稿制限に引っかかるになった話。](https://www.pnkts.net/2023/07/06/line-bot-error)
- [【重要】LINE公式アカウント 料金プラン改定のお知らせ](https://www.lycbiz.com/jp/news/line-official-account/20230601/)

## ドキュメント
- [Messaging APIの概要](https://developers.line.biz/ja/docs/messaging-api/overview/)
Windows Server 2025 Azure Edition を Azure CLI で作ってみた

自分自身は Windows Server を触る機会がほとんどない仕事環境なのですが、ごく稀に検証が必要になることがあります。その時のためにサクッと検証できるように、Azure CLI で Windows Server 2025 を作ってみました。

## VM のイメージを探す

```zsh:zsh
az vm image list-skus \
  --location japaneast \
  --publisher MicrosoftWindowsServer \
  --offer WindowsServer \
  --output table \
  | grep 2025

japaneast   2025-datacenter
japaneast   2025-datacenter-azure-edition
japaneast   2025-datacenter-azure-edition-core
japaneast   2025-datacenter-azure-edition-core-smalldisk
japaneast   2025-datacenter-azure-edition-smalldisk
japaneast   2025-datacenter-core
japaneast   2025-datacenter-core-g2
japaneast   2025-datacenter-core-smalldisk
japaneast   2025-datacenter-core-smalldisk-g2
japaneast   2025-datacenter-g2
japaneast   2025-datacenter-smalldisk
japaneast   2025-datacenter-smalldisk-g2
```

## Windows Server 2025 を作成

```zsh:zsh
prefix=mnrw2025

az group create \
  --name ${prefix}-rg \
  --location japaneast

az vm create \
  --resource-group ${prefix}-rg \
  --name ${prefix}-vm \
  --os-disk-name ${prefix}-vmOSDisk \
  --image MicrosoftWindowsServer:WindowsServer:2025-datacenter-azure-edition-smalldisk:latest \
  --size Standard_F4s_V2 \
  --admin-username azureuser \
  --nsg-rule NONE
```

## NSG で自身の IP のみ許可

```zsh:zsh
az network nsg rule create \
  --resource-group ${prefix}-rg \
  --name Allow-RDP \
  --nsg-name ${prefix}-vmNSG \
  --priority 100 \
  --source-address-prefixes $(curl -s inet-ip.info) \
  --destination-port-ranges 3389 \
  --access Allow \
  --protocol Tcp
```

## リモートデスクトップ接続して OS 情報を確認

![win2025-azure-edition-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675885/3c15428b-4653-22b3-b160-a254209da95f.png)

## 参考

https://learn.microsoft.com/ja-jp/cli/azure/vm?view=azure-cli-latest#az-vm-create

https://learn.microsoft.com/ja-jp/windows-server/get-started/azure-edition
nvidia gpuをつんだPCにubuntu24.04インストール

# はじめに
NVIDIA GPUを搭載したPCを購入し、Ubuntuをインストールしました。スムーズにはいかなかったため、詰まった箇所を記録として残します。

# PCの仕様
- FRONTIERで購入したBTOデスクトップ。Windows 11 Home 64bit版がインストール済み
- CPU: Ryzen 7 5700X
- SSD: 1TB、HDD: 2TB
- GPU: RTX4060 Ti 16GB
- 無線LAN: なし

# インストール手順
- Macのddコマンドを使用して、Ubuntu 24.04 Desktopのインストールメディア（USBメモリ）を作成
- USBメモリを挿入しPCを起動。DELETEキーを連打してUEFI起動。USBメディアのBOOT優先度を上げ、変更を保存してExit
- インストールオプションで「Try and install Ubuntu」を選択
- 画面が暗くなり、先に進まなくなった
- 調査の結果、[NVIDIAのGPUを搭載したPCにUbuntuをインストールすると、ドライバの関係で画面が正常に表示されなくなる](https://kledgeb.blogspot.com/2020/04/ubuntu-2004-25-ubuntu-2004-lts.html)ことがあると判明
- PCを再起動し、インストールオプションで「safe graphics」を選択。高度なドライバを使用しない設定
- 無事にGUI上でインストールが可能な画面が表示された
- インストールオプションで「サードパーティのNVIDIAドライバをインストールする」にチェックを入れると、NVIDIA対応のドライバがインストールされる
- OSなどのインストール先を設定変更
- SSDとHDDを併用する場合、bootやルートを高速なSSDにインストールし、容量を必要とするhomeはHDDにマウントするのが一般的。デフォルトではすべてSSDまたはHDDのみにインストールされる。インストール後にマウントし直すことも可能だが、面倒なのでインストール画面で設定
- 「手動でパーティショニング」を選び、マウント先を設定
- UIがわかりにくいが、ブート先メディアは左下のセレクトボックスから選ぶと自動で専用のパーティションが作成される
- SSDの残りはルートに設定。「空き状態」を選択し「＋」で作成。フォーマットはext4で問題ないと思われる
- HDDはすべてhomeに設定
- 以前Ubuntuをインストールした際はスワップ領域用のパーティションを作成したが、今回は作成せず。スワップ領域はRAMが不足した際にストレージをRAM代わりに使用する機能だが、最近はスワップファイルを使用するのが主流。Ubuntuの最近のバージョンではスワップファイルを自動で作成してくれる
- インストールが完了したら再起動

# 画面表示の不具合解消
- 再起動後、画面が真っ暗になる現象が発生。NVIDIAのドライバ関連の不具合が続いている模様
- 調査して見つけた対処法をいくつか試す
- UEFI画面でSecureBootを無効化して起動したが、改善せず
- GRUBから[nomodesetの追記とblacklist-nouveauの追記](https://qiita.com/Chamusuke/items/55d93838cc98e480385d)を試したが、改善せず
- [似た状況の方](https://qiita.com/YaezakuraP/items/507a7a9713b4e6f63f4b)を参考に、GRUBからrootシェルにログインし、`apt update && apt upgrade`、`apt --purge remove -y nvidia-*`を実行し、再起動したら画面が表示されるようになった
  - リカバリモードでネットに接続するために「Enable networking」コマンドをシェルに入る前に実行する必要あり
  - ハード特有の事情かもしれないが、PCの有線LAN端子にLANケーブルを挿すと変なIPを取得しネットに接続できなかった。USB2LANコネクタを使用すると正常なIPをDHCPで取得できた
- SecureBootを有効に戻しても画面が表示されることを確認（結局、nvidia-driverのインストールのために再度無効化するが）
- blacklist-nouveauを削除するとFRONTIERと表示された画面から進まなくなったため、blacklist-nouveauを復活させた（つまり、blacklist-nouveauの設定とnvidiaドライバの削除が必要だった模様）

# NVIDIAドライバの再インストール
- 画面表示の不具合解消の過程でNVIDIAのドライバを削除したため、再インストール
- 削除前に確認したNVIDIAのドライバは535だった
- `ubuntu-drivers devices`で確認すると560が推奨されていた
- 参考：https://qiita.com/porizou1/items/74d8264d6381ee2941bd
- UEFIでSecure Bootを無効化
- `sudo add-apt-repository ppa:graphics-drivers/ppa`
- `sudo apt update`
- `sudo apt install nvidia-driver-560`
- `sudo reboot`
- 再起動後、`nvidia-smi`が実行できることを確認

# 考察
- 結果から考えると、nouveauとnvidia-driver-535を両方無効にしたら、起動するようになったので、そのどちらもがハードと相性が悪かったのだと思われる。nvidia-driver-535はおそらくインストール時にチェックを入れたことでインストールされたと思われる。インストール時はsecurebootがenableだったので、インストールが上手く行っていなかったとかだろうか。
# おわりに
画面表示の不具合を解消し、ubuntuをインストールできたといえるところまでこれたので区切りとします。
cudaのインストールなどは引き続きやってみようと思います。
K8s+ArgoCDでGROWI構築してみた件


こんにちは。
デジタル創作サークルUniProjectのあかつきゆいとです。

今回はサークル内Wikiである、UniWikiを構築した時の話をしていきたいと思います。

## GROWIとは

GROWIは、株式会社WESEEKが開発を行う、オープンソースの社内Wikiツールで、Markdown記法が使えたり、HackMDのように同時編集ができたりします。

元々はHackMDだけ導入するつもりでしたが、~~Mediawikiで構築していた旧WikiのWiki構文に嫌気がさしていたのもあり、~~Markdown使えるのいいねってことで、GROWIを導入しました。

## ArgoCDへのマニフェストファイルの準備

なぜにArgoCDかというと、**GitHubで管理すると、あとで何かしらぶっ壊して再構築する時に楽だから**です。

というわけで、GitHubに適当なリポを作りましょうねということで、こんな感じに作りました。
一個一個解説していきましょうか。

https://github.com/UniPro-tech/growi-argo

### *-deployment.yaml

これにはデプロイメントの設定が載っています。
環境変数を弄るだけで十分ですね。

### *-service.yaml

サービスですね。
GROWIは既定で3000番が開きます。これは、**NextJSだから**です。

ということで、SSLとかはないので、Ingressを通してあげる必要があります。

### ingress.yaml

これには、Ingressの設定をしますが、気をつけなければならないのは、**内側のポートが3000番であるということ**です。

ぼくはこれを80にして、だいぶと苦しみました()

## ArgoCD側の設定

ArgoCD側の設定は主に許可するリソースの設定ですね。
PersistentVolume系を許可する設定を必ずすることですね。

## GROWI側の設定

今回は、S3ではなく、MongoDBを使いました。
このため、**DBの容量は若干大きめに取っておいた方がいいです**。

PV/PVCは後から変更できず、Recreateになるので、非常にめんどくさいです。

## まとめ

今回はGROWIの構築をしました。
今度はOGPの設定をしたいなぁと思っています。

ではでは...
AtCoder ABC 381E - 11/22 Subsequence 偽ACのソースを晒します

ABC 381 E問題で、TLEになるはずの回答でACとって喜んでいたので戒めのために晒します😌

晒し用にある程度ソースを整えて、念のためジャッジに出したらTLE になったので不思議に思っていたら、コンテスト後にテストパターンが追加になっていたのですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798407/bbeab13e-37ab-c877-e113-e7e59338e3c8.png)

言い訳だけど、コンテスト中も気づいてはいたので～。これだと最終的に '/' の回数、ほぼ総当たりなので、極端に '/' が多いパターンは TLE になるな、と思いながら、残り時間があと9分だったから、5分ペナよりジャッジに出して、どの程度正解になるか確認しよう、って出したら通って「あれ？ なんか俺が思い違いしたかな？」ってなって。

寝る前と起きてから少し考えて、やっぱりあの回答はダメだよな？ と思って自分で試験パターン作って確認しよう。その前に記事書いて晒そう、と思って今ココ！です。競技プログラミングだと、通ればよかろうなのだっていうのもあるでしょうけど、これを仕事でやって、仮にもしここがRT のクリティカルセッションだったりしたらえらいこっちゃなので、反省反省。

本当の正解は解説配信とか拝見して今から考えます、はい😌 今のところ自分では、連続する '/' を潰しておくぐらいしか思いつかないけど、それでもさらに都合の悪い入力だとなんとなく足りない気がするので、どうしようかな。

```cpp:Main.cpp
#include <bits/stdc++.h>
using ll = long long;
using namespace std;

// 1, 2 の出現回数の累計和
ll gPreSum1[100009];
ll gPreSum2[100009];

int main( void )
{
	// 入力
	ll N, Q;
	string S;
	cin >> N >> Q >> S;

	// スラッシュの位置一覧
	vector<ll> vecPosSlash;

	for( ll i = 1; i <= N; ++i)
	{
		gPreSum1[i] = gPreSum1[i-1];
		gPreSum2[i] = gPreSum2[i-1];

		if( S[i-1] == '1' )
		{
			++gPreSum1[i];
		}
		else if ( S[i-1] == '2' )
		{
			++gPreSum2[i];
		}
		else
		{
			vecPosSlash.push_back(i);
		}
	}

	for( ll i = 0; i < Q; ++i)
	{
		ll L, R;
		cin >> L >> R;

		// L と以上のスラッシュの位置を探す
		auto itr = lower_bound( vecPosSlash.begin(), vecPosSlash.end(), L);
		if( itr == vecPosSlash.end())
		{	// そもそもない
			cout << "0" << endl;
			continue;
		}
		if( R < *itr)
		{	// あるが R よりでかい
			cout << "0" << endl;
			continue;
		}

		// 少なくとも / はある
		ll result = 1;
		while( itr != vecPosSlash.end() && *itr <= R )
		{
			// / の位置から前の1の数
			ll cnt1 = gPreSum1[*itr] - gPreSum1[L-1];
			// / の位置から後ろの2の数
			ll cnt2 = gPreSum2[R] - gPreSum2[*itr];
			// 短いほうの2倍+ / 分の長さ
			ll tmp = min(cnt1, cnt2) * 2 + 1;
			result = max( result, tmp);

			++itr; // 次の / も評価する
 		}
		cout << result << endl;
	}

	return 0;
}
```
20分で終わる！最も簡単にlocalでNext.jsを動かす

# 導入
今回は最新のNext.jsを最も簡単にセットアップして動くようにするコードを用意したので軽い検証や初めてNextを使う方はぜひ使ってみてください！

# 必要なもの
* [docker desktop](https://www.docker.com/ja-jp/products/docker-desktop/)
* [vscode](https://code.visualstudio.com/download)

これだけです！
初学者向けに今回はvscodeで説明していますがエディターはなんでもいいです

# 手順
gitが普通に使える方は以下のリポジトリからクローンしてREADME.md通りに構築してください

https://github.com/YuuseiMatsunaga/easy-next-start


gitがよくわからない方は以下の手順で進めてください

1. 適当な空のフォルダを開きます
![スクリーンショット 2024-11-17 17.49.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1178067/90c72bee-ed30-885d-feae-5e6e912a9de8.png)

<br>
2. `Dockerfile`, `Makefile`, `setup.sh` の3つのファイルを作成します

![スクリーンショット 2024-11-17 18.08.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1178067/6476c0c8-d84c-eb81-f037-227b7be8115d.png)


<br>
3. それぞれの中身は以下をコピペしてください

Dockerfile
```
FROM node:18-alpine
WORKDIR /usr/src/app
RUN npm install -g create-next-app

COPY setup.sh /setup.sh
RUN chmod +x /setup.sh

CMD ["/setup.sh"]
```

setup.sh
```
#!/bin/sh
PROJECT_DIR="/usr/src/app"

# 以下はproject作成後は消していい
if [ ! -f "$PROJECT_DIR/package.json" ]; then
  TMP_DIR=$(mktemp -d -t tmp-nextjs-XXXXXX | tr '[:upper:]' '[:lower:]')
  npx create-next-app@latest $TMP_DIR --use-npm --ts --eslint --src-dir
  mv $TMP_DIR/* $PROJECT_DIR
  mv $TMP_DIR/.[^.]* $PROJECT_DIR
  rm -rf $TMP_DIR
fi

echo "Starting Next.js development server..."
npm run dev
```

Makefile
```
CONTAINER_NAME=nextjs-container
IMAGE_NAME=nextjs-docker

build:
	docker build -t $(IMAGE_NAME) .
run:
	docker run --rm -it -p 3000:3000 -v $(PWD):/usr/src/app --name $(CONTAINER_NAME) $(IMAGE_NAME)
bash:
	docker exec -it $(CONTAINER_NAME) /bin/sh
```
<br>

4 . ターミナルを開いてください
![スクリーンショット 2024-11-17 18.09.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1178067/c28f4d8d-fda1-0f09-d351-d4fca036cdc8.png)
<br>

5 . ターミナルに以下のコマンドを打ちます
```
make build
```
```
make run
```
最初に立ち上げる時はそこそこ時間がかかります。15分くらいかかったかも!

いくつか質問がされますがよくわからない方は全て適当にEnter押して大丈夫です。後から変更できるので
ターミナルが写真のようになった後、http://localhost:3000 にアクセスしてNextの画面が表示されれば成功です
![スクリーンショット 2024-11-23 7.10.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1178067/c258113b-a271-ecb4-c4bd-6b5406da236b.png)


<br>

コンテナに入りたい場合は
```
make bash
```

を使ってください


# 最後に
わからないことやエラーがあったらお気軽にコメントください！



<br>
<br>
<br>
ここから先は興味がある人のみ読んでください

### なぜこの方法が「最も簡単」なの？
ホストにNodeやnpmが無くてもよく、それらのバージョンに左右されないからです
公式サイトの手順でNextを動かそうとすると
1. 動かしたいバージョンのnodeをインストールする
1. インストールしたnodeのバージョンを設定する
1. node -v をするがなぜかバージョンが変わっていない
1. なんかごちゃごちゃしてpathを通す
1. やっと新しいバージョンのnodeのpathが通る
1. 動かしたいバージョンのnpmをインストールする
1. インストールしたnpmのバージョンを設定する
1. npm -vするがなぜかバージョンが変わっていない
1. 以下略

こんなことが起きて普通のエンジニアでも1~2時間手こずることがあります
初学者だとここで挫折してもおかしく無いです
だからこそ初学者こそDockerを使うべきだと私は考えており、初学者がDockerのことをよく知らなくても簡単に動かせるようなコードを今回作成しました
読書感想文「内部構造から学ぶPostgreSQL設計運用計画の鉄則」アーキテクチャ部分のみ

# 書籍名「内部構造から学ぶ　POstgreSQL　設計運用計画の鉄則」　
改訂３版
上原一樹、勝俣智成、佐伯昌樹、原田登志
技術評論社

# 読もうと思った動機
仕事でDB設計パフォーマンスの計測をする機会があり、知識不足を実感したため
本書では内部構造、監視計画、監視運用が書かれており学ぶに良い本だと思ったため。


# 印象に残った部分
公式ドキュメントで関係ありそうな部分も提示しておきます。
バージョンは特に統一してません！

## p38 サーバプロセス
正直あんま理解できなかったのですね。
せめて単語だけでも理解するよう努めます。



### マスタサーバプロセス
PostgreSQLを制御するさまざまなプロセス（バックグランドプロセス）をforkして起動する親プロセス

fork プロセスを開始(fork)します。
https://www.postgresql.jp/document/8.1/html/tutorial-arch.html

接続の確立
https://www.postgresql.jp/docs/9.4/connect-estab.html


### ライタ
共有バッファ内の更新されたページを、対応sるデータファイルのブロックに書き出すプロセス

20.4.5. バックグラウンドライタ 
https://www.postgresql.jp/document/16/html/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-BACKGROUND-WRITER


### WALライタ
WALライタプロセスは、WAL（Write Ahead Logging）をファイルに書き出すプロセスです。
WALはPostgresSQLの更新情報が記録されたログで、リカバリ時やストリーミングレプリケーションで使用される非常に重要な情報

https://www.postgresql.jp/document/8.0/html/wal.html

### チェックポインタ
チェックポイントを設定に従って自動的に実行するプロセスです。
チェックポイントは、PostgreSQLがクラッシュした時に、どの箇所からリカバリ処理を行うのか示すポイント

https://www.postgresql.jp/docs/9.4/wal-configuration.html


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/6755fa91-f5ad-d8c7-97b4-7d0977877e1c.png)


### 自動バキュームランチャと自動バキュームワーカ
自動バキュームを制御/実行するプロセスです。
自動バキュームランチャーが自動バキュームワーカを起動する

### 統計情報コレクタ
データベースの活動状況に関する統計情報を一定間隔で収集するプロセス。

https://www.postgresql.jp/docs/11/monitoring-stats.html


## p41 クライアントとサーバの接続　通信

## 問い合わせの実行
データベースからデータを取り出す処理、または、取り出すためのコマンドを問い合わせと言います。
https://www.postgresql.jp/document/8.0/html/queries.html

### パーサ

字句解析、構文解析を実行する。

パーサー
https://www.postgresql.jp/docs/9.4/textsearch-parsers.html

一般的なパーサー
https://e-words.jp/w/%E3%83%91%E3%83%BC%E3%82%B5.html

#### 字句解析
SQLがどういったトークン（構文の単位）から構成されるか解析すること

https://www.postgresql.jp/docs/14/sql-syntax-lexical.html

https://www.postgresql.jp/docs/9.4/parser-stage.html


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/76e24e9f-3d11-d4d0-6225-2c9cd4310250.png)


#### 構文解析
字句解析で分解された字句の並びがPostgreSQLで扱えるSQLの記述規則に合っているかを検査して
問い合わせツリーを生成します。

https://www.postgresql.jp/docs/9.4/parser-stage.html


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/0b797e05-46b7-6ee0-3473-de1a07871cc4.png)



### リライタ
SQLを実行するデータベースにルール（SQLを書き換える規則）が定義されている場合、
そのルールを参照してリライタで問い合わせツリーを修正します。

https://cellbank.nibiohn.go.jp/legacy/information/pc/postgres_man/overview.html


### プランナ
リライタで修正された問い合わせツリーを本に最適な実行計画を生成します。

https://cellbank.nibiohn.go.jp/legacy/information/pc/postgres_man/overview.html


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/83ea1278-808a-07d5-7675-09925caf305f.png)


### エグゼキュータ

プランナで決定された実行計画に従って必要な行の集合を抽出します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/79652a57-14c4-4e74-5d1d-c572f802bb8c.png)

# 実践できること or 感想


## 感想
自分の知りたい情報は集まっており、勉強になった部分が多いです。
知らない単語が多かったのでその把握がメインでしたね。

監視、実行計画の部分も勉強になったので後で読書感想書きます。

## 実践できること
p6プロセス構成、p10のメモリ構成をplantumlで模写する。（配置図）

p41 クライアントとサーバーの接続、p43問い合わせの実行をplantumlで書く。（シーケンス図の予定）

# 参考

富士通　Postgresql アーキテクチャ
https://www.fujitsu.com/jp/products/software/resources/feature-stories/postgres/article-index/architecture-overview/
Neovim

# NeovimでTerminer開発環境構築。

>## 1.使用環境
>- Ubuntu 24.04.1 LTS(desktop)

>## 2.必要ツール
>- Neovim　v0.9.0以上
>- git　v2.45.0以上
>- Nerd Font　最新
>- ripgrep 最新

>## 3.Lazy.luaパッケージ管理ツール呼び込み
>![图片.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2735439/268083d9-dbbe-de32-0fae-20310678f0c2.png)

>## 4.Theme導入（ここでは"catppuccin"使用する）
>・pluginsフォルダでTheme専用ファイル作成し下記ソースコピー
>```lua
>return { 
>  "catppuccin/nvim",
>  name = "catppuccin",
>  priority = 1000,
>  config = function()
>    vim.cmd("colorscheme catppuccin")
>  end
>}
>```

>## 5.Telescope導入
React(vite) + LaravelでTwitterみたいなの作った

# Biography

URL:

~~[http://choishoi.site](http://choishoi.site/)~~

ログイン情報:

email: demo@example.com

password: password

GitHub:

バックエンド: 

[https://github.com/yamaneko05/server](https://github.com/yamaneko05/server)

フロントエンド: 

[https://github.com/yamaneko05/client](https://github.com/yamaneko05/client)

### 概要

誰でも登録可能で短文の投稿、いいね、コメントができるSNSサービスです。

いいね、コメント、フォロー、通知など基本的なSNSとしての機能を実装しました。

### 使用技術

フロントエンド

Tailwindcss, Shadcn-ui, lucide

axios, react-query, react-router-dom, react-hook-form, zod, laravel-echo

バックエンド

Laravel,

Sanctum (SPAに対する認証, セッション管理ライブラリ),

Breeze (認証周りの機能を自動生成してくれるライブラリ),

Pusher (プッシュ配信)

その他 → MySQL, XServer VPS, Git, htaccess, Ubuntu

### 経緯

Reactなどフロントエンド周りの学習の成果物として何かWebサービスを開発したいと思い、より身近に感じるもので多くの機能を実装できる拡張性のあるものとして考えたときにTwitterのようなSNSが良いと思いこれを開発するに至った。

## 苦労したこと

### VPSでの本番環境構築, プッシュ配信

メッセージ機能にてリアルタイムでのプッシュ配信を実装したいと思い、Laravelのbroadcast, Pusherを用いて実装した。

しかし、レンタルサーバーではプッシュ配信を処理するプロセスを常時実行することができなかったため、VPSにて環境の構築をした。

VPSの環境構築ではUbuntuにPHP, Apache, FTPサーバーのインストールなどの工程をすべてCGI上で行わなければならなかったので大変だった。

### ディレクトリ構成のパターン選定

Laravelと比べてディレクトリ構成の自由度が高かったので自分にとってしっくりくる方法を探すのが大変だった、最終的には下記のリポジトリにて採用されているfeaturesというフォルダで機能ごとにhooks, components, apiなどのフォルダを作る方法が、コードの管理がしやすいし依存関係の宣言文が揃いやすく美しいと思ったので採用した。

[https://github.com/alan2207/bulletproof-react](https://github.com/alan2207/bulletproof-react)

### 状態管理・APIデータの再フェッチ・APIデータのキャッシュ

ログイン状態やログイン中のユーザー情報などの状態管理をどうするかで迷走した

& APIから取ってきたデータとフロントエンド側のstoreとの連携に苦戦した

Recoilを導入して状態管理したりしてみたが、react-queryのキャッシュ(stale?)やinvalidateなどを使ってみてこれらで無駄なフェッチングやレンダリングを防げたのでreact-queryのみで解決した。react-queryが今まで触ったすべてのライブラリの中で一番すごいと感動した。

### CORS

HTTPヘッダーにwith-credentialを設定したり、APIサーバー側でクライアントのURLを指定したりなどLaravelのみでのMPA開発では不要な工程について学習するとき最初は少し戸惑って大変だった。
go.modファイルについて

### 概要

Goプログラムの依存関係とモジュール情報を管理するためのファイルである
go.modファイルについて

### モジュールファイルの作成方法

①ワークスペースとなるフォルダを作成
②go mod init フォルダ名でgo.modファイルを作成。
例えばワークスペースのフォルダ名が「GoBasic」だとすると以下のようなコマンドとなる

```
go mod init GoBasic
```
### go.modファイルの役割

#### 1.モジュールの宣言
プロジェクトのモジュール名を宣言する。

#### 2.依存関係の管理
プロジェクトが依存している他のモジュールやパッケージの情報を記載する

#### 3.バージョンの固定
依存関係のバージョンを固定することで、特定のバージョンのモジュールを使用することが保証される

#### 4.ビルド情報の提供
go buildやgo runコマンドを使用する際、go modファイルの情報を元に必要な依存関係を
自動的にダウンロード・管理する。

#### 5.モジュールのアップグレード
依存関係のバージョンを手動または自動でアップグレードする際に、go.modにその情報が反映される
【Proxmox】Bluetooth を HomeAssistant にパススルーする

# はじめに
`Proxmox` に入れた `HomeAssistant` で `Switchbot` 製品を `Bluetooth` 接続するために、`TP-Link Bluetooth USB Bluetooth 5.3` を USB 接続して `HomeAssistant` にパススルーをする。

https://amzn.asia/d/2Dz1yOd

# Proxmox で認識しているかどうか確認
以下コマンドで確認できる (不要な出力は消している)
```
root@server:~# lsusb
Bus 001 Device 004: ID xxxx:xxxx TP-Link TP-Link Bluetooth USB Adapter
```

# HomeAssistant VE にパススルーする
1. `Hardware` タブの `Add` ボタンから `USB Device` を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/9600c665-5ef7-86fc-78fe-dfb956ef4344.png)

2. `Use USB Vendor/Device ID` から 先ほど確認したものを選択し Add する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/713d294a-04c8-5117-7952-2e8e5cef6678.png)

3. 念のため再起動しておく

# HomeAssistant で確認する
1. 設定 > デバイスとサービス > 統合を追加から `Bluetooth` を追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/0ba047e6-87d8-ba3b-f5c7-4070f356d3d9.png)

2. 検出されたデバイスがあればパススルーに成功しているので追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/232bfa39-0560-ff10-8fd8-0d0e76ddb0c8.png)

3. 追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/0ecf5cad-3dd9-9108-3563-13cdc93fb7c5.png)

4. 成功すれば完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/fcb881ce-8397-a72c-67c7-c0545ca6992b.png)

5. SwitchBot がデバイスとサービスに表示されていれば完璧！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/fd1270d5-3e79-5cf5-c9dc-cf733a9c200e.png)

# 参考
https://note.com/nanomana/n/n9860b3260156?magazine_key=m6412cc86ddea

https://community.home-assistant.io/t/proxmox-nuc-and-bluetooth-again-sorry/385415