OmniAICreator/Qiita-1.07M huggingface dataset:
【ゲリラアドカレ】UE4ゲーム実装　進捗報告 3日目(クエスト画面作り)

【非公式】某会社設立記念ゲリラ Advent Calendar 2016 5日目の記事です。

FlashゲームをUE4で再実装するゲリラアドカレです。

クエスト画面を作り始めたので、進捗をアップします。
今回はアセット配置です。

・注意
許可を取ってないので通常業務の空いた時間を利用して作成するため、作成中のゲーム、及びアドカレは完成保証がなければ、ゲーム自体もリリースされる保証も皆無なので、あんまり期待しないでください。

#クエスト画面を作る
いよいよクエスト画面を作ります。
まずオリジナルのクエスト画面です。クリックすれば先に進む、ソーシャルゲームでよく見かける単純なぽちぽちタイプです。
![クエスト１.png](https://qiita-image-store.s3.amazonaws.com/0/104377/969dcdb0-de9d-3349-b615-d64d9d652b35.png)

![クエスト2.png](https://qiita-image-store.s3.amazonaws.com/0/104377/32fc4838-316e-93f6-35ad-d8376fa06e46.png)


出来れば某迷宮のような形式にしたいのですが、素材と時間がないためポチポチ形式で実装していきます。
ただ、プロトタイプを作るにはどきどきゲージ、新密度など色々と不要な要素があるのでとりあえず取っ払ったバージョンを作ります。

#デザイン作成

では早速画面を作っていきます。
まず新規にレベルを作ります。

![レベル作成.png](https://qiita-image-store.s3.amazonaws.com/0/104377/4ba86c7e-21e0-9d7d-6967-30e50e5302ea.png)

レベルを作成したら開いて、素材を配置していきます。
![エディタ.png](https://qiita-image-store.s3.amazonaws.com/0/104377/f3c66d1b-43b9-f7ae-6ab2-567f4f05ae5b.png)

とりあえず最低限のものを配置したので、先に進むUIを作ります。
![UI作成.png](https://qiita-image-store.s3.amazonaws.com/0/104377/d515a0f1-e0bc-687f-8b70-36db14c62510.png)

ボタンを押せば先に進んでエンカウント判定の上、バトルへ進むみたいな感じで実装する予定です。
赤いボタンは別のフィールドへ進むためのボタンになります。

こちらは単純にUIを表示するだけなので、先に実装しました。
![UI追加2.png](https://qiita-image-store.s3.amazonaws.com/0/104377/21ce4db9-fb88-1b1d-91a2-7731cf7d5e23.png)

赤いボタンを押すとクエスト選択画面が開きます。
![成果2.png](https://qiita-image-store.s3.amazonaws.com/0/104377/abf3b02a-c78d-6226-d8de-eb9faba982ae.png)

最後にレベルブループリントにUIを表示するようにして終わりです。
![UI追加.png](https://qiita-image-store.s3.amazonaws.com/0/104377/45a4bf7f-b495-51d5-cb79-b6ee3aa1fb01.png)

#とりあえずデザイン完成

![成果.png](https://qiita-image-store.s3.amazonaws.com/0/104377/4c501e7c-2af4-59e1-c435-692e7b01b635.png)

とりあえず仮のデザインが完成しました。
次は先に進んだように見える演出を実装していきたいと思います。

先は長そうです……。
【HTML入門】スペース(空白)を表示させる3つの方法

※こちらの記事は、プロスタ編集部が学習者の多いHTMLの文法記事を公開することで、皆様の学習にお役に立ちたい意図で投稿しております。
参考サイト：[【HTML入門】スペース(空白)を表示させる3つの方法](http://programming-study.com/technology/html-space/)

#【HTML入門】スペース(空白)を表示させる3つの方法

HTML上で空白や改行を入力したのに、思った通りにブラウザで表示されなかったことはありませんか。
例えば、

```
<html>
  <head>
    <title>プロスタ</title>
  </head>
  <body>
  プロスタは         
  プログラミング初心者が         自分に合った勉強法を見つけられるサイト   です。
  </body>
</html>
```

「プロスタはプログラミング初心者が自分に合った勉強法を見つけられるサイトです。」という文章を以上のようにHTML上に入力しても、下記のように表示されます。

>プロスタは プログラミング初心者が 自分に合った勉強法を見つけられるサイト です。

ブログ等とは異なり、HTML上に半角スペースや改行をいくら入力しても、ブラウザ上では空白が一つ分に詰められて表示されます。今回は、HTML上でスペースを詰めずに連続したスペースを空ける方法をご紹介します。

目次 
1 [特殊文字を用いた方法](##特殊文字を用いた方法)
2 [preタグを使う方法](##preタグを使う方法)
3 [全角スペース](##全角スペース)

##特殊文字を用いた方法

連続でスペースを表示させる最も一般的なやり方が特殊文字を用いた方法です。半角スペースを連続で表示するには、「&nbsp;」という特殊文字を使います。特殊文字とは、HTMLに記述してもブラウザで直接表示することが出来ない文字や記号のことです。例えば、HTML上でpタグと表示したい時は、<p>と記述するとタグと解釈されてしまい上手く表示できないので、<を表す「&lt;」と>を表す「&gt;」を使って、「&lt;p&gt; 」と記述する必要があります。

HTML上の表示

```
<html>
  <head>
    <title>プロスタ</title>
  </head>
  <body>
  プロスタは&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;プログラミング初心者が自分に合った勉強法を見つけられるサイトです。
  </body>
</html>
```
ブラウザ上の表示

>プロスタは        プログラミング初心者が自分に合った勉強法を見つけられるサイトです。

&nbsp;の他にも空白を表す特殊文字があります。
・&nbsp;　通常の半角スペースと同じサイズの空白です。
・&ensp;　半角スペースより少し広めの空白です。
・&emsp;　半角スペースよりさらに広めの空白です。全角スペースとほぼ同じ幅です。
・&thinsp;　&nbsp;より狭い空白です。

##preタグを使う方法

preタグを使えば、HTMLに記述された半角スペースや改行などをブラウザにそのまま表示することができます。

HMTL上の表示

```
<html>
  <head>
    <title>プロスタ</title>
  </head>
  <body>
  <pre>
  プロスタは     プログラミング初心者が自分に合った勉強法を見つけられる      サイトです。</pre>
  </body>
</html>
```

ブラウザ上の表示

>プロスタは　　　プログラミング初心者が自分に合った勉強法を見つけられる　　　　サイトです。

##全角スペース
半角スペースではなく、全角スペースを使って連続してスペースを空ける方法があります。日本語入力に切り替えた後、スペースキーを入力すれば、入力回数分だけそのまま空白が表示されます。

HTML上の表示

```
<html>
  <head>
    <title>プロスタ</title>
  </head>
  <body>
  プロスタは　　　プログラミング初心者が　　　　自分に合った勉強法を見つけられるサイトです。
  </body>
</html>
```

ブラウザ上の表示

>プロスタは　　　プログラミング初心者が　　　　自分に合った勉強法を見つけられるサイトです。

いかがでしたか。今回は、①特殊文字②preタグ③全角スペースを使って連続でスペースを表示させる方法をご紹介しました。ぜひ、実際に記述してみてスペースを表示できるか確かめてみてください。
Node.jsで理解する、Ruby開発環境入門

Rubyの環境構築といえば...その昔Railsの入門サイトみたいなやつで、どう動くかも分からずただ書いてあるままにポチポチとコマンドを実行して構築した覚えがあります。

結局、なんだかよく分からなくなって「Ruby on RailsはサルでもWebアプリが作れると聞いたが、ぼくはサルより下だった。」と放り投げた記憶があります。

ときは流れ、私はRubyのRの字にも触れることなく`Node.js / npm`の文化で育ちました。

そうした中、何やらRubyを触らないといけないことになりまして、次こそはちゃんと理解して環境を構築しようという気持ちになりました。

以下、`Node.js/npm`で理解するRubyの環境構築です。

# 前提
- `Node.js / npm`についての知識がある
- `Node.js / npm`の知識でRubyを理解したい
- Rubyのバージョン管理は`rbenv`、Node.jsのバージョン管理は`nodebrew`ということで進める

# Node.jsで置き換えてみる

## rbenvとは
どの言語にも存在する、手軽にバージョンを切り替えるやつです。
Node.jsで言うところの`nodebrew`です。

## ruby-build
いきなりですが、これは該当するコマンドが無いです。
強いていうと、Node.jsで言うところの`nodebrew install`に該当します。
`rbenv install`は`ruby-build`無しでは動かないということのようです。

## gem
だいたいの言語に存在する、パッケージを管理する便利なやつです。
Node.jsで言うところの`npm`です。

### gem installの落とし穴
Node.jsしか知らない人からすると、落とし穴なのが`gem install`はグローバルにインストールされるというところです。
つまり、`gem install hoge`すると、`npm install hoge -g`みたいな動作をするということです。

「マジかよ。全てグローバルとか正気かよ。」と思ってしまいます。

## bundler
上で書いた、`gem install`の落とし穴をなんとかするのがbundlerです。
`bundle install`という感じで使います。
Node.jsで言うところの、`npm install`(`-g`が付かない)です。

### node_modules = vendor/bundle
Web上でbundlerについての文献を見ていると、以下のような表記を見かけます。

```
bundle install --path vendor/bundle
```

これは、インストールしたパッケージの実体は`vendor/bundle`に入れてねということです。
そう、Node.jsで言うところの`node_modules`です。

## Gemfile
パッケージの依存関係が書いてあるやつです。(これは環境構築とは関係ないけど)
Node.jsで言うところの`package.json`の`dependencies`とか`devDependencies`に当たります。

# まとめ
| Ruby / gem | Node.js / npm |
|:---|:---|
| `rbenv` | `nodebrew` |
| `rbenv install (with ruby-build)` | `nodebrew install` |
| `gem` | `npm` |
| `gem install ` | `npm install -g` |
| `bundle install ` | `npm install` |
| `bundle exec ` | `npm run` |
| `Gemfile` | `package.json` |
| `Gemfile.lock` | `npm-shrinkwrap.json` |


# あとがき
こうして見てみると、大したことないですね。
ややこしいのは、「`gem`コマンドでインストールするとグローバルに入っちゃうから、`bundler`を使おうね」というところだと思います。
偏差値が低いので、道具が増えると頭が追いつかないです。つらい。

Ruby周辺の知識に関してはまだまだ理解が浅いです。
何か間違い等ありましたら、編集リクエストかコメントを頂けますとありがたいです。
Multidex サポートと minSdkVersion の関係

Multidex について細かい説明はしませんので [Android Developer を参照](https://developer.android.com/studio/build/multidex.html)のこと。日本語版は内容がちょっと古いので英語版を読んでください。

Multidex についてググると、上記説明をもとに書かれたと思わしき記事がたくさんヒットしますが、minSdkVersion との関係について書かれている記事があまり見られません。しかし、自分がとある問題にピンポイントでハマったので、そのへんを記録として残しておきます。

説明では、minSdkVersion が 20 以下の時は下記を指定せよと書いてあるのですが、

```groovy:build.gradle
dependencies {
  compile 'com.android.support:multidex:1.0.1'
}
```

実は最近の Android Gradle Plugin では、この依存関係を勝手に解決してしまいます。

[VariantManager.java](https://android.googlesource.com/platform/tools/base/+/android-7.1.1_r4/build-system/gradle-core/src/main/groovy/com/android/build/gradle/internal/VariantManager.java)

```VariantManager.java
public class VariantManager implements VariantModel {
    protected static final String COM_ANDROID_SUPPORT_MULTIDEX =
            "com.android.support:multidex:1.0.1";
//
// 中略
//

if (variantConfig.isMultiDexEnabled() && variantConfig.isLegacyMultiDexMode()) {
           project.getDependencies().add(
                   variantDep.getCompileConfiguration().getName(), COM_ANDROID_SUPPORT_MULTIDEX);
           project.getDependencies().add(
                   variantDep.getPackageConfiguration().getName(), COM_ANDROID_SUPPORT_MULTIDEX);
}
```

isLegacyMultiDexMode() とは何ぞや？と調べると

```VariantConfigration.java
public boolean isLegacyMultiDexMode() {
    return isMultiDexEnabled() && getMinSdkVersion().getApiLevel() < 21;
}
```

となっていました。つまり、minSdkVersion が 20 以下の時に、multiDexEnabled true とすると、com.android.support:multidex:1.0.1 の依存関係が勝手に解決される、ということです。
Windows 10でDHCPクライアントが正常動作せず『インターネットなし』になった時の対処方法

原因がよくわからんがとりあえず対処方法はわかったので書いておく。

2016-12-16追記: [KB3206632](https://support.microsoft.com/en-us/help/4004227/windows-10-update-kb3206632)をインストールすると直り、この問題は発生しないと思われる(確証はない)。この修正はWindows Updateで自動更新対象になっている。既に問題が発生してネットワーク接続が切れてたらそれも無理だが…

* [MS、一部の「Windows 10」マシンでネット接続ができなくなる問題に対処 - ZDNet Japan](http://japan.zdnet.com/article/35093745/)
* [一部の「Windows 10」でDHCPによるIPアドレス取得ができなくなる不具合 | スラド IT](https://it.srad.jp/story/16/12/15/0913254/))

## 対処方法

順番に実行して、直らなかったら次へ。

1. `ネットワークのトラブルシューティング` を実行し、DHCPが無効になっているとの問題が検出されたら 自動修復 を実行
2. ネットワークアダプタの無効 → 有効
3. 再起動
4. シャットダウン→起動
5. 管理者権限で `netsh interface ip reset c:\reset.log` 実行 → OS再起動
6. `ネットワークのトラブルシューティング` を実行し、DHCPが無効になっているとの問題が検出されたら `自動修復` を実行

5がミソですね。

## 背景

弊社の業務用PCはほぼすべてWindows 10 Pro 64bitなのだが、ここ数日で「インターネットに繋がらない」と言われることが数件あった。特定のネットワークアダプタやドライバで発生しているわけではなく、Wi-Fiでも有線接続でも発生している。DHCPでIPアドレスを取りに来ない(パケットが飛んで来ない)し、IPアドレスが不足しているわけでもないのでサーバ側の問題ではないらしい。

詳しい方、コメントなどで教えていただけると嬉しいです。

## 感想

Windowsむずかしい。
innobackupexについてざっくり

[マイネットエンターテイメント Advent Calendar](http://qiita.com/advent-calendar/2016/mynet)8日目の記事です。

主にiOS, AndroidやUnityなどを担当していますが、かくかくしかじかで２サーバ間のDB移行を実施することがありました。
そこで今回はDB移行ツールでお世話になったinnobackupex(xtrabackup)についてお話します。

# DBのバックアップについて
DB移行方法として、mysqldumpを利用することが考えられます。
mysqldumpでバックアップ作成を行うとなると事前確認として、DBをロックした後、logのポジションを確認し、dumpファイルを吐き出し....。そして移行先のDBでリストアを実行するとどえらい時間がかかる...なんてこともあります。急いでる身としては操作ミスするかもしれないし、そんな悠長に待ってられないヨ〜というセッカチな方は、以下に記すinnobackupexを利用すると救われることがあるかもしれません。
ここでは以下の手順について記していきます。

- 移行元DBサーバよりフルバックアップ作成
- 移行元DBサーバから移行先DBサーバへバックアップデータをコピー
- 移行先DBサーバにてリストア

# innboackupexとは
これはxtrabackupのperlラッパースクリプトで、バイナリタイプのバックアップツールです。
mysqldumpとは違い、ざっくり言うとdatadir`/var/lib/mysql`以下のデータをいい感じでバックアップデータを作成・リストアしてくれるツールです。

## インストール
ここではRHEL系のインストール方法を記します。

```:RHEL5
$ wget http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm
$ rpm -ivH percona-release-0.1-3.noarch.rpm
```

```:RHEL6
$ yum install http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm
```

以下共通です。

```
yum list | grep percona
yum install percona-xtrabackup-24
```

# 実作業
## バックアップ作成 & 移動
移行元サーバにてバックアップ作成と、移行先への移動を一気に行います。[^1]　[^2]

```:移行元サーバ
# time innobackupex --user=<mysqluser> --stream=xbstream --compress --no-timestamp /tmp/backup \
| ssh user@otherhost "xbstream -x -C /path/to/backupdir/"
```

## 解凍
qpressが必要になりますので、未インストールである場合は導入してください。

```:移行先サーバ
# yum install -y qpress
# time innobackupex --decompress /path/to/backupdir
```

## ログ適用
Write Ahead Logを適用します。

```:移行先サーバ
# time innobackupex --apply-log /path/to/backupdir
```
これにてバックアップ先のディレクトリ内に`xtrabackup_binlog_info`が作成されます。
スレーブ設定する場合はログポジションにこれを利用してください。

## データ移行
以下の操作は、**前もってmysqlを停止しておいてください**
事前に移行先サーバのdatadir内を一度削除するか、バックアップをとります。

```:移行先サーバ
# cp -R /var/lib/mysql /path/to/mysql_backupdir
or
# rm -rf /var/lib/mysql/*
```

以下のコマンドを実行することで、datadirに対してバックアップデータのコピーが行われます。

```:移行先サーバ
# time innobackupex --copy-back /path/to/backupdir
```

## 移行完了後の作業
copy-backupが完了したのち、datadirの所有権を修正します。

```:移行先サーバ
# chown -R mysql: /var/lib/mysql
```

以上で完了です。mysqldを起動し、DB移行が完了しているか確認してみましょう。

# まとめ
以上の説明はかなりざっくりしたものになります。innobackupexを用いたバックアップ手法は幾つか方法もありますし、現在では外部mysqlからAWSのAuroraへ移すのにもinnobackupexの利用が推奨されています。(DMSでも良いと思います)
ニーズに合わせて適切な利用を心がけるといいと思います。

# 参考

- [The innobackupex Script](https://www.percona.com/doc/percona-xtrabackup/2.1/innobackupex/innobackupex_script.html)
- [外部の MySQL データベースから Amazon Aurora DB クラスターへのデータ移行](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Aurora.Migrate.MySQL.html)


[^1]: 移行先サーバにてinnobackupexの導入が完了していることが前提です。
[^2]: なんやかんやで時間がかかるので、バックグランドか、screen上で実行するのが吉です。
Ajaxのページネーション「もっと見る」がブラウザバックで勝手に閉じる問題

# 概要
表題の件でイライラしていたのですが、HistoryAPIで無理やり解決しました。
が、結論から言うとこのやり方はオススメしません！笑
Amazonに倣って、
「もっと見る」よりも、素直に「次のページ」を表示しましょう。

# 問題
1. ajax実装された「もっと見る」を押して、リスト末尾に20件とか追加される。
2. リストからアイテムを選び、アイテム詳細ページに遷移。
3. ブラウザバックする。
4. DOMの状態が初期化されているので、末尾に追加された20件は消えている。
→もっと奥にあるアイテムを見るには、また「もっと見る」を押さないといけない。

**イライラする！！**

# 解決方法
1. 詳細ページに遷移するタイミングで、現在開かれているページ数をURLに追加し(?page_num=2)として、HistoryAPIで履歴に追加もしくは書き換え。
2. 「戻る」を押すと「hogehoge.com/items?page_num=2」が開かれるので、(page_numの値x20)件を初期表示。
3. 併せて「もっと見る」押下時に追加されるリストのoffsetを(page_numの値x20+1)に変更する。

# 結論
ゴリ押しですが、ブラウザバック時のイライラは無くなります。

が！！
ここで無理やり頑張るぐらいなら、
「もっと見る」では無く「次のページ」を表示して、AjaxでDOMとブラウザ履歴を書き換えてしまえば良さそう。
AmazonのUIが実装しやすそうで、かつユーザーとしても快適。
Google URL Shortener をJavaScript (Webページ) で使用する

[Google APIs Client Library for JavaScript](http://code.google.com/p/google-api-javascript-client/)を使うと、ブラウザだけで goo.gl の短縮URLを作成できます。

## 準備

1. [Google APIs ダッシュボード](https://console.developers.google.com/apis/dashboard)でプロジェクトを作成する。または既存プロジェクトを選択する。
2. 左のメニューから**ライブラリ**を選択して、検索欄に**url**等と入れると**URL Shortener API**が見つかるので選択する。
3. 上部の**有効にする**を選択する。
4. 左のメニューから**認証情報**を選択して、**認証情報を作成**→**APIキー**と選択してAPIキーを作成する。

Firebaseで作成したプロジェクトを使うこともできます。

## 実装

まずGoogle APIs Clientを読み込みます。HTML内に`<script src="https://apis.google.com/js/api.js"></script>`を書けばOKです。

```html
<html>

<head>
  <!-- Google APIs Client -->
  <script src="https://apis.google.com/js/api.js"></script>
</head>

<body>
  <h1>Hello World</h1>
</body>

</html>
```

次に、このライブラリを使って短縮URLを生成する関数を作成します。`url-shortener.js`というファイルを作成して、以下のコードを記述します。

```js:url-shortener.js
function shorten(url) {
  return new Promise((resolve, reject) => {
    gapi.load('client', _ => {
      gapi.client.init({
        'apiKey': 'YOUR_API_KEY',
        'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/urlshortener/v1/rest'],
      })
        .then(_ => gapi.client.urlshortener.url.insert({
          longUrl: url
        }))
        .then(resolve, reject)
    });
  });
}
```

`YOUT_API_KEY`は、**先程作成したAPIキーに置き換えてください。**

そしてこれを先程のGoogle APIs Clientの読み込みの後に加えます。

```html
<html>

<head>
  <!-- Google APIs Client -->
  <script src="https://apis.google.com/js/api.js"></script>
  <!-- shorten 関数 -->
  <script src="url-shortener.js"></script>
</head>

<body>
  <h1>Hello World</h1>
</body>

</html>
```

あとは、`shorten(url)`関数を呼べば、短縮URLのレスポンスが`Promise`オブジェクトで取得できます。

```html
<html>

<head>
  <!-- Google APIs Client -->
  <script src="https://apis.google.com/js/api.js"></script>
  <!-- shorten 関数 -->
  <script src="url-shortener.js"></script>
</head>

<body>
  <h1>Hello World</h1>
  <div id="shortUrlOutput"></div>

  <script>
    // 短縮URLを取得する
    shorten('http://www.eje-c.com')
      .then(function(response) {
        // response.result.id に短縮URLが入っている
        var shortUrl = response.result.id;
        // 画面に表示
        document.getElementById('shortUrlOutput').innerHTML = shortUrl;
      });
  </script>
</body>

</html>
```
MacのCHROMEのキャッシュを1秒でクリアする方法

`⌘` + `shift` + `R` 

このショートカットでキャッシュをクリアしてのリロードになります。

2016年12月くらいからChromeのキャッシュが強くなり、困っていたのでこれで対処しています。
FirebaseAuth GoogleでSigninする時、毎回アカウント選択の画面を出したい。#Android #firebase

Firebase AuthのGoogle認証で初めてサインインする時は、どのGoogleアカウントを使用するか、Googleアカウントを選択できるダイアログが出てくるのですが、1度サインアウトしてもう一度サインインしようとすると、前回サインインをしたGoogleアカウントで自動的にサインインが実行されてしまいます。複数のGoogleアカウントを所持している人にとっては不便です。何よりテストアカウントを選べないのが痛い。

#毎回どのアカウントを使うか選択したい！
解決方法はAuth.GoogleSignInApi.signOut()を実行するだけです。

```java:MainActivity.java
//この1行だけだと、次回以降に選択画面が出ない
mFirebaseAuth.signOut(); 

//Auth.GoogleSignInApi.signOutも呼び完全にサインアウトします
if (mGoogleApiClient.isConnected()){
    Auth.GoogleSignInApi.signOut(mGoogleApiClient);
}
```

GoogleApiClientのインスタンスが必要なので、onCreate()あたりで生成しておくことをオススメします。

```java:MainActivity.java

 private GoogleApiClient mGoogleApiClient;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);

     GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
        .requestIdToken(getString(R.string.default_web_client_id))
        .requestEmail()
        .build();

     mGoogleApiClient = new GoogleApiClient.Builder(this)
        .enableAutoManage(this, new GoogleApiClient.OnConnectionFailedListener() {
                    @Override
                    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

                    }
                })
     .addApi(Auth.GOOGLE_SIGN_IN_API, gso)
     .build();
 }
```
【Ruby入門】ファイルの書き込みと読み込み

※こちらの記事は、プロスタ編集部が学習者の多いRubyの文法記事を公開することで、皆様の学習にお役に立ちたい意図で投稿しております。

参考サイト：[【Ruby入門】ファイルの書き込みと読み込み](http://programming-study.com/technology/ruby-file/)

#【Ruby入門】ファイルの書き込みと読み込み

今回はファイルの書き込みと読み込みの方法をご紹介します。

目次 
1 [ファイルを開く](##ファイルを開く)
2 [ファイルに書き込む](##ファイルに書き込む)
3 [ファイルを読み込む](##ファイルを読み込む)

##ファイルを開く

Rubyでは、Fileクラスを使ってテキストファイルを読み込んだり、書き込んだりすることができます。そして、その前にまずファイルを開いてやる必要があります。ファイルを開く場合、以下のようなコードを書きます。

```	
File.open("ファイル名","モード")
```

※File.openは、単にopenと書いてもかまいません。

ファイル名の部分には、開きたいファイルの名前を拡張子つきで書きます。もちろん、rbファイルと開きたいファイルが違うディレクトリにある場合は「ディレクトリ/ファイル名」のように、置いてあるディレクトリを / で区切って指定する必要があります。

また、モードというのは、以下のようなものです。

r : 読み取りモード。readのrと覚えればよいでしょう。
w : 新規作成書き込みモード。writeのwと覚えればよいでしょう。ファイルの中に書いてあるテキストを消して、すべて新しく書き換えます。
a : 追加書き込みモード。今までファイルの中にあったテキストは消さず、その続きを追加していく形でテキストを挿入します。appendのaと覚えればよいでしょう。
r+ : 両用モード
w+ : 新規作成読み書き両用モード
a+ : 追記書き込み読み込み両用モード

つまり、+がつくと両用モードとなります。モードはとくに何の指定もなければ、デフォルトのrが自動選択されます。

##ファイルに書き込む

では、Fileクラスを使って、テキストファイルを作ってみましょう。ファイルの書き込みを行う場合は、以下のようにコードを書きます。

```
File.open("ファイル名","モード") do |変数|
変数.puts("本文")
変数.puts("本文")
end
```

※本文は何行作っても構いません。

これを使って、text_write_test.txtというファイルをrbファイルと同じディレクトリに作成する場合、以下のようにコードを書きます。


```
File.open("text_write_test.txt","w") do |text|
 text.puts("Hello!!")
 text.puts("How are you?")
end
```

このコードを書いたrbファイルを実行すると、同じディレクトリに「text_write_test.txt」というファイルが作成され、その中身には以下のような文章が書いてあります。

>Hello!!
How are you?

##ファイルを読み込む

rbファイルを実行したときにテキストファイルを読み込んで、書いてあるテキストを表示する場合、以下のようにコードを書きます。

```
file = File.open("ファイル名","モード")
file.each do |変数|
 puts 変数
end
file.close
```

指定したファイルから読み込んだ文字列を、eachメソッドを使って変数の中にいれてから表示するという仕組みになっています。

text_open_test.txtというファイルを読み込んで表示させるというプログラムを書く場合、以下のように書きます。あらかじめtext_open_test.txtというファイルを作り、中身に何か文字列を書いておきましょう。

```
file = File.open("text_open_test.txt","r")
file.each do |text|
 puts text
end
file.close
```

このプログラムをテキストファイルと同じディレクトリに保存して実行すると、text_open_test.txtに書かれている文字列が表示されます。

ここでは表示させるだけでしたが、Fileクラスはputsで表示させる意外にも、ファイルについての情報を取得したりなど、さまざまな使い道があります。
細かすぎて伝わらないCLionのいいところ

CLionを業務で1年程使ってみて個人的に気に入った渋いニッチな機能をメモします。有益な情報が得られないかもしれないという覚悟の上で御覧ください。また、「他のIDEでも～」等の宗教論争はする気はないので悪しからず。

## CLionとはなんぞや
CLionとはIntelliJ IDEAやWebStrom等でおなじみのJetBrainsのC/C++向けのIDE製品です。半分以上興味本位、趣味でライセンスを購入し1年ほど業務で使用しています。あまり使っている方の情報を見かけないので、そんなに盛り上がっていないのかな？同社にはVisualStudioをパワーアップするReSharper/ReSharper C++というプラグイン製品もありますが、そちらは使ったことがないので私には比較できません。

## 使用環境
 - CLion 2016.3.1
 - Windows7 64bit

## 【その１】Semantic highlighting
関数内の引数やローカル変数をそれぞれユニークな色でハイライトする機能です。人のコードや過去の自分と向き合う時に使ってます。結構カラフルになってチカチカするので、コードを書く時はOFFったりします。
[詳細はここに](https://blog.jetbrains.com/clion/2016/09/clion-opens-2016-3-eap/#semantic_highlighting)。

WebStorm 2016.3 でも確認してみましたが、WebStormでも使えるようです。

## 【その２】リガチャ（合字）フォント標準装備
最近のJetBrains社のIDEには[Fira Code](https://github.com/tonsky/FiraCode)がバンドルされています。フォントなので好みが別れるところですね。個人的には!=の合字が素晴らしいと思っています。ちなみに[Fira Code](https://github.com/tonsky/FiraCode)は自分でインストールすれば他のフォントリガチャに対応しているアプリケーションでも使えます。

CLion等で使用する場合は、[Editor]->[Colors & Fonts]->[Font]のEnable font ligaturesのチェックを入れるのを忘れずに。

## 【その３】Doxygenのタグを補完してくれる
@noteとか@typedefなどのDoxygen用のタグもコードアシストが働きます。

## 【その４】組み込みのVCSクライアント機能のデキが結構いい
普段Gitを使っていますがツリーも綺麗に表示されるし、Diffも見る事ができます。普段よく使うような操作はそのままIDEから行なえます。流石に細かい事はコンソールから行っていますが、正直SourceTreeは起動しなくなりました。

## 続く…かも
また何か見つけたら追記するかもしれません。
IoTグラウンドプラットフォーム

世界中のあらゆるデバイスがネットワークでいつでも繋がることで、様々な価値を生むことが期待されています。センサーデバイスより得られた様々なな情報を蓄積・分析することで、より精度の高いノウハウを構築することができ、さらに快適で安全な生活と、作業効率の見える化が実現します。株式会社日昇テクノロジーのIoTは、中国国内のみならず、日本でのワンストップソリューションをスームレスにご提供いたします。 
![ind_gpc_1b.jpg](https://qiita-image-store.s3.amazonaws.com/0/153266/973b3eb2-01bd-e11f-fb11-ec05ab6f796c.jpeg)
特徴：
1.弊社は開発したゲートウェイを通じてクラウドサーバに転送します。
![图层-6.png](https://qiita-image-store.s3.amazonaws.com/0/153266/44e60349-81d0-bcf1-95cc-5c26faab5607.png)
２.デバイス構成、センサーの測定値、イベントやアラームなどあらゆる情報を保存します。
![图层-8.png](https://qiita-image-store.s3.amazonaws.com/0/153266/f6f29a03-bdac-67d0-c79f-79d7e151fd42.png)
3.様々なデータ価値を活用してアプリを開発します。
![图层-5.png](https://qiita-image-store.s3.amazonaws.com/0/153266/7642b4cb-65fa-049c-1ac2-5808bdc7fe18.png)
使用事例：
![cont06_01.gif](https://qiita-image-store.s3.amazonaws.com/0/153266/86b22ddb-3c87-84af-49f1-d8db6d0c62f2.gif)![cont06_02.gif](https://qiita-image-store.s3.amazonaws.com/0/153266/e87034a2-78a1-e305-e47a-6932d8e162fe.gif)
![cont06_03.gif](https://qiita-image-store.s3.amazonaws.com/0/153266/5f50bc2f-f29c-f04f-ae13-c82d11cf6fd3.gif)![cont06_04.gif](https://qiita-image-store.s3.amazonaws.com/0/153266/c38f9068-8583-69c2-4dcc-e539c20160ca.gif)
rubyで大きな配列をハッシュに変換する時のスタックの枯渇に注意


fiberを使ったrubyプログラムでfiberに割り当てられたスタック領域を使い切ってプロセスが死ぬという問題が起こりました。

落ちた原因を調査していると、以下のようなコードが原因であることが分かりました。

```ruby
big_array = [[:hoge 'fuga'], [:foo, 'bar'], ...] # 巨大な配列
Hash[*big_array.flatten]
```

`Hash.[]`に引数として渡している配列が大きすぎるために、スタックを使い切ってしまっていたようです。

こちらの資料によると、スタックサイズは数十〜数百KBなので、それ以上のサイズの配列を引数に渡すとスタックが枯渇します。
http://www.atdot.net/~ko1/diary/edit_comment.cgi?mode=edit&year=2012&month=12&day=21

ruby 2.1以降では`Array#to_h`が実装されているので、そちらを使いましょう。
Cakephp3でnewEntity時に子要素のバリデーションに引っかかってしまう

Cakephp3であるシステムの開発を行っているのですが、下記の状況で困っています。
どなたか詳しい方いらっしゃいましたらアドバイスいただけませんでしょうか

▼概要
記事データを入れるAirticleテーブルと、各記事に対するコメントを入れるCommentsテーブルの２つのテーブルがhasManyで連結されています。
記事とコメントを一度に保存しようとしてまとめてnewEntityをすると、comments.article_idのrequirePresence に引っかかってしまいます。

▼詳細

記事データのテーブル
src/Model/Table/ArticlesTable.php
で下記のようにhasManyを設定しています。

        $this->hasMany('Comments', [
            'foreignKey' => ['article_id', 'comment_id' ],  
        ]); 

また、記事データのプライマリキーのarticle_id は AutoIncrement になっています。

このAirticleテーブルとhasManyの対象のCommentsテーブルを一度にデータを保存するために
記事データのコントローラー
src/Controller/ArticlesController.php
で下記のようにnewEntityを実行しています。

        $article = $articleTable->newEntity(
            $data,
            ['associated' => [
                'Comments',
            ]]
        );

ここで渡している $data は下記のような値です。

        $data = array(
            'title' => '記事タイトル',
            'comments' => [
                [
                    'comment' => 'コメント内容',
                ],
             ],
        );

この時、newEntityの中でバリデーターが実行されると思うのですが、どうしてもCommentsのバリデーションに引っかかってしまいます。
引っかかるのは、下記のバリデーションです
src/Model/Table/CommentsTable.php

        $validator->requirePresence('article_id', true, '入力してください')

data[comments][0] に article_id が入っていませんので、そのためにフィールド未定義のエラーが出ているものと思いますが、そもそもarticle_idは親articleが生成されないと定義されませんので、$dataの時点でこれを含めることは不可能です。

このバリデーションを取り除いて実行してみると、article保存後に生成されたarticle_idが自動的にセットされて保存されているのでバリデーションをなくせば問題なく動くこともわかっています。

しかしそれだと、直接CommentsテーブルだけをnewEntityする時に requirePresence のチェックが無しになってしまいますので、これは避けたいところです。
この状況を回避する手段は何かありますでしょうか。

私の方では下記のようなことを検討してみました

- 親テーブルに含まれる形でnewEntityされる時と単体でnewEntityされる時とで、バリデーションを変更することができないか
- validationでrequirePresenceするのをやめて、Rule でrequirePresence をするべきか

しかし、あまりスマートな手段に思えず、うまい解決方法をご存知の方いらっしゃいましたらお教えいただければ幸いです。

お手数ですがよろしくお願い致します。
Jade / pug を使ってjsonからページ大量生成

EJS を使って json からページを生成するノウハウは見当たるのですが、
意外と Jade / pug で同じことをしようとすると手こずってしまったのでメモ。

やりたいことは、
1. １つのテンプレートをベースに使う
2. json に生成したいページの情報をまとめる
3. (1)と(2) から静的 HTML を量産する

です。

## 実装
gulp-jade を使っています。

```planData.json
[
  {
    "no": 1,
    "title": "北海道旅行",
    "text": "札幌、小樽、旭川のツアーはこちら"
  },
  {
    "no": 2,
    "title": "東北旅行",
    "text": "青森、秋田、岩手のツアーはこちら"
  },
  {
    "no": 3,
    "title": "関東旅行",
    "text": "群馬、栃木、茨城のツアーはこちら"
  }
]
```


``` task_jade.js
/**************************************************
 * modules load
 *************************************************/
const gulp   = require('gulp');
const fs     = require('fs');
const jade   = require('gulp-jade');
const data   = require('gulp-data');
const rename = require('gulp-rename');

/**************************************************
 * config
 *************************************************/
const template = './src/jade/planTemplate.jade';
const jsonPath = './src/json/planData.json';
const dest     = './dest/';

/**************************************************
 * task
 *************************************************/
gulp.task('jade', () => {
  const json = JSON.parse(fs.readFileSync(jsonPath));

  for (let key of json) {
    gulp.src(template)
        .pipe(rename(key.no + ".html"))
        .pipe(data (function (file){
          return {
            'fileName': file.path.split('/').pop().replace('.html', ''),
            'planList': json
          }
        }))
        .pipe(jade({
          pretty: true
        }))
        .pipe(gulp.dest(dest));
  }
});

```

```planTemplate.jade
block vars
  - function getNo(){
  -   for(var i = 0; i < planList.length; i++){
  -     if(planList[i].no === Number(fileName)){
  -       return i;
  -     }
  -   }
  - }
  - const i = getNo()

html
  head
    meta(charset="utf-8")
    title プラン#{planList[i].no} - #{planList[i].title}

  body
    h1 #{planList[i].title}
    p #{planList[i].text}

```

タスク内で、テンプレートから json のデータを取り出すための key を 変数に入れています。

問題なければ、下記のHTML ファイルが生成されるはずです。

```1.html
<head>
  <meta charset="utf-8"/>
  <title>プラン1 - 北海道旅行</title>
</head>
<body>
  <h1>北海道旅行</h1>
  <p>札幌、小樽、旭川のツアーはこちら</p>
</body>
```

```2.html
<head>
  <meta charset="utf-8"/>
  <title>プラン2 - 東北旅行</title>
</head>
<body>
  <h1>東北旅行</h1>
  <p>青森、秋田、岩手のツアーはこちら</p>
</body>
```

```3.html
<head>
  <meta charset="utf-8"/>
  <title>プラン3 - 関東旅行</title>
</head>
<body>
  <h1>関東旅行</h1>
  <p>群馬、栃木、茨城のツアーはこちら</p>
</body>
```
---
2017/01/12 追記:
pug でも同様に量産できます！
管理画面を作らないサービス運営

これは[VAddy Adventカレンダー](http://qiita.com/advent-calendar/2016/vaddy)8日目の記事です。
[VAddyは、継続的なWeb脆弱性検査が簡単に実現できるSaaSです。](https://vaddy.net/ja)

[昨日の記事で、BrewDog Jack Hammer IPAを紹介しました。](http://blog.ichikaway.com/entry/2016/12/06/102026)
知り合いのエンジニアから国内も！という声を頂いたので今日は国内ビールについて。
私が日本のクラフトビールで一番好きな醸造所は、[伊勢角屋麦酒](http://www.biyagura.jp/)で、ここのペールエールがあれば絶対に飲みます。伊勢角屋が好きな理由は、いつ飲んでも美味しく品質が安定していることと、自分の好みの味のビールが多いからでしょうか。
ビールフェスに行くとよく見かけるので是非飲んでみてください。限定でIPAなどもあるので機会があれば是非。

## 管理画面
VAddyでは管理画面を持っていません。チームの人数が少ないのもありますし、DBを直接操作するようなオペレーションも多くないからです。
エンジニア以外の人がサポートする時のユーザ情報や統計的なデータをみたいという要望もあるため、それらは参照できるようにしています。ただこれも管理画面は特に作っていません。DBにエンジニア以外が見るVIEWテーブルを作成して、参照してもらっています。

メリットは、管理画面がないため工数が少ないこと。参照したいデータが増えたり、統計処理を変更したいなどの要望の際にもVIEWテーブルの追加・変更のみのため非常にスピーディーに対応できます。
 
## アクセス方法
エンジニア以外の人もMacを使っているのでsshの鍵を作ってもらい、ssh経由で特定サーバを踏み台にしてアクセスしてもらっています。DBツールは[Sequel Pro](https://www.sequelpro.com/)を使っており、一度接続設定をすればターミナルを使うような設定はないため誰でも簡単に操作できます。

<img width="797" alt="スクリーンショット 2016-12-08 11.38.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/61278/2ee679a9-f566-ca5b-14a6-7b391d543fe6.png">


ssh接続の際にIP制限をかけています。それだと社外からのアクセスで不便になるためVPNを使って固定IPからの接続をしています。Interlinkの固定IPサービスを利用すれば、VPN接続して固定IPが利用できるので便利だと思います。1ヶ月千円ぐらいですし。

## VIEWテーブル

DBのテーブルはアクセスできないようにしています。VIEWテーブルのみアクセスできるようにしておいて、必要最低限の情報のみ表示するようになっています。

`CREATE VIEW view_posts AS select ....`
というようにVIEWテーブルを作成して、アクセスするユーザにそのVIEWテーブルだけの参照権限を付与します。
`grant select,show view on dbname.view_posts to 'username'@'%';`

## さいごに
今回の方法は、プロジェクトに関わる人数が増えたり、DBを管理者が更新するようなフローが多い場合は難しいですが、プロジェクトスタートしてしばらくはこのような方法で工数を抑えながら、エンジニア以外の人にもデータを見やすく提供できます。
.dotsとconnpassの新着イベントをRSS化する

はじめに
====================

dots.とconnpassのRSSが無いのが不満だったのでFEED43で作りました。

- dots. : https://feed43.com/7730204456361548.xml
- connpass : https://feed43.com/8462677488023262.xml


つくりかた
====================

[FEED43でQiitaのストックをRSSにする](http://qiita.com/ryskiwt/items/ee0852ccc757f715cc3a) にまとめてあります。

dots.
--------------------

### URL
https://eventdots.jp/event/search?pref=13

愛知県とか出てきちゃったので、東京都（pref=13）で絞ってあります（他県の方ごめんなさい）

### 抽出ルール

```html
<div class="title other">
{*}<div class="tags">{%}</div>
{*}<div class="count">
{*}<span class="accepted">{%}</span><br>{%}</div>
{*}<div class="year">{%}</div>{*}<div class="day">{%}</div>
{*}<div class="time">{%}</div>
{*}<div class="place">{%}</div>
{*}<h3><a href="{%}" target="{*}">{%}</a></h3>
{*}</div>
```


connpass
--------------------

### URL

https://connpass.com/explore/

### 抽出ルール

```html
<span class="month">{%}月</span>
{*}<span class="date">{%}</span>
{*}<span class="dtstart"><span class="value-title" title="{*}T{%}:00Z"></span></span>
{*}<span class="dtend"><span class="value-title" title="{*}T{%}:00Z"></span></span>
{*}<p class="event_title">
{*}<a href="{%}">{%}</a>
{*}<p class="event_subtitle">{%}</p>
{*}<span class="icon_gray_place">{%}</span>
{*}<span class="amount"><span>{%}</span>/{%}</span>人
```

おわりに
====================

- FEED43の制約で、更新は半日おきです。
- 取得できる最大件数は２０件だけなので、おそらくボロボロ取りこぼします。
- アプリ連携でslackにつっこむと、概要をとってきてくれるのでわりと便利です。
- 検索条件をurlに追加すれば、好みのタグとかカテゴリに絞ることもできます。

以上
ブラウザで回転寿司

これは [絵文字 / Emoji Advent Calendar 2016](http://qiita.com/advent-calendar/2016/emoji) 8日目の記事です。

### はじめに

僕は絵文字の中で「🍣」が一番好きです。
数日前、[three.js](https://threejs.org/)に触れる機会があり、ブラウザで回転寿司が出来たら良いな〜と思い始めてみました。

### 結論

何とも言えないシュールな感じになってしまった

<blockquote class="twitter-video" data-lang="en"><p lang="und" dir="ltr"><a href="https://t.co/GCf7oucGUq">pic.twitter.com/GCf7oucGUq</a></p>&mdash; ガースー (@poolside_14) <a href="https://twitter.com/poolside_14/status/806767911389929473">December 8, 2016</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

### おまけ

回転する寿司

![emoji.gif](https://qiita-image-store.s3.amazonaws.com/0/55821/dbd616c8-e800-e0c6-d4f4-7dc421011a9c.gif)

### 参考

[https://github.com/luruke/three-emoji](https://github.com/luruke/three-emoji) を参考にして書きました💃
あまりにソースが汚いので追々載せます、、😷
editorConfigの導入メモ

# EditorConfig
プロジェクトのタブ/スペース, 2/4タブ, 改行コードなどをエディタまたぎで設定・統一できるツール。
EditorConfig http://editorconfig.org/

とりあえず、reactで書いてるプロジェクトに下記ファイルをルートにぶっこむ

```bash:.editorconfig
root = true

[*]
indent_style = space
end_of_line = lf
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.js,*.jsx]
insert_final_newline = false

[*.md]
trim_trailing_whitespace = false

```

# エディタへの導入
## vim

deinユーザーなら下記を追加

```:~/.vim/rc/dein.toml
[[plugins]]
 repo = 'editorconfig/editorconfig-vim'
```

## atom

```
apm install editorconfig
```


# vscode

```
# パレット起動
cmd+shift+P

ext install EditorConfig
```
JuliaでBrainfuck

```julia
function parse_parens(code)
  pos_open = [i for (i, c) in enumerate(code) if c  == '[']
  pos_close = [i for (i, c) in enumerate(code) if c  == ']']
  if length(pos_open) != length(pos_close)
    error("parenthesis mismatch")
  end
  dict_parenspos = Dict(zip(pos_open, reverse(pos_close)))
  return dict_parenspos
end


function brainfuck(code)
  tape = zeros(Int, 30_000)
  tape_ptr = 1
  code_ptr = 1
  dict_parenspos = parse_parens(code)
  stack = []

  while code_ptr < length(code)
    c = code[code_ptr]

    if c == '[' && tape[tape_ptr] == 0
      code_ptr = dict_parenspos[tape_ptr]
    elseif c == '[' && tape[tape_ptr] != 0
      push!(stack, code_ptr)

    elseif c == ']' && tape[tape_ptr] == 0
      pop!(stack)
    elseif c == ']' && tape[tape_ptr] != 0
      code_ptr = pop!(stack) - 1

    elseif c == '>'
      if 30_000 <= tape_ptr
          error("Segmentation fault")
      end
      tape_ptr += 1
    elseif c == '<'
      if tape_ptr <= 0
          error("Segmentation fault")
      end
      tape_ptr -= 1

    elseif c == '+'
      tape[tape_ptr] = mod(tape[tape_ptr] + 1, 256)
    elseif c == '-'
      tape[tape_ptr] = mod(tape[tape_ptr] - 1, 256)
    elseif c == '.'
      print( Char(tape[tape_ptr]) )
    end

    code_ptr += 1
  end
end


code = """
  +++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.
  ------------.<++++++++.--------.+++.------.--------.>+.
  """

brainfuck(code)
```


こんな感じでしょうか。

## 参考資料
- [ワナビープログラマー脱却の手引き - hogelog - ニコニコ動画:GINZA](http://www.nicovideo.jp/watch/sm3425172)
- [Brainfuck Visualizer](https://fatiherikli.github.io/brainfuck-visualizer/)
- [Welcome to IBrainfuck - The Brainfuck Language Kernel for IPython¶
](http://nbviewer.jupyter.org/gist/robbielynch/e611442ca2d056f3b78f)
- [joelbm24/brainy: A brainfuck interpreter written in python](https://github.com/joelbm24/brainy)
- [Writing a Brainfuck interpreter in Python. | The Vogon Poet](https://thevogonpoet.wordpress.com/2012/09/02/writing-a-brainfuck-interpretter-in-python/)
- [Hello worldプログラムの一覧 - Wikipedia](https://ja.wikipedia.org/wiki/Hello_world%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AE%E4%B8%80%E8%A6%A7#Brainfuck)
inputタグのname属性の付け方

これって常識なのかもしれないですが、最近気づいたname属性の付け方


     name="user[name]"(テーブル名[フィールド名])

こうすると、POSTされた配列からテーブル名を指定すれば、そのフィールドの値すべてとれるので便利。
これはちょっとしたことなんですが、こういう形に統一すると、モデルからビューへの値の受け渡しのコードも書きやすくなり、
ビュー側でどのテーブルのどのフィールドのデータを読み込んでるかが簡単にわかり、保守もしやすい。

他のサイトの要素を見ると

     name="data[user][name]"


となっていることも多い。キーに'data'を指定すればデータベースの変更に使う値をすべて取れるという使い方だと思う。
検索フォームのnameは


    name="q"

となっているところが多い。
このことからもDB変更用のデータと分けて扱いたいということなんだろう。
Facebookイイネ数のJQUERYメモ

Facebookのイイね数をFQLで取得し表示させていたけど、ふと気づいたらコンソールに見慣れないエラーが出てるのに気がついたwwwww（遅）
デザイン的にイイね数が表示されてなくても違和感ないのが気づくの遅れた理由ということにw

FQLは廃止されたみたいorz

で、結論的コードは以下w

```javascript:sample.js
function get_facebook_count(){
  $.ajax({
    url:'https://graph.facebook.com/',
    dataType:'jsonp',
    data:{
      id:location.href
    },
    success:function(fb){
      if(fb.share && fb.share.share_count){
        console.log(fb.share.share_count);
      }else{
        console.log(“0件っすね”);
      }
    },
    error:function(){
      console.log(“なんかエラーでたよ”);
    }
  });
};
get_facebook_count();
```
VagrantでたてたOSにGitLabつっこむメモ

# 概要
Vagrantの記事しか書いてない気がしてきました。
しかもどれも中途半端。。。

今回は、GitLab運用するときに本番とは別に仮想環境がほしいな～と思ったので、色々試した結果うまくいった方法を整理して記事にします。
（そもそもVagrantに触れようとしたきっかけはこれ）

Vagrant initからGitLabの動作確認までやります。

はーい早速

# 前提
* Vagrant知ってるし手元に利用できる準備できてる
* GitLab知ってる

# 目指す環境
* CentOS6
* GitLab動いてる

# Vagrant init※
※Vagrantfileさえば`vagrant up`だけで良いので実際はinitしません。

結果だけ書きます。色々試した結果この内容にたどり着きました。

```ruby:Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "bento/centos-6.7"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.provider :virtualbox do |vb|
    vb.customize ["modifyvm", :id, "--memory", "2048"]
  end
end
```

## 説明
```
 config.vm.box = "bento/centos-6.7"
```
Vagrantの公開Boxが置いてある [Atlas] (https://atlas.hashicorp.com/boxes/search) よりCentOS6のBox引っ張ってきています。

```
config.vm.network "forwarded_port", guest: 80, host: 8080
```
よくわかっていません。なんかこの設定をしておくと、`localhost:8080`にアクセスできるようになるのかナアーって感じです。

```
config.vm.provider :virtualbox do |vb|
  vb.customize ["modifyvm", :id, "--memory", "2048"]
end
```
これ重要。virtualboxの仮想マシンのメモリの設定をここで変更してます。デフォルトやと500ちょっとしかなくて、おかげさまで大変ご迷惑被った。

## 手順1 上記の`Vagrantfile`を作成したディレクトリで`vagrant up`する
この記事の書き方ぐちゃぐちゃやな。掲題のとおり

# 環境はできたはずなのでGitLabをインストーーール
## 手順2 `vagrant ssh`で接続
WindowsやとMSYSのmsys-opensshとかを準備しないとできないです。
ちなみに
# 手順3 インストーーーール
https://about.gitlab.com/downloads/#centos6
手順通り頑張る

```
sudo yum install curl openssh-server openssh-clients postfix cronie
sudo service postfix start
sudo chkconfig postfix on
sudo lokkit -s http -s ssh
```

```
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
sudo yum install gitlab-ce
```

```
sudo gitlab-ctl reconfigure
```

# できたかな。。

## `localhost:8080`にアクセス
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/117615/335efc81-2dc9-a420-ac75-dcd278c6caf9.png)

なんかわからんけどパスワード設定する画面にリダイレクトされたぞ！！できたっぽい！！！！

## できた

![a.PNG](https://qiita-image-store.s3.amazonaws.com/0/117615/4322e979-a6b2-dbc3-962e-401752a99402.png)

設定したパスワードとusername[root]でログインできた模様。

# ついでにこの状態をVagrantでパッケージ化する

```
vagrant halt
```
まずはVM停止

```
vagrant package default --output GitLabOnCentOS6.box
```
パッケージ名を指定してパッケージ作成
sublimetext初心者のメモ

sublime text初心者が使ってみた際のメモです。
個人用テキストメモをそのまま貼り付けているため、書いた本人以外には分かりづらいと思いますので、内容については本文中の各urlのページを参考にしてください。

```
sublime text note.txt
(OS:Windows7.32bit)


■Sublime Text

参考記事：
http://techacademy.jp/magazine/3060
https://liginc.co.jp/242481
http://jobtech.jp/other/416/
http://jobtech.jp/other/453/
http://number333.org/2013/11/07/sublime-text-browser-refresh/

・有料/無料試用有（機能制限なし）
支払い方法はpaypalのみ



●手順

1.ダウンロード
http://www.sublimetext.com/
（作業時のファイル：『Sublime Text Build 3126 Setup.exe』）

2.インストール
インストーラーを起動
「add to explorer context menu」コンテキストメニューは任意で
Fishで完了

3.スタートメニューから起動

4.Package Control インストール

https://sublime.wbond.net/installation
コードをコピペして Package Control をインストール

5.パッケージをインストール

・パッケージコントロール画面を開く
「Preferences -> Package Control」又は ctrl+shift+p(win)

・入力欄に「Package Control: Install Package」入力又は選択

・任意のパッケージを選択するとインストールされる

※インストールしたもの

IMESupport：日本語変換をエディタ画面内で行う

SublimeLineter：エラーチェッカー
HTML5：HTML5のスニペット集、自動補完とハイライト
BracketHighlighter：開始/終了タグの強調
SublimeLinter-html-tidy：HTML5の構文チェッカー
SublimeLinter-jshint：JavaScriptの構文チェッカー
SublimeLinter-json：JSONの構文チェッカー
SublimeLinter-phplint：PHPの構文チェッカー
SublimeCodeIntel：関数・変数が定義されているところにジャンプする
abacus：イコールやコロンなどを綺麗に揃える
AutoFileName：コード入力補完に対象ファイル名を取得して表示する

Emmet：
SideBar Enhancements：サイドバー（ファイルリスト）を表示
SublimeLinter-csslint：
Browser Refresh：保存した瞬間にブラウザ更新
Sass：
SCSS：
SCSS Snippets：

●さらにカスタマイズ
「Dreamweaver感覚で使えるようにカスタマイズ」
https://liginc.co.jp/226222
http://www.qript.co.jp/blog/technique/1965/


All Autocomplete：デフォルトでは補完できない、ファイル中にあるワード（タグ、関数、クラス名等）を補完してくれます。


正規表現の特殊文字をエスケープしてペーストするSublime Text3プラグイン
http://wood-roots.com/web%E5%88%B6%E4%BD%9C/%E3%83%84%E3%83%BC%E3%83%AB%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE%E3%81%AE%E7%89%B9%E6%AE%8A%E6%96%87%E5%AD%97%E3%82%92%E3%82%A8%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%97%E3%81%97%E3%81%A6%E3%83%9A%E3%83%BC%E3%82%B9%E3%83%88%E3%81%99


```
kextのloadがうまくいかなかったときに原因を調べる


MacOSのkext開発で作ったkextを`kextload`しようとして何かしら問題が発生した場合、以下のように `kextutil`コマンドで原因を調べることができる。


```shell-session
kextutil -tn /Libaray/Extensions/something.nice.kext
```
秀丸エディターで特定の文字列を含まない行を消す置換

# 概要

秀丸エディターで特定の文字列を**含まない**行を消す置換です。
いつもググってる自分用の備忘録です

#

`ABC`を含まない文字列を検索する

```
^(?!.*abc).+\n
```

# 実際にやってみる


検索する文字：`^(?!.*abc).+\n`

置換する文字：``

## 置換前 
```
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaabcaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
abcaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaabc
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
abc
aaaaaaaaaaaaaaaaaaaaaaaaaaaaa
```
## 置換後 
```
aaaaabcaaaaaaaaaaaaaaaaaaaaaa
abcaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaabc
abc
```

# 感想
`grep`で`abc`を含む文字列を検索したほうが分かりやすいが
`grep`はファイル名とかが邪魔になる場合があるのでこちらも活用したいところ
Carthageで複数のframeworkを一つにまとめてバイナリ配布する方法


雑ですみません

## 前提知識
* carthageライブラリの基本的な配布方法
	* タグ切ってgithubにpushして等
* carthageライブラリのバイナリをgithubのrelaseを介して配布できること

## やり方

```shell
$ cd MyLibraryAandB # ２つのframeworkを吐くようなプロジェクトがあるとして、まずはプロジェクトフォルダに移ります
$ carthage build --no-skip-current
$ ls Carthage/Build/iOS/ # ちゃんと２つのframeworkができてるか確認
  Carthage/Build/iOS/MyLibraryA.framework
  Carthage/Build/iOS/MyLibraryB.framework
$ carthage archive MyLibraryA MyLibaryB
$ ls # カレントディレクトリに zipが出来たか確認
  MyLibraryA.framework.zip # 名前はAだけど両方入っている
$ mv MybraryA.framework.zip Carthage.framework.zip # 動作に影響はないが、名前が紛らわしいのでリネーム。このあたりの作法はrealm-cocoaを参考にした
$ # githubのreleaseにpostする
```
MacOSX&Node.jsでAmazon Dash Buttonを制御する

## 概要
Mac OS X環境で Amazon Dash Button のボタンクリック時の動作を Node.jsから制御できるようにしてみます。

## Dash Buttonの初期設定
Wifiアクセスポイントを設定して、`最後の製品を選ぶところまでステップを進めます。`
製品は選択せずに、右上の☓ボタンから設定を終了してください。

## 環境構築
Node.jsをセットアップしていない場合はインストールしてください。

```
$ mkdir dash-button // 任意のディレクトリを作成
$ npm init
$ npm install node-dash-button --save
```

## Dash Buttonを探す
以下のコマンドを実行するとWifiに繋がっている端末がScanされるので、該当する端末のMACアドレスをコピーしておきます。
Manufacturer: Amazon Technologies Inc. が正解らしいのですが、自分の環境では Manufacturer: unknown が Dash Buttonでした。

```
$ cd cd node_modules/node-dash-button
$ sudo node bin/findbutton
```

## app.jsを作成

```
const dash_button = require('node-dash-button');
const execSync = require('child_process').execSync;
// Dashボタンのアドレス(コピーしたMACアドレスをここに入力)
const dash = dash_button('aa:bb:cc:dd:ee', null, null, 'all');

// ボタンをクリックしたときのアクション
// クリックしてから数秒遅延します。
dash.on('detected', () => {
  const text='こんにちは世界';
    // sayコマンドで声を出力
    execSync(`say ${text}`);
    console.log(text);
});
```

## app.js を実行

```
$ sudo node app.js
// Dash Buttonクリックで以下が表示されて声が出ればOK
こんにちは世界
```
設定もファイルのパーミッションも所有者も問題ないのに 403 Forbidden になってしまうときの対処法

# 前置き
今までVagrantで使用する仮想サーバを4つほど用途によって使い分けていたんですが、さすがに面倒になったので1つにまとめることにしました。

そして、今までは非公式のCentOSのboxを使っていたんですが、今回は公式のboxを使うことにしました。

今まで通りNginxをインストールして設定をしたんですが、なぜか 403 Forbidden になってしまいます。設定も間違っていないし、ファイルのパーミッションも所有者も問題はなかったです。

さらに不思議なことに、全く同じファイルなのに、あるディレクトリで見ると普通に見れるのに、別のディレクトリで見るとForbiddenになってしまう現象も起きました（もちろんディレクトリも名前以外は全く同じ条件です）。

さすがに何かおかしいと思い調べたらとんでもないところに問題がありました。

# SELinuxが有効になっていた
SELinuxとは、Wikipediaによると、カーネルに強制アクセス制御を付与するモジュールらしいです。要するにセキュリティ対策のためのモジュールです。

ところがSELinuxはあまりの強度のために、普通にWebサーバでファイル配信しようとしただけでも作用してしまいます。どのように動作しているかはわからないのですが、まったく同じ条件のファイル・ディレクトリでも配信できたりできなかったりするので開発者的には正直言って邪魔です。しかも自分の場合は仮想サーバなので、ただ邪魔をされるだけの存在です。

ディレクトリによってOKだったりNGだったりするのでファイルのパーミッションとかファイルシステムに問題があるんじゃないかと思って、全く見当外れのところにかなりの時間を費やしてしまったので、今後こういうことが起こらないように記事に残しておきます。

# 解決法
まずはSELinuxが起動しているかどうかを確認してください。

```bash
$ getenforce
```

`Enforcing`と出てきたらSELinuxが起動していて悪さをしている可能性があります。`Permissive`または`Disabled`と出てきた場合は他のところに問題があると思われます。

それぞれの状態は以下の通りです。

|状態|説明|
|---|---|
|Enforcing|SELinux機能、アクセス制御が有効|
|Permissive|SELinuxは警告を出力するが、アクセス制限は無効|
|Disabled|SELinux機能、アクセス制御が無効|

参考: [SELinuxを無効化する](http://rfs.jp/server/security/selinux01.html)

## 一時的に停止する
とりあえず停止したい場合は以下のコマンドを実行します。

```bash
$ sudo setenforce Permissive
```

参考: [nginxで権限を設定した後も403 Forbiddenが出た話](http://kakakazuma.hatenablog.com/entry/2015/04/24/235812)

これでアクセス制限は無効化できます。が、サーバを再起動すると再び元の状態に戻ってしまいます。また`Permissive`でもForbiddenになる問題は解決できますが、SELinuxが停止しているわけではありません。`setenforce`コマンドでは`Disabled`に設定することができません。

## 恒久的に停止する
個人的にはこちらをおすすめします。`/etc/selinux/config`ファイルを開き、設定を変更します。

```diff:/etc/selinux/config
- SELINUX=enforcing
+ SELINUX=disabled
```

`SELINUX`の箇所が`enforcing`になっていたら`disabled`に変更しましょう。

本当にSELinuxが恒久的に無効になっているかを確認するには、いったんサーバを再起動して、`getenforce`を実行してください。`Disabled`になっていれば成功です！

# さいごに
今まで使っていたCentOSのboxではこんな問題は起こりませんでした。というかそもそもSELinuxなんてものが入っていることすら知りませんでした。やはりboxをによって若干初期設定が異なるので、新しい環境にすると思わぬところで問題が発生します。

今回は調べれば簡単に見つかる内容だったものの、今までは問題なかった＆ファイルのパーミッションや所有者、権限等がおかしいと思いこんでしまったがために原因に気づくのが遅くなりました。つまづいたらとりあえず調べてみるのも大事ですね。

# 参考サイト
* [nginxで権限を設定した後も403 Forbiddenが出た話](http://kakakazuma.hatenablog.com/entry/2015/04/24/235812)
* [SELinuxを無効化する](http://rfs.jp/server/security/selinux01.html)
WebViewClientのonReceivedError(WebView view, WebResourceRequest request, WebResourceError error) の注意点

## 概要
webviewの通信エラーを通知してくれる、`WebViewClient`の [onReceivedError(android.webkit.WebView, int, java.lang.String, java.lang.String)](https://developer.android.com/reference/android/webkit/WebViewClient.html#onReceivedError(android.webkit.WebView, int, java.lang.String, java.lang.String)) がAPI level 23 から deprecatedになりました。

代わりに　[onReceivedError(WebView view, WebResourceRequest request, WebResourceError error)](https://developer.android.com/reference/android/webkit/WebViewClient.html#onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceError))　が用意されたのですが、これを使うときの注意点のまとめメモです。

## 注意点
`onReceivedError(WebView view, WebResourceRequest request, WebResourceError error)`のドキュメントを見てみるとこんな記載になっています

> Report web resource loading error to the host application. These errors usually indicate inability to connect to the server. Note that unlike the deprecated version of the callback, the new version will be called for any resource (iframe, image, etc), not just for the main page. Thus, it is recommended to perform minimum required work in this callback.

以前とは違ってiframeのエラーだったり、画像が取得できなかったりした場合もこのコールバックが呼ばれるようになってしまいました。

そのため、`onReceivedError(android.webkit.WebView, int, java.lang.String, java.lang.String)` が呼ばれたらエラー表示をするような使い方をしている場合、同じことを`onReceivedError(WebView view, WebResourceRequest request, WebResourceError error)`でそのまま実行すると、リンク切れ画像があるようなページを表示する際にエラーになってしまいます。

## 解決策
`onReceivedError(android.webkit.WebView, int, java.lang.String, java.lang.String)` と同じような使い方をしたい場合は以下のようにします。

```java
    @Override
    public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
        if (request.isForMainFrame()) {
            // エラー処理を実行
        }
    }
```

[WebResourceRequest.html#isForMainFrame()](https://developer.android.com/reference/android/webkit/WebResourceRequest.html#isForMainFrame()) を使ってメインページのリクエストに対してだけエラー処理を実行するようにします。
アプリケーションのログは標準出力に出すのがいい

# 参考
[Twelve-Factor App](https://12factor.net/ja/logs)

# 概要

自分は今までアプリケーションのログを「/var/log/app/access.log」などにファイルを指定して出力していたが、[Twelve-Factor App](https://12factor.net/ja/logs)によるとアプリ側でそれを制御するべきでは無いと書かれている。

アプリログは全部標準出力に出しておけば、開発時はコンソール見ながらデバッグできるし、dockerで動かしている場合はdocker logsでログが確認できる。

本番環境へデプロイする場合は以下のようにdaemon起動時にloggerで出力しrsyslogやfluentdで所定のサーバーやストレージにログを転送してあげればよい。

```
daemon $MyAPP | /usr/bin/logger -p local0.info &
```
IntelliJのScalaDocのインデントが気持ち悪い

IntelliJを使ってScalaを書いていて思ったのがScala Docのインデント。
アスタリスクのインデントが気持ち悪くて設定を探していたら見つけたのでメモです。

使用バージョン： IntelliJ IDEA 2016.3

こんな感じで右側に寄ってるのが気持ち悪くいつも手動で直していました。
![before.png](https://qiita-image-store.s3.amazonaws.com/0/34814/45c679da-ae99-e326-4f88-2d2c9298d3ac.png)


Preferences → Code Style → Scala → ScalaDocタブ
「Use scaladocホニャララ」のチェックを外せばOKでした。
![config.png](https://qiita-image-store.s3.amazonaws.com/0/34814/136eb0f0-5401-283a-9ae7-46a052b1df69.png)


いい感じです
![after.png](https://qiita-image-store.s3.amazonaws.com/0/34814/65e0a434-7049-3280-d40e-fb1f38311b92.png)


2年くらい使ってるのに初めて気づきました（泣）
[Cloud102]#1 Pythonを始めよう(第3部 Jupyter Notebook構築 GCP Cloud Shell編)

AGENDA
0.はじめに
1.Cloud Shell の Web Preview
2.jupyter notebookのインストールと起動確認

#0.はじめに

(1)前置き
・本コンテンツは "[Cloud102]#1 Pythonを始めよう"の第3部 Jupyter Notebook構築GCP Cloud Shell編です。
 第1部はこちら： http://qiita.com/nagahisa/items/f378ff23d93119cb3c60
・GCPハンズオンで、すっかりCloud Shellが気に入ったので、Cloud ShellでJupyter Notebook使えるようにします。

(2)元情報
 QIITAにUbuntuにJupyter入れるコンテンツがあるので、これをGCP Cloud Shell版に変更して利用します。
Jupyter事始め
http://qiita.com/taka4sato/items/2c3397ff34c440044978

#1.Cloud Shell の Web Preview

Cloud Shellにjupyter notebookインストールできたとして、どうやって httpアクセスするの？って感じますが、なんと Web Previewって機能があります。
ちゃんと使えるものかどうか、SimpleHTTPServerで確認してみます。

・Cloud Shellの黒い画面で、SimpleHTTPServerを 8080ポート指定で起動

```
python -m SimpleHTTPServer
```

![050.JPG](http://qiita-image-store.s3.amazonaws.com/0/79389/546d550c-c4e2-f70f-4197-a55026242cc5.jpeg)

・Web Previewで8080を開きます。
![051.JPG](http://qiita-image-store.s3.amazonaws.com/0/79389/152b3b3f-2230-21c6-4eec-03e453568a06.jpeg)

・動きました！
![052.JPG](http://qiita-image-store.s3.amazonaws.com/0/79389/bfcebdf2-b096-f8f6-aa17-082ef4ffb3d6.jpeg)

＃2.jupyter notebookのインストールと起動確認

・元情報を参考に、以下をインストールします。

```
sudo apt-get update && sudo apt-get -y upgrade
sudo apt-get install -y python-pip libpq-dev python-dev
sudo pip install -U pip
sudo pip install ipython[notebook]
sudo apt-get install -y libpng12-dev libjpeg8-dev libfreetype6-dev libxft-dev
sudo pip install numpy pandas matplotlib seaborn scikit-learn
```

・元情報を参考に、設定ファイルを生成してを以下を記述します。

```
c = get_config()
c.NotebookApp.ip = '*'
c.NotebookApp.open_browser = False
c.NotebookApp.port = 8080
```
・起動します

```
jupyter notebook
```

![055.JPG](http://qiita-image-store.s3.amazonaws.com/0/79389/3af5b857-36c3-a28a-3cad-88be70488cf1.jpeg)

・Web Previewで動作確認します
![053.JPG](http://qiita-image-store.s3.amazonaws.com/0/79389/941452ea-a378-1cf2-c2b3-326650f61609.jpeg)

簡単ですね:smile:
[Javaの小枝] LinkedHashMapを使ったLRUキャッシュ

# 内容はないよう

タイトルにあるように LinkedHashMap を用いて LRU キャッシュを簡単に作成できる、というのを何かで以前読んで記憶していた。LinkedHashMapはキーの順序を保持するタイプのマップで、キーの順序には「挿入順モード」と「アクセス順モード」の二つが存在する。LRUキャッシュの部品として使う場合、後者のアクセス順モードにてキーを保持すれば良い、という訳だ。

で、今回仕事で LRU キャッシュを使う必要があり、確認のため JavaDoc を見ると著しく不安をかきたてる日本語が書かれていた… 

![LinkedHashMap_j.png](https://qiita-image-store.s3.amazonaws.com/0/110035/5c0afcbf-74ac-0577-0e91-8a54a0820792.png)

「アクセス順のリンク・ハッシュ・マップでは get でマップを照会することだけが構造的変更です。」
なんだとっ！！ もしかして put しても構造的変更(=キー順序の入れ替え)にならない？

思わず検証してしまった。(-_-;; 当然そんなことはなかった。（－＿－；；

対応する英語版は以下の通り。「単なるgetクエリだけでも構造的変更となります」と書かれている。つまりは get と put の両方で構造的変更が発生する。

![LinkedHashMap_e.png](https://qiita-image-store.s3.amazonaws.com/0/110035/6fa4334a-1949-a6c9-559f-3d51bbb49847.png)

日本語版にいろいろ誤訳があるのは諦観の念を持ってはいるが、このレベルの誤訳はさすがに不安になるのでかんべんしてほしい。まとめると、LRUキャッシュを作成する際、安心して以下のように書いてかまわない。

```Lru.java
Map<String, Long> lruCache = new LinkedHashMap<String, Long>(16, 0.75f, true)
```