OmniAICreator/Qiita-1.07M huggingface dataset:
nvm +  Node.js + npmのインストール

# Node.js始めました

いろいろあってNode.jsを触り始めました。
備忘録も兼ねて、これからぼちぼち記事を書いていきます。

## 構成について

Node.js自体バージョンアップが頻繁であり、また、バージョン毎の差異で動作に支障が出ることも多いらしく[^1]、Node.js自体を管理する**[nvm(Node Version Manager)](https://github.com/creationix/nvm)**をインストールした上で、nvmにNode.jsを管理させる形が良しとされている。
その為、nvmからインストールしていく。

# nvmのインストール

[nvmのドキュメント](https://github.com/creationix/nvm#install-script)を参考にしながら以下のコマンドを実行。

```bash
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
```

インストール後は`.bash_profile`に以下の文が追加される（Vagrant環境の場合）。

```bash
export NVM_DIR="/home/vagrant/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
```

## Macの場合

`.bash_profile`が無い場合、上記のexport〜の設定がされないので手動で作成する。

```bash
touch ~/.bash_profile
```

```bash:.bash_profile
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
```

# Node.js + npmのインストール

とりあえず最新のLTSをインストールする。

```bash
nvm install --lts
nvm use --lts
```

```bash
node -v
```

でバージョンが表示されればOK。

```
MacBook:~ sansaisoba$ node -v
v8.11.3
```


### LTSとは

Long Term Supportの略で、「長期サポート」的な意味。

https://nodejs.org/ja/download/

ここのダウンロードページに「推奨版」と書いているとおり、安定稼働の推奨版だと思えば良い。
記事執筆時点でのLTSはv8.11.3。

## デフォルトの設定

このままだとsshでログアウトして再接続後は有効にならないので、
defaultのバージョンを指定しておく。これでログイン後にすぐ使える。

```bash
nvm alias default lts/*
```

[別の記事](http://qiita.com/dribble13/items/e895208727c85ef9bc52)では、`.bash_profile`に`nvm use default`を書き込んでいるような記載もあるが、`nvm alias default`の設定をしておけば不要。

# うまく動作しない場合

## nvm: command not found

[nvmのNoteにも書かれている通り](https://github.com/creationix/nvm#install-script)Macであれば`.bash_profile`があるか、上記の記載があるかどうかを確認する。
nvm自体は、`~/.nvm`以下にインストールされるので、このディレクトリも存在するとか念のため確認する。

## node: command not found

再ログイン後に`node: command not found`になるのであれば、
`nvm use --lts`や`nvm alias default lts/*`を実行していないのであれば実行する。

-----

[^1]: そのためか、導入記事だけでも１年前の記事が古くなってたりするのが多いので、こうやって初心者記事を再度まとめようという動機にもなりました…。（そしてこの記事もすっかり古くなったけど未だに参照されているので若干更新@07/2018）
Visual Studio for Mac PREVIEWをインストールしてみた

##概要

Visual Studio for Mac <sup>PREVIEW</sup> が発表されたということで、早速お試し。
Xamarinに興味もあったので。

##記事の執筆時点

プレビュー版ということもあり、どんどん更新もされていくと思うので、念のため執筆時点の日付を記しておく。
2016.11.18時点での情報を基に記載している。

##環境構築

###Visual Studio for Mac <sup>PREVIEW</sup> のインストール

手順を一通り書いていたんだけど、公式サイトの[Introducing Visual Studio for Mac](https://developer.xamarin.com/guides/cross-platform/visual-studio-mac/)も後から見つけたので、そっちを残しておく。

私の環境でインストールに必要な容量は約18GBぐらいだったみたい。
これにAndroid SDKやiOS SDKもインストールしないといけないので、50GBぐらい容量に空きがないと、実際の開発業務には使えないかもしれない。

###.NET Coreのインストール

上述した公式サイトに書いてあったので、インストール。
リンクもそこにあるけど、念のため。
[.NET Core site](https://www.microsoft.com/net/core#macos)

ここからインストーラーをダウンロードして、インストール。

###アップデートしろって言われるので、従ってみる

早速起動したら、Xamarin Profilerをアップデートしてねって言われたので、言うとおりにしてみる。
…アップデートに失敗したよ。

![アップデート失敗.png](https://qiita-image-store.s3.amazonaws.com/0/81221/0ddbf992-34c4-e01a-db1d-a4ec47931d5d.png "アップデート失敗.png")

ま、プレビュー版だしね。
PC再起動したらいけたりするのかな。

###起動してみての感想

おお、メニュー類が日本語！
ちょっと嬉しい。
英語でも別にいいんだけど、初めて使うIDEだとメニュー操作に時間かかるので、そこがわかりやすいので、ありがたい。

###サインインをしておく

Microsoft Credentialsでサインイン。
このサインイン、5分ぐらいローディングが続くので、注意ね。

もしアカウントがなかったら作っておくと[Visual Studio Team Services](https://www.microsoft.com/ja-jp/dev/products/visual-studio-online.aspx)も使えるので、便利。

##サンプル作ってみるのは別記事に

せっかくなので、[Xamarin.Forms](https://www.xlsoft.com/jp/products/xamarin/xamarin_forms_intro.html)で作ってみようと思う。
けど、結構時間かかりそうなので、別記事でそのうち。

追記：
書いた。
[Visual Studio for MacでXamarinのチュートリアルアプリを作ってみた](http://qiita.com/BlackCat/items/c60694e625f9ed1b2ebb#_reference-5df3cd09ea20a44fbfa9)

参照：
[Xamarin.Forms 入門](https://www.xlsoft.com/jp/products/xamarin/xamarin_forms_intro.html)
[Xamarin.Forms Samples(公式)](https://developer.xamarin.com/samples/xamarin-forms/All/)

##まとめ

Visual Studioって銘打ってるけど、Xamarin Studioでしたって感じ。
クロスプラットフォーム、憧れるんだけど、Xamarinは結構ハードルが高い印象。
UI部分がある程度共有化できるといえど、独自部分はiOS、Androidのネイティブ開発を理解していないと対応できないと思う。
さらにXamarin独特のお作法の習得となると、学習コストは馬鹿にならないと感じた。
ビジネスロジックが共有できるという最大のメリットはかなり大きいものの、サービスを継続して続けていくためにXamarinができる人を確保する必要があるわけで、果たしてiOS、Androidの技術者ほど見つかるものなのか。

まー、でもMicrosoftにがんばってもらって、シェアが広がっていったら面白いよね。
いい加減アイドル巡業みたいなのはやめてほしいんだけど、まずは知ってもらう必要があるから、しかたないか。
Xamarinを普及させるためにはMicrosoft以外から技術的に引っ張ってく人が必要なんじゃないかなー。
すでにいらっしゃるのかもしれないけど。
NHK WorldをLinux端末から視聴

2016年11月19日現在、NHK Worldをライブ視聴しようとすると「Live streaming not available on this browser.」と表示されて再生できない。

VLC Media Playerで直接ストリームのURLを叩けば解決した。

# 手順

http://www3.nhk.or.jp/nhkworld/app/tv/hlslive_tv.xml

を開き、一番上にあるURLをコピーする。

次にVLCを開き、Open media > Network に、上でコピーしたURLを入れれば視聴可能。

NHKは公共の放送局なのだから、広範な端末に対応してほしい。

# 参考

http://askubuntu.com/questions/704612/nhk-live-streaming-not-available-on-this-browser
Chromeのブックマークバーにfaviconを並べると便利

超ウルトラ小ネタ。

Chromeでブックマークするときに、名前を空欄にすると…

<img width="363" alt="スクリーンショット 2016-11-19 14.02.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/145575/6b0917b3-31b1-ddfe-412c-03cb2610d860.png">

ブックマークバーにfaviconだけを並べることができます。
<img width="251" alt="スクリーンショット 2016-11-19 14.00.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/145575/e5a9fccf-87bf-04f4-066e-970879cb974a.png">

きれい！　すっきり！

おしまい。
【Linux】yumコマンド

投稿日：2016-11-19

# 環境
- Amazon Linux AMI 2016.09-release

# yumコマンド
##### パッケージをインストールする
`yum install [パッケージ]`

##### サーバーにあるパッケージを一覧する
`yum list`

##### パッケージの情報を表示する
`yum info [パッケージ]`

##### 既にインストールしたソフトウェアの一覧を表示
`yum list installed`

###### インストールしているか探す
`yum list installed | grep [パッケージ]`

##### ソフトウェアをアップデート
###### 更新情報の確認
yum check-update

###### 更新
`yum update
[パッケージ]を指定することも可能

###### セキュリティ更新の確認
`yum --security check-update`

###### セキュリティ更新
`yum --security update`

##### ソフトウェアをアンインストール
`yum remove [パッケージ]`

##### 外部リポジトリを追加


```
epel
$ rpm -ivh http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
```

```
remi
$ rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
```

##### OSによって適切なURLを探して変更する

######epel
http://ftp-srv2.kddilabs.jp/Linux/

######remi
http://rpms.famillecollet.com/enterprise/


##### よく使うオプション
###### y/n をスキップ
`yumコマンドの直後に　-ｙ　をつけると、全自動でyesになります`

###### リポジトリを指定
`-enablerepo=[リポジトリ] `
【備忘録】Ruby ワンライナー(1行)でメソッド定義


```ruby
# クラスメソッドを定義
class TestData
  class << self

    # 一般的なメソッド定義
    def hoge1
        "hoge1"
    end
    
    # １行でメソッド定義（文字列を返す）
    def hoge2() "hoge2"  end
    define_method(:hoge3) { "hoge3" }
    
     # １行でメソッド定義（ハッシュを返す）
    def hoge4() { foo: "foo", bar: "bbb" } end
    define_method(:hoge5) { { foo: "foo", bar: "bbb" } }
    
  end
end

# メソッドを呼び出す
puts TestData.hoge1 # => hoge1

puts TestData.hoge2 # => hoge2
puts TestData.hoge3 # => hoge3

puts TestData.hoge4[:foo] # => foo
puts TestData.hoge5[:foo] # => foo
```
【備忘録】Ruby クラスメソッド定義

# クラスメソッド

## 特異メソッド方式

```ruby
# クラスメソッド
class Hoge
  def self.foo
    puts "foo"
  end
end

# クラス定義の外でもメソッド定義できる
def Hoge.bar
    puts 'bar'
end

# インスタンス化しなくてもメソッドが実行できる
Hoge.foo # => foo
Hoge.bar # => bar

Hoge::foo # => foo
Hoge::bar # => bar
```

```ruby
# クラスメソッド
class Hoge
  def Hoge.foo
    puts "foo"
  end
end

# クラス定義の外でもメソッド定義できる
def Hoge.bar
    puts 'bar'
end

# インスタンス化しなくてもメソッドが実行できる
Hoge.foo # => foo
Hoge.bar # => bar

Hoge::foo # => foo
Hoge::bar # => bar
```

## 特異クラス方式

```ruby
# クラスメソッド
class Hoge
  class << self
    attr_accessor :title

    def foo
      puts "foo"
    end

  end
end

# インスタンス化しなくてもメソッドが実行できる
Hoge.foo # => foo

# インスタンス化しなくても変数が読み書きできる
puts Hoge.title # => nil

Hoge.title = "123"
puts Hoge.title # => 123
```

# インスタンスメソッド

```ruby
# インスタンスメソッド
class Hoge
  attr_accessor :title

  def initialize
    @title = 0
  end

  def foo
    puts "foo"
  end

end

# インスタンス化するとメソッドが実行できる
hoge = Hoge.new
hoge.foo # => foo

# インスタンス変数が読み書きできる
puts hoge.title # => 0
puts hoge.title # => 123"
```
Tomcat8.5.XにおけるsetMaxAgeの挙動(期限付きCookie作成時の注意)

8.5.XからsetMaxAgeで期限付きCookieを設定する際のレスポンスヘッダ出力に変更があります。影響があるのはIEのみですが、Tomcatのバージョンを上げる場合は注意が必要です。

**挙動の違い**
8.5.X系のTomcatから、CookieにsetMaxAge()を設定した場合、レスポンスヘッダの出力項目が変わります。

```java:Cookie.java
Cookie newCookie = new Cookie("CTEST", "kusa");
newCookie.setMaxAge(600);
response.addCookie(newCookie);
```

**レスポンスヘッダの出力**
現時点(2016/11)での最新を取得して比較します。
8.0.39 OR 8.5.8

```log:responce
#8.0.39
HTTP/1.1 200 OK
Set-Cookie: CTEST=kusa; Expires=Sat, 19-Nov-2016 04:02:57 GMT

#8.5.8
HTTP/1.1 200
Set-Cookie: CTEST=kusa;Max-Age=600
```

Expiresと出力していた部分が、Max-Ageという出力になっています。IEの場合、Max-Ageを無視するため、setMaxAgeで期限を設定してもセッション間で有効なCookieとなるため注意が必要です。

![nw_head.png](https://qiita-image-store.s3.amazonaws.com/0/110457/bab70a0b-da13-cd0a-5ba3-4c5411bed124.png)

![cookie_nw.png](https://qiita-image-store.s3.amazonaws.com/0/110457/08f7cbaa-fe49-3903-761b-176232f00ff8.png)

上記は、Windows7/IE11のレスポンス結果です。Cookieの有効期限に日付が入って欲しいのですが、MaxAgeを無視しているため、セッションとなっています。動作環境がないため、Edgeでは確認できていません。

setMaxAgeの挙動を　8.0.X以前に戻す場合は以下の方法があるようです。
http://stackoverflow.com/questions/38696081/how-to-change-cookie-processor-to-legacycookieprocessor-in-tomcat-8
[Win10]粗悪なノートPCのためにVBScriptのピン止めでスクリーンキーボードを登録する

[【VBS】Windowsアプリケーションを起動するコードサンプル](http://qiita.com/mono_cat/items/2d29427dd82948d1df9a)
という素敵なページがあります。
これと、[Win10 安物ノートPC用にデフォルトキーモードVBSを登録する](http://qiita.com/Q11Q/items/99664a3fa716ff3469ed)
こちらを組み合わせてみたいと思います。
それにしても昨今の激安PCはひどいですね。
Breakキーも右クリックキーもスクリーンロックキーもないなんていうのがあります。こんなの欠陥商品では？
　特にマクロを使う時の強制終了のCtrl+Breakなんて使われないのでしょう。Ctrl+FN+右シフトキーが代用なんてわかるわけがないだろう。
　プログラムを組む人ってそんなに少ないのでしょうか。
　仕方がないのでせめてスクリーンキーボードを表示させましょう。このソフトの名前osk.exe on screen keyboardというのも安直ですね。
　これはOsk.exe自体をピン止めしてもいいでしょう。事実私はスタート画面にもピン止めしています。（というかそうしておかないと危ない）
　しかしタスクバーはピン止めをすると狭くなってしまいます。激安ならなおさらです。
ここでVBSを使ってタスクバーに登録すると、一つのピン止めでいろいろなアプリがピン止めされたことになるわけです。メモ帳、Calc、こうしたものが一つにまとめられるわけです。自分の都合上サクラエディタも作ります。

####スクリーンキーボード

```VB:スクキー.vbs

CreateObject("WScript.Shell").Run "%windir%\system32\osk.exe", 1, False

```

####メモ帳

```VB:メモ帳.vbs

CreateObject("WScript.Shell").Run "%windir%\system32\notepad.exe", 1, False

```

####計算機

```VB:計算機.vbs

CreateObject("WScript.Shell").Run "%windir%\system32\calc.exe", 1, False

```

####サクラエディタ
サクラエディタはフリーのテキストエディタです。[http://sakura-editor.sourceforge.net/index.html.ja](http://sakura-editor.sourceforge.net/index.html.ja)
32bit版です。プログラムファイルズ(x86)に入っていますが、[三重ダブルクォーテーション](http://jutememo.blogspot.jp/2014/03/vbscript-2.html)にします。


```VB:サクラE.vbs

CreateObject("WScript.Shell").Run   """C:\Program Files (x86)\sakura\sakura.exe""" ,1 ,False

```

これらをメモ帳を起動して、コピペし、.vbsとして保存します。.txtにならないようにしてください。文字コードはAnsiでよいはずです。

なお、スクリプトを登録するフォルダは %USERPROFILE%\Onedrive\ドキュメント\Scripts
と言ったフォルダを作ってある程度まとめて置いています。わたくしは前回述べた通りサクラエディタのフォルダに置くなどしています。

そして保存したスクリプトを一度起動させて、タスクバーのVBSのアイコンを右クリックし、最近使ったファイルに出てきたものをピン止めします。

これでまあスクリーンキーボードもでてくるようになりました。
lockステートメントで注意すべきコト

#概要

`lock`ステートメントを利用した相互排他ロックを利用する際に留意すべき点をいくつかまとめてみました。

また、`lock(<obj>)`の`<obj>`の部分を以下`ロックトークン（Lock token）`と呼称することにします。

#型引数を利用した場合

メソッドなどのパラメータによって貰ってきたエンティティをロックトークンにすることはデッドロックをはじめとする厄介ゴトの根源みたいなもんなので避けるか使うにしても相当注意すべきでしょうが、まぁサンプルなので以下のようなメソッドが有るとします。

以下のようなメソッドを考えてみます。

```csharp

static void LockSample<T>(T lockToken)
{
	lock (lockToken)
	{
		foreach (var c in "Lock!")
		{
			Console.Write(c);
			Thread.Sleep(10);
		}
		Console.WriteLine();
	}
}
```

パラメータ使ったロックは色々と問題がありますが、まぁ話を単純化するってコトでご理解下さい。
こいつを、以下のように呼び出したとします。

```csharp
static void Main(string[] args)
{
	object lockToken=new object();

	Parallel.For(0, 10, i => { LockSample(lockToken); });
}
```

この場合、想定通り、”Lock!”というキャラクタがコンソールに10個出て終了となります。
他方、下記の場合は想定外の結果になると思います。

```csharp

static void Main(string[] args)
{
	int lockToken = 10;

	Parallel.For(0, 10, i => { LockSample(lockToken); });
}
```

実行結果は神のみぞ知るとしか言い様がありませんが、あらかた想定通りとは行かないと思ったり。

##なんでこんなことになるのか？

本来、ロックトークンは参照型であることが条件なので、以下のようなコードはメソッド名通り`CS0185`が発生しちまう。

```csharp

static void OccurCS0185(int i)
{
	lock (i)
	{
		foreach (var c in "Lock!")
		{
			Console.Write(c);
			Thread.Sleep(10);
		}
		Console.WriteLine();
	}
}

```


けれど、型引数を利用した場合、型引数に`where T:class`のような制約無しで、コンパイルは通るし、実行も出来ちまう。
その結果、Tが値型になった場合、本来コンパイルすら出来ないのにコンパイルも実行も可能になってしまい、結果が破綻することになる。
ちなみに、なぜコンパイル出来ちまうかというと、先の`LockSample`はばらしてみると概ね以下のような状況になってるから。

```csharp
static void LockSampleReveal<T>(T lockToken)
{
	object token = lockToken;

	lock (token)
	{
		foreach (var c in "Lock!")
		{
			Console.Write(c);
			Thread.Sleep(10);
		}
		Console.WriteLine();
	}
}
```
一度、`objecdt`型のローカル変数で`lockToeken`を受けているので、参照型という条件を満たしている。但し、Tが値型の場合、`token`への代入は、ボックス化が伴うので、呼び出し毎に別個のエンティティが作成されてしまいlockが用をなさなくなっちまう。


この辺、実はC#6のRCではコンパイルエラーになってくれていた。けれどリリースでRejectされちまった事実があるので、Microsoftも問題を認識しつつも、その影響のでかさゆえ手を着けることができないんじゃ無いかなとか思ってる。


#まとめと蛇足

このように、型引数をロックトークンとしてしまった場合、意味を成さないロックになってしまうことが有るので、注意が必要となるかなと。

また、剥き身で使うことはそうそう無いだろうけど、`Monitor.Enter`はロックトークンの型が`object`なので、基本何でも入るけど結果は先ほどと同じなので、その辺も注意した方が良いかなと思います。
GAEでLINE Message API(line-bot-sdk-python)を試してみた

LINE BOT AWARDS の発表をうけて、自分もLine Message APIを試してみました。
機械学習を使ったLINEのBotを作ってみようという軽い気持ちではじめています。
GAEがLINEのBotと相性がよさそうだったので、使わせていただきました。

#Line Message APIを使えるようにする設定
[コチラ]
(https://bita.jp/dml/line-messaging-api-exp)を参考に設定をしていきます。

下記のBot設定は少し注意が必要かもしれません。
どうゆう設定をしたか気にしておきます。

![snip_20161117132901.png](https://qiita-image-store.s3.amazonaws.com/0/121860/3cd14fec-2e5b-c4ec-3f46-1617881c5bfc.png)

#Google Cloud Shellを使う
Google Cloud Shellだと、ブラウザ上で手軽に作業できるので楽です。


1. [Google Cloud Console](https://console.cloud.google.com/?hl=ja) にアクセス。

2. 右上にある Cloud Shell アイコンをクリック。
![googleshell.png](https://qiita-image-store.s3.amazonaws.com/0/121860/196c8da8-63f7-c578-af70-f17814664979.png)

3. Google Cloud Console の画面下に表示されるのでココで作業していきます。
![shellconsole.png](https://qiita-image-store.s3.amazonaws.com/0/121860/59d9e39d-f42e-4e89-eb2b-1719b7b289ac.png)

#Botのコード
[line-bot-sdk-python]
(https://github.com/line/line-bot-sdk-python) のGitHubを見ながら実装していきました。

しかし、GAEは外部にリクエストを送るのにURLFetch APIを使う必要があるので。。
ここでどうやって解決しようかと悩みましたが
イメージに近いコードをあげてくださっている方がいてとても助かりました。
[参考にしたコード](https://github.com/mursts/recommend-lunch-BOT)

出来上がったコードは下記になります。
https://github.com/mochan-tk/line-bot-python-sample

#作業開始
ここからGoogle Cloud Shellを使って作業していきましょう。

まず、GitHubからコードをクローン  

```
$ git clone https://github.com/mochan-tk/line-bot-python-sample.git
```

フォルダを移動し

```
$ cd line-bot-python-sample
```

app.yamlの projectをご自分の環境にあわせて変更

```
$ vi app.yaml
```

下記のファイル に SecretキーとAccess Token を設定します

```
$ vi config.py
```

SecretキーとAccess Tokenは LINE developersのサイトにあるものですね
![gamen1.png](https://qiita-image-store.s3.amazonaws.com/0/121860/08d98781-6e0e-dba9-f74a-b3048b6d8275.png)

下の項目にそれぞれあって、「SHOW」ボタン、「ISSUE」ボタンを押すと表示されます
![gamen2.png](https://qiita-image-store.s3.amazonaws.com/0/121860/a5c461bc-039d-051c-81ca-f678029fabf6.png)
![gamen3.png](https://qiita-image-store.s3.amazonaws.com/0/121860/9417a2ff-3cf5-e9c3-3abf-67cc1d170985.png)


そして、必要なライブラリを追加

```
$ mkdir lib
$ pip install -t lib flask
$ pip install -t lib line-bot-sdk
```

以上です^^

#デプロイ

下記を実行してデプロイ

```
$ appcfg.py update .
```


最後にLINE developersのサイトで「Webhook URL」の設定をします

![gamen-new.png](https://qiita-image-store.s3.amazonaws.com/0/121860/5e4c3864-6ec1-c401-c5d3-b686d9192001.png)


画面下にある「EDIT」ボタンから編集できます
![gamen5.png](https://qiita-image-store.s3.amazonaws.com/0/121860/58140a63-9cb4-77de-ed24-e4a01c6ef928.png)


これで完了です！
LINEから「友達」追加を行って動作を確認してみましょう！
<img width="320" alt="IMG_3855.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/121860/a1e3f5d0-4e47-47b2-a4ef-0aa855d30078.jpeg">

#まとめ
GAEであればフルマネージドなサービスが受けられるため、開発のみに専念できます。
Task Queueなどの機能が使えるのもありがたいです。

Botのコードに関しては、コアな処理を除くと共通で使いまわせるロジックがあると思っています。
より良いLINE Botがうまれるためにも、自分もできるだけコードを共有して他の開発者の助けになるよう頑張っていきたいです。

今回は本当にBotが動作するまでですが、ココから機械学習を含めた詳細な処理を実装していこうと思っています！
続く。。。



# 追記
## 2016/11/20 (Sun) 14:00

LINE developersのサイトの「VERIFY」ボタンを押した時に、サーバーのログに
LineBotApiError [Invalid reply token] のメッセージが出ているかと思います。
LINEさんに確認したところ、「VERIFY」の処理は疎通確認が主なので、Tokenの整合性までは
意識していない処理になっている(?) とのことで、LINEアプリからの応答処理でサーバーに
本件のエラーメッセージが出ていなければ問題無さそうでした。
本件は問い合わせも何件かきているので、修正していく方針とのことでした。
そのうち出なくなる現象と思われます。
ActiveJobを実行するメモ


Railsの機能にActiveJobというものがあって、これを使うとバックグラウンドで動くジョブを登録できたり、コマンドラインからRailsに触れたりするみたいです。
ActionCableの使い方を調べていて、サーバーのコマンドラインからクライアントに対して何かできたらいいなぁ〜と思っていたので、まずActiveJobの使い方を調べることにしました。

##ジョブをつくる
`rails`コマンドで作成できるみたいです。

```console
rails generate job HelloWorld
```

`app/jobs`ディレクトリの下に、ファイルが作成されました。

```
create  test/jobs/hello_world_job_test.rb
create  app/jobs/hello_world_job.rb
```

作成されたファイルを開き、`perform`メソッドの中に実行したいことを書いていくようです。

```ruby:app/jobs/hello_world_job.rb
class HelloWorldJob < ApplicationJob
  queue_as :default

  def perform(*args)
    puts "ジョブが実行されたよ！＼(^o^)／"
  end
end
```

##ジョブを実行する

ジョブを作ったはいいけど、どうやって実行させればいいのかわかりません。どうしましょう。

###rails consoleから実行する


とりあえず`rails console`から実行してみます。

```console
rails console
```

ジョブを実行するには`perform_now`というクラスメソッドを実行します。

```:rails_console
HelloWorldJob.perform_now
```

こんな感じになりました。`async`って書いてあるので非同期で実行されたのでしょう。おそらく、ええはい、、、

```
2.3.0 :001 > HelloWorldJob.perform_now
Performing HelloWorldJob from Async(default)
ジョブが実行されたよ！＼(^o^)／
Performed HelloWorldJob from Async(default) in 0.1ms
 => nil
```

###コマンドラインから実行する
rakeコマンドを使えばできるような気がします。

rakeのタスクを作るのも`rails`コマンドでできるみたいです。すごいですね！

```console
rails generate task job helloworld
```

タスクは`lib`ディレクトリの中に作成されるんですね。

```
create  lib/tasks/job.rake
```

作成されたファイルはこんな感じになっています

```ruby:lib/tasks/job.rake
namespace :job do
  desc "TODO"
  task helloworld: :environment do
  end
end
```

説明と実行する処理を書いてこうなりました。

```ruby:lib/tasks/job.rake
namespace :job do
  desc "HelloWorldJobを実行する"
  task helloworld: :environment do
    HelloWorldJob.perform_now
  end
end
```

実行してみます。
最近はrakeタスクの実行も`rails`コマンドでやるみたいですね。知りませんでした。

```:console
rails job:helloworld
```

うまくいきました。

```
ジョブが実行されたよ！＼(^o^)／
```
GR-CITRUS ＆ WA-MIKAN

GR-CITRUSはRubyが使える小型マイコンボードで、WA-MIKANはそれにフィットしたWi-Fiモジュール兼マイクロSDカードアダプタボードとのこと

http://gadget.renesas.com/ja/product/citrus.html

Rubyと言っているが、実際にはmrubyじゃないかと思うんだけど実際のところはどうなんだろう

mrubyは２年前から興味を持っていて、それを扱える安価なボードがあったらと思っていたので、GR-CITRUSに興味ありあり

ちょうど「GR-CITRUSでIoTワークショップ」があるとのことだったので、申し込んでみた。

http://gadget.renesas.com/ja/event/2016/nov/citrus_workshop.html
[プログラミング初心者向け]GoでFizzBuzz

#Go言語でFizzBuzz

golangを使ってFizzBuzzのプログラムを買いていきたいと思います。
使用しているgoのバージョンは1.7.1です。

#Go言語とは？
プログラミング言語の一つで2009年にgoogleから発表されました。
主な特徴としては、

>軽量スレッディングのための機能、Pythonのような動的型付け言語のようなプログラミングの容易性

などがあります。 (wikipediaより引用)

#FizzBuzzとは？
3の倍数でFizz 5の倍数でBuzz 3かつ5の倍数(つまり15の倍数)でFizzBuzzをコンソールに出力させるプログラミング問題です。
基本中の基本の問題ではありますが意外と奥が深い...



#Hello worldから
まずは、goファイルを作っていきます。
go言語のファイルは.go拡張子で表現されます。

```
touch fizzbuzz.go
```

これで現在いるディレクトリにfizzbuzz.goというファイルが作成されたかと思います。

このファイルを編集してFizzBuzzのプログラムを書いていきます。
確認としてhelloworldのプログラムを書きます。

```fizzbuzz.go
pakage main

import "fmt"

func main(){
  fmt.Println("Hello, world!!")
} 
```

まず、一行目のpackageについて
goのコードは全てpackageで構成されています。
packageとは、他の言語で言うところのクラスやモジュールに似たものです。
packageは一つ、もしくは複数の.goファイルから構成されていて、それぞれのファイルはそのpackageが何をするのかを決めています。

その下のimportでは何をしているのでしょうか？
それは、import文によってgoのパッケージを読み込んでいるのです。
fmtは入出力をするための関数が含まれているパッケージです。

これを読み込まないとfmt.Printlnは動きません。

**では、実行してみましょう！**

```
  go_practice git:(master) ✗ go run fizzbuzz.go                 
Hello, world!!
```

**Hello,worldが出力されましたね。**


ここでgoのコマンドについて少し解説します。

まず、go言語はコンパイル言語です。
コンパイルすることによってソースコードを機械語に翻訳し、コンピューターに命令を送っています。
run コマンドはファイルをコンパイルし、ファイルを実行します。

コンパイルしたファイルを実行せずに保存する場合はbuildコマンドを使います。

```
go build fizzbuzz.go
```
このコマンドによってファイルがコンパイルされfizzbuzzというバイナリファイルが生成されます。
実行する場合は、./fizzbuzzを入力します。

```
./fizzbuzz

Hello, world!!
```


#FizzBuzzを書こう!

では本題のfizzbuzzのプログラムを買いていきましょう！

色々なやり方がありますが、今回はシンプルに条件分岐を用いた方法で実装していきます。

## if文について

if文はif 条件式　と書いたときに条件が真であればブロック({})で囲まれた中身の命令を実行します。
偽であれば実行されません。

goでは ``if 条件部 {}`` という形式で書きます。

##変数
試しに xの値が3のときに文字列"xは3です"と出力されるようにプログラムを書きます。
変数の宣言は、 ``var x string`` のように var 変数名　型と宣言します。
宣言するときに代入を行いたい場合は var x := value というようにします。

```fizzbuzz.go
pakage main

import "fmt"

func main(){
  var x := 3

  if x == 3 {
    fmt.Println("xは3です。")
  }
}  
```

```
go run fizzbuzz.go

xは3です。
```

##ループ
go言語でループをさせいときは、for文を使えます。
ループも色々とあるのですがfor文を使っていきたいと思います。

for 初期化式;条件式;位置ループ終わったときの処理 {}
という風に書きます。

##fizzbuzz

これだけでfizzbuzzを書くことができちゃいます。
※なお、ここでは100までの数字に対してfizzbuzzしていきたいと思います。

```fizzbuzz.go
package main

import "fmt"

func main(){
  for i := 1; i <= 100 ; i++ {
    if i%3 == 0 && i % 5 == 0 {
      fmt.Println("FizzBuzz")
    } else if i%3 == 0 {
      fmt.Println("Fizz")
    } else if i%5 == 0 {
      fmt.Println("Buzz")
    } else {
      fmt.Println(i)
    }
  }
}

```

出力は...

```
➜  go_practice git:(master) ✗ go run fizzbuzz.go                 (git)-[master]
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
31
32
Fizz
34
Buzz
Fizz
37
38
Fizz
Buzz
41
Fizz
43
44
FizzBuzz
46
47
Fizz
49
Buzz
Fizz
52
53
Fizz
Buzz
56
Fizz
58
59
FizzBuzz
61
62
Fizz
64
Buzz
Fizz
67
68
Fizz
Buzz
71
Fizz
73
74
FizzBuzz
76
77
Fizz
79
Buzz
Fizz
82
83
Fizz
Buzz
86
Fizz
88
89
FizzBuzz
91
92
Fizz
94
Buzz
Fizz
97
98
Fizz
Buzz
```

うまくいきました！

いかがでしたでしょうか？
基本中の基本の問題なので簡単に解けたかもしれません。
しかし、意外とfizzbuzzだけでも言語の特徴が見えてくるので奥が深い問題だと思います。

これからもgoでアルゴリズム問題を解いていこうと思っているのでよろしければ見てくださいね！
AzureBotServiceのSkypeBotを試してみた

**AzureBotService**が11/15にリリースされたようです。
MicrosoftBotFrameworkを使ったSkype用BotをAWSLambdaで実行しているBot職人としては触らない選択肢はない！！
Azureも触ってみなきゃと思いつつ、よいきっかけがなかったので初めて手を出してみました。

## AzureBotServiceとは
AzureFunctionで実行するBot専用Serviceです。
AzureFunctionはAWSでいうLambdaのようなFunction as a Serviceですので、今はやりのサーバレスですね。
https://azure.microsoft.com/ja-jp/services/bot-service/

AzureですのでもちろんMicrosoftBotFramework上で動くBotを作るためのサービスになっています。

## Botを作ってみる

以下の手順にそってやってみます。
https://blogs.msdn.microsoft.com/bluesky/2016/11/16/how-to-create-publish-bot-using-azure-bot-service/

テンプレートを実行するだけなので特にはまることはなかったです。

## 感想

### MicrosoftBotFrameworkの設定が各画面に組み込まれている！

これはわかりやすい。便利。

botの設定画面
![2.JPG](https://qiita-image-store.s3.amazonaws.com/0/47589/fce3e7f6-5f6d-aa32-ab7f-b13baa7427b3.jpeg)

各チャネルの設定画面
![1.JPG](https://qiita-image-store.s3.amazonaws.com/0/47589/88e5389e-5545-265e-435c-7118232e2c73.jpeg)

### 何もしなくても動くテンプレート

C#をまともに触ったことないですが、これくらいまで書かれていると触ろうという気になります。
![3.JPG](https://qiita-image-store.s3.amazonaws.com/0/47589/0a54f68e-d8d7-89a8-a644-f873b196f88a.jpeg)

echoボットは以下の機能でした。

* 話しかけられた回数をカウントアップする
* resetと話しかけられると、確認ダイアログを使ってYesなら1に戻す

サンプルとはいえ、単なるテキスト返すだけじゃないのがいいですね。
コードもわかりやすく、見るとすぐわかると思います。

### Skypeでもそのまま使える！

Channelからコンタクトに追加するだけでbotがすぐに使えます。
![4.JPG](https://qiita-image-store.s3.amazonaws.com/0/47589/4ca3cb1b-2f98-5d05-c35b-37816b96cba3.jpeg)

## まとめ

AWSLambdaで実現しようと思った場合、
・LambdaFunctionを作って・・
・APIGatewayを設定して、Lambdaへパラメータを渡して※、デプロイして・・
・BotFramework側にEndpointを登録して、実際のチャットでテストして・・
という流れですが、さすがにそういう手間は省かれていてすばらしいです。

※今はAWSのAPIGatewayで、パラメータをすべてLambdaに渡すということができますが当時はできなかった。

あと、ダイアログが使えるのもいいですね（RestAPIでもできるのかな・・）


これは今後も積極的に利用していく価値はあると感じました。
使ったことはありませんが、FacebookMessengerやSlackとも連携しているようなのでそちらのBot用環境としても便利だと思います。
ofxImGuiの日本語表示・入力について


[jvcleave/ofxImGui](https://github.com/jvcleave/ofxImGui)

ofxImGuiはOpenFrameworksで使用できる、GUIライブラリ[ImGui](https://github.com/ocornut/imgui)のラッパー。
UTF-8の表示・入力にも対応しているので日本語の表示や入力も可能……のはずなのですが、実際に試したら手間取ったので備忘録を残しておきます。

結論から言うと、日本語の表示は可能ですが入力は不可能です。

日本語表示
---

フォントを予め用意した日本語フォントに設定しておけば、他の設定は不要で日本語表示が行えます。
ただし、gui.setup()の実行の前にフォント設定を行わないとデフォルトのフォントが使用されてしまいます。

```cpp
void ofApp::setup()
{
    // ※ フォント設定はgui.setupの前
	ImGuiIO& io = ImGui::GetIO();
	io.Fonts->AddFontFromFileTTF("data\\migu-1m-regular.ttf", 14.0f, nullptr, io.Fonts->GetGlyphRangesJapanese());

    //required call
    gui.setup();
```



日本語入力
---

setupにて、以下のようにIMEのハンドラ設定を行えばよいはずなのですが、InputTextにてIMEを起動すると「????」と表示されてしまい、日本語入力が行えません。

```cpp
    // MSIMEのハンドラ設定
	io.ImeWindowHandle = ofGetWin32Window();
```

[InputText show '???' when use IME #471](https://github.com/ocornut/imgui/issues/471)

OpenFrameworksと使用しているGLFWのバージョンの問題のため、現状は日本語入力は正しく行えないようです。
バージョンアップに期待。
google test のインストールでハマったのでメモ

GoogleTestをやろうとして、意外とハマったのでメモ。

# ハマった原因
+ google mockがない時代？のドキュメントが多く、ディレクトリ構成が微妙に今と違うドキュメントが多い。
+ 環境変数名で悩む（定番がどれかわからず。。。）　＝＞これは結局わからず。



# 事前準備
gitとcmakeは別途インストールなど、準備してください。
# ビルド
```
$ git clone https://github.com/google/googletest.git
$ cd googletest
$ mkdir build
$ cd build
$ cmake ..
$ make
```
# ビルド結果確認
できあがったライブラリはどこでしょう。。。

```
$ find ./ -name "*.a"
googlemock/gtest/libgtest.a
googlemock/gtest/libgtest_main.a
googlemock/libgmock.a
googlemock/libgmock_main.a
```
ありました。

gtest.hも探しておきます。

```
$ cd ..
$ find ./ -name "gtest.h"
.//googletest/include/gtest/gtest.h
.//googletest/include/gtest/internal/custom/gtest.h
```
今後使うのは、googletest/includeの方のinclude directoryです。

# ここで環境変数設定しておく

```
export GTEST_ROOT=".gitのあるディレクトリ"
export GTEST_INCLUDEDIR=$GTESTROOT/googletest/include
export GMOCK_INCLUDEDIR=$GTESTROOT/googlemock/include
export GMOCK_LIBDIR=$GTESTROOT/build/googlemock
export GTEST_LIBDIR=$GTESTROOT/build/googlemock/gtest

```
適宜、.bashrcなどに書いておく。

# 環境変数のチェック

環境変数の設定間違えるとハマるのでチェック

```
 $ ls $GMOCK_INCLUDEDIR
gmock

$ ls $GTEST_INCLUDEDIR                                           
gtest

$ ls $GMOCK_LIBDIR                                               
CMakeFiles              cmake_install.cmake     libgmock_main.a
CTestTestfile.cmake     gtest
Makefile                libgmock.a

$ ls $GTEST_LIBDIR
CMakeFiles              Makefile                libgtest.a
CTestTestfile.cmake     cmake_install.cmake     libgtest_main.a
```


# テストしてみる


## main()をlibgtest_main.aに任せる場合

```c++:test1.cpp
#include "gtest/gtest.h"

TEST(Test1, test11)
{
    ASSERT_EQ(1, 1);
}
```

```
$ g++ test1.cpp -I$GTEST_INCLUDEDIR -L$GTEST_LIBDIR -lgtest -lgtest_main

$ ./a.out
Running main() from gtest_main.cc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from Test1
[ RUN      ] Test1.test11
[       OK ] Test1.test11 (0 ms)
[----------] 1 test from Test1 (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 1 test.

```



## main()を自分で書く場合

```c++:test2.cpp
#include "gtest/gtest.h"

TEST(Test1, test11)
{
    ASSERT_EQ(1, 1);
}

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();

}
```

```
$ g++ test2.cpp -I$GTEST_INCLUDEDIR -L$GTEST_LIBDIR -lgtest
```
studioコマンドとpecoとghqでクローンしてきたリポジトリを簡単にAndroid Studioで開く

今までGitHubでAndroidのリポジトリをみて、ちょっとAndroid Stdioで開いて中身みてみたいな〜。と思う時は、以下の手順を踏む必要があった。

```
ghq get <repository>
cd $(ghq list -p | peco) # 実際にはaliasを指定してる
pwd | pbcopy
# Android Studioで開く
# File Open→ペーストして開く
```

常々だるいなーと思ってたのだけど、いろいろあって以下のような手順に改善された

```
ghq get <repository>
studio $(ghq list -p | peco) # 実際にはaliasを指定してる
```

なんと、たったの２ステップに改善された！！！結構カジュアルに開けるようになったので最高という感じ。
なお、studioコマンドは事前にAndroid Studioから作っておく必要がある。
作り方はこちら。

http://qiita.com/takahirom/items/e9ad33e94140b09855c3


## Thanks

https://twitter.com/mapyo/status/799769577232080896

https://twitter.com/mapyo/status/799790655652253696


zipper先生にアイディアをもらったのはこれで２回目だった

http://mapyo.hatenablog.com/entry/2016/01/27/191919
python > 処理を途中で抜ける > import sys / sys.exit()

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 14.04 LTS desktop amd64
TensorFlow v0.11
cuDNN v5.1 for Linux
CUDA v8.0
Python 2.7.6
IPython 5.1.0 -- An enhanced Interactive Python.
```

pythonのコードを途中で止めたかった。
Jupyterを使って逐次実行でも良かったが、scriptで止める方法を調べた。

参考 http://stackoverflow.com/questions/179369/how-do-i-abort-the-execution-of-a-python-script

- import sys
- sys.exit()

以下はTensorFlowというDeep Learning用のスクリプト。
`print(input_ph.get_shape())`の次で終了したかった。

```py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import tensorflow as tf
import tensorflow.contrib.slim as slim

# ファイル名の Queue を作成
filename_queue = tf.train.string_input_producer(["input.csv"])

# CSV を parse
reader = tf.TextLineReader()
key, value = reader.read(filename_queue)
input1, output = tf.decode_csv(value, record_defaults=[[0.], [0.]])
inputs = tf.pack([input1])
output = tf.pack([output])

batch_size=4 # [4]
inputs_batch, output_batch = tf.train.shuffle_batch([inputs, output], batch_size, capacity=40, min_after_dequeue=batch_size)

input_ph = tf.placeholder("float", [None,1])
output_ph = tf.placeholder("float",[None,1])

#if 1 // debug
print(input_ph.get_shape())
sys.exit()
#endif

## NN のグラフ生成
hiddens = slim.stack(input_ph, slim.fully_connected, [1,7,7,7], 
  activation_fn=tf.nn.sigmoid, scope="hidden")
prediction = slim.fully_connected(hiddens, 1, activation_fn=tf.nn.sigmoid, scope="output")
loss = tf.contrib.losses.mean_squared_error(prediction, output_ph)

#train_op = slim.learning.create_train_op(loss, tf.train.AdamOptimizer(0.01))
train_op = slim.learning.create_train_op(loss, tf.train.AdamOptimizer(0.001))

def feed_dict(inputs, output):
    return {input_ph: inputs.eval(), output_ph: output.eval()}

init_op = tf.initialize_all_variables()

with tf.Session() as sess:
  coord = tf.train.Coordinator()
  threads = tf.train.start_queue_runners(sess=sess, coord=coord)

  try:
    sess.run(init_op)
    for i in range(30000): #[10000]
      _, t_loss = sess.run([train_op, loss], feed_dict=feed_dict(inputs_batch, output_batch))
      if (i+1) % 100 == 0:
        print("%d,%f" % (i+1, t_loss))
#        print("%d,%f,#step, loss" % (i+1, t_loss))
  finally:
    coord.request_stop()

  coord.join(threads)
```

```txt:結果
$ python linreg2_feeddict.py 
I tensorflow/stream_executor/dso_loader.cc:111] successfully opened CUDA library libcublas.so locally
I tensorflow/stream_executor/dso_loader.cc:111] successfully opened CUDA library libcudnn.so locally
I tensorflow/stream_executor/dso_loader.cc:111] successfully opened CUDA library libcufft.so locally
I tensorflow/stream_executor/dso_loader.cc:111] successfully opened CUDA library libcuda.so.1 locally
I tensorflow/stream_executor/dso_loader.cc:111] successfully opened CUDA library libcurand.so locally
(?, 1)
```
shc で shell script をバイナリ化しようとして "shc: invalid first line in script:" と言われた時

# 結論
シバン（#!）がないからかな？と思ったらやっぱりそうでした

# はじめに
shc は shell script をストリップ済のバイナリにコンパイルしてくれるツールです

暗号化ストレージを起動時に復号化する shell とか、起動時にコピーされたSDかチェックするとか中身を読んでほしくないし触ってほしくない shell をカジュアルに難読化するのに便利です

shc が元の shell script から生成した c ファイルを眺めてみると（キレイで読みやすいコードで、読んでて楽しいです）、元の shell を RC4 で暗号化してバイナリで保持し、複合して実行してくれるようです
ファイルへの変更の痕跡のチェックとかいい感じで対タンパーチェックもしてくれているようです

# shc のインストール
debian だと

`sudo apt-get install shc`

でオッケーです。Raspberry Pi の Raspbian もこれでオッケーでした

# shc の使い方
man page を見ると例として

`shc -v -r -T -f myscript.sh`

とかで myscript.sh から myscript.sh.x というバイナリの実行形式をつくってくれるそうです。
因みに -T は「トレーサブル」オプションで、strace とか ptrace とかでトレースできちゃうようなバイナリをつくってくるそうです。いらないので私はつかってません

詳細な説明は[文献1](http://www.natzworks.com/digital/2010/410.html) のブログがすごくわかりやすかったです

# エラー
で、表題のエラー

シバンがないことが原因かな？とか思いながらググってみたらやっぱり[文献2](http://www.linuxquestions.org/questions/linux-newbie-8/how-to-encrypt-shell-script-717670/)のとおりでしたので、バイナリ化する shell の先頭行に

`#!/bin/bash`

を追加すると正常にバイナリ化できました

# 感想
「結論を最初に」ってよく言いますけど、思い切って「はじめに」よりも前に「結論」をもってきてみたんですけど、これ、案外いけてる構成な気がするんですがどうでしょ

# futur works
生成された c のコードを例えば [Obfuscator-LLVM](http://qiita.com/UedaTakeyuki/items/8429261ae7203d393df2) みたいなオブフスケーターにかけてみたらどうなるかとか

# references
- [文献1][シェル・スクリプトをバイナリ化 (shc)](http://www.natzworks.com/digital/2010/410.html) わかりやすく詳細な説明がありがたいです。このブログで shc の存在を知りました。感謝です。

- [文献2][how to encrypt shell script](http://www.linuxquestions.org/questions/linux-newbie-8/how-to-encrypt-shell-script-717670/) シバンがないよ、という回答
(非推奨)キョードー東京のクレジット決済が完了できない場合の対処

**この方法は非推奨です。実行する場合、自己責任でお願いします。**
TwitterではIEの互換モードならOKというようなツイートは見かけましたので、まずはブラウザを変更して試すのが良いでしょう。

キョードー東京でチケットの決済方法にクレジットカードを選択し、流れに沿って進めていくと最後の画面でボタンを押しても何も起こらない場合がある。
私の環境ではjavascriptで問題があったのでそれを回避するような手順を取ったところ、決済が完了しました
購入手続き完了メールも来て、申し込み詳細ページでも入金済みに見えるので一応公開します。思い出しながら手順を書いているので、誰かが人柱になって実際のスクショで記事作ってくれるとそれが一番なんだけど

以下chromeでの手順

1. 決済を完了するページまで進める
2. chromeのメニュー -> その他のツール -> デベロッパーツール を開く
3. 決済完了ボタン(正確なボタン名は忘れた)を押す。何も起こらないはず
4. デベロッパーツールに以下のようなエラー(画像は再現なので実際とは違うかも)が表示されるので、その行の右端をクリックしてスクリプトのエラー箇所を表示する
![scripterror.png](https://qiita-image-store.s3.amazonaws.com/0/81847/5a4f7cab-26aa-24d0-ead1-eded6a4a3d5f.png)
5. スクリプトの該当行左端に行番号をクリックする。クリックした箇所が青くなるはず。
6. 再度決済完了ボタンを押す。すると画面が暗くなりデベロッパーツールにフォーカスが移る。
7. コンソールに```clickFlg = 0;```を入力する  
![console.png](https://qiita-image-store.s3.amazonaws.com/0/81847/59328569-ec61-12a6-85fb-0c25f91c22ff.png)
8. ブラウザ画面の青い矢印をクリックする。しばらくすると処理が完了する。
![pause.png](https://qiita-image-store.s3.amazonaws.com/0/81847/a740f1cc-99a3-9561-4f3f-f816ffb13aa5.png)

以上です。
SurfaceViewを使用するために１

#はじめに
いろいろと調べたところスマートフォンの画面に何かを表示するとき、
ビデオメモリがダブルバッファになっているので画面を更新するときのチラつきが抑えれる
ということから描画にはSurfaceViewを使用することにしました。
SurfaceViewを使用することに決めましたが、使い方が分からず苦労したので、
分かったことをまとめました。
※Activityで描画してもHardware Accelerationによって高速な描画が可能なようです。

#分からなかったこと
SurfaceViewを使用するとき
EclipseのGraphical Layoutで配置する
SurafaceViewを継承したクラスを実装する
の２通りの方法があり、どのように使うのかが分かりませんでした。

#分かったこと１
EclipseのGraphical LayoutでSurfaceViewを配置した場合、
SurfaceViewのインスタンスは生成されているので、
自分でインスタンスを生成する必要はなく、
SurfaceView surfaceView = (SurfaceView)findViewById(R.id.surfaceView1);
でインスタンスを取得して使用することが分かりました。

#実装例１
EclipseのGraphical LayoutでSurfaceViewを配置した場合

```java:MainActivity.java
import android.view.SurfaceView;

public class MainActivity extends Activity implements SurfaceHolder.Callback, Runnable, OnTouchListener {

	@Override
	public void onCreateView() {

		super.onCreateView();

		SurfaceView surfaceView = (SurfaceView)findViewById(R.id.surfaceview1);
	}
}

public class MainSurfaceView {

	private Surfaceview surfaceView;

	public MainSurfaceView(SurfaceVew surfaceView) {

		this.surfaceView = surfaceView;
	}
}
```

温度計アプリケーションではこちらの方法を使用しています。
ソースコード(MainActivity.java)は[こちら](https://github.com/AkimotoMasane/thermometer)です。
**MainSurfaceViewクラスはインナークラスとしています。**

#分かったこと２
SurafaceViewを継承したクラスを実装する場合は
public class MainSurfaceView extends SurfaceView {
というクラスを作成して、SurfaceViewをActivityに登録する
必要があることが分かりました。

#実装例２
SurafaceViewを継承したクラスを実装する場合

```java:MainActivity.java
public class MainActivity extends Activity {

	@Override
	public void onCreateView(Bundle savedInstanceState) {

		super.onCreateView();

		SurfaceView surfaceView = new MainSurfaceView();

		setContentView(surfaceView);
	}
}

import android.view.SurfaceView;

public class MainSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {

	public MainSurfaceView() {
	}
}
```

#まとめ
EclipseのGraphical Layoutで配置する場合
SurfaceViewはシステム内でインスタンス化されているので、
SurfaceViewのインスタンスをfindViewByIdで取得して使用する。

SurfaceViewを継承したクラスを実装する場合
SurfaceViewを継承したクラスを実装し、
SurfaceViewを自分でインスタンス化して、
Activityに登録して使用する。
AWS Lambda環境変数対応をお触り

# AWS Lambda環境変数対応を早速使ってみる

皆様待っていた機能ですよね。Lambdaの環境変数対応の記事は[こちら](https://aws.amazon.com/jp/blogs/aws/new-for-aws-lambda-environment-variables-and-serverless-application-model/)
これで開発と商用の設定環境差などのコーディング部分が便利になりますね。
個人的には、デバッグ用のlog出力 level flagとか、接続情報をハードコーディングしなくてもよくなるのにも便利かなと思っています。

# 環境変数名の制約
数に制約はなく、Total 4KB
アルファベットで始まる必要があり、a-zA-z0-9_なので、記号は"_"のみ利用可能

予約名もありますので、以下のKey名は利用不可
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_SESSION_TOKEN
AWS_ACCESS_KEY
AWS_SECRET_KEY
AWS_SECURITY_TOKEN
AWS_DEFAULT_REGION
AWS_REGION
AWS_LAMBDA_LOG_GROUP_NAME
AWS_LAMBDA_LOG_STREAM_NAME
AWS_LAMBDA_FUNCTION_NAME
AWS_LAMBDA_FUNCTION_MEMORY_SIZE
AWS_LAMBDA_FUNCTION_VERSION
LAMBDA_TASK_ROOT
LAMBDA_RUNTIME_DIR


最新の情報は必ず[公式](http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/env_variables.html#env_limits)をご確認ください。

# 環境変数の設定
KeyValueで設定します。

GUIからはコードエディタの下に環境変数部が追加されています。とりあえず Keyに"env" Valueに"prd"を設定してみます。
![スクリーンショット 2016-11-19 10.11.02.png](https://qiita-image-store.s3.amazonaws.com/0/100893/c7cd8b40-28c2-1b89-9dc8-c2d2763d21b3.png)

CLIからは、[こちら](http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/env_variables.html)のsetting upをご参考に。

# とりあえずの取得までの流れです

当たり前ですが、環境変数としてとれます。。pythonでのサンプル

```py:just_print.py
import os

def lambda_handler(event, context):
    # TODO implement

    print '---all env value---'    
    for i in os.environ.items():
        print i

    print '---get target---'            
    print os.environ['env']
    
    return
    
```

# 結果
```
---all env value---
('AWS_LAMBDA_FUNCTION_VERSION', '$LATEST')
('LAMBDA_TASK_ROOT', '/var/task')
('PATH', '/usr/local/bin:/usr/bin/:/bin')
('LD_LIBRARY_PATH', '/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib')
('LANG', 'en_US.UTF-8')
('AWS_LAMBDA_FUNCTION_NAME', 'Just_print_event')
('AWS_REGION', 'us-west-2')
('AWS_SESSION_TOKEN', 'xxxxx')
('AWS_SECURITY_TOKEN', 'xxxxxxx')
('LAMBDA_RUNTIME_DIR', '/var/runtime')
('AWS_LAMBDA_FUNCTION_MEMORY_SIZE', '128')
('env', 'prd')
('PYTHONPATH', '/var/runtime')
('AWS_LAMBDA_LOG_GROUP_NAME', '/aws/lambda/Just_print_event')
('AWS_LAMBDA_LOG_STREAM_NAME', '2016/11/19/[$LATEST]')
('AWS_ACCESS_KEY_ID', 'xxxxxxxxxxxxxxxxxxxxxxxxx')
('AWS_DEFAULT_REGION', 'us-west-2')
('AWS_SECRET_ACCESS_KEY', 'xxxxxxxxxxxxxxxxxxxxxx')
---get target---
prd
```

# 注意事項
DBへの接続パスワードなどの機密情報は平文で置かないように[推奨](http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/env_variables.html#env_encrypt)されています。
KMSなどを利用した暗号化処理の検討をしましょう！

Storing Sensitive Information

For sensitive information, such as database passwords, we recommend you use client-side encryption using AWS Key Management Service and store the resulting values as Ciphertext in your environment variable. You will need to include logic in your Lambda function code to decrypt these values.

# 免責
本投稿は、個人の意見で、所属する企業や団体は関係ありません。
また掲載しているsampleプログラムの動作に関しても保障いたしませんので、参考程度にしてください。
OpsWorks Rails, nginx + unicorn + rails + custom cookbook ON でsites-availableが作られないとき。

# はじめに
とあるプロジェクトでOpsWorksにツンデレされたwときの対処法を書いておきます。
同じ現象に当たったときの助けになればと。

(もろもろの用語の説明は省いてます。あしからず。。)

# 状況
* AWS の DevOps サービスである OpsWorks を利用。
* 設定は nginx + unicorn
* アプリは Rails で作成
* ELB を挟み
* DB は RDS
* Stack の設定で custom cook book を有効にしている。
* custom cook book はgithub のリポジトリから取得している。

![スクリーンショット 2016-11-19 10.09.27.png](https://qiita-image-store.s3.amazonaws.com/0/49986/1ca2bf4a-6d5d-b054-7b45-aa65b25129ea.png)

# 現象
nginx のサイト設定であるsites-available が無いと言われる。

![スクリーンショット 2016-11-19 10.13.40.png](https://qiita-image-store.s3.amazonaws.com/0/49986/53ae9ce4-09bc-0164-2896-6e15152aaecb.png)

custom cook book を無効にすると発生しない。

# 最初に対策
↓ のcookbookを、custom cookbook に指定して、setup時にnginx::defaultレシピを実行するよう設定。

https://github.com/tinms/cookbooks-for-aws

![スクリーンショット 2016-11-19 10.18.56.png](https://qiita-image-store.s3.amazonaws.com/0/49986/0fb56c38-77b8-dad7-4956-be86daced8ef.png)

これで現象を回避できます。

# もろもろ
実はこの現象が発生したときには、以下のフォルダ／ファイルができていないこともわかっています。
上のレシピはこれらを補完してます。

/etc/nginx/sites-enabled フォルダがない
/etc/nginx/sites-available フォルダがない
/usr/sbin/nxensite スクリプトが無い(普通はデフォルトレシピのnginx::defaultで入る）
/usr/sbin/nxdissite スクリプトが無い(普通はデフォルトレシピのnginx::defaultで入る）

# 最後に
愛してきたOpsWorksに少しツンデレされて、仲良くなるのに3日ほど費やしました。
治ってよかった。同じようにツンデレされてもこれですぐ仲良くなれますねw
久しぶりにelectronを使ってハマった、electron v1.4.7

# electron

electronがバージョンアップしていて色々ハマった。
今のバージョンは```v1.4.7```

## menuモジュールについて

下記のようなコードで、menuモジュールが無いといわれるケース

```
var Menu = require('menu');
```

menu moduleをnpm installのではなく、electronのMenuを使う。

```
var Menu = electron.Menu;
```

### ipcモジュールについて

mainProcessとrenderProcessで違う

昔のバージョンではこうだった。

```
var ipc = require("ipc");
```

mainProcessではこう

```
var ipc = electron.ipcMain;
```

renderProcessではこう

```
var ipcRenderer = require('electron').ipcRenderer

```

## renderProcessでrequireを使う方法

nodeIntegrationを有効にしないとrenderProcessで```require```を使えない。


```
var browserWindow = new BrowserWindow({
      webPreferences: {
        nodeIntegration: true
      }
    });
```
FXシステムトレードのプログラムをいくつか作ってみて分かった課題とその解決法について

以下の通りいくつか、システムトレードのプログラムを作ってきましたが、継続的（長期ではなく短中期でも安定して）に勝つには課題があることが分かったので書いておきます。

※コメント欄に画像のリンク張ってたりしてるので、そちらもご覧ください
[ディープラーニングでFXのシステムトレーディングをするコードを書いた - Qiita](http://qiita.com/ryo_grid/items/7746528f8cae8026b936)
[機械学習を用いたオレオレFXシステムトレーディングプログラムのロジック解説 - Qiita](http://qiita.com/ryo_grid/items/56a086fee1b780157df7)
[ディープラーニングでFXのシステムトレーディングをするコードを書いた (2) -RNN/LSTM編- - Qiita](http://qiita.com/ryo_grid/items/a3163ac50806f8494a53)
[xgboostによる決定木アンサンブル学習でFXのシステムトレードするコードを書いた - Qiita](http://qiita.com/ryo_grid/private/757fa93fc479439b2676)

#課題
- 市場は常に変化しており1つのアルゴでは対応しきれない（ように思えた）
 - 当たり前かもしれないが、機械学習でアルゴを作っても勝てる期間と勝てない期間が出てくる（数カ月とかのスパンで）
 - 市場はざっくり分けても平均に回帰する平均回帰性の強い期間とそうでない期間がある(らしい)。他にも様々な要因について特性が変化している（と思われる）。
 - (すごく賢い機械学習アルゴなら、市場の特性の変化すらカバーできるのかもしれない)

#考えられる対応策は3つ（うまくいくかは不明）
- 機械学習なアルゴであれば、市場の変化に応じて再学習を続けていく
  - バックテストしようとすると計算量が膨大になるので試せていない。この点については、全部一から再学習するのではなく、学習期間のウィンドウをスライドさせて追加学習及び過去の学習内容の忘却ができるようなアルゴリズムがあるとよさげ。ただ、実運用では適当なタイミングでまるっと再学習でもさほど問題にはならないだろう。
- 複数のアルゴを市場の状況に応じて切り替える
 - 強化学習の一つであるバンディットアルゴリズムで市場に適したアルゴを動的に選択していくようなことができるはず
 - ただし、市場の変化に十分な速度で追従できるのかは不明。
- グリッドトレーディングのような市場の特性に左右されないストラテジーを採用する
 - [グリッドトレード戦略でFXシステムトレード - Qiita](http://qiita.com/ryo_grid/items/c8d2d268e3f0d64af1e6)

以上、頭の中にあることをメモがてら書いてみました。

# 追記
続きを書いてみました
http://qiita.com/ryo_grid/items/5f8114c11bd2959ea9a6
Node.js + Express4 + Angular2をクラウドに配置１

この前、Angular2の勉強会にいってきたので、忘れないうちに。
## 前提
- 「Visual Studio  2015」 （Community以上）をインストール
- 「Node.js Tools for Visual Studio」（現在1.2 ）をインストール
- 「Microsoft Azure」のアカウントで「Web Apps」（無料以上）を起動

## プロジェクトの作成
- 「ファイル」「新規作成」「プロジェクト」を選択。
- 「テンプレート」「他の言語」「JavaScript」「Node.js」を選択。
（TypeScriptにしたいとこですが、なぜかExpress3までしかない）
- 「Basic Azure Node.js Express 4 Application」を選択。
- 適当な名前を決めて（ここでは「ExpressApp1」）「OK」ボタンを押す。
![image](https://qiita-image-store.s3.amazonaws.com/0/150107/0a63999b-3f63-b8d0-cd03-9fc6e56d59af.png)

## ローカルで確認
- 「F5」を押してローカルで実行してみます。
- 確認できたら「Shift + F5」で停止します。
![image](https://qiita-image-store.s3.amazonaws.com/0/150107/0e47a697-c525-7e1f-55f5-1e079f15ca4d.png)

## プロジェクトの公開
- プロジェクト「ExpressApp1」を右クリック「公開」を選択
- プロファイルから発行先を「Microsoft Azure App Service」を選択
![image](https://qiita-image-store.s3.amazonaws.com/0/150107/8cf46314-2541-021c-dffa-911fb32f0615.png)

- デフォルトのままで「発行」ボタンを押します。
![image](https://qiita-image-store.s3.amazonaws.com/0/150107/4b1a6e42-4860-8d35-631f-2d6d66b5bbc7.png)


- ここまで６回のクリックでクラウドに公開できました。
![image](https://qiita-image-store.s3.amazonaws.com/0/150107/598ef3b1-f1ec-c8fb-422f-d6307c503ae8.png)



次回はこのサーバーにAngular2を設定してみたいと思います。
python > cのquick swapを使う > #if 1 // no reshape

C言語では`#if 1`を使ってQuick swapをすることができる。
http://qiita.com/7of9/items/867287b73d3b2cc1b87f

```.c
#if 1 // no reshape
   // do nothing
#else
   use_reshape();
#endif
```

上記の`#if 1`を`#if 0`とすることでelse以降が有効となる。

このquick swapは別の用途でも使っている。「直近で作業していることの明示」。
(quick swapという意味ではないかもしれない）。

pythonで同じことができないだろうかと思った。

```py
#if 1 // feed_dict
      _, t_loss = sess.run([train_op, loss], feed_dict={input_ph:inputs_batch.eval(), output_ph:output_batch.eval()})
#else    
#      _, t_loss = sess.run([train_op, loss], feed_dict=feed_dict(True, inputs_rs, output_rs))
#endif      
```

pythonでは`#`で始まるコードはコメントになるので、上記を足すことによるコードの影響はない。
quick swapではないが、「直近で作業していることの明示」はできそう。
無効にしたいコードは`#`を自分でつける「セルフサービスコメントアウト」方式。

なお`#if 1`関連の部分は直近の作業が終わり次第消すので、VCSには残さない。
ContainingAppとExtensionのバージョンはそろえる

Action Extensionに対応したアプリをリリースしたところ、収容アプリケーションとエクステンションのバージョンが違うという旨の警告がでました。

そのまま審査出すこともできるようですが、毎回警告がでてしまうため、合わせておくのがよさそうです。

```
Dear developer,

We have discovered one or more issues with your recent delivery for "XXX App". Your delivery was successful, but you may wish to correct the following issues in your next delivery: 

CFBundleVersion Mismatch - The CFBundleVersion value '1' of extension 'XXX.app/PlugIns/YYY.appex' does not match the CFBundleVersion value '3.0.0' of its containing iOS application 'XXX.app'. 

CFBundleShortVersionString Mismatch - The CFBundleShortVersionString value '1.0' of extension 'XXX.app/PlugIns/YYY.appex' does not match the CFBundleShortVersionString value '3.0.0' of its containing iOS application 'XXX.app'. 

After you’ve corrected the issues, you can use Xcode or Application Loader to upload a new binary to iTunes Connect. 

Regards,

The App Store team
```
TensorFlow / keywords < TensorFlow Data Input (Part 1): Placeholders, Protobufs & Queues

TensorFlowというDeep Learningのフレームワーク学習中。

tf.train.shuffle_batch()を調べていた以下の記事
https://indico.io/blog/tensorflow-data-inputs-part1-placeholders-protobufs-queues/

キーワードだけ拾っておく

- placeholders
   - numpy array
- binary files / raw data
- Feed dicts
- protobuf
- queue
- Records format
- Protocol Buffers
- TFRecords
- tf.train.Example
- tqdm
- Features
- FloatList / ByteList / Int64List
- records, read back sequentially
- TensorFlow's graphs contain state
   - (補足) 現在の読込み位置情報を保持する
- Queue / Queue Runners
- batch_size + min_after_dequeue examples
Python > link > yieldとnext() > yieldを使ったジェネレータの実装

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 14.04 LTS desktop amd64
TensorFlow v0.11
cuDNN v5.1 for Linux
CUDA v8.0
Python 2.7.6
IPython 5.1.0 -- An enhanced Interactive Python.
```

TensorFlowというDeep Learningのフレームワークの学習中。

https://indico.io/blog/tensorflow-data-inputs-part1-placeholders-protobufs-queues/
の１つ目のコードで見たことがない記述に出くわした。

```py
...
def data_iterator():
    """ A simple data iterator """
    batch_idx = 0
    while True:
        # shuffle labels and features
        idxs = np.arange(0, len(features))
        np.random.shuffle(idxs)
        shuf_features = features[idxs]
        shuf_labels = labels[idxs]
        batch_size = 128
        for batch_idx in range(0, len(features), batch_size):
            images_batch = shuf_features[batch_idx:batch_idx+batch_size] / 255.
            images_batch = images_batch.astype("float32")
            labels_batch = shuf_labels[batch_idx:batch_idx+batch_size]
            yield images_batch, labels_batch


iter_ = data_iterator()
while True:
    # get a batch of data
    images_batch_val, labels_batch_val = iter_.next()
    # pass it in as through feed_dict
    _, loss_val = sess.run([train_op, loss_mean], feed_dict={
                    images_batch:images_batch_val,
                    labels_batch:labels_batch_val
                    })
    print loss_val
```

上記でぱっとみて分からなかったのは「iter_.next()のnext()はどこで定義されているのか」ということだった。

iter_のクラスdata_iterator()にはnext()の定義はない。

一方で、yieldという記述がある。
これはUnityでソフトを作った時に出てきたような気がする。
http://qiita.com/7of9/items/194e1c7f4b87a79dd129

next()とyieldで検索するとQiita記事が見つかった。
http://qiita.com/tomotaka_ito/items/35f3eb108f587022fa09#yieldを使ったジェネレータの実装

やはりUnityで使ったyieldと同じような使い方ができるようだ。
Koozali - SME Server 9 (失敗)

## download

* [Koozali - SME Server](http://www.koozali.org/)
* [download mirror](http://mirror.chiropratique.org/releases/)
* [DistroWatch.com: SME Server](https://distrowatch.com/table.php?distribution=smeserver)
* [wiki - SME Server](https://wiki.contribs.org/Main_Page)
    * [Documentation](https://wiki.contribs.org/SME_Server:Documentation)

## 特徴

* CentOS 6.7 ベース。32bit, 64bit両方ある。
* [インストール時、Raid1を組んでくれる](https://wiki.contribs.org/SME_Server:Documentation:Administration_Manual:Chapter4#4.3._Hard_Drive_Configuration)
* 自分が毎回入れるパッケージが割と標準搭載。

## インストール

* 言語を日本語にすると以下のように読めなくなるので注意！！

![1.png](https://qiita-image-store.s3.amazonaws.com/0/25728/e77e882b-cd58-3aba-e573-ff7e613af981.png)
![2.png](https://qiita-image-store.s3.amazonaws.com/0/25728/3920d0af-8aa4-12b6-49f3-688d283afa68.png)
![3.png](https://qiita-image-store.s3.amazonaws.com/0/25728/90a9f54e-930a-5c85-1d97-5b8147c77c5c.png)
![4.png](https://qiita-image-store.s3.amazonaws.com/0/25728/0d14d15a-b6a3-8d4a-f164-c4800d3b95ca.png)

![5.png](https://qiita-image-store.s3.amazonaws.com/0/25728/0593a4bf-0c6b-8287-05b1-396572fb0a43.png)

* ホスト名の設定。(間違えてuser1と入力してしまった。)

![6.png](https://qiita-image-store.s3.amazonaws.com/0/25728/d801996d-10bb-52d5-3a5a-9e84fc970523.png)
![7.png](https://qiita-image-store.s3.amazonaws.com/0/25728/34d1ee66-f614-bcc6-a7f3-0dcf2e221b68.png)
![8.png](https://qiita-image-store.s3.amazonaws.com/0/25728/78cc8e83-9dba-3205-8cdd-169320837c9f.png)
![9.png](https://qiita-image-store.s3.amazonaws.com/0/25728/6c7e1c65-52d7-bfda-8a79-79ac7e00ffc4.png)
![10.png](https://qiita-image-store.s3.amazonaws.com/0/25728/4396dce0-4e2f-3cc7-fd2d-088b14ba6cc4.png)
![11.png](https://qiita-image-store.s3.amazonaws.com/0/25728/1f4b84c3-345a-f7ea-5235-4bfc838747b4.png)
![12.png](https://qiita-image-store.s3.amazonaws.com/0/25728/ddd438a4-a5ef-597c-8c1b-0f2e6643f36f.png)
![13.png](https://qiita-image-store.s3.amazonaws.com/0/25728/165b9f5c-1dd9-d685-58ef-9e45b95000b4.png)
![14.png](https://qiita-image-store.s3.amazonaws.com/0/25728/2e7e1347-056f-6192-f9b6-b8d12b2a5f58.png)
![15.png](https://qiita-image-store.s3.amazonaws.com/0/25728/3eed9ea4-a5b7-2c1b-0b90-ee43af0984fd.png)

## ログイン画面

![login.png](https://qiita-image-store.s3.amazonaws.com/0/25728/d59e66c0-c348-def8-30a1-bbb9a930ee2b.png)

* ブラウザからログインできなかった・・・。

![ログインできない.png](https://qiita-image-store.s3.amazonaws.com/0/25728/adf6610b-cbf0-c647-c3ef-412cebc63f82.png)