OmniAICreator/Qiita-1.07M huggingface dataset:
Nodeでスプシデータをcsv→jsonに変換して、条件に合う要素をリスト化する

スプシの大規模データを整理するときに楽になったので備忘録として残します。


> この記事で扱うデータはフィクションです。実在の人物や団体などとは関係ありません。
>> ※この記事のダミーデータはこちらからお借りしています。
>> →[テストデータ・ジェネレータ](https://yamagata.int21h.jp/tool/testdata/)

<img width="1239" alt="スクリーンショット 2019-10-08 12.12.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317674/7da2e7cf-0ca6-8ab8-5197-f67298879231.png">
**この記事の目標 : 住所が大阪の人をリストアップしてテキストデータに書き出す！**


#使用環境
OS: macOS
Node: v12.2.0
npm: 6.9.0

#パッケージのインストール
Nodeとnpmの環境設定は省略しています。
まずはターミナルから適当なプロジェクトフォルダに必要なパッケージをインストールします。

```
$npm init -y
$npm i -D fs csvtojson js-beautify
```
[csvtojson](https://www.npmjs.com/package/csvtojson)がコンバータ


#csv -> json の変換
スプシからcsvをダウンロード
<img width="1025" alt="スクリーンショット 2019-10-08 11.59.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317674/f61f91bd-d24c-88bb-c321-5d08d96003ff.png">


変換スクリプトを書く

```csvjson_converter.js
let fs   = require('fs');
let csv  = require('csvtojson');
let beautify = require('js-beautify').js;

let csvFile = './checksheet.csv';


csv().fromFile(csvFile).then((jsonData)=>{
  fs.writeFile('checksheet.json', beautify(JSON.stringify(jsonData),{}), function(err) {
    if (err) console.log('error', err);
  });
});

```

スプシからダウンロードした[checksheet.csv]を[checksheet.json]に変換して
beautifyでインデントを追加して書き出す命令を記述。

```
$ node csvjson_converter.js
```
ターミナルからスクリプトを実行
<img width="626" alt="スクリーンショット 2019-10-08 12.26.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317674/d6fc274d-00e5-f993-c754-1c89a07828e7.png">
こんな感じのjsonが書き出されました。


#必要な要素をリスト化してテキストデータに保存する。
条件を絞って、[.txt]データに書き出します。

```checkitem.js
let fs   = require('fs');

// check item
let json = JSON.parse(fs.readFileSync("checksheet.json"));
let targetItem = [];
json.forEach(function(value,index){
  if(value.住所.match(/大阪/)){
    // console.log(value.url);
    targetItem.push(value.名前+" : "+value.住所+"\n");
  }
});

fs.writeFile('大阪の人.txt',targetItem,function(err){
  let texts = fs.readFileSync('大阪の人.txt','utf-8');
  console.log(texts);
  fs.writeFile('大阪の人.txt',texts.replace(/\,/g,""),function(err){});
});

```
先ほど書き出した[checksheet.json]を読み込んで、[住所]の項目が[大阪]を含む値を判定。
条件に当てはまったデータを[大阪の人.txt]に書き出し。

```
$ node checkitem.js
```
ターミナルからスクリプトを実行

##正しく出て来た。
<img width="345" alt="スクリーンショット 2019-10-08 12.36.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317674/19192b3b-f43a-c578-4ce6-8d87f4dbafef.png">

>この記事で扱うデータはフィクションです。実在の人物や団体などとは関係ありませ

条件式の使い方次第で色々絞り込めます。
↓生年月日から２０代を絞り込みの場合

```checkitem.js
//if(value.住所.match(/大阪/)){
if(1998 >= value.生年月日.slice(0,4) && 1989 <= value.生年月日.slice(0,4)){
```

#おわりに
スプシのフィルタ機能でカバーできない様な、痒いところに手が届いた気がしました。
スプシ１行目に空のデータがあると、自動で　`"field番号":[{値},{..}]`が当て込まれるので注意です。

うまく書き換えて、ejsを使ったHTML書き出しにも使えそうです。

###出典
- [Node.js でファイルを保存する方法](https://qiita.com/phi/items/b5ade0c2ecc58935e046)
- [fs.writeFileの使い方。Node.jsでファイルを書き込み](https://photo-tea.com/p/17/fs-write-nodejs/)
- [JavaScriptの同期、非同期、コールバック、プロミス辺りを整理してみる](https://qiita.com/YoshikiNakamura/items/732ded26c85a7f771a27)
Debian(OS)のインストールとSSH

#2019/10/8
最近はサーバーの構築などサーバー周りを勉強し始めたのですがこれがまぁ苦戦しました、、自分はさくらVPS構築したのですが、viをいじると仕様でキーボードがおかしくなるのであまりオススメはしないです、、

配置がこのキーボードになります。
https://ecl.ntt.com/faq/2.0/virtual-server-keyboard/

:がないのでこの仕様に変わることを知らないと詰みます。
vi上であれば「Shift+Q」キーで"　:　"を入力できます。

この記事は自分を含むガチガチの初心者向けのものになっています。知ってるよって方は飛ばしてください

## カスタムOSをインストールする（自分はDebian）
 VNCコンソールを開き
#### 1.rootユーザーのパスワード
#### 2.rootユーザーパスワードの確認
#### 3.任意のユーザーname
####4.確認
####5.任意のユーザーのパスワード
####6.Guided - use entire diskを選択
####7.virtual disk 1 (vda) - 21.5 GB Virtio Block Deviceを選択
####8.Finish partitioning and write changes to disk 選択
####9.yes
####10.Continue を選択

の順番で各種打ち込んでいきます


## さくらVPSに戻ってサーバーを起動させる（シャットダウン（黄色）の横の起動（緑）を押して）

・再度VNCコンソールを開く

##rootユーザーでログインし
＃ apt update
＃ apt install sudo
をしsudoをインストールする

・sudoとは(スーパーユーザー Do)
全ての権限をもつユーザー

## 任意のユーザーにsudoコマンドを付与
＃　visudo
で確認する

＃ allow members of group sudo to execute any comandの
％sudo ALL=(ALL:ALL)ALLの

％sudoのところを任意の最初に登録したユーザーネームに書き換える。
ユーザー名 ALL=(ALL:ALL)ALL

control ＋ X
そのあとの項目はyesでエンター
これで変更の保存はOKです

##sudoコマンドが任意のユーザーが使えるか確認しsshのrootユーザーの権限を制約する
・任意のユーザーネームでログイン後
sudo ls
をする

$ sudo cp /etc/ssh/sshd_config  　/etc/ssh/sshd_config.org
でバックアップを取り

sudo vi /etc/ssh/sshd.config
を入力しviを開く

・/Root
でファイル内検索をし、
・ ＃PermitRootLogin 
を探し、そのなかの
＃PermitRootLogin hogehoge
を
PermitRootLogin no
に書き換える
・このときにハッシュを消すのを忘れない
・インサートモードの切り替え注意
####さくらVPSだとここでキーボードが変になるから注意
（vi上であれば「Shift+Q」キーで"　:　"を入力できます。）

入力が終わったら
escを押して
：wq
（保存して移動）

最後に設定を反映させるために再起動をする

## 再起動
/etc/init.d/ssh restart

自分はなんとかこれでできました。
最後まで見てくれてありがとうございます( ͡° ͜ʖ ͡°)
第1回ETロボコン講座

#＃ETロボコン講座
始まりましたETロボコン講座
プライマリークラスの初心者向けに向けてのやっていきます
最終的にはゴールできるまでのレベルまであげていけたらいいなと思います
##注意事項
初心者向けの講座になります。
アドバンスクラスやレベルの高い方にはあまり参考にならないと思うので読み飛ばすか、
間違っている所をみつけようとしてくれたら幸いです
筆者の環境はwindows10、cigwin64です
#本編
今日の講座が終わればコードをコンパイルまでができるようになります
##環境構築
開発は環境を整えなければ何もできませんまずは環境を整えましょう
環境構築は公式サイトを参考にしてください。
チームに配布されるパスワードがあれば閲覧できるはずです。
正直これが一番大変です。
[ETロボコン公式サイト](https://www.etrobo.jp/tool/)
##ファイル構造
大変な環境構築が終わったらファイル構造から理解していきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422529/648b07f1-62f5-a849-a67e-35d08a760f5c.png)
workspaceのなかで開発します。workspaceの中で開発したいもののファイルを作成します。
そのファイルの中に必須のファイルがあるので以下に記します
###app.c
必須ファイルです
ここでソースコードを書いていきます
###app.h
app.cの構造を理解しなければapp.hは理解できないので今回は**おまじない**としておきます
###app.cfg
これも**おまじない**です
###Makefile.inc
これも**おまじない**です

`この4つがコードを書く上で同一のファイル内に必須となります`![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422529/f82fb8b0-28c3-de39-0575-c602f2f353c3.png)
*test*というファイルを作成する場合は上の画像のようになります。
##app.cの構造
必須のコードが以下に示します

```c#:app.c
#include "ev3api.h"
#include "app.h"
#include <stdio.h>
#include <stdbool.h>
#include <balancer.h>

#if defined(BUILD_MODULE)
#include "module_cfg.h"
#else
#include "kernel_cfg.h"
#endif

#define DEBUG

#ifdef DEBUG
#define _debug(x) (x)
#else
#define _debug(x)
#endif
#define GYRO_OFFSET  0 

static const sensor_port_t
touch_sensor    = EV3_PORT_1,
sonar_sensor    = EV3_PORT_2,
color_sensor    = EV3_PORT_3,
gyro_sensor     = EV3_PORT_4;

static const motor_port_t
left_motor      = EV3_PORT_C,
right_motor     = EV3_PORT_B,
tail_motor      = EV3_PORT_A;
void bt_task(intptr_t unused)
{

}
void main_task(intptr_t unused)
{

}
```
このコードの中ではポートの設定や同一ファイル内にあるapp.hファイル等を呼び出しています。
よくわからない場合はとりあえずコピペしてください。
##実際に書いていく
実際にコードを書く場所は上の部分の｛　｝内となります。

```C#:test.c
void main_task(intptr_t unused)
{

}
```

これはタイヤを70のスピードで走らせるコードです

```C#:test.c
void main_task(intptr_t unused)
{
    ev3_motor_config(right_motor,LARGE_MOTOR);
    ev3_motor_config(left_motor,LARGE_MOTOR);

    ev3_motor_set_power(EV3_PORT_C,70);
    ev3_motor_set_power(EV3_PORT_B,70);
}
```
上の2行で接続されているLARGEMOTERに接続しているポート名を宣言します。
下の2行は
**ev3_motor_set_power(動かしたいモーターのポート名,モーターのスピード（100~-100))**
となります。
##コンパイル編
**1.cygwinでCドライブ内のworkspaceディレクトリ内に移動します**
コンパイルしたいファイルがworkspaceディレクトリ内にあるか確認してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422529/d3fb85b6-05d1-fb1c-ebd2-e03544d46a3a.png)
**2.make appコマンドで実行します。**
今回の場合はtest.cファイルをコンパイルしたいので下のようになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422529/abf5b925-6f6b-cbce-08d1-2a4df1f72806.png)
LD appと表示されれば成功です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422529/e34ac100-613e-4319-4c2a-7788204d415d.png)
**3.コンパイル後**
コンパイルが成功するとworkspace内にappファイルが作成されます。
このappファイルを**EV3にSDカード等を使用し移動**させれば完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422529/c27b1afc-abf6-347f-9a5a-23c228f1ac60.png)
【SpringBoot】java.lang.NoClassDefFoundError: kotlin/reflect/full/KClassesへの対処【Kotlin】

# 問題
既存のプロジェクトに`Kotlin`を導入した所以下のようなエラーが出ました。

```bash:スタックトレースの一部（整形済み）
org.springframework.beans.factory.BeanCreationException:
  Error creating bean with name '${beanの名前}' defined in file [${ファイルのフルパス}]:
    Unexpected exception during bean creation;
    nested exception is java.lang.NoClassDefFoundError: kotlin/reflect/full/KClasses
```

全く同じプロジェクトについて、この問題が出たのは一部の環境のみでした。

## 環境
- `Kotlin`: 1.3.50
- `SpringBoot`: 2.0.9
- `Maven`: 3.6.1

# 対処
`kotlin-reflect`をpomに追加することで解決しました。

```xml
<!-- https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-reflect -->
<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-reflect</artifactId>
    <version>${kotlin.version}</version>
</dependency>
```

# 雑感
環境によって出たり出なかったりするのが、何故そんな挙動になるのかちょっとよく分かりませんでした……。

# 参考にさせて頂いた記事
- [spring \- Exception thrown when using @Service in Kotlin \- Stack Overflow](https://stackoverflow.com/questions/47174036/exception-thrown-when-using-service-in-kotlin?rq=1)
(OutSystems)Reactive Web AppとTraditional Webの違い

Reactive Web Appは、最近リリースされたOutSystemsの新機能で、内部的にはReactベースになっているそうです。

# 動作確認環境
Personal Environment(Version 11.0.606.0) 
Service Studio(Version 11.6.1)

2019/10のアップデート以降のPlatformで使用可能になった機能です。

# アプリケーション・モジュール
これまでのWebアプリケーションは"Traditional Web"と改称され、New Applicationダイアログオプションの下の方に追いやられています。

New Applicationダイアログ(Traditional Webはスクロールしないと出てこない)
![Reactive_Diff1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/14f7b86c-a7c7-6884-b49d-ae3d7185d259.png)

# 処理は主にクライアントで行われる
Traditional Webでは、処理(Action)はサーバ内で実行されていました。

Reactive Web AppではClient Actionが追加されました。これまでのActionはServer Actionと呼ばれます。

白抜きの円形のアイコンがついているのがClient Action。Server Actionはこれまでと同じようにオレンジの円形で表されます。

![Reactive_Diff2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/b4d7ec7e-2f9d-e2dc-6e91-5278e4952f2d.png)


Screen ActionはClient  Actionになります。サーバサイドの処理が必要な時は、Client ActionからServer Actionを呼び出すことができます。

Client Actionのみで処理が完結する場合、通信は発生しません。

# データ取得
Traditional Webでは、PreparationでAggregateを呼んでおいて、Screen ActionやWidgetでそれを利用することが多かったと思います。

Reactive Web Appでは、Screenに直接Aggregateを作成します。
![Reactive_Diff3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/45f9b0e6-8866-50dd-de2a-5dad58f3ee68.png)

定義しておいたAggregateは、画面表示時に自動的に並列で実行され、取得が終了すると、紐づけておいたWidgetに自動で反映されます。

なお、Aggregate取得後に別の処理を挟みたい場合は、AggregateのOn After Fetchを利用してください。。

# 表示の更新
Traditional Webでは、一度表示した値を更新する場合、

- SubmitやNavigateでページを再描画する
- Ajax Submitでサーバに処理を返し、Ajax Refreshで更新したいWidgetを指定する

のどちらかでした。
Reactive Web Appでは、Widgetに紐づけておいた変数の値を更新すると自動的に表示が更新されます。

# イベント
ScreenとBlockに以下のイベントがあります。

- On Initialize：新しい画面に遷移する前に、その画面のこのイベントが発生
- On Ready：DOMがReadyのタイミングで発生
- On Render：変数変更などでそのUIの表示が更新されたときに発生
- On Destroy

また、BlockにOn Parameters Changedというイベントがあります。これは配置先のScreenからBlockに渡しているInput Parameterが変更されたときに動作するイベント。

# セッション変数がない
代わりに、Client Variablesというのがあります。
セッション変数と違い、クライアント側に保持されます。

同じUser Providerを共有する複数のアプリケーションで共用されるようです。

# モバイルとの関係
OutSystemsでのモバイルアプリケーション開発とかなり似ています。
Web とモバイルアプリケーション開発で開発者のスキルを共有できる幅が広がったといえるのではないでしょうか。

Local Entityがないのと、プラグインがないのはモバイルアプリケーション開発との違いですね。

Client Variablesはモバイルアプリケーション開発でも使えるそうです。
[Rust] 実行時に DOS 窓を表示しない

本記事の内容は以下の環境で確認しました.

* Windows 10 v1903
* Rust 1.36 stable-x86_64-pc-windows-msvc

# 本論

Rust コードを Windows で普通にコンパイルして実行ファイル (.exe) を生成するとコンソールアプリ扱いとなるため, それを実行するとコマンドプロンプトのウィンドウ (いわゆる DOS 窓) が開かれます. これを防ぐには, ソースコード (`src/main.rs`) の冒頭に

```rust
#![windows_subsystem = "windows"]
```

というアトリビュートを設定します. これだけで Windows アプリ扱いとなるため, 実行時に DOS 窓が表示されません. より詳しくは下の参考文献をどうぞ.

なお, DOS 窓がないため標準出力および標準エラーは表示されず虚空の彼方へ消え去ります.

# コード例

`hello.txt` という空ファイルを生成するだけのプログラムです. (強制的に空ファイルで上書きするので注意)

```rust
#![windows_subsystem = "windows"]

fn main() {
    let _ = std::fs::File::create("./hello.txt").unwrap();
}
```

# 参考文献

* [Rust RFC1665 - Windows Subsystem](https://github.com/frol/rust-rfcs/blob/master/text/1665-windows-subsystem.md)
* [Microsoft Docs - /SUBSYSTEM (サブシステムの指定)](https://docs.microsoft.com/ja-jp/cpp/build/reference/subsystem-specify-subsystem?view=vs-2019)
AWS Sysmtems Manager OpsCenterで増えすぎたOpsItemを一括で解決済みにする

## AWSCLI ワンライナー
以下をご使用ください。

```shell
$ aws ssm describe-ops-items --ops-item-filters '{"Key":"Status","Values":["Open"],"Operator":"Equal"}' --query 'OpsItemSummaries[*].OpsItemId' --output table | grep "oi-" | awk '{print $2}' | while read line; do echo update item: $line; aws ssm update-ops-item --status Resolved --ops-item-id $line; done
```
ステータスが未解決(Open)の Item を何も考えずに一括で解決済み(Resolved)に
変更してしまうのでご注意ください。
以降は解説です。

## OpsCenter とは
2019年6月に追加された Systems Manager の新しい機能です。
CloudWatch Events と連携して AWS リソースの運用上の問題、イベント、アラート等を
OpsItems として集中管理する機能を提供します。

**AWS Systems Manager OpsCenter**
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/OpsCenter.html

## OpsItem の作成のしくみと蓄積
OpsItem を作成するには大きくわけると2つの方法があります。

* コンソールや OpsCenter API を通して手動で作成する
* CloudWatch Events で各種イベントを検知し、自動作成する

後者の CloudWatch Events ルールは自身で作成してもよいのですが、基本的なルールは
AWS 側であらかじめ用意されており、OpsCenter のコンソールから設定することが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/e750c8d9-2d47-3070-aeba-23a609f16aae.png)

基本的な運用イベントが網羅されていてとても便利なのですが、アカウントの用途によっては
EC2 の停止または終了は頻繁に発生するため、これがノイズになってしまうこともあります。

実際に開発用の環境で OpsCenter を検証していたところ
未解決イベントが大量に溜まってしまいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/61e188ec-1310-5cb1-aad3-abc2c7c30ceb.png)

各 OpsItem を手動で解決済みにしていってもよいのですが、数が増えてくると大変辛い。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/56122443-e05a-a54b-8f17-34e6136be7b7.png)

## 対策
### CloudWatch Events ルールの無効化
基本設定で不要なルールは、CloudWatch Events で個別にルールを無効化すれば
Item の自動登録を止めることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/27d4b26b-0058-9496-7780-e2fd925c0e2a.png)

### AWSCLI によるステータス変更
冒頭のコマンドを改行ありで記載すると以下のような感じになります。

```shell
$ aws ssm describe-ops-items \
> --ops-item-filters '{"Key":"Status","Values":["Open"],"Operator":"Equal"}' \
> --query 'OpsItemSummaries[*].OpsItemId' --output table |
> grep "oi-" |
> awk '{print $2}' |
> while read line;
> do echo update item: $line; 
> aws ssm update-ops-item --status Resolved --ops-item-id $line;
> done
update item: oi-xxxxxxxxxxxx
update item: oi-yyyyyyyyyyyy
update item: oi-zzzzzzzzzzzz
.
.
以下略
```
describe-ops-items コマンドでステータスが Open の OpsItemId を抜き出し、
各IDに対して、update-ops-item コマンドでステータスを Resolved に変更しています。

注意点としては describe-ops-items が一度に最大で50件までしかリストできないので
上記のコマンドも50件しか処理できません。
50件以上溜まっている場合、Open状態のアイテムが無くなるまで繰り返し実行する必要があります。

以上です。
参考になれば幸いです。
古の非Nitro世代インタンス(T2)を最新のインスタンス(T3)に変更する

# はじめに
昔からAPIサーバーとして運用されているEC2インスタンスのインスタンスタイプを変更しようとしたところ、諸々のエラーが出てすんなり変更できなかったため、最終的な更新手順の備忘録です。

#TL;DR
・インスタンスのenaモジュールとカーネルバージョンを確認
・カーネルをアップデートしてenaをインストール
・AWSCLIからenaを有効化

# 現状の確認
※ 以降の手順でsshでEC2に接続、及び、AWSCLIを使用しますが、環境構築については割愛させていただきます。

最初にt2インスタンスを停止し、インスタンスタイプをt3に切り替えて起動を試みたところ、下記エラーで起動することができませんでした。
![ENA ERROR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265206/e10d6826-c239-be11-c4b4-050b1f440e2f.png)

エラーについて調べると下記公式の適用手順が見つかったため、これにしたがって進めていきます。
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/enhanced-networking-ena.html

１. EC2にsshで接続

２. enaモジュールがインストールされていることを確認

```実行.
modinfo ena
```

```結果.
modinfo: ERROR: Module ena not found.
```
古いAMIにはenaモジュールが含まれていないため、
> enaを含む最新のカーネルとカーネルモジュールでインスタンスを更新

する必要があるようです。

３. カーネルのバージョン確認

```実行.
uname -srv
```

```結果.
Linux 3.14.35-28.38.amzn1.x86_64 #1 SMP Wed Mar 11 22:50:37 UTC 2015
```

# インスタンスの更新
公式の手順に従ってパッケージを更新して確認します。
> 以前の Amazon Linux AMI を使用してインスタンスを起動し、まだ拡張ネットワーキングが有効になっていない場合、拡張ネットワーキングを有効にするには次の手順を実行します。

##１. パッケージの更新

```
sudo yum update -y
```
アップデートが完了したら一旦再起動して再度sshで接続します。

##２. 再起動して確認
**ena**

```実行.
modinfo ena
```

```結果.
modinfo: ERROR: Module ena not found.
```
**カーネルのバージョン**

```実行.
uname -srv
```

```結果.
Linux 3.14.35-28.38.amzn1.x86_64 #1 SMP Wed Mar 11 22:50:37 UTC 2015
```

なんと、変化がありません...

[【CPUの脆弱性対応】古いAmazon Linuxのkernelを最新版にアップデートする](https://qiita.com/taketora/items/07b0a99d29c255a7ccf1)によると、`yum.conf`ファイルに`releasever`の変数を設定しないと、カーネルのバージョンが固定されてしまい更新できないそうです。

##３. `yum.conf`の修正（追加）

```実行.
sudo vi /etc/yum.conf
```

```yum.conf.diff
~
# of Amazon Linux AMI. If you prefer not to automatically move to
# new releases, comment out this line.
- #releasever=latest
+ releasever=latest

#  This is the default, if you make this bigger yum won't see if the metadata
# is newer on the remote and so you'll "gain" the bandwidth of not having to
~
```

これで再度`sudo yum update -y`で更新し、再起動して確認します。

##４. 再起動して確認
**ena**

```実行.
modinfo ena
```

```結果.
filename:       /lib/modules/4.14.146-93.123.amzn1.x86_64/kernel/drivers/amazon/net/ena/ena.ko
version:        2.1.1g
license:        GPL
description:    Elastic Network Adapter (ENA)
~
```
**カーネルのバージョン**

```実行.
uname -srv
```

```結果.
Linux 4.14.146-93.123.amzn1.x86_64 #1 SMP Tue Sep 24 00:45:23 UTC 2019
```

無事カーネルのアップデートとenaのインストールが完了しました！

続いて、インスタンスのEnaSupportを有効化します。
以降の手順はAWSCLIでローカルPCから実行するため、インスタンスはシャットダウンしておきます。

##５. `EnaSupport`の確認

```実行.
aws ec2 describe-instances --instance-id i-XXXXXXXXXXXX --query 'Reservations[].Instances[].EnaSupport'
```

```結果.
[]
```
無効の場合は空の配列が帰ってきます。

##６. `EnaSupport`の有効化

```実行.
aws ec2 modify-instance-attribute --instance-id i-XXXXXXXXXXXX --ena-support
```
実行しても反応がないため、有効化されたか確認します。

##７. `EnaSupport`の確認

```実行.
aws ec2 describe-instances --instance-id i-XXXXXXXXXXXX --query 'Reservations[].Instances[].EnaSupport'
```

```結果.
[
    true
]
```
有効の場合は`true`が帰ってきます。

これでインスタンスの更新は完了です！
インスタンスタイプをt2からt3に変更して、無事起動できることを確認します。

# まとめ
おそらくあまりにも古いAMIを使用していたため、公式の手順だけでは更新することができませんでした。
定期的にカーネルのバージョンを確認して、最新の状態に保つのが大切ですね。
JupyterのAnimation ではまった

これからのGUIは、Jupyterだろ！ということで、いろいろ調べているのだけど、ハマったのでメモ。下のコードは動く。`animate`という関数がコールバックされてプロット内の`line`をアップデートしている。直接コールバック関数のなかで`plot`してもいいらしいが、ここでの本題ではないので、とりあえずこれで。

``` Python
%matplotlib nbagg
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation


fig, ax = plt.subplots()
line, = ax.plot([], [], lw=2)

def animate(i):
    x = np.linspace(0, 1, 1000)
    y = np.sin((x + (0.01 * i)) * 2 * np.pi) * 0.5 + 0.5
    line.set_data(x, y)
    return (line,)

animation.FuncAnimation(fig, animate, frames=100, 
                        interval=20, blit=True)
```

おどろくべきことに、このコードを関数の中に移しただけの次のコードは動かない。

``` Python
def createGraph():
    fig, ax = plt.subplots()
    line, = ax.plot([], [], lw=2)

    def animate(i):
        x = np.linspace(0, 1, 1000)
        y = np.sin((x + (0.01 * i)) * 2 * np.pi) * 0.5 + 0.5
        line.set_data(x, y)
        return (line,)

    animation.FuncAnimation(fig, animate, frames=100, 
                            interval=20, blit=True)
createGraph()
```
エラーがでるわけではないのだけど、プロット領域が表示されるだけで、全くグラフが描画されない。いろいろ試してみると`animate`関数が全く呼ばれていないことがわかった。

これを動くようにするには、`createGraph`関数の末尾で作成した`Animation`オブジェクトを`return`すればいい。

```
    return animation.FuncAnimation(fig, animate, frames=100, 
                                    interval=20, blit=True)
```

## なぜなのか
[マニュアル](https://matplotlib.org/3.1.1/api/animation_api.html)を見たら、冒頭にちゃんと書いてあった。。

> In both cases it is critical to keep a reference to the instance object. The animation is advanced by a timer (typically from the host GUI framework) which the Animation object holds the only reference to. If you do not hold a reference to the Animation object, it (and hence the timers), will be garbage collected which will stop the animation.

`Animation`オブジェクトの参照が作られると同時に開放されるので、`animate`を一度も呼び出す暇もなく、即回収されていた、ということらしい。１番最初の書き方でも返り値を変数に代入していないので即死しそうなものだけど、Jupyterでは各入力セッションの最後の文の値が自動的に`_`に代入されるので、参照が失われないので死ななかったようだ。だから、末尾に

``` Python
a = 'test'
```
とかダミーの文を入れてやると、`_`にバインドされるのがこのダミーの文の結果になるので動かなくなる。

でも、一度動き出すと代入した変数を書き潰しても止まらないんだよなあ。どこかに別途参照が保持されるのだろうか。

ちなみに、アニメーションを停止させるには下記のようにするればよい。

``` Python
_.event_source.stop()
```

## 教訓
マニュアルを先にちゃんと読みましょう。
「API Gateway で Lambda エラーを処理する」が動かなかった話

元ネタ
[API Gateway で Lambda エラーを処理する](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/handle-errors-in-lambda-integration.html)

※2019.10.08 AWSのドキュメントのフィードバックに報告済みなのでドキュメント側も修正済みの場合があります

このドキュメントですが、これに書いてある通りにやってもエラー処理が正常にできずステータス２００が帰ってきてしまう。

原因はここの誤記

```
aws apigateway put-integration-response --rest-api-id [rest-api-id] --resource-id [resource-id] --http-method GET --status-code 400 --selection-pattern "Invalid*" --region us-west-2
```

`"Invalid*"`を`"Invalid.*"`にするとちゃんと動きました。

# 詳しい解説

## 誤記について

`--selection-pattern`は正規表現を用いることになっていますが

[基本的な正規表現一覧](https://murashun.jp/blog/20190215-01.html)

によると、`"Invalid*"`だと`"Invalid〜"`みたいな文字列にはマッチしません。
（"Invali", "Invalid", "Invaliddddd"とかがマッチ対象になるのかな）
なので、`"Invalid〜"`に対応させるには`"Invalid.*"`と表記します。

## Lamvda -> API Gateway でのエラー検知について
上記の正規表現ですが「どこをみてるの？」という話。
結論から言うと標準エラーからハンドリングする場合は

```
{
  "errorMessage": "Malformed input ...",
  "errorType": "Error",
  "stackTrace": [
    "exports.handler (/var/task/index.js:3:14)"
  ]
}
```

こちらの標準エラーの`"errorMessage"`が上記正規表現の対象になるみたいです。
なので、ドキュメントの解説に沿って対応させるには正規表現は`"Malformed.*"`と設定する必要があります。

## まとめ
以下のようにそれぞれのステータスコードを設定していくと管理しやすそうですね。

> Lambdaエラーの正規表現
400.*
メソッドレスポンスのステータス
400

レスポンス処理

```Node.js
exports.handler = function(event, context, callback) {
    callback(new Error("400 Bad Request"));
};
```
Linux基礎(X Window System)

#X Window Systemとは
多くのUNIXやLinuxで使用されているウィンドウシステムで、これによりGUIを実現している。

- X Window System上での処理の流れ

![スクリーンショット 2019-10-08 11.41.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374557/500edbc3-a84d-81a4-e629-8cd4bedf981d.png)

① キーボードでデータを入力する 
② Xサーバーは入力データを受け付けて、Xクライアント(アプリ)にデータを送る
③ Xクライアントは受け取ったデータを処理して、処理結果をXサーバーに送る
④ Xサーバーは、Xクライアントから受け取った処理結果をディスプレイに出力する

#X Window Systemの設定ファイルX.Orgの設定
無料のX Window Systemとして、LinuxではXFree86が採用されていた。現在はX.Orgが主流。
X.Orgの設定ファイルは「/etc/X11/xorg.conf」。xorg.confファイルにはキーボード、ディスプレイ、フォント、解像度などの設定が記述されている。xorg.confファイルは複数のセクションから構成される。

|セクション|説明|
|---|---|
|ServerLayout|入力・出力用のデバイスの組み合わせとスクリーン設定|
|Files|フォント関連のパスの設定|
|Module|Xサーバーがロード予定のダイナミックモジュールの設定|
|InputDevice|Xサーバーに対する入力デバイス(キーボード等)の設定|
|Monitor|システムにより使用されるモニタタイプの設定|
|Device|システム用のビデオカードの設定|
|Screen|ディスプレイの色深度と画像サイズの設定|

xorg.confファイルの設定をコマンドラインで設定することもできる。

```shell
# xorg.confファイルを自動生成するコマンド
$ Xorg - configure

# xorg.confファイルのテスト
$ X -config /root/xorg.conf.new 
```

#ネットワーク経由での利用
ネットワークを経由してX Window Systemを利用することができる。リモートアクセスでは、ローカルコンピュータでXサーバーが稼働して、リモートホストのXクライアントが、ローカルのXサーバーを使用してディスプレイに表示する。クライアント・サーバー配置の考え方とは逆のような構成になる。

- X Window Systemのネットワーク経由での利用

![スクリーンショット 2019-10-08 11.56.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374557/8830b441-854e-83fb-8a11-d597596a268f.png)

Xサーバーへのリモートアクセスを許可するためにはxhostコマンドを使用する。

xhost [+または-] [ホスト名]

|オプション|説明|
|---|---|
|+ホスト名|指定したホストからのXサーバーへの接続を許可|
|-ホスト名|指定したホストからのXサーバーへの接続を拒否|
|+|アクセス制御の無効化(全てのホストからの接続を許可)|
|-|アクセス制御の有効化(アクセス許可されていないホストからの接続は拒否)|

```shell
#Remote PCのXクライアントが、Local PCのXサーバーを利用を許可する設定
$ xhost +[Rempote PCのホスト名]

```
Xクライアントの処理結果を表示するために、Remote PCの環境変数DISPLAYでXサーバーを指定して環境変数のDISPLAYをエクスポートする必要がある。

```shell
# ホスト名：ディスプレイ番号
$ DISPLAY=localpc:0
$ export DISPLAY
```

# Xサーバーが起動するまでの流れ

1. コンソールから「startx」コマンドを実行
2. xinitコマンド
3. ~/.xinitrcがあれば実行。ない場合、「/etc/X11/xinit/xinitrc」を実行
4. ~/.xsessionを実行。ない場合、~/.Xclientsを実行。更にない場合、「/etc/X11/xinit/Xclients」を実行
5. KDEまたはGNOMEまたは、他のウィンドウマネージャが起動

# Xクライアントコマンド
X Window Systemの設定確認、情報収集のためのコマンド集

|コマンド|説明|
|---|---|
|showrgb|X Window Systemで利用可能な色とRGB値の情報表示|
|xlsclients|実行中のXクライアントの表示|
|xwininfo|コマンド実行後に指定したウィンドウのサイズ、位置、色深度の情報確認|
|xdpyinfo|ディスプレイの情報の表示(X Window System内のディスプレイ情報)|
Googleバックアップと同期を使って新PCへデータを移行する

##事の発端
WindowsPCをクリーンインストールしてきれいにしたいけど、データの移行方法どうしよ

→バックアップと同期を使ってバックアップとってるじゃん、これ使って移行しよ！


移行しようとしたら見事につまずいたのでその詳細を書き残しておきます
##つまずいた事

###予想

新PCにバックアップと同期をインストールすると旧PCのフォルダと同期をとってデータを移行できる

###結果

別PCと認識される
![理想と現実.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381405/6defbc0d-6525-6a6d-91d2-341bd5c2cc32.png)


##解決策

####1.同期先に旧PCのフォルダを割り当てる
方法を探したが見つからず

####2.旧PCのフォルダからデータを直接ダウンロードする
データが大きすぎて終わる気配が全くない

####3.新PCのフォルダに旧PCのデータを移動させる
できない

####4.旧PCの"Documentsの中身"を右クリして場所を移動
新PCのフォルダに移動できて同期ができた！
![理想への一歩.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381405/22f2c2e9-e5ff-8d5e-1265-cf7a6fe24277.png)


この手法なら、ローカルにバックアップを作らなくても、新PCでデータを復元できるんじゃないかと思います。ただし、同期がちゃんと終わってからしましょう。(フォルダが表示されてても中身がないとかよくある）
あと、1.の同期先フォルダの割り当て方法があったらコメントで教えていただけるとありがたいです。
数値計算向けパラメータファイルを読み込むシングルファイル C++ ライブラリ

# はじめに

数値計算でパラメータを読み込む必要がある時、毎回似たようなの書いている気がするので、C++のシングルヘッダファイルライブラリにまとめました[^1]。

https://github.com/kaityo256/param

[^1]: 車輪の再開発感半端ないですが・・・

## 使い方

こんなパラメタファイルを考えます。

```sh:input.cfg
# Comment
bool=yes
int=12345
double=12.345
```

フォーマットは「key=value」で、`#`から始まる行はコメントです。

こんな感じに読みこめます。

```cpp
param::parameter param("input.cfg");
bool b = param.get<bool>("bool");
int  i = param.get<int>("int");
double d = param.get<double>("double");
```

キーがない場合はエラーになりますが、キーが無いときにはデフォルトの値を使いたい場合は第二引数にデフォルト値を指定します。

```cpp
bool b = param.get<bool>("non-existing key", false);
int  i = param.get<int>("non-existing key", 0);
double d = param.get<double>("non-existing key", 0.0);
```

読み込みがこけたかどうかは`if`文で判断します。

```cpp
if (!param) {
  std::cerr << "Could not find file " << filename << std::endl;
  std::abort();
}
```

まぁ、それだけの、100行ちょっとのライブラリなんですけど。

## 雑談

数値計算やってて、なんかプログラムにパラメータを渡したいことがあります。数値計算なので、渡すパラメータはせいぜい真偽値、整数、浮動小数点数だけです。

例えば、システムサイズ`L`と温度`T`を指定したい場合を考えましょう。サイズは整数、温度は浮動小数点数です。この時、様々なプログラムの結合度をもった与え方がありえます。

### 実行時引数

一番簡単なのは、実行時引数として与えてしまうことでしょう。

```sh
$ ./a.out 32 1.5
```

プログラム側は`argv`と`std::stoi`とか`std::stod`を使って受け取ります。

さすがにこれはちょっとアレ感があるので、もう少しなんとかしたいところです。

### ファイル(順番に並べる)

やはりパラメータはファイルに残しておきたい気がします。というわけで順番に並べておきましょう。

```sh
32
1.5
```

プログラムにはリダイレクトで渡して`std::cin`とかで受け取るんでしょうね。ファイルに吐いている分だけ、プログラムとの結合度は下がりましたが、パラメタが増えてくると「何番目がなんだっけ？」ということになるので、やっぱりパラメタに名前をつけたい気がします。

### INIファイル形式

パラメタに名前をつけたいので`key=value`という形式にしましょう。古のWindows INIファイルのセクションとかが無いやつみたいなイメージです。

```sh:input.cfg
L=32
T=1.5
```

パラメタに名前がついたので、順番が意味をもたなくなります。また、ファイル中にコメントが書けるようになるのが地味に便利です。ただし、データに階層構造をもたせることはできません。

### JSON/YAML/XML

もう少しちゃんとやるなら、JSON/YAML/XMLといったファイルを使うことになるでしょう。ただ、それぞれC++のパーサはあるものの、やりたいことに比してちょっと道具立てが大仰かな、という気がします。

まとめるとこんな感じでしょうか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79744/6ca3d5ea-6312-99c1-7a7e-17e63c9e86c2.png)

# まとめ

数値計算のインプットパラメタを簡単に渡すためのライブラリを書きました。今回、そろそろJSONかYAMLで行こうかな、と思ったのですが、わりと「重い」ライブラリしかなかったのと、書いてもどうせ100行程度なので自前で用意しました。ものすごく昔、XMLでパラメタを渡すプログラムがあって、ちょっと特殊な環境のマシンでlibxmlのビルドに苦労してから、どうも「重い」ライブラリに苦手意識があります。最近はまた状況が変わったんでしょうか。
Oracle Certified Java Programmer, Gold SE 8 を受けて

今更ですがようやくSJC-PからOracle資格へのアップグレードをしました。
試験を受けた動機は会社から「取あっておきましょうね!」と言われたから。
個人的にも**Java1.5の知識しかなかった**ので、Java8の勉強 + 複数復習を兼ねて取り組みました。

結果としては・・・
勉強期間：1か月(平日。勤務時間すべてを使ってました。)
結果：なんとか合格できた感じ。

##受けた試験
[Upgrade to Java SE 8 OCP ( Java SE 6 and all prior versions)](https://education.oracle.com/ja/upgrade-to-java-se-8-ocp-java-se-6-and-all-prior-versions/pexam_1Z0-813)
SJC-Pからのアップグレードだから。

##やったこと
**1.黒本で勉強**
[黒本](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5-Java-Gold-%E5%95%8F%E9%A1%8C%E9%9B%86-1Z0-809/dp/4295000035)で問題を解く⇒解説を理解する⇒総合問題を解く⇒解説を理解する。⇒DL総合問題を解く⇒解説を理解する。を2回繰り返しました。
2回目の結果がかなりいい線まで行ったので、これで完璧じゃね？と錯覚。
けれども、ネットでは「紫本」というワードがチラホラあったので油断せず、紫本を買うことにしました。

**2.紫本で勉強**
[紫本](https://www.amazon.co.jp/%E3%82%AA%E3%83%A9%E3%82%AF%E3%83%AB%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E6%95%99%E7%A7%91%E6%9B%B8-Java%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E-Gold-SE-EXAMPRESS/dp/479814682X/ref=pd_lpo_sbs_14_t_1/355-7173565-4802505?_encoding=UTF8&psc=1&refRID=PK2FKVDKCFGHVC2C7FQM)を渋々購入し、黒本でついた力を試すため、即行、総合問題をやりました。
結果・・・

**悲惨**

自分ができている！理解してる！ことが実はごくごく一部であることを思い知らされました。
黒本と紫本は全く同じ構成なのに、問題の出し方が違います。
自分の抜けている部分と理解できていない点が、明らかになったのでほんとうに買ってよかったです。

**3.APIを見る**
MapやListなど、お馴染みクラスもJava8で機能が追加されていますので、読みました　。
天才ではないので、ノートに一つ一つ書きましたが、完全に覚えきれていません・・・。

**4.Oracleのキャンペーン問題を解く**
かなり助けられました。
キャンペーン問題と同じ内容が少し試験にも出てくれました。。。

**5.試し実行する**
StreamやNIO2に関しては、私とってははじめて出会った技術なのでとにかく
試し実行をしました。試し実行すると、頭で理解しにくいことがスンナリ入ってくるので
環境がある方は是非！

##いざ申し込み！
めちゃくちゃ戸惑いました・・・。
ムズイ・・・。
初めてのピアソンVUE。わけわからずイライラが止まりませんでした・・・。
こちらを参考にがんばって申し込みます。
[オラクル認定Javaプログラマ試験の申し込み方法と合格証書・領収書の取得方法](https://csmajors.net/how-to-apply-for-oracle-certified-programmer-exam/)　

※なお、私は受験6日前にピアソンVUEのアカウントを作りました・・・。

##実際の試験
さすがに変なひっかけは無かったように思いますが、日本語が理解できない問題もあり
四苦八苦しました。
Stream、NIO2、try-with-resource、Fork/Join、ローカライズなどがよく出ました。
こんなニッチな
メソッドわかんない!!と心で叫んだ問題もちらほらありました・・・。

##試験の結果を見る
メールが5分くらい経ってやってきます。
メールにCertViewへのリンクがあるのでそれをクリックしてCertViewへログインします。
この段階で私は、Oracleアカウントがないことに気づき、急いでアカウントを作ります。
そのせいなのか、CertViewにログインができず、1時間あけたらなんとかログインして結果が見れた感じです。
（事前にちゃんとやっておけば良かったと後悔しました・・・）


## 感想
1Z0-813の試験と1Z0-809では試験の内容が違いますが、1Z0-809の勉強をすることで
Java8の新機能やそれ以前の重要新機能の勉強をすることができたのでとても有意義でした。

Java8の勉強をしないとなぁ・・・。
とふんわり思っていた時は、何をどう勉強すればよいのかわからず、結局勉強せずでしたが
今回の1Z0-813の資格勉強を通して、体系的に学べたと思います！
2019-10-08 WPS > setupエラー > Your Fortran + NETCDF did not run successfully.

```txt:動作環境
動作環境 CentOS Linux release 7.7.1908 (Core)
```

WRF (Weather Research and Forecasting Model)関連。

### 状況

- NETCDF(C API, FORTRAN API)のセットアップ完了
- WRFのセットアップ完了
- WPSの./configureにて以下のエラーになる
    - Enter selection [1-40] では「3」を選択

```
Testing for NetCDF, C and Fortran compiler

This installation NetCDF is 64-bit
C compiler is 64-bit
Fortran compiler is 64-bit


Your Fortran + NETCDF did not run successfully.
```

### 対処

NETCDFのインストール先は`/usr/local/netcdf-4.7.1/gcc44/`である。

.bashrcの設定に以下の行を追加したら解決した。

```
#for WPS configure (2019-10-08)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/netcdf-4.7.1/gcc44/lib/
```
インシデントとアクシデントの違い

#インシデントの意味と定義、アクシデントとの違いとは？
####インシデントとは「事件(ミス)」アクシデントとは「事故」です。

事件(ミス)があったが事故に至らなかった場合がインシデントであり、事件(ミス)が事故に至った場合がアクシデントということです。また、重大インシデントとは国が認定するもので、主に旅客機や鉄道など多くの人々の健康や生命に甚大な損害を与えかねない事象のことです。最近では機体や列車の損傷や故障等によって大事故に繋がる可能性のあった事象や状態をさす場合が多くなっています。

医療機関の場合には、ミスをしたけど患者に影響は無かった場合をインシデントといいます。医療現場では「ヒヤリハット」とも呼ばれています。ただ本来インシデントとヒヤリハットは同義ではありません。

##インシデントとアクシデントの例
インシデントとは何かについて看護師の業務を例に解説します。

####インシデントの例
看護師が間違った薬剤を患者に投与しようとしたが、同僚の看護師がミスに気づき指摘したので、間違った薬剤を投与しなかった。この場合はインシデントとなります。

####アクシデントの例
看護師が主治医の指示を誤認して、誤った薬剤の投与を行った。それによって、患者の容体が悪化した。この場合はアクシデントになります。

##最後に
インシデントとアクシデントの境界は曖昧であり、本来の意味である「事件(ミス)」と「事故」との境界ともズレがあります。

そのため、医療機関ごとにインシデントとアクシデントの境界に対して線引きを行い、何をインシデントとして取り扱うのか、何をアクシデントとして扱うのかを組織の中で話し合っておくことが大切です。
プロダクトマネージャー（PdM）のキャリアと役割について

プロダクトマネージャー（PdM）のキャリアと役割がなかなかイメージしづらい方も多い印象です。
プロダクトマネージャーって何をやる人で、どのようなキャリアを歩んで行くかを書いていきます。

<h1><b>プロダクトマネージャーの役割</b></h1>
まず、PdMの役割は大きく分けて下記となります。

<h4><b>「調査と計画」　→　「デザイン」　→　「実装とテスト」　→　「リリース」</b><h4>

プロダクトのライフサイクルは、企業によって異なりますが、大体上記のイメージで進めていきます。
※役割や体制も企業によって異なる部分は多いです。

<h3><b>調査と計画</b></h3>
プロダクト機能は調査と計画から始まります。次に何を作るかのアイディアの源泉は顧客からのリクエスト、競合分析、新しいテクノロジー、ユーザー調査、セールスやマーケティングのチームなど大きなプロダクトビジョンが大切となります。

プロダクトマネージャーの重要なミッションはプロダクトの長期計画を立て実行する事です。
関係各所の責任者と話合い、方向性を決め、考えられる機能、開発作業、競合の状況、顧客のニーズ、優先順位付けをして進めていきます。

プロダクトマネージャーは「何のためにやっているのか？」の問いに対して、答えられるビジョンや目的を明確にし、「どうすれば成功と言えるのか」の定義を決める事も大切です。
多くの企業がOKR（Objectives and Key Results／目標と主要な成果）のモデルを用いて、チームの最も重要なゴールについてコミュニケーションを取ります。測定可能な成果を上げるためにチームとともに力を尽くしていきます。


<h3><b>デザイン</b></h3> 
チームがこれから作るプロダクトの合意が出来たら、プロダクト機能をデザインします。

プロダクトデザインは単にユーザーインタフェイス（UI）のデザインやプロダクトの外観を定義するものではありません。プロダクトデザインとは、プロダクトの特徴と機能を定義するものです。
プロダクトデザインにおけるPdMの役割は企業やチームにより異なります。

例えば、PdMがデザインのゴール、ユースケース、要求事項、ワイヤーフレームを設計し、デザイナーに対してスペックの検討、レビューを反復行い、PdMに決定権が多い会社もあれば、デザイナーがほとんど意思決定権を持ち、PdMはプロジェクトマネジメントに徹するチームもあります。

<h3><b>実装とテスト</b></h3>
エンジニアがコーディングを始めてもPdMの役割は終わりではありません。実装の段階ではプロジェクトマネジメントの役割も担います。

エンジニアが実装をしている間に最も重要な役割は、エンジニアが効率よく働けるように支援する事です。PdMは定期的にチームの状況を観察し、進捗管理と調整をしていきます。

例えば、チームに進捗のバラつきが出た時に調整を行ったり、機能の実装が予想よりもリリースが難しい場合は、優先順位を検討する事もあります。

PdMはプロダクトの初期バージョンに関するフィードバックの収集とバグレポートも始めます。デザイン段階では良いと思われた機能が、実際に利用してみると期待した機能でない事があります。このような問題を早期に発見し、チームにユーザビリティの調査、社内でのテストを実施します。

ローンチ前にプロダクトの動作を確認する方法には、もうひとつユーザビリティ調査もあります。ユーザーや協力者にプロトライプを利用してもらい調査をしてもらう事もあります。
大手の企業ではユーザーリサーチャーがいることが多く、プロダクトマネージャーからの情報提供を受けて調査内容を開発し、実施します。小規模な企業ではPdMが兼任する事が多いです。

<h3><b>リリース</b></h3>
開発のプロセスが完了したら、プロダクトマネージャーはローンチをスムーズに進行させる必要があります。ローンチのプロセスはチームにより事なりますが、通常は次のような業務があります。

<b>・ローンチのチェックリストをすべて確認する</b>
法務などの重要なステークホルダーから最終的な承認を得たり、マーケティングやオペレーションなどのチームとの調整をします。

<b>・プロダクトのこの咲の進行を支援するチームの準備状況を確認する。</b>
カスタマーサービス・サクセスのチーム、オペレーションのチームとの調整になります。

<b>・考えられるすべての問題点に備える</b>
リリースが近づくと、必ず緊急性の高い問題が持ち上がります。PdMはその時のための存在と言えます。

ローンチが成功したら、PdMは社内にローンチした事を告知し、チームの労いましょう。
それから次のプロダクトとライフサイクルに備えます。

PdMはプロダクト作りに関わる企画段階～リリース、サービスの品質向上に関わるチーム体制・ライフサイクルの構築をし、サービスを世の中に広めていく役割を担います。

<h1><b>プロダクトマネージャーのキャリア</b></h1>

PdMの役割の後は、どのようなキャリアを歩めばPdMへ近づけるのでしょうか。
プロダクトマネージャーはエンジニアリングから転身する場合が多いですが、必ずしもそうとも限りません。
様々な職種からプロダクトマネージャーを目指す事が可能です。

<h3><b>プロダクトマネージャーで一番大切な事</b></h3>
プロダクトマネージャーで一番大切な事は以下になります。

<b>結果</b>
プロダクトマネージャーはプロダクトの結果にコミットする必要があります。
プロジェクトマネージャーは実行・納品に結果を求められ、ディレクターは一機能の改善に結果を求められる事がありますが、プロダクトマネージャーはサービス成功にコミットをする覚悟が必要です。

<b>視点</b>
プロダクトマネージャーは顧客と競合に目を向ける必要があります。
プロジェクトマネージャーは効率化・生産性向上がメインになる事から現場に目を向ける事が多くなります。

プロダクトマネージャーは顧客が何を求めているか？競合他社の製品の機能や強みを理解し、自社製品の差別化・戦い方を考える必要があります。

<b>業務内容</b>
プロダクトマネージャーの一番重要な仕事は意思決定と方針を決める事です。
開発しているプロダクトが「誰のために」、「何のために」必要なプロダクトなのか？
どういう状況になったら成功と定義するか（KGI・KPI設計、OKRなど）など、
エンジニア、デザイナーにビジョンを示し、ゴールを明確にする必要があります。

上記をどうやって身に着けていくかが重要となります。

<h3>まとめ</h3>
プロダクトマネージャーをスキルを身に着けるのに、一番の近道は開発フェーズ初期段階のサービスに携わる事です。
サービスを作り、成長をしていけば勝手にやらなければならない仕事と権限が増え、意思決定の回数も増えてきます。上流工程の人とも距離が近く、プロダクトマネージャーの仕事を近くで感じる事が出来ます。

上長にプロダクトマネージャーになりたいと伝え続ける事も重要です。キャリアを考えてくれる会社であれば、チャンスを手に入れる事も可能です。

プラットフォーマーでプロジェクトマネージャーをされている方は、なかなかプロダクトマネージャーの椅子は空かないので、プロダクトマーケターのような役割を担いグロースハッカーを目指すのも有だとは思います。
Maxトレーニング (3) jitterでのカメラ画像取り込みとオブジェクトによるエフェクト

## jitterによる映像の加工

jitterには、`jit.`で始まる各種のオブジェクトが存在します。PC内臓のカメラで画像を取り込んだり、映像の輝度やコントラストを変更したり、画像の拡大縮小・回転・色の反転・グレースケール変換など。[こちら](https://www.dropbox.com/s/8jv1ssoehabzsbe/jitterEffect.maxpat?dl=1
)からパッチをダウンロードし、開いてみて下さい


![スクリーンショット 2019-10-08 11.27.08](https://tva1.sinaimg.cn/large/006y8mN6gy1g7ql1na58lj30x50nnn7k.jpg)

パッチを開くと、jit.pwindow(小さい画面)は真っ黒の状態です
一番左上のオブジェクト`jit.grab`につながっている`open`を押した後に、`toggle`をクリックすると、内蔵カメラの映像が表示されます
映像信号は`s mainSignal`を通して、他のオブジェクトに送信されています
`s`は`send`オブジェクトの略称です
同様に、`r`は`receive`オブジェクトの略称です。よく使うので覚えておいて下さい

ここで活用されている各オブジェクトをより深く知りたい方は、Jitter Bookを読んでみて下さい。
http://okikata.org/ma3/jitterbook/Jitter_book.pdf
ここでは、jitterにおけるピクセルの扱い方から具体的なオブジェクトの活用法が記載されています。授業の中では余裕があればいくつか紹介していきますが、今回は今開いているパッチに使われている下記オブジェクトを詳しく見ていきます。



## このパッチに掲載されているjitterオブジェクト



- `jit.brcosa`：画像のbrightness(明度), contrast(コントラスト), saturation(彩度)を調整するオブジェクト
- `jit.rgb2luma`：画像の明るさに基づいてをモノクロ変換するオブジェクト
- `jit.robcross`：画像のエッジ検出を行うオブジェクト
- `jit.brass`：エンボス画像に変換するオブジェクト
- `jit.rota`：画像の回転, 拡大, 縮小を行うオブジェクト
- `jit.slide`：残像効果をつけることができるオブジェクト
  - 明るい背景で暗い物体が動く時：slide_upの値を大きくする
  - 暗い背景で明るい物体が動く時：slide_downの値を大きくする
- `jit.scissors`：画像を指定したcolumns(行), rows(列)に分割する
- `jit.glue`：分割された画像を再びつなぎ合わせる
- `jit.op`：別々の画像同士を重ね合わせる（各ピクセルのA, R, G, B値に対して演算を行う）
- `jit.world`：toggleをONにすると出力結果を別ウィンドウで表示する
  - fullscreen：チェックを入れるとフルスクリーン表示(抜けるときはESCキーを押す)
  - floating：チェックを入れると別ウィンドウを常に手前に表示する

## やってみよう！



> 1. [**sensorPlayer**パッチ](https://www.dropbox.com/s/1o8e3gjbsg2z46n/sensorPlayer.maxpat?dl=1)を参考に`send`オブジェクト、`receive`オブジェクトを使って[**someFunk**パッチ](https://www.dropbox.com/s/ixa35sulwtkua4a/someFunk.maxpat?dl=1)でセンサの値を見れるようにして下さい
> 2. **someFunk**パッチで受けたセンサの値をナンバーボックスに接続し、センサの値による各オブジェクトの振る舞いを確認してみましょう
> 3. [**someFuncMoviePlayer**パッチ](https://www.dropbox.com/s/xmhsuilvjchctja/someFuncMoviePlayer.zip?dl=1)を開き、`send`オブジェクト、`receive`オブジェクトを使ってセンサの値で再生速度をコントロールしてみましょう
[Git] 月ごとのコミット数を出力する

月ごとのコミット数を調べるときに使えます。

CI導入前のコスト算出に使いました。

リポジトリのディレクトリで下記を実行します。

```bash
month=("01" "02" "03" "04" "05" "06" "07" "08" "09" "10" "11" "12")
for m in "${month[@]}"
do
  echo "2019-$m\t"$(git log --date=iso --pretty=format:"[%ad] %h %an : %s" | grep 2019-"$m" | wc -l)
done
```

2重ループにすれば複数年でもチェックできそうです。

### 参考
* https://qiita.com/noracorn92/items/6210fa243a0892574499
* https://shellscript.sunone.me/array.html
ビルドとデプロイについて

#ビルドとデプロイとは
ソフトウェア開発してるとでてくる用語ですね。

辞書的意味
Weblio辞書さんより

##ビルド
ビルドとは、コンピュータやソフトウェア関連の用語としては、ソースコードとしてコーディングされたソフトウェアを、コンパイル、リグレッションテスト、リリースノートや関連ドキュメントの生成、第三者に提出したり配布したりするための専用のファイルの生成、などを行う一連の工程のことである。

##デプロイ
デプロイとは、主にネットワークを通じて提供されるWebアプリケーションなどのシステム開発工程において、システムを利用可能な状態にすることである。
デプロイ（deploy）という言葉は元々、配置する、展開するといった意味の英語である。デプロイはソフトウェアのリリースやインストールも含んだ意味の広い言葉であり、開発環境からステージング環境へシステムを反映させることも、ステージング環境から本番環境へ反映させることも、「デプロイする」と表現できる。

くだいてみる
辞書的な意味が結構わかりやすくてびっくりした。。

##ビルド
これまでソースコード1つのプログラムしかやってなかった経験からだと、書いたソースコードをちゃちゃっと機械語に翻訳して実行ファイルを作成するのがコンパイルだ、と思ってたんですが、
厳密には少し違うみたい。

大きなプロジェクトを作成するときなんかはソースコードのファイルはたくさんある。
そのそれぞれのソースコードをそれぞれ機械語に翻訳したあと、1つの実行ファイルにまとめるみたいな流れになるらしい。

この、ソースコードをそれぞれ翻訳するのがコンパイルで、コンパイルされたファイル達を1つの実行ファイルにまとめてあげるのがリンク。

ビルドっていうのはこのコンパイルとリンクをまとめて行っているみたいなイメージでいいのかな。

##デプロイ
ビルドしてできた実行ファイルを、実行する環境に合わせて、実際に実行できるようにすること。
まあデプロイしたらプレイできるんです。(雑)

インストールとどう違うねん！？！？！？みたいな疑問(僕は持たなかったけど持つ人いるかな)に対する答えとしては、

開発者がデプロイして「準備おっけーだよ」ってあげたやつはネットワーク上で利用できるようになる。例えば ブラウザでできるゲームとか。
インストールっていうのは自分のpcとかにソフトを入れて自分のpcだけで利用できるようにすること
@isoyamさんの記事を引用
OCI アカウント作成時に初期作成されるユーザ・グループとログイン・フロー

# やったこと
アカウント初期作成されるユーザとグループ、ログイン・フローとの関係性がわからなかったので図示した。

# 参考にしたもの

・[OracleCloudユーザ管理 個人的おすすめな管理方法](https://qiita.com/sugimount/items/4841297e2166104e51b9)

・画面の遷移と登録されている情報をみながら自分の解釈。(間違っていたらすいません。)

# ユーザ・グループとログイン・フロー
同名で、IDCS管理者とOCI管理者がそれぞれ作成されるので、混乱する。。

![idcslogin01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456818/ca9df5c8-3c3f-24b7-933d-c6f15f1966d3.png)
[CSS/HTML]IE11でmainタグの背景画像(SVG)が表示されない＆切れてしまう[IEバグ]


コーディングしててたまにはIEでも見てみたら、
**サイト全体の背景画像が表示されてなくて**衝撃が走ったのでまとめとく。

#参考サイト
[IE11におけるmain要素の扱い \- Qiita](https://qiita.com/rukiadia/items/9c8191590dc151d6ae85)
[IE11で背景に指定したSVGが正しく表示されない件 \- Qiita](https://qiita.com/soh-web/items/e4d2209b896d8ad70d35)

#IEだと背景が表示されない
もちろんChrome、Firefox、Safariでは表示が確認できた。
だがIEだけ真っ白な状態、、

もとの　HTMLとCSSはこちら。

```html:HTML
<main class="l-main">
  <!--------- 省略 --------->
</main>
```
```scss:SCSS
.l-main{
  background-color: rgba($gray,0.25);
  background-image:
    url("../img/main-bg-tubu-shiro.svg"),
    url("../img/main-bg-tubu-dot.svg"),
    url("../img/main-bg-tubu-sankaku.svg");
  background-size: 300px;
  // ※背景画像の部分だけ抜粋
}
```
##IEではmainタグが未サポートであることが原因

**未サポートとかあるのか。**

対策としてはとても簡単だった。

>main要素に「display: block」を付与する。
[IE11におけるmain要素の扱い \- Qiita](https://qiita.com/rukiadia/items/9c8191590dc151d6ae85)

これでブロック要素として扱ってくれるらしい。

```scss:SCSS
.l-main{
  display: block; // ←ここを追加！！
  background-color: rgba($gray,0.25);
  background-image:
    url("../img/main-bg-tubu-shiro.svg"),
    url("../img/main-bg-tubu-dot.svg"),
    url("../img/main-bg-tubu-sankaku.svg");
  background-size: 300px;
  // ※背景画像の部分だけ抜粋
}
```

これで表示されて解決、、、と思ったら、
表示はされるけど、**画面全体に出したいのに途切れて表示されてしまってた、、、**

#IEだとSVGの背景画像が切れる

表示はされてるが、**空白~画像~空白~、、、のような感じ**切れまくっていた。
調べてると**SVGであることが原因**だとわかった。

##Illustratorで書き出したSVGをそのまま使ったのが原因

対策はこれも簡単。

>・SVGタグにwidth,heightを追記
・SVGタグに「preserveAspectRatio=”xMinYMid”」を追記
[IE11で背景に指定したSVGが正しく表示されない件 \- Qiita](https://qiita.com/soh-web/items/e4d2209b896d8ad70d35)

```html:SVG
<svg width="300px" height="300px" preserveAspectRatio="xMinYMid" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300">
  <!--------- 省略 --------->
</svg>
```

他のブラウザと同じように表示された！！！
やったー！

#まとめ
IEで背景画像出てなくて焦ったけど、対策はあって簡単だったから良かった。
SVGについてはもう少し勉強しようと思った。
【コピペで済ませたい人向け】 rbenvのインストールを環境構築からパスチェックまとめ [2019版]


# コマンドを探しにきた人に
```
# macOS
brew tap homebrew/core && brew install apple-gcc42

# Ubuntu/Debian/Mint
sudo apt install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm5 libgdbm-dev

# CentOS/Fedora
yum install -y gcc-6 bzip2 openssl-devel libyaml-devel libffi-devel readline-devel zlib-devel gdbm-devel ncurses-devel

# openSUSE
zypper install -y gcc6 automake gdbm-devel libffi-devel libyaml-devel libopenssl-devel ncurses-devel readline-devel zlib-devel

# Arch Linux
pacman -S --needed base-devel libffi libyaml openssl zlib
```

```
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
eval $(rbenv init)
source ~/.bashrc

rbenv install 2.x.x
rbenv local 2.x.x
```

# 動かない場合（既存の環境など）
パスとバージョンを確認

```
which rbenv
rbenv -v

which ruby
ruby -v

which gem
gem -v

which bundle
bundle -v
```

※インストールしてもパスが適用されていない場合は手動で通す。

```
# [command]はパスが間違っているコマンド名
cd $(which ruby)
unlink [command]
ln -s $HOME/.rbenv/bin/[command] [command]
```

# 解説
[コマンドの最新はWiki参照](https://github.com/rbenv/ruby-build/wiki)
ここでは執筆時点の最新を公式Wikiより引用。

また、[bash_profileではなくbashrcに書く理由](https://qiita.com/dark-space/items/cf25001f89c41341a9fd)はリンク先の通り。

# 筆者環境
WSLを使用している。
実行環境にbashを使用しているのでzshやfishでは実行できないかもしれない。

```
cat /etc/os-release 
# NAME="Ubuntu"
# VERSION="18.04.3 LTS (Bionic Beaver)"
# ...
```

# 動機
rbenvの情報が多いので解説はいいとして、そういうのは既に分かっている側の立場としては検索するのも面倒なんでお手軽にできるものが欲しかった。
執筆時点では、後述の筆者環境のみ検証しており、必要に応じて他環境も追記したい。

# 読了後いいね！をお願いします。
どれだけの方に読んでもらっているか知りたいので、お手数をおかけしますがご協力いただけると嬉しいです。
Ubuntu16.04にCP-ABEをインストールする.

#ubuntu16.04にCP-ABEをインストールする方法
cp-abeのmakeに失敗するから忘れないように書いておく

必要なもの
1:cp-abe
http://acsc.cs.utexas.edu/cpabe/

2:libbswabe
http://acsc.cs.utexas.edu/cpabe/libbswabe-0.9.tar.gz

3:pbc
https://crypto.stanford.edu/pbc/

4:gmp
https://gmplib.org/

解凍

```
$tar -zxvf hogehoge.tar.gz
$tar --lzip -xvf hogehoge.tar.lz
```

cp-abe以外を適当な順番で

```
./configure 
make 
make install
```

する。エラーでたら頑張って


cp-abeのインストールでコンパイルするとエラーが発生する.


```
./configure
make LDFLAGS="-lgmp -lpbc -lcrypto -L/usr/lib/x86_64-linux-gnu -lglib-2.0 -lbswabe -lgmp"
```

```
policy_lang.y: In function ‘yyparse’:
policy_lang.y:67:38: error: expected ‘;’ before ‘}’ token
policy_lang.y: In function ‘eq_policy’:
policy_lang.y:212:21: warning: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument 3 has type ‘uint64_t {aka long unsigned int}’ [-Wformat=]
    (g_strdup_printf("%s_flexint_%llu", attr, n->value));
                     ^
policy_lang.y:215:21: warning: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument 4 has type ‘uint64_t {aka long unsigned int}’ [-Wformat=]
    (g_strdup_printf("%s_expint%02d_%llu", attr, n->bits, n->value));
                     ^
policy_lang.y: In function ‘yylex’:
policy_lang.y:391:18: warning: format ‘%llu’ expects argument of type ‘long long unsigned int *’, but argument 3 has type ‘uint64_t * {aka long unsigned int *}’ [-Wformat=]
   sscanf(s->str, "%llu", &(yylval.nat));
                  ^
policy_lang.y: In function ‘parse_attribute’:
policy_lang.y:577:17: warning: format ‘%llu’ expects argument of type ‘long long unsigned int *’, but argument 4 has type ‘uint64_t * {aka long unsigned int *}’ [-Wformat=]
   if( sscanf(a, " %s = %llu # %u ", s, &value, &bits) == 3 )
                 ^
policy_lang.y:596:26: warning: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument 4 has type ‘uint64_t {aka long unsigned int}’ [-Wformat=]
     (*l, g_strdup_printf("%s_expint%02d_%llu", s, bits, value));
                          ^
policy_lang.y:598:22: warning: format ‘%llu’ expects argument of type ‘long long unsigned int *’, but argument 4 has type ‘uint64_t * {aka long unsigned int *}’ [-Wformat=]
   else if( sscanf(a, " %s = %llu ", s, &value) == 2 )
                      ^
policy_lang.y:612:26: warning: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument 3 has type ‘uint64_t {aka long unsigned int}’ [-Wformat=]
     (*l, g_strdup_printf("%s_flexint_%llu", s, value));
                          ^
Makefile:49: ターゲット 'policy_lang.o' のレシピで失敗しました
make: *** [policy_lang.o] エラー 1
```

policy_lang.yの67行目を

```
 result: policy { final_policy = $1; }
```

こんな感じに直す.
するとコンパイルできるから
あとは
make install
でインストールできる.

cpabe-encでなんか出てきたら完了
Laravel サービスプロバイダ

## サービスプロバイダとは

- Laravelのサービスコンテナへのバインド処理で利用する機能。
- FWやアプリケーションに含まれるサービス(機能)の初期処理を行う。
- Laravelのライフサイクルでは、ビジネスロジックが実行される前に、サービスプロバイダのメソッドが呼ばれる。

## 役割

- サービスコンテナへのバインド
- イベントリスナーやミドルウェア、ルーティングの登録
- 外部コンポーネントを組み込む

## 基本的な動作

- Laravelの初期処理で、各サービスプロバイダの`register`メソッドが実行される。
- `register`メソッドでは、サービスコンテナへのバインドのみ行う。(メソッドの実行タイミングでは、サービスコンテナから他の機能のインスタンスを取得する処理を実行できないため。)
- すべての`register`処理が終わると、`boot`メソッドが呼ばれる。
- `register`メソッドの実装は必須、`boot`メソッドは任意。

## `defer`プロパティによる遅延実行

- `defer`プロパティを`true`に設定することで、アプリケーション起動時の`register`メソッドの実行を**遅らせる**ことができる(デフォルトは`false`)。
- この場合、`register`メソッドの実行タイミングを指定するため、`provides`メソッドもしくは`when`メソッドで指定する必要がある。

### providesメソッド

- サービスコンテナで解決する文字列を指定する。
- 文字列の解決をサービスコンテナに依頼したタイミングで、サービスプロバイダの`register`メソッドが呼ばれ、解決が行われる。

### whenメソッド

- イベントを指定する。
- 対象イベント名を配列で指定すると、リスナーが登録され、その中でサービスプロバイダの`register`メソッドが実行される。
- 設定したイベントが発行されると、このリスナーが発動して、`register`メソッドが実行される。

※ `provides`、`when`いずれの場合も、サービスコンテナでの解決やイベントの発行がアプリケーション内で実行されるまで、インスタンス登録は行われない。

### コード例

```php

class SampleServiceProvider extends ServiceProvider
{
    protected $defer = true;

    public function register()
    {
        $this->app->singleton('foo', function ($app) {
            return new Foo($app);
        });
        $this->app->singleton('bar', function ($app) {
            return new Bar($app);
        });
        $this->app->singleton('buzz', function ($app) {
            return new Buzz($app);
        });
    }

    public function provides()
    {
        return [
            'foo', 'bar', 'buzz'
        ];
    }
}
```

上記の例では、サービスプロバイダの`provides`メソッドで、文字列を要素とした配列を返している。ビジネスロジックで`foo`などのクラス名をサービスコンテナで解決すると、`register`メソッドが実行され、ロジック側にインスタンスが返される。

## 参考図書

[PHPフレームワーク Laravel Webアプリケーション開発 バージョン5.5 LTS対応](https://www.amazon.co.jp/gp/product/4802611846/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1)
Azuriteを使ったリモートからアクセス可能なAzure Storageテスト環境構築

# はじめに

Azure Storage にアクセスするアプリケーションを開発したとき、接続テストをするはずです。
以前まで公式サイトでは、Azure Storage Emulator を使ったテスト方法が紹介されていましたが、
最近、Azurite を使った方法も紹介されていますので、簡単に違いを紹介します。

# Azure Storage 開発時の課題

Azure Storage との通信をテストしたいとき、検証用のAzure環境があれば、そちらを利用することも可能ですが、
ローカルの開発環境に制限してテストしたいことがあると思います。
このとき、Azure Storage Emulatorを利用すれば可能ですが、制限があります。
説明を口述しますね。

## Azure Storage Emulator

"[Azure ストレージ エミュレーターを使用した開発とテスト](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-use-emulator)"に紹介されているように、ローカルに簡易的なAzure Storageサービスを起動することができます。
ただし、Localhostからしか利用できません。
これだと別ポートから起動したWebアプリからのアクセスができなかったり、Android(エミュレータ)やVMからのアクセスもできません。

![AzureStorageEmulator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179413/27c95cb8-94ad-d5d1-6294-de4a1a8caae1.png)

## Azurite

"[Azure Storage の開発とテストに Azurite オープンソース エミュレーターを使用する (プレビュー)](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-use-azurite?toc=%2fazure%2fstorage%2fblobs%2ftoc.json)"に紹介されているAzuriteは、オプションを変更することでAzure Storage Emulatorの制限を解除できます。
以下のようにWebアプリやAndroid EmulatorやVM, 別のリモートホストからもアクセスが可能になります。

※Firewall等も確認ください
※固定IPでアクセスしてください

![AzureStorageEmulator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179413/74fd7655-4b3b-c939-a266-35a827be3564.png)

具体的には以下の起動オプションを変更します。

```
npm i azurite -g
cd c:\AzuriteDataDirectory\
azurite --blobHost 0.0.0.0
```

上記コマンドでAzurite起動後に、別PCから以下URLにアクセスしてみてください。
XMLが表示されれば成功です。

* 【IPアドレス】:192.168.128.107
* 【コンテナ】:test(認証無しアクセス許可)

```
http://192.168.128.107:10000/devstoreaccount1/test?restype=container&comp=list&maxresults=1000&delimiter=%2F
```

![azurite_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179413/7f360578-ed64-4a1e-a191-84d67d8dcf3e.png)
Rails6 のちょい足しな新機能を試す91（ActiveRecord annotate編）

# はじめに

Rails 6 に追加された新機能を試す第91段。 今回は、 `ActiveRecord annotate` 編です。
Rails 6 では、 ActiveRecord で、発行される SQL にコメントを含めることができるように `annotate` メソッドが追加されました。
ログに出力して解析したり、デバッグしたりするときに便利そうです。

Ruby 2.6.4, Rails 6.0.0 で確認しました。

```shell
$ rails --version
Rails 6.0.0
```

今回は、User の CRUD を作り、一覧ページを表示するとき、そこで実行される SQL がどのコントローラのどのアクションから呼ばれているのかわかるようにしてみます。

# プロジェクトを作る

```shell
rails new rails_sandbox
cd rails_sandbox
```

# User の CRUD を作る

name をもつ User の CRUD を作ります

```shell
bin/rails g scaffold User name
```

# コントローラとアクションの名前を返すメソッドを定義する

`full_action_name` というプライベートメソッドを `ApplicationController` に追加します

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  private

  def full_action_name
    "#{self.class.name}##{action_name}"
  end
end
```

# ApplicationRecord に scope を追加する

`annotate` を使った scope を1つ `ApplicationRecord` に追加します。

```ruby:app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
  scope :called_from, ->(from) { annotate("called from #{from}") }
end
```

# UserController#index を変更する

`User.all` が `UsersController#index` から呼ばれていることがわかるように、修正します。

```ruby:app/controllers/users_controller.rb
class UsersController < ApplicationController
  ...
  def index
    @users = User.all.called_from(full_action_name)
  end
  ...
end
```

# 実際に一覧ページを表示してコンソールを確認する

`rails server` を実行し、ブラウザから http://localhost:3000/users にアクセスし、コンソールを確認します。
SQL 文にコメント"called from UsersController#index" が含まれていることがわかります。

```
...
  User Load (0.4ms)  SELECT "users".* FROM "users" /* called from UsersController#index */
...
```

# 試したソース

試したソースは以下にあります。
https://github.com/suketa/rails_sandbox/tree/try091_activerecord_annotate

# 参考情報

* [What is new in Rails 6.0](https://bogdanvlviv.com/posts/ruby/rails/what-is-new-in-rails-6_0.html)
* [Add support for annotating queries generated by ActiveRecord::Relation with SQL comments](https://github.com/rails/rails/pull/35617)