OmniAICreator/Qiita-1.07M huggingface dataset:
[LSI] LSIと周辺知識

# 一覧
|用語|詳細|
|:--|:--|
|LSI|Large Scale Integration<br>多数の電子部品を集積した集積回路|
||``集積``: トランジスタ、加算器など<br>``利用``: CPU、メモリ、インターフェースチップなど、特定機能を持つ集積回路(FPGA、ASSP、ASIC)|
|FPGA|Field-Programmable Gate Array<br>ユーザーがプログラム可能な集積回路|
||``集積``: 多数の論理ゲートやフリップフロップ、I/Oブロックなど<br>``利用``: 開発前の集積回路の機能検証、特定用途向けのカスタムハードウェア<br>``設計``: 変更可能|
|ASSP|Application Specific Standard Product<br>特定の用途やアプリケーション向けに設計された標準製品の集積回路|
||``集積``: <br>``利用``: オーディオ・ビデオデバイス、通信、車載システムなど<br>``設計``: 固定<br>|
|ASIC|Application Specific Integrated Circuit<br>特定のアプリケーション向けにカスタム設計された集積回路|
||``集積``: <br>``利用``: 家電製品、通信機器、自動車のECU（電子制御ユニット）、医療機器、データセンターなど<br>``設計``: 変更可能（一度変更した後、変更不可）<br>|
|SoC|System on Chip<br>システム全体の機能を1つのチップに統合したもの|
||``集積``: CPU、GPU、メモリ、インターフェースチップ、（LSI、FPGA)など<br>``利用``: スマートフォンやIoTデバイスなど、小型・省電力かつ高性能な機器に最適化して利用|




# 

# 参考リンク
- [令和4春20_FPGA](https://www.ap-siken.com/kakomon/04_haru/q20.html)
- [令和5秋20_FPGA](https://www.ap-siken.com/kakomon/04_haru/q20.html)
- [令和3春20_SoC](https://www.ap-siken.com/kakomon/27_haru/q20.html)
同期と非同期の違いを理解する（同期処理とか非同期コミュニケーションとか）


# 同期と非同期
A と B でやりとりする場合を考える。

処理の場合、A が B を呼び出す形。A が B に仕事をお願いして、B が処理して、その結果を A に返す。

- 1: A → B
- 2: B 側で処理
- 3: A ← B

コミュニケーションの場合、A と B がやりとりをする。

いずれにせよ、A から B に、または B から A に何らかの情報を渡していることになる。情報をやりとりしている。

## 同期
同期とは **ターン制** のこと。

A から B に情報を渡したら、A は **B から返事が返ってくるまで待つ**。

一往復の場合はこれで終わりだが、n 往復する場合、交互に待つことになる。

- 1: A → B
- 2: B 側で処理（この間、Aは待っている）
- 3: A ← B
- 4: A 側で処理（この間、Bは待っている）
- ……

まるでポケモンやカードゲームで交互にターンが来ているかのよう。

## 非同期
非同期とは **渡したらおしまい** のこと。

A から B に情報を渡した後、A は **B の返事を待たない**。

ただしこれだけだとやりとりできないので、A は受信箱をつくっておいて、「なあ B さん、返事があったらここに入れといてくれよ」とする。適当なタイミングで受信箱を見て、もし B からの返事があったら対応する。なければ対応しない。あった場合も、別にすぐに対応する必要はない。

ちなみに、A についても、B に直接渡しているというよりは、**B の受信箱に情報を入れている** 形となる。

# 同期と非同期の使い分けは？
どちらもメリデメがある。

## 同期のメリデメ
同期のメリット:

- 早いこと
    - 直接捕まえて、待たせて、やりとりをさせるのだから一番早い
- 信頼できること
    - 互いがお互いを独占しており、相手のことも、やりとりの内容もわかっている
- わかりやすいこと
    - 人間のコミュニケーションが同期的なので、わかりやすい

同期のデメリット:

- 拘束されること
    - やりとりが終わるまではずっと拘束される（ブロッキング）
    - B が遅くても待たないといけないし、途中でミスったら最初からやり直さないといけない
        - 途中で保存とかしておけばそこからやり直せるけど

## 非同期のメリデメ
非同期のメリット:

- 待たなくてもいいこと
    - 相手の受信箱に入れておけばいいだけ
- 情報を広くやりとりできること
    - 受信箱を見れる人は誰でも見れる
    - 誰でも受信箱に情報を入れられる
    - たとえば、1人が1000人から情報を受け付けることもできる（処理じゃなくて受け付ける段階）

非同期のデメリット:

- 早くないこと
    - 少なくとも同期よりは遅くなる
- 信頼しづらいこと
    - 確実に見てもらえたか、処理してもらえたかがわからない
- 続けるのがちょっと難しいこと
    - 同期だとお互いに順にやりとりするだけで進めていける
    - でも非同期だと、適当に受信箱に放り投げるだけでは成立しづらい
    - どの受信箱に何を置いて、こっちの受信箱はこういう情報を入れて……みたいな取り決めや流れを工夫しないといけない

# 元は同期だけでしょ？なんで非同期が出てきた？
Ans: 同期のデメリットである「拘束される」がキツイから。

## プログラムやシステムの話
ずっと待たされると遅くてストレスである。融通が利かない。

コンピュータは基本的に処理が早いが、それでも処理する量や性能によって遅くなることがある。また、途中でエラーが出たり、フリーズして永遠に応答しなくなったり、ネットワーク回線が途中で切れてそもそも通信できなくなったり、単純にプログラム A が相手してるプログラム B が異常終了していたり、などトラブルは起こる。その度にやり直し？冗談じゃない。特に昨今はクラウドで、色んなサービスとやりとりするようなシステムも多い感じで「本質的に複雑」、ゆえに「それなりにトラブルは起きる」。同期だけだとキツすぎ。神頼みになっちゃうよ。

もっと融通を利かせるための仕組みを偉い人が？考えて、非同期的なやり方が生まれた。すでに述べたとおり、非同期で上手くやるためには色々工夫しないといけないが、逆を言えば工夫さえできれば成立できる。成立した。工夫は結構難しいし、使い所も決して万能ではないが、ともかく拘束から解放されたのだ。

## 次にコミュニケーションの話
この考え方はコミュニケーションにも応用できる。

コミュニケーションは従来、ほぼ対面で口頭で喋るものだった。これは同期的と言えるが、時間や場所を拘束するので融通が利かない。

そうではなくて、情報を残し合ってやりとりできれば、同期的に待たされずに済む。元々手紙やメールなど、改めて言うまでもないほど当たり前にあったが、まだまだ実用的ではなかった。たとえば手紙やメールだけで仕事を完結させられるか、というと厳しい。

それが技術の発展により、比較的実現しやすくなった。特に Slack や Teams などビジネスチャットの存在がわかりやすい。単純に時系列的にメッセージを流すことしかできなかったチャットという世界に、ワークスペースやチャンネルやスレッドという分類を設けたことで、ビジネスで使える代物になった。まだまだこれだけですべてのコミュニケーションをまかなえるほどではないが、だいぶ融通が利くようになった。

また、非同期とは情報を残しておくことも意味するので、皆が読める場所で残せば、皆に情報を見てもらえる。情報共有や透明性の観点でも優れている。

※ちなみにリモートであっても、実態としてはリモート会議が多いと思う。これはリモートで同期的にコミュニケーションしている。まだまだ人類のコミュニケーションは同期的だろう。ゆえに拘束される。
HTTP,URI,HTMLとは

# WEBを支える基本的な技術
>Webを支える最も基本的な技術は、`HTTP`(Hypertext Transfer Protocl)と`URI`(Uniform Resource Identifer),そして`HTML`です。
URIを使えば、ショッピングサイトの商品でも学術論文でも動画サイトに投稿された映像でも、`世界中のあらゆる情報を指し示せます`。HTMLは、それらの`情報を表現する文書フォーマット`です。そしてHTTPというプロトコルを使って、それらの`情報を取得したり発注`したりします。
HTTP,URI,HTMLはシンプルな技術です。
...
HTTP、URI,HTMLに支えられたWebは、情報システムとして見ると`ハイパーメディアシステム`(hypermedia System)と`分散システム`(Distributed System)の２つの側面を持っています。

# ハイパーメディアシステムとは
>テキストや画像、音声、映像など様々なメディアを`ハイパーリンク(Hyper Link)で結び付けて構成したシステム`です。

理解できなかったので書かなかったのですがハイパーメディアは非線形的にユーザが自分でリンクを選択して情報を取得するらしいです。何がどう非線形なのかはいつか理解できると思います。

### ハイパーリンクあるはリンク
>ハイパーメディアにおいて`情報同士を結びつける機構`のことです。リンクによって、ユーザはある情報から`別の情報へと自由に参照`できるようになります。
webはハイパーメディアの一例です。HTMLで記述したwebページには、他のwebページや埋め込まれた画像、映像へのリンクが含まれています。ユーザは`ブラウザを使って自由にそれらをたどれます`。

# 分散システムとは
>複数のコンピュータやプログラムをネットワーク上に分散して配置し、一台のコンピュータで実行するよりも効率的に処理できるようにしたシステムです。
### 実現できること
>分散システムでは、`複数のコンピュータ上に存在するデータを一元的に扱ったり`、`一台のコンピュータでは扱いきれない膨大な情報を操作`したりできます。分散システムを用いると、単一のコンピュータからなる`集中システムでは難しい機能や性能を実現`できます。

一元的の言葉を調べても理解できなかったけどとりあえず複数のサーバの情報を取り扱うことができるのか

# webとは
### webは分散システム
>webとは`世界中に配置されたサーバに世界中のブラウザがアクセスする分散システム`です。

### webの特徴
過去にwebほど`大規模な分散システムは存在しません`でした。
...
`プロトコルがシンプルな点`です。プロトコルが`シンプルだからこそ、これだけの規模のシステムが実現`できているのです。

# 出典
https://gihyo.jp/book/2010/978-4-7741-4204-3

# 感想
まだまだ深掘りしないといけない。
この内容でまだ１ページ程度か
Reactとは？

### １．概要
webアプリケーション開発でReactがよく使用されているが、
・ そもそもReactってなに？
・ Reactで開発するとどんなメリットがあるの？
これらを一問一答のような形で、**まずは把握することが目的です。**
最低限、一言で説明できるようにして、詳しくは他の記事を参考にすると理解が深まると思います。
<br>
***
### ２．Reactってなに？
A. <font color="turquoise">動的なユーザインタフェースを構築するためのJavaScriptライブラリ</font>


※ユーザインタフェース：　コンピュータと人間がやり取りする際の「見た目」、「操作方法」を指す。
※ライブラリ：　プログラムにおいて、よく使われる機能や処理を集めたコードのセット。



***
### ３．Reactを使うとどんなメリットがあるの？
A. <font color="turquoise">webページの表示速度が早い</font>

ユーザの待つ時間が少なくなるので、利用するストレスが減る。
表示速度が早い理由は、再表示(レンダリング)するために必要最低限の処理しか行わないから。

※SPA(Single Page Application)や仮想DOMという設計構造やプログラミング上の概念を用いることで実現できるが、こちらは別で解説を書きたいと思います。

***

### 備考
沢山解説を読んで結果頭に残らないもはもったいないと思い、一問一答形式に書いてみました。
もう少し深い理解が必要なときは、調べて肉付けしていくと自分の知識になると思います。
まだまだ知識不足な部分があるため引き続きアップデートしていきます。
Swift, SwiftUIで「⚪︎秒後」を実現する！！

## 結論

以下を実行する！
```swift: SampleView.swift
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
    # 以下に５秒後に行いたい処理をかく。
    print("5秒経ちました")
}
```

上記では、５秒後に、「5秒経ちました」と出力されますね。

## まとめ
簡単ですね。
これ以上述べることがないので、今回はこれで終わりにします。


## 最後に
少しでも参考になれば嬉しいです。
また、個人的に手書き機能を搭載したアプリを開発したいと考えているのですが、手書き機能の実装経験のある方やおすすめの方法等あれば、教えていただきたいです！！（UIkit, SwiftUI）

最後までお読み頂きありがとうございました！！
echoコマンドでファイルの末尾に改行を入れる

# 結論
echoコマンドを使う
`echo >> {file_name}`

echoではデフォルトで改行が含まれるので、以下のように指定しなくても問題ない。
`echo -e "\n" >> {file_name}` : これだと改行が二つ入ります
`echo -n -e "\n" >> {file_name}` : -nオプションでデフォルトの改行を無効にすることもできる

# 背景
スプレッドシートからcsv形式でファイルダウンロードすると最終行に改行がついていないことに気が付く
* macOS
```
$ cat sample.csv
aaa
bbb
ccc
ddd
eee%  
```
* centOS
```
[root@hoge ~]# cat sample.csv
aaa
bbb
ccc
ddd
eee[root@hoge ~]# 
```

# 問題
ダウンロードした複数のcsvを単純に以下のようにマージしたかったのですが、末尾の改行がないと境界部分の行同士が繋がってしまう問題が起きた。
`cat b.csv >> a.csv`

### e.g.
```
[root@hoge ~]# cat a.csv
aaa
bbb
ccc
ddd
eee[root@hoge ~]# cat b.csv
fff
ggg
hhh
iii
jjj
[root@hoge ~]# cat b.csv >> a.csv
[root@hoge ~]# cat a.csv
aaa
bbb
ccc
ddd
eeefff
ggg
hhh
iii
jjj
```

### 補足
csvの行数が多いとviコマンドとかで手動で改行追加するの面倒だなと思っていたのですが、
`vi {file_name}`とかで一旦開いてそのまま編集せずに保存するだけでも自動的に末尾の改行追加されるのですね
【無料】Blu-ray プレーヤーで再生できるディスクを Mac で作成する

動画ファイルを家庭用の Blu-ray プレーヤーで再生したいけど、ググると**怪しい有料ソフトばかり**……。本当に動くのか不安ですよね。
書き込みが行えるドライブがあれば、お好みのファイルをBlu-rayに"焼く"ことができます。 ("オーサリング"というのが正しいのでしょうか？)

家電量販店とかでのダビングサービスも調べましたが DVD もしくは、データ用の Blu-ray 作成しかなく、再生できるBD-Rは作ってくれなさそうな感じ。
「Blu-ray って作成するハードルがめっちゃ高いのでは？」と不安でしたが、この手順でなんとか成功しました。

# 環境・使ったもの
* Apple MacBook Pro (2021 / Apple M1 Pro)
  * macOS 12.2 (Monterey)
* BUFFALO BRXL-PC6VU2
  * 昔買った外付けのBlu-rayドライブです
* BD-Rメディア
  * 空のディスク
  * 片面1層 / 25 GB のもの。保険も兼ねて5枚組のものを買いました(笑)

# 手順
## 0. 準備
```bash
brew install ffmpeg
brew install cdrtools #後述の mkisofs コマンドのためにインストール
```
## 1. 映像をエンコード
Blu-rayに適したフォーマットが「H.264コーデック」「AC3オーディオ」のようでしたので、以下で変換しました。
解像度やフレームレートの変更があれば、ここでオプションの指定が必要です。

```bash
ffmpeg -i input.mov -c:v libx264 -preset slow -crf 18 -c:a ac3 -b:a 320k encoded.m2ts
```

|引数|説明|
|---|---|
|`input.mov`|自分で作成した動画ファイル|
|`encoded.m2ts`|エンコード結果 （`M2TS`: Blu-ray でも使用される高解像度ビデオフォーマットのようです) |

## 2. Blu-ray フォルダ構造の作成
`tsMuxeR`を使いました。
[CLI 版](https://github.com/abakum/tsmuxerCLI)もあるようですが、純粋にMac での使い方が分からなかったので、GUI 版を使いました。

1. [GUI版の**tsMuxeR**](https://www.videohelp.com/software/tsMuxeR)をダウンロードし、起動
2. **[`Blu-ray`] タブ**
    * `Chapters` で `No Chapters` を選択
![スクリーンショット 2024-08-19 23.51.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688698/60bc340f-9b10-c86b-ad96-6e7602bad199.png)
※ デフォルトが `Insert chapter every N minutes` となっており、[`Input`] タブで登場するコマンドらしきエリアにもそれっぽいオプションが付いてました。今回チャプターは不要なので、念のため選択しました

3. **[`Input`] タブ**
    * `Input files:` へ `encoded.m2ts` を add
    * `Output` では `Blu-ray folder`を選択し、任意の `Folder` も指定 (空のディレクトリがおすすめです)
![スクリーンショット 2024-08-19 23.49.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688698/b8fa34b5-bb67-d735-8b45-9f8c3f9243b3.png)

:::note warn
**[`Input`] タブ**の `Output` で。直接ISOが作れそうな `Blu-ray ISO`のラジオボタンもありますが、私は失敗しました。M2TS を作成する時点でのエンコード設定も異なっていたので、何が悪さをしたかは分かりませんが、後述の Burn もできませんでした。
:::

## 3. ISOファイルの作成

```bash
mkisofs -udf -o output.iso /foo/bar/baz
```
|引数|説明|
|---|---|
|`/foo/bar/baz`| Blu-ray フォルダ構造の一番上|
|`output.iso`| 作成結果 |

## 4. Blu-ray に焼く！
空のディスクを Mac にマウントさせたら、

1. `Burn` の [`Copy`] タブへ `output.iso` をドロップ
2. `Burn` をクリック

:::note info
`Kind:` が `DVD/CD master` となってて「Blu-ray じゃないじゃん！」と怖くなりますが、恐れず迷わず Burn しましょう！
> "*All I hear is, Burn!*"
― Deep Purple "Burn" https://youtu.be/ZQGstnfTmAk?t=43
:::


## 5. 完成！
Blu-ray プレーヤーで再生されるかを確認してみてください。

# その他
どうやら今回作成した Blu-ray は `BDMV` という規格だったようです。ほかに `BDAV` といった規格もあるようですが、今は `BDMV` のほうが一般的なよう。
フォルダ構造によって変化するみたいなので、今回の手順だと `tsMuxeR` が肝となっていたのかな？

# 謝辞
DVDを作成する際に以下の記事を見つけて、「コマンド ＋ Mac純正の機能のみでメディアが焼けるのか！」と感銘を受け試してみました。

https://qiita.com/abcb2/items/b6ac3e5a7aab068d1373

# 後記
今回はすべてコマンドとはいかず、GUI ソフトを2つほど使ってしまいましたが、
同じ手順をいつでもすぐ再現できるように、コマンドだけで作りたいですね。良いやり方があれば教えて下さい！
（ちょっと調べるともしかして`cdrtools`で焼くのまでいけちゃったりする？）

結婚式の披露宴で自作のプロフィールムービーを上映するために作成しました。
DVD だと大きい画面だと画質面で見劣りしてしまうので、Blu-ray で再生したかったのです。
この時代でもまだ、ディスクを式場へお預けするのが一般的なようなので（データ納品でなく）、どなたかの役に立てれば幸いです！
Linuxシェル機能

## Linuxシェルの便利な機能とショートカット
Linuxのシェルは、強力で柔軟なコマンドラインインターフェースを提供します。シェルを効率的に使用するために、いくつかの便利な機能とキーボードショートカットを紹介します。

### シェルの基本機能
1. コマンドの履歴
シェルは過去に入力したコマンドの履歴を保持しています。これにより、以前のコマンドを簡単に再実行できます。

↑（上矢印キー）: 前のコマンドを表示
↓（下矢印キー）: 次のコマンドを表示
2. コマンドの補完
コマンドを入力する際に、タブキーを使用すると自動的に補完を行います。これにより、長いファイル名やコマンドを短縮して入力できます。

Tabキー: 入力中のコマンドやファイル名を補完
3. 変数の使用
シェルでは、変数を使って値を格納し、コマンドで利用することができます。

例:
コピー
MY_VAR="Hello, World!"
echo $MY_VAR


### キーボードショートカット
以下は、Linuxシェルでよく使われるキーボードショートカットです。

* 基本的なカーソル移動
Ctrl + A: 行の先頭に移動
Ctrl + E: 行の末尾に移動
Ctrl + B: カーソルを一つ左に移動
Ctrl + F: カーソルを一つ右に移動
* テキストの編集
Ctrl + K: カーソルから行の末尾までを削除
Ctrl + U: カーソルから行の先頭までを削除
Ctrl + D: カーソルの位置にある文字を削除
Ctrl + W: カーソルの左側の単語を削除
* その他の便利なショートカット
Ctrl + L: 画面をクリア
Ctrl + C: 実行中のコマンドを中断
Ctrl + Z: 実行中のコマンドをバックグラウンドに送る
!!: 最後に実行したコマンドを再実行
!n: n番目の履歴のコマンドを実行（例: !3 は履歴の3番目のコマンドを実行）
Flutterで認証機能付きレシピ共有アプリを作っているが躓いている話

# アプリの目的
夫婦間でレシピを共有するアプリを作成したいと思ったことがきっかけです。
私の家は夫婦共働きで子供もいるので夫婦どちらか余裕がある方がごはんを作ることになっています。
レシピを共有できれば「冷蔵庫の食材は何を作るために買ったの？」ということがなくなると思ったのでアプリの作成を始めました。

![flutter3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/b5a7f1b4-8df5-fed7-8431-3ba007ae03ec.gif)
↑制作途中の為、途中でエラー画面になります。


# アプリ作成の現況
KotlinでAndroidアプリをリリースできたので、次はもう少し複雑な機能を入れたアプリを作成しようと思い着手したもの。
認証機能とDB連携に加えて、ユーザ間でレシピを共有できるようにしたいと思い、
ユーザのUIDをお互いのレコードに保持することで実装できないかと思い進めてきました。

結論としてはDB周りが複雑になりすぎて中断中です。
連携機能をつける前はレシピ登録もメニュー登録もエラーなく機能していたのですが、今ではエラーの山となってしまい頭を抱えているところです。

DB設計が甘かったというか、実装しながらDBの設計もしようと進めたのが原因だと思っています。
恐らくDBとアプリのリポジトリの間でやりとりする変数が異なっているのが問題です。
しばらく開発の時間がとれなくなるのでお蔵入りのアプリになりそうです。


# 現状の動作
以下が現状の動作になります。
認証周りは問題ありませんが、（パスワードが見えているところは課題）レシピや週のメニュー登録が機能していない状態です。
DB設計を変える前はうまくいっていたのですが、Gitのように上手くいかなくてもすぐ戻れるわけではないので安易に
DB設計を変えてはいけないことがわかりました。

今の段階でできるところは下記の機能のみになっています。

サインアップ　→　サインイン　→　メニュー表示　→　レシピ表示


# 参考にした動画
作成のために参考にしたのは下記動画になります。これを見れば１からFlutterの開発ができるようになります。
この動画ではTwitter（現X）のクローンアプリを作成することを目的としていますが、
今回はこれを応用してレシピ共有アプリを作ってみました。

https://www.youtube.com/watch?v=XnxZLhtkFeg&t=9782s

## 工夫したこと
工事中。

```dart


```


# ローカル環境はDockerで
appwriteというプラットフォームをDockerで起動してこちらにアプリを接続してローカルで開発しています。
MySQLや色々なものが入っているので、認証やDBも全てこちらで準備できます。

![flutter1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/44445f37-d810-c1d2-cc59-92cc7ae48821.gif)

# 開発プラットフォームAppwrite
Dockerで起動したappwriteはブラウザで操作します。
Auth,Databaseなど開発に必要なものが一通りそろっています。
以下はlocalhostに接続してコンソール画面を表示しているところです。

![flutter2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/fc074dd8-4dc2-2313-6f38-08793508b228.gif)
UnityからXcodeへのビルド時に発生する「Framework not found FBLPromises」エラーの解決方法

# UnityからXcodeへのビルド時に発生する「Framework not found FBLPromises」エラーの解決方法

UnityでiOS向けのアプリケーションを開発している際に、Xcodeでビルドを実行すると「Framework not found FBLPromises」というエラーが表示され、ビルドが失敗してしまうことがあります。私自身もこのエラーに直面しましたが、解決するきっかけとなったのが[こちらの記事](https://lilea.net/lab/error-framework-not-found-fblpromises/)でした。

この記事を通じて、エラーの原因と解決方法に気づき、無事に問題を解決することができたので、その体験を共有したいと思います。

## 遭遇した問題

UnityでiOS用のプロジェクトをビルドし、そのプロジェクトをXcodeで開いてビルドを試みた際、次のようなエラーメッセージが表示されました：

```
Framework not found FBLPromises
```

このエラーは特にFirebase SDKを利用したプロジェクトでよく発生するようです。原因を調べていく中で、CocoaPods関連の問題だと感じたのですが、明確な解決策に行きつくことができませんでした。

そんな中で出会ったのが、[lileaLabのこの記事](https://lilea.net/lab/error-framework-not-found-fblpromises/)です。

## 解決のきっかけ

この記事のおかげで、私がXcodeで開いていたファイルが間違っていたことに気づきました。具体的には、FirebaseやCocoaPodsを利用しているプロジェクトの場合、`.xcodeproj`ではなく、必ず`.xcworkspace`を使用してXcodeを開く必要があるという点です。

自分がエラーの原因として考えていたものとは違い、単純なファイルの選択ミスが原因だったことが判明しました。この記事を読んで初めてこの事実に気づき、正しい手順を実行することができました。

## 解決編

エラーの解決方法は非常にシンプルです。以下の手順に従って、正しいファイルを開くだけで問題が解決しました。

### 手順: 正しいファイルを開く

1. FinderでUnityのビルドフォルダを開きます。
2. `Unity-iPhone.xcodeproj`ではなく、**`Unity-iPhone.xcworkspace`**ファイルをダブルクリックして開きます。
3. その後、Xcodeでプロジェクトをビルドすると、無事にエラーが解消されました。

この記事の指摘通り、正しいファイルを開くことが重要なポイントでした。これだけで「Framework not found FBLPromises」エラーを完全に解決できました。
TDD の話

Podcastを聞いてて、これは読み返せる形に残したいと思ったので、この記事を書きました。

# ネタ元
- Qiita FM エンジニアのキャリアを深堀り
[「#18 テストの意味と TDD の役割」](https://art19.com/shows/qiitafm/episodes/6f495fb0-1131-446d-8424-011eb51e11f4)
ゲスト：t-wada さんこと 和田卓人さん

# 概要
### テストを書いているのに効果的じゃない？！
- 「なぜテストを書くのか？」「どういった書き方が効果的なのか？」が腹落ちしていない

### 変化を支えないテスト?!
- 機能追加、バグ修正、アーキテクチャを変化させるときに、既存のテストが支えにならない

### 変化を支えないテスト①
- 不安定なテスト
  - 遅い
  - よく失敗する
  - 実装は悪くない

### 変化を支えないテスト②
- 粒度の細かいユニットテスト
  - 実装の詳細に対して網羅的に書かれているが、実装に対して構造的な結合度が高い
  - 実装を変えるとしょっちゅうテストが壊れる
  - 壊れているテストを見てみると、実装の内部深くのプライベートメソッドをテストしていたり、内部変数をみている
  - 外部からのふるまいは変わらないはずなのに、内部の実装をちょっと変えただけですぐに失敗する、脆いテスト
  - 設計の可動域が狭すぎる

### テストの信頼性
- テストの成功、失敗、のどちらも信じられること
  - 下記の２択に判断が収束する
    - テストが成功したら、デプロイできる
    - テストが失敗したら、コードのどこかに原因がある

### 負のループ
- テストが不安定だからリトライしよう、みたいにテストが不安定であることが常態化している
- 実装を触るとテストがすぐ壊れるからあまり設計変更しないようにしよう、既存のテストを活かしながら開発しよう
- 新しく開発したときでも、今ある自動テストのやり方を基本的に真似してしまうので、設計変更の役に立たないびっしりと網羅的に書かれた構造的結合度の高いユニットテストが書かれていて、開発の邪魔になっているにも関わらず、新たに書かれたコードに対してもやっぱり同じような構造的結合度のテストを書いてしまう

### コードの内部品質
- あるタイミングで「上げるぞ」と決意しないと、基本的には上がらない、ジワジワ下がっていくもの

### 現場あるある
- 基本的にコードの編集は、だいたい既存のコードを真似してコピー＆ペースとしてちょっと直して、みたいな形のことが続いていく
- しかもこれがよかれと思って行われている
- 例えば本当はもうちょっと中くらいの修正をしたほうが全体として良い状態になる、重複が少ない状態になるけど、GitHubのブラウザ上でコードレビューをやりすくするためにdiffを小さくして、diffを小さくするために小さなif文の追加だけで留めるだけにしよう
- よかれと思って小さな変更を行うっていうのが、ちょっと視点を引いてみると、全体の複雑性をジワジワ上げ続けている、つまり保守性を下げ続けている
- よかれと思って、新しく追加された小さなif文にびっちりと密着したテストを書いてしまう、そうするとその設計が固着化してしまう
- 本当はもっとリファクタしてそのif文自体をなくすべきなのに、if文をなくすとテストが壊れる
- だんだんよかれと思って小さな変更をして、よかれと思ってびっしりユニットテストを書いて、その保守性よくよく一歩引いて見てみると、保守性が低い状態がずっと維持されている

### ソフトウェアはやわらかい
- ソフトウェアは変化しないといけない
- ソフトウェアは変更に対してやわらかい
- ソフトウェアエンジニアとして働くとは、常に不確実なものと戦うこと
- 「良いものを作れば形を変えなくてすむ」ではなくて、「形を変えられるものがよいもの」

### 自動テスト
- 変化を安全に素早くやるために自動テストで支える
- 形を変えられる自動テスト、実装に対して結合度が低い、インテグレーションテスト、E2Eテストだけでは変更を支えるテストにはならない
- インテグレーションテスト、E2Eテスト、ユニットテストをバランスよく配分することで、素早く自信のある変化を支える開発をすることができる

# 感想
個人的にこの回はささった。
それは、日々TDDで開発はしているものの、ユニットテストの粒度が細かすぎないか不安になるときがあるから。
ユニットテストの流派的にはロンドン派と呼ばれる方で書いているので、デトロイト派に比べたら構造的結合度の高いユニットテストになりがちなのかもしれない。
それでもできるだけ入力と出力に目を向けて、実装の中身は気にしない書き方を心がけているつもりでいる。
無理解でとりあえずTDDをしているだけでは自然とよい設計に導かれるわけもなく(多少は寄せれると思うけど)、「どういった書き方が効果的なのか？」というところは常に意識して学んでいく必要があると改めて感じさせられた。また、よい設計とは何なのかとか、どういうリファクタリングができそうかといったところの引き出しがあると、さらに自信の持てるコードが書けそうと感じた。
【超初心者向け】Chat GPTを使って30分でWebアプリ作成

プログラミング超初心者のだいきです。
2024年5月から、Chat GPTを使用して、スマートフォン向けの簡単なWebアプリを作成中で、現在5か月目です。
ようやくデプロイまで到達したため、今までの手順や失敗点を記録として残していこうと思います。
現状多くの理解不足がありますが、やさしく訂正いただけたら幸いです。
<detail>
## 1. この記事で伝えること。
Webアプリを作成しようとしている超初心者に対し、Chat GPTを使ってコード作成からローカル環境で動作できるアプリの作成までの流れを共有する。
（読むためにかかる時間：3分程度）

## 2. 作成中のWebアプリ「寿司ネタ 1000円ガチャ」
まず私が現在開発中の「寿司ネタ 1000円ガチャ」を見て、改善点を教えてください。
リンク：https://sushigacha.com/

## 3. 作成手順
### (0) 準備 (20分)
以降の手順には、VS CodeとPythonのインストールが必要のため、Chat GPTに以下質問して教えてもらってください。
<div style="text-align: center;">
  <img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887889/f53cd665-e97e-8635-676c-b9ddb5613456.png">
</div>

Pythonの場合も、同様に質問する。

### (1) Chat GPTによるコードの作成 (3分)
寿司ガチャであれば、以下のように質問してガチャ機能を作成しました。
<div style="text-align: center;">
  <img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887889/942fa43b-fe7c-93be-431a-f3d053e673c6.png">
</div>
以下のようにコードとファイル構造について、回答が返ってきました。作成されたコードをVS codeなどのエディタにコピペすることで、コードを作成していきました。
<div style="text-align: center;">
  <img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887889/edbbd35a-5303-e65a-f3c8-14bc81e13293.png">
</div>
Chat GPTの回答にファイル構造が記載されていない場合は、「どのようなファイル構造にすればいいですか。」のように質問してみると教えてくれます。

### (2) ローカル環境でコードを動かす (7分)
VS Codeにコードを入力したら、ローカル環境で動作させます。
私の場合は、(1)のChat GPT回答で「app.pyを実行してFlaskサーバーを起動します。」といった記載されていました。しかし、この程度の回答ではわからないので、追加で質問します。
<div style="text-align: center;">
  <img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887889/29bce11f-9e52-2f7d-c542-1bdd991dbe2e.png">
</div>
すると以下のように丁寧に教えてくれました。
<div style="text-align: center;">
  <img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887889/1a685bc9-00b4-c7ea-0631-6b91495d66ae.png">
</div>
ここで、「コマンドプロンプトにコマンドを入力しろ」と言われた場合、特定のPathに対して入力しなくていけない場合があるので、「どのPathに対して、コマンドを入力すればいいですか。」と追加で質問すると安全でした。

### (3) webアプリの完成 (0分)
(1)(2)の結果、このアプリが完成しました。私の場合、コードの修正も1度も必要ありませんでした。Chat GPTがとても優秀でした。
<div style="text-align: center;">
  <img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887889/a308aedd-2c69-2c10-43e9-0c8560d3b6f5.png">
</div>
あとはこれを微修正して、完成度を上げていくのみです。

## 4. エラーが出た場合
手順の中でミスを犯し、「templates」のフォルダを「templetes」と記載したため、エラーが出ました。
そこで、Chat GPTに質問し解決しました。このように、エラー画面をChat GPTに見せて質問することで、簡単に修正方法を教えてくれます。
<div style="text-align: center;">
  <img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887889/15a0c381-5b75-cca6-2936-dd7d73d54ca3.png">
</div>
<div style="text-align: center;">
  <img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3887889/7720bc28-2ba2-65d6-9d9a-31cd5914cd98.png">
</div>

## 5. まとめ
Chat GPTがとても優秀である結果、VS codeとPythonのインストールが完了していれば、コードの勉強をせずにアプリを10分で作成することができました。Chat GPTを使って作れる需要があるアプリはたくさんあると思います。初心者の同士たち一緒にがんばりましょう。よろしくお願いいたします。
Hikey960 AOSP build (2024/9/29版)

## 背景
Hikey960でのAOSPのビルド方法をすぐに忘れてしまい、毎回ビルド時にトラブってしまうのでメモ

## 手順
1. AOSPのビルド
    ```
    $ repo init -u https://android.googlesource.com/platform/manifest -b android-13.0.0_r69
    $ repo sync -j20
    $ ./device/linaro/hikey/fetch-vendor-package.sh
    $ . ./build/envsetup.sh
    $ lunch hikey960-userdebug
    $ make -j20
    ```
1. Kernelのビルド
    ビルドしたAOSPイメージをHikey960に書き込んで起動したところ以下のBinderエラーが大量に出力された。
    ```
    binder: 467:467 ioctl 40046210 7ff5391764 returned -22
    ```
    cmd:40046210(BINDER_ENABLE_ONEWAY_SPAM_DETECTION)がkernelでサポートされていないことが原因。
    AOSPドキュメント記載のkernelだとこのコマンドはサポートしていそうだったので、これをビルドする。

    ```
    $ mkdir repo-common
    $ cd repo-common
    $ repo init -u https://android.googlesource.com/kernel/manifest -b common-android12-5.4
    $ repo sync -j8 -c
    $ rm -rf out
    $ BUILD_CONFIG=common/build.config.hikey960 build/build.sh
    ```
1. ファイルのコピー
   \\$\{AOSP\_TOPDIR\}device/linaro/hikey-kernel/hikey960/5.4/ 内のオブジェクトをすべて削除し、out/android12-5.4/dist/ 内のカーネルビルドからビルド アーティファクトを \$\{AOSP\_TOPDIR\}/device/linaro/hikey-kernel/hikey960/5.4/ にコピー (AOSP doc引用)
1. DTB連結
    ```
    cat device/linaro/hikey-kernel/hikey960/5.4/Image.gz
    device/linaro/hikey-kernel/hikey960/5.4/hi3660-hikey960.dtb  >
    device/linaro/hikey-kernel/hikey960/5.4/Image.gz-dtb
    ```
1. ビルド
    ```
    $ . ./build/envsetup.sh
    $ lunch hikey960-userdebug
    $ make -j20 | tee buildlog.txt
    ```
1. 書き込み
    SW1, SW3 : ON, SW2 : OFFしてHikey960を起動した状態で以下のコマンドを入力
    ```
    $ sudo ./device/linaro/hikey/installer/hikey960/flash-all.sh
    ```
    書き込み失敗した場合はやり直すと解消する。
1. 起動
    ディスプレイをHDMI接続して起動する（未接続だと何故か正常に起動できずadbやscrcpyも使えない。
scratchで擬似的なpython

## scratchで模擬的なpythonを作っている話
https://scratch.mit.edu/projects/1074063277/
(↑)

とにかく暇だったのと、scratchで調べても改善できそうなものばかりだったのでならば自分が作ろう！と思って作り出したのですがめんどくさい事だらけでした()例えば、print(2+2*2)のようなものだと計算の順序を合わせないといけなかったり、scratchだと反応させれないキーなどなどでとても苦戦しています()
.NETのキャッチアップをするために使用したサイトの紹介

新しく参加する可能性がある案件でスキル要件に.NETのスキルを求められていましたが、全く触ったことが無かったのでまずは簡単にでもキャッチアップをしてみようと思い探したところ、個人的に勉強がしやすいなと感じたサイトを共有します。

## .NETとは？
.NETとはMicrosoft社が開発したアプリケーション開発用のクロスプラットフォームです。C#,Visual Basic,C++,F#などの複数のプログラミング言語に対応しているため、高い拡張性があります。またWindowsをインストールすればだれでも使うことができるので誰でも使うことができることも特徴です。

またC#もMicrosoftが開発したものなのでこの2つの関連性は強く、.NETの学習をする上でC#を学ぶ必要があります。

## Microsoft Learn
先ほども紹介しましたが.NETはMicrosoftが開発したもので一般的にC#が使われるとのことでラーニングコースが用意されていました。初歩的なコードの書き方やVScodeを使った環境構築から、条件分岐や繰り返しなどを使ったアプリの構築についてもコースの中に組み込まれているので初めて触る方にも優しい仕様になっています。

[Microsoft Learn](https://learn.microsoft.com/ja-jp/training/browse/?products=dotnet "C#の学習コース")

## Free Code Camp
こちらのサイトはMicrosoftアカウントでログインをすることでC#の無料の認定資格をもらえるというものです。先ほどのMicrosoft Learnと連動しており、順番にトロフィーを獲得質疑のセッションに進むという流れになっています。
無料ではありますが、認定試験を受けて資格を取得するので知識の定着や進捗度の可視化といった部分でMicrosoft Learnとの併用がおすすめです。

[Free Code Camp](https://www.freecodecamp.org/learn/)

## キャッチアップを通しての感想
コースの消化と認定試験の合格まではおそらく20～30時間くらい使ったと思います。そして学習の定着についてですが、正直まだまだC#を理解できているわけではないですし、これをやったかすぐに何か成果物を出すことができるといったものではないと感じます。（私が初心者エンジニアのためキャッチアップが遅いのかもしれませんが…）

ただC#を学ぶ入り口として、Udemyの学習コースや関連書籍の購入をするわけではなく無料で使えるサイトになっているので気楽な気持ちで触ることはできるのでその点ではおすすめかなと感じました。
最適輸送の整数解

```math
\def\middlemid{\;\middle|\;}
\def\set#1{\left\{{#1}\right\}}
\def\setin#1#2{\left\{{#1} \middlemid {#2}\right\}}
```

# 導入

　2つの整数値のベクトル$\mathbf{a} =( a\_i )\_{i} \in \mathbb{Z}\_{\geq 0}^n$, $\mathbf{b}=(b\_j)\_j\in \mathbb{Z}\_{\geq 0}^m$と，$i$と$j$の輸送コストを$c_{ij} \in \mathbb{R}$とします．このとき，**最適輸送行列は整数解として取れます**．今回は，この主張の詳細と，最適輸送問題と整数計画版の最適輸送問題との等価性，及び，証明のスケッチについて述べます．

# 最適輸送問題と主張

　まず，主張を述べる前に，最適輸送について復習します．最適輸送問題とは，次の輸送行列$\mathbf{p} = (p\_{ij})\_{ij}$を求めることです．
$$ \mathrm{argmin}\_{\mathbf{p} \in \Pi (\mathbf{a},\mathbf{b})} \sum_{ij} c_{ij} p_{ij} .$$ここで，$\Pi (\mathbf{a},\mathbf{b})$は輸送多面体，つまり，
$$ \Pi (\mathbf{a},\mathbf{b}) = \setin{ \mathbf{p} = (p\_{ij})\_{ij} \in \mathbb{R}^{nm} }{ p\_{ij} \geq 0 ; \forall j , \sum\_i p_{ij} = b\_j ; \forall i , \sum\_j p_{ij} = a\_i } . $$

主張の準備が整ったので，今回の主定理を述べます．
> 定理 1.　ベクトルを$\mathbf{a} \in \mathbb{Z}\_{\geq 0}^n$, $\mathbf{b} \in \mathbb{Z}\_{\geq 0}^m$, $\mathbf{c} = (c\_{ij})\_{ij} \in \mathbb{R}^{nm}$とします．このとき，最適輸送問題の解は$\mathbf{p} \in \mathbb{Z}^{nm}$と取れます．

# 最適輸送問題と整数計画版の最適輸送問題との等価性

整数計画版の最適輸送問題とは，
$$
    \mathrm{argmin}\_{\mathbf{p} \in \Pi\_{\mathbb{Z}} (\mathbf{a},\mathbf{b})} \sum\_{ij} c\_{ij} p\_{ij} .
$$
ここで，$\Pi_{\mathbb{Z}} (\mathbf{a},\mathbf{b})$は
$$
    \Pi_{\mathbb{Z}} (\mathbf{a},\mathbf{b}) = \setin{ \mathbf{p} = (p\_{ij})\_{ij} \in \mathbb{Z}^{nm} }{ p\_{ij} \geq 0 ; \forall j , \sum_i p\_{ij} = b_j ; \forall i , \sum\_j p\_{ij} = a\_i }
    .
$$

最適輸送問題と整数計画版の最適輸送問題は定理 1から等価であることがわかります．
> 定理 2.
> ベクトルを$\mathbf{a} \in \mathbb{Z}\_{\geq 0}^n$, $\mathbf{b} \in \mathbb{Z}\_{\geq 0}^m$, $\mathbf{c} = (c\_{ij})\_{ij} \in \mathbb{R}^{nm}$とします．このとき，
>
> $$
    \min_{\mathbf{p} \in \Pi (\mathbf{a},\mathbf{b})} \sum_{ij} c_{ij} p_{ij}
    =
    \min_{\mathbf{p} \in \Pi_{\mathbb{Z}} (\mathbf{a},\mathbf{b})} \sum_{ij} c_{ij} p_{ij} .
$$
> 

定理2は，ボールの個数のように，整数でしか輸送できない場合でも，実数の輸送と考えて解いて良いことを意味します．

# 証明のスケッチ

輸送多面体は次のように書けます：
```math
    \Pi (\mathbf{a},\mathbf{b}) = \setin{ \mathbf{p} = (p\_{ij})\_{ij} \in \mathbb{R}^{nm} }{ p_{ij} \geq 0 ; \mathbf{A} \mathbf{p} = \begin{pmatrix} \mathbf{a} \\ \mathbf{b} \end{pmatrix} }
    .
```
ここで，
```math
    \mathbf{A} = \begin{pmatrix} \mathbf{1}_n^{\top} \otimes \mathrm{Id}_m \\  \mathrm{Id}_n \otimes \mathbf{1}_m^{\top} \end{pmatrix},
```

$\mathrm{Id}\_n$はサイズが$n$の行列であり，$\mathbf{1}\_n$はサイズが$n$の$1$が並んでいるベクトルです．

天下り的ですが，完全単模行列の定義を与えます．
> 定義 3. (cf. [MS2013, p117]) (正方形とは限らない)整数行列は，任意の小行列式の値が$0,1,-1$のいずれかであるとき，完全単模(たんも)行列(totally unimodular matrix)と呼びます．

制約条件に現れる行列が完全単模行列であるとき，線形計画の制約条件の整数性が最適解に遺伝することが知られています．

> 命題 4. (cf. [MS2013, 定理 4.17]) 行列$A\in\mathbb{Z}^{nm}$は完全単模行列であり，$b \in \mathbb{Z}^n$，$c \in \mathbb{R}^m$とします．このとき，線形計画問題
>
> ```math 
> \min_{\substack{Ax = b \\ x \geq 0}} c^{\top}x 
> ```
>
> は整数解$x \in \mathbb{Z}^m$を持ちます．



実は，**行列$\mathbf{A}$は完全単模行列である**ことがわかります．これは，練習問題とします．
命題4から，定理1が従います．


# 参考文献

\[[YCor2020][YCor2020]\] YCor, integer solution of optimal transport, mathoverflow,  (2020). 

[MS2013] 室田一雄, 杉原正顕, 東京大学工学教程 基礎系 数学 線形代数II, 丸善出版,  (2013). 

[YCor2020]:https://mathoverflow.net/questions/374912/integer-solution-of-optimal-transport?newreg=5e6a2718646a4c56b602a07012d0d265
BlazorでMySQLを使用するための初期セットアップ

## 前提
Visual Studio 2022を使用。

## パッケージのインストール
「プロジェクト>NuGetパッケージの管理」を開き、以下のパッケージを検索し、インストールする。

### 共通
+ Microsoft.EntityFrameworkCore
+ Microsoft.EntityFrameworkCore.Design
+ Microsoft.EntityFrameworkCore.Tools
+ Microsoft.VisualStudio.Web.CodeGeneration

### MySQL用
+ Microsoft.EntityFrameworkCore.Relational
+ omelo.EntityFrameworkCore.MySql

## DB接続情報を追加
appsettings.json にDB接続情報を追加する。
以下はlocalhostのtestデータベースに接続をするサンプル。
~~~json
"ConnectionStrings": {
    "DefaultConnection": "server=localhost;database=test;userid=test;password=testtest"
},
~~~

## DbContextを設定
DbContextクラスを継承し、アプリケーション用のDbContextを作成する。
例として、Sampleモデルを追加してある。
モデルが増えたら、同様にここへ追加していく。
~~~c#
using Test.Models;
using Microsoft.EntityFrameworkCore;

namespace Test.Data
{
    public class AppDbContext : DbContext
    {
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

        public DbSet<Sample> Samples { get; set; }
    }
}
~~~

### Program.csを設定
Program.csにDB接続処理を追加する。

~~~c#
string? connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<AppDbContext>(options =>
        options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)));
~~~

これでそれぞれの画面において、以下のように依存性の注入をすることで、DBの操作が可能となる。
~~~c#
@inject AppDbContext _context
~~~

### マイグレーションとアップデート
モデルを作成したら、以下コマンドを「パッケージマネージャーコンソール」で実行することで、テーブルを作成することができる。
Identifyの部分は任意の文字列ならなんでもよい。
~~~ shell
Add-Migration Identify
Update-Database
~~~

モデルを変更した場合は、Identifyの部分を変更して、再度実行すると差分更新してくれる。
ただし、大幅な変更を行った場合はうまくいかないこともあるので、その場合はテーブルをすべて削除し、Migrationsフォルダの中もすべて削除してから、再度実行する。
Dockerfileでのビルド時エラー Could not read package.json: Error: ENOENT: no such file or directory の解決法

## エラーの内容

Dockerfile内で`RUN npm install`をした際にちらほら見る下記のエラーについて1つ試してほしい解決策があります。

![スクリーンショット 2024-09-10 1.21.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3829908/2dd9ccfa-1e73-d8f4-dbf9-c77002ef9440.png)

## ディレクトリ構造

その他必要なファイルもありますが、今回はエラーに関わる必要最低限のディレクトリファイルの構造のみ記述しました。

```
|---- project/
         |
         |---- docker/
         |        |---- node/
         |                |---- Dockerfile
         |
         |---- src/
         |
         |---- docker-compose.yml
         |---- package.json
         |---- package-lock.json

```

## Docker関連のファイル内容

```Dockerfile
# node/Dockerfile

FROM node:22.9

RUN apt-get update -y && \
    apt-get clean all

WORKDIR /var/www/html

# ホスト側の`project/`ディレクトリをコンテナ側の`/var/www/html`ディレクトリにコピー
COPY ../../package*.json .

# ここでエラーが出る
RUN npm install

```

```docker-compose.yml
services:
    node:
        build:
            context: ./docker/node
            dockerfile: Dockerfile
    stdin_open: true
    tty: true
    volumes:
        - .:/var/www/html
````

docker-compose.ymlファイルで`context: ./docker/node`なので、Dockerfileの`COPY ../../package*.json .`は間違っていないように見えますがイメージをビルドしてみると、

`Could not read package.json: Error: ENOENT: no such file or directory`

package.jsonが見つからないというエラーが出てしまう。

## エラーの解決法

- docker-compose.ymlの`context: ./docker/node` -> `context: .`に変更
- docker-compose.ymlの`dockerfile: Dockerfile` -> `./docker/node/Dockerfile`に変更
- node/Dockerfileの`COPY ../../package*.json .` -> `COPY ./package*.json .`に変更

上記を試してみてください。

色々調べ、WORKDIRを作成したりバインドマウントのマウント部分を変えてみたりとしてみましたが、私はこれで解決することができました。

(処理の内容的には変更前・変更後同じことだと思うのですがなぜかエラーが出る(or 解決する)。。。原因分かる方がいればコメントください)
【PHP】Carbon使用する時に気をつけること

# はじめに
Carbon使用する時に気をつけたいと思ったのでメモです。

# SubMonthsメソッド

- 1ヶ月前を取得を検索するとだいたい`subMonth()`メソッドが結果としてよく出ているが、月末になると日付がずれてしまうので注意が必要。

```
$date = new Carbon('20241031')->subMonth(1);
echo($date);
```

- 結果は`2024-10-01 00:00:00`になり、期待している`2024-09-30 00:00:00`にはならない。CarbonはDateTimeのラッパーとして、存在しない日付に対して適切に調整してくれるらしい。この場合は9月31日は存在しないので、10月1日に調整してくれているみたい。

# subMonthsNoOverflowメソッド

- 上記のようにならないために`subMonthsNoOverflow`を使用すると良いみたい。


```
$date = new Carbon('2024-10-31')->subMonthsNoOverflow(1);
echo $date;
```
- 期待通り`2024-09-30 00:00:00`が表示される。

# addMonthメソッド

- 1ヶ月後も同様になる。11月31日は存在しないので`2024-12-01 00:00:00`になる。

# addMonthsNoOverflowメソッド

- 期待通り`2024-11-30 00:00:00`が表示される。

# まとめ
月末・閏年など、このあたりテストの観点として抜けがちだったので、注意しようと改めて思いました。

# 参考
- [【PHP】Carbonで月末日付をsubMonthしたら死んだ話](https://iine-programming.hatenablog.com/entry/2021/08/03/094724)
[Java] 素数判定プログラム

# 素数とは
そもそも素数とは何なのか（ほとんどの人はわかっていると思いますが）

素数（そすう、英: prime あるいは prime number）とは、2 以上の自然数で、正の約数が 1 とその整数自身のみであるもののことである。
出典: フリー百科事典『ウィキペディア（Wikipedia）』
# Javaで素数判定プログラム書いてみた
・**自然数以外が入力されるのを防ぐ**ために、入力を求める文言を"自然数を入力してください"としました
・**1は自然数ではないので最初にif文で除外**しました

多くの素数判定プログラムでは、自然数が入力されるのが**暗黙の了解**みたいになっていますが、"自然数を入力してください: "のように指定してあげると親切？だと思います。

Pythonですが、下のリンク先内の実装例では、 n = int(input('素数判定したい3以上の整数nを入れてね。n='))と親切に書かれていました。
https://club.informatix.co.jp/?p=12181

私が書いたコードはこちらです。
~~~Java:PrimeNumber.java
//入力された自然数が素数かどうか判定するプログラム
import java.util.Scanner;

public class PrimeNumber {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("自然数を入力してください: ");
        int n = sc.nextInt();

        boolean isPrime = true;
        for (int i = 2; i < n; i++) {
            if (n % i == 0) {
                isPrime = false;
                break;
            }
        }

        if (n == 1) {
            System.out.println(n + "は素数ではありません。");
        } else if (isPrime) {
            System.out.println(n + "は素数です。");
        } else {
            System.out.println(n + "は素数ではありません。");
        }
    }
}
~~~

# 2から100までの範囲の素数を出力する
・ある数が素数かどうかを判定するためには、**その数の平方根までの数で割り切れるかを確認すれば充分**であることを利用して効率的なプログラムにしました。
~~~PrimeNumber2.java
public class PrimeNumber {
    public static void main(String[] args) {
        boolean[] Prime = new boolean[101];
        
        for (int k = 1; k < Prime.length; k++) {
            Prime[k] = true;
        }

        // 素数判定
        for (int i = 2; i < Prime.length; i++) {
            for (int r = 2; r * r <= i; r++) {
                if (i % r == 0) {
                    Prime[i] = false;
                    break;
                }
            }
        }

        // 素数の出力
        for (int j = 2; j < Prime.length; j++) {
            if (Prime[j]) {
                System.out.println(j);
            }
        }
    }
}
~~~
# 最後に
素数判定のアルゴリズムは色々あるので下の記事などを参考にしてください。
https://qiita.com/ppza53893/items/e0f464340d6f97760cd5
PostgreSQLでdata_checksums、wal_segment_sizeを変更したい場合

## data_checksums、wal_segment_sizeは後から修正できない！
initdbで最初からやりなおしになります。

なので、既存のものを変更したい場合は、データをダンプして、インポートしなおしとなるので注意。


## data_checksums
~~~
データチェックサムは、PostgreSQLのデータベースクラスタ初期化時に、有効にするかどうかを指定します。 
後から設定を変更することはできないのでご注意ください。 
具体的には initdb に -k オプションを付けてデータベースクラスタを作成すると、データチェックサムが有効になります。
~~~

## wal_segment_size
~~~
WALセグメントサイズをメガバイト単位で設定します。
これはWALログの個々のファイルの大きさです。 
デフォルトの大きさは16メガバイトです。
値は1から1024の間の2の冪でなければなりません。
このオプションは初期化の際にのみ設定することができ、後で変更することはできません。
~~~

コマンド例
~~~
su - postgres -c '/usr/pgsql-xx/bin/initdb -k --wal-segsize=64 -E UTF8 --locale=C -A scram-sha-256 -W'
~~~

 -E UTF8 :エンコーディングの設定
 --locale=C：ロケールの設定
RSpecのテストコードを整理する：describe→context→it の使い分け

[describe の使い方](#describe-の使い方)
[describeブロックを二重に使用するパターン](###describeブロックを二重に使用するパターン)
[context の使い方](#context-の使い方)
[it の使い方](#it-の使い方)
[before テストの整理とリファクタリング](#before-テストの整理とリファクタリング)
[簡易例](#簡易例)



# describe の使い方
`describe` ブロックは、主題を明確にするために使用します。
クラスやメソッドなど、テストしたい対象の単位でグループ化します。
※`#full_name`の`#`はインスタンスメソッドを識別している

```ruby:ruby
describe User do
  # Userクラスのテストを記述
end

describe '#full_name' do
  # full_nameメソッドのテストを記述
end
```
### describeブロックを二重に使用するパターン
```ruby:ruby
describe Person do
  describe '#name' do
    context '名前が設定されている場合' do
      it '名前を正しく返すこと' do
        person = Person.new(name: '山田太郎')
        expect(person.name).to eq('山田太郎')
      end
    end

    context '名前が設定されていない場合' do
      it 'nilを返すこと' do
        person = Person.new(name: nil)
        expect(person.name).to be_nil
      end
    end
  end

  describe '#age' do
    context '年齢が設定されている場合' do
      it '年齢を正しく返すこと' do
        person = Person.new(age: 30)
        expect(person.age).to eq(30)
      end
    end

    context '年齢が設定されていない場合' do
      it 'nilを返すこと' do
        person = Person.new(age: nil)
        expect(person.age).to be_nil
      end
    end
  end
end
```
最上位の `describe` は `Person` クラス
（`name` と `age`）は `describe` の属性で、各々に焦点を当てグループ化しています。

`context`は以下の章で記述している通りですが、
更に詳細に区分して、各属性が設定
`されているか？`
`されていないか？`
という条件を基にテストグループ化しています。




# context の使い方
`context` ブロックは、条件や状況を基にテストをグループ化する際に使用します。
結果が返ってくる場合、返ってこない場合という2つの状態を使いこなします。

```ruby:ruby
describe '#full_name' do
  context 'ユーザーにミドルネームがある場合のテスト' do
    #テストコード
  end

  context 'ユーザーにミドルネームがない場合のテスト' do
    #テストコード
  end
end
```
# it の使い方
`it` ブロックは、具体的な期待値を記述します。
これはテストの最小単位で、一つの it ブロックには一つの振る舞いや結果が期待されます。

```ruby:ruby
describe '#full_name' do
  context 'ユーザーにミドルネームがある場合のテスト' do
    it 'ミドルネームを含む' do
      user = User.new(first_name: 'John', middle_name: 'H.', last_name: 'Doe')
      expect(user.full_name).to eq('John H. Doe')
    end
  end
end
```

# before テストの整理とリファクタリング
DRY原則を守るために、`before` ブロックを利用して共通のセットアップを行います。
テスト毎に繰り返し必要になる前提条件や処理を一箇所にまとめ、コードの重複を防ぎます。
```ruby:ruby
describe '#full_name' do
  before do
    @user = User.new(first_name: 'John', last_name: 'Doe')
  end

  it '連結されたフルネームを返す' do
    expect(@user.full_name).to eq('John Doe')
  end
end
```


<br>

### 簡易例

```ruby:ruby
describe '数値の加算' do
  context '両方の数値が正の場合' do
    it '合計を正しく計算する' do
      expect(1 + 2).to eq(3)
    end
  end

  context '一方の数値が負の場合' do
    it '正しい合計を返す' do
      expect(1 + (-1)).to eq(0)
    end
  end

  context '両方の数値が負の場合' do
    it '合計が負の数になる' do
      expect(-1 + (-1)).to eq(-2)
    end
  end
end
```

`describe '数値の加算'`:  数値加算機能全体をテストする範囲を示しています。
`context '両方の数値が正の場合'`: 両方の数値が正の値である場合の動作を検証します。
`context '一方の数値が負の場合'`: 一方の数値が負である場合の結果を検証します。
`context '両方の数値が負の場合'`: 両方の数値が負の場合の合計をテストします。
`itブロック`: 各itブロックでは、特定の期待される結果を詳細にテストしています。
プログラミングの基礎学習の開始

# はじめに
　2024年9月24日より書籍『プログラミングの基礎』および関数型言語OCamlを用いてプログラミングを基礎から学び始めた。

 # 過去における筆者のプログラミング経験
 　3年ほど前にプログラミング知識ゼロの状態から半年ほどかけてWebアプリケーションを1つ作成した。
　その際使用した言語は
  * HTML
  * CSS
  * Javascript
  * Ruby

 の4つである。
　また、フレームワークとしてRuby on Railsを使用した。
 　当時作成したアプリケーションの内容としては食事のコストパフォーマンスを評価するものであったが、その出来栄えは控えめに言っても粗末なものであった。（今となっては、当該アプリケーションのデータが残存しているかすら怪しい…）

 # 経験を踏まえたうえでの自己能力評価
 　以前おこなったWebアプリケーション作成は短い期間のなか急ピッチで進めたものであったため、まともにプログラミングの学習を深める余裕がほとんど無かった。そのため、当時の経験というのはまさに付け焼刃でしかなく、はっきり言って現在（2024/9/28）の私にはプログラミングの能力があるとは言い難い。

# 基礎からのプログラミング学習
　プログラミングの技術・知識を体系立てて身に着けるべく、まずはプログラミングに関する基礎知識や概念の学習から始めることとした。学習に使用した書籍は以下の2冊である。

### 書籍①『基礎からのプログラミングリテラシー』
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3896883/c4a85fdb-9654-6276-91d3-b844332bebb9.png)

### 書籍②『これからはじめるプログラミングの基礎の基礎』
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3896883/be0cd460-15cc-4728-8ba1-0ec73982750c.png)

　そして、実際にプログラミング言語を触るべく書籍『**プログラミングの基礎**』を用いた学習を始めた。

　次の記事からは『プログラミングの基礎』を用いた学習の軌跡を記していくこととする。
　なお、第1章は前置きにあたる部分であるため省くこととする。

[次項：『プログラミングの基礎』第2章 データ型・四則演算](https://qiita.com/D_Sato_01/items/35044d6be21990db766c)
MySQLでインポート時に「1118 Row size too large (> 8126)」エラー

## エラーメッセージ

~~~
1118 Row size too large (> 8126). 
Changing some columns to TEXT or BLOB may help. In current row format, 
BLOB prefix of 0 bytes is stored inline.
~~~

## my.ini が修正できる場合

以下のパラメタを追加する
~~~
innodb_strict_mode=0
~~~

## RDS（AWS）などで、修正出来ない場合

インポートするダンプファイルのヘッダに以下を追加する
~~~
/*!50001 SET innodb_strict_mode      = 'off' */;
~~~
msmtpのインストール

# はじめに
ラズベリーパイにmsmtpのインストールについて記事があまり見つからないので、自分用備忘録がてら書きます。

けど、こちらを参考にしました。

https://remoteroom.jp/diary/2021-03-05/

# そもそも
LS220Dを入手し、SSHで入れるようにしAWSCLIでS3へのアップロードを試みました。
上手くいかず、LS220DはNAS専用機としました（当たり前ですが）。
VPNやSMBサーバーを兼ねているラズパイにて、AWSCLIをインストール、ここからLS220Dの中身をS3にバックアップする方法を取っています。
この中で、ログの取得や、実行失敗時にメールにて通知をさせたい背景があります。


# 事前情報
本当は大好きGmailなんですが、たまに二段階認証とかで躓いたり、改変されたりするので、
BCP的な観点からも今回は、プロバイダ支給のメールアドレスに設定します。
定期的にプロバイダも入れ替えているので、メールアドレスや設定更新に心が折れないかが心配です。


https://faq.support.biglobe.ne.jp/faq_detail.html?faq_id=12951


# インストール

    sudo apt update
    sudo apt install msmtp msmtp-mta


# 設定内容

    $ cat ~/.msmtprc
    defaults
    
    account biglobe
    host mail.biglobe.ne.jp
    port 587
    user xxxxxxx@xxx.biglobe.ne.jp
    password yyyyyy
    from xxxxxxx@xxx.biglobe.ne.jp
    tls on
    tls_starttls on
    tls_certcheck on
    auth on
    
    account default : biglobe

所有権類の変更

    sudo chown hogeuser:hogeuser /home/hogeuser/.msmtprc
    chmod 600 /home/hogeuser/.msmtprc


# テスト

    echo -e "Subject: test of subj\n\ntest of text" | msmtp -v example1@gmail.com

エラーではないですが、色々出てきますが、メール送信できました。
このあたりも丁寧にやりたい方は、上記のリンク先などを参照されるといいと思います。
パスワードも平文で書くのがだめだとかもあると思います。
細かい部分は抜きにして、まずは大枠の動作確認まででした。
いろいろなスクリプトや、crontabで定期送信させて、遊びましょう。


# 実は。。。
最近は、事前テストと称して、WSL2のdebianで前もって実行・検証しています。
Windows上の仮想環境で、実環境にsshする手間や、環境が汚れる恐れがなくなります。
上記は下記の環境で一旦テストしています。


    $ cat /etc/os-release
    PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
    NAME="Debian GNU/Linux"
    VERSION_ID="12"
    VERSION="12 (bookworm)"
    VERSION_CODENAME=bookworm
    ID=debian
    HOME_URL="https://www.debian.org/"
    SUPPORT_URL="https://www.debian.org/support"
    BUG_REPORT_URL="https://bugs.debian.org/"


debianのみならず、いろいろなディストリビューションで遊べます。
ですが、pipを使ったインストール時には色々言われてめんどいです。

    
    $ pip3 install requests
    error: externally-managed-environment
    
    × This environment is externally managed
    ╰─> To install Python packages system-wide, try apt install
        python3-xyz, where xyz is the package you are trying to
        install.

完全な解決ではありませんが、下記で一時しのぎできます。

    pip3 install requests --break-system-packages
【備忘録】Java言語でyyyy/MM/ddを最速で取得する

### 結論
```java
import java.time.LocalDate;
LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
```

### 前提

#### ・Java 1.8以降

### 使うメリット
:::note info
SimpleDateFormatを使う場合に比べ、ちょっとコードが短い
:::
:::note info
日付を加算・減算したい場合においては、SimpleDateFormatを使う場合に比べ、遥かにコードが短い
:::

#### ソースコード(Java 23を体験したかったので、Java 23用のコードです)
```java:Java23_LocalDate.java
import java.time.LocalDate;

void main() {
    // 現在日を出力
    println(LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")));

    // 7日前を出力
    println(LocalDate.now().minusDays(7).format(DateTimeFormatter.ofPattern("yyyy/MM/dd")));
}
```

#### 実行
```bat
java --enable-preview .\Java23_LocalDate.java

2024/09/28
2024/09/21
```
---
#### おまけ(SimpleDateFomatterの場合)
```java:Java23_SimpleDateFomatter.java
import java.time.format.DateTimeFormatter;
import java.util.Calendar;

void main() {
    // 現在日を出力
    println(new SimpleDateFormat("yyyy/MM/dd").format(Calendar.getInstance().getTime()));

    // 7日前を出力
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.DAY_OF_MONTH, -7);
    println(new SimpleDateFormat("yyyy/MM/dd").format(calendar.getTime()));
}
```

#### 実行
```bat
java --enable-preview .\Java23_SimpleDateFomatter.java

2024/09/28
2024/09/21
```
【自分用・随時更新】Latexで文書作成するときの有用情報まとめ

# 環境設定

## VSCode
https://qiita.com/rainbartown/items/d7718f12d71e688f3573

# マクロ部分

## ファイル構成
https://zenn.dev/kyaon/articles/b6ac105075b079

## インデント
https://mathlandscape.com/latex-indent/

## パッケージ
### 確認とインストール
http://www2.yukawa.kyoto-u.ac.jp/~koudai.sugimoto/dokuwiki/doku.php?id=latex:パッケージの追加

### 使うパッケージ
```latex
\usepackage[top=20mm, bottom=20mm, left=20mm, right=20mm]{geometry} % 
\usepackage{amsmath, amssymb} % 数式関連
\usepackage{bm} % 数式環境の太字
\usepackage{amsthm} % 証明環境
\usepackage{fancyhdr} % ヘッダとフッタのカスタマイズ
\usepackage{framed} % framed,shaded,leftbar
\usepackage{fancybox} % 文中レベルの枠囲み
\usepackage{ascmac} % デザイン性が高い枠囲み環境
\usepackage{enumitem} % 箇条書き環境
\usepackage[dvipdfmx]{graphicx}  % 画像の挿入
\usepackage{subcaption} % サブキャプション
\usepackage{flushend} % 段組みのカスタマイズ
\usepackage{footnote} % ページ下部にフットノートを入れられる
\usepackage{tikz} % 図の作成
```

# 環境レベル

## 目次
https://phithon.hatenablog.jp/entry/20110224/tex_change_the_depth_of_the_table_of_contents

## 箇条書き
https://mathlandscape.com/latex-enum/

### ex) enumerate環境の添字を(1),(2),...に変える
```latex
\begin{enumerate}[label=(\arabic*)]
    \item   
    \item
\end{enumerate}
```

### 行間を変えたい場合
```latex
\begin{enumerate}
  \setlength{\parskip}{0cm} % 段落間
  \setlength{\itemsep}{0cm} % 項目間

  \item
  \item
\end{enumerate}
```
https://sleepy-yoshi.hatenablog.com/entry/20080115/p2

マクロ化もできる。特殊な添字を使う場合はそれも含める
```latex
\let\oldenumerate\enumerate
\renewcommand{\enumerate}{
   \oldenumerate
   \setlength{\itemsep}{1pt}
   \setlength{\parskip}{0pt}
   \setlength{\parsep}{0pt}
}
\let\olditemize\itemize
\renewcommand{\itemize}{
   \olditemize
   \setlength{\itemsep}{1pt}
   \setlength{\parskip}{0pt}
   \setlength{\parsep}{0pt}
}
```
## 枠囲み
### framed, fancybox, ascmac
https://atatat.hatenablog.com/entry/cloud_latex14_frame

### tcolorbox
https://marukunalufd0123.hatenablog.com/entry/2019/03/15/071717

# 文章レベル
## 数学記号
https://mathlandscape.com/latex-set/

# お役立ち
## section カウンタをリセットする
```latex
\setcounter{section}{0}
```
https://synboo.hatenadiary.org/entry/20080904/1220509672

## 複数行コメントアウト
\if0 - \fiが非常に有用
```latex
% 一行コメント

\if0
複数行コメント
\fi

% commentパッケージを利用した方法
% プリアンブルに以下を追加
\usepackage{comment}
% 利用する場合はbegin-endで囲む
\begin{comment}
複数行のコメント
\end{comment}

```
https://qiita.com/takatea/items/9748956003c9b2df9ae0
Next.jsでCloudinaryに画像を保存する方法

# はじめに
Next.jsを用いてTwitterクローンアプリを作成しているのですが、ツイートに投稿した画像を保存するストレージとしてCloudinaryを採用しました。
今回はNext.jsでのCloudinaryの使い方をメモしておきます。

# 環境構築
以下のライブラリをインストール
```
npm install cloudinary
```

Cloudinaryのページにて``CLOUD_NAME``と``API_KEY``と``API_SECRET``の3つを取得し、環境変数に設定してください。

```.env
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=<CLOUD_NAME>
NEXT_PUBLIC_CLOUDINARY_API_KEY=<API_KEY>
CLOUDINARY_API_SECRET=<API_SECRET>
```

# 実装

以下のようにして自分のCloudinaryとアプリを結びつける。
今回、APIを使用して保存する実装にしている。
POSTメソッドで使用している``upload``の引数については[こちら](https://cloudinary.com/documentation/image_upload_api_reference#upload)を参照

```
import { v2 as cloudinary } from "cloudinary";

cloudinary.config({
    cloud_name: process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME,
    api_key: process.env.NEXT_PUBLIC_CLOUDINARY_API_KEY,
    api_secret: process.env.CLOUDINARY_API_SECRET
});


export async function POST(request: NextRequest) {
    try {
        const body = await request.json();
        const { imageData } = body;
        const result = await cloudinary.uploader.upload(imageData);
        return NextResponse.json(result.secure_url);
    } catch (err) {
        return NextResponse.json(null, { status: 500 });
    }
}
```

今回``upload``の引数に使用している``imageData``は、以下のようにして求めたデータURLを用いた

```
export const fileRead = async (file: File) => {
    const fileReader = new FileReader();
    fileReader.readAsDataURL(file);
    await new Promise<void>((resolve) => (fileReader.onload = () => resolve()));
    return fileReader.result as string;
};
```
```
const [imageDatas, setImageDatas] = useState<(string | ArrayBuffer | null)[]>([]);
const selectedImageDatas = [];

selectedImageDatas.push(await fileRead(file));
setImageDatas([...imageDatas, ...selectedImageDatas]);
```

あとはPostAPIの返り値として受け取るURLを用いてツイートの文章と紐付けを行いました。
ubuntuにrootユーザでvnc接続できるようにする

## インストール

~~~
apt install xfce4 xfce4-goodies
apt install tightvncserver
apt install dbus-x11
~~~

パスワード設定
~~~
vncpasswd
~~~

~~~
Password:
Verify:
Would you like to enter a view-only password (y/n)? n
A view-only password is not used
~~~

root接続許可設定
~~~
vi /etc/gdm3/custom.conf
~~~

~~~
[security]
AllowRoot=true
AllowRemoteRoot=true

[xdmcp]
Enable=true
~~~

起動
~~~
tigervncserver -xstartup /usr/bin/gnome-session -geometry 1024x768 -localhost no :2
~~~

起動確認
~~~
vncserver -list
~~~

停止
~~~
vncserver -kill :*
~~~

WindowsPCからの接続は
TigerVNC Viewerがお勧めです
https://github.com/TigerVNC/tigervnc/releases

vncviewer64-x.xx.x.exe をダウンロード
NFCを使ってみる

# はじめに
FeliCa Lite-Sの検出ができたので、テストとしてデータの読み書きを行ってみたいと思います。

# 使用機器
PN5180 NFC RFセンサーモジュール
FeliCa Lite-S RC-S966

# 手順
FeliCa Lite-Sの動作確認のため、スクラッチパッド0にデータを書き込み、書き込んだデータを読み出してみたいと思います。
スクラッチパッド0に
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
のデータを書き込んで、書き込んだデータを読み出してみようと思います。

スクラッチパッド
ユーザーが自由に使用できる16バイトの領域
S_PAD0からS_PAD13までの14ブロックある

データの送受信を行うためには、カードの検出で取得したIDを使用します。
サービスコードは0x0009を使用します。

○Write Without Encryptionコマンド（FeliCa仕様）
0x09 0x00
0x20
0x08
0x01 0x2E 0x50 0xE7 0xDA 0xC7 0x8B 0x47
0x01
0x09 0x00
0x01
0x80 0x00
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F

IDについて
0x01 0x2E 0x50 0xE7 0xDA 0xC7 0x8B 0x47は私の使用したFeliCa Lite-SのIDになります。

サービスコードリストについて
0x01
0x09 0x00
サービス数はFeliCa Lite-Sの仕様により1固定となります。
サービスコードは、0x0009（リード／ライトサクセス）をリトルエンディアンで指定します。

ブロックリストについて
0x01
0x80 0x00
今回は、スクラッチパッド0のみに書き込みを行うので、ブロックリスト数は1とします。
ブロック番号は1バイトで設定しています。

![FeliCaLiteS-ページ2.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148400/73d6b3fd-0391-cb2d-4bcb-76928d803794.png)

○Read Data（PN5180仕様）
0x0A 0x00

○Response（FeliCa仕様）
0x0C
0x09
0x01 0x2E 0x50 0xE7 0xDA 0xC7 0x8B 0x47
0x00 0x00

○Read Without Encryptionコマンド
0x09 0x00（FeliCa仕様）
0x10
0x06
0x01 0x2E 0x50 0xE7 0xDA 0xC7 0x8B 0x47
0x01
0x09 0x00
0x01
0x80 0x00

○Read Data（PN5180仕様）
0x0A 0x00

○Response（FeliCa仕様）
0x1D
0x07
0x01 0x2E 0x50 0xE7 0xDA 0xC7 0x8B 0x47
0x00 0x00
0x01
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F

# 編集後記
データの読み書きができたので、次はセキュリティ対応を行ってみたいと思います。
ubuntuにsshを入れる

## インストール
~~~
apt install openssh-server
~~~

## 確認
~~~
systemctl status ssh
~~~

~~~
●    ssh.service    -    OpenBSD    Secure    Shell    server
Loaded:    loaded    (/usr/lib/systemd/system/ssh.service;    disabled;    preset:    enabled)
Active:    active    (running)    since    Mon    2024-09-23    11:47:17    JST;    18min    ago
~~~
個人開発したwebサービスのアクセス数をみてみた

# 背景
先日、ChatGPTと対話しながらWebサービスを開発した記事を作成しました。
9/24に投稿してからのアクセス数の推移について確認しました。
本記事を作成している9/28の15:00時点では「463」の閲覧がありました。
果たして記事の効果はあったのでしょうか？

![スクリーンショット 2024-09-28 14.59.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3892822/a720af6a-2f9c-77a8-bde5-2fc74d9854f9.png)

https://qiita.com/travelclass0606/items/135263b166a0db7ca988

# 結果
さあ、結果をみていきましょう!

アクティブユーザー数
![スクリーンショット 2024-09-28 15.09.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3892822/541b5b69-fe4d-d384-802c-1ce014eb1f1b.png)

アクティブユーザー数は24から25日かけて少し増えた気もするが、ほぼ影響なしですね…


新規ユーザー数
![スクリーンショット 2024-09-28 15.11.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3892822/d28b8e68-80ad-89eb-bfa6-d332dc6f5370.png)

新規ユーザー数も24日から25日にかけて少し増加したように見えます。多少の効果はあったのかもしれません。

![スクリーンショット 2024-09-28 14.51.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3892822/43d8de39-4e5c-8848-9f42-8f6d52d546a3.png)

アクセスのほとんどは日本からですが、なぜか中国からのアクセスも確認されました！？

# 最後に
まだまだアクセス数は少ないですが、自分が作ったサービスに少しでも興味を持ってもらえたことや、記事が400回以上閲覧されたことにとても感謝しています。これからも頑張っていきます！

最後に、自分が作成したWebサービスのリンクを貼っておきます。

https://travel-class.com