OmniAICreator/Qiita-1.07M huggingface dataset:
Rubyの例外処理まとめ

## そもそも例外とは？

プログラム実行中に発生したエラーの意。
例外処理を記述しないと、例外発生時点でプログラムが停止してしまい、それ以降に記述してあるコードが読み込まれない。
Rubyで例外を補足するためには`rescue`メソッドを用いる。

## 例外の種類

[Ruby公式リファレンス](http://doc.okkez.net/2.1.0/view/library/_builtin)を参照。

## begin~rescue

例）「1/0」の箇所で、整数は0では割れないため、「**ZeroDivisionError**」という例外が発生。

```ruby
begin
  1/0
rescue => e
  puts e
end

#=> divided by 0
```

eには例外オブジェクト(ZeroDivisionErrorなど)が代入されるので、それら例外オブジェクトに実装されている基本的なメソッドを使用することができる。
 - class : 例外の種類
 - message : 例外のメッセージ
 - backtrace : 例外発生の位置情報

```ruby
begin
  1/0
rescue StandardError => e
  puts e
  puts e.class
  puts e.class.superclass
  puts e.message
end

#=> divided by 0
#=> ZeroDivisionError
#=> StandardError
#=> divided by 0
```

## 応用メソッド（ensure/retry/raise/File.open）

**ensure**：例外の有無に関わらず実行される

```ruby
begin
  1/0
rescue => e
  puts e
ensure
  puts "ensure"
end

#=> ensure
```

**retry**：beginからの実行をもう一度やり直す

```ruby
count = 0
begin
  1/0
rescue
  p count += 1
  retry if count < 3
  puts "failed"
end 

#=> 1
#=> 2
#=> 3
#=> failed
```

**raise**：意図的に例外を起こす

```ruby
begin
  raise
  rescue
    p "例外です"
end

#=> 例外です
```
unameのオプション -表示順別意味-

## 環境
GNUコマンド: GNU core utilities version 8.26 

## unameコマンド概要
Linuxサーバにログインした時等に使う uname コマンドについて調べてみました。
unameは、”システムについて情報を表示する。"コマンドでGNU Coreutilsのひとつです。

## オプションの意味と表示順
複数のオプションや ‘-a’ オプションが指定された場合の表示順別にオプションの意味をまとめました。

|表示順|表示情報|option|意味|備考|
|--:|:-:|:-:|:--|:--|:-:|:-:|
|1|kernel-name|-s|カーネル名を表示する|OSによってOS名とカーネル名が同じものと(FreeBSD, HP-UX など)、 違うものがある (GNU/Linux, Solaris など) |
|2|nodename|-n|ネットワークノードのホスト名を表示する。|現場ではhostnameの代替としてよく使われる（hostnameだとホスト名を変更可能なので、ポカ除けの意）
|3|kernel-release|-r|カーネルのリリース名を表示する。|
|4|kernel-version|-v|カーネルのバージョンを表示する。|
|5|machine|-r|マシンのハードウェア名を表示する。|ハードウェア・クラスとかハードウェア・タイプと呼ばれることもある|
|6|processor|-p|プロセッサ・タイプを表示する|情報が取得できない場合は、‘unknown’ と表示する。GNU/Linux ディストリビューション同士の間ですら可搬性がない。|
|7|hardware-platform|-i|ハードウェア・プラットホームの名前を表示する|情報が取得できない場合は、‘unknown’ と表示する。GNU/Linux ディストリビューション同士の間ですら可搬性がない。|
|8|operating-system|-p|オペレーティング・システムの名前を表示する。||

processorやhardware-platformで表示されるものは、アーキテクチャやプロセッサにより異なるようです。unameのソース（Cで書かれている）としては、processorを返してくれと言っていても其々のプロセッサが違うものを返して来たらどうしようもないですね。

## 補足
ちなみに、公式マニュアルには下記のように書いてあり、どこかでスペースで区切られたものは見づらいよね。的なことを言っています。
> 複数のオプションや ‘-a’ オプションが指定された場合、選択された情報は次の順番で表示される。

>``` 	
kernel-name nodename kernel-release kernel-version
machine processor hardware-platform operating-system
```

[GNU Coreutils 公式マニュアル](https://linuxjm.osdn.jp/info/GNU_coreutils/coreutils-ja.html)より引用




## 参考文献
- [GNU Coreutils 公式マニュアル](https://linuxjm.osdn.jp/info/GNU_coreutils/coreutils-ja.html)
- [MaiZure's Projects(GNU Coreutilsのソースコードを解読しているサイト)](https://www.maizure.org/projects/decoded-gnu-coreutils/uname.html)
GAEでGo1.9からGo1.11へ移行したらストレージでマルチリージョンのバケットが使用されていた

＊メモ的な感じで記載しています。

2020年3月2日に2020年2月請求として￥3円が発生。
何事かと思い請求内容を確認したところ、ストレージのマルチリージョンに対して請求があった。
今年の1月までは無料トライアル期間であったため気がついていなかった。

どうやら移行作業を行なった時からストレージのマルチジーリョンのバケットが使用されていることがわかった。

当時（昨年末）、Go1.9からGo1.11へ移行するため試行錯誤し、やっとデプロイできる様になったので、
問題なくデプロイできるか確認するために何度もデプロイを行なった。
(Mac のターミナルで gcloud app deploy を実行)
結果、ビルド？されたファイルが多く作成され、数百MBも使用していた。


調べた結果、次のことがわかった。
・デプロイするとローカルにあるソースがストレージ（標準？のリージョン）へアップロードされる。
・次に、Cloud Build サービスを使用してコンテナイメージを作成される。
・コンテナイメージが App Engine へ適用される。

ん？Cloud Build サービス？

Google Cloud ドキュメントを確認しました。

* [アプリケーションのデプロイ](https://cloud.google.com/appengine/docs/standard/go111/testing-and-deploying-your-app#deploying_your_application)
デプロイを行うと、Cloud Build サービスが App Engine スタンダード環境で実行するアプリケーションのコンテナイメージを作成します。

* [ビルドイメージの管理](https://cloud.google.com/appengine/docs/standard/go111/testing-and-deploying-your-app#managing_build_images)
新しいバージョンをデプロイするたびに、Cloud Build サービスを使用してコンテナイメージが作成され、Container Registry の app-engine フォルダに保存されます。
自動的に削除されないので、保存容量の上限に達する前に不要なイメージは削除するとよいでしょう。

* [ローカル イメージにレジストリ名でタグ付けする](https://cloud.google.com/container-registry/docs/pushing-and-pulling#tag_the_local_image_with_the_registry_name)
イメージを新しいホスト名でレジストリに push すると、Container Registry では、指定された**マルチリージョン内にストレージバケットを作成します。**

ここです！
「マルチリージョン内にストレージバケットを作成します。」って書いてある！
ビルドイメージの管理には「自動的に削除されないので」と書いてある！

確認のために何度もデプロイをした結果、コンテナイメージファイルが大量に作成され、数百MBも使用してしまったようです。
リージョンが asia-northeast1 でしたので、us-east1 で新規に作成したけど、マルチリージョンが使用されていました。

とりあえず、古いファイルを削除して料金がどの様になるか様子を見ています。

請求が発生しない方法？など、知っている方がいましたら教えてください。

---

気になる点

* [支払い方法の設定が必要](https://cloud.google.com/appengine/docs/standard/payment-instrument#what_is_remaining_the_same)

App Engineの標準環境であるPython 3、Java 11、PHP 7、Go 1.11 / 1.12、Ruby、NodeJSランタイム、およびApp Engineフレキシブル環境は変更されていません。これらのランタイムは常にCloud Buildを使用しており、支払い手段が​​必要でした。（翻訳）

と書いてあるので、第二世代のランタイムは全てデプロイ時にマルチリージョンのバケットが使われるのだろうか？
【PHP】ファイル操作

ファイルの基本的な操作についての覚書。

#ファイル作成・書き込み

ファイルの作成・書き込みには`file_put_contents`を使います。

```php
file_put_contents("./news.txt","aaa");
```

第1引数にはファイルを配置する場所（ファイルパス）を指定し、第2引数には書き込む内容を指定します。

実行すると自動的にnews.txtが作成されaaaが書き込まれているのが確認できます。

`file_put_contents`は処理に失敗すると「false」が返ってくるので、if構文で下記のようにすることもできます。

```php
$success = file_put_contents("./news.txt","aaa");

if($success) {
    echo "書き込み成功";
}else{
    echo "書き込み失敗";
}
```

今回は自分のパソコン内で試しているのでドキュメントルートにnews.txtを保存しましたが、外部サーバーを使う場合には注意しなければなりません。

以下のアドレスを叩くとnews.txtの中身が丸見えです。
*http://ドメイン名/news.txt*

ドキュメントルートに保存したファイルはWebブラウザで閲覧できてしまうので、通常ファイルはドキュメントルートの外に保存します。

```php
file_put_contents("./news.txt","aaa")

//↓ドキュメントルート外に保存

file_put_contents("../test/news.txt","aaa")
```

##ファイル読み込み
ファイルを読み込むときは`file_get_contents`を使います。
先ほど作成したファイルを読み込んでみます。

```php
$data = file_get_contents("../test/news.txt");
echo $data;
```

実行すると、先ほど書き込んだ「aaa」が表示されることを確認できます。

#ファイル読み込みと表示を同時に行う
ファイルを読み込んで画面にそのまま表示するとき、先ほどのように読み込み→表示とステップを踏むのもいいですが、それを一度に行える関数が用意されており、下記のように書き換えることができます。

```php
$data = file_get_contents("../test/news.txt");
echo $data;

//↓ readfileで一気に行う

readfile("../test/news.txt");
```

#ファイルに追記
既存のファイルに追記する場合、下記のようにします。

```php
$data = file_get_contents("../test/news.txt");
$data .= "<br>bbb";

file_put_contents("../test/news.txt",$data);

readfile("../test/news.txt");
```
まずファイルを読み込んで、「.=」で内容を付けたしました。
「.=」は文字列連結を省略した書き方で、次の書き方と同義です。

```php
$data = $doc . "<br>bbb";
```
そしてfile_put_contentsで上書き保存をします。
実行した結果、下記のように表示されることが確認できます。

```
aaa
bbb
```
Atcorder151 A~C問題

Atcorder151 
https://atcoder.jp/contests/abc151/tasks

#A問題
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/f91a4eb7-a161-8fa7-b77f-896831d1c1f3.png)

```A問題.c++
#include <bits/stdc++.h>
#define rep(i,n) for (int i=0; i<(n); i++)
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

int main(){
    char c; cin >> c;
    cout << char(c+1) << endl;
}
```

#B問題
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/9eb2b3d8-40e0-619b-8b79-8d4da45c1879.png)

```B問題.c++
#include <bits/stdc++.h>
#define rep(i,n) for (int i=0; i<(n); i++)
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

int main(){
    int N,K,M; cin >> N >> K >> M;
    int sum=0;
    vector <int> A(N);
    rep(i,N-1){
        cin >> A[i];
        sum+=A[i];
    }
    
    if(sum/N>=M) cout << 0 << endl;
    else if((sum+K)/N<M) cout << -1 << endl;
    else cout << M*N-sum << endl;
}
```

#C問題
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475270/6acd768d-bf64-860f-3d5b-6e7c64fb8c2a.png)

```C問題.c++
#include <bits/stdc++.h>
#define rep(i,n) for (int i=0; i<(n); i++)
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

int main(){
    int N,M; cin >> N >> M;
    int A[N+1]; //ACの初期状態
    int B[N+1]; //ACが出るまでのWA数
    rep(i,N+1){
        A[i]=0;
        B[i]=0;
    }
    int AC=0;
    int WA=0;
    
    rep(i,M){
        int a; cin >> a;
        string b; cin >> b;
        
        if(b=="AC" && A[a]==0){
            A[a]=1;
            AC++;
            WA+=B[a];
        }
        if(b=="WA" && A[a]==0) B[a]++;
    }
    cout << AC << " " << WA << endl;
}
```

#まとめ
・A問題　**アスキーコード問題**に少し手間取った…

```c++
cout << 'a' << endl; 
>> a

cout << char(97) << endl;
>> a
```

・C問題　問題文をよく注意して読まないと間違える（**WAをいくら出しても、その問題でACを一度も出さなかったらWAの数には入れない！**）
【Rails】フレンドリーフォワード

#フレンドリーファワード
ログインしていないユーザーが編集ボタンをクリックする際に、ログイン後にトップページではなく編集ページに飛ぶようにしたい。
そういった機能を追加できるのがフレンドリーフォワードです。

#実装

```sessions_helper.rb
  def store_location
    session[:forwarding_url] = request.original_url if request.get?             
  end
```
```users_controller.rb
    def logged_in_user                                                                
      unless logged_in
        store_location                                 
        flash[:danger] = "please login"
        redirect_to login_url                                                   
      end
    end
```
ユーザーのログイン時にフレンドリーフォワードを実装するにはセッションヘルパーに`store_location`を定義し、`users_controller.rb`にて`logged_in_user`メソッドを定義します。

まず`logged_in_user`でユーザーがログインしていない場合に`store_location`を実行させ、現時点のURLを`session[:forwarding_url]`に保存します。

`original_url`はhttp(s)以外も扱えるよう指定しています。
`request.get?`でGETリクエストの時だけ値を格納しているように指定しているのは、ログインしていないユーザがフォームで送信した場合にurlを転送先に保存させないためです。

```sessions_helper.rb
  def redirect_back_or(default)
    redirect_to(session[:forwarding_url] || default)
    session.delete(:forwarding_url)
  end

  def store_location
    session[:forwarding_url] = request.original_url if request.get?             
  end
```

```sessions_controller.rb
  def create
    @user = User.find_by(email: params[:session][:email].downcase)
    if @user && @user.authenticate(params[:session][:password])true
      log_in @user
      params[:session][:remember_me] == '1' ? remember(@user) : forget(@user)
      redirect_back_or @user
    else
      flash.now[:danger] = 'Invalid email/password combination'
      render 'new'
    end
  end
```
そしてセッションヘルパーに`redirect_or_back`メソッドを追加し、`sessions_controller.rb`の`createアクション`にて`redirect_back_or @user`を追記します。

`session[:forwarding_url] || default`で`session[:forwarding_url]`の値がnillだった場合に`default`になるようになっています。

`session.delete(:forwarding_url)`ではログイン後に指定のパスに移動した後に`:forwarding_url`を削除するようにしています。
こうすることで次回ログインした時に保存していたURLに飛ぶことを防いでいます。

上記手順でフレンドリーフォワードを実装できました。
VisualStudio2017でリモートデバッグ

## やること
ubuntu環境をdockerで構築し、VisualStudio2017からリモートデバッグを行います。

## リモートデバッグを行うコンテナを用意
 
``` docker:dockerfile
FROM ubuntu:16.04

# 各種インストール
RUN apt-get update
RUN apt-get install -y openssh-server sudo bash-completion g++ gdb gdbserver rsync git
# SSH用のディレクトリ作成
RUN mkdir /run/sshd
# ユーザーを追加
RUN useradd -m -s /bin/bash ubuntu && gpasswd -a ubuntu sudo
# パスワードを設定
RUN echo 'ubuntu:ubuntu' | chpasswd

# 22番ポートを公開
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
```

### 
``` docker:docker-compose
version: '2.3'
services:
  dev:
    build: .
    ports:
    - "2222:22"
    volumes:
    - ../volume:/tmp/data
```

#### イメージをビルド/コンテナを起動
```
$ docker-compose build
$ docker-compose up -d
```

#### SSH
```
$ docker exec -it docker_dev bash
```

## VisualStudio
### デバッグを行うプロジェクトを用意
- 新規作成 > Visual C++ > クロスプラットフォーム > Linux
    - ない場合はインストーラから「C++によるLinux開発」を選択し、インストール

### VisualStudio側の設定
- 接続先の指定
    - ツール > オプション > クロスプラットフォーム > 接続マネージャー > 追加
        - ホスト名：リモート先のIP(localhost)
        - ポート：22番ポートにマッピングされているポート(2222)
        - ユーザー名：ゲストOSのユーザー名(ubuntu)
        - 認証の種類：パスワード
        - パスワード：上記で設定したパスワード(ubuntu)

> ()は上記で設定した場合の値

### デバッグ
- ソリューションのリビルドを実行
    - ビルド > ソリューションのリビルド
- Linuxコンソールの表示
    - デバッグ > linux コンソール
Javascript fixedで固定したボタンを特定の位置で止める

初投稿です。
駆け出しのエンジニアではありますが、質問やご意見等が御座いましたらお気軽にどうぞ。

##概要
サイト制作をしていると、
スクロール時に追従してくるボタンなんかをよく実装すると思います。
ですがデザイン上、フッター等の背景色とボタンの色が被ってしまうこともあるでしょう。

今回はトップに戻るボタンを、footer等の要素手前辺りで停止させるのに色々試した結果、
Javascriptでの制御がとても解りやすかったので備忘録的に残しておきます。

##制御部分のコード

```Javascript:Javascript
window.addEventListener('scroll', () => {
      const elem = '任意のボタン positionはfixedで右下に設定';
      const docHeight = document.body.clientHeight;
      const scrollCount = document.documentElement.scrollTop || document.body.scrollTop;
      const scrollPos = document.documentElement.clientHeight + scrollCount;
      const footerHeight = document.querySelector('footer（任意）').clientHeight;
      if (docHeight - scrollPos <= footerHeight) {
        elem.style.position = 'absolute';
        elem.style.bottom = footerHeight + 20 + 'px';      
      } else {
        elem.style.position = 'fixed';
        elem.style.bottom = 20 + 'px';
      }
 });
```
##下準備として
ボタン部分はHTML/CSSで任意に作成しfixedで追従しておきます。
また、JSのイベント時にはabsoluteに切り替えますので、body下に親要素のrelativeを設定しておく必要があります。

##部分的に解説
###定数に格納
```Javascript
//ページ全体の高さ取得
const docHeight = document.body.clientHeight;
//対応ブラウザ別に縦のスクロール量取得
const scrollCount = document.documentElement.scrollTop || document.body.scrollTop;
//ページの表示領域を取得し、スクロール量を足す
const scrollPos = document.documentElement.clientHeight + scrollCount;
//この場合はfooterの高さを指定
const footerHeight = document.querySelector('footer（任意）').clientHeight;
```
スクロールイベントに必要なそれぞれの値を取得し、定数に格納します。
ブラウザによる違いや、スクロールバーを含むか含まないか等少しややこしいですが、
それぞれ意味が異なってきますので注意。

###イベントの処理
```Javascript
if (docHeight - scrollPos <= footerHeight) {
  elem.style.position = 'absolute';
  elem.style.bottom = footerHeight + 20 + 'px';       
} else {
  elem.style.position = 'fixed';
  elem.style.bottom = 20 + 'px';
}
```
scrollCountによりscrollPosの値はスクロールとともに増えていきます。
ページ全体の高さがfooterの高さ以下になった時、
fixedからabsoluteに切り替わります。
位置設定はfooterの高さより20pxほどマージンを取るように設定しているだけなので、
デザインによりけりとなります。

範囲外では元に戻すように設定しております。
これで違和感なく切り替わります。
Kotlin + JUnit 5 で Table Driven Test

## TL; DR
[Go言語のテーブル駆動テスト][TDT]みたいなことをKotlin + JUnit 5でやってみたのでスニペットレベルに近い形で軽くまとめました。


## 環境
- Kotlin: `1.3.50`
- Spring boot: `2.1.5.RELEASE`
- JUnit: `5.5.1`

## テストケースを内部クラスで定義

```kotlin
inner class TestCase(
    val testName: String,
    val paramsMap: Map<String, String>
)
```


## `@TestFactory` アノテーションでテストケースのインスタンスをStreamで流し込む

```kotlin
@TestFactory
fun test(): Stream<DynamicNode> {
    return Stream.of(
        TestCase(
            testName = "データ取得オフセットの値が0より小さい場合",
            paramsMap = mapOf("limit" to "15", "offset" to "-1")
        ),
        TestCase(
            testName = "記事取得件数が0より少ない場合",
            paramsMap = mapOf("limit" to "-1", "offset" to "0")
        )
    ).map { testCase ->
        DynamicTest.dynamicTest(
            testCase.testName
        ) {
            val queryParams = LinkedMultiValueMap<String, String>()
            queryParams.setAll(testCase.paramsMap)

            mockMvc.perform(
                MockMvcRequestBuilders
                    .get("articles")
                    .params(queryParams)
            )
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().isUnprocessableEntity)
                .andReturn()
        }
    }
}
```


## まとめ
APIのクエリパラメータの異常系のテストとかはテーブルドリブンテストでまとめると、テストケースの一覧性があって見やすいので積極的に活用していきたいです。


[TDT]:https://github.com/golang/go/wiki/TableDrivenTests
elasticbeanstalkにcronoを設定したので、そのconfig

# Elasticbeanstalk + rails + crono

railsでcron的なものを使いたかったけど、crontabを触りたくなかったので、cronoを使うことにした.その設定ファイル（結構作るのに時間かかったので。。。）
Cronoは[こちら](https://github.com/plashchynski/crono)
I would like to use something like cron with rails, but didn't want to use crontab, so I try to use crono(I know it may not be maintained, but...), here is the config which I used.

## 環境
```console
# rails -v
Rails 6.0.2.1
# uname -a
Linux ip-172-31-27-188 4.14.165-103.209.amzn1.x86_64 #1 SMP Sun Feb 9 00:23:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
```

## 設定ファイル
```yaml
# cat .ebextensions/05_crono.config 
commands:
  create_post_dir:
    command: "mkdir -p /opt/elasticbeanstalk/hooks/appdeploy/post"
    ignoreErrors: true

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/post/50_restart_crono.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/usr/bin/env bash
      EB_APP_DEPLOY_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_deploy_dir)
      EB_APP_PID_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_pid_dir)
      EB_APP_USER=$(/opt/elasticbeanstalk/bin/get-config container -k app_user)
      EB_SCRIPT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k script_dir)
      EB_SUPPORT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k support_dir)
      EB_APP_LOG_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_log_dir)

      . $EB_SUPPORT_DIR/envvars
      . $EB_SCRIPT_DIR/use-app-ruby.sh
      PID=$EB_APP_PID_DIR/crono.pid
      cd $EB_APP_DEPLOY_DIR
      if [ -f $PID ] 
      then
        su -s /bin/bash -c "kill -TERM `cat $PID`" $EB_APP_USER
        su -s /bin/bash -c "rm -rf $PID" $EB_APP_USER
      fi
      . $EB_SUPPORT_DIR/envvars.d/sysenv
      sleep 10
      su -s /bin/bash -c "bundle exec crono start -P $PID " $EB_APP_USER
      sleep 10
      ln -sf $EB_APP_DEPLOY_DIR/log/crono.log $EB_APP_LOG_DIR
    "/opt/elasticbeanstalk/hooks/appdeploy/pre/03_mute_crono.sh":
      mode: "000755"
      owner: root
      group: root
      content: |
        #!/usr/bin/env bash
        EB_APP_USER=$(/opt/elasticbeanstalk/bin/get-config container -k app_user)
        EB_SCRIPT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k script_dir)
        EB_SUPPORT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k support_dir)
        . $EB_SUPPORT_DIR/envvars
        . $EB_SCRIPT_DIR/use-app-ruby.sh
        PID=$EB_APP_PID_DIR/crono.pid
        if [ -f $PID ] 
        then
          su -s /bin/bash -c "kill -USR1 `cat $PID`" $EB_APP_USER
        fi

```

## テストに使ったjob
```rb
class CronoTestJob < ApplicationJob
  queue_as :default

  def logger
    Crono.logger.nil? ? Rails.logger : Crono.logger
  end

  def perform(*args)
    logger.info '*** start crono test job ***'
  end
end
```
コード品質を改善できるツール


# Visual Studio Code (VSCode)の良いプラグイン

## Region folding

![Region folding](https://raw.githubusercontent.com/maptz/Maptz.VSCode.Extensions.customfolding/master/imgs/CSharp_region_wrap.gif)

## Better comments

![Better comments](https://raw.githubusercontent.com/aaron-bond/better-comments/master/images/better-comments.PNG)

## PHP DocBlocker
PHPDocBlockerの記述を容易にしてくれる。例えば、「/**」と入力して［Tab］キーを押せば、そのスケルトンを自動生成してくれる。また、「@」で始まるタグ名の補完も可能だ（PHP IntelliSenseではこれはサポートされていない）

![PHP DocBlocker](https://user-images.githubusercontent.com/43112/32235144-a7397b34-be2c-11e7-8817-4f5a463d2d83.gif)

## Text Maker (High light)
## Rainbow brackets
## GitLens
## GitBlame
## Git History


# Gitのコメントの良い方法
Conventional Commitsの仕様は、コミットメッセージのための軽量の規約です。 明示的なコミット履歴を作成するための簡単なルールを提供します、この規則に従うことで自動化ツールの導入を簡単にします。 この規約はSemVerと組み合わせることで、コミットメッセージへ機能、修正、重大な変更を入れることで、さらに詳細な説明を可能にします。
- Conventional commit (https://www.conventionalcommits.org/ja/)
![Conventional commit](https://miro.medium.com/max/2800/1*6NqkGS0Jwv5Pwhv_LOC3yQ.png)

# コード品質をチェック
- PHP-CS-Fixer
- PHPMD [日本語](https://github.com/unilabo/phpmd_jananese_rulesets)

[PHPMD](https://phpmd.org)
バグにつながりそうな怪しい ソースコードをチェックして教えてくれる phpmd。 コーディング時に必ず使うようにしておくとミスやバグが減るので是非使いましょう
<img width="1094" alt="Screen Shot 2020-03-19 at 13.41.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564275/af1fc9dc-f796-3f2f-a8d0-13bb4be8b4d7.png">


# ボーナス
- Octotree
GitHubのエクスペリエンスを次のレベルに引き上げるブラウザー拡張機能。 このリポジトリには、Octotree Coreのソースコードが含まれています。 ローカルでビルドおよび実行して、無料版のすべての機能にアクセスできます。 または、当社のウェブサイトからフルバージョンをダウンロードできます。 Octotreeは、Chrome、Firefox、Opera、およびSafariをサポートしています。
![octotree](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564275/4df8adb2-e3a8-fa56-47a1-37fb5f534f12.gif)
AWS Athenaで複数のクエリをまとめて実行する方法（SQL Workbench）

はじめましてSE歴2年目でまだまだ未熟者です。
このたび業務でAWS Athenaでパーティションを作成するクエリを数年分用意して実行することになったのですがAthenaでは複数のクエリを実行できないため、自分が困ったので記事にしました。

<h1>Athenaとは</h1>
>標準 SQL を使用して Amazon S3 内のデータを直接分析することができるインタラクティブなクエリサービスです

[Amazon Athenaとは](https://docs.aws.amazon.com/ja_jp/athena/latest/ug/what-is.html)

僕の中では、ログなどのデータに対してSQL文で検索、抽出ができるものといった認識です。（違ったらすみません。）


<h1>SQL Workbenchを使って複数のクエリをまとめて実行する。</h1>
先述の通りAthenaではSQLを1文ずつしか流せないので、今回はSQL WorkBenchというものを使いました。
こちらを使ってAthenaへ接続してSQLをまとめて実行するといった具合でやっていきます。


<h1>事前に準備するもの</h1>
①[SQL Workbench](https://www.sql-workbench.eu/downloads.html)

②[JDBCドライバー(4.1系または4.2系)](https://docs.aws.amazon.com/ja_jp/athena/latest/ug/connect-with-jdbc.html)
どちらのバージョンでも動作するようです。(※JDKがインストールされてない場合はそちらも必要です)

私は4.1にしました。
ダウンロード後は適当なフォルダに入れます。（そのままでもいい）
例 C:\Driver\

③AWSアカウント情報
- Access key ID
- Secret access key
- クエリ結果出力用のS3Bucket(s3://hoge/)
　
　アクセスキー及びシークレットアクセスキーが不明な場合はこちらを参照してください。
　[IAM ユーザーのアクセスキーの管理](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_access-keys.html)


<h1>設定方法</h1>

まず、ダウンロードしたSQL Workbenchのなかにあるsqlworkbench.jarを開きます。

下記のような画面が表示されたら、New profileを選択しましょう。
もし何も表示が無ければ「Select connection profile」画面の左上部を押して新しくプロジェクトを作ります。

![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533140/4cd023b7-7b1a-88ea-d954-df3d98eeb39c.png)


**設定が必要な項目は以下の6つです。**

①ProjectName：任意
　(AWS Athenaなど)


②Driver：画面左下のManage Driverを押して開いたウインドウから設定を行います。（下の画像参照）
さきほど事前に保存したローカル上のjdbcドライバーを追加する事により、フォルダのマークのドライバー一覧から選択してOKを押します。


![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533140/9ecbe7af-6d8b-ffaf-2d22-435690b839df.png)


OKを押した後は以下を設定していきます。

③URL：JDBCドライバーのバージョンにより設定が異なります。以下を参考に設定をお願いします。

　4.1～の場合
　jdbc:awsathena://athena.ap-northeast-1.amazonaws.com:443
　4.2～の場合
　jdbc:awsathena://AwsRegion=ap-northeast-1;

基本は東京リージョン（ap-northeast-1）だと思いますが異なるリージョンを利用されている場合は、ap-northeast-1の部分を各自変更してください。


④UserName：AWSのアクセスキー


⑤Password：AWSのシークレットアクセスキー

　アクセスキー及びシークレットアクセスキーに関してはこちらを参照してください。
　[IAM ユーザーのアクセスキーの管理](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_access-keys.html)

⑥Extended properties：クエリ結果を保存しておくバケットを指定します。

　・Property：　s3_staging_dir 　or S3OutputLocation
　・Value： クエリ結果を保存したいs3ディレクトリ(s3://hoge/)

**Extended propertiesは必須項目なので設定しないと必ずエラーが起きます。**

上記の6つの設定が終わって画面右下のtestを押下すると、「Connection to うんたらかんたら~~successful」というメッセージが表示されます。
エラーの場合は設定が間違っていますので設定を見直してください。

設定は以上です。

後は実行したい複数のSQL文（一つでも良い）を入力して
SQLタブ→Execute ALLを押したらAthenaへクエリを実行することができます。


お疲れ様でした。


<h1>参考元リンク</h1>
https://310ch.net/work/analytics/sql-workbench-amazon-athena

https://docs.aws.amazon.com/ja_jp/athena/latest/ug/connect-with-jdbc.html

https://dev.classmethod.jp/cloud/aws/amazon-athena-automate-partition-setting/
iOS版chromeでCSSのtransitionが動作しない

CSSで何気にtransitionを使ってたら詰んでしまったのでメモ。

#1.現象
・iOS版ChromeでCSS transition(opacityとtransform)が機能せず、がたついてしまう
→アプリを再起動するとうまくいくが、しばらくするとなぜかうまくいかなくなる。

・自分のサイトだけおかしいのかと思い、別サイト(例えば https://kenwheeler.github.io/slick/ とか)を開いてみたが、同様にがたつくので、やばいのでは？？と思い始める

・GPU起動させる、will-changeをつける、ベンダープレフィックスを頑張る、などなど色々やったが何も解決に繋がらない。

・PC版Chromeやその他のブラウザでは再現されない。

#2.背景
　おそらくは***バグ***
　「いったんタブを切り替えて、そこから元のページに戻ると、transitionのさいのfpsが落ちる」という現象が確認されている模様。
　参考にした開発側のスレッド → https://bugs.chromium.org/p/chromium/issues/detail?id=899130

　今後のアップデートで治るのを期待します。

#3.対策
　iOS版ChromeだけJavaScriptの処理で弾くことにしました。
　たとえばこれを参照 → https://qiita.com/tatunori4210/items/11a05bf54984d36732ae
KNN

**大学授業を個人的にまとめたものです**


##K Nearest Neighbors
KNNはClassificationの１つ。

KNNはResponse(Y)がmultiple classesの場合に使用できる。
例) Eye color {Blue, Brown, Green}

もし、変数Xがr attributes含んでいる場合は、r-dimensional spaceを作成する。

KNNはそれぞれの要素の距離を測り、分類する手法である。
そのため、ユークリッド距離を使用する。

```math:
dis(x_{i},x_{j})=\sqrt{(x_{i1}-x_{j1})^2+...(x_{in}-x_{jn})^2}
```


どのようにKを設定するのだろうか？
Kを決定するには、Cross-validationやLOOCV(Leave-one Out Cross-validation)を使用して
最も精度が高いKを適用する。

##Normalizing
KNNを使用する際に気をつけなければならないことは、
Variablesの値の大きさである。
KNNはユークリッド距離を使用して分類を行うため、variable毎の規模が異なると精度が落ちてしまう。
例)
 Y: 売上
 X1: お店までの距離(km)
 X2: 値段
 において、
 距離は1(km), 5(km), 10(km)という値をとる。
 しかし、値段は100, 1500, 10000などと安価なものから高額なものがある。
 そのため、距離と値段の規模は異なるため、値段の距離がモデルの結果に大きく影響してしまう。

そこで使うのがNormalizationである。

```math:
new x_{i}= \frac{x_{i}-minx_{i}}{maxx_{i}-minx_{i}}\\
```
blocklyでobjectを動かす。 その9

#概要

blocklyでobjectを動かして見る。
wemosで、Lチカ、やってみた。

#写真

![CIMG2929.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/ae01bbe4-7444-d76b-9a77-48e2758b3882.jpeg)

#ブロックを書く。

```

Blockly.Blocks.send = {
	init: function() {
		this.jsonInit({
		message0: "send %1",
		args0: [{
			type: "input_value",
			name: "TEXT"
		}],
		previousStatement: null,
		nextStatement: null,
		style: "text_blocks",
		tooltip: Blockly.Msg.TEXT_PRINT_TOOLTIP,
		helpUrl: Blockly.Msg.TEXT_PRINT_HELPURL
	})
}};
```

#フローを書く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/bf5f5e5c-86a4-bbfc-04bf-422ea0f1e3cb.png)


#objectを書く。

```

Blockly.JavaScript.send = function(a) {
    return "send_(" + (Blockly.JavaScript.valueToCode(a, "TEXT", Blockly.JavaScript.ORDER_NONE) || "''") + ");\n"
};

function send_(data) {
    var str = "http://192.168.10.8/off";
    if (data == 'on')
    {
      str= "http://192.168.10.8/on";
    }
    var xhr = new XMLHttpRequest();
	xhr.open("GET", str, false);
	xhr.send(null);
	if (xhr.status != 200)
	{
		alert("ng");
	}
	else
	{
		var res = xhr.responseText;
		alert(res);
	}
}

```

#サンプルコード


```
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

const char * ssid = "";
const char * password = "";
ESP8266WebServer server(80);
const int led = 2;

void handleRoot() 
{
	server.send(200, "text/plain", "hello from esp8266!");
}
void handleNotFound()
{
	String message = "File Not Found\n\n";
	message += "URI: ";
	message += server.uri();
	message += "\nMethod: ";
	message += (server.method() == HTTP_GET) ? "GET" : "POST";
	message += "\nArguments: ";
	message += server.args();
	message += "\n";
	for (uint8_t i = 0; i < server.args(); i++)
	{
		message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
	}
	server.send(404, "text/plain", message);
}
void setup(void)
{
	pinMode(led, OUTPUT);
	digitalWrite(led, 0);
	Serial.begin(115200);
	WiFi.begin(ssid, password);
	Serial.println("");
	while (WiFi.status() != WL_CONNECTED) 
	{
		delay(500);
		Serial.print(".");
	}
	Serial.println("");
	Serial.print("Connected to ");
	Serial.println(ssid);
	Serial.print("IP address: ");
	Serial.println(WiFi.localIP());
	if (MDNS.begin("esp8266")) 
	{
		Serial.println("MDNS responder started");
	}
	server.on("/", handleRoot);
	server.on("/on", []() {
		digitalWrite(led, 1);
		Serial.println("on");
		server.send(200, "text/json", "{text: \"on\"}");
	});
	server.on("/off", []() {
		digitalWrite(led, 0);
		Serial.println("off");
		server.send(200, "text/json", "{text: \"off\"}");
	});
	server.onNotFound(handleNotFound);
	server.begin();
	Serial.println("HTTP server started");
}
void loop(void)
{
	server.handleClient();
}




```

#成果物

http://embed.plnkr.co/plunk/NaxLwWzWZxfMVjTT

以上。
Random Forest

まず最初にDecision Treeについて理解する。なぜかというと、Decision TreeはRandom Forestの各ブロック（構成要素）だからだ。Decision Treeはnon-linear modelの一員である。

## CART algorithm
Decision TreeではCARTアルゴリズム法に基づいて構成されていく。CARTアルゴリズムを簡単に説明すると、最初のルートノードに目的変数を最も良く分類する説明変数を採用する。この場合、最も良く分類する基準として、ジニ指標が使用される。例えば、目的変数がXとYの２価をとり、説明変数がA ,B,Cで１、２の２値をとる時、説明変数のそれぞれの値の時のGini impurity（一塊のデータの中から適当に一つピックアップしてそれの”真のラベル”が”Decision Treeのアルゴリズムによって弾き出されたラベル”と異なるかを数値化したもの。「gini impurity=0」は完璧に分類されていることを意味する。）を計算し、平均値が最も低くなるような変数をルートノードとして採用する。これを続けていき、ノードをどんどん決めていく。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583706/e16b9f1c-c2e8-838c-b994-483c70f12bba.png" width=100%>

## Random Forest
### 前書き
Random ForestはDecision Treeを集めたものだ。集める理由は、Decision Tree単体でアルゴリズムを組もうとすると、train dataにoverfittingしてしまうからだ。さらに、noiseにも反応してしまう。よって、Decision Tree単体を利用するよりも、これらをCombineしensemble modelに仕上げた、Random Forestがより適しているのだ。

The random forest is a model made up many decision tree. Rather than just simply averaging the prediction of tree, this model uses 2 key concepts that give it the name random:
1. Random sampling of training data points when building trees.
2. Random subsets of features considered when splitting nodes

## 1. Random sampling of training data points when building trees.
When training, each tree in a random forest learns from a random sample of the data points. それぞれのDecision Treeにランダムに選択したサンプルを学習させる。Bootstrappingという手法が使用される。

## 2. Random subsets of features considered when splitting nodes
Only a subset of all the features are considered for splitting each node.　例えば、１６のFeaturesが存在し、そのうちの４つのみをsplitting the nodeのために使用するということ。








参考：
CARTアルゴリズムについて；
https://www.gixo.jp/blog/3980/

Gini impurityについて；
https://victorzhou.com/blog/gini-impurity/

Random Forestについて；
https://towardsdatascience.com/an-implementation-and-explanation-of-the-random-forest-in-python-77bf308a9b76
2つの日付のdiffを求める方法がPostgreSQLとMySQLで異なる

# TR; DL

## PostgreSQL

```sql
SELECT 'date(''2020-03-01'') - date(''2020-02-01'')' AS expr,
       date('2020-03-01') - date('2020-02-01') AS days;
```

| expr | days |
| :--- | :--- |
| date\('2020-03-01'\) - date\('2020-02-01'\) | 29 |

## MySQL

```sql
SELECT 'datediff(''2020-03-01'', ''2020-02-01'')' AS expr,
       datediff('2020-03-01', '2020-02-01') AS days
```

| expr | days |
| :--- | :--- |
| datediff\('2020-03-01', '2020-02-01'\) | 29 |


# ハマったこと

これまで2年超、業務でPostgreSQL (9.6 〜 11)を使ってきたのですが、最近これに加えてMySQL (5.7) も触るようになりました。

そこで、PostgreSQLのノリで日付計算を書いたところ、

```sql
-- MySQLで実行
SELECT 'date(''2020-02-29'') - date(''2020-02-01'')' AS expr,
       date('2020-02-29') - date('2020-02-01') AS days
UNION
SELECT 'date(''2020-03-01'') - date(''2020-02-01'')' AS expr,
       date('2020-03-01') - date('2020-02-01') AS days
UNION
SELECT 'date(''2021-03-01'') - date(''2020-02-01'')' AS expr,
       date('2021-03-01') - date('2020-02-01') AS days;
```

| expr | days |
| :--- | :--- |
| date\('2020-02-29'\) - date\('2020-02-01'\) | 28 |
| date\('2020-03-01'\) - date\('2020-02-01'\) | 100 |
| date\('2021-03-01'\) - date\('2020-02-01'\) | 10100 |

~~時空を超えたようです~~ 

同一月であれば問題ないようにも見えますが、月や年を跨ぐと、正しい結果になりません。
NestJSアプリケーションのビルドサイズをncc使って300MB減らした話


Dockerイメージサイズをできるだけ小さくする際に試行錯誤した結果、[ncc](https://github.com/zeit/ncc)を使ってイメージサイズを減らせたので備忘録

|ncc使う前|ncc使った後|結果|
|:--|:--|:--|
|599MB|245MB|354MB削減!|

[![Image from Gyazo](https://i.gyazo.com/35ea2acfd2a276f9d77530b354874c18.png)](https://gyazo.com/35ea2acfd2a276f9d77530b354874c18)


## ビルド手順

nccはTypeScriptをサポートしています。ですが、tsconfig.jsonの指定ができないため`tsconfig.app.json`のような複数の設定ファイルを保持している場合、うまく使用することができません。

そこで次の手順を踏みます。

例: `api`というアプリをビルド
1. nest-cliでwebpackモードでビルドする: `nest build api --webpack`
2. 1の成果物をnccで更にビルドする `ncc build dist/api.js -m -o dist/api`

するとアプリに必要なファイルをまとめて出力してくれます。 Dockerイメージにはこれを含めればいいだけ。

[![Image from Gyazo](https://t.gyazo.com/teams/unity/ed495f661b9f79a9e6f363f10c9f833d.png)](https://unity.gyazo.com/ed495f661b9f79a9e6f363f10c9f833d)

nccすごいですよ。webpackのやつを更にビルドできるの。

これにより、node_modulesが必要なくなり必要最低限のファイルのみがDockerイメージに含まれることになりました。
(node_modulesはもちろん`npm ci --production`でインストールしたもの)
[![Image from Gyazo](https://t.gyazo.com/teams/unity/2b050ebdaf3ea138dc0f63dab0868c52.png)](https://unity.gyazo.com/2b050ebdaf3ea138dc0f63dab0868c52)

### ... attempted to require "@nestjs/microservices" but could not be resolved, assuming external.

（↑正確なエラー文忘れて記録にも残ってないので前半ぼかしてます...）

nccでビルドしたファイルを実行すると、`@nestjs/microservices` のインポートがうまく解決できないエラーが発生しました。関連issueはこちら: https://github.com/zeit/ncc/issues/463

私の場合、@nestjs/microservicesはメインで使っておらず`@nestjs/terminus`が動的に読み込みを行っているようです。terminusはヘルスチェックに必要ですが、少し前に[サーバーレスに移行した](https://qiita.com/kyusyukeigo/items/ec798fc06c0c50fb0893)ため、重要度が低くなりました。なので`@nestjs/terminus`自体を削除しました。


### nccの成果物にtypescriptが含まれる

場合によって、typescriptがまるっと含まれる可能性があります。47.8MB、めちゃくちゃでかい。当たり前なんですが、typescriptフォルダ自体削除しても特に動作に支障はありませんでした。
[![Image from Gyazo](https://i.gyazo.com/825995ea5d2b9e100fbc46db7bb12026.png)](https://gyazo.com/825995ea5d2b9e100fbc46db7bb12026)

### え、300MBも削減されてんの？動くのこれ？という不安

[![Image from Gyazo](https://i.gyazo.com/35ea2acfd2a276f9d77530b354874c18.png)](https://gyazo.com/35ea2acfd2a276f9d77530b354874c18)

↑の結果を初めて見た時、かなり不安になりました。本当に最適化されただけ...?何か重要なファイル消えてない..?と言う感じで。
e2eテストをこのnccで行いましたが、ちゃんとテストは通っているので問題無しとしています（テスト書いててよかった）

あと、パッケージによっては古いバージョンのライブラリを参照してることがあります。バージョンの異なる同じパッケージが含まれているか調べましたが、ちゃんと含まれているようです（uuidのパッケージが4つも含まれてた...）。

### 更にpkgでシングルファイルにすれば完璧では...!?

alpine + pkg の組み合わせは動かなかった。static link周りでエラーが出る。
https://github.com/zeit/pkg-fetch/pull/72
そもそもpkgはサーバーレス用途では使わないでってREADMEに書いてあるし使うのは辞めた。
https://github.com/zeit/pkg/blob/master/README.md
Flexbox プロパティ まとめ

Flexboxって様々なことができるのに全て覚えている人って少ないのではないでしょうか？
そこでFlexboxのプロパティをまとめてみました。

#Flexboxの使い方
まずはFlexboxの使い方から
よく使う横並びの方法

```html:flexbox.html
<div class="container">
  <div class="item">子要素 1</div>
  <div class="item">子要素 2</div>
  <div class="item">子要素 3</div>
</div>
```
親要素にあたるcontainerにdisplya: flexbox;を指定してあげるだけです。

```css:flexbox.css
.container {
  display: flex;
}
```
これで子要素が横並びになるはずです。
<img width="750" alt="スクリーンショット 2020-03-19 11.27.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536289/74d962cd-9b0c-9ff1-b48b-8ec9f79f94f9.png">
#Flexboxのプロパティ一覧

Flexboxには親要素にかけれるものと子要素にかけれるものの２種類あります。
まずは親要素にかけれるプロパティから。

##親要素に指定するプロパティ 

| プロパティ          |              効果 |              使える値 |
|:-----------------|:------------------|:------------------|
| flex-direction   | 子要素の並ぶ向きを指定することができる | <ul><li>row（初期値） : 子要素を左から右に配置</li><li>row-reverse : 子要素を右から左に配置</li><li>column : 子要素を上から下に配置</li><li>column-reverse : 子要素を下から上に配置</li></ul> |
| flex-wrap        | 子要素の折り返しを指定することができる |  <ul><li>nowrap（初期値） : 子要素を折り返しせず、一行に並べる</li><li>wrap : 子要素を折り返し、複数行に上から下へ並べる</li><li>wrap-reverse : 子要素を折り返し、複数行に下から上へ並べる</li></ul> |
| flex-flow        | flex-directionと、flex-wrapをまとめて指定することができる(ショートハンド・プロパティ ) | - |
| justify-content  | 横並びの位置を指定することができる | <ul><li>flex-start（初期値） : 行の開始位置から配置。左揃え。</li><li>flex-end : 行末から配置。右揃え。</li><li>center : 中央揃え</li><li>space-between : 最初と最後の子要素を両端に配置し、残りの要素は均等に間隔をあけて配置</li><li>space-around : 両端の子要素も含め、均等に間隔をあけて配置</li></ul> |
| align-items      | 縦並びの位置を指定することができる | <ul><li>stretch（初期値） : 親要素の高さ、またはコンテンツの一番多い子要素の高さに合わせて広げて配置</li><li>flex-start : 親要素の開始位置から配置。上揃え。</li><li>flex-end : 親要素の終点から配置。下揃え。</li><li>center : 中央揃え</li><li>baseline : ベースラインで揃える</li></ul> |
| align-content    | 複数行になった時に縦並びの位置を指定することができる | <ul><li>stretch（初期値） : 親要素の高さに合わせて広げて配置</li><li>flex-start : 親要素の開始位置から配置。上揃え。</li><li>flex-end : 親要素の終点から配置。下揃え。</li><li>center : 中央揃え</li><li>space-between : 最初と最後の子要素を上下の端に配置し、残りの要素は均等に間隔をあけて配置</li><li>space-around : 上下端にある子要素も含め、均等に間隔をあけて配置</li></ul> |


##子要素に指定するプロパティ 

| プロパティ          |              効果 |              使える値 |
|:-----------------|:------------------|:------------------|
| order            | 並び順を指定をすることができる | 初期値は0。<br>マイナス値を含む数値のみ指定することができる |
| flex-grow        | 子要素が画面幅に満たない場合に伸びる比率を指定することができる | 数値のみ指定することができる。<br>初期値は0。<br>マイナス値は無効 |
| flex-shrink      | 子要素が画面幅より小さい場合に縮む比率を指定することができる | 数値のみ指定することができる。<br>初期値は1。<br>マイナス値は無効 |
| flex-basis       | 子要素の基準幅を指定することができる | パーセントやピクセル値で指定することができる<br>初期値はautoでautoと指定した場合は子要素のコンテンツのサイズが適応される。 |
| flex             | flex-growと、flex-shrink、flex-basisをまとめて指定できる(ショートハンド・プロパティ) | - |
| align-self       | 子要素の縦方向を指定することができる | <ul><li>auto（初期値） : 親要素の align-items の値を継承</li><li>stretch : 親要素の高さ、またはコンテンツの一番多い子要素の高さに合わせて広げて配置</li><li>flex-start : 親要素の開始位置から配置。上揃え</li><li>flex-end : 親要素の終点から配置。下揃え。</li><li>center : 中央揃え</li><li>baseline : ベースラインで揃える</li></ul> |

##共に働くWebエンジニアを募集しています!
不動産SHOPナカジツでは自社サービスを作っていく仲間を募集しています。
詳しくは[Wantedly](https://www.wantedly.com/projects/134741)からお問い合わせください。
PMP試験に合格しました 一問一答

# PMP試験に合格しました 一問一答

2020年1月にPMP試験に合格しました。
記憶が新しいうちに、一問一答でPMP試験をまとめたいと思います。

## Q. あなたのキャリアの背景は?
ソフトウェアエンジニアです。
プラグラマー、プロジェクトマネージャの経験が5年づつあります。

## Q. PMPって?
PMI（米国プロジェクトマネジメント協会)が発行しているベンダー資格です。
PMBOKにもとづいて実施されます。

## Q. なんで取得しようとおもったの?
現在PMもどきをやっておりますが
社内にいる他PMは皆独自の方法論でマネージメントしている場合が多く、炎上案件が後を耐えません。
そのため、私だけでもPMとしての一般的な知識を身に着けようと受験を決意しました。

## Q. IPAの試験と比べてPMP試験って難しい?
IPAの資格は応用情報技術者/ネットワークスペシャリスト等複数所有していますが、
試験自体の難易度も試験に至るプロセスもPMP試験のが難しく感じました。

## Q. PMP試験の何が難しい?
試験に至るプロセスが面倒くさいです。
受験資格(高校卒業もしくは相当する資格を持っている人は、60か月のプロジェクトマネジメント経験、7,500時間に及ぶプロジェクト指揮・監督実務経験が必須)と認定講座を35時間受講の上、
PMIの公式サイトから申し込みを行い、初めて受験出来ます。(途中で監査に引っかかる人もいます)

試験もシチュエーション問題と呼ばれる架空の状況に基づいた問題が多数出題されるため
PMBOKの丸暗記ではなく、「なぜ?」を問いながら読み込む必要があります。

そして肝心のPMBOKを読むのがとても辛いです。
PMBOKはソフトウェアだけでなく、
建設やハードウェアといった様々なプロジェクトからナレッジを集め一つにまとめたものになります。
そして、「理想のプロジェクト、プロジェクトマネージャ」を前提に書かれています。
そのため、ソフトウェアエンジニアとしてPMBOKの記載に「？」が付くことが多く、
理想と現実の間でもやもやしておりました。
あくまでの「理想」なので、そこをキッチリと割り切る勇気が必要です。

## Q. PMP試験のための勉強は英語教材を使用したほうが良いの?
私は英語の勉強も兼ねて、日本語/英語教材を半々使いながら勉強しました。(教材は後でまとめます)

試験を受かるためであれば日本語教材で十分かと思いますが、PMP試験の日本語は1,2問助詞が変な日本語が混じっているため、正確な問題を確認するために多少英語を読めたほうがようです。

## Q. 試験勉強の時間は?
3ヶ月×3時間/日=180時間かかりました。

## Q. 試験勉強で使用した講義/教材とその費用は?
35時間講義はUdemyで提供されている”PMP Exam Prep Seminar - Earn 35 PDUs by completing the entire PMP course”を使用しました。
英語講義ですが1,500円ととてもリーズナブルです。
講義終了時にスキンヘッドのおじさんがいつも励ましてくれます。
Udemyは倍速再生が可能のため、1.5倍速で受講し35時間よりも短く受講完了できました。

テキストは PMPパーフェクトマスター PMBOK第6版対応( https://www.amazon.co.jp/dp/4828205977/ref=cm_sw_r_tw_dp_U_x_pCUCEbTBY18QS )を使用しました。
4,180円となります。

合計で5,700円ほどです。

## Q. 試験にかかる費用の合計は?
上記の5,700円に加え、PMI登録日とPMP受験料が67,000円ほどかかります。
合計は72,700円となります。
テキストは買う必要はないため、ミニマムで68,500円で取得できます。

## Q. PMP試験はどうだった?
1発で合格しましたが、正直手応えはありませんでした。

テストシステムには自信のない問題にフラグを付ける機能があるのですが、
試験終了時には100問ほどフラグが付いていました。
200問の6割・120問正解で合格と言われているので、アウトですね。

なぜ100問もフラグが付いたかというと
"シチュエーション問題で2つまで絞り込めたが、残りの2つのどちらが正しいか"を悩む問題が多かったからです。
これがPMBOK丸暗記ではだめな理由です。
PMPイズムと呼ばれる独特の雰囲気を感じ取る必要があります。

結果としては、140問くらい正解しているようでした。

## Q. 取得してよかった?
まだ取得して間もないので利益は何ら感じません。

PMBOKを組織内の共通の理念・言語にするにも、まず組織改革が必要です。
しかし、私にはその権限がないため、あくまでも自己満足で終わってしまっています。。。

## その他
質問があれば受け付けますので、コメントでお願いいたします。
Windows + Vagrant で CakePHP

かなり昔の作業メモです。

# Ubuntu環境

WindowsのコマンドはPowerShellを使った
適当にディレクトリを作成してそこに移動
boxはすでに持っていたので、initから

```
> vagrant init ubuntu/xenial64
```

`Vagrantfile` ができる

```
> Vagrant up
```

Ubuntu起動

# 各種パッケージ

Apache
本体とPHP用モジュール

```bash
$ apt-get install -y apache2
$ apt-get install -y libapache2-mod-php7.0
```

PHP
本体とCakeで必要なモジュール

```bash
$ apt-get install -y php7.0 php7.0-intl php7.0-mbstring php7.0-xml
```

Zip
無ければ入れる、Cakeの解凍に必要

```bash
$ apt-get install -y zip unzip
```

Composer

```bash
$ curl -s https://getcomposer.org/installer | php
```

CakePHP

```bash
$ mkdir ../../vagrant/cakephp
$ php composer.phar create-project --prefer-dist cakephp/app ../../vagrant/cakephp
```

# Apache設定

AllowOverride を None から All に変更
`/etc/apache2/apache2.conf`

```
<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
</Directory>
```

mod_rewriteを有効化

```bash
$ sudo a2enmod rewrite
```

Apacheをserviceコマンドで起動

```bash
$ sudo service apache2 start
```

なおVagrantの共有フォルダ設定によって、Apache2のルートディレクトリである `/var/www/html` の中にCakeディレクトリを配置してある

# 動作確認

ホストで `http://localhost:8080/cakephp/` へアクセスしてみて、Cakeの画面が表示されればOK
Illustrator で作った DXF を Fusion360 読み込む方法

Illustrator などで作ったDXFは、サイズ単位が入っていない事があります。
サイズ単位をフリーのCAD を使って設定する方法をまとめてみました。

# [LibreCAD](https://librecad.org/)
フリーで使い勝手のいい LibreCAD をインストールして利用するので インストールしてみる。
`HomeBrew` でもインストールできるようなので試してみましょう。
 
```
brew update
brew cask install librecad
```

# [LibreCAD](https://librecad.org/) 初期設定
`/Applications/LibreCAD.app` にインストールされるので、起動してみる。
`GUI Language` だけ `japanese 日本語` へ変更
<img width="703" alt="スクリーンショット 2020-03-18 15.25.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100147/50af9cdb-a037-3b5d-61b7-8bfcc9919963.png">

# DXF を読み込んで設定変更
原点 と サイズ単位を設定します。 `ファイル` → `開く` で DXF を開く。  

1. 図面の単位を変更する `Option` → `図面の設定` を選ぶ。 
<img width="404" alt="スクリーンショット 2020-03-18 15.44.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100147/56c1276d-97ba-268a-7cbb-026128e6aef0.png">  

2. `単位・書式` タブを選んで 図面で用いる単位を `ミリメートル mm` に変更してOKを押す
<img width="428" alt="スクリーンショット 2020-03-18 15.50.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100147/698c426f-9e08-e1f9-8c80-5018cd582415.png">

# DXF 保存形式を R14 にする
`ファイル` → `名前をつけて保存` で 形式を DXF R14(*.dxf) を指定して保存する。

<img width="553" alt="スクリーンショット 2020-03-19 12.21.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100147/d600739f-9ed4-36a9-e1a2-caab9783e385.png">


# Fusion360 に取り込む
`ツールバー` → `挿入` → `DXFを挿入` を選択する 
<img width="620" alt="スクリーンショット 2020-03-19 12.31.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100147/e9b6f95c-ba21-8c31-5d43-755bd3883971.png">

`平面` を指定して、DXFファイルを読み込む。 単位が `ミリメートル` になっている事を確認して OK を押す。
<img width="269" alt="スクリーンショット 2020-03-19 12.32.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100147/76473943-8163-692e-d1f7-e59dc89cc2b4.png">

# まとめ
DXF に 単位が設定してあれば、 Fusion360 での挿入は簡単にできます。
[Scala] typesafe config で取得したデータを扱いやすくする

typesafe config については [こちら](https://qiita.com/4245Ryomt/items/d8368ec8b60fb7e44c04) の方が超わかりやすく書いていただいているのでこちらを参照

で、 typesafe config で取得したファイルは javaの型で返ってくるのでかなり扱いづらいです

以下のデータを取得して、sampleListをループで回したいとします

```application.cong
sampleList = [
  {
    id = 1
    name = "mike"
    sex = 1
    age = 24
  },
  {
    id = 2
    name = "neko"
    sex = 0
    age = 31
  },
  {
    ...
]
```

そのまま取得しただけではmapが使えないので、 `toArray` をして上げる必要があります

```scala
    config.getConfigList("sampleList").toArray.map(
      x => println(x)
    )

### output
Config(SimpleConfigObject({"id":1,"name":"mike","sex":1,"age":24}))
Config(SimpleConfigObject({"id":2,"name":"neko","sex":0,"age":31}))
```

ここから中身を取得したいのですが、うまくいきません

```scala
    config.getConfigList("sampleList").toArray.map(
      x => println(x.getInt("Id"))
    )

### エラーメッセージ
cannot resolve symble getInt
```

Scalaで扱いやすい型に変換するために、 `asScala` を使います

```scala
import scala.collection.JavaConverters._

    config.getConfigList("sampleList").asScala.map(
      x => println(x)
    )

### output
Config(SimpleConfigObject({"id":1,"name":"mike","sex":1,"age":24}))
Config(SimpleConfigObject({"id":2,"name":"neko","sex":0,"age":31}))
```

出力される値は同じなのですが、 get~~が使えるようになるため簡単に中身が取得できます。

```scala
    config.getConfigList("sampleList").asScala.map(
      x => println(
          x.getInt("id"),
          x.getString("name"),
          x.getInt("sex"),
          x.getInt("age"),
      )
    )

### output
(1,"mike",1,24)
(2,"neko",0,31)
```

configから配列などを受け取る場合はこちらがよさそうです。
Rails5 slim 掲示板やトピック等でのtextの表示形式

#掲示板を実装した時に改行やスペース、URLの反映がちょっと手間取ったのでメモ
ユーザーがフォームで入力したtextを取得して掲示板に表示させる時何も設定していないと改行等全く反映されない。
コピペしたURLも文字列として扱われてリンク表示にならないです。あとスペースも反映されない。

`-require 'uri'
   - @board.comments.each do |comment|
    | >
    = simple_format(text_url_to_link(h(comment.content.gsub(/ /, '&nbsp;').html_safe)), {}, sanitize: false)`

上記の記載で私の場合は解決できました。

`require 'uri`
と
`simple_format(text_url_to_link(h(comment.content.gsub(/ /, '&nbsp;').html_safe)), {}, sanitize: false)`

がキモ。それぞれの意味についてはググれば出てきます。
この記載で「改行、半角スペース、全角スペース、URLリンク」が全て反映されるようになりました。
MacにKubernetes操作環境を構築

# はじめに
自分用のメモです。
ローカルのMacからEKSに繋げられるようにしたかったので、kubectlとeksctlの導入手順をメモとして記載します。

# 実行環境
### ローカル
- macOS Catalina(10.15.3)
- zhs + prezto
- aws-cli/1.18.24 Python/3.8.2 Darwin/19.3.0 botocore/1.15.24
- Homebrew 2.2.10

### EKS
- 1.14


# kubectlインストール
書いて気づきました。。eksctlをインストールすれば、kubectlが自動的に入ることを。。。
eksctlを入れる方はここはスキップでOKです。
### kubectlインストール
[ここ](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/install-kubectl.html)の手順に従います。
バイナリはK8s公式のものでもいいようです。
落としたバイナリは`~/$HOME/.local/bin`にインストールしたい派なのでAWSの手順とは少し変えます。

```shell
$ curl -o kubectl https://amazon-eks.s3-us-west-2.amazonaws.com/1.14.6/2019-08-22/bin/darwin/amd64/kubectl
$ chmod +x ./kubectl
$ mkdir -p $HOME/.local/bin && cp ./kubectl $HOME/.local/bin/kubectl
```

(オプション).zshrcにまだ`~/$HOME/.local/bin`へのパスが通ってない場合は以下を実行

```shell
$ echo 'export PATH=$PATH:$HOME/.local/bin' >> ~/.zshrc
$ zsh -l
```

ちゃんと使えるか確認します。大丈夫ですね。

```shell
$ kubectl version --short --client

Client Version: v1.14.7-eks-1861c5
```
### kubeconfigの作成
kubeconfigを作成します。`region-code`と`cluster_name`は自分の環境にあわせます。

```shell
aws eks --region region-code update-kubeconfig --name cluster_name
```

インストールできたか確認します。おっけーですね。

```shell
kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.100.0.1   <none>        443/TCP   44h
```

### kubectlコマンドの補完
[K8s公式](https://kubernetes.io/ja/docs/reference/kubectl/cheatsheet/)に載ってました。

```shell
echo "if [ $commands[kubectl] ]; then source <(kubectl completion zsh); fi" >> ~/.zshrc
```

K8s初心者の私にはすごい便利です。

```shell
$ kubectl get n
namespaces                         networkpolicies.networking.k8s.io                                   
networkpolicies.extensions         nodes   
```

# eksctlのインストール
### eksctlのインストール
[ここ](https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/getting-started-eksctl.html)に従ってインストールしていきます。

Weaveworks Homebrew tap をインストールします。

```shell
$ brew tap weaveworks/tap
```

eksctl をインストールします。

```shell
$ brew install weaveworks/tap/eksctl
```

インストールできたか確認します。おっけーですね。

```shell
$ eksctl version
0.15.0
```

### インストール後の設定
[kubectlをインストールした際に行ったこと](#kubeconfigの作成)をやればおっけーです。
[kubectlコマンドの補完](#kubectlコマンドの補完)も必要に応じてどうぞ。

# まとめ
最初にeksctlのインストール手順調べればよかった。。。みなさんはお気をつけを！
Rails5 slim bootstrap4　placeholderの反映

#Rais5でBootstrap4を使用した際にplaceholderが反映されなかった時のメモ

#slim使用しているとbootstrapの記載で迷うことが多くて、、

今回はplaceholderを反映させる記載方法メモ

`=f.text_field :term, class: 'form-control', :placeholder => '※月※日〜※月※日、平日※時〜※時の間'`

私はこの記載で反映されました。
バージョンによって違ったり、slimでの記載方法もあるのでちょっとたどり着くのに時間がかかりました。。
【メモ】Raspberry Pi でも Rust と Cargo

[個人用のホームページ](https://tkyonezu.com/)を作成しました。今後は、そちらの方に整理していきたいと思いますので、よろしくお願いします。

# 1. Rust のインストール

```
$ curl https://sh.rustup.rs -sSf | sh
```

`Current installation options:` では、1 を選択します。

```
Current installation options:


   default host triple: armv7-unknown-linux-gnueabihf
     default toolchain: stable
               profile: default
  modify PATH variable: yes

1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
>1
```

`.profile`にPATHが追加されるので、ログインし直します。

``` .profile
export PATH="$HOME/.cargo/bin:$PATH"
```

再度ログインすると `rustc` と `cargo` を実行できます。

```
$ rustc --version
rustc 1.41.1 (f3e1a954d 2020-02-24)
$ cargo --version
cargo 1.41.0 (626f0f40e 2019-12-03)
```

# 2. libssl-dev、pkg-config のインストール

Raspbian では （JetsonNano の Ubuntu 18.04 でも同じでした）、libssl-dev がインストールされていないようなので追加しておきます。

```
$ sudo apt install -y libssl-dev
```

`libssl-dev` がインストールされていない場合、例えば `cargo install cargo-edit` を実行すると `openssl-sys v0.9.54` のコンパイルでエラーが発生します。

```
error: failed to run custom build command for `openssl-sys v0.9.54`

Caused by:
  process didn't exit successfully: `/tmp/cargo-installbbspY5/release/build/openssl-sys-fdd93143b81b5895/build-script-main` (exit code: 101)
```

Ubuntu の場合 `pkg-config` がインストールされていないようなので追加しておきます。

```
$ sudo apt install -y pkg-config
``` 



# 3. cargo-edit のインストール

```
$ cargo install cargo-edit
```

cargo add などのコマンドが使えるようになります。

# 4. cargo make のインストール

[cargo-make](https://github.com/sagiegurari/cargo-make) をクローンしてインストールします。

```
$ git clone https://github.com/sagiegurari/cargo-make.git
$ cd cargo-make
$ cargo install --force cargo-make
```

# 5. rust を最新版に更新

```
$ rustup update
```
Montecarlo Applications in systems engineering 

```{r}

#Montecarlo Applications in systems engineering 

#p.99 

library(dplyr)

func=function(x){

return(exp(-x^2)^2)

}

A=0;B=10

N=100

t=seq(A,B,abs(A-B)/N)

gamma=c()

for(i in 1:(length(t)-1)){

a=t[i];H=abs(A-B)/N;n=100000

Y=(H/3)*(1/(n-1))*(func(a)+func(a+H));

for(j in 1:(n-2)){
  coefficient=ifelse(j-floor(j/2)*2==0,4,2)
  Y=Y+((H*coefficient)/(3*(n-1)))*func(a+(j*H)/(n-1))

}

gamma=c(gamma,(t[i+1]-t[i])*Y)

}

lam=sum(sqrt(gamma))

p=sqrt(gamma)/lam

f=c()

for(j in 1:(length(p)-1)){

f=c(f,p[j+1]/(t[j+1]-t[j]))

}

plot(exp(-t^2))




```
【HTML,CSS,JQuery】ブログ機能などの一覧でリンク先や詳細ページがないときにアニメーションを止める。

よく使うので忘備録として・・

##パターン１
一番シンプルなやつ 
＃は環境に応じて使い分ける。

```HTML
<ul class="blog-list">
  <li><a href="pathToTheBlog">ブログ始めました。</a></li>
  <li><a href="pathToTheBlog">詳細ページあります</a></li>
  <li><a href="#">詳細ページないです。</a></li>
</ul>
```

```SCSS
.blog-list {
  >li >a[href="#"] {
    pointer-events: none;
  }
}
```

##パターン２
一番ありがちなやつ

```HTML
<ul class="blog-list">
  <li>
    <a href="pathToTheBlog"><!-- 透明なアンカータグを要素全体の上に配置 --></a>
    <div class="img-wrap" style="background: url(pathToDefaultImg) no-repeat center/cover">
      <img src="pathToImg" alt="ユーザー投稿した画像です。">
    </div>
    <div class="txt-wrap">
      <p>テキスト入ります。</p>
    </div>
  </li>
  <li>
    <a href="#"><!--  --></a>
    <div class="img-wrap" style="background: url(pathToDefaultImg) no-repeat center/cover">
      <img src="pathToImg" alt="ユーザー投稿した画像です。">
    </div>
    <div class="txt-wrap">
      <p>テキスト入ります。</p>
    </div>
  </li>
</ul>
```

```javascript
$(function() {
  $('.blog-list > li').each(function(){
    if ($(this).children('a').attr('href') == '#') {
      $(this).css('pointer-events', 'none');
    }
  });
});
```

```SCSS
.news-list {
  display: flex;
  justify-content: space-around;
  width: calc(100% + 15px);
  >li {
    width: calc(50% - 15px);
    margin-right: 15px;
    position: relative;

    >a {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      z-index: 1;
    }

    .img-wrap {
      overflow: hidden;
      height: 200px;
      width: 100%;

       >img {
         height: 100%;
         width: 100%;
         object-fit: cover;
         transition: .3s transform;
       }
     }

     .txt-wrap {
       font-size: 16px
     }

     &:hover {
        .img-wrap {
          transform: scale(1.05);
        }
        .txt-wrap p {
          text-decoration: underline;
        }
     }
  }
}
```