OmniAICreator/Qiita-1.07M huggingface dataset:
App Runnerを使用して安くホスティングしたい

:::note warn
この記事は、[Supershipグループ Advent Calendar 2023](https://qiita.com/advent-calendar/2023/supership)の18日目の記事になります。
:::

# はじめに
AWS上にアプリケーションをホスティングしようと考えた際に、EC2やFargateを使用する等いくつかのパターンが考えられます。
その中で、App Runnerのコスト計算方法が少し特殊で、これを利用すれば安くホスティングできるのではないかと考えたため、まとめます。
# App Runnerとは
AWS App Runnerとは、AWS上でコンテナ化されたアプリケーションを構築・運用できるフルマネージドサービスです。

https://aws.amazon.com/jp/apprunner/

Codebuildからデプロイ環境までマネージドしてくれるサービスであり、Githubのソースコードをビルド・デプロイ、もしくはECRのビルド済みコンテナを用いてデプロイすることもできます。
GithubにソースコードをpushするとApp Runnerが検知して、かいい感じにデプロイまでしてくれるのでとても便利と感じました。

AWSのECR Public Galleryを用いるとコンテナイメージを準備せずにApp Runnerを気軽に試すこともできます。

https://gallery.ecr.aws/

# 特徴
今回のテーマである「App Runnerを使用して安くホスティングしたい」について関係するApp Runnerの特徴です。

### Auto Scalingの方式
ECS等他のAWSのサービスにおいてはCPU使用率等のしきい値を設定してオートスケーリングを設定するかと思います。
それに対して、App Runnerでは"リクエスト数"を監視し、オートスケーリングを行います。
アプリケーションに対してリクエストが無い場合はインスタンス数が0となります。

### プロビジョンドインスタンス
インスタンス数が0の場合はプロビジョンドインスタンスと呼ばれるインスタンスが立っている状態になるようです。
CPUスロットリングされたインスタンスが数ミリ秒以内にリクエストに対して対応するような状態になるため、コールドスタートの問題を気にすること無く使用することができます。

# コスト
App Runnerのコストについてです。

https://aws.amazon.com/jp/apprunner/pricing/

ECS等の他のサービス同様に、立っているインスタンス数と時間に対して設定したCPUとメモリサイズからコストが算出されます。
AWSのサービスはマネージドの範囲が広がれば広がるほどどうしてもコストが上がってしまうため、ベースはECSと比較すると高めの設定になっています。

ここで注目すべき点は「アプリケーションに対してリクエストが無い場合はインスタンス数が0となる」部分です。
つまり、リクエストがない時間帯に関してはインスタンスが立っていない状態になるため、CPU分のコストが発生せず、メモリに対してのみの課金となります。
常時CPU・メモリ共に課金される他のサービスと違ってこの点はかなり優位と言えます。

1つリクエストがあった場合は最低1分間分の料金がかかり、その後、プロビジョンドインスタンスに戻ることになるようです。
```
コンテナインスタンスの処理はすべて 1 秒ごとに請求され、1 秒未満は切り上げられます。
プロビジョニングされたコンテナインスタンスがリクエストの処理を開始するたびに、vCPU リソースに対して 1 分間分の最低料金が発生します。
```

App Runnerにおいて「リクエスト」とは、外部のサービスからのリクエストになるようです。つまり、Route53からヘルスチェックを設定すると、リクエストと判定されるので常時インスタンスが立っている状態になります。
ただし、App Runner内部の機能としてヘルスチェックがありますが、こちらはリクエストとしてカウントされないようです。

# おわりに
App Runnerのコストについて調べてみましたが、常時立ち上げておきたい個人利用のアプリケーション等にはかなり良いのではないかと感じました。
ホスティングしたいアプリケーションに対してどのくらいの頻度でリクエストがあるのかにもよるかと思いますが、個人的にはFargate等から置き換えることにより安くなるのではないかと感じました。

:::note
**最後に宣伝です。**

Supershipではプロダクト開発やサービス開発に関わる人を絶賛募集しております。
ご興味がある方は以下リンクよりご確認ください。
[Supership 採用サイト](https://supership.jp/recruit/)
是非ともよろしくお願いします。
:::
Goでテストを書く

# Goでテスト
標準パッケージの`testing`を用いたテストの書き方についてみていきます。

テスト対象は先日作成した多層キャッシュプログラムです。

https://qiita.com/shuyaeer/items/f77ce597c4b55dec57ad


テスト対象↓
```go:adapters/redis_adapter.go
package adapters

import "github.com/go-redis/redis"


type  RedisAdapter struct {
	client *redis.Client
}

func NewRedisAdapter() *RedisAdapter {
	return &RedisAdapter{
		client: redis.NewClient(&redis.Options{
			Addr:     "localhost:6381",
			Password: "",
			DB:       0,
		}),
	}
}

func (adapter *RedisAdapter) Get(key string) string {
	val, err := adapter.client.Get(key).Result()
	if err != nil {
		return ""
	}
	return val
}

func (adapter * RedisAdapter) Set(key string, value string) {
	adapter.client.Set(key, value, 0)
}

func (adapter * RedisAdapter) Delete(key string) {
	adapter.client.Del(key)
}j
```

命名規則としてファイル名の末尾は`_test.go`である必要があります。
```bash
touch adapters/redis_adapter_test.go
```

関数名の命名規則は`Test`から始まる必要があります。
```go:adapters/redis_adapter_test.go
package adapters

import (
	"testing"
)

func TestRedisAdapter_Get(t *testing.T) {
	adapter := NewRedisAdapter()

	adapter.Set("key", "value")
	want := "value"
	got := adapter.Get("key")

	if got != want {
		t.Error("失敗")
	}
}
```
`testing`に`assert`関数は無いため、期待と実際が異なった際に、
`t.Error("失敗")`にしています。

### テスト実行
```bash
 go test ./adapters

ok  	in_memory_cache_demo/adapters	0.286s
shuyafukushima@Shuya:~/programing/in_memory_cache_demo
```
`-v`オプションをつけることでより詳細な出力を得ることができます。
```bash
go test -v ./adapters
=== RUN   TestRedisAdapter_Get
--- PASS: TestRedisAdapter_Get (0.02s)
PASS
ok  	in_memory_cache_demo/adapters	0.124s
```
【Rails】preloadとeager_loadの個人的な使い分け

# 概要
RailsでN+1問題を解決する際によく使われる`preload`と`eager_load`の違いと個人的な使い分け方針をまとめました。

# 背景
先日実務で扱っているアプリケーションにて、メモリ使用率が急上昇しプロセスがダウンしてしまうトラブルがありました。原因は、ActiveRecord関連の処理で**JOINやLEFT_JOINを複数回重ねたSQLが発行**されており、その結果膨大な件数のレコードがRailsに返却され、それらのオブジェクトがメモリ上に展開されてしまったというものでした。

上記の経験から、普段何気なく使っている`preload`や`eager_load`も場合によってはメモリを圧迫しかねないのではと思い、改めてこれらの処理が何をしているのかを理解し利用方針を整理することにしました。

# 詳細
### 仕組みの違い
preload, eager_loadいずれも関連先のレコードをキャッシュしてくれるものですが、その仕組みには以下のような違いがあります。

|| preload | eager_load |
|----| ---- | ---- |
|キャッシュ方法| 関連先毎にクエリを発行 | 関連先をLEFT OUTER JOINで結合 |
|SQL発行回数| 結合元で1回+関連先数分 | 1回 |
|結合先での絞り込み| 不可 | 可能 |

 - `Article.preload(:comments)`で実行されるSQL
```sql
-- 1. articlesテーブルから全ての記事を取得
SELECT * FROM articles;

-- 2. commentsテーブルから必要なコメントを一度のクエリで取得
SELECT * FROM comments WHERE article_id IN (1, 2, 3, ...);
```
 
 - `Article.eager_load(:comments)`で実行されるSQL
```sql
-- articlesテーブルとcommentsテーブルを結合して、全ての記事とコメントを一度のクエリで取得
SELECT articles.*, comments.* FROM articles
LEFT OUTER JOIN comments ON comments.article_id = articles.id;
```

### 使い分け
いずれも関連先のデータをキャッシュするため、関連先のレコード数が膨大な場合はメモリを大量に消費してしまう可能性があり注意が必要です。以下に個人的な使い分け方針をまとめます。

#### ①関連先で絞り込みが必要 → eager_load
`preload`は関連先での絞り込みができません。
なお関連先のキャッシュは不要で単に関連先で絞り込みを行いたいだけの場合は、補足に記載の`joins`を使いましょう。(メモリが節約できる。)

#### ②複数の関連先をキャッシュしたい → preload(関連先のレコード数にもよる)
もし`eager_load(:comments, :author)`のように、`eager_load`で複数の関連先をキャッシュしようとした場合、LEFT OUTER JOINが複数回実行されるため、結合後のテーブルのレコード数が膨大になり、パフォーマンスの低下やメモリを大幅に消費する恐れがあります。複数の関連先をキャッシュする場合は、`preload`で関連先の数分クエリを発行したほうが高速かつメモリの消費も抑えられる可能性が高いです。

#### ③その他の場合 → まずはpreload、遅い場合はeager_load
関連先での絞り込み不要で、１つの関連先をキャッシュする場合は、まずは`preload`を試してみることをお勧めします。この場合は`preload`でも発行されるSQLは2文であるため、`eager_load`の場合(LEFT OUTER JOINS)と比較してもそこまで性能の差は出ないのではと考えています。もし`preload`で遅いと感じる場合は`eager_load`を試してみる、といった流れでもよいのではないでしょうか。

本番運用開始から日数が経過するにつれてDBのレコード数はどんどん増えていきます。
リリース当初は`eager_load(LEFT OUTER JOIN)`でも問題なかったが、ある時期からパフォーマンスの低下が謙虚になった、というケースも考えられなくはないため`preload`を選択したほうが事故は起きにくいのかなという気がしています。


# 補足
 - includesについて
`includes`は状況によって`preload`として働いたり、`eager_load`として働いたりと予期せぬ挙動を取りかねないため、直接preloadまたはeager_loadを使うことをお勧めします。
 - joinsについて
`joins`は関連先の項目で絞り込みをしたい場合に使われます。`preload`や`eager_load`と異なり関連先をキャッシュしません。

# 余談
本題と少し逸れますが、複雑なSQLを1つ実行するよりも、単純なSQLを複数回実行する方がパフォーマンス、リソース面で優れている場合も多いようです。これについては、SQLアンチパターンという書籍で、「スパゲティクエリ」という章でも述べられています。

https://www.oreilly.co.jp/books/9784873115894/
Udemyで設計力を高めるためにこのSOLID原則の講座を学ぶことをおすすめしたい

この記事は[Udemyおすすめ講座をシェアしよう！ by Udemy Advent Calendar 2023](https://qiita.com/advent-calendar/2023/udemy)のシリーズ2の19日目です。

# おすすめする講座
私がおすすめする講座はつぎです。
講師は**ピーコック アンダーソンさん**でSOLID原則の解説講座の3シリーズです。

https://www.udemy.com/user/anderson-355/

* オブジェクト指向の原則１：単一責務の原則とオープンクローズドの原則
* オブジェクト指向の原則２：リスコフの置換原則と継承以外の解決方法
* オブジェクト指向の原則３：依存関係逆転の原則とインタフェース分離の原則

https://www.udemy.com/course/objectfive1/

https://www.udemy.com/course/objectfive2/

https://www.udemy.com/course/objectfive3/


# 講座受講の背景
今年度はソフトウェア設計力を高めることを目標にしていました。
SOLID原則を学び、自社・自社以外に勉強会を開催することを考えていました。
SOLID原則を学べるコンテンツを探していたところ、ピーコック アンダーソンさんのSOLID原則のシリーズを知り受講しました。

# おすすめする理由
おすすめの理由です。

## SOLID原則の解説、コードをセットで説明してくれるところ
講座の構成ですがSOLID原則の解説だけではなく、コードを提示し解説してくれています。
原則はどういうものか理解できた後にそれをどうコードで表現するのか解説してくれるので理解度が増します。
講座のコードはC#となっています。
それほど難易度が高いC#のコードは登場しないので、C、C++がメインで組込みソフトウェア領域の私でも理解できました。

## 原則違反するとどのような影響があるか説明してくれるところ
原則違反するとどのような影響があるのか、解説してくれます。
コードで具体的に提示してくれるので、なぜ原則違反しない方が良いのか?、を解像度高く理解できます。

## 原則違反、原則に則った解説をセットで比較して説明してくれるところ
原則に違反した場合、原則に則った場合の解説を比較して説明してくれるのでわかりやすいです。

## 付加価値がある説明
SOLID原則の技術的な説明に加え、高い視座・考え方を提示してくれています。

## SOLID原則のエッセンスを後輩にどう伝えるのか、のヒント
SOLID原則とはこういうものだから従おう、では後輩には伝わりにくい。
どのような説明をすれば伝わるかの観点で解説してくれています。
具体的には[オブジェクト指向の原則１：単一責務の原則とオープンクローズドの原則](https://www.udemy.com/course/objectfive1/)シリーズのオープンクローズドの原則で説明されている**拡張ポイント**の説明です。

## 依存性注入の具体的事例
[オブジェクト指向の原則３：依存関係逆転の原則とインタフェース分離の原則](https://www.udemy.com/course/objectfive3/)シリーズでは依存関係逆転の原則をテーマに解説しています。依存性注入についても解説しています。
依存性注入は自動テストの文脈で説明されることが多いと思います。
講座の中ではつぎの項目を解説してくれています。

* 自動テストとはどういうものか
* 自動テストの問題
* 自動テストを依存性注入で解決する方法
* モックについての説明
* Moqを使って自動テストする方法

依存性注入の説明だけ出てもひとつのコンテンンツにできる濃度を感じとても参考になりました。
私はここで学んだことを参考にさせてもらい、組込みソフトウェア開発でよく使われるCppUTestのモックをつくり、学習の振り返り・実践を行いました。


# 個人的に特におすすめするコンテンツ
個人的に特におすすめする講座は[オブジェクト指向の原則２：リスコフの置換原則と継承以外の解決方法](https://www.udemy.com/course/objectfive2/)です。
この講座を受講する前まではリスコフの置換原則がいまいち理解できていませんでした。
この講座を受講後はリスコフの置換原則について理解が深まりました。
この講座をおすすめする理由を書きます。

## 圧倒的ボリューム!!!
リスコフの置換原則の講座だけでトータル3時間24分という圧倒的ボリュームです。

## 継承のガイドラインについての説明が丁寧でわかりやすい!!!
リスコフの置換原則は継承の説明に触れると思います。
この講座では継承自体の説明から継承以外の方法でリフコフの置換原則に違反しない解決方法を丁寧に、コードと一緒に解説しています。
紹介されている継承以外の解決方法を視聴、理解すれば継承についての理解が深まります。
継承以外の解決方法を紹介しているチャプターはつぎのとおりです。

* L29_継承以外のアイデア1_別で作る
* L32_継承以外のアイデア２_持つという考え方
* L38_アイデア３_共通化という解決
* L42_アイデア４_最小カプセル化という解決

## 継承の使いところの説明が参考になった
講座の多くの時間を継承に変わる解決方法に割いています。
講座の終盤のつぎの章で継承のつかいところについて解説・コードで説明してくれています。

* L48_共通要素をまとめる継承
* L49_共通要素をまとめる継承の実装例

個人的にこの説明が非常にわかりやすかったです。
講座のコード例はWindowsフォームの例でしたが自分の組込みソフトウェアの領域でも継承の使いところについて学習・調査・模索していきたいと感じました。
【Git】プッシュしたいブランチに既に別のコミットがプッシュされていた際にやったこと

タイトルの問題を解決する際に行なったことをまとめます．
類似の問題が発生した際の参考としていただけると幸いです．

:::note warn
投稿主はGitの経験が浅いため，本記事で紹介する内容は不正確，または遠回りなものである可能性があります．
:::

# 問題の詳細

![Screenshot 2023-12-17 at 14.34.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483756/478c5dc9-12a8-bb97-81b4-f9ab176dec18.png)

コミット２を基にコミットAをローカルで作成したが，いざリモートにプッシュしようとするとコミット２から派生したコミットBが既にプッシュされていた，という問題です．

# 解決の形
コミットBを取り消すことは望ましくなかったため，**コミットAでの変更をコミットBに反映することで解消する**，ということを解決の形としました．

なお，コミットAとコミットBで扱うファイル数は同じ，コミットA-コミットB間で名称が異なるファイルは存在しないものとします．

# 実際に行なったこと
## 1. コミットAの内容をスタッシュに保存する

コミットAの内容をスタッシュに保存します．

![コミットAの内容をスタッシュに保存](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483756/c383a54d-c564-2f25-9420-2928b58023f8.png)

```
# コミットAの内容をスタッシュに保存
$ git stash

# コミットAの内容をスタッシュに保存（新規作成ファイルも保存する場合）
$ git stash -u

# スタッシュへの保存を確認
$ git stash list
```

スタッシュへの保存を確認したら，コミットAのあるブランチに移動します．
```
$ git checkout [コミットAのあるローカルブランチ名] 
```

## 2. リモートの最新コミットBの内容をローカルに持ってくる

コミットAの内容をリセットしてコミット２の状態（コミットAをコミットしていない状態）に戻します．

![コミットAをリセット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483756/c0579e85-a20b-a319-3d0c-bd3fbc31dff6.png)

こうすることで，コミットBの内容をローカルにプルすることが可能となります．

```
# コミットAをリセット
$ git reset --hard [コミットAのハッシュ値]
```

続いて，コミットBの内容をローカルに反映します．反映先は先ほどリセットコマンドで戻ったコミット２になります．

```
# コミットBをプル
$ git pull [リモートリポジトリURL] [コミットBのあるリモートブランチ名]
```

## 3. スタッシュをコミットBにマージする
ここまででローカルにもコミットBが反映された状態となるので，ローカルのコミットBに先ほど保存したスタッシュの内容をマージします．

![ローカルにコミットBが反映された状態](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483756/29468cb6-95b8-3d53-dfa7-dd53f0f3dfc6.png)

```
# スタッシュの内容をローカルのコミットBにマージ
$ git merge stash
```

コミットBにマージしてできたコミットをコミットCとします．

## 4. マージ後のコミットCをリモートにプッシュする

![スタッシュマージ後](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483756/7e4fa5ad-910b-6f8d-47a1-72c2ba8672df.png)

これでローカルの最新コミットであるコミットCは，コミットBから派生し，かつコミットAの変更を反映したコミットであるため，リモートのコミットBの先にプッシュすることが可能です．

このコミットCをリモートにプッシュします．

```
$ git push [リモートリポジトリのURL] [コミットCのあるローカルブランチ名]
```

以上で，求める解決の形が実現できました！
【Go言語】定数の使い方

変数や引数などに代入して利用する値のことを、まとめて**定数**と呼ぶ。
Go言語の**定数**の扱い方について、その特性と利用方法を説明する。

### 型のない定数の定義
Goでは、`const`キーワードで定数を定義できる。
実行時ではなく、コンパイル時に定数の値が計算されるため、実行時のコストは発生しない。

```go
const (
    a = 1
    b = 1 + 2 // 演算も可能
    c = 9223372036854775807 + 1 // uint64を超える数値も可能
    d = "hello world" // 文字列定数
)
```

### 型付き定数の定義
型を指定して定数を定義することもできる。

```go
type ErrorCode int

const (
    f int = 10
    code ErrorCode = 10
)
```

### `iota`について
`iota`識別子を使用して連即した定数を簡単に作成することができる。

#### サンプル
```go
const (
    Sunday = iota  // 0
    Monday         // 1
    Tuesday        // 2
    Wednesday      // 3
    Thursday       // 4
    Friday         // 5
    Saturday       // 6
)
```
`iota`は式の一部としても使用できる

```go
const (
    Bit0 = 1 << iota  // 1 << 0 == 1
    Bit1              // 1 << 1 == 2
    Bit2              // 1 << 2 == 4
    Bit3              // 1 << 3 == 8
)
```

`const`ブロックを分けることで`iota`の値をリセットすることができる

```go
const (
    Apple = iota // 0
    Grape        // 1
    Orange       // 2
)

const (
    Cat = iota // 0 (新しいconstブロックでリセットされる)
    Dog        // 1
)
```


## 参考
https://qiita.com/curepine/items/2ae2f6504f0d28016411

https://www.oreilly.co.jp/books/9784873119694/
【React】イベントハンドラーの型指定

イベントハンドラーの型指定は以下のように行います。

```tsx
export function Sample() {
  const onChange = (e: React.FormEvent<HTMLInputElement>) => {
    console.log('sample')
  }
  return (
    <div>
      <input type="text" onChange={onChange} />
    </div>
  )
}
```

または以下のようにします。

```tsx
export function Sample() {
  const onChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
    console.log('sample')
  }
  return (
    <div>
      <input type="text" onChange={onChange} />
    </div>
  )
}
```


- イベントの型一覧

https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/forms_and_events/#list-of-event-types
JOJOを例にして見やすいコードを書いていくで part1

# はじめに
まいど。大阪生まれ大阪育ち、4年目エンジニアの「スイッチくん」っていうもんや
初心者の時はそれはそれは見るも無惨なコードを書いてきたワイやが、
泣きそうになるほどの先輩の厳しいレビューや素晴らしい書籍のおかげでましなコードを書けるようになってきた
そこで、ワイが普段気をつけていることを書いていくで
プログラミングうまい人からすれば「そんな当たり前なこと何いっとんねんな」と思うかもしれないが、
知らない人はこれを知っておくことで見やすいコード書けるようになるから是非みたって～

今日は、「ガード節」について説明していくで

# ガード節
ガード節とは、条件分岐の後、早めにreturnなどで処理を終わらせることや
ん？全然意味わからない？？ほなワイが今ハマっているJOJOを例えにして詳しく説明していくで
例で定義している関数は、名字と第何部かの変数を受け取り、その部に応じた主人公を返すものや
名字がジョースターじゃない時点で主人公ではないのが確定するので、空文字を返してるで

```:ガード節使用例.js
fucntion getJOJOMainCharacter(firstName, part) {
    if (firstName !== 'ジョースター') {
        return '';
    }
    
    if (part === 'one') {
        return 'ジョナサン';
    }

    if (part === 'two') {
        return 'ジョセフ';
    }

    if (part === 'three') {
        return '承太郎';
    }

    return '';
}
```
見ての通り、各条件内に入った場合に該当する値をreturnで返してるやろ
これをするメリットは主に以下や
・該当の条件で処理が終わるので、それ以外の条件内は見なくすむ。結果、見やすいコードになる
・ネストが短くなる

逆にガード節使わんかったらこんな感じや
```:非ガード節使用例
fucntion getJOJOMainCharacter(firstName, part) {
    const mainCharacterName = '';
    
    if (firstName === 'ジョースター') {
        if (part === 'one') {
            mainCharacterName = 'ジョナサン';
        }
    
        if (part === 'two') {
            mainCharacterName = 'ジョセフ';
        }
    
        if (part === 'three') {
            mainCharacterName = '承太郎';
        }
    }
    
    return mainCharacterName;
}
```
見ての通り、最初に主人公の変数を定義し、各部に該当する主人公を変数に格納して最後にreturnしてるやろ
最初の「ガード節使用例」と比べてどうや？？ネストは深くなっとるし、該当条件の処理に入った後でも違う条件の処理みないとあかんやろ？？
こういうあかんところがなくなるから「ガード節」がいいんや
だから使ってない人がいたら積極的に使っていくんやで
ワイ？？先輩に「ガード節使わんやつはカス」って言われてから使うよう意識しとるで～（泣）
SQLServer のオートナンバー(Is Identity)の値で無理やり 0 のレコードを作成するとバグる？

ASP.NET Core MVC にてスキャフォールディングで作ったマスタ画面で
従業員マスタを更新（Update）したところ、なぜか同じデータが「追加」された。
他のマスタでもほぼ同様のつくりをしているがこのような現象は発生しない。

コード上の違いは見つからない。。

たまたま本番から流用したデータに自分専用の従業員用データを追加して更新のテストを行っていたのだが、試しに違うデータを更新したところ普通に更新される。

自分専用の追加されてしまったデータにて更新を行ったところ普通に更新される。

このレコードが他のレコードと違うところは主キーであるIDが「0」であること。
通常。オートナンバーは1から開始されるはず。

おそらく初期に自分でテスト用に無理やり作ったデータだと思われる。
一旦、そのレコードを消して良しとした。

下手すれば一生解決できなかったかもしれない。。
Elixir　IEx.Helpersの知ってると便利かもしれない機能

# はじめに

iexって何気なくつかってるんですが、Elixirの関数を試しに実行してみるとかくらいしか使ってませんでした。
マニュアルみてみたら、知らない機能もあったので、探索してみました。

https://hexdocs.pm/iex/1.14/IEx.Helpers.html

# i/1
引数に渡した値の情報を表示。protocolsが出るのはいいかも。

```Elixir
iex(10)> i([1,2,3])
Term
  [1, 2, 3]
Data type
  List
Reference modules
  List
Implemented protocols
  Collectable, Enumerable, IEx.Info, Inspect, List.Chars, String.Chars
```

# i/0
タプルって、Enumerableじゃないんですよね。
```
iex(12)> {1,2,3}
{1, 2, 3}
iex(13)> i
Term
  {1, 2, 3}
Data type
  Tuple
Reference modules
  Tuple
Implemented protocols
  IEx.Info, Inspect
iex(14)>
```

# open

openコマンドで、エディターを開けるらしいのでやってみます。
まず環境変数で開くエディターをセットする（VSCodeを開く場合の例）
```
ELIXIR_EDITOR="code --goto"
```

open(開きたいモジュール名)を実行
```Elixir
iex(2)> ls
elixir101.ex     user.ex
iex(3)> open(User)
iex(4)>
```

VSCodeが開きました。
.exのファイル名を指定するのではなく、モジュールで開けるところが面白いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/759fdfe3-38a5-6ac4-d4a3-a8d125317ec4.png)

# recompile

これは、たまに使います。
ソースを変更した時に、recompileを実行した時に実行中のiexに反映するときに使います。

```Elixir
iex(4)> recompile
Generated elixir101 app
:ok
iex(5)>
```
# runtime_info

あまり使う事ないかもしれないけど、試してみました。
いろいろな情報が表示されます。

```Elixir
iex(5)> runtime_info

## System and architecture

Elixir version:     1.14.4
Erlang/OTP version: 25
ERTS version:       13.2.2
Compiled for:       x86_64-pc-linux-gnu
Schedulers:         8
Schedulers online:  8

## Memory

Total:              28 MB
Atoms:              576 KB
Binaries:           43 KB
Code:               13 MB
ETS:                904 KB
Processes:          5 MB

## Statistics / limits

Uptime:             7 minutes and 23 seconds
Run queue:          1
Atoms:              19921 / 1048576 (1% used)
ETS:                28 / 8192 (0% used)
Ports:              3 / 65536 (0% used)
Processes:          66 / 262144 (0% used)

Showing topics:     [:system, :memory, :limits]
Additional topics:  [:applications]

To view a specific topic call runtime_info(topic)

iex(6)>
```

# v/0 v/1

引数の値のヒストリーの値を返します。値を再利用するとき便利です。
v()だと直前の値になります。
知ってると何か使えそう。

```Elixir
iex(6)> [1,2,3]
[1, 2, 3]
iex(7)> {10,20,30}
{10, 20, 30}
iex(8)> v(6)|> IO.inspect()
[1, 2, 3]
[1, 2, 3]
iex(9)> v(7)|> IO.inspect()
{10, 20, 30}
{10, 20, 30}
```

# break!

ブレークポイントを設定して実行して、実行中の状態を確認する事ができます。
Userモジュールのprint関数で止めてみて、userの値を表示してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/93ff2c60-f29d-c2be-017c-d80ddfa0ba70.png)


いろいろあるので皆さんもみてみてください。
IPMessenger

[インターネット老人会の魔法書 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/ancient-internet) の10日目の記事です。

# IPMessengerとは

このアプリを入れている同士でメッセージを送れる通信ツール。
ローカルIPに対して送れるので、インターネットにつながっていないイントラネットでも使える。
添付ファイルも送れる優れもの。
なんとコマンドでも送れる。

# 無料で簡単に使えるチャットアプリがなかった時代に重宝

今でこそ無料でもある程度はSlackなりChatworkなりで簡単にチャットの環境が用意できるが、そういうのがなかった時代は、有料のそういうサービスを使うか、構築するしかなかった。

そんな時代に、このIPMessengerは重宝した。
プロジェクトによってはインターネット環境がないところもあり、そういうところだとEメールも使えないので、こういったイントラネットで通信できるものは大変便利だった。

今でもそういう環境はあると思うので、そういうところでは結構使われているのではないかと思う。

# 誤爆も多かった

チャットでは部屋という概念があるので、同じ部屋で発言し続ける分には宛先など気にしなくてよいが、このIPMessengerは「宛先を選択して、メッセージを書いて、送信」という手順をとるため、宛先を間違えて誤送信してしまうケースがままあった。

よくあるのが、誰かの陰口をたたこうとして、その陰口の相手の名前が頭にあるせいか宛先に陰口の相手を選んでしまい、**陰口ではなく当人に思いっきりヘイトを送りつけてしまう**という事故が多々起きた。
送ったほうもすぐには間違えたことに気づいていないことが多く、後になって友達と話しているときに「そんなメッセージ来てないよ」と言われ、ログを見て青ざめるという寸法だ。

# Message attack

先に述べたようにコマンドでもメッセージを送ることができ、かつ、受け取り拒否の機能は（多分）ないので、無限ループでメッセージを送り続ければ相手のPCのリソースがなくなるまでメッセージウィンドウが次々と開き続け、最後にはハングアップさせることができた。
設計書って何を書くもの？

# はじめに
みなさんは設計書を書く際に気を付けていることはありますか？
今回は私が最近設計書レビューをしてて感じる事について記載していこうと思います。

# その設計書ただのメモ書きになってませんか？
何故この記事を書こうと思ったのかですが、
**「その設計書はあなたがコーディングをするためだけのものじゃない」**
ということをお伝えしたいためになります。

では、具体的に何を意識するのか。
* コーダーが何をどのように実装したいのか理解しやすい内容とする。
    * 設計を担当したものを自分が作るとは限りません。
* 保守・運用を行う際にどのような造りになっているのか分かりやすい内容とする。
    * 開発を行ったシステムを同じ人がそのまま保守・運用を行っていくとは限りません。

要するに、他人が見るドキュメントだということを意識してほしいということになります。

:::note info
自分が開発を行うためだけのものではなく、
チームとして開発～保守・運用を行うドキュメントであることを意識する。
:::

次の項では具体的に何を書くべきかについて記載していきます。
（具体的にと言いつつ抽象的な気もしなくもない・・・）

# 基本設計では何を書くのか
基本設計では要件定義をもとにシステムとして何を実現したいのかを記載していきましょう。
大まかにまとめると下記三点を意識できればよいと思います。
* 正常系の動作
* バリデーション
* 異常系の動作

この中で特に書かれてないと感じるのは異常系の動作です。
以下の三点は最低限基本設計で検討しておけるとよいと思います。
* エラーログの出力内容
* ユーザにどのように通知するか
    * 画面に表示するメッセージの出力方法や、バッチであればメールを送信する等
* リカバリをどのように行うか

:::note info
エラーが起きた際にどのように対応するかをしっかり検討しておく。
:::

# 詳細設計では何を書くのか
詳細設計では各モジュールの処理内容や関連性を明確にしましょう。
その上で書かれてないなと感じる事は下記三点です。
* 共通化
* どのようなライブラリを使用する想定なのか
* モジュール同士の関連性

詳細設計において設計者から感じることは
**「コーディングする際に考えればいいや」**
ということです。

自分がコーディングするのであればそれでも何とかなるかもしれません。
しかし、その記載レベルだとほぼ必ずと言っていいほどコーダーから質問が飛んできます。
（質問がない場合は全然違うものができたりします・・・。）
せっかく詳細設計書を書いたにもかかわらずそこでコミュニケーションに時間を取られるのはもったいないですよね。
コーダーが迷子にならないように各モジュールで実装するべき内容を明確に記載しましょう。

:::note info
誰がコーディングしてもコーディング内容に大きな相違が起きないレベルで記載する。
:::

# 余談
設計について記載してきましたが、コーディングの際のコメントも同様になります。
美しいソース（保守・改修・運用しやすいソース）というのはコメントも含めて完成するものだと思います。
得てして開発は時間が足りなくなりがちで、蔑ろになってしまう部分ではありますが、
そこで書いたあなたのコメントで救われる命があります（笑）

# まとめ
初めてこの様な記事を書かせていただきましたが、
「設計書に限らず各ドキュメントは他人が見ることを想定した記述レベルで書く」
ということがお伝えできていれば幸いです。
自分が何を表現したいか分からないドキュメントであれば他人は絶対に分かりません（苦笑）
どこまで書けばいいのか最初は難しいと思いますが、その際は周りの諸先輩方を頼りながら分かりやすいドキュメントを作成していきましょう。
[Protocol] プロトコル一覧　

## プロトコルについて、備忘録としてここに記す。

### 環境
- MacOS Monterey

### まとめ

||OSI基本参照モデル||TCP/IP||||
|:---|:---:|:--:|:---:|:--:|:---:|:--:|
|階層|階層名|階層|階層名|主なプロトコル|用途|ネットワーク機器|
|7|アプリケーション層|4|アプリケーション層|HTTP、FTP、SMTP等|メール、HP閲覧、ファイル転送|ゲートウェイ|
|6|プレゼンテーション層|"|"|"|"|"|
|5|セッション層|"|"|"|"|"|
|4|トランスポート層|3|トランスポート層|TCP、UDP|通信方式の選定|"|
|3|ネットワーク層|2|インターネット層|IP|相手先の特定|ルータ|
|2|データリンク層|1|ネットワークインターフェース層|ETHERNET、WIFI、PPP|物理的なLANケーブルでPCを接続、ルーターの接続|ブリッジ、スイッチングハブ|
|1|物理層|"|"||"|リピータ|



### ネットワーク機器
- #### ゲートウェイ：
    ネットワーク双方で使っているプロトコルの差異をなくす（本来、モバイルメールとWebブラウザメールは使用しているプロトコルが異なるため通信できないが、ゲートウェイを通過すことで通信が可能となる）
- #### ルータ：
    外部へパケットを転送（ブリッジは、MACアドレスが確認できる範囲のみで有効なため、外部のネットワークへの転送は不可能）
- #### ブリッジ：
    パケットのMACアドレス（次の送付先を示す情報）から、目的以外の送付先にパケットが流れ込まないよう制御
- #### リピータ：
    流れる電気信号の増幅

### 参考リンク
[OSI参照モデルとは？TCP/IPとの違いを図解で解説](https://www.itmanage.co.jp/column/osi-reference-model/)
[プロトコルとは？種類全部わかりやすく解説＆まとめ](https://ardent.jp/rentoffice-consultation-center/cloudpbx-info/wifi-vpn-network/protocol-matome/)
[【国家資格に挑戦!!】応用情報技術者試験～プロトコル一覧～ ](https://note.com/hiroyoshi1610/n/n1dd5ec18859e)
[IT初心者のための基本情報ではじめる OSI基本参照モデル 入門](https://www.seplus.jp/dokushuzemi/ec/fe/fenavi/learn_tech/osi_reference_model4beginners/#!)
リーダーの質問の意図は何か？

# はじめに
最近は実装よりも、リーダーとして進捗管理や要望の調整をしていることが多くなりました。
昔、「なんでリーダーはこんなことを聞くのだろう」と思っていたことに対する、今の私からの回答です。
人によっては違う意図で聞いてると思いますので、こんな考え方もあるという参考までに。
# 前提
私はエンジニアの育成もしている立場で、製品開発の管理とともにライン管理もしています。
リリーススケジュールを考慮して、開発を管理しつつ、勤怠管理をしつつメンバー育成をする立場です。
製品は機能でいくつかのチームに分かれていて、1つのバージョンに複数のチームの修正が入ってリリースされます。
# 通話での毎日の進捗確認
どんな状況かの確認です。開発進捗も勤怠も問題の芽をひろって対応するきっかけを作ろうとしています。
特に気にしているのはこのあたりですね。
- 体調不良だったりしないか？
- 休みを言い出せなかったりしてないか？
- 仕事量やレベルは適切か？
- どういう風に作業してるのか？簡単なやり方を知らなくて苦労してないか？
- 製品特有の作業手順を知らなくて間違ったことしてないか？
- 他のメンバーとコミュニケーションとれてるか？
# 勤怠チェックと修正依頼
基本的にリモートなのは開発だけなので、トラブルがあると制度の見直しや出社が基本に変わる可能性があります。そのため問題が起きないように神経をとがらせています。
ちょっとしたミスでもPCの稼働ログと本人の申告がずれたまま管理部門に届くと勤怠の虚偽になって大問題になります。
私のところで修正できれば問題にならないので少しでもおかしなところがあれば確認します。
ときには1分残業がおかしいとかのレベルで確認します。
# ボトルネックある？
誰かの作業が終わって無いのであれば、作業がスムーズに進むように確認や調整をしなければなりません。もしかしたら、スケジュールの引き直しが必要かもしれません。
状況を確認し改善手段の認識合わせをして、開発が進むような段取りをしようと思って聞いています。
# 行き詰まってない？次に何をするか具体的に見えてる？
できないと言い出せない人もいるのでこういう聞き方をしています。
行き詰まりかけてるとか、具体的な作業手順が説明できない場合はフォローをする必要があると判断します。
進捗がよくないときや、進捗報告が明確じゃないときによく使います。ただ、変な勘ぐりをされないように大丈夫そうな状況でも聞くように意識しています。
# どういう手順で進めてる？
製品特有の作業手順を知らなくて間違った作業になってないかを気にしています。
優先順位の考え方があっているかの確認をしたいときも使います。
# これ確認した？
よくテスト漏れや作業漏れになるやつですね。
心配な人に直接聞くこともありますが、一緒に話をしている別の人に気を付けて貰いたくて言うときもあります。
こっそり作業予定に追加して確認しておいてくれれば指摘しなくて済むので。
# どのくらいかかりそう？
現実的なスケジュール組みたいので聞いています。「スムーズに行けばxxくらい、経験則から言うと更にxxくらいかかる」と言うような回答だと嬉しいです。
関係者が無茶な日程を出してこないように、開発の見立てを先に出したくて聞いているときもあります。
# その心は？その意図は？
私は違うと思っているが、実はメンバーの意見も正しいかもしれないと思って聞いています。
話を聞いてみると以下のように色々なパターンがありますね。
- 前提条件が伝わってなかったり
- 考慮がたりてなかったり
- 私が間違ってたり
- メンバーが間違ってたり
# 終わりに
突然思い立って書いたので、よく聞く質問が抜けているかもしれません。
反応によっては続編を書くかも知れないです。
Turboについて理解するために役に立ったリンク集

# はじめに
本記事は錆びかけたRailsの知識を頑張ってアップデートするアドベントカレンダー15日目です。

筆者は現在、Rails7のHotWireを学んでいます。

HotWireを学ぶ教材として、猫Rails様の書かれた[猫でもわかるHotwire入門 Turbo編](https://zenn.dev/shita1112/books/cat-hotwire-turbo)を読み手を動かしています。

Hotwireについて学習していく中で追加で気になったことを調べており、その中でも役に立ったなと思うサイトを備忘録兼ねてまとめておきます。今後も随時更新していく予定です。

# 背景
Rails7について、特にHotWireについて集中的に学んでいます。手を動かして実際に起きたことや感じたことを自分なりにアウトプットすることで理解が深まりました。さまざまなリソースを参考にしていますが、その中でも特に役立ったものをちょっとした説明付きでまとめています。どのようなタイミングで読むべきかの参考になると嬉しいです。

# Hotwireを学ぶ上で役に立ったサイトまとめ

### 考え方を学ぶ
https://www.youtube.com/watch?v=i_x6poZ_NoU

まずHotWireとはどんなことができるのか、実際に画面の動きやコードとの対応を見ながら学習することができます。
情報量が多いので、目で追ったり耳で聞くなど様々な手段でインプットすることがおすすめです。

https://zenn.dev/kenzan100/articles/0f9b100655a4bf

https://zenn.dev/mizchi/articles/d33a4174cca886#%E3%83%95%E3%83%AD%E3%83%B3%E3%83%88%E3%82%A8%E3%83%B3%E3%83%89%E3%83%91%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%B3%E3%82%B9%E3%81%A8-rails-way

Railsが流行し、徐々にフロントエンドに辛さが出てきた過程、そしてサーバサイドとフロントエンドを分けて開発する体制がメジャーになっていきReact/TypeScriptが勃興していく様子がわかります。

さらに、そこからHotWireが何をしようとしているのかについても掴むことができます。

https://qiita.com/nazomikan/items/eab3352dbd5e2b79724b

こちらの記事も併せて読むことで、Railsの作者であるDHHがどのように考えてHotWireを作っていったのかがわかります。

### チュートリアル

https://zenn.dev/shita1112/books/cat-hotwire-turbo

日本語で書かれた圧倒的にわかりやすいチュートリアル。とりあえず何も考えずにこのチュートリアルを一通り読んで手を動かせば、HotWireは何ができてどのように記述するのかを効率良く学べます。作者の方に本当に感謝です。

https://gorails.com/series/hotwire-rails

動画でHotWireの具体例を学ぶことができるページです。全編英語ですが、コードを書いていく様子と合わせて見ることができるので、何をやっているかは一目瞭然です。

### 実際に使ってみた事例

https://note.com/everyleaf/n/n5c0f123b20a6

https://note.com/everyleaf/n/ndf30e8aad64a

[株式会社万葉様の技術ブログ](https://note.com/everyleaf/)が大変ためになりました。HotWire記事以外でも、仕事において大切なことなど学びがあるものばかりでした。

### 最新情報
https://buttondown.email/hotwireweekly

HotWireについて毎週情報が送られてくるメルマガ

https://note.com/everyleaf/n/nd7c77758c610

2023年秋のHotWire関連の情報がまとめられている万葉様のブログ
Software Durability: Concepts and Practices

『Software Durability: Concepts and Practices』は、ソフトウェアの耐久性について書かれた技術書というよりは学術書です。
<a href="https://www.amazon.co.jp/Software-Durability-Practices-Rajeev-Kumar/dp/1032344784"><img src="https://m.media-amazon.com/images/I/61VsM2QGn1L._SL1500_.jpg" width="200" alt="Software Durability: Concepts and Practices書影"/></a>
大学の研究者たちが書いた本のようで、実用性には乏しいです。

ソフトウェアの耐久性(Durability)は以下の要素からなるとしています。

* Dependability
* Trustworthiness
* Usability
* Security
* Human Trust

DependabilityもTrustworthinessも日本語訳すると「信頼性」になりますし、Human Trustもまた信頼で、直交していない感じがして気持ち悪さがあります。

さらには、この5つの要素も分解して説明されているのですが、例えばDependabilityは、

* Availability
* Reliability
* Maintainability
* Accountability
* Survivability

で説明されていて、ここでもまた別の信頼性（Reliability）が出てきます。せっかくなので、ソフトウェアの品質特性として挙げられる「信頼性」について深掘りしておきます。

## 信頼性

信頼性と訳せるものは、この本に出てくるものと、Wikipediaの[品質特性](https://en.wikipedia.org/wiki/List_of_system_quality_attributes)のページから拾うと以下のようにたくさんあります。

* Reliability
* Dependability
* Trustworthiness
* Credibility
* Confidentiality

### Reliability

このうち品質特性での「信頼性」というと、Reliabilityを指します。「特定の期間で必要な機能を提供し続けられる能力」を意味する、というのが一般的な解釈です。

したがって、ReliabilityはISO/IEC FCD 25010の定義だと、可用性や耐障害性、復旧可能性などのサブ品質特性を持ちます。

### Dependability

Dependabilityも日本語訳は通常「信頼性」なのですが、品質特性では、メタ的なものと考えられることが慣例で、『[Basic Concepts and Taxonomy of Dependable and Secure Computing](https://ieeexplore.ieee.org/document/1335465)』の論文によれば、

* Reliability
* Availability
* Safety
* Integrity
* Maintainability

からなるとされます。

### Trustworthiness

Trust系の「信頼」は、エンドユーザの期待を意味するためにとっておかれている言葉で、品質特性として挙げられることはあまりありません。『Software Durability』の書籍では、これを品質特性として挙げているのですが、Dependabilityと区別が曖昧で、悪手だと思います。

### Credibility

アーキテクチャの品質特性というよりは、サービスおよびコンテンツがユーザから信頼できる、信じられると認識される度合いを指します。

[WikipediaのCredibilityのページ](https://en.wikipedia.org/wiki/Credibility)によれば、
* 善意、真実、偏りのない情報、および情報源の知覚された善良さや道徳性に関連する。
* 知識がある、経験がある、有能であるなどの用語と関連し、情報源の知覚された知識と技術を捉える。

とされます。

### Confidentiality

Confidentialityは、ソフトウェアの世界では機密性と訳されることが多いので、混乱することは少ないかと思いますが、一応品質特性としては、不正なアクセスや開示から機密情報を保護するソフトウェアの能力を指します。

## 保守性

『Software Durability』では、メインは耐久性には、信頼性が大事という主張なのですが、実際にソフトウェアの寿命が短くなる主要因の1つにMaintainabilityがあります。この書籍では、(Dependabilityの1要素ではあるので、考慮されていないわけではないはずなのですが…)残念ながらMaintainability(保守性)への言及が弱いです。

これまた、ISO/IEC FCD 25010を参照すると、Maintainabilityは、以下からなります。

* Modularity
* Reusability
* Analyzability
* Modifiability
* Testability

結局は、影響範囲調査のしやすさ、変更容易性、テスト容易性などが、ソフトウェアの寿命を決めるのは直感に一致するところかと思います。

## 品質特性の議論の注意点

ISO/IEC FCD 25010もそうであるように、品質特性は、上下関係を持たせてツリー状で整理することが多くあります。

ここまでの議論でも、ISO/IEC FCD 25010ではReliabilityのサブ特性であるはずのAvailabilityが、本書の整理では、並列になっているなど、解釈は統一されていません。

[Software Architecture in Practice 4th](https://www.amazon.co.jp/Software-Architecture-Practice-Engineering-English-ebook/dp/B094CPJ96B/)によれば、「機能的正確性」は「信頼性」の一部であるべきだとか、「移植性」は「変更容易性」の一種である、または「保守性」は「変更容易性」の一種である（その逆ではない）などの議論があるようだし、ISO 25010の策定者たちは、セキュリティを機能のサブ特性ではなく、独自の特性として決定するために時間と労力を費やしたらしいです。

なので、品質特性の整理は、チェックリストとして使うのは良いが、用語や構造に固執することはありません。

と、いうことが書いてある[Software Architecture in Practice 4th](https://www.amazon.co.jp/Software-Architecture-Practice-Engineering-English-ebook/dp/B094CPJ96B/)は、とにかくオススメなので、未読の方はこちらをまず読んだ方が良いです。
[改訂版] Blazor でラジオボタン input 要素に双方向データバインドする方法

## 素の input 要素を相手にする限りは 2023年12月現在も変わりありません

Blazor がまだ v.0.5 (!) だった頃、以下の記事を書きました。

https://qiita.com/jsakamoto/items/51407c55498ccd016921

上記記事は 2023年12月現在、かれこれ 6 年近く前の記事となります。本記事では、Blazor が公式リリース後に、ラジオボタン input 要素に双方向データバインドする方法がどうなったのか、確認します。

まず、以下のようについ書きたくなるコードは、引き続き残念ながら、
`Eerror RZ10008: The attribute 'value' is used two or more times for this element. Attributes must be unique (case-insensitive). The attribute 'value' is used by the '@bind' directive attribute.` というビルドエラーになり、ビルドすら通りません。

```html
<-- 👇これはビルドエラーになります -->
<label>
    <input type="radio" value="1" @bind="_editionCode"/>
    Home
</label>
<label>
    <input type="radio" value="2" @bind="_editionCode"/>
    Pro
</label>
<label>
    <input type="radio" value="3" @bind="_editionCode"/>
    Enterprise
</label>

@code {
    private int _editionCode = 1;
}
```

`@bind` 構文について、下手に対象要素に応じて挙動を変えることは返って問題を増やすのみと判断されたのでしょう、Blazor としては `@bind` 構文の振る舞いは一貫性が保たれていることから上記エラーとなるようです。

すなわち、`@bind` 構文は、言ってみればある種の糖衣構文のようなものですから、件の 6 年前の記事のように、自前で "モデルから UI へ" の方向と "UI からモデルへ" の方向のバインド処理を記述することで、ひとまず正解となります (下記コード)。

```html
<-- 👇これで正常に動作します -->
<label>
    <input type="radio" checked="@(_editionCode == 1)" @onchange="(() => _editionCode = 1)" />
    Home
</label>
<label>
    <input type="radio" checked="@(_editionCode == 2)" @onchange="(() => _editionCode = 2)" />
    Pro
</label>
<label>
    <input type="radio" checked="@(_editionCode == 3)" @onchange="(() => _editionCode = 3)" />
    Enterprise
</label>

@code {
    private int _editionCode = 1;
}
```

## .NET 5 以降は、簡単に書けるようになりました

さて、件の記事作成後、Blazor が 2019年9月に .NET Core 3.0 リリースで公式リリースになったさらにその後、2020年11月の .NET 5 リリースで、新しい標準添付のコンポーネント **`InputRadioGroup` および `InputRadio` コンポーネント**がリリースされました。`InputRadioGroup` および `InputRadio` コンポーネントを使うと、以下のように書けるようになります。

```html
<InputRadioGroup @bind-Value="_editionCode">
    <label>
        <InputRadio Value="1" />Home
    </label>
    <label>
        <InputRadio Value="2" />Pro
    </label>
    <label>
        <InputRadio Value="3" />Enterprise
    </label>
</InputRadioGroup>

@code {
    private int _editionCode = 1;
}
```

特に説明も要らないくらいシンプルですね!

あと、これまでのサンプルコードでは、簡略化のためにちょっとサボっているところがあって、それは `<input type="radio".../>` 要素に `name` 属性を明示していませんでした。このサンプルの程度ではそれなりに動いてしまうのですけど、`<input type="radio".../>` 要素は、同じ `name` 属性値をもつ要素間でチェック状態が排他になるので、実際にはちゃんとページ内でユニークなグループになるよう `name` 属性値を設定する必要があります。

その点、この Blazor に標準添付されている `InputRadioGroup` および `InputRadio` コンポーネントは、`Name` パラメーターを明示しないときは、GUID 値に基づく `name` 属性値を自動で付与してくれます。なので、とくに `name` 属性をなんとするか気にせずに実装できるのも嬉しいポイントです。

## まとめ

ということで、Blazor でラジオボタン input 要素に双方向データバインドするには、Blazor に標準添付されている `InputRadioGroup` および `InputRadio` コンポーネントを使いましょう。

_Learn, Practice, Share!_
【Apache】クエリパラメータの値を基にリダイレクトを行う

# 事のはじまり

わたし「MediaWikiを別サーバーに移行するよ」
わたし「使っていたドメインはレンタルサーバー会社から貸し出されているサブドメインだったから独自ドメインにするよ」

(中略)

わたし「やっと移行できたよ…あとはしばらく旧サーバーでリダイレクトするだけ…」
？？？「パス構成も変わったけどどうするんですか」
わたし「あっ」

# 新旧のパス比較

```text:旧サーバーでのパス
/wiki/index.php?title=＜ページタイトル＞
```

```text:新サーバーでのパス
/＜ページタイトル＞
```

というわけで、クエリパラメータに指定しているページタイトルを抜き出してパスに入れこまないといけません。
~~移行ついでにURLをすっきりさせようとかするからこうなる。~~

# というわけで正解の.htaccess

```apache:.htaccess
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/wiki/index.php$
RewriteCond %{QUERY_STRING} (?:^|&)title=([^&]+)
RewriteRule ^(.*)$ https://＜新ドメイン＞/%1? [R=301,L,NE]
```

Rewriteの条件は、下記の2つです。
- リクエストURIが `/wiki/index.php` である
- クエリパラメータに `title` があり、1文字以上指定されている

Rewriteの内容は下記の通りです。

- 新ドメインの `/＜titleパラメータ＞` に301リダイレクトする
- 置換後URLの末尾に `?` をつけることで、元々あったクエリパラメータをすべて削除
- オプションで `NE` (No Escape) をつけることでtitleパラメータを再エスケープしない

# おわりに

これ、もう二度と書きたくないので記録としてここに残します。(などと)
【Detectron2を掘り下げる】MLflowで実験管理

# はじめに
Detectron2は物体検出やセグメンテーションをする上で色々と便利な機能が簡単に実装できるライブラリです。
ただ、使ってみるとモデルを構築する上で提供されていないものがチラホラあるので、掘り下げて実装してみました。
今回は実験管理ツールであるMLFlowで評価指標のログを取れるようにしてみます。
Detectron2はtensorboardをデフォルトでサポートはしていますがMLFlowを使うにはカスタムで実装しないといけません。
ただ、割と簡単に実装ができます。

# 環境

- Python 3.10.13
- CUDA 11.7
- pytorch==1.13.1
- detectron2==0.6

# 実装

Hookとして以下のようなクラスを定義します。

```python
import mlflow
import torch
from detectron2.config import CfgNode
from detectron2.engine import HookBase


class MLflowTracker(HookBase):
    def __init__(self, cfg: CfgNode) -> None:
        super().__init__()
        self.cfg = cfg.clone()

    def before_train(self) -> None:
        with torch.no_grad():
            mlflow.set_tracking_uri(self.cfg.MLFLOW.TRACKING_URI)
            mlflow.set_experiment(self.cfg.MLFLOW.EXPERIMENT)
            mlflow.start_run(run_name=self.cfg.MLFLOW.RUN_NAME)
            for k, v in self.cfg.items():
                mlflow.log_param(k, v)

    def after_step(self) -> None:
        with torch.no_grad():
            latest_metrics = self.trainer.storage.latest()
            for k, v in latest_metrics.items():
                mlflow.log_metric(key=k, value=v[0], step=v[1])

    def log_artifacts(self, file_dir: str) -> None:
        mlflow.log_artifacts(file_dir)

    def log_artifact(self, artifact_path: str) -> None:
        mlflow.log_artifact(artifact_path)

```

定義したHookを`Trainer`の`register_hooks`に渡します。

```python:main.py
# mlflow
mlflow_tracker = MLflowTracker(config)

# train
trainer = Trainer(config)
trainer.register_hooks(hooks=[mlflow_tracker])

...
```

これで学習を行うとMLFlowで評価指標のログを取ることができます。

# 実験結果の確認

`mlflow ui`コマンドを実行して、実験結果を表示する画面を起動します。
デフォルトでは`http://127.0.0.1:5000`で表示できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/e3c2a18e-5f66-90c3-3ba9-f60652b10f20.png)

# Artifactとしてファイルを保存

`log_artifacts()`で指定のディレクトリのファイルすべてを、`log_artifact`で指定のファイルをArtifactとして保存することができます。

```python:main.py
# store artifacts in mlflow
mlflow_tracker.log_artifacts(config.OUTPUT_DIR)
mlflow_tracker.log_artifact("config/parameter_config.yaml")
```
Pybricks のブロックプログラミング環境

# はじめに

開発中の Pybricks v3.4.0 では、ブロックプログラミングが可能になりました。といいますか、もう ベータ2 まできているのに、追加された機能はほぼブロックプログラミング機能だけです。

# ブロックプログラミングをはじめるには

開発中の Pybricks はベータ版リリースから [Pybricks Code ベータ版](https://beta.pybricks.com/)で使えるようになります。

Pybrick にアクセスして新規ファイルの「+」記号をクリックすると、ファイル名入力のダイアログが現れますが、ここでブロックプログラミングか、Python プログラミングを選択することになります。

![スクリーンショット 2023-12-17 19.48.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106817/ac26453e-1539-04a6-144f-2dbf570c2f35.png)

ブロックプログラミングを選択すると「寄付」が要求されます。将来的にこれが解除されるのかは不明ですが、１週間の無料期間があるので、とりあえず登録して体験することは可能です。

※ 私は日頃楽しませてもらっているので 5$/月の寄付をすることにしました。

寄付の登録も終わって、ブロックプログラミングが可能になると、次のような画面になります。

![スクリーンショット 2023-12-17 19.56.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106817/835c2810-58fa-c333-b7de-01ff691c6d37.png)

ブロックプログラミングによくある、セットアップ用(set up)と実処理用(program)のブロックがあります。

ファイルの拡張子はブロックプログラミングになっても `.py` です。

# プログラミング

エディタ領域の左側にプログラミングで使うブロックを選択して配置します。

* Setup -- ハブやデバイスの初期化用ブロックがあります
* Output -- モーターやLED、送信用のブロックがあります
* Input -- センサーやタイマー、受信用のブロックがあります
* Flow -- 条件分岐やループのブロックがあります
* Tasks -- マルチタスクや独自モジュール用のブロックがあります
* Data -- データ値や演算子のブロックがあります
* Variable -- 変数定義のブロックがあります

たとえば、ハブ内蔵の LED でLチカするプログラムは次のようになります。

![スクリーンショット 2023-12-17 20.31.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106817/aee5723d-30c3-2ee6-3fdd-c69a000f40b0.png)

# 使ってみた感想

ブロックは Pybricks の API にや制御構造にほぼ１対1に対応しています。その分、抽象化不足でプログラミング初心者にはわかりずらいかもしれません。たとえば micro:bit の MakeCode では、メインの処理とボタンのイベント処理を別々にブロック配置すれば、自動的に並行して動いてくれますが、Pybricks Code だとイベントループを意識して作り込むか、マルチタスクのブロックを駆使しなければならないので、プログラミング初心者にはなかなかに難しいところです。

ドキュメントでの機能提示方法としては、API と対に示せばよいので楽でしょうね。たとえば、テクニックハブに内蔵 LED のAPIは次のように示されています。

![スクリーンショット 2023-12-17 20.33.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106817/2fbd2c4e-aa0f-9877-3977-e0726ab07f43.png)

# 変換後の MicroPython スクリプトを見るには

現在のところ、ブロックから変換した MicroPython スクリプトを Pybricks コードで見る手段は提供されていないようです。プロックプログラミングでもファイルの拡張子は `.py` であることから、先ほどのLチカのブロックブログラムを PC にダウンロードしてきて中身を見てみることにします。

![スクリーンショット 2023-12-17 21.36.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106817/9fcd526f-b4b2-d16a-1e72-f9feb09b49f8.png)

中身は１行目にコメントでブロック情報のある MicroPython スクリプトでした。

## 2023/12/25 補足

その後、ブロックプログラミング環境を使ってみて、いちいちPCにダウンロードしなくても MicroPython コードを見る方法が見つかりました。編集領域の右側にある `</>' をクリックするだけでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106817/1604793e-07f4-2392-6e52-d5bc277b20a0.png)

次のように、右側に MicroPython コードが現れます。残念ながら MicroPython 側のコードは編集できません。元の画面に戻すには、もう一度 `</>' をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106817/5d4167cb-ca54-cecb-171b-ec4154613a1b.png)
Replitでdiscord.pyのFFmpegPCMAudioを使う

# はじめに

Replitは手軽で使いやすい開発環境でありながら、一部の上位ディレクトリへのアクセス権が制限されていることがあります。これは、セキュリティや環境の一貫性を保つための措置であり、一般的には安全な開発をサポートしています。しかし、discord.pyで音声を再生する場合、特に`FFmpegPCMAudio`や`PCMVolumeTransformer`を使用する際には、この制約がいくつかの課題になります。

この記事では、Replit環境でdiscord.pyの`FFmpegPCMAudio`を利用するために必要な手順について解説します。

## この記事の対象者

- ある程度Pythonの知識があり、replitでdiscord.pyの音声クライアント関連の関数を利用したい

## 前提知識

- ReplitのPython、discord.pyテンプレートはLinuxの環境で動作しています(シェルから`uname`コマンドで確認できます)
- Windowsではバイナリが自動で読み込まれますが、その他のOSでは`discord.opus.load_opus(name)`関数が必要です[^1]

# 手順

## 1. システムの依存関係にffmpegを追加する

### 1. 新しいタブからSystem Dependenciesを開く

画像のように、システムの依存関係を扱うタブがあります。
![replitのSystem Dependenciesの項目.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114394/c8b3c77f-9615-6de9-24ab-42315639b075.png)

### 2. ffmpegを追加する

`ffmpeg`で検索をかけると画像のような項目が見つかるのでインストールします。(画像はインストール後のものです)
![ffmpeg@5.1.3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3114394/0c098ff2-0bfe-8038-8969-2f81e6a2a5b7.png)

## 2. libopusを扱えるディレクトリ内に配置する

### 1. 必要なファイルをダウンロードする

本来であれば少し面倒な作業が必要なのですが、今回は私がすぐ使えるようにしたものをGitHub上に公開しているのでそれを利用します。

`libopus.tar.gz`をダウンロードしてreplにアップロードします。
https://github.com/t3tra-dev/discordpy-ffmpeg-replit/blob/main/libopus.tar.gz

### 2. ファイルを展開する

アップロードした`.tar.gz`ファイルを`tar`コマンドで展開します。
```bash
tar -zxvf libopus.tar.gz
```

## 3. libopusを読み込ませる

botを動かしているPythonファイルの任意の位置で`discord.opus.load_opus('libopus/lib/libopus.so')`を実行します。`FFmpegPCMAudio`や`PCMVolumeTransformer`を使用する前であればどこでも構いませんが、お勧めは`discord.Client`や`discord.ext.commands.Bot`のインスタンスを作成した直後です。

例:
```python:main.py
import os

import discord
from discord.ext import commands

intents = discord.Intents.all()
bot = commands.Bot(command_prefix='!', intents=intents)
tree = bot.tree
discord.opus.load_opus('libopus/lib/libopus.so')


@commands.command()
async def play(ctx: commands.Context, url: str, volume=1):
    if ctx.guild.voice_client is None:
        vc = await ctx.author.voice.channel.connect(self_deaf=True)
      else:
        vc = ctx.guild.voice_client
    try:
        source = discord.FFmpegPCMAudio(url)
        source = discord.PCMVolumeTransformer(source, volume=float(volume))
        vc.play(source)
    except Exeption as e:
        await ctx.send(f"再生の過程でエラーが発生しました: {str(e)}")


bot.run(os.environ['TOKEN'])
```
この例では、入力されたURLをソースに音声を再生し、オプションの引数で音量が指定できるようになっています。

# 終わりに

最後まで読んで頂きありがとうございます。今回初めてQiitaの記事を書いたのでいくらか不備があると思います。その際は是非コメントで指摘して下さい。

# 追記

discord.pyの音声関連の機能がインストールされていないと正常に動作しません。その場合は
```bash
pip install discord.py[voice]
```
を実行して音声関連の機能をインストールして下さい。

[^1]: https://discordpy.readthedocs.io/ja/latest/api.html#opus-library
2023 Advent Calendar完走の感想(振り返り)

本記事は、[めんどい太郎の Advent Calendar 2023](https://qiita.com/advent-calendar/2023/mendoitarou_first_calendar) 25日目の記事です。

# はじめに

この記事は初心者が書いています。

ということで...25日目です！

この記事で完走なので、厳密に言えばまだ完走はしていませんが...

私は初めてのAdvent Calendar参加&作成&完走ということで振り返りをしていきたいと思います。

# 振り返り
## 1〜3日目
1〜3日目は結構スムーズにかけました。

久しぶりにQiitaの記事を書きました。

何年ぶりなんでしょうか...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/388444/8eec41dd-b69e-d917-3bc1-32af0a046ff9.png)

3年ぶり！？

時が流れるのは早すぎる...

あっ...下書きに書こうと思って書いてない記事がたくさんありますね...

## 4〜10日目
4〜10日目は普通に忙しくて途中当日の朝記事を書くなんて自体になりました。

危なかった...

ここらへんはまだ書くことがあります。

カレンダー作成時点で書くことを決めていたところらへんですね。

## 12日目
この日は[ConoHa Advent Calendar 2023](https://qiita.com/advent-calendar/2023/conoha)にも参加させていただきました。

記事[^1]の内容としてはただVPSで遊んだだけですが...

ConoHaのアドベントカレンダーの記事を見てるとConoHaってこんな事もできたのか！とかConoHaでこんなことしてる人もいるんだな〜となかなか面白いです。

アドベントカレンダーってのはいいですね。おもしろい。

## 11〜17日目
11〜17日目は書くことを決めていませんでしたので、そこから考える必要ありました。

あと内容がここらへんからてきとうになってきています...クソ記事量産...

4日目以降は常に忙しい！みたいな感じでした。

## 18〜25日目
これを書いているのが18日目です。

19〜25日目はこの3日間で書きました。

ネタが思いつかないので、なにかやっていなかったことにチャレンジしてみよう！といった感じでした。

いい機会になりました。

# アドベントカレンダー完走して良かったこと
先程書きましたが、新しいことにチャレンジする機会になりました。

アドベントカレンダー作成してよかった！

自身の伝える能力のなさを知るきっかけにもなりました。

日本語力を鍛えていかないとですね...!

# Qiitaの記事を書くメリット
Qiitaの記事を書くことで、自分自身が同じことをまたしたいときにどうやればいいかという振り返りもできますし、同じことをしたい人のためにもなります。

これは非常に大きいメリットですね！

私は普段Qiitaの記事を読む側ですが、Qiitaの記事はためになる内容が多いので非常にいいプラットフォームだと思います。

なにか苦戦していたことが成功したときはQiitaの記事を書いてみましょう。

もしかしたら、同じように苦戦している方の手助けができるかもしれません！

# 完走した感想
タイトル回収です。

感想としては、書いてよかった！の一言ですね。

上でも書きましたが自分の現状を知ることもできましたし、新しいことにチャレンジもできました。

.....おんなじ内容ばっかり書いてるな...

# 終わりに
アドベントカレンダーはいいぞ！

(最終日に内容のうっすい記事を書いてしまった...)

[^1]:[ConoHaのVPSにWineを入れて遊ぶ](https://qiita.com/mendoitarou_/items/f8cb185194d4f863b403)
ISO 25021 品質測定量要素の紹介

ISO 25021 では [ISO 25030 の品質測定量](https://qiita.com/mmake/items/57900605a6d9f2cec3bc)を導出するための品質測定量要素（QME）を定義します。この記事では品質測定量要素の概要を紹介します。

![136.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/d99afb0d-a422-4b5c-a9b1-e055221d3c44.png)

## 利用時の品質を表す測定量
### 割込みの数 
システムが外部からの割り込み（操作）にどれだけ対応する必要があるかを示す数を指します。
#### 測定方法
システムが外部からの割り込み（操作）に対応した回数を数える。
#### 単位
件（数）
### 運用操作の数 
システムが実際に運用される際に行う操作や手順の数を指します。
#### 測定方法
システムが実際に運用される際に行う操作や手順の数を数える。
#### 単位
件（数）
### （手順の）ステップの数 
特定の作業やプロセスを実行するために必要な手順やステップの数を指します。
#### 測定方法
特定の作業やプロセスを実行するための手順やステップの数を数える。
#### 単位
個（数）
### ユースケースの数 
システムの振る舞いを説明するためのユースケースの数を指します。
#### 測定方法
システムの振る舞いを説明するためのユースケースの数を数える。
#### 単位
件（数）
### 致命的なエラーの数 
システムがクラッシュや重大なエラーにより停止する回数を指します。
#### 測定方法
システムがクラッシュや重大なエラーにより停止した回数を数える。
#### 単位
件（数）
###  利用者問題の数 
ユーザビリティの問題、理解しにくい機能、不明瞭なエラーメッセージなどが含まれます。
#### 測定方法
ユーザーテストや利用者フィードバックを収集し、利用者が報告した問題の数を数える。
#### 単位
件（数）
### アクセシビリティを配慮した機能の数 
視覚的な制約を持つユーザー、聴覚的な制約を持つユーザー、モビリティの制約を持つユーザーなどがシステムを使用しやすいように構築された機能の数を指します。例えば、音声読み上げ機能、大文字表示、色の対比などが該当します。
#### 測定方法
アクセシビリティの要件を定義し、その要件を満たす機能の数を数える。各機能がアクセシビリティの観点からどれだけ利用しやすいかを評価する。
#### 単位
個（数）

## ソフトウェアの外部品質を表す測定量
### 製品の機能規模 
製品が提供する機能や機能セットの総量を指します。
#### 測定方法
機能点（Function Point）や機能ポイントなどの尺度を使用して、ソフトウェアの機能規模を測定する。
#### 単位
機能点（Function Point）や機能ポイントなどが使われることがあります。
### 故障の件数 
システムやソフトウェアの機能が正しく動作しない回数を指します。
#### 測定方法
システムの機能が正しく動作しなかった回数を記録する。
#### 単位
件（数）
### 作業工数（時間を単位とした） 
プロジェクトやタスクの実施にかかる総作業時間を指します。
#### 測定方法
プロジェクトメンバーが作業に費やす総時間を計測する。作業ログやタイムトラッキングツールが利用されることがあります。
#### 単位
時間（時間単位）
### 所要期間 
プロジェクトやタスクの完了にかかる時間を指します。
#### 測定方法
プロジェクトが始まって終わるまでの期間を計測する。
#### 単位
時間（時間単位）
### システム故障の件数 
システムが予期せず停止または誤動作する回数を指します。
#### 測定方法
システムが予期せず停止した回数や誤動作が発生した回数を記録する。
#### 単位
件（数）
### 障害の数 
システムやアプリケーションが利用者にとって利用しにくい状況や問題の数を指します。
#### 測定方法
システムが利用者にとって使いづらい状況や問題が発生した回数を記録する。
#### 単位
件（数）
### メッセージの数 
システムがユーザーや他のシステムとのコミュニケーションで発するメッセージの数を指します。
#### 測定方法
システムがユーザーや他のシステムとのコミュニケーションで発するメッセージの数を数える。
#### 単位
件（数）
### エラーメッセージの数 
システムが発生させるエラーや問題に関するメッセージの数を指します。
#### 測定方法
システムが発生させるエラーや問題に関するメッセージの数を数える。
#### 単位
件（数）
### メモリの規模 
システムが必要とするメモリの量や規模を指します。
#### 測定方法
システムが必要とするメモリの総サイズを計測する。
#### 単位
バイト、キロバイト、メガバイト、ギガバイトなど（メモリのサイズによる）

## ソフトウェアの内部品質を表す測定量
### データ項目の数 
システム内で使用されるデータ項目や変数の数を指します。
#### 測定方法
システムで使用されるデータ項目や変数の総数を数える。
#### 単位
個（数）
### データベースの規模 
データベースに格納されるデータの量や規模を指します。
#### 測定方法
データベース内のデータの総サイズを計測する。
#### 単位
バイト、キロバイト、メガバイト、ギガバイトなど（データのサイズによる）
### タスク複雑性 
特定のタスクを実行するのに要する複雑性を示す指標です。
#### 測定方法
タスクの実施に要する手順や判断の複雑性を主観的に評価する。
#### 単位
無単位（主観的な指標）
### テストケースの数 
ソフトウェアやシステムをテストするためのテストケースの数を指します。
#### 測定方法
ソフトウェアやシステムをテストするためのテストケースの数を数える。
#### 単位
件（数）
### エラーの数 
システムやソフトウェアの実行中に発生したエラーの数を指します。
#### 測定方法
システムやソフトウェアの実行中に発生したエラーの数を数える。
#### 単位
件（数）

## データの品質を表す測定量
### レコードの数 
データベース内のレコード（行）の数を指します。
#### 測定方法
データベース内のレコードの総数を数える。
#### 単位
件（数）

## 参考文献
- 日本産業標準調査会（ユーザアカウントを登録すれば、無料で閲覧できます）
 https://www.jisc.go.jp/
 JIS X 25022:2019 利用時品質の測定
 JIS X 25021:2014 品質測定量要素
Dockerでsystemdを走らせたい！

## はじめに
　Dockerでsystemdを走らせて複数プロセス動かしたいときってありますよね？（自分だけだと思いますが。）１コンテナ１プロセスというお作法があるのは理解していますが、その方法を記事にしたいと思います。

### 環境
Ubuntu 20.04 LTS

## イメージを作成
### コンテナの作成と起動
　自作のイメージを作成します。以下のコマンドでコンテナを立ち上げます。
```shell
docker run -it \
--name make-systemd-ubuntu2204 -h make-systemd-ubuntu2204 \
ubuntu:22.04 /bin/bash
```

### パッケージの更新とインストール
　aptコマンドを用いてパッケージの更新をしてから、必要なパッケージをインストールします。
```shell
apt -y update&&apt -y upgrade&&apt -y autoremove
apt -y install systemd init sudo ufw wget net-tools iproute2 vim nano htop
```

### パスワードの設定
　rootのパスワードを設定します。設定しないとログインできなくなってしまいます。
```shell
passwd
```

### イメージの作成
　コンテナから抜けます。
```shell
exit
```
　コンテナをシャットダウンさせます。
```shell
docker stop make-systemd-ubuntu2204
```
　コンテナからイメージを作成します。
```shell
docker commit make-systemd-ubuntu2204 systemd-ubuntu:22.04
```

## 起動
　以下のコマンドで、作成したイメージからコンテナを起動します。
```shell
docker run -it --privileged \
--name systemd-ubuntu -h systemd-ubuntu \
systemd-ubuntu:22.04 /sbin/init
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2942430/fe8ed191-1b16-2309-611c-61afe95f87e4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2942430/31ae4403-7589-9168-23a1-f96573cdfb36.png)
　`systemd`がコンテナで走っていることを確認できました。

## おわりに
　DockerでもLXCみたいなことができるんですね。このことを利用して、コンテナにデスクトップ環境を導入した上で、リモートデスクトップするみたいなこともできそうですね。
Rails7+Hotwireによるstimulus.jsのフォルダの配下のコントローラの書き方

# はじめに
stimulus.jsのコントローラをフォルダで分けた際のHTML上での記述方法を解説します。
# 問題
JavaScript/controllers/test_controllerは
そのまま
```html
<div data-controlelr="modal">
    <button data-action="click->modal#close">
        閉じる
    </button>
</div>
```
というふうに記述する。

しかし
JavaScript/controllers/users/test_controllerのactionを使用する際の書き方がわからなかった。

# 解決方法
JavaScript/controllers/users/test_controllerの記述方法は
```html
<div data-controlelr="users--modal">
    <button data-action="click->users--modal#close">
        閉じる
    </button>
</div>
```
フォルダ配下のものは"--"で表現する
```js
data-controlelr="users--modal"
```

# おわりに
なかなか調べても出てこなかったので、同じように困った人のためにメモとして残します。
【Android】画面回転した時に処理を入れたい【Kotlin】

# 実践
AndroidManifestに以下を記載します。
```
android:configChanges="orientation|screenSize"
```

また、以下をActivityに記載します。
```
override fun onConfigurationChanged(newConfig: Configuration) {
        // ここに回転した時の処理
　}
```

# onConfigurationChanged
 **onConfigurationChanged()** メソッドは、デバイス構成を指定する **Configuration** オブジェクトを受け取ります。アクティビティを再起動することなく UI の要素を再設定できるようになります。

**Configuration**オブジェクトとは、すべてのデバイス構成情報を記述します。
具体的には入力モード、画面サイズ、画面の向きなどに影響を与えるオブジェクトです。


# 参考

https://developer.android.com/guide/topics/resources/runtime-changes?hl=ja


https://developer.android.com/reference/android/content/res/Configuration
rex0220 計算式プラグイン 添付ファイル名の取得

計算式プラグインで、添付ファイル名の取得を行います。

# 概要

添付ファイル項目は、kintone API の仕様により編集画面上でファイル情報を取得できません。
そのため、レコード保存成功イベントで、ファイル情報を取得する必要があります。
計算式プラグインでは、EV_INFO 関数でイベントを識別して、ファイル情報を取得できます。

![2023-12-17_20h28_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/af8d145c-d471-abc0-8453-147e7f5c07b9.png)

# 操作例

![2023-12-17_20h35_35.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/3a0c5151-55f9-0035-583d-8429e9c0857f.gif)

# 計算式プラグインの設定

![2023-12-17_20h39_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/585ee269-2f11-eb1a-cedd-6c9ca41a5717.png)

OPTION: 循環参照を許可

- ファイル名
    - EV_INFO("mode")="success" : 
        - レコード追加成功イベントとレコード編集成功イベントが "success" となります。
    - &IF(更新者,"") :
        - レコード追加保存成功後イベント、レコード編集保存成功後イベントで計算処理を実行するために、更新者を指定しています。
        - 空の文字列を連結するため、文字列は変化しません。
        - 更新者・更新日時が計算式に指定されると、レコード保存成功イベントで計算処理を行います。
    - 添付ファイル
        - 文字列に添付ファイルを指定すると、カンマ区切りでファイル名をセットします。
- ファイル数
    - ARRAY_COUNT(添付ファイル)
    - 添付ファイルのファイル数を ARRAY_COUNT 関数で取得できます。


```.js
// ファイル名 SINGLE_LINE_TEXT
IF(EV_INFO("mode")="success",
  添付ファイル,ファイル名
)
&IF(更新者,"")

// ファイル数 NUMBER
IF(EV_INFO("mode")="success",
  ARRAY_COUNT(添付ファイル),ファイル数
)
&IF(更新者,"")
```

# ちょっと便利なプラグイン設定

詳細画面で「画像ファイルを横並び」をチェック

![2023-12-17_20h37_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/93f9a666-ecf4-a78f-9d2c-241abdca5632.png)