OmniAICreator/Qiita-1.07M huggingface dataset:
カラムの型を time から datetime に変更する

time 型のカラムを datetime 型に変更しようとした際に以下のエラーがでました。

```bash
$ rails db:migrate
(中略)
PG::DatatypeMismatch: ERROR:  column "カラム名" cannot be cast automatically to type timestamp without time zone
HINT:  You might need to specify "USING カラム名::timestamp without time zone".
: ALTER TABLE "テーブル名" ALTER COLUMN "カラム名" TYPE timestamp
```

結論からいうと、time 型から datetime 型への変換はできないので、(time 型のカラムの日付がわからないため)

1. time 型のカラムを削除
2. datetime 型で該当カラムをもう一度追加
 
とすることで解決しました。

カラムの追加と削除については、[Ruby on Rails カラムの追加と削除](https://qiita.com/azusanakano/items/a2847e4e582b9a627e3a) という記事にわかりやすくまとめてあります。

## 参考

[Rails & Postgres: Migration to change_colomn gives error “cannot be cast to type timestamp without time zone”](https://stackoverflow.com/questions/5522520/rails-postgres-migration-to-change-colomn-gives-error-cannot-be-cast-to-type)
Eloquentを使ってみて、timestampでエラーになる件

アプリケーションを移行している際に、DBの処理をEloquentに移行しました。
タイムスタンプの部分でエラーが出続けたため、試行錯誤した結果です。

# 現象

いまのサービスのtimestamp型に入っているデータで、ミリ秒まで入っているデータとミリ秒がないデータがありPHPのDatetime型にうまく変換してくれない状態です。

データベースのデータを修正する方針でもよかったけど、他のプロジェクトも直す必要があったため、Eloquent側で対応してみました。

登録する際になるエラーを対応した内容です。

# 対応内容

Modelクラスの$datasにカラムを指定すると、Carbonに変換してくれるみたいですね。

$datesに指定すると、asDateTime関数に処理が任されるため、オーバーライドして、全部ミり秒ありに変換して対応です。

```php

<?php

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;

class AppEloquent extends Illuminate\Database\Eloquent\Model
{
    public function getDateFormat()
    {
        return 'Y-m-d H:i:s.u';
    }

    /**
     * オーバーライド
     * @param  [type] $value [description]
     * @return [type]        [description]
     */
    protected function asDateTime($value)
    {

        // If this value is already a Carbon instance, we shall just return it as is.
        // This prevents us having to re-instantiate a Carbon instance when we know
        // it already is one, which wouldn't be fulfilled by the DateTime check.
        if ($value instanceof Carbon) {
            return $value;
        }

        // If the value is already a DateTime instance, we will just skip the rest of
        // these checks since they will be a waste of time, and hinder performance
        // when checking the field. We will just return the DateTime right away.
        if ($value instanceof DateTimeInterface) {
            return new Carbon(
                $value->format('Y-m-d H:i:s.u'), $value->getTimezone()
            );
        }

        // If this value is an integer, we will assume it is a UNIX timestamp's value
        // and format a Carbon object from this timestamp. This allows flexibility
        // when defining your date fields as they might be UNIX timestamps here.
        if (is_numeric($value)) {
            return Carbon::createFromTimestamp($value);
        }

        // If the value is in simply year, month, day format, we will instantiate the
        // Carbon instances from that format. Again, this provides for simple date
        // fields on the database, while still supporting Carbonized conversion.
        if ($this->isStandardDateFormat($value)) {
            return Carbon::createFromFormat('Y-m-d', $value)->startOfDay();
        }

        // 追加した内容
        $value = date( $this->getDateFormat(), strtotime($value));

        // Finally, we will just assume this date is in the format used by default on
        // the database connection and use that format to create the Carbon object
        // that is returned back out to the developers after we convert it here.
        return Carbon::createFromFormat(
            str_replace('.v', '.u', $this->getDateFormat()), $value
        );
    }

}
```
Pythonで競プロに挑む日誌 vol.5 ~リスト操作の基本~

台風がやばそう

# 現在の目標
* 今年の10月内に茶色を取得する **←イマココ**
* 年内に緑色を取得する
* [APG4b](https://beta.atcoder.jp/contests/apg4b) で C++ にも手を出す

#今日の問題
ABC088B - Card Game for Two 
https://beta.atcoder.jp/contests/abs/tasks/abc088_b

**結果**

```answer1.py
# coding: utf-8
N = int(input())
lis_an = sorted(list(map(int, input().split())), reverse=True)
#lis_an = sorted([int(x) for x in input().split()], reverse=True)

alice = sum(lis_an[i] for i in range(N) if i%2 == 0)
bob = sum(lis_an[i] for i in range(N) if i%2 != 0)
 
print(alice - bob)

# 実行時間：17 ms
# メモリ　：3060 KB
# コード長：227 Byte
# 得点　　：200/200
```
個人的には納得の出来でした.  しかしながら, ほかの方の回答でもっとスマートなものがありました. Loi さんという方のコードを参考にした結果が下記です.

```another_answer.py
# coding: utf-8
N = int(input())
lis_an = sorted([int(x) for x in input().split()], reverse=True)

print(sum(lis_an[0::2]) - sum(lis_an[1::2]))

# 実行時間：17 ms
# メモリ　：2940 KB
# コード長：147 Byte
# 得点　　：200/200
```
うん.  ひとつおきにリストの中身を参照するなら, for 文を使う必要はないですね.  なんか悔しいです.  やはり基礎は大切だな, と思いました.  

とはいえ, あとから読み返したら answer1 のほうが思いだし易い気がするんだよなぁ, と負け惜しんでみる.

#明日やること
[ABC085B - Kagami Mochi](https://beta.atcoder.jp/contests/abs/tasks/abc085_b) を解く.
CUDA9.0のインストール(Win10_201809版）

新しくPCを組んだので入れ方をメモ
なんで9.0+V7.1かというとjetson　TX2と同じにしたかった為

#1.入れたものと入れた先の情報
 **1)インストールしたもの**
　　cuda_9.0.176
　　CuDNNv7.1

 **2)インストール環境**
　　OS:Windows10Home
　　GPU：GTX1070
　　GPUのドライバー：399.07
　　VS2015：Version 14.0.25431.01 Update 3
　　開発環境
　　　(1)python3.6.6
　　　(2)tensorflow1.10.0
　　　(3)keras2.2.2

#2.ソフトの入手
　**1)VS2015**
　　ローカルにあったのを使用（）
　**2)CUDA9.0**
　　[ダウンロード](https://developer.nvidia.com/cuda-90-download-archive?target_os=Windows&target_arch=x86_64&target_version=10&target_type=exelocal)
　本体とパッチ４つを落とす
　**3)CuDNNの入手**
　　[ダウンロード](https://developer.nvidia.com/cudnn)
　　詳細略()

#3.インストール
　**1)VS2015**
　入れるときはカスタムにしてC++とPythonのオプションを入る
　**2)CUDA9.0**
　　(1)本体
　　　高速だとExperienceとドライバーも選択されるのでカスタムを選択し
　　　下記のように☑を外す
![cuda.jpg](https://qiita-image-store.s3.amazonaws.com/0/286585/edda2485-e957-c914-5327-e60cfd4b4bd6.jpeg)

　　(2)パッチ
　　　1番から順番通りに入れていくんですが、パッチの１が他のパッチと挙動がちがって
　　　突然落ちたようにウインドウが閉じる
　　　正しく入っているかは謎
　**3)CuDNN（場所は適時変更）**
　(1)"C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.0"を開く
　(2)CuDNNを解凍
　(3)解凍すると3つフォルダ+ファイルが作成される
　(4)(1)に同じ名前のフォルダがあるので(3)の中身をコピーする

#4.PATHの設定
　昔は手動でしたが勝手に切れてました

#5.動作確認
　上記の開発環境でCNN走らせたら動いたので
　多分問題なし
CentOS 7 の logwatch に付属している php のエラーログを処理するスクリプトは最近の PHP では動かない

素の CentOS 7 の PHP 5.3.3 だと動くのかもしれないけれども 5.3.8 以降だと動きません。

```sh
grep -E 'date_format|filter' /usr/share/logwatch/scripts/services/php
```

```perl
my $date_format = '%d-%b-%Y %H:%M:%S';
my $filter = TimeFilter($date_format);
    next unless $line =~ /^\[($filter)\]/o;
            print strftime($date_format, localtime($msgs->{$msg}->{'first_occurrence'}+int($rms/2)));
            print strftime($date_format, localtime($msgs->{$msg}->{'first_occurrence'}));
```

一方、PHP 7.0.10 のエラーログ。

```
[05-Feb-2018 11:18:48 Asia/Tokyo] PHP Fatal error:  Uncaught Exception: oops in Command line code:1
Stack trace:
#0 {main}
  thrown in Command line code on line 1
```

`Asia/Tokyo` のようなタイムゾーンがついているのでパターンにマッチしない。

下記から察するに 5.3.8 からエラーログにタイムゾーンも書かれるようになったのだろうか。

- [PHP :: Bug #60723 :: error_log error time has changed to UTC ignoring default timezo](https://bugs.php.net/bug.php?id=60723)

なお、logwatch のアップストリームでは修正されている模様。

- https://sourceforge.net/p/logwatch/git/ci/master/tree/scripts/services/php

```perl
    # skipping messages that are not within the requested range
    # the last part of the regex matches optionally occurring specification
    # of timezones, either in Continent/City or abbreviations like UTC
    next unless $line =~ /^\[($filter)(?: \w+(?:\/\w+)?)?\]/o;
```

---

ちなみにわたくしの perl 力ではもとのコードがなにをやっているかよくわからないけれども、メッセージごとの件数とどれぐらいの期間に発生していたかを表示するっぽい。

例えば下記のようなものが出力される。

```
13 times:
[05-Feb-2018 11:57:13 +/-24 seconds]  Uncaught Error: Call to a member function hoge() on null in Command line code:1

1 times:
[05-Feb-2018 12:08:25]  Uncaught Exception: oops in Command line code:1

Warnings:

1 times:
[05-Feb-2018 12:07:04]  printf(): Too few arguments in Command line code on line 1

Notices:

16 times:
[05-Feb-2018 11:57:16 +/-30 seconds]  Undefined variable: o in Command line code on line 1
```

ただし、デフォだと Warning や Notice は出力されない。また、個人的によくやる例外を `error_log()` に渡す `error_log($exception)` みたいなのにも反応しない。

`trigger_error($exception, E_USER_WARNING)` みたいにすれば大丈夫だけど・・そうするほうが良いかも。

---

とりあえずの代替として下記のようなものを使えば大丈夫そう。

```perl
#!/usr/bin/perl

use strict;
use Logwatch ':dates';

my $date_format = '%d-%b-%Y %H:%M:%S';
my $filter = TimeFilter($date_format);
my $messages = {};

while(<>) {
    my $line = $_;
    next unless $line =~ s/^\[$filter[^]]*\]\s*//;
    $messages->{$line}++;
}

foreach my $line (reverse sort { $messages->{$a} <=> $messages->{$b} } keys %$messages) {
    print "[$messages->{$line} times]\n$line\n";
}
```
PHPでMySQL接続

<?php

function db_connect(){

    $user = '******';
    $password = '******';
    $dbname='******';
    $host ='******.com:3306';
    $dsn = "mysql:host={$host};dbname={$dbname};charset=utf8";

    try{
        $pdo = new PDO($dsn, $user, $password);
        $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
        $pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);

//        echo "データベースに接続しました。";
        return $pdo;

    }catch (PDOException $e){
        echo '<span>DB接続においてエラーがありました。</span><br>';
        echo $e->getMessage();
        die();
    }

}

?>

pdoを利用したMySQL接続コードは上記です。functionを利用しているので「return $pdo」を使っている。

別のphpスクリプトが上記を流用する場合下記のコードでＯＫ
require_once("dbconnect_function.php");
$dbh = db_connect();

使い終わったら $dbh=nullをわすれずに
Laravelで画面とAPIで共通のFormRequestを使う方法

# 前提
Laravel 5.x

# 書くこと
画面でPOSTするときとJSONでポストされたとき、同じFormRequestを使いたかった
→ 共通のFormRequestで画面もJSON応答でも使えるように考えてみた
  思いつきなので、「こっちのほうがよいよ！」とかあればコメントお願いします。

# 書いたコード

[Githubはこちら](https://github.com/yamatox/laravel-form-request-example)

```php:App/Http/Requests/TodoFormRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

/**
 * HTMLのFORM POST時に使うFormRequest
 */
class TodoFormRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'task_name' => 'required',
            'remarks' => 'required',
        ];
    }

    public function attributes()
    {
        return [
            'task_name' => 'タスク名',
            'remarks' => '備考',
        ];
    }
}
```

```php:App/Http/Requests/Common/ApiFormRequestTrait.php
<?php

namespace App\Http\Requests\Common;

use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;

/**
 * FormRequestのバリデート結果をJSONに変換して返却するトレイト
 */
trait ApiFormRequestTrait
{
    protected function failedValidation( Validator $validator )
    {
        $response['data']    = [];
        $response['status']  = 'NG';
        $response['summary'] = 'Failed validation.';
        $response['errors']  = $validator->errors()->toArray();
        $response['errorMessages']  = $validator->errors()->all();
        

        throw new HttpResponseException(
            response()->json( $response, 422 )
        );
    }
}
```


```php:App/Http/Requests/Api/TodoApiFormRequest.php
namespace App\Http\Requests\Api;

use App\Http\Requests\Common\ApiFormRequestTrait;
use App\Http\Requests\TodoFormRequest;

/**
 * AjaxなどApi用Controllerで使われるFormRequest
 */
class TodoApiFormRequest extends TodoFormRequest
{
    use ApiFormRequestTrait;
}
```

# どんなときに使うの？
HTMLのFormでPOSTする・AjaxでPOSTするの両ケースが存在する場合
（本当にある……？ は横に置いておきます）

# 参考にさせていただいたページ
https://qiita.com/junsan50/items/ec7f810decd3b82d3d76
(ApiFormRequestTrait.php の内容はそのまま頂いています)
常用linux下的postgres命令

超级用户登录
su - postgres
psql

普通用户
psql postgres cy

再启动
systemctl restart postgresql-9.5

用户一览
\du

スキーマ一览
\dp

バージョンを確認
select version();

DB一览
\l

DB作成
create database XX;

DB接续
\connect XX

Postgresのselect結果を、シェルからワンライナーでテキストファイルに保存する
psql -U <username> -d <dbname> -c 'SELECT * FROM users where id > 10;' -A > log.txt
一部のサイトにアクセスできない病を直す

ubuntu 16.04環境のPCを新規に利用しようとしたら、firefoxで一部のサイトだけアクセスできなかった。
そのときの解消方法メモ！


#病の原因
単純なプロキシ設定ミス！
プロキシ環境下であったが、設定しなくても他のサイトが見れたため油断していた・・・！

#治し方
ページ上部にある歯車っぽいアイコンからブラウザの設定ページへ行く
↓
(英語の状態で使っているので以下英語ブラウザver.での説明になります)
「General」にて、Network ProxyのSettings...を開く
↓
Use system proxy settingsの設定になっているので、Manual proxy configurationに変更
↓
HTTP Proxy部分に自身のProxyとPortを入力
↓
OKボタンを押して終了


(　Proxyが分からないとき、Use system proxy settingsの設定をAutomatic proxy configuration URLに変更するだけでもいけるっぽい　)


以上！
Windows2016へiCloudをインストールする方法

Windows2016へiCloudをインストールする方法

参考URL記載のとおり以下の順番にてイントールし成功した
1 - Bonjour64.msi
2 - AppleApplicationSupport.msi 
　　※AppleApplicationSupport64.msiを利用すると失敗する
3 - iCloud64.msi（※OrcaにてLaunchConditionを削除する必要有り）

以下参考URL
https://www.reddit.com/r/techsupport/comments/78i3zx/install_icloud_on_windows_server_2016/

https://www.raffaelechiatto.com/installare-apple-icloud-microsoft-windows-server-2012-r2/
MySQLデータベース接続について

awsのRDBに接続しようとしたところ、ずっとタイムアウトのエラーが返ってきた。
原因はＤＢに訪問するＩＰを設定しなかったから

![q13.png](https://qiita-image-store.s3.amazonaws.com/0/286146/bcd72658-c911-6396-db57-df42694c14e0.png)

RDSの中で上記のような設定がある、赤枠はＩＰアドレスを指定する場所。訪問するＩＰアドレスもしくはEC2のセキュリティコードを指定しないとアクセスが制限される。

このケースはＥＣ２のセキュリティコードを入力したら解決。

セキュリティコードについてＥＣのダッシュボードを見ればわかるのでここでは割愛。

１日考えてたのでここで備忘する

原因をたどり着いたのがpingができなかった、もしかしたらＩＰ制限されていると、やっぱりそうだった。
Qiitaのデザインがまた改悪された


[8月頭に劣化して](https://qiita.com/rana_kualu/items/ec860155a4d3a44410a0)数日で元に戻ったと思ったら、8月末に再度改悪されたという話。

まず、こちらがタグ検索新着2ページ目の表示だ。

![01_sinchaku2.png](https://qiita-image-store.s3.amazonaws.com/0/26088/e12af146-f965-3b93-69ea-4fee29916d07.png)


[先日](https://qiita.com/rana_kualu/items/ec860155a4d3a44410a0)邪魔だと言っていた『トレンド』がなくなり、きちんと最初から新着2ページ目が表示されるようになった。
ここについては評価点と言えるだろう。
しかしそれ以外については問題点しかない。

・そもそもタグの『投稿数』『フォロワー数』はさして重要な情報ではないので、毎回でかでかと出す必要はない。
・明らかにそれ以上に重要な、投稿の『いいね数』『コメント数』を削除するという暴挙。
・というか『最近いいねされた順』の表示がなくなった。
・デザインが一貫してなさすぎる。

サイトトップ
![03_1_top.png](https://qiita-image-store.s3.amazonaws.com/0/26088/fc68a5fa-d03f-2712-a293-b2e476c52cd8.png)
タグ検索新着順2ページ目
![03_2_sinchaku2.png](https://qiita-image-store.s3.amazonaws.com/0/26088/28a1f983-6057-3a1b-27c0-7a59dc761f36.png)
全投稿2ページ目
![03_3_all2.png](https://qiita-image-store.s3.amazonaws.com/0/26088/ea830149-5fa8-1905-8a08-67b7f5f575fe.png)

ランキングを表示するのはかまわないが、表示するならせめて左右くらい揃えないか？

さて次はタグ検索1ページ目だ。

![02_sinchaku1.png](https://qiita-image-store.s3.amazonaws.com/0/26088/976ba9c1-e3c6-b253-563e-dc5f8dab7014.png)

ここではまだ『新着順』を指定していないので、上にトレンドが表示されているのは問題ないだろう。
しかし、トレンドにはいいね数が出ているのに新着順には出ていない。
トレンドと新着順のHTML構造はほとんど同じなのだが、トレンドでは`tst-ArticleBody_likeCount`を出力しているくせに新着順では`tsf-ArticleBody_likeCount`を出していないという意味不明なセコさ。
せめてhiddenにしてくれればユーザCSSで対処できるというのに。


まあ間違いなく、今のままでは全体いいね数は激減するだろう。
[殿堂](https://qiita.com/youwht/items/9851c2ac9024633fc04e)の2018年9月の結果が楽しみですね。

というかむしろ、いいね順表示を削除したってことは、いいねして欲しくないってことなのだろうか？
CentOS 7 + nginx で 403 forbidden が出た時の対処法

#はじめに
nginxの環境構築をしていて躓いたのでまとめる。
＊自分用メモ

#構築環境
以下のバージョンで環境を構築する。
>CentOS 7
nginx1.14.0
php 7.2.9

#やったこと
php-fpmとnginxはsocketにて接続した。

```/etc/nginx/conf.d/default.conf
fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
```

```/etc/php-fpm.d/www.conf
listen.owner = nginx
listen.group = nginx

listen = /var/run/php-fpm/php-fpm.sock
```
＊ownerとgroupもnginxに変更しておく（忘れやすい）
## 解決策
パーミッションは確認していたので、下記の設定を編集しなおした。
（ファイルに読み取り・ディレクトリに実行権限を与えておく）

変更前

```/etc/nginx/conf.d/default.conf
fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
```

変更後

```/etc/nginx/conf.d/default.conf
fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
```

#まとめ
実際に修正した点は1行のみであったが、変更箇所を見つけるまでに時間がかかった。
JavaScript・再帰・トランポリン

# 現状整理
- JavaScript では末尾再帰最適化(PTE: Proper Tail Call) は、完全には期待できない
    - https://kangax.github.io/compat-table/es6/
    - [末尾再帰による最適化 - Qiita](https://qiita.com/pebblip/items/cf8d3230969b2f6b3132)
- なので再帰は注意して使わねばならない
    - スタックオーバーフローしないことをチェック
    - 再帰を辞めて for 文とかに何とか変換する
- とはいえ再帰を使いたい
    - こともある
    - じゃあどうするか？が本稿の目的

再帰におけるスタックオーバーフローは、末尾再帰の最適化ができる他の言語でも起こりえる(例: 末尾再帰できない場合)。じゃあ、他の言語の場合どうしているかというと、トランポリンするらしい。もちろん JavaScript でもトランポリンできる。トランポリンすると、再帰が深くなってもスタックオーバーフローしない。

# 処方箋
ざっくりいうと以下の処方でスタックオーバーフローしなくなる。

- 再帰関数の実装を少し変更して、終了時以外には **再帰を実行する関数(正確にはクロージャ)** を返すようにする
- トランポリン関数に上記関数を渡してトランポリン化する
- トランポリン化した関数を実行する

例をあげた方がはやい。まず、スタックオーバーフローする再帰関数:

```countDown.js
function countDown (num) {
  if (num === 1) return 1;
  if (num % 1000 === 0) console.log(num);
  return countDown(num - 1);
}
countDown(30000); // 18000 まではカウントダウンできた。Node v10
```

これを以下のように変更:

```countDown2.js
function countDown2 (num) {
  if (num === 1) return 1;
  if (num % 1000 === 0) console.log(num);
  return () => countDown2(num - 1);
}
```

これをトランポリン関数に渡してあげる:

```js
function trampoline (fn) {
  return (...args) => {
    let result = fn(...args);
    while (typeof result === 'function') {
      result = result();
    }
    return result;
  };
}

const tramped = trampoline(countDown2);
```

そんで実行

```js
console.log(tramped(30000)); // -> カウントダウンされ、再帰の結果の 1 が返される
```

まあ、簡単。

# 何が起こっているのか？

私の説明よりも、わかりやすい説明があるのでそれを紹介

- StackOverflow
    - https://stackoverflow.com/a/27704484/9427427
    - トランポリンというファンシーな名前の由来もばっちりわかる
- Using trampolines to manage large recursive loops in JavaScript
    - https://blog.logrocket.com/using-trampolines-to-manage-large-recursive-loops-in-javascript-d8c9db095ae3

関数を実行すると関数が返ってくるので、それをまた実行するとまた関数が帰ってくるのでそれを実行して、というように(スタックに積むのではなく)同一のフレームで逐次処理ができるのがポイント。再帰を while を使ったイテレーションに変換した、ともいえる。

# まとめ
JSの再帰でスタックオーバーフローするときはトランポリンしよう。
メールサーバ立てる(受信編)

#前回の[「メールサーバ立てる（送信編)」](https://qiita.com/iaoiui/items/4a67d1e372ae79ad629a)のつづき

#想定環境
OS: CentOS 7

##メール受信用IMAPサーバ(dovecot)の構築

```
yum -y install dovecot
```

```/etc/dovecot/dovecot.conf
protocols = imap pop3 lmtp
listen = *
dict {
  #quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
  #expire = sqlite:/etc/dovecot/dovecot-dict-sql.conf.ext
}
!include conf.d/*.conf
!include_try local.conf
```

```/etc/dovecot/conf.d/10-auth.conf
disable_plaintext_auth = no
auth_mechanisms = plain login
!include auth-system.conf.ext
```

```/etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:~/Maildir
namespace inbox {
  inbox = yes
}
first_valid_uid = 1000
mbox_write_locks = fcntl
```

```/etc/dovecot/conf.d/10-master.conf
service imap-login {
  inet_listener imap {
  }
  inet_listener imaps {
  }
}
service pop3-login {
  inet_listener pop3 {
  }
  inet_listener pop3s {
  }
}
service lmtp {
  unix_listener lmtp {
  }
}

service imap {
}
service pop3 {
}
service auth {
  unix_listener auth-userdb {
  }

  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }
}
service auth-worker {
}

service dict {
  unix_listener dict {
  }
}
```

```/etc/dovecot/conf.d/10-ssl.conf
ssl = no
ssl_cert = </etc/pki/dovecot/certs/dovecot.pem
ssl_key = </etc/pki/dovecot/private/dovecot.pem
```


##サービスの自動起動設定・起動
systemctl restart dovecot && systemctl enable dovecot
Laravel の DB のマスター/スレーブでマスターで SELECT したりスレーブでトランザクションしたり

Laravel で↓のように `read/write` の接続先を設定したとき。

```php
<?php
return [
    'default' => env('DB_CONNECTION', 'mysql'),
    'connections' => [
        'mysql' => [
            'driver' => 'mysql',
            'read' => [
                'host' => env('DB_SLAVE_HOST', '127.0.0.1'),
                'port' => env('DB_SLAVE_PORT', '3306'),
            ],
            'write' => [
                'host' => env('DB_MASTER_HOST', '127.0.0.1'),
                'port' => env('DB_MASTER_PORT', '3306'),
            ],
            'database' => env('DB_DATABASE', 'test'),
            'username' => env('DB_USERNAME', 'ore'),
            'password' => env('DB_PASSWORD', 'are'),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8',
            'collation' => 'utf8_bin',
            'prefix' => '',
            'strict' => false,
            'engine' => null,
        ],
    ],
];
```

意図的にマスターで SELECT したりスレーブでトランザクションする方法。

---

Illuminate の Connection オブジェクトは２つの PDO インスタンスを持っていて、

- https://github.com/laravel/framework/blob/v5.5.42/src/Illuminate/Database/Connection.php#L27-L39

実行するクエリによってどちらを使うかが選択されているようなのですが、

- https://github.com/laravel/framework/blob/v5.5.42/src/Illuminate/Database/Connection.php#L391-L400

トランザクションを開始しているときは常にマスターの方が使われます。

- https://github.com/laravel/framework/blob/v5.5.42/src/Illuminate/Database/Connection.php#L928-L930

なので明示的にマスターを指定するのは単にトランザクションに入れればOKです。

```php
DB::select('select user_name from users'); // -> SLAVE

$user = User::find('admin'); // -> SLAVE

$user->user_name = 'oreore';
$user->save(); // -> MASTER

DB::transaction(function() { // -> MASTER

    DB::select('select user_name from users'); // -> MASTER

    $user = User::find('admin'); // -> MASTER

    $user->user_name = 'areare';
    $user->save(); // -> MASTER
});
```

普通にトランザクションを開始するとその中ではマスターを見に行ってしまうので、読み取り一貫性のためにスレーブでトランザクションを開始したいときはあんまり綺麗な方法はなさそうです。

```php
try {
    DB::getReadPdo()->beginTransaction(); // -> SLAVE
    $user = User::find('admin'); // -> SLAVE
} finally {
    DB::getReadPdo()->rollBack(); // -> SLAVE
```
ハッキングを心配して2段階認証にしたらOutlookでgmailが受信できなくなった件


こんにちは。初投稿なので読みづらかったらすいません。

きっかけはgmailである1通のメールを受信したことでした。
送信元はGoogle、件名は重大なセキュリティ通知...
内容を読むと、どうやら私のアカウントにログインしようとした人物(?)がいるというお知らせでした。

パスワードの変更を推奨されたので、若干不審に思いつつ変更の手続きをしました。
しかしこのご時世、パスワードがどこから漏れるか分からない時代です。
いかにGoogle Chromeのセキュリティが堅固でも、ログイン連携しているサイトやアプリケーションの脆弱性を突かれたら一発でアウトです。
それを不安に思ったのでブラウザで2段階認証を設定しました。

そんな作業をしているうちに私が使っているメーラーOutlook2016に異変が起こりました..
Outlookにメールサーバーの認証用のパスワードを求めるポップアップが湧いて出てくるようになったのです!!:scream:

若干引くくらいのペースでメッセージが出てくるので、焦って何思ったのか私は攻撃者のIPアドレスを調べ始めました。(https://www.cman.jp/network/support/ip.html)

結果出てきたのは、某大手ISP(プロバイダ)のIPアドレスでした。tracertコマンド使って調べても出てくるIPはそこだけで他のルーターをホップしてきたような形跡もありませんでした(この辺りで気づけたらよかったのですが..)。

時間がたって冷静になった私は、Outlookに出てきたエラーメッセージを調べ始めました。そうしていくらか格闘したのち、たどり着いたのがこの記事でした。(http://www.atmarkit.co.jp/ait/articles/1409/03/news109.html)

ざっくりまとめてしまうと、Chromeで使われている認証方式(OAuth 2.0)にメーラー側(outlook)が対応していないために起こる現象だそうです。
解決策としては、Chromeのアカウントページでアプリパスワードを生成してそれを登録したのち、あの憎きポップアップ画面に張り付けてあげればOKです。
このやり方で無事素晴らしきOutlookライフに返り咲くことができました!(やったね!)

それで今回のオチなのですが、ブラウザに残っていた攻撃者(仮)のIPアドレスをよく見てみると...なんと私のIPアドレスでした（笑）
メールサーバー(gmail)にアクセスしようと頑張った私のかわいいOutlookの記録が残っただけであって、実はハッキングでもなんでもなかったのです(棒)

タイトル詐欺では..と若干書いてて思ったのですが、クラッキングとは書いてませんし、あくまでも心配しているだけなのでセーフですよね（out:relaxed:lookだけに）

オチがくだらなさ過ぎたので、ちょっとした愚痴のつもりで初投稿です。最後まで読んで下さった皆様、ありがとうございました!
PHPUnitの遅いテストケースをあぶり出すphpunit-speedtrap

単体テストは数秒で結果が出ると、テストを回しながらの開発がしやすくなったり、継続的インテグレーションの待ち時間が短くなったりと良いことが多い。しかし、プロジェクトが成長するにつれ、テストにかかる時間が伸びだし、待つのが辛くなってくることがある。

[johnkary/phpunit-speedtrap](https://github.com/johnkary/phpunit-speedtrap)はPHPUnitの遅いテストケースを報告してくれるプラグインだ。これを導入すると、実行時間がしきい値を超えたテストケースについて、遅いテストワーストランキングをテスト結果に表示してくれる。その結果をヒントに遅いテストをチューニングすることができる。

![687474703a2f2f692e696d6775722e636f6d2f5a7233346769522e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/889/98592214-6fae-ef41-d2fd-9743954067b9.png)

## インストール方法

```
composer require --dev johnkary/phpunit-speedtrap
```

もしも、PHPUnit6系を使っている場合は、最新のバージョン3.0は入らないため、phpunit-speedtrapの2.0を入れる必要がある:

```
composer require --dev johnkary/phpunit-speedtrap='^2.0'
```

## 設定

phpunit.xmlにlistnerを追加するだけ:

```xml:phpunit.xml
<phpunit bootstrap="vendor/autoload.php">
...
    <listeners>
        <listener class="JohnKary\PHPUnit\Listener\SpeedTrapListener" />
    </listeners>
</phpunit>
```

しきい値を設定することもできる:

* slowThreshold: 「遅いテストケース」とするしきい値。デフォルトは500ミリ秒。
* reportLength: テスト結果に表示する最大テストケース数。デフォルトは10件。

```xml:phpunit.xml
<phpunit bootstrap="vendor/autoload.php">
    <!-- ... other suite configuration here ... -->

    <listeners>
        <listener class="JohnKary\PHPUnit\Listener\SpeedTrapListener">
            <arguments>
                <array>
                    <element key="slowThreshold">
                        <integer>500</integer>
                    </element>
                    <element key="reportLength">
                        <integer>5</integer>
                    </element>
                </array>
            </arguments>
        </listener>
    </listeners>
</phpunit>
```
Python3のsubprocessでプロセスが殺せない

# 前提
Pythonのsubprocessで実行ファイルに時間制限をつけて実行していた.
一覧からなぜかプロセスが消えないため調査した.

# 発生した環境
[この記事を参考にしました](https://qiita.com/koshian2/items/66465ebda4cbe32f2f09)

```python
import subprocess
import time

p=subprocess.Popen('a.exe args',shell=True)
time.sleep(5)
p.kill()
```

プロセスが生き続けているため,無限ループの場合ずっと生きていることになる
UNIX環境の場合は親のPythonが終了すると子となっているプロセスも落ちるようだ.
# 解決方法
```diff
- p=subprocess.Popen('a.exe args',shell=True)
+ p=subprocess.Popen(['a.exe', 'args'],shell=False)
```
シェルモードをFalseにする.

# 参考
https://stackoverflow.com/questions/4789837/how-to-terminate-a-python-subprocess-launched-with-shell-true
Visual Studio Code 整形しないでコピペする

####Atomから最近乗り換えたのでメモ的に。

	<div><p>hoge</p></div>

こんなコードをコピペする際に
Visual Studio Codeだと

	　　<div>
         <p>hoge</p>
        </div>

改行を入れられてしまった。



ファイル > 基本設定　>　基本

<pre>"editor.formatOnPaste": false,
</pre>


追記で忠実にコピペ。
安全な! migration ファイルの作り方

みなさん Rails でマイグレーションを使ってると思います(大きなところ以外は?)

デプロイでマイグレーションが失敗することはありませんか?
マイグレーションが失敗すると, 場合によっては DB をバックアップから復元する必要があったりします.

安全な migration ファイルをつくって気楽にデプロイしましょう.

# どういうときにマイグレーションが失敗するのか
1. fk が絡んだとき
2. uniq インデックスを付けたいのにすでに重複しているとき
3. NOT NULL 制約を付けたいのに, NULL が入っているとき

などなど


# 本番デプロイでマイグレーションがコケるとどうなる?


最初の部分で失敗していればいいのですが, 途中で失敗すると中途半端なDB になってしまいます.
再度デプロイしようとしても, また最初からマイグレーションが実行されるので今度は最初の部分で失敗します.
なので, バックアップから復元して元の状態に戻したりなどの対応が必要ですが,
その間アプリケーションが正常な状態ではなくなるので, ご不便です


```rb
class ChangeColumnsToBooks < ActiveRecord::Migration[5.0]
  def change
    add_column :books, :name, :string
    add_index :books, :isin, unique: true # <= ここでコケると面倒
  end
end
```

# 解決策

## migration の単位を小さくする

上の例ですと `add_column` と `add_index` を別の migration ファイルにしてしまう

```rb
class AddNameToBooks < ActiveRecord::Migration[5.0]
  def change
    add_column :books, :name, :string
  end
end


class AddIsinIndexToBooks < ActiveRecord::Migration[5.0]
    add_index :books, :isin, unique: true # <= ここでコケても次回またここからはじまる
  end
end
```
とはいえ再デプロイまでアプリケーションが動いていると, アプリケーションコードと DB の schema が合わない状態が続くので良くない

## レコード をいじくる(本題)

```rb
class AddIsinIndexToBooks < ActiveRecord::Migration[5.0]
  def change
    Book.order(isin: :asc).each_cons(2) do |first, second|
      first.destroy if first.isin == second
    end
    add_index :books, :isin, unique: true
  end
end
```

これでとりあえず `books.isin` が重複したカラムはなさそう
ただし, もし追加した部分のコードでは不十分だった場合は?
デプロイでそれがわかっても後の祭り

## いじくった後にチェックする => だめならロールバック

```rb
class AddIsinIndexToBooks < ActiveRecord::Migration[5.0]
  class まだ重複しているレコードがあるよエラー < StandardError; end
  def change
    ActiveRecord::Base.transaction do
      Book.each_cons(2) do |first, second| 
        first.destroy if first.isin == second
      end
      raise まだ重複しているレコードがあるよエラー if Book.pluck(:isin).uniq.count != Book.count
    end
    add_index :books, :isin, unique: true
  end
end
```


これなら, レコードをいじくる部分に不備があったとしても元の状態にロールバックしてくれます


## 将来 Book の実装が変化したとき


```rb
class AddIsinIndexToBooks < ActiveRecord::Migration[5.0]
  class Book < ActiveRecord::Base; end # <= アプリケーションの Book の実装に依存しないように
  def change
    Book.order(isin: :asc).each_cons(2) do |first, second| # <= ここで使われるのは `AddIsinIndexToBooks::Book` になる
      first.destroy if first.isin == second
    end
    add_index :books, :isin, unique: true
  end
end
```

マイグレーションでモデルとかを使う場合はマイグレーション用にクラスを作って置きましょう

`after_destory` とかのコールバックが追加されたりする場合にも対応できます
マイグレーションはなるべくアプリケーションコードに依存しないようにしときましょう




# 結論

あとは, staging で本番データと同じものを用意してマイグレーションしてみるとか (ただし, それが許されるなら)
そもそもマイグレーション使わんほうがいいって話もありますがとはいえ
【shell】lotateされたログ毎にgrepでヒットした件数をまとめて表示する

# 経緯
ログからエラーの件数を数える際に、lotateされたログファイルをいちいち一個ずつ見ていくのがだるい。
ファイル名に日付がつくという性質上、サジェストしても最後までファイル名が確定しないのが特に辛い。
仕事をしてて結構な回数この作業をやっているなと思い、重い腰を上げてまとめて出せるようにしようと決意した。

以下、`/path/to`というディレクトリにログファイルと、lotateされたログファイルが一緒に入っている、という前提で進めていく。

# 結論
## コマンド
```sh
find /path/to -type f -name "hogehoge.com.ssl.access.log*" | xargs zgrep -wc {{調べたい文字列}} | sort
```

## 出力
```sh
/path/to/hogehoge.com.ssl.access.log-20180825.gz:273
/path/to/hogehoge.com.ssl.access.log-20180826.gz:231
/path/to/hogehoge.com.ssl.access.log-20180827.gz:239
/path/to/hogehoge.com.ssl.access.log-20180828.gz:280
/path/to/hogehoge.com.ssl.access.log-20180829.gz:337
/path/to/hogehoge.com.ssl.access.log-20180830.gz:284
/path/to/hogehoge.com.ssl.access.log-20180831.gz:298
/path/to/hogehoge.com.ssl.access.log-20180901.gz:318
/path/to/hogehoge.com.ssl.access.log-20180902.gz:288
/path/to/hogehoge.com.ssl.access.log-20180903.gz:298
/path/to/hogehoge.com.ssl.access.log:254
```

# 何をしているか
## find
`/path/to`の場所にある、前方一致で`"hogehoge.com.ssl.access.log"`という名前を含むファイルを検索している。
find部分のみの結果は以下のようになる。

```sh
/path/to/hogehoge.com.ssl.access.log
/path/to/hogehoge.com.ssl.access.log-20180831.gz
/path/to/hogehoge.com.ssl.access.log-20180828.gz
/path/to/hogehoge.com.ssl.access.log-20180829.gz
/path/to/hogehoge.com.ssl.access.log-20180902.gz
/path/to/hogehoge.com.ssl.access.log-20180826.gz
/path/to/hogehoge.com.ssl.access.log-20180901.gz
/path/to/hogehoge.com.ssl.access.log-20180825.gz
/path/to/hogehoge.com.ssl.access.log-20180830.gz
/path/to/hogehoge.com.ssl.access.log-20180903.gz
/path/to/hogehoge.com.ssl.access.log-20180827.gz
```

## xargs
`|`以前のコマンドの実行結果を引数にして、`xargs`以降のコマンドを実行する。
今回は上記の`find`コマンドの結果を一行ずつ`zgrep`コマンドの引数として渡している。

余談だが、`-p`オプションを指定すると、「このコマンドを実行するけどいい？」というプロンプトを、実行予定のコマンド文字列と共に表示してくれる。
どんなコマンドが実行されるか一目瞭然なので、これを上手く利用するとxargsと仲良くなりやすい。

## zgrep
`.gz`拡張子のファイルをそのまま扱えるgrepみたいなものという認識。
lotateされたログファイルは`.gz`になっているのでgrepではなくzgrepを使用している。
（あとで調べてみたら`zgrep`は`grep -Z`と同じらしい）
https://nxmnpg.lemoda.net/ja/1/zgrep

`-w`は単語として含まれている物を検索、`-c`はヒットした行を表示するのでなく、その行をカウントするオプション。

## sort
日付順に並んでてほしいなと思ったので。

# 最後に
GUI生まれGUI育ちなのでシェルに苦手意識を持っていたが、**「パイプは結果をそのまま渡してあげてるだけ」**ということと、**「xargsはパイプで渡された結果を（-Lオプションで指定しなければ）1行ずつ引数にしてコマンドを実行しているだけ」**ということを意識した結果、実現したいこと実現できるコマンドを自分の力で書けて気持ちよかった。
Nginxで何が起こってるんや...

#ってときにデバッグする方法
設定ファイルの/1つで挙動が大きく異なったりするため
禿げそうになることがある。そんな時にnginxの動作が見れると嬉しいね

##想定環境
OS: CentOS7

##nginxのインストール

```
yum install -y nginx
```

##サービスの自動起動設定・起動
ここでnginxではなくnginx-debugというサービスを使うのが最初のつまづきポイント
nginxをインストールすると付いてくる。動作はnginxサービスと同様。

```
systemctl enable nginx-debug && systemctl start nginx-debug
```

##ログ書き出しの設定
やることは2点
rewriteログの有効化(これがないとデバッグ厳し目
ログレベルの変更

元のファイルからの変更箇所は下記2行だけのはず

```
error_log   /var/log/nginx/example-error.log debug;
rewrite_log on;
```

変更後のファイルも併記しておく

```変更後の/etc/nginx/nginx.conf
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;
    error_log   /var/log/nginx/example-error.log debug;
    rewrite_log on;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
```

##terminalでログをみてみる
鬼のようにログが流れることが確認できるであろう。

```
tail -f  /var/log/nginx/example-error.log 
```

##ログの見方
初めは見る気すら失せるが、HTTPリクエストごとに下記のような
レスポンスヘッダが現れるので、そこを1区切りと考えれば良い

```
Server: nginx/1.15.2
Date: Sun, 02 Sep 2018 19:00:38 GMT
Content-Type: text/html
Content-Length: 185
Connection: close
Location: https://localhost/
```


##設定ファイルについても書けたらいいな(
SPAのハッシュ付きURL遷移にGTMを仕込む

Angularのハッシュ付き遷移を使っているんですが、これだとGoogleAnalyticsのPageViewで `/` しか取れていないことがわかった。
そこでGoogleタグマネージャを使ってハッシュ付きURLの遷移でもPageViewを取れるようにします。


# 1. 変数の追加

## 1.1 hash変数の作成
名前はなんでもいいですが、ここでは`hash`としました。

変数の種類：JavaScript変数
グローバル変数名：location.hash

![スクリーンショット 2018-09-03 19.03.19.png](https://qiita-image-store.s3.amazonaws.com/0/17135/9b6a826c-84ed-a3fa-442c-2445c292e089.png)

これを保存します。


## 1.2 ハッシュ付きトラッキングコードの作成
また名前はなんでもいいです。
GoogleAnalyticsからトラッキングコードを持ってきて入力します。
また、詳細設定＞設定するフィールドの`page`に先程作成した変数の`hash`を入れます。

![スクリーンショット 2018-09-03 19.12.00.png](https://qiita-image-store.s3.amazonaws.com/0/17135/ade5d8cd-6707-c421-b87d-099bc7bb458f.png)


これを保存します。


# 2. トリガーの追加
また名前は(ry

トリガーの種類：履歴の変更
トリガーの発生場所：すべての履歴の変更

![スクリーンショット 2018-09-03 19.07.07.png](https://qiita-image-store.s3.amazonaws.com/0/17135/f288cd32-4b49-b687-f79d-cfb5515c8127.png)

これを保存します。


# 3. タグの追加
名前は(ry

以下設定をして、できあがりです。

![スクリーンショット 2018-09-03 19.14.15.png](https://qiita-image-store.s3.amazonaws.com/0/17135/07ebcc66-66d9-835c-8bea-d25568a7458a.png)
Dispose後にonErrorが発生すると`UndeliverableException`になる

RxJava2初心者です。

正確には、subscribeOnで別スレッドで処理中の場合という条件付き。でも、同じスレッドを使う人はいないと思うので大半は引っかかるはず。（AndroidだとUIスレッド等の兼ね合いもありますし。）


発端
--------------

subscribeしたけどやっぱキャンセルしよーっと！って思ってdispose(unsubscribe)したら、Androidのアプリがクラッシュした。安直にdisposeするのは良くなかったらしい。

調べてみると、disposeした瞬間に処理を中断するわけではなくて、まずInterruptが行われsleepしていればInterruptExceptionが発生する模様。もちろん、（interrupted状態をチェックしないような）普通の処理中であれば処理が続く。そのままonErrorまで処理が到達すると、本件の例外が発生し、待ち受けているdoOnError等の処理が行われないまま、アプリが死ぬという感じ。

要するに、onErrorを書いてるのに何も考えずにdisposeするとクラッシュする場合がある。


対応
--------

色々悩んだ挙句、ドキュメントに書いてあった。ちゃんとドキュメント読みましょう。

https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0#error-handling

大まかには、グローバルなエラーハンドラーがあるのでそれでキャッチして処理するか、OnErrorする前にdispose済みであるかどうかで処理を書き分けるしかなさそう。

1. 2.0以上であれば、グローバルなエラーハンドラを設定する
    

       ``` kotlin:
       RxJavaPlugins.setErrorHandler {
           println("${Thread.currentThread().name}: catch GlobalErrorHandler ${it.message}")
       } 
       ```

    ただ、今回のケースで最適なのか良くわかってない。
2. `ObservableEmitter#onError`使う前に`ObservableEmitter#isDiposed`で破棄済みかどうか確認してから行う。
3. 2.1.1以降であれば、`ObservableEmitter#onError`ではなく`ObservableEmitter#tryOnError`を使う。

disposeしたならもう処理結果に期待していないのだから、クラッシュしない程度に適当に処理しましょう、という感じに見える（雑）

### 蛇足

最初、ドキュメントのエラーハンドリングの項目を見つけるまでは悩んでて、でもtryOnErrorを実装していることから、tryOnErrorの実装した雰囲気から頑張ってチェック処理かけってことなのかな？って思っていたが、そうじゃなかった。

https://github.com/ReactiveX/RxJava/blob/2.x/CHANGES.md#version-211---june-21-2017-maven
https://github.com/ReactiveX/RxJava/pull/5344



再現コード
-------------

エラーだけ見たいのであればこんな感じに書いておけば起きます。
上記からグローバルなエラーハンドラーを登録するコードをコピペしたり、onErrorをtryOnErrorにすると落ち着くことが分かります。

``` kt
    fun sleep(time: Long ) = try{ TimeUnit.MILLISECONDS.sleep(time) }catch(e:InterruptedException){ println("Ignore Exception ${e.message}") }

    @Test
    fun test1() {
        println("start")

        val disposable = Observable.create<String> { emitter ->
            // 別スレッドで重い処理
            println("observer start")
            sleep(1000)
            println("observer end")
            emitter.onError(Exception("FOOOOO")) // NG. isDisposedで確認してから使う。もしくはtryOnErrorを使う。
        }.onErrorReturn {
            println("onErrorReturn ${it.message}")
            "onErrorReturn"
        }.doOnError {
            println("doOnError ${it.message}")
        }.doOnDispose {
            println("Dispose")
        }.subscribeOn(
                Schedulers.newThread() // Observerを別スレッドで処理する
        ).subscribe({
            println("next")
        }, {
            println("error")
            println(it)

        }, {
            println("compleate")
        })

        sleep(200)

        // 気が変わったのでキャンセル
        disposable.dispose()

        sleep(1000)
        println("end")
    }
```

エラーハンドリングしないと以下のようなエラーになります。(sleepのtry-catchを削除すればInterruptException)

```
io.reactivex.exceptions.UndeliverableException: java.lang.Exception: FOOOOO
```
シェープファイルとその実体で混乱した話

ArcGIS を使って地理情報の解析をする必要ができてきたので、人生で初めて ArcGIS を使うことになりました。

<img src="https://qiita-image-store.s3.amazonaws.com/0/278104/7754009f-e6e3-2136-400b-cc43daaa4e87.jpeg">

初めて ArcGIS を使ったときに躓いた点が、ArcGIS のデータフォーマットでした。

## ArcGIS のデータフォーマット

ArcGIS を勉強するために本やネットのリファレンスを読んでみたのですが、私はデータの説明がいまいちよくわかりませんでした。こういった説明によくあるのが

- GIS で扱うデータはベクタデータとメッシュデータがある
- 点・線・面で表される情報はベクタデータ、連続的に変化する状態などはラスタデータ
- シェープファイルはベクタデータを格納するデータフォーマットである
- ジオデータベースではベクタデータだけでなくラスタやアノテーションなども格納できる

といった雰囲気のものです。けれど、初心者の私からするといろいろな疑問が生じました。

## （疑問１）シェープファイルはファイルなのか

いわゆるシェープファイルというものを[e-Stat 政府統計の総合窓口](https://www.e-stat.go.jp/)からダウンロードした私は最初、複数のファイルがそこにあったので戸惑いました。「どれがシェープファイルなのだ」と。

<img width="284" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/278104/452ca66c-0677-bc42-f910-7c333a36c86b.png">

さらに ArcMap でこのファイルを開こうとしたら単一ファイルしか表示されないのでさらに混乱しました。

<img width="428" alt="キャプチャ2.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/278104/e14026cd-3242-dd61-dc2b-9ea4746b5789.png">


これについてですが

- __「狭義の」シェープファイルは .shp という拡張子のファイル__
- __「広義の」シェープファイルは、同一ディレクトリに格納された、共通のファイル名を持つファイル郡( .shp, .shx, .dbf, ...)__

というふうに私は解釈しています。

#### 狭義のシェープファイル

シェープファイルはベクタデータを格納している、という話は「狭義の」シェープファイルのことを指しています。つまり .shp のこと。この .shp には ArcMap で表示されるようなマップ情報を保持しています。たとえば以下の図のデータ。

<img width="1056" alt="キャプチャ3.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/278104/74b057f3-83b9-0d65-48cb-128d7029ecde.png">

#### 広義のシェープファイル

一方で ArcMap でシェープファイルを開いたら、この図のデータ以外にもデータがあります。例えば属性テーブル。

<img width="359" alt="キャプチャ4.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/278104/24d6acc6-2c96-6adb-b669-c501171aa22f.png">

この属性テーブルは .dbf ファイルとなっていて、狭義のシェープファイルではありません。しかしながら ArcGIS で扱うレベルの話ではシェープファイルに含まれています。

#### ArcGIS では広義のシェープファイルを単一のファイルとして扱う

先程 ArcMap でシェープファイルを開こうとしたら単一ファイルしか表示されなくて混乱した、と書きましたが、これは ArcMap が広義のシェープファイルを扱うようになっているからです。ArcMap を始めとした ArcGIS 製品で表示されるファイルは、実際のファイルシステム上のファイルとは微妙に異なります。

#### （追記 2018年9月5日）

コメントでいただきましたが、__「シェープファイルはshp, dbf, shxの3種(サフィックス)ファイルがそろって1つのシェープファイルをなす」__ と考えるのがよいそうです。

## （疑問２）ポリゴンデータとテーブルデータの間の対応関係はどこに定義されている？

広義のシェープファイルには図形データ（ベクタデータ）と属性テーブルが格納されていることがわかりました。けれど１つ疑問が残ります。属性テーブルのレコードと図形データには対応関係がありますが、その対応関係はどこに記述されているのでしょうか。

（下図は属性テーブルのレコードを選択したときの様子）

<img width="790" alt="キャプチャ5.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/278104/6d77d68e-c462-8118-8527-ca15460328ae.png">

これですが、 [Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%A7%E3%83%BC%E3%83%97%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB) の説明では

> .shp, .shx, .dbfの各ファイル内での各シェープの順序は互いに対応している

というで、どうやら __.shp と .dbf に格納されているデータの順序で対応関係が決まっている__ ということだそうです（Wikipedia なので正しくないかもしれませんが）。

ちょっと心もとない気もする弱い結びつきですが、この結びつきによって複数のファイル群から構成されるデータが ArcGIS 上で単一のファイルとして利用できるようになるようです。

## 余談

ArcGIS は実際には ArcMap, ArcCatalog などのソフトウェア群で構成されていますし、シェープファイルは .shp, .dbf などで構成されていることもわかりました。なんか ArcGIS 関係のものはちょっとわかりにくいものが多いですね...。
ElastiCacheの設定に要注意！うっかりしてると高額請求も

# ElastiCacheの設定に注意！
ある日AWSからの請求メールで$270以上もの請求があり、
不正アクセスかと思い急いで請求の内訳を確認。
するとElastiCacheの項目だけとんでもない金額になってました。
<img width="1186" alt="スクリーンショット 2018-09-03 19.07.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/254871/5b1f3cae-0293-fb9a-5895-108d8552445f.png">

調べてみると、ElastiCacheは起動しているだけで料金が発生しており、
しかも作成時デフォルトで高額の設定となるようにノードのタイプが選択されていました。
<img width="649" alt="スクリーンショット 2018-09-03 19.11.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/254871/a73f9c40-4ced-fffb-0b8b-18a90aa120d6.png">

作成するときは、メモリの小さいものに手動で設定し直す必要があります。
知らなかったとはいえこの仕様ひどすぎじゃないですかね？

個人でAWS使うときは必ず請求アラームを設定しておきましょう。

怒りに任せて一筆書きました、以上。
Anaconda環境でPyTorch 〜株価予想〜 #03 予測編

## はじめに
[株式会社クリエイス](http://creaith.jp/)の[曽宮](https://qiita.com/ryosomiya)です。  
[前回](https://qiita.com/creaith/items/f47c33e78fb97349b4c8)は、ざっくり環境構築と試しに株価を取得しました。

[Anaconda環境でPyTorch 〜株価予想〜 #01 環境構築編](https://qiita.com/creaith/items/f47c33e78fb97349b4c8)
[Anaconda環境でPyTorch 〜株価予想〜 #02 基礎知識・学習編](https://qiita.com/creaith/items/2d606a7f0effd5d839d5)
Anaconda環境でPyTorch 〜株価予想〜 #03 予測編（今回）
[Anaconda環境でPyTorch 〜株価予想〜 #04 予測(リベンジ)編](https://qiita.com/creaith/items/a7d0ba9b9cbb4be42490)
[Anaconda環境でPyTorch 〜株価予想〜 #05 表示編](https://qiita.com/creaith/items/54c1666682210d8cbce3)



前回は学習はさせましたが、予測まではできていません。
今回は学習結果を保存し、そのデータを使って予測するところまで~~やります~~やりたかったです。


### 学習結果の保存

[前回](https://qiita.com/creaith/items/2d606a7f0effd5d839d5)の続きでagent.pyに学習データを保存する処理を追加します。

```python:agent.py
import torch  # 前回からの追加行
import torch.nn as nn
import torch.optim as optim
from network import Network
from get_data import Get_data

data_code = "WIKI/AAPL"  # Quandl data code

n_prev = 30  # how much data to use to predict
hidden_size = 300  # how big hidden layer size
cell_size = 100  # how big cell layer size
learning_epochs = 5  # learning epochs

if __name__ == "__main__":
    model = Network(n_prev, hidden_size, cell_size)
    data_from = Get_data(n_prev, data_code)
    loss_function = nn.MSELoss()
    optimizer = optim.Adam(model.parameters(), lr=0.1)

    raw_data = data_from.get_raw_data()

    for learn in range(learning_epochs):
        for day in range(n_prev, len(raw_data) - 1):
            material, target = data_from.get_data(day)
            predict = model(material)
            loss = loss_function(predict, target)
            loss.backward()
            optimizer.step()

    torch.save(model.state_dict(), 'model.pth') # 前回からの追加行

```

のように最終行に`torch.save(model.state_dict(), 'model.pth')`と追加すると`model.pth`というファイルで学習結果が保存されます。
(このままだと、ローカルで実行するには時間がかかるので、`lerning_epochs=  1`にして検証しています)


## 学習結果を使い予測結果を得る
学習結果が保存できた（っぽい）ので、「よし！予測するぞ！」とイキりたってましたが、
そこまで出来ませんでした。

__そこで、__
機械学習、PyTorchに詳しい方々の知見をお借りしたいと思っております。
この学習結果を使って翌日の株価予測をする方法を__教えていただきたいです__。
よろしくお願いします。

m(_ _)m

## 次回
今回解決できなかった予測結果の出力をします。

## 別チーム
[別チームでもPyTorchの記事](https://qiita.com/creaith/items/bf513e65809ab5c5ce46)を書いています。~~進んでるぅ〜~~
[Docker環境でPyTorch 〜画像解析〜 #03 転移学習編](https://qiita.com/creaith/items/589f6fcfb205b0554a27)

## Creaithメンバー
この記事の著者：[曽宮](https://qiita.com/ryosomiya)、[モトキ](https://qiita.com/pickles)
その他メンバー：[志村](https://qiita.com/naoto1222)、[上田](https://qiita.com/uedashuhei)

## 参考
https://pytorch.org/docs/stable/autograd.html
MY SQL テーブルのCHARSETがlatin1になっていて日本語の文字列が入らなかった時の対処法

mysqlをいじっていて、テーブルを作成した時のデフォルトのCHARSETがlatin1だったので、それをutf8にしたいときにどうすればいいかメモ程度に


#特定のテーブルのCHARSETだけ変える
	ALTER TABLE テーブル名 CONVERT TO CHARACTER SET utf8;

#デフォルトでutf8にする
/etc/my.cnfに設定を書く

	[mysqld]
	character-set-server=utf8 

	[client]
	default-character-set=utf8 

そのあとにmysqldを再起動させれば設定が反映される。
ディープラーニングのコンペにチャレンジしてみる

# SIGNATEでコンペティションにチャレンジ
Kaggle参加の準備を進めているが、日本語で参加できるSIGNATEにも参加してみようと思う。

# 海洋研究開発機構 熱帯低気圧（台風等）検出アルゴリズム作成
※以下、概要からの抜粋
[掲載サイトはこちらから](https://signate.jp/competitions/134)

台風やハリケーンなどの大型の熱帯低気圧は人間生活、農業、林業、漁業、インフラに対して甚大な被害をもたらします。熱帯低気圧の発生をできる限り早く予測することは非常に重要な課題です。ところが、発生前の熱帯低気圧（熱帯低気圧のタマゴ）は専門家でさえも正しく識別するのは難しく、熱帯低気圧の発生予測を精度よく行うのは難しいのが現状です。

今回は海洋研究開発機構が提供する雲解像気象モデルNICAM [1], [2], [3]によって生成された1984年から2000年の合計17年分の大気シミュレーションデータ（画像化されたデータ）を用いて熱帯低気圧とそのタマゴを検出するアルゴリズムの作成に挑戦していただきます。 

とのことで、チャレンジ！

# とりあえず基本的なモデルからやってみよう
**学習データが半端ない！**

画像：64px×64pxのグレースケールパッチ画像
　　　水平解像度：14 km

学習用画像データ：2,244,223枚（1984年～1998年の15年分）
　　　正例：71,779枚
　　　負例：2,172,444枚

自宅のPCで処理できそうもないが、とりあえずモデル構築のあたり付けまでは自宅PCでやってみて、行けそうならクラウドを使ってみるか。

# 今後、途中経過を記録
挑戦過程(順位とか？)を記録としてアップしていければと。
たとえば、**「他参加者との情報共有は禁止」**というルールがあるので、あくまでもルールの範囲内で。
学習内容とかは、コンペが終了して結果発表があるまでは書けないねｗ
複数のファイルをワンライナーでCloudantのAttachmentsへ一括登録する

Cloudantを使っていると、ディレクトリにある全てのファイルを一括登録したくなるときがあります。
IBM Cloudantにファイルを一括で登録したくなるときがありますが、CloudantのUIだと１つずつしか登録できない。。。
しかたないのでシェルのワンライナーで実現しましょう。

```bash
# 最後のBASIC=user_name:passwordにBASIC認証のパスワードを入力する
# DOC_URL=https://your_cloudant-bluemix.com/your_db/your_document/にdocumentのURLを入力する
$ ls | xargs -L1 -I{} echo 'echo "File:{}" && curl -u $BASIC -sS "$DOC_URL" | jq -r ._rev | tr -d \\r\\n | xargs -L1 -I__rev curl -u $BASIC -XPUT --url "$DOC_URL"'{}?rev=__rev' --data-binary @{}' | BASIC=user_name:password DOC_URL=https://your_cloudant-bluemix.com/your_db/your_document/ bash
```

**どんなに多いファイルでも、Cloudantへのデータ登録は１行で。そう、シェル芸ならね。**


ファイル名を表示しつつ、ファイルをアップしてくれます。
また、**[単一のattachmentsファイルの最大サイズは10MBまで](https://console.bluemix.net/docs/services/Cloudant/offerings/bluemix.html#maximum-individual-document-size#request-and-document-size-limits)**なので、ファイルサイズには気をつけましょう。

![output.gif](https://qiita-image-store.s3.amazonaws.com/0/155890/609fa21c-dba3-a830-1c9a-1ae4c93ee498.gif)

## 参考
https://console.bluemix.net/docs/services/Cloudant/api/attachments.html#attachments
Google Cloud Storage試行「オブジェクトの一般公開」

# 前提
- GCP環境は保持済み。

# 実践
## 01.バケットを作る
![01.png](https://qiita-image-store.s3.amazonaws.com/0/180599/ca28af00-a816-1be9-a7b1-3019e44d37ba.png)

## 02.名前などは適当
![02.png](https://qiita-image-store.s3.amazonaws.com/0/180599/db97a7b1-f7ac-6e5b-4199-cfe6e2f6dceb.png)

## 03.バケットの下にフォルダーを切って
![03.png](https://qiita-image-store.s3.amazonaws.com/0/180599/005f5bf3-a8d1-2212-1c8e-0208f03b4d91.png)

![04.png](https://qiita-image-store.s3.amazonaws.com/0/180599/4959381e-a7ec-74d7-e6a0-5c9cfd106b64.png)

## 04.できたフォルダー内に入って
![05.png](https://qiita-image-store.s3.amazonaws.com/0/180599/107c7dd7-a7fa-f702-1495-e37d82387c9a.png)

## 05.適当なファイル「ocean.png」をアップロード
![06.png](https://qiita-image-store.s3.amazonaws.com/0/180599/cab82d01-09ab-b981-f5d9-b8dd4c5cd282.png)

## 06.できたファイルのリンクを押すと
![07.png](https://qiita-image-store.s3.amazonaws.com/0/180599/a6842ef5-c732-bee6-aa5e-51fbd440316f.png)

## 07.以下のようなURLでファイルが参照できる
https://25e9e6〜〜〜〜b9dchc3b〜〜〜〜0c9b791uui-apidata.googleusercontent.com/download/storage/v1/b/xxx-tutorial-bucket-01/o/xxx-folder-01%2Focean.jpg?qk=G89MEtE6Cf1Ieo〜〜

でも、これは、あくまで認証済みの自分しか見えないもの（のはず）。
![08.png](https://qiita-image-store.s3.amazonaws.com/0/180599/13bbcd00-ba95-e5a5-123a-4e4a6cc76d38.png)

## 08.なので、一般公開してみる
![09.png](https://qiita-image-store.s3.amazonaws.com/0/180599/7dcb5efa-f8b5-af79-35c1-1f08ec7f8f5d.png)
![10.png](https://qiita-image-store.s3.amazonaws.com/0/180599/269abbaf-efe1-5186-f35b-962c580239f8.png)
![11.png](https://qiita-image-store.s3.amazonaws.com/0/180599/8ca9a48b-91b2-62ea-8ff6-6baa3cc1f420.png)

## 09.公開リンクが表示されているので押下
![12.png](https://qiita-image-store.s3.amazonaws.com/0/180599/87262d1d-630a-fb54-1a55-ec4de6e40640.png)

https://storage.googleapis.com/xxx-tutorial-bucket-01/xxx-folder-01/ocean.jpg
![13.png](https://qiita-image-store.s3.amazonaws.com/0/180599/c04bf72f-b5c3-188b-1289-223b1c911d97.png)

↑のリンクはスマホなどで見ても、表示される。

## 10.今度は一般公開設定の解除
![14.png](https://qiita-image-store.s3.amazonaws.com/0/180599/0114d76a-2da5-bc2d-a2cf-a76d5a2994a7.png)
![15.png](https://qiita-image-store.s3.amazonaws.com/0/180599/54a69416-521f-5640-ca6d-630cf9cefd52.png)
![16.png](https://qiita-image-store.s3.amazonaws.com/0/180599/766a92ec-5760-cd25-857a-950435e31bdd.png)

## 11.（★１時間ほど経過してから★）先程の公開アドレスにアクセスすると
https://storage.googleapis.com/xxx-tutorial-bucket-01/xxx-folder-01/ocean.jpg
![17.png](https://qiita-image-store.s3.amazonaws.com/0/180599/87d7670f-f2c6-34ae-5d23-cb961b1c8b74.png)

ちなみに、一般公開前のオブジェクトアップロード直後に表示した以下のアドレスにアクセスすると
![18.png](https://qiita-image-store.s3.amazonaws.com/0/180599/e8d10409-664b-9e0e-5c2e-81c220dd2022.png)

このようになった。
線・辺の定義（地理情報システム）

こんにちは。
地理情報システム（GIS）における線・辺の定義は、調べてみますと３種類あるようです：

(1) 回転楕円体面の測地線   （例：GeographicLib, RethinkDB）
(2) 球面投影した大円   （例：D3.js、S2 Geometry Library, ArangoDB 3.4 or later）
(3) 正距円筒図法影した直線  （例：GeoJSON, GDAL, GEOS geometry library, Boost.Geometry, ほか大多数）

多角形領域内に与点が含まれるかどうかの判定では、上記の違いの差が生じます。（ただし線長距離計算の際は、(3) の例示システムも当然ですが (1) or (2) の定義で計算しています。）

なお (1) の回転楕円体定義の GIS が発達していない原因の一つは、プログラミング上の難点があると思われているからのようです。
Android端末のデータベース（SQLite）の中身を簡単に見る方法

開発しているとデータベースの値を見たいときがあると思います。
しかし、調べると古い情報にあたって出来なかったりするので、今現在の情報をまとめました。


# この記事の環境
- Android端末・・・ Android 8.0.0 ASUS_Z01KDA(ZenFone 4)
- エディタ・・・ Android Studio 3.1.4
- PC ・・・ Windows 10

# 概要
SQlite3は1つのsqliteファイル（一般的に.sqlite3の拡張子）にデータベース情報の全てが入っているので、そのsqliteファイルを端末から自分のPCにコピーしてDB Browser for SQLiteなどで確認すれば中身を見ることができる。

# Android StudioのDevice File Exploreでコピー
端末からのコピーはAndroid Studio のDevice File Exploreを使うと楽にコピーができる。

右下の「Device File Explore」をクリック
<img width="174" alt="device.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/105211/71d5be70-493b-2ba2-a618-f0e431f2fac0.png">

クリックすると端末内のファイルエクスプローラーが表示される。
<img width="417" alt="dddd.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/105211/8cd66cb5-2b27-cca8-cf92-e072574cc562.png">

sqliteファイルの場所は```/data/data/(アプリのパッケージ名)/databases/(sqliteファイル名)```にある
※sqliteファイル名はSQLiteOpenHelperクラスを継承したクラスで指定した名前になる

sqliteファイル上で右クリック→保存 で自分のPCの好きな場所に保存できる

# コマンドでsqliteファイルをコピー
Terminalから下記のコマンドでsqliteファイルがコピーできます

```
adb exec-out run-as (アプリのパッケージ名) cat databases/(sqliteファイル名) > (コピー先の自分のPCでのパス名)
```

## 解説

- `adb exec-out (コマンド)` ・・・コマンド自体の解説は出てこなかったのだが、おそらく`adb shell`として端末にログインしたときのユーザーとしてコマンドを実行し、その端末での標準出力を自分のPCでの出力として出力するコマンドではなかと思う。
- `run-as (アプリのパッケージ名) (コマンド)` ・・・そのアプリのパッケージのユーザーとして実行するコマンド。
`/data/data/(アプリのパッケージ名)/`がそのユーザーのホームディレクトリになる。


## ググったらよくある
1. 端末のsqliteファイルを端末内でみんながアクセスできる場所（SDカードなど）に`cat (コピー元) > (コピー先)`でコピー
2. そこから`adb pull`で自分のPCにコピー

という手法は今は1.ができないのでできません。

#参考リンク
- [nyan のアプリ開発 - [Android] Device File Explorer でファイルをのぞいてみた](https://akira-watson.com/android/file-sys.html#1)
- [吟遊詩人の戯言 - 【#Android】’Lolipop’以降で，cat使ってSQLite3ファイルを取得したらサイズ０の対策を見つけた](http://gurizuri0505.halfmoon.jp/20161031/81756)
- [Qiita - [Android]端末にあるデータベースの中身を見る方法](https://qiita.com/korin0021/items/8873d2efbe5459c20694)