OmniAICreator/Qiita-1.07M huggingface dataset:
「아직도 바다가 보일까요」を韓国語形態素Universal Dependenciesで解析する

Yige Chen, Eunkyul Leah Jo, Yundong Yao, KyungTae Lim, Miikka Silfverberg, Francis M. Tyers, Jungyeul Park[『Yet Another Format of Universal Dependencies for Korean』](https://aclanthology.org/2022.coling-1.482)(Proceedings of the 29th International Conference on Computational Linguistics (October 2022), pp.5432-5437)を横目に、[一昨日の記事](https://qiita.com/KoichiYasuoka/items/0671e0088bbe24151868)の例文に対応する「아직도 바다가 보일까요」を、韓国語形態素Universal Dependenciesで解析してみた。

```
# text = 아직도 바다가 보일까요
1	아직	아직	ADV	MAG	_	5	advmod	_	SpaceAfter=No
2	도	도	ADP	JX	_	1	case	_	_
3	바다	바다	NOUN	NNG	_	5	nsubj	_	SpaceAfter=No
4	가	이	ADP	JKC	_	3	case	_	_
5-6	보일까요	_	_	_	_	_	_	_	_
5	보이	보이	VERB	VV	_	0	root	_	_
6	ㄹ까요	ㄹ까요	PART	EF	_	5	mark	_	_
```

![ko-morph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428317/71c7afe0-6e32-7393-af21-bf10f6b73e5d.png)

「아직도」と「바다가」は形態素の境界が文字の切れ目にあるが、「보일까요」は「보이」「ㄹ까요」で切れる。つらい。が、その点さえ何とかすれば、少なくともこの例文に関しては、韓国語(形態素単位)とイラヴ語(国語研短単位)がほぼ同じ統語構造になる。韓国語形態素Universal Dependenciesの知識を、イラヴ語へ転用できる可能性があるということだ。素晴らしい。ただし、音韻が全く異なっているので、そこは苦労する可能性が高い。また、韓国語形態素Universal Dependenciesは、私(安岡孝一)の知る限り、[2年近く放置状態にある](https://github.com/jungyeul/morphUD-korean/issues/1)。さて、どうしたものかな。
【初めての人用】Django 環境構築　＃1

<h1>今回やること</h1>

<p>前回HTMLを表示までやりたいといったが、長いので2回に分ける</p>


<ul>
<li>ルートurlの記述</li>
<li>settings.pyへの記述</li>
<li>templateフォルダの用意</li>
</ul>




[#【初めての人用】Django　環境構築ロケット飛ばすところまで](https://qiita.com/souichirou157/items/0ebe37a1016d79062f49)
<br>
[#【初めての人用】Django アプリケーションフォルダを作る](https://qiita.com/souichirou157/items/6fd44126871b45e9b1a0)





プロジェクトフォルダとアプリケーションフォルダの中身
```
プロジェクトフォルダ/
          __init__.py
          asgi.py
          settings.py
          urls.py  
          wsgi.py

```


```
アプリケーションフォルダ/
                        __pycache__ /
                        migrations /
                        __init__.py
                        admin.py
                        apps.py
                        models.py
                        tests.py
                        views.py
```

<h1>settingsに記述</h1>
プロジェクトフォルダの中にある
settings.pyを開く<br>


```

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
 #追記箇所   'アプリケーションフォルダ名.apps.DjangoappConfig' 
]

```

<p>DjangoappConfigの部分が何なのか少し説明すると、apps.pyにある
クラス名を指している。</p>
アプリケーションフォルダの中にあるapps.pyの
DjangoappConfigクラスって意味。


```
----apps.py---
from django.apps import AppConfig


class DjangoappConfig(AppConfig):

    default_auto_field = 'django.db.models.BigAutoField'
    name = 'DjangoApp'

```








<h1>ルートurlを記述</h1>
プロジェクトフォルダの中にあるurls.pyを開くと


こんな風になっているはず

```
from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]


```
<br>


先にアプリケーションフォルダ
の中でルーティング用のファイルを作る。
今回はapp-urlsにする。


```
from django.contrib import admin
from django.urls import include,path


urlpatterns = [
    path('admin/', admin.site.urls),
    path('アプリケーションフォルダの名前/',include('フォルダ名.app-urls'))
]
```

<h6>変わったとこ</h6>
<ul>
<li>includeをインポートしている</li>
<li>フォルダ名.app-urlsと記述することで作ったファイルを見つけてくれる</li>
</ul>
<br>

<h1>templateフォルダを作る</h1>

次回のために、アプリケーションフォルダの中に、テンプレートフォルダを作る


```
アプリケーションフォルダ
                     __pycache__ /
                     migrations /
                     __init__.py
                     admin.py
                     apps.py
                     models.py
                     tests.py
                     views.py
             #追記   template/index.html

```



今回はここまで、次回は
実際に表示ができるとこまでやりたい。
これだけ知っておけばなんとかなるITの英会話

直近1年間、英語でコミュニケーションを取る必要のある現場にいたので、そこで得られた知見をまとめてみます。

# 実際の事例をもとに解説

3月18日朝、支払システム(Payment System)で本番障害が発生したため、あなたは本番環境のログを確認して原因を調査するよう命じられた。本番環境にはインフラ担当しかアクセスできないため、本番環境のログを参照する際はインフラ担当に依頼して、ファイルサーバーへログファイルをコピーしてもらう必要がある。

インフラ担当はインド人技術者のKumar（クマル）氏である。Kumar氏は業務では英語でコミュニケーションを取っており、日本語はほとんど話すことができない。知っている日本語は「お疲れ様です」「ちょっと待って」「お先に失礼します」のみであり、好きな食べ物はココイチカレーである。

Kumar氏に英語で作業依頼を行い、本番環境のログファイルを受領しなさい。

## まずは話しかける

### とりあえずハロー

*Excuse me* なんて、そんな難しい言葉使わなくていいです。使っている人見たことがありません。 *Hello* で十分です。

*Hello* って結構いろいろな意味があって、「こんにちは」はもちろんハローだし、「もしもし」もハローだし、「なんだって？」「聞いてる？」「お疲れ様です」全部ハローです。積極的にハローって言っていきましょう。

だいたいの場合はあちらからも *Hello* って返ってきます。

### 英語でも「～さん」でOK

Kumarってありがちな名前なんですが、厄介なことに苗字の場合と名前の場合があるのです。苗字を呼び捨てにするのは失礼に当たるし、名前に *Mr.* を付けるのもおかしな感じです。

あと、Kumarだったら明らかに男性名ですが、名前によっては男性なのか女性なのかがわからない場合がありますね。

そこで便利なのが *-san* です。苗字でも名前でも男でも女でも使えます。日本語の「～さん」を英語でも使ってしまいます。

```
Hello, Kumar-san.
```

反応は様々で、あちらも普通に *-san* を付けて、

```
Hello, Cress-san.
```

のように返ってくる場合が大半ですが、中には「ハハハ、ジャパニーズってマジで名前に *-san* 付けるのかよ、ウケる」みたいな反応もあるかもしれません。痛くも痒くもないです。積極的に使っていきましょう。

## 本題に入ります

### 自分がやりたいことを伝える

今回はログが見たいです。最低限の会話で伝えるのであれば「ログが欲しい」なので、

```
I want logfile.
```

で全然OKです。あちらはインド人である以前に技術者です。通じます。

でも、せめて「ログが見たい」くらいにしましょうか。

```
I want to check the logfile.
I want to see the logfile.
```

「どこのログ？」「どのアプリ？」と聞かれるかもしれません。

もうちょっとちゃんと言うのであれば「本番環境の支払システムのログが見たい」なので、

```
I want to check the logfile in production payment system.
I want to see the logfile in production payment system.
```

まあこんなもんでしょうか。これに「今日（今朝）のトラブルの件です」でも付けたら、

```
It's regarding today's trouble.
It's regarding the trouble occurred this morning.
```

おお、いい感じですね。 *regarding* は *about* とだいたい同じで「～について」というような意味ですが、 *regarding* の方がビジネス風で固い言い方になります。

### どうしてほしいかを伝える

確認したいログファイルの名前はこんな感じでした。

> SystemOut.log.2024-03-18

日本語で伝えるのであれば「今日の日付が付いたSystemOut.logを持ってきて、どこか見えるフォルダに置いてください」みたいな感じでしょうか。

```
Could you get SystemOut.log (system out dot log) whose name includes today's timestamp at the end.
Then, put it into any folder where I can access.
```

関係代名詞とか使っていますが中学三年レベルです。

あと、依頼するときは *Could you ...* が丁寧な言い方です。 *Will you* は使いません。

会話の場合は相手からは *OK* のような返答が多いですが、チャットで送った場合は以下のような返答の場合があります。

```
Noted.
```

「了解しました」という意味です。口語ではあまり言いません。覚えておくといい感じです。

### ファイルを置いてくれたようです

作業が終わったようなので、「確認します」と伝えましょう。

```
I will check it.
```

未来形を使っていますが、難しい単語は何一つありません。

## 確認しました

### 違うファイルが入っていました

よくあるよくある。

> SystemErr.log.2024-03-18

「これは違うファイルです。正しくは SystemOut.log です。」

```
This is a wrong file.
SystemOut.log is correct.
```

ITの現場では *wrong* が便利です。よく使います。逆に「正しい」は *correct* で、これもよく使います。

ということで、正しいファイルを置いてもらいました。

### お礼を言います

「以上です、ありがとうございました」

```
That's all. Thank you.
```

# ね、簡単でしょ？

SQL文と一緒です。こんなもの。

難しい単語ないんですよ。文法も中学レベルでどうにかなるし。

英語ネイティブの人と仕事することって実際にはあまりなくて、相手も外国語として英語を話している場合が多いです。つまり、相手も難しい単語は使いたがらないし、難しい文法も避けてきます。

何が言いたいのかというと、中学英語をちゃんとやっておけばどうとでもなりますよという話です。
pod installが Installing gRPC-Coreで進まない

## 問題
`pod install`すると`Installing gRPC-Core`で進まなくなりました。
```
Installing cloud_firestore (4.14.0)
Installing firebase_core (2.24.2)
Installing gRPC-C++ (1.62.1)
Installing gRPC-Core (1.62.1)
```

## 開発環境
MacBook Air(M1, メモリ：8G)
pod: 1.16.3
## 解決方法
ズバリ、"待つ"ことが解決策でした。
gRPC-Coreは約1Gあるのでダウンロードに時間がかかります。私の場合、12分ほど待ちました。
【小ネタ】iPad（第10世代）で Type-C接続のビデオキャプチャデバイスを使ってみる（iPadOS 17 での UVCサポート）：Safari ＋ WebRTC samples

## はじめに
昨年、話題になっていた「iPadOS 17 での UVCサポート」に関して、軽く試してみて記事を書きました。

https://applech2.com/archives/20230918-ipados-17-uvc-web-camera-support.html

これまでは自分の個人所有の iPhone・iPad が、UVCサポート非対応のデバイスのみだったため、この UVCサポートは試せていない状況が続いていました。
しかし最近、UVCサポートに対応した iPad（第10世代）を買ったので、今さらながら iPadOS 17 の UVCサポートを試してみました。

### 試した時の様子
まずは、実際に試してみた時の様子を掲載してみます。

https://twitter.com/youtoy/status/1770417116224856474

上記では、iPad にビデオキャプチャデバイスを接続し、そのビデオキャプチャデバイスの入力が iPad側で認識・表示されることを確認しました。

その確認には、Safari で開いた「とある Webサイト（※ 後で補足）」を使っています。
ビデオキャプチャデバイスに HDMIケーブルをつないでないので、カラーバーが表示されている状態になっていますが、ページ右あたりを見ると「USB Video」という選択肢を選べているのが分かります。

ちなみに、このページはマイクを選ぶプルダウンメニューもあるのですが、そこでは「USB Digital Audio」を選択できるようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/a332c0f1-e7f5-ec09-58a1-dc9d18808683.png)

ちなみに、ビデオキャプチャデバイスが接続されてない時の、選択可能なカメラは以下の 3つになります（全て、iPad内蔵のカメラです）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/d36dd557-b069-a97c-5bbe-c30c0051934d.png)

### お試しで使ったサイト
上で、「とある Webサイト」と書いていたページについて補足します。

その Webサイトは、以下の WebRTC samples に掲載されているサンプルの中の 1つです。

●WebRTC samples
　https://webrtc.github.io/samples/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/31ac4d1c-bd22-406d-798b-912dc41433ae.png)

具体的には、「Devices」カテゴリの中にある「Choose camera, microphone and speaker」で、[MediaDevices.getUserMedia()](https://developer.mozilla.org/ja/docs/Web/API/MediaDevices/getUserMedia)を使った処理を試せるサンプルです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/20a42e36-0162-5f36-5acc-7d93101b4723.png)

そのサンプルの URL は以下です。

●Select audio and video sources
　https://webrtc.github.io/samples/src/content/devices/input-output/

このサンプルは、PC で MediaDevices.getUserMedia() の挙動を確認する際にも便利なサイトです。

## 余談： UVC対応アプリ
今回は、ビデオキャプチャデバイスの入力を Safari上で確認しましたが、UVC対応アプリもいろいろ出ていて、それを使うこともできます。
今まで Web のニュース・記事で、iPadOS 17 での UVCサポートを試した方の話を見ていくと、複数のアプリが登場しています。

また、App Store上で「UVC」というキーワードで検索してみると、以下のように複数のアプリが出てきます（※ 以下の画像は、出てきたアプリの一部のみで、さらに他のアプリも検索結果に出てきています）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/9290a2f8-96bb-7dd5-5f2d-811fd893526c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/4da0d938-d264-0819-6bba-873cee56d507.png)

これらとの組み合わせも、別途、試せればと思っています。
GASのSHA256を16進数の文字列に変換したいときのコードスニペット

# 目的のコード
指定された鍵で HMAC-SHA256 を使用して指定された値に署名し、16進数の文字列にして返す
```js
function toSha256(key: string, value: string): string {
	const signatureBytes = Utilities.computeHmacSha256Signature(value, key);
	const signature = signatureBytes
		.map((byte) => (byte < 0 ? 256 + byte : byte))
		.reduce((str, byte) => str + byte.toString(16).padStart(2, "0"), "");
	return signature;
}
```
keyに鍵を、valueに目的の値をいれる。戻り値が16進数の文字列だ。

# 解説
* 下記のユーティリティ関数のwrapperである。
 
https://developers.google.com/apps-script/reference/utilities/utilities?hl=ja#computeHmacSha256Signature(Byte,Byte)

* GASのバイト列は、符号付き整数になっているのがNode.jsのByteとは異なるので、単純な流用ができなかった。
* あんまり低レイヤー詳しくないが、負数に256を足して、それぞれ16進数に変換したら目的のものが得られたので良しとした。

## 先行記事があります
https://qiita.com/tatataichi/items/7e3a27e1b69200d3fd86

こちらが先行記事でして、私の貢献は、この機能をモジュール化して切り出したこと。

## 何に使用したのか
* 個人的に、とあるprivate APIにアクセスする際に必要となった。

## ちょっとしたNode.jsのサーバーほしいな、ってとき、GASも選択肢
* GASはHTTPクライアント/サーバーになれる
* GASは定期実行できる
* GASは永続化層をスプレッドシートにすればいいので、状態も持てる
* ただGASはNode.jsみたいにライブラリがないのが弱点なので、今回紹介したようなユーティリティがないと辛い
* 僕は暇なときこのへん進めてくので、Universalな機能で困ったら相談してください

## 関連記事

https://qiita.com/shinout/items/ab69b78205a2c44e1360
M1 Macでmysql2がインストールできない時の対処法

久しぶりにローカル環境でRailsを構築した際にエラーが出たので対処法をまとめます。


# 使用環境

- Apple M1 
- ruby 3.1.2

# エラー文
`bundle install`をするとmysql2のビルドエラーが出ました。

```
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
Installing mysql2 0.5.6 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

...
中略
...

Using mysql_config at /opt/homebrew/bin/mysql_config
-----
checking for mysql.h... yes
checking for errmsg.h... yes
checking for SSL_MODE_DISABLED in mysql.h... yes
checking for SSL_MODE_PREFERRED in mysql.h... yes
checking for SSL_MODE_REQUIRED in mysql.h... yes
checking for SSL_MODE_VERIFY_CA in mysql.h... yes
checking for SSL_MODE_VERIFY_IDENTITY in mysql.h... yes
checking for MYSQL.net.vio in mysql.h... yes
checking for MYSQL.net.pvio in mysql.h... no
checking for MYSQL_DEFAULT_AUTH in mysql.h... yes
checking for MYSQL_ENABLE_CLEARTEXT_PLUGIN in mysql.h... yes
checking for SERVER_QUERY_NO_GOOD_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_NO_INDEX_USED in mysql.h... yes
checking for SERVER_QUERY_WAS_SLOW in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_ON in mysql.h... yes
checking for MYSQL_OPTION_MULTI_STATEMENTS_OFF in mysql.h... yes
checking for my_bool in mysql.h... no
checking for mysql_ssl_set() in mysql.h... no
-----
Don't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load
-----
-----
Setting libpath to /opt/homebrew/Cellar/mysql/8.3.0_1/lib
-----
creating Makefile

...
中略
...

An error occurred while installing mysql2 (0.5.6), and Bundler cannot continue.

In Gemfile:
  mysql2
```
# 原因

MySQLのヘッダーファイルとライブラリの環境変数が設定できていなかったため。

`Don't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load` 
というメッセージは、システム上でMySQLのライブラリへのパスを設定する方法が不明であるとのことです。

# 対処法

mysqlの正しいパスを設定します。

## MySQLのパスを確認

正しい場合は次のように出てきます。

```
$ which mysql
/opt/homebrew/bin/mysql
```

## MySQLのヘッダーファイルとライブラリの環境変数を確認

正しい場合は次のように出てきます。
自分はここが設定できていませんでした。

```
$ echo $LIBRARY_PATH
/opt/homebrew/lib
$ echo $CPATH
/opt/homebrew/include
```

## 環境変数を更新する
もしパスが含まれていない場合は、以下のコマンドを実行して環境変数を更新しましょう。

```
$ echo 'export PATH="/opt/homebrew/bin:$PATH"' >> ~/.bash_profile
$ echo 'export LIBRARY_PATH="/opt/homebrew/lib:$LIBRARY_PATH"' >> ~/.bash_profile
$ echo 'export CPATH="/opt/homebrew/include:$CPATH"' >> ~/.bash_profile
```

## bash_profileを読み込む

```
$ source ~/.bash_profile
```

以上により、解決しました。


# 参考

こちらは事前にやった対応です。
今回の原因とは違いますが、こちらを事前に行いました。

https://zenn.dev/obregonia1/articles/2a804d3a3ecb17

https://zenn.dev/kosuke_ito/articles/0d508035bcd570
未経験40代から始めたLinux街道

# はじめに
私は今SESで働いていますが、この会社に入社した時は40歳未経験でした。それまで営業、販売の仕事ばかりだったのでコールセンターの類しか参画できる現場がありませんでした。ITエンジニアらしいキャリアを積むにはどうすればいいか？そこで、私が営業だったら今の自分を売り込むにはどうすればいいか思案しました。

# LinuCを選んだのはなぜ？
経験はそういう現場に参画できないことには得られない。未経験であることはどうしようもないので他のことを考えます。「経験はないけど、これならまぁいいか」と思わせるには何があればいいか考えます。わかりやすいものに資格があります。では、どの資格がいいか考えます。市場は大きいけど、だれでも持っているとはいえないものが理想です。最上位のレベルまで計画的に、順調に取得できるものが理想です。どれがいいか考えます。試案に試案を重ねた結果、選んだのがLinuCでした。

# 未経験のままLinuC レベル3まで
会社は資格取得を奨励しています。合格すれば受験料も報奨金も出ます。結果的に受験料は会社持ちになるけど無駄な経費を支出させたくないのでPing-tの割引チケット(バウチャー)を利用したりでコストを抑えながら計画的に受験してレベル3まで取得しました。1年ちょっとかかりましたが、この間もLinuxを使う現場には参画できず未経験のままレベル3認定までいきました。おかげさまで、その後はLinuxを使う現場に参画することもでき、そこそこの経験を積むことができています。選考の際に先方からよく言われたのが「え、未経験でLinuCレベル3まで？すごいですね」という言葉。LinuCを選んだことで期待通りの結果を得られました。

LinuCとは

https://linuc.org/about/01.html

受験前に割引チケットは要確認！

https://mondai.ping-t.com/g/ticket_exams

コスパがいいプレミアムプラン

https://mondai.ping-t.com/g/contents/premium_plan_introduction

# 教科書の更新にも参加しちゃった
LinuCでは努力によって評価を手に入れました。縁あって昨年からLinuCの認定機関LPI-Japanの掛け声のもとオープンコミュニティに参加し、Linuxサーバー構築標準教科書のバージョンアップに貢献することで開発協力者として名前を載せてもらいました。まだまだすごいエンジニアとはいえないレベルですが、貢献の競争に参加することで社内外に通用するソフトパワーを得るに至りました。

無償公開中のLinuxサーバー構築学習用教材「Linuxサーバー構築標準教科書」がバージョンアップ

https://lpi.or.jp/news/press/page/20240201_01/

# さいごに
私が働いている会社は生涯現役エンジニアをミッションに掲げています。未経験で40代で、普通ならNGになりそう。それでもLinuCで望むキャリアを手に入れています。IT業界にいて資格選びで迷っているならLinuCがおすすめです。リスキリングにも。40歳超えて知識0からでも上述の結果を出せるのだからだれでもやれるのです。
そう、約半世紀ずっーーーーーと引きこもりで地球から一歩も出ていない石ころでも。
C++の配列に代入したいとき

# 目的
例えばこんな構造体があって、メンバーの配列に値を設定したいとします。
```cpp:今更変更なんて出来ないヘッダー.h
struct Hoge {
    /* 省略 */
    uint8_t hoge_color[4]; // RGBA
};
```
C++では良くあることです。

```cpp
// 当然エラーになる
hoge.hoge_color = {255, 255, 255, 0};
```

# こんなときRustであったならば…
もし、現状の開発環境がRustに対応していれば、悩む必要は無かったでしょう。
```rust
// 当然のように動く
hoge.hoge_color = [255, 255, 255, 0];

// これも行ける
let _ = std::mem::replace(&mut hoge.hoge_color, [255, 255, 255, 0]);

// サイズ不一致だとコンパイルエラー
hoge.hoge_color = [5, 4, 3, 2, 1, 0, 0, 0];
```

# 手遅れでなければ
もし、構造体の定義を変更できるのであれば、配列をstd::arrayに変更すべきです。
```cpp:変更が間に合ったヘッダー.h
#include <array>
struct Hoge {
    /* 省略 */
    std::array<uint8_t, 4> hoge_color; // RGBA
};

// 動く
hoge.hoge_color = {255, 255, 255, 0};
```

std::arrayは、配列の代替として(十年以上前に)提案されたクラスです。
C++で配列からstd::arrayに移行しないのはバッドプラクティスです…と言いたいところですが、そもそもC++の存在そのものがバッドプラクティスでしょう。

しかしながら、このような解決策をとれないことも、C++では良くあることです。

# 解決策(暫定)
以下のように書けるよう、テンプレート関数を定義してみました。
```cpp
set_array(hoge.hoge_color, {255, 255, 255, 0});
```
関数の中身は以下の通りです。
```cpp
#include <algorithm>
#include <array>
template <typename T, size_t N>
inline void set_array(T (&dest)[N], const std::array<T, N> &src)
{
    std::copy(src.begin(), src.end(), std::begin(dest));
}
```

第一引数がよく分からないことになっています。この様にすることで、[固定長配列を引数にできる](https://www.techscore.com/blog/2013/02/08/how-to-calculate-array-length-in-c-and-cpp/)らしいです。
第二引数は先程登場したstd::arrayですね。何故かこちらを使用しないと動かなかった…。

# おしまい
- C++には、昔ながらの代入出来ない配列と、代入できるstd::arrayがある
- ~~この状況でも入れる保険があるんですか~~代入出来ない配列も、テンプレートを利用することで、それっぽいことはできる
- もっと良い書き方はないだろうか?
SIerのトンチキスクラムについて (7)

# 決定的な違いについて

そもそもお客様はスクラムの採用に際し、全てを受け入れるという立ち位置で何の色にも染まっていなかったと思います。
問題は仕事を受注したSIerのプロパーの方々との意見相違でした。

ざっくり考え方の違いを列挙すると下記の通り。
* 管理と自律（自立）
* 統治と自治
* 完全な計画と不確定への対処

何よりも決定的な認識相違が３番目の、不確定さへの対処だと思います。

それらに対し彼らの主張と私の思うところは下記

* 我々が全てを知っている、我らに従え
    * →技術にしろ手法にしろ、全てが時代遅れ。アーキテクチャの最適解は年単位で変わる。
* 雇われの信用も信頼もできないエンジニアどもらはそれに従えばよい
    * →自らの無知を知り活動を顧みることで成長すればいいんじゃないですか？　何も信用してないどころか見下す傾向が強く、人権は無いらしい。
* 計画してないことが怖い、恐ろしい
    * →しないわけがなくて計画を回すサイクルが短いだけです。これだけの不確定要素が揃っている中で、なぜそんなに完全な計画に縋ろうとするのか。

彼らとは最後までわかりあえなかったと思います。
あれから５年くらい経つけれど、おそらく今やってもだめでしょう。

私がとったスタンスは「話は誰のものでもなんでも聞くけどスクラムを破綻させうるものはなんであろうと排除する」「妥協点を探す」でした。

そりゃ億単位の仕事請けたんだから失敗はできないと思うし干渉もしたいと思うけど、だったら自分たちが好き勝手干渉できるようなフレームワーク使えばよかったんじゃいですかね。

まあ、そこに私は居ないんですけど。

干渉するにもルールがあり、それに従わなければ混沌と破綻が待つのみですし、外部からの不用意な干渉や制約でスクラムが崩壊した事例は枚挙に暇がございません。

戦いは続く。
ある日私が必要なくなったことに気づくまで。
DBeaver日本語版のカラム設定の「身元」って何だ？

絶対に英語→日本語の翻訳ミスだとは思うけど、「身元」って何なんだ・・・？
![CleanShot 2024-03-20 at 21.41.07@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24333/0fbd5082-1620-8a4f-c05c-17ee4a519e85.png)

正解は「Identity」でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24333/d0d8fef5-eaed-8914-7bfc-c783be152d6b.png)

公式ドキュメントより

https://dbeaver.com/docs/dbeaver/Creating-columns/

> Set the column as an identity column, which will auto-increment its value with each new row.

> カラムを identity カラムとして設定すると、新しい行が来るたびにその値が自動的にインクリメントされます。

Collationは英語のままなんだから、Identityも英語のままにしてほしいもんだよね。

ではまた！
PostgreSQL 基本コマンド

# はじめに
こんにちは！初級エンジニアのふかこうです！
私が現在勉強中のPostgreSQLの基本コマンドについて記事を書いていこうと思います。
興味がある方、ぜひ一緒に勉強していきましょう！

# この記事の対象者
・PostgreSQLを学びたい方
・初級エンジニア
・IT企業に就職する学生

# 筆者のレベル
・初級エンジニア

# 1.ログイン/ログアウト
ログイン
`$ psql -U ユーザ`

ログアウト
`# ¥q`

# データベース操作
データベース一覧を表示
`# ¥l`

データベースを新規作成
`# create database 新規データベース名;`

データベースを削除
`# drop database データベース名;`

データベースに操作
`# ¥c データベース名;`


# テーブル操作

テーブル一覧を表示
`# ¥dt`

テーブルを作成
`# create table 新規テーブル名;`

テーブルを削除
`# drop table テーブル名;`

# データ操作

データを新規追加
`# INSERT INTO テーブル名(列名1, 列名2)　VALUES （　値１, 値2）;`

データを削除
`# DELETE FROM テーブル名 WHERE 条件；`

データを編集
`# UPDATE テーブル名　SET 列名=値　WHERE 条件；`

データを検索
`# SELECT * FROM テーブル名　WHERE 条件；`
or
`# SELECT 列名　FROM テーブル名　WHERE 条件；`
PostgreSQL 使用例

# はじめに
こんにちは！初級エンジニアのふかこうです！
私が現在勉強中のPostgreSQLについて記事を書いていこうと思います。
興味がある方、ぜひ一緒に勉強していきましょう！

# この記事の対象者
・PostgreSQLを学びたい方
・初級エンジニア
・IT企業に就職する学生

# 筆者のレベル
・初級エンジニア

# PostgreSQLとは
PostgreSQLは、拡張性とSQL準拠を強調するフリーでオープンソースの関係データベース管理システム。
ライセンスコストがかからないこと、世界中の技術者による知見によって開発される高品質なプログラムであること、ベンダーロックインを回避できることなど、OSSならではのメリットに加え、商用に耐えうる機能の豊富さや性能、堅牢性、拡張性を備えています。

# よく使うSQL文
■Copyコマンド、カンマ区切り
Copy テーブル名 from 'ファイル名' (delimiter ',' format csv, header true)
ヘッダーがない場合は、header trueを削除

■Copyコマンド　タブ区切り
COPY users TO 'ファイル名' (delimiter e'\t' format csv)

■Update
update テーブル名　set カラム名 = value where 条件式;
他の方も見ているテーブルの場合、影響を最小限に留めるためにupdateをよく使用する

■truncate
truncate テーブル名;
サイズが大きいテーブルを削除する場合に使用。deleteと違い、検索せずにテーブルを削除できるため、処理スピードが速い

■revoke
ユーザーから、テーブルへのアクセス権限を奪うときに使用
REVOKE SELECT ON テーブル名 FROM ユーザー名;

■grant
ユーザーにテーブルへのアクセス権限を付与するときに使用
grant SELECT ON テーブル名 to ユーザー名;

# ロールバックについて
実行中のトランザクションの処理を全て廃棄し、データをトランザクション開始前の状態にすること。
Begin;
update テーブル名 set カラム名 = 1 where 条件式;
rollback;

# ロックについて
トランザクションが実行され、あるレコードにアクセスしている際に、他のトランザクションから削除や更新できないようにすること
ex)
Select * from テーブル名 where 条件式 for upate;
select 文が実行された時点で、commit/rollbackが実行されるまで条件に一致した行にロックがかけられる。
S3 Transfer AccelerationとAWS Global AcceleratorとAmazon CloudFrontのそれぞれの特徴について

初めまして、目黒です。

4月からAWSの仕事に携わるために、AWSの資格を取得するため日々勉強をしています。
現在は3月末の SOAの試験に向けて勉強中です。

今回は以下サービスの特徴についてまとめます。
* **S3 Transfer Acceleration** 
* **AWS Global Accelerator** 
* **Amazon CloudFront** 

### S3 Transfer Acceleration 
一言まとめ：S3へのデータアップロードを高速化するためのサービス
※「Amazon CloudFront の PUT/POST」もS3にデータをアップロードを高速化できる
　(CloudFrontの詳細は下記リンクを参照)

https://aws.amazon.com/jp/s3/faqs/#:~:text=%E5%8F%82%E7%85%A7%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82-,Amazon%20S3%20Transfer%20Acceleration,-Q%3A%20S3%20Transfer

### AWS Global Accelerator について
一言まとめ：一つのエッジロケーションから遠くのユーザと通信を可能とするためのサービス

https://aws.amazon.com/jp/global-accelerator/faqs/

### Amazon CloudFront について
一言まとめ：静的、動的コンテンツをエッジロケーションへ配信するためのサービス(CDN)

https://aws.amazon.com/jp/cloudfront/faqs/

# 自己紹介
初めまして、目黒です。(@megggguguuuuuuu)

高専を卒業後、新卒で今の会社に入社をしました。
今年の4月で、3年目突入になります。

現在は、SESにてとあるサービスの運用・保守をしています。
4月以降はAWS関連のメインの業務に参画する予定なため、AWSの勉強を行っております。

AWS資格を現在 CLF,SAA を取得しており、現在 SOA の資格取得に向けて勉強中。
DVA は6月までに取得するつもります。

AWS資格 12冠することが目標です。
同じくAWS 資格を目指す方は、お互いに刺激しあいながら資格取得に向けて頑張りましょう！

# 宣伝
毎週の土日に、僕が入社している会社のオフィス(池袋)にて「もくもく会」をしています。
ぜひご興味がある方がいましたらご参加ください！！！

https://mokumoku-teikoku.connpass.com/
動画でWindowsPCデスクトップをキャプチャしてアニメーションGIFに変換


Windowsはデスクトップキャプチャの機能があります。画面の操作を動画に保存できます。

`CTL+G` でXBOXツールバーみたいのが出てくるので、それでmp4として保存できます。mp4のままだとQiitaなどにアップできあにので、アニメーションgifに変換します。（本当はmp4の方が容量も小さく収まるのでアニメーションgifは苦肉の策です）

以下私が先程実行したサンプルです。

```bash
## まずは取り回しやすいように縮小する（高さを360で変形させずに）
ffmpeg -i /mnt/c/Users/yugoy/Videos/Captures/te11.mp4 -vf scale=-1:360 out.mp4

## タイトルバーの領域を切り取る(ざっくり上から30ピクセルをcropするつもり)
## 出力時の幅：出力時の高さ：x原点:y原点の順にcrop領域を設定する
ffmpeg -i out.mp4 -vf crop="580:330:0:30" out2.mp4

# できあがったmp4をgifに変換する
ffmpeg -i out2.mp4 out.gif
```

上から30ピクセルを取り除いたのは適当です。

そうやって作ったアニメーションgifを以下の記事で使っています。

https://qiita.com/yugo-yamamoto/items/ca8e8236e2a044298b79
SPA、SSG、SSR、ISRについてまとめてみた

# はじめに
こんにちは！エンジニア転職を目指している伊藤です！
今回は、Next.jsを学習している中で、SSG、SSR、ISRという聞き慣れない言葉が出てきたので、記事にまとめようと思います。

# SPA(Single Page Application)とは
SPAは、クライアント側（フロントエンド）でページのレンダリングとデータの操作を行うウェブアプリケーションの手法です。
初回のページロード時に全ての必要なリソース（HTML、CSS、JavaScript、画像など）を取得し、その後はJavaScriptを使用してページ遷移やコンテンツの更新を行います。

**メリット**
* UXの向上
* シームレスなページ遷移
* キャッシュを活用した高速なロード

**デメリット**
* 初期ロードが遅くなる場合がある
* SEO（検索エンジン最適化）が弱い
* セキュリティ上のリスクがある


**代表的なフレームワーク**
* React
* Angular
* Vue.js

# SSG(Static Site Generation)
SSGは、サーバー側（バックエンド）で静的なHTMLファイルを生成する手法です。
サーバーが事前にページをビルドし、その静的なファイルをクライアントに提供します。
ブログや企業のウェブサイトなど、頻繁に変更されないコンテンツを効率的に配信することができます。

**メリット**
* 高速なロード
* SEOに優れる
* 安全性が高い
* ホスティングが容易

**デメリット**
* コンテンツの更新に再ビルドが必要
* 動的なコンテンツへの対応が難しい
* データの適切なキャッシュ管理が必要

**代表的なフレームワーク**
* Gatsby
* Next.js

# SSR(Server-Side Rendering)
SSRは、サーバー側（バックエンド）でウェブページのHTMLを生成してからクライアントに送信する手法です。
ユーザーがページにアクセスすると、サーバーが要求されたページを動的に生成し、そのHTMLをブラウザに送信します。
クライアント側でJavaScriptを実行する必要がないため、低速なデバイスやネットワーク環境でも優れたUXを提供できます。

**メリット**
* UXの向上
* 初期ロードが速い
* SEOに優れる

**デメリット**
* サーバーサイドの負荷が増加する可能性がある
* レンダリングの遅延が発生する可能性がある
* クライアント－サーバー間の通信が必要

**代表的なフレームワーク**
* Next.js
* Nuxt.js

# ISR (Incremental Static Regeneration)
ISRは、SSGの一種であり、動的なコンテンツを含む静的サイトを構築するための手法です。
ISRでは、静的なページをビルドし、一部のページを定期的に再生成します。ユーザーがページにアクセスすると、古いバージョンの代わりに最新のページが提供されます。
これにより、ブログの最新記事や商品リストなどを自動的に更新することができます。静的ページのメリットを保ちながら、最新の情報を提供することが可能になります。

**メリット**
* 静的サイトのパフォーマンスとSEOを維持しながら動的なコンテンツを更新できる
* 部分的な再ビルドで効率的な更新ができる

**デメリット**
* 更新のタイミングによっては古い情報が表示される可能性がある
* ビルド時間とサーバーのリソースが必要

**代表的なフレームワーク**
* Next.js

# さいごに
今回、SPA、SSG、SSR、ISRの各手法について整理したことにより、各手法のメリットとデメリットを理解することができました。
また、Next.jsを使用すれば、それらの手法を状況に応じて使い分けられることがわかったので、引き続き学習を続けたいと思います。
Zod入門

## Zod
- TypeScriptで使える、データ構造をチェックするライブラリ
- バリデーションをするのによい

### スキーマ
- データ構造の定義
```
const mySchema = z.string();

const User = z.object({
  username: z.string(),
});
// (小文字objectはプリミティブ型以外の型)
```

### パース
- データ構造に合うかをチェック
```
// スキーマ.parse(チェックしたい対象)の形式
mySchema.parse("tuna") // =>"tuna"
mySchema.parse(12) //=>throws ZodError
User.parse({ username: "Ludwig" });

// safeParseを使うと、エラースローされない
mySchema.safeParse("tuna"); // => { success: true; data: "tuna" }
mySchema.safeParse(12); // => { success: false; error: ZodError }

```

### coercion
- 型の変換を行う
- 変換できない場合はエラー
- 内部的にはJavaScriptのString()メソッドで変換が行われる
```
const schema = z.coerce.string();
schema.parse("tuna") //=> "tuna"
schema.parse("12") //=> "12"

```

### エラーメッセージ
- stringなどのスキーマでは、エラーメッセージを設定できる
```
const FormSchema = z.object({
  id: z.string(),
  customerId: z.string({
    invalid_type_error: 'Please select a customer.',
  }),
  status: z.enum(['pending', 'paid'], {
    invalid_type_error: 'Please select an invoice status.',
  })
});
```


参考:
- https://zod.dev/?id=basic-usage
- https://nextjs.org/learn/dashboard-app/mutating-data
- https://nextjs.org/learn/dashboard-app/improving-accessibility
推し活ドリブンで作ったメッセージ表示ツール

### 実行結果

![out.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53489/879efb9d-d425-f6e0-de7f-0ff70e4e6a90.gif)

### ソース

```html
<html>
<style>
    html,
    body {
        margin: 0;
        padding: 0;
        background-color: black;
        overflow: hidden;
    }

    /* メインの画面はマーキーされてる画面 */
    #main_pane {
        margin: 0;
        padding: 0;
        line-height: 100vh;
        height: 100vh;
        color: white;
        font-size: 80vh;
        width: max-content;
        transform: scale(0.7, 1);
        font-weight: bold;
    }

    /* 設定画面はモーダルっぽい動き */
    #config_pane {
        position: fixed;
        text-align: center;
        top: -100vh;
        width: 60vw;
        left: 20vw;
        height: 60vh;
        background: #999;
        /*動き*/
        transition: all 0.6s ease-in-out;
        padding: 10px;
    }
    /* 設定画面アクティブ */
    #config_pane.paneactive {
        top: 10vh;
    }

    button {
        margin: 10px;
        font-size: 300%;
    }

    input {
        margin: 10px;
        font-size: 300%;
    }
</style>
<div id="main_pane">タップするとメッセージを変えることができます</div>
<div id="config_pane">
    <div><input id="marquee_text" type="text" placeholder="ここにメッセージ"></div>
    <div style="font-size: 300%;">長体:
        <select size="1" id="chotai" style="font-size: 100%;">
            <option value="1">正体</option>
            <option value="0.9">長１</option>
            <option value="0.8">長２</option>
            <option value="0.7" selected>長３</option>
        </select>
    </div>
    <div><button id="start_marquee">スタート</button></div>
    </form>
</div>
<script>
    document.addEventListener('click', (e) => {
        console.log(e.target)
        // ベースをClickされたら設定画面をトグル
        if (e.target.id == 'main_pane' || e.target.nodeName == 'BODY') {
            config_pane.classList.toggle('paneactive')
            return
        }
        // マーキースタートでテキストを反映してスタート
        if (e.target.id == 'start_marquee') {
            main_pane.innerText = marquee_text.value
            config_pane.classList.toggle('paneactive')
            startMarquee()
            return
        }
    })
    function startMarquee() {
        const textLength = main_pane.innerText.length;
        main_pane.animate(
            [
                {
                    // ギリ画面の外に出しておく
                    transform: `translateX(100vw) scale(${chotai.value},1)`,
                },
                {
                    // divの幅すべてを左に出す
                    transform: `translateX(-100%) scale(${chotai.value},1)`,
                },
            ],
            {
                // 文字数 x 0.8秒かけて移動させる
                duration: textLength * 800,
                iterations: Infinity,
            }
        )
    }
    startMarquee();
</script>
</html>
```

### 解説

- コピペで動くようにペラ１で作ってます
- getElementByIdを使わなくても、id付けた要素はグローバルにアクセスできるのを最近知った（命名規約がないと混乱するな）
- 設定画面がグィんと降りてくるのは、クラスを変えたときにy座標が変わるんだけど、`transition: all 0.6s ease-in-out;`でアニメーションぽくしています

### 残課題

- スマホでテストしてない（viewportさえつけてない）のでそのテスト
- 本当はぷっくりフォントに影付けて立体にしたい（CSSだけで出来るのか？）
CoppeliaSim(旧Vrep)の各フォルダの関係性

# CoppeliaSimの各フォルダの分類と意味
CoppeliaSimにはいくつかのフォルダが存在します.

## scripts

scriptsフォルダは, CoppeliaSimのシナリオやシーン内で使用されるluaスクリプト（または一部の場合Pythonスクリプト）を保存するためのフォルダです.　これらのスクリプトは,オブジェクトの振る舞い・制御・センシング・データ処理などのさまざまな機能を実装するために使用されます.　これらのスクリプトはシーン内のオブジェクトに直接関連付けられることがあります.

### __pychache__
scriptsの中に存在します. __pychache__

__pychache__ディレクトリは,各スクリプトのバイトコード(Bytecode)が格納されます.バイトコードとは,　高水準言語で書かれたソースコードをプログラム実行時に実行可能な形式に変換する中間表現のことです.　これはソースコードが解釈されたり実行される前にプログラムの性能を向上させるために使用されます.

　基本的にプログラミングのソースコードは,　一般的に人間が理解しやすい形式で書かれます.しかし,　コンピュータが直接理解し実行するためには,　機械語やアセンブリ言語などの低水準言語に変換する必要があります. 高水準言語から直接機械語に変換するのではなく,　中間表現であるバイトコードに変換されます.

バイトコードを利用すると,　プログラムの移植性・セキュリティ・パフォーマンスの向上等の利点を得ることが出来ます.

## cfg
cfgフォルダは,　CoppeliaSimの設定ファイルを保存するためのフォルダです.　このフォルダ内には,CoppeliaSimの動作や外部アドオンの設定など,シミュレーション全体の構成に関する設定ファイルが含まれています.これらのファイルは,CoppeliaSimの起動時に読み込まれ,シミュレーションの動作に影響を与えることがあります.

## jsons
jsonsフォルダは,シーンやモデルに関連する追加のデータファイル（JSON形式）を保存するためのフォルダです.　これらのファイルには,オブジェクトのパラメータ,　外部リソースへの参照,シミュレーションの初期設定などが含まれる場合があります.

## src
srcフォルダは,CoppeliaSimのソースコードを保存するためのフォルダです.　このフォルダには,CoppeliaSimの開発に使用されるC++ソースコードやその他のソースファイルが含まれています.　一般的なユーザーが直接触れることは少ないですが,CoppeliaSimの開発者やアドオンの開発者がこのフォルダを使用することがあります.

### まとめ
以上のフォルダは,CoppeliaSimのプロジェクトの異なる側面に関連するさまざまな種類のファイルを整理するために使用されます. それぞれのフォルダは特定の目的を持ち, シミュレーションの構成・振る舞い・データ管理などに関する異なる側面を処理します.
Windows上にubuntuをインストール

# 初めに

Windows上にubuntuをインストールする手順を残します。
自分なりにやった手順を書いていきます。

## 環境
Windows11

## インストール手順

### 1.PowerShellを管理者で実行する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1243082/8c73aa4d-136d-447e-8db0-6b3df3a59c5b.png)

スタートメニューで PowerShellと検索
右クリックで「管理者として実行」を選択


### 2.コマンドの実行

https://learn.microsoft.com/ja-jp/windows/wsl/install-manual

これを参考にします。

PowerShellに以下のコマンドを流していってください

`
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
`

`dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
`

### 3.Ubuntuのインストール

MicroSoft StoreでUbuntu と検索してください

2024/03/20現在
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1243082/6c74e75b-8977-da4d-8ab1-e3dc42e47bca.png)

インストールします

### 4.更新プログラムパッケージのダウンロード

2の中で紹介した
https://learn.microsoft.com/ja-jp/windows/wsl/install-manual

の手順4に

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1243082/7fc2c0ea-69b6-83d4-1ff0-d1a2f559daf7.png)

こう書いてあります。
これの「x64 マシン用　WSL2 Linux カーネル更新プログラムパッケージ」と書いてあるリンクを押下してください。
ダウンロードが完了したら、ダウンロードしたプログラムを開くと更新プログラムが走ります。

### 5.Windowsの機能の有効化

スタートメニューで「Windowsの機能の有効化または無効化」と検索してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1243082/cd21d6d0-53a4-4441-1845-440b23913bc7.png)

クリックした後、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1243082/f36a81e2-3a50-636c-639d-4b6c6e51e83b.png)

画面の「Linux用Windowsサブシステム」にチェックボックスを入れてください。その後、再起動します

### 6.Ubuntuを立ち上げる

手順3でインストールしたUbuntuを開いてください。エラー無く立ち上がるはずです
Gradleの`-m`、`--dry-run`オプションでタスクの実行計画を確認する

## はじめに

- 既存のGradleのビルドパイプライン内で`publishAllPublicationsToMavenRepository`を実行する前に、新たに`test`タスクを追加したい要件がありました

## 結論

- `-m`または`--dry-run`オプションを付ける事で、実行されるタスクの一覧が確認可能です

> Run Gradle with all task actions disabled. Use this to show which task would have executed.

参考：[Command-Line Interface Reference - Execution options](https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_execution_options)

## 確認したこと

`publishAllPublicationsToMavenRepository`タスク単体での実行

```powershell
PS C:\Users\yoyoyo-pg\git\gradle-sample> .\gradlew publishAllPublicationsToMavenRepository --dry-run                                                        
:lib:compileJava SKIPPED
:lib:processResources SKIPPED
:lib:classes SKIPPED
:lib:jar SKIPPED
:lib:generateMetadataFileForMavenPublication SKIPPED
:lib:generatePomFileForMavenPublication SKIPPED
:lib:publishMavenPublicationToMavenRepository SKIPPED
:lib:publishAllPublicationsToMavenRepository SKIPPED

BUILD SUCCESSFUL in 617ms
```

`publishAllPublicationsToMavenRepository`の前に`test`タスクを実行

```powershell
PS C:\Users\yoyoyo-pg\git\gradle-sample> .\gradlew test publishAllPublicationsToMavenRepository --dry-run
:lib:compileJava SKIPPED
:lib:processResources SKIPPED
:lib:classes SKIPPED
:lib:jar SKIPPED
:lib:compileTestJava SKIPPED
:lib:processTestResources SKIPPED
:lib:testClasses SKIPPED
:lib:test SKIPPED
:lib:generateMetadataFileForMavenPublication SKIPPED
:lib:generatePomFileForMavenPublication SKIPPED
:lib:publishMavenPublicationToMavenRepository SKIPPED
:lib:publishAllPublicationsToMavenRepository SKIPPED
```

`diff`の内容

```diff
:lib:compileJava SKIPPED
:lib:processResources SKIPPED
:lib:classes SKIPPED
:lib:jar SKIPPED
+ :lib:compileTestJava SKIPPED
+ :lib:processTestResources SKIPPED
+ :lib:testClasses SKIPPED
+ :lib:test SKIPPED
:lib:generateMetadataFileForMavenPublication SKIPPED
:lib:generatePomFileForMavenPublication SKIPPED
:lib:publishMavenPublicationToMavenRepository SKIPPED
:lib:publishAllPublicationsToMavenRepository SKIPPED
```
動画や音声におけるコーデックの表記

# はじめに

動画や音声を扱っていると、`avc1.4D401E` や `mp4a.40.2` などのコーデックを表す記述を目にします。
この投稿では RFC 6381 の枠組みと、筆者がよく扱う AVC1 (H.264) や AAC について簡単に整理します。

# RFC 6381

MP4 や MPEG2-TS のような複数のコーデックを内包するデータにおいて、 MIME Type に加えて複数のコーデックやプロファイルを表す方法が [RFC 6381](https://datatracker.ietf.org/doc/html/rfc6381) で規定されています。

コーデックは BNF （バッカスナウア記法）で次のように書かれています。（AVC1 と AAC の該当箇所を抜粋）

```
id-simple   :=/ id-iso
id-encoded  :=/ id-iso
id-iso      := iso-gen / iso-mpega / iso-mpegv / iso-avc
iso-mpega   := mp4a "." oti [ "." aud-oti ]
iso-avc     := avc1  / avc2 / svc1 / mvc1 / mvc2 [ "." avcoti  ]
mp4a        := %x6d.70.34.61 ; 'mp4a'
oti         := 2(DIGIT / "A" / "B" / "C" / "D" / "E" / "F")
            ; leading "0x" omitted
avc1        := %x61.76.63.31 ; 'avc1'
avcoti      := 6(DIGIT / "A" / "B" / "C" / "D" / "E" / "F")
            ; leading "0x" omitted
aud-oti     := 1*DIGIT
```

`avc1` や `mp4a` の後にはピリオドで区切られて OTI (Object Type Indication) が続きます。
AVC1 なら `avc1.` に続いて 16 進 6 桁で Profile と Level が書かれます。
MPEG-4 Audio なら `aac.` に続いて `oti` と `aud-oti` が続きます。
OTI の具体的な値については後述します。

RFC 6381 にはコーデックに加えてプロファイルについても書かれています。プロファイルというのは `isom` や `mp41` などのことです。 MP4 のブランドに相当するものだと思いますが、筆者はまだあまり詳しくないので機会があれば改めて書きます。

# OTI に入る値

OTI に入る値は例えば [Codecs in common media types - Web media technologies | MDN](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/codecs_parameter) の説明が参考になります。
ここでは私がよく扱う AVC1 と AAC について簡潔にまとめます。

## AVC1 (H.264)

極めてよく使われている動画コーデックである AVC1 は MPEG-4 AVC （簡易的には単に「AVC」）あるいは H.264 と表記される場合がありますが、複数の標準化団体による呼び方の都合によるもので技術的には同じものを指しています。
RFC 6381 では `avc1` という表記を用いるので、ここでは AVC1 と呼ぶことにします。

OTI の最初の 2 桁はプロファイルを表し、よく見かけるものだと

- 42 - Baseline Profile
- 4D - Main Profile
- 64 - High Profile

があります。

中央の 2 桁は互換性のあるプロファイルを表し、上位ビットから順に Baseline, Main, Extended Profile を指しています。
例えば `C0 (= 80 | 40)`  なら Baseline + Main となります。
Main Profile であれば 通常は `avc1.4D40xx`  になります。
Baseline Profile の場合に `avc1.42C0xx` は Constrained Baseline と呼ばれるものを指し、それ以外の場合は `avc1.42E0xx` となります。

最後の 2 桁が Level を表しています。
例えば `1F` なら 10 進に変換すると `31` となり、間にピリオドを打った `3.1` が H.264 で定義されている  Level になります。

例えば `avc1.42C00D` の場合、

- Profile - Constrained Baseline
- Profile Compatibility - Baseline + Main
- Level - 1.3

を表します。

なお、 16 進数に使うアルファベットが小文字で書かれているケースもしばしば見かけます。それらを読み取るプログラムを書く場合、各言語の標準ライブラリを使えば通常は問題無いと思います。

## MPEG-4 AAC

MPEG-4 AAC なら OTI は 40 （16進数）です。
AC-LC なら `mp4a.40.2` , HE-AAC なら `mp4a.40.5` や `mp4a.40.29` などとなります。

# MP4 について

筆者は MP4 のボックスから値を取り出して RFC 6381 を書き出す実装をしたことがあるので、表記そのものの話とは違いますが最後に少し触れておきます。

AVC1 については ISO/IEC 14496-15 の中で AVCDecoderConfigurationRecord が定義されています。その要素のうち以下の 3 つをこの順序通りに 16 進数で記述すれば OTI になります。

```
unsigned int(8) AVCProfileIndication;
unsigned int(8) profile_compatibility;
unsigned int(8) AVCLevelIndication;
```

これは例えば avcC ボックスの中から取り出すことができます。

オーディオについては esds ボックス (ISO/IEC 14496-14 ) の値でコーデックを判別できます。
esds ボックスの中から DecoderConfigDescriptor (ISO/IEC 14496-1) を取り出すと objectTypeIndication があり、その値が 0x40 であれば AAC と判断できます。
さらに AAC-LC かどうかは DecoderSpecificInfo を取り出すことでわかります。

この辺りの実装は [abema/go-mp4](https://github.com/abema/go-mp4/blob/v1.2.0/probe.go) で公開しています。
ポッドキャストの文字起こし #Whisper


ポッドキャストを最近はじめました。
ウェブマーケターとしては**ポッドキャストの集客のしづらさ**は問題に映ります。
これをカバーするために、字幕（トランスクリプト／文字書き起こし）作成の作業をプログラマーらしく自動化したいと考えることは、不自然なことではないでしょう。

## Whisperで音声認識（Speech To Text）

ChatGPTでおなじみのOpenAIが作っている[Whisper](https://github.com/openai/whisper)を使います。

録音された音声ファイルを指定して実行すると、以下のように出力されます。

```
$ whisper 240320.mp3 --language Japanese
[00:00.000 --> 00:08.000] すごいレス付いてるよね、これ。259レスって書いてあるよ。
[00:08.000 --> 00:15.000] あの、いや、これ。
[00:16.000 --> 00:26.000] 罰一かどうか、結婚して離婚しましたっていうものかどうかと、同じか同義かどうかっていうのは分かんないけど、
[00:26.000 --> 00:33.000] そこについて俺が同意するとか確かにそう思うよとかっていうのは、別に結婚したとか罰一かとかって、
[00:33.000 --> 00:43.000] それだってさ罰一だろうがなんだろうが、期間による、深さとか深度、期間によると思うし、10年ぐらいいました。
[00:44.000 --> 00:51.000] 10年ぐらいいましたなのか、少ないのか、短いのか、全然違うし。
[00:51.000 --> 00:59.000] 罰一かどうかっていうのは、俺は別に結婚っていう枠組みについては、なんかこだわりがないから、
[00:59.000 --> 01:12.000] 結婚罰一かどうかっていうのは、おいとくとしても、同性の経験が彼女の方、女の子の方にありましたっていう風になると
```

処理が完了するとファイルに出力されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739217/f15fe3e2-b56d-ac88-785e-503e0114cd19.png)

見ると分かりますが、まあ完全ではありません。誤認識、誤植がある程度目立ちます。
例えばバツイチと発言しているところが"罰一"となっていたり、同棲と言っているところが"同性"になっていたりしていました。

これらは必要に応じて、手動で直す必要があります。VSCode等テキストエディタ上であれば、文字の置換や、同一文字列の選択を行うショートカットキーの利用等により素早く処理することができるかと思います。

実際にアンカー（Spotify for Podcasters）に投稿した際には"バツイチ"とかを修正しています ▼

## 環境構築

Githubページを見ればすぐ分かることですが、一応書いておきます。

Whisperは2年前頃から環境構築してありましたが、バージョンも変わってるだろうしということで再度入れ直しました。

僕の場合はpython 3.9.9でインストールしました。

```
$ PYENV_VERSION=3.9.9 python -m virtualenv venv

$ . venv/bin/activate

$ pip install -U openai-whisper==20231117
// or: pip install -U openai-whisper

// 任意。
$ echo $?
0

// 任意。
$ pip freeze > pip_freeze.txt

$ type whisper
whisper is hashed (/home/user/pg/whisper_2403_dev/venv/bin/whisper)

// e.g. whisper filename.mp3 --language Japanese
```

なお、Google ColaboratoryやHugging Faceでも使えるようです。お勧めはできませんが、気軽に試すには一つの方法としてよいと思います。

また、渡す音声データは無論、音がよいに越したことはありません。こういった場合のノイズ除去はFL StudioからEdisonプラグインのdenoiseで行うようにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3739217/e40b785d-ea36-6fbb-e070-9774a96e478e.png)

ポッドキャストのレコーディングはまだ慣れていなく手探りですが、徐々に上手くできるようになっていければいいなあと思っています。
コマンドプロンプト $ / # / %

# はじめに
コマンドプロンプト（ターミナルエミュレータ）の表記で、`$`が使われてるのをよく見ます。

```
$ touch sample.txt
```

実は、以下のような表記（`#` / `%`）も使用されるようです。

```
# touch sample.txt
```

```
% touch sample.txt
```

この記号の違いはなんでしょうか？
# そもそも、コマンドプロンプトとは？

ChatGPTによると、「OSがユーザーの入力を待っている状態」を指すようです。
なるほど、確かにそうかも。「状態」というより「ツール」「ソフトウェア」というイメージも強いですが。

> コマンドプロンプトの「プロンプト」とは、コンピュータのオペレーティングシステムがユーザーの入力を待っている状態を指します。具体的には、テキストベースのインターフェイスで、ユーザーがコマンド（命令）を入力する場所のことを言います。プロンプトは通常、コマンドラインインターフェイス（CLI）における入力行の先頭に表示される文字や記号のことで、ユーザーが次に何か操作を行うことができる「準備ができている」というシグナルを表しています。

> たとえば、Windowsのコマンドプロンプトでは、`C:\Users\YourName>`のように現在のディレクトリのパスが表示され、ここにコマンドを入力することで、ファイル操作やシステム設定の変更など様々な操作を行うことができます。この表示がプロンプトであり、コンピュータがユーザーの入力を促している状態を示しています。

英語の原義としてはどうでしょうか。
ChatGPTとMac備え付け辞書で確認してみましょう。
両者ともに「入力を促す・待つ」という点で同じですね。

ChatGPT
> プロンプト（prompt）という英語の原義は、「迅速な」や「即座の」を意味し、さらに「促す」や「刺激する」という行動を促す意味合いも持ちます。この言葉は、人が行動を起こすように促したり、何かをするための即刻の刺激や動機づけを提供することを表します。コンピュータのコンテキストで使用される場合、ユーザーにアクションを促すためのシグナルやメッセージという意味で使われています。つまり、コマンドプロンプトでの「プロンプト」は、ユーザーにコマンドの入力を促す、そのための待機状態を示しているという意味で使用されています。

Mac備え付け辞書
![スクリーンショット 2024-03-20 18.03.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457770/381a3864-3e6e-0645-2820-c1e2a780f140.png)

# 本題：`$` / `#` / `%` の違い

これらの違いは、
- ユーザー権限の違い
- コマンドシェルの違い
を表しています。

## `$` vs `#`

これはユーザー権限の違いです。
`$` は非特権ユーザー（標準ユーザー）のプロンプトを示します。
`#` は特権ユーザー（スーパーユーザー・root）のプロンプトを示します。

例えば、`docker compose exec web bash`と実行すると、コマンドプロンプトに`#`と表示されます。
これはスーパーユーザー権限で実行することを示しているようです（ChatGPTによると）。

## `$` vs `%`

コマンドシェルの違いです。
一般的には`$`を使用しますが、一部コマンドシェル（現在macで使用されている`zsh`など）では`%`を使用します。

## `#`の注意

`#`は、「コメントアウト」も表します。
ユーザーが`#`を使うと「コメントアウト」
コマンドプロンプトが表示した場合「スーパーユーザー」です。

# おわりに

`$` に特に意味はないと思ってましたが、ちゃんと意味があったんですね。
身近なものにも知らないことが溢れていて楽しいです。

さて、次は何を書こうかしら・・・

# 参考

[エンジニアなら知っておきたいmacOS環境のキホン コマンド・Docker・サーバなどをイチから解説](https://www.amazon.co.jp/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AA%E3%82%89%E7%9F%A5%E3%81%A3%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84macOS%E7%92%B0%E5%A2%83%E3%81%AE%E3%82%AD%E3%83%9B%E3%83%B3-%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%83%BBDocker%E3%83%BB%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AA%E3%81%A9%E3%82%92%E3%82%A4%E3%83%81%E3%81%8B%E3%82%89%E8%A7%A3%E8%AA%AC-%E5%A4%A7%E6%B4%A5-%E7%9C%9F/dp/4295015032)
DatabricksのSQLノートブックにおけるSQLウェアハウスの利用

こちらのアップデートでGA(正式提供)になっています。

https://docs.databricks.com/en/release-notes/product/2024/march.html#sql-warehouses-for-notebooks-is-ga

> ノートブック向けSQLウェアハウスがGAになりノートブックのリッチでコラボレーティブな開発環境でのSQLワークロードで、完全マネージド、即座に利用できるスケーラブルな計算資源を利用できるようになります。詳細は[SQLウェアハウスによるノートブックの活用](https://docs.databricks.com/ja/notebooks/notebook-ui.html#use-a-notebook-with-a-sql-warehouse)をご覧ください。

これまでは、ノートブックでの計算資源はクラスターを使う必要がありましたが、SQLノートブックであればSQLウェアハウスを利用できます。そして、SQLウェアハウスは[サーバレス](https://qiita.com/taka_yayoi/items/1f314088d8917387277d)になっていますので、起動時間を待つことなしにすぐにSQLクエリーを実行できます。

SQLのノートブックを作成します。
![Screenshot 2024-03-20 at 19.45.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/066b1bef-8802-1924-268e-1a0784997199.png)

クラスターセレクターでSQLウェアハウスを選択します。**SQL**のマークがついているのがSQLウェアハウスです。
![Screenshot 2024-03-20 at 19.45.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/0aca7638-0149-e696-4799-c71d5c089f18.png)

SQLだけでなくマークダウンのセルも問題なく記述できます。
![Screenshot 2024-03-20 at 19.51.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/fbff2452-2b50-3f6a-3335-1748e7da9c6b.png)

```sql
SELECT * FROM takaakiyayoi_catalog.japan_covid_analysis.covid_cases;
```

即座に結果が表示されます。
![Screenshot 2024-03-20 at 19.51.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/14608867-caed-adab-422d-6a7e0a8a7cdf.png)

SQLウェアハウスで実行したクエリーの詳細は、サイドメニューの**クエリー履歴**からアクセスできます。
![Screenshot 2024-03-20 at 19.52.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/267d0d55-985c-60a3-a463-b9874ed40819.png)

是非ご活用ください！

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
Anakin.aiのRATIO LLMs使ってみた

LLMを一ヶ所で比較したり、同時に使うことができる **「RATIO LLMs」** がAnakin.ai上にローンチされたので、さっそく使ってみました。

# RATIO LLMsとは
1つのプロンプトに対して、5つの生成AIが同時に回答を返してくれる生成AI比較アプリです。

**【採用モデル（2024/3/20時点）】**
- ChatGPT4
- Claude3 Opus
- Google PaLM2
- Mistral Large
- Perplexity

詳細は以下ポストから。

https://twitter.com/shota7180/status/1770289551246045470

# Anakin.aiとは
## Anakin.aiとは
Anakin.aiとはノーコードでAIアプリを簡単に作成できるプラットフォームです。

ChatGPTやGemini、Stable Diffusion、最近話題のclaudeなど有名どころのAIアプリも搭載されているのが特徴です。

様々なAIアプリケーションが1つのプラットフォーム上に多数内臓されているので、誰でも適切なAIアプリを使用することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3663858/288e2421-eb5c-8037-2cc7-1a87adcfb9b4.png)

## 料金プラン
料金プランは以下の通り、無料プランからプレミアムプランまで合わせて4つあります。

無料プランでも毎日AIを使うためのクレジットが付与されるので、少し試すだけであれば無料プランでも良いかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3663858/8f3df2db-517c-ba65-006b-d85d146b9bf4.png)

# RATIO LLMsの使い方
## Anakin.aiのログイン

今回発表されたRATIO LLMsはこのAnakin.aiプラットフォーム上で動作させるため、まずは、Anakin AIの公式サイトへアクセスします。

Anakin.aiの公式URL：https://anakin.ai/

トップページ中央にある「Launch App」をボタンをクリックします。

ログイン画面が出たら、メールアドレスを入力しログインしてください。※アカウント作成のみであれば料金は発生しません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3663858/8ab63637-0584-4430-1ae0-b09145adc8da.png)

## RATIO LLMsの起動

ログインが完了したら、アプリストアからRATIO LLMsを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3663858/1e7dbdb9-fe0f-671c-375c-0affb4c49f65.png)

アプリの詳細が表示されるので、今すぐ使用を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3663858/4f4d9df0-c6d9-6b7c-e084-c73909c15135.png)

## RATIO LLMsを使う
下記画面になったら利用開始。

Inputに聞きたいことを入力をすると5つの生成AIが出力画面に回答を返してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3663858/261cb4a0-513e-e898-3c56-633d63924df9.png)

さっそくInputに質問を書いてみる。

今回は「生成AIについて教えてください。」と入力してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3663858/9f5accac-c63c-2231-72c3-896da99fe45b.png)

大体50秒ほどですべてのAIが回答を作成してくれました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3663858/27a70797-74e1-b781-c397-ba3058c1f945.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3663858/a02ec407-f3b1-29bc-c0b9-96f86cb94245.png)

ログを選択すると、各AIの回答とその回答にかかった時間が表示されます。

**※ただ、どの回答がどのAIなのか表示されておらず、少し見づらい仕様になっていました、、、**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3663858/c86ad409-b5ea-c92f-75a3-739bcd339e7f.png)

クレジット消費ですが、今回のプロンプトで、約80クレジット程消費しました。
短いプロンプトだったのですが、意外と消費が多くて驚きました。1日3-4個の会話が限度でしょうか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3663858/fe2dfda5-76ae-648d-b07e-550be7608a16.png)

Perplexityに少しバグがみられることも、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3663858/58cb18f4-3498-502e-4382-7cb45a746938.png)

# まとめ
今回はリリース直後のRATIO LLMsを使用してみました。

とても使いやすく、**LLMを一ヶ所で比較したり、同時に使いたいとき**にかなり便利になるツールです。

今後LLMの追加などの機能拡張にも期待ですね。
余らせたラズパイの使い道

# about



みんなだいすきRaspberry Pi(以下ラズパイ)、せっかく買ったのに、仮想化基盤を家に用意して不要になったり、電子工作に飽きてもう使わなくなりがち…
買ったときは数千円〜1万円以上出したのにね…

そんな可哀想なラズパイ、家に転がってませんか？もったいなくないですか？
僕も
- ラズパイ初代
- ラズパイB+ **×2**(マジでいらない…)
- ラズパイ4B(2GB)
- ラズパイ4B(4GB)

が家に転がってます。

そこで、使い道を考えてみました。というか実際に運用しているものもあります。

# 使い道

## Magic Mirror2

Magic Mirror2をご存知でしょうか？
なんかいい感じに、「鏡よ鏡、世界で一番美しいのは誰？」的なのをすることができます。

実際にどういった使い方を想定しているかは、「スマートミラー」を検索してみればいいかな〜と。(適当でごめんなさい)

直近の自分のタスクとかをいい感じに表示したりできて結構便利です。

https://x.com/MiutakuTech/status/1770390086670237813?s=20 

動作環境はラズパイ4B(2GB)ですが、おそらくラズパイ2とかでもいけます。
ちなみに、茨の道感すごいですが、ラズパイB+でも動きそうです。ブラウザアプリケーションがchromiumを使えないだけで、軽量なmidoriとかなら行けそうな気がしてます。
さらにちなみに(?)、ラズパイB+だと、swapを2GB追加して、オーバークロックで1GHzにした状態で、MagicMirror2をセットアップするとエラーが出るものの、セットアップはできました。使い物にはなりません。。
```
(node:1716) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 close listeners added to [TLSSocket]. Use emitter.setMaxListeners() to increase limit
```

## armな仮想化基盤

ProxmoxVE、実はラズパイで動きます！！！！(多分aarch64だけ)
非公式なんですけどね。[Pimox](https://github.com/pimox/pimox7) っていうのを作ってくれている有志がいて、そのおかげで使えます。
ESXiが無償版の提供をやめるってなって話題になった(?)仮想化基盤アプリケーションですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271301/c509dd5c-347a-dcea-30af-d51d4b8076e3.png)

が…正直、今だとCockpitのほうがいいかもですね。まずCPUアーキテクチャの制限や動作するLinuxOSの制限もほぼないし、cockpit-podmanでコンテナ管理できちゃうし、cockpit-machinesで仮想マシンも管理できちゃいます。
しかも、PVEと違って、**公式サポート**されてますし。ここすごい嬉しいポイント。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271301/ea4f9373-f7f3-16c0-9834-13d4b350466c.png)

うちだと、PVEはRPi4B(4GB)で、CockpitはRPi4B(2GB)で動かしてます。
ゆくゆくはこれにすべて置き換えて遊ぶ予定だったりします。

## センサーbot

AliExpressとかでよくセンサーが色々売ってますよね。CO2取れるやつとかいろいろ。
安くセンサを仕入れたら、物によっては、市販品より安くいろいろ作れるかもしれないですよ〜

今、在宅勤務してるよーって人とか、会社と違って、労働環境をちゃんと整備できてないことがしばしば。
空調が適切に効いてないー、とか、CO2の濃度が高いー、とか。
そういうのを、アラートを自分に飛ばすbotとして使うの結構良くないですか？？？？？
[WARNING!]とか、[CRITICAL!]とかで飛んできたらドキッとしますよね。そんな感じで。

## 踏み台

SSHとか…なんか踏み台サーバ的なアレ…

ラズパイ初代をこれに使ってます…(これくらいしか使い道がなかった…)

## 監視サーバ

多分grafana/prometheusとかは非力なラズパイだと動かないと思いますが、Pi3以降とかならそれなりに使える…かも？

## VPNサーバ

SoftEther VPNを動かすサーバとして使うのありです。
ただし、マシンスペック的には、非常用のVPNとかの用途でしか使えないと思います。
というか、VPN使うくらいならゼロトラスト化したほうがいいです。Cloudflare Tunnelとか使って。
うちはCloudflare Tunnelですべてゼロトラスト化してますし、一部どうしてもゼロトラスト化できないものはTailscaleを使っています。

## Tailscale relay node

https://tailscale.com/kb/1019/subnets

Tailscaleという、VPNを利用したメッシュネットワークを提供するサービスがあります。
無料で20台までマシンを追加できます。
家のサーバが多くなりすぎて20台を超える人は、リレーノードとして使うのがいいかなーと。
詳しくは↑のドキュメントを読んでいただきたいのですが、以下のようにしてやれば、tailscaleのメッシュネットワークから、自宅のLANにアクセスができるようになります。
```
sudo tailscale up --advertise-routes=192.168.0.0/24,192.168.1.0/24
```
これ、非常用のVPN程度にする程度でトラフィックあまり流さないなら、大してマシンリソース食わないので、ラズパイ初代でも全然動きます。
公式ドキュメントにも書いてますが、2台以上のラズパイをリレーノードとしてやっても問題ないっぽいので、それによって高可用性を担保するってのもいいですね。余ってるラズパイをいい感じに消費できますね！
私は、非常用で家に接続したいときのため、Tailscaleのリレーノードを仮想化基盤上で立てていますが、ラズパイ初代を2台使うのいいかも…ってなってます(笑)

→ 2024.08.01 追記
実際にtailscaleのsubnetルーターを、RPi B+ 2台で動かしました。
OCIに立てているHomeAssistantサーバ <-> 家のIoT機器の通信と、
たまに外からどうしてもLANのIPで接続したい時に使ってます。非常に快適に動いています。

# あとがき

お酒飲みながら色々書いてたのでなんかいろいろめちゃくちゃなこと書いてる気もしないでもないですが…
他にもこんな使い方あるよ！とかあれば、コメントとかでぜひ教えて下さい！