OmniAICreator/Qiita-1.07M huggingface dataset:
Google Maps JavaScript APIの使い方

#はじめに
この記事はapiのキーを取得していることを前提として書きます。(キーの取得に関する部分は割愛いたします。)
※キーの取得には[こちら](https://developers.google.com/maps/documentation/javascript/get-api-key?hl=ja)を参考にしてください。
また、jsがまともにかけるようになって2年目の備忘録です。
実際にページにマップを表示できるようになるにはどうしたらいいか書きました。

##ページにマップを表示できるようになるまで

###1.今回説明するコード
```html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<title>サンプル</title>
</head>

<body>
	<div id="map"></div>

	<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
	
	<script>
		$(function () {
			//位置情報
			var myLatLng = {lat: 0, lng: 0};

        //mapの描画
        var map = new google.maps.Map(document.getElementById('map'), {
        	zoom: 17,
        	center: myLatLng
        });


        //マーカーの描画
        var marker = new google.maps.Marker({
        	position: myLatLng,
        	map: map,
        	draggable: true
        });

    </script>
</body>
</html>
```

###2.Google Maps JavaScript APIのロード
 ```html
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"async defer></script>
```
これをhtmlに入れる。
YOUR_API_KEYには自分で取得したキーを入れる。

###3.マップを表示させる
表示させたい部分に`<div id="map"></div>`を挿入する。
大きさ等をcssで調節してください。
※heightを指定しないと表示されないようです。

###4.マップを描画する
```js
var map = new google.maps.Map(document.getElementById('map'),{
    zoom: 1,
    center: {lat: 0, lng: 0}
});
```

また、

```js
var map = new google.maps.Map(document.getElementById('map'),{
    zoom: 1,
    center: myLatLng
});
```
このように後で緯度経度を変更できるように
`var myLatLng = {lat: LatitudeData, lng: LongitudeData};`と宣言して
動的に値を変えることも可能です。
※`myLatLng`更新のための関数は割愛させていただきます。


###5.マップを生成する様々なプロパティ
・zoom:マップの表示範囲を指定する。
(zoomの値は[こちら](https://developers.google.com/maps/documentation/javascript/tutorial?hl=ja#header)を参考にしてください。)
・center:マップの中心をどこにするか指定する。
※マップの中にあるズームコントローラーやマップのタイプを切り替えるコントローラーは無効にしたりもできるので必要に応じて調べて追加してください。


###6.マーカーの表示
```js
var marker = new google.maps.Marker({
    position: myLatLng,
    map: map,
    draggable: true
});
```
・position:緯度経度を設定し、マーカーの位置を指定する。設定は必須。
・map:マーカーを配置するマップを指定する。はじめに設定しない場合、マーカーは作成されるが表示されない。別途`marker.setMap(map);`で呼び出すことで、マーカーをマップ上に追加できる。設定は任意。
・draggable:マーカーをドラッグでの移動の有効/無効にする。設定は任意。


###7.マーカーを動かした時の処理
下記のように、マーカーを動かしたときの処理をかくこともできる。この場合は、マーカーをドラッグし終えたときの処理の書き方です。

```js
marker.addListener('dragend', function () {
    //実行したい処理をかく
});
```


#終わりに
今回は、マップを表示させるだけにフォーカスしました。
本来はもっと多くのことができるので
必要に応じて[こちら](https://developers.google.com/maps/documentation/javascript/?hl=ja)を見てみてください。
「immediate=true イコール 入力チェック回避」ではない

JSFで、
```
<h:commandButton immediate="true"
```
とかにしておくと、このボタンを押してsubmitしたときはValidationが回避される。

それは間違いではないのだが、安易に使っていたらハマってしまった。
immediate="true"にすると、アクションメソッドの実行が、バッキングビーンの更新より先に行われるようだ。

そのためアクションメソッドでビーンの値を取得しても、古い値が取れるので、現在の入力値を期待した処理を行っている部分が失敗していた。

immediate="true"は、入力チェックやバッキングビーンの更新をすっ飛ばして、とっととアクションメソッドを実行したい！という時に使うのだろうな。戻るボタンとか。
gitBucket+sourcetreeでプッシュが失敗する

## プッシュに失敗する
### エラー
gitBucketに対してSourceTreeでプッシュしたらエラーが出て失敗した。

■エラー内容

```
error: src refspec {branch/tag name} matches more than one.
error: failed to push some refs to {https://xxxxx.git}
```

### 原因
タグ名とブランチ名で同じものがあるとこのエラーになる。
タグまたはブランチを削除してから再度プッシュすれば成功する。

### 対応
開発環境ではSourceTreeを使用しているのでSourceTreeで行った手順を書いておく。

1. タグリストの中にプッシュするブランチと同じ名前のタグを右クリックする。
2. 「{branch/tag name}を削除」というメニューがある。押す。
3. 「全リモートから削除」にチェックを入れて実行する。
4. 再度プッシュする。
複数のI2Cモジュールを接続すると動作しない？

#障害内容
開発中のセンサーで下記の三軸加速度センサーの値を取得しようとするとinit()メソッドを呼び出した場所でプログラムが落ちてしまう。
https://www.switch-science.com/catalog/823/

#原因調査
##１．挿し口が壊れている？
GroveシールドのI2Cの挿し口を変更してみたが、結果は変わらなかった。

##２．単体で動作するか調査
Groveシールドに刺さっているほかのモジュールをすべて抜いて、サンプルコードを実行すると予想通りの値が取得できた。
三軸加速度センサーの故障ではないことが確認できた。

##３．I2Cのほかのモジュール（光センサ）を接続してテスト
init()メソッドで落ちた。
このことにより、三軸加速度センサーの問題ではなく、別のI2Cモジュールが問題と推測した。

ネットで調べても複数のI2Cモジュールを接続したら動かなくなるという事象は見当たらなかった。
だいたいこういう時は初歩的なことでミスをしていることが多い。
案の定、配線を確認してみると、ケーブルグランドで束ねられた先の接続先モジュールがI2Cのモジュール（光センサ）ではなくLEDモジュールにつながってしまっていた。

LEDモジュールを外し、I2Cモジュール（光センサ）を接続すると正常な動作を確認することが出来た。

#調査結果
I2CコネクタにI2C接続ではないモジュールを接続すると、他のI2Cモジュールも動かなくなることが分かりました。
複数のI2Cモジュールは当然、問題なく接続して動作させることが出来ました。

#まとめ
接続をうっかり間違えたのがいけなかったのですが、もし同じうっかりをしてしまった人がいれば参考になるかなと思い記事とさせていただきました。

次からは気を付けないとということで、各接続先にテプラでラベルを張り間違えないようにしました。
しかし今回はうっかりでArduinoが壊れなかったのが幸いですｗ
肥大化したnode_modulesを一発でダイエット「node-prune」

node.js使っててnpm使ったこと無い人は流石にいないと思う。npm installして出来るのがnode_modulesディレクトリである。今だとyarnか

大抵はgitの管理から外すので意識しないが、放っておくと**いつの間にか容量を食ってて**ディスク容量の貧しい俺のMacbookが死ぬ。だからとてnode_modulesを削除して再度npm installしたくない。。という人におすすめなのが[node-prune](https://github.com/tj/node-prune)

# インストール

一発

```
go get github.com/tj/node-prune/cmd/node-prune
```

goなんて入ってねーよって人は[ここ](https://github.com/tj/node-prune/releases)からバイナリファイルをダウンロードできる。Macの人なら「node-prune_*_darwin_amd64.tar.gz」

解凍して適当に/usr/local/bin/にコピればおｋ

```
$mv node-prune /usr/local/bin/
```

# 実行

node_modulesがあるディレクトリ上でコマンド実行するだけ

```
$node-prune 

         files total 2,637
       files removed 791
        size removed 2.8 MB
            duration 240ms
```

ホントはもっとダイエットできた奴もあったんだけど残すの忘れた。

容量気にしてる方にはおすすめのコマンド。
AWS EC2（Ubuntu16.04）の初期セットアップ

AWS EC2のUbuntu16.04インスタンス作成後、最初に設定することをまとめました。（あくまで私個人がやっていること）

#### rootアカウント解除

```shell-session
$ sudo passwd root
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
```

#### ubuntuパスワード設定

```shell-session
# passwd ubuntu
```

#### timezoneをAsia/Tokyoに変更

```shell-session
# timedatectl set-timezone Asia/Tokyo
```

#### zip/unzipのinstall
lambdaのコードを生成する際や、sdkを解凍する際に利用するため。

```shell-session
# apt-get install zip unzip
...(log)...
```

#### Pythonのシンボリックリンク

```shell-session
# python
The program 'python' can be found in the following packages:
 * python-minimal
 * python3
Try: sudo apt install <selected package>
# ln -s /usr/bin/python3 /usr/bin/python
# python
Python 3.5.2 (default, Sep 14 2017, 22:51:06)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
```

#### pip、python3.6のインストール
https://qiita.com/TKYK38/items/2a73696a9d8f1f856f68


#### aws cliのインストールとconfigure
https://qiita.com/TKYK38/items/62879bc7e4257ba5a642
Django 開発時の Visual Studio Code の設定 (Windows版)


#参考（基本的な設定方法）

- Visual Studio CodeでPython + Djangoを書いて、py.testを実行してみた
 - http://thinkami.hatenablog.com/entry/2016/07/05/224416
- Mac + Windows + VisualStudio CodeでPythonの開発環境を整える（Windows版）
 - https://qiita.com/gelehrte/items/7a02b3df666217895c68
- Visual Studio CodeでDjangoのインテリセンスを有効にする。
 - https://qiita.com/Nekonecode/items/66863a0af5f1aad23ce8


基本的な流れについてはすでに他の方が十分書いているので、自分の設定だけメモ

#ワークスペース設定
```json:setting.json
{
    // 統合ターミナル
    "terminal.integrated.shell.windows": "C:\\windows\\system32\\cmd.exe",
    // デバッグパス
    "python.pythonPath": "${workspaceRoot}\\env\\Scripts\\python.exe",
    // コード整形
    "python.formatting.provider": "autopep8",
    "python.formatting.formatOnSave": true,
    // lintツール
    "python.linting.pylintEnabled": true,
    "python.linting.pylintArgs": [
        "--errors-only",
        "--load-plugins",
        "pylint_django"
    ]
}
```

#### 統合ターミナル

PowerShellはWindows単体の管理には便利ですが、VSCode上だとうまく使いこなすのがむつかしいです。manage.pyの実行時に別ウィンドウが立ち上がっちゃったりします。
ここでコマンドプロンプトのシェルに変更しています。

#### lintツール

pylint_djangoというpylintのプラグインを見つけたので使っています。
通常のpylintだと標準生成されたurls.pyにさえ警告が出て面食らいましたが、こちらを使えば大丈夫です。

- landscapeio/pylint-django
 - https://github.com/landscapeio/pylint-django


Djangoは色々勉強中です。警告が多すぎると気が散ってしまうので「errors-only」を指定してます。業務で使うときは解除してください。

#起動バッチ

毎回ターミナルを立ち上げて「code .」をたたくのは面倒なので、プロジェクトフォルダ内にバッチファイルを作成しました。ショートカットをデスクトップに置くと起動が楽です。

```bat:vscode.bat
cd /d %~dp0
call ".\env\Scripts\activate.bat"
call code .
exit
```

#デバッグ設定

デバッグ実行時に１行目で止まるのはlaunch.jsonの「stopOnEntry」の設定のため。
falseにすると止まらず進みます

#デバック環境の選択リストに注意
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/217094/6a0b9255-1118-8a80-54b8-3a87ee311f6b.png)

左ペインを狭くして使っていると、デバッグ環境が選択可能であることに気付かないという悲劇が起きます。
狭いディスプレーで使うときは注意です。
Android4.1のブラウザでテキストが折り返されるのを防ぐ

#なんか勝手にテキストが折り返されるんだけど！
Android4.1のタブレットでWebの画面を表示させたときにテキストが折り返されちゃう！なんかバグらしい。

##対処法
- nowrap付ける
  
```css:example.css  
.p {
  white-space: nowrap;
}
```
こんな感じに指定してあげると、対象の要素が折り返し禁止になるらしいです。

---

初心者なので、もっと良い記述法があれば教えてください！
【決定版】Railsで個別の属性を検証するカスタムバリデーションを作る

この記事では、 `ActiveModel::EachValidator` を使った、個別の項目を検証するバリデータの作り方を基礎から応用まで解説します:shield:

## :beginner:基礎

まず[Railsガイド](https://railsguides.jp/active_record_validations.html#%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%83%90%E3%83%AA%E3%83%87%E3%83%BC%E3%82%BF)を読んでみましょう。

> 個別の属性を検証するためのカスタムバリデータを追加するには、ActiveModel::EachValidatorを使用するのが最も簡単で便利です。この場合、このカスタムバリデータクラスはvalidate_eachメソッドを実装する必要があります。このメソッドは、そのインスタンスに対応する「レコードと属性と値」、バリデーションを行なう属性、そして渡されたインスタンスの属性の値の3つの引数を取ります。
> 
> ```rb
> class EmailValidator < ActiveModel::EachValidator
>   def validate_each(record, attribute, value)
>     unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
>       record.errors[attribute] << (options[:message] || "はメールアドレスではありません")
>     end
>   end
> end
> 
> class Person < ActiveRecord::Base
>   validates :email, presence: true, email: true
> end
> ```
> 
> 上の例に示したように、標準のバリデーションとカスタムバリデーションを組み合わせることもできます。

とあります。

補足です:bulb:。たしかにこれで動くのは動くとは思いますが、バリデータは `app/validators/email_validator.rb` とかに入れ、モデルには

```rb:app/models/model_name.rb
validates :field_name, email: true
```

など、2つを分けて書くのが普通だと思います。補足終わりです:smile:

なるほどなるほど、 `email: true` のようなバリデータはこの知識だけで作れますが、 `true` だけではすまないバリデータ、すなわち、 `inclusion: ['01', '02']` や、オプションも指定した `numericality: { only_integer: true }` のようなバリデータは実装できません。

では、応用編です。

## :muscle: 応用

### オプションありパターン

では理解しやすい、オプションありパターンからいきましょう。 `numericality: { only_integer: true }` のように `Hash` つきで呼び出すと、 `{ only_integer: true }` は（引数にありませんが） `options` で取れます。つまり、 `only_integer` の値が取りたければ、 `options[:only_integer]` を呼ぶことになります。

Railsガイドの例でも `options[:message]` と書いてある部分があり、

```rb
validates :field_name, email: { message: 'を正しく入力してください' }
```

のように書く機能も備えていたことになります。

### オプションなしパターン

では、 `Hash` なし、すなわち、 `inclusion: ['01', '02']` のような呼び出しパターンでは、与えられた `['01', '02']` の部分はどう受け取ればよいのでしょうか。これ、さらっと探したけどあまり説明がなく、[Railsのソースを見て](https://github.com/rails/rails/blob/master/activemodel/lib/active_model/validations/validates.rb)たどり着きました。結論は、

`['01', '02']` の部分が、：

- `Range` or `Array` の場合、 `options[:in]` で、
- 上記以外の場合、 `options[:with]` で

取ります:astonished:

えーー！　ハッシュの値に指定した型によって、取り方が変わるの？？　あっ、でも確かに、オプションの有無によって、

```rb
validates :field_name, format: /\A[a-zA-Z]+\z/
validates :field_name, format: { with: /\A[a-zA-Z]+\z/, message: "英文字のみが使用できます" }

validates :field_name, inclusion: %w(small medium large)
validates :field_name, inclusion: { in: %w(small medium large), message: "%{value} のサイズは無効です" }
```

のように、 `in` と `with` が（自然と）使い分けられているのを見たことがある方は多いのではないでしょうか。それはこういうことだったのか……。

## まとめ

Railsのバリデータを自作するときは `in` と `with` の使い分けを知らないとプチハマりする。
Objective-C パスの連結について

何でもかんでもstringByAppendingPathComponentで連結したら痛い目を見たので、
備忘録として書き残しておく。

## ファイルパスの場合
パスを連結したい場合は、**NSString** の **stringByAppendingPathComponent** を用いる。
便利な点は、末尾に '/' が付いていない場合は、勝手に付加してくれる。

```objc:Objective-C
NSString *path = @"/hoge";
NSLog(@"%@", [path stringByAppendingPathComponent:@"content/"]);
```
```text:Output
/hoge/content/
```

**※しかし、ファイルパスの場合は問題は無いが、URL文字列を連結すると正しいパス文字列が作られない。**

```objc:Objective-C
NSString *path = @"http://hoge";
NSLog(@"%@", [path stringByAppendingPathComponent:@"content/"]);
```
```text:Output
http:/hoge/content/
```
上記の通り、
スキーム文字列が **http:/** となり、正しく扱えなくなる。

## URLの場合

URLに関するパス文字列を作る場合は、**NSURL** の **URLByAppendingPathComponent** を用いる。

```objc:Objective-C
NSString *path = @"http://hoge";
NSLog(@"%@", [[[NSURL URLWithString:path] URLByAppendingPathComponent:@"content/"] absoluteString]);
```
```text:Output
http://hoge/content/
```
確率②　連続確率変数と離散確率変数

これまでの学習は[確率①](https://qiita.com/yossyyossy/items/cced479f4f8b18d076f3)に書いてます！

pythonで実装をする予定でしたが、まだまだ覚えるところがあることがわかったので、少しづつ埋めていくことにしました。

#その前に！

連続型確率変数と離散型確率変数の違いについて知ろうと思います。

###**確率変数**

>確率論ならびに統計学において、ランダムな実験により得られ得る全ての結果を指す変数である[1]:391。 数学で言う変数は関数により一義的に決まるのに対し、確率変数は確率に従って定義域内の様々な値を取ることができる。

参照：【[確率変数 - wikipedia](https://ja.wikipedia.org/wiki/%E7%A2%BA%E7%8E%87%E5%A4%89%E6%95%B0)】

ある事象が起こる確率を表す変数ってことですね。

###**離散型確率変数**

**ポイント**
・サイコロの目のよう1が出た後に4や3、また6がでるかもしれません。0.999や1.001のような数字とは対照的に、整数になり、**間にある値を取れない変数**のようです。

###**連続型確率変数**

**ポイント**
・今持っている荷物の重さのように、1.001kgや0.8999kgといった重さが変数になるのが、確率変数です。離散型とは対照的で、**量り売りのお菓子と同じ感覚**だと思います！


連続や離散と聞くと、1,2,3のように連続の数字がでる条件下での確率のように感じるかもしれません。しかし、1,2,3と出ることがわかっているのであれば、1の次に2が出る確率は100％なので、確率の話ではなくなってしまいます。

##連続確率分布、離散確率分布を知る前に

1-6の目を持つサイコロのnの目がでる確率は$\frac{1}{6}$と表示できます。しかし、それは意味がないようです。

なぜなら、nの目にぴったり一致する確率は0パーセントだからです。

参照:【[離散型確率変数と連続型確率変数の違いについて](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12119105417)】


でも、「**n番目からn+x番目までが出る確率はなんとかパーセント**」といえることは、ある程度の推測になります。

だから、**まずは双方の確率変数を分布にして、わかりやすくしようぜ！**というのが双方の確率分布になります！

#連続確率分布、離散確率分布

確率密度関数を理解してからじゃないとかけなそうなので、勉強後再度投稿します！m(__)m

#最後に

覚えること多いですが、少しづつ理解してきているかなと思っています！

間違っているところ等ありましたらおしえていただけますと幸いです><

読んでくださってありがとうございました!!
display:flex系をまとめる②（古いブラウザ対応用）

[display:flex系をまとめる①（古いブラウザ対応用）](https://qiita.com/kaip04/items/22b21d5af0fb43fba4ee)の続きです。

## flex-direction
子要素の配置方向
デフォルトは左から右に配置されます。
### row
デフォ。左から右に
![スクリーンショット 2017-11-28 15.13.41.png](https://qiita-image-store.s3.amazonaws.com/0/94307/7a7e4d67-901e-6472-590b-ba5001e9ca12.png)

```css:css
    -webkit-box-orient: horizontal;
    -webkit-box-direction: normal;
    -webkit-flex-direction: row;
    -ms-flex-direction: row;
    flex-direction: row;
```
### row-reverse
右から左へ
![スクリーンショット 2017-11-28 15.19.40.png](https://qiita-image-store.s3.amazonaws.com/0/94307/4182a4d9-984e-e20b-f7e7-4a7f6193c67a.png)

```css:css
    -webkit-box-orient: horizontal;
    -webkit-box-direction: reverse;
    -webkit-flex-direction: row-reverse;
    -ms-flex-direction: row-reverse;
    flex-direction: row-reverse;
```

### column
上から下。
![スクリーンショット 2017-11-28 15.15.10.png](https://qiita-image-store.s3.amazonaws.com/0/94307/81f805b3-2be2-af30-bda2-b24cc29cd1b4.png)

```css:css
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
    -webkit-flex-direction: column;
    -ms-flex-direction: column;
    flex-direction: column;
```

### column-reverse
下から上。
![スクリーンショット 2017-11-28 15.21.10.png](https://qiita-image-store.s3.amazonaws.com/0/94307/62af4f38-0a03-6b81-97c8-8af10fee2f2e.png)

```css:css
    -webkit-box-orient: vertical;
    -webkit-box-direction: reverse;
    -webkit-flex-direction: column-reverse;
    -ms-flex-direction: column-reverse;
    flex-direction: column-reverse;
```

## flex-wrap
子要素の折り返し設定

* 改行なし：.wrapに収まらなくても子要素が縮小されてむりやり収まる。
* 改行あり：.wrapに収まらなかったら折り返されて複数行になる。floatのイメージ

### nowrap
改行なし/デフォルト
![スクリーンショット 2017-11-28 15.57.16.png](https://qiita-image-store.s3.amazonaws.com/0/94307/16d33bbb-03e5-74e4-ca0b-221b1418c1ce.png)

```css:css
    -webkit-flex-wrap: nowrap;
    -ms-flex-wrap: nowrap;
    flex-wrap: nowrap;
```
### wrap
改行あり
![スクリーンショット 2017-11-28 16.01.18.png](https://qiita-image-store.s3.amazonaws.com/0/94307/879e55d1-fbbe-cecc-8649-86fe134e245f.png)

```css:css
    -webkit-flex-wrap: wrap;
    -ms-flex-wrap: wrap;
    flex-wrap: wrap;
```
### wrap-reverse
改行ありだが折り返し地点が違う
![スクリーンショット 2017-11-28 16.03.17.png](https://qiita-image-store.s3.amazonaws.com/0/94307/aca31600-fba1-ab30-054c-872a577a9ce2.png)

```css:css
    -webkit-flex-wrap: wrap-reverse;
    -ms-flex-wrap: wrap-reverse;
    flex-wrap: wrap-reverse;
```
## flex-flow
上記２点（flex-direction、flex-wrap）はまとめて書ける
```css:css
    -webkit-flex-flow: column wrap;
    -ms-flex-flow: column wrap;
    flex-flow: column wrap;
```
## flex
伸縮性設定のショートハンド
### flex-grow
要素の伸びる倍率。全ての要素が収まりまだ余白がある際自動で可能領域まで伸びる。
### flex-shrink
要素の縮小倍率。要素がはみ出てしまった際に自動的に収まるように縮む。
### flex-basis
デフォルトは0
ベースとなる長さ、最小領域と言った感じ。
AWSのVPC内のElasticsearchServiceにPHPのelasticserach/elasticsearchを使っても繋がらない

Elasticsearchの公式PHPライブラリであるところの[elasticsearch/elasticsearch](https://github.com/elastic/elasticsearch-php)を使ってAWSのVPC内にあるElasticsearchServiceに接続しようとする。

```php
$builder = \Elasticsearch\ClientBuilder::create();
$builder->setHosts(['https://xxxxxx.xxxxx.es.amazonaws.com/']);
$client = $builder->build();
$client->ping();
```

何の問題もない完璧なるパーフェクトなコードに見えるけど、全く繋がらない。

弊社のElasticserachマスターに聞いたら以下が正解とのこと。

```php
$builder = \Elasticsearch\ClientBuilder::create();
$builder->setHosts(['https://xxxxxx.xxxxx.es.amazonaws.com:443']);
$client = $builder->build();
$client->ping();
```

Hostの末尾の `/` を削除して `:443` とポートを明示的に指定すると動く。
HTTPSだからってポートが自動的に443になると思うのはゆとり:innocent:

助かった :pray:
これだけはおさえておこうJava9の新機能

この記事は[SRA Advent Calendar 2017](http://qiita.com/advent-calendar/2017/sra)の1日目の記事です。

## Java9のリリース内容
こんにちは！　関西事業部の佐々木です。
2017年9月、Java9がリリースされました。
Java8についてはLambda式やinterfaceのデフォルトメソッド、メソッド参照やOptionalの追加など、コーディングに大きく影響を与える内容のせいで注目が集まりました。
おかげでJavaの最新情報ををウォッチしていない人でも、Java8については新機能についてある程度知っている人が多いように思えます。
しかしJava9については、積極的に情報収集していない人はどんなリリースがされたかあまり認識していないようで、とりあえず時間のない人に向けて「これだけはおさえておけ」というJava9のリリース内容の一部をご紹介したいと思います。
ここでいう「これだけ」は私個人の判断なので、異論があるかもしれませんがその場合はコメントで補足していただけると嬉しいです。（他力本願）

## jshell
REPLツールのjshellが使えるようになりました。
![jshell.JPG](https://qiita-image-store.s3.amazonaws.com/0/100799/5aafcf15-abcc-342b-fd10-346b309353ae.jpeg)
文末のセミコロンは省略できますし、Javaのコードを実行するためにわざわざクラスやメソッドを作る必要はありません。（もちろん、クラスもメソッドも作ることはできます）
また、上の例ではRandomオブジェクトを生成したあと「```r.```」とタイプし、TABキーを押してメソッド補完を行っています。
さらにjshellでは「/（スラッシュ）」で始まるコマンドがたくさんあります。
以下はほんの一部です

* /list 入力した内容を表示
* /save ファイルに保存
* /open ファイルの内容を入力
* /! 最後の命令を再実行

## Javadocの検索機能
Javadocで検索機能が使えるようになりました。
![javadoc_search2.JPG](https://qiita-image-store.s3.amazonaws.com/0/100799/d982eb27-74cb-d621-b738-cff5823fa67b.jpeg)
右上にある検索窓にキーワードを入力すると、パッケージ名やクラス名などのインクリメンタルサーチができます。
パッケージ名やクラス名なら、今までもブラウザの検索機能である程度できたと思いますが、メソッド名の検索もいきなりできます。
![javadoc_search3.JPG](https://qiita-image-store.s3.amazonaws.com/0/100799/238412e3-3f0a-215a-83bc-e979a2439d04.jpeg)

## モジュールシステム
実はJava9の一番の目玉機能は「モジュールシステム」です。
モジュールシステムは深く理解しようとすると結構難解なのですが、ここでは最低限の内容に留めておきます。
まず、モジュールシステムの前に以下の2つの問題について簡単に説明します。

* JAR hell
* 見えすぎちゃって困るの問題

### JAR hell
JAR hellとはJavaアプリケーションが多くのJARに依存しているせいで起こる問題です。
依存するJARが多すぎて管理できず実行時にClassNotFoundExceptionが発生したり、異なるバージョンの同じJARファイルがあるせいでエラーが起こったりすることです。
### 見えすぎちゃって困るの問題
この「見えすぎちゃって困るの問題」は私が勝手に命名したものですが、JavaではJARに含まれているクラスというのは「見る」ことができます。
クラスにはprivaite、publicなどのアクセス制御ができますが、他のパッケージからアクセスできるようにするにはpublicにする必要があり、その結果他のJARなどからもアクセスできるようになってしまいます。
また、パッケージにはクラスのようなアクセス制御ができませんでした。

## module-info.java
上記のような問題を解決するのがモジュールシステムです。
モジュールシステムを利用するにはsrcのトップディレクトリに「module-info.java」というファイルを置きます。

```
src -- kazsharp.lambda_logging.jcl
     |                          |
     |                          -- LambdaLog4jLog.java
     |
     -- module-info.java
```
そしてmodule-info.javaには依存するモジュールや公開するパッケージなどを記述します

```module-info.java
module <モジュール名> {
  requires <依存するモジュール名>;
  exports <公開するパッケージ名>;
}
```
従来どおり、自分のモジュール内ではexportsしていないパッケージでもアクセス可能ですが、他のモジュールはexportsされているパッケージにのみアクセスできます。
また、複数ののモジュールに同じパッケージがあるとエラーになります。

## 経過措置
モジュールシステムを知ると心配になるのが、Java9を使うと

* requiresを書かないと他のJARが使えないの？   
* exportsを書かないと他のJARから使えないの？

ということですが「経過措置」という期間が設けられています。
経過措置には「無名モジュール」や「自動モジュール」というものがあり、module-info.javaを配置していなくても

* モジュールパス上の全モジュールをrequires
* 自分の全パッケージをexports

などの措置が行われますが、あくまで経過措置なのでJava9を使うのならmodule-info.javaにより適切な設定を行うのがいいと思います。


以上、Java9で最低限これだけは押さえておけという内容をご紹介しました。
実際に開発を行うにはモジュールシステムやその他の内容についてもっと知っておく必要がありますが、この記事をきっかけにJava9についてより詳しい情報を調べる足掛かりになれば幸いです。
ゼロから始める物体検出

よくあるアレの忘備録。
![FullSizeRender.png](https://qiita-image-store.s3.amazonaws.com/0/192887/92b17115-cd65-ad94-06b2-153b9861f46f.png)

参考にした記事
参考：[YOLOv2(Keras/TensorFlow)でディープラーニングによる画像の物体検出を行う](https://qiita.com/yampy/items/7a705acf4c6899bc11c7)(yampyさん)



#1.Tensorflowをインストールする
PythonとTensorflowをインストールする。
参考：[(初心者向け)TensorFlowをインストールする](https://qiita.com/egplnt/items/c5055f821a4770edbf8a)(egplntさん)の3まで


</br>
</br>
</br>
</br>
</br>

#2.ライブラリのインストール
ターミナルを立ち上げ、色々インストールします。
$より後をコピペ。

まずはwgetというコマンドを使えるようにします。後々使うらしい。
`$ brew install wget`
インストールできたら次へ。


`$ git clone https://github.com/allanzelener/YAD2K.git
`

yad2kというディレクトリができているので
`$ cd yad2k`
で移動します。

必要なライブラリを1行ずつインストール
`$ pip install numpy h5py pillow`
`$ pip install tensorflow-gpu`
`$ pip install keras`

</br>
</br>
</br>
</br>
</br>


#3.config と weight　のダウンロード
config=設定ファイル
weight=学習済みの重み

`$ wget https://pjreddie.com/media/files/yolo.weights`
`$ wget https://raw.githubusercontent.com/pjreddie/darknet/master/cfg/yolo.cfg`

ファインダーなどでyad2kのフォルダの下に
・yoro.cfg
・yolo.weights
<img width="273" alt="スクリーンショット 2017-11-28 16.14.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/192887/11dbd771-3cf4-137b-2193-d77156bfa341.png">
が入って入ればおっけー。

これらは、学習データとして[Pascal VOC Challenges](http://host.robots.ox.ac.uk/pascal/VOC/)の2007年+2012年のデータを使用しているらしいです。

</br>
</br>
</br>
</br>
</br>

#4.モデル生成

まずは1で入ったtensorflowのあるpython3に入ります。
binの下にあるactivateを以下コマンドで実行します。
`$ source acrivate`
うまく実行されれば、`(tf)$`と＄の前に仮想環境の名前がつきます。


configとweightを読み込んでモデルを生成します。
yad2dk.pyのあるフォルダまで移動して以下実行。
`(tf)$ python yad2k.py yolo.cfg yolo.weights model_data/yolo.h5`


</br>
</br>
</br>
</br>
</br>

#5.実行
`(tf)$ python test_yolo.py model_data/yolo.h5
`
imagesフォルダの中にデフォルトで数枚写真があります。
それを読み込んで、検出結果はimages/outのフォルダに新しく生成されます。
Cloud Functions for Firebase で deploy 先を切り替える

Firebase Project を develop, staging, production など切り替える場合、例えば iOS だったら `GoogleService-Info.plist` を環境別に切り替えれば良い。  
しかしその場合 Cloud Functions の deploy 先もそれぞれ切り替える必要がある。

## firebase use --add

このコマンドを打つと、deploy 先を設定できる。

* `? Which project do you want to add?`
    * 対話モードになり、 Firebase Project の一覧が表示される。そこから使うものを1つ選ぶ
* `? What alias do you want to use for this project?`
    * 名称を決める

```bash
$ firebase use --add
? Which project do you want to add? development-project
? What alias do you want to use for this project? (e.g. staging) default


$ firebase use --add
? Which project do you want to add? staging-project
? What alias do you want to use for this project? (e.g. staging) staging
```

すると .firebaserc というファイルが生成される

```json
{
  "projects": {
    "default": "development-project",
    "staging": "staging-project"
  }
}
```

## firebaes use で切り替え

```bash
$ firebaes use staging
$ firebase deploy --only functions
```

これでそれぞれの環境への deploy ができるようになった。

## 参考

*  [Firebase CLI リファレンス  \|  Firebase](https://firebase.google.com/docs/cli/?hl=ja)
【質問】Pepperのタブレットに証明書をインストールしたい

プリンターに自己証明書を登録して、Pepperのタブレットとプリンターを
SSL暗号化通信したいと考えています。

プリンターに登録を行い、HTTPSで印刷までは出来たのですが、
自己証明書なので、タブレット側にルート証明書を持っていない為、
印刷前にタブレットにて確認アラートが出てしまう状況です。

そこでPepperのタブレットにルートCAとして証明書を登録したいのですが、
インストールの方法がわからず、手詰まっています。

どなたか、タブレットに証明書をインストールする方法をご存じないでしょうか。
SE歴8年の無職がSilexでサイト構築に挑む



簡単にできるって書いてたからやってみました。

- [PHPマイクロフレームワークSilexでつくるシンプルWebサイト | | リーテラトバリタブログ](http://elsur.xyz/website-with-silex)


#ComposerからSilexをダウンロード

書いてあるコードはこちら。

	composer require silex/silex:~2.0 twig/twig

composerというのがイマイチまだ理解しきれてないんですけど、こうやって書いてあるからにはダウンロードしてくれるマンなんでしょう。

**あと最初、silexとtwigって書いてあるのに１行しかねえぞ！！**

とか意味不明なこと思っててすみませんでした。文盲。
並べて書けるんですね。
ただ問題は次。


##どこに？
**詰まりました。**

ダウンロード……するのは、プロジェクトを置く場所？的なところですよね、多分。

どこに作るの？
デスクトップ？

というわけではないはずなので、空気を読んでプロジェクト用のディレクトリを作成します。

**考えてみればこの程度のことをわざわざ書く必要もなかった。**


##実行。
こんなになりました。

	$ cd sample2
	$ ls
	composer.json	composer.lock	vendor
	
	$ ls vendor/
	autoload.php	pimple		silex		twig
	composer	psr		symfony

以降の手順でindexとかなんか色々作るんですが。

**sample2に作るのか、vendorに作るのかがわかりません。**

たぶんここ（sample2）だとは思うんですけど……書いてて悲しくなってきた……。


#中身をつくる
##index.php

> 公式ドキュメント通りで全く問題なしです。

**公式ドキュメント is 何。**

- [Homepage - Silex - The PHP micro-framework based on the Symfony Components](https://silex.symfony.com/)

ああ、確かにここに書かれてるサンプルと同じですね。
なるほど。

viを最近ようやくおぼろげに覚えたのでサクッと作成しました。

1. vi index.php
2. [A]（追加書き込み）
3. コピペ。Command+vが問題なく使えて良かった
4. [Esc]（編集終了）
5. [:x]から[Enter]（上書き保存して終了）

こんな感じで。

> PHP（5.4.0以上）のビルトインサーバーを起ち上げて、指定したホストにアクセスすれば「Hello, World!!」が表示されます。

###なんて？

とりあえず、書いてあるコマンドを叩いてみます。
ルートディレクトリは自分でいいんだよね？
ってことでこんな感じで。

	php -S localhost:8000 -t ./

起動は成功。
**アクセスでエラー。**

###デバッグ
見てみるとindex.phpの2行目でエラーとのこと。
そんなんファイルパスしか書かれてないぞ。
つまりファイルパスがだめと。

該当部分はこんな感じ。

	require_once __DIR__.'/../vendor/autoload.php';

えっと、現在のところから一個戻ってvendorにアクセスしてるから……。

**sample2じゃなくてもう一つ深いところに作らないといけないんですね、これ。**

じゃあ適当にwwwとかフォルダ作ってそこを指定してサーバーを立ち上げると……成功しました。
なるほどー。

##twigでviewを作る
よくわかりませんが、layout.twigとindex.twigというものを作成するようです。

###どこにだろう。
例によってぶちあたる疑問。

まあいいやとばかりに作成しました。
あとからmoveすることにします。


##Twig表示のためにindex.phpを修正
次にindex.phpを修正するようです。
**テキストの中に、ディレクトリを指定する場所があります。**
なるほどここで指定するわけですか。
じゃあviewとか作ってそれに放り込めばいいのかな。

指定先はこんな感じに修正。

	'twig.path' => '../view'


###どこを置き換える？
あと、書いてあるphpって全部じゃないですよねたぶん。

適当に読み解いて、app->getが重複していたので『Routeがどうこう』ってコメント以下を全とっかえしました。


###そして実行

![スクリーンショット 2017-11-28 16.00.36.jpg](https://qiita-image-store.s3.amazonaws.com/0/214031/968c7738-f38c-ff12-1379-3c0b1fce2eb1.jpeg "スクリーンショット 2017-11-28 16.00.36.jpg")

できましたー！！


#課題
これローカルだけどGCPにアップロードするにはどうするんだろう？
とりあえずステップで進んでいきます。
次はユーザ認証。
参考資料はこれ。

> [PHPマイクロフレームワークのSilexでログイン処理をささっとつくる |  | リーテラトバリタブログ](http://elsur.xyz/silex2-loginform)
alpineにlibnsl.soをインストールした備忘録

alpineのphp7からoracleに接続しようとして、以下のエラーが出たときの試行錯誤

PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib/php7/modules/oci8.so' - Error loading shared library libnsl.so.1: No such file or directory (needed by /usr/local/lib/instantclient_11_2/libclntsh.so.11.1) in Unknown on line 0

alpineにはlib***のデータを入れるためのパッケージがapkでインストールできなかったりします。
他のサイトにはもうdebianとかcentosとか使おうぜって書いてあるけど、軽量化したいからalpineつかってるんだが？ってなります。
ソースから入れましょう。

以下dockerfileの抜粋です。

```
FROM alpine

RUN apk --update add \
    gettext-dev \
    git \
    libtirpc-dev \
    libtool \
    -- nocache

RUN wget https://github.com/thkukuk/libnsl/archive/v*.*.*/libnsl-*.*.*.tar.gz &&
    tar xf libnsl-*.*.*.tar.gz &&
    cd libnsl-*.*.*/ &&
    sh autogen.sh &&
    ./configure &&
    make &&
    make install

RUN ln -s /usr/lib/libnsl.so.2 /lib/libnsl.so.1
```


別にイメージ大きくなってもいいやって人はcentsとかでパッケージを一括インストールしたほうが圧倒的に楽です。
毎回毎回パッケージをインストールし直して一喜一憂するのが本当に手間。。。
いずれ時間があったら全体的な構成含め書きます。
RubyでTwitterAPIを使う準備をしよう。

#TwitterAPIを使うために準備していきます。

##gemを入れて行きましょう。
###Gemfileを作ります。

```ruby:ターミナル
$$ touch Gemfile
```
###Gemfileを書いて行きます。
```ruby:Gemfile
source "https://rubygems.org"

gem 'rails_12factor', group: :production

gem "rake"
gem "sinatra"
gem "sinatra-contrib"
gem "twitter"
gem "curb"
gem "omniauth-twitter"
gem "oauth"
```
要らないと思われるコードもありますが、要らないと思った方は消してください。
###gemをインストールして行きます。
```ruby:ターミナル
gem install bundler
bundle install --path vendor/bundle
```

##TwitterAPIを取得しよう
ここは追って書いて行きます。
今回は取得している前提で話を進めます。

以下から取得できます
[TwitterAPI](https://apps.twitter.com)


##gemを入れ終わったらrbファイルを書いて行きます。

今回は環境変数を使っているので環境変数の設定は各自でお願いします。
時間があれば追って記述して行きます。

取得してきたKeyを環境変数に入れ以下のコードを書きます。

```ruby:twitter.rb
class TwitterSet
  def initialize(config)
    @config = config
    @rest   = Twitter::REST::Client.new(@config)
    @stream = Twitter::Streaming::Client.new(@config)
  end
  private
end

CONFIG = { #TwitterTokenKey
	consumer_key:        ENV.fetch("CONSUMER_KEY"),
	consumer_secret:     ENV.fetch("CONSUMER_SECRET"),
	access_token:        ENV.fetch("ACCESS_TOKEN"),
	access_token_secret: ENV.fetch("ACCESS_TOKEN_SECRET")
}
app = TwitterSettings.new(CONFIG)
app.[ここにメソッド名]
```


##以上を使用して出来る事

###[RubyでTwitterAPIを使いプロフィールを更新しよう](https://qiita.com/flmil/items/2b989f845fa8d62c7a06)
crontabを冪等に編集するスクリプト

# 必要になったシチュエーション

- 複数人でユーザーを共用しているサーバー
    - 他の人が別のcrontabの設定を加えるかも知れない（そして間違えて `crontab -r` を実行して削除してしまうかも知れない）
- 決まった時刻にスクリプトを実行する設定を、簡単かつ確実に登録・編集したい。

# 試した環境

```
$ cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
```

# 実際に作ったスクリプト

下記の2つのスクリプトを同じディレクトリーに置き、`install-cron.sh`を実行しよう。
ここでは`run.sh`というスクリプトを毎週木曜日の朝8時に実行する設定を、crontabに登録する場合を想定して書いた。

```bash:install-cron.sh
#!/bin/bash

script_dir="$(pwd)"/"$(dirname "$0")"

# EDITOR 環境変数として edit-crontab.shを設定することで、スクリプトでcrontabを編集する
env EDITOR="$script_dir"/edit-crontab.sh crontab -e
```

```bash:edit-crontab.sh
#!/bin/bash

crontab_file="$1"

script_dir=$(dirname "$0")

# 実際に実行するスクリプト。もちろんここはご自由に。
run_sh="$script_dir"/run.sh

# 毎週木曜日の午前8時に実行する場合。ここの設定方法はググろう。
new_cron_entry="0 8 * * 4 $run_sh"

# NOTE: $run_sh に、正規表現のメタキャラクターが入っていると正しく動作しないので注意。
if grep --no-messages -e "$run_sh" "$crontab_file" ; then
    # crontab に run.sh （実行したいスクリプトの名前）が書かれていなければ、該当する行を新しいcrontabの行で書き換える。
    sed -ie "s|.*$run_sh.*|$new_cron_entry|" "$crontab_file"
    echo Edited crontab entry.
else
    echo "$new_cron_entry" >> "$crontab_file"
    echo Added crontab entry.
fi
```

# 注意事項

- 「対象のcrontabの設定が設定済みかどうか」を、「crontabに実行したいスクリプトの名前が書かれているかどうか」で判定するため、同じスクリプトを実行する設定を2つ以上書きたい場合などはうまくいかない。
- その他、込み入ったことをしたくなったら素直に[ansibleのcron module](http://docs.ansible.com/cron_module.html)などを使った方がいいと思う。
Sotaモーションパラメータ一値一覧

#####Sotaのモーションパラメータをまとめてみた
各モーターのパラメータが見やすくまとまっているサイトがないので書きました。

Sotaモーションプログラミングの参考になれば。。

| ID| CSotaMotion const| name| Min. val| Max. val| Neutralpos. |
|:-----------------|:------------------|:------------------:|:------------------:|:------------------:|:------------------:|
|1|SV_BODY_Y        | 胴体      | -1500 (turn right) | 1500 (turn left)  | 0           |
| 2 | SV_L_SHOULDER    | 左肩      | -1500 (behind body)| 900 (beside head) | -900        |
| 3 | SV_L_ELBOW       | 左肘      | -900 (angeled)     | 650 (overextended)| 0           |
| 4 | SV_R_SHOULDER    | 右肩      | -900 (beside head) | 1500 (behind body)| 900         |
| 5 | SV_R_ELBOW       | 右肘      | -650 (overextended)| 900 (angeled)     | 0           |
| 6 | SV_HEAD_Y        | 首ヨー軸  | -1500 (look right) | 1500 (look left)  | 0           |
| 7 | SV_HEAD_P        | 首ピッチ軸| -270 (look up)     | 50 (look down)    | 0           |
| 8 | SV_HEAD_R        | 首ロール軸| -300 (lean right)  | 300 (lean left)   | 0           |
VIMから秀丸Grepを呼び出す

# VIMから秀丸Grepを呼び出す
- [「vimから秀丸のgrepを呼び出す」を参考にしました。](http://deris.hatenablog.jp/entry/20111023/1319381440)
    - 上記だと上手く動かなかったので、スクリプトを若干修正。

## 「なにやってんだろう」って、VimScript書きながら100回は唱えたかな
- 苦しみ
    - Windowsのランチャーアプリからgrepを呼び出した時、カレントがランチャーアプリのフォルダになる
    - 上記の解決方法がよくわからない
    - 上記理由で、vimからgrep呼び出すとパス入力が億劫
    - 上記理由で、Grepだけ秀丸を使っている
    - もっと良い方法があれば、教えてください


```vim
"call hidemall grep"{{{
if has('win32')
  nnoremap <silent> <leader>H :<c-u>call <SID>HidemaruGrep()<CR>

  function! s:HidemaruGrep()
    let l:word = input('Search:')
    let l:ftype= input('Extension(.txt):')
    if l:ftype == ""
        let l:ftype = "*"
    else
        let l:ftype = "*" . l:ftype
    endif

    let l:targetfile  = expand("%:p")
    let l:lastfolderid = strridx(targetfile,"/")
    let l:targetfolder = l:targetfile[0:l:lastfolderid] . l:ftype

    let l:cmd = '!"C:\Program Files (x86)\Hidemaru\Hidemaru.exe" /gu, "' . l:targetfolder . '"' . l:word
    silent execute l:cmd
  endfunction
endif
"}}}

```
Qiitaでのマークダウンの記述の仕方を覚える

# マークダウンでのコードの記述の仕方
マークダウン記法でコードを記述するときは\`（バッククオート。キーボードの＠マークのところにあるやつ。）を使う。'（シングルクオーテーション）とは違うよ！

## 全体をコード化
\`\`\`
↑
これで囲うと囲った範囲が全てコードと認識される。
↓
\`\`\`




```
↑
これで囲うと囲った範囲が全てコードと認識される。
↓
```
---
## 一部分をコード化
\`←　これ　→\`　で囲うと一部分だけ表示もできる。（インライン表示というらしい）
　　
`←　これ　→`　で囲うと一部分だけ表示もできる。（インライン表示というらしい）
[Riot.js]Maximum call stack size exceededに陥った


Riot.jsで下記エラーに遭遇して少しだけハマりました。
```Uncaught RangeError: Maximum call stack size exceeded```

# Maximum call stack size exceededとは
再帰関数などでreturnされずに上限まで呼び出されたときに起こります。

関数を呼び出す毎にスタックに追加してるけどもう限界ってときになります。

このエラーが出た時は再帰関数のreturn漏れを疑うのが早期解決っぽいです。

# 再帰関数がない
私の場合、コードを確認しても再帰してる自作関数が見つかりませんでした。
となると怪しいのはRiot.jsが提供してる関数かなと思い、this.update()周りを要確認してました。
console.log()で確認しながら探していると、自作タグの呼び出し先で繰り返しthis.update()が呼ばれているらしい。

ということでその周辺を探していると、変数名で誤字が発覚して、本来通らなくなるif文を常に通ってるせいで毎回this.update()が呼ばれていた模様。

# まとめ
結果単なる誤字が原因だったんですが、子タグのupdate()が毎回呼ばれてることになかなか気づかなかったので備忘録に。
Android Studio3.0を勉強していてdimen.xmlがなくてハマった

#dimen.xmlがない。
Android2.x系の参考書で勉強してたら出てきた。
res > valuesの直下に作成するらしい。ふーん。

```xml:dimen.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="activity_horizontal_margin">25sp</dimen>
</resources>
```
これで他のlayout.xmlから参照できる。参照するときは
`android:paddingBottom="@dimen/activity_horizontal_margin"`
みたいに書くとよい。
irohaboard のコンテナイメージ、オールインワン

# iroha Board について
マニュアルなしでも、めちゃめちゃ使いやすいLearning Management SystemのOSS。

http://irohaboard.irohasoft.jp/

オールインワンのコンテナイメージを作ってみた。

##通常のインストール
http://irohaboard.irohasoft.jp/download/

##通常のコンテナイメージ（RDBMSとHTTPDを分ける）
https://hub.docker.com/r/bbrfkr0129/irohaboard/
bbrfkr0129作、コンテナ２つでリンク

##オール・イン・ワン・コンテナイメージ
めんどくさがり屋のために作成
https://hub.docker.com/r/tksarah/irohaboard/

### オールインワンのコンテナの使い方

```shell-session
# docker run -itd --name irohaboard -p 80:80 tksarah/irohaboard
```

プラウザで``http://＜docker host address＞/``にアクセスし、管理者として初期ログインは「root/irohaboard」

### 環境とコンテナイメージの仕様
Dockerfile作ればいいじゃんというつっこみは置いといて、以下程度の内容。

* irohaboard のインストールはセットアップ済み
* データベースは専用のirohaboardを作成済み
* httpd.conf : ".htaccess" の許可をドキュメントルートに設定済み「AllowOverride All」
* /sbin/start_iroha.sh にてmariadb,httpdを起動

|item|version|
|:---:|:---:|
|irohaboard|0.9.10|
|base image|CentOS 7.4|
|httpd|2.4.6|
|mariadb|5.5.56
|php|5.4.16|
|cakephp|v2.7.11

## 学習システムの構築

ざっくり

* **ログイン**
  * ロールは管理者と受講者
     * 管理者でユーザ・グループ・コース・コンテンツもろもろ作る
     *   作られた受講者（ユーザ）でコースを受講できる

* **コース**
   * コース作成
   * コースの中でコンテンツ作成
     * テキスト、リッチテキスト、動画、配布資料、テスト、（ラベル）等から選ぶ・・・具体的コンテンツ作成部

* **グループ**
  * グループを作成
  * コースを紐付ける事ができる

* **ユーザ**
  * ユーザを作成
    * コースを紐付ける事ができる
    * グループを紐付ける事ができる
* **他**
  * 全体へのお知らせを表示できる
  * グループに対して個別のお知らせを表示できる
  * テストの学習履歴を一望できる
  * システム設定、
       * LMS名、テーマカラー、コピーライト、全体へのお知らせ（Top）
  * IDにはマルチバイトも可能
  * 学習の進捗管理が可能、一覧をCSV出力可能（うまく動いていない・・・）

# 参考

* https://github.com/irohasoft/irohaboard
天気予報を取得してLINEに通知を送る

#はじめに
学校でちょっとかじった程度のプログラム初心者です。
このご時世プログラムくらい書けるようになっておくべきだろう、という軽い動機で勉強してみることにしました。
まずはじめに、指南ページに載っていた題材に手を出してみました。

使用言語はGoogleAppsScriptです。
よく調べずに選びましたが、開発環境を整えなくてもすぐ作業に取りかかれるところ、
自動実行の設定が簡単なところなどが決め手になりました。

#構成
livedoor天気のWeb API（json形式）を取得
http://weather.livedoor.com/weather_hacks/webservice
↓
必要なお天気情報を取り出しテキストを整形
　今日明日の天気と最高/最低気温
↓
LINE Notifyにテキストを送る

#コード
~~~javascript:main
//LineNotifyにメッセージを送信
function sendHttpPost(message){
  var token = "--LineNotify token--";
  var options =
   {
     "method"  : "post",
     "payload" : "message=" + message,
     "headers" : {"Authorization" : "Bearer "+ token}

   };

   UrlFetchApp.fetch("https://notify-api.line.me/api/notify",options);
}

//メインルーチン
function whetherMailDay() {
  //livedoor天気からjson形式のWEBAPIをリクエスト
  var response = UrlFetchApp.fetch("--json URL--");
  var json=JSON.parse(response.getContentText());
  
  //jsonから日時を取り出してdateに格納
  //日時の表示形式をYYYY-MM-DDからMM/DDに変換
  var date = new Array(2);
  for (var x = 0; x < 2; x++){
    date[x] = json["forecasts"][x]["date"];
    date[x] = date[x].slice(5);
    date[x] = date[x].replace( /-/g , "/" ) ;
  }
  
  //気温がnullの場合--に変換
  var maxMin = ["max","min"];
  var Temp = new Array(2);
  for(var i = 0; i < 2; i++){
    Temp[i] = new Array(2)
    for(var j = 0; j < 2; j++){
      if(json["forecasts"][i]["temperature"][maxMin[j]] == null){
        Temp[i][j] = "--";
      }else{
        Temp[i][j] = json["forecasts"][i]["temperature"][maxMin[j]]["celsius"];
      }
    }  
  }
  
  //送信用文字列の作成
  var strBody = "天気予報";
  for(var i = 0;i < 2;i++){
    strBody = strBody + "\n" + date[i] + " : " + json["forecasts"][i]["telop"]
            + "\n" + "最低気温 : " + Temp[i][1] + "℃  最高気温 : " + Temp[i][0] + "℃";
  };

  sendHttpPost(strBody);
}
~~~
実行結果
>天気予報
>mm/dd : 雨
>最低気温 : --℃  最高気温 : XX℃
>mm/dd : 晴
>最低気温 : XX℃  最高気温 : XX℃

#わかったこと
 - JSON形式の読み込み方
 - LineNotifyへのテキストデータの送り方


#課題
 - 別の天気予報APIから降水確率を取得
   - 可能ならXML形式の読み込みに挑戦したい
 - livedoor天気のAPI内にある天気アイコンをLINEに表示させる
   - LineNotifyを通して画像を表示させるには


#おわりに
コード的にはほとんどコピペで済むようなものでしたが、APIの中身を理解するのに時間を費やしてしまいました。
天気予報APIを取得する時刻によって、気温にnullが入っている場合があることがわかり、そりゃないだろという感じでした。


#参考サイト様
 - http://coreblog.org/ats/minpy-4th-omake/
 - https://tonari-it.com/gas-api-weather/
 - https://qiita.com/tadaken3/items/5f916a12587e42ece814
ActiveRecordで動的なjoinをスッキリ書く方法

[エイチームライフスタイルアドベントカレンダー2017](https://qiita.com/advent-calendar/2017/ateam-lifestyle)、1日目です！
初回は [株式会社エイチームライフスタイル](http://life.a-tm.co.jp) のエンジニア @u_minor3110 が担当します。
今日はActiveRecordのお話をします。

さっそくですが、SQLでは簡単に書けても、ActiveRecordではどうやって書くんだろう？と悩んだことはありませんか？Arelを使うにしても、可読性が下がってしまう気がするし、N+1を回避するためにpreloadさせたい、なんて時はさらに書き方に困ります。
今回は **join時に動的に結合条件を追加したい、かつ、preloadさせたい** 時の解決方法です。

たとえば以下の情報が取得したい時。
「本の一覧を特定の日付以降のレビューがあればそれを添えて表示させる」

```sql
SELECT * FROM books b LEFT JOIN reviews r ON b.id = r.book_id AND r.created_at >= 'xxx'
```

SQLで書くと一例としてこうなります。
ActiveRecordで書くなら、まず思いついた書き方は、

```ruby
Book.eager_load(:reviews).where('reviews.created_at >= ?', 'xxx')
```
これだと、レビューのない本が表示されません。
(join後にwhereが適用されるため。)

```ruby
Book.eager_load(:reviews).where('reviews.created_at >= ? OR reviews.id IS NULL', 'xxx')
```
これだと、レビューのない本も表示されますが、レビューの日付がxxxより古い本が表示されません。

## associationに動的に条件をつけられるようにしてみる 
次に思いついた書き方。

```ruby
class Book < ApplicationRecord
  cattr_accessor :recent_created_at
  has_many :recent_reviews, lambda { where('created_at >= ?', @@recent_created_at) }, class_name: 'Review'
end
```
```ruby
Book.recent_created_at = 'xxx'
Book.eager_load(:recent_reviews)
```

これだといちおう上手くいきます。ただ、クラス変数を使っている時点で**スレッドセーフではありません。**
変数をスレッドセーフに扱えるgemもありますが、秘伝のタレ化するのが見えています。

## ggrks
次に検索して出てきたtipsを試してみる。

```ruby
Book.eager_loads(:reviews).joins("and reviews.created_at >= 'xxx'")
```

いけます。上手くいきますが、**joinsが複数あるとandの位置がjoinの最後に来てしまう**ためダメです。ゆえにオススメはできません。

## 別々にクエリを発行してみる
次に考えたのは、別々にクエリを発行する方法。

```ruby
books = Book.all
reviews = Review.where(book_id: books.pluck(:id)).where('created_at >= ?', 'xxx').index_by(&:id)
```
```ruby
books.each do |book|
  reviews[book.id]
end
```

いけます！ただ、スマートではない気がしますね。

よくある処理だと思っていたので、簡単に対応できると思っていたのですが、こうなるといよいよArelの出番か、、、と思っていたのですが、よい方法が見つかりました。

## Preloaderが鮮やかだった

```ruby
books = Book.all
ActiveRecord::Associations::Preloader.new.preload(books, :reviews, Review.where('created_at >= ?', 'xxx'))
```
```ruby
books.each do |book|
  book.reviews
end
```

これなら通常のassociationのように扱えます。
実はこれ、半年くらい解決方法に悩んでいました。他に良い方法をご存知の方がいらっしゃったら教えてください。

# 参考
https://qiita.com/k0kubun/items/80c5a5494f53bb88dc58
https://kadoppe.com/archives/2012/01/dinamic_conditions_for_has_many_association.html
http://aserafin.pl/2017/09/12/preloading-associations-with-dynamic-condition-in-rails/

# 最後に
[エイチームライフスタイルアドベントカレンダー2017](https://qiita.com/advent-calendar/2017/ateam-lifestyle)の1日目、いかかでしたか。
まずは新しいことより、実用的なところをテーマにしてみました。
2日目は[株式会社エイチームライフスタイル](http://life.a-tm.co.jp)が誇る、インフラを中心に活躍する @ihsiekさんが Elasticsearch に関する記事を書かれるそうですので、お楽しみに！

[株式会社エイチームライフスタイル](http://life.a-tm.co.jp/)では、一緒に働けるチャレンジ精神旺盛な仲間を募集しています。興味を持たれた方はぜひエイチームグループ採用サイトを御覧ください。
http://www.a-tm.co.jp/recruit/
[メモ]ターミナルの設定

ターミナルの色やユーザ名の表示の変更は以下のファイルをいじる

**~/.bashrc**

またPS1は以下のコマンドで調べられる

**echo $PS1**

現在の設定はこんな感じ

```.bashrc
PS1="\[\e[31m\]\w>\[\e[0m\]"
```

参考
[Linuxで、bash プロンプトを素敵で実用的なものに変更する ](https://jp.linux.com/news/linuxcom-exclusive/416957-lco20140519)
gmpy2をインストールする手順メモ

# gmpy2をインストールする手順
下記を実行するだけ。

``` bash
sudo apt-get update
sudo apt-get install python3-gmpy2
```

# gmpy2をインストールする手順(自分でビルドする場合)
自分でビルドする場合の手順メモは以下。ubuntu desktop 16.04LTSで実施しました。

# python3-devをインストール
``` bash
sudo apt-get -y update
sudo apt-get -y install python3-dev
```

# 作業用ディレクトリを作成
``` bash
cd ~
mkdir static
cd ~/static
mkdir src
```

# m4をインストール
``` bash
cd ~/static
wget https://ftp.gnu.org/gnu/m4/m4-1.4.18.tar.gz
tar xf ./m4-1.4.18.tar.gz
cd ~/static/m4-1.4.18/
./configure --prefix=/usr
make
make check
sudo make install
```

# gmpをインストール
``` bash
cd ~/static
wget https://gmplib.org/download/gmp/gmp-6.0.0a.tar.bz2
tar xf ./gmp-6.0.0a.tar.bz2 -C ~/static/src
cd ~/static/src/gmp-6.0.0
./configure --prefix=$HOME/static --enable-static --disable-shared --with-pic
make
make check
make install
```

# mpfrをインストール
``` bash
cd ~/static
wget http://www.mpfr.org/mpfr-3.1.2/mpfr-3.1.2.tar.bz2
tar xf ./mpfr-3.1.2.tar.bz2 -C ~/static/src
cd ~/static/src/mpfr-3.1.2
./configure --prefix=$HOME/static --enable-static --disable-shared --with-pic --with-gmp=$HOME/static
make
make check
make install
```

# mpcをインストール
``` bash
cd ~/static
wget https://ftp.gnu.org/gnu/mpc/mpc-1.0.3.tar.gz
tar xf ./mpc-1.0.3.tar.gz -C ~/static/src
cd ~/static/src/mpc-1.0.3
./configure --prefix=$HOME/static --enable-static --disable-shared --with-pic --with-gmp=$HOME/static --with-mpfr=$HOME/static
make
make check
make install
```

# gmpy2をインストール
``` bash
cd ~/static
wget https://github.com/aleaxit/gmpy/releases/download/gmpy2-2.1.0a1/gmpy2-2.1.0a1.tar.gz
tar xf ./gmpy2-2.1.0a1.tar.gz -C ~/static/src
cd ~/static/src/gmpy2-2.1.0a1
sudo python3 setup.py build_ext --static=~/static install
```

# 参考
https://github.com/aleaxit/gmpy/blob/master/INSTALL
Charset.forNameでUnsupportedEncodingExceptionを回避する

#UnsupportedEncodingExceptionが発生する例

```java
public static void main(String[] args) {
	try {
		String str = "hello";
		byte[] utf8Bytes = str.getBytes("UTF-8");
		byte[] sjisBytes = str.getBytes("SJIS");
	} catch(UnsupportedEncodingException e) {
		// 発生し得ないが、書くしかない
	}
}
```

Javaで文字列⇔バイト配列の変換を行う際に、`String.getBytes(String charsetName)` や `new String(byte[] bytes,String charsetName)`を使うことができますが、`charsetName`が不正な場合に、検査例外である`UnsupportedEncodingException`が発生します。
検査例外のため、`try-catch`や`throws`が必要となりますが、文字コードを動的に変更するのでなければ、まず発生し得ない例外なので、記述が冗長になります。

#Charset.forNameを使う

```java
public static void main(String[] args) {
	String str = "hello";
	byte[] utf8Bytes = str.getBytes(StandardCharsets.UTF_8);
	byte[] sjisBytes = str.getBytes(Charset.forName("SJIS"));
}
```

文字コードの指定に`Charset`型を使用すると、`UnsupportedEncodingException`が発生しなくなります。
UTF-8は`java.nio.charset.StandardCharsets`クラスの定数として用意されていますが、SJISは無いので、`Charset.forName(String charsetName)`を使います。
当然、`charsetName`が不正であれば例外が発生しますが、その場合の例外は全て非検査例外のため、ハンドリング処理が不要になります。
アクセスされたブラウザ名をPHPで判別する方法


アクセスされたブラウザ名をPHPで判別するサンプルコードを以下に記します。
よりよい方法やバグ等ございましたら、アドバイスいただけると光栄です。

##ブラウザを判別するには
PHPでブラウザ名を取得するには、ヘッダーに含まれるHTTP_USER_AGENTを取得し判別します。 
実際に [$_SERVER変数][strstr] の内容を確認してみましょう。

```php
echo $_SERVER['HTTP_USER_AGENT'];
```

Firefoxを使用していた場合、以下のようなデータが取れます。

```
Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0
```

「Firefox」という文字列があるので、それを使えば判定が出来そうです。
[strstr関数][strstr] を使って判定してみます。

```php
if (strstr($browser , 'Firefox')) {
    echo('ご使用のブラウザはFirefoxです。');
}
```

これで、Firefoxを使用していることの判定は出来ました。

思ったより簡単そうです。

##思わぬ落とし穴
しかし、何事もそう簡単にはいかないのが現実。

Chromeを使っていた場合のユーザーエージェントの文字列をご覧ください。

```
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36
```

「Chrome」という文字列があるので、それを使えば判定が出来そうです。

**あれ。ちょっと待った。「Safari」って入ってる。**



ちょっと危険な香りがしてきましたね。

続いて、Edgeを使っていた場合のユーザーエージェントの文字列をご覧ください。

```
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299
```

**おい。「Chrome」も「Safari」も入ってるぞ。どうしてくれるんだ。**


なんだかややこしくなってきました。

最後に、Safariを使っていた場合のユーザーエージェントの文字列をご覧ください。

```
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/600.8.9 (KHTML, like Gecko) Version/8.0.8 Safari/600.8.9
```

**今度は「Safari」だけかよ！！**


といった具合に、一部のブラウザでは非常にややこしい感じになっているので、判定の順序に気を付けないと、本当はChromeを使っているのにSafariを使用していると誤判定したり、Edgeを使っているのにChromeを使用していると誤判定したりする恐れがあります。

なので、以下を踏まえた上でコードを組む必要があります。
>① ChromeよりEdgeが先
>② SafariよりChromeが先


##サンプルコード
以上を踏まえた上で、以下のようなサンプルコードを作成しました。

```php:UserAgentChecker.php

// 判定するのに小文字にする
$browser = strtolower($_SERVER['HTTP_USER_AGENT']);

// ユーザーエージェントの情報を基に判定
if (strstr($browser , 'edge')) {
    echo('ご使用のブラウザはEdgeです。');
} elseif (strstr($browser , 'trident') || strstr($browser , 'msie')) {
    echo('ご使用のブラウザはInternet Explorerです。');
} elseif (strstr($browser , 'chrome')) {
    echo('ご使用のブラウザはGoogle Chromeです。');
} elseif (strstr($browser , 'firefox')) {
    echo('ご使用のブラウザはFirefoxです。');
} elseif (strstr($browser , 'safari')) {
    echo('ご使用のブラウザはSafariです。');
} elseif (strstr($browser , 'opera')) {
    echo('ご使用のブラウザはOperaです。');
} else {
    echo('知らん。');
}

```

しかし、これらの値はバージョンアップなどで予期せず変更される可能性があります。
実際にIEでは、IE11になってユーザーエージェントの文字列から「MSIE」が削除され「Trident」が追加されました。
>[Microsoft ユーザー エージェント文字列の変更][IEandEDGE]

そのため、IEのところ見てもらえばわかる通り、識別子が2種類あります。

あくまで参考程度にご覧ください。

##関連URL
>[UserAgentからOS/ブラウザなどの調べかたのまとめ][link-3]
>[JavaScriptでUserAgentを使った判別をする][link-1]
>[OS、ブラウザごとのCSSハックなどまとめ][link-2]

[strstr]:http://php.net/manual/ja/function.strstr.php
[server]:http://php.net/manual/ja/reserved.variables.server.php
[IEandEDGE]:https://msdn.microsoft.com/ja-jp/library/hh869301(v=vs.85).aspx
[link-1]:http://cly7796.net/wp/javascript/make-a-determination-using-the-useragent-in-javascript/
[link-2]:https://qiita.com/katsunory/items/0cbb26bf23d961161642
[link-3]:https://qiita.com/nightyknite/items/b2590a69f2e0135756dc
RocketchatでLDAP認証する

#目的
Rocketchat 0.59 で、LDAP認証するときにハマッたのでメモ。

###環境
 - Rocketchat 0.59
 - Windows Server2012(Active Directory) または OpenLDAP

#気をつけること
ADの情報として**mail**項目の設定が必須です。
抜けていると、Rocketchatの管理画面では接続OKでも、
実際にログインしようとしたときにエラーになります。
（エラーはサーバーログに出力されます）

#手順
- 本家

https://rocket.chat/docs/administrator-guides/authentication/ldap
（ActiveDirectory向けの記載です）

- 簡易

1. Rocketchatの管理メニューより「LDAP」を開く
2. LDAP接続情報を記入
3. 「Authentication」タブを開き、閲覧可能なユーザー情報を記入
4. 「Sync/Import」タブを開き、取り込む情報のフィールド名を編集
heroku 初心者がRailsアプリケーションの公開で躓く原因はDBにあった

# はじめに
「herokuは簡単にアプリケーションを公開できる！」
と聞いていたんですが少しハマったので共有します。
簡易的なものですが:pray:

※最低限の設定しかしていません

# 基本的には2ステップで公開できる？
以下の2ステップです。

```
$ heroku create
$ git push heroku master
```
まあしかしそんな甘くはなかったです。
ローカルで普通に動くからってこの2ステップだけで動くわけない...
当たり前なんだよなあ...



# ソースの変更点

```ruby:config/application.rb
config.assets.initialize_on_precompile = false
```

```ruby:Gemfile
gem 'pg'
```

```yml:database.yml
adapter: postgresql
encoding: unicode
url: <%= ENV['DATABASE_URL'] %>
```

＿人人人人人人人人人人人人人人人人人人人人人＿
＞　herokuではpostgresを使う必要があります　＜
￣Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y￣

# SQLを起動するのを忘れない

```
$ heroku addons:add heroku-postgresql
```

# まとめ

つまり、ソースを3箇所変更して以下の4ステップで完了します。


```
$ heroku create
$ git push heroku master
$ heroku addons:add heroku-postgresql
$ heroku run rake db:migrate
```
Gitlab-ceをVer10台にあげたら「502-Whoops, GitLab is taking too much time to respond」が出て困った

#GitlabをVer9系列からVer10系列にyumでアップデートしたら「502-Whoops, GitLab is taking too much time to respond」と出て先に進まないよ、助けてと言われたので調査してみました

##前提
- OSはRedHat7.4
- Gitlab-ceはyumでインストール
- ドキュメント類は読まないと豪語された　_:(´ཀ`」 ∠):
  - 何もやっていません　： やってないとなりません(๑╹ω╹๑ ) 
  - ちゃんとメッセージ出すべきだ :  Webサイトに書いてるよ(☝︎ ՞ਊ ՞)☝︎

#まずは状況確認
※sudo もしくは　rootになって作業

- Gitlabの各プロセス動作状況確認

  ```
   gitlab-ctl status
  ```
　　　<font color="DeepPink">Postgresql</font>がダウンしているとのこと


- 各プロセスのログを確認

  ```
   gitlab-ctl tail
  ```

  <font color="Blue">postgresql.confとruntime.confにエラーがあるとのご報告</font>

- confの中身を見てみる

別にエラーではないと思われる。
再度postgresqlのみ再起動してみると<font color="Red">socketがつくれねぇぇぇ</font>とのたまわれて死亡

gitlabのWebサイトを漁るとGitlab10.0以降はpostgresql9.2系はサポートしないよとの情報発見
これかなと思ってgitlab embededのpostgresqlバージョンを確認すると9.6系列....
しかも9.2のpostgresは残ってない(T ^ T)

- 一旦confのエラー行をコメントアウトしてみる

その後、postgresを起動してみると

```
DETAIL:  The data directory was initialized by PostgreSQL version 9.2, which is not compatible with this version 9.6.5.
```

やっぱり、これでした

#復旧作業（別の名を正しいアップデート手順）

1. yumで9系列のgitlab-ceのバージョンダウン
2. postgresqlを9.2系から9.6系にバージョンアップ
3. 10系列のgitlab-ceにバージョンアップ

## 1. yumで9系列のgitlab-ceのバージョンダウン

yumでインストール可能なバージョン全て表示するには<b>--showduplicates</b>オプションを利用
```
yum list --showduplicates |grep gitlab
```

gitlab-ce.x86_64 <font color="red">9.5.10-ce.0.el7</font> gitlab_gitlab-ceが9系列最後の模様
よってこれをインストールすることでバージョンダウン

```
yum install gitlab-ce-9.5.10-ce.0.el7
```

postgresqlは何が入ってるかなぁと見てみると9.2系と9.6系両方準備されている！！素晴らしい

## 2. postgresqlを9.2系から9.6系にバージョンアップ
- gitlabの各サービスを停止

```
gitlab-ctl stop
```

- gitlabのpostgresをアップデート

```
gitlab-ctl pg-upgrade
```

- gitlabが正しく起動するか確認

```
gitlab-ctl start
```

元気にpostgresqlが動いている事を確認して、gitlabのwebにアクセス。ログインしデータも残っていることを確認

## 3. 10系列のgitlab-ceにバージョンアップ

```
yum update
```

```
gitlab preinstall: 
gitlab preinstall: Backup failed! If you want to skip this backup, run the following command and
gitlab preinstall: try again:
gitlab preinstall: 
gitlab preinstall:   sudo touch /etc/gitlab/skip-auto-migrations
gitlab preinstall: 
```
こういうエラーが出る場合は表示されてるとおり
```
sudo touch /etc/gitlab/skip-auto-migrations
```
した後に
```
yum update
```
でOKです。終わったら/etc/gitlab/skip-auto-migrationsは消しておきましょう

上手くいって良かった(๑╹ω╹๑ )
困る方は、そんなに居ないと思いますがご参考まで

#参照情報
- [GitLab 10.0 Released with Auto DevOps and Group Issue Boards](https://about.gitlab.com/2017/09/22/gitlab-10-0-released/#postgresql-9.2-support)
JavaScriptでxrangeを実装する

iterator/generator周りの復習がてら，Pythonでいう xrange を実装してみました．

```js
> for (let i of xrange(10)) console.log(i)
0
1
2
3
4
5
6
7
8
9
undefined
```

単に渡された引数長の配列を生成するのではなく，遅延評価を行っています．

## iteratorでxrange

```js
export default max => {
  let i = 0;
  const next = () => {
    i++;
    return {
      done: i == max,
      value: i
    };
  };
  return { [Symbol.iterator]: () => ({next}) };
};

```



## generatorでxrange

```js
export default function* (max) {
  for(let i = 0; i < max; i++) {
    yield i;
  }
};
```

なお，アロー関数をジェネレータとして利用することは出来ません．