OmniAICreator/Qiita-1.07M huggingface dataset:
wslで、最小のカーネルをコンパイル その4

# 概要
wslで、kernel.elfのコンパイル、やってみた。
cで、書いたカーネルをQEmu で、実行してみた。

# 環境
Windows10

# 手順
diskexplorerで、kernel1.elfを入れる。

![](https://camo.qiitausercontent.com/ade8672feb13246904247720b462f39655ca9fc5/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f31383130342f63316137356461302d373665632d643334372d376365382d3733633132643962633438632e706e67)

# QEum Luncharで、bootgrub.imgを起動

![](https://camo.qiitausercontent.com/cc947818b8c0f595f168cdf3c61bc13599703109/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f31383130342f37613138396336662d633562322d623537372d363037312d3738356266616539346332372e706e67)

Cキーで、コマンドラインに入る
kernelを設定
bootで起動

```
grub> kernel (fd0)/boot/kernel1.elf

grub> boot
```

![](https://camo.qiitausercontent.com/765da680951c3bfb31aaaa2eb19db835a23bdd41/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f31383130342f34386562376331612d326436632d616631662d643939362d3537666436376463326139392e706e67)

# kernelが起動
Hello world

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/171acb50-af99-4dd3-5526-6e627f20a81b.png)



以上。
Rによる中華料理店過程のスクラッチ実装

# ノンパラメトリックベイズ
ノンパラメトリックベイズとは、柔軟なモデリングが可能なベイズ統計学の手法の一つです。手法のイメージとしては、パラメトリックな仮定を置かない手法というよりも、通常のベイズ的な手法の複雑さを決定するパラメータを無限大に拡張した手法と言えます。

この記事では、佐藤一誠先生の[ノンパラメトリックベイズ本](https://www.kspub.co.jp/book/detail/1529151.html)を参考に、本の中のモデルを実装していきます。理論的な詳細については、こちらの本をお読み下さい。

# 中華料理店過程

中華料理店過程について簡単に説明します。

#### 中華料理店過程のイメージ

中華料理店に次々とやってくる客は、料理の置いてあるテーブルを一つ選んで座ります。この時、客は自分よりも前に来た客がどのテーブルに集まっているかを見て、人気のあるテーブルに座りたいと考えるでしょう。また稀に、誰も座っていないけど、あのテーブルの料理は美味しそうだと気付き、新しいテーブルに座る客も現れます。このような客が座るテーブルに番号をつけて、それを記述した確率過程が中華料理店過程です。

#### 実装に必要な数式

客、テーブルにはそれぞれ$i = (1,2,...n)$、$k = (1,2,...)$と番号が割り振られてられています。また、$z_i$は客$i$が座ったテーブルの番号を表します。例えば、一人目の客は必ず$k=1$のテーブルに座り($z_1 = 1$)、二人目の客は$k=1$のテーブルか$k=2$($z_2 = 1\ or\ 2$)のテーブルのどちらかに座ります。中華料理店過程において$z_i=k$の確率は以下のようになっています。[^1]


```math
p(z_i = k | z_{1:i-1}) = \left\{
\begin{array}{ll}
\frac{n_k}{i-1+\alpha} & (k \in K^+(1:i-1)) \\
\frac{\alpha}{i-1+\alpha}  & (k = |K^+(1:i-1)|+ 1)
\end{array}
\right.
```

$K^+(1:i-1)$は$1$から$i-1$の客が既に座っているテーブルの集合、$n_k$は各テーブルの人数を表しています。上の式は既に人が座っているテーブル$k$に客が座る確率、下の式は新たなテーブルに座る確率を表しています。
また、パラメータ$\alpha$が登場しています。これは式の形からも分かるように、客が新たなテーブルを選ぶ確率を制御するパラメータであると解釈します。[ノンパラメトリックベイズ本](https://www.kspub.co.jp/book/detail/1529151.html)を参考にここでは$\alpha＝1$として実装しました。

# 実装

#### 実装
Rのコードは以下の通りです。
```R
# params set
alpha <- 1
n <- 100

z <- c(1)


# CRP process
set.seed(428)

for (i in 2:n) {
  num_table <- max(z)

  prob <- rep(0, num_table + 1)
  for (table in 1:num_table){
    num_guest <- sum( z == table)
    table_prob <- num_guest/(i - 1 + alpha)
    prob[table] <- table_prob
  }
  prob[num_table + 1] <- alpha/(i - 1 + alpha)
  
  z_i <- rmultinom(n = 1, size = 1, prob = prob) |> 
    which.max()
  z <- c(z, z_i)
}

```
客の数$n$は100として、最初の客は$k=1$のテーブルに座るものとします。

#### 結果のプロット
ggolot2を使ってヒストグラムを表示します。
```R
hist <- ggplot2::ggplot(mapping = ggplot2::aes(x = z)) +
  ggplot2::geom_bar() +
  ggplot2::scale_x_continuous(breaks = 1:max(z))

hist
```

![CRP_plot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3732503/9357eeb0-99a2-e836-04e6-30bd066a3b08.png)
テーブル１に客が集中していることが分かります。今回はテーブル４まで生成されました。


# 付録
$\alpha$を２にして実行しました。
![CRP_plot_alpha2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3732503/36a54c5e-91c2-9d6b-3e6c-c7c323d9e261.png)

$\alpha$が１のときと比較して、新たなテーブルが選ばれやすくなっています。

[^1]:中華料理店過程は、ノンパラメトリックベイズで用いられるディリクレー多項分布モデルとは別に提案されたものですが、後者のモデルにおいてクラスの数を無限にとったときのクラスの分割に関する分布と同じ形になっています。詳しくは、[ノンパラメトリックベイズ本](https://www.kspub.co.jp/book/detail/1529151.html)をお読み下さい。

# 参考文献
[1]佐藤一誠. (2016).「ノンパラメトリックベイズ 点過程と統計的機械学習の数理」.　講談社.\
(https://www.kspub.co.jp/book/detail/1529151.html)
TypeScript 用の Symbol-SDK ver.3 環境構築

## Node.js

https://nodejs.org/en

Node.jsは最新のLTSをインストールしておきましょう。


## プロジェクト作成と設定
### 各種インストール
任意のディレクトリを作成して、作成したディレクトリに入ります。
```bash
mkdir slowly-symbol-learning
cd slowly-symbol-learning
```

#### package.jsonの作成
対話型で作成しますが、公開までは考えていないので全部yesになるよう`-y`を付けます。
```bash
npm init -y
```

#### Symbol-SDKバージョン3のインストール
実験版などがインストールされる可能性があるので`@3`を付けてインストールします。
```bash
npm i symbol-sdk@3
```

#### TypeScriptのインストール
ついでにNode.jsの型定義もインストールする。
```bash
npm i -D typescript @types/node
```

#### ts-nodeのインストール
簡単にTypeScriptを実行できるようにグローバルにts-nodeをインストールします。
```bash
npm i -g ts-node
```

#### package.jsonの編集
`"type": "module",`を追加します。下の例では、descriptionの次の行に追加しています。
```package.json
{
  "name": "slowly-symbol-learning",
  "version": "1.0.0",
  "description": "",
  "type": "module",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/node": "^20.11.24",
    "@typescript-eslint/eslint-plugin": "^7.1.0",
    "@typescript-eslint/parser": "^7.1.0",
    "eslint": "^8.57.0",
    "eslint-config-prettier": "^9.1.0",
    "prettier": "^3.2.5",
    "ts-node": "^10.9.2",
    "typescript": "^5.3.3"
  },
  "dependencies": {
    "symbol-sdk": "^3.1.0"
  }
}
```

#### tsconfig.jsonの設定
`tsconfig.json`ファイルを作成して、下記を入力します。
```tsconfig.json
{
  "compilerOptions": {
    "module": "NodeNext",
    "target": "ESNext",
    "sourceMap": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
  },
  "ts-node": {
    "esm": true
  }
}
```

### コードスタイル＆整形
#### ESLint、Prettier各種インストール
```bash
npm i -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-config-prettier prettier
```

#### ESLintの設定
`.eslintrc.json`ファイルを作成して、下記を入力します。
```.eslintrc.json
{
  "env": {
    "node": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "sourceType": "module",
    "project": "./tsconfig.json"
  },
  "plugins": [
    "@typescript-eslint"
  ],
  "rules": {
    "@typescript-eslint/no-explicit-any": 1,
    "@typescript-eslint/no-non-null-assertion": 1
  },
  "root": true
}
```

#### Prettierの設定
`.prettierrc.json`ファイルを作成して、下記を入力します。
タブ幅や改行位置などお好みで。
```.prettierrc.json
{
  "tabWidth": 2,
  "printWidth": 80,
  "trailingComma": "es5",
  "semi": true,
  "singleQuote": true
}
```
ラズパイでCLIカレンダー+予定表アプリ

### ラズパイでCLI予定表

CLIコマンドラインで予定を書き込んだり
予定表を表示するアプリを発見しました。

`calcurse`です

GooglecalendarとかOutlook予定表とかの
コマンドラインインターフェース版をイメージです。

Linux系OSで使えます。未着手ですがおそらくWSLでもいけるでしょう。

### 導入方法

raspbian OSには、ncursesなどがプレインストールされてない模様なので
それらをまず導入します。

```
sudo apt-get install libncurses5 libncurses5-dev
sudo apt install gettext
```

そのあと、アプリサイトからtarをダウンロードしてください。

```
wget https://calcurse.org/file/calcurse-4.8.1.tar.gz
```

しかし、このファイルはgzipでなくたんなるtarですので、

```
mv calcurse-4.8.1.tar.gz calcurse-4.8.1.tar
tar xvf calcurse-4.8.1.tar
```

しましょう。そのあとはマニュアルに記載のとおり

```
cd calcurse-4.8.1
./configure
make
sudo su
make install
```

### iCalendar形式の出力に対応

予定表（日付と時間帯と場所とイベント）の場合、iCalという
共通フォーマットがあるので、その形式で出力し
そのファイルをGitリポジトリにいれればOKですよね。

たとえば、ghrというgitリポにcalcurse.icalというファイルがあるとして
そいつを読み出したいときは、

```
calcurse -i ./ghr/calcurse.ical
```

こうすることで複数の端末間でシェアできます。

### 端末間共有についての追記

iCalファイルを読み出すと、既存のカレンダーに追記されるかたちとなります。
その結果、おなじアイテムがどんどんどんどん重複されていくこととなります。
解決法については作者にお問い合わせ中ですが、さしあたりの対策として、
`calcurse`ディレクトリにある `apts`ファイルをGitリポジトリ保存する
というのをおもいつきました。端末間共有の場合はコピーコマンドで最新の
`apts`を表示するようにするというものです。

アプリのマニュアルには、ファイルの保存場所が`.calcurse`のようにかいてますが、
じっさいには、以下の場所のようです。

```
~/.local/share/calcurse/apts
```

Google calendarとのシンクロをおこなうためのアプリもあるようですが、
それについては、ためしていません。


### やってみたいこと

RaspbianなのでCLIで完結できてうれしいです。
Windowsの場合はWSLの黒い画面で完結みたいなはずですが、いまからこころみます
ほかにも、よいアプリをご紹介ください。よろしくお願いします。

### リマインド機能

```
notification.command (default: printf \a)
```

このオプションは、`important`としてフラグが立てられた今後の予定があるときに
どのコマンドを起動するかを示します。 
このコマンドはユーザーのシェルに渡され、解釈されます。 
どのシェルを使用する必要があるかを知るには、$SHELL 環境変数の内容が使用されます。
(多くの場合、`.bashrc`だとおもいます)

muttmuaをつかっているばあい、`.config/calcurse/conf`をいじって
次のようにすると24時間前にリマインドメールが送られるはずです。

```
notification.command=echo "$(calcurse -n)" | mutt -s "Don't forget..." user@host.com
```

### ご参考

ちなみにTODOリストだと、[todo.txt](http://todotxt.org/)
ってのがあります。

- https://github.com/agarrharr/awesome-cli-apps
- https://calcurse.org
- https://qiita.com/kunihiros/items/92880ae9a0fdf8c18eca
アプリ開発完全未経美少女エンジニアが最強のToDoアプリを怒りに任せて自作するまでの話#最終回(2/20~2/26)

自己紹介
🌻著者プロフィール🌻
名前：おじょち(25歳)
技術領域：ねっとわーく(よわ)、さーば(よわよわ)、ことりん(げきよわ)
趣味：おさんぽ、くりーむそーだ
X：@ojochi_510510

# 🌻緊急最終回🌻

突然ですが、なんと最終回となっております！
結論からお話すると、TODОアプリとかじゃなく技術的にもっと鍛えてから作りたいもの作りたい！！！
のお気持ちになったわけですね🤗
現状のおじょちの集大成と呼べるTODOアプリのようなものはできたのでお披露目します！
今後は、誰かにとって有益な情報だ〜！と思ってもらえるような記事作りを心がけていきます！皆さんの目に止まったらまた見てくださいね🤗💥🤗

それではご紹介です！！

# TODOアプリ紹介
### メイン画面
- 「＋」ボタン→タスクの追加が可能！！
- 更新ボタン→チェックボックスの全解除

![Screenshot_2024-03-11-06-26-41-20_15186ae57f783689b9a40006d3377217.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1566153/fb478c4c-502a-dfc7-d500-de31b212f5ca.jpeg)

### タスク追加ダイアログ
- 「名前」「説明」「実行回数」が追加可能！
- ダイアログってなんかかわいいよね！

![Screenshot_2024-03-11-06-25-14-17_15186ae57f783689b9a40006d3377217.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1566153/836095e4-f606-9828-63e6-5620a91ed4ff.jpeg)

### タスクカード
- 編集と削除が可能！

![Screenshot_2024-03-11-06-25-17-58_15186ae57f783689b9a40006d3377217.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1566153/5c758a34-eb5d-b890-4533-e9a81fc8b996.jpeg)

### 機能紹介
- 編集ボタン→編集モードに移行
- ゴミ箱ボタン→削除
- チェックボックス→グレーアウト＋実行回数に1回＋

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1566153/215da0be-a0cd-8111-2e4e-c2083cd02790.png)
　
## さいごに
以下がだったでしょうか！

DBも実装してないからアプリを落としたらデータは消えちゃうし、、、、😢
デザインもとりあえず自分に並べられる範囲の要素を並べてみてるだけなんですけど、、、、、
自分で作ったアプリってなんだかかわいいですね🤗

最強のTODOアプリにはまだまだ遠いですが、モノを作りきる経験が詰めて取ってもよかったです！！

次回からは、また別の形で記事を書いていく予定ですので、またどこかで！🔥
それでは、ここまで見ていただきありがとうございました！
よく使うHTTPメソッド

#  はじめに
プログラミングを学習する中でも大事な、HTTPについてまとめてみました。
今回はHTTPメソッドについてです。

##  HTTPとは？
HTTP(Hyper Text Transfer Protoocol)、HTMLなどから画像など様々なコンテンツのやり取りをするときに使うプロトコルのこと。
簡単に言うと、インターネットを使う時の約束事のようなものです。
> プロトコル:データのフォーマットと処理の一連のルールのこと

## HTTPメソッド
HTTPリクエストの中の、Webサーバーに具体的な要求内容を伝える役目になるのが、「HTTPメソッド」です。
HTTPメソッドはリクエストする目的別に複数定義されています。
今回は、よく使う５つのHTTPメソッドを紹介します。

-  Webサイトを表示するときに使う「GET」メソッド
-  データをサーバに送信する「POST」メソッド
- データの書き換え、編集をする「PUT」メソッド
- データの一部書き換えをする「PATCH」メソッド
-  削除の「DELETE」メソッド

HTTPメソッドには他にも「CONNECT」メソッドや、「TRACE」メソッドなど様々なメソッドがあります。

#  おわりに
現在のRuby,Railsを学習中ですが、言語の学習だけでなく、Webの仕組みを知っておかないと動かすことができないのだと感じました。
引き続きプログラミング学習と並行して、Webの基本技術も学習していきたいと思います。
docker compose run時にNameError: uninitialized constant Nokogiri::HTML4と遭遇した時の対処法

Dockerを使ってRailsの環境構築を行なっている時に遭遇したエラーの解決方法を備忘録も兼ねてここに記します。

開発環境
M2チップ Mac Book Air
OS: MacOS Sonoma
Rails: 5.0.0.1
DB: MYSQL 5.7
Ruby: 2.4.6
※詳細は省きますが、Windows11の環境でも同様のエラーに遭遇しました。
　同エラー遭遇時にPCを上記のMac Book Air に買い換えた為、Windows環境では解決まで 　の確認はできていませんが、恐らく解決できると思います。

## 実行したコマンドと遭遇したエラー

```
実行したコマンド
docker compose run web bundle exec rake db:create
```

```
遭遇したエラー
rake aborted!
NameError: uninitialized constant Nokogiri::HTML4
Did you mean?  Nokogiri::HTML
```

## エラー解決の為に行なったこと
1, Gemfileを編集して下記の行を追加する
```
gem 'loofah', '~> 2.19.0'
```

2,下記のコマンドを実行することでGemfile.lock上のloofahのバージョン指定を修正する
```
docker-compose run web bundle update loofah
```
bundle updateを行うとBundlerはGemfileを元にgemのインストールを行います。
その後、Gemfile.lockが更新されます。

3, buildを実行して更新された内容でDockerイメージを再構築してコンテナを改めて起動
```
docker compose build
docker compose up
```

参考にした記事
https://hackmd.io/@SKjw2RY-RNCUNSdJfEWPig/ByXXyQcEn
https://qiita.com/lasershow/items/1a048d03ddaaba98171e
2024/3/11主にITとかセキュリティの記事

英国、IoT製品のサイバー対策義務化　日本企業も対応(3/9)
https://www.nikkei.com/article/DGXZQOUC05CMA0V00C24A3000000/

Teslaアカウントを盗んで車のロック解除とエンジン始動が行える攻撃手法が発見(3/9)
https://news.mynavi.jp/techplus/article/20240309-2901808/

ロシア支援のサイバー攻撃急増　Microsoftが注意喚起(3/9)
https://www.nikkei.com/article/DGXZQOGN0906G0Z00C24A3000000/

ロシア関与のハッカー集団、米マイクロソフトに不正アクセス図る(3/9)
https://jp.reuters.com/business/technology/BGYIM35JNJNWTAC7TECJXGVDCM-2024-03-08/

ＬＩＮＥヤフー／総務省から行政指導／松本総務相「定期的な報告を求む」（2024年3月7日号）
https://www.bci.co.jp/nichiryu/article/14585

LINEヤフーに行政指導　佐藤一郎さんらとThink!(3/9)
https://www.nikkei.com/article/DGXZQODL084XC0Y4A300C2000000/

企業におけるAI開発・利用のボトルネック解消へ、データベースの移行を取り払うプラットフォームが登場(3/9)
https://news.yahoo.co.jp/articles/b4528d8ee3c96ae78aef24f26ffc0c6cd9fab576?source=rss

生成AIを、インシデント対応で使ってみた！(3/8)
https://www.nttdata.com/jp/ja/trends/data-insight/2024/0308/

AWS 認定トレーニング「Advanced Architecting on AWS」を受講してみた(3/9)
https://dev.classmethod.jp/articles/advanced-arc-on-aws-hirane-report/

SBOM(Software Bill of Materials)とは（前編）～ SBOM の基礎知識から詳しく解説 ～(3/8)
https://www.cybertrust.co.jp/blog/oss-security/sbom-01.html

【EU】EU理事会と欧州議会、サイバー連帯法とCSA改正で政治的合意。認証制度対象拡大へ(3/9)
https://sustainablejapan.jp/2024/03/09/eu-cyber-solidarity-act/100217

「トロイの木馬に侵入されました」60代男性のPC画面に突然表示…連絡きっかけに"修理"名目で電子マネー要求される 1月にも別の高齢者被害 北海道芦別市(3/9)
https://nordot.app/1138961663117115920
Next.js の Pages Router と App Router の特徴

2023年5月にリリースされたNext.js 13.4からルーティングの処理が従来のPages RouterからApp Routerに切り替わり、どちらの機能を利用することも可能ですが、今後はApp Routerを利用することが推奨されています。
2つのルーティングの仕組みに関する特徴を理解するため、記事にしたいと思います。
以下はあくまで二つのルーティングの違いについて一部の要素に過ぎないので、私の理解が深まり次第随時追記していきたいと思っています。

## Pages Router

### ルーティング フォルダ構成
Pages Routerは、'pages'フォルダ配下に追加されたファイルやフォルダ名をもとに、ルーティングを定義します。

例えば、'pages/login.tsx'のようにファイルを追加すると、'/login'へのアクセス時に'login.tsx'ファイルの内容が表示されます。また、'pages/login/index.tsx'のようにすることもできます。

## App Router

### ルーティング フォルダ構成
App Routerは、'app'フォルダ配下にファイルやフォルダを追加することで、ルーティングが定義されます。

例えば、'/login'へのルーティングを作成する場合、'app/login/page.tsx'とする必要があります。
上記のように、フォルダ名でルートを指定し、'page.tsx'ファイルで内容を表示する仕様になっております。

また、App Routerを使用する際には共通のレイアウトを表示させる'app/layout.tsx'ファイルの作成が必須となります。

### React Server Component(RSC)
App Routerで作成されるコンポーネントはすべて Server Component(サーバー側でレンダリング) として扱われます。Pages Routerでは全てClient Component(クライアント側でレンダリング)でした。App Router内でClient Component として扱うには、ファイルに 'use client' と記載する必要があります。"use client"と記載したファイル内にimportしたファイルは、全てClient Conponentとして解釈されます。以下の例の場合、Labelをimportしていますが、Labelファイル内に'use client'を記載していなくてもClient Componentになります。
```ruby:
"use client"
import Label from "./Label"
export default function Login() {
  return <Label>login</Label>;
}
```

Server Componentはリクエスト前にレンダリングをし、クライアントのJavaScriptのバンドルサイズを減らすことができるため、パフォーマンスが向上します。しかし、Server Componentはクライアント側で実行される React Hooks や イベントハンドラーが使えないなどのデメリットもあります。このような処理をするには Client Component として扱う必要があります。

### Route Groups
ディレクトリ名を(フォルダ名)のようにして囲うと、そのフォルダがURLパスに含まれないようにすることができます。
例えばログイン済みユーザーのディレクトリは(app)、ゲストユーザーのディレクトリは(auth)のようにディレクトリを分けることで、それぞれのディレクトリ毎にレイアウトを分けることができます。
【Flutter】StackでPositionedを追加するとなぜかエラーがでる。

# Positionedを追加するとエラーがでる
Positionedがないときはうまくレンダリングされるのに、Positionedをつけるとエラーが発生するという状況。
簡単な該当プログラムを下に示す。
```dart
Stack(
    children:<Widget>[
        Positioned(
            left:10,
            right:10,
            child:Container(
                width: 10,
                height: 10,
                child: MyWidget()//自分で作ったWidget
            )
        )
    ]
)
```
エラーログとかを調べると、どっかのサイズが無限になっているとかでてくる。
MyWidget()をしているとはいえ、Containerで囲っているからサイズは確定できるはず。なのにサイズが分からないとかワケワカメっていう状態になって、解決に苦労したので備忘録として残しておく。

# 解決方法
Stackのサイズを指定してあげる必要がある。

以下、ChatGPTの回答。

>エラーが発生する原因は、Positionedが使用されるとサイズが有限でなくなり、Stackがその子要素のサイズを決定できなくなることです。Positionedは、Stack内での子要素の配置とサイズを制御するために使用されますが、その際には親要素であるStackのサイズが有限である必要があります。
Positionedウィジェットを使用する際に、親要素であるStackのサイズを指定していない場合や、指定したサイズが有限でない場合にこのエラーが発生します。

ChatGPTの回答を参考に、以下のようにプログラムを変えたら無事に解決した。
```dart
Container(
    height: 100,
    width: 100,
    child:Stack(
        children:<Widget>[
            Positioned(
                left:10,
                right:10,
                child:Container(
                    width: 10,
                    height: 10,
                    child: MyWidget()//自分で作ったWidget
                )
            )
        ]
    )
)
```

# まだ残る疑問点
Positionedの使い方を見ていると、Containerで囲っていないやつも見た気がする。
例えば、この[サイト](https://qiita.com/yu124choco/items/0c0b8566d7bf2c9f18fe)などでは、Containerで囲っていない。bodyとかだと、自動で決定するんかな？？という疑問が湧くが、一応目的は達成したので深追いはしないことにした。
ここらへんに詳しい方がいらっしゃいましたら、ご教示お願いします。
論文メモ：GNNExplainer


# この論文を読んだ理由
- GNNの説明可能性に興味を持ったから


# 読んだところ
- abstract
- 図
- 提案手法の一部


# 解いている課題
- GNNの説明可能性...GNNの推論結果において，重要な役割を果たした近傍ノードを特定する．


# 提案手法のアプローチ

- **GNNの推論結果**と，**あるサブグラフとある特徴量を用いた場合の推論結果**の<font color="red">相互情報量</font>が大きくなるようなサブグラフと特徴量を選択する．
→つまり，**推論結果に大きな影響を与えるノードと特徴量を見つける**．
```math
\max_{G_S} MI(Y, (G_S, X_S)) = H(Y) - H(Y|G=G_S, X=X_S).
```

ただし，$G_S$はサブグラフ，$X_S$は一部の特徴量，Hはエントロピーを表す．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583007/765ae173-e53b-2003-b348-887db40c3ba8.png)
左：GNNの推論結果，右：推論結果に大きな影響を与えるノードと特徴量

## 結果
勾配や，GATを用いた推論の説明と比較して，GNNExplainerが説明の正確性で上回った．

# 次に読む論文
この論文を引用しているGNNの説明可能性に取り組んだ論文，例えば，[GNES: Learning to Explain Graph Neural Networks](https://ieeexplore.ieee.org/abstract/document/9679041) など．
拝啓 これから社会人（IT屋）になるみなさん

## なかなか言えないことなので。。。
大いなる期待と夢を持って入社される社会人バブちゃん、入社おめでとう！

## 涙が出ちゃうこともある
ここから数十年、学生の頃のような大型連休は取れないかもしれないし、睡眠時間を削っての遊びも出来なくなるかもしれないし、休みが合わないため気軽に友達を呼んで遊びに行くとかも出来なくなるかもしれないし、日曜の夜が来ると急に泣き出したくなる日もくるかもしれませんが、何かしらの楽しさを見出して毎日を精一杯生きてください。

## プロとの差に絶望
ITの専門に行ってた方、学校での知識は思ってる以上にリアルでは使えないということを痛感するかと思います。
特に学校で学んでた言語と関係ない言語での開発の際には、1度初心に帰り、無駄に高いプライドは捨て、人に教えを請うことも大事なことになります。
変に知ったかぶりな尖った考えでいると、腫れ物扱いで誰にも相手にされなくなってしまう可能性があるので、分からないことは分からないとキチンと言える素直な心を持ってください。

## 個人技はチームプレイが出来るようになってから
個よりも和、精度より速度が重要視されるため、
スケジュールを乱さぬよう・そこそこな精度の成果物を上げられるよう努めてください。
また遅れが生じそうな場合は、早急に上司へ相談してください。
期限ギリギリで無理と言われますと、終電や休日・睡眠時間が継続してなくなってしまう可能性もありますので、何卒早急に相談してください。

## 付き合う年齢の幅がグンと広がる
先輩方は幅広い年齢・性別・出身の方々がいらっしゃいますが、基本的には皆さんを受け入れる姿勢や意欲はあります。
ただ先輩とは言え完璧超人ではないので、自分の面倒＋他人の面倒まで見られるほど余裕のある方は決して多くありませんので、業務で手一杯の時などは、冷たくあしらってしまう可能性もありますのでご了承ください。

また逆にしつこく進捗などを確認されたときは、期待されている作業スピードが出ていなが故に、心配で聞いてくるんだなと察してください。

## 出来るの詰み重ねって大事
基本的に配属当初は、今のレベルのキミが出来るであろう仕事しか振らないつもりではありますが、たまに難易度の高いことをやらせようと無茶な仕事を振るかもしれません、それはキミへの期待値が大いに高いための試練的なものになりますので、無理なくこなせないようであれば即相談をするようにしてください。

## ちょっとぐらいミスっても別にいいよ
失敗をイッパイしたとしても、次に同じ過ちを起こさないように成長してくれれば、一緒に「ゴメンね」してあげる気持ちはあります。
ただイッパイを頻繁にやられると「期待しすぎてゴメンね、もう頼めないよ。。。」な気持ちになっちゃいます。

## とりあえずファイト！
最初は目の前のことで精一杯かと思いますが、来年の今頃は次の新人が入ってくるという事実を目の当たりにし、もう新人というバッチを使えない絶望が待ってます。
「新人」の内に出来ること、許されることを有効活用して、日々成長して言ってください。

## これからのみなさんのご活躍を期待しております。

敬具
【Django】テーブル定義が更新できないときの解決法（SQLite3）

# はじめに
Djangoでテーブル定義を修正したのにマイグレーションしても更新されない点で詰まったので、解決方法を残しておきます。

# 内容
```
$ python manage.py makemigrations
It is impossible to add a non-nullable field '×××××' to ××××× without specifying a default. This is because the database needs something to populate existing rows.
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 2) Quit and manually define a default value in models.py.
Select an option:
```
Models.pyで定義したフィールドに設定する要素が足りていない状態を指摘されている。

# 解決方法
Models.pyの各フィールドに
`blank = False, null = False` を追加する。

許容するとき：True
許容しないとき：False
のように、適切なものを設定する必要がある。

修正後、下記コマンドを実行するとテーブル定義が更新された。
`$ python manage.py makemigrations`
`$ python manage.py migrate`
【個人開発向け】Googleドライブ上にGitリモートリポジトリを作る

## 概要
gitを使い始めたばかりで自分一人きりの個人利用ということで、理解を深める意味も込めてクラウドストレージ上にリモートリポジトリを作成しました。
Googleドライブに限らず、デスクトップアプリで同期できるクラウドストレージサービスにおいては、同様の手法で運用可能だと思います。

## 環境インストール
1.パソコン版Google Driveをインストール
2.gitをインストール
```
$ brew install git 　　　　　　　　　　　　　　 #MacならHomebrewが簡単
> winget install git.git   #WindowsならWingetが簡単
```

## リモート用ベアリポジトリを作成
1.Google Driveに「<ディレクトリ名>.git」フォルダを作成
```
$ 　mkdir g:\マイドライブ\Project\<ディレクトリ名>.git
$ 　cd g:\マイドライブ\Project\<ディレクトリ名>.git
```

2.ベアリポジトリを作る
```
$ 　git init --bare --shared
```

## 実ファイル転送用ノンベアリポジトリを作る
1.実ファイル転送用ノンベアリポジトリをGoogle Driveの任意の場所にcloneする
```
$ git clone 'g:\マイドライブ\Project\<ディレクトリ名>.git'
```

## ローカルマシン側に作業ディレクトリを作成する
1.作業ディレクトリ用ノンベアリポジトリをローカルマシン側の任意の場所にcloneする
```
$ cd c:\Project
$ git clone 'g:\マイドライブ\Project\<ディレクトリ名>.git'
```

2.リモートリポジトリへpushする
```
$ cd <ディレクトリ名>
$ touch hoge.txt
$ git add.
$ git commit -m 'First　Commit'
$ git push origin master
```
cloneしているのでremote設定はclone元に設定されている

## ベアリポジトリからノンベアリポジトリにpullする
１．Googleドライブ上のベアリポジトリから実ファイル転送用ノンベアリポジトリへpullしてみる
```
$ cd g:\マイドライブ\Project\<ディレクトリ名>　　　　　　　　　　#ベアリポジトリからノンベアcloneすると.gitがつかないディレクトリができる
$ git pull origin master
```
ローカルマシン側からpushしたファイルが転送できていれば成功

## ベアリポジトリからノンベアリポジトリへ自動転送設定
1.ベアリポジトリにノンベアリポジトリへのリモート設定をする
```
$ 　cd g:\マイドライブ\Project\<ディレクトリ名>.git
$ git remote add origin g:\マイドライブ\Project\<ディレクトリ名>
```
いらないかもしれないけど、念の為に設定しておく
　

2.post-receiveを作成
ベアリポジトリの.git/hooksにpost-receiveを作成
```
cd .git/hooks
touch post-receive
```

post-receiveに下記コードを追加
```
#!/bin/sh

cd /c/Project/<ディレクトリ名> || exit
unset GIT_DIR
git pull origin master
```
コードの内容は、
・ローカルマシンからpushを受け取ると
・自動でノンベアリポジトリにカレントディレクトリを移動
・pullを実行する

3.post-receiveの実行権限を付与
```
$ chmod 755 post-receive
```
忘れずに。

## ローカルマシンからpush
1.ローカルマシン側からpushする
```
$ cd /c/Project/<ディレクトリ名> 
$ touch hogehoge.txt
$ git add.
$ git commit -m 'Second　Commit'
$ git push origin master
```
自動的にノンベアリポジトリへ実ファイルが転送されていれば成功
【React】ルートコンポーネントファイルとは

# ルートコンポーネントファイルとは
Reactのルートコンポーネントファイルは、通常、Reactアプリケーションのエントリーポイントとして機能します。これは、アプリケーション全体のメインコンポーネントであり、他のすべてのコンポーネントを含む階層構造のトップレベルです。通常、このファイルは `index.js` または `App.js` のような名前を持ちます。

ルートコンポーネントファイルは、次のような役割を果たします。

1\. **アプリケーションのエントリーポイント** : ブラウザーがReactアプリケーションを読み込むときに最初にロードされるファイルです。

2\. **ルーティングの設定** : Reactルーターを使用して、アプリケーション内の異なるURLパスに対して異なるコンポーネントを表示します。

3\. **グローバルステートの管理** : 必要に応じて、グローバルステートのコンテキストや状態管理ライブラリを初期化し、アプリケーション全体で共有するデータを管理します。

4\. **レイアウトの定義** : アプリケーション全体のレイアウト構造を定義し、ヘッダーやフッターなどの共通コンポーネントを含めることができます。

一般的に、ルートコンポーネントファイルは以下のような形式を取ります。
```jsx
// App.js または index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

import Home from './components/Home';
import About from './components/About';
import Contact from './components/Contact';

const App = () => {
  return (
    <Router>
      <div>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/contact" component={Contact} />
        </Switch>
      </div>
    </Router>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));
```

この例では、`App` コンポーネントがルートコンポーネントとして機能し、`react-router-dom` を使用してルーティングを設定しています。ReactDOMによって、`App` コンポーネントがHTMLのルート要素にレンダリングされます。
【React】デフォルトエクスポートとは

# デフォルトエクスポートとは
Reactのデフォルトエクスポート（export default）は、モジュールから1つだけエクスポートする方法です。モジュール内で1つのコンポーネントや関数、クラス、またはオブジェクトをデフォルトとしてエクスポートすることができます。このようにエクスポートされた要素は、インポート時に名前を変更することなく利用できます。

# 使用方法
例えば、以下のようにReactコンポーネントをデフォルトエクスポートすることができます。
```jsx
// MyComponent.js

import React from 'react';

function MyComponent() {
  return <div>Hello, World!</div>;
}

export default MyComponent;
```

この場合、`MyComponent`はデフォルトエクスポートされており、他のファイルでインポートする際には以下のように書くことができます。
```jsx
import MyComponent from './MyComponent.js';
```

`export default`を使用すると、インポート時に任意の名前を付けることができます。上記の例では、`MyComponent`がデフォルトエクスポートされているため、インポート時に任意の名前（ここでは`MyComponent`）を指定できます。

一方、`export`文を使用してエクスポートする場合、エクスポートする変数や関数の名前を指定する必要があります。この場合、インポート時に指定した名前でエクスポートされた変数や関数を使用する必要があります。
```jsx
// MyFunction.js

export function myFunction() {
  return 'Hello, World!';
}
```

このようにエクスポートされた関数は、インポート時に同じ名前で使用する必要があります。
```jsx
import { myFunction } from './MyFunction.js';
```

# まとめ
デフォルトエクスポートは、ファイルごとに1つの要素をエクスポートする必要がある場合や、エクスポートされる要素が単一である場合に便利です。一方で、`export`文を使用すると、複数の要素をエクスポートすることができるため、柔軟性があります。
【React】export と export default の違い

# export と export default の違い
Reactコンポーネントをエクスポートする場合、`export`と`export default`の2つの方法があります。これらの違いは以下の通りです。

1\. **export** : export文は、コンポーネントを名前付きエクスポートします。名前付きエクスポートを行うため、インポートする際には波括弧 {} を使用して、エクスポートされたコンポーネントの名前を指定する必要があります。
```jsx
// MyComponent.js
export const MyComponent = () => {
  return <div>Hello, World!</div>;
};
```
```jsx
// 別のファイルでのインポート
import { MyComponent } from './MyComponent';
```

2\. **export default** : `export default`文は、コンポーネントをデフォルトエクスポートします。デフォルトエクスポートされたコンポーネントは、インポートする際に任意の名前を使用することができます。名前がなく、ファイル全体から1つのエクスポートだけを行いたい場合に便利です。
```jsx
// MyComponent.js
const MyComponent = () => {
  return <div>Hello, World!</div>;
};

export default MyComponent;
```
```jsx
// 別のファイルでのインポート
import MyComponent from './MyComponent';
```

通常、コンポーネントが1つしかない場合は`export default`を使用し、複数のコンポーネントをエクスポートする場合は`export`を使用します。ただし、どちらを使用しても機能的には同じです。
【React】Gatsbyとは

# Gatsbyとは
Gatsbyは、Reactベースの静的サイトジェネレーター（SSG）およびフレームワークです。Gatsbyを使用すると、高速でセキュアなウェブサイトやウェブアプリケーションを構築することができます。以下に、Gatsbyの特徴と機能の概要を示します。

# 特徴
1\. **Reactベース** : GatsbyはReactをベースにしており、Reactのコンポーネントベースの開発パターンを使用してウェブサイトやアプリケーションを構築できます。

2\. **静的サイトジェネレーター** : Gatsbyは静的サイトジェネレーターとして動作し、ビルド時にすべてのページをHTML、CSS、JavaScriptにプリレンダリングします。これにより、高速な読み込み速度とSEOの向上が実現されます。

3\. **GraphQL**: GatsbyはGraphQLを使用してデータをクエリすることができます。データソースからのデータを取得し、コンテンツを管理することができます。さまざまなデータソース（Markdownファイル、API、データベースなど）からデータを取得できます。

4\. **プラグインシステム** : Gatsbyは豊富なプラグインエコシステムを提供しており、ウェブサイトやアプリケーションに必要なさまざまな機能を追加できます。画像の最適化、SEOの改善、データの取得などのためのプラグインが利用可能です。

5\. **ホスティングの柔軟性** : Gatsbyは静的なファイルを生成するため、ほとんどのホスティングプラットフォームで簡単にデプロイできます。NetlifyやVercelなどのサーバーレスプラットフォームとの統合も容易です。

6\. **パフォーマンス** : Gatsbyは最適化された静的ファイルを生成するため、高速な読み込み速度を提供します。また、サイトのパフォーマンスを向上させるためのベストプラクティスを備えています。

Gatsbyは、静的なブログ、ポートフォリオ、企業のウェブサイト、電子商取引サイトなど、さまざまな種類のウェブプロジェクトに適しています。
文字列から特定の文字列だけ抜き出したい時の正規表現はどう書いたらいいの？

目的の文字列を抜き出す方法がわからず困ったのでうまく行った正規表現の書き方をメモしておきます。
結論から言うと正規表現の先読み、後読みを利用して特定の文字列を抽出できました。
今回はRubyで試しています！

## 先読み、後読みとは
 :::note info
- `(?=ex)` : 先読み。次に`ex`がくる位置にマッチする
- `(?<=ex)` : 後読み。前に`ex`がくる位置にマッチする
- `(?!ex)` : 否定先読み。次に`ex`がこない位置にマッチする
- `(?<!ex)` : 否定後読み。前に`ex`がこない位置にマッチする
:::

## 文字列と文字列の間から文字列を抜き出してみるパターン
`cat`に格納された`Cat:tama_mike`という文字列から'tama'だけを抜き出してみます。

```irb
> cat = "Cat:tama_mike"
> cat.match('(?<=\:).*(?=_)')
 => #<MatchData "tama"> 
 ```

 - `(?<=\:)`：後読みを利用して、コロン(:)が前にくる位置を指定。コロンは記号なのでバックスラッシュでエスケープし、`\:`と書きます。
 - `.*`：任意の1文字(`.`)を0回以上繰り返す(`*`)という意味。
 - `(?=_)`：先読みを利用して、次に`_`が来る位置にマッチさせています。

これで`tama`だけが抜き出せました！

## 文字列と改行の間の文字列を抜き出してみるパターン
以下のようにJSON形式で整えられたデータを用意しました。

```irb
> require "json"
> hash = {"key" => { "name" => "tama", "color" => "yellow" }}
> json_str = JSON.pretty_generate(hash)
> puts json_str
{
  "key": {
    "name": "tama",
    "color": "yellow"
  }
}
 => nil 
 ```
今回はこの改行コードが入ったデータから`"yellow"`だけ抽出してみます。
```irb
 > json_str.match('(?<="color": ).*(?=\n)')
  => #<MatchData "\"yellow\""> 
```
 - `(?<="color": )`：後読みを利用して、`"color": `が前にくる位置を指定。
 - `.*`：任意の1文字(`.`)を0回以上繰り返す(`*`)という意味。
 - `(?=\n)`：先読みを利用して、次に改行コード(\n)が来る位置にマッチさせています。

データを扱う際に色々応用できそうですね！

### 参考
- [先読みと後読みを使ったパターン](https://www.javadrive.jp/regex-basic/writing/index2.html "先読みと後読みを使ったパターン")
SQLにおけるNULLについて

## SQLにおけるNULLの危険性について

こんにちは、jjj0331です。、
今回はSQLのNULLに関する特性や。デメリットについてご紹介したいと思います。
本記事を通してNULLの危険性を理解し、NULLの撲滅に共感して頂けると幸いです。

### NULLを使う目的
SQLでNULLが挿入される目的は
データを挿入しなければならないが、一部の列の値がまだ決まっていない場合に「無」「不明」の意味を込めてNULLを挿入します。
SQLがNULLを持ち込んだことにより、**3値論理**を持ち込まざるをえなくなり大きな混乱を生み出しました。

**3値論理**とは、真理値が「true」「false」の2つの値だけではなく、「**unknown**」という第三の値を持つ理論体系を指します。一般的なプログラムが2値論理を採用していることからSQLの3値論理が多くのプログラマーの混乱をまねくことになりました。



## NULLを許容したことによるデメリット
SQLでは仕方なくNULLを許容することはありますが、
極力NULLの使用は避けたほうが良いです。
それは、NULLのデメリットが大きすぎるためです。

- 条件式を書く場合に、3値論理を考慮する必要がある
- 「is NULL」「 is not NULL」と書かないとNULLを判定できない
- 四則演算や関数の引数にNULLがあると期待値が得られない
- DBMSによりNULLの扱い方が異なる
- Oracleの場合、is NULLを使用するとインデックスが使用されない

## NULLを撲滅するために
- 値が決まっていない場合を想定しあらかじめ未定コードを用意しておく
- 数字列の場合は0で代用 ※0と不明を分けなくてもよい場合
- 列に**NOT NULL**制約を宣言する

## それでもNULLは撲滅できない
すべてのテーブルに**NOT NULL**制約を宣言したとしても、NULLは発生します。
外部結合やCUBEを使用することで簡単にNULLは入り込んできます。
というわけで、
SQLを使う上で、NULLは避けられないので、常に気を付けましょう
【React】Remixとは

# Remixとは
Remixは、ウェブアプリケーションを構築するためのフレームワークであり、サーバーサイドレンダリングやクライアントサイドレンダリングなどの技術を組み合わせて、高速でパフォーマンスの高いアプリケーションを作成することを可能にします。Remixは、Reactをベースにしたアプリケーションの開発に焦点を当てています。

# 特徴
Remixの主な特徴は次のとおりです。

1\. **サーバーサイドレンダリングとクライアントサイドレンダリングのハイブリッドアプローチ** : Remixは、サーバーサイドでの初回のレンダリングと、クライアントサイドでのインタラクティブな操作におけるレンダリングの両方をサポートしています。これにより、高速な初期読み込みと滑らかなユーザーエクスペリエンスを実現します。

2\. **ルーティング** : Remixは、簡潔で柔軟なルーティングシステムを提供し、ネストされたルーティングやパラメータ付きルーティングなどをサポートしています。

3\. **データローディング** : ルートコンポーネント内でデータのフェッチやプリロードを行うための統一された仕組みを提供し、データの取得を簡単かつ効率的に行うことができます。

4\. **コードスプリッティング** : Remixは、コードスプリッティングをサポートし、必要なコードのみをユーザーに提供することで、初期ロード時間を最適化します。

5\. **自動プリフェッチング** : ユーザーの操作に基づいて自動的にデータをプリフェッチする機能を提供し、ユーザーエクスペリエンスを向上させます。

6\. **フルスタック** : フロントエンドとバックエンドの両方をカバーし、データベースや認証などのバックエンド機能も組み込むことができます。

Remixは、Reactの開発者向けに設計されており、Reactの概念やパターンに沿った開発が可能です。
【React】複数のstateの同時更新

# 複数のstateの同時更新
Reactで複数の状態（state）を同時に更新するには、`useState`フックの代わりに`useReducer`フックを使用することがあります。`useReducer`フックは、複雑な状態ロジックを持つコンポーネントや、複数の状態をまとめて管理したい場合に便利です。

# 使用方法
以下は、`useReducer`フックを使用して複数の状態を同時に更新する方法の例です。
```jsx
import React, { useReducer } from 'react';

// 初期状態
const initialState = {
  count: 0,
  text: ''
};

// reducer関数
const reducer = (state, action) => {
  switch (action.type) {
    case 'increment':
      return { ...state, count: state.count + 1 };
    case 'decrement':
      return { ...state, count: state.count - 1 };
    case 'setText':
      return { ...state, text: action.payload };
    default:
      return state;
  }
};

function MyComponent() {
  // reducer関数と初期状態を渡してstateとdispatch関数を取得する
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>Decrement</button>
      <input
        type="text"
        value={state.text}
        onChange={(e) => dispatch({ type: 'setText', payload: e.target.value })}
      />
    </div>
  );
}

export default MyComponent;
```
この例では、`useReducer`フックを使用して`reducer`関数と`initialState`を渡して、`state`と`dispatch`関数を取得します。`dispatch`関数を使用してアクションを送信し、`reducer`関数によって新しい状態が計算されます。`dispatch`関数は、アクションを受け取り、それに基づいて状態を更新するために使用されます。このようにして、複数の状態を同時に更新することができます。
【React】入力値の取得

# 入力値の取得
Reactで入力値を取得するためには、通常はコンポーネントの状態（state）を使用します。入力フィールド（input要素など）にユーザーが入力した値は、コンポーネントの状態に格納され、必要に応じて取得や更新が行われます。

# 使用方法
以下は、Reactで入力値を取得する基本的な方法の例です。
```jsx
import React, { useState } from 'react';

function MyForm() {
  // 入力値を格納する状態を初期化する
  const [inputValue, setInputValue] = useState('');

  // 入力値が変更されたときに呼ばれるハンドラー関数
  const handleInputChange = (event) => {
    // 入力値を更新する
    setInputValue(event.target.value);
  };

  // フォームが送信されたときに呼ばれるハンドラー関数
  const handleSubmit = (event) => {
    // フォームのデフォルトの動作を防止する
    event.preventDefault();
    // 入力値を使用して何かを行う（例：サーバーにデータを送信する）
    console.log('入力された値:', inputValue);
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* 入力フィールド */}
      <input
        type="text"
        value={inputValue} // 状態に格納された値を表示する
        onChange={handleInputChange} // 入力値が変更されたときにハンドラー関数を呼び出す
      />
      {/* 送信ボタン */}
      <button type="submit">送信</button>
    </form>
  );
}

export default MyForm;
```

この例では、`useState`フックを使用して`inputValue`という状態を定義し、その初期値を空文字列で設定しています。`handleInputChange`関数は、入力値が変更されるたびに呼び出され、新しい入力値を状態に設定します。`handleSubmit`関数はフォームが送信されると呼び出され、現在の入力値をコンソールに出力します。
【jQuery】ユーザー作成時の初期画像の設定

# 手順
jQueryを使用してユーザーの初期画像を設定する場合、一般的な手法は次のとおりです。

1\. **画像の選択** : ユーザーがプロフィール画像をアップロードするフォームを提供します。ユーザーが画像を選択しなかった場合やアップロードが完了するまでの間、デフォルトの初期画像を表示する必要があります。

2\. **初期画像の表示** : ページがロードされたときやユーザーが画像を選択しなかった場合に、初期画像を表示します。これはHTMLの`<img>`要素を使用して実現できます。
```html
<img id="profile-image" src="default-image.jpg" alt="Profile Image">
```

3\. **ユーザーが画像を選択したときの処理** : jQueryを使用して、ユーザーが画像を選択したときに初期画像を置き換える処理を実装します。
```js
$('#file-input').change(function() {
  var file = $(this)[0].files[0];
  var reader = new FileReader();

  reader.onload = function(e) {
    $('#profile-image').attr('src', e.target.result);
  };

  reader.readAsDataURL(file);
});
```

上記のコードでは、`file-input`というIDを持つファイル入力フィールドに変更があった場合に、選択された画像を読み取ってプレビューとして表示します。`profile-image`というIDを持つ画像要素の`src`属性を選択された画像のデータURLに置き換えることで、画像のプレビューを更新します。

4\. **サーバーへの画像のアップロード** : ユーザーが画像を選択し、プロフィール画像を変更したときに、選択された画像をサーバーにアップロードする処理を実装する必要があります。これは通常、バックエンドの技術（Node.js、PHP、Pythonなど）を使用して実装されます。

以上の手順に従って、jQueryを使用してユーザーの初期画像の設定を実装することができます。
【Rails】一覧表示の順番を指定する(古い順、新しい順)

こんばんは！
ポートフォリオ実装でユーザーの使いやすさを考えたときに、一覧といってもものによっては古い順、新しい順と変えた方がよさそうだと気づき、実装してみました！
実装自体はコントローラ―の記述を少し加えるだけだったので、ご紹介したいと思います。

## 環境
AWS Cloud9
Rais 6系

## 方法
### 新しい順
例えばですが、普通の投稿の一覧などはより新しい情報をユーザーに見せたいですよね！特に投稿１つ１つに文脈などの関係がない場合は新しい順の方が適しているといえます。
そのような場合どのように新しい順にするか説明したいと思います！

普段だと一覧表示をしたい際には
```rb:app/controller/xxxx_controller.rb
class XxxxsController < ApplicationController
  def index
    @posts = Post.all
  end
end
```
というように記述しますよね。これだと特に順番は指定されていない状態で、更新などがあると順番が変わる可能性があります。
そのため、新しい投稿などを上に表示させたい場合は
```rb:app/controller/xxxx_controller.rb
class XxxxsController < ApplicationController
  def index
    @posts = Post.all.order(created_at: :desc)
  end
end
```
というように、`.order(created_at: :desc)`を付け加えます。この付け加えた部分を分解して解説すると、`.order`はorderメソッドで、データの順序を変更するためのメソッドであり、その後ろの( )の中で`created_at`と書くことで作成された日時を参照できます。そして、`desc`というのは並び替えの降順(上から新しい順)で表示させることを示しています。つまり、**作成日時を降順で並び替えしてください**というような指示をしています。やりたかったことをしっかり指示できていますね！

#### 応用編
少し応用させると`created_at`の部分を`updated_at`などに変更すると、更新した日時が近いものから降順で表示してくれます。また、`created_at`の部分を`id`に変えるとidの降順で並べることができます。

## 古い順
コメント機能などは上から順を追っていかないと話の流れが分からないことがありますよね。そんな場合、古い順(昇順)で並べられるように指定してみましょう！

新しい順とほとんど同じですが、後ろの方に注目してください！
```rb:app/controller/xxxx_controller.rb
class XxxxsController < ApplicationController
  def index
    @posts = Post.all.order(created_at: :asc)
  end
end
```
古い順だと`.order(created_at: :asc)`を追記します！
今回新しく出てきた`asc`で昇順になるよう指定しています(orderメソッド、created_atの説明は上でしているので割愛します:bow_tone1:)。

## おまけ。asc, descは何の略？
asc: 昇順はascending orderともいい、ascもそこからきているようです。ascendingは直訳すると上昇で、イメージとしては小さい方から大きい方へ登っていくイメージです(0,1,2,3,4やあいうえおなど)。created_atの昇順と言葉でいうとイメージつきづらいですね。番号や配列などでイメージすると分かりやすいですが、古いものが小さい方にあたります。

desc: 降順はdescending orderといい、これも頭文字をとっていますね！こちらは大きい方から小さい方の順に並ぶというイメージで、created_atだと最新のものが大きい方にあたるので新しい順になります。


今回の説明はこれで以上です！
お疲れ様でした！
【kodi】YouTubeアドオンがインストールできない問題【Nexus】

## 前文
`Kodi`備忘録。

## 環境
| Pi | Raspberry Pi OS | kodi |
| ---- | ---- | ---- |
| 5B 4G | Raspberry Pi OS with desktop / 64-bit / bookworm 12.5 | 20.3 |

## 手動で inputstream.adaptive を入れるべし
[前回投稿](https://qiita.com/god19/items/02a479dc6c97c9e25087#kodi "Raspberry Pi 5 がやって来たヤァ!ヤァ!ヤァ!")の続き。リポジトリの整合性の問題でインストールに失敗する問題。
その内環境が整うのかと思いきや待てど暮らせど状況は変わらず。

改めてぐぐると、`inputstream.adaptive`は手動で入れる必要があるとのこと。

[Kodi - missing Inputstream.Adaptive](https://dietpi.com/forum/t/kodi-missing-inputstream-adaptive/18895/4 "Kodi - missing Inputstream.Adaptive - Troubleshooting - DietPi Community Forum")
```shell
sudo apt-get install kodi-inputstream-adaptive
```

実は当初から手動で入れる試みはしていて、zipファイルを DL し、Kodi上のアドオン管理画面から入れようとするも失敗していた。
単純にコマンドラインからインストールすれば良かっただけでござる。

これで無事YouTubeアドオンのインストールが完了した。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/d417b106-5a9a-9917-9f03-9c33e28a7ede.png" width=80%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/c5b14f03-1f74-a0da-0bb6-c0a2077b48d4.png" width=80%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/93cd6ff6-b514-2b8b-3a83-d2940942c261.png" width=80%>

## 一難去ってまた一難
ところがここ数日、以下のエラーを突然吐くようになり YouTube動画が再生できなくなった。
`Player response failed for video_id: v5_xxxxxxxx using android client (logged in).`

エラーメッセージでぐぐると以下がヒット。公式フォーラムにも同様の報告が挙がっていて正に現在進行形の問題の模様。
[Kodi Community Forum](https://forum.kodi.tv/showthread.php?tid=356934&pid=3186994#pid3186994 "YouTube")


[YouTubeアドオン公式github](https://github.com/anxdpanic/plugin.video.youtube/releases "Releases · anxdpanic_plugin.video.youtube")から最新の`v7.0.3.2`を DL し、手動でインストールするべし、とのこと。
こちらも無事問題解決。
多分 YouTube API 側の仕様が変わって問題が発生していた系と思われ。

そうこうしているうちに 5V/5A電源アダプタも入手、SSD起動環境に移行。
徐々に環境を整えている感じ。
引き続きぼちぼちとやっていく予定。
【StoryBook】コンポーネントを作成しカタログに登録してみる

# はじめに
StoryBookのインストールからコンポーネントをカタログに登録するところまで
学んだのでアウトプットのための本記事を作成してます。
本記事のゴールとしては自作のUIをカタログに登録し使用する事とする。


# 環境
next：14.0.4
tailwindcss：3.4.1
storybook": 7.6.9

# SotryBookのインストール

次のコマンドでSotryBookのインストール。
```
npx storybook@latest init
```

インストールが終わると、プロジェクト直下に`.storybook`のディレクトリが作成される。

https://storybook.js.org/docs/get-started/install

# tailwindcssの適用
tailwindcssをドキュメントに沿ってインストール。

https://tailwindcss.com/docs/guides/nextjs

`preview.ts`に以下のインポートを追加。
これによりglobal.cssが読み込まれtailwindcssが有効になる。

```
import '../src/styles/globals.css'
```


# コンポーネントの作成
今回は正方形のコンポーネントを作成する。
`stories`フォルダの直下に`Square.tsx`と`Square.stories.ts`フォルダを作成。
tailwindcssでしているする色の濃ゆさを3パターン準備し、
テンプレートリレテラルで背景色部分を設定してます。

```tsx:Square.tsx
type Props ={
    ColorIntensity:200| 400 | 600;
};

export const Square = ({ColorIntensity}:Props) => {
    let bgColor = `bg-blue-${ColorIntensity}`;

    switch(ColorIntensity) {
        case 200:
            bgColor = 'bg-blue-200';
            break;
        case 400:
            bgColor = 'bg-blue-400';
            break;
        case 600:
            bgColor = 'bg-blue-600';
            break;
    }

  return (
    <div className={`${bgColor} w-20 h-20 p-2 rounded`} />
  )
}
```

# メタデータの作成

コンポーネントのメタデータを定義していきます。
ストーリーのコンポーネント、タイトル、カタログ上の設定を行う。

```ts:Square.stories.ts
import { Meta, StoryObj } from "@storybook/react";
import { Square } from "./Square";

type Story = StoryObj<typeof meta>;

const meta:Meta<typeof Square> ={
  // ストーリーのコンポーネント
  component: Square,
  // ストーリーのタイトル
  title: 'Example/Square',
  argTypes:{
    ColorIntensity: {
      // カタログにおけるControlの表示形式
      control: { type: 'inline-radio'},
      options: [200, 400, 600]
    }
  },
  // ドキュメントの作成
  tags:['autodocs']
};

export default meta;

export const SampleSquare:Story = {};
```

ここまで出来たら以下のコマンドで起動してカタログを確認してみます。
```
npm run storybook
```

カタログにUIが表示されている事を確認できました。

![storysample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/8c34f6f8-e86c-f080-2a40-1ab2069f2c98.gif)

以下の記述により自動でコンポーネントのドキュメントを作成できます。

```tsx
tags:['autodocs']
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/40049398-f8c3-06aa-b306-7e90a470016e.png)


# 参考

https://storybook.js.org/docs/get-started/install

https://storybook.js.org/docs/essentials/controls
PenguinHack 2024を開催しました


2024/3/7(木)と3/8(金)にペンギンハックという学生向けハッカソンを実施しました！

https://x.com/hacks_penguin/status/1765661829026525580?s=20

ご参加いただいた皆様、メンターとしてお手伝いいただいた皆様、スポンサーいただいた各社様、運営を一緒に行なっていただいた皆様、本当にありがとうございました！

第二回目となるこのイベントの開催報告を行うとともに、参加を検討していただいている学生や、企業の方に向けて、ペンギンハックとはどのようなイベントなのかお伝えできればと思います！

## 当日の様子
開催日両日とも、九州工業大学 飯塚キャンパスで開催しました。
参加者は14名、メンターや運営を含めると40~50名ほどが会場に一同し、ハッカソンを実施しました。

特にこのハッカソンの特徴は「参加者にメンターが1on1で2日間つく」ことであり、参加者が14名程度であるにも関わらず、倍以上の人間が開発をしている状態はペンギンハック特有の雰囲気です。

会の開始直後は、参加者が持ち寄ったアイデアをメンターと一緒にブラッシュアップするチームがほとんどのため、ガヤガヤしたり、弛緩した空気になります。このタイミングで、私が1チームずつインタビューをして回りましたが、「今どんな感じですか？」と聞くと、参加者もメンターも笑顔で、進捗やアイデア、今後の方針について話してくれました。

その後、運営が用意した地元の美味しい個人店に発注したお弁当を配り、お昼ご飯を終えたら、少しずつ開発に皆さんが没頭していきます。

https://x.com/nrslib/status/1765574590947086782?s=20

会場の都合で、夜の20:30から翌日の8:30まで参加者は帰宅をしますが、翌朝になると、皆さんの顔つきが大きく変わります。

コードフリーズが近づくにつれ、会の雰囲気はヒリヒリしたものになり、休憩していたメンターの方も「参加者とペアでやるからこそ、自分にも時間内に完成させるための責任が乗っかって大変だ」とおっしゃってました。もうこのタイミングはどのチームも話しかけることができないくらい集中しています。

https://x.com/hacks_penguin/status/1765901914628305141?s=20

発表会では、1週間前まで、reactを触ったことがない学生が、reactを用いたwebアプリのデモを全員がこなしました。機能は全て揃っていなくても、基本的なCRUDを操作のデモはほとんどのチームが実装しました。そこから賞を取るチームは、自身で見つけたライブラリを使用したり、外部サービスのAPIを使用したりして、自身が考えたwebアプリを動かしました。

https://x.com/hacks_penguin/status/1765983793947758860?s=20

今年も多くの関係者の皆様のおかげで無事開催することができました。

ペンギンハックでは、「初心者がとりあえずイベントに参加してみて、何もできずに終わる、その場限りで終わる」という挫折をできるだけ取り除くような企画・運営を目指しています。

まだまだ実現の途中ではありますが、もし参加して、「もっとこうなればいいのに」と思った方は、twitterの@omotidaisukijpまでお気軽にご連絡ください。次回以降の開催の参考にします。

また、次年度の開催も計画しており、興味のある方がいらっしゃれば、こちらも@omotidaisukijpまでお気軽にご連絡ください。


## 補足: ペンギンハックとは何か
ここからは、来年度以降のペンギンハックに参加を考えられている学生の方、何かしらのご協力を検討いただいている企業様向けの説明です。

ペンギンハックとは、これまで授業ではプログラミングについてよく学んだ学生に対して、そこから一歩先に進む支援をするためのイベントです。対象学生は以下のような悩みを持っていたり、挫折をしています。

* プログラミングを使って、何を作れるかわからない
* ハッカソンや外部のLT会などに出てみたが、よくわからないまま終わってしまった
* 同じ学生の上級者を見て、心が折れてしまった
* インターンや就活の選考に通らず、諦めかけている

私自身が上記のような挫折を学生時代にしたのですが、インターン先で先輩にペアプロをしていただき、少しずつできるようになっていった経験から、「インターンや企業、コミュニティに入れていない学生でも、ペアプロを通じて、プログラミングでものづくりができることを知ってもらいたい」という思いで開催しています。

ペンギンハックでは初心者に手厚いサポートをするために、以下のような形式で実施しています。
1. ハッカソンでは40~100名程度の参加者を集め実施するイベントが多い中、15名前後と、少ない参加者で実施している。参加者が少ない代わりに、全員に1on1でまる2日間メンターがつき、ペアプロする。
2. ハッカソン当日までに、原則参加のブートキャンプを3日程度実施している。参加できなかった学生は、その分のカリキュラムを宿題として行なってもらう。
3. いろんなコミュニティや企業に支援をもらい、学生がペンギンハックを参加した後に、インターンや、イベント参加、コミュニティ参加を推奨している。ペンギンハックに参加した後に、エンジニアの世界に飛び込む機会を提供したい。

初心者に手厚いイベントを、多くのメンターとともに開催できるのは、大学周りや福岡のエンジニアコミュニティが盤石であること。すでに多くのハッカソンやLT、カンファレンスなどのイベントが存在していること。その上、多くの関係者に支えられていることに他なりません。

イベントの形式上、参加者数を増やしにくいイベントではあるのですが、継続して開催することで、世代が変わっても同様のチャンスが学生に与えられることが重要だと考えています。

できるだけ多くの学生に、世代を超えてこの機会を提供することを目指しながら、これからも運営を続けていく予定です。
##
【Next.js】Canonical Tag

# Canonical Tagとは
Canonicalタグは、検索エンジン最適化（SEO）のために使用されるHTMLのメタタグの1つです。Canonicalタグは、複数の同一または類似したコンテンツがある場合に、そのコンテンツの正規な（主要な）バージョンを指定するために使用されます。これにより、検索エンジンは重複したコンテンツを適切に認識し、インデックスする際に問題が生じるのを防ぎます。

# 使用方法
Next.jsのCanonicalタグは、ページの`<head>`セクション内に追加されます。以下は、Next.jsでCanonicalタグを設定する方法の例です。
```js
// pages/some-page.js

import Head from 'next/head';

function SomePage() {
  return (
    <div>
      <Head>
        <title>Some Page</title>
        <link rel="canonical" href="https://example.com/some-page" />
      </Head>
      <h1>This is Some Page</h1>
      {/* コンテンツ */}
    </div>
  );
}

export default SomePage;
```

この例では、`<Head>`コンポーネント内でCanonicalタグが設定されています。`<link>`要素のrel属性には`canonical`が指定され、`href`属性には正規なURLが指定されています。このCanonicalタグにより、検索エンジンはこのページが他の類似したコンテンツの正規バージョンであることを理解し、適切にインデックスすることができます。
【Next.js】APIルートとは

# APIルートとは
Next.jsのAPIルートは、Next.jsアプリケーション内でサーバーレスのAPIエンドポイントを定義するための特別なディレクトリです。このディレクトリ内のファイルは、サーバーサイドで実行されるAPIエンドポイントとして機能し、クライアントからのリクエストに対してデータを返すことができます。

通常、APIルートは`/pages/api`ディレクトリに配置されます。このディレクトリ内の各ファイルは、HTTPリクエストに対応するAPIエンドポイントを表します。たとえば、`/pages/api/users.js`ファイルは`/api/users`パスに対応し、ユーザーに関するデータを返すAPIエンドポイントとして機能します。

APIルートのファイルは、通常のReactコンポーネントとは異なり、以下のルールに従う必要があります。

1\. ファイルのエクスポートは、APIエンドポイントのハンドラー関数である必要があります。この関数は、リクエストオブジェクトとレスポンスオブジェクトを受け取り、データを返す役割を果たします。

2\. APIルートのファイルは、サーバーサイドでのみ実行されることを意味するため、クライアントサイドのコードは含まれません。

以下は、簡単なAPIルートの例です。
```js
// pages/api/hello.js

export default function handler(req, res) {
  res.status(200).json({ message: 'Hello, Next.js API!' });
}
```

このファイルは、`/api/hello`エンドポイントにアクセスした際に`{ message: 'Hello, Next.js API!' }`というJSONデータを返します。APIルートを使用することで、Next.jsアプリケーション内で簡単にサーバーレスのAPIを作成し、クライアントからのリクエストに応答することができます。
【Next.js】PostCSS 構成のカスタマイズ

# PostCSS 構成のカスタマイズ
PostCSSの構成をカスタマイズするには、通常はプロジェクトのルートにある`postcss.config.js`ファイルを編集します。このファイルには、PostCSSプラグインやオプションを定義することができます。以下は、基本的な`postcss.config.js`ファイルの例です。
```js
module.exports = {
  plugins: [
    require('autoprefixer'), // ベンダープレフィックスを自動的に追加する
    require('cssnano')({ preset: 'default' }) // CSSを圧縮する
  ]
}
```

この例では、`autoprefixer`プラグインがベンダープレフィックスを自動的に追加し、`cssnano`プラグインがCSSを圧縮します。PostCSSのプラグインは`require`関数を使用して読み込まれ、`plugins`配列に追加されます。

プラグインを追加するだけでなく、PostCSSのオプションを設定することもできます。たとえば、ブラウザーの対応バージョンを指定することができます。
```js
module.exports = {
  plugins: [
    require('autoprefixer')({
      browsers: ['last 2 versions', 'not dead', '> 0.2%']
    })
  ]
}
```
また、PostCSSの構成をより細かくカスタマイズするために、プラグインのオプションを設定したり、プリセットを使用したりすることもできます。プロジェクトのニーズや要件に合わせて、構成を調整してください。
【TypeScript】オブジェクトの全てのプロパティを必須にする方法

以下のように`Required<T>`を使用するとオブジェクトの全てのプロパティを必須にできます。

```ts
type User = {
  id?: string
  name?: string
}
  

const currentUser: Required<User> = {
  id: "1",
} 
// Error: property 'name' is missing.
```
【Next.js】SWRとは

# SWRとは
Next.jsのSWR（Stale-While-Revalidate）は、データ取得のためのReactフックであり、リアルタイムなデータの取得とキャッシュ管理を簡素化するために設計されています。SWRは、データのキャッシュを使用してコンポーネントのレンダリングを最適化し、非同期データの再取得を制御します。

# 特徴
SWRの主な特徴は次のとおりです：

1\. **キャッシュとリフレッシュ** : SWRは、データをキャッシュし、必要に応じて自動的に再取得します。キャッシュされたデータは即座に使用され、同時にバックグラウンドで最新のデータをフェッチし、キャッシュを更新します。

2\. **リアルタイムデータの取得** : SWRは、リアルタイムでデータを取得するためにWebSocketなどのリアルタイム通信プロトコルをサポートします。これにより、サーバー側でデータが更新されると、クライアント側のキャッシュが自動的に更新されます。

3\. **フォールバックとエラーハンドリング** : データの取得中にエラーが発生した場合、SWRは自動的にエラーを処理し、フォールバックデータを提供することができます。また、タイムアウトや再試行間隔などのカスタマイズも可能です。

4\. **シンプルなAPI** : SWRはReactフックとして提供され、シンプルなAPIを介して使用することができます。データのフェッチやリフレッシュ、キャッシュの更新などを自動的に処理します。

SWRは、Next.jsアプリケーションでのデータ管理を効率化し、ユーザーエクスペリエンスを向上させるのに役立ちます。特にリアルタイムなデータの表示やキャッシュの最適化が必要な場合に有用です。
【Next.js】ユーティリティ関数とは

# ユーティリティ関数とは
Next.jsのユーティリティ関数とは、Next.jsアプリケーションの開発やビルドプロセスを効率化するために使用される関数のことです。これらの関数は、一般的なタスクを自動化したり、コードの再利用性を高めたりするのに役立ちます。

一般的なNext.jsのユーティリティ関数には、次のようなものがあります：

1\. **getStaticProps/getServerSideProps** : 静的生成ページやサーバーサイドレンダリングページで使用され、データを取得してページにpropsとして渡すための関数です。

2\. **getStaticPaths** : 動的なルーティングが定義されたページで使用され、ビルド時に生成されるパスのリストを定義するための関数です。

3\. **Link** : ナビゲーションやページ遷移を実現するためのコンポーネントです。内部的には、プリフェッチやプリレンダリングの機能が備わっています。

4\. **Image** : 画像の最適化とレンダリングを容易にするためのコンポーネントです。自動的に適切な画像サイズを選択し、レスポンシブな画像を提供します。

5\. **useRouter** : ルーティング情報へのアクセスを提供するフックです。現在のURLやクエリパラメータなどの情報を取得することができます。

6\. **Head**: ページのヘッダー情報（タイトル、メタデータ、スタイルシートなど）を動的に操作するためのコンポーネントです。

7\. **useEffect** : Reactのフックであり、コンポーネントがマウントされた後や更新された後に副作用を実行することができます。例えば、データの取得やDOMの操作などが含まれます。

これらのユーティリティ関数は、Next.jsの開発プロセスを効率化し、より迅速かつ柔軟な開発を可能にします。
表示灯作成

LEDマトリクス（HUB75 32*32）で表示灯を作ってみた。
LED顯示屏上顯示了標誌。

ビットデータを計算するのは結構手間だったけど意外と簡単に作れた。
沒有想像中複雜。只花兩三個小時就能完成了。

![IMG_7452.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3120035/bba83943-b161-986b-e072-5e3829289506.jpeg)

![IMG_7453.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3120035/2b21e266-554e-9afb-6250-5c29802000ed.jpeg)

使ったのはESP32を2機。（1機でも点灯はさせられるが、wifiで表示切替えできるように2機使用した。）
為了可以用WiFi控制標誌，用了兩個ESP32單晶片。
Rails 7 + Vue.js 3 でaxiosを使ったAPI通信で遭遇したエラーとその解決

Rails 7とVue.js 3を組み合わせた開発では、非同期通信のためにaxiosを利用する場合があります。この記事では、axiosを使用してAPI通信を試みた際に発生したエラーと、その解決方法について説明します。

## 問題点

Vue.jsコンポーネントでaxiosを使用しようとした際に、次のようなエラーが発生しました。

```bash
ViteRuby::MissingEntrypointError in Tasks#index
Showing /path/to/app/views/tasks/index.html.erb where line #8 raised:

Vite Ruby can't find entrypoints/tasks.js in the manifests.

Possible causes:
  - The last build failed. Try running `bin/vite build --clear --mode=development` manually and check for errors.

Errors:
  The CJS build of Vite's Node API is deprecated. See https://vitejs.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.
  x Build failed in 112ms
  error during build:
  Error: [vite]: Rollup failed to resolve import "axios" from "app/javascript/components/DraggableCalendar.vue".
  This is most likely unintended because it can break your application at runtime.
```

このエラーは、`DraggableCalendar.vue`でaxiosをインポートしようとしたところ、Viteがaxiosのモジュールを解決できずにビルドに失敗したことを示しています。

## 解決方法

### Step 1: axiosのインストール確認

まず、axiosがプロジェクトに正しくインストールされているかを確認します。ターミナルで次のコマンドを実行し、axiosをインストールします。

```bash
npm install axios
```

### Step 2: Viteのビルドを再実行

axiosのインストール後、Viteのビルドプロセスをクリアしてから再実行します。これにより、新たにインストールしたaxiosがビルドプロセスに含まれます。
※このプロセスを飛ばしてもエラー解消することはよくあります。

```bash
bin/vite build --clear --mode=development
```

このコマンドは、ビルドキャッシュをクリアして開発モードでビルドを実行します。これにより、以前のビルドで発生した問題を解消できます。

### Step 3: ブラウザのキャッシュをクリア

ビルドが成功した後、ブラウザのキャッシュをクリアしてからページを再読み込みします。これにより、axiosを含む新しいビルドが正しく読み込まれるようになります。
※このプロセスを飛ばしてもエラー解消することはよくあります。

## axiosとは？

axiosは、ブラウザやNode.jsで動作するプロミスベースのHTTPクライアントです。REST APIへのGET、POST、PUT、DELETEなどのHTTPリクエストを簡単に行うことができます。プロミスベースであるため、非同期処理を扱う際に`.then()`や`.catch()`、`async/await`構文と組み合わせて使用することができ、非同期通信のコードをシンプルに書くことが可能です。

```javascript
// GETリクエストの例
axios.get('https://api.example.com/data')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error(error);
  });
```

axiosはその使いやすさから、Vue.jsやReactなどのフロントエンドフレームワークと組み合わせてよく使用されます。

## まとめ

Rails 7とVue.js 3の開発において、axiosを使用したAPI通信は強力な機能を提供します。しかし、セットアップ中に問題が発生することがあります。この記事で紹介した手順を通じて、エラーを解決し、非同期通信の実装を進めることができます。