OmniAICreator/Qiita-1.07M huggingface dataset:
KuduのCustom Deployment Script でのデプロイにて、MSBuild14が動かなくなった

今まで普通に動いていたCustom Deployment Script(Azure Web Apps)によるデプロイ処理が、突然エラーで終了するようになってしまいから何とか改善まで至った時のメモです。

そのため情報が不十分である可能性がありますので、ご注意ください。

## どんなエラーが出たのか

    The syntax of the command is incorrect.
    D:\Program Files (x86)\SiteExtensions\Kudu\73.10510.3399\bin\Scripts\starter.cmd deploy.cmd

## 発生の経緯まで

コードの変更も特になかったため、残念ながら分からず終いでした。

## 調べた内容

ツールをVisual Studio2015から2017に変えたからか？とも思いましたが、変えたのは2018年4月ころで、そのうえ事象が発生するまでの間に何度となくデプロイは行っていたので対象外としました。

その他文字コード、改行コードも調べてみましたがデプロイできていたころと変わらずエラー、、、

ちなみにそれぞれ以下の設定になってました。

- 文字コード : UTF-8
- 改行コード : CRLF

## どうやって直したのか

上記のエラーをさらに追ってみたところ、MSBuild14が動作してないらしいことまで追えたため、

[Add "Build Tools for Visual Studio 2017" to Azure App Service #2350](https://www.notion.so/Kudu-Custom-Deployment-Script-1f9f5ccaf5674d19ad84706539fa6007#395672065b9f4eca9819c2477ec2fcc3)

に記載のある修正内容に則って(コメントアウトが変更前のコード)

```shell
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Deployment
:: ----------

echo Handling .NET Web Application deployment.

:: 1. Restore NuGet packages
IF /I "XXXXX.sln" NEQ "" (
  :: call :ExecuteCmd nuget restore "%DEPLOYMENT_SOURCE%\XXXXX.sln"
  call :ExecuteCmd nuget restore "%DEPLOYMENT_SOURCE%\XXXXX.sln" -MSBuildPath "%MSBUILD_15_DIR%"
  IF !ERRORLEVEL! NEQ 0 goto error
)
``` 

加えて

```shell
:: 2. Build to the temporary path

IF /I "%IN_PLACE_DEPLOYMENT%" NEQ "1" (
  :: call :ExecuteCmd "%MSBUILD_PATH%" "%DEPLOYMENT_SOURCE%\AAAA.BBBB\AAAA.BBBB.csproj" ^
  call :ExecuteCmd "%MSBUILD_15_DIR%\MSBuild.exe" "%DEPLOYMENT_SOURCE%\AAAA.BBBB\AAAA.BBBB.csproj" ^
  /nologo ^
  /verbosity:m ^
  /t:Build ^
  /t:pipelinePreDeployCopyAllFilesToOneFolder ^
  /p:_PackageTempDir="%DEPLOYMENT_TEMP%";AutoParameterizationWebConfigConnectionStrings=false;Configuration=%DEPLOY_MODE%;UseSharedCompilation=false ^
  /p:SolutionDir="%DEPLOYMENT_SOURCE%\.\\" %SCM_BUILD_ARGS%
) ELSE (
  :: call :ExecuteCmd "%MSBUILD_PATH%" "%DEPLOYMENT_SOURCE%\AAAA.BBBB\AAAA.BBBB.csproj" ^
  call :ExecuteCmd "%MSBUILD_15_DIR%\MSBuild.exe" "%DEPLOYMENT_SOURCE%\AAAA.BBBB\AAAA.BBBB.csproj" ^
  /nologo ^
  /verbosity:m ^
  /t:Build ^
  /p:AutoParameterizationWebConfigConnectionStrings=false;Configuration=%DEPLOY_MODE%;UseSharedCompilation=false ^
  /p:SolutionDir="%DEPLOYMENT_SOURCE%\.\\" %SCM_BUILD_ARGS%
)
``` 

というように修正したところ、無事起動するようになりました。
ERROR: An HTTP request took too long to complete. Retry with --verbose to obtain debug information.(Docker + Rails )

# 状況

```
## スペック
MacOS HighSierra 10.13.5
Docker For Mac version 18.03.1-ce-mac65
```

`❯ docker-compose run web bundle install`　実行時に下記のError

```
ERROR: An HTTP request took too long to complete. Retry with --verbose to obtain debug information.
If you encounter this issue regularly because of slow network conditions, consider setting COMPOSE_HTTP_TIMEOUT to a higher value (current value: 60).

```

# 解決策
Docker For Mac を再起動したら解決しました。



<img width="220" alt="スクリーンショット 2018-06-25 08.20.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/112515/52b290a0-2b31-ff04-5d08-aa47ebf60d5f.png">

### twitterもフォローよろしくおねがいします。 ！
https://twitter.com/yoshixj
WordPressのメディア追加、アップロード時に選択肢を制限する方法

WordPressのメディアの追加の画面って、なんか無駄なもんが多くて、使いにくいなーって思ってたんすよね。
まぁ自分が使う分には、我慢すればいいだけだけど（とはいえ気持ち悪い）、
お客さんにさぁどうぞってやるには、やや雑ですよね。

そこで、選択肢を制限する方法です。
CSSで見えないようにしてるだけなんですがｗ

```functions.php
// メディアアップロード時の選択肢を制限
add_action( 'admin_print_styles', 'admin_css_custom' );
function admin_css_custom() {
  // "hoge"というカスタム投稿タイプだけに適用。
  global $post;
  if(!isset($post) || "hoge" != $post -> post_type){
    return;
  }
  echo '
    <style>
      .attachment-details label[data-setting="caption"],
      .attachment-details label[data-setting="description"],
      div.attachment-display-settings .alignment option[value="center"],
      div.attachment-display-settings .alignment option[value="none"],
      div.attachment-display-settings .setting:nth-child(3),
      div.attachment-display-settings .setting:nth-child(4)
      {display: none;}
    </style>';
}
```

上から、
使いみちがあんまりない「キャプション」、「説明」、
「配置」の選択肢の「中央」と「なし」
そして、「リンク先」、「サイズ」

これに合わせて、画像の自動生成にも制限をかけておきました。
デフォルトで生成される「中サイズ」と「大サイズ」も不要そうだったので、
![メディア設定](https://qiita-image-store.s3.amazonaws.com/0/59927/24e64330-9a3c-57be-f406-19d9586fc92f.png)
メディア設定の中サイズと大サイズの数値を削除しておきました。
そうすることで、生成されないし、選択肢にも出てこなくなる、って寸法。

あと、前半に書いてある処理は、特定のカスタム投稿タイプのみに適用させる処理。
ダブルクォートを赤く染める

[zaim](https://zaim.net/)のCSVをいじっているときに、なぜかダブルクォートがエスケープされてたりされてなかったりする現象に遭遇したのですが、よく見たらそれはダブルクォート(U+0022)ではなく `“`(U+201C) と `”`(U+201D) でした。（[引用符 - Wikipedia](https://ja.wikipedia.org/wiki/%E5%BC%95%E7%94%A8%E7%AC%A6)）
たびたびこれではまってる気がしたので、awkでダブルクォート(U+0022)だけエスケープシーケンスで色をつけてみることにしました。

```awk:ダブルクォートを赤色にするawkスクリプト
{
  gsub("\"", "\033[31m\"\033[m", $0);
  print $0;
}
```

<img width="1053" alt="スクリーンショット 2018-06-25 6.13.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/26038/dfddce58-55ac-ca68-8411-8d507e9661ac.png">

劇的にわかりやすくなった感じはしないけど、まあ、無いよりはマシかな・・・
FessとElasticsearchとLuceneの違い

Fessがクローリングして検索できるようになるまで、内部ではElasticsearchやLuceneが動いています。
どの部分がFessで、どの部分がElasticsearchやLuceneの役割なのかを簡単に記述します。

#Luceneの役割
倒置Indexを作成できる全文検索エンジンです。全文検索の機能や構文解析機の機能はこのレイヤーで持っています。自分で独自の構文解析機（アナライザー）を作成しようと思ったらこのレイヤーで作成します。

#Elasticsearchの役割
Luceneを上のレイヤーからラッピングして動いています。Luceneのインデックス作成や検索機能、アナライザーの設定を扱い易いAPI形式で提供しています。プラグイン機能を経由してLuceneのアナライザーをElasticsearchのレイヤーで設定する事ができます。プラグインでない独自のアナライザーを作ろうと思ったらLuceneのレイヤーを理解する必要があります。

#Fessの役割
クローリングをしてHTMLを解析する他、Elasticsearchで作成するIndexの定義をしています。検索結果(Elasticsearchにクエリーを投げた結果)をHTML形式でユーザーに表示するのもFessの役割です。検索クエリーはFessではほぼ加工せずElasticsearchAPIをそのままFessが呼び出す形で実行しています。

##おわりに
読んでいただきありがとうございます。

仕事でFessで社内リソースを検索するシステムを作り、その際に検索精度が弱かったために解析器まわりをいじる必要があったのですが、その際に内部構造が分からず苦戦しました。

調べていたらそこそこ理解が深まったので、詳しく知りたい方は連絡いただければ説明出来る事もあると思います。
CSSでのvar + calcでの計算方法

# 背景
`css` 内で変数定義して計算をしたかったので動作などを確認した。
備忘録的な…
`※Chromeでしか動作確認しておりません`

# はじめに
`css`でも変数定義して計算ができる。
下記のような感じ。

## 変数定義と呼び出し
```css
:root {
  --w: 30px;/*変数定義*/
}
.c{
  width:var(--w);/*呼び出し*/
}
```

## 計算
```css
.c{
  width:calc(100% - 10px);
}
```

# 実施
この２つを利用すれば変数計算で行けるはず！

```css
:root {
  --p1: 10px;/*変数定義*/
  --n1: 10;/*変数定義*/
}
.c{
  width:calc(var(--p1));        /*var:10px        ok*/
  width:calc(var(--p1) * 10);   /*var:10px * 10   ok*/
  width:calc(var(--p1) * 10px); /*var:10px * 10px ng*/
  width:calc(var(--p1) + 10px); /*var:10px + 10px ok*/
  
  width:calc(var(--n1));        /*var:10          ng*/
  width:calc(var(--n1) * 10);   /*var:10   * 10   ng*/
  width:calc(var(--n1) * 10px); /*var:10   * 10px ok*/
  width:calc(var(--n1) + 10px); /*var:10   + 10px ng*/

  width:calc(var(--n1) * var(--p1));           /*var:10 * var:10px ok*/
  width:calc(var(--n1)*1px + var(--p1));       /*(var:10 * 1px) + var:10px ok*/
  width:calc(calc(var(--n1)*1px) + var(--p1)); /*(var:10 * 1px) + var:10px ok*/
  width:calc(var(--n1)*1px + var(--n1)*1px);             /*(var:10 * 1px) + (var:10 * 1px) ok*/
  width:calc(calc(var(--n1)*1px) + calc(var(--n1)*1px)); /*(var:10 * 1px) + (var:10 * 1px) ok*/

  width:calc(10%-10px);         /*    10% - 10px  ng*/
  width:calc(10%+10px);         /*    10% - 10px  ng*/
  width:calc(10px + 10px);      /*    10px + 10px ok*/
  width:calc(10% + 10px);       /*    10% + 10px  ok*/
  width:calc(10% - 10px);       /*    10% - 10px  ok*/
}
```

## 結論
1. `+`,`-`をするときは前後にスペースが無いと上手く動かない
2. `px`などの単位がなければ計算できない場合がある(`+`,`-`など)
3. 計算は`calc`で囲わなくてもOK

個人的に`１`でめっちゃ詰まった…
RxSwiftでonErrorを遅延させる

APIの読込中にアニメーションを表示させるために一定時間`onNext`,`onError`を遅延させたいことがあったのでその実装について

## NGな例

```swift
// delaySubscriptionを使うことで購読は遅延させられるが
// repository経由のAPI呼び出しそのものが遅くなってしまうので🙅‍♂️
self.repository.get()
    .delaySubscription(1, scheduler: scheduler)
    .subscribe(
        onSuccess: { [weak self] _ in
            self?.state.accept(.success)
        }, onError: { [weak self] _ in
            self?.state.accept(.fail)
        }
    ).disposed(by: disposeBag)

// API呼び出しを実行しつつonSuccessの呼び出しは遅延されるが
// APIがネットワークエラーなどの時に即時onErrorが呼ばれるてしまうので🙅‍♂️
let timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance).take(1).asSingle()
Single.zip(self.repository.get, timer)
    .subscribe(
        onSuccess: { [weak self] _ in
            self?.state.accept(.success)
        }, onError: { [weak self] _ in
            self?.state.accept(.fail)
        }
    ).disposed(by: disposeBag)
```

## 最終的な実装

```swift
// Observable#materialize()を使うことでAPI呼び出しの結果を`Observable<RxSwift.Event<Self.E>>`にラップする
// それによりAPI呼び出しが失敗してもonNextに`Error`が流れてくるので、timerの発火を待って処理が行える🙆‍♂️
let timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance).take(1)
Observable.zip(timer, self.repository.get().asObservable().materialize()) { $1 }
    .dematerialize()
    .take(1)
    .subscribe(
        onNext: { [weak self] _ in
            self?.state.accept(.success)
        }, onError: { [weak self] _ in
            self?.state.accept(.fail)
        }
    ).disposed(by: disposeBag)
```
複数の配列やイテレータを同時にforeachする

従来だと`each()`で配列ポインタをぶん回したり、`array_map(null)`を使ったりするのが一般的な方法だった。

## 要約

 * [`each()`](http://php.net/manual/ja/function.each.php)はPHP8の頃には削除されるよ
 * `array`がだめなら[`ArrayIterator`](http://php.net/manual/ja/class.arrayiterator.php)でいいじゃん
 * 


## 今回の提案

`parallel()`ってヘルパー関数を作ってやります。

```php
/**
 * @param iterable[] $iters    イテレータ／配列の組
 * @param int      $key_index  foreachのkeyになるindex
 * @param int|null $stop_index イテレーションを停止する条件のindex (無指定は$key_index)
 */
function parallel(array $iters, $key_index = 0, $stop_index = null)
{
    foreach ($iters as $i => $iter) {
        if (is_array($iter)) {
            $iters[$i] = new ArrayIterator($iter);
        }
    }
    
    if (count($iters) == 0) {
        throw new BadFunctionCallException();
    }

    $stop_index = $stop_index ?? $key_index;

    if (!isset($iters[$key_index])) {
        throw new OutOfRangeException();
    }

    if (!isset($iters[$stop_index])) {
        throw new OutOfRangeException();
    }

    while ($iters[$stop_index]->valid()) {
        $key = $iters[$key_index]->key();
        $current = [];
        foreach ($iters as $iter) {
            if ($iter->valid()) {
                $current[] = $iter->current();
                $iter->next();
            } else {
                $current[] = null;
            }
        }
        
        yield $key => $current;
    }
}
```

こうやって動かす。

```php
<?php

$fruits = ['りんご', 'ばなな', 'みかん'];
$prices = [100, 140, 80];

foreach (parallel([$fruits, $prices]) as $key => [$fruit, $price]) {
    var_dump([$key =>compact('fruit', 'price')]);
}
// array(1) {
//   [0]=>
//   array(2) {
//     ["fruit"]=>
//     string(9) "りんご"
//     ["price"]=>
//     int(100)
//   }
// }
// ...
```

`as $key => [$fruit, $num]` の部分を `as $key => $row` にすれば、実際は `array_map(null)` と同じようになる。つまりは`zip`関数と同じ動作だ。

大事なポイント

 * `array_map()`と違って「配列以外も同時にイテレーションできる
    * ジェネレータなども同時に指定できる **←超重要**
 * `array_map(null)`と同じように、長さが足りない場合は`null`で埋められる
 * `foreach`のキーになるイテレータを指定できる (無指定では`0`)
 * `foreach`を停止する条件のイテレータを指定できる (無指定ではキーと同じ)
    * 迂闊にも無限リストを停止条件にすると永遠に停止しなくなるお

----

ねむいので続きはそのうち書く。
NatureRemoのAPIを使って各種センサーの数値取得

#API
NatureRemoのAPI項目が増えてました。
いままで温度、湿度センサーは取得できていましたが、
照度センサーも今回取得できるようになりましたので活用したいと思います。
（公式swaggerが更新されていなかったので気づかなかったです）
<br><br>
##NatureRemoのアクセストークンを発行する
[https://home.nature.global/](https://home.nature.global/)
Generate Access Tokenでトークンを作成してください。
NatureRemo固有のトークンになりますので他人に知られないように注意。

#NatureRemoのデータを取得する
環境導入等は以下をご参照を
[NatureRemoのAPIを活用する準備](https://qiita.com/onm/items/8462b5b792132f42336d)

swaggerによると
1/devices　で、デバイスの各種値を取得できるようです
以下のコマンドで取得します
<br>

```
curl -X GET "https://api.nature.global/1/devices" -H "Authorization: Bearer [アクセストークン]" >> data.json
```
<br><br>
jqコマンドで整形する場合は以下。
<br>
<br>

```
curl -X GET "https://api.nature.global/1/devices" -H "Authorization: Bearer [アクセストークン]" | jq . >> data.json
```

<br><br>
#devices取得データ

```json
[
  {
    "name": "Remo",
    "id": "device_id",
    "created_at": "2018-02-20T12:02:31Z",
    "updated_at": "2018-06-24T14:33:28Z",
    "firmware_version": "Remo/1.0.62-gabbf5bd",
    "temperature_offset": 0,
    "humidity_offset": 0,
    "users": [
      {
        "id": "user_id",
        "nickname": "onm",
        "superuser": true
      }
    ],
    "newest_events": {
      "hu": {
        "val": 40,
        "created_at": "2018-06-24T14:01:18Z"
      },
      "il": {
        "val": 182.19,
        "created_at": "2018-06-24T14:33:51Z"
      },
      "te": {
        "val": 26.2,
        "created_at": "2018-06-24T12:30:40Z"
      }
    }
  }
]

```
<br>
hu val =<b>【湿度】</b>
il val =<b>【照度】</b>
te val =<b>【温度】</b>

です。　

#赤外線リモコンの登録情報
1/appliancesのアドレスにcurl GETで取得できます。

```
curl -X GET "https://api.nature.global/1/appliances" -H "Authorization: Bearer [アクセストークン]" | jq . >> data.json
```

#appliances取得データの一部

```json

{
    "id": "[device id]",
    "device": {
      "name": "Remo",
      "id": "[device id]",
      "created_at": "2018-02-20T12:02:31Z",
      "updated_at": "2018-03-18T10:22:27Z",
      "firmware_version": "Remo/1.0.62-gabbf5bd",
      "temperature_offset": 0,
      "humidity_offset": 0
    },
    "model": null,
    "nickname": "light",
    "image": "ico_light",
    "type": "IR",
    "settings": null,
    "aircon": null,
    "signals": [
      {
        "id": "[on/offするためのid]",
        "name": "on/off",
        "image": "ico_off"
      },
      {
        "id": "[常夜灯にするためのid]",
        "name": "small",
        "image": "ico_io"
      },
      {
        "id": "[フル点灯するためのid]",
        "name": "full",
        "image": "ico_on"
      }
    ]
  },
```

#まとめ
取得したデータを利用してintegromatでいろいろとやっていこうと思います。
RHEL 7 再起動時に eth0 が上がってこない

/etc/sysconfig/network-scripts/ifcfg-eth0 で ```ONBOOT=no``` になっていたので修正して解決:
```ONBOOT=yes
```

この項目は CentOS や Oracle Linux では変更した事がなかったけど、RedHat だけ必要なのかな。

参考
- Network interface does not come up after reboot; must be manually brought up with ifup https://access.redhat.com/solutions/38109
rails、君に決めた！！~8[wip]

一連の記事の目次
[rails、君に決めた！！~目次](https://qiita.com/satousatou/items/d20b61c198a4d439f2e7)


# View
## 基本の理解
### テンプレートエンジン(ERB,Haml,Slim)
> 変数を埋め込んだり条件分岐を記述して、動的にページを生成する雛形のこと

#### 格テンプレートエンジンの特徴
- ERB(Embedded Ruby)

- Haml

- Slim

#### 結局どれを使う？
今回はSlimを利用する

Gemfile

```ruby
gem 'slim-rails'
```

を追記し、bundle installしておく

### 部分テンプレートで共通化
Djangoで言う所のBase.htmlみたいなもの。複数の画面で共通している部分を共通化、再利用できるようにする仕組みを部分テンプレート、またはパーシャルと呼ぶ。

部分テンプレートは_comment.html.slimのように、アンダースコアで始まるファイル名にする

部分テンプレートを呼び出す場合はapp/views/articles/index.html.slim

```ruby
= render partial: 'comment', locals: { comment: @comment}
```

`partialオプション`
部分テンプレートを指定する。ファイル名にはアンダースコアがつかないことに注意
`localsオプション`
部分テンプレート内に変数を渡すことができる。`{部分テンプレート内で参照する変数名:渡す変数}`のハッシュ形式で指定。

#### 部分テンプレートの注意点
- パフォーマンスの劣化
少し遅くなる、くらいは覚えておいた方がいいかも
- インスタンス変数を参照しない
部分テンプレート内では@から始まるインスタンス変数を参照しないようにする。
部分テンプレートの再利用性が低下してしまう、らしい。よくわからない。。

#### 部分テンプレートの置き場

### レイアウト
#### コントローラ単位でのレイアウト設定
管理者用画面、エラー画面などは一般ユーザ用画面と異なるレイアウトにしたいよね？ってとき。
app/views/layouts/books.html.slimファイルを追加し、
app/controllers/books_controller.rb

```ruby
class BooksController < ApplicationController
  layout 'books'

  def index

  end
end
```

上記のようにコントローラ内でlayoutを宣言することでレイアウトファイルを切り替えられる。

### content_for
格viewは、layoutの`= yield`に挿入されるけど、titleとか変えたい場合どうすればいいの？を解決してくれる。

## 作ってみる
### slimをデフォルトにする
rails generateなどのコマンドで生成されるデフォルトのテンプレートエンジンをslimに設定する。
config/application.rb

```ruby
module RailsApp
  class Application < Rails::Application
    # デフォルトのテンプレートエンジンの追加設定
    config.generators.template_engin = :slim
  end
end
```

既存のERBファイルをSlimにするため、html2slimというgemを使う。

```bash
gem install html2slim
``` 

本には

```bash
gem install erb2slim
```

と書いてあるが、インストールしてもcommand not foundとなるだけだった。誤植？

app/views以下のerbファイルを変換

```bash
# -dを付けるとslimに変換した後にerbを削除する
erb2slim app/views app/views -d
```

### ビューの作成

```bash
bin/rails g controller users index show
```

以前にも同じコマンドを実行しているのでコンフリクトするが、上書きしてしまう。

app/controllers/users_controller.rb
app/views/users/index.html.slim
app/views/users/show.html.slim
などが生成される。

config/routes.rbを編集
resourcesメソッドを使う形にする（以前変更したのと同じ）

```ruby
Rails.application.routes.draw do
  # get 'users/index'
  # get 'users/show'
  resources :users, only: [:index, :show]
end
```

### ビューの命名規則

### layoutの作成

### 部分テンプレートの作成

### CSS/JavaScriptの読み込み

### flash

## ヘルパー
### ビューヘルパー
### フォームヘルパー
### オリジナルのヘルパー

## Ajax処理

## スマホ用レイアウト

## 多言語化対応

## パフォーマンスチューニング
rails、君に決めた！！~7[wip]

一連の記事の目次
[rails、君に決めた！！~目次](https://qiita.com/satousatou/items/d20b61c198a4d439f2e7)

## セキュリティ
brakemanというgemがセキュリティチェックに有用

#### Digest認証
HTTP認証方式にはBasic認証とDigest認証がある。
どちらの認証方式も通信内容が暗号化されていないため、必ずSSL/TLSと併用しないとダメ
- Basic認証
認証時のユーザー名とパスワードがほぼ平文で通信される

- Digest認証
Basic認証とほぼ同じだが、通信する時にユーザーIDとパスワードがハッシュ化されるため、Basic認証よりは安全

- Digest認証の実装

```ruby
require 'digest/md5'

class ApplicationController < ActionController::Base
  # Digest認証の認証領域(realm)
  REALM = 'SecretZone'.freeze
  # ユーザー名 => (ユーザー名:Realm:パスワード)のMD5ハッシュ値
  USERS = { 'user1' => Digest::MD5.hexdigest(['user1', REALM, 'passw0rd'].join(':'))}.freeze

  before_action :authenticate

  private

  # Digest認証
  def authenticate
    authenticate_or_request_with_http_digest(REALM) do |username|
      USERS[username]
    end 
  end 
end 
```

ここで衝撃の一言
> 一般に公開するアプリケーション認証の仕組みとしては、ユーザーエクスペリエンスとセキュリティ上の観点からHTTP認証は避けるべき。代わりに、フォームとセッションを使ったフォーム認証方式がよく利用される。

まじか。。。~~じゃあ最初からフォーム認証やってよ~~
HTTP認証の問題点をもうちょっと具体的に知りたい！ってことで調べた

```
- ログアウト機能がないこと
- ログインせずに同じページのコンテンツを閲覧するという使い方（ゲストアクセス）ができないこと
- サーバ側からログイン状態を無効にする手段が存在しないこと
- ホストをまたがったシングルサインオンが実現できないこと
```

っていうのが理由っぽい。

#### SSL/TLSを強制する
##### HTTPSの仕組み
`SSL:Secure Socket Layer
TLS:Transport Layer Security`

通信を暗号化する仕組み。
httpと組み合わせてhttpsにする。
現在ではSSLではなくTLSが主流。

- 盗聴防止（暗号化通信）
通信内容を傍受されても解読されないように暗号化してデータを送る

- 改ざん防止
通信の途中で内容を書き換えられないようにする。`メッセージダイジェスト`がなんちゃらってあるけどよくわからないな。ダイジェストも改ざんされたらハッシュ値の比較できないような気がするけどなー。要勉強。
- なりすまし防止
webサーバーにSSLサーバー証明書を配置して起き、接続時に検証することでサイトのなりすましを防ぐ

##### RailsでHTTPアクセスの遮断
config/environments/production.rbに

```ruby
Rails.application.configure do
  config.force_ssl = true
end
```

#### CSRF対策
Cross Site Request Forgery
リクエスト強要

> Railsではセキュリティトークンをフォームに埋め込んでおくことで、リクエスト時に検証を行える仕組みが採用されている

```ruby
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
end
```

ただ、RailsでAPIサーバーを構築する時はアクセスを制限しなくていいので、`protect_from_forgery with: :null_session`とする必要がある

#### Secure Headersを使う
> Twitterが公開しているgem
> セキュリティ関係のResponse Headerをまとめて設定できる

セキュリティ関係のHTTP Response Headerなんてあるの？？
色々あった！
[HTTPレスポンスヘッダによるセキュリティ対策](https://qiita.com/mint__/items/a4039d3cc659959d9231)


> httpsのページ内にhttpリンクが混在している時の検知や、XSS脆弱性の緩和が可能になる

XSS:Cross Site Scripting

##### 導入
Gemfile

```ruby
gem 'secure_headers'
```

を追記してbundle install

config/initializers/secure_headers.rbを作成し、

```ruby
SecureHeaders::Configuration.default
```

もっと細かく設定もできるので、詳しくは公式ドキュメントを参照。
vagrantにcentos7とnginxをインストールして、ブラウザで表示するまで

タイトルどおりのメモです！
varnishの練習のために、環境を構築してみました。
(学習用のため正確ではないかと思います。注意ください。varnishがそもそもあまり分かっていないので、これで練習できるのかなど、よく分かってなかったりします笑）
varnishに関しては、一切触れていません。
また別記事にできたらと思います。

---
作業フォルダを作成して以下のコマンドを実行
vagrant init centos/7

表示されたコマンドを実行
vagrant up
インストール開始

出力されたので何気なくメモ
default: SSH address: 127.0.0.1:2222
default: SSH username: vagrant
default: SSH auth method: private key

接続
vagrant ssh

参考：
https://qiita.com/grachro/items/4d34a43a9a57946f3693


rootユーザに
sudo su -

vi /etc/yum.repos.d/nginx.repo
nginx.reposを作成
コピペ元
https://www.nginx.com/resources/wiki/start/topics/tutorials/install/

nginxインストール
sudo yum install nginx

Is this ok [y/d/N]: y



nginx起動
sudo service nginx start


エラー
Redirecting to /bin/systemctl start nginx.service
Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details.


● nginx.service - nginx - high performance web server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Sun 2018-06-24 06:26:52 UTC; 3min 34s ago
     Docs: http://nginx.org/en/docs/
  Process: 2923 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=1/FAILURE)



SELinuxあたりのエラー？

以下のコマンドで確認
getenforce

SELinuxが有効になっている
Enforcing

セキュリティ的にあれだが、テストのため無効に修正。

/etc/selinux/config ファイル内のSELINUX=disabledにして
再起動：reboot
再接続：vagrant ssh
rootユーザに切り替え：sudo su - 
確認：getenforce
　->　Disabled


参考：
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/selinux_users_and_administrators_guide/sect-security-enhanced_linux-working_with_selinux-changing_selinux_modes


再度nginx起動（centos6とかのコマンド?）
sudo service nginx start
エラー？
Redirecting to /bin/systemctl start nginx.service

centos7はsystemctlコマンドを使用する
systemctl start nginx
（停止時：systemctl enable nginx）

参考：
https://labs.precs.co.jp/2014/12/16/75/

nginxの起動状態の確認コマンド
sudo systemctl status nginx

nginxのプロセス確認
ps aux | grep nginx

ポート確認
ss -an | grep LISTEN | grep :80



centosにnginxをインストールして表示するまで
https://hajipro.com/local-development-environment-mac/vagrant-centos7-nginx  （すごい参考になりました）
http://vdeep.net/centos7-nginx 
https://weblabo.oscasierra.net/nginx-centos7-install/


ブラウザにアクセスできない。。。
そもそもvagrantfileなるものにアドレスの設定していなかった...
修正
vagrantfile
  config.vm.network "private_network", ip: "192.168.33.10"

vagrant up
vagrant ssh
sudo -su


nginxの起動状態の確認コマンド
sudo systemctl status nginx


nginx再起動
centos7はsystemctlコマンドを使用する
systemctl start nginx
（停止時：systemctl enable nginx）


ブラウザに192.168.33.10でアクセス
open http://192.168.33.10/index.html

表示された！！

ファイヤーフォールやSELInuxの設定周りをどうするかも、学習せねば！

　
　
次の記事: [varnishをvagrantにインストールする](https://qiita.com/memorow/items/e2ff6af0966a3480ca64)

---

メモ
===========================
vagrant init (centos/7とか) / 初期化、vagrantfileの作成
vagrant up / 起動
vagrant ssh / ログイン
vagrant halt / 終了
vagrant reload / リロード
===========================
vim
コピー：yy
ペースト：p
行削除：dd
１文字削除：x
Project EulerでF#の勉強をしました（Problem4～5編）

## はじめに
この記事は以下の記事の続きです。
[Project EulerでF#の勉強をしました（Problem1～3編）](https://qiita.com/nanoyatsu/items/0f44b5b19fb49241d7b2)

手元でしか動かしていないので、間違いがあったら指摘を頂けると喜びます。

## Problem 4
> 左右どちらから読んでも同じ値になる数を回文数という. 2桁の数の積で表される回文数のうち, 最大のものは 9009 = 91 × 99 である.
> では, 3桁の数の積で表される回文数の最大値を求めよ.

```Fsharp
let collect pred xs =
    let rec inCollect xs =
        match xs with
        | [] -> []
        | y::ys -> pred y @ inCollect ys
    inCollect xs

let ketaCount n = n |> abs |> float |> (+) 1.0 |> log10 |> Math.Ceiling |> int

let listReverse ns =
    let rec inListReverse reverse = function
        | [] -> reverse
        | n::ns -> inListReverse (n::reverse) ns
    inListReverse [] ns

let checkPalindromic n = 
    let rec numToList num ketasu nlist =
        match (ketasu - 1) with
        | k when k < 0 -> nlist
        | k -> numToList (num % (pown 10 k)) k nlist@[num / (pown 10 k)]
    let numL = (numToList n (ketaCount n) [])
    numL = listReverse numL

let Problem4 = collect (fun x -> [for i in 1..999 -> x*i]) [1..999]
                |> filter checkPalindromic
                |> List.max //906609
//filter,maxの中身は前回参照(といっても名前の通りです)
```
~~実はウソがあります。(!?)
作業時にはリスト生成を[900..999]として横着をしていたんですが、
今回投稿用に[1..999]としたところ、最終的な値が変化し、"Problem4 = 90909"となりました・・・。
（[900..999]の時の回答は906609）
少し試行錯誤したもののロジック側に変なことは無いような気がするので、
「要素数が多すぎると切り取られる部分がある・・・？」くらいに思っています。
また調べようと思います。今回は投稿を優先してしまいました。すみません。~~
**自作max関数が原因だったようです。List.maxを使用して解決しました。自作関数のほうはまた見直しておきます。**

ともかくロジック側ですが、
① 値xに対してリストxsの各要素の値を用いた処理をするcollect関数(とfor文)を用いて
　[1..999]と[1..999]を相互にかけ合わせたリスト(要素数1000000個ということ)を作り、
② filterとcheckPalindromicで回文数だけを抽出し、
　②-1 10底のlogを用いて、対象の値のケタを数える(ketaCount)
　②-2 対象の値を1ケタずつリスト化する(checkPalindromic内、numToList)
　②-3 そのリストと、そのリストの並びを反転したもの(listReverse)を比較して成否を返す
③ maxで最大値を抽出しています。

回文判定の実装方法で各人の個性が出る問題だと思いますが、自分の方法がスマートなのかは不明です・・・。

## Problem 5
> 2520 は 1 から 10 の数字の全ての整数で割り切れる数字であり, そのような数字の中では最小の値である.
> では, 1 から 20 までの整数全てで割り切れる数字の中で最小の正の数はいくらになるか.

```Fsharp
//この辺りからfunctionキーワードに抵抗が無くなってきて、多用しているようです（余談）
let rec euclideanAlgorithm a = function
    | 0 -> a
    | b -> euclideanAlgorithm b (a % b)
     
let lcm a b =
    (a / (euclideanAlgorithm a b)) * b

let allNumLcm xs =
    let rec inAllNumLcm n = function
        | [] -> n
        | y::ys -> inAllNumLcm (lcm n y) ys
    inAllNumLcm 1 xs

let Problem5 = allNumLcm [1..20] //232792560
```
数学らしさがあって嬉しい問題でした。コードも短めです。（Problem4比）
ユークリッドの互除法(euclideanAlgorithm)を使用しました。最大公約数がわかるやつです。関数名は"gcd"でもよかったですね。
それを用いて最小公倍数lcmを求める関数を用意して、
あとは1から順に先頭の値との最小公倍数を求め続けます。
1と1なら1、1と2なら2、2と3なら6、6と4なら12で、無駄は出ません。

## おわり
今回は2問になりましたがここまでにしておきます。
Problem10まで続きます。（投稿したらリンクを貼りに来ます。→来ました）
[（Problem6～7編）](https://qiita.com/nanoyatsu/items/7823d28eccab995fbadb)
[（Problem8～10編）](https://qiita.com/nanoyatsu/items/89dc542c9c2fb84c8fe7)


ご指導してくださる方がいらっしゃれば、よろしくお願い致します。
Android開発で役に立ったライブラリ集

#はじめに

Android開発をやってきて開発で役に立ったライブラリをまとめました。
グループごとにまとめていて同じグループであれば上にある方がおすすめかなと思います。

##JSON変換系

+ [GSON](https://github.com/google/gson)
+ [Jackson](https://github.com/FasterXML/jackson)

##通信量削減系

+ [MessagePack](https://msgpack.org)

##コード簡略化系

+ [Lombok](https://github.com/rzwitserloot/lombok)
+ [Parceler](https://github.com/johncarl81/parceler)
+ [Retrolambda](https://github.com/orfjackal/retrolambda)

##通信系

+ [Retrofit2](http://square.github.io/retrofit/)
+ [OkHttp3](http://square.github.io/okhttp/)
+ [Volley](https://github.com/google/volley)

##メモリリーク検出系

+ [LeakCanary](https://github.com/square/leakcanary)

##バーコード系

+ [ZXing](https://github.com/zxing/zxing)

##DB系

+ [Android-Orma](https://github.com/maskarade/Android-Orma)
+ [Realm](https://realm.io)
+ [SQLCipher](https://www.zetetic.net/sqlcipher/)

##画像系

+ [Glide](https://github.com/bumptech/glide)
+ [Picasso](http://square.github.io/picasso/)

##アニメーション系

+ [Lottie](https://github.com/airbnb/lottie-android)

##非同期処理系

+ [RxJava](https://github.com/ReactiveX/RxJava/)

##UI系

+ [ArcNavigationView](https://github.com/rom4ek/ArcNavigationView)
+ [CoordinatorTabLayout](https://github.com/hugeterry/CoordinatorTabLayout)
+ [Calligraphy](https://github.com/chrisjenx/Calligraphy)
+ [ListViewAnimations](https://github.com/nhaarman/ListViewAnimations)
+ [AndroidStaggeredGrid](https://github.com/etsy/AndroidStaggeredGrid)

##CI(おまけ)

+ [CircleCI](https://circleci.com/docs/2.0/language-android/)
+ [TravisCI](https://docs.travis-ci.com/user/languages/android/)
Pythonで音楽解析する"music21"

音楽×機械学習で何かしたいと思った時に、最初にネックなのがデータの前処理だと思います。
便利なものがないか探していたら良いものがあったので、自分の勉強がてら紹介したいと思います。

# [music21](http://web.mit.edu/music21/)とは？
MIT（マサチューセッツ工科大学）で開発されている音楽解析のためのPythonで動くオープンソースソフトウェアです。
[MusicXML](https://ja.wikipedia.org/wiki/MusicXML)や[ABC](https://ja.wikipedia.org/wiki/ABC記譜法)、ly言語(後述のLilypond用言語)のような記譜用のマークアップ言語で書かれたファイルを入力とし、音楽構造の抽出、変換、編集などといったことを記号操作によって行うことができます。[MuseScore](https://musescore.org/ja)や[Finale](https://www.finalemusic.jp)（Finale Reader）、[Lilypond](http://lilypond.org/index.ja.html)などの外部プログラムと連携して、抽出した情報の可視化（楽譜など）もできます。
また、MIDIファイルから上記のマークアップ言語に変換等も可能。
公式ドキュメントは[こちら](http://web.mit.edu/music21/doc/about/what.html)

# 何ができるの？使用例
楽曲の構成、パターンなどの解析はもちろん、機械学習の前処理などにも使えます。
以下は他記事へのリンクになります。

## 機械学習の前処理

### [Magenta](https://github.com/tensorflow/magenta)
googleのプロジェクトMagenta（ニューラルネットワークを使って、美術や音楽を生成するプロジェクト）内でもデータの前処理等にmusic21が使われています。


### [DeepJazz](https://deepjazz.io)
DeepLearningを使ってJazzの曲生成を行うソフトウェア。
MIDIデータを使用しているが、その前処理等にmusic21を使っています。

## 楽曲の解析
### [ショパンのエチュードを解析](http://d.hatena.ne.jp/naraba/20121201/p1)
記事の中でLilypond（ly言語）は入出力として使えない、とありますがバージョンアップにより現在は使えるようになっています。

### [宮城道雄の「春の海」を解析](http://www-b.uec.tmu.ac.jp/shakuhachi/music21/)

## 楽譜の生成
### [楽譜生成の基本操作](https://ameblo.jp/delphinus1024/entry-12365734855.html)

# インストール・動作確認
後ほど詳細を更新予定です。
- [Python(3.x系)をインストール](https://www.python.jp/install/install.html)
- 楽譜ソフトMuseScore、Lilypond、Finaleのどれかをインストール(楽譜利用の場合)
~~- [Python用のMIDI入出力ライブラリ](https://qiita.com/marshi/items/18bf9199b1b164ec1856)をインストール(MIDI利用の場合)~~→music21で入出力可能
- music21をインストール
- 楽譜ソフトにパスを通す（楽譜ソフト利用の場合）

[こちら](https://ameblo.jp/delphinus1024/entry-12365205195.html)でもまとまっています



# MIDIデータの前処理（例）
後ほど更新予定です。
Spring Bootのfat jarから外部のjarを読み込む

Spring Bootのfat jarは依存ライブラリのjarを内包しているが、実行時に外部のjarを読み込むにはどうすればよいか記す。

あまり有ることではないが、ライブラリが環境毎に異なるjarを提供している場合などに使用する。

## 環境

- Java 8
- Spring Boot 2
- Gradle 4.7

## 設定方法

Executable Jarを起動するのにデフォルトでは`JarLauncher`が使用され、jar内の`BOOT-INF/lib/`配下を見に行く。
実行時にクラスパス等を変更するには代わりに`PropertiesLauncher`を使う。

### `build.gradle`の設定

```gradle
bootJar {
    manifest {
        attributes 'Main-Class': 'org.springframework.boot.loader.PropertiesLauncher'
    }
}
```

### `loader.path`の指定

追加したいクラスパスを`loader.path`プロパティで指定する。環境変数`LOADER_PATH`でもよい。
ありがたいことに、ディレクトリ指定もできて、jar or zipファイルを再帰的にスキャンしてくれる。

```sh
export LOADER_PATH=/develop
java -jar app.jar
```

## 参考

- [Appendix E. The Executable Jar Format](https://docs.spring.io/spring-boot/docs/current/reference/html/executable-jar.html)
- [Spring Boot Gradle Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#packaging-executable-configuring-properties-launcher)
【第三弾】Kubernetesベストプラクティス：Health Check

# ベストプラクティス第三弾です

こんにちは、jackです。

さて、第三弾ですね。今回はKubernetesのhealth checkのお話です。
コードはあまりなく、前回より少し冗長的になってしまいそうな雰囲気ですが、やってきましょう。

毎度のことですが、公式ブログはこちら。
[Kubernetes best practices: Setting up health checks with readiness and liveness probes](https://cloudplatform.googleblog.com/2018/05/Kubernetes-best-practices-Setting-up-health-checks-with-readiness-and-liveness-probes.html)

# TL;DR
* 分散システムに**health checkは欠かせないもの**である、Kubernetesもまた例外ではない
* Kubernetesの**health checkの種類は2つ**
    * Readiness
    * Liveness
* **Health checkプローブの種類は3つ**
    * HTTP Probes
    * Command Probes
    * TCP Probes
* Livenessの**initialDelaySeconds**に要注意


# もう少し詳しく

## health checkは欠かせない

分散システムは複数のコンピュータ（VM）がそれぞれの役割を担っているため管理が大変です。なにか一つが壊れてもすべてがクラッシュするのではなく、異常を感知し、トラフィックを転送するなどして、**自動的に復旧**してくれるようなシステムを構築をする必要があります。

そのそうな対応するためにも、health checkをすることはシステムが正常に動作しているかを確認するのに、**もっともシンプルな手段**と言えます。

Kubernetesの場合、Podが正常に立ち上がってからトラフィックを送り始め、クラッシュしたら再起動するような処理がデフォルトで設定されています。
これはこれで嬉しいことなのですが、**完璧とは言い切れません**。ということで、今回はより強固なシステムを構築するべく、Kubernetesのhealth checkの設定に必要な知識を紹介していきます。

## health checkの種類

Kubernetesのhealth checkには**2種類**あり、これらの違いを知っておく必要があります。

### 1. Readiness

Readinessプローブはアプリケーションが正常に起動し、トラフィックを受ける準備ができたことをKubernetesに知らせるものです。
成功したらKubernetesはそのPodにトラフィックを送り始め、仮に失敗した場合は成功するまでそのPodにトラフィックを送らないようにすることができます。

#### どういう時に使うのか

通常、KubernetesはPodのコンテナが正常に起動したことを確認したら、すぐさまトラフィックを送り始めてしまいます。**しかし、多少起動時間がかかるアプリケーションだった場合どうでしょう？**
Kubernetesの通常時の挙動ではアプリケーションが準備できる前にトラフィックを受けてしまいます。そこで、Readiness probeの出番です。Readiness probeを使うことで、KubernetesにそのPodにトラフィックを送らず待機してくれるよう知らせることができます。

### 2. Liveness
一方、Livenessプローブはアプリケーションの正常・異常をKubernetesに知らせるものです。失敗した場合Podを消去し新しいPodを立ち上げ、置き換えます。

#### どういう時に使うのか
例えば、アプリケーションにDeadlockが存在したとします。この場合、アプリケーションはいつまでも次の処理ができず、固まってしまいます。しかし、**Kubernetesはアプリケーション側の動作を知らず、Podは正常に動いていると判断します**。よって、アプリケーションが固まっているにもかかわらず、次から次へのそのPodにリクエストを送り続けてしまいますよね。
こういった場合にLiveness probeを使いましょう。KubernetesにアプリケーションがDead（死んだ）と伝え、再起動するようといったことができます。

## プローブの種類

さて、Health checkの種類を見てきましたが、実際にどんな種類のプローブがあるか見ていきます。**種類は3つ**です。

### HTTP
まず1つ目は、HTTPです。もっともよく使われる種類のプローブです。
アプリケーションがHTTPサーバーでなくても、立ち上げるのが簡単なので一番使い勝手が良いプローブでしょう。

* HTTPレスポンスで判断
    * 2XX、3XXのレスポンス `healthy`
    * それ以外が `unhealthy`


### Command
Command probeはKubernetesがコマンドをコンテナ内で実行します。

* exit codeで判断
    * 0 の時は `healthy`
    * それ以外は `unhealthy`

### TCP
最後に、TCP probeです。
特定のポートにTCPコネクションを張ることで判断します。

* TCPコネクションで判断
    * 繋がれば `healthy`
    * 繋げられなければ `unhealthy`

# まとめ

Health checkの種類とProbeの種類、それぞれ見てきましたがいろいろありましたね。これらの知識を活用してより強固な土台と、安定したシステムを作ることができるのではないでしょうか。

また、Probeのより詳しい設定は[公式ドキュメント](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes)にわかりやすく書いてあるので、こちらもどうぞ。

それでは、また次回。
UnityでVroom開発

最近、わくわくするものを見つけた！！
[ヴルームSDK専用コントローラ（JC-VRR02VBK）](https://www.amazon.co.jp/%E3%82%A8%E3%83%AC%E3%82%B3%E3%83%A0-%E3%83%AA%E3%83%A2%E3%82%B3%E3%83%B3-Bluetooth-%E3%83%B4%E3%83%AB%E3%83%BC%E3%83%A0SDK%E5%AF%BE%E5%BF%9C-JC-VRR02VBK/dp/B076X4M7BH)を使えばいろいろ開発アプリの幅が広がりそう！！
まだまだVroom対応のアプリが少ないので、知ってもらうためにも記事書きました！！
これから、開発チュートリアル的なものも上げていきたいです！
今回はインポートまでです

#開発環境
Unity 2018.1
MacBook Pro MacOS : Hight Sierra 10.12.5


#もくじ
1. Vroomとは
2. ヴルームSDKをダウンロード
3. Unityへインポート

#1.Vroomとは
「VROOM(ヴルーム)」は、モーションコントローラーのハードウェア仕様で、iOSおよびAndroidに対応したAR/VRアプリ開発社向けSDKを提供しており、このSDKを使ったアプリ開発者は、6軸センサーやボタン・ジョイスティックを搭載したモーションコントローラーとスマートフォンを使った新しいプレイスタイルのアプリを作ることが可能

#2.ヴルームSDKをダウンロード
↓ここからダウンロード↓
https://vroom.wonderleague.co.jp/sdk/index.html

![ダウンロードページその１.png](https://qiita-image-store.s3.amazonaws.com/0/159245/0a17c9cd-6330-c2cb-9e80-943840534406.png)

①今回は、個人開発を想定しているため、こちらをクリック
②必要事項を記入（個人を選択した場合、メールアドレスと名前だけ）
③ヴルームSDK使用許諾契約書を確認の上、チェックする
④全ての記入を確認し、こちらをクリック
![申し込みページ.png](https://qiita-image-store.s3.amazonaws.com/0/159245/34346faf-8257-5d3a-cd81-4879ff68ba58.png)

![SDKのダウンロード.png](https://qiita-image-store.s3.amazonaws.com/0/159245/33fa47b1-b1bd-7adf-f122-a72b866ee6bf.png)

#3. Unityへインポート
Assets　>　Import Package > Custom Package をクリック
![カスタムパッケージ](https://qiita-image-store.s3.amazonaws.com/0/159245/08e02396-6df7-e1d3-6021-f9922e07227a.png)

VvrController2_33を開く
![VvrController2_33を開く](https://qiita-image-store.s3.amazonaws.com/0/159245/25d26d25-f76c-e409-df2c-888da052f07e.png)

インポート
![インポート](https://qiita-image-store.s3.amazonaws.com/0/159245/c8aa026a-a084-a844-49f0-3ecbcf125a09.png)

サンプルシーンをAndroidかios にビルドすると動きます！！（Unityエディターのままだと動作しません）
詳細は次回に！！

#参考
[1] [Wonderleague corp.](http://www.wonderleague.co.jp/)
[2] [ヴルーム SDK 開発者ポータル](https://vroom.wonderleague.co.jp/sdk/index.html)
[3] [エレコムがAR/VR本格参入、iOS/Android両対応VROOMモーションコントローラーで新たな楽しみ方を創造](https://techwave.jp/archives/elecom-enters-ar-vr-motion-controller.html)
JavaScript学習記録３　2018年6月24日分

日刊とは一度も書いていない！心は全然折れてないよ。楽しい楽しい！

使用図書
『ここからはじめるJavaScript入門』（井上久夫　2002年1月25日発行）

やったこと
６章：文字の入力やボタン、メニューなどを活用しよう

・テキストエリアの文字を入れ替える。
　　　イベントハンドラを利用してマウスポインタが重なった時に表示文字を入れ替える。
前回まででやったようなことだけど、フォームの構造の確認のようだ。重なっている間だけ入れ替える、という記述も可能みたいだ。後者の方をよく使う気がするのでまとめて覚えておこう。

```js

MouseOver
onMouseOut
```

・ボタンをクリックすると他のページに飛べるようにする。
　　webページっぽい機能の登場だ。これは嬉しい。

```js
INPUT type="button" 
onClick=location.href="どこかのURL"
```

locationはオブジェクトだけど、アドレスとかファイル名を示すものらしい。英語まんまね！

・指定フレーム内のページを移動させる。
　ページの構造にはフレームなるものがあることはわかっているけど、じゃあフレームを細かく指定して別のページに飛ばすには？ってこと……であっているかな？　
　FRAMESETとmainとmovedのhtmlファイルを作ってフレームを指定、onClickのイベントハンドラで起動！parentの中のmainフレームに命令をぶちこんでさしあげますわ。
無事打ち込み終わって動作確認するも、動かねえ動かねえ！ってなった。よーーーく見ると、framesetのファイルをクリックして作動させるとのこと。なるほど、トップページっぽいものを起動しないとほかも上手く動かないもんね。意味をわかっていなかったみたいだ。

使っている本も残り２章。おわりが見えてきたから次の本とかを探さなきゃね！
Rubyで言語処理100本ノック 第2章: UNIXコマンドの基礎 (17 ~ 19)

[言語処理100本ノック](http://www.cl.ecei.tohoku.ac.jp/nlp100/)の挑戦記録です。

今回も引き続きファイルの読み込み処理と、
読み込んだデータのソートが課題です。

# 17. １列目の文字列の異なり
> 1列目の文字列の種類（異なる文字列の集合）を求めよ．
確認にはsort,uniqコマンドを用いよ．

``` ruby:Ruby
file_name = "hightemp.txt"

lines = File.readlines(file_name)
strings = []

File.open(file_name) do |file|
  file.each_line do |line|
    strings << line.split(/\t/).first
  end
end

puts strings.uniq.sort

```
``` shell:shell
cut -f 1 hightemp.txt | sort | uniq
```

``` shell:結果
千葉県
埼玉県
大阪府
山形県
山梨県
岐阜県
愛媛県
愛知県
群馬県
静岡県
高知県
和歌山県
```

# 18. 各行を3コラム目の数値の降順にソート
>各行を3コラム目の数値の逆順で整列せよ（注意: 各行の内容は変更せずに並び替えよ）．
確認にはsortコマンドを用いよ（この問題はコマンドで実行した時の結果と合わなくてもよい）．

``` ruby:Ruby
file_name = "hightemp.txt"
lines = File.readlines(file_name)

ROW_TEMP = 2

puts lines.sort_by { |line| -line.split(/\t/)[ROW_TEMP].to_f }
```
### **sortコマンド**
sortコマンドに関して、[こちらの記事](https://qiita.com/richmikan@github/items/cc4494359b1ac2f72311)を参考にさせていただきました。感謝です！

3カラム目の逆順なので、
`-k`で並び替える列を指定してあげます。
`n`で、数値の順番でソートします。
`r`を指定すると降順になります。

``` shell:shell
sort -k 3nr,3 hightemp.txt
```

``` shell:結果
高知県	江川崎	41	2013-08-12
埼玉県	熊谷	40.9	2007-08-16
岐阜県	多治見	40.9	2007-08-16
山形県	山形	40.8	1933-07-25
山梨県	甲府	40.7	2013-08-10
静岡県	天竜	40.6	1994-08-04
和歌山県	かつらぎ	40.6	1994-08-08
山梨県	勝沼	40.5	2013-08-10
埼玉県	越谷	40.4	2007-08-16
愛知県	愛西	40.3	1994-08-05
群馬県	館林	40.3	2007-08-16
群馬県	上里見	40.3	1998-07-04
千葉県	牛久	40.2	2004-07-20
愛媛県	宇和島	40.2	1927-07-22
静岡県	佐久間	40.2	2001-07-24
山形県	酒田	40.1	1978-08-03
群馬県	前橋	40	2001-07-24
岐阜県	美濃	40	2007-08-16
山形県	鶴岡	39.9	1978-08-03
山梨県	大月	39.9	1990-07-19
大阪府	豊中	39.9	1994-08-08
埼玉県	鳩山	39.9	1997-07-05
千葉県	茂原	39.9	2013-08-11
愛知県	名古屋	39.9	1942-08-02
```

# 19. 各行の1コラム目の文字列の出現頻度を求め，出現頻度の高い順に並べる
> 各行の1列目の文字列の出現頻度を求め，その高い順に並べて表示せよ．
確認にはcut, uniq, sortコマンドを用いよ．

今回はRuby標準ライブラリのcsvを使ってみました。

``` ruby:Ruby
require "csv"

file_name = "hightemp.txt"

table = CSV.table(file_name, col_sep: "\t", headers: %w(pref city temperature day))
prefs = table[:pref].group_by(&:itself).map { |k, v| { "#{k}": v.count } }

sorted_prefs = prefs.sort_by{ |pref| pref.values }.reverse

sorted_prefs.each do |hash|
  puts "#{hash.keys.first} : #{hash.values.first}"
end
```
シェルだとこんな具合です。
1カラム目なので、`-f`で指定してあげます。

``` shell:shell
cut -f 1 hightemp.txt | sort | uniq -c | sort -r
```
``` shell:結果
3 群馬県
3 山梨県
3 山形県
3 埼玉県
2 静岡県
2 愛知県
2 岐阜県
2 千葉県
1 和歌山県
1 高知県
1 愛媛県
1 大阪府
```

# まとめ
UNIXコマンド、自在に使えたら便利！精進しなければ...!
次回、**第3章: 正規表現** です!!

これまでの挑戦
[第1章: 準備運動](https://qiita.com/mamem/items/6d5f8d18cb6b08fc8286)
[第2章: UNIXコマンドの基礎](https://qiita.com/mamem/items/0cfa95a8b96a35eaa348)
FermiユーザだってKerasをやりたい

※ここではWindows7でやったお話です

# はまりポイント
1. Deep Learningをやりたい
2. お気軽にKerasにしよう
3. 最新のモジュールで開発環境を作る
4. CUDA 9のインストールに失敗する（TensorFlowが使っている）
5. 調べる
6. GPUがFermiであることに気づく（FermiはCUDA 9が動かない）
7. 困る

とりあえず、インストール済みのNVIDIA関連のアプリ等を**全て**アンインストールする。
（再起動時に自動的にインストールされるものはそのままで）

以降、一から環境設定をしていく。
すでにインストール済みのものは飛ばしてOK。

# 順番にインストールしていく
## Visual C++ Build Tools 2015
```
https://www.microsoft.com/ja-JP/download/details.aspx?id=48159
```
にアクセスし、ダウンロードする。
![image3.png](https://qiita-image-store.s3.amazonaws.com/0/130771/bfb47c4a-e41e-cb05-3a39-a48eae2417ce.png)
その後、インストーラを実行する。

## CUDA 8
```
https://developer.nvidia.com/cuda-80-ga2-download-archive
```
にアクセスし、「Select Target Platform」で環境にあった選択をして、ダウンロード。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/130771/336342b3-71b2-2252-ddef-977cb00aa84f.png)
その後、インストーラを実行する。

## cuDNN 6
```
https://developer.nvidia.com/rdp/cudnn-download
```
にアクセスし、「Download cuDNN v6.0 (April 27, 2017), for CUDA 8.0」から「cuDNN v6.0 Library for Windows 7」（※環境ごとに変えること）を選択肢、ダウンロード。
![image1.png](https://qiita-image-store.s3.amazonaws.com/0/130771/de22c9d8-1b05-d20b-b36b-aa38f259403e.png)
その後、解凍して、
```
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0
```
にコピー。

## Anaconda（最新版）
```
https://www.anaconda.com/download/
```
にアクセスし、環境にあったインストーラをダウンロード。
インストール後、「Anaconda Navigator」を立ち上げ、「Environments」から「Create」で新しい環境を作成する。
その後「Open Terminal」でDOS窓を開く。

## TensorFlow 1.4.0
```
pip install --ignore-installed --upgrade tensorflow-gpu==1.4.0
```

## Keras 2.1.0
```
pip install keras==2.1.0
```

# おまけ
基本的にFermiでDeep Learningするにはパワー不足なので、早くもっといいGPUに買い換えるようにすること。
（これだけやって環境を構築しても、GPUメモリが足らなくてサンプルが動かないってことがよくある）
トークンを使ってgithubからcloneする

## 概要
githubからPersonal Access Tokensを使ってコードをcloneする手順をメモしておく。

## Github情報
環境変数に定義する。

```bash:ターミナル
export GIT_USER=hoge
expoft GIT_EMAIL=hoge@example.com
export GIT_TOKEN=**************************
export GIT_REPOSITORY=example/ruby2.5
```

## コード配置
下記コマンドにてcloneする。

```bash:ターミナル
git clone https://${GIT_USER}:${GIT_TOKEN}@github.com/${GIT_REPOSITORY} .
```

## Git環境設定
必要であれば、下記コマンドでgit設定を行う。

```bash:ターミナル
git config --local user.name ${GIT_USER}
git config --local user.email ${GIT_EMAIL}
```

以上
HoloViewsで可視化力あげようとしたら環境構築でハマった

# 本記事のサマリ
pythonでグラフの可視化をするのに、holoviewsというmatplotlibやBokehなどの可視化ツールを使いやすくしたラッパ的なライブラリがあるのですが、
http://holoviews.org/#installation
を参考に、インストールして、サンプルコードを実行したところ、
```
import holoviews as hv
```
したときにエラーになってしまいました。

結論としては、「param:1.6.1-py_0」が悪さしていたので、ちゃんと動くparamをバージョンをインストールしたら動くようになりましたという話です。

### 対象読者
- holoviews環境を構築していて、「ModuleNotFoundError: No module named 'param'」になってしまった方(おそらくエラーメッセージでググって、たどり着いた方)

### 動作確認バージョン
```
python --version
Python 3.6.0 :: Continuum Analytics, Inc.
conda --version
-> conda 4.3.8
jupyter --version
-> 4.3.0
```

### 経緯
よし、データ分析環境をRから、Pythonに乗り換えるぞ
-> グラフもちょっとインタラクティブなやつつかってみるか。
bokehを直接使おうと思ったけど、なんか、Holoviewsというラッパーが便利そう。
pipで環境構築 -> 動かん。。。
condaで環境構築 -> 動かん。。。
調査 -> 解決。
調べても同じように困っている人が出てこなかったので、投稿しておくか <- イマココ

##  最終的に動くようになったものはここ
https://github.com/yukimura1227/trainings/tree/master/jupyter_training
環境情報は、jupyter_training.yamlにexportしてあるので、

```
conda env create --file jupyter_training.yaml
source activate jupyter_training
jupyter notebook
```

としていただければ、動くことが確認出来ます。


## 遭遇したエラー

```
import holoviews as hv
```
holoviewsを利用するために、importすると、holoviewsが依存している、paramが無いようなErrorになりました。

```
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-1-e0fc180c467c> in <module>()
      1 import numpy as np
----> 2 import holoviews as hv
      3 hv.extension('matplotlib')

~/.pyenv/versions/anaconda3-4.3.0/envs/jupyter_training/lib/python3.6/site-packages/holoviews/__init__.py in <module>()
      8 sys.path.insert(0, os.path.join(_cwd, '..', 'param'))
      9 
---> 10 import param
     11 
     12 __version__ = param.Version(release=(1,8,3), fpath=__file__,

ModuleNotFoundError: No module named 'param'
```

## 調査と解決策

### 調査結果
pythonをほとんど使ったことが無いので、いろいろと、調べたのですが、特に得られるものは無かったので
割愛します。
Errorになっているparamのバージョンを調べると、
param=1.6.1=py_0
担っていて、py_0？？となったので、バージョンを下げました。
https://github.com/ioam/param/releases/tag/v1.6.1
を見ると、2018/06/24時点でlatest releaseになっていますが、直接 `import param` としてもうごかないようでした。




### 解決策
versionを下げて、こうなりました。
https://github.com/yukimura1227/jupyter_training/commit/d63b2a2489cd6ca4e049d2ecbccb8697613cc3e6

condaでinstallしているのですが、
以下のように、バージョンを指定して上げると、古いversionもインストールできるので、古いバージョンをインストールしました。

```
conda install -c <channel> <package_name>=<version>=<build_string>
```

具体的には、以下のように実行。
```
$ conda install -c ioam param=1.5.1=py36_0
Fetching package metadata ...........
Solving package specifications: .

Package plan for installation in environment /Users/yukimura1227/.pyenv/versions/anaconda3-4.3.0/envs/jupyter_training:

The following packages will be DOWNGRADED due to dependency conflicts:

    param: 1.6.1-py_0 ioam --> 1.5.1-py36_0 ioam

Proceed ([y]/n)? y

param-1.5.1-py 100% |####################################################################################################| Time: 0:00:02 205.15 kB/s
```

これで、動くようになりましたので、めでたしめでたし
Vue-routerで遷移時にパラメタを渡し方

vue-routerで画面遷移時にパラメータ渡すのに手詰まったのでメモ

## サンプルリポジトリ

[https://github.com/Godan/tutorial-vue-router](https://github.com/Godan/tutorial-vue-router)


<!-- more -->



## サンプルのvue-routerのルーティング
pathにはパターンを書きます。```:```を先頭に書くのはrailsのroutesと同様ですね。  

```js
import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'index-page',
      component: require('@/components/index').default
    },
    {
      path: '*',
      redirect: '/'
    },
    {
      path: 'fuga',
      name: 'fuga-view',
      component: require('@/components/fuga').default
    },
    {
      path: '/hoge/:value',
      name: 'hoge-view',
      component: require('@/components/hoge').default
    }
  ]
})

```
## リンク元ページ  

リンク元でrouter-linkタグを使ってリンクを張ります。toの中身はハッシュで渡していきます。

```js
<template>
  <div id="wrapper">
        <router-link :to="{ name: 'hoge-view', params: { value: 'test value' }}" >hoge Link</router-link >
        <router-link :to="{ name: 'fuga-view' }" >fuga Link</router-link >
    </main>
  </div>
</template>
  
```

## リンク先ページ
リンク先は通常変数と同様に展開します。

```js
<template>
  <div>
    <router-link :to="{ name: 'index-page' }"> back </router-link>
    This is hoge page.   value is {{ $route.params.value }} 
  </div>
</template>
```

## リンクが変更されたときに関数を呼び出す

変更に合わせて関数を呼び出す場合はvueに用意されているウォッチャーを使います


```js
new Vue({
  components: { App },
  router,
  store,
  template: '<App/>',
  watch: {
    $route: function (to, from) {
      // ここにコードを書く
    }
  }
}).$mount('#app')

```
クリック時サブウインドウを開くのにハマった（超初歩）

##サブウインドウを開く方法

初心者ですみません。
もうあまりサブウインドウ自体使用する機会もあまりないかもしれないけど、
よくわかっていなくて結構な時間はまってしまったのでメモ。
URLにforeachで回してるPHPの変数を入れたかった

```php
<a href="<?php $url;?>" onClick="window.open('<?php $ur;?>','subwindow','width=500,height=500,scrollbars=no')">hogehoge</a>
```
あほなのですが、これでいけると思ってしまってました。
正しくは下ですね。。。

```php
<script>
function subwindow(url){
window.open(url,'subwindow','width=500,height=500,scrollbars=no');
}
</script>
<a href="<?php $url;?>" target="subwindow" onClick="subwindow('<?php $url;?>');">hogehoge</a>
```
PythonでGoogleの画像を大量スクレープする

Googleの画像検索で必要な画像を大量ダウンロードするプログラムを作ってみました。深層学習や画像分析の準備に役立ちそうです。

ソースコード (Python 3で実証済み)：

```python

import bs4
import requests
import re
import urllib.request, urllib.error
import os
import argparse
import sys
import json

# How To
# (1) ソースコードを保存して命名する (e.g. scrape.py)
# (2) プログラムを起動する python scrape.py
# (3) オプション
# -s: Google Imagesにかける検索キーワード、複数可 (デフォルト "banana") 
# -n: ダウンロードする画像の数量 (デフォルト 10枚)
# -o: 画像の保存先 (デフォルト　<DEFAULT_SAVE_DIRECTORY>で指定する)

def get_soup(url,header):
    return bs4.BeautifulSoup(urllib.request.urlopen(urllib.request.Request(url,headers=header)),'html.parser')

def main(args):
	parser = argparse.ArgumentParser(description='Options for scraping Google images')
	parser.add_argument('-s', '--search', default='banana', type=str, help='search term')
	parser.add_argument('-n', '--num_images', default=10, type=int, help='num of images to scrape')
	parser.add_argument('-o', '--directory', default='<DEFAULT_SAVE_DIRECTORY>', type=str, help='output directory')
	args = parser.parse_args()
	
	# 複数のキーワードを"+"で繋げる
	query = args.search.split()
	query = '+'.join(query)
	max_images = args.num_images
	
	# 画像をフォルダーでグループする
	save_directory = args.directory + '/' + query
	if not os.path.exists(save_directory):
		os.makedirs(save_directory)	
	
	# スクレーピング
	url="https://www.google.co.jp/search?q="+query+"&source=lnms&tbm=isch"
	header={'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36"}
	soup = get_soup(url,header)
	ActualImages=[]
	
	for a in soup.find_all("div",{"class":"rg_meta"}):
		link , Type =json.loads(a.text)["ou"]  ,json.loads(a.text)["ity"]
		ActualImages.append((link,Type))
	for i , (img , Type) in enumerate( ActualImages[0:max_images]):
		try:
			Type = Type if len(Type) > 0 else 'jpg'
			print("Downloading image {} ({}), type is {}".format(i, img, Type))
			raw_img = urllib.request.urlopen(img).read()
			f = open(os.path.join(save_directory , "img_"+str(i)+"."+Type), 'wb')
			f.write(raw_img)
			f.close()
		except Exception as e:
			print ("could not load : "+img)
			print (e)

if __name__ == '__main__':
	from sys import argv
	try:
		main(argv)
	except KeyboardInterrupt:
		pass
	sys.exit()
```

##実証テスト

キーワードを「tanuki」で画像25枚スクレープする：
![image.png](https://qiita-image-store.s3.amazonaws.com/0/263382/b23bb001-18ff-1363-a2bb-5e28d1718229.png)


スクレーピングの結果：
![image.png](https://qiita-image-store.s3.amazonaws.com/0/263382/4887db4d-475d-1c1e-e62e-317b8e42b25f.png)
ちゃんと「tanuki」のフォルダーに画像がダウンロードされました。


因みにこちらが同じキーワードをGoogle画像検索にかけた結果です：
![image.png](https://qiita-image-store.s3.amazonaws.com/0/263382/91fd8b55-9f07-0161-5f25-ab37072f4b04.png)
Go Map!!を持ってハッピー・マッピング :)

## 前置き
[Go Map!!](https://itunes.apple.com/app/id592990211)の名はなんとなく耳にしていたんだけどようやく試してみたところ自分史上最強に使えるモバイルOSMエディターだということが分かってついカッとなったのでまとめてみました。日本でも使っている人は結構いるようですね。

iPhoneが出た頃からいろんなモバイル版のOSMエディターを試してきましたが、雑なタグ付けしかできなかったり、位置合わせが難しかったり、POIしか編集できなかったりといった点で、どうにも思い通りのマッピングができずに、じきに飽きてしまうということを繰り返して来ました。そのため近頃自分でどこかへ出かける際にはモバイルエディターは全く使わずmapillaryでひたすら写真を撮って、気が向いた時に自宅で編集するということをやっています。

しかしそんなことをやっているとマッピングされていないmapillary写真だけがひたすら溜まって行きます。やはり興が乗った時にやってしまわないとバックログ的なタスクは楽しくありません。

そこでGo Map!!に出会ったわけですよ。ひとことでいえば、すごく合理的に作られたOSMerのための現地リアルタイムマッピングツール。もちろんJOSMの機能には及ぶべくもありませんが、結構iDに近い感覚でマッピングができます。オープンソースで無い点を指摘する声もありますが（開発協力は求めている）、これだけ質の高いアプリの開発を非営利で続けている訳ですから個人的には素直に称賛してしまいます。一部しか多言語化されていない点だけは残念ですが。

## 機能
詳細は[Wiki記事](https://wiki.openstreetmap.org/wiki/JA:Go_Map!!)を参照して欲しいのですが、かゆい所に手の届く使いやすさはこのあたり：
- ノード、ウェイ、クローズドウェイのいずれも直感的に編集可能
- 現在地（トラック機能）アイコンをオンにすると現在地と進行方向に合わせてマップビューを自動スクロールしてくれる
<img src="https://qiita-image-store.s3.amazonaws.com/0/35320/74ca1957-079e-bc38-fe3b-9681472721a3.png" width=25%>
- トレース（GPSログ）もほぼ自動的に取得
- タグのプリセットが充実（JOSM/iDから持ってきているフシがある）し、カスタマイズもできるので細かいタグ付けが素早くできる（コンビニに支店名を足すとか）
- タグのコピペができる
- タグのローカル保存とサーバーへの一括アップロードが分かれているので思う存分ローカルで編集できる（PC版エディターで修正してローカル値と矛盾が生ずることがあるので適度にローカルキャッシュのクリアが必要）
- オブジェクトの複製、直線化、直角化、円環化、回転といったPC版なみの操作ができる
- エリアで描かれた建物を指定して「Measure Height」からカメラで覗くと現在地からの距離を元に高さを計測してくれる（すごいー）
<img src="https://qiita-image-store.s3.amazonaws.com/0/35320/5c91ea06-aa6a-5a0e-5299-6071d434dca1.png" width=25%>
<img src="https://qiita-image-store.s3.amazonaws.com/0/35320/5c1e9c8f-1249-6991-d9b1-0bac7bd451eb.png" width=25%>
- オフラインマッピングもサポート
- 現在地アイコンを長押しするとNominatimによる場所の検索ができる
- 背景画像を切り替えたり追加したりできる
- ビル名が分かりやすく表示されているので抜けているところを入れやすい
- 住居表示板を見ながら住所を入れられる（けど結構大変でビルを眺めながらじっとしていると不審者ぽいのがつらい）
- 設定(Turn Restrictions)によって道路関連タグがアイコンで可視化されタグ付けしやすい
- Undo, Redoが素早くできるので大胆に操作できる

## おわりに
ということで久々にマッピング欲が湧き上がってきたところです。See you.