OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonで間違えて変数名にビルトイン関数を使ってしまったのに動いてしまったことについて

# なんでそんなことしたの

某プログラミングスキルチェックサイトで問題を解いていたのですが、2桁の数字を0埋めで表示させたい場面がありました。
この問題はPythonで挑みました。恐らくPythonに慣れ親しんでいる方であれば、文字列型の`.format`関数を使うというのがパッと思い浮かぶのではないかと思われます。特にこの問題は2つ2桁の数字を並べるものだったので、後でそれが最適解だったことに気付きました。
ただ、私は普段JavaScriptやTypeScriptに慣れ親しんでいたので、そこで使いがちな手法を使うことにしました。

```python
def to2digit(num):
  return ('0' + str(num))[-2::]
// ...

hoge = to2digit(hour)+to2digit(min)
```

…おわかりいただけたでしょうか。
もう既にタイトルでネタバレになっていますが。

# これどうなるの

この動作を括弧の内側の方から追っていきます。
`min`は数字だと思って使ってしまったビルトイン関数ですが、`str(min)`はエラーにならず、文字列になるようでした。この値は`<built-in function min>`になるようでした。
これに対して頭に文字列`0`を付けた上で後ろの2文字を取ると、`n>`になります。
そういうことで、上記の`hoge`は、`23n>`とかそんな感じの値になります。
もう言ってしまうと、変数名から察せるように時刻を扱っていた訳ですが、そんな珍妙な値が完成してしまっていました。なんということでしょう。

# 終わりに

- 予約語や定数的なものになってしまいそうな命名には気をつけたい
- 便利な機能は覚えてどんどん使っていきたい

と思ったのでした。
システムからユーザへ通知を行うコマンドについて

●システムからユーザへ通知を行う方法

■ログイン時に通知する
特定のファイルに記述した内容が表示。表示させるタイミングによって、記述するファイルが異なる。

・/etc/issue
ログインプロンプトの手前に表示される内容を設定するファイル。
このファイルの内容はログイン画面に表示されるので、ログインを行わなくても閲覧される。

・/etc/issue.net
SSHなどネットワーク経由でのログインプロンプトの手前に表示される内容を設定するファイル。

・/etc/motd
ユーザがシステムにログインした直後に、コンソールに表示される内容を設定するファイル。
/etc/issue とは違い、ログインが成功して初めて表示されるので、正しいユーザにのみ表示したいような内容ならばこちらが適します。

■コマンドで通知する
ログイン中の他のユーザーに、任意のタイミングで通知できます。

・wall
書式
　wall 表示するメッセージ

ログインしているユーザ全員のコンソールに、引数で指定したメッセージを表。
システムを再起動する際の予告などに利用。

・shutdownコマンドの-kオプション
書式
　shutdown -k now "message"

wallと同様にログインしているユーザ全員にメッセージを送る。
shutdownは第一引数にシャットダウンや再起動を行うタイミングを、第二引数にメッセージを指定して実行すると、まずそのメッセージをユーザに表示してから、指定したタイミングでシャットダウン・再起動などを行うコマンド。
-kオプションを指定した場合にはシャットダウン・再起動などの動作はキャンセル。

・write
書式
　write ユーザ [tty]

writeコマンドの後に入力したメッセージを、指定したログイン中のユーザのターミナルに表示。Ctrl+Dで入力を終了。

・talk
書式
　talk ユーザ[@ホスト]

指定したログイン中のユーザとチャットができるコマンド。Ctrl+Cでtalkを終了。

■通知メッセージの受け取り設定
他のユーザーからの通知は、mesgコマンドで制御。

書式
　mesg [ y | n ]

使用中のターミナルへ、他のユーザがwriteコマンドやtalkコマンドでメッセージを送信できるかどうかを制御。
引数無しで実行した場合は現在の設定を表示。
【Go】`fmt.Sprintf`で同じ変数を複数の箇所に埋め込みたい

## 概要
Goで文字列に対して変数の値を埋め込みたい場合、`fmt.Sprintf`の関数を使うことがあると思います。Sprintfの概要については、[【Golang】Sprintf関数で文字列を組み立てる方法を解説](https://asapoon.com/golang/3901/sprintf/)の記事を参照ください。
今回はこのSprintfで、同じ変数を複数箇所に埋め込む場合、どうするかというのをメモ書きします。（なお、Printfを使う場合でも同様の対応です）

## 対応方法
[Replace all variables in Sprintf with same variable](https://stackoverflow.com/questions/37001449/replace-all-variables-in-sprintf-with-same-variable)のstackoverflowの記事にある通り、`%[1]v`のような形式で埋め込む設定のところにindexを付与すれば、実現できます。

## 実装サンプル
例題として`第一著者　第二著者　第三著者`という文字列があるとします。この内、「第」の文字と「著者」の文字を、Sprintfを使用して変数で置き換えて文字列を取得します。


```go
package main

import (
	"fmt"
)

func main() {
	result := fmt.Sprintf("%[1]s一%[2]s　%[1]s二%[2]s　%[1]s三%[2]s", "第", "著者")
}
```
公式のTwitter SDKを使ってTweetを取得するメモ (Twitter API v2)


[公式SDK](https://www.npmjs.com/package/twitter-api-sdk)のサンプルなどを漁ってもイマイチぱっと動かせるものがなかったので動かせたものメモ

## Bearer Token

> ![スクリーンショット 2022-10-16 1.08.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/c4457026-cb55-b056-38ea-321eeadbdd96.png "スクリーンショット 2022-10-16 1.08.45.png")

Bearer Tokenを取得しておく。

## SDKインストール

```
$ npm i twitter-api-sdk
```

## ツイート取得

TypeScript SDKですがJavaScript(Node.js)で利用してます。

```js
const {Client} = require('twitter-api-sdk');
const client = new Client(`<Bearer Tokenを記載>`);

const userName = "n0bisuke";

(async () => {
    const { data } = await client.users.findUserByUsername(userName);
    const tweets = client.tweets.usersIdTweets(data.id);
    for await (const page of tweets) {
    	console.log(page.data);
    }
})();
```

以下の記事を参考にさせてもらいました。

> 参考: https://shinshin86.hateblo.jp/entry/2022/07/22/115511
Ubuntu 22.04 から 22.10 へのアップグレードの仕方

# 1. まず現在の Ubuntu 22.04 を最新状態にします。
```
$ sudo apt update 
$ sudo apt full-upgrade
```

# 2. 次に不要物を全消しします
```
$ sudo apt autoremove
```

# 3. 更新の設定をします。
`/etc/update-manager/release-upgrades` を開いて、`Prompt`を`normal`に設定します。

```
# Default behavior for the release upgrader.

[DEFAULT]
# Default prompting behavior, valid options:
#
#  never  - Never check for a new release.
#  normal - Check to see if a new release is available.  If more than one new
#           release is found, the release upgrader will attempt to upgrade to
#           the release that immediately succeeds the currently-running
#           release.
#  lts    - Check to see if a new LTS release is available.  The upgrader
#           will attempt to upgrade to the first LTS release available after
#           the currently-running one.  Note that this option should not be
#           used if the currently-running release is not itself an LTS
#           release, since in that case the upgrader won't be able to
#           determine if a newer release is available.
Prompt=normal
```

# 4. 最後に 22.10 へのアップグレードを実行します。
```
$ sudo do-release-upgrade
```
いつも通り数時間、時間がかかりますので、余裕をもって作業してください。

アップグレード後、22.10になっていることを確認します。
```
$ cat /etc/issue
Ubuntu 22.10 \n \l
```

お疲れさまでした。
M5AtomでGrove MP3モジュールを使う



# Grove MP3モジュール v3.0
Seeed Studio社から発売されている「Grove - MP3 V3 -Music Player」をM5Atom LiteからArduino IDEで利用した時の覚書です。

https://www.seeedstudio.com/Grove-MP3-V3-p-4297.html

こちらを利用してオーディオ出力できるようにしました。

こちらは、制御するマイコン（今回はM5Atom）側から音を渡すのではなく上記MP3モジュール内にセットしているSDカードに保存している音を鳴らすものになります。
と思っていますが、もしも他にやり方があって私がそれを知らないだけだったらすみません。

# M5Stack(M5Atom)から使う
https://wiki.seeedstudio.com/Grove-MP3-v3/
SeeedStudioさんの上記Wikiにサンプルコードがあるのですが、M5で使おうと思った時にどうやったら良いかわかリませんでした。

## 1.ライブラリのインストールとインクルード
まずはWikiにある通りGithubからSeeed_Serial_MP3ライブラリ（下記）をダウンロードしてインストールします。
https://github.com/Seeed-Studio/Seeed_Serial_MP3_Player

![スクリーンショット 2022-10-16 0.32.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308578/644d8008-7301-7a0a-72fd-d96de6061217.png)

それからArduino IDEで「ライブラリをインクルード」すると下記３行が追加されます。
```c++
#include <WT2003S_Player.h>
#include <SeeedGroveMP3.h>
#include <KT403A_Player.h>
```

## 2.コードを書く
HardwareSerialとして下記のように定義します。
```c++
HardwareSerial hSerial(1);
WT2003S<HardwareSerial> Mp3Player;
```
setup時にはHardwareSerialのhSerialをbeginするのですが、この時3,4番目の引数にTX, RX のピンを定義します。
今回はM5Atom LiteのGrove端子を使っているのでTX：32, RX:26をセットします。
それからMp3Playerのinit時の引数としてhSerialを渡します。
```c++
void setup() {
  hSerial.begin(9600,SERIAL_8N1,32,26);
  Mp3Player.init(hSerial);
```
UARTを使っているのでM5.beginするときの１番目の引数はtrueにしないといけないのかなと思いましたが、試してみたところどちらでも大丈夫そうでした。
```c++
  // 本体初期化（UART（どっちでもいいみたい）, I2C, LED）
  M5.begin(false, false, true);
```
あとはWiki仕様にある通りのメソッドが利用できます。
```c++
// ■ 音量の設定（MAX３０）
Mp3Player.volume(30);
// ■ 音声ファイル名を指定して再生
Mp3Player.playSDSong("song.mp3");
```

多分M5Atom Lite以外のM5StackデバイスでもTX,RXの値を変更すれば大丈夫なのではないかなと思いますが未確認です。
電力需給を取得する

電気の需給が逼迫しているというニュースがあった。そこで、手軽に現在の電力需給を把握できるアプリがあればと思った。

## 以前のもの
以前はヤフーに「電力使用状況API」というのがあったが今は終了している。
https://techblog.yahoo.co.jp/web/shinsai/setsuden/

　そこで大本のデータを取得する必要がある。系統情報サービス・でんき予報・広域予備率Web公表システムの中で、でんき予報では、各電力会社が公開している。

## 広域ブロック使用率
広域ブロック使用率は電力会社の地域と周辺を合わせた使用率のようだ。つまり、自分のところが足りなくなると周辺の地域からも供給できるのでそれらを合わせた使用率となる。

広域ブロック使用率は広域予備率Web公表システムから取得できる。
https://web-kohyo.occto.or.jp/kks-web-public/
データのダウンロードは、下のアドレスからダウンロードができるが、zipファイルになっていて面倒だったので直接データを取る方法を取った
https://web-kohyo.occto.or.jp/kks-web-public/download

例えば下記アドレスのクエリを見るとCSVでいつからいつまでというデータを指定することができる。
https://web-kohyo.occto.or.jp/kks-web-public/download/downloadCsv?jhSybt=02&tgtYmdFrom=2022/07/29&tgtYmdTo=2022/07/29

## CSVファイルのパース
取得したCSVは時間と地域が混ざった状態であり、特定の地域を取得するならば抽出する必要がある。北海道から沖縄まで、30分ごとに24時までデータがある。
```csv
"対象年月日","時刻","ブロックNo","エリア名","広域ブロック需要(MW)","広域ブロック供給力(MW)","広域ブロック予備力(MW)","広域予備率(%)","広域使用率(%)","エリア需要(MW)","エリア供給力(MW)","エリア予備力(MW)"
"2022/08/02","00:30","1","北海道","10927.818","13151.098","2223.28","20.35","83.09","2681","3009","328"
"2022/08/02","00:30","1","東北","10927.818","13151.098","2223.28","20.35","83.09","8246.818","10729.998","2483.18"
"2022/08/02","00:30","2","東京","50433.828","58811.602","8377.774","16.61","85.75","34906","40360","5454"
"2022/08/02","00:30","2","中部","50433.828","58811.602","8377.774","16.61","85.75","15527.828","17863.702","2335.874"
"2022/08/02","00:30","3","北陸","29524.168","34507.014","4982.846","16.88","85.56","3318","4408","1090"
"2022/08/02","00:30","3","関西","29524.168","34507.014","4982.846","16.88","85.56","16462","18437.44","1975.44"
"2022/08/02","00:30","3","中国","29524.168","34507.014","4982.846","16.88","85.56","6724","7599","875"
"2022/08/02","00:30","3","四国","29524.168","34507.014","4982.846","16.88","85.56","3020.168","4062.574","1042.406"
"2022/08/02","00:30","4","九州","9796","11820.68","2024.68","20.67","82.87","9796","11820.68","2024.68"
"2022/08/02","00:30","5","沖縄","963","1710.7","747.7","77.64","56.29","963","1710.7","747.7"
```


## でんき予報CSV

CSVデータとしては、次のところから取得できる。https://www.occto.or.jp/keitoujouhou/

北海道電力

http://denkiyoho.hepco.co.jp/area/data/juyo_01_20220704.csv

東北電力

https://setsuden.nw.tohoku-epco.co.jp/common/demand/juyo_02_20220703.csv

東京電力

https://www.tepco.co.jp/forecast/html/images/juyo-d1-j.csv

中部電力

https://powergrid.chuden.co.jp/denki_yoho_content_data/juyo_cepco003.csv

北陸電力

https://www.rikuden.co.jp/nw/denki-yoho/csv/juyo_05_20220703.csv

関西電力

https://www.kansai-td.co.jp/yamasou/juyo1_kansai.csv

中国電力

https://www.energia.co.jp/nw/jukyuu/sys/juyo_07_20220704.csv

四国電力

https://www.yonden.co.jp/nw/denkiyoho/juyo_shikoku.csv

九州電力

https://www.kyuden.co.jp/td_power_usages/csv/juyo-hourly-20220704.csv

沖縄電力

http://www.okiden.co.jp/denki2/juyo_10_20220704.csv

## 完成したアプリ
これらをグラフとして表示するアプリを作った。
https://play.google.com/store/apps/details?id=io.github.kyukyunyorituryo.electricitysupplyanddemand

https://www.amazon.co.jp/dp/B0BGMC38VD
【Windows11】Docker ComposeでRedmineを秒速導入【2022】

## はじめに

自身の趣味(UE5やAI開発，アプリ開発など)や副業などにどれくらいの割合で時間を割いているかを可視化するため，工数管理できる`Redmine`を導入しようと思いやってみました．



## 必要なもの/環境
- Docker for windows

![file](https://hamaruki.com/wp-content/uploads/2022/10/image-1665750381209.png)

この画面が見えるような状態であれば問題ありません．

続きはこちら

▼▼▼▼▼▼▼▼

▼▼▼▼▼

▼▼▼

▼▼

▼

▼

https://hamaruki.com/2022/10/14/docker_001/
【JavaScript】デフォルト引数に三項演算子

jsではデフォルト引数に三項演算子が使える。

```javascript
let isFuga = true;

function hoge(a = isFuga ? 114 : 514) {
    console.log(a);
}

hoge(); // 114

isFuga = false;

hoge(); // 514
```

そんだけ
【SpringBoot】lazy-initializationが有効な環境で全てのBeanが正常に初期化されるかテストする

## やること
`Bean`を遅延初期化することで起動を高速化する`lazy-initialization`オプションですが、`SpringBootTest`の高速化にも有効です。
一方、ただ`lazy-initialization`を有効にするだけではテストで初期化されない`Bean`が出てしまい、最悪デプロイしてみて初めて初期化エラーに気付くことになります。

そこで、全ての`Bean`が正常に初期化されるかだけを確認するテストを作ります。

## やり方
- `@SpringBootTest(properties = ["spring.main.lazy-initialization=false"])`を特定のテストクラスに付ければできる
- `Spring Initializr`で追加される`...ApplicationTests`に付与するのが良さげに思える

```kotlin:サンプルコード（KotlinですがJavaでもそう変わりません）
import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest

@SpringBootTest(properties = ["spring.main.lazy-initialization=false"])
class FooApplicationTests {

    @Test
    fun contextLoads() {
    }
}
```

### 解説
やっていることは別記事でまとめています。
また、この記事では`SpringBootTest`の引数を設定する以外の方法についても触れています。

https://qiita.com/wrongwrong/items/06dddee865df87e36569

付与先を`...ApplicationTests`にしているのは、単に1アプリケーションに1つ存在するテストだからで、特に深い理由は有りません。
Microsoft Ignite関連のAzureリリース情報ピックアップ

## 概要
先日のMicrosoft Ignite関連で発表されたAzureのリリース情報について、検証ネタとして気になるものをピックアップしました。
データ分析系、AKSといったトレンド周りのアップデートは普段利用していないためチェックしきれていませんが、Igniteのセッションでもやはりメインになっていた様子。

また、Azure Stack HCIやAVS等のHybrid関連でも面白いリリース情報が出ていましたが、そちらは別途まとめていこうと思います。

### VM関連
---
#### [[GA] Azure VMのWindows Admin Center管理](https://azure.microsoft.com/ja-jp/updates/windows-admin-center-for-azure-virtual-machines/)
- AzureポータルからWACでVM管理ができる機能
- 対象OSはWindows Server 2016以降
- 使い方
    - Windows Admin Center拡張機能をVMにインストールする必要があり、インストールのためにWindows Admin CenterとAzure ADのサービスタグへの送信許可が必要になる
    インストール時のチェック1つで以下のNSGルールが自動適用
 ![f818c144b66cc3afe7cbf0caba1e2d30311d969dadde056de7db569c2e1224be.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/ebd703d3-653d-bafd-6fb6-e5e038bcc736.png)

    - Windows Admin Center Administrator Loginロールをユーザーに適用する
      ※Data Actionが必要なため、所有者ロールを持っていても権限不足になるため注意
 ![960135283eeaf862f58a3d9651c5a70dad44dbbf749c4125e2d032d55b89bb4f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/6520c2c6-2d0c-8bca-f473-0da65ace6720.png)

    - WAC接続のためには特定ポートでのTCP接続許可が必要（ソースIPは絞れない？）
- 接続イメージ
![30a0519efc211648d9efb8632648ef42bd7c372cd60962206cb9b05619e1d3d7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481267/1fbcd911-f809-928b-4fcc-9e26cb079e73.png)

#### [[GA] WindowsクライアントOSへのAzure Monitorエージェント対応](https://azure.microsoft.com/ja-jp/updates/generally-available-azure-monitor-agent-support-for-windows-clients/)
- Sentinelとの連携等が可能になるが、具体的なユースケースはちょっと浮かばない


### ネットワーク関連
---
#### [[GA] Azure DNS Private Resolver](https://azure.microsoft.com/ja-jp/updates/general-availability-azure-dns-private-resolver-hybrid-name-resolution-and-conditional-forwarding/)
- 5月頃からパブリックプレビューで提供されていた機能のGA情報
- オンプレからAzure上の名前解決をする際に自分でVMを立てずともマネージドでDNSフォワーダーを提供してくれる便利機能、Azure⇒オンプレの逆方向の名前解決も可能
- 提供リージョンに東日本あり

#### [[Preview] DDoS ProtectionのIPアドレス単位での利用](https://azure.microsoft.com/ja-jp/updates/public-preview-ip-protection-sku-for-azure-ddos-protection/)
- これまでVNet単位で提供されていたDDoS Protectionの範囲限定版
- VNet単位の価格が2,944ドル/月（最大100IP）、IP単位が199ドル/月と嬉しい選択肢


### プライベートエンドポイント関連
---
以下はプライベートエンドポイント関連のGA情報
プロジェクトの規約でNIC名称を指定したい、IPも任意に固定したいことはよくあるケースなので嬉しい機能
※正直今までプレビューであることに気づかず使っていましたが・・・
#### [[GA] プライベートエンドポイントで任意のIPアドレスを指定](https://azure.microsoft.com/ja-jp/updates/general-availability-static-ip-configurations-of-private-endpoints/)

#### [[GA] プライベートエンドポイントのNIC名の指定](https://azure.microsoft.com/ja-jp/updates/general-availability-custom-nic-name-configurations-of-private-endpoints/)


### バックアップ関連
---
#### [[Preview] Azure Backupの不変設定](https://azure.microsoft.com/ja-jp/updates/azure-backup-immutable-vaults-preview/)
- Recovery Serviceコンテナとバックアップコンテナを対象にバックアップデータの削除操作や保存期間の短縮をできないようにする機能
- 「削除できないようにする機能」と「『削除できないようにする機能』を無効にできないようにする機能」の2段階で設定が可能で、後者は不可逆的な設定
git addしたファイルの差分を確認する方法

はじめに
--
git addしたファイルの変更箇所を改めて確認したいことがあったので、確認方法を備忘録としてまとめようと思います。


git add後は"git diff --cached"を使用する
--
下記のようにaa.rbファイルを変更してgit addした場合、

~~~aa.rb
put "before"
~~~

~~~aa.rb
#beforeをafterに変更し"git add"でステージングエリアに追加
put "after"
~~~

`aa.rb`の変更箇所(差分)は、下記のコマンドで確認することができます。
~~~
git diff --cached {filename}
~~~

~~~bash
~ % git diff --cached aa.rb
diff --git a/aa.rb b/aa.rb
index e21c5fa..e12c435 100644
--- a/aa.rb
+++ b/aa.rb
@@ -1 +1 @@
-put "before"
+put "after"
~~~

git add前は"git diff"
--
下記のようにaa.rbファイルを変更のみ行なった場合、

~~~aa.rb
put "before"
~~~

~~~aa.rb
#beforeをafterに変更のみ(git add前)
put "after"
~~~


`aa.rb`の変更箇所(差分)は、"git diff"で確認することができます。
~~~
git diff {filename}
~~~

~~~bash
~ % git diff aa.rb         
diff --git a/aa.rb b/aa.rb
index e21c5fa..e12c435 100644
--- a/aa.rb
+++ b/aa.rb
@@ -1 +1 @@
-put "before"
+put "after"
~~~

参考
--
https://qiita.com/shibukk/items/8c9362a5bd399b9c56be
【備忘録】【Rails】before_actionとは

11月からRailsを実務で使うことが決まったので、これから学習したことを備忘録に残していきます。

今日は【before_action】について。

▼ 参考にさせていただいた記事
[pikawaka　【Rails】 before_actionの使い方とオプションについて](https://pikawaka.com/rails/before_action)

# before_actionとは
コントローラの各アクションが実行される前に、何らかの処理を行いたい時に使用するもの。
フィルタの一つ。フィルタとは、コントローラにあるアクションの直前や直後、または直前と直後の両方に実行されるメソッドのことをいい、Railsには様々なフィルタが用意されている。

```rails:before_actionの使用例
class UsersController < ApplicationController
  before_action :メソッド名
end
```

これをコントローラーファイルの上部に記述しておくことで、コントローラーのアクションが動く前にメソッドが実行されて、そのあとでアクションが実行されるようになる。

# どんな場合に、アクションが動く前にメソッドが実行されることが必要？

### ①ログイン認証時

```
before_action :authenticate_user!
```

authenticate_user!は、ログインしていない場合にログインページにリダイレクトさせてくれる、ヘルパーメソッド（Railsが元々用意してくれているメソッド）。便利ですね。

### ②重複した記述をまとめたい時

```ruby
class MessagesController < ApplicationController

  def index
    @messages = Message.all
  end

  def show
    @message = Message.find(params[:id]) # 同じ
  end

  def new
    @message = Message.new
  end

  def create
    Message.create(message_params)
  end

  def edit
    @message = Message.find(params[:id]) # 同じ
  end

  def update
    message = Message.find(params[:id])
    message.update(message_parmas)
  end

  def destroy
    message = Message.find(params[:id])
    message.destroy
  end

end
```

例えば、上記のようにshowアクションとeditアクションで全く同じ記述をしているとします。
Railsでは重複をなるべくさせない原則があるため、重複箇所をメソッド化してまとめてしまいましょう。

```ruby:メソッド定義例
def find_message
  @message = Message.find(params[:id])
end
```

このようにメソッドを定義したら、あとはbefore_actionに書くだけです。

```ruby
class MessagesController < ApplicationController

before_action :find_message

  def index
    @message = Message.all
  end

  def show
  end

  def new
    @message = Message.new
  end

  def create
    Message.create(hoge_params)
  end

  def edit
  end

  def update
    message = Message.find(params[:id])
    message.update(hoge_parmas)
  end

  def destroy
    message = Message.find(params[:id])
    message.destroy
  end

  private

  def set_message
    @message = Message.find(params[:id])
  end

end
```

今回の例では、find_messageメソッドはshowアクションとeditアクションでしか必要がないので、
以下のようにbefore_actionにオプションをつけます。

```ruby
before_action :set_message, only: [:show, :edit]
```

オプションには他にもexceptやif、unlessなど色々ありますが、ここでは自分が一番使いそうなものだけ書いておきました。

## 補足
この記事の最初に「authenticate_user!」について書きましたが、
「authenticate_user!」の記述先であるApplicationControllerは、
全てのコントローラーが継承しているため、全てのコントローラーで働いてしまいます。
もし一部のコントローラーでbefore_actionが動いて欲しくない時があれば、

```ruby
class HogesController < ApplicationController
  skip_before_action :hogehoge
end
```

このようにskip_before_actionというメソッドを使いましょう。
stella_vslamのROS2向けチュートリアル

## 概要

Ubuntu 18.04 で ROS2 galactic (Ubuntu 20.04) の docker コンテナを作って stella_vslam_ros (https://github.com/stella-cv/stella_vslam_ros) を動かしてみました。

## ビルド

```shell
git clone --recursive --branch galactic-devel --depth 1 https://github.com/stella-cv/stella_vslam_ros.git
cd stella_vslam_ros
docker build -t stella_vslam-ros2 -f Dockerfile.socket .
```

## Viewer のビルド

stella_vslam のビューア用のDockerイメージをビルドする。（docker のバージョンは 20.10.12 でした。）

```shell
git clone --recursive https://github.com/stella-cv/stella_vslam.git
cd stella_vslam
git checkout 0.3.7
cd viewer
docker build -t stella_vslam-viewer .
```

## Viewer のサーバ用コンテナを起動

Viewer のサーバ用のコンテナを起動する。

```shell
docker run --rm -it --name stella_vslam-viewer --net=host stella_vslam-viewer
```

## Viewer のクライアントを起動

`http://localhost:3001` をwebブラウザで開く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472745/ea8951c3-49b8-7dd6-8e37-acb31fc3b9fb.png)

## stella_vslam_ros 実行用のコンテナを起動

別のターミナルを開いて、stella_vslam_ros 実行用のコンテナを起動する。

```shell
docker run --rm -it --name stella_vslam-ros2 --net=host stella_vslam-ros2
```

## データセット等のダウンロード

起動した stella_vslam 実行用のコンテナの中にデータセット等をダウンロードする。

```shell
apt update
apt install -y python3-pip
pip3 install gdown

curl -sL "https://github.com/stella-cv/FBoW_orb_vocab/raw/main/orb_vocab.fbow" -o orb_vocab.fbow
curl -sL "https://raw.githubusercontent.com/stella-cv/stella_vslam/0.3.7/example/aist/equirectangular.yaml" -o equirectangular.yaml

gdown "https://drive.google.com/uc?id=1d8kADKWBptEqTF7jEVhKatBEdN7g0ikY"
gdown "https://drive.google.com/uc?id=1TVf2D2QvMZPHsFoTb7HNxbXclPoFMGLX"
unzip aist_living_lab_1.zip
unzip aist_living_lab_2.zip
```

## 再生用ツールをインストール

```shell
apt install -y ros-galactic-image-publisher
source /ros2_ws/install/setup.bash
```

## tf を publish する

以下のコマンドで tf を publish するノードをバックグラウンドで起動する。

```shell
ros2 run tf2_ros static_transform_publisher 0 0 0 0 0 0 odom base_footprint&
ros2 run tf2_ros static_transform_publisher 0 0 -1.57 0 0 -1.57 base_footprint camera&
```

## SLAM 実行

stella_vslam-ros2 のコンテナに戻って、以下のコマンドで run_slam をバックグラウンドで実行する。

```shell
ros2 run stella_vslam_ros run_slam \
    -v ./orb_vocab.fbow \
    -c ./equirectangular.yaml \
    --map-db-out map.msg&
```

以下のコマンドで、動画を publish する。（ループ再生になっていることに注意。）

```shell
ros2 run image_publisher image_publisher_node ./aist_living_lab_1/video.mp4 --ros-args --remap /image_raw:=/camera/image_raw
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472745/607f687b-c3cf-0622-7d37-8cef13554917.png)

Viewer の Terminate ボタンを押すと、地図を保存して run_slam が終了する。

## Localization 実行

保存した地図を使って自己位置推定を行う。

```shell
ros2 run stella_vslam_ros run_slam \
    --disable-mapping \
    -v ./orb_vocab.fbow \
    -c ./equirectangular.yaml \
    --map-db-in map.msg&
```

以下のコマンドで、動画を publish する。

```shell
ros2 run image_publisher image_publisher_node ./aist_living_lab_2/video.mp4 --ros-args --remap /image_raw:=/camera/image_raw
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472745/2e44714d-96d9-7216-e190-65b53349fda8.png)
自動車工学とBosch Vehicle Handbook

# 科学分類

科学を、自然科学、社会科学、人文科学の３つに分類する。　
科学のうち、自然科学、社会科学、人文科学に分類するのを保留したものに哲学と数学を記載する。哲学は人文科学に分類してもよい。数学は自然とは限らず、自然科学に分類するのは違和感がある。
自然科学、社会科学、人文科学の中身をそれぞれ３つに分類する。ここには、世の中で言う、文系・理系という分類はない。文系・理系は大学受験の科目による分類であって科学の分類ではないし、卒業時点の研究の分類でもない。

科学　
・哲学　
・数学　
・自然科学　
・・物理学　
・・化学　
・・生物学　
・社会科学　
・・法学　
・・経済学　
・・社会学　
・人文科学　
・・言語学　
・・文学　
・・人類学　

<この項は書きかけです。順次追記します。>
This article is not completed. I will add some words in order.
## 科学における自動車工学の位置
科学分類を詳細化し、自動車工学の位置を確認する。

・哲学　
・・論理学
・・認識論
・数学　
・・代数学　
・・幾何学
・・解析学
・・集合論
・・確率論
・・統計学
・自然科学　
・・物理学　
・・・力学　
・・・・機械工学
・・・・・自動車工学
・・・・・・駆動(Drivetrain)
・・・・・・車台系(Chassis system)
・・・・・・車体(Vehicle body)
・・・・・・連結・結合技術(joining and bonding technique)
・・・・・・自動運転(automated driving)
・・・・・航空工学
・・・・・ロボット工学
・・・・・有限要素法
・・・・・制御工学
・・・熱力学　
・・・・内燃機関(internal combustion engines)
・・・流体力学
・・・電磁気学　
・・・・電気工学
・・・・電子工学
・・・・・計算機科学・計算機工学
・・・・・通信工学
・・・・・人口知能
・・・量子力学
・・・・量子計算機
・・化学　
・・・無機化学　
・・・・金属学・金属工学
・・・・・塗装
・・・有機化学　
・・・・高分子学　
・・生物　
・社会科学
・・法学　
・・・排ガス法規制
・・・特許
・・・規格　
・・・・WTO\TBT協定　
・・・・産業標準化法
・・経済学　
・・・原価計算
・人文科学　
・・言語学　
・・・英語　
・・・日本語

# bosch vehicle handbook
自動車工学（Motor vehicles)
基本原理（Basic principles)
数学・方法(Mathematics and methods)
材料（Materials)
機械部品（Machine parts)
連結・結合技術(joining and bonding technique)
自動車物理(vehicle phisics)
作動液(operatin fluid)
駆動(Drivetrain)
内燃機関(internal combustion engines)
火花発火機関管理(management for spark-ignition engine)
代替燃料揮発油機関運転(Gasoline engine operation with alternative fuels)
軽油機関管理(management for diesel engines)
給電(electrification of the drive)
放出制御診断法規制(emission control and diagnosis legislation)
車台系(Chassis system)
車台制御(chasis control)
車体(Vehicle body)
快適便利(comfort and convenience)
自動車安全系(Safety systems in the motor vehicle)
自動車安心系(Vehicle security system)
自動車電気(Automotive Electics)
娯楽情報系(infotainment)
運転補助検知器(driver assistance and sensors)
運転補助系(driver assistance systems)
自動運転の将来(future of automated driving)

ボッシュ自動車handbook(英語)11版(0)
https://qiita.com/kaizen_nagoya/items/dfa35aa6f669e5df983e

ボッシュ自動車handbook(英語)11版(0) 課題と記事一覧
https://qiita.com/kaizen_nagoya/items/dfa35aa6f669e5df983e

ボッシュ自動車ハンドブック
https://qiita.com/kaizen_nagoya/items/8e330ce57880f04d71d9

# 関係図　
現在、関係図を作成中。　

おおまかな分類での関係図と、詳細な項目での関係図は様相が異なるかもしれない。　

法規制、安全、安心(security)は、社会科学領域の原理が大きく影響しており、工学分類で理解するのでは不十分である。　

少なくとも、自然科学、社会科学、人文科学の３軸に分類するとよい。　

排ガス規制、エンジン電子制御が始まってから５０年である。　

自動車業界１００年の変革期という人がいる。
５０年前に、Hondaが排ガス規制によるエンジン制御を初めて、電子制御が興隆したことを考えると、電気自動車と自動運転は５０年ぶりの変革期だと思う。

<この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。>
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.

# 文書履歴(document history)
ver. 0.01 初稿 　20221015
ver. 0.02 URL追記 20221024
ver. 0.03 ありがとう追記 20230314
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
【Terraform】Terraformで扱える変数とデータ型まとめ

# はじめに
udemyを使ってTerraformの勉強をしたので、Terraformで扱える変数とデータ型についての学習備忘録です。

https://www.udemy.com/course/iac-with-terraform/

# HCL2とは
Terraformは、HCL2言語で書きます。
HCL2とは、```the HashiCorp configuration language```です。

https://github.com/hashicorp/hcl

# コメントの書き方
```terraform
# コメントは#で書ける
```

# ブロックタイプとは
下記のコードで、resource部分を```ブロックタイプ```と言います

```terraform
resource "aws_instance" "hello-world" {
```
## ブロックタイプまとめ

|  種類  |  説明  |
| ---- | ---- |
|  locals  |  外部から変更できない変数  |
|  variables  |  外部から変更できる変数  |
|  terraform  |  terraformの設定  |
|  provider  |  プロバイダ  |
|  data  |  terraform管理していないリソースを参照する  |
|  resource  |  terraform管理対象となるリソース  |
|  output  |  外部から参照できるようにする値  |


# localsの定義
```localsブロック```で定義して、```${local.<NAME>}```で参照します

```terraform
locals {
  name = "HelloWorld"
}
resource "aws_instance" "hello-world" {
  ami           = "ami-0ce107ae7af2e92b5"
  instance_type = "t2.micro"
  tags = {
    Name = "${local.name}-ec2"
  }
}
```

# variablesの定義
```variablesブロック```で定義して、```${var.<NAME>}```で参照します

```terraform
# variable <変数名>
variable "name" {
  type    = string       # 変数の型
  default = "HelloWorld" # デフォルト値
}
resource "aws_instance" "hello-world" {
  ami           = "ami-0ce107ae7af2e92b5"
  instance_type = "t2.micro"
  tags = {
    Name = "${var.name}-ec2"
  }
}
```

# HCL2で扱えるデータ型

## プリミティブ
### ```string``` : Unicode文字列
### ```number``` : 数値。整数と少数の両方を表現する
### ```bool```: true/false

```terraform
variable "string" {
  type    = string       # 変数の型
  default = "HelloWorld" # デフォルト値
}

variable "number" {
  type    = number # 変数の型
  default = 10     # デフォルト値
}

variable "bool" {
  type    = bool # 変数の型
  default = true # デフォルト値
}
```


## 構造体
### ```object({<NAME>=<TYPE>, ...})``` : キーバリュー型データ

```terraform
# 定義
variable "object_sample" {
  type = object({
    name = string
    age  = number
  })
  default = {
    name = "sasayoshi"
    age  = 100
  }
}
```

```terraform
# 参照
Name = ${var.object_sample.name}
```

### ```tuple([<TYPE>, ...])``` : 各列の型が決まっている配列

```terraform
# 定義
variable "tuple_sample" {
  type = tuple([
    string, number
  ])
  default = ["sasayoshi", 1000]
}
```

```terraform
# 参照
 Name = "${var.tuple_sample[0]}"
```


## コレクション
### ```list(<TYPE>)```: 特定の型で構成される配列


```terraform
# 定義
variable "list_sample" {
  type    = list(string)
  default = ["hoge", "hogehoge"]
}
```

```terraform
# 参照
Name = "${var.list_sample[0]}"
```


### ```map(<TYPE>)```: キーが文字列の配列

```terraform
# 定義
variable "map_sample" {
  type = map(string)
  default = {
    "High" = "m5.2xlarge"
    "Mid"  = "m5.large"
    "Low"  = "t2.micro"
  }
}
```

```terraform
# 参照
instance_type = var.map_sample.High
```


### ```set(<TYPE>)```: 値の重複がない配列


```terraform
# 定義
variable "set_sample" {
  type = set(string)
  default = [
    "tanaka",
    "sato",
    "tanaka",
    "sato"
  ]
}
```

```terraform
# 参照
[for itm in var.set_samle : itm]

→ toset([
    "sato",
    "tanaka"
  ])
```

以上です。今日は、Terraformで扱える変数とデータ型をまとめてみました。
AWS Glue Studioで機密データ （PII）検出と処理を試す

AWS Glue DataBrewに続き、AWS Glueでも個人識別情報 (PII) やその他の機密データの自動検出に対応してます。

https://aws.amazon.com/jp/about-aws/whats-new/2022/04/aws-announcing-sensitive-data-detection-glue/

公式ドキュメントはこちら
https://docs.aws.amazon.com/ja_jp/glue/latest/ug/detect-PII.html#choose-pii-entities


## 機密データ検出ジョブ作成

`Detect Sensitive Data`アクションを利用する。
以下の例は単純にS3上のファイルをPII検出して変換し、S3に保存する。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/8cd671fc-48fa-1c9c-3fec-bfb37b836af1.png" width=40%>

標準は`Find sensitive data in each row`で全てのデータをスキャンして、PIIなど機密データの検出を行う。
もう１つの`Find columns that contain sensitive data`は、PII検出のスキャン対象を絞るために、ある程度の指定した範囲のサンプルをスキャンしてPIIカラムを特定して実行する方法。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/8706ae45-9f38-fbb0-7731-9849b6305c7e.png" width=60%>

機密データとして識別可能なパターンは、2022/10/15時点では17種類。
2022/11に新たに下記日本のデータタイプも追加された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/e13cc533-c6f5-0834-b30e-2cb1885b7c9c.png)

https://aws.amazon.com/jp/about-aws/whats-new/2022/11/aws-glue-sensitive-data-detection-identify-process-sensitive-data-japan-uk-entities/


あらかじめカテゴリという定義もあり、各要件に応じて項目がマッピングされている。氏名や電話番号などいわゆる個人情報以外にも、IPアドレスやMACアドレスなど様々。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/f2d9137f-f5be-974a-188e-982715a6951e.png" width=60%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/c172825e-d6e0-757e-7349-5b44055bbcbe.png" width=60%>

ビルトインで定義されていないパターンはカスタムで正規表現で定義できる。
以下はハイフンを含む電話番号を検知したい場合のパターン定義例。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/5123c36e-0be7-120e-37cc-c5b17ae7b4a3.png" width=60%>

正規表現の文法チェックには以下が便利
https://www-creators.com/tool/regex-checker

機密データを検知したらどうするか？を定義できる。
`Redact detected text`にチェックを入れると、デフォルトでは機密データを削除するが、オプションで ******* のような固定文字に変換できる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/d477966a-1a9f-fa8b-15fc-dd787d97a2de.png" width=60%>

## ジョブ実行結果サンプル

ダミーデータに対して実行した結果例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/55711085-4728-393f-f6a5-aa0b0571646c.png)
１行目の結果は元データで、２行目はジョブ実行結果行。
SSN（社会保障番号）、氏名、電話番号、メールアドレス、CCN（クレジットカード番号）が自動的に検知されて ******* でマスクされている。

なお、AWS Glue Studio ジョブ中に Detect PII transform を使用する場合、AWS Glue 3.0が必要。

### 日本語対応
ちなみに日本語ダミーデータでも試したところ、メールアドレスやCCNなど万国共通のものは検知と変換されましたが、氏名、住所など漢字または日本特有フォーマットの項目は現時点では未対応となってます（2022/10/15時点）。電話番号などは前述の正規表現によるカスタムパターン定義でも対応できます。

追記）
2022/11/7のアップデートで、以下の日本固有のデータタイプに対応が追加されてます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112537/bc1d0505-e96c-fa24-a57a-0d40197c38c7.png)
https://docs.aws.amazon.com/ja_jp/glue/latest/dg/aws-glue-api-sensitive-data-api-sensitive-data-api-example.html
https://aws.amazon.com/jp/about-aws/whats-new/2022/11/aws-glue-sensitive-data-detection-identify-process-sensitive-data-japan-uk-entities/

## まとめ
Glue Studioを使えばGUIだけで比較的簡単に機密データの自動検知と変換処理を組み込める。
機密データ項目が予め特定できており、カラムレベルで一律変換したい場合は単純に項目指定の変換処理を組み込むでも良いが、検知や各基準への準拠を自動化したい場合には有効。
Excel業務(無駄)を自動化したい　part1 Excelに値を代入しよう

# はじめに
このサイトでは、社会人なりたての私が無駄を省くための戦いをまとめています。
今回のテーマは、pythonのライブラリを用いて、
Excelに文字列を代入することをメインに書いていきます。
ライブラリ名は、openpyxlです。

# 実行環境
Windows10
Python 3.10.5

# openpyxlとは？
openpyxlはExcelファイル(`.xlsx`)を読み書きできるツールです。
公式ドキュメント　[openpyxl/openpyxl-Bitbucket](https://bitbucket.org/openpyxl/openpyxl/src/master/)
詳しくは[こちら！](https://note.nkmk.me/python-openpyxl-usage/)
**今回はExcelファイル内のデータを読み込んで、分析するのではなく、
代入したいだけなので、pandasではなくopenpyxlを使用しています！**


# Excelに値を代入しよう！
Excel業務の自動化の第一歩として、Excelデータをロードして、セルの値を変更を行うプログラムを作成します。
## Excelデータのロード
セルに値を代入する上で、前処理として代入したいセルを持つExcelファイルをロードする必要があります。
ロードするためには、Excelファイルのパスがあればできます！
openpyxlを用いたロード方法は、
```python:excelデータのロード
import openpyxl

xlsx_path = "Excelファイルのパス"
wb = openpyxl.load_workbook(xlsx_path)
```
これでExcelファイルをロードすることができます。
ただこれだけでは、どのシートをいじるかわかりません！
```python:excelデータのシートの指定
ws = wb.worksheets[0]
```
上記のコードを加えることで、シートを指定できるので、これでロード完了です！
※今回はコピペですが、別途関数の話はしたいと思います(多分)

## セルに値を代入する
前章でExcelファイルのロードができました。
ここからいよいよセルに値を代入に入りましょう！
`Worksheet`オブジェクトにExcelのセルを指定すると`cell`オブジェクトを取得できます。
また`cell`オブジェクトには`value`属性があるため、これを操作すると代入できます！
```python:セルの代入方法
print(ws['A1'].value)
# ""

str = "代入OK！"
ws['A1'].value = str

print(ws['A1'].value)
# "代入OK！"
```
このように`cell`オブジェクトの`value`の値を変えることで、Excelに値を代入できます。
※セルの指定方法は別にある
```python:セルの代入方法(別解)
str = "代入OK！"
ws.cell(row=1, column=1).value = str
```

# 終わりに
みなさん、会社に所属しているとExcelとは切っても切れない関係なので、
いい関係で終われるように、楽をしましょう！
これからシリーズでpythonを使ったExcel業務の自動化についてのことを学びながら書いていきます。
(早く自動化系のこと書きたい…)
AWS Certified Machine Learningの勉強方法

2022/09/25に[AWS Certified Machine Learning](https://aws.amazon.com/jp/certification/certified-machine-learning-specialty/)を822点で合格しました。
合格に至るまでに、何をどれぐらい勉強したか、記載します。


# 目次
1. [試験範囲](#1-試験範囲)
2. [前提知識](#2-前提知識)
3. [勉強したこと](#3-勉強したこと)
     1. [TechStock](#3-1-TechStock)
     2. [AWS公式対策講座](#3-2-AWS公式対策講座)
     3. [AWS公式模擬試験](#3-3-AWS公式模擬試験)
4. [最後に](#4-最後に)


# 1. 試験範囲
試験範囲は公開されています。
[こちら](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-ml/AWS-Certified-Machine-Learning-Specialty_Exam-Guide.pdf)を見ましたが、結局練習問題をたくさん解くので、解いているうちになんとなく理解できます。
特徴としては、AWS用語が全く出ない**機械学習そのものの知識が問われる問題**もあります。


# 2. 前提知識
私は[Kaggle](https://www.kaggle.com/)という機械学習の予測精度を競うコンペに出場しており、Kaggle Expertという称号を持っています。
なので、機械学習そのものの知識は多少あり、実際、**試験で機械学習の知識が足りない、ということはありません**でした。
![Kaggle__Your_Machine_Learning_and_Data_Science_Community.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173913/bd45f793-e20b-6a8e-f615-b025bd72d1ee.png)

一方、AWSに関してはSagemakerも触ったことがなく、**実務は初心者**です。
ただ、[AWS Certified Cloud Practitioner](https://aws.amazon.com/jp/certification/certified-cloud-practitioner/)は取得しており、最低限の知識だけはある状態です。


# 3. 勉強したこと
**基本的には、問題集を解きまくりました。**
もちろんただ解くだけでなく、**選択肢を含め、知らない単語があれば全て調べました。**
私は実際にAWSは触りませんでしたが、触った方がイメージしやすくてより良いと思います。


# 3-1. TechStock
[TeckStock](https://techstock.jp/)という、AWS試験のWeb問題集があります。
![TechStock｜AWS_WEB問題集で学習しよう.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173913/f1a349ec-f2bc-fec1-7aed-9eafad2e6fb3.png)


- 問題数：161
- 費用　：90日で5480円
私はこれを2周しました。
ただ、解答が間違っていると思われるケースも3%程度ありました。
私は前述の通り、機械学習の知識が多少あるため間違いに気づけましたが、**初めて機械学習に触れる方は単純に答えを信じるのではなく、ご自身で調べることをお勧めします**。

# 3-2. AWS公式対策講座
[Exam Readiness: AWS Certified Machine Learning - Specialty (Japanese) 日本語実写版](https://aws.amazon.com/jp/blogs/news/aws-certification-exam-readiness/)を受けました。
![AWS_Skill_Builder.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173913/85d78b03-8ae5-54d2-508c-144c13f2c1a6.png)

最後に模擬試験があるのですが、私が受けた時は**50問程度ありました。**
こちらは解答が間違っているということはないはずです。
こちらも2周しました。

# 3-3. AWS公式模擬試験
問題数は**20問程度**と少ないですが、公式模擬試験もあります。
少し前は数千円かかったみたいですが、**今は無料**です。
受講までの手順は[こちら](https://dev.classmethod.jp/articles/new-aws-official-practice-questions/)にまとまっているため、ご確認ください。
![ななななんと！AWS認定の模擬試験が無料になりました！！___DevelopersIO.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173913/5c5ab409-f582-cded-618e-84a720b50913.png)

# 4. 最後に
冒頭にも記載しましたが、**2022/09/25に822点を取得し、合格**しました。
合格ラインは1000点中750点なので、ある程度余裕はありました。
機械学習の知識が一定ある方であればそこそこ簡単に取れると思いますが、**機械学習を全く知らない方はその部分の知識補充が大変**かもしれません。
【Material-UI Tabs】タブのスタイルを変更する

# Tabs

MUI では Tabs コンポーネントが用意されています。

https://mui.com/material-ui/react-tabs/

# スタイル変更

通常のタブは以下のようになっています。

```react
<Tab label="Item One" {...a11yProps(0)} />
<Tab label="Item Two" {...a11yProps(1)} />
<Tab label="Item Three" {...a11yProps(2)} />
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/93e5b0ff-a81d-d4fd-5f93-6d84a8c48b2f.png)


タブの背景のスタイルを変更するには以下のように `label` タグにタグを埋め込みます。

```react
<Tab label={<span className='tabLabel'>Item One</span>} {...a11yProps(0)} />
<Tab label={<span className='tabLabel'>Item Two</span>} {...a11yProps(1)} />
<Tab label={<span className='tabLabel'>Item Three</span>} {...a11yProps(2)} />
```

![Qiita-gif用.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621414/0cb9b87d-33a7-286c-1ff2-e915917afdc6.gif)

下線のスタイル変更は以下の記事が参考になりました。

https://zenn.dev/hirof1990/scraps/c007dcdf5db118

完全なコードは以下に置きました。

https://github.com/quryu-1/react-mui-example/tree/main/tabs

# 参考記事

https://mui.com/material-ui/react-tabs/

https://zenn.dev/hirof1990/scraps/c007dcdf5db118

https://stackoverflow.com/questions/50965941/material-ui-tab-label-font-size-is-really-small
静的変数に関する知識

# 何についての記事か
c++の静的変数：静的記憶域期間（static storage duration）を持つ変数についての知識について記載しています。
静的記憶域期間（static storage duration）を持つ変数とはプログラム実行開始時にメモリに値が格納され、プログラムの実行が終了するまでそこにあり続ける変数のことです。

# まとめ
- 静的変数の種類
    - グローバル変数
    - 静的メンバ変数
    - 静的ローカル変数(関数内static変数)
- 静的変数の初期化仕様
    - 前提
        - 静的変数の初期化はmain()前に行われる
    - 初期化種類
        - 静的初期化（コンパイル時に完了）
            - コンパイル時に値が決まる場合はプログラム開始時にその値が書き込まれる
            - 値が決まらない場合は0が書き込まれる
        - 動的初期化
            - コンストラクタが呼ばれコンパイル時には決まらなかった値が設定される
    - 初期化順
        - 静的初期化→動的初期化
        - 異なる翻訳単位の静的変数は順序不定
        - 同じ翻訳単位の静的変数は宣言順に初期化
        - templateクラスの静的メンバ変数（明示的特殊化なし）の場合はすべて不定

# 静的変数の種類
- グローバル変数
```c++
//main.cpp
static int a = 10;//これ
extern int b;//これ
int main(){
}

//b.cpp
int b = 10;
```

- 静的メンバ変数
静的メンバ変数は個々のインスタンスが持つことはなく、クラスSampleの全てのインスタンスで共通となる。
```c++
struct Sample {
	void CountUp() {
		num++;
		std::cout << "num: " << num << std::endl;
	}
	static int num;
};


int main(){
    Sample instance1;
	instance1.CountUp();//num==1

	Sample instance2;
	instance2.CountUp();;//num==2
}
```

- 静的ローカル変数(関数内static変数)
関数が初めてcallされた際に初期化される。初期化順を規定したい場合に使用したりする。
```c++
void f()
{
    static int num = 0;//これ
    num += 1;
    return ;
}

int main(){
    f();//num == 1
    f();//num == 2
}

```

# 静的変数の仕様を知らないと何がまずいか
「Static Initialization Order Fiasco」と呼ばれる問題に出会います。
静的変数の初期化順序が不定であるために起きる問題の総称で、"Fiasco"は「
(野心的な企てがこっけいな結果で終わるような)大失敗」という訳だそうです。
main()開始前に○○してやろうと思ったときは一度、静的変数の仕様に注意を払う必要がありそうです。

[Static Initialization Order Fiasco](https://in-neuro.hatenablog.com/entry/2020/12/12/001244)で紹介されている例は以下です。
yのコンストラクタでX::xsにpush_backしているが、X::xsの初期化はyのコンストラクタの前と後どちらでしょうか。push_backした後に初期化されたら不具合です。
```c++
struct X
{
    static std::vector<int> xs;
};

struct Y
{
    Y() {X::xs.push_back(42);}
};
static Y y;
std::vector<int> X::xs{};


```

ここからは初期化の仕様についてです。
初期化には２種類あり、静的初期化→動的初期化の順で実行されます。
- 初期化種類
    - 静的初期化（コンパイル時に完了）
        - コンパイル時に値が決まる場合はプログラム開始時にその値が書き込まれる
        - 値が決まらない場合は0が書き込まれる
    - 動的初期化
        - 静的初期化の後に実行される
        - コンストラクタが呼ばれコンパイル時には決まらなかった値が設定される

```c++
//Test.h
struct Test {

	Test(int n) : num(n) {

	}
	int num;
};

//Test.cpp
Test staticA(10);


//main.cpp
extern Test staticA;//コンパイル時に0で初期化

int staticB = staticA.num;//静的初期化の値を使用してしまっている

int main() {
	std::cout << "staticB: " << staticB << std::endl;//staticB==0 静的初期化の値を使用してしまっている
	std::cout << "staticA.num: " << staticA.num << std::endl;;//動的初期化(コンストラクタ)で10がSetされている
}


```

- 初期化順
    - 異なる翻訳単位の静的変数は順序不定
    - 同じ翻訳単位の静的変数は宣言順に初期化
    - templateクラスの静的メンバ変数（明示的特殊化なし）の場合はすべて不定

# 参考
[コンパイル時初期化を強制する"constinit"](https://cpprefjp.github.io/lang/cpp20/constinit.html)
[Static Initialization Order Fiasco](https://in-neuro.hatenablog.com/entry/2020/12/12/001244)
Ubuntu 22.10でElixirをインストール検証

公式サイトを確認してみる
https://elixir-lang.org/install.html#gnulinux

確認した結果、今までと違って
`sudo apt-get install elixir`
のみでインストール可能

20.04までは
```
wget https://packages.erlang-solutions.com/erlang-solutions_2.0_all.deb && sudo dpkg -i erlang-solutions_2.0_all.deb

sudo apt-get update

sudo apt-get install esl-erlang

sudo apt-get install elixir
```
必要だったが22.04以降は不要のようだ

インストールした結果下記のバージョンがインストールされた
```
Erlang/OTP 24 [erts-12.3.2.1] 
Elixir (1.12.2)
```

![Screenshot 2022-10-15 21:30:02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/97c35b7e-320e-13d6-5d27-5e4646955922.png)

![Screenshot 2022-10-15 21:31:40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/0c522dfe-1147-7714-3929-7a6449e890c8.png)
openpyxlでグラフの凡例を一部項目だけ消したい

Excelのグラフ(散布図)を作るとき、指定した横軸座標を示す縦棒(カーソル)を入れたくなることがあります。
散布図の系列として縦線を追加すればいいのですが、そのままでは凡例に余計な項目が表示されてしまうのが気に入りません。

そこで、openpyxlでグラフを生成し、カーソルとなる線を追加した後にその凡例の項目を消すように試みました。

```python
import math
import openpyxl

xax = list(range(360))
values = [
    ['', *xax]
    ,['sin', *[math.sin(x*math.pi/180) for x in xax]]
    ,['cos', *[math.cos(x*math.pi/180) for x in xax]]
]

wb = openpyxl.Workbook()
ws = wb.active
for l in values:
    ws.append(l)

chart = openpyxl.chart.ScatterChart()   #散布図
chart.anchor = 'A7' #chart挿入先セル
chart.y_axis.scaling.min = -1.5 #y軸最小値
chart.y_axis.scaling.max = 1.5  #y軸最大値

#データ系列追加
xvalues = openpyxl.chart.Reference(ws, min_col=2, max_col=361, min_row=1)
for id in range(len(values)-1):
    values = openpyxl.chart.Reference(ws, min_col=1, max_col=361, min_row=id+2)
    series = openpyxl.chart.Series(values, xvalues, title_from_data=True)
    chart.series.append(series)

#カーソル追加
for ic, v in enumerate([135, 180]):
    id+=1
    eq = '=B' + str(ws.max_row + 1)
    l = ['cursor' + str(ic+1), v, eq, eq, -1.5, 1.5]
    ws.append(l) 
    xvalues = openpyxl.chart.Reference(ws, min_col=3, max_col=4, min_row=id+2)
    values = openpyxl.chart.Reference(ws, min_col=5, max_col=6, min_row=id+2)
    series = openpyxl.chart.Series(values, xvalues, title_from_data=False)
    chart.series.append(series)
    chart.legend.legendEntry.append(openpyxl.chart.legend.LegendEntry(idx=id, delete=True)) #legend項目消去

ws.add_chart(chart)
wb.save('chartCursors.xlsx')
```

LibreOffice Calc で開くと期待通りの結果になったのですが、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1923193/e3f45537-c749-6e6d-e720-94a485afc1f1.png)

Excelでは凡例の項目が消えてくれませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1923193/b7d6738d-ff50-8847-2caf-4585f803fc72.png)

どうやら、同じ現象に悩んでいる人もいるようで、xlsxファイルの中身(XML)は正しく生成されていても、Excelが正しく表示してくれない(?)ようです。
https://foss.heptapod.net/openpyxl/openpyxl/-/issues/1604
【Git】ステージした変更を取り消す方法

## ステージングのみ取り消す

変更内容はそのままにステージングのみ取り消すには以下を実行します。  

```zsh
git restore --staged パス
```

`test.txt`を作成して試しに実行してみます。  
作成後に`git add test.txt`を実行した状態が下の画像です。  

![5C0748CF-728C-4AC0-890B-7B5EEE254B94.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/ae503746-27d9-770f-ad8b-f23c6742dc4e.png)

「ステージされている変更」に`test.txt`があります。  
ターミナルでコマンドを実行し取り消します。  

```zsh
git restore --staged test.txt
```

![4C590208-CF47-49C4-B49F-11C8028F5F09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/9e788611-838d-5f59-893b-4af3228334d9.png)

ステージングが取り消されて「変更」に`test.txt`が表示されています。  

なお`--staged`をつけないで実行するとステージ後に加えた変更を取り消せます。  

ステージ後に`test.txt`へ変更を加えます。  

![DD5522BA-71BA-4B30-BF44-009522399D89.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/384593d0-da4a-38f7-90c5-c1bc303f5a30.png)

ステージ後に変更が加えられたため「ステージされている変更」と「変更」の両方に
`test.txt`が表示されています。

`--staged`をつけないで実行します。  

```zsh
git restore test.txt
```

するとステージング後の`test.txt`への変更が取り消されます。  

![6C8FE656-86BA-4F52-A7AA-0809F76C9B28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/54a7990b-627f-1122-4013-1db12ec45de7.png)

「変更」から`test.txt`の表示が消えました。  

## 変更内容ごと取り消す

変更内容ごとステージを取り消すには以下のように実行します。

```zsh
git restore --source=HEAD --staged --worktree パス
```

上記を実行するとステージと変更内容の両方が取り消され、直前のコミットの状態に戻ります。

## ステージング前の変更のみ取り消す

ステージング前の変更のみ取り消すには以下のように実行します。

```zsh
git restore --worktree パス
```
【Unity】 RuntimeTestでFrameCountを取得したい

## 本記事について

↓こんな感じでいつ呼ばれてるか出したかった。
![スクリーンショット 2022-10-15 20.06.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/1a05093b-41e6-4bdf-5dd3-97b6b1a40440.png)

この処理何フレームで呼ばれてるんだろう。ってときにUnity Test Runnerで `Time.frameCount`使ったら固定値で使えなかった。
仕方ないから自分で計測する

## 実装

```.cs
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Cysharp.Threading.Tasks;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
using System;
using System.Threading;

namespace HogeTests
{
    public class FugaTest
    {
        int frameCount = 0;
        CancellationTokenSource frameCountCts = null;

        async UniTask FrameCount(CancellationToken cancellationToken)
        {
            int maxCount = 1000;
            while(frameCount < maxCount)
            {
                await UniTask.Yield();
                frameCount++;
                Debug.Log(frameCount); // 毎フレームログに出力
                cancellationToken.ThrowIfCancellationRequested();
            }
        }

        [SetUp]
        public void SetUp()
        {
            frameCount = 0;
            frameCountCts = new CancellationTokenSource();
            FrameCount(frameCountCts.Token).Forget();
        }

        [TearDown]
        public void TearDown()
        {
            frameCountCts?.Cancel();
            frameCountCts?.Dispose();
        }

        [UnityTest]
        public IEnumerator テストテスト() => UniTask.ToCoroutine(async () =>
        {
            // ゴニョゴニョ
        });

```

もっとうまいやり方あったらコメントで教えていただけると嬉しいです。
GASでテンプレシートを対象者分コピーするスクリプトを作った

# 概要
対象者を記載することで、スプレッドシートのテンプレシートを対象者の名前でその数分コピーするスクリプトを作りました。
同じシートを複数、名前を変えて作ることができます。

イベントや各種表を人数分作りたい時に便利です。

# 例
対象者の名前分、交通費のテンプレートのコピーを作成します。

![GAS.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2918286/3f65786e-13a2-9916-c403-5657231002c1.gif)

# アプローチ
以下の方針でアプローチしました。
1. 対象者を取得する。
2. 対象者分、繰り返す。
-1.対象者の名前で既にシートがあればスキップする。
-2.テンプレシートをコピーする。
-3.コピーされたシートを対象者の名前でリネームする。
3. 作成したシート数を表示する


# エッセンス

## 1. 対象者を取得する。
以下のように実装しています。
memberSheet は対象者一覧のシートでSheetオブジェクトです。

```.js
    var members = memberSheet.getDataRange().getValues();
```
Sheetオブジェクト.getDataRange() では Rangeオブジェクトが返ってきます。
Rangeオブジェクトに対して、getValues()することで値が入っている範囲を行・列の二次元配列として取得できます。
https://developers.google.com/apps-script/reference/spreadsheet/sheet#getdatarange
https://developers.google.com/apps-script/reference/spreadsheet/range#getvalues

## 2. 対象者分、繰り返す。
### 2-2 対象者の名前で既にシートがあればスキップする。
スプレッドシートでは同じ名前のシートは作れません。
対象の名前で既に存在する場合は、作成をスキップする必要があります。
THIS_SHEETはこのGASがあるスプレッドシートで、SpredSheetオブジェクトです。
memberNameは １. で取得した対象者の個々の名前です。
```.js
    // 対象者の名前のシートを探す
    var memberNamedSheet = THIS_SHEET.getSheetByName(memberName);
    // 作成されていない場合のみ作成する
    if(memberNamedSheet == null){
        // 作成処理
    }
```
getSheetByName(name)で、その名前のシートを取得できます。
ない場合はNULLが返ります。
https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet#getsheetbynamename
### 2-3 コピーされたシートを対象者の名前でリネームする。
templateSheet はテンプレートのシートでSheetオブジェクトです。

```.js
    // 「テンプレート のコピー」　を作成し、名前を変更する。
    templateSheet.copyTo(THIS_SHEET).setName(memberName);
```

copyTo(sSheet)でスプレッドシートをコピー先を指定してコピーできます。
名前が「[元の名前]のコピー」となるので、setNameで名前を変更しています。
https://developers.google.com/apps-script/reference/spreadsheet/sheet#copytospreadsheet
https://developers.google.com/apps-script/reference/spreadsheet/sheet#setnamename

## その他UI的なところ
### 実行するためのボタンをツールバーに追加
以下でスプレッドシートを開いた時にボタンを追加します。
addItemの第二引数は関数の名前を指定してあげればOKです。
```.js
    function onOpen() {
      var ui = SpreadsheetApp.getUi();
      var menu = ui.createMenu("シート作成");
      menu.addItem("シート作成実行","makeSheets");
      menu.addToUi();
    }
```
MySQL mariaDB ON UPDATE CURRENT_TIMESTAMP

# 概要

- カラム定義（属性）の一つである`ON UPDATE CURRENT_TIMESTAMP`についてまとめる

# 内容

- `ON UPDATE CURRENT_TIMESTAMP`は属性の一つである。
- この属性が付与されているカラムをNULLで更新しようとするとDBに設定されているタイムゾーンから現在時刻を取得して勝手に保存する。（DBのタイムゾーン設定がUTCなら多分UTCの現在時刻を取得してきて勝手に保存する。）
- カラムに`ON UPDATE CURRENT_TIMESTAMP`が付与されているか否かは下記のSQL句を実行することでExtra部分に表示される。

    ```sql
    show full columns from テーブル名;
    ```

    ![examinations-1st-year-end___laravel_-_MariaDB_10_9_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/467aad0d-d16e-b052-f6f0-b8d0a19a28e4.png)

# 参考文献

- [https://dev.mysql.com/doc/refman/8.0/ja/timestamp-initialization.html](https://dev.mysql.com/doc/refman/8.0/ja/timestamp-initialization.html)
- [https://dev.mysql.com/doc/refman/5.6/ja/time-zone-support.html](https://dev.mysql.com/doc/refman/5.6/ja/time-zone-support.html)
Fortigate VMトライアルライセンス永続化

昨日の脆弱性（CVE-2022-40684）を受けて、最新バージョンの7.2.2をダウンロードしEVE-NG上でデプロイした所、ライセンスを適用する旨の画面が。。。
15日トライアルライセンスは廃止？？となりましたが、翌々確認すると記事題名の通り、制限付きライセンスは永続化したようです。（これで15日の呪縛から解放されます！）

https://yurisk.info/2021/02/28/fortigate-vm-evaluation-license-15-days-limitations/

という事で、備忘録的に手順を記事にしていきます。

## 1. FortiCloudからダウンロード
こちらの記事を参考にどうぞ。
https://qiita.com/nw-engineer/items/82519ed8516aabc51893

## 2. デプロイ後の画面

評価ライセンス適用に伴い、Fortigateからインターネットへの直接接続（もしくはプロキシ経由）が必要になります。私の場合は、直接インターネットへ抜けれるよう設定をし、管理画面I/F(Port1)はDHCPでIPが取得（デフォルトの構成）しています。

以下、管理画面へのアクセスした際に表示される画面となります。
「Evalution Lisense」を選択し、FortiCloudに登録したEmailとPasswordを入力して、「OK」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/c50a55ae-ec0b-518a-9379-85185af94791.png)

再度確認が求められますので、「OK」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/d9eadb73-3b5b-a8e8-35dd-faf2698b4209.png)

評価license適用のため、Fortigateがリブートします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/e7624899-96f9-eca1-8086-8df3d1c1ea0b.png)

## 3. 管理画面に再度ログイン

ホスト名やシリアルなどはキャプチャから削除していますが、下記のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/e1351dd7-face-77a3-4ddc-3d7765d24be7.png)

画面右上ベルマークから「評価VMライセンス使用中」をクリックすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/105e96e2-0239-c684-84a5-46df8d93b40a.png)

画面が遷移し、ライセンスの有効期限がない（永続版）であることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/daaef453-53ee-01a8-ca45-defebde6578c.png)

7.0.7 と 7.2.2でのコマンド（diag debug vm-print-license）違いは下記の通りです。（左が7.0.7で右が7.2.2）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/60b00477-7ec2-5951-390c-fa82d5d0fd62.png)
7.0.7ではある「Evalution license expires」が7.2.2ではなくなっている事が分かります。

## 4. 10/16日追記
永続ライセンスは1 FortiCloudアカウントにつき1 licenseのようです。試しに2台目を設定したらライセンス適用できませんでした。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/4ac77464-aeeb-5076-ac49-86a63c87a467.png)

また、ライセンス適用後にFortiCloudのダッシュボードでは登録されている情報を確認する事が出来ます。画面右上のFortigateをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/3c82156e-7a82-3d91-b365-cf429c094c54.png)

登録されているシリアル番号（ForiGateの真下）が出てきますので、こちらをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/36f7989f-2678-529c-cb39-32abbd585f57.png)

licenseファイルのダウンロードや登録情報が確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/4464f6eb-6837-b5ba-71bb-aa5067c09c50.png)

もし誤って仮想ノードを削除してしまった場合は上記画面の「Decommission This Unit」をクリックして下記画面が出てきますので、チェックボックスにチェックを入れてContinueをクリックすると再度ライセンスを適用する事が出来るようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/75734ebe-dd82-8109-c8af-154e47d928e8.png)