OmniAICreator/Qiita-1.07M huggingface dataset:
awscliでCPU使用率80%以上になったらアラートを上げる設定を入れる

## 準備
[対象のEC2インスタンスIDを取得](https://qiita.com/yuta_vamdemic/items/dbe493132716974bd0a8)
[連携対象のSNSのarnを取得](https://qiita.com/yuta_vamdemic/items/d132d0b8e4f7430d7fa5)
コンソール画面上から見てもOK

## オプションいっぱいのコマンド

```
aws cloudwatch put-metric-alarm --alarm-name "CPUUtilization80%" --namespace AWS/EC2 \
--metric-name CPUUtilization --dimensions "Name=InstanceId,Value=i-0219028c30d71bee2" --period 300 \
--statistic Average --threshold 80 --comparison-operator GreaterThanOrEqualToThreshold \
--evaluation-periods 1 --alarm-actions arn:aws:sns:ap-northeast-1:697333814928:Default_CloudWatch_Alarms_Topic  \
--ok-actions arn:aws:sns:ap-northeast-1:697333814928:Default_CloudWatch_Alarms_Topic 
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/ba076ef7-c990-9e91-d941-887913932c23.png)


# 参考
https://recipe.kc-cloud.jp/archives/9733
半角全角空白（スペース）トリミング

## 【序文】
SQLServer2017 で追加された [TRIM関数](https://docs.microsoft.com/ja-jp/sql/t-sql/functions/trim-transact-sql?view=sql-server-2017 "TRIM (Transact-SQL)")。
全角空白（任意の一文字）の削除にも対応している。

```SQL
1> SELECT TRIM(N'　' FROM N'　　令和元年');
2> GO

------
令和元年

(1 行処理されました)
```
少々違和感のある文法だけど。
しかしこの手の組み込みトリミング関数は半角空白にしか対応してない場合が多い。SQLServer で言えば、``LTRIM``、``RTRIM``関数とか。
全角空白にも対応させる必要に迫られ関数を自作する局面も多いが、難しい処理ではない。
特に簡単な方法を取り上げる。

## 【環境】

| SQLServer | SQLCMD | SSMS |
| ---- | ---- | ---- |
| 2017 | 14.0.1000.169 | v18.2 |
設定はデフォルト。
従って文字列の比較で半角・全角空白は区別されない。

## 【PATINDEX関数を利用する方法】
[PATINDEX関数](https://docs.microsoft.com/ja-jp/sql/t-sql/functions/patindex-transact-sql?view=sql-server-2017 "PATINDEX (Transact-SQL)")を利用すれば、半角・全角空白以外の文字が最初に現れる先頭位置を求めることができる。
後はその文字数分削除すれば良い。
ループで回し、先頭から一文字ずつ自力で調べて……といった冗長な実装を見かけることがあるが、そんな面倒なことをする必要はない。
実装例は以下。

```SQL
DECLARE @str    NVARCHAR(MAX)   = N' 　 令和元年';                  -- 対象文字列(先頭に半角・全角空白)
DECLARE @cutLen INT             = PATINDEX(N'%[^ ]%', @str) - 1;   -- カットする先頭文字列数

SELECT
      @str                              [処理対象文字列]
    , @cutLen                           [カットする先頭文字列数]
    , RIGHT(@str, LEN(@str) - @cutLen)  [処理後文字列(RIGHT版)]
    , STUFF(@str, 1, @cutLen, N'')      [処理後文字列(STUFF版)]
;
```

``N' 　 令和元年'`` は `` ``+``　``+`` ``+``令和元年`` と半角・全角空白が先頭に含まれる。
``N'%[^ ]%'`` は ``^``+`` `` で半角・全角空白以外の意味。

実行結果は以下。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/6da2c1ff-5b7b-ad75-e129-efe3cfb71396.png" width=50%>

トリミング処理は ``RIGHT`` ``STUFF`` 関数のどちらでも良い。
パフォーマンスの差は未検証だが、誤差の範囲だろう。お好きな方を。
勿論、先頭に半角・全角空白が含まれないケースでもこのコードは正しく動作する。
また半角・全角空白が区別される環境でも、``N'%[^ ]%'`` に全角空白を追記し、``N'%[^ 　]%'`` とすれば良い。
半角・全角が区別される環境については別投稿にまとめたので[そちら](https://qiita.com/god19/items/638c2243d764070c6a51 "…まさか、ココは半角・全角空白の区別がなかった世界！？")参照。


## 【自力で空白を調べるアルゴリズム】
関数化すれば以下の処理だけ書けば良い。トリミング対象文字列は引数で与えられるものとする。

```
1. 引数で与えられた文字列の先頭 1文字が空白以外の場合は処理を終了
2. 引数で与えられた文字列の先頭 1文字を削除し、それを引数に自分自身をコール
```

実装例は以下。

```SQL
IF OBJECT_ID (N'dbo.LTrimEX', N'FN') IS NOT NULL
    DROP FUNCTION LTrimEX;
GO
-- 全角空白対応版 LTRIM
CREATE FUNCTION dbo.LTrimEX(@STR NVARCHAR(MAX))
RETURNS NVARCHAR(MAX)
AS
BEGIN
    IF LEFT(@STR, 1) = N' '                                 -- 先頭1文字が空白の場合
        SELECT @STR = dbo.LTrimEX(STUFF(@STR, 1, 1, N''));  -- 先頭1文字を削除し再帰呼び出し
    RETURN(@STR);
END;
GO
```

実行例は以下。

```SQL
1> PRINT dbo.LTrimEX(N' 　 令和元年');
2> GO
令和元年
```


関数の中身はたった 3行。
簡単なアルゴリズムなので大抵のプログラミング言語にも移植できるだろう。
…まさか、ココは半角・全角空白の区別がなかった世界！？

## 【序文】
以前、SQLServer における半角・全角空白の扱いについて個人的には色々と調べたが、記憶が曖昧になってきた。
改めて調べ直し記録に残す。

## 【環境】

| SQLServer | SQLCMD | SSMS |
| ---- | ---- | ---- |
| 2017 | 14.0.1000.169 | v18.2 |
各種設定はデフォルト。

## 【後ろ空白】
文字列の比較。
``A`` と ``A　`` は一般的なプログラミング言語なら、後ろ空白有無によって異なる文字列と判定されるだろう。
しかし、SQLServer では等しいと判定される。

```SQL
1> IF N'A' = N'A   ' PRINT N'一致' ELSE PRINT N'不一致';       -- 後ろ半角空白
2> GO
一致
```

厳密にはこれは ANSI/ISO SQL-92 specification の仕様であり、後ろに空白を足して長さを揃えて比較するとのこと。
[SQL Server - 後ろにスペースがある場合の文字列の比較について](https://sql55.com/column/string-comparison.php "SQL Server - 後ろにスペースがある場合の文字列の比較について")

では全角空白の場合はどうか。

```SQL
1> IF N'A' = N'A　　　' PRINT N'一致' ELSE PRINT N'不一致';    -- 後ろ全角空白
2> GO
一致
```

こちらも一致。両者の後ろに混在する半角・全角が存在し、数が異なる場合も一致する。

```SQL
1> IF N'A 　 ' = N'A　 　 　' PRINT N'一致' ELSE PRINT N'不一致';  -- 後ろ半角・全角空白
2> GO
一致
```

## 【前空白】
前述はあくまでも文字列末尾の仕様であり、先頭空白は比較対象となる。

```SQL
1> IF N'A' = N'  A' PRINT N'一致' ELSE PRINT N'不一致';       -- 先頭半角空白
2> GO
不一致
```

しかし、両者の先頭空白文字数が同じであれば、半角全角の違いがあっても同じ文字列として判定される。

```SQL
1> IF N'  A' = N'　　A' PRINT N'一致' ELSE PRINT N'不一致';    -- 先頭半角・全角空白
2> GO
一致
```

## 【途中空白】

文字列の途中に存在する半角・全角空白も同様。

```SQL
1> IF N'A B' = N'A　B' PRINT N'一致' ELSE PRINT N'不一致';     -- 途中半角・全角空白
2> GO
一致
```

## 【半角・全角空白の比較】
つまり、文字列の比較で半角空白と全角空白は区別されない、ということになる。

```SQL
1> IF N' ' = N'　' PRINT N'一致' ELSE PRINT N'不一致';         -- 半角・全角空白
2> GO
一致
```

と、ここまで空白に限定してきたが、そもそもデフォルトの設定では、文字列の比較で半角・全角カナを区別されない。

```SQL
1> IF N'ｱ' = N'ア' PRINT N'一致' ELSE PRINT N'不一致';         -- ｱ・ア
2> GO
一致
```

半角空白と全角空白が区別されないのもこの仕様に沿っているだけだろう。
[照合順序と Unicode のサポート - SQL Server _ Microsoft Docs](https://docs.microsoft.com/ja-jp/sql/relational-databases/collations/collation-and-unicode-support?view=sql-server-2017 "照合順序と Unicode のサポート - SQL Server _ Microsoft Docs")

| オプション | [説明] |
| --------- | ------ |
| 文字幅を区別する (_WS) | 全角文字と半角文字を区別します。 このオプションを選択しないと、同じ文字の全角表現と半角表現は、並べ替えを行う際に SQL Server によって同じものと見なされます。 文字幅を区別しないように指定する唯一の方法は、このオプションを省略することです。 |

照合順序の設定、確認手順は以下参照。
[データベースの照合順序の設定または変更 - SQL Server _ Microsoft Docs](https://docs.microsoft.com/ja-jp/sql/relational-databases/collations/set-or-change-the-database-collation?view=sql-server-2017 "データベースの照合順序の設定または変更 - SQL Server _ Microsoft Docs")

以下はデフォルトの照合順序設定。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/221e4614-5fdf-db24-27cd-a72e0d6d8336.png" width=40%>

``_WS``オプションを設定すると、半角全角は区別されるようになる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254888/f3a64b85-0bee-5558-a2e4-ec9fe0c31781.png" width=40%>

```SQL
1> IF N'ｱ' = N'ア' PRINT N'一致' ELSE PRINT N'不一致';         -- ｱ・ア
2> IF N' ' = N'　' PRINT N'一致' ELSE PRINT N'不一致';         -- 半角・全角空白
3> GO
不一致
不一致
```

## 【組み込み関数】
組み込み関数も文字列比較処理が含まれていれば照合順序の影響を受ける。


```SQL
照合順序 : Japanese_CI_AS
1> PRINT REPLACE(N'ｱアイウエオ', N'ｱ', N'');                   -- ｱ 削除
2> GO
イウエオ
```

```SQL
照合順序 : Japanese_CI_AS_WS
1> PRINT REPLACE(N'ｱアイウエオ', N'ｱ', N'');                   -- ｱ 削除
2> GO
アイウエオ
```

## 関連投稿
[PostgreSQL 文字列末尾スペース、文字列型の上限、暗黙型変換等の備忘録](https://qiita.com/god19/items/1e21ef8bd86c65693aba "PostgreSQL 文字列末尾スペース、文字列型の上限、暗黙型変換等の備忘録 - Qiita")
Monodepth2を動かすメモ(仮)

## 概要
1. CUDA10.0のDocker imageで環境構築
2. PyTorchのインストール
3. Monodepth2を動かす

## 結論
* すぐ動かせるので簡単に試せる！すごい！！

## てｓｔ
* 「Digging Into Self-Supervised Monocular Depth Estimation」のソースコードがGitHubで公開されている
  * https://github.com/nianticlabs/monodepth2
* testのサンプルを動かすところまで


### 環境構築
* Anacondaは使わない

```
docker pull nvidia/cuda:10.0-cudnn7-devel-ubuntu16.04
docker run --runtime=nvidia -it --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix/:/tmp/.X11-unix -e QT_X11_NO_MITSHM=1 -v /data:/data -w=/data nvidia/cuda:10.0-cudnn7-devel-ubuntu18.04
cd /data && git clone https://github.com/nianticlabs/monodepth2.git
```

### 関連インストール
* 流用しているので不要なライブラリも含む

```
apt update
apt-get install -yq --no-install-recommends --no-upgrade software-properties-common curl  python3-dev python3-tk  locales  libatlas-base-dev libprotobuf-dev libleveldb-dev  libsnappy-dev libhdf5-serial-dev protobuf-compiler libboost-all-dev libgflags-dev libgoogle-glog-dev liblmdb-dev opencl-headers ocl-icd-opencl-dev libviennacl-dev libopenexr-dev libsm6 libxext6 libxrender-dev
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python3 get-pip.py --force-reinstall
pip install --no-cache-dir Cython numpy protobuf openexr torch torchvision tensorboardX matplotlib opencv-python
```

### 実行
```
cd /data/monodepth2/
python3 test_simple.py --image_path assets/test_image.jpg --model_name mono+stereo_640x192
```

## まとめ
* 親切な設計とREADMEはありがたい…
awscliでEC2インスタンス操作関連でよく使うコマンド

# EC2インスタンス情報を取得する系コマンド

## EC2インスタンス一覧

```
aws ec2 describe-instances
```

## ID一覧
jsonストリームを加工するため、`jq`コマンドが必要

```
aws ec2 describe-instances | jq '.Reservations[].Instances[].InstanceId'
```

## タグでフィルター

```
aws ec2 describe-instances --filter "Name=tag:Name,Values=ClowdWatch_test"
```

## インスタンスIDを指定して取得

```
INSTANCEID='i-0219028c30d71bee2'
aws ec2 describe-instances --instance-ids ${INSTANCEID}
```

## インスタンスIDとNameタグを取得

```
aws ec2 describe-instances | jq '.Reservations[].Instances[]|{InstanceId, Tags}'
```

## AMI一覧

```
aws ec2 describe-images --owners self | jq '.Images[] | {Name, ImageId}'
```


## キーペア一覧

```
aws ec2 delete-key-pairs
```

## キーペア削除

```
aws ec2 delete-key-pair --key-name  master-key
```

## セキュリティグループ一覧

```
aws ec2 describe-security-groups
```

## セキュリティグループ削除

```
aws ec2 delete-security-group --group-name admin
```

# 参考
https://qiita.com/toshiro3/items/37821bdcc50c8b6d06dc
「ITエンジニアのためのビジネスアナリティクス」読書メモ【更新途中】

## 書籍情報

[ITエンジニアのためのビジネスアナリティクス](https://www.amazon.co.jp/gp/product/4822285030/)
2019/07/20読了

## 個人的に印象に残った個所とメモ(※更新途中)

### ビジネスルールからのソリューション構築
- ビジネスの整合性とアジリティというもろ刃の剣
- ビジネスルール⇒構造化言語 RuleSpeak
-「ゾウを見よう」⇒盲人とゾウ

### 第1章
ビジネスアナリシスの基本原則

- ビジネス担当者とビジネスについて話すときには、日常的に使用する用語以外のものを用いてはならない
- 「ユーザー」という語を用いないこと。
「ThoughtWorksアンソロジー」読書メモ【更新途中】

## 書籍情報
[ThoughtWorksアンソロジー アジャイルとオブジェクト指向によるソフトウェアイノベーション](https://www.amazon.co.jp/dp/487311389X/)
2019/07/19読了

## 個人的に印象に残った個所とメモ(※更新途中)

9つのルール

- 1つのメソッドにつきインデントは1段階までにすること
- else句を使用しないこと
- すべてのプリミティブ型と文字列型をラップすること
- 1行につきドットは1つまでとすること
- 名前を省略しないこと
- すべてのエンティティを小さくすること
- 1つのクラスにつきインスタンス変数は2つまでにすること
- ファーストクラスコレクションを使用すること
- Getter,Setter,プロパティを使用しないこと
「実践ドメイン駆動設計」読書メモ【更新途中】

## 書籍情報

[実践ドメイン駆動設計 (Object Oriented SELECTION)](https://www.amazon.co.jp/dp/479813161X/)
2019/07/19読了

## 個人的に印象に残った個所とメモ(※更新途中)

### p20.要するにユビキタス言語って・・・
- 業務で使う用語のこと？⇒NO
- その業界で標準として定められている用語のこと？⇒NO
- ドメイン・エキスパートが普段つかっている言葉のこと？⇒NO

⇒ユビキタス言語とは「ドメインエキスパートやソフトウェア開発者を含めたチーム全体で作り上げる共有言語」

### p24.DDDを採用する事業価値
- 組織として、ドメインに関する有用なモデルを獲得できる ⇒ ビジネス的に最も重要なところの作業に注力する。まず注目するのはコアドメイン。モデリングをやりすぎたりはしない。
- 事業について、より洗練された正確な定義ができて、さらに深く理解できる
- ドメインエキスパートが、ソフトウェアの設計に貢献できる
- よりよいユーザー体験を提供できる
- モデルとモデルの間に、明確な境界を定められる
- エンタープライズアーキテクチャが、より整理されたものとなる
- アジャイルでイテレーティブなモデリングを、継続的に行える
- 戦略的な面でも戦術的な面でも、新しいツールを使える

### p43.ドメインとサブドメインそして境界づけられたコンテキスト
- ドメイン
    - 商品カタログサブドメイン
    - 注文サブドメイン
    - 請求サブドメイン
    - 発送サブドメイン

　　　｜Eコマースシステム
　　　｜在庫システム
　　　｜外部の需要予測システム

　　　｜在庫サブドメイン

### p48.支援ドメインと汎用サブドメイン
### p58.境界づけられたコンテキストの意味を知る
   - コンテキストは主として「言語的な境界」となる。

```
　　　例)銀行取引コンテキスト・ アカウント
　　　　 文学コンテキスト・・・ アカウント
　　　　⇒ 全く違う意味だが、名前は同じ。
```
　　　　

### p84.コンテキストマップ

### p121.ヘキサゴナルアーキテクチャ

### p163.エンティティ
- ドメインよりもデータを気にする場合、データモデルがオブジェクトに反映され、「ドメインモデル」の
ほぼすべての概念が、一つのエンティティと大量のゲッター／セッター群になってしまう。  
- エンティティには一意な識別子があって、変化するという特性がある。　⇒　これが「値オブジェクト」と異なる点  

- 【CRUDベースの手法との対比】

### p209.値オブジェクト

### p235.JavaBeanの仕様の悪影響。流れるような表現力の喪失
### p273.ドメインイベント
### p319.モジュール
- Javaではパッケージ
- C#では名前空間
- Rubyではmodule

DDDの文脈において、モデル内のモジュールは、ドメインオブジェクト内のひとまとまりのクラス群をまとめる、
名前付きコンテナとして機能する。
その目的は、別のモジュールのクラス群との結合を少なくすること。

適切な名前を付けることも重要になる。
モジュールの名前は、ユビキタス言語の重要な一面である。

ドメインの概念についての最新の状態を、モジュールに込めるようにしよう。

モジュールの「べし」「べからず」

- モジュールは、モデリングの概念にフィットするように設計すべし
- モジュールの名前は、ユビキタス言語に従うべし
- コンポーネントの型やモデル内で使っているパターンなどから、モジュール名を機械的に決めるべからず
- モジュールは、疎結合になるよう設計すべし
- 対等なモジュールどうしの結合が必須になる場合は、循環依存にならないようにすべし
　(対等なモジュールとは、同じ「レベル」にある、つまり、同程度の重要性だったり、同じ方向を向いて作られていたりするモジュールを指す)
- 親子関係のモジュールの結合の場合は、ルールを多少緩和すべし（親モジュールは上位レベルにあるモジュール、子モジュールは下位レベルにあるモジュールを指す)
- モジュールをモデルの静的な概念とせず、モジュールが取りまとめるオブジェクト群にあわせて変えるべし

### p333.集約
コアドメイン（スクラム）における集約の使用

### p491.アプリケーション
プログラムって、要は使えてナンボのもんでしょ Linus Torvalds
VirtualBox + Ubuntuでのパーテーション拡張方法（CUI）

# 概要
やってること事態はQiitaにも同じような記事が多数あったがUbuntu+CUIの記事が見つからず、苦労したため手順を残す。
皆さんの参考になれば幸いです。
また注意事項としては、手順を間違えるとゲストマシンが起動不能になることもあるので、クローンを取得してから実施すると安心です。
※本記事通り実施しても破損する可能性がありますのでそこは自己責任でお願いいたします。

# 環境
- ホストマシン : Windows10
- Virtual Box : 6.0
- ゲストマシン : Ubuntu 18.04
    - ストレージはvdiで作成済み

# ホストマシンでの作業
### 該当ゲストマシンをシャットダウン
もちろん、ゲスト内からshutdownコマンドでシステムを終了してもOK

### 仮想HDDの拡張
該当の仮想HDDがどこに保存されているかを確認。
その後、VBのマネージャーから該当仮想マシンの設定画面を開くと画像のような画面が見える
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125791/47a53bf4-409c-37c3-5bc4-1791afb45275.jpeg)
パスはコピーできるので、画像のように右クリックでコピーしておく

その後、コマンドプロンプトで下記コマンドを実施

```
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" modifyhd "先程コピーしたパズ" --resize 20480
```

文字列で打ち込む必要があるので"もそのまま打ち込むこと。
VBboxManage.exeはのパスはデフォルトの場所です。変更してる場合は合わせて変更してください。
resizeの容量はMBで指定できます。
1GB=1024と記載してください。上記の例では20GBになります。
その後、ゲストマシンを起動。

# ゲストマシンでの作業

```shell
# 現在のファイルシステムを確認
df -h 
# partedを起動
sudo parted
# 増やしたいパーティションの番号と終端アドレス（容量）を確認
(parted) p free
# 確認したパーティションの番号でリサイズを開始（今回は仮に2とする）
(parted) resize 2
Warning: Partition /dev/sda1 is being used. Are you sure you want to continue?
Yes/No? Yes
# 最大限拡張するなら先程確認した終端アドレスを入力  
End?  [10.0GB]? 20GB
# 確認
(parted) p free
# partedを終了
(parted) q
# fstabを変更（今回のファイルシステムは仮にsda2とする）
sudo resize2fs /dev/sda2
# 念の為に再起動
sudo reboot
# 再度ログインしたあと、ファイルシステムを確認
df -h
```

これで容量が増えていれば成功です！
お疲れさまでした。

ブログ始めました、よかったら遊びに来てください
https://red-full-moon.com/
Laravelのユニットテストでサービスコンテナに入れるrequestを作る方法

# 背景
`Request::path()`でその時のリクエストを元に処理をするような機能をテストをしようとした時に、FacadeのMockeryの機能を使って

```php:Example.php
use Request;

...

    $request = Request::shouldReceive('path')->andReturn({欲しいパス});
    app()->instance('request', $request);
```

という感じでサービスコンテナに突っ込もうとしたら、以下のように怒られた。

```
BadMethodCallException: Method Mockery_1_Illuminate_Http_Request::setUserResolver() does not exist on this mock object
```

正直なところよく分からないが、どうやらサービスコンテナにrequestを突っ込むためには`setUserResolver()`というメソッドも定義してあげないといけないらしい。
そんなところまで定義しなきゃいけないとかmockを使うメリットが無くなるので普通にrequestインスタンスを作ってサービスコンテナに入れる方法にしたというもの。

# 結論
```php:ExampleTest.php
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
use Illuminate\Http\Request;

...

    $symfonyRequest = SymfonyRequest::create($uri);
    $request = Request::createFromBase($symfonyRequest);
    app()->instance('request', $request);
```

# 解説
[Laravel API](https://laravel.com/api/5.4/Illuminate/Http/Request.html)をみた限りでは、特にコンストラクタは無く、[サーバー変数から作成する方法](https://laravel.com/api/5.4/Illuminate/Http/Request.html#method_capture)か、[SymfonyRequestから作成する方法](https://laravel.com/api/5.4/Illuminate/Http/Request.html#method_createFromBase)くらいしか見つからなかった。
サーバー変数をユニットテストでいじるのは違う気がしたので後者を選択。
`SymfonyRequest`は[コンストラクタ](https://github.com/symfony/symfony/blob/6916822e463ad23190b7c97f709de2dfb7acecd7/src/Symfony/Component/HttpFoundation/Request.php#L237-L240)でインスタンスを作れるので、これで作れば良い。
「エンジニアリング組織論への招待」読書メモ

2019/07/18 読了
個人的に印象に残った内容や用語の記録、メモ

## マーカー／メモ
- エンジニアリングは「実現」の科学
- 仮設法。わずかな痕跡から、それを説明可能とする大胆な思考展開、モデル化を行い、その証拠を探す
- BSとP/Lは微分積分の関係
- アジャイルは3倍の成功率、1/3の失敗率。大規模プロジェクトほど効果あり
- トヨタの特殊工と多能工
- 心理的安全とは、高い生産性を実現するための追込み法。ぬるま湯的な安心ではない
- エントロピー増大の法則に対しての散逸構造論、自己組織化
- 単純なルールが複雑な構造を作る「創発」。管理者のいない中で秩序を構築していく様子
- クールエイドを飲むな
- 役割を分けない
- 経験のみを知識に変える
- プリンシパル、エージェント理論
- CCPM、ToC理論。サバ取り。プロジェクトバッファ
- 見積り手法の一つ、Tシャツサイズ。
- 生産性とは
- 技術的負債、最初のコードは借金と同じ。固定的箇所と変動的箇所を設計。ジェンガの例
- 社内における取引コスト
- 管理会計の罠。企業内部に技術組織を持つのは取引コストを減少させるため
- OKR。目標による管理と、透明性の重視。目標がノルマにならないようにする
サクッとDockerでpyspark on jupyter notebookを試してみる

# 本記事の背景・目的・対象者
[サクッとDockerでPySparkを試してみる](https://qiita.com/yuma300/items/e411987ca0c3524b8ae6) にてPySparkを用いたETLスクリプトで解析しやすいデータを生成できるようになりました。
こうなると実際にその解析しやすくなったデータを解析したくなりますね。昨今データ解析でよく使われるのがjupyter notebookというツールです。

前回同様本記事では jupyter notebook の詳しい説明はしません。 
従って、本記事の対象者はこれからデータ基盤エンジニアを目指す人や目指すかどうかはおいといてデータ基盤エンジニアの仕事に興味がある人やとにかくjupyter notebookをいじってみたい！という人を対象としています。


# jupyter notebookとは
jupyter notebookは解析クエリや解析スクリプトのエディタ、解析結果のビジュアライズがセットになったWebベースのGUIを提供してくれます。

従ってどこかで jupyter notebookサーバーが動いていてそこへブラウザでアクセスして操作するという使用方法になります。jupyter notebookはあくまでGUIの提供をしているだけで実際のクエリエンジンや解析スクリプト言語の実行環境は提供しておらず jupyter notebook がそれらを使う形となります。

jupyter bookで使用できるクエリエンジンやスクリプト言語は多種多様ですが今回はPySparkを使います。

# 準備
jupyter notebookの公式がdockerイメージを用意してくれているのでそれをそのまま使わせてもらいます。[こちら](https://github.com/yuma300/docker-pyspark-try)にjupyter notebookを簡単に使えるようにしたリポジトリを用意しておきました。


```
$ git clone git@github.com:yuma300/docker-pyspark-try.git
$ cd docker-pyspark-try
$ docker-compose up -d jupyter
```

これで準備完了です。あとは試してみるだけです

# 実行
ブラウザで `http://localhost:8890` にアクセスします。すると以下の画面が表示されます

![Screenshot from 2019-09-09 00-22-53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9278/4192e46a-b198-e63d-41cf-f4b0079b759c.png)

Passwordに `12345678` と入力して `Login`ボタンを押下します。
ログインできると以下の画面が表示されるので `New` ボタンを押下します。

![Screenshot from 2019-09-09 00-23-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9278/c48f4f5a-3d62-82ee-9ad3-4a9733a83d6f.png)

以下の画面のようにエディタが表示されます。

![Screenshot from 2019-09-09 00-24-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9278/ba299a83-2134-647d-ec53-6d64e8715478.png)

フォームに以下のスクリプトを入力して `Run` ボタンを押下すると結果が出力されます。

```
from pyspark import *
from pyspark.sql import *
from pyspark.sql.types import *

conf = SparkConf()
sc = SparkContext.getOrCreate(conf=conf)
sqlContext = SQLContext(sc)


df = sqlContext.read.format('com.databricks.spark.csv') \
    .options(header='true', inferschema='true') \
    .load('/home/jovyan/work/sample.csv') 

df.where('id < 3').show()
```

`.load('/home/jovyan/work/sample.csv') ` この部分でcsvを読み込んでいます

`df.where('id < 3').show() `の部分で実際に解析処理を行ってます（解析というほど大層な事はしてないですが）。


# 採用目的

現在私が所属するbitbankではデータ基盤エンジニアの採用を行っております。興味を持たれた方は是非下からご応募よろしくお願いします。

https://career.bitbank.cc/engineer-data
AWSーGCP間をVPNでつないでみた

AWSとGCPの間をIPSec VPNでつないでみました。

# 構成

AWS側にVirtual Private Gateways、GCP側にVPN Gatewayを用意して、両者をIPsec VPNで接続します。

![vpn-gcp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/c8e3f327-784e-0185-50c1-a9d8b4be3937.png)

GCPのドキュメントにはAWSと接続可能との記述があります。(英語版)
https://cloud.google.com/vpn/docs/concepts/overview
> A gateway that is connected to a Cloud VPN gateway. A peer VPN gateway can be one of the following:

> - Another Cloud VPN gateway
> - A VPN gateway hosted by another cloud provider such as AWS or Azure
> - An on-premises VPN device or VPN service

# 接続結果

AWS側

<img width="646" alt="aws-gcp.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/0d04d7db-bfea-314b-4f1b-33826381084a.png">


GCP側

<img width="1139" alt="gcp-aws.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/63092d85-d440-5fc4-8dd3-82b01a87e221.png">


# 必要なもの

- GCPのアカウント
- AWSのアカウント

# 構築手順

Pre shared keyとIP以外はデフォルト値で接続できました。

### 1. GCP: VPN connectionの作成開始

Classic VPNを選択します。

<img width="376" alt="gcp-1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/10afb043-1bc9-4f39-d701-7b0163b82d5b.png">

名前等指定します。IP addressはこの画面から新規に作成します。

<img width="376" alt="gcp-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/e67f0a95-8db7-8ace-1b64-fb6d9e057cfa.png">

### 2. AWS: Virtual Private GatewayとCustomer Gatewayの作成

Virtual Private GatewayとCustomer Gatewayを作成します。
Customer Gateway作成時に、1.で作成したIPを指定します。

### 3. AWS: VPN Connectionの作成

VPN Connection作成時に、2.で作成したVirtual Private GatewayとCustomer Gatewayを指定します。
また今回はルーティングはStaticにしたので、GCP側のCIDRを指定します。
Pre-Shared Keyは指定しないまま、作成します。

### 4. GCP: Tunnelの指定

Remote peer IP addressに3.で作成したtunnelのOutside IP Addressを指定します。
Remote network IP rangesには、AWSのVPCのCIDRを指定します。
IKE pre-shared keyを作成して、Doneをクリックします。

tunnelは2個必要なので、上記手順をもう１回繰り返します。

<img width="379" alt="gcp-3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/00786e54-aa4d-7998-25b1-1b449b84f306.png">

tunnelを2個指定したらCreateをクリックしてVPN connectionを作成します。

<img width="372" alt="gcp-4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192584/404be0ab-ab5d-6f74-2ac8-086a2c223291.png">

### 5. AWS: VPN ConnectionにPre-Shared Keyを設定

4.で作成したIKE pre-shared keyを、VPN Connectionの各tunnelのPre-Shared Keyに設定します。
tunnelは1個づつしか変更できないため、少し時間がかかります。

### 6. 完成
python 2.x の tkinter で画像を表示したいけど ImageTk が読み込めなくてエラーになるのを解決する方法

ターミナルから以下のコマンドを実行します。

```bash:terminal
sudo apt-get install python-imaging-tk
```
#参考文献
- https://stackoverflow.com/questions/48317606/python-cannot-import-imagetk
HackerRank 30days of Code Python3で解いてみた

##はじめに
未来電子テクノロジー（https://www.miraidenshi-tech.jp/intern-content/program/）
でインターンをしているrayaと申します。
プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

##今回の内容
HackerRankの30Days of Codeを解いているので、復習で少しずつまとめていきます。

##Day0
print関数を使う問題。

```python
input_string=input()
print("Hello, World")
print(input_string)
```
##Day1
入力された値のデータ型を指定する問題。同じデータ型だから足し合わせられる。
double型は、小数の中でも小数点以下の桁数が多い場合のデータ型だそうですが、Python3では扱わないのでfloat型で解きます。

```python
i = 4
d = 4.0
s = 'HackerRank '

a=int(input())
b=float(input())
c=str(input())
print(i+a)
print(d+b)
print(s+c)
```

##Day2
計算問題。関数に渡される引数で式を定義する
・round()関数：round(数値)で浮動小数点数の数値を整数に四捨五入する。第２引数には小数点以下何桁までを四捨五入して示すか指定できる。　

```python
def solve(meal_cost, tip_percent, tax_percent):
    tip = meal_cost * tip_percent / 100
    tax = meal_cost * tax_percent / 100
    total_cost = meal_cost + tip + tax
    print(round(total_cost))
```
##Day3
条件分岐の問題。

```python
if __name__ == '__main__':
    N = int(input())
    if N % 2 != 0:
        print("Weird")
    elif 2 <= N <= 5:
        print("Not Weird")
    elif 6 <= N <= 20:
        print("Weird")
    else:
        print("Not Weird")
```
##Day4
クラスとコンストラクタを定義する問題。コンストラクタ（def --init--()）はPersonクラスのインスタンスを作ることで呼び出される。selfはインスタンス自身を示し、インスタンスの引数をinitialAgeに代入し、そのInitialAgeが適切な値（正の数）ならインスタンス変数ageに代入する。インスタンス変数はself.変数名の形で定義して、原則クラス内のメソッドで呼び出せる。

```python
class Person:
    def __init__(self,initialAge):
        if initialAge < 0:
            print("Age is not valid, setting age to 0.")
            self.age = 0
        else:
            self.age = initialAge

    def amIOld(self):
        if self.age < 13:
            print("You are young.")
        elif 13 <= self.age < 18:
            print("You are a teenager.")
        else:
            print("You are old.")

    def yearPasses(self):
        self.age += 1
```

##Day5
for文でループ処理する問題。
・format()メソッド："文字列{}".format(変数)で、文字列中の{}に引数の変数を順番に代入する。

```python
if __name__ == '__main__':
    n = int(input())
for i in range(1,11):
    result=n*i
    print("{} x {} = {}".format(n, i, result))
```
IBM Cloud: Cloud Foundry アプリケーションの停止・開始

IBM CloudのCloud Foundry アプリケーションはクレジットカードを登録したPAYGアカウントの場合、動かしたまま1ヶ月経過すると課金対象になります。またライトアカウントの場合は最大256Mまでしかメモリが使用できませんので、新しいアプリケーションを動かしたい場合は、使っていないアプリケーションを停止しないと動かない場合があります。

ここでは、IBM Cloud上のCloud Foundry アプリケーションの停止・開始の方法を説明します。

#1. Cloud Foundry アプリケーションの停止
##1.1: IBM Cloudにログイン
https://cloud.ibm.com/login よりIBM Cloudにログインしてください。

#1.2:  表示されたダッシュボードの[リソースの要約]から`リソースの表示`をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/52b9bdb9-8204-e76e-e658-22c529d83639.png)


#1.3: `Cloud Foundry Apps`の文字をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/6a4cfa11-4b91-719e-32e4-af09f332bfd1.png) 

#1.4: 実行中の停止したいアプリケーションの名前の右側にある`・・・`で表示されているメニューをクリック、停止をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/6a71477e-a1d4-bb92-e855-3490db1e7fa0.png)

#1.5: 確認のウィンドウが表示されるので、`停止`をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/cdba44f8-aef4-ea7b-df74-340883ced102.png)



#2. Cloud Foundry アプリケーションの開始
##2.2: IBM Cloudにログイン
https://cloud.ibm.com/login よりIBM Cloudにログインしてください。

#2.3:  表示されたダッシュボードの[リソースの要約]から`リソースの表示`をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/52b9bdb9-8204-e76e-e658-22c529d83639.png)


#2.4: `Cloud Foundry Apps`の文字をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/6a4cfa11-4b91-719e-32e4-af09f332bfd1.png) 

#2.5: 停止中の開始したいアプリケーションの名前の右側にある`・・・`で表示されているメニューをクリック、開始をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/4b189518-522f-6632-99df-3744ab92c23b.png)

以上です。
機械学習のための数学入門【情報理論編】受講メモ(2019/08/29)

## 概要
[【初心者歓迎】機械学習のための数学入門【情報理論編】](https://to-kei.connpass.com/event/142643/) 2019/08/29開講分

## カリキュラム
- 確率変数
- 期待値・分散・共分散
- 周辺確率
- 条件付き確率と独立
- ベイズ則
- 情報量
- シャノンエントロピー
- KLダイバージェンス

## 学べたこと
- 基本的な概念や数式の意味などを知ることができた。
- なんとなく知っていた程度の用語の理解を深めることができた。
- 演習がよかった。手を動かし計算してみることで数学を活用することの実感を得られた。
ターミナルからSQL文を使ってmysqlでデータベース、テーブルを作る方法

#ターミナルからmysqlに接続する方法
```
mysql -u ユーザー名
```

#データベースを一覧で表示する
```sql
SHOW DATABASES;
```
※SQL文の終わりには;(セミコロンが必要)
#データベースの作成方法
```sql
CREATE DATABASE データベース名;
```
※SQL文の終わりには;(セミコロンが必要)

#データベースを選択する
```sql
USE データベース名;
```
#データベースに存在するテーブルを一覧で表示する
```sql
SHOW TABLES;
```
#テーブルの作成
```
CREATE TABLE テーブル名 (カラム名　カラム名の型,　カラム名　カラム名の型,...);
```
| 型名 |値|
|:-----------------:|:------------------:|:------------------:|
|    INT        |      数字       |    
|　　VARCHAR(M)  　　| 最大M文字の文字列| 
#カラムの追加
```
ALTER TABLE テーブル名　ADD (カラム名　カラム型, カラム名　カラム型,....);
```
#カラム名の修正
```
ALTER TABLE テーブル名　CHANGE 古いカラム名　新しいカラム名　新しいカラム型;
```
※カラム型は変わらなくても必ず記述する必要がある
#カラム名の削除
```
ALTER TABLE テーブル名　DROP カラム名;
```
PRML1.5.1 誤識別率の最小化は事後確率最大化と等価

PRMLの1.5.1を読んでいると，「誤り確率の最小にするのが，事後確率が最大のクラスに割り当てるときであると言い換えられる．」とあって，いきなりなんでそんなことになるんだと疑問に思ったので，覚え書きのために自分なりの解釈を書いてみました．

#誤識別率の最小化(クラス分類問題)
ある患者のX線画像(のピクセル強度)を入力xとして，その患者が癌であるか否か(癌であるクラスをC1,そうでないクラスをC2)を判別するという決定問題の下で，間違った判断をしてしまう確率を最小化したいということがここでの目標です．

ここでは，決定領域$R_k$上に存在する入力xをクラス$C_k$に割り当てるという決定規則を採用しています．

この時，誤って本来癌である患者のX線画像(入力x)を癌でないクラス$C_2$に割り当てたり，その逆が起きる場合があります．その誤り確率は

```math
\begin{align}
p(誤り)&=p(x\in R_1,C_2) + p(x\in R_2,C_1)\\
&= \int_{R_1}p(x,C_2)dx\,+\,\int_{R_2}p(x,C_1)dx
\end{align}
```

この誤り確率を最小にするには上の積分値が小さくなるように入力$x$をクラスに割り当てなければなりません．

PRMLではここでいきなり「誤り確率の最小にするのが，事後確率が最大のクラスに割り当てるときであると言い換えられる．」となるのです．
ここで論理の飛躍があるので，この行間を自分で補ってあげる必要があると思うのですが，この誤り確率の最小化の説明の後に，より一般のKクラスの場合には正解確率を最大化してやる方が簡単だという風にあります．

この正解確率を用いると，先ほどの誤り確率は

```math
\begin{align}
p(誤り)&=1-p(正解)\\
&= 1-\Bigl(\int_{R_1}p(x,C_1)dx\,+\,\int_{R_2}p(x,C_2)dx\Bigr)
\end{align}
```

と表すことができます．

この式より誤り確率の最小化は正解確率の最大化と等価であることはお分かり頂けると思います．

そしてここで，

```math
p(x,C_k)=p(C_k\,|\,x)p(x)
```

より，正解確率(同時分布)の最大化は正解確率での事後確率最大化と等価であるということが分かります．

このことから，誤り確率の最小化は(正解確率としての)事後確率の最大化と等価であるということなのです．

#引用
パターン認識と機械学習　上
ベイズの定理

#ベイズの定理
- 条件付確率に関して成り立つ定理で、いくつかの未観測要素を含む推論などに応用される

#数式

```math
P(B|A)=\frac{P(A|B)P(B)}{P(A)}
```
一般に、確率及び条件付き確率に関して、P(A)>0の時次が成り立つ。
【Unity】謎のアサーション'IsNormalized(dir)'&'IsNormalized(ray.GetDirection())'

# バージョン
Unity 2019.1.9f1

# はじめに
こんなアサーションに遭遇しました。
![error_log.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483690/0a0d166a-89f1-69e1-f90f-0da6300da0db.png)

```
Assertion failed on expression: 'IsNormalized(dir)'
Assertion failed on expression: 'IsNormalized(ray.GetDirection())'
```

クリックしてもそれ以上の情報はなく、どこに問題があるのかどころか、誰がこのアサーションを吐いているのかさえ分からず。

とりあえず調べてみると公式フォーラムで[Flare Layerを切ると消えたという情報](https://forum.unity.com/threads/assertion-failed-on-expression-isnormalized.468392/)が出てきます。
切ってみると確かに出なくなりましたが、このままではレンズフレアが使えない、ということで色々試して回避できそうな方法が分かったので共有します。

# 再現手順
1. 空のシーンを作成します。
1. Directional LightにLens Flareを追加します。
1. Main CameraにFlare Layerを追加します。

ここまではレンズフレアを使うときにやる普通の作業かと思います。
このあと下記の2パターンで確認できました。

## パターン1（Orthographicカメラ）
1. Main CameraのProjectionをOrthographicにします。
1. 再生します。
1. Main CameraとDirectional LightのPositionを一致させます。

## パターン2（Perspectiveカメラ）
1. Main CameraのProjectionをPerspectiveにします。
1. 再生します。
1. Main CameraとDirectional LightのTransformを一致させつつ、PositionとRotationを適当に動かします。
（例えばPosition: -2, -13, -10、Rotation: 77.2, 112.32, 0とか）

原因ははっきりとは分からないのですが、カメラとLens Flareの位置関係によってはレンズフレアの計算ができない状況になるのでしょう。

# 対処法
このアサーションに遭遇する原因として一番ありそうなのがカメラにLens Flareが付いてしまっているパターン。
この場合、Lens Flareの使い方が間違っていると思われますので、まずは使い方が合っているか確認するのがいいかと思います。
[こちら](https://nabesi777.hatenablog.com/entry/2019/03/03/%E3%81%BE%E3%81%B6%E3%81%97%E3%81%84%E5%85%89%E3%81%AE%E8%A1%A8%E7%8F%BE_Bloom)や[こちら](http://nakamura001.hatenablog.com/entry/20110605/1307277791)を参考にさせて頂くと、空のオブジェクトやLightに付けるのが正しいかと思いますので、そのようにしましょう。

それでも、再現手順でやったように、カメラとLens Flareの位置が一致する状況があれば発生してしまうことでしょう。
その場合は両者の位置関係を意識したうえで、スクリプトやオブジェクト配置を見直してみるのがいいかと思います。

# おわりに
すぐに原因箇所が分からないアサーションなので、解決に時間を取られてしまわないよう、一助になれば幸いです。
IBM Cloud: Cloud Foundry アプリケーションとサービスの接続

IBM CloudのCloud Foundry アプリケーションと　IBM Cloud上のサービスを接続(bind)すると、資格情報や接続情報が連携され、個別に設定する必要がなくなります。

ここではIBM CloudのCloud Foundry アプリケーションと　IBM Cloud上のサービスを接続する方法を説明します。
（2021/01/16 最新の画面イメージに更新）


#0. 前提はCloud Foundry アプリケーションがIBM Cloud上にDeploy済であること
IBM CloudのCloud Foundry アプリケーションと　IBM Cloud上のサービスを接続する方法なので既にDeploy済だと思いますが、まだDeployしてない場合はDeployしておいてください。

#1. IBM Cloudにログイン
https://cloud.ibm.com/login よりIBM Cloudにログインしてください。

#2. 表示されたダッシュボードの[リソースの要約]から`すべて表示`をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/4f17abd1-e4d3-8dac-c1c6-14c035517f2f.png)


#3. `Cloud Foundry アプリ`の先頭の`v`をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/8f559e8e-ed1b-be88-5ee2-d5a0a7c9b8b6.png)


#4. 接続を作成したいアプリケーション名をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/3876ac9e-dcd5-485e-7979-4416a6aa66c7.png)


#5. 左のメニューから`接続`をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/18d9b61a-9bec-94b2-4e6a-4a01a48806d3.png)



#6. `「接続の作成」`ボタンをクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/7c4de989-950a-6c9f-9aa4-7fea27c3c88c.png)



#7. 接続したいサービスののラジオボタンをクリックし、`「次へ」`をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/fca4b011-81c2-c059-b738-4389ffbb0a13.png)



#8. `接続の作成`という画面が表示されるので、デフォルト値ののまま、`「接続」`ボタンをクリックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/71fbaffc-a6bf-2df5-bc7c-1e88e485f2f7.png)






#9. `アプリの再ステージ`というウィンドウが表示されるので、`「再ステージ」`ボタンをクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/f05adccf-9e79-b713-c0f7-0ba390535ee9.png)



ステージング中は`再ステージング中`と表示されます:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/f6702779-64d5-be6e-c586-69d779452c50.png)


`実行中`と表示されれば再ステージングは完了しています:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/53c87aba-c686-efc3-806f-cab1bbe10c99.png)


#10. オプション: アプリケーションの開始
再ステージが完了後、アプリケーションが停止していて開始したい場合は、`アクション`ボタンをクリックし、`開始`をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/c290f93b-2678-b3fc-99d5-3a75a7ca90a6.png)


以上です。
【Oracle】２つのSQLの実行結果の差分を抽出する時に使っている関数

障害対応で原因調査のため、問題のSQLとこっちで予想したSQLを投げて、想定外のデータを確認する時に使う関数をご紹介します。

# 差分を抽出SQL
## MINUS
```
SELECT test_col FROM test1_tbl -- （１）
MINUS
SELECT test_col FROM test2_tbl -- （２）
```
上記SQLを投げると、（１）の 実行結果から、（２）の実行結果を引きます。
で、残った結果だけが表示されます。

##### （１）の実行結果
|test_col  
|---
|1
|2
|3
##### （２）の実行結果
|test_col  
|---
|1
|2

の場合に、MINUS句を使うと、「３」だけ抽出がされます。

|test_col
|---
|3

（１）の結果から、（２）の結果を引く（MINUS）した結果となります。

（１）と（２）を逆に書いた場合

```
SELECT test_col FROM test2_tbl -- （２）
MINUS
SELECT test_col FROM test1_tbl -- （１）
```

（２）の結果は、（１）が全て網羅しているので、
結果は、何も表示されません。

|test_col  
|---

なので、２つのSQLの実行結果が同一か？を調べたりする時にも使えます。
ASP.net MVC 

# モデルの作成

モデルファイルの定義を元にデータベースのTableが新規作成される。

モデル命名規則：　単数形名詞
新規追加されるTable名：　モデル名の複数形

※モデルに定義したプロパティ名と同名のカラムを持つテーブルを新規作成

# DbContext

DBからデータ取得、更新、削除などDBの操作を担う。

新規クラスを作成し、DbContextクラスを継承して使用する。

「DbSet」メソッドを使用して、データ操作を行う。

# Viewの作成
## 　Razor

HTMLにC#のコードを埋め込んで記述する形式。

「@」を冒頭に記述する事で、C#のコードと認識される。
rustのHello, wasm-game-of-lifeの最初だけやってみた。

https://rustwasm.github.io/docs/book/game-of-life/hello-world.html#serving-locally
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253014/3f9df4a3-5f3b-3f69-0655-ec29e5cb6897.png)

自分のコードだと、devDependenciesはあるけど、dependenciesは無くて困りました。
結果的には、devDependenciesをdependenciesに書き換えて、該当の行を追記したら動きました。
devDependenciesはそのままに、dependenciesのみ該当行を追記した時は、ファイル一覧がwebページに表示されてうまくいきませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253014/fa613fba-67b5-d746-a71d-70acff1887de.png)

うまくいくとこんなふうになります

解決したんですが、devDependenciesとdependencies調べてみると
https://qiita.com/chihiro/items/ca1529f9b3d016af53ec

> パッケージとして公開し、開発者以外の人がnpm install sampleとしたときには、dependenciesに書かれているパッケージがnode_modules内にインストールされ、devDependenciesに書かれているパッケージはインストールされません。

てことで、パッケージとして公開した時に困ることがあるかもしれないみたいです。

wasm-game-of-life初めて見ました。不思議

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">epic conway&#39;s game of life <a href="https://t.co/Df1dz2GqHn">https://t.co/Df1dz2GqHn</a> <a href="https://twitter.com/YouTube?ref_src=twsrc%5Etfw">@YouTube</a>さんから</p>&mdash; 中村一貴 (@kajirikajiri) <a href="https://twitter.com/kajirikajiri/status/1170717761196019713?ref_src=twsrc%5Etfw">September 8, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
ブラックボックステストを勉強しました。

# ブラックボックステストを勉強しました。

2か月前に、勉強しましたが、
全然、Qiitaに投稿しなかったので、
今、勉強した内容を整理します。

ブラックボックステストは、Programを一種のブラックボックスで見て、
さまざまな入力を実行して、テストをする方法です。
ほとんどのソフトウェアのテストは、ブラックボックステストです。

## ブラックボックステストの基本

### Equivalence partitioning(同値分割法)

同値分割法は、
ソフトウェアやシステムの入力値を同様の動作（結果）を示すもので、
期待しているグループに分類して、
グループに属する入力値は、同じ方法で処理されるという前提に設計する手法です。

![wefwsaf.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421654/8b161671-02f9-0d7b-c07a-df3139e0dbcb.png)


|Test|1|2|3|4|
|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|
| バッテリー容量      |              2.75  |        2.99        |3.55                | 4.05|
| 分割           |            2.05≤ <2.80|       2.80≤ <3.30|3.30≤ <3.80|3.80≤ <4.30|
| 結果             |              バッテリー 0|  バッテリー 1 |バッテリー 2|バッテリー 3|


### Boundary value analysis(境界値分析)

同値分割法が、グループの内部を確認する奴なら、
境界値分析は、グループの境界を確認するやつです。
大体、バグは、グループの内部より、グループの境界から発生する可能性が高いです。


### Decision Table

Decision Tableは、
すべての入力の組み合わせを表作成し、その入力に対して動作や出力を表示します。
表には、状態、規則、同漁整理されていて、この表を使用してテストをする。
しかし、この方法には問題があります。
大規模なソフトウェアをテストする場合は、
かなり多くのテストケースが生じるので、表を使用することは困難です。

自分も、テストケースを作成する時、
結構、ケースが多かったので、大変でした。
ちゃんと、確認するべきのケースをテストしたり、効率的にテストする方法を探す必要があります。

### State transition diagram

システムの状態が変化することによるテストケース設計も可能です。
現在の条件や、以前の状態に応じて、他の応答を示すことができます。
この場合には、状態遷移図を使用してシステムを表現することができます。

![edgser.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421654/c74cb1d5-8450-7e7d-3ff1-be619c25feeb.png)
![ghmnfjghdr.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/421654/07eeac09-95db-942f-d6f3-e28ef409bf8d.png)

上にある絵みたいに、State transition diagramを作成した後、
流れに合わせて、テストケースを作成します。




テストは、リリースする前に開発したProgramがちゃんと動くのか、確認する重要な作業です。
みんな、テスト頑張りましょう！
Git関連の参考URL

個人用のメモです。
僕が初学者なので、初学者の人が読んでわかるリンクを載せています。
日々更新します。
世の中に発信してくれている人達のおかげで僕もコツコツ作品作れます。
ありがとうございます。

- *GitHub登録からプッシュまでの流れ*

[https://qiita.com/KosukeQiita/items/cf39d2922b77ac93f51d](https://qiita.com/KosukeQiita/items/cf39d2922b77ac93f51d)
shellとevalとlambda

ふと思いついたのでdashのevalを使って無名関数的なものを作る。

## 無名関数の生成
レキシカルスコープは無理なのでただの文字列にする。

```
$ foge='echo $(($1+$2+$3))'
```

## 生成した関数の呼び出し
fcallで呼び出す。

```bash
fcall() {
  local __LAMBDA_FUNC=$1;
  shift
  eval "$__LAMBDA_FUNC"
}
```
```
$ fcall "$foge" 1 2 3
6
```

## 部分適用
shは引数を無制限に渡せるため、部分適用用の関数(papp)と
呼び出し用の関数(fcall)を分けることにする。

これは少し難しいが、無名関数の文字列と引数を受け取って、
以下のような関数に変換する。

* fcall時に与えられた引数の前にpappで渡された引数を割り込ませてsetする。
* pappで渡された引数がevalの際にshellによりいじられないようにエスケープする。

```bash
# エスケープ  h"og'e -> 'h"og'\''e'
esc() {
  local h= v="$1"
  while :; do
    case "$v"
    in *\'*)
      eval 'h="$h${v%%'\\\''*}"'
      h="$h"\'\\\'\'
      eval 'v="${v#*'\\\''}"'
    ;; *)
      RET="'$h$v'"
      break
    esac
  done
}

# 部分適用
papp() {
  local RET __FUNC="$1" args= arg
  shift

  for arg in "$@"; do
    esc "$arg"
    args="$args $RET"
  done

  echo 'set -- '"$args"' "$@";'"$__FUNC"
}
```

```
$ x="`papp "$foge" 1`" 
$ y="`papp "$x" 2`"
$ echo "$x"
set --  '1' "$@";echo $(($1+$2+$3))
$ echo "$y"
set --  '2' "$@";set --  '1' "$@";echo $(($1+$2+$3))
$ fcall "$y" 3
6
``` 

## 付録 : スコープ
レキシカルスコープがなくても例によってカウンタとか作ろうとしなければ
だいたいなんとかなる。

```
$ a=hello
$ fuga="local a=$a;"'echo "$a" "$1"'
$ hoge='local a=bye; fcall "$1" "$2"'
$ fcall "$hoge" "$fuga" world
hello world
```
IntelliJ　データベース管理を行う　①概要編

#IntelliJで行うデータベース管理とは？
結論から言います。
こんな感じの事が出来ます。
![screenshot.219.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450687/3159e51f-ff19-467c-ffb4-1d071e9b63c7.jpeg)
設定画面はこんな感じです。簡単です。
![screenshot.218.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450687/bf20e467-967b-6214-7190-f6fa12e744a3.jpeg)

##できること
・データベースの作成、編集、削除
・スキーマの各種操作（テーブル操作等）
他にもいろいろなことが出来るようですが、まずは上記2点を次回解説していこうと思います！
MicrosoftはいつになったらVBAの定数のちんぷんかんぷんさをなくせるのか 日本のユーザーやライターはなぜ韓国のように怒ったりバカにしないのか

#このへんでマスコミが弱いものいじめしかしない卑怯者としかいいようがない
まあこれはITに限らないのでいいんですけどね。

##公式の惨状
https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/schemaenum
###定数が「個」
adschemaindexes　個 カタログに定義され、所定のユーザーが所有するインデックスを返します。 (INDEXES 行セット)
###定数が「波線」
adschemakeycolumnusage　~　カタログに定義され、所定のユーザーがキーとして制約した列を返します。 (KEY_COLUMN_USAGE 行セット)
###定数が「スリー」 交付 与え
adSchemaColumnPrivileges スリー　カタログに定義され、所定のユーザーが利用できる、または権限を持つテーブルの列に対する特権を返します。 (COLUMN_PRIVILEGES 行セット)
TABLE_CATALOG
TABLE_SCHEMA
TABLE_NAME
COLUMN_NAME
交付
与え
##1-d pbm-2 分数はもはや普通
adSchemaCatalogs 1-d DBMS からアクセスできるカタログに関連付けられている物理的属性を返します。 (CATALOGS 行セット
CATALOG_NAME
adSchemaCharacterSets pbm-2 カタログに定義され、所定のユーザーがアクセスできる文字セットを返します。 (CHARACTER_SETS 行セット)
CHARACTER_SET_CATALOG
CHARACTER_SET_SCHEMA
CHARACTER_SET_NAME

adschemacheckconstraints 5 カタログに定義され、所定のユーザーが所有する CHECK 制約を返します。 (CHECK_CONSTRAINTS 行セット)
CONSTRAINT_CATALOG
CONSTRAINT_SCHEMA
CONSTRAINT_NAME

adSchemaCollations 1/3 カタログに定義され、所定のユーザーがアクセスできる文字照合順序を返します。 (COLLATIONS 行セット)

###定数名そのものが崩壊
RightsEnum
https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/rightsenum
完全な ad権　268435456(&H10000000)
ad権作成　16384(&H4000)
###タブですら
そら確かに右だけど...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/4e754bce-efbb-f56b-b18c-206a20c25cf7.png)

##マイクロソフトの翻訳のおかしな点
6をシックスと訳すなど、数字をカタカナに翻訳したり分数、記号、意味不明な文字列に変えてしまう
定数の途中をスペースで切っていないのに翻訳。
adRightCreate は本来権利とよめない。しかしなぜかMSの翻訳は訳してad権作成としてしまう。

##注意書きは役立たない
マイクロソフトは機械翻訳を使っていますと書いているが、どこが機械なのかがわからない。このため、ユーザーは確かめようがない。
したがって、この公式の処理はとてもまずいと思う。
##対策はあるがめんどくさい
https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/schemaenum
このja-jpをen-usに変えると、正常に数字が示される
しかてヘルプがまともな数字を示さないのでは使い物にならないと判断するのが常識だろう。

##マイクロソフトというかアメリカ資本企業に弱すぎる日本人
これが日本か中国や韓国の企業なら当然文句を言うだろう。だがどういうわけかマイクロソフトにはなにも言わないし、炎上すらしない。
この辺でも「炎上」ということ自体がでたらめで、差別だったりします。
日本人は差別しているというより強気を助け、強気に媚びて弱気をくじく。
GitHub Action で Railsプロジェクト のCIを回す

## GitHub Actionの種類

### ワークフローの記述

GitHub Actionは提供当初はHCLで記述するタイプでしたが、現在はYAMLで記述するタイプになっています。

今回はYAML形式のワークフローを記述していきます。

### 実行環境

GitHub Actionの実行環境は共用VMでのホストモードと、その上でコンテナで稼働させるコンテナモードの２種類が存在しています。

今回はコンテナモードを使用します。

∵ ホストモードの場合、空きポートを探したり、変数で割り当てポートを探してポートを露出する必要がありますが、コンテナモードの場合はその手間がないため、簡単に構築できます

## Railsプロジェクトの概要

今回ビルドするサンプルのRailsアプリは下記の仕様のものです。

* DBにMySQLを使用している
* Ruby 2.6.5でbundle installされている
* Rails6.0にWebpackを追加している
* Rakeタスクのデフォルト実行タスクでテストが走るようになっている

※ 実際にはRails5.x系や、APIモードのRailsプロジェクトでも、最後から二行目の `bundle exec rails yarn:install db:setup assets:precompile` を `bundle exec rails db:setup` とすれば動きます。

## 手順

手順としては `.github/workflows/` 以下にワークフローを記述したYAMLファイルを作成・コミットし、 Gitプッシュするだけで動作します。

今回作成するRailsプロジェクトの場合は、下記のファイルを作成します。

```yaml:.github/workflows/rails.yml
name: Rails

on: [push]

jobs:

  build:
    runs-on: ubuntu-latest

    services:
      mysql:
        image: mysql:5.7
        options: --health-cmd "mysqladmin ping -h localhost" --health-interval 20s --health-timeout 10s --health-retries 10
        env:
          MYSQL_ROOT_PASSWORD: mysql123
      redis:
        image: redis:5.0-alpine
        options: --health-cmd "redis-cli -h localhost ping" --health-interval 10s --health-timeout 5s --health-retries 15

    container:
      image: ruby:2.6.5
      env:
        DATABASE_URL: mysql2://root:mysql123@mysql:3306/rails6_sample
        REDIS_URL: redis://redis:6379/1

    steps:
    - uses: actions/checkout@v1
    - name: Setup YARN and NodeJS
      run: |
        curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
        echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
        curl -sL https://deb.nodesource.com/setup_13.x | bash -
        apt-get install -y yarn nodejs
    - name: Build and setup
      run: |
        rm -f config/database.yml
        gem install bundler --no-document -v $(grep "BUNDLED WITH" -1 Gemfile.lock | tail -n 1)
        bundle config set deployment 'true'
        bundle install --jobs 4 --retry 3
        bundle exec rails yarn:install db:setup assets:precompile
    - name: Exec tests
      run: bundle exec rake
```

その後作成したファイルをリポジトリにプッシュします。コミットメッセージやpush先は適宜設定してください。

```shell:command
git add .github/workflows/rails.yml
git commit -m "Add GitHub Action's workflow."
git push
```

しばらく経つとワークフローが実行されます。
実行状況や実行結果は、リポジトリの Actions タブで表示することができます。
また、プルリクにもこのビルド結果は表示されます。

### ポイント

* 今回は実行環境としてコンテナモードを使用しているので、空きポートの探索やポートの動的参照が必要なく、service以下に定義した名前でコンテナに対してアクセスし、ジョブを実行しています
* GitHub Actionではserviceコンテナの起動確認にhealthcheckの結果を使用しているため、MySQL等の起動に時間がかかるものについてもoptionsでhealthcheckの設定を上書きすることで、起動完了まで待った後にジョブを実行しています


### おまけ： RubyプロジェクトでのCI

非RailsのRubyプロジェクト（Gem等）も下記の内容で同様にCIを実行することができます。

```yaml:.github/workflows/ruby.yml
name: Ruby

on: [push]

jobs:

  build:
    runs-on: ubuntu-latest

    container:
      image: ruby:2.6.4

    steps:
      - uses: actions/checkout@v1
      - run: gem install bundler --no-document
      - run: bundle config set deployment 'true'
      - run: bundle install --jobs 4 --retry 3
      - run: bundle exec rake
```
DIとServiceLocatorの違い

ZF2(ZendFramework2)を勉強する際、DI(DependencyInjection)とServiceLocatorを混同してしまっていたため、整理するために２つについてまとめてみました。

# DIとServiceLocatorの共通点
DIとServiceLocatorは両方とも密結合なメソッドの結合度を緩和するために用いられるデザインパターンです。

# 密結合とは
この記事内において密結合とはメソッド同士の依存度が高い状態を指します。具体的には、インスタンスの生成から利用まで 直接他のクラスに依存している状態です。密結合にはデメリットがあり、依存先のクラスに変更があった際に影響が大きく、依存元クラスの再利用性は低くなってしまいます。
![密結合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/470294/d8025f55-3c9c-1d99-2071-a2f97b9ebba2.png)

# DIとは
**呼び出し元に使用する 依存オブジェクトを用意してもらい、 それを注入してもらうことです。**クラス間で直接インスタンスを生成するのではなく、メソッドの呼び出し元で依存先のインスタンスを生成し、メソッドにそのインスタンスを引き渡します。DIのメリットとしては依存度を緩和することができ、またテストしやすいメソッドを生成できるといったことが挙げられます。
![DI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/470294/ad795911-e6c8-db7a-8a00-a56795cd9171.png)

**実装の比較（PHP）**
![DI実装.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/470294/42851655-3bea-928f-2c2b-539a8159aefc.png)

# ServiceLocatorとは
**オブジェクトのインスタンス 生成方法を管理するデザインパターンです。**ServiceLocatorを呼び出して依存先のインスタンスを取得する際、ServiceLocatorはあらかじめ登録された生成方法でインスタンスを生成し、これを呼び出し元へ返却します。これにより、クラス間の直接的な依存関係を緩和することができます。（ZF2のMVCにおいてはServiceManagerがServiceLocatorの役割をしています。）
ServiceLocatorにはデメリットもあります。ServiceLocatorを使うことで確かにクラス間の直接的な依存関係は緩和されるのですが、代わりにServiceLocatorへの依存度が高くなってしまいます。もしServiceLocatorに依存したメソッドを再利用しようとした時、移植先で同様のServiceLocatorを用意しなくてはならなくなるといった事態が発生してしまいます。
![ServiceLocator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/470294/153cba1c-caec-c73b-1ff2-a2b8a65407b7.png)

**実装の比較（PHP）**
![ServiceLocator実装.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/470294/62384438-f1e9-f44d-de96-11920a829fc5.png)

# まとめ
DIとServiceLocatorは両方とも密結合の結合度を緩和するために用いられます。密結合へのアプローチとしてはテストのしやすさの面で個人的にはDIを推していますが、こちらは適材適所で使えればいいと思います。

突っ込みたくなるところがありましたら是非ともご指摘お願いします。
フィードバック制御、PID制御、ゲイン

## フィードバック制御とは

>フィードバック制御とは**偏差**をゼロにするための手段を考えること。
偏差とは・・**制御変数**と目標値の差
制御変数とは・・(時間とともに目標値に向かっていく)現時点での動作

『[メカトロ二クスTheビギニング』](https://www.amazon.co.jp/%E3%83%A1%E3%82%AB%E3%83%88%E3%83%AD%E3%83%8B%E3%82%AF%E3%82%B9-%E3%83%93%E3%82%AE%E3%83%8B%E3%83%B3%E3%82%B0%E2%80%95%E3%80%8C%E6%A9%9F%E6%A2%B0%E3%80%8D%E3%81%A8%E3%80%8C%E9%9B%BB%E5%AD%90%E9%9B%BB%E6%B0%97%E3%80%8D%E3%81%A8%E3%80%8C%E6%83%85%E5%A0%B1%E3%80%8D%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%83%AC%E3%82%B7%E3%83%94-%E8%A5%BF%E7%94%B0-%E9%BA%BB%E7%BE%8E/dp/4526063835)より引用

**つまり、フィードバック制御の最大の目的とは**
**「目標とする動作と現時点での動作の誤差をなくすよう制御すること」**
と言って差し支えないでしょう。
その他、簡単にイメージできる例でいくと、
・ライントレーサがラインの情報を取得し、その情報から機体の動きを制御すること
・お風呂のお湯はりをある位置のところで止まるように設定すること

## フィードバックに与えられた課題とは
**外乱**です。
外乱とは・・制御を乱す要因のこと。
例えば車で道路を走行する際、坂道や突風や段差のように
思いがけない条件が外乱に当たります。
このような外乱をいかにクリアするのかが、
フィードバック制御に与えられた課題といえるでしょう。

## PID制御とは
フィードバック制御の一種で、温度の制御をはじめ、
モータの回転制御や位置決めをする場合によく用いられる。

PはProportional:比例動作
→目標値と測定値の差分を計算して比較する要素

IはIntegral:積分動作
→目標値の面積と設定値の面積を一致するように調整する要素

DはDifferential：微分動作
→微分は曲線の接線のこと、この場合は傾きを調整する要素

#### PID制御に重要なキーワード **「ゲイン」**
ゲインとは・・一般的に利得と訳されるが「感度」と解釈するのが良いみたいです。
メカトロニクス製品では個体差が生じるのでそれぞれの製品の状態によって、
感度を強めたり、弱めたりして力を調整することが必要になります。

## PID制御の例
### 高速道路の料金所で一旦停止した後、80km/hまで加速する場合
#### P(比例)ゲイン
なるべく早く、スムーズに目標の80km/hまで到達するにはどういう手法(曲線)がいいのか、
目標値と現時点での差分で比較検討する。
![01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450697/0fdae71a-b96d-9ed8-04fe-70db6e987e4a.png)
#### D(微分)ゲイン
この曲線の傾きが微分要素

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450697/c52965a0-9b8c-750f-03dd-b0a179812266.png)

#### D(微分)ゲイン_オーバーシュート
曲線の傾きを立たせる・・
到達時間が早くなる、オーバーシュートする
（波形が定常値を一旦超過してから引き返すようにして定常値に近づく）

![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450697/bb22b999-146e-ec64-4ddb-67797f0d9dd0.png)

#### D(微分)ゲイン_オフセット
曲線の傾きを寝かせる・・
到達時間が遅くなる、スムーズな動きになるがパワー不足となる

![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450697/613709e0-9f07-c8fc-fda3-bf0d8a4997ed.png)

#### I(積分)ゲイン
そこで、オフセットした分をできるだけ目標の値に近づけるため、積分ゲインが登場！
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450697/32f86008-4125-c375-083f-b4a579ec4611.png)
(小ネタ)応答ファイルにゴミが残ってSysprep失敗

#概要
Windows SIM[^1]で応答ファイルを編集しても、正しい応答ファイルが作成されるとは限らない。
[^1]: System Image Manager

#何があった？
Windows SIMでWindows 2016用の応答ファイルを作成。
いろいろ動作検証をしていたため、設定値を変えたり、消したりしていた(Windows SIM上から)。
そして気がついたら、Sysprep[^2]に失敗するようになった。
応答ファイル読み込み失敗の無限ループで、OS起動不可･･･
(仮想環境で検証していたので、スナップショットを取っておいて良かった！)
[^2]: OSの一部設定を初期化してくれる(SIDとかホスト名とか)。Windowsの大量展開ではお馴染みの儀式。

#原因は？
調査の結果、Windows SIMから、「設定値」を削除したら、「設定項目」のタグだけ残っていた。
不要なタグを残ったままにしておくと、応答ファイル読み込み時に、処理に失敗する。
(ツールを利用しているから大丈夫、と過信するのはよくない。。)


#対処方法
手っ取り早い方法は、応答ファイルの中身を直接編集し、不要なタグを削除してしまうこと。
自信が無い場合は、Windows SIMから、対象の「コンポーネント」を削除して、再登録するのが無難。
今回は、プロダクトキーのタグが残っていた。これを手動で、応答ファイルから削除したらSysprepに成功した。

```xml:untitled.xml
    <settings pass="specialize">
            <ProductKey></ProductKey>   ←これが残っていた。手動削除でSysprep成功。
```
【sbt】サブプロジェクトによる依存関係の強制を有効活用しよう！

# 問題

中・大規模なアプリケーションでクラスの集合レベルでアクセス方向を強制したい(MVC, MVVM, MVPやDDDのレイヤー化アーキテクチャ, cleanアーキテクチャ)が `private` や `protected` などのアクセス修飾子ではアーキテクチャの原則が解りづらい。
また解りづらいことによりチームメンバーがアクセス修飾子を間違えたりつけ忘れることがある。

# 回答

sbtのマルチプロジェクト機能を使いましょう[^1]。

[sbt Reference Manual — マルチプロジェクト・ビルド](https://www.scala-sbt.org/1.x/docs/ja/Multi-Project.html)

マルチプロジェクト機能によりソースコードをサブプロジェクトごとに分割してサブプロジェクト間で依存関係を宣言することにより、クラスの依存関係を一方向へ限定できます。
また、修飾子ではなくソースコードの配置場所レベルで依存関係が強制されるため、他のメンバーや新規メンバーが修飾子を間違えたり依存関係の原則を破ってしまうような恐れもありません。

[^1]: mavenではmoduleに当たる、らしいです

このテクニックは各レイヤー間の依存関係を強制したいDDDやclean architectureで特に有効活用されます[^3]。

例: [Spring Bootアプリケーションをmavenのmulti moduleで構成する \- Qiita](https://qiita.com/rubytomato@github/items/118817023845b4284553)

[^3]: このような強い強制力を持つ仕組みを用いなければ、理解の深くないメンバーが容易にレイヤー間のアクセス方向の原則を破ってしまうためです。

# 蛇足

Scalaではアクセス修飾子でアクセスを許可するパッケージを指定できます。またそのパッケージは自身を含むものでなくてはいけません(=つまり祖先パッケージのどれかである必要がある)。
一方サブプロジェクトを使用すると、パッケージと関係なくアクセス方向(= 依存関係)を制御できます。
つまり、これらの依存関係の制御は相補的です。サブプロジェクトで大枠を定めてアクセス修飾子で細かい調整を行うと僕は最初誤解していたのですが、サブプロジェクトとアクセス修飾子にはそれぞれできることが違います。
うまく使えば非常に便利ですが、一方で過剰にややこしくもなりやすいため注意して使いましょう。
GitLabの過去バージョンのドキュメントを見る

# はじめに

本記事ではGitLabのアーカイブされたバージョンのドキュメントを見る方法を試してみようと思います。

GitLabのドキュメントは以下のサイトで確認することができます。
https://docs.gitlab.com/ce/README.html

もちろん最新版(2019/09現在)の12.2は確認できますし
画面上部のバージョンを変更することで、12.0なども確認できますが
それより古いバージョンが選択できない状態となっています。

過去のバージョンの仕様を知りたくなることもありますよね？
また”色々な”事情で古いバージョンを使わざるを得ないケースもあると思います。
そんな時でも簡単に過去のバージョンのドキュメントは確認できます。

# 過去のバージョンのドキュメントを確認してみる

過去のバージョンのドキュメントを確認するためには、dockerを使える環境が必要です。
dockerさえ使えれば、確認まで2stepで完了します。

1.　以下のコマンドを実行します。<ドキュメントを見たいバージョン>には、10.3等のバージョンを指定します。なお、port4000番を別の用途で使用している場合は、-pの左側の値を変更してください。　　

```
　　　　docker run -it --rm -p 4000:4000 registry.gitlab.com/gitlab-org/gitlab-docs:<ドキュメントを見たいバージョン>
```
上記コマンドを実行すると標準出力にログが出力される状態になります。　　

2.　ブラウザで http://localhost:4000/ にアクセスすることでドキュメントを確認できます。
今回は10.3を確認してみました。

　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/433578/6014f81d-a873-8459-3779-009810f38156.png)


3.　確認が終わったら、docker runをCtrl+Cなどで終了すればOKです。


なお、この方法で遡れるのは10.3までのようです。（2019年9月現在: https://gitlab.com/gitlab-org/gitlab-docs/container_registry より）