OmniAICreator/Qiita-1.07M huggingface dataset:
Dot Install Ansible入門 前編

プレミアム会員になって千円/月取られるようになったのでもとを取るために勉強する。
# 01 Ansibleとは
Ansibleはサーバー構成管理ツール。
サーバー立てたときの設定をスクリプトで管理できる。
これにより、同じ構成で複数台のサーバーを一基に立ち上げることができたり、設定修正管理が楽にできる。

# 02 全体観
Vagrantを使って3台のサーバーを立ち上げる。
host(Ansible)サーバー、DBサーバー、Webサーバーの3つ。
Ansibleで管理されるサーバーに特別なツールの導入は必要ない。
Pythonが入ってることと、ssh接続ができればいい。

hostサーバーにAnsibleをインストール。
Web,DBサーバーにAnsibleサーバーからssh接続テスト
Ansibleの設定。
    - Inventory: どのサーバーを管理するか
    - ansible.cfg: ansibleの設定ファイル
    - playbook: 管理サーバーの構成を書く

# 03 Vagrantでサーバー立ち上げ
vagrantfileを上手いこと弄れば3台同時起動とかできる。
vagrantの勉強もやると便利になりそう。
3台同時にvagrant upしようとするとエラーを吐いたので症状とその対処法リンク
http://javabayashi.hatenablog.com/entry/2017/02/10/135852

# 04 Ansibleインストール
hostサーバーにansibleをインストールする。
```
wget https://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
sudo rpm -Uvh
sudo yum -y install ansible
```

# 05 SSH接続の設定
## .ssh/configの編集
ssh接続用に名前解決するファイルを作成する。
- .ssh/configファイルを編集する。
``` rb:.ssh/config
Host web
    HostName 192.168.43.52
Host db
    HostName 192.168.43.53
```
- パーミッションを変える(？)
```
chmod 600 .ssh/config
```

## 秘密鍵、公開鍵の生成
sshで使用する鍵(秘密鍵、公開鍵)をhost側で生成し、公開鍵をweb、dbサーバーに配布する。
- 鍵の生成

```
ssh-keygen -t rsa
```
イロイロ聞かれるけどひとまずEnter連打。
id_rsaが秘密鍵、id_rsa.pubが公開鍵

## 公開鍵を配布
鍵専用のコピーコマンドがあるらしい。
```
ssh-copy-id web
ssh-copy-id db
```
パスワードはvagrantで立ち上げてるのでどっちもvagrantで。

## ssh接続する
```
ssh web
ssh db
```

# 06 ansibleを使ってみよう
## inventoryファイル
「ansible管理下に置くサーバー」を記述するファイル。
``` rb:./hosts
[web]
192.168.43.52
[db]
192.168.43.53
```
[]で管理サーバーにグループ名をつけることができる。
## inventoryファイルを指定する
ansible.cfgに今回編集したinventoryファイルを指定する。
``` rb:ansible.cfg
[defaults]
hostfile = ./hosts
```
これでデフォルトのinventoryファイルが今回編集したhostsに設定された。

## ansibleを試しに使ってみる
```
ansible all -m ping
```
allの部分はinventoryファイルで書いたグループを指定する。
web(192.168.43.52)に向かってpingしたいときは以下のようにコマンドを打つ。
```
ansible web -m ping
```

# 07 playbookを使ってみよう
## ansibledでサーバーにユーザーを追加する
playbookに管理対象サーバーの設定を書き込み、ansibleで実行する。
このセクションではweb、dbサーバーにユーザーを追加する。
```yaml: playbook.yml
---
# 設定対象サーバーを記述
- hosts: all
# 管理者権限が必要かどうか
  sudo: yes
# 実行するタスク
  tasks:
  # タスクの名前と実際に実行するタスクを記述
    - name: add a new user
      user: name = taguchi
```
実行する。
```
ansible-playbook playbook.yml
```
playbookファイルで
- 全ての管理対象サーバに対して(hosts: all)
- 管理者権限で(sudo: yes)
- taguchiユーザーを追加する(tasks: 以下)

と記述しているので、web、dbサーバーに対してtaguchiユーザーが追加される。

いったんここまで。
ファイルを読み込み標準入力として扱う方法

テストをするのにわざわざ入力するのが面倒だったので、どうにかならないかなぁと思いまして。
調べたところInputStreamを実装した**FileInputStream**を標準入力に指定することで
実現できるらしいのでコードを書いてみました。

## コード
```java
try {
    InputStream stream = new FileInputStream("filename");
    System.setIn(new FileInputStream(stream);
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String str = br.readLine();
    /* 
     * その他データの加工など記述
     */
} catch (IOException e) {
    e.printStackTrace();
}
```

## 感想
他に使う機会があるかと言われればそうでもない気がした。
大体は普通にファイル読み込んで処理するし。
mysqlのGROUP BYでグループ化した中で最新のレコードを取得する

GROUP BY区で括った中で最新のレコードを取得する場合を想定しています。

例えば、ユーザーがどのページを閲覧したかを記録する`user_page_logs`テーブルがあるとします。

- user_page_logsテーブル
<img width="1003" alt="スクリーンショット 2017-05-20 19.53.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/104359/e4f0f107-1892-30c7-70df-1a6cdadeef9e.png">

- user_page_logs内データ
<img width="546" alt="スクリーンショット 2017-05-20 20.23.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/104359/29687835-45eb-b3d9-dc5a-83a3234d2d4a.png">


指定したユーザーのページごとの閲覧時間(created)の最新が知りたいとします。

パッと思いつくSQLは以下のようなものでした。

```sql
SELECT * FROM user_page_logs WHERE user_id = 111 GROUP BY page_id ORDER BY created DESC;
```

上記の実行結果は以下のようになります。
<img width="773" alt="スクリーンショット 2017-05-20 20.09.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/104359/90481aea-ff30-1fac-d6c5-5e2f713bdc83.png">


page_idが1のグループは閲覧時間`2017-05-20 20:00:00`のレコードが取得されてほしいのに、`2017-05-03 10:00:00`のレコードが取得されてしまいます。

GROUP BYされた後にORDER BYされているようで、これでは期待する結果は得られません。

idはAUTOINCREMENTが前提ですが、以下のSQLで取得できました。

```sql
SELECT * FROM user_page_logs WHERE id IN( 
  SELECT MAX(id) FROM user_page_logs WHERE user_id = 111 GROUP BY page_id 
);
```

<img width="952" alt="スクリーンショット 2017-05-20 20.17.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/104359/a50ecea1-9845-0cce-d7e7-8dde635cef8a.png">
hubot-redis-brainで認証付きRedisサーバを設定する

`この記事では hubot-redis-brain 0.0.3 を使用しています`

hubot-redis-brain のRedisサーバに Azure Redis Cache を使用してみました。
(SSLアクセスするようにした方が良いかなと思いましたがいったんhttpで進めました)

Azure Portal で Azure Redis Cache の接続情報を見ると、接続時にパスワードの指定が必要です。
hubot-redis-brain の使用するRedisサーバをどのように設定するのか、調べながら進めました。

## 結論
環境変数 REDIS_URL に `redis://${auth}@${host}:${port}/${prefix}` の形式で設定

| パラメータ | デフォルト| 設定値|
|:----------|----------|-------|
| auth      |          | パスワード認証が必要な場合は、 `:${password}` で指定。**パスワード前に':'がある点に注意！**|
| host      |          | RedisサーバのFQDN、IPアドレス|
| port      |    6379  | ポート|
|prefix| hubot | Redisに投入する際のキーのプリフィックス|

## はまった流れ
まずは hubot-redis-brain が使用するRedisサーバの設定方法を調べました。
https://github.com/hubot-scripts/hubot-redis-brain を見ると、以下のような記載がありました。
> hubot-redis-brain requires a redis server to work. It uses the REDIS_URL environment variable for determining where to connect to. The default is on localhost, port 6379 (ie the redis default).
> 
> The following attributes can be set using the REDIS_URL
> 
> authentication
> hostname
> port
> key prefix
> For example, export REDIS_URL=redis://passwd@192.168.0.1:16379/prefix would authenticate with password, connecting to 192.168.0.1 on port 16379, and store data using the prefix:storage key.

REDIS_URLに `redis://${password}@${host}:${port}/${prefix}` の形で設定すれば良さそうなので早速設定してみました。
ログを見ると接続には成功しているようですが、Redisに対して情報が投入されません。

```
INFO hubot-redis-brain: Discovered redis from REDIS_URL environment variable
DEBUG hubot-redis-brain: Successfully connected to Redis
```

通常、URLに認証情報を埋め込む場合は `http://user:password@example.com/` のように書きます。
ホスト情報の前に
hubot-redis-brain のコードを見てみると${password}部分は**認証情報**としてみており、それを':'でsplitして2番目のパラメータをパスワードとして利用していました。
`redis://:${password}@${host}:${port}/${prefix}` の形式で設定してみると、Redisに情報が投入され始めました！
ログにも認証に成功した旨が表示されました。

```
INFO hubot-redis-brain: Discovered redis from REDIS_URL environment variable
INFO hubot-redis-brain: Successfully authenticated to Redis
DEBUG hubot-redis-brain: Successfully connected to Redis
INFO hubot-redis-brain: Data for hubot brain retrieved from Redis
```

めでたしめでたし。
Javaがわからないエンジニアが、JJUG CCC行ってみた。

![IMG_0013.JPG](https://qiita-image-store.s3.amazonaws.com/0/95804/4f3a94ef-1111-7040-b381-01b8573a4bc7.jpeg)

## どうして行こうと思った？

GWに開催された
soudaiさんの[たけともそん](https://soudai1025.connpass.com/event/55846/)に参加させていただいて
そのsoudaiさんが登壇されるということで
行ってきました。

## JJUG CCC参加してみて

基本的なタイムテーブルは[こちら](http://yujisoftware.github.io/jjug-ccc/2017-Spring/)参照。

会場はこんな感じ。

■ 休憩中のLT

![IMG_0011.JPG](https://qiita-image-store.s3.amazonaws.com/0/95804/545aa80d-8390-1cf0-4b02-140512db33aa.jpeg)

■ 講演中

![IMG_0012.JPG](https://qiita-image-store.s3.amazonaws.com/0/95804/77f38bb4-ba42-adbb-02ba-2ab202a70ded.jpeg)


（ぼやけとるー笑）

以下、自分が参加したセッションと
思い返して大事だと思ったポイントとコメント。

### 1. Javaエンジニアに知って欲しいRDBアンチパターン
----
#### ポイント
	- データにロジックを埋め込むな
	- アプリには、データベースの中身がわからない
	- DBを停止すると、サービスが止まる
	- DBを変更すると、複数サービスの改修が必要
	- データは常に変化する
	- アプリと違って、DBの知識、数年では廃れない。
	- モニタリング大事。

#### コメント
	- 当たり前なんだけど、どれも大事。
	- 特に、モニタリング。
	- 何が良くて、何が悪いのかが推測になってしまう。

### 2. Javaとアイドルのコラボ！？某アイドルBot開発の裏側
----

乃木坂46の若月佑美さんと会話できる[若様bot](http://wakasamabot.sakamichi46.com/)の話。

#### フレーズ
	- みなさん、会場合ってますか？（笑）
	- とりあえず、このセッションのゴールは、みんなが若月さん推しになること（笑）
	- LINEbotって難しそうなイメージがあるけど、そうでもない。
	- 思っているより、コードは買いていない
	- 基本的に、LINEで受け付けた言葉を、[Microsoft Cognitive Services](https://azure.microsoft.com/ja-jp/services/cognitive-services/)に投げつけて、解析結果を返しているだけ。

#### コメント
	- 実際、若様bot使って見たけど、すごい！面白い！笑
	- 自分でもなんか作ってみようかなと思える講演でこういうのやってみたい。笑
	- Microsoft Cognitive Servicesの画像解析とかは面白そう。
	- 何bot作ろうかな。俺だと、[吉岡里帆](https://ameblo.jp/yoshi-rihorihoriho/)botでも作ろうかな笑

### それ以外に聞いた講演
----

#### 3. Javaエンジニアから見たKotlinの魅力
- [Google I/O 2017](https://events.google.com/io/)で話題のKotlinってどんな感じなのかなと気になったので。
- とりあえず、Javaとの互換性が高く、シンプルに書けるんだなという感じ。（違ったらすいません。笑）

#### 4. グラフデータベース入門
- まぁ本当に入門って感じ。
- グラフデータベース面白いけど、まだまだ面白い領域を超えない感じ。
- あとは、百々さんが頑張ってくれるだろう。。。笑

## その他

講演聞く以外は、基本的には
以前の[Atlassianユーザー会](http://jkkitakita.com/archives/2017/04/20/2017042019/)でお会いした	
Atlassianの犬山さんに	
JIRAの使い方に関して相談させてもらっていた。
まだまだどの企業も探り探りらしい。

誰か、[Portfolio for JIRA](https://ja.atlassian.com/software/jira/portfolio)の良い使い方知らないかなー。
まぁJIRAを使っているので、それでできれば一番ベストなのでしょうが。
まぁAgileの`モニタリング`するよい方法があればいいのですがといった感じ。

## さいごに

自分はまだまだ外の世界がわからないペーペーなので	
引き続きこういう外のイベントは参加していこー。	

## みなさん、有難うございました！

- [soudaiさん](http://soudai.hatenablog.com/)
- [嶽　雅也さん](https://www.slideshare.net/MasayaDake/ss-76145383)
- [キクタローさん](http://kikutaro777.hatenablog.com/)
- [空中さん](https://twitter.com/soranakk)
- [Atlassian犬山さん](http://japan.blogs.atlassian.com/author/ninuyama/)
Rails 5 Action CableチャットアプリのiOSクライアント側を作る

# はじめに
iOSでリアルタイム通信がデモできるアプリを作りたいと思っていたところ。
RailsのAction Cableを使ったアプリケーションと通信する簡単なiOSアプリを作ってみました。

今回のRailsとiOSのコードはGithubに上げましたので、ご興味があれば動かしてみてください。
[ariiyu/ActionCableSample: Action Cable Sample with Rails 5.1 and Swift 3.1](https://github.com/ariiyu/ActionCableSample)

## Action Cableとは
Ruby on Rails 5で導入された、WebSocketによる双方向通信とRailsを統合するための仕組みです。
[Action Cable の概要 | Rails ガイド](https://railsguides.jp/action_cable_overview.html)

# Railsアプリケーション
※ruby 2.4.1、Rails 5.1.0
以下の記事を元に、Rails側の実装を行いました。
コードはほぼそのままです。

[Rails 5 + ActionCableで作る！シンプルなチャットアプリ（DHH氏のデモ動画より） - Qiita](http://qiita.com/jnchito/items/aec75fab42804287d71b)

## iOS側からのリクエストを許可

以下の記述を加えておきます。

```ruby:config.environment/development.rb
config.action_cable.allowed_request_origins = ['ws://localhost:3000']
```

# Swiftアプリ
[Swift-ActionCableClient](https://github.com/danielrhodes/Swift-ActionCableClient)というライブラリを利用しました。
WebViewを使わずに、ネイティブのコードを書いてRailsのAction Cableアプリケーションとやりとりします。


## 接続

接続が成功したら`onConnected`が呼ばれます。

```swift
var client: ActionCableClient!

self.client = ActionCableClient(url: URL(string: "ws://localhost:3000/cable")!)
client.connect()

client.onConnected = {
  print("Connected!")
}

client.onDisconnected = {(error: Error?) in
  print("Disconnected!")
}
```

## チャンネル作成・購読        

`client.create`でチャンネルを購読します。

```swift
self.roomChannel = self.client.create("RoomChannel")
```

## メッセージ受信

メッセージを受信したら`onReceive`が呼ばれます。

```swift
roomChannel.onReceive = { (JSON : Any?, error : Error?) in
  if let json = JSON {
    self.receivedBodyLabel.text = (json as! NSDictionary)["message"] as? String
  } 
}

roomChannel.onSubscribed = {
  print("Subscribed")
}
                
roomChannel.onUnsubscribed = {
  print("Unsubscribed")
}
                
roomChannel.onRejected = {
  print("Rejected")
}
```

## アクション送信


```swift
if let error = roomChannel["speak"](["message": "hello: " + String(random)]) {
    print("Error: ", error)
} else {
    print("spoke message")
}
```

# 動作確認
```
$ rails s
```
Railsサーバーを起動してWebブラウザで`http://localhost:3000`にアクセスすると、チャット画面が表示されます。
iOSアプリをシミュレータで実行して`message`を送受信すると、それぞれの端末の画面の表示がリアルタイムに更新されることを確認します。


# おわりに
Action Cableを使ったサーバーと通信するiOSクライアントアプリを作ってみました。
今回は単純なサンプルを作るのが目的でしたが、Rails側、iOS側ともにサクッと作れたように思います。

# 参考
- [Action Cable の概要 | Rails ガイド](https://railsguides.jp/action_cable_overview.html)
- [Rails 5 + ActionCableで作る！シンプルなチャットアプリ（DHH氏のデモ動画より） - Qiita](http://qiita.com/jnchito/items/aec75fab42804287d71b)
- [Ruby on Rails 5 でWebSockets通信を試してみる - 株式会社BEFOOL](http://befool.co.jp/blog/8823-scholar/ror-web-sockets/)
- [danielrhodes/Swift-ActionCableClient](https://github.com/danielrhodes/Swift-ActionCableClient)
サーブレットを動かすためのtomcatの設定をしてみた箇条書き

http://tomcat.apache.org/
サイトに行き、左のDownloadからバージョンを選び、Coreの中から自分にあったものを選ぶ。
今回は32-bit/64-bit Windows Service Installer を選んだ。

インストールをし、パソコンの右下の腕時計みたいなアイコンをクリックし、動いてることを確認。
動かなかったら、コマンドプロンプトに netstat -ano　といれ、かぶってるポートはないか確認、タスクマネージャからでも確認を取れる。
見るのはローカルアドレスである。8080があったらだめ。
http://localhost:8080/ へアクセスをする。
猫かトラかわからない生物が出てきたら成功。
コンテキスト.xmlというのでアプリケーションの管理をする。
コンテキストは、serverやwebなどがある。
最初の設定はserver.xmlで確認できる。
tomcatを開くと bin conf lib logs temp webappas workなどがあると思う。
webappsを開く。
docs manager ROOTがある。
ここに新しく、任意の名前のフォルダを作る。
http://localhost:8080/任意の名前 になる。
ここに確認用の自分で作ったindex.htmlを入れる。
無事表示。
同じ場所にWEB-INFのフォルダを作る。
その中にclassesフォルダ　libフォルダ　xeb.xmlファイルを作る。
classesにサーブレットのclassを入れる。
classesのclassを認識してもらうためにxeb.xmlに記入をしていく。
xeb.xmlに

```xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE web-app>

<web-app>
   <servlet>
     <servlet-name>hello</servlet-name>
     <servlet-class>aa.MA</servlet-class>
   </servlet>
   <servlet-mapping>
       <servlet-name>hello</servlet-name>
       <url-pattern> /aaa</url-pattern>
   </servlet-mapping>
</web-app>
```
http://localhost:8080/任意の名前のフォルダ/aaa

これでいけるはずがなぜかはまる。
原因はweb.xmlを更新しても更新されてなかった。
元のファイルで消しても、エディタでそこを見るとファイルがあるのでそれも消さなければいけなかった。
一つのファイルなのに、二回消さないといけないという謎現象。

```
<servlet>
　　　<servlet-name>そいつにつける名前
　　　</servlet-name>
　　　<servlet-class>そいつのクラス名 パッケージがあればそれが入ってるフォルダをつくり
     フォルダにclassを入れそれも記入する　  例　aa.hello
      </servlet-class>
</servlet>
```


```
<servlet-mapping>
      <servlet-name>
      探してもらう名前
      </servlet-name>
      <url-pattern>
      希望のurl        例　/kibou
      </url-pattern>
</servlet-mapping>
```
フォルダでいう/WEB-INF/classesはなぜか無視されるらしい。
AWSユーザがGCPを使い始めてみた②

「[AWSユーザがGCPを使い始めてみた①](http://qiita.com/kazu23pole/items/9828a5e025c7fdd15932)」から日が開きましたが、とりあえずパート２です

今回はネットワーク周りを中心に深掘り。

## グローバルIP
* AWSで扱うグローバルIPは基本的にはElastic IP
* GCPではインスタンスを起動するときにデフォルトでグローバルIPが付く
  * もちろん外すことも可能
* GCPのグローバルIPは２種類
  * エフェメラル
    * 再起動する度に変わる
  * 静的
    * 再起動しても変わらない
    * 代わりにインスタンス停止中はお金がかかる
* グローバルIPの管理は「ネットワーキング」→「外部IPアドレス」でおこなえる
* AWSに慣れてるとグローバルIPを使うことに違和感を感じる
    * CloudSQLなどグローバルIPしか持っていないものもある

## NAT Gateway
* GCPではAWSで提供されているようなNAT Gatewayは存在しない
    * 基本的にグローバルIPを用いるのでNATなんていらないという考えみたい
* どうしてもグローバルIPを持ちたくない場合、NATを構築することも可能
    * ただし、GCE上にNATインスタンスとして構築する必要がある
    * [NATゲートウェイの設定](https://cloud.google.com/compute/docs/networking?hl=ja#natgateway)
* NATインスタンスを構築した場合、冗長化の不安がある
    * ルートの設定をうまくすることで冗長化は可能
        * 複数NATインスタンスを構築し、同じ数だけルートを作成
        * ネクストステップ以外をすべて同じにする
        * ネクストステップはそれぞれルートごとにそれぞれのNATインスタンスを設定する
        
　　　　![nat.png](https://qiita-image-store.s3.amazonaws.com/0/98887/f2e41e50-655d-15d4-6dca-61e373e25bc2.png)

* NATインスタンスが単一障害点になるので、微妙・・・
    * しかもそれを自分で構築するのはなんとも
    * NATを提供して欲しい


## 続きは後ほど追記
特定の文字列が何文字あるかカウントする方法


![特定文字のカウント.png](https://qiita-image-store.s3.amazonaws.com/0/160563/dbb18c32-2769-629c-1175-55dc98f37958.png)

#利用シチュエーション

* 特定の文字が1つのセルの中に何文字あるかカウントしたい時

##直面した問題
　×　COUTIF関数はセルに対して文字列があれば+1としかカウントしてくれない

#記述方法
```
=LEN(参照)-LEN(SUBSTITUTE(参照,"特定文字列",""))

<記述例>
=LEN(A2)-LEN(SUBSTITUTE(A2,"o",""))
```

> **前提条件**
> A列に文字列情報
> ![文字列カウント前提.png](https://qiita-image-store.s3.amazonaws.com/0/160563/6ada7ed5-261b-5ecd-f65e-2b42798b97e2.png)

---

> **抽出結果**
> ![文字列カウント結果.png](https://qiita-image-store.s3.amazonaws.com/0/160563/1947a111-aa27-47b5-9f4b-6fa1c8aa83cd.png)

---

> **解説**

> **範囲の抽出**
> * LEN関数で文字列の全体の文字数を取得。
> * SUBSTITUTE関数で該当文字列を空白に変換。
> * 該当文字列が無くなった文字数をLEN関数で取得。
> * 全体から特定の文字列を除外した文字数を引くことで該当文字列の数を算出。


> ####個々の関数の説明####
> LEN関数は指定された文字列の文字数を返す

> ||書き方|利用例|
> |:---|:---|:---|
> |書式|LEN(文字列)|LEN(A2)|
> |引数1|文字数を数えたい文字列をを指定|A2|

> SUBSTITUTE関数は、文字列中の指定した文字を他の文字に置き換える

> ||書き方|利用例|
> |:---|:---|:---|
> |書式|SUBSTITUTE(文字列,検索文字列,置換文字列,置換対象)|SUBSTITUTE(A2,"o","")|
> |引数1|文字列またははセル参照を指定|A2|
> |引数2|置き換えたい文字列を指定|o|
> |引数3|置き換える文字列を指定||


#サンプル

* [Googleスプレッドシート](https://goo.gl/q4h1JD)
フロントエンド開発ツールのまとめ

フロントエンド開発に供するツールがたくさんあって位置づけがよくわからんので、整理してみた。

# 環境構築

## Bootstrapping tool

1. [VirtualBox](https://www.virtualbox.org/), [Docker](https://www.docker.com/)
2. [Vagrant](https://www.vagrantup.com/), [HashicorpのBox](https://atlas.hashicorp.com/boxes/search)  

サーバOSの設定や仮想マシンによるサーバ立ち上げの自動化に関するツールのこと。[VirtualBox](https://www.virtualbox.org/) と[Vagrant](https://www.vagrantup.com/)や[Docker](https://www.docker.com/)は直接仮想サーバを構築できるが、[Vagrant](https://www.vagrantup.com/)は[VirtualBox](https://www.virtualbox.org/) と[Vagrant](https://www.vagrantup.com/)や[Docker](https://www.docker.com/)のラッパーであり、直接仮想サーバを構築することはできない。また、[Vagrant](https://www.vagrantup.com/)はウェブ上から[Hashicorpに登録された仮想イメージ](https://atlas.hashicorp.com/boxes/search)を自動的にダウンロードし、[VirtualBox](https://www.virtualbox.org/) と[Vagrant](https://www.vagrantup.com/)や[Docker](https://www.docker.com/)を自動操作して仮想サーバを構築することができる。

## Configration

[Ansible](https://www.ansible.com/), [Ansible Galaxy](https://galaxy.ansible.com/)  

サーバやミドルウェアの設定を自動化するツールのこと。Bootstrapping toolの[Vagrant](https://www.vagrantup.com/)はConfigrationの機能も備えているが、機能が貧弱なので[Ansible](https://www.ansible.com/)を使ったほうが良い。なお、[Ansible Galaxy](https://galaxy.ansible.com/)はウェブ上に公開された[Ansible](https://www.ansible.com/)の自動設定ファイルを自動的にダウンロードし実行することができるツールであり、設定ファイルの作成を省略できるため非常に便利である。

# 実装

## Scaffolding tool

[Yeoman](http://yeoman.io/)

自動的にWebアプリケーションのテンプレート（足場＝scaffold）を構築するツールである。ウェブ上に公開されたgeneratorと呼ばれる設定ファイルを指定することで、コマンド一行だけでTask RunnerやPackage Managerの設定ファイル、ウェブサイトのテンプレート及びサイトのディレクトリ構成等を自動生成する。

## Task Runner

[Grunt](https://gruntjs.com/), [gulp](http://gulpjs.com/)  

JavaScript向けのビルドツールである。ビルドにかかる様々なタスクを自動化することができる。JavaのAnt/Mavenに相当する。

## Module Bundler

[Webpack](https://webpack.github.io), [browserify](http://browserify.org/)  

JavaScript向けのビルドツールである。Task Runnerとは異なり、依存関係の解決を自動的に行うことに特化している。

## Package Manager

[npm](https://www.npmjs.com/), [Bower](https://bower.io/), [yarn](https://yarnpkg.com/lang/ja/)

ウェブ上のアーカイブに事前に登録されたJavaScript向けのライブラリを自動的にダウンロードして配備するツールである。

## MVC Framework

[AngularJS](https://angularjs.org/) と [Backbone.js](http://backbonejs.org/)  

JavaScriptのフルスタックフレームワークである。

# ドキュメンテーション

## Style Guide Generator

[sc5-styleguide](http://styleguide.sc5.io)  

スタイルガイドとは、ある文書の用語法、段組又はタイポグラフィ等の文書の見た目に関する事項事項(スタイル)を定義する規約のことである。Style Guide Generatorは、スタイルガイドを簡単に自動生成できるドキュメンテーション・ツールである。  

- [スタイルガイドジェネレータを比べてみた](http://qiita.com/shwld/items/d41ba36e9fd2e636c723)

# テスト

## Test Automator

[Selenium](http://www.seleniumhq.org/) と [Karma](https://karma-runner.github.io/1.0/index.html)  

試験自動化ツールである。[Selenium](http://www.seleniumhq.org/)はウェブブラウザの操作を自動化し、[Karma](https://karma-runner.github.io/1.0/index.html)はJavaScriptの単体テストを自動化する。

# CI

## Configuration Management

[Git](https://git-scm.com/)

ソースやドキュメントを管理するための構成管理ツール。バイナリファイルの管理には不向き。

## CI Tool

[Jenkins](https://jenkins.io/), [GitLab](https://about.gitlab.com/)

継続的インテグレーション（CI）に用いるビルドツールである。GitLabは、Project ManagementやConfiguration Managementの機能も有する。

## Project Management

[Redmine](http://redmine.jp/overview/)

CI Toolとセットで用いられるプロジェクトマネジメントツールである。
slider 改良版　メモ

少し、改良しました。なので、メモします。

```js
    let parts = {
      width: 406,
      left: 0,
      index : 0,
      next : $(".slider_event-no1 .next.btn"),
      prev : $(".slider_event-no1 .prev.btn"),
      $prent_b : $("#slider_id_v2 ul.slider_event"),
      $prent : $("#slider_id_v1 ul.slider_event"),
      slide_anime : function(){
        $child = this.$prent.children("li");
        len = $child.length-1;
        // parts.$prent.stop().animate({
        //   left : (parts.width * parts.index) * -1 + "px"
        // },600);
        // $child.filter(':first-child').appendTo(parts.$prent);
          if (parts.index > 3) {
                parts.index = 0;
                parts.$prent.stop().animate({
                  left : 0
                },0);
            } else {
              parts.$prent.stop().animate({
                left : (parts.width * parts.index) * -1 + "px"
              },600);
          }
      },
    }
//1
    let target_1 = function(){
          parts.next.click(function(){
            parts.index++;
//            parts.play_clone();
            parts.slide_anime();
        });
          parts.prev.click(function(){
            parts.index--;
            // parts.play_clone();
            parts.slide_anime();
        });
      };
      target_1();
```
```js
この箇所です。

       if (parts.index > 3) {
                parts.index = 0;
                parts.$prent.stop().animate({
                  left : 0
                },0);
            } else {
              parts.$prent.stop().animate({
                left : (parts.width * parts.index) * -1 + "px"
              },600);
          }
```
では、参考までに
シェルスクリプトでテキストから改行を取り除くたった一つの方法

ネタが細かすぎるのでQiitaに書く。

# tr コマンドを使う

```
tr -d "\n"
```

いつも忘れるんですよね・・・。忘れて `sed -e "s/\n//g"` とか書いちゃう。反省。

例えば、JSONファイルから改行、タブ文字、空白を取り除く場合以下のようにする具合。(文字列中の該当文字も消えるので注意)

```
cat hoge.json | tr -d "\n\t "
```
osclassのいじり方-css編集編

#osclassのいじり方-css編集編

##osclassて何？
osclassは、マッチングサイトのオープンソース。phpで書かれている。

[構築でお世話になったサイト](https://triz-web.com/toronomado/category/osclass/)

##この記事の趣旨は？
ビジネスロジックをゴリゴリ修正してカスタマイズしたい私向けのメモです。
デフォルトのphpやらsassからコンパイルされたっぽいcssやらを修正するので、本家のアップグレードとかは使えなくると思うので、ご注意を！

##開発環境
windows10 + AptanaStudio3
レンタルサーバのlolipopにデプロイして修正確認してます。

##cssの修正の仕方
日本語化が終わって、フロントページを見てみると、
「検索」というボタンの文言が枠からはみ出してしまっている。
どうにも良くないから直したい。

chromeのデザインの修正に慣れている人は、
F12キーを押して、該当のノードに有効になっているスタイルを探して、
記述してあるファイルを修正すると思うのだけど、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/182516/2ab99e92-f5dd-989f-76ea-970b18820247.png)
これがどうにも適用されない。というか拡張子scssなんて見たこと無いですね。

拡張子scssというのはsassというやつで、cssをコンパクトに開発できるもののようです。
詳しくは[こちら](http://www.atmarkit.co.jp/ait/articles/1402/17/news102.html)

本記事ではsassの解説はしないです。あしからず。

さて本題に戻って、cssの修正方法を解説します。

cssは
[osclassデプロイ位置]/oc-content/themes/bender/css
の
main.css
になります。

まず、改行なしで入っていて見づらいので、
[こちら](https://syncer.jp/css-prettyprint)で整形してからの方が、修正しやすくなります。

整形後、.main-search .cell のブロックの下に
```
.main-search .cell button {
	width: 100px;
}
```
を追記してみてください。
ボタンの枠からはみ出していた「検索」の文字が、すっきりと入るように、、、なりませんね。。。:frowning2:


これはcssファイルがchromeにキャッシュされてしまっているのが原因です。
キャッシュを削除するという方法もあるのですが、
毎回消すのは面倒なので、キャッシュ回避の方法を記述しておきます。

[osclassデプロイ位置]/oc-content/themes/bender/common/head.phpの76行目

変更前

```
<link href="<?php echo osc_current_web_theme_url('css/main.css') ; ?>" rel="stylesheet" type="text/css" />
```
↓
変更後

```
<link href="<?php echo osc_current_web_theme_url('css/main.css') ; ?>?cache=<?php echo date("YmdHis"); ?>" rel="stylesheet" type="text/css" />
```

ようやく「検索」の文字が枠に収まりましたね。
railsのmigrationでtinyint(1)を定義する

論理削除用のカラムなど、真偽値を入れるtinyint(1)を作成したい場合があると思います。

railsのmigrationではbooleanで定義します。
以下のis_deletedが記述例になります。
<img width="658" alt="スクリーンショット 2017-05-20 18.22.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/104359/a18786b5-0eed-d024-42da-8b4243b8e82b.png">

作成されたテーブルです。
<img width="1215" alt="スクリーンショット 2017-05-20 18.23.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/104359/c51b2ecc-cac6-e34a-f6e0-7405ba9e1edb.png">
windowsだとGitすら難しいらしい

Gitってなんなの？な初心者さんに最初に伝えてたい『簡単手順フロー』

前提として「公開鍵認証」をしておく必要があるのと「Git上のユーザー名とパスワードは忘れずに」を大事にする事...？当たり前か!

このページでは、ファイル作る・レポジトリ作る・addしてcommitしてpushしてを理解する工程だけです。

Github上で「Github上のエリア」

1.ワーキングディクレトリ
2.ステージングエリア
3.リポジトリ

に関する理解はひとまずとして、pushする事すら難しい方に向けて内容ですね。
ひとまずここら辺ができてから、細い部分など各人ググればどうにかなるよ

```
$ カレントディレクトリ(現在のフォルダ階層にいるよ)
$ mkdir "作りたいフォルダ名(ディレクトリとも言うよ)"
$ cd "作りたいフォルダ名" 
$ touch "作りたいファイル名"(touchコマンドでファイルが作れるよ)
$ ls (lsコマンドでファイルが作れたのかを確認)
$ github.comで新しいリポジトリを作成する(今回はfdsafdsa)
$ git init
$ git add README.md
$ git commit -m "first commit"(-mオプションは必要だから忘れない)
$ git remote add origin https://github.com/tommottom/fdsafdas.git
$ git push -u origin master
```
Wio Nodeの設定変更用CLIツールを作ってみた

# はじめに
先日dotstudioさん主催の「[WioNodeで始めよう！挫折しないIoT入門ハンズオン](https://dotstudio.connpass.com/event/53388/)」に参加し、初めてWio Nodeに触れました。

> Wio Node自体はずいぶん前からあるらしいので、それの使い方やファームを書き換えてArduinoとして使う方法などがQiitaにもたくさん上がっているので、その辺りはそちらに任せるとして。


参加したハンズオンでは、最初のWio Nodeの設定に[Androidアプリを使った人が手ごずったようです](https://togetter.com/li/1104866)（自分は幸運にも設定できました）。
どうやら最初の設定には必ずスマートフォンアプリを使う必要があり、さらにWio Nodeに書き込んだSSIDに再度つなぎなおす、など、WiFiの切り替えも頻繁に行うため、特に機種差のあるAndroidではWiFi切り替え時に失敗するものがあるようです。

また設定時にはスマートフォン自体が設定したいSSIDに接続していることが必要らしく、スマートフォンのテザリングに接続したい場合は、設定用とテザリング用の2台のスマートフォンが必要となります。
その他、Wio Nodeにアクセスするときに必要なアクセスキーの取得が大変でした。

# CLIツール
前置きが長くなりましたが、上で書いた大変さはすべてWio Nodeの設定アプリがスマートフォン版しかないためと思い、[Wio NodeのWiFi設定用CLIツール](https://www.npmjs.com/package/wio-setup)を作ってみました。
下記のことができます。

- 新規のWio Nodeの登録＆WiFi設定
- 登録済みのWio Nodeの名称＆WiFi設定の更新
- 登録済みのWio Nodeのリスト表示
  - 名称
  - オンライン状態
  - アクセストークン（APIで使います）

# インストール
事前にnode.js（v6.10.3以降）を入れてください。
その後下記コマンドでインストールできます。

```shell-session
$ npm install -g wio-setup
```

動作確認は、bash（macOS / Creators Update以降のBash on Ubuntu on Windows）とコマンドプロンプト（Windows10）で行っています。
また設定可能なデバイスはWio Nodeのみです。
\# Wio Linkは手元にないため動作の確認はできていません。

# 使い方
```shell-session
$ wio-setup -h

  Usage: wio-setup [options]

  Options:

    -h, --help              output usage information
    -V, --version           output the version number
    -e, --email [value]     email address
    -p, --password [value]  password
    -s, --wifiSsid [value]  wifi ssid
    -P, --wifiPwd [value]   wifi password
    -n, --wioName [value]   wio-node name
    -l, --list              list your wio-node
```

## 使用例
設定

```shell-session
$ wio-setup
```

一覧取得

```shell-session
$ wio-setup -l
```

Wio Nodeの設定でつまづいたときは一度お試しください。
* * *
(追記)
上記ツールの宣伝を「[IoT縛りの勉強会! IoTLT vol.27 @ ヤフー（紀尾井町）](https://iotlt.connpass.com/event/52082/)」で「[WioNodeのWiFi設定を頑張った話](https://speakerdeck.com/horihiro/wio-nodefalsewifishe-ding-wowan-zhang-tutahua)」というタイトルでやったところ、

* [Androidを機内モードにしてからWiFiだけ有効にしてあげれば大抵うまく行く](https://twitter.com/wamisnet/status/865524335703764992)
* AndroidのWiFi詳細設定にある「接続不良のとき無効にする」をオフにしておく

などのフィードバックが得られました。ありがとうございました！
\# こういう情報／ノウハウが非公式にしかないのがツラい

* * *
(さらに追記)
また上より詳しい使い方を、@n0bisukeさんが速攻で[まとめてくれました](https://dotstud.io/docs/wionode-wiosetup/)。スクリーンショットも使って操作手順が分かりやすくまとまっています。
\# ホントは私がやるべきことなんですけどねぇｗ。。。
こちらもありがとうございます！！
カラムにかける制約について整理

データベースのカラムの制約についてメモ。

# カラムの制約

## 制約とは
特定のデータの保存を許さないためのバリデーション。
例えば同じニックネームのユーザーを登録できないようにする、メールアドレスが空のユーザーは保存ができないようにする、といったことができるようになる。

## なんのために制約をかけるのか
不正なデータや予期せぬデータが保存されることを防ぐため。


# 制約の種類とかけ方
主に以下の4つ。

## NOT NULL制約 (Not Null Constraint)
テーブルの属性値にNULL(空の値)が入ることを許さない制約。
絶対に値が必要なカラムに対してかける。


マイグレーションファイルでカラムを追加する時に書く。

【例】nameというカラムにNULLが入ることを許さない

```ruby
t.string :name, null: false
```

## 一意性制約 (Unique Constraint)
テーブル内で重複するデータを禁止する制約。


【例】usersテーブルにemailというカラムを追加する際、emailカラムには重複した値が入らないようにする

```ruby
class AddEmailToUsers < ActiveRecord::Migration
  def change
    add_column :users, :email, :string # 型がstringのemailカラムを追加する
    add_index :users, :email, unique: true # emailカラムに一意性制約をかける
  end
end
```

## 主キー制約(Primary Key Constraint)
主キーである属性値が必ず存在してかつ重複していないことを保証する制約。
Railsでは主キーはidカラムとして自動で生成され、重複しないようにできている。


## 外部キー制約(Foreign Key Constraint)
外部キーに対応するレコードが必ず存在することを保証する制約。

【例】studentsテーブルを生成し、classroomとのアソシエーションに外部キー制約を設定する

```ruby
class CreateStudents < ActiveRecord::Migration
  def change
    create_table :scores do |t|
      t.string :name
      t.references :classroom, foreign_key: true
      t.timestamps null: false
    end
  end
end
```
AppCodeを触ってみた

WIP AppCodeを触ってみた所感

## AppCode
https://www.jetbrains.com/objc/
JetBrainsというAndroidStudioを出しているところのIDE。
iOS開発にて、XCodeの代替として(もしくは作業の一部範囲をカバー)使えるかどうか。実際に使ってみた。

## 良かった点
- AndroidStudioとショートカットキーが似ている
- Xcodeと違って、まだ保管がトチ狂ったりはしていない
- プロジェクト構成ファイルエディターとしても使えそう
    - 「⌘;」から行ける
    - build phaseのrunscriptが見当たらないぞぉ〜
- AndroidとiOSを両方開発している人なら当然AndroidStudioをそれなりに使っているはずなので導入コストが低い

## 悪かった点
- 既存のProjectがXcodeのRunscriptにSwiftLintやCarthageCopyFrameworksを仕込んでいるのでそれが動かなくなっている
- ideaVimを使っているとRunAppのショートカットキーが死ぬ
    - View->ToolBarを出したらおなじみのボタンが出てきたのでよしとする
osclassのいじり方-日本語化という名の文言変更編

#osclassのいじり方-日本語化という名の文言変更編

##osclassて何？
osclassは、マッチングサイトのオープンソース。phpで書かれている。

[構築でお世話になったサイト](https://triz-web.com/toronomado/category/osclass/)

##この記事の趣旨は？
ビジネスロジックをゴリゴリ修正してカスタマイズしたい私向けのメモです。
デフォルトのphpやらsassからコンパイルされたっぽいcssやらを修正するので、本家のアップグレードとかは使えなくると思うので、ご注意を！

##開発環境
windows10 + AptanaStudio3
レンタルサーバのlolipopにデプロイして修正確認してます。

##日本語化という名の文言変更
![screencapture-rhg-exe-shizuoka-jp-1495267340170.png](https://qiita-image-store.s3.amazonaws.com/0/182516/010221d5-80cd-6aae-4152-6d96851c1be1.png)
上の絵は日本語になってますが、基本的には英語です。

これを変更するには、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/182516/58c429d7-0ac9-728d-8d2b-828ab4f6e26e.png)
[osclassデプロイ位置]/oc-content/languages/ja_JA/
の
core.mo
theme.mo
messages.mo
のいずれかのファイルの修正が必要です。
※日本語化対応が終わっていることが前提です。対応方法は[こちら](https://triz-web.com/toronomado/osclass-japanease-plugin/)

修正は体感的にやってみると良いと思います。

さて、このmoファイルなのですが、コンパイルして吐き出されたもので、直接編集することは、まずできないでしょう:frowning2:
↓テキストエディタで開くとこんな感じになっちゃう
![image.png](https://qiita-image-store.s3.amazonaws.com/0/182516/00a9adcc-6b2e-33ed-bade-1d840b00050e.png)

なので、コンパイルするためのファイルを修正する必要があります。
それが、同じディレクトリにあります、
core.po
theme.po
messages.po
になります。

それで、コンパイラが必要になるのですが、
それが[Poedit](https://poedit.net/)と言うものになります。
インストール方法はそれほど難しくないと思いますので省きます。

コンパイル方法は、
ファイル > MOにコンパイル
でできます。

それでは、試しに修正してみたいと思います。
「最新のレンタル家庭菜園」
という文言を
「作って学べるカレーシチュー特盛」
に変更してみます。

まず、theme.poをPoeditで開きます。
そして、「翻訳-日本語」列に当該文言を探し出します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/182516/db774775-1e4e-3c6f-2d19-9ef6ea7f11e6.png)
下部の「翻訳：」にある文言を修正します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/182516/019e793f-764c-ea4a-d4d9-67d275a21385.png)
そして、ファイル > MOにコンパイルでmoにコンパイルし、
[osclassデプロイ位置]/oc-content/languages/ja_JA/
へ配置します。

![screencapture-rhg-exe-shizuoka-jp-1495269561328.png](https://qiita-image-store.s3.amazonaws.com/0/182516/51192470-5996-cbbe-2e32-995b689f4e9e.png)

文言変更できました。
C++でSliceをやってみる 

某通信処理で64KBで分割したchunkを作る予定なのでSliceを試してみた。

* 資料: [sliced example](http://www.boost.org/doc/libs/1_54_0/libs/range/doc/html/range/reference/adaptors/reference/sliced.html)

# Install
```
$ sudo apt install libboost-dev
```

# 評価コード
```
#include <iostream>
#include <iterator> 
#include <fstream>
#include <boost/range/adaptor/sliced.hpp>
#include <boost/range/algorithm/copy.hpp>

int main(){
  std::ifstream input( "1.jpg", std::ios::binary );
  std::vector<char> buffer((
    std::istreambuf_iterator<char>(input)), 
    (std::istreambuf_iterator<char>()));
  
  for (size_t i=2; i<10; i++){
    std::cout << std::hex << (int)(unsigned char)buffer[i];
  }
  std::cout << std::endl;
  
  std::string str;
  boost::copy(
    buffer | boost::adaptors::sliced(2,10),
    std::back_inserter(str));
  
  for (int x = 0; x < str.size(); x++)
  {
    std::cout << (int)(unsigned char)str[x];
  }
  std::cout << std::endl;
  
  // std::cout << str << std::endl;
  // std::ofstream ofs("out.bin", std::ios::binary);
  // ofs.write(&str[0], str.size());
}
```

# 出力
```
ffe00104a464946
ffe00104a464946
```

# バイナリ
```
$ od -x 1.jpg | head -n 1
0000000 d8ff e0ff 1000 464a 4649 0100 0001 0100
```
DCGAN-tensorflowで自動画像生成をお手軽に試す

DCGAN は Deep Convolutional Generative Adversarial Networks の略で、超ざっくり言うと畳み込みニューラルネットワークを使って画像生成するアルゴリズムです。元論文以外に、日本語で噛み砕いて説明してくれている記事もたくさんあります。

- [はじめてのGAN](https://elix-tech.github.io/ja/2017/02/06/gan.html)
- [できるだけ丁寧にGANとDCGANを理解する - 午睡二時四十分](http://mizti.hatenablog.com/entry/2016/12/10/224426)

これを使って[アイドルの顔画像を生成](http://memo.sugyan.com/entry/20160516/1463359395)したり、イラストを生成したり、そういうことができるアレです。ググるとおもしろい事例がたくさん出てきます。

そんな**「なんだかすごい」**DCGAN、勝手に**「使うのも難しそう」**なイメージを持ってたのですが、TensorFlowを用いた実装が公開されてまして、

- https://github.com/carpedm20/DCGAN-tensorflow

実はデモを試すだけであれば**手順通りにコマンド実行するだけ**で簡単に実行できます。

以下手元で試した手順のメモです。（2017年5月更新）


##データダウンロード

git cloneしてきて、ダウンロードスクリプトを実行します。

```
$ python download.py celebA
```

自分の環境では以下のようなエラーが出ました。

```
Traceback (most recent call last):
  File "download.py", line 20, in <module>
    from tqdm import tqdm
ImportError: No module named 'tqdm'
```

tqdmというモジュールがないそうなので、インストール。

```
$ pip install tqdm
```

再度 `download.py` を実行することでデータのダウンロードと解凍が始まります。

ちなみに上記コマンド例の引数にある `celebA` はセレブ顔生成デモ用のデータを指定するもので、手書き数字を生成するデモを試す場合は

```
$ python download.py mnist
```

とします。


##学習

TensorFlowがアクティブな状態で、main.pyを実行するだけ。

```
(tensorflow)$ python main.py --dataset celebA --input_height=108 --train --crop
```

MNISTの場合は

```
(tensorflow)$ python main.py --dataset mnist --input_height=28 --output_height=28 --train
```


かなり時間がかかるのですが、`samples` フォルダに**途中経過の生成サンプル画像**を出力してくれるので、学習完了まで待たなくてもモデルが学習されていく様子を見ることができます。

![train_00_0099_celeb.png](https://qiita-image-store.s3.amazonaws.com/0/3180/da944f31-193c-b05f-86dd-061328b95875.png)

（CELEB, Epoch0, 100枚学習）

![train_00_0498.png](https://qiita-image-store.s3.amazonaws.com/0/3180/3008adcd-2c44-41af-9536-cc37a2d5e0e5.png)

（CELEB, Epoch0, 500枚学習）

![train_00_1098.png](https://qiita-image-store.s3.amazonaws.com/0/3180/0fd2d53f-864f-bda7-c726-8a3441b31c39.png)

（CELEB, Epoch0, 1100枚学習）

![train_01_0033.png](https://qiita-image-store.s3.amazonaws.com/0/3180/d71e098a-f988-f215-5f70-37320fce8a59.png)

（CELEB, Epoch1）


---


![train_00_0099.png](https://qiita-image-store.s3.amazonaws.com/0/3180/2a2beb05-8cb5-4299-d8a0-901cc4d0f1e4.png)

（MNIST, Epoch0）


![train_01_0006.png](https://qiita-image-store.s3.amazonaws.com/0/3180/07a8ff01-7a94-bcd5-a1f8-55726ee2f51f.png)

（MNIST, Epoch1）

・

・

・

![train_06_0041.png](https://qiita-image-store.s3.amazonaws.com/0/3180/46cb2ba5-44a9-1aa5-02d1-c7f6ea922c12.png)

（MNIST, Epoch6）

![train_08_0755.png](https://qiita-image-store.s3.amazonaws.com/0/3180/86b341f4-80ef-5fd5-93bf-190986c3bd1e.png)

（MNIST, Epoch8）

学習が進む毎に画像生成の精度が向上していることがわかります。


##テスト

学習完了したら、そのモデルを使用して次のように画像生成を実行できます。

```
$ python main.py --dataset mnist --input_height=28 --output_height=28
$ python main.py --dataset celebA --input_height=108 --crop
```



##自前学習データで試す

こうなってくると自前データで試したくなります。別記事につづく（予定）

→ 試しました＆書きました：　[ゲームアプリの「ドット絵」をディープラーニングで自動生成する](http://qiita.com/shu223/items/bd9102a10dd4ec8a86be)
AWS IoTの利用手順

AWS IoTに関する基本的な内容をまとめてみたものです。AWS IoTに関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
[AWS IoTの利用手順] (https://www.techcrowd.jp/iot/howtouse/)

# [AWS IoTを使うための手順] (https://www.techcrowd.jp/iot/howtouse/)

1) デバイスの作成
まずは、「Register -> Things」メニューの中の、 Register Thingsを選択して、デバイスを作成します。名称を指定して登録すると、AWS IoTの中にその名称のThingsおよびシャドウが作成されます。
その次に、そのデバイスのRuleを設定します。Ruleとは、どのデータに対してどういう条件のときにアクションを実行するかを決める情報です。

2) 証明書の作成
次にデバイスに登録する証明書を作成します。「Security -> Certificates」メニューの中の、Create a certificatesを選択して、証明書を作成します。

3) ポリシーの作成
次にデバイスに対して、AWS IoTの各種操作を許可するためのポリシーを作成します。全ての操作を許可するのか、一部の操作だけを許可するのか、許可する操作の定義です。「Security -> Policies」メニューの中の、Create a policyを選択して、ポリシーを作成します。

4) 証明書にデバイスとポリシーを割り当てる
作成した証明書とポリシーを関連づけします。証明書を作成した後に、「attach a policy」を選択して、関連付けしたいポリシーを設定、「attach a thing」を選択して割り当てしたいデバイスの設定をします。

マネジメントコンソールの設定は以上です。


# [デバイスの作成からデータを受信できるまで] (https://www.techcrowd.jp/iot/howtouse/)

AWS マネジメントコンソールは、Amazon IoT リソースのすべてにアクセスして管理するためのウェブベースのインターフェイスを提供しますが、プログラムから AWS IoT へのアクセスは、AWS CLI と AWS SDK を使用して有効にできます。

ハードウェアデバイス、センサー、モバイルアプリケーション、モノを接続するには、AWS IoT デバイス SDK を使用します。AWS IoT に接続が実装された AWS スターターキットから 1 つ選択します。それに加えて、AWS IoT は、幅広い種類のサードパーティ製のツールおよびゲートウェイでサポートされています。

AWS IoTデバイスSDK
AWS IoT デバイス SDK にはオープンソースライブラリ、サンプルの付属した開発者ガイドおよび移植ガイドが含まれているので、お客様の選択したハードウェアプラットフォームに革新的な IoT サービスを構築できます。

証明書と秘密鍵
マネジメントコンソールで作成した証明書と秘密鍵は、マネジメントコンソールからダウンロードしてデバイス側に設定します。

以上の作業で、デバイスからのデータのpublish/subscribeが可能となります。


# [AWS IoTへの各種アクセス方法] (https://www.techcrowd.jp/iot/howtouse/)

AWS IoT サービスには AWS マネジメントコンソール、AWS SDK、AWS CLI、AWS IoT API を使用してアクセスできます。接続されたデバイスからは AWS IoT デバイス SDK を使用して AWS IoT サービスと簡単に通信できます。
AWS IoT API およびコマンドは、コントロールプレーンオペレーションと、データプレーンオペレーションに大きく分かれています。コントロールプレーンオペレーションでは、セキュリティの設定、デバイスの登録、ルーティングデータのルールの設定、ログ記録の設定などのタスクを実行することができます。データプレーンオペレーションでは、接続されたデバイスから AWS IoT へ大規模に低レイテンシーかつ高スループットレートでのデータ取り込みを可能にします。
Serverless Step FunctionsにてLambdaの環境変数にStatemachineのARNを指定する方法

## 結論
以下のようにserverless.ymlを記述することで、Lambdaの環境変数にstatemachineのARNを記述することが出来ます。

```yaml:serverless.yml
functions:
  hello:
    handler: handler.hello
    environment:
        statemachine_arn: ${self:resources.Outputs.HelloStepfunc.Value}

stepFunctions:
  stateMachines:
    hellostepfunc:
      definition:
        <your definition>

resources:
  Outputs:
    HelloStepfunc:
      Description: The ARN of the example state machine
      Value:
        Ref: HellostepfuncStepFunctionsStateMachine

plugins:
  - serverless-step-functions
```

これでstatemachineを実行するだけのLambdaファンクションを作って、Lambdaのイベントからstatemachineを開始することが可能となります。
AWS IoTのルールエンジンとシャドウ

AWS IoTに関する基本的な内容をまとめてみたものです。AWS IoTに関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
[ルールエンジンとシャドウ] (https://www.techcrowd.jp/iot/ruleengine/)


# [ルールエンジンによりデバイスのデータに基づいたアクションを設定] (https://www.techcrowd.jp/iot/ruleengine/)

AWS IoTでは、ルールエンジンによって、接続されたデバイスによって生成されるデータを収集し、処理し、分析し、データに基づいたアクションを実行するアプリケーションを構築します。

ルールエンジンで直感的にルールを設定し、SQL に似たシンタックスでインバウンドデータを自動的にフィルタおよび変換できます。AWS IoT サービスから他のいくつかの AWS のサービスまたはお客様がお使いのサードパーティサービスへルーティングするルールを設定できます。

例)
• 受信メッセージのフィルタリングおよび変換、DynamoDB へ時系列データとして保存。
• センサーからのデータが特定のしきい値を超えた時、SNS を経由してプッシュ通知を送信。
• ファームウェアファイルを S3 に保存。
• Kinesis を使用して複数のデバイスからのメッセージを同時に処理。
• 受信データのカスタム処理を行うため Lambda を呼び出し。
• 自動再発行して、デバイスのグループへコマンドを送信。


# [ルールはSQLライクな構文にて指定] (https://www.techcrowd.jp/iot/ruleengine/)

AWS IoT のルールは 2 つの主要な部分で構成されます。

SQLステートメント:
SQL ステートメントでは、ルールを適用するトピック、必要に応じて実行するデータ変換、およびルールを実行する際の条件を指定します。ルールは指定されたトピックに発行されたすべてのメッセージに適用されます。

アクションリスト:
受信メッセージがSQLステートメントで定義された条件と一致した時、アクションリストで定義されたアクションが実行されます。

ルールの定義は JSON ベースのスキーマを使用しています。直接 JSON を編集、または AWS マネジメントコンソールのルールエディタを使用できます。


# [デバイスシャドウによるデバイスの状態管理の仕組み] (https://www.techcrowd.jp/iot/ruleengine/)

デバイス　シャドウは、デバイスの現在のステータス、アプリケーションから要求されたステータスを管理するJSONドキュメントであり、デバイスシャドウには、デバイスがオフライン状態のときでも、各デバイスについて最後に報告された状態と、希望する今後の状態が保持されます。最後に報告された時点の状態の取得や、希望する今後の状態の設定は、API またはルールエンジンによって実行されます。

デバイスシャドウでは、REST API が常時利用できるため、デバイスと協働するアプリケーションの構築が容易になります。さらに、アプリケーションではデバイスの現在の状態を取得することなく、希望する今後の状態を設定できるようになります。希望する状態と最後に報告された時点の状態との相違は AWS IoT によって比較され、相違を補うようデバイスに対してコマンドが送られます。

デバイスのシャドウには、デバイスの状態を最大 1 年間無料で保存できます。最低 1 年間に 1 度更新していれば、デバイスのシャドウは無期限に継続できます。更新しなかった場合は消去されます。
dein.vimのtomlのhook_*部分をシンタックスハイライトさせる

<img width="396" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/58084/b2b6dc9e-ccee-bbb4-d42c-cf4761e6edec.png">
こんな感じにする。

[SyntaxRange](https://github.com/inkarkat/vim-SyntaxRange)というプラグインを使うと、ある範囲のシンタックスハイライトを違うファイルタイプのシンタックスでハイライトにできる。

```
call SyntaxRange#Include("hook_add = '''", "'''", 'vim', '')
```

で`hook_add = '''`から始まって`'''`で終わる範囲をvimのシンタックスでハイライトできる。最後の引数は始まりと終わり部分の文字列のハイライトグループ（NonTextなど）の設定。ここでは空にしているので、なにも設定しない。

これを他の`hook_*`とか`"""`で囲んだときにも対応させて、`dein*.toml`のファイルを開いたときに実行するように設定するとこんな感じ。

```vim
augroup MyVimrc
    autocmd!
augroup END

autocmd MyVimrc BufNewFile,BufRead dein*.toml call s:syntax_range_dein()

function! s:syntax_range_dein() abort
  let start = '^\s*hook_\%('.
  \           'add\|source\|post_source\|post_update'.
  \           '\)\s*=\s*%s'

  call SyntaxRange#Include(printf(start, "'''"), "'''", 'vim', '')
  call SyntaxRange#Include(printf(start, '"""'), '"""', 'vim', '')
endfunction
```

## プラグインの修正

**この修正は本家に取り込まれました。**

元々のSyntaxRangeでは、`SyntaxRange#Include`するたびに、すでに読み込み済みのシンタックスファイルも

```
unlet b:current_syntax
syntax include @vim syntax/vim.vim
```

して再読込している。vimのシンタックスファイルを再読込すると

```vim:runtime/syntax/vim.vim
syn sync linecont "^\s\+\\"
```

の部分で「E403: 構文同期: 連続行パターンが2度指定されました」というエラーが出てしまう。
なので、~~読み込み済みのシンタックスファイルは読み込まないようにする処理を追加する必要がある~~ 読み込まないようにすると再度ファイルを開いたときシンタックスを効かせたい範囲のシンタックスが消えてしまったので、例外をcatchしてもみ消すようにした。

また、`SyntaxRange#Include`で渡した文字列を`printf`で

```vim
start="%s" end="%s"
```

のように直接当てはめているので、文字列に"を含む場合はおかしくなるので、"をescapeしてやる必要がある。

オリジナルとのdiff

- [Comparing vim-scripts:master...tmsanrinsha:master · vim-scripts/SyntaxRange](https://github.com/vim-scripts/SyntaxRange/compare/master...tmsanrinsha:master)
tmuxの罫線素片をACSに強制する

# TL;DR
unicodeの罫線素片がうまく表示されないフォントでも綺麗に罫線を表示するため、tmuxの罫線素片にVT100 alternate character setを強制できるようにした。

# 背景
プログラミングフォントはITエンジニアの生産性に直結する要素の一つであり、この選択肢を広げることは我々の業務環境を改善する上でとても重要である。ところで、tmux 2.4ではUTF-8環境での罫線素片の描画にunicodeの罫線素片[^1]を使用しており、使用フォントのU+2500からU+257Fの対応状況によっては罫線が連続した線にならない。例えば、次の図はM+ MN Type-1[^2]を使用して画面を左右に分割したところである。中央を横切っているペイン分割線が破線になってしまっていることが分かる。

![8616098e-38b4-11e7-846e-a2f04231c41d.png](https://qiita-image-store.s3.amazonaws.com/0/80240/d9412290-0d29-93f8-578e-4fc0205377a1.png)

一方、tmuxはCUIの描画ライブラリにncursesを使用している。ncursesはVT100のalternate character set(ACS)[^3]に対応しており、unicodeの罫線素片を使用することなく罫線を描画することができる。したがって、UTF-8環境でもACSを使用して罫線を描画するためのオプションがあれば、使用しているフォントの罫線素片対応状況によらず連続した罫線を表示することができる。

# 実装
そこで上記を実現するため、まずは素朴な実装を作ってtmuxの公式リポジトリに[プルリクエスト](https://github.com/tmux/tmux/pull/927/commits/ae5e76ef755126b80b8fcea4d79feb0129d5e644)を送ってみた。これはtmuxを-aオプション付きで起動するとACSを強制するというものである。最初は私の文章がイマイチだったこともあり意図が伝わらなかったが、[hattya氏](https://github.com/hattya)が援護してくれたこともあり根気よく説明しているとtmux開発者の[nicm氏](https://github.com/nicm)に火が点いてきた。以下はその[議論](https://github.com/tmux/tmux/pull/927)の要約。

- nicm「やりたいことの意味はわかったけど起動オプションでやるほどのこと？」
- yanma「じゃあ.tmux.confで設定するのは？」
- hattya「.tmux.confで設定する方法ならパッチあるよ」
- nicm「いや、NCURSES_NO_UTF8_ACSっていう環境変数がもうあるからそっち使うべきでは。別パッチ作ったよ」
- yanma「オプション逆じゃね？」
- nicm「確かに……というか調べてて気付いたけどterminfoに指定できるからそれに指定するのが正解。パッチ作ったから見て」
- hattya「オプション逆じゃね？」
- nicm「確かに……。ややこしすぎる。これでどう？」
- yanma「動いた！　プルリク変えたよ」
- nicm「反映させたよ」

というわけで、最終的に`tmux.conf`に下記のように書けばACSが強制できるようになった。次回のtmuxリリースから使えるはずである。

```.tmux.conf
set -ag terminal-overrides ',*:U8=0'
```

次の図は冒頭の環境に今回の設定を適用したところである。確かにペイン分割線がACSで描画されている。
![861da0fe-38b4-11e7-9af3-7a6dc04f41fa.png](https://qiita-image-store.s3.amazonaws.com/0/80240/b15def07-60ed-05a0-1080-30498e4e9182.png)

# 感想

tmuxレベルの有名プロジェクトにプルリクを送るのは初めてだったが、無事意見が反映されて嬉しかった。またこちらの意図が伝わってからのnicm氏の動きが洗練されていて、とても勉強になった。コマンドラインオプションや`.tmux.conf`で設定するのはすぐに思いつく安直な解決策なのだが、ncursesがterminfoを使用して文字を描画している以上、それと独立なパラメータをtmux側に定義することは設定の二重定義になり混乱を招く。これは言われてみれば正しいがtmuxのレイヤースタックを理解していなければ絶対にたどり着かない解決策であり、自分では思いつかなかっただけにローカル変更に留めずにプルリクを送ってみて正解だったなと思う。

# 参考資料
[^1]: Unicode 罫線素片 http://www.unicode.org/charts/PDF/U2500.pdf
[^2]: M+ FONTS https://mplus-fonts.osdn.jp/about.html
[^3]: NCURSES Extended Characters http://melvilletheatre.com/articles/ncurses-extended-characters/index.html
Amazon EC2でAWSが提供するWindows AMIの検索方法 (AWS Tools for Windows PowerShell)


* [Windows AMI の検索](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/finding-an-ami.html)
* [PowerShell を使用した AMI の検索](http://docs.aws.amazon.com/ja_jp/powershell/latest/userguide/pstools-ec2-get-amis.html)
* [Management ConsoleでのAMI検索](https://ap-northeast-1.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-1#Images:filter=amazon-images;platform=windows;visibility=public-images;sort=name)

**Get-EC2ImageByName**は日本語版が検索の対象になっていない。

## AMIの名前
AWS提供のWindowsAMIの名前パターン

- *OSバージョン* `Windows_Server-2016`, `Windows_Server-2012-R2_RTM`, ...
- *言語* `Japanese`, `English`, ...
- `Full`, `Core`, `Nano`
- `Base`(SQLServerなし), `SQL_2016_Standard`, `SQL_2016_Web`, ...
- *AMIのリリース年月日*

##検索条件
- region = 検索するリージョン
- owner = "amazon"
- platform = "windows"
- name = 先頭から末尾までのワイルドカード(`?`、`*`)、大文字小文字を区別する(CaseSensitive)検索

## 名前で検索して最新の1件を取得する
```ps1
Get-EC2Image `
    -Region ap-northeast-1 `
    -Owner amazon `
    -Filter `
        @{name="platform"; values="windows"}, `
        @{name="name"; values='Windows_Server-2016-Japanese-Full-Base-*'} `
    | sort CreationDate -Descending `
    | select name, imageid, Description -First 1
```
AWS IoTの実現するセキュアな双方向通信

AWS IoTに関する基本的な内容をまとめてみたものです。AWS IoTに関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
[AWS IoTの実現するセキュアな双方向通信] (https://www.techcrowd.jp/iot/secure/)


# [IoTサービスでサポートする通信プロトコル] (https://www.techcrowd.jp/iot/secure/)

AWS IoT では数十億のデバイスと数兆のメッセージをサポートし、それらのメッセージを AWS エンドポイントおよび他のデバイスに確実かつ安全に処理しルーティングします。AWS IoT では、断続的な接続を許容し、デバイスのコードフットプリントを削減し、必要なネットワーク帯域幅を削減するよう特にデザインされた HTTP、WebSockets、および MQTT といった軽量の通信プロトコルをサポートしています。

HTTP:
HTTPプロトコルでの通信をサポートしており、デバイス側からrestAPIで呼ぶことが可能
MQTT:
MQTTは軽量でリソースの限られているデバイスとの通信に広く使われているプロトコル。
AWS IoTは、MQTT 3.1.1ベースで実装
WebSockets:
MQTT over WebSocketsをサポートしているので、ブラウザベースのアプリケーションがAWS IoTと接続しているデバイスと双方向通信を行うことが可能。WebSocketはTCP port443での通信が可能のため、大部分のファイアウォールやwebプロキシーサーバを通すことが可能


# [軽量でリソースを消費しないMQTTプロトコル] (https://www.techcrowd.jp/iot/secure/)

MQTT は軽量の pub/sub プロトコルでネットワーク帯域幅とデバイスリソースを最小限に抑えるよう設計されています。MQTT では TLS を使用した安全な通信もサポートされています。MQTT は IoT ユースケースで頻繁に使用されています。MQTT v3.1.1 では OASIS 標準で、AWS IoT デバイスゲートウェイはほとんどの MQTT の仕様をサポートしています。

MQTTの軽量・リソースを消費しない点をHTTPS通信と比較すると、下記のようになります
(出展; http://stephendnicholas.com/posts/power-profiling-mqtt-vs-https)
・スループットが93倍
・メッセージ送信において消費電力が1/12
・メッセージ受信において消費電力が1/180
・コネクション維持において消費電力が1/2
・ネットワークオーバーヘッドが1/8


# [デバイスとの双方向通信] (https://www.techcrowd.jp/iot/secure/)

AWS IoTは、長期間のセッション保持によるクラウドを介したメッセージの送受信を実現します。クライアント(デバイスやアプリ)は制御信号やコマンドなどをクラウドから受信することができます。

AWS IoT では、断続的な接続を許容し、デバイスのコードフットプリントを削減し、必要なネットワーク帯域幅を削減するよう特にデザインされた HTTP、WebSockets、および MQTT といった軽量の通信プロトコルをサポートしています。AWS IoT では他の業界標準およびカスタムプロトコルをサポートし、複数の異なるプロトコルを使用しているデバイス同士でも相互に通信できます。

AWS IoT ではデバイスの最新の状態情報を保存し、いつでも読み込みまたは設定できるので、デバイスが常にオンラインであるかのようにアプリケーションに出現させることができます。これはデバイスとの通信が切断されていてもアプリケーションがデバイスの状態を読み込むことができ、デバイスが再接続された時にもデバイスの状態を設定し実装できることを意味します。

また、AWS IoTのMQTTでの通信では、ベストエフォート型と品質保障型のふたつの通信モードをもっています。ベストエフォート型はメッセージの到達は保障していませんが、オーバーヘッドは少なく、保障型ではメッセージの到達を保障しているものの、オーバーヘッドがベストエフォート型よりは大きくなります。


# [TLSによる相互認証] (https://www.techcrowd.jp/iot/secure/)

AWS IoT では接続するすべてのポイントで認証とエンドツーエンドの暗号化を提供し、デバイスと AWS IoT 間で身元が証明されたデータのみが交換されます。それに加え、詳細なアクセス権限のポリシーを適用することによってデバイスとアプリケーションに安全にアクセスできます。

AWS IoT では、AWS の認証メソッド (「SigV4」と呼ばれます) および X.509 証明書ベースの認証がサポートされています。HTTP による接続ではこれらの方法のいずれかを使用できます。MQTT による接続では証明書ベースの認証、WebSockets による接続では SigV4 を使用できます。AWS IoT では、AWS IoT によって生成された証明書、および推奨される認証機関 (CA) によって署名された証明書を使用できます。それぞれの証明書に対するロールやポリシーの選択をマッピングでき、デバイスに触れることなく、デバイスやアプリケーションによるアクセスを認証したり、考えが変わったときにすべてのアクセスを取り消したりできます。
React+Redux+Firebase Authenticationでログイン/ログアウト機能を実装する (1)

# はじめに

表題の通り、React+Reduxで作っているアプリにFirebase Authenticationによるユーザー認証システムをのっけてみようというものです。ログインにはGoogleアカウントを使用することにします。

アプリといってもあくまでログイン機能のサンプルなので

- ログインしていない場合はログインボタンが表示されており、そのボタンをおすとポップアップでGoogleアカウントログイン

- ログインしている場合は画面にユーザー情報を表示する

だけのものです。

サンプルアプリのリポジトリは↓にあります。
https://github.com/k5trismegistus/react-redux-firebase-login

リポジトリをみてもらえばわかりますが、ディレクトリ構造は次のようになっています。フロントエンドは家でちょろちょろいじる程度なのでよくわかってないです><。普通こうじゃない？みたいなツッコミがアレばぜひコメントください。

```
src/
  ├ actions
  ├ components (Presentational)
  ├ containers (Container)
  ├ firebase (Firebaseの設定など)
  ├ reducers
  └ index.js (エントリーポイント)
```

# Firebaseの準備

何はともあれFirebaseが使えないと話になりません。さっそく準備しましょう。

次の記事を参考にして、Firebaseを使える状態にしておきます。'firebase-toolsを使う'まで行えばOKかと。
[FirebaseのGoogleアカウントOAuth認証を試したのでメモ](http://qiita.com/cyokodog@github/items/eeedc5c94477602ec9f3)

準備ができたら、次のようにfirebase用のファイルを作成しておきましょう。

まずはアプリ内でfirebaseを使えるようにするイニシャライザ。

```js:firebase/index.js
import firebase from 'firebase'
import { config } from './config'

export const firebaseApp = firebase.initializeApp(config)
```

次にAPIキーなどの情報を記載する設定ファイル。空欄になっているところはfirebaseコンソールから得られる情報で埋めてください。

```js:firebase/config.js
export const config = {
  apiKey: "",
  authDomain: "",
  databaseURL: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: ""
}
```

# Redux Stateの設計

ログイン情報だけなので、こんな設計にしてみました。

```json
{
  auth: {
    uid: '',
    displayName: '',
    email: ''
  }
}
```

displayNameがGoogle+の名前に対応します。

非ログイン状態であればすべて空文字、ログイン情報であれば値が入っているということにします。ログインしているかどうかの判定は`uid`に値が入っているかどうかで行うことにしましょう。

# ルートReactコンポーネントの準備

## 基本的な考え方

このサンプルアプリでは、次のような設計をとります。

- ログイン時に表示されるコンポーネントとログアウト時に表示されるコンポーネントが存在する
- 上位のコンポーネントでログイン状態をみて、状態に応じてどちらかを表示するか切り替える。

まずは簡単な最上位のコンポーネントから作ることにしましょう。

## Container component

```js:containers/AppContainer.js
import firebase from 'firebase'
import { connect } from 'react-redux'
import App from '../components/App'

const mapStateToProps = (state) => {
  console.log(state.auth.uid)
  return {
    uid: state.auth.uid,
  }
}

const AppContainer = connect(
  mapStateToProps
)(App)

export default AppContainer
```

Reduxステートの`auth.uid`をPresentational componentのpropsにバインドするだけ。

## Presentational component
```js:components/App.jsx
import React, { Component } from 'react'

import UserInfoContainer from '../containers/UserInfoContainer'
import AuthContainer from '../containers/AuthContainer'
import { firebaseApp } from '../firebase'

export default class App extends Component {
  constructor(props) {
    super(props)
  }

  render() {
    return (
      <div>
        { this.props.uid ? <UserInfoContainer /> : <AuthContainer /> }
      </div>
    )
  }
}
```

`uid`の有無に応じて表示する下位のコンポーネントを切り替えます。
今回はログインしていたら`UserInfo`、ログアウトしていたら`Auth`というコンポーネントを表示するようにします。

# 今後

(2)では、Authコンポーネントをつくりログインできるところまでを解説しています。
[React+Redux+Firebase Authenticationでログイン/ログアウト機能を実装する (2)](http://qiita.com/k5trismegistus/items/7aa3b61d3815a4474016)