OmniAICreator/Qiita-1.07M huggingface dataset:
居酒屋シフト提出の紙をいい感じにするWebサイトを作る


こんにちは、居酒屋勤務（ガチ）をしているエンジニア的な人です。

> 参考: [エンジニア社長がコロナ禍下で人生初の居酒屋バイトを始めた話](https://covergraph.jp/article/jimukyoku8-1)

> ![スクリーンショット 2021-12-25 23.50.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/f53f3bad-2739-2c26-133b-a3c789d8172c.png "スクリーンショット 2021-12-25 23.50.13.png")

以前、居酒屋のシフト提出周りをいい感じにするLINE Botを作ってみました。

> [紙で申請を出す居酒屋店員のシフト希望と管理業務をちょっとスマートにする](https://qiita.com/n0bisuke/items/0c6d6a236b31e3897d41)

この時は紙で提出するシフトを写真を撮ってLINE Botに送ることで管理をしやすくする仕組みを作ってみました。

**とはいえ紙業務は無くなっておらず、紙を印刷するタスクは継続中** でした。

## シフトの紙、印刷業務

シフトの紙を印刷して、スタッフに配布するという業務は継続的に残っています。

こんな感じで希望を紙に書いて提出しています。

>  ![スクリーンショット 2021-12-25 23.49.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/fa8c29de-0e0d-888f-b869-1d17cc549b93.png "スクリーンショット 2021-12-25 23.49.20.png")

この紙自体もこんな感じで印刷してカットしてます。

> ![スクリーンショット 2021-12-25 23.56.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/556c7e4e-8306-1b46-7df2-d18469cfbe72.png "スクリーンショット 2021-12-25 23.56.54.png")

## 日付設定の手間。エクセルからWebへ

シートはエクセルで作っていますが、毎回スタッフは日付をいじってシートを作っていて、かなり面倒な状態でした。

話を聞くとカレンダー的なUIがあって、 **自動的にカレンダーに日付が反映されてたら印刷するだけでめちゃ助かる**とのことだったのでそんな感じのWebサイトを作ってみました。

## サンプルを探して改変していく。

まずはカレンダー実装は世の中的に色々出てるので、ググって出てきたページを参考に実装してみます。

> [HTMLでカレンダーを使う方法を解説！作り方や埋め込み方法など](https://webukatu.com/wordpress/blog/8050/)

### まずはサンプルを実装してみる

側だけできた感

```html
省略
       <tr>
        <th>月</th>
        <th>火</th>
        <th>水</th>
        <th>木</th>
        <th>金</th>
        <th>土</th>
        <th>日</th>
      </tr>

      <tr class="day">
        <td>1</td>
        <td>2</td>
        <td>3</td>
        <td>4</td>
        <td>5</td>
        <td>6</td>
        <td>7</td>
      </tr>
省略
```

> ![スクリーンショット 2021-12-25 11.15.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/c55e994f-d377-ad82-1d44-d83bac79f3d5.png "スクリーンショット 2021-12-25 11.15.19.png")

### JS実装

結構勉強になりますね

- 指定の日付から曜日の取得
	- https://colo-ri.jp/develop/2010/01/javascript_this_month_and_last_month.html
- 月末の日付を取得
	- 31日なのか30日なのか28日なのか知りたいですよね。
	- https://qiita.com/akase244/items/f558b9b3c51804103d16


特にシフト業務に関していうと、当月ではなく翌月の話になるので、翌月の末日を知るは実装的に参考サイトが助かりました。

```js
	//翌月末を知りたい
	const dt = new Date(); // 「今日」のインスタンスを取得
	// console.log(dt);
	const lastDayNextMonth = new Date(dt.getFullYear(), dt.getMonth() + 2, 0);
	const lastDayVal = lastDayNextMonth.getDate();
	console.log(lastDayVal); // Fri Feb 28 2014 00:00:00 GMT+0900 (東京 (標準時))
```


## 一旦出来たページ

あんまり上手く使えてないけど勉強がてらSvelteで作ってます。

> ![スクリーンショット 2021-12-25 23.42.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/62057aa9-353c-7c8d-6c95-2f84d993eda8.png "スクリーンショット 2021-12-25 23.42.29.png")

一旦出来たけどCSS調整がまだ出来てないですね。シフトの紙に希望休を書き込むスペースが作れてなく、このままだと使いにくい感じになってると思います。

## まとめと来月

一旦そんなWebサイトを作りましたが、毎月15~20日頃にならないとシフト用紙を印刷するルーチンがないので、クリスマス時期の今は実運用としていい感じなのか？を試せないです。

来月にスタッフの人に試してもらってダメなのか有効なのかを確かめたいと思います。

少しでも作業負荷が減ると嬉しいですね。

それでは！
最近の解いたCTFまとめ

# 最近の解いたCTFまとめ
#### Harekaze mini CTF 2021
・ first exam
・ sage training
・ mulmulmulti-prime rsa
・ lost key


#### hxp CTF 2021
・ gipfel

## Harekaze mini CTF 2021
###first exam
$ct = flag \otimes key$なので，$ct\otimes key = flag \otimes key\otimes key$で求まりますね.base64に注意して戻すと
`HarekazeCTF{OK_you_can_join_wizardry_school}`
これで無事に魔法学校に入学できました!
###sage training
$F_p$の行列を$e$乗したもの暗号文としています

```math
{\begin{pmatrix}
p^e & 0 \\
0 & flag^e\\
\end{pmatrix}}
={\begin{pmatrix}
p & 0 \\
0 & flag\\
\end{pmatrix}}^e
```
より$n=pq$を考えると$gcd(n,p^e)=p$となるので$p,q$が求まります.
後はRSAぽく $ed\equiv 1\ mod (\varphi(n))$として
$pt \equiv flag^d \ mod(n)$ で求まります!


`HarekazeCTF{which_do_you_like_mage_or_sage?}`
個人的にはmageの方が好きですね!

###mulmulmulti-prime rsa

通常のRSAの素数と$flag$の十進の数以下の素数をかけ合わせたものをNとしています.
ここで，慣れている人だと素数多い→CRTかな?となりそうですけど，謎に

```python:problem.py
from sympy.ntheory.modular import crt
```
となればCRTかぁってなりますね

```python:solve.py
list1=[]
list2=[]
while num< 1000:
    if N%num==0:
        N =N// num
        list1.append(num)
        d = gmpy2.invert(e,num-1)
        list2.append(pow(c,d,num))
        print(num)
    num += 1

print(list2,list1)

print(long_to_bytes(crt(list2,list1)))
```
これでおしまい!

`HarekazeCTF{Small_prime_numbers_give_a_large_amount_of_information}`

###lost key

さぁラストです!
$flag$の文字列を一文字ずつUTF-8に変換しそれを基準にして$e$乗しています．

```math
f(x) =  \left\{
\begin{array}{ll}
m[0]^e \equiv ct[0]& mod(n) \\
m[1]^e \equiv ct[1]& mod(n)
\end{array}
\right.\\
= \left\{
\begin{array}{l}
m[0]^e - ct[0] = k_0n \\
m[1]^e - ct[1] = k_1n
\end{array}
\right.\\
```

よって，$gcd(m[0]^e - ct[0],m[1]^e - ct[1])=n $ ( $ k_0,k_1 $ が互いに素なため)
$n$が求まります．ここで，mは0x20から0x7fまでの値が取れるのですべて$e$乗して合致するか調べていくと答えが出ます．
`HarekazeCTF{Can_you_Recover_with0ut_the_public_4nd_pr1vate_keys!?}`

###感想
タイムアタック的な感覚で面白かったです．解き方はわかるけどコードが書けない人からすると3つ目で少し事故りました...要精進...


##hxp CTF 2021
ついでなんで書いちゃいます

###gipfel

```math
\begin{align}
password &= random\\
g &= H(password)\\
privA &\equiv random\\
pubA &\equiv g^{privA} \ mod(q)\\
shared &\equiv pubB^{privA} \  mod(q)\\
verA &\equiv g^{shared^3} \ mod(q)\\
verB &\equiv g^{shared^5}\ mod(q)\\
\end{align}
```

出現する変数をまとめてみました．ここで行うことは$varB, password, shared$の導出です．
私たちが行えることは$pubB$の値の設定，$pubA,varA$の値の確認です．
ここで，$pubB$の値を決めることで$shared$→$verA$→$verB$と順に値が決まっていきます．
強引に$n$乗根を求めてもいいのかもしれませんが，$pubB=q-1$とすることで$shared=-1 \ or \ 1$となり，更に進めて$verA=verB=g^{-1}\ or \ g$となるため簡単に$varB, shared$を導出でき残りの$password$は$[0,10^6]$の間にあるためブルートフォースでも短時間で求めることができます．
後は$key$をハッシュ関数から求めAESを解くとflagが得られます．
`hxp{ju5T_k1ddIn9_w3_aLl_kn0w_iT's_12345}`
Vonage Video APIのチュートリアルを試してみた

[最新CPaaSコミュニケーションAPIを比べる or 使ってみよう！ 【PR】Vonage Japan Advent Calendar 2021](https://qiita.com/advent-calendar/2021/vonage2021)に、ギリギリですが飛び入りで5日目に投稿させていただきます。

### 実施したチュートリアル

[Set up a Basic Web Client](https://tokbox.com/developer/tutorials/web/basic-video-chat/)

チュートリアルを実施すると次の画像が表示されました。
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/68cf4cb0-6708-6ed7-02e3-9c5b0b2d24f3.png)
Macbookのカメラからの画像です。散らかっていてすみません。

### 実施中に気になった事

ブラウザの翻訳機能で英語を日本語に翻訳して実施しました。

![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/7c75ccb7-fed8-a171-0218-a958224e6bbc.png)

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/afdb043e-5e10-15cb-e89f-efa5fad1142a.png)

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/d8a7805d-791a-31fc-f1d6-c0b5a7895f10.png)

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/63d131e3-fced-f122-dbee-58b79ac6acfc.png)

Create Project押下すると2種類選べるのですが、Vonage Video APIを選んでください。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/02897d54-d47c-8e8a-d60e-8b3ded9713de.png)

プロジェクト名はmyprojectにしました。VP8はそのままで、「Create」押下。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/c033fae0-974b-0e6c-b179-5bfa86a1b7c6.png)

API KEYとSECRETをapp.jsにコピー。トークンはそのままvar token = "YOUR_TOKEN";放置で動きました。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/6e0dec17-6058-c3af-b2c5-6fab3817d554.png)

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/071bcdfc-4749-abdb-67a1-c6c66523cb67.png)

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/c338c159-4404-b29e-1a94-94f939994c94.png)

Invalid token format Token: YOUR_TOKEN (1004)
無効なトークン形式トークン：YOUR_TOKEN（1004）

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/56277dbd-2dbb-7813-86c8-74eec9feff7c.png)

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/22f4bd6e-87cd-690c-1a68-e62670d62fd5.png)

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/1440e5bc-aedb-157d-69c7-39f9323e7464.png)

![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155894/be2f2007-1f21-1f99-2f9a-875ffab103d4.png)


### 感想
サーバーを使わずに、ローカル環境で気軽に試せたので良かったです。
Raspberry Pi OS Bullseyeにenebular-agentをインストールする

Debian Bullseyeをベースとした、Raspberry Pi OSが2021/10/30にリリースされました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/33e2d32f-a647-1fed-a598-224bccb4dcf0.png)


このRaspberry Pi OSにenebular-agentをインストールしようとするとエラーが起こり、インストールができません。
これは、インストーラーの問題によるもので、現在、対応を予定していますが、インストーラーではenebular-agentがインストール出来ないのが現状です。
インストーラーを使用しないで、手動であればインストールできますので、その方法を解説します。

# enebular-agentの手動インストール
enebular-agentは、githubにソースコードが公開されています。githubからソースコードをダウンロードし、npmでインストールすれば、インストールできますが、素のRaspberry Pi OSにインストールするためには以下の手順で、モジュールを事前にインストールする必要があります。

```shell
$ sudo apt install -y cmake
```

次にNodejsとnpmをインストールしますが、ここではnを使用して、enebular-agentでサポート対応しているNodejs v2.22.5をインストールします。

```shell
$ curl -L https://git.io/n-install | bash
$ sudo ./n/bin/n 12.22.5
```

enebular-agentのソースコードをgithubからクローンして、インストールしていきます。

```shell
$ git clone https://github.com/enebular/enebular-runtime-agent.git
$ cd enebular-runtime-agent
$ cd agent
$ npm ci && npm run build
$ cd ..
$ cd node-red
$ npm ci
$ cd ..
$ cd port/awsiot
$ npm ci && npm run build
```

enebular-agentはenebularとの接続にAWS IoTを使用します。インストーラーを使えば、自動的に設定されますが、手動で設定します。
設定方法については、[AWSIoTの環境をセットアップする](https://qiita.com/jksoft/items/c9892ea41c053738df5c#awsiot%E3%81%AE%E7%92%B0%E5%A2%83%E3%82%92%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E3%81%99%E3%82%8B)を参照下さい。

enebular-agentとAWS IoTを接続するための設定方法は、[enebular-agentとAWSIoTの接続設定](https://qiita.com/jksoft/items/c9892ea41c053738df5c#enebular-agent%E3%81%A8awsiot%E3%81%AE%E6%8E%A5%E7%B6%9A%E8%A8%AD%E5%AE%9A)を参照下さい。

# enebular-agentを動作させる

enebular-agentは、```./enebular-runtime-agent/ports/awsiot/```のパスの上で、以下のコマンドで起動します。

```
$ DEBUG=info npm run start
```

最終的に以下のように表示されれば、正常に起動しています。

```
internal: aws-iot: Connected to AWS IoT
internal: aws-iot: Thing shadow registered
```

# 最後に
とりあえず、enebular-agentが動作することが確認できました。ちなみにこの手順では、enebular-agentのリモートメンテナンスの機能は使用できません。
その他の機能もすべて確認はしていないので、その点はご了承下さい。
フォルダのパーミッション設定やアプリケーションが動作する権限もインストーラーでインストールされるものとは異なります。

※本記事は、enebular公式に動作を保証するものではありません。
DX白書 2021 と仮説検証サイクル

これは [弁護士ドットコムアドベントカレンダー 2021](https://qiita.com/advent-calendar/2021/bengo4com) の25日目の記事です。
昨日の記事は @t0daaay さんの [Cypress Component Test Runner を Vue Vite で使ってみる](https://qiita.com/t0daaay/items/c7fa204c30112ad6305e) でした。

# はじめに
「[DX白書 2021](https://www.ipa.go.jp/ikc/publish/dx_hakusho.html)」がIPAにより10月に発行された。「IT人材白書」と「AI白書」を統合し、新たに今年から発行された白書だ。
訳も分からずDXが連呼される中で「またDXか」と思われるかもしれないが、白書の内容は非常に興味深いものになっている。

# デザイン思考・アジャイル開発・DevOps
とはいえ白書の内容は戦略・人材・開発手法と多岐に渡るので、開発手法の部分に絞って話を進めたい。
開発手法としてはデザイン思考・アジャイル開発・DevOpsが主に取り上げられている。

![システム開発手法.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65313/66efa9bf-fa6c-fde1-b483-d8020f273b32.png)
「DX白書 2021」 (IPA) より引用

- デザイン思考
    - 製品やサービスのユーザーが抱える真の問題と最適な解決方法を探索し創出す
る思考方法
- アジャイル開発
    - 小さなチームで開発・適用を短期間で繰り返しながら開発する手法
- DevOps
    - 開発チームと運用チームが技術的のみならず組織的文化的にも連携することでスピードと品質の向上を目指す

VUCAとも言われる環境が激しく変化する中で、開発手法としての対応としては、各段階で仮説検証サイクルを回していく必要がある。
まぁVUCAだからというよりも、従来から[開発プロジェクトの半数以上が失敗](https://business.nikkei.com/atcl/opinion/15/100753/030700005/)してきた中で、早く失敗して早期に軌道修正するためにこうした手法を取り入れることが競争力につながる面もあるのだろう。

# 日米の差
と、ここまでであればWeb系エンジニアとしては濃度の差はあれ認識している所だろう。
ただDX白書ではこれらにおいて日米企業での比較調査を行っている。

たとえば上記にとりあげた各手法の活用度では、圧倒的な差がついている。

![開発手法の活用状況.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65313/ae3197dd-e850-c2bb-fbd7-c80890584e3e.png)
「DX白書 2021」 (IPA) より引用

より大きなところでは評価や見直しの頻度だろう。

![評価や見直しの頻度.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65313/4171e99f-f186-c198-76e5-03b0c42088ec.png)
「DX白書 2021」 (IPA) より引用

米国企業の大半がCXを毎週/毎月見直している一方で、日本企業では半数が評価対象外としている。他の項目も似たようなものだ。

検証サイクルを高頻度にしていくには、例えば予算や組織編成や他部門との連携も必要であり、開発部門だけが取り組んでできるものではない。組織全体としてアジリティを高めていく必要がある。
日本でもデザイン思考やアジャイルを取り入れている企業も多いだろうが、組織全体としてここまで徹底して高頻度に回すことができているのは少数だろう。

結局は経営陣のコミットメントが必要ということだが、それは巻頭言でも指摘されている。

> そもそも組織のDXとは、その組織の経営の問題であり、デジタルはその経営変革の重要なリソースでしかありません。本白書の方向づけのためにIPA新白書有識者委員会の委員の皆さんにご議論いただきましたが、委員の皆さんが言うことはほぼ同じでした。
> まずは経営者自身がデジタルの意味を率先して理解し、自分は何のため誰のためにビジネスをしているかという覚悟とビジョンを提示し、DX推進のリーダーシップを発揮することが何よりも大切であるということ。

# おわりに
DX白書は他にも興味深い内容が多いが、特に興味を惹かれた点を紹介してみた。

今年も1年間おつかれさまでした。みなさんよいお年を。
CSSで描く、少し理解しやすい吹き出しのしっぽ

[Qiita株式会社 Advent Calendar 2021](https://qiita.com/advent-calendar/2021/qiita)（2）の9日目の担当は、CX向上グループの@xrxoxcxoxです！

https://qiita.com/advent-calendar/2021/qiita

## この記事の概要

`CSS 吹き出し`で調べると大抵borderを使ったテクニックが出てきます
しかし、実際に描画される大きさがパッと理解しづらくないですか？

記述量は少し増えるものの、頭で理解しやすい吹き出しのしっぽの書き方を記事にしてみました。
`clip-path`を使うのがポイントです。

## 共通するスタイル

以下のHTML, CSSは全てに共通するので先に抜き出しておきます。

```html:HTML
<div class="base balloon">
  clip-pathを使った吹き出し1
</div>
```

```css:CSS
.base {
  background-color: #fff;
  border-radius: 1rem;
  font-weight: bold;
  line-height: 1;
  padding: 2rem;
  position: relative;
}

.base::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
}
```

## パターン1：左右対称

| イメージ |
| --- |
| ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/1bbd42dc-2444-d2b7-64e7-aeb880538e74.png) |

よく紹介されているのは以下のようなコードです。

```css:CSS
.balloon::after {
  border: 1rem solid transparent;
  border-top: 1rem solid #fff;
}
```

`border`を全体に指定した上で`border-top`だけオーバーライドする……。
なんとも不思議なコードですね。

`clip-path`を使うとどうなるでしょう？

```css:CSS
.balloon::after {
  background-color: #fff;
  width: 2rem;
  height: 1rem;
  clip-path: polygon(0 0, 50% 100%, 100% 0);
}
```


幅が2rem、高さが1remの矩形の中に`0 0, 50% 100%, 100% 0`の座標で点が打たれている、と多少脳内でレンダリングしやすくありませんか？

## パターン2：片側に寄ってる

| 片側に寄ってる |
| --- |
| ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/06c518bc-5593-6af9-3cc5-a93728bcd7f1.png) |

よく紹介されているのは以下のようなコードです。

```css:CSS
.balloon::after {
  border-top: 0.5rem solid #fff;
  border-right: 1rem solid transparent;
  border-bottom: 0.5rem solid transparent;
  border-left: 1rem solid #fff;
}
```

またなんとも不思議な感じがしますよね。

こちらも`clip-path`に置き換えてみましょう。

```css:CSS
.balloon::after {
  background-color: #fff;
  width: 2rem;
  height: 1rem;
  clip-path: polygon(0 0, 0% 100%, 100% 0);
}
```

先ほどとほぼ同様です。

幅が2rem、高さが1remの矩形の中に`0 0, 0% 100%, 100% 0`の座標で点が打たれています。

パターン1よりも更に`border`のテクニックが複雑になっているので`clip-path`のシンプルさが際立っている気がします。

## まとめ

- 吹き出しのしっぽをCSSで描くときはclip-pathを使うと
    - 記述量が少し増えるものの
    - デザインのモックアップを見たままコードに変換しやすい
Unityでマウスカーソルがオブジェクト上に来た時の処理

オブジェクトを選択して，コンポーネントを追加 ⇒ イベントトリガー を選択する．

![スクリーンショット (139).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149593/d4c2e8d3-1926-424f-b6e6-9c659dbfa479.png)

⇒Pointer Enterを選択する．
⇒重ねる対象のオブジェクトをドラッグ＆ドロップする．
⇒重なったときに処理するための関数を選択する．<font color="red">※コンポーネント追加したスクリプト内のpublic関数しか使えなので注意．</font>
![スクリーンショット (140).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149593/2af0294a-77a2-15d5-71df-a0e5662fc5fb.png)
Arduinoでレトロなエンジン車が復活？　 オープンソースECU Speeduino 2021

#はじめに
3年ほど前に、[Arduinoでクルマのエンジンが動く？　オープンソースECU Speeduino](https://qiita.com/covao/items/e592b07983b901c22ecc)の記事を書きました。その後アップデートされた内容を含めて、概要についてまとめてみたいと思います。
#Speeduinoとは
オープンソースのエンジン電子制御ユニットをつくるプロジェクトです。😎
https://speeduino.com/home/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329764/8b9bce8e-4181-624c-2e8b-a2662439c6ea.png)

#ハードウエア
センサで回転数、空燃比、温度などを計測し、燃料の噴射量や点火タイミングをリアルタイムで制御します。
##マイコンボード
### Arduino Mega
基本構成では、Arduino Mega 2560を使用しています。Arduinoシリーズの中でI/Oポート数の多いマイコンボードです。 純正のArduino Mega互換ボードであれば、Amazonで1500円前後で入手できます。半導体不足のご時世ですが、十分に入手が可能なようです。😊
### Teensy
ARM Cortexを搭載したマイコンボードです。CAN BUSポートが含まれています。Teensy4.1では ARM Cortex M7 600MHzを搭載しています。
##ECU基板、アセンブリー品
### SPEEDUINO V0.4 ASSEMBLED
部品実装された基板です。Arduino Megaを利用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329764/07aaeb49-e240-e103-78bd-cdf03abd8384.png)
https://speeduino.com/shop/home/20-speeduino-v04-complete.html

### MIATA / NX5 NA6 PLUG N PLAY SPEEDUINO
Arduino Megaマイコンボードを搭載したアセンブリーECUです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329764/643689ed-3e26-5e9e-22d7-d9df874a37a1.png)
https://speeduino.com/shop/plug-and-play-units/22-miata-nx5-na6-plug-n-play-speeduino.html

### SPEEDUINO Dropbear
Teensy3.5マイコンボードを搭載したアセンブリーECUです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329764/e4c207d6-fa5c-a985-68f1-a7de39f6011a.png)
https://speeduino.com/shop/home/38-speeduino-dropbear.html

#ソフトウエア
##ソースコード
- Githubに公開されています。 https://github.com/noisymime/speeduino
- C言語(一部C++言語)で記述されています。
- 高速な信号処理とエンジンの様々なバリエーションに対応するようプログラムされています。

## TunerStudio
- EFI社の適合ツールで、エンジンの状態を計測しながら、パラメータのチューニングが行えます。
- 燃料噴射量や点火タイミングなど、きめ細かなチューニングができます。 

https://speeduino.com/home/about/interface

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329764/b89dc536-2e14-aa17-dffc-9edc5039bd6c.png)

## SpeedyLoader
Arduino Megaにビルド済みのファームウエアを書き込むソフトです。
https://speeduino.com/home/support/downloads
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329764/ee6814ea-389d-84f2-3725-86a2a464815f.png)

## ArduStim
エンジンの回転を検出するクランク角センサの信号を模擬するシミュレータです。
様々なメーカーの信号を生成が可能です。
https://github.com/speeduino/Ardu-Stim/releases/tag/0.0.3
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329764/370828a0-84a9-1f32-994e-4e2747d8ef3e.png)

#Supeeduinoを使ったDIYやテスト走行動画
- [Supeeduino - YouTube](https://www.youtube.com/c/Speeduino/videos)
- [Supeeduinoを使ったテスト走行例 - YouTube ](https://www.youtube.com/results?search_query=speeduino+test+drive)

#コミュニティ
- [Speeduino Forum](https://speeduino.com/forum/) 
- [Facebook](https://www.facebook.com/groups/191918764521976/) 
- [Slack](https://speeduino.com/home/community/slack) 

#さいごに
脱炭素化のながれのなか、自動車はEVシフトの道へと歩みつつあります。
内燃機関のエンジン車は、将来、真空管オーディオやレトロゲーム機のように、DIYの世界で一部のマニアに支持されていく世界となっていくのかもしれません...
M1チップ搭載MacでCocoaPods導入時のTips

# なんの記事
- m1Max macbookを新しく迎え、意気揚々とCocoapodsを`sudo gem install cocoapods`でインストールし、xcodeのプロジェクトをコンパイルしようとしたところ、`pod install`でエラーを吐いた。
- 調べたところ、3つの解決方法があったが、`Homebrew`から`Cocoapods`インストールするのが一番環境を汚さなさそうだったから、この方法を採用。


## エラー
```
LoadError — dlopen(/Library/Ruby/Gems/2.6.0/gems/ffi-1.15.0/lib/ffi_c.bundle, 0x0009): missing compatible arch in /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.0/lib/ffi_c.bundle — /Library/Ruby/Gems/2.6.0/gems/ffi-1.15.0/lib/ffi_c.bundle
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require’
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require’
/Library/Ruby/Gems/2.6.0/gems/ffi-1.15.0/lib/ffi.rb:6:in
```

## 3つの解決方法
- 以下の3つの方法のどれでも一応は機能するみたい。だが、三番目の方法を採用。

### 1.ターミナルを開いて`ロゼッタを使って開く`をチェックし、`sudo gem install ffi`を実行
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535198/c47fe95c-1386-0f99-f7da-ed529c6ddf31.png" width='150'>

### 2. 以下のスクリプトを実行
```
sudo arch -x86_64 gem install ffi
arch -x86_64 pod install.
```

### 3. `Homebrew`を使用し`CocoaPods`をインストール
Apple SiliconのMontereyにも対応しており、安定版だとわかった。
https://formulae.brew.sh/formula/cocoapods
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535198/5dc2f3b7-240d-8c99-e772-d073827ac663.png" width='500'>
![Screen Shot 2021-12-25 at 23.14.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535198/3004aeda-2d42-ca9c-c4fe-c9eba89f2e54.png)
# 参考
https://dev.to/staceypyee/installing-cocoapods-on-m1-macbook-air-big-sur-h0l
Raspberry Pi OS 64bitでVOICEVOX COREのビルド

voicevox_coreはこちら
https://github.com/VOICEVOX/voicevox_core

Raspberry Pi 4 8G
Raspberry Pi OS 64bit(2021-05-07-raspios-buster-arm64-lite)

LinuxもPythonもましてやAIのことなどほとんど知識ないのでご容赦を。
～だったかも程度のメモで泥臭いと思います。

##ONNX Runtimeのビルド準備
何をいれたのかうろ覚え...。

```
sudo apt install cmake
```
とはいえビルドでcmakeのバージョンが低いと怒られたためcmakeのサイトから最新バージョンをインストールした。

```
sudo apt install git build-essential libcurl4-openssl-dev libssl-dev libatlas-base-dev 
sudo apt install tk-dev libncurses5-dev libncursesw5-dev libreadline6-dev libdb5.3-dev libgdbm-dev libsqlite3-dev libssl-dev libbz2-dev libexpat1-dev liblzma-dev zlib1g-dev libffi-dev libv4l-dev
sudo apt install libavutil56 libcairo-gobject2 libgtk-3-0  libpango-1.0-0 libavcodec58 libcairo2 libswscale5 libtiff5 libatk1.0-0 libavformat58 libgdk-pixbuf2.0-0 libpangocairo-1.0-0 libwebp6
pip3 install opencv-python
```

##適当な作業ディレクトリへ

```
mkdir ~/tekitou
cd ~/tekitou
```

##ONNX Runtimeをビルド
参考：https://axross-recipe.com/recipes/352

```
git clone https://github.com/microsoft/onnxruntime
cd onnxruntime
./build.sh --use_openmp --config Release --arm64 --update --build --build_shared_lib --build_wheel
pip3 install build/Linux/Release/dist/onnxruntime-{バージョン}.whl
```
↑pip3でのonnxruntimeインストールは不要かも。

```
you@raspberrypi:~/tekitou/onnxruntime $ find -name *.so
./build/Linux/Release/onnxruntime/capi/libonnxruntime_providers_shared.so
./build/Linux/Release/onnxruntime/capi/onnxruntime_pybind11_state.so
./build/Linux/Release/libonnxruntime_providers_shared.so
./build/Linux/Release/onnxruntime_pybind11_state.so
./build/Linux/Release/build/lib/onnxruntime/capi/libonnxruntime_providers_shared.so
./build/Linux/Release/build/lib/onnxruntime/capi/onnxruntime_pybind11_state.so
./build/Linux/Release/libtest_execution_provider.so
./build/Linux/Release/libcustom_op_library.so
./build/Linux/Release/libonnxruntime.so
```
libonnxruntime.soがあればオッケー。

##VOICEVOX COREをビルド

```
cd ~/tekitou

git clone https://github.com/VOICEVOX/voicevox_core
cd voicevox_core
mkdir build
cd build
cmake .. -DONNXRUNTIME_DIR=~/tekitou/onnxruntime/
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/tekitou/onnxruntime/build/Linux/Release/ cmake --build . --config Release
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/tekitou/onnxruntime/build/Linux/Release/ cmake --install .
cd ..
ORIGIN=~/tekitou/voicevox_core/core/lib/libcore.so LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/tekitou/onnxruntime/build/Linux/Release" python3 setup.py test
pip3 install .
cd example/python
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/tekitou/onnxruntime/build/Linux/Release python3 run.py --text "これは本当に実行できているんですか" --speaker_id 1 --root_dir_path="../../model"
```

エラーはなくdeprecated NumPyのワーニングがあったのみ。
（毎回ライブラリパスなどを追加していますがよくわかっていないので毎回やっています。）

```
you@raspberrypi:~/tekitou/voicevox_core/example/python $ ls
acoustic_feature_extractor.py  makelib.bat
core.pxd                       __pycache__
core.pyx                       requirements.txt
Dockerfile                     run.py
forwarder.py                   setup.py
full_context_label.py          これは本当に実行できているんですか-1.wav
```

おお！できたwavを神棚にお供えしたいほどの感動がありました！
再生してみると...(@～@)？？
補数について

[う　え　き　ぷ　に　き　あ　く　ん　笑 Advent Calendar 2021](https://adventar.org/calendars/6939 "うえきです") 25日目です
pwn記事は書けませんでした。悲しいです...（かなしいです...）

##この記事について
本記事内でのn進数の表記は以下の通りとします。
$ (数字)_{n} $

例えば、

$ (123)_{10} $ → 10進数の123

$ (101)_{10} $ → 10進数の101

$ (101)_{2} $ → 2進数の101（10進数では5）

とします。しかし、10進数のみはこの表記をしないこととします（ちょっと　書きにくいし（ぼくが）読みにくいので（は？））。

また、様々な証明や詳細な理屈について、本記事内では省略しています。ご了承ください。ごめんなさい。うう...

##補数の種類
前提として、補数は、各n進数に対し、nの補数とn-1の補数の2種類存在します！！！

##n進数におけるnの補数
n進数におけるnの補数とは、ある正整数Aに対し、足し合わせるとちょうど桁上がりが発生する数のことです。
以下、実例です。

$ A = 3 $のとき、10の補数は$ 7 $
$ A = 100 $のとき、10の補数は$ 900 $
$ A = (101)_2 $のとき、2の補数は$ (11)_2 $

Aの桁数をdとすると、n進数における、Aに対するの補数は以下の式で表すことができます。

$ n^d - A $

すごい！わかりにくくなった気がする！うう！ごめんなさい！！！

##n進数におけるn-1の補数
n進数におけるn-1の補数とは、ある正整数Aに対し、足し合わせた際に桁上がりが発生しない最大の数のことです。すなわち、Aに対するnの補数から1を引いた値になります。先程の例を元にすると、

$ A = 3 $のとき、9の補数は$ 6 $
$ A = 100 $のとき、9の補数は$ 899 $
$ A = (101)_2 $のとき、1の補数は$ (10)_2 $

##nの補数の用途
nの補数の使用用途として、減算を行うために用いることができます。具体的には、n進数でA - Bを行うとき、CをBに対するnの補数とする（桁数はAに合わせます）と、A + Cを行い、桁上がりした部分を捨てることで実現が可能です。
以下、実例です。

$ A = 3, B = 2 $のとき、$ C = 8 $
$ A + C = 11 $桁上がりした部分を捨てると$ 1 $
$ A - B = 1 $なので等しい

$ A = (1001)_2, B = (100)_2 = (0100)_2 $のとき、$ C = (1100)_2 $
$ A + C = (10101)_2 $桁上がりした部分を捨てると$ (0101)_2 = (101)_2 $
$ A - B = 9 - 4 = 5, (101)_2 = 5 $なので等しい

##コンピュータにとっての2の補数
コンピュータにとって、2の補数はとても大事な役割を担っています。
それは、減算を行うための役割です。

そもそも、コンピュータにとって、加算は容易ですが、減算は難しいです。
しかし、2の補数を使うことで、加算を用いて減算と同じ結果を得ることができます。ここでは、その手順を説明します。

###コンピュータが2の補数を作る手順
2進数における2の補数は、ある正整数Aとその桁数dによって、以下の式

$ 2^d - A $

で表されますが、この式中にそもそもマイナスの符号が出てきています。しかし、2進数における1の補数について考えると、正整数Aに対する1の補数（Bとします）は、Aの各ビットを反転させたものになっています。
以下、実例です。

$ A = 10 = (1010)_2 $
$ d = 4 $なので
$ B = 2^4 - 10 = 16 - 10 = 6 = (0101)_2 $
$ (1010)_2 $と$ (0101)_2 $は互いに各ビットを反転させたものになっており、足し合わせると$ (1111)_2 $になるため、1の補数として適切。

ここで、Aに対する1の補数は、Aに対する2の補数-1であることから、
$ Aに対する2の補数 = Aに対する1の補数+1 $であることがわかります。
よって、2進数における2の補数をコンピュータが作るには、以下の手順を踏んでいることがわかります（ここでは、Aをある正整数としています）。

1. Aの各ビットを反転させたものをBとする
2. Bに1を足す（桁上がりは捨てる）

シンプルですね。わかりやすい！すげー　ちなみに、コンピュータでは、符号付きの整数は、最上位ビットが符号を表しているため、少し手順は増えますが、Aが負の整数でも上記のような手順で期待した結果を得ることができます。

###コンピュータが減算を行う手順
これまでで、コンピュータが2の補数、というよりも、ある数の符号を反転させる手順はわかりました。わからなかったらごめんなさいです...
これからは、コンピュータが減算を行う手順を説明していきます。ここでは、Aを引かれる整数、Bを引く整数としています。

1. Bに対する2の補数の数Cを作る
2. A + Cを行う（桁上がりは捨てる）

おわり　よっしゃ！（え？）
これでできます！この項、内容薄いな...

##最後に
このようなコンピュータの動作原理を知ることは、とっても楽しいしうれしいし大事だと思うので、貪欲に勉強していきたいですね！そうですね！

今日でアドベントカレンダーは終わりのようです。最後を締めくくるにふさわしい記事になったかな...？と心配です...
yaml-cppでYAMLファイルの読み込み

# YAMLの読み込み
yaml-cppを使う。Fedora 35の場合パッケージがあるのでdnfでインストールできる。

```
$ sudo dnf install yaml-cpp-devel
```

# 文字列のパース

```cpp
#include <iostream>
#include <yaml-cpp/yaml.h>

void test1(void) {
    YAML::Node node = YAML::Load("key: value");

    // valueが出力される
    std::cout << "key == " << node["key"] << std::endl;

    // これは何も出力されない
    std::cout << "key2 == " << node["key2"] << std::endl;

    // これだと例外発生
    try {
        std::cout << "key2 == " << node["key2"].as<std::string>() << std::endl;
    } catch (const YAML::TypedBadConversion<std::string>& e) {
        std::cout << "エラー: " << e.msg << std::endl;
    }

    // aaaが出力される
    std::cout << "key2 == " << node["key2"].as<std::string>("aaa") << std::endl;
    return;
}
```

`as<T>()`で指定した型で値を取り出せる。キーが存在しない場合などは例外がスローされる。引数にデフォルト値を指定するとキーがなくても例外がスローされることなくデフォルト値が返却される。

# ファイルを指定してパース

下記のようなYAMLファイルをロードする。

```yaml
# hoge
# コメント
config:
  number: 12345
  number2: aaa
  hoge: true
  seq:
    - name: test1
      key: 値 
    # コメント
    - name: test2
      key: 値2
```

```cpp
#include <iostream>
#include <yaml-cpp/yaml.h>

void test2(const char *file) {
    YAML::Node node = YAML::LoadFile(file);
    YAML::Node config = node["config"];

    std::cout << "number == " << config["number"].as<int>() << std::endl;

    // number2: aaaなので、引数で指定した128が返される
    std::cout << "number2 == " << config["number2"].as<int>(128) << std::endl;
    // std::stringを指定しているのでaaaが返される
    std::cout << "number2 == " << config["number2"].as<std::string>() << std::endl;

    std::cout << "hoge == " << config["hoge"].as<bool>() << std::endl;
    
    YAML::Node seq = config["seq"];
    if (seq.IsSequence()) {
        for (const auto seq_node: seq) {
            std::cout << "name == " << seq_node["name"] << ", key == " << seq_node["key"] << std::endl;
            YAML::Mark mark = seq_node.Mark();
            std::cout << (mark.line + 1) << "行目" << std::endl;
        }
    }
    return;
}
```

`Mark()`関数で何行目かの情報が返される。
curl -sf (address.sh) | sh -sで(address.sh)に書いたecho $0の結果が知りたかった

## 結論
パイプで実行したshが返されます。
たとえば、タイトルのように`(略) | sh -s`だと、`sh`
これをbashとかzshに変えたらそれぞれの結果になりました。

検証用URL(curlで呼び出せます）

``` 検証用URL.sh(r_and_d.sh)
# curlで実行された場合に何を出力するか検証
echo $0
```

[検証用URL(r_and_d.sh)](https://raw.githubusercontent.com/shimajima-eiji/Settings_Environment/%2314_20211225_ver1_brew_upgrade_sh/for_Mac/r_and_d.sh)

※普段からブランチや場合によりリポジトリをいじっているので、動かなくなったら↑の内容をご自身の環境において試してみてください。

``` ログインシェルで実行.sh
curl -sf https://raw.githubusercontent.com/shimajima-eiji/Settings_Environment/%2314_20211225_ver1_brew_upgrade_sh/for_Mac/r_and_d.sh | sh -s
```

### 補足
当然ですが、ファイルをローカルに保存して、ローカルから呼び出すと`$0`は「ファイル名」になります。
shだろうがbashだろうがzshだろうがファイル名です。

### 補足の補足
試しに、`which sh`の結果である`/bin/sh`で実行したところ、結果は`/bin/sh`になりました。

``` curl_$0.sh
curl -sf https://raw.githubusercontent.com/shimajima-eiji/Settings_Environment/%2314_20211225_ver1_brew_upgrade_sh/for_Mac/r_and_d.sh | /bin/sh -s
```

これもbashのフルパス、zshのフルパスに変えてもそれぞれ同様の結果です。

## 疑問、そして理解したこと
これは質問に投稿するべきだと思ったのですが、記事を分けると上記を説明する必要があるので気付いた有識者の方に見てもらえればと思います。

### $0とはそもそもなんなのか？
私は「スクリプトを実行しているもの（名前）が格納されている」という認識をしていました。
なので、

- shで実行すればshが、
- /bin/shで実行すれば/bin/shが
- ファイル名から呼び出せばファイル名が

それぞれに入っているという認識です。

今回の場合、curlでファイルを**文字列として受け取って、それをパイプ先に渡しているだけ**なので、実体はパイプで指定したものなんだろうという認識をしました。
これは、例えばログインシェル（対話モード）で`echo $0`を実行した時の結果がそのまま出ている（$SHELLと同じはず）ので、同じことが`curl... | sh`にも起こっただけなんだろうという理解です。
mac Parallels Desktop 17 で Windows11 を使う

M1 MacBook Pro で、Windows11 を動かすのが、とっても簡単になっていた。
Excel も問題なく、Windows11 で動作します。

ARM 版 Windows11 で、Excel を起動してスクリーンショット
mac のタスクバーに、mac と Windows11 のアプリが並ぶ
アイコンに赤の縦線表示が、Windows11 のアプリ

![スクリーンショット 2021-12-25 20.53.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/33009f40-bf4c-6a13-d887-650352a2baed.png)

# 環境

- MacBook Pro (13-inch, M1, 2020)
- Apple M1
- メモリ 16 GB
- Parallels Desktop 17 For Mac
- Windows 11 Pro
- Microsoft 365 Apps for business
- Chrome

# Parallels Desktop インストール

無償トライアル版で、試してその後ライセンス購入でOK
Parallels Desktop の公式サイトからダウンロード＆インストール
手順どおりに進めていけば、問題ない

https://www.parallels.com/jp/

少し試した結果、かなり出来が良いので、Parallels Desktop Pro Edition　のサブスクライセンスを購入
9,818 円/年　：　購入時は、もう少し安かった気がする

# Parallels Toolbox

Parallels Desktop　に無償で付いてきた。
いろいろ便利な機能があるようだ。

![スクリーンショット 2021-12-25 22.17.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/aff7c1be-824c-1680-be2e-4932eb0a0c79.png)


# Windows 11 Pro

無償トライアル版をインストールすると、ARM 版 Windows 11 Home をライセンス未認証の状態で起動される。
手持ちの Windows 8 Pro ライセンスで、ライセンス認証を行うと　Windows 11 Pro になった。

解像度
なぜか 2880 x 1800 が推奨となっているので、そのまま。
macbook pro の仕様は、 2560 x 1600

![スクリーンショット 2021-12-25 21.17.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/6823b531-dcb0-223f-1317-a6011a1a5530.png)

# Windows11 の構成

Windows11 Pro、Office365、Chrome などをインストールして、約30GB。

![スクリーンショット 2021-12-25 23.03.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/86dfee7a-ae37-259d-a7be-88d9192b3552.png)

# Microsoft 365 Apps for business

1ライセンスで、5 台の Windows PC または Mac　にインストールできるお得な Office
1 台の mac に mac 版と windows 版をインストールして、動作確認してみました。
ファイルは、Excelのテンプレートから作成。

Windows 版 Excel ：　ARM 版がインストールされてそのまま動いている。
![スクリーンショット 2021-12-25 21.32.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/9e90f0e4-9411-693a-8b81-0dae4cc48f5a.png)

- ARM 版 Excel といっても x86 版との違いはわからない。
![スクリーンショット 2021-12-25 21.34.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/b375fb88-a2ca-3668-ea30-a53a1896fe0f.png)

- mac 版 Excel
mac 版 Excel は、解像度の関係で表示される大きさが異なる。
フォントも異なるので、見た目が少し違う。
![スクリーンショット 2021-12-25 21.41.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/eaad28e6-6a7f-41f0-ee72-ef58543cacec.png)

# Chrome

Chrome は、x８６　版がインストールされ、エミュレーターで実行されているようです。
特に遅さを感じることもなく、普通に使えます。

![スクリーンショット_2021-12-25_22_28_03_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/d074291a-fb9d-de2b-9a0b-50e6c3d80bed.png)


# 日本語切り替え

使ってて、少し面倒なのが日本語切り替え。
US　キーボードなのでショートカットで日本語切り替えをしますが、　mac と Windows でよく間違う。
macアプリ、windowsアプリ間の切り替えは、特に意識しないでスムーズだが、IME　が違うのが面倒。
できればカスタマイズで、統一したい。

mac: contorol+space
windows: shift+caps lock

# まとめ

特にトラブルもなく、mac で　Windows11 が使えるようになり、便利。
kintone のように、WEB ベースのしくみだと、１台でmac・　Windows11 の開発・テストができてしまう。
たぶん ARM 版特有の動作などもあるはずだが、エミュレータでもそれを感じない。
実際によく使うのが Excel, Chrome, VSCode なので、それほど重い処理は無くこれで十分。
Java(maven)+Springboot+Docker環境でデプロイの一連の流れ

<h4>きっかけ</h4>
・技術課題に取り組む際に環境構築やらでいっつも時間かかって、挙句、諦めよう・・・って思いがよぎったこともあったので雛形を作っておこう。

<h4>環境構築</h4>
1.環境構築自体はほとんど以下のページで完結するので省略。

https://spring.pleiades.io/guides/gs/spring-boot-docker/

https://qiita.com/A-Kira/items/beaf79a0d39d9839e61e

<h4>注意点</h4>
・「mvnw package」実施する際はmvnwの一つ上の階層に移動してから
・java -jar target/<b><　ここは適宜あわせる　></b>.jar

<h4>ソース修正した後に反映させるには</h4>
プロジェクト階層直下で
docker-compose build
docker-compose exec <　コンテナ名　> bash

bash-4.4# cd 　<　mvnwの一つ上の階層　>
bash-4.4# sh mvnw package
bash-4.4# java -jar target/<　適宜合わせる　>.jar

・参考URL
どうせしょぼいミスなんだろうけどブラウザ上で見れない・・・って時は↓

https://web.plus-idea.net/on/docker-web-server-access-denied/

DBeaverで変なエラー出た・・・って時は↓

https://qiita.com/noy__/items/f53e9e6210e02233d414

なんか無駄な手順ありそうだな。とは思ってはいるのでご指摘あれば・・・。
Udon TechメンバーのGoを知ってる人向けのPlan 9 from Bell labs

今更ながらPlan 9 from Bell labsの紹介です。どちらかというと言語のGoを知ってる人向けに書きますね。
よくPlan 9と呼ばれますが、正確にはPlan 9 from Bell labsが正式名称です。
しかし、この記事でずっとPlan 9 from Bell labsと書き続けるのはしんどいのでPlan 9と今後書いていきますね。

Plan 9とはどういうOSかというと、今は結構普及した言語であるGoを開発したRob PikeやKen Thompsonが中心に開発したOSです。
言語の流れからすると、最初にCがあって、その後Plan 9の時にCも改修されPlan 9 Cがあって、その後Alefが出てきて、Plan 9の後継のOSとしてInfernoが開発された時の言語としてLimbo(その後Plan 9にもLimboを移植)が来て、そしてその開発者がみんなGoogleに行ってしまって、今のGoがある訳です。詳細はかどたさんのブログ記事の方が詳しいです。

Plan 9の特徴としてはたくさんありますが、幾つか列挙しますと、
・UTF-8を最初に実装されたOS
・/proc
・9P
・Cはcreatがcreateにちゃんと修正されている
・shellはrc
・Windows systemはrio
・namespace
・UNIXの流れとしては正統な系譜のOS
・CPUサーバー、ファイルサーバー、認証サーバー、ターミナルの4種類に分割可能

とか、挙げだすときりがないくらいですし、今のLinux等のOSに取り込まれてるものが結構多いですね。UTF-8や/proc,ファイルシステムを被せるNetBSDでいうunionfs的なnamespaceとか本当に挙げだすときりがないです。
そんなPlan 9の大きな特徴としてCPUサーバーを立てて、９PでCPUリソースを持ってくる事が可能という事で、ターミナルのCPUが貧弱であってもCPUサーバーのCPUが高速であれば問題ないというものです。それも前提としてはネットワークは無限に速いという前提です。
ファイルサーバーとの共有も9Pです。
9Pって実はいろんなものにこっそり入っていて、最近ですとChromebookにこっそり入っていて、アップデートの時に9Pを一瞬使っているらしいです。

そんなPlan 9ですが、Bell Labsが解散してから色々中途半端な状態で宙に浮いた状態でしたが、最近はforkした9legacy中心にだと思いますが、今年Plan 9のライセンスがLPLからMITに変更され、Plan 9 foundation中心に分散したパッチのマージしていくように見えます。
また、後継のOSのInfernoのライセンスも同時にMITに変更されて、こちらも同様の動きがみられます。
ちなみにInfernoの方はMMU無しでも動く組み込み系にも使えるOSですし、色んなOS上でも動く仮想OS的な物としても使えるものです。そちらはまた別の時にでも書きます。

次回は9PやInfernoの記事にしましょうか?

とりあえずは、こんな感じで。
Barrier でバッククオートを入力できないときの対処法

諸事情で MacBook と Windows PC を二台持ちで使うハメになったのです。そんなときは [Barrier](https://github.com/debauchee/barrier) ですね。MacBook をサーバーに、Windows PC をクライアントにすれば、MacBook のキーボードとトラックパッドで Windows を操作できてホント便利です。

ただ、MacBook は英字キーボードなのに Windows PC は日本語キーボードなので色々ややこしい。とりあえず Windows PC で日本語を入力するときも英語キーボードになるようにしたんですが (下図)、バッククオートを入力しようとすると半角・全角が発動してしまって困ったことに。Windows PC の日本語キーボードで半角・全角キーを叩いても、ちゃんとバッククオートが入力されるのにね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249782/55d8704e-e54a-ae80-d8ac-3521098ff365.png)

でも、Windows PC に [PowerToys](https://docs.microsoft.com/en-us/windows/powertoys/install) をインストールして Keyboard Manager で半角・全角キー (VK_243) をバッククオートにリマップしてあげたら、ちゃんと動くようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249782/7f279ef7-10b4-4bed-02d1-f2231413f84f.png)

めでたしめでたし。
【SAP-C01試験対策】AWS Organizationsのまとめ

# はじめに
AWS SAP試験対策でAWS Organizationsについて学習したので、内容をまとめます。

https://www.slideshare.net/AmazonWebServicesJapan/20180214-aws-blackbeltorganizations

# 背景
本記事はAWSソリューションアーキテクトプロフェッショナルに合格するために、[Udemyの模擬試験](https://www.udemy.com/course/aws-53225)を解いて分からなかった部分を勉強してまとめるものです。

試験対策用のため、分からない知識を補足したり試験で問われなさそうなところを省略したりしながらまとめています。
なるべくわかりやすい記載を心がけますが、最終目的は自己学習用であるということをご容赦ください。

# マルチアカウント
- 独立型のマルチアカウント：独立したアカウントを複数作成して管理する。または、組織の一括請求のみ利用して支払いを管理する。
- 一元管理されたマルチアカウント：管理アカウントとメンバーアカウントから構成されるマルチアカウント
 - 管理アカウント（マスターアカウント）：組織を作成するためのアカウント。リソース作成はしない。
 - メンバーアカウント：管理アカウントに紐づく複数のアカウント。リソース関連作業をする。

## 管理アカウントでできること
- 組織にアカウントを作成、削除
- 組織にアカウントを招待、招待の管理
- 組織内のエンティティ（ルート、OU、アカウント）にポリシー（SCP）の適用
- 支払の管理

## アカウント分割の例
- 管理アカウント
- ログ用アカウント
- 監査用アカウント
- 開発用アカウント
 - 開発アカウント
 - テストアカウント
 - 本番アカウント

## クロスアカウントアクセス(スイッチロール)
アカウント内のIAMユーザが他のアカウントのIAMロールを利用すること。

- 管理アカウント→メンバーアカウント
- メンバーアカウント→メンバーアカウント

# AWS Organizations
アカウント管理のためのAWSサービス。

## 機能
- 一括請求：請求のみまとめる機能
- すべての機能：メンバーアカウントに対して権限の管理などができる機能

## 用語
- 組織：管理アカウントが管理するアカウントたち。
- 親：下層にアカウントたちを持つアカウント。
- OU：親以下のアカウントたち
- ルート：親にたどり着くまでの道のり

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951272/539429d6-796d-230a-6023-ae55cf29ae57.png)

## すべての機能の例
1. SCP：組織を管理するためにアカウントにリソースへのアクセス許可、拒否を明示的に指定する。（明示的な拒否＞明示的な許可＞暗黙の拒否）
1. タグポリシー：アカウント内のタグの使用方法に関するルールを定義できる。
1. 組織の証跡：Cloudtrailで「組織の証跡」を有効にすることで全てのメンバーアカウントのイベントを記録することが可能。

# 試験対策

## 設問①：監査人がすべてのメンバーアカウントのAPIイベントを記録するログファイルにアクセスしたい
- 管理アカウントのCloudtrailで「組織の証跡」を有効化し、メンバーアカウントのログを管理アカウントのS3バケットに配信し、監査人にはS3バケットへの読み取り権限のみを付与する。
- 各メンバーアカウントでCloudtrailを有効化し、（以下同文）

## 設問②：管理アカウントからメンバーアカウントの権限でリソースを停止、削除、終了したい
- 管理アカウントにIAMユーザを作成し、メンバーアカウントのクロスアカウントロールを作成したIAMユーザに付与する。

## 設問③：全メンバーアカウントでAWSリソースン大してタグを作成するよう規則化したい
- 全メンバーアカウントをOUとし、タグポリシーを適用しタグの標準化をメンバーアカウントに強制する。ただし、タグ付けの強制はできない。

## 設問④：管理アカウントだが、OUからメンバーアカウントが削除できない。
- メンバーアカウントの支払情報を登録し、独立できる状態にしたのちOUから削除する。

## 設問⑤：メンバーアカウントのAWSリソースへのアクセス許可、拒否を明示的に指定しつつ、コストも最適化したい
- OUを設定しSCPをアタッチする
- OU内のユーザー、ロールに対して個別でIAMポリシーを追加する

## 設問⑥：メンバーアカウント内への許可されていないサードパーティのアカウントの作成の早期発見、予防がしたい
- AWS ConfigによりAWS Organizationsのコンプライアンス状況をモニタリングして変更に関する通知を設定する
- Cloudtrailを利用してAWS Organizationsへの全APIコールをモニタリングし、通知を設定する。

## 設問⑦：Cloudtrailを全メンバーアカウントで有効化したい
- AWS Organizationsのすべての機能を選択。管理アカウントでCloudtrailの「組織の証跡」の有効化。SCPでメンバーアカウントのCloudtrailの非有効化を拒否する。

##設問⑧ 各メンバーアカウントにて適切な権限管理をしたい。
- OUを使用してアカウントをグループ化しSCPを設定。
- OUのメンバーアカウント内のIAMユーザ単位に必要なクロスアカウントアクセスとIAMポリシー設定を付与する。


-
【Vue】Cannot read property ‘value’ of undefined

###事象
Vueで子コンポーネントであるInputフォームから親コンポーネントへ値を渡す際に

```console:開発者ツールのコンソールに表示される
Cannot read property ‘value’ of undefined
```

が発生して、フォームになにか入力したら即座にエラーが発生してしまいました。

###コンポーネントたち

```vuejs:子コンポーネント
<template>
  <v-text-field
    type="text"
    :value="value"
    :counter="counter"
    :label="label"
    required
    @input="updateValue"
  />
</template>

<script>
export default {
  name: 'InputForm',
  props: {
    value: { type: String, default: '' },
    counter: { type: Number, default: 20 },
    label: { type: String, default: 'defaultname' }
  },
  methods: {
    updateValue (e) {
      this.$emit('input', e.target.value) //ここの書き方がダメ
    }
  }
}
</script>
```

```vue.js:親コンポーネント
// コンポーネントの呼び出し部分のみ
<input-form v-model="fullname" :label="nameLabel" :counter="11" /
```

###v-modelを使っている場合はthis.$emit('input', e)にしないといけない

子コンポーネントの`this.$emit('input', e.target.value)`がダメみたいです。

公式ドキュメントの該当箇所
https://jp.vuejs.org/v2/guide/components.html#%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%A7-v-model-%E3%82%92%E4%BD%BF%E3%81%86

一応一度は読んだことはあったがちゃんと理解してなかったな。

というか、`v-model`が何たるかをちゃんと理解していないことがわかった＼(^o^)／

###v-modelとは？

```vue.js
<input v-model="searchText">

// 下のことと同じらしい
<input
  v-bind:value="searchText"
  v-on:input="searchText = $event.target.value" //ここがミソ
>
```

`v-on:input="searchText = $event.target.value"`というのが
`v-model`には含まれているらしい。

なので、子コンポーネントで`$emit('input', $event.target.value)`とすると親コンポーネントでは

`searchText = $event.target.value.target.value`を実行していることになるっちゅうことですな。

そらエラー出るで！！

**イベントから値の抽出は`v-model`がやってくれるのです。**


###子コンポーネントからはイベントそのものを渡せばいい(.target.value不要)

ということで、子コンポーネントから親コンポーネントに入力値を渡す場合は

```vue.js
  methods: {
    updateValue (e) {
      this.$emit('input', e) //イベントをそのまま渡す!!
    }
  }
```

というふうに書き換えればよいというのが正解ですね。

インラインで書くなら

```vue.js
    @input="$emit('input', $event)"
```

※thisが不要になるんですね。


###まとめ

エラーをもとに、公式ドキュメントを読み下して行くことで少しずつ理解が深まり、ドキュメントを読む力がついてきますね。

Qiitaや技術ブログ記事も参考になりますが、基本的に「公式ドキュメントのどこに当たるのか」ということを意識して理解することが大切だと思いました！！

参考にした記事
https://chico-shikaku.com/2021/05/emit-cannot-read-property-value/

ちゃんと公式ドキュメントの該当箇所のリンクを貼っていてくれて助かりました。

これから私も意識いたしますm(__)m
期待値調整の失敗と心理的安全性を築けなかったことからの学び

# はじめに
エンジニアリングマネージャー(以下　EM)3年目、
具体的にはチームリーダー兼プロジェクトリーダーとして働かせてもらっています。

1日1日が学びで、今年 2021年も濃密な時間を過ごさせてもらいました。

自分が今まで考えてたことの一つとして、
EM に求められることは、組織の体制とフェーズによって大きく異なるため、
EM としての自身の体験を書いたとしても、再現性の低さからそれほど多くの人には刺さらないと思っていました。

しかし、今回書こうと決意したのは、たとえ再現性は低くとも、
自分が置かれていた状況と、どのような思いで意思決定をしたかをまとめておこうと私自身の考えの変化があったことがきっかけです。


# 前提
冒頭に書いたように EM としては現在3年目ですが、
それに至るまで自分が EMになってからの 2年間をどのように過ごしてたかというと、
元々前任者が作ったシステムを自分がチームリーダーとして引き継ぎ、以来小規模な機能開発や既存システムのアップデートはしてきました。

しかし、大きなサービスを作った実績があったわけではなかった上に、顧客体験を向上させたという成果はありませんでした。

目立った実績を作れずにいたため、これまでの2年間自分自身の存在意義を見出せず、自己肯定感は低いままでした。そのため自分自身に焦りがありました。

# 2021年の計画をどのように作ったか
計画を練っている時に、優秀なエンジニアにチームに入ってもらう機会が訪れ、千載一遇のチャンスが訪れました。
彼に新規サービス開発プロジェクトにアサインすることで、我々は新しいサービスを持つことができそうだと確信。迎えるための準備を整えることにしました。

彼にはプロジェクトB（新規サービス開発プロジェクト）専任で、まずは一人で先行して作って貰うことにして、
他のメンバーはプロジェクトA（既に今までのメンバーで取り組んでいたプロジェクト。この時点で5月終了予定）
が終わった後、プロジェクトA を担当しているエンジニアを
プロジェクトB（新規サービス開発プロジェクト）に合流させて進めるチームの方針を打ち出し、チームに共有しました。

# 2021年を終えてみて
よかったところとして、両プロジェクト共にとりあえず形になり着地しました。

しかし、順風満帆ではなく、プロジェクトA は5月終了予定が延び9月終了で着地し、プロジェクトB は必要最低限のスコープで開発を完了。
着地したものの満身創痍で走りきった感じです。

反省点は多いです。

## アサイン計画の失敗

メンバーが現在担当している5月に終了予定のプロジェクトAが終わったら
プロジェクトB（新規サービス開発プロジェクト）に入ってもらうようアサインしましたが、
プロジェクトAが遅れ、9月まで長期化しました。

プロジェクトAが予定通り終了することを前提に
プロジェクトB（新規サービス開発プロジェクト）へのアサイン計画を立ててしまったことは
そもそもの失敗の一つでした。

## 期待値の調整の誤り
プロジェクトBに参画したエンジニアに対し期待値調整を誤りました。

プロジェクトA完了後 メンバーをアサインし共に開発する予定でしたが、
上記の通り長期化してしまったためにメンバーをアサインできませんでした。

プロジェクトBはエンジニア一人でほとんど作って貰う恰好になりました。
実際、技術的に彼一人で十分可能でしたが、当初他のメンバーも参画されるという約束を果たせず、
それを補うよう EMの私がいちメンバーとして参画して巻き取ろうとしましたが、
私自身も十分に時間を割けなかったこと、また、私が技術者として能力が不十分だったことから結果、彼の信頼を失くしてしまいました。

プロジェクトAが長期化が見えた段階で予定していたメンバーがアサインできなくなるので、プロジェクトBを止めるというタフな意思決定も必要だったのかもしれません。もちろん多方面にめちゃめちゃ謝ることになります。

仮に他のメンバーのアサインができなくなっても一人でプロジェクトBを進めてくれるという合意形成が取れていたのなら、まだ関係性は穏やかだったかもしれません。

## 心理的安全が保証された環境を作れなかった
上記の通り、メンバーも自分自身も十分にプロジェクトに入れなかったり、能力が不十分だったということから、大きな負い目を感じるようになりました。
期待値調整の誤りもあり、先方は怒りを覚えるようになったように感じます。無理もありません。
言いたいことも言えない状況が続いたため。あの期間は自分だけではなく双方地獄だったと思います。


# 学び
これらの経験から次に活かすのに、どのように反省し、次に結びつけるかも EM の考え方一つで変わると思います。

私は、プロジェクトの状況を敏感に見極め、アサインの目処が立たなりそうな段階で期待値を修正するべきだったという点、
それとお互い言いたいことも言えなくなってしまった心理的安全性の確保に邁進すべきだったという点は強烈に思いました。

この反省は来年に繋げたいと思います。
Nuxt.jsのcomponentを追加したのに読み込まれない件

Nuxt.jsを触ってて1時間以上詰まったので備忘録として残す。

## 前提
- バージョン `2.15`
- 命名規則は問題ない
- `nuxt.config.json`の自動importの設定はtrueにしてある

## 現象
以下のエラーが発生

```
Unknown custom element: <{呼び出したコンポーネント名}> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
```

よくある原因として、ファイル名と呼び出したコンポーネント名が違うこと、コンポーネントをimportしていないことが多いが前提があるのでそれも違う。

## 原因
どうやら`npm run dev`を実行したままコンポーネントを追加しても自動では認識しない。

## 解決法
componentを追加したら`npm run dev`を再実行する
なぜ未踏で釣りのプロジェクトを提案したのか

# はじめに
こんにちは，未踏にて釣りCPS（Cyber Physical System：サイバーフィジカルシステム）の開発を行っているmattkazzです．この記事の読者は未踏をご存じの方を前提としているのですが，今年度になぜ未踏で釣りのテーマが採択されてるのか？と疑問を持つ方もいらっしゃるかと思います．

そこで今回は，「釣りCPSとはなんぞや？」「釣りのデータ分析って何が嬉しいの？」というところにフォーカスした記事を書かせていただくことで，その疑問を解消し，皆さんに釣りTechの領域に少しでも興味を持っていただけたらなと思います．

# 釣りCPS（サイバーフィジカルシステム）とはなんぞや？
そもそも，（誤解を恐れずに言うと）サイバーフィジカルシステムという言葉は，数年ほど前から日本が唱えている*Society5.0*という開発目標の中に多用される単語のことで，クラウドやデータベースに貯められたデータを分析する「サイバー空間」と我々の生活する「フィジカル空間」を上手く融合させることで，新たな価値を作るシステムのことを指します．

今回の場合でいうと，「釣りに関してセンシングしたアレコレのデータ」を分析することで「実際の釣り現場」を変えてしまう，そんなシステムが我々の提案する釣りCPSとなります．

# 実際の釣りの難しさと課題
読者の方で実際に釣りをしたことがある方はいらっしゃるでしょうか？趣味としてはまだしも，人生で1度位は経験がある方が多数派ではないでしょうか？

その中でも「今日もすっげー魚釣れたわｗ釣りってちょろいわｗ」と考える人はかなり少数だと思います．

実は釣りは案外奥が深く，
1. 釣り道具を揃える
2. 釣り場所の選定
3. 釣り時期の選定・天気や潮汐の確認
4. ターゲット魚種の選定
5. 実際の釣り方・魚の誘い方
などなど．．．

考える必要があり，初心者だけでなくある程度の経験者でも何も釣れずに帰路につくこともしばしばあります．
それも当然で，相手は生きている魚であり，お腹が空いていることもあれば空いていないこともあります．美味しくなさそうな餌には興味が出ないこともありますし，そもそも釣りの仕掛けを海に垂らしても，その場所に魚が存在していないこともあります．
![釣り.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489582/84454746-c8e7-d2d2-6afe-74378c47f5dc.png "釣りの壁たち")

経験者ですらこれらの壁をクリアするのは難しいものです．

# 釣りのCPSで実現したいこと
以上のことから，我々が実現したいのは，”釣りの経験者に対して”，”釣りのデータを可視化・分析”した結果を，**現場で手軽に確認するための手段**を提供することです．

実際に，そこそこ釣りに熟達している人でもない限り，現場の状況を見ただけで適切な釣り方を考えることは難しいでしょう．私も趣味でたまに釣りをしますが，その程度では到底たどり着けない領域だと思います．

解析するデータは多岐にわたっており，各種公開されているAPIを利用するものや，特別に制作したIoTデバイスにより収集したものまで様々です．それに応じて開発するものも，Webアプリから電気回路，デバイスの外装設計まで本当に様々です．

釣りをする方や興味がある方はTwitter（@mattkazz1）で直接聞いていただいても結構です（秘密保持契約もあるため答えられる範囲でですが...）し，外部公開される最終発表会や報告書をご覧ください！
2021年の振り返り＠RailsGirls

この記事は、[Rails Girls アドベントカレンダー2021](https://qiita.com/advent-calendar/2021/railsgirlsjapan)  最終日の記事です。
Ruby3.1、リリースされましたね！

そして毎年、このアドベントカレンダーで、私自身のRails Girlsに関する振り返りを書いていますが、今年もいつもどおり、振り返ることとします。

## いちおう自己紹介
* Rails Girls Nagoya 1st〜5th オーガナイザー
* Rails Girls JPメンバー
* Rails Girls Nagoya、Naganoに出没。
* クマ好き。特にくまモンが好き。
* 最近自作キーボードに再び手を出し始めた・・・。

# 2021年のRails Girlsふりかえり
今年もCOVID-19の影響で、オフライン開催はなし。
来年こそは、できるといいなあ・・・

## Rails Girls Gathering Japan 2021 @ 2021.8.28
昨年に引き続き、オンラインイベントとして開催。
去年よりも参加人数も増え、盛況でした！

## mruby Girls＠2021.10頃〜継続中。
* きっかけは、RubyKaigi Takeout 2021で、hasumikinさんが発表した、[PRK Firmware: Keyboard is Essentially Ruby](https://rubykaigi.org/2021-takeout/presentations/hasumikin.html) 
    * Rails Girlsつながりの有志で集まって、主にキーボード関連の話で盛り上がってます
    * ただ、PRK Firmwareって、よく考えたら、PicoRubyなんですよね・・・
        * なので「PicoRuby Girls」が適切な名称なのかもしれないと、この記事を書いていて、今更ながら思った次第・・・
* ちなみに、私自身の進捗は
    * Meishi2はPRK Firmwareで動作するようになった（hasumikinさんの[リポジトリ](https://github.com/picoruby/prk_meishi2)に感謝！）
    * 次はLily58でやるぞー。と思いながらまだ未着手。足高のコンスルー買わなきゃ・・・

## 2022年に向けての抱負
* まずは小さい自作キーボードを（基板から）つくってみたい
* 状況を伺いつつ、オフラインでRails Girls できたらいいなあ
* Rails Girls Gatheringも今年に引き続き開催したいな
OpsRamp 同じアラートが繰り返された場合に抑制できるか？

# 概要

OpsRampではアラートを自動で集約して、アラート一覧では一行で表示してくれたり、suppress状態にすることでアラートを抑制することができます。しかし、suppress状態にしてみたものの、同一アラートが新たなアラートとして検知されることがありましたので、その条件を探ってみたいと思います。


# Windowsイベントログアラートの抑制
Windowsサーバを監視していると、同じIDのアラートが定期的に発生することがあります。そこで、Windowsイベントログを定期的に検知した場合の挙動を確認してみました。

### Select状態での複数検知
アラートを検知して何も対応していない状態（select）で、定期的に連続して同一アラート（イベントID：999と777）を検知した場合の結果は下記の通りです。

> * 同一アラートを自動で集約（件数が3件となっていて一行に集約されていることが分かります）
> * アラートエスカレーション通知は最初の1回のみ

![2021-1225-2027-17.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/c1654fa3-0c01-bb53-d5e7-5626ad548324.jpeg)


### Suppress状態での複数検知
アラートを検知してSuppress（抑制）にした状態で、定期的に連続して同一アラートを検知した場合の結果は下記の通りです。

> * 同一アラートを集約できず、新規アラートとして検知
> * アラートエスカレーション通知も新規アラートとして通知される

イベントID：999をSuppressに設定します。
![2021-1225-2027-47.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/b5d17b09-685f-ab46-34dd-d5c826ae7763.jpeg)
![2021-1225-2028-58.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/54bdbff5-8ba5-c384-614d-4414655b2e9b.jpeg)

イベントID：999のアラートを発生させると、新規アラートとして検知されてしまいました。WindowsイベントログについてはSuppressが有効ではないようです。
![2021-1225-2031-12.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/087e7f07-eb5b-c1c2-f7ab-0661c5415d4b.jpeg)


<font color = "red">Windowsイベントログを抑制したい場合は、監視設定で除外設定することをおススメします。
select状態にしたままでも良いと思いますが、アラートエスカレーションで一定期間経つとインシデント化する設定にしているので、その都度新しいアラートとして検知されてしまい面倒な思いをしたことがあります。</font>




# CPU使用率アラートの抑制
WindowsサーバでCPU Stressツールを使って負荷をかけ続けた状態で、アラート抑制できるか確認してみました。
![2021-1225-2137-44.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/fd384de5-80ab-e46a-921c-04f58c4a4f6d.jpeg)


### Select状態
アラートを検知して何もしてない状態で、CPU使用率のアラートを検知した場合は下記の通りアラート・通知を集約できました。

> * 同一アラートを自動で集約（件数が2件となっていて一行に集約されていることが分かります）
> * アラートエスカレーション通知は最初の1回のみ

![2021-1225-2141-52.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/0b212abf-a7be-1bf7-2e54-d99a6d84ff92.jpeg)


### Suppress状態

> * 同一アラートを自動で集約（件数もカウントアップされません）
> * アラートエスカレーション通知は最初の1回のみ
> * 一度復旧すると、新しいアラートとして検知される

Suppressに設定すると、件数がカウントアップされずにアラートが抑制されています。
![2021-1225-2146-34.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/976b903f-3074-58f4-422b-2dabb4c23728.jpeg)

一旦CPU負荷を下げて復旧させてみます。この状態で再度CUP負荷を上げるとどうなるでしょうか。
![2021-1225-2218-21.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/6e024a83-edf5-b79e-9c3a-b958ccfdef46.jpeg)

予想通り、新たなアラートとして検知されてしまいました。
![2021-1225-2229-01.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333529/4a5f06e0-b8cf-884a-91e5-f43f0fe67f46.jpeg)


作業でアラートが対象に発生する場合には、Suppressを利用するのではなくて、アラート静観時間を指定できるので、そちらを利用することをおススメします。


おわり。
MQL4/MQL5で似たようなパラメーターをまとめて作成する

似たようなパラメーターをまとめて作成する方法を紹介します。

例えばEAやインジケーターで移動平均線を使用したいとき、次のようなパラメーターを作成するかと思います。

```cpp
input int period = 10;
input int shift = 0;
input ENUM_MA_METHOD method = MODE_SMA;
```

使用する移動平均線が1本であればこれだけで済みますが、もし複数の移動平均線を使用する場合、パラメーター変数には同じ名前を使用できないのでパラメーターを変えて記述していく必要があります。
例えば期間に関するパラメーターであればperiod_1, period_2, ...といったように番号を振っていくこととなります。
もし移動平均線を10本や100本使用したいとなってくるとこの作業は少々面倒ですし、パラメーター名を変えたくなった際や、平滑化する価格に関するパラメーターも増やしたくなった場合などは更に手間が増えます。

そこでマクロを使って少し楽に作成する方法を紹介します。
実際に作成したコードは下記になります。

```cpp
#define CREATE_PARAMS(index, period) \
    input int period_##index = period; \
    input int shift_##index = 0; \
    input ENUM_MA_METHOD method_##index = MODE_SMA;
```

## マクロの基本
マクロを使うには#defineを使います。
基本は下記の形式で使用します。

```cpp
#define 識別子 式
```

識別子にはパラメーターを渡すこともできます。（ただしパラメーターは最大8個まで）
その場合は下記の形式となります。

```cpp
#define 識別子(パラメータ1,... パラメータ8) 式
```

今回はCREATE_PARAMSと命名しました。
バックスラッシュを使うことで改行もできるので、複数行の処理でも見やすく定義できます。


## 変数名への対応
\#defineを使ってパラメーターのセットを定義した際に問題となるのが、パラメーターの変数名です。
同じ変数名は宣言できないため、CREATE_PARAMSの呼び出し毎に作成されるパラメーター名を変えてあげる必要があります。
今回CREATE_PARAMSにはindexというパラメーターを用意しました。
indexで渡された数字をパラメーター名に付けることで、この問題を解決します。

この時、indexの前に\#\#が付いているのがポイントです。
もし\#\#を付けずにperiod_indexとしてしまうと、作成されるパラメーターも「period_index」という名称になってしまいます。
period_##indexとすることで、indexが1であれば、「period_1」という名称となってパラメーターが作成されます。
後は適当なパラメーターをCREATE_PARAMSに渡して呼び出すだけです。

```cpp
#define CREATE_PARAMS(index, period) \
    input int period_##index = period; \
    input int shift_##index = 0; \
    input ENUM_MA_METHOD method_##index = MODE_SMA; \

CREATE_PARAMS(1, 10)
// period_1, shift_1, method_1の3つのパラメーターが作られる
// period_1の初期値は10

CREATE_PARAMS(2, 20)
// period_2, shift_2, method_2の3つのパラメーターが作られる
// period_2の初期値は20
```

複数行必要だった宣言を1行で書けるようになり、コピペして数字を変えていく地道な作業から開放されます。

## 欠点
この方法の欠点として、コメントを使ったパラメーター名に日本語や記号を設定する方法を使用することができません。
通常のパラメーター宣言は、宣言した行の最後にコメントアウトを付けることで、コメントの内容がパラメーター名となります。
\#define内でも/* コメント */形式でのコメントが挿入可能ですが、この方法を使ってもパラメーター名をコメントに変えることはできません。

```cpp
input int test = 1; /* hoge */
// -> パラメーター名はhogeになる

#define CREATE_PARAMS(index, period) \
    input int period_##index = period; /* uga */ \

CREATE_PARAMS(1, 10)
// -> パラメーター名はperiod_1になる(ugaにはならない)
```

何らかの理由でパラメーター名に日本語や記号などを使いたい場合は、地道にパラメーターを宣言しましょう。