OmniAICreator/Qiita-1.07M huggingface dataset:
JavaScript学習メモ　時間制御

```javascript
var DAYSTART = new Date();
var DAYEND   = new Date('2017/11/20 00:00:00');
var INTERVAL = 1000;
var calc = new Date(DAYEND - DAYSTART + INTERVAL);
function countdownTimer() {
  var addZero = function(n) {
    return ('0' + n).slice(-2);
  }
  if (new Date(calc) <= INTERVAL) {
    document.getElementById('timer').textContent = '終了しました。';
  } else {
    calc = new Date(new Date(calc) - INTERVAL);
    console.log(calc);
    console.log(new Date());
    var date = calc.getUTCDate() - 1 ? calc.getUTCDate() - 1 + '日' : '';
    var hours = calc.getUTCHours() ? calc.getUTCHours() + '時間' : '';
    var minutes = addZero(calc.getUTCMinutes()) + '分';
    var seconds = addZero(calc.getUTCSeconds()) + '秒';
    document.getElementById('timer').textContent = date + hours + minutes + seconds;
  }
}
countdownTimer();
setInterval(function() { countdownTimer() }, INTERVAL);


```
AV Foundationのドメインモデル

### はじめに

iOSのフレームワークはドメインモデルの良質なサンプル群である。そこでAV Foundationについてどういう思想で成り立っているか調査した

### AV Foundationについて

AV FoundationはQuick Timeの後継である。知っている人はご存じのとおりQuick TimeのAPIはCベース、しかもCore FoundationやCore Graphicsの様にオブジェクト指向風実装でないので見通しが悪かった。でiPhone版iMovieを出すにあたり、動画関係APIをObjective-Cで一から書き直した。
その次に、Mac OS Xに移植されてFinal Cut Pro Xに導入された。

### オブジェクト図から明らかになるドメインモデル

![20140923124147.png](https://qiita-image-store.s3.amazonaws.com/0/39706/83cf2d4e-63a6-a6e4-26dd-d2a646fcbc23.png)

オブジェクト図である。関係が複雑であみの目の様になっているが、以下の通りに分類するとAV Foundationの設計思想が分かる。

* 紫：再生制御
    *  AVPlayer
    *  AVPlayerItem
* 黄：レンダリング前のポストエフェクト
    * AVVideoCompositing
    * MTAudioProcessingTapRef
* 緑：特殊効果
    * AVMutableAudioMixInputParameters
    * AVMutableVideoCompositionLayerInstruction
    * AVMutableAudioMix
    * AVMutableVideoCompositionInstruction
    * AVMutableVideoComposition
    * AVVideoCompositing
* 水：編集中のメディアファイル
    * AVMutableComposition
    * AVMutableCompositionTrack
* 赤：元のメディアファイル、素材
    * AVAsset
    * AVAssetTrack

つまり、５つのレイヤーに関心毎を分離して自由に組み合わせれる様になっているのである。

これは動画アプリの事を考えれば当たり前で、元ファイルからいろいろ試行錯誤しながら編集してそれぞれを比較したいし、いろいろ特殊効果を検討したい、という要件を考えればこういうモデルに行き着くだろう。

### オブジェクト図から明らかになるドメインモデル　その２

![20140923124310.png](https://qiita-image-store.s3.amazonaws.com/0/39706/895cf212-1b7d-bddd-a53a-66d514a3ba18.png)

順序は逆になるが普通の再生中のオブジェクト図を示す。
AVPlayerクラスはクロックの更新をしているだけで、現在再生位置はAVPlayerが保持している。
ギャンブルで絶対に勝つ方法(?)マーチンゲール法が信じられないんだ! シミュレーション結果

# 背景
**絶対に勝てるギャンブルの仕方知っていますか?**
あなたはこの情報を手に入れるだけで夢のような生活を送ることができます!

このような怪しい情報商材みたいなのありますよね。
**そんな話をシミュレーションしてみようという話です。**

# マーチンゲール法
いわゆる絶対負けないギャンブルの仕方(掛け金の変え方)です。
**この方法を利用して負けても当方は責任を負いません。**

**ゲーム**
・単純化として「ルーレットの赤か黒だけに賭ける」場合を考える。
・ルーレットの玉が自分の指定の色だったら掛け金分貰えて、外れたら掛け金分失う。
・ルーレットは「0」や「00」という赤や黒でもない場所があり、そこに玉が入れば赤や黒にかけていたひとは負けになる。(だから還元率は97%程度)

**マーチンゲール法のやり方**
・負けたら賭け金を倍にするだけ
・(勝ったら掛け金を最小単位にもどす)

**マーチンゲール法の前提**
・青天井(掛け金に上限がない)であること
・かなりの元手で必要

**例**
1. 1コインを賭けて負ける (収支-1コイン)
2. 負けたので2コインを賭ける
3. 2コインを賭けた試合で負ける (収支-3コイン)
4. 負けたので4コインを賭ける
5. 4コインを賭けた試合で勝つ (収支+1コイン)

このような感じでどんなに負けても一回勝てば取り戻せる賭け方。
**でも私はこの方法が理解できるが納得がいかない。**
**だからシミュレーションしてみる。**

# プログラム
Pythonを使って作ってみました。

```python:simu.py
from random import random

balance = 1000000 # 残高
min_bet = 1.0 # 最小掛け金
win_chance = 0.475 # 勝てる確率
game_times = 1000000000 # 最大ゲーム数

def game():
    global balance
    if random() < win_chance:
        balance += min_bet
        return True
    else:
        balance -= min_bet
        return False

def print_state(state, count):
    print("before_state", str(state)[0], "count", count, "balance:", balance, "bet", min_bet)

if __name__ == "__main__":
    for i in range(game_times):
        if balance < 0:
            print_state(vic_or_def, i)
            break;

        vic_or_def = game()

        print_state(vic_or_def, i)

        # マーチンゲール法
        if vic_or_def:
            min_bet = 1.0
        else:
            min_bet *= 2
            # min_bet += 1
```

# シミュレーション結果
縦軸が残高で、横軸がゲーム数(≒時間軸)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/91558/70508ee8-77c8-c6e0-9c2d-b4b96510aab9.png)
**図1. 初期の残高1,000,000(勝率0.475)でゲームを行った1**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/91558/d2cbd850-c163-da2a-1ae8-1ecf871cf8c5.png)
**図2. 初期の残高1,000,000(勝率0.475)でゲームを行った2**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/91558/365adb42-cb7c-adb0-946c-64062ecc8b00.png)
**図3. 初期の残高1,000,000(勝率0.5)でゲームを行った2**

**順調に勝てるが、最終的に負けが込み破たんする**

# まとめ
・確かに勝てることがわかった(途中まで)
・元手が**本当に大量に**ないと勝てない
・**実際に行うには机上の空論感が強い**

# 宣伝
フォローお願いします。:lifter_tone5:[@redshoga](https://twitter.com/redshoga)
CodeIQ 「進捗ないですマーク」問題の僕の回答

CodeIQ 「進捗ないですマーク」問題の僕の回答です。

Python の皮をかぶった SQL です。

 #sinchokuniq

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


def main():
    try:
        conn = sqlite3.connect(':memory:')
        strSQL = '''
SELECT
        'invalid'
    WHERE
        :1 & 1 = 0
UNION ALL
SELECT
    *
FROM
    (
WITH P(x,y) AS (
        WITH X(x) AS (
                SELECT 1 WHERE :1 & 1 = 1
                UNION ALL SELECT x + 1 FROM X WHERE x < :1)
        SELECT X,1 FROM X
        UNION ALL SELECT P.x,P.y + 1 FROM P WHERE y < :1)
    SELECT
        group_concat(
            CASE
                WHEN
                        x = 1
                        or x = :1
                        or x = y
                    THEN 'n'
                ELSE '.'
            END,'')
    FROM P
    GROUP BY y
);
'''
        n = int(input())
        lines = conn.execute(strSQL, (n,)).fetchall()
        for line in lines:
            print(line[0])
    finally:
        conn.close()


if __name__ == '__main__':
    main()
```
手動でMacのキーボード設定をおこなう

# 手動でMacのキーボード設定アシスタントを起動する

通常初めてWindowsキーボード（JIS配列）を接続した際には自動的にキーボード設定アシスタントが起動して配列設定などをおこなうことができる。

しかし一部Bluetoothキーボードなどを接続した際には自動的にキーボード設定アシスタントが起動しない場合がある。その場合には以下のパスにあるキーボード設定アシスタントを起動すれば設定することができる。
※v10.12(Sierra)環境

```
/system/Library/CoreServices/KeyboardSetupAssistant
```

※kzthrkさんにHigh Sierraにてご確認いただいた場合以下のような手順だったそうです。
>手元の環境はHigh Sierraですがパスとしては以下です。
>```
>/system/Library/CoreServices/KeyboardSetupAssistant.app
>```
>ターミナルからだとディレクトリになってしまうので、Finderでここへくるとアプリとして認識されていて起動できます。

以前使っていた環境ではキーボード設定画面から「キーボードの種類を変更」ボタンがあったが、なぜかボタンが表示されていなかったので焦ったがこれで解決した。

参考：
Appleフォーラム
https://discussionsjapan.apple.com/thread/10180884?start=0&tstart=0
1つの値を遅延評価してみよう

「Rubyで遅延評価」と言えば、`Enumerator::Lazy`をよく見かけますが、それ以外の手段を使うことになった話をしてみます。

# 遅延評価、とは

Rubyを含め多くの言語では、`a = foo(b)`のようにすれば、`foo(b)`の処理が行われて、その結果が`a`に代入される、という挙動になります。これを**先行評価**といいます。

一方で、Haskellでは、（そもそも変数は再代入不可、関数も結果は引数のみで一意に決まる、という特徴があるからこその話という面も大きいですが）実際に`a`の値が必要となるまで`foo(b)`の処理は行われません。これを**遅延評価**といいます。

## 遅延評価が便利な面
遅延評価にしてメリットがあることといえば、

* 無限リストや、ものすごく長いリストも簡便に扱える（`Enumerator::Lazy`もこれです）
* 引数に渡すために計算はしたけど、関数内で使わなかった…という余計な計算をカットできる（[竹内関数](https://ja.wikipedia.org/wiki/%E7%AB%B9%E5%86%85%E9%96%A2%E6%95%B0)では劇的に効果があることで有名です）
* 宣言と評価のタイミングをずらすことができる

# 今回使ったライブラリ

Rubyの場合、標準ライブラリについている[`Delegator`](https://docs.ruby-lang.org/ja/latest/class/Delegator.html)のように、ダックタイピングや`method_missing`を駆使すれば、「他のオブジェクトにメソッドを丸投げする」ようなオブジェクトは比較的簡単に作れます。

今回は、[bhuga/promising-future](https://github.com/bhuga/promising-future)を使ってみましたが、ソースコードはシンプルなものでした。

# 使うことになった場面

Railsで検索条件をハッシュ定数に入れて、あとでぶん回す、なんてことをやっていたのですが、条件値の1つとして`scope`を入れていたため、データベースのない環境下では定数定義の段階でDB接続を探してしまって死ぬ、という事態となってしまいました。

しかも、定数を使った構造は変えづらいという事情もあったので、遅延評価して「DBがなくても、実際に使わなければ問題なく通る」という形にしました。さっきのライブラリで`Kernel.#promise`が生えているので、こんな形となりました。

```rb
class SomeCalculator
  CALCULATIONS = {
    foo: promise { SomeModel.some_cond_scope }
  }
end
```

まあ、本来は定義ごと違う形にすべきなのかもしれませんが、こんな遅延評価の使い方もある、という話でした。
3GIM > GPS > 3GIMを採用


これは以下の記事で書いた事を実現するにあたり、どうやったらGPSリアルタイムトラッキングが可能かを最初に考察した記録です。

#### **[3GIMでGPS リアルタイムトラッキング](https://qiita.com/sugasaki/items/450845e8a5285a1bf6ab)**



## 3GIMとの出会い

情報を探し回っているうちに3GIMを発見

https://www.switch-science.com/catalog/3432/[3GIM V2\.2（3Gフレキアンテナ付き） \- スイッチサイエンス](https://www.switch-science.com/catalog/3432/)


すごく小さい。これは持ち運びにすごくいいのではないか！
<img src="https://qiita-image-store.s3.amazonaws.com/0/49910/6e8b2f21-1bca-43a8-433b-021134ecd060.png" width=250 />

3GIM+AruduinoでGPSをクラウドへ送信可能なようである
[第54回 SORACOM Air×3GIMによるArduinoの3G通信 その２〜Arduinoで3G通信をする方法 \| Device Plus \- デバプラ](http://deviceplus.jp/hobby/entry054/)

その後、調べていくと3GIMといい感じに組み合わさりケースまで付いているDENSUKEがあった。
[DENSUKE（伝助） for 3GIM v2\.0 \- スイッチサイエンス](https://www.switch-science.com/catalog/2814/)

<img src="https://qiita-image-store.s3.amazonaws.com/0/49910/8d0ae727-cae7-c104-d90a-81f2193599f2.png" width=250 />


これで完璧じゃないかと思ったが、対応バージョンが3GIM v2.0と書いてあったのが気になり
サイトへ問合せ開始。
が、DENSUKEのサイトは以下な感じで問合せはどこへ・・・
http://utec2.web.fc2.com/densuke_TOP.html


そこで3GIMのタブレインへ問合せた
[株式会社タブレイン \| 3GIM V2\.2](http://tabrain.jp/new/product/3GIM.html)

そこで帰っきた答えは「電話してくれ」
これが運命の分かれ道だった気がする。

## IoTabとの出会い

電話で話す前は、値段から3GIMは候補から外れかかっていた。
しかし電話で話してみると現在開発中の新しいボード（IoTab）があり、それだとすごく省電力で3GIM+IoTab+SIMだけでクラウドへデータをUPできるという。
なんか楽しそうに思えてきた。やっぱ楽しそうなのがいい。
詳しくはFacebookを見てくれとの事。
[タブレイン \- ホーム](https://www.facebook.com/tabrain/)

IoTabも確かに小さい。バッテリーは400mAhのリチウムポリマー
<img src="https://qiita-image-store.s3.amazonaws.com/0/49910/94aaf4af-9ed8-4395-f77b-be19ef857b8f.png" width=250 />

というわけで、3GIMはスイッチサイエンスへ、IoTabをタブレインへ注文した。
SIMはSORACOM SIMにした。
rails_adminがbundle installできない、又はrails g rails_admin:installできない時はsafe_yamlを入れる

##rails adminという管理者用のgemのインストールがうまくいかない。
今月、知り合いが３人くらいrails_adminがインストールできなくて全員おんなじ解決方法で行けたのでメモ。

↓ポイントはこれだけ↓
##gem safe_yamlを入れる
(stack over flowには0.6.3入れろって書いてあったけど、ruby2.2以上では1.0.4が必要)
http://ikm.hatenablog.jp/entry/2015/02/24/230812

~~~ruby:Gemfile
gem 'safe_yaml'
~~~

これだけで`bundle install`は成功するが、、以下の警告文が出る事がある。

何でもsafe_yamlってのはセキュリティをチェックしてくれるものらしいが、割と曖昧なやつでも警告を出してくるらしい。
詳しいことは以下ドキュメント参照。
https://github.com/dtao/safe_yaml

そんな時は以下の記述を書けば警告文は消すことができる。

~~~ruby:config/enviroments/development.rb
require 'safe_yaml'

# Do this before loading any YAML
SafeYAML::OPTIONS[:default_mode] = :safe

~~~
production.rbにはまだ書いたことないけど、必要なのかな？
こちら参照 - https://github.com/dtao/safe_yaml/issues/45
github - https://github.com/dtao/safe_yaml


##他に気にした方が良さそうなこと

・rails admin自体のバージョン（git hubからインストール）
http://linuxserver.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0/ruby/on-rails/rails-admin


これとかも参考になる？
https://stackoverflow.com/questions/23256575/installing-rails-admin-causes-safeyaml-warning
GPS > GPS リアルタイムトラッキング 方法の考察

これは以下の記事で書いた事を実現するにあたり、どうやったらGPSリアルタイムトラッキングが可能かを最初に考察した記録です。

**[3GIMでGPS リアルタイムトラッキング](https://qiita.com/sugasaki/items/450845e8a5285a1bf6ab)**


# はじめに

以下は2017年10月16～19日くらいに考えていた内容です。
やりたい事は明確でしたが、どのように実現したらよいのかがはっきりしておらず、方法を模索している段階です。
SORACOMのWio LTEはまだ発売される前でした。


##背景
やりたい事：３日間連続してGPSトラッキングしてデータをクラウドへ送信
遠隔地でGPS装置の場所を地図で確認（対象者は複数）

以下検討内容

# ハードウェア

## さくらのIoT + Arduino + GPS

* 安い（8000円）
* ArduinoやArduinoと接続するシールドを購入必要
* 物が大きくなりそうなのがネック


## 3GIM + densuke + Soracom

* 小さい、軽い、電力消費小さい
* GPS付
* 高い（27,000円）
* 他への流用がしにくい？

## micro:bit + 何か

* GPSは使えるが、送る手段がない
* micro:bit→iPhoneへBLE
* Bluetoothはよく切れるので心配
* 再接続がめんどい

## iPhone 単体

* みんな持ってる（将来の展開に強そう）
* 電池持つかが不安
* 実機有りだが普段使いしてるので、
　　実験と併用できるか？
* アプリを作り込む時間があるか？
* GPSの精度に疑問。
　　（自分の携帯だけかもしれないが精度悪い）
* 実機テストでやれば、ストアに上げなくてもOK?

## Windows Phone

* アプリが少ない分、消費電力が小さそう。
* C#で簡単に作れそうだ
* 実機テストでやれば、ストアに上げなくてもOK?

## Android
* ここもターゲットに入れるならXamarinで開発要？* * * 
* 実機もっていない
* 中古でやすいの転がってそう


# サーバーサイド

## Azure

* ハードからGPSデータ受信してDBに保存するだけ
* 無料枠でいけそうな気がする。
* レンタルサーバーだとレスポンス心配
* 汎用的に使えそうだ
* Azure IoTハブが使えそう？

## Map

* DBからデータ取得
* GoogleMap
* オープンストリートマップ
* Leaflet
3GIM > GPS > 3GIMでGPS リアルタイムトラッキング



まだ作成中です

# はじめに

あるイベントの為に、
リアルタイムで位置情報を取得しインターネット越しに誰でも地図で位置を確認できるようにしたい。
と思いたちGPSシステムを構築しました。これはその記録です。

実稼働は11月2日～4日。3日間稼働するを条件としました。

最終的には以下のようなものになりました。
<img src='https://qiita-image-store.s3.amazonaws.com/0/49910/1f54373b-26c0-382c-c1f5-385cad846424.png' width=250px /><img src='https://qiita-image-store.s3.amazonaws.com/0/49910/fc79a174-396f-7693-87e5-96d733c3239a.png' width=230px />

## システム構想の遷移

### ハードの選定

## 1.  リアルタイムトラッキング 方法の考察
[GPS リアルタイムトラッキング 方法の考察](https://qiita.com/sugasaki/items/2e769c5c5a2ee4b9df94)

2017年10月16～19日くらいに考えていた事です。
やりたい事は明確でしたが、思いつく選択肢が多く手段をいろいろ試行錯誤している段階です。

この時はまだ3GIM以外を考えていました。
SORACOMのWio LTEが発表される前の段階でした。



## 2. ハードの決定 3GIMを採用
上記を実現するにあたりハードを考察し、結果3GIMに決定しました。
[3GIM > GPS > 3GIMを採用](https://qiita.com/sugasaki/items/8cb941672436e3d203b4)



## 3. 3GIMの電源確保の方法考察
[3GIM > GPS > 3GIMの電源確保の方法考察 \- Qiita](https://qiita.com/sugasaki/items/9ed73ab49b31b3c3b5b6)

IoTといえば屋外で使うことが多いと思います。
最初に悩むのは「電源どうしよう？」だと思います。
同じように悩み電源についてあれこれ考えました。


## 4. 3GIMの組み立て
3GIMは様々な環境での利用を想定しているので基盤にピンヘッダが付いていません。ピンヘッダをハンダつけして組み立てました。
[3GIM > 3GIMの組み立て \- Qiita](https://qiita.com/sugasaki/items/166eebd5f850f04dd80d)

## 5. Arduino IDEのインストール
3GIMを制御するプログラムを作成する環境の構築です。

[3GIM > Arduino IDEのインストール（IoTab版） \- Qiita](https://qiita.com/sugasaki/items/e6db62d7b1e07d8a982d)

## 6. 3GIMの初期設定
環境が構築できたら3GIMの初期設定を行います。

[3GIMの初期設定 \- Qiita](https://qiita.com/sugasaki/items/a8e2998cbb25f766a0cc)

## 7. 3GIMのケース
どんなケースに収めたら問題なく使えるか？考えました。
[3GIM > 3GIMのケース \- Qiita](https://qiita.com/sugasaki/items/ec86bf925618c49f3d66)

## 8. サーバー側処理の考察
サーバー側について考えました
[3GIM > 3GIM サーバー側 \- Qiita](https://qiita.com/sugasaki/items/a70f6a9f5a0400fbdbbc)

## 付録

[3GIM > 3GIM コマンド集 \- Qiita](https://qiita.com/sugasaki/items/364abde8962381719a2f)


### メモ
3GIMの動作は4.2V～3.5Vの間がよい
3.5ｖを下回りそうになったら電池の換え時
【ぶっちゃけAndroidアプリ開発】Androidの画面サイズ

Androidアプリを開発する時、どんな画面サイズを想定すべきでしょうか。
# 結論
360x640dpで作成しましょう。
#解説
Androidは各端末メーカーが画面解像度（横×縦のピクセル数）を自由に決めています。
アプリ開発する時は端末依存の解像度をなるべく意識しなくていいようにdpという単位が設けられていますので、端末の解像度の事は忘れましょう。アプリ開発する時はdpを使ってください。
dp解像度もいくつかのバリエーションがあるのですが、だいたい360x640dpで作っておけば大丈夫です。
これより低い解像度のものは画面に表示し切れませんが、古い端末です。（私見）
これより高い解像度のものは画面に余白が生まれてしまいますが、そんなに酷くありません。
#360x640dpで作成した例
Googleが言う純粋Android端末であるNexusで、AndroidStudioのレイアウトエディタの表示を比較してみます。
Activityに配置した部品は以下の通り。
- TextView Width:360x240dp
- TextView 320x100dp
- Button 120x48dp
###Galaxy Nexusで表示
発売:2011年11月
端末解像度:720×1280ピクセル
dp解像度:360x640dp
※dp解像度が合っているのでぴったりです。
![GalaxyNexus.png](https://qiita-image-store.s3.amazonaws.com/0/142654/f78c87bb-cddf-848e-d9f3-a3847b1f551d.png)
###Nexus6で表示
発売:2014年11月
端末解像度:1440x2560ピクセル
dp解像度:410x730dp
※dp解像度が高いので余白が生まれます。
![Nexus6.png](https://qiita-image-store.s3.amazonaws.com/0/142654/8ad45c0c-721a-5558-81e9-cb2b04a052da.png)
###Nexus Sで表示
発売:2010年12月
端末解像度:840x480ピクセル
dp解像度:320x534dp
※dp解像度が低いので表示が切れてしまいます。
![Nexus_S.png](https://qiita-image-store.s3.amazonaws.com/0/142654/f9fdfed7-4251-af13-34f2-5c98f41a1c24.png)
#その他
- タブレット対応するためには不十分です。タブレット対応する方法は別途記事にする予定です。
- 新しい端末で綺麗に表示したい時は、画像リソースなどをdpiごとに準備しましょう。
　　

---
ぶっちゃけAndroidアプリ開発は、アプリ開発にあたってとりあえず知っておくべきことをズバリ書きます。例外はありますのでご了承ください。
Unity上で物体が衝突したら爆発する→消滅の処理

##爆発は男のロマン

上記のとおりですが爆弾の処理はゲームオーバーや攻撃エフェクトとしては必須ですよねぇ(・∀・)

今回は物体が衝突したら爆発して、消失する処理を作ります
爆発のエフェクトは便利なAssetがあったのでそちらを使います（以下Assetへのリンク）
（[Simple Explosion](https://www.assetstore.unity3d.com/jp/#!/content/76511)）
実はprice:0 , explosion　で検索したら一発目にでてきたので使いました(；´∀｀)

#衝突検知からの爆発

上記のAssetを使用する場合の処理の流れは以下のようになります

衝突検知　→　消失　→　爆発エフェクトの配置

のようになります(・∀・)
爆発エフェクトの配置とありますが、上記Assetには爆発エフェクトごとprefab化してくれてます
今回は以下の私の記事で作った、万有引力のものを使って実装したのでそちらのコードを載せます

[惑星から万有引力を受ける物体をUnity上で実装](https://qiita.com/kugipanti/items/ad538a937118822c773c)

衝突して消失するオブジェクトの方へ以下のコードをアタッチしました

```C#:explosion.cs
public class rocketPower : MonoBehaviour {
        Rigidbody rb;
        public GameObject explode;//explodeにはunity上でprefabを関連付けます
	void Start () {
        rb = this.GetComponent<Rigidbody>(); //衝突時にオブジェクトを消す際に使用
    }
	// Update is called once per frame
	void Update () {
    }

    void OnCollisionEnter(Collision collision) //衝突時の処理
    {
        //Destroy(this.gameObject);
        if(collision.gameObject.tag == "Planet") 
        //タグで限定（他のオブジェクトに衝突した場合は呼び出さない
        {
            rb.isKinematic = true; //位置を固定
            this.transform.localScale = Vector3.zero; //みえない大きさにする
            Instantiate(explode, this.transform.position, Quaternion.identity);
            //ぶつかった位置にexplodeというprefabを配置する
        }
    }
}
```
タグのif文を書いたことで他のものにぶつかっても爆発しなくなります
isKineticはそこで固定する意味があります
destroyを使うことも考えたのですが、今回ロケットの位置をカメラが参照していたのでバグが起こったので今回はコードにあるとおり、スケールで縮小とiskineticをオンにすることで解決しました
普通の物体であれば、Destroyだけでよいはずです

以下のようになりました
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/B-7CDNtnbe4/0.jpg)](http://www.youtube.com/watch?v=B-7CDNtnbe4)
(画像クリックで再生します)

ちなみに、タグのおかげですが、以下のように間に関係ない壁を配置すると爆発しません
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/6OgnkVDOySY/0.jpg)](http://www.youtube.com/watch?v=6OgnkVDOySY)
(画像クリックで再生します)


記事をお読みくださってありがとうございました
WP_Queryの使い方（パラメーター）

意図した投稿データを出力するための便利タグであるWP_Queryの使い方とパラメーターの使い方を紹介します。
以下では今まで使ったものを記述していきます。

## 投稿タイプを指定する
・投稿タイプ名には任意の文字を入力してください。
・post_type指定をarrayにすることで複数設定をすることができます。

```ruby:php
$args = array( 
    'post_type' => array( 
            '投稿タイプ名'
            ),//投稿タイプ名（複数入力可能）
    'posts_per_page' => 6   //投稿数
	);
	
	$the_query = new WP_Query( $args );
	
     if ($the_query->have_posts()) : 
     $count = 1;
     while ($the_query->have_posts()) : 
         $the_query->the_post();

	   the_content();

     $count++;
     endwhile;
  endif;
wp_reset_postdata();
```

## タクソノミーのタームを指定する
```ruby:php
$args = array( 
'tax_query' => array(
   'relation' => 'OR',     
	array(
          'taxonomy' => 'タクソノミー名',
           'terms' => array( 'ターム名その１', 'ターム名その２'),
           'field' => 'slug',
           'operator' => 'IN',
		),
	   ),
	'posts_per_page' => 4,
	);
	$the_query = new WP_Query( $args);
        if ($the_query->have_posts()) : 
           while ($the_query->have_posts()) : 
             $the_query->the_post();

	       the_content();
           endwhile;
    endif;
wp_reset_postdata();
```


## タクソノミーの指定タームを除外する
```ruby:php
$args = array( 
 	'post_type' => '投稿タイプ名',
	'tax_query' => array(
   		'relation' => 'AND',
    		array(
          		'taxonomy' => 'タクソノミー名',
           		'terms' => array('ターム名その１'),
           		'field' => 'slug',
           		'operator' => 'NOT IN',
        	),
       	),
    'posts_per_page' => 4,
    );
    $the_query = new WP_Query( $args);
        if ($the_query->have_posts()) : 
           while ($the_query->have_posts()) : 
             $the_query->the_post();

           the_title();

           endwhile;
    endif;
wp_reset_postdata();
```

参考サイト
[WP_Queryの使い方をPHPコードにまとめた便利なコード・スニペット](http://notnil-creative.com/blog/archives/1288)
Gitコマンド/GitHub備忘録

個人用の備忘録です。自分がよく使うコマンドやTipsをまとめており、適宜更新していく予定です。

##始める前に
これは日本語の記事ではあまり書かれていないことですが、大学のEメールアドレスを持っていれば、[Student developer pack](https://education.github.com/pack)を使うことによって、通常毎月€7掛かるプライベートリポジトリを無料で持つことができます。大学のEメールアドレスをPersonal settingsのEmailsに登録しましょう。

##初期設定
リモートリポジトリからのクローン　`git clone $URL`
リポジトリの作成　`git init`
ssh公開鍵設定　([参考URL](https://qiita.com/htano/items/d154d7a207ecdb97d535))
[GitHubのssh公開鍵設定](https://github.com/settings/keys)に自分のid_rsa.pubファイルの中身を加筆します。
クローン時に以下のようなエラーが出ることがある場合は、公開鍵の設定が必要です。

```
Permission denied (publickey).
fatal: Could not read from remote repository.
```
設定の確認　`git config --list`



##ファイルの取扱
ファイル追加

```
git add ${ファイル名}
git commit -m '${変更内容}'
git push origin ${ブランチ名}
```

gitで管理しないファイル名一覧を`.gitignore`に記載。

gitでは`mv`ではなく`git mv`を使う。

##作業の取り消し
git addによるステージングを取り消し　`git reset HEAD $ファイル名`
一つ前のコミットの取り消し　`git reset --soft HEAD^`
`--soft`オプションはファイルを残す場合。残さない場合は`--hard`

##ブランチ操作
ブランチ一覧表示　`git branch`
ブランチの作成　`git branch ${ブランチ名}`
ブランチの削除　`git branch -d ${ブランチ名}`
ブランチの切替　`git checkout ${ブランチ名}`
ブランチ名を指定してクローン　`git clone -b ${ブランチ名}`

##共同モデル開発におけるGitHubの利用例
GitHub を用いた共同モデル開発ワークフローの一例です。 ([参考URL](https://gist.github.com/mvitocruz/946941))

1. リモートリポジトリの内容のマージを行わずに、最新の情報を確認する。
 (正確には、リモートのコピーをローカルにダウンロード)
`git fetch`

2. 一時作業用のブランチを作成。`-b`オプションによりチェックアウトも同時に実行。
`git checkout -b ${ブランチ名} origin/master`

3. 作成したブランチ内で作業をしコミット。

4. 再度アップデート
`git pull --rebase`

5. 作業中のブランチをpush
`git push origin ${ブランチ名}`

6. GitHub上でPull requestをする。Reviewerに共同作業者を追加し、承認を待つ。

7. masterに送る (Pull requestのみで)
`git push origin ${ブランチ名}:master`
別ホストで動作しているPostgreSQLにSSHトンネルで接続する方法

# 目的/条件
- PostgreSQLベースのWebアプリケーション（Java,PHP,Perl etc）のDBを分離して別ホストで運用したい。
- 接続はSSHトンネル（ポートフォワーディング）で行う
- OS再起動時にSSHトンネルを自動的に開始したい
- アプリケーションのソースコードは一切変更したくない
 - アプリケーションからlocalhostのポート5432にアクセスしたら別ホストのPostgreSQLにつながってほしい

# 条件
- アプリケーションサーバのホスト名を app.mydomain.com とする
- DBサーバのホスト名を db.mydomain.com とする
- アプリケーションサーバからDBサーバにSSHで接続可能にfirewallやtcp-wrapperで設定されている
- アプリケーションサーバではLinuxベースでsystemdでdaemon等の起動管理をしている

# 手順１：SSHトンネルの用意
- アプリケーションサーバの任意のユーザ（user1@appとする）から、DBサーバの任意のユーザ（user2@dbとする）にパスワード無しでSSHログインできるようにしておく。user1@appの公開鍵をuser2@dbの./ssh/authoriezed_keysに登録すればよい
 - user1@app, user2@db 共に、アプリケーション実行やDBアクセスの権限等は不必要で、全く無関係のユーザで構わない。
- DBサーバにPostgreSQLをインストールし、目的のアプリケーションのDBを動作させておく。

# 手順２：アプリケーションサーバ側のPostgreSQLの停止
- PostgreSQLを停止するか、ポートを変更して起動運用する。

# 手順３：SSHトンネル接続を自動実行する設定
- 以下のファイルをrootで作る。ファイル名のpgtunnelの部分は適宜変更してよい。

```bash:/etc/systemd/system/pgtunnel.service
[Unit]
Description = PostgreSQL ssh tunnlel to db.mydomain
After=network.target sshd.service

[Service]
ExecStart=/usr/bin/ssh -f -N -L 5432:db.mydomain:5432 user2@db.mydomain
Type=forking
User=appuser

[Install]
WantedBy = multi-user.target

```
- 以下のコマンドで起動してみる。うまくいったらOS再起動して再確認する。 

```bash
systemctl daemon-reload
systemctl enable pgtunnel.service
systemctl start pgtunnlen.service
```

以上で完了です
JQueryでformの内容を受け取る

## テーブル形式で行ごとにsubmit
例えば下記のような形式で行単位でsubmitできるようにしたい場合、
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/86958/c81fb05e-05ba-da55-7cc7-5abe331c4945.png)

こんな感じになるでしょうか。

```html:html
<!-- 行数分繰り返し -->
<tr>
    <form>
        <td>
            <input type="hidden" name="key" value="001" />
            001
        </td>
        <td style="position: relative;"><!-- textboxをセルいっぱいにするstyle -->
            <input type="text" name="val" value="hoge" style="width: 100%; box-sizing: border-box" />
        </td>
        <td>
            <input type="button" value="更新" class="update" />
        </td>
    </form>
</tr>
```

行ごとにformをつくって、ボタンを押したらその行のデータを拾いたい、というときは・・・

## form.serialize()
script側で`form.serialize()`でフォームデータを丸ごと受け取れます。

```js:script
$(function(){
	$('.update').click(function(){
		var data = $(this.form).serialize();
		...
	});
});
```

中身は`key=001&val=hoge`という形になっており、そのままajaxのPOSTパラメータとして渡せます。

```js:script
var d = $(this.form).serialize();
$.ajax({
	type: "post",
	url: "./hogehoge.php",
	data: d,
}).fail(function(){
	//...
}).done(function(data){
	//...
});
```

## 参考
[ajaxの際に form.serialize で一括送信できる件](http://nkawamura.hatenablog.com/entry/2013/11/12/204147)
jQueryを使い、<ul>内のn番目〜n番目の<li>にclassを付与する

とある案件で、件名のようなピンポイントな事が出来たら便利だなと考え、方法を調べてみました。簡単かと思ったら、方法を書いてあるページがなかなか見つからず、苦労しました。

##やりたいこと
```html:test.html
<ul class="list">
 <li>リスト1</li>
 <li>リスト2</li>
 <li>リスト3</li>
 <li>リスト4</li>
 <li>リスト5</li>
 <li>リスト6</li>
 <li>リスト7</li>
 <li>リスト8</li>
 <li>リスト9</li>
 <li>リスト10</li>
 <li>リスト11</li>
 <li>リスト12</li>
</ul>
```
上記のHTMLに、jQueryを使って

```html:test.html
<ul class="list">
 <li class="group1">リスト1</li>
 <li class="group1">リスト2</li>
 <li class="group1">リスト3</li>
 <li class="group1">リスト4</li>
 <li class="group2">リスト5</li>
 <li class="group2">リスト6</li>
 <li class="group2">リスト7</li>
 <li class="group2">リスト8</li>
 <li class="group3">リスト9</li>
 <li class="group3">リスト10</li>
 <li class="group3">リスト11</li>
 <li class="group3">リスト12</li>
</ul>
```
のように、

- 1〜4番目のliには、class"group1"を付与
- 5〜8番目のliには、class"group2"を付与
- 9〜12番目のliには、class"group3"を付与

##試行錯誤の末、これで行けました

```html:test.html
<script type="text/javascript">
// ▼1〜4番目のliに、class"group1"を付与
$("ul.list li:nth-child(-n+4)").addClass("group1");
// ▼5〜8番目のliに、class"group2"を付与
$("ul.list li:nth-child(n+5):nth-child(-n+8)").addClass("group2");
// ▼9〜12番目のliに、class"group3"を付与
$("ul.list li:nth-child(n+9):nth-child(-n+12)").addClass("group3");
</script>
```
##コピペ用

```html:test.html
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>test</title>
<style>
.group1{color: blue;}
.group2{color: red;}
.group3{color: green;}
</style>
</head>

<body>
<ul class="list">
 <li>リスト1</li>
 <li>リスト2</li>
 <li>リスト3</li>
 <li>リスト4</li>
 <li>リスト5</li>
 <li>リスト6</li>
 <li>リスト7</li>
 <li>リスト8</li>
 <li>リスト9</li>
 <li>リスト10</li>
 <li>リスト11</li>
 <li>リスト12</li>
</ul>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script type="text/javascript">
// ▼1〜4番目のliに、class"group1"を付与
$("ul.list li:nth-child(-n+4)").addClass("group1");
// ▼5〜8番目のliに、class"group2"を付与
$("ul.list li:nth-child(n+5):nth-child(-n+8)").addClass("group2");
// ▼9〜12番目のliに、class"group3"を付与
$("ul.list li:nth-child(n+9):nth-child(-n+12)").addClass("group3");
</script>
</body>
</html>
```


##参考記事
下記ページの8番目の項目が参考になりました。
[CSSの:nth-childと:nth-last-child擬似クラスの使用例 | NxWorld](https://www.nxworld.net/tips/css-nth-child-and-nth-last-child.html)
[Firefox 57+] Roomy Bookmarks Toolbar が動かなくなったんですけど！

## Firefox Quantum がリリースされましたね！
今まで数々の反対にあい先延ばしにされてきた、WebExtensionsでない旧形式アドオンのサポート終了が、ついに強行されました。
皆様におかれましては、数々のアドオンが無効化されChromeへの移行を考え始めていることと思います。

## Roomy Bookmarks Toolbar
ぼくが特に困ったのはこのアドオンでした。
機能としてはブックマークツールバーのラベルが非表示にできたり、ブックマークを2段にできたりするだけのシンプルなものでしたが、いざなくなってみるととても不便でした。

![キャプチャ1.PNG](https://qiita-image-store.s3.amazonaws.com/0/111100/acb547d3-5d40-e33a-2e01-50bccc3df5f3.png)
普段は小さくしておいて

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/111100/46377492-4e1b-a200-c04c-72ae3815694b.png)
マウスオーバーでラベルを表示、とかもできたりします。

そして、どうやらWebExtensionsには対応しない様子。

## userChrome.css で対処しよう

Firefoxでは、userChrome.css なるファイルを編集することで外観を好みにカスタマイズできるとのこと。
ということで、これを編集することでお茶を濁すことにしたのでした。
ファイルの配置場所はおなじみProfile下です。
`C:\Users\%USERNAME%\AppData\Roaming\Mozilla\Firefox\Profiles\{ランダム文字列ファイル}`
分からんという方は、Firefoxのメニューから [ヘルプ]>[トラブルシューティング情報]をクリックし、[アプリケーション基本情報]にある[プロファイルフォルダー]の[フォルダを開く]をクリックしましょう。

プロファイルフォルダを開いたら、`chrome`フォルダに移動し、`userChrome.css` ファイルを以下の内容で作成して、Firefoxを再起動します。

```css
/* https://www.reddit.com/r/firefox/comments/72qkvt/any_replacement_for_roomy_bookmarks_toolbar_i/ */

/* --- Made by Trustadz --- */
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); /* only needed once in userChrome.css */

.bookmark-item{
    margin-left: 0 !important;
    margin-right: 0 !important;

    /* --- アイコン間の距離を大きくしたい場合は数値を変更する --- */
    padding-right: 0 !important;
    padding-left: 0 !important;
}

toolbarbutton.bookmark-item .toolbarbutton-text{
    display: none !important;
}

/* --- [1] hoverでラベルを表示しない場合は [/1] までの行を消す --- */
toolbarbutton.bookmark-item:hover:not(.subviewbutton):not([disabled="true"]):not([open]) .toolbarbutton-text{
    display: -moz-box !important;
}
/* --- [/1] --- */

/* --- [2] フォルダ名をブックマークツールバーに表示しない場合は [/2] までの行を消す --- */
toolbarbutton.bookmark-item[type="menu"]{
    margin-right: .5em !important
}
toolbarbutton.bookmark-item[type="menu"] .toolbarbutton-text{
    display: -moz-box !important;
    margin-right: .5em !important;
}
/* --- [/2] --- */

/* --- [3] ブックマークツールバーの半透明を無効にするには [/3] までの行を消す --- */
#PlacesToolbarItems{
    /* --- ブックマークの透明度 --- */
    opacity: 0.3;

    /* --- 好みに合わせて値を変更する --- */
    transition-delay: 3s; /* 透明へ戻るまでの時間 */
    transition-duration: .5s; /* エフェクトにかかる時間 */
}

#PlacesToolbarItems:hover{ /* ここは変えないこと */
    transition-delay: 0s;
    opacity: 1;
}
/* --- [/3] --- */
```

2段組みとかはまだですが、とりあえず急はしのげました。

### 情報元
https://www.reddit.com/r/firefox/comments/72qkvt/any_replacement_for_roomy_bookmarks_toolbar_i/
プログラミング未経験者がエンジニア目指す（その６）

# N予備校の章
●第1章　07.JavaScriptで論理を扱う
## はじめに
●論理と聞いただけで？がたくさん浮かび、この単元を最後まで進めるのに3時間かかった。
## 概要
●論理演算子、比較演算子について学ぶ
●if文について学ぶ
## 分かったこと
●論理演算子＝言葉のあいまいさをなくすための手段。
●比較演算子＝「以上」「より小さい」とか使う時の手段。
●if文＝英語のifとは考え方が違う。「場合分け」するときに使う手段。
## 疑問点
●論理を楽しく覚える方法ってあるのかな。
## 感想
●論理演算子と比較演算子、よく読めばまったく違う意味なのに、同じ意味のものだと思い終始混乱してた。
●どうしても英語のifが頭から離れなかった。
## 終わりに
●単元最後まで進めたけど、理解度がかなり低い気がするので復習しなくちゃ。
GOGO LLC の勝手アカウント作成の件

#GOGO LLC の勝手アカウントの件

## メール
GOGOからいきなり登録済メールが届いた。

<img src=https://qiita-image-store.s3.amazonaws.com/0/49910/89f16246-5fbd-f6df-3d2c-bb731715f04c.png width=200px />



無意識に登録したっけ？と思って、GOGOサイトをいちおう確認
http://www.gogoair.com/jp/


## ログイン画面
登録した覚えがないので当然ログインできない。

<img src=https://qiita-image-store.s3.amazonaws.com/0/49910/e02e7088-3136-c110-05ed-52d5909c8ac2.png width=500px />


パスワードをお忘れですか？　があったのでお忘れですの処理を進める。

## パスワードをお忘れですか画面

お忘れ処理を開始する前に「秘密の質問」を入れとな。
<img src=https://qiita-image-store.s3.amazonaws.com/0/49910/d037a93f-0f98-606f-802d-29442febd10e.png width=500px />

いや、登録した覚えないから秘密の質問も分からないし。詰んだか・・・

右側をちらっと目を移すとチャットでお答えしますの文字が。

<img src=https://qiita-image-store.s3.amazonaws.com/0/49910/73a1c9b0-d61e-f1ba-65b0-e712cd640f2d.png width=500px />


ダメ元で問い合わせる。

<img src=https://qiita-image-store.s3.amazonaws.com/0/49910/fa3ed374-5d45-a231-b4b3-97f92ec4dee5.png width=500px />


## 確認結果

意外とサポートの調査は早く、
誰かが勝手にメールアドレスを拝借した模様。

飛行機機内でネット使用前にメールアドレスを登録するしくみらしい。（紙か電子かは不明）
自分のメールアドレスで知らぬ（知ってる人かも）誰かが存分にログインしてたかと思うとぞっとする。

もしサポートがなかったら、のっとり放題ですね。と苦言を伝えた。

GOGOさん、メールアドレス保持者の同意無しにアカウント作るのやめてくれ。

<img src=https://qiita-image-store.s3.amazonaws.com/0/49910/2b4694d6-bce0-33d9-5b08-bda687cbd7c1.png width=500px />


どうかこの叫びがGOGOの元へ届きますように。
梅キャンIoT勉強会について

#はじめに
[梅キャンIoT勉強会](https://studygroup-umecanoit.connpass.com/)とは、大阪工業大学梅田キャンパスの学生数人が主催する[LT大会](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%88%E3%83%8B%E3%83%B3%E3%82%B0%E3%83%88%E3%83%BC%E3%82%AF)です。テーマは主に**IoT**ですが、ここで述べるIoTには**Internet or Things**の意味も含まれています。要は**技術っぽい話なら何でもあり**な感じの勉強会ですね。今回はこの**梅キャンIoT勉強会**を開催した経緯についてお話しします。事前に注意してほしいのは、本ページは私の考えや意見を只々ずっと述べるだけの内容がほとんどです。

#勉強会について
ここで私が述べる勉強会について事前にご説明いたします。本ページで語る勉強会は、**所謂意識高い系(笑)が開くような勉強会とは名ばかりの飲み会の集まり**とは当然違います（別にそのような集まりを批判するつもりは全くありませんが）。私が語りたいのは**技術勉強会**についてです。でも技術勉強会といっても基本はIT勉強会になってしまいますね。
[技術勉強会について説明する記事](https://blog.codecamp.jp/study-group/)は沢山あるのでそこに説明は投げておきます。[もう少し参加者目線で述べている記事](https://qiita.com/nx_r0b/items/dfa49fd7f2417e3641d2)もあるのでご覧ください。またここで私自身も参加者の目線で勉強会について分類すると主に

- ビジネスチャンス系
- 交流を楽しむ系

の２つに分けられるかなと思います。両者とも知見を共有したいという点では同じですが、そこから先にビジネスを考えているか否かで勉強会の参加者層や雰囲気がかなり違うなという印象を感じます。

#関西は楽しむ系の技術勉強会が少ない
技術系の勉強会を探すとき私は主に[connpass](https://connpass.com)を使うのですが、ここでセミナーとか勉強会を調べて出てくるもののほとんどが東京で開催してるものなんですよね。関西でもいくつかのコミュニティが勉強会やワークショップを開催してはいますが、やはりちょっと下火なイメージを感じてしまいます。もちろんそういった状況を打破しようと活動されている関西のコミュニティもあります。しかしその所謂活発なコミュニティは**ベンチャー企業系やビジネス**に寄ったもので、技術的な交流を楽しむことがメインの**ファンクラブ**的な集まりというのはいまいち盛り上がりに欠けるなあという印象です。それで何を言いたいのかというと、関西の勉強会コミュニティって新しく技術の勉強をしたい初心者や、技術の知識はそこそこあるけど起業やビジネスを考えているほどガチでは無い人たち（主に学生）が気兼ねなく参加できるものがかなり少ないなと常日頃感じています。
もちろんビジネス目的のコミュニティが盛り上がるのは非常に良いことだと思います。ただ私たち非ビジネス目的の人達が交流を楽しめる勉強会というのももう少しあってもいいのではと思います。こういった活動も東京ではけっこう活発に行われているので羨ましいなと感じます。

#関西で新たな勉強会を開きたい
ここから梅キャンIoT勉強会を開催させた話をしていきます。まず梅キャンIoT勉強会が最初に開催されたのは2017年の4月です。またこの勉強会を開こうと企画し始めたのは3月中旬あたりだと思います。
このきっかけになったのは2017年4月から始まった大阪工業大学の梅田キャンパスでした。学科の関係で私は大学院進学からこの新キャンパスに移ることになったのですが、せっかく新キャンパスの住人になったのだから何か新しいことを始めたいなと研究室の先輩と話していました。
また、新しく勉強会を開くのにネックとなるのが開催場所と人数集めですが、幸い我々は学生だったので学生権限を使って学内に開催場所を確保できました。また梅田キャンパスはほぼ大阪駅にあるので、集客もやりやすい環境でした。

#なぜIoTなのか
さて、ここまででこの**勉強会のタイトルにIoTがある理由**については一切触れておりませんでした。ここからはそれについて説明します。
これは私自身のIoT観の話になるのですが、IoTはすごくあやふやで定義がなく、多くの技術の集合体である。またソフト・ハード関係なくどんな技術も間接的にIoTに関係してくると思っています。私はIoTを特別新しい技術体系とは思っておらず、既存のあらゆる技術をまとめた概念のようなものと捉えています。例え**インターネットに繋がってないモノ**であろうが、**モノに繋がってないインターネット**であろうが何処か間接的にはIoTに関係してくると思います。
また、こういった技術勉強会はソフト系の発表がほとんどで私のようなハード系から来た人間としては少し寂しいなという感想を抱いております。
そういった意図を含めた上で私は**Internet or Things**と紹介ページに書かせていただいてます。まあ、私自身がハードとソフトまんべんなく学ぶことが好きだという個人的理由も含んでおりますが。

#おわりに
ここまで私の拙い長文を読んでくださってありがとうございます。結論として私が目指す梅キャンIoTというのは、**交流を楽しむための勉強会**です。やっぱりいろんな人と交流すると自分の勉強へのモチベーションにもなりますし、独自の調査では得られなかった知見を新たに得ることも出来るわけです。
そんなこんなで、梅キャンIoT勉強会は毎月末の19:00~20:00に大阪工業大学梅田キャンパスにて開催しております。
こういったコミュニティ活動があるということだけでも知っていただくと幸いです。
FireBase Hostingを始めよう

まぁ、URL転載なんだが、躓いたところを共有しておく。

# firebase Hostingの使用方法
https://dev.classmethod.jp/smartphone/firebase-using-hosting-service/
このサイトが分かりやすい。

## しかし、以下の注意点があった。
- 「firebase init」で作成される「firebase.json」の中身が空になる。（だった。）
以下のコードを張り付けると動く。（細かい設定はこちらを参照。）

```json
{
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ]
  }
}
```

他のサイトのサンプルでは、"public": "app"となっている。試していないけど、次の注意点の「public」フォルダを「app」フォルダにすれば動き出す。（試してはいない。どなたか報告していただきたいです）

- 「firebase init」を実行してもフォルダ構成まで自動で作成してくれない。（くれなかった。）
firebase initを実行したフォルダの配下に「public」フォルダを作成し、そこに静的アセットを配置すること。
Windows Subsystem for Linux正式版になったので使ってみたよ

# 祝! Windows Subsystem for Linux正式版!

Windowsの大型アップデータとFall Create Updateが降ってきて、Windows Subsystem for Linuxのベータが外れたので開発環境を移していく。


# まずはWindows Subsystem for Linuxを入れる

詳しいことは[Build Insider](http://www.buildinsider.net/enterprise/wsl/01)が詳しく書いてくれているのでそれに従います。


### 1.Windows Subsystem for Linuxのコアとなる部分をインストール

```powershell:管理者権限のPowerShellで以下を実行する
	
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
```

実行が終わったら一旦、再起動する。


### 2.好きなLinuxディストリビューションをStoreからダウンロード
`Microsoft Store`を開いて`linux`などを検索して、インストールする。

![cap.PNG](https://qiita-image-store.s3.amazonaws.com/0/90529/c2982e02-979a-ccce-321f-baf6391094cb.png)

インストールが終わったら、再起動する。

### 3.インストールしたディストリビューションを起動して初期化しておく

今回は、Ubuntuを導入した。スタートメニューの中に`Ubuntu`があるので立ち上げると自動で初期化が始まる。
(なぜか自分の環境では画面に変化がなくEnterを押すと完了画面が表示された。)

**これで、使用できるようになりました!**

## ちょっと使ってみる


特につまるところありませんでしたね。
試しに、SSHコマンドで他のサーバに入ってみましたがすんなり入れました。

PathはLinuxのパスになっており、Windowsの`C`ドライブは`/mnt/c`に格納されており、読み替える必要があります。

#### もうちょい本格的に

普段は、Nodeで利用しているので導入して実行して見ましょう。
npmを叩くと、はい動きませんね！(体験には個人差があります)

node_modulesにインストールされているのがwindowsようだからLinuxに入れ替える必要があります。
今ある、node_modulesフォルダを削除して、`npm i`を叩きます。
そうすれば、動きますね。


# おまけ　ConEmuも導入する

これでも十分に使えるのですが、ConEmuというTerminalを導入します。
タブ機能などが使えます!
環境を移し終わるまでは今までの環境も使いたいので、タブ機能が役立ちますね。


ConEmu:https://conemu.github.io/

インストールすると、`Windows Subsystem for Linux`を認識しているので、一覧から選択するだけで使用できます！

## 作業パスで開くようにする

ConEmuを作業パスで開いたり、登録した作業パスでタブを開くことができます。

### 作業パスを登録してタブで開く

1."三"マークのメニューから "Settings"を選択し設定画面を開きます
2. Startup -> Tasksを開く
3. "+"マークで項目を追加する(空の項目が追加される)
4. Bashを参考に空き項目を埋める
　　名前欄は、`::`が区切り文字で `グループ名::個別の名前`のように設定できる
5.パスの欄に`-dir "C:\Users\hoge"`のように作業ディレクトリまでのパスを追加する

![2017-11-17 18_55_32-Settings [xml] ConEmu 161206 [64] {Stable}.png](https://qiita-image-store.s3.amazonaws.com/0/90529/0783e386-106a-8f54-7d03-90c33d1be521.png)


登録したら、"Save setting"で設定を閉じる。
これで、緑の"+"ボタンでプロジェクトのタブを開く事ができる

### 起動時に開くterminalの指定

設定画面の"Startup"で、
Specified name task で、上で登録したtaskを選択すればOkです。

**おしまい**
SourceTree Mac版で複数のリポジトリをタブで切り替える方法

Windows版だと複数のリポジトリをタブで切り替えられるのにMac版だとできない！と思っていたらいつの間にかできるようになっていた。
もしかすると僕が気づいていなかっただけで昔からできていたのかもしれない。

## やり方

### 複数のリポジトリを開く

<img width="1152" alt="スクリーンショット 2017-11-17 19.04.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/16060/07e7a517-b00e-5ac9-3df7-8325b837c809.png">

### ウインドウメニューから「すべてのウインドウを結合

<img width="641" alt="スクリーンショット 2017-11-17 19.06.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/16060/bc885d30-5bfe-8947-ddd2-96f218cc5e2f.png">

### タブになりました

<img width="1069" alt="スクリーンショット 2017-11-17 19.07.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/16060/76bbe2b0-16e8-e0c0-ac3f-dbca66d0ea0f.png">

おわり。
__version__ ってアンチパターンじゃね？

Python のライブラリでは、よく `__version__` が定義されていて、
インタラクティブシェルで、簡便なバージョン確認に使えますが、

```python
>>> import pandas
>>> pandas.__version__
'0.21.0'
```

自分でライブラリを書くのに、`__verson__` を定義するのはアンチパターンじゃないかと、最近思い始めました。

# じゃあどうするの？

こうします。

- `__version__`　は定義しない
- バージョンは `setup.py` に（だけ）指定する

以下理由です。

# 理由1: 二重管理になる

バージョン番号は、setup.pyにも書かなくていけません。

```python
# mylibrary.py
__version__ = '1.2.3'
```

```python
# setup.py
from setuptools import setup
import mylibrary

setup(
  version='1.2.3',
  ...
)
```

ファイルを２つ編集するのは面倒ですね。
面倒だけならまだいいのですが、両者のバージョンがズレてしまったらどうするのか？バージョンを合わせるだけのために、新しいバージョンをリリースするのか？

# 理由2: setup.py が本体のコードに依存してしまう

二重管理を避けるために、setup.py で`__version__`を参照する方法もよく取られています。

```python
# setup.py
from setuptools import setup
import mylibrary

setup(
  version=mylibrary.__version__,
  ...
)
```

しかしこれは、`mylibrary` がどこでも容易にimportできることを暗黙に仮定しています。もし、

- `mylibrary` が内部で他のライブラリに依存していたら？
- `mylibrary` がC言語拡張モジュールだったら？
- `mylibrary` が import にすごく時間がかかる巨大なライブラリだったら？

特に１番目のケースでは、依存ライブラリのインストールに setup.py を実行しなけりゃならないが、`mylibrary` が import できないので setup.py が実行できない！

って状況になります。

# 理由3: 無くても困らない

**そんなにバージョンを知りたいですか？**

別に、バージョンを知りたければ、`pip freeze` コマンドでよくないですか？

```
$ pip freeze | grep mylibrary
mylibrary==1.3.4
```

依存ライブラリのバージョンごとに振る舞いを変えるために、こんなポリフィルを書くことがありますが、

```
if mylibrary.__version__ >= '1.4.0':
   something = mylibrary.something
else:
   def something():
      mylibrary.something のポリフィル
```

しかし、そもそも**これは適切なのか？**

バージョン関係の処理は ライブラリの責務なのでしょうか？。
あんまり頑張るのではなく、**単に古い依存ライブラリは切ってしまう**。それが、古いライブラリの更新を促し、結果的にみんなが幸せになるのではないかとも思います。

なお、どうしてもプログラム的にバージョンを取りたいなら、`pkg_resources` を使うこともできます。

```
import pkg_resources
v = pkg_resources.get_distribution('mylibrary').version
```

# 理由4: そもそも標準でもなんでもない

`__version__` はなんとなくみんな定義しているだけで、定義しなくてもよいものです。「`__version__` を追加してください」ってIssueは建てられるかもしれませんが。

標準では無いので、バージョンを確実に取得したいなら、上述の`pkg_resources` を使わざるをえません。そして、`pkg_resources` では `__version__` は不要です。

# 感想

SQLアンチパターンみたいな本を読むと、アンチパターンって、「簡単にできる」とか「一見シンプル」なものが多いような気がするんですが、`__version__` はまさにそれだなって思います。初心者でも簡単にできるし、一見シンプルで賢そうな解決。でも後々困る。
《JavaScript》jQueryみたいなセレクターでDOMを取得するES6なクラス

jQueryなしのプロジェクトで、`document.getElementById()` や `document.getElementsByClassName()` を省略するためのヘルパーはいろいろ知恵がありますが、自分でも使いやすいものを作ってみました。


`$(element)` のようなものをclass構文で書きます。




## DOMの取得をjQueryみたいにシンプルな記述にしたい

セレクタにシンボルを付与して、その文字列からメソッドを振り分けるようにしています。

毎回 `new` を記述するのを避けてシンプルにするため、ラップして隠蔽できるようにしました。



```js

/**
 * # / . / * を含むセレクタを受け取ってDOMを返す
 * # : getElementById
 * . : getElementsByClassName
 * * : querySelectorAll
 */
const Selector = class {

  /**
   *
   * @param selector
   * @returns {*[]}
   */
  constructor(selector) {

    this.selector = selector;
    return this._getEl();

  }

  /**
   * セレクタを判別してDOMを取得
   * @returns {[*]}
   * @private
   */
  _getEl() {

    const method = this._selectMethod();

    const el = document[method](this.selector.slice(1));

    return !el.length ? el : [...el];

  }

  _selectMethod() {

    const matches = {
      '#': 'getElementById',
      '.': 'getElementsByClassName',
      '*': 'querySelectorAll'
    }[this.selector[0]];

    return matches;

  }

};


/**
 * new を省略するためのラッパー
 * 好きな関数名を与える
 */
const _$ = target => new Selector(target);


/**
 * こんな感じで使う
 */
console.log(_$('#el'));

console.log(_$('.el'));
console.log(_$('*[data-el]'));
console.log(_$('*p'));

console.log(_$('*#el2 p'));

```

これで、 `_$('#yourSelector')` `_$('.yourSelector')` `_$('*yourSelector')` でDOMを取得できるようになりました。




### forEachを使えるように

取得したDOMは、これも取り回しやすくするために、`[...el]` の部分で配列に展開して、`forEach()` にチェインできるようにしました。


```js

_$('*p').forEach((el) => {

  el.style.color = '#22aacc';

});

```





## クラスをimportできるようにする

このヘルパークラスを selector.js として main.js に `import` できるように手を加えてみます。


```selector.js

const Selector = (() => {

  class Selector  {

    constructor(selector) {

      this.selector = selector;
      return this._getEl();

    }

    _getEl() {

      const method = this._selectMethod();

      const el = document[method](this.selector.slice(1));

      return !el.length ? el : [...el];

    }

    _selectMethod() {

      const matches = {
        '#': 'getElementById',
        '.': 'getElementsByClassName',
        '*': 'querySelectorAll'
      }[this.selector[0]];

      return matches;

    }

  }

  const omitNew = (target) => new Selector(target);

  return omitNew;

})();

export default Selector;

```

```main.js

import _$ from './utility/selector';

console.log(_$('#el'));
console.log(_$('.el'));

```





## 参考

* [saltjs](https://github.com/james2doyle/saltjs)
restart=alwaysなコンテナを探して自動再起動を解除する

# restart=alwaysでdocker runしたコンテナを探す

docker inspectとdocker ps -aqを組み合わせて、RestartPolicyの状態を出力し、結果をgrepで絞る

```shell-session
docker inspect -f "{{.Name}} {{.HostConfig.RestartPolicy.Name}}" $(docker ps -aq) | grep always
```

# 自動再起動を止める

見つかったコンテナのうち、自動再起動を解除したい任意のコンテナに対してdocker updateする

```shell-session
docker update --restart=no $container_name
```
pepperにm4aファイルをアップロードして再生するとエラーになるのを解消

#pepperに歌を歌ってもらいたい
CD音源をcoregraphからアップロードしてみました。
問題プロジェクトにインポートされることは確認できたのですが、その状態で再生ボタンを押すと、

---
*現在のプロジェクトを再生できません*

*インストール中にエラーが発生しました：パッケージのインストールに失敗しましたboost::filesystem::path codecvt to wstring: error*

---
というエラーが発生してしまいます。

何回もやりすぎると

---
*申し訳ありません。
Choregraphe に問題が生じてクラッシュしました。
我々がこの問題を診断、解決するためにも、クラッシュレポートの送信にご協力ください。*

---
というエラーが発生して、、Coregrapheが落ちます。


#環境
ちなみに環境は　
　Choregraphe　バージョン2.5.5.5
です。

#原因らしきもの

https://robotstart.info/2017/04/18/naoqi2-5-5-dev.html

m4aファイルはpepper使えなそうな記事が書かれており、そういうことか。
何回やってもm4aファイルがある時はこのエラーが必ずでることが判明しました。

#m4aファイルをやめよう
m4aのファイルをmp3に変換して実行したら、あら、、これも同じエラーが出て解消しません。
ちなみに、もうすでに効果音などをアプリにmp3で入れているので、mp3が原因ではなさそう。
ということでファイルサイズを疑ってみます。

Gabagebandで音質をだいぶさげて、これまで4MBだったものを2MBまで圧縮してみました。

すると、、
うまくいきました。
ファイルのサイズが重要のようです。
pepper実機でも確認すると問題なく動きました。
めでたしめでたし
PHPでログインが必要なサイトを作る方法(第2回)

こんにちは、片山学園 鉄道研究会の[stmkza](https://twitter.com/stmkza)です。

今回は前回の続きです。前回：[PHPでログインが必要なサイトを作る方法(第1回)](https://qiita.com/rrc/items/69c3dde5eb00de8772ba)

# URLの拡張子を消す方法
それではログインページを作りましょう。

その前に、URLの`.php`を消して、`/login`でアクセスできるようにしましょう

今回はApacheを使っているので、`.htaccess`か`httpd.conf`ファイルに設定を記述していきましょう。

```apache:/.htaccess
<IfModule mod_rewrite.c>
    RewriteEngine on
    # URLがディレクトリでなくて
    RewriteCond %{REQUEST_FILENAME} !-d
    # URLのファイル名に「.php」をつけたファイルが存在するなら
    RewriteCond %{REQUEST_FILENAME}\.php -f
    # そのPHPファイルを代わりに表示する
    RewriteRule ^(.*)$ $1.php
</IfModule>
```

# PHPファイルからincludeされるファイルの直接アクセスを禁止する
内部で読み込まれるためのPHPファイルに直接アクセスされると不具合が出たり、セキュリティー上の問題が起こることがあります。

ですので、`/inc/*`のファイルへのアクセスは禁止します。

```apache:/inc/.htaccess
deny from all
```
単純にすべてのアクセスを拒否する単純な設定です。

# ログインページを作る
すみません、具体的なソースコードはセキュリティー上の理由で公開できません。ですので、大体の仕様をここに書きます

* ログインフォームは`/login`にPOSTする
* ユーザー名は`[name="username"]`、パスワードは`[name="password"]`とする
* ログインチェック処理は
    1. セッションを開始(`session_start()`を実行)
    1. ユーザー名とパスワードが送信されているかチェックする
    1. パスワードソルトとパスワードを連結して、ストレッチングしてDBから取得したパスワードハッシュと比較
    1. 成功したら`$_SESSION['user']`にユーザー名を格納する
    1. エラーをを表示(失敗時) or `/index`にリダイレクト(成功時)

こんな感じにしました。

注意点としては、**絶対に`/inc/auth.php`を読み込んではいけない**ということです。

前回も書いた通り、リダイレクトループになります。
Swift3 WKWebViewのBasic認証対応

#iOS11にアップしたらBasic認証対応URLが接続できなくなりました。
以前対応は以下のURL見たいにBasic認証のIDとパスワードをURLに追加して表示しました。
http://id:password@xxxxxx.jp

```swift:修正前
        let link = URL(string: "http://id:password@xxxxxx.jp")
        var request = URLRequest(url: link!)
        
        webView.load(request)
```

#修正：ヘッダーにIDとパスワード追加
```swift:修正後
        let link = URL(string: aUrl)
        var request = URLRequest(url: link!)
#if DEBUG || STAGING
        let username = "testUser"
        let password = "testPass"
        let loginData = String(format: "%@:%@", username, password).data(using: String.Encoding.utf8)!
        let base64LoginData = loginData.base64EncodedString()
        
        request.setValue("Basic \(base64LoginData)", forHTTPHeaderField: "Authorization")
#endif
        
        webView.load(request)
```
Springで明示的トランザクション

## 概要
Springで明示的トランザクションを行う方法を調査した。  
※ここでは宣言的トランザクション（@Transactional）については触れません。

## 目的
宣言的トランザクションでは満たせない要件があるときに使う？

## やり方
### TransactionManagerを使う
getTransactionからcommit / rollbackまでがトランザクションの範囲となる。

```
@Autowired
private PlatformTransactionManager transactionManager;

public void test() {
    TransactionDefinition def = new DefaultTransactionDefinition();
    TransactionStatus status = transactionManager.getTransaction(def);

    // DB操作
    ...

    if( <DB操作結果の判定> ) {
        // NGならロールバック
        transactionManager.rollback(status);
        return;
    }
        
    // OKならコミット
    transactionManager.commit(status);
}
```


### TransactionTemplateを使う
TransactionTemplateのexecuteメソッドがトランザクションの範囲となる。  
例外が発生すると自動でロールバックされ、そうでなければコミットされる。  
明示的にロールバックしたいときは、setRollbackOnlyを呼び出す。

```
@Autowired
private TransactionTemplate transactionTemplate;

public void test() {
    Entity result = transactionTemplate.execute( status -> {
        // DB操作
        Entity result = select();
        
        // 明示的にロールバックしたいとき
        // status.setRollbackOnly();
        
        // 参照結果等があるときはreturnする
        return result;
    });
}
```

##
Laravel コマンドでHelloControllerの作成し、index を表示させる

#コントローラー作成

artisan(アーティザン)コマンドを使用して作成する

コントローラーの格納場所
/app/Http/Controllers

```
php artisan make:controller コントローラ名
```

今回はHelloControllerを作成

```
php artisan make:controller HelloController
```


```/app/Http/Controller/HelloController.php
//デフォルト作成ファイル
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HelloController extends Controller
{
    //
}

```

```/app/Http/Controller/HelloController.php
//記述後　indexアクションの追加
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HelloController extends Controller
{
    //
    public function index() {
    //パラメーターを渡す場合　
    //public function index($id='no name',$pass='unknown') {
        return <<<EOF
    <html>
    <head>
    <title>Hello/index</title>
    <style>
    body {
        font-size:16pt; 
        color:#999;
    }
    h1 {
        font-size:100pt;
        text-align: right;
        color:#eee;
        margin:-40px 0 -50px 0;
    }
    </style>
    </head>
    <body>
        <h1>index</h1>
        <p>こちらはHelloコントローラーのindexページです</p>
    </body>
    </html>        
EOF;

    }
}

```

これを書いただけでは表示されないので
下記ディレクトリに追加

```/routes/web.php
//HelloController.php と連携 indexアクションの表示
//第二引数:コントローラ名@アクション名　という風に記述する
Route::get('hello','HelloController@index');

//パラメーターを渡す場合の記述例
Route::get('hello/{id?}/{pass?}','HelloController@index');
```
AWSのECSでGPUを使う方法

# はじめに
AWSのECSでGPUを使う場合、ECS側ではGPU搭載のインスタンスはデフォルトでは選べません。今のところ自分自身でどうにかするしかありません。その方法を記載します。

# 1. ECSでクラスターを作成
ECSで新規にクラスターを作成します。ここで設定するクラスター名は後ほど使います。今回の説明ではecs-clusterという名前で説明します。

# 2. ECSで動かせるGPUのAMIを作成する
AWSの公式ページにあるので、こちらの手順に沿ってAMIの作成まで行います。
[GPUワークロードのAMIの作成](http://docs.aws.amazon.com/ja_jp/batch/latest/userguide/batch-gpu-ami.html)
こちらの手順の最後にec2-userでsudoをつけずにDockerを叩けるように設定しておくと構築時に便利になります。

```
$ sudo usermod -g docker ec2-user
$ sudo /etc/init.d/docker restart
```
上記のコマンド入力後は一度ターミナルから抜けて再接続する必要があります。

# 3. 作成したGPUのAMIを使ってインスタンス作成
## インスタンスの設定
ここではp2.xlargeを使って、インスタンスを立ち上げます。

<img width="931" alt="スクリーンショット 2017-11-17 17.04.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/199445/63364afb-1a7a-f6de-dc81-98da0d19b685.png">

**以下の点に注意する必要があります**

- 作成するインスタンスのロール設定はECSインスタンスロールを与えてください。
 作成方法はこちらを参照ください：[Amazon ECSインスタンスロール](http://docs.aws.amazon.com/ja_jp/batch/latest/userguide/instance_IAM_role.html)

- インスタンスの設定タブの下部の高度な詳細でユーザデータを設定する（下記）

```
#!/bin/bash
echo ECS_CLUSTER=ecs-cluster >> /etc/ecs/ecs.config
```

# 4. Dockerfileの構築
ここではGPUを使うためのDockerfileを作り、ECRへプッシュします。
今回は**tensorflow-gpu 1.4.0**を使います。TensorFlowのバージョンに合わせて、nvidiaのイメージを使いますので、下記のURLからご確認ください。
https://www.tensorflow.org/install/install_sources#common_installation_problems

上記のURLで確認するとcuDNN:6 CUDA:8なのでnvidiaのimageはこのバージョンに沿ったものを使います。

下記のDockerfileは一例なので、各自行いたい構築を設定してください。

```text:Dockerfile
FROM nvidia/cuda:8.0-cudnn6-devel
RUN apt-get update
RUN apt-get install -y  git \
                        vim \
                        build-essential \
                        libncursesw5-dev \
                        libgdbm-dev \
                        libc6-dev \
                        zlib1g-dev \
                        libsqlite3-dev \
                        tk-dev \
                        libssl-dev \
                        openssl \
                        libbz2-dev \
                        libreadline-dev \
                        checkinstall \
                        wget \
                        jq

RUN git clone https://github.com/yyuu/pyenv.git /root/.pyenv

ENV PYENV_ROOT "/root/.pyenv"
ENV PATH "$PYENV_ROOT/bin:$PATH"
ENV PATH "$PYENV_ROOT/shims:$PATH"
RUN pyenv install 3.6.2
RUN pyenv global 3.6.2
RUN pip install tensorflow-gpu==1.4.0

```

DockerFileを作成したら、ECRへプッシュします。
ECSのリポジトリで新規リポジトリを作成するとプッシュまでの流れが記載されているのでその通りに行います。

**個人的にハマった点**
tensorflowとtensorflow-gpuは一緒に入れないでください、tensorflowを入れるとCPUで動きます。必ずtensorflow-gpuだけにしてください。

# 5. タスク定義
ここで重要な部分は下記です。

* 特権付与をつける
* ボリュームマウントでホスト側のnvidia関連をマウントする
ホスト側の「/var/lib/nvidia-docker/volumes/nvidia_driver/latest」とコンテナ側の「/usr/local/nvidia」

以上のことを行えば、ECSでGPUインスタンスを使えて、かつTensorFlowが回せると思います。