OmniAICreator/Qiita-1.07M huggingface dataset:
日本語版Googleホームで自作アプリを「ねえ、グーグル」してみる。

先日ようやく日本で発売された「Googleホーム」を（auショップでiPhone6Sを下取りに出し）購入してきました。

![DSC_0169 (1).JPG](https://qiita-image-store.s3.amazonaws.com/0/47128/d5c29a04-136b-5e0b-0ed5-de252f7541d6.jpeg)

RaspPiなどで音声認識を試した事がある方はわかると思うのですが、精度の高い日本語の音声認識を自作しようと思うと困難を極めます。

音声でのリクエスト後すぐにレスポンスが返って来るのを体感し思わず一言

「すっごいよ。これ。」

## 「宿題の時間」

さて、先日Raspberry PiとAruduino（WioNode）を利用して、子供が宿題（公文式）をやった時間を保存するアプリを自作してみたのですが、

[子供の公文式学習を Google Assistant で見守る。【Raspberry Pi / AIY Projects: Do-it-yourself AI】](https://qiita.com/PonDad/items/baceec6c6c9323c8724a)

「Google Assistant」のリクエストとレスポンスは英語でしか出来ませんでした。開発者ページ「Actions on Google」を覗いてみると、「Googleホーム」の日本での発売に合わせて、日本語対応していました。

そこで早速先日作ったアプリを日本語化してみました。

![Actions on Google 2017-10-08 11-47-45.png](https://qiita-image-store.s3.amazonaws.com/0/47128/db36992e-e2db-195b-f4d2-dac7defaa224.png)

「ねえ、グーグル。『宿題の時間』につないで」と話しかけると、こんな感じで答えます。

[![PonDad | Pon Dad | Free Listening on SoundCloud 2017-10-08 11-45-22.png](https://qiita-image-store.s3.amazonaws.com/0/47128/f5753e69-81a1-441e-5429-ee0f55f70c5b.png)](https://soundcloud.com/toshio-ohta/sound1)

[Googleホーム「宿題の時間」(1) - SoundCloud](https://soundcloud.com/toshio-ohta/sound1)

「はい。 テストバージョンの宿題 の 時間です。」

「ようこそ！」

以前の機械的な音声に比べると、かなり自然な発話で驚きます。続いて長女の宿題した時間を聞いてみます。「今日のきなこ（仮名）」と話しかけてみます。

[![PonDad | Pon Dad | Free Listening on SoundCloud 2017-10-08 11-45-36.png](https://qiita-image-store.s3.amazonaws.com/0/47128/c3cce86b-d548-8e43-32b4-87a71db744f4.png)](https://soundcloud.com/toshio-ohta/google2)

[Googleホーム「宿題の時間」(2) - SoundCloud](https://soundcloud.com/toshio-ohta/google2)

「2017年10月8日 。 きなこ（仮名） ちゃんは宿題をやったよ。 始めたのは 7:59:00 だよ。 終わったのは 8:04:00 だよ。 すごいね！」

こんな感じで答えてくれます。RaspberryPiに立てたサーバーにリクエストを送ると、Googleスプレッドシートに保存してある長女・次女の宿題をした日時が確認できるという仕組みです。

以前英語版で作った時と方法が少し変わっていますのでまとめてみます。

## Actions on Googleの日本語化

はずはGoogle Cloud Platformにインスタンスを作り、[コンソール画面](https://console.actions.google.com/)にログインし、「Your projects with an Assistant app」でアプリを登録します。手順は[こちら](https://qiita.com/PonDad/items/bd54cf02805cddc064b2)に簡単にまとめてあります。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/47128/1807175e-5262-0f3c-c677-fe7c64a62f11.png)

「Overview」　> 「App information」 の上部に言語選択ボタンが追加されました。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/47128/80ba02eb-f06b-351b-a487-459518c92d99.png)

「Add language(s)」で日本語にチェックを入れます。もう一つ言語設定が必要なので注意が必要です。

「Overview」　> 「Location targeting」　で使用する地域を選択します。

![3.png](https://qiita-image-store.s3.amazonaws.com/0/47128/0c4fdd9d-5448-14ca-5c21-fa65ade6395e.png)

日本にチェックを入れます。

![4.png](https://qiita-image-store.s3.amazonaws.com/0/47128/50d9e894-e43c-0218-99f3-b75737cb8599.png)

シミュレーションを起動してみましょう。

![5.png](https://qiita-image-store.s3.amazonaws.com/0/47128/d3e1077d-9eb3-d523-f237-1e202f70e54f.png)

「language」を日本語で、「Location」を現在位置で設定すれば日本語のアプリが実行されます。

アプリの実行ファイルは「Google Cloud Functions」を利用するのですが、このファイル内では言語指定はしなくて良いみたいですね。（`lang="ja-JP"`みたいなの）参考まで実行ファイルのサンプルを貼っておきます。

[PonDad/index.js - Gist](https://gist.github.com/PonDad/957774fa65c648a0abaf3bfee4b83e05)

以前作ったファイルのレスポンス部分を日本語に置き換えました。

## まとめ

音声認識の精度もさることながら、ハンズフリーでの操作がとても快適です。今回は試しに自作アプリを使ってみましたが、便利なアプリが増えればより快適に使えると思いました。

自作ロボットの音声操作なんかも比較的簡単に出来そうなので今度試してみたいと思います。では。
標準入力された値の最頻値が複数あった場合でも昇順した状態で返す問題にすごく苦労した。

##某競プロ系サイトの初級問題がすごく難しかった##

問題の内容を簡単に言うと、
標準入力された値で最も多く入力された数を返すだけ。
ただし、**複数あった場合は昇順で返すこと。**
たったそれだけの問題なのに非常に悩まされました...。

##最初に考えた答え##

```py3
import statistics as st

N = int(input())
lis = list(map(str, input().split()))
print(st.mode(lis))
```

初級問題だし余裕でしょ、っと思ったらmode()は複数の最頻値を返せないと気づく。


##思考の整理##

このイメージならイケるはずと思いプログラムを組む
![スクリーンショット 2017-10-08 12.26.47.png](https://qiita-image-store.s3.amazonaws.com/0/124071/96dc032d-6dea-c989-6f7c-42a384b9474b.png)


```py3
#以下のような数値の入力があったとする
a = [12, 3, 12, 4, 3, 64, 43, 64, 12, 4, 64]
c = []

b = list(set(a))
print(b)
for x in b:
    c.append(a.count(x))

d = dict(zip(b,c))
max_val = max(d.values())
keys_v = [i for i in d if d[i] == max_val]
keys_v.sort()
e = " ".join((map(str,keys_v)))

print(e)
#output -> 12 64
```


イメージではsortしたリストをdictにできると思ったけど、
dictにする時点でsortが無意味になることを知ってすごく悲しかった...。

最頻値が複数あった場合を考えるだけでこんなにも大変なのかとすごく苦労しましたね...。

##参考記事##
https://qiita.com/matsudai/items/5c03c6d7f19893fa2e86

ありがとうございます。
初期化配列の実装

こんにちは、最近ハマっている初期化配列について紹介したいと思います。

# はじめに

皆さんプログラミングをする時に配列を使ってますか？使ってない人はほとんどいないのではないでしょうか？  
長さNの固定長配列AはN個の要素を格納でき、かつ任意の位置に保存された要素A[i]を最悪定数時間（以下、定数時間）で読み書き可能な最も基本的なデータ構造の一つです。配列の様々な操作の中で読み書きについで頻出する重要な操作が、配列の全ての要素を指定した値に書き換える初期化操作です。配列の初期化は配列長に対して線形な時間がかかるため、配列長が長い場合や、初期化が頻出する処理では配列の初期化操作が大きなボトルネックとなります。この問題を解決するデータ構造が初期化配列です。本記事ではシンプルな初期化配列の実装法、folkloreアルゴリズムを紹介したいと思います。

# 初期化配列

初期化配列とは通常の読み書きに加え、配列の全ての要素を任意の値に設定する配列の初期化も定数時間で行うことが可能な特別な配列です。そんな事が本当に出来るのかという感想を抱くかもしれませんがそれが出来るんです。もちろん本当に全ての要素への書き込みを定数時間で行うことは出来ません。ただし、まるで全ての要素を書き込んだかのように振る舞うことは出来るんです。

# Folkloreアルゴリズム

初期化配列の実装方法については実は昔から知らています。真の作者は不明ですが、1974年Ahoらの書籍[^1]によって始めて初期化配列の存在について言及され、その後Mehlhorn[^2]、Bentleyらの書籍[^3]で具体的な実装方法が示されました。今回はBentleyの書籍で説明されたアルゴリズムをFolklore（伝承）アルゴリズムとして説明したいと思います。
[^1]: Alfred V. Aho, John E. Hopcroft, and Jeffrey D. Ullman. The Design and Analysis of Computer Algorithms. Addison-Wesley, 1974.
[^2]: Kurt Mehlhorn. Data Structures and Algorithms 1: Sorting and Searching, volume 1 of EATCS Monographs on Theoretical Computer Science. Springer, 1984.
[^3]: Jon Louis Bentley. Programming pearls. Addison-Wesley, 1986.

Folkloreアルゴリズムでは3つの長さNの配列V, F, T（Value, From, Toの頭文字）と２つの変数b, initvで初期化配列Zを実装します。Zは抽象的な配列で実体はありませんが、補助データ構造（V, F, T, b, initv）を使ってまるでZが存在するかのように振る舞います。ここでinitvは初期値を保存し、Tはstack、bはTのスタックサイズを表します。
これらを使って次の不変条件を維持します。

- V[i]がchainを持つならばZ[i] = V[i]
- V[i]がchainを持たないならばZ[i] = initv

ここでchainとはF[i] = j < b, T[j] = iとなり、お互いにリンクを持つ状態のことを言います。
下記の図（簡単のため全てのchainは表示してません）ではV[i]がchainを持つのでZ[i]=V[i]、V[j]はF[j]とT[F[j]]=jと相互リンクがありますがF[j] ≧ bのためchainではなく、Z[j]=initvとなります。
![2017-10-08-folklore-v1.png](https://qiita-image-store.s3.amazonaws.com/0/67384/8920db6c-7435-0c6d-9b0b-f52c4ef559b3.png)

さてこの不変条件から読み書き、配列の初期化は以下のように導けます。全て定数回の操作で完了します。

- Z[i]の読み込み：V[i]がchainを持つかチェック、chainがあればV[i]を返し、chainが無ければ初期値initvを返します。
- Z[i] ← vの書き込み：V[i]がchainを持つならばV[i]に書き込み、持たないならばbを1増加させ、空いたスペースを使ってV[i]にchainを作り、書き込みます。b ← b + 1、F[i] ← b-1、T[b-1] ← i、V[i] ← v。
- Z[i] ← v for all iの初期化：不変条件から全てのchainを削除すれば初期化が完了したことになります。initv ← v、b ← 0とし、全てのchainを削除すれば完了です（下記の図を参照）。

![2017-10-08-folklore-break.png](https://qiita-image-store.s3.amazonaws.com/0/67384/b5a149d6-4e65-7ee8-d105-84f5ea8c9dbe.png)

# おわりに

如何でしたか、一見不可能に見える配列の定数時間の初期化が驚くほど簡単に実装可能なことを実感出来たでしょうか。初期化配列は普通の配列よりも高機能ですが幾つかの課題があります。

- 読み書きが普通の配列に比べ遅い：配列のランダムアクセスが複数回必要でキャッシュミスが起こりやすいため、どうしても時間がかかってしまいます。
- 普通の配列の３倍以上の領域が必要：究極的には時間はそのままで領域が定数領域の実装が求められています。

実は２つ目の課題については既に解決されています。Katoh and Gotoの論文[^4]では普通の配列の領域にたった**1 bit**の追加領域を加えただけで初期化配列を実現しています。実装はfolkloreアルゴリズムのシンプルな拡張で、folkloreアルゴリズムと同様にV, F, T, b, initvを使います。但しそれら全ての補助データ構造を単一の長さNの配列に埋め込むことで、追加1 bitでの初期化配列の実現に成功しています。とてもシンプルな実装ですので興味があればぜひ読んで見て下さい。そして、ぜひ一つ目の課題である実用に高速な実装についてぜひ取り組んでみて下さい。

P.S. 競技プログラミングで初期化配列がときどき使われていると、ちらっと耳にしたのですが本当でしょうか？
どんな場面で使われているのか興味があるので、ご存知の方は問題のリンクなど教えて頂けるととてもうれしいです。

[^4]: Takashi Katoh, Keisuke Goto, In-Place Initializable Arrays. CoRR abs/1709.08900, 2017.
エンジニア向けmacの初期設定（おすすめアプリ/homebrew）

macを購入し、前回のデータを以降せずに一から設定したときのメモ。
5年以上macをメインで使っていませんでしたが、パッケージ管理は、macportでなく、homebrewが主流のようです。

> macOS 10.12.6


# 最初にやること

- ソフトウェアアップデート
 - (appleマーク) > このmacについて > ソフトウェアアップデート
- OSアップデート
 - app store > OSなどアップデートできるやつは一通り

# 使い勝手の設定

- システム環境設定（自分好みの使いやすい設定に）
 - コンピューター名変更： 共有 > コンピューター名 
 - ホットコーナー：　MissionControl > ホットコーナー
<img width="284" alt="hotcorner.png" src="https://qiita-image-store.s3.amazonaws.com/0/120047/956a4076-10b4-1414-7ee8-c2b31f5c630a.png">
- terminalのテーマ変更
 - デフォルトよりも使いやすいテーマを求め、「iceberg」を利用しています
 - 参考：[お前らのターミナルはダサい](https://qiita.com/kinchiki/items/57e9391128d07819c321)
 - キャプチャ(bashrc変更後）
<img width="300" alt="terminal.png" src="https://qiita-image-store.s3.amazonaws.com/0/120047/2e0f807e-d4d9-4c98-c5bb-2dbf40cca0eb.png">

 
# アプリのインストール

下記がおすすめアプリです。
- ブラウザ：　Chrome/Firefox
- 便利ツール：　Skitch/Evernote
- Office: LibreOffice
- 動画再生：　LVC
- 日常：　Slack、Kindle

# シェル・エディタ

linuxサーバーでの利用とおなじく、gitでdotfilesを管理するのが楽です。

- bashrc/vimrcなどの設定を管理してます
- 参考： [dotfilesをGitHubで管理](https://qiita.com/okamos/items/7f5461814e8ed8916870)

# パッケージ管理：Homebrew

Mac OS Xのパッケージ管理システムには、2017/10現在、MacPortsとHomebrewがあるが、Homebrewが主流のよう。依存関係でインストールされるソフトが少ないため、とのこと。

1. javaのインストール
 - `$ java -version`
1. Command Line Toolのインストール 
 - 下記のいずれかでインストール
 - 2-1. X Codeインストール（重いので回線が低速の場合は、下記がおすすめ）
 - 2-2. Command Line Toolのみインストール（[こちらのAppleサイトから](https://developer.apple.com/downloads/index.action)）
1. Homebrew本体のインストール
 - [Homebrew公式](https://brew.sh/)記載のインストールコマンド実行
 - 例： `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"`

- インストール後の確認

```
$ brew doctor
-> Your system is ready to brew.  と表示されればOK

$ brew update

$ brew -v
-> Homebrew 1.3.4
```

## Homebrewでいれたいコマンド

思いついたら追記します。

- nkf: 文字コード変換
- wget:　ダウンローダー
- aria2：　爆速ダウンローダー（参考： [curlやwgetの数倍速い 爆速ダウンローダー aria2を使う](https://qiita.com/TokyoMickey/items/cb51805a19dcee416151)

## Homebrewについて参考

- 参考：[公式Requirements](https://docs.brew.sh/Installation.html)

```
* An Intel CPU 1
* OS X 10.10 or higher 2
* Command Line Tools (CLT) for Xcode: xcode-select --install, developer.apple.com/downloads or Xcode 3
* A Bourne-compatible shell for installation (e.g. bash or zsh)
```
- 参考：　[パッケージ管理システム Homebrew](https://qiita.com/b4b4r07/items/6efebc2f3d1cbbd393fc)
PhpStormにLaravel Bladeのスニペット登録しておく。

### ダウンロードしてくる
https://github.com/koomai/phpstorm-laravel-live-templates

### xmlファイル突っ込む

```
cd ~/Library/Preferences/PhpStorm2017.2/templates
open ./
```

<img width="392" alt="スクリーンショット 2017-10-08 11.57.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/9907/f611abc1-cb6f-d1f5-a0b3-e61e2737e6b1.png">

### PhpStorm再起動

### LiveTemplatesに反映を確認
<img width="745" alt="スクリーンショット 2017-10-08 11.58.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/9907/e3cddfb1-7bee-f072-d265-0c6d24c00573.png">

- bladeファイルで候補でてくる

<img width="793" alt="スクリーンショット 2017-10-08 12.00.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/9907/0f379b68-7f8a-8692-0102-9ceb59cd12ae.png">
tomcatでBasic認証を有効にする方法

#１．「web.xml」に以下の記載を追加する。
＜web.xmlの格納先＞
\apache-tomcat-8.5.15\webapps\ROOT\WEB-INF\web.xml
or
\apache-tomcat-8.5.15\conf\web.xml

■記載内容

```
<security-constraint>
 <web-resource-collection>
  <web-resource-name>User Basic Auth</web-resource-name>
  <url-pattern>/*</url-pattern>
 </web-resource-collection>
 <auth-constraint>
  <role-name>role1</role-name>
 </auth-constraint>
</security-constraint>

<login-config>
 <auth-method>BASIC</auth-method>
 <realm-name>User Basic Auth</realm-name>
</login-config>

<security-role>
 <role-name>role1</role-name>
</security-role>
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/243bef5b-8a72-7248-3a85-d82ffabf6153.png)

#２．「tomcat-users.xml」に以下の記載をする。
＜tomcat-users.xmlの格納先＞
\apache-tomcat-8.5.15\conf\tomcat-users.xml

■記載内容

```
<role rolename="role1"/>
<user username="sample" password="test" roles="role1"/>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/696ab3a0-711e-a743-937a-80303a2ce1e0.png)

#３．Tomcatを再起動する。
PHPカンファレンス2017@東京_メモ①PHPの今とこれから

#PHPの今とこれから
##PHPのリリースサイクルとか
　リリースサイクル：1年
　ライフサイクル：3年(バグ修正：2年/セキュリティ修正：1年)

##7.xの特徴
　7.0
　　大幅高速化(データ構造の見直し->最新CPUへの対応)
　　戻り値型宣言
　　スカラー型宣言
　7.1
　　Nullable
　　複数例外キャッチ
　7.2 (11月リリース)
　　暗号フレームワーク
　　高速化
　
##7.2改善ポイント
　7.1から10%高速化
　関数の引数型宣言や戻り値でobject型を使用可能
　　従来：Typehintingではクラス名を指定
　　制約：同一クラスまたは継承されたクラスのみ確認可能
　　→汎用クラスを表すobject型を型引数または戻り値に指定
　　public function method() : object <- 戻り値の型指定
　ハッシュ生成
　　5.5でパスワードハッシュ用APIを導入
　　password_hash()
　　　Argon2をパスワードハッシュで使用可能
　　　柔軟な設定が可能：メモリコスト、時間コスト、並列度を調整
　パスワード検証
　　タイミング攻撃に対する対応
　　password_verify()
　セキュリティフレームワーク
　　Libsodium標準サポート化
　　　OpenSSLのみ対応だとRSAやAESの間違った使い方を誘発、認証付き暗号を未サポート
　　　　認証付き暗号：暗号 + MACで構成/秘匿性 + 完全性・認証性　　　
　サイドチャネル攻撃に対応可能、高速な暗号実装
　
##7.2廃止予定機能
　Mcrypt：PECLに移動
　__autoload等
　extentionロードの環境依存廃止　　

##フレームワーク
　Laravelの人気が高い

##HHVM/Hackの進化
　Facebookが開発するPHP/Hackの実行環境
　PHP7の完全互換は目指さない
　Hack用ツール/ライブラリ提供
　Hack言語の改良：デストラクタ・リファレンスの廃止
　　PHPとは別の方向に進む可能性/つかず離れず
　(ロードマップが公開されている)　

##PHPのこれから
　7.3開発
　JIT for PHP；OpCacheを拡張、Zendが次期
seabornのkdeplotで、エラーがでた場合の対処

https://github.com/mwaskom/seaborn/issues/1103
より

seaborn.kedplot()を呼ぶと以下のように、`TypeError: slice indices must be integers or None or have an __index__ method`というエラーが出てしまった場合の対処法。

```
u = np.array([ 3.41959 , 1.79315 , 1.17229 ], dtype=float)
Se_u = pd.Series(u)
sns.kdeplot(Se_u)

TypeError: slice indices must be integers or None or have an __index__ method
```

以下のように、statsmodelsを入れ直してやると、エラーが出なくなります。

```
conda uninstall statsmodels --yes
conda install -c taugspurger statsmodels=0.8.0
```
MySQL で root のパスワードを root に

https://qiita.com/RyochanUedasan/items/9a49309019475536d22a

細かいことは上記に詳しく書いてくれています。コマンドだけ

```
# grep "temporary password" /var/log/mysqld.log
# mysql -uroot -p
> set password for root@localhost=password('passwordPASSWORD@999');
> SET GLOBAL validate_password_length=4;
> SET GLOBAL validate_password_policy=LOW;
> set password for root@localhost=password('root');
```
GitとGitHub　基本的な流れ

Gitでバージョン管理をするのは大事なことだ。なぜなら、**どこで・どのように・なぜコードを変更したのか、自分でも忘れてしまうことがあるから**だ。しかし、大事なのはわかるが、**リポジトリ**とか**コミット**とか**プッシュ**とか、日常生活にはまず出てこないであろう用語で説明されるので、どの処理のことを指しているのか混乱することが多い。そこで、GitとGitHubのことをまとめてみた。

## 環境
開発環境：Cloud9
git version：2.14.1

## Gitとは
そもそもGitとは何なのだろうか。
> Git（ギット）は、プログラムのソースコードなどの変更履歴を記録・追跡するための分散型バージョン管理システムである。
>引用元：Wikipedia

プログラムを書いていると機能の変更や追加を繰り返し行っていくことになる。どのタイミングでどんな機能を追加・変更したのか記録していくのにGitを使用するとわかりやすくなる。ということみたいだ。

実際にGitを使用して環境構築をしていく。

## リポジトリの作成
>リポジトリとは、ファイルやディレクトリの状態を記録する場所です。保存された状態は、内容の変更履歴として格納されています。変更履歴を管理したいディレクトリをリポジトリの管理下に置くことで、そのディレクトリ内のファイルやディレクトリの変更履歴を記録することができます。
引用元：[履歴を管理するリポジトリ【Gitの基本】 | サルでもわかるGit入門 〜バージョン管理を使いこなそう〜](https://www.backlog.jp/git-guide/intro/intro1_2.html)

ファイルやディレクトリの状態を記録する場所である。知っている人からしたらあたり前のことであると思うが、はじめて聞いた身としてはピンとこない。
見当違いかもしれないが、日記のようなものだろうか。●月×日 sample.rbにputs機能を追加した。みたいな。
しかも、ただの日記ではなくて、その変更前の内容も保存してくれるので元に戻すことも容易にできる。なんて便利なんだろうか。

コンソールで`cd`コマンドを使用して管理したいディレクトリの先頭位置に移動し、`git init`コマンドでリポジトリを作成することができる。実行後に`.git`というディレクトリが生成され、その中に必要なファイルが生成される。
また、Cloud9であればコマンド実行後、$の前に(master)と表示される。

## コミットまで
リポジトリの生成が終わったら今度はコミットしていく。コミットとは、実際に対象ファイルをリポジトリへ記録することである。
コミットする前に**ステージングエリア**という場所にコミットする対象を追加しなければならない。
`git add .`でステージングエリアにファイルを追加する。`git add`はコマンドで、`.`の部分がディレクトリの指定。`.`はカレントディレクトリ以下のすべての変更がaddされる。また、**オプション-A**を追加すると**git管理内のすべての変更がaddされる。**基本的には`git add -A`を使用したいと思う。
ちなみに、ステージングエリアに追加されているファイルを確認するには、`git status`コマンドで確認することができる。

さて、ステージングエリアにファイルを追加したのでコミットしていく。コミットは`git commit`コマンドを使う。
引数に`-m "コメント"`と記述するとコメントが追加できる。

## GitHub
gitを使用するにはまずリポジトリを作成し、ファイルの変更があるごとにステージングエリアに追加⇒コミットを行えばいい。しかし、この方法で管理できるのは自分自身だけであり、開発者同士でコードの共有ができない状態である。
そこで使用するのが**GitHub**。つまり、ソースコードの変更記録をアップロードしてインターネット上に公開する。
今回はGitHubへの登録方法などは割愛させていただく。

リポジトリの種類についても触れておこう。
リポジトリには2種類あり、ローカルリポジトリとリモートリポジトリがある。

- ローカルリポジトリ・・・ネットワークに接続されていないリポジトリ。ユーザ一人ひとりの管理下。
- リモートリポジトリ・・・ネットワーク上にあるリポジトリ。複数ユーザーで共有可能。

基本的にはリポジトリを作成したらローカルリポジトリが作成され、それをネット上にアップロードなりするとリモートリポジトリとなる。GitHubはリモートリポジトリである。前置きが長くなったが、GitHubへアップロードしてみる。

## pushする
まずは以下のコマンドを実行する。
`git remote add origin https://github.com/<username>/<project_name>.git`
**username**と**project_name**の部分は書き換えていただきたい。(**<>**は不要)
そして以下を実行
`git push origin master`
これでGitHubにアップロードができた。

## まとめ
- Gitでコードのバージョン管理ができる
- GitHubでGitの内容を公開・共有できる
- まずはリポジトリの作成から。作成は一度でいい
- リポジトリへ記録するのをコミットという
- ステージングエリアへ追加→コミット　の順番
- GitHubへのアップロードはプッシュコマンドで行う

とりあえずはGitとGitHubの基本的な流れをまとめてみた。しかし、Gitにはマージやブランチなど、まだまだたくさんの便利機能があるので興味を持ったら調べてみてはいかがだろうか。
ご閲覧ありがとうございました。
もしぼくが「それ、もっとスマートに書けるよ」を書くなら

「[それ、もっとスマートに書けるよ](https://speakerdeck.com/wakamsha/sore-motutosumatonishu-keruyo-javascript-kodowomotutoduan-ku-motutosinpurunishu-ku-tips-4xuan)」をもしもぼくが書くなら

## ある特定の文字列が別の文字列内にあるかどうか

> ```js
> const ua = navigator.userAgent;
> 
> if (~ua.indexOf('iPhone') || ~ua.indexOf('iPod') || ~ua.indexOf('iPad')) {
>   return 'ios';
> } else {
>   return 'other';
> }
> ```

正規表現を使います

```js
const isAppleDevice = !!navigator.userAgent.match(/iPhone|iPod|iPad/)
```

## それlet使わなくてもできるよ

> ```js
> const { foo, bar } = (() => {
>   if (new Date().getHours() < 12) {
>     return {
>       foo: 'forenoon',
>       bar: 'am'
>     }
>   } else {
>     return {
>       foo: 'afternoon',
>       bar: 'pm'
>     }
>   }
> })();
> ```

基本は別関数にして返す形にしますが、この例ならこうするかなと。

```js
const isForenoon = new Date().getHours() < 12
const [ foo, bar ] = isForenoon ? ['forenoon','am'] : ['afternoon','pm']
```


# 参考
[それ、もっとスマートに書けるよ](https://speakerdeck.com/wakamsha/sore-motutosumatonishu-keruyo-javascript-kodowomotutoduan-ku-motutosinpurunishu-ku-tips-4xuan)

[「それ、もっとスマートに書けるよ」がもっとスマートに書けるよ](https://qiita.com/yassh/items/21b5f53a7ae2f5d4d63e)
LinuxでSSHを許可する方法

LinuxへのSSHを許可する設定方法を以下に記載する。

*なお、作業は、root権限を保有するIDにて行うこと*

#SSHのインストール状況確認コマンド
コマンド : **yum list installed | grep ssh**

以下がインストールされていることを確認
＜確認対象＞
openssh-server.x86_64 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/00cba26e-a839-8d45-93b7-32c4bbb579a4.png)

#「sshd_config」にSSHを許可する設定を追加
編集対象ファイルは以下の通り。
＜編集対象ファイル＞
/etc/ssh/sshd_config

ファイル内にport等の記述があるが、初期設定を残しておく為、最終行に以下に内容を記述する。
＜記述内容＞
Port 22
PermitRootLogin no
PasswordAuthentication yes
#####■編集中
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/8c032aad-e333-526f-82cd-46198c793a44.png)

#####■編集結果確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/cecef77f-77f1-2e51-7396-38b0d37240e3.png)

#SSHを起動
コマンド : **systemctl start sshd.service**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/f7e8c6d9-cc20-d8f8-894f-a1e802dd8105.png)

#SSHの起動状況確認
コマンド : **systemctl status sshd.service**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/fb6f5461-fa19-4faf-c45f-e073d9bbfc40.png)

#FirewallのSSHポートの開放状況確認、及び設定
確認コマンド : **firewall-cmd --list-all**
確認対象 : 「services: dhcpv6-client http ssh
」が設定されていることを確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/5295f0ee-a581-9be2-1b80-e5ebb9a0e47f.png)

*もし、SSHが設定されていない場合は、以下のコマンドを実行する。
設定コマンド : firewall-cmd --permanent --add-service=ssh*

#SSHさせる為のユーザ作成、及びパスワード設定
ユーザ作成コマンド : **useradd sshuser**
作成したユーザのパスワード変更コマンド : **passwd testuser**

#SSHクライアントからアクセスする為にサーバのIPアドレスを確認
確認コマンド : **ifconfig**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/cb7bc5d5-9cbd-6eff-dc85-4dbee03cc7a3.png)

#SSHクライアント(Teraterm)を起動してアクセスする
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/151dd240-1dca-2e12-6043-6a36f85963a0.png)

先ほど作成したユーザIDとパスワードを入力する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/b8efbd5a-ff42-7dff-b170-b9d1d46a049d.png)

#SSH完了
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204260/44f0324b-68e0-8387-51b2-191800306fac.png)
mixhost で cakephp2.x の cron shell 動かない

mixhost で cakephp2.xの cron が動かなかったので対応方法。

#考え方
- register_argc_argv が On になっていないので動かない
- .htaccess からも変更できるようだが、cron及びshellスクリプトには通じない
- よって元からある php.ini を コピー変更、それを読み込みcronやshellを実行



#ssh でログイン

## php.ini ファイルをコピー
cp /opt/alt/php70/etc/php.ini /home/your/www/kanojyo/app/original-php.ini

##original-php.ini を以下のように編集
register_argc_argv = On

##original-php.ini を読み込みつつ実行
/usr/bin/php -c /home/your/public_html/kanojyo/app/original-php.ini /home/your/public_html/kanojyo/app/Console/cake.php Cron getAccess -app /home/your/public_html/kanojyo/app

以上です。:relaxed:
Ruby の empty? の逆は any? ではない

ruby の `empty?` は要素の数が 0 の場合に `true` を返すメソッドですが、`any?` は真となる要素が存在している場合に `true` を返すメソッドなので、例えば次のコードは両方とも `false` を返します。

```rb
a = [false]

p a.empty? #=> false
p a.any?   #=> false
```

なので、 `empty?` の逆の結果が欲しい場合は `!` を使いましょう。

```rb
a = [false]

p a.empty?   #=> false
p !a.empty?  #=> true
p a.empty?.! #=> true (これはあまり見ないかも)
```
PSR-8 Hug (日本語訳)

Mutually Assured Hug (相互高信頼性ハグ)
====================

このドキュメント内の "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", "OPTIONAL" キーワードは [RFC 2119](http://tools.ietf.org/html/rfc2119) の説明にしたがって解釈されるものとします。


## 1. 概要

この標準は、オブジェクトが互いの感謝と支持を表明するための、一般的な方法を確立します。 これでオブジェクトは、建設的な方法で互いをサポートすることができ、異なるPHPプロジェクト間の協力を促進します。

## 2. 仕様

この仕様では2つのインターフェース `\Psr\Hug\Huggable` と `\Psr\Hug\GroupHuggable` を定義します。

### Huggable オブジェクト

1. Huggable オブジェクトは、その `hug()` メソッドを呼び出すさい第一パラメータとして `$this` を渡すことで、他のオブジェクトへの思いやりと支持を表現します。

2. `hug()` メソッドが呼び出されたオブジェクトは、少なくとも1回、呼び出したオブジェクトを `hug()` し返さなければなりません (MUST)。

3. ハグするさい2つのオブジェクトは、何度も反復して互いに継続してハグし返すことができます (MAY)。 しかし、すべてのハグ可能オブジェクトは、無限ループを防ぐための終了条件を持っていなければなりません (MUST)。たとえば、最大 3 回までの相互ハグしか許可しないようにオブジェクトを設定すると、その後、ハグの連鎖を破棄して return するといったようにします (MAY)。

4. ハグされたとき、オブジェクトは、状態の変更などの副次的なアクションをとることができます（MAY）。一般的な例として、内部の幸福感もしくは充足感のカウンターをインクリメントすることが挙げられます。

### GroupHuggable オブジェクト

1. オブジェクトは、複数のオブジェクトを一括で支援/肯定することができることを示す、GroupHuggable を実装することがあります。

## 3. インターフェース

### HuggableInterface

~~~php
namespace Psr\Hug;

/**
 * Defines a huggable object.
 *
 * A huggable object expresses mutual affection with another huggable object.
 */
interface Huggable
{

    /**
     * Hugs this object.
     *
     * All hugs are mutual. An object that is hugged MUST in turn hug the other
     * object back by calling hug() on the first parameter. All objects MUST
     * implement a mechanism to prevent an infinite loop of hugging.
     *
     * @param Huggable $h
     *   The object that is hugging this object.
     */
    public function hug(Huggable $h);
}
~~~

~~~php
namespace Psr\Hug;

/**
 * Defines a huggable object.
 *
 * A huggable object expresses mutual affection with another huggable object.
 */
interface GroupHuggable extends Huggable
{

  /**
   * Hugs a series of huggable objects.
   *
   * When called, this object MUST invoke the hug() method of every object
   * provided. The order of the collection is not significant, and this object
   * MAY hug each of the objects in any order provided that all are hugged.
   *
   * @param $huggables
   *   An array or iterator of objects implementing the Huggable interface.
   */
  public function groupHug($huggables);
}
~~~
テンプレートを置いたら CLI コマンドに追加されて、フラグ渡したりでファイル作る感じのツール

新しいの作るたび最初にあれこれ設定ファイル（`*.json`, `.*rc`）を用意すると思いますが、あんましググらずに用意できたことがないなと思って。この辺やっぱり CLI で作れたら楽かな思ったので、[moza](https://github.com/nju33/moza)とかいうの作りました。

## 流れ

1. `./.moza/`か`~/.config/moza/`ディレクトリに`*.hbs`（[handlebars](https://github.com/wycats/handlebars.js/)）ファイルを置く
2. その頭にフロントマターを記述（[yargs](https://github.com/yargs/yargs)の[options](https://github.com/yargs/yargs/blob/master/docs/api.md#optionskey-opt)形式）
3. その下に[handlebars](https://github.com/wycats/handlebars.js/)で適当にテンプレートを書く
4. コマンド実行でテンプレートを展開してファイル作成

> プロジェクト固有なのは`./.moza/*.hbs`みたいな

## インスト

```bash
npm i -g moza
# yarn global add moza
```

実行。

```bash
moza
# npx moza
```

## 例

こんなファイルを`./.moza/`下に置く。

```text:tsconfig.hbs
---
CONFIG:
  description: description
  usage: usage
NOTE: |
  `preact`や`ink`を使う場合は、`--jsx-factory`に`h`を指定
lib:
  alias: l
  default:
    - es2016
    - es2017
    - es2017.object
target: es6
jsx:
  default: false
  type: boolean
jsxFactory:
  default: React.Component
  type: string
  choices:
    - React.Component
    - h
module: commonjs
---

{
  "compilerOptions": {
    "target": "{{target}}",
    "module": "{{module}}",
    "lib": [
      {{#each lib}}
      "{{this}}"{{#unless @last}},{{/unless}}
      {{/each}}
    ],
    {{#if jsx}}
    "jsx": "React",
    "jsxFactory": "{{jsxFactory}}",
    {{/if}}
    "strict": true,
    "sourceMap": true
  },
  include: [
    "./src/**/*.ts",
    "./src/**/*.tsx"
  ]
}
```

すると、`tsconfig.hbs`というファイルだったので、`tsconfig`というコマンドが使えるようになっています。また`CONFIG`と`NOTE`以外は KebabCase に変換されてフラグで渡せるようになってます。

> ```bash
> moza --help
> #
> # Commands:
> #   tsconfig
> #
>
> moza tsconfig --help
> #
> # Variables:
> #   --lib, -l                       [default: ["es2016","es2017","es2017.object"]]
#   --target                                                      [default: "es6"]
#   --jsx                                               [boolean] [default: false]
#   --jsx-factory
#          [string] [choices: "React.Component", "h"] [default: "React.Component"]
#   --module                                                 [default: "commonjs"]
#
```
> ---
>
> - `CONFIG.description`には`tsconfig`コマンドの説明。
> - `CONFIG.usage`には`--help`時に表示される使い方。
> - `NOTE`には`moza note tsconfig`みたいにした時に表示できるテキスト。（`npm i ...............`みたいなの書く想定で…）

あとは`moza tsconfig [flags] <dest-path>`みたいな感じで生成だけです。

> 1つ注意で、`type: array`なフラグがある場合は`<dest-path>`の前に`--`が必要です。
>
> ```bash
> moza foo --value 0 --value 1 --value 2 -- foo.json
> ```
>
> ---


> ![Kapture 2017-10-08 at 7.22.32.gif](https://qiita-image-store.s3.amazonaws.com/0/84144/b0ad928e-64aa-cab6-932d-72299ed81a0e.gif)

以上!

## その他

### リモートにあるテンプレートファイルを取ってくる

例えばgistとかから。

```bash
moza add <url> --output foo.hbs # ダウンロードして ./.moza/foo.hbs へ作成
moza add -g <url> -o foo.hbs    # 〃 ~/.config/moza/foo.hbs
```

### 持ってるテンプレートファイル一覧を見る

パスも表示されるので削除するときとか。

```bash
moza ls    # ./.moza/*
moza ls -g # ~/.config/moza/*
```

### ノート表示

```bash
moza note <command>
```
これから勉強すること　再確認

#まず箇条書きで思いついたものから・・・

・Python3の基礎
・機械学習(自分でいろいろな物を作りたい。)
・Kivy(自分の直感では今後使われることが多くなりそう)
・Unity(ゲーム作りでは便利,　将来的にVRやMRなどのコンテンツを作ってみたい)
・C#(Unityで使う文法)
・英語(最新のドキュメント？やマニュアルなどスラスラ読めるようになりたい)
　TOEICとかの試験で高得点をとってみたい。
・ギター上手くなりたい

---

#後回しできそうなもの

~~Python3基礎~~,
機械学習,
Unity,
C#,
~~英語~~,
ギター

---


#これからやるべきこと

・Python3の基礎固め
みんなのPython3を分からない所が出てきても逃げない。
**とりあえず先に進む**という方法は自分に合っていなかったので
terateil等で調べたり質問する、分からないままにしない。
どうしても分からなかった場合は・・・やむを得ず先に進む。。

・英語
文法も語彙力もまだまだだからやばい。
第五文型もいまいちな感じくらいやばい。
**主語＋動詞**が第一文型で、　
順番が　**動詞＋主語**　でも第一文型になるんだという事を最近知ったレベル。

---

#これから・・

・ある程度勉強が落ち着いたら、
以前作っていたWordPressのページも作り直す（改造する？）

・なるべく糞みたいなツールでも、コードでもできたら復習も兼ねてこのコードは何を意味しているのかの解説を復習の意味で載せる。


#最後に

**現在のPC環境**
・Windows10 一般的なやつ
・GTX970
・Python3.6.2(Anaconda3)
・kivy1.10.0
・Unity2017 最初の方

**最近のメモ**
遭遇した問題 : pipコマンドが使えない！？(python3更新？pip更新？したとき)

pip.ini や　pip.confを作ると書かれているものが多かったけど、自分の場合はそれで解決しなかった！(検索の仕方が間違ってただけかもしれないｗｗ　おそらくpip listコマンドでの表示方法を変えるためのファイルなのかなと思った。ちなみに自分の環境であるWindows10の場合　**C:\Users\ユーザー名\AppData\Roaming\pip**というところに**pip.iniファイル**を作ってるよ）

答え:
Anacondaフォルダにある、
**python.exe**　と　**script**と書かれたフォルダのpathを通す。
(Pythonを直接インストールしてるならpython.exeと同じところにあるのかな？Anaconda3はよく使われている外部ライブラリがたくさん詰まっているし、説明してくれている人も多いのでこの機会に、環境を変えてみるのもイイかもしれない！)
Google HomeにつぶやくとTwitterでつぶやくやつ、IFTTTですぐできた。

昨日、日本語版の[Google Home](https://store.google.com/product/google_home)が届いた。

<img width="1256" alt="Screen Shot 2017-10-08 at 6.51.36 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/38290/640101ba-03fc-4308-e6dd-f586f5398427.png">

このGoogle Homeと[IFTTTのGoogle Assistant連携](https://ifttt.com/google_assistant)の組み合わせがとても便利そうなので、さっそく試してみた。15分くらいでTwitter連携できた。

<img width="582" alt="Screen Shot 2017-10-08 at 7.07.54 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/38290/596435e3-6010-a319-2d02-699e3a28f7d9.png">

ちなみに、実行するアクションを入れ替えれば、FacebookやSlackにメッセージを送ったり、家電をオンオフしたり、Google Sheetに記録したりと等々、多彩な連携が可能。

以下に連携方法をメモしておく。

## Google Homeの設定

これは開封後10分くらいで終わる。

## IFTTTのAppletを作る

まずはIFTTTにサインアップしておく。IFTTTでは「コレをトリガーにアレを実行」ってルール設定を「Applet」と呼んでいる。今回は、Google AssistantをトリガーにTwitterでツイートするAppletを作る。

[IFTTTのMy Applets](https://ifttt.com/my_applets)ページを開き、`New Applet`をクリック。「コレをトリガーに」を指定する部分で、Google Assistantを選ぶと、以下の選択肢が出て来る。

<img width="986" alt="Screen Shot 2017-10-08 at 7.03.19 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/38290/592aaad1-5406-cd86-1b82-77dcbf30c57f.png">

それぞれ、

- Google Assistantで指定のフレーズを認識
- Google Assistantで数値を含む指定のフレーズを認識
- Google Assistantでキーワードを含む指定のフレーズを認識
- Google Assistantで数値やキーワードを含む指定のフレーズを認識

って機能を表す。今回は、キーワード付きのフレーズを認識できる機能`Say a phrase with a text ingredient`を試してみた。こんな感じだ。

<img width="565" alt="Screen Shot 2017-10-08 at 7.14.45 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/38290/796d40f2-d424-ee88-3498-ca0e5bb7d048.png">

ここで引っかかりポイント。「つぶやく」と発音すると、「つぶやく」「呟く」の2パターンで認識されるのだ。なので、上図のように両方とも登録しておかないとうまく認識されない。ちなみに、このように`$`記号を使って、つぶやきとして認識したいキーワードを取り出せる。

ちなみに、IFTTTのiOSアプリでは日本語入力がバグっていて使い物にならない。Webページからの設定がおすすめ。

## Twitter連携設定

つづいて、Appletの「アレを実行」部分として、Twitterでつぶやくルールを以下のように指定する。

<img width="526" alt="Screen Shot 2017-10-08 at 7.18.55 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/38290/ee6f75b2-836d-a40a-f184-6f347645f561.png">

ここは好きなテキストをいれてよいが、{{TextField}}ってのを入れた場所にGoogle Assistantで認識したキーワードを挿入できる。

以上。最後に`Finish`ボタンをクリックしてAppletを登録すると完成。すぐ試せる。

## テスト＆デバッグ

Google Homeに向かって、「OK Google, インターネットで これはテスト とつぶやく」のように話しかけると、うまく行けば数秒でTwitter上にツイートが現れる。成功だ。

つぶやくキーワードが短いと成功しやすいけど、長い文だとあまりうまく動いてくれない。デバッグしたい場合は、Google Homeアプリのマイアクティビティが便利。認識に失敗した場合もすべてここにログとして残る。

![IMG_0115.PNG](https://qiita-image-store.s3.amazonaws.com/0/38290/677fad2e-c327-0dc7-4f80-ae0409173bae.png)

ちなみに、今回のようにキーワードを含む文章を認識するルールを使うと、認識の成功率はあんまり高くない。日々の生活で使うなら、固定文をトリガーに固定文をつぶやくルールの方が実用性はよさそうだ。

## IFTTT連携は使える

IFTTTはいろいろなサービスやデバイスとの連携をサポートしているので、Twitter以外にもいろいろ遊んでみたくなる。例えば、

- FacebookやSlackなどにメッセージ送信
- [littleBits](https://shop.littlebits.cc/products/cloudbit)でおうちIoT連携
- WeMoで家電のオンオフ
- Google Sheetに音声メモ記録
- Gmailでメール送信

といったところがすぐに思いつく。

Google Home＋IFTTT連携、お手軽すぎるので皆さんもお試しあれ。

-----
Disclaimer この記事は個人的なものです｡ここで述べられていることは私の個人的な意見に基づくものであり､私の雇用者には関係はありません｡
Spring Data JPA にてメタモデルを使用すると NullPointerException が発生する

#概要

JPA にてメタモデルを使用して、実装した結果、NullPointerException が発生しました。

#詳細

JPA では、メタモデルの機能を提供しています。
メタモデルはエンティティの構造を明確にするものです。
メタモデルを使用せず、Criteria API を書くと下記のような実装になります。

```NumberSpecification.java
public class NumberSpecification {
    public static Specification<Group> members(Map<Integer, Integer> lowerUpper) {
        return (root, query, cb) -> {
            final Collection<Predicate> predicates = new ArrayList<>();
            lowerUpper.forEach((lower, upper) -> {
                predicates.add(
                        cb.and(cb.between(root.get("number"), lower, upper))
                );

            });
            return cb.or(predicates.toArray(new Predicate[predicates.size()]));
        };
    }
}
```

上記の場合、文字列で Group クラスの number フィールドを指定して、下記のような条件を作成しています。

```condition.sql
where number between 1 and 2 or number between 3 and 6 ...
```
上記の文字列指定ではフィールド名が "number" から違う名前に変わったとき正常に動作しません。
メタモデルを使用すると、この問題を解消できます。

```Group.java
@Entity
@Table(name ="group_member")
public class Group extends Artist {

    @Getter
    private int number;

}
```
上記エンティティのメタモデルを作成する場合、@StaticMetamodel(<Class.class>) アノテーションをつけて、該当のエンティティのクラス名の最後に "_" をつけたクラスを作成します。

```Group_.java
@StaticMetamodel(Group.class)
public class Group_ {
    public static volatile SingularAttribute<Group, Integer> number;
}
```

これにより下記のように Specification を記述できます。

```NumberSpecificationWithMetamodel.java
public class NumberSpecificationWithMetamodel {
    public static Specification<Group> members(Map<Integer, Integer> lowerUpper) {
        return (root, query, cb) -> {
            final Collection<Predicate> predicates = new ArrayList<>();
            lowerUpper.forEach((lower, upper) -> {
                predicates.add(
                        cb.and(cb.between(root.get(Group_.number), lower, upper))
                );

            });
            return cb.or(predicates.toArray(new Predicate[predicates.size()]));
        };
    }
}
```

しかしながら、上記実装において、Group_.number が Null になる現象が発生しました。

#解決策
非常に単純です。
[こちらのページ](https://stackoverflow.com/questions/3854687/jpa-hibernate-static-metamodel-attributes-not-populated-nullpointerexception) での示唆のように、メタモデルとエンティティを同じパッケージに配置したら問題は解消します。
SRE本まとめ（14章 インシデント管理）

自分の理解を深めるためにまとめてみました。[13章](https://qiita.com/bassbone/items/883cf21f5a1f44b8b1c2)の続きです。

## 14章 インシデント管理

### インシデント管理がうまくいっていないと？
インシデントの管理がうまくいっていないと、技術的な問題への過剰な集中が発生してしまい、コミュニケーション不足によりステークホルダーからの信頼悪化、勝手で不適切なリカバリによる二次災害等が起きてしまう。

### インシデント管理のプロセス
#### 役割分担
自分の役割を知り、他の誰かの領域に踏み込んでしまわないことが重要。これにより各人が自律的に動けるようになるから。具体的な役割としては以下がある。

- インシデント指揮者：全体の統制を取る。
- 実行担当者：障害復旧する。
- コミュニケーション担当者：対外的なコミュニケーションを受け持つ。さらにインシデントに関するドキュメントをメンテナンスする場合もある。
- 計画：再発防止を行う。

#### 明確な司令所
可能であれば一箇所に集まれるのがよいが、難しければチャットツールを有効活用するとよい。

#### ドキュメント
リアルタイムで更新が反映されていくようなドキュメントがあるとよい。GoogleのほとんどのチームはGoogle Docsを使っている。（ただし、Google DocsのSREチームはGoogle Sitesを使っている。）

#### 引き継ぎ
曖昧な引き継ぎはNG。

### インシデント管理のためのベストプラクティス

- 優先順位
- 準備
- 信頼
- 自己観察　<--- 意外とこれ大事！
- 代案の検討
- 訓練
- 持ち回り

（[15章](https://qiita.com/bassbone/items/11862caadd185c85889b)に続く）
「それ、もっとスマートに書けるよ」がもっとスマートに書けるよ

「[それ、もっとスマートに書けるよ](https://speakerdeck.com/wakamsha/sore-motutosumatonishu-keruyo-javascript-kodowomotutoduan-ku-motutosinpurunishu-ku-tips-4xuan)」がもっとスマートに書けるよ。


## ある特定の文字列が別の文字列内にあるかどうか

> ```js
> const ua = navigator.userAgent;
> 
> if (~ua.indexOf('iPhone') || ~ua.indexOf('iPod') || ~ua.indexOf('iPad')) {
>   return 'ios';
> } else {
>   return 'other';
> }
> ```

[String.prototype.includes()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes)を使いましょう。

```js
const ua = navigator.userAgent;

if (ua.includes('iPhone') || ua.includes('iPod') || ua.includes('iPad')) {
  return 'ios';
} else {
  return 'other';
}
```

※「それ、もっとスマートに書けるよ」を書いた人は`navigator.userAgent`を配列だと勘違いしていますが、`navigator.userAgent`は文字列です。（だから`ua.indexOf()`は[Array.prototype.indexOf()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)ではなくて[String.prototype.indexOf()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf)です。）「ある特定の要素が配列内にあるかどうか」を調べる場合は、[Array.prototype.includes()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes)を使いましょう。


## それ即時関数使わなくても出来るよ

> ```js
> const { foo, bar } = (() => {
>   if (new Date().getHours() < 12) {
>     return {
>       foo: 'forenoon',
>       bar: 'am'
>     }
>   } else {
>     return {
>       foo: 'afternoon',
>       bar: 'pm'
>     }
>   }
> })();
> ```

三項演算子を使いましょう。

```js
const { foo, bar } =
  new Date().getHours() < 12 ?
  { foo: 'forenoon', bar: 'am' } :
  { foo: 'afternoon', bar: 'pm' }
```


## URLクエリーパラメータのパース

> ```js
> const result = params.reduce((acc, param) => {
>   const pair = param.split('=');
>   acc[pair[0]] = decodeURIComponent(pair[1]);
>   return acc;
> }, {});
> ```

[URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)を使いましょう。

```js
const result = new URLSearchParams(params);
```
開発用サーバーを作る on AWS（Ruby on Rails 5）

# はじめに
まぁそのまんま。
[こちら](https://qiita.com/yutaka_izumaru/items/75176c639ec30086005a)のRubyonRails編。

Ruby 2.4.2
Ruby on Rails  5.1.4
なり。

Amazon Linux AMI+Nginx+Unicorn
やで。

### インストールなど

```shell-session
sudo yum update
sudo yum -y install git
sudo yum install nodejs --enablerepo=epel
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
source ~/.bash_profile
sudo yum install gcc openssl-devel readline-devel sqlite-devel
rbenv install 2.4.2
rbenv global 2.4.2
gem update --system
gem install --no-ri --no-rdoc rails
gem install bundler
gem install sqlite3
gem install unicorn
rbenv rehash
rails -v
rails new /var/www/html/sample
sudo mkdir /var/run/unicorn
sudo chmod 777 /var/run/unicorn
sudo chown -R nginx:ec2-user /var/www/html
sudo chmod 2777 /var/www -R
```

まぁ、だいぶ時間がかかりまっせ。

# sample/config/unicorn.rbを作成

```rb
application = 'sample'

worker_processes 2
timeout 15

pid "/var/run/unicorn/unicorn_#{application}.pid"
listen "/var/run/unicorn/unicorn_#{application}.sock"

preload_app true

before_fork do |server, worker|
  Signal.trap 'TERM' do
  puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
  Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
  ActiveRecord::Base.connection.disconnect!end

after_fork do |server, worker|
  Signal.trap 'TERM' do
  puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
  end

  defined?(ActiveRecord::Base) and
  ActiveRecord::Base.establish_connection
end

stderr_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])
stdout_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])
```

# 起動

```shell-session
bundle exec unicorn_rails -c config/unicorn.rb -E development -D
```

# OSの再起動対応
~/.bashrcに追記

```bash
sudo mkdir -p /var/run/unicorn && sudo chmod 777 /var/run/unicorn
```

# /etc/nginx/conf.d/sample.conf作成

```
upstream unicorn {
  server unix:/var/run/unicorn/unicorn_sample.sock;
}
server {
    listen 8080;
    server_name localhost;
    root /var/www/html/sample;

    access_log /var/log/nginx/myapp_access.log;
    error_log /var/log/nginx/myapp_error.log;

    try_files $uri/index.html $uri @unicorn;
    location @unicorn {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_pass http://unicorn;
    }
}
```

PHPを80で動かしてる都合上8080でごわす。

# Nginx再起動

```shell-session
sudo service nginx restart
```

いじょー
Security Groupで8080はあけておきましょうね。

# 追記
[こちら](https://qiita.com/yoshi111kazu/items/e8b29aa2b103f6e4ec03)を参考にinit.d作っておくと便利ですね。

by [株式会社Arrvis](http://www.arrvis.com/)
サンプルコードから始める Java EE 8 (NetBeans IDE 8.2使用) その１ 環境構築

# 遂にJava EE 8がリリース

Java EE 8 のリリースから２週間がたちました。Java One直前の突然の？（それとも計画的な？）正式リリースの発表に驚きましたね。

そんなJava EE 8を、IDE（NetBeans）の環境設定から提供されているサンプルプログラムを使用しながら若干応用も実験しながらお試しプログラムしてみました。

# まずは環境構築

## Java EE 8 SDK のダウンロードから

[Java EE 8 SDKのダウンロードページ](http://www.oracle.com/technetwork/java/javaee/downloads/index.html)
から、「Java EE 8 Platform SDK」の方をダウンロードします。（いろいろ試したいからね）

![javaee8_img001_ee_install_2.png](https://qiita-image-store.s3.amazonaws.com/0/105193/b8f352f2-0370-32d2-aec6-9271dfdcce7e.png)

当該ページに書いてあるとおり、SDKにはソースやAPIの他に

- コードサンプル
- APIドキュメント
- チュートリアル

そしてGlassfish 5 が内包されています。
ダウンロード後は解凍し任意のフォルダへ配置します。
今回はC直下（C:\java_ee_sdk-8\glassfish5）に配置しました。

## Netbeans 8.2 のインストール

[Netbeans8.2のダウンロードページ](https://netbeans.org/downloads/?pagelang=ja)
からダウンロード

![javaee8_img003_netbeans_dl_2.png](https://qiita-image-store.s3.amazonaws.com/0/105193/e0135549-e666-2105-d14c-57d0be2bbfda.png)

インストール時は画面に従って進みますが、最初の「IDEとともにインストールするアプリケーションサーバを選択」はGlassfish 4.1.1なのでチェックボックスを外し、インストーラでは入れないようにします。

![javaee8_img002_netbeans_install.png](https://qiita-image-store.s3.amazonaws.com/0/105193/2bfe43de-89d9-d51b-d942-90e7f4660b25.png)

## サーバ・インスタンスの追加

無事Netbeans8.2をインストールできたら、起動し
インストール時に入れなかったアプリケーションサーバを追加します。

### サーバを選択

メニュー > ツール > サーバ
からサーバ画面をだして、「サーバーの追加」ボタンを押下してサーバ・インタンスの追加を行います。
サーバ：GlassFish Server
名前：（各自任意で）
「次へ」

### サーバーの場所
インストール場所：C:\java_ee_sdk-8\glassfish5（※先ほど配置したGlassFish 5(JavaEE8)の場所を指定）
●ローカルドメイン
ライセンス契約を～のチェックボックスをリンク先を読んでチェック
「次へ」

### ドメインの場所

ドメイン：domain1（デフォルト）
ホスト：localhost（ループバックはチェック）
DASポート：4848
HTTPポート：8080
※その他は未入力。別途サーバを追加していない限りはこのデフォルト設定で問題ないはず
「終了」

これでJava EE 8 / GlassFish 5の環境は整いました
以下ちゃんとサーバタイプが読めてるーの図

![javaee8_img005_netbean_servertype.png](https://qiita-image-store.s3.amazonaws.com/0/105193/fb8e323e-3b78-1a45-93f1-e2588a09eb9b.png)

----
ちなみにEclipseの最新版（現在はOxgen）でもサーバ設定はGlassFish 3.xか4.xまでしか認められません。embedded環境などを別途用意してテストします。

![javaee8_img004_eclipse_err._3.png](https://qiita-image-store.s3.amazonaws.com/0/105193/17bbd5ed-564f-2493-3661-beab1aa934ef.png)

# サンプルプログラムの作成は次回

配置先をC:\java_ee_sdk-8\glassfish5としてサンプルとチュートリアルとAPI仕様の場所を書いておきます。

## サンプルプログラム

サンプルは
C:\java_ee_sdk-8\glassfish5\samples
ネット上だとgithubで[こちら](https://github.com/javaee/tutorial-examples)
にどんどん追加されていってる。

## チュートリアル

チュートリアルは
C:\java_ee_sdk-8\glassfish5\docs\javaee-tutorial\doc
ネット上だと[ココ](https://javaee.github.io/tutorial/toc.html)でよいのかしら。。。

## APIリファレンス（API仕様）

APIドキュメントは
C:\java_ee_sdk-8\glassfish5\docs\api\javaee-full
ネットだと[ココ（API）](https://docs.oracle.com/javase/jp/8/docs/api/)

次回があれば、プロジェクト作成してみます。
kaggle-cliでデータをダウンロードする

# 追記

[Kaggle公式のツール](https://github.com/Kaggle/kaggle-api)がでました。
以下で紹介するkaggle-cliより公式のものを使うことをおすすめします。

---

KaggleをAWSなどのクラウドで学習をまわす場合、データが数十GBもあると、ローカルにダウンロードしてからクラウドに送るのは大変ですよね。

そこで、[kaggle-cli](https://github.com/floydwch/kaggle-cli)という便利なツールがあるので、紹介します。

# インストール

```
$ pip install kaggle-cli
```

# データのダウンロード

ユーザ名、パスワード、コンペ名を指定してダウンロードできます。

```
$ kg download -u <username> -p <password> -c <competition>
```

事前に、コンペのルールにacceptしていないとダウンロードできません。
Googleアカウントなどでログインしていてパスワードがない場合は、[パスワードを設定](https://www.kaggle.com/forgot/password)する必要があります。

## 特定のファイルのみダウンロード

```
$ kg download -u <username> -p <password> -c <competition> -f train.zip
```

# config設定

```
$ kg config -u <username> -p <password> -c <competition>
```

とすると、`.kaggle-cli/`にファイルが作成され、コマンドを実行するときにオプションが不要になります。

# その他

その他、submitもできます。詳しくは、[Githubのページ](https://github.com/floydwch/kaggle-cli)を参照ください。
rebaseフロー



```
git checkout branch-name
git pull --rebase origin master
(confilict箇所直して)
git add .
git rebase --continue
git push -f origin branch-name
```


*********************************************************
エンジニアがPullrequestにレビューをして副収入を得られるサービスを始めました。
<a href="https://www.reviewers.center/" target="_blank" rel="noopener noreferrer">Reviewers</a>
*********************************************************
sqlite3 で 最後に更新した行のデータを取得したい。

色々調べてみた結果。

**IDを自動で入れていないとしても
挿入したデータの日付さえ入っていれば** 

```sqlite3
SELECT max(date), <value1> FROM <TABLE>;
```

というSQL文で取得できる。
内容は簡単で、

date というカラムに入ってる
日付の情報を **max(date)** という
関数を使って、日付の数値が最大のもの＝最新
の行を取得するという方法。

Google先生で検索したけどうまく引っかからなかったため、
備忘録も兼ねてメモしておくことに。

余談

```sqlite3
SELECT * FROM <TABLE> ORDER BY <date_column> DESC LIMIT 5;
```

このSELECT文で最新から５つ取り出すとかできた。
Xcodeからのリモートの登録Xcode9.0(変わっていたので)

いつものようにgithubにSampleをプッシュするためにリモートの登録の方法が変更されていたので、又焦らないようにここに書いときます。誰かもう書いてたりして…:shamrock:なんとなく最後おまけとして今までの方法を書いてみました。

**いつも同じみのところの上の方にある**
<img width="267" alt="スクリーンショット 2017-10-08 0.45.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/133940/b957e3ca-7d03-8591-1a2b-fee8e0b91931.png">
**この印をクリック。今までのヒストリーの見え方も変わりましたよね(｡･ω･｡)**
<img width="32" alt="スクリーンショット 2017-10-08 0.45.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/133940/01eb3a14-4320-9afa-2742-a6828a43532f.png">
**自分がリモートに反映するブランチのところを選択**
<img width="272" alt="スクリーンショット 2017-10-08 0.45.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/133940/94e992b6-1ebe-c385-536d-278d61446d29.png">
**その後上部の**
<img width="861" alt="スクリーンショット 2017-10-08 0.45.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/133940/7c8e9082-5062-4f3d-586b-8784e5249f7f.png">
**EditorのAdd Existing Remoteを選択**
<img width="219" alt="スクリーンショット 2017-10-08 0.46.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/133940/2f2eb413-2b9f-8b94-7ca5-555282f53e7f.png">
**この画面、この画面というような感じでここに登録すればあとは同じみにという感じです。**
<img width="487" alt="スクリーンショット 2017-10-08 0.46.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/133940/8ce30c64-818b-4bbe-ffef-cbf81deee3d4.png">



**ちなみに今までは(おまけ)**
<img width="469" alt="スクリーンショット 2017-10-08 0.52.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/133940/91a13ef3-e1f6-74e1-bd82-b01415096fd2.png">
<img width="706" alt="スクリーンショット 2017-10-08 0.52.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/133940/6dfdc2f1-07aa-bcae-bce4-fc65b559edb5.png">
<img width="497" alt="スクリーンショット 2017-10-08 0.52.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/133940/9bf9bd3c-ab13-e5a9-1156-ad0ee2bd13fe.png">

こんな順序でした(｡･ω･｡)
ANDROID JSON Create


Method use:

	JSONObject jsonRegister = JSONBuilt(mailString, passwordString);
	
	
Method: 
    
    private JSONObject JSONBuilt(String mailString, String passwordString) {
        final JSONObject jsonRegister = new JSONObject();

        try {
            jsonRegister.put("mail", mailString);
            jsonRegister.put("password", passwordString);

        } catch (JSONException e) {
            e.printStackTrace();
        }

        Log.v("Kronox", jsonRegister.toString());
        return jsonRegister;
    }
ANDROID HTTP POST


	public void saveDni(String id, String dni) {     
 
	HttpClient httpclient = new DefaultHttpClient();     
	HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");      
 
	try {         
		//Añade las variables a enviar por post         
		List<NameValuePair> postValues = new ArrayList<NameValuePair>(2);         
		postValues.add(new BasicNameValuePair("id", "000001"));         
		postValues.add(new BasicNameValuePair("dni", "23234345T"));         
 
		httppost.setEntity(new UrlEncodedFormEntity(postValues));          
 
		//Hace la petición         
		HttpResponse response = httpclient.execute(httppost);              
	} 
	catch (ClientProtocolException e) {         
		//TODO Auto-generated catch block     
	} 
	catch (IOException e) {         
		//TODO Auto-generated catch block     
	} 
 	}
Ruby2.5で導入されるyield_selfについて


`Object#yield_self`が導入されます。`tap`と違って`yield`の戻り値がそのまま`yield_self`の戻り値となっています。

```ruby
class Object
  def yield_self(*args)
    yield(self, *args)
  end
end
```

引用：https://bugs.ruby-lang.org/issues/6721

```ruby
class Kernel
  def tap
    yield self
    self
  end
end
```

引用：[Rubinius](https://github.com/rubinius/rubinius/blob/b836b1b14f402c1744b16f8e11e72bbab73938a3/core/kernel.rb#L914)

これを見たときになんとなくパイプライン演算子ぽいなと思いました。Elixirでやるとこんな感じです。

```elixir
IO.puts "I love Elixir"
        |> String.upcase
        |> String.reverse

# RIXILE EVOL I と表示されます
```

もし、Ruby2.5になったらこんな感じにかけます。

```ruby
class Object
  def yield_self(*args)
    yield(self, *args)
  end
end

puts "I love Ruby"
     .yield_self(&:upcase)
     .yield_self(&:reverse)

# YBUR EVOL I と表示されます。
```

Elixirはファンクションの第一引数に次々に値をセットしている一方で、Rubyは`yield`の戻り値をチェーンしています。~~プログラミングの幅が広がればよいですが、いまのところベストプラクティスは思いつきません:sweat_smile:~~と思っていたのですが、頂いたコメントからヒントを得ることができました:tada: 

`tap`では`break`を利用して戻り値に無理やりしていたことを自然に書くことが出来ます。文字列や整数の結果をチェーンするのを思いついたのですが、ステップごとに異なるクラスのインスタンスに変化していくときに活躍しそうです！（Elixirでの例とおんなじですね:smile:）

```ruby
require 'net/http'

class Object
  def yield_self(*args)
    yield(self, *args)
  end
end

uri = 'https://www.libertyfish.co.jp/'
puts uri.yield_self(&URI.method(:parse))
        .yield_self(&Net::HTTP.method(:get_response))
        .code
# ステータスの200が表示される
```

蛇足ですが、`tap`と似たようなものだと思って`yield_self`に渡すブロックで破壊的メソッドを使った場合は思ってたのと違う！というのが起こりそうですね。

```ruby
class Object
  def yield_self(*args)
    yield(self, *args)
  end
end

puts "HELLO"
     .yield_self{|greet| greet.upcase!}

# すでに大文字であれば、`upcase!`の戻り値は`nil`

puts "HELLO"
     .yield_self{|greet| greet.upcase}

# すでに大文字であっても、"HELLO"

puts "HELLO"
     .tap{|greet| greet.upcase!}

# すでに大文字であっても、"HELLO"

puts "HELLO"
     .tap{|greet| greet.upcase}

# すでに大文字であっても、"HELLO"
```
SRE本まとめ（13章 緊急対応）

自分の理解を深めるためにまとめてみました。[12章](https://qiita.com/bassbone/items/3ed4fe9aba370e8a439c)の続きです。

## 13章 緊急対応

### テストによって引き起こされた緊急事態
Googleは、ひどい障害や緊急事態のテストについて、予防的なアプローチを採用している。SREはシステムに障害を起こさせ、その障害の様子を観察し、そして信頼性を向上し障害が再発しないようにするための改善を行う。しかし想定と実際の結果が大きく異なることもあり、不測の事態を起こすこともある。

### 変更が引き起こした緊急事態
Googleには数多くの複雑な設定があり、それらの設定には常に変更が加えられている。不測の事態が起きないようにしているが、Googleのインフラストラクチャの規模と複雑さゆえに、全ての依存関係や関連性を予測することは不可能であり、設定変更が完全に計画通りには進まないこともある。

### プロセスが引き起こした緊急事態
大量のマシンを管理するための自動化に相当の時間とエネルギーをつぎ込んでいる。きわめてわずかな労力だけで大量のマシン上で多数のジョブを起動し、停止し、再構成できるのは驚くべきこと。自動化の効率性は、物事が完全に計画通りにいかなかった場合には少々恐ろしいものがある。

### 解決できない問題は存在しない
Googleが学んだ中で最も大きなことは、必ず解決策は存在するものである。最も優先すべきなのは、目の前の問題を素早く解決することであるため、そのためにはできることは何でもすべき。

### 過去から学び、繰り返さない
障害から学びを得るための最も良い方法は、過去に何が壊れたのかを書き記しておくこと。徹底的に、誠実に、そして何より厳しい問いを投げかけること。大局的な見地から考えること。現実以上に大きなテストは無い。より規模の大きい問いかけを自身に投げかけ、不測の事態を想定してみる。障害に関しては理論と現実は大きく異なる。というのも、実際に障害を起こすまではシステムがどのように振る舞うのかはわからない。

（[14章](https://qiita.com/bassbone/items/cb3501fe4bbad4c9b514)に続く）
ちょっとずつ読むドメイン駆動設計 第ニ部 モデル駆動設計の構成要素 第五章 ソフトウェアで表現されたモデル11(モデリングパラダイム) 

# モデリングパラダイム

こんなトピックがあったのかと、改めて読んでみました。

基本は、広く使われてもいるオブジェクト指向設計でのモデリング。

ここまで広まった理由はシンプルかつ洗練されているから。ドメイン駆動設計では、技術寄りでないメンバーも参加する。

> チームにいる技術よりでないメンバが、少なくともパラダイムの初歩を把握することができなければ、モデルを理解することもできず、ユビキタス言語が失われることになる。(第ニ部 第五章 より)

さらに、インフラストラクチャのツールサポートも充実している。開発者も見つけやすい。

## 他のパラダイムとの混合

> プロジェクトにおいて、支配的なモデルパラダイムが何であれ、ドメインの中には、他のパラダイムならばはるかに容易に表現できる場所が必ずあるものだ。(第ニ部 第五章 より)

こういうときに、例えばルールエンジンやワークフローエンジンなんかは統合しやすいと言っています（使ったことはないですが・・・

ルールエンジンを使用する場合、こういったルールとオブジェクトをシームレスにつなぐ環境が必要になります。最も効果的なツールは**ユビキタス言語**。モデル駆動設計に忠実であることがコツになりそうですね。

## RDB

このパラダイムは特殊。なぜならオブジェクトそのものを構成するデータの、永続ストレージとして機能するからです。
６章のレポジトリで詳しく解説されると思います。

RDBのパラダイムはオブジェクト指向のパラダイムとは別のパラダイムとして（当然）上げられています。
ゆえに、オブジェクト指向のパラダイムで作られたドメインのモデルとRDBのテーブル設計・モデルは別物であるということですね。

RDBのテーブルとモデルを関連付ける、RailsのActiveRecordはモデル駆動設計をするのには向いてないフレームワークといえるかもしれません。