OmniAICreator/Qiita-1.07M huggingface dataset:
Unityでシューティングゲームを作る(4)

##ここまでの進捗

- 背景がループするようにした。
- 普通の敵の動作を作成し、その敵が3秒ごとに生成される。
- 瞬間移動する敵の動作を作成し、5秒ごとに生成する。
- プレイヤーが画面の範囲外に行かないようにした。
- 敵とプレイヤーが衝突したらプレイヤーが消滅する。
- 分散攻撃の敵を実装する。
- タイトルシーンとエンディングシーンを追加する。


##今後やること

- ボスキャラの動作を実装する。
- エフェクトとBGMを追加する。
- プレイヤーが横に移動すると機体が傾くアニメーションをつける
- <font color="Red">プレイヤーがダメージ受けると点滅して数秒だけ無敵状態になる</font>

この記事では赤い部分を作成した。

##プレイヤーがダメージを受けると点滅する
点滅するコルーチンを作成してプレイヤーの衝突判定の中でコルーチンを実行するようにした
コルーチンは関数内で時間を空けて処理をさせたいときに使われる

点滅するコルーチンの作成に関してはこのサイトがとても参考になった。
[ftvlog/オブジェクトを点滅させるスクリプト](http://ftvoid.com/blog/post/789)

以下がコルーチンとなる

```
//ダメージを受けた時に点滅する
    IEnumerator Blink() {
        for(int i=0;i < 4; i++) {
            renderer.enabled = !renderer.enabled;

            yield return new WaitForSeconds(0.2f);
        }
    }
```
この中でオブジェクトの点滅を0.2秒間隔で4回行っている
これによってダメージを受けると以下のようになった
![ezgif.com-video-to-gif (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482973/09291bfe-b5e8-9c40-ea14-1eae6df4716f.gif)

##プレイヤーがダメージを受けて点滅してる間は無敵になる
今回はプレイヤーが攻撃を受けてから点滅している間だけプレイヤーのレイヤーを変更することによって衝突判定を無効化した。
teratailに質問があったので参考にした。
[teratail/衝突判定を一定時間無効化したいです](https://teratail.com/questions/184106)

![コメント 2020-02-07 033604.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482973/99b96a97-203f-5adb-a6eb-e090b07d923a.png)

まずレイヤーを追加するために[Edit]→[Project Settings]を選択する。

![コメント 2020-02-07 033643.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482973/fc03f50f-9a0c-4259-5c49-f85e349d7967.png)

この設定画面がでるので左の欄から[Tags and Layers]を選択し、Layersの中からUser Layerのどれかに名前を付ける
今回はUser Layer 9にInvisibleという名前を付けた。

![コメント 2020-02-07 033725.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482973/5f218e38-ed54-0826-7a00-e04bb44ab70c.png)

最後に左の欄からPhysicsを選択し、衝突を無効化したいオブジェクトがあるレイヤーと先ほど作成したレイヤーのチェックを外す。
これによってInvisibleのレイヤにあるオブジェクトとDefaultにあるオブジェクトの衝突が無効化される。

![ezgif.com-video-to-gif (3).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482973/34fb8179-2c5f-94fc-d058-cac02006ed03.gif)

ちょっと見ずらいかもしれないけど、点滅時間が1.2秒で短いので一瞬しか無効にならない。
今後調整していこうと思う。

これで弾を受けたときの点滅と無敵時間を作ることができた。
難易度をあげるにつれて点滅時間の延長も検討していきたい。

次回はアニメーションをつけてボスを作成して完成させたい。
ちなみにここからこだわるつもり
Laravelの認可処理はGateとPolicyどっちを使えばいいのかわからない

## 概要

Laravelには認可処理として、GateとPolicyというものが用意されています。

最初はよくわからなくてどっちがどっちなんだ？と思うでしょう。

## 結論

わからなかったらGateをつかえばよい。

そもそも認可処理を担当するクラスは`Illuminate/Auth/Access/Gate.php`で、Policyも結局はGateを使っています。

Policyはあくまでもモデルに対しての認可処理を簡単にかけるようにしたものです。

## Policyのmiddlewareでの指定方法

Policyでの認可処理の書き方の一つにルートでミドルウェアとして書く方法があります。

```php
Route::post('/book', 'HogeController@update')->middleware('can:update,book');
```

`can`は固定で、`:`のあとの1つめはポリシーのメソッド名になります。そのあとのは主に書き方が2種類あります。

### モデルをつかわないメソッドの場合

ポリシーで以下のようなメソッドを定義したとします。

```php
public function create(User $user)
{
}
```

このメソッドは引数にユーザーしか受け取っていません。

引数にモデルを渡さない場合の書き方は、

```
Route::get('/create', 'HogeController@create')->middleware('can:create,App\\Book');
```

とこのように完全修飾名を渡してあげます。この文字列はサービスプロバイダーに登録されたポリシーを探し出すためのkeyとしてのみ使用されます。

### モデルをつかうメソッドの場合

```php
public function update(User $user, Book $book)
{
}
```

このメソッドは引数にユーザーしか受け取っていません。

引数にモデルを渡さない場合の書き方は、

```
Route::put('/{book}', 'HogeController@store')->middleware('can:update,book');
```

としてあげます。第一引数の`{}`の中身と同じ名前を指定しなければいけないことに注意してください。

ルートモデルバインディングを利用しているので合わせる必要があります。

Policyを使うときには`AuthServiceProvider`に登録するのを忘れないようにしましょう。（よく忘れて怒られる...）
ADサーバのつくりかた！

(生きていました。)

ADサーバ(オンプレ)の材料


筐体とモジュールのことをざーーーっと書きます。




まずAD(アクティブディレクトリ)について。、
![CF24382E-7609-4468-A4A6-5823DB324420.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482793/351d816d-74dc-76ba-d0b9-ee5b384eaa50.png)

Active Directory (アクティブディレクトリ) とはマイクロソフトによって開発されたオンプレミスにおけるディレクトリ・サービス・システムであり、Windows 2000 Serverから導入された、ユーザとコンピュータリソースを管理するコンポーネント群の総称である。

https://ja.m.wikipedia.org/wiki/Active_Directory

WindowsServerを使ってるシステムならほぼ確で導入されてるであろうサービスです。
会社内の共有フォルダのアクセス許可を出したりするのに使われています。
わたしはつい最近まで名前しか知らなかったよ！！！😇🤧


↓こんな感じで組みました↓
【メイン】
・4core以上のサーバ(メモリ16GB)
・1TBのディスク3本(RAID5)
【モジュール】
・nicの追加ポート
・ディスク拡張スロット
・DVDメディアベイ、プレーヤー(内蔵タイプ)
【その他】
・windowsserverライセンス
・保守

(※アクセスしてくる人数は500人とする。)


他の人が作ればもっと違うもっと良い構成があるかもしれないし、
身も蓋もない言い方をすればAWSで作っても平気です🤣🤣🤣


↓解説↓
【メイン】
サーバ:
500人だとぎりぎり中規模ですね
なので4core以上でいきたいとおもいます(震え)
足りないより多い方がマシです。
参考：https://sys-guard.com/post-12597/
メーカーは正直何でもいいとおもいます。
電源の数、予算、、要件の中で何がいちばん大事か考えてはずせない条件が叶うものを選びましょう( ᐛ )

ディスク:
ディスク4本RAID10を考えたけど、ADサーバはそんなに忙しなく読み書きするわけでもないので速さはいらないそうです。( ᐛ )
そういう理由でRAID5です。
(SAS SATA SSD HDDは個人の好みとかもあるのでここでは触れません)

【モジュール】
追加nic:
これを買うとLANケーブルの口が増えます。

拡張スロット:
これを買うとディスクを挿す場所が増えます。

↑この二つに関しては、あとになってラックから外して付け直すのは大変すぎるので最初から付けたほうがいいので買っておきましょう！！！

DVDメディアベイ(内蔵):
ノートpcとかと違ってDVD再生するとこデフォルトでは付いてません。注文して付けてもらわないといけません。()
USB接続の外付けタイプもあるよ


、、、、とても疲れたので一旦終わります
WindowsServerライセンスは気が向いたら追記します


物理で困ってる人の助けになったら幸いです(∩´﹏`∩)

【おまけ】
DVDメディア「ベイ」
「ベイ」←枠
DVDプレーヤーを突っ込むための枠を作るのを注文する
みたいな感じです。とても紛らわしい。


p.s.
RAIDの記事に訂正入れました。(いまさら)
Laravelのルートモデルバインディングを応用して自由にインスタンスを生成する

## 例

ルートに指定されるtypeで生成するインスタンスをわけて、コントローラーのメソッドに注入したい。

```php
Route::get('/{type}/{parent}', 'HogeController@fuge');
```

```php
class HogeController extends Controller
{
    public function fuga(Parent $child)
    {
        return $child->fuga();
    }
}

```

```php
abstract class Parent extends Model
{
    public function fuga() {return;}
}

class Child_1 extends Parent
{
}

class Child_2 extends Parent
{
}
```

## 明示的結合

Laravelではルートモデルバインディングは2種類あり、明示的結合と暗黙的結合がある。

今回は明示的結合で魔改造していく。

`RouteServiceProvider`の`boot()`の中に追記する。


```php
$this->app['router']->bind('parent', function ($value, $route) {

    $type = $route->parameter('type');

    if ($type === 'child_1') {
        $child = new Child_1();
    }
    if ($type === 'child_2') {
        $child = new Child_2();
    }

    $route->forgetParameter('type');

    return $child->where('id', $value)->first();
});
```

`bind()`の第一引数にはURIで指定したキーワードのどれにバインドさせるかを文字列で渡す。

今回は`parent`を第一引数に渡しているので、クロージャの第一引数の`$value`には`{parent}`の箇所に実際に指定された値が入ってくる。

`/child_1/500`というURLでリクエストされたら`$value`には500が入ってくる。

これだけだと`{type}`の値がとれないので、`$route->parameter('type')`で値を取得し、if文で生成するインスタンスを変えている。

あとは生成したインスタンスを使って、whereなりをしてかえしてあげればよい。

`$route->forgetParameter('type')`をしているのは、parameterから削除しないとコントローラーの引数に入ってきてしまうため。

このように明示的結合を使えば好きなインスタンスをコントローラーの引数に渡してあげることができる。
Apache2.4でテスト環境を構築する話

##はじめに
こんにちは、はるちゃです。
開発環境に**AWS**を使用しています。
テスト環境に移行した際に社外の人に見られたくない。。。
と思ったので、メモとして置いときます。

###前提
- AWSのアカウントを所持していること
- インスタンスを生成していること
- apacheをインストールしていること

私はAWS初心者なので **Amazon Linux 2 AMI (HVM), SSD Volume Type**を使用しています。

## 目次
1.ip制限をかける
2.Basic認証の導入
3.ip制限、Basic認証の併用

###ip制限をかける
```httpd.conf
<Directory "/var/www/html">
...
# Require all granted #ここのコメントをオンにすると全体から閲覧できるようになります。
Require ip XXX.XXX.XX.X #IPアドレスを挿入します。
...
</Directory>
```
この方法が一番簡単です。
自社の人なら誰でも見ていいよーって時はこの方法でいいと思います。

###Basic認証の導入
はじめに**htpasswd**が存在するか確認。。。

```
[ec2-user@プライベートip]$htpasswd 
Usage:
htpasswd [-cimBdpsDv] [-C cost] passwordfile username
htpasswd -b[cmBdpsDv] [-C cost] passwordfile username password

htpasswd -n[imBdps] [-C cost] username
htpasswd -nb[mBdps] [-C cost] username password
 -c  Create a new file.
 -n  Don't update file; display results on stdout.
 -b  Use the password from the command line rather than prompting for it.
 -i  Read password from stdin without verification (for script usage).
 -m  Force MD5 encryption of the password (default).
 -B  Force bcrypt encryption of the password (very secure).
 -C  Set the computing time used for the bcrypt algorithm
     (higher is more secure but slower, default: 5, valid: 4 to 17).
 -d  Force CRYPT encryption of the password (8 chars max, insecure).
 -s  Force SHA encryption of the password (insecure).
 -p  Do not encrypt the password (plaintext, insecure).
 -D  Delete the specified user.
 -v  Verify password for the specified user.
On other systems than Windows and NetWare the '-p' flag will probably not work.
The SHA algorithm does not use a salt and is less secure than the MD5 algorithm.
```
存在しない場合は↓のリンクを参照してinstallしてください。
http://tanihiro.hatenablog.com/entry/2014/02/05/172938

次に

```
$ cd /etc/httpd/conf #このコマンドでconf階層まで必ず移動してください
$sudo htpasswd -c <filepass名> <username> 
New password: パスワード入力
Re-type new password: パスワード再入力
Adding password for user <username>
```

あとは下記の通りにDirectoryにBasic認証条件を記入します。

```httpd.conf
<Directory "/var/www/html">
...
    AuthType Basic
    AuthName "Basic Auth"
    AuthUserFile /etc/httpd/conf/.htpasswd
    Require valid-user
...
</Directory>
```
ここまでの設定が終わったら、**apache**を再起動してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240422/4b7036f2-c4ea-226f-7f42-fe43eb65c592.png)

こんな画面が出てきたら成功です！

###ip制限、Basic認証の併用
```httpd.conf
<Directory "/var/www/html">
...
<RequireAll>
	Require ip 自分のIPアドレス
	<RequireAny>
 		AuthType Basic
  		AuthName "適当なコメント"
  		AuthUserFile /etc/httpd/conf/<ファイル名>
  		Require valid-user
	</RequireAny>
</RequireAll>
・・・
</Directory>
```

上記のように設定すれば、IPアドレスが違うユーザーはサイトに入ることができません。
仮にIPアドレスが一致していた場合もBasic認証が作動します。
うっかり開発者以外の人が入ってデータを消してしまう心配が少し減ります。

##終わりに
今回はここまでです。
テスト環境を構築するのに困っている人の役に立てば幸いです。

記載にミスがあったり書き方が違うなど、あればコメントよろしくお願いします！
rails チュートリアル2週目~ヘルスケアwebサービスを自分で作る医者の日記~

railsチュートリ
の3章初めからてこずった

最初sqlite3 をsqlite とgemfileに書いて
失敗
その後　書き直して add commit heroku にpushするも

デプロイできず

```
heroku run rails 
```
するも

```
Specified 'sqlite3' for database adapter, but the gem is not loaded. Add `gem 'sqlite3'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord). (Gem::LoadError) heroku
```
となる。
herokuはsqlite3いらないんじゃなかったの？
bundle install --without production でsqlite3はのぞいているのに



```
remote: ###### WARNING:
remote: 
remote:        Detecting rails configuration failed
remote:        set HEROKU_DEBUG_RAILS_RUNNER=1 to debug
remote: 
remote: 
remote: ###### WARNING:
remote: 
remote:        No Procfile detected, using the default web server.
```

が結局残ったがデプロイできた


誰がこの辺の理屈教えてください。

次回は3.2
あとgitの仕組みわからない
いい理解方法ないものか
比較演算子とfor構文

- while構文

```php
$i = 1;
while ($i <= 365){
     print $i . PHP_EOL;
     $i = $i + 1;
}
```

- 比較演算子 `<=`
  - 不等号のこと
  - `A<B`　数学ではAがBより小さい
     - プログラミングの中でも使うことができる
  - `A≦B`　数学ではAがB以下
     - ≦はプログラムの中で使うことができない
     - 変わりに`<=`を使う
  - `A=B`　数学ではAとBは等しい
     - =は代入で使ってしまっているので使えない
     - 変わりに `===` を使う
     - `==` と `===`　は似ているが少し違う
     -  [参考記事：PHP比較演算子「==」と「===」の違いについて](https://qiita.com/atsushi586/items/adca2368d9a760ad862d)
  - `A≠B` AとBが等しくない
     - プログラミングで≠は使えない
     - 変わりに `!==`　を使う
  - `!A`　Aではない
- `$i = $i + 1;`　をもっと簡単に書く方法
  - `$i += 1;`　→　`$i++;`（インクリメント）
  - `$i -= 1;`　→　`$i--;`（デクリメント）
     - 掛け算と割り算には用意されていないので普通に書く
     - `$i *= 5;` `$i /= 5;`

- for構文

```php
for ($i=1; $i<=365; $i++){
    print $i . PHP_EOL;
}
```
　↓↓↓↓↓

```
for (初期化処理; 繰り返す条件; 更新処理){
繰り返したい処理
}
```
- for構文使えば、上のようなwhile構文もスッキリまとめることができる
- 単純に◯回繰り返す、同じ変数を使って計算をして繰り返すような、簡単な繰り返し処理であればfor構文を使った方が良い
- ただし初期化処理や更新処理が複雑になっている場合もある。その場合は、無理やりfor構文にまとめようとせず、while構文をつかようにする
- 使い分けに迷ったらwhile構文を使う

※参考：Udemy/Webサーバーサイドプログラミング入門
MAMPのApacheが起動しないとき

環境:windows10 MAMP(2020/2/6)

原因として以下の2つが多いそうです。
1.PHPversionの指定ミス
2.ポート80を既に使用している


#1.PHPversionの指定ミス

PHPversionの指定ミスはとっても簡単です。

まずMAMPを起動してください。

左上のメニューから
「Preferences→PHP→Standard Version」のタブを7.3.7から7.2.14としたらOK



#2.ポート80を既に使用している場合

MAMPで使用するポート80でバックグラウンドが動いているのかと思ったのでコマンドプロンプトで動作しているポート確認。

```
netstat -ano
```
するとこんな感じで表示されます。

```
アクティブな接続

  プロトコル  ローカル アドレス      外部アドレス           状態            PID
  TCP         0.0.0.0:135            0.0.0.0:0              LISTENING       468
  TCP         0.0.0.0:445            0.0.0.0:0              LISTENING       4
  TCP         0.0.0.0:3306           0.0.0.0:0              LISTENING       10620
  TCP         0.0.0.0:5040           0.0.0.0:0              LISTENING       4196
  TCP         0.0.0.0:49664          0.0.0.0:0              LISTENING       756
 
```

ローカルアドレスに0.0.0.0.80があれば以下のコマンドで切ってください。

```
taskkill /pid 任意のPID /F
```
MATLABでGitを操作しよう (第2回 : git add/git commit)

# はじめに
前回に引き続きMATLAB GUIによるGit操作の第2回目

[第1回 : プロジェクト作成とGUIの説明 ](https://qiita.com/stozaki/items/e4fa14c36f6c134e53e7)
**第2回 : git add/git commit**
第3回 : チェックアウト(特定のコミットに戻る)
第4回 : ブランチ作成
第5回 : リモートリポジトリとの連携 (git push/git pull)
第6回 : クローンを作成する
第7回 : 応用1
第8回 : 応用2

CUIから実行するには`git add`及び`git commit`。
MATLABのコマンドウィンドウから実行する場合は`!git add`、`!git commit`です。
では、同様の操作をMATLABのGUIから実行するには？

## 1プロジェクトを開く
[第1回 : プロジェクト作成とGUIの説明 ](https://qiita.com/stozaki/items/e4fa14c36f6c134e53e7)
にて作成したプロジェクトを開くところから始めます。
GtiPrj.prjをダブルクリックします。
![GIT2_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/bbe52ef3-85a8-2f2a-8dd2-aae9aaa26bbd.png)

プロジェクトウィンドウが開きます。Gitのステータスも表示されています。
![GIT2_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/d632ce60-3a0f-baeb-3122-909ef242e1c4.png)

git addするために新規ファイルを作成します。ここではMATLABの簡単な関数を作成します。

#### git add 方法1
1. プロジェクト内の.gitがある現在のフォルダに新規MATLABファイルを保存。
2. 右クリックで「ソース管理」⇒ 「Gitに追加」。
3. ステータスが白丸から＋印になります。これで`git add`は完了

![GIT2_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/a0e0d182-166f-eb9f-a30e-7e895df383ab.png)


#### git add 方法2
1. 方法1同様に新規MATLABファイルを現在のフォルダに保存。
2. プロジェクトウィンドウにおいて、「すべて」タブを選択。
3. ファイルを右クリックして「プロジェクトに追加」を選択。Gitステータスが＋になります。これで`git add`は完了。プロジェクトに登録するとgit addになるんですね！

![GIT2_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/c6b996f1-7161-bf7f-bb06-e6b29d4b0ebc.png)

![GIT2_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/3f086172-51dd-7a25-bb65-2727ee283985.png)


#### git commit 方法1
続いて、`git commit`です。これも2通り。
方法1は正確には `git commit .`(ステージングエリアにあるファイルを一括コミット)です。
ステージングエリアにあるファイルに対して、コミットアイコンをクリックすると対象ファイル全てがコミットされます。

![GIT2_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/d4f78ab6-5409-2bb0-ab5f-2d3981b3d37b.png)

コミットコメントを入力するダイアログが起動するので、規定のコメントフォーマットに従って設定してください。この辺りの、専用ダイアログは使いやすいと思います。
![GIT2_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/11e8fe5b-6e8d-2134-1e6d-4e17319c493d.png)

Gitステータスがグリーンの◯になったのでOKです。
![GIT2_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/e89eeaff-316d-b35f-417e-3eec8c7ecacc.png)


#### git commit 方法2
先程の操作で全てコミットされたので、goofy.mを一旦編集します。

プロジェクトウィンドウまたは、現在のフォルダで、goofy.mを選択し、コンテキストメニューから「コミット」を選択します。ついでにプロジェクトに登録します。
![GIT2_9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/f5338d9f-4d14-c469-24a5-dc3161dd07c9.png)

##  最後に
ここで一旦「プロジェクトの整合性チェック」を実行します。
![GIT2_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/c9c3047d-5153-ceb3-90c3-3544bc301187.png)
プロジェクトの整合性チェックは、ファイルがgti管理化に存在するか? パス設定が正しく設定されているか? などGit及びSimulinkプロジェクト内のファイルの整合性をチェックしてくれます。
コミットしたあと等、定期的に実施すると良いかと思います。

![GIT2_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/88d87929-51dc-e202-3afb-0c950428bdec.png)

## 次回
予定では第3回ですが、ちょっと2日前に面白い質問を頂いたので、
その回答をするかもしれません。


[第1回 : プロジェクト作成とGUIの説明 ](https://qiita.com/stozaki/items/e4fa14c36f6c134e53e7)
[第2回 : git add/git commit]()
**第3回 : ブランチ作成**
第4回 : リモートリポジトリとの連携 (git push/git pull)
第5回 : クローンを作成する
第6回 : 応用1
第7回 : 応用2

では、よい週末をお過ごし下さい。
RailsでmySQLを使ってgem:deviseを実装する

こんにちは

Railsでポートフォリオを作るときに、mySQLを使ってさらにdeviseを導入してログインなどのシステムを導入したい

そんな人たちに、自分が使ったやり方を自分の復習も込めて書きます。

まずは、データベースにmySQLを使っている、railsプロジェクトを作る

＄rails new プロジェクト名　-d mysql

造られたプロジェクトのgemfileに

gem 'devise'

を記述する。

ここまで書いたら、下記のコマンドを実行して、gemファイルを読み込みます。

$bundle install

まずはここまでで一セット。そして、間髪入れず第二セットいきます。

gem:deviseの関係ファイルをプロジェクトに作ります。このとき、先ほどの作ったrailsプロジェクトのフォルダに移動しておいてください。

$ rails generate devise:install

上記のコマンドを実行すると下記のような文章が出てきます。

===============================================================================
Some setup you must do manually if you haven't yet:

  1. Ensure you have defined default url options in your environments files. Here
     is an example of default_url_options appropriate for a development environment
     in config/environments/development.rb:

       config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

     In production, :host should be set to the actual host of your application.

  2. Ensure you have defined root_url to *something* in your config/routes.rb.
     For example:

       root to: "home#index"

  3. Ensure you have flash messages in app/views/layouts/application.html.erb.
     For example:

       <p class="notice"><%= notice %></p>
       <p class="alert"><%= alert %></p>

  4. If you are deploying on Heroku with Rails 3.2 only, you may want to set:

       config.assets.initialize_on_precompile = false

     On config/application.rb forcing your application to not access the DB
     or load models when precompiling your assets.

  5. You can copy Devise views (for customization) to your app by running:

       rails g devise:views

===============================================================================

上から順に説明すると

１、config/environments/development.rbにconfig.action_mailer.default_url_options = { host: 'localhost', port: 3000 }を記述してくれよな

２、config/routes.rbにroot to: "home#index"を記述してくれよな

３、app/views/layouts/application.html.erbに
　　　　<p class="notice"><%= notice %></p>
       <p class="alert"><%= alert %></p>
を追記してくれよな

4,使っているRailsのバージョンが3.2だったらconfig/application.rbに
　config.assets.initialize_on_precompile = falseを記述してくれよな
  (Railsのバージョンはrails -vでわかる)

5,deviseにデフォルトで設定されている画面（view）をカスタマイズしたい時は、
　rails g devise:views
　を実行すると変更を加えるためのviewファイルを作成するぞ

という意味です。

これで、第二セットは終わり。ラストにデータベースを作って終わります。

mySQLを

$sudo service mysqld start

で立ち上げてから

下記のコマンドでデータベースを作る

rake db:create

そして、モデル(今回はUserモデルを作る)

$ rails g devise user

gem 'devise'のおかげでemailとpasswordはこのコマンドを使うと自動で追加されるらしい

追加したいカラムは都度追加すれば良い

また、このままではコントローラーがdeviseになっているため

userコントローラーで操作できるようにするため、下記のソースをroute.rbに記述する

devise_for :users, controllers: {
    registrations: 'users/registrations',
         sessions: 'users/sessions',
        passwords: 'users/passwords'
  }

その後、userコントローラーを作る,

認証ユーザーのモデルが User であれば、app/controllers/users ディレクトリ以下にファイル作成

$rails g devise:controllers users

そして、この設定をデータベースに反映させる

rake db:migrate

以上です。
TestcafeのSelectorでcustom attrを対象にする

## やりたいこと

testcafeで要素をdata-*で特定する。

## 公式

[公式のwithAttribute](https://devexpress.github.io/testcafe/documentation/test-api/selecting-page-elements/selectors/functional-style-selectors.html#withattribute)に書いてあった。

## Testcafeの用意

```
~$ npm i testcafe
```

これだけ。

## コード

一応。

### html

```html
<a id="to-hoge" href="/hoge.html">to hoge</a>
```

```html
<p id="msg" data-test="msg">hoge!</p>
```

### js

```js
import { Selector } from "testcafe";
fixture("Test start").page("http://localhost:3000");

test("check link", async t => {
  await (t)
  .expect(Selector("#to-hoge").innerText).eql("to hoge");
});

test("check message", async t => {
  await (t)
  .click("#to-hoge").expect(Selector("p").withAttribute("data-test", "msg").innerText).eql("hoge!");
});
```

## 実行

```
~$ php -S 0.0.0.0:3000
~$ npx testcafe chrome test.js
```

PHPでサーバ立てましたが何でも良いです。
ファイルの読み書き

# はじめに
ただの備忘用のメモです。
ファイルの入出力ってたまに使うんですが何故か思い出せないことが多いです (´-ω-`)


# 環境
```
Microsoft Visual Studio Community 2019 Version 16.4.3
.NET Core 3.1
```

# 書く、読む
FileStream, StreamWriter, StreamReader を使います。
オーバーロードがいろいろあるんですがその中から目についたモノを書いておきます。
※詳細は[[参考]](https://qiita.com/drafts/448cb2308fcf99750b40/edit#%E5%8F%82%E8%80%83)を参照

```c#:
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp7
{
    class Program
    {
        static async Task Main(string[] args)
        {
            // ファイルパスを渡すと内部でFileStreamが生成されてそこにデータが流し込まれる
            // StreamWriterにMemoryStreamとかを渡せば書き込み先を変えられる
            using (var writer = new StreamWriter(@".\test.txt", append: true, encoding: Encoding.UTF8))
            {
                writer.WriteLine("hogeee");

                // 非同期でも書ける
                await writer.WriteLineAsync("hunngaaa!!");
            }

            using (var stream = new FileStream(@".\test.bin", FileMode.Append, FileAccess.Write))
            {
                stream.Write(new byte[] { 0x66, 0x32, 0x87, 0x12, 0x11, 0x88, 0x45, 0x23 });

                // バイナリの場合も非同期で書ける
                await stream.WriteAsync(new byte[] { 0x76, 0x12, 0x23, 0x99, 0x50, 0x43, 0x18, 0x66 });
            }


            // StreamWriterと同じ要領で使える
            using (var reader = new StreamReader(@".\test.txt", Encoding.UTF8))
            {
                Console.WriteLine(reader.ReadLine());
                Console.WriteLine(await reader.ReadLineAsync());
            }

            // あんまり使わない
            using (var stream = new FileStream(@".\test.bin", FileMode.Open, FileAccess.Read))
            {
                var buffer = new byte[8];
                stream.Read(buffer, 0, 8);
                Console.WriteLine(string.Join(", ", buffer.Select(b => $"{b,2:x2}")));

                await stream.ReadAsync(buffer, 0, 8);
                Console.WriteLine(string.Join(", ", buffer.Select(b => $"{b,2:x2}")));
            }
        }
    }
}

```

# 参考
[FileStream クラス](https://docs.microsoft.com/en-us/dotnet/api/system.io.filestream?view=netcore-3.1)
[StreamWriter クラス](https://docs.microsoft.com/en-us/dotnet/api/system.io.streamwriter?view=netcore-3.1)
[StreamReader クラス](https://docs.microsoft.com/en-us/dotnet/api/system.io.streamreader?view=netcore-3.1)
[$ - 文字列補間](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated)
[複合書式指定](https://docs.microsoft.com/en-us/dotnet/standard/base-types/composite-formatting#format-string-component)
GCEインスタンス上で、`auth_kind: machineaccount`設定でAnsibleを走らせる

# はじめに
`gcp_compute`等のプラグインを利用してGCEに対してAnsibleでアクセスしたい場合には、[公式ガイドにあるように](https://docs.ansible.com/ansible/latest/scenario_guides/guide_gce.html)Service Accountのjsonを発行し、適当な場所に配置することを求められます。
しかし、Ansibleを実行する環境がGCEインスタンス、もしくはGCPのCloud Shellの場合、Service Accountをインスタンスに紐付けることが可能であり、これを利用して実行することが可能です。

本記事では、Service Accountのjsonを発行せずにAnsibleでGCEインスタンスを操作するための設定を説明します。

# 前提条件
* `pip install ansible requests google-auth` が実行済である
* 実行するインスタンスにService Accountが紐付いている
* 紐付いているService Accountには「Compute 閲覧者」の役割を与えられている
  * 今回実行するコマンドに対して必要な権限。やりたいことに応じて権限は適宜変更すること

# TL;DR
任意のディレクトリに以下のファイルを準備してください。
`{}`で囲われている部分については適宜編集してください。

なお、ファイル名について以下の条件があります：

* `ansible.cfg`は固定
* `foobar.gcp.yml`は拡張子に当たる`.gcp.yml`は固定

また、**`foobar.gcp.yml`について、`service_account_email`を設定していないと走りません。**（罠）



```ansible.cfg
[inventory]
enable_plugins = gcp_compute
```

```foobar.gcp.yml
plugin: gcp_compute
projects:
  - {HOGE_PROJECT}
  - ...
zones:
  - {FUGA_ZONE}
  - ...
auth_kind: machineaccount
hostnames:
  - name
service_account_email: default
```


準備ができたら、`ansible-inventory --list -i foobar.gcp.yml`を実行してください。
Ansibleを使用して構成する準備ができたGCEインスタンスのリストが作成されます。

Enjoy!!!!

# 参考文献
* https://docs.ansible.com/ansible/latest/plugins/inventory/gcp_compute.html
公開鍵暗号方式なのに電子署名とSSLって違うんですか？

# 電子署名とSSL通信

電子署名を触る機会があり、その時のお勉強ログ。にわかです。

## SSL通信

電子署名とSSL通信、どちらも公開鍵暗号方式を採用している。
同じ暗号方式を採用しているのにも関わらず、利用方法に明確な違いがある。

SSLでは、サーバから公開鍵をクライアントに送りつける。
クライアントは送られてきた公開鍵を利用して、自身の通信プロトコルを暗号化しサーバにお返事を返す。

サーバは、クライアント側で暗号化された通信を受け取り、
サーバ自身で所持している秘密鍵で通信を復号してクライアントの情報を受け取る。

秘密鍵は、通常サーバでしか所持していないので、クライアントの情報はサーバでしか確認できない。

悪意のある第三者が通信を覗きこんでも、SHA256RSAで暗号化された情報は、そう簡単には解読できない。

→クライアントが公開鍵で暗号化し、サーバが秘密鍵で復号することで情報漏洩を防いでいる。

## 電子署名

電子署名でもSSLと同じく公開鍵暗号方式が採用されています。

そもそも電子署名の目的は、契約書などの重要な書類に。。。長くなるので割愛

電子署名された文書が改竄されていないか。を確認するために公開鍵暗号方式が利用されています。
電子文書からは、指紋を取ることができます。ハッシュ値というのですが、もしも、文書の内容を一文字変えたとすると、以前とは全く異なるハッシュ値が取得できます。電子文書からランダムな値を取得することができるのです。

一文字変更を加えるだけで、大きく値を変えて出現するハッシュ値。
ですので、その電子文書が改竄されていないことを証明するためには、ハッシュ値が変わっていない証拠があればいい。

電子署名では、署名者が原本から取り出したハッシュ値に対して、秘密鍵を使って復号文（署名値）を作成します。
そして、原本と共に復号文と公開鍵を送りつけます。

受け取った側は、これが改竄されていないかを確認（検証）します。
もしも、通信の途中で悪意のある第三者によって、原本が改竄されていたら
原本のハッシュ値　と　復号文の中に入っているハッシュ値　がイコールの関係ではなくなるので、改竄されていることを確認することができます。

復号文は、公開鍵で暗号化してハッシュ値を取り出すことができます。

##　暗号化と復号の使い方間違ってない？という疑問ですが

秘密鍵で行えるのは、復号
公開鍵で行えるのは、暗号化

ここでつまずきました。。。

日本語で、暗号文を作成すること＝暗号化　文字を元どおりにすること＝復号
って固定観念が理解を邪魔するのですが、

SSL通信
暗号化　　暗号文＝　平文の（公開鍵１）乗/（公開鍵２） の余り
復号　　　　平文＝暗号文の（秘密鍵１）乗/（公開鍵２）の余り

電子署名
復号　　　暗号文＝　平文の（秘密鍵１）乗/（公開鍵２）の余り
暗号化　　　平文＝暗号文の（公開鍵２）乗/（公開鍵２）の余り

### つまり、〇〇の（秘密鍵１）乗/（公開鍵２）の余り　という式が復号を表す

文系ですので、数式めちゃくちゃですが、
秘密鍵が行う計算式は、いつも変わらないのですよ。
公開鍵が行う計算式も、いつも同じ何ですよね。

ですので、日本語的な意味での暗号化に惑わされずに、式として判断するとわかりやす。。。
説明下手くそ。

説明間違ってるいるかもしれないので、、、今の所は忘れてください。

## 結論 

SSL通信は、最初の１回の通信だけ公開鍵暗号を使用しており、2回目からは、共通鍵で通信します。
１回目の通信で、クライアントから共通鍵をサーバに無事に届けるために公開鍵暗号を使用しております。

ので、最初の１回の通信を守ることができれば、いいのです。

秘密鍵の所有者が、クライアントの鍵を受け取ることができればいいのです。


電子署名は、文書の改竄を検知できるように、作成者がハッシュ値に対して秘密鍵を使って復号（署名）し、
その文書が、改竄されていないか。公開鍵を使って確認することができる。

検証する人が、改竄していないかを確認することができればいいのです。

そのために、秘密鍵の所有者は、署名します。


公開鍵暗号は、秘密鍵所持者の目的に応じて、使い方に差が出ます。


長くなりましたが、もしも説明間違っておりましたら、優しく教えてください。
特異値分解とフォンノイマン代数と極大部分等長作用素

1. ヒルベルト空間上の有界作用素 Aは特異値分解 A=W|A| が可能であることをさっと証明する．(Wは部分等長作用素)
2. 部分等長作用素W をAをつかって代数的に書いてみる．
3. 特異値分解がフォンノイマン代数で閉じていることを確認する．
4. 極大部分等長作用素というものを考えて ユニタリー作用素で特異値分解ができる条件を調べてみる．

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ヒルベルト空間上の特異値分解定理に関するらくがき <a href="https://twitter.com/hashtag/%E6%95%B0%E5%AD%A6?src=hash&amp;ref_src=twsrc%5Etfw">#数学</a> <br>特異値分解とフォンノイマン代数と極大部分等長作用素 - koichi yamagata のブログ<a href="https://t.co/xfkP0ws0RE">https://t.co/xfkP0ws0RE</a></p>&mdash; Yamagata (@YamagataTwit) <a href="https://twitter.com/YamagataTwit/status/1225433862454407170?ref_src=twsrc%5Etfw">February 6, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
githubにあるリポジトリをクローンする手順

# 手順
1. クローンしたいリポジトリのページへ行き「Clone or download」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490769/0074a0ae-f00d-899a-3a5c-425c8bafb263.png)

2. HTTPSを使ってリポジトリをクローンする場合はそのままコピーボタンをクリック、SSHキーを使ってクローンする場合は右上の「Use SSH」をクリック後にコピーボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490769/71ac51dc-2f1c-e77e-077c-d649f6bfa996.png)

3. クローンしたいフォルダを作成し、そこで`$ git clone [クローンURL] [フォルダ名]`で実行する

```
~
❯ cd MyApp

~/MyApp
❯ mkdir portfolio # 作成したフォルダ名を

~/MyApp
❯ git clone https://github.com/ユーザー名/リポジトリ名.git portfolio # ここへ入力する
```
`git clone`のコマンドは単に`$ git clone [クローンURL]`とすると、クローン側のフォルダごと作成したフォルダに入ってしまうのに対し、上記のコマンドだと綺麗に作成したフォルダにクローン側の中身が入ると思います

# 終わりに
うまくいきましたでしょうか。私自身クローンする機会があまりなかったので殆ど自分のために手順を書いてみました。参考になれば幸いです。
シェル上の操作動画を表示可能にするasciinemaのPowerShell版PowerSession

こんなんあったのね……

取り急ぎ撮ったものを投稿します

詳細は今週末に時間あったらかも

>> dotnet tool install --global PowerSession

https://github.com/ibigbug/PowerSession

<script id="asciicast-298633" src="https://asciinema.org/a/298633.js" async></script>
CentOSでApacheのHTTPSサーバを構築するメモ

#はじめに
趣味とか色々でよく似たようなことをするのに毎回忘れて困るので，自分用の備忘録としてApacheでHTTPSサーバを立てる手順をメモしておく．今回はドメイン取得済みでSSL証明書はletsencryptで用意する．

＊この記事に書いている一切の作業は**Rootユーザ**で行っているので，適宜`sudo`や`su -`等で実行してください．

#環境
* CentOS7.7
* Apache2.4

#Apacheの導入
とりあえずインストールする．

```
yum -y install httpd
```
自動起動を有効にして起動する．

```
systemctl enable httpd.service
systemctl start httpd.service
```
これで自分のドメインにアクセスすればApacheでいつもの画面が見えるはず．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382909/ce326a3a-afa9-bf20-7fee-044e736c1602.png)
ついでにSSL用のモジュールもインストールしておく．

```
yum -y install mod_ssl
```

この後に`/etc/httpd/conf/httpd.conf`のServerNameを`自分のドメイン名:80`に書き換えておく．例えば`example.com:80`とか．

```bash:/etc/httpd/conf/httpd.conf
ServerName example.com:80
```

#Certbotの導入
次はletsencryptの証明書発行と更新に使うCertbotのインストール．

```
yum -y install epel-release
yum install certbot
```

#証明書発行
初期状態なら`/var/www/html`はそのまま，`example.com`には自分のドメイン名を，`sample@example.com`は自分のメールアドレスを入れておく．

```
certbot certonly --webroot \
-w /var/www/html \
-d example.com \
-m sample@example.com \
--agree-tos -n
```
Congratulations!って出たら成功．

次に証明書を反映させる．`/etc/httpd/conf.d/ssl.conf`の以下3行を書き換える（コメントアウトされてるものもある）

```bash:/etc/httpd/conf.d/ssl.conf
SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
```

一度Apacheを再起動`systemctl restart httpd`したら，`https://ドメイン名`でアクセスできるようになるはず．

#おまけ
##強制SSL化
httpでアクセスされたらhttpsのほうにリダイレクトさせてしまう．
###方法
`/etc/httpd/conf/httpd.conf`の最後にこれを追記しておく．

```bash:/etc/httpd/conf/httpd.conf
ewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
```
Apacheを再起動`systemctl restart httpd`すると，成功していれば`http://...`でアクセスしても`https://`に変更されてブラウザの鍵マークが出る．

##初期ページを消す
先ほどから見えているこれ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382909/ce326a3a-afa9-bf20-7fee-044e736c1602.png)
を消しておく．ちなみに同階層内に`index.html`があればファイル名の指定がない`http://example.com/`などの場合に利用されるので，こちらを使って細かい調整もできる．
###方法
`/etc/httpd/conf.d/welcome.conf`の下の部分を全部コメントアウトする．変更後にApacheの再起動を忘れないようにする．

```bash:/etc/httpd/conf.d/welcome.conf
# <LocationMatch "^/+$">
#    Options -Indexes
#     ErrorDocument 403 /error/noindex.html
# </LocationMatch>
```
##一覧表示を無効化
下の画像のようにサーバー内のファイル一覧が見えてしまうことがあるので無効化しておく．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382909/f71f1bbe-b4cc-712c-1e6b-32536b8bf27a.png)

###方法
`/etc/httpd/conf/httpd.conf`の`Options Indexes FollowSymLinks`をコメントアウトする．

```bash:etc/httpd/conf/httpd.conf
# Options Indexes FollowSymLinks
```
こちらも変更後にApacheの再起動を．

##証明書の自動更新
[こちら](https://qiita.com/tmatsumot/items/aca49d99558d2646ef36)を参考にcronを設定させていただいた．下の例だと毎月1日の午前3時に証明書の更新を行う．ただし，期限が30日以内に迫っていないと実行されないので注意．

###方法
`/etc/cron.d/`に適当な名前のファイルを作って以下を書き込んでおく．今回は`letsencrypt`というファイル名の例．

```bash:/etc/cron.d/letsencrypt
00 03 01 * * root /bin/certbot renew --webroot-path /var/www/html/ --post-hook "systemctl reload httpd"
```

#最後に
全然理解が追い付いてないので時間があるときにApacheについて一度学びなおしたい...
誤字・修正等ありましたらご連絡ください．
#PowerAutomate の"LookUp" 番外編 (compose json dictionary)

#2020/10/26 更新

https://mofumofupower.hatenablog.com/entry/json_dictionary

こちらでもう少し詳しく書きました。


#前回の投稿
前回 [PowerAutomateにおける"LookUp"](https://qiita.com/h-nagao/items/0ccd5bf291605cc9a622)では、First+Filterと、xpathによるLookUpの方法を紹介しました。

今回はよりトリッキーな感じですが、番外編としてCompose Json Dictionary Methodと呼ばれる方法を紹介します。
この方法はもともと[John LiuのYoutube](https://www.youtube.com/watch?v=z-HOsOYxdQE)で紹介されていたものです。

# 手法の概要
非常に大まかにいえば、{customerId, customerName}という列から構成される配列を、転置して1行のデータにしてしまおうというものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/950237f5-910e-bcf5-c30a-9ba830583972.png)
この方法にはもともと配列にID列が必要です。(転置により生成される列を一意にするため)
このような1行データ (Object)ができてしまえば、あとは ```outputs('Compose')?['customerId123']``` のようにして各列(プロパティ)にアクセス、目的の値を取り出せます。

似たような方法は @shibatea さんの投稿 (https://qiita.com/shibatea/items/a07ecd00697d26417e70) の配列の選択アクションでも書かれています。

# Compose json dictionary method
実際にやってみます。Compose json dictionaryというだけあって、Composeアクションを使います。

その前に、配列から転置後の列：値の関係にした文字列を生成します。
Selectのアクションを追加し、以下の数式を利用します。

```
concat('"customerId',item()?['customerId'],'":"',item()?['customerName'],'"')
```


手順が少し面倒なので、動画でどうぞ↓

![output3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/ba355c25-43dd-1a4b-3c9a-dcd7fc98ad6f.gif)

この手順を行うと、以下のような結果が得られます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/2a744e03-915d-d2d7-30af-010ad3dc9736.png)
なんとなく、もう少しという感じです。
あとはこれをカンマで結合して、json関数でオブジェクトに変えれば完成です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/c8366aaa-cc84-0a0f-930c-848ec23af595.png)

**完成!!!!**
これで目的のオブジェクトができました！あとは後続のステップで ```outputs('Compose_3')?['customerId124']``` のようにすれば、望む値が取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/78c98157-6d7b-9977-5737-68d81a4cd59d.png)

#まとめ
今回の方法は少し難易度高めでしたが(中級くらい)、こういう方法もあるということで、知っておくと高速に処理できたりします。（for eachして中で条件式書いたりしないで済む）
特にJohnのビデオでも説明されているように、2つの配列をJoinする際に非常に高速な処理を実現できます。

ぜひ前回の方法と合わせて試してみてください！
【毎日更新】新型コロナウイルスの日本人感染者の都道府県別人数を可視化してみた

# 最新の情報
最新の情報はプロフィール内のサイトで毎日更新中

# 概要
新型コロナウイルスが蔓延していて、日本の都道府県のどこにいるのかを知りたい人がたくさんいると思いますが、nCovダッシュボード[Coronavirus 2019-nCoV](https://gisanddata.maps.arcgis.com/apps/opsdashboard/index.html#/bda7594740fd40299423467b48e9ecf6)では日本は国レベルでしか見ることができない。

Qiitaでも
[コロナウイルスの感染状況を都道府県別に可視化してみた](https://qiita.com/relu/items/c0c74dfd7c2a960d16a8)
で可視化されていたが日々の更新がないので最新の情報が知りたい。

なので新型コロナウイルスの日本の感染者数の都道府県別人数を可視化して、最新の情報に更新することにする。

# 元データ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581040/1353aca7-df68-0277-754e-6e9ea80bd595.png)

こんな感じのデータを自力で作成し、地道に日々更新していく。


# 可視化方法
①Tableauにデータを読み込ませる。
<img width="869" alt="スクリーンショット 2020-02-06 23.57.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581040/48c92844-d81c-f6de-6968-b5c388f044eb.png">

②都道府県別に感染人数を色塗りマップで作成
<img width="888" alt="スクリーンショット 2020-02-06 23.58.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581040/59147404-1e78-715a-524b-822c78c8ecdd.png">

③別シートで棒グラフを作成
<img width="876" alt="スクリーンショット 2020-02-06 23.59.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581040/9d759dae-9a7f-5153-589a-02965f653a24.png">

④２つのシートをひとつのダッシュボードにする
<img width="1055" alt="スクリーンショット 2020-02-07 0.00.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581040/e90a7ab4-6617-b122-0b59-390fc1950a19.png">


# おわりに
今回は新型コロナウイルスの日本の都道府県別での感染者数を可視化した。

皆様のお役に立てば幸いです。
Laravel バリデーションで変数を利用

# Laravelのバリデーションで変数の使い方

##なぜ気になったのか
ECサイトを制作中に、商品をカートに追加する際にデータベース上の商品の在庫数以上の数を買い物かごに入れることができてしまう。
バリデーションを利用するときに商品の在庫数はそれぞれ異なるので固定の値は設定できない。
商品ごとにデータベースの商品の在庫数をMAXとしてそれ以上買い物かごに入れる時にはバリデーションを発動してエラーメッセージを出したかったから。

##まず試したこと
```
$data['test'] = 5;
$max = 10;

$validator = Validator::make($data, [
            'test' => 'max:$max',
        ]);
```
これでは全くバリデーションは効かず

##ではどうするべきか。
PHPで変数を文字列内で展開したい場合は変数を`｛ ｝`（波括弧）で囲って書くことで、文字列の中に変数があること明示している。
ただし、文字列の中に変数を入れる場合は、文字列を必ず`" "`（ダブルクォーテーション）で囲む必要がある。
詳しくは[PHPマニュアル](https://www.php.net/manual/ja/language.types.string.php#language.types.string.syntax)

これを踏まえて下記で実行してみました。

```
$data['test'] = 5;
$max = 10;

$validator = Validator::make($data, [
            'test' => "max:{$max}",
        ]);
```

しかしこれでもうまくいきませんでした。

##何が必要なのか。

Laravelバリデーションの`min` `max` `size`などを利用するときは指定された**値**を判断する。
そのため、上記の書き方では文字列と判断され**値**は文字長を判断する。
詳しくは[Laravel5.5 バリデーション](https://readouble.com/laravel/5.5/ja/validation.html#rule-size)
在庫数などの数値を判断する場合には`max`の前に整数値であるバリデーションが必要なため`integer`を記述する必要がある。

これを踏まえると下記の書き方になる。

```
$data['test'] = 5;
$max = 10;

$validator = Validator::make($data, [
            'test' => "integer|max:{$max}",
        ]);
```

細かい部分ですが、つまずいたポイントなので復習がてらにまとめてみました。
git ローカルリポジトリとリモートリポジトリをリンクさせる

# 目的

- ローカルリポジトリとリモートリポジトリをリンクさせる方法をまとめる

# 実施方法

1. ローカルリポジトリの`.git`フォルダが見えるディレクトリ階層で下記コマンドを実行する。(Githubのリモートリポジトリの場合、「Clone or Download」をクリックした際のURL)
    <img width="363" alt="スクリーンショット 2020-03-10 15.38.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/7076e7b1-bc50-ad11-4164-d04c6ac2bbab.png">    

    ```terminal
    $ git remote add origin "リモートリポジトリのURL"
    ```

1. 同階層で下記コマンドを実行してリンクされたリモートリポジトリのURLを確認する。

    ```terminal
    $ git remote -v
    >origin  リモートリポジトリのURL.git (fetch)
    >origin  リモートリポジトリのURL.git (push)
    ```
vue.jsの下準備とimportについて

Vue.jsの開発を始めるまでの下準備と、Vue.jsで必ず必要になるimportについて、正確に理解したいと思います。

# WebCLIとは
WebCLIとは、Vue.jsで作成するアプリの骨格を作ってくれるコマンドラインツールのことです。
Vue.jsを学習する中で、最初はCDN経由でVue.jsを呼び出して使っている方も多くいると思います。
CDNとはコンテンツを配布するためのネットワークのことです。
WebCLIを使うと、プロジェクトを作成するのもターミナル経由で行うことができるようになります。

```
vue create プロジェクト名
```
でプロジェクトの作成をすることができます。

# プロジェクトの骨格
CLI経由で作成されたプロジェクトは多くのファイルから構成されていますが、主に使うのはsrc（ソースコード）に入っているファイルになります。

## components
コンポーネント。細かく使い回す部品を管理するフォルダ

## views
ページに関するvueファイルを入れるフォルダ。

## App.vue
アプリ共通で管理するコンポーネントが集まったファイル。ヘッダーやフッターなどが入っている。

## main.js
最初に読み込まれるファイル。この中に、最初に読み込ませたいファイル、やるべき処理を入れておく。
main.jsには以下のようなコードがある。

```
new Vue({
  router,
  render: function (h) { return h(App) }
}).$mount('#app')
```

まず、 `new Vue` は新しくVueインスタンスを作成するということです。
その中にはオプションオブジェクトが入っており、これはこのようなコードに変換されます。

```
new Vue({
  el: '#app',
  components: { App },
  template: '<App />'
})
```

つまり、アプリを開始したときにAppエレメントがインスタンスとして作成されるということです。
ノートPCの画面の明るさが勝手に変わるのをやめたい時にチェックする箇所

# なんか勝手に明るさが変わるぞ…
私のPCはThinkPad X1 Carbonなんですが、作業をしてると勝手に画面の明るさが変わるんです。
なんとなく、部屋の明るさに合わせた調整を勝手にやってくれている感じですが、
個人的にはそれでやけに見づらくなったり目が疲れたりと違和感がすごいので、なんとかしたい。

調べてみた結果分かった、チェックすべき箇所を挙げておきます。
ちなみに私は調べてすぐに見つかった1番目ではなく、なかなか見つからなかった2番目が原因でした。

## 1. 電源オプションの「自動輝度調整」
デスクトップで右クリック＞ディスプレイ設定＞電源とスリープ＞電源の追加設定＞プラン設定の変更＞詳細な電源設定の変更
表示された「電源オプション」の一覧の中にある「ディスプレイ」を開くと、
「自動輝度調整を有効にする」という項目があり、ここをオフにすればよいみたいです。

（ポイント）
* そもそも「自動輝度調整」機能が付いていないPCの場合、「自動輝度調整を有効にする」という項目自体が表示されないようです。（当たり前）
* 電源オプションの中にある「現在利用できない設定の変更」をクリックしないと、「自動輝度調整を有効にする」という項目が表示されないことがあるようです。

## 2. インテルグラフィックスの設定
デスクトップで右クリック＞インテルグラフィックスの設定＞電源
「プラン設定の変更」欄の「ディスプレイ省電テクノロジー」が「有効」になっている場合、「無効」にするとよいみたいです。

（ポイント）
* そもそも「インテルグラフィックスの設定」がインストールされていないと、右クリックメニューに表示されないようです。（当たり前）
Azure DevOps Pipelines(パイプライン)のYAMLを学ぶ基礎コンテンツ

最終的に言いたいのは
https://aka.ms/adopac
↑はじめにこれやったら幸せというお話しです。

# はじめに
現在、シアトルで開催中の社内勉強会に来ています。
そこで扱われているコンテンツで１つ、入門に良い感じのコンテンツがあり公開されていましたので共有しようと思います。

# パイプラインはYAMLで書く
[Azure DevOps PipelinesのBuilds（ビルドパイプライン）を使ってみる](https://qiita.com/mstakaha1113/items/c2816c06e38cc3101cca)ではクラシックを使いました。
ただこれだけでは、再現性やら管理やらいろいろと大変です。
ざっくり言うと
**１回作ったけど、これコピペして使えませんか？**
に対応できません。

そこでYAMLが登場しているのですが、最初はとっつきにくいです。

# 現場で使える内容じゃないけどとっつきやすいコンテンツ

こちらです。
https://aka.ms/adopac
"Advanced Azure DevOps with Pipelines-as-Code"ということでGitに公開されているコンテンツになります。
英語で書かれていますが、~~ChromeでGoogle翻訳~~ 新型のEdgeでBing翻訳とかに書けたらまぁまぁ読めます。
英語わからんちんなボクがやれたので大丈夫です。
英語であることがハードルで「読めない」「理解できない」という声が多かったらForkして翻訳しますのでフィードバックをいただけますとありがたいです。（逆に「これで十分だね」的なフィードバックもありがたいです）

これだけやっても現場じゃ使い物にならないことは認めます。
でもこのコンテンツ、2時間もあればまぁまぁできます。
最初にこれだけやってみたら、かなり学習コストが下がると思いました。

# さいごに
時差で起きたら眠れなくなった現場からは以上です。
【Rails】Sorceryでfacebook認証　エラーと解決法

# はじめに

Sorceryによるfacebookログイン認証をしようとして、盛大なエラー祭りになりました。
誰かのための逆引き辞典になればいいなと思い、記録します。
ざっくりとした流れについては[別記事](https://qiita.com/aiandrox/items/ca798da0bca617074795)で書いています。

## 動作環境

```
ruby 2.6.5
Rails 5.2.3
sorcery 0.14.0
mkcert 1.4.1
```

# エラーとその解決法

## ArgumentError in Hogehoge

<img width="814" alt="スクリーンショット 2020-02-06 23.13.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322882/34eb203c-fa55-7b06-5772-0bab080214dd.png">

> ArgumentError in BoardsController#index
No association found for name `authentications'. Has it been defined yet?

### 原因と解決法

Userモデルにおける`accepts_nested_attributes_for :authentications`
は`:authentications`とのアソシエーションが存在することが前提となっている。
そのため、`has_many :authentications, dependent: :destroy`より下に書く必要がある。

## Sorry, something went wrong.

<img width="777" alt="スクリーンショット 2020-02-04 16.11.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322882/8c4e54a0-6cc4-0807-de48-5f719f10849c.png">
> Sorry, something went wrong. 
we're working on getting this fixed as soon as we can.

### 解決法


```rb:sorcery.rb
  config.facebook.user_info_path = 'me?fields=email'
  config.facebook.access_permissions = %w[email]
```

ここに不適な値を入れていた場合に起こるので、一旦デフォルトに戻してみる。


## URLはブロックされています

<img width="617" alt="スクリーンショット 2020-02-04 20.28.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322882/6bd15690-ef9e-2944-3538-1b6be78b96a0.png">

>URLはブロックされています: リダイレクトURIがアプリのクライアントOAuth設定でホワイトリストに追加されていないため、リダイレクトできませんでした。クライアントとウェブOAuthログインをオンにして、すべてのアプリドメインを有効なOAuthリダイレクトURIとして追加してください。


### 解決法

`https://localhost:3000`と`https://localhost:3000/oauth/callback?provider=facebook`を有効なOAuthリダイレクトURIに登録する。
リダイレクトURIはSorceryの`callback_url`のことです。

## 接続はプライベートではありません

<img width="642" alt="スクリーンショット 2020-02-04 20.26.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322882/4c2a310b-e55f-ac4c-9007-0c4848ad8b6b.png">
「OK」をクリックすると
<img width="826" alt="スクリーンショット 2020-02-04 20.19.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322882/23ff025a-d9e5-6837-8251-cbd00f017ef5.png">
<img width="747" alt="スクリーンショット 2020-02-04 20.31.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322882/8baf059c-a65a-07c0-4cb7-1cdee75aa442.png">

### 原因と解決法

リダイレクトURIを`https://0.0.0.0:3000/oauth/callback?provider=facebook`のままにしているとこのような警告が出る。
mkcertの設定では`https://0.0.0.0`は証明書の対象ではないので、HTTPS化していない。
`https://localhost:3000/oauth/callback?provider=facebook`に書き換える。

# おわりに

と言う名の反省。

最初にいろんな作業を中途半端に進めた結果、エラーが出たときにどこが原因なのかわからなくなってしまいました。
みなさんは、まずはwikiに従って、その後自分で設定を追加していくようにしてください。
くれぐれも、よくわかってもいないのにリファクタリングとか設定の追加をしながら書き進めていかないように。
基本情報技術者　テクノロジ系　第9章 データ構造、アルゴリズム、プログラミング②


# リスト,スタック,キュー
リスト: データとデータをリンクで接続して、順番にデータを取れるようにしたものです。
スタック: 直近から古い順にデータを遡ってデータを取り出したい時に使用します。
       のデータ構造ともいいます。後入れ先出し(LIFO)
キュー: データを格納した順に取り出したい時に使用


## リスト(線形リスト)
リストの構成データをリストの要素といいます。

特徴として

* レコード型の変数
* データをいれる項目
* 次の要素のアドレスをいれる項目
* 末尾の.nextにはNULLや-1がが入れられます。


## スタック
データを積み重ねて管理するイメージです。

用語として
* プッシュ(PUSH): データをいれる。
* ポップ(POP): データを取り出します。

後入れ先出しの法則です。

## キュー
データを行列入れて管理するイメージです。

* エンキュー(ENQUEUE　またはENQ): データを格納する
* デキュー(DEQUEUEm またはDEQ): データ取り出し
IT企業でよく使われる横文字をまとめてみた

# はじめまして
ここ最近、転職をしましてエンジニアらしくプログラミング等々をお勉強しております。前職でDB少しいじって、転職後はSpringを学んでたんですけど、ここに来て急遽Swiftをやることになりました。文法はもとよりXcodeを使いこなさないと…

今後は、自分の備忘録も兼ねて記事を残して行こうと思いますが、最初はとりあえずQiitaに投稿することを目的に自分の書きたいことを記事にしてみました。

# ターゲットとなる読者
- IT企業への入社を考えている方
- これからIT企業に入社する方
- 直近でIT企業に入社した方

# そもそも横文字ってなに？
所謂、カタカナ語のことです。
その中でも、ビジネスシーンで使われるカタカナ語のことを「横文字」と言っているような気がします。（あくまで個人の見解ですが。。。）
横文字が得意な人、苦手な人、好きな人、嫌いな人といろんな方がいらっしゃると思いますが、IT企業で働く上で頻出の横文字を興味本位でまとめてみましたのでご覧ください。

# 【超頻出】IT企業で使われる横文字

## アサイン
### 意味
仕事を割り当てる、任命するという意味
### 使用例
Aさんを〇〇のプロジェクトにアサインする
(Aさんをプロジェクトに割り当てる)

## エビデンス
### 意味
証拠。IT企業で使われるエビデンスとは、主にシステムテストなどの際にスクショした画面のキャプチャのこと。テスト結果とテストの完遂を担保する証拠として画面キャプチャを取得することが多い。
### 使用例
「エビデンス取得しておいて！」
(「テストの時の画面キャプチャ取っといて！」)

## タスク
### 意味
仕事。作業。自分やチームがやるべき仕事
### 使用例
「タスク管理できてる？」
(「自分のやるべき作業の管理できてる？」)

# 【頻出】IT企業で使われる横文字
## サマリー
### 意味
要約、概要という意味。文量の多いドキュメントをまとめるときとか会議の時によく使われる。
### 使用例
「このドキュメント、お客様のところ持ってくからサマリー作ってもらえる？」
(「このドキュメント、お客様のところ持ってくから要約した文章作ってもらえる？」)

## リスケ
### 意味
Reschedule(リスケジュール)の略称。つまり、スケジュールを変更する、計画を立て直すという意味。
### 使用例
「〇〇プロジェクトの進捗が遅れてるからリスケしないと」
(「〇〇プロジェクトの進捗が遅れてるからスケジュールを練り直さないと」)

## デフォルト
### 意味
直訳すると、標準や基本という意味。IT企業では初期値や初期設定という意味で広く使われる。
### 使用例
システムをデフォルトのまま使う
(システムを標準の初期設定から変更せずに使う)

## リソース
### 意味
直訳すると資源という意味を持つがIT企業では様々な使い方をする。

1. 人手、人材という意味。プロジェクトにアサインすることのできる要員

2. サイトやシステムで使うためのファイルや画像のこと。

3. PCのCPU性能やメモリ、ディスクの容量のこと

###使用例(1の例を)
慢性的なリソース不足
(慢性的な人手不足)

## アラート
### 意味
直訳すると警報という意味。使われ方としては、プロジェクトが納期に間に合わなそうな時とかに、助けを求めたり、上に報告するときによく出てくる。
### 使用例
ヤバイなと思った時は早めにアラートあげてね
(ヤバイなと思った時は早めに悪い状況を報告してね。)

【よく聞く】IT企業で使われる横文字
## バッファ
### 意味
IT企業では主に2つの意味で使われる。

1. 時間的なゆとり、期限までの余裕という意味

2. データを一時的に保存しておく領域のこと

### 使用例(1の例を)
バッファを持たせて計画を立てる
時間的なゆとりを持って計画を立てる

## スクラッチ
### 意味
ゼロから。最初からなどという意味。IT企業ではスクラッチ開発というワードで使われる。スクラッチ開発とは、パッケージや既存のものを使わずにゼロからシステム開発をすること。ゼロベース開発とも言う。
###使用例
今回のプロジェクトはスクラッチ開発にする
(今回のプロジェクトはゼロから開発して作る)

##エンハンス
###意味
高める、促進するという意味。IT企業ではエンハンス開発というワードで使われる。エンハンス開発とは、既存のシステムに対して追加機能を使ったり、性能の改善を行うこと。機能追加とか改修と同じ意味。
###使用例
エンハンスの案件が獲れた
(追加機能作成[あるいは改修]の案件が獲れた)

#おわりに
とまあ、ざっくりこんな感じ。いやもっとある、はず。。。
というわけなので、時間があるときにコレと思うのがあったら追加しようと思う。

ちなみにタイト、アウトプット、ソリューションとかは会社以外でもよく聞く一般的な横文字なので割愛しましたー。
JQLサンプル

## 動機

JiraのIssueをJiraクエリ言語 (JQL: JIRA Query Language)を利用して効率的に取得したかった．

## サンプルコード

* 特定プロジェクト/特定Issue

```SQL
project = "" AND issueType = ""
```

* 特定プロジェクト/特定Issue/特定期日

```SQL
project = "" AND issueType = "" AND duedate = "<yyyy/mm/dd>"
```

* 特定プロジェクト/特定Issue/未アサイン

```SQL
project = "" AND issueType = "" AND assignee is EMPTY
```

* 特定プロジェクト/特定Issue/今週期限

```SQL
project = "" AND issueType = "" AND due < endOfWeek()
```

## 参考

* [課題の検索](https://ja.confluence.atlassian.com/jiracoreserver073/searching-for-issues-861257157.html)
* [詳細検索 - 関数リファレンス](https://ja.confluence.atlassian.com/jiracoreserver073/advanced-searching-861257209.html#)
* [詳細検索 - フィールド リファレンス](https://ja.confluence.atlassian.com/jirasoftwarecloud/advanced-searching-fields-reference-764478339.html)
* [JIRAのチケット検索で使うJQLの例(適宜追加)
](https://qiita.com/takahirono7/items/4052321fe26130957c03)
基本情報技術者　テクノロジ系　第9章 データ構造、アルゴリズム、プログラミング①



# 変数と配列
データの格納方法を【データ構造】といいます。


## データ型
データの種類のこと

* 整数型
* 少数型
* 文字型
* 論理型:　偽が真を表す

## 変数
数学で扱うものと一緒

変数にはデータを一つだけ格納することができます。

## レコード型の変数
構造体変数ともいいます。
複数の項目をもつ情報カードのような変数です。

例として

⚪️学生型の形式　⇦ 〜型の形式と呼称する

| 項目名 | 型 | 内容 |
|:-:|:-:|:-:|
|  id |整数型   |1000   |
|  name |文字型   | tanaka  |
|  sex | 文字型  | otoko  |

このように

形式を呼称して

格項目に情報を入れて行きます。

変数aに会員番号を格納するには

a.id ⇦ 10001

と表記します。

## 配列
棚や靴箱と行ったイメージ

一つの配列に同系統のデータが複数入っている訳です。

先頭要素を0か1とする場合があるので注意が必要です。

()などの括弧で要素番号を指定します。

例えば配列aの6番目の要素を指定する時

最初が1の時

a(6)

最初が0のとき

a(5)

とします。


## 二次元配列

基盤の目のようにマス目をもつ配列です。

例えば

配列名: 学生
行番号: 学生の名前
列番号: 数学の成績(他にも国語の成績など)

という風に取り出します。
AWSのちょっとしたコストを節約した話

みなさま、こんにちは。

**今回はAWSの利用でちょっとしたものだけど地味にお金がかかる部分とそのコスト削減する方法をお伝えします！**

少しのお金でも放っておくとちりつもで洒落にならない金額になることもあるので、この機会に是非見直してみてください。

# その1 EBSのスナップショット:cold_sweat:

意外と見落としがちなこちら！
EBSのスナップショットです。

そんなのあまり作ったことないなーという方もいるかと思います。

ですが、**AMI**はどうでしょうか。

実はAMIとは裏側ではEC2のインスタンス情報とEBSのスナップショットで構成されています。

そのため、AMIを作ったことのある方はもれなくEBSスナップショットを作っています！

しかもここからが怖いところでして、、

### なんとAMIを解放したとしてもEBSスナップショットは削除されません！！

そのため削除する仕組みを別でこさえなければ永遠に増えていきます。

削除する方法はこちらがおすすめです。
https://coatiblog.sios.jp/ami登録解除時、スナップショットを自動で削除す/

EBSの料金はこちらになっていますが、家庭のAWSなどでは少しの費用でも節約したい方が多いと思いますのでお気をつけください。（企業の方も知らないうちに何TBとかになっていませんか。。？）

<img width="1242" alt="スクリーンショット 2020-02-06 20.47.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424626/387567fd-c906-b47b-92ec-8538ede9afc2.png">
(AWS公式ドキュメントより）


# その2 EIP(ElasticIP):disappointed_relieved:

こちらはご存知の方も多いと思うので、大きいポイントを紹介します。
#### 1. EIPは起動中のインスタンスに紐づいている時は課金されない
#### 2. EIPは停止中のインスタンスにくっついている場合、課金される
#### 3. EIPは紐づいていない場合課金される

そのため、早めに気づいて不要ならば解放する必要があります。
私のお勧めする方法は
#### Config → CloudWatchEvents → Lambda
です。

現在AWS Configにはeip-attachedなるマネージドルールがあり、そちらを利用することでCloudWatchEventで検知できる状態になります。

CloudWatchEventsのポイントとしては下記のように細かく絞れるのですが、特定のルールで**"eip-attached"**を指定するのがポイントです！
<img width="1248" alt="スクリーンショット 2020-02-06 22.29.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424626/1b1e3afb-65b0-ee9d-2fa2-239ef7e4a414.png">

ターゲットに指定するLambdaの方はまた次回の記事、Lambdaでイベントを検知する。で紹介したいと思います。
Lambdaを書くのが得意な方は独自の書き方でも構いません。

EIPの料金はこちらです。リージョンごとに違いますね。
<img width="1020" alt="スクリーンショット 2020-02-06 22.34.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424626/7c98c986-e90c-718a-91a4-36665feee544.png">


#### この２つは特に金額が小さく見落とされがちですが、数が多かったり放置する時間が長くなれば意外と大きな金額になります!!

みなさまもこの機会にAWSのコストを最適化し、少しでも他の必要なところにお金を使っていきましょう。

お読みいただきありがとうございました！！
docker+Oracle環境下でbuild後に発生したDB接続エラー

## 事象
docker + oracle/PHPUnit実行環境での開発時、dockerfileの更新を行い
imageをbuildしphpunitを動かすとDB接続エラーが発生。

何度かphpunitを実行すると<b>Oracleエラーコードが変化する</b>不思議な事象に遭遇した時のお話。

## 環境情報
開発はdockerコンテナ上に、
・Oracleサーバーを構成し、開発DB環境よりデータをdumpしローカルDB環境へテーブル構造をimportするイメージ
・PHP7環境にphptunitをcomposerでインストールしvolumeしたテストコードを実行するイメージ
のサービス構成となっている。

##変化していくエラーコード
コンテナを立ち上げ、UnitTestを実行すると以下のエラーが順に発生。

```
`ORA-12528:TNS:リスナー: 該当するインスタンスはすべて、新規接続をブロックしています`
`ORA-12526:TNS:リスナー: 該当するインスタンスはすべて限定モードになっています`
`ORA-12537:TNS:接続がクローズされました。`
`ORA-01017:ユーザー名/ パスワードが無効です。ログオンは拒否されました。`
`ORA-01045: user ユーザ名 lacks CREATE SESSION privilege; logon denied`
```

環境変数`ORACLE_HOME`や`ORACLE_SID`を再確認し、`tnsnames.ora`を見直していく中、
変わり身の早さに負けまいと対処を続け、果てには`shutdown & setup`も行う。
暫くすると……突然エラー解消、UnitTestが成功。

構築環境がカタストロフィではなかったもの、釈然としない。

##原因はOracleのstartup
何度か同様の動作を繰り返していくうちに、

・コンテナの再起動では発生しない、再ビルドで発生する
・時間経過で解消される
　　　　　↓
<b>「dumpしたテーブル構造のimport処理に時間がかかっているのでは？」</b?>

と推測し、コンテナのプロセスをUnitTest実行時にチェックするようにした。

```
#!/bin/sh -u

# option取得
# * -f オプションで強制的に実行
getopts "f" forceExec

# 起動中のコンテナでimportが走っていないか確認
# 自身のgrep処理は除外
if [[ -n `docker-compose exec (database/image) /bin/bash -c 'ps ax | grep -e "(起動script/α)" -e "(起動script/β)" -e "impdp(import処理)" | grep -v "grep"'` ]]; then
  # option check
  if [[ ${forceExec} != 'f' ]]; then
    echo 'now running database script. please wait a few minutes.'
    exit
  fi
fi

# unit test
# phpunit は composer.jsonで定義
docker-compose exec (api/image) bash -c 'phpunit (対象directory)'
```

UnitTest実行のshellにチェックを設けて、チーム内周知で一件落着。
インスタンス環境構築の落とし穴に入りかけた一幕と相成りました。