OmniAICreator/Qiita-1.07M huggingface dataset:
JavaMailでiPhoneが送信したcharset=cp932のメールを扱う

iPhoneが`charset=cp932`のメールを送ってくることがある。
Javaはcp932なんて知らないので、`getContent`するとJavaMailが死ぬ。


```java
public static void convertContentType(Part part) throws MessagingException {
	String[] headers = part.getHeader("Content-Type");
	String contentType = headers[0].toLowerCase();

	if(contentType.contains("cp932")) {
		part.removeHeader("Content-Type");
		part.setHeader("Content-Type", contentType.replaceAll("cp932", "ms932"));
	}
}
```

これで`getContent`する前にContent-Typeを変換する。
ms932ならJavaが理解できるので`getContent`できるようになる。
riot.js global mixin

### trigger は長いのでemitに変更してみる。
```js
riot.mixin({emit:function(){return this.trigger.apply(this,Array.from(arguments)) } });
```
### 確認
```html
<script src="//gnjo.github.io/riot.js"></script>
<t></t>
<t2></t2>
```
```js
riot.mixin({emit:function(){return this.trigger.apply(this,Array.from(arguments)) } })
;
riot.tag('t',false,function(opts){
 this.on('xyzed',(x)=>{console.log('xyzed',x)})
 this.emit('xyzed','emit');
 this.trigger('xyzed','trigger')
});
riot.tag('t2',false,function(opts){
 this.on('xyzed',(x)=>{console.log('xyzed',x)})
 this.emit('xyzed','t2 emit');
 this.trigger('xyzed','t2 trigger')
});
riot.mount('*')
```
CakePHPのお勉強

CakePHPを触ることになったので、解読しながら学んだことのメモ

#データベースとの接続
データベースを使うにはModelを使う。

>**モデル**
>モデルはアプリケーションのビジネスレイヤーを担当するクラスです。 すなわち、業務ドメインにおけるデータやその妥当性、トランザクションや 情報ワークフローの過程で発生する全てのことがらを管理する役割を負うということです。

>モデルクラスは通常はデータを表すもので、 CakePHP のアプリケーションではデータアクセスに使われます。 具体的に言うと、モデルはデータベースのテーブルを表しますが、それに限らず ファイルや外部ウェブサービス、iCal のイベントや CSV ファイルの行など、 データを扱うあらゆるものに使われます。

>https://book.cakephp.org/2.0/ja/models.html

Modelを使って、DBから値を取ってくるのは、読んでいて分かったのだが、
どうやってModelとテーブル名を紐づけているのかが、不思議だった。

>**データベース設定**
>CakePHP では、データベースの詳細設定は app/Config/database.php ファイルに記載されていることを前提としています。

>https://book.cakephp.org/2.0/ja/development/configuration.html

データベースの設定は、app/Config/database.phpに記載する。

>**useTable**
>useTable プロパティはデータベースのテーブル名を指定します。 デフォルトでは、モデルのクラス名の小文字の複数形が用いられます。 この属性を他のテーブル名にするか、 データベース・テーブルをこのモデルで使いたくない場合、 false を指定してください。

>https://book.cakephp.org/2.0/ja/models/model-attributes.html


デフォルトでは、モデルのクラス名の少文字の複数形が用いられます（！）
IEでsvgタグ内のimageが表示されない

#症状
Chromeで表示される画像が、IEで表示されない。

```test.html
<!DOCTYPE html>
<html lang="ja" >
#ライブラリ読込などは省略
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
  <div class="test" ></div>
</body>
<script>
var svg = d3.select(".test").selectAll("svg").remove();
  svg = d3.select(".test").append("svg")
      .attr("width", 300).attr("height", 300)
      .attr("stroke-width", 2).attr("xmlns","http://www.w3.org/2000/svg");

svg.append('image').attr({
    'x' : careerCX,
    'y' : sides - radius * 0.3,
    'height' : 55,
    'xlink:href' : "./images/kamo.png"
   });

<script>
</html>
```

###chromeでの表示
<img width="495" alt="crome.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/202956/adab2f17-945c-ce1e-2d0f-b77736539009.png">

###IEでの表示
<img width="499" alt="IE.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/202956/1480d0b5-4009-2ca4-3ad3-c2fdd20cf4fe.png">

何も出力されてねーじゃねーか。
#対策
タグのプロパティに「width」追加したら出た。

```test.html
#省略
<script>
var svg = d3.select(".test").selectAll("svg").remove();
  svg = d3.select(".test").append("svg")
      .attr("width", 300).attr("height", 300)
      .attr("stroke-width", 2).attr("xmlns","http://www.w3.org/2000/svg");

svg.append('image').attr({
    'x' : careerCX,
    'y' : sides - radius * 0.3,
    'height' : 300,
   'width':300,        #←追加
    'xlink:href' : "./images/kamo.png"
   });

</script>
</html>
```
IE②
<img width="499" alt="IE2.png" src="https://qiita-image-store.s3.amazonaws.com/0/202956/48d80823-bb2a-2bba-566c-dc54c4f1097e.png">

#学んだこと
chromeは足りない変数は明示的に補完してくれるけど、IEはなかったら「値無いからゼロにしとくわ（ドヤ）」って意地悪してくる。
#愚痴
chromeの開発者ツールはSVGタグ内のコンテンツも選択できるけど、IEはそれができないからめっちゃ苦労した。
ProxyCommandでsshの多段接続をする

日々の業務でsshの接続先から更にsftpを叩いてローカルまでファイルを取ってくるという作業がめんどくさかったので
ProxyCommandを使って多段接続することにしました。

```~/.ssh/config
Host server1
  HostName 111.222.333.444
  User tom
  Port 11111

Host server2
  HostName 555.666.777.888
  User bob
  Port 22222
  ProxyCommand ssh -W %h:%p server1
```

`~/.ssh/config` に上記のように記述します。

sshでserver2に接続すると、server1を踏み台にしてserver2にローカルから接続できます。

```terminal
$ ssh server2
```
WebAudioAPIでリバーブを製作

Convolverリバーブがデフォルトでありますが、コムフィルタを４個(各々にローパスフィルタでハイダンプしたもの）並列接続した擬似リバーブを製作してみました。

これにオールパスフィルタを２個直列接続すれば、シュレイダー式のリバーブ風になりますが、面倒なのでパス。


インスタンスのプロパティやパラメータを最初の宣言でまとめられたら楽なのですが、やり方がわからないので適当です。
配列を作ってXXのゲイン、Qとか書くのすごい面倒ですね。

```js:javascript
var dry = Actx.createGain();
var parallel = Actx.createGain();
var wet = Actx.createGain();

var delay = new Array();
var feedback = new Array();
var LPF = new Array();
//ディレイタイム、フィードバックゲインのリスト化
var delaytimeList = [0.039, 0.0367, 0.0332, 0.0299];
var feedbackList = [0.8356, 0.8445, 0.8582, 0.8321];

//コムフィルタの製作
for (var i = 0; i < 4; i++) {
	delay[i] = Actx.createDelay();
	feedback[i] = Actx.createGain();
	LPF[i] = Actx.createBiquadFilter();
	LPF[i].type = "lowpass";
	LPF[i].frequency.value = 12000;
	LPF[i].Q.value = 0;
	delay[i].delayTime.value = delaytimeList[i];
	feedback[i].gain.value = feedbackList[i];
}

dry.gain.value = 1.0;
wet.gain.value = 0.5;
parallel.gain.value = 0.25;

//ルーティング
source.connect(dry).connect(gain);
//コムフィルタ４個を並列接続
for (var i = 0; i < 4; i++) {
	source.connect(parallel).connect(delay[i]).connect(wet);
	(delay[i]).connect(feedback[i]).connect(LPF[i]).connect(delay[i]);
}

wet.connect(gain).connect(Actx.destination);
```
Installing Julia kernel on Windows JupyterLab

# IJulia Kernel

Okay, in this document, we will discuss how to install Julia on jupterlab.

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/7aab9209-b338-afdb-505c-1052e7ec85cd.png)


# prerequisites

## installing julia

https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6.2-win64.exe
from https://julialang.org/downloads/

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/ab706bb0-f48a-9885-9f04-ae8387b576f7.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/ab2a0465-90d2-79fa-6b57-2fa18b1ea062.png)

C:\Users\Administrator\AppData\Local\Julia-0.6.2\bin\julia.exe 

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/53d295f9-2386-67ce-9b81-db70d55c95dc.png)

## installing IJulia

https://github.com/JuliaLang/IJulia.jl

run julia and `Pkg.add("IJulia")`
```
julia>Pkg.add("IJulia")
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/52d86400-c192-9b5e-8cc0-4098deb90bf2.png)

using IJyulia
notebook()

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/2bb25442-b561-3f14-35cd-5d213b6f18b7.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/e48f5842-73e0-471a-2804-f8ebfa1cd40e.png)

No. this is not what I want. I want IJulia on my current conda environment.

## removing IJulia and reinstalling IJulia with setting env["jupyter"]

```
julia>Pkg.rm("IJulia")
julia>ENV["JUPYTER"]="/c/ProgramData/Anaconda3/envs/jupyterlab/Scripts/jupyter";
julia>Pkg.add("IJulia")
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/1a1582c1-dde6-82d0-9fd6-ef7252e1d46e.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/c9c91ff9-5a9e-13ff-7fb7-99d22789230d.png)

# jupyter lab
```
cd %conda_prefix%
jupyter lab
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/3cacc894-6cd6-f955-a73c-14a3dae981c1.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/7aab9209-b338-afdb-505c-1052e7ec85cd.png)

# test julia
```
Pkg.update()     # けっこうかかる
Pkg.add("Plots") # 可視化、フロントエンド
Pkg.add("GR")    # 可視化、バックエンド
Pkg.add("DataFrames")

```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/df56abec-3887-ce95-facf-9825235bc897.png)

```
using Plots
gr(size=(200, 200))
const Matrix = rand(1000, 200);
tic()
@time heapmat(Matrix)
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/b2f1b340-b32a-6ef8-c042-e2741e37c4b0.png)

# ref

IJulia
https://github.com/JuliaLang/IJulia.jl

julia download 
https://julialang.org/downloads/

IJulia display logic
https://github.com/JuliaPlots/Plots.jl/issues/157
WPのプラグイン管理でよく使うsvnコマンドの覚書

覚書です。
「あのコマンドどこでみたっけ」となった時に自分が見るようです。

## ディレクトリの削除
via:https://sousaku-memo.net/php-system/252

composerとpharでライブラリ入れ替えたいときとかに。
updateしないとcommitがこけるときあり。

```
$ rm -rf vendor/
$ svn status | grep '^!' | awk '{print $2}' | xargs svn delete
$ svn update
$ svn commit -m "remove vendor"
```
VS CodeでDockerで起動したNode.jsのアプリをデバッグする

## 1. npm scriptsを定義

```json
{
  "scripts": {
    "dev": "npx node-dev --inspect=0.0.0.0 index.js"
  }
}
```

などどする。
上記では```node-dev```を使用しているが、代わりに```node```を使うときも同様に
```--inspect=0.0.0.0```を付ける。
デフォルトでポート9229でデバッガーが起動する。

## 2. Dockerとかdocker-composeで起動

DockerfileのEXPOSEやdocker-composeのportsで
ポート9229をリッスンできるようにする。

例.

```yaml
  app:
    build: .
    command: npm run dev
    ports:
      - "3000:3000"
      - "9229:9229"
```

```docker-compose up```等して起動する。

### 3. VS Codeのlaunch.jsonに構成を追加

launch.jsonの設定画面で"構成の追加"ボタンからDocker: Attach to Nodeを選ぶことで追加できる。

![SS_ 2018-04-18 15.37.29.png](https://qiita-image-store.s3.amazonaws.com/0/2648/9546eaa9-897e-8254-b0cc-1c7e7a5be2e9.png)

remoteRootは任意に設定する。

例.

```json
    {
      "type": "node",
      "request": "attach",
      "name": "Docker: Attach to Node",
      "port": 9229,
      "address": "localhost",
      "localRoot": "${workspaceFolder}",
      "remoteRoot": "/usr/src/app",
      "protocol": "inspector"
    }
```
Let'sEncryptでSSL証明書発行


手動での秘密鍵生成等は要らず。

コマンドの実行で、秘密鍵生成、署名、証明書発行まで行ける。

### コマンドのインストール

```sh
$ cd /usr/local/bin
$ sudo wget https://dl.eff.org/certbot-auto
$ sudo chmod 755 certbot-auto
```


### SSL証明書発行

```sh
$ /usr/local/bin/certbot-auto certonly
```

以下、内容に沿って入力

```
Saving debug log to /var/log/letsencrypt/letsencrypt.log

How would you like to authenticate with the ACME CA?
-------------------------------------------------------------------------------
1: Spin up a temporary webserver (standalone) # アプリケーションサーバで動かす場合 (WEBサーバは止めておくこと)
2: Place files in webroot directory (webroot) # ドキュメントルートがある場合
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): [1 or 2を入力]
Plugins selected: Authenticator webroot, Installer None
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'to cancel): [ドメイン/サブドメインを入力]
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for [ドメイン/サブドメイン]
Input the webroot for [ドメイン/サブドメイン]: (Enter 'c' to cancel): [ドメイン/サブドメインのドキュメントルート]
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/[ドメイン/サブドメイン]/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/[ドメイン/サブドメイン]/privkey.pem
   Your cert will expire on 2018-07-17. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot-auto
   again. To non-interactively renew *all* of your certificates, run
   "certbot-auto renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le
```

### SSL証明書発行 生成場所

```sh
$ sudo ls -al /etc/letsencrypt/live/[ドメイン/サブドメイン]/

README
lrwxrwxrwx 1 root root   52  4月 18 12:40 cert.pem -> ../../archive/[ドメイン/サブドメイン]/cert1.pem
lrwxrwxrwx 1 root root   53  4月 18 12:40 chain.pem -> ../../archive/[ドメイン/サブドメイン]/chain1.pem
lrwxrwxrwx 1 root root   57  4月 18 12:40 fullchain.pem -> ../../archive/[ドメイン/サブドメイン]/fullchain1.pem
lrwxrwxrwx 1 root root   55  4月 18 12:40 privkey.pem -> .
Progateで習ったじゃんけんプログラム

# 初投稿でございます <h2>
今回はprogateで習ったじゃんけんプログラムに少し要素を追加してみました。


追加した要素は
・ 続けて複数回できるように
・ 結果によって得点をつける
・ 指定した回数が終わったら得点をみて大田泰示になれるかを表示する

```janken.py
retry = 0
score = 0
while(retry < 2): #2回する
    print('何を出しますか？（0: グー, 1: チョキ, 2: パー）')
    player_hand = int(input('数字で入力してください：'))

    if import_junken.validate(player_hand):
        # randintを用いて0から2までの数値を取得し、変数computer_handに代入してください
        computer_hand = random.randint(0, 2)

        if player_name == '':
            import_junken.print_hand(player_hand)
        else:
            import_junken.print_hand(player_hand, player_name)

        import_junken.print_hand(computer_hand, 'コンピューター')

        result = import_junken.judge(player_hand, computer_hand)
        print('結果は' + result + 'でした')

        if result == "勝ち":
            score += 3
            print("勝ち点" + str(score) + "が与えられました")
            retry += 1
        elif result == "負け":
            score += 0
            print("勝ち点は０です")
            retry += 1
        else:
            score += 1
            print("勝ち点" + str(score) + "が与えられました")
            retry += 1
    else:
        print('正しい数値を入力してください')
        retry += 1

    if retry == 2 and score > 0:
        print("あなたは勝ち点が" + str(score) + "点以上なので大田泰示になりました")
    elif retry == 2 and score == 0:
        print("あなたは勝ち点が" + str(score) + "点なので大田泰示にはなれませんでした")

```

ソースは途中からなんですけど、retryやscoreを新たな変数として定義し、その値をみて判断できるようにしました。

結果はこんな感じです。

<img width="355" alt="スクリーンショット 2018-04-18 15.17.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/246662/ae250a3b-6de4-04a5-0ba4-e03d5ec07092.png">

<img width="377" alt="スクリーンショット 2018-04-18 15.15.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/246662/38d0e153-bf20-9ad7-fae4-88893a6cd9c1.png">

# 最後に <h2>
０点より大きければみなさん大田泰示選手になれます。
Herokuのチュートリアルアプリをデプロイするメモ

# ローカルで動作

```sh
% git clone https://github.com/heroku/ruby-getting-started.git
% cd ruby-getting-started
% rbenv install 2.3.5
% gem install bundle
% bundle install
% bundle exec rake db:create db:migrate
% heroku local
★この時点でlocalhost:5000で動作
```

# リモート（Heroku）にデプロイ

```sh
% heroku create
% git push heroku master
% heroku run rake db:migrate
% heroku open
```

# 参考
https://github.com/heroku/ruby-getting-started.git
C# 7.0 パターンマッチングで楽々nullチェック

## 概要
C# 7.0にて導入されたパターンマッチング
本来はアップキャストされたオブジェクトを安全にダウンキャストして分岐を可能にするものだが実はnullチェックにも使える

```csharp
// 本体の使い方
object obj = "objectなstring";
if (obj is string str)
{
//このスコープ中のみobjがstringにキャストされたstr変数を使うことができる。
//キャストできなかった場合はif内部を通らない
}
```

## nullチェックにも活用可能
C#ではnullは型無しとしているためその仕様を逆手に取った方法

### 従来の方法
```csharp
var obj = GetNullOrString(); //半々の確率でnullか実体のあるstringを返してくれるメソッド
if (obj != null)
{
//nullではない場合if内部を通る
}
```

### パターンマッチング
```csharp
if (GetNullOrString() is string str)
{
//null時には型無し = string型では無いためif内部を通らない
//但しスコープはif文限りのため外からはstr変数を使えないことに注意
}
```
Sourcetreeでのエラー


チーム制作に先立ち、GithubとSourcetreeを利用しようとしていくつか問題点があり、記録に残しておく。

# **問題点**
- プッシュができない。
- プロジェクト設定においての注意点
- gitignoreの設定

# **解決**
- プッシュができない。
    - レポジトリ設定のリモート詳細のアドレスに自分のＩＤがなかった。
    - ![d.png](https://qiita-image-store.s3.amazonaws.com/0/214218/dafa2ee5-3b89-b65c-ce5c-b020452da048.png)
    - ＩＤを追加して解決。

- プロジェクト設定においての注意点
    - Unityのバージョンを統一すること。
    - Unity上でmeta formatを'force text'にする。
    - コミットする時自分の作業物を反映されるに必要なファイルだけコミットすること、.metaファイルもいっしょにコミットすること。
    - コミットの前にシーンをセーブしたりEditorを閉じ、projectをセーブすること。prefabファイルの更新タイミングがこのタイミングのため。

- gitignoreの設定
    - gitで管理する場合、ignoreに「 https://github.com/github/gitignore/blob/master/Unity.gitignore 」このurlのものを追加すること。
    -  .gitignoreを使うと無視するファイルやディレクトリを指定できる。

  







>参考サイト
https://docs.google.com/document/d/1ZPwEBlx9DY4GCmjVWu5We4juZOpRf4Nb70GNcCbz-pM/mobilebasic?pli=1#h.abafa4hlom9h
【Rails×MySQL】保存できる画像ファイルの容量を変更する

RailsでDBをsqlite3からMySQLに変更したのち、今まで通り画像の登録を行おうとしたら`Data too long for column 'binary_data' `と怒られました。

[調べてみたところ](http://rails.clickyourstyle.com/articles/56)、どうやらMySQLではBINARY型が無いため、自動でBLOB型に変換されるそうで、またそれと同時に最大量（lmit）も決めてくれていて、これが65535Byte(64KB)になっています。

そして今回登録しようとした画像ファイルの容量218KBは、上記の最大量63KBを超えていたためエラーとなりました。

これを回避するために、下記の記事を参考に最大量5MBに変更して対応してみました。

- migrationファイルの作成と実行方法。
    - [rails generate migrationコマンドまとめ](https://qiita.com/zaru/items/cde2c46b6126867a1a64#%E6%97%A2%E5%AD%98%E3%82%AB%E3%83%A9%E3%83%A0%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B)
- カラムの修正
    - [blob型カラムのサイズ制限を変更する](http://rails.clickyourstyle.com/articles/56)
- migrationファイルのchangeメソッドについて
    - [【Rails】migrationのchangeとup/downって何が違うの？](http://tanihiro.hatenablog.com/entry/2014/01/10/182122)

次のコードが実際に作成したマイグレーションファイルになります。

```マイグレーションファイル.rb
class ChangeBinaryToImage < ActiveRecord::Migration[5.0]
  def change
    change_column :images, :binary_data, :binary, :limit => 5.megabyte
  end
end
```
こちらを適応させたのち、再び画像を登録して見るとうまく行きました！
Rからクリップボードに大きめのデータをコピーする方法

RからExcelに手軽にデータをコピーしたい時、

```R
write.table(sample_data, file = "clipboard", sep="\t")
```
が便利なわけですが、
コピーしたいデータのサイズが大きいと、以下のエラーが出ます。

```R
clipboard buffer is full and output lost
```


対処として

```R
write.table(sample_data, file = "clipboard-16384", sep="\t")
```
と書くと、16Mくらいまでであれば、コピー可能になります。（これ以上は無理のようです）

どういうことかと言いますと、
"clipboard-*****" →　*****の部分で、クリップボードの容量最大値を指定できるようです。
詳しくは下記をご参照下さい。（というかこの記事は下記の和訳です。）
https://stackoverflow.com/questions/32035119/how-to-solve-clipboard-buffer-is-full-and-output-lost-error-in-r-running-in-wi

R上にも明記があって、
?connection でClipboardの項を見ると、
"When writing to the clipboard, the output is copied to the clipboard only when the connection is closed or flushed. There is a 32Kb limit on the text to be written to the clipboard. This can be raised by using e.g. file("clipboard-128") to give 128Kb."
とクリップボードの容量を変えられる記載があります。

よろしくお願いします。
10コアのCPUを導入してわかったOpenCVカスケードトレーニングのボトルネック

カスケードトレーニングをするときにはopencv_traincascade.exe を使うわけなのですが、
Gitから最新をもってきて作ると、OpenCVのパラレルフレームワークを使うようになります。TBBを指定しているところがなくなりました。
早速ビルドして試しましたが、TBBを使った自前ビルドのほうが早いです。時間が惜しい人は公式配布の3.4.0あたりまでのソースから自前でWITH_TBBでビルドしたものを使うとよいと思います。Windows10でVisualStudio2017以外でしたら結果は違うかもしれません。

また、意外と古くから知られていたようなのですが、opencv_traincascade　のボトルネックになっているところは、CvCascadeClassifier::fillPassedSamples という処理で、やっていることは、不正解画像に正解画像を当ててチェックしているようなのですが、画像を一つ一つチェックしているようで、マルチコアマシンで学習を進めても1コアしか使わないので、ステージが上がってくると、非常に目立ってきます。今のところ、CPUのオーバークロックくらいしか対処方法がありません。
http://answers.opencv.org/question/16496/parallelization-of-linear-part-of-opencv_traincascade/
ここで提示されているコードも試しましたが、かえって遅くなってしまいました。

それでは。
MATLAB上で時間のかかるシミュレーションが終ったら通知して欲しい

# 動機
パラメータを学習させたい！！！けど時間かかる！
いつまでも画面を見ているわけには行かないけど，計算が終わったらすぐ結果を知りたい．
そう，そんな時は終わり次第メールで通知すればいい．

# ソース
https://jp.mathworks.com/matlabcentral/answers/93383-how-do-i-use-sendmail-to-send-email-from-matlab-7-2-r2006a-via-the-gmail-server-or-yahoo-server
http://blog.livedoor.jp/itukano/archives/51833649.html

# コード
```matlab
% Modify these two lines to reflect
% your account and password.
email = 'myaddress@gmail.com';    %変更するのは
password = 'password';            %この２行

setpref('Internet','E_mail',email);
setpref('Internet','SMTP_Server','smtp.gmail.com');
setpref('Internet','SMTP_Username',email);
setpref('Internet','SMTP_Password',password);

props = java.lang.System.getProperties;
props.setProperty('mail.smtp.auth','true');
props.setProperty('mail.smtp.socketFactory.class', ...
                  'javax.net.ssl.SSLSocketFactory');
props.setProperty('mail.smtp.socketFactory.port','465');

%ここで sendmail を使ってテストメールを送っている
%ここに設定するアドレスは gmail のものではなくて大丈夫。
%自分の gmail 経由で目的のアドレスにメールが送られてきます
sendmail(email, 'Gmail Test', 'This is a test message.');
```
GooglePlayGameServices実装時のチェックリスト的なもの

#経緯
GooglePlayGameServices（以下、GPGSと記述）関連の実装をしてみましたが、必要な箇所を調べつつ実装したり動作確認したり修正したり、という作業が非常に面倒でした。
調べた情報が古かったりすることも多かったので、今後の自分用のメモを兼ねてQiitaに投稿しておきます。
何か抜けていることや間違っていることなどありましたらコメント・編集リクエストなど下さると助かります:bow:

なお、基本的にリリース前（テスト段階）でのチェックを想定しています。
もしかするとリリース後だと事情が変わる部分があるかもしれない（そもそもリリース後にGPGS関連の実装をすることがあるかは分からないですが……）ので、お気をつけください。

#PackageNameを確認する
GooglePlayConsoleで登録しているPackageNameと一致しているか確認します。
具体的には

- `AndroidManifest.xml`の`<manifest>`要素内の`package`
- `build.gradle`の`defaultConfig`内の`applicationId`

あたりです。
もしGooglePlayConsoleに登録しているものと違っている場合、変更してあげる必要があります。

#app_idを確認する
GooglePlayConsoleで確認できるapp_idと一致しているか確認します。
基本的には`strings.xml`内に以下のように記載していることが多いかと思います。

```xml:strings.xml
<string name="app_id">1234567890</string>
```

#meta-dataを確認する
`AndroidManifest.xml`の`application`要素内に以下の記述があることを確認します。

```xml:AndroidManifest.xml
<meta-data android:name="com.google.android.gms.games.APP_ID"
           android:value="@string/app_id" />
<meta-data android:name="com.google.android.gms.version"
           android:value="@integer/google_play_services_version" />
```

なお、過去の情報を調べていると`"com.google.android.gms.appstate.APP_ID"`も必要という記述があったりしますが、[AppState APIは2015年春で削除されている](https://support.google.com/googleplay/android-developer/answer/6136246?hl=ja)ので不要かと思われます。

#テストユーザーを設定する
テスターに設定されていないアカウントではそのアプリのGPGSへ接続することは出来ません。
もしまだテスターを設定していない場合、GooglePlayConsoleの「設定→テスターの管理」からテスターのリストを追加することが可能です。
その他、[「アルファ版、ベータ版、内部テスト版のテストをセットアップする」](https://support.google.com/googleplay/android-developer/answer/3131213)などのドキュメントもチェックしておくと良いかと思います。

#端末のアカウントを確認する
上記全てを確認した後、テスター登録されたアカウントを使って動作確認を行うも以下のようなエラーに悩まされました。

```
E/GameAgent( 2425): Application [app_id] is not associated with package [PackageName]. Check the application ID in your manifest.
```

どうやら設定しているapp_idがパッケージ名と結びついていないという旨のことを言っているようです。
**そんなわけねーだろ。**
（一応GooglePlayConsoleで確認しましたが、どちらも正しい値でした）

実はこの時、使っている端末には2つのアカウントが紐付けられていました。
片方はテスター登録されたアカウント、もう片方はテスター登録されていないアカウントです。
ふと思い立ってテスター登録されていない方のアカウントの端末との紐付けを解除してみると、このエラーは発生しないようになりました:sweat:
テスター登録されていないアカウントが残っていれば絶対に発生するエラーなのかどうかは不明ですが、このエラーが解消されない場合には試してみるべきかもしれません。
ちなみに私はこのエラー調査に丸々1日使わされました:sob:
サインインに使っていない方のアカウントのせいだと判明した時には膝から崩れ落ちそうになりました……。
REST APIを無効にする

すべて無効にするのではなく，特定の機能を使う場合は，たとえば，

```php
disable_rest_api( false, [ 'oembed', 'contact-form-7' ] );
```

のように呼び出します（これで埋め込み機能とContact Form 7は有効のままとなります）．


```php:stinc/src/basic/blocker.php
function disable_rest_api( $force = true, $permitted_route = [] ) {
	if ( $force ) {
		remove_action( 'rest_api_init', 'create_initial_rest_routes', 99 );
		add_filter( 'rewrite_rules_array', function ( $rules ) {
			foreach ( $rules as $rule => $rewrite ) {
				if ( preg_match( '/wp-json/', $rule ) ) {
					unset( $rules[ $rule ] );
				}
			}
			return $rules;
		} );
		return;
	}
	add_filter( 'rest_pre_dispatch', function ( $result, $wp_rest_server, $request ) use ( $permitted_route ) {
		$route = $request->get_route();
		foreach ( $permitted_route as $r ) {
			if ( strpos( $route, "/$r/" ) === 0 ) return $result;
		}
		return new \WP_Error( 'disabled', [ 'status' => rest_authorization_required_code() ] );
	}, 10, 3 );
}
```
Redmineをコンテナ化しつつ、アップデートする

# Redmineをコンテナ化しつつ、アップデートする。

## 概要
VM上で立ったRedmineを雑にコンテナに移行した。 
ついでにバージョンもあげておいた。 (3.3.4.stable.16840 → 3.4.5.stable)
ので、メモを残す。

Redmineは公式のコンテナを使っていて、
既存のアプリをコンテナに包む話ではない。


## やったこと
・VM上にたったRedmineのDBから、ダンプを取る。
・ダンプをpostgresコンテナに流し込む。
・RedmineのDBアップデートをかける。
・Redmineを起動する。

## 手順
### VM上にたったRedmineのDBから、ダンプを取る。
RedmineのDBに繋いでDUMPを取る

```bash
pg_dump redmine > redmine_db.dump
```

### ダンプをpostgresコンテナに流し込む。
なんでもいいからコンテナにダンプを打ち込む。
自分はこんな感じで、雑にコンテナに流しこんだ。

**①公式のPostgresイメージをカスタマイズしてビルドする。**
Dockerfile

```dockerfile
FROM postgres:9.5.12

# ロケールを日本に設定
RUN localedef -i ja_JP -c -f UTF-8 -A /usr/share/locale/locale.alias ja_JP.UTF-8
ENV LANG ja_JP.utf8

# データベース初期設定処理を書いたスクリプトを配置
COPY initialize.sh /docker-entrypoint-initdb.d/initialize.sh
RUN chmod 755 /docker-entrypoint-initdb.d/initialize.sh

# DUMPの取り込み
COPY redmine.dump /redmine.dump
```
postgresのイメージは、
「/docker-entrypoint-initdb.d/」配下にスクリプトを配置すると、
コンテナ起動時に実行してくれる。

---

DB初期化用のスクリプト
initialize.sh

```bash
#!/bin/bash

set -e

psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
    CREATE USER redmine WITH PASSWORD '${REDMINE_DB_USER_PASS}';
    CREATE DATABASE redmine;
    GRANT ALL PRIVILEGES ON DATABASE redmine TO redmine;
EOSQL

psql redmine < /redmine.dump
```
コンテナ起動時に流れて、redmine用ユーザーとDBを作る。
ダンプもインポートする。

----

ビルドする。

```bash
docker build -t redmine-pgsql .
```


**②実行する**
PostgreSQLコンテナを起動する

```bash
docker run --name redmine-pgsql \
--rm \
-p 15432:5432 \
-e POSTGRES_PASSWORD=mysecretpassword \
-e REDMINE_DB_USER_PASS=hogepassword \
-d redmine-pgsql:latest
```


### RedmineのDBアップデートをかける。

**DB設定ファイルの作成**
database.yml

```yaml
production:
  adapter: postgresql
  database: redmine
  host: postgres
  username: redmine
  password: "hogepassword"
  encoding: utf8
```

**データベースのアップデート実行**

```bash
docker run \
--rm \
--name redmine \
--link redmine-pgsql:postgres \
-v "$PWD/database.yml":"/usr/src/redmine/config/database.yml" \
redmine bundle exec rake db:migrate RAILS_ENV=production
```

Redmineのコンテナを使って、db:migrateを実行する。
（いちいち、これのためにRedmineインストールするのが億劫だった）

---


### Redmineを起動する。
**redmineのコンテナを実行**

```bash
docker run -d \
--rm \
--name redmine \
--link redmine-pgsql:postgres \
-p 3000:3000 \
-e REDMINE_DB_USERNAME=redmine \
-e REDMINE_DB_PASSWORD=hogepassword \
-e REDMINE_DB_POSTGRES=postgres \
redmine
```
これで動くようにはなっているはず。

---

## おわりに
コンテナを削除するたびデータが飛ぶイカれた感じの構成なので、
今後、データの永続化とかをやってこうと思う。
（今回はしっかり作り上げることを目的にしていない）


トライアンドエラーで作って壊して、アップグレートを試せてよかった。
Redmineのインストールも面倒に感じていたが、
コンテナで実行することでスキップできた。

こういうところは、コンテナの素敵な所だと思う。
埋め込み機能を無効にする

記事の編集画面で，本文にURLを張り付けると，自動的にカードのような表示になる機能を無効にします．利用者によっては意図していない表示となる場合があるためです．

```php:stinc/src/basic/blocker.php
function disable_embed() {
	add_filter( 'embed_oembed_discover', '__return_false' );
	add_filter( 'embed_oembed_html', function ( $cached_html, $url, $attr, $post_id ) {
		global $wp_embed;
		return $wp_embed->maybe_make_link( $url );
	}, 10, 4 );
}
```
ファイル編集機能を無効にする

管理画面からテーマ・ファイルを編集できないようにします．万が一の場合を考えてと，利用者が不用意に触ってしまうことを避けるのが目的です．

```php:stinc/src/basic/blocker.php
function disable_file_edit() {
	if ( ! defined ( 'DISALLOW_FILE_EDIT' ) ) {
		define( 'DISALLOW_FILE_EDIT', true );
	}
}
```
Kubernetesで複数のPodのログを同時にtailする

[kubetail](https://github.com/johanhaleby/kubetail)を使うと簡単にログを確認することができます。

<img width="696" alt="admin_ip-172-20-47-164___.png" src="https://qiita-image-store.s3.amazonaws.com/0/7565/7ad0fc5b-c5d1-cf92-8cb5-2741de73514e.png">


## インストール

macOSの方はbrewでインストールできます。

```
brew tap johanhaleby/kubetail && brew install kubetail
```

その他の環境の場合はbashで書かれているので、https://raw.githubusercontent.com/johanhaleby/kubetail/master/kubetail このファイルをダウンロードして適切な場所に配置します。

## Serviceに含まれるPodのログを確認する

```
kubetail {$service_name}
```

## Podの名前を複数指定してログを確認する

```
kubetail app
```

`app` から初まるPod名のPodが対象になります。

## 参考

* [GitHub kubetail](https://github.com/johanhaleby/kubetail)
samba でどうしてもログインに失敗するときの解決法

Samba でディレクトリ共有するときにハマったのでここに書き記す。

server: centos7
client: windows10
samba version: 4.6.2

## 適当にググって出てきたサイト通りにやる
[Samba Server Installation and Configuration on CentOS 7](https://www.howtoforge.com/samba-server-installation-and-configuration-on-centos-7)の通りにやる。
英語が嫌な方は[centos7にsambaをインストール](https://orebibou.com/2014/12/centos7%E3%81%ABsamba%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/)でもだいたい変わらない気がする。

## ログインできない
↑の通りにやっていると、 `guest ok = yes` のディレクトリまでは順調に進んだが、ログインを必要とするディレクトリはうまくいかなかった。
何度 Windows で接続してもログインで失敗するのだ。

（ `guest ok = yes` のディレクトリにも接続できない場合はこの記事は役に立たないと思う。）

## 解決した
長い時間ハマって途方に暮れた時、救世主が現れた。
[Samba 4.5以降のNTLMv1認証](https://www.miyabi-solutions.com/blog/?p=1910)

ちなみに [global] に書かないと動作してくれなかった。

```
[global]
	...
	ntlm auth = yes

[...]
```

あなたもこれで解決できることを願う。
セキュリティ的に良いかは知らない。
XML RPCを無効にする

使っていない機能は無効にします．

```php:stinc/src/basic/blocker.php
function disable_xml_rpc() {
	add_filter( 'xmlrpc_enabled', '__return_false' );
	add_filter( 'xmlrpc_methods', function ( $methods ) {
		unset( $methods['pingback.ping'] );
		return $methods;
	} );
}
```
ジェネレーター出力を無効にする

出力されることに特別なリスクがあるとは思いませんが，意図していない情報が表に出てしまうのを避けるために，無効にします．各所に出力されるので，列挙しています．

```php:stinc/src/basic/blocker.php
function disable_generator_output() {
	$actions = [
		'rss2_head',
		'commentsrss2_head',
		'rss_head',
		'rdf_header',
		'atom_head',
		'comments_atom_head',
		'opml_head',
		'app_head'
	];
	foreach ( $actions as $action ) {
		remove_action( $action, 'the_generator' );
	}
}
```
著者ページを無効にする

複数の著者が書くブログのようなウェブサイトでなければ，そもそも著者ページは必要ありませんし，セキュリティ上よいことではありませんが，ユーザーIDがよくあるものになっている場合，第三者によってそのことを確認するためにアクセスされてしまうので，無効にします．

```php:stinc/src/basic/blocker.php
function disable_author_page() {
	add_filter( 'author_rewrite_rules', '__return_empty_array' );
	add_filter( 'author_link', '__return_empty_string' );

	add_filter( 'parse_query', function ( $query ) {
		if ( ! is_admin() && is_author() ) {
			$query->set_404();
			status_header( 404 );
			nocache_headers();
		}
	} );

	// Remove authors from feeds
	add_filter( 'the_author', function ( $author ) {
		return is_feed() ? get_bloginfo( 'name' ) : $author;
	} );
	add_filter( 'the_author_url', function ( $author_meta ) {
		return is_feed() ? home_url() : $author_meta;
	} );
}
```
ActiveRecordの暗黙の型変換について再認識

## 前置き
これを無意識に使用すると ActiveModelなどで思わぬ所ではまることがあります。
共有と再認識の意を込めて記事にしました。

## 概要
- ActiveRecordは代入時に型変換を行います。
- 型変換後も、型変換前の値を取得できます。

## 検証環境
- Rails5.1

## 検証

### マイグレーション例
```
class CreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      t.string   :name
      t.integer  :age
      t.datetime :birthday

      t.timestamps null: false
    end
  end
end
```

### 呼び出し例
```
user = User.new(age: '20')
user.age                   # => 20
user.age.class             # => Fixnum

user = User.new(birthday: '20180418')
user.birthday                         # => Wed, 18 Apr 2018 00:00:00 UTC +00:00
user.birthday.class                   # => ActiveSupport::TimeWithZone
```

### Nilになるケース例
```
user = User.new(birthday: '')
user.birthday                  # => nil
user.birthday.class            # => NilClass

user = User.new(birthday: 'dmm')
user.birthday                  # => nil
user.birthday.class            # => NilClass

user = User.new(birthday: 20180418)
user.birthday                  # => nil
user.birthday.class            # => NilClass
```

## キャストされる前の値の取得
```
user = User.new(birthday: '20180418')
user.birthday                                    # => Wed, 18 Apr 2018 00:00:00 UTC +00:00
user.birthday.class                              # => ActiveSupport::TimeWithZone
user.read_attribute_before_type_cast('birthday') # => 20180418
```

## 参考 (GithubのActive Modelのテスト)
- https://github.com/rails/rails/blob/5-1-stable/activemodel/test/cases/type/date_time_test.rb
Populusでテストするとき、FileNotFoundError: No populus project found for testingと出るとき

# 環境
populus 2.2.0

# 現象
```
FileNotFoundError: No populus project found for testing in /Users/hidehiro/code/hidehiro98/populus_test

../../../.pyenv/versions/anaconda3-5.0.0/lib/python3.6/site-packages/populus/plugin.py:60: FileNotFoundError
```

# 解決策
`defaults.v8.config.json`をプロジェクトのルートにコピーして、`project.json`とリネームする。
コマンド例: `cp ../../../.pyenv/versions/anaconda3-5.0.0/lib/python3.6/site-packages/populus/assets/defaults.v8.config.json project.json`

# 参考
https://github.com/ethereum/populus/issues/414#issuecomment-352265217
https://github.com/ethereum/populus/issues/452
自己紹介

takepesoといいます。
Qiitaはずっと閲覧する側だったのですがせっかくなので書いてみようと思いました。
よろしくお願いいたします。

## 経歴
2013年ごろにWEBサービスの会社にディレクターとして新卒入社。
社会人になってはじめてHTMLとCSSというものをちゃんと知りました。
フロントエンド、アクセス解析、データ分析に興味があって日々勉強中。
ペンギンがとても好き。

## 書いていきたいもの
主にWEBディレクター向けツールについてとか

- プロトタイピングツール
- GoogleTagManger
- GoogleAnalytics
- フロントエンド回り

## やっていきたいもの
- 統計学（ちゃんと勉強してないので）
- Python
PowerShell と Scoop でWindows開発環境を整える

ガッツリLinux環境を構築したい人向け -> [WSLでWindowsにLinux開発環境を構築する](https://qiita.com/taquaki-satwo/items/b379a141492ce8927deb)

# Scoopとは

コマンドラインで操作するパッケージマネージャ。
Homebrewやapt-get的なもの。
WindowsでもLinuxと同じようにツール類を扱いたい人向け。

詳しくはGitHubのWiki （[So What?](ttps://github.com/lukesampson/scoop/wiki/So-What%3F)） を参照。

# 手順

今回はScoopを使ってNode.jsをインストールする。

## 1. Scoopのインストール

power shellを起動し次のコマンドを入力。

```
iex (new-object net.webclient).downloadstring('https://get.scoop.sh')
```

もしエラーが出たら次を入力。

```
Set-ExecutionPolicy RemoteSigned -scope CurrentUser
```

## 2. Node.jsをインストール

Scoopはパッケージをbucketと呼ばれるもので管理している。
まず、Node.jsを `scoop search` コマンドで検索する。

```
scoop search node
'main' bucket:
    eventstore (4.1.0) --> includes 'EventStore.ClusterNode.exe'
    node-chakracore (8.11.1)
    nodejs-lts (8.11.1)
    nodejs (9.11.1)
    sliksvn (1.9.7) --> includes 'svn-populate-node-origins-index.exe'
```

`'main' bucket`に存在する `nodejs-lts (8.11.1)` と `nodejs (9.11.1)` がインストールできることがわかる。

ではNode.jsをインストールする。

```
scoop install nodejs
...中略
'nodejs' (9.11.1) was installed successfully!
```

このようにScoopは常に最新のパッケージがインストールされる。

## 3. versions bucketをインストール

Scoopには~envのようなバージョン管理はなく、そのかわりに `version bucket` をインストールした上でバージョンの違うパッケージをインストールする。

```
scoop bucket add versions
```

もう一度Node.jsを検索する。

```
scoop search node
'main' bucket:
    eventstore (4.1.0) --> includes 'EventStore.ClusterNode.exe'
    node-chakracore (8.11.1)
    nodejs-lts (8.11.1)
    nodejs (9.11.1)
    sliksvn (1.9.7) --> includes 'svn-populate-node-origins-index.exe'

'versions' bucket:
    nodejs010 (0.10.48)
    nodejs012 (0.12.18)
    nodejs4 (4.9.1)
    nodejs6 (6.14.1)
    nodejs7 (7.10.1)
    nodejs8 (8.11.1)
    nodejs9 (9.11.1)
```

`'versions' bucket` に存在するバージョン違いのNode.jsがインストールできるようになる。

```
scoop install nodejs8
...中略
'nodejs8' (8.11.1) was installed successfully!
node -v
v8.11.1
```

## 4. バージョンの変更

`scoop reset` コマンドを使う。

```
scoop reset nodejs
Resetting nodejs (9.11.1).
Linking ~\scoop\apps\nodejs\current => ~\scoop\apps\nodejs\9.11.1
node -v
v9.11.1
```

また、bucketは自作することができ、Scoopに登録されていないパッケージもインストールできるそうな。

# おまけ

### `scoop uninstall` で ` 〜を削除できません: パス '〜' の一部が見つかりませんでした。` と表示されたら

インストールされたパッケージのファイルパスが長いせいかと思われる。下記を参考にディレクトリのリネームを試す。

> [Can't uninstall nodejs; larger problem afoot · Issue #478](https://github.com/lukesampson/scoop/issues/478#issuecomment-135579615)

### bashでScoopが使えるかどうか

使えるけどScoopが実行されるたびにPowerShellが起動されるから効率悪い。

> [Can I use Scoop in bash?](https://github.com/lukesampson/scoop/wiki/Can-I-use-Scoop-in-bash%3F)

# 参考にした記事

* Scoop 公式: [Scoop](http://scoop.sh/)
* Scoop Wiki: https://github.com/lukesampson/scoop/wiki
* [Scoop と PackageManagement を使った Windows 環境の構築](https://qiita.com/kikuchi_kentaro/items/77793e4a21db6ffdb7cd)
* [ScoopでWindowsにおける開発環境構築を最適化しよう | さにあらず](https://blog.satotaichi.info/scoop/)
Anacondaのインストールでとらぶった話　【解決済み？】

もう二度とあって欲しくないが、とりあえず備忘録代わりに。

【症状】
Anacondaのインストールができないいや正確に言うと、インストール後にAnaconda navigatorが立ち上がらずJupyter NoteBook・Spyderも立ち上がらない。

【環境】
Windows7 SP1
Windows 64 bit
Anaconda 5.1.0
Python3.6.4 

【原因調査】
仕方ないのでとりあえずアンインストールしてから、もう一回いれるとAnacondaのメニューにAnaconda promptしかない・・・。更にAnaconda promptにはactivate.batが無いとか言われる。

なんじゃこのエラーはのレベルとりあえずAnaconda PromptからPythonが動くかみてみる・・・動かないそんなコマンドは無いと言われる。仕方が無いと思いつつPythonの実行ファイルがある場所にターミナルを移動して、実行しようとする。

```
'cd'は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチファイルとして認識されていません。
```


***は？*** 自分の目を一瞬疑ってしまった。とりあえず何をやってこうなったか聞いてみると
「パスを書いたら動かなくなったらしい」
ふむふむと環境変数パスを確認すると、システム環境変数PathとユーザーPathがGraphVizのソフトの実行ファイルのパスのみなっている・・・orz
いやこれどうやって直すんだよ。。。と思いつつとりあえず原因はwindowsのコマンドが全部吹っ飛んだため、
インストールはAnaconda無事にされたように見えるが、エラー等は吐かず実行されるようである。

【解決方法】
とあえずC:\Windows\System32、Systemroot、Systemroot¥system32、Systemroot¥system32¥wbem辺りを追加する。ドライバー？そんなもん知らんといいつつも一度Anacondaから入れなおすがCの C1083: Cannot open include file: 'io.h': No such file or directoryやら様々なエラーがでる。調べるとWindows SDKを入れると直るらしいが、下の方が盛大に壊れているようで当然windows SDKも入らない。SDKやRuntimeも入れるついでにVisual Studioを入れてみるが、何やら個別項目にAnacondaがある。知らんけどもとりあえずこっちから入れてみる。あれそして何故か動く。

【教訓】
自分で下手にAnaconda入れて、Visual Studio のソフト関連とC++のpathリンクを頑張るよりもVisual StudioからAnaconda入れて見ると上手くPATHの設定やらをやってくれるようである。



注意：パス消した時点でクリーンインストールしたかったが、クリーンインストールすると社内規定上一度会社のシステム部にパソコンを預け社内基準にしないといけないという謎の工数が発生してしまい、間に合う気がしなかったため泣きながら直すことになった。
rbenvでruby2.2.1をインストールした時に出たエラーメモ（Ubuntu 16.04）

出たエラー↓

```sh
 % rbenv install 2.2.1
Downloading ruby-2.2.1.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.1.tar.bz2
Installing ruby-2.2.1...

WARNING: ruby-2.2.1 is nearing its end of life.
It only receives critical security updates, no bug fixes.


BUILD FAILED (Ubuntu 16.04 using ruby-build 20180224)

Inspect or clean up the working tree at /tmp/ruby-build.20180418140914.24400
Results logged to /tmp/ruby-build.20180418140914.24400.log

Last 10 log lines:
./libffi-3.2.1/.libs/libffi.a: error adding symbols: 不正な値です
collect2: error: ld returned 1 exit status
Makefile:325: ターゲット '../../.ext/x86_64-linux/fiddle.so' のレシピで失敗しました
make[2]: *** [../../.ext/x86_64-linux/fiddle.so] エラー 1
make[2]: ディレクトリ '/tmp/ruby-build.20180418140914.24400/ruby-2.2.1/ext/fiddle' から出ます
exts.mk:177: ターゲット 'ext/fiddle/all' のレシピで失敗しました
make[1]: *** [ext/fiddle/all] エラー 2
make[1]: ディレクトリ '/tmp/ruby-build.20180418140914.24400/ruby-2.2.1' から出ます
uncommon.mk:189: ターゲット 'build-ext' のレシピで失敗しました
make: *** [build-ext] エラー 2
```

↓で解決

```sh
 % sudo apt-get install libffi-dev
```
コメント関連機能を無効にする

WordPressをブログとしてよりも，組織などのウェブサイトとして使う際は，必要でないコメント機能を初めから無効にしておいた方が，スパム・コメントに悩まされずに済みます．

## 管理画面のコメント機能を無効にする

```php:stinc/src/basic/antispam.php
function disable_comment() {
	remove_post_type_support( 'post', 'comments' );
	remove_post_type_support( 'page', 'comments' );

	add_filter( 'comments_open', '__return_false' );
	add_filter( 'comments_array', '__return_empty_array' );
	add_filter( 'comment_reply_link', '__return_false' );
	add_filter( 'comments_rewrite_rules', '__return_empty_array' );

	$counts = wp_count_comments();
	$sum = 0;
	foreach ( $counts as $key => $val ) {
		$sum += $val;
	}
	if ( $sum === 0 ) {
		add_action( 'admin_menu', function () {
			remove_menu_page( 'edit-comments.php' );
		} );
		add_action( 'admin_bar_menu', function ( $wp_admin_bar ) {
			$wp_admin_bar->remove_menu( 'comments' );
		}, 300 );
	}
}
```

## コメント・フィード機能を無効にする

```php:stinc/src/basic/antispam.php
function disable_comment_feed() {
	remove_theme_support( 'automatic-feed-links' );

	add_filter( 'feed_links_show_comments_feed', '__return_false' );
	add_filter( 'post_comments_feed_link_html', '__return_empty_string' );
	add_filter( 'post_comments_feed_link', '__return_empty_string' );
	add_filter( 'feed_link', function ( $output ) {
		return ( false === strpos( $output, 'comments' ) ) ? $output : '';
	} );
	remove_action( 'do_feed_rss2', 'do_feed_rss2' );
	remove_action( 'do_feed_atom', 'do_feed_atom' );
	add_action( 'do_feed_rss2', function ( $for_comments ) {
		if ( !$for_comments ) load_template( ABSPATH . WPINC . '/feed-rss2.php' );
	} );
	add_action( 'do_feed_atom', function ( $for_comments ) {
		if ( !$for_comments ) load_template( ABSPATH . WPINC . '/feed-atom.php' );
	} );
}
```

## トラックバック機能を無効にする

```php:stinc/src/basic/antispam.php
function disable_trackback() {
	remove_post_type_support( 'post', 'trackbacks' );
	remove_post_type_support( 'page', 'trackbacks' );

	add_filter( 'pings_open', '__return_false' );
	add_filter( 'site_url', function ( $url, $path, $scheme, $blog_id ) {
		return ( false === strpos( $path, 'xmlrpc.php' ) ) ? $url : '';
	}, 10, 4 );
	add_action( 'template_redirect', function () {
		if ( is_trackback() ) {
			global $wp_query;
			$wp_query->set_404();
			status_header( 404 );
			nocache_headers();
		}
	} );
}
```
docker-knowledge インストールメモ

https://github.com/support-project/docker-knowledge

```bash
$ git clone https://github.com/support-project/docker-knowledge.git
$ cd docker-knowledge
$ docker-compose up -d
```

注意としてldapやsmtpを使う場合は、Dockerfileでポート開放を追加する。
smtpなら25(認証なし)を開ける。
aws-cliでインスタンス名で絞り込んでNameとInstanceIdだけにする。


```
aws ec2 describe-instances --filters "Name=tag:Name,Values=<絞り込む名前>" \
| jq '.Reservations[].Instances[]' \
| jq -r '{"name": (.Tags[] | select(.Key == "Name").Value), "id": .InstanceId}'
```
コミュニケーション

・時間のない時の質問
短い時間に確認できること
質問の答えにより自分のその後の行動が変えられるものから聞く
そうでなければ時間がある時に

・相手の意図との整合性を確かめる時は、
　「〜という想定ですが、これであっていますか？」
・宙に投げるようなオープンクエスチョンは避けるべき？

・データソースがわからない時は、分かる人を探すかつ分かる人を探してもらえる人を探す
Openrec の読み上げ Chrome Extension を作ってみた。

# openrec スピーチ

Splatoon が大好きで実況とかもたまにみるので Openrec の読み上げ extension を作ってみました。


[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/vSZWiIMwUdg/0.jpg)](http://www.youtube.com/watch?v=vSZWiIMwUdg)


インストールはこちら
[openrecスピーチ](https://chrome.google.com/webstore/detail/heafjkmnmjofnclmhimleodkhcibpgbj/publish-accepted?hl=ja)

リポジトリは [https://github.com/coa00/openrec_speech](https://github.com/coa00/openrec_speech)

## 読み上げエンジン

ブラウザに搭載されている[speechSynthesis](https://developer.mozilla.org/ja/docs/Web/API/Window/speechSynthesis)をそのまま使いました。

これだけのコードで喋らせることができます。

```js
const utterThis = new SpeechSynthesisUtterance('読み上げるよー'); |
speechSynthesis.speak(utterThis); |
```

## チャットの更新を検知

dom の更新の検知方法ですが、今回は chrome の Extension なので実験的な　[MutationObserver](https://developer.mozilla.org/ja/docs/Web/API/MutationObserver)を使うことにしました。

やることを簡単に書くと

- 増減を監視したい DOM を取得する
- 増えた時の処理を書く（MutationObserver　のコールバックに設定）

ソースはこんな感じです。

```js
// 監視したいDOM
const liveChatList = document.getElementsByClassName('js-liveChatList')[0]

// オブザーバインスタンスを作成
const chatListObserver = new MutationObserver((mutations) => {
  mutations.forEach((mutation) => {
    const li = mutation.addedNodes.item(1);
　　　　　　　　　// li からテキストを取り出して喋らせる

  });
});

// オブザーバの設定
// 子要素の増加を知りたいのでchildList
const listConfigs = { childList: true };

// 対象ノードとオブザーバの設定を渡す
chatListObserver.observe(liveChatList, listConfigs);
```

## extension の作り方

extension には色々種類はあるのですが、今回は特定のサイトだけで動作する　content_scripts　にしました。

manifest.json を下記のようにします。

```json

  "content_scripts": [
    {
      "matches": ["https://www.openrec.tv/live/*"],
      "js": ["openrec_voice.js"]
    }
  ]
```

https://www.openrec.tv/live/　

から始まるパスにアクセス時に、JS を呼び出すといった動きを実現できます。

[このあたり](https://developer.chrome.com/extensions/getstarted)を参考にしました。

### icon のバリエーションを作るのがめんどくさい。

アイコンをストアに公開するにあたり作らないといけないのですが、地味に面倒でした。
Mac はコマンドラインでリサイズしてくれました。

```
sips -Z 16 source.png --out icon16.png  
sips -Z 48 source.png --out icon48.png  
sips -Z 128 source.png --out icon128.png  
```

素晴らしい。

ストアに公開するのに初期費用　5　ドル必要でした。まあいいかと思って払いました。
【PHP】header関数が使えない環境でのリダイレクト処理の実装方法とは


# header関数が使えない

header関数が使えない。使えない。~~勘弁してくれ~~。
ではheader関数以外でリダイレクトさせるにはどうすりゃいいのかにゃー:cat:？

# header関数が使える環境での書き方

普通（？）だったらこんな感じで書くんですけど、こういう書き方ができない

```hoge.php
<?php

// ～なんかの処理～

// checkError()・・・処理の結果が正常ならtrue、異常ならfalseを返す関数
if(checkError($result) !== true) {
    // 処理の結果が正常でないならheader関数でTOPページにリダイレクトさせる
    header('Location: ./', true);
    exit;
}
```

# header関数が使えない環境での代替案

## JavaScriptでリダイレクトさせる

まあHTML読み込んでからでも支障ないのかなとは思うのですが、
`echo`で出力させつつリダイレクトさせるのが早いかなと思いましたのでこんな感じで書いてみました。

```hoge.php
<?php

// ～なんかの処理～

// 処理の結果が正常でないならJavaScriptでTOPページにリダイレクトさせる
if(checkError($result) !== true) {
    echo '
        <script type="text/javascript">

        setTimeout("redirect()", 0);

        function redirect() {
            location.href="https://**********************/";
        }

        </script>';
    exit;
}
```

## HTMLのmetaタグでリダイレクトさせる

無理やりな感じもするのですが、一応動作はします。（本来はheadタグ内に記述すべきですが）
エラーメッセージ表示させたりする場合はアリかなぁ・・・？（JavaScript版でもできるやんて話ですが）

```hoge.php
<?php

// ～なんかの処理～

// 処理の結果が正常でないならmetaタグでTOPページにリダイレクトさせる
if(checkError($result) !== true) {
    echo '<meta http-equiv="refresh" content="5;URL=https://**********************/">
          <p>エラーが発生しました。エラーコード：******<br/>5秒後にTOPページへ戻ります。</p>';
    exit;
}
```

# おわり
- SEO？考慮してないすね・・・
- リダイレクトさせずにエラーページを`include 'error.html'`みたいに読み込んでもありかもしれません。
- `checkError`関数の名前のセンスがあれですけど、正常なら`true`、異常なら`false`を返す関数です。
- なにかいい案をお持ちの方、コメント待ってます。
BigQueryで、CROSS JOINを使わずに配列から重複を省く

#はじめに
BigQueryで、配列から重複を省く方法です。

#シンプルな場合
重複アイテムを持つ配列内の重複を削除します。

```sql
#standardSQL
WITH T_SAMPLE AS(
  SELECT 'id1' id, ['item1', 'item2', 'item2'] items
  UNION ALL SELECT 'id2', ['item1', 'item2']
  UNION ALL SELECT 'id3', ['item10', 'item11', 'item10']
)

SELECT 
  id,
  (SELECT ARRAY_AGG(DISTINCT items_list) FROM UNNEST(T_SAMPLE.items) items_list) items
FROM 
  T_SAMPLE
```

|クエリ実行前のテーブル |実行後のテーブル |
|---|---|
|T_SAMPLE||
|<img width="135" alt="スクリーンショット 2018-04-20 6.31.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/155165/712b86c1-b117-9eae-74f7-6841d1f4c559.png">|<img width="140" alt="スクリーンショット 2018-04-20 6.28.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/155165/315efd3f-8f2e-e1d4-8a0e-b0accbdccdd0.png">|

#集約しつつ重複を省く場合
サブクエリでいったん配列を結合してから、同様に集約します。（しか無い？）

```sql
#standardSQL
WITH T_SAMPLE AS(
  SELECT 'id1' id, ['item1', 'item2', 'item2'] items
  UNION ALL SELECT 'id1', ['item1', 'item2']
  UNION ALL SELECT 'id3', ['item10', 'item11', 'item10']
)

SELECT 
  id,
  (SELECT ARRAY_AGG(DISTINCT items_list) FROM UNNEST(items) items_list) items
FROM(
  SELECT 
    id,
    ARRAY_CONCAT_AGG(T_SAMPLE.items) items
  FROM 
    T_SAMPLE
  GROUP BY
    id
)
```
|クエリ実行前のテーブル |実行後のテーブル |
|---|---|
|T_SAMPLE||
|<img width="132" alt="スクリーンショット 2018-04-20 6.53.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/155165/d503a0ba-6a45-c59f-3462-8ea097707c67.png">|<img width="132" alt="スクリーンショット 2018-04-20 6.53.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/155165/b8678434-d3a9-f0bd-dde7-683035ef8652.png">|



#おわりに
最近は、AWS Athenaも使っていきたいです。
【シェル 改行コード】rails aborted! ' (see --tasks)to build task 's が出るときの対処

## 改行コードには気を付けよう！
結論です

## 問題の詳細
Windows10上で改行コード**CRLF**で以下のシェルを書いて実行しようとしていました。
2行目は開発途中でherokuにアップロードしたりする際に使ったのでとりあえずコメントアウトしてました。

```shell:改行コードCRLFの闇
service mysql start && rails db:create && rails db:migrate && rails s
# rails db:migrate && rails s -b 0.0.0.0 -p $PORT
```

実行すると以下のエラーが

```shell:CRLF
rails aborted!
' (see --tasks)to build task 's
…
…
bin/rails:3:in `load'
bin/rails:3:in `<main>'
(See full trace by running task with --trace)

```

なんだ・・・何が悪いんだ・・・？と思い色々やってみると以下のことが分かりました

* Mac上で動かすと上手くいく
* 1行だと上手くいく

もしやこれは改行コードか・・・と思い、VSCodeで確認してみるとCRLFになってる・・・
LFに変えたら動きました・・・！
初めて改行コードがらみの問題に当たってちょっとうれしいやら悲しいやら笑

## 結論
シェルを書くときは改行コードはLFにしよう！！（当たり前）
Soracomスターターキットで作るGPSなしの位置情報トラッカー ~その1~

Soracomスターターキットで3G接続したRaspberry PIと
Google Geo Location APIを使って、GPSなしのGPSトラッカーを作成したときのメモです。

[https://github.com/ymmtyuhei/geolog](https://github.com/ymmtyuhei/geolog)

# Bill of Materials

 - Raspberry PI 3+
 - [Soracomスターターキット](https://www.switch-science.com/catalog/2767/)
 - ポータブルUSBバッテリー


![F47F157F-C45B-4601-9840-79177CE42A35.jpg](https://qiita-image-store.s3.amazonaws.com/0/6968/65f58847-7a68-1d0f-9b5c-228e515f177e.jpeg)



# 準備

## Raspberry PIを3G接続する
[SORACOM x RaspberryPi ハンズオン - 3G接続- ](https://github.com/soracom/handson/blob/master/setup/setup.md)

## Google Geolocation キーを取得
[キーの取得、認証](https://developers.google.com/maps/documentation/geolocation/get-api-key?hl=ja)

## Ambient

サインアップ・ログインし、チャンネル一覧から「チャンネルを作る」

[Ambient　「チャンネルを作る」](https://ambidata.io/ch/channels.html)

「グラフ種類」「地図」のチャートを設定します

<img width="1181" alt="スクリーンショット 2018-04-13 20.17.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/6968/f3717e18-8d92-7ae9-a3d0-9aaaf8225ce9.png">


# 環境構築

## ソフトウェア

SSID取得、GeolocationAPI、Ambientへ送信する、簡単なスクリプトをNode.jsで書きました。
先に取得したGeolocation APIのトークンと、Ambientのトークンをスクリプトに設定して下さい。

[https://github.com/ymmtyuhei/geolog](https://github.com/ymmtyuhei/geolog)

## 永続化

さきのNode.jsのスクリプトを[PM2](http://pm2.keymetrics.io/)で永続化する設定をしました。

```shell
npm install pm2 -g 
pm2 start GeoLog/index.js
pm2 save
pm2 startup
```

# Ambient上で確認 

Ambient上に位置情報がプロットされます

<img width="1162" alt="スクリーンショット 2018-04-16 13.03.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/6968/7030c6c6-2f4a-5ddd-2fb6-f951fda9624e.png">


# 運用にかかった費用

１時間ほど動かしてみたところ、以下のような転送量が確認されました。

種別 | １時間あたり転送量 | １時間あたり転送量(その２)
---|---|---
上り | 52.3KiB (0.05107 MiB) | 113.7KiB
下り | 188.2KiB (0.18379 MiB) | 69.5KiB

\* s1.standard 上り0.24 円/MB 下り0.8 円/MB

<img width="889" alt="スクリーンショット 2018-04-16 12.37.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/6968/5686e42e-75c1-10e5-fca2-3ce037a05b7f.png">


# その２へ続く

今回はRaspberry PI上からGeolocation APIへ直接リクエストを送りましたが、
AWS IoTとLambdaを使って、SSIDを取得した以降の処理をクラウドで実行したいとおもいます。

[Soracomスターターキットで作るGPSなしの位置情報トラッカー ~その2 AWS IoT連携~](https://qiita.com/ymmtyuhei/items/bc4670820030c312b817)
SFDC Lightning開発時エラー集

Salesfroce(SFDC) Lightning コンポーネントの開発時のエラー集
ここにためていこうかなと。


１．コンポーネントのコンパイルエラーその１
==
※Lightiningコンポーネント（Lightning Component）実装時に以下のコンパイルエラーとなる。

```
must be followed by either attribute specifications, ">" or "/>"
```

３０分ほどしらべる。時間持った稲。

## 事由
全角スペースがコンポーネント中に存在するとでます。

例：
&lt;lightning:select 　name="Namae" value="VALUU"&gt;
selectとnameの間に全角スペースがいる。

## 教訓
　全角スペースはエディターを目で見てわかるようにしましょう。