OmniAICreator/Qiita-1.07M huggingface dataset:
AWSにsshログインした時にスライムを出現するようにしてみた。


# やること
AWSサーバにログインした時にドラクエお馴染みスライムを出現させる。
<img width="473" alt="slime00.png" src="https://qiita-image-store.s3.amazonaws.com/0/248805/ef3e1ff7-8cd5-92de-7757-e70e0dc5d86e.png">


# なぜ試したのか
毎回AWSにsshログインした時に文字しか表示されないのはつまらないと思ったから。
あと、知り合いのサーバを勝手にスライムを出現させて驚かせたかったからという出来心...

# スライムがもたらす効果

- 本番環境と開発環境の違いを表現できる
- ドラクエがやりたくなってくる
- スライムLOVE！！！！！が止まらなくなり思考停止
- みんなの心が癒される

# スライム化計画
## スライムの調達
ドラクエのスライムや勇者達のドット絵が<a href="https://github.com/dot-motd/dragon-quest">Github</a>で公開されている。
この中から好きなスライムを選んでURLをコピーする。

<img width="494" alt="slime01.png" src="https://qiita-image-store.s3.amazonaws.com/0/248805/21073f65-e3a6-90bd-99ca-55362a3baf3e.png">


これでスライムの調達は完了！！


## AWS設定変更
AWS EC2にec2-userとしてログインする。

### 設定確認
ログインした時に表示されるお決まり文字は `/etc/motd` に定義されている。
この設定ファイルの内容を変更するとログインした時の表示内容を変更することができるが、AWSサーバを再起動すると`/etc/motd`の内容がリセットされてしまう。

```bash
[ec2-user@ip-172-000-11-222 ~]$ sudo su  # rootユーザにスイッチ
[root@ip-172-000-11-222 ec2-user]# cat /etc/motd

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
13 package(s) needed for security, out of 23 available
Run "sudo yum update" to apply all updates.
```

実はこのファイルを作成するための元ファイル（オリジナルファイル）が存在。
今回はサーバを再起動しても設定内容が変更されないようにオリジナルファイルを変更する。

### オリジナルファイルの変更
オリジナルファイルは`/etc/update-motd.d/30-banner`に存在する。
ファイルの中身を確認すると、「EC2」の文字アートと「Amazon Linux AMI」などの文字が設定されている。
この中身をスライムに置き換えることで、ログインした時にスライムを出現させることが可能である。

早速、スライムを出現させられるようにファイルを編集してみよう！

#### 変更前

```bash
[root@ip-172-000-11-222 ec2-user]# cat /etc/update-motd.d/30-banner 
#!/bin/sh
version=$(rpm -q --qf '%{version}' system-release)
cat << EOF

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/$version-release-notes/
EOF
```

#### 変更後

```bash
[root@ip-172-000-11-222 ec2-user]# cat /etc/update-motd.d/30-banner 
#!/bin/sh
version=$(rpm -q --qf '%{version}' system-release)
curl -s "https://gist.githubusercontent.com/makocchi-git/9775443/raw/02e67ad144bd9ab5b71472e46e9a553d49f413d4/slime.txt" # 調達したスライムのURLを設定する。
cat << EOF
https://aws.amazon.com/amazon-linux-ami/$version-release-notes/
EOF
```

#### スライムの確認
これでスライムが出現する条件は整った。
`30-banner`ファイルはbashで構成されているため、このファイルを実行することでスライムが出現するか確認することができる。
コマンドを入力してスライムが出現できれば成功！

```bash
[root@ip-172-000-11-222 ec2-user]# /bin/bash /etc/update-motd.d/30-banner
```

<img width="472" alt="slime02.png" src="https://qiita-image-store.s3.amazonaws.com/0/248805/a89ed2b9-51c7-d3d9-bff6-6596fe860d5e.png">

可愛らしいスライムが綺麗に表示されていますね。

しかし、これで終わりではありません。
オリジナルファイルを設定した後`/etc/motd`ファイルに変更を反映が必要です。

### 更新内容反映
オリジナルファイルを反映するのはコマンドを1回実行するだけで反映できます。
コマンドは`update-motd`です。

```bash
[root@ip-172-000-11-222 ec2-user]# update-motd
```

実行後に再度`/etc/motd`の中身を確認してみるとスライムがひょっこり出現していますね。
これで設定は完了です。ログインし直すとスライムが出現します！！


# スライムは正義！
知り合いのサーバにスライムを導入してもきっと怒られないだろう。
だって、スライム可愛いじゃん！！！

- 私は「スライムを導入してスキルアップ」
- 知り合いは「スライムを見てほっこり」

win-winの関係ってこのことかな・・・！！！！！
みなさんも良い旅を！！！
[TestCafe]テストコードを書いてみる(超初級)

TestCafeのチュートリアルサイトへアクセスしてみます。
チュートリアルの内容をほぼ流用してみます。

```
import { Selector } from 'testcafe';

fixture `Getting Started`
    // アクセスしたいURLを指定します。
    .page('http://devexpress.github.io/testcafe/example');

test('My first test', async t => {
    await t
    // アクセスできたことを確認する為、画面のタイトルを比較してみます。
    .expect(Selector('h1').withText('Example').textContent).eql('Example')

    // ちょっとだけそのままでいてもらいます、ここでは10秒待つよう指定しています。
    .wait(10000);
});
```

### OK時
上記でテストを実行すると、このような結果になると思います。
Passed と表示されているのがわかりますね。
![TutorialTest_OK.PNG](https://qiita-image-store.s3.amazonaws.com/0/277582/22a763f6-a706-cd47-281c-0ce4dc67ce54.png)


### NG時
アサーションの期待値を変更して、意図的にNGとなるようにしてみます。
すると、このようなレポートが表示されました。
![TutorialTest_NG.PNG](https://qiita-image-store.s3.amazonaws.com/0/277582/2c8b7e90-e961-2c85-9409-30f4d600c23a.png)

赤線部が実際の値、青線部は期待値となります。
エラーとなったコードの行数も明記してくれているので、確認が容易です。
先程のOK時から意図的にNGとなるよう期待値をいじっているので、この内容のエラーが正しい動作ですね。


ほんの少し、TestCafe でテストを実行してみましたが、いかがでしたか？
これは TestCafe のスタートラインからほんのちょっと片足が出てきたくらいですが、
ツールの選択肢を増やすというのもテストの幅を広げるという意味では有効かと思います。
colaboratoryでの数式(ベクトル表記)注意点

# μのベクトル表記が出来ない…？？？
`\bm{\mu}`
おや？Latexのコマンドだとこれでよかったはず…

追記(2018/12/03)：Qrunchも同様だった
 

# colaboratoryでのLaTex注意点
実は、[colaboratoryの公式説明](https://colab.research.google.com/notebooks/basic_features_overview.ipynb#scrollTo=Id6tDF1HQSHD)にはLaTexが**MathJax**によって実現されていると明記されている。

> 
## Text cells
This is a **text cell**. You can **double-click** to edit this cell. Text cells
use markdown syntax. To learn more, see our [markdown
guide](/notebooks/markdown_guide.ipynb).

> You can also add math to text cells using [LaTeX](http://www.latex-project.org/)
to be rendered by [MathJax](https://www.mathjax.org). 

### ベクトル表記にはboldsymbol

[mathjaxではbmが使えないので代わりにboldsymbolを使う](https://minus9d.hatenablog.com/entry/2014/07/24/183210)

らしい。

[MathJax で利用可能な TEX コマンド（非公式）](http://memopad.bitter.jp/web/mathjax/TeXSyntax.html) を参考にしてみる。
LXD&X2GOでVSCODE

#開発環境はLXDの上に置きたい
　Microsoftも最近はオープンソース界隈に魂を売って地獄の業火を弱めた結果か、VSCODEは使いやすくなった。しかしVSCODEをX2GOを介してLXD上で動かすとうまく動かなかった。
　しかし、この投稿の通りにやったらうまく行った。
https://github.com/Microsoft/vscode/issues/3451#issuecomment-227197582
```mkdir ~/lib
cp /usr/lib/x86_64-linux-gnu/libxcb.so.1 ~/lib
sed -i 's/BIG-REQUESTS/_IG-REQUESTS/' ~/lib/libxcb.so.1```
　これを一回すると、以下のコードでVSCODEが起動できる。
``LD_LIBRARY_PATH=$HOME/lib code``
　どうやら、libxcbというのが起動しない原因のようで、sedコマンドでこのファイルを編集するようだ。テキストファイルではないと思うのだがどうなっているのだろう......
　全体で共有されているやつを編集すると他のアプリケーションが死ぬ(自分の場合firefoxが死んだ)のでコピーしてそいつを編集し、vscode起動時にそれを使うように指定するようだ。
　起動コマンドをスクリプトファイルにしてデスクトップにおいたのでこれで使えそう。
RaspberryPi3で初めてcrontabを使う前に

#■はじめに
Raspberryでは、とりあえずでcrontabに内容を記載しても何も起こりません（でした）。初めてcrontabを利用する前に必要な設定をまとめます。

　1. rsyslogの設定
　2. cronログレベルの設定
　3. cronログの確認
　おまけ　cron内の言語設定

#■1. rsyslogの設定
システムログ制御デーモンのrsyslogのcronログ出力設定を確認します。

①/etc/rsyslog.confの設定
rsyslog.conf内のcron記載がコメントアウトされているようなら、コメントアウトを外します。

設定ファイル:　`/etc/rsyslog.conf`

```sh:/etc/rsyslog.conf(抜粋)
###############
#### RULES ####
###############

#
# First some standard log files.  Log by facility.
#
auth,authpriv.*			/var/log/auth.log
*.*;auth,authpriv.none		-/var/log/syslog
#cron.*				/var/log/cron.log
daemon.*			-/var/log/daemon.log
kern.*				-/var/log/kern.log
lpr.*				-/var/log/lpr.log
mail.*				-/var/log/mail.log
user.*				-/var/log/user.log
```
↓cronのコメントアウトを外す

```sh:/etc/rsyslog.conf(抜粋)
cron.*				/var/log/cron.log
```

②rsyslogの再起動
設定変更後に、デーモンの再起動を行います。

```
sudo /etc/init.d/rsyslog restart
```

#■2. cronログレベルの設定
①cronログレベルの設定
cronログレベルの設定です。ログレベルは設定内容の合計値で設定します。今回は「EXTRA_OPT="-L 15"」を設定します。

設定ファイル:　`/etc/default/cron`

```sh:/etc/default/cron 
# Cron configuration options

# Whether to read the system's default environment files (if present)
# If set to "yes", cron will set a proper mail charset from the
# locale information. If set to something other than 'yes', the default
# charset 'C' (canonical name: ANSI_X3.4-1968) will be used.
#
# This has no effect on tasks running under cron; their environment can
# only be changed via PAM or from within the crontab; see crontab(5).
READ_ENV="yes"

# Extra options for cron, see cron(8)
#
# For example, to enable LSB name support in /etc/cron.d/, use
# EXTRA_OPTS='-l'  
#
# Or, to log standard messages, plus jobs with exit status != 0:
# EXTRA_OPTS='-L 5'
#
# For quick reference, the currently available log levels are:
#   0   no logging (errors are logged regardless)
#   1   log start of jobs
#   2   log end of jobs
#   4   log jobs with exit status != 0
#   8   log the process identifier of child process (in all logs)
#
#EXTRA_OPTS=""
```

↓cronログレベルを設定

```sh:/etc/default/cron(抜粋) 
EXTRA_OPTS="-L 15"
```

②cronの再起動
設定変更後に、デーモンの再起動を行います。

```
sudo /etc/init.d/cron restart
```

#■3. cronログの確認
以下に設定ファイルが生成されたことを確認します。

ログファイル：　`var/log/cron.log`

```
root@raspberrypi:~# ls var/log/cron.log
```

#■おまけ　cron内の言語設定
cron内では言語設定がされていないため、cron内に日本語を利用する場合、あらかじめ言語設定を書いておく必要があります。

言語設定：　`LANG=ja_JP.UTF-8`
設定コマンド：　`crontab -u <ユーザ名> -e`
参照コマンド：　`crontab -u <ユーザ名> -l`


```sh:
root@raspberrypi:~# crontab -u pi -l

LANG=ja_JP.UTF-8
30 2 1 * * echo "日本語" >> japanese.txt
~後略～
```
※piユーザのcrontabを設定



#■出典/参考
cron の使い方
http://landisk.kororo.jp/diary/30_cron.php

cronのログを出すように設定する
http://shima-nigoro.hatenablog.jp/entry/2016/06/12/182903

cronでスクリプトを定期実行させるときに注意したい4つのこと
https://orebibou.com/2014/12/cron%E3%81%A7%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%82%92%E5%AE%9A%E6%9C%9F%E5%AE%9F%E8%A1%8C%E3%81%95%E3%81%9B%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AB%E6%B3%A8%E6%84%8F%E3%81%97%E3%81%9F/

cronで文字化けするときの対処
http://www.koikikukan.com/archives/2013/08/12-000300.php
Subgraph isomorphism (J. R. ULLMANNのアルゴリズム)

グラフ$G_\beta = (V_\beta, E_\beta)$の中に$G_\alpha = (V_\alpha, E_\alpha)$が部分グラフとして存在するかどうかを判断する問題です. $(\\#V_\alpha \geq \\#V_\beta)$
グラフ埋め込み問題とも言います.<br>

<img src="https://qiita-image-store.s3.amazonaws.com/0/154548/607d2558-a67d-3d76-2367-cea2eedbd828.png", width=600>


Subgraph isomorphismの解法として, **J. R. ULLMANNのアルゴリズム [1]** を紹介します.



## Outline
1. $G_\alpha$のノードを, $G_\beta$のノードのどれに対応づけるかを表す(写像)行列$M'$を用意する.
1. $M'$を用いて同型な埋め込みとなっているか (すなわち$G_\alpha$の枝が, 移した先の$G_\beta$でも保存されているか), チェックする条件を作成. 
1. Brute-Force Tree-Search(力任せ木探索)により, 解を探索
1. そのときに, 同型ならば"$G_\alpha$の枝が, 移した先の$G_\beta$でも保存されている"という条件を用いて, 探索時に枝刈りを行うことで, より効率よく探索を行う.


## STEP1
$p_\alpha := \\#V_\alpha, p_\beta := \\#V_\beta$ として, $p_\alpha \times p_\beta$行列$M'$を作成する.
これは$G_\alpha$のノードの$G_\beta$のノードへの対応を表すものであり, 

```math
M'_{ij} = 1 \Rightarrow G_\alpha{\rm のノード}iを, G_\betaのノードjに対応させる
```
ということを意味する. よって, 各行, 各列ともに, 1成分は1つ以下であり, 残りは0とする.

## STEP2
グラフ$G_\alpha, G_\beta$の接続行列をそれぞれ$A, B$とする.
例えば, $G_\alpha$のノード$i$と$j$が接続されているならば, $A_{ij} = 1$で, そうでないならば$A_{ij} = 0$となる.

$M'$によって決まる$G_\alpha$のノード$i, j$の移り先を, それぞれ$i_\beta, j_\beta$とすると, 

まず, 

```math
\displaystyle (M'B)_{ik} = \sum_{l=1}^{p_\beta}M'_{il}B_{lk} = B_{i_\beta k}
```

すなわち, $i_\beta$と$G_\beta$のノード$k$が接続されているならばこれは1となり, そうでないならば0となる.

また, 

```math
\displaystyle (M'(M'B)^T)_{ij} = \sum_{l=1}^{p_\beta}M'_{il}(M'B)_{jl} = (M'B)_{ji_\beta}
```

すなわち, $j_\beta$と$i_\beta$が$G_\beta$上で接続されているならば1, そうでないならば0となる.

$M'$が同型な埋め込みであれば, "$G_\alpha$上で, ノード$i$と$j$が接続されているならば、 $G_\beta$上で, ノード$i_\beta$と$j_\beta$も接続される" はずなので, $M'$が同型な埋め込みである十分条件は, $C:= M'(M'B)^T$とすると, 

```math
A_{ij} = 1 \Rightarrow C_{ij} = 1 (\forall i, j \in V_\alpha)
```

となる.

## STEP3
$G_\alpha$の各ノードを$G_\beta$のどのノードに割り当てるかを力任せに調べる. あるノードをどのノードに移すかで一階層をなすような木探索になる. $G_\alpha$の全てのノードを割り振り終わったら, STEP2の条件に当てはめて, 同型な埋め込みとなっているかを調べる.

## STEP4
STEP3の探索をより効率的に行うために, 次の**自明な**条件を加える. $M'$によって$G_\alpha$のノードが$G_\beta$に移ったとき, $G_\alpha$の枝が, 移した先の$G_\beta$でも保存されている. すなわち

もし$A_{ix} = 1$ならば, $B_{i_\beta x_\beta} = 1$となっていなければならない. (ここで, $i_\beta, x_\beta$は$M'$によって決まるノードに移り先)

よって, STEP3の探索中, $M'_{ij}$は次の条件を満たさないならば0に更新される

```math
A_{ix} = 1 \Rightarrow (\exists \,\, y \,\, s.t. M'_{xy}・B_{jy} = 1)
```


## 参考文献
[1] ULLMANN, Julian R. An algorithm for subgraph isomorphism. Journal of the ACM (JACM), 1976, 23.1: 31-42.
splitとjoinの使い分け

# splitとjoinで配列を扱う

splitは文字列を配列にするメソッド(と認識してます）
splitの引数に区切りたい対象の文字を指定することで返り値を配列にできます。

```ruby:sample.rb
array = "hoge,huge"
p array.split(",")
=> ["hoge","huge"]
```


joinは配列を文字列にするメソッド（と認識してます）
joinの引数に連結させたい文字列を渡すことで返り値を文字列にできます。

```ruby:sample.rb
array = ["hoge","huge", "haga"]
p array.join(",")
=> "hoge,huge,haga"
```

正直何に使うかよくわからんが、とりあえず覚えておく！
Swagger定義ファイルの書き方(超手抜き編)

Swagger定義ファイルは、いろいろ定義してバリデーションを厳密にできる反面、ちょっと使おうと思うと、ルールが厳しくて億劫になりがちです。

そこで、必要最低限のSwagger定義ファイルの書き方を備忘録として残しておきます。
いざ本番となるときには、SwaggerのSpecificationに従って厳密に定義してください。

(参考情報)
https://swagger.io/docs/specification/2-0/basic-structure/

# 一番簡単な定義

結論だけ示すと、一番簡単な定義は以下の通りです。
/pathsのところを参考にしてください。

```swagger.yaml
swagger: '2.0'
info:
  version: 'first version'
  title: Sample Api
host: localhost:10010
basePath: /

schemes:
  - http

consumes:
  - application/json
produces:
  - application/json

securityDefinitions:
  basicAuth:
    type: basic
  tokenAuth:
    type: apiKey
    name: Authorization
    in: header
    
paths:
  /swagger:
    x-swagger-pipe: swagger_raw

  /test_post:
    post:
      x-swagger-router-controller: echo
      operationId: test_post
      parameters:
        - in: body
          name: body
          schema:
            type: object
      responses:
        200:
          description: Success
          schema:
            type: object

  /test_get:
    get:
      x-swagger-router-controller: echo
      operationId: test_get
      parameters:
        - in: query
          name: param
          type: string
      responses:
        200:
          description: Success
          schema:
            type: object

definitions:
  Empty:
    type: "object"
    title: "Empty Schema"
```

# swagger-nodeで最短で立ち上げる

RESTful実行環境に最適なswagger-nodeを使って立ち上げます。
swagger-nodeについては、以下の記事を参考にしてください。

[SwaggerでRESTful環境を構築する](https://qiita.com/poruruba/items/72d8c85f8923bc78b918)

```
> swagger project create first_restful
※Frameworkにはexpressを選択します。

> cd first_restful
```

Swagger定義ファイルをさきほどのswagger.yamlに置き換えてください。

>置き換え対象ファイル：./api/swagger/swagger.yaml

以下のファイルを作成します。

>作成ファイル：./api/controllers/echo.js

```echo.js
'use strict';

module.exports = {
  test_post: test,
  test_get: test
};

function test(req, res) {
  console.log("calling: test");

  var event = {
    headers: req.headers,
    body: JSON.stringify(req.body),
    path: req.swagger.apiPath,
    httpMethod: req.method,
    queryStringParameters: req.query
  };

  res.json( { event: event } );
}
```

./api/controllers/hello_world.js はいらないので削除してもよいです。

Restful環境を立ち上げます。

```
> swagger project start
```

# curlでたたく

さっそく、Web APIを呼び出したく、例えば、curlを使います。

```
> curl https://localhost:10010/test_get

{“event”:{XXXXXXわらわらXX}}
```

# マイ最速

とはいいつつも、なんだかんだ言って、私は以下が最速

```
> git clone https://github.com/poruruba/swagger_template.git
> cd swagger_template
> npm install
> node app.js
```

(参考)
[SwaggerでLambdaのデバッグ環境を作る(1)](https://qiita.com/poruruba/items/e3a46787c79517a815f9)

以上。最短の記事でした。
House Price

1. データ分析の目的
まず今回のデータ分析の目的を確認します。
家を買うときに何LDKなのか、何坪なのかといったデータはもちろん不動産価格に影響するでしょう。

しかし今回はそれら以外にも多くの要因が不動産価格に影響することを確認します。
具体的には79の変数を元に、不動産価格を予測することになります。データはアメリカ合衆国アイオワ州エイムズの不動産です。

2. データセットについて
SalePriceが予測したい不動産価格で、それら以外に1階の広さや地下の天井の高さ、基礎の種類からプールの有無まで多数の特徴量が含まれています。
全部が全部不動産に影響することはないでしょうが、常識的には部屋の広さ、高さ、築年数などは大きく影響するはずです。
特徴量としては面積のように連続値のものもあれば、品質のようなカテゴリカル変数も存在しています。

ベンチマーク編では特徴量同士のデータ可視化や外れ値の処理などは行いません。
79もの特徴量があるため、いくつか重要と考えられる変数だけ抽出したとしてもそこには主観が入ってしまいます。
例えばSalePriceと1回の広さ1stFlrSFをプロットして、外れている点を削除するというのも単変量しか見ておらず、特徴量同士の相互作用を考慮できていません。

データはtrain.csvとtest.csvに分かれており、またKaggleにアップロードする際の形式としてsample_submission.csvが用意されています。
データの説明(Data_Description.txt)も用意されており、必ず読む必要があります。79変数あるのでここでは省きますが、欠損値の補完ですぐに必要になります。

3. 欠損値の補完
データセットの中身を見てみると、結構データが存在しない(NaN)レコードが多いことに気が付きます。これは本当に欠損しているのか、あるいは単純に”該当なし”という意味なのか紐解きながら補完する必要があります。
いずれかのデータが欠損しているレコードを削除してしまうというのは一つの手ですが、可能な限り手元にあるデータを生かすためまずは補完します。

4.前処理
すぐに機械学習したいところですが、カテゴリー変数の処理を行います。

カテゴリー変数の扱い方はLabel EncodingやOne Hot Encodingなど様々な方法が存在します。
今回は大したレコード数ではないことと、特徴量の数も1000すらいかないと思われるのでOne Hot Encodingでダミー変数化します。

5. 機械学習で不動産価格を予測する
ベンチマーク編なので、とりあえずラッソ回帰、ランダムフォレスト、SVRでやろうと思います。

チューニングはとりあえずざっくり辺りをつけてグリッドサーチします。
Javaのお勉強①

Javaの勉強を始めたので覚えたことなどを残しておく。
#出力する
```.java
System.out.println("Hello World!");
System.out.println(123);

//実行結果
//Hello World!
//123
```
()内を出力し、改行する。
printlnの読み方はプリントライン。
Systemやoutは何を意味してるんだろうと調べてみたけれど、今は深く突っ込まないことにした。
参考) [System.out.println("hello, world")を読み解く](https://qiita.com/pale2f/items/5d19adc954c3572ff5cb)

#変数の宣言
```.java
int number; //int型の変数numberを宣言
String str; //String型の変数strを宣言
```

#変数の初期化
```.java
int number = 5;
String str = "hoge";
```
変数の宣言と同時に値を代入する。

#変数の計算、連結
```.java
//int型変数の計算
int number1 = 3;
System.out.println(number1 + 5);   //結果は8
int number2 = 10;
System.out.println(number1 + number2);   //結果は13

//String型変数の連結
String greeting = "おはよう";
System.out.println(greeting + "ソラ");   //おはようソラ
String name = "リク";
System.out.println(greeting + name);   //おはようリク
```

#自己代入
```.java
x = x + 10;   //変数xに10を足したうえで上書きする
```
記述方法には基本形と省略形がある。

| 基本形 | 省略形 |
|:-:|:-:|
|x = x + 10|x += 10|
|x = x - 10|x -= 10|
|x = x * 10|x *= 10|
|x = x / 10|x /= 10|
|x = x % 10|x %= 10|

###1だけ足し引きする場合
更に省略形が存在する。

|基本形|省略形|更に省略|
|:-:|:-:|:-:|
|x = x + 1|x += 1|x++|
|x = x - 1|x -= 1|x--|

#double型
値を扱うデータ型の変数にはint型以外にもいくつかある。
参考) [Javaの道：変数（１．変数）](http://www.javaroad.jp/java_variable.htm)
double型は小数点以下を持つ値を扱う。

```.java
double number = 3.14;
System.out.println(number);   ///結果は3.14
```
[TestCafe]アクションとアサーションAPI 一覧

ほとんど公式にドキュメントがあるのですが、
私の私による私の為のメモとして。

自分の使用したことのあるものを、自分の理解している範囲で残します。

#ACTION

|操作|形式|備考|
|---|---|---|
|クリック|t.click( selector )||
|指定の座標へドラッグ|t.drag( Selector, dragOffsetX, dragOffsetY )|Selector(要素)をドラッグする先のX、Y座標を指定します|
|指定の要素へドラッグ|t.dragToElement( selector, destinationSelector )|Selector(要素)をドラッグする先のdestinationSelector(要素)を指定します|
|マウスオーバー|t.hover( selector )||
|文字を入力|t.typeText( selector,'文字列' )||
|キーボード操作|t.pressKey('key')||
|ファイルアップロード|t.setFilesToUpload( selector ,filepath )||



#ASSERTION
||形式|備考|
|---|---|---|
|Deep Equal|t.expect( selector ).eql('比較対象')||

### Deep Equal
今のところほぼこれしか使用していませんが、要素の出力が正しいか等で有用です。
t.expect( selector.textContent).eql('TEST')
として、出力文字列が「TEST」となることを確認したい時等に使用します。

PASSの時

```
✓ TEST になっているか
```

FAILの時

```
AssertionError: expected 'テスト' to deeply equal 'TEST'
```
こんな感じで期待値と結果をデフォルトで教えてくれるようになってます。
便利！

今後のテスト状況で他にも多様するものがあれば、随時追記していきます。
[Excel]罫線を崩さない書式変更は覚えておいてもよいかもしれない

書式設定を開いて罫線を更新すると隠れている罫線が更新されてしまう仕様を[前回](https://qiita.com/tomikiya/items/1ad69b23230d7e529987)まとめた。
この仕様、実は回避することができる。
**（回避できても実用的かはまた別の話）**

まずは問題のおさらい。

## 罫線を更新すると変更していない罫線も更新され、かつ外周のセルの罫線も更新される。
普段見えないところで行われてしまうので裏で発動した変更がセルのコピーとかで不意に現れる。
これが罫線が崩れてしまう原因であった。詳しくは「[[Excel]イラっとする罫線の挙動、その原因と対策をまとめた](https://qiita.com/tomikiya/items/1ad69b23230d7e529987)」で。

もし、発動する条件が分かれば意図的に回避できるということだ。

## 書式を開いてプレビューに線が引かれていたら危険
プレビューで、「一意に特定できる線」が表示されたら、そこはその線で再度上書きされてしまうおそれがある。
この状態が罫線を狂わせる。

以下の書式設定は、下辺の罫線「なし」を含みめて全部上書きの可能性がある。
![罫線1.png](https://qiita-image-store.s3.amazonaws.com/0/97601/0064e39c-4730-8cd5-8a06-9396bcc754ad.png)


このようなケースは当然のように発生するので、ほとんどのケースで無意識に線を崩しているということだ。

## 逆に更新されない線とは何なのか。
それはこんな線。
![罫線2.png](https://qiita-image-store.s3.amazonaws.com/0/97601/ca2f70d5-1c95-f312-b85c-7e99a4d2c7c4.png)


線が一意に特定できない場合に網掛けのような線が表示される。この線の場合は更新されることはない。
実際に更新されていないことを確認してみる。

まずは前回紹介した罫線が崩れるBadケースの再掲。
![崩れる自セル.gif](https://qiita-image-store.s3.amazonaws.com/0/97601/3fc691d8-db7c-44cf-bc4e-706416a36c52.gif)

この変更を防ぐために、ダミーのセルを作って一緒に選択してから変更すると・・・、
![罫線を壊さない工夫1.gif](https://qiita-image-store.s3.amazonaws.com/0/97601/dd703268-699a-40d3-961a-ac5006aaa8c8.gif)


右辺含み外枠がすべて網掛けの線になった。
この状態で左辺だけ更新すると右辺は二重線にならず太線を維持している。

**網掛けを意識すれば変更したい罫線だけを編集対象にできそうだ。**

## 意図的に網掛けを作る選択方法
全てを網掛けにするダミーのセルの作り方でお手軽なのがコレ↓。
![網掛けの線.png](https://qiita-image-store.s3.amazonaws.com/0/97601/27f48e80-61ef-8d62-f914-7523cc654a06.png)

書式を開くとすべての線が網掛けの線になっていることが分かる。
![罫線3.png](https://qiita-image-store.s3.amazonaws.com/0/97601/13d1f297-bb3f-34a7-00fe-da2483f17f10.png)

上のようなダミーのセルを選択しつつ本来変更したいセルも選択してから書式変更すればどんな時でも網掛けになる。

## まとめ
罫線が壊れないような操作を意識することで崩れる頻度は激減する。
ただし、毎回このやり方を実践するのは効率よくない。
さらに言えば、共有しているファイルなら第三者は問答無用で崩してくるので自分だけが意識しても無意味。
何かの初版を作る時にでも思い出せればよいかなと思う。

### 余談
書式設定が網掛けになる条件が外枠と内側で違うみたいだった。
外枠は見た目上の線がプレビューされ、内側はセルの設定上の線がプレビューされるみたいだ。ふーん。
Datumixの機械学習テクノロジーの紹介

##ワイド＆ディープラーニング
Datumixの推薦エンジンのユニークなところは顧客一人一人のニーズに合う推薦システムを作れるところです。
記事のデータがワイド＆ディープラーニングで処理される前に、Word2vec, CNN, とLSTMというメソッドを通って一つのデータの代表的な多次元ベクトルに変換されます。
入力データは記事データとユーザーデータに区別されます。この両方のデータの部分がワイド＆ディープラーニングのワイド側とディープ側に混ぜられます。ワイドラーニングは情報を記憶することに適していて、過去のデータからとても特定な推薦を返すことができます。ディープラーニングは情報をまとめて、広い範囲の情報を似ている情報として認めることができます。結果的に、過去のデータからバラエティーのある多数の推薦を返すことができます（しかし、時々間違った推薦をすることがあります）。ワイド＆ディープラーニングは文字通りワイドラーニングとディープラーニングの長所を取り入れているから、より正確な推薦を返すことが出来ます。
ワイド＆ディープラーニングの最終結果は１か０で表すことが出来ます。ワイド側とディープ側の結果が同じなら、１が出力されます。０はワイド側とディープ側の結果が異なっていたら出力されます。記事全体のデータが処理され１か０摘出されたあとにディープ側が次回からもっと正確な推薦を出せるように新しい結果を元にシステム自身を再構築します。

##Word2vec
Word2vecは言葉のセット（例えば商品の説明文）を取り込み、各単語のために多次元ベクトルを作ります。各ベクターは多次元グラフに記載されます。グラフ上のベクターの位置は過去のプログラムの研修期間に入力されたデータによって決められます。二つの単語ベクトルの間の距離が縮まるほど二つの単語は似ています。Word2vecの一番特徴的なところは似た関係を持つ単語のセットを簡単なベクター足し算と引き算で発見できる能力です。例えば、v(King)-v(Man)+v(Woman)の結果は v(Queen)です。一般的な単語の関係をシステムが理解できれば、他の単語で同じ関係を持つ言葉を探すことができます。

Word2vecは実践される前に研修期間を通る必要があります。研修期間の間はアルゴリズムはそのアルゴリズムの仕事と関連を持つ膨大な単語のデータベースを入力されます。例えば、美容サイトの推薦エンジンで使われるWord2vecは百万単位もしくは億単位を入力します。研修時によくロジスティック回帰という重要な言葉に高確率、無駄な言葉に低確率な推薦を課すテクニックが使われます。
Word2vecには Continuous Bag of Words (CBOW) と Skip-gramの二種類があります。CBOWは周りのコンテキスト単語から作られたベクトルを使ってターゲット単語を予測します。予測したい言葉の周りのある特定の範囲にある単語を取り、過去データを元に予測した単語を出力します。Skip-gramは反して、ターゲット単語からコンテキスト単語を予測します。Datumixの場合は膨大なデータを処理することに適しているSkip-gramモデルを使います。

##CNN
Convolutional Neural Network (CNN)は普段写真解析のたみに使われています。CNNは写真を数種類の層に通して一番特徴的な部分を摘出する技術です。写真解析の時にCNNはピクセルをひとつひとつベクターとして取り扱います。CNNはどんな情報でもベクターで表現できれば処理できます。つまり、CNNはWord2vecからのベクターを処理することができるのです！
CNNは主に畳み込み層、プール層と、完全接続層の三種類の層からでできています（実際のCNNでは各層が多数はいっています）。CNNは入力されたベクターを行列として扱い、各ベクターにWord2vecの結果を元に値を与えます。テキストデータは次に畳み込み層という重要な特徴をとりだすフィルタの役割を務める行列を通り抜けます。このフィルタは入力データより小さいため、徐々に入力データの行列のの部分を少し覆いながら進みます。Strideというデベロッパーが決めた値を元に動きます（１は１ピクセルごと動きます）。フィルタとフィルタによって覆われた入力データはドット積を課され、一つの数字を出力します。この数字は覆われた入力データの部分を象徴します。CNNが終わった結果は、feature map という元の行列より小さい行列を出します。
Feature mapはプール層に移され、プール層がデベロッパーの指示を特定の値を取り出します（例えば、最小値か平均値。最大値は一番正確な情報を摘出すると調査によって知られています）。この値は feature mapの代表値になり、各 feature mapの代表値は完全接続層を通ります。完全接続層は前の完全接続層の全体のニューロンに繋がっています。代表値は何層もの完全接続層を通り、処理され、一つの値として摘出されます。この値はデベロッパーによって過去にプログラムに挿入された可能な結果と比べられ、最終結果は出力された値に一番近い可能な結果となります。

##LSTM
テキストデータがWord2vecとCNNを通った後に上出来な推薦エンジンが完成したと思われるかもしれませんが、残念なことにまだこの推薦エンジンには弱点があります。Word2vecとCNNは単語しか見ないため、周りの単語の関係を解析し文全体のトーンを見出せません。つまり皮肉な商品レビューを正確に理解できないのです。この問題を解決するために、LSTM（Long-short term memory)というもうひとつのアルゴリズムが使われます。前の二つと違って、LSTMは単語の順を理解することを得意としています。その理由はLSTMは過去の言葉を記憶して次の言葉を解析できるからです。
このプロセスはLSTMがRNN（リカレントニューラルネットワーク）の一種だから可能なのです。RNNの中には過去の情報を常に循環しているループが回っており、このループのおかげで過去のデータを記憶できます。RNNの中では、LSTMは言葉の長期依存性を理解するのに適しています。鎖状の構造で、鎖全体の中にセルステイトというベルトコンベアーに似た構造が通っており、ひとつの鎖から次の鎖に情報を運びます。各鎖（セルとも呼ばれる）の中には「ゲート」というセルステイトの内容を変えることができる構造があります。このゲートの中には何個もの層がはいっており、各層には別の仕事があります。例えば、入力ゲート層はセルステイトのどの部分を更新するか決め、tanh層はセルステイトに挿入する新しい値を作ることができます。Word2vec, とCNN, LSTMが全部終了すれば、最後に入力データ全部を代表するベクターが出力されます。
swift4でRxSwiftを使用して、ViewControllerからアプリのバックグラウンド、復帰のイベントを取得する

アプリを制作していると、アニメーションとか、諸々のデータ処理ですとか……そういったロジックが沢山あると思います。
そんな中、ホームに戻る時には該当の処理を止めて、アプリに戻ってきたら処理を再開させる……とか、そういった処理をたまに実装しないといけなくなったりします。

RxSwiftを使うと、そういった処理が簡単に実装できたので備忘録もかねて。

# 実装例！

```notification.swift

import RxSwift

class HogeViewController: UIViewController {
    private let bag = DisposeBag()

    override func viewDidLoad() {
        NotificationCenter.default.rx.notification(.UIApplicationDidBecomeActive)
                                     .subscribe(
                                         onNext: { [weak self] _ in
                                             // アプリに戻ってきた時の処理！
                                         }).disposed(by: bag)

        NotificationCenter.default.rx.notification(.UIApplicationDidEnterBackground)
                                     .subscribe(
                                         onNext: { [weak self] _ in
                                             // homeボタンなどで、バックグラウンドに行った時の処理！
                                         }).disposed(by: bag)
    }
}
```

何も使用しないでいると、AppDelegeteでNotificationCenterで各画面に通知、購読の解除……等々を自力で実装しないといけないので。
便利な世の中になったもんだ:blush:
git-completion.bash利用時にエラーが出るため、HomebrewでのGitを利用するようにする

## 対象バージョン

* Mac OS Hight Sierra 10.13.6（17G65）
* git version 2.17.1 (Apple Git-112)
* git version 2.19.0
* bash-completion stable 1.3

## 現象

https://git-scm.com/doc
のPro Gitで紹介されている、git-completion.bashの設定をし、

```:bash
$ curl https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash -o ~/git-completion.bash
$ echo source '~/git-completion.bash' >> ~/.bash_profile
$ source ~/.bash_profile
```

git brでタブを押し、補完を利用しようとした所、下記エラーが発生する

```:bash
$ git brunknown option: --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config
usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
           <command> [<args>]
```

## 原因

curlで落としてきたgit-completion.bashに紐付いているgitのバージョンと
Command Line Toolsに紐付いているgitのバージョンが合っておらず、
2.18から追加されたlist-cmdsがgit-completion.bashに存在せずにエラーになっている

```
$ xcode-select -p
/Applications/Xcode-10.app/Contents/Developer
$ git version
git version 2.17.1 (Apple Git-112)
```

## 対応

Version 2.17.1用のgit-completion.bashを利用することも考えたが、
Command Line Toolsを切り替えるごとに紐付いているgitのバージョンが変わるのは安定性に掛けるため、
Homebrewでインストールしたgitを優先して利用できるようにする。

### 事前準備

現象で設定したgit completionの設定を削除する

```:bash
$ sed -i "" "/source ~\/git-completion.bash/d" ~/.bash_profile
$ rm ~/git-completion.bash
```

### Gitのインストール

HomebrewでGitをインストールする

```:bash
$ brew install git
```

そのままだとCommand Line Toolsに紐づくgitが利用されるため、パスの設定を行う。

```
$ echo export PATH='/usr/local/Cellar/git/2.14.1/bin:$PATH' >> ~/.bash_profile
$ source ~/.bash_profile
$ git version
git version 2.19.0
```

### bash-completionのインストール

HomebrewでインストールしたGitに紐づくgit-completion.bashを利用するため、
bash-completionをインストールする。

```
$ brew install bash-completion
```

パス設定を行い、補完が効くようにする。

```
$ echo '[ -f /usr/local/etc/bash_completion ] && . /usr/local/etc/bash_completion' >> ~/.bash_profile
$ source ~/.bash_profile
```

## 確認

git brでタブを押す

```
$ git branch
```

変換された

## 参考

* [.git-completion.bash producing error on macOS Sierra 10.12.6](https://apple.stackexchange.com/questions/327817/git-completion-bash-producing-error-on-macos-sierra-10-12-6)
* [Git でサブコマンドを補完しようとしたときに Unknown option: --list-cmds と表示される問題の解決法](https://qiita.com/varmil/items/9b0aeafa85975474e9b6)
* [
「Git補完をしらない」「git statusを1日100回は使う」そんなあなたに朗報【git-completionとgit-prompt】](https://qiita.com/noraworld/items/aa73932d001d0746373d)
webアクセス解析でよく使う指標

ウェブ解析でよく使われる指標をまとめた。


# web解析で押さえておくべき概念

- アクセス解析ツールの取得方法について
    - webビーコン方式
        - サイトのHTMLにJavascriptのタグを埋め込み、アクセス時にデータをサーバーに送信してログに蓄積する
    - サーバーログ方式
        - Webサーバーに蓄積されたアクセスログを解析する
    - パケットキャプチャ方式
        - Web解析のトラフィックを監視して、アクセスログを生成する


- PV(ページビュー)
    - ページを閲覧すること
    - webビーコンでは読み込みごとにアクセスが取得されるが、他の方式ではキャッシュによりWebサーバーにアクセスしないため測定できないことがある
- セッション
    - セッションは、サイトを閲覧し離脱するまでの一連アクセスの単位
    - webビーコンでは、クッキーを利用してセッションを測定する
        - デバイスによりクッキーが扱えない場合、セッションを正確に取得できない
        - ツールによって、同一セッションと判定する条件が異なる
    - 他の方式では、IPアドレスやユーザーエージェントを基に測定する
        - 環境によっては、複数のセッションが同一と判定される

- ユーザ
    - サイトに訪問した人単位
    - セッション同様に、クッキーやIPアドレスなどを基にユーザを識別する
    - Webビーコンで使用するクッキーは、ブラウザ単位で管理されるため、正確な測定はできない
    - また、クッキーは削除されたり有効期限があることで、別クッキーが発行されることに注意する必要がある
    - 仕組みの整備が必要だが、会員IDと紐づけて特定することもできる

- 離脱
    - サイト内のページに移動せず、他のサイトのページへ移動すること

- 直帰
    - セッションの一番最初でそのまま離脱すること

# 主要な指標

- PV数
- セッション数
- 平均PV数
    - セッションあたりの平均PV数
- ユニークPV数
    - １セッションで見たユニークのPV数
- ユーザ数
- 新規ユーザ数
    - 初訪問のユーザ数
- リピートユーザ数
    - 訪問したユーザのうち、過去に訪問したユーザ数
- ページ滞在時間
    - ページに滞在した時間
    - 対象とするページの閲覧開始時刻と次に閲覧したページの閲覧開始時刻とのさで求める
    - 離脱ページは次の閲覧開始時間が分からないので、滞在時間は分からない
- サイト滞在時間
    - 同一セッションで、サイトに滞在した時間
- セッション別平均滞在時間
    - セッションあたりの平均滞在時間
- ページ別平均滞在時間
    - ページごとの平均滞在時間

- 直帰率
    - セッションあたりの直帰数
- 加重直帰率
    - 直帰率×(該当ページPV/サイト全体PV)
    - 直帰率の高さとページのPVの多さを加味した指標
- 回遊数
    - セッション数-直帰数
- 離脱率
    - PVあたりの離脱PV数
- 回遊離脱率
    - 1-(該当ページ到達数/回遊数)
- 離脱改善指標
    - (離脱数-直帰数)^2/PV数
qiita不具合：見出しに"<",">"を含むとき、目次から見出しへジャンプできない。


# eee \<eee>
- これは目次からジャンプできない
- ccc
- ccc
- ccc
- ccc
- ccc
- ccc

# あああ <あああ>
- これは目次からジャンプできない
- aaa
- aaa
- aaa
- aaa
- aaa
- aaa

# いいい
- これは目次からジャンプできる
- bbb
- bbb
- bbb
- bbb
- bbb
- bbb
- bbb
東証2部最強やなという話コード篇

昨日自分のはてなブログで[「東証2部最強やなという話」](https://www.mazarimono.net/entry/2018/9/23/tse2)を書きました。この記事はTOPIX指数、東証2部指数、マザーズ指数のデータをダウンロードして加工し、各々の価格データを指数化したものと標準偏差を比べ見て、東証2部指数が最強やなみたいな記事を作りました。（決して投資を推奨するわけではありません。そうして、TOPIX,マザーズ指数に投資する方法はたくさんありますが（投資信託、ETF、先物など）、東証2部指数に投資する方法は筆者が知る限りありません。）     
     
最強やなというところで使ったグラフは以下のものでmatplotlibで書きました。     
      
![tse1.PNG](https://qiita-image-store.s3.amazonaws.com/0/85433/4ce43868-daa0-5a35-518b-20611acffb81.png)
![tse2.PNG](https://qiita-image-store.s3.amazonaws.com/0/85433/ab365c25-2cce-b9bd-e638-410973053889.png)

     
そのコードを以下では書いていきます。     
     
まず価格データに関しては、SBI証券よりダウンロードしました。TOPIX、東証2部指数に関しては2000年からのデータをcsvでできました。マザーズ指数に関しては、[算出が2003年9月12日](https://www.jpx.co.jp/markets/indices/line-up/files/fac_5_mothers.pdf)ということで、その日からのデータしかありませんでした。     
      

```python3
# ローカルにダウンロードしたCSVを4本足と出来高だけ取る。日付は文字列なのでパースする。ウィンドウズなのでencoding='cp932'を忘れない。
def get_csv(ind_name):
    df = pd.read_csv('{}.csv'.format(ind_name), parse_dates = ['日付'], index_col = '日付', 
    header=0,  encoding='cp932').sort_index()
    df = df.iloc[:, [0, 1, 2, 3, 8]].copy()
    return df

# 指数をいくつか比較するつもりなので終値だけ指数化したものを作る。（開始：100）
def price_index(df):
    df['pind'] = df['終値'] / df.iloc[0, 3] * 100
    return df

# 標準偏差を作るために前日との比率を作る。        
def add_pchg(df):
    df['pchg'] = df['終値'].pct_change()
    return df

# 標準偏差を作る。1か月分（20日）と3ヵ月分（20×3）
def add_std(df):
    df['std20'] = df['pchg'].rolling(20).std() * np.sqrt(365)
    df['std60'] = df['pchg'].rolling(60).std() * np.sqrt(365)
    return df
     
# 上のモジュールをまとめてデータを作る
def csv_to_data(ind_name, start_year='2000'):
    df = get_csv(ind_name)
    df = df[start_year:]
    df = price_index(df)
    df = add_pchg(df)
    df = add_std(df)
    return df

```

という感じで価格データを作りました。     
     
グラフのデータは以下のような感じで、まぁ簡単です。     
     
```python3
def rel_chart60(df, df2, name, name2):
    fig = plt.figure(figsize=(10,7))
    ax = plt.subplot(2,1,1, title='Price')
    ax2 = plt.subplot(2,1,2, title='STD')
    
    ax.plot(df['pind'], label='{}'.format(name))
    ax.plot(df2['pind'], label='{}'.format(name2))
    ax.legend()
    ax.grid()
    
    ax2.plot(df['std60'], label='{}'.format(name))
    ax2.plot(df2['std60'], label='{}'.format(name2))
    ax2.legend()
    ax2.grid()
    
    plt.show()
```

で実際にチャートを作る時は以下のような感じです。     
     
```python3
df = csv_to_data('tse2')
df2  csv_to_data('tpx')
rel_chart60(df, df2, 'TSE2', 'TOPIX')
```

という感じでデータを加工して、チャートを作って眺めて感想を述べたという感じです。    
     
今後は、大型株と小型株の動くタイミングが違うので、その辺をどうやってうまく見定めるかなってのを、過去データから見抜けたらなと思います。
cryptowat APIからいろんな取引所のbitcoin価格を取得する

cryptowat APIからいろんな取引所のbitcoin価格を取得するコード

```python
import requests,time
from datetime import datetime,timedelta
import pandas as pd

def get_price(before, after, periods, strExchange):
    url = 'https://api.cryptowat.ch/markets/' + strExchange + '/ohlc'
    query = {
        'before':before,
        'after':after,
        'periods':periods,
        }
    res = requests.get(url ,params=query).json()['result'][periods]
    return res

def get(url='https://api.cryptowat.ch/pairs/btcusd'):
    res = requests.get(url).json()
    return res
    
unixTime = lambda y,m,d,h: int(time.mktime(datetime(y,m,d,h).timetuple()))

list_markets=get(url='https://api.cryptowat.ch/pairs/btcusd')['result']['markets']
list_markets_cur_exhange=[]
for ret in list_markets:
    list_markets_cur_exhange.extend([ret['exchange']+r'/'+ret['pair']])

# now = datetime.now()
# print get_price(unixTime(now.year,now.month,now.day,now.hour), unixTime(now.year,now.month,now.day,now.hour), u'3600', u'bitfinex/btcusd')[0][4]


data = []
i = 0
strExchangeList = list_markets_cur_exhange
now = datetime(2018, 9, 24, 11)

y,m,d,h = now.year, now.month, now.day, 11

NewDate = now - timedelta(days=160)
strDate = NewDate.strftime('%Y/%m/%d %H:%M:%S')

y2,m2,d2,h2 = NewDate.year, NewDate.month, NewDate.day, 11
df=pd.DataFrame(columns=list_markets_cur_exhange)
for eachEchange in strExchangeList:
    ret = get_price(unixTime(y,m,d,h), unixTime(y2,m2,d2,h2), u'86400', eachEchange)
    ret=pd.DataFrame(ret, columns=['CloseTime', 'OpenPrice', 'HighPrice', 'LowPrice', 'ClosePrice', '_','Volume'])
    ret=ret.set_index('CloseTime',drop=True)
    df[eachEchange]=ret['ClosePrice']

df['utc']=0
for each in df.index:
    df.loc[each,'utc']=datetime.utcfromtimestamp(each)
df=df.set_index('utc', drop=False)
print(df)
df.to_csv('out.csv')
```
QuasarFramework v0.17 で SSR を試す


QuasarFramework v0.17 から ServerSideRendering (通称 SSR）がサポートされました。というわけで、どんな感じなのか試してみました。なお QuasarFramework は内部に Vue.js を利用しており `vue-server-renderer` にラッパー的に対応しているので基本的なノリは同じです。

## SSR の設定

SSR の設定は非常に簡単で `quasar.conf.js` に下記の一行を足すだけです。

```javascript
module.exports = function (ctx) {
  return {
  	preFetch: true
  }
}
```

あとは SSR を有効にして Quasar を起動します。

```shell
$ quasar dev -m ssr
```

これで起動した Web サーバにアクセスをして実際に HTML のソースを確認すると JavaScript でレンダリングされていたテンプレートが実 HTML として返却されているのが確認できます。

## Ajax などの非同期データ

さて、単純に SSR するだけならこれで良いのですが実際のアプリケーションはもっと複雑です。例えば Ajax を使って非同期にデータを取得してレンダリングするケースが多いと思います。今回は Qiita の API を利用した例を表示します。

```shell
$ quasar new page Posts
```

### routes.js

```javascript
const routes = [
  {
    path: '/',
    component: () => import('layouts/MyLayout.vue'),
    children: [
      { path: '', component: () => import('pages/Index.vue') },
      { path: '/posts', component: () => import('pages/Posts.vue') } // 追加
    ]
  }
]
```

### Posts.vue

`preFetch` というフックがあり、これを利用します。ここで Vuex の Action を使って Qiita API へ Ajax でデータを取得、state に保存します。あとは普通に参照しているだけです。

```html
<template>
  <q-page padding>
    <h1>Posts</h1>
    <ul>
      <li v-for="(tag, index) in tags" :key="index">
        {{tag}}
      </li>
    </ul>
  </q-page>
</template>

<script>
export default {
  preFetch ({ store, currentRoute, previousRoute, redirect, ssrContext }) {
    return store.dispatch('example/fetchTags')
  },
  computed: {
    tags () {
      // 実際は getters 経由で参照するほうが良いでしょう
      return this.$store.state.example.tags
    }
  }
}
</script>
```

以降の Vuex モジュールコードはいたって普通のコードです。

### state.js

```javascript
export default {
  tags: []
}
```

### actions.js

```javascript
import axios from 'axios'

export const fetchTags = async ({ commit }) => {
  // Promise を返す
  return axios.get('https://qiita.com/api/v2/tags').then(res => {
    res.data.forEach(tag => {
      commit('INSERT_TAG', tag)
    })
  })
}
```

### mutations.js

```javascript
export const INSERT_TAG = (state, payload) => {
  state.tags.push(payload)
}
```

動作確認をすると Qiita API の返却データを含んで HTML としてサーバから出力されているのが確認できます。この程度のものであれば非常に簡単に非同期データを含んだ SSR を作ることができました。まぁ…実際にはもっと考慮しなくては行けないところが多いので「簡単」ではないですが…。

Vue.js での SSR はこのドキュメントを読むと理解が捗ると思います。

- [Vue SSR ガイド](https://ssr.vuejs.org/ja/)
vue-apolloでAPI取得結果が変数に代入されない？


vue-apolloを使っていてAPI取得結果を変数に値を入れようとした際、
なぜか入らない！っと半日以上詰まりました。

* APIの呼び出し方が悪いのか？
* リクエストのタイミングの問題か？
* データは本当にあるの？？
* webpackの設定なのか？

等々調べまくり本当に詰まったのですが、結果はものすごくシンプルなものでした。

## 対象のクエリ

詰まったのは、以下のようなpostの総レコード件数を取得するクエリを使用したときでした。

```js:graphql.js
// postモデルのレコード数を取得
export const MAX_POST_COUNT = gql`
    query maxPostCount{
        postsConnection {
            aggregate {
                count
            }
        }
    }
`
```

query以下をAPIコンソール上でこれを実行すると以下レスポンスが返ります。

```json
{
  "data": {
    "postsConnection": {
      "aggregate": {
        "count": 20
      }
    }
  }
}
```


これをApolloで呼び出し、結果を変数に格納します。

## 変数にデータが入らないパターン

最初に書いていたのがこれです。
何度リロードしても取得できません。。

```vue
<template>
  <div>
    <h1>投稿数は{{ maxPostCount.aggregate.count }}</h1>
  </div>
</template>

<script>
  import {MAX_POST_COUNT} from "./graphql";

  export default {
    name: "PostCount",
    data: () => ({
      maxPostCount: {},
    }),
    apollo: {
      maxPostCount: MAX_POST_COUNT
      }
    }
  }
</script>

```

## 変数にデータが入るパターン

以下書き方なら投稿数が変数に格納され、無事20という値が描画されます。

```vue
<template>
  <div>
    <h1>投稿数は{{ postsConnection.aggregate.count }}</h1>
  </div>
</template>

<script>
  import {MAX_POST_COUNT} from "./graphql";

  export default {
    name: "PostCount",
    data: () => ({
      postsConnection: {},
    }),
    apollo: {
      postsConnection: MAX_POST_COUNT
    }
  }
</script>

```

## 解説

違いはAPIからの取得データを格納する**変数名**です。

「クエリは別に設定するし、変数名は分かりやすいものでよいでしょ。」と思っていたら、vue-apolloではクエリの返すスキーマ名と変数名が同じ場合のみ暗黙的に値がセットされるとのことでした。

なので、**目的のスキーマ名と変数名は合わせましょう。**

## 補足

もし、スキーマと違う変数名を使いたい場合は、updateを使えば良いそうです。
先の例だと以下はOKです。

総数の取得などの際に、変数名をpostConectionとするとわかりにくいので、こちらのほうがよいですね。

```vue
<template>
  <div>
    <h1>投稿数は{{ maxPostCount.aggregate.count }}</h1>
  </div>
</template>

<script>
  import {MAX_POST_COUNT} from "./graphql";

  export default {
    name: "PostCount",
    data: () => ({
      maxPostCount: 0,
    }),
    apollo: {
      maxPostCount: {
        query: MAX_POST_COUNT,
        update (data) {
          return data.postsConnection.aggregate.count
        }
      }
    }
  }
</script>
```


以下参考にさせて頂きました。
https://www.google.co.jp/amp/s/marketing-web.hatenablog.com/entry/vue-apollo_github%3famp=1
HTMLとjavascriptを利用してFormの内容をファイルに出力する方法

#HTMLとjavascriptを利用してFormの内容をファイルに出力する方法
##概要
業務でExcelにマクロを実装して入力した内容をファイルの出力するツールを利用することがある。
ただ、Excelのマクロに詳しくない場合はメンテナンスにコストがかかる。
HTMLとJavascriptであれば、有識者が多いため、メンテナンスコストは削減できる。
ここでは、Formの内容をファイルに出力する方法を記載する。
ただし、入力チェックは記載しない。

##プログラム

```html:ファイル出力
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>Form内容のファイル出力ツール</title>
	<h1>Form内容のファイル出力ツール</h1>
	<script>
		function dispText() {
			var text = "'" +
				document.formname.a001.value + "','" +
				document.formname.a002.value + "','" +
				document.formname.a003.value + "','" +
				document.formname.a004.value + "','" +
				document.formname.a005.value + "'";
			var blob = new Blob([text], { "type": "text/plain" });

			//IEの場合
			if (window.navigator.msSaveBlob) {
				window.navigator.msSaveBlob(blob, "outFileFromWindows.txt");
				//IE以外の場合
			} else {
				document.getElementById("createFile").href = window.URL.createObjectURL(blob);
			}
		}
	</script>
</head>
<body>
	<form name="formname" id="id_form" action="">
		<label id="001">Form1 : </label>
		<input type="text" name="a001" size="30" maxlenglabel="30" value="">
		</br>
		<label id="002">Form2 : </label>
		<input type="text" name="a002" size="30" maxlenglabel="30" value="">
		</br>
		<label id="003">Form3 : </label>
		<input type="text" name="a003" size="30" maxlenglabel="30" value="">
		</br>
		<label id="004">Form4 : </label>
		<input type="text" name="a004" size="8" maxlenglabel="8" value="">
		</br>
		<label id="005">Form5 : </label>
		<input type="text" name="a005" size="30" maxlenglabel="30" value="">
		</br>

		<a id="createFile" href="#" download="outFile.txt" value="ファイル作成" onclick="dispText()">ファイル作成</a>
	</form>
</body>
</html>
```

##実行例
左上：ブラウザでの表示結果　左下：作成したファイル　右：プログラム
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/aee21eea-d71a-3c73-7202-e196f0d56561.png)
Scipyの高速フーリエ変換のデータ数(2のべき乗か否か)と計算時間の関係について

## 初めに

　高速フーリエ変換(FFT)は通常の離散フーリエ変換(DFT)と比較して計算速度も速くて非常に便利ですが、データ数が2のべき乗個のでないと計算効率が良くないという欠点があります。<br>　Scipyのfftpackのfft場合、2のべき乗個でなくても計算はしてくれるのですが、大量のデータを計算した時に体感でもかなり速度が低下したことがわかります。<br>　ちなみに理論的にはFFTの計算量はNlogN、DFTはNの自乗の計算量になるらしいです。詳しくはwikideiaのFFTのページを参照ください。<br>　理論はともかく、今回2のべき乗のデータとそうでないデータを作成して実際に計算速度を比較してみました。<br>環境は

+ scipy version 1.0.0
+ numpy version 1.12.1
+ CPU core i5 7200U
<br>となっています。Jupyter Notebookのマジックコマンド%timeitで計算速度を計算してます。


##2のnべき乗個でない場合

```python
# -*- coding: utf-8 -*-
import numpy as np
from scipy import fftpack

data = np.random.random(2**17-2)
%timeit fftpack.fft(data)
```

2の17乗個から2個マイナスして131070個の乱数を生成しました。<br>本当はもう少し意味のあるデータのほうが良いかもしれませんが、手抜きです。

結果は<br>100 loops, best of 3: 11.5 ms per loop<br>となりました。<br>このぐらいのデータ数だと特に計算速度は問題ならないですね。

##2のnべき乗個の場合

上記のコードのデータ数だけいじります。

```python
# -*- coding: utf-8 -*-
import numpy as np
from scipy import fftpack
data = np.random.random(2**17)
%timeit fftpack.fft(data)
```
結果は<br>100 loops, best of 3: 2.7 ms per loop<br>となり、(これぐらいのデータ数では誤差の範囲ですが)かなり時間短縮されました。<br><br>しかしながら現実のデータが2のべき乗個であることはほとんどありません。その場合はデータ数が2のべき乗個になるように前後に0のデータをつけることによって、データ数を2のべき乗個になるように調節する方法があります。

```python
# -*- coding: utf-8 -*-
import numpy as np
from scipy import fftpack
data = np.random.random(2**17-2)
data_sq = np.zeros(2**17)
data_sq[1:-1] = data

%timeit fftpack.fft(data_sq)
```
今回は2のべき乗個でない配列dataを、2のべき乗個の「ゼロ」で構成された配列data_sqに代入しています。<br>data_sqに対してFFTを行った時の出力結果は<br>100 loops, best of 3: 2.69 ms per loop<br>となり、11.5 msと比較してかなり高速になっていることがわかります。<br>

## まとめ
+ SciPyのFFTPackは2のべき乗個でなくても計算してくれるが、計算速度は犠牲になる。
+ 計算速度が問題になる場合は前後に0のデータをつけると良い。
Action Cableとdeviseの併用


```ruby
module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_session_user

    def connect
      self.current_session_user = find_session_user
    end

    protected

    def find_session_user
      session_user = env['warden'].user(scope: :operator)
      return reject_unauthorized_connection unless session_user
      session_user
    end
  end
end
```

認証ユーザーのscopeが１つなら ` env['warden'].user` だけで問題ないが、
複数あるなら `scope`の指定が必要.

```ruby
 env['warden'].user(scope: :operator)
```

devise helperの `current_user` のようにChannelで参照できる
Controllerのhelperではないので、devise helperの `current_user` と競合しないため、
`current_user`と定義していても問題はない


```ruby
identified_by :current_session_user
```
CuPyのFFTを高速化する隠し機能

## 追記
CuPy v7で[planをcontext managerとして扱う機能](https://docs-cupy.chainer.org/en/v7.0.0/reference/generated/cupyx.scipy.fftpack.get_fft_plan.html#cupyx.scipy.fftpack.get_fft_plan)が追加されたので、この記事の方法よりそちらを使う方がオススメです。

## はじめに
[CuPy](https://cupy.chainer.org/)にv4からFFTが追加されました。
これにより、NumPyと同じインターフェースでcuFFTを使うことができるようになりました。
しかし、NumPyとインターフェースを揃えるために、cuFFTの性能を使い切れていない場合があります。
この記事では、CuPyの内部実装を利用することによってFFTを更に高速化する方法を紹介します。
**（注）この方法は仕様になっていない内部実装を利用するので、minor updateでも使えなくなる可能性があります。**

## 環境
CPU: Intel Core i7-8700K
GPU: GeForce GTX 1080 Ti
CUDA: 9.1
NumPy: 1.15.2 (+MKL)
CuPy: 4.4.1

長さ1024の単精度の配列を100個ずつ100回FFTしたときの速度を計測します。

計測用ソースコードは[こちら](https://gist.github.com/not522/19d555d500e33d40b4203a0ebbae7a7c)。

## NumPy
100×1024のndarrayを作って、100回FFTします。

```Python
x_cpu = numpy.random.rand(100, 1024) + 1j * numpy.random.rand(100, 1024)
x_cpu = x_cpu.astype(numpy.complex64)

with timer('numpy.fft.fft'):
    for i in range(100):
        numpy.fft.fft(x_cpu)
```
```
numpy.fft.fft: 93.943119 ms
```

## CuPy
CuPyはNumPyと同じインターフェースを持つので、基本的にnumpyをcupyに置換するだけでGPUを使うコードになります。

```Python
x_gpu = cupy.asarray(x_cpu)

with timer('cupy.fft.fft'):
    for i in range(100):
        cupy.fft.fft(x_gpu)
```
```
cupy.fft.fft: 24.476290 ms
```

すでにこの時点で4倍弱速くなっていますが、実はこのコードではcuFFTのplanを作る処理がボトルネックとなっています。
今回のように同じサイズのFFTを何回も行う場合はplanを使いまわした方が速くなります。

## cupy.cuda.cufft.Plan1d
NumPyと同じインターフェースでplanを使い回すことはできないので、CuPyの内部実装でplanを管理しているクラスを使います。

```Python
with timer('cupy.cuda.cufft.Plan1d'):
    plan = cufft.Plan1d(1024, cufft.CUFFT_C2C, 100)
    for i in range(100):
        y_gpu = plan.get_output_array(x_gpu)
        plan.fft(x_gpu, y_gpu, cufft.CUFFT_FORWARD)
```
```
cupy.cuda.cufft.Plan1d: 1.344442 ms
```

さらに1桁速くなりました。
一方で、インターフェースはいろいろ引数が増えてわかりにくくなっています。
この例はまだマシな方で、直接```Plan1d```を呼ぶと実装がかなりややこしくなることがあります。
そういう場合でも```cupy.fft```は型やサイズや軸などをよしなに調整してくれるので便利です。

## 配列の長さを変えた場合
![NumPy、CuPy、CuPy Plan1d.png](https://qiita-image-store.s3.amazonaws.com/0/251355/90a299dd-e5d7-49b6-91eb-bb2a006612b4.png)
配列の長さが短い時に高速化されています。
データが大きくなるとFFTの実行の方が時間がかかるようになって、planを作るオーバーヘッドが見えなくなります。

## まとめ
内部実装を利用して```Plan1d```を直接使ったほうが速くなる。
コードはややこしくなるし仕様になっている機能でもないので、速度をそれほど必要としないなら```cupy.fft```を使ったほうが良い。
google-translate--search-tkk: Failed to search TKK


Emacsでgoogle-translateを愛用しています。

ところが数日前から、”Failed to search TKK” というエラーを吐いて突然動かなくなりました。どうやらGoogleの仕様が変わったらしいとのことです。

今日（2018.9.24）、作者の [issuse board](https://github.com/atykhonov/google-translate/issues/52#issuecomment-423742883) に応急的な修正案が提示されていたので試してみたらバッチリ動くようになりました。あくまで応急的な対応だと思うので恒久的に機能するかどうかはわかりませんが、とりあえずやれやれです。


### Update infomation
- 2018.12.03 Version: 0.11.16 にupdateされて直りました。
- 2018.11.30 最近また再発しているのでこのおまじないを復活すると直りました。
- 2018.09.27 Version:0.11.15 にupdateされて無事解決しました。


## google-translateの設定（修正版）

````lisp
(use-package google-translate)

(defun google-translate-enja-or-jaen (&optional string)
  "Translate words in region or current position. Can also specify query with C-u"
  (interactive)
  (setq string
        (cond ((stringp string) string)
              (current-prefix-arg
               (read-string "Google Translate: "))
              ((use-region-p)
               (buffer-substring (region-beginning) (region-end)))
              (t
               (thing-at-point 'word))))
  (let* ((asciip (string-match
                  (format "\\`[%s]+\\'" "[:ascii:]’“”–")
                  string)))
    (run-at-time 0.1 nil 'deactivate-mark)
    (google-translate-translate
     (if asciip "en" "ja")
     (if asciip "ja" "en")
     string)))

(bind-key "C-t" 'google-translate-enja-or-jaen)

;; Fix error of "Failed to search TKK"
(defun google-translate--get-b-d1 ()
    ;; TKK='427110.1469889687'
  (list 427110 1469889687))
````
Cygwinインストールメモ: ssh, X window, C++, Emacs

Cygwinインストール時に選択するパッケージのメモ. 

# sshとXwindow関連

- Net
     - openssh
- X11
     - xorg-server
     - xinit
     - xorg-docs
     - xlaunch
     - font-jis-misc

※容量を気にしない場合は, Net, X11をまるごとインストールすればよい. 

これらをインストールすることで, `ssh(ログイン)`, `scp(ファイル転送)`, `X window(画面転送)`が使えるようになる. 

## X windowを使うときの注意
インストール後, `xlaunch.exe`を起動すれば, `xterm`で`ssh -Y`することで, 画面転送できるが, `xterm`は日本語に弱いので, 次のようにCygwin terminalでX windowを使えるようにしておくとよい. 

Cygwinの設定ファイル`~/.bashrc`に次を追加する. 

```bash
export DISPLAY=:0.0
```

- 参考文献
    - [Setting Up Cygwin/X](http://x.cygwin.com/docs/ug/setup.html#setup-cygwin-x-installing)
    - [Cygwinで X Windows を使う](http://keisanbutsuriya.hateblo.jp/entry/2015/01/25/221642)

## ログイン
ターミナルで
`ssh アカウント名@アドレス`
と打てば接続できる.

この状態では, ターミナル以外の画面の生成はできない. (`emacs &`などで失敗する. )
画面を転送したいときは, 次のようにする. 
`ssh -Y アカウント名@アドレス`
Yオプションをつけることで, 画面をこちらへ転送することが可能になる. 

画面の生成を手助けするソフトウェアは, 上で説明した`xlaunch`. 
このsshをする前に`xlaunch`を起動しておく必要がある. 

cygwinターミナルで`xlaunch &`と入力し, 窓が閉じるまでEnterで進めていく. (または, Windowsの検索窓から`xlaunch`を呼んでもよい. )
その後, 上記のYオプションでsshログインし, 
`xeyes &`
などと入力すれば, 画面の生成が確認できる. 

ここで失敗する場合は, 上記の設定を正しく行っていない可能性あるため要確認. 
画面の生成は便利だが, 非常に遅いため, ファイラーやテキストエディタなどは, 
`nautilus &` `emacs &`とやるよりも, ターミナル上での操作`ls` `emacs -nw`に慣れたほうがよい.  

# C++関連  

- Devel
     - gcc-core
     - gcc-g++
     - gdb
     - make

統合開発環境Netbeans, Eclipseとの連携もできる. 

- 参考文献
    - [C/C++/Fortran向けのNetBeans IDEの構成](https://netbeans.org/community/releases/73/cpp-setup-instructions_ja.html)

# Emacs
インストールパッケージは以下の通り. 

- Editors
     - `emacs` : emacs本体. 
     - `emacs-w32` : emacsをウィンドウで使いたい場合. ターミナルUserは不要. 
     - `emacs-anthy` : 日本語入力Anthyを使うためのもの. 
- Text
     - `anthy` : 日本語入力. emacsのデフォルトの日本語入力は変換がいまいち. 

Emacs上での日本語入力の変換は, `Ctrl + \`でできる. 
OSの日本語入力IMEを使いたい場合は, ターミナル上でEmacsを開くか, それ用のショートカットを作っておくとよい. 
`C:\cygwin64\bin\mintty.exe -t emacs -e bash -c "cd ~;emacs -nw"`

# その他

- コマンドをcmdでも使えるようにする
     - 環境変数`PATH`に`C:\cygwin64\bin`を追加
- （一度Cygwinを起動して設定ファイルを作ってから）ホームを変える
     - 環境変数に`HOME`を追加
- フォント変更
     - Cygwinターミナルを開いた後`Alt + Space`のOptionsから
- 右クリックにCygwinターミナルを追加する
     - `chere`インストール
     - `chere -ian -e "Bash Here(&B)" -t mintty`実行 (管理者権限必要)
- Python環境: [uv](https://github.com/astral-sh/uv)のインストール
- タブ化: Windowsターミナルのデフォルト起動をCygwinに切り替える
- topコマンドを使う
     - `procps-ng`インストール
- コマンドでパッケージインストール
     - [apt-cyg](https://github.com/transcode-open/apt-cyg)
     - zip展開後, `install apt-cyg /bin`
- gitを使う
     - `git`インストール
     - `bash-completion`インストール (入力補完)
- openコマンド
    - `alias 'open'='cygstart'`を.bashrcに追加

Cygwinターミナルでのコピペは`Ctrl + Ins`, `Shift + Ins`.
STORYBOOKの導入

これ見ればだいたい
http://top-men.hatenablog.com/entry/2018/08/01/020938

これだめ
https://www.webprofessional.jp/react-storybook-develop-beautiful-user-interfaces-with-ease/

パッケージのインストールが抜けている
```
yarn add @storybook/cli
```