OmniAICreator/Qiita-1.07M huggingface dataset:
超入門GitHubでのソース公開方法

　先日GitHubでソースを公開しようと試みたものの初めてでうまくわからず、検索してもversionが古いのかうまくいかなかったので個人的な学習も含めてQiitaに投稿してみました。GitHubはQiitaを利用している時点ですでに登録済みかと思われるので割愛します。


##リポジトリーの作成
　リポジトリとは、ファイルやディレクトリの状態を保存する場所です。リポジトリを作成することで変更履歴を記録することができます。リポジトリの作成にはまず、GitHubにログインした状態で「**Start a project**」または、緑色の「**New Repository**」ボタンを選択します。

![スクリーンショット (27).png](https://qiita-image-store.s3.amazonaws.com/0/133775/78f300ff-8217-7a77-fcff-33bc66ee7189.png)



##GitHub（ソフトウェア）をダウンロード
　次に、作成したファイルを自分のパソコンから公開できるようにGitHub(ソフトウェア)をダウンロードしています。画像の右上にある「**Set up in Desktop**」を選択しするとダウンロード画面が表示されるのでダウンロードを開始してください。

![スクリーンショット (30).png](https://qiita-image-store.s3.amazonaws.com/0/133775/09ca606f-6bfe-27e4-8d79-835f73f85f2b.png)

ダウンロードが完了されると、ディスクトップにGitHubのショートカットが作成されます。
##GitHub（ソフトウェア側）でのレポジトリ作成方法
　ディスクトップからGitHubを立ち上げ、左上の十字キーを選択して下さい。「**name**」(フォルダ名)を入力し、「**Create repository**」を選択するとGitHubにフォルダを作成することができます。

![スクリーンショット (33).png](https://qiita-image-store.s3.amazonaws.com/0/133775/9c91bd56-9805-76ad-4070-a56310e97a89.png)

作業が完了すればドキュメントに「test」フォルダが作成されていると思います。（今回は「test」と入力しました）
次にGitHubに公開するためのファイルを作成していきます。「**open this repository**」　を選択すると作成したフォルダにアクセスできます。また、右上の「**Atom**」からもファイルの作成は可能です。

![スクリーンショット (34).png](https://qiita-image-store.s3.amazonaws.com/0/133775/47d1977e-7e63-9294-abac-3142a39df2e2.png)

ファイルの作成が完了すればGitHub上に作成したファイルが表示されていると思います。作成ファイルに誰でも読みやすくできるように「**Summary**」（タイトルになる部分）と「**Description**」（説明欄になる部分）を記入します。

![スクリーンショット (35).png](https://qiita-image-store.s3.amazonaws.com/0/133775/bc84e325-cf35-dbb4-de0a-47229192324e.png)





##GitHub（ソフトウェア側）ソースを公開する公開
　最後にファイルをオンライン上で公開します。右上の「**public**」を選択してください。
上手くいっていればこのようにGitHub（サイト側）でファイルが公開されています。

![スクリーンショット (38).png](https://qiita-image-store.s3.amazonaws.com/0/133775/a72ecc2a-4033-72db-ce66-02a7ad7a8dcc.png)

以上でGitHub公開可能かと思います。超初心者なので説明が適切でないかもしれません。

参考サイト
[今さら聞けない！GitHubの使い方【超初心者向け】](https://techacademy.jp/magazine/6235)
Visual Studio 2015のISOファイルをダウンロードする

# 本記事について
## シナリオ
ISOファイルを利用する事によって、Visual Studio 2015のインストールを短縮する。
本記事は、Visual Studio Community 2015 with Update 3の日本語のISOファイル(ファイルサイズは7.1GB)をダウンロードするシナリオを記載する。
なお、必要に応じて、アプリケーションやEditionを読み替えていただきたい。

**注意 : Visual Studio 2017のISOファイルは、本手順では作成できません。**

### 解決しようとする事
Web Installerを利用して、WindowsへのVisual Studio 2015をインストールすると、通信速度の影響を受け、インストールに時間がかかる場合がある。
本記事では、Web Installerではなく、ISOファイルを利用する事によって、インストール時に通信速度の影響を小さくする事で、インストールにかかる時間を短縮する。

### 解決しない事
MSDNサブスクリプション契約者は、[MSDN サブスクライバー ダウンロード](https://msdn.microsoft.com/ja-jp/subscriptions/downloads/)からISOファイルをダウンロード出来るので、本記事では取り扱わない。

## 免責事項
1. Webサイトのデザインが変わった時は、後述の手順を実施できない事がある。
2. Visual Studioのバージョンによって、ISOファイルを作成する方法が変わった場合に、本手順が適用できない事がある。
3. インストールの設定によっては、ストレージのサイズが不足する事がある。状況によっては、ストレージの多いパソコンを買うのも1つの手段。

> Xamarin で**全部入り**の Visual Studio 2015 Community をインストールしようとすると、45GB の容量が必要になります。
> 
[Windows で Xamarin 開発をしたい方はインストールする前に読んでほしい - Xamarin 日本語情報](http://ytabuchi.hatenablog.com/entry/2016/04/05/142525)より抜粋

# 手順
1. https://www.visualstudio.com/ja/downloads/ を開く
2. [すべてのダウンロードを見る >]ボタンを押す(下図の赤枠部分)
![VSinstall_edited.png](https://qiita-image-store.s3.amazonaws.com/0/46949/18e8a779-73b3-5582-7099-21efb2c6320d.png)
3. 対象アプリケーションをクリックする。本手順では、Visual Studio Community 2015 with Update 3を例とする(下図の赤枠部分)
![VSinstall2_edited.png](https://qiita-image-store.s3.amazonaws.com/0/46949/2306b0f1-96c9-c3ed-7c59-4bde295576e7.png)
4. ISOファイルと言語を選択する。![VSinstall3_edited.png](https://qiita-image-store.s3.amazonaws.com/0/46949/ab042382-82ca-74f7-7de9-11a1a6dc3a73.png)
5. [Download]ボタンを押す。Visual Studio Community 2015 with Update 3の日本語のISOファイルのファイルサイズは、7.1GB。
AWSのまずやっておきたいユーザセキュリティ対策について

#AWSのまずやっておきたいセキュリティ対策について
AWS自体のユーザーセキュリティ、監査を強化したいと思います。

##IAMでのユーザ設定
rootで作業するべきではなく、ユーザを新たに作り運用していきたいと思います。
IAMで設定します。
初期の段階では下記のようになっているので、これを変えていきたいと思います。

![image](https://qiita-image-store.s3.amazonaws.com/0/56889/c4e8bdf7-dd22-820b-757a-745b3062534a.png)

###ルートアカウントのMFAを有効化
ルートアカウントの多要素認証を有効にします。
今回はアンドロイドに入れた「Google Authenticator」を使用するので「仮想 MFA デバイス」を有効にします。

![image](https://qiita-image-store.s3.amazonaws.com/0/56889/a5d8131b-24a8-4f45-72d5-385d3f92a3a9.png)

続いて表示されるQRコードを「Google Authenticator」に読み込ませます。
成功すると 3桁 3桁のコードが表示されます。時間経過でどんどん数字が切り替わるので
連続して6桁、6桁を入力して認証ボタンを押下します。
成功すると成功メッセージが表示され、メニューも変わります。

![image](https://qiita-image-store.s3.amazonaws.com/0/56889/b2fb9bae-741f-7e36-9db1-3aa4c4fc1547.png)

尚、なくしたり壊したりするとログインできなくなりAWSに連絡してMFAを無効にしてパスワードでログインできるようにしてもらわないといけないので注意してください。
http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_mfa_lost-or-broken.html

###グループの作成
グループを作成し、ポリシーを割り当てます。更にこのグループにユーザを割り当てていきます。

下記画面よりグループを作成していきます。
![image](https://qiita-image-store.s3.amazonaws.com/0/56889/e9e34da8-6ef7-42f4-af56-25b6a0906072.png)

とりあえずadminとして何でも出来るユーザを作っておきます。
AdministratorAccessをチェックして作成します。

![image](https://qiita-image-store.s3.amazonaws.com/0/56889/c1d1f3f4-387b-e169-90c9-ef6a91454c94.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/56889/d6573cb5-c0a2-aa49-a0b8-caf0b0f7034b.png)

adminが出来ました。
この他にユーザ管理以外は何でも出来るグループ、stop,startできるグループ、見るだけのグループ
などを作って行けばいいと思います。

一例
![image](https://qiita-image-store.s3.amazonaws.com/0/56889/00118650-cfcf-d11d-f541-ffc9b87c5e43.png)

###ユーザの追加
ユーザを作成して先程のグループに紐づけていきます。
AWS アクセスの種類でAPIを使用しない場合はコンソールのみにする、逆も然りで注意しましょう。

![image](https://qiita-image-store.s3.amazonaws.com/0/56889/9675ae86-1d45-67b1-3d5a-6864b2ece8c7.png)

作成後、先程と同じようにMFAも割り当てておきましょう。
ユーザ名をクリックするとMFAデバイスの編集リンクが出てきます。

![image](https://qiita-image-store.s3.amazonaws.com/0/56889/cbefbc9c-5161-52a5-b9c8-e34098af1e2c.png)


以上。
KarabinerがmacOS Sierraに対応するまでの繋ぎのアプリを作った。

# 概要

macOS Sierraで[Karabiner](https://pqrs.org/osx/karabiner/index.html.ja)が使えなくなったことで、US配列のキーボードを使用している人は、Karabinerで割り当てていた英数/かなキーが使えなくなり、非常に辛いと思います。
そこで、`左⌘`に`英数キー`、`右⌘`に`かなキー`を割り当てるためのシンプルなアプリをSwiftで作って見ました。(⌘と他のキーを組み合わせて押下した場合は、⌘キーとして動作します)

[k-yamada/Kenban](https://github.com/k-yamada/Kenban)

以下は、そのアプリの説明です。
(おまけで、アプリにマウスカーソルを操作する機能もつけているのですが、Karabinerのように低レイヤーのキーボード入力イベントが取得できてないので、操作性は非常に悪いです。)

# [Kenban](https://github.com/k-yamada/Kenban)

- macOS Sierra向けのキーバインド変更アプリです。
- キーバインドは、US配列のキーボードを使用している日本人向けです。
- KarabinerがSierraに対応するまでの繋ぎとしてご使用ください。

# セットアップ

- [最新版のKenbanをダウンロード](https://github.com/k-yamada/Kenban/releases)して、`/Applications `フォルダに移動してください。
- Kenban.app を実行し、アプリケーションにコンピュータの制御を許可してください。 (システム環境設定 > セキュリティとプライバシー > プライバシー > アクセシビリティ > Kenban.appにチェック)

# キーバインド

キーバインド | 動作
---- | ----
左⌘ | 単独で押下した場合は`英数キー`として働く。他のキーと組み合わせて押下した場合は、⌘キーとして働く。
右⌘ | 単独で押下した場合は`かなキー`として働く。他のキーと組み合わせて押下した場合は、⌘キーとして働く。
⌘+d | マウスキーモードに変更。
(マウスキーモード中) h | マウスカーソルを左に移動。
(マウスキーモード中) j | マウスカーソルを下に移動。
(マウスキーモード中) k | マウスカーソルを上に移動。
(マウスキーモード中) l | マウスカーソルを右に移動。
(マウスキーモード中) f+hjkl | マウスカーソルの移動量が大きくなる。
(マウスキーモード中) v | 左クリック
(マウスキーモード中) b | 右クリック
LeakCanaryとFirebaseを併用するとクラッシュする

## 事象

FirebaseをLeakCanaryを併用するとLeakCanaryのプロセスが以下のログを出力しながらクラッシュします。

```
Caused by: java.lang.IllegalStateException: Default FirebaseApp is not initialized in this process com.hogehoge:leakcanary.
Make sure to call FirebaseApp.initializeApp(Context) first.
```

LeakCanaryはアプリのメインプロセスとは別のプロセスで稼働しているので~~アプリ自体はクラッシュしません(しばらくフリーズしますが)~~時と場合による。

## 原因

FirebaseはContentProviderを利用してライブラリの初期化を行っています。
この手法については[こちら](https://medium.com/@andretietz/auto-initialize-your-android-library-2349daf06920#.4s5yd6kzs)が詳しいです。

ContentProviderはデフォルトでマルチプロセスが無効となっているため、メインプロセス以外ではFirebaseが初期化されていない状態となってしまいLeakCanaryのプロセスで最初に示したエラーとなってしまいます。

このため、Firebaseに限らずContentProviderで初期化するアプローチを取っているライブラリは何らかの問題が発生する可能性があります。

## 対応方法

Firebaseには手動で初期化するためのAPIが用意されているのでそちらを使用してApplicationクラスの `onCreate` で初期化します。
ref: [FirebaseApp  \|  Firebase](https://firebase.google.com/docs/reference/android/com/google/firebase/FirebaseApp.html#initializeApp(android.content.Context))

```java
@Override
public void onCreate() {
    // 必要に応じて他のオーバーロードと使い分ける
    FirebaseApp.initializeApp(this)
}
```

これで、とりあえずクラッシュは回避できますが、初期化のためのContentProviderは残っているため無駄に初期化処理が動いてしまいます。
なのでAndroidManifestに次の記述を追加して、Manifest MergerがContentProviderを追加するのを防ぎます。

```xml
<provider
        android:authorities="${applicationId}.firebaseinitprovider"
        android:name="com.google.firebase.provider.FirebaseInitProvider"
        tools:node="remove"/>
```

他にContentProviderを使用しているライブラリがあれば同様に `tools:node="remove"` を指定してAndroidManifestに追加されないようにしていきます。
その際、 `android:authorities` はなんでもいいのですが、 `android:name` は実際のものと一致している必要があります。
ライブラリのソースを見るか、マージ後のAndroidManifestから探して正しいものを指定してください。

例えば、拙作のライブラリ[Kotpref](https://github.com/chibatching/Kotpref)の場合は次のように指定することで自動初期化用のContentProviderを無効化することができます。

```xml
<provider
        android:authorities="${applicationId}.KotprefInitProvider"
        android:name="com.chibatching.kotpref.KotprefInitProvider"
        tools:node="remove"/>
```

```java
@Override
public void onCreate() {
    Kotpref.init(this)
}
```
Pythonスクレイピング（Beautiful Soup）+XPathでテキスト文指定でリンク先ＵＲＬを取得

先日来から訓練中のスクレイピングですが、
以下のことがなかなかできなかったのですが、
出来たので記事に。

・テーブル構造の中に存在する、テキストと、リンク先URLをセットでスクレイピングしたい（pandasのDataFrameを利用）
・当該リンク先URLは、同じテーブル内で複数のa hrefがあり、かつ識別可能な名前が付与されておらず正規表現でもとりにくいものだった
→テキスト文章を指定してそのテキストのリンク先として指定をして、スクレイピングしたら良さそうだったのでXPathを使うことに
（DataFrameは行数が揃わないとエラーが返ってくるので不要なデータを省いて確実にとりたい）
・Beautiful SoupはXPath使えないけど、lxmlを使えば出来た

【参考にさせていただいたサイト】
http://gci.t.u-tokyo.ac.jp/tutorial/crawling/
http://www.slideshare.net/tushuhei/python-xpath
http://qiita.com/tamonoki/items/a341657a86ff7a945224

```scraping.py
#coding: utf-8
from bs4 import BeautifulSoup
import urllib2
import pandas as pd
import time
import lxml.html

aaa = []
bbb = []

for page in range(1,2):
	url = "http://www.～～～" + str(page)
	html = urllib2.urlopen(url)
	html2 = urllib2.urlopen(url)
	soup = BeautifulSoup(html, "lxml")
	dom = lxml.html.fromstring(html2.read())

	for o1 in soup.findAll("td", class_="xx"):
		aaa.append(o1.string)

	for o2 in dom.xpath(u"//a[text()='xxx']/@href"): #xxxの部分をテキスト指定でhrefを取得
		bbb.append(o2)

	time.sleep(2)

df = pd.DataFrame({"aaa":aaa, "bbb":bbb})
print(df)
df.to_csv("xxxx.csv", index=False, encoding='utf-8')
```

簡単ですが、今日は以上です。
３ヶ月でMVPを作る - Week 9 & 10

###進歩
-ほぼなし。。。




###やったこと
-ローカル環境の作り方の復習
-「パーフェクトRuby」のPart１とPart２
-クローラー（スクレーパー）の作成
-SendGridの環境変数を設定した（$exportで）
-ImageMagick, Paperclipとphotoモデルの作成
-エンジニアの友達からのフィードバックをもらう




###学び
-ローカル環境の設定について分かりやすい！
http://dotinstall.com/lessons/basic_localdev_mac_v2﻿
-Ruby本では分からないところだけを復習、ピンとこない時はドットインストールで。
http://dotinstall.com/lessons/basic_ruby_v3/37111﻿
-Rubyの基本が分かったら、クローラーを作ってみる
http://tango-ruby.hatenablog.com/entry/2015/03/09/185701﻿
-ずっとうまくいかなかったSendGridの設定ができた時
https://plus.google.com/u/1/107221871269602934448/posts/4J1n6LiVcuk?sfc=true
-Railsのコントローラー特訓の方法（現在進行中）
https://plus.google.com/u/1/107221871269602934448/posts/H3T488QdRg8?sfc=true
-（興味本位で）Meetupはどんな技術が使われているか。
https://builtwith.com/meetup.com﻿


（全ての学びはここに👇）
https://plus.google.com/u/1/107221871269602934448


###これから
-旅行フォームの入力画面を作成する
-写真のアップロード機能をAjaxで実装する
-terminalからgit pushで、本番環境に反映されるようにする
-secret.ymlを使うことで毎回の環境変数設定をなくす




###感想
改めて近くにメンターがいない状態でプロジェクトをやるのは大変なことに気づく。。。
ゆっくりでもいいから、一歩ずつ前進していかないと。
iOSで機内モードを検知する

#機内モードを検知する方法
- Wi-Fiに繋がっている状態から機内モードになった時
- 機内モードでアプリを起動した時

これらを検知するにはInfo.plistに
`UIRequiresPersistentWiFi` を付け足して、`YES` に設定しておきます。
(`Application uses Wi-Fi` と変換されます。)

<img width="864" alt="Screen Shot 2016-11-27 at 22.37.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/122365/b89c673a-4346-fb9a-365e-887d5c7aac3e.png">
YubiKeyの予備キー

SSHの鍵管理などにYubiKeyを導入して、[便利に活用していた](http://qiita.com/jkr_2255/items/6927758094c3078e62c5)のですが、予備の鍵が必要だと感じたので購入することにしました。

## 必要だと思った理由

YubiKeyを使いだして以来、全ての鍵をYubiKeyへ寄せるようになりました。そうしてしばらくの時間が過ぎたのですが、今になって予備の必要性を感じだしたのには、以下の2つの理由があります。

### 単一障害点
「すべての鍵を寄せた」代償として、「YubiKeyを壊したりなくしたりすればログイン不可能となってしまう」ということがあります。はじめのうちはそう多くなかったのですが、次第に「YubiKeyしか鍵を設定していない」ものが出だして、「このままだとまずい」と思い始めました。

### 証明書が切れる
SSH鍵として使うためにYubiKeyで証明書を作成しますが、この証明書には期限があって、しかも**更新ができなさそう**なので、期限が切れれば鍵を作り直しとなってしまいます。そんなこともあって、最初に作った鍵の証明書の期限（1年）が迫ってきた最近になって「せっかく再設定が必要になるのなら」ということで、予備のYubiKeyを用意することにしました。

## 複数使う場合の設定

SSH鍵は`~/.ssh/authorized_keys`にいくつでも書けるので、新しい鍵を追加することは特に問題ありません。

そして、Googleの2要素認証でも鍵を複数本セットできるので、こちらも問題なく設定を完了しました（モバイルでの運用などを考え、さらに別な要素でも認証できるようにしてあります）。

## おまけ

いざトラブルに見舞われてしまうと、気も動転しますし、普段できていることすらうまくできなくなるかもしれません。「予備の方法」も普段と合わせておけば、緊急時の対応もそこまで焦らずに済むことでしょう。
Dockerの基本的な使い方まとめ

# Dockerの基本的な使い方まとめ

個人的なメモも兼ねて、Dockerの基本操作をまとめてみます。

## Dockerイメージの起動コマンド

```sh
# dockerコマンドで "cnetos6" のDockerイメージを起動
docker run -it -p 80:80 -v /root/botpj:/tmp/share centos:6 /bin/bash
```

+ -it
  - Dockerイメージ起動後にコンテナ内で操作
  - コマンドの末尾で指定したシェルを利用

+ -p <ホストのポート番号>:\<Dockerコンテナ内のポート番号>
  - ホストの指定ポートにDockerの指定ポートをマッピング

+ -v <ホストのディレクトリパス>:\<Dockerコンテナ内のディレクトリパス>
  - ホストの指定ディレクトリをDockerの指定ディレクトリにマウント
  - 有効にしている場合はSELinuxの無効化が必要(しないとホストのディレクトリ内を見れない)


## Dockerイメージの更新手順

+ Ctrl-p -> Ctrl-q
  - 起動中のDockerイメージから一時的に抜ける

+ $ docker ps
  - それまでいじっていたDockerイメージのコンテナ名、もしくはコンテナIDを調べる

+ $ docker commit <コンテナ名 | コンテナID> <新規リポジトリ名 | 既存リポジトリ名:タグ名>
  - 新規リポジトリ名もしくはタグ名で変更したDockerイメージの内容を保存する


## 抜けたDockerコンテナへの復帰

+ $ docker attach <コンテナ名 | コンテナID>
  - 指定したコンテナの中に入り、bash等で操作を再開する
【WIP】Cloud at Costの個人的なメモ

# メモ
- 個人的なメモです。
- [CloudatCost](www.CloudatCost.com)はカナダのホスティングサービス。
    - サーバ代金を1度支払えば、ホスティングサービスが終了するまで使える。
    - 60%から80%の割引セールが頻繁にある。
    - 稼働率99.99%らしいけど、価格相当。



# よくある罠(サーバーを作る前)

## [管理パネル](https://panel.cloudatcost.com/)につながらない
- その日は、あきらめて寝る。
- セールが開催された直後はダメなこと多い。

## Failed: Cant Get IP from DC-2. Please Try again.
- DC-2用のIPアドレスが枯渇中。
    - 2~3日で解消するらしい。
- DC-3にサーバを構築する。
- あきらめて寝る。

## "Install Pending"
- Your server is getting ready to be built. This process should start in a few seconds.
    - あなたのサーバは準備中。この処理は数秒で終わるはず。
- 実際には……
    - VPSを作成するデータセンター(DC-2 / DC-3)によって、構築される時間がかなり違う気がする。
    - Black Fridayのセールまでは、DC-2だと5分もしないでVPS作成されたけど、2016/11/27現在、かなり待たされる。
    - DC-3だと、Black Fridayのセール前は24時間くらいまたされた感。セール後は、、、いつ用意されるんだかわからない。
    - 構築できるまで、あきらめて寝る。



# よくある罠(サーバーを作った後)

## ネットワークにつながらない。
- コンソールからrootでログインして、アップデートするかーっとおもったら各種の更新コマンドが失敗する。
- 管理パネルのサーバーの"Modify"→"Network Test"をして状態をしらべる。
    - 各種ポイントからのテストが「Success」なら大丈夫
    - 「failed」とかの場合、24時間くらい待てば回復するらしいけど、待てども回復しないこともある(というか、回復しない)
    - 待っても無駄な時間になってしまうことがおおいので、failなら、そのサーバーはあきらめて捨てる(Delete server)


## Safe Mode？
- 自動的に7日後にシャットダウンされる安全機能。初期設定だとON。
- 勝手にシャットダウンされるのは安全かどうかは、おいておいて、"Modify"→"Change Run mode"で切り替え可能。


# 動くサーバを手に入れるまで
1. サーバを作成。
2. "Failed: Cant Get IP from DC-2. Please Try again.
"   
→ あきらめて寝る、次の日にチャレンジ。
3. "Install Pending"   
→ 5分くらい待って反応がなければ、あきらめて寝る。朝起きたら、チャレンジ
4. サーバ構築されたっぽい？
5. "Network Test"   
→ failなら、サーバを削除。1に戻る。
6. Successなら「おめでとう！動くサーバを手に入れた！」的なゴール。
Rails Tutorialのsample appがHerokuにデプロイできなかった理由。

Rails Tutorialを第5章まで進めた時、今更ながらHerokuにデプロイできていなかったことに気付き、そこからハマりにはまったので書き残します。

##**状況**

```
remote: -----> Detecting rake tasks
remote: sh: 2: Syntax error: Unterminated quoted string
remote: sh: 2: Syntax error: Unterminated quoted string
remote: !
remote: ! Could not detect rake tasks
remote: ! ensure you can run `$ bundle exec rake -P` against you
r app
remote: ! and using the production group of your Gemfile.
remote: ! rake aborted!
remote: ! NoMethodError: undefined method `web_console' for #<Rails::Application::Configuration:0x00000000>
```
何度デプロイを試みてもこんな感じでエラーになる。

##**原因と対処**
###原因1 gemのweb_console
自分ではいじっていない部分だったので、戸惑いと「見慣れない部分は見たくない」と思って目をそらしていましたが・・・

このエラーはRailsをproduction環境で動かす時に出ることがあるようで、Gemパッケージのweb_consoleに関する設定が`config/application.rb`や、`config/initializers`ディレクトリ内に記述されている場合に起こります。
私の場合は

```ruby:config/application.rb
class Application < Rails::Application

  config.web_console.development_only = false
end
```
となっていました。
通常、Gemfileではweb_consoleをproduction環境で使用しないよう設定されているためにここでエラーが発生するとのこと。

###対処
上記のようなディレクトリやファイルにあるweb_consoleの設定に関する記述を、`config/environments/development.rb`に移動します。

```ruby:config/environments/development.rb
Rails.application.configure do

  config.web_console.development_only = false
end
```

###原因2 コミットしてない
こちらはいかに私がGitやHerokuについて理解していないかですが・・・
原因1の対処はしていたのに何度デプロイしても失敗したので、一時「これが原因じゃなかったのか」と思っていました。
でももっと根本的なこと。コードを変更したままコミットせずに`$git push heroku master`をしていたのです。

###対処
対処も何もないのですが・・・

```
$git commit -am "hogehoge"
$git push
$git push heroku master
```

##**まとめ**
以上でやっとのことデプロイできました。
「見たくない」とか、コミットしてないってとこでかなり無駄な時間を費やしてしまいました・・・
でも未だ理解は不十分です。コミットしただけで良いのか、それともリモートへのpushも必要なのかわかっていません。
今はRailsを覚えることに集中しているので、チュートリアルが終わったらこちらの仕組みについてもきちんと勉強したいです。

参考にさせていただきました。
原因1
https://www.oiax.jp/books/rails4book/undefined_method_web_console.html
原因2
http://koulog.hatenablog.com/entry/2015/11/19/090000
OpsWorks から ECS に乗り換える理由

trippieceでは2014年末頃からレガシーなEC2からOpsWorksに移行しています。
前提条件としてインフラ専属エンジニアが現時点で社内に存在せず、兼任であるため管理サーバーなどの監視、運用工数がほとんど、もしくは全くかからないで、管理サーバーなどを自前で立てないで済む選択肢に限っています。
かっちりとした構成管理、リソースに依存した設定を入れなくて済むのでスケールアップが自由自在、githubにプッシュするだけのお手軽デプロイオートメーションなど今までの面倒な手順や操作ミスから解放されるという、非常に当時は画期的な導入効果がありましたが約2年の運用期間を経てDocker運用のノウハウが一般的に十分蓄積され成熟してきたことと、OpsWorksやChefに関連する以下の問題が顕著になり移行を計画し始めました。

- 新規インスタンスの追加に相当時間がかかる (構成によっては20分以上) ためトラフィック急増に対応できない。
- 起動できなくなるケースが少なからずある。(Chefバージョンの過渡期で、依存しているCookbookがさらにその中で依存しているCookbookの対応バージョンが変更になってしまったり、依存しているパッケージファイルが削除されたり、一時的な障害でダウンロードに失敗するなど) また、失敗した場合に対応できるエンジニアが非常に限られる。
- 各インスタンスの実行時間に差が出てしまうのでデプロイ時の細かい制御(オーケストレーション)を入れるのに向いていない。
- 長時間実行非同期タスク(Celery Task)が走っている最中にデプロイを流してしまうとデプロイがブロックされてしまうのと、タスク終了後にCeleryプロセスがダウンしてしまう。

上記とは別に、運用上の問題としてChefレシピを弄って簡単に構成拡張ができるが故に一つのスタックに時間と共に色々詰め込んでいってしまい、結果としてモノリシックなシステムとなってしまっていました。これにより複数インスタンス間の同期処理を自前で書かなければいけなかったり、一度実行すればよいものが複数回実行しデプロイ時にパフォーマンスダウンする事象も起きていました。

作り込み次第でこれら問題が軽減できることがありますが、ここで頑張ってOpsWorksに拘るよりも上記のような問題を根本的に解決できる一つの方法であるECSへと段階的に移行することにしました。
まずは定期実行タスクのトリガーとその実行処理をモノリシックなOpsWorksから切り離し、ECSとRunDeckに置き換えます。その後のフェーズでWebやAPIその他をECSに移行する計画です。

以下は定期タスクをECSに載せ替えた場合のメリットです。

- 起動が劇的に速い
- docker imageをECR(EC2 Container Registry)にアップロードしておけば起動しなくなることはまずない
- docker imageが更新されても実行中の定期(長時間実行)タスクを終了する必要はほとんどなく、既存タスクはそのままで、新しく起動するタスクは新しいコードで動くというシームレスなデプロイが可能
- 1タスク1コンテナなのでタスクの独立性が高い
- ハードウェアリソースの管理も自動で行ってくれるためリソース利用効率が高い

その他、弊社特有のメリットとして実行スケジュールをコードではなくWebUIでいつでも変更、逐次実行ができるようになり柔軟性が格段にあがりました。

次回は具体的な定期タスクのECS移行について投稿する予定です。
**[投稿しました](http://qiita.com/amrael/items/6909e3fcc918b84ac395)**

--
trippieceではエンジニアを募集しています。
https://www.wantedly.com/projects/38518
5分でできるXamarin で IOS WebViewApp

VS for MACを入れたので早速試してみたいと思います。

# 1. 前提条件
1. Visual Studio for MACのインストール
2. XCodeのインストールをエミュレーターの起動確認


[ドキュメント](https://developer.xamarin.com/recipes/ios/content_controls/web_view/load_a_web_page/)

# 2. ウィザードよりテンプレートを選択
![スクリーンショット 2016-11-27 20.28.16.png](https://qiita-image-store.s3.amazonaws.com/0/89997/dbf20b16-a20c-8e7c-9b28-fb25e8d49b20.png)

# 3. WebViewController.csをいじる
ViewDidLoad()内でローカルのhtmlを読み込んでいる部分をリモートのURLを読み込むように変更します。

![スクリーンショット 2016-11-27 21.00.35.png](https://qiita-image-store.s3.amazonaws.com/0/89997/73573d9d-a0f2-cca2-1610-e1e7ca7a482e.png)

# 4. ついでにデフォルトサンプルの中身確認
1. [View内のRazorView.cshtml](https://developer.xamarin.com/guides/cross-platform/advanced/razor_html_templates/)

RazorHTMLはASP向けのテンプレートエンジンみたいです。
Urlロード時のイベントをオーバーライドする所などは、ネイティブと同じみたいですね。

2.WebViewController.cs
UIViewControllerを継承したクラスです。
partialとなっているのが.NETっぽいですね。
WebViewController.designer.csというのがあります。
その中で、[UIKit.UIWebView](https://developer.xamarin.com/api/type/UIKit.UIWebView/) WebViewを生成してます。

3.[Models内のモデル](https://codezine.jp/article/detail/5549)
[こちら](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor)のページに細かい記述方法がまとまっています。
Ruby FFIとCUDA CでRubyからGPUを使う

この記事は[Ruby Advent Calendar 2016](http://qiita.com/advent-calendar/2016/ruby)の6日目です。

rubyでも、GPU使いたいということで、 [Ruby FFI](https://github.com/ffi/ffi) を使ってCUDA Cで作ったShared Libraryを実行する方法について試してみました。

# 前提

- ruby 2.3.1
- ffi v1.9.14
- CUDA 8.0 (Cuda compilation tools, release 8.0, V8.0.44)

かんたんにGPUを使うことだけを考えて、GPUでHello Worldと表示するプログラムを作ってみます。

# CUDAのShared Libraryを作る

## ヘッダファイルの作成

Shared Libraryとして、実行するメソッドに`extern "C"`とつけておく。

```c:hello.h
#ifndef _HELLO_H
#define _HELLO_H

extern "C" void helloGPU();

#endif // _HELLO_H
```

## 本体ファイルの作成

GPU側で"Hello World from GPU!!\n"と10回出力するコードを作成

```cu:hello.cu
#include "hello.h"
#include <stdio.h>

__global__ void helloFromGPU()
{
    printf("Hello World from GPU!!\n");
}

void helloGPU() {
    helloFromGPU<<<1, 10>>>();
    cudaDeviceReset();
}
```

## Shared Libraryのコンパイル

ターミナルから、以下のコマンドでコンパイルすると、libhello.soというファイルが作成される。

```bash
$ nvcc --ptxas-options=-v --compiler-options '-fPIC' -o libhello.so --shared hello.cu
```

これで、CUDA側の必要な作業は完了。次に、Ruby FFIを使って、作成したShared Libraryを呼び出すコードを作成する。

# Ruby FFI

## モジュールを定義

[Ruby FFIのExamples](https://github.com/ffi/ffi/wiki/Examples)に習って、モジュールを定義します。

```ruby:hello.rb
module Hello
  extend FFI::Library
  ffi_lib "libhello.so"
  attach_function :helloGPU, [], :void
end
```

`ffi_lib`の引数に、先ほどコンパイルしたShared Libraryファイルを記載。

`attach_function`の第一引数に、呼び出す関数の名称をSymbolで記載、第二引数は、呼び出す関数の引数の型を指定しますが、今回は引数がないので空にします。第三引数には、戻り値の型を指定します。今回はvoidなので、`:void`としていします。

## RubyからFFI経由でCUDAの関数を実行する

用意したHelloモジュールを実行してみます。

```ruby:main.rb
require 'ffi'
require_relative './hello.rb'

Hello.helloGPU
```

先ほどのモジュールの`attach_function`で定義したメソッドを実行するコードです。コンソールから、実行してみます。

```bash
$ ruby main.rb
Hello World from GPU!!
Hello World from GPU!!
Hello World from GPU!!
Hello World from GPU!!
Hello World from GPU!!
Hello World from GPU!!
Hello World from GPU!!
Hello World from GPU!!
Hello World from GPU!!
Hello World from GPU!!
```

GPUスレッドが10個生成されて、`Hello World from GPU!!`が10回プリントされました。

# 結論

ニューラルネットワークブームで、かなり注目されているCUDAをRubyから実行できることが確認できました。

CUDAには、オフィシャルのライブラリとして、

- cuDNN
- cuFFT
- cuSPARSE
- cuBLAS

など、CPUで実行すると時間がかかりそうな処理をGPUで実行するのに最適化されたライブラリが用意されているので、必要なケースがあれば使ってみてはどうでしょうか。
UIをロックさせてプログレスダイアログバーを出したい。 #Android

キャンセル機能をfalseにして、プログレスダイアログを出します。

```java:MainActivity.java

ProgressDialog progressDialog;
private void showProgressDialogWithTitle() {
    progressDialog = new ProgressDialog(this);
    progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    progressDialog.setCancelable(false);
    progressDialog.setTitle("少々お待ち下さい。");
    progressDialog.setMessage("画像をアップロード中です。");
    progressDialog.show();

    // このプログレスを閉じたい場合は以下のメソッドを呼び出すだけ
    //progressDialog.dismiss();
}

```
戻るボタンでDrawerLayoutを閉じたい　#Android #Java

通常、戻るボタンを押すとActivityが終了してしまいます。DrawerLayoutが開いている時はActivityを終了させず、DrawerLayoutのみを閉じたい場合は以下のように実装します。

```java:MainAcvity.java
DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

@Override
public void onBackPressed() {
　　if(mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
  　　　//drawer is open
     mDrawerLayout.closeDrawer(Gravity.LEFT);
　　}else{
     super.onBackPressed();
}
```
OpenAI GymでゲームMsPacman(ミズ・パックマン)をやると初期に操作を受け付ない時間がある?

![_Users_taki_atari-rl_run_py.png](https://qiita-image-store.s3.amazonaws.com/0/118618/a542143c-a45e-b730-c8d3-933bda1ea82a.png)


## 問題と現時点の解決策

### 問題
OpenAIでゲームMsPacman(ミズ・パックマン)をやると、初期に操作を受け付けない時間がある。

### 現時点の解決策
エピソードフレーム番号258まで処理を行わず（以下処理参照）、それ以降に操作する。

（自分の環境でエピソードフレーム番号258番前後より前までは操作を受け付けるが、それより前に操作を入れても操作を受け付けない。
自分のソースにバグが有るのかもしれないし、こうやらないといけないのかもしれない。）



```python
ep_frame_number = 0
while ep_frame_number < 258:
    observation, _, _, _ = gym_env.step(0)
    ep_frame_number = float(gym_env.ale.getEpisodeFrameNumber())
```

## 環境
Python 3.5.2 :: Anaconda 2.5.0 (x86_64)
macOS Sierra 10.12.1

## 経緯1:機械学習を使わずにどれぐらいのポイントが取れるか実施したらreward(得点)が取得できなかった。
OpenAIでMsPacmanをやろうと思い、まず機械学習を使わずにどれぐらいのポイントが取れるか確認したところ、初めの方のreward(得点)がすべて0になっている。
Pacmanは少しでも動けばポイントが得られるので、これはおかしい。
以下でactionとそれに対応するreward(得点)をcsv出力することで確認。
https://github.com/tflare/atari-rl



デバックしたところ、エピソードフレーム番号258番前後より前にactionを送っても
操作を受け付けていないことがわかった。
（エピソードフレーム番号の取得は以下参照）


```python:エピソードフレーム番号の取得
gym_env = gym.make(game_name)
ep_frame_number = float(gym_env.ale.getEpisodeFrameNumber())
```

## 経緯2:他のソースに同様の処理がない


最初は初期に操作を受け付けていない期間があると思い、
他の人のコードで同様の箇所がないか確認を行った。
しかし、初期状態をランダムにするために"NOOP"を複数回やっている処理があるぐらいで
同様の処理（以下を5回実行）を行っても、操作を受け付けない状態が続いた。

```python
gym_env = gym.make(game_name)
action = 0 # 0 : "NOOP"
gym_env.step(action)
```

## 経緯3:OpenAIの実行処理がランダムで行われるためstepを複数回呼び出しても安定しない
そこで"NOOP"の処理を80回程度実施したところ、うまく行くことがわかったが、
何回かやったところ、うまくいかない時があることがわかった。
（処理前に動いてしまう　0："NOOP"の場合は初期で左の入力があるため、左に動く）

調べたところ、OpenAIではactionを受取、stepを実施する際に
ランダムな回数繰り返し実施する（以下コード参照）ため、
この回数によってエピソードフレーム番号258番前後に行ったり行かなかったりするため安定しなかったようだ。

```python:OpenAIの処理を一部抜粋、加工
self.frameskip = (2, 5)

if isinstance(self.frameskip, int):
    num_steps = self.frameskip
else:
    num_steps = self.np_random.randint(self.frameskip[0], self.frameskip[1])
for _ in range(num_steps):
    reward += self.ale.act(action)
    
```

## 情報提供のお願い
現在は上記で行っているが、何か間違いがあるのではと考えています。
もし何か情報をお持ちでしたら、コメントを頂けるとありがたいです。
Railsログをキレイに整理してプロファイルリングするGem

Railsで開発していく上で、パフォーマンスのチューニング作業はついて回ります。
パフォーマンスをよくする上でよく使用されているのがrack-mini-profiler、bullet等のgemだと思います。

開発期間が長く、肥大化してきたプロダクトだと１リクエストごとに長い長いログが出力され、クエリを丹念に目で追う作業は半ばめまいを覚え、目の疲労が困ぱいしてきて時々、プログラムから離れて、どこか遠くの島に行きたくなるものです。

そんな苦しみから少しでも楽になりたいのでログを綺麗に整理する[gem](https://github.com/fukumone/rails_log_profiling)を作りました

詳しい使用方法は下記のサイトに譲りますが、簡単な使用方法を解説しようと思います
https://github.com/fukumone/rails_log_profiling

## 簡単な使用法

##### 1： gemfileに下記を記入

```
gem 'rails_log_profiling', :group => "development"
```

基本的に開発環境がdevelopmentで使うのを想定して作成しています

##### 2： bundle install後にconfig/development.rbに下記のコードを追加

```
# クエリのプロファイリングを有効にします
Rails::Log::Profiling.query_profiling_enable = true
# viewのプロファイリングを有効にします
Rails::Log::Profiling.view_profiling_enable = true
```

パフォーマンスよくする上で、開発者が気になるのはクエリのログや、viewのレンダリングかと思います
なのでrails_log_profilingは主要な二つの機能に分けました

- クエリをプロファイリングする
- viewレンダリングをプロファイルする

##### 3： Railsサーバーを起動

専用のログが作成され、記録されます。
クエリのプロファイリングに関してはlog/rails_log_query_profiling.logに記録されます
***Identify Query Location: xxx***は実際にクエリが実行されたファイルの箇所を検知します、[オプション](https://github.com/fukumone/rails_log_profiling#configuration)でメソッドの呼び出し状況を深く探索することができます

出力例

```
$ tail -f log/rails_log_query_profiling.log

# output
PostsController#index

total query count: 2, total query time: 26.6ms

  1: Articles Load (21.7ms)  SELECT  `articles`.* FROM `articles` ORDER BY `articles`.`id` ASC LIMIT 1
  Identify Query Location:
    /Users/fukumone/private_repo/rails_test/app/controllers/posts_controller.rb:9:in `index'

  2: Post Load (4.9ms)  SELECT `posts`.* FROM `posts`
  Identify Query Location:
    /Users/fukumone/private_repo/rails_test/app/views/posts/index.html.erb:16:in `_app_views_posts_index_html_erb__3476269730194822991_70352062040540'
```

viewのプロファイリングに関してはlog/rails_log_view_profiling.logに記録されます
N+1 partial renderingの対策として、重複するpartialファイルに対してはpartial viewファイルの下に***rendering page count: xxx***と記述されます

出力例

```
$ tail -f log/rails_log_view_profiling.log

# output
Parent: 65.5ms
  /Users/fukumone/private_repo/rails_test/app/views/posts/index.html.erb
Children: total time: 6.9ms, partial page count: 3, total rendering page count: 12
  5.4ms: /Users/fukumone/private_repo/rails_test/app/views/articles/_show.html.erb
    rendering page count: 10
  0.8ms: /Users/fukumone/private_repo/rails_test/app/views/articles/_show_3.html.erb
  0.7ms: /Users/fukumone/private_repo/rails_test/app/views/articles/_show_2.html.erb

```

どれか一方の設定でも利用可能で、rails_log_profilingはdevlopment.rbに設定がないと初期の段階ではなにも行いません。

rails_log_profilingは優れたアイデア、機能が入った以下のgemに影響を受けています

- [rack-mini-profiler](https://github.com/MiniProfiler/rack-mini-profiler)
- [Activerecord::Cause](https://github.com/joker1007/activerecord-cause)
- [Bullet](https://github.com/flyerhzm/bullet)
線形符号の定義を解説する

## はじめに
テスト勉強も兼ねて、情報通信に用いられる2元線形符号の定義を解説します。
線形符号は情報の符号化と復号化が容易であるという特徴を持っており、通信の分野では基本的な符号という扱いになっているようです。
線形符号のうち、特に0と1のバイナリで符号を表現するものは2元線形符号と呼ばれます。

2元線形符号の定義は次のとおりです。  
__符号Cが2元有限体$\mathbb{F}_2^n$の部分集合で表現され、かつその符号が線形空間をなすものを線形符号と呼ぶ__
  
言葉が難しいので解説します。

## 有限体
有限体という単語が聞き慣れないという方もいるかもしれませんが、今回扱う有限体は、みなさんが知っている__ビット__と同じものです。

有限体とは数の集合のことです。特に今回扱う2元有限体$\mathbb{F}_2$は0と1で構成される集合です。

```math
\mathbb{F}_2 = \{0, 1\}
```

また、集合の要素についての四則演算は「演算の結果を2で割ったその余り」になります。

### 四則演算
$\mathbb{F}_2$の上では、四則演算の結果は「演算の結果を2で割ったその余り」となります。
例えば足し算だとこんな感じです。

```math
\begin{align}
0 + 0 &= 0  \\
0 + 1 &= 1  \\
1 + 0 &= 1  \\ 
1 + 1 &= 0  \\
\end{align}
```

整数上では$1 + 1 = 2$ですが、$\mathbb{F}_2$上では「演算の結果を2で割ったその余り」が演算の結果となるため、$1 + 1 = 0$となります。これは繰り上がりを考慮しないビットの可算と同じですね。
引き算の結果は足し算の結果と同じになります。

```math
\begin{align}
0 - 0 &= 0  \\
0 - 1 &= 1  \\
1 - 0 &= 1  \\ 
1 - 1 &= 0  \\
\end{align}
```

掛け算はこうなります。

```math
\begin{align}
0 \times 0 &= 0 \\
0 \times 0 &= 0 \\
1 \times 0 &= 0 \\
1 \times 1 &= 1 \\
\end{align}
```

割り算は0があってちょっとややこしいのでここでは考えません。

## 有限体のベクトル
有限体のベクトルは、有限体の要素を並べてベクトルにしたものです。
例えば2元有限体の要素を3つ並べて作られるベクトルの集合は次のようになります。

```math
\mathbb{F}_2^3 = \{
    (0 0 0),
    (0 0 1),
    (0 1 0),
    (0 1 1),
    (1 0 0),
    (1 0 1),
    (1 1 0),
    (1 1 1)
\}
```

要はビット列のことです。
$\mathbb{F}_2^3$の上で成り立つ四則演算は繰り上がりを考慮しないので、例えばベクトルの足し算は

$$(0 0 1) + (0 1 1) = (0 1 0)$$

というふうになります。

## 線形符号とは
### そもそも符号とは
ここでは2元ブロック符号という符号を扱います。
2元ブロック符号とは、要は$\mathbb{F}_2^n$の部分集合で構成される符号、もっと大ざっぱに言ってしまえば、決まった長さのビット列で表される符号のことです。
例えば長さ3の2元ブロック符号は

$$C_1 = \\{(0 0 1), (0 1 1), (1 1 0)\\}$$

長さ4の2元ブロック符号には

$$C_2 = \\{(0 0 0 0), (0 0 1 1), (1 1 0 0), (1 1 1 1)\\}$$

といったものがあります。

### 2元線形符号とは

2元線形符号とは、「符号Cが$\mathbb{F}_2^n$の部分集合で表現され、かつその符号が線形空間をなすもの」です。

線形空間とは、$k$個の線形独立なベクトル$\mathbf{e}_1, \mathbf{e}_2, ..., \mathbf{e}_k$によって張り出される空間のことを言います。

例えば$\mathbb{F}_2^3$において、2本の線形独立なベクトル

```math
\mathbf{e}_1 = (0 1 1) \\
\mathbf{e}_2 = (1 1 0)
```

によって張り出される空間$V$は

```math
\begin{align}
V &= \{ \\
  &  0 \times (0 1 1) + 0 \times (1 1 0), \\
  &  0 \times (0 1 1) + 1 \times (1 1 0), \\
  &  1 \times (0 1 1) + 0 \times (1 1 0), \\
  &  1 \times (0 1 1) + 1 \times (1 1 0) \\
\} \\ \\
V &=
\{
    (0 0 0),
    (1 1 0), 
    (0 1 1), 
    (1 0 1) 
\}
\end{align}
```

となります。

符号$C$が$V$と同じものであるとき、$C$は$\mathbb{F}_2^n$の部分線形空間をなしています。すなわち$C$は2元線形符号であると言えます。
Botkitで画像ファイルをslackにアップロードする

botkitでのファイルのアップロードには
`bot.api.files.upload` を用いる。

```javascript
fs.readFile('hoge.png', function(err,data){
  if(err) throw err;

  bot.api.files.upload({
                    content: data,
                    filename: 'hoge.png',
                    channels: message.channel
                },function(err,res) {
                    if (err) console.log(err)
                })
});
```

ただし上記の方法で画像ファイルをアップロードしても
`plain text` としてアップロードされてしまう。

画像ファイルでは以下のように `content` ではなく `file` にstream を
渡してあげる必要がある。

```javascript
bot.api.files.upload({
                    file: fs.createReadStream('hoge.png'),
                    filename: 'hoge.png',
                    channels: message.channel
                },function(err,res) {
                    if (err) console.log(err)
                })

```

下記コミットにて修正された模様。
https://github.com/howdyai/botkit/commit/2bde51ff5326ccc44b8764ecc3110dac6696ef6c

`content`にデータを設定すると通常のformとしてapiを叩くが、
`file`にデータを設定するとMultipart form としてapiを叩くようにしているよう。

参考
-----------
[SlackのBotkitでファイルをアップロードする方法](http://qiita.com/nobukatsu/items/e6ba8d9299816e1a503e)
phpdbgでコンパイル後のopcode列を確認する方法

#　準備

今回はPHP 7.0.0で実装されたphpdbgの-pオプションを使ってopcode列を表示してみます。筆者はPHP 7.0.13で実験しました。

もし`php.ini`でxdebugを読み込んでいたら外してください（余計なopcodeが付くのを防ぐため）。

# opcode列の表示

まずopcode列を表示したいPHPプログラムを用意します。

```php:foo.php
<?php
foo(8);
function foo($i) {
    $i++;
    var_dump($i**3);
}
```

次にコマンドラインから次のように実行。

```
$ phpdbg -p'*' foo.php
```

すると下記のようにopcode列が表示されます。

```
function name: (null)
L1-7 {main}() /private/tmp/foo.php - 0x110c6c0a0 + 5 ops
 L2    #0     INIT_FCALL_BY_NAME                           "foo"
 L2    #1     SEND_VAL_EX             8                    1
 L2    #2     DO_FCALL
 L3    #3     NOP
 L7    #4     RETURN                  1

function name: foo
L3-6 foo() /private/tmp/foo.php - 0x110c65600 + 8 ops
 L3    #0     RECV                    1                                         $i
 L4    #1     POST_INC                $i                                        ~0
 L4    #2     FREE                    ~0
 L5    #3     INIT_FCALL              112                  "var_dump"
 L5    #4     POW                     $i                   3                    ~1
 L5    #5     SEND_VAL                ~1                   1
 L5    #6     DO_ICALL
 L6    #7     RETURN                  null
[Script ended normally]
```

また、下記のようにすればOPcache適用後のopcode列を確認することもできます。

```
$ phpdbg -dopcache.enable_cli=1 -p'*' foo.php
```

```
function name: (null)
L1-7 {main}() /private/tmp/foo.php - 0x10d507ca0 + 4 ops
 L2    #0     INIT_FCALL              128                  "foo"
 L2    #1     SEND_VAL                8                    1
 L2    #2     DO_FCALL
 L7    #3     RETURN                  1

function name: foo
L3-6 foo() /private/tmp/foo.php - 0x10d507b70 + 7 ops
 L3    #0     RECV                    1                                         $i
 L4    #1     PRE_INC                 $i
 L5    #2     INIT_FCALL              112                  "var_dump"
 L5    #3     POW                     $i                   3                    ~0
 L5    #4     SEND_VAL                ~0                   1
 L5    #5     DO_ICALL
 L6    #6     RETURN                  null
[Script ended normally]
```

PHP 7以降でPHP本体がかなり最適化をするようになったとはいえ、OPcacheの最適化もちゃんと仕事してるんだなーなんてことがわかったりします。
良くない設計指針：include  "mycode.h"の指定にも設定用の変数を利用する

良くない設計指針：

C++で開発している際に、ソースコードのファイルの数が増えてくると、コードの管理が込み入ってくる。自分たちが開発しているソースコードのヘッダファイル(通常""で囲む)を相対パスで指定するのが次第にこみいったものになってくる。特に、ある一式と別の一式とで同じソースコードを共用させたいと思うと、コンパイラの設定用の変数を利用して、次のようなヘッダファイルへの相対的な配置情報を含めない方がいいかもと思うかもしれない。

```
#include "../someModule/module_A.h"
#include "../someModule/module_B.h"
#include "../nestedModule/moduleC/module_C.h"
```

そこで、CMakeLists.txtに記載してCMakeでMakefileやVisual Studioの設定を作ることができる。


CMakeLists.txt中の記述

```
include_directories(/path/to/include)
```


C++のソースコード中の記述

```
#include "module_A.h"
#include "module_B.h"
#include "module_C.h"
```

このようにして、C++のソースコード*.cpp や*.h、*.hppの中に、ユーザーコードのヘッダファイルがどのようなフォルダ構成で置かれているかという記述をしないことも可能ではある。

しかし、このようにしてはならない。
以下の指摘を受けたように、「includeの指定には設定用の変数を利用しよう」というのはよくない設計指針だということに同意します。

「よく設計されているものなら特に、名前空間とディレクトリ構造は一致しています。」
このように書き換えていかなくては。
Reekのドキュメント更新プルリクエストをマージしてもらった

Rubyスクリプトの「コードの臭い」を警告してくれる[Reek](https://github.com/troessner/reek)というツールがある。[メソッドが長過ぎる](https://github.com/troessner/reek/blob/master/docs/Too-Many-Statements.md)とか、[変数名の意図がわかりづらい](https://github.com/troessner/reek/blob/master/docs/Uncommunicative-Variable-Name.md)とか、多様な「臭い検出器」が備わっていて、とても便利だ。

とはいえ、多くの人が気にならない臭いの検出器はさすがに備わっていない。臭いに敏感な人は、自分で作るしかないのだ。かくいうぼくにも人一倍気になる臭いがあるので、Reekの勉強がてら自作してみようと思い立った。

手始めに「[How to write new detectors](https://github.com/troessner/reek/blob/b3b378688388f18caf6794201aec7a42a4ccbd9c/docs/How-To-Write-New-Detectors.md)」を読んでみた。すると、すぐにコードとの齟齬に気づいた。[このコミット](https://github.com/troessner/reek/commit/c9bea17becb5763532d3a7117a3bc62aaf868b04)によるリファクタリングがドキュメントに反映されていないらしい。

これはオープンソースソフトウェアに貢献するチャンスだ。さっそくforkして、[変更点のプルリクエスト](https://github.com/troessner/reek/pull/1148)を送った。送ってから2時間あまり経った後、「Can't believe we missed that! Thanks a lot」とのコメントとともに、マージしていただけた。ありがたい話だ。

* * *

ちなみに、ぼくが気になっている臭いは「一部のインスタンス変数しか使わないインスタンスメソッド」である。興味のある方は、昔のブログに書いた「[何をクラス分割の指針とすべきか](http://d.hatena.ne.jp/IwamotoTakashi/20090530/p1)」を参照されたい。

Reekでいう「[Utility Function](https://github.com/troessner/reek/blob/master/docs/Utility-Function.md)」の延長線上にあるものだが、この臭いが気になる人はあまりいないと思う。首尾よく検出器が作れたとしても、プルリクエストは送らないだろう。
ffmpegのあれこれ

自分用メモ

#情報を表示
```shell-session
ffmpeg -i <input.mp4>
```

#動画と動画を連結する
```shell-session
ffmpeg -i <imput1.mp4> -i <imput2.mp4> -strict -2 -filter_complex 'concat=n=<動画数>:v=1:a=1' output.mp4
```
v=1　動画を連結する
a=1　音声を連結する

#iosで読み込めるmp4にする
```shell-session
ffmpeg -r 25 -i %03d.tif -pix_fmt yuv420p output.mp4
```

#指定秒数を切り出して動画を時間で分割する
```shell-session
ffmpeg -i <input.mp4> -t <秒数> -ss <開始時間> <out.mp4>
```

#フレームレートを変更する
```shell-session
ffmpeg -i <input.mp4> -r <fps> <output.mp4>
```

#動画から連番画像にする
```shell-session
#fpsを指定しなければ全フレーム
#動画のfpsが60で指定したfpsが30なら1フレームおき
ffmpeg -i <input.mp4> -vcodec <画像の拡張子> -r <fps> <image_%03d.png>
```

#連番画像から動画にする
```shell-session
ffmpeg -framerate <元のfps> -i <image_%03d.png> -vcodec libx264 -pix_fmt yuv420p -r <出力のfps> <output.mp4>
```

#サイズ変更
```shell-session
ffmpeg -y -i sample.mp4 -vf scale=320:-1  sample.out.mp4
```

#クロッピング
```shell-session
ffmpeg -i <input.mp4> -vf crop= <width> : <height> : <x> : <y> <output.mp4>
```

#映像と音声を合成する
```shell-session
ffmpeg -i <input_movie.mp4> -i <input_music.mp3> <output.mp4>
```

#映像を抜き出す
```shell-session
ffmpeg -i <input.mp4> -an -vcodec copy <output.mp4>
```

#音声を抜き出す
```shell-session
#ffmpeg -i <input.mp4>で音声のコーデックを調べる
ffmpeg -i <input.mp4> -vn -acodec copy <output.[指定のコーデック]>
```

#音声の拡張子を変える
```shell-session
ffmpeg -i <input.m4a> -ab <256k> <outfile.mp3>
```
仕事で開発する時に気をつけていること

# 仕事で開発する時に気をつけていること

### 何故この記事を書いたか
* 自分の備忘録として（気付きや指摘があれば更新する）
* 問題が発生した時のチェックシートとして
* 最低限これぐらいはやっておきましょうという指標として
* 仕事以外の開発でも何を決めるべきか、何を意識するべきかの目安として

### 大前提
* 開発者は自分で責任を取る権限は持っていない
  * なんかやらかしたら即共有しようね
  * 自分のミスを自分だけで取り戻そうとするのはただの自己満足

<!---->

- 体調が悪い時は無理して出勤しない
  - 大概の開発は数日遅れたところで何の影響もない
  - それどころか風邪等を巻き散らかすとネズミ講のように遅延が広がる

<!---->

* スケジュールの見積もりは自分が思った時間の倍掛かると考える
  * そもそも聞かれたとき以外は自分の思ったスケジュールを口外しない

<!---->

- やったことがないことや知らないことははっきり答える
  - 人に聞くのでも自分で調べるのでも時間が掛かるので

<!---->

* 繰り返しの作業や毎日やるようなことは出来る限り自動化する
  * ミスしやすいしミスに気づきにくいので自動化大事
  * 自動化出来ないならせめてテンプレート作ったりする

<!---->

- 休憩は積極的に取るか、一定時間ごとに取れるように工夫する
  - 集中している時は取りたくないかもしれないけど、一定時間のリセットは大事
  - そういう時は集中が途切れないように、次に何をするか等をメモして休憩する

<!---->

* 上記のうち一つでも出来ないことがある案件は早々に退散する
  * 給料が良くてもよく考えるべき、ストレスは人間の大敵
  * インターネットが使えない案件も同様
    * たまにあるけど凄まじく待遇が良い場合以外はよく考えるべき

***

### どんなことに気をつけるべきか
* どんな規約や決まりがあるか
  * 自分の常識は世間の常識ではない

<!---->

- 仕様書に載っていないことはあるか
  - 別紙だったりそもそも記載がない仕様が存在することがある

<!---->

* 開発環境や共通して使っているツールはあるか
  * 自分が普段使っているツールを使っていいかも合わせて確認

<!---->

- やるべきこと、やっていいこと、やってはいけないこと
  - 少しでも疑問に思ったら人に聞く

<!---->

* 人から聞いた話や自分が調べたことのメモを必ず残す
  * 紙ではなくPCのテキストやMarkdown等で残すこと
  * 紙は検索できない、仕事中はPCを起動しているはずなのでいつでも使えるはず
  * 紙で取ったメモやメールでの情報もPCのメモにまとめておく
  * TODOや何時から別の作業に移ったか等も残しておくと自分が困らない

<!---->

### コーディング時の気をつけるべきこと
* コーディング規約に沿っているかどうか
  * 規約よりも統一性が重視される場合もあるので要確認

<!---->

- 自分が実装しようとしている処理が他で実装されていないか
  - 実装されていればそれを利用するべき
  - ただし、本当に共通化してよいかはよく考えること

<!---->

* 条件分岐や繰り返しには必ずコメントを記載する
  * 何をやっているかよりも何のための処理かを重視する

<!---->

- 自分が分かりづらいと思う部分、忘れそうな部分にもコメントを記載する
  - あまり書きすぎると可読性が下がるので、基本は一行コメントで短めに

<!---->

* 変数の宣言は出来る限り使用する処理の直前にする
  * 宣言と処理が遠すぎると変数の内容が判断しにくくなる
  * ただし、変数の宣言はまとまっているのが好みという人もいる
  * 基本は規約に従い、記述がない場合や決まっていない場合はご参考まで

<!---->

- 変数の使い回しは安易にしない
  - 処理に使う変数、処理結果を格納する変数は別にすると分かりやすい
  - 一貫してひとつの値に対して処理を行っていく場合などは例外

<!---->

* 命名規則がある場合、命名規則に則っているか
  * 命名規則がない場合でも、他のソースコードとの統一を図る

***

### あとがき
* お金が貰えるからといってあんまり肩肘張らずにやろう
  * こっちも時間を提供しているので立場は対等だよ
  * でもやらなきゃいけないことはやらないと駄目だよ

<!---->

- 何か新しいことを覚える時は、今後に活かせるように習得しよう
  - 趣味で使えるように色々考えを巡らせておくと一石二鳥

<!---->

* お昼休憩等の時に散歩を兼ねたりするとリフレッシュになるよ
  * お弁当派も食べ終わったあとに外に出たりするのがいいよ
JSONをインタラクティブに掘り下げるコマンド jid 

## はじめに

私はCLIを利用することが多いのもあり、 [jq](https://stedolan.github.io/jq/) は今やJSONを利用する上は欠かせないツールとなっています。

ただ
・ jqのクエリを書くことなれるまで少し時間がかかる
・ クエリを書くことに慣れたとしても、初見だったりして **構造を把握していないJSONに関しては非常に手間** 
でみたいな感じだなと思っていました。

インタラクティブに jq のクエリを書いていければいいのに、と思ってツールを探しました(CLI限定で)が、あまり良さそうなものが見つかりませんでした。

そこで、Golangで何か作ってみたいのもあったので、作ったのが jid というツールです。

リポジトリ
[Github : simeji/jid](https://github.com/simeji/jid)

## インストール

以下からバイナリダウンロードしてzip解凍するだけです。
https://github.com/simeji/jid/releases

Macの場合はbrewで入れる事もできます。(thx. @ikeisuke )

```bash
brew install jid
```

また、以下のOSでは公式リポジトリに組み込んでくださっていたので、各OSのパッケージマネージャーを利用してインストールできます。
[![Packaging status](https://repology.org/badge/vertical-allrepos/jid.svg)](https://repology.org/metapackage/jid/versions)


## できること

タイトルの通り、パイプで標準出力のJSONを渡すことで、掘り下げていくことができます。
大体は、`TAB` と `ENTER` 押しておけばなんとかなることが多いです。
※ キーマップ一覧は[こちら](https://github.com/simeji/jid#keymaps)

絞り込んだ結果は標準出力されるので更にパイプすることも可能です。

デモ(カラー出力対応しました)
![jid](https://github.com/simeji/jid/wiki/images/demo-jid-main-640-colorize.gif)

aws cliの戻り値もJSONのものが多いので利用できます。

普段は `aws ec2 describe-instances` などと合わせて利用することが多いですが、IDなどを伏せるのが面倒だったので今回は `ec2 describe-availability-zones` でやってます。

![jid-with-awscli](https://github.com/simeji/jid/wiki/images/demo-jid-aws-640.gif)

## まだできないこと、したいこと

* jq のクエリではできる `|` や `[]` 、 `map` や `select` は実装されていません。
* もう少し設計を変えてプラガブルに他のフォーマットにも対応できるようにしたい。
* リファクタリングをもっとしたい。

## 開発の中で気づいたこと

1. 最初は２ファイルくらいに収まるでしょと思って作り始めた
2. 適当に思いついたベースで機能を追加していってしまっていた
3. 最初からテストを書いてなくて途中からさかのぼって書き始めた

あたりの話があって、後ほどデグレに気をつけながら機能追加していくのが、だんだんと辛くなってきたので最低限のテストは書き始めたが、もともとテスタブルなコードを意識していなかったので、書くのに辛くなりました。
すでに結構辛い。

あとから一部Interfaceとかにしたんですが、すごい中途半端な状態になった。
（とはいえ最初からがっちり設計はできなさそうだったんでどっかのタイミングで作りなおした方がいいんだろうなと思ってます）

ただ、振り返ってても思ったのですが、 **一番大変だったのはUI考えるところ** です。
サジェストやオートコンプリートのタイミングとかどこまでどうやって絞り込むんで、どうやって選択させるかとかは、何度か人に使ってもらって意見もらいながら変更し、という感じでやってました。
この辺はまた変更するかもしれません。

## さいごに

vimのネタも書きたい
Docker Swarm modeで動作しているコンテナのカーネルパラメータを変更する


# この記事でわかること
swarm modeで動作しているコンテナのカーネルパラメータを変更する方法

# 目的
Docker swarm modeで動作hしているコンテナのカーネルパラメータ
(具体的にはnet.core.somaxconn)の変更方法を整理する。

# なぜこの記事を書いたか

## swarm-modeがsysctlオプションに対応していない

Docker 1.12以降で、非swarm modeの場合は--sysctlオプションにより
カーネルパラメータをコンテナ毎に設定することが可能であるが、
swarm modeでは同等のオプションが設定されていない(ように見える)から。

## コンテナ起動後は/proc配下を書き換えできない
コンテナ起動後は/proc配下の(擬似?)ファイル群はread onlyでマウント
されており変更を受け付けないため。


# 手順
ここでは例としてnginxをあげている。
端的に述べると1.11以前の方法を用いることでコンテナ起動後にカーネルパラメータを
変更することが可能です。

## コンテナの起動

起動時にコンテナに/proc以下の適当なボリュームをマウントする。

```Bash:起動
docker service create --volume type=bind,source=/proc/sys/net/core/somaxconn,destination=/somaxconn --replicas 1 nginx
```

ポイントは
**/proc/sys/net/core/somaxconnを/somaxconnにマウント**
しているところです。

## コンテナでコマンドを実行


```Bash:コンテナのターミナルにはいる
sudo docker exec -it コンテナID/名前 /bin/bash
```

```Bash:somaxconnの値を確認
sysctl -a | grep "somaxconn"
 中略
net.core.somaxconn = 128
```

```Bash:somaxconnの値の書き換えと確認
echo "512" > /somaxconn
sysctl -a | grep "somaxconn"
 中略
net.core.somaxconn = 512
```

これで変更できた。

# 補足
このようにしてしまえば/wproc/sys配下のファイルに値を書き込むことで
様々なカーネルパラメータをもりもり変更できるようになる。
試行錯誤するぶんには良いかもしれない。

```Bash:まとめてマウント
docker service create --name nginx -p 80:80 --replicas 1 --mount type=bind,source=/proc/sys,destination=/wproc/sys nginx:latest
```



# 注意
仕組みとしてはnamespace周りが云々とのことだけれども、
そのあたりはあまり詳しくないので詳細には説明できない。

docker inspactから個別コンテナに与たカーネルパラメータの値を取得できるため、
非swarm mode(docker runで起動)コンテナの場合はsysctlオプションを使ったほうがよい。

# 参考文献
http://eagletmt.hateblo.jp/entry/2016/07/15/020443
Bool関連のStringをBoolに変換するExtension

#Purpose
Personal Note
あんまり使いませんが使用する機会があったのでとりあえずメモ

#Development Environment
- OS X El Captain 10.11.2
- Xcode Version 8.0

#Language
Swift 3.0

#Code
 ```swift
extension String {    
    func toBool() -> Bool? {
        switch self {
        case "TRUE", "True", "true", "YES", "Yes", "yes", "1":
            return true
        case "FALSE", "False", "false", "NO", "No", "no", "0":
            return false
        default:
            return nil
        }
    }
}

```
公開したくない情報をlocal.propertiesに定義しbuild.gradleに読み込む

GitHubでコードを公開する場合にAPI KEY等は一緒に公開したくありません。
一般的に `local.properties` は `.gitignore` に指定するため、ここに書いて読み込めば大丈夫だろうということで `local.properties` に定義した値を読み込む方法を記載します。

```local.properties
sdk.dir=/Users/hoge/Documents/Library/android-sdk
api_key= ...
```


```groovy:build.gradle
android {
    defaultConfig {
      def properties = new Properties()
      properties.load(project.rootProject.file('local.properties').newDataInputStream())
      // local.propertiesのapi_keyに定義されている値を読み込む
      def API_KEY = properties.getProperty("api_key")
      // ついでにbuildConfigFieldに定義
      buildConfigField("String", "API_KEY", "\"${API_KEY}\"")
    }
}
```

### 参考
[How do i read properties defined in local.properties in build.gradle] (http://stackoverflow.com/questions/21999829/how-do-i-read-properties-defined-in-local-properties-in-build-gradle)
UILabelのテキストの一部をハイパーリンク化

This post is about how to make hyperlink of words in UILabel.

#Purpose
Personal Note

#Development Environment
- OS X El Captain 10.11.2
- Xcode Version 8.0

#Language
Swift 3.0

#Code
```swift
    @IBOutlet weak var yourLabel: UILabel!
    var targetRect: CGRect = CGRect()
    // Hyper Link
    func setHyperLink(hyperlinkText: String){
        let text = "Hello Qiita Hello Law Hello Guys"
        
        yourLabel.backgroundColor = UIColor.clear
        yourLabel.textAlignment = .left
        
        let nsText = text as NSString
        let linkRange = text.range(of: hyperlinkText)
        
        let style = NSMutableParagraphStyle()
        style.alignment = NSTextAlignment.left
        
        let attributedString = NSMutableAttributedString(string: text, attributes: [ NSParagraphStyleAttributeName: style ])
        
        let firstStart = text.distance(from: text.startIndex, to: linkRange!.lowerBound)
        let firstLength = hyperlinkText.characters.count
        let firstRange = NSMakeRange(firstStart, firstLength)
        let boldFontAttribute = [NSFontAttributeName: UIFont.boldSystemFont(ofSize: 13.0)]
        
        // all text colour
        attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.black, range: NSMakeRange(0, nsText.length))
        // link colour
        attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.black, range: firstRange)
        attributedString.addAttributes(boldFontAttribute, range: firstRange)
        yourLabel.attributedText = attributedString
        
        yourLabel.isUserInteractionEnabled = true
        targetRect = getRect(str: yourLabel.attributedText!, range: firstRange, width: yourLabel.frame.width)
        yourLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapText(sender:))))
    }
    
    func getRect(str: NSAttributedString, range: NSRange, width: CGFloat) -> CGRect {
        let storage = NSTextStorage(attributedString: str)
        let container = NSTextContainer(size: CGSize(width: width, height: CGFloat.greatestFiniteMagnitude))
        let layoutManager = NSLayoutManager()
        layoutManager.addTextContainer(container)
        storage.addLayoutManager(layoutManager)
        container.lineFragmentPadding = 0
        let pointer = UnsafeMutablePointer<NSRange>.allocate(capacity: 1)
        layoutManager.characterRange(forGlyphRange: range, actualGlyphRange: pointer)
        return layoutManager.boundingRect(forGlyphRange: pointer.move(), in: container)
    }
    
    func tapText(sender: UITapGestureRecognizer) {
        if targetRect.contains(sender.location(in: sender.view)) {
            // add your action from here
        }
    }
```

However, this code is not compatible with Emoji... counting emoji characters is still problematic.
fastlaneを使ってハッピーになった話

新規のiOSアプリを作っていて、fastlaneを導入していろいろ捗ったという話です :smile: 

## どんなプロジェクトだったか

* 0からの新規開発アプリ
* iOS開発は自分一人


## fastlane導入前 :runner: 

* Deploygateで社内配布していた
* 1回配布するのに15分くらいはかかっていた(ほぼビルドの時間) :clock1: 
* 配布作業中はXcodeとかDeploygateをポチポチする必要があるので、他の作業がし辛い
    * 他の作業してるとarchiveが終了していたのに気づかず、そこで止まっていて先に進んでないとか良くあった
* bundle_idをstaging等で分けており、Deploygateでは2つ配布したかった (15分 x 2回)

たまにやるだけならいいんですが、週に数回くらいの頻度だったので結構な手間でした :raised_hand: :hand_splayed: :raised_hand: 


## fastlane導入後 :rocket: 

* archive→Deploygateアップロードまでをやってくれるレーンを作った :wrench: 
    * `bundle exec fastlane submit_deploygate_staging`とかを叩けば今まで手作業でやっていたことを全部自動でやってくれる
* stagingなどの環境別に配布できるレーンを作った
    * レーン別にconfiguration設定やinfo.plist書き換えなどをやっている
    * `bundle exec fastlane submit_deploygate_staging; bundle exec fastlane submit_deploygate_prod`とかを叩けば、後は自動で2つそれぞれビルドしてDeploygateに配布できるようになった！ :robot: 
    * 超楽ちん！


## 導入して良かったこと :smile: 

* 30分早く帰れるようになった :beer: 
    * 「今日の作業分をDeploygateにあげてから帰ろう :muscle: 」
        * 今まで: ぽちぽち30分くらい作業してから帰社
        * fastlane導入後: コマンド叩いて帰社
* ストアの申請も楽になった
    * レーンをちょっといじれば、そのままiTunesConnectへの申請用のビルド→アップロードもできる :apple: 
* 気軽に最新版を配布できるので、社内フィードバックが早くなった(はず)
    * ちゃんと見て無いけど、導入前後では配布頻度がだいぶ増えたと思う
* [badge](https://github.com/HazAT/badge)というfastlaneのアクションを追加して、stagingアプリのアイコンを区別できるようになった


## 悲しい所 :cry: 


* 手元のマシンでfastlaneを走らせている :computer: 
    * fastlaneを走らせている間(30分くらい)はXcodeさわれない(ソースコードいじれない)
        * なので、開発以外の作業をするはめになる
        * 帰る時とか昼休みとかによくfastlaneを走らせていた
    * 諸事情でCIを使えなかったが、CIを使えば解決
* レーンを作るのが大変だった :railway_track: 
    * 丸1日以上はかかったような...
    * 私の場合だとfastlane構築工数の元を取るのに1ヶ月以上かかる計算に


## 感じたこと

* ビルドとか配布を既に手動でやっている人向けの自動化ツールである
    * iOSの複雑なビルド/配布周りを隠蔽してくれるわけではない
    * fastlaneを使ってて何かエラーが起きたときに、結局ビルド/配布周りの知識がないと直せない
    * ビルド職人は引き続き必要か
        * とはいえfastlaneが壊れた時だけ必要になるのでだいぶ出番は減らせそう
* fastlane超便利最高
iPhoneが「検索中」のままになった場合の対処

iPhone5(au) + mineo simで運用していた端末が
ある日突然「検索中...」の表示になって通話やモバイル通信ができなくなった時に行った事。

ネット上を探してまず試す事とては

* 機内モードのOnOff
* iPhoneキャリアのアップデート
* 電源のOffOn
* SIMカードの抜き差し
* OSのアップデート
* ネットワーク設定のリセット
* すべてのコンテンツと設定をリセット

といった内容が書かれているが
今回はこれらでは解決せず、いよいよ端末故障か？
と諦めつつ最後に工場出荷状態にリセットを試みたら解決した。

**以下手順**

iPhoneをケーブルでMacに接続してiTunes起動
端末バックアップ
iPhoneを探すをOnにしている場合はOffにする
概要＞「iPhoneを復元」を行う。
何度かの再起動後復元が終わったら
バックアップしていた内容を復元
念のため mineo用プロファイルをインストール

これで解決した。
原因もきっかけも不明のままですが。