OmniAICreator/Qiita-1.07M huggingface dataset:
PHP の「http_build_query()」で「%5B0%5D」の自動挿入

## TL;DR （その値、文字列ですか？）

> 「%5B0%5D」は文字列「[0]」を URL エンコードしたもの

PHP の`http_build_query`関数を使う際、第１引数に渡す配列に注意する必要があります。
というのも、**配列の値（value）が文字列以外の場合はキー名に「[n]」が付加される**からです。

```php:パターン１
/* パターン1 */
$params = http_build_query([
    'hoge' => ['fuga'],
]);

echo $params . PHP_EOL;
echo urldecode($params) . PHP_EOL;

// 出力結果（'hoge'のキー名に"%5B0%5D"が付いてしまう）
//
// hoge%5B0%5D=fuga
// hoge[0]=fuga
```

```php:パターン２
/* パターン2 */
$params = http_build_query([
    'foo'  => 'bar',
    'hoge' => ['huga', 'piyo']
]);

echo $params . PHP_EOL;
echo urldecode($params) . PHP_EOL;

// 出力結果（'hoge'のキーに"%5B?%5D"が付くが'foo'のキーには付かない）
//
// foo=bar&hoge%5B0%5D=huga&hoge%5B1%5D=piyo
// foo=bar&hoge[0]=huga&hoge[1]=piyo
```

```php
/* 受け手（POST/GET先）の仕様上どうしても消したい場合は置き換える（削除する） */
$params = preg_replace('/%5B(\d+?)%5D/', '', $params);
echo $params . PHP_EOL;

// 出力結果
//foo=bar&hoge=huga&hoge=piyo

```

## 所感

実家の WiFi ルーターが、WiFi カメラを設置してから調子が悪く（同じカメラのセッションが大量に残ってしまうため）定期的な再起動が必要になりました。

病院提出用にトイレの回数を取るために使っていたラズパイ3と AmazonDashButton（ADB） があったので、ADB でルータを再起動させたいと思いました。しかし、`curl` で叩くと正常に再起動するのに、PHP で書いた CLI スクリプトが動かない。

出力した内容（POST する内容）をよくよく見ると「%5B0%5D」という見慣れない文字列が入っていました。

どうやらルータを再起動するために必要なセッション ID を取得する為に使った `DOMDocument()` で XML（リブートのページ）から抜き出したフォームの `value` 属性値がオブジェクトのままだったようです。アチョンブリケ。

### 参考文献
- "[PHP:http_build_query](http://php.net/manual/ja/function.http-build-query.php) | manual @ PHP.net
- "[Strip http_build_query string of %5B and %5D](https://www.reddit.com/r/PHPhelp/comments/3pd126/strip_http_build_query_string_of_5b_and_5d/)" @ reddit.com
heroku環境でmb_xxx関数を使うと、Fatal error: Call to undefined function …のエラーが表示される

Fatal error: Call to undefined function …っていうのは、
「深刻なエラーです：未定義の関数を呼び出しています」ってことですね。
このエラーが出る場合によくあるのが、マルチバイト関数が無効化されている状態でマルチバイト関数を呼び出しているケースです。

マルチバイト関数というのは、マルチバイト文字（日本語など）用の関数群で、mb_strpos()、mb_substr()、mb_strlen()などがあります。

特に、herokuのphp環境は、マルチバイト関数がデフォルトで無効の設定になっているので、どっかで調べてきて使おうとしてもエラーが表示されて使えません。

ちなみに、ローカル環境でしたら、php.iniのコメントアウトを消去することでマルチバイト関数を有効にします。

```php.ini
;extension=php_mbstring.dll
```

この行のコメントアウト、";"を取り除けば、マルチバイト関数が有効になります。

しかし、heroku環境ではデプロイ環境のphp.iniをいじることができません。
さて本題です。
herokuでマルチバイト関数を有効にするには、composerに"ext-mbstring"を追加してPushします。

```composer.json
"require": {
  "ext-mbstring": "*"
},
```

こんな感じ。
あと、忘れてはいけないのがcomposer.lockの更新です。
CLI（Windowsならコマンドプロンプト）を開いて、アプリケーションのFile上で、composer updateコマンドを叩きます。

```コマンドプロンプト.
...\heroku\アプリ名> composer update
```

私はこれに気づかずしばらくうんうん言ってましたｗ

以上の手順を踏めば、マルチバイト関数が使えるようになるはずになり、原因が正しい場合は、エラーも解決されるはずです。

参考：
[Heroku上でmbstringなどcomposerを用いて、有効にする方法-雄大スタジアム](http://yudai-stadium.com/blog/heroku-mbstring/)
[「Fatal error: Call to undefined function …」と表示されるとき-PHPプログラミングの教科書 [php1st.com]](https://php1st.com/419/)
firestoreでタグ検索とか

firestoreのwhere句で1時間くらいハマったのでメモ。
## TL;DR
firestoreで、全てのcatカテゴリーが登録されてるデータを取得したい場合、カテゴリーObjectに```cat: マップ値```のデータを登録するが
```new Date()```ではなく```Date.parse(new Date())```のように正しくマップ値に変換して登録しないと```where('categories.cat', '>', 0)```は解釈できない。 
そりゃそうだ。

## 公式Doc

> ### [cloud firestore: 配列、リスト、セットの操作](https://firebase.google.com/docs/firestore/solutions/arrays?hl=ja)
> 
```js
// The value of each entry in 'categories' is a unix timestamp
{
  title: "My great post",
  categories: {
    technology: 1502144665,
    opinion: 1502144665,
    cats: 1502144665
  }
}
```
> 範囲フィルタを使用して複数のフィールドにクエリを実行するには、複合インデックスが必要です。しかし、上記の手法ではこれが不可能です。インデックスは、特定のフィールドパスに定義する必要があります。したがって、categories.cats や categories.opinion などの可能なフィールドパスごとにインデックスを作成しなければなりませんが、カテゴリがユーザー生成されている場合にはこれを事前に行うことができません。
> 
> この制限を回避するには、クエリのすべての情報をマップ値にエンコードします。
> 
> 有効なクエリ
>
```js
 db.collection('posts')
    .where('categories.cats', '>', 0)
    .orderBy('categories.cats');
)
```

上記のようなfirestore設計、
フィールドの値をマップ値にエンコードすることで、categoriesにcatが存在する全てのドキュメントをorderBy込みで取得可能になります。


## ハマった点

タイムスタンプ入れとけばいいのか〜と、そのまま```new Date()```入れていたので```where(`members.${userId}`, '>', 0)```は解釈できなかった。 
```new Date()```ではなく```Date.parse(new Date())```を保存が正しい。


#### sample document (firestore)
<img width="403" alt="スクリーンショット 2018-02-22 2.46.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/12153/4546681b-5b68-a287-2d29-8c9f2a440884.png">

#### 修正済みコード

```js
// save
export const addSampleCollection = async ({ commit }, { doc }) => {
  const now = new Date()
  let members = {}
  // members[doc.author] = now          // [NG] 2018年2月22~~ (タイムスタンプ)
  members[doc.author] = Date.parse(now) // [OK] 151923~~~
  await docsRef.add({
    author: doc.author,
    members: members,
    release_at: doc.release_at
    title: doc.title,
    create_at: now,
    update_at: now,
  }).then(function () {
    console.log('[success] addDoc')
  }).catch(function (error) {
    console.log('[error] addDoc', error)
  })
}

// get
export const getSampleCollectionDoc = async ({ commit }, { userId }) => {
  let query = await partiesRef.where(`members.${userId}`, '>', 0).get()
    .then(function (querySnapshot) {
      querySnapshot.forEach(function (doc) {
        console.log(doc.id, ' => ', doc.data())
      })
    })
    .catch(function (error) {
      console.log('Error getting documents: ', error)
    })
}
```

画像のとおり、firestore上の```member.uri_m```に正しく数字が登録されており、where区は正しく働く。
Azure Cosmos DBをMongoDBとしてNode.jsから使ってみる


MongoDB利用を検討して調べていて見つけたので試しに使ってみます。

* macOS High Sierra
* Node.js v9.5.0
* Mongoose v5.0.6

です。

## Azure Cosmos DB

https://docs.microsoft.com/ja-jp/azure/cosmos-db/

![](https://i.gyazo.com/9af773bf429edd542a0cd7043c4199d8.jpg)

宇宙感あってかっこいい。

機能は

```
待機時間が非常に短く、極めてスケーラブルなアプリケーションを世界中どこでも実現する、NoSQL のネイティブ サポートが付いたデータベース
Azure Cosmos DB は、グローバル分散と水平方向への拡張性を中心として一から構築されました。透過的なスケーリングとあらゆる場所のユーザーへのデータ レプリケーションにより、使い始めてすぐに任意の数の Azure リージョン全体でグローバル分散を実現できます。世界中でスループットとストレージを弾力的にスケーリングでき、お支払いは必要な分のみとなります。Azure Cosmos DB では、NoSQL の各オプションをネイティブでサポートしており、明確でわかりやすい複数の整合性モデルを提供しています。また、99 パーセントで 10 ミリ秒未満の待機時間を保証すると同時に、マルチホーム機能による高可用性と、世界中のあらゆる場所での短い待機時間を保証します。これらはすべて、業界トップレベルの包括的なサービス レベル アグリーメント (SLA) の対象となります。
```

らしいです。

AWS系もGCP系もこの手の文句は似てるのでそこまで気にしてないやつです()

## MongoDBとして利用

作成はAzure使ってる人なら通常なポータル画面からリソース作成でいけます。

APIの箇所でMongoDBって選択できますね。

![](https://i.gyazo.com/41fa54ff4a46ac8654b5200133b09fda.png)

## Mongooseから利用する

[Azure Cosmos DB: Azure Cosmos DB で Mongoose フレームワークを使用する](https://docs.microsoft.com/ja-jp/azure/cosmos-db/mongodb-mongoose)というAzure公式のチュートリアルはあるのですが、参考にはなるのですが、 **そのままやっても動かなかったのでmongooseの公式ページを参考にして書いた方がよさそう**です。

```bash
mkdir cosmos
cd cosmos
npm init -y
npm i --save dotenv mongoose
```

チュートリアルを参考に[dotenv](https://www.npmjs.com/package/dotenv)で環境変数利用します。

`app.js`を作成して[mongooseの公式](http://mongoosejs.com/)サンプルを参考に接続コードを作ってみます。

```app.js
'use strict';

const mongoose = require('mongoose');
const dotenv = require('dotenv').config();

const authParams = {
    auth:{
        user: process.env.COSMOSDB_USER,
        password: process.env.COSMOSDB_PASS,
    }
};

mongoose.connect(process.env.COSMOSDB_HOST,authParams);

const Cat = mongoose.model('Cat', { name: String });
const kitty = new Cat({ name: 'のびすけ' });
kitty.save().then(() => console.log('meow'));
```

`.env`ファイルを作成して、ユーザー名パスワード、ホスト情報を記述します。

AzureのCosmos DB管理画面の接続文字列の画面から確認できます。
![](https://i.gyazo.com/e834dacadef99c303c19fefd735a6cc1.png)

```.env
COSMOSDB_USER=""
COSMOSDB_PASS=""
COSMOSDB_HOST="mongodb://xxxxxxxx.documents.azure.com:10255/?ssl=true&replicaSet=globaldb"
```

実行すると`catsコレクション`が作成されて`のびすけ`というデータが保存されます。

## クライアントアプリからデータの確認を利用してみる

[Robo 3T](https://robomongo.org/)を利用してみました。

![](https://i.gyazo.com/07b23b62f7ea5fe78d8e821d7671ca0b.png)

ちゃんと`のびすけ`ってデータが入ってました。

## 所感

まだ全然使ってないですが、MongoDBのセットアップを素でやるとけっこう大変だった印象があるので、セットアップの時間がほぼかからずに利用開始できるのは魅力的でした。

もっと使っていかないと良さみは分からなのでもうちょい触ってみます。

## 補足: 出てたエラー

Azure側のチュートリアルのコードを利用すると`Error: Password contains an illegal unescaped character`というエラーが出ます(2018年2月時点)。
Stack Over Flowの[Cannot connect to MongoDB in Azure](https://stackoverflow.com/questions/48029723/cannot-connect-to-mongodb-in-azure)によると特殊文字列が`connect()`のところで使えないようになったみたいで、別途以下のようなオブジェクトを用意する必要があるとのことです。MongooseのバージョンなのかMongo DBのバージョンなのか。

```
auth: {
       user: 'username',
       password: 'p@ssword',
    }
```

という感じで今回のコードに落ち着きました。
React+Material-UIなコンポーネントをEnzymeでテスト

通常ReactのコンポーネントをEnzymeを使ってテストするには以下のように記述する感じ。

```javascript
import React from 'react';
import { expect } from 'chai';
import { shallow, mount } from 'enzyme';
import sinon from 'sinon';
import MyComponent from './MyComponent';


it('renders without crashing', () => {
  const wrapper = mount(<MyComponent />);
  expect(wrapper.find("input[type='text']").length).to.equal(0);
});
```

しかし、この `MyComponent` が Material-UI に依存している場合はテストを実行すると以下のようなエラーが出てしまいます。

```
Warning: Failed context type: The context `muiTheme` is marked as required in `TextField`, but its value is `undefined`.
```

このエラーの意味は、`MyComponent` が `muiTheme` を必要としているよということなので、以下のように `<MuiThemeProvider />` で囲むとエラーが出なくなります。

```javascript
const wrapper = mount(<MuiThemeProvider><MyComponent /></MuiThemeProvider>);
```

でもこれでエラーが引っ込んだとしても、`wrapper.props()` や `wrapper.state()` にうまいことアクセスできなかったりするので、テストをいい感じに記述することができません。

## 解決策

この問題を解決するには、以下のようにテストを記述することで解決できます。

```javascript
import React from 'react';
import { expect } from 'chai';
import { shallow, mount } from 'enzyme';
import sinon from 'sinon';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import PropTypes from 'prop-types';
import MyComponent from './MyComponent';

const muiTheme = getMuiTheme();

it('renders without crashing', () => {
  const wrapper = mount(<MyComponent />, {
    context: { muiTheme },
    childContextTypes: { muiTheme: PropTypes.object },
  });
  
  expect(wrapper.find("input[type='text']").length).to.equal(0);
});
```

ポイントは以下の部分。

```javascript
const wrapper = mount(<PasswordField id="hello" name="world" />, {
  context: { muiTheme },
  childContextTypes: { muiTheme: PropTypes.object },
});
```

あと、これに必要な以下のモジュールをロードしているところです。

```javascript
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import PropTypes from 'prop-types';

const muiTheme = getMuiTheme();
```
iOS アプリでマルチタスク切り替え画面に入ったことを検出する話

小ネタです。アプリがアクティブなときに、マルチタスク切り替え画面(ホームキー二連打)に入ったことを検出したい。

# 結論

マルチタスク切り替えそのもの画面に入ったことそのものは検出できないが、マルチタスク切り替え画面に入るとアプリケーションは `Inactive` になるので、たとえば `UIApplicationWillResignActive` を購読しておけばそれで検出できる。通知センターやコントロールセンターを開いた場合もアプリケーションは `Inactive` になるので厳密な見分けが必要な場合はもう少し考えなければいけないかも。

# iOS アプリのライフサイクル

アプリにまつわるイベントであると考えられるので、 [Execution States for Apps](https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html#//apple_ref/doc/uid/TP40007072-CH2-SW3) を見ましょう。これは散々引用されてますしみなさん一度は見たことがあると思います。

| State | Description |
|:--|:--|
| Not running | The app has not been launched or was running but was terminated by the system. |
| Inactive | The app is running in the foreground but is currently not receiving events. (It may be executing other code though.) An app usually stays in this state only briefly as it transitions to a different state. |
| Active | The app is running in the foreground and is receiving events. This is the normal mode for foreground apps. |
| Background | The app is in the background and executing code. Most apps enter this state briefly on their way to being suspended. However, an app that requests extra execution time may remain in this state for a period of time. In addition, an app being launched directly into the background enters this state instead of the inactive state. For information about how to execute code while in the background, see Background Execution. |
| Suspended | The app is in the background but is not executing code. The system moves apps to this state automatically and does not notify them before doing so. While suspended, an app remains in memory but does not execute any code. When a low-memory condition occurs, the system may purge suspended apps without notice to make more space for the foreground app.|

# Inactive

アプリケーションライフサイクルのイメージとしては

```
Not running
　↓
Inactive
　↓
Active
　↓↑
Inactive
　↓↑
Background
```

ではないかと思います。 Notification で `UIApplicationDidEnterBackground` はよく使うと思いますが、 `UIApplicationWillResignActive` は通り過ぎるだけでなにに使うんだ...？

`Inactive` の説明を読んでみると

> The app is running in the foreground but is currently not receiving events. (It may be executing other code though.) An app usually stays in this state only briefly as it transitions to a different state.

アプリケーションは通常、状態遷移する一瞬この状態になると言っています。やっぱり通過するだけ？

# フォアグラウンドだけど UI イベントだけ受け取らない状態

`Inactive` の説明の前半にはこうも書いてあります。`Inactive` なアプリケーションはフォアグラウンドにいるけれど UI イベントは受け取らないよ。

よくよく考えると __マルチタスク切り替え画面__ はまさにこの状態に当てはまります。 ~~エスパーじゃないと気づけないと思うんですが。~~

さらによくよく考えると、マルチタスク切り替え画面以外にもアプリケーションはフォアグラウンドだけれど UI イベントを取らない状態があります。__通知センター__ や __コントロールセンター__ を開いた時もこの状態になります。よく出来てますね。~~でも遷移中一瞬なる状態だよって説明は消したほうがいいと思う。~~

というわけで、アプリケーションの状態が `Inactive` になる時を見ていればほぼ目的は達成できそうです。

おしまい。
`&&` と `||` のショートサーキット評価を利用したトリッキーな bash script の書き方

## tl;dr

次のような処理を行う関数を考える。

```
成功した時は "succeed" を出力して、終了コードは `0`
失敗した時は "failed" を出力して、終了コードは `1`
```

次に書いた `straight` 関数と `tricky` 関数の挙動は同じ。

```bash
straight() {
  if $(run-command) ; then
    echo "succeed"
    return 0
  else
    echo "failed"
    return 1
  fi
}

tricky() {
  { $(run-command) && echo "succeed"; } || { echo "failed" && false; } 
}
```

普段からこの形式で書くことはオススメはしないけど、ちょっとした時の tips として役に立つやも

## 背景

元々は「成功したら成功メッセージを書く」という処理を書いていたのだけど失敗した時の値を取りたいと思ったのがきっかけ。

```bash
# 元々のコード。ちょっとしたテストコード的なもの
assert() {
  local cmd=$1
  local expect=$2
  local actual=$($cmd)

  [[ "$actual" == *"$expect"* ]] && echo "succeed" >&2
}
```

:point_up_2_tone3: このコードを、殆ど手直しすること無くデバッグ用のダンプを出そうとした結果

こうなった :point_down_tone3:

```bash
# 変更後のコード。元のコードに殆ど手を加える必要がなかった事が勝因
assert() {
  local cmd=$1
  local expect=$2
  local actual=$($cmd)

  { [[ "$actual" == *"$expect"* ]] && echo "succeed" >&2; } \
    || { echo "Actual: $actual" && false; }
}
```

`true` コマンド、 `false` コマンドを使ったシンプルなバージョンに落とし込むと何が起きているか分かりやすい。

```shell-session
$ { true && echo "true"; } || { echo "false" && false; }
true
$ echo $?
0
$ { false && echo "true"; } || { echo "false" && false; }
false
$ echo $?
1
```

`true` の時はそのまま `&&` 演算子の右辺の `echo "true"` が実行される。
この時どちらも成功ステータスなので `{ true && echo "true"; }` の結果は成功ステータス。
そうすると `||` 演算子の挙動で右辺の評価はスキップされ、かつ成功ステータスが確定する。

ちなみに最初の値の結果によって右辺の評価をスキップする、この挙動を [_ショートサーキット評価_](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_Operators#.E3.82.B7.E3.83.A7.E3.83.BC.E3.83.88.E3.82.B5.E3.83.BC.E3.82.AD.E3.83.83.E3.83.88.E8.A9.95.E4.BE.A1) と呼ぶらしい

逆に `false` の時は最初の `&&` がショートサーキット評価により失敗ステータスで確定する。
なのでそのまま次の `||` 演算子の右辺が評価される。今度は `echo "false"` は成功するものの、そのまま右辺も評価され、 `false` があることで失敗ステータスであることが確定する。

`{}` を使ってグルーピングしているのは評価の順番を確実にしたかった為。（というか思ったように動いてくれなかったため←）
`{}` のグルーピングはちゃんとセミコロン `;` で終わらせないと syntax error になるのも注意

## ちなみに
echo 関数が失敗したらこちらの目論見は見事に失敗します。
まぁデバッグ用だし、echo コマンドがそうそう失敗するわけないよねと高をくくっている実装です。

## つまりは

日々の利用にはオススメしません。
draggable な親の contenteditable な子の挙動について

# contenteditable 要素

div 要素などの直接編集などブラウザ上で直感的に操作可能となる属性だが・・・

# draggable 要素の子 (あるいは孫) 要素としての contenteditable 要素

複数のブラウザ間での挙動の違いにより実装として利用する際に注意が必要な模様

```html:draggableParent-contenteditableChild
<div draggable="true">
  draggable
  <div contenteditable="true">content editable</div>
</div>
```

## Chrome

contenteditable, draggable それぞれの期待される挙動が確認される

* contenteditable 要素内においてはクリックした箇所にカーソル (キャレット) が移動する
* draggable 属性を持つ要素についてドラッグ (&ドロップ) が可能

## FireFox

* HTML の記述のみでは draggable による挙動は実現されない
* `draggable="true"` となる親要素を持つ `contenteditable="true"` の要素において
  クリックによるカーソル位置が要素の先頭となる

  * 十字キーなどで移動したのち、一度フォーカスを外して (onblur)   
    再度フォーカスしたところカーソル位置が変更されていないようなので  
    クリックによるカーソル移動が行われないと思われる

## Microsoft Edge

* シングルクリックでは contenteditable 要素にフォーカスしない
* ダブルクリックにて初めて contenteditable 要素へのフォーカスが行われる
* ただしクリックによるカーソルの移動については  
  Firefox と同様にクリックによるカーソル移動は行われなかった

# 属性の指定、変更による解決

親、あるいは先祖となる要素に `draggable="true"` となる要素が存在しなければ
contenteditable な要素に対しクリックがそのまま編集個所の指定となりそう・・

```html
<div draggable="false">
  draggable
  <div contenteditable="true">content editable</div>
</div>
```

## jQuery 対応

:has により先祖をことごとく無効化してしまう

```js:draggable無効化
jQuery(':has([contenteditable])').prop('draggable', false);
```
クラウドって何？という人のためのAWSと他ベンダーの比較およびAWSのメリット

今日、AWS、GCP、Azureなど様々なクラウドサービスが使用されてきています。
これらのサービスを利用するメリットは多々あります。

# クラウドIaaS、PaaSを使うこと自体のメリット
よく言われる（と、思っている）のは下記の通り。

* リソースがすぐ調達でき、すぐに捨てられる
* マネージドサービスなら、運用の手間をプラットフォームに押し付けられる
* 内部的な仕組みをわかっていなくても、プラットフォーム自体が欲しい機能を提供してくれる
* 自分たちでリソースを持たなくて良い
など…。  
最近強く感じることは、欲しい機能を次々提供してくれることは非常にありがたいですね。  
自分で構築するとそれなりに手間がかかるようなものを、マネージドサービスとして次々と提供してくれるので、いらぬ手間をかけずにサービス自体を組み合わせて目的を果たすこともできるようになります。  
今回はそれぞれの簡単な特徴と、（自分はAWSをメインで使っているので）その中で、AWSはここがよい、という点を書いてみます。

# どういったクラウドベンダーがあるのか

既に記載してしまいましたが、今回は総合的にサービスを展開するクラウドベンダーとして主要なところを記載します。主観たっぷりです。

* AWS  
Amazon Web Service。主要なクラウドベンダーとしては最も早く（2006年）サービスを開始。歴史の長さゆえか、使用者も多く、ユーザーコミュニティも非常に発達している。そのためノウハウが見つかりやすい。サービスの種類が増えるのがとても早い。
* GCP  
Google Cloud Platform。Googleの巨大なバックエンドを活かした高性能なサービスが多い。日本ではAWS、Azureに後塵を拝している印象だが、ピンポイントでBigQueryだけを使用する例があったり、サービスの性能はやはり評価されているのでは、と思う。
* Azure  
Microsoft Azure。AWSやGCPはLinux系のテクノロジーと親和性が高いが、こちらはMicrosoftが提供するだけあって元々Microsoft系のテクノロジーを使っていたユーザがそのまま以降するケースが増えている印象。
その他
IBM Cloud IaaSなど…。今回は扱わないことにします。

#それぞれを比較した中でのAWSのメリット

さて、ここまでを踏まえた上でこの中からAWSを使うメリットは下記のようなものだと思います。

* ノウハウが多く、わからないところを調べやすい  
やはりサービス開始が早く、ユーザ数も多いため、何か困ったときに調べたり効いたりすればすぐに解決する可能性が比較的高いと思います。
* サービスの追加ペースが早く、新しいことがどんどんできるようになる  
AWSは新しいサービスをバンバン追加してきます。  
2017年のRe;Inventでは非常に多くのアップデートが発表されています。  
	https://aws.amazon.com/jp/new/reinvent/
* 他サービスよりも利用者が多いため、使っている人をすぐに見つけられる  
	一つ目と被る部分でもありますが、利用者がとても多く、同士を見つけるのが比較的簡単です。  
エンタープライズの分野でも少しずつ採用が進んでいます。

というわけで、どれを選ぼうか迷ったら、とりあえずAWSを選択しておけば間違いはあまりないかなと思います。

# まとめ
まず最初に選ぶならとりあえずAWS！
その他は使いながら比較してみて、良し悪しを判断しながら使い分けるとよいのではないかなと思います。
google apps scriptでスプレッドシートへ独自メニューを作成

## まずはじめに
Googleドライブの機能を最近になって少し使用頻度が上がってきました。クラウドサービスとしてどこからでも利用できるのが便利というのが大きいですね。特にエクセルの代わりとして使える利用頻度が上がり、少しでも便利に使おうと思っているとgoogle apps scriptを目にする事になります。

その中で作成した機能を簡単に実行しようと思うと、独自のメニューがあればいいのに、という話になります。独自メニューの追加自体は調べればすぐにわかるのですが、コーディングの可読性を含めて納得できるものがありませんでした。そのため、備忘録としてまとめておこうと思った次第です。

## コーディング
ということで早速コーディングです。非常にシンプルです。

```javascript

//------------------------------------------------------------
// Mark: custom menu
//------------------------------------------------------------
function onOpen() {
  // メニュー内容作成
  var menuEntries = [];
  menuEntries.push({name: "getGmail", functionName: "getGmail"});

  // メニュー追加  
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  ss.addMenu("custom menu", menuEntries);
}
```

こんなイメージになります。
![Screenshot_2018-02-22_01-06-52.png](https://qiita-image-store.s3.amazonaws.com/0/48817/4dc24119-5d0a-2074-54af-6fbb9dbb480f.png)



## 解説
コメント通りのシンプルなロジックであるため、コード自体の解説ではなく「なぜこのコードであるか」という解説です。

**メニューの追加が簡単**
機能を追加し、メニューを増やしたいとなった場合は`menuEntries.push({name: "xxx", functionName: "xxx"});`を追記すればよいです。前後のロジックに手を入れることなく、追加した機能に関するものだけ書けばよいのです。当たり前のようですが、これができていないことが多いのです。

**機能を詰め込みすぎないことを前提としている**
他のサイトを見るとサブメニューにしたり、セパレーターを入れたりといったこともできるようです。しかし、実現可能であることと機能として実装することは別の話です。
基本はスプレッドシートであるため、一つのシートへ機能を詰め込み過ぎると使いにくくなることが懸念事項としてあがります。GAS（google apps script）は処理速度がそれほど早くないこともあり、なるべく処理を軽くしたいです。
そのあたりを踏まえて、ほどよい機能追加ができるところだと思います。

**結果として可読性が高く、不具合になりにくい**
なるべく機能を複雑にしない、追加をする場合でも簡単に修正を行えることから、結果として不具合が起きにくくなります。今回の場合はメニューのすごく単純なところですが、機能豊富な画面を作成するようなことになったときに大きな差が出てきます。大袈裟な言い方のようですが、他の人が作ったプログラムを読むことが多い人には理解していただけるかと思います。

## さいごに
調べればすぐに出てくることではあるものの、あえて記事をアップしました。理由は解説の部分に書いてあるとおり、なるべくシンプルに、不具合をなくしたいという思いからきています。少しでも不具合に遭遇する機会を減らせればと思っております。
優先度付きキュー(PriorityQueue) maxキューにする

ちょっと忘れていたので、ここにメモしておく。

普通PriorityQueueはminimum ヒープです。

PriorityQueue<Integer> pq= new PriorityQueue<Integer>();
pq.poll();    //これは最小の要素を取得する

これを最大の値(maximum heap)から順に取得できるようにするには、

PriorityQueue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());


とすればいい。

後、オブジェクトの特定のフィールドを使う場合は
PriorityQueue<Person> pq = new PriorityQueue<Person>(Comparator.comparing(SumTree::getAge));
もしくは
PriorityQueue<SumTree> pq = new PriorityQueue<SumTree>(Comparator.comparing(SumTree::getAge).reversed());

とすればいい。
PSD to HTML Conversion

Give ur visitors an amazing experience while visiting your website, get your PSD to HTML conversion by experts. Details: https://goo.gl/Z2vV3z


#Convert_Photoshop_to_HTML #PSD_to_HTML_Conversion_Services #Convert_PSD_to_HTML #Photoshop_to_HTML
![psd-to-html-conversion.jpg](https://qiita-image-store.s3.amazonaws.com/0/239957/4ae5b73d-fbe2-d81c-3538-a58c8400ff34.jpeg)
UnityでFirebaseのAuth使ってみる サンプル動かすところまで

##環境
mac
Unity2017.3.0f3
Xcode 9.2

##事前準備
とりあえず<a href="https://console.firebase.google.com/" target="_blank">firebase</a>
に登録してプロジェクトを追加。

そして<a href="https://firebase.google.com/docs/unity/setup?hl=ja" target="_blank">SDKをダウンロード</a>

今回はauthとそれからDatabase使うのでその二つのパッケージを入れました。
Authだけ使う場合はAuthだけでいいかと。
<img width="305" alt="スクリーンショット 2018-02-22 00.24.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/46444/5abab0ec-7ab0-1c83-cf98-2d6339a0f8ef.png">

各プロジェクトのサンプルがあるので<a href="https://github.com/firebase/quickstart-unity" target="_blank">ダウンロード</a>

<a href="https://firebase.google.com/docs/unity/setup?authuser=0" target="_blank">Unity プロジェクトに Firebase を追加する</a>ここの下の方に記載があるようにplistのファイルをAndroid ios両方作成

場所はメニューの左のとこからプロジェクトの設定
![auth1.png](https://qiita-image-store.s3.amazonaws.com/0/46444/28cda899-4b89-7de8-7d89-c32df5c635ac.png)

ios Androidのを作って両方ダウンロード
<img src="https://qiita-image-store.s3.amazonaws.com/0/46444/a0b3ca9d-c89e-86da-1227-542d26b52a76.png" width="400"/>

##Authのサンプルを動かす
新規プロジェクト作成。
FirebaseのAuth、Databaseのパッケージをインポート。
先ほどダウンロードしたios Androidのファイルをプロジェクトの適当なところに置く。
githubから落としたサンプルのAuthのファイルをそのまま配置

<img width="250" alt="スクリーンショット 2018-02-22 00.34.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/46444/8cf6b27f-5398-3728-5074-b643badbdfba.png">

Androidでビルド。
これだけでAndroidは動く。
実行画面はこんな感じ。
<img width="321" alt="スクリーンショット 2018-02-22 00.35.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/46444/31ebad8a-612f-c1bb-8a01-a6aa6b95d7ef.png">

あとあと、もう一個設定があって
Firebaseのログイン方法、これがデフォルト全てfalseになっているので必要なものを有効にしないとログインでエラーになる。
<img src="https://qiita-image-store.s3.amazonaws.com/0/46444/0aa9bf19-e61e-395c-3d96-96c5cb52f62c.png" width="500"/>

エラーになる場合はこちらの<a href="https://firebase.google.com/docs/auth/ios/errors?hl=ja" target="_blank">エラー一覧</a>で原因見ればわかるかも。


メールアドレスでのCreateUser、サインイン、ログアウトなど動いた。

ログインできればこんな感じでデータが見れる
<img src="https://qiita-image-store.s3.amazonaws.com/0/46444/5334f997-c601-81be-42d5-be49ff053b64.png" width="500"/>

##iosで動かす。
iosでビルド。そしてxcodeで実行・・・エラーorz

<img width="554" alt="スクリーンショット 2018-02-22 00.56.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/46444/92411c69-0b9a-0151-ddb2-1eab16fc0e42.png">

調べた結果、普段ってUnity-iphone.xcodeprojをクリックして起動していたのですが、
一個下のxcworkspaceの方で起動するらしい。
<img width="287" alt="スクリーンショット 2018-02-22 01.10.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/46444/5a0691ad-9854-2bc5-9950-e39d658aae36.png">

これでios無事ビルド成功、起動しました。
xcodeの知識がないから苦労するな・・・。
これでAndroidでユーザー作ってiosで同じアカウントでログインとかもバッチリ。
とりあえずサンプル動いたのでいったんここまで
Flywayのsbt pluginを利用した環境で、SQL-based migrationとJava-based migrationを併用する

# 概要

FlywayのMigrationには、SQLを利用した [SQL-based migration](https://flywaydb.org/documentation/migrations#sql-based-migrations) の他に、マイグレーション処理をコードで書くことができる [Java-based migration](https://flywaydb.org/documentation/migrations#java-based-migrations) がある。
(`Java-based` と書かれているが、もちろんScalaなどで書くことが可能なので `Code-based migration` と呼んだ方が正確かも)

Flywayのsbt-pluginを利用した環境で、この2種類のマイグレーション方法を併用する(通しのバージョン番号を付ける) 方法についてまとめる。

# サンプルプロジェクト

実際にやってみたサンプルプロジェクトがこちら。

https://github.com/h-1k10/sbt-flyway-sample

sbtの `flyway` サブプロジェクト内で `flywayMigrate` タスクを実行するとマイグレーション処理が走る。

# サンプルプロジェクトの説明

[flyway-sbt](https://github.com/flyway/flyway-sbt) の基本的な設定については説明を省略し、2種類のマイグレーション方法を併用するのに関連する設定についてのみ説明する。

## build.sbt

- `libraryDependencies` に `flyway-core` を追加する
  - `Java-based migration` に必要
- `flywayLocations` にマイグレーション用のSQLファイルを配置したディレクトリ名と、マイグレーション用のScalaコードを配置した**パッケージ名**(ディレクトリ名ではない点に注意) を設定する

## マイグレーション用Scalaコード

- [flyway/src/main/scala/com/github/h_ikio/sbt_flyway_sample/migration](https://github.com/h-1k10/sbt-flyway-sample/tree/master/flyway/src/main/scala/com/github/h_ikio/sbt_flyway_sample/migration) 配下を参照
- `JdbcMigration` インターフェースを実装するクラス内にマイグレーション処理を書く
- [ドキュメント](https://flywaydb.org/documentation/migrations#naming-1) に記載がある通り、クラス名のネーミングにルールがある点に注意
- サンプルプロジェクトでは、ScalikeJDBCを利用してマイグレーション処理のコードを書いている
- バージョン番号は `SQL-based migration` のものも含めて通し番号で付ければよい
最近のAWS Cloud9 + Railsでのハマりポイント

AWS CodeStar * AWS Cloud9がタイムリーで熱いということで、試用中。
はまりどころとその対応の備忘録です。

# Q1 railsコマンドで、new以外のサブコマンドが実行できない
ターミナルでrails コマンドを実行しようとしても、なぜか「rails new」だけのhelpが表示される。
これは該当のアプリケーションフォルダが、
railsフォルダだと識別されてないため。

たしかに、ルートディレクトリにbin/がない。
おそらくはコードベースがtemplateから生成されている訳だが、
templateにbin/が含まれていない。

ということで、
まずは、以下を実行して解決。
```rake app:update:bin```

参考: https://forums.aws.amazon.com/thread.jspa?messageID=818926&#818926



# Q2 [RUN]を押しても、Webrickが起動しない

デフォルトのRun設定は登録されていないので、手動で登録します。
```rails s -b $IP```

昔のような $PORTは要らない模様。

production実行するなら、右端の「...」から環境変数設定ね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/9701/5a18a9c6-96fb-cfcb-2bd0-1f94b6684fca.png)


↓は英語のブログだが、非常によくまとまっている。

参考: https://medium.com/@obrientimothya/developing-ruby-on-rails-5-1-apps-with-the-aws-cloud9-ide-18826ae1426b#Configure%20a%20Run%20Configuration


# Q3 マウス操作が多くて、スピードアップしない
ショートカット系がなじむまで時間かかりますね。
元々 Javaist の Eclipserですが、なかなか勘が戻ってこない。
現在は下のチートシートを眺めて1日5ショートカットを体に叩き込んでます。

チートシート:
　https://www.shortcutfoo.com/app/dojos/cloud9-win/cheatsheet

なお、ペイン毎に使えるショートカットが異なるのも悩みどころ。
Editor上では正常にCtrl+Sが効きますが
TerminalでCtrl+Sなどを押してしまうと、Terminalがフリーズして操作不能になるという罠


# Q4 Cloud9が自動終了に失敗？　→　EC2使用料発生 (T-T)

Cloud9はEC2上で動いています。デフォルト設定では、t2.microで、「操作なしで30分経つと自動終了」され、EC2使用料はだいぶカットされます。
というのが、本来の動きですが…
なぜか自動終了せず。
半月ほど経って請求書の違和感からEC2インスタンス群を見て気づきました。

どうやら上手く自動終了しないことがある模様（苦悩）。

CodeStar経由で実施している場合には、
- Project数 * チームメンバー数
- 本番環境のEBS/EC2が常時起動
となるので、もう少しシビアにみる必要がありそうです
↓
定期的に
- EC2インスタンスの起動状態をチェック
- 不要なProjectを除去
- 不在のメンバー・試し作成のCloud9の除去
という運用になりそうですね。

# Q5 CodeStarでRailsが選べなくなった!?

3/7現在。プロジェクトのテンプレート選択にRailsがない。
※ Sinatraはある。
※ PHP プロジェクトも減ってる気がする。そうだWordPressもなくなった

![image.png](https://qiita-image-store.s3.amazonaws.com/0/9701/f5e803c8-b5ed-2b0c-2a77-b392cf097916.png)

ひとまず、新しいPRJで作成する場合には、
Sinatraを選択して、
Gemとファイルをごっそり消してRailsに差し替えてます（詳細割愛）。

公式情報は、未発見 orz

→ 2018/3/16 復活。どこかで圧力あったのかもですね。
ぐりぐりしたいk-means++シリーズ(Julialang)

###ソースコードはこれ
https://nbviewer.jupyter.org/github/Ooshita/ml_page/blob/master/julia/manifold_ml.ipynb

Juliaでかきました．

![Feb-21-2018 08-43-46.gif](https://qiita-image-store.s3.amazonaws.com/0/33329/bf5a9337-7de6-36ff-da3b-e2d267cd8237.gif)

クラスタリングでは何かと出てくる，スイスロール（ロールケーキ）．
クラスタ数を3つにするとこのように分類されるんですね．

![Feb-22-2018 00-05-06.gif](https://qiita-image-store.s3.amazonaws.com/0/33329/0f362ff9-0c75-0f08-167a-a7a40b3ac5ed.gif)

円(sphere)のクラスタ数を３つで分類したもの．

![Feb-22-2018 00-13-54.gif](https://qiita-image-store.s3.amazonaws.com/0/33329/a04d6fe3-ba19-6459-69e4-b2abcd8a29a1.gif)

5つで分類したもの．


#### 宣伝
ブログも見てくれるとうれしいです．
https://whispon.com
OpenShiftの提供サービス

OpenShiftはいくつかのサービスを提供しており、それぞれ想定している利用ケースや対象者が異なっています。それらの概要を把握したうえで、さらにOpenShiftOriginについても調べてみようと思います。

##そもそも OpenShift って何？

OpenShift は Makara というクラウド配信・管理・監視ツールがベースとなっていて、MakaraはRedhat社が2010年に買収したものだそうです。
JBossをAPサーバに内包しておりJavaEEに対応しているのが特徴。
複数の開発言語、開発フレームワーク、データベースに対応し、コマンドライン、ウェブインターフェースを利用し利用/管理が可能になっています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/222266/88afc6d2-6b10-9469-5955-415538e6836d.png)

アプリケーションの開発や実行環境を提供するだけではなく、開発やリリースのスピードアップを実現するための機能も提供しているそうです。

OpenShiftは以下のサービスを提供しています。

・OpenShift Origin : OSS版ツール
・OpenShift Enterprise : RedHat社サポートによる企業向け版ツール
・OpenShift Online : PaaS（公共向け）
・OpenShift Dedicated ： PaaS（一社向け）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/222266/848c151f-5c7d-b93f-7c55-f692433138f2.png)

データセンター内利用や企業向けのプライベートクラウドの環境構築向けのものとして提供しているようです。

##OpenShift Origin
上記のOpenShiftサービス群の一つでOSSの OpenShift Origin を利用することでPaaS環境のプライベートクラウドを構築することができるようです。また開発リポジトリについてはGithubにて公開されているそうです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/222266/2687ecdd-5c9a-a806-1054-9664a6231aaf.png)
https://www.openshift.org/
どうもここからOpenShift Origin の最新版をダウンロードできそうなので次回は実際に導入してみようと思います。
delegate(Swift)とdelegate(.NET)は違う

# delegate(Swift)とdelegate(.NET)の違い

Swiftで初めてiOSアプリを書こうとして混乱したのでメモ。
Swift歴まだ数時間なのでいい加減なことを書いている可能性が多々あります。

### ポイント
- Swift(やObjective C)のdelegateは言語そのものの機能ではない
- 一種のデザインパターンとして理解すべきもの
- .NET系言語のdelegateは言語の機能であり、別のもの（だがもちろん関係はある）

## Swiftのdelegate
色々ググっても、使い方ばかりでクラス図とかシーケンス図がないためスッキリ分からないなぁ思いました。
で、書いてみようかなと思ったのですが、その前にぐぐってみたら書いてる方がいらっしゃいました。
[iOSの画面の基礎、デリゲート(Delegate)をマスターする](https://qiita.com/zucay/items/03080645dde1a62ec570)

ということで、どういうデザパタなのかはこの記事を参照いただければ良いと思います。
さて、高度な使い方の話はおいておくとして、UIのイベント駆動などをどう書くかというと、

- 適当なクラスでUIに対応したプロトコル(Javaなどで言うところのインターフェースに近いもの）を適合（継承）させる。
- プロトコルを適合させたクラスで、必要に応じてプロトコルで定義された処理を実装。
- 制御したいUI部品のdelegateに、プロトコルを適合させたクラスのインスタンスを指定する。

ということで良いようです。

## C#でのdelegate

C#歴はSwiftよりは少しは長いので以前から知っていたので逆に混乱してしまいました。
どんな機能なのかは例えば、
[C#入門 第17回 処理を委譲するdelegate](http://www.atmarkit.co.jp/fdotnet/csharp_abc/csharp_abc_017/csharp_abc01.html)
に載っていますが、こちらもイベント処理に使われます。
ただ、これは言語の機能なので単語としては同じでも、Swift上でdelegateと読んでいるものとは違うものですね。

## その他参考
[Wikipedia デリゲート(プログラミング)](https://ja.wikipedia.org/wiki/%E3%83%87%E3%83%AA%E3%82%B2%E3%83%BC%E3%83%88_%28%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%29)
Snipe-IT を Ubuntu 16.04 LTS(AMI) に導入する

## はじめに
とにかくExcel上での資産管理から脱却したい。
共有したファイルが壊れるとか、開くのに超時間がかかるなどExcelはつらみしか無い。
かといって大規模な管理ソフトを入れるための（時間的）余裕も（資金的）余裕も無い。
　→snipe-it

##snipe-itとは
- 資産管理ツール
- webベースなのでクライアントにアプリケーションのインストール不要
- オープンソース
- 公式HP： https://snipeitapp.com/
- 公式マニュアル： https://snipe-it.readme.io/docs
- デモサイト： https://snipeitapp.com/demo

## 構築した環境
- AWS EC2 
- インスタンス：t2.micro
- AMI：ubuntu-xenial-16.04-amd64-server-20180109 (ami-d39a02b5)
- OS：Canonical, Ubuntu, 16.04 LTS, amd64 xenial image build on 2018-01-09
- その他設定：デフォルト

## 構築
基本的に公式マニュアル （ https://snipe-it.readme.io/docs ）
を参照して進めていけば問題ない。

インストール方法はGitCloneなど4つあるが、とりあえず下記に記載されている通常のインストーラーを使用した。
https://snipe-it.readme.io/docs/downloading#section-3-download-the-installer

wgetでダウンロードし、chmodでインストーラーに権限付与。
`wget https://raw.githubusercontent.com/snipe/snipe-it/master/install.sh`
`chmod 744 install.sh`
`./install.sh`

インストーラを起動するとDBの初期設定などが流れて、いくつか質問される。
回答後、自動的にインストールが進む。

## 設定
手順通りインストーラーを流した後にブラウザでアクセスすると、apacheのデフォルトページが表示されてしまう。
その為、デフォルトページの無効化を行った
`cd /etc/apache2/sites-available`
`a2dissite 000-default.conf`

apache再起動
`systemctl restart apache2`

これでAWSのIPアドレスにブラウザでアクセスすると初期設定画面が表示される。
![Snipe-IT Pre-Flight1.jpg](https://qiita-image-store.s3.amazonaws.com/0/129423/07750a40-d298-55c1-39c2-6b41c9968a02.jpeg)

管理者ユーザの作成などが終わると、snipe-itのポータル画面が表示される。
![Snipe-IT.jpg](https://qiita-image-store.s3.amazonaws.com/0/129423/022653f3-f2bf-ae8a-0d16-572e9f013a11.jpeg)

ちなみに日本語化は、ポータル画面で
右上の”Admin” → ”Edit Your Profile” → ”Language”を”Japanese”に変更

##終わりに
思ったよりも簡単に構築が出来た。
躓いたのは自分にUbuntuの知識があまりなく、apacheの設定する箇所を調べたくらい。
後は実際に使用してみて、どの程度業務に活用できるか検討したい。
Project Honolulu あれこれ

Project Honoluluについていろいろ書いてみようかと思います。

初回リリースから1回アップデートがあり、現在は下記のバージョンとなっています。

Version 1712 Build 1.1.1712.05002

実行できる環境はWindows10 + Edgeとなります。

管理できる対象は

Windows Server 2016
Windows Server 2012/R2 ← WMF5のインストールが必要です
Windows10

Windows Server 2012R2では登録は可能ですが、WMF5がインストールされていないと下記のようにメッセージが表示されます。
![スクリーンショット (2).png](https://qiita-image-store.s3.amazonaws.com/0/203732/71ce3f53-24d7-3fda-aa58-fc545551c7c3.png)

WNF5を入れると情報が取得できました。
![honolulu01.png](https://qiita-image-store.s3.amazonaws.com/0/203732/f567fbbc-82f2-ed98-87b3-f7df68241053.png)

現在のバージョンで日本語対応となっていますが・・・・・
訳がダメダメなので、英語の方がまだわかりやすいです。

あと、認証がWindows10でサインインしたユーザーが基本となります。
サインインユーザーで管理対象に権限がない場合は、一応認証を指定できます。
認証を設定したいサーバーにチェックを入れて、「Manage As」をクリックすると設定ができます。
![honolulu02.png](https://qiita-image-store.s3.amazonaws.com/0/203732/460068ad-fdd4-dce0-aca2-bb329a672fdf.png)

一番下にメッセージがありますが、認証は保存ができずこのセッションのみとなります。このあたりは、変わるんですかねぇ。

Windowsサーバーに搭載されているサーバーマネージャーの豪華版といった感じで役割/機能の追加からイベントログの確認まで行える。
グラフィカルインターフェースを持たないSAC版のWindows Serverなどで利用できると効果がでるのではないかなぁと思います。

タスクマネージャで見れるパフォーマンスグラフも見れるので、運用でも効果を発揮するのではないでしょうか？

Windows Server 2012ではWMF5のインストールが必要であるため本番環境では少し敷居が高いかもしれません。
また、情報の収集にWinRMを使用するため、Windows10側も管理対象側も設定が必要です。今となっては簡単ですね。
WinRMだけでエージェントレスなのでホントに正式リリースが待ち遠しいですね。
S3 Browserを使ってVPCエンドポイント経由でS3にアクセスする

# やりたいこと
S3 Browser (http://s3browser.com) は S3をWindowsのエクスプローラーライクなGUIで管理する有償のクライアントソフトウェアです。
今回このツールを使って東京リージョンのプライベートサブネットからVPCエンドポイント経由で S3 Browserが使えないかなと思ってやってみました。
このイメージ。
![s3-0.png](https://qiita-image-store.s3.amazonaws.com/0/104514/9d71e503-3bfb-c574-317f-c7b12d3d68e6.png)

# S3 Browserのアカウント設定
S3 Browserのアカウント設定は8種類ありますが、今回は東京リージョンのEC2から東京リージョンのS3バケットにアクセスしたかったので、選択肢としては5つでした。

* Amazon S3 Storage
* S3 Compatible Storage
* Amazon S3 on EC2 via IAM Role
* Amazon S3(Credentials from Environment Valiables)
* Amazon S3(Credentials from AWS Config or Credential file)

![s3-1.png](https://qiita-image-store.s3.amazonaws.com/0/104514/de893fd2-2f1d-27f6-d7c1-3f69072094d7.png)

試したみた結果、アクセスできたのは *S3 Compatible Storage* かつ 署名バージョン2 を利用した場合のみでした。署名バージョン2 がサポートされていないリージョンは次とありましたので、東京リージョンだから通ったようです。署名バージョン4なぜかダメでした。

* 米国東部 (オハイオ) リージョン
* カナダ (中部) リージョン
* アジアパシフィック (ムンバイ) リージョン
* アジアパシフィック (ソウル) リージョン
* 欧州 (フランクフルト) リージョン
* 欧州 (ロンドン) リージョン
* 中国 (北京) リージョン

参考) 署名バージョン 2 の署名プロセス
https://docs.aws.amazon.com/ja_jp/general/latest/gr/signature-version-2.html

# 設定のポイント
繰り返しになりますが、REST Endpointを s3.ap-northeast-1.amazonaws.com に、署名を署名バージョン2にすることです。なお、SSL/TLS は有効でも無効でもどちらでもOKでした。

![s3-2-1.png](https://qiita-image-store.s3.amazonaws.com/0/104514/5a118d13-e35a-dc60-af1a-e39e983dbe08.png)


参考) AWS のリージョンとエンドポイント
https://docs.aws.amazon.com/ja_jp/general/latest/gr/rande.html#s3_region

結局、署名のバージョンも古いし、IAM Roleも使えないので微妙です...。
もちろん awscli は何の苦労もなくアクセスできますので、通常は awscli で良いのですが、ニッチな状況（例えば、社内からS3Browser→VPN→Squid@EC2→VCPEndpoint→S3へアクセスするといった）においては需要があるかもしれません :sweat_smile:
DjangoでWeb Appその②

前回は[ここ](https://qiita.com/howk_yamoh/items/4c874ca0bb9a69389edd)

# 環境

* macOS High Sierra version 10.13.3
* Python 3.6.3
* Django 2.0.1

# テーマ
今回のテーマは、「ページを表示する」です。
とにかくページを表示できるようになることが目標。

# urls.py
今回の主役1号です。




###プロジェクトの方
まずはプロジェクトの方のurls.pyを以下のように変更します。

```urls.py
from django.contrib import admin
from django.urls import path, include # includeを追加

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('todo.urls')), # ここも追加
]

```
これは何をしているかというと、todoアプリのurls.pyを読み込んでねっていうお願いの宣言です。
この辺は本家にもあると思うので、さらっと。

さて、次はアプリの方のurls.pyに行きたいところですが、先にviewを書いちゃいましょう。


#Views.py
todo/views.py ですね。
主役2号です。

以下のようにします。

```views.py
from django.shortcuts import render

# Create your views here.
# 以下追加部分

def index(request):
    hello = "Hello, World"
    context = {
        'hello': hello,
    }
    return render(request, 'todo/index.html', context)

```

viewは表示するデータを渡してレンダリングする役割を果たします。
view関数を定義する他、クラスベースビューを使う方法もありますが、それはまた後ほど。

ビュー関数は引数に必ず`request`をとります。ここに渡される内容はHTTPリクエストですね。
レンダリングする方法はいくつかありますが、一番簡単且つ、後々応用が効く方法だと勝手に思っているのが、コンテキストを定義して、リクエストと一緒に`render()`関数へ渡しちゃう方法です。

###コンテキスト
コンテキストとはテンプレートへデータを渡すためのデータ辞書ですね。（たぶん）
keyの部分には、テンプレート上で使用する文字を、valueの部分には実際に渡すデータを。
ここでは、`hello`という変数に`"Hello, World"`という文字列を格納して、それをコンテキストへ渡してます。
つまり、テンプレート上で`{{ hello }}`とすば、"Hello, World"の文字がレンダリングされるという事です。

###render()
render()関数へ渡している引数は順に以下の通りです。

第1引数：request。 HTTPリクエストが渡されている。
第2引数：どのテンプレートを使うかを指定。`index.html`はあとで作ります。
第3引数：コンテキスト。直接辞書を書くことも可能ですが、分かりにくいので、辞書型の変数を渡す派です。


#index.html
view関数の定義が完了したので、先ほど指定したテンプレートを用意しましょう。

```
project/todo/templates/todo/index.html
```

こんな感じですね。


テンプレートは、djangoが自動的に`templates`以下を探してくれるのですが、アプリが複数になった時、`index.html`とか被りやすい名前の判別に困ってしまうようです。
なので、今はあまり意味のないことですが、`todo/temolates/todo/index.html`という複雑な階層で用意しましょう。

###内容
とりあえずindex.htmlの中身ですが、`{{ hello }}`でいいと思います。
波括弧で囲うのはjinja2の表記ですね。

```index.html

{{ hello }}

```
本当にこれしか書いてません。抜粋ではないです。


#またまた、urls.py
最後にアプリ側のurls.pyを書きましょう。

アプリ内にはもともとurls.pyはないので、新たに作る必要があります。
内容はこんな感じ。

```urls.py
from django.urls import path
from todo import views

urlpatterns = [
    path('', views.index, name='index')
]

```

プロジェクトの方のurls.pyと似たようなものですね。
違いといえば、アプリのviewsをインポートしてます。
views.pyの中のindex関数を見てねということでしょうか。

`name=index`の部分ですが、これは追い追いテンプレートで役立つので、書いとくと良いです。
まぁ、ちょっと表記が省略できる程度ですが、可読性も上がるし書くべきだと思います。


#いざ、runserver

`$ python manage.py runserver`で開発用のローカルサーバーが立ち上がるので、コマンドを打って、ブラウザで確認しましょう。


こんな感じで表示されれば成功です！
![スクリーンショット 2018-02-21 22.57.35.png](https://qiita-image-store.s3.amazonaws.com/0/237417/50b0afc2-4a0b-b5cf-115f-e94ab885815d.png)


#まとめ

ポイントは、views.pyでコンテキストをセットして、render()関数へ渡すことと、urls.pyでその関数を指定してあげることだと思います。
この基本の繰り返しで好きなURLから好きなページをレンダリング＝表示させることができると思います。

以上です。
DjangoでWeb App その①

# はじめに
職場で使う用の簡単なWebアプリをdjangoで作成したので、djangoでアプリを作る手順の覚書として、1からまとめてみます。

自分の忘備録的なものではありますが、これからdjangoでアプリを作りたいという方の一助となれば幸いです。

Railsのように日本語チュートリアルが溢れいてるわけではないので。
特にリレーションやfieldsetのあたりとかかなりハマりましたので、何回かに分けてその辺りも書いていければと思います。
今回はプロジェクトの作り方のみです。


# 環境

* macOS High Sierra version 10.13.3
* Python 3.6.3
* Django 2.0.1


# プロジェクトとアプリ 
###プロジェクトの作成
```
$ cd workingdir # ワーキングディレクトリへ移動

$ django-admin startproject myproject

$ cd myproject
```  
`django-admin startproject [プロジェクト名]`で、`manage.py`とプロジェクト名のディレクトリが作成されます。
今回の場合だと、以下のような感じ。

```
workingdir/

       ├ myproject/

                 ├ myproject/
                 ├ manage.py
```

djangoのプロジェクトは？と言われれば、workingdir直下にある`myproject`ディレクトリがそれだという認識でたぶん大丈夫。
ちなみに、`myproject/myproject`の中には、`setting.py`、`urls.py`など、djangoアプリを作っていく上で必ず触る事になるファイルなどが入っています。
各内容については今後触れていきます。


###アプリの作成
djangoはプロジェクトの中に複数アプリを持ちます。
今回はTodoアプリを作るという前提なので、myprojectの中にtodoアプリを作っていきます。

```
# myproject

$ python manage.py startapp todo
```
todoというディレクトリができたはず。


これから、主にこの「todo」内のファイルをいじっていくことになります。


###アプリの追加

最後に、作成したアプリをプロジェクトに追加するところまでやってしまいます。

```setting.py
  .
  .
  .

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'todo', # ← 追加したところ
]

```

これでプロジェクトの作成と、アプリの作成・追加が終了。


[次回その②](https://qiita.com/howk_yamoh/items/2e4f3e6a7ea6a7f38d32)
WindowsでfastTextをインストールした備忘

# WindowsでfastTextをインストールした備忘
- 2019/11/20 内容があまりに雑だったのでちょっと修正しました

## [fastText](https://github.com/facebookresearch/fastText)とは
- facebookが発表した自然言語向けの機械学習ライブラリです
    - 単語をベクトル化するモデルを作成します
        - 単語を「単語の意味」を示すようなベクトル値に変換できます
    - 学習の文章を単語レベルで分割（分かち書き）し、近くに出現した単語は近くなるように学習します
    - 単語をベクトル化することで、単語同士の距離を測定したり単語の演算ができたりします
        - 例えば女性 + 王様 - 男性 なんていう計算ができたりする
    - 単語内で文字ngram分割をかけることで、活用形を考慮することもできます
        - subwordsという考え方です
        - 「going」という単語を学習すると、その単語を構成している「go」も同じように学習してくれる感じ
        - 結果的にgoとgoing,goedみたいな活用形は同じ単語ベクトルになる（関連性がある）という感じになります

## 環境
* Windows7（後でWin10環境でもやりました）

## fastTextを動かすために必要なもの
- c++のコンパイル環境
    - fastTextのソースをコンパイルするため、c++11のコンパイル環境が必要になります
    - コンパイルしたexeを実行する環境も同じです
- Pythonで動かす場合
    - 公式でPythonから動かすライブラリも提供されています
    - 必要なもの
        - c++11コンパイル環境
        - Python（バージョン2.7または≥3.4）
        - NumPy
        - SciPy
        - pybind11

## インストールしたもの
- c++コンパイル環境
    - Cygwin（msys2でもよい）
    - Cygwinのパッケージでmake、g++
- Python
    - Python3.6
- 分かち書き用
    - Python用MeCab(日本語の単語分割→分かち書き用）→[pipでインストール](https://qiita.com/yukinoi/items/990b6933d9f21ba0fb43)
    - MeCabの辞書

## 手順

### 1. fastTextをコンパイルする
fastTextをクローンしてコンパイルする

```
$ git clone https://github.com/facebookresearch/fastText.git
$ cd fastText
$ make
```
[ここでthreadのエラーがでたらc++のコンパイラが古い可能性があります](https://qiita.com/yakipudding/items/158a6a036aad57777959)

### 2. Pythonライブラリをインストールする
- cloneしたfastTextで以下を実行

```
pip install .
```

ここで

```
C2039: 'to_string': 'std' のメンバーではありません
```

というエラーがでた場合、src/productquantizer.ccを直接編集して

```
#include<string>
```

を足すといける。
→[issues](https://github.com/facebookresearch/fastText/issues/411)にあがっていた

## fastTextを動かすために
- 実際にfastTextを動かすときには以下の作業が必要になります
    - 教育用データの作成 
    - モデルの作成（supervised）
    - 検証（test）

このあたりは気が向いたら記事でも書くかもしれない。。。
airbnb クローンスクリプトでbundle installした時のエラー


airbnb クローンスクリプト(http://sharingeconomies.jp/ )をローカルでbundle install したところ下記のエラーがでました。

```
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
・
・
・

checking for BIO_read() in -lcrypto... no
checking for BIO_read() in -llibeay32... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/Users/hatori/.rbenv/versions/2.3.1/bin/$(RUBY_BASE_NAME)
	--with-puma_http11-dir
	--without-puma_http11-dir
	--with-puma_http11-include
	--without-puma_http11-include=${puma_http11-dir}/include
	--with-puma_http11-lib
	--without-puma_http11-lib=${puma_http11-dir}/lib
	--with-cryptolib
	--without-cryptolib
	--with-libeay32lib
	--without-libeay32lib

To see why this extension failed to compile, please check the mkmf.log which can be found here:

・
・
・

extconf failed, exit code 1

Gem files will remain installed in
・
・
・
・

An error occurred while installing puma (2.11.1), and Bundler cannot continue.
Make sure that `gem install puma -v '2.11.1'` succeeds before bundling.

In Gemfile:
  puma

```


pumaのgemがインストールできない。調べてみると、opensslが悪さをしてるみたい。

```
xcode-select --install

brew link --force openssl
```



```
・
・
checking for Ruby version >= 1.8.5... yes
checking for clang... yes
checking for Magick-config... no
checking for pkg-config... yes
checking for ImageMagick version >= 6.4.9... yes
checking for stdint.h... yes
checking for sys/types.h... yes
checking for wand/MagickWand.h... no

Can't install RMagick 2.13.4. Can't find MagickWand.h.
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.
・
・
```

続いてrmagickのエラー

```
brew uninstall imagemagick

brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/6f014f2b7f1f9e618fd5c0ae9c93befea671f8be/Formula/imagemagick.rb

gem install rmagick
```

インストールし直しで解決。

```
bundle install
```


成功！！！！
Markdownでかけなかったアレ、Asciidocならこうかけますよ。

AsciidocというMarkdownに似た軽量マークアップ言語があります。
Asciidocの基本的な使い方等は[参考文献](#%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE)に譲るとして、ここでは「Markdownでかけなかったアレ、Asciidocならこうかけますよ」っていうのを書きたいと思います。

画像はVSCodeでPreviewした結果です。

# 順序有りリストの途中でコードを書く

Markdownで順序有りリストの途中にコードを書くと残念なことになってしまいます。

```markdown:qiita.md
1. まずこうします。
2. 次にこうします。その時叩くコマンドはこれです。
\```　(適当にエスケープしています)
$ echo "hoge"
\```　(適当にエスケープしています)
3. 最後にこうして完了。
```

これを表示させるとこうなります。

![01.md.png](https://qiita-image-store.s3.amazonaws.com/0/152997/b8144e41-273c-3722-fd51-76bc377f140b.png)

「最後にこうして完了。」の部分が「1.」になってしまっています。
途中でコードを入れたことで順序リストが一旦終わってしまったんですね。

これはAsciidocだと回避することができます。

```text:qiita.adoc
== 順序付きリスト

. まずこうします。
. 次にこうします。その時叩くコマンドはこれです。
+
----
$ echo "hoge"
----
+
. 最後にこうして完了。
```

![01.adoc.png](https://qiita-image-store.s3.amazonaws.com/0/152997/3b314d83-6801-b66c-a640-a1ac3ad4373a.png)

`+`を書くことで「まだリストが続きますよ」ということを表すことができるのです！

# テーブル

Markdownではテーブルは標準では(HTMLを使わないと)かけないので、各自同時実装しているのが現状です。
各自、微妙に書き方が違っていて困りものなのですが、それ以上に困るのがセルの結合です。
特に縦の結合については、それがかけるMarkdownの処理系というのは(少なくとも自分は)知りません。

Asciidocではテーブルは標準表示でセルの結合も使放題です。

```text:qiita.adoc
== テーブル

|===
|1     |2  |3 |4
|5 2.2+|6 1.3+|7
|8
|9   2+|10
|===
```

![02.adoc.png](https://qiita-image-store.s3.amazonaws.com/0/152997/af56fb15-156e-73c6-d60d-2dd1c5894900.png)

書き方も複数用意されていて、csvで書くこともできます。

```text:qiita.adoc
[format="csv", options="header"]
|===
アーティスト,トラック,ジャンル
Baauer,Harlem Shake,Hip Hop
The Lumineers,Ho Hey,Folk Rock
|===
```

# ファイルのインクルード

Asciidocでは他のファイルをインクルードすることができます。これがめちゃくちゃ便利！

```text:qiita.adoc
include::other.adoc[]
```

```text:other.adoc
=== Other

他のこと
```

![03.adoc.png](https://qiita-image-store.s3.amazonaws.com/0/152997/45ba7b23-1e84-4f17-ede8-2dc1965b067b.png)

## 応用

ファイルのインクルードと先程のテーブルのcsv記法やコードの表示を使えばcsvファイルやプログラムファイルも読み込めちゃいます。

```text:qiita.adoc
=== csvをテーブルとして表示

[format="csv", options="header"]
|===
include::other.csv[]
|===

=== プログラムの埋め込み

[source,ruby]
----
include::other.rb[]
----
```

```csv:other.csv
国,首都,人口(2006) CRLF
日本国,東京,127767944 CRLF
アメリカ合衆国,ワシントン,300007997 CRLF
```

```rb:other.rb
require 'sinatra'

get '/hi' do
  "Hello World!"
end
```

![03-2.adoc.png](https://qiita-image-store.s3.amazonaws.com/0/152997/cde8d150-caea-a894-ce69-dece20a0435e.png)


# 注釈

Asciidocではこんな注釈が用意されています。
地味に嬉しい。

![04.adoc.png](https://qiita-image-store.s3.amazonaws.com/0/152997/4c042e9b-4f90-9138-73ab-1729d23d03e7.png)

# 最後に

どうでしょうか?
Asciidoc使ってみたくなってきたでしょうか?
GithubやGistはもう対応しているようなので、自分は今後は積極的にAsciidocを使っていきたいと思っています。
皆さんも是非。

**QiitaもはやくAsciidocに対応するべき！**

# 参考文献

- [Asciidoctor 文法クイックリファレンス(日本語訳)](https://takumon.github.io/asciidoc-syntax-quick-reference-japanese-translation/)
- [AsciiDoc入門](https://qiita.com/xmeta/items/de667a8b8a0f982e123a)
- [脱Word、脱Markdown、asciidocでドキュメント作成する際のアレコレ](https://qiita.com/tamikura@github/items/5d3f62dae55617ee42bb)
Golang1.10で複数パッケージのカバレッジが一度に取れるようになった

# はじめに
Golang 1.10がリリースされました。
[複数パッケージのカバレッジが一度で取れるようになった](https://golang.org/doc/go1.10#test)のが個人的にはかなりうれしかったです。


# 1.9以前
以前は以下のようにパッケージごとに`go test`を走らせて、カバレッジの結果を1ファイルにまとめるようなスクリプトを使っていました。

```bash
for d in $(go list ./... | grep -v vendor); do
    go test -race -coverprofile=profile.out -covermode=atomic $d
    if [ -f profile.out ]; then
        cat profile.out >> coverage.txt
        rm profile.out
    fi
done
```

# 1.10

1.10では次のように一度に複数パッケージのカバレッジが取れます。

```bash
$ go test -race -coverprofile=profile.out -covermode=atomic ./...
```

#まとめ

これでCIでテストするときにわざわざスクリプト用意しなくて良くなった！
IT企業が採用すべき技術新卒は情報系ではなくて理学系の学生である

「IT企業が採用すべき技術新卒は情報系ではなくて理学系の学生である」
全部そうしろってわけじゃないです
ましてや情報系の学生に恨みがあるとかそういうのでもないです
すこしは理学系の学生を採用したほうがいいよって話です

# 即戦力がほしいんだけど？
新卒に即戦力を期待するのが間違い。ミスマッチです。

即戦力が欲しかったら中途採用するとして
２年後３年後会社の役に立つのは
プログラム経験ありで入社した情報系学生よりも
プログラム経験なしで入社した理学系学生だと思います

# 理学系の学生は成長性が高い
例えば物理学では何をしているのか？
・予め法則が決められているだろう自然現象を観測する
・その自然現象の法則を知るために仮説をたてる
・仮説を元に方程式をたててみる
・その方程式があっているのかどうか実験して確かめる
これが物理学です。ニュートンやアインシュタインもこうしてきました。

これはプログラミングに応用がききます
・予め決められているプログラムの動きを観測する
・要件を実装するために構想をたてる
・構想を元にしてコードを書いてみる
・書いたコードがあっているのかどうかテストして確かめる
一緒ですね。
別にこじつけてるわけじゃなくて本当に一緒だと思います。
理学の取り組み方はまさにこれです。

つまり
まったくのプログラム経験０で
**未経験のド素人でも理学的なものの考え方ができる人はプログラムが書けます**
しかも時間はかかれど自分で０から調べて様々な観点からテストするからバグのでにくいコードが書けるんです
そして地頭が良いです。論理的なものの考え方ができます。

真っ白なキャンパスに自社システムに特化した技術を描くことができます
これは将来的に会社にとってかなりの利益になります

# 情報系の学生は何かの言語に特化してしまっている
よくあるはなしで学校でその言語を学んでいたからその言語しか書けないし
それ以外の技術には興味がないってパターン
しかし日々の業務では偏った知識の人はボトルネックになりがちです
大学や専門学校では仕事で役立つコンピュータの知識は教えてくれません。

例えば自社システムはJavaで動いてるからJavaの経験のある新卒を採用しましたってとき
でも実際はクライアントの都合でPHPやjavascriptも扱うことがあるでしょう
こういう時半端に知識があると言語間の差異に戸惑いパフォーマンスが悪くなる人がいます。
なまじ「コンピュータに関しては素人じゃないだ」なんて自負もあるためそれほど詳しくない人より落ち込みが激しいです。
そして「この会社向いてないな」って感じてやめてしまったりします。
こういう人はプログラムはかけても業務には向かないですよね。

# 同時に採用するのが一番いい
経験者は未経験な同期に操作方法やコーディングを教えることでやる気や満足度が得られます。
理学系学生はどんどん入ってくる新しい知識に胸が躍り成長も早いことでしょう。

# 実際のところ
理学系って学校で学んだ知識を活かせる就職先はほぼないので
その地頭を活かせる環境があることを教えてあげると食いつくと思います

しかし
採用って技術力うんぬんよりも人柄や協調性とかコミュニケーション力とかが重要なんだと思います。
なのでまぁ愚直に経験者で求人をかけるんじゃなくて
未経験な理学系のところにも採用の目を向けてみてほしいなって話でした。
railsの親子関係にあるモデルで子モデルの数でvalidationする

#はじめに
railsでSTIどうしの親子関係を作って、各STIの親モデルごとに子モデルの種類をvalidationしたかった。

#validationの記述
普通のカラムのvalidationと同じように書けば指定できる。

```ruby:model
# 親モデル
class MainBlock < Block
validates :text_items, presence: true
validates :button_items, presence: true
end

# 子モデル
class TextItem < Item
end

class ButtonItem < Item
end

# 継承関係は各STIのスーパークラスで定義してあります。
```
また、lengthを使うことで個数のvalidationもかけられます。エラーメッセージがおかしくなるけど、、

```ruby:model
validates :text_items, presence: true, length: { minimum: 1 }       # 「1個以上」
validates :text_items, presence: true, length: { maximum: 10 }      # 「10個以下」
validates :text_items, presence: true, length: { in: 1..10 }        # 「1個以上10個以下」
validates :text_items, presence: true, length: { is: 8 }            # 「8個のみ」
```
#参考
[Railsバリデーションまとめ](https://qiita.com/shunhikita/items/772b81a1cc066e67930e)