OmniAICreator/Qiita-1.07M huggingface dataset:
Excelで条件にマッチする行番号を文字列で返す関数をつくってみた。

# はじめに

元ネタは[『Excelで列の値が条件に一致する行を別の場所に抜き出して表示する』](https://qiita.com/draganmaistir/items/25d5f5b6e4433e262d9b)です。
元ネタに、以下のようにコメントを付けたのですが、MATCHだと "条件" で検索することはできないが、
COUNTIF　だと "条件" が書けます。これが利用できないかと考えました。

```vba
(A2)　=IF(COUNTIF(F2,"条件")=1,COUNTIF(F$2:F2,"条件"),"")
(A3)　=IF(COUNTIF(F3,"条件")=1,COUNTIF(F$2:F3,"条件"),"")
...
```

# 最初のプログラム
RANGEの範囲をOFFSETで移動させ、RESIZEで１セルにしたので、返る値は０か１です。
条件に合った場合は１なので、行数をコンマ付きで文字列Sに追加します。

```vba
Function ML(R, V, Optional S = "") ' MATCH LINES
    Dim I: For I = 1 To R.Rows.Count
        If WorksheetFunction.CountIf(R.Offset(M - 1).Resize(1, 1), V) = 1 Then S = CC(S, I, ",")
    Next I
    ML = S
End Function

Function CC(ParamArray PA())
    On Error Resume Next
    Dim S: S = ""
    Dim I: For I = LBound(PA) To UBound(PA)
       S = S & PA(I)
    Next I
    CC = S
End Function
```
# 少し改良
WorksheetFunction が煩いので関数CIFで包み、関数MLの返り値の最後のコンマを取り除きます。
更に、引数Lに行番号の文字列を与えると、検索範囲を絞れるようにします。
全件検索を L="0" としました。そうしないと、検索範囲なしの L="" と区別がつかなくなります。

```vba
Function CIF(R, M, V, Optional S = 0)
    On Error Resume Next
    S = WorksheetFunction.CountIf(R.Offset(M - 1).Resize(1, 1), V)
    CIF = S
End Function

Function ML(R, V, Optional L = "0", Optional S = "") ' MATCH LINES
    On Error Resume Next
    Dim A, I, J
    
    If L = "0" Then
        For I = 1 To R.Rows.Count
            If CIF(R, I, V) = 1 Then S = CC(S, I, ",")
        Next I
    ElseIf L = "" Then
        
    Else
        A = Split(L, ",")
        For I = LBound(A) To UBound(A)
            J = A(I)
            If CIF(R, J, V) = 1 Then S = CC(S, J, ",")
        Next I
    End If
    If S <> "" Then S = Left(S, Len(S) - 1)
    ML = S
End Function
```
# CIF,MLの使用例
```vba
(O1)  =CIF(M02N_[O],3,7000)                [1]
(O2)  =CIF(M02N_[O],3,7001)                []
(O3)  =ML(M02N_[O],7000)                   [3,11,20,27,28,29,122,123,124]
(O4)  =ML(M02N_[O],7001)                   []
(O5)  =ML(M02N_[済],1,ML(M02N_[O],7000))   [11,20,27,28,29,122,123,124]
(O6)  =ML(M02N_[済],1,ML(M02N_[O],7001))   []
```

(O5)の使用例は、順番が判り易くありません。複数の条件を適用順に定義できる関数を作成します。

# 引数の順序を並べかえた関数を定義する。

引数の並びを分かり易いように、MLS(R1,V1,R2,V2,....)　としました。

```vba
Function MLS(ParamArray PA())                       ' MATCH LINES IFS
    Dim S: S = "0"
    Dim I: For I = LBound(PA) To UBound(PA) Step 2
        S = ML(PA(I), PA(I + 1), S)
    Next I
    MLS = S
End Function
```
# MLSの使用例

```vba
(O7)  =MLS(M02N_[O],7000,M02N_[済],1)     [11,20,27,28,29,122,123,124]
(O8)  =MLS(M02N_[O],7000,M02N_[済],0)     [3]
(O9)  =MLS(M02N_[O],7001,M02N_[済],1)     []
(O10) =MLS(M02N_[O],7001,M02N_[済],0)     []
(O11) =MLS(M02N_[O],">7000",M02N_[済],0)  [1,2,4]
```
# MLSの改良
引数の個数が奇数か偶数かにより、引数の並びの意味を変えてみる。

(奇数の場合)    MLS(L,R1,V1,R2,V2,...)
(偶数の場合)    MLS(R1,V1,R2,V2,...)

```vba
Function MLS(ParamArray PA())                       ' MATCH LINES IFS
    Dim S: S = IFC(WorksheetFunction.IsOdd(UBound(PA) - LBound(PA)), "0", PA(LBound(PA)))
    Dim J: J = IFC(S = "0", 0, 1) + LBound(PA)
    Dim I: For I = J To UBound(PA) Step 2
        S = ML(PA(I), PA(I + 1), S)
    Next I
    MLS = S
End Function

Function IFC(C, V, Optional S = "")
    If C Then IFC = V Else IFC = S
End Function
```





以上
JSON

Newtonsoft の JSON.NET を使って、シリアライズ / デシリアライズを行う。
# シリアライズ
```csharp
var book = new Book()
{
    Id = 1,
    Title = "hello, world."
};

using (var stream = new StreamWriter("book.json"))
using (var writer = new JsonTextWriter(stream))
{
    JsonSerializer serializer = new JsonSerializer()
    {
        NullValueHandling = NullValueHandling.Ignore,
        ContractResolver = new CamelCasePropertyNamesContractResolver()
    };
    serializer.Serialize(writer, book);
}
```

# デシリアライズ
```csharp
using (var stream = new StreamReader("book.json"))
using (var reader = new JsonTextReader(stream))
{
    JsonSerializer serializer = new JsonSerializer() {
        NullValueHandling = NullValueHandling.Ignore,
        ContractResolver = new CamelCasePropertyNamesContractResolver()
    };
    var book = serializer.Deserialize<Book>(reader);
    System.Diagnostics.Debug.WriteLine(book);
}
```

# 天気予報 (JSON) の取得
```cshap
var wc = new WebClient();
wc.QueryString = new NameValueCollection()
{
    // yokohama
    ["city"] = 140010.ToString()
};
wc.Encoding = Encoding.UTF8;

var result = wc.DownloadString(@"http://weather.livedoor.com/forecast/webservice/json/v1");

JObject o = JObject.Parse(result);

List<string> forecasts = o["forecasts"].Select(i => i["telop"].ToString()).ToList();

foreach(var f in forecasts)
{
    System.Diagnostics.Debug.WriteLine(f);
}

//object json = JsonConvert.DeserializeObject(result);
//System.Diagnostics.Debug.WriteLine(json);
```

## 参考
* JSON.NET
   https://www.newtonsoft.com/json/help/html/Introduction.htm
* Weather Hacks
  http://weather.livedoor.com/weather_hacks/webservice
初心者でも使いこなせる！Emmetのかんたん操作


#Emmet 基本コマンドについて#

Emmetとは？
簡単に説明すると、短いコマンドでコーディングできる魔法のようなツール。

色々ルールはあって覚えるほどコーディングが効率的になりますが、
Emmet初心者で「何から使えばいいかよく分からないよ〜」という方は
下記のコマンドをまず試してみて、使えるようになると良いと思います。

#HTML#
##`<table>`
```lang:HTML
<table>  <tr>
    <th></th>
    <td></td>
  </tr>
  <tr>
    <th></th>
    <td></td>
  </tr>
  <tr>
    <th></th>
    <td></td>
  </tr>
</table>
```
例えば上記のようなコードを書きたい場合。

**table>tr*3>th+td**


#CSS#

##line-height: 1.5;##
```lang:CSS
line-height: 1.5;
```
この場合の書き方はこう。

**lh:1.5**

##margin-top: 5px;##
```lang:CSS
margin-top: 5px;
```

**mt:5**


##border-top: 1px solid #000;##
```lang:CSS
border-top: 1px solid #000;
```

**bt+**



これだけでもかなり楽になります。

これらをマスターしたら次へ進むと良いでしょう。
Linterのよく出るWarningを訳してみた

##ATOM　CSSLintのワーニング・エラーを訳してみた##

Linterって便利ですよね。
でもちょっと気になるのが、普通に書いていてもでてくるWarning。

エラーでは無いので、問題はないのですが、気になるという方へ。


##Don't use IDs in selectors##
IDはセレクターに使うべきではないよ。なぜならそのルールは限定的で再利用できないからね。
クラスを使用したほうがいいよ。

##Using width with border can sometimes make elements larger than you expect<BR>Using height with border can sometimes make elements larger than you expect##
width/heightは、ボーダーと合わせて使うと良く無いよ。
ブラウザによって、罫線を横幅や高さに含めるかどうかが違うからね。


なお原文
http://csslint.net/about.html#docs
OculusGoで開発時にテストで作ったアプリなどを削除する方法

自分で開発したアプリはOculusGoのライブラリで「提供者不明」のところに表示される。
ただOculusGo側の操作では提供者不明アプリは消せないため、テストで作ったアプリなどを削除するにはADB (Android Debug Bridge)コマンドをPC側から打ってやる必要がある。

## 具体的な方法

OculusGoを開発者モードでPCにUSB接続する

adb.exe が置いてあるパスに移動
`cd "D:\Unity\AndroidSDK_r25.2.5\platform-tools"`

adbでパッケージ一覧を取得して、不要パッケージを探す。
`adb shell pm list packages`
`adb shell pm list packages | clip`とやってテキストエディタで探すのが楽かも。

以下コマンドでパッケージを削除する。
`adb uninstall パッケージ名`
例：
`adb uninstall my.oculus.sample`
【cakephp3】CSRFコンポーネントロード時のテストコードのリクエストの送り方

# バージョン
Cakephp3 3.5

# 背景
$this->loadComponent('Csrf')で
CSRFコンポーネントをロードしているコントローラにて
テストコードを書いた際、$this->postが403Forbiddenになり困った。

# 解決

```php
$this->_csrfToken = true; //この行を追加

$this->get('users/add');

$email　= 'test@email.com';
$button = 'confirm';

$this->session($this->_requestSession->read());
$this->post('users/add',compact(['email','button']);
```

※1行目が無いと403Forbiddenがレスポンスされる。
Windows10 64bitへのRのインストール

## R言語とは
R言語（あーるげんご）はオープンソース・フリーソフトウェアの統計解析向けのプログラミング言語及びその開発実行環境です。

## 参考
* [The R Project](https://www.r-project.org/)
* [Wikipedia: R言語](https://ja.wikipedia.org/wiki/R%E8%A8%80%E8%AA%9E)

## 環境
* Windows 10 64bit
* Rバージョン 3.5.0（2018/07時点）

## Rのインストール
### ダウンロード
１．[The Comprehensive R Archive Network](https://cran.r-project.org/)で「Download R for Windows」をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/256143/feb00d41-736a-6c5a-f26d-795e0b4cb2c8.png)

２．「base」をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/256143/7a61f872-e413-1139-c53e-10d63e8263cb.png)

３．Download R x.x.x for Windows (xx megabytes, 32/64 bit)をクリック
（※投稿時点では3.5.0）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/256143/7fc117d9-06bd-6e6b-86d2-f29915f7c4e9.png)

### インストール
１．ダウンロードした「R-X.X.X-win.exe」を実行

２．日本語を選択

３．次へ

４．インストールフォルダを指定して次へ

５．コンポーネントの選択で、「64bit 利用者向けインストール」を選択して次へ（※OSが32bitの場合は32bitを選択）

６．起動時オプションは「いいえ」を選択して次へ

７．次へ

８．次へ

９．起動
IBM Cloud アカウント登録

# IBM Cloud アカウント登録

### 1.アカウント登録ページを開く 
IBM Cloudライト・アカウント (Bluemix)
https://www.ibm.com/cloud-computing/jp/ja/bluemix/lite-account/

### 2.メールアドレス等個人情報入力してアカウントの作成
※パスワードは大文字小文字数字記号などを含む必要あり

### 3.入力したアドレスにメールが届くので[Confirm Account」をクリックして認証

### 4.プライバシーポリシーに同意し、次に進む

### 5.ダッシュボードが開かれる
CSSで任意サイズの枠線を％指定のボックスぴったりに収める

# 背景
`％`指定等で枠線をつけると、枠線は対象の外側に引かれるためサイズがぴったりにならない
これの防止をする。

主として健忘症である未来の自分へのメモ


# 実装
※Chromeでのみ動作確認済み

```css:css
.class{
  --b:5px;                              /* 枠線のサイズ指定 */
  Width:calc(100vw - calc(var(--b)*2)); /* 枠線は左右に2本入るため枠線のサイズかける2をした数を引く */
  Height:calc(50vh - calc(var(--b)*2)); /* 枠線は上下に2本入るため枠線のサイズかける2をした数を引く */
  border: var(--b) solid #fff;          /* 枠線指定 */
}
```


<p data-height="265" data-theme-id="0" data-slug-hash="vrbKpQ" data-default-tab="css,result" data-user="hashito" data-embed-version="2" data-pen-title="border perfect" class="codepen">See the Pen <a href="https://codepen.io/hashito/pen/vrbKpQ/">border perfect</a> by hashito (<a href="https://codepen.io/hashito">@hashito</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


# 追記
## 背景
@takamoso 様からコメントを頂き、「そこまでしなくても、`box-sizing` を使えばできますよ。」とのこと…

## 調査
`box-sizing`がわからなかったので調べてみると
「ボックスサイズの算出方法の指定、`border-box`に指定すれば`padding`と`border`の幅を含める」
ということで**探していたのはまさにこれ**です

## 例／デモ

例としてコードも頂きましたので、下記に転記させていただきます。

```css
div{
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  border: 5px solid #f00;
  background: #000;
}
```

デモ

<p data-height="265" data-theme-id="0" data-slug-hash="bKzKaK" data-default-tab="css,result" data-user="hashito" data-embed-version="2" data-pen-title="border perfect2" class="codepen">See the Pen <a href="https://codepen.io/hashito/pen/bKzKaK/">border perfect2</a> by hashito (<a href="https://codepen.io/hashito">@hashito</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

@takamoso 様コメントありがとうございました。
slack BOTでのメンションの飛ばし方！！

シンプルにslackのBOTでのメンションの飛ばし方のみの解説です。

こちらの記事を参考にしてお掃除当番のBOTを作って見ました。
[弊社猫会長に日直当番を任命していただくbotを作った](https://qiita.com/BlackCat/items/78a4619b9ef4f2a1feda#%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89)
すると、メンションが飛ばない。。。。


色々探して公式の情報をこちらをやってみてもうまくいかない

ようやく上手くいったのがこちらの方法です。

前までは、
```<@username>```

新しい方法は
```<@userID>```

と、上記のように<@ユーザID>を使うことによりメンションを飛ばすことが出来ました！

そして肝心のユーザIDですが、
1.slackにてユーザIDを知りたいユーザのプロフィールを表示
2.プルダウンを選択すると、『メンバーIDをコピー』これを選択するとユーザIDを取得できます！
【入門】WindowsでCodeigniter3を触ってみる 【Hello World】

# 用意するもの

XAMPP
 ・公式ページよりダウンロード（https://www.apachefriends.org/index.html ）
 ・ダウンロード後、OKボタンをひたすら押してインストール

Codeigniter
　・公式ページよりダウンロード（https://codeigniter.com/
）して解凍。ファイル名を【codeigniter】にする。
　・XAMMPにあるhtdocsフォルダに【codeigniter】を配置。デフォルトのままであれば【C:\xampp\htdocs】が配置パス。
　
# 起動手順

### １. XAMMPのコントロールパネル起動して、Apacheを起動
![XAMMP.png](https://qiita-image-store.s3.amazonaws.com/0/230829/1f15fb25-0d25-57e4-5a7f-66e7870d5abd.png)

### ２. 以下のURLを入力して起動を確認
http://localhost/codeigniter

![XAMMP2.png](https://qiita-image-store.s3.amazonaws.com/0/230829/230ca7e3-7a21-e774-48c9-9ab6765839f3.png)

### ３. Hello!Worldを書く

codeigniter内にある以下のPHPファイルを編集して、以下の箇所にHello Worldを追加
application/controllers/Welcome.php

```php:Welcome.php
<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Welcome extends CI_Controller {

	/**
	 * Index Page for this controller.
	 *
	 * Maps to the following URL
	 * 		http://example.com/index.php/welcome
	 *	- or -
	 * 		http://example.com/index.php/welcome/index
	 *	- or -
	 * Since this controller is set as the default controller in
	 * config/routes.php, it's displayed at http://example.com/
	 *
	 * So any other public methods not prefixed with an underscore will
	 * map to /index.php/welcome/<method_name>
	 * @see https://codeigniter.com/user_guide/general/urls.html
	 */
	public function index()
	{
		echo '<p>Hello World</p>'; // here
		$this->load->view('welcome_message');
	}
}
```

### ４. 以下の画面をリロードして確認。画面左上にHello Worldがある。

http://localhost/codeigniter
![XAMMP2.png](https://qiita-image-store.s3.amazonaws.com/0/230829/9e316fd7-0846-4a20-e2f7-3e3f83766d67.png)
365日EXCELの強制終了に苦しむエンジニア（旋盤工）が、テクニックを詰め込んでみる。

# はじめに
本屋に行くと、[数学ガール（ポアンカレ予想）](http://www.hyuki.com/girl/poincare.html)『初版』　が売っていたので、ポエムのネタにすべく早速購入しました。
ネタといえば、この記事の元ネタは[これ](https://qiita.com/7404/items/ce80e1425a413832473e)です。
EXCELでNC管理システムを構築して、関数型プログラミングを楽しんでいたのですが、
ある日を境に突然強制終了を繰り返すようになりました。
セルに埋め込む関数が多くなれば、それだけ処理時間が掛かるし、
EXCEL自体は負荷を掛けると簡単に強制終了します。
そこで強制終了しないためにやったテクニックを晒してみたいと思います。

# 最初から繰越前提でシステムを設計する。
本業の合間にEXCELを弄っているので、前年のデータがそのまま残っている状態でした。
そのままでは、破綻するのは目にみえているので、データに棚卸項目を作って年末の棚卸に備えます。
業務アプリを作る場合は、常識なのだけれど、作り始めた時は、あまり考えていませんでした。

# 残しておく必要のない埋め込み関数は、マクロで数値化する。
どうやら日報作成システムを作り始めてから、強制終了が日常化したようです。
日報は、メールで報告したら、データだけ履歴として必要なので、割と数値化は簡単なのですが、
手動で数値化する範囲をコピーして値をぺったんでは、面倒ではあります。
また、数値化すると、テーブルに行を追加する場合に、埋め込み関数を勝手にコピーしないので、
行追加マクロで、関数を埋め込む仕組みにする必要があります。
今、メール送信時に、マクロで数値化できるように改造中です。

# INDIRECTではなくRANGEを使用する。
割と最近[発見](https://qiita.com/matumoto_onga/items/45d29070851cb529da8e)したのですが、条件により参照テーブルを変えるのは、INDIRECTではなくRANGEを使用します。
危険な事をすると直に強制終了になりますので、RANGEのほうが安全ですしね。
引数にテーブル名を組み込むよりも、関数内で自由に使えた方が便利です。

# テーブル+INDEX+MATCH+OFFSET+RESIZE でテクニックを駆使する。
　[あの記事](https://qiita.com/matumoto_onga/items/7adfd4cf48288c477901)で説明しています。
関数を簡単にして負荷を掛けるのを防ぎます。

# 関数をリリースする前に、別のEXCELでテストしてからコピペする。
コーディングを少しでも間違えると、エラー処理が走って重すぎて、強制終了になるようです。
しかし、当人は怠惰なので実践していません。

# 絶対、無限ループにならないようにコーディングする。
以下のように、必ず有限回で終わるように、FOR NEXT ループを回します。

```vba
DIM I:FOR I = 1 TO R.ROWS.COUNT
   IF DI(R,I) = "" THEN EXIT FOR
   ...
NEXT I
```

以上ですが、追加するかも。
機械学習でストリートファイター

機械学習を使って、ストリートファイターを認識するアプリを作ってみました。アイパッドを使ってリアルタイムに認識します。ゲームだからキャプチャーすればいいのですが、これが上手くいけば実写へと期待しています。

<img src='https://qiita-image-store.s3.amazonaws.com/0/253995/14131403-5341-e100-4cd6-8d41eb969ef7.png' width=50%>

モデルの作成とSwiftのコードは前回の記事にあります。
[iPhoneで顔認識 - Qiita](https://qiita.com/koji4104/items/7afc8c8fba6a942f4145)

## 使用環境
- Xcode  
iOSとSwiftを使います。
- CoreML Framework
iOSの機械学習ライブラリ。
一般的な学習済みモデルは Apple Developer からダウンロードできます。
https://developer.apple.com/machine-learning/
モデルには1000個のカテゴリーが入っており、画像を与えると1000個の中で「強いて言えば何か」を分類します。例えばマウスであったり、コンピューターキーボードであったり、PCモニターの前に座った人をバーバーと分類したりします。

- Turi Create
学習モデルを作成します。TuriはAppleがを2016年に買収しました。学習モデルとは拡張子.mlmodelのファイルのことで、Xcodeに置いてCoreMLからファイル名を指定するだけで使えます。TuriCreateはPC上でPythonで実行します。

## モデルの作成

<img src='https://qiita-image-store.s3.amazonaws.com/0/253995/c1156608-1713-e1f6-e9c0-f508d90c3482.png' width=50%>
<img src='https://qiita-image-store.s3.amazonaws.com/0/253995/2a1043ea-8cc3-99b4-d9e4-cbad62d1c6c9.png' width=50%>

機械学習とは分類です。今回は10個のカテゴリーを作成しました。表示していませんが立ち状態があります。分類結果は、10個足して100％になるように値が出ます。なので、その他である立ち状態をしっかりと定義することが大切になります。

## プレイ

[![Youtube](http://img.youtube.com/vi/X_tm580lsMo/0.jpg)](http://www.youtube.com/watch?v=X_tm580lsMo)

1秒間に10回程度認識させます。認識したモーションには5点与えます。点数は徐々に減っていきます。

## 失敗

今回は Vision.framework にあるオブジェクトトラッキングを試してみました。動画の場合に物体を追跡してくれます。マウスやペットボトルなど、カメラを揺らしても追跡してくれます。ただ今回のようにゲームキャラだと変化が激しいためか、すぐに追跡が外れてしまいました。他にも色々試しましたが、位置がズレたりしてボツにしました。

画面上を捜査する機能も作ってみました。リュウ、春麗、背景の３つに分類して、リュウの一致度が高いものを探します。しかしこれだと秒間10回の処理に追いつきませんでした。

ジャンプ攻撃について、画像を切り出してMLに与えるので、ML側はジャンプしているとは認識しません。何か別のパラメータと組み合わせる必要があります。ただ現実でこれだけジャンプする人はいないので、考えなくてもいいのかも知れません。

しゃがみ状態を外しました。上半身に絞った方が認識率が上がったためです。野球とかボクシングなどは上半身のみでいいと思うので、競技によると思います。てなことを考えながら黙々とトレーニング画像を切り出していました。とにかくトレーニング画像を集めるのが大変なので、このあたり自動化できたらいいと思います。

## これから

iPhoneやiPadを使ってリアルタイムに処理が出来たら面白いと思っています。今回の実験を経て色々思い付いたので、次回につなげたいと思います。
WSL (Bash on Ubuntu on Windows) からadbでUSB接続のAndroid端末を操作するには 

Windows側にもWSL側と同じバージョンのadbをインストールし、
Windows側でadb start-serverし、WSL側から接続(adb)する。

# 出典
- https://github.com/Microsoft/WSL/issues/2195
- https://github.com/ethanhs/WSL-Programs/issues/29#issue-170066892

# メリット
- mac/linuxで作ったadbのシェルスクリプトとかをbatに移植せんで済む。
unicorn nginx web表示 確認

unicornの設定をしていて、いろいろと解説しているページがある。

nginx単独では表示できたが、unicornと連動して、railsで表示させるのに、
３日くらい？かかった。
macのローカルの環境で、表示できるのに、CentOSのweb上では表示できない。

結局、CentOSとは別に、Ubuntuでnginxとunicornをインストールして、
http://to-developer.com/blog/?p=1994
上のサイトの通りやったら、railsが表示できた。その後、CentOSでも表示できた。
他のサイトの解説でやっても、自分はことごとくrailsの表示がうまくいかなかった。


nginxの解説としてよかったページは下のサイトなど。

https://qiita.com/syou007/items/555062cc96dd0b08a610
http://www.omohayui.com/entry/2015/07/18/154837

config/unicorn.rbの設定ファイルの解説がわかりやすかった。
しかし、これらページの通りやったが、なぜか表示できなかったりした。

メモ）
CentOSだと8080のポートがデフォルトでは解放されていない。
（ubuntuではデフォルトで8080などが解放されている）
そのため、CentOSでは8080のポートを一時的に解放してやる。

```
sudo firewall-cmd --add-port=8080/tcp
```

これで、http://IPアドレス:8080　にアクセスして表示を確認することができた。

この後、8080のポートを閉じたい場合は、firewallをリロードした。

```
sudo firewall-cmd --reload
```
BracketsでHTML書いたらストレスフリーだった話

#はじめに
今までAtomで書いていたHTMLをBracketsで書いたら色々良い機能があったという話です。Emmetとライブプレビューの話をします。初心者目線の記事になります。

#環境
- OS: Windows10
- Editer: Brackets 
- ブラウザ: Google Chrome

#Bracketsの導入
[こちら][brackets]からダウンロードしてインストール
特に難しくないし、勝手に日本語化されるのが嬉しいポイント
[brackets]: http://brackets.io/

#使い勝手の良い（拡張）機能紹介
- 表示の話
![スクリーンショット (38).png](https://qiita-image-store.s3.amazonaws.com/0/244873/cf7f72b6-bde5-b458-4341-9c5da70a9a6e.png)<br>
開くとこんな感じになっていると思います（Emmetは拡張機能なので、インストールしてすぐだと表示されてないです）
右にある３つのアイコンが上から「ライブプレビュー」「拡張機能マネージャー」「Beautify」です（Beautifyは拡張機能）
拡張機能マネージャーから拡張機能の入手・管理を行えます。<br><br>

- ライブプレビュー
ライブプレビューはHTMLを編集するとブラウザに即座に反映する機能です。時々バグを踏みます（f5でだいたい解決する）が、それ以上に一度触ると戻れない魅力があります。<br><br>

- 拡張機能紹介

1. Emmet
何も書いてないindex.htmlで
　「!」→tabキー
で雛形が出来て、
　「div.container」→tabキー
で\<div class="container></div>と書き込めるのが強い<br><br>

2. Beautify
コードを書いててインデントがめちゃくちゃになったときに使う拡張機能
「編集」→「保存時にBeautifyする」or「Beautify」で使う<br><br>

3. Indent Guides
インデントに縦線が引かれるもの。Editerの見やすさに関わる。

4. HTML Block Selector
タグから閉じタグまでを一括で選択する拡張機能

#Atomのほうが良かったこと（解決方法募集中）
Atomは行移動を行うときにインデントが自動で補完されるのに対し、Bracketsは補完されない。
Beautifyで空行が増える＆消えない


#おわりに
Editerと拡張機能でコーディングの効率が数倍違うので、是非に。（回し者ではないです）
Ubuntu16.04でtensorflow-gpuを動かす

## 環境
* Ubuntu 16.04.4
* GPU: GTX 1080

## インストールするライブラリのバージョンを決める

 * 動かしたいtensorflowのバージョンを以下のリストから探してくる。
 * 動かしたいtensorflowのバージョンのテストに使われてるCUDAとcuDNNのバージョンを調べる。

https://www.tensorflow.org/install/install_sources#tested_source_configurations

まず、これで今からインストールするtensorflow, CUDA, cuDNNのバージョンが決まる。

今回は、以下のバージョンをインストールする。

* tensorflow-1.8
* cuDNN 7.1
* CUDA 9.0

## 1. 準備

```shell
$ sudo apt update
$ sudo apt upgrade
```

## 2. CUDAのインストール


```shell
$ sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/7fa2af80.pub

$ wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_9.2.88-1_amd64.deb
$ sudo dpkg -i cuda-repo-ubuntu1604_9.2.88-1_amd64.deb
$ sudo apt update

$ sudo apt install cuda-9-0 cuda-drivers
$ sudo reboot

$ rm cuda-repo-ubuntu1604_9.2.88-1_amd64.deb
```

`~/.bashrc`に以下を追記して、ログオフするかターミナルを開き直して反映させる。

```shell
export PATH="/usr/local/cuda/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"
```

`nvidia-smi`コマンドを実行して、CUDAのバージョンが見れるか確認しておく。

## 2. cuDNNのインストール

実はaptでもインストールできる。

```shell
$ wget http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1604/x86_64/nvidia-machine-learning-repo-ubuntu1604_1.0.0-1_amd64.deb

$ sudo dpkg -i nvidia-machine-learning-repo-ubuntu1604_1.0.0-1_amd64.deb

$ sudo apt-get install libcudnn7
```

## 3. tensorflow-gpuのインストール

```shell
$ pip install tensorflow-gpu
```

pythonで以下のコードを実行して`device_type: "GPU"`が出てれば、tensorflowからGPUが使える状態になっている。

```python
from tensorflow.python.client import device_lib
device_lib.list_local_devices()
```
venv環境にAnsible Jupyter Kernelの導入でハマったため備忘録としてメモを残しておく

Jupyter notebookのカーネルに [Ansible Jupyter Kernel](https://github.com/ansible/ansible-jupyter-kernel) が使えるようになりました。
Ansible Jupyter Kernelを使う事でセルにAnsibleのYAML(Playbook)を書いてネイティブに動かすことが可能です。
今まではチュートリアルとしてJupyter notebookを使ってPlaybookのファイルを出力しコマンドで実行した結果を表示させていましたが、こちらの方が便利そうなのでvenv環境で使ってみたらちょっとハマったのでメモっておきます。

# 1. TL;TD

* Python3じゃ動かなかった
* Ansible Jupyter KernelをインストールしたらJupyterにKernel追加をするコマンドの実行が必要
* venv環境のpipでインストールしたモジュールを使う場合は環境変数にPYTHONPATH設定が必要

# 2. 環境

|   項目  |  バージョン  |
|---------|--------------|
| OS      | macOS Sierra |
| Ansible | 2.6.0        |
| Jupyter | 4.4.0        |
| Python  | 2.7.10       |

# 3. Ansible Jupyter Kernelインストール手順

venv環境とJupyterとAnsibleは既に導入済みを前提とします。

## 3-1. Ansible Jupyter Kernelインストール

(1) pipでインストールします。

```shell-session
$ pip install ansible-kernel
```

## 3-2. JupyterがAnsible Jupyter Kernelを認識しているか確認

(1) 追加したカーネルを認識しているか確認します。

```shell-session
$ jupyter kernelspec list
Available kernels:
  python2    /Users/ユーザー/Library/Jupyter/kernels/python2
```

`python2` しかないので追加します。

(2) jupyterに `ansible jupyter kernel` を追加します。

```shell-session
$ python -m ansible_kernel.install
```

(3) jupyterでAnsible Jupyter Kernelが認識された確認します。

```shell-session
$ jupyter kernelspec list
Available kernels:
  ansible    /Users/ユーザー/Library/Jupyter/kernels/ansible
  python2    /Users/ユーザー/Library/Jupyter/kernels/python2
```

# 4. Jupyter notebookの動作確認

(1) Jupyter notebookを起動します。

```
$ jupyter notebook
```

(2) `New` に `Ansible` があることを確認します。

![スクリーンショット 2018-07-01 0.48.50.png](https://qiita-image-store.s3.amazonaws.com/0/180118/34bf7536-caeb-b200-7d32-88b440f37b85.png)

(3) 試しにdebugモジュールを実行させて動くか確認します。

![スクリーンショット 2018-07-01 0.52.07.png](https://qiita-image-store.s3.amazonaws.com/0/180118/a60099db-36c8-bcd7-0381-fec7eac83827.png)

# 5. 追加モジュールを使う場合(VMwareモジュール編)

例えばVMwareモジュールを動かすには `pyvmomi` の追加導入が必要です。
ここでは `pyvmomi` をインストールして動かすところまでやってみます。

## 5-1. pyvmomiインストール

(1) pipでpyvmomiをインストールします。

```shell-session
$ pip install pyvmomi
```

(2) モジュールのパスをJupyter側へ認識させる必要があるので以下のファイルを作成してパスを記述します。

```shell-session
$ vi ~/.jupyter/jupyter_notebook_config.py
import os

os.environ['PYTHONPATH'] = "/Users/ユーザー/repository/devel/jupyter/venv/lib/python2.7/site-packages"
```

環境変数を設定しないと `pyvmomi` が無いと怒られる...

## 5-2. VMwareモジュールの動作確認

ここでは `devel2` という仮想マシンの電源を付けてみます。

(1) vmware_guestのPlaybookを書いて実行します。

![スクリーンショット 2018-07-01 1.03.44.png](https://qiita-image-store.s3.amazonaws.com/0/180118/931bafc4-d701-07f2-0db3-260818d32bdb.png)

これで問題なく動きました :)
Ubuntu16.04でNICもWifiも認識されない

## 症状

* Ubuntu 16.04.3をPCにクリーンインストール。
* 有線LANを刺してもネットに接続できない。WifiもSSIDの一覧が表示されない。

## 調査

`ifconfig`の結果に`Local Loopbackアドレス`しか表示されない。
NICが正常に認識されていない。

`lspci`コマンドを実行すると、NICとWifiのデバイスが表示される。

```
$ lspci | grep 'Ethernet\|Network'
05:00.0 Network controller: Qualcomm Atheros QCA6174 802.11ac Wireless Network Adapter (rev 32)
06:00.0 Ethernet controller: Qualcomm Atheros Device e0b1 (rev 10)
```

PCIデバイスとしては認識されているが、正常に動作はしていない。
ドライバーの問題なのではないかと思われる。

## 対処

新し目の`linux-firmware`をインストールして再起動したら直った。

https://launchpad.net/ubuntu/xenial/amd64/linux-firmware/1.157.20

今回の場合、完全にインターネットに接続できなかったので、手元にあったAndroidで上記のファイル(`linux-firmware_1.157.20_all.deb`)をダウンロードし、USBでUbuntuに繋いでファイルをコピーして来た。

コマンドとしてはこう

```shell
$ dpkg -i linux-firmware_1.157.20_all.deb
$ sudo reboot  # 再起動
```
MFC PictureCtrl 上にラバーバンドを出す

MFC環境での、PictureControl 上でラバーバンドを作成するときのサンプル。
PictureControl を使うと、WM_MOUSEMOVE などのイベントがそのままでは取れません。
リソースエディタの設定で Notify を True に設定すると、PictureControl を張り付けた親のダイアログのPreTranslateMessage() で、イベントをとれるようになります。
あとは、ラバーバンドの一般的なLDown/Up,MouseMove の処理を行ってやればかけます。

ちょっとはまったポイントは、
SetCapture()とデバイスコンテキストの取得先が、
PictureControl からでないといけなかったこと。
PreTranslateMessage() で取得する座標がデスクトップの座標になっていたこと。

冷静に考えれば自然とそうなるのですが、サンプル参考にしながら書くと
なかなか気づきにくかった。。。

IDC_IMAGE_CTRL ... PictureControl の ID名

補足：
OnLButtonUp() などの UINT nFlags は、ひとまず0固定で。
入力されたキーをとる処理を書けば、ちゃんとしたものになるのでしょうが、
これは必要に応じて。。。


``` SampleAppDlg.cpp
void SampleAppDlg::InitFocusInfo()
{
	focusRect_.bottom = 0;
	focusRect_.left = 0;
	focusRect_.right = 0;
	focusRect_.top = 0;

	isDrawing_ = false;
}

void SampleAppDlg::OnMouseMove(UINT nFlags, CPoint point)
{
	if (isDrawing_ == false) {
		return;
	}

	const RECT newFocusRect = { focusRect_.left ,focusRect_.top ,point.x, point.y };

	HDC hDC = GetDlgItem(IDC_IMAGE_CTRL)->GetDC()->GetSafeHdc();
	DrawFocusRect(hDC, &focusRect_);
	focusRect_ = newFocusRect;
	DrawFocusRect(hDC, &focusRect_);
	ReleaseDC(GetDlgItem(IDC_IMAGE_CTRL)->GetDC());

	CDialogEx::OnMouseMove(nFlags, point);
}

void SampleAppDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
	ReleaseCapture();

	HDC hDC = GetDlgItem(IDC_IMAGE_CTRL)->GetDC()->GetSafeHdc();
	DrawFocusRect(hDC, &focusRect_);
	InitFocusInfo();
	ReleaseDC(GetDlgItem(IDC_IMAGE_CTRL)->GetDC());

	CDialogEx::OnLButtonUp(nFlags, point);
}

void COpenCVApplicationDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
	if (isDrawing_ == true) {
		return;
	}
	GetDlgItem(IDC_IMAGE_CTRL)->SetCapture();
	isDrawing_ = true;

	focusRect_.left = point.x;
	focusRect_.top = point.y;


	CDialogEx::OnLButtonDown(nFlags, point);
}

BOOL SampleAppDlg::PreTranslateMessage(MSG* pMsg)
{
	if (pMsg->hwnd == GetDlgItem(IDC_IMAGE_CTRL)->GetSafeHwnd()) {
		
		RECT rect;
		GetDlgItem(IDC_IMAGE_CTRL)->GetWindowRect(&rect);
		POINT point;
		point.x = pMsg->pt.x - rect.left;
		point.y = pMsg->pt.y - rect.top;

		switch (pMsg->message) {
		case WM_LBUTTONDOWN:
			OnLButtonDown(0, point);
			break;
		case WM_LBUTTONUP:
			OnLButtonUp(0, point);
			break;
		case WM_MOUSEMOVE:
			OnMouseMove(0, point);
			break;
		}
	}
	return CDialogEx::PreTranslateMessage(pMsg);
}

```
Redのエモい関数たち

# Redのおもしろい関数を紹介

Red言語には他の言語にはないユニークな関数に遭遇します。独特の挙動をするので、使いこなすと他の言語ではできない書き方ができて、おもしろいです。
ここでは私が気に入っているエモい関数たちを紹介します。

## collect

`collect`関数は、引数のブロックの中で`keep`キーワードの直後に現れた要素だけ返します。以下は最もシンプルな例です。

```red
collect [1 keep 2 3 4 keep 5]
; == [2 5]
```

この例だと**なにがうれしいねん、これ**という感じですが、ブロック内で自由にコードが書けるので、非常に柔軟です。たとえば、以下のような感じです。

```red
; ブロックから奇数だけ取得
numbers: [1 4 9 7 2]
collect [foreach n numbers [if odd? n [keep n]]]
; == [1 9 7]
```

```red
; 関数型のmap関数のような使い方
; 各文字列の長さを取得
animals: ["dog" "cat" "bird" "elephant"]
collect [foreach animal animals [keep length? animal]]
; == [3 3 4 8]
```

```red
; 辞書データを作る
animals: ["dog" "cat" "bird" "elephant"]
make map! collect [foreach animal animals [keep animal keep length? animal]]
; == #(
;     "dog" 3
;     "cat" 3
;     "bird" 4
;     "elephant" 8
; )
```

私は普段、C#を使っている時は**なんでもLINQで書きたい病**ですが、Redでは**なんでもcollectしたい病**です
## compose

`compose`は渡されたブロックの中で`( )`が付いている箇所だけ評価します。

```red
a: 1 b: 2 c: 3
compose [a (b) c]
; == [a 2 c]
```

動的にコードを組みたい時などに重宝します。

```red
; ここは日本か？
in-japan?: true

; 日本だったら日本語の「あいさつ.txt」からあいさつメッセージを読み込む
; 日本でなければ英語の「greeting.txt」からあいさつメッセージを読み込む
; なお、「%」で始まるのはfile!型のリテラルです。
message: read either in-japan? [%あいさつ.txt][%greeting.txt]

; あいさつメッセージを出力する関数を作る
say-hello: function [] compose [print (message)]
; == func [][print "こんにちは"]
```

## any

`any`はブロックの中の最初のtrueだったものを返します。
どちらかと言うと`truthy`[^1]だったもの、という方がいいかもしれません。
Redでは**falseとnoneだけがfalsy（偽）になり、それ以外はすべてtruthy（真）**です。単純な例としては、以下のようにif文で短絡評価のために使います。

```red
if any [
    2 < 1
    2 < 3
    4 < 3
][
    print "どれかがtrueです"
]
; どれかがtrueです。
```

なお、他の言語だとanyという文言の関数は戻り値がtrue/falseなことが多いですが、Redでは値そのものが返ります。

```red
any [false 7]
; == 7
```

このことと、noneはfalsyであるということを利用して、以下のようにnull合体演算子っぽい使い方が可能です。

```red
a: none
b: any [a "noneの場合の値"]
print b
; noneの場合の値
```

```red
; 以下はRedの辞書リテラル
; 犬は1匹、猫は2匹いる
animal-count: #(
    dog 1
    cat 2
)

print ["猫は" any [animal-count/cat 0] "匹です"]
; 猫は 2 匹です
```

## foreach

foreachは基本的には他の言語と同じ役割で、ブロックの要素を１つずつ列挙して処理します。
列挙用のwordは任意の名称を使えます。

```red
animals: ["dog" "cat" "bird" "elephant"]

; ここではanimalが列挙用のword
foreach animal animals [print animal]
; dog
; cat
; bird
; elephant
```

しかし、Redではブロックを使うことで列挙用のwordを複数指定でき、1ループでいくつ取り出すかを調整できます。

```red
animals: ["dog" "cat" "bird" "elephant"]

; ここではx,yが列挙用のword
; wordの数が2個だと、2個ずつ取り出してくれる。
foreach [x y] animals [print [x "and" y]]
; dog and cat
; bird and elephant
```

# まとめ

Redのユニークな関数や、ちょっとめずらしい関数の使い方をご紹介しました。
Redを触られる際はぜひ使ってみてください。

[^1]: 日本語訳が難しいですが、[Mozilla](https://developer.mozilla.org/ja/docs/Glossary/Truthy)では「trueとみなされるもの」と訳されていますね。
MacBookPro買ったから実行したコマンドをメモしていく

自分用メモ。はたして次使うことはあるのかな。

### 編集履歴

|日付|内容|
|---|---|
|2018/07/01|記事作成。brewとrails追加|
|2018/07/02|React Native追加|
|2018/07/13|yarn install時のエラー解消|
|2018/07/21|sshconfig追加|

### OS

- macOS High Sierra 10.13.5

### homebrew

とりあえずこれ。XCodeはAppStoreから事前にインストール済み。
https://brew.sh/index_ja.html

```
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

### rails開発環境

参考: https://qiita.com/is-lab/items/e0443b79da117ed48294

##### rbenv

```
# install
brew update
brew install rbenv

# update path
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi' >> ~/.bash_profile
source ~/.bash_profile

# update rbenv
rm -rf ~/.rbenv/plugins/ruby-build
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
```

##### ruby

開発中のアプリでは2.5.0を使用。

```
rbenv install 2.5.0
rbenv global 2.5.0
```

##### bundler

```
gem install bundler

(git clone myproject)

bundle update
```

ここで問題発生。postgresのインストールで怒られる。

```
Installing pg 0.18.4 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /Users/tocomi/.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/pg-0.18.4/ext
/Users/tocomi/.rbenv/versions/2.5.0/bin/ruby -r ./siteconf20180630-22055-1az5ohh.rb extconf.rb
checking for pg_config... no
No pg_config... trying anyway. If building fails, please try again with
 --with-pg-config=/path/to/pg_config
checking for libpq-fe.h... no
Can't find the 'libpq-fe.h header
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.
```

`libpg-fe.h` ってのが無いって言われているから、これを含むライブラリをインストールすればいいのかな？
とか考えながらググって、結局先にpostgresインストールしちゃえばうまくいくよってので解決。
参考: https://stackoverflow.com/questions/6040583/cant-find-the-libpq-fe-h-header-when-trying-to-install-pg-gem

```
brew install postgresql

bundle update
bundle install
```

うまくいった。

##### node.js

webpacker使うため。nodebrewを使っていくスタイル。

参考: https://qiita.com/Alex_mht_code/items/422f5ce10d9c9d5729b7

```
brew install nodebrew

nodebrew setup
echo 'export PATH="$HOME/.nodebrew/current/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile

nodebrew install-binary stable
nodebrew use stable
```

##### yarn

homebrewでyarnとnodeを合わせてインストールできるらしいのでそっちのほうが楽だったかも。
参考: https://yarnpkg.com/lang/ja/docs/install/#mac-stable

```
npm install -g yarn
```

yarn install時にエラー発生
参考: https://qiita.com/DQNEO/items/372f20b17af8af8c4d11

```
yarn install --ignore-engines
```

### React Native

公式サイトに沿って進める。
参考: https://facebook.github.io/react-native/docs/getting-started.html

```
# nodeはインストール済みなのでスキップ
brew install watchman

(公式サイトを参考にXCodeの設定をする)

npm install -g react-native-cli
```

### sshconfig

自宅サーバーへの接続設定追加。パスワードでのログイン。

```
vim ~/.ssh/config

Host hoge
  HostName fuga
  User piyo
  Port 22
  ServerAliveInterval 60
```

### ここまで
ハードウェアトラブルで早速修理に出すことになったので意外と早く役に立つかもしれない笑
OpenAPI3.0形式で定義したドキュメントを利用して、APIレスポンスのテストコードを書く(RSpec)

## はじめに
RSpecを利用して、最低限のAPIレスポンステストをしたい！という方に向けて書いてみました。  
細かい部分のテストは置いておいて、とにかく `定義通りのレスポンスが得られているかどうか` のみのテストを簡単に行う方法について書いてます。

Swagger2.0形式でのテストに関しては、多くの記事や専用のgemが見つかる中、OpenAPI3.0形式でのドキュメントでテストを行う方法に対する記載があまりなかったので、備忘録もかねて記事にしました。

## この記事を読んでできるようになること

- APIが、ドキュメント通りの仕様でレスポンスを返すことができているか？ を自動テスとできるようになる

下記のようなケースに、いち早くきづけるようになります。

-  プログラム修正で他のAPIにも不具合がでた
-  知らない間に定義が変わっていた

## 前提条件
- Rails 5を利用してAPI開発を行っている
- OpenAPI3.0形式で記載したAPIドキュメントを利用している
  - 私はswaggerを利用してドキュメントを記載しています
- できるだけコストをかけず、自動テストを書きたい！と思っている

## 下準備
RSpecでのテストにあたり、下記の２つのgemを利用します。

- [json-schema](https://github.com/ruby-json-schema/json-schema)
  - JSONオブジェクトのValidateを行うためのgem
  - これがなきゃ始まらないぐらい便利なので、是非いれましょう
- [rspec-request_describer](https://github.com/r7kamura/rspec-request_describer)
  - request specをシンプルに記載できるようになるgem
  - 正直なくてもRSpecはかけるが、テストコードの可読性や記述量が圧倒的に違うので可能であれば入れたい
  - 本記事では、このgemを利用していることを前提でサンプルコードを記載しています

テストでしか利用しない場合は、下記のようにGemFileに記載し、bundle installをすればOK

```ruby
group :test do
  gem "json-schema"
  gem "rspec-request_describer"
end
```

## テストコードを書く

request specになるため、今回はspec/requestsディレクトリの下にテストコードを記載していきます。

`/api/users`にアクセスすると、下記のようなレスポンスを返すAPIのテストを書いてみます。
### レスポンス
---
```
"users": [
  {
    "id": 1,
    "name": "山田太郎"
  },
  {
    "id": 2,
    "name": "山田花子"
  } 
]
```

### テストコード
---
/spec/requests/user_requst_spec.rb

```ruby
describe User do
  context "ユーザ一覧を取得する" do
    let(api_schema) { #OPenAPI3.0で定義したスキーマ情報を取得 }
    let(errors){ JSON::Validator.fully_validate(api_schema, request.body, strict: true) }
    describe "GET /api/users" do
      is_expected.to eq 200 #レスポンスコードの検査
      expected(errors).to [] #エラーチェック
    end
  end
end
```

### 簡単な解説
---
### スキーマ情報の取得部分
```ruby
let(api_schema) { #OPenAPI3.0で定義したスキーマ情報を取得 }
```

OpenAPI3.0で記載したスキーマ情報を、Hashに変換しておく。
下記のような感じでとってくると楽かと思います（spec_helperにでも取得メソッドとして切り出しておくと便利）

```ruby
api_schema = JSON.parse("スキーマファイル"）.dig("paths", "/api/users", "get", "responses", "200", "content", "application/json", "schema")
```

### レスポンスのバリデーション部分
下記のように記載することで、ドキュメントから精製したスキーマ情報と、レスポンスの結果の検証が可能です。
`strict`オプションを有効にすることで、定義とレスポンスの項目の過不足があった場合でもエラーと判定するようにしてます。
検査の結果、エラーがある場合は、配列にエラーメッセージが返却されるため、RSpec内で空配列`[]`と比較してます。

```ruby
JSON::Validator.fully_validate(api_schema, request.body, strict: true)
```

## まとめ

以上で

- レスポンスが200であること
- レスポンスBodyがOpenAPI3.0で定義した定義通りになっていること

のテストができるようになりました。
API仕様というのは比較的変わりやすく、その都度テストが必要になってくると思います（特に設計初期段階では）
上記のテストを１つ書いておくと、`最低限の品質`は担保できるようになると思います。
この程度のコストで貴族的に自動テスとを行えるようになるのであれば、長く続く開発プロジェクトなどには非常に有効なのではないかと考えてます。

また、今回はレスポンスの検証のために利用しましたが、リクエストの検証にも利用できるので、APIでのリクエスト受付時に必ず通すValidationとして実装することもできます。

今回、いろいろ探したもののあまり情報がなく、ちょっと困ったので記事にしてみました。

## おわりに
私自身、本記事の内容のテストを書くために、今更ながらRSpecをもう一度勉強しなおした人間です。
より良い方法などがありましたら、是非ご意見いただけるとありがたいです。
linux コマンドのメモ

Vimでコピペしたいときは、
iで入力モードにする前に、:でコマンドモードにして、
:set pasteと入力してから、iで入力モードにしてcommand + vでコピペすれば良い。

参考）http://sugamasao.hatenablog.com/entry/20080512/1210613116




特定の文字列があるファイルを抽出
grep -r "アカウントが更新"

参考）http://imagawa.hatenadiary.jp/entry/20110913/1315921917


間違えて覚えていた読み方
yml  →　ヤムル
pry  →　プライ
HerokuでPlayframeworkのProcfileのハマりどころ

# はじめに
　PlayFrameworkを使ってWebサービスを作ってみたので、簡単にデプロイできると噂のHerokuを今更ながら試してみました。git push heroku masterで使用しているフレームがPlayFrameworkということを検出して自動でビルド開始するログを見て思わず「Heroku ってすげー！」ってなってましたが、ステータスがcrashedとなってハマったので、Herokuデプロイ時に必要なProcfileについての解決方法を簡単にまとめたいと思います。

#環境
- PlayFramework 2.4.1(Java)

# 解決方法
　Herokuでデプロイをする場合、Procfileに最低限の情報を記載してあげる必要がありますが、その書き方をきちんと理解してなかったようです。
ちなみに[Herokuの公式サイト](https://devcenter.heroku.com/articles/heroku-cli)には以下のように記載するように書かれています。

```bash:Procfile
web: target/universal/stage/bin/{your project name} -Dhttp.port=$PORT
```

　ここで私は、your project name にHerokuのプロジェクトネームを記載していましたが、ここにはPlayFrameworkのプロジェクト情報が記載されている「build.sbt」の name属性を記載する必要があります。

```bash:build.sbt
name := "XXX" /* ここが　{your project name}に相当 */

version := "1.0"

lazy val `baseball` = (project in file(".")).enablePlugins(PlayJava,PlayEbean)


resolvers += "scalaz-bintray" at "https://dl.bintray.com/scalaz/releases"

scalaVersion := "2.11.11"

libraryDependencies ++= Seq(javaJdbc, cache, javaWs)

unmanagedResourceDirectories in Test <+= baseDirectory(_ / "target/web/public/test")
``` 

　PlayFrameworkはバージョンによってProcfileｎ書き方は変わるようですが、[Herokuの公式サイト](https://devcenter.heroku.com/articles/heroku-cli)に加えてHerokuのrunコマンドを使ってHerokuに動作しているコンテナの実態を抑えるのが問題解決には早そうです。

```bash 
heroku run "ls -l target/universal/stage/bin"
Running ls -l target/universal/stage/bin on ⬢ apps... up, run.5849 (Free)
total 28
-rwx------ 1 u43543 dyno 13969 Jun 30 11:37 apps
-rw------- 1 u43543 dyno  9362 Jun 30 11:37 apps.bat
```

上記のように、target/universal/stage/bin以下に何が格納されているのか把握できれば、Procfileには以下のように記載すればOKだということが分かると思います。。

```bash:Procfile
web: target/universal/stage/bin/apps -Dhttp.port=$PORT
```


# 最後に
　Herokuに依存するProcfileの書き方でハマってしまったわけですが、これさえ分かっておけばHerokuのログを見れば解決していける内容(Herokuには依存しない)だと思います。
Rails チュートリアル メモ 第13章

# メモ

## references

```
$ rails generate model Micropost content:text user:references
```

のように、モデルの generate 時に `references` 型を指定すると、外部キー参照付きのカラムが作られる。また、Micropost モデルに

``` ruby
  belongs_to :user
```

が自動的に追記される。これによって、Micropost のインスタンスに `user` メソッドが生えて、`micropost.user` のように関連するユーザーを参照することができるようになる。

たぶん xxx_id の xxx の部分が重要なんだろう。

## belong_to / has_many

belongs_to / has_many の関係を設定することで、チュートリアル中の [表13.1](https://railstutorial.jp/chapters/user_microposts?version=5.1#table-association_methods) のようなメソッドが使えるようになる。このうち1つはすでに前述した。

重要なのは、所有側（今回でいう User）に `user.microposts.create` のようなメソッドが生えることである。これを使うと、`user_id` が初めから埋まった状態で Micropost のインスタンスを作ることができる。むしろ、Micropost のインスタンスは **そのようにして作るのが慣習** らしい。

```ruby
# 慣習的に間違い
@micropost = Micropost.new(content: "Lorem ipsum", user_id: @user.id)

# 慣習的に正しい
@micropost = @user.microposts.build(content: "Lorem ipsum")
```

`build` は `create` と違って DB に保存しない。細かいところでいうと、`@user.micropost **s**` のように複数形であることに注意。 has_MANY だからね。

belong_to は Micropost モデルの generate 時に自動的に記述されたが、User クラスに has_many を書くところまではやってくれないので、そこは自分で書く必要がある。

## 並び順の制御

default_scope を使う。

チュートリアルでは default_scope を並び順の制御にだけ使っているが、そのためだけの機能ではないんだろうなと思う。詳細は [こちら](https://railsguides.jp/active_record_querying.html#%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97%E3%82%92%E9%81%A9%E7%94%A8%E3%81%99%E3%82%8B) を参照。何となく、DB から検索するときの SQL にデフォルト条件を設定するようなイメージっぽい。

## 親を消したときの子の扱い

親側のモデルで設定する。具体的には has_many にオプションを渡す。

`dependent: :destroy` を渡すと、親（user）が消えたときに子（microposts）も消す。DB にゴミが残らないのでスッキリする。他にもいくつか選択肢があるんだろうな。

## DB の操作

```ruby
User.order(:created_at).take(6)
```

Rails から DB を操作するときは、上記のようにメソッドチェーンを使う。
`take` と似た働きのメソッドとして `limit` がある。`take` は User のインスタンスの配列が得られるが、`limit` で得られるのは ActiveRecord::Relation クラスのオブジェクトである。

・・・とここまで書いてからわかったけど、take は ruby の Enumerable に定義された標準メソッドでした。

## Fixture 同士の関連付け

```
orange:
  content: "I just ate an orange!"
  created_at: <%= 10.minutes.ago %>
  user: michael
```

上記のような **micropost の** Fixture を書くと、自動的に **user の** Fixture から michael を探して関連付けてくれる。`user_id` ではなく `user` なところにも注意。Rails のこういう仕様を把握しきれる自信がない。

## resources によるルーティングの only オプション

route.rb で resources を使ってルーティングを定義すると、RESTful なルートが片っ端から用意されてしまうが、今回のように「create と destroy しか使う気がない」という場合は、only オプションで絞ることができる。

```
  resources :microposts,          only: [:create, :destroy]
```

## DB の操作2

where 句は以下のように使う。

```ruby
Micropost.where("user_id = ?", id)
```

ここで重要なのが `?` の利用だ。こうすることで、変数の中身がエスケープされて展開されるらしい。つまり SQL インジェクションの危険性が減る。下記のようにしないよう注意。

```ruby
# ダメな例！
Micropost.where("user_id = #{id}")
```

## 簡易 friendly redirecting

`request.referrer` を使えば可能。ログインの場合はログイン画面が `request.referrer` に入ってしまうのでダメだが、ポスト削除の場合は削除画面を経由したりすることがないので、これで十分。

```ruby
redirect_to request.referrer || root_url
```

`||` を使って、request.referrer が空だったときのケアをしている。rails 5 からは `redirect_back(fallback_location: root_url)` でもいいらしい。

## バリデーションの自作

* validates ではなく validate なので注意（s がつかない）
* データをチェックして、不正だったら `errors.add` するようなメソッドを作って登録する
LaTexの参考文献表示スタイルについて

#概要

LaTexで論文を書く際、文内引用は`\cite{einstein}`、表示スタールの指定は`\bibliographystyle{unsrt}`、最後bibファイルの読み込んで参考文献を出力するのは`\bibliography{sample}`である（[参考](https://ja.sharelatex.com/learn/Bibliography_management_with_bibtex)）。

BIBファイルは以下の雰囲気です。

```text:sample.bib
@種類{今回説明対象外,
	title 			= {タイトル},
	author			= {作者},
}
```

これを参考文献に出力されると以下の雰囲気になる。

```text:論文.pdf
...前略...

参考文献
　[1] 作者, タイトル
```

が、正確には、bibファイルに記載された種類、指定された表示スタイルによって、参考文献に表示される項目（上記のtitle, authorなどのこと）も変わる。その対照例を作成しました。

#bibファイルに記載できる種類

bibファイルに記載できる種類は主に以下がある（[参考](https://ja.sharelatex.com/learn/Bibliography_management_with_bibtex#Reference_guide)）。

```
article
book
booklet
conference
inbook
incollection
inproceedings
manual
masterthesis
misc
phdthesis
proceedings
techreport
unpublished
```

#bibliographystyleで指定できる表示スタイル
指定できる表示スタイルは以下にある（[参考](https://ja.sharelatex.com/learn/Bibtex_bibliography_styles)）。

```
abbrv
acm
alpha
apalike
ieeetr
plain
siam
unsrt
```

#bib種類とスタイルの組み合わせ例
上記のbib種類とスタイルの組み合わせ例
##試験方法
　以下のようにbibファイルを作成すると、参考文献にどの項目がどの位置、どのように表示されたかが簡単に確認できる。

```text:試験に利用されるbibファイルの一部
@article{article,
	title 			= {title},
	url 			= {url},
	urldate 		= {urldate},
	author			= {Author Name,Buthor mid Name, Cuthor Familyname},
	organization 	= {organization},
	address			= {address},
	year 			= {year},
	month			= {month},
	note            = {note},
	annote			= {annote},
	booktitle		= {booktitle},
	chapter			= {chapter},
	crossref		= {crossref},
	edition			= {edition},
	editor          = {editor},
	institution     = {institution},
	journal         = {journal},
	key             = {key},
	number          = {number},
	organization    = {organization},
	pages           = {pages},
	publisher       = {publisher},
	school          = {school},
	series          = {series},
	type            = {type},
	volume          = {volume},
	ISBN            = {ISBN},
	ISSN            = {ISSN},
	LCCN            = {LCCN},
	abstract        = {abstract},
	keywords        = {keywords},
	price           = {price},
	copyright       = {copyright},
	language        = {language},
	contents        = {contents},
}
```
##試験結果
![rapture_20180630235256.png](https://qiita-image-store.s3.amazonaws.com/0/32912/61421353-ba4b-3b40-1128-301a7c64003f.png)
![rapture_20180630235513.png](https://qiita-image-store.s3.amazonaws.com/0/32912/72d7c7ab-7d04-4351-9d5d-739a8da1331a.png)
![rapture_20180630235632.png](https://qiita-image-store.s3.amazonaws.com/0/32912/9d725726-f268-a1ec-9bb8-1d01af4e0fe9.png)
![rapture_20180630235738.png](https://qiita-image-store.s3.amazonaws.com/0/32912/a6e43b65-f0e3-7d97-fe86-c3922291c347.png)
![rapture_20180630235848.png](https://qiita-image-store.s3.amazonaws.com/0/32912/1222a6fc-ebd1-3503-a507-c5740b2cc5bb.png)
![rapture_20180701000001.png](https://qiita-image-store.s3.amazonaws.com/0/32912/d91f61a0-94bc-8428-2b22-183c5a621b09.png)
![rapture_20180701000105.png](https://qiita-image-store.s3.amazonaws.com/0/32912/e26cbc40-683b-6be5-4da5-612b7c460e7c.png)
![rapture_20180701000210.png](https://qiita-image-store.s3.amazonaws.com/0/32912/9a325497-b5ca-4886-feac-25d34833b8ac.png)

##試験で利用されたファイル
[overleafにある](https://www.overleaf.com/read/jyzrzhphkxxd#/66388069/)
HandsontableのfixedColumnsLeftによる不具合の対処法

Handsontable for Reactで開発していて遭遇した躓きポイントと対処法を書きます。

#固定カラムと非固定カラムとの間がズレる
以下のようにrowHeadersを設定せずにfixedColumnsLeftをセットすると、固定カラムと非固定カラムとの間がズレます。

    <HotTable
        data={data}
        fixedColumnsLeft={2}
    />

<img width="277" alt="スクリーンショット 2018-06-30 23.58.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/4196/25170022-462b-b4be-0be1-06aebe2bc1b1.png">
（１、２行目が固定カラム、３、４行目が非固定カラム）

#対処法
「autoRowSize: true」をセットします。

    <HotTable
        data={data}
        fixedColumnsLeft={2}
        autoRowSize
    />

<img width="278" alt="スクリーンショット 2018-07-01 0.15.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/4196/71f8d77c-cbc1-26b7-a859-634ea7ddcc09.png">
スッキリ！

#参考
Handsontableは日本語の情報が少ないので対処法を探すのに苦労しました。
・https://github.com/handsontable/handsontable/issues/4202
Pythonでディレクトリ,ファイル操作のやり方まとめ

# 概要
pythonのディレクトリ、ファイル操作のときに使うモジュールのまとめです。



# パスからディレクトリ名を取得する(os.path.dirname)
```python:terminal
>>> os.path.dirname("/aaa/bbb/ccc/ddd.txt")
'/aaa/bbb/ccc'
```


# パスからファイル名を取得する(os.path.basename)
```python:terminal
>>> os.path.basename("/aaa/bbb/ccc/ddd.txt")
'ddd.txt'
```


# パスからディレクトリ名とファイル名を取得する(os.path.split)
```python:terminal
>>> dir, file = os.path.split("/aaa/bbb/ccc/ddd.txt")
>>> dir
'/aaa/bbb/ccc'
>>> file
'ddd.txt'
```

# パス、ファイル名から拡張子を取得する(os.path.splitext)
```python:terminal
>>> dir, ext = os.path.splitext("/aaa/bbb/ccc/ddd.txt")
>>> dir
'/aaa/bbb/ccc/ddd'
>>> ext
'.txt'
```


# パスを結合する(os.path.join)
```python:terminal
>>> dir = "/aaa/bbb/ccc"
>>> file = "ddd.txt"
>>> os.path.join(dir, file)
'/aaa/bbb/ccc/ddd.txt'
```


# ディレクトリを生成する(os.makedirs)
```python:terminal
>>> os.makedirs("./1/2/3", exist_ok=True)
```
ディレクトリ"1"と"2"がなければ一緒に生成されます。
exist_ok=Trueにしておくと、すでにディレクトリが存在していても例外を発生させずに無視します。


# ディレクトリを削除する(shutil.rmtree)
```python:terminal
>>> os.makedirs("./1/2/3", exist_ok=True)
>>> shutil.rmtree("./1")
```
この場合、ディレクトリ"1","2","3"全てが削除されます。

```python:terminal
>>> os.makedirs("./1/2/3", exist_ok=True)
>>> shutil.rmtree("./1/2/3")
```
この場合は、ディレクトリ"3"のみが削除されます。


# ファイルをコピーする(shutil.copyfile/shutil.copy)
名前を指定してコピーする。

```python:terminal
>>> shutil.copyfile("./test.txt", "./test2.txt")
'./test2.txt'
```
コピー元のファイル名でコピーする。

```python:terminal
>>> shutil.copy("./test.txt", "./temp")
'./temp/test.txt'
```


# ファイルを移動する(shutil.move)
```python:terminal
>>> shutil.move("./test.txt", "./temp")
'./temp/test.txt'
```


# ディレクトリかどうか判定する(os.path.isdir)
```python:terminal
>>> os.makedirs("./1", exist_ok=True)
>>> os.path.isdir("./1")
True
```


# ファイルかどうか判定する(os.path.isfile)
```python:terminal
>>> os.path.isfile("./test.txt")
True
```


# ディレクトリ,ファイルが存在するかどうか判定する(os.path.exists)
```python:terminal
>>> os.path.exists("./1")
True
>>> os.path.exists("./test.txt")
True
```


# 画像の形式を判定する(imghdr.what)
```python:terminal
>>> imghdr.what("./1.png")
'png'
>>> imghdr.what("./2.jpg") # 2.jpgはpng形式の画像ファイル
'png'
>>> imghdr.what("./test.txt") # 画像以外のファイルは何もしない
>>> 
```
imghdrを使うと指定したファイルの画像形式がわかります。
拡張子が間違ったファイルでも正しい画像形式を返します。
例えば、以下の例では"2.jpg"は拡張子はjpegですが、中身はpng形式のファイルです。
PySide2(pyqt5)を直感的に読みやすく書いてみた

#BoxLayoutをQtWidgets.QWidgetの拡張にしてみる
pyside2(pyqt5)がわかりずらいのは、QtWidgets.QHBoxLayoutとかQtWidgets.QVBoxLayoutがQtWidgets.QWidgetの拡張じゃないせいだと理解した。それで、BoxLayoutをQtWidgets.QWidgetに取り込んでみた。それと、layoutは入れ子構造なのに、pythonがインデントに厳格なせいで、更に分かりずらくなっている。かなり強引だが、スクリプトからレイアウトが、イメージできるような書き方を考えてみた。

```py
import sys
from PySide2 import QtCore,QtWidgets

class HLayoutWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.layout = QtWidgets.QHBoxLayout()
        self.setLayout(self.layout)
    def addWidget(self,w):
        self.layout.addWidget(w)

class VLayoutWidget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.layout = QtWidgets.QVBoxLayout()
        self.setLayout(self.layout)
    def addWidget(self,w):
        self.layout.addWidget(w)

class Window(HLayoutWidget):
    def __init__(self):
        super().__init__()
        self.resize(500, 500)
        self.setWindowTitle("layout demo")
        leftLayout = VLayoutWidget();                          self.layout.addWidget(leftLayout)
        leftButton1 = QtWidgets.QPushButton();                 leftLayout.addWidget(leftButton1)
        leftButton2 = QtWidgets.QPushButton();                 leftLayout.addWidget(leftButton2)
        leftButton3 = QtWidgets.QPushButton();                 leftLayout.addWidget(leftButton3)
        rightLayout = VLayoutWidget();                         self.layout.addWidget(rightLayout)
        self.rightButton1 = QtWidgets.QPushButton("Button1");  rightLayout.addWidget(self.rightButton1)
        self.rightButton2 = QtWidgets.QPushButton("Button2");  rightLayout.addWidget(self.rightButton2)
        
        leftLayout.sizeHint = lambda: QtCore.QSize(450,240)
        leftLayout.setSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Expanding)
        
        rightLayout.layout.setContentsMargins(0, 0, 0, 0)
        
        leftButton1.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_TitleBarMenuButton))
        leftButton2.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_MessageBoxInformation))
        leftButton3.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_MessageBoxQuestion))
        
        self.rightButton1.clicked.connect(self.hoge1)
        self.rightButton2.clicked.connect(self.hoge2)
        
    def hoge1(self):
        self.rightButton1.setText("Button click")
        
    def hoge2(self):
        self.rightButton2.setText("Button click")
        
if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())
```

![2018-07-01.png](https://qiita-image-store.s3.amazonaws.com/0/153571/826aad85-d8cf-da63-d27b-e942e4e4cbe3.png)

#シンプルな入れ子構造がいい
QtWidgets.QHBoxLayoutは、addWidget()で子を持つことはできる。だけど、QtWidgets.QWidgetのように実体をもってないので、サイズの変更ができない。サイズを変更するにはQtWidgets.QWidgetにsetLayout()を使ってQtWidgets.QWidgetにセットしなければならない。セットしなくてもレイアウトはできる。この辺りが、面倒なところである。いっそのことQtWidgets.QWidgetにaddWidget()を組み込めば書き方がシンプルになると思い試してみた。
レイアウトは入れ子構造なのに、pythonがインデントに厳格なせいで、更に分かりずらく部分については、pythonで ; を使っての1行で書くやり方で親子関係も、わかりやすくなった。
レイアウト部分、Widgetの細かい調整、シグナル、スロットと分けて書けば、Qtデザイナーを使わずに、直感的に書ける。かなりシンプルになりました。