OmniAICreator/Qiita-1.07M huggingface dataset:
【PHP】組み込み関数のまとめ

PHPの学習を始めたため、備忘録として保存します。

## 組み込み関数のまとめ
### 出力系

| 関数 | 処理の内容 |
| ---- | ---- |
| print|文字列を出力する|
|print_r|データ型と値を出力する|
|var_dump|データ型・値・長さなどを詳細に出力する|

###文字列操作系

| 関数 | 処理の内容 |
| ---- | ---- |
| strlen | 文字列の長さを返す |
| mb_strlen | 文字列の長さを返す（日本語対応） |
| substr | 文字列の一部分を返す |
| str_replace | 検索文字列に一致したすべての文字列を置換する |
| implode | 配列から文字列を生成する |
| explode | 文字列から配列を生成する |


### 数学系

| 関数 |	処理の内容 |
| ---- | ---- |
| floor | 小数点以下を切り捨てた値を返す |
| max |	引数の中の最大値を返す |
| min |	引数の中の最小値を返す |
| mt_rand | 乱数を生成する。引数にその範囲を指定することができる。 |
| round | 四捨五入した値を返す。桁数を指定することができる。 |

### 日付・時刻系

| 関数 |	処理の内容 |
|----|----|
| time | 現在のタイムスタンプ値を取得 |
| mktime | 指定された年月日、時分秒に対応するタイムスタンプ値を取得 |
| date | タイムスタンプ値を指定フォーマットで整形 |
| checkdate | 日付が妥当か判定 |

### セッション関数

| 関数 |	処理の内容 |
|----|----|
| session_id | セッションIDを確認できる |
| session_name | セッション名を確認できる |
| session_regenerate_id | セッションIDを再発行できる |
| session_unset | セッション変数を開放できる |
| session_destroy | 全セッションデータを破棄できる |


上記以外にも多くの関数があるありますが、数が膨大なのでメモはこれくらいにしておきます。

変数操作も今後よく使いそうな気がするので公式ドキュメントを貼っておこう。
https://www.php.net/manual/ja/ref.var.php
GAMENI(仮)を開発中！

# はじめに

[弊社](https://aisic.jp/)というか私自身、kintoneがサービスインした頃(2011年)から、色々と触りながらコンサルティング＆開発をしてきました。

気が付けば10年ほどになりますが、今まで、しこたま失敗しながら、kintoneでの開発を進めてきて、試行錯誤の結果、ここ数年である程度、効率的かつ安定的な開発の考え方と、それを支える開発環境とが固まってきて、弊社なりのベストプラクティスが構築できてきました。

これらは、もちろん弊社の開発ノウハウではあるのですが、公開＆共有することで、kintoneでの開発をすることの敷居を下げて、たくさんのSIerさんに参入してきてほしいなと思っておりますし、コードを書く楽しさを味わっていただく方も増えていただければと思います！

ノーコード開発やローコード開発が大きく注目され、世の中がその方向に進んでいる中で、全くの逆行ではありますが、GAMENIの思想と環境を使うことで、通常のシステム開発のように、素早くかつ安定的に実装することができるようになります。

**過去の記事はコチラ**

https://qiita.com/j-kume/items/4b67f361d54259a11a1c

https://qiita.com/j-kume/items/e5458094ebf9be9834f0

https://qiita.com/j-kume/items/fd0e9f892314e16facfb


# GAMENIのソース
**[Github](https://github.com/j-kume/gameni)**からご利用ください。
と言いつつ、まだキレイに整理できていないので、ちゃんと使える状態にはなっていません。
(近いうちにそこそこのレベルには持っていきます…。)


# GAMENIが提供できること
* TypeScriptで開発できます。
* 開発環境と本番環境などを設けながらの開発手法が盛り込まれています。
* 開発環境 → 本番環境などへのデプロイができます。
    * [ginue](https://github.com/goqoo-on-kintone/ginue)を使わせてもらっています。
* kintoneへのJavaScriptの配置をプログラマブルに行うことができます。
    * [kintone-customize-uploader](https://github.com/kintone/js-sdk/tree/master/packages/customize-uploader)を使わせてもらっています。
* [Jest](https://jestjs.io/ja/)を使ったテストを流すことができます。
* エラーログ出力
* kintone向けのutility系関数群の提供
    * 数値のカンマ区切り、端数計算など

GAMENIは、kintoneでカスタマイズ開発を効率的かつ安全に実施するためのToolKitのような側面は多分にあるのですが、kintoneカスタマイズをする上での思想というか、どのような構成でkintoneアプリ群を構築するとよいか、カスタマイズをするときのプログラムの書き方のベストプラクティス等、kintoneカスタマイズの開発フレームワークとしての役割を担いたいと思っています。


# GAMENI の今後
2022年春頃をメドに、ちゃんとした版(1.0.0？？)をリリースできるように開発を進めていきたいと思います。

しばらくはコアメンバーで開発を進めていくことになるかと思いますが、折を見ていろいろな方からの意見やアイデアも織り込みながら、継続的なブラッシュアップができるように、取り組んでいきたいと思いますので、ぜひIssueやプルリク貰えると大変嬉しいです！

また、開発環境の提供だけによらず、開発手法の勉強会や開発者同士のコミュニティ作りもできればと思っていますので、たくさんの方にかかわっていただきつつ、GAMENIが育ってくれるといいなと考えています！


# ちなみに…
開発コードネームの「**GAMENI**」とは、福岡の郷土料理の「**がめ煮**」から取りました。
![publicdomainq-0029840.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319512/223c5fc8-fc7c-e6b0-c2fb-791a3e9c0313.jpeg)
↑ こういうやつです。「筑前煮」とも言いますかね。


たいした意味はないのですが、私が福岡出身＆在住ということと、今回の開発環境ツールが色んなツールがこちゃまぜになったようなものなので、ちょうどいい(？)かと思って、開発コードネームにしちゃいました笑


# スペシャルサンクス
長井さん([@akvabit](https://twitter.com/akvabit))、石際さん([@moji0112](https://twitter.com/moji0112))、三宅さん([@tomo63ko](https://twitter.com/tomo63ko))のおかげで前に進める勇気が出てきています！感謝！！
若干、巻き込まれ事故感に溢れていますが笑、引き続きよろしくお願いしますmm


# お知らせリンク
**[顧問エンジニアプラン](http://aisic.jp/service/emotional-si/engineer-advisor/)**
<a href="https://www.rescutone.com/"><img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319512/c5061092-a73b-dc4b-f302-5aaafd81ef9e.png"></a>　<a href="https://www.renovatone.com/"><img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319512/8bc6d788-f012-8c1b-e2d0-2291fcb2f77f.png"></a>　<a href="https://aisic-showroom.qloba.com/"><img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319512/b5612c0c-da50-449e-9fa3-70b327fa66e8.png"></a>
.batファイルで画面拡張・解除を切り替える方法

「同時に2端末使ってるけど2枚目のディスプレイはどっちでも使ってる・・・」
「常にじゃないけどたまに両方の画面確認しながら作業しないといけない・・・」

という状況が最近多かったのですが、
いちいち設定→ディスプレイ設定開くのもwindowsキー + pで変えるのも面倒でした。
なのでとりあえず作ったのが以下のバッチファイルです。
フリーソフトで専用のショートカットキーに充てるなどすればより便利になると思います。

## サンプル
サンプルですがこんな感じです。多分他の環境でも使えると思います。

環境
OS：Windows 10 Pro
バージョン：21H1



```
@echo off

echo -------------------------------
echo 1. 解除
echo 2. マルチディスプレイ適用
echo -------------------------------
set /p key=1 or 2を入力してください:

if %key%==1 (
  C:\Windows\System32/DisplaySwitch.exe /internal
) else if %key%==2 (
   C:\Windows\System32/DisplaySwitch.exe /extend
) else (
  echo 1 or 2を入力してください。
)
```

![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258938/b4c6fb32-7185-5add-b5f6-78bac09cd12c.png)


## 中身の概要
調べたところ
##### DisplaySwitch.exe
で、windowsキー + pで出てくるアレを表示し、引数に応じてそれぞれ選択・実行できるようです。

今回は
元画面のみ：internal
画面拡張：extend
を引数として使いました
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258938/87d24816-366f-0e55-6a64-9a68546819ae.png)

参考となる情報はwindowsコミニュティなどで調べました。
他にも色々調べたのですが、ディスプレイ設定系だと解像度変更を簡単にできるようにしたい方が多いみたいですね。
自分のような用途は少なそうです。
https://answers.microsoft.com/ja-jp/windows/forum/all/%e3%83%ad%e3%82%b0%e3%82%a4%e3%83%b3%e6%99%82/1aa3285f-fccf-48a6-8f49-e0b818472de4
TeamGeekから学ぶ最強のチーム

# はじめに
チームをマネージメントする立場になって１年ちょっと経って
改めて本書を読み返したら気づきがたくさんあったので、
皆さんにも最強のチームを作る参考になればいいなと思います。

# 三本柱（HRT） 
チームで働くときのポイント。
<strong>三本柱、HRT（ハート）
・謙虚（Humility）常に自分を改善していこう
・尊敬（Respect）一緒に働く人を心から思いやる
・信頼（Trust）自分以外の人を信用して仕事を任せよう<strong>

この本のテーマでもあるし、上記のことが大切ということが
至るところで言われているけれど、ここを意識することが
改めて大切だと実感しています。
自分がHRTを持って相手に接していても相手にHRTがなければ
うまくいかないことも出てくるということ。
また、チームを作る中では人間関係やコミュニケーションが大切に
なってくるので、HRTはとても大切だけど、そんなに簡単にできること
でもないよということ。
なのでスキルとしてHRTを身につけるといいよということかなと思います。
まずはHRTを意識してやってみる。

>現実的に考えてみよう。君は天才じゃない。
仮に君が天才だったとしても、それだけでは不十分なんだ。
天才だってミスをする。優れたアイディアやプログラミングスキルがあっても、
開発したソフトウェアが必ずしも成功するとは限らない。
今後のキャリアがうまくいくかどうかは、同僚たちとうまく協力できるかに
かかっている。

確かに私も天才じゃないし、天才がいたとしても一人では
偉業は成し遂げられない。
なので隠すのではなくなんでもオープンにして協力していこうということ。
チームでうまくやっていく為には自己開示はとても大切。
私自身も1on1などを通して少しずつオープンにできるようになってきたかなと思っています。
チームみんなでオープンにできる環境を作って協力していくことはとても大切。

# チーム文化　
文化とはチームが共有する経験・価値・目標のこと。
ドキュメント化して振り返り共有する。
今の時代、特にオンラインとオフラインのバランスが大切。
強いチームを作るにはコミュニケーションが大切。
チームメンバーみんなで文化を作っていく。


# チームリーダー 
マネージャーはエンジニアを「信頼」
してリーダーはチームの為の道を作る
技術的な側面と人間関係、両方サポートしていく。

## アンチパターン
・自分の言いなりになる人を採用する
・パフォーマンスの低い人を無視する
・人間の問題を無視する
・みんなの友達になる
・採用を妥協する
・チームを子どもとして扱う

## リーダーシップパターン
・エゴをなくす（チームを信頼する）
・禅マスターになる（問題解決の手伝いをする）
・触媒になる（合意形成）
・先生やメンターになる
・目標を明確にする
・正直になる
・幸せを追い求める

パフォーマンスの低い人には早めに対処する。
相手を尊敬して一緒に併走してあげることでパフォーマンスは上がっていく。
小さな目標を設定し、小さな成功体験を何度も経験させるために進捗を確認する。
ここは苦手でしたが、
相手を信頼して方向性を示した上で仕事を任せていくことで
メンバーが自分で考えて行動するようになってきたと思います。

そして1on1を活用していくこと。
自己開示をしながら信頼関係を作り、
直接　「何か必要なものはある？」と質問する。
個人の幸せとチームの幸せを重ねていくことでみんなで幸せになる。
これはエイチームの経営理念「みんなで幸せになれる会社にすること」
にも繋がっていくと感じています。

また、モチベーションを高める為には内発的動機を高めること。
仕事の目的を与える。
自分で考えて行動する（自律性がある）。
エンジニアには新しいスキルを学び、
既存のスキルを向上させる機会を作る（熟達）。
ここはわかっているようでもより意識的に行うことでモチベーションも上がるし、
生産性も上がる。

# 有害な人に対処する 
>彼の振る舞いを追い出そうとしたのである。
好ましくない振る舞いは受け入れなれない。
何度警告しても振る舞いが改善されなかったら、
その時は正式に追い出すことを検討してもいいだろう。

チームにとって有害な人には振る舞いを正しくするよう警告しても
改善されない場合は追い出すということを検討に入れても良いと
いうことが書かれている。こういう選択肢もあるんだということを
持った上で人が悪いわけではなく問題は振る舞いであるということ。

ベストプラクティスを身につけて有害な振る舞いを受け入れにくくする。
・ミッションステートメントを決めて目標とそれ以外の両方に集中する。
・メールで議論するときのマナーを作る。
アーカイヴを保存して、新来者に読んでもらえば、時間の節約になる。
・すべての履歴を　文書化する。
コードの履歴だけでなく、設計決定・バグ修正・失敗なども記録する。
・効果的にコラボレーションする。バージョン管理システムを使う。
コードの変更は小さくてレビューしやすいものにする。
縄張り意識を作らずに「パス係数」を増やす。
・バグ修正・テスト・リリースなどについて、明確なポリシーや手続きを用意する。
・新来者の参入障壁をなくす。
・合意ベースの決定を信頼する。合意できないときの衝突解消のプロセスも定義しておく。


# 組織的操作
許可を求めるより寛容を求める方が簡単
上司の許可を得なくてもできる範囲を知ること。
道がないなら道を作る。

# 常にユーザーのことを考える
・マーケティング
　ソフトウェアがどのように見られるか気を配る。
・ユーザービリティ
　使いにくかったらユーザーは去ってしまう。
・顧客サービス
　ユーザーとの長期的な関係構築が、ソフトウェアの進化やユーザーの
　定着に影響を与える。

ユーザーと向き合っていないとソフトウェアの価値がなくなってしまう。
技術的にエンジニアの方がユーザーよりも上であることを傲慢に思って
ユーザーを見下したりしてはいけない。
開発は常にHRTの精神で行うべきである。
やはり大切なのはHRTの精神。

# まとめ
・HRTを常に意識する。スキルとして身につける。
・コミュニケーションのできるチームを作る。
・本人が成長できる機会を与える。
・評価軸をたくさん持つ。小さい目標から成功体験を何度もする。
・個人の幸せとチームの幸せを重ねていき、みんなで幸せになる。
・チームの協力が成功のガギ。


参考
[Team Geek](https://www.amazon.co.jp/Team-Geek-%E2%80%95Google%E3%81%AE%E3%82%AE%E3%83%BC%E3%82%AF%E3%81%9F%E3%81%A1%E3%81%AF%E3%81%84%E3%81%8B%E3%81%AB%E3%81%97%E3%81%A6%E3%83%81%E3%83%BC%E3%83%A0%E3%82%92%E4%BD%9C%E3%82%8B%E3%81%AE%E3%81%8B-Brian-Fitzpatrick/product-reviews/4873116309?pageNumber=2"Team Geek")


Ateam Brides Inc. Advent Calendar 2021の21日目は、
マーケターの@MAB_cx がとっても面白い記事を書いてくれるはず。お楽しみに！
開発環境のCloud9から本番環境のCodeCommitへpushするまでの作業

現在ソースコードを本番環境のCodeCommitで管理することになり、開発環境のソースコードをどうやったら本番環境のCodeCommitにpushできるのか調べたので共有します。

手順
1IAMユーザの作成
これは基本的にできていると思うのでスキップします

２Cloud9のマネージド一時認証をオフにする
　①cloud9の画面へ移動
　②preferences⇨AWS Settings⇨Credentialsの順に移動
　③マネージドクレデンシャルをOFFにする

3本番環境のアカウントでクロスアカウントに必要なロールを作成
　公式ページを参照　　
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html

4Cloud9環境のCLI設定ファイルにIAMロール設定の切り替え設定を追加
　公式ページを参照
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-role.html

　①"~/.aws"ディレクトリに移動
　②aws configure set role_arn "本番環境で作成したロールARN" --profile "プロファイル名"
　③aws configure set source_profile "参照先プロファイル" --profile "プロファイル名"
　④configファイルを確認すると
　'''
[profile プロファイル名]
role_arn = "arn"
source_profile = "参照先プロファイル名"
*参照先のプロファイルがない場合は作成する
今回自分は参照先プロファイルをdefaultとしてそこにアクセスキーを記述しておきました
参照先のプロファイルがない場合は作成をしておく
aws configureで作成が可能

5gitを使用する環境で認証情報ヘルパーを使用する設定にする
以下のコマンドを入力
git config --global credential.helper '!aws --profile CodeCommitProfile codecommit credential-helper $@'
git config --global credential.UseHttpPath true

これでおそらくできると思いますw
QRコードにも文字コードはある

# はじめに
少しニッチな内容なのですが、ハンディターミナル[^1]という機器のアプリケーション開発時に出会った事象をご紹介します。

[^1]: 物流現場で使われることが多いバーコードを読み取る機械です。「ハンディ」、「HT」と省略されることが多いです。

# 事象
QRコードの読み取り結果が文字化けする。

# 原因
読み取った値をShift-JIS に変換して扱っていたが、QRコードの文字コードがUTF8だったため、正しく変換されなかった。


# 対応
今回のHT開発で使用している.NET Compact Framework 3.5[^2]には文字コード判別の方法が用意されていないため、第三者作成のDLLを使うかロジックを自作する方法が考えられますが、今回は事前に文字コードが分かっているため、判断ロジックを入れずに対応しました。
以下は文字コード変換部分のコード抜粋です。

```C#
// QRコードがShift-JIS の場合
// Encoding クラスに用意されている文字コード以外のインスタンスを取得する際はGetEncoding を使う
System.Text.Encoding sjis = System.Text.Encoding.GetEncoding("shift_jis"); 
byte[] codeData = sjis.GetBytes(code); // code はstring 型の読み取った値
string result = sjis.GetString(codeData, 0, code.length);

// QRコードがUTF8 の場合
System.Text.Encoding utf8 = System.Text.Encoding.UTF8;
byte[] codeData = utf8.GetBytes(code); // code はstring 型の読み取った値
string result = utf8.GetString(codeData, 0, code.length);
```

# さいごに
Android/iOS 向けのアプリ開発の場合、上記文字コードの考慮はあまり必要なさそうです。
Flutterのpub.dev で提供されているフリーのバーコードリーダーライブラリでも文字コードを自動的に判別して正しい読取結果を返してくれます。
昨今Windows CE 端末向けの開発は減ってきていると思われますが、ご参考になれば幸いです。

[^2]: Windows CEベースのモバイル・組み込みデバイス上で動作するように設計された、アプリケーション開発・実行環境です。.NET Frameworkの完全なコピーではなく、より少ないスペース、リソース環境下において使用できるよう縮小されているため、開発時に利用したい機能が含まれていないことが判明するケースが稀にありました。引用: https://ja.wikipedia.org/wiki/.NET_Compact_Framework
『SeaaaMan、Live2D始めたってよ』

[パーソンリンク アドベントカレンダー](https://qiita.com/advent-calendar/2021/personlink)24日目です！🎉
タイトル通りです。
桐島君が部活辞めたとかは全く知らないですね。帰宅部も立派な部活だと思います。


今回は技術ネタでも、路線を変えた技術を紹介しようと思います。

## Live2Dってなに？美味しいの？
大体の人が**VTuber**を知っていると思います。
一応、知らない人のためにリンクを貼っておきますね

<iframe width="560" height="315" src="https://www.youtube.com/embed/P5Td-Gt4E7w" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>



<br>Live2Dは**2Dイラストを立体表現を可能にするクリエイティブツール**です。
上の動画でありますが、VTuberさんのアバターが瞬きをしたり、左右を見たり、髪がひらひらさせたり、口をパクパクしたりする立体的な動きを作り出せるんですね。なので食べ物ではないんですね。
原画（イラスト）をそのまま素材として扱い、動いのモデリングをしていくんです。


ちなみにイラストから配信まで持っていくには以下のフローがあるそうです。
![イラストから配信まで.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678140/c2381f57-910c-aa30-f0e6-97cb3daad5a5.png)



## SeaaaMan、LIve2Dやってみた
今回はサンプルデータ（イラストのpsdファイル）を使用させていただきました。現在も色々やってるので途中経過までの内容を紹介します。1から紹介するとめんどくさいのイイ感じの部分だけ選別させていただきました。あと動画もくっつけました。


### アートメッシュ
各パーツ（目、髪の毛、眉など）の動きをつける際に、パーツデータには多角形の頂点の集合体（メッシュ）が割りてられます。自分で頂点の数を調整ができ、動きにこだわる人は頂点の数が多いそうです。



<br>各パーツの動きの設定を**パラメータ**といい、設定値にパーツのアートメッシュの形や位置を設定することでモデリングしていくのが基本操作です。眉を動かしてみました。

![まつげのモーションgif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678140/a1bb33db-bcbd-8bbe-0da5-02b8d788205b.gif)


<br>目のパーツを一通り設定した動きは以下になります。

![目の最新のモーション.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678140/75ba9122-c4ee-bf38-844d-2a0fd2f2503d.gif)



### ワープデフォーマー
上記で「目」の動きをつけましたが、実際のVTuberの動きを見ていると、顔の表情を１パーツのみで表現しているわけではないすよね。複数のパーツを連動させて、動きをつけていく必要があります。そんな時はデフォーマーを使うことでパーツ同士を一緒にして、メッシュの動きを同時につけれます。見た方が早いのでどうそ。（ここまでの現在進行形なので、おかしいところもありますがご容赦下さい）

![顔のデフォーマー.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678140/91cfca01-f392-e91c-58b0-a59f4e109658.gif)


<br>複数のパーツごとにまとめて、動きを付けました、デフォーマーを使うことで１パーツずつの編集（メッシュの調整）をしないで済むので、デフォーマーは必須操作らしいです。


## まとめ
Live2Dを初めて２週間ぐらいですが、本当にモデリングが難しいです。いざ、表情を作るときに1パーツのメッシュの位置が少し変わるだけで全然印象が変わってしまう。。これを仕事にしている人たちのセンスと集中力はすごいですね。皆さんの身近にクリエイターがいらしたら、レッドブルかモンスターエナジーを奢って労ってやってください。（SeaaaManはリポビタンD11が好きです）


<br>おっと、良い子たちにプレゼントを配りに行く準備をしなければ
では、皆さん ***Happy Christmas Eve to all !!***

![スクリーンショット 2021-12-19 16.10.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678140/32975025-7478-e69d-d6d6-8f7e63f28289.png)
仮想DOMとは

## 概要
仮想DOMについて学習したのでアウトプットしたいと思います。

## 結論
仮想DOMとは端的に言うと__効率よくレンダリングを行う仕組み__のことです。

## 前提知識

#### DOM
DOMとはDocument Object Modelの略称で、HTMLを操作するためのAPIのことです。
`<html>`や`<body>`といった__Node（ノード）__と呼ばれるものがツリー構造になって構築されています。
JavascriptでHTMLを操作する際に使用します。

## DOMが変更される際の仕組み
1. DOMに変更が発生した場合、再度情報を受け取り直してDOMを再構築。
1. 再構築されたDOMをもとに再描画されてブラウザに表示。

通常DOMを変更する場合は、DOMが再構築されるので描画が遅くなってしまいます。
そこで登場するのが__仮想DOM__です。

## 仮想DOMの仕組み
1. DOMに変更が発生する場合、実際のDOMと同じ仮想DOMを作成。
1. 仮想DOM上で変更を反映し、仮想DOMの変更前と変更後の差分を検出。
1. 発生した差分のみを実際のDOMに反映。

差分のみを実際のDOMに反映しているためレンダリングが早くなります。

## 参考文献
[【React】仮想DOMって何！？コンポーネントのレンダリングと描画について理解しよう！](https://qiita.com/seira/items/6767e222890c9890ecb9)
本番でステージング環境のリソース見てました

# 何があった

本番WordPressであるページの画像が急に出なくなったというので調査。
出なくなった画像のURLを確認してみると。。。**ステージング環境の画像サーバのURLでした**。

それの少し前にステージング環境のリソースを整理したので、そのタイミングで不要な画像として削除してしまっていたようです。

# どうしてそうなった

ステージング環境のWordPressでテストで作成したページを、コピペで本番にもって行ってしまったようです。
さらにステージング環境の画像サーバに特にIP制限などかけていなかったので、本番で使われても気づかない状態になっていました。

# どうすればよかった

- CMSを使った場合ファイルやデータなどはその環境にしか残らないので、本番にあげるときは同じ手順を行うようにしましょう
    - なんかいい方法ないのかな
- ステージングで使う全環境はIP制限などで開発拠点からしか見られないようにしましょう
    - ふざけてあげた画像が本番で使われていたりしたら怖いし
スクレイピング＆メール通知システムを作って運用した（レポ）

この記事は、スクレイピング＆メール通知システムを作った後、筆者が私的に運用している体験について簡単にまとめたものです。

実装の詳細は載せませんが、ご興味があれば[参考リンク](#参考リンク)の記事をご参照ください。

# 何を作ったか

[tenki.jp](https://tenki.jp/indexes/freezing_water/)から今日・明日の”水道凍結指数”をスクレイピングし、その情報を毎日同じ時刻にメール通知する簡素なシステムです。

![image-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303867/1475c36b-4f82-a145-01ed-e850e8f23883.png)

このシステム（フロー）を実装し、実際に運用するまで1時間もかかりませんでした。

enebularに慣れている方は、それくらいの速さで似たようなことができると思います。

# なぜ作ったか

最近のパソコンは、タスクバーやウィジェットからワンクリックで天気を確認できますね。が、この”水道凍結指数”までは確認できません。

「tenki.jpの”水道凍結指数”を毎日確認しに行き、凍結のおそれがあれば水抜きする」という風にすれば良いのでしょうが、それよりも毎日メールで通知してくれた方が楽です。

# どのように作ったか

メール通知するために必要な情報を、tenki.jpのページで調べます。
次に、この情報をフローの実装に反映させます。
最後に、enebularからHerokuアプリへデプロイします。
Free Dynoの場合は、スケジューラーも設定します。

# 実際に運用してみた感想

筆者の住んでいる地域では、冬期に水道管が凍結して破損する事例は珍しくないです。
かといって、毎日凍結するおそれがあるかといえばそうでもないので、うっかりすると水抜きするのを忘れてしまいかねません。

実際に毎日メール通知が来てわかったことですが、このような仕組みは注意喚起として有効だということです。

意外と印象に残っているらしく、就寝前などに「今日は水抜きしないと！」という風に思い出せることが何度かありました。

このような「自動で教えてくれる」仕組みは地味ですが、便利だと感じました。

![image-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303867/8c981600-36e2-16b4-9682-5c174e65c8d8.png)


# 参考リンク

- [Webサイトを定期的にチェックする](https://blog.enebular.com/samples/check-the-web-site-regularly/)

- [メール・ノードを使おう](https://blog.enebular.com/nodes/letsuse-emailnode/)

- [Herokuにデプロイしたアプリを眠らせない方法](https://blog.enebular.com/samples/heroku-unsleep-free-dyno/)

    ”無料のスケジューラーを使う方法” を参考にしました。
NoSQLの設計メモ


NoSQLの設計の記事一覧。
何か他にいい記事とか情報あれば嬉しいです。


https://qiita.com/ne-peer/items/86c154574f5bc34e4355

https://gist.github.com/matope/2396234

https://qiita.com/_kensh/items/2351096e6c3bf431ff6f

https://masa-w.hatenablog.com/entry/20101130/1291084939

https://www.slideshare.net/recruitcojp/rdbnosqlnosql

https://honey8823.hateblo.jp/entry/2016/01/19/122819
バッチ動いてませんでした & 動きすぎてました

# 何があった

## 動いてませんでした

デイリーでデータを集計するバッチ処理を作成。
テストでも問題なく動作したので、本番リリースし、cronにスケジュール登録。
リリースしてから1週間後・・・、**「集計結果全然ないんだけど」**

## 動きすぎてました

デイリーで古いデータを削除するバッチ処理を作成。
テストでも問題なく動作したので、本番リリースし、cronに深夜に実行されるようスケジュール登録。
リリースしてから1週間後・・・、**「深夜のバッチ昼ごろまで動いてるんだけど」**

# どうしてそうなった

## 動いてませんでした

プログラムは問題なかったものの、それを呼び出すシェルの記述がミスっていて、本番で一度も実行されてませんでした。

## 動きすぎてました

本番データがでかすぎて、テストでは数分で終わっていた処理が数時間かかるようになってしまっていました。

# どうすればよかった

- 本番でcronの設定を変更したときは、スケジュール通り動いたか確認しましょう
- シェルもテストしましょう
- 本番データでもテストしてみましょう
Laravelのログで配列を見る

# 配列を出したいとき
```php
Log::info($array);
```

# ログの場所
```
storage/logs/日付のログ
```

# デバッガとログの違い
VSCodeのデバッガで見えるデータは、
配列数やプロパティ数が多くなると切れて表示されない時がある。

ログは正確なので、ログの方が信頼できる。
単体テスト自動化について独り言

技術的なことはなく、単体テストただの独り言ですのでブラウザバックしていただいてOKです。

CD/CIが気になるお年頃で、単体テストを自動化について考える機会が増えたので備忘録的に残したいと思います。
手動・自動どちらで単体テストを実施するにしても、下記は一般的なことだと思いますが、しかし私は納期に追われて蔑ろにすることが多かったです・・・。

- 単体テスト設計
- データ設計
- 単体テスト実装
- 単体テスト実施

改めて過去のソースコードを見直して、そのコードたちに単体テストテストコードを施してやろうとしたときに、いくつかの壁にぶち当たりました。
一言でいうと、**煩雑**。

具体的にいうと・・・。

- データをイジイジするところは、エンジニアごとにバラバラ
- 似たような関数もチラホラ
- 共通化や部品化してないので1関数が超大作
など

結果からいうと、既存のソースに対してテストコードを書くのは**断念**しました。
単体テストコードを適用するにしても、課題が割と足を引っ張るので、作業コストがかかりすぎてしまう。

共通化・シンプル設計などの重要性を感じました。

- テーブル設計もシンプルに→データ設計・テストデータの実装のスピードUP↑
- 共通化→テストコードの実装コストDOWN↓
- シンプル設計（メソッドの細分化）→テストコード実装コストDOWN↓、テスト設計コストDOWN↓

CI/CDの関連知識として、Gitlab連携など記事書いていますので、このあたりの課題感についても個人的な解決策を記事にしていきたいと思います。
高級ストレージを放置していた件

# 何があった

**金の力で**パフォーマンス改善するため、DBを入れていたベアメタルのサーバに高速ストレージの**Fusion-io**を導入することになりました。

Fusion-ioを入れた結果、パフォーマンスは改善し、「やっぱFusion-ioってすげーんだなー」みたいな話をすること**2年**。

**Fusion-io**使ってませんでした。

# どうしてそうなった

サーバを構築したエンジニアが設定をミスっていて、Fusion-ioをマウントしたドライブとは別のドライブをDBのストレージとして使っていました。

別件でサーバの設定変更をするタイミングで発見されました。

**パフォーマンスが改善したのは別の要因だったようです。**

数百万のストレージを2年間置き物としてだけ使っていました。

# どうすればよかった

- Zabbixなどを使って、インフラを数値的に管理しましょう。
- サーバの設定などはGitなどで情報共有とか難しいので、複数人でレビュー・チェックしましょう。
フォームデザインについて考えたこと 〜2021〜

この記事は「弁護士ドットコム Advent Calendar 2021」の 20 日目の記事です。
昨日は @NaokiTsuchiya さんでした。

# はじめに

弁護士ドットコムでエンジニアをしている @blkclct です。2021 年は，フォームのフロントエンド側を実装する機会が多い年になりました．ログインフォームや，会員登録フォーム，問い合わせフォームなど，どのアプリにもありそうなものを，ゆっくり検討するいい機会をいただきました．検討した中で，最低限この辺りは押さえておくとよさそうだな！と思ったものを何個かピックアップして紹介します！そんなの当たり前だよ！という内容もあるかもしれませんが，お手柔らかに．

# 参考にした文献

最初にフォームのことを考える上で参考にした文献を紹介しておきます．

* [Form Design Patterns シンプルでインクルーシブなフォーム制作実践ガイド|Adam Silver,土屋 一彦,株式会社Bスプラウト](https://www.amazon.co.jp/dp/4862464513/)

フォーム実装の基本的なことを,様々なフォームを元に，網羅的にまとめられているのでおすすめです．

# フォーム実装のいろは

フォーム実装におけるフロントエンド側の役割の大部分はユーザビリティを担保してあげることだと思っています．こちらを踏まえた上で読んでいただけると助かります．

## maxlength を指定しない

HTML の input 要素や textarea 要素に対して，maxlength 属性を指定するのは，（フォーム実装に関しては，）必要になるケースはないと思っています．
例えば，input 要素の場合，意図しない文字の切り詰めが起きて，それをユーザーが気づかない可能性があります．スマホだと画面幅が狭かったりするので，割と起きると思っています．
特に，パスワードフォーム実装で，input 要素の `type="password"` で文字長に切り詰めが起こるとまずいので，絶対指定しないようにした方がいいと思います．たまに遭遇するんですが，登録フォームでは，maxlength 指定があって，ログインフォームでは指定ないとかだと一生ログインできなくて泣きます．

Twitter のように 140 文字制限があるのであれば，それを入力中もしくは，submit 時にその旨をフィードバッグしてあげればいいだけの話だと思います．

## バリデーションのルールの明示する

こちらもユーザビリティ観点なのですが，基本的に入力フォーム付近に，バリデーションルールの明示もしくは例示を入れるべきだと思います．submit しないとエラーがわからないような仕組みはよくないと思っています．またパスワードフォームの話になりますが，パスワードフォームは，ルールが複雑な場合が多いと思うので，登録時にはルールを明示してあげることは必須だと思います．何度もエラーを返していると，ユーザをイライラさせ，離脱の原因になり，結果 CVR などにも影響が出ると思います．

## submit ボタンに disabled 属性をつけない

よく最後に利用規約にチェックを入れないと submit ボタンが活性化されない仕様があると思いますが，それについてです．
こちらは賛否両論ありそうですし，実際ものによると思います．disabled を入れたほうが都合のいい UI もあると思います．ただ，僕は基本的には，入れなくていいと思っています．
この仕様があることで，まず，ユーザーはボタンを有効化するために，どれを入力しないといけないのか考えることを強いなければなりません．その時点で入力ハードルは上がりますし，実装者視点でも，実装もデザインも複雑になりがちです．また，そのフォーム自体の拡張性を悪くすると思っています．最初は，シンプルで簡単だったフォームも仕様が変わり，複雑になっていくかもしれないので，それに備えて最初から，disabled 属性は使わず，submit イベントが起きてからエラーを発生させてユーザーにエラー内容を伝える方法にした方がいいと思ってます．今回の記事では，あまり触れていなかったのですが，アクセシビリティの観点でも，`aria-disabled` を使いつつ，状態を伝えることはできますが，何を入力しないといけないかまで伝えるのは，また大変だったりするのでおすすめできません．

## HTML 最低限正しく書く

意外と漏れてたりするのですが，フォームの各要素について，HTML を正しく書いてあげることは，当然ですが，大切です．モバイル端末で，入力するユーザーに恩恵を得られるので．
特に，最近では，パスワードや個人情報を自動入力させるアプリケーションを使っているユーザーが増えていると思うので，それを使えるよう正しく HTML を書いてあげなければいけないと思ってます．

最低限抑えておくべきなのは下記2点です．

* **input 要素の type 属性を正しく設定する**
* **input 要素の name 属性の値を適切に設定する**

### input 要素の type 属性を正しく設定する

こちらは，例えば，電話番号の入力欄で，`<input type="text" name="tel" />` とするのではなく，`<input type="tel" name="tel" />` と正しく設定するという話だけです．こちらは，特にこれ以上ないです．

### input 要素の name 属性の値を適切に設定する

input 要素の name 属性はデタラメにつけるのではなく，意図に合った命名にした方がいいという話です．なぜかというと，name 属性が適当だったりすると，ブラウザの自動入力補完が働かなったりするためです．
また，name 属性に加えて，[autocomplete](https://developer.mozilla.org/ja/docs/Web/HTML/Attributes/autocomplete) 属性を使って正しい値を当てることも大切です．name 属性の値がよくなくても，補完が効くようになるはずです．

このあたりの話は，ics.media さんの掲載記事である，[今どきの入力フォームはこう書く！](https://ics.media/entry/11221/)に詳しく書いてあったので見てみて下さい！

# 余談

## フロントエンドとバックエンド両サイドのバリデーション管理

今年中にいい結論が出なかったのですが，フロントエンドとバックエンドのバリデーションルールをいい感じに同期させる方法について頭を悩ませました．バックエンド側で仕様が変更されたときにフロントエンド側も同時に変更しないといけないのはつらいよな．．という話です．昨今のフロントエンドではリッチな UI が求められがちで，複雑な状態管理を行う都合上，結構変更入れないといけないとかになる，よりつらいよなーと思ってます．
何かいい方法はないだろうか．．いい方法があればご教示いただきたいですmm

# おわりに

以上になります．実装については，ほぼなく，ポエムっぽい記事になってしまいましたが，ご容赦ください．
最後まで読んでくださりありがとうございました！

明日は，@edi_t さんです．お楽しみに！
Azure Portal上で特定のAzure Blob Storageのみ閲覧可能にする

[**セゾン情報システムズ Advent Calendar 2021**](https://qiita.com/advent-calendar/2021/sisco) 19日目の記事です。
特定のBlob Storageのみに閲覧権限を付与する方法です。

# 設定内容
* ストレージアカウントのIAMで「ストレージ BLOB データ閲覧者」と「閲覧者」の2つのロールを付与する必要があります。
* 一見「ストレージ BLOB データ閲覧者」のみでよさそうですが、「閲覧者」ロールがないとポータル上で表示できないため注意が必要です。このあたりは [公式ドキュメント](https://docs.microsoft.com/ja-jp/azure/storage/blobs/assign-azure-role-data-access?tabs=portal) にも書かれています。

# やってみます
* 該当のストレージアカウントのIAMから[ロールの割り当ての追加]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/1fff3a14-81c1-1981-4922-032c00c2b9a6.png)

* まずは[閲覧者]ロールを選んで次へを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/b18a2611-3c65-6464-47ac-eb9330195683.png)

* ロールを付与するユーザーを選択し権限を割り当てます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/1b2fef34-8ab1-78a0-2648-127555ba2e9c.png)

* 同じように「ストレージ BLOB データ閲覧者」ロールも付与します。

# ポータルからどう見えてくるか
* ポータルにログインして[すべてのリソース]を見てみると、先ほど権限付与したストレージアカウントだけが表示されていることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/2c12960e-69d6-6c65-ccf6-77450039b5ac.png)

* オブジェクトが表示できてますね。ダウンロードもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/9e4ed93d-f674-7209-3303-fe4a2df2fff9.png)

* コンテナーにオブジェクトをアップロードしようとすると403エラーになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/42cc1752-6785-2d85-57e7-ca9f297500b0.png)

* 「ストレージ BLOB データ閲覧者」だけだとAzure Portalにリスト表示する権限を持たないところが注意が必要ですね。

以上
IPアドレスの枯渇

# なにがあったのか

わい「なんか社内LANつながらないのだけど」

ネットーワーク管理者「あれ？DHCPで払い出されるIPアドレスが全部払い出されちゃって、無くなっちゃってる。まだまだ余裕あったはずなのに」

わい「先週から来た会議室１室にこもっている10人くらいの外注さんのせいでは？」

ネットーワーク管理者「いや、それでも１０個使われるくらいなら全然問題ないはずだったんだけどなあ。ちょっと見てくるわ。」


**結論、外注さんがWiFiルータ持ち込んでました。**

その会議室にあったLANケーブルにWiFiルータを接続し、各メンバーがPC、スマホ、音楽プレイヤー、ゲーム機など色々つなげまくった結果、**外注さん10人で50個以上のIPアドレスを使用していました**。

# どうしてそうなった

あるとき外注さん10人くらいに常駐で仕事してもらうことになり、会議室１室をその外注さん用に割り当てて自由に使ってもらっていました。
ネットワークは基本は有線LANで、仕事上WiFiが必要な人だけネットワーク管理者につなげたい機器のMACアドレスを教えてWiFiを使えるようにしてもらっていました。

それだと不便に思ったのと、会議室１室貸切でレンタルオフィス感覚になったのか、自由な環境を勝手に構築されてしまいました。

状況を伝えてすぐに止めてもらいました。

# どうすればよかった

相手の良識に任せて、明確にこちらもセキュリティポリシーを伝えていなかったのが問題でした。

が、**普通、客先のネットワーク勝手にそんな使い方しないよね**って思ったエピソードでした。
migrationのrollbackの注意点（dafault値の取り扱い）

# TL;DR
migrate後のmigrationファイルを書き換えると、データの値が荒れがち。
rubocopに「直したほうが良い」と言われようとも、migrationファイルは書き換えないのが基本。
(自戒の念を込めて記事化)

# 状況
rubocopで静的解析をかけた時のお話。
こんな表示が出ました。

```ruby:rubocop実行画面
db/migrate/20210827131348_add_activations_to_users.rb:9:5: 
C: Rails/BulkChangeTable: 
You can use change_table :relationships, bulk: true to combine alter queries.
```

「add_columnを何度も重ねずに、add_tableで一括変更してくれ」とのことなので、
そのように変更。


# やったこと

"rails db:migrate:status" => ID確認。
"rails db:migrate:down　VERSION=xxxxxxx" => downに

その後、migrationファイルを変更してmigrate実行

```ruby:migrationファイル
class AddActivationToUsers < ActiveRecord::Migration[6.1]
  def change
    add_column :users, :activation_digest, :string
    add_column :users, :activated, :boolean, default: false
    add_column :users, :activated_at, :datetime
  end
end

↓

class AddActivationToUsers < ActiveRecord::Migration[6.1]
  def change
    change_table :users, bulk: true do |t|
      t.string :activation_digest
      t.boolean :activated, default: false
      t.datetime :activated_at
    end
  end
end
```

# 結果
既に開発環境で存在しているuserのdefault値が変化。
default値は新規作成の時だけ効果発揮するのだと思ってたけど、違うのね…。

```ruby:console
[1] pry(main)> User.find(1)
  User Load (0.9ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
=> #<User:0x000055d27e9d5548
 id: 1,
 name: "正太郎",
…
 activated: false,   # migration前はactivated: trueだった
```
このままデプロイすると、本番環境のデータベースに格納されている値も変化してしまって、非常によろしくない。。

# 改善
- migrationによってでデータベースに格納されている値を変えてしまうのはよろしくない。
基本的にはmigrationファイルの書き換えはしない。
DBの変更するときはremove_columnとか、change_defaultとか、変更履歴がわかるものにとどめるのが無難だと推察される。

- rubocop.ymlは以下の通りに変更

```ruby:rubocop.yml
  Exclude:
    - 'db/**/*'
```

- そもそも、本番環境に関しては定期的にバックアップをとりましょう。
リマインドツールで少しでもストレスを減らそう

# はじめに
本記事は、[サムザップ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/sumzap) の12/20の記事です。
昨日の記事は @takahashi-kenichiさんの「「ピグパーティ」で数百に及ぶFlash製のモーションデータをSpineに変換した話」でした。

今回は、日々業務で、頻繁に発生するリソース組み込み作業のストレスになっていたスケジュール管理をリマインドツールで緩和することができたので、その紹介になります。

# 背景
現在、私は運用プロジェクトに所属しています。
運用プロジェクトでは、月に複数のイベントがリリースされ、必要となるリソースは数多くあり、それらを短期間で用意しなくてはなりません。
お客様を楽しませるためにクオリティの高い画像等の作成することはもちろん大事ですが、バグがない品質の高いイベントをお客様にお渡しすることも大切なことです。
品質向上させるためには、QAのデバッグ作業をしっかり行う必要があり、十分な確認時間を確保しなくてはいけません。
そのため、**あらかじめ決められたスケジュール通りにQA確認が開始できるように準備しておくことが重要になります。**

# 遅れてしまうスケジュール
現在は以下のフローでイベントのリソースを用意しています。
1.プランナーが仕様を決め、必要なリソースをデザイナ-に発注する
2.デザイナーがリソースを制作、エンジニアに納品
3.エンジニアがリソースを組み込み、QAに渡す
4.QAのチェックをし、問題がなければリリース
![フロー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249963/13fd7608-51c9-c310-e07a-81e8ba5c6520.jpeg)
しかし、日々の他のタスクと並行で作業していると、<font color="red">リソースの組み込み作業を締め切り日までに準備することを忘れてしまうこともあり、しばしばQAに迷惑をかけていました。
また、運用スケジュールを常に意識しておく必要があるのは、とてもストレスが溜まりました。</font>
![フロー２.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249963/edda6aed-ed31-07b7-d88d-b8fef2c81b47.jpeg)

# リマインドツール
この遅延問題を解決するために、組み込み忘れの防止のためにリソース組み込みの締め切り日を通知するツールを用意しました。
運用スケジュール（Googleスプレッドシート）を確認し、組み込み完了されていないといけないリソースかつタスク管理ツール（Wrike）でステータスが完了になっていないものを締め切りの3日前、前日にSlackで通知します。

![リマインドツール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249963/eb9f2450-07ee-5ce5-c8ff-ffb7e7a28f6f.png)
上図）リマインドツールからSlackに投稿された通知


![運用スケジュール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249963/7e191455-62a5-8933-9cc9-4e936e8c29fe.png)上図）Googleスプレッドシートで管理されている運用スケジュール（実際のものを簡易化したもの）


![wrike.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249963/c4598d24-ad01-d0e8-7bdf-e17fab147dbe.png)
上図）wrike(タスク管理ツール)で管理されているリソース組み込みタスク

# 通知の流れ
![system.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249963/d27523eb-7f59-b173-34d1-d31143b6ba9d.jpeg)
リマインドツールは以下のフローで通知してくれます
1. AM10:00でGoogle Apps Scripts(GAS)が実行される
2.運用スケジュールで通知すべきイベントはないかを抽出
3.通知するイベントの関連し、未完了のステータスになっているリソース組み込みのタスクをないかをwrikeで確認
4.通知すべきタスクがあれば、Slackで通知
# 結果
簡単に作れるシンプルなリマインドツールですが、効果はかなりありました。
リソース組み込みをするスケジュールをリマインドツールに外部化させたことで、常に意識をしておかないといけないというストレスから解放されました。また、リマインドツールを導入してから、リソースの組み込みの遅れによるQAのスケジュールを遅延はなくなり、当初の目標は達成できました。
リマインドツールを作成から導入を通して、今後も人がやるべきところ、自動化すべきところはしっかり区別をし、開発の効率化、ストレスの解放を積極的に進めたいなと思いました！
最後まで読んでいただき、ありがとうございました。

明日は @Buna_unity_game さんの記事です。
Azure Cognitive Servicesについてまとめてみた。

#はじめに
Azureが提供しているAIサービスのAzure Cognitive Servicesですが提供している機能が多いのでどんな機能を提供しているのかをざっくりまとめてみました。

#Cognitive Services の主なカテゴリ
Cognitive Servicesは主に下記の5つのカテゴリーに分けられています。
・視覚
・音声
・言語
・決定
・検索

##視覚に関するCognitive Services
・Computer Vision　Service
→画像からテキストの抽出、特定のブランドや物体の検出や空間分析の機能です。

・Custom Vision Service
→独自の画像識別子モデルを構築、デプロイ、改良できるようなる機能です。


・Face　Service
→画像に含まれている人の顔の検出、認識、分析する機能です。
また、検出した顔の年齢、感情、ひげの有無、眼鏡の有無を予測することもできます。

##音声に関するCognitive Services
・Speech Services
→こちら、前回の記事でご紹介した機能です。
音声テキスト変換、テキスト読み上げ、音声翻訳を提供するサービスです。

https://qiita.com/popo-kc/items/8b5fddc4cf6cb112defb

##言語に関するサービス
・Azure Cognitive Service for Language
→NLU を使用し非構造化テキストから情報を抽出、尋ねられている質問に対する回答する機能です。

・Language Understanding LUIS
→自然言語での会話テキストに適用して、全体の意味を予測し関連性のある情報を引き出す機能です。

・QnA Maker
→任意の入力に対して、カスタム ナレッジ ベースの情報から最も適切な回答を見つける機能です。
主にチャット ボットなど、会話型クライアント アプリケーションの作成に使用されます。

・Translator
→ほぼリアルタイムでのテキスト翻訳を提供する機能です。

##決定に関するCognitive Services
・Anomaly Detector 
→時系列データを監視し、その中の異常を検出する機能です。

・Content Moderator 
→不快感を与えたり、望ましくなかったり、危険であったりする可能性があるコンテンツを監視する機能です。

・Personalizer
→ユーザーのリアルタイムの動作から学習し、ユーザーに表示する最良のエクスペリエンスを選択できるようにする機能です。

##検索に関するCognitive Services
・Cognitive Search
→weアプリやモバイルアプリなどにプライベートで異種のコンテンツに対するリッチな検索エクスペリエンスを組み込むことが出来る機能となっております。

#まとめ
ざっくりとですが、Cognitive Servicesの機能を紹介しました。
Cognitive Servicesを利用することで人工知能やデータ サイエンスに対して知見がなくても簡単にアプリケーションなどを多機能にすることが出来るの今後はより詳しくご紹介していきます！
TypeScript で未使用のパラメータを書くと怒られる件

# 結論

TypeScript の関数定義で、使用しないパラメータを書くときは、パラメータ名をアンダースコアで始める。

例:

```ts
app.use((_req, _res, next) => {
  next();
});
```

# 説明

例えば`express-generator`でExpressのテンプレートを生成したとき、存在しないパスへのリクエストを処理するのに次のようなコードが作られる。

```ts
// catch 404 and forward to error handler
app.use((req, res, next) => {
  next(createError(404, '存在しないパスへのリクエストです'));
});
```

参考: [express-generatorで生成したapp.js のコードを1行ずつ解読](https://qiita.com/oekaki-hoho-ron/items/e9c67c0075652c5fc3b6)

JavaScriptのままなら問題ないが、TypeScriptの場合、`req`, `res` の部分で怒られる

```
'req' が宣言されていますが、その値が読み取られることはありません。ts(6133)

'res' が宣言されていますが、その値が読み取られることはありません。ts(6133)
```

パラメータ名の先頭にアンダースコアをつけると解決する。つまり `req` を `_req` , `res` を `_res` にする。

```ts
// catch 404 and forward to error handler
app.use((_req, _res, next) => {
  next(createError(404, '存在しないパスへのリクエストです'));
});
```

これなら怒られない。
laravelの同じことができるので困るやつを集めてみた。

## 指定された値を「ドット」記法でネストされた配列から取得
### ヘルパークラスの静的な関数 or ファサード
```php
$price = Arr::get($array, 'products.desk.price', 1100);
```

### ヘルパー関数
```php
$discount = data_get($data, 'products.desk.discount', 0);
```

## viewインスタンスを返す
### ヘルパークラスの静的な関数 or ファサード
```php
return View::make('profile');
```

### ヘルパー関数
```php
return view('profile');
```

## authenticatorのインスタンスを返す
### ヘルパークラスの静的な関数 or ファサード
```php
$user = Auth::guard($guard)->user();
```

### ヘルパー関数
```php
$user = auth($guard)->user();
```

## キャッシュから値を取得する
### ヘルパークラスの静的な関数 or ファサード
```php
$cache = Cache::get('key');
```

### ヘルパー関数
```php
$value = cache('key');
```

## debugレベルのメッセージをログへ書き出す
### ヘルパークラスの静的な関数 or ファサード
```php
Log::debug('An informational message.');
```

### ヘルパー関数
```php
logger('An informational message.');
```

## バリデータインスタンスを生成する
### ヘルパークラスの静的な関数 or ファサード
```php
$validator = Validator::make($data, $rules, $messages);
```

### ヘルパー関数
```php
$validator = validator($data, $rules, $messages);
```

他にも色々ありますがプロジェクトどちらの記載をどの処理層で使用するかは
決めておくと読みやすくなるとおもいます。
クリスマスの飾りつけを。

クリスマスまで1週間を切りました。
せっかくのキリスト生誕カウントダウンなのでクリスマスに関連したブラウザ上でできる何かを作ってみようと思いました。
作ったのはリースをドラッグ＆ドロップで飾り付けしてから画像がダウンロードできるというもの。

![q3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351246/8b82155b-309f-6831-46db-6a56975ac33d.jpeg)
↓実際のページ。
https://unt-nakaji.github.io/create-xmas/index.html

## つかったもの
Canvasダウンロードはhtml2canvasを使用しました。
https://html2canvas.hertzen.com/

SVG素材は配色数とパス数を考慮して作ってみました。


## 詰まったところ

1. svgをimgタグで表示し、Canvasで書き出すとviewBoxがずれる（Chromeブラウザ）
- svgをuseで使用するとCanvasに描写されない（Chromeブラウザ）
- Android端末で上部をドラッグするとリロードされる


## 1.viewBoxがずれる
1. svgファイルをimgタグで表示し、Canvasで書き出すとviewBoxがずれる
ブラウザ上では問題ないように見えてダウンロードすると拡大されている状態でした。

後々思えばもしかして、.svgファイル内で調整をうまくできればよかったのかも。。
最終的にSVG書き出しをプレゼンテーション属性にしてベタ書きにしてviweBoxを調整しました。

## 2.useで使用するとCanvasに描写されない（Chromeブラウザ）
書き出しをすると透明になってしまう。
調査不足ですがuseを使わなければ問題なさそうだったのでuseは使わない方向で進めました。

## 3.Android端末で上部でドラッグするとリロードされる
[pull-to-refreshの問題](https://support.google.com/chrome/thread/8121253/%E3%82%A6%E3%82%A7%E3%83%96%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%A7%E3%81%AE%E3%82%B9%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%AB%E3%81%8C%E7%AA%81%E7%84%B6%E3%80%81%E5%86%8D%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86%E3%80%82-%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5%E3%82%84%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E5%89%8A%E9%99%A4%E3%82%92%E3%82%84%E3%81%A3%E3%81%9F%E3%81%8C%E5%8A%B9%E6%9E%9C%E3%81%8C%E3%81%AA%E3%81%84%E3%80%82-%E8%A7%A3%E6%B1%BA%E7%AD%96%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%81%8B%EF%BC%9F-%E3%82%B9%E3%83%9E%E3%83%9B-android-%E3%81%A7%E3%81%99%E3%80%82?hl=ja)

長年Androidユーザーだったのですが、
一昨日Android12にアップデートした瞬間出た問題でびっくりしました。
スクロールを強制的にとめるために縦幅はoverflow:hidden;で切り落とし、
JSにタッチ無効化を入れるのがよさそうと判断しました。

## はじめてやったこと
ラジオボタンと:checkedを使って背景色切り替えました。

```css:index.html
<div class="bg-container">
 <input type="radio" name="bg" id="bg-1" checked>
 <input type="radio" name="bg" id="bg-2">
 <input type="radio" name="bg" id="bg-3">
 <div class="imgbox">
  <div class="bg-item bg-color1"></div>
  <div class="bg-item bg-color2"></div>
  <div class="bg-item bg-color3"></div>
 </div>
</div>
```
```css:style.css
#bg-1,#bg-2,#bg-3{
  display: none;
}
#bg-1:checked ~ .imgbox .bg-item:nth-child(1){
 opacity: 1;
}
#bg-2:checked ~ .imgbox .bg-item:nth-child(2){
 opacity: 1;
}
#bg-3:checked ~ .imgbox .bg-item:nth-child(3){
 opacity: 1;
}
```

## まとめ
解決したい課題は多いですがひとまずやりたいことが
ブラウザ上で可能なことまで確認できたのでよかったです。

SVG難しい…！またどこかで深掘りしたいです。
mysql -u root -pで「ERROR 1045 (28000): Access denied..」「The server quit without updating PID file ...」が表示された時の解決法

# 実施環境
### ハードウェア環境
| 項目 | 情報 |
|:-:|:-:|
| OS  |macOS Catalina(10.15.7)   |
|ハードウェア   |  MacBook Air (11-inch, Early 2015) |
|プロセッサ   | 1.6 GHz デュアルコアIntel Core i5|
|メモリ   |  4 GB 1600 MHz DDR3 |
|グラフィックス   |  intel HD Graphics 6000 1536 MB |
### ソフトウェア環境
| 項目 | 情報 |
|:-:|:-:|
| homebrew  | 3.3.8 |
| mysql | Ver 8.0.27 for macos10.15 on x86_64 |

# 早速
[こちら](https://qiita.com/shintarou-akao/items/9993853c61e903655c35)の記事を参考に、

```
mysql.server restart
```
でサーバを再起動させる。

すると

```
Shutting down MySQL
... SUCCESS! 
Starting MySQL
.. ERROR! The server quit without updating PID file (/usr/local/var/my..
```
とのエラーに遭遇。

#PID fileって何？？
メモリを使って動かすプログラム一つ一つのことを**プロセス**と呼ぶが、そのプロセスが作成されたときに自動的に付与されるのがプロセス識別子(Process ID→PID)。
そしてこのPIDが書かれているファイルがPIDファイルである。

# The server quit without updating PID file ...

[こちら](https://qiita.com/busitora2/items/36681f9356c564a62b0b)の記事を参考に
- 権限の変更
- PCの再起動
- プロセスkill
と試したが、エラー文は変わらないため、最終手段であるMySQL入れ直しを図る。
完全に[こちら](https://qiita.com/akiko-pusu/items/aef52b723da2cb5dc596)の記事を参考にしてhomebrewを使ってMySQLを再インストール、、、、、

```
mysql.server start
Starting MySQL
......... SUCCESS!
```
完了！！！

# /usr/local/opt/mysql@5.7/bin/mysql: No such file or directory.....
これでイケたと思い、最後にもう一度```mysql -u root -p```を実行するも、、

```
/usr/local/opt/mysql@5.7/bin/mysql: No such file or directory
```
PATHが通っていないよう。

```
$ echo 'export PATH="/usr/local/opt/mysql@5.7/bin:$PATH"' >> ~/.bash_profile
$ source ~/.bash_profile
```
もう一度```mysql -u root -p```、、、、

```
mysql>
```
できた！！！
PID file参考
https://hirocorpblog.com/post-487/
https://wa3.i-3-i.info/word11040.html
[Amplify] 多対多のリレーション作成後、queriesが正しく生成されない

## はじめに
これもDB操作に不慣れな弱々フロントエンドエンジニアのつまづき記録です~~~

## 環境
amplify
GraphQL
Next.js


## 状況
- GraphQLスキーマ　にて多対多のリレーションを作成した後に、createやdeleteはできるが、ローカルだとquery叩くとリレーションしたデータが返ってこない、、、


- amplify mock apiして、モックURL上でクエリを叩く分には、多対多のリレーションデータも返ってくる

![スクリーンショット 2021-12-20 8.49.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/750557/5c525d27-0190-6d1d-31d1-f473da78a51e.png)



```schema.graphQL

type Resource @model {
  id: ID!
  categoryId: ID!
  userId: ID!
  title: String!
  url: String!
  category: Category @connection(fields: ["categoryId"])
  users: [ResourceUser] @connection(keyName: "byResource", fields: ["id"])
}

type ResourceUser
  @model(queries: null)
  @key(name: "byResource", fields: ["resourceId", "userId"])
  @key(name: "byUser", fields: ["userId", "resourceId"]) {
  id: ID!
  resourceId: ID!
  userId: ID!
  resource: Resource! @connection(fields: ["resourceId"])
  user: User! @connection(fields: ["userId"])
}
type User @model {
  id: ID!
  name: String!
  email: String!
  profileImagePath: String!
  progressRate: Int!
  resourcesCount: Int!
  posts: [Post] @connection(keyName: "postsByUserId", fields: ["id"])
  resources: [ResourceUser] @connection(keyName: "byUser", fields: ["id"])
}


```

## 結論

下記で解決します！！

```


$ amplify configure codegen
? Choose the code generation language target javascript
? Enter the file name pattern of graphql queries, mutations and subscriptions src/graphql/**/*.js
? Enter maximum statement depth [increase from default if your schema is deeply nested] 4

```


```
$ amplify codegen
â Downloaded the schema
â Generated GraphQL operations successfully and saved at src/graphql


```


## 参考資料
https://github.com/aws-amplify/amplify-cli/issues/2818

##  終わりに
「デフォルトで4で設定しといてよ、amplifyさん」って心から思いました笑
Xcodeのアップデートがおわらないときの対処法

# 対処法
アップデート時にダウンロードが終わってそうなのに不安になる時があるので、対処法を書いておきます。

1. コンソールで進行状況を確認する
1. AppleDeveloperからインストールする

## コンソールで進行状況を確認する
1. コンソールを開く
1. デバイスを選択
1. 「ストリーミングを開始」又は「開始」をクリック
1. 検索バーに「appstore」を入力
1. ログのメッセージ部分に「completed」と表示されているのが流れてくるので進行状況を確認

そもそもかなり時間がかかるので、寝る前にアップデートするといい感じに終わってます

## AppleDeveloperからインストールする
コンソールで確認して、ダウンロードが止まっている場合はAppleDeveloperのサイトから直接ダウンロードする
[AppleDeveloper - Xcode](https://developer.apple.com/download/all/)
【Rails】GETでリクエストボディを利用しない方がよい理由

# はじめに

Web APIを開発する場合、必要なパラメータを取得する方法はいくつか存在します。

1. URLパラメータ
1. リクエストヘッダ
1. リクエストボディ

> リクエストの最後の部分が本文です。本文が存在しないリクエストもあります。リソースを取り込むリクエストである GET, HEAD, DELETE, OPTIONS は通常、本文は不要です。サーバー内のデータを更新するためにデータを送信するリクエストもあり、 POST リクエストでよくあります (HTML フォームのデータを持つ)。

参考: https://developer.mozilla.org/ja/docs/Web/HTTP/Messages#body

# GETでリクエストボディを利用したらどうなるか

そもそもGETメソッドはリソースを取り込むリクエストであるため、リクエストボディを用いなくても要件を実現できるはずですが、実装次第ではリクエストボディを用いることができてしまいます。
ここでは、GETメソッドでリクエストボディを利用した場合のケースを解説します。

## 実例

実際の開発現場で書かれていたコード例を紹介します。

```ruby
class UsersController
  def index
    user_params
  end

  private

  def user_params
    params.require(:user).permit(:name)
  end
end
```

通常、ストロングパラメータはリソースを取り込むリクエストであるGETメソッドで不要です。
このようなコードを書いてしまうと、

```curl
curl http://localhost:3000/users/?name=Taro
```

というようなリクエストではなく、

```curl
curl -H "Content-Type: application/json" -d '{"name":"Taro"}' http://localhost:3000/users/
```

というような、GETメソッドなのにリクエストボディを要求するというAPIになってしまいます。
これは、`ActionController::ParamsWrapper` がデフォルトで、`application/json` を受け付けていることに起因しています。

`config/initializers/wrap_parameters.rb`

```ruby
ActiveSupport.on_load(:action_controller) do
  wrap_parameters format: [:json]
end
```
既存の動画にフィルターをかけたいなら、一枚一枚処理すべし

#既存の動画ファイルにフィルターをかける
カメラで撮りながらリアルタイムでフィルタをかけるのではなく、
既存の動画ファイルにフィルターをかける方法です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/30c8fa02-1b33-f137-a3dd-2ddf80067a03.gif"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/12612f6d-de10-318a-3183-b5e22ea97720.gif"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/546c5f1c-abd2-0f98-9c38-e117ee9d090c.gif">


#画像だけではなく動画にもフィルターをかけたい。しかもフィルターを設定して撮った動画ではなく、撮った後の動画にかけたい。
既存の動画にフィルターをかけられたら、オリジナルビデオを撮影した後で、隠したい部分にモザイクをかけたり、可愛いエフェクトを付け加えることができます。
撮影前にエフェクトを設定してリアルタイムで加工するサンプルはちらほら見かけますが、
元々ある動画にあれこれフィルターをかけるコードはなかなか見つかりませんでした。

###動画の一括処理はうまく動かなかった
アップル公式ドキュメントには、動画ファイルにフィルターをかける二つの方法が見つかりますが、
僕の手元ではうまく動きませんでした。
AVAssetにCIFilterをかけるAVVideoCompositionを作るイニシャライザも動作しなかったし、
CustomAVVideoCompositionクラスも、（ウォーターマークをつける画像合成はできた）CIFilterでは動かなかった。

#コマごとに分解して1枚ずつかけちゃえ

動画をコマごとに分解し、1枚ずつフィルターをかける。
そして、動画として再構成する。
これをすることで、1枚ごとに確実に処理できます。
1枚ずつ処理していたら、ものすごく時間がかかるんじゃないかと思いましたが、動画の長さの実時間程度でした。
メモリをちゃんと解放してあげると、クラッシュすることもありません。

#手法

AVAssetReaderで動画をフレームごとに読み込んで、
コマごとに分解した段階で、CIFilterの処理をはさみます。
そしてAVAssetWriterに書き込みます。

ポイントは、AVAssetWriterInputに直接サンプルバッファーを書き込むのではなく、
AVAssetWriterInputPixelBufferAdaptorというピクセルバッファーの受容器を作って、そこにフィルタリング後のピクセルバッファーを書き込む点です。

```swift
let pixelBufferAdaptor = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: assetWriterVideoInput, sourcePixelBufferAttributes: [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)])
assetWriter.add(assetWriterVideoInput)

...

let presTime = CMSampleBufferGetOutputPresentationTimeStamp(buffer)
pixelBufferAdaptor.append(filteredPixelBuffer, withPresentationTime: presTime)
```

これでいろんなCIFilterが動画に適用できるようになりました。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
簡単な開発内容をお書き添えの上、お気軽にご連絡ください。
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
CloudFrontのIP範囲の変更を検知してnginxのset_real_ip_fromを変更するプルリクを自動で作成する

CloudFrontを用いたWebアプリの構成にしている場合、接続元のクライアントのIPを正確に取得するにはCloudFrontのIP範囲を把握して管理しておく必要があります。
しかしCloudFrontのIP範囲は変更されるので、それを検知して都度対応する必要があるので少々面倒です。
なのでこの作業を簡略化したいと思います。

# CloudFrontのIPを設定すると何ができるか
CloudFrontのIPをnginxの`set_real_ip_from`に設定することで信頼できるIPだと判断されるので、接続元クライアントのIPが`REMOTE_ADDR`で判断できるようになります。そのため`X_FORWARDED_FOR`で判断することをせずに済み安全になります。

# IP範囲の変更をどうやって検知するか
Amazon SNSで通知してくれるものもありますが、今回は`https://ip-ranges.amazonaws.com/ip-ranges.json`を定期的に確認することで対応します。

# プルリク自動作成までのステップ
```
1. 公開されているIP範囲がnginxのconfと差分があるか確認
2.　　差分があればプルリクを作成  
```

やることはこれだけなのでGithubActionを使用して実現してみます。

# GithubAction
```yaml
jobs:
  update-if-ip-changed:

    runs-on: ubuntu-latest
    timeout-minutes: 10

    steps:
      - name: checkout master
        uses: actions/checkout@v2
        with:
          ref: master

      - name: update CloudFront IPs
        id: update-cloudfront
        env:
          FILE_PATH: path/to/set_real_ip_fromを記述するファイル
        run: |
          curl https://ip-ranges.amazonaws.com/ip-ranges.json \
          | jq -r '.prefixes | map(select(.service == "CLOUDFRONT")) | sort_by(.ip_prefix)[] | .ip_prefix' | awk '{print "set_real_ip_from " $1 ";"}' > $FILE_PATH

      - name: create PullRequest
        uses: peter-evans/create-pull-request@v3
        with:
          title: 'CloudFrontのIP範囲が変わったのでnginxに設定する'
          commit-message: 'feat: CloudFrontのIPをset_real_ip_fromで設定'
          branch: automated/update-cloudfront-ips
          base: master
          delete-branch: true
          reviewers: |
            hoge
            fuga
```


IP範囲を取得する際に`sort_by(.ip_prefix)[]`をすることで、管理しているIP範囲と差分が発生した時になるようにしています。
またステップがこれだけ簡易化できたのは、[peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request)のおかげです。このアクションが、コミットしてプルリク作成までを全て担ってくれるので、特にこちらで差分確認などの制御をする必要がありませんでした。（とても感動しました。）


## 動作確認
※動作確認のため、適当なIP範囲を設定しておきました。

![スクリーンショット 2021-12-19 0.19.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64174/170fc21e-3087-3277-61ae-ec4510f5201d.png)

無事に正しいIP範囲に変更するプルリクが作成されました。

# 最後に
作業的なプルリク作成って意外とあると思うので[peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request)こちらを使用すると色々できるかもしれません。
他にも、リリースイメージ作成時にイメージタグ更新のプルリクを自動で作成することをこのアクションを使用して行なっています。
ぜひ何かに使ってみてはいかがでしょうか。
受験談 AWS Certified Security – Specialty 認定

AWS Certified Security – Specialtyを受験しました。

受験される方の参考になりましたら。

# 前提
8月：SAA [(受験談)](https://qiita.com/h2m_kinoko/items/5179bcb73b6773771f79 "受験談 AWS Certified Solutions Architect – Associate 認定")
9月：SAP
11月：SOA [(受験談)](https://qiita.com/h2m_kinoko/items/0b05378d96f4246bbdd0 "受験談 AWS Certified SysOps Administrator - Associate 認定")
12月：SCS（←今回ココ）

SAA受験談に私のAWSの事前知識・経験が書いてありますが、業務等での経験はほぼゼロです。ひたすら試験勉強のために触ってた感じですが、試験を受ける順番も今思えば良かった気がします。SAA（SAP）で、AWSサービスやアーキテクチャの部分を広く知れて、その後にSOAで運用周りのサービスや知識を学び。

SCSはSOAを受けてからすぐに勉強を開始しましたが、SOAで勉強した内容が新しいうちにと思いました。登場するAWSサービスも重なるものが多いです。

SOAは2度落ちてますが、立て続けに受験してます。。。

![名称未設定.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119864/8b465703-674f-ea2e-3e02-91b3dafea94f.jpeg)

# 唯一の書籍

おそらくSCSの勉強をと思ったら、まず最初にこの本に出会うと思います。他に日本語書籍で相応しいのが現時点（2021年11月）では見当たらなかったです。

https://www.amazon.co.jp/%E8%A6%81%E7%82%B9%E6%95%B4%E7%90%86%E3%81%8B%E3%82%89%E6%94%BB%E7%95%A5%E3%81%99%E3%82%8B%E3%80%8EAWS%E8%AA%8D%E5%AE%9A-%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3-%E5%B0%82%E9%96%80%E7%9F%A5%E8%AD%98%E3%80%8F-NRI%E3%83%8D%E3%83%83%E3%83%88%E3%82%B3%E3%83%A0%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE/dp/4839970947

資格の試験勉強にあたり、全体像を把握することが大事だと思ってます。書籍だと目次や公式の「[試験ガイド](https://aws.amazon.com/jp/certification/certified-security-specialty/)」がそれにあたりますね。

ざっくりまずは概要や大項目を把握して、どのあたりの知識が必要かなどを知る。まずは敵を知ることからでしょうか。
という意味でも、この書籍はまとまっていてとても良かったです。40問の問題もついてますので、問題の雰囲気などもつかめると思います。ただ、試験合格という意味ではやはり足りない部分もあると思いますので、この書籍をベースに分からない言葉や理解できていない部分を別途調べるということを繰り返しました。

# 公式サンプル問題

こちらはどの試験にもありますが、公式サンプル問題で雰囲気を掴みます。SAAとSOAを勉強していたためか、比較的とっつきやすい印象でした。初見でSAAやSOAを見た時は手応えが違ったと言いますか。

https://d1.awsstatic.com/ja_JP/training-and-certification/docs-security-spec/AWS-Certified-Security-Speciality_Sample-Questions.pdf

# AWS BenchPrep認定試験練習

このサイトは今まで知らなかったのですが、たまたま辿り着きました。20問の模擬問題があります。SCSに限らずありますし、1つ1つの選択肢の解説もついててお勧めです。

https://amazonwebservices.benchprep.com/

# koiwaclub

なかなか模擬問題が少ない中、このサイトも活用しました。SCSに関しては25x7=175問の問題が載ってましたので、2周繰り返し、それでも理解が深まっていない部分はググったりして理解の定着をはかりました。

https://aws.koiwaclub.com/

# Googleスプレッドシート

スプレッドシートはAWS認定試験勉強当初SAAから活用しています。とにかくわからない言葉や問題などをスプレッドシートにまとめて、あとで見返したり試験直前の復習に使ったり。
ひたすらこの繰り返しでここまで。

# 実際の試験

見たことあるなという問題は5問くらいだった気がします。あと、これまで受けた試験と違い時間を全部使い切りました。自身の理解度の問題なのか、何が違ったのかわかりませんが、見直しを含めてギリギリでした。

また途中途中で長文問題が出てきますが、サッと一読して理解できなかった時は飛ばしてすぐに次の問題に着手しました。ここで丁寧に解いていたら時間が足りなかった気がするのと、全体を通してどれくらいで解き終えられるかが想像つかなかったので。集中力の問題もありますが、5問ほど飛ばした気がします。一通り最後まで進めてから、残った時間を見て見直し問題や未回答問題に着手すると良い気がします。

# まとめ

BlackBeltは試験対策というよりは、ながら読みするような感じで活用しました。もちろん実際は隅々まで読み込んで理解することが良いと思いますし、とてもよくまとまっていて神です。

当初はSCSまで受験するつもりはなかったのですが、割引クーポンがあるのと記憶があるうちに次を受けときたいという衝動にかられ、結果ここまできました笑

全冠制覇かされている人とかすごすぎ・・
Microsoft 認定: Azure の基礎（AZ-900）を受けてみた。

- [はじめに](#はじめに)
  - [Microsoft 認定: Azure の基礎（AZ-900）とは](#microsoft-認定-azure-の基礎az-900とは)
  - [受験動機](#受験動機)
  - [当該試験を無料で受験する方法](#当該試験を無料で受験する方法)
  - [受験時の筆者のレベル](#受験時の筆者のレベル)
- [勉強方法](#勉強方法)
  - [学習期間](#学習期間)
  - [参考書](#参考書)
  - [講座](#講座)
    - [講座の良かった部分](#講座の良かった部分)
    - [講座の不満な部分](#講座の不満な部分)
- [今後](#今後)

## はじめに
### Microsoft 認定: Azure の基礎（AZ-900）とは
Microsoftが実施する「クラウドの概念、Azureサービス、Azureワークロード、Azureのセキュリティとプライバシー、および Azureの価格とサポートに関する知識を証明」する認定資格です。   
試験の実施形態は、テストセンター（試験会場）か、オンラインでのCBT試験となります。  
出題範囲は以下となります。
- cloud concepts
- core Azure services
- core solutions and management tools on Azure
- general security and network security features
- identity, governance, privacy, and compliance features
- Azure cost management and Service Level Agreements  

詳細は[こちら](https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-900#certification-exams)を参照ください。  
※2021年10月25日に試験内容が更新されました。

### 受験動機
筆者が従事しているプロジェクトでAzure DataBricksを使用している関係でAzureに対する知識を少しでも習得する目的の一環で受験しました。

### 当該試験を無料で受験する方法
Microsoftでは定期的にVirtual Trainingを実施されています。このうちの「Fundamentals」を受講するとMicrosoft Azure Fundamentals 認定試験を無料で受験することができます。  
Virtual Trainingは、無料で受講できますが、平日の2日間（それぞれ半日）でビデオを試聴するタイプの講習となります。  
詳細は[こちら](https://mvtd.events.microsoft.com/Azure?azureevent=Microsoft%20Azure%20Virtual%20Training%20Day:%20Fundamentals&language=%E6%97%A5%E6%9C%AC%E8%AA%9E)を参照ください。  
注意：受講後に『「Microsoft Azure Virtual Training Day: Fundamentals」にご参加いただき、ありがとうございました』のメールが届くとの案内がありますが、筆者の場合、1か月後に届きました。しかし受講時のメールアドレスで試験の予約画面に行くと、ちゃんと特典が反映されているので不安になることはありません。  
なお、筆者の場合、特典は9ヶ月くらいの期限が設定されていました。  

### 受験時の筆者のレベル
クラウドの「ク」の字程度の知識しかありません。  
今までもAWSでの開発経験はありますが、既に環境構築された上での開発なので、ほぼ素人の状態です。
ですので、初回で合格する自信の無さから、無料特典を取得した次第です。

## 勉強方法
できるだけ「お金をかけない」主義なのですが、流石に今回は知識が乏しいので多少の出費は覚悟しました。

### 学習期間
学習したりしなかったりで全体としては3カ月ほどありましたが、実質は1ヶ月くらいでしょうか。

### 参考書
特になし。

### 講座
Udemyの「これだけで合格！AZ-900：Microsoft Azure Fundamentals模擬試験問題集」をバーゲン時に購入し、ひたすら繰り返しました。  
何回か繰り返した後、不正解と不安な問題のキーワードを集中的に学習するスタイルにシフトしました。

#### 講座の良かった部分
あくまでも個人の印象ですが、「これだけで合格」と謳うだけあって問題数が多い。  
Udemyの講座はメンテナンスされるので作りっぱなしではない。

#### 講座の不満な部分
この講座に限ったことではありませんが、試験サイトや無料トレーニング等の日本語自体が「無理矢理翻訳しました」的なので日本語なのに理解するのに少し苦労しました。  

## 今後
インフラエンジニアを目指している訳ではないので、今後はクラウド構築や運用ではなく、例えば機械学習等に特化した資格にシフトしていくことを考えています。