OmniAICreator/Qiita-1.07M huggingface dataset:
四半期毎の今期を判断する方法

今期を判断する方法がなんかないのかな〜って考えていました。

http://api.rubyonrails.org/v5.1/classes/DateAndTime/Calculations.html

この辺のメソッドを見ていると`end_of_quarter`をいう文字が見つかりました。

というか、`quarter`系のメソッド多くないか？

これは何かできそうだ！ということが、下記のように判定しました。

```ruby
class Season
  def self.present
    today = Time.current
    present_end_of_quarter = today.at_beginning_of_month.at_end_of_quarter.month

    case present_end_of_quarter
    when 3
      'winter'
    when 6
      'spring'
    when 9
      'summer'
    when 12
      'autumn'
    end
  end
end

Season.present
=> "autumn"
```

他にも便利メソッドがあるので、積極的に時間に関わるメソッドはrails側でできないかを調べて見る方が良さそう。
ALB・EC2小ネタ／AWS CLIでALB配下のTGにEC2インスタンスを登録／削除するためのポリシー（メモ）

kakakakakkuさんが以下のブログ記事で公開されているALBのターゲットグループにEC2インスタンスを登録／削除するシェルスクリプトを実行するために必要なポリシーです。

 * **[AWS CLI で ALB 配下のインスタンスを deregister / register する](http://kakakakakku.hatenablog.com/entry/2017/04/22/233836)（kakakakakku blog）**

# 1. 指定するポリシー

以下のポリシーを登録し、スクリプトを動かすEC2インスタンスに付与するIAM Roleにアタッチします。

```text:AlbRegistrationPolicy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "elasticloadbalancing:DescribeTargetHealth",
                "elasticloadbalancing:DeregisterTargets",
                "elasticloadbalancing:RegisterTargets"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstances"
            ],
            "Resource": "*"
        }
    ]
}
```

特に何のひねりもないですが、AWSユーザーガイドの以下のページにある通り、

 * ALBの3つのAPIアクション
 * EC2の1つのAPIアクション（これはkakakakakkuさんの記事中「aws_utils.sh」の「get_instance_id()」で使用）

とも、リソースレベル権限の詳細な指定に対応していないので、Resourceには「*」を指定する必要があります（最初見落としていて、AWSパートナーさんに教えていただきました）。
本番（プロダクト）環境とステージング／開発環境を同一のアカウントで運用している場合は、指定するターゲットグループのARNを間違えないよう注意が必要です。

 * **[Elastic Load Balancing のリソースレベル権限](http://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/userguide/load-balancer-authentication-access-control.html#elb-resource-level-permissions)**
 * **[Amazon EC2 API アクションでサポートされるリソースレベルのアクセス許可](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-supported-iam-actions-resources.html)**

# 2. おまけ1

私の場合、登録／削除するEC2インスタンス自身でAWS CLIのスクリプトを実行しているので、前述の「get_instance_id()」は使わず、curlで http://169.254.169.254/latest/meta-data/instance-id をGETしてインスタンスIDを取得しています。
その場合は「ec2:DescribeInstances」の権限は不要です。

# 3. おまけ2

crontabから呼び出すスクリプトの場合、初期設定のままでは「.」や「source」で「aws_utils.sh」をインポートできないので、1つのスクリプトにまとめるか、以下の記事を参考にしてインポートできるようにします。

 * **[cron で source コマンドを有効にする方法](http://cm3.hateblo.jp/entry/2016/08/13/064842)（Drafts／cm3さん）**
ProGuardで-dontoptimizeを使いたくないから作った何か

# はじめに
## 結論
https://github.com/nao20010128nao/ProguardTransformFix

## はじめに
こんなエラー見たことありませんか?

```java
Unexpected error while computing stack sizes:
  Class       = [com/google/android/gms/internal/zzgr]
  Method      = [run()V]
  Exception   = [java.lang.IllegalArgumentException] (Stack size becomes negative after instruction [166] pop in [com/google/android/gms/internal/zzgr.run()V])
Warning: Exception while processing task java.io.IOException: java.lang.IllegalArgumentException: Stack size becomes negative after instruction [166] pop in [com/google/android/gms/internal/zzgr.run()V]
```

Support Libraryとかgms更新すると`-dontoptimize`無しには難読化はできなくなってしまいます。
*でも使いたい!* [^1]

もちろん、

```java
-keep class com.google.android.gms.internal.zzgr { *; }
```
は効きません。
ProGuard改造なんてしてもまともに動かない。

でも結局諦めるしか...と思いつつ考えていたら、ある結論にたどり着きました。

**ProGuardを2回やればいいんだ**

# Transform API
AndroidのGradleプラグインには、Transform APIなるものがあります。[^2]
詳細については省きますが、これにはProGuardで難読化する部分があります。[^3]

## 優先順位は選べない
Gradleには`dependsOn`みたいにTaskの順番を左右する指定をすることができますが、Transform APIが崩壊するのは間違いないので使わないことにしました。
また、`android.registerTransform`はTransformの順番を変えられないので、途中に挿入することは諦めました。

# 改造
じゃあ**Transform自体を**改造すればいいじゃない!
`Transform`をなんとか改造すれば、ProGuardを起動するまでの部分に手を加えることができます。
`TransformTask`がガバガバだったこともあり[^4]、**これだ!**と一瞬閃きました。
ですがJVMの仕様上、一度読み込まれたクラスは書き換えられません。
書き換えるのではなく、継承をしつつ、`TransformTask`にはフィールドの読み書きで対応することにしました。

意外とコピペでもエラーは多く出ないんですね。びっくりしました。

# 2段階ProGuardって一体何してるの?
## 1段階目
**ユーザーの指定したProGuard設定を少し変更し**、入力ファイルの組成を変更して難読化をします。

*ProGuard設定の変更内容*

```
-keep class **.R { *; } # 追加
-keep class **.R$** { *; } # 追加
```

*libraryJars*
- android.jarと愉快な仲間たち
- jarファイル(大体ライブラリです)
*inJars*
- ディレクトリのクラスファイル群(大体プロジェクトに属するコードです)

`inJars`からライブラリを排除することが重要で、これをすれば難読化ができます。

## 2段階目
**ユーザーの指定した**ProGuard設定を少し変更し、入力ファイルの組成を再変更して難読化をします。

*ProGuard設定の変更内容*

```
-dontoptimize # 追加
```

*libraryJars*
- android.jarと愉快な仲間たち
*inJars*
- 1段階目でのjarファイル(1段階目の時点では変わっていません)
- 1段階目で吐き出したjarファイル

ここまでの時点ですべての入力クラスファイルが全てProGuardによって処理されます。
エラー? 出ませんよ[^5]

# 最後に
ここまでご覧いただきありがとうございました。
ソースコードは[ここ](https://github.com/nao20010128nao/ProguardTransformFix)に置いておいたので、改変するなりPRするなりIssueするなりご自由に。
そして[JitPack.io](http://jitpack.io)って便利ですね

---
[^1]: `-dontoptimize`の使用が推奨されている模様。仕方ないね
[^2]: `transform`で始まるTaskがTransform APIによるものです。
[^3]: https://github.com/nao20010128nao/android-gradle-plugin-source-codes/blob/master/gradle-core-2.4.0-alpha7-sources/com/android/build/gradle/internal/transforms/ProGuardTransform.java
[^4]: 面白いことに`TransformTask`の`transform`フィールドはfinalではないのでリフレクションで触れるんです。
[^5]: 少なくとも投稿者の環境では、ですが。
sed で特定行の改行を削除する


sed は比較的簡単にテキストデータの加工ができて大変重宝するツールですが、複数行マッチさせて何か処理するという際にちょっと困ってしまったのでメモ。

## GNU sed (Linux)

```bash:sh
sed -r "/.+:/N;s/(.+:.*)\n(.*)/\1\2/g" sample.txt
```

## BSD sed (Mac, UNIX)

```bash:sh
sed -E "/.+:/N;s/(.+:.*)\n(.*)/\1\2/g" sample.txt
```


これで、最初のパターン「.+:」にマッチする対象行を次の行と連結できます。
正しい動作を理解しているわけではないのですが、「N」を指定して直前の条件式にマッチする対象行の次の行をパターンスペースに追加して、対象行と次の行の２行に対して置換しているイメージです。
ただし、あくまでも次の行のみなので、間に空行を含む場合等ではさらに工夫が必要です。

例えば次のようなデータの場合、

```txt:sample.txt
AAA:
 200

BBB:
 100
```

下記のようになります。

```
AAA: 200

BBB: 100
```
[Survey] Kaggle - Outbrain 13位解法まとめ

Kaggle - Outbrain Click Prediction[^1]の13位解法[^2]の調査記事です．

Name: ololo
Kaggle Discussion: https://www.kaggle.com/c/outbrain-click-prediction/discussion/27897
Writeup: http://www.csie.ntu.edu.tw/~r01922136/kaggle-2014-criteo.pdf
Code: https://github.com/alexeygrigorev/outbrain-click-prediction-kaggle


- 下記特徴量をSVMやFTRLで予測
	- イベント関連: user id, document id, platform id, day, hour, geo
	- 広告関連: ad document id, campaign, advertizer id
- 特徴量の平均でのXGBoostやETでの予測
	- すべてのカテゴリ特徴量
	- 出版社やsource, 上位カテゴリ, トピックやentityといった文書の特徴量
	- これらの特徴量の相互関係
	- 広告文書とページでのコサイン類似度
- 下記特徴量のFFM
	- 文書類似度，文書カテゴリ，トピックやentityを除くカテゴリ特徴量
	- XGBoostの葉(cf.[^3])
- 最終的にXGBoostで結合

## References

[^1]: Kaggle, [Outbrain Click Prediction](https://www.kaggle.com/c/outbrain-click-prediction), 2017.
[^2]: ololo, [Congrats and Solution Sharing](https://www.kaggle.com/c/outbrain-click-prediction/discussion/27897)
[^3]: Juan, et al., [3 Idiots’ Approach for Display Advertising Challenge](http://www.csie.ntu.edu.tw/~r01922136/kaggle-2014-criteo.pdf)
XGBoostをUbuntuにもAnaconda環境にも入れられなかった話

# はじめに
XGBoostのインストールで詰まる人が多いみたいですが、私もそのうちの一人で、悲しみを背負っていました。
「この方法ならできるよ」というベストプラクティスでもなぜかエラーが起こる悲しい世界。
私は以下の方法でインストールが完了しました。なぜできたのかは謎。

# 実行環境
- n1-standard-1（vCPU x 1、メモリ 3.75 GB）
- Ubuntu 16.04.3
- Anaconda 3.4.0

# 成功した手順
## Ubuntu環境にインストールする

```bash:install-xgb-ubuntu
$ sudo apt-get install gcc
$ git clone --recursive https://github.com/dmlc/xgboost
$ cd xgboost; make -j4
$ sudo apt-get install python-setuptools
$ cd python-package
$ sudo python setup.py install

# numpy errorが出た場合は以下で代用
# $ sudo -s
# $ python setup.py install
```

##　Anacondaの仮想環境にインストールする

調べてみると**Python2の環境なら`$ pip install xgboost`を実行するだけでインストールできるよ（ニッコリ**という投稿が多かったのですが、私はエラーが発生しました。

上記の`Ubuntu環境にインストールする`の `$ sudo apt-get install python-setuptools`まで実行してから下記の手順で進めていけばエラーなくインストールできました。

```bash:install-xgb-condaenv
$ cd xgboost  
$ ./build.sh
$ source activate py27 #py27は仮想環境の名前
$ pip install -e python-package
```

# 参照
- [Installation Guide](https://github.com/dmlc/xgboost/blob/master/doc/build.md)
- [pip install failure #463](https://github.com/dmlc/xgboost/issues/463)
同名の名前がある影響でvagrant upができない時の対処法

# 問題
LaravelのHomeSteadで環境を新たに作成する際、既に過去に作ったことがある場合には、下記のエラーが発生する可能性があります。
直訳すると、同名のファイルがあるので名前変更して下さいと言われているので、VirtualBoxを起動し名前を変更してあげます。

# エラー文
```php
A VirtualBox machine with the name 'homestead-7' already exists.
Please use another name or delete the machine with the existing
name, and try again.
```

# 対処法
1. VirtualBoxを起動します
2. 名前が重複してしまっているものを右クリック⇒設定を選択します
3. 該当の名前を変更します

# 参考イメージ
![2017-10-09_22h30_13.png](https://qiita-image-store.s3.amazonaws.com/0/164066/b113a2cb-b855-1f0b-2323-02a4acb8fa32.png)
AWSでDirectConnect経由のNLBを試してみる

# 現状の環境
<img width="703" alt="スクリーンショット 2017-10-09 21.46.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/202960/5a608fd1-fad0-49c6-c40a-03358f80c3cb.png">

社内からaws、awsから社内環境共にHttpProxy専用のVPCを通して、アクセスしています。
社内、aws環境共に複数のHttpProxyサーバに対してCNAMEを切ってアクセスしています。(DNSラウンドロビン)

# やりたいこと
現在の構成では、HttpProxyサーバが死んだ場合にDNSに登録し直さないといけません。
社内環境では結構面倒なので、NLBを挟んでNLB配下のHttpProxyサーバは、autoscaleにしたいと思います。
(ちなみにELBの場合はIPアドレスが固定ではないので使えません)
NLBの場合は、プライベートアドレスも固定されるらしいので、こちらを使ってみたいと思います。
DNSには、NLBのプライベートアドレスを登録する予定です。

# 完成予定図
<img width="703" alt="スクリーンショット 2017-10-09 22.02.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/202960/310d24fd-12f5-7f8b-370c-fda311b2ab30.png">

# ここで問題発生
同一VPC内からのNLBへのプライベートIPへのアクセスは上手く行くのですが、社内もしくは他VPCからNLBへのプライベートIPへのアクセスが上手くいきません。
awsへ質問を投げた所、同様の問い合わせが来てるとの事です。（バグっぽい感じでした）
進展があったら更新します。
Laravelでモデルの関連テーブルを動的に指定

# やりたかったこと
- Modelクラスの関連テーブルを動的に指定する

　→　Temporaryテーブル用にModelクラスを用意するのが面倒なので、Modelクラスを使いまわしたい

# 問題点
- Modelクラスの関連テーブルをsetTable()メソッドを使用して設定できるが、save()メソッドなどを利用した場合に変更前の関連テーブルに対して実行されてしまう

# 原因
- newInstance()メソッドでModelクラスの別インスタンスを生成し利用しているため、設定が反映されない

# 対応
1. newInstance()メソッドをOverrideし、生成されたインスタンスのtableプロパティを設定する

```php:Model.php
/**                                                                                            
 * Create a new instance of the given model.
 *
 * @param  array  $attributes
 * @param  bool  $exists
 * @return static
 */
public function newInstance($attributes = [], $exists = false)
{
    $model = parent::newInstance($attributes, $exists);

    // 設定されている関連テーブルを新しいインスタンスにも設定
    $model->setTable( $this->getTable() );
    return $model;
}
```

# その他
1. query()メソッドは(new static)のインスタンスに対するnewQuery()メソッドの結果を返すため、今回の対応では意味なし
2. newQuery()メソッドでQueryBuilderを取得する必要がある
PaperclipでBase64エンコードされた画像を受け取る

方法がQiitaに載ってなく、探すのに手間取ったため書き残しておく。

# 概要

画像(ファイル)の受け取り方は主に下記2パターンらしい。
1. multipart/form-data
2. Base64エンコード

参照：https://qiita.com/mserizawa/items/7f1b9e5077fd3a9d336b

Paperclipに関して、
1のパターンについては、いくらでも記事が見つかるが、
2のパターンがあまり見つからない。
APIの実装時に2のパターンで作ってみようと思い、調べたので書き残す。

# コードサンプル
いきなりですが…

```
class Image < ActiveRecord::Base
  attr_accessor :image_name, :image_data

  has_attached_file :image

  before_validation :decode_base64_image

  private

  def decode_base64_image
    if image_data && image_name
      content_type = Mime::Type.lookup_by_extension(File.extname(image_name)[1..-1]).to_s
        # => 'image/jpeg'などが取得できる
      image_file = Paperclip.io_adapters.for("data:#{content_type};base64,#{image_data}")
　　　　　　　　　　　   # => 'data:#image/jpeg;base64,/9j/4AAQSkZJRgAB...'
      image_file.original_filename = image_name
      self.image = image_file
    end
  end
end
```

# 結論
↓の形が作れれば良いようです
`data:#image/jpeg;base64,/9j/4AAQSkZJRgAB...`
Ansibleでジャバダウンロード


## はじめに
サーバ構築を自動化するのに便利な Ansible ですが、JDK をインストールしようと思うといくつかしんどいポイントがあります。解消方法について、日本語の情報が少なかったので簡単にまとめてみます。

## ライセンスへの同意ができない
ダウンロード画面からお判りいただける通り、 JDK のダウンロードにはライセンスへの同意が必要です。

![スクリーンショット 2017-10-09 13.58.09.png](https://qiita-image-store.s3.amazonaws.com/0/158574/b845badd-b127-e90f-35fe-0a25e48b3d06.png "スクリーンショット 2017-10-09 13.58.09.png")

Ansible では、 `yum` モジュールや `get_url` モジュールを利用してミドルウェアのダウンロードが簡単に行えますが、 JDK の場合は素直にダウンロードすることができません。この問題は、ライセンス認証済みであることを Cookie に付与することで回避できます。

Cookie は  `get_url` モジュールの `headers` オプションに設定できます。

```yml
headers: "Cookie:' gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie'"
```

## 証明書チェックに引っかかる
加えて、 Java のダウンロードは SSL を介して行われるため、証明書の問題も潜り抜ける必要があります。

`get_url` モジュールには `validate_certs` というオプションがあるため、ここに `no` を設定することで回避できます（文字通り認証をすっ飛ばすオプションなので、信頼できるサイトに対してのみ使用するようにしてください）。

```yml
validate_certs: no
```

## まとめると
以下のスクリプトでジャバダウンロードできます。

```yml
- name: download JDK
  get_url:
    url: "http://download.oracle.com/otn-pub/java/jdk/8u144-b01/090f390dda5b47b9b721c7dfaa008135/jdk-8u144-linux-x64.rpm"
    dest: "/opt/jdk-8u144-linux-x64.rpm"
    headers: "Cookie:' gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie'"
    validate_certs: no
    owner: root
    group: root
    mode: 744
- name: install JDK from a local file
  yum:
    name: "/opt/jdk-8u144-linux-x64.rpm"
    state: present
```
Raspberry pi zero Wのwifi設定

wifiルータを新しくする際、Raspberry Piのwifi設定をしようとしたらハマったのでメモ。
他にもたくさん記事があるのだが、Raspbianの設定が最近変わったせいか、
なかなか接続できなかったので参考になれば幸いである。

## 接続先のネットワーク設定
* ステレスSSID
* WPA2-PSK[AES]

## 設定箇所
以下の２ファイル。

* /etc/network/interfaces
* /etc/wpa_supplicant/wpa_supplicant.conf

### interfaces
```
auto wlan0
allow-hotplug wlan0       #ここは消さなくてもよい？
iface wlan0 inet dhcp     #dhcpで試した。
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf    #wpa-roamとなっている記事もあったがconfでうまく行った。
```

### wpa_supplicant.conf
```
country=JP                     #これをつけてから繋がったので重要かもしれない。
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev       #この２行はいじってない。
update_config=1

network={
  ssid="*****"                 #SSID
  proto=RSN                    #WPA2だとRSNらしい。WPAとしている記事やWPA2としている記事もあった。
  key_mgmt=WPA-PSK             #WPA2-PSKとするとダメでした。
  pairwise=CCMP                #CCMP TKIPとする、という記事もあった。
  group=CCMP                   #
  auth_alg=OPEN
  scan_ssid=1
  psk=******
}
```



## 参考
* https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md
* https://qiita.com/mascii/items/0d1a280ac58ed8f6f999
* https://qiita.com/yosi-q/items/c677e4650b22ffffa806
* https://qiita.com/shigeru-yokochi/items/5d273b3444ffb008c778#vi-etcnetworkinterfaces
Javaの基本文法

2017年10月09日に限定公開した記事．「**[スッキリわかる Java入門](http://amzn.asia/4lFETZ4)**」を参考にした．

## 開発環境の構築
[Oracle](http://www.oracle.com/technetwork/java/javase/downloads/index.html)からJava SE，[JET BRAINS](https://www.jetbrains.com/idea/)からIntelliJ IDEAをDL，インストール．[Atom](https://atom.io/)エディタも有用．

## 基本事項
### 変数宣言
```java:Main.java
public class Main{
    public static void main(String args[]){
        int 変数名 = 値;
        final int 定数名 = 値; // 定数名は大文字
    }
}
```
| 分類 | 型名 | 格納データ |
|:-:|:-:|:-:|
|  整数 | long  | 大  |
|   | **int**  | 普通  |
|   | byte  | -128 ~ 127  |
| 小数  | **double**  | 普通  |
|   | float  | 曖昧  |
| 真偽値  | **boolean**  | true / false  |
| 文字  | **String**  | 文字列  |
|   | char  | 1文字  |

### 演算子
```java:Main.java
int age = 15;
```
| 演算子 | 機能 | 評価方向 |
|:-:|:-:|:-:|:-:|:-:| 
| ++  | 左辺 = 左辺 + 1  | ->  | 
| --  | 左辺 = 左辺 - 1  | ->  |  
| *  | 乗算  | ->  | 
| /  | 除算  | ->  | 
| %  | 剰除  | ->  | 
| +  | 加算  | ->  |  
|   | 文字列連結  | ->  | 
| -  | 減算  | ->  | 
| =  | 代入  | <-  | 
| +=  | 左辺 = 左辺 + 右辺  | <-  |   
|   | "左辺" = "左辺" + "右辺"  | <-  |      
| -=  | 左辺 = 左辺 - 右辺  | <-  |   
| *=  | 左辺 = 左辺 * 右辺  | <-  |   
| /=  | 左辺 = 左辺 / 右辺  | <-  |   
| %=  | 左辺 = 左辺 % 右辺  | <-  | 

### 基本的な命令実行
```java:Main.java
// 画面出力(改行あり)
System.out.println("文字列");
// 画面出力(改行なし)
System.out.print("文字列");
// 文字列を数字に変換
int n = Integer.parseInt(文字列);
// 乱数発生
int r = new java.util.Random().nextInt(上限);
//キーボードから入力受付
String m = new java.util.Scanner(System.in).nextLine();
int n = new java.util.scanner(System.in).nextInt(); 
```

## 条件分岐
### 演算子
| 演算子 | 意味 |
|:-:|:-:|
| == | 左辺 = 右辺 |
| != | 左辺 ≠ 右辺 |
| >  | 左辺 > 右辺 |
| <  | 左辺 > 右辺 |
| >= | 左辺 ≧ 右辺 |
| <= | 左辺 ≦ 右辺 |
| && | 条件式1 ∨ 条件式2  |
| &#124;&#124; | 条件式1 ∧ 条件式2  |
### If-ElseIf-Else文 - 分岐分岐
```java:Main.java
if (条件式1) {
    ブロック1
} else if(条件式2) {
    ブロック2
} else {
    ブロック3
}
```
### Switch文
**整数・文字列・文字**の**左辺と右辺の一致**を評価するとき，If-ElseIf-Else文をSwitch文に書き換えられます．

```java:Main.java
switch(条件値)　{
    case 値1:
        処理1
    case 値2:
        処理2
        break; //処理自体を中断
    default:
        デフォルトの処理
}
```
### Do-While文 - 繰り返し
```java:Main.java
do{
    ブロック
}while (条件式) {
    ブロック
}
```
### For文
繰り返し回数が分かっているとき，For文を使うべきです．

```java:Main.java
for (int i = 0; i < 10; i++) {
    ブロック
    if (i == 7) {
        continue; //現在の周回を中止
    }
}

while (true) {
    ブロック // 無限ループ
    for (;;) {
        ブロック // 無限ループ
    }
}
```

## 配列
```java:Main.java
int[] 配列名 = {値0, 値1 ... 値n}
配列名 = null; // 配列を切る
int 配列の要素数 = 配列名.length;

// 拡張For文
for(int 任意の変数名: 配列名) {
    ブロック
}
```
jsdoでMK-80 その9

#概要
jsdoでMK-80やってみた。
アセンブルして、メモリーへロードするまで、自動化した。
100秒、タイマーやってみた。

#サンプルコード

```
showsegdata  EQU  01C0H
timer45      EQU  022DH
timer9       EQU  02EAH
timer27      EQU  02EFH
    
ORG 8200H

start:
    mvi b, 0H
loop1:
    mvi c, 23H
loop:
    mov a, b
    sta 83F7H
    push b
    call showsegdata   
    call timer27
    pop b
    dcr c
    jnz loop
    mov a, b
    inr a
    daa
    mov b, a
    jmp loop1

```

#成果物

http://jsdo.it/ohisama1/cm69
馬鹿の一つ覚え: Fortran 2008

かつてFORTRAN 77を勉強し、ある程度のプログラムを書けるようになったのだが、使う機会がないので、もう全く何も書けなくなってしまった。一度は習得したのだから、ここでFortran 2008を勉強してみることにする。

## コンパイル方法
```
$ gfortran -v 2>&1 | grep version
gcc version 6.4.1 20170727 (Red Hat 6.4.1-1) (GCC) 
$ cat foo.f08
program do_nothing
! comment
  implicit none
end program do_nothing
$ gfortran -Wall -Werror -std=f2008 -O -o foo foo.f08
$ ./foo 
$ ls -l foo*
-rwxr-xr-x 1 glire glire 8648 Oct 13 12:13 foo
-rw-r--r-- 1 glire glire   68 Oct 13 11:55 foo.f08
```
Fortran 2008のソースプログラムの拡張子は .f08 とする。
Fortran 2008に沿ったコーディングにするために -std=f2008 を添える。
感嘆符 ! の後がコメントになる。
implicit none により、暗黙の型宣言ではなく、明示的な型宣言を必須とする; 暗黙の型宣言はバグを作り込みやすいので使わない

## 文字列の入力

```
  character(len = 76) :: line
  read (*, *) line    ! 空白文字の手前までを読み込む; (*, *) の直後にカンマは入れない
  read (*, '(a)') line    ! '(a)' 1行全部を読み込む
  read (5, '(a)') line    ! 5は標準入力
```

## 文字列の出力

```
  print *, line    ! printはwriteと比べ標準出力にしか出力できないなど制約がある
  write (*, *) line    ! (*, *) の直後にカンマは入れない
  write (*, '(a)') line    ! '(a)' で行頭にスペースを入れないようにできる
  write (6, '(a)') line    ! 6は標準出力
  write (0, '(a)') line    ! 0は標準エラー出力
  write (6, '(a)', advance = 'no') 'do not put a new line'    ! 改行しない
```
[Windows10]サービスオプション

Windows10は、Windows as a Service(WaaS)という考えのもと、継続的に機能改善や新機能を提供している。
機能アップグレードにより最新の機能が使えるようになることはありがたいが、企業としては機能アップグレードの影響でシステムが動かなくなることは避けなければならない。
Windows10には**サービスオプション**という考え方があり、適切なサービスオプションを選択することで機能アップグレードの配信を遅らせることもできる。

以下、サービスオプションの概要。

- CB(Current Branch)
	- 即座に機能アップグレードが配信されるオプション。
	- Home、Pro、Enterpriseで選択可。
	- 一般利用者向け。
	- 既定はこれ。

- CBB(Current Branch for Business)
	- 機能アップグレードの配信延期が可能なオプション。
	- Pro、Enterpriseで選択可。
	- ビジネス利用者向け。

- LTSB(Long Term Servicing Branch)
	- 機能アップグレードが全くされないオプション。
	- Enterprise LTSBでのみ選択可。
	- 特定システム向け。

なお、どのサービスオプションにおいても、サービス更新プログラム(セキュリティパッチ)は提供される。

また、CB、CBBに置き換わるSemi-Annual Channelというサービスオプションがリリースされているようだが、まだあまりよくわかっていない。

【参考】
[Windows 10 のサービス オプション](https://technet.microsoft.com/ja-jp/library/mt574263(v=vs.85).aspx)
[Windows 10 のリリース情報](https://technet.microsoft.com/ja-jp/windows/release-info.aspx)
[Swift] 親Viewを辿ったりする操作を抽象化する


# Tl;Dr

以下のようなヘルパー関数を定義しておくと、便利かも。

```swift:ヘルパー関数
func chainIterator<T>(_ value: T, _ f: @escaping (T?) -> (T?)) -> AnyIterator<T> {
    var next: T? = value
    return AnyIterator {
        defer { next = f(next) }
        return next
    }
}
```

```swift:親Viewを辿る
let v1 = UIView(); v1.tag = 1;
let v2 = UIView(); v2.tag = 2; v1.addSubview(v2)
let v3 = UIView(); v3.tag = 3; v2.addSubview(v3)
let v4 = UIView(); v4.tag = 4; v3.addSubview(v4)

let superviews = chainIterator(v4) { $0?.superview }
superviews.forEach { print($0.tag) }
/*
 4
 3
 2
 1
 */
```

# 一般的な方法

例えば、Viewの階層が以下のようになっていたとします。
（`()`内は`tag`プロパティ値）

```
v1 (1)
|
+- v2 (2)
   |
   +- v3 (3)
      |
      +- v4 (4)
```

```swift:View階層のセットアップ
let v1 = UIView(); v1.tag = 1;
let v2 = UIView(); v2.tag = 2; v1.addSubview(v2)
let v3 = UIView(); v3.tag = 3; v2.addSubview(v3)
let v4 = UIView(); v4.tag = 4; v3.addSubview(v4)
```


`v4`から`superview`を辿る場合には、おそらく`while`を使うのが一般的かと思います。

```swift:whileを使って辿る
var v = v4
while let superview = v.superview {
    print(superview.tag)
    v = superview
}
/*
 3
 2
 1
 */
```

ワンショットの走査ならこれでも良いかもしれませんが、何回か登場する場合にはちょっと冗長になりがちです。
`superview`専用の関数を用意しても良いかもしれませんが、せっかくなのでこの手の操作を一般化したいところです。

# 走査するIteratorを返す関数を定義する

冒頭でも記載しましたが、以下のようなヘルパー関数を書くと一般化できそうです。

```swift
func chainIterator<T>(_ value: T, _ f: @escaping (T?) -> (T?)) -> AnyIterator<T> {
    var next: T? = value
    return AnyIterator {
        defer { next = f(next) }
        return next
    }
}
```

これは以下のように利用します。

```swift
let superviews = chainIterator(v4) { $0?.superview }
superviews.forEach { print($0.tag) }
/*
 4
 3
 2
 1
 */
```

`while`で書くのに比べた利点は、共通化されていて再利用できるのはもちろんですが、意図が明白になるという点が挙げられるかと思います。

```swift
chainIterator(v4) { $0?.superview }
```

”`v4`をベースとして`superview`を辿る”という意図が非常に読み取りやすいかと思います。

また`Iterator`であるため、リスト系の操作をそのまま利用することも出来る利点もあります。

```swift
let superviews = chainIterator(v4) { $0?.superview }
superviews
    .filter { $0.tag % 2 == 0 }
    .map { "tag: \($0.tag)" }
    .forEach { print($0) }
/*
 tag: 4
 tag: 2
 */
```

このような操作が必要になるかはさておき、Iteratorとして抽象化して扱えるのはメリットかと思います。

# リフレクションで継承チェーンを辿る

リフレクションで継承チェーンを辿りたいときにも利用できます。

```swift
class A {}
class B : A {}
class C : B {}
class D : C {}

let mirrorD = Mirror(reflecting: D())
let superclasses = chainIterator(mirrorD) { $0?.superclassMirror }
superclasses.forEach { print($0) }
/*
 Mirror for D
 Mirror for C
 Mirror for B
 Mirror for A
 */
```

このように、自身と同じ型か`nil`を返す、プロパティまたは関数で利用することができます。

# 最後に

こういった処理が必要になるケースはそんなに多くないかもしれませんが、こういったIteratorを使った「繰り返し」としての抽象化テクニックを覚えておくと、他のケースでも応用が効くかもしれません。（と言えるほど、私も詳しくはないのですが・・・）

一応、Gistにソースを上げています。
https://gist.github.com/YusukeHosonuma/8798429da3d117bf3c4bc004292ecb82

P.S.
Twitter上でのアドホックな議論だったのですが、せっかくなので知識共有としてQiitaに記事として上げてみました。
S3にアップロードしたファイルをダウンロードする

今回することとしては、S3へアップロードしたファイルをダウンロードすることです。
実装の経緯としては、「ファイルをまとまった所にアップロードして共有し、そのファイルをいつでもダウンロードできるようにしたい」といった要望があったためです。

ファイルのアップロード自体は、何度が実装したことがあったのですが、よくよく考えると「S3側からダウンロードさせる」ことはしたことがないことに気づきました。まだまだ理解が乏しく参考になるかわかりませんが、同じような実装をしようとしている方の参考に少しでもなればと思います。

※S3へのファイルアップロードは、他にも参考記事がたくさんあるので省略します。当該記事では、carrierwaveを使用しS3へアップロードしています。
参考URL:https://qiita.com/junara/items/1899f23c091bcee3b058


##実装方法
実装方法としては、S3のpathを指定して[send_data](http://railsdoc.com/references/send_data)でダウンロードする方法です。

```ruby:download_controller.rb
  def download
    file = params[:download_file]
    file_id = params[:download_id]
    # ファイルネームをエンコード（日本語のファイルに対応させるため）
    file_name = ERB::Util.url_encode(file)

    # data = open("https://[エンドポイント名]/[バケット名]/[ディレクトリ名]/[ファイル名]")
    data = open("https://s3-ap-northeast-1.amazonaws.com/sample-bucket/uploads/upload/file/#{file_id}/#{file_name}")
    send_data data.read, filename: file_name, disposition: 'attachment', stream: 'true', buffer_size: '4096'
  end
```
※上記の場合、`/uploads/upload/file/`の箇所が**ディレクトリ名**となります。
viewのほうで、ダウンロードリンクを設置します。この際、***download_id***と***download_file***のような形でパラメータをコントローラー側へ渡します。

```rb:index.html.slim
- @downloads.each do |download|
  - download.uploads.each do |upload|
    = link_to upload[:file], download_path(download, download_id: upload[:id].to_s, download_file: upload[:file]) if upload[:file].present?        
```
##はまった点
・下記の実装では、[send_file](http://railsdoc.com/references/send_file)で行なっています。S3の場合は、ファイルデータの保持の仕方が違うのかsend_fileのpath指定をしてもダウンロードをすることができませんでした。S3ではなくサーバーに直接アップロードした場合できるかもしれません。（確認していません・・・ローカルでは確認済み）

```rb:send_fileでの例
 file = params[:download_file]
 file_id = params[:download_id]
 file_name = ERB::Util.url_encode(file)
 # ここまではS3の方法と同じ。

 filepath = Rails.root.join('public/uploads/upload/file/'+ file_id, file_name)
 send_file(filepath)
```
参考URL:https://qiita.com/akkun_choi/items/64080a8e17930879b4da

・[AWS SDK](https://github.com/aws/aws-sdk-rails)を利用した方法では、ブラウザ上でダウンロードされず、実行しているプロジェクトのディレクトリ下にファイルがダウンロードされていました（「S3　ファイルダウンロード」で検索すると大抵「AWS　SDK」の記事がでてくる）。そもそも今回しようとしていたブラウザ上でダウンロードする形に至らなかったため使用を断念。

##まとめ
今回なんとか求めていたファイルダウンロードを実装することができたが、まだまだ理解が乏しく無理やり実装した感が否めません・・・上記について、間違いやベストな方法がわかったら適宜更新していきたいと思います。
【勉強メモ】テーブルのデータをviewに表示させる【挫折しない！】

##１．controllerにテーブルデータの変数を代入

```app/controller/test_controller.rb
  def index
    @memos = Memo.all
  end
```

##２．viewをいじる
何度書いても忘れるから書いておく。

```ruby
@memos each.do |memo|
```

each.doの繰り返し。

```app/view/test/index.html.erb
<h1>Test#index</h1>
<p>Find me in app/views/test/index.html.erb</p>
<center>
<table border="1">
<tr><th>名前</th><th>性別</th><th>メモ</th></tr>
<% @memos.each do |memo| %>
<tr><td><center><%= memo.name %></center></td>
<td><center><%= memo.sex %></center></td>
<td><center><%= memo.memo %></center></td>
<% end %>
```

##３．ビューで表示させる。
<img width="944" alt="スクリーンショット 2017-10-09 18.45.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/205578/98348468-e7c7-3515-c3e5-47d1df66ee31.png">

やった！！
【勉強メモ】カラムの追加方法【挫折しない！】

##１．コマンドを入力

```
$ rails g migration add_カラム名_to_テーブル名 追加カラムのデータ型
```

今回はmemoテーブルにnameカラムを追加した。データ型はtext。

```
$ rails g migration add_name_memos name:text
```

###データ型。
string 文字列型
text テキスト（不定長文字列）型
integer 整数型
float 浮動小数点数型
decimal 固定長整数型
datetime 日時型
timestamp タイムスタンプ型
time 時刻型
date 日付型
binary バイナリ文字列型
boolean 真偽値型


##２．新しく作成されたマイグレーションファイルに以下のアクションを追加。

```
def change
  add_column :テーブル名, :カラム名, :データ型
end
```

っていうのを追加するんだけど

```db/migrate/20171009081631_add_name_to_memos.rb
class AddNameToMemos < ActiveRecord::Migration[5.1]
  def change
    add_column :memos, :name, :text
  end
end
```

追加しなくても入っているじゃない？
なぜ？？？

##３．マイグレーションファイルを反映
いつものあれをやる。

```
$ rails db:migrate
```

railsコンソールを起動させ

```
$ Memo.all
```

で、カラムが追加されたことを確認した。

とりあえず、カラム追加はこれでいいのか？？？

いいとしたら、少しレベルアップした。
Swift4の機能を活用してGoogle画像検索結果を利用する

Google画像検索APIをiOSで利用する - Qiita
https://qiita.com/ukandori/items/234156f97eb6dad77966
などの先人を参考に。Codableや~~新しいreduce~~URLComponentsを使ったらだいぶシンプルになりました。
(追記)コメントを受けて、URLComponentsに書き替えました。こちらのほうがStringでやるより適切ですね。


```swift
// Structure defined by https://developers.google.com/custom-search/json-api/v1/reference/cse/list#response
struct CustomSearchedResult: Codable {
    struct Item: Codable {
        struct Image: Codable {
            let contextLink: String
            let thumbnailLink: String
            let thumbnailHeight: Int
            let thumbnailWidth: Int
        }
        let link: URL
        let displayLink: URL
        let mime: String
        let image: Image
    }
    let items: [Item]
}

let query = "ほげほげ"
var urlComponents = URLComponents(string: "https://www.googleapis.com/customsearch/v1")!
urlComponents.queryItems = [
    URLQueryItem(name: "searchType", value: "image"),
    URLQueryItem(name: "q", value: query),
    // To get `key`, create your own project from https://console.developers.google.com/projectcreate
    URLQueryItem(name: "key", value: "xxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"),　
    // To get `cx`, create your own search engine from https://cse.google.com/cse/create/new
    URLQueryItem(name: "cx", value: "000000000000000000000:xxxxxxxxxxx")
]
print(urlComponents.string!)

let task = URLSession.shared.dataTask(with: urlComponents.url!) { data, response, error in
    guard let jsonData = data else {
        print(error as Any)
        return
    }

    do {
        let result = try JSONDecoder().decode(CustomSearchedResult.self, from: jsonData)
        print(result.items[0])

        let task = URLSession.shared.dataTask(with: result.items[0].link) {data, response, error in
            guard let image = data.flatMap(UIImage.init) else {
                print(error as Any)
                return
            }
            // imageとれた
        }
        task.resume()
    } catch(let e) {
        print(e)
    }
}
task.resume()
```
python+beautifulsoup+selenium+phantomjsで画像スクレイピング

## 経緯
- 機械学習で使うための画像データ収集をしたかったため、beautifulsoupを使ってWebスクレイピングをしていた。
- jsで書かれたところ(「次へ」ボタン等)は処理できなかったため、1ページ分の画像しか収集できなかった。
- 機械学習で使うためにも、jsに対応してたくさんの画像を収集したい

## beautifulsoup4
pythonのhtmlスクレイピング用ライブラリ
単体ではjsで書かれている動的な部分は触れない
## Selenium
webブラウザ上でのテストによく使われているツール
今回はPhantomJSの制御に使用
## PhantomJS
ヘッドレスブラウザ
Chromeやfirefoxなど、GUIのブラウザのCUI版
いちいちブラウザを立ち上げずにスクレイピングできる
JSで書かれたコードもレンダリングできる

## 環境構築
### beautifulsoup4
`$ pip install --upgrade beautifulsoup4`
### selenium
`$ pip install --upgrade selenium`
### PhantomJS
[公式ページ](http://phantomjs.org/)からダウンロードしたファイルにpathを通す

    # ダウンロードしてきたディレクトリに移動
    # 以下の場合は、Downloadフォルダにある例です
    cd ~/Downloads/phantomjs-2.1.1-macosx/
    
    # /usr/local/bin にコピー
    cp bin/phantomjs /usr/local/bin/

## 実行
コード→[https://github.com/daaaisuke/scraping](https://github.com/daaaisuke/scraping)(scraping2.py)
sampleではyahooの画像検索で実行

手順
1. dirnameで指定した名前のファイル(画像保存用ファイル)がなければ作成(35行目)
2. PhantomJSをブラウザとして選択(40行目)
3. 指定したurlのページをPhantomJS(ヘッドレスブラウザ)でレンダリング(43行目)
4. レンダリング結果をPhantomJSから取得
5. 取得したhtmlをbeautifulsoupに渡し、画像のurlを取得(52~55行目)
6. 取得したurlの配列をfor文で回して、ローカルに保存する(57~70行目)
7. 次ページへ進むためのjsを探し出し、クリック(73行目)
(4~7をloop)

### 注意点
- 最初のfor文のpage_numで指定した数だけ次のページへと遷移していく。
- 手順7でjsをクリックした後のhtmlを、次の周の手順4で、レンダリングしている。
- `remove("javascript:void(0);")`は配列に入ってしまったノイズを削除しているだけ


うまくいけば、ログが吐かれ続けた後、指定されたディレクトリに画像がたくさん入っているはず！
RubyやRailsでこれの名前なんだっけとなりやすいものメモ（随時更新）

# Ruby
## メソッド最後に!や?がついているメソッド
* !: Bang method [参考](http://ruby-for-beginners.rubymonstas.org/objects/bangs.html)
* ?: Predicate method [参考](http://ruby-for-beginners.rubymonstas.org/objects/predicates.html)

## Arrayに要素を追加する<<
shovel [参考](https://stackoverflow.com/questions/9343680/how-does-shovel-operator-work-in-ruby-hashes)
Kali Linux 2017.2 に Parallels Tools をインストールする

Parallels tools のディスクを挿入した後通常通り

`./install`

すると

`Permission denied`

と言われてしまった。

まず、デスクトップ上に新しいフォルダを作ります。（今回はtmp）
そのフォルダにディスクの中身を全てコピーします。（リードオンリーなので）

```Bash
cd /root/Desktop
chmod -R 777 tmp/
```

をしたあと

```Bash
cd tmp/
./install
```

で無事インストールできた！
fishを使っている私がMacでRubyのバージョン変更しようとしてハマったので備忘録を残す

#### rbenv, ruby-build インストール

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

#### 現在の設定されているバージョンを確認
```bash
$ rbenv versions
$ ruby -v
```

#### インストール可能なバージョンのリストを確認
```bash
$ rbenv install -l
```

#### 設定したいRubyのバージョンをインストール
```bash
$ rbenv install <変更したいバージョン>
```

#### インストールしたRubyを設定
```bash
$ rbenv global <変更したいバージョン>
```

#### 変更後のバージョンを確認
```bash
$ rbenv versions
$ ruby -v
```

`ruby -v` の出力が以前と変わらん...

#### config.fish 修正して rbenv init - を実行するようにしてみる
```bash
echo "eval (rbenv init - | source)" >> ~/.config/fish/config.fish
```
※ `rbenv init` は rbenv の環境変数(RBENV_ROOT)の値を書き換えるらしい([rbenv + ruby-build はどうやって動いているのか](http://takatoshiono.hatenablog.com/entry/2015/01/09/012040))。

#### 再度、確認

```bash
$ ruby -v
```

変わらず...

#### `eval (rbenv init - | source)` をターミナルから直接実行してみる

```bash
$ eval (rbenv init - | source)
```

#### 再度、確認
```bash
$ ruby -v
```
変わった、なぜ config.fish を経由するとダメなのか...

終わり。
とりあえずPHPが使いたいだけなのでMac標準のApacheを起動してindex.phpファイルを開くとこまで

とりあえず```
sudo apachectl start
```でApache起動。

止めるのは```
sudo apachectl stop
```でOK。

設定ファイルをいじらないとPHP使えない。標準で```
/private/etc/apache2/httpd.conf```
にあるので```
sudo vi /private/etc/apache2/httpd.conf```
で編集。sudoでやんないと、保存できない。

169行目あたり
```#LoadModule php5_module libevec/apache2/libphp5.so```
をとりあえずアンコメントだ！

つぎ
```237 DocumentRoot "/Library/WebServer/Documents"
 238 <Directory "/Library/WebServer/Documents">```
なんだこれ。じぶんの作業ディレクトリにしちゃえ。
```237 DocumentRoot "/Users/komaki/www"
 238 <Directory "/Users/komaki/www">```

さらに
```418 AddType application/x-compress .Z
419 AddType application/x-gzip .gz .tgz```
これに```
418 AddType application/x-compress .Z
419 AddType application/x-gzip .gz .tgz
420 AddType application/x-httpd-php .php .html```
という行を追加することで.htmlを受け取ってもApacheが起動するようになる。らしい。何の役に立つのかは不明。


参考サイト
http://motw.mods.jp/Mac/local_server.html
eclipse でXDEBUGの設定

eclipse でXDEBUGの設定

いつも戸惑うので記録

# 前提条件

```
php7.1
nginx
ubuntu16.04
vagrant
```


ワークスペースは、

```
d:\workspace
```

とする。

ここのファイルを利用する

```
d:\workspace\cakephp003\cake001\
```


# 内容（vagrant）
vagrant ssh にて ubuntu にログイン

```
sudo vim /etc/php/7.1/fpm/conf.d/20-xdebug.ini
```

以下を追記

```
xdebug.remote_enable=1
xdebug.remote_autostart=1
xdebug.remote_handler=dbgp
xdebug.remote_mode=req
xdebug.remote_port=9000
xdebug.remote_connect_back=on
xdebug.idekey=
```

サービスを再起動

```
sudo service php7.1-fpm restart
```

# 内容（eclipse）
メニューから

```
	実行
		デバッグの構成
```
		
PHP Web アプリケーション

```
	新規
```
	
```
名前
	cakephp003-cake001
サーバー
	Default PHP Web server
ファイル
	/cakephp003/cake001/webroot/index.php
```


サーバー

```
	［構成］
```

をクリック
サーバー

```
	サーバー・プロパティ
		ベースURL
			http://dev301.cakephp.dev
		文章ルート
			D:\workspace\cakephp003\cake001\webroot
```

					
デバッガ
	ポート:9000

パス・マッピング
/app
/cakephp03


# おまけ

ブレイクポイント設定しようとしたら、○に斜め斜線になった。
メニューから
	実行
		すべてのブレークポイントをスキップ
のチェックを外して無事ブレークした。
macOS High Sierra にアプデしたら、therubyracer (libv8) 周りでハマった（解決）

High Sierra からなのか、


```:bash
 ls -las /usr/local/opt/
total 0
0 drwxrwxr-x  29 YuzoNishikawa  admin  928 10  9 17:39 .
0 drwxr-xr-x  13 root           wheel  416  9 28 00:25 ..

.................... 省略 ...................................

0 lrwxr-xr-x   1 YuzoNishikawa  admin   23 10  9 17:17 v8 -> ../Cellar/v8/5.1.281.47
0 lrwxr-xr-x   1 YuzoNishikawa  admin   30 10  9 17:39 v8@3.15 -> ../Cellar/v8@3.15/3.15.11.18_1
0 lrwxr-xr-x   1 YuzoNishikawa  admin   23 10  9 17:17 v8@5.1 -> ../Cellar/v8/5.1.281.47

```

のように、v8@3.15 （アットマーク）でディレクトリが構成されている。

```:~/.bundle/config
---
BUNDLE_BUILD__LIBV8: "--with-system-v8"
BUNDLE_BUILD__THERUBYRACER: "--with-v8-dir=/usr/local/opt/v8\@3.15"
```

これでOK
Neo4jrbでRelをfindする

#Neo4jrbとは
　グラフィカルデータベースの一つであるNeo4jとruby/railsとの間のO/Gマッパー。要はrubyやrailsとneo4jデータベースを繋ぐパーツである。ActiveRecordはruby/railsとリレーショナルデータベースを繋いでいたが、それのグラフィカルデータベース版。

#Neo4jrbの使い方
http://neo4jrb.readthedocs.io/en/9.0.x/　

ActiveRecordとほぼ同じ。ただし、ActiveNodeとActiveRelという二つに分かれている。
 ActiveNodeはノードオブジェクトのために存在する。ActiveRecordと同じようにfindメソッドなどが使える。
　ActiveRelはリレーションオブジェクトのために存在する。

#Relを検索するには
　ActiveNodeはfindメソッドが使えるので、Nodeの検索は簡単にできる。一方で、Relにはfindメソッドがなく、あるノード同士の間にあるRelを検索するには、ノードから検索しなければいけない。

例えば、あるノードAとノードBの間にrelが存在するかどうかを調べるのは、
1. ノードAから出ている全てのRelを調べる
2. それらのRelの一つが、ノードBに繋がっているか調べる
のが必要。
例えば、
　A.each_rel{ |r| r.to_node == B ? break : return false }
のように書く。
Neo4jの生クエリであれば、
 match (A)-[r]-(B) return r
でrが存在するなら、rが帰ってくるし、rが存在しなければnilになるから、わかりやすい。

要は、ここで多少面倒な処理をしなければならないのは、ActiveRelで、同時に二つのノードを指定できないことにある。特定のRelを検索するには、当然二つのノードが決まっていなければならないので、ふたつのノードを同時に指定できるメソッドが欲しい。

ちなみに、上の式は、
 　A.query_as(:a).match('(a)-[r]-(b)').pluck(r)
みたいに生のクエリにAを組み入れることもできる。このquery_asメソッドが複数選択で使えると便利なのだが。

　(A,B).query_as(:a,:b).match('(a)-[r]-(b)').pluck(r)

みたいに。
Java8のお勉強(ラムダ式)

第二段。今更ラムダです。
職場で使ったことがないのであんまりピンとこないんですが[こちらの神サイト](http://www.ne.jp/asahi/hishidama/home/tech/java/lambda.html)
を参考に勉強してみました。

#とりあえず動かそう
とりあえず一番簡単なものをを書いてみました。

```
		/* 例1。引数なしの簡単なやつをとりあえず動かしてみる */
		Runnable runner = () -> {
			System.out.println("初ラムダ式。今の所何が凄いのか分かってない。");
		};

		Thread t = new Thread(runner);
		t.start();
```


これを実行するとよくわからないけど標準出力のところに書いたメッセージがコンソールに出ます。
書き方としては<b>引数 -> 処理</b> って書くみたいですね。
この例では引数がないのでピンとこないのですが、引数がある時は

(s) 型省略
(String s)　型も変数名も書く
s 変数名だけ書く

とかいろいろできる。()まで省略できるのは引数が１個だけの時のみらしいです。

例①だけだとピンとこないのでもう少しやってみる。

```
		/* 例2。引数ありの場合 */
		List<String> l = new ArrayList<>();
		l.add("hello");
		l.add("world");

		// ラムダっぽくしてみたぞ
		l.forEach(s -> {
			System.out.println("loop:" + s);
		});
```

なんとなくラムダっぽいですね（謎）。実行すると

```
loop:hello
loop:world
```
と出ます。
いきなりforEachメソッドの引数の所にラムダ式が出てきていて、最初、書いておきながら？？？？
ってなりましたが、forEachメソッドの引数はConsumerっていう標準の@FunctionalInterfaceで、
このConsumerの実装を記述してあげてると思えば良さそう。（FunctionalInterface＝関数型インターフェースについては後述）
なので、Consumerの実装クラスをちゃんと用意して、こんな風にも出来る。

```
/**
 * ConsumerIFを実装してみたクラス。
 * @author komikcomik
 *
 */
public class ConsumerImpl implements Consumer<Object> {

	@Override
	public void accept(Object t) {
		System.out.println("Consumer実装したよ:" + t);
	}

}
```

これをこんな感じで呼び出す。

```
		/* 例3。Consumerを実装した、自前のFunctionalInterface（関数型インターフェース）を使用した場合。もはやラムダではないが */
		l.forEach(new ConsumerImpl());
```

実行すると以下のように出ます。

```
Consumer実装したよ:hello
Consumer実装したよ:world
```


例2の方がラムダ式使った感を満喫できますね（使った感で選ぶのもどうかって思いますが）。
例1だけだと匿名クラスの書き方変えたバージョンくらいにしか思えず、
あまり開発現場で使うイメージがわかなかったのですが
例2，3のように関数型インタフェースを引数にとるjava標準のメソッドで、
引数IFの実装を書くっていうならまあまあ使い所がありそうに思えます。
しかし理屈は分かっても使い慣れるまでには時間がかかりそう。

#関数型インターフェース
さっき途中で出てきたやつです。
細かい条件は[こちらの神サイト](http://www.ne.jp/asahi/hishidama/home/tech/java/functionalinterface.html)を参照していただければと思いますが、適当に説明すると
抽象メソッドが1つだけ定義されているインターフェースのことです。
このIFはラムダ式やメソッド参照（まだ私の投稿では扱ってないけど）の代入先になれる存在みたいです。
なので、ラムダとかのJava8要素を理解しようと思ったら関数型IFの理解は必須な感じですね。

関数型IFとなれる条件は書いたとおり簡単なので自作してもいいけど、Java8では
・Supplier・・・引数無しで値を返す
・Consumer・・・引数ありで値は返さない（なにか処理をする）。さっきの例でも出てきたやつ。
・Predicate・・・引数ありでtrue/falseを返す
・Function・・・引数ありで、任意の型を返す（プリミティブ型用のもあるよ）
みたいに色々標準的な関数IFを提供しているらしいので、
変に自作するよりはすでに標準提供されているものを選んだほうが開発プロジェクトに新規参画した人には「なんですかこのオリジナルの関数型IF」ってならなくて良いかもしれない。
F# から Azure Table Storage にデータをインサートする

AzureとF#をいじったときのメモ。

# 参考にしたもの
- https://docs.microsoft.com/en-us/dotnet/fsharp/using-fsharp-on-azure/table-storage
- http://www.fssnip.net/nR/title/Using-Azure-Table-Storage

# コードの外観
だいたいF# Snippetsのものと同じです。ただ、CloudConfigurationManagerを使わずに、AzurePortal->ストレージアカウント->アクセスキー画面にある「接続文字列」を直接CloudStorageAccout.Parseに渡しても動きました。

- 外部からJSONをFSharp.Data.JsonProviderで読み込み、それをAzure Table Storageに投げ込むという処理です
- NuGetからFSharp.DataとWindowsAzure.Storageをパッケーとして追加しておいてください

```fsharp
// F# の詳細については、http://fsharp.org を参照してください
// 詳細については、'F# チュートリアル' プロジェクトを参照してください。

open System
open FSharp.Data
open Microsoft.WindowsAzure.Storage
open Microsoft.WindowsAzure.Storage.Table

let conn = "..." // AzurePortal->

let docid = "..."

let key = "..."

let baseUrl = "https://www.../"

type ConnpassEvents = JsonProvider<"""
{
    "kind": "fusiontables#sqlresponse",
    ...
}
""">

type TechEvent(partition, row, title: string, url: string, address: string, createDate: string) =
    inherit TableEntity(partitionKey = partition, rowKey = row)

    new (title, url, address, createDate) = TechEvent("defaultPartition", Guid.NewGuid().ToString(), title, url, address, createDate)

    member val Title = title with get, set

    member val Url = url with get, set

    member val Address = address with get, set

    member val CreateDate = createDate with get, set

[<EntryPoint>]
let main argv = 
    let result = ConnpassEvents.Load(sprintf "https://www.../%s/%s" docid key)
    let table =
        let account = CloudStorageAccount.Parse conn
        let client = account.CreateCloudTableClient()
        let table = client.GetTableReference("Table")
        table.CreateIfNotExists() |> ignore
        table
    let mutable batchOp = TableBatchOperation()
    for row in result.Rows do
        let title = row.JsonValue.[0].AsString()
        let url = row.JsonValue.[1].AsString()
        let address = row.JsonValue.[2].AsString()
        let createDate = row.JsonValue.[4].AsString()
        let entity = TechEvent(title, url, address, createDate)
        let op = TableOperation.Insert(entity)
        table.Execute(op) |> ignore

    0 // 整数の終了コードを返します
```
eclipse で新規プロジェクトを作成し既存ファイルを組み込む

eclipse で新規プロジェクトを作成し既存ファイルを組み込む

いつも戸惑うので記録

# 前提条件

ワークスペースは、
d:\workspace
とする。

ここのファイルを利用する
d:\workspace\cakephp003\cake001\

# 内容

新規プロジェクトを作成
プロジェクト名
cakephp003
ワークスペース内に新規プロジェクトを作成

［次へ］


[フォルダの追加]
cake001
を選択

［完了］
mysqlからviewのdefiner一覧を取得するワンライナー

```
$ DB='<database_name>'; sudo mysql -NBe "select concat('show create view ',TABLE_NAME, ';') from information_schema.tables where TABLE_TYPE = 'VIEW' and  TABLE_SCHEMA = '$DB';" | sudo mysql $DB | awk '{print $1,$4}' | grep DEFINER

sample_view1 DEFINER=`user`@`host`
sample_view1 DEFINER=`user`@`%`
sample_view1 DEFINER=`user`@`localhost`
```

- `<database_name>` に対象のDB名を
- mysqlのユーザー・パスワード指定は適当に
Vaporのルーティングについて(基礎編)

# 動作環境
この記事では以下の環境で動作を確認しています。

* Xcode9.0
* macOS Sierra バージョン 10.12.6
* MacBook Pro (13-inch,2017,Four Thunderbolt 3 Ports) 
* Homebrew 1.3.2
* ruby 2.1.8p440 (2015-12-16 revision 53160) [x86_64-darwin15.0]
* Vapor Toolbox: 2.0.4
* Vapor Framework: 2.2.2


# ルーティング-基礎編
ルーティングはWebフレームワークで最も重要となる機能です。ルーティングをきちんと設定することで、あらゆるリクエストに対して適切なレスポンスを返すことができます。

この記事ではVaporのルーティングの設定をみていきます。

# エンドポイント登録
エンドポイントの登録は`Droplet`インスタンスに対して、HTTPメソッドと対応するインスタンスメソッドを実行します。その際にエンドポイントを文字列で引数に指定します。レスポンスはクロージャーの中で値を返すことで表現します。

> ルーティングをするためには`RouteBuilder`プロトコルを適応する必要があります。`vapor new <Name>`でVaporアプリケーションを作成している場合はVapor Toolboxがデフォルトで適応させています。`vapor build`を実行後下記のファイルを参照することで確かめられます。
> /.build/checkouts/vapor.git-[チェックアウトハッシュ値]/Sources/Vapor/Routing/Droplet+Routing.swift


`GET /welcome`でアクセスされた場合に`Hello`という文字列を返すには以下のようにします。

```swift
//getメソッドを実行
drop.get("welcome"){ req 
    return "Hello"
}
```

標準的なHTTPメソッドがすでに利用できます。
`get`、`post`、`put`、`patch`、`delete`と`options`などです。

先程のエンドポイントをPOSTでも対応できるようにしてみます。
`POST /welcome`でアクセスされた場合に`Hello`という文字列を返すようにします。

```swift
//postメソッドを実行
drop.post("welcome"){ req in 
    return "Hello"
}
```

# ネスト
`/`で区切られるエンドポイントを作成したい場合、エンドポイントをそのまま文字列として引数に渡せばよいです。

`GET /welcome/to/vapor`にアクセスしたら`Hello`の文字列を返すエンドポイントを作成するには以下のようにします。

```swift
drop.get("welcome/to/vapor"){ req in
    return "Hello"
}
```

しかし、各パスを引数として渡しても同じ結果を得られます。

```swift
drop.get("welcome", "to", "vapor"){ req in
    return "Hello"
}
```

このやり方は、`welcome/to/vapor`のように全てのパスを文字列として渡すよりも、URLパラメーターとして値を渡せるメリットがあります。

# 型安全なパラメーター
従来のWebフレームワークはルート設定に文字列を指定しているので型の違いからエラーが発生することがありました。
VaporではSwiftの型安全の仕組みを使い、安全にルーティングのパラメーターを扱えます。

型安全なパラメーターを作るためには、パスの一部に型を指定します。
Userを検索するためのエンドポイントを作成してみましょう。

`GET /users/:id`のエンドポイントを作成します。`/:id`はInt型の値とします。

```swift
drop.get("users", Int.parameter) { req in
    let userId = try req.parameters.next(Int.self)
    return "You requested User #\(userId)"
}
```

引数を型で指定しない場合は以下のように書くことで同じような結果を得ることができます。

```swift
drop.get("users", ":id") { request in
    guard let userId = request.parameters["id"]?.int else {
        throw Abort.badRequest
    }

    return "You requested User #\(userId)"
}
```


# その他のエンドポイントの指定
メソッドを第一引数として渡す方法もあります。

```swift
drop.add(.trace, "welcome") { request in
    return "Hello"
}
```
ルーティングを動的に設定したり、あまり使用頻度の低いHTTPメソッドを利用する際にこの構文は有効です。

# フォールバック
引数に`＊`を追加することで、フォールバックルートを設定することができます。

```swift
drop.get("anything", "*") { request in
    return "/anythingの後ろのどんなものでもマッチする"
}
```

上記の場合エンドポイントは下記のように`/anything`以下すべてのパスにマッチします。

* /anything
* /anything/foo
* /anything/foo/bar
* /anything/foo/bar/baz


# 参考
Basic Routing
https://docs.vapor.codes/2.0/routing/overview/

Routing Parameters
https://docs.vapor.codes/2.0/routing/parameters/
IFTTTとIRKitでGoogleHomeから家電をコントロールする


![IMG_4141.JPG](https://qiita-image-store.s3.amazonaws.com/0/206394/4949ffe9-5387-02ae-3db3-4749408905ca.jpeg)

# 概要
## ゴール
- GoogleHomeに「エアコンつけて」といったらエアコンがつくようにする

## 手順

- IRKitの接続情報を取得する
    - IRKitのIPアドレスを取得する
    - IPアドレスをキーに、クライアントトークン（clienttoken）を取得する
    - クライアントトークン（clienttoken）をキーに、クライアントキー（clientkey）とデバイスID（deviceid）を取得する
- リモコンの信号をスキャンする
- IFTTTにレシピを登録する
    - If This Then ThatのThisとThatに次のように登録する
        - 「This」側にはGoogleAssistantを選択する
        - 「That」側にはWebhooksを指定する
            - Webhooksを選択
            - URL：https://api.getirkit.com/1/messages
            - Method：POST
            - Context Type："application/x-www-form-urlencoded"
            - Bodyはスキャンした信号とキー情報を編集して入力
                - clientkey=xxx&deviceid=xxx&message={xxx}

IFTTTの設定（Googleアシスタント側）

![2017-10-09-01.PNG](https://qiita-image-store.s3.amazonaws.com/0/206394/c0bd0669-dcb2-17dc-93a2-1c98a9d1daf6.png)

IFTTTの設定（Webhooks側）

![2017-10-09-02.PNG](https://qiita-image-store.s3.amazonaws.com/0/206394/019704e7-a960-c983-3e0d-a7138a14df37.png)


## 参考サイトの補足情報
後述の参考サイトに詳しい記述があるので、それを参考にすればよい。
参考サイトどおりにできなかった箇所のみ補足する。

- Windows環境にcurlコマンド等がインストールされていない場合はGowをインストールするのをおすすめ（Cygwinよりも簡単）
- 参考サイトではIFTTTのThat側に「Maker」を使用しているが、2017/10/09現在検索できなかったため「Webhooks」を選択した
- Googleアシスタント側に「TVをつけて」のようなフレーズ登録すると、Chromecastの操作と混同して「対応する機器が登録されていません」のようなエラーになってしまうことがある。仕方がないので「テレビオン」のようなフレーズにした。（「エアコンつけて」はうまくいくのに「エアコン消して」はうまくいかないという事象も発生した）


# 参考サイト
以下のサイトを参考にさせていただきました。ありがとうございます。

- [IRKit と IFTTT でエアコンを決まった時間に自動でオフする - Qiita](https://qiita.com/ikeyasu/items/dfb991007a31d5aa03c2)
- [IRKitとIFTTTを連携してエアコンをつけてみる - ガジェットと写真とランニングのblog](http://kossie0o0.hatenablog.com/entry/2017/01/08/231636)
- [Google home + IRKit で既存の家電を操作するアプリを作ってみた - Qiita](https://qiita.com/flatfisher/items/8e2da20b054674a23021)
NumPyでテキスト形式の時系列データ読み込み

# TL;DR

genfromtxtメソッドの使い方メモ


# 読み込み対象のフォーマット

```data.csv
日時,列A,列B,データ1,データ2
2017/10/9 0:10,日本語,Eng,0,1
```

# 読み込み用サンプルコード

```py3
import numpy as np
from datetime import datetime as dt

def main():
  str2date = lambda x: dt.strptime(x.decode("utf8"), '%Y/%m/%d %H:%M')
  str2utf8 = lambda x: x.decode("utf8")

  data = np.genfromtxt("data.csv", delimiter=",", skip_header=1,
              dtype=[('col1', dt), ('col2', 'U16'), ('col3', 'S16'), ('col4', 'f'), ('col5', 'f')],
              converters={0:str2date, 1:str2utf8})

  print( data )

if __name__ == '__main__':
  main()
```

# 出力

```
(datetime.datetime(2017, 10, 9, 0, 10), '日本語', b'Eng',  0.,  1.)
```

# ポイント
## 空白セルの読み込み

nanになる。

## dtype

読み込むすべてのカラムに対して設定する。
整数なら'i'を使う。
小数の型を'f8'といった具合に選べる。
outputとしてdatetime型が欲しければdatetimeと書けば良い。

## converters

dtypeに型が無いデータはこちらが必要。
dtypeで格納するための前処理と考えればよい。

# Thanks for

* csv/tsvファイルの読み書き
 http://www.mwsoft.jp/programming/numpy/csv.html
Image Content Pipelineのデフォルトの出力先の変更

変更したいプロジェクトを選択->右クリック->プロパティ

![hoge.jpg](https://qiita-image-store.s3.amazonaws.com/0/167635/3e8a8ab1-e45f-2775-0b65-f2ce83a8cde0.jpeg)
Vimのプロファイル機能を使って反応の悪いプラグインを特定する

Clojureでの開発をNeoVim上で行う際、ファイルを開くのに時間がかかる場合があり、開発効率が落ちていました。その原因をVimのプロファイル機能を使って特定できたので、使い方を共有します。

## 手順

* Vimを起動し、遅い動作の手前まで作業を進める。
* 下記の3行をVimのコマンドウィンドウ内で入力する。

``` 
:profile start profile.log
:profile func *
:profile file *
```
* 遅い動作を実行する。
* 下記の2行をVimのコマンドウィンドウ内で入力する。

```
:profile pause
:noautocmd qall!
```
* カレントディレクトリ内に `profile.log` が作成されているはずなので、その内容を確認する。ファイルの末尾に概要が出力されているので、そこから遅いロジックを特定していく。

## profile.logの出力例

```
FUNCTIONS SORTED ON TOTAL TIME
count  total (s)   self (s)  function
    1   8.584595   0.000036  nerdtree#ui_glue#invokeKeyMap()
    1   8.584559   0.000131  77()
    1   8.568358   0.000042  76()
    1   8.568316   0.000028  <SNR>75_activateFileNode()
    1   8.568288   0.000047  105()
    1   8.568241   0.000034  122()
    1   8.568115   0.000017  175()
    1   8.568098   0.000055  176()
    1   8.488279   0.006735  16()
    2   8.093759   0.002042  ProjectionistDetect()
    2   7.712956   0.002847  projectionist#activate()
   40   7.418631   0.004057  projectionist#query()
   40   7.407037   2.785267  projectionist#query_raw()
   36   6.686320   0.001272  projectionist#query_exec()
    2   5.947827   0.001345  <SNR>168_query_exec_with_alternate()
48720   3.367385   2.290765  <SNR>168_match()
490400   1.252515             projectionist#lencmp()
97440   0.871693   0.602253  <SNR>168_slash()
    4   0.735650   0.000254  projectionist#query_file()
   17   0.457497   0.286622  provider#python#Call()

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
   40   7.407037   2.785267  projectionist#query_raw()
48720   3.367385   2.290765  <SNR>168_match()
490400              1.252515  projectionist#lencmp()
97440   0.871693   0.602253  <SNR>168_slash()
   17   0.457497   0.286622  provider#python#Call()
   14              0.284700  <SNR>166_nrepl_transport_dispatch()
97606              0.269994  projectionist#slash()
48720              0.202756  <SNR>168_startswith()
    1   0.170747   0.170734  provider#pythonx#Require()
    2   0.171497   0.150765  projectionist#navigation_commands()
    8              0.108033  projectionist#define_navigation_command()
    2   0.377909   0.044814  <SNR>152_projectionist_detect()
    1              0.028492  <SNR>95_DirenvExport()
  752              0.028444  <SNR>130_get_syn()
  376   0.058135   0.025600  airline#highlighter#get_highlight()
 2436              0.020623  <SNR>168_gsub()
    5   0.018016   0.017663  fireplace#ns()
   18              0.014815  <SNR>106_Highlight_Matching_Pair()
  168   0.043886   0.013509  airline#highlighter#exec()
    1   0.012891   0.012863  ctrlp#utils#writecache()
```

この場合は、`vim-projectionist`という、プロジェクトのファイル構成を分析してファイル操作を支援したり、ソースファイルとテストファイル間のジャンプを実現してくれるプラグインに時間がかかっていることがわかります。私は最近では、[ctrlp](https://github.com/kien/ctrlp.vim)というプラグインでファイル操作を主に行っているので、このプラグインをコメントアウトすることにし、動作速度の改善を図ることができました。