OmniAICreator/Qiita-1.07M huggingface dataset:
Macで不調なWi-Fiに繋いでいるときに自動でON/OFFするスクリプト

自宅のWi-Fiネットワークの調子が悪く、MacのWi-Fiの電源を切入しなければいけませんでした。
さすがに面倒になってきたので、Wi-FiデバイスのOff/Onを自動化しようと思います。

# 概要
ネットワークが正常か調べて、不調なときに電源を切入するスクリプトをcronで定期的に実行させます。

# Wi-Fiネットワークデバイスの名前
`networksetup -listnetworkserviceorder`で
Wi-Fiネットワークデバイスの名前を調べておきます。
自分は`en0`でした。

![ネットワークデバイスの名前.png](https://qiita-image-store.s3.amazonaws.com/0/14380/5add892b-494f-1c21-ea0b-eff97b0e7232.png)

# スクリプト
下記のスクリプトを任意の場所に準備します。
(自分は`/Users/ken1flan/bin/fix_wifi.sh`)
コードの説明はコメントを参照してください。

```bash:fix_wifi.sh
TARGET_HOST=google.co.jp
LOG_FILE=/tmp/fix_wifi.log
DEVICE=en0
PATH=:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH

# LOG_FILEで指定したファイルに、日時とともに指定された文字列を追記する。
function _write_log {
  echo "`date +\"%Y/%m/%d %H:%M:%S\"` $1" >> $LOG_FILE
}

# DEVICEで指定したネットワークデバイスの電源を確認する。ONのときに0が返す。
function _check_device {
  networksetup -getairportpower $DEVICE | grep 'On$' > /dev/null 2>&1
}

# TARGET_HOSTにpingが到達したことをもってネットワークが正常であるとする。正常のときに0を返す。
function _check_network {
  ping -c 3 -t 3 $TARGET_HOST > /dev/null 2>&1
}

# DEVICEで指定したネットワークデバイスの電源を切入してリセットする。
function _reset_device {
  networksetup -setairportpower $DEVICE off
  networksetup -setairportpower $DEVICE on
}

_write_log "Start"

# ネットワークデバイスに電源が入っていない場合は何もしない。
_check_device
if [ $? != 0 ]; then
  _write_log "Device is off"
  return 0
fi

# ネットワークが不調だったらネットワークデバイスをリセットする。
_check_network
if [ $? != 0 ]; then
  _write_log "Network is not work"
  _reset_device
  _write_log "Device was reset"
fi
```

# cronで定期実行
`crontab -e` で下記を登録し、5分毎にスクリプトが実行されるようにします。

```bash
*/5 * * * * /usr/local/bin/bash /Users/ken1flan/bin/fix_wifi.sh
```

# 参考
* [コマンドラインからMac OS XのWi-Fiを無効化する](http://qiita.com/r7kamura/items/b58c236eb1c3b1c38957)
Excelファイルが壊れたらそのときにお知らせしてほしい　(アイデア)

事業部長が事業計画を作ってて、「あー! このExcelファイル、式が壊れてるー」と嘆いてた。

ひるがえってエンジニアであるぼくらには、Kent Beckからの贈り物である単体テストフレームワークがあって、安心して前に進むことができる。

だったらExcelファイルでも単体テストやればいいんじゃないかー。

beforeSaveでSheet1:A1がFalseだったらダイアログを出すとかね。
そんなExcelアドオンをビールウェアでリリースしたら、おいしいお酒がたくさん飲めそう。
[EXCEL]クエリタブを表示するとマウスのホイールでスクロールができなくなるので一時回避

## バージョン
Windows10 Excel2016で確認

## 再現手順
- PowerQueryを使ってシートに何かしらのテーブルを出力する。
- 出力したテーブルを選択し「クエリ」タブを表示させる。

## 症状
マウスのホイールでスクロールできなくなる。
PageUpやPageDownキーではスクロールできる。
後述する方法で改善したとしても再度クエリタブが表示さると再発する

## 直し方（一時対応）
数式バーをクリックしたり、F2を押したり、エクセルを最小化＆元に戻したりするとスクロールできるようになる。
一番手っ取り早いのはalt×2。win×2もアリ。
RDKitをc++で動かす ～git cloneからHello methaneまで～

＊この文章は2016.09.4バージョンを使うものとして書かれています。2017.03.01バージョンでは指定するlibの名前がいちいち異なります。

ある程度前にOpen Babelをc++で動かしていたが、RDKitのほうがpythonで数倍便利ってイメージがあるのでそちらを利用する。
…ところで、RDKitをc++で利用するのって日本語はおろか英語でもほとんど資料がないんですが…

## git clone

RDKitは以下のgithubで開発をされているので、cloneしてくる。
https://github.com/rdkit/rdkit
後述の理由により、インストールしたい場所でgit cloneをするのが望ましい。

```bash
cd /path/to/install
git clone https://github.com/rdkit/rdkit.git
cd rdkit
git checkout origin/Release_2016_09 # ver 2016.09.4
```

## cmake
実は、RDKitは-DCMAKE_INSTALL_PREFIXを指定しても全く役に立たない。
というか、make installしても移動させてくれない。
なのでインストールしたいパスでgit cloneすることを推奨している。

```shell-session
mkdir build
cd build
cmake ..
```

## make

```
make install
```

## library pathを通す
最後に、LIBRARY_PATHなどを通す。
以下はlinux SUSE上での例。

```bash
export RDKIT_INSTALL_PATH=/path/to/install
export LIBRARY_PATH=${RDKIT_INSTALL_PATH}/lib:$LIBRARY_PATH
export LD_LIBRARY_PATH=${RDKIT_INSTALL_PATH}/lib:$LD_LIBRARY_PATH
```

これでコードを書く準備が完了。

## c++コード
とりあえず、methaneをsdfで読み込み、"Hello "の文字列とともにsmilesを表示させてみる。

```cpp:hello_rdkit.cpp
#include <iostream>
#include <GraphMol/FileParsers/MolSupplier.h>
#include <GraphMol/SmilesParse/SmilesWrite.h>

int main(void){
  RDKit::SDMolSupplier supplier("methane.sdf");
  RDKit::ROMol *mol;
  mol = supplier.next();
  std::cout << "Hello " << RDKit::MolToSmiles(*mol) << "!" << std::endl;
  delete mol;  //MolToSmilesは中でnew ROMolをしている
  return 0;
}
```

## コードのコンパイル
methane.sdfを用意したうえで・・・

```bash
g++ hello_rdkit.cpp -I /path/to/install/Code -L /path/to/install/lib -lFileParsers -lSmilesParse
```

これを実行してやると、```Hello C!```と。できた。

## 補足
-Iは /path/to/install/includeでないことに注意。
libraryも指定する必要があるが、どうやらincludeするパスの最後のdir名を指定してやれば大丈夫っぽい。

```c++
#include <GraphMol/FileParsers/MolSupplier.h> // -lFileParsers
#include <GraphMol/ROMol.h>                   // -lGraphMol
```
Xamarin Studio をアンインストールして Visual Studio for Mac(Preview) をインストールする


Visual Studio for Mac(Preview) のインストール、失敗にもいろいろあるようですが、私の場合、インストーラを実行すると、しばらくして以下の画面が表示されてしまうというケースでした。

![](http://blog.amay077.net/assets/images/posts/install_failed_vs_for_mac_01.png)

これの原因が本当によくわからなくて、

* Xamarin Studio のアンインストール
* Mono のアンインストール
* Android SDK の削除

とかいろいろやってみたけど症状変わらずでした。

改めて、ディスクの中に Xamarin 関係の残骸が残っていないかチェックしてみると、 ``/Developer/MonoAndroid`` にシンボリックリンクを発見！「おまえかー！」と叫びながらそれを削除。

さらにアプリケーションの中に

* Xamarin Workbooks
* Xamarin Inspector

なども残ってました。

そして何度目かのインストーラ実行…ついに…


![](http://blog.amay077.net/assets/images/posts/install_failed_vs_for_mac_02.png)

インストールできたぁ！

## まとめ

Xamarin Studio をアンインストールして、Visual Studio for Mac をクリーンインストールするには、

1. [Uninstalling Xamarin - Xamarin](https://developer.xamarin.com/guides/cross-platform/getting_started/installation/uninstalling_xamarin/) に従って、Xamarin Studio をアンインストールする（``./xamarin_uninstall.sh`` が便利ですぞよ）
2. Xamarin Workbooks とか Inspector とか、「Xamarin関連の」アプリが残ってないかチェックしてそいつらも消す
3. [Xamarinをアンインストール後、関連ファイルを手動で削除した（Mac OS X）](http://qiita.com/gayou/items/3919b567c226e155cb1c) に沿って、残骸を探して消す（私が見つけるのに苦労した ``/Developer/MonoAndroid`` も載ってます）

でOKなはずです。 

この状態で Visual Studio for Mac をインストールしてみましょう。

ちなみに Android SDK は削除しなくて OK です。ディスク内に Android SDK が入っている場合は、 Visual Studio のインストール時にそれを選択することもできます。

さあ、 Mac で Visual Studio 生活、はじめましょうか。
Proxmox VE ログイン時に｢No valid subscription｣を表示させないようにする

# [概要]
Proxmox VEを使っているとログイン時に毎回下記のような警告が表示されます。
サブスクリプションが有効じゃないから確認してね！ って感じに毎回でうのがうざいので、非表示にする方法をまとめます。
![proxmox_-_Proxmox_Virtual_Environment](http://drive.google.com/uc?export=view&id=0Byh1aAqbAigJN1NLb0c2RmtnTFE)

# [事前準備]
* Proxmoxがインストールされていること。
 - [Proxmox VEをNUCに入れてお遊び環境を構築する](http://qiita.com/ghfdjk/items/1840ca3934be85c194f9)

# [作業内容]
## 該当ファイルをバックアップ
```bash
root@proxmox:~# cp /usr/share/pve-manager/ext6/pvemanagerlib.js{,.bk}
```

## sedファイルで置換
```bash
root@proxmox:/usr/share/pve-manager/ext6# sed -i "s/data.status !== 'Active'/false/g" /usr/share/pve-manager/ext6/pvemanagerlib.js
```

# [事後確認・作業]
特に再起動とかは不要です。Web管理画面にアクセスすれば消えているはず！ :+1:
context.Contextでリクエストスコープな値を持ち回す

WEBアプリを作る際、ログインユーザー情報など、リクエスト毎に値を保持しておいて各層のコンポーネントから透過的にアクセスしたいケースがあります。ここではリクエストスコープと呼んでおきます。

JavaのWEBフレームワークなどではリクエストスコープはthread local storageを使って実装されていたりします[^1]が、Go言語にはそれに相当するものがありません。
そもそもGoはgoroutineで手軽に並行処理を書けるのが大きなウリなので、thread local storageではその魅力が生かせなくなります（異なるgoroutine間で値を共有出来ません）。
その為Goではリクエストスコープな値が必要な場合、必ず引数で持ち回さなければなりません。

ただ、必要なものを全て別々の引数で受け渡していると引数の数が増えてコードの見通しが悪くなりますよね。

Go1.7からcontextパッケージが追加されました。`context.Context`を各層コンポーネント関数の引数に受け渡すルールにしておけば、その中にあるデータに透過的にアクセスできる様になります。
※context.Contextの機能はこれだけではありませんが、本記事では割愛します。

以降、ログインユーザー情報の設定と取得の例を使い方を記述します。

## 値の設定

リクエストに紐づくログインユーザー情報を設定しておきます。

実際のコードではログインが必要なAPIの前処理でリクエストヘッダのtokenなどからユーザーIDを取得し設定することになると思います。

```go
type userKey struct{}
```

```go
    c := context.Background() // WAFが用意しているcontextがあればそれを使う
    c = context.WithValue(c, userKey{}, userID)
```

`context.WithValue`関数を使って値を設定した新しいcontextを作成します。

第２引数のkeyは`interface{}`なので等値比較出来るものなら何でも渡せますが、string等基本型を使用すると他のライブラリとkeyが競合する危険性があります。上記の様にstructのalias typeをkeyにしておくと、競合がおきません。[^2]

[^2]: 最新のgolintではkeyにalias typeを使わないと`should not use basic type xxxx as key in context.WithValue`と怒られます。

## 値の取得

```go
userId := c.Value(userKey{}).(string)
```

`context.Context`の`Value`メソッドで値を取得します。戻り値は`interface{}`なのでtype assertionする必要があります。
下記の様な関数を用意しておけば利用する側がtype assertionする必要はなくなりますね。

```go
func UserID(c context.Context) string {
	return c.Value(userKey{}).(string)
}
```

## まとめ

ログインユーザー情報に限らず、トランザクション情報や、リクエストスコープキャッシュなど、いろいろと使えると思います。

他言語のthread local storageに比べると記述のシンプルさは劣るかと思いますが、Concurrent Programmingを考慮するとこういう方式になるのも仕方ないかなーと思っています。

上記コード例、もっと良いパターンなどあれば是非ご指摘くださいm(_ _)m


[^1]: 他の言語は詳しくありませんが同様なものが多いと推測します
ActionCable内でRedisに保存したセッションからログインユーザーデータを取得する

#まえがき
リアルタイムWebアプリケーションを開発していると、channel内でログイン情報を扱いたくなる時がよくあると思います。

ActionCable内でセッションストアをCookieStoreにした場合の
ログイン情報の取得例はいくつかサンプルがありましたが、
セッションストアにRedisを利用している場合のサンプルがなかったのでまとめておきます。

#環境
Ruby: 2.3.1
Rails: 5.0.0.1

で試しています。

# RailsのセッションストアをRedisにする
まずはセッションストアをredisにする為に以下のGemをインストールします。
また、Redisを扱いやすくするためにredis-namespaceも利用しています。

```
gem 'redis'
gem 'redis-rails'
gem 'redis-namespace'
```

続いて以下のファイルを設定します。

```ruby:config/initializers/session_store.rb

Rails.application.config.session_store :redis_store, {
  servers: {
    host: 'localhost',
    post: 6379,
    db: 0,
    namespace: 'sessions'
  },
  key: 'sessions',
  expire_after: 1.day
}
```

## ユーザーデータをcookieに書き込む
ログイン認証部分でsessionにデータをセットしたあとにCookieにuser_idをいれておきます。

```ruby
	def login
	  # ユーザーデータをセット
	   session[:user_id] = 1
	   session[:nickname] = "test"
	   
      # signed cookieにuser_idを持っておく
      cookies.signed[:user_id]  = user["user_id"]
    end
      
```

## redis側の設定

```config/redis.yml

development:
  hosts:
  - localhost
  db:
    session: 0
test:
  hosts:
  - localhost
  db:
    session: 0
production:
  hosts:
  - <%= ENV['REDIS_HOST'] %>
  db:
    session: 0
```

# ActionCable内でユーザーログイン状態を取得する
ActionCable内では通常の`session`は利用できません。
そのため、WebSocket経由で送られてくるCookieからuser_idを特定し、session_dataを取得する必要があります。
ApplicationCable内では`identified_by`で指定した値でユーザーを識別することができます。


```ruby:app/channels/application_cable/connection.rb
module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      val = session_from_redis
      if val
        self.current_user = {
          user_id:  val["user_id"],
          nickname: val["nickname"]
        }
      end
    end

    def session_from_redis
      # redisのsessionのnamespaceを取得
      redis_namespace = Rails.application.config.session_options[:servers][:namespace]

      # session cookieの名前を取得
      cookie_key = cookies[Rails.application.config.session_options[:key]]

      # redis内にあるsession_keyを組み立てる
      session_key = "#{redis_namespace}:#{cookie_key}"

      # redisからsessionを取得
      redis = CustomRedis.new({'db' => 'session'})
      val = redis.get(session_key)

      # Marshalされているのでdecode
      val ? Marshal.load(val) : nil
    end
  end
end
```

## ユーザーデータの参照
channel内でも`current_user`からユーザーデータを取得することが可能です

```ruby:app/channels/room_channel.rb
class RoomChannel < ApplicationCable::Channel
  def subscribed
    stream_from "room_channel"
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end

  def speak(data)
    ai = AI::Engine.new(user_id: current_user[:user_id], nickname: current_user[:nickname])
    ai.trigger(data['message'])
  end
end

```

#まとめ

実際に運用する場合は細かいエラー処理やセキュリティ対策などが必要ですが、簡易的に保存＆取得したい場合はこのような手法でログイン情報をやり取りすることができます。
30分で作る事業計画書: ウェディング関連サービス

注意: この事業計画書は、下記のイベントにて **ウェディング関連サービス** をテーマに30分で作成・発表したものです。

http://startupstudio.connpass.com/event/44630/

---

## SpaceWedding

---

## サービス概要
- シェアリングウェディングサービス
    - 貸会場を利用した低価格・アットホームさが特徴の手作りウェディングをプロデュース
    - 貸会場でも安心な料理・アイテム・衣装・スケジューリングのサポート

---

## ミッション・解決すべき課題
- 結婚式のニーズは多様化・個別化しつつあり、それに伴い高コスト化の傾向
- 一方、結婚式を挙げるカップルの割合は約40%
    - 経済的な理由がおよそ90%を占めると言われている
    - いわゆる低価格結婚では、祝い金でコストを賄う方式が殆ど、多様なニーズに答えられない
- 「自分たちらしい結婚式にしたい」「でもコストは抑えたい」という矛盾したニーズを叶えるためのソリューションが必要

---

## サービス内容
- 貸会議室や古民家、別荘などの空いたスペースを活用する
    - 結婚費用のほとんどは会場と飲食費、そして衣装代が占める
    - そのうち会場と飲食費を大幅に低価格化、かつ個別のニーズに対応可能にする
- ユーザとスペースオーナーとのマッチングを行う
    - スペースオーナーは日付を抑えておくだけでOK
    - アイディア出しから、スケジューリング、料理・アイテム・衣装の情報提供までサポート

---

## ビジネスモデル
- 手数料 結婚式資金の10%
    - ユーザは情報提供や結婚式までのサポートを受ける代わりに、結婚資金と手数料10%を支払う
    - スペースオーナーは会場代を受け取り、会場を提供する
    - (フリーランスプロデューサーだと手数料が10~15%)

---

## 業績計画とコスト構造
- 2017年1月 検証開始
- 2017年6月 月5組のカップルから開始する
    - 1組100万円として10万 x 5組 = 50万円/月
    - 人員3名 x -50万 = -150万円/月
    - 収支: -1200万円/年
- 2018年1月 人員を拡大して月50組のカップルに対応する
    - 1組100万円として10万 x 50組 = 500万円/月
    - 人員20名 x -50万 = -1000万円/月
    - 収支: -6000万円/年
- 2019年1月 本格的にWebや紙媒体による広告施策を開始する
    - 1組100万円として10万 x 100組 = 1000万円/月
    - 広告費 -1000万円/年
    - 人員30名 x -50万 = -1500万円/月
    - 収支: -7000万円/年
- 2020年1月 料理・アイテム・衣装面での企業提携を進め、低コスト化と多面拡大を狙う
    - 1組100万円として10万 x 500組 = 5000万円/月 = 1億2000万円/年
    - 広告費 -1000万円/年
    - 人員30名 x -50万 = -1500万円/月
    - 収支: 5000万円/年

---

## 課題
- 一生に一度の結婚式を貸会場や他人の家で行いたいと思えるか？
    - ホームウェディングの伸び具合を参照
- どこまでの低価格化を実現できるか？
- そもそもニッチなマーケットになる、どのくらいリーチできるか、リーチできそうなチャネルは？
    - 広範囲向けな紙媒体は費用対効果が良くない
    - 自社メディアの立ち上げなどを検討、1年目までに確率できる見込み 
- どこまで拡大できるか？他展開するならどうか？
    - AirBnBと提携し、安価かつ安心な海外での結婚式に対応する
    - 海外観光客を中心に、日本での結婚式(寺や神社、古民家)を提案する
複数のモデルが入り混じったメンバに対してrenderメソッドを使うと、各モデルに適切なパーシャルを読んでくれる

[Railsガイド](http://railsguides.jp/layouts_and_rendering.html#%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B)を眺めていたら、`render`メソッドにcollectionを渡す場合に置いて以下のような興味深い記述があった。

> 使用するパーシャル名は、コレクション内のモデル名に基いて決定されます。実は、メンバが一様でない (さまざまな種類のメンバが入り混じった) コレクションにも上の方法を使用できます。この場合、コレクションのメンバに応じて適切なパーシャルが自動的に選択されます。


つまり、複数のモデルが混在したメンバに対して、以下の様にrenderメソッドを呼び出すことで、
それぞれのモデルに対応したパーシャルが自動的に選択されてレンダリングされるという事。

```ruby
render @contents
```

たとえばQiitaのフィードの様な物を想定したとする。

サイト内の様々なユーザーが取るアクティビティを、Feedモデルに対応したfeedsテーブルに格納し、
それぞれのアクションに対応するモデルをFeedモデル継承させた(単一テーブル継承)させたモデルとして作成し、

```ruby

class Feed < ActiveRecord::Base
  # 何らかの実装
end

class FeedPost < Feed
  # 何らかの実装
end

class FeedStock < Feed
  # 何らかの実装
end
```

それぞれ、`app/views/feed_posts/_feed_post.html.erb`, `app/views/feed_stocks/_feed_stock.html.erb`という、モデルに対応したパーシャルを作成しておき、controllerでおもむろにFeedモデルからデータを取得して、


```ruby
class FeedsController < ApplicationController
  def index
    @feeds = Feed.all
  end
end
```

アクションに対応するViewテンプレートで、以下の様にrenderメソッドを呼び出すと、
感動的な事に、事前に用意したFeedPost, FeedStockのモデルに対応したパーシャルが呼ばれる。

```ruby
# app/views/feeds/index.html.erb
<%= render @feeds %>
```

強い。

Railsの単一テーブル継承つかった場合、親モデルからActiveRecordのメソッド(`where`等)をつかってオブジェクトを取得すると、
以下のように`Feed`モデルを継承したサブクラス(`FeedPost`, `FeedStock`)としてオブジェクトを取得することが出来るので、renderメソッドとの相性が非常に良い事がわかった。

```ruby
> Feed.all
  => #<ActiveRecord::Relation [#<FeedPost id: 1, user_id: 1, content_id: 1, created_at: "2016-11-17 03:20:56", updated_at: "2016-11-17 03:20:56">, 
#<FeedStock id: 2, user_id: 1, content_id: 1, created_at: "2016-11-17 04:25:21", updated_at: "2016-11-17 04:25:21">]>
```
acts_as_taggableのfixtureの書き方

ポイントは

1. fixtureのファイルを`acts_as_taggable_on`の下に置く
2. taggingの方でcontextを指定する（generatorが作るfixtureにはない）


```
# models/post.rb
class Post < ActiveRecord::Base
  acts_as_taggable
end

# fixtures/posts.yml
one: {}
two: {}

# fixtures/acts_as_taggable_on/tags.yml
tag_one:
  name: good
tag_two:
  name: bad

# fixtures/acts_as_taggable_on/taggings.yml
tag_one
  taggable: one (Post)
  context: tags
  tag: tag_one
```
BigQuery Standard SQLでn-gramを作る方法


文字列を与えると、その文字列をn-gramに分解する関数をSQLで書いてみました。
bigramとtrigramは使用頻度が高いので、特殊化した関数を別途定義してみました。

```sql
#standardSQL
CREATE  TEMPORARY FUNCTION NGRAM(str STRING, n INT64)
RETURNS ARRAY<STRING> AS ((
  SELECT ARRAY(SELECT SUBSTR(str, seq, n) FROM UNNEST(T.seqs) AS seq)
   FROM (
    SELECT str, GENERATE_ARRAY(1, LENGTH(str) - n + 1) AS seqs
  ) AS T
));

CREATE TEMPORARY FUNCTION BIGRAM(str STRING)
RETURNS ARRAY<STRING> AS (NGRAM(str, 2));

CREATE TEMPORARY FUNCTION TRIGRAM(str STRING)
RETURNS ARRAY<STRING> AS (NGRAM(str, 3));

SELECT BIGRAM('I am an NLPer')
```
[JAWS-UG CLI] IoT #14 IoTポリシーの削除

AWS CLIを利用して、IoT上にThingを削除してみます。


前提条件
========


IoTへの権限
-----------

AWS IoTに対してフル権限があること。


AWS CLIのバージョン
-------------------

以下のバージョンで動作確認済

- AWS CLI 1.11.14

```bash:コマンド:
aws --version
```

```text:結果(例):
      aws-cli/1.11.14 Python/2.7.10 Darwin/15.6.0 botocore/1.4.71
```

バージョンが古い場合は最新版に更新しましょう。

```bash:コマンド:
sudo -H pip install -U awscli
```


0. 準備
=======


0.1. リージョンの決定
---------------------

構築するリージョンを決めます。 (カレントユーザが利用するカレントリージ
ョンも切り変わります。)

```bash:コマンド(東京リージョンの場合):
export AWS_DEFAULT_REGION='ap-northeast-1'
```


0.2. 変数の確認
---------------

プロファイルが想定のものになっていることを確認します。

```bash:コマンド:
aws configure list
```

```text:結果(例)
            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile         administrator-prjz-mbp13        env    AWS_DEFAULT_PROFILE
      access_key     ****************XXXX shared-credentials-file
      secret_key     ****************XXXX shared-credentials-file
          region                         ap-northeast-1  env    AWS_DEFAULT_REGION
```

AssumeRoleを利用している場合はprofileが '<not set>'と表示されます。 それ以外のときにprofileが '<not set>' と表示される場合は、以下を実行して
ください。

   変数の設定:

         export AWS_DEFAULT_PROFILE=<IAMユーザ名>


0.3. 削除するポリシーの指定
---------------------------

```bash:コマンド:
aws iot list-policies \
        --query 'policies[].policyName'
```

```json:結果(例):
      {
         AWSIoTFullAccess
      }
```

削除するポリシー名を変数に格納します。

```bash:変数の設定:
IOT_POLICY_NAME='AWSIoTFullAccess'
```


1. 事前作業
===========

必ず削除するポリシーの内容を確認します。

```bash:コマンド:
aws iot get-policy \
        --policy-name ${IOT_POLICY_NAME}
```

```text:結果:
      (略)
```

依存関係が存在していないことも確認しておきます。

```bash:コマンド:
aws iot list-policy-principals \
        --policy-name ${IOT_POLICY_NAME}
```

```json:結果(例):
      {
        "principals": []
      }
```


2. ポリシー削除
===============

```bash:変数の確認:
cat << ETX

        IOT_POLICY_NAME: ${IOT_POLICY_NAME}

ETX
```

```bash:コマンド:
aws iot delete-policy \
        --policy-name ${IOT_POLICY_NAME}
```

```text:結果(例):
      (戻り値なし)
```


3. 事後作業
===========

同名のポリシーが存在しないことを確認します。

```bash:コマンド:
aws iot get-policy \
        --policy-name ${IOT_POLICY_NAME}
```

```text:結果(例):
      An error occurred (ResourceNotFoundException) when calling the GetPolicy operation: Policy default version not found
```


完了
====
単一テーブル継承を使って複数のコンテンツへのLikeをいい感じにまとめる

仕事で開発しているサービスで、

- ユーザーは複数種類のコンテンツを投稿出来る(開発済み)
- 複数種類投稿されるコンテンツに対してそれぞれ「いいね！」が出来る(開発済み)
- マイページ上で、自分がつけられた「いいね!」の合算数や、1週間の純増数などを表示させる(新規開発)
- マイページ上で、自分がつけた「いいね!」のコンテンツを時系列順に表示させる(新規開発)

の様な仕様に取り組む必要があった。
開発着手時点でのテーブルの構造は下の様に、
それぞれのコンテンツのデータが格納されているテーブル(左側の`articles`等)に対応する、
「いいね!」のデータを格納するテーブル(右側の`article_likes`等)を持つ設計で実装されていた。

![スクリーンショット 2016-11-17 17.13.44.png](https://qiita-image-store.s3.amazonaws.com/0/76641/838da6c5-1dc0-578f-f700-dd9582a44175.png)

しかし、

> - マイページ上で、自分がつけられた「いいね!」の合算数や、1週間の純増数などを表示させる(新規開発)
> - マイページ上で、自分がつけた「いいね!」のコンテンツを時系列順に表示させる(新規開発)

を実現させるうえで、`hoge_likes`テーブルがコンテンツの数だけある為、
直接合計数を取得する為には`hoge_likes`テーブルの数分だけjoinするなり、
非正規化したカラムにデータを集計させていくなりと、一手間加えないと実現させるのが辛い自体に直面したので、
「いいね!」の関連のデータは`likes`テーブル一つに集約して行くことにした。

`likes`テーブルへのデータの集約をするにあたって、RailsのActiveRecordの単一テーブル継承の機能を利用する事で、
以下のようにデータベースの世界では、テーブルは一つに集約され、
Railsのモデルを対象とするコンテンツに合わせて分ける事が出来るので、
今回満たしたい要件を、ビジネスロジック部分を殆ど弄ること無く実現することが出来る。

![スクリーンショット 2016-11-17 20.17.52.png](https://qiita-image-store.s3.amazonaws.com/0/76641/4530ccaa-c8cc-c9c9-352c-c221a5c5a621.png)

Railsの単一テーブル継承については以下が参考になる

http://qiita.com/kidach1/items/789c2e7aebbcfbd2583e


また具体的な作業内容としては、以下の様にLikeモデルを定義し

```bash
$ rails g model Like user_id:integer content_id:integer type:string
```

Like全体で共通のassociation・validationなどをLikeモデルに実装し

```ruby
class Like < ActiveRecord::Base
  belongs_to :user
  validates :user, presence: true, uniqueness: { scope: [:content_id, :type] }
  validates :content_id, presence: true
end
```

`Like`モデルクラスを継承する形で各コンテンツに対応したLikeのクラスを作成し、それぞれのクラスに必要なコードを記述していく
普通のオブジェクト指向の継承と同じなので、Likeモデルクラスで定義した`validation`や`association`は当然継承先のクラスでも適用される。
`association`を作成する際に、外部キーをちゃんと指定してあげないと、「`article_id`」無いぞと怒られるので注意

```ruby
class ArticleLike < Like
  belongs_to :article, foreign_key: 'content_id'
  # 以下何かしらクラスごとに必要なコードを記述していく...
end

class ArticleCommentLike < Like
  belongs_to :article_comment, foreign_key: 'content_id'
end
```

これだけで、あたかも`ArticleLike`と`ArticleCommentLike`が別のテーブルに対応したモデルかのように振る舞ってくれる。
実際に、コンソールでそれぞれのクラスからActiveRecordのメソッドを呼び出してみると、
それぞれ別のモデルクラスから新しいオブジェクトを作成しているが、データベースのレコード上は同じテーブル内にインサートされ、
`Like`モデルから継承したサブクラスのオブジェクトをそれぞれ取得することが出来る。

```ruby
> ArticleLike.create(user_id: 1, content_id: 1)
  => #<ArticleLike id: 1, user_id: 1, content_id: 1, type: "ArticleLike", created_at: "2016-11-17 03:20:56", updated_at: "2016-11-17 03:20:56">

> ArticleCommentLike.create(user_id: 1, content_id: 1)
  => #<ArticleCommentLike id: 2, user_id: 1, content_id: 1, type: "ArticleCommentLike", created_at: "2016-11-17 04:20:56", updated_at: "2016-11-17 04:20:56">

> Like.all
  => #<ActiveRecord::Relation [#<ArticleLike id: 1, user_id: 1, content_id: 1, created_at: "2016-11-17 03:20:56", updated_at: "2016-11-17 03:20:56">, 
#<ArticleCommentLike id: 2, user_id: 1, content_id: 1, created_at: "2016-11-17 04:25:21", updated_at: "2016-11-17 04:25:21">]>

```

この特性を利用する事で、自分につけられた「いいね!」の総数や、自分が「いいね!」したコンテンツを時系列順に取得して表示する
等の機能を開発する事が非常に簡単に出来る様になる。
Qiitaの新しいContributionの数式をTeX記法で書く

公式ブログでアナウンスがあったように、 [Qiita の Contribution の算出基準が変更されました](http://blog.qiita.com/post/153200849029/qiita-like-button)。

上記のブログエントリーの中で、 Contribution の算出基準について数式があるのですが、なぜか画像になってしまっています[^1]。画像がぼやけてしまっていますし、引用や編集もしづらいです。 Qiita には数式を書くための [TeX 記法がある](http://qiita.com/Qiita/items/c686397e4a0f4f11683d#%E6%95%B0%E5%BC%8F%E3%81%AE%E6%8C%BF%E5%85%A5)ので、 TeX 記法で書き直してみました。

```math
C(x) = \sum_{N(x)}^n L_n + \sum_{E(x)}^m min(0.1 T_m(x), 10) + w \sum_{Cm(x)}^n L_n
```

キレイですね！ Qiita 中であれば、次のような Qiita Markdown で書けます。

<pre><code>```math
C(x) = \sum_{N(x)}^n L_n + \sum_{E(x)}^m min(0.1 T_m(x), 10) + w \sum_{Cm(x)}^n L_n
```</code></pre>

インラインにしたい場合は `$C(x) = \sum_{N(x)}^n L_n + \sum_{E(x)}^m min(0.1 T_m(x), 10) + w \sum_{Cm(x)}^n L_n$` で OK です。

ついでに、記号の表もテーブル記法 &amp; TeX 記法で書き直してみました。

| 記号 | 意味 |
|:--|:--|
| $C(x)$ | ユーザー$x$のContribution |
| $N(x)$ | ユーザー$x$の記事 |
| $Cm(x)$ | ユーザー$x$のコメント |
| $E(x)$ | ユーザー$x$が編集リクエストを送った他人の記事 |
| $L_n$ | 記事やコメント$n$の「いいね！」数 |
| $T_n$ | ユーザー$x$が編集リクエストを送った後に増えた記事$n$の「いいね！」数 |
| $w$ | コメントの「いいね！」へのContributionへの重み。$0.5$とする。 |

ソース（ Qiita Markdown ）は↓です。

```
| 記号 | 意味 |
|:--|:--|
| $C(x)$ | ユーザー$x$のContribution |
| $N(x)$ | ユーザー$x$の記事 |
| $Cm(x)$ | ユーザー$x$のコメント |
| $E(x)$ | ユーザー$x$が編集リクエストを送った他人の記事 |
| $L_n(x)$ | 記事やコメント$n$の「いいね！」数 |
| $T_n$ | ユーザー$x$が編集リクエストを送った後に増えた記事$n$の「いいね！」数 |
| $w$ | コメントの「いいね！」へのContributionへの重み。$0.5$とする。 |
```

---

[^1]: ブログは Qiita 本体と違って TeX 記法がないのかもしれませんが。
[JAWS-UG CLI] IoT #11 IoT Thingの削除

前提条件
========


IoTへの権限
-----------

AWS IoTに対してフル権限があること。


AWS CLI
-------

以下のバージョンで動作確認済

- AWS CLI 1.11.14

```bash:コマンド:
aws --version
```

```text:結果(例):
      aws-cli/1.11.14 Python/2.7.10 Darwin/15.6.0 botocore/1.4.71
```

バージョンが古い場合は最新版に更新しましょう。

```bash:コマンド:
sudo -H pip install -U awscli
```


0. 準備
=======


0.1. リージョンの決定
---------------------

```bash:変数の設定
export AWS_DEFAULT_REGION='ap-northeast-1'
```


0.2. 変数の確認
---------------

プロファイルが想定のものになっていることを確認します。

```bash:変数の確認:
aws configure list
```

```text:結果(例):
            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile       iotFull-handson-mbpr13        env    AWS_DEFAULT_PROFILE
      access_key     ****************XXXX shared-credentials-file
      secret_key     ****************XXXX shared-credentials-file
          region        ap-northeast-1        env    AWS_DEFAULT_REGION
```


0.3. モノ名の指定
-----------------

```bash:コマンド:
aws iot list-things \
        --query 'things[].thingName'
```

```json:結果(例):
      [
        "handson-thing-20161117"
      ]
```

削除するモノの名を変数に格納します。

```bash:変数の設定:
IOT_THING_NAME='handson-thing-20161117'
```


1. 事前作業
===========

削除する前に、モノの内容を確認します。

```bash:コマンド:
aws iot describe-thing \
        --thing-name ${IOT_THING_NAME}
```

```text:結果:
      (略)
```


2. モノの削除
=============

```bash:コマンド:
aws iot delete-thing \
        --thing-name ${IOT_THING_NAME}
```

```text:結果(例):
      (戻り値なし)
```


3. 事後作業
===========

同名のモノの不存在確認

```bash:コマンド:
aws iot describe-thing \
        --thing-name ${IOT_THING_NAME}
```

```text:結果(例):
      An error occurred (ResourceNotFoundException) when calling the DescribeThing operation: Failed to describe thing handson-thing-20161117 because it does not exist in our ecosystem for your account
```


完了
====
[JAWS-UG CLI] IoT #10 モノからのデバイス証明書のデタッチ

前提条件
========


IoTへの権限
-----------

AWS IoTに対してフル権限があること。


AWS CLI
-------

以下のバージョンで動作確認済

- AWS CLI 1.11.14

```bash:コマンド:
aws --version
```

```text:結果(例):
      aws-cli/1.11.14 Python/2.7.10 Darwin/15.6.0 botocore/1.4.71
```

バージョンが古い場合は最新版に更新しましょう。

```bash:コマンド:
sudo -H pip install -U awscli
```


0. 準備
=======


0.1. リージョンの決定
---------------------

```bash:変数の設定
export AWS_DEFAULT_REGION='ap-northeast-1'
```


0.2. 変数の確認
---------------

プロファイルが想定のものになっていることを確認します。

```bash:変数の確認:
aws configure list
```

```text:結果(例):
            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile       iotFull-handson-mbpr13        env    AWS_DEFAULT_PROFILE
      access_key     ****************XXXX shared-credentials-file
      secret_key     ****************XXXX shared-credentials-file
          region        ap-northeast-1        env    AWS_DEFAULT_REGION
```


0.3. モノ名の指定
-----------------

```bash:コマンド:
aws iot list-things 
```

```json:結果(例):
      {
        "things": [
          {
              "attributes": {},
              "thingName": "handson-20161117"
          }
        ]
      }
```

証明書をデタッチするモノを指定します。

```bash:変数の設定:
IOT_THING_NAME='<証明書をデタッチするモノ名>'
```


1. 事前作業
===========


証明書IDの指定
--------------

```bash:コマンド:
aws iot list-thing-principals  \
        --thing-name ${IOT_THING_NAME}
```

```json:結果(例):
      {
        "principals": [
          "arn:aws:iot:ap-northeast-1:XXXXXXXXXXXX:cert/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
        ]
      }
```

```bash:コマンド:
aws iot list-thing-principals \
        --thing-name ${IOT_THING_NAME} \
        --query 'principals[]' \
        --output text \
      | sed 's/arn:.*:cert\///'
```

```text:結果(例):
      xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

この値を変数に取り込みます。

```bash:変数の設定:
IOT_CERT_ID='<証明書ID>'
```

ARNを取得します。

```bash:コマンド:
IOT_CERT_ARN=$( \
        aws iot describe-certificate \
          --certificate-id ${IOT_CERT_ID} \
          --query 'certificateDescription.certificateArn' \
          --output text \
      ) \
        && echo ${IOT_CERT_ARN}
```

```text:結果(例):
      arn:aws:iot:ap-northeast-1:XXXXXXXXXXXX:cert/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```


2. モノから証明書をデタッチする
===============================

```bash:変数の確認:
cat << ETX

        IOT_THING_NAME: ${IOT_THING_NAME}
        IOT_CERT_ARN    ${IOT_CERT_ARN}

ETX
```

```bash:コマンド:
aws iot detach-thing-principal \
        --thing-name ${IOT_THING_NAME} \
        --principal ${IOT_CERT_ARN}
```

```text:結果(例):
      (戻り値なし)
```


3. 事後作業
===========

```bash:コマンド:
aws iot list-thing-principals  \
        --thing-name ${IOT_THING_NAME}
```

```json:結果:
      {
          "principals": []
      }
```


完了
====
Machine learning course memo

# Apply patch to fix submit error
```
$ cd ex3
$ patch -p1 < ../diff.patch
```
diff.patch は、
`git diff 958e1^ 958e1 --no-prefix > diff.patch`
として作成。

https://github.com/ogiekako/learn-machine-learning/commit/958e1e8e178d3ab1daae2d128fa7657b5175dd76

# Octave

`~` をダミー引数として使える
`max(m, [], 2)` は、各行の max をとった列ベクトルを返す。第二引数を指定した場合、そこに argmax を返す。

```octave
>> [~, i] = max(magic(3), [], 2)
i =

   1
   3
   2
```

`find(y==0)` : `y(i) == 0` となるインデックスのリスト

`v(2:length(v))` のかわりに `v(2:end)` とかける

# Linear regression example

Data set:

| feature foo | bar | result |
|:-:|:-:|:-:|
| 1 | 2 | 5 |
| 2 | 3 | 4 |

```octave
data = [1 2; 1 3];
y = [5; 4];
m = length(y); % #data
n = length(data(1,:)); % #feature

X  = [ones(m,1) data];
% 1 1 2
% 1 2 3
x = X(1,:)
% 1 1 2
```

### Gradient descent
hypothesis:  $ h_{\theta}(x) = x'\theta $.

cost function: $$ J(\theta) = \frac{1}{2m} \sum_{i=1}^m \left(h_{\theta}(X^{(i)}) - y^{(i)}\right)^2 = \frac{1}{2m}(X\theta - y)^2$$

```octave
function J = costFunction(X, y, theta)
  J = sum((X * theta - y) .^ 2) / (2 * length(y))
end
```

学習率 learning rate: $\alpha$.

```math
\theta_j := \theta_j - \alpha\frac{\partial}{\partial \theta_j}J(\theta)
= \theta_j - \alpha\frac{1}{m}\sum_{i=1}^m X^{(i)}_j  \left(h_{\theta}(X^{(i)}) - y^{(i)}\right) =  \theta_j - \frac{\alpha}{m}X'_j(X\theta - y)
```
or $$\theta := \theta - \frac{\alpha}{m}X'(X\theta - y)$$

```octave
theta = theta - alpha / m * X' * (X * theta - y)
```

Plot:

```octave
history = zeros(num_iter, 1);
for iter = 1:num_iter
  history(iter) = costFunction(theta)
  theta = theta - alpha / m * X' * (X * theta - y)
end
```

### Visualization

```octave
theta0s = linspace(0,1)  % 0~1 を等間隔に100個. = linspace(0,1,100). logspace というのも.
theta1s = linspace(0,1)
data = zeros(len(theta0s), len(theta1s))
for i = 1:length(theta0s)
  for j = 1:length(theta1s)
    data(i,j) = f(theta0s(i); theta1s(j));
  end
end
% Bad knowhow for surf
data = data'
figure;
surf(theta0s, theta1s, data)
xlabel('\theta_0'); ylabel('\theta_1');

% TODO: contour.
```

# Libraries
## Visualization
```octave
x=linspace(0,1); % 1 x 100
y=logspace(0,1); % 1 x 50
data=x' * y;  % 100 x 50
surf(x,y,data'); % data' is a bad know-how for surf.
```
<img src=https://qiita-image-store.s3.amazonaws.com/0/10671/5f398d33-2e99-08cd-f2b8-01e71b6b3048.png height=300px>

[タイトル、軸ラベル、凡例のグラフへの追加](https://jp.mathworks.com/help/matlab/creating_plots/add-title-axis-labels-and-legend-to-graph.html)
`plot(x(1:50),y,'rx','MarkerSize', 5) % rx: use *red* *x* mark.`
<img src=https://qiita-image-store.s3.amazonaws.com/0/10671/32c1f56d-2b41-acf4-6c20-df2db5173ed7.png height=300px>

`plot(y,'g--') % x = [1, 2, ...] if omitted.  'g--' means blacK dash line.`
<img src="https://qiita-image-store.s3.amazonaws.com/0/10671/086638b5-b42f-d6cd-d759-faa9d3a4ba28.png" height="300px">

重ねて書く
```
plot(1:50, J1(1:50), ‘b’);
hold on;
plot(1:50, J2(1:50), ‘r’);
plot(1:50, J3(1:50), ‘k’);
```
[JAWS-UG CLI] IoT #9 IoTトピックルールの削除

前提条件
========


IoTへの権限
-----------

AWS IoTに対してフル権限があること。


AWS CLI
-------

以下のバージョンで動作確認済

* AWS CLI 1.11.14

```bash:コマンド:
aws --version
```

```text:結果(例):
      aws-cli/1.11.14 Python/2.7.10 Darwin/15.6.0 botocore/1.4.71
```

バージョンが古い場合は最新版に更新しましょう。

```bash:コマンド:
sudo -H pip install -U awscli
```


0. 準備
=======


0.1. リージョンの決定
---------------------

```bash:変数の設定
export AWS_DEFAULT_REGION='ap-northeast-1'
```


0.2. 変数の確認
---------------

プロファイルが想定のものになっていることを確認します。

```bash:変数の確認:
aws configure list
```

```text:結果(例):
            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile       iotFull-handson-mbpr13        env    AWS_DEFAULT_PROFILE
      access_key     ****************XXXX shared-credentials-file
      secret_key     ****************XXXX shared-credentials-file
          region        ap-northeast-1        env    AWS_DEFAULT_REGION
```


1. 事前作業
===========


1.1. Topic Role名の指定
-----------------------

```bash:コマンド:
aws iot list-topic-rules \
        --query 'rules[].ruleName'
```

```json:結果(例):
      [
        "handson_rule_20161117"
      ]
```

削除するトピックルールを指定します。

```bash:変数の設定:
IOT_RULE_NAME='<削除するトピックルール名>'
```

削除する前に内容を確認します。

```bash:コマンド:
aws iot get-topic-rule \
        --rule-name ${IOT_RULE_NAME}
```

```text:結果(例):
      (省略)
```


2. トピックルールの削除
=======================

```bash:変数の確認:
cat << ETX

        IOT_RULE_NAME: ${IOT_RULE_NAME}

ETX
```

```bash:コマンド:
aws iot delete-topic-rule \
        --rule-name ${IOT_RULE_NAME}
```

```text:結果(例):
      (戻り値なし)
```


3. 事後作業
===========

同名のトピックルールが存在しないことを確認します。

```bash:コマンド:
aws iot get-topic-rule \
        --rule-name ${IOT_RULE_NAME}
```

```text:結果(例):
      An error occurred (UnauthorizedException) when calling the GetTopicRule operation: Access to topic rule 'handson_rule_20161117' was denied
```


完了
====
「ストック」と「いいね！」ボタンの既視感

この既視感はなんだろうと考えていたのだけど、やっと気づいた。
一昔前のPixivのアプリのデザインそのものだった。

Pixivは、☆の数で評価するシステムと、ユーザーを評価するシステムと、お気に入りするボタンがあって、☆で評価しつつ、ユーザーを評価しつつお気に入りボタンも押してた。

結局どうすればいいのかわからないから、全部押してしまう。
今回の変更は、かなり挑戦したなと思いました。

いくらストックの存在感を薄めたところで、今までのストックの重要性が薄まるわけではないから、
しばらくは結局どうすればいいのか混乱しそう。

やっぱり、いいね！しあって馴れ合いたいわけじゃないから、シンプルに情報整理という意味でストックでいいのではないかと思いました。
AWSをドットインストールに従って始めたときの私のつまづきポイントまとめ

　2016年11月にAWSをドットインストールで始めた私がつまづいたポイントとその解決方法を備忘録も兼ねてまとめます。説明が雑なところあるけど、同じ動画見た人になら伝わるって信じてる。

## RDSのセキュリティグループが選べない
飛んだ先のEC2のセキュリティグループで、インとアウトの両方にSSH,HTTPなどと一緒にMYSQL~も追加。カスタム。セキュリティグループ(sg-~~~)を入力。
（インはSSH,HTTP,MYSQL、アウトはすべての〜,MYSQLになる）
（セキュリティグループ名はdefaultとかじゃなくてもいい）

## PHP3.~じゃなくて5.6にしたい
これ（http://qiita.com/yamaguchi_takashi/items/d4b7b2693b42679dc3ae ）を参考にしました。ドットインストールに従っていた僕らはAmazon Linux AMIのやり方で。

## FTP(Cyberduck)で立ち上げたインスタンスに接続
1. SFTPを選択、サーバ:パブリックIP、ポート:22、ユーザ名:ec2-user、パスワード:(空欄)、パス:/var/www/html、公開鍵認証を使用する
2. ~.pemを選択

## 許可permissionがなくFTP(Cyberduck)でデータを転送できない
1. /var/www/htmlフォルダのパーミッションを777(じゃなくてもいいのかも)にしちゃう
2. `$ sudo chmod 777 /var/www/html`

## パブリックDNSで飛んでるしindex.htmlもあるのにブラウザで表示されない
1. httpd（phpやmysqlと一緒にinstallしたやつ）が動いてないかも
2. `$ service httpd status`で確認
3. `httpd is stopped`なら止まってるーーー
4. `$ sudo service httpd start`で動いた。
GoogleMap を画像としてWebpage に埋め込む方法のあれ 



Google Maps Static Maps APIを使用すると便利っぽい

https://developers.google.com/maps/documentation/static-maps/intro?hl=ja

## Google Developer ConsoleからAPIキーを取得

Google Developer Console からプロジェクトを作成して、APIキーを作成する。

https://console.developers.google.com/

## URLを組み立てる

APIキーが取得できればあとは、URLを組み立てるだけで画像が取得できる。

基本となるURLは`https://maps.googleapis.com/maps/api/staticmap`で後ろにクエリを続けてURLを構築する。幾つか必須のパラメータがあり、最後に指定するkeyも必須

公式で提供されているURLを利用すると以下の様なURL形式となる。

https://maps.googleapis.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&zoom=13&size=600x300&maptype=roadmap
&markers=color:blue%7Clabel:S%7C40.702147,-74.015794&markers=color:green%7Clabel:G%7C40.711614,-74.012318
&markers=color:red%7Clabel:C%7C40.718217,-73.998284
&key={API_KEY}

![公式のMapサンプル](https://maps.googleapis.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&zoom=13&size=600x300&maptype=roadmap&markers=color:blue%7Clabel:S%7C40.702147,-74.015794&markers=color:green%7Clabel:G%7C40.711614,-74.012318&markers=color:red%7Clabel:C%7C40.718217,-73.998284)

## 場所に関するパラメータ

ともにマーカーを設定しない場合必須

**center** マップの中央を定める。地名または、緯度経度が利用可能

**zoom** マップのズームレベルを定める。0(世界地図) から 21まで

## 地図に関するパラメータ

**size** **必須** 画像の縦横比を指定する。フリー利用でのサイズは640x640が限界

https://developers.google.com/maps/documentation/static-maps/intro?hl=ja#Imagesizes

**scale** 画像の縮尺を指定する。scale=1がデフォルトで、sizeで指定したとおりの画像が帰ってくるが、scale=2 では単純に縦横２倍に拡大された画像が返ってくる。無料のアカウントで選択可能なのは2のみ

**format** 画像のフォーマット。デフォルトはpng

https://developers.google.com/maps/documentation/static-maps/intro?hl=ja#ImageFormats

**maptype** マップのタイプ。`roadmap`, `satellite`, `hybrid`, `terrain`などが選択可能。

https://developers.google.com/maps/documentation/static-maps/intro?hl=ja#MapTypes

## マーカーをセットする

マーカーは`markers`という名前で何度でも指定できる。

マーカーにはcolorやlabelに加え位置情報を設定できる。

````
markers=color:0x555555|label:A|osaka
````

https://developers.google.com/maps/documentation/static-maps/intro?hl=ja#Markers

## 感想
Prism.FormsのNavigationService用のViewを一括登録する

WPFではかずきさんのこの記事の
http://blog.okazuki.jp/entry/2014/09/11/224645
Bootstrapperの作成の項で書いてあるViewの一括登録を使ってたんですが
こんな感じでPrism.FormsのRegisterTypeForNavigationも一括でできないもんかなといろいろ試してみたらこんな感じで出来ました。

## コード

```csharp
protected override void RegisterTypes() {

    this.GetType().GetTypeInfo().Assembly
            .DefinedTypes
            .Where(t => t.Namespace?.EndsWith(".Views", System.StringComparison.Ordinal) ?? false)
            .ForEach(t => {
                Container.RegisterTypeForNavigation(t.AsType(), t.Name);
            });
            
}
```

この例では.Viewsで終わる名前空間の型を根こそぎ登録しているだけです。
別の場所に置いているならViewのある名前空間を指定するようにしてください。

## 追記

匿名型がある場合にNamespaceがnullになり、そこで落ちてしまう問題があったので以下のように修正しました。

``.Where(t => t.Namespace.EndsWith(".Views", System.StringComparison.Ordinal))``
↓
``.Where(t => t.Namespace?.EndsWith(".Views", System.StringComparison.Ordinal) ?? false)``
Guzzleのリクエストを再現するcurlコマンドを生成する。

小ネタです。
GuzzleでHTTPリクエストを実行したときに、それと同じリクエストを生成するcurlコマンドが欲しい場合があります。

[Cuzzle](https://github.com/namshi/cuzzle)　を使うと、Guzzleで実行したリクエストと同等のcurlコマンドを出力することができます。

# install
composerで一発。

```shell
$ composer require namshi/cuzzle
```

# 使い方

```php
<?php
// composer.jsonはよしなに…。
require_once './vendor/autoload.php';

// ロガーの設定
$logger = (new \Monolog\Logger('guzzle.to.curl'))
            ->pushHandler($curl_logger = new \Monolog\Handler\TestHandler());

// Guzlleのイベントハンドラにロガーを設定して、curlフォーマッタを指定。
$handler = \GuzzleHttp\HandlerStack::create();
$handler->after('cookies', new \Namshi\Cuzzle\Middleware\CurlFormatterMiddleware($logger));

// Guzlleクライアントにイベントハンドラを指定。
$client = new \GuzzleHttp\Client(['base_uri' => "http://www.example.com", 'handler' => $handler]);

// リクエスト実行
$response = $client->request('POST', "/v1/hoges", [
    'form_params' => [
        'param1' => 'abc',
        'param2' => 'def'
    ]
]);

// 結果を出力
$records = $curl_logger->getRecords();
echo $record[0]['message'];
```

```shell:結果
curl 'http://www.example.com/v1/hoges' -A 'GuzzleHttp/6.2.1 curl/7.49.1 PHP/7.0.12' \
  -H 'Content-Type: application/x-www-form-urlencoded' -X POST -d 'param1=abc&param2=def'
```

もちろんContent-Type: application/x-www-form-urlencodedやPOSTメソッドだけではなく、json形式や他のメソッドにも対応しています。

```php:（差し替え部分）
$response = $client->request('PUT', "/v1/fuga", [
    'json' => [
        'param1' => 'abc',
        'param2' => 'def'
    ]
]);
```

```shell:結果
curl 'http://www.example.com/v1/fuga' -A 'GuzzleHttp/6.2.1 curl/7.49.1 PHP/7.0.12' \
  -H 'Content-Type: application/json' -X PUT -d '{"param1":"abc","param2":"def"}
```
Xperia X PerformanceがZ5 Compactより遅い件(一応解決)

#より美しく、より使いやすく…でも遅い？

Xperia X Performanceは2016年6月、Z5 Compactは2015年11月発売の機種で、スペック的にもX Performanceのほうが良いはずなんですが、同じUnityアプリを実行すると、なぜかZ5 Compactのほうが安定して60fpsが出て、X Performanceは30fps前後。これはおかしい。

最初は画面解像度の違いで、X Performanceは1920x1080、Z5 Compactは1280x720だから後者の方がフィルレート的に有利なのかなーとも思ったんですが、Screen.SetResolutionで1280x720にしてもフレームレートの改善がほとんど見られませんでした。OSはともにAndroid 6.0。

#Profiling

ということで、Profilerで見てみました。

Xperia Z5 Compact
![xperia_z5.png](https://qiita-image-store.s3.amazonaws.com/0/141731/b826a13d-c129-f9d3-f220-044d863110dc.png)

Xperia X Performance
![xperia_xp.png](https://qiita-image-store.s3.amazonaws.com/0/141731/548d8a49-e7bf-bfdd-8344-f38d966de879.png)

CPUの"Others"がZ5では2ms程度、Xではなんと10ms。そりゃ16msに収まらないわけです。"Others"の中身は"Unaccounted"と"Overhead"。つまり、"不明"です。"Overhead"は同程度なので、明らかに"Unaccounted"に何かあります。

#調査編

日本語での情報はほとんどなく、英語だと関係ありそうな情報があるにはあるものの、Unityのバージョン5.4と特定の機種(解像度が高いものに多い？)の組み合わせっぽいというところまでは分かったんですが、このスレッドも解決には至っていませんでした。

Profiler constant 'unaccounted' entry takes 50% (13ms) on a SINGLE android device
http://answers.unity3d.com/questions/1235376/profiler-constant-unaccounted-entry-takes-50-13ms.html
BIG Performance Issue with Unity5 on Android !!!
https://forum.unity3d.com/threads/big-performance-issue-with-unity5-on-android.338847/

#解決編

…が、見つけましたー！！

Unity 5.3にアップデート後、Android端末での処理落ち
http://contoracutar.blog.fc2.com/blog-entry-37.html

簡単に言うと、"Player Settings->Other Settings"の"Auto Graphics API"のチェックを外して、"OpenGLES2"->"OpenGLES3"の順番に入れ替える、つまりOpenGL ES 3.0を使うのをやめると直るのでした。
![OpenGLES.png](https://qiita-image-store.s3.amazonaws.com/0/141731/d1416479-e5a3-5566-5329-2b3bf572c6be.png)

Profilerもこんな感じ。美しい！！
![xperia_xp_2.png](https://qiita-image-store.s3.amazonaws.com/0/141731/7ad6ce3b-4a08-a30c-19c6-e3d71e31ac03.png)

#最後に

特定の機種でしか発生しないようなので、気付いていない開発者の方も多いと思います。OpenGL ES 3.0専用の機能を使っていないのであれば、OpenGL ES 2.0にすると、今まで以上にいろんなユーザーに喜ばれるかもしれません。

…ただ、実際の原因が分からないんですよねー。OpenGL ES 3.0を使うようにしたら直ったので、OpenGL ES 3.0のUnity側の実装がまずいのか、Xperia X Performance側の実装がまずいのか、そういうものなのか。試しにUnity5.5ベータでもビルドしてみましたが、結果は同じでした。うーむ。

#追記(2016/11/18)

気になって、修正前のUnityアプリに拙作のこれ( http://qiita.com/MARQUE/items/fd08fe57cbe4e0b53aa8 )を実装して各機種の描画APIを見てみたんですが、XもZ5も”OpenGLES3"と表示されました。予想していたのは「Z5だけOpenGL ES 2.0が適用される」だったんですが、違った…。Adrenoのドライバーの問題なのか、Unityが機種による実装レベルの違いを抽象化できていないのか、はたまた、1920x1080という画面解像度に最適化されていないという問題なのか…。

#追記2(2016/11/21)

Xperia X Performanceと同じSnapdragon820を搭載するGalaxy S7 edgeと、Exynos7420を搭載するGalaxy S6をチェック。どちらもOpenGLES3のままでも謎なCPU負荷は発生しませんでした。それどころか、2560x1440という高解像度ながらUnityChan程度なら60fps出るレベル。さらに謎。
jquery-cookieを使い、初回ログイン時と、１ヶ月以上ログインしなかったユーザーにだけチュートリアルビデオをモーダルで表示する

[jquery-cookie](https://github.com/carhartl/jquery-cookie)を使い、初回ログイン時と、１ヶ月以上ログインしなかったユーザーにだけチュートリアルビデオをモーダルで表示するプログラムを書いた。
jquery-cookieプロジェクトは2016年11月現在[js-cookie](https://github.com/js-cookie/js-cookie)に移行しているので、こちらを利用したバージョンも追記できれば…。

```html:dashbord.html
<section id="section">
  <p><a id="modal-open" class="button-link">チュートリアル・ビデオをもう一度見る</a></p>
  <div id="modal-content">
    <video src="video/login/tutorial.mp4" autoplay controls></video>
    <a id="modal-close" class="button-link"><span class="is-hidden">閉じる</span></a>
  </div>
</section>

<script
  src="https://code.jquery.com/jquery-3.1.1.slim.min.js"
  integrity="sha256-/SIrNqv8h6QGKDuNoLGA4iret+kyesCkHGzVUUV0shc="
  crossorigin="anonymous"></script>
<script
  src="https://code.jquery.com/jquery-3.1.1.slim.min.js"
  integrity="sha256-/SIrNqv8h6QGKDuNoLGA4iret+kyesCkHGzVUUV0shc="
  crossorigin="anonymous"></script>
<script src="/js/jquery.cookie.js"></script>
<script src="/js/function.js"></script>
```

```javascript:function.js
$(function() {
      var $X_modal = 0;
      var $Y_modal = 0;
      var $modal_content = $("#modal-content");
      var $modal_overlay = $("#modal-overlay");
      if ($('#dashboard').length) {
        if ($.cookie('tutorialVideo') !== 'on') {
          $(window).on('load', function() {
            overlayCheck();
          });
        }
      }
      $("#modal-open").on('click', function() {
        overlayCheck();
      });

      function overlayCheck() {
        $(this).blur();
        if ($modal_overlay[0]) {
          return false;
        }

        var dElm = document.documentElement,
          dBody = document.body;
        $X_modal = dElm.scrollLeft || dBody.scrollLeft;
        $Y_modal = dElm.scrollTop || dBody.scrollTop;
        $("#main").append('<div id="modal-overlay"></div>');
        $("#modal-overlay").fadeIn();

        centeringModal();

        $modal_content.fadeIn();

        $("#modal-overlay,#modal-close").on('click', function() {

          window.scrollTo($X_modal, $Y_modal);

          $("#modal-content,#modal-overlay").fadeOut(function() {
            $.cookie('tutorialVideo', 'on', { //cookieにtutorialVideoという名前でonという値をセット
              expires: 30, //cookieの有効日数
              path: '/' //有効にするパス
            });
            $modal_overlay.remove();
          });
        });
      }

      $(window).resize(centeringModal);

      function centeringModal() {

        var w = $(window).width();
        var h = $(window).height();

        var cw = $modal_content.outerWidth();
        var ch = $modal_content.outerHeight();

        $modal_content.css({
          "left": (w - cw) / 2 + "px",
          "top": (h - ch) / 2 + "px"
        });
      }
});
```
### 所感
Qiitaの仕様変更で「ストック」が「いいね」と「ストック」にわかれたけど前の方が好きだった…。「いいねもせずにストックはマナー違反」とかありそうで怖い。

### 参考
- [jquery.cookie.jsが便利](http://negimemo.net/1108)
- [jquery-cookie](https://github.com/carhartl/jquery-cookie)
- [初心者でも分かる！モーダルウィンドウの作り方](https://syncer.jp/jquery-modal-window)
- [js-cookie](https://github.com/js-cookie/js-cookie)
30分で作る事業計画書: やりたいことリストサービス

## cuplist

---

## サービス名
- cuplist
    - 海外では「死ぬまでにやりたいことリスト」を bucket list と呼ぶ
    - やりたいことを気軽に、たくさん持とう
    - カフェタイムのように、やりたいことを語る時間を誰かとシェアしよう

---

## サービス概要
- 自分のやりたいことを探しながら、リスト化できるサービス
    - やりたいことを見つける・集める・叶えることで人生を豊かにする

---

## ミッション・解決すべき課題
- やりたいことリスト100を作ろうとしたけど...
    - やりたいことリストに最適なツールがない
    - やりたいことが思い付かない、誰かのリストを参考にしたい
- やりたいことリスト100を作った後は...
    - 達成したものは記録をしたい、シェアしたい
    - 何から始めたらいいか分からないものがある

---

## サービス内容
- やりたいことリストを作成・記録・管理できる
- 誰かのやりたいことを見ることができて、自分のリストに追加できる
- 同じやりたいことを持った人たちで情報交換ができる、達成した人からアドバイスがもらえる

---

## ビジネスモデル
- 広告
    - ユーザの将来的な消費意欲を把握することができ、効果的なリコメンド広告を打つことができる
    - 一般的な広告であればPV単価10円ほど

---

## KPIの推移
- フェーズ1: やりたいこと管理機能を実装
- フェーズ2: ユーザ調査・機能追加と改善・リリース準備
- フェーズ3: リリース・コミュニティ機能検証

---
## 業績計画

---
## 市場規模

---

## 競合環境
- [BuckitDream](http://pitchbook.com/profiles/buckitdream-profile-investors-funding-valuation-and-analysis)
    - 2012年 創業
    - 2013年 シードで400万円調達
    - [2016年 1.3億円調達](http://www.startupsmart.com.au/advice/funding/melbourne-startup-buckitdream-secures-1-3-million-investment-from-investible-after-officially-launching-with-the-help-of-ellen-degeneres/)
    - ユーザの消費意欲を表す"passion data"のプラットフォームとして注目されており、総額では9.3億円の投資を受けている

---

## 時価総額

---

## 資金調達額

---

## リーンキャンバス
![IMG_20161105_213409.jpg](https://qiita-image-store.s3.amazonaws.com/0/44003/70954cf0-7c67-327a-8bc0-968447af1f6e.jpeg)
C++でのvector.erase()は遅い

openFrameworksでアプリ作ってて、とある処理部分に17秒かかっててなんとか高速化できないかずっと
悩んでた。
具体的には3Dオブジェクトの全頂点をfor文回して調べてごにょごにょーってしてる箇所で、
再帰関数である事、for分ないでif分も多様しててopenCLやGPGPUなどのテクニックも使えそうになくって
どうしようかと思ってたらふとvector.erase()は遅いんではないか？と調べてみた。


ネット上の記事によるとやっぱりそうらしくって、
「最後の要素と交換してから消せば遅くならない」という記事を発見！
早速試してみた所、手持ちのプロジェクト内で再帰関数内で計23418回vector.erase()が
実行されて処理に17sec掛かっていた箇所がなんと9.3secに軽減された！
ありゃ、びっくり、、
こんな最適化方法があったんですね、、
これからはもうvector.erase()は使いません

※配列の一番最後にあるべき値が途中に移動してシャッフルされてしまうわけなので、配列内の要素の順番が
重要なプログラムの時にに使うときは注意ですね！

```cpp
    //Test1
    {
        vector<ofVec3f> list;
        list.resize(40000);
        
        float startTime = ofGetElapsedTimef();
        
        int l = list.size();
        for(int i = 0; i < l; i++) {
            if(i % 2 == 0) {
                //途中の要素を消すと遅い事がある
                list.erase(list.begin() + i);

                l--;
            }
        }
        
        cout << "erase    = " << ofGetElapsedTimef() - startTime << endl;
    }
    
    //Test2
    {
        vector<ofVec3f> list;
        list.resize(40000);
        
        float startTime = ofGetElapsedTimef();
        
        int l = list.size();
        for(int i = 0; i < l; i++) {
            if(i % 2 == 0) {
                //最後の要素と交換してから消せば遅くならない
                list[i] = list.back(); //std::swap(list[100], list.back())だとコピー1回多い
                list.pop_back();
                
                l--;
            }
        }
        
        cout << "pop_back = " << ofGetElapsedTimef() - startTime << endl;
    }

    //出力結果
    //erase    = 0.119303
    //pop_back = 0.00086391

```

[参考URL]
[C++]ゲームのオブジェクト管理システムが遅い場合
http://qiita.com/mrdagon/items/009dfad2413faee2a827









「追記 11/17 21:38]
Twitterでこんなご指摘を受けました。


「状況に応じてvector以外の最適化コンテナを使った方がよいのでは？」といったご指摘
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/selflash">@selflash</a> コンテナごとに特徴あるんで、挿入削除を高速で行いたいならそういうの向いてるコンテナにするといいですよ <a href="https://t.co/u3cHIrX9cl">https://t.co/u3cHIrX9cl</a></p>&mdash; cellfusion (@cellfusion) <a href="https://twitter.com/cellfusion/status/799196494339260416">2016年11月17日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>



「まとめて削除する様に実装を見直してみては？」といったご指摘
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/selflash">@selflash</a> erase-removeイディオムというものがあります。これはvectorコンテナの範囲内を指定した条件でまとめて削除する方法です。これでやれば速度面でも問題にならないはずです。<a href="https://t.co/1Cdo6HlLil">https://t.co/1Cdo6HlLil</a></p>&mdash; alwei@C91 西は22b (@aizen76) <a href="https://twitter.com/aizen76/status/799199833378537472">2016年11月17日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>