OmniAICreator/Qiita-1.07M huggingface dataset:
python を用いた主成分分析(PCA) のかんたんスクラッチ

#Ice Break

[前回の記事](https://qiita.com/ajioka/items/efb74db0ff51e7f7da48)では主成分分析(PCA)を題材に線形代数の総復習を行いました。

本稿ではpythonを用いたPCAの実装例について書きます。

sklearn使うとつまらないのでnumpy縛りで実装しました。

次回記事では今回作成したモジュールを用いて次元削減が回帰分析に対して与える影響について考察します。

#データセット準備
sklearnに付属しているBoston House Prices datasetを使用します。
まずhouse price 以外のデータを説明変数 X として使用するためにデータフレームからアレイとして取り出します。
また作法として X をカラムに沿って正規化しておきます。

```python
from sklearn.datasets import load_boston
from sklearn.decomposition import PCA
import pandas as pd
import numpy as np

def create_X():
    boston = load_boston()
    data = pd.DataFrame(boston.data, columns = boston.feature_names)
    data = data.values
    X = np.delete(data,12,1)
    mean = np.mean(X,axis=0)
    std  = np.std(X,axis=0) 
    X = (X-mean)/std
    return X

```
#PCA
前回の記事で述べた通り、PCAでは$X^{T}X$に対する固有ベクトルを探索します。

そのためまず始めに$X^{T}X$を計算します。(1) 

つぎにnumpy.linali.eigを用いて固有ベクトルを計算します。(2) 

$D$は固有ベクトルを対応する固有値が大きい順に並べたものです。任意の次元に圧縮するためn_componensを変数としています。また以下で数式と同様に計算を進めるために一度転置を挟んでいますが、実装上は必要ないです。(3)

最後に$D^{T}X$を計算することで次元を削減することが出来ます。(4)

```python

def PCA_Sc(X,n_components):
    columns = X.shape[1]
    #　1 calucurate X_TX
    X_TrX = np.dot(X.T,X)
    # 2 clucurate eigenvalue & Eigenvector
    w,v = np.linalg.eig(X_TrX)
    # 3 create D
    D_list = [v[:,i] for i in range(n_components)]
    D_array = np.array(D_list)
    D_reshape = np.reshape(D_array,(n_components,columns))
    D = D_reshape.T
    # 4 colucurate D_TX
    X_transform = np.dot(D.T,X.T)
    return X_transform
```
#sklearn との比較
sklearnで生成した主成分$D$との比較を行いました。結果は以下になります。
![図1.png](https://qiita-image-store.s3.amazonaws.com/0/335420/6be686d2-588c-7ae3-9029-5b9d28207f41.png)
この図から分かることはsklearnでは第１主成分の最初の値が正になるように符号を反転させる機能が内蔵されている事です。（このことは他の方も報告していたと思います。）

スクラッチで書くとこのような発見があって楽しいですね。
定義参照したほうが早いですが…
プログラミング学習記録45〜わかばちゃんで学ぶGitがわかりやすい〜

##今日やったこと
- ブログにProgate Gitのコマンドまとめを書く
- ProgateのGitをリセット復習
- わかばちゃんで学ぶGit使い方入門を読む
- Railsで作ったアプリにパスワード確認機能をつける

今日は作業時間の割に多くのことができたと思います。

久しぶりにブログも書けました。

書かないと書く力が衰えるというか、書きたいことがあるのに文章が思いつかなくなってしまうので、最低でも週１くらいは更新しないとダメですね。

Progateで習った内容をざっとまとめただけの記事ではありますが、後で復習するには十分の内容だと思います。

<br>
「わかばちゃんで学ぶGit使い方入門」もとてもわかりやすくてよかったです。

この本ではSource Treeというソフトを使って、Gitを漫画でわかりやすく解説してくれます。

ターミナルでの操作の解説はないのですが、基本的な概念は変わらないので、Gitの基礎的な部分はこの本で学べると思います。

あと、ささやかですが、この前作ったRailsのアプリに機能を追加しました。

新規登録の時に同じパスワードをもう一度入力してもらって、確認するアレです。

意外と簡単にできてよかったです。

こちらの記事を参考に実装しました↓

[再確認用のパスワードについて](https://teratail.com/questions/117924)

詳しくは後日、ブログに書こうと思います。

メールアドレスのバリデーションもついでに追加したのですが、エラー文が英語のままなので次はそこを修正できたらいいなと思います。

ということで、明日からも引き続きプログラミング学習頑張ります。

おわり
Solidity コントラクトのロジック更新、隠蔽

#はじめに
ブロックチェーンはデータが公開されますが、一度公開した後に、コントラクトのロジックを更新または隠蔽したいときがあります。どうすればできるのかを調査しました。

#ロジックを更新、隠蔽する方法

ロジックを更新、隠蔽するために、3つのファイルがあります。

|sol|内容|
|:--|:--|
|CatInterface.sol|ロジックのインターフェースを記載します。|
|Cat.sol|ロジックの実装を記載します。|
|CatGenerate.sol|インスタンスを設定、ロジックを使います。|

```CatInterface.sol
pragma solidity ^0.5.0;

 contract CatInterface {
    function add(uint256 _x, uint256 _y) public returns(uint256, uint256);
}
```

`CatInterface.sol`では、ロジックのインターフェース`add(uint256 _x, uint256 _y) public returns(uint256, uint256)`を記載しています。


```Cat.sol
pragma solidity ^0.5.0;

import "./CatInterface.sol";

 contract Cat is CatInterface {
    uint256 public x;
    uint256 public y;
    function add(uint256 _x, uint256 _y) public returns(uint256, uint256) {
        x = _x + 1;
        y = _y + 1;
        return (x, y);
    }
}

```

`Cat.sol`では、`add(uint256 _x, uint256 _y) public returns(uint256, uint256)`の実装を記載しています。

```CatGenerate.sol
pragma solidity ^0.5.0;

import "./CatInterface.sol";

 contract CatGenerate {
    uint256 public v;
    uint256 public w;
    CatInterface catInstance;

    function setCatAddress(address _address) public {
        catInstance = CatInterface(_address);
    }
    
    function test(uint256 _x, uint256 _y) public returns(uint256, uint256) {
        (v, w) = catInstance.add(_x, _y);
    }

}
```

`CatGenerate.sol`では、`setCatAddress(address _address)`に、`Cat.sol`をdeployしたアドレスを入れて実行すると、`catInstance`を設定できます。
その後に、`add(uint256 _x, uint256 _y) public returns(uint256, uint256)`を実行すると、`Cat.sol`のロジックが実行されます。

`setCatAddress(address _address)`をすることで、`add(uint256 _x, uint256 _y) public returns(uint256, uint256)`のロジックを更新、隠蔽することができます。

#おわりに
アドレスを指定することで、ロジックを変更できるようにしました。

ただ、Storageも更新に対応できるようにしたいという方もいるかと思います。
その場合は、proxy contractという方式を使うことでできます。
また別途、記載したいと思います。
画像をnumpy形式で保存する

# はじめに

画像を学習用データとテストデータに分けた時の手法のメモ

# 使用したモジュール

```Python
#画像を取得するため
from PIL import Image
#ファイルのパスなどを扱うので　
import os,glob
#numpy形式でファイルを保存する
import numpy as np
#データ分割用のためのscikit-learn
from sklearn import model_selection
```

# ラベルと画像サイズ

今回はサルとイノシシとカラスの画像を用意した。

```python
#配列を用意
classes = ["monkey","boar","crow"]
#0をサル、1をイノシシ、2をカラスとする
NumClasses = len(classes)
#画像の大きさを50*50とする
ImageSize = 50
```

# データの変換

```python
#変数の代入用の配列を宣言
X = []
Y = []
#0のmonkey,1のboar,3のcrowをindexに代入
#enumerate()を使うことでインデックス番号、要素の順番で取得する
for index, ClassLabel in enumerate(classes):
    PhotosDir = "./"+ClassLabel
    #写真をfilesに代入
    files = glob.glob(PhotosDir+"/*.jpg")
    for i, file in enumerate(files):
        #写真を開く
        image = Image.open(file)
        #RGBに変換
        image = image.convert("RGB")
        #大きさの統一(50*50)
        image = image.resize((ImageSize,ImageSize))
        #画像を配列に変換
        data = np.asarray(image)
        X.append(data)
        Y.append(index)
```

# データの保存

他のプログラムで画像データを使いまわすときのためにデータを numpy 形式で保存します。

```python
#numpy配列に変換
X = np.array(X)
Y = np.array(Y)
#テストデータと訓練用データに分割
X_train,X_test,Y_train,Y_test = model_selection.train_test_split(X,Y)
#一つの変数に保存
xy = (X_train,X_test,Y_train,Y_test)
#numpy形式で保存
np.save("./animal.npy",xy)
```

# 学習データを増やす

取得した画像を回転や左右反転することで学習データとなる画像を増やすことができます。

```python
# 0のmonkey,1のboar,3のcrowをindexに代入
for index, ClassLabel in enumerate(classes):
    PhotosDir = "./"+ClassLabel
    # 写真をfilesに代入
    files = glob.glob(PhotosDir+"/*.jpg")
    for i, file in enumerate(files):
        # 写真を開く
        image = Image.open(file)
        # RGBに変換
        image = image.convert("RGB")
        # 大きさの統一
        image = image.resize((ImageSize, ImageSize))
        # 画像を配列に変換
        data = np.asarray(image)
        #num_testdataは100とします
        if i < num_testdata:
            X_test.append(data)
            Y_test.append(index)
        else:
        #-20度から20度まで5度ずつ回転させる
            for angle in range(-20, 20, 5):
                # 回転
                img_r = image.rotate(angle)
                data = np.asarray(img_r)
                X_train.append(data)
                Y_train.append(index)
                # 左右反転
                img_trans = image.transpose(Image.FLIP_LEFT_RIGHT)
                data = np.asarray(img_trans)
                X_train.append(data)
                Y_train.append(index)

```
プロパティに関する備忘録

# 概要
c#の自分が今まであまり使ってこなかった機能を調べてまとめていく。
記事の内容に誤りがあった場合指摘してもらえると嬉しい。
今回はプロパティについて
# 本題
基本的な使い方

```C#:test1.cs
using System;

    class Program
    {
        private int num;
        public int Num { get { return num; } set { num = value; } }
        //setのnumにはvalue以外に定数なども代入出来る。また、複数行の処理もget、set内に書ける

        public int mNum { get { return num; } }
        //public int mNum => num;
        //このmNumは読み取り専用。上二行は同じ働きをする。

        //public int Num { get; set; }
        //自動実装プロパティ。上と同じ働きをするがgetは省略出来ない。そしてsetに色々処理を書くことは無理。
        //自動実装プロパティはとりあえずプロパティを使うことが決まっている場合に書いておくと良いらしい。後々コードを書き換えるのが楽になるとか                                    

        static void Main(string[] args)
        {
            var pro = new Program();
            pro.Num = 456;
            Console.WriteLine(pro.Num);//あくまでNumはフィールドではないので上2行で参照が必要
        }
    }
```

キーワードを付加すればプロパティを継承して置き換えたり動作を変更することが出来る。

```C#:test2.cs
using System;

    abstract class ProgramBase
    {
        public abstract int Num { get; set; }
    }

    class ProgramOverride : ProgramBase//中身を何も書かないとエラーを吐く。下に書くオーバーライドを用いて実装する必要があるようだ。
    {
        private int num;
        public override int Num { get { return num; } set { num = value; } }
    }

    class Program1
    {
        static void Main(string[] args)
        {
            ProgramBase pb = new ProgramOverride();
            pb.Num = 456;
            Console.WriteLine(pb.Num);
        }
    }
```
以上。クラス継承などに関しては次回以降にまとめようと思う。
OpenSSL ECDSA署名検証の仕組みおさらい

#はじめに
ECDSAでの自己認証局を作成したので、サーバー証明書、クライアント証明書を作成できるが、原理を学ぶため、まず基本の証明書の検証動作を確認する。


#環境
前回作成した環境にて検証を実施
[OpenSSL ECDSAでの自己認証局作成](https://qiita.com/kmitsu76/items/ac2db516ba46c50f43d6)

#検証内容
自己認証局の中間CAにて署名したメッセージを検証していく。
ルートCA証明書までの証明書チェーン全体を検証する

#メッセージの作成と中間CAでの署名
中間CAの秘密鍵を使って署名を行う。

```
echo "123456" > test.txt
openssl dgst -sha256 -sign /etc/pki/AWS/private/icacert.key test.txt > signature.dat
```

#中間CAの証明書を分析と公開鍵の抜き出し
```
openssl x509 -in /etc/pki/AWS/icacert.pem -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 2 (0x2)
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=JP, ST=Tokyo, L=<任意>, O=<任意>, OU=<任意>, CN=<ルートCAのCN>
        Validity
            Not Before: ... 2019 GMT
            Not After : ... 2029 GMT
        Subject: C=JP, ST=Tokyo, O=<任意>, CN=<中間認証局のCN>
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (256 bit)
                pub:
                    04:63:....




                ASN1 OID: prime256v1
                NIST CURVE: P-256
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                .....
            X509v3 Authority Key Identifier:
                .....

            X509v3 Basic Constraints:
                CA:TRUE, pathlen:0
            X509v3 Key Usage:
                Digital Signature, Certificate Sign, CRL Sign
    Signature Algorithm: ecdsa-with-SHA256
         30:45:02:20:......

         02:21:......

-----BEGIN CERTIFICATE-----
MIIC....

.....eaNfjfO0
-----END CERTIFICATE-----
```
上記から中間CA証明書の公開鍵を抜き出す。

```
openssl x509 -in /etc/pki/AWS/icacert.pem -pubkey -noout
-----BEGIN PUBLIC KEY-----
MFkw...
       ....==
-----END PUBLIC KEY-----
openssl x509 -in /etc/pki/AWS/icacert.pem -pubkey -noout > icapub.pem

```

#メッセージの中間CA公開鍵での検証
```
openssl dgst -sha256 -verify icapub.pem -signature signature.dat test.txt
Verified OK
```
検証OK


#中間CA証明書のルートCA証明書での検証

```
openssl verify -CAfile /etc/pki/AWS/cacert.pem /etc/pki/AWS/icacert.pem
/etc/pki/AWS/icacert.pem: OK
```

組み込みでの証明書チェーンの完全な検証を行うためには中間CA証明書のルートCA証明書での検証のメカニズムも把握する必要がある。また後日。
Unityでドラッグ&ドロップ

ドラッグしたいオブジェクトにつける（カードゲームならカード）

```csharp:DragObj.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class DragObj : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {
	public Transform parentTransform;
	public void OnBeginDrag(PointerEventData data){
		Debug.Log("OnBeginDrag");
		GetComponent<CanvasGroup>().blocksRaycasts = false;
		parentTransform = transform.parent;
		transform.SetParent(transform.parent.parent);

	}
	public void OnDrag(PointerEventData data){
		transform.position = data.position;
    }
	public void OnEndDrag(PointerEventData data){
		Debug.Log("OnEndDrag");
		transform.SetParent(parentTransform);
		GetComponent<CanvasGroup>().blocksRaycasts = true;
	}	
}
```

ドラッグしたいオブジェクトにCanvasGroupをつける（）
<img width="511" alt="スクリーンショット 2019-04-02 20.10.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/67439/aaddb0ff-c026-c462-d87f-6de2bc4a4a47.png">



ドロップしたいオブジェクトにつける（カードゲームならフィールドなど）

```csharp:DropArea.cs
using UnityEngine;
using UnityEngine.EventSystems;

public class DropArea : MonoBehaviour, IDropHandler
{
    public void OnDrop(PointerEventData data){
		Debug.Log(gameObject.name);
		
		DragObj dragObj = data.pointerDrag.GetComponent<DragObj>();
		if(dragObj != null){
			dragObj.parentTransform = this.transform;
			Debug.Log(gameObject.name+"に"+data.pointerDrag.name+"をドロップ");
		}		
    }
}
```
スタジオしまづでゲームの作り方を学びたい人向けのサロン▶︎https://camp-fire.jp/projects/view/149191
AWS Beanstalk(Multi-Container Docker)をPythonで試してみた ！ Web編その5 / ebextensions

第５回です。Web編の最終回になります。

## 連載一覧

- [その1 / 初期設定](https://qiita.com/i_matsui/items/63d9268531f97e348647)
- [その2 / 環境設定](https://qiita.com/i_matsui/items/f2c61015228303df9540)
- [その3 / Dockerrun.aws.json](https://qiita.com/i_matsui/items/042ef74d3f8cb6614d5d)
- [その4 / python-uwsgi環境作成](https://qiita.com/i_matsui/items/b6cee261d1c77d7064ae)
- [その5 / ebextensions](https://qiita.com/i_matsui/items/402808f11ce345b74999)

### 今回の概要

beanstalkではeb createをするディレクトリに

.ebextensionsというディレクトリを作り、「.config」で終わる

yamlまたはjsonファイルを配備することによって

Benastalkで構築されるAWS環境やEC2サーバの設定を行うことができます。

この記事ではyamlフォーマットを元にサンプルをお伝えします。

### 設定ファイルについて

設定ファイルは複数ファイルに分けることが可能です。

ファイル名の昇順で読み込まれていく為、

01-xxxx.config、02-yyyy.configなど順序性が必要な場合は

連番のファイル名にします。

１ファイルで複数の設定定義することも可能です。

### 今回説明する設定内容

- EC2のタイムゾーン設定
- EC2のインスタンスタイプ
- 構築対象のVPCやサブネットの設定
- ALB(ロードバランサ)の設定やSSLの設定
- オートスケールの設定
- CloudWatchLogsの連携設定

その他のAWSサービスの設定や詳細については

[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/command-options-general.html#command-options-general-elasticbeanstalksqsd)を確認してください。

### EC2のタイムゾーン設定

```
files:
  "/etc/sysconfig/clock" :
    mode: "000644"
    owner: root
    group: root
    content: |
      ZONE="Asia/Tokyo"
      UTC=false

commands:
  timezone:
    command: ln -sf  /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
```

### EC2のインスタンスタイプ

```
option_settings:
  aws:autoscaling:launchconfiguration:
    InstanceType: t2.micro
```

t2インスタンスでは後述のVPCやサブネットの設定が必須です。

### 構築対象のVPCやサブネットの設定

```
option_settings:
  aws:ec2:vpc:
    VPCId: vpc-xxxxxxx
    Subnets: subnet-yyyyyyy,subnet-zzzzzzz
    ELBSubnets: subnet-yyyyyyy,subnet-zzzzzzz
    AssociatePublicIpAddress: true
```

### ALB(ロードバランサ)の設定やSSLの設定
```
option_settings:
  aws:elasticbeanstalk:environment:
    LoadBalancerType: application

# HTTPでリクエストを受け付ける
  aws:elbv2:listener:80:
    Protocol: HTTP
    DefaultProcess: default
    ListenerEnabled: true

# HTTPSで独自ドメインを利用する場合
# 証明書を発行してACMに登録済みである必要があります。
  aws:elb:listener:443:
    SSLCertificateId: {ACMのARNを指定}
    Protocol: HTTPS
    DefaultProcess: default
    ListenerEnabled: true
```
# オートスケールの設定

```
option_settings:
  aws:autoscaling:asg:
    MinSize: 1
    MaxSize: 3
```
どの条件の時にインスタンスを増減させるかは
公式ドキュメントを確認してください。

各EC2インスタンスの平均CPU使用率がN％の場合、1台増やす・・・など。

# CloudWatchLogsの連携設定

```
files:
  "/etc/awslogs/config/logs.conf" :
    mode: "000600"
    owner: root
    group: root
    content: |
      [/var/log/containers/python-container/app.log]
      log_group_name = `{"Fn::Join":["/", ["/aws/elasticbeanstalk", { "Ref":"AWSEBEnvironmentName" }, "python"]]}`
      log_stream_name = {instance_id}
      file = /var/log/containers/python-container/app.log
      [/var/log/containers/nginx-proxy/access.log]
      log_group_name = `{"Fn::Join":["/", ["/aws/elasticbeanstalk", { "Ref":"AWSEBEnvironmentName" }, "nginx"]]}`
      log_stream_name = {instance_id}
      file = /var/log/containers/nginx-proxy/access.log

commands:
  "01":
    command: chkconfig awslogs on
  "02":
    command: service awslogs restart
```
インスタンスプロファイル(例：aws-elasticbeanstalk-ec2-role)に
CloudWatchのCreateLogGroup権限を与える必要があります。
AWS Beanstalk(Multi-Container Docker)をPythonで試してみた ！ Web編その4 / python-uwsgi環境作成

第４回はDockerリポジトリを使わずに

Python*uWSGI*flaskの環境の作る方法です。

## 連載一覧

- [その1 / 初期設定](https://qiita.com/i_matsui/items/63d9268531f97e348647)
- [その2 / 環境設定](https://qiita.com/i_matsui/items/f2c61015228303df9540)
- [その3 / Dockerrun.aws.json](https://qiita.com/i_matsui/items/042ef74d3f8cb6614d5d)
- [その4 / python-uwsgi環境作成](https://qiita.com/i_matsui/items/b6cee261d1c77d7064ae)
- [その5 / ebextensions](https://qiita.com/i_matsui/items/402808f11ce345b74999)


## 構築の前提

本来はECRなどのDockerリポジトリを使うべきですが

検証の為にリポジトリを用意せずに対応する方法になります。

　

AWSの公式[ドキュメント](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/create_deploy_dockerpreconfig.dockerfile.html)ではシングル構成のDocker時に

amazon/aws-eb-python:3.4.2-onbuild-3.5.1

というイメージを利用する記載がありますが

- Pythonのバージョンが古い

- multi container構成(Dockerrun.aws.json)ではイメージのカスタマイズができない

という理由により、[GITで公開されている](https://github.com/aws/aws-eb-python-dockerfiles)、

amazon/aws-eb-python:3.4.2-onbuild-3.5.1のDockerfileを元に

シェルにてコンテナ作成時にセットアップを実行します。

### start-docker.shの配備

eb createをするカレントディレクトリにstart-docker.shという名前の

シェルスクリプトを作成します。

```
#!/bin/bash

# virtualenvのインストールをして
# 仮想環境(xxxdemo)を作成
pip3 install virtualenv
virtualenv /var/xxxdemo

# virtualenv環境にuwsgiをインストール
/var/xxxdemo/bin/pip install uwsgi

# volumeの共有ディレクトリから
# プログラム一式を仮想環境のディレクトリにコピー
cp -PR /var/app/* /var/xxxdemo/

# uWSGI用の実行ユーザーの作成
useradd uwsgi -s /bin/false

# ログディレクトリの作成と権限を付与
mkdir /var/log/uwsgi
mkdir /var/log/xxxdemo
chown -R uwsgi:uwsgi /var/log/uwsgi
chown -R uwsgi:uwsgi /var/log/xxxdemo

# uwsgiの起動関連の設定
chmod 700 /var/xxxdemo/uwsgi-start.sh
if [ -f /var/xxxdemo/requirements.txt ]; then /var/xxxdemo/bin/pip install -r /var/xxxdemo/requirements.txt; fi

# uwsgiの起動シェルを実行
sh /var/xxxdemo/uwsgi-start.sh
```

### uwsgi-start.shの配備

eb createをするカレントディレクトリにuwsgi-start.shという名前の

シェルスクリプトを作成します。

```
#!/bin/bash

cd /var/xxxdemo

. bin/activate

# Flask support
if cat requirements.txt | grep -q -i Flask && [ -z "$WSGI_MODULE" ]; then
        WSGI_MODULE=application:app
fi

[ -n "$WSGI_MODULE" ] && UWSGI_MODULE="--module $WSGI_MODULE"

# defaulting to application.py if not explicitly set
[ -z "$WSGI_PATH" ] && WSGI_PATH=application.py

uwsgi --http :8080 --chdir /var/app --wsgi-file $WSGI_PATH $UWSGI_MODULE --master --processes $UWSGI_NUM_PROCESSES --threads $UWSGI_NUM_THREADS --uid $UWSGI_UID --gid $UWSGI_GID --logto2 $UWSGI_LOG_FILE
```

上記のファイルを配備するとDockerrun.aws.jsonの

entryPointの指定よりシェルスクリプトが起動してuWSGIが起動します。

flaskの起動モジュールはeb createのカレントディレクトリの

application.pyという名前ファイルで配備する必要があります。
AWS Beanstalk(Multi-Container Docker)をPythonで試してみた ！ Web編その2 / 環境設定

前回に続きBeanstalkについてです。

今回は実際にBenastalkの【環境】を作るところになります。

## 連載一覧

- [その1 / 初期設定](https://qiita.com/i_matsui/items/63d9268531f97e348647)
- [その2 / 環境設定](https://qiita.com/i_matsui/items/f2c61015228303df9540)
- [その3 / Dockerrun.aws.json](https://qiita.com/i_matsui/items/042ef74d3f8cb6614d5d)
- [その4 / python-uwsgi環境作成](https://qiita.com/i_matsui/items/b6cee261d1c77d7064ae)
- [その5 / ebextensions](https://qiita.com/i_matsui/items/402808f11ce345b74999)

## 今回の記事の対象範囲

Benastalkでmulti containerを動かす場合は

事前にコンテナ定義ファイルであるDockerrun.aws.jsonを用意して

Dockerコンテナの設定をしたり、

ロードバランサーの設定・関連づけるVPCの設定、オートスケールの設定など

AWS環境の設定も色々しないといけません。


今回は純粋にBenastalkの環境を作るだけをターゲットにします。

次回、Dockerrun.aws.jsonの詳細を、

今後の回ではAWS環境設定(.ebextensions)の説明をしようと思います。

## 環境作成の手順

前回、eb initにてアプリケーションを作りました。

このコマンドを実行するとカレントディレクトリに.elasticbeanstalkというディレクトリができます。

この中のconfig.ymlにinitした時の設定やこの後作る【環境】の設定情報がされます。

以降はebコマンドをカレントディレクトリで打つとこの設定を元に動作することになります。

> eb create

このコマンドを打つと環境が作成されます。

いくつか対話式で設定を選択することになりますが

インスタンスの種類やオートスケール設定などなど細かい設定はデフォルトになります。

コマンドオプションで指定することもできますが

次回以降にお伝えする.ebextensionsという

設定ファイルに外出しすると良いでしょう。


また、このコマンドを実行する前に事前に

- aws-elasticbeanstalk-ec2-role
- aws-elasticbeanstalk-service-role

というインスタンスプロファイル・サービスロールを作成する必要があります。

AWS BeansalkのWebコンソールからサンプルの環境が作れますので

サンプルを作ると上記の２のロールが自動生成されます。

Beanstalkが各種AWSサービスを構築したり、

EC2(Dockerのホスト)が環境構築の為にS3やECS・CloudWatchなどに

アクセスする為の権限設定になります。


　
前回同様、eb create実行じの対話コマンドの抜粋をしますが

```
eb create \
 --elb-type application \
 --vpc.id vpc-xxxxxxx \
 --vpc.ec2subnets subnet-yyyyyyy,subnet-zzzzzzz \
 --vpc.elbsubnets subnet-yyyyyyy,subnet-zzzzzzz \
 --vpc.elbpublic --vpc.publicip
```

今回はこちらのコマンドで実行します。

ロードバランサーの種類をALB(application)にしたいので

本来はebextensionsで設定すれば良いはずなのですが

ebextensionsで設定しても対話で聞かれてしまいます。

そして対話でALB(application)を設定すると

VPCの紐付けをオプションで指定しないとエラーになります。

EB CLIのバージョンが3.14.6なのですがCLIのバグなのかもしれません。

> Enter Environment Name
> (default is xxxxxxxxx-dev): 

【環境】の名前を指定します。デフォルトは「アプリケーション名-dev」になるようです。

> Enter DNS CNAME prefix
> (default is xxxxxxxxx-dev): 

CNAMEの名前を指定します。

これはアプリケーションにアクセスする為のALBに紐付けされるドメインとなります。

xxxxxxxxx-dev.ap-northeast-1.elasticbeanstalk.com

このような名前になります。上記のURLからわかるように

環境名は全AWS上でユニークになるので

同一アプリケーション内・同一AWSアカウント内はもちろん、

他者の環境名とも重複は許されません。

　

本番運用ではこのドメインに対して独自ドメインを紐づけることになります。

> Creating application version archive "app-190402_165432".
> Uploading xxxxxxxxx/app-190402_165432.zip to S3. This may take a while.
> Upload Complete.

こちらのログが出るとデプロイ中になります。

カレントディレクトリのファイルがzipに固められてS3に配備され、

その後に自動構築されるEC2の「/var/app/current」に解凍されます。


しばらく待つと上記のCNAMEのドメインでアプリケーションにアクセスできるようになります。

一度環境を作った後はカレントディレクトリでeb deployをすることで

環境の最新化をすることができます。

eb deployではEC2インスタンスやALBなどはそのまま利用されるので

インスタンスタイプなどのオプションは不要です。

次回はDockerrun.aws.jsonについて説明します。
ABC088 C - Takahashi's Information (300点)

#問題概要
[問題のリンク](https://atcoder.jp/contests/abc088/tasks/abc088_c)

$3×3$ のグリッドがある。各行を上から$i$、各列を左から$j$でナンバリングしていく時、マス$(i,j)$に数$c_{i,j}$が書かれている。
また $c_{i,j} = a_i + b_j$である。

以下のように$c_{1,1}$~$c_{3,3}$までが与えられる時、成立するか判定しろ。

>1 0 1
2 1 2
1 0 1

#制約条件
$c_{i,j} (1≤i≤3,1≤j≤3)$  は $0$ 以上 $100$ 以下の整数

#考えたこと
$c_{i,j} = a_i + b_j$ ということは $c_{i,j} - a_i =  b_j$ である。
よって、各行の数から $a_i$を引き、各列の値が同じになれば与えられたグリッドは正しいと言える。

ではどのように$a_i$を求めるかだが、$a_i$と$b_j$の制約はないため、同じ基準で$a_i$を仮定すればよい。私は最小値を使った。

入力例で実験すると以下のようになる。
![20190402_abc088-c.001.jpeg](https://qiita-image-store.s3.amazonaws.com/0/326440/a9af3e60-59a4-cece-5c33-13929ae76fac.jpeg)
![20190402_abc088-c.002.jpeg](https://qiita-image-store.s3.amazonaws.com/0/326440/e153d3bd-4401-2117-e16d-77cbab283d95.jpeg)
![20190402_abc088-c.003.jpeg](https://qiita-image-store.s3.amazonaws.com/0/326440/56ee0836-5181-5de1-c598-e7b610051b2b.jpeg)

計算量は入力によらず一定で $O(1)$である。

#解答

```c.cs
using System;
using System.Linq;

class Program
{
    static void Main(string[] args) {
        int[][] c = new int[3][];
        c[0] = Console.ReadLine().Split().Select(int.Parse).ToArray();
        c[1] = Console.ReadLine().Split().Select(int.Parse).ToArray();
        c[2] = Console.ReadLine().Split().Select(int.Parse).ToArray();
        Console.WriteLine(solve(c) ? "Yes" : "No");
    }
    static bool solve(int[][] c) {
        for (int i = 0; i < c.Length; i ++) {
            int min = c[i].Min();
            for (int j = 0; j < c[i].Length; j ++) {
                c[i][j] -= min;
            }
        }
        for (int i = 0; i < c.Length; i ++) {
            if(c[0][i] != c[1][i] || c[1][i] != c[2][i]) return false;
        }
        return true;
    }
}
```
pythonでじゃんけん作ってみた

```jyanken.py
import random
dic = {"a": "グー", "b": "チョキ", "c": "パー"}

print("じゃんけん")
print("a=グー　b=チョキ　c=パー")
user_hand = input(">>>  ")

user_choice = dic[user_hand]

choice_list = ["a", "b", "c"]
pc = dic[random.choice(choice_list)]

draw = 'あいこ'
win = 'あなたの勝ち'
lose = 'あなたの負け'

if user_choice == pc:
    judge = draw
else:
    if user_choice == "グー":
        if pc == "チョキ":
            judge = win
        else:
            judge = lose

    elif user_choice == "チョキ":
        if pc == "パー":
            judge = win
        else:
            judge = lose

    else:
        if pc == "グー":
            judge = win
        else:
            judge = lose

print("あなた:" + user_choice)
print("コンピュータ:" + pc)
print("結果:" + judge)
```
aws working_directory=/var/www/current (ArgumentError)

mac highsierra
ruby 2.3.1
rails 5.0.1
bundler 2.0.1



まず、以前自動deployして、仕様を更新しようとした。
そのときに、bundle exec cap production deployを行いdoneになったけれども更新した内容が反映され無いという現象が起こった。

それで、unicorn周りが怪しいかと目星を付けて、unicorn_rails -c config/unicorn.rb -E development -Dを行ったときになった。

```unicorn/configurator.rb:592:in `working_directory': config_file=config/unicorn.rb would not be accessible in working_directory=/var/www/current (ArgumentError)
```

working_directoryのpath（場所）がおかしいのでは無いかと思ったが、実際は違うかった。
bundle updateをすると、

```

Bundler could not find compatible versions for gem "bundler":
  In Gemfile:
    rails (= 5.0.1) was resolved to 5.0.1, which depends on
      bundler (< 2.0, >= 1.3.0)

  Current Bundler version:
    bundler (2.0.1)
This Gemfile requires a different version of Bundler.
Perhaps you need to update Bundler by running `gem install bundler`?

Could not find gem 'bundler (< 2.0, >= 1.3.0)', which is required by gem 'rails
(= 5.0.1)', in any of the sources.

Bundler could not find compatible versions for gem "rubygems":
  In Gemfile:
    rubygems (= 2.5.1)
    haml-rails was resolved to 2.0.0, which depends on
      rubygems (>= 3.0.0)
```
bundlerのversionがおかしいや無いかと言われ、一旦1.9に落とした。
でもうまく行かずだった。


解決策：

gem file.lockにBUNDLED WITH
   1.16.2
という記述を発見！！！

これにbundlerのversionを合わしてあげるといけた！！！
bundlerのversionを1.9から1.16.2に落として、installし
deployを行うとうまくいった。

なんで、入ってるbunlderのversionが違うねんww
Laravel で migrate 実行時に migrations テーブルの id が重複した

## 概要

Laravel デプロイ時、何故か migrate コマンドで失敗した正常にデプロイできなかったので、その時の原因の調査と解消方法をまとめます。（多分デプロイ時であるかどうかは関係ないです）

## 環境

- Laravel 5.7
- PostgreSQL
- Deployer (デプロイツール)

## 起きたこと

Deployer が `php artisan migrate --force` を実行した時に、 PostgreSQL の `migrations` テーブルに既存の id と同じ値で INSERT しようとしたため、ユニーク制約が掛かっているのでダメだと言われコケたようです。

```shell

  [Deployer\Exception\RuntimeException (1)]
  The command "/usr/bin/php /var/www/html/releases/214/artisan migrate --force" failed.

  Exit Code: 1 (General error)

  Host Name: 172.30.1.94

  ================
  Migrating: 2019_04_02_path_to_migration_file

  In Connection.php line 664:

    SQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value violates u
    nique constraint "migrations_pkey"
    DETAIL:  Key (id)=(1314) already exists. (SQL: insert into "migrations" ("m
    igration", "batch") values (2019_04_02_path_to_migration_file, 10))


  In PDOStatement.php line 119:

    SQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value violates u
    nique constraint "migrations_pkey"
    DETAIL:  Key (id)=(1314) already exists.


  In PDOStatement.php line 117:

    SQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value violates u
    nique constraint "migrations_pkey"
    DETAIL:  Key (id)=(1314) already exists.
```

## 解消手順

`migrations` テーブルの id カラムの sequence の `last_value` を以下のSQLで確認しました。

```sql
select * from migrations_id_seq
```

実際に last_value が、失敗した INSERT 時に指定していた値になっていたので、
これを実際の現在の最大値に設定し直しました。

```sql
select setval('migrations_id_seq', {最大値})
```

この状態でデプロイをやり直したら解決しました。

## 起きた原因

特定できませんでした :joy:
hardwareAcceleratedがデフォルトTrueは嘘

真に嘘かはわかりません。すみません。

広告をアプリ内に実装する際に、リリース後痛い経験をしたので共有も兼ねてTipsとして残せればと思います。

## `hardwareAccelerated` は明示的に指定しましょう
広告を実装するときには以下のような指定を `<application>` ルートに求められていることが多いです。

```gradle
android:hardwareAccelerated="true"
```

## 公式ドキュメントにはデフォルトTrueと書いてある

> The default value is "true" if you've set either minSdkVersion or targetSdkVersion to "14" or higher; otherwise, it's "false".

Ref: https://developer.android.com/guide/topics/manifest/application-element.html#hwaccel

最近でいうと `minSdkVersion` は `19` か `21` を指定することが多いと思うのでTrueがデフォルトだと認識してしまいますね。

## `hardwareAccelerated` の指定を消したら盛大にクラッシュが増えた
上がってきたクラッシュは以下のような内容でした。
<img width="733" alt="スクリーンショット 2019-04-02 19.12.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/83877/a5e9d31f-0d04-c921-7d1b-82aa17288a9f.png">

1週間でクラッシュフリーユーザー比率が5%は減るくらいこの2つのクラッシュで影響があったのでユーザーには申し訳なかったなと思います。。。

エラー内容でググっても全然情報出てなかったので大半は、
`広告使ってるのにhardwareAcceleratedの指定消すなんてあり得ないでしょ`
みたいな認識なんだろうなと思います。

## `hardwareAccelerated=true` の指定を戻したら盛大にクラッシュが減った
デフォルト値の意味ってなんなんでしょう、、、

## OSや機種によって挙動が変わっていた
クラッシュの情報を追っていくと、
OSは`7以上9未満`、メーカーも `Xperia、Galaxy、AQUOS` に集中していることがわかりました。

端末によってクラッシュが起きる端末と起きない端末があるようでした。

## まとめ
- 出来るだけ指定するべきものは省略しない
  - チームのエンジニア全員がすぐに理解できるようなコードを意識して書いていきましょう
- Android全端末がデフォルト値を使ってくれると思わない
  - 改めて機種依存の怖さを思い知らされました
- SDK導入のWikiをもっと信頼していこう
  - 誰かが一生懸命調査してまとめてくれた成果物を最初から否定的な視点で見るのをやめる
  - 常に情報が間違っていないか疑いを持つことは大事
  - Wiki通りに`ちゃんと`実装していけばちゃんと動くのはあるある

以上です。
Vapor のホストネームと起動ポートを変更する

Vapor のホストネームと起動ポートを変更する方法です。
以下の方法で`localhost:8080`から任意のホストネーム、ポートに変更することが可能です。


#### コマンドでホストネームとポートを変更する場合

``` bash
$ swift run Run --hostname 0.0.0.0 --port 9090
```

#### 設定ファイルに記述する場合

``` swift:configure.swift
let serverConfiure = NIOServerConfig.default(hostname: "0.0.0.0", port: 9090)
services.register(serverConfiure)
```


参考: [Changing hostname and port with Vapor 3](https://stackoverflow.com/questions/48450239/changing-hostname-and-port-with-vapor-3)
バッチスクリプトでテストデータ複製

###背景・経緯
会社で提供しているWebシステム(地図上に顧客データをマッピングする、営業活動支援ツール)で性能課題がしぶとく残っていて、今期で何とか解消しようということで案件化したものの、テスト環境に性能検証用のデータ（大量データ）をつっこむようなツールもない。
やろうと思えば本番データをマスキングして取り込めば本番想定件数の確認はできるが、たとえば「表示対象の顧客データが１００００件ある場合だと何秒くらいかかる？」みたいな検証パターンに対応できない（厳密にはできなくはないんだけど手作業での対応にめちゃくちゃ時間がかかる）

###実施したこと
そういえばスクリプトもロクに書けないなぁというコトで、勉強を兼ねて、アナクロだけどテストデータを１件用意すれば、何件データを作るかさえちょこっと書き換えて実行すればその分だけテストデータを複製してくれるバッチスクリプトを作った。

```batch
@echo off

rem テストデータ作成処理

rem 遅延環境変数に対応
SETLOCAL enabledelayedexpansion

rem カレントディレクトリ指定
cd /d %~dp0

rem ループ制御用
set cnt=1
rem ループ回数
set loop=1500

set str0=abc
 
rem 入力ファイルを同じフォルダに置く
for /f "delims=" %%A in (in_table1.csv) do (
  rem レコードを変数にセット
  set str0=%%A

  call :outputfile
)

exit /b

rem サブルーチン(レコード編集・出力処理)
:outputfile

  rem 1-35ﾊﾞｲﾄを抽出
  set str1=!str0:~0,35!
  rem 36-43ﾊﾞｲﾄ(顧客キー)を抽出
  set str2=!str0:~35,7!

  :next 

  rem 顧客コードに１を加算
  set /a str2 = str2 + 1
  set str3=!str0:~42,32!
  set str4=!str2!
  set str5=!str0:~81!
  rem 顧客コード編集後レコード
  set str6=!str1!!str2!!str3!!str4!!str5!

  rem 出力
  echo !str6! >> output_table1.sql

  set /a num = num + 1
  echo !num!
  echo !loop!

  if !num! gtr !loop! (
    exit /b
  ) else (
    goto :next
  )

ENDLOCAL
```

###つまずきポイントなど
１．for文の中の変数が更新されない
　％で囲んだ変数はfor実行時の値でループ処理が実行される

　解決策：①遅延環境変数を使う
　　　　　②ループ処理内部の変数は！で囲む
　　　　　→その行の処理が実行される時点で変数の値を再取得する

２．for文の中ではgotoを使ったループができない
　for文の中ではラベル（：）が記述できない

　解決策：for文の中でのループ（二重ループ）にしたい部分をサブルーチン化する。
　　　　　その上で、サブルーチン内にgotoを使ったループ処理を書く

３．半角スペースまでしかレコードが読み込まれない。

　解決策：for文の「delims」(デリミタ/区切り文字)に何も指定しないことで、
　　　　　各行の最後の文字まで読み込むようにする。

###今後の課題
１．複製する件数や入力ファイル名は実行に入力パラメータとして渡せるようにする。

２．レコード長が変わっても対応できるように区切り位置も変数化する。

３．そもそも、各テーブル定義はきちんとデータ化されてるんだから、
　　テーブルＩＤと欲しい件数を指定すればレコードを作成してくれるツールがそう手間をかけずに作れる、ハズ。

あんまり時間もない中で手早くできそうってコトでバッチスクリプトで何とかしたけど、今後はどこかで時間を確保して汎用的に使えるツールにしていきたい。

※課題は近々解消して記事も更新します。
　妥当性を気にするほどの規模でもないけど、これくらいのスクリプトは何も見ずにパパッと書けるようになりたい。
WinActor シナリオを順次実行する(不完全燃焼版)


##順次実行とは？
1番から順番に実行していくような処理
例(カップ麺を食す)
1.お湯を沸かす　
2.カップ麺のふたをあける
3.カップ麺にお湯を入れる
4.カップ麺のふたの上にたれを乗せる(あたためる)
4.3分待つ
5.たれをとる
6.カップ麺のふたを開ける
7.たれを入れる
8.混ぜる
9.麺を持ち上げる
10.息を吹きかける
11.食べる
12.むせる

##WinActorシナリオ順次実行の問題点
シナリオを区切りの良い処理単位でファイルにしていた。
WinActorシナリオを移動できるライブラリを見かけたので
それで理想図が行けると信じていた。

###理想図
![image.png](https://qiita-image-store.s3.amazonaws.com/0/345260/95f4a764-4866-e3ac-df7a-7fc44465c8c9.png)
シナリオを指定したらメインシナリオに戻ってきて、次の処理へ行くイメージ。これでメインシナリオの順番を変えれば実行順も簡単に変更できる。元の処理は何も変更せずに済む

###シナリオGotoの現実
![image.png](https://qiita-image-store.s3.amazonaws.com/0/345260/7c752994-3a2a-2c2f-db53-7747f47edcf1.png)
多分Gotoっていうのは理不尽なもんなんだよっていうことなんだとおもう。
確かにGotoだよ。行ったきりで戻ることなんかしない。
目が覚めたら夢見てるんじゃないと名前でわかっとけという話だと涙しました。

###シナリオGotoで理想に近づける方法(アルゴリズム的には片方向連結リスト)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/345260/96e5d4b7-8418-b800-9d45-0ecd4c95d9ad.png)
全部のシナリオの後ろにGotoをつける
ただ、これだと各シナリオを部品っぽくできない。
気軽に順番を変えたり、シナリオを飛ばしたりできると思ってはいけない。
単独でシナリオ1だけ実行したい場合は実行フラグを設定化するような感じが必要になる。

####本当はやりたい追加仕様
pythonでいうところのif __name__ == '__main__':
シナリオ1単独実行時はシナリオ1の処理だけ行って終了。メインから呼ばれたら次のシナリオ実行

####問題点
シナリオの順番を変える場合は前後の順番のシナリオも書き換える必要がある。
本当はやりたい追加仕様を実現するには自動化処理分岐などが必要。
変数引継ぎが楽そうだが
メインシナリオはシナリオ1に引き継ぐ
シナリオ1はシナリオ2に引き継ぐ
・・・・
とやるとシナリオの数だけ変数が雪だるま式に増えるので自動フラグは変数以外で実装する必要がある。

##妥協策
###bat処理でメインシナリオ相当を作成する
でも失敗時とかの制御が面倒(多分返却値をファイルにして失敗時値を変えてbatではシナリオ終了後確認するなどで実現自体は出来ると思うが・・・)

```bat:メインシナリオ.bat
"C:\Program Files (x86)\WinActor\WinActor.exe" -f "C:\シナリオ\シナリオ1.ums5" -r -e
"C:\Program Files (x86)\WinActor\WinActor.exe" -f "C:\シナリオ\シナリオ2.ums5" -r -e
"C:\Program Files (x86)\WinActor\WinActor.exe" -f "C:\シナリオ\シナリオ3.ums5" -r -e
```

###batの問題点
WinActorがシナリオ終了ごとに立ちあがっては消え、立ちあがっては消えます。その分だけ時間がかかる。

##本当に欲しかったもの
シナリオCall
シナリオを関数みたいに読んで、終わったら戻ってきてほしい。
GotoではなくCall。NTTの人お願いします。
Azure DevOpsで急にgit pushができなくなった

# Azure DevOpsで急にgit pushができなくなった

## 状況

- Visual Studio(2019 RC)のチームエクスプローラーから、
リモートレポジトリにpush(fetchも)できなくなった。
- 別のリポジトリだと問題なし。
- push時のエラーメッセージは以下のとおり。

> Logon failed, use ctrl+c to cancel basic credential prompt.
Error: cannot spawn /c/program files (x86)/microsoft visual studio/2019/enterprise/common7/ide/commonextensions/microsoft/teamfoundation/team explorer/Git/mingw32/libexec/git-core/git-askpass.exe: No such file or directory
フェッチ中にエラーが発生しました: Git failed with a fatal error.
could not read Username for 'https://dev.azure.com': terminal prompts disabled

## 解消方法

- 下記ファイルを削除する。
    - %localAppData%\GitCredentialManager\tenant.cache

## 補足

- エラーメッセージからは、git-askpass.exeに原因があると思って、Credential ManagerやGit for Windowsをインストールし直すなど、試行錯誤してみたのですが解決に至らず、私の場合はこの方法で直りました。
- 急に操作できなくなった理由は不明ですが、前日にAzure DevOps 組織のAzure ADドメインを変更したりしていたので、それが影響しているかもです。
ABC - 076- A&B&C

#AtCoder ABC 076 A&B&C
[AtCoder - 076](https://atcoder.jp/contests/abc076)


#A問題

```java
	private void solveA() {
		int numR = nextInt();
		int numG = nextInt();

		out.println(numG * 2 - numR);
	}

```

#B問題

 - 常に最小の操作をすればよい
    - どちらの操作が最小値になるのかを比較

```java
	private void solveB() {
		final int numN = nextInt();
		final int numK = nextInt();

		int res = IntStream.range(0, numN).reduce(1, (sum, i) -> {
			if (sum * 2 > sum + numK) {
				sum += numK;
			} else {
				sum *= 2;
			}
			return sum;
		});

		out.println(res);
	}
```

#C問題

 - 可能性のある文字を全部調べて文字コード順に並べ替える
 - ロジックの説明はコメントで記載

```java
	private void solveC() {
		char[] strS = next().toCharArray();
		char[] strT = next().toCharArray();

		if (strS.length < strT.length) {
			out.println("UNRESTORABLE");
			return;
		}

		List<String> memo = new ArrayList<String>();

		//文字列Sの1文字目から開始
		int resT = chkC(strS, strT, 0, memo);

		//memoの文字列をソートする
		Collections.sort(memo);
		//文字列が1つ以上あった場合はソート順で一番先頭の文字を表示
		out.println(resT > 0 ? memo.get(0) : "UNRESTORABLE");
	}

	private int chkC(char[] strS, char[] strT, int indexS, List<String> memo) {
		//文字列Sの開始位置+文字列Tの長さが文字列Sの長さを超えた場合は終了
		if (indexS + strT.length > strS.length) {
			return 0;
		}

		int res = 0;

		int cntT = 0;
		boolean isMatch = false;

		/*
		 * 置き換えた場合の文字列を作成する
		 * ただし、ここで作成した文字列は正しいかどうかはわからない
		 */
		StringBuilder builder = new StringBuilder();
		for (int i = 0; i < strS.length; i++) {

			if (i < indexS || i >= indexS + strT.length) {
				//文字列Sの内、文字列Tに置換しないところはそのまま文字列Sをappend
				builder.append(strS[i]);
			} else {
				if (strT[cntT] == strS[i] || strS[i] == '?') {
					//文字列Sと文字列Tが同じ文字または、文字列Sが'?'なら文字列Tの置き換える
					builder.append(strT[cntT]);
					//文字列Tの文字をappendしたカウント
					cntT++;
				} else {
					/*
					 * 文字列Sと文字列Tが違う場合は文字列Sをappend
					 * 基本的にこのルートにきた場合、その文字列は文字列Tを含んでいない
					 */
					builder.append(strS[i]);
				}
			}
		}

		/*
		 * 文字列Tの文字をappendしたカウントと文字列Tの長さが同じなら、
		 * 文字列Tで置き換えることに成功している。
		 */
		isMatch = (cntT == strT.length);
		if (isMatch) {
			//作成した文字列が正しい場合のみmemoにadd
			memo.add(builder.toString().replace("?", "a"));
			/*
			 * ただしい文字列を作成できたので作成カウント+1、
			 * その後indexSを+1して再度マッチングしてほかの文字を探す
			 */
			res += chkC(strS, strT, indexS + 1, memo) + 1;
		} else {
			//ただしい文字列を作成できなかったので、indexSを+1して再度マッチング
			res += chkC(strS, strT, indexS + 1, memo);
		}

		return res;
	}
```
データベースリンクを使う場合は分散トランザクションに注意

リンクのテーブルにselectをした後、違うテーブルにupdateをかけると
トランザクションのエラーが発生する。

データベースリンクしているテーブルにselectをかけると、DB間にセクションが貼られる。
そのため、データベースリンクしているテーブルへselectをかけた際は、
一度明治的にコミットをする必要がある。

http://otndnld.oracle.co.jp/document/products/oracle11g/111/doc_dvd/server.111/E05760-03/ds_appdev.htm

http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19224-02/ds_txns.htm
質問サイトStack Overflowのキラキラの紫色のやつを止める

## やりたいこと

Stack Overflowの見た目が、以下のようになってます（2019/04/02）。

<img width="1121" alt="Screen Shot 2019-04-02 at 18.38.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/84451/00fe8d4d-f63f-dd87-d1d2-0dd50d658103.png">

数日前からなっていて、最初はStack Overflowの内容をスクレイピングして作ったニセサイトかと思いましたが、「90年代風にデザイン変更」とのことなんですね。

楽しくていいですが、内容に集中しづらいのでOFFにする方法を探したら、
Stack Overflow自体に質問がありました。

## 右上の「時計」を押せば止まる

時計🕘のアイコンを押すと、いつもどおりのStack Overflowに戻ります

<img width="518" alt="Screen Shot 2019-04-02 at 18.44.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/84451/32c23cd8-a8b8-4447-e519-bcf21164fa00.png">

（最初に訪問するときに、90's lookに関して小さなポップが出てたんですけど、多分読まずに消しました。）

## 参考
* [How to stop the 90’s look of the Stack Overflow? - Meta Stack Overflow](https://meta.stackoverflow.com/questions/382077/how-to-stop-the-90-s-look-of-the-stack-overflow)
Nuxt.js で ESLint ＆ Prettier を導入する

ESLint だけでもコード整形はできるようですが、Prettier のコード整形の方が優れているらしい。
Nuxt.js の公式ドキュメントの通り、併用して導入することにします。

## Nuxt.js で ESLint を使う

### インストール
```bash
$ npm install --save-dev babel-eslint eslint eslint-config-prettier eslint-loader eslint-plugin-vue eslint-plugin-prettier prettier
```

### ESLint の設定ファイルをつくる
プロジェクトの root に `.eslintrc.js` を作る

```js:.eslintrc.js
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true
  },
  parserOptions: {
    parser: 'babel-eslint'
  },
  extends: [
    "eslint:recommended",
    // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
    // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
    "plugin:vue/recommended",
    "plugin:prettier/recommended"
  ],
  // required to lint *.vue files
  plugins: [
    'vue'
  ],
  // add your custom rules here
  rules: {
    "semi": [2, "never"],
    "no-console": "off",
    "vue/max-attributes-per-line": "off",
    "prettier/prettier": ["error", { "semi": false }]
  }
}
```

#### 注意
公式ドキュメントをコピペすると `module.exports {` となっていましたが、
IDEに文法エラーだと怒られたので `module.exports = {` に修正しました。

## package.json にエイリアスコマンドを追加する
```package.json
"scripts": {
  "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
  "lintfix": "eslint --fix --ext .js,.vue --ignore-path .gitignore ."
}
```

以上で `npm run lint` で LINT チェック、 `npm run lintfix` で LINT の簡易修正が可能になる。
ちなみに、ESLint は `.gitignore` に書いてあるものは無視します。

## ホットリローディングしたいとき
`npm run dev` 中は常に変更を検知させたい場合（というかそうするのがおすすめ）は `nuxt.config.js` で下記のような設定をする。

```js:nuxt.config.js
  /*
   ** Build configuration
  */
  build: {
   /*
    ** You can extend webpack config here
   */
   extend(config, ctx) {
      // Run ESLint on save
      if (ctx.isDev && ctx.isClient) {
        config.module.rules.push({
          enforce: "pre",
          test: /\.(js|vue)$/,
          loader: "eslint-loader",
          exclude: /(node_modules)/
        })
      }
    }
  }
```


## 参考
[公式ドキュメント]
(https://nuxtjs.org/guide/development-tools#eslint-and-prettier)
[Step by Stepで始めるESLint]
(https://qiita.com/howdy39/items/6e2c75861bc5a14b2acf)
[Prettier 入門 ～ESLintとの違いを理解して併用する～]
(https://qiita.com/soarflat/items/06377f3b96964964a65d#%E4%BD%95%E6%95%85prettier%E3%82%92%E5%88%A9%E7%94%A8eslint%E3%81%A8%E4%BD%B5%E7%94%A8%E3%81%99%E3%82%8B%E3%81%AE%E3%81%8B)
javaでCの[lower_bound関数]や[upper_bound関数]を使いたい

# C のlower_bound関数や upper_bound関数はjavaにないのか？

##【結論】
 - そのものズバリの関数は存在しない
 - ただし、Arrays#binarySearch()を使えば可能
    - やり方は二通り
        - comparatorを実装する
        - Arrays#binarySearch()に渡す引数を操作する

##【実装】

 - Comparatorを実装する
    - 【参考】のリンク先に丁寧な解説があるので其方で

 - Arrays#binarySearch()に渡す引数を操作する
    - binarySearch(Object[] a, Object key)　の keyを $\pm0.1$ （影響が出ない桁数で $\pm$ ）する

**サンプル出力用ソース***

```java
	private void hoge() {
		final int CONST_LOOP = 10;
		double[] sampleArray = { -1d, 0d, 1d, 1d, 3d, 3d, 5d, 5d, 6d, 7d };
		System.out.println("normal");
		System.out.println("xs: " + Arrays.toString(sampleArray));

		for (int index = 0; index <= CONST_LOOP; ++index) {
			long result = Arrays.binarySearch(sampleArray, index);
			long insertionPoint = (result >= 0) ? result : ~result;
			System.out.printf("index: %d | result: %2d | the position where value can be inserted: %d\n", index, result, insertionPoint);
		}
		System.out.println("upper");
		System.out.println("xs: " + Arrays.toString(sampleArray));

		for (int index = 0; index <= CONST_LOOP; ++index) {
			long result = Arrays.binarySearch(sampleArray, index + 0.1);
			long insertionPoint = (result >= 0) ? result : ~result;
			System.out.printf("index: %d | result: %2d | the position where value can be inserted: %d\n", index, result, insertionPoint);
		}

		System.out.println("lower");
		System.out.println("xs: " + Arrays.toString(sampleArray));

		for (int index = 0; index <= CONST_LOOP; ++index) {
			long result = Arrays.binarySearch(sampleArray, index - 0.1);
			long insertionPoint = (result >= 0) ? result : ~result;
			System.out.printf("index: %d | result: %2d | the position where value can be inserted: %d\n", index, result, insertionPoint);
		}
	}
```


**実行結果**
**normal(引数加工無し)**
Search対象の配列 $ [-1.0,\quad 0.0,\quad 1.0,\quad 1.0,\quad 3.0,\quad 3.0,\quad 5.0,\quad 5.0,\quad 6.0,\quad 7.0]$

|挿入したい数値|生のresult|否定して得られる挿入位置|
|:-:|:-:|:-:|:-:|
|0 |  1 |1|
|1 |  2 |2|
|2 | -5 |4|
|3 |  4 |4|
|4 | -7 |6|
|5 |  7 |7|
|6 |  8 |8|
|7 |  9 |9|
|8 | -11 |10|
|9 | -11 |10|
|10 | -11 |10|

**upper_bound(引数を+0.1)**
Search対象の配列 $ [-1.0,\quad 0.0,\quad 1.0,\quad 1.0,\quad 3.0,\quad 3.0,\quad 5.0,\quad 5.0,\quad 6.0,\quad 7.0]$

|挿入したい数値|生のresult|否定して得られる挿入位置|
|:-:|:-:|:-:|:-:|
|0 | -3 |2|
|1 | -5 |4|
|2 | -5 |4|
|3 | -7 |6|
|4 | -7 |6|
|5 | -9 |8|
|6 | -10 |9|
|7 | -11 |10|
|8 | -11 |10|
|9 | -11 |10|
|10 | -11 |10|

**lower_bound(引数を-0.1)**
Search対象の配列 $ [-1.0,\quad 0.0,\quad 1.0,\quad 1.0,\quad 3.0,\quad 3.0,\quad 5.0,\quad 5.0,\quad 6.0,\quad 7.0]$

|挿入したい数値|生のresult|否定して得られる挿入位置|
|:-:|:-:|:-:|:-:|
|0 |-2 |1|
|1 | -3 |2|
|2 | -5 |4|
|3 | -5 |4|
|4 | -7 |6|
|5 | -7 |6|
|6 | -9 |8|
|7 | -10 |9|
|8 | -11 |10|
|9 | -11 |10|
|10 | -11 |10|


##【参考】
[java.util.Arrays.binarySearch で二分探索 + Java で std::lower_bound/upper_bound](https://qiita.com/taskie/items/b4e45e2005aa38e90bcb)
[Vue.js] $refsでコンポーネント内の子要素を触る

ちょっと詰まったところがあったのでメモがわりに。

### $refsから子要素を触ろう
配置したコンポーネントを動的に取得して、スタイルとかプロパティを取得して弄りたかったり、処理を実行させたかったりする時がある。
そういう時は触りたい要素に`ref`を設定すると`$refs`から取得できるようになる。
 
```vue
<template>
  <hogehoge ref="hogehoge" />
</template>

<script>
  ...
    let component = this.$refs.hogehoge /// コンポーネントインスタンス hogehoge
  ...
</script>
```

### リストレンダリングした物も$refsで取れる
`v-for`でリストレンダリングしたコンポーネントも`$refs`で取得することができる。

```vue
<template>
  <hogehoge v-for="item in hoge" ref="hogehoge" />
</template>

<script>
  ...
    let component = this.$refs.hogehoge[0] /// リストレンダリングした hogehoge の先頭要素
  ...
</script>
```

この例のように、リストレンダリングしたオブジェクトに`$refs`からアクセスすると
それぞれのインスタンスが順番に格納された配列が返ってくる。

### ひらめいた
これ、同じ`ref`名を設定してやれば配列で格納されるって事じゃないの？
じゃあリストレンダリングの後に同じref名でコンポーネント設置してやれば
配列の最後に必ず特定の状態のコンポーネント入れられるんじゃね？

```vue
<template>
  <hogehoge v-for="item in hoge" ref="hogehoge" />
  <fugafuga ref="hogehoge" />
</template>
```

### されない
**そんな訳がなかった。**
同名refが配列として格納されるのではなく、あくまで**リストレンダリングしたコンポーネントを配列として返しているだけ**。
じゃあ上に書いたコードだとどのような結果になるかというと

```vue
<script>
  ...
    let component = this.$refs.hogehoge /// コンポーネントインスタンス fugafuga
  ...
</script>
```

`<fugafuga>`要素だけが取れる。
つまり**同名のrefを持つコンポーネントを2つ以上設置した場合、後に配置した方に上書きされる**のだった。
~~これに気付かず型チェックやら何やらの判定をコンソールに吐き出して散々デバッグする苦い目にあったのでメモ替わりに投稿。~~

### 他に気をつける事
コンポーネントインスタンスにアクセスする関係上、親コンポーネントがレンダリングされていない状態で既に処理を行っている
`created`や`beforeMount`では当然使えない。`computed`も最初の処理時にDOM要素が無いのでif条件で何とかしないと使えない。

あとAxiosとかの非同期処理で引っ張ってきたデータを元にリストレンダリングしている場合、
当然非同期処理の終了を待たないと`$refs`の中を見ても何も無いので注意。

### 参考
- [Vue.js公式ガイド/特別な問題に対処する](https://jp.vuejs.org/v2/guide/components-edge-cases.html#子コンポーネントインスタンスと子要素へのアクセス)
半歩ずつ進める機械学習　~scikit-learnボストン住宅価格編~④

##前回まで
[前回の投稿][1]では、scikit-learnの`LinearRegression`を使用してモデルを作成し
`cross_val_score`を使って5分割の交差検証を行いました。
その結果1回目の結果から順番に

+ 0.63861069 
+ 0.71334432 
+ 0.58645134 
+ 0.07842495 
+ -0.26312455

というスコア（決定係数）を得る事が出来ました。
1~3回目までの結果と比べて、4･5回目の結果が著しく悪いので
これは一体何故だろう、データを詳しく見てみようという所までやりました

##その前に
前回は`cross_val_score`を使って交差検証を行いました
この関数はサンプルデータを分割する時にデータの並び順に分割します
例えば200個のデータを2個に分ける時、1～100までと101～200までの2つに分けるといった感じです

蛇足になるかもしれませんが、例えば身長から体重を推定する為のデータセットがあったとして
データが身長の低い物から高い物順にソートされていた場合
150cm～170cmのデータで作ったモデルで、180cmの人の体重を推測する事になったりします。
このようにモデル作成に使ったサンプルデータの外のデータを推測する事を**外挿**というそうです
逆に、150～160cmと170～180cmのサンプルデータで作ったモデルで
165cmの人の体重を推測する事は**内挿**になります（違ってたらｽｲﾏｾﾝ･･･

##もう一度データを確認
初回の投稿で、データの相関等をグラフにして俯瞰しましたが
ここでもう一度各データを、今度は折れ線グラフで確認します
画像が縦に大きいので、折り畳んでいます。

<details><summary>折れ線グラフ①</summary><div>
![image.png](https://qiita-image-store.s3.amazonaws.com/0/316551/e50ff722-838f-73ad-7293-7966cfd4c17d.png)
</details></div>

うーん、なんだか後半150件分くらいのデータが偏ってませんか
特に**INDUS RAD TAX**あたりは、前半のデータと後半のデータの差が激しく見えます。
見易いように**INDUS**が高い部分を囲ってみると以下のような感じです。

<details><summary>折れ線グラフ②</summary><div>
![image.png](https://qiita-image-store.s3.amazonaws.com/0/316551/296b5353-2876-bb3f-2d49-85a50a1b4124.png)
</details></div>

あまりデータに対して主観的な先入観を持つのは、良くない事かもしれませんが
**INDUS(商業地率)**が高い所を**商業区**
**ZN(住居区画率）**が高い所を**住宅地**
と2分して考えると

商業区では働く人間の出入りが多い為**RAD(高速道へのアクセスの良さ)**が高く
それに伴って**NOX(窒素酸化物濃度）**も高い
住んでる人は少ないが、働く人は多いので**CRIM(人口比犯罪率)**も高い。
住宅地と比較して物件価格がやや安く**LSTAT(低所得者人口）**も多い。

みたいな関係がありそうな気がします（主観が入ってます）

前回`cross_val_score`で試行毎に大きなスコアの差があったのは
データセットのデータの並びに偏りがあり、住宅街データで学習して商業区物件の予測
みたいな事が起きていたからだと思われます。

##次回へ
次回はランダムに分割したデータで交差検証を行い
その結果を改善出来ないか検討します。

##お願い
機械学習初心者が備忘録・知識の確認の為に投稿しています。
間違っている点や、厳密には正しくないといった点が多いにあるかと思います
お気づきの方がいらっしゃいましたら、ご指摘を頂けましたら幸いです。

[1]:https://qiita.com/Mukomiz/items/1a87f89cea1f0bb28a63
M2Detでデモ・評価・学習までやってみる

噂のM2Detのチュートリアルを一通りやってみました。
M2Detについては以下の記事がわかりやすいです。
[最新最強の物体検出技術M2Det](https://qiita.com/kzykmyzw/items/1831f70dcade04db2210)

##実行環境
| OS |Ubuntu16.04 |
|:---|-----------:|
| **GPU**| **Nvidia GeForce GTX 1080** |
|**CPU**|**intel Core i7 8700**|

# デモ

※Anacondaは使いません。

####1. Pytorch他、必要なパッケージをインストール

```
pip install torch torchvision
pip install opencv-python, tqdm
```

####2. M2Detのリポジトリをクローン

```
git clone https://github.com/qijiezhao/M2Det
```

####3. シェルを実行
※M2Detディレクトリに移動して以下を実行します。

```
sh make sh
```

####4. Demoを実行
①https://drive.google.com/file/d/1NM1UDdZnwHwiNDxhcP-nndaWj24m-90L/view
　より`m2det512_vgg.pth`をダウンロードし、`M2Det/weights`に置きます。(weightsディレクトリは自分で作ってください)
②以下を実行します。

```
　python demo.py -c=configs/m2det512_vgg.py -m=weights/m2det512_vgg.pth --show
```

※Webカメラを使う場合

```
　python demo.py -c=configs/m2det512_vgg.py -m=weights/m2det512_vgg.pth --show --cam=0
```

これだけ！簡単ですね。

#評価
####1. ssd.pytorchのリポジトリをクローン

```
git clone https://github.com/amdegroot/ssd.pytorch
```

####2. COCOデータセットをダウンロード
※ssd.pytorchディレクトリに移動して以下を実行します。

```
sh data/scripts/COCO2014.sh
```

何も指定しなければ`~/data`に保存されます。

※`~/data/coco/annotations` に`instances_minival2014.json`が存在しない場合は
`~/data/coco/annotations/annotations/instances_val2014.json`
を`~/data/coco/annotations`にコピーし、ファイル名を`instances_minival2014.json`に変更してください。

####3. 評価を実行
M2Detディレクトリで以下を実行します。
※事前に`~/data/coco_cache` ディレクトリを作成します。

```
python test.py -c=configs/m2det512_vgg.py -m=weights/m2det512_vgg.pth
```

![eval.png](https://qiita-image-store.s3.amazonaws.com/0/265258/12f18c55-c558-822e-5c95-1883d280d0b7.png)

↑のような表示が出れば成功です。

#トレーニング
M2Detディレクトリで以下を実行します。
※`CUDA_VISIBLE_DEVICES`は使用するGPU番号、`ngpu`は使用するGPUの数を指定してください。

```
CUDA_VISIBLE_DEVICES=0,1,2,3 python train.py -c=configs/m2det512_vgg.py --ngpu 4 -t True
```

GPUが1台の場合は

```
CUDA_VISIBLE_DEVICES=0 python train.py -c=configs/m2det512_vgg.py --ngpu 1 -t True
```

となります。

※`M2Det/weights` に`vgg16_reducedfc.pth`が存在しない場合は
https://s3.amazonaws.com/amdegroot-models/vgg16_reducedfc.pth
より`vgg16_reducedfc.pth`をDLし、`M2Det/weights` に配置してください。

※`~/data/coco/annotations` に`instances_train2014.json`が存在しない場合は
`~/data/coco/annotations/annotations/instances_train2014.json`
を`~/data/coco/annotations`に配置してください。

※`~/data/coco/annotations` に`instances_valminusminival2014.json`が存在しない場合は
https://drive.google.com/drive/folders/0B1_fAEgxdnvJSmF3YUlZcHFqWTQ
より`instances_valminusminival2014.json`をDLし、`~/data/coco/annotations` に配置してください。

※メモリが足りない場合
入力サイズの小さいconfigファイルを使用する(m2det320_vgg.pyなど)、
または`M2Det/config/m2det512_vgg.py` の
`per_batch_size`の値を小さくしてください。

![train.png](https://qiita-image-store.s3.amazonaws.com/0/265258/f25d1707-518b-ce24-bd12-52e639b3f202.png)

学習が開始すれば成功です。
(こちらはかなり重いです…)

#まとめ
事前情報通り、小さなオブジェクトの検出精度がかなりいいです。
ただ本格的に使うとなるとそれなりのマシンスペックも必要になりそうですね。

次回は自前のデータセットを使用してモデルを作成したいと思います。

#おまけ
動画ファイルでデモを実行してみました。(YouTubeにジャンプします。)
https://youtu.be/LNrjiZrklKA

#参考
[M2Detを試してみた](https://qiita.com/K_ichijima/items/a415d3d03f91274da4f3)
[最新最強の物体検出技術M2Detを動かしてみた](https://qiita.com/kzykmyzw/items/c6a66e2c03c917cff36b)