OmniAICreator/Qiita-1.07M huggingface dataset:
スピル時代のExcel VBA(2)

# 初期化関数の定義
[前回](https://qiita.com/matumoto_onga/items/10f622687e152eaf8320)からの続きです。SPILLがInsiderだけでなく、一般に使用できる様になったら、Excel VBAの書法は、
大きく変化していくのでしょう。それに伴い、入門書も大幅に書き換えて欲しいと思います。
(入門書には、Option Explicitが奨励されていますが、VBAには無意味なので、
以下のプログラムには変数定義を行っていません。)
　今もまだ一般的でない、テーブルと構造化参照、Rangeと、Rangeと同等に扱える２次元配列について
詳しく見て行く必要があります。
　２次元配列を生成する関数L_INITをコンパクトにする為に、
Polymorphismを使いたいのですが、VBAではサポートされていません。
Polymorphism風にしたいので、TypeNameを使った関数を前もって定義します。

```vb
Function TN_(R)
    TN_ = TypeName(R)
End Function

Function TR_(R, Optional T = "Range")
    TR_ = (TypeName(R) = T)
End Function

Function TV_(R, Optional T = "Variant()")
    TV_ = TR_(R, T)
End Function

Function TS_(M, Optional N = "", Optional T = "String")
    TS_ = TR_(M, T) * TR_(N, T)
End Function
```

関数L_INITは、自分自身を呼び出すことにより、下記の様に簡潔に定義できます。
L_PAIRを弄っていたら、タイトルを付けられるようにしたかったので、
途中で、Elseif TS_(L1) Then ... を追加しました。

```vb
Function L_INIT(M, N, Optional L1 = 1, Optional L2 = 1, Optional S = "")
    On Error Resume Next
    If TR_(M) Then
        S = L_INIT(M.Rows.Count, N, L1, L2)

    ElseIf TV_(M) Then
        S = L_INIT(UBound(M, 1), N, L1, L2)
    
    ElseIf TS_(M, N) Then
        L = Split(M, " "): M = UBound(L) - LBound(L) + 1
        T = Split(N, ","): N = UBound(T) - LBound(T) + 1
        S = L_INIT(M, N, 0, 0)
        For I = 1 To M: S(I, 0) = L(I - 1): Next I
        For J = 1 To N: S(0, J) = T(J - 1): Next J
        
    ElseIf TS_(N) Then
        T = Split(N, ","): N = UBound(T) - LBound(T) + 1
        S = L_INIT(M, N, 0, 1)
        For J = 1 To N: S(0, J) = T(J - 1): Next J

    ElseIf TS_(L1) Then
        T = Split(L1, ",")
        N = UBound(T, 1) + 1
        S = L_INIT(M, N, 0, 1)
        For J = 1 To N: S(0, J) = T(J - 1): Next J
    
    Else
        ReDim S(L1 To M, L2 To N)
        For J = L2 To N: For I = L1 To M: S(I, J) = "": Next I: Next J
    End If
   
    L_INIT = S
End Function
```
# ２次元配列を抽象的に扱う為の関数
定義した関数L_INITを使って、ここでは、２つのRange(または２次元配列）を
横につなげる関数L_PAIRと、縦につなげる関数L_CONSを定義します。
関数的プログラムで抽象的に配列を扱うのに、見えてはいけないFor文を関数中に閉じ込めます。


```vb

Function L_RMN(R, M, N, Optional S = "")
    S = R
    M = UBound(S, 1) - LBound(S, 1) + 1
    N = UBound(S, 2) - LBound(S, 2) + 1
    L_RMN = S
End Function


Function L_PAIR(R1, R2, Optional S = "")
    On Error Resume Next
   
    S1 = L_RMN(R1, M1, N1)
    S2 = L_RMN(R2, M2, N2)
    M = WorksheetFunction.Min(M1, M2)
    N = N1 + N2
   
    S = L_INIT(M, N, L1, L2)
   
    For I = 1 To M
        For J = 1 To N1: S(I, J) = S1(I, J): Next J
        For J = 1 To N2: S(I, J + N1) = S2(I, J): Next J
    Next I
    L_PAIR = S
End Function

Function L_CONS(R1, R2, Optional S = "")
    On Error Resume Next
   
    S1 = L_RMN(R1, M1, N1)
    S2 = L_RMN(R2, M2, N2)
    N = WorksheetFunction.Min(N1, N2)
    M = M1 + M2
   
    S = L_INIT(M, N)
   
    For J = 1 To N
        For I = 1 To M1: S(I, J) = S1(I, J): Next I
        For I = 1 To M2: S(I + M1, J) = S2(I, J): Next I
    Next J
    L_CONS = S
End Function
```

色々、説明が足りてないが、まずはメモなので。
ビルド時に生成されるAPK/AABのファイル名を変更する方法

Android Studioで「Generate Signed Budle / APK」したときに生成される APK/AAB のファイル名。そのままでもそんな問題があるって訳でもないけど、所望のファイル名つけたいなって思いますよね。
知らない人が調べるのはしんどいと思うので、というか自分がしんどかったので、書きます。

# デフォルト状態

まずは、特段なにも指定しない場合にどうなるかをまとめてみます。

## APKの場合

### ビルドタイプのみの場合

```
/app/release/app-release.apk
```

モジュール配下に`[buildType]/`のディレクトリが作られ、`[module]-[buildType].apk` という名前のファイルになります。

### プロダクトフレーバーを設定している場合

```
/app/production/release/app-production-release.apk
```

モジュール配下に`[prodctFlavor]/[buildType]/`のディレクトリが作られ、`[module]-[productFlavor]-[buildType].apk` という名前のファイルになります。

## AAB (Android App Bundle) の場合

### ビルドタイプのみの場合

```
/app/release/app.aab
```

モジュール配下に`[buildType]/`のディレクトリが作られ、`[module].aab` という名前のファイルになります。

### プロダクトフレーバーを設定している場合

```
/app/production/release/app.aab
```

モジュール配下に`[prodctFlavor]/[buildType]/`のディレクトリが作られ、`[module].aab` という名前のファイルになります。

どちらにしてもAABの場合、モジュール名しか名前に反映されません。

# APKのファイル名を変更する方法

APKのファイル名を完全に制御する、スマートな方法はなさそうです。
以下のようにして指定することができますが、多分バージョンが変わるとこの方法では通用しなくなります。
また、この方法ではAABの名前は変更できません。
※ Gradle 4.10.3の時点で動作することを確認しています。

```gradle
android {
...
    applicationVariants.all { variant ->
        if (variant.buildType.name != "release") {
            return
        }
        variant.outputs.all {
            outputFileName = "hogehoge.apk"
        }
    }
}
```

作成されるディレクトリは変わらず以下のように生成されるファイル名が変わっています。

```
hogehoge.apk
```

「アプリ名＋バージョン名」みたいな名前にしたいので私は以下のように指定したりします。

```gradle
def applicationName = "Application"
def versionMajor = 0
def versionMinor = 0
def versionPatch = 1

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "net.mm2d.myapplication"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode versionMajor * 10000 + versionMinor * 100 + versionPatch
        versionName "${versionMajor}.${versionMinor}.${versionPatch}"
    }
    applicationVariants.all { variant ->
        if (variant.buildType.name != "release") {
            return
        }
        variant.outputs.all {
            outputFileName = "${applicationName}-${versionName}.apk"  // ←ココ
        }
    }
}
```

こうなります。

```
Application-0.0.1.apk
```

# AAB(Android App Bundle) のファイル名を変更する方法

AABの方が簡単です。
デフォルト状態でモジュール名が当てはめられていた部分の名前は`archivesBaseName`を指定することで変更できます。
以下のようにすると

```gradle
archivesBaseName = "hogehoge"
```

作成されるディレクトリは変わらず以下のように生成されるファイル名が変わっています。

```
hogehoge.aab
```

「アプリ名＋バージョン名」にしてみましょう。

```gradle
def applicationName = "Application"
def versionMajor = 0
def versionMinor = 0
def versionPatch = 1

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "net.mm2d.myapplication"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode versionMajor * 10000 + versionMinor * 100 + versionPatch
        versionName "${versionMajor}.${versionMinor}.${versionPatch}"

        archivesBaseName = "${applicationName}-${versionName}"  // ←ココ
    }
}
```

できました。

```
Application-0.0.1.aab
```

APKの場合も同様に、モジュール名部分が `archivesBaseName` で指定した名前に変化します。

```
Application-0.0.1-production-release.apk
```

APKの場合は、名前の後ろに`-[productFlavor]-[buildType]`がつきますが、これで十分な場合も多いでしょう。

こっちは技巧的な変更方法って訳ではないので、多分前述の方法よりは長く使えそうです。

以上です。
DNS移設時に気を付けるべきこと

# DNS移設って？
あまり頻繁には発生しないけど、DNSサーバを変更するときに(特に外部業者に委託しているケースとかで)起きるやつ。
オンプレからクラウドに持っていくときも起きるのかな。

いずれにせよ、自分のドメインの名前解決を行うサーバが変更される事。もっというと、権威DNSサーバの変更の事。
色々なところで、色々な人が、似たようなことを書いていると思うけど、
**移設前権威DNSサーバのNSレコード更新だけは忘れるな！！**

# 目次
　1.DNSの概要
　2.引っ越しの手順
　3.まとめ

# 1.DNSの概要
DNSには大きく2種類ある。
　・権威DNSサーバ(Authoritative DNS)
　・DNSキャッシュサーバ(resolveするから「リゾルバ」とも呼ぶ)
　　※日本語のせいで分かりにくいという説もある。俺もそう思う。

### 1-1 権威DNSサーバ？
「偉いDNSサーバ」くらいの意味。
そのドメインのIPアドレスを管理しているサーバのこと。
「URLをIPアドレスに変換する機能」を有したサーバ。

自分の管理下にあるサーバのURLとIPアドレスの対応表を持っているイメージ。
で、ユーザ側がそのURLにアクセスしに来た時に、IPアドレスを答えてあげるのがお仕事。

<例>　持っている対応表

| URL(FQDN)       |  IPアドレス |
|:-----------------|------------------:|
| web1.hoge.co.jp  | 333.1.2.3 |
| web2.hoge.co.jp  | 333.3.2.1 |


　問合せ：web1.hoge.co.jpのIPアドレス教えてください
　回　答：IPアドレスは333.1.2.3です


### 1-2 DNSキャッシュサーバ(リゾルバ)
「でも同じ企業なのに、毎回自分で問い合わせにいくのって非効率じゃない？」
って考えがあるのかは知らんけど、問い合わせに行く専用のサーバがいる。それがリゾルバ。(resolve(解決)してくれる人)
「どうせ専用なんだったら、しょっちゅう開くURLのIPとかは一時保存しといたほうが早くね？」という訳で、DNSのデータを一時保存(キャッシュ)してる。
だからDNSキャッシュサーバとも呼ばれる。


# 移設のステップ
　①移設元権威DNSサーバと移設先権威DNSサーバのレコード状態を同じにしておく
　**②移設元権威DNSサーバのNSレコードを移設先権威DNSサーバに向けておく**
　③親の権威DNSサーバーで、移設先を指し示す
　④TTLが切れるまで並行運用して、TTLが切れたら(古いDNSが使われなくなったら)古い方を捨てる

ポイントは②のステップ。多分①と③、④は対応してくれるはず。
(①はどうかな…同期してるのが一番いいんだけど…。)

### ②を行わないとどうなる？
例えば以下のケースがあったとする
移設前の権威DNSサーバ：ns1.hoge.co.jp
移設後の権威DNSサーバ：ns1new.hoge.co.jp

まず移設前の状態で"web1.hoge.co.jp"名前解決すると、DNSキャッシュサーバ的には以下の状態になる
　※TTL(Time To Live)とは、「どれくらいの間、その情報を保存するか」という数値。
　名前解決結果：web1.hoge.co.jp　333.1.2.3　TTL:300秒
　回答元　　　：ns1.hoge.co.jp　TTL:3600秒

当然、この状態で切替を行ったとしても、上記のキャッシュは残ったままになる。
問題なのはこの後。例えば400秒後に再度名前解決したとすると、
**キャッシュに回答元の情報を持っている為に、また古いサーバに聞きに行く。**
**場合によっては回答元のTTLが最新化されるから、一生新しいほうに向かない。**


# 3.まとめ
ざっくりと、DNSの概要と移設の大まかな流れ、その背景を書きました。
DNS周りのことも考える必要はあると思うけれど、何かの参考になれば。
5日目: LSTM Fully Convolutional Networks for Time Series Classification

# LSTM Fully Convolutional Networks for Time Series Classification 要約
## 読んだ論文
LSTM Fully Convolutional Networks for Time Series Classification
FAZLE KARIM, SOMSHUBRA MAJUMDAR, HOUSHANG DARABI, SHUN CHEN,
https://ieeexplore.ieee.org/document/8141873
上記の論文を読んだので簡単にまとめます．IEEE ACCESS, 6, 2018です．

## 3行でまとめる
- FCN (Fully Convolutional Networks)が時系列分類データ問題で強力な成果を上げている．
- FCNに対してAttention LSTMを並列で結合したモデル（LSTM FCN）を提案する．
- 85 UCR time series datasetsを用いて各種state-of-the-art手法と比較を行いおおむね精度で勝った．

## 提案手法
### 使用モデル
![20190317_001.png](https://qiita-image-store.s3.amazonaws.com/0/376859/e7a191d0-e92d-66c6-764e-24b49eb06c88.png)

- FIGURE1のようにシンプルなFCN（下段）に加えて，次元シャッフルして通常のLSTMかAttentionLSTMに接続される（これは普通のLSTMとAttentionLSTM両方で評価しているということ．ついでに転移学習（Refinementと書かれている）の評価も含めて4種類出している）．
- FCNとは全てConvで構成されるCNNである．
- 最終的にはFCNとLSTMそれぞれをGlobal Average PoolingしてconcatしてFully-connectedする．
- 次元シャッフルしないと早期に過学習して大幅に精度が落ちるらしい．
- また，次元シャッフルすることで学習速度が大幅に向上するらしい．

## 評価実験
- 85 UCR time series datasets[^1]を用いて提案手法を評価した．
- 各種state-of-the-artな手法と比較して少なくとも43データセットで提案手法の方が精度が高かった．
- 各種state-of-the-artな手法の精度はそれぞれのデータセットごとに引用してきている様子（Table1内で引用されている）．
- 続いて，Wilcoxonの符号順位検定で提案手法と各手法の検定を行っている．
 - 結果として提案手法は様々なベースライン手法[^2]と比較して有意差があった（符号は問わない）．
 - というか，この引用論文[^2]様々な手法で精度出してくれているのでBaselineを引用するのにとても使いやすそう．

[^1]: Y. Chenet al.(Jul. 2015).The UCR Time Series Classification Archive.[Online]. Available: http://www.cs.ucr.edu/~eamonn/time_series_data/
[^2]: Z. Wang, W. Yan, and T. Oates, ‘‘Time series classification from scratchwith deep neural networks: A strong baseline,’’ inProc. Int. Joint Conf.Neural Netw. (IJCNN), May 2017, pp. 1578–1585.

## まとめ
- 時系列分類問題において，FCNだけでなくLSTMを並列利用することで精度が上がることを提案した論文である．

## 所管
今回は1時間くらいで読めました．本稿の実験はGTX 1080Ti一つでやっている様子で，頑張ったなぁという印象です．ただ時系列分類は基本Conv1Dなのでそこまでマシンパワーに依存せずモデル検証ができます．
NotificationCenterでの複数の通知をコールバックで待ちあわせる

# はじめに
NotificationCenterでの複数の通知を待ちたいユースケースの実装例です。
複数の通知を待ち合わせ、すべての通知を受信した場合にコールバックを実行します。

# 使用例

```swift
NotificationWaiter.wait(for .someNotification) {
    // .someNotificationの通知を受信した時
}

NotificationWaiter.wait(for [.fooNotification, .barNotification]) {
    // .fooNotification, .barNotificationの通知をすべて受信した時
}
```

# サンプルコード

```swift
/// NotificationCenterでの通知を1度だけコールバックで待つためのクラス
public enum NotificationWaiter {
    /// 引数で指定したNotification.Nameが通知されるまで待ち、通知されたタイミングでcompletionを実行する
    ///
    /// - Parameters:
    ///   - name: 対象となる通知名
    ///   - notificationCenter: 通知センター
    ///   - completion: 通知を受信した際に実行するクロージャー
    static func wait(for name: Notification.Name,
                     notificationCenter: NotificationCenter = NotificationCenter.default,
                     completion: @escaping () -> Void) {
        var token: NSObjectProtocol?
        token = notificationCenter.addObserver(forName: name,
                                               object: nil,
                                               queue: nil) { _ in
                                                guard let token = token else { return }
                                                notificationCenter.removeObserver(token)
                                                completion()
        }
    }
    
    /// 引数で指定したNotification.Nameが全て通知されるまで待ち、全て通知されたタイミングでcompletionを実行する
    ///
    /// - Parameters:
    ///   - names: 対象となる通知名の配列
    ///   - notificationCenter: 通知センター
    ///   - completion: 全ての通知を受信した際に実行するクロージャー
    static func wait(for names: [Notification.Name],
                     notificationCenter: NotificationCenter = NotificationCenter.default,
                     completion: @escaping () -> Void) {
        let dispatchGroup = DispatchGroup()
        let dispatchQueue = DispatchQueue(label: "", attributes: .concurrent)
        
        names.forEach { name in
            dispatchGroup.enter()
            dispatchQueue.async(group: dispatchGroup) {
                wait(for: name) {
                    dispatchGroup.leave()
                }
            }
        }
        
        dispatchGroup.notify(queue: .main) {
            completion()
        }
    }
}
```
CDK(Chemical Development Toolkit)でSMILESを生成する

# はじめに
SDFファイルを読み込んでSMILESに吐き出すプログラムを作成した。併せてSMILES生成のオプションについても確認した。

# 環境
- Windows 10
- Java 11
- CDK 2.2

# ソースコード
以下のソースでできた。

```Sdf2Smiles.java
import org.openscience.cdk.DefaultChemObjectBuilder;
import org.openscience.cdk.smiles.SmiFlavor;
import org.openscience.cdk.smiles.SmilesGenerator;
import org.openscience.cdk.tools.manipulator.AtomContainerManipulator;

public class Sdf2Smiles {

    public static void main(String args[]){

        if(args.length!=1){
            System.err.println("Sdf2Smiles <sd-file>");
            System.exit(1);
        }
        FileInputStream fis = null;
        IteratingSDFReader isr = null;
        try{
            fis = new FileInputStream(new File(args[0]));
            isr = new IteratingSDFReader(fis, DefaultChemObjectBuilder.getInstance() );

            while( isr.hasNext() ) {
                IAtomContainer mol = (IAtomContainer) isr.next();
                String id = (String) mol.getProperty("cdk:Title");
                SmilesGenerator sg = new SmilesGenerator(SmiFlavor.Generic |SmiFlavor.UseAromaticSymbols);
                AtomContainerManipulator acm = new AtomContainerManipulator();
                try {
                    // sg.setUseAromaticityFlag(true);
                    String can = sg.create(acm.removeHydrogens(mol));
                    System.out.printf("%s\t%s\n", can, id);
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(isr != null) {
                try {
                    isr.close();
                }catch(IOException e2) {
                    e2.printStackTrace();;
                }
            }
            if(fis != null) {
                try {
                    fis.close();
                }catch(IOException e2) {
                    e2.printStackTrace();
                }
            }
        }
    }
}
```
結果はこんな感じ。

```
CCCCC	n-pentane
C1CCCC1	cyclopentane
CCCCCC	n-hexane
CCCC(C)C	2-methylpentane
CCC(C)(C)C	2,2-dimethylbutane
C1CCCCC1	cyclohexane
C1CCCC1C	methylcyclopentane
CCCCCCC	n-heptane
C1CCCCC1C	methylcyclohexane
CCCCCCCC	n-octane
```

# SMILES生成オプションについて
SmilesGeneratorのコンストラクタの引数によって、SMILESの生成方法を指定できる。

| オプション       |Canonical|  同位体または立体性をエンコード |
|:-----------------|------------------:|:---------------------:|
| SmiFlavor.Generic   |×|×|
| SmiFlavor.Unique    |○|×|
| SmiFlavor.Isomeric  |×|○|
| SmiFlavor.Absolute  |○|○|

上は代表的なものであるが、SmiFlavor.Stereoや、SmiFlavor.AtomicMass等により詳細なオプションを指定することも可能である。さらに、SmiFlavor.UseAromaticSymbolsによってAromatic記号を使うかどうかも指定できる。もっとも各原子が芳香環に属するかどうかは、IAtom#setIsAromatic等によって明示的に指定する必要がありそうだ。（そこが最も面倒なところなのだが。。)


# 参考文献
- [CDK 2.2 API Smiles Generator](http://cdk.github.io/cdk/2.2/docs/api/index.html?org/openscience/cdk/io/iterator/package-summary.html)
変数とは

# 変数とは
変数とは、**何か値を入れておく入れ物**だと思って下さい。

## 数学の変数とは違う
例えば、<br>
`x = 1`<br>
という式があるとします。<br>
数学では**『右辺』と『左辺』が等しい**。つまり、**xと1が等しい**という意味です。<br>
しかしプログラミングにおいての意味合いは違います。<br>
この場合であれば、**xという入れ物のなかに1という数字を入れておく**という意味になります。

## 変数のルール
- 変数名の先頭は小文字を使用する。
- Rubyで予め決められている予約語は使用できない。

- ルールではないですが、、変数名は分かりやすい名称を使いましょう。

## 変数を使用してみる

example<br>

入力

```rb
number = 5
puts(number)
```
出力

```rb
5
```
## 変数に入れる値は途中で変更できる
『変数』というくらいなので、中に入れる文字や数値は途中で書き換えることが可能です。

example1<br>

入力

```rb
number = 5
puts(number)
number = 10
puts(number)
```
出力

```rb
5
10
```
数値だったものを文字列に変更することも可能です。(文字列だったものを数値にすることもできます。)<br>

example2<br>

入力

```rb
number = 5
puts(number)
number = "こんにちは"
puts(number)
```
出力

```rb
5
こんにちは
```

## 変数を使った計算
<br>変数を使用して簡易的な計算プログラムを作成できます。<br>

example<br>

入力

```rb
x = 21000
y = 3000
puts x + y
puts x - y
puts x*y
puts x/y
```
出力

```rb
24000
18000
63000000
7
```
変数を使用して計算式を作ると、変数内の数字を変更するだけで様々な計算が出来るので便利です。

## 変数を交えた文字式を表示
文字式の中で変数を使用する場合は`#{}`で変数を囲みます。

example<br>

入力

```rb
name = "Seiya"
puts "私の名前は#{name}です。"
```
出力<br>

```rb
私の名前はSeiyaです。
```

ちなみに`#{}`を忘れると、、、<br>

入力

```rb
name = "Seiya"
puts "私の名前はnameです。"
```
出力<br>

```rb
私の名前はnameです。
```
[Rails]Viewでカテゴリーを色分けする方法

#概要
カテゴリーを作成し、日本語でカテゴリーを作っていた場合にviewのclassを付与して色分けをしたいと思ったため、
そのやり方を説明します。

かなりクソコードですので、他にもっといい方法を教えてください！

##付与するクラスにbackgrond-colorを指定します。

```category.scss
#色は適当です。
.business{
  background-color: #cc0000;
}
.medicine{
  background-color: #ccffff;
}
.nature{
  background-color: #34ce57;
}
.culture{
  background-color: #BBBBBB;
}
.art{
  background-color: #ff66ff;
}
.person{
  background-color: #f5f5dc;
}
.social{
  background-color: #333333;
}
.novel{
  background-color: #cc6600;
}
.computer{
  background-color: #9caeb7;
}
.test{
  background-color: #fdf5e6;
}
.nocategory{
  background-color: lightgoldenrodyellow;
}
```
##上記のcssを当てる条件分岐のhelperを作成します。

```reviews_helper.rb
module ReviewsHelper
  def translation_class_name(name)
    if name == "カテゴリーなし"
      name.gsub(name,"nocategory")
    elsif name == "コンピュータ"
      name.gsub(name,"computer")
    elsif name == "ビジネス"
      name.gsub(name,"business")
    elsif name == "医学・心理学"
      name.gsub(name,"medicine")
    elsif name == "生物・自然"
      name.gsub(name,"nature")
    elsif name == "教養・雑学"
      name.gsub(name,"culture")
    elsif name == "アート・スポーツ"
      name.gsub(name,"art")
    elsif name == "人物"
      name.gsub(name,"person")
    elsif name == "社会"
      name.gsub(name,"social")
    elsif name == "小説・文庫"
      name.gsub(name,"novel")
    elsif name == "コンピュータ"
      name.gsub(name,"computer")
    elsif name == "資格・試験"
      name.gsub(name,"test")
    end
  end
end

```

##viewで作成したhelperを読み込みます。

```index.html.haml
- @books.each do | book |
.card-head{class:"#{translation_class_name(book.category.name)}"} 

```
translation_class_nameの引数にbook.category.nameを渡し、gsubを使って文字列を置換しviewに表示することができます。

##以上
かなりのクソコードですが、card-headにclassを動的に付与することで、色分けをすることができるようになります。
Web ブラウザで Bluetooth デバイスをスキャンする

- Web Bluetooth を実装しているブラウザであれば、次のような非常に簡単なコードで Bluetooth デバイスをスキャンすることができます。
- 注意点として、ユーザのアクション（ボタンのクリック等）により、コードを実行する必要があります。（セキュリティの観点から、そのように仕様が定義されています。

```html
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>WebBleTest</title>
</head>
<body>

	<button onclick="scan()">scan</button>

	<script type="text/javascript">
	function scan() {
		navigator.bluetooth.requestDevice({
  		acceptAllDevices: true
		})
		.catch(error => console.log(error))
	}
	</script>

</body>
</html>
```

#参考
- https://webbluetoothcg.github.io/web-bluetooth/
Google Colabの無料GPUを使用する

現在、無料のTesla K80 GPUを使用してGoogle Colaboratoryディープラーニングプロジェクトをコーディングできます。 使用できるライブラリは、Keras、Tensorflow、PyTorchなどです。
![1_Kbta9F_ZiRQmvETa-JkOSA.png](https://qiita-image-store.s3.amazonaws.com/0/344186/30a7a908-1c69-1924-fa0f-9361b4e60901.png)
私は無料で学習目的でGoogle Colabを使用する方法をご案内します。
###Google Colabは何ですか。###
Google Colabは無料のクラウドサービスで、現在GPUを持っています。

次のことができます。

- Pythonコードの機能を向上させる。
- Keras、TensorFlow、PyTorch、OpenCVなどの有名なライブラリを使って機械学習アプリケーションを開発します。

すべて無料です。 以下に、データセットを保存するためにGoogle Driveと平行して使用する方法について詳しく説明します。
###Google DriveでGoogle Colabと連携するフォルダを作成します。###
![1_9x6GVBOwbAEsx7h8k5ruBw.jpeg](https://qiita-image-store.s3.amazonaws.com/0/344186/991f49f9-367e-7a4c-3559-5ebabc57b95e.jpeg)

Colabはグーグルドライブ上で動くことができるので、私達がコードするフォルダーを作るでしょう。 ドライブに 「app」というフォルダを作成しました。 もちろん、何でも構いません。
![1_vtTvpFVdCcsmEXtQA6k2Kw.png](https://qiita-image-store.s3.amazonaws.com/0/344186/fce6c2ae-74bd-c670-869c-74a3f408cd49.png)

###新しいColab Notebookを作成する###
イメージのようにしてくだいさい：
![1_7XLisHAnGGnflIYyqQja8Q.jpeg](https://qiita-image-store.s3.amazonaws.com/0/344186/cda99698-dfa3-c843-f988-f9b6e2ae1d09.jpeg)
そして名前を変更します。
![Screenshot from 2019-03-17 22-01-55.png](https://qiita-image-store.s3.amazonaws.com/0/344186/76bb5dcf-1a22-7249-c025-2b734cba45f2.png)

これまでにPythonをやったことがない場合は、始めるための基本的な手順は次のとおりです。それらの動作メカニズムはNoteBook形式であるため、youtubeでいくつかのJupyter Notebookチュートリアルを見るべきです。
###GPUモードをオンにする###
単純すぎますね。**Edit > Notebook settings** あるいは **Runtime>Change runtime type**を選んで **GPU as Hardware accelerator**も選ぶことができます。
![1_WNovJnpGMOys8Rv7YIsZzA.png](https://qiita-image-store.s3.amazonaws.com/0/344186/090f7fd0-b06c-9050-2a72-d3d028bba6be.png)
###いくつかの単純な行をコーディングする###
![1_02ylPr7JIn_qiJkc4iprpw.png](https://qiita-image-store.s3.amazonaws.com/0/344186/e67730ea-26cc-860b-f254-8e4580694035.png)
走れ！ セル内のコードはセルの真下に表示されます。 より具体的には、自分で見つけることができます。
単純すぎますね。

もっと多くの情報を必要とするならば、電子メールhungph.dev.ict@gmail.comを通して私に連絡してください。
TextViewの一部にリンクをつける

### SpannableStringBuilder
* ハイライトしたい文字列とTextViewに入れる全体の文字列を定義
* `SpannableStringBuilder#setSpan`で`ClickableSpan()`を呼び出し
    * onClickにてIntentを指定
    * updateDrawStateにて色を指定

```kotlin
private fun createLinkSpannable(): SpannableStringBuilder {
    val highLightText = getString(R.string.high_light_text)
    val introductionText = getString(R.string.introduction_text)

    val spannableTextBuilder = SpannableStringBuilder(introductionText)
    val startPos = introductionText.indexOf(highLightText)
    return spannableTextBuilder.apply {
        setSpan(object : ClickableSpan() {
            override fun onClick(view: View) {
                val intent = Intent(Intent.ACTION_VIEW, Uri.parse(URL))
                    view.context.startActivity(intent)
                }

                override fun updateDrawState(ds: TextPaint) {
                    super.updateDrawState(ds)
                    ds.color = ContextCompat.getColor(this@MainActivity, R.color.colorAccent)
                }
            }, startPos, startPos + highLightText.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        }
}
```

### TextView
* textに上記のSpannableを指定
* movementMethodを指定

```MainActivity.kt
link_text.apply {
    text = createLinkSpannable()
    movementMethod = LinkMovementMethod.getInstance()
}
```

こんな感じになります
<img width="250" alt="スクリーンショット 2019-03-17 23.45.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/260353/9672b354-b7da-7b15-3016-6ac92479ed79.png">


レポジトリは[こちら](https://github.com/sudo5in5k/linkspannable)
ReactJS のコンポーネント

#１．コンポーネントの定義
ReactJSでは小さなコンポーネントで使って、サイトが構築することができる。コンポーネントをさまざまな状態や属性で、さまざまな場所で再利用できて、コンポーネント内に別のコンポーネントを含めることがある。ReactJSの各コンポーネントは別々のステータスを持って、変更することができる。Reactはステータスの変更に基づいてコンポーネントのアップデートを実行します。コンポーネントはReactの最も重要な成分の1つです。したがって、方法と操作方法とおよび方法の役割が理解できることが必要です。

#２．コンポーネントの機能・メソッド一覧
- constructor(props) :
 - コンポーネントのstateの設定を行う。
 - super(props)を使うことの意味はコンストラクタ関数内でthis.propsが使用できるようになる。

```react:qiita.js
constructor(props){
   super(props)
   }
```

- componentWillMount() :
 - いくつかのタスクを実行すると、この関数はレンダリングが行われる前にクライアントとサーバーの両方で一度呼び出される。

- componentDidMount() :
 - いくつかのタスクを実行すると、この関数はレンダリング後にクライアント方で一度だけ呼び出される。
 - この関数はMapを使うときに非常に便利のだ。DOMにnode(id)があるときだけMapがレンダリングできるからのだ

- componentWillUnmount() :
 - 一度だけ実行して、コンポーネントがunmountする時、コンポーネントが終る前にこの関数は呼び出される。
 - この関数は、未使用のタイマーを削除する必要があるときに便利のだ。
 
- componentWillReceiveProps(nextProps) :
 - この関数はpropsが変わるたびに実行される

- shouldComponentUpdate(nextProps, nextState) :
 - この関数はpropsとstateが変わるたびに実行される。
 - この関数はtrue / falseを返する。コンポーネントを更新する必要がある場合は、この関数を使って処理する必要がある。

- componentWillUpdate(nextProps, nextState) :
 - この関数はshouldComponentUpdate関数の結果に基づいて動作する。shouldComponentUpdate関数がfalseを返した場合、Reactはこの関数を呼び出さない。

- componentDidUpdate(prevProps, prevState) :
 - この関数は、componentWillUpdateの結果から、コンポーネントが再度レンダリングされた後に実行される。

- render() :

```react:qiita.js
render() {
            return (
              <div>
                //　レンダリングが行われる
              </div>
            );
          }
```
Docker 使い方 メモ

Dockerの使い方を勉強し始めたので、よく使うコマンドを記録しておく。

# Dockerイメージ操作
```
Dockerイメージのダウンロード
$ docker pull <イメージ名>

Dockerイメージの確認
$ docker images

Dockerイメージの削除
$ docker rmi <イメージ名>

Dockerイメージの作成
$ docker commit <コンテナ名>
```

# Dockerコンテナ操作

```
Dockerコンテナの確認
$ docker ps -a

Dockerコンテナの起動
$ docker run -d --name <コンテナ名> --network <ネットワーク名> <イメージ名>

Dockerコンテナの停止
$ docker stop <コンテナ名>

Dockerコンテナ内でのコマンド実行
$ docker exec -it <コンテナ名> <コマンド>

Dockerコンテナの削除
$ docker rm <コンテナ名>
```
ウェブサイトで使われている技術を確認できるChrome拡張が便利

ウェブサイトで使われている技術を確認できるChrome拡張が便利なので紹介します。

## ウェブサイトで使われている技術を確認できるChrome拡張が便利
[Wappalyzer](https://chrome.google.com/webstore/detail/wappalyzer/gppongmhjkpfnbhagpmjfkannfbllamg?hl=en)というChrome拡張が便利です。例えばQiitaを見ると、
<img width="473" alt="Screen Shot 2019-03-17 at 23.48.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/250231/dc560b21-731c-e690-9910-5f3c6978e450.png">

このように表示されます。ぜひ使ってみてください。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
GeoLiteのLegacy版datがダウンロードできなくなったのでなんとかする話

# GeoLite IPのdatはもうないんだってさ

これまで使っていたGeoIPタダ版（GeoLite IP）のdatファイルが404 Not Foundになってた。
下記に説明があるように、2019年1月2日から使えないらしい。
https://support.maxmind.com/geolite-legacy-discontinuation-notice/
古い形式はもう扱わないからGeoLite2に移行しろとか書いてある。

GeoLite2は下記のからダウンロードできるが、、、
https://dev.maxmind.com/geoip/geoip2/geolite2/

![1.png](https://qiita-image-store.s3.amazonaws.com/0/367048/b1d50208-4327-35ad-b893-081defa617ae.png)

ダウンロードできるのはMaxMind DB形式かcsv形式となっている。古い形式であるdatはもういない。
困った。今動いている既存アプリのソースをいじるのは面倒だ。

# ググればなんとかなる

世の中には同じように困って、何とかしてくれる親切な人がたくさんいる。
ググったら下記のツールを見つけた。
https://github.com/sherpya/geolite2legacy

ありがたく使わせてもらうことにする。
使い方はそのままExamplesに書いてある通りにやればOKだった。

```
[root@cent7 ~]# git clone https://github.com/sherpya/geolite2legacy.git 
[root@cent7 ~]# cd geolite2legacy/  
[root@cent7 geolite2legacy]# pip install -r requirements.txt
[root@cent7 geolite2legacy]# wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-City-CSV.zip
[root@cent7 geolite2legacy]# wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country-CSV.zip
[root@cent7 geolite2legacy]# wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-ASN-CSV.zip
[root@cent7 geolite2legacy]# ./geolite2legacy.py -i GeoLite2-City-CSV.zip -f geoname2fips.csv -o GeoIPCity.dat
[root@cent7 geolite2legacy]# ./geolite2legacy.py -i GeoLite2-Country-CSV.zip -f geoname2fips.csv -o GeoIP.dat
[root@cent7 geolite2legacy]# ./geolite2legacy.py -i GeoLite2-ASN-CSV.zip -o GeoIPASNum.dat
[root@cent7 geolite2legacy]# cp *.dat /usr/share/GeoIP/
```

以上。
AWS 認定ソリューションアーキテクト アソシエイト合格(2019/3/17) 

# 経緯
AWS SAAに合格した為、勉強方法を忘備録として記載します。
何となく2018年度内に取得しようと2月中旬に思い立ちました。
以下、元々の経験値と勉強方法、問題の傾向を記載します。
あくまで参考としてお読み下さい。

## AWS経験値

### AWS案件
AWS案件：5か月くらい

### 使ったサービス

- EC2
- Route53(一瞬の設定変更のみ)
- Lambda(Python3)
- AWS Config
- GuardDuty
- Inspector
- CloudFormation
- CloudWatch Logs/Events
- S3
- Aurora(インスタンス建てて、削除くらい)

CloudWatchをトリガーにLambdaでJSONを整形してSNS通知が主で、
CloudFormationで自動構築したりしてました。

## 学習
資格取得を思い立ったのが、おそらく2019/2/16くらい?
受験日が2019/3/17
約一ヵ月(平日0～2時間、土日5-7時間)

### 参考書類
- 徹底攻略 AWS認定 ソリューションアーキテクト – アソシエイト教科書 徹底攻略シリーズ
出版社：インプレス
- 最短突破　AWS認定ソリューションアーキテクト　アソシエイト　合格教本 出版社: 技術評論社
- AWS WEB問題集で学習しよう 

### 学習方法
①いわゆる一冊目の黒本を最初に読んで模擬試験をやりました。
②AWSの模擬試験を実施したら58%・・・
　いろんなところで記載がありますが、二回受けることができないので、
　メモしながら受験すると、後程実力を測るのにいいと思います
③黒本は試験の出題ジャンルに沿って記載されている為、同じサービスの説明が断続的に出てきます。
　個々のサービスを網羅的に理解がしづらかったので二冊目の参考書を購入しました。
　こちらはAWSサービス毎の記載であった為、サービス単位での理解を深めることができました。
④通勤時間にWeb問題集を解きました。全部は説きませんでした。(1-70、103-117)
　途中抜けているのは、最近更新された問題の方が更新スピードの速いAWSサービスや
　試験にマッチしているのかなと思ったからです。(特段根拠はありません)
⑤参考書についてきた模擬試験を受け、よく間違えるサービスのページを読み直したり、
　ブラックベルトを読んだり、ノートにまとめました。

### 今思うと
上から
最短突破　AWS認定ソリューションアーキテクト　アソシエイト　合格教本
徹底攻略 AWS認定 ソリューションアーキテクト – アソシエイト教科書 徹底攻略シリーズ
Webテスト(通勤とか机に向かえない時間)
模擬問題
ブラックベルト or 間違い箇所まとめ
模擬問題
の順番が各サービス理解して、弱点を埋める方法が良いのかなと思います。

## 試験内容
### 細かな仕様と他のサービスとの組み合わせでの用途を問われたサービス

- EC2(コスト削減、オートスケーリング)
- セキュリティグループ、アクセスコントロールリスト
- S3
- EBS
- ELB
- Route53
- RDS
- Aurora
- Dynamo

### 他のサービスとの組み合わせでの用途
- SQS
- kinesis
- Lambda
- API Gatway
- Redshift
- ECS
- ElastiCache

# 最後に
今回の資格は触ったことのあるサービスが多々あったので、
業務経験のないLPICの時と比べてだいぶ楽でした。
業務経験ってとても大事ですね。(本来の資格はそれが正しいと思いますが)
それでもきちんと理解せず使っていたところが露呈し、
模擬問題で撃沈するなど大変だった部分もあります。

AWSサービスの理解とどの用途で何と何を組み合わせるかを理解できれば
合格できるかと思います。勿論保障はできませんが。
どなたかの参考になれば幸いです。

## 個人的な忘備録
試験前日の参考書模擬問題が59/65
自信のある問題が53/65
合格ライン720点
スコア879点
見直しなしの残り時間が68分
見直し後の残り時間が40分くらい
Reactのinput（arrayのstateを更新し複数inputへ伝播）

https://qiita.com/y_ohr/items/616496f6262951a00d51 の続きです。

# 環境
```
Ubuntu 18.04.2 LTS
node v8.10.0
npm 3.5.2
create-react-app v2.1.5
```

# ３行まとめ
- array.map()でDOMをレンダリングした
- レンダリングされたinputのonChangeから、stateのarrayを更新するのに苦戦した
- とりあえずUIはできた

# arrayのstateを更新し複数inputへ伝播するように修正

diffが多いので、全文掲載。

```react:src/index.js
import React from 'react';
import ReactDOM from 'react-dom';

class Square extends React.Component {
    constructor(props) {
        super(props);
        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(e) {
        this.props.onNumberChange(e.target.value);
    }

    render() {
        return (
            <input
                type="text"
                value={this.props.number}
                className="square"
                onChange={this.handleChange}
            >
            </input>
        );
    }
}

const xyData = [
    { x: 0, y: 1 },
    { x: 3, y: 4 },
    { x: 6, y: 7 },
];

class Board extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            xyData
        };
    }

    renderSquare(i, m) {
        return <Square number={i} onNumberChange={m} />;
    }

    toNumber(n) {
        return n * 1;
    }

    render() {
        const title = 'XY加算機';
        const xyData = this.state.xyData.slice();
        return (
            <div>
                <div className="title">{title}</div>
                {xyData.map((value, i) => (
                    <div className="board-row">
                        {this.renderSquare(value.x,
                            (e) => {
                                xyData[i].x = e;
                                this.setState({ xyData });
                            })
                        }
                        +
                        {this.renderSquare(value.y,
                            (e) => {
                                xyData[i].y = e;
                                this.setState({ xyData });
                            })
                        }
                        =
                        {this.renderSquare(this.toNumber(value.x) + this.toNumber(value.y))}
                    </div>
                ))}
            </div>
        );
    }
}

class Game extends React.Component {
    render() {
        return (
            <div className="game">
                <div className="game-board">
                    <Board />
                </div>
                <div className="game-info">
                    <div>{/* status */}</div>
                    <ol>{/* TODO */}</ol>
                </div>
            </div>
        );
    }
}

// ========================================

ReactDOM.render(
    <Game />,
    document.getElementById('root')
);
```

# 感想

- StateのArrayを永続化して、複数クライアントから同時更新すると、当初の目的だった、SPAにおけるDB排他の辺りを調べられそう？
- 長い前段だったけれど、いろいろと、とても勉強になった
- AngularやVueも調べてみたい

以上
BigQueryで別のプロジェクトのデータセットの中身を叩く

メモ書き。

1. クエリを叩くプロジェクト（Aとする）でサービスアカウントを作る
1. プロジェクトAでサービスアカウントにBigQuery管理者権限を付ける
1. データを持っているプロジェクト（Bとする）で、↑で作ったサービスアカウントにデータ閲覧者権限を付ける（やり方参考→https://qiita.com/kndt84/items/96a8df3d00efd9d6de0d）
1. プロジェクトAの旧UIのページで、プロジェクトBを表示する。何を言っているのかわからんと思うが、左のメニューのプロジェクト名の横の▽とかから表示させられるはず
1. プロジェクトAで from `プロジェクトB.dataset.table` する
ABC087 C - Candies (300点)

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

$2×N$のマスにそれぞれ数字がある。
$(1,1)$のマスから出発して、右方向か下方向への移動をし$(2,N)$まで行く。マスを通る時にマスの数字の和をとっていく。和が最大値となるように移動した時の和の値を求めよ。

#制約条件

- $1\leqq N\leqq 100$
- $1\leqq A_{i,j}\leqq 100(1\leqq i\leqq 2, 1\leqq j\leqq N)$


#考えたこと
行数は$2$行なので、下方向への移動は一回しかない。$i$マス目で下方向に移動とすると、$1 \sim i$まで1行目の右方向に移動、$i$で下方向に移動、$i \sim n$まで右方向に移動となるので、移動ルートは列数によって決まり$n$通りである。
よって、1行目の$１ \sim i$マス目と2行目の$i \sim n$マス目までの移動の和を$n$回とっていけばよい。

とった和を配列につめていき最大値が答えである。

入力例1で実験すると以下のようになる。
>5
3 2 2 4 1
1 2 2 2 1

|下に移動するマス($i$)|$sum(１\sim i)$|$sum(i \sim n)$|総和|
|:-:|:-:|:-:|:-:|
|1 |3  |8 |11 |
|2 |5  |7 |12 |
|3 |7  |5 |12 |
|4 |11 |3 |14 |
|5 |12 |1 |13 |


#解答

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

class Program
{
    static void Main(string[] args) {
        int n = int.Parse(Console.ReadLine());
        int[] a1 = Console.ReadLine().Split().Select(int.Parse).ToArray();
        int[] a2 = Console.ReadLine().Split().Select(int.Parse).ToArray();
        int[] result = new int[n];
        for (int i = 0; i < n; i ++) {
            result[i] = a1.Where((x,y) => y<=i).Sum() + a2.Where((x,y) => y>=i).Sum();
        }
        Console.WriteLine(result.Max());
    }
}
```

実装に関しては以下のように書くと簡単に書ける。
$Where((x,y) => y<=i)$ で、配列のインデックスが$i$以下の部分を取得できる。

```.cs
for (int i = 0; i < n; i ++) {
  result[i] = a1.Where((x,y) => y<=i).Sum() + a2.Where((x,y) => y>=i).Sum();
}
```
FlexBoxの個人的まとめ

# FlexBoxとは

1次元のレイアウトモデルです。
->　ポイントは、行か列（縦か横）のどちらかしかレイアウトを選べない事です。

# FlexBoxの構成
「Flexコンテナー」と「Flexアイテム」から成り立ちます。
Flexボックスの領域が「Flexコンテナー」で、その子要素が「Flexアイテム」になります。
-> `display: flex`が指定された要素が「Flexコンテナー」になります

# レイアウトの考え方
## Flexコンテナー

###ベース
Flexコンテナーでは、2つの軸を考える必要があります。
1つは主軸（main axis）、もう1つは交差軸（cross axis）です。

主軸は`flex-direction`によって定義されます。プロパティは4つです。
これらのプロパティで、**主軸の向き**と、コンテンツの**始点**が決まります。
主軸の向きはFlexアイテムレイアウトの**縦/横方向**、始点はFlexアイテム**表示順**になります。

| プロパティ      |軸の方向 |    始点と終点    |
|:--------------|:---------------:|:----------------|
| row |インライン要素の並ぶ方向（横） |左から　（A,B,C）|
| row-reverse |インライン要素の並ぶ方向（横） | 右から　（C,B,A）|
| column|ブロック要素の並ぶ方向（縦） |上から|
| column-reverse |ブロック要素の並ぶ方向（縦） | 下から|
参照：https://developer.mozilla.org/ja/docs/Web/CSS/flex-direction

### 折り返し
折り返しのプロパティを設定していない場合、flexアイテムはflexコンテナからはみ出します（オーバーフロー）。

折り返す為には`flex-wrap`を指定します。valueは`wrap`になります。
参照：https://developer.mozilla.org/ja/docs/Web/CSS/flex-wrap

###アイテムの位置

#### align-items
交差軸におけるFlexアイテムの位置合わせを定義します。
初期値（`stretch`）の場合、Flexアイテム内のもっともheightが高いアイテムと同じ高さまで伸長します。
よく使用されるのは`center`で、**垂直センタリング**したい場合に使用されます。

#### justify-content
主軸でのアイテム配置を定義します。
初期値は`start`なので、`flex-direction`で決定した主軸の向きと始点からアイテムが設置されます。
良く使用されるのが、

- 右寄せしたい場合に`flex-end`
- コンテンツの端に余白を割り当てる`space-around`
- コンテンツの端に余白を割り当てない``space-between

などがあります。

参考：https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Flexible_Box_Layout/Aligning_Items_in_a_Flex_Container



## Flexアイテムのサイズに関するもの

flexコンテナでコンテンツの向きは決定できますが、FlexBox内のstyleはflexアイテムで決定します。

| プロパティ      |       内容    |
|:--------------:|:----------------:|
|    flex-basis    |itemのサイズを決めます。|
|    flex-grow    |itemのflex-basisを拡大します|
|    flex-shrink    |他のitemと比較して、itemがどれだけ縮小されるかを指定します。|


### flex-basis
`flex-basis`はアイテムのサイズを定義します。
もしこれが定義されていない場合は、flexアイテムのコンテンツ自体のサイズが`flex-basis`の値として使用されます。

### flex-grow
flexコンテナ内に余白が存在していた場合、このプロパティの値によって余白が、そのアイテムのflex-basisに追加されます。
実際のページでは、flexコンテナのサイズに応じて拡大するように見えます。

例：アイテム全ての`flex-grow`を1にした場合。
余白部分を均等に分けて、それぞれのアイテムのbasisに追加します。

例：アイテム1つのgrowを2、残りのアイテム2つのgrowを1にした場合、
growを2にしたアイテムに余白の半分（2分の一）、growを1にしたアイテムに各4分の1の余白を追加します。

### flex-shrink
`flex-shrink`に正の数字が設定されている場合、他のアイテムより大きな割合で`flex-basis`が縮小します。
より大きな数字が指定されているアイテムほど、他のアイテムより大きな割合で縮小します。


---
# 最後に

ざっくりとまとめてみました。
flexboxには、まだまだやれる事はあります。

ただ、flexboxを使用する場合で大事なのが1次元である事です。
例えば、flex-wrapで折り返しを出来るようにした場合、コンテンツが左右によるような表示になります。（すでにtipsが存在しています）。
もし複数行になるようなレイアウトを作りたい場合は、縦横を定義できる**[Grid](https://developer.mozilla.org/ja/docs/Glossary/Grid)**の使用を検討してください。

---
# 参考
CSS フレックスボックスレイアウト
https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Flexible_Box_Layout

フレックスボックスの基本概念
https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox
モブプログラミング・ベストプラクティス（を読んだ）

# 読んだ本

- [モブプログラミング・ベストプラクティス](https://www.amazon.co.jp/%E3%83%A2%E3%83%96%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%83%BB%E3%83%99%E3%82%B9%E3%83%88%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9-%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AE%E5%93%81%E8%B3%AA%E3%81%A8%E7%94%9F%E7%94%A3%E6%80%A7%E3%82%92%E3%83%81%E3%83%BC%E3%83%A0%E3%81%A7%E9%AB%98%E3%82%81%E3%82%8B-%E3%83%9E%E3%83%BC%E3%82%AF%E3%83%BB%E3%83%91%E3%83%BC%E3%83%AB/dp/4822289648/ref=tmm_hrd_swatch_0?_encoding=UTF8&qid=&sr=)

# この記事を書いた人はこんな人です

- モブプログラミングなるものがあると知って、動画なりSlideShareなりを漁ってどんなものか学んだ
- 学んだ後に実際にやってみて、理想と現実をちょっとだけ思い知った

# 学習教材

1. https://www.youtube.com/watch?v=p_pvslS4gEI
2. https://qiita.com/TAKAKING22/items/31e027dfb6ea8b1a8d69
3. https://speakerdeck.com/takaking22/mob-programming-startup-manual-number-mobprogramming-number-mobupuro

とかとか。。。

# 思い知った理想と現実の差

- 理想
    - コミュニケーション取りながら、作業するだろう
    - 効率よく進むからきっと楽しい
- 現実
    - なかなか会話が弾まない
    - 戸惑うことの方が多かった
    - 時間内に終わらなくて、不完全燃焼

# 自分で振り返る

- 全部に適用するかどうかはチーム次第なところもあるけど、使い所として全体効率が上がるような箇所でやるといいよね、みたいな話ができたのはよかった
- Timebox決めたけどなかなか守れないね
- ドライバーとナビゲーターの役割についてうまく説明できてなかったから、チームメンバーは困っていたかも
- 初回は話せなかったけど4回目ともなるとそこそこ会話がでてきて、色々な話がでていた
- 全く知らない人・ちょっとだけ知ってる人・それなりに知っている人だと、それなりに知っている人がほとんど話をしていた

# さらに振り返った内容を掘り下げてみる

- 戸惑ってるところが多そうだし、もっと前提や想定・何を目的としているかといったところをはっきりさせてあげた方が良さそう
- Timeboxの考え方はとても重要だしタイムキーパーよりももっと非情になってやった方が良さそう
- ドライバーの基準、ナビゲーターの基準を前提として用意しておこう
- 参加者のスタンスを明確にできた方が良さそう

# そんな状態で書籍を読んでみた

## 第一章

- 「上層部からのお墨付きのもらい方」1.3のところは必読
- 自分で知ったとか、やってみたいとか思っている人はこの辺求められると思います。
- そもそもチーム内からもでるはずなので必読です

## 第二章

- この本だとタイピストとその他のモブという呼び方だけど、それぞれの役割が解説してあるのでやっぱり飛ばしてはいけない
- 「その他のモブの仕事」のところは私の困っているところに当てはまりました
- インターバルはTimeboxから逆算してやってましたけど、基本が理解できるのでよかった

## 第三章

- 読み飛ばしそうなところではあるけど、結局やるのは人だよ、人がやることを想定していますか？というのを問うている章
- 多分ここを読み飛ばすとうまくいかないチームの出来上がり。読み飛ばしてはいけない
- すっとばしていた点もあるので振り返って導入していきたい

## 第四章

- **エキスパートがいるモビング** これが書いてある
- 絶対に読み飛ばしてはいけない
- 初めてやる分野であったり、単純作業が続くような場合についても書いてある

## 第五章

- 環境は大事
- モブプログラミングだけでなくて、いつも使いたい環境にできるので読み飛ばしてはいけない
- 環境が用意できなかったら、優れたチームであっても人がいなくなっていく（戒め）

## 第六章

- やるぜーうえーい、で定着したら世話ないという話
- ここで非常に苦労しているので読み飛ばしてはいけない
- 有意義な時間にするための、始め方・進め方・さらには開発プロセスについてもアドバイスがある
- 読もう

## 第七章

- 布教していく立場であれば必読、つまり読み飛ばしてはいけない
- 効率悪いといわれたときに、「あなたがやっている方法がなぜ効率がよいと言い切れるのですか」と言い返すための材料になる

## 第八章

- 丁度新卒という新メンバーが参加したこともあり、大いに参考になる。読み飛ばしてはいけない
- 絶対モビング！というとらわれ方をしている場合にも役立つ。読もう。


# まとめ

- 布教者は読もう
- 躓いた時の解決策になるよ
- 横の人が何やってるか知らない、っていう状況が嫌な人はぜひ読んでみて

# 次のアクション

- 自分のチームでやってるモブプログラミング用の資料をつくる
- 今の課題を解決できる完璧な資料が作れるが余白が足りない
XAMPP を捨てて Vagrant に乗り換えるときにやったこと

バックエンド案件のXAMPPでの開発に不満を感じ、Vagrantに乗り換えるまでに試行錯誤しながらやったことの覚書になります

![名称未設定 1.png](https://qiita-image-store.s3.amazonaws.com/0/242655/00d45fec-3a3d-5c6d-95bb-2aedb66b1099.png)

## XAMPP の代わりになる開発環境の検討
案件で利用できるレベルの開発環境を探す

### XAMPP への不満の洗い出し
- 複数案件にかかわると、複数バージョンの XAMPP をインストールする場合がある
    - XAMPP がどんどん増えていって、気持ち悪い
    - ディスク容量を消費する
- XAMPP に含まれないミドルウェア (PostgreSQLなど) を使う場合、別途インストールする必要がある
    - 環境の起動をそれぞれ手動で行うのが手間
    - Windows 用の環境構築手順しか残ってない
- XAMPP の設定を変更して利用する場合がある
    - 手順書をたよりに手動で設定
    - 個人の環境によって動かないことがある

### 乗り換え先の要件整理
- 誰でも簡単に環境構築できる
- ランニングコストがかからない
- Apache, PHP, MySQL 以外のミドルウェアも使える
- ディスク容量をあまり消費しない（再構築が簡単であれば、優先度：低）
- マルチプラットフォームである (Windows/macOSで動作する)

### 乗り換え先の検討
- [Docker](https://www.docker.com/)
    - 最近流行ってきてる
        - 自分の周りでは、まだ本番環境でDockerが導入される流れはないので、開発環境構築のためだけの知識になってしまう 
    - Windows/macOS/Linuxで動く
    - 新しいミドルウェアを入れる場合、Dockerイメージを作らないといけない
        - 多くのDockerイメージが公開されているが、品質の問題やセキュリティのリスクであまり使いたくない
- [Vagrant](https://www.vagrantup.com/)
    - 最近流行ってきてる
    - Windows/macOS/Linuxで動く
    - [Scotch Box](https://box.scotch.io/) などの構築済みBoxを使えば、ある程度の環境は簡単に用意できる
        - 品質の問題やセキュリティのリスクであまり使いたくない
    - 環境構築の手間を省くために、環境構築済みの仮想マシンイメージを保管、展開する必要がある
        - 環境構築済みの仮想マシンイメージを作るために、インフラ構築の知識がいる

以下の理由から **Vagrant** に決定！

- 本番環境に近い構成が実現できる
- 得たノウハウが実際のインフラ構築に活かせる

### 残課題の確認
- Boxの品質の問題やセキュリティのリスク
- Boxイメージの保管、展開

安全でプレーンなBoxを確保し、案件に応じて**"自動的に"**構築すればいい （**構成管理ツール**の採用）

### 構成管理ツールの検討
- [Chef](https://www.chef.io/chef/)
- [Ansible](https://www.ansible.com/)
- [Puppet](https://puppet.com/)

以下の理由から **Ansible** に決定！

 - 一通り触ってみて、一番学習コストが低い
 - 開発が活発
 - エージェントレス
   - 構築するサーバに、Ansibleのエージェントをインストールする必要がないため、本番環境への導入の敷居も低い

### プロトタイプの作成
ベースになるものを作ってみた
https://github.com/ohnaka0410/Vagrant-Ansible-Prototype

## 乗り換えの推進
自分だけ乗り換えるわけにはいかないので、他の人にも使ってもらう

### 導入実績を増やす
- 新規案件を中心に、プロトタイプをカスタマイズして配る
- 興味を持ってくれた人にカスタマイズの方法をレクチャーする

### だれでもカスタマイズできるようにする
- Webフォームで構成をカスタマイズし、ダウンロードできるようにする （着手中）

### 品質の担保
以下のような、自動テストツールの導入を検討中
- serverspec
- AnsibleSpec

## おまけ
- **Vagrant**は、ローカルの仮想マシンだけでなく、プラグインを利用してAWSのEC2などのクラウドサーバの管理もできる
- **Ansible**は、リモートサーバに対して実行できるので、本番環境や検証環境にできる
【学習記録】JS(ES6)の機能、node.jsインストール、jQuery基本、Bootstrap基本


ここ２日でやったことを忘れないうちにざっくりと記録。

###筆者の状況
プログラミング初心者（HTML・CSS、JavaScript、Ruby、PHP、Pythonの基本だけ学んだ）
JavaScriptのフレームワークに手を出し始めている段階。

##1. JavaScript(ES6)の学習
###インプット
[Progate](https://prog-8.com/)のJavaScript(ES6)レッスン4～6を１周

###学習内容
- クラス（設計図）からオブジェクトをつくる概念と手法
- インスタンス生成直後に行われるコンストラクタの処理
- クラスの継承
- constructorのオーバーライド
- ファイル間のexport, import
- 配列に対して使えるメソッド（push, forEach, find, filter, map）

##2. Node.js関連のあれこれインストール
- nodist（Node.jsのバージョン管理ツール）のインストール
- Node.js（サーバーサイドでJS動かす）のインストール
- npm（Node.jsのパッケージ管理ツール）からパッケージの使用
- babel（ESバージョンの橋渡し）のインストール

##3. jQueryの学習
###インプット
- [Progate](https://prog-8.com/)のjQuery初級編～上級編
- YouTube動画（https://www.youtube.com/watch?v=hMxGhHNOkCU） #1~#4

###学習内容
- 書き換えメソッド(css, html, text)
- click, hover メソッド
- eq, index, prev, next, lengthメソッド
- ゲット用メソッド(text, html, css, attr)
- animateで動きをつける
- thisの構文
- formの受け取り（val, submit）
- カスタムデータ属性
- scrollTop、ページ内ナビゲーション、offset

##4. Bootstrap 4の基礎
htmlとcss学んだあなたへの簡単なフレームワーク、的な記事で紹介されていた。
静的サイトを作るため興味を持つ。
そもそも、bootstrapが何なのかよくわかっていなかった。
CSSをあらかじめストックしているファイル群のことで、タグにclassを指定すれば勝手にスタイルがついていくものだと理解した。

###インプット
- Learn Bootstrap 4 for free - scrimba（https://scrimba.com/g/gbootstrap4）
- Bootstrap 4入門 - ドットインストール （https://dotinstall.com/lessons/basic_twitter_bootstrap_v5）

[startbootstrap](https://startbootstrap.com/)でサイトを作ってみよう、という段階

##次にやりたいこと
学んだことをすぐにアウトプットできる場所をつくる、学習記録をQiitaではない場所に残す。
そのため、静的サイトをつくる。

##具体的にやること
####1. 静的サイトを作る
載せるものは、学んだ言語のアウトプット、学習記録、ポートフォリオくらいなので、静的サイトに特化したサイトジェネレーターを使う。

JSベースの静的サイトジェネレーターはNuxt.js、Next.js、Gatsbyなど様々あるみたいですが、[React Staticを使うとシンプルに静的サイトを作れるので良い](https://qiita.com/ky7ieee/items/94d3b1e90682ec8b4497)という記事の影響と、React.jsがトレンドっぽいのでなんか良さそうということで、**React Static**で制作しようと考えています。
####2. サーバーを利用してサイトを公開する
- Githubでの公開はできるけれど色々制限があるみたいなので、**GitLab、Netlify、Heroku**（違いがよくわかっていない）のどれかを使ってサイトを公開する

少々あせりぎみで学習しているので、復習のためアウトプットを増やして着実に学んでいこう。
HTML復習

#**はじめに**
初学者のアウトプット用記事です。

#**学習状況**
TECH::EXPERT短期コース3/9~
progate:HTMLCSS,Ruby,Rails(少し)
スクールに通って8日

#**HTML復習**

スクールの課題にて分からなかったCSSプロパティを調べた。

```css
list-style: none;
```
リストタグ(ul,li)の黒点を消す。

```css
position: fixed;
```
ヘッダーの固定
```css
line-height: 60;
```
行間

```css
font-weight: bold;
```
通常の設定値はnormal値をboldにすることで太字になる。

また値を数値に変えることも可能で

```css
font-weight: 100;
font-weight: 200;
```

数値で指定した場合の種類は100/200/300/400/500/600/700/800/900の9段階ありますが、実際にはブラウザで2種類のみで設定されていることが多く、画面上でも一番下の800のみが太字で表示されています。(値700以上でboldと同様の表示になります)




とりあえず備忘録
ローカルでRails環境構築

##Railsを始めてみる

フロントエンジニア歴約1年半のエンジニアです。
今の業務は、ほぼほぼコーダーなので、反抗してRailsに手を出してみることにしました。

[Ruby on Rails チュートリアル](https://railstutorial.jp/chapters/static_pages?version=5.1)というサービスでドキュメントに沿って進めるとアプリが作れると教えていただいたので、早速「[第1章ゼロからデプロイまで](https://railstutorial.jp/chapters/beginning?version=5.1#cha-beginning)」を進めてみました
(世界的に有名な書籍の 「Ruby on Rails Tutorial」 を日本語訳したサイトらしいです)

##AWS、触りたかったけど・・・一旦スルー

環境構築は[Cloud9](https://aws.amazon.com/jp/cloud9/?origin=c9io)が楽だよー（超要約）との記載があったので、途中まではCloud9を使ってました

が、Gitでリポジトリにプッシュする際に公開鍵の認証がうまく行かず、結局ローカルで進めることに、、、

こんな風に拒否された、、、

```
$ git push -u origin master
Permission denied (publickey).
fatal: Could not read from remote repository.
```

2019/5/9追記
もう1回プロジェクトを立ち上げ直したらインスタンス作成されてました。
~~AWSの公式で「[Amazon EC2 でのセットアップ](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/get-set-up-for-amazon-ec2.html#sign-up-for-aws)」、「[インスタンスへの接続に関するトラブルシューティング](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/TroubleshootingInstancesConnecting.html#troubleshoot-unprotected-key)」というページがあるようなので後ほど試して見ようかと・・・
(´-`).｡oO(あ、そもそもユーザー作ってないし、鍵ファイルの拡張子もpemにしてなかった、、、)~~



そんな感じでローカルでは以下のように環境構築をしました
（本当はCloud9の前にローカルで環境構築していた）



##ローカルで環境構築

Homebrewでrbenvとruby-buildのインストール

```
$ brew install rbenv ruby-build
```



パスを通す

```
\$ echo 'export PATH="~/.rbenv/shims:/usr/local/bin:$PATH"' >> ~/.bash_profile

\$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

$ source ~/.bash_profile
```

Rubyのインストールとシステム全体で使用するRubyのバージョン指定

```
$ rbenv install 2.5.1

$ rbenv global 2.5.1
```

shimのリフレッシュ

```
$ rbenv rehash
```

設定が反映されているか確認

```
$ which ruby
#/Users/(ユーザー名)/.rbenv/shims/ruby

$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]

```

gemはrubyに同梱されているようですが、念のためバージョンアップ
bundlerは入っていたようなので、バージョンを上げておく

```
$ gem update --system

$ gem update bundler
```

railsのインストール

```
$ gem install rails -v 5.2.1

$ rails -v
Rails 5.2.1
```


##1章完了！
あとはドキュメントの通りに進めてデプロイまでできましたー
2章からはアプリを作っていくところに入るようなので面白くなってきそうです
Shellをクリックで実行できるようにする

「毎回，sh [ファイル名].shするのが面倒だ！」

「アイコンをクリックするようにシェルを実行したい！」

そんなニーズはけっこうあると思います．

ということでメモ


１．シェルを選択した状態で，「このアプリケーションで開く」
<img width="573" alt="shell1.png" src="https://qiita-image-store.s3.amazonaws.com/0/377231/3443e0c0-c04a-68dd-f6d2-edc14e81e627.png">

２．**ターミナル**を「常にこのアプリケーションで開く」に指定
<img width="781" alt="shell2.png" src="https://qiita-image-store.s3.amazonaws.com/0/377231/cde16b77-2708-fd8c-6280-836cca58eddb.png">

３．対象のシェルファイルがある場所で実行

```
$ chmod +x [ファイル名].sh
```

４．完了
![shell3.gif](https://qiita-image-store.s3.amazonaws.com/0/377231/76a48b47-31a3-fe73-0923-fc0f282b1202.gif)
MacOSでGradleによってScalaのJarを作成します

#Gradleインストル
MacのHomebrewでGradleをインストルします。

```
brew update
brew install gradle
# インストルした結果
######################################################################## 100.0%
🍺  /usr/local/Cellar/gradle/5.2.1: 13,355 files, 235.3MB, built in 3 minutes 36 seconds
```
- インストルされたGradleの場所： /usr/local/Cellar/gradle/5.2.1
- インストルされたGradleのバージョン： 5.2.1

Gradleを確認します。

```
gradle -v
# 確認結果
------------------------------------------------------------
Gradle 5.2.1
------------------------------------------------------------
Build time:   2019-02-08 19:00:10 UTC
Revision:     f02764e074c32ee8851a4e1877dd1fea8ffb7183
Kotlin DSL:   1.1.3
Kotlin:       1.3.20
Groovy:       2.5.4
Ant:          Apache Ant(TM) version 1.9.13 compiled on July 10 2018
JVM:          11.0.2 (Oracle Corporation 11.0.2+9-LTS)
OS:           Mac OS X 10.14.3 x86_64
```
# ディレクトリ準備

```
cd /work
mkdir jar_scala
cd jar_scala
mkdir -p src/main/scala
mkdir -p src/main/resources
mkdir -p src/test/scala
mkdir -p src/test/resources
cd src/main/scala
mkdir -p com/demo/gradle
```
scalaのソースコードを編集します。

```
# scala作成
vi com/demo/gradle/HelloWorld.scala
# 以下の内容を編集
package com.johnathanmarksmith.gradle;
 object HelloWorld {
    def main(args: Array[String]) {
      println("Hello, world!")
    }
  }
```
scalaをコンパイルします。

```
cd /work/jar_scala
# ビルドするためのファイルを編集
vi build.gradle
# 以下の内容を編集
apply plugin: 'scala'
dependencies {
    compile 'org.scala-lang:scala-library:2.11.7'
}
jar {  
    manifest {     
        attributes 'Main-Class': 'com.demo.gradle.HelloWorld' 
        }
    }
# ビルドを行います
gradle build
```
アウトプット開始宣言

###自己紹介
軽く自己紹介させていただきます。
30歳男妻子持ち。前職は製造業で工場で作業服着て働いてました。
完全にプログラミングは未経験のまま2019.3.9からTEC::EXPERTに短期コースに通いはじめました。

###アウトプット
これから学んだ技術を自分の復習も兼ねてアウトプットしていこうと思います。
csvファイルのpostgres転送時間比較。pandas.to_sql,embulk,copy

1000万行のcsvファイルのpostgres転送時間を比較してみた

# 結論
copyが圧倒的に早い。csvファイルの出力より早い。

|方法|時間|
|---|---|
|pandas.to_sql|22分2秒|
|embulk(insert_direct)|6分3秒|
|copy(postgres)|0分12秒|
|参考）csvファイル出力|0分50秒|

# 環境
cpu:ryzen 7 1700
メモリ:32G
postgres:Ver10
os:win10
記憶装置：HDD

# 考察
* postgresの設定デフォルトのままなので、最適化するとちょっと結果が変わるかも
* pg_bulkloadを使えばembulkでも高速化できそうだがwin10だと大変そう。

# 転送データの作成
pythonでダミーデータを作成。1000万行

```python
import pandas as pd
import numpy as np
from sqlalchemy import create_engine

df = pd.DataFrame({ 'A' : np.random.randint(0,100,10000000),
                        'B' : np.random.randint(0,100,10000000),
                        'C' : np.random.randint(0,100,10000000),
                        'D' : np.random.randint(0,100,10000000)
                        })
df.to_csv('embulk_test.csv',index=False)
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/130987/fc0e5a2c-83aa-1979-ddf8-8b7228a71655.png)

# pandas.to_sqlで転送

```python
engine = create_engine('postgresql://postgres:password@localhost:5432/test')
df.to_sql('pandas_to_sql', engine, if_exists='replace')
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/130987/d6acf836-bf1b-fff0-5a44-5c68bfec64b5.png)


# embulkで転送

```yml
in:
  type: file
  path_prefix: embulk_test.csv
  parser:
    charset: UTF-8
    newline: CRLF
    type: csv
    delimiter: ','
    quote: '"'
    escape: '"'
    trim_if_not_quoted: false
    skip_hander_lines: 1
    allow_extra_columns: false
    allow_optional_columns: false
    columns:
    - {name: 'A', type: long}
    - {name: 'B', type: long}
    - {name: 'C', type: long}
    - {name: 'D', type: long}

out:
  type: postgresql
  mode: insert_direct
  default_timezone: "Asia/Tokyo"
  host: localhost
  port: 5432
  user: postgres
  password: "password"
  database: test
  table: embulk_table
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/130987/79d1bf80-90cf-edf0-9c49-b5f1d2a89d06.png)