OmniAICreator/Qiita-1.07M huggingface dataset:
よく使う Atom の

## ショートカットキー

意外と便利なショートカット一覧、随時更新予定です。

### コードペーン

|操作名|ショートカットキー|
|:-:|---|
タブを移動|⌘ + option → [←, →] / ⌘ + shift + [[, ]]
ペーンを分割|⌘ + [K] → [↑, →, ..]
ペーンを移動|⌘ + [K] → ⌘ + [↑, →, ..]
[split-diff](https://atom.io/packages/split-diff)|option + control + [T]

#### VS Code だと

|操作名|ショートカットキー|
|:-:|---|
ペーンを分割|⌘ + option + control + [¥]
ペーンを縦に分割|⌘ + [K] → 〃
ペーンを移動|⌘ + [K] → ⌘ + [↑, →, ..]
指定のペーンに移動|⌘ + [1, 2, ..]
ペーンを入れ替え|⌘ + [K] → ⌘ + [↑, →, ..]
【Android】WebViewでWebStorage(LocalStorage)を使用・削除する方法


AndroidでWebViewを使用、Html5側でAndroid端末側のWebStorageにタブの位置などを保存することとなったため、対応。
調査し、対応した結果をメモとして残しておきます。

#使用方法
Html5側で対応するだけではダメで、Android側のWebView定義の際、以下を行なう必要がある。

```kotlin
webView = view.findViewById(R.id.webview) as WebView

// JavaScriptをONにする
webView.settings.javaScriptEnabled = true

// Storageの使用許可
webView.settings.domStorageEnabled = true

// API Level 19より前の場合はデータベースの保存場所の指定が必要
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
	val path : String = this.getDir("データベースの名前", Context.MODE_PRIVATE).path
	webView.settings.databasePath = path
}
```

#削除方法
上記で、Html5側からWebViewのWebStorageは使用出来るようになったが、１つ問題が発生。
ヒストリーバックでタブ位置など保存された状態を復元することはいいが、
WebViewを再生成した場合やアプリの再起動した後でも状態が保存されていた。

仕様にもよると思うが、今回は上記の場合はタブ位置を初期化させておきたいため、WebStorageを削除したい。
調査の結果、onCreateやonDestoryのタイミングなどで以下を実行することで削除が可能。


```kotlin
// 保存されているJavaScript WebStorage(LocalStorage)の削除
WebStorage.getInstance().deleteAllData()
```

これにより、WebViewのヒストリーバック時や再読込時のみ、WebStorageが使用される。


#感想
iOSのWKWebViewではこの辺りは自動でやってくれているみたい。
AndroidのWebViewめんど(ry
もっといい方法あるよ！とか、ここはこうしたほうがいいよ！とかあったら教えていただきたいです。


#参考サイト
■HTML5のWebStorageを利用できるようにする
http://www110.kir.jp/Android/ch0809.html

■公式リファレンス
https://developer.android.com/reference/android/webkit/WebStorage.html#deleteOrigin(java.lang.String)
shellについての個人的まとめ

#この記事について#
自分の備忘録として、shell全般についての自分の考えや調べたことを記載していきます。
ほぼリンク集として使用。
経験が浅いので、間違っていることもあると思いますがご容赦ください。


#小技

| 事項       |       説明|       参照|
|:-----------------|:------------------|:------------------|
|dateコマンド|日付を取得する|[日付の取得](http://shellscript.sunone.me/date.html#過去-未来の日付を求める)|
|サーバー作業用コマンドまとめ|-|[サーバー作業用コマンドまとめ](https://qiita.com/Amebayashi/items/2ec2423d54a1e1d304ed)|
|シェルスクリプトからMySQLを実行|-|[シェルスクリプトからMySQLを実行](http://www.tree-tips.com/mysql/bash/)|
|出力|標準出力とエラーを出しわける|[bash: 標準出力、標準エラー出力をファイル、画面それぞれに出力する方法](https://qiita.com/laikuaut/items/e1cc312ffc7ec2c872fc)|
|コメント|-|[シェルスクリプトで複数行のコメントアウト](https://qiita.com/kaw/items/ffdaf5d23627c0bd7e87)|
|終了ステータス|コマンド実行の際の成功判定で使用|[終了ステータス](https://shellscript.sunone.me/exit_status.html)|
|if文と比較|if文とtest文を組み合わせて、判定する|[if 文と test コマンド](https://shellscript.sunone.me/if_and_test.html#if-%E6%96%87%E3%81%A8-test-%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89)|


#エラー対応

| メッセージ       |       説明|       対策|       参照|
|:-----------------|:------------------|:------------------|:------------------|
|must be privileged to use -u|-uを使用するには特権が必要。|sudoで回避可能|-|



#参考#
[UNIX & Linux コマンド・シェルスクリプト リファレンス](http://shellscript.sunone.me/)
作業ブランチではcomposer.lockの変更を最小化してください

お疲れ様です。田中です。

PHPのプロジェクトの作業ブランチ内で、追加のライブラリが必要になったとき `composer.json` に変更を入れますよね。このときおもむろに `composer update` を叩くと `composer.lock` に派手な差分が発生するので、**絶対にしないでください**。

`composer update` はすべてのパッケージについて、現時点で可能な限り高いマイナーバージョンに上げようとします。当然、自分が master からブランチを切った時点でインストールされていたパッケージのバージョンは、現時点より古くなっています。直接使っているものだけでなく、その依存パッケージも上がります。

いちど `composer.lock` に大きな差分が発生すると、コミットログが無駄に大きくなるばかりでなく、その後のりベースやマージに支障をきたします。後のリベース/マージ後はつねにフルの `composer update` が必要となります。本来であれば、コンフリクトするのは本当に必要なバージョン制約か、それ以外はせいぜい `content-hash` だけで済むはずです。([解消ヒント](https://qiita.com/kzbandai/items/8087cb8fb2ba343e6e8c))

無条件にフルの `composer update` を強制してしまうことは、未テストなバージョン組み合わせでもいったん受け入れなければならないということです。昨日まで動いていた master への変更影響は極力少なく、でないとせっかく **.lock** があるのに意味がありません。

というわけで、作業ブランチにライブラリを追加する場合は、`composer require vendor/package` のみ行ってください。既存パッケージのバージョン制約を変えるなら、`composer require "vendor/existing-package:^2.0.1"` です。そうすると、これまでにロックされたバージョンはなるべく据え置きで、どうしても変えなければならない内容だけが書き変わります。

また、`composer.lock` に過剰な影響がないかをコミット前に差分確認してください。もし意図しないバージョンアップがあった場合は、`git checkout HEAD -- composer.lock` してもとに戻したあと、`composer update vendor/package vendor/existing-package` というふうに、`composer.json` 内で **自分が変更したパッケージだけ** を更新するようにします。`--dry-run` オプションで、影響を事前にチェックするのも有効です。

ちなみに、`composer.lock` の差分がが十分に小さく、GitHub で折りたたまれないということは、レビュアーがどのライブラリのバージョンに影響があったかを目視できるというメリットもあります。

そのうえで、全パッケージの一括更新を行ってもいいのは、リードプログラマーが master (もしくはdevelop) ブランチでのみとします。リードが意図したタイミングで全体のマイナーバージョンを上げ、その結合テストに合格することを確認しなければなりません。

以上、何卒よろしくお願い申し上げます。


追伸: これの npm/yarn 版とか bundler 版とかどなたか...
Java8 Silver試験の備忘録

Javaで開発していても、良く知らずに使っている箇所が多い。

##配列
###初期化
```Java
int[] arrayInt = new int[2];
System.out.println(arrayInt .length); // 2が表示される
for (int i : arrayInt ) {
    System.out.println(i); // 0が表示される
}

String[] arrayStr = new String[2];
System.out.println(arrayStr.length); // 2が表示される
for (String str : arrayStr) {
    System.out.println(str); // nullが表示される
}
```

```Java
int[] arrayInt = new int[2] { 1, 2 }; // コンパイルエラー
```

### 参照渡し
```Java
int[] array1 = new int[1];
int[] array2 = { 1, 2, 3 };
array1 = array2;
for (int i : array1) {
    System.out.println(i); // 1, 2, 3と表示される
}
```
###コピー
```Java
int[] array1 = { 1 };
int[] array2 = array1.clone();
array2[0] = 2;
System.out.println(array1[0]); // 1が表示される
System.out.println(array2[0]); // 2が表示される
```

##比較

```Java
StringBuilder sb = new StringBuilder(5);
String str = "";
System.out.println(sb.equals(str)); // 参照の比較のためfalse
System.out.println(sb.toString().equals(str)); // 値の比較のためtrue
```
##ポリモーフィズム

```Java
interface A {
    void test1(); // publicが自動でつけられる
    void test2(); // publicが自動でつけられる
}

abstract class B implements A{
    abstract void test3(); // publicは自動でつけられない
                           // privateの修飾は不可
}

class C extends B{
    public void test1(){} // 定義しないとコンパイルエラー
    public void test2(){} // 定義しないとコンパイルエラー
    public void test3(){} // 定義しないとコンパイルエラー
}

public class test {
    public static void main(String[] args) {
        A a = new A(); // コンパイルエラー
        B b = new B(); // コンパイルエラー
        C c = new C();
    }
}
```

##オーバーロード
```Java
public static void main(String[] args) {
    test(1, 2);
}

private static void test(int... i) {
    System.out.println("A");
}

private static void test(int i, int j) { // 呼び出される
    System.out.println("B");
}
```

##ループ
###whileの省略形式
```Java
int i = 0;
do
    System.out.println("A");
    i++; // 省略形式では、複数行書けないためコンパイルエラー
while (i < 3);
```

###forの初期化
```Java
for (int i = 0, j = 0; i < 5; i++) {
    System.out.println("A");
}

for (int i = 0, int j = 0; i < 5; i++) { // コンパイルエラー
    System.out.println("A");
}
```
親がいなくなったTrailをfade out させる

例えばミサイルにTrailをつける場合、ミサイルが消滅するとトレイルも一緒に消えてしまいます。
![before2_image-iloveimg-cropped.gif](https://qiita-image-store.s3.amazonaws.com/0/59911/4554d200-ecf0-3e72-fd5d-78f540c1e993.gif)

Trailをミサイルの子に付け、ミサイル消滅時に切り離すことで綺麗にフェードアウトできるようにしてみます。
![after2image-iloveimg-cropped.gif](https://qiita-image-store.s3.amazonaws.com/0/59911/7c683ec7-95f5-1282-d534-e3091a127b54.gif)
![スクリーンショット 2018-02-16 13.01.39.png](https://qiita-image-store.s3.amazonaws.com/0/59911/12589572-3fd8-3e6d-2355-a57c60f2619b.png)

```TrailFadeOut.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TrailFadeOut : MonoBehaviour {
    [SerializeField, Range(0f,1f)] float forrowRate = 0f;
    [SerializeField, Range(0.1f, 4f)] float fadeTime = 1f;
    Coroutine coro;
    TrailRenderer trail;
    Vector3 oldPos;

	// Use this for initialization
	void Start () {
        coro = null;
        trail = GetComponent<TrailRenderer>();
        oldPos = transform.position;
	}
	
	// Update is called once per frame
	void Update () {
        if(transform.parent==null){
            if (coro == null){
                Vector3 spd = (transform.position - oldPos) / Time.deltaTime;
                coro = StartCoroutine(trailFadeCo(spd));
            }
        }else{
            oldPos = transform.position;
        }
	}

    IEnumerator trailFadeCo(Vector3 _spd){
        Color defCol = trail.material.GetColor("_TintColor");
        Color col = defCol;
        yield return null;
        while(col.a>0f){
            col.a = Mathf.Max(col.a-Time.deltaTime/fadeTime, 0f);
            trail.material.SetColor("_TintColor",col);
            transform.position += _spd * forrowRate * Time.deltaTime;
            yield return null;
        }
        Destroy(gameObject);
    }
}
```

Trailは親から切り離されるとフェードアウトを開始し、消えてから自分自身をDestroy()します。

```
trail.material.SetColor("_TintColor",col);
```

の部分はTrailに使用しているシェーダーによって適宜書き換えてください。
_Colorプロパティがある場合は

```
trail.material.color = col
```

と記述することもできます。
![スクリーンショット 2018-02-16 12.57.32.png](https://qiita-image-store.s3.amazonaws.com/0/59911/a24cc083-46ce-b8b2-812e-d438f5121939.png)
GoogleDriveからGoogleCloudStorageに階層構造をコピーするのをDataflowで実装した

# はじめに
Google Drive（以下Drive）と Google Cloud Storage（以下GCS）を同期したいことがしばしばあると思ったので実装しました。
GCSはディレクトリという概念が存在しないため、ファイルパスが分かっていればコピーの並列化が可能です。

```
[Drive]                            [GCS]

root/                              gs:root/
　├ hoge.txt                         ├ hoge.txt
　├ folderA/                         ├ folderA/fuga.txt
　│  └ fuga.txt                      ├ folderB/folderC/hogehoge.txt 
　├ folderB/               ----->    └ piyo.txt
　│  └ folderC/                      
　│　　　└ hogehoge.txt/             
　└ piyo.txt

*Drive上のファイルパスがGCS上でのファイル名になるイメージ                         
```

# なぜ Dataflow？
最初はGoogle App Engine（以下GAE）で並列コピー処理を書いていた。
しかし、並列コピーのタスクを分散させてしまうと、全てのコピーが終わったことを検知するのが難しい。
また、単純にGAEはバッチ処理をこなすのが苦手ということと、最近仕事でDataflowに触れているため。
Dataflowを利用すれば、分散した処理が終わるのを待つことができます。その後、Pub/SubやらCustomIOを書くなりして後続の処理に繋げれば良いと考えました。

# 要件
Driveのあるフォルダ（以下ルートフォルダ）直下の階層構造をGCSに並列コピーする。
Spreadsheet等、コピーできないファイルは対象外とする。
同フォルダ内の同ファイル名のファイルに関してはどうする？

# 実装の概要
ルートフォルダのIDから以下を探索し、ファイルIDとファイルパスを持つオブジェクトのリストを作成する。
作成されたオブジェクトを各タスクに分散し、「Driveからファイルをダウンロードし、GCSにアップロードする」部分を並列化する。

### パイプライン設計
- 標準でDriveIOは存在するの？
	- 存在しません。自前で実装しましょう！
- カスタムソースやシンクを書かないといけないの？
	- 面倒くさいのでDoFnで実装！ 
	- 最初に適当な入力を作り、リストを作るためのDoFnのInputとして受け取る

### 簡単なパイプラインコード

```java
// *ポイント1: 最初に適当な値で入力を作っておくのがミソ
p.apply("First Input",Create.of("A")).setCoder(StringUtf8Coder.of())
 
 .apply("Read Drive", ParDo.of(new ReadDriveDoFn(rootFolderId)))
 .apply("Write GCS", ParDo.of(new WriteStorageDoFn()));
 
 // *ポイント2: 全てのコピー処理が終わるまで待ちたいのでOutputの合計値を取っている
 .apply("Combine!", Sum.integersGlobally()))
 
 .apply("コピーが終わってるので、後続の処理をお好きにどうぞ！")

p.run();
```
- ReadDriveDoFn: ルートフォルダ直下のファイルリストを作成
	- ルートフォルダIDから再帰的に以下を探索し、ファイルIDとそのパスをオブジェクトとしてリストを作成する
	- リストをループしてOutputすることで分散する


```java
	public class ReadDriveDoFn extends DoFn<String, File> {

		private List<File> file;

	    @ProcessElement
	    public void processElement(ProcessContext c) {
	        recursiveSearch(rootFolderID, filePath); // リストを作成
	        for (File file : fileList) {
	            c.output(file); // リストを分散！
	        }
	    }
	}
```

- WriteStorageDoFn: ファイルをDriveからダウンロードし、GCSにアップロードする 
	- Inputとして受け取ったオブジェクトからファイルIDを取得し、ダウンロード。その後、ファイルパスを元にGCSに保存
	- ここでのOutputは適当に「1」とする（なんでも良いが、コピーしたファイル数を把握できる）

```java
	public class WriteStorageDoFn extends DoFn<File, Integer> {
	    @ProcessElement
	    public void processElement(ProcessContext c) {
	    	downloadFromDrive(fileId);
	    	uploadToGCS(filePath);
	    	c.output(1);
	    }
	}
```

- Sum.integersGlobally: Outputの要素数を足す > ここではコピーしたファイル数を表す
	- 全てのOutput要素を足すDoFnを挟むことで、ファイルコピーの終了を待つことができ、コピーしたファイル数も把握することができる

# さいごに
最初にGAE/Goで書いていた処理と比べると2倍以上早くはなりました。
しかし、G Suite（Apps）系のAPIってめちゃくちゃ脆いんですよね。
今回コピーを分散させることが可能になったわけですが、大量のファイル数を捌こうとすると、かなりエラーがでます。
リトライ処理はちゃんと書きましょう。
Dataflowはまだ細かいことが苦手ではありますが、無限の可能性を秘めていると思うので、今後も色々な用途で使っていきたいと思います。
Rust シグナル メモ

## クレート

chan, chan-signal

## 宣言

```Rust
#[macro_use]
extern crate chan;
extern crate chan_signal;

use chan_signal::Signal;
```

## 使い方

### SIGINT待機

```Rust
let signal = chan_signal::notify(&[Signal::INT, Signal::TERM]);
```

### シグナル列を格納するバッファを作成

引数が0ならキューに、非0なら要素数1のバッファになります。

```Rust
let (sdone, rdone) = chan::sync(0);
```

### メイン処理をする関数を作成

```Rust
fn 関数(_sdone: chan::Sender<()>, 引数...) {
/* 処理 */
}
```

### メイン処理をさせるスレッドを作成

```Rust
std::thread::spawn(move || 関数(sdone, 引数));
```

### シグナル解析

```Rust
chan_select! { //シグナル解析フェイズ
    signal.recv() -> signal => { //シグナル受信時
        if signal.unwrap() == Signal::INT { //もしシグナルがSIGINTならば
            /* 処理 */
            std::process::exit(0); //こうするとSIGINTっぽくなる
        }
    },
    rdone.recv() => {} //シグナルを受信してければ何もしない
}
```

### 全文

```Rust
fn hoge() { // 並列化,シグナル処理の関数
    let signal = chan_signal::notify(&[Signal::INT]);
    let (sdone, rdone) = chan::sync(0);
    thread::spawn(move || fuga()); // fuga(): シグナルを受信するまで動かす関数
    chan_select! {
        signal.recv() => {
            // シグナル受信時の処理
        },
        rdone.recv() => {}
    }
}
```

### 悪い例

以下のような方法でもシグナル処理は可能だが、シグナル待機が必要なので速度が著しく低下してしまう。

```Rust:while内で使用して常にシグナル待機
while true {
    let sig_int = chan_signal::notify(&[Signal::INT]); //SIGINTを待機
    let no_signal = chan::after_ms(20); //20msだけ待つ
    /* 処理 */
    chan_select! { //シグナル処理フェイズ
        sig_int.recv() -> signal => { //SIGINT時
            /* 処理 */
            std::process::exit(0); //こうするとSIGINTっぽくなる
        },
        no_signal.recv() => {} //無シグナル時は何もしない
    }
}
```
adb を必要最小限のパッケージで

「取り急ぎ、メールで送付したadbを入れてくれれば動きますよ」と言われたが、開発環境は移行する前の端末だったし、最近androidアプリの開発もないので、adbだけ動くようにしたいなぁ
といった人向けです（長い

<h1>JDK9</h1>
jdk8でだとbrewで入れられるし、簡単だと思うけど、９が最新だしというそれだけの理由で９を選択する。

オラクルさんのダウンロードページから
http://www.oracle.com/technetwork/java/javase/downloads/index.html
JDK9.0.4を選択
http://www.oracle.com/technetwork/java/javase/downloads/jdk9-downloads-3848520.html
「Accept License Agreement 」にチェックするのを忘れずに（私です）。。
jdk-9.0.4_osx-x64_bin.dmg

<h1>android tools</h1>
コマンドラインツールのみインストールします。
https://developer.android.com/studio/index.html#downloads
　sdk-tools-darwin-3859397.zip

<h1> sdkmanager の前に　</h1>
環境変数を設定しないと、「javax/xml/bind/annotation/XmlSchema」云々で怒られます。
　https://github.com/NativeScript/nativescript-cli/issues/3139
　上記を参考にして、コマンドラインから以下のコマンドを実行

```bash
export JAVA_OPTS='-XX:+IgnoreUnrecognizedVMOptions --add-modules java.se.ee'
```

<h1>　sdkmanagerからPlatform-toolsをインストール </h1>
コマンドラインツールのzipを適当な場所に展開し、その場所から、以下のコマンドをコマンドラインから実行する

```bash
bin/sdkmanager platform-tools
```

<h1>エンディング</h1>
必要な材料は揃いました、一応適当な場所から、~/Androidにまとめておきましょう。

```bash
mkdir ~/Android
mv ~/Download/tools ~/Android
mv ~/Download/platform-tools ~/Andorid
cd ~/dev/… 　　（適当な場所にあるxxx.adbがある場所へ）
~/Android/platform-tools/adb install xxx.adb
```

<h1>余計なお世話</h1>
時間が経つと、その時にはうまくいっていたものも、うまく動作しなくなることは当然ありうることでございまして、今回2018/2/16に実行した時にうまくいったやり方をメモしているものです、新しい記事がある場合、そちらを参考にされるコトをオススメいたします
Spring Initializrで作成した雛形がbootRunで起動しなくて困ったメモ

# 起きたこと

### [Spring Initializr](https://start.spring.io/)
で雛形を作りダウンロード。

+ Generate a [Gradle Project] with [Kotlin] and Spring Boot [1.5.10]
+ Project Metadata [com.example] [demo]
+ Dependencies [Web] [Thymeleaf]

### bootRunを実行

```
./gradlew bootRun
```

なぜか `java.lang.ClassNotFoundException` で落ちてしまう。

## 対応

`build.gradle` の `org.jetbrains.kotlin:*` を削除したら動いた。

別の時にダウンロードした雛形には `org.jetbrains.kotlin:*` がなくて動いていたので消してみました。

+ 修正前

```build.gradle
dependencies {
	compile('org.springframework.boot:spring-boot-starter-thymeleaf')
	compile('org.springframework.boot:spring-boot-starter-web')
	compile('com.fasterxml.jackson.module:jackson-module-kotlin')
	compile("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}")
	compile("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
	testCompile('org.springframework.boot:spring-boot-starter-test')
}
```

+ 修正後

```build.gradle
dependencies {
	compile('org.springframework.boot:spring-boot-starter-thymeleaf')
	compile('org.springframework.boot:spring-boot-starter-web')
	compile('com.fasterxml.jackson.module:jackson-module-kotlin')
	testCompile('org.springframework.boot:spring-boot-starter-test')
}
```

とりあえず動いたがなぜかは不明なのであとで調べる。
Project Euler 31「硬貨の和」

はじめての再帰関数。
頭の中がグッチャグチャだよ。
何度も無限ループかましちゃったよ。

# Problem 31 「硬貨の和」
イギリスでは硬貨はポンド£とペンスpがあり，一般的に流通している硬貨は以下の8種類である.
1p, 2p, 5p, 10p, 20p, 50p, £1 (100p) and £2 (200p).
以下の方法で£2を作ることが可能である．
1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p
これらの硬貨を使って£2を作る方法は何通りあるか?

```python
coins = [1, 2, 5, 10, 20, 50, 100, 200]
coins.sort(reverse=True)

def hoge(coins, target):
    # 大きい貨幣から順に使っていくイメージ
    cnt = 1 # 1pのみの場合は初めにカウントしておく
    for c in coins[:-1]: # forループは1pを除く
        # 使えるだけ使うパターンから順にやっていく
        for n in reversed(range(target//c)):
            amount = c * (n + 1)
            if amount == target:
                cnt += 1
            else:
                # 残りの貨幣と差額を渡して再帰呼び出し
                cnt += hoge(coins[coins.index(c)+1:], target-amount)
    return cnt

print(hoge(coins, 200))
```

コンガラガル。サイキコワイ。
インスタンス変数を nil で初期化しておく明確な理由がわかった(と思ったら勘違いだった)

# もともと nil なのにわざわざ nil で初期化するのは何のため？

インスタンス変数をすぐに使わないときでも initialize の時点で nil で初期化しておきましょう、みたいな作法があって、その理由はメンバ変数が一目でわかりやすい、つまりほぼコードの読み易さのためにあると考えていました。

そして、なるべくその作法を守るようにする一方で、もともと nil が返ってくるのに nil で初期化するのは意味がないし冗長な気もしてきて、しだいにその作法はあやふやな感じになっていきました。

# もしかして速度に影響？

ところがプロファイラを通していたとき、何でもない箇所が飛び抜けて遅くなっていることに気づいて、見るとそこは初期化していないインスタンス変数を参照しまくっている箇所でした。プロファイラがバグって行をまちがえたんじゃないかと疑いつつ念のため初期化の有無の差からくる参照速度を比較してみるとこうなりました。

```rb
RUBY_VERSION                    # => "2.5.0"

@var1 = nil
@var2

@var1                           # => nil
@var2                           # => nil

instance_variables              # => [:@var1]

require "benchmark/ips"
Benchmark.ips do |x|
  x.report("@var1") { @var1 }
  x.report("@var2") { @var2 }
  x.compare!
end

# >> Warming up --------------------------------------
# >>                @var1   265.090k i/100ms
# >>                @var2    34.342k i/100ms
# >> Calculating -------------------------------------
# >>                @var1     10.617M (± 7.4%) i/s -     52.753M in   4.999961s
# >>                @var2    415.672k (±13.2%) i/s -      2.026M in   5.024280s
# >> 
# >> Comparison:
# >>                @var1: 10616536.9 i/s
# >>                @var2:   415672.1 i/s - 25.54x  slower
```

# これでわかったこと

- 初期化していないと約**25倍遅い**
  - そんなにも？
  - 今のスコープには見つからないのでどんどん奥まで探しに行っているかんじ？
- 一回目に参照したときに nil がセットされるんでしょ説 → ウソ
  - そうなればこんなに差がでるわけがない
  - そもそも instance_variables に出てきてない

# まとめ

すぐに使わないインスタンス変数でも nil で初期化しておく理由は、作法とか行儀とか曖昧な理由ではなく初期化して存在を明確化しておかないとびっくりするほど**参照の速度が遅くなる**から、ということがわかりました。

# (追記) 本当のまとめ

でたらめ書いてすみませんでした。
@scivola さんの追試のおかげで気づいたのですが、未定義インスタンス変数の参照が遅かったのは、$VERBOSE が true の環境で、未定義インスタンス変数を参照したときのチェックや**警告を出す処理**に時間がかかっているからでした。
なお $VERBOSE が false の状態で実行すると次のようにほとんど差はありません。

```
               @var1: 12634855.7 i/s
               @var2: 11420363.3 i/s - 1.11x  slower
```

より正確に計れる benchmark_driver ではもう少し差がでてきます。

```
               @var1: 191046369.9 i/s 
               @var2:  76384674.3 i/s - 2.50x  slower
```

個人的には、この程度ならびっくりしないので遅いというのは理由にはなりませんが、それより $VERBOSE = true にしたときに警告がでる状態にあるというのがあまり気持ちの良いものではないので、それを理由に作法を守ろうと思います。

# (追記) Ruby 3.0 からは

未初期化インスタンス変数にアクセスしても警告が出ないようになった
https://techlife.cookpad.com/entry/2020/12/25/155741

とにかく面倒なので警告は無くなったそうです
docker login での Sign in について

# docker login での Sign in について

## 現象

macOS で docker-compose を使って docker pull 中に、次のようなエラーが発生。

```
unauthorized: authentication required
```

ブラウザで https://registry-1.docker.io/v2/library/memcached/manifests/1.4.34-alpine にアクセスしたときにも `authentication required` みたいなエラーが出るので、それと同じですね。

Docker for Mac のメニューを見るとログインできているんだが。。
ネットを検索すると docker login すればいいよ、みたいな情報が出てくる。なるほど、 Docker for Mac のログインとはリンクしているようなしていないような関係なのか。

docker login を試してみる。が、メールアドレスを入れると、認証失敗。

```
$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: xxxxxxxxxxxxxxx@gmail.com
Password:
Error response from daemon: Get https://registry-1.docker.io/v2/: unauthorized: incorrect username or password
```

ユーザ名だと、認証成功。

```
$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: xxxxxxxxxxxxxxx
Password:
Login Succeeded
```

認証成功後は docker pull も通るようになりました。


## Docker registry への Sign in

Docker for Mac のメニューからの Sign in の場合、以下のいずれの組み合わせでも認証成功しました。 ([Docker Cloud](https://cloud.docker.com/) も同様)

- ユーザ名 / パスワード
- メールアドレス / パスワード

ところが、 docker login を使った場合、以下の組み合わせでしか認証通りませんでした。

- ユーザ名 / パスワード

docker login の Reference 見てみると、 [v17.03](https://docs.docker.com/v17.03/engine/reference/commandline/login/) の時点では、 `--email, -e` option というのがある。なるほど、これにメールアドレスを渡せばよかったのか。。

だがしかし、 [v17.06](https://docs.docker.com/v17.06/engine/reference/commandline/login/) を見てみると、 `--email` option が消えてる!!

調べてみると、もともとあった `--email` option は、 email との組み合わせでログインするのではなく、該当ユーザが作成されていなかった場合に、指定した email でユーザを作成しますよ、という機能で v17.06 でその機能自体が削除されたらしい。

つまりは docker login の場合は必ず ユーザ名 / パスワード でログインしてくださいということですね！ひいては Docker for Mac の場合もその組み合わせでログインしたほうが良さそう。

> References

- [docker unauthorized: authentication required - upon push with successful login - Stack Overflow](https://stackoverflow.com/questions/36663742/)
- [Deprecated Engine Features](https://docs.docker.com/engine/deprecated/#-e-and---email-flags-on-docker-login)
Unduxと接続したコンポーネントに追加のpropsを渡す方法

Unduxを知らない方は以下の記事からどうぞ
[【Reduxに疲れた人のための】Undux入門](https://qiita.com/IzumiSy/items/c26f69219178b79f586d)

# 前置き

Unduxに接続したコンポーネントの`props`は、基本的にはストアのデータを持つ`store`という要素しか持たない。

なので、例えば以下のように`other`という`props`を追加で受け取ろうとするとTypeScriptに怒られるので、無理やり`any`による解決をするしかない用に見える。

```tsx
import { connect } from 'undux';

const withStore = connect(store);

const MyComponent = withStore('users')({ store, other }: any) => {

  // ...      

});
```

# ジェネリクスを使う
だが、実際には上の`withStore`で作られるHOCは追加で`props`に渡る要素のジェネリクスを指定できるので、以下のようにすると`any`をつける必要がなくなる。

```tsx
interface OtherProps {
  // ...
};

const MyComponent = 
  withStore('users')
    <OtherProps>({ store, other }) => {

      // ...      

    });
```

# react-navigationとの例
実際のケースとして、例えばreact-navigationは、ナビゲーターにマウントされるコンポーネントの`props`に`navigation`という画面遷移操作のための要素を渡してくるので、Unduxと一緒に使うには以下のように工夫するとよい。

```ts
import { NavigationScreenProps } from 'react-navigation';

interface NavProps extends NavigationScreenProps<any> {}

const MyComponent =
  withStore('users')
    <NavProps>({ store, navigation }) => {
     
      // navigation.goBack();
      // ...

    });
```
Rをソースからコンパイルしようとしたらlibcurlのバージョンで怒られた件

少し古く、root権限もない共有環境で最新のRが使いたかったので、ソースからRをコンパイルした時に、libcurlのバージョンが古いと怒られました。

```sh
$ tar -xzf R-3.4.3.tar.gz
$ cd R-3.4.3
$ ./configure --prefix=$HOME/...
...
checking curl/curl.h usability... yes
checking curl/curl.h presence... yes
checking for curl/curl.h... yes
checking if libcurl is version 7 and >= 7.22.0... no
configure: error: libcurl >= 7.22.0 library and headers are required with support for https
```

そこで、まずlibcurlもインストール。これはソースをダウンロードして、

```sh
$ ./configure --prefix=${curl_home} && make && make install
```

でOK。

次に、このlibcurlの場所をRのconfigureに教えてあげようとしましたが、configureのヘルプを見ても、```--with-curl=...```などのlibcurlのパスを指定する方法はありません。
```CPPFLAGS=-I${curl_home}/include```とか、```LDFLAGS=-L${curl_home}/lib```とかやっても、自前でインストールした最新のlibcurlを見つけてくれません。

解決方法を探すと、Rのソースの中の、m4/R.m4にありました。

```
AC_PATH_PROG(CURL_CONFIG, curl-config)
if test -n "${CURL_CONFIG}"; then
  echo "checking libcurl version ..." \
    `${CURL_CONFIG} --version | sed -e 's,^[[^0-9]]*,,'`
  if test -z "${CURL_CPPFLAGS}"; then
    CURL_CPPFLAGS=`${CURL_CONFIG} --cflags`
  fi
  ## This should be correct for a static-only build, user will
  ## need to override to specify static linking (see config.site)
  if test -z "${CURL_LIBS}"; then
    CURL_LIBS=`${CURL_CONFIG} --libs`
  fi
fi
```

パスの中からcurl-configコマンドを探して、それを使ってビルド時のパラメータを取得するようです。configureするときだけ、最新のcurl-configコマンドがパスから見つかればよいので、

```sh
$ PATH="${curl_home}/bin:${PATH}" ./configure --prefix=${HOME}/...
```

とすると、無事に通りました。以上。
作業ブランチが汚いときでもシュッとmasterにpullしたい

カレントブランチに未コミットな差分があると、他のブランチをチェックアウトできません。そこでいったん `git stash` やってからチェックアウトして `git pull` しますが、これ面倒ですよね。

というわけで `git fetch` で、カレントでないローカルブランチに直接リモートのコミットを落としてきます。

```
git fetch -u origin master:master
```

```
-u, --update-head-ok
By default git fetch refuses to update the head which corresponds 
to the current branch. This flag disables the check. This is purely 
for the internal use for git pull to communicate with git fetch, 
and unless you are implementing your own Porcelain you are not 
supposed to use it.
```

リモートのブランチが多いのでそれ GUI で一覧から選んで指定するの大変で、ってときに都合いいですね。

また、カレントブランチはクリーンな状態でも、リベースの時とかいちいち切り替えて戻ってやってワーキングのファイルをごちゃごちゃ書き換えするよりは、こうやって...

```
git fetch -u origin master:master
git rebase -i master
```
Lambda（Node.js）へのX-Ray導入でハマったところ

簡単にできるAWS LambdaへのX-Ray導入ですが、ハマったところをメモしておきます。

## httpではなくrequestモジュールを使っている場合

`AWSXRay.captureHTTPsGlobal`を使えば大丈夫です。

```javascript
var request = require('request');
var AWSXRay = require('aws-xray-sdk');

AWSXRay.captureHTTPsGlobal(require('http'));
```

https://docs.aws.amazon.com/ja_jp/xray/latest/devguide/xray-sdk-nodejs-httpclients.html

## ローカルで実行するとエラーになる

次のようなエラーが出る場合。

```bash
Error: Failed to get the current sub/segment from the context.
```

`AWS_XRAY_CONTEXT_MISSING`という環境変数が足りないようです。Lambdaで実行する場合はデフォルトで`LOG_ERROR`が指定されます。

固定でよければ、次のようにコードで指定することもできます。

```javascript
var AWSXRay = require('aws-xray-sdk');

AWSXRay.setContextMissingStrategy('LOG_ERROR');
```

`LOG_ERROR`ではなく別の値を指定したい場合は変更してください。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-x-ray.html
iPhoneでinput要素に付く影や角丸を消す



### input要素の影を消す場合はスタイルで下記を指定。
``` -webkit-appearance: none; ```

![sp_iphone_input_6.png](https://qiita-image-store.s3.amazonaws.com/0/145590/34192516-277a-9b10-7692-17af3e7b37eb.png "sp_iphone_input_6.png")


###ボタンスタイルが付いてしまうので同じように適用させれば、影や角丸を消すことが可能。
Atlassian Jira の環境を立てる


# 概要
前回の記事の[Atlassian Confluence の環境を立てる](https://qiita.com/hiro_alt/items/cbdbc933a944195c9d16)でポチポチ触ってみたが、とてもいい感じ。Redmineとかダサいしこっちの方がスマート感があって「使ってみたい」と思うようになりました。
 課題管理もしたいと思ったときJiraという別製品があるとのことで、インストールまでしましたのでその記録.


# インストール

 
```
wget https://www.atlassian.com/software/jira/downloads/binary/atlassian-jira-core-7.6.3-x64.bin

chmod +x atlassian-jira-core-7.6.3-x64.bin

# Execute shell
./atlassian-jira-core-7.6.3-x64.bin

Unpacking JRE ...
Starting Installer ...
Feb 16, 2018 1:37:23 AM java.util.prefs.FileSystemPreferences$2 run
INFO: Created system preferences directory in java.home.
You do not have administrator rights to this machine and as such, some installation options will not be availabl
e. Are you sure you want to continue?
Yes [y, Enter], No [n]
This will install JIRA Core 7.1.4 on your computer.
OK [o, Enter], Cancel [c]
o
Choose the appropriate installation or upgrade option.
Please choose one of the following:
Express Install (use default settings) [1], Custom Install (recommended for advanced users) [2, Enter], Upgrade 
an existing JIRA installation [3]
1
The following default options cannot be used. You will be asked to provide alternatives for these options.
* HTTP Port (In use)
Configure which ports JIRA Core will use.
JIRA requires two TCP ports that are not being used by any other
applications on this machine. The HTTP port is where you will access JIRA
through your browser. The Control port is used to startup and shutdown JIRA.
Use default ports (HTTP: 8080, Control: 8005) - Recommended [1], Set custom value for HTTP and Control ports [2,
 Enter]
2 ## 私の場合Redmineがいてポートが被ったので変更しました
HTTP Port Number
[8091]
8095
Control Port Number
[8010]
Details on where JIRA Core will be installed and the settings that will be used.
Installation Directory: /home/hiroyuki_fukui_va/atlassian/jira 
Home Directory: /home/hiroyuki_fukui_va/atlassian/application-data/jira 
HTTP Port: 8095 
RMI Port: 8010 
Install as service: No 
Install [i, Enter], Exit [e]
i
Extracting files ...
                                                                           
Please wait a few moments while JIRA Core starts up.
Launching JIRA Core ...
Installation of JIRA Core 7.1.4 is complete
Your installation of JIRA Core 7.1.4 is now ready and can be accessed via
your browser.
JIRA Core 7.1.4 can be accessed at http://localhost:8095
Finishing installation ...


```

以上
MaxProductOfThree

名前の通り、Answer the maximum product of three numbers in the numbers! って感じの課題ですね。

## [1st][a]

あれ？

<table>
    <tr><th>Correctness</th><th>Performance</th><th>Task Score</th></tr>
    <tr>
        <td>50%</td>
        <td>40%</td>
        <td>44%</td>
    </tr>
</table>

```php:MaxProductOfThree-1.php
function solution($A) {
    rsort($A);
    return ($A[0] * $A[1] * $A[2]);
}
```

```php:TestMaxProductOfThree-1.php
use PHPUnit\Framework\TestCase;
include 'MaxProductOfThree-1.php';

class TestMaxProductOfThreeTest extends TestCase {

    public function testExpect60() {
        $array = array(-3, 1, 2, -2, 5, 6);
        $ans = solution($array); $this->assertEquals(60, $ans);
    }

    public function testExpect6() {
        $array = array(1, 2, 3);
        $ans = solution($array); $this->assertEquals(6, $ans);
    }

}
```

例題と３値のケースは通った。
と思ったら、アホやった。

> The product of triplet (P, Q, R) equates to A[P] * A[Q] * A[R] (0 ≤ P < Q < R < N).

これ。全然条件満たしてなかった。やり直し。

## [2nd][b]

<table>
    <tr><th>Correctness</th><th>Performance</th><th>Task Score</th></tr>
    <tr>
        <td>100%</td>
        <td>100%</td>
        <td>100%</td>
    </tr>
</table>

```php:MaxProductOfThree-2.php
function solution($A) {
    $N = count($A);
    $product = 0;

    rsort($A);
    $max = $A[0] * $A[$N-2] * $A[$N-1];

    for($i = 2; $i < $N; $i++) {
        $product = $A[$i-2] * $A[$i-1] * $A[$i];
        if($product > $max) {
            $max = $product;
        }
    }

    return $max;
}
```

  一回目での失敗は、例えば [-1, 5, -9, 7] という配列が与えられたとき、`rsort()` して先頭から
数えるだけだったため、**負の数を考慮できていなかった**こと。
上記の配列は `rsort()` すると、[7, 5, -1, -9] となるが、これを先頭から三つ乗算すると、 -35 に
なる。しかし、負の数で掛け合わせてから 7 とかけると、(-1 * -9) * 7 = 63 となる。ゆえに最大値は
63 なのだが、これを考慮出来ていなかった。
  これを解決する手段として、`$max` の初期値を変更した。以下の通り。

```diff
- $max = $A[0] + $A[1] + $A[2];
+ $max = $A[0] * $A[$N-2] * $A[$N-1];
```

これが決め手となった。後者は、`rsort()` した後の最後の２つ、つまり最小値と二番目の最小値を意味
する。よって、その２つの値が負の数のとき、`$max` は正の値となり、それらの絶対値が配列の値の
すべての絶対値の中で３番以内に大きいとき、`$max` が求める答えになる。そうでないときは、`for` 
ループによって正の数を三つ使い最大値を求める。
  一応、*Painless* の問題らしいが、少し *Pain* を感じてしまった。まだまだコーディングのレベルが
低いんだろう。

<!-- 以下、参考 URL -->
[a]: https://app.codility.com/demo/results/training42E963-FVV/
[b]: https://app.codility.com/demo/results/trainingDE8A4J-HEF/
Ruby open-uri の open の戻り値

# Ruby open-uri の open の戻り値

## Ruby open-uri ライブラリの open メソッド

open メソッドは引数に URL を取り、通常呼び出し or ブロック呼び出しのいずれかのスタイルを取ります。

```ruby
require 'open-uri'

file = open('https://hogehoge.com/image.jpg')
# 何らかの処理
file.close
```

```ruby
require 'open-uri'

open('https://hogehoge.com/image.jpg') do |file|
  # 何らかの処理
end
```

## open メソッド戻り値の型

ここで戻り値 (上記の場合 `file`) は、実は開こうとしたファイルのサイズによって、戻り値の型が以下のように変わるようです。

- 10 kb (10,240 bytes) より大きい場合、 [Tempfile](https://docs.ruby-lang.org/ja/latest/class/Tempfile.html)
- 10 kb (10,240 bytes) 以下の場合、 [StringIO](https://docs.ruby-lang.org/ja/latest/class/StringIO.html)

これは結構罠で、例えば Tempfile であることを期待して `file.path` なんて呼んでしまうと、以下のような例外が出てしまうケースがあります。

```
undefined method `path' for #<StringIO:0x00005583b538edc8>
```

## 対策

なら、どうするかということで、 10kb のしきい値を決めている `OpenURI::Buffer` の定数 `StringMax` を無理やり書き換えるなんで荒業もあるようですが、いい方法とは思えません。
もし常に Tempfile であることを期待したいのであれば、素直に手動で Tempfile を作るしか無いのかなぁという、現在までの結論です。

```ruby
temp_file = Tempfile.new('test_')
temp_file.binmode
open('https://hogehoge.com/image.jpg') do |file|
  # read は Tempfile でも StringIO でも duck typing でいけます。
  # 本来ならこれを handling すれば問題ないのですが、あくまで Tempfile であることを期待したい場合は...
  temp_file.write(file.read)
end
temp_file.rewind

# 何らかの処理

temp_file.close
```

> References

- [library open-uri (Ruby 2.5.0)](https://docs.ruby-lang.org/ja/latest/library/open=2duri.html)
- [Rubyのopen_uriでファイルオブジェクトがTempfileになる瞬間を追った - Qiita](https://qiita.com/Pujyoooo/items/96c680a156405b8cd442)
- [ruby - Why does OpenURI treat files under 10kb in size as StringIO? - Stack Overflow](https://stackoverflow.com/questions/10496874/)
- [OpenURI's open, Tempfile and StringIO - WinstonYW](http://winstonyw.com/2013/10/02/openuris_open_tempfile_and_stringio/)
- [Ruby - Reading A Remote Zip File - WinstonYW](http://winstonyw.com/2013/10/01/ruby_reading_a_remote_zip_file/)
Android KTXを使ってみた〜contentValuesOf編〜

# 検証環境
この記事の内容は、以下の環境で検証しました。

* Java:open jdk 1.8.0_152
* Kotlin 1.2.10
* Android Studio 3.0.2
* CompileSdkVersion:26
* MinSdkVersion:21
* TargetSdkVersion:26
* BuildToolsVersion:26.0.2
* gradle:4.0.0
* Android KTX:0.1

# Android KTXとは
AndroidアプリのKotlinコードを簡潔に快適に記述できるように設計された拡張機能です。
提供元は*Google*です。オフィシャルのライブラリーになります。
※この記事を書いている時点（2018/02/08）では、プレビュー版のため、今後、APIの変更も予想されます。ご注意ください。

# 参考
Android Develpers Blog
https://android-developers.googleblog.com/2018/02/introducing-android-ktx-even-sweeter.html

Github
https://github.com/android/android-ktx/

API reference
https://android.github.io/android-ktx/core-ktx/

# 目標
Android KTXを利用したContentValuesの生成方法で、従来の記述方法との違いを確認する。

# 準備
Android KTXを使用するために、下記をbuild.gradleに追記してください。

```groovy:build.gradle（一部省略）
repositories {
    google()
}
dependencies {
    implementation 'androidx.core:core-ktx:0.1'
}
```

## 注意点
Android KTXはcompileSdkVersionが27になっていなければ使用できません。
また、compileSdkVersionを27にする場合、その他のライブラリもバージョンを上げる必要があります。
結果的に以下のような形になります。

```groovy:build.gradle（一部省略）
android {
   compileSdkVersion 27
}
repositories {
    google()
}
dependencies {
    implementation 'com.android.support:appcompat-v7:27.0.2'
    implementation 'androidx.core:core-ktx:0.1'
}

```


# 実装
## 今回の例
テーブルにレコードを挿入するコードを例とします。

## テーブル
今回は下記のテーブルを使用します。
テーブル名：User

|列|型|
|---|---|
|id| INTEGER |
|name|Text|


## データベースアクセス

Android KTXで記述すると以下のようになります。

```kotlin
val dbHelper = DatabaseOpenHelper(this)
dbHelper.writableDatabase.use {
    // KTXでの書き方
    val taroCvo = contentValuesOf("id" to 1, "name" to "太郎")
    it.insert("User", null, taroCvo)

    val hanakoCvo = contentValuesOf("id" to 2, "name" to "花子さん")
    it.insert("User", null, hanakoCvo)
}
```

従来の記述方法で書くと以下のようになります。

```kotlin
val dbHelper = DatabaseOpenHelper(this)
dbHelper.writableDatabase.use {
    // 従来の書き方
    val taroCv = ContentValues().apply {
        put("id", 1)
        put("name", "山田太郎")
    }

    val hanakoCv = ContentValues().apply {
        put("id", 2)
        put("name", "花子さん")
    }

    it.insert("User", null, taroCv)
    it.insert("User", null, hanakoCv)
}
```

差分だけを抜き出すと以下のようになります。

```kotlin
// KTXでの書き方
val taroCvo = contentValuesOf("id" to 1, "name" to "太郎")
it.insert("User", null, taroCvo)

val hanakoCvo = contentValuesOf("id" to 2, "name" to "花子さん")
it.insert("User", null, hanakoCvo)

// 従来の書き方
val taroCv = ContentValues().apply {
    put("id", 1)
    put("name", "山田太郎")
}

val hanakoCv = ContentValues().apply {
    put("id", 2)
    put("name", "花子さん")
}

it.insert("User", null, taroCv)
it.insert("User", null, hanakoCv)
```
従来の記述方法では、事前にContentValuesクラスのオブジェクトを生成してからinsertメソッドを呼び出してレコードを挿入していました。
Android KTXを利用することにより、contentValuesOfを呼び出し、Pairを利用しContentValuesが簡潔に生成できるようになりました。
管理者権限がないWindows環境でPython(WinPython)を導入する

# WinPythonを使うモチベーション

分析をする際に、(データの権限周りとか)諸々の都合で、用意されたPCで作業することがよくある。
ただ、モデルの作成など高度なことをしようとすると、それなりの分析環境が用意されてないと難しい。
そういう訳で、分析環境を用意したいが、管理者権限が与えられていないことが多いので、その制約下でも使用できるWinPythonを使ってみた。
（ソフトウェアの導入には、セキュリティやコンプライアンス関連による障害が起きることもあるが、ここでは割愛）

選択肢としてPythonを選ぶのは、趣味もあるけど、やはりデータ分析の一連の工程(データ加工、集計、モデル作成、可視化など)をまとめてでできるのが魅力的だから。

# WinPythonのインストールまで

[WinPythonの配布ページ](https://winpython.github.io/)から欲しいバージョンをダウンロードする。

後は、インストーラの指示に従って、インストール設定をする。簡単。
**インストール先にユーザフォルダ配下を指定すれば、管理者権限が無くてもインストールできる。**

インストールフォルダに、インタプリタやSpyder(IDE)、jupyter notebookなどのexeがインストールされているので、任意のアプリケーションを起動すると、それらを介してPythonが利用できる。

# WinPython環境へのモジュールのインストール

WinPythonのインストール直後は、デフォルトで用意されているモジュールが限られている。
しかし、モジュールの追加もできるので一安心。

jupyter notebookを使う場合は、ノートブック上で「!pip install [モジュール名]」を実行。

それ以外の方法でも、インストール先にできている「WinPython Control Panel.exe」を使うと、gitとかからダウンロードしたモジュールデータを手動で追加できるみたい(未確認)。
Nowを使ってNext.jsのアプリをデプロイする時にFile size limit exceededになる時の対処

無料プランだと1MBしかファイル容量が無い

```
$ now -d
```

をするとどのファイルでエラーになっているかわかる。
大体Webpackのビルドファイルやsourcemapの容量が1MBを超えているのが原因

```
$ next build
```

上記コマンドを事前に実行してと本番用にminifyしてビルドされるので容量が削減される。あとはエラーになったsoucemapファイルを削除しておく。

```
$ now -d
```

それらを対策してから`now`すればデプロイされるはず
manjaro-cinnamonに(今更)乗り換えた時の覚え書き1 〜インストールまで

# はじめに
毎回、新規環境構築の時につまずくので、メモを残すことにしました。
あくまで自分(+初心者)のためのメモのつもりで書いているので、熟練の方は興味ない部分はすっとばしてください。~~(そもそも熟練の人はこんな記事見ない)~~
また、将来記憶喪失になることも考え(適当)、くどいほど説明を書きます。

## 経緯
とりあえず、僕は２年毎位に「そろそろ環境変えたい」って思う人種の人間でして、
[UBUNTU](https://www.ubuntulinux.jp)とmateの環境に飽きが来たのと環境がゴチャゴチャして来たのを機に環境を変えることにしました。

で、折角個人の環境ですし、[Arch](https://www.archlinux.jp)みたいなローリング・リリースのOSにしたい･･････
でも、初心者マークを貼り付けた人間が1からやっていくのは厳しい･･････
って事で、最近流行りの[Manjaro](https://wiki.manjaro.org)をチョイスしました。
~~(実質Arch linux)~~ 

# Manjaroの導入
## isoイメージの作成
どのOSを使うにも、まずはISOイメージ入りのUSBの作成からです。
ということで、Manjaroの場合は[こちら](https://wiki.manjaro.org/index.php?title=Burn_an_ISO_File)にやり方が書いてありますので、こちらを参考にしました。

今回は手元にCDがないのでUSBを使います。
UBUNTUで焼く方法も考えましたが、面倒だったのでWindowsで焼きました。
いつもの[unetbootin](https://unetbootin.github.io)先輩は残念ながら未対応との事ですので、
[Diskimager](https://launchpad.net/win32-image-writer/)をインストールしまして、
[ここ(公式サポートのKDE,GNOME,xfce)](https://sourceforge.net/projects/manjarolinux/files/release/)か[ここ(それ以外のdesktop)](https://sourceforge.net/projects/manjarolinux-community/files/)から好きなISOを落としてきまして、
あとはUSBを挿したPCでDiskimagerでISOをUSBに焼いておしまい。

ちなみに、僕は折角なので使ったことのないCinnamonを選択しましたが、ここは慣れたDesktopか好みのものがいいかと思います。

## manjaroのインストール
### USBからの起動
PCを再起動します。
ここでBIOSを開くのですが、[^1]この時、SecureBoot[^2](←の脚注をよく参照すること)をOFFにしましょう。そうしないとUSBイメージの起動すらできません。
[^1]: 大概はF2,F10,F12,Delのどれかを長押しか連打)(各PC毎に違うのでなんとも言えません。)
[^2]: [セキュアブート](https://freesoft.tvbok.com/tips/efi_installation/about_secure_boot.html)とは、署名のあるOSのみ起動する（意訳）機能なので、*当然これをOFFにする事にはそれに相当するデメリットがあります。* *初めての人はそれを理解した上で切りましょう。* いやならUBUNTUなんかはonでも起動しましたので、そういった初心者向け、と言われるものを使いましょう(初心者並感)。

で、同時にBootの順番を変更し、USBが一番最初に起動するように設定すればOK。
保存して再起動すれば、ごちゃごちゃエラーやら成功やらの黒画面がでて、無事Manjaroのメニューが起動するはずです。十字キーとEnter、escキーを駆使して、簡単な言語設定だけしておきましょう。
"language"= の部分を選択してEnter、下に下がって"language=jp"をチョイス。
これで(少なくとも今回の起動に関しては)日本語で表示をしてくれます。
他も、timetableはAsia→Asia/Tokyoだったりとか設定すると、インストールのときに自動でそのあたりの設定を推奨してくれます。

### PCへのインストール
まず、メニューバーからネットワークを示す部分を探します(Desktopによって違うのでなんとも言えない)。
そこでインターネットにつなぎましょう(繋げなくてもなんとかはなりますが、つなげるときはつなぐことを推奨します)。
次に、 "Install manjaro" とかいう部分をクリックし、GUIの指示に従ってインストールすれば 誰でも簡単にインストールできます。出来るはずです。[^3]
[^3]: よくあるLinuxのGUIインストール画面とほぼ同じです。UBUNTUやらmintやらがインストール出来たなら簡単なはずです。
あとは終了するまで待って、再起動しますか？といった感じのメッセージに「はい」を選択すれば終わりです。電源が切れたタイミングでUSBを抜きましょう。

### 続き
Linux使いは、むしろここからの設定が本番ですが、(実際、地獄の１日を過ごした)
続きが長くなると思いますので、とりあえず終わりにします。
続きは気が向いたときに、忘れないうちに書くつもりです。

追記：1文字もコードを書いていないですね…。次はコードでいっぱいになるはずです。
Buttonのbackground drawableの実装を効率よくやっていくTips

## selectableの実装がめんどくさい

- 本当に本当のTipsです
- わざわざ実機やエミュレータで動かさなくても、Layout file上で、例えば `tools:enabled` を変更するとpreviewがそれに追随するためやりやすいです
- `enabled="true"` を確認したい
  - ![スクリーンショット 2018-02-16 10.01.49.png](https://qiita-image-store.s3.amazonaws.com/0/32424/16de53d9-2871-ac01-df6c-0d8fb35e312f.png)
- `enabled="false"` を確認したい
  - ![スクリーンショット 2018-02-16 10.03.13.png](https://qiita-image-store.s3.amazonaws.com/0/32424/aea81644-720e-8990-bd83-9cb01c9cdde4.png)
CSS3で角丸のボーダーをアニメーションさせる

## CSS3で角丸のボーダーをアニメーションさせる

CSSでミシンっぽい表現のアニメーションを作ってみたかったのでやってみました。
ミシン感あるかどうかは諸説ありですが、なんとなくできました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5557/0af791c4-a669-57b4-30ed-e7d07d657257.png)


動くサンプルはこちらです。
[jsfiddle](https://jsfiddle.net/shinobu_shiva/3u8wys3y/12/)
オレンジの領域をホバーするとアニメーションが開始します。

検索ではボーダーシャドウを使ってやる方法は多くヒットしたのですが、
角を丸くすることができなさそうだったので試してみました。

beforeとafter疑似要素を使って、ボーダーの上に色を乗せて隠しておき、
アニメーションで隠している部分の位置とサイズを調整して徐々に表示していく感じです。

コードは次のとおりです。

```html:HTML
<div class="draw">
  <div class="border">
    <div class="content">
      Rounded border animation
    </div>
  </div>
</div>
```

CSSはSassで記述しています。

```scss:CSS(SCSS)
$speed: 2s;
$base-color: orange;
$color: white;

.content {
  z-index: 2;
  position: relative;
  display: block;
  padding: 20px;
  color: $color;
  text-shadow: -1px -1px #d48020;
  
}

.draw {
  width: 300px;
  height: 70px;

  margin-top: 100px;
  margin-left: 100px;
  
  top: calc(50% - 50px);

  background: $base-color;
  border: 0;
  box-sizing: border-box;

  border: 2px dashed $color;
  border-radius: 10px;
  font-size: inherit;
  font-weight: bold;
  position: relative;
  vertical-align: middle;

  &::before {
    display: block;
    position: absolute;
    background-color: $base-color;
    content: '';
    box-shadow: 0 0 0 4px #FBA848, 2px 1px 6px 4px rgba(10, 10, 0, 0.5);

    top: -10px;
    left: -10px;
    width: calc(100% + 20px);
    height: calc(100% + 20px);
    border-radius: 10px;
    z-index: -1;
  }
}

.border {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;

  &::before {
    display: block;
    position: absolute;
    background-color: $base-color;
    content: '';

    top: -5px;
    left: -5px;
    width: calc(100% + 10px);
    height: calc(100% + 10px);
    border-radius: 10px;
  }

  &::after {
    display: block;
    position: absolute;
    background-color: $base-color;
    content: '';

    top: 0px;
    left: -5px;
    width: calc(100% + 5px);
    height: calc(100% + 5px);

    border-radius: 10px;
  }

  &:hover::before {
    top: calc(100% + 5px);
    left: 100%;
    width: 5px;
    height: 0;
  }
  
  &:hover::after {
    left: -5px;
    width: 5px;
    height: 0;
  }

  &:hover::before {
    transition:
      width $speed ease-out,
      left $speed ease-out,
      height $speed ease-out $speed,
      top $speed ease-out $speed;
  }

  &:hover::after {
    transition:
      width $speed ease-out $speed * 2,
      height $speed ease-out $speed * 3;
  }
}
```
Windows > link:Explorerからファイルリストを取得しテキストファイルとする

```txt:動作環境
Windows 8.1 Pro (64bit)
Sublime Text2 Version 2.0.2, Build 2221
```

Explorerに表示されるファイルリストをテキストファイルとして取得する。

https://stackoverflow.com/questions/1187479/copy-a-file-list-as-text-from-windows-explorer

- Shift押しながら右クリックした時に表示される「パスのコピー」を選択
- Sublime TextにてCtrl+v
- 不要なフォルダ表記などはSublime Textでマルチ選択し取り除く
    - 置換を使ってもよい
    
ファイルリストに対して付随情報を追記したExcelファイル作成時に上記の作業が発生した。
RustでAlpineからHTTPS

## 目的
`x86_64-unknown-linux-musl`でビルドしたバイナリを使って、DockerコンテナのAlpineからHTTPS通信をしたい！

HTTPS通信と書いていますが、想定しているユースケースは`hyper`を使った通信処理です。
[gotham](https://github.com/gotham-rs/gotham/)など多くのWebFrameworkが`hyper`を使用しているため、WebServerを作る場合のTipsでもあります。

Ubuntuでビルドして、Ubuntuで起動するなら簡単ですが、`musl`を使ってBuildし
Alpineで起動するとハマりどころが多いのでメモっておきます。

## 前提
軽量なDockerイメージにするため、Compile OSとRuntime OSを分けます。

## 環境
- Compile OS: ubuntu16.04
- Runtime OS: alpine3.7
- Rust: v1.23
- Target: `rust-opensslx86_64-unknown-linux-musl`
- SSL Lib: OpenSSL(openssl-rust)
    - [rust-openssl](https://github.com/sfackler/rust-openssl)
- [サンプルソース](https://github.com/watawuwu/sample-rust-alpine-https)
    - `make`で実行

## 設定

### Compile時の設定
OpenSSLを静的リンクするために以下の設定を行います。

- OpenSSLを`musl-libc`を使ってコンパイルし、Staticなlibraryを用意
- 静的リンクするためのビルド設定を環境変数に設定
    - `OPENSSL_STATIC=1`
    - 必要に応じて`OPENSSL_`プリフィックスで始まる環境変数の設定

具体的には[こちら](https://github.com/emk/rust-musl-builder/blob/master/Dockerfile#L62-L96)のDockerfileが参考となります。

### Runtime時の設定
Linuxディストリビューションによって証明書のパスが違うため、証明書のパスを設定する必要があります。
Alpineで実行する際には以下の設定をします。

```
$ apk add --no-cache ca-certificates && update-ca-certificates
$ export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
$ export SSL_CERT_DIR=/etc/ssl/certs
```

他の方法として、Alpine以外のLinuxディストリビューションでも動作させたい場合、[openssl-probe](https://crates.io/crates/openssl-probe)を使うことで証明書のパスをRuntime時に解決できます

```
[dependencies]
openssl-probe = "0.1"
```

`init_ssl_cert_env_vars()`を実行する。

```
extern crate openssl_probe;

fn main() {
    openssl_probe::init_ssl_cert_env_vars();
    //... your code
}
```

## Docker
上記で紹介した[イメージ](https://hub.docker.com/r/ekidd/rust-musl-builder/)を利用しMultiStageでbuildすると、軽量なDockerイメージを作成できます。

```
FROM ekidd/rust-musl-builder:stable AS rust-builder
ADD . .
RUN cargo build --release --target x86_64-unknown-linux-musl

FROM alpine:3.7
COPY --from=rust-builder /home/rust/src/target/x86_64-unknown-linux-musl/release/{bin} /usr/local/bin
RUN apk add --no-cache ca-certificates && update-ca-certificates
ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
ENV SSL_CERT_DIR=/etc/ssl/certs
CMD ["{bin}"]
```

[サンプルソース](https://github.com/watawuwu/sample-rust-alpine-https)では13Mと軽量なDockerイメージを作ることができました。

## 備考
証明書が発見できない場合は以下の様なエラーが発生します。

```
The OpenSSL library reported an error: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed:s3_clnt.c:1269
```
TouchDesignerでPythonコードとDAT間で入出力する

#Table DAT→Python(Text DAT)入力
<img width="259" alt="スクリーンショット 2018-02-16 9.39.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/77925/3efc86e6-bf29-187a-c126-45175f4ae5b9.png">
１と2をPythonを使って足してほしいとき、みなさんもこれまでの人生何度もあったと思います

##そんなときはこう
```python:input
n = op('table1')[0,0] + op('table2')[0,0]
print(n)
```
★[縦,横]です

<img width="403" alt="スクリーンショット 2018-02-16 9.41.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/77925/d422d532-6d51-a056-f60d-75b700a17818.png">
⌘+Rしましょう

##答えは
<img width="558" alt="スクリーンショット 2018-02-16 9.43.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/77925/4e9959f6-5e81-aa6f-ecd0-34b045fbcf8c.png">
世界に平和が訪れた


#Python(Text DAT)→Table DAT出力
<img width="420" alt="スクリーンショット 2018-02-16 9.34.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/77925/e7793ca7-a024-ff63-3328-0d3e7a00ffca.png">
1+1の計算結果をPythonで知りたいとき、みなさんもこれまでの人生何度もあったと思います

<img width="427" alt="スクリーンショット 2018-02-16 9.35.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/77925/094ab8b4-fbbe-5b2c-af9b-de182aee3ea2.png">
普通に⌘＋RでRun Scriptすれば

<img width="530" alt="スクリーンショット 2018-02-16 9.36.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/77925/4a19c2f9-e85a-ad1b-d528-6b596564b8d3.png">
Textportで結果を見られます。

<img width="287" alt="スクリーンショット 2018-02-16 9.45.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/77925/7dc66164-6ce4-46b7-52e1-7723d3b48353.png">
でもなんとしてもtable3に入れてほしいときが、あなたの人生にも訪れると思います

##そんなときはこう
```python:output
n = 1+1
op('table3')[0,0] = n
```
マジかそんな簡単でええんか…と思いましたがいいようです
参考：http://derivative.ca/Forum/viewtopic.php?f=27&t=9721

<img width="369" alt="スクリーンショット 2018-02-16 9.49.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/77925/dc5ed404-73ab-2d70-e7f5-d2a9168efd3e.png">


##答えは
![1518742113493.gif](https://qiita-image-store.s3.amazonaws.com/0/77925/7b903801-f971-b279-2c85-b959896489a6.gif)
世界に平和が訪れた

`moviefilein1`とかのときは`op( 'moviefilein1' ).par.file = url`みたいにパラメータ指定して入れてあげるとできちゃうみたいです。みなさま快適な入出力ライフを
Ubuntu16.04にriakを入れます😉

## Riakのインストール

`curl -s https://packagecloud.io/install/repositories/basho/riak/script.deb.sh | sudo bash`
`sudo apt-get install riak=2.2.3-1`

### riak.confのバックアップ

- `cp -a /etc/riak/riak.conf /etc/riak/riak.conf.bak`

## riak.confの設定

1. `sudo vim /etc/riak/riak.conf`
2. `riak.conf`を編集
 
```riak.conf
storage_backend = leveldb
nodename = riak@192.168.0.111 ## サーバのIP
listener.http.internal = 0.0.0.0:8098
listener.protobuf.internal = 0.0.0.0:8087
riak_control.auth.user.admin.password = naruhaya
```

## 起動

`sudo riak start`

## 参考

- [Riakインストール手順(Qiita)](https://qiita.com/hit/items/6ae19345ddc14fd6c2d2)
- [riak](https://packagecloud.io/basho/riak/packages/ubuntu/xenial/riak_2.2.3-1_amd64.deb)
GoアプリケーションをSupervisorでデーモン化😘

Goは言語レベルでのデーモン化がサポートされていない（らしい）のでSupervisorやsystemdでデーモン化します。

## Supervisorの導入

`sudo apt-get install supervisor`

## Goアプリケーションのビルド

`go build hoge`

## supervisord.confの編集

`sudo vim /etc/supervisor/supervisord.conf`

以下を追記

```
[program:hoge]
command = /path/to/hoge
autostart = true
startsecs = 5
user = root
redirect_stderr = true
```

## supervisorの実行

`sudo supervisord`

### エラーが出たら

> Error: Another program is already listening on a port that one of our HTTP servers is configured to use.  Shut this program down first before starting supervisord.
 
こいつが出たら

`ps -ef | grep supervisord`

を実行

```
root     17310     1  0 05:40 ?        00:00:02 /usr/bin/python /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
pi       17638 16611  0 06:17 pts/0    00:00:00 grep --color=auto supervisord
```

pidを確認してkillする

`kill 17310`

## 参考

[Supervisor を利用して Go アプリケーションをデーモン化する](https://qiita.com/macococo/items/71a007ecd3c176cc3529)
[Supervisorで簡単にデーモン化](https://qiita.com/yushin/items/15f4f90c5663710dbd56)