OmniAICreator/Qiita-1.07M huggingface dataset:
サーバー管理で考える仮想化技術

# 前置き
講義で機器・サーバー管理を学ぶ際、いくつかの仮想化技術について教えを得た。また、Dockerなど仮想化技術に関する記事を最近読み、多様な仮想化の知識をまとめておきたいというのが記事作成の動機である。内容は基礎的で初学者向けである。
# 非仮想化（物理的）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3078929/76b8ea59-893f-81e0-2e8f-e2f1f814c692.png)
上図の通り、この記事では図に木構造を用いる。
物理サーバー（物理マシン）に一つのOSがぶら下がり、そのOSに一つのサービスがぶら下がっている状態。
当然ながら **一つのホストに対し、一つのサービスを提供する。**
### 問題点
- OSがクラッキングされる、又は物理マシンに故障が生じると、サービスが使えなくなる。
- 物理マシンをサービスの数だけ用意しなければならないのでコストがかかる。
# ホスト(Host)型
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3078929/61d3fe71-8f12-9d38-3f11-943b9424f5cc.png)
一つの物理マシンに複数OS、複数サービスがぶら下がる。よって、必要な物理マシンの数は減り、**コストを抑えることができる。**
また、一つのゲストOSがハッキングされても他のサービスは動かし続けることができる。
さらに仮想化プログラム上で動く仮想サーバーはデータの移行が容易である。単純にコピーして別の物理サーバーに移行することが可能。そのため物理マシンが故障してもサービスの復旧に要する時間は仮想化しない場合と比べ、大幅に縮小される。
ただ、実際にはこの形態はサーバーにおいては使用されず、主に開発向けである。サーバー向けには次項で述べるハイパーバイザー型が代替技術となる。
具体的な仮想化プログラムはVMware社のWorkstation Playerなどが有名である。
# ハイパーバイザー(Hypervisor)型
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3078929/4c5fa067-bd49-82ee-a229-4393cc8d4a42.png)
こちらもホスト型同様一つの物理マシンに複数サービスがぶら下がり、大きくは違わない。だがホストOSを必要せず、Hypervisorと呼ばれる仮想化ソフトを物理マシン上に直接置き、その上で仮想サーバーを複数立てる。
ホスト型と比較した大きな利点は物理マシンのリソースをより各仮想サーバーに使用できるので**処理速度が向上する**ことだ。
HyperVisorソフトの一例としてMicrosoft社のHyper-Vがある。
# コンテナ(Container)型
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3078929/87196d59-e217-9b5c-c133-fb70e954d0c7.png)
ゲストOSなしで仮想化する技術。OSをダウンロードする手間を省くことができる。また、容易に開発環境を整えられる。さらにホスト型やハイパーバイザー型と比べ動作が軽量で、高速な開発を実現することができる。
こちらもホスト型同様、サーバーではなく開発に使用される技術である。
各仮想環境上のミドルウェア、アプリケーションを合わせてコンテナと呼ぶ。
有名なコンテナエンジンにはDockerがある。
# CPUの性能と仮想化技術
現在CPUの性能は計算系のサーバーなどの速い処理速度が必要なサーバーを除き、一つのサービスのみを提供するには十分すぎる性能を持つ。そのため、仮想化技術を用い、複数サービスを一つの物理マシン（CPU）で処理させることが促進されている。
# 仮想化によるサーバー管理における変化
従来、機器・サーバーは一つの物理ホスト（物理マシン）で一つのサービスのみを提供してきた。そのため、サーバーの物理的な管理としては各ブレードのサービスは何であるかのみを一覧にしておけば問題はなかった。例えば、一つのラックにA,B,Cの三つのブレードがあり、それぞれWebサーバー、FTPサーバー、メールサーバーなどと記載しておけば良かった。しかし現在のように一つの物理ホストが複数のサービスを提供する場合、それぞれのサーバーに対しても一覧を作成し管理しておかなければならない。
# 所感
仮想サーバーを利用しない利点としては管理が単純である点があるが、それ以上に高コストや低効率なCPUの扱い方といった不利な点が目立つ。仮想サーバーでは上述した通り、移行も簡単であるため運用・保守の面で仮想化技術は優れている。
## 最後に
記事を読んでいただきありがとうございます。内容に間違い等があればご指摘願います。
【LaTeXエラー解決方法】! LaTeX mark Error: Infinite shrinkage found in 'column'.

TeXWorks（pLaTeX（ptex2pdf））でLaTeXの文書を書いているときに, 以下のようなエラーが見られた.
```
! LaTeX mark Error: Infinite shrinkage found in 'column'.

For immediate help type H <return>.
 ...       
```
最初に読み込んだパッケージが問題だったらしく, 
```
\usepackage{nidanfloat} 
```
を削除することでエラーをなくすことができた.
ポリモーフィズム

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<h2>説明</h2>
実際に動作しているインスタンスを、インスタンスの元となった型とは異なる型で扱える仕組みのことを指す。条件は、継承、あるいは実現の関係にある場合のみである。

```java
public interface A {
    public void start();
}
public class B implements A {
    public void start(){
        System.out.println("B")
    }
}
public class C extends B {
    public void start(){
        System.out.println("C");
    }
}
public class Main {
	public static void main(String[] args) {
        A b = new B();
        A c = new C();
        b.start();//B
        c.start();//C
	}
}	
```

```java
public class A {
	int test;
}
public class B extends A {
	int test;
}
public class C extends B {
	int test;
}
public class D extends C {
	int test;
}
public class Main {
	public static void main(String[]args) {
		A[]e= {
			new A(),
			new B(),
			new C(),
			new D()
		};
		for(A d : e) {
			d.test += 50;
			System.out.println(d.test);
		}
	}
}
```
</body>
</html>
【Playdate】paturnを使って動く罫線アニメーションを作る

![capture_221224.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100912/6d8088bb-cd62-624e-c28b-5b1365c75835.gif)

`setPattern`を使うと2進数で表現されたバイナリパターンをグラフィックの描画時にセットできます。
[こちら](https://qiita.com/sada_lp1/items/1751040555361bae33b7)のプロジェクトをベースに`setPattern`を用いて動く罫線を描画します。
今回のプロジェクトは以下devフォーラムのスレッドがベースです。

https://devforum.play.date/t/matts-prototypes/826/4

```main.lua
import "CoreLibs/object"
import "CoreLibs/graphics"
import "CoreLibs/sprites"
import "CoreLibs/timer"

local gfx <const> = playdate.graphics

local playerSprite = nil

local function b(e)
	return tonumber(e, 2)
end

local pattern = {
	b('11110000'),
	b('11100001'),
	b('11000011'),
	b('10000111'),
	b('00001111'),
	b('00011110'),
	b('00111100'),
	b('01111000'),
}
local ticks = 0

function myGameSetUp()

	local playerImage = gfx.image.new("Images/playerImage")
	assert( playerImage )

	playerSprite = gfx.sprite.new( playerImage )
	playerSprite:moveTo( 200, 120 )
	playerSprite:add()

	local backgroundImage = gfx.image.new( "Images/background" )
	assert( backgroundImage )

	gfx.sprite.setBackgroundDrawingCallback(
		function( x, y, width, height )
			backgroundImage:draw( 0, 0 )
			
			if ticks % 10  == 0 then
				table.insert(pattern, 1, table.remove(pattern))  -- パターンをローテーション
			end
			gfx.setPattern(pattern)
			gfx.drawRect(10,10,380,220) -- 矩形の線を描画
		end
	)

end

myGameSetUp()

function playdate.update()

	if playdate.buttonIsPressed( playdate.kButtonUp ) then
		playerSprite:moveBy( 0, -2 )
	end
	if playdate.buttonIsPressed( playdate.kButtonRight ) then
		playerSprite:moveBy( 2, 0 )
	end
	if playdate.buttonIsPressed( playdate.kButtonDown ) then
		playerSprite:moveBy( 0, 2 )
	end
	if playdate.buttonIsPressed( playdate.kButtonLeft ) then
		playerSprite:moveBy( -2, 0 )
	end
	
	ticks += 1
	gfx.sprite.redrawBackground()

	gfx.sprite.update()
	playdate.timer.updateTimers()

end
```

`b(e)`というローカル関数が tonumber を実行するラッパー関数となります。
`pattern`テーブルには2進数の文字列が記述されたパターンが記述されています。
`myGameSetUp`　の `setBackgroundDrawingCallback`内でパターンをローテーションするために`table.insert(pattern, 1, table.remove(pattern))`で`pattern`内の値を入れ替えています。
前行の`if ticks % 10  == 0 then`は`playdate.update()`内でカウントアップしている`tick`が10で割り切れる値になる毎に実行するようにしています。
入れ替えた`pattern`は`gfx.setPattern(pattern)`で描画時のパターン設定をしています。
ねおすでたのしかったこと

## はじめに
- NeosVRで、おもしろいたのしいギミックを思い返します

## 楽しいイベント
### NeosFesta4
- これは、自分自身も制作に関わりました。
    - イベント自体というより作ってる時が楽しかったです。
- 製作人員が少ないので一人当たりの裁量が結構おおきいので割となんでもできてたのしかったです。
    - その代わり、重くなりました。
- NeosFesta4でLogiX力が叩き込まれたので割となんでもできるようになったのと、LogiXをやったおかげでわりと人間語に近いプログラミング言語の意味がわかるようになったので個人的に大きな経験の一つです。
- NeosFesta4に出展されたアイテムの中にも非常に興味深いアイテムがあります！
    - 個人的に、クラゲを育てるやつがすごいとおもってます。

### ClubPulse
- ギミックが楽しい！
- 背景のLEDパネル風のやつ、どういう仕組みで動いているのか不思議だったのですが、Rendering > HiddenLayerでそれ以下の階層をCamera以外に映らないようにしているみたいですね。
    - NeosVRにはあまり音楽に合わせてモノが動いたり、動的に生成される派手な映像みたいなものがないので、もし行ったことが無ければぜひ行ってほしいイベントです。

- あと、一定以上離れたユーザーの描画が簡略化される仕組みもあります。軽量化、大事。

### ちょっぱやワールド

- NeosVRの、Neos内外問わずよそで作ったアセットをその場に出していきおいでワールド公開できる仕組みを最大限使って短時間でワールドを作って公開するイベントです。
    - たのしい！
- 基本的に激重。

- ユーザーが作った見知らぬアセットや、見知らぬギミックとか見知らぬ技術に触れることができてたのしいです。
    - みんな個人の趣味を全力でNeosに落とし込んで作ったアイテムを置いていくので最終的にできあがるものがとても賑やかだし、「これは○○さんのやつでは？」という会話も後からできたりしてとても楽しいです。
    
## 楽しいアイテム
### 乗り物全部
- スピードは、すべての人間が憧れるモノの一つです。
    - 最近のNeos(2022年12月くらいの日本語圏のはなし)では、
        - 航空機の操縦
        - はやい車を広いワールドで走らせまくる
        - 車を走らせるためのサーキットを外でつくってきてNeosに持ち込む
    - みたいなことが流行ってます。ちょいちょい見に行くけどたのしい！

- 個人的に飛行機がアツい。
    - なんか翼の角度ごとのパラメータをかなりいい感じに近似しているらしく、やたらとリアルな飛行機操縦をVRで体験できます。
        - 制作者さんはすごいひとだ
## 楽しいギミック
- LogiXとかを使うとなんでもできます。
    - 最近、NeosVRでシェーダーのシミュレートができるアイテムをつくったりしました。
        - 割と、なんでもできます。

- NeosVRのVR空間(3D空間)は、立体音響の品質が非常に高い。
    - デフォルトの音量の距離減衰が線形ではなく距離の対数に比例して減衰していくので、音量から感じ取る距離感が現実のものと近い。
    - あと、音源が前後左右上下にあるときの周波数特性の変化がしっかりしていて、365日ASMR生活ができます。
        - 人間の体は頭とか型とか耳の形のせいで、音が鳴る方向によって全く同じ音でも響きが変わってくるのですが、Neosの音声はなぜかそれがうまく再現できているのです。

    - 理論上無限の距離まで、無限に距離が減衰するのですが、これのおかげで結構遠くまで声が聞こえる（ちゃんと小さくなる）のです。

- どういうわけか、NeosをDiscord代わりにする人もいます。
    - 音声通話の品質がいいのに加えて、その場で画面共有ディスプレイを出せるのでNeosとDiscordを併用するよりNeos一本でやったほうが楽なのです。
        - GPU負荷がすごい！
## さいごに
- NeosVRはデジタル特有のものから、現実に近いようなものまで、かなり広い範囲の制作活動を集団で、VR空間内で行うことができます。たのしいです。みんなもNeosをたのしんでね。
laravel タスクスケジューラー バッチコマンドの多重起動を防止する

:::note info
この記事は[miriwoお一人様 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/miriwo)の25日目の記事です
:::

# 概要

- タスクの多重起動を防止する方法をまとめる。

# 方法

- どうやらデフォルト状態だと、自身のジョブが起動中の場合でも重ねてジョブを実行する事ができてしまう。これを防止するには`withoutOverlapping()`を使用する。

    ```php
    $schedule->command('hogehoge')
        ->withoutOverlapping();
    ```

- ちなみに既に実行中の場合、`withoutOverlapping()`が指定されたジョブが実行されると後から実行したほうがスキップされます。

# 参考文献

https://readouble.com/laravel/8.x/ja/scheduling.html#preventing-task-overlaps
書籍『暗号から学ぶ代数学』の紹介

この記事は [EAGLYS Advent Calendar 2022](https://qiita.com/advent-calendar/2022/eaglys_adcal) の21日目の記事です

# はじめに
昨年のアドカレでは，↓の書評記事を書きました

[書籍『耐量子計算機暗号』の紹介](https://qiita.com/0917laplace/items/7c1535c3236c259e07ea)
[書籍『データ解析におけるプライバシー保護』の紹介](https://qiita.com/0917laplace/items/babf31440efe255e9e7d)
[書籍『セキュリティエンジニアのための機械学習』の紹介](https://qiita.com/0917laplace/items/7f20ef077967b44f9760)

~~書評記事は書くのが楽なので~~今年も書こうと思います

Q. それってあなたの感想ですよね？
A. はい

ということですので，あくまで個人の感想となります

# 今回紹介する本

[暗号から学ぶ代数学](https://gihyo.jp/book/2021/978-4-297-12516-5)

[目次](https://gihyo.jp/book/2021/978-4-297-12516-5#toc)

昨年の記事でも参考文献として触れていたのですが，さらっと読んでみたので気になったところを紹介してみます

# 第2章
思ったより代数をしていました（この感想は読めばわかるかと）
なんですが，かなり具体例が多くて，スルッと読み進められると思います

# 第5章
めちゃめちゃわかりやすい，個人的最推し章です

対称群っていまいち掴みどころが分かりづらいですが，イラストだとかなりスッと理解できるんですね・・・

# 第7章
個人的な準同型のハマりポイントとして，

$g_1, g_2 \in G$ に対して $f : G \rightarrow H$ が $f(x_1 \cdot x_2) = f(x_1) \cdot f(x_2)$ を満たすとき・・・

と書いたときに，左辺の $f(x_1 \cdot x_2)$ の $\cdot$ と右辺の $f(x_1) \cdot f(x_2)$ の $\cdot$ は異なるものでもよい，というのは定義の段階で強調してもいい気がします

この本では，その後に異なる演算で対応している例が挙げられているので，すごく配慮されているなと思いました（こなみかん）

本質的には同じですが，$\mathbb{R}$ を実数全体の集合として，$f : \mathbb{R} \rightarrow \mathbb{R}$ で，$f(x) = e^x$ とすると，$x, y \in \mathbb{R}$ に対して，$f(x + y) = f(x) \cdot f(y)$ なので，$f$ は準同型です

# 第8章
環の元に対して，可逆とか単元ではなく，正則という言い方をするのを初めて知りました（まあこの辺の言い回しはどうでもいいといえばどうでもいいのですが）

演習問題8.1
$0^{-1}$という書き方が気になりました（元 $a$ に対して，$a$ の逆元が存在してはじめてその逆元を $a^{-1}$ という書き方をするため）

# まとめ
前回紹介した [現代暗号技術入門](https://bookplus.nikkei.com/atcl/catalog/22/06/08/00221/) とは異なり，Caesar暗号からスタートなので，テイストが全然違うなって感じでした

必要な数学を全て用意してから暗号に進む，というよりは，暗号を進めてその場その場で必要なものを調達するという認識でしょうか

あまりこういうのを書くのは良くない気がしますが [代数学1　群論入門](https://www.nippyo.co.jp/shop/book/5462.html) に挫折した方は（~~暗号に興味がなかったらそこは飛ばしてもいいので~~）こちらの本がおすすめです（思った以上に代数メインでしたし，冒頭でそのようなことが書かれています）

------------------------------------
今回の内容はここまでです．ここまでご覧になってくださった方々ありがとうございます！
マーメイド#22 Mermaid APIを使ってみる

**ひとりマーメイド22日目**
**Mermaid APIを使ってみる**

## 概要
マーメイドエンジニアのひろきです。こんにちは。
最近流行り（流行らせたい）のマーメイドについて理解を深めていこうと思います。

この記事ではMermaid APIの使い方を紹介します！

↓↓前回の記事はこちら

https://qiita.com/hirokiwa/items/1a792f4f87a77dd2c930

## Mermaid APIとは
Mermaid API はマーメイドの記述を文字列で受け取り、レンダリングされたダイアグラムを svg で返します。

この記事では最も簡単に Mermaid API を呼び出す方法を紹介します。

## Mermaid API を使ったレンダリング

HTMLに`<pre>`タグを配置し、その中にマーメイドを記述します。
```haml:index.html
<pre class="mermaid">
    flowchart
        A([start])-->B{true?}
        B--Yes-->C[process]
        B--No-->D[exception]
        C-->E([end])
        D-->E
</pre>
```

Mermaid.jsをインポートします。
スクリプトが実行されると全ての`<pre>`タグに記述されたマーメイドを取得し、Mermaid APIをコールします。
```html:index.html
<script type="module">
    import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
    const config = { startOnLoad: true }
    mermaid.initialize(config);
</script>
```
Mermaid APIはレンダリングされたダイアグラムをsvgで返します。このsvgが記述元の`<pre>`タグに埋め込まれます。

---
複数のダイアグラムを埋め込む場合はも同じ`class`名で記述します。全て同時にレンダリングされます。
```html:index.html
<pre class="mermaid" style="text-align: center;">
    flowchart
        A([start])-->B{true?}
        B--Yes-->C[process]
        B--No-->D[exception]
        C-->E([end])
        D-->E
</pre>
<pre class="mermaid" style="text-align: center;">
    flowchart LR
        A --> B & C --> D
</pre>
<pre class="mermaid" style="text-align: center;">
    flowchart TB
        A & B & C --> D & E & F
</pre>
<script type="module">
    import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
    const config = { startOnLoad: true }
    mermaid.initialize(config);
</script>
```
---

**startOnLoad**
`startOnLoad`に`true`を指定するとロードと同時にレンダリングされます。
`false`を指定するとレンダリングされないため、マーメイドのコードがそのまま表示されます。
```js
const config = { startOnLoad: false }
```

---

とりあえず試したい場合は以下のコードだけで動きます。
プレビューは[こちら](https://hirokiwa.github.io/mermaid_page/)
```html:index.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8" />
        <title>Mermaid Test</title>
    </head>
    <body>
        <h1 style="text-align: center;">Mermaid Page</h1>
        <pre class="mermaid" style="text-align: center;">
            flowchart
                A([start])-->B{true?}
                B--Yes-->C[process]
                B--No-->D[exception]
                C-->E([end])
                D-->E
        </pre>
        <script type="module">
            import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@9/dist/mermaid.esm.min.mjs';
            const config = { startOnLoad: true }
            mermaid.initialize(config);
        </script>
    </body>
</html>
```

## まとめ
Mermaid API をコールして HTML にダイアグラムを埋め込むだけであれば、API の知識がなくても実装することができます。

さらに詳しい仕様は以下を参照してください。

https://mermaid.js.org/config/usage.html

↓↓ 次回の記事はこちら！！

https://qiita.com/hirokiwa/items/ed0ab188c72a1a2a14d4

## 参考

https://mermaid.js.org
ml-agentsがインストールできない「No matching distribution found for torch<1.9.0,>=1.6.0 (from mlagents==0.28.0)」

#### 現象
pip install で　ml-agents をインストールしようとしたが以下のエラーが発生

```
No matching distribution found for torch<1.9.0,>=1.6.0 (from mlagents==0.28.0)
```
pythonのバージョンを以下にしても同様のエラーが発生する
3.10
3.8.12
3.7

####  環境
MacBook Pro （Apple M1 Pro)
iTerm

#### 結論
iTermをlosetta2 で起動してからやる

#### 方法
iTermの情報の詳細を開いて「Rosetta2を使用して開く」にチェック
![スクリーンショット 2022-12-24 16.39.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376429/98923a6f-d09f-9649-bfb4-b47de4e233ec.png)

その後、全てのiTermを閉じて、立ち上げてから、もう一度手順通りにやると成功する
データベースの入門レベルの知識の整理(参考：『おうちで学べるデータベースのきほん』)

ミック・木村明治『お家で学べるデータベースのきほん』という本を参考に、
データベースの入門レベルの知識の整理をしました。

**データベースの分類**
	- 階層型
	- リレーショナル
	- オブジェクト指向
	- XML
	- NoSQL
	-  最も主流なのはリレーショナルデータベース

**リレーショナルデータベース**
	- リレーショナルの意味は、二次元表
	ここでは関係という意味ではない。
	
**DBMSとデータベースの違い**
	- データベースは、機能や構造を表す抽象的な観念
	- DBMSは、それらを具現化した実在するソフトウェア

**ソフトウェアとデータベースの関係性**
	- データベースはミドルウェアに属するソフトウェア。
	すなわち、データベースはOS上にインストールすることで動きます。
	

**データベースにまつわるお金の話**
	- システムの開発や維持の際には、
	システムに起因する利益と費用のバランスをとることが大切。
	システムが完成しても、リリース後に投資回収できず赤字になるなら失敗です。
	- システムのトータル費用の内訳
		○ イニシャルコスト＝最初にまとめて払うお金
		○ ランニングコスト＝サービスを利用する期間、継続的に払うお金
		例：アパートでは、敷金・礼金がイニシャルコスト。家賃はランニングコストです。
	- DBMSの費用
		○ イニシャルコスト＝ライセンス料金
		○ ライセンス料は、論理的な単位で販売されます。
		代表的な販売単位は、プロセッサライセンスとユーザライセンス。
		○ さらに、イニシャルコストを決定する要素は「エディション」と「オプション」の選択。オプションはレプリケーションなどの機能です。
		○ ランニングコスト＝サポート料
		サポートの例：バグ修正のプログラムリリース、技術的なQ&A
		○ 製品にはバージョンがあります。バージョンが古いと、それに対応したサポート期間が終了してサポートが受けられなくなる可能性があります。一方、バージョンが新しいと、利用者が少ないがゆえに製品の動作が不安定だったり、バグが多かったりする可能性があります。


**データベースとアーキテクチャ構成**
	- アーキテクチャとは
		○ アーキテクチャ＝「どのような機能を持ったサーバを用意し、どのようなストレージやネットワーク機器と組み合わせてシステム全体を作り上げるか」というハードウェアとミドルウェアの構成
		○ システムの目的と機能を表現するものと言えます
	- データベースのアーキテクチャ
		○ Web3層がWebベースのシステムの標準

Web3層のシステムの図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1081780/bbc28d15-cd0d-fe30-14f4-7295b9f9b7c5.png)
     - 可用性と拡張性を確保するためのアーキテクチャ
			§ 信頼性＝ハードウェアやソフトウェアが故障する頻度、故障の期間がどれほど少ないか
			§ 可用性＝利用者目線で、システムをどの程度使用できるか
			個々のコンポーネントの信頼性が低くとも、アーキテクチャによって可用性を高めることができます。
			§ アーキテクチャの二つの方針
				□ 1つのコンポーネントの信頼性を上げる(故障しにくくする)
				□ コンポーネントをたくさん並列する。この方法はクラスタリングと呼びます。

DBサーバのクラスタリング
		○ データベースは大量のデータを永続的に保存することとパフォーマンスが要求されます。
		○ DBサーバ内部のローカルストレージやメモリではこの要求を満たせないので、
		専用の外部ストレージが用いられます。
		○ データの冗長化は困難。なぜならデータは常に更新されるので、並列したデータ同士の間でデータ整合性を保つための仕組みが必要になるからです。
		○ そのような課題の中での冗長化の方法は、シェアードディスク、レプリケーション、シェアードナッシングです。
			§ シェアードディスク
				□ DBサーバのみを冗長化
				□ ストレージは単一

シェアードディスクの図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1081780/b2491265-bb84-2c18-82d5-e9d7d3450b03.png)
				□ シェアードディスクの下位の分類
					〇DBサーバの状態がActiveとActive
						◊ DBサーバが同時に稼働
						→ダウンタイム時間が短い
						&パフォーマンスが向上
					〇DBサーバの状態がActiveとStand-by
						◊ 障害発生時以外は稼働しないDBサーバがある
						→Active-Activeに比べるとダウンタイム時間が長い

レプリケーション
			§ シェアードディスクだと、ストレージ部分が冗長化されないので、
			ストレージが壊れるとデータが失われます
			§ これに対処するためのクラスタ構成が
			レプリケーション
			＝DBサーバとストレージのセットを冗長化

レプリケーションの図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1081780/b64ecca8-4517-386d-15ec-84b6dff993a5.png)


シェアードナッシング＝ストレージは共有しないで分離
		→仕組みが単純&サーバとストレージのセットを増やせば並列処理により線形に性能が向上
		一方、デメリットは各ストレージにデータが分散しているので、単一のDBサーバがアクセスできないデータが出てくる点

シェアードナッシングの図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1081780/3945bff6-fec7-7227-766e-dfc59fcf44c9.png)
対比のためのシェアードディスクの図(ストレージ内のデータに注目)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1081780/4fb71e1c-9b62-661f-cd41-e90152569b4f.png)
	

以上です。
拙文をお読みくださりありがとうございました。
イーサリアム 2.0：シャーディングについて

イーサリアム 2.0 のコンセンサスアルゴリズムが PoS に移行できました。次の課題はシャーディングになります。
- 2018 年頃スタートしてから研究し始めて、だんだん「ビーコンチェーン＋シャードチェーン」の設計でした。
- 2021 年末ごろ、rollup を基づいて新しい設計の記事 [New sharding design with tight beacon and shard block integration](https://notes.ethereum.org/@dankrad/new_sharding) が公開されました

それ以来、新しい設計がコミュニティで広く議論され danksharding と名付けました。

## もとの設計の課題
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4777/5a667df5-58ee-35d7-e07a-d541252e1099.png)
引用元：https://vitalik.ca/general/2021/04/07/sharding.html

元の設計案では、シャードチェーンにあるノードサーバーは、そのシャードチェーンのデータだけ同期・処理します。課題はコンセンサスに参加するバリデーターのデータ同期です。
設計上は、コンセンサスに参加するバリデーターは、エポック毎に、バリデーターがランダムで委員会を編成し、その委員会がシャードチェーンに割り振られれます。このエポック内では、そのシャードチェーンのデータを処理します。
となると、バリデーターはほぼエポック毎にシャードチェーンを切り替える必要があり、新しいシャードチェーンのデータを同期する必要があります。これは結構広い範囲のデータ同期になり、相当複雑な内容になります。
規定の時間内ですべてのバリデーターが全部正常にデータ同期できる保証が難しいです。いくつソリューションがありますが、攻撃の対応も必要なので、全体的には難航な状況でした。

## danksharding 設計
![Screen Shot 2022-12-24 at 23.38.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4777/404d9d0d-af87-835e-66c7-f43e8ad1bfad.png)
引用元：https://docs.google.com/presentation/d/1-pe9TMF1ld185GL-5HSWMAsaZLbEqgfU1sYsHGdD0Vw/edit#slide=id.g1150d91b32e_0_800

シャードチェーンを使わずに、ビーコンチェーンにデータを付加する提案になります。
- 付加データは、今までのブロックデータ・ステートデータのように永久保持するのではなく、保持期間が設けられています。期間をすぎると、期限切れのデータを削除することが許されます
- データが多くなると検証などの処理も合わせて重くなりますが、数学的に、データの一部を検証するだけで確率的に大きいデータの可用性を証明できます。この辺は Reed-Solomon（Erasure Coding の実装であり、データを分割し冗長化する技術）と、KZG Commitment で保証されます。これは「DAS：Data Availability Sampling」という概念
- といっても、やはり処理が重くなるため、ブロックチェーンのノードサーバーの中央集権がもっと酷くなると思われるため、ブロック生成過程の中、ブロック提案者とブロック作成者を分けて、ブロック作成者の中央集権化は避けられないが、ブロック提案者がサーバースペックの要求がそれほど高くないため、分散化されることが期待できます。これは「PBS：Proposer-builder Separation」になります。大まかな流れとしては、
    - ブロック作成者は、ブロックヘッダーと手数料を提出する
    - ブロック提案者は、優勝ブロックヘッダーとブロック作成者を選択し、手数料をもらう
    - バリデーター委員会は、優勝ブロックヘッダーを検証する
    - ブロック作成者は、優勝ブロックのボディーを公開する
    - バリデーター委員会は、優勝ブロックボディーを検証する
- PBS があっても、ブロック作成者が意図的にある有効なトランザクションを無視することができます。これを解決するため設計したのは「crList：Censorship Resistance List」です
    - ブロック提案者は、crList を公開する
    - ブロック作成者は、ブロックヘッダーを提出する際に、自分が crList をみたことを証明し、crList にあるトランザクションを全部ブロックに含めなければなりません

詳細はまだこれから決めるので、細かい実装はまだはっきりになっていません。

## まとめ
Danksharding は今までの「シャーディング」と全く変わった設計なので、「シャーディング」とは言えるかどうかも疑問になりますね。
Sudachi v1.0 にむけて

## はじめに

2017年8月に Sudachi が公開されて5年がたちました。これまでは API、辞書構造ともに互換性をおおきくそこねるような変更は避けてきましたが、こんごは Java 版 v1.0 にむけてあたらしい機能を積極的にいれていく予定です。それにともなって従来の系統は v0.6 系までとし、v0.7 からは非互換な変更がはいるようになります。

以下では v1.0 で予定している新機能について簡単にお話しします。

## 辞書構造の変更

辞書のデータ構造を大幅に変更するため、これまでの辞書とはバイナリ互換性をもたなくなります。変更のおもな目的は省メモリ化と高速化ですが、それ以外に以下のような機能を追加します。

### ユーザー定義データ

ユーザーが自由に利用できるカラムを1つ用意し辞書に埋め込みます。これまでユーザーが独自定義した情報はユーザー定義品詞を利用するか、正規化表記に無理矢理埋め込むなどして辞書に搭載する必要がありましたが、この機能をつかうことで無理なく導入することができます。

### デフォルト分割

従来 C 単位分割モード (デフォルトの分割モード) では分割をおこなわず辞書に収録されている語がそのまま出力されていましたが、このモードでも分割が適用される C 単位分割情報を導入します。誤解析になる入力や解析結果を固定したい文字列があるときに、それをひとつの語として登録し出力したい並びを C 単位分割情報として付与することで、かならずその並びで解析結果をえることができます。

もう庭に埴輪、ニワトリがいる生活とはサヨナラです[^1]。

[^1]: Sudachi 辞書には「外国人参政権」が C 単位語として登録されているのでニンジンによる侵略行為はおきません。


### ヘッダー付き CSV

これまで辞書ソースはヘッダーなし、カラム固定でしたがヘッダー付き CSV に変更します。ヘッダーがある場合はカラム順を自由に変更することができます。また、この変更にともない分割情報における ID (行番号) での参照は廃止となり構成語情報による参照に一本化される予定です。

## API の変更

Sudachi 開発当初は既存の形態素解析器などを参考に API の設計をおこないましたが、ユースケースの深化とともにつかいづらい部分が目立つようになってきました。これまでの知見をもとに API を全面的に見直し、よりつかいやすい体系に変更します。

すでに設定まわりや[辞書作成](https://qiita.com/eiennohito/items/311f56e86c25275f4626)についてはあたらしい API が実験的に導入されていますが、こちらも v1.0 にむけて確定させていきます。

## Sudachi.rs / SudachiPy

もちろん Sudachi.rs / SudachiPy も Java 版にあわせてアップデートしていきます。v1.0 にむけて、これからも Sudachi ファミリーをよろしくおねがいします。

ではよい Sudachi life を。
JUCE / MATLAB ～ スタンドアローン VST の活用方法

[<B>JUCE Advent Calendar 2022</B>](https://qiita.com/advent-calendar/2022/juce) に参加しました。


・使用ツール
<dt>　JUCE</dt>
<dt>　Visual Studio</dt>
<br>

<H4><a href="https://note.com/leftbank/n/n47c42909152e"</a> [<B>note</B>]にUpしました。</H4>
離島ITエンジニアはじめました 

# はじめに

 離島ITエンジニアというチャレンジを行なっていますhugeと申します。
「離島でITエンジニアを実現するにはどうしたら良いか」を複数回に分けてお届けしたいと思います！
稀に人が居ないところに行きたいな。もっと自然と触れ合いながら仕事をしたいな。
でも、エンジニアから離れたくないな。と思っている方IUターン希望者を獲得したい
と思っている方に共有したいです。

# 人がいないという事

`田舎 = 人がいない`と思っていませんか？
事実合っているのですが実は「企業が狙っている世代が居ない」が現在居住している離島で起こっています。企業としてほしいのは２０代〜３０代位が多いかと思いますが、その世代を獲得するのは物凄くハードルが高いのが現実です。
小学校・中学校・高校まではあるのですが、大学・専門学校となると中々無いのが現実です。
そのため、17~18歳の方々は田舎から都会へ出るケースが多い様です。

そうなってくると下記のようなループが待っています。

```
若い人材が入ってこない = 後継者不足に陥る
後継者不足に陥る = 企業として新しい事にチャレンジができない
企業として新しい事にチャレンジできない　= 新規人材を雇い入れするだけの余裕がない
新規人材を雇い入れできない　= 低賃金になってしまう
低賃金になってしまう = 人が来ない
```

つまり、`田舎や離島 = 仕事がない`が最終的な結論になってしまいます。

# リモートでどうでしょう

リモートワークであれば田舎でも離島でも何処でも働けるし金銭的な問題も解決するじゃないか！　と言う考えに至った方、私も最初はそうでした。ですが現実は甘くなく`自然災害`が待っていました。

# 待っていた自然災害
`人がいないと言うことは ＝　自然が多い地域である`という事が大前提となります。
自然が多い地域であると言うことはご推察の通り「災害に弱い地域である」と言う事がほぼほぼ成り立ちます。2022年12月24日現在、警報が出ており船が出ず離島に辿り着けておりません。
この事は全く予想していませんでした。正直、「ま、船なんて何時でも出るでしょう」と思っていたのですが、さすがに波が高過ぎれば出ない。これは良いのですが、停電しても２〜３日復旧に掛かるというのは完全に予想外でした。
コンピュータを扱う業種である以上これは致命的です。
特に仕事に追われている状況だったら次から仕事が無くなるかもしれません。

# この場所が好きだ！

私の事例で言うと、春・夏に散歩した時に歩くたびに現れる風景に感動してしまい、
「この場所で仕事ができるようになれば幸せ度合いが増えるかもしれない」と思ったのがきっかけでした。
都会では味わえない事の「この場所が好きだ」なんです。
立地が良い等ではなく「この場所が好きだ」と言えることが田舎・離島でITエンジニアができるきっかけなのかもしれません。

# 終わりに

この田舎・離島が余程好きだ！と思えないと「帰りたい」欲の方が強くなってしまうかもしれません。
ですが！ベストな田舎・離島が見つかると仕事で抱えたストレスも散歩や運動「この場所でしかできないこと」
をすることですぐ解消されます！
ぜひ皆さんにベストな田舎・離島が見つかることを祈っております
Arch Linux 個人的ミニマルインストール

(そこそこ)ミニマルにインストールしたい方向けに解説します。``archinstall``を使用します。
```shell:terminal
archinstall
```
にて、Profileを
```shell:terminal
xorg
```
にしてインストールを進めてください。その他の詳しい設定については[前の記事](https://qiita.com/H-goto16/items/37fe94997d3b189c4aea)を参照ください。

# インストール完了後

デスクトップ環境もしくはウィンドウマネージャをインストールします。今回は例の通り`gnome`をインストールします。

```sh:terminal
sudo pacman -S gnome
```

のときに、
```sh
:: Repository extra
   1) baobab  2) cheese  3) eog  4) epiphany
   5) evince  6) file-roller  7) gdm
   8) gnome-backgrounds  9) gnome-calculator
   10) gnome-calendar  11) gnome-characters
   12) gnome-clocks  13) gnome-color-manager
   14) gnome-console  15) gnome-contacts
   16) gnome-control-center  17) gnome-disk-utility
   18) gnome-font-viewer  19) gnome-keyring
   20) gnome-logs  21) gnome-maps  22) gnome-menus
   23) gnome-music  24) gnome-photos
   25) gnome-remote-desktop  26) gnome-session
   27) gnome-settings-daemon  28) gnome-shell
   29) gnome-shell-extensions  30) gnome-software
   31) gnome-system-monitor  32) gnome-text-editor
   33) gnome-user-docs  34) gnome-user-share
   35) gnome-video-effects  36) gnome-weather
   37) grilo-plugins  38) gvfs  39) gvfs-afc
   40) gvfs-goa  41) gvfs-google  42) gvfs-gphoto2
   43) gvfs-mtp  44) gvfs-nfs  45) gvfs-smb
   46) malcontent  47) mutter  48) nautilus
   49) orca  50) rygel  51) simple-scan  52) sushi
   53) totem  54) tracker3-miners
   55) xdg-user-dirs-gtk  56) yelp
```
とでてきます。そのままEnterを押すとマップとか天気とかプログラミングに全く必要のないパッケージまで勝手にインストールされます。

そこで
```sh
7 14 27 28
```
のみインストールをします。
あとはEnterでインストールしましょう。

パッケージのインストールが完了したら、CUIからGUIを立ち上げる手順について解説します。
```sh:terminal
touch ~/.xinitrc
vim ~/.xinitrc
```
をしてください。好きなエディタでいいですが、自分はCUIだとVim以外使えません。
ない方は
```sh:terminal
sudo pacman -S vim
```
をししてください。**gnome**の場合の設定を載せておきます。
```sh:~/.xinitrc
export XDG_SESSION_TYPE=x11
export GDK_BACKEND=x11
exec gnome-session
```

あとは``:wq``して完了です。

* CUIからGUIの起動
```sh:terminal
startx
```
で完了です。これで余計なものを入れず、CUIでログインから手動GUI起動になりました。
お疲れ様でした。
クリスマスなのでローストビーフ作る

クリスマスなのでローストビーフ食べたいですよね
家にあるものを使って作っていきます。
~~そこはチキンだろという意見は認めません~~

# どうやってつくるか
低温調理器で作るレシピを参考に電気ケトルの水温をESP32で計りながらリレーを使って水温をコントロールします。調理は今回60度を2時間半で行きます。（この辺りは自己責任で）
調理完了したらslackへ通知を飛ばします。

# 用意するもの
* ESP32
* DS18B20（防水仕様）
* G5LE-14
* 電気ケトル
* 牛肉

ESP32は最近手に入りにくいという話を聞きますが、みなさん家にありますね（）

# 回路図
ざっくり書いたのが以下の通りです。
電気ケトルの線の間にリレーを噛ませることで水温をコントロールします。
直接電気ケトルの線を剥くのが嫌だったので今回は延長コードの間にリレーを噛ましてます。
![Untitled(1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115485/9db1adcb-40aa-b51c-c700-396740a95e22.png)

# プログラム

```
#include <OneWire.h>
#include <DallasTemperature.h>
#include <ArduinoJson.h>
#include <HTTPClient.h>
#include <WiFi.h>
#include "esp32/rom/rtc.h"

#define ONE_WIRE_BUS 33  // DS18B20
#define RELAY_BUS    23  // リレー

#define SENSER_BIT    9  // 精度の設定bit

const char* ssid = "SSID";
const char* password = "PASSWORD";
const char* webhook_url = "https://hooks.slack.com/services/XXXXXX";

HTTPClient httpClient;
unsigned long startTime;
  
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
  
void setup(void) {
  Serial.begin(115200);
  
  wifi_connect();
  slack_post("<!channel> 調理開始します");
  
  // センサーセットアップ
  sensors.setResolution(SENSER_BIT);
  pinMode(RELAY_BUS, OUTPUT);

  startTime = millis();
}
  
void loop(void) {
   unsigned long elapsedTime = millis() - startTime;
   if (elapsedTime > 9000 * 1000) {
     slack_post("<!channel> 調理完了しました。");
     
     esp_deep_sleep_start();
     return;
   }
  
   sensors.requestTemperatures();
   float temp = sensors.getTempCByIndex(0);
   Serial.println(temp);
   if(temp > 60){
     digitalWrite(RELAY_BUS, LOW);
   } else {
     digitalWrite(RELAY_BUS, HIGH);
   }
}

void wifi_connect(){
  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
}

void slack_post(const char* message){
  WiFi.reconnect();

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("Connected to WiFi.");
  
  StaticJsonDocument<JSON_OBJECT_SIZE(1)> json_array;
  char json_string[255];

  Serial.println(message);
  
  json_array["text"] = message;
  
  serializeJson(json_array, json_string, sizeof(json_string));
  httpClient.begin(webhook_url);
  httpClient.addHeader("Content-Type", "application/json");
  httpClient.POST((uint8_t *)json_string, strlen(json_string));
  
  httpClient.end();
}
```

# 調理の様子

電気ケトルの中に下処理してジップロックに入れた肉と温度計を入れてESP32の電源を入れて2時間半待ちます。
最後にフライパンで表面を焼きましょう。
![IMG_7664.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115485/a3e20e49-7236-e06c-f0c3-f671d879b02d.jpeg)

# 完成
おいしかったです。
夜食べるのに合わせて作っていたらアドベントカレンダー~~ぎりぎりになりました~~ 遅刻しました

![IMG_7666.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115485/84f9a1f0-c76a-cc99-d7f4-f46e4c01238a.jpeg)

# 最後
本当はブラウザからタイマーと温度を設定できるようにしたかったのと、このプログラムだと60度付近になった時のリレーのON・OFFが機敏すぎるので改善の余地はありそうです。
完成したローストビーフとテストするのに作った温泉卵はおいしくいただきました。
zerofill型のコードマップのkeyの型には気を付けて

# zerofill型のコードマップのkeyの型には気を付けて

## やっぱりコードマップだよね
俺はコウヘイ。エンジニアマスターを目指して開発修行の旅に出ている。DBのカラムのコードマップを作っていた時のお話。

MySQL< zerofillだぞ

僕< なるほど、0埋めね

僕< このカラムのコードマップをアプリケーションに組み込みぞ！


```php
const MONSTER_CODE = [
    '01' => 'ドラゴン',
    '02' => 'スライム',
    '03' => 'おばけ',
    ...
    '99' => '吸血鬼',
];
```

僕< DBからfetchするとstringになるしkeyの型はstringにしておくか

## 上手くいかない分岐

僕< どうやらNo99は存在してはいけないモンスターらしい。分岐処理で表示を分けるか

```php

foreach (BOKEMON::MONSTER_CODE as $key => $val) {
    if ($key === '03' || $key === '99') {
        $hideMonster[] = $key;
        continue;
    }
    $showMonster[] = $key;
}

var_dump($hideMonster); // ['おばけ']
```

僕< うわぁ！おばけだ！

吸血鬼が取れません。何故でしょうか。


## $keyの型が、、、変わってる、、、

理由は以下。

```php
var_dump(BOKEMON::MONSTER_CODE); 
/**
[
    '01',
    '02',
    '03',
    ...
    99,
];
```

PHP< int型で取れるときは勝手に変えちゃうよ

僕< うわあああああああああ

**zerofill型トラップに気をつけろ**
Pyxelで使うリソースファイルpyxres２つを１つへ統合、ミクさんと寿司をまとめてみた


Pyxelでリソースファイルを２つ並行して作っていたけど
１つにまとめたいと思ったのでその過程を残します。

※開発者さまのTwitter投稿で
　「.pyxresはzipにして解凍すれば編集可能」
　と拝見したのでそれを実際に行ってみました。


統合してみるのは次の２つ

ミクさんの画像リソース（miku.pyxres）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151818/1197e9fa-76d5-f966-b055-fdbf6480dceb.png)

寿司の画像リソース（maguro.pyxres）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151818/f6b1f10f-95cd-14bc-5f27-9d27dc597750.png)

この２つを統合（寿司側に統合）してみます。

それぞれコピーして、zipに拡張子を変更して開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151818/98ceccfc-1e41-414c-9f95-d76307a8ef08.png)

image0をsakuraエディタ等で開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151818/4a5611ed-dbec-9e92-ad7e-7f88965b4cc8.png)
編集画面の状態がそのまま対応しているように見えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151818/e4692498-2bb1-4c7d-02f4-b730223e4543.png)

まるっとコピーして、統合先の同様に開いたファイルの
0並びの領域へ移します。
今回だと、miku側の16×128の矩形選択領域を
寿司側の既存データ横に貼り付けました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151818/8db00828-8083-ae24-e63f-cfd5b3d94947.png)

貼り付けたimage0と、versionファイルを含んだフォルダを
任意名にリネーム後zipに戻し、拡張子をpyxresに変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151818/28cfc854-b28c-2954-6487-91791af6de70.png)
↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151818/af44928d-bda9-f947-2a6f-82023424ef60.png)


これをPyxelEditorで開いて確認してみます。
≫pyxel edit kurukuru.pyxres
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151818/d841e0b5-b7e9-ac9a-c394-7089dcf88a2e.png)

統合できました！

![pyxel-20221224-233024.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151818/ba951253-b221-13be-f7e3-4575d690c63a.gif)

以上です。簡単！
UnityでTest書こうとしたけど、簡単に書かせてもらえなかった話

# はじめに/やりたかったこと
- [Unity Test Runner](https://docs.unity3d.com/ja/2018.4/Manual/testing-editortestsrunner.html)を使って、アプリのロジック部分のテストをサクッと書きたかった

# 先に結論
- 自作クラスをテストしたい場合は、`Assembly Definition File(.asmdef)`を作成し、テスト側の`.asemdef`から参照させる必要がある
- アプリケーション側の`.asemdef`を作成する際、依存しているアセット側の`.asemdef`も参照する必要がありそう
 
```plantuml
@startuml
file Test.asemdef as test
file 開発中アプリ.asemdef as app
file TextMeshPro.asemdef as tmp
file ModernUIPack.asemdef as muip
file 自作アセット1.asemdef as yt1
file 自作アセット2.asemdef as yt2
file 自作アセット3.asemdef as yt3

test --> app
app --> tmp
app --> muip
app --> yt1
app --> yt2
app --> yt3
@enduml
```

# 試したこと/困ったこと
1. EditModeでディレクトリを作成
1. Test Scriptの作成
1. 自作クラスをとりあえずインスタンス化しようと試みる
    ```csharp:CheckAnswerTest.cs
    using System.Collections;
    using System.Collections.Generic;
    using NUnit.Framework;
    using UnityEngine;
    using UnityEngine.TestTools;

    public class CheckAnswerTest
    {
        [Test]
        public void test_CheckSentence()
        {
            yt.E2.Logic.QuestionManager qm = new yt.E2.Logic.QuestionManager();
        }
    }
    ```
1. エラー……
    ```sh
    Assets/xxx/Tests/CheckAnswerTest.cs(13,9): error CS0246: The type or namespace name 'yt' could not be found (are you missing a using directive or an assembly reference?)
    ```
1. アプリケーション側の自作クラスをテスト側で参照するには、アプリケーション側で`Assembly Definition`を作成し、それを参照する必要がありそうとのこと
    - [【Unity】Test Runner で自動テストを試してみようとしたら CS0246 エラーが出て困ってしまった](https://www.papacoder.net/unity-test-runner-assembly-definition/)
1. 上記の資料を参考に、`Assembly Definition`の作成をしてみる
1. そうすると今度はもっと大量のエラー……😇
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/921fece9-2310-d2f3-883d-1d9aee5afe01.png)
1. `Assembly Definition`の理解が薄いので理解を深める……
    - [【Unity】Assembly Definition Filesという神機能](https://tsubakit1.hateblo.jp/entry/2018/01/18/212834)
    - 既存プロジェクトに対してアセンブリを分けるのは、メリットもあるけど大変そうという知見を得る……
1. 地道に必要そうなアセットのアセンブリを作成＆参照していく
    - TextMeshPro
        - 既に用意されているので、参照だけする
    - ModernUIPack
        - 存在しないので、Scriptsディレクトリごと`Assembly Definition`を作成
        - 作成したものを参照
    - 自作アセット
        - そんな存在全然知らなかったので、各アセットごとに`Assembly Definition`を作成
        - 作成したものを参照
1. 6で作成したアプリケーション側の`Assembly Definition File`に9の`Assembly Definition File`を参照させる
    - 結果、以下のような感じになった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87713/d66c7e6d-8c18-41a9-d5e1-e27ce57b4f20.png)
1. Applyしたらエラーが消えた！🎉
1. 最終的な`Assembly Definition`の関係はこんな感じ
```plantuml
@startuml
file Test.asemdef as test
file 開発中アプリ.asemdef as app
file TextMeshPro.asemdef as tmp
file ModernUIPack.asemdef as muip
file 自作アセット1.asemdef as yt1
file 自作アセット2.asemdef as yt2
file 自作アセット3.asemdef as yt3
file 自作アセット4.asemdef as yt4
file 自作アセット5.asemdef as yt5
file 自作アセット6.asemdef as yt6

test --> app
app --> tmp
app --> muip
app --> yt1
app --> yt2
app --> yt3
app --> yt4
app --> yt5
app --> yt6
@enduml
```

# 感想
- EditorModeでのテスト早い〜〜〜〜〜〜！
- テストやるために、`Assembly Definition Files`という神機能に触れられて、しかも最適化できた？ので良かった
- テストを気楽に書きたい！という思いに反して、対応が重かった（知らなかったのもあり）😇
- アセット公開する際は`Assembly Definition`も提供するようにしようと思った
「雑キャラ」STM32G071とSSD1331でドット絵を表示



x だんだんめんどくなったので過去ログを見よ

x 「オバQ」風の「雑キャラ」



目的
16x16のキャラをdrawPixel分で書く
ほぼ、デザインで芸術の類でプログラム要素は、低め


![o_cop282.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b02c1755-067c-a42b-6e09-ed262959ae19.jpeg)



```c++




//OLED_SSD1331_gatu1_TEST1_071

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <SPI.h>


// You can use any (4 or) 5 pins
#define sclk 13
#define mosi 11
#define cs   10
#define rst  9
#define dc   8


// Color definitions
#define BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0
#define WHITE           0xFFFF


Adafruit_SSD1331 display = Adafruit_SSD1331(&SPI, cs, dc, rst);

#define x_ BLACK
#define xo BLUE


const uint16_t gatu1 [] = {

/*
0  0  0  0  0  0  0  0  0  0  1  1  1  1  1  1
0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
*/

x_,x_,x_,x_,x_,x_,xo,xo,xo,x_,x_,x_,x_,x_,x_,x_, //0

x_,x_,x_,x_,xo,xo,x_,x_,x_,xo,xo,x_,x_,x_,x_,x_, //1

x_,x_,x_,xo,x_,x_,x_,x_,x_,x_,x_,xo,x_,x_,x_,x_, //2

x_,x_,xo,x_,x_,xo,x_,x_,xo,x_,x_,x_,xo,x_,x_,x_, //3

x_,x_,xo,x_,x_,xo,x_,x_,xo,x_,x_,x_,xo,x_,x_,x_, //4

xo,xo,xo,x_,x_,x_,x_,x_,x_,x_,x_,x_,xo,x_,x_,x_, //5

xo,xo,xo,x_,x_,x_,x_,x_,x_,x_,x_,x_,xo,xo,x_,x_, //6

xo,x_,xo,x_,x_,x_,x_,x_,x_,x_,x_,x_,xo,x_,xo,x_, //7

x_,x_,xo,x_,x_,x_,x_,x_,x_,x_,x_,x_,xo,xo,xo,xo, //8

x_,x_,xo,x_,x_,x_,x_,x_,x_,x_,x_,x_,xo,x_,x_,x_, //9

x_,x_,xo,x_,x_,x_,x_,x_,x_,x_,x_,x_,xo,x_,x_,x_, //10

x_,x_,xo,x_,x_,xo,xo,xo,xo,x_,x_,x_,xo,x_,x_,x_, //11

x_,x_,xo,x_,xo,x_,x_,x_,x_,xo,x_,x_,xo,x_,x_,x_, //12

x_,xo,x_,x_,xo,x_,x_,x_,x_,xo,x_,x_,xo,x_,x_,x_, //13

xo,x_,x_,x_,xo,x_,x_,x_,x_,xo,x_,x_,x_,xo,x_,x_, //14

xo,xo,xo,xo,xo,x_,x_,x_,x_,x_,xo,xo,xo,xo,xo,x_  //15

};


//初期化
void setup() {

  //表示の開始
  display.begin();

  //display.fillScreen(BLACK);

}//setup


//メインループ
void loop() {

  int px,py; //座標
  int ii;    //ループカウンター

  // 画面表示をクリア
  display.fillScreen(BLACK);

  ii = 0;
  for(py=0;py<16;py++){
  for(px=0;px<16;px++){

    // display.drawPixel(座標x, 座標y, 点の色);
    display.drawPixel(px, py, gatu1[ii]); ii++;

  }//for px
  }//for py

  delay(1000); //1秒待つ

}//loop




```
飲食店横断検索サービス「おうだん君」を作って公開してみた🎉

## 完成品
https://dev.d2flr1kh2qduyd.amplifyapp.com/

出来上がったものがこちら！！

## 概要
アドベントカレンダーで色々tipsを書いていたのですが、最終成果物として１つwebアプリケーションを作ってみたのでそれの紹介

## なぜ？
アプリケーションを作ろうと思ったきっかけは以下の2つ
- アドベントカレンダーを埋めるにあたって最終的に何かを目指して開発をしていったほうがネタが集まりやすそう
- 最近新しいサービスを作れてなかったから作りたかった

## 「おうだん君」とは？
![スクリーンショット 2022-12-24 23.07.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/b3a4f08f-be58-4773-e287-7e9f6c206622.png)
おうだん君とは、タイトルに有るように**飲食店横断検索サービス**です。
皆さんお店を探す際にGoogleMapだったり食べログだったりRettyだったりいろんなサイトを見て判断の材料にしていると思います。
ただ、こっちのサイトではこう書かれてるけど他のサイトだとどうなんだろう？って思うことありませんか？
それを解決してくれるのがこのおうだん君です。

## 使い方
使い方はいたってシンプルで
![スクリーンショット 2022-12-24 23.12.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/0d3cc88e-b56d-e14e-8e54-fd0d830228ea.png)
ページにアクセスして、エリアとキーワードを入力すると
![スクリーンショット 2022-12-24 23.12.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/831f4288-47bd-3f17-c8df-5a542393b405.png)
こんな感じで検索結果が下の方に表示されます。

|食べログ|GoogleMap|Retty|
|-|-|-|
|![スクリーンショット 2022-12-24 23.13.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/70543762-a0a2-f2ff-0e3b-49aeb70ad91e.png)|![スクリーンショット 2022-12-24 23.13.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/d66da599-7902-241c-9365-6efb7aea8968.png)|![スクリーンショット 2022-12-24 23.13.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/a8adbe0c-51dd-e944-413e-a6a92f93166b.png)|

タブを切り替えることで簡単に比較ができます。
それぞれのサイトのレビュー数や評価、ストック(お気に入り)数など出しているので色々検討の材料にはなるかと。

## システム設計
ここからは裏側の話、他の記事でも触れたりしているのですが一応
![スクリーンショット 2022-12-24 23.09.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83409/9f72fce3-535a-8109-55cf-26768af0773d.png)
フロントエンドはvueで開発していて、AWS Amplifyを用いてホスティングしています。
バックエンドはサーバーレス構成になっていて、API Gatewayを経由してLambda(ruby)で各サイトに情報を取りにいっています。

## どうやってサイトの情報を取得してるの？

https://qiita.com/itaya/items/d6918a17d9f546a4ea60

https://qiita.com/itaya/items/bd3d749b079c12c35d9a

このあたりの記事で軽く触れているので興味あるようでしたら見てみてください

## 各種インフラ構築について
自分も今までちゃんとawsに触れたことはなかったので手探りでやってましたが、下記の記事を見てもらえればもがいた様子がわかるかと...

https://qiita.com/itaya/items/0ff7516c0a6ac9059706

https://qiita.com/itaya/items/dbe628b7b8d896eb6c8f

https://qiita.com/itaya/items/c184cc110f8ee01f0547

https://qiita.com/itaya/items/712e16fd0bfc7a93bcd5

## 最後に
使ってみてくれた方がいたら感想とかコメントにくれると嬉しいっす！
以上アドベントカレンダ最終日の記事でした！！！！
Laravelで開発始めるなら「TALL Stack」でしょう！！！


::: note warn
この記事では環境構築の説明はしていません。
<b><font color="red" >ただのTALL Stackの推し活するだけの記事です。</font></b>

推し活記事です。（大事なことなので2回言い申した）
:::
※恵美押勝ではない

# なんなんすかそれ？
### TALL
* TailwindCSS
* Alpine.js
* Livewire
* Laravel

これらの頭文字を並べて「TALL」と呼んでいます。

# よいとこ
### ①ファイルの数を削減できる
TailwindCSSはHTML要素に直接スタイルを書くので、基本的にCSSファイルは無くてもOKです。
Alpine.jsも同様にHTML要素に直接JSを書くので、JSファイルを別で作らなくてOKです。

この2つを使う時点で、基本的にphpファイルだけで開発できてしまいます。

::: note
<b>
<b>長いコード/少ないファイル　⇔　短いコード/多数のファイル</b>

この二者はトレードオフな関係だと思いますが、TALL Stackでの開発は「長いコード/少ないファイル」の方が好きな方に向いている気がします。
Reactみたいにコンポーネントでファイル分割しまくる開発苦手な方はTALLで開発すると良いかも？
:::

### ②動的な処理がお茶の子さいさい
PHPはサーバーサイド言語なので、ページを切り替えるたびに毎度毎度のサーバーへの通信が起こりがちですが、Alpine.jsやLivewireを使えばまるでSPAのような挙動が実現できます。

### ③Laravelが使えれば、他の学習コストがそんなに高くない
* <b>TailwindCSS</b>
慣れるまでチートシートを見ながら開発すればOKなので、実質学習コストゼロ

https://nerdcave.com/tailwind-cheat-sheet

* <b>Alpine.js</b>
文法が分かりやすいので、JavaScriptを書ければすぐ使えます。

* <b>Livewire</b>
LaravelのコンポーネントとMVCを理解していれば同じような感覚で書けるので、実質学習コストゼロ（に近い）

* <b>Laravel</b>
Laravelを使ったことある前提なので、実質学習コストゼロ

### ④直感的に書ける

説明難しいんですが、TALLは個人的に直感的に書けるなーと思ってます。
基本的にはLaravelのMVCを理解していればTALLは扱えると思います。
Livewireにはライフサイクルが存在するので、そこだけ注意すればOK。


# よくないとこ
<b>良いとこだけ書くポジショントーク的なことはせず、<font color="red" >ちゃんと良くないとこも書く聖人ムーブをキメていく。</dont></b>
（そもそもそんなポジション持ってない）

### ①日本語の情報が少ない

<b>Alpine.jsとLivewireはかなり少ないと思います。</b>
エラーや分からないことは公式ドキュメントを読みこむか、英語の記事を検索するかになってしまうのでしんどい。

::: note
<b>Alpine.jsの日本語の情報は私が量産しました。</b>
有益かは分からないですが、気になったらQiitaのアドベントカレンダーを見てください。
:::

https://qiita.com/advent-calendar/2022/alpinejs

### ②フロントはBladeで書かなければならない
Bladeじゃなくてもいいかもしれませんが、LivewireやAlpine.jsを使うとなればフロントはBladeになると思います。
ReactとかVueを使いたい方にとってはちょっと嫌かもしれないです。

ワタクシはBlade信者です。


### ③HTMLはゴリゴリ書く
②で述べた通り、bladeテンプレートを使うのでゴリゴリHTMLを書きます。
HTML書くのは嫌だという方はやめた方がいいです。

### ④コンポーネントが見にくい
* Reactの場合
緑色のキミがコンポーネントかぁ！とすぐ分かる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1311883/e9fea849-265b-af1c-d8f7-03c22f9f2cca.png)


* Laravelの場合
<b>HTML要素とコンポーネントが同化してます。
見にくすぎわろた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1311883/1bdafd26-4abc-9e49-a755-346d5e33d6d7.png)


::: note
VSCodeのプラグインで何とかできるかもしれませんが、ワタクシは知りません…
:::

# まとめ
一長一短ですね。
メリットデメリットを見た上で、自分に合ってそうと思った方はぜひ「TALL」での開発をしてみましょう。
一回開発してみればドハマりして…飛ぶぞ。
個人的Rubyメソッドまとめ

# １、メソッドの定義から
defを使って定義。
```
def hello()
    puts "hello world"
end
```
定義されたメソッドは、それより下の位置から呼び出すことができる。
```
def hello()
    puts "hello world"
end

hello()
```
出力結果として
```
hello world
```

# ２、メソッドの命名規則

メソッドの名前は、次のルールに従う。
・1文字目：英語または、「\_」(アンダーバー)
・2文字目以降：英語の大文字・小文字・数字「\_」(アンダーバー)
・慣習として、メソッドの先頭には大文字を使わない

# 3,引数と戻り値を追加する
```
def sum(x, y)  # xとyが引数
    return x + y  # 戻り値(returnは省略可)
end

puts sum(3, 4)  
puts sum(300, 400)
num = sum(30, 40)  # numに戻り値が代入される
puts num   
```
出力結果は
```
7
700
70
```
色々調べた結果TPM2.0を有効にできたので記事にしてみた

初投稿です！

今回は，Windows10である自作PCをWindows11にアップグレードをするという回です．
ただ，更新だけするならこの記事を書いてないです．
今回記事を書こうと思ったきっかけはある問題でWin11の要件に満たしてなかったからです．

それは，TPM2.0を有効にしていなかったことです．

というわけで，今回は折角TPM2.0を有効にしたのでその備忘録として記事にしたいと思います！

まず，自分のPCがどのくらい要件に満たせているかを確認するために自分は「PC正常性チェック」を使いました．
https://aka.ms/GetPCHealthCheckApp

![2022-12-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071716/24e6d421-cf01-d323-4ccb-30925eccd3f3.png)

すると，TPM2.0が有効になっていないことを教えてくれます．
というわけで，TPM2.0を有効にする旅に出かけたいと思います．

☆動作環境☆
・OS→Microsoft Windows 10 Home
・CPU→Intel(R) Core(TM) i7-10700
・メモリ→16GB
・マザーボード→B560M AORUS PRO AX

TPM2.0を有効にするには，BIOS画面で編集します．
BIOS画面に移行するためには，【設定】→【更新とセキュリティ】→【回復】→【今すぐ再起動】で一旦再起動をします．
すると，オプションの選択の画面が表示されるので【トラブルシューティング】→【詳細オプション】→【UEFIファームウェアの設定】→【再起動】に行くとBIOS画面を表示することができます．

BIOS画面が表示出来たら，Settingタブから【Miscellaneous】を選び，【Intel Platform Trust Technology(PTT)】をDisabledからEnabledに変更します．

![69417542-0ABA-42F3-8055-864AEF6AEF9C.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071716/d2049124-4383-82da-b54e-1af71490e054.jpeg)

変更出来たら，Save&ExitタブからSave&Exit Setupで設定を保存し終了します．

![90181D8B-7EA9-4486-B274-AAE25BE5B8B5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071716/11bd35c5-69c7-4c75-b155-9676ec0fc8ee.jpeg)

BIOSを終了したら再起動するので，再起動したら要件が満たせているか「PC正常性チェック」でもう一度確認します．

![2022-12-15 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071716/4c509fa0-0219-6d18-7215-b0e4912ef53a.png)

すると，要件を満たせていると確認することができます．そのほかに，「WhyNotWin11」(URL:https://github.com/rcmaehl/WhyNotWin11/)
でもすべての要件が満たせているか確認することができます．

![2022-12-15 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071716/075122f7-be44-f965-cf95-674d93160d06.png)

全ての要件が満たせていることを確認したのでいざ，アップグレードを！…と思ったのですが，肝心の設定の更新ではまだアップグレードができない状態でした．なので，いったんあきらめて後日へ…

～数日後～

やりました！アップグレードができる状態になりました！要件を満たしてもすぐには反映されないっぽいですね…

![2022-12-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071716/4c3223a9-b404-9b6b-a5bd-d0dd0df34f19.png)

というわけで，さっそくWin11にアップグレードしました！これで，目標達成です！

もし，自分と同じ問題でWin11にアップグレードできない方がいましたら，参考にしてみてください！
（スタートボタンが真ん中が気持ち悪かったので左下に設定しなおしました．）

![2022-12-24 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071716/cd865c3b-0f64-19b5-d5b8-5978cafef6e1.png)

～後記～
初めてブログを書いてみました．わかりずらい点があったらすみません，こんな感じで様々な分野で時間があったら備忘録みたいな形で書いていこうと思います．よろしくです．
特定の文字列以外が来てほしくないしエディターに強制してほしい！

## 特定の文字列以外が来てほしくないしエディターに強制してほしい！

そう思ったことは、人生で１度や２度ではないはずです。


フィールドを全部Read Onlyにする`as const`と型定義で実現することができますよ
- 宣言時から変更・更新されないことが保証される。
- ReadOnlyな要素は型として指定することができる！　☜ これが嬉しい

宣言のやり方
```typescript
const YousoList = [
    "要素1",
    "要素2",
    "要素3",
    "要素4",
] as const
export type yousoType = typeof YousoList[number];
// 以下と同値になる
export type yousoType2 = "要素1" | "要素2" | "要素3" | "要素4" ;

```

## 直接 `|`でつなぐものとas constの違い
https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types

- Enum的な挙動をする型には`literal-types`と呼ばれるものがある。
- これは、特定の文字列で型を判断することができる機能である。
- as const導入前にこれをやろうとすると型定義の変数と実際に使う変数の２か所を変更しなければならず大変だった。
【Bash】trapコマンドの使い方

## `trap`コマンドとは

`trap`コマンドはシグナルを受け取った際の動作を設定するコマンドです。

以下のように記述します。  

```terminal
trap 'コマンド' シグナル
```

上記の「シグナル」にはシグナル名またはシグナル番号を記述します。  

## シグナル

使用できるシグナルの一覧は`trap -l`を実行することで確認できます。  

```terminal
$ trap -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX
```

| シグナル名 | シグナル番号 |                        説明                        |
| :--------: | :----------: | :------------------------------------------------: |
|   SIGHUP   |      1       |     制御端末を切断するか、制御プロセスを終了     |
|   SIGINT   |      2       |  ユーザーが`Ctrl + C`（割り込みシグナル）を入力  |
|  SIGQUIT   |      3       |    ユーザーが`Ctrl + \`（終了シグナル）を入力    |
|  SIGTERM   |      15      | 終了シグナル。`kill)コマンドのデフォルトシグナル |
|    EXIT    |      0       |                  シェルの終了時                  |

## 設定されているコマンドの確認

現在設定されているコマンドを確認するには`trap -p`を実行します。  

```terminal
$ trap 'echo trap-exit' EXIT 
$ trap 'echo trap-sigint-sigquit' SIGINT 3
$ trap -p
trap -- 'echo trap-exit' EXIT
trap -- 'echo trap-sigint-sigquit' SIGINT
trap -- 'echo trap-sigint-sigquit' SIGQUIT
```

`trap -p シグナル`とすることで特定のシグナルの設定を確認できます。  

```terminal
$ trap -p EXIT
trap -- 'echo trap-exit' EXIT
```

## 設定の上書き

同じシグナルに対して複数回設定すると上書きされます。  

```terminal
$ trap 'echo trap-exit' EXIT
$ trap 'echo trap-sample' EXIT
$ trap -p EXIT
trap -- 'echo trap-sample' EXIT
```

また設定をリセットする場合にはコマンド部分を記述せずに実行します。  

```terminal
$ trap EXIT
$ trap -p EXIT
<!-- 何も出力されない -->
```
Microsoft Sentinel分析ルールの紐解き（User Assigned Privileged Role）

Microsoft Sentinelにおいてもともと準備されている分析ルールについてクエリの中身や注意点等を紐解いていく。

:::note warn
警告
なお、このルールは利用環境によっては過検知が多発するためチューニングが必要である。
例えば
- PIM(Privileged Identity Management)による権限付与は検知除外する
- 条件付きアクセスで許可されたロケーションからの操作は検知除外する
- 特定の作業者（情報システム部門の担当者 等）による権限付与は検知除外する

である
::: 


# 1. ルール概要
|項目|説明|
|--|--|
|重大度|高|
|ルール名|User Assigned Privileged Role|
|ルールの種類|Scheduled|
|ルールの頻度|2時間ごとにクエリを実行|
|ルールの期間|過去2時間のデータ|
|バージョン|1.0.3|
|説明|新しい特権ロールがユーザーに割り当てられたときに識別されます。ロールの対象となるアカウントには、特権的なアクセス権が与えられています。割り当てが予期しないものであったり、アカウント所有者の責任ではないロールに割り当てられたりした場合は、調査してください。（by DeepL）|
|Ref|https://learn.microsoft.com/ja-jp/azure/active-directory/fundamentals/security-operations-privileged-accounts#things-to-monitor-1|

# 2. 活用するテーブル
|テーブル名|概要|参考URL|
|--|--|--|
|AuditLogs|Azure ADの監査ログ|<https://learn.microsoft.com/ja-jp/azure/azure-monitor/reference/tables/auditlogs>|

# 3. クエリ解説
```Kusto:User Assigned Privileged Role / version1.0.3
// AzureADの監査ログを対象とする
AuditLogs
// 大文字小文字区別せずに CategoryフィールドがRoleManagementのものに絞り込む
| where Category =~ "RoleManagement"
// 操作の種類が付与のものに絞り込む
// https://cloudsteady.jp/post/33813/
| where AADOperationType in ("Assign", "AssignEligibleRole")
// アクティビティもしくは操作の名称がPIMもしくはアクティブによる権限追加によるものに絞り込む
// ※ユーザー、グループ問わずに権限付与された際は上記文字列になることに注意
| where ActivityDisplayName has_any ("Add eligible member to role", "Add member to role")
// TargetResourcesフィールドの配列データを展開する
| mv-expand TargetResources
// TargetResources.modifiedPropertiesフィールドの配列データを展開する
| mv-expand TargetResources.modifiedProperties
// displayName_ というフィールドにstring型で変更内容の表示名を格納
| extend displayName_ = tostring(TargetResources_modifiedProperties.displayName)
// 大文字小文字区別せずに displayName_フィールドがRole.DisplayNameのものに絞り込む
| where displayName_ =~ "Role.DisplayName"
// RoleName というフィールドにstring型で付与された権限名を格納
| extend RoleName = tostring(parse_json(tostring(TargetResources_modifiedProperties.newValue)))
// 大文字小文字区別せずに付与された権限名にAdminのものに絞り込む
| where RoleName contains "Admin"
// InitiatingApp というフィールドにstring型で権限が付与された際のアプリケーションの表示名を格納
| extend InitiatingApp = tostring(parse_json(tostring(InitiatedBy.app)).displayName)
// Initiator フィールドに権限付与のきっかけとなった情報を格納する
// アプリケーションの場合（InitiatingAppフィールドが何かしら文字列が入っていれば）そのアプリケーション名を
// 文字列が入ってない場合は権限付与したユーザーのUPNを格納する
| extend Initiator = iif(isnotempty(InitiatingApp), InitiatingApp, tostring(parse_json(tostring(InitiatedBy.user)).userPrincipalName))
// Uncomment below to not alert for PIM activations
// Privileged Identity Managementによる権限付与の場合を除く
//| where Initiator != "MS-PIM"
// Target というフィールドにstring型で付与されたユーザーのUPNを格納する
| extend Target = tostring(TargetResources.userPrincipalName)
// 発生時間を1時間単位に丸め、操作名、権限名、権限付与された対象ユーザーのUPN、権限付与したアプリもしくは人、付与結果にサマライズする
| summarize by bin(TimeGenerated, 1h), OperationName,  RoleName, Target, Initiator, Result
// AccountCustomEntityフィールドに権限付与された対象ユーザーの情報を格納する
| extend AccountCustomEntity = Target
```