OmniAICreator/Qiita-1.07M huggingface dataset:
Gradleで実行可能なjarファイルを作成する

## 前提条件

- intelliJ
- java8

## 手順

### intelliJで、Gradleプロジェクトを作成する

<img width="294" alt="スクリーンショット 2018-02-18 18.59.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/114561/df224fe8-514e-4ddf-7306-282a3cd9adf7.png">

### 簡単なJavaプログラムを作成して、Gradleの設定ファイルを編集する
```java:src/main/java/HelloWorld.java
public class HelloWorld {
    public static void main(String... args) {
        System.out.println("Hello World");
    }
}
```

build.gradle（一部抜粋）

```gradle:build.gradle
group 'helloworld'
version '1.0-SNAPSHOT'

apply plugin: 'java'

sourceCompatibility = 1.8

// （中略）

jar {
    manifest {
        attributes 'Main-Class': 'HelloWorld'
    }
}
```

### 実際にjarファイルを作成する

以下のgradleコマンドを実行すれば、プロジェクトのbuildディレクトリ配下にjarファイルが作成される

```
$ gradle build
Starting a Gradle Daemon (subsequent builds will be faster)
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:assemble
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build

BUILD SUCCESSFUL

Total time: 7.82 secs
```
<img width="297" alt="スクリーンショット 2018-02-18 19.02.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/114561/243b3850-63b0-6fe9-5d16-a13cdf528d95.png">
メソッドチェーンで遊ぶ

####
![スクリーンショット 2018-02-18 19.01.34.png](https://qiita-image-store.s3.amazonaws.com/0/166241/edf9de7c-7269-3bae-58f4-f5b05af9387b.png)

UILabelに愛してると表示するとき

``` swift:
        let label = UILabel()
        label.frame.origin = CGPoint(x: 100, y: 100)
        label.frame.size = CGSize(width: 200, height: 50)
        label.backgroundColor = .red
        label.layer.cornerRadius = 25
        label.clipsToBounds = true
        label.text = "i love you"
        label.textColor = .white
        label.textAlignment = .center
        view.addSubview(label)
```
labelって描くのめんどくさいとふと思いメソッドチェーンぽく描いて遊んでみた。

``` swift:
    let label = UILabel().chain
        .origin(x: 100, y: 100)
        .size(width: 200, height: 50)
        .backgroundColor(.red)
        .cornerRadius(25)
        .clipsToBounds()
        .text("i love you")
        .textColor(.white)
        .alignment(.center)
        .object()
    view.addSubview(label)
```

やっぱりメソッドチェーンはxcodeの補完でサクサクかけて楽チンだと思う。



#### 実装

``` swift:

protocol Chainable {}

extension Chainable where Self: UIView {
    var chain: ChainMaker<Self> {
        return ChainMaker(self)
    }
}

class ChainMaker<T> {
    
    private var base: T
    init(_ base: T) {
        self.base = base
    }
    
    func object() -> T {
        return base
    }
}

extension UIView: Chainable {}
```


とりあえずこれでUIViewがchainプロパティーを持つのでChainMaker（仮）を拡張していく
object()メソッドはキャスト用で最後に使う。

``` swift:

extension ChainMaker where T: UIView {
    
    func origin(x: CGFloat, y: CGFloat)  -> ChainMaker<T> {
        base.frame.origin = CGPoint(x: x, y: y)
        return self
    }
    
    func size(width: CGFloat, height: CGFloat)  -> ChainMaker<T> {
        base.frame.size = CGSize(width: width, height: height)
        return self
    }
    
    func backgroundColor(_ color: UIColor) -> ChainMaker<T> {
        base.backgroundColor = color
        return self
    }
    
    func clipsToBounds() -> ChainMaker<T> {
        base.clipsToBounds = true
        return self
    }
    
    func cornerRadius(_ radius: CGFloat) -> ChainMaker<T> {
        base.layer.cornerRadius = radius
        return self
    }
}

```


``` swift:
extension ChainMaker where T: UILabel {
    
    func text(_ text: String) -> ChainMaker<T> {
        base.text = text
        return self
    }
    
    func textColor(_ color: UIColor) -> ChainMaker<T> {
        base.textColor = color
        return self
    }

    func alignment(_ alignment: NSTextAlignment) -> ChainMaker<T> {
        base.textAlignment = alignment
        return self
    }
}
```

#### 追記

クロージャーで描いた方がスッキリしてていいですね

``` swift:
extension Chainable where Self: UIView {
    
    func chain(_ closure: (ChainMaker<Self>)->(ChainMaker<Self>)) -> Self {
        let maker = ChainMaker(self)
        return closure(maker).object()
    }
}
```

``` swift:
        let label = UILabel().chain { $0
            .origin(x: 100, y: 100)
            .size(width: 200, height: 50)
            .backgroundColor(.red)
            .cornerRadius(25)
            .clipsToBounds()
            .text("i love you")
            .textColor(.white)
            .alignment(.center)
        }
        view.addSubview(label)
```
Digit Recognizer Overview

[Digit Recognizer](https://www.kaggle.com/c/digit-recognizer)

# Description
* computer vision 初心者の導入にいい
* 手書き画像は分類アルゴリズムのベンチマークとして古典的なもの
* このコンペの目的は数万の手書き画像データセットを識別すること
* 回帰からニューラルネットワークまでをカバーしたチュートリアルを用意されている
* 様々なアルゴリズムを実験できる
* 身につくスキル
    * ニューラルネットワークの基本
    * サポートベクターマシン・k 近傍法などの分類法
* よりデータセットの詳細を知りたければ[ここに](http://yann.lecun.com/exdb/mnist/index.html)

# Evaluation

* 一桁の数の手書き画像を識別
* 各 ImageId に解答 label を記載
* メトリック
    * 解答の正確性
* 解答フォーマット

```
ImageId,Label
1,0
2,0
3,0
etc.
```

# Tutorial

* Kaggle Kernels はブラウザ内計算環境
* Kernels には多くのライブラリやパッケージが preload されている
* R と Python が利用可能
* ファイルの提出と競技データの探索ができる
    * 新しいスクリプト or notebook の作成
    * 他の kernel の fork
* 競技を始めるのに最適な kernel をいくつか選んだ
    * Python
        * [A beginner’s approach to classification](https://www.kaggle.com/archaeocharlie/a-beginner-s-approach-to-classification)
            * scikit-learn’s SVM
        * [Deep neural network the Keras way](https://www.kaggle.com/poonaml/deep-neural-network-keras-way)
            * standardization と One-Hot を含む前処理をカバー
            * Keras を使ったニューラルネットワーク
            * Inspired by Jeremy Howard’s fast.ai deep learning MOOC
        * [Simple deep MLP with Keras](https://www.kaggle.com/fchollet/simple-deep-mlp-with-keras/code)
            * Keras を 使った MLP の実装
            * Francois Chollet (Keras の作成者) から Keras を学べる
        * [An introduction to dimensionality reduction](https://www.kaggle.com/arthurtok/interactive-intro-to-dimensionality-reduction)
            * Dimensionality Reduction テクニックの PCA, LDA, t-SNE の比較と紹介
            * Plotly の使用
* [Follow TensorFlow's Python tutorial](https://www.tensorflow.org/tutorials/layers)
AWS Lamabda で Amazon S3 からファイルをダウンロードする

この記事は、AWS Lamabda で Amazon S3 からファイルをダウンロードする際のメモです。


# 環境

- AWS Lambda の実行環境
  - [Node.js 6.10.3](https://nodejs.org/dist/v6.10.3/docs/api/)
- AWS SDK for JavaScript
  - [Release v2.194.0](https://github.com/aws/aws-sdk-js/releases/tag/v2.194.0)


# コード

```js
const s3 = new AWS.S3({
  apiVersion: '2006-03-01',
  signatureVersion: 'v4'
});

function download(srcBucket, srcObjectKey, dstFilePath) {
  return new Promise((resolve, reject) => {
    const params = {
      Bucket: srcBucket,
      Key: srcObjectKey,
    };
    let error = null;
    const writeStream = fs.createWriteStream(dstFilePath);
    s3.getObject(params)
      .createReadStream()
      .on('error', (err) => {
        console.error('Failed to read object from S3: ', error);
        error = err;
        writeStream.end();
      })
      .pipe(writeStream)
      .on('error', (err) => {
        console.error('Failed to write file to local: ', error);
        error = err;
        writeStream.end();
      })
      .on('close', () => {
        if (error) {
          reject(error);
          return;
        }
        resolve();
      });
  });
}
```

## ダメなコード

以下のようなコードを書くと、正常系は動作するものの、S3 の object が存在しない場合に **NoSuchKey** のエラーが捕捉しきれずに、Lambda が異常終了します。。。

> NoSuchKey: The specified key does not exist.

```js
const s3 = new AWS.S3({
  apiVersion: '2006-03-01',
  signatureVersion: 'v4'
});

function download(srcBucket, srcObjectKey, dstFilePath) {
  return new Promise((resolve, reject) => {
    const params = {
      Bucket: srcBucket,
      Key: srcObjectKey,
    };
    let error = null;
    const writeStream = fs.createWriteStream(dstFilePath);
    const request = s3.getObject(params);
    request.on('error', (err) => {
      console.error('Failed to read object from S3: ', error);
      error = err;
      writeStream.end();
    });
    writeStream.on('error', (err) => {
      console.error('Failed to write file to local: ', error);
      error = err;
      writeStream.end();
    });
    writeStream.on('close', () => {
      if (error) {
        reject(error);
        return;
      }
      resolve();
    });
    request.createReadStream().pipe(writeStream);
  });
}
```
軽い気持ちでLinkedListを使ったら休出する羽目になった話

# ざっくり言うと
リスト構造のデータに対してランダムアクセスはしちゃだめだぞ。お兄さんとの約束だ！

# 発端
数年前に他部署の支援で作ったJavaのシステムに、ちょっとデカめのデータを突っ込んだらありえないほど遅いので助けてくれ、と連絡が入った。

まぁクエリとかインデックスをちょっと見れば直るっしょ・・・と鼻をほじりながら支援に向かった。

# 処理内容
遅い部分の処理は以下のようなものであった。

* 処理対象のデータをListで受け取る。
* それをforループで1件ずつ前処理する。
* 処理結果をオブジェクトに格納し、ORマッパーでDBにINSERTする。

これだけ？
そう、これだけだ。並列処理なんて高級なことはもちろんやってない。

# インフラ調査
処理中のサーバのようすを調査する。今回のインフラは典型的な3層3サーバ構成。

WEBサーバはなにもかもが余裕。
APサーバではCPUを1つ使い切っている。
14コアのサーバ（EC2のc4.4xlarge）なので、1つのCPUがどれだけ頑張っても使用率7%なのが悲しい。
DBサーバでは多少のディスク負荷はあるが性能的には余裕。

ネットワーク、メモリ等も調査したがすべてのリソースが有り余っている。
各種設定値も正常だ。

# DBまわりを調査
ご覧の通りほぼINSERTしかやってないような処理である。
そのため、APのCPU負荷は気になるものの、その場の全員がDBまわりを疑いいろいろといじりまわしていた。
しまいにはORマッパーのバグを踏んだのでは？という声まで出てきて、JDBCを直接使うという懐かしい体験もした。

しかし成果はなく、ランボー怒りの休日出勤が決定する・・・。

# 発見
基本に立ち返り、ロジックの処理時間の分析をやりなおす。
「ループ回数が進むごとに処理が重くなってる気がする」という証言のもと、
ループ回数と1ループの処理時間の関係を出してみることにした。

以下は分析結果のイメージである。入力データ量を変え、N万件と2N万件で比較した。
![graph.png](https://qiita-image-store.s3.amazonaws.com/0/60348/fd0f17b5-bc62-a21c-6b27-483130898181.png)

**「後半減っとる・・・！！」**

小さい方のデータは大きい方のデータの前半を切り出したものなので、データの内容による変動ではなさそうだ。
さらに細かく分析すると、グラフの頂上の部分で最も時間を食っていたのは以下の一行だった。
変数`data`の型は`List<MyClass>`である。

```java
MyClass record = data.get(i);
```

これには度肝を抜かれた。Listから要素を取得するだけがめちゃくちゃ遅いのである。
誰かが口を開いた。

**「これ、LinkedListなんじゃね？」**

2N万件もあるLinkedListのN万番目を取り出そうとして、とてつもない時間がかっていたのだ。
おそらくリストのサイズの半分を基準にして、後半の方のデータにはお尻からアクセスするようになっているのだろう。

我々を休出に誘ったトラブルは、for文を拡張for文に変えるというリファクタリングレベルの変更で幕を閉じた。

```java
for (int i = 0; i < data.size(); i++) {
    MyClass record = data.get(i);
    ...
}
```

↓

```java
int i = 0;
for (MyClass record: data) {
    ...
    i++;
}
```

一見これ何の違いがあるの？という変更ではあるが、Listにとっては変更前はランダムアクセス、
変更後は（Iteratorによる）シーケンシャルアクセスということになり、データ件数が多いときにはパフォーマンスに雲泥の差が出るのだった。

# 大変勉強になりました。
はじめ拡張for文を使っていなかった理由は、処理の中でiの値も使いたかったというもの。
JavaにもPythonのenumerateがあればなあ・・・（恨み言）
Google Colaboratory コマンド チートシート【jupyter対応】

## これから熱いGoogle Colaboratory

GPUが標準で使えてipynbで保存ができてなおかつクラウド保存可能な、jupyter notebookのいいとこ取りだけをしたようなそんなエディタが存在しているなんて・・・

とはいっても標準ではjupyter同様のショートカットが設定されていないため、jupyter notebookのように気軽には使えません。

ですので、ColaboratoryをJupyterの用に使うための最小限の心得とコマンドの対応を記載していこうと思います。

【2020/02/28 更新】
気がつけばこの記事書いて2年立つわけですが、もっともっとやれることが増えてきていたので改めて追記していきたいと思います。

## キーボード ショートカットを確認
Colaboratoryを起動したら、メニューバーから

「ツール」 -> 「キーボード ショートカット」

をクリック。するとこんな画面が出てきます。

【2020/02/28 更新】
![Screen Shot 2020-02-28 at 17.42.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186010/64bce000-32ae-f397-5109-45eb903a0b42.png)

どうやら基本的なコマンド配置は、されているようですがjupyterとの大きな違いは

**「⌘/Ctrl + M」を挟んで実行**

というところですね。この辺はコマンドモードとコードモードの用にモードを分けていないためにこういうコマンドになってしまうわけですね。

というわけで基本的な違いはこの１つだけであとは大体Jupyterの用に使用できるかと思います。またcolaboratory特有のコマンドもショートカットとして登録できるみたいですので、使いこなせるようになってきたらコマンドに追記すると便利かと思います。またツールから**コマンドパレット**を開くことができ、マウス操作で実行もできるので、使う際には `⌘/Ctrl + Shift + p` でメニューを開いてみてください。
【2020/02/28 更新】
「エディタのキーバインディング」も設定できるようになったらしいのでこちらも説明を加えます。

- default: (classicとの違いが見つけられなかった)
- vim: LinuxベースのCLIで使用されているエディタのキーバインドです。慣れている人はこちらが良さそうです。
- classic: 以前のエディタで使われていた一般的なキーボード ショートカットの一部を復元します。

参考: <https://colab.research.google.com/notebooks/editor_details.ipynb>

## チートシート
|キーボードショートカット|共通コマンド|Google Colaboratory|Jupyter(コマンド)|Jupyter(エディタ)|
|---|---|---|---|---|
|コマンドパレットの表示|`⌘/Ctrl + Shift + p`|`⌘/Ctrl + Shift + p`|`p`, `⌘/Ctrl + Shift + p (or) f`|`⌘/Ctrl + Shift + p (or) f`|
|セル移動|`十字キー`||||
|コードセルを下に追加||`⌘/Ctrl + m -> b`|`b`||
|コードセルを上に追加||`⌘/Ctrl + m -> a`|`a`||
|セルの選択||
|セルの切り取り||なし|`x`||
|セルのコピー||なし|`c`||
|セルのペースト||なし|`v`||
|セルの削除||`⌘/Ctrl + m -> d`|`dd`||
|セルの検索||`⌘/Ctrl + h`|`f`||
|コードセルをMarkdownセルへ||`⌘/Ctrl + m -> y`|`y`||
|Markdownセルをコードセルへ||`⌘/Ctrl + m -> m`|`m`||
|コードの行数表示||`⌘/Ctrl + m -> l`|`l`||
|キーボードショートカットの確認||`⌘/Ctrl + m -> h`|`h`||

ざっくりとよく使うコマンドだけまとめてみました。あとはコードモードなどもどんどん追記して行こうかと思います。
φ(..)メモメモ　Node-REDでGoogle Translate API

#フロー
![20180218-03.PNG](https://qiita-image-store.s3.amazonaws.com/0/145508/028e4dbd-9ba0-d09d-841c-4ebc34509a1c.png)
#payloadを更新
![20180218-03-01.PNG](https://qiita-image-store.s3.amazonaws.com/0/145508/20b73fb6-c46e-b6e0-af2a-2f5bf8224d2c.png)
#出力
![20180218-03-02.PNG](https://qiita-image-store.s3.amazonaws.com/0/145508/f4aa6a5f-981a-924e-24bd-5bb43fa8075a.png)
φ(..)メモメモ　Node-REDでNLC(Natural Language Classifier)

#フロー
![20180218-02.PNG](https://qiita-image-store.s3.amazonaws.com/0/145508/1d04d78b-0bd3-b4bd-fc0e-78d509e29944.png)
#payloadを更新
![20180218-02-01.PNG](https://qiita-image-store.s3.amazonaws.com/0/145508/30159ef9-25b1-821a-627c-148ff138bde7.png)
#SoftBank NLC
URL ユーザ名　パスワードを指定します。
![20180218-02-02.PNG](https://qiita-image-store.s3.amazonaws.com/0/145508/efd86f57-f5e1-54ab-331f-8599fb07779b.png)
#回答セット
![20180218-02-03.PNG](https://qiita-image-store.s3.amazonaws.com/0/145508/a62990e2-6ed7-622d-2d13-b0b8c2e10edd.png)
#A002
![20180218-02-04.PNG](https://qiita-image-store.s3.amazonaws.com/0/145508/6820fb07-ec24-e37b-e742-194163f10463.png)
φ(..)メモメモ　Node-REDでWatson Discovery

#フロー
![20180218-01.PNG](https://qiita-image-store.s3.amazonaws.com/0/145508/d37bf0c7-c824-54d4-9efd-660fec65e605.png)
#入力文章
![20180218-01-01.PNG](https://qiita-image-store.s3.amazonaws.com/0/145508/5e615d57-d80d-0a90-c491-932f23a5d9e7.png)
#output
![20180218-01-02.PNG](https://qiita-image-store.s3.amazonaws.com/0/145508/35009416-7c33-f9da-1bb2-9b5a2c632eb7.png)
#filename
![20180218-01-03.PNG](https://qiita-image-store.s3.amazonaws.com/0/145508/fef4382b-c67d-a9be-d07c-496de8af250a.png)
#参考
[Node-REDでWatson Discovery Service 日本語体験サンプル - Qiita](https://qiita.com/kolinz/items/b3be17c33694c9745697)
【勉強会】会場提供Wi-Fiは無いよ！というメッセージをWi-FiのSSIDで伝える

[IoTLT](https://iotlt.connpass.com/)といった勉強会においては、会場様のご厚意でインターネットに繋がるWi-Fiのアクセスポイントが用意されていることが多いのですが、セキュリティや回線容量の都合などで会場様がWi-Fiのアクセスポイントを用意できない場合もあります。
勉強会の受付中の時間は、スクリーンやマイクでWi-Fiのアクセスポイントを用意がないことを告知できるのですが、LT発表等が始まってしまうと告知ができず、遅れて来た方々が会場提供Wi-Fiを探してしまってLT発表を聞くことに集中できないかもしれません。

![wifi_no.png](https://qiita-image-store.s3.amazonaws.com/0/137045/7e743586-fe58-bd45-8689-64f16f495598.png)

そこで、ESP32をWi-Fiのアクセスポイントにして解決できないか考えてみました。

# 動作環境
- [ESP32-DevKitC ESP-WROOM-32開発ボード](http://akizukidenshi.com/catalog/g/gM-11819/)などのESP-WROOM-32搭載ボード
    - [Installation instructions for Mac OS](https://github.com/espressif/arduino-esp32/blob/master/docs/arduino-ide/mac.md) に書かれている手順で[Arduino IDE](https://www.arduino.cc/en/Main/Software)と[arduino-esp32](https://github.com/espressif/arduino-esp32)をインストール

# スケッチ
日本語(+絵文字)のSSIDを設定して、会場提供Wi-Fiが無いことを伝えてみるサンプルのスケッチです。
パスフレーズに関してはランダムなものを設定し、このスケッチが書き込まれたESP32の持ち主であっても接続できないようにしています。

```C++:wifimessage.ino
#include <WiFi.h>

WiFiServer server();

#define PASS_LENGTH 32

const char ssid[] = "📶WiFiありません📶";

void setup() {
  char pass[PASS_LENGTH + 1];
  for (int i = 0; i < PASS_LENGTH; i++) {
    pass[i] = (char)random(0, 256);
  }

  WiFi.softAP(ssid, pass);
}

void loop() {

}
```

Arduino IDE(macOS)上で絵文字を入力すると、ダブルクォーテーションまで一緒に文字化けするといった現象が発生しますが、スケッチは正常に書き込むことができました
<img width="300" alt="ide文字化け.png" src="https://qiita-image-store.s3.amazonaws.com/0/137045/eadf3795-a7db-6cc6-ad0c-bc6ef9d6d013.png">

# 各OSの日本語(絵文字)SSID対応状況
SSID `※WiFiありません※` と `📶WiFiありません📶` で試してみました。

## Windows 7
![win7.png](https://qiita-image-store.s3.amazonaws.com/0/137045/07e8b0aa-42fb-5dac-4d07-1bd46be1c1b7.png)
絵文字、※印、ひらがなすべてダメですね...
糸偏の漢字が見受けられるので、[UTF-8からSJISに文字化けすると糸偏の漢字がよく出てくる](https://qiita.com/kaityo256/items/878cbe35d4c8444b045a)の記事で書かれているような現象が起きているのだと考えられます。

## Windows 10
![win10.png](https://qiita-image-store.s3.amazonaws.com/0/137045/8543f442-de1d-eb0b-ea00-e37f1999b6df.png)

## macOS (High Sierra)
<img width="290" alt="スクリーンショット 2018-02-18 12.04.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/137045/e4a4e8e5-d13d-42d5-f5a3-d2bfa4bb470d.png">

## iOS 11
<img width="375" alt="写真 2018-02-18 12 16 42.png" src="https://qiita-image-store.s3.amazonaws.com/0/137045/ae040d7c-cc79-97ed-16b3-7fdfcd989838.png">

## Nintendo Switch
![DWSVf94VoAEbftr.png](https://qiita-image-store.s3.amazonaws.com/0/137045/708851f9-c834-fd7b-f528-3a21aa8b906f.png)
勉強会でこれを使う人はいないと思いますが、一応試してみました。
絵文字がSSIDに入っていると、アクセスポイントの検索でSSIDが出てきませんでした。

# まとめ
Windows 7以外であれば、日本語+絵文字のSSIDでほぼ問題なさそうです。
絵文字を使ってSSIDを目立たせれば、SSIDでメッセージが伝わる可能性もアップすると思います。

# 参考文献
[【備忘録】ESP-32 DevKitCでのWiFi接続方法（APモード）](http://rikoubou.hatenablog.com/entry/2017/05/09/180847)
JavaScrptで2次元配列や3次元配列を簡単に用意する方法

# 背景
JavaScriptで多次元配列を加工するときに、事前に挙動をテストしたいと思うことがあります。多次元配列を簡単に作るにはどうしたらいいかを考えました。

# 問題
テスト用の2次元配列や3次元配列を簡単に作る。

例

```javascript
//2x2
const data1 = [
  [0,0],
  [0,0],
]
```

```javascript
//3x3x3
const data2 = [
  [[0,0,0],[0,0,0],[0,0,0]],
  [[0,0,0],[0,0,0],[0,0,0]],
  [[0,0,0],[0,0,0],[0,0,0]],
]
```

# 対処法
スプレッド演算子とmapを使うと簡単にできる。

```javascript
//2x2
const data1 =[...Array(2)].map(k=>[...Array(2)].map(k=>0))

//3x3x3
const data2 =[...Array(3)].map(k=>[...Array(3)].map(k=>[...Array(3)].map(k=>0)))
```

# あとがき
前はfor文のループやArray.fromを使っていましたが、最近は[...Array]を使っています。
SAM で API Gateway に API Key を設定する

この記事は、AWS Serverless Application Model (AWS SAM) で API Gateway の API Key を設定した際の記録です。

# はじめに

- SAM では、API仕様を定義した Swagger を使用することで、API Gateway のリソースを作成できます


## 参考

- [SwaggerをAWS Serverless Application Modelから扱う方法を理解する](https://dev.classmethod.jp/cloud/aws/understanding-aws-serverless-application-model-and-swagger/)
- [AWS Serverless Application Model (AWS SAM)](https://github.com/awslabs/serverless-application-model) とは
- [Swagger](https://swagger.io/)


# API Gateway の API に API Key を指定する

１．Swagger の **securityDefinitions** に **apiKey** を定義する

```yaml:swagger.yml
securityDefinitions:

  SampleApiKey:
    type: apiKey
    name: x-api-key
    in: header
```

２．API Key を要求する path に対して **security** に **apiKey** を指定する

```yaml:swagger.yml

paths:
  /pet:
    post:
      summary: "Add a new pet to the store"
      operationId: "addPet"
      security:
        - SampleApiKey: []

      （以下省略）

```

３．SAM の template で **AWS::Serverless::Api** に加えて以下のリソースを作成する
  - **AWS::ApiGateway::ApiKey**
  - **AWS::ApiGateway::UsagePlan**
  - **AWS::ApiGateway::UsagePlanKey**

```yaml:template.yml

  SampleApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      DefinitionUri: swagger.yml

  SampleApiKey:
    Type: AWS::ApiGateway::ApiKey
    DependsOn: SampleApi
    Properties: 
      Name: sample-api-key
      Enabled: true
      StageKeys: 
        - RestApiId: 
            Ref: SampleApi
          StageName: Prod

  SampleApiUsagePlan:
    Type: AWS::ApiGateway::UsagePlan
    DependsOn: SampleApi
    Properties:
      ApiStages:
      - ApiId: !Ref SampleApi
        Stage: !Ref SampleApiProdStage
        # AWS::Serverless::Api のリソース名 + AWS::Serverless::Api の 'StageName' + Stage 
      Throttle:
        BurstLimit: 200
        RateLimit: 100
      UsagePlanName: sample-api-usage-plan

  SampleApiUsagePlanKey:
    Type: AWS::ApiGateway::UsagePlanKey
    DependsOn:
      - SampleApiKey
      - SampleApiUsagePlan
    Properties : 
      KeyId: !Ref SampleApiKey
      KeyType: API_KEY
      UsagePlanId: !Ref SampleApiUsagePlan

```
[Node.js]ES6仕様で動くようにする

わりと出尽くされているネタのような気がしますが、メモも兼ねて書きます。
発端としては、下記のように`Unexpected token export`と出たことです。

```
> hoge@1.0.0 start /Users/fuga/my_pj/hoge/src
> node app.js

/Users/fuga/my_pj/hoge/src/modules/Piyo.js:1
(function (exports, require, module, __filename, __dirname) { export class Piyo
                                                              ^^^^^^

SyntaxError: Unexpected token export
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:607:28)
    at Object.Module._extensions..js (module.js:654:10)
    at Module.load (module.js:556:32)
    at tryModuleLoad (module.js:499:12)
    at Function.Module._load (module.js:491:3)
    at Module.require (module.js:587:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/Users/fuga/my_pj/hoge/src/app.js:3:20)
```
基本的には下記のリンクに従って書きます。
[babel/example-node-server: Example Node Server w/ Babel](https://github.com/babel/example-node-server)

## ディレクトリ構成

root/
　├ app/
　│　└ app.js
　├ dist/
　├ node_modules/
　└ package.json

## 手順

### ①必要なパッケージのインストール
```
$ npm install --save-dev babel-cli
$ npm install --save-dev babel-preset-env
```
最初、ES2015の機能だけ使えればよいかと思って`npm install --save-dev babel-preset-es2015`と書いていましたが、

```
npm WARN deprecated babel-preset-es2015@6.24.1: 🙌  Thanks for using Babel: we recommend using babel-preset-env now: please read babeljs.io/env to update!
```
とのエラーが出たので、babel-preset-envに変えました。

### ②package.jsonに追記
```
  "scripts": {
+   "start": "babel-node app/app.js --presets babel-preset-env -x js,json"
+   "build": "babel app -d dist --presets babel-preset-env --copy-files",
+   "serve": "node dist/app.js"
  }
```

完成。
これで下記のコマンドが使えるようになります。

```
$ npm start // 開発用のコマンド
$ npm run build // Releaseビルド
$ npm run serve // Releaseビルドしたものを起動
```
ReactNativeのエラー画面の色を変える

ReactNativeのエラー画面の色を変える小ネタです。

変えるといってもライブラリを導入するとかではなくて、ReactNativeのソースをいじる感じです。

react-native initをすると、node_modules/react-native/React/Modules/配下にRCTRedbox.mというファイルができると思います。

このファイルがエラー画面のスタイルを設定してるコードです。

なのでここにあるスタイル定義部分の色を好きに変更すれば終わりです。


```
- (instancetype)initWithFrame:(CGRect)frame {
...
// 背景を白にする
self.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:1]; 
```

```
- (UITableViewCell *)reuseCell:(UITableViewCell *)cell forErrorMessage:(NSString *)message {
...

// テキストカラーを黒にする
cell.textLabel.textColor = [UIColor blackColor];
cell.detailTextLabel.textColor = [UIColor blackColor];
```


```
- (UITableViewCell *)reuseCell:(UITableViewCell *)cell forStackFrame:(RCTJSStackFrame *)stackFrame {
...
// テキストカラーを黒にする
cell.textLabel.textColor = [UIColor blackColor];
cell.detailTextLabel.textColor = [UIColor blackColor];
```

これらの変更を加えてから、再度react-native run-iosとかして再起動するとエラー画面の色が変更されます。

<img width="283" alt="スクリーンショット 2018-02-18 12.11.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/13609/e8abee1b-f147-d85d-e18a-345d93e9955a.png">

小ネタでした。
AliCloudのOSS(Object Storage Service)をコマンドで操作する(Ubuntu16.04 64bit)

#概要
AlicloudのOSS(Object Storage Service)はAWSのS3に相当するサービスです。
簡単に使用法を説明します。
#準備
##ダウンロード
```
curl -O http://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/assets/attach/50452/cn_zh/1506525299111/ossutil64
```
##権限設定
```
chmod 755 ossutil64
```
##クレデンシャル情報の登録
```
./ossutil64 config -e endpointname -i Access_Key_Id -k Access_key_Secret
```
#実行
##ファイル一覧
```
./ossutil64 ls oss://backetname
```
##ファイルコピー
```
./ossutil cp local_filename oss://backetname/filename
```
Ansibleのset_factでYesとNoが入るとTrue/False変換されてしまう時の対応方法

## 2019/10/04追記

Ansible 2.7 で追加された DEFAULT_JINJA2_NATIVE という設定項目を `true` にすると、set_fact モジュールでも `"yes"` は文字列になるようです。

```cfg:~/.ansible.cfg
[defaults]
jinja2_native = true
```

詳細はコメント欄にて。


##set_fact でYes/Noを入れると自動的にtrue/falseに変換される

ansibleでset_factを利用すると自動的にtrue/falseに変換されてしまう

実際に"Yes"と入れてデバッグしてみる。

```
- name: Test 
  hosts: localhost
  tasks:
    - set_fact:
        STRING_YES: "Yes"
    - debug: var="{{ STRING_YES }}"
```

結果
Yesで代入したものがTrueに置き換わっている。

```
PLAY [Test] ***************************************************************************

TASK [Gathering Facts] ****************************************************************
ok: [localhost]

TASK [set_fact] ***********************************************************************
ok: [localhost]

TASK [debug] **************************************************************************
ok: [localhost] => {
    "True": "VARIABLE IS NOT DEFINED!"
}

PLAY RECAP ****************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0  
```

## 対応方法

jinja2　templateを利用して`vars`か`include_vars`で異なる変数に変換する。


```
- name: Test
  hosts: localhost
  tasks:
    - set_fact:
        STRING_YES: "Yes"
    - debug: var="{{ STRING_YES }}"


- name: Test vars
  hosts: localhost
  vars:
    RAP_VARS_STRING_YES: "{% if STRING_YES %}Yes{% else %}No{% endif %}"
  tasks:
    - debug: var="{{ RAP_VARS_STRING_YES }}"
```

一応解決

```
TASK [set_fact] ***********************************************************************************************************************************************************************************

ok: [localhost]

TASK [debug] **************************************************************************************************************************************************************************************

ok: [localhost] => {
    "true": "VARIABLE IS NOT DEFINED!"
}

PLAY [Test vars] **********************************************************************************************************************************************************************************


TASK [Gathering Facts] ****************************************************************************************************************************************************************************

ok: [localhost]

TASK [debug] **************************************************************************************************************************************************************************************

ok: [localhost] => {
    "Yes": "VARIABLE IS NOT DEFINED!"
}

PLAY RECAP ****************************************************************************************************************************************************************************************

localhost                  : ok=5    changed=0    unreachable=0    failed=0
```

うーん。なんか微妙な仕様。issues上げようかなと検討。。
ちなみにここで書き換えているみたい。yes noの時に明示的にboolean型に変換する必要なくないか。。
https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/action/set_fact.py#L52
Google Home から Raspberry Pi を経由した操作まとめ

# Google Home から Raspberry Pi を経由した操作まとめ

![1.png](https://qiita-image-store.s3.amazonaws.com/0/235420/8d092a81-2667-6484-a70b-914416224f46.png)


## １．Google Home から IFTT への連携
[Google Home で独自のコマンドを利用する（IFTTT）](https://qiita.com/minatomirai21/items/3fffec8b32ba25d0aa00)

## ２．IFTT から Raspberry Pi への連携
[IFTTT から Raspberry Pi に指示を出す](https://qiita.com/minatomirai21/items/4c4e777b43ede1e42900)

## ３．Raspberry Pi での Node-REDの利用
[Raspberry Pi での Node-RED 利用](https://qiita.com/minatomirai21/items/184e04bab76bee70470e)

## ４．Node-RED からリモコン操作
[コンセントをリモコンで操作する（Raspberry Pi & irMagician & リモコンコンセント）](https://qiita.com/minatomirai21/items/ae4b69980772fc0fb5de)

## ５．Node-RED から Philips Hue を操作
[Raspberry Pi から Philips Hue を操作する](
https://qiita.com/minatomirai21/items/58babe51a546ad025730)

## ６．Node-RED から kintone へ書き込み
[Raspberry Pi から kintone にデータを書き込む](
https://qiita.com/minatomirai21/items/a6ea55ff10fc3754c834)
クラウドIDE

# クラウドIDE

クラウドIDEとして、[PaizaCloud Cloud IDE](https://paiza.cloud/ja/)を取り上げます。

クラウドIDEは、ブラウザ上で動作する統合開発環境(IDE)です。クラウド上のサーバで動作しています。


## 特徴
- 開発環境構築不要
あらかじめ開発環境が設定されているので、面倒なインストールや環境構築が不要です。
[PaizaCloud Cloud IDE](https://paiza.cloud/ja/)の場合、Ruby on Rails, Node.js, Django, PHP(LAMP), Laravel, Java(Tomcat), MySQLなどの主要環境が導入済みです。

- 起動が早い
[PaizaCloud Cloud IDE](https://paiza.cloud/ja/)の場合、3秒ほどで起動します。

- ブラウザだけで使える
ローカルの環境、OSに依存しません

- どこからでも使える
環境がクラウド上にあるので、どのマシンからでも同じ環境で使えます。

- 同じ環境
常に、クリーンな同じ環境が用意できるので、チュートリアル、ハンズオン、トレーニング、研修などで環境に依存した問題が発生しません。
MVVMの旨味を知る

**MVVM**って調べるとデータの流れとかとか全部いっきに書かれてる記事が目立って実際コード書こうと思ったらなかなか書けない、「っで、MVVMの旨味ってなんなん？」的な事になりかねません。

でも実際はそれほど深く考えなくてもいいと思います。

ここではKotlinとかJavaとかのコードは載せません。それと、AndroidのArchitectureComponentsの説明もしません。
純粋にMVVMだけ取り上げます。
今回は概念というか考え方というか旨味を知ってほしいからです。

## ざっくり

![MVVM.png](https://qiita-image-store.s3.amazonaws.com/0/73994/fa79c2df-aa7d-7ac6-6175-acf4eabef9de.png)

自分の中ではこれが一番旨味がわかる図だと思います。

## 説明

`View`は`ViewModel`内の関数を呼び出す。その反対はない。
`ViewModel`は`Model`内の関数を呼び出す。その反対はない。

## 旨味

> 例えば読み込んでくる`Model`を変えたくなった時、`ViewModel`が呼び出してる`Model`の参照先を変えればいいんです。🎉

こうする事でテストデータから本番データへの切り替えが非常にわかりやすくなります。
また、エラーが出てもどこでエラーが出たのかがわかりやすくなります。

説明は以上です。必要最低限で書きました。
【メモ】コマンドラインからPull Requestを出すシェル関数

## できること
現在のローカルブランチから引数で与えたブランチへGithub上にPull Requestを出す。

## 使用例
`opr master`

## 内容
```
# opens a PR from the current branch
function opr() {
  parentBranch=$1
  currentBranch=`git branch | grep "*"`
  repoName=$(git remote show origin -n | ruby -ne 'puts /^\s*Fetch.*:(.*).git/.match($_)[1] rescue nil')

  open -a /Applications/Google\ Chrome.app  https://github.com/${repoName/* /}/compare/${parentBranch/* /}...${br/* /}
}
```
Raspberry Pi から Philips Hue を操作する

# Raspberry Pi から Philips Hue を操作する
Raspberry Pi（Node-RED）から Philips Hue を点灯・消灯します。
以下の方法があります。
・API を POSTする
・hue set ノードを利用する


## API を POSTする
以下の手順を参考に、APIのエンドポイントを取得し、点灯・消灯させるJSONを作成、Raspberry Pi（Node-RED）からHTTP Requestします。
[Getting started | Philips Hue API](https://www.developers.meethue.com/documentation/getting-started)



## hue set ノードを利用する
hue を操作できるノードがあります。
デフォルトでは導入されていないので、手動でノードを導入します。
[node-red-contrib-hue - Node-RED](https://flows.nodered.org/node/node-red-contrib-hue)
Visual Studio Codeの設定ファイルをDropboxで同期する

# 背景

この記事では、VSCodeが公式に「設定を同期する機能」を実装する以前に考え出した、VSCodeのいくつかの設定を同期する方法を紹介しています。よほど酔狂な人でなければ公式の機能を使うべきでしょう。

設定ファイルの保存先は Dropbox を前提にしていますが、ローカルファイルを同期してくれるシステムであれば何でも良いでしょう。Dropbox（またはその他同期システム）クライアントを同期させるすべての端末にインストールする必要があります。現在、Dropbox無料版では同期できる端末の上限数を 3 に制限しています。

機能拡張は大量のファイルの追加・削除が発生することが想定され、Dropboxのようなローカルファイル同期システムでは実行速度が極端に遅くなることが考えられるため、今回は対象外としています。

# 手順

## 1. ファイルの保存

同期対象のファイルをコピーします。
ファイルの保存先と同じディレクトリに下記のスクリプトを保存し、実行して下さい。

```bash:init.sh
#!/usr/bin/env bash

set -eu

SETTINGDIR="$HOME/Library/Application Support/Code/User"
SOURCEDIR="$(dirname "$(realpath "$0")")"

cd $SOURCEDIR
while read; do
  cp $SETTINGDIR/$REPLY .
done <<EOS
snippets
keybindings.json
settings.json
EOS
```

このスクリプトはもう使用しません。削除しても大丈夫です。

## 2. シンボリックリンクの作成

コピーしたファイルから本来配置すべき箇所へシンボリックリンクを張ります。
ファイルの保存先と同じディレクトリに下記のスクリプトを保存し、実行して下さい。

```bash:symlink.sh
#!/usr/bin/env bash

set -eu

SETTINGDIR="$HOME/Library/Application Support/Code/User"
SOURCEDIR="$(dirname "$(realpath "$0")")"

cd $SETTINGDIR
while read; do
  [ -d "$REPLY" ] && rm -rf "$REPLY"
  ln -sf "$SOURCEDIR/$REPLY" "$REPLY"
done < <(ls "$SOURCEDIR" | grep -v "$(basename $0)")
```

新規の同期対象端末が増えた場合、このコマンドを実行するだけで同期が完了します。

# その他

機能拡張も手動で同期するようなスクリプトを書いたのですが、他の自家製スクリプトを使用する構成になっているため、こちらの掲載は見送りました。
LetsEncryptでSSL証明書を取得

# LetsEncryptでSSL証明書を取得
## インストール
```
git clone https://github.com/letsencrypt/letsencrypt.git
cd letsencrypt
./letsencrypt-auto --help
```
## webrootを利用する場合
```
./letsencrypt-auto certonly --webroot --webroot-path ~/encrypt.example.com -d encrypt.example.com
```
## standaloneを利用する場合
```
./letsencrypt-auto certonly --standalone -d encrypt.example.com
# - Congratulations! Your certificate and chain have been saved at
#    /etc/letsencrypt/live/encrypt.example.com/fullchain.pem. Your cert will
#    expire on 2016-03-03. To obtain a new version of the certificate in
#    the future, simply run Let's Encrypt again.
#  - If like Let's Encrypt, please consider supporting our work by:
# 
#    Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
#    Donating to EFF:                    https://eff.org/donate-le
```
証明書は `/etc/letsencrypt/live/encrypt.example.com/fullchain.pem`
秘密鍵は `/etc/letsencrypt/live/encrypt.example.com/private.pem`
に出力されている
【Ruby】unicode制御文字の削除

# 事象
iOS11以上での話。
とあるアプリの開発中、iphone電話帳からコピーした電話番号を、アプリの電話番号入力フォームにペーストして確認画面に遷移しようとすると、なぜかバリデーションエラーが発生する。
特に電話番号におかしな点はないのだが...

# 調査
色々見てるとどうもlengthチェックで引っかかっていた。
どういうことかというと、
・普通に入力：xx-xxxx-xxxx　→ ハイフンをとって10文字　
・電話帳コピー：xx-xxxx-xxxx　→ ハイフンをとって12文字
なんか電話帳コピーの場合だけ2文字多い!?
これはconsole.logやalert表示では、パッと見で違いが分からない!

そこでencodeして1つづつ表示してみると、電話番号先頭に「¥u202d」、末尾に「¥u202c」という文字がくっ付いていた事が判明。

```hoge.js
for(var i=0; i<tel.length; i++) {
  alert(escape(tel)); // %u202dXX-XXXX-XXXX%u202c
}
```
なんだこれ?と思い調べてみると、文字の方向を制御するunicodeらしい。
参考：http://www.tohoho-web.com/html/attr/dir.htm

# 解決
サーバー側にもlengthバリデーションがあり、jsと同じくそこで引っかかっていたので、該当オブジェクトのインスタンスの制御文字込み電話番号から、制御文字を削除しました。

```ruby:hoge_contoller.rb
tel_str.gsub!(/\u202D|\u202C/, "\u202D":"", "\u202C":"")
```
keras-rlとOpenAI Gymで強化学習（ pacman サンプル）

# はじめに
 keras-rlとOpenAI Gymで breakout サンプルで強化学習したコードをベースにpacmanを試します。
https://qiita.com/kznx/items/dc269d55976f030e028e

# pacman サンプル
　breakoutのコードから変更した箇所は一点だけ。環境を pacman に変えただけです。

```
env_name=('MsPacman-v0')
```

　
# トレーニング結果
　デフォルトの1750000step完了には、15時間ほどかかりました。やっぱり強化学習にはGPUは必須な様です。

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">最近試している <a href="https://twitter.com/hashtag/keras?src=hash&amp;ref_src=twsrc%5Etfw">#keras</a>-rl と <a href="https://twitter.com/hashtag/openaigym?src=hash&amp;ref_src=twsrc%5Etfw">#openaigym</a> で強化学習。子供の頃遊んだpacman は、1750000 step 完了しても、今ひとつ上手くなってない。コードはbreakoutと共通なのは驚嘆。  reinforcement learning by openai gym, pacman sample (1750k steps) <a href="https://t.co/r6Y58PbArH">https://t.co/r6Y58PbArH</a> via <a href="https://twitter.com/YouTube?ref_src=twsrc%5Etfw">@YouTube</a></p>&mdash; Kazutoshi Nakano (@kznx) <a href="https://twitter.com/kznx/status/965123988157419520?ref_src=twsrc%5Etfw">February 18, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 最後に
　pacman サンプルを試してみました。breakout サンプルと共通のコードで学習できるのは、理解しているつもりでも、驚嘆してしまいます。
多人数によるFuelPHPプロジェクト開発の概念図

個人的に、こういう設計で開発を進めると良いんじゃないかな、という概念図。

# 全体

![Untitled(3).png](https://qiita-image-store.s3.amazonaws.com/0/36569/6d97e0cb-0519-17a4-f168-ff9de458aa9c.png)


# 開発時

![Network Diagram(6).png](https://qiita-image-store.s3.amazonaws.com/0/36569/6edd643b-6e54-1f72-7821-6a5e3280e3fc.png)

開発用DBを使って動きを確認しつつ、FuelPHPのプロジェクトファイルを変更。


# テスト実行時

![Untitled.png](https://qiita-image-store.s3.amazonaws.com/0/36569/b762e9e6-61e3-4a4d-f777-c7c6f97ffe2d.png)


テストは、主に
- モジュール開発時のユニットテスト
- git push する前の受入テスト
の2つ。

テスト実行前にDBダンプファイルからテスト用DBにインポート。
その後、テスト用DBに対して自動でテストを実行。


# 検証時

![Untitled(2).png](https://qiita-image-store.s3.amazonaws.com/0/36569/2630f5ab-8d84-a8b7-9611-93ebf1c2f433.png)

本番環境に適用する前に、検証環境に適用し、本当に問題がないか確認する。
(検証環境にアクセスできる人は制限する)

検証環境にログインして、```git pull```と```oil r migrate```を実行。

# 本番環境適用時

![Untitled(1).png](https://qiita-image-store.s3.amazonaws.com/0/36569/1062f7b8-a1b5-4bb2-1d1e-90dff619a938.png)

本番環境にログインして、```git pull```と```oil r migrate```を実行。


# 追記

自分の開発環境では、ユニットテスト時のDBはダンプファイルを利用するのではなく、fixtureファイルをインポートしています。
(「はじめてのフレームワークとしてのFuelPHP」の開発手順を真似させてもらってます)
ダンプファイル単位で操作するより、ユニットテストに必要なテーブルだけゴニョゴニョできるのがメリットかと思います。
jenkinsでAWS s3 で指定されたファイルがあるかを確認する

#AWS s3 で指定のファイルがあるかを確認したい
はじめ以下のコマンドで試してみる。
`aws s3 ls s3://hoge/hoge.txt`

ファイルが存在しない場合、return code 1を返しているようで上手くいかない。
`ERROR: script returned exit code 1`

jenkins でのshell 実行はデフォルトで
`/bin/sh -xe`
がついているよう。
`-e`で`return 0　`以外が返ってきた場合に強制終了されてしまう。
なので以下のように`echo`でラップしてあげると上手くいく。

`　echo `aws s3 ls s3://hoge/hoge.txt` `
WindowsでTeX用の図を作成する方法

# はじめに
TeXの図を作成する方法をググると，EPSファイルの作り方ばかり出てくる！
でもEPSファイルをLaTeXから読み込むとコンパイルが遅い！
更にEPSファイルをWindowsで作るのはめんどい！
という理由で，Windows上でPDF形式の図を作る方法をまとめます．

# 注意
- 筆者はLaTeXにそこまで詳しくありません．
- 以下に示す方法は自分用のメモ書きを兼ねているため，記述が雑かもしれません．
- 正確でない情報が含まれている可能性があります．もし誤りを見つけた場合はお教えいただければ幸いです．

# 環境
- TeX Live 2017での動作を確認
- latex/platex + dvipdfmx を想定

# やること
1. PowerPoint等で図を作成
2. PDF形式でエクスポート（ファイル名：xxxx.pdf）
    - 1つの図に対して1つのPDFファイルを出力する．
    - PDFファイルのバージョンを確認しておく．（PowerPoint 2016の場合 バージョン1.7）
3. pdfcropを使って図の領域を切り出す（bounding boxを指定すれば必要ない）

    ```sh
    $ pdfcrop xxxx.pdf
    ```

4. xxxx-crop.pdfというファイルが作成されるので，extractbbでbounding boxを取得

    ```sh
    $ extractbb xxxx-crop.pdf
    ```

5. .texファイルに図を記述
6. latex/platexによりDVIファイルを生成し，dvipdfmxでPDFファイルを生成

    ```sh
    $ latex hogehoge
    $ dvipdfmx -V 7 hogehoge
    ```

    ここで，-VオプションによりPDFファイルのバージョンを指定する．
    ステップ2で生成した図のPDFファイルのバージョンが1.7のときは，7と入力すれば良い．
Docker用 Jenkins をTimezone JSTで稼働させるDockerfile

### Dockerfile
Docker 初心者の私がお勉強がてら Jenkins のタイムゾーンを JST(Asia/Tokyo) にする DockerFile を書いてみた。
https://hub.docker.com/r/k1tajima/jenkins_tzjst/~/dockerfile/

```dockerfile
FROM jenkins/jenkins:lts
LABEL maintainer="https://qiita.com/k1tajima"

# set timezone for Java runtime arguments
ENV JAVA_OPTS=-Duser.timezone=Asia/Tokyo

# set timezone for OS by root
USER root
RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

# drop back to the regular jenkins user - good practice
USER jenkins
```

内容はわかってしまえば簡単。

* JAVA_OPTS で JavaVM 起動時にタイムゾーンを指定
* OS のタイムゾーンも合わせて変更する時は USER root してから変更


### その他のノウハウ
* Docker Hub 上で `official` と付記されている Docker Image: [`jenkins`](https://hub.docker.com/_/jenkins/) は廃止されている。  
Full Description の先頭にも **DEPRECATION NOTICE** と明記されている。
* 他にも類似のイメージが散見されるが、現時点で Jenkins Community によって公式メンテされている Docker Image は
 [`jenkins/jenkins`](https://hub.docker.com/r/jenkins/jenkins/) とのこと。
* この Docker Image では `docker exec -it` でコンテナにログインしても sudo できないようになっている（[README.md](https://github.com/jenkinsci/docker/blob/master/README.md#installing-more-tools) 参照）。  
なので、root 権限が必要な変更は Dockerfile を用意して対処しておくのが得策。
ポリモーフィック関連のモデルがある場合のフォーム作成

関係：
User > memo

ハマりポイント：

- ビューとストロングパラメーターをどう書くか
- accepts_nested_attributes_forを使用する場合inverse_of　を記載しないとうまく動かない（バリデーションエラー？になる）
    - バリデーションエラーとしたのは @user.error.fullmessagesで　`Memos memoable must exist`となるから

###accepts_nested_attributes_forを使用しない場合
ネストとか考えなくていいので楽といえば楽。モデルの記述もシンプル。
ポリモーフィック関連のある子要素がhas_manyなのかhas_oneなのかで以下の記載を書き換え

- モデルの has_many :複数形 / has_one　:単数形　記述
- controllerで用意するインスタンス　@user.memos.build (複数形）/ @user.build_memo（単数形）
 	
```memo.rb
class Memo < ApplicationRecord
  belongs_to :memoable, polymorphic: true
end
```

```user.rb
class User < ApplicationRecord
  has_one :memo, as: :memoable
end
```

```user.controller.rb
  def new
    @user = User.new
    @user.build_memo
  end

  def create
    @user = User.new(user_params)
    @user.build_memo(memo_params)

    @user.save
  end
:

  private

    def user_params
      params.require(:user).permit(:name)
    end

    def memo_params
      params.require(:memo).permit(:body)
    end
```
※ストロングパラメーターは個別に分けて記述
※子要素を作成する際にアソシエーションを利用しているので、　memoable_idとmemoable_typeは記述しなくても自動で補填された

```erb
<%= form_for @user do |form| %>
    <%= form.label :name %>
    <%= form.text_field :name, id: :user_name %>

  <%= fields_for :memo do |field|%>
    <%= field.label :body %>
    <%= field.text_field :body %>
  <% end %>

    <%= form.submit %>
<% end %>
```
※ fields_forはform_forにネストさせない形で記載

###accepts_nested_attributes_forを使用する場合

```user.rb
class User < ApplicationRecord
  has_many :memos, as: :memoable, inverse_of: :memoable
  accepts_nested_attributes_for :memos
end
```
```memo.rb
class Memo < ApplicationRecord
  belongs_to :memoable, polymorphic: true, inverse_of: :memoable
end
```

```users_controller.rb
  def new
    @user = User.new
    @user.memos.build
  end

  def create
    @user = User.new(user_params)
    @user.save
  end
:
 private
    def user_params
      params.require(:user).permit(:name,memos_attributes:[:body])
    end
```
※newに@user.memos.buildを記載していないとフォームが表示されない注意


```erb
<%= form_for user do |form| %>
    <%= form.label :name %>
    <%= form.text_field :name, id: :user_name %>

  <%= form.fields_for :memos do |field|%>
    <%= field.label :body %>
    <%= field.text_field :body %>
  <% end %>

    <%= form.submit %>
<% end %>
```
※ fields_forはform_forにネストさせて記載

userモデルを削除した際に関連したmemoモデルも削除する場合は以下を追記

```user.rb
class User < ApplicationRecord
  has_many :memos, as: :memoable, inverse_of: :memoable, dependent: :destroy
  accepts_nested_attributes_for :memos
end
```

```users_controller.rb
 private
    def user_params
      params.require(:user).permit(:name,memos_attributes:[:body,:id,:_destroy])
    end
```
Amazon Driveで写真以外を探す方法

写真であればプライムフォトで無制限になる

![alt](https://qiita-image.cloudremix.net/Amazon-Drive.jpg)

# 結論 - **ない**
ググったりサポートに問い合わせたりしたけど、結論からいうと「**ない**」

少し足掻くと

ビデオ・動画であればブラウザからログインして上部の[プライムフォト] → 左側の[ビデオ] から一覧表示できる。

それ以外のファイルで拡張子がわかっているなら検索でその拡張子のファイルが一覧表示できる。（名前も同じく）

※[rclone](https://rclone.org/)や[NetDrive](http://www.netdrive.net/)も試したけど、ファイル数が多いとアプリが落ちる

# ご協力をお願いします
Amazon Driveは右上の[こんにちはXXXX様]のドロップダウンから、要望を送信することができます。

![alt](https://qiita-image.cloudremix.net/Amazon-Drive-Request.jpg)

こちらから

```:txt
プライムフォト対象外のファイルをリスト化する機能を実装してください。
```

と送信していただくと中の人に届くようです。回答などはないようですが、ご協力をお願いいたします。

~~サードパーティツールをBANしたりと活用には消極的のため、星１にすると良いかも~~

## 補足
サポート回答は

> 写真以外を一発でリスト化する機能はありません
> フォルダを一つ一つ確認して、画像かどうかを調べてください。
> またこちらからは容量しか確認できませんので、対応いたしかねます
nDs(Ds)でダイス判定を行う処理を組んでみた

# はじめに
discordでchatbotを使うためにダイス判定処理をどのようにしているのか調べてみたら
正規表現を使って配列に分解する手法が一般的らしいの正規表現を試してみた。

# 概要
nDs、Dsと指定したダイス判定を行うプログラム。

n ...振りたいダイスの数量を指定する
s ...ダイスの種類を指定する(100面体,20面体,18面体,12面体,10面体,8面体,6面体,4面体)

## 正規表現で分解する構成
グループ1 判定するダイスの数
グループ2 ダイス宣言 ... D or d (一応大文字、小文字対応)
グループ3 ダイスの種類 ... 100 or 20 or 18 or 12 or 10 or 8 or 6 or 4

## コード
```csharp:Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;

namespace RollingDice
{
    class Program
    {
        static void Main(string[] args)
        {
            //繰り返しテストできるように無限ループ
            while (true) {
                Console.Write("input dice > ");
                string input = Console.ReadLine();
                
                string regex_rule = @"^([1-9]??)(|d|D)(100|20|18|12|10|8|6|4)*$";

                var regex = new Regex(regex_rule);
                Match match = regex.Match(input);
                GroupCollection groups = match.Groups;

                //処理が間違ってたら後続処理を中断
                if (match.Groups[0].Length == 0)
                {
                    Console.WriteLine("その指定は使用できません");
                    continue;
                }

                // ダイス判定処理
                int NumberOfDice=0;
                int SizeOfDice=0;

                //ダイスの数量指定がない時は1を指定する
                if(match.Groups[1].Length > 0)
                {
                    NumberOfDice = int.Parse(match.Groups[1].ToString());
                } else
                {
                    NumberOfDice = 1;
                }

                if (match.Groups[3].Length > 0)
                {
                    SizeOfDice = int.Parse(match.Groups[3].ToString());
                }

                string ResultOfRolls = null;
                int TotalOfRolls = 0;
                int i;
                for(i=0; i < NumberOfDice; i++)
                {
                    Random randomizer = new Random();
                    TotalOfRolls += randomizer.Next(1, SizeOfDice);
                }

                string ResultOfRolls = "ｺﾛｺﾛｺﾛ..." + match.Groups[0] +":" + TotalOfRolls;
                Console.WriteLine(ResultOfRolls);
            }
        }
    }
}
```

# 今後の課題
3d6+10とかd4-1とか加算・減算を交えた処理をしたかったが、正規表現がうまく動かず。普段使わなすぎ。
後、クラスとか使って処理を見やすくする努力を覚えよう。
Ubuntu 16.04 LTS > sound > 音量を変更する > amixer -D pulse sset Master 50%

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
Jaybird RUN (ワイヤレスイヤホン)
```

コマンドから音量を調整するには？

参考: https://askubuntu.com/questions/97936/terminal-command-to-set-audio-volume

### 絶対指定 (正式名称ではない)

```bash
$ amixer -D pulse sset Master 50%
Simple mixer control 'Master',0
  Capabilities: pvolume pswitch pswitch-joined
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 65536
  Mono:
  Front Left: Playback 32768 [50%] [on]
  Front Right: Playback 32768 [50%] [on]
```

### 相対指定 (正式名称ではない)

```bash
$ amixer -D pulse sset Master 5%+
Simple mixer control 'Master',0
  Capabilities: pvolume pswitch pswitch-joined
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 65536
  Mono:
  Front Left: Playback 36045 [55%] [on]
  Front Right: Playback 36045 [55%] [on]
```

このあたりをコントロールするPythonスクリプトを書けばよさそう。
C/C++ の条件演算子（3項演算子）は短絡評価（的なことを）する

JIS規格では以下のように書かれています。

> 6.5.15 条件演算子
> 意味規則  第 1 オペランドを評価し，その評価の直後を副作用完了点とする。第 1 オペランドが 0 と比較して等しくない場合だけ，第 2 オペランドを評価する。第 1 オペランドが 0 と比較して等しい場合だけ，第 3 オペランドを評価する。第 2 又は第 3 オペランド（いずれか評価したほう）の値を結果とする。

つまり、こういうことが可能だということです。

```c
int a;
int *b;
...
// a が 0 ならば 10 / a を評価しないので0除算エラーにならない
x = (a != 0) ? 10 / a : 1;
// b が NULL ならば *b を評価しないのでヌルポインタアクセスにならない
y = (b != NULL) ? *b : 1;
```

ちなみに、短絡評価とはこういうことをいいます。

```c
// is_a() の値が真ならば is_b() を評価しない
x = is_a() || is_b();
// is_a() の値が偽ならば is_b() を評価しない
y = is_a() && is_b();
```

「3項演算子 短絡評価」でググってもトップに出てこないので書いたのですが、よく考えたら条件演算子は論理演算ではないので短絡評価とはいいません。しかし、同じキーワードで検索する人のためにこういうタイトルにしておきます。
同じ内容を書いた記事は山ほどあるので…。
Gmail自動削除と権限付与

自分用に簡単に整理。
# Gmailの自動削除
## スプレッドシートの準備
Googleアカウントにログインしてスプレッドシートを開く。
私の場合は「ドライブ」-「Google スプレッドシート」から開く。

## スクリプトエディタを開く
「ツール」-「スクリプトエディタ」

## スクリプトの記述
今回は受信から90日経った既読のスターなしのメールを削除する。
スクリプトはこんな感じ。細かいところはAPIリファレンス参照(https://developers.google.com/apps-script/api/)


```AutoDelete.gs
function expire90days() {
  var day = 90;
  var threads = GmailApp.search('older_than:' + day + 'd -is:starred is:read');
  //ラベルを指定して削除したい場合は下記を使用
  //var deleteLabel = "xxx";
  //var threads = GmailApp.search('older_than:' + day + 'd -is:starred is:read label:'+ deleteLabel);
  for (var i = 0; i < threads.length; i++) {
    threads[i].moveToTrash();
    Utilities.sleep(1000);
  }
}
```

大量のデータを削除しようとすると途中でエラーになるので初回起動時は注意。

# 権限の付与
## スクリプトをアカウントに登録
具体的なタイミングはいつからか不明だがセキュリティ的に必要になった手順らしい。参考になったサイトはhttps://www.virment.com/step-allow-google-apps-script/
詳細 - 安全ではないページへ移動 - 許可

私の場合、テキストの入力は求められなかった。


私の場合は**2段階認証を有効**にしたときにこんなメールが通知されたことで気がついた。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/130149/3aed958a-8106-a218-c2d3-6cf8b259a8ae.png)


今更だけどすこしずつノウハウはネット上に残していこう…
Raspberrypi3でデバイスドライバを作る

Raspberrypi3で簡単なデバイスドライバを作ってみる
以下は全てRaspberrypi上で行う

ソースコードを作る
---

```c
kernel_module.c

#include <linux/module.h>
#include <linux/init.h>
 
static int device_init(void)
{
     printk(KERN_ALERT "Hello Linux kernel ^o^/ \n");
     return 0;
}
 
static void device_exit(void)
{
     printk(KERN_ALERT "GoodBye Linux kernel  \n");
}
 
module_init(device_init);
module_exit(device_exit);

MODULE_DESCRIPTION("Tutolial kernel module");  //デバイスドライバの簡単な説明を入れる。入れなくてもソースとして問題なし
MODULE_AUTHOR("your name");
MODULE_LICENSE("GPL v2");
```

makefileを作る
---

```makefile
KERNEL_HEADERS=/lib/modules/$(shell uname -r)/build
 
obj-m := kernel_module.o
 
all:
	$(MAKE) -C $(KERNEL_HEADERS) M=$(shell pwd) modules
 
clean:
	$(MAKE) -C $(KERNEL_HEADERS) M=$(shell pwd) clean
```

linuxのカーネルソースをダウンロードする
---
Raspbian用のLinxuカーネルソースをダウンロードするための「rpi-source」コマンドのソースをダウンロードしインストールする。「rpi-source」を実行すると自動でカーネルソースがダウンロードされる。以下が手順である

```shell
pi@raspberrypi:~/kernel-module $ sudo apt-get install bc
pi@raspberrypi:~/kernel-module $ sudo wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source
pi@raspberrypi:~/kernel-module $ sudo chmod +x /usr/bin/rpi-source
pi@raspberrypi:~/kernel-module $ sudo /usr/bin/rpi-source -q --tag-update
pi@raspberrypi:~/kernel-module $ sudo rpi-source
```

コンパイルする
---

```shell-session
pi@raspberrypi:~/kernel-module $ sudo make
make -C /lib/modules/4.9.35-v7+/build M=/home/pi/ko modules
make[1]: Entering directory '/root/linux-be2540e540f5442d7b372208787fb64100af0c54'
  CC [M]  /home/pi/kernel-module/device_drv.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/pi/kernel-module/device_drv.mod.o
  LD [M]  /home/pi/kernel-module/device_drv.ko
make[1]: Leaving directory '/root/linux-be2540e540f5442d7b372208787fb64100af0c54'
```

出来ているか確認する。デバイスドライバの拡張子はkoである
---

```shell-session
pi@raspberrypi:~/kernel-module $ ls
Makefile         kernel_module.ko     kernel_module.o 
Module.symvers   kernel_module.mod.c  make.log
kernel_module.c  kernel_module.mod.o  modules.order
```

カーネルに組み込む
---

```shell-session
pi@raspberrypi:~/kernel-module $ sudo insmod kernel_module.ko
```

問題なければ何も表示されない

カーネルにロードされたか確認する
---

```shell
pi@raspberrypi:~/ko $ lsmod
Module                  Size  Used by
kernel_module           1086  0 
・
・
・
```

表示されたので確認できた

```shell
pi@raspberrypi:~/ko $ dmesg | tail -2
[ 3106.470423] End.. Test Device  
[ 3108.859836] Hello linux kernel ^o^ 
```

削除する
---

```shell
pi@raspberrypi:~/ko $ sudo rmmod kernel_module
pi@raspberrypi:~/ko $ dmesg | tail -2
[ 3108.859836] Hello linux kernel ^o^ 
[ 3194.654974] Goodbye Linux kernel 
```

おしまい
Vimで「ヤンクしたテキストをdで上書きしちゃったよ」を解決

# 結論

主な2つを紹介します。

## ブラックホールレジスタの使用

以下のように通常のコマンドの前に"_をつけることで、レジスタに保持されたテキストを上書きすること無くカーソル下のテキストを削除することが出来ます。

```
行削除
"_dd

単語削除
"_diw
```

## ヤンクレジスタの使用

以下のようにプット時にpの前に"0をつけることで、直前にヤンクしたテキストをプットすることが出来ます。
このようにヤンクレジスタを使用することで、ヤンクしたテキストをdd等で削除しても上書きされることなく使用することが出来ます。

```
直前にヤンクしたテキストをプット
"0p
```

# レジスタ

vimの削除/ヤンク/プットは一般的なソフトウェアで用いられるクリップボードを使用することは基本的にありません。
vimは20~30個ほどのレジスタを提供しています。
そこからレジスタを指定してテキストを保持するのがvimです。
`"ayiw`と入力すればaというレジスタにテキストを保存することが出来ます。
私達が普段レジスタを指定せずに`diw`と入力している時は、無名レジスタというレジスタを使用しています。
そのため、削除とヤンクで別のレジスタを使用すれば上書きされることは無いということです。
冒頭で述べてる`"_`はブラックホールレジスタと呼ばれ、テキストはどこかにコピーすることなく削除されます。
`"0`はヤンクレジスタと呼ばれ、直前にヤンクしたテキストが保持されます。