OmniAICreator/Qiita-1.07M huggingface dataset:
Homebrewメモ


- OSX 10.12 Sierra向けです。
- 気が向いたときに更新します。

## arj/unace/twintail/openhsp
- 私が見る限りFormulaがなさそうだったので入門を兼ねて作りました。
  - 161228: 「ツインテールdeエンジェルモード!!」のFormulaを追加しました。
  - 170224: OpenHSPのFormulaを追加しました。
- https://github.com/cielavenir/homebrew-ciel

## sbcl/rust/octave/io/fpc/upx
- 現在、問題なくインストールできます

## mozart
- https://github.com/caskroom/homebrew-cask/blob/e2c225f679d8895f93aa8ce1b6a8c3eb76080bf2/Casks/mozart.rb
- を、/usr/local/Homebrew/Library/Taps/caskroom/homebrew-cask/Casks/に放り込む。

## lftp
- `brew install homebrew/boneyard/lftp`
- cf: http://stackoverflow.com/questions/39633159/homebrew-cant-find-lftp-formula-on-macos-sierra

## valgrind
- (`brew install valgrind --HEAD`を試しましたが、まだ動かないようです)
Ubuntu 16.04 CapsLockをControlに置換する方法 

Ubuntu 16.04 CapsLockをControlに置換する方法 
=======

環境によって色々な方法があるようですが，私の環境でうまくいった方法を紹介します．

環境
---

- OS : Ubuntu 16.04 LTS
- PC : Thinkpad X201s

方法
----

`/etc/default/keyboard`に`XKBOPTIONS="ctrl:nocaps"`を記述して再起動すればOKです．


``` bash
sudo vi /etc/default/keyboard
```

``` bash:/etc/default/keyboard
# KEYBOARD CONFIGURATION FILE

# Consult the keyboard(5) manual page.

XKBMODEL="pc105"
XKBLAYOUT="jp"
XKBVARIANT=""
XKBOPTIONS="ctrl:nocaps" 
BACKSPACE="guess"
```

``` bash
sudo reboot
```
build.sbtでのunresolved dependencyを解決する

## 現象
ScalaのPlayFrameworkを利用する際,`build.sbt`ファイルが外部ライブラリを読み込まず、`Unresolved dependency`(ライブラリ依存関係が解決できない旨の)エラーを吐く。

###### 環境
Mac OSX
Intellij IDEA
scala 2.11.8
sbt 0.13
playframework 2.5

## 解決策
build.sbtでplay-slickを入れたいとする.
以下のようにversionを指定してあげる。
moduleのversionはIntellijの場合、Cmdを二回押したときに画面右端に出てくる
`SBT->{project_name}->root->Dependencies`から確認できる.



```diff:build.sbt
scalaVersion := "2.11.8"

libraryDependencies ++= Seq(
  jdbc,
  cache,
  ws,
-  "com.typesafe.play" %% "play-slick" % "2.0.0"
+  "com.typesafe.play" % "play-slick_2.11" % "2.0.0"
)
```
### why

`%%`指定子を用いた場合バージョン指定をsbt任せにできるが、この場合sbtは`play-slick_2.11.8`を捜査しているっぽい。
`%`を用いてバージョン指定することで`unresolved dependency`から逃れられた.
オーバーフローに気をつけよう


時刻の計算をしている時に、つい失敗したので共有。

# 問題

下のプログラム、どこに間違いがあるか？

```java:OverflowSample.java
class OverflowSample {
    public static void main(String[] args) {
        /* 現在時刻をミリ秒で表示 */
        System.out.println(System.currentTimeMillis());
        /* 現在時刻の30日前をミリ秒で表示 */
        System.out.println(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 30);
    }
}
```

```実行結果
$ java OverflowSample
1474654212417
1476357179713  ← あれ？　引き算したのに増えている？！
```

# 原因

「30日前のミリ秒」がintの範囲を超えています（オーバーフロー）。

```
1000 * 60 * 60 * 24 * 30 → -1702967296
```

# 解答

オーバーフローする計算結果をlongに変換しておきます。

```java:OverflowSample.java
class OverflowSample {
    public static void main(String[] args) {
        /* 現在時刻をミリ秒で表示 */
        System.out.println(System.currentTimeMillis());
        /* 現在時刻の30日前をミリ秒で表示 */
        System.out.println(System.currentTimeMillis() - 1000L * 60 * 60 * 24 * 30);
    }
}
```

```実行結果
$ java OverflowSample
1474654536537
1472062536537 ← チャンと引かれている
```

メデタシ、メデタシ。
WindowsでLet's DeepLearning! (VS2013+caffe+CUDA7.5+cudnn5.1)

##WindowsでもDeepLearningがやりたい
DeepLearningのフレームワークといえば、CaffeやTensorflow、Chainerなどが有名ですが、これらはWindowsをサポートしていないものが多く、これまでUbuntuで環境構築をしていました。（ChainerはWindowsでも動きます）
でもやっぱりWindowsでもやりたい。
というわけでCaffeをWindowsでできないかと試行錯誤した結果、なんとかビルドできたので記しておきます。

といっても特に難しいことはなく、Windows版のCaffeは公式のページからGithubのレポジトリへのリンクがあるので、そのREADMEに従えばビルドできます。
https://github.com/Microsoft/caffe

ただ上の手順だと、cudnn3あるいはcudnn4じゃないといけなかったり、詳細な説明がなかったり…

自分はcudnn5.1が使いたいので、CaffeのWindowsブランチをForkしてcuDNNv5向けに変更を加えたリポジトリを使います。
変更箇所は以下の通りです。
>・include\caffe\layers\cudnn_relu_layer.hpp
・include\caffe\layers\cudnn_sigmoid_layer.hpp
・include\caffe\layers\cudnn_tanh_layer.hpp
・include\caffe\util\cudnn.hpp
・src\caffe\layers\cudnn_conv_layer.cu
・src\caffe\layers\cudnn_relu_layer.cu
・src\caffe\layers\cudnn_relu_layer.cpp
・src\caffe\layers\cudnn_sigmoid_layer.cu
・src\caffe\layers\cudnn_sigmoid_layer.cpp
・src\caffe\layers\cudnn_tanh_layer.cu
・src\caffe\layers\cudnn_tanh_layer.cpp

https://github.com/yuzsh/caffe

###実行環境

- Windows10
- VisualStudio2013 (2015はCUDAが対応していないためできません)
- CUDA7.5
- cudnn5.1 (v3やv4でも良い)
- Python2.7 (自分はanacondaで)

###準備
リポジトリのクローン（場所はお任せします）
Windows版のブランチをダウンロードします。
>```git clone -b windows https://github.com/yuzsh/caffe.git```

caffeのルートディレクトリに移動して、プロパティファイルをコピーしておく。
>```cd caffe
copy .\windows\CommonSettings.props.example .\windows\CommonSettings.props
```

各種ライブラリのインストール方法は省略しますが、
CUDAやcudnnは[NVIDIAの公式ページ](https://developer.nvidia.com/cuda-gpus)からインストールしてください。
Pythonは[Anaconda](https://anaconda.org)を使うと便利です。

またPythonモジュールで、numpy、scipy、matplotlib、scikit-image、protobufが必要となるのでインストールが必要です。自分は以下のようにしました。
>```activate anaconda2
conda install -y numpy scipy matplotlib scikit-image pip
pip install protobuf
``` 


###CommonSettings.propsの編集
.\windows\CommonSettings.propsを開きます。VisualStudioで開くと見やすいでしょう。
確認するところは、
>```xml:CommonSettings.props
<CpuOnlyBuild>false</CpuOnlyBuild> //デフォルトはfalse GPU使えない人はtrueに
<UseCuDNN>true</UseCuDNN> //デフォルトはtrue GPU使えない人やなくてもいい人はfalseに
<CudaVersion>7.5</CudaVersion> //CUDAのバージョン
<PythonSupport>true</PythonSupport>  //Python使うのでtrueに デフォルトはfalse
<MatlabSupport>false</MatlabSupport>  //Matlab使うか 今回使わないのでfalse(デフォルト)
<CudaArchitecture></CudaArchitecture>  //デフォルトではいろいろ書いてあるけど、最近のアーキテクチャ使ってる人は空に(GTX1080など)
<CuDnnPath> path to your cudnn </CuDnnPath> //$(CuDnnPath)\cuda\include となるように
<PythonDir>C:\Anaconda3\envs\anaconda2</PythonDir>  //Pythonのパス
```

ちなみにDebugモードのときはPythonはfalseにしないとPython27_d.libがないためエラーになります。

これが終わったら、今度はプロジェクトの設定で「警告をエラーとして扱う：No」に変更するのですが、自分のリポジトリをクローンした場合はすでにやってあるので大丈夫かと思います。

###ビルド
あとはcaffe.slnファイルを開いて、ソリューションのビルド。
結構時間かかります。
ビルドが無事完了すると、Build\x64\Release(またはBuild\x64\Debug)に、exeとdllが作成されます。

###PATHの設定
環境変数PYTHONPATHに```<caffe_root>\Build\x64\Release\pycaffe```を追加します。
ちなみにwindowsでの環境変数の取り扱いは、[RapidEE](http://www.rapidee.com/en/about)が便利です。

###動作確認
コマンドプロンプトを開き、pythonを立ち上げ、import caffe がエラーなく通ればインストール完了。
また、<CAFFE_HOME>\Build\x64\Releaseに移動してcaffe.exeを実行して使い方のメッセージが表示されれば問題なくEXEが生成されていることが確認できます。

補足ですが、MNISTなどのサンプルはシェルスクリプトで書かれているため、これを実行できる環境やソフトを準備する必要があります。
自分はgitを入れるときに設定していました。


以上となります。
Ubuntuよりも簡単にできた気がします。

ちなみにchainerは```pip install chainer```だけでインストールできます。
raspberrypi3にraspbianをインストールしてSSH接続する

# 準備（必要なもの）
   * raspberrypi3 model B
   * microSD （だいたい8GB以上あれば）
     * 対応しているかは[こちら](http://elinux.org/RPi_SD_cards#Working_.2F_Non-working_SD_cards)参照
   * HDMIケーブル
   * HDMI接続できるディスプレイ
   * microUSB タイプBの電源（5V 2.0A～2.5A）
   * USB接続のキーボード、マウス（Bluetooth接続でできるのかは未確認）
   * raspberrypi用ケース（無くても問題ない）
   * microSD書き込み用端末(windows,macなど）
   * microSDリーダ
   * LANケーブル（Wifiで接続する場合は不要）

# OSのインストール
 1. OSのイメージファイルを下記からダウンロードする。
   * [公式サイト](https://www.raspberrypi.org/downloads/raspbian/)からraspbian jessieというファイルをZIPで落としてくる。
   * 落としてきたZIPファイルを解凍する。
    （raspbian jessie liteはcui版）
 2. microSDに書き込む
   * 解凍したファイルを[DD for Windows](http://www.si-linux.co.jp/techinfo/index.php?DD%20for%20Windows)でmicroSDに書き込む。
     * 管理者として実行する。  
        ![DDWin実行.jpg](https://qiita-image-store.s3.amazonaws.com/0/141266/9b7de5ad-9013-c2f9-92b6-be2b0c4c381d.jpeg)
     * ディスク選択でmicroSDのドライブを選択、ファイル選択で解凍してきたイメージファイルを選択する。  
        ![DDforWindows1.jpg](https://qiita-image-store.s3.amazonaws.com/0/141266/2cb4398f-6c57-03fa-9be0-ddef144134fd.jpeg)
     * 書込をクリックする。  
      ![ddforwindows2.jpg](https://qiita-image-store.s3.amazonaws.com/0/141266/75683855-18e6-27b1-5ef1-930098c7c5b7.jpeg)
     * 何回かポップアップがでるがすべて「はい」をクリックすると書込みがスタートする。

 3. raspbian 2016-11-25版以上の場合
 そのままではsshでログインできません。
 raspbian 2016-11-25版以上はssh接続がデフォルトで無効となったため、
microSDに書き込んだ後、`ssh`という空のファイルを作成しておくことによりsshログインができるようになる。


 4. raspberrypi3でraspbian起動
   * キーボード、マウスを接続後前項で用意したmicroSDを挿入し、給電用microUSBケーブルを接続する。（raspberrypiには電源スイッチはないため接続した瞬間に起動する。）
   * 有線でLAN接続していない場合には、raspbian起動後、右上にあるネットワークアイコンをクリック、接続先SSIDを選択し、パスワードを入力することによってWifi接続される。
   * ネットワークに接続されていることを確認する。
   * 左上にあるTERMINALをクリックする。
   * 起動した画面に下記コマンドを入力する。（場合により数十分かかる）
      * `sudo apt-get update`
      * `sudo apt-get upgrade`

# 日本語キーボード対応
   * デフォルトだと英語キーボードのため設定を日本語キーボードに変更する。
     * デスクトップ画面左上のmenuをクリック→Preferences→Mouse and KeyBoard Settings→Keyboard→Keyboard Layoutをクリック
     * CountryからJapanを選択
     * Variantはそのままでよさげ（Japanese(PC98xx Series)）

#WiFi設定（有線接続だけでよい場合は不要）
 - 下記コマンドを[SSID] [password]を書き換えて実行する。  
`$ sudo sh -c 'wpa_passphrase [SSID] [password] >> /etc/wpa_supplicant/wpa_supplicant.conf'`
 - [password]の内容も`/etc/wpa_supplicant/wpa_supplicant.conf`に書き込まれてしまうため消しておくこと。
 - reboot後WiFiが繋がっているか確認する。

# IPアドレス固定
   * 想定設定例：
     * IP : 192.168.0.10
     * subnetmask : 255.255.255.0
     * gateway : 192.168.0.1
     * DNSサーバ : 192.168.0.1
   * `$ sudo vi /etc/dhcpcd.conf`

     ```
     interface eth0 #（Wifiの場合はwlan0）
     static ip_address=192.168.0.10/24
     static routers=192.168.0.1
     static domain_name_servers=192.168.0.1
     ```


# ssh接続
   * ssh接続元の端末から前項で設定したIPアドレスにssh接続を行い成功すれば問題なし。
     * ユーザ名：pi
     * パスワード：raspberry




# 参考にさせていただいたページ：
* [Raspberry Pi 3 Model B をインストールしてSSH接続できるようにしてみる](http://techblog.clara.jp/2016/04/raspberry-pi-3-model-b_install_and_ssh_connect/)
Swiftでshellscript実行

#shell to swift
shellscriptで書いたツールをios上で実行したくなったが、~~swiftを書けないため~~shellのコードをそのまま使いたいため、swiftからshellscriptを呼び出すことにした

```swift:ls.swift
#!/usr/bin/swift

import Foundation

let task = Task.launchedTask(withLaunchPath: "/bin/ls", arguments: ["-la"])
task.waitUntilExit()
```

iPadにアプリとしてインストールできるか試してみる
Pythonで「UnicodeDecodeError」に遭遇した場合

今、Pythonでシステムを作っているのですが、日本語でDB登録する際、下記エラーに遭遇しました。

```python:error
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 0: ordinal not in range(128)
```

テスト時、英語では正常に登録されたので日本語が悪いとわかっていました。
エラー内容をググったら、下記のサイトに出会い、速攻で解決。


### 追記:Google Analyticsでよく訪れられるページ...
※Google Analyticsでよく訪れられるページとして、君臨してるので追記しました。
自分の場合は、下記のようにして、コーデックを替えてます。
参照先では、2.7の記事なのですが、3.x系だと下記のようにして対応すれば、コーデックの変更が可能です。

```python:index.py
import sys, codecs
# 3.5 =>
sys.stdout = codecs.getwriter("utf-8")(sys.stdout)

import io
# 3.6 =< 3.x
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
```

参考にしたサイト
[Python スクリプト実行時に UnicodeDecodeError が出る場合の対処方法](http://d.hatena.ne.jp/shu223/20111201/1328334689)
macOS Sierra で karabiner を使いたい。設定サンプル

## karabiner
mac のキー設定でお世話になっている karabiner さん
今までの karabiner は Sierra に対応していない見たい
公式によると Sierra 対応すべく新しく作っている様子

### 公式
https://github.com/tekezo/Karabiner-Elements

まだ絶賛開発中なのかキー設定は手動で json ファイルを作る必要あり

### 書き方はこちら
https://github.com/tekezo/Karabiner-Elements/blob/master/usage/README.md

## 設定サンプル
実際に書いて見たので参考に載せておきます。（まだキーの置き換えしかできないみたい）
設定したのは以下のもの

 - 英語キーボードの「右command」を「かな」に変更
 - 英語キーボードの「右alt」を「英数」に変更 [^1]
 - 「caps lock」を「control」に変更 [^2]

`~/.karabiner.d/configuration/karabiner.json`

```json
{
    "profiles": [
        {
            "name": "cap to control",
            "selected": true,
            "simple_modifications": {
                "caps_lock": "right_control",
                "right_command": "japanese_kana",
                "right_option": "japanese_eisuu"
            }
        }
    ]
}
```

[^1]: 本当は「左commando」を「かな」にしたいが単純な置き換えしかできないので「右alt」で一時代用
[^2]: なぜか macOS の「設定」の「キーボード」で設定しても効かなかったので karabiner で設定
Machine Learning 勉強リソースメモ帳

> ド素人のML勉強メモ。不定期更新。

# MLのための python リソース

* Awesome Pysci by bafoo
 * https://github.com/bakfoo/awesome-pysci
 * あのawesome pythonの機械学習版。丁寧な日本語説明付き。

# webinar

* Machine Learning by Stanford Univ.
 * https://www.coursera.org/learn/machine-learning/
 * 有名なやつ。無料、わかりやすい、日本語（字幕）あり。
 * 基本的に数学の話ばっか。これを観て数学的な部分を理解した上で numpy / scikit-learn / tensorflow 等を触るとより効果的。
 * 時間がかかる。毎日1〜2時間かかる。テストもありわりと本気でやらないとだめ。
 * [【終了した方の所感記事】Courseraの機械学習コースを修了しました](http://yuzutas0.hatenablog.com/entry/2016/03/24/073000)

# 本

* Python機械学習プログラミング 達人データサイエンティストによる理論と実践
 * https://www.amazon.co.jp/dp/4844380605 

# データセット

* UCI Machine Learning Repository
 * http://archive.ics.uci.edu/ml/
 * Irisをはじめいろいろある
* Kaggle Datasets
 * https://www.kaggle.com/datasets
 * European Soccer Database みたいな面白いデータセットがあり楽しそう （ https://www.kaggle.com/hugomathien/soccer ）

# ウェブ記事

* Machine Learning in a Week
 * https://medium.com/learning-new-stuff/machine-learning-in-a-week-a0da25d59850#.y88amjan7

### #1：線形回帰
* scikit-learn video #6:
Linear regression (plus pandas & seaborn)
 * http://blog.kaggle.com/2015/05/28/scikit-learn-video-6-linear-regression-plus-pandas-seaborn/
 * kaggle のブログは購読すべき。 （http://blog.kaggle.com/）

* A friendly introduction to linear regression (using python)
 * http://www.dataschool.io/linear-regression-in-python/

* 練習：Bike Sharing Demand (kaggle)
 * https://www.kaggle.com/c/bike-sharing-demand
 * 締め切っちゃってるので正式なランクはもらえないけど評価してくれる
 * かんたんそうだけどそうでもない
 * 安易にコードを書いて提出したら3000/3200（期限中の参加者総数）位くらい
   * season, holiday, workingday, weather で grouping してから、それぞれ学習させ、テストデータは同グループの学習結果を使って予測する
   * 学習するには temp, atemp, windspeed, humidity を使う
 * 解説： https://www.analyticsvidhya.com/blog/2015/06/solution-kaggle-competition-bike-sharing-demand/

* メモ
 * 学習率の選び方：（小さすぎる：収束が遅い）..., 0.001,0.003, 0.01, 0.03, 0.1, 0.3, 1, ...（大きすぎる：コスト関数が小さくならないか、収束しない）→ 3倍ずつ
 * Feature Scailing（ノーマライズ）：normalized_value = (original_value - average) / (max - min)

# 応用

### オンライゲームのチート対策

* Probabilistic Approaches to Cheating Detection in Online Games
 * http://www.hamilton.ie/dwmalone/CIG2010.pdf
配列宣言 Javaの問題をTypeScriptにしてみる4-2

次のプログラムをコンパイル、実行した時の結果として、正しいものを選びなさい


```java:java.java
public class Main{
 public static void main(String[] args){
  int[] a;
  int b[];
  int[][] c;
  int d[][];
  int[] e[];
  int[][] f[];
 }
}
```

A.３行目でコンパイルエラー
B.４行目でコンパイルエラー
C.5行目でコンパイルエラー
D.6行目でコンパイルエラー
E.4行目と6行目でコンパイルエラー
F.7行目と8行目でコンパイルエラー
G.コンパイルエラーは発生しない。

答えはGでコンパイルエラーは発生しないです。
型宣言と変数名どちらに[](添字演算子)をつけてもいいということになっているようです。
これをtsにすると

```ts:TypeScript.ts
a:number[];
b[]:number;
c:number[][];
d[][]:number;
e[]:number[];
f[]:number[][];
```

と、なります。

この中でコンパイルが通るのは
a・cの二つになります。
TypeScriptでは型宣言側に[](添字演算子)をつけることになっているようです。
変数と演算子の振舞 Javaの問題をTypeScriptにしてみる3-2

次のプログラムをコンパイル、実行した時の結果として、正しいものを選びなさい

```java:java.java
public class Sample {
 public static void main(String[] args){
  int num = -10;
  System.out.println(10 * -num);
 }
}
```
A.100が表示される
B.-100が表示される
C.コンパイルエラーが表示される
D.実行時に例外がスローされる

答えはAの100になります。

これをTypeScriptにすると、

```ts:TypeScript.ts
var num:number = -10;
console.log(10 * -num);
```

となります。
もちろん100を表示します。
Unity でShaderの勉強 その4

引き続きShaderの勉強をしていきます。

前回はZTestやZWrite周りを勉強したので今回はBlend周りをやってみたいと思います。

Test1(半透明用)とTest2(不透明用)シェーダーを作りました。

```lang:Test1
Shader "Custom/Test1"{
	Properties {
		_MainColor("MainColor" , Color) = (1,1,1,1)
	}
	SubShader {
		Tags {"Queue" = "Transparent" "RenderType" = "Transparent"}
		ZWrite Off
		ZTest LEqual
		Blend SrcAlpha OneMinusSrcAlpha

		Pass {
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			uniform float4 _MainColor;

			float4 vert(float4 pos : POSITION ): SV_POSITION {
				return mul(UNITY_MATRIX_MVP,pos);
			}

			float4 frag() : SV_TARGET {
				return _MainColor;
			}
			ENDCG
		}
	}
}
```

```lang:Test2
Shader "Custom/Test1"{
	Properties {
		_MainColor("MainColor" , Color) = (1,1,1,1)
	}
	SubShader {
		Tags {"Queue" = "Geometry" "RenderType" = "Opaque"}
		ZWrite On
		ZTest LEqual

		Pass {
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			uniform float4 _MainColor;

			float4 vert(float4 pos : POSITION ): SV_POSITION {
				return mul(UNITY_MATRIX_MVP,pos);
			}

			float4 frag() : SV_TARGET {
				return _MainColor;
			}
			ENDCG
		}
	}
}
```

白CubeにTest1,赤CubeにTest2をつけてみたところ正常に動作しました。
<img width="533" alt="スクリーンショット 2016-09-23 0.14.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/67575/f54f9979-5dd7-6fe4-2b2f-806b48baed7c.png">
<img width="486" alt="スクリーンショット 2016-09-23 0.15.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/67575/1163aa51-676c-8644-f661-d495ac4bbb97.png">


###あえて描画しない

```lang:描画しない
Shader "Custom/Test3" {
	Properties {
		_Color ("Color", Color) = (1,1,1,1)
	}

	SubShader {
		Tags {"Queue" = "Geometry-1"}

		Pass{
			Zwrite On
			ColorMask 0
		}

	} 
}
```

このシェーダーをつけることによって、
これが
<img width="451" alt="スクリーンショット 2016-09-23 1.14.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/67575/a331b783-836d-1053-7ef7-975ea437dc0f.png">
こうじゃ！
<img width="856" alt="スクリーンショット 2016-09-23 1.15.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/67575/9a0adf85-8b4d-c0c4-ac26-a2e71bb33d4d.png">

プチ解説
完全透明Cubeの背後にあるタイルのシェーダーのQueueはGeometryが設定されています(Unlitシェーダー)
今回のシェーダーのQueueはGeometry-1が設定されているので先に描画が行われます。デプスバッファに位置情報が書き込まれますが、ColorMask 0が設定されているため何も描画されません。そのためピクセル位置にはQueue = Backgroundの背景の色がそのまま残ることになります。
次いでQueue = GeometryのタイルのZTestが行われますが、ZTest LEqualが指定してあるため、より手前にある完全透明に勝てず描画が行われません。
結果的にピクセルに残る色は背景になる、というわけです :)
シェーダー面白い :)
macOS Sierra で git pull できなかった話

macOS Sierra にして git pull を実行したら下記のメッセージ。

```
Unable to negotiate with xx.xx.xx.xx port xx: no matching host key type found. Their offer: ssh-dss
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

よく分からんがアルゴリズムが宜しくない模様。
最近の OpenSSH は、デフォルトで DSA鍵 を非推奨にしたらしい。


## 対応

#### (1) ~/.ssh/config にリモートリポジトリのホストを記述

```
Host example.git
  HostKeyAlgorithms +ssh-dss
  HostName xx.xx.xx.xx
  User hoge
```

#### (2) ローカルリポジトリの .git/config を編集

```
[remote "origin"]
    url = ssh://hoge@xx.xx.xx.xx/path/to/aaa.git
```
　　↓　↓　↓

```
[remote "origin"]
    url = ssh://example.git/path/to/aaa.git
```


## 参考
[Unable to negotiate with XX.XXX.XX.XX: no matching host key type found. Their offer: ssh-dss]
(http://stackoverflow.com/questions/34208495/unable-to-negotiate-with-xx-xxx-xx-xx-no-matching-host-key-type-found-their-of)
[OpenSSH Legacy Options](http://www.openssh.com/legacy.html)

-----

~~そもそも鍵を新しくしろよって話かも知れん~~

__追記：__
わざわざこんなことしなくても`~/.ssh/config`の一番上に`HostKeyAlgorithms +ssh-dss`を書くだけで解決できますね...
SwiftでUITabBarとUINavigationBarをスクロール時にサクッと隠す


[homyu](http://qiita.com/homyu)さんの[UITabBarとUINavigationBarをスクロール時にサクッと隠す](http://qiita.com/homyu/items/db22be23f7a7bee8d9c0)を参考にSwiftで書いたらどうなるかなーをやってみて、できたのでメモしておきます。

```swift
func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    if velocity.y > 0 {
        //上下のバーを隠す
        hidesBarsWithScrollView(scrollView, hidden: true, hiddenTop: true, hiddenBottom: true)
    } else {
        //上下のバーを表示する
        hidesBarsWithScrollView(scrollView, hidden: false, hiddenTop: true, hiddenBottom: true)
    }
}

/**
 * コントローラ上のtabBarとNavigationBarの表示/非表示を切り替える
 * @param scrollView 切り替え対象のScrollView
 * @param hidden     trueの場合は、下記パラメータに応じてバーを非表示にする
 * @param hiddenTop  trueの場合は、NavigationBarを非表示の対象にする
 * @param hiddenBottom  trueの場合は、Tabbarを非表示の対象にする
 **/
func hidesBarsWithScrollView(scrollView :UIScrollView,hidden:Bool,hiddenTop:Bool,hiddenBottom:Bool){
    let tabBarController = self.tabBarController
    var inset = scrollView.contentInset
    
    //上下バーのframe
    var tabBarRect = tabBarController?.tabBar.frame
    var topBarRect = self.navigationController?.navigationBar.frame
    
    //各パーツの高さ
    let tabBarHeight = tabBarController?.tabBar.frame.size.height
    let naviBarHeight = self.navigationController?.navigationBar.frame.size.height
    let statusBarHeight = UIApplication.sharedApplication().statusBarFrame.size.height
    let controllerHeight = tabBarController?.view.frame.size.height
    
    if hidden {
        if hiddenTop {
            topBarRect?.origin.y = -(naviBarHeight! + statusBarHeight)
            inset.top = 0
        }
        if hiddenBottom {
            tabBarRect?.origin.y = controllerHeight!
            inset.bottom = 0
        }
    } else {
        topBarRect?.origin.y = statusBarHeight
        inset.top = naviBarHeight! + statusBarHeight
        tabBarRect?.origin.y = controllerHeight! - tabBarHeight!
        inset.bottom = tabBarHeight!
    }
    
    UIView.animateWithDuration(0.5, animations: {() -> Void in
    scrollView.contentInset = inset
    scrollView.scrollIndicatorInsets = inset
    tabBarController?.tabBar.frame = tabBarRect!
    self.navigationController?.navigationBar.frame = topBarRect!
    })
}
```
RelativeLayoutの使いどころ

layoutを作るさいに普段RelativeLayoutを使わなきゃって思うタイミングを紹介します。

# RelativeLayoutとは
指定したviewから相対的に位置を指定できる。メリットとしては、ネストを減らせる。デメリットとしては、可読性が著しく下がる。
RelativeLayoutの詳細に関しては、[今さら聞けないRelativeLayout](http://qiita.com/yysk/items/c686153b39d32571d1bd) がわかりやすいかと思います。

# なんで使うの？
ネストを減らすため。起動速度を上げるため。
UXを向上させるために、起動速度というのは重要というのはご存知かと思いますが、LinearLayoutでがんがんネストしているのをRelativeLayoutで減らすことでかなり速くなります。（当社比）
なので、ネストが変わらない場合はあんまり意味がないです。

# 使いどころ
ざっと思いつくのはこんな感じのlayoutの場合
- ３つ以上ネストができている
- RecyclerViewで繰り返し使う
- MainActivityといったユーザーが繰り返し見る
特に、デザイナーさんがこだわりをもってデザインされた（複雑な）layoutで使うと、効果を発揮しやすいです。

どこでも使えばいいような気がしますが、可読性も下がりますし、調整も大変なので、効果が出そうなところでやるのが精神衛生上もいいかと思います。

# コツ
LinearLayoutでは考慮しないところです。
- ネストを減らすためにviewを増やすのはok
- layout_alignHogehogeをしっかり理解する
- 完璧を目指さない、あきらめない

相対なので、ダミーのviewをわざと置いて位置を調整することがよくあります。また、layout_alignHogehogeを組み合わせることで、なんかいい感じになってくれることがあるので、1回やってダメでも後日やってみるとうまくいくことがあります。

# おわりに
もっと実例やイメージを見せながら説明した方がわかりやすかったのかもしれませんが、起動速度が速くなることは自明ですし、出力結果も同じなのでざっくりとした説明だけにしておきました。

実際に見てみたいなどありましたらgithubか何かを教えていただければ、afterをお見せできると思うので、コメントか何かに書いてもらえればと思います。

# おまけ
起動速度の計測についてですが、
AndroidStudioのAndroid MonitorでNo FilterにしてDisplayedで検索するとActivityの起動時間が出力されますので、それを参考にして計測しています。
CentOS7にFTP：ホームディレクトリにファイルをアップロードできるようにする

CentOS7のFTP構築
SELinuxの設定でハマったのでメモ
（ルートログインの場合はsudo不要）

サービスのインストール
```$ sudo yum -y install vsftpd
$ sudo yum -y install ftp```

設定ファイルの編集(/etc/vsftpd/vsftpd.conf)
```anonymous_anable=NO
ascii_upload_enable=YES
ascii_download_enable=YES```

有効化
```$ sudo systemctl enable vsftpd```

起動
```$ sudo systemctl start vsftpd```

ファイアウォールの設定変更
```$ sudo firewall-cmd --permanent --zone=public --add-service=ftp```

SELINUXの設定変更して、FTP経由のホームディレクトリ操作を有効化する
```$ sudo setsebool -P ftp_home_dir 1```
Test-Driven Development with Python をやってみた -1

色々中途半端にしてるのに、新しいことを始めるのもどうかと思おうが、DjangoとTDDが同時に勉強できるお得な本があったので、実際にやってみることにした。


[Test-Driven Development with Python](http://www.obeythetestinggoat.com/pages/book.html)

[Cloudn](http://www.cloudn-service.com/)に新しいUbuntuのvmを立って。
環境を準備。

```shell
$ sudo apt-get update

$ sudo apt-get upgrade

$ sudo apt install python3-venv python3-pip

$ pip install -U selenium
```

```shell
$ vim functional_tests.py
```


```py3
from selenium import webdriver

browser = webdriver.Firefox()
browser.get('http://localhost:8000')

assert 'Django' in browser.title
```
最初のテスト functional_tests.pyを実行した。
本だと次のようなエラーになるはずだが

```shell-session
$ python3 functional_tests.py
Traceback (most recent call last):
  File "functional_tests.py", line 6, in <module>
    assert 'Django' in browser.title
AssertionError
```

実際のエラーはこんな感じ、いきなり本の内容と違うエラーが発生。
Xが入っていないから当然か

```shell-session
$ python3 functional_tests.py
Traceback (most recent call last):
  File "functional_tests.py", line 3, in <module>
    browser = webdriver.Firefox()
  File "/home/ubuntu/venv/lib/python3.5/site-packages/selenium/webdriver/firefox/webdriver.py", line 80, in __init__
    self.binary, timeout)
  File "/home/ubuntu/venv/lib/python3.5/site-packages/selenium/webdriver/firefox/extension_connection.py", line 52, in __init__
    self.binary.launch_browser(self.profile, timeout=timeout)
  File "/home/ubuntu/venv/lib/python3.5/site-packages/selenium/webdriver/firefox/firefox_binary.py", line 68, in launch_browser
    self._wait_until_connectable(timeout=timeout)
  File "/home/ubuntu/venv/lib/python3.5/site-packages/selenium/webdriver/firefox/firefox_binary.py", line 99, in _wait_until_connectable
    "The browser appears to have exited "
selenium.common.exceptions.WebDriverException: Message: The browser appears to have exited before we could connect. If you specified a log_file in the FirefoxBinary constructor, check it for details.
```

解決するためにXvfb と pyvirtualdisplay　をインストール

```shell
$ sudo apt-get install xvfb
$ sudo pip install pyvirtualdisplay
```

さらに、今のバージョンのだとエラーになるようなのでFirefoxのバージョンをさげたら

```shell
$ sudo apt-get install firefox=45.0.2+build1-0ubuntu1
$ sudo apt-mark hold firefox
```

これでやっと本と同じ結果が表示された

```shell
$ python3 functional_tests.py
Traceback (most recent call last):
  File "functional_tests.py", line 10, in <module>
    assert 'Django' in browser.title
AssertionError
```

Djangoプロジェクトを作成して、起動すると。

```shell
$ django-admin.py startproject superlists

$ python3 manage.py runserver

$ python3 functional_tests.py
$
```

テストは問題なく終了。
openDCIMインプレッション（ワークフロー編）

[インストール編](http://qiita.com/n-i-e/items/f4ba15640e58b031d7f6)、[構成管理編](http://qiita.com/n-i-e/items/8f7447c6fe274d05829a)に引き続き、openDCIMインプレッション第3弾、ワークフロー編をお届けします。

#Rack Request Form

機器1台単位でリクエストを出せます。

フォームに機器諸元を入力すると、担当者にメールが飛び、ホーム画面の目立つ位置にあるPending Rack Requests一覧表に項目が立って担当者にプレッシャーを与えます。担当者がそこをクリックし、架名と位置を選択してMove to Rackボタンを押すと、その機器が架に載ってPendingが解消されます。

。。。というものです。

ところで、Rack Request Formに入力する際、どういうわけかSerial Number欄の入力が必須です。Rack Request Formを通さずにAdd Deviceから機器を入力するときには空欄で構わないのですが。

#Issue Escalation

この機能は正直なところ、何のためにあるのかよく分かりません。Issue Escalationの下にはTime PeriodsとEscalation Rulesの２つの項目があり、どちらも一行の自由記述を入力できるのですが、だから何？というか、特に何も起こらないというか。。。

#Project

Project Catalogタブ→New Projectでプロジェクトを作成します。このとき、以下の5項目を入力するように求められますが、新規作成のときはダミーデータでいいので__全部のフィールドを埋めて下さい。__そうしないとプロジェクトが作られません。プロジェクトができたら、さっき入力したダミーデータは消して構いません。

- Project Name
- Project Sponsor
- Project Start Date
- Project Expiration Date
- Project Actual End Date

デバイスをプロジェクトに所属させることができます。デバイスとプロジェクトの対応関係は多対一ではなく、１つのデバイスを複数のプロジェクトに所属させる多対多の対応もできます。openDCIMで管理しているのは対応関係だけですので、減価償却費の按分比率などは別な場所で管理する必要があります。

#Supplies Management

予備品とか部材とかの管理機能です。
Supplies Management→Manage Suppliesで品番・品名を登録します。このとき数量の上限・下限も入力しておきます。
実際の数量はManage Supply Binsで管理します。Bin Locationに場所（倉庫名）を入力すると、品番と数量を入力する画面が出てくるのでぼちぼち入力していきましょう。

。。。それだけです。在庫管理システムと呼ぶにはちょっと機能不足な感じです。

##Work Order Builder

初期状態では使えません。Edit Configurationタブ→Workflow→Work Order BuilderをEnabledに設定すると使えるようになります。

この機能を有効にすると、架の画面（Uが縦に並んでいるData Center Cabinet Inventoryと呼ばれる画面）上の各機器欄の右端に、黒丸にプラスのアイコンが出ます。クリックするとチェックアイコンになるトグルスイッチです。
これで機器をいくつか選択し、Work Orderタブ（というのが現れる）をクリックすると、選択した機器の一覧が出てきます。
この状態でExport Connectionをクリックすると、Excelの配線表が出てきます。

。。。が、LibreOffice Calcでは正しい表示になりませんでした。Excelでないとダメのようです。

で、そもそもこれは何のための機能なのかという話ですが、[公式Wiki](http://wiki.opendcim.org/wiki/index.php/WorkOrderBuilder)を見るところ、どうやらテプラの流し込み印刷機能を使って示名条片を作る際に使うExcelシートを作るために用意された機能のようです。まあ便利は便利かもしれませんが、これをWork Order Builderと呼ぶのはちょっと誇大表現なんじゃないかという気がします。

##Audit

AuditとかLogとか称するボタンがあっちこっちに出てきますが、これは何かというと、MySQLのfac_GenericLogテーブルにタイムスタンプつきコメントを書き込むというものです。それだけです。タイムスタンプが残りますので、現場でCertify Auditボタンをピコピコと押して回り、後から集計するようなフローにすれば、固定資産実査の時に役に立つかもしれません。ただ、MySQL側にアクセスする権限とSQLスキルがないと厳しいかなという気がします。openDCIM標準のレポーティング機能で出てくるPDFファイルは、正直あまり読みやすくありません。私の環境では日本語が文字化けしました。

#考察

##インプレッション

openDCIMのワークフロー関連機能は、構成管理機能に比べると、あまり充実していない印象です。何というかコレジャナイ感がします。

##素朴な疑問

全体的に分からないのが、そもそもopenDCIMって、__工事前__に場所を予約するためのシステムなんでしょうか、それとも__工事後__に記録するシステムなんでしょうか。そのあたりがどうも曖昧で、openDCIMのワークフロー関連機能は全体として業務のどこに組み込んで使えばいいのかよく分からない印象があります。openDCIMの特性を考慮して、ローカルルールを頑張って作り込む必要がありそうです。

##規模感

更新権限を持つ人を相当絞り込んで、小チームで意識を合わせながら運営していかないとぶっ壊れると思います。閲覧権限の範囲は、守秘義務が守られる範囲である程度広げていいと思うんですが。

以上！3回に渡ってお届けしたopenDCIMインプレッションは今回で終わりです。幸運を祈る。

#参考文献

openDCIM WIKI （公式）
http://wiki.opendcim.org/wiki/index.php/Main_Page

不肖私 (2016)
openDCIMインプレッション（インストール編）
http://qiita.com/n-i-e/items/f4ba15640e58b031d7f6

不肖私 (2016)
openDCIMインプレッション（構成管理編）
http://qiita.com/n-i-e/items/8f7447c6fe274d05829a
Xcodeのバージョンを切り替える (ついでに共存)

うっかりXcode8でビルドしてみたら、使ってるライブラリが、まだXcode8(iOS SDK10)に対応してなかったっぽいので、ひとまずXcode7環境に戻してみたら、色々とハマったので、メモです。

# 2022/9/28追記

今はXcodeの複数バージョンの共存には、xcodesという便利なコマンドラインツールが使えます！
aria2を使った高速ダウンロード＆インストールや、一覧・切り替え・削除などが簡単にできます。

```sh
brew install robotsandpencils/made/xcodes aria2
xcodes installed
xcodes list
xcodes install 14.0.1
xcodes select 13.4.1
```

(DeviceSupportの最新OSのコピーも簡単にできるといいなぁ。)

## AppStoreでXcodeを入れないようにしましょう

自動でアップデートされるので、最新版を置いておくにはいいかなと思ったのですが、xcode-selectで選ばれてるディレクトリの中身を勝手にアップデートしてしまうようです…😇

# 新しいXcodeを使う前に

storyboardなどは、一度Xcodeで編集すると、古いXcodeで開けなくなるので、必要なものは全てcommitしておきましょう。(まあ本当なら当たり前なのですが…)

# Xcode7のインストール

- [Xcode7.3.1のダウンロード](https://developer.apple.com/download/more/?name=Xcode)
    - 1時間くらいかかります
- 一応Xcode8を削除(ゴミ箱に入れて再起動)
    - どうせ共存させるなら、そのままでもいけるかも？？
- dmgがマウントできませんエラーが起きた場合
    - ダウンロードに失敗してた(サイズが微妙に小さかった)ので、再度ダウンロード
- XcodeをApplicationsにドラッグでコピーしようとすると、なぜか弾かれる
    - 原因不明。コマンドラインでインストール (ついでに名前をXcode7.3.1にして、Xcode8と共存できるようにしておきます)

```bash
sudo /usr/bin/ditto /Volumes/Xcode/Xcode.app /Applications/Xcode7.3.1.app
```

- "Could not find Developer Disk Image" 古いXcodeで、実機のOSの方が新しくて動かない場合
    - [最新のXcodeから古いXcodeにiOSのイメージをコピーします](http://qiita.com/Hakota/items/59b4247a203e2639f8c9)

```bash
cp -R /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/11.* /Applications/Xcode7.3.1.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/
```

# Carthageを使ってる場合

- carthage updateでCommand Line Toolsがないよエラーが出る
    - 指示に従ってCommand Line Toolsをインストール
    - 名前をXcode7にしたので、そちらにパスを通す

```bash
sudo xcode-select --switch /Applications/Xcode7.3.1.app/Contents/Developer/
```

- モジュールが新しいswiftでコンパイルされてるよエラーが起きた場合
    - "Module file was created by a newer version of the compiler"
    - Xcode8にしてから、CarthageでRealmモジュールをビルドしちゃうと起こるようです
    - XcodeでプロジェクトをCleanする (Cmd + Opt + Shift + K)
    - 普通にcarthage updateしてもまだエラーが残るようなら、Carthageのモジュールをクリーンビルド (かなり時間かかりますが、これで解決しました)

```bash
rm -rf ./Carthage/
rm -rf ~/Library/Developer/Xcode/DerivedData/
carthage update --platform iOS --no-use-binaries
```

# Storyboard問題

- Xcode8で編集したMain.storyboardが開けないよエラー
    - Xcode7時点のものがcommitしてあれば、discardして元に戻す
    - 最悪、Main.storyboardをテキストで開いて、minToolsVersionを8から7に書き換えると、運良く開けることもあるようです

# 複数のXcodeバージョンの共存

最新の安定版は、AppStoreでインストールして自動アップデートされるようにし、それ以外のバージョンは名前を変えて入れるのがよさそうです。

- 最新の安定版Xcodeは、AppStoreから入れる (/Applications/Xcode.app/)
- 古いXcodeは名前を変えて入れる (/Applications/Xcode7.3.1.app/ など)
- ベータ版のXcodeも名前を変えて入れる (/Applications/Xcode8.2b2.app/ など)

Command Line Toolsのバージョンは、xcode-selectで切り替えます。グローバルに変更されちゃうので、若干面倒ですね。
HTMLとCSSで正六角形をつくってみた

#HTMLとCSSで正六角形つくってみた

正六角形をつくってみました。
ちょっと浮き出ている正六角形です。

![スクリーンショット 2016-09-22 21.12.02.png](https://qiita-image-store.s3.amazonaws.com/0/141150/266e19d0-ebe6-3ad6-aa7e-886692e8f428.png)

背景を紫にしてみました。こうなっています。
![スクリーンショット 2016-09-22 21.16.33.png](https://qiita-image-store.s3.amazonaws.com/0/141150/4756d544-9c26-77bb-ab75-27c46061d023.png)

コードはこちらです。
最初は緑の部分をborderで実装していました。
しかしborderは長さをpxでしか指定出来なく、
可変な正六角形を実装することができなかったのでやめました。

```html
<div class="box">
</div>
```

の中で作業をすることでwindow拡大縮小による形崩れが起きないようにしています。
参考→[windowの高さを変更してもデザインが崩れない方法](http://qiita.com/risagon/items/cb1ab10fd0531993defe)

```html:hexagon.html
    <div class = "box">
      <div class="rightshadow shadow right"></div>
      <div class="center">
        <div class="hexagon shadow topleftshadow"></div>
        <div class="hexagon shadow toprightshadow"></div>
        <div class="hexagon shadow bottomleftshadow"></div>
        <div class="hexagon shadow bottomrightshadow"></div>

        <div class="hexagon shadow right"></div>
        <div class="hexagon shadow left"></div>

        <div class="hexagon topleft"></div>
        <div class="hexagon topright"></div>
        <div class="hexagon bottomright greenshadow"></div>
        <div class="hexagon bottomright"></div>
        <div class="hexagon bottomleft"></div>
      </div>
    </div>
```

```css:hexagon.css
  .box{
    top: 31%;
    left: 18%;
    position: absolute;
    width: 26%;
    padding-top: 28.36%;
  }

  .center{
    position: absolute;
    background-color: pink;
    width: 92%;
    height: 100%;
    top: 0%;
    left: 0%;
  }

  .hexagon{
    position: absolute;
    height: 49.9%;
    width: 58.8%;
    background-color: white;
    transform: rotate(59deg);
  }

  .shadow{
    background-color: #9cbb1c;
  }

  .topleft{
    top: -22%;
    left: 5%;
    width: 26%;
  }

  .topright{
    transform: rotate(30deg);
    top: -6%;
    left: 50%;
    width: 73%;
    height: 22.9%;
  }

  .bottomleft{
    width: 62.8%;
    top: 85%;
    left: -19%;
    transform: rotate(30deg);
  }

  .bottomright{
    top: 85%;
    left: 65%;
  }

  .greenshadow{
    background-color: #5f6527;
    width: 4%;
    height: 52.9%;
    top: 62%;
    left: 75%;
  }

  .topleftshadow{
    top: -9.5%;
    left: 22.5%;
    width: 6%;
    height: 48%;
  }

  .toprightshadow{
    top: 12%;
    left: 44%;
    height: 5%;
    transform: rotate(30deg);
  }

  .bottomleftshadow{
    top: 84%;
    left: -3%;
    height: 5%;
    transform: rotate(30deg);
  }

  .bottomrightshadow{
    width: 5%;
    top: 61%;
    left: 72%;
  }

  .right{
    top: 25%;
    left: 95%;
    width: 6%;
    transform: rotate(0deg);
  }

  .rightshadow{
    position: absolute;
    width: 5%;
    height: 50.8%;
    background-color: #5f6527;
    left: 92%;
  }

  .left{
    top: 25%;
    width: 5%;
    transform: rotate(0deg);
  }
```
【Slack】Custom slash commandsを使う

# 最初に
Slackそんなに使ってないけど社内でSlackに移行しようって流れになったのでSlack開発始めました。
→流れでCustom slash commandsを登録しそこから作成したプログラムを叩かせることをやったのでまとめました。　

# 背景
社内Slackからお知らせを投稿してDBに保存、そのお知らせを自社ポータルに表示したい。

# 問題
Publicのchannelだと全員見れてしまうし（インターンも）それはどうなんだろう？
Outgoing webhooksだとprivate channelでつかえない。
*Outgoing webhook...特定チャネルへのpostをフックにしてURLを叩いてくれる、楽

# 調べる
> The outgoing webhook integration is only available in public channels. If you would like to get data out of private groups and DMs in real-time, try a slash command.

by [Slackさん公式](https://api.slack.com/outgoing-webhooks)

<b>Slash Commands</b>というものを使えばいいらしい。

# [Slash Commands](https://api.slack.com/slash-commands)とは
"/command hogehoge"で特定の動きをしてくれる。
→Custom Slash Commandsが登録できる
このSlash Commandsにひも付けて既存のサービスをフックするようにすればいい

# やることアウトライン
1. Slackからフックさせる先のプログラムを作る
2. Custom slash commandsの登録
3. テスト

# Custom slash commandsの登録
私は今回の場合もうプログラムは作ってあったので、説明は省略します。
1. [Custom slash commands](https://naked-tokyo.slack.com/apps/A0F82E8CA-slash-commands)から"Add configuration"をクリック
2. "Choose commands"で自分の登録したいコマンドを登録する->次へ
    例： /addinfo
3. "URL"のフォームに叩きたいURLを貼る,その他随意に登録
4. OK

# 叩くプログラムの作り方
基本的にresponseをjson形式でechoで返せばok

```php:test.php
$res = array(
	"text" => "response by bot"
);
header('Content-Type: application/json');
echo json_encode($res);
```

slash commandsでPOSTされるデータにはトークンやチャネルidも入っているので、プログラム側でそういうの考慮してあげることができます。
>token=***
team_id=T0001
team_domain=example
channel_id=C2147483705
channel_name=test
user_id=U2147483697
user_name=Steve
command=/weather
text=94070
response_url=https://hooks.slack.com/commands/1234/5678

こういう感じらしいです。(https://api.slack.com/slash-commands#how_do_commands_work）
今回はPOSTが良かったのでPOSTにしましたが、GETでリクエストさせることもできます。

# テスト
![スクリーンショット 2016-09-23 21.22.23.png](https://qiita-image-store.s3.amazonaws.com/0/72946/34b157d8-8fdc-1849-e91e-0b61e8a4c327.png)


# つまったとこ
## 投稿した内容がタイムラインに表示されない
response_typeをin_channelにして返す。（参考→https://api.slack.com/slash-commands#responding_to_a_command）
これを指定しないと"only visible to you"にできる。

```php:test.php
$res = array(
	"text" => "response by bot",
	"response_type" => "in_channel"
);
header('Content-Type: application/json');
echo json_encode($res);
```

## json_encodeしても上手くいかない
headerを登録してあげる

```php:test.php
header('Content-Type: application/json');
echo json_encode($res);
```

これ忘れててなんで表示されないんだろう〜？てちょっと詰まってました。

## Botのレスポンスなしにしたい

```php
$res = array(
		"text" => "",
		"response_type" => "in_channel"
		);
	header('Content-Type: application/json');
	echo json_encode($res);
```

こうやると、ユーザのポストは全員に見れるようになって、botのレスポンスはされないようにできました。

# 参考文献
https://api.slack.com/slash-commands
http://www.programmableweb.com/news/how-to-use-slack-api-to-build-slash-commands-powered-google-app-engine-and-go/how-to/2015/09/16
【Ansible】CentOS 6にAnsible2を入れるまで

# 入れたばっかのCentOS6にAnsible2を入れるまで
どうせ、pipでインストールするだけでしょ？とか思っていたのですが、
Vagrantで構築したCentOS6環境でAnsibleをインストールしようとしたら、意外と大変。
そんなわけで、メモとして纒めておきます。 

```bash
# yumでepelレポジトリインストール
sudo yum install epel-release 

# yumで、必要なパッケージをインストール
sudo  yum install python-devel python-pip gcc libffi-devel openssl-devel

# pipをアップデート
sudo pip install –upgrade pip

# pipでansibleをインストール
sudo pip install --upgrade ansible
```

「pip使ったら　か・ん・た・ん・よ」　とか思ってたら、pipが古くてAnsible1が入ったり、
インストールするまでに、いろいろパッケージ要求されたり、意外と大変だったのでした。

ちなみに、epelレポジトリをインストールしなくても、
easy_install使えばpipをインストール可能です。
その場合は、yumでpython-pipをインストールする代わりに

```bash
sudo yum install python-setuptools
sudo easy_install pip
```
を実行してください。
Pascal's triangle

```pascal.lisp
(defun ncr (n r)
  "異なるN個のものから、異なるR個のものを選ぶ組合せの総数。"
  (if (or (= n r) (zerop r))
      1
      (/ (* (ncr n (1- r)) (1+ (- n r))) r)))

(defun pascal (n)
  "N+1行のパスカルの三角形を表すリスト。
(pascal 3) => ((1) (1 1) (1 2 1) (1 3 3 1)\)"
  (let ((lines nil))
    (dotimes (i (1+ n))
      (let ((l nil))
        (dotimes (j (1+ i))
          (setq l (append l (list (ncr i j)))))
        (setq lines (append lines (list l)))))
    lines))

(defun display-pascal (n)
  "N+1行のパスカルの三角形を表示する。"
  (let ((i 1) (lines (pascal n)) len)
    (setq len (length lines))
    (dolist (l lines)
      (format t "~vT~a~%" (* (- len i) 2) (format nil "~{~4D~}" l))
      (incf i))))

(display-pascal 10)
```
#### 実行結果
```shell-session
% sbcl --script pascal.lisp
                       1
                     1   1
                   1   2   1
                 1   3   3   1
               1   4   6   4   1
             1   5  10  10   5   1
           1   6  15  20  15   6   1
         1   7  21  35  35  21   7   1
       1   8  28  56  70  56  28   8   1
     1   9  36  84 126 126  84  36   9   1
    1  10  45 120 210 252 210 120  45  10   1
```
11行目がなんかズレる……。

### 改訂版
```pascal.lisp
(defun ncr (n r)
  "異なるN個のものから、異なるR個のものを選ぶ組合せの総数。"
  (if (or (= n r) (zerop r))
      1
      (/ (* (ncr n (1- r)) (1+ (- n r))) r)))

(defun pascal (n)
  "N+1行のパスカルの三角形を表すリスト。
(pascal 3) => ((1) (1 1) (1 2 1) (1 3 3 1)\)"
  (let ((lines nil))
    (dotimes (i (1+ n))
      (let ((l nil))
        (dotimes (j (1+ i))
          (setq l (append l (list (ncr i j)))))
        (setq lines (append lines (list l)))))
    lines))

(defun display-pascal (n)
  "N+1行のパスカルの三角形を表示する。"
  (let ((i 1) (lines (pascal n)) len)
    (setq len (length lines))
    (dolist (l lines)
      (format t "~v,0T~a~%" (* (- len i) 2) (format nil "~{~4D~}" l))
      (incf i))))

(display-pascal 10)
```
#### 実行結果
```shell-session
% sbcl --script pascal.lisp
                       1
                     1   1
                   1   2   1
                 1   3   3   1
               1   4   6   4   1
             1   5  10  10   5   1
           1   6  15  20  15   6   1
         1   7  21  35  35  21   7   1
       1   8  28  56  70  56  28   8   1
     1   9  36  84 126 126  84  36   9   1
   1  10  45 120 210 252 210 120  45  10   1
```
ズレが無くなった！
anohana様、ありがとうございますm(_ _)m
El-Getでerror "Recursive load"が出た時の対処法

El-Getとinit-loaderを組み合わせて使っていて, この問題に遭遇しました. 結局のところ気をつけなければいけないのは, **init-loaderがロードするファイルの中で(el-get 'sync)を呼ばない**ということです.


# 発生条件
- init-loaderを次のように`el-get-bundle!`している.

    ```el
    (el-get-bundle! 'init-loader
      (setq-default init-loader-show-log-after-init nil)
      (init-loader-load))
    ```
- `init-loader-load`するファイルの中で`(el-get 'sync)`している.

# メカニズム
`el-get-bundle!` の第2引数以降は ディレクトリにファイルとして保存されるのですが, `*Backtrace*` によれば `(el-get 'sync)` がこのファイルをロードします. 結果として相互再帰的なロードが行われます.

同じ理由により `el-get-bundle!` の代わりに `el-get-bundle` を, `(el-get 'sync)` の代わりに `(el-get)` や `(el-get nil '(init-loader))` を呼んでもやはり同じエラーが出ます.

# 解決法
`(el-get 'sync)` をinit-loaderがロードするファイルの外に移動させます. 例えば`el-get-bundle!`の呼出しの後に記述します.
XMLから、所在が不明なタグを名前だけで検索する方法

↓こんなふうにXML内のどこにでも配置されうるタグ`<foo>`を、PHPの標準XMLパーサ(SimpleXML)を使って取得したい場合、

```xml
<somexml>
  <foo hoge="2"/>
  <bar>
    <foo hoge="2"/>
      <baz>
        <foo hoge="3"/>
      </baz>
  </bar>
</somexml>
```

XPathをによる検索(`xpath()`)を使うとかんたんだった。


```php
$str = file_get_contents($path)
$xml = simplexml_load_string($str);

// 全文検索したい場合は'//タグ名'とする
$foos = $xml->xpath('//foo'); 

// 検索結果がSimpleXMLオブジェクトとして操作できる
foreach($foos as $foo){
    $hoge = $foo['hoge'];
    // ...
}
```

XPathはXMLを検索するためのクエリ言語で、
規格化されているためPHP/SimpleXMLに限らず他言語でも利用可能とのこと。


## 参考
- [PHP - simplexml_load_string](http://php.net/manual/en/function.simplexml-load-string.php)
- [MSDN - XPath の例](https://msdn.microsoft.com/ja-jp/library/ms256086(v=vs.120).aspx)
- [Wikipedia - XML Path Language](https://ja.wikipedia.org/wiki/XML_Path_Language)
【Ansible】ansible-vaultでファイルを暗号化するときの注意

ドキュメントの[BestPractices](http://docs.ansible.com/ansible/playbooks_best_practices.html)に倣って、ロールを利用しつつ、
ファイルを暗号化する場合の注意点。

自動で読み込まれる`roles/*/tasks/main.yml`などのYAMLファイルは、
`ansible-playbook`コマンドを、`--ask-vault-pass`オプション等を利用せずに実行すると、

```
ERROR! Decryption failed
```

と、実行前にエラーでお叱りを受けるわけですが、
これが、

- roles/*/files
- roles/*/templates

などの、YAML以外のファイルを暗号化していると、
***ファイルを利用するところまで処理が実行されます***。

これ自体が致命的な問題になることも殆どないと思いますが、
2度手間になるので、気を付けましょう、という話でした。
WindowsかMacか選択を迫られた場合の対処法

# 概要
自分はオンラインゲームをよくやるため、メイン機はWindowsになります。
普段はWindowsでAndroid開発したりLinuxでサーバ弄ったりとかしてます。
そんなMacの「魔」の字も知らない人がMacを使ってみて思ったことを書きます。
WindowsかMacか悩んでるエンジニアの卵に向けて書きます。

# 基礎知識
まずは、以下の記事を御覧ください。Windowsのシェアが９０％を占めていることがわかります。おそらくこの記事を見ている貴方はMacの必要性を感じているのでしょうが、Windowsを恥じることはないのです。
http://news.mynavi.jp/news/2016/07/03/035/

次に、価格の比較です。自分はAndroidエンジニアなのでAndroid Studioの推奨環境を最低限満たすスペックで比較します。中古Windowsノートで２〜３万、Macなら4~5万はするのではないでしょうか？
https://developer.android.com/studio/index.html?hl=ja#Requirements

最後に、できること、できないことです。ゲームが動くのはWindows、iPhone開発するならMacで、それ以外には大した差はないです。あと自作Macって聞いたことないですね。[要参考文献]

# 感想
Windows系男子にはMacは辛かったです。仮想ウインドウやショートカットなど、あると便利な機能を使うまでが面倒だと感じました。それ以外の基本的な動作に関してはどちらも変わらないです。
直感的に使えないと疲れます。慣れればいいのでしょうけど。


# 結論
好きな方を使えば良いのです。
争っている場合ではありません。
【Ansible】処理(Play)単位でユーザを切り替えるのに、やたら悩まされた話

# 処理(Play)単位でユーザを切り替えるのに、やたら悩まされた話
基本はroot権限でPlayを実行したいけど、ここだけローカルのユーザでPlayを実行したいナァ...
なんて思い、やたら悩まされた話。

## 前提
- Ansible 2
- 切り替えるユーザは`user`として変数に定義

## 方法
やり方は単純で、becomeとbecome_userを、処理に記載するだけです。

``` yaml:user_env.yml
(略)
- name: composer install
  composer: working_dir=/home/{{ user.name }}/{{ webapp.name }}
  become: true
  become_user: '{{ user.name }}'
(略)
```

ただ、これで苦労した...。

上手く行かなかったのは、以下が原因として考えられます。

- become_userに指定する変数を、クオートで囲んでいなかった
- become関連の記述を、最後に書いていなかった

とにかく、うまく動く様になってよかった...
vagrant上のmariadbにローカルのマネージメントツールからアクセスするためにやったこと

# vagrant上のmysqlにローカルからアクセスするためにやったこと

プライベートでvagrantでdebianのサーバ上にmariadbを入れてmac上のDBマネージメントツールからログインしようとしたら、ちょっと準備が必要でしたのでメモっておきます。

## 環境

* ローカル
Mac
Vagrant 1.8.3
VB 4.3.38

* 仮想環境 (192.168.33.10)
Debian 8.4
mariadb 10.1.14 (mysql 15.1)

## 接続方法

### listenされてるportの確認

以下のコマンドで状況を確認します。

```bash
netstat -ant
```
mysqlで使われる3306のポートがlocalhost(127.0.0.1)縛りになっているのであるならば、これを解放します。

### mysqlの設定を変更

/etc/mysql/my.cnf 内の以下の行をコメントアウトすれば全解放になります。

```text
# bind-address = 127.0.0.1
```
bind-addressを付け足して、IPアドレスを明示的に指定するかどうかは好みで。

設定が終わったら以下のコマンドで再起動します。(mariadbの再起動コマンドです)

```bash
systemctl restart mariadb
```
netstatを実行してみて、0:::3306となってればOK。

### mariadbに接続する

terminalからtelnetで疎通確認してみます。

```bash
$ telnet 192.168.33.10 3306
Connected to ***.***.com.
Escape character is '^]'.
GHost '192.168.33.1' is not allowed 
to connect to this MariaDB serverConnection 
closed by foreign host.
```

と怒られます。
mysql上で192.168.33.1から接続されてもいいように許可しましょう。
今回ユーザ名はroot、パスワードはpasswordとしてます。

```mysql
mysql> grant all privileges 
on *.* to root@"192.168.33.1" 
identified by 'password' with grant option;
```

とすると、telnetでつながるかと思います。

あとはDBマネージメントツールにて、以下の接続情報を設定すれば接続できるかと思います。

```text
user : root
password : password
host : 192.168.33.10
port : 3306
```
【Ansible】一連の処理をループ (loop_control)

# ひとまとめの処理をループする
## ことのはじまり
開発サーバに、開発環境を、開発ユーザ分だけ整える、というロールを構築する機会があったのですが、
**ユーザごとに、一連の処理をループしたいな。。。
でもwith_itemsたくさん書くのもやだし、registerとか使うとごちゃごちゃになるなぁ。。。**
とか、変に悩みました。
悩んだ結果、**loop_control**という機能をつかうことで解決できました。

## 前提
- Ansible 2
- ベスト・プラクティスに倣い、roleを利用
- role名は`user_env`とする。

## 方法
Playbookのrolesには、通常通りの指定でOKです。

```yaml:user_env.yml
---
- hosts: dev
  become: True
  roles:
    - user_env
```

はい。いつも通りですね。
こうして、`roles/user_env/tasks/main.yml`が、
tasksとして自動で読み込まれるわけですが、
この、`roles/user_env/tasks/main.yml`が、ループの親となります。

```yaml:roles/user_env/tasks/main.yml
---
- name: ユーザごとに一連の環境設定
  include: user_env.yml
  with_items:
    - name: user_1
    - name: user_2
  loop_control:
    loop_var: user
```
`include`には、`user_env.yml`が指定されています。
これで、単純なループと同様に、`with_items`の要素分だけ`include`した`tasks`が実行されます。

また、`loop_control`下に、`loop_var`を`user`として記述しています。
こうしておくことで、呼び出された`user_env.yml`の内部で、ループの要素を`user`として展開できます。

```yaml:roles/user_env/tasks/user_env.yml
- name: ユーザディレクトリがあるか確認
  command: ls -la chdir=/home/{{ user.name }}
  ignore_errors: True
  changed_when: False
```

## まとめ
これで、何重にもループ処理が可能です。
やったぜ。
Android向け赤外線送信アプリ作成した時の備忘録

# 概要
Androidアプリ向け赤外線送信方法

# 実装
https://github.com/h-adachi/IRController

# 記事にする事
+ Androidで赤外線通信する方法

# 詳細
大きく以下をする事で赤外線センサーを使う事が出来る

+ Android 4.4以上にする
+ ConsumerIrManagerを使用し赤外線センサを取得する
+ AndroidManifest.xmlのpermissionにandroid.permission.TRANSMIT_IRを追加する


## ConsumerIrManager
https://developer.android.com/reference/android/hardware/ConsumerIrManager.html

### 準備

[DeviceChoiceActivity.java](https://github.com/h-adachi/IRController/blob/master/app/src/main/java/h_adachi/com/ircontroller/DeviceChoiceActivity.java)

```java:DeviceChoiceActivity.java
	ConsumerIrManager ir = (ConsumerIrManager)getSystemService(CONSUMER_IR_SERVICE);
```

として実体を取得する
hasIrEmitter()がfalseの場合使用できないデバイスなので諦める

より良くは、

```java:DeviceChoiceActivity.java
	ConsumerIrManager ir = (ConsumerIrManager)getSystemService(CONSUMER_IR_SERVICE);
	ConsumerIrManager.CarrierFrequencyRange[] ranges = ir.getCarrierFrequencies();
	for(int i = 0; i < ranges.length; i++)
	{
		if(ranges[i].getMinFrequency() < 任意の周波数 && ranges[i].getMaxFrequency() > 任意の周波数)
		{
			// 使用可能! 
		}
	}
```

### 送信

[CommandChoiceActivity.java](https://github.com/h-adachi/IRController/blob/master/app/src/main/java/h_adachi/com/ircontroller/CommandChoiceActivity.java)

```java:CommandChoiceActivity.java
	if(mIR.hasIrEmitter())
	{
		mIR.transmit(ir.CarrierFrequency(), ir.MakeData(data));
	}
```

送信時の赤外線のOn/Offの時間をマイクロ秒でint配列に詰め込む
例)
10マイクロ秒On、20マイクロ秒Off、15マイクロ秒On

```java
// 最後にOFFする事も考慮した配列にしている
int[] datas = new int[]{10, 20, 15, 1};
```


## AndroidManifest.xml
https://developer.android.com/reference/android/Manifest.permission.html

### 記載例
コピれば良い

```mxml
	<uses-permission android:name="android.permission.TRANSMIT_IR" />
```
ブックマークレットの登録方法

# ブックマークレットの使用準備


> **ブックマークレット (Bookmarklet)** とは、ユーザーがウェブブラウザのブックマークなどから起動し、ウェブブラウザで簡単な処理を行う簡易的なプログラムのことである [注釈 1]。 携帯電話のウェブブラウザで足りない機能を補ったり、ウェブアプリケーションの処理を起動する為に使われることが多い。
> [ブックマークレット - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%96%E3%83%83%E3%82%AF%E3%83%9E%E3%83%BC%E3%82%AF%E3%83%AC%E3%83%83%E3%83%88)




## ブックマークレットの使用準備

#### 手順1. ブックマークバーを表示する

![image](https://qiita-image-store.s3.amazonaws.com/0/103957/4c014861-3bb6-c822-a1a9-c6f78509a6c8.png)
図の青枠で囲っている部分がブックマークバー

　[Chrome ブックマークバーの使用法](https://support.google.com/chrome/answer/95745?hl=ja)
　[Firefox ブックマークバーの使用法](https://support.mozilla.org/ja/kb/bookmarks-toolbar-display-favorite-websites)
　[Safari ブックマークバーの使用法](https://support.apple.com/kb/PH21460?viewlocale=ja_JP&locale=ja_JP)
　[IE11,Edge ブックマークバーの使用法](https://support.microsoft.com/ja-jp/instantanswers/cb97447c-a200-476f-a241-cd3958144d02/see-your-favorites-bar)




#### 手順2.ブックマークレットをブラウザのブックマークに登録

ブックマークバー上で右クリックすると、ブックマークを追加するためのメニューが表示されるので選択する

![ブックマークバーにて右クリック](https://qiita-image-store.s3.amazonaws.com/0/103957/28dbdf7c-d613-5d6c-a759-89f0e37aaffb.png)

**URL部分**
`javascript:`から始まるブックマークレットのコードを入力

今回のサンプル中では
[【Bookmarklet】ブラウザ上で黒丸になっているパスワードの中身をワンクリックで表示させる - Qiita](http://qiita.com/AQRiL_1132/items/10d6934da27b171a1e2e)のコードを使用

> ```:bookmarklet
javascript:(function(){if(typeof this.tgt==='undefined')this.tgt=document.querySelectorAll('input[type="password"]');var nit=(this.tgt.item(0).getAttribute('type')=='password')?'text':'password';for(var i=0;i<this.tgt.length;i++)this.tgt.item(i).setAttribute('type',nit);})();
```

**名前**
わかりやすい任意の名前をつければOK（今回のサンプル中では `view_pswd`としている）

![新しいブックマークを登録する画面](https://qiita-image-store.s3.amazonaws.com/0/103957/7a442ce4-ee3b-e6dc-9287-3e56d40c83ad.png)


![ブックマークレットを登録し終わった画面](https://qiita-image-store.s3.amazonaws.com/0/103957/5b4ae505-3784-6942-0cce-5f421f1738b1.png)


以上でブックマークレットの利用準備は完了


## 参考になるリンク

- [知ってそうで知らないブックマークレットの仕組みと使い方（と便利な11点まとめ） ｜ ライフハッカー［日本版］](http://www.lifehacker.jp/2013/04/130402bookmarklet_matome.html)
- [ブックマークレットをインストールする方法 | Firefox ヘルプ](https://support.mozilla.org/ja/kb/bookmarklets-perform-common-web-page-tasks)
- [bookmarklet maker](http://userjs.up.seesaa.net/js/bookmarklet.html)