OmniAICreator/Qiita-1.07M huggingface dataset:
jra公式データから3連複の払戻金の2010年から2021年の金額統計

```sql
SELECT
	min(N_HARAI.PaySanrenpukuPay1)*1,
	avg(N_HARAI.PaySanrenpukuPay1)*1,
	max(N_HARAI.PaySanrenpukuPay1)*1
FROM
	N_RACE
INNER JOIN
	N_HARAI
		ON
			N_HARAI.Year = N_RACE.Year
				AND
			N_HARAI.MonthDay = N_RACE.MonthDay
				AND
			N_HARAI.JyoCD = N_RACE.JyoCD
				AND
			N_HARAI.RaceNum = N_RACE.RaceNum
WHERE
	N_RACE.JyoCD IN("01", "02", "03", "04", "05", "06", "07", "08", "09", "10")
		AND
	N_RACE.Year IN("2010", "2011", "2012", "2013", "2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021")
		AND
	N_RACE.TorokuTosu = "18"
```
jra公式データから3連複の人気通りの2010年から2021年の確率統計

```sql
SELECT
	count(*)
FROM
	N_RACE
INNER JOIN
	N_UMA_RACE AS FIRST
		ON
			FIRST.Year = N_RACE.Year
				AND
			FIRST.MonthDay = N_RACE.MonthDay
				AND
			FIRST.JyoCD = N_RACE.JyoCD
				AND
			FIRST.RaceNum = N_RACE.RaceNum
				AND
			FIRST.KakuteiJyuni = "01"
INNER JOIN
	N_UMA_RACE AS SECOND
		ON
			SECOND.Year = N_RACE.Year
				AND
			SECOND.MonthDay = N_RACE.MonthDay
				AND
			SECOND.JyoCD = N_RACE.JyoCD
				AND
			SECOND.RaceNum = N_RACE.RaceNum
				AND
			SECOND.KakuteiJyuni = "02"
INNER JOIN
	N_UMA_RACE AS THIRD
		ON
			THIRD.Year = N_RACE.Year
				AND
			THIRD.MonthDay = N_RACE.MonthDay
				AND
			THIRD.JyoCD = N_RACE.JyoCD
				AND
			THIRD.RaceNum = N_RACE.RaceNum
				AND
			THIRD.KakuteiJyuni = "02"
WHERE
	N_RACE.JyoCD IN("01", "02", "03", "04", "05", "06", "07", "08", "09", "10")
		AND
	N_RACE.Year IN("2010", "2011", "2012", "2013", "2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021")
		AND
	N_RACE.TorokuTosu = "18"
		AND
	FIRST.Ninki IN("01", "02", "03")
		AND
	SECOND.Ninki IN("01", "02", "03")
		AND
	THIRD.Ninki IN("01", "02", "03")
```
WEB上のテキストを読むのに疲れた方々へ（クロームアドオンRead Aloudが良い感じ😉）

# はじめに
クロームアドオン大好きプログラミング初学者の[@kat_log](https://twitter.com/kat__log "Twitter")と申します。

WEBページのテキストの音声を読み上げる便利な方法を共有です。

## 使用例
Railsチュートリアルをテキスト版で勉強しているが読むのに疲れた…
でも進めなきゃ…！
というあなた（私）に最適です。

![eye_ganseihirou_computer_man.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455073/5b97586f-7c8b-75fd-4bef-9339995d518b.png)


# 結論
クロームアドオン**「Read Aloud: テキスト読み上げ音声リーダー」**
をインストールしましょう！！
（**読み上げ開始ショートカットキー登録**もやるとさらに便利！！）

# インストール

https://chrome.google.com/webstore/detail/read-aloud-a-text-to-spee/hdhinadidafjejdhmfkjgnolgimiaplp

# 読み上げスピードなどの設定
1. アイコン右クリック
1. 拡張機能を管理
1. 拡張機能のオプション
1. スピードやピッチ等調整できます！

![スクリーンショット 2021-12-29 103105.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455073/b96d0912-502b-fdab-0fca-a5e07766490a.png)


# ショートカットキー設定
1. 先程のスピード等調整ウィンドウの「ショートカットキーを編集する」
1. 一覧から「Read Aloud: テキスト読み上げ音声リーダー」を探す
1. 「play/pause」に任意のショートカットキーを設定！（私はReadのRでAlt+Rにしてます）

# 使い方
拡張機能のアイコンをクリックするとページの音声を読み上げてくれます！
※聞きたい部分だけをドラッグで選択状態→**右クリック「選択したテキストを読み上げる」**も便利です！
（※ページ全体も選択部分のみもショートカットキー使えます）

# おわりに
お読みいただきありがとうございました。
プログラミングに限らず勉強や情報集されてる方々の参考になれば嬉しいです。
Dynamodbでテーブルの変更をStreamに流して同一テーブルにアトミックカウンター使おうとしたら無限ループした

`テーブルA -> DynamoDBStream -> Lambda(アトミックカウンター) -> テーブルA書き込み`

の流れにした場合に、
テーブルA書き込みによってDynamoDBStreamが再度発火して無限ループに陥る。

DynamoDBStreamで発火する項目の指定ができれば対処可能に見えるが、調べた限りだと無い。

今回は書き込むテーブルを変更し、対処できた。

他にも
1. lambdaのポリシーでアトミックカウンターへの書き込み処理ではLambdaに読み込めないようにする。
2. lambdaの処理を変更し、アトミックカウンターへの書き込み処理ではDynamoDBに書き込まないようにする。

等考えられるが未確認。

---

[※] AWSサーバーレス系のループは料金的に致命傷になるので戒めで投稿
情報処理安全確保支援士試験　合格体験記

# はじめに
先日(2021/12/17)発表の情報処理安全確保支援士試験に合格しておりました。
春の応用情報に合格していたので、午前Ⅰ免除で受験できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539054/04107e32-bc52-4e8a-40ab-fd1f558bd6c2.png)

ざっくり試験対策としてやったことを書いていきます。

# 午前Ⅱの勉強法
午前は何はともあれ過去問道場です。
情報処理安全確保支援士の午前Ⅱ試験は問題数が２５問でサクサク１回分が終わるので、過去問道場に公開されている問題をすべて解きました。

情報処理試験に共通することですが午前の４択問題は過去問と全く同じ問題もたくさん出題されます。
過去問道場を繰り返し解いて「同じような問題ばっかりでてくるな」と思えるようになったら、午前試験で落ちることはまずなくなると思います。


# 午後Ⅰ・午後Ⅱの勉強法
午後対策の問題集として「情報処理安全確保支援士「専門知識+午後問題」の重点対策」を使用しました。

午前Ⅰの問題については、２回ずつ解きました。
１回目はほとんど解けないので、答えをすぐ見る。
２回目は自分の頭の中で解説しながら解く感じで時間を気にせず丁寧に解く。
という感じでやりました。

午後Ⅱの問題については、１つの問題に本番試験で２時間かけて解くボリュームです。
問題文を読んで、解答して、答え合わせをする気力が持たなかったので、
１回ずつ問題文と回答を読むという感じで終わってしまいました。

# Youtubeで勉強
今回の試験では、机で勉強する以外にYoutubeで試験対策の動画を見ていたことが大きかったと思います。
「まさるの勉強部屋」というYoutubeチャンネルで情報処理安全確保支援士の対策動画を公開してくださっていたので、それを活用しました。
勉強をする気が起きないときもとりあえずYoutubeを開いて動画を見ると勉強した気にはなれました。また、実際動画で全体像を把握できたことが合格に大きく貢献したと思います。

他にも勉強につかれてきたなと思ったら、情報処理安全確保支援士に合格された方の動画を見たりしてモチベーションを回復させたりしていました。

# 午後試験のコツ 登場人物のメモ
午後試験を解いていてまず思ったのが、
A社のBさん、C社のDさん、Eシステム・・・とたくさん登場人物（人以外も）が出てきて何が何だか分からなくなるということでした。
応用情報までと比べても問題文がはるかに長いのでなおさらです。

そこで、問題文を読みながら登場人物の属性を関係性を問題文の端っこにメモしていくことを思いつきました。
そのことで自分の頭の中で整理できるので問題文がスッと頭の中に入ってきましたし、Bさんってどんな立ち位置の人だっけ？と思ってもそのメモを見ればすぐ思い出せるようになります。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539054/925abac3-adf4-6bdf-48f7-ad7ca9c44962.png)
↑実際の試験中に書いたメモ
<br>
このメモは自分的には画期的でこれをしないと合格どころか問題文をすべて読み切ることもかなわなかったと思います。

# おわりに
これまで基本情報→応用情報→情報処理安全確保支援士試験と受験してきましたが
今回の支援士試験が一番楽だったと思います。
要因としては、
・試験範囲が限られること　
・SEとして業務経験を積んだことで自然と知識が増えたこと　
・Youtubeを活用して楽しく勉強できたこと
などがあると思います。

<br>
楽だったと言いましたが、初の高度資格（？）に合格できて大きな自身にもなりました。

・午前試験は過去問道場をやっていれば確実にクリアできる。
・午後試験は登場人物のメモを取りながら丁寧に問題文を読み解く。
上記の２つをやっていけば他の高度資格も取れる気がしてきます。
今後も高度資格に挑戦していきたいです。
Excelで行コピーしたテキストをC#で処理する

C#とWPFでポンチな業務アプリ作ってるんですが,「Excelで送られてきたデータを行でコピーしてセル毎に個別のテキストボックスに格納する」みたいな事をしています。

Excelで複数セルをコピーするとセル毎にタブ区切りされたテキストになるので、C#側で「str.Split('\t')」して一旦リストに格納するなりの処理をしているのですが、セル内で改行があったりすると当該セルの値だけダブルクォーテーションで括られっちゃうんですよね。
なので以下のような文字列としてクリップボードに格納されています。
（「↵」は改行、「→×」はタブとご理解ください）。

```
セル１→×セル２→×"改行されてる↵
セル３"……
```

それでまあタブ区切りの前に「str.Replace("\"", "")」でダブルクォーテーションを全部除去してからタブ区切りしていたんです。

これで数年何の問題もなく上手く行ってたのが、昨日になって「突然テキストボックスに格納される値がズレる」って事象が発生して、何事かとデータを調べたらエクセルのセルにタブが混じってる……

```
"セル１→×"→×セル２→×"改行されてる↵
セル３"……
```

上記のように先頭セルの末尾にタブ文字がくっついてました。Excelでタブキー押下したら普通セル移動やろがい！どうやってタブ文字突っ込んでんねん！（メモ帳からのコピペとかでうっかり出来ます）と元データ作った奴に怒りを覚えましたが、元データはいろんな人が作成しているのでそりゃまあおバカちゃんもおるやろ、と思い直してこっち側で対策することにしたのですが、これがなかなか難儀したので、今回の解決策を共有しておこうと思いました。

まあ糞コードなんですが……

当初は正規表現で「"」で括られてる間に含まれるタブ文字を見つけて除去すりゃいいだろうと高をくくったのですが、上記データの通り複数セルに改行やタブなどの制御文字が含まれている場合だと、セル１の終わりの「"」とセル３の始まりの「"」の間もヒットしちゃってセル間の区切りのタブも除去されちゃって駄目だったので、泥臭いコードを書いて解決しました。

```C#
//修正した文字列を格納する変数
string fixStr = "";

//「"」の数を数えるカウンタ
int counter = 0;

//半自動入力文字列を1文字ずつ分解したArrayをforeachする
foreach (char c in SemiAutoText_textBox.Text.ToCharArray())
{
	//cが「"」の場合、カウンタの値を+1する
	if (c == '"')
	{
		counter++;
	}

	//「"」が奇数番目の場合（始まりの「"」か、「"」で括られた「中」と評価する）
	if (counter % 2 != 0)
	{
		//三項演算子：cがタブの場合はfixStrの末尾に空文字を追加、タブ以外の場合はcを追加
		fixStr += c == '\t' ? "" : c.ToString();
	}
	//上記以外＝最初の「"」の前か、「"」が偶数番目の場合（終わりの「"」か、「"」で括られた「外」と評価する）
	else
	{
		//cをfixStrの末尾に追加
		fixStr += c.ToString();
	}
}

//ダブルクォーテーションを除去
fixStr = fixStr.Replace("\"", "");

//タブで区切ってListに変換する
List<string> excelCell = fixStr.Split('\t').ToList();
```

「"」の数を数えてカウンタに格納し、カウンタの値が奇数なら括りの頭の「"」か括りの内側だし、カウンタの値が偶数になってたら括りの終わりの「"」か括りの外側って評価してるのがアイデアと言えばアイデアかな……
Windows API AとWどちらがお得？

# Windows API とは
その名の通り、Windows上で動作するアプリケーションにとって、Windowsの各機能にアクセスするための接点(インターフェース)です。
pythonやJavaなどOS/プロセッサに影響されない上級言語からはあまり意識されませんが、C/C++では直接扱う事が少なくないです。

AとW結局どちらがお得かという話は[結論](#結論)まで飛んでください。
以下、小噺です。
# ばかめ、それは残像(マクロ)だ
以下はVisual Studio 2019で適当にWindows APIを使って見たものです。
![スクリーンショット 2021-12-29 085013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595099/0a0f42c9-f5e9-8e62-dca3-6f17f6322ede.png)
`GetTickCount64`と`CopyFile`は両方ともWindows APIっぽいですが、強調の色が違いますね。つまり、同じものではないということです。
それぞれの定義を見てみましょう。

```c:sysinfoapi.h
WINBASEAPI
ULONGLONG
WINAPI
GetTickCount64(
    VOID
    );
```
```c:WinBase.h
WINBASEAPI
BOOL
WINAPI
CopyFileA(
    _In_ LPCSTR lpExistingFileName,
    _In_ LPCSTR lpNewFileName,
    _In_ BOOL bFailIfExists
    );
WINBASEAPI
BOOL
WINAPI
CopyFileW(
    _In_ LPCWSTR lpExistingFileName,
    _In_ LPCWSTR lpNewFileName,
    _In_ BOOL bFailIfExists
    );
#ifdef UNICODE
#define CopyFile  CopyFileW
#else
#define CopyFile  CopyFileA
#endif // !UNICODE
```
ということで、`GetTicCount64`は純粋なWindows APIでしたが、`CopyFile`は`CopyFileW`または`CopyFileA`が割り当てられるマクロだったのです。

## 切り替わる仕組み
`UNICODE`が定義されているか否かでどちらが`CopyFile`となるかが決まります。
Visual Studioでは文字セットの項目からUnicode文字を選択すると`UNICODE`が定義されます。
![スクリーンショット 2021-12-29 094815.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595099/e4abcd64-4eea-d9dc-09ff-cfc22cd55152.png)
# AとWの違い
Aはマルチバイト文字を扱い、Wはユニコード文字を扱います。
`char`はサイズが1byteであり、`wchar_t`は2byteです。
`char`でも表現に2byteが必要な日本語などを扱う事はできますが、`鷗`外や川`﨑`と行った環境依存文字を扱う事ができません。
よって、日本でお仕事をするなら、Wを使用する事が求められます。
# 結論
「いやいや、日本語環境なんて扱うことなんてないですから。私はサイズもコンパクトなAの方が賢いと思います」という方がいるかもしれません。
しかし、私個人の意見ではWを使った方が良いと考えています。
その理由はA関数の中身にあります。
![スクリーンショット 2021-12-29 101033.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595099/72069a6b-a377-7559-6216-d81c0ed19d53.png)
上図は`CopyFileA`の中身です。(Windows10 20H2)
WindowsさんもWをスタンダードとしているようで、Aを呼ぶとUnicode変換を行った上で、`CopyFileW`に投げています。
よって、オーバーヘッドが発生してしまうため、初めからWの関数を使用する事をおススメします。
[Gradle]War作成時、含まれるapplication.propertiesを環境ごとに切り替える

## 環境
Java 11
Spring Boot 2.6.1
Gradle 2.24

## 環境ごとにapplication.propertiesを配置
`src/main`配下に、環境毎にresourcesディレクトリを作成し、application.propertiesを配置していきます
![スクリーンショット 2021-12-29 10.08.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539971/d1ec7c7e-a9e0-c4be-69f3-4d1cf6ec67e6.png)

## build.gradleにwar作成ロジックを記載
`srcDirs "src/main/resources_$env"`で環境変数毎に作成するresourcesディレクトリを指定します

Gradleは最初に`src/main/resources`ディレクトリをコピーするようなので、
↓を記載して、上書きするようにします
`duplicatesStrategy = DuplicatesStrategy.INCLUDE`

https://docs.gradle.org/7.3.1/dsl/org.gradle.api.tasks.Copy.html#org.gradle.api.tasks.Copy:duplicatesStrategy


```build.gradle
def env
if (project.hasProperty('env')) {
	env = project.env
}
sourceSets {
	main {
		java {
		}
		resources {
			if (env != null) {
				println "env build for $env"
				srcDirs "src/main/resources_$env"
			}
		}
	}
}
war {
	enabled = true
	archiveFileName = "sample-" + env + "-0.0.1-SNAPSHOT.war"
}

processResources {
	duplicatesStrategy = DuplicatesStrategy.INCLUDE
}
```

## 最後に
間違っている、気になる等ありましたら、優しく諭していただけるととても喜びます。
Google Cloud アップデート (12/23-12/29/2021)

### Anthos clusters on bare metal: [Dec 22, 2021](https://cloud.google.com/anthos/clusters/docs/bare-metal/latest/release-notes#December_22_2021)
- 1.9:
    - 1.9.3リリース！
        - Kubernetes 1.21
    - [CVE-2020-21913](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-21913)、クラスタ作成時やアップグレードじの不具合修正
    - [既知の問題の共有](https://cloud.google.com/anthos/clusters/docs/bare-metal/1.9/troubleshooting/known-issues)

### Eventarc: [Dec 22, 2021](https://cloud.google.com/eventarc/docs/release-notes#December_22_2021)
- Cloud Storageのバケット内のオブジェクト作成、削除、アーカイブ、メタデータ更新等をトリガにできるCloud Storage triggerがGAになったよ！

### Migrate for Anthos and GKE: [Dec 22, 2021](https://cloud.google.com/migrate/anthos/docs/release-notes#December_22_2021)

### Dataproc: [Dec 21, 2021](https://cloud.google.com/dataproc/docs/release-notes#December_21_2021)
- 1.3.95-debian10/-ubuntu18 イメージ追加
    - Log4j 2の[CVE-2021-44228](https://nvd.nist.gov/vuln/detail/CVE-2021-44228)と[CVE-2021-45046](https://nvd.nist.gov/vuln/detail/CVE-2021-45046)対応
        - 1.3のイメージはサポート外のままでアップグレードはされないので気をつけてね

### Anthos clusters on VMware: [Dec 22, 2021](https://cloud.google.com/anthos/clusters/docs/on-prem/1.9/release-notes#December_22_2021)
- 1.10.0-gke.194リリース！
    - Kubernetes 1.21.5-gke.1200
    - vCenter/ESXi host 6.7u2以下はサポート外なのでアップグレードしてね
    - kubernetes1.21でdeprecatedになったdiskformatがvSphereのStorageClassドライバから削除されたよ
    - Egress NAT gatewayがプレビューになったよ！
    - クラスタのライフサイクルや性能、セキュリティ、運用性の向上！
    - その他Kubernetesのバージョン更新に合わせて色々変更があるので、ドキュメント要確認

### Anthos clusters on VMware: [Dec 23, 2021](https://cloud.google.com/anthos/clusters/docs/on-prem/1.9/release-notes#December_23_2021)
- SeesawをNSX-Tのstateful distributed firewallsを利用している場合に1.9.0以上をデプロイするとstackdriver-operatorが失敗する可能性があるよ。
    - ワークアラウンドは[ここ](https://cloud.google.com/anthos/clusters/docs/on-prem/1.10/how-to/bundled-load-balance#configuring_stateless_nsx-t_distributed_firewall_policies_for_use_with_seesaw_load_balancer)確認

### Vertex AI: [Dec 23, 2021](https://cloud.google.com/vertex-ai/docs/release-notes#December_23_2021)
- 新しいFeed追加
    - [Vertex AIとVertex AI Workbench] (https://cloud.google.com/feeds/vertex-ai-product-group-release-notes.xml)
    - [Vertex AIだけ](https://cloud.google.com/feeds/vertex-ai-release-notes.xml)
    - [Vertex AI Workbenchだけ](https://cloud.google.com/feeds/aiplatformnotebooks-release-notes.xml)

### VMware Engine: [Dec 28, 2021](https://cloud.google.com/vmware-engine/docs/release-notes#December_28_2021)
- northamerica-northeast2, australia-southeast1-bで使えるようになったよ！

### ディスクレーマ
- アップデートの内容はあくまでも個人の理解していることを書いています。正しい内容はリリースノート等を確認下さい。
- リリース内容できるだけ拾うようにしているのですが、抜けていそうなリリースノートは追加するのでぜひ教えて下さい！(一覧[ここ](https://qiita.com/kenzkenz/items/ac18a359b803dbb6b490)で更新してます。)
【macOS】MySQLインストール方法と基本コマンドまとめ

# はじめに
MySQLのインストールに必要な手順と、基本コマンドを忘れないために本記事を書きました。
初めてMySQLをインストールする方の参考になれば幸いです。
本記事ではmacOSにてHomebrewがインストールされていることを前提としています。
下記リンクは前に私が書いたQiita記事のリンクです。よければ見てください。
[【Homebrew】インストール方法と便利なコマンドまとめ
](https://qiita.com/Utsubo/items/727af376146e9ba9418c)

# 環境
ハードウェア ：MacBook Pro(13インチ、2020年 Intelモデル)
OS：macOS Big Sur Version11.4
Shell：zsh

インストールしたMySQLバージョン：mysql  Ver 8.0.27 for macos11.6 on x86_64 (Homebrew)

# インストール方法
以下のコマンドをターミナル上で実行

```:zsh
brew install mysql
```

MySQLのバージョンを指定したい場合は以下のように記入します

```:zsh
brew install mysql@5.7
```

HomebrewでインストールできるMySQLのバージョンは下記Hombrewのサイトで確認できます。

https://formulae.brew.sh/formula/mysql



# MySQLの基本コマンド
## インストールしたMySQLのバージョン確認

```:zsh
mysql --version
```

## 起動

```:zsh
brew services start mysql
```

または

```:zsh
mysql.server start
```

これら2つのコマンドの違いとしては、
brew services start mysql：Mac再起動後に自動的に再起動する
mysql.server start：Mac再起動後に自動的に再起動しない
みたいです。ネット上で調べた際にどちらもよく使われていたので気になって調べました。

## ログイン

```:zsh
mysql --user=root --password
```

ルートユーザーとしてログインする。ログインすると下記のように表示されます。

```:zsh
mysql> 
```

## ログアウト

```:zsh
mysql> exit
```

上記のように入力すると、ログアウトしてシェル入力に戻ります。

## 停止

```:zsh
brew services stop mysql
```

または

```:zsh
mysql.server stop
```

## パスワード設定

```:zsh
mysql_secure_installation
```

詳しい内容は下記MySQLホームページで確認できます。

https://dev.mysql.com/doc/refman/8.0/en/mysql-secure-installation.html

# おわりに
不備やアドバイス、その他何かコメントがあればいただけると嬉しいです！

# 参考記事
以下の記事を参考にさせていただきました。

- [MySQLの開発環境を用意しよう（macOS）](https://prog-8.com/docs/mysql-env)
- [【Mac】HomebrewでMySQLをインストールする方法](https://chiritsumo-blog.com/mac-mysql-install/#toc8)
- [「brew services start mysql」と「mysql.server start」の違い](https://qiita.com/yamayamasou/items/3f54afad6448a3ddb652)
Fedora35 Silverblue に VMware Workstation を入れる

[Fedora Silverblue に VMWare Workstation を入れる](https://qiita.com/Mercury/items/fd81b3abbd8cd1507e90) では /usr を overlay fs にしてインストールした。

今回は overlay fs を嫌ってインストールしてみた。
rpm-ostree update を実行する度に下記手順が必要になる。

# 準備
```
# ostree admin status
* fedora d9f37bcdff5345c352b4d445b0b229d26aa2a0b1d57f95bdb51505a757696671.0
    Version: 35.20211222.0
    origin: <unknown origin type>
  fedora 10bdab04c794f9707e52417622d0f23a6c96acfce5eec597c5f51e475c08d369.0 (rollback)
    Version: 35.20211216.0
    origin: <unknown origin type>
# NUM=d9f37bcdff5345c352b4d445b0b229d26aa2a0b1d57f95bdb51505a757696671.0
```
ostree admin status を実行してパスを調べる。
それを NUM に代入しておく。

# 手順(VMware のインストールから実行する場合)
1. `mkdir -p /usr/local/lib/modules/$(uname -r)/misc`
1. `ln -s /usr/local/lib/modules/$(uname -r)/misc /ostree/deploy/fedora/deploy/${NUM}/lib/modules/$(uname -r)`
1. `ostree admin unlock`
1. `<VMware インストーラー .bundle> -I --custom`
1. `rsync -HaxvSuR /var/tmp/ostree-unlock-ovl*/upper/./{lib/modules,share}/ /ostree/deploy/fedora/deploy/${NUM}/usr/`
1. `reboot`

:::note info
VMware は、 /usr/local にインストールする
:::

# 手順(インストール済み VMware の module だけ rebuild する場合)
1. `mkdir -p /usr/local/lib/modules/$(uname -r)/misc`
1. `ln -s /usr/local/lib/modules/$(uname -r)/misc /ostree/deploy/fedora/deploy/${NUM}/lib/modules/$(uname -r)`
1. `ostree admin unlock`
1. `vmware-modconfig --install-all --console`
1. `rsync -HaxvSu /var/tmp/ostree-unlock-ovl*/upper/lib/modules/ /ostree/deploy/fedora/deploy/${NUM}/usr/lib/modules/`
1. `reboot`

:::note info
- 必要に応じ、 vmware-netcfg を実行する。
- 2022-03-07 時点では、vmware-modconfig でヘッダー stdarg.h 等が見つからないエラーが出る。この場合は次のようにする。[参考](https://communities.vmware.com/t5/VMware-Workstation-Pro/Compiling-vmmon-module-fails-on-linux-kernel-5-16-0-arch1-1/m-p/2892330/highlight/true# "vmware Communities")
```CPATH=/usr/src/kernels/$(uname -r)/include/linux vmware-modconfig --install-all --console```
:::
URI（URL）について

# 概要

- 「Webを支える技術」に記載されていたURIの記載をまとめておく

# URIって？

- URLとほぼ同意味の言葉
    - 正確に言うとURIはURLとURNの総称
- ネットの海に存在するリソース（ページや情報）を一意に特定するための識別子のこと

# URIのルール

- URI側の文字数制限は無いけどIEでは2038バイトまでという制限がある。
- 使用できる文字はいわゆるASCII文字である（正規表現でURIを判定したいときに使えるのでちょっと覚えておくといいかも）
    - アルファベット: A~Z と a~z
    - 数字: 0~9
    - 記号: 「-」「.」「~」「:」「@」「!」「$」「&」「'」「(」「)」
- 直接日本語は使えない。使いたいなら「%エンコード」する必要がある。
- 絶対パスと相対パスが使える。
    - 我々がいつも見ているURIは絶対パスのURIである。
    - 相対パスはlinuxのディレクトリ移動とか、ファイルコピーとかに使うやつ。`$ cd ../etc`みたいに基準となる場所からのパスでリソースを特定するやつ。
    - 相対パスを使えることは知っておいていいけど、そんなに使うことは多くなさそうだった。

# URIの構造

- 多分一番シンプルなURIの構造は下記になる。（URIスキームとホスト名の間にある`://`は`:`と`//`でそれぞれ意味を持っているらしい。`:`はURIスキームの後ろの区切り文字で`//`はユーザー情報とホスト情報の開始を宣言しているっぽい。）

    ```
    URIスキーム://ドメインもしくはIPアドレス（ホスト名）/パス
    ```

- [https://qiita.com/miriwo](https://qiita.com/miriwo)で説明すると下記の様になる。

    |　項目　|　情報　|　備考　|
    | --- | --- | --- |
    | URIスキーム | https | 通信に使うプロトコルの指定 |
    | ドメインもしくはIPアドレス（ホスト名） | qiita.com | ドメインの場合、DSNサーバーでIPとドメイン名が紐付けられているっぽい |
    | パス | /miriwo | 当該のホストのなかでのリソースの場所 |

- その他にもポート番号や、クエリパラメータとかがURIに記載されていることもある。

# あとがき

- 最近のWeb系フレームワークはめっちゃ優秀だからこの辺深くまで理解しなくても開発はできる。
- しかし、しっかり理解することもこれまた大切だなと思った。
- この記事の内容ですら暗記する必要は無いと思うが、「あーなんかURIはこんな感じだったな〜」っておもっておこう。

# 参考文献

- [https://gihyo.jp/book/2010/978-4-7741-4204-3](https://gihyo.jp/book/2010/978-4-7741-4204-3)
AtCoder Beginner Contest 012をやった(Java)

AtCoder Beginner Contest 012をやった。

D問題もパッと見た感じ解けそうな気がするので、明日以降に挑戦したく。
※D問題追記予定

##[A](https://atcoder.jp/contests/abc012/tasks/abc012_1)
入力された二つの値を入れ替える問題

```Java
import java.util.*;
 
public class Main {
    public static void main(String[] args) throws Exception {
        Scanner scan = new Scanner(System.in);
        int A = scan.nextInt();
        int B = scan.nextInt();
        
        if(A == B){
            System.out.println(A + " " + B);
        } else {
            System.out.println(B + " " + A);
        }
    }
}
```

##[B](https://atcoder.jp/contests/abc012/tasks/abc012_2)
時間を秒数に変換する典型的な問題
秒数を与えて適当に変換してくれる時間関数が見つからなかったので、自分で実装

```Java
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        
        String hour = String.format("%02d", N / 3600);
        String minute = String.format("%02d", N % 3600 / 60);
        String second = String.format("%02d", N % 3600 % 60);
        
        System.out.println(hour.concat(":").concat(minute).concat(":").concat(second));
    }
}
```

##[C](https://atcoder.jp/contests/abc012/tasks/abc012_3)
九九の合計値から、入力分の差分+1を取って、それの該当する九九の範囲内の計算式を求める問題
結構きれいにかけた。

```Java
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        
        N = 2025 - N;
        for(int i = 1; i < 10; i++){
            if(N % i == 0 && N / i < 10){
                System.out.println(i + " x " + N/i);
            }
        }
    }
}
```
AmazonのSDKでASINからJANを取得する方法

ASINからJANは取得できないかと思っていたが、どうやらできる模様


```
amazon-php-sdk/src/com/amazon/paapi5/v1/GetItemsResource.php
```

の49行目にある

```php
const ITEM_INFOEXTERNAL_IDS = 'ItemInfo.ExternalIds';
```

が外部のIDを取得するResourceのようだ

$resourcesにITEM_INFOEXTERNAL_IDSを追加して

```php
$resources = [
GetItemsResource::ITEM_INFOTITLE,
GetItemsResource::ITEM_INFOEXTERNAL_IDS];
```

のように（どこでも良いが一番下に追加）する

リクエストした結果から

```php
$jan = $item->getItemInfo()->getexternalIds()->geteANs()->getdisplayValues()[0];
```

JANを取得できました

めでたしめでたし
[Swift]Text Fieldに文字が入力できない時の対処法

#概要
Swift(Storyboard)を使ってTextFieldを配置したのに、文字が入力できなくて困った時は予想される原因がいくつかあると思います。
#本文
##スマフォ用のキーボードが表示されているけれどmac側キーボードからの入力ができない時
Swiftでアプリを実行した後、iPhoneシミュレータ機が表示された状態で画面上側のメニューから「I/O」→「Keyboard」→「Connect Hardware Keyboard」にチェックをつけてください
![スクリーンショット 2021-12-29 6.59.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/39f5eaeb-8b27-9891-2276-fc619d249870.png)
##入力されているけれど文字が見えていない
SwiftのStoryboard上のTextFieldを選択状態にして右側のユーティリティエリアで設定を確認します。
・ Fontの数値が小さすぎて文字が見えなくなっていないか？もしくは大きすぎないか？
・ ColorがBackgroundの色と同じで同化していないか？
・ TextFieldのサイズ自体が小さすぎないか？
![スクリーンショット 2021-12-29 6.57.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/9a4ed969-ae65-bb2c-3774-1a23182791fb.png)
##それでも解決しない時は
Swiftでアプリを実行した後iPhoneシミュレータ機が表示された状態で画面上側のメニューから「Device」→「Erase All Content and Settings...」を選ぶとシミュレータ機の設定がリセットされて解決する事があります。
![スクリーンショット 2021-12-29 6.58.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/6fdd5981-7700-1479-e6ad-cc47dee1c2c5.png)
最新版Log4j 2.17.1ではCVE-2021-44832のリモートコード実行が修正されています

本記事は2021年12月28日（米国時間）に公開した英語ブログ[New Log4j 2.17.1 fixes CVE-2021-44832 remote code execution but it’s not as bad as it sounds](https://snyk.io/blog/new-log4j-2-17-1-fixes-cve-2021-44832-remote-code-execution-but-its-not-as-bad-as-it-sounds/)の日本語版です。

![logo-solid-background.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2216557/74e6f228-71a2-b5d1-5821-c3ddf906f55c.png)

[事前の予測通り](https://snyk.io/blog/log4j-2-16-vulnerability-cve-2021-45105-discovered/)、2021年12月28日19時35分頃（GTM/グリニッジ標準時）、ロギングライブラリLog4jに影響を与える別のセキュリティ脆弱性が[CVE-2021-44832](https://security.snyk.io/vuln/SNYK-JAVA-ORGAPACHELOGGINGLOG4J-2327339)として公表されました。

この新しいセキュリティ脆弱性 CVE-2021-44832 は、これまで修正されたと考えられていた 2.17.0 までのバージョンに影響します。この脆弱性は、Log4j の 1.x ブランチに影響を与えた [CVE-2021-4104](https://security.snyk.io/vuln/SNYK-JAVA-LOG4J-2316893) と性質が似ています。

#CVE-2021-44832の影響

もし、Log4jの最新の修正バージョンに速やかにアップグレードできるのであれば、そうすべきです。とはいえ、この特定の CVE-2021-44832 脆弱性は、CVSS スコアが中程度の 6.6 であり、攻撃者が悪用するためにはかなり高い事前条件を必要とすることを指摘しておきたいと思います。

[CVE-2021-44832](https://security.snyk.io/vuln/SNYK-JAVA-ORGAPACHELOGGINGLOG4J-2327339)は、Log4j 2.17.0 (およびそれ以前のバージョン) に、攻撃者がロギング設定ファイルの内容を制御、変更し、リモート URI データソースを指して、任意の Java コードをロードできる場合、コード実行の脆弱性があると判断されます。

2.17.1 での修正と JVM 互換の旧バージョンへのバックポートのいずれも、設定ファイルの JNDI データソースが Java プロトコルのみを使用するように制限され、リモートネットワーク呼び出しが行われないようになり、この脆弱性が軽減されました。

#CVE-2021-44832を修正するために直ちに行うべき手順

Log4j チームは、このセキュリティ脆弱性に対する修正プログラムを公開しました。

* Java 8 以降をお使いの場合は、**Log4j 2.17.1 にアップグレードしてください**
* Java 7 用の 2.12.x ブランチを使用している場合、**Log4j 2.12.4 にアップグレードしてください**
* Java 6 用の 2.3.x ブランチを使用している場合、**Log4j 2.3.2 にアップグレードしてください**


#早々に流出した一連のLog4j脆弱性

今回の脆弱性の公開は、ますます憂慮すべきLog4jにおける無責任な公開の傾向の影響を受けたもので、メンテナンスをする人たちがが適切に問題を修正して新しいリリースを公開する前に、セキュリティ研究者が公開した脆弱性の詳細を漏らしてしまいました。

この問題は、最初の Log4j [RCE](https://security.snyk.io/vuln/SNYK-JAVA-ORGAPACHELOGGINGLOG4J-2314720) から始まっており、研究者は、公式公開の数時間前に、Twitter や GitHub で脆弱性の詳細や概念実証までリークしました（[タイムライン](https://snyk.io/blog/log4j-2-15-vulnerability-cve-2021-45046-critical-ace/)を参照）。今回も、公式発表の数時間前に、この脆弱性を発見したと主張するセキュリティ研究者によって、その存在が[Twitterでリーク](https://twitter.com/YNizry/status/1475764153373573120)されました。

どちらのケースでも、情報の漏洩は、おそらく悪意はないものの、Apacheのためにリリースを急がせることにつながったようです（新しいリリースにさらなる脆弱性やバグがある可能性を残すことになります）。さらにこの特定の例では、多くの組織が長期休暇を取るために、必要でも問題を迅速にトリアージして修正することができない時期にあたるため、選択肢があれば、Apacheはリリースを急ぐことを選ばなかっただろうと推測されます。

[オープンソースのセキュリティは、世界全体にとってますます重要になってきており](https://snyk.io/blog/responding-to-open-source-criticism-post-log4shell/)、[責任ある情報開示の実践](https://snyk.io/blog/responsible-disclosure/)は、私たちのコミュニティが継続的にセキュリティを確保するための基礎となります。私たちは、Log4jやその他のオープンソースパッケージにおける将来の情報開示が、今後より安全に処理されることを望んでいます。

弊社Snykは、[今後も責任ある情報開示に努めるとともに](https://snyk.io/blog/vulnerability-disclosure-program/)、新たな脅威の発生に注意を払い、ユーザーやオープンソース・コミュニティ全体に向けて、対応に役立つ情報を迅速に提供していきます。

#最後に
Snykでは日本語の公式[Twitter](https://twitter.com/snykjp)と[Facebookページ](https://www.facebook.com/snykJP/)を開設しました。ぜひフォローをして最新情報をご確認ください。

* [Snyk Japan Twitter](https://twitter.com/snykjp)
* [Snyk Japan Facebook](https://www.facebook.com/snykJP/)
イベントソースとは？

# イベントソースとは？
イベントの発生元となるAWSリソースのことをイベントソースと呼びます。
イベントソースの違いによってファンクション起動時の挙動が変わります。

Pushモデル
イベント発生に応じて直接Lambdaファンクションを起動します。
API Gate WayやAmazon S3など

Pullモデル
AWS Lambdaに対して直接的にイベント発行を行わないようなサービスもあり、その場合はAWS Lambdaがそれらへポーリングを行い自らイベントを取得します。
Amazon DynamoDBとAmazon Kinesis　など

# イベントソースを確認する
AWS Lambdaのダッシュボートから「Functions」をクリックします。
![スクリーンショット 2021-12-29 6.52.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/dc960612-b8c6-c555-56b8-46b1234f8239.png)

任意のFunctionをクリックします。
![スクリーンショット 2021-12-29 6.52.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/41825996-7f7c-c621-6dfb-83097b6ce3f6.png)

「Test」タブをクリックし、「New Event」を選びます。
Templateで、「API Gateway AWS Proxy」を選びます。
![スクリーンショット 2021-12-29 6.53.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/787a002a-69d1-339d-59f8-2ef6a562914d.png)

Eventの内容が表示されます。
![スクリーンショット 2021-12-29 6.55.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/15d4645c-2f42-12f8-c112-eee85a7d539c.png)
JavaScriptのIIFEを使うユースケース


PRにてIIFEを使ったコードがあり、「普通の関数を使いましょうか」と指摘したところ。どういうケースで使うべきかの質問がきたのでメモしておきます。

## IIFEとは

Immediately Invoked Function Expressionの略称。雑に日本語にすると、即時に呼び出される関数式。


```tsx
// case: general function
(function () {
  statements
})();

// case: arrow function 
(() => {
  statements
})();
```

REF: https://developer.mozilla.org/en-US/docs/Glossary/IIFE

## ユースケース


### グローバル領域を汚したくないケース

例えば、bootstrap的に初回ロードしたいだけどの関数を実行するとき。

```tsx
(function(){
   preparetion();
   bootstrap();
   // ...
}();
```

### 非同期処理を即時実行したいとき

コールバックの中などでこういうケースに遭遇します。例えば、ReactのuseEffectとかですね。

```tsx
React.useEffect(() => {
  (async function(){
    const result1 = await asyncFunc1();
    const result2 = await asyncFunc2(result1);
    ...  
  })();
}, []()
```

### 擬似的なブロックの代入をしたいとき

擬似的なブロックの代入はこのような感じで書けます。ただ、後述しますがIIFEよりも専用の関数を作るほうが大抵の場合はベターです。



```tsx
// 擬似的なブロック代入
const item = (function() {
  let item = fetcheItem();
  item.isActive = true;
  const serialized = serialize(item);
  return serialized;
})();
```

JavaScriptではこんな感じのブロックの結果を代入できなくて代わりに上のようなIIFEで実現できます。

```tsx
// JS ではブロックの代入ができない
const item = {
  const item = fetcheItem();
  item.isActive = true;
  const serialized = serialize(item);
  return serialized;
}; // エラー
```

このようにリファクタをしたいと思う動機は、条件分岐が多いときケースやmutableにパラメータを変更する場合にスコープ範囲を狭められるので有効です。



### 具体例）条件分岐

```tsx
// 条件が多いケースを愚直にlet使ってJS的に書く
let item;
if(isActive) {
  item = fetchedByCondition1();
} else if (isLogin) {
  item = fetchByCondition2();
} else {
  item = {}
}

// IIFEで書き直し
const item = (function() {
  if (isActive) return fetchedByCondition1();
  if (isLogin) return fetchByCondition2();
  return {};
}()

// 普通に関数で書く
const fetchItem = ({isActive, isLogin}) => {
  if (isActive) return fetchedByCondition1();
  if (isLogin) return fetchByCondition2();
  return {};
}
const item = fetchItem({isActive, isLogin});
```

このケースの場合はたいていIIFEにしないで普通に関数化したほうがいいですね。

### 具体例）mutable/immutableのスコープ管理

```tsx
// mutableなスコープを限定して、グローバルではimmutable化する

// JS的に書くとitemがmutableになる
let item = fetchItem();
item.isActive = true;
item.belongsTo = user;
...

// IIFEでmutableなスコープを限定して、immutable化する
const item = (function(){
  let item = fetchItem();
  item.isActive = true;
  item.belongsTo = user;
  return item;
})()
...
```

これでmutableなスコープを限定しつつimmutableなconstを使うような明示的なコードになりますた。ですが、実際はJavaScriptの場合はconstで定義してもオブジェクトのパラメータは変更可能なので実際は厳格なimmutableではないです。

Swiftなどでは、こういった書き方をすれば完全にmutable/immutableを分離できるのですがJSの場合はあくまで「そのように見せられることができる」くらいです。

とはいえ、個人的にはmutable/immutableの範囲を明示化するほうが好きなのでたまにこういう書き方をします。

### おわりに

正直、大抵の場合はIIFEを使うメリットが薄いのでかなりのエッジケースのときだけ使ってます。
今持っている除菌グッズは信用できる？アルコール消毒の原理

#導入
アルコールを手に塗ると消毒できた気がします。消毒の原理を学んで、今持っている消毒・除菌グッズの効果を想像してみてください。

#ウイルスって？
ウイルスとは生物の一種です。

#生物は環境が大事
生物ということは生きるための環境が必要です。人間であれば、酸素や適温が必要です。水の中で生きていられないですし、炎の中でも生きていられないです。

#ウイルスの生きる条件は？
ウイルスが生きるため条件は、生物の中です。生物の中に入れずにマスクなどについたウイルスは、24時間程度で死んでしまいます。適度の水分と適度な気温と空気が必要です。生物の中でない環境であれば、自然に消えていきます。生物の中でないとは、温度が100度を超える環境や、高濃度なアルコールの中です。

#ウイルスの成分はアルコールが苦手
ウイルスはタンパク質というものの塊なので、高温の場合はウイルスの形をたもっていられなくなります。高濃度アルコールの中ではタンパク質がアルコールの中に溶けて塊の形をたもてないです。

#アルコールが苦手な理由
アルコールに溶ける原理を話します。世界には水にとけるものと水に溶けないものの2種類しかありません。マジックペンは水にとけるものと水に溶けないモノがあります。水性と油性のことです。水性とは水に混ざります。手についたマジックが水性であれば水道で手をこすると水に混ざっていって洗い流されます。油性であれば水道で手をこすっても水に溶けないので、こする力で少し削られる程度です。石けんなどの洗剤は油性と水性を混ぜる性能があります。石けんを使って油性マジックをこすると、水に溶け出して洗い流されます。
中学校では、親水性、疎水性という単語で習います。

#実はアルコールも石けんも同じ
洗剤と同じ役割なものがアルコールです。石けんで手洗いすることもアルコールで手洗いすることはウイルスを溶かす点では同じです。違いは洗った後です。石けんは洗い流すと思いますが、そのときに水と一緒にウイルスが流れます。アルコールは洗った後洗い流さないですが、蒸発します。蒸発と一緒にウイルスの機能を持たないタンパク質も一緒に空気中に流れます。

#結論
アルコールまたは石けんでウイルス消毒はできます。
あなたが今持っている除菌や抗ウイルスと書いてあるグッズの意味を調べてみましょう
polars dfの重複するindexの削除

# pandas

```python
df = df[~df.index.duplicated()]
```

# polars

polarsのdfにはインデックスが無いので、指定したカラムを対象に重複する行の削除を行う

```python
df = pl.DataFrame(
    {
        "hoge": [1, 2, 2],
        "bar": [6, 7, 8],
        "ham": ["a", "b", "c"],
    }
)
df = df.drop_duplicates(subset="hoge")
```
今後のプログラム更新(gitコマンド)

次回からこれで定型化

```terminal
(myenv) ユーザー名-no-MacBook-Pro:hoge1 ユーザー名$ heroku login
(myenv) ユーザー名-no-MacBook-Pro:hoge1 ユーザー名$ git add .
(myenv) ユーザー名-no-MacBook-Pro:hoge1 ユーザー名$ git commit -m "hoge2"
(myenv) ユーザー名-no-MacBook-Pro:hoge1 ユーザー名$ git push origin master 
```
herokuでアプリセッティング　エラー修正


Invalid HTTP_HOST header: 'hoge.herokuapp.com'. You may need to add 'hoge.herokuapp.com' to ALLOWED_HOSTS.


ALLOWED_HOSTS = ['*']

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    '任意のページ名',
]

'DIRS': [BASE_DIR, 'templates'],
【IoT検定 受けてみた】 〜プロフェッショナル コーディネータ編〜

## 背景
「IoT検定パワーユーザー」を受験したので、こちらも受験しました。
本試験もパワーユーザーと同じように会社のプログラムで受験しました。

パワーユーザー編は以下にまとめています。
[IoT検定受けてみた 〜パワー・ユーザー編〜](https://qiita.com/MONSOON/items/d603f5b7c9e517cb665c)

## 結果
総合評価点(100%)：74%
合否（60％以上の正解で合格）：合格
## 本試験について
本試験は「IoT検定パワーユーザー」のグレード判定と異なり、合否判定となっています。
試験の中身は以下のとおりです。

　　|内容　　|
---|---|---
正式名称|IoT検定レベル１試験プロフェッショナル・コーディネータ|
試験方法|CBT　四肢択一|
試験時間	|60分|
出題総数	|70問（8分野から出題)|
評価方法	|合否（60％以上の正解で合格）　　|
認定方法|合格者にはプロフェッショナル・コーディネータ認定証を発行|
開催時期	|通年受験可能|
受験料金|11,000円(10%消費税込)|

## 勉強方法
下記の公式参考書で4日間、1日3時間ほど勉強しました。

[問題を解いて実力をチェック IoTの問題集](https://www.amazon.co.jp/%E5%95%8F%E9%A1%8C%E3%82%92%E8%A7%A3%E3%81%84%E3%81%A6%E5%AE%9F%E5%8A%9B%E3%82%92%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF-IoT%E3%81%AE%E5%95%8F%E9%A1%8C%E9%9B%86-%E4%BC%8A%E6%9C%AC-%E8%B2%B4%E5%A3%AB/dp/4822256154/ref=as_li_ss_tl?ie=UTF8&qid=1527906475&sr=8-1&keywords=IoT%E3%80%80%E5%95%8F%E9%A1%8C%E9%9B%86&linkCode=sl1&tag=iotcert-22&linkId=92e4b1001ff0aecee8a4e4303c4baaa3)
[IoTの全てを網羅した決定版 IoTの教科書](https://www.amazon.co.jp/dp/4822259471/ref=as_li_ss_tl?ie=UTF8&linkCode=sl1&tag=iotcert-22&linkId=e234a59828fe28b6d5811ea81e5c2ec2)

勉強は以下の感じで進めました。
1.「IoTの問題集」を一通り解く/問題集の解説を一通り見る
2. 覚える項目が多くて焦る
3. 解説を見てもよく分からない分野を「IoTの教科書」で再度学習する
4. それでも分からない部分はネットでひたすら検索して学習する
5. 1~4を何度も繰り返す

「IoTの問題集」と「IoTの教科書」は公式の参考書というだけあって、完全に内容がリンクしてます。
そのため学習しやすかったです。ただ「IoTの教科書」は単語帳の色が強く、内容としては分かりにくい部分もありました。
## 受験してみて思ったこと

* 問題集に出てくる問題は95%以上は出題されない。（体感）
    * 問題集の問題は本として露出しているので試験にはほぼ出ないです。むしろその周りが出ます。
    * 仮に問題集だけ１００％解ける状態で試験に臨むとあれっ？てなると思います。
    * 何となく似てる問題は出ます。ただ似てない問題の方が体感多かった気がします。
* 問題の回答以外の選択肢/解説部分/問題部分に同じ粒度で置換可能な周辺内容を学習した方が効率的
    * 例えば、誤った文章を選ぶ四択問題には正しい文章が3つあるのでこっちを覚えるとかです。
* 違和感を感じる日本語の出題文がいくつかある。
    * 運転免許試験を思い出す出題文でした。
* 結果の詳細が見れないため、何を間違えたのかよく分からない。
    * 各セッションごとの正答率のみフィードバックされるため、一問一問の正否が分かりません。
 


## 最後に
「IoT検定パワーユーザー」と同じように、こちらも大変勉強になりました。
ただし文章で理解して試験に臨む戦法は、このレベルが個人的に限界だと感じました。
今回はたまたま仕事でバックエンド側のAPI開発や、ラズパイを使った重量センサー検証などをやっていたため、なんとかなった感があります。その経験がなかったらいくら時間をかけても、全然頭に入ってこなかったと思います。

IoT検定にはこれより上の検定が2つあるそうです。それは機会があってもひとまずパスしたいと思います。
自分のレベルが追いついていないからです。 
※ 上位2つの試験は2021年12月の時点ではまだ公開されていません。

今後は学んだことを実践の場で経験して、試験で得た知識を血が通ったものにしていきたいです。
なお、他の試験は引き続き積極的に受験していきたいです!!
Google SpreadSheetのデータを`curl`コマンドで取得する

Google SpreadSheetのデータを`curl`コマンドで取得するための備忘メモ

## １．Google SpreadSheetにアクセスできるようにしておく

2021/12/28時点では、スプレッドシートID、シート名、APIキーが必要らしい。
以下を参照して、Google SpreadSheetにアクセスできるようにしておく


> [【最新版】Google SpreadSheetのデータをJSONで取得する手順](https://macoblog.com/google-spreadsheet-json/#h-anker11)
> `https://sheets.googleapis.com/v4/spreadsheets/｛スプレッドシートID｝/values/｛シート名｝?key=｛APIキー｝`
>
> ③：専用URLにアクセスする
> JSON取得URL【テンプレート】

事前に、[https://docs.google.com/forms/u/0/](https://docs.google.com/forms/u/0/)から`google form（質問と回答）`とスプレッドシートを作成しておくとよい

## ２．コマンドラインから取得できるようにする

１．を設定した後、以下を実行すればOK

```
curl https://sheets.googleapis.com/v4/spreadsheets/｛スプレッドシートID｝/values/｛シート名｝?key=｛APIキー｝ -o result.json
```

### `400(Bad Request)`エラーが返る

入力パラメータである、スプレッドシートID、シート名、APIキーが間違っている可能性がある。
（自分の場合はシート名が間違っていた）

```json
{
  "error": {
    "code": 400,
    "message": "Unable to parse range: sheet",
    "status": "INVALID_ARGUMENT"
  }
}
```

### `404 not found`エラーが返る

URLがそもそも間違っているので、１から見直しが必要。

# 参考
[【最新版】Google SpreadSheetのデータをJSONで取得する手順](https://macoblog.com/google-spreadsheet-json/#h-anker11)
[https://docs.google.com/forms/u/0/](https://docs.google.com/forms/u/0/)
[gsutil をインストールする](https://cloud.google.com/storage/docs/gsutil_install?hl=ja#deb)
[Google Formsの回答データをスプレッドシートからダウンロード](https://blanche-toile.com/tools/google-forms-download)
[Google spreadsheetの値を取得する](https://qiita.com/suisuina/items/a41932088acacea4835e)
【Azure Storage】ブラウザから Blob を表示する方法

Azure Blob Storage では、ストレージアカウントに格納したデータにアクセスする際に、既定で認証が必要です。
そのため、Blob URL をそのままブラウザに入力してアクセスしただけでは、認証エラーで弾かれてしまいます。

Azure Blob Storage の認証方法は、下記が用意されています。
・アカウント アクセス キー 認証
・Azure AD 認証

https://docs.microsoft.com/ja-jp/azure/storage/blobs/authorize-data-operations-portal#permissions-needed-to-access-blob-data

>
◆アカウント アクセス キーを使用する
アカウント アクセス キーを使用して BLOB データにアクセスするには、Azure RBAC アクション Microsoft.Storage/storageAccounts/listkeys/action を含む Azure ロールが割り当てられている必要があります。 この Azure ロールは、組み込みロールまたはカスタム ロールのどちらでも構いません。 Microsoft.Storage/storageAccounts/listkeys/action をサポートする組み込みロールには、権限が最小のものから最大のものの順に、次のものが含まれます。
・閲覧者とデータ アクセス ロール
・Storage Account の共同作成者ロール
・Azure Resource Manager の共同作成者ロール
・Azure Resource Manager の所有者ロール
>
◆自分の Azure AD アカウントを使用する
Azure AD アカウントを使用して、Azure portal から BLOB データにアクセスするには、次のステートメントが両方とも自分に当てはまる必要があります。
・BLOB データへのアクセスを提供する組み込みロールまたはカスタム ロールのいずれかが割り当てられている。
・Azure Resource Manager のリーダーロールが、少なくとも、ストレージ アカウント以上のレベルを範囲として割り当てられている。 リーダー役割は最も制限の厳しいアクセス許可を付与しますが、ストレージ アカウントの管理リソースへのアクセス権を付与する別の Azure Resource Manager ロールも受け入れることができます。


今回は、Azure AD 認証を利用します。
しかし、Azure Blob Storage 単体で、ブラウザからのアクセス時に Azure AD 認証を行う機能がないため、Azure AD 認証を行いたい場合は、あらかじめ発行した SAS を利用することを考えました。

https://docs.microsoft.com/ja-jp/azure/storage/common/storage-sas-overview

>
◆ Shared Access Signatures (SAS) を使用して Azure Storage リソースへの制限付きアクセスを許可する
Shared Access Signature (SAS) を使用すると、ストレージ アカウント内のリソースへのセキュリティで保護された委任アクセスが可能になります。 SAS を使用すると、クライアントがデータにアクセスする方法をきめ細かく制御できます。 次に例を示します。
>
クライアントがアクセスできるリソース。
それらのリソースに対するアクセス許可。
SAS が有効である期間。


発行した SAS を Blob URL に付け加えることで、ブラウザからアクセスした際に、SAS を利用して要求が承認されます。

```
<Blob URL 例>
https://<mystorageaccount>.blob.core.windows.net/<myContainer>/sampleblob.txt?sp=racwdli&st=2021-01-01T01:00:00Z&se=2021-01-02T00:00:00Z&spr=https&sv=2020-08-04&sr=c&sig=S5b3mQ8FwAHbBmBhIGRjiejKwu658N%2MHri7%2Fa9yC9LE%3D
```

SAS の取り扱いは十分注意が必要です。

https://docs.microsoft.com/ja-jp/azure/storage/common/storage-sas-overview#best-practices-when-using-sas

>
◆ SAS を使用する際のベスト プラクティス
アプリケーションで Shared Access Signature を使用する場合は、次の 2 つの潜在的なリスクに注意する必要があります。
>
・SAS が漏えいすると、取得した人はだれでも使用できるため、ストレージ アカウントの安全性が損なわれるおそれがあります。
・クライアント アプリケーションに提供された SAS が期限切れになり、アプリケーションがサービスから新しい SAS を取得できない場合は、アプリケーションの機能が損なわれる可能性があります。


Azure Blob Storage 側で認証を行う必要がない場合、下記方法でも可能です。
・匿名のパプリックアクセスを許可する
・静的 WEB  サイトとして公開

これらの方法では、外部からのアクセスが認証なしで行えます。
利用する際は、Azure Storage のファイアウォール機能で、アクセス元の IP アドレスを制限するなどの方法を検討しましょう。
IP アドレスの制限は、SAS を利用したアクセスでも有効で 設定した IP アドレス以外からのアクセスをブロックします。

https://docs.microsoft.com/ja-jp/azure/storage/common/storage-network-security?tabs=azure-portal

>
Azure Storage では、多層型セキュリティ モデルが提供されています。 このモデルでは、使用されるネットワークまたはリソースの種類とサブネットに基づいて、アプリケーションやエンタープライズ環境で求められるストレージ アカウントへのアクセス レベルを確保して制御できます。 ネットワーク ルールを構成すると、指定したネットワークのセットまたは指定した Azure リソースのセットを経由してデータを要求しているアプリケーションのみが、ストレージ アカウントにアクセスできます。 ストレージ アカウントへのアクセスを、指定した IP アドレス、IP 範囲、Azure Virtual Network (VNet) 内のサブネット、または一部の Azure サービスのリソース インスタンスから発信された要求に制限できます。
pipでopencvをインストールする

[こちらの記載](https://pypi.org/project/opencv-python/)を参考にして、pipでopencvをインストールする

```
# python3の場合
pip3 install opencv-python

# pythonの場合
pip install opencv-python
```

#参考

https://qiita.com/fiftystorm36/items/1a285b5fbf99f8ac82eb

https://pypi.org/project/opencv-python/
Rmarkdownのチャンク外で変数とかを呼びたい時

Rmarkdownの文中にRコードを埋め込むことも可能。
文章中、チャンクの外で変数や計算結果を呼びたい時は以下のように書く。

\`r ここに呼びたいコード結果や変数を書く\`

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324570/e7b9416c-5562-331e-274d-124c78294b11.png)
live-buildで自分好みのDebian Live ISOを作成する

昔からの夢でした。以下の記事で一気に進みました。本当に感謝です。

https://qiita.com/homelith/items/f30a1fbac89dc977c1ff

# とにかく公開したもの

https://github.com/numeru55/live-build-my

# 目標としたこと

- Debian/Gnomeデスクトップ
- 自分のMacBook用に，BroadcomのWiFiドライバーを加える
- Google Chrome等，自分好みのパッケージ同梱。ほかはできる限りシンプルに

- 他のメディアにインストールし起動できるよう，ESP修正スクリプトとrEFIndも加えた。

# Google Chrome同梱について

配布はだめ，とどこかの記事で見た気がします。なので，出来上がったISOを配布したりするのはやめておいたほうが...

マニュアルを読んで，リポジトリと公開鍵を追加しました。ダサいけどMakefile参照。そのうえで，パッケージリストに追加することでLive環境に含めることができました。

# ESP修正について

我ながら，これもダサいスクリプトだが，入れました。
テキストモードのrEFIndが好きなので，インストールできるようにスクリプトを作ってみました。また，標準的な手順も別スクリプトにしました。

どちらも内蔵のSSDを飛ばしかねない危険なものなので，スクリプトを修正して使うことを前提とした動きにしました。よろしくおねがいします。

# 日本語入力について

Debianでは，今のところ`uim-mozc`が気に入っています。私のMacのキーボードで，「[かな]を押せば日本語モードになり，[英数]を押せば英数の直接入力モードにする」が実現できたからです。

ライブ環境で実現する方法がわかりませんでした。そのため，上記では `ibus-mozc` を使いました。Macでは，[command]+[space] を何度か押し，Mozcにして日本語入力を行います。
Xamarin.FormsでMaterial Iconをコードビハインドから使う方法

# 結論
- `\uffff`という風に4桁の16進数の前に`\u`をつけたらOK

```csharp
var label = new Label();
label.Text = "\ue8b6"; // Search icon
label.FontFamily = "Material";
```

## 概要
Xamarin.Formsでマテリアルデザインのアイコンを使いたいことがあると思います。
私の作成しているアプリでもマテリアルデザインのアイコンを使用していました。
基本的にはXAMLからすべて設定を行っていたのでしばらくは問題無く使えていたのですが、ある時どうしてもコードビハインドに処理を記述する必要が出てきました。
さらに、その処理の中でアイコンを使う必要があったのですが、XAMLで使用するときと同じように設定しても動きませんでした。

(XAMLで使う方法)
[Xamarin.Forms でアイコンフォントを使う](https://qiita.com/amay077/items/4c315e7f212834183316)

上記記事にもあるように、XAMLの場合は以下のように指定します。

```xml
<Label Text="&#xe8b6;" FontFamily="Material"/>
```

上記で`Text`に指定している`&#xe8b6;`ですが、このままコード側で指定しても動いてくれません。
`e8b6`の部分はアイコンのIDのようなものなので、その前後についている奇妙な文字列に秘密がありそうです。

よくよく調べていると見つけました。

- [XMLにおける文字参照と実体参照](https://www.javadrive.jp/xml/ini/index6.html)

> 文字参照は 10 進数または 16 進数の文字番号を使って次のように記述します。
> 
> &#(10進数の文字番号);
> &#x(16進数の文字番号);

XAMLというよりもXMLの仕様なんですね :thinking: 

ということで奇妙な文字列の意味はわかりました。
あとはコード側でどうやって表現するかですが、上記より16進数ということがわかったので16進数を文字列として表現する方法を探します。

- [文字列にエスケープ文字を埋め込むには？［C#／VB／WPF］](https://atmarkit.itmedia.co.jp/ait/articles/1709/27/news017.html)

> \u	16進表記のUnicode文字
※「\u」に続けて16進数4桁を記述する

`\u`で良さそうです。

ということで、XAMLでは`&#xe8b6;`と指定していたものは`\ue8b6`としてあげることで正しく表示されました！

# 参考URL
- [XMLにおける文字参照と実体参照](https://www.javadrive.jp/xml/ini/index6.html)
- - [文字列にエスケープ文字を埋め込むには？［C#／VB／WPF］](https://atmarkit.itmedia.co.jp/ait/articles/1709/27/news017.html)
- [How to add font icon in toolbar item in xamarin forms](https://stackoverflow.com/questions/57395091/how-to-add-font-icon-in-toolbar-item-in-xamarin-forms)
【IoT検定 受けてみた】 〜パワー・ユーザー編〜

## 背景
会社のプログラムで受験可能とのことで受験しました。
## 結果
総合評価(100%)：79%
グレード（ABC）：B
## 本試験について
本試験はグレードで判定されます。そのため合否はありません。
試験の中身は以下のとおりです。

概要　　　|内容　　|
---|---|---
正式名称|IoT検定ユーザー試験パワー・ユーザー|
試験方法|CBT　三肢択一|
試験時間	|４０分＋アンケート|
出題総数	|４８問（８分野＊６問）|
評価方法	|グレード制　<br>・グレードA＝正答率８６〜１００％　<br>・グレードB＝正答率７６〜８５％<br>・グレードC＝正答率６６〜７５％<br>・グレードなし＝正答率６５％以下 　　|
認定方法|試験終了後証明書（スコアレポート形式）が発行されます。|
開催時期	|通年受験可能|
受験料金|8,800円(10%消費税込)|
## 勉強方法
下記の公式参考書で一週間、1日2時間ほど勉強しました。
ぱらぱら眺めてました。意味が全部パッ！と分かるレベルまで繰り返し何度も眺めました。

[図解即戦力 IoTのしくみと技術がこれ1冊でしっかりわかる教科書 IoT検定パワーユーザー対応版](https://www.amazon.co.jp/exec/obidos/ASIN/4297111799/hanmotocom-22/ref=as_li_ss_tl?fbclid=IwAR2i8vCOMwxL7L2nijRwd1rYGvRCG6IUdHY5Cq4Fj1Ugj4nGVvY4foVR8OI&linkCode=sl1&tag=certification-22&linkId=1069ad2a0997a94235e8616a2a4e0040&language=ja_JP)

## 受験してみて思ったこと

* 初学者の場合、上記の参考書だけでは100点は取れない。
    * 明らかに今回利用した参考書には記載されていない内容が出題されていました。
* 100点は取れないが、参考書を勉強していれば初学者でも80点近くは取れる。
    * グレードBぐらいならこの参考書だけで十分だと感じました。
* 日本語に違和感を感じる出題文がいくつかある。
    * 運転免許試験を思い出す出題文でした。
* 結果の詳細が見れないため、何を間違えたのかよく分からない。
    * 各セッションごとの正答率のみフィードバックされるため、一問一問の正否が分かりません。
 
## 最後に
会社からこのような機会をいただけて良かったです。
試験があるというだけで、勉強のモチベーションが爆上がりしました。何事も目に見えた目標があると頑張れるということを思い出しました。 

また通常の案件だけですと学習の範囲が限られてくるので、体系的に学習できて、なおかつモチベーションも自然と上がる今回のような試験の機会があれば積極的に手を挙げていきたいです。

本試験の次のレベルも受講しました。以下の記事にまとめてます！
[【IoT検定 受けてみた】 〜プロフェッショナル コーディネータ編〜](https://qiita.com/MONSOON/items/8bfe80728a5bead42008)
【React】カウントアップボタンの作成方法【入門】

## はじめに
　本記事は、プログラミングの学習を始めて1ヶ月の初学者が、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
　そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
　間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

##React 入門

###Reactとは
Facebook社（現 Meta Platforms）が開発したUIパーツを構築するためのJavaScriptライブラリです。

###カウントアップボタンの作成
カウントアップボタンを例に説明します。
以下のように記述することでカウントアップボタンを作成することができます。

```App.js
// Reactをインポート
import React from 'react';

// React.Componentを継承するAppクラスを定義
class App extends React.Component {
  constructor(props) {
    super(props);
     // stateをオブジェクトを使って定義
    this.state = {count: 0};
  }
   // カウントアップするためのメソッドを定義
  handleClick() {
        // 指定したプロパティに対応するstateの値を変更する（ここではcountの値を変更する）
  	this.setState({count: this.state.count + 1});
  }
  // JSXが返り値であるrenderメソッドを定義
  render() {
    return (
      {/* return内はJSXを記述。中括弧で括ることでJavaScriptを埋め込むことができる */}
      <div>
        <h1>
          {/* stateのcountを呼び出し。最初は0が表示される。 */}
          {this.state.count}
        </h1>
        {/* onClickイベント時にhandleCkickメソッドを実行。（プラスボタンが押されるとカウントアップ） */}
        <button onClick={() => {this.handleClick()}}>+</button>
      </div>
    );
  }
}
// Appクラスをエクスポート
export default App;

```

####補足

- `state`とは、Reactではユーザーの動きに合わせて変わる値のことを指します。

- Reactでは、stateの値に直接代入することで値を変更してはいけません。そのため、上記でいう`this.setState({count: this.state.count + 1});`のような記述で値を変更します。
 
- JSXはほぼHTMLと同じように記述することができますが、いくつかの相違点がありますので注意が必要です。

- return内に複数の要素があるとエラーになります。そのため、上記の例では、divタグで囲んで1つの要素にまとめています。
Google Assitant SDKで自分のPCをGoogleアシスタントにしよう

# はじめに
この記事は、[Aizu Advent Calander2021](https://adventar.org/calendars/6636)の19日目の記事です。
大遅刻です。
# 本編ここから
こんにちは。PythonParrotです。
ラズパイをGoogleアシスタントにしようとして、まずは自分のPCでやってみたのでその話です。
あと「OK, Google」で起動できるようにしたのでその話も。


## やったこと
以下のサイトの通りにやった。

https://developers.google.com/assistant/sdk/guides/service/python/embed/setup

今回はPCだったのでイヤホンとマイクがあればOKだった
## 躓いたところ
### OAuth2.0認証するところ
https://developers.google.com/assistant/sdk/guides/service/python/embed/install-sample
ここのセクションでOAuth認証が必要なのだが、なぜか403で拒否されてしまう（自分のプロジェクトなのに・・・）
OAuth同意画面のテストユーザーに自分を追加するとうまくいく。/

## OK, Googleする対応
さて、以下のページにもある通り、GoogleアシスタントSDKには「Hands-free activation」すなわち「OK Google」で起動する機能が存在しない。（deprecatedなGoogle Assistant Libraryにはあるのに・・・）
ということで、Porcupineというワードエンジンを使ってこの機能を実装してみた。


## コード
```python3
# add for Hotword detectation
import pvporcupine
from pvrecorder import PvRecorder
## 中略 ##
# Porcupineのアクセスキーを引数で指定できるようにする
@click.option('--access_key', default='', help='Access Key')
def main(api_endpoint, credentials, project_id,
         device_model_id, device_id, device_config,
         lang, display, verbose,
         audio_sample_rate, audio_sample_width,
         audio_iter_size, audio_block_size, audio_flush_size,
         grpc_deadline, once, access_key, *args, **kwargs):
### 中略 ###
    handle = pvporcupine.create(access_key=access_key, keywords=['ok google', 'hey google'])
    while True:
        ## ここで起動ワードを指定する
        recorder = PvRecorder(device_index=-1, frame_length=handle.frame_length)
        recorder.start()
        result = -1
        while result < 0:
            pcm = recorder.read()
            ## ここのresultが0以上なら指定したワードを聞き取ったことになる
            result = handle.process(pcm)
        recorder.stop()
        recorder.delete()
        audio_sink = audio_source = (
            audio_helpers.SoundDeviceStream(
                sample_rate=audio_sample_rate,
                sample_width=audio_sample_width,
                block_size=audio_block_size,
                flush_size=audio_flush_size
            )
        )
        # Create conversation stream with the given audio source and sink.
        conversation_stream = audio_helpers.ConversationStream(
            source=audio_source,
            sink=audio_sink,
            iter_size=audio_iter_size,
            sample_width=audio_sample_width,
        )
        with SampleAssistant(lang, device_model_id, device_id,
                             conversation_stream, display,
                             grpc_channel, grpc_deadline,
                             device_handler) as assistant:
            assistant.assist()

```

全ソースコードはこちらを参照。
https://github.com/rf-castle/google-assistant-sdk-hotwordDetect-sample/blob/master/src/talk_hotword.py
【RailsAPI】AbstractController::DoubleRenderErrorの対処法

<h2>症状</h2>
RailsAPIモードで、条件でrenderするものを変えるアクションを作成時に、以下のエラーが発生しました。
翻訳すると、「このアクションでは、レンダリングおよび/またはリダイレクトが複数回呼び出されました。ご注意ください」

```terminal:error
AbstractController::DoubleRenderError (Render and/or redirect were called multiple times in this action. Please note that you 
may only call render OR redirect, and at most once per action. 
Also note that neither redirect nor render terminate execution 
of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".):

//全文翻訳
AbstractController :: DoubleRenderError（このアクションでは、レンダリングまたはリダイレクト、あるいはその両方が複数回呼び出されました。
レンダリングまたはリダイレクトのみを呼び出すことができ、アクションごとに最大1回呼び出すことができます。
また、リダイレクトもレンダリングも実行を終了しないことに注意してください
したがって、リダイレクト後にアクションを終了する場合は、「redirect_to（...）andreturn」のような操作を行う必要があります。）：
```

以下が該当のコードです。(すごい簡略化しました)

```ruby:HogeController.rb
def update_hoge
  user = User.find_by(id: params[:user_id])

  if(user.update!(
    hoge: params[:hoge],
  ))
     render json: {user: user}, status: :ok
  else
    render json: {}, status: :unauthorized
  end

  render json: {user:user}, status: :ok
end
```

<h2>解決策</h2>
if分の後にもrenderがあったため、2重でrenderにかエラーが発生していたようです。
最後のrenderを消すことで解決しました。

```ruby:HogeController.rb
def update_hoge
  user = User.find_by(id: params[:user_id])

  if(user.update!(
    hoge: params[:hoge],
  ))
     render json: {user: user}, status: :ok
  else
    render json: {}, status: :unauthorized
  end
end
```
駆け出しエンジニアで契約打ち切りになったあなたへ


## コレは何？
Twitterで「#駆け出しエンジニアと繋がりたい」というハッシュタグを見かけました。
このハッシュタグの件数が意外と多い。

私が１０年以上前に駆け出しエンジニアとして歩み始めた頃と比べたら、色々便利なプログラミングツールや環境が整っていますが、教育環境という面ではあまり進歩していない部分があります。例えば「３ヶ月で学習して成果を出せるか」という妙な試練を未だに課している点です。

そういった環境で駆け出したエンジニアが悩んでいること、例えば「自分にはプログラミングの才能がないのでは？」「プログラミング漬けになるぐらい勉強しているのに成果が出ない」とかの悩みのヒントとなればと思い自分の考えを綴っています。

## 「３ヶ月」では大抵の人は無理です
未経験の人でも３ヶ月だけ入れてみて、「使えない」と判断されたら切られる開発会社のシステムがあります。あれって何を見ているのでしょう？３ヶ月で何を判断されているのでしょうか？色々な面を判断されていると思いますがこういったことを判断されています。

1. プログラム言語をある程度習得できる飲み込みの速さ
2. 何がわからないのか言語化できる
3. プレッシャーに強いか
4. 素行が良いか 

何を判断しているかというと「この人は学校の優等生か？」というものです。３ヶ月である程度プログラムを書けるようになる人は極稀だと思ったほうが良いです。
学校の勉強ができた人向けです。

プログラム言語習得は概念が日常とかけ離れている部分が多いので脳が受け付けないのです。例えば「A=1」は日常生活では「Aと1は等しい」を意味しますがプログラムの世界では「Aに1の値を代入する」という意味になります。最初のこの部分でも初心者狩りが発生します。（この点ではR言語の「A <- 1」という表し方は画期的だと思います）

## ３ヶ月で契約を切られたあなたへ
３ヶ月で契約を切られたあなたに言っておきたい。
「３ヶ月でプログラミングのセンスが有るか無いかはわからない」
短い期間ではセンスを計ることはできません。飲み込みが早いかどうかぐらいです。
「君はセンスがない」と言われたら、それは嘘だと思ったほうが良いです。

飲み込みが遅くても悩んでいるなら、長期的には問題はありません。
一つの言語を覚えると他の言語にもすぐに適応できるようになります。

その人が適性があるのかは判断できるのは２年後ぐらいです。


## ダークホース的戦略
プログラミングを習得できなかった、いや「習得できないと思っている」あなたに戦略を提案をします。ちなみに「ダークホース的戦略」の名前は[Ｄａｒｋ　Ｈｏｒｓｅ『好きなことだけで生きる人』が成功する時代](https://www.amazon.co.jp/dp/B09D35FS3N/ref=cm_sw_r_tw_dp_1EXQZZCRJV7SQ2ZXYDHF "DarkHorse")という本から丸パクリです。「正規の学習法を無視した自分にあった学習戦略を組むことが大事なんだ」ということを力説していて、プログラミング学習にも適応できる内容でした。　

1. **独学を行う。**
　基本的にプログラム言語は独学です。誰から教わることはあまりありません。また人から教わることがプレッシャーにもなります。

2. **学習期限を１年以上とする**
　この戦略は長期的な戦略なので自ずと１年以上になります。えっ？もっと早くできないか？できません。これは学校の勉強ができなかったあなた向けです。（自分も含め）

3. **金銭的な余裕を確保する。**
 期限は１年ですし、プログラミングの本は高いので金銭的な余裕がないといけません。完全な書籍は存在しませんので何冊も買う必要があります。金銭的な余裕によりプレッシャーもありません。

4. **最初は毎日サンプルコードを写経する（上限３つまで）**
　こういう反論が来ますよね。「何も考えずサンプルコードを打つことは意味がない」と。本人が考えていなくても脳が学習しています。脳がニューラルネットワークをゆっくり構築しています。脳が基礎のベースを組んでいるので待ちましょう。理解はあとからやってきます。
最初は打ったものが動くという感動を体験してほしいです。同じように打ってみたけどエラーになる状態になるなら儲けものです。その問題を解決できるとプログラムを少し理解できるようになります。
一番ダメな状態は本人がプログラミングの作業が苦痛に思い写経をやめてしまうことです。脳の構築作業がストップして最後には消えてなくなります。
それを回避するために**「毎日のサンプルコードの写経は必ず１つは行い、最大３つまで」**とします。**焦って無茶なノルマを課してはいけません。無茶なノルマを課して投げ出す自分を責めてはいけません。** その戦略は何度も失敗しているでしょ？
ちなみに写経と言っても紙に書くほうではなく、エディタにキーボードで打ち込む方です。念の為。
参考文献:[ジェームズ・クリアー式 複利で伸びる1つの習慣](https://www.amazon.co.jp/dp/B07YY2WV6K/ref=cm_sw_r_tw_dp_69CDPQJFAKZXS86GX1CN?_encoding=UTF8&psc=1 "ジェームズ・クリアー式 複利で伸びる1つの習慣")

5. **プログラム資格試験の合格を目標にしない**
 合格してもサービス・ソフトが作れることを証明するものではないので。プログラム資格試験は会社から「取れ」と強制されてから受けるものです。例外として例えばCISCOが主催しているCCNAなどは価値があります。合格するとネットワークの基本がわかるレベルになっているので有意義です。
またITの資格を持ち過ぎな人って,結構暇な...おっと誰かが来たようだ。

6. **アプリを10個作ってみる。**
 どんなものでもいいので作ってみましょう。画期的なものじゃなく、どこにでもあるようなものです。体重を記録するアプリでもいいです。全然、思いつかない場合は「これをコピペしたらソフトが動く」というソースコードを写経してみましょう。


写経とアプリづくりを通してプログラミングのブレイクスルーが訪れます。
ブレイクスルーが訪れた後に自分がプログラミングの適性があるかわかると思います。プログラミングの基本が分かれば、あとは想像力の高さが物を言う世界が待っています。

何を言いたいのかわからなくなったので、ここで終わります。
少しでも役に立ったらいいなー。