OmniAICreator/Qiita-1.07M huggingface dataset:
とある条件時に、レコードを除外するやり方

# NOT EXISTS句使って除外テーブルを作成

```:sql
SELECT
*
FROM
  `xxx` `x`
  LEFT JOIN `yyy` `y`
    ON `x`.`id` = `y`.`x_id`               
WHERE
  NOT EXISTS ( 
    SELECT
      1
    FROM
      `xxx` `x2` 
    WHERE
      `x2`.`zzz` = 'hoge'
    AND
      # ここからは、突合せ
      `x`.`fuga` = `x2`.`fuga`
  );
```
さくらVPSの初期設定をカスタムスクリプトで自動化

さくらインターネットが公開しているCentOS6の場合の初期設定( https://help.sakura.ad.jp/hc/ja/articles/206208181 )を自動化するカスタムスクリプトを作りました。次のページで公開しています。

https://github.com/nnabeyang/sakura_vps_init_config

はじめはansibleを使うことも検討しましたが、環境を壊さない限り一度限りの実行であること、OSをインストールしたら自動実行するカスタムスクリプトの方がステップが少ないことから、カスタムスクリプトを選びました。
Excelでよく見かけるエラーのまとめ。

以外と曖昧なものもあったりするので、ココらへんで情報を整理。

| エラー | 読み方 | 原因 |
|:-:|:--|:--|
| ####  | シャープ  | ・セルの幅が狭いために数値が表示できない<br>・日付や時刻のセルに負の値が入力されているため表示できない<br>・「1E+05」と表示される / エラーではなく数値を指数表示したもので、<br>　「1E+05」=「100000」という意味。  |
| #NULL! | ヌル| NULL intersection<br>・セル指定の「:（コロン）」や「,（カンマ）」がない<br>・セル範囲に共通部分がない    |
|  #VALUE! | バリュー  | Wrong type VALUE<br>・不適切なデータが入っている|
| #DIV/0!  | ディバイド・パー・ゼロ  | DIVided by 0<br>・0で割り算を行った  |
| #REF!  | リファレンス  | A REFerence to a cell that does not exist<br>・セルが参照できない  |
| #NAME?  | ネーム  | Unrecognized NAME <br>・関数名やセル範囲名などの名前が正しくない  |
| #N/A  | ノー・アサイン  | Not Available value<br>・値がない  |



> 参考元：[そうだったのか!!よく見るエクセルエラーを解決！](https://www.microsoft.com/ja-jp/atlife/tips/archive/office/tips/072.aspx)
FuelPHPのORMをEASYにまとめる

# よく使うやつだけ、ぱぱっとまとめておく

## SELECT
### 入れ子
```php

$Entities = Model_XXX::find('all', array(
  'where' => array(
    array('yyy_zzz', $hoge),
  ),
));
```
### メソッドチェーン(こっちの方が見やすくて推奨)
```php

// １レコード取得時
$Entity = Model_XXX::query()
  ->where('aaa_bbb', '=', $hoge)
  ->where('xxx_zzz', '=', 0)
  ->get_one();

// 複数レコード取得時
$Entities = Model_XXX::query()
  ->where('aaa_bbb', '=', $hoge)
  ->get();
```
## JOIN
Modelクラスで
リレーションを定義すれば、JOINできる($_has_manyや$_belongs_toなど)

```php

$Entity = Model_XXX::query()
  ->related('Modelのプロパティ')
  ->get();
```

## INSERT
```php

$data['hoge'] = $this->hoge;
$data['huga'] = $target['foo'];
// インスタンスの作成
$entity = Model_XXX::forge ( $data );
// INSERT実行
$entity->save();
```
## UPDATE
```php

$entity = Model_xxx::query()
  ->where('hoge', '=', $target['fuga'])->get_one();
$entity->foo = 'bar';
$entity->save();
```
## DELETE
```php

// 1レコード取得後削除
Model_yyy::query()
  ->where('hoge', '=', $hogehoge)
  ->where('fuga', '=', $fugafuga)
  ->get_one()
  ->delete();

// 複数レコード取得
$entities = Model_xxx::query()
  ->where('foo', '=', $foofoo)
  ->where('bar', '=', $barbar')
  ->get();
// 件数分、削除
foreach($entities as $entity) {
  $entity->delete();
}
```

## ログ出力(おまけ)
直前の発行されたクエリを取得できる

```php

\Log::debug(DB::last_query());
```
ビットコインの現在価格を表示する

[coincheck](https://coincheck.com/ja/documents/exchange/api) の公開APIがめちゃくちゃ使い勝手がよかった。

```python
import urllib.request
import json

with urllib.request.urlopen('http://coincheck.com/api/ticker') as response:
   res = response.read()
   d = json.loads(res.decode('utf-8'))
   print(d['last'])
```

Python は細部に渡ってきちんとしているところが気持ち良い。最高。
ExcelでTRIM関数が効かない場合の対処

## Excel関数のTRIM()が効かない！
【事象】
・WebからデータをコピーしてExcelに貼り付けると、見えない空白が存在する
　→文字列比較しても正しい結果が得られなかったりする
【原因】
・Webからデータを取得すると、見えない空白(スペース、ブランク)が存在するため
・見えない空白の正体は文字コード160、HTMLでよく利用されるNBSP(ノーブレークスペース)
【対処】
・大量にあるならVBAを使うのも1つ。

```vbnet:sample
Function Nbsp2Sp(str As String) As String
    Dim nbsp(0 To 1) As Byte
    nbsp(0) = 160
    nbsp(1) = 0
    NBSP2SP = Replace(str, nbsp, " ")
End Function
```

・関数だけでよければ、下記のように記述すれば良い。

```
=TRIM(CLEAN(SUBSTITUTE(D4[対象セル],CHAR(160)," ")))
```
Google Cloud PlatformのPub/SubからDataflow経由でBigQueryにデータを流す。

#初めに
##何故、Google Cloud PlatformのIoT Coreを使用するか。
自宅でセンシングしたデータをサーバレスでWEBから表示出来るようにしたかったため。
##何故、GoogleCloudPlatformか。
Google Cloud Next Tokyo'17に参加して興味を持ったため。

##目標
Pub/Subでメッセージを公開して、Dataflow経由でBigQueryにデータを入れるところまでやってみます。

#前提
2017年11月時点の情報です。



#使用するまでの手順
##1.BigQueryを有効にしデータセットを作成する
GCPのコンソールでビッグデータのBigQueryを選択する。プロジェクト名の右にある▼を押して、データセットを作成する。
入力内容は以下の通り。

| フィールド |入力内容 |
|:-:|:-:|
| Dataset ID   | (適当なID)  |
| Data location   | US |
|  Data expiration | Never |

##2.データセット内にテーブルを作成する
先ほど作成したデータセットの右にある＋を押します。
入力内容は以下の通り。

| フィールド | 入力内容| 
|:-----:|:-----:|
| Source Data | Create Source Table  |
| Destination Table  | |
|   Table name|  (適当なテーブル名) |
|   Table type	 |  Native table |
| Schema | (スキーマは後述) | 
| Options | |
| Partitioning| None|

スキーマは以下の通り。入力したらAdd Fieldを押してください。

| Name| Type | Mode |
|:-----:|:-----:|:-----:|
| TEST_MESSAGE | STRING | NULLABLE |

最後にCreate Tableボタンを押します。

##3.バケットを作成する
GCPのコンソールでストレージのStrageを選択し、バケットを作成します。APIを有効化するか問われたら有効化します。
一時的に使用する領域になります。入力内容は以下の通り。

| フィールド | 入力内容| 
|:-----:|:-----:|
| 名前 | (適当なバケット名) |
|   デフォルトのストレージ クラス|  Regional |
|  Regional のロケーション	 |  us-central1 |

最後に作成を押します。

##4.Dataflowを有効にする
GCPのコンソールでビッグデータのDataflowを選択し、テンプレートからジョブの作成を押します。APIを有効化するか問われたら有効化します。



##5.ジョブを作成する
次に、ジョブを作成します。テンプレートからジョブを作成を押して以下の通り入力します。

| フィールド | 入力内容| 
|:-----:|:-----:|
| ジョブ名 | (適当なジョブ名) |
|   Table name|  (適当なテーブル名) |
|   Cloud Dataflow リージョン エンドポイント	 |  us-central1 |
| Cloud Dataflow テンプレート | PubSub to BigQuery | 
| パラメータ | |
| Cloud Pub/Sub input topic| projects/(プロジェクトID)/topics/(Pub/SubのトピックID)|
|BigQuery output table| (プロジェクトID):(データセットID).(テーブル名)|
| 一時的なロケーション| gs://(先ほど作成したバケット名)/temp|

最後にジョブの実行を押します。

##6.メッセージを公開してBigQueryにデータが入っているか確認する
Pub/Subコンソールのトピックに移動し、メッセージの公開を押します。。

メッセージに以下の通り入れて公開を押します。

```json
{"TEST_MESSAGE":"これはメッセージです。"}
```

BigQueryのコンソールに移動し、SELECT *なQueryを発行するとデータが入っていることが確認できます。
![WS000022.JPG](https://qiita-image-store.s3.amazonaws.com/0/168941/1dbe8fe4-b1e2-d379-5ac0-8515c85e7be3.jpeg)



#終わりに
Dataflowにテンプレートが用意されていたので簡単にPub/SubからBigQueryへデータを流し込むことができました。また、WEBコンソールだけで実装できるのは楽でいいですね。
数値型や日付型等への型変換をどこで実施するのかが気になるところです。
次回はBigQueryに入れたデータをDataStudioで見たいと思います。

#参考にしたサイト

[GCP公式 Google提供のテンプレート](https://cloud.google.com/dataflow/docs/templates/provided-templates)
【質問】全文検索ソフト「FESS」のdiskについて

全文検索ソフト「FESS」を使ってみようとしているのですが今手詰まりになっています。
どなたかお力添えいただければ幸いです。

今使っているFESSのversionは11.3です。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/215824/c830a6fc-cd7a-c2ce-4415-56b3dfdd1ef1.png)

現在はファイル認証とファイルクロールを使って大体2TBぐらいのファイルサーバをクロール対象にしています。

何回かクロール処理を行ったのですが，その度に上の画像の「disk」という項目の使用容量が増えていき
今では容量使用率が90％を超えています。
この項目に空きがないと次のクロール処理はできず，失敗してしまう状況です。

FESSのメニューを見てもこの容量を増やしたり減らしたりする方法が見当たりませんでした。

この「disk」という項目の使用容量を減らす方法、また総容量を増やす方法があればご教授いただきたいです。
ご存じの方がいらっしゃれば宜しくお願い致します。
Numpy > [2,7]から[[2,2,2],[7,7,7]]を作る > np.repeat(cf, 3, axis=0).reshape(2,3)

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

### Error


```test_shape_171123.py
import numpy as np

xc = np.array([[3,1,4],[1,5,9]])
cf = np.array([2,7])

print(xc/cf)
```

```txt:run
$ python3 test_shape_171123.py 
Traceback (most recent call last):
  File "test_shape_171123.py", line 6, in <module>
    print(xc/cf)
ValueError: operands could not be broadcast together with shapes (2,3) (2,) 
```

今日は２０回くらい怒られている。

`[2,7]`から`[[2,2,2],[7,7,7]]`を作る必要があるようだ。

### code

```test_shape_171123.py
import numpy as np

xc = np.array([[3,1,4],[1,5,9]])
cf = np.array([2,7])

print(xc)

print('--case1:')
cf1 = np.tile(cf, (1,3)).reshape(2,3)
print(cf1)

print('--case2:')
cf2 = np.tile(cf, (3,1)).reshape(2,3)
print(cf2)
#print(xc/cf)

print('--case3:')
#cf3 = np.repeat(cf, 3, axis=0).reshape(2,3)
cf3 = np.repeat(cf, len(xc[0]), axis=0).reshape(len(xc),len(xc[0]))
print(cf3)

print('--xc/cf3')
print(xc/cf3)

```

```txt:run
$ python3 test_shape_171123.py 
[[3 1 4]
 [1 5 9]]
--case1:
[[2 7 2]
 [7 2 7]]
--case2:
[[2 7 2]
 [7 2 7]]
--case3:
[[2 2 2]
 [7 7 7]]
--xc/cf3
[[ 1.5         0.5         2.        ]
 [ 0.14285714  0.71428571  1.28571429]]
```

case3で実現できた。

circumcenterSphTri()完成。
中規模のSwaggerファイルをいい感じに管理するために薄いフレームワーク作った - swglow


## 今回の成果物
### Swaglow
https://github.com/chuross/swaglow

## 特長
特定のルールに基づいたディレクトリ階層から、SwaggerのYamlファイルを結合して出力する。

* SwaggerのYaml運用に**最低限**の秩序をもたらす
	* フレームワークが生成したディレクトリに沿ってファイルを追加していくので、ファイル管理をルール化しやすい
* ディレクトリ階層や名前から`paths`や`definitions`の定義を自動生成
	* 最終的なYamlがどう生成されるのか意識する必要は無い
	* Yamlファイルを個別に管理していくことに集中できる

## 経緯
Swaggerで扱うYaml(or Json)は最終的には1つのファイルとして扱わないといけないが、何も考えずにそれに乗っかるとファイルが肥大化して管理しづらくなる。

そのためYamlを分割して結合するのが良く、npmにも既にそれを実現するライブラリも豊富にある。しかし、そのどれもが`$ref`を使う方式で、これだとファイルをどの単位で分割するかのルールが無いので、もうちょっと仕組み的に縛りたかった。

## 導入

1. `$ npm install -g swaglow`

## 使い方
### 初期化
まずはプロジェクトのルートディレクトリでinitコマンドを実行

`$ swaglow init -o [output path]`

するとこのようなディレクトリが出力先に生成される

```
swaglow root // -oで指定したパスのルート
- swaglow.json // 専用のコンフィグファイル
- paths // APIのエンドポイントを管理するディレクトリ
- definitions // モデルを管理するディレクトリ
- parameters // APIリクエストで使う共通のパラメータを管理するディレクトリ
```

### 開発
簡単な例としてREADME.mdにある内容をリンク貼っとく
[GitHub - chuross/swaglow: simple swagger framework](https://github.com/chuross/swaglow#example)

より実践的な例だと、このライブラリを使ってQiita API用のSwaggerを作るリポジトリを用意したのでそちらを確認してほしい

swagger-toolsなどを用いて出力したyamlをvalidateしたりiOS Clientにビルドする仕組みを入れてCIで回すようにしている

[GitHub - chuross/qiita-swagger-yaml: swagger yaml file for Qiita](https://github.com/chuross/qiita-swagger-yaml)


### ビルド
`$ swaglow build -o [output path]`

出力先に結合されたSwagger Yamlファイルが生成される

## ライセンス
MIT

## あとがき
今回紹介したように手運用でSwaggerのYamlを生成するのは基本的にはオススメしない。

* 追従しないとサーバー側の実装と乖離する可能性がある(メンテコストの増加)
* Swagger Yaml職人が出る可能性がある(属人化)
	* チーム全体で管理していく仕組み作りなどが必要になる

そういった意味では自社開発のAPIにリクエストを投げる場合であればメンテの効率を上げるためにサーバー側で書かれたコードから自動生成させるのが良いだろう。

では手運用は果たして意味が無いのかと言うと状況によってはそんなこともない。

例えばこのようなケースには使えると思われる

* プロジェクトがスタートした直後でサーバー側の準備ができていない場合
	* モックサーバーとして活用する
	* 本格的な運用はサーバー側ができたらそっちでやるのが良さそう
* 別会社・別チームのプロダクトなどそもそもSwaggerの連携が難しい場合

このような感じでケース・バイ・ケースだと思うので、もし何らかの理由で手運用の管理が必要になった場合はこのフレームワークを使うと良いかもしれない。
Node.js express メモ Memo

**Node.js and Express (+nodemon)**

```
$ mkdir express-server
```

```
$ cd express-server/
```

```
$ yarn init -y
```

```
$ yarn add express
```

```
$ yarn install
```
create a **server.js** file and copy and paste↓

from this website
http://expressjs.com/en/starter/hello-world.html

```server.js
const express = require('express')
const app = express()

app.get('/', (req, res) => {
res.send('Hello World!');
});

app.listen(3000, () =>
console.log('Example app listening on port 3000!'));
```




```
$ yarn add nodemon --env
```

```
$ node server.js
```

command + T　　⇨　with running server,

```
$ curl localhost:3000

Hello World!
```

Go to http://localhost:3000/ 

It should show...
Hello World!

---

post & get
Edit like this

```server.js
const express = require('express')
const app = express()

app.get('/', (req, res) => {
    res.send('This is a GET\n');
});

app.post('/', (req, res) => {
    res.send('This is a POST\n');
});

app.listen(3000, () =>
console.log('Example app listening on port 3000!'));
```

Then run

```
$ curl -X POST localhost:3000
This is a POST
```

And open it in browse http://localhost:3000/
It should show ⇨　This is a GET
TDM-GCC-64でlibiconvを使う


C言語で文字コード変換したいと思った。
iconvが定番らしい。あるものは使おう。

## 入手
https://www.gnu.org/software/libiconv/ からダウンロードする。
2017/11/23現在の最新版は「libiconv-1.15.tar.gz」。

## インストール
```
$ which gcc
/c/TDM-GCC-64/bin/gcc
$ ./configure prefix=/c/TDM-GCC-64 --enable-static --disable-shared
$ make
$ make install
```

参考: <a href="http://up-cat.net/%BA%A3%B9%B9MinGW+2009.06(7)+iconv,libxml2.html">猫科研究所 - 今更MinGW 2009.06(7) iconv,libxml2</a>

## 使ってみる
<a href="https://ja.wikipedia.org/wiki/Iconv#.E8.87.AA.E4.BD.9C.E3.83.97.E3.83.AD.E3.82.B0.E3.83.A9.E3.83.A0.E3.81.8B.E3.82.89iconv.E3.83.A9.E3.82.A4.E3.83.96.E3.83.A9.E3.83.AA.E3.82.92.E4.BD.BF.E7.94.A8.E3.81.97.E5.A4.89.E6.8F.9B.E3.81.99.E3.82.8B.E5.A0.B4.E5.90.88">iconv - Wikipedia</a>のサンプルコードを使ってみた。

```
$ gcc main.c -liconv
$ cat sjis.txt # SJISは文字化けする
▒▒▒▒▒▒▒▒▒▒
$ ./a.exe      # SJIS→UTF8変換
$ cat utf8.txt # UTF8は表示できる
あいうえお
```

たしかに変わった。
DS-Lite(RFC6333) for systemd

**2018/01/25追記：現在のところ、何らかの理由でシェルスクリプト内のipコマンドが「systemdから呼ばれた場合に限って」正しく動きません。サービスファイルかスクリプトそのものか、どちらかに修正が必要ですが今の私にはわからないままです。**

お待たせしました、systemdなLinux向けのDS-Lite systemd-unit記事です。

# トンネル掘りスクリプト

シェルスクリプトはおなじみ[てくろぐ](http://techlog.iij.ad.jp/contents/dslite-raspi)さんとこのスクリプトにいくらか手を入れたものを使います。
ルータではないマシンが自力でトンネルを使って（LANにIPv4パケットを投げずに）IPv4オンリーなウェブサイトを利用する想定なので、ルータにしたい人は[てくろぐ記事](http://techlog.iij.ad.jp/contents/dslite-raspi)と見比べながら不足を補ってください。

```bash:setup-dslite.sh
#!/bin/sh

NIC=NGNに接続したNICのデバイスネーム
REMOTE=`お使いのDNSコマンドで目指すAFTRを引いて、アドレスのみを抽出するワンライナー`
LOCAL=`ip addr show $NIC　| grep 'mngtmpaddr' | awk '{print $2}' | awk -F/ '{print $1}'`

modprobe ip6_tunnel

ip -6 tunnel add dslite0 mode ip4ip6 remote $REMOTE local $LOCAL dev $NIC
ip link set dev dslite0 mtu 1500 up

sysctl -w net.ipv4.conf.$NIC.forwarding=1

ip route del default
ip route add default dev dslite0
```

```bash:destroy-dslite.sh
ip route del default
ip tunnel del dslite0
```

スクリプト内に紛れている日本語部を適宜各自の環境に合わせたものに書き換えてご利用ください。
なお、デバイスネームをdslite0としていますが、どうも名前は重複していなければ何でも受け入れてくれるみたいです。これでは生理的にダメな方はてくろぐ記事と同じようにip6tnl1としておけば普通の名前になります。

REMOTEアドレスに関しては、念のためちゃんと名前解決してから使うようにしてあります。例えば`dig(1)`や`drill(1)`が使える方がgw.transix.jpを目指すとすると（transixの場合はクエリに答えてくれるサーバが限られる点に留意の上）、`dig gw.transix.jp AAAA +short | sed -n '1p'`といった感じで。`systemd-resolved(8)`をお使いの方であれば`systemd-resolve --type=AAAA gw.transix.jp | grep AAAA | awk '{print $4}' | sed -n '1p' `などとするとよいかと思います。

本当は、得られた複数のクエリ結果から一つを抽出する段でどれを抽出するかをランダムにできるとより良さそうですが、シェルスクリプトがド素人の私には一目でそれとわかるような書き方が全く分からず、とりま改行区切りで得られた結果からsedで先頭行を抽出した格好です。

# systemdユニットファイル

それから、systemdのユニットファイルはこんな感じになります。

```systemd.unit:ds-lite.service
[Unit]
Description=RFC6333 4in6 tunnel
After=network-online.target

[Service]
ExecStart=/（スクリプトを置いた場所）/setup-dslite.sh
ExecStop=/（上に同じ）/destroy-dslite.sh
Type=oneshot
User=root

[Install]
WantedBy=multi-user.target
```

Descriptionはお好みの説明書きを入れるとジャーナルに「今～を走らせたよ」って出てくるものなので、ジャーナルが見づらくならない程度の長さで書きましょう。

このユニットファイルを`/etc/systemd/system`に置いて、`# systemctl enable ds-lite.service`すれば次回起動時から自動で掘ってもらえるようになります。
スクリプトに実行権限を与え忘れドボンするケースに気を付けましょう。

こうして、うちではメインマシンからIPv4パケットが出なくなりました。
あと手元の対応機ではMac(Sierra)が残りなんですが、一見開通したようでブラウザ以外のソフトウェアではうまくつながらなくなってしまうという症状によりいったん諦めてます。High Sierraにしたらもう一回挑戦しようかな。

あ、Gentooもありました……Gentooは、DS-Liteのためのカーネルコンフィグがよくわからずにいます。CONFIG_IPV6_TUNNELを有効にしてありはするのですが、どうもそれだけでは不足な模様。

ではでは。

# 参考文献
http://techlog.iij.ad.jp/contents/dslite-raspi
http://shellscript.sunone.me/filter_sed.html#特定の行のみを表示する
systemd.unit(5)のmanpage
MATLAB: dot(x1, x2, 2) > dot product > Numpy: 実装 v0.1, v0.2 > 一次元と二次元は確認

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

### MATLAB

参考: https://jp.mathworks.com/help/matlab/ref/dot.html

```matlab
K>> x1 = [ 3 1 4; 1 5 9 ];
K>> x2 = [ 2 6 5; 3 5 8 ];
K>> res = dot(x1, x2, 2)

res =

    32
   100
```

### Numpy 実装 v0.1

参考: https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.dot.html

上記をNumpy実装してみた。

```test_dotproduct_171123.py
import numpy as np

# on Python 3.5.2


def calc_dotProduct_2d(x1, x2):
    ndim = len(x1)
    res = []
    for idx in range(ndim):
        res += [np.dot(x1[idx], x2[idx])]
    return res


x1 = [[3, 1, 4], [1, 5, 9]]
x2 = [[2, 6, 5], [3, 5, 8]]

res = calc_dotProduct_2d(x1, x2)
print(res)

```

```txt:run
$ python3 test_dotproduct_171123.py 
[32, 100]
```

３次元でも使えるかもしれないが、今は試さない。
１次元ではMATLABと答えが異なる。MATLABと合わせるにはnp.sum()が必要になる。


### Numpy 実装 v0.2

１次元対応した。

```test_dotproduct_171123.py
import numpy as np

# on Python 3.5.2


def calc_dotProduct(x1, x2):
    ndim = x1.ndim
    if ndim == 1:
        return np.sum(np.dot(x1, x2))

    res = []
    for idx in range(ndim):
        res += [np.dot(x1[idx], x2[idx])]
    return np.array(res)


def test_dotProduct_1d():
    x1 = np.array([3, 1, 4])
    x2 = np.array([2, 6, 5])
    res = calc_dotProduct(x1, x2)
    print(res)


def test_dotProduct_2d():
    x1 = np.array([[3, 1, 4], [1, 5, 9]])
    x2 = np.array([[2, 6, 5], [3, 5, 8]])
    res = calc_dotProduct(x1, x2)
    print(res)


test_dotProduct_1d()
test_dotProduct_2d()
```

```txt:run
$ python3 test_dotproduct_171123.py 
32
[ 32 100]
```
Xcodeのバージョンが古くて最新OSでデバッグできません？


Swift愛好会のアドベントカレンダー2日目担当の @toshi0383 です。
小ネタを投下します！

# An error was encountered while enabling development on this device

使っているXcodeよりもOSが先に新しくなってしまって、こういうエラーが出ることがあります。
![Screen Shot 2017-11-22 at 11.40.04.png](https://qiita-image-store.s3.amazonaws.com/0/35008/61d319c9-4733-0467-3734-054bc432d308.png "Screen Shot 2017-11-22 at 11.40.04.png")

デバイス再起動してとか書いてありますが、単純にXcodeが古くてOSのサポートファイルがないために起きることが多いです。
以下のようにDeviceSupportのディレクトリを見てみると、Xcode9.1には11.1のイメージがありますが、Xcode9.0.1にはないことがわかります。
![Screen Shot 2017-11-22 at 11.40.36.png](https://qiita-image-store.s3.amazonaws.com/0/35008/057f3c58-9580-14d9-1c89-8e87d7c7d91b.png "Screen Shot 2017-11-22 at 11.40.36.png")

新しいXcodeをダウンロードしてもいいですが、最近になってもまだちょっとバージョンを上げるとSwiftの互換性がなくなったりするので、単純に11.1のフォルダごとコピーして同じ状態にしてあげましょう。
Xcodeを再起動すると設定が読み込まれて上のエラーが出なくなると思います。

# DeviceSupportってどこよ
ただこのDeviceSupportは結構深いところにあるので、探すのが面倒です。
毎回消耗していたので、以下のスクリプトを書きました。
https://github.com/toshi0383/scripts/blob/master/xcode/open-device-support-dir.sh

これを使うと、コマンド一発でインストールされているXcodeそれぞれのDeviceSupportを探して、上記のようにFinder窓をパパッと表示してくれます。

# cmdshelfで管理

[cmdshelf](https://github.com/toshi0383/cmdshelf)で管理していると、スクリプトの更新もすぐに反映することができて便利ですね。

```
$ cmdshelf remote add toshi0383-scripts git@github.com:toshi0383/scripts.git
$ cmdshelf run xcode/open-device-support-dir.sh tvOS
```

コマンド名の一部しか思い出せないときも`cmdshelf list`からgrepできます。

```
$ cmdshelf list | grep device
    xcode/open-device-support-dir.sh
```

私もさっき思い出せなくて「あーそれそれ。」という感じでした。

自分が何を実行しているのか気になる人は`cmdshelf cat`しましょう。

```
$ cmdshelf cat xcode/open-device-support-dir.sh | head
#!/bin/bash
OS=${1:-'[a-z]'}
for xcode in `ls -d /Applications/Xcode*.app`
do
    case $OS in
    i[oO][sS])
        dirs="$dirs ${xcode}/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport"
        ;;
    tv[oO][sS])
        dirs="$dirs ${xcode}/Contents/Developer/Platforms/AppleTVOS.platform/DeviceSupport"
```

# まとめ

https://github.com/toshi0383/cmdshelf

明日はSwift愛好会のUI番長 @fumiyasac@github が何か書くそうです。
楽しみです！
WordPressから画像を取得してTwitterへ投稿するBotを作る :制作方針編


他大のサークルのTwitterアカウントで制作物を写真で投稿しているので、やれるのならうちでもやろうということに

フリーのBotでやろうにも画像を投稿してからそのリンクをコピペしてBotに登録するとかいう七面倒なことはしとうない。出来ることならランダムに画像を引っ張ってきて投稿できるとよい。

## 制作方針
- 使用言語はPHP
- 引継ぎ時にプログラミングに詳しくない人でもわかりやすいように書く
- 仮想環境で動作確認後、実環境で試す
- 自動化はXserverで可能

一応環境はWordPress最新環境を前提としているのでPHP最新Verでいきましょう。
Twitterへ投稿するAPIは"twitterOAuth"の予定


基本的に画像に関連付けられたタグで投稿する画像を判別したいところ
3月を目途に制作を開始していきます。
小さい組織の俺達はJumpCloudからはじめてアカウント・システム管理をかなり楽にしよう

俺です。

只今社内のIdP整えてます。
現在アカウント管理は[すだちの人](https://www.cloudnative.co.jp/)に教えてもらった
[JumpCloud](https://jumpcloud.com)で運用しています。

[弊社](http://www.andgate.co.jp)ではMac/Winが半々ですが、以下の内容を統一し、オペレーションをJumpCloudでカバーしています。
- 社員PCのログインIDとパスワード, sudoの許可
- サーバへのログイン許可, 公開鍵
- スクリーンロック(180秒)
- G Suiteへのシングルサインオン
- PCログイン時にMFA認証
今のところADでガッチガチにするパワーはないけど、ユーザーとPCの管理をカジュアルにSaaSでまかないたいってフェーズには非常に便利かなと考えてます。
さらに10人まで無料という起業直後の俺には最高に嬉しいネ申SaaSです.Kami as a Service
11人目以降は$7.50/monthですが、まあ提供されてる機能を実際使ってみるとどーかんがえても安いよねと感じるでしょう！
早く人増やしてJumpCloudに課金して利用貢献したいのでお前の会社is気になるって思った方はとりあえずinfo@andgate.co.jpにメール下さいmm職種はなんでもいいのでめしいきましょうｗｗ


さて、

# 何ができるのか

- ユーザー登録, システム(PC)ごとにsudo許可, 公開鍵登録, MFAデバイス認証の有効/無効
- ユーザーのグルーピング
- JumpCloudAgentをインストールし、PCへのログイン制御が可能
- PCのグルーピング
- 簡易ポリシー設定.スクリーンロック, USBデバイスのブロック
- G Suiteやo365にJumpCloudユーザーのパスワードを同期
- 登録済みのシステムへシェルコマンドを発行

カジュアルに痒いところに手が届きます。

## ユーザー管理画面

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42755/0f6b76f8-c7bc-453d-a33f-e47aa69de783.png)

## システム管理画面

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42755/e19d62a7-6599-0ba5-05e5-428f68421527.png)

ログイン可能なユーザー
![image.png](https://qiita-image-store.s3.amazonaws.com/0/42755/9936e1f3-85c0-23ef-4a3f-51ab160e0322.png)

ポリシー設定
![image.png](https://qiita-image-store.s3.amazonaws.com/0/42755/081731eb-fec4-c6a4-3d53-53bd629dd945.png)

## ポリシー

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42755/d755f1dd-b69a-cf57-d488-6d4c0b6b659c.png)

## グループ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42755/be8375d9-6e9d-67df-68ea-85ff0083dd63.png)

## Applications

SSOも設定できるよ。ただSaaSのSAML対応プランはEnterpriseがほとんどでつらい。
https://jumpcloud.com/daas-product/sso-single-sign-on

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42755/bccc6d4b-f575-d3c9-19f6-f08b70bf63a6.png)

## Directories

ディレクトリサービス連携ができるよ
ActiveDirectoryの情報を、JumpCloudへsyncしたり、G SuiteアカウントのユーザーID/パスワードをJumpCloudユーザーID/パスワードと同期できる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42755/f1fbc100-b624-15af-55b0-ec97d047195d.png)

## Commands

JumpCloudに登録しているシステムへシェルコマンドを発行することができます。
対応OSはWindows/Linux/Macです。地味に便利

![image.png](https://qiita-image-store.s3.amazonaws.com/0/42755/295c64f6-630b-b7ec-cd96-c838b1781c7e.png)

# 利用例

## 入社

- PC購入
- PCにJumpCloud Agentをインストール
- G Suiteに社員アカウント登録してパスワード(A)設定
- JumpCloudに社員アカウント登録
- JumpCloud側で社員アカウントのパスワード(B)設定
- 使ってもらう。

このとき、社員はパスワード(B)を知っておけばPCログインとG Suiteの利用が可能です。

## 退社

- JumpCloudより社員のアカウントを停止
- ログイン可能なシステムからアカウントを解除
- G Suiteアカウント停止
- JumpCloudのユーザー削除

社員はパスワード(B)しかしらないので、退社手続き後からアカウント削除までの間に、
個人所有の端末からG Suiteへアクセスして情報を見ようとしてもパスワード(A)を知らないので`多分`見れません（要検証)
※G Suite SyncしてたらJumpCloudとG Suiteのパスワードが同じものになるのでダメですよ

今度はo365とのSAMLとADサーバ立ててJumpCloudでアカウント持たず、マスタはADに持たせた連携ができるかやってみようかなーー


おわり
ゼロから始めるデータサイエンス 1章で使うリスト内包表記のエラーについて

#python３で取り組んでいる方向け


p7の、「知り合いかも？」の部分のメソッドで、リスト内包表示に関するエラーがでました。


該当のメソッド
※少しだけ変数変えています

```sample.py

#辞書型のusersにfriendsを追加する工数は省略させていただきます。

users = [
    #0番目のユーザーはidが1,2,5の知り合いがいる可能性があります
    {"id": 0, "name": "Hero","friends":[{"id": 1, "name": "Dunn"},{"id": 2, "name": "Sue"},{"id": 5, "name": "Clive"}]},
     #1番目のユーザーはidが0,2,6の知り合いがいる可能性があります
    {"id": 1, "name": "Dunn","friends":[{"id": 2, "name": "Sue"},{"id": 0, "name": "Hero"},{"id": 6, "name": "Hicks"}]}
]



"""
下記のリスト内包表示では、n番目のuserが友達の可能性があるユーザーをループカウンタ変数のfriendとして
探し出し、friendのidをリストとして返すよう書いています。
"""


#=============ここでエラーが出る！！=============
print [friend["id"] for friend in users[0]["friends"]]
#>>> 正しければ[1,2,5]が出力されるはずです。
print [friend["id"] for friend in users[1]["friends"]]
#>>> 正しければ[0,2,6]が出力されるはずです。

```


##printはpython3から関数になっていた

下記のエラーが発生しました。

`syntaxError: Missing parentheses in call to 'print'`

python3よりprintは()で囲む必要がでてきました。その為、下記のように修正します

```sample.py
print(friend["id"] for friend in users[0]["friends"])
#>>> 正しければ[1,2,5]が出力されるはずです。
print(friend["id"] for friend in users[1]["friends"])
#>>> 正しければ[0,2,6]が出力されるはずです。
```

#しかし、出力は下記のとおりでした

```
>>>print(friend["id"] for friend in users[0]["friends"])
<generator object <genexpr> at 0x1028cc830>
```

generatorが出力されました。

ググってみたのですが、あまりピンとくる答えを見つけられませんでした。
※**何を参考にするべきかおしえていただけますと幸いです。**

そのため、usersがどのように出力されているか確認したところ、**friendsはリスト**だと判明しました。

そもそも、リスト内包表示のために書いていたのだと思い出し、下記のように修正したところ、無事出力されました。

#正解はこちらです！
```py

>>>print([friend["id"] for friend in users[0]["friends"]])
[1, 2, 5]
>>> print([friend["id"] for friend in users[1]["friends"]])
[2, 0, 6]
```

#リスト内包表記

なぜリスト内包表記を使うのかも学んだので、書いておきます。

今回のfor文は、他のプログラミング言語のようにかけます。

```py
#空のリストを作成
list = []

for friend in users[0]["friends"]:
     #カラのリストに友達の可能性があるuserのidを追加
     list.append(friend["id"])

print(list)
#[1, 2, 5]
```
改めて比較してみましょう！

```py3
>>>print([friend["id"] for friend in users[0]["friends"]])
[1, 2, 5]
```

だいぶ短くなりましたね！

リスト内包表記によるメリットは、書く行数が減るのみではないようです。
・実行速度がはやい
・if文を書きやすい(rubyみたいに書ける)

などなど

参考:@y__samaさん「[pythonの内包表記を少し詳しく](https://qiita.com/y__sama/items/a2c458de97c4aa5a98e7)」

一行でfizzbuzzを書く方法も紹介されていました。まとまっていて、めっちゃ綺麗でした。

#終わりに

見てくださった方、ありがとうございました！
PyTorch: Incremental inferenceをサポートしたDilated Convolution 1d実装

WaveNet、DeepVoice3等、1d dilated convolutionを利用したauto-regressive系のモデルを実装したい人には、役に立つかもしれません

```py
# coding: utf-8
import torch
from torch import nn
from torch.autograd import Variable
from torch.nn import functional as F


class Conv1d(nn.Conv1d):
    """Extended nn.Conv1d for incremental dilated convolutions
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.clear_buffer()
        self._linearized_weight = None
        self.register_backward_hook(self._clear_linearized_weight)

    def incremental_forward(self, input):
        # input: (B, T, C)
        if self.training:
            raise RuntimeError('incremental_forward only supports eval mode')

        # run forward pre hooks (e.g., weight norm)
        for hook in self._forward_pre_hooks.values():
            hook(self, input)

        # reshape weight
        weight = self._get_linearized_weight()
        kw = self.kernel_size[0]
        dilation = self.dilation[0]

        bsz = input.size(0)  # input: bsz x len x dim
        if kw > 1:
            input = input.data
            if self.input_buffer is None:
                self.input_buffer = input.new(bsz, kw + (kw - 1) * (dilation - 1), input.size(2))
                self.input_buffer.zero_()
            else:
                # shift buffer
                self.input_buffer[:, :-1, :] = self.input_buffer[:, 1:, :].clone()
            # append next input
            self.input_buffer[:, -1, :] = input[:, -1, :]
            input = torch.autograd.Variable(self.input_buffer, volatile=True)
            if dilation > 1:
                input = input[:, 0::dilation, :].contiguous()
        output = F.linear(input.view(bsz, -1), weight, self.bias)
        return output.view(bsz, 1, -1)

    def clear_buffer(self):
        self.input_buffer = None

    def _get_linearized_weight(self):
        if self._linearized_weight is None:
            kw = self.kernel_size[0]
            # nn.Conv1d
            if self.weight.size() == (self.out_channels, self.in_channels, kw):
                weight = self.weight.transpose(1, 2).contiguous()
            else:
                # fairseq.modules.conv_tbc.ConvTBC
                weight = self.weight.transpose(2, 1).transpose(1, 0).contiguous()
            assert weight.size() == (self.out_channels, kw, self.in_channels)
            self._linearized_weight = weight.view(self.out_channels, -1)
        return self._linearized_weight

    def _clear_linearized_weight(self, *args):
        self._linearized_weight = None
```

https://github.com/r9y9/deepvoice3_pytorch を作る過程でできたものでした。https://github.com/facebookresearch/fairseq-py/blob/884e30464b8f6a74bfaea5688b31e2005e0fbef5/fairseq/modules/conv_tbc.py をベースに、dilationをサポートしました。[テスト](https://github.com/r9y9/deepvoice3_pytorch/blob/a93535d7e2caa170608b068faac1287960efd295/tests/test_conv.py)も書いたので間違ってないと思います。
[メモ] Debianソースにパッチを当てて、debパッケージ作成

# 概要

Debianで、ソースをちょっといじって、パッケージを作りたいときに。
\# テラテイルでの回答([asciijump というアプリが実行されない](https://teratail.com/questions/99133))にて、使用.


# TL;DR
1. `debian/patches/`フォルダにパッチファイルを入れる。
2. `debian/patches/series`ファイルにパッチファイル名を記述する。


# 手順 (例)

```bash:ラズパイにて
# aptでsourceのレポジトリを有効化
sudo sed -i -e 's/#deb-src/deb-src/g' /etc/apt/sources.list
sudo apt update
#
# deb作成用パッケージ
sudo apt install -y devscripts
#
# asciijumpのビルドに必要なパッケージ取得
sudo apt build-dep -y asciijump
#
# 作業フォルダへ移動
mkdir ~/asciijump
cd ~/asciijump
#
# ソース取得
apt source asciijump
cd asciijump-1.0.2~beta/
#
# パッチを入れる (作る)
wget https://gist.githubusercontent.com/mt08xx/9cdf4bebed3b04509253f8778620372b/raw/cf94da0d0debb80cf8b016636fca325acb3e452e/xfnc.c.patch -O ./debian/patches/xfnc.c.patch
echo xfnc.c.patch  >> debian/patches/series
#
# ビルド
debuild -us -uc
#
# できあがったパッケージ
# ls -1 ../*.deb
# ../asciijump_1.0.2~beta-7.1_armhf.deb
# ../asciijump-dbgsym_1.0.2~beta-7.1_armhf.deb
#
# asciijumpパッケージをインストールしてたら、削除する
sudo apt remove -y asciijump 
#
# 今回のつくったdebファイルを指定して、インストール
sudo apt install -y ../asciijump_1.0.2~beta-7.1_armhf.deb
#
# 実行
asciijump
```

# その他
- 配布時には、バージョンの記述などを変えないといけないと思う。(混同するよね?)
シェル書いててcan't cd to [directory]に出くわした

## 概要
シェル書いてて `can't cd to [directory]` というエラーが出たのでメモ。

## 環境
OS : debian 7.6

## 解決法
vim で新規にファイル作成した時に、改行コードをLFにする必要があるみたい。
tr　使って置換もありだけど、もはや思考停止したので、vimでLFとしてファイルを開く方法を採択してみた。

```
:edit ++fileformat=unix
```

これで解決。
EC2上でアタッチされたroleを使用してaws-cliを行う

# やりたいこと
- EC2上で動くjenkinsでaws-cliを使う
- EC2にアタッチされているroleを使う
- Access KeyやSecret Keyは持たない
- AWSのAPIを使って行う

# 実現方法
シェルファイルでAPIを叩き、
レスポンスを環境変数に入れて一時tokenを使えるようにする

```shell:credential.sh
# bin/bash

url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME
curl $url > credential.json
export AWS_ACCESS_KEY_ID=`cat credential.json | jq .AccessKeyId | tr -d \"`
export AWS_SECRET_ACCESS_KEY=`cat credential.json | jq .SecretAccessKey | tr -d \"`
export AWS_SESSION_TOKEN=`cat credential.json | jq .Token | tr -d \"`
```

# ちなみにJenkinsfile
作ったlambda関数を自動的にS3に上げてくれるジョブです
~~lambdaを更新するコマンドでやらないとS3に上げるだけになっちゃうので要改良~~

```groovy:Jenkinsfile
#!groovy
pipeline {
    agent any
    triggers {
        pollSCM('H/3 * * * 1-5')
    }
    //environment {}
    stages {
        stage('Develop') {
            when {
                branch 'PR-*'
            }
            steps {
                ansiColor('xterm') {
                    echo '<<< start develop >>>'
                    sh '''
                        source `pwd`/credential.sh
                        Lambdadir="`pwd`/Lambdafiles/*"
                        for filepath in $Lambdadir; do
                            dirname=`basename $filepath`
                            zip `pwd`/$dirname.zip $filepath/*
                            aws s3 cp `pwd`/$dirname.zip s3://BUCKET_NAME/
                            aws lambda update-function-code --function-name dev_$dirname --zip-file fileb://$dirname.zip
                        done
                    '''
                }
            }
        }
    }
}
```

```shell-session:folder構成
.
├── Jenkinsfile
├── Lambdafiles
│   └── MODULE1_NAME_FOLDER #中にlamda用の関数を入れておく
│   └── MODULE2_NAME_FOLDER #中にlamda用の関数を入れておく
├── README.md
└── credential.sh
```
Ubuntu16.04のリモートデスクトップ接続

レンタルサーバー借りたので折角ならとWindows端末からリモート接続できるように下記などを参考に環境構築してみたものの、全く接続できず。。

https://qiita.com/oniipon/items/4fe3ba65d64d6eed231c

XRDPはインストールできるのだけど、接続画面が真っ黒のまま。
ログインプロンプトは出てきたりするのだけど、ログインしても状況変わらず。
下記を参考にバージョン等変えてインストールしても同様のまま。

https://xrdp.vmeta.jp/X11RDP-o-Matic

もはや諦めかけていたところ、下記を参考にして、ソースをビルドしていくことで何とかなった。
本当に感謝。

https://gtrt7.com/blog/linux/ubuntu-16

自分の環境ではXRPDのバージョンは0.9.1-9とした。
特に(3)のBuild準備は足りないものやダウングレードが面倒。。。
デスクトップ環境はメモリが脆弱なのでMateではなく、LXDEにした。
苦労した分、ログイン出来た時の感動はひとしお。
ネーミングと設計、分析

#ネーミングのスキルとは何か？

　ネーミング（名前付）とそれらの関連付けはソフトウェア開発そのものである。システム設計の技術的、手法的進歩はネーミング手法の進歩と言っても過言ではない。例をあげるとデータ辞書、ERモデル、オブジェクトモデル、ドメイン駆動といった形で進化していった。ネーミングにはプログラマーのドメインへの理解力、英語力、概念や考えを端的な言葉に変える能力が如実に反映される。

#ネーミングのスキルがないとどうなる？

ネーミング能力が低いと以下の問題が発生する。

 - システムの設計品質がどんどん劣化していく。
 - クラスやメソッドの抽出精度が低くなり、結果としてメンテしづらいコードになる。
 - 語彙に対する感度が低いため、ある程度質の整ったライブラリやフレームワークを早く理解できない。

#ネーミングのスキルの高めかた

楽な方法はないが、他の創作物同様、優れた成果物を研究するによって質やセンスを高める事ができる。

具体的な方法を以下に示す。なお、ドメイン層で使う名前の決定方法については[ドメイン駆動設計](https://www.amazon.co.jp/dp/B00GRKD6XU)に譲る。

 - OSやアプリを言語設定を英語にする。: UI系クラスに出てくる名前を定義するのに必要な用語を覚えることができる。また、開発しているアプリと似たアプリが存在する場合、ヘルプも含めてその中で使われている各用語が参考になる。
 - Rest APIクライアント等、非UI系クラスについて[dash](https://kapeli.com/dash)から参考になりそうな名前を検索する。：[参考](https://qiita.com/Disko-Muzik/items/08deef825e0da6477dc3 "参考")
 - オープンソースで作られたアプリを参考にする。同じくUI系クラスの命名方法についてヒントを得ることができる。

#普段からネーミングを意識しよう

ネーミング能力は他とは違って、なんでこんなクラス名、メソッド名か考える、開発対象のシステムで使われる用語に気をつける等、業務中にちょっと注意する事で少しずつ向上させる事ができ、かつ品質に影響を与えることができる数少ない能力である。

#参考文献
[命名のプロセス] (ttps://scrapbox.io/kawasima/命名のプロセス)
[実装パターン-ケント・ベック] (https://www.amazon.co.jp/dp/4894712873/)
[オブジェクト指向方法序説基盤編 - ジェームズ-マーチン] (https://www.amazon.co.jp/dp/4810185923/)
[モデルとプロセスをめぐる冒険 - 橋本 隆成]  (https://www.amazon.co.jp/dp/4798110558/)
Rails db migrate でエラーになったときの調査方法

#db migrateがうまく行かない時の調査方法についてメモ

## 1.RAILS_ENVで指定する環境はあっているか

デフォルトは```development```
指定する環境と対応するDBは```config/database.yml```で確認

```ruby:cmd
bundle exec rake db:migrate RAILS_ENV=test
```

## 2.エラーとなっているmigrationファイルを特定する
rake aborted以降をみる
エラー例

```ruby:example
bundle exec rake db:migrate RAILS_ENV=development
~
rake aborted!
ActiveRecord::StatementInvalid: Mysql2::Error: Specified key was too long; max key length is 767 bytes: CREATE  INDEX `idx_test` ON `tests` (`message`(761))
```
## 3.エラーとなったマイグレーションファイルを参照し、必要があれば修正して再実行

ファイル場所：db/migrate/xxxxxxxx.rb

対象のファイルだけ試したい場合は、
以下の手順で実行対象idを特定し、実行する。

※upまたはdownのメソッドを実行するとき、実行時のstatusが実施メソッドと異なる必要がある。(statusがupの状態でup実施しても実行されない。downの時も同様)

```ruby:migration
bundle exec rake db:migrate:status

Status   Migration ID    Migration Name
--------------------------------------------------
   up     20111016164835  Create test
   up     20111016164912  Create views

# 実行したいバージョンと実行したい処理(upまたはdown)を指定。
bundle exec rake db:migrate:up VERSION=20111016164835　RAILS_ENV=test
bundle exec rake db:migrate:down VERSION=20111016164912 RAILS_ENV=test

# マイグレーションファイル内のdown実施後、upを行いたいときは'redo'を使用すると楽
bundle exec rake db:migrate:redo VERSION=20111016164912 RAILS_ENV=test

```

## 4.上記3つを確認しても分からないときは、生SQLで確認

使用しているDBにターミナルで接続してSQLそのものに問題があるのかmigrateファイルでの実行方法に問題があるのか切り分ける。

dbconsoleの例

```terminal
# RAILS_ENVは繋ぎたい環境にする
RAILS_ENV=development rails dbconsole
```

mysqlの例

```ruby:mysql
#DBを指定したい時は、-Dオプションを使用
mysql -hlocalhost -utest -p
# migrateでエラーとなっているSQLを実行してみる
DROP INDEX idx_test ON tests;
```

## 5.その他
マイグレーションのdownで書いたものがうまく動いてなかったりすると、何度も実行している間にテーブルの状態が想定と異なってきて何がおかしいのか分からなくなってくるので注意。

詰まっているときは、マイグレーションファイルの中でもテストしたい箇所以外はコメントアウトして確認すると良い。
Markdownのurl記法を生成するブックマークレットを作った

## 概要

ブックマークレットを作る練習にいい題材がないかなと考えていたところ、Markdownでurlを書く時に自分でタイトルをつけるのがめんどくさかったので、ワンクリックで完了するようなブックマークレットを作ってみました。


## 作成したコード

```js
javascript: (function(){
  var title = document.title;
  var url = location.href;
  var md = '[' + title + '](' + url + ')'

  var temp = document.createElement('div');

  temp.appendChild(document.createElement('pre')).textContent = md;

  var s = temp.style;
  s.position = 'fixed';
  s.left = '-100%';

  document.body.appendChild(temp);
  document.getSelection().selectAllChildren(temp);

  var result = document.execCommand('copy');

  document.body.removeChild(temp);
})();
```

このコードを[JS Minifier (JavaScriptの圧縮)](https://syncer.jp/js-minifier)で圧縮しました。

```
javascript:(function(){var f=document.title;var c=location.href;var e="["+f+"]("+c+")";var b=document.createElement("div");b.appendChild(document.createElement("pre")).textContent=e;var d=b.style;d.position="fixed";d.left="-100%";document.body.appendChild(b);document.getSelection().selectAllChildren(b);var a=document.execCommand("copy");document.body.removeChild(b)})();
```

このコードをコピペしてブックマークバーに追加すればOK。


## 感想

作った後にググったら似たような記事をいくつか見つけたので、時間の無駄だった感がすごいです。


## 参考記事

[JavaScriptでクリップボードに文字をコピーする(ブラウザ) - Qiita](https://qiita.com/simiraaaa/items/2e7478d72f365aa48356)
KubernetesのToken Review API


KubernetesのAPIサーバと同じ認証を自前のpodとかでやりたいことがありませんか？  例えばAPIサーバにアクセスするためのIDトークンで認証しメールアドレスを使いたいとかサービスアカウントで認証したいとか。

そんなときはTokenReview APIを使ってみるといいかもしれません。

これはKubernetesのAPIサーバに対してBearerトークンをリクエストパラメータとして渡すと、APIサーバが有効かどうかを判断して結果を返してくれるAPIです。例えばServiceAccountのトークンや、OIDCを有効にしている場合にはID Tokenなんかを渡すことができます。

v1.7以降ではTokenReview APIには以下のURIでアクセスできます。

```
https://${API_SERVER_ADDR}/apis/authentication.k8s.io/v1/tokenreviews
```

リクエストパラメータは以下のようなJSONデータです。

```json
{
    "apiVersion": "authentication.k8s.io/v1",
    "kind": "TokenReview",
    "spec": {
        "token": <USER_TOKEN>
    }
}
```

これをTokenReviewAPIにPOSTしてやるとレスポンスが返ってきます。

```bash
$ curl -H "Content-Type: application/json" \
       -H 'Authorization: Bearer ${SYTEM_TOKEN}' \
       -d '{"apiVersion": "authentication.k8s.io/v1","kind": "TokenReview","spec": {"token": <USER_TOKEN>}}'
       https://${API_SERVER_ADDR}/apis/authentication.k8s.io/v1/tokenreviews \
```

例えばkube-apiserverに対してOIDCの認証設定かつusernameのフィールドとしてemailを使う設定をしている場合などは、TokenReview APIにID Tokenを渡すと、認証した結果のusernameの値としてemailアドレスが入っています。

```json
{
  "kind": "TokenReview",
  "apiVersion": "authentication.k8s.io/v1",
  "metadata": {
    "creationTimestamp": null
  },
  "spec": {
    "token": <USER_TOKEN>
  },
  "status": {
    "authenticated": true,
    "user": {
      "username": "foo@example.org"
      "groups": [
        "system:authenticated"
      ]
    }
  }
}
```

ServiceAccountトークンを渡した場合はusernameが以下のようなフォーマットの文字列になります。

```
system:serviceaccount:<namespace>:<name>
```

Tokenが有効でない場合や期限が切れている場合などは `status.authenticated` の値が `false` になります。

```json
{
  "kind": "TokenReview",
  "apiVersion": "authentication.k8s.io/v1",
  "metadata": {
    "creationTimestamp": null
  },
  "spec": {
    "token": <USER_TOKEN>
  },
  "status": {
    "authenticated": false,
  }
}
```

このAPIを呼び出すには `system:auth-delegator` の権限が必要なので、TokenReview APIを呼びすアカウントに対してClusterRoleBindingまたはRoleBindingで権限を付与してあげてください。

```yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: sample-ns:system:auth-delegator
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:auth-delegator
subjects:
- kind: ServiceAccount
  name: default
  namespace: sample-ns
```

さらにGoLangのコードからこれらを呼び出す場合にはvaultのKubernetes Auth Backend プラグインのコードを参考にするとよいでしょう。client-goのパッケージを使ってTokenReview APIを呼び出しています。

<https://github.com/hashicorp/vault-plugin-auth-kubernetes>

最後にひとつ注意すべき点を記載しておきます。  
今回TokenReview APIで扱っているID TokenやServiceAccount TokenはいずれもJWT形式なので署名を検証するための公開鍵さえあれば自前で検証できてしまいますが、TokenのRevokeや公開鍵ペアのローテーションが発生した場合の考慮を十分にしておく必要があります。

ID Tokenの場合にはトークンのclaimとしてexpなどが含まれているため、Revokeやキーのローテーションが発生したとしても最悪の場合でもexpの値である期限までしか使えませんが、ServiceAccount Tokenは期限を持っていないためRevokeやローテーションに関係なく永遠に使い続けられてしまいとても危険な状態になります。

よほど問題がない限りは正しくTokenReview APIを使って検証しましょう。
ループ処理の大まかな歴史

[C#のforeachの仕組み(2)](https://qiita.com/y_ohr/items/a8f50b15657b8b256caf)にコメントしようかと思ったけどこっちへ

#最も原始的なループ処理

```csharp
  int counter = 0;
  goto loop_check;
loop_start:
  //処理
  counter++;
loop_check:
  if (counter < 5) goto loop_start;
```
CPU命令(機械語)やアセンブラで書いていた時代のスタイル。
今でもCPU命令レベルではこれに近いことをやっています。

#for文の登場
ループ処理は頻繁に使う割には原始的スタイルだとけっこうな長さを食うため、「初期化」「終了条件」「次へ進む処理」をまとめて書くfor文が考案されました。
たぶんFORTRANあたりから。

#スクリプトでのループ処理
foreach(のようなもの)はスクリプトが発祥だったと思います。[^1]

* リスト(配列)から一つずつ内容を取り出して順次処理できると便利
* 何回繰り返すかは「リストの要素数」で決めればいい、「終了条件」を別に書くのは冗長
* 「次へ進む処理」は「次の要素をリストから取り出す」に決まってるからこれも省略できる
* そしたらループカウンタも明示的に用意する必要はないよね(内部的にはカウンタ持ってるんだけど)[^2]

昔は処理が遅かったこともあって、スクリプトはインタプリタ処理なので速度が遅いため簡略化した記述が好まれ「リストを渡せばリストの要素数分だけループする」というカウンタ変数や終了条件を省いた記述法が生まれたのでしょう。

[^1]: UNIXのBourne Shellの「for~in文」あたり？
[^2]: スクリプトの変数は式に応じて数値になったり文字列になるのでそれなりに重いです。インデックスを隠し変数にすることで整数型に固定できるだけでも高速化の効果はあるでしょう。

#プログラミング言語にもforeachを導入
普通のプログラミング言語でも「配列の中身を一つずつ取り出して処理」というのはよくあります。
ループカウンタは配列のインデックスと終了判定にしか使っていないことも珍しくないです。
なのでそういう処理のための省略記法としてforを簡略化したforeachを導入する言語も出てきました。

#イテレータ誕生
「複数の要素を格納したデータ」は配列が多いけど他の形もあります。
ディクショナリ(ハッシュ)とかスタックとか二分木とかリングバッファとか。
そういうものに対しても「格納された要素を一回ずつ取り出し、全部の要素を取り出し終わったら終了」という統一された手法が使えると便利。
ループカウンタのかわりにイテレータを使うことで同じようにfor文のループで処理できます。

#enumeratorはforeach用のイテレータみたいなもの(だと思う)
「イテレータでぐるぐる回すfor文」というのはだいたい同じような書き方になります。
「次へ進む処理」と「終了条件」はイテレータが処理するので、for文はイテレータが「もうないよ」と言うまで「次の要素を渡して」というお願いを繰り返すだけだから。
だったらforeach文に要素のリストを渡すと勝手にイテレータを作り、繰り返し処理のたびにイテレータに次の要素をもらえばいいだけです。すっきり！

でもこの時点でループカウンタ/イテレータの存在はソースコードから消えてしまうので、古典的なループ処理に慣れている人は「今どこまで処理したかを覚えてる変数がないのになんで『次の要素』がどれなのか把握できるの？」と戸惑います。
私も最初のころは気になってました。単に隠してるだけだったというオチ。

#そしてLINQ to Objectsに
リスト(コレクション)から内容を一つずつ取り出してそれに対して処理を行うなら、SQLクエリの結果リストと同じように処理できる、どんな形で格納されているかは気にする必要はない、必要なのはデータ集合から一つずつ要素を取り出し、全部取り出し終わったら終わることだけ。
つまりSQL文がテーブルの内容やサブクエリの結果データを集計したり加工して別の結果データを作るように、テーブルをコレクションに置き換えてもよく似た処理ができる、元データとなるコレクションに必要なのはアクセスするためのenumeratorを持っていることだけ。
という発想からLINQ to Objectsは生まれたんじゃないかなと思ってます。

#(おまけ)for文は死なず
foreachでかなり便利になってfor文を使う機会は減ったけど、foreachやLinqは「元となるデータ集合ありき」なループ処理です。
ループカウンタを「データ集合のインデックス」以外の目的でも使う場合は、明示的な変数として見えていないと困ることもよくあります。
同じようなことをするのにたくさんの方法があるのは混乱するしめんどくさいですが、上手に使い分けたいですね。

#(おまけその2)foreachとほぼ等価なfor文

```csharp:元コード
foreach (string s in collection)
```

```csharp:無理矢理for文にする
IEnumerator<string> e;
bool isContinue;
string s;
for (new Action(() => { e = collection.GetEnumerator(); isContinue = e.MoveNext(); if (isContinue) s = e.Current; })() ;
    isContinue ;
    new Action(() => { isContinue = e.MoveNext(); if (isContinue) s = e.Current; })())

//別の書き方
for (e = collection.GetEnumerator() ;
    new Func<bool>(() => { isContinue = e.MoveNext(); if (isContinue) s = e.Current; return isContinue; })() ;)

//enumeratorのDisposeなど知るか
```
失敗…

↓こちらに転載しました

https://metagrapher.net/2017/12/09/3861/



(2018年12月にCYBIRDの社外執行役員は退任しました)
# 起
こんにちは。[CYBIRDエンジニア Advent Calendar](http://qiita.com/advent-calendar/2017/cybird)9日目の@tossyzです。8日目は@kakizakiさんの「[Web UI の自動テストツール Cypress のご紹介](https://qiita.com/kkakizaki/private/4b6625a56fd2fa4c741c)」でした。あんなこんな積み上げでソフトウェア品質が日々上がってるんだそうな。
# 承
さて、本性はプログラマーだけど業務では技術統括部 統括部長という肩書でプログラム書く以外のエンジニアリング諸々をしています。
ビジネスセミナーなどにも目が行くのですが、「あの◯◯を成功させた××氏が！」という感じで成功談を語られているのをよく見かけます。
が、新しいことにチャレンジする時に、それがすぐ成功するなんてことは稀で、全力を尽くしたにもかかわらず失敗して終わるなんてことは珍しくありません。そんなものです。ごめんなさい。
# 転
さて、成功談と失敗談を比較すると、成功とはその案件と状況に徹底的に個別最適化を極めた結果で、失敗とは最適化し損ねた結果であることが見えてきます。
実際の所、成功談で語られる手法は個別最適化され過ぎていて、自分が抱えている課題に適用出来そうにないことばかりです。
一方、失敗談は最適化出来ていないので、二の轍を踏まない為の参考になることばかりです。

というわけで、失敗を成功のもとにするポインターを3つ御紹介します。

(1)[失敗学(wikipedia)](https://ja.wikipedia.org/wiki/失敗学)
　先達の失敗事例をどのように分析して役に立てるかという基本的な手法が簡潔にまとまっています。
(2)[失敗知識データベース(Webサイト)](http://www.shippai.org/fkd/index.html)
　古今東西の失敗事例を収集公開しています。ほとんど目を通しましたが、時々読み返しています。
(3)[失敗の本質(書籍)](https://www.amazon.co.jp/dp/B00BN16XX8)
　太平洋戦争で日本軍が各作戦でいかに誤った判断をしていったかを著した有名な書籍です。
　一つ一つ「なんでこんな判断しちゃったの？」って考えさせられ過ぎて、読み進められてないのが難点です。
# 結
そして、失敗も糧として果敢にチャレンジしたい方は是非サイバードへ！

[CYBIRDエンジニア Advent Calendar](http://qiita.com/advent-calendar/2017/cybird)明日は、@crystal_geyserさんの「数多あるWebサービスをつなげて遊ぼう」です！明日もお楽しみに！
litecoin toolchain のビルド, Ubuntu 17.10

https://github.com/litecoin-project/litecoin/

```
sudo apt install autoconf libtool libdb-dev libdb++-dev
```
準備

```
./autogen.sh
./configure
```
セットしていきます

## configure: error: Found Berkeley DB other than 4.8, required for portable wallets (--with-incompatible-bdb to ignore or --disable-wallet to disable wallet functionality)                      

libdb-5系がシステムに入っているが4.8じゃないと駄目だそうな。 `--with-incompatible-bdb` を付けることで回避してみる

> ./configure --with-incompatible-bdb

## configure: error: Could not link against boost_filesystem !

```
sudo apt install libboost-all-dev
```

他にもいくつか依存があったのでboost関連を全部入れちゃう

## configure: error: libevent not found. 

読んだまま

```
sudo apt install libevent-dev
```

configure完了

> make -j10

完了

> ./src/litecoin-cli --version                                                                                                                                     

> Litecoin Core RPC client version v0.15.0.1-ba8ed3a93

確認

> make install
Firebase CLIでAngularアプリをFirebase Hostingにデプロイする

Firebaseを始めてみたかったので、一番手軽そうなFirebase Hostingを試してみました。
angular-cliで作成したSPAアプリをFirebase Hostingにデプロイする方法を紹介します。

# 前提

* Firebaseのアカウントは取得済み(無料枠で可)
* ホスティングするAngluarのSPAを用意済み(今回はng newした直後のアプリを使用)

試してみた際の環境

```bash
$ ng -v
Angular CLI: 1.5.2
Node: 9.2.0
OS: darwin x64
Angular: 5.0.2
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

@angular/cli: 1.5.2
@angular-devkit/build-optimizer: 0.0.33
@angular-devkit/core: 0.0.20
@angular-devkit/schematics: 0.0.36
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.8.2
@schematics/angular: 0.1.5
typescript: 2.4.2
webpack: 3.8.1

$ firebase -V                                                                                                     
3.15.2
```

# 手順

## 事前準備

Firebase CLIをインストールします。

```bash
$ npm install -g firebase-tools
```

## Firebaseプロジェクトの作成

FirebaseのWebコンソールにログインして事前に空のプロジェクトを作成しておきます。
https://console.firebase.google.com

![プロジェクト作成.png](https://qiita-image-store.s3.amazonaws.com/0/79414/8f05e1f3-50fe-b47a-86ea-a12c2b487416.png)


後述する、`firebase init`コマンドで「プロジェクトを新規作成する」を選択出来るのですが、まだ対応していないようです。

コンソールからFirebaseにログインします。

```bash
$ firebase login
```

次のようにエラーレポートを送信してもいいかという質問に答えた後に、ブラウザが立ち上がりGoogleアカウントでのログインを求められます。




<img width="814" alt="ログイン.png" src="https://qiita-image-store.s3.amazonaws.com/0/79414/2b127f56-2f36-9225-50ec-82c54c1c19d8.png">

ログインが完了すると、次のような画面に移行するので、コンソールに戻ります。

![ログイン完了.png](https://qiita-image-store.s3.amazonaws.com/0/79414/c34f1e23-5b2d-699c-1c60-f7e4254d5e3c.png)


次にFirebaseプロジェクトの初期化を行います。
その前に、今回デプロイするAngularアプリのプロジェクトディレクトリに移動しておきます。

```bash
$ cd angular-firebase-hosting
```

次のコマンドを実行します。

```bash
$ firebase init
```

<img width="500" alt="init.png" src="https://qiita-image-store.s3.amazonaws.com/0/79414/7c5c4b62-7878-e7d0-5cbb-0ca9ffed925b.png">


プロジェクトの種類を聞かれるので
`Hosting: Configure and deploy Firebase Hosting sites`を選択しておきます。

また、プロジェクトの選択を求められるので、先ほど作成したプロジェクトを選択します。

## デプロイ設定

firebase.jsonを編集してAngular向けのデプロイ設定を行います。

```json:firebase.json
{
  "hosting": {
    "public": "dist",
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}
```

`public`にはホスティングするディレクトリを指定しています。
`rewrites`ではhttpのリライトルールを設定しています。
Angular Routerを使う場合はお決まりの設定かと思います。

## デプロイ&確認

Angularアプリをビルドしておきす。

```bash
$ ng build --prod
```

次のコマンドを実行して、Angluarアプリをデプロイします。

```bash
$ firebase deploy
```

デプロイが完了した後に、次のコマンドを実行後`Hosting: Deployed Site`を選択するとデプロイ済みのAngluarアプリがブラウザで表示されます。

```bash
$ firebase open
```

![デプロイ完了.png](https://qiita-image-store.s3.amazonaws.com/0/79414/42596a44-3418-bb69-55c5-08b03d8ebb98.png)


# まとめ

ポイントとしてはfirebase.jsonの`public`と`rewrites`の設定でしょうか。
その他、Firebase CLIによる複数環境の使い分けやカスタムドメインの設定などは、他に参考になる記事が色々公開されていますのでそちらを参考にしてみると良いかもしれません。




# 参考

https://github.com/firebase/firebase-tools
https://qiita.com/Ijoru/items/5b27f1c32df2222514fb
https://firebase.google.com/docs/hosting/full-config?hl=ja
CSS TransitionをJavaScriptと組み合わせる

CSS Transitionが普及してアニメーションが低負荷に行えるようになりましたが、JavaScriptと組み合わせることも可能です。

# Transitionの仕組み

[MDN](https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions)の、いかにも翻訳な文章からの引用ですが、

> CSS3 仕様の一部である CSS transitions は、CSS プロパティが変化する際のアニメーションスピードの操作法を提供します。アニメーションによる変化は即座に反映されるのではなく、指定された時間の間に渡ってプロパティが変化します。例えば、ある要素の前景色を白色から黒色に変更する場合、通常は即座に前景色が替わります。transitions が有効な CSS では、指定した時間をかけて、またカスタマイズした加速度曲線に従って変化していきます。

つまり、「CSSプロパティ」の変化に対して、その場で変化するのでなくアニメーションで緩やかに変化させる、という仕組みです。これは**変更の方法を問うものではない**ので、クラスの切り替えや`:hover`などの変化だけでなく、JavaScriptでCSSの値を直接変化させた場合にも、Transitionは発生します。

# 活用例

もちろん、定型的なものであれば、CSSで書いてしまって、JavaScriptではクラスを付け外しするだけにするほうが楽なのは間違いないです。ただ、`transition`させる値として`auto`は使えないので、中身の分量が変動するようなボックスを`transition`させたい場合、JavaScriptで高さを割り出して、それを明示的に指定することで、きれいに`transition`させることができます。
GitKrakenで、リポジトリをエクスプローラーで開く方法

# 「エクスプローラーで表示」が見当たらない！
GitKraken、かっこよくて大変気に入ったのですが、SourceTreeでよく使っていたリポジトリをエクスプローラーで開く機能が見当たりません。
ターミナルだけあればいい方々にはよいのかもしれませんが、少し不便です。
私は意識が低いので、方法をいろいろ模索してみました。

# 方法その1 fuzzy finder から開く
`Ctrl+p`で出る入力欄から「Open in file manager」を選べば開けます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/50286/30f34220-a0b1-5cd6-f7c1-c886005867cc.png)

# 方法その2 Tree Viwe から開く
「Show in folder」で開けます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/50286/da93581f-5ba3-91a1-42ed-9f1b0735815b.png)

# 方法その3 (本命・オススメ) Custom Terminal Commandを利用して開く

まず以下のようなシェルスクリプトを適当な場所に配置します。

```bash
#!/bin/bash
echo $1 | tr -d '\n' | iconv -f UTF-8 -t SJIS | sed -e 's/\//\\/g' -e 's/\(^\\.\)/\1:/' -e 's/\(^\\\)//'| xargs -I@ -0 explorer '@'
exit 0
```

今回は`"D:\bin\open.sh`に配置しています。

パスの変換については、以下を参考にさせていただきました。
> Linux形式のパスをWindows形式のパスに変換してクリップボードにコピーする方法 by @t2wonderland on @Qiita >
> https://qiita.com/KemoKemo/items/f91800836799102cf1f9


その上で、GitKrakenの Custom Terminal Command に以下を設定します。
`"C:\Program Files\Git\bin\bash" "D:\bin\open.sh" "%d"`

以上で、メニューバーの File > Open Terminal から対象のリポジトリをエクスプローラーで開くことができました。

# まとめ
 Open Terminal 作るなら Open file manager も作って！