OmniAICreator/Qiita-1.07M huggingface dataset:
Rails チュートリアル メモ 第2章

# 暗記事項

## Scaffold

```bash
# rails generate scaffold モデル名(大文字単数) カラム名:型 カラム名:型 ...
rails generate scaffold User name:string email:string
```

Scaffold すると、モデル・ビュー・コントローラがすべて実装される。ただしバリデーションは行われない。

## マイグレーション

```bash
# 下記のどちらか
bundle exec rails db:migrate
bundle exec rake  db:migrate
```

Rails 4 以前は rake のみ。Rails 5 以降は rails コマンドで実行可能。

## Heroku へのデプロイ

```bash
git push heroku master
heroku run rails db:migrate
```

デプロイしただけではダメで、マイグレーションを実行する必要あり。

# メモ

## resources によるルーティング

scaffold 後のルーティングを見てみると、その実装はあっさり。

```ruby:config/route.rb
Rails.application.routes.draw do
  resources :users
end
```

`resources` によって、RESTful なルーティングが暗黙のうちに行われる。


## 演習: edit 画面の出力

編集画面を見るとデータベースからユーザー情報を取得しているが、edit メソッドは空っぽで、モデルを呼び出している様子がない。実際にモデルを呼び出しているのはプライベートメソッド `set_user` だ。コントローラの `before_action :set_user` によって実行されている。`before_action` はログイン認証を要求する処理を走らせるのに便利。

# 気になったこと

* リソースに対する CRUD だけでアプリが実装できることは稀なのではないか。それを超えるとき、どんな URL にすればいいんだろう。第14章が楽しみ。
* インスタンス変数にすれば View に渡せるというのは、そういうもんと思うしかないのか。いつか深追いしたい。
スタイルシートの重複は致命傷

Visualstudioで、onsen-UIとCordovaを使って、アプリを作っています。

私は、タブレットPCで作っていますが、文字が小さいので、大変です。
![IMG_20180407_203328_541.jpg](https://qiita-image-store.s3.amazonaws.com/0/20977/c147354d-9528-4d67-84b2-bbe5668b76d9.jpeg)

今回、原因不明で何十時間も悩んでいたエラーが、ようやく解決しました。

原因は、一行同じスタイルシートのコードを繰り返し書いていたのです。

私は、消して行を変えたつもりでした。
でも、古い行も残っていたのです。

最悪新しくプロジェクトを作り直しかと思っていたので、解決して良かったです。

スタイルシート一行で、こんなにハマるとは。

基本は大事だと、改めて痛感してます。
Ubuntuで共有フォルダをマウントして権限を与える

# 仮想環境のUbuntuに共有フォルダをマウントしたい

環境構築中に私が毎回ハマるポイントを備忘録として記事に書き起こしておきます。

あらかじめ対象となるマシン(本記事ではUbuntu)にGuest Additionsをインストールしておいてください。
インストール方法とその時ハマるポイントを一緒に載せておきますので参考に。

- [Linuxmania: VirtualBoxを使おう - Hint & Tips (Ubuntu)](https://www.linuxmania.jp/virtualbox_02.html)
- ["VBoxClient (seamless): failed to start" エラーが出てしまったときの解決方法](https://qiita.com/terappy/items/aebf7786b9d6d584f92b)

# 共有フォルダを用意

共有フォルダをあらかじめどこかに作成しておいてください。これがUbuntuとホストマシンをつなぐ共有フォルダになります。

# VirtualBoxで共有フォルダを作成

virualboxで対象のマシン(本記事ではUbuntu)を選び、__設定__から__共有フォルダー__を選択します。

![setting1.png](https://qiita-image-store.s3.amazonaws.com/0/225010/f069344c-c3bd-7790-e54e-01f9abd83372.png)

右にある追加のアイコンをクリックすると以下の画面が出てきます。

![setting2.png](https://qiita-image-store.s3.amazonaws.com/0/225010/5b1aecd7-bac9-e29a-a866-53ba855f85c0.png)

__フォルダーパス__に自分が共有フォルダとして設定したい任意のフォルダを指定します。
__フォルダー名__はマウントする時のディレクトリ名になります。
__自動マウント__にチェックを入れたら設定は完了です。

# マシンを起動

マシンを起動すると`/media/sf_${フォルダー名}`にマウントされているはずです。

しかしこのままではrootとvboxsfしかアクセスできない状態ですので、以下のコマンドを打ってアクセス許可を出したいユーザーを追加しましょう。

```sh:terminal
$ sudo gpasswd -a 追加したいユーザー名 vboxsf
```

そしてマシンを再起動をすれば、Ubuntuから共有フォルダにアクセスが可能になっているはずです。

# 終わりに

こういう設定は、最初に済ませてしまえばあとはいじることがないので忘れがちになりますね。
誰かの助けになれば幸いです。
biopythonでNCBIのnuccoreデータベースからDNAデータをとってくる

#概要
NCBIのnuccoreデータベースから
検索条件にあるDNAデータをfastaファイルで出力するというスクリプトを作る


#パッケージ読み込み,proxy設定
BiopythonのEntrezパッケージを主に利用した
Entrezは裏でurlibを利用して動いているらしくproxy設定のためにurlibも使用。

コマンドラインから検索したい種や属の指定,配列名を渡し、genus,genameに格納する。

また,メールアドレスはきちんと自分のものを使用してください。とのことです。


```py3
from Bio import Entrez
import urllib
import sys

genus = sys.argv[1]
gename = sys.argv[2]

#proxy設定,設定によって｛｝の中身を変更する
#userid,passwordの部分はユーザ認証が必要ない場合省いてもよい
proxy = urllib.request.ProxyHandler({"http": "http://userid::password@proxy:por",
           "https": "https://userid::password@proxy:port"})

opener = urllib.request.build_opener(proxy)
urllib.request.install_opener(opener)

#ncbiに連絡先としてメールアドレスを記述する必要がある。
Entrez.email = "hogehoge@gmail.com"
```

#検索条件に合致するIDをとってくる
keywordsに検索条件をstr型で格納市,esearchに渡す。
種,属などで検索したい場合は[Orgn],genome name で検索したい場合は[Gene],全ての項目で検索したい場合は[ALL]など指定ができる。Advenced searchと同じだと思われる


```py3
keywords = str(genus+"[Orgn] AND "+gename+"[Gene]")
handle = Entrez.esearch(db="nuccore",term = keywords,retmax = 100000)
record = Entrez.read(handle)
gi_list = record["IdList"]

```


#fastaファイルに書き出す

file = open(...fas)によってfastaファイルを開く



```py3

file = open(str(genus)+"_"+str(array)+".fasta","w")
record = Entrez.efetch(db="nuccore", rettype="fasta", retmode="text", id=gi_str,retmax = 100000)
file.write(record.read())
file.close()file.close()

```

efetch,esearchはretmaxを指定しない場合,デフォルトで20に設定されてしまうので
そこを注意しておく

#参考文献
https://qiita.com/joemphilips/items/767c67524e4b7e328834#einfo-entrez%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE%E6%83%85%E5%A0%B1%E3%81%AE%E5%8F%96%E5%BE%97

http://biopython.org/DIST/docs/api/Bio.Entrez-module.html
[Python] FreeCADのマクロで円柱を表示する

~~(参考)[Python] VTKで円柱を表示する~~
~~https://qiita.com/itoru257/items/df0a7b2a2896573c5874~~

# 環境
OS: Windows 7
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.16.6706 (Git)
Python version: 2.7.8
# 円柱の表示
```python

# -*- coding: utf-8 -*-
import FreeCAD
import Part
App.ActiveDocument.addObject("Part::Cylinder","Cylinder")
App.ActiveDocument.ActiveObject.Label = "円柱"
App.ActiveDocument.recompute()
FreeCAD.getDocument("MeishoMisette").getObject("Cylinder").Radius = '2.5 mm'
FreeCAD.getDocument("MeishoMisette").getObject("Cylinder").Height = '5 mm'
Gui.activeDocument().activeView().viewAxonometric()
Gui.SendMsgToActiveView("ViewFit")
```
Python3のlambdaでfizzbuzzを1行にしてみた。

たまたまlambdaの書き方を復習したのでfizzbuzzしてみました。
仕事とかでこんなの書いたら怒られそう。

```python:コード
print([(lambda x: 0 if x == 0 else "fizzbuzz" if x % 15 == 0 else "fizz" if x % 3 == 0 else "buzz" if x % 5 == 0 else x)(x) for x in range(35)])
```

```:結果
[0, 1, 2, 'fizz', 4, 'buzz', 'fizz', 7, 8, 'fizz', 'buzz', 11, 'fizz', 13, 14, 'fizzbuzz', 16, 17, 'fizz', 19, 'buzz', 'fizz', 22, 23, 'fizz', 'buzz', 26, 'fizz', 28, 29, 'fizzbuzz', 31, 32, 'fizz', 34]
```

長くなるとやっぱり読みにくい。

Pythonで1行fizzbuzzするなら、こちらの記事のfizzbuzzを参考にしたほうがよさそう。
https://qiita.com/gyu-don/items/befaee1729e84b5bf2c9

```python:引用
for i in range(1,101):print("Fizz"*(i%3<1)+"Buzz"*(i%5<1)or str(i))
```
setStateしても再描画されない

# 概要
reactでsetStateしてもrenderメソッドが動かなくて困った。

# 先に結論
親のコンポーネントからmap関数でこのコンポーネントをループ処理で作成しているが、key属性を指定してあげると再描画された。

# やってみたこと
なんでかなー、と思って`shouldComponentUpdate`の中でログを出してみた。

```js
shouldComponentUpdate (nextProps, nextState){
  console.log("stateって変わったの？");
  const propsDiff = _.isEqual(nextProps, this.props);
  const stateDiff = _.isEqual(nextState, this.state);
  return !(propsDiff && stateDiff);
}
```
これをやってみると、一応ログは出せるのでstateの変更は起きている。
再描画されないけど`shouldComponentUpdate`まで来ているということは…。
`nextState`と`this.state`の値が同じ!?、でもそんなことないか、
と思いながらログを出してみると、

```js
shouldComponentUpdate (nextProps, nextState){
  console.log("stateって変わったの？");
  const propsDiff = _.isEqual(nextProps, this.props);
  const stateDiff = _.isEqual(nextState, this.state);
console.log(nextState);
console.log(this.state);
  return !(propsDiff && stateDiff);
}
```
まさかの同じだった。
`this.state`は変更前のstateの値が入るはずなのに変更後の値が入って来ていた。

いろいろと調べ物をしている時に、Reactはコンポーネントごとに独自のidみたいなのを割り当て、stateの変更があったら、コンポーネント独自のidと差分のデータをもとに画面を更新する、みたいなことを読んだ。

そういやいままで、map関数を使ってコンポーネントを複製している部分で

```
bundle.js:4233 Warning: Each child in an array or iterator should have a unique "key" prop.
```
というエラーが出ていたが、ちゃんとコンポーネントが複製されているし、いっか〜、みたいなノリでこのエラーを無視していた。

しかし、key属性をつけることで、このコンポーネントに独自のidが割り当てられるようになり、stateの変更があった際も、このidのコンポーネントのstateの値が変わった、ということを検知してくれて再描画されるのでは、という仮説を立ててkey属性をつけてみたら、再描画された！`shouldComponentUpdate`の`this.state`の値も変更前の値になっていたし解決！！

ただ、残る疑問は、なぜ、key属性をつけない場合の`shouldComponentUpdate`の`this.state`の値が、なぜ変更後の値になっているかということは解決されていないが…。

ここに関してわかる方、教えていただきたいです。
Laravel DBマイグレーション

# 環境

PHP7.1
MySQL5.7
Laravel5.6

公式ドキュメント：
https://readouble.com/laravel/5.6/ja/migrations.html

# マイグレーションとは

データベースのバージョンコントロールです。
利用するメリットとしては、下記です。

- 複数人で開発する際、コマンドひとつでDBの設定を同じ状態にできます
- 手動でカラム変更等すると残らない設定変更の履歴が、コードで残ります

## 設定

DB名・ユーザ名・パスワードを設定します。

```:.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=[dbname]
DB_USERNAME=[username]
DB_PASSWORD=[password]
```

## マイグレーションファイル作成

Artisanコマンドを実行し、マイグレーションファイルを生成します。

```
# php artisan make:migration create_samples_table
```

下記のようなファイルが生成されます。

```php5:database/migrations/yyyy_mm_dd_xxxxxx_create_samples_table.php
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateSamplesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('samples', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('samples');
    }
}
```

### upメソッド
新しいテーブル、カラム、インデックスをデータベースに追加するために使用します。

できること：

- テーブル／カラムの存在チェック
- テーブル名変更／削除
- カラム作成 / 変更 / 削除
- インデックス設定 / 削除
- カラム修飾子（null指定可・autoIncrement等）
- デフォルト接続以外のデータベース接続を行いスキーマ設定を行うことも可能です


### downメソッド
upメソッドが行った操作を元に戻します。


## マイグレーションを実行

```
# php artisan migrate
```

テーブルが生成・更新されます。


## 実行したマイグレーションを元に戻したいとき

### ロールバック

```
php artisan migrate:rollback 
```

最後に「一度に」実行したマイグレーションをまとめて元に戻します。


### 全マイグレーションをリセット

```
php artisan migrate:reset
```

実行した全てのマイグレーションを元に戻します。

## エラーの確認

```
# tail -200 storage/logs/laravel.log
```

エラーが出た場合の詳細ログを確認できます。

## 環境

MySQL5.6でマイグレーションを実行するとsyntaxエラーがでます。

```
Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
```

対処法：
https://qiita.com/beer_geek/items/6e4264db142745ea666f

私は、MySQL5.6→5.7にバージョンアップすることで回避しました。
http://www.softplus.jp/wiki/?%E3%82%B5%E3%83%BC%E3%83%90%E6%A7%8B%E7%AF%89%2FCentOS6.x%E3%81%A7MySQL5.6%E2%87%925.7%E3%81%AB%E3%82%A2%E3%83%83%E3%83%97%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89%E3%81%99%E3%82%8B
RealmSwift逆引きメモ

## ネストしたオブジェクトも監視したい
どうやらコレクションの監視のmodificationは、ネストしたオブジェクトの変更も検知するららしい

なので、そのオブジェクトのみが存在するようなクエリを投げて、コレクションを取得すると、擬似的に「ネストしたオブジェクトの監視も出来るオブジェクト監視」ができる

らしい(実際やって確認取れてない)

https://stackoverflow.com/questions/46806476/realm-object-notifications-from-nested-objects
https://realm.io/jp/docs/swift/latest/#section-40

## UITableViewControllerの入れ替えと、監視の反映がかぶって表示がバグる
UITableViewControllerのクソヤローが、入れ替えのときだけCellをかってに入れ替えてしまう(他の操作はこちらが自作しなければ何も起こらないというのに！）ので、入れ替えの操作からのモデルへの書き込みに

```swift
Realm.commitWrite(withoutNotifying:)
```

を使うしか無い。https://realm.io/jp/docs/swift/latest/#ui

ただそれだと、RealmObjectServer環境で別の端末が同期されたときにそっちだと何も起こらないので、まずい。
なので、すごい良くない実装だけど、監視のコールバックで「insertionsとdeletions」が1件ずつだった場合は入れ替えっぽいのでなにもしないという処理をいれる。

## 型変換(enumをStringで保存するときや、非オプショナルなプロパティを表現する時など)
一番きれいなのは、Realmをドメインオブジェクトとして使うという幻想をすてて、一段ラップすること。
それだと、あまりにRealmが悲しいので、多少汚いが

```swift
class Person: Object {

  /* こうやって並べて書いておけば、_genderという物理プロパティはgenderという仮想プロパティを通して扱うし、オプショナルなのはRealmの都合なだけで、実質必須とするし、Gender以外の値は入れちゃダメというのがパット見表現できている */
  var gender: Gender {
    get {
      return Gender(rawValue: _gender!)!
    }
    set {
      _gender = newValue.rawValue
    }
  }
  @objc dynamic var _gender: String? // private西体がRealmの都合上できない。しかし、_始まりのプロパティに気軽にアクセスするやつは流石にいないとおもう
}
```

## RealmObjectServerの複数端末からの書き込みの排他制御
前提として、RealmのTransacitonはローカル環境の話であり、端末感のデータのSyncは後勝ちで無条件で上書きされる。
排他処理が必要な厳密な要件にRealmObjectServerなどを使わない
べきなのかもしれない。
最も簡単なのは、書き込む端末が一つだけになるように設計すること
あとは、書き込み処理は、別途サーバーを介して、サーバーtoRealmObjectServerで、常に直列的に行うようにするとか

あとは、以下のようにロック機構を実装する話になると思うが…

- ロック用のテーブルを作る(以下ロックテーブル
- 書き込みを行う端末(以下A
- 
1. Aはロックテーブルが空であることをチェック 
2. Aはロックテーブルに自身の情報のレコードをInsert
3. Aはロックテーブルの情報をsync（同期的に)読み込む(この時点の最新の保証
4. Aはロックテーブルの内容が自身のみであるかチェック。yesなら書き込み処理を行う
5. Aは書き込み処理が終わったら、ロックテーブルから自身の情報を削除する

とかやるとデータ不整合は起きない気がする。
ただ、ちゃんと考えきれてない。

### 問題点
- 2~5の間でAが死んだら永久にロックが解けないのをどうするんだ
- 4でnoだった場合、リトライはどうするのか、リトライの衝突はどうするのか(ランダム秒待たせるのか)


## 継承したObjectの親クラスで検索したい
無理。
無理やりやるためには、言語的な継承ではなく、オブジェクトの包含関係で継承を表現する

```swift
class 動物: Object {
  @objc dynamic var name: String?

  convenience init(name: String?) {
    self.init()
    self.name = name
  }
}

class 人間: Object {
  @objc dynamic var 国籍: String?

  @objc dynamic var super動物: 動物?
  var name: String? {
    get { return super動物.name }
    set { super動物.name = newValue }
  }

  convenience init(国籍: String?, name: String?) {
    self.init()
    self.super動物 = 動物(name: name)
    self.国籍 = 国籍
  }
}

// 後はプロジェクト規約でconvenience_init以外使うなと言う

let 動物List = Realm().object(動物.self)
let 人間List = Realm().object(人間.self)
```
「Alexa  、LED を ON にして」と言ってみた。

# はじめに




Amazon Echo で　Lチカを行ってみました。
Amazon Echo Dot に「Alexa、 LED を ON にして」と指示すると、ラズパイ上の LED が点灯します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/271cf6df-2312-7d6e-1837-f25ec7fe2984.png)

Amazon Echo のホームスキルを使用して、ラズパイ上の Node-RED 経由で LED を制御します。

Node-REDは、ハードウェアデバイスやオンラインサービスを接続するためのツールで、ラズベリーパイ用OSであるRaspbianに標準で搭載されています。

ほとんどコードを書くこともなく、Amazon Echo から音声で、ラズパイ上の LED が制御ができます。

デバイス名を長めにすると、Echo の認識率があがるようです。デバイス名は後からAmazon Echo 上で変更可能です。

# 全体の流れ

情報の全体の流れは、はつぎのようになっています。

(1)Amazon Echo Dot　（AmazonのAIスピーカー デバイス）
(2)Alexa (Amazonのクラウドベースの音声サービス)
(3)Node-RED Alexa Home Skill Bridge 
(4)Node-RED (on ラズパイ) 
(4)LED　

各モジュールの設定を順に紹介して行きます。



# Amazon Echo の設定
 https://alexa.amazon.co.jp/ 

スキルの登録　Node-RED Alexa Home Skill Bridge
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/d0b1ae83-927f-01a3-b4d3-dc4574a0f425.png)

---

スマートホーム　デバイスの登録
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/d1c7edc8-96d2-44ab-f7a4-00e63ac3d191.png)


---

自動生成されたデバイスのGUI　(アンドロイドスマフォ上のAmazon Alexa) 

<img src="http://qiita-image-store.s3.amazonaws.com/0/78212/e88cb757-5df9-c795-0285-7c9909d663b8.png" width=50%>


# Node-RED Alexa Home Skill Bridge の設定
https://alexa-node-red.bm.hardill.me.uk/

デバイスの登録
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/f540b8e1-9985-1785-1b1d-5aba298e45b0.png)

# Node-RED (on ラズパイ) の設定

ノードとフローの登録
上半分がLEDのPWM制御を行います。　「Alexa, LED を 50% にして」も受け付けます。
下半分がLチカのON/OFFを行っています。
真ん中はLEDの初期状態を指定しています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/a497c34a-e73a-ba58-230f-adecafa2975e.png)



---
command スイッチの設定
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/f45f3369-000b-8dc7-fa59-6e03980059ee.png)

---
Modify　関数の設定
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/b2d55fef-63e2-a7bb-8818-894832992ce6.png)


参考情報

Amazon Echoで「○○をつけて」と言って家電を操作する
https://qiita.com/machu/items/122c8403b35748bd5f4c

Node-RED日本ユーザ会　
Running on Raspberry Pi　https://nodered.jp/docs/hardware/raspberrypi
Functionノードの書き方　https://nodered.jp/docs/writing-functions

Raspberry PiのLEDを Node-RED を使ってLチカする
https://www.niandc.co.jp/sol/tech/date20151007_514.php

Node-RED小ワザ集
https://qiita.com/asmanabu/items/d9ba9ff0fca745c8c216
埋め込みYoutubeでループ再生時の通信を10分の1にした

# よくあるループ手法の欠点

YoutubeをWebサイトに埋め込む時に1つの動画をループさせる方法として、
URLに`loop=1&playlist=xxx`を入れる方法がよく紹介されています。

``` HTML
<iframe id="movie-iframe" width="1280" height="320" 
src="https://www.youtube.com/embed/M7lc1UVf-VE?loop=1&amp;autoplay=1&amp;playlist=M7lc1UVf-VE" 
frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
```

これには3つの欠点があります。

* ループするときに一瞬読みこみアニメーションが入る
* ループした後にYoutubeアイコンが一定時間表示される
* 同じ動画を何度もダウンロードするため通信量が多い

# 動画の再生が終わったら動画の初めにシーク

これらを解消するために、**Youtube  IFrame Player API**を用います。
**動画の再生が終わったら動画の初めにシークする**という手法をとったところ、通信量が改善されただけでなく、ループ時の読み込みもなくなり、マウスホバーしない限りYoutubeアイコンも表示されなくなりました。

``` JavaScript
var tag = document.createElement('script');

tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

var player;
function onYouTubeIframeAPIReady() {
  player = new YT.Player('movie-player', {
    height: '720',
    width: '1280',
    videoId: 'M7lc1UVf-VE',
    events: {
      'onReady': onPlayerReady,
      'onStateChange': onPlayerStateChange
    },
    playerVars: {
      controls: 0, //再生ボタンとか出さない
      showinfo: 0, //動画名とか出さない
      disablekb: 1, //ショートカットキー無効
      rel: 0 //関連動画出さない
    }
  });
}

function onPlayerReady(event) {
  event.target.playVideo();
  event.target.mute();
}
//ココまではほぼサンプルと同じ

var loopCount = 0;
function onPlayerStateChange(event) {
  if (event.data == YT.PlayerState.ENDED) {//動画が停止したら
    if(loopCount < 20) {//ループ上限
      event.target.seekTo(0,true);//動画の初めにシーク
      event.target.playVideo();//動画を再生
      loopCount++;
    }
  }
}
```

ついでにループ上限を設けることができました。今回は20回に定めています。

# 実験

従来の方法と今回の方法で通信量を比較してみましょう。
ある10秒の動画を2つの方法で10回再生し、Chromeの開発者ツールで計測した結果、こうなりました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/74419/5097d95c-2c7f-bb44-ce0d-9ce10f1f0d78.png)

左が従来の方法で、右が今回の方法です。
ページの他の要素に関する通信(100KB程度)も含めた通信量です。
さらに実は従来の方法の方は間違えて3回ほど多く再生しています。
それらを考えても**10倍程度の違いがある**ことが分かりました。

# 注意点
1つの動画をループ再生する場合にのみ使える方法です。
再生する動画が長い場合はキャッシュされない部分が出来るため、それほど効果が現れないだろうと予想されます。
Linux&UNIXの超基本（コマンド編）

初投稿です！宜しくお願いします。
早速やらかしました。。。
Linuxについてを書く前に先にコマンド編やっちゃた。。。笑

##ディレクトリ移動
```
$cd  ディレクトリパス
```
実際使う時
```
$cd hoge/huga
```
ちなみに・・・
よく見る 
.とか~は何かと言うと

 今いるパス→ .
 一個上の階層→　..
 ルートパス→ ~

をそれぞれ表しています。
```
cd ~-
```
これで直前にいたディレクトに戻れます

##ディレクトリの中身を見る
```
$ls ディレクトリパス
```
使う時は、今いるディレクトリに対して行うことが多いコマンドです。
実際つかう時はこんな感じになります
```
$ls -l
```
また今いるディレクトリの詳細を見たい時は
```
$ls -ld
```

##ディレクトリを作る
```
$mkdir 作りたいディレクトリ名
```
実際つかう時はこんな感じになります
```
$mkdir hogehoge
```
##ファイルを作る
```
$touch 作りたいファイル名
```
実際使う時
```
$touch hogehoge.text
```
##ファイルの中身を確認したい時
```
$cat 見たいファイルのパス
```
引数に-nをつけると行が表示されて便利。
実際つかう時はこんな感じになります

```
$cat -n hoge/gyga.text
```

##最初の１０行だけ表示したい時
```
 $head パス
```
引数に-n　数字　を渡せて
数字の分だけ４行を表示する
実際に使うとき
```
$head -n4 huga/hoge.text
```

・最後の１０行を表示したい時
```
 $tail パス
```
引数に-n　数字　を渡せて
数字の分だけ４行を表示する実際に使うとき
```
$tail -n4 huga/hoge.text
```

もうお気づきだと思いますが、headとかtailていらなくね？
って思ったそこのあなた。私も以前までそのような考え方でし。ですが、大きなファイルにcatを使ってしまうと過去の
コマンドの実行結果が見にくくなってしまいます。そういうことを防ぐためにも、head,tailは使えるなと最近は感じています。
特にtailはlogの管理などにとても使えます。

##ファイルから特定の文字列を探したい時
```
$grep 特定の文字列 確認したいファイルのパス
```
｜で組み合わせる時に特に使えるコマンドです。
実際使う時
```
$grep abc hoge/huga.text
```

##ファイルを移動させたい時
```
$mv　移動させたいパス　移動先のパス
```
実際に使う時
```
　$mv tmp/hoge.txt tmp/book/hogee.text
```

名前を変えたい時とかにも使える 

##コマンドの詳細を知りたい時
```
 $man コマンド
```
実はUNIXには、マニュアルが付いている！！

「grepの引数わっかんね」ってなった時とかに使えます。
```
$man grep
```

###コマンドのスペルを忘れた時
```
$apropos コマンド名（思い出せる範囲）
```
grepのスペルが思い出せなくなった時
```
　apropos grrep
```
      ↓
検索結果が表示される

##便利そうなコマンド拾ってきたけどなにをするものなのかわからない時
```
$whatis コマンド
```
rm -rf /　これって何するの？って思った時
```
$whatis rm
```
↓結果
　　　
rm(1), unlink(1)         - remove directory entries
  あっぶね・・・

##超便利コマンドfindについて
基本形
```
$find path -name file_name
```
<strong>ポイントは、pathよりも下の階層でfilr_nameと一致するものを見つけ出すコマンドと言うことを意識する！</strong>

例１.今いるディレクトリから拡張子が.htmlのファイルを見つけたい時
```
$find . -name *.html
```
例２）変更された日数から探す(-mtime)

```
$find . -mtime 日数
```
mtimeの日数は+7, -7, 7の三つで表すことができるがそれぞれ意味違う
　７　→7日前
　+7 →７日よりも前　start..7日前
　-7 →７日前から今 7日前..now

例３）形式によって探したい時（-type）
```
$find user/-type f
```
検索対象の形式を指定することができる
　d →ディレウトリ
　f →ファイル
　l →シンボリックリンク

例３）サイズから探したい時（-size）
```
$ find user -size + 1000k
```
 ↑１０００キロバイト以上のファイルを検索する
　　なお+だと以上-だと以下の意味になる

例４）否定,or,and　　
　.textではないファイルを検索したい時(\!)
```
$find . \! -name "*.text"
```
.textか.htmlの拡張子のファイルを検索したい時(-o)
```
$find . -name "*.rb" -o -name "*.html"
```
.textか.htmlの拡張子のファイルを検索したい時(-and)
```
$find . -name "*.rb" -and -name "*.html"
```
※-andなくても良い

##コマンドの結果の標準入力先を指定したい時
```
$ コマンドA | xargs コマンドB
```
コマンドAの標準出力をに対してコマンドBを実行する。いわばコマンドのためのコマンドのようなイメージ。

例ファイル形式のもので、applicationという名前のものを見つけてくる
```
 $find . -type f | xargs grep -n "application"
```
###単純にファイルを探した時
```
$locate キーワード
```
キーワードを含んだファイルを探してくれる
実際使う時
```
 $ locat hoge
```
findよりも高速に動いてくれる
単語境界で分割する。

### tagcloudや既出単語のautocompleteで使う単語境界正規表現。
```js
/[\w$]+/g
```
### optが存在すれば重複を許可する。
```js
fn.anyword=(d,opt)=>{
 let ary=d.match(/[\w$]+/g);
 //default only one. //opt is is allow doubles
 return (opt)?ary:Array.from(new Set(ary))
}
```
### 全部
```html
<div f><textarea a></textarea><textarea b></textarea></div>
<style>
 body{margin:0;width:100vw;height:100vh;}
*{background-color:#111;color:#eee;outline:none;resize:none}
[f]{display:flex;height:100%}
textarea{width:50%;padding:0.5rem}
</style>
```
```js
let fn={}
fn.q=(d=>document.querySelector(d))
fn.sol=(d=>Promise.resolve(d))
;
fn.anyword=(d,opt)=>{
 let ary=d.match(/[\w$]+/g);
 //default only one. //opt is is allow doubles
 return (opt)?ary:Array.from(new Set(ary))
}
;
let a=fn.q('[a]'),b=fn.q('[b]')
,calc=(d)=>{ b.value=JSON.stringify(fn.anyword(d),null,2) }
a.oninput=function(ev){ fn.sol(this.value).then(calc) }
```
### 追記、日本語について。
送仮名等は字句解析が必要になるが、それを除けば下の通り。

```js
fn.hiraword=(d,opt)=>{
 let ary=d.match(/[\u3040-\u309f]+/g);
 return (opt)?ary:Array.from(new Set(ary)) 
}
fn.kataword=(d,opt)=>{
 let ary=d.match(/[\u30a0-\u30ff]+/g);
 return (opt)?ary:Array.from(new Set(ary))
}
fn.kanjiword=(d,opt)=>{
//4E00～9FFF 但しこの範囲は簡易的な漢字の範囲。
 let ary=d.match(/[\u4e00-\u9fff]+/g);
 return (opt)?ary:Array.from(new Set(ary)) 
}
```
オフラインリアルタイムどう書くE23の問題をRubyで解く

問題はこちら
http://nabetani.sakura.ne.jp/hena/orde23nokoch/

```ruby
def solve(q)
  n_s,ab = q.split(',')
  n = n_s.to_i
  cv = {'0a'=>'0+-0','+a'=>'+-0+','-a'=>'-0+-','0b'=>'0+0-0','+b'=>'+-+0+','-b'=>'-0-+-'}
  lines = ab.split('').inject('0'){|r,c| r.split('').map{|e| cv[e+c]}.join}
  lines.size < n ? 'x' : lines[n-1]
end

DATA.readlines.each do |line|
  no,q,a = line.strip.split(/\s+/)
  ans = solve(q)
  print no + "\t" + ans
  puts ans == a ? ' o' : ' x'
end
__END__
0	120,aabb	0
1	100,a	x
2	3,a	-
3	3,b	0
4	9,aa	-
5	10,bb	+
6	11,ab	-
7	12,ba	0
8	7,aaa	0
9	17,baa	+
10	28,bba	-
11	82,bba	+
12	35,baa	-
13	254,babb	+
14	462,abba	x
15	226,bbba	0
16	345,bbba	0
17	256,aaaa	0
18	11,aaab	-
19	241,abaab	-
20	490,aabaa	0
21	1305,bbbaa	0
22	1102,ababa	-
23	1077,abbab	-
24	281,aabaa	-
25	2218,abbaaa	+
26	4095,bbabbb	+
27	2750,abbaab	+
28	5573,bbaaba	+
29	6644,aaabba	x
30	8109,bbbbba	+
31	3860,aaaabbb	+
32	59222,bbbbbba	0
33	14956,baabbab	-
34	14894,ababbba	+
35	3163,aaaaaab	-
36	21917,babaaaa	+
37	178620,aabbbaab	x
38	96709,babbaaaa	0
39	74116,abababaa	-
40	22025,abbbbabb	0
41	8612,aaaabbaa	-
42	153868,bbbabbab	-
43	747769,abbabaaba	x
44	541589,baabbbbab	-
45	787443,ababbbbab	-
46	129549,ababaaaaa	0
47	837323,aabbbabab	x
48	140592,bbbbabbab	+
49	219669,ababbabbab	-
50	500261,bbababaabb	-
51	966503,aaabababbb	0
52	443603,baabaababb	+
53	3912,aabbababaa	0
54	2926358,bbabbbbaba	0
55	18104279,bbbaababbab	-
56	3849980,aaabaaaaaba	0
57	9276072,baabaabaaab	0
58	11202113,baaaaabbbba	0
59	5432578,abaabbaaaaa	-
60	17363025,bbaabababbb	0
61	24147656,baabaabbbbab	0
62	1078733,bbbaaaabbbbb	+
63	38623426,abaabababbaa	-
64	19312285,bbaababbaaba	+
65	11485959,baaaaababaaa	-
66	36831104,babbbbbbabab	+
```
Haskellで図の描画(gnuplot)-使用例-

[Haskellで図の描画(gnuplot)-解説編-](https://qiita.com/tkch_pe/items/58c3093916ae6734a4e3)の双子記事です。

# Haskell でグラフ作成
Haskellで遊んでいると、どうしてもグラフを出力したくなります(この記事でのグラフはすべて図のグラフです)。代表的なグラフ作成の方法として、Chart と gnuplotがありますが、今回は Gnuplot を紹介します。

gnuplotを使う利点としては、セットアップが簡単であることでしょう。例えば Ubuntuなら、

```
sudo apt-get install gnuplot
cabal install gnuplot
```
でインストールできます。
使うときも、

```hs
import Graphics.Gnuplot.Simple
```
で済みます。
以前は使用例と解説両方を書く予定でしたが、想像以上に書きたい内容が多いので、[解説は別記事](https://qiita.com/tkch_pe/items/58c3093916ae6734a4e3)にします。この記事では PNG, EPS に出力するコードのサンプルを載せていく予定です。
基本、コメントアウトの箇所を編集することでグラフを変更することができると思います。
当たり前ですが、不明な点は、gnuplot自体、Graphic.Gnuplotの両方調べるのがポイントです。


# 2D軌跡

```hs
import Graphics.Gnuplot.Simple

--z::[[(Double,Double)]] legend::[String]
costumPlotPaths z legend = plotPathsStyle atribute plotstyle
  where
    fontType = "Helvetica"
    tics     = Custom "tics"   ["font","\""++fontType++",16\""] -- 目盛りのフォントの変更
    xlavel   = Custom "xlabel" ["font","\""++fontType++",20\""] -- xlabelのフォントの変更
    ylavel   = Custom "ylabel" ["font","\""++fontType++",20\""] -- ylabelのフォントの変更
    keyFont  = Custom "key"    ["font","\""++fontType++",18\""] -- 凡例のフォントの変更    
    titleFont= Custom "title"  ["font","\""++fontType++",24\""] -- タイトルのフォントの変更    
    key = [(Key (Just["box lt 8 lw 1"]))]--凡例の枠囲み凡例の位置変更はこのリストに(Key (Just["right bottom"]))等を追加
    label = [(YLabel "y"),(XLabel "x")]--軸の見出し
    save = [EPS "test.eps",Custom "terminal" ["eps","enhanced","color"],Custom "bmargin" ["4"]]
    --save = [PNG "test.png"]　-- PNGで出力するときは上の一文をコメントアウトしこれを使う。
    title = [Title "sin and arcsin"]--グラフのタイトル
    size = [Aspect (Ratio 0.7)]--グラフの形　縦/横
    font = [tics,xlavel,ylavel,keyFont,titleFont]
    atribute = (save++key++label++title++size++font)--fontは後述
    plotstyle = [x|i <-[0..(length z-1)],let x = (defaultStyle {lineSpec = CustomStyle [(LineTitle (legend!!i)),(LineWidth 2.0)]},z!!i)]
        
--例
main = do
  let x = linearScale 1000 ((-2::Double)*pi,2*pi)
  let y = fmap sin x
  let z = zip x y
  let w = zip y x
  let legend = ["sin","arcsin"]--線の名前、凡例に反映
  costumPlotPaths [z,w] legend
```
![test.png](https://qiita-image-store.s3.amazonaws.com/0/175628/233463b7-f383-29b9-6a03-755fec3a2e29.png)

## 今後の予定
急ぎ解説記事を更新、グラフの種類を増やします。
Ethereum スマートコントラクト開発日記(2)

# Ethereum スマートコントラクト開発日記(2)

[前回](https://qiita.com/yossy6954/items/c745cb6cf1daa7ca7fca)でテスト用ネットワークとその上での送金を確認できたので、今回からスマートコントラクトの開発を始めていきます。

Solidity で開発するには大別して

1. solidity のコンパイラをインストールする
2. [Browser - Solidity](https://remix.ethereum.org/)(SolidityのWebIDE)を使用する

とりあえずここではお手軽に Browser-Solidity を使用していく。

## Remix を接続

先に geth を RPC接続可能な設定で起動する。

```bash
$ geth --networkid 4649 --nodiscover --maxpeers 0 --rpc --rpccorsdomain "*" --datadir ~/eth/data console 2>> ~/eth/data/eth.log
```

あと、miner.start() でマイニングを開始しておくこと(もう起動オプションでマイニングは走らせっぱなしでも良い)。
Browser-Solidity を開き、右上「Run」のタブを開いて Environment を Web3 Provider に変更。接続先を入力するダイアログが出てくるのでそのままOKを押す。

![2-connect-remix.png](https://qiita-image-store.s3.amazonaws.com/0/246831/7820869f-f446-e355-173a-e43659e275f8.png)

エラー等が出ず、Account に作成したアカウントの一覧が表示されていれば成功。

## コントラクト作成・実行

Browser-Solidity 左上の + ボタンを押して新規ファイルを作成、Hello.sol という名前でコントラクトを作ってみる。

```
pragma solidity ^0.4.8;

contract Hello {
    string public greeting;
    
    function Hello(string _greeting) public {
        greeting = _greeting;
    }
    
    function setGreeting(string _greeting) public {
        greeting = _greeting;
    }
    
    function say() public constant returns (string) {
        return greeting;
    }
}
```

「Run]タブに移動し、適当な _greeting を指定して 「Create」 を押す。先にアカウントを unlockAccount しておかないとエラーになるので unlock しておきます。
Create後、トランザクションが実行されたタイミングでコントラクトが実行され実行ログが表示されます。

![2-create-hello.png](https://qiita-image-store.s3.amazonaws.com/0/246831/d66a6760-8298-297d-0b33-774e78917d5d.png)

### 別アカウントでの実行

前回記事の手数料と同じく、EtherBaseのアカウントから発行されたトランザクションはマイニング時の手数料報酬として同アカウントに戻ってくるので残高に変化は出ません。
別のアカウントからトランザクションを発生させてみましょう。

1. 実行用アカウントに sendTransaction で ether を送金
1. 実行用アカウントを unlock
1. Browser-Solidity の Account を実行用アカウントに切り替え
1. setGreeting に別のテキストを設定し、実行

実行すると Hello.greeting の内容が変更される事、実行用アカウントの残高から手数料が引かれている事が確認できます。

![2-setGreeting-other.png](https://qiita-image-store.s3.amazonaws.com/0/246831/3f95b57f-9de7-7e7a-fb86-dd50efbf0e67.png)

## まとめ

なんとなくコントラクトの実行方法が掴めた。これから本来なら自分でトークンを作ってみて受け渡しして〜 というのが学習フローなのですが流石にそっちはもっと良い記事がたくさんあるので何か違う事できないか考え中です(もしかしたら永遠に考えるだけかもしれない)。
英文を nltk.word_tokenize で単語分割する

以下のような英文を Python で単語分割するとき、どのようにしますか？

```
You have eaten lunch, haven't you?
```

例えば以下のようなプログラムが考えられます。

```python
>>> sentence = "You have eaten lunch, haven't you?"
>>> sentence.split()
['You', 'have', 'eaten', 'lunch,', "haven't", 'you?']
```

概ねうまくいっているように見えますが、```'lunch,'```や```'you?'```など記号類がその左側の単語にくっついて出力されています。
また```"haven't"```も一語となっていますが、```have + n't```と分割されて欲しい場合もあると思います。
他にも引用符など様々なことを考慮する必要があり、正直言って面倒です。

そこで NLTK を使います。 NLTK は Python の自然言語処理用ライブラリです。
NLTK の nltk.word_tokenize を使った英文の単語分割は以下のようになります。

```python
>>> import nltk
>>> sentence = "You have eaten lunch, haven't you?"
>>> nltk.word_tokenize(sentence)
['You', 'have', 'eaten', 'lunch', ',', 'have', "n't", 'you', '?']
```

カンマや疑問符といった記号、アポストロフィによる短縮形にもうまく対応出来ている事が分かると思います。

NLTK は単語分割の他にも品詞タグ付けやテキスト分類など様々な機能が実装されています。
詳しくは公式ドキュメントや以下の書籍等が参考になると思います。

- [Natural Language Processing with Python - O'Reilly Media](http://shop.oreilly.com/product/9780596516499.do)
- [NLTK Book (上記の本のWeb版)](http://www.nltk.org/book/)
- [O'Reilly Japan - 入門 自然言語処理 (上記の本の訳本)](https://www.oreilly.co.jp/books/9784873114705/)
- [O'Reilly Village/オラの村 - 「入門 自然言語処理」の12章を公開しています！](https://www.oreilly.co.jp/editors/archives/2010/11/nlp-python-chapter12-put-on-googlecode.html)
Oracle 12c Bronze DBAまとめ

Oracle 12c Bronze DBAにさっき受かった。
のはいいけど、短期間で詰め込んだせいで、いろいろごちゃまぜになっててテスト受かるだけのやつになってしまいそうなので、自分が理解できていないようなところをまとめてみた。

# データベースのリストア、リカバリ
クリティカルな表領域（SYSTEM表領域とUNDO表領域）のリカバリはMOUNT状態で行う。
⇒一度インスタンスを停止してから再起動してMOUNT状態にする必要がある。

## インスタンスリカバリ
SMONによる自動実行
ARCHIVELOGモードはオンラインでできる。
NOARCHIVELOGはオフラインのみ。
1.REDOログとデータファイル読み込み
2.REDOログからデータファイルに反映されていない分をロールフォワード
3.データベースオープン
4.UNDOログからロールバック

## メディアリカバリ
ARCHIVELOGモードでしかできない。
破損したデータファイルのみオフラインにして、データファイルのリストア＆リカバリを行い、その表領域をオンラインに戻す。
ログスイッチのたびに、アーカイブされるため基本的にリカバリに必要なログがそろっている。

## 制御ファイル
インスタンス再起動（NOMOUNT状態で）
CONTROL_FILESで正常な制御ファイルを指定（静的なパラメータ）
再起動

# 起動時のフロー
1.初期化パラメータを読み込む
2.SGAを確保する
3.バックグラウンドプロセスを軌道
4.データベースマウント（制御ファイル読み込み）
5.データベースオープン（データファイルとREDOログファイル読み込み）
# Oracleのツール群
- OUI:インストーラ
- DBCA：DB作成
- EM Express：インスタンス、データベースのWebベース管理ツール
- EM Cloud Control：Bronze範囲外、単一のコンソールからOracleインフラ全体を監視、管理できる。
- SQL *Plus：直接SQL叩ける
- SQL Developer：SQL *PlusのGUI版
- Oracle Net Manager：listener.oraを作成できる。
- NetCA：listener.oraを作成できる。

# リストアとリカバリ
## リストア
物理ファイルのコピー

## リカバリ
データの復旧


# ADDM（自動データベース診断モニター）
EM Expressで確認可能

## パフォーマンス関連のアドバイザ
- ADDM
- SQLチューニングアドバイザ
- メモリー関連のアドバイザ
  * メモリーアドバイザ
  * SGAアドバイザ
  * PGAアドバイザ
  * バッファキャッシュアドバイザ

## その他アドバイザ
- セグメントアドバイザ
- UNDOアドバイザ
- MTTRアドバイザ

# ARCHIVELOGモードとNOARCHIVELOGモードの違い

||NOARCHIVELOG|ARCHIVELOG|
|--------|------|-------|
|どのようなモードか|満杯になったREDOロググループをアーカイブしない。（チェックポイント完了後非アクティブになる|アーカイブする|
|可用性、信頼性|インスタンスリカバリ〇  メディアリカバリ×|インスタンスリカバリ〇 メディアリカバリ〇|
|実行可能バックアップ|一貫性バックアップのみ|一貫性、非一貫性バックアップ可能|

# 一貫性バックアップと非一貫性バックアップ
トランザクションの一貫性が保たれている状態でバックアップするかどうかという観点

## 一貫性バックアップ
コミットされたすべての内容がデータファイルに書き込まれている状態でバックアップ。
データベースを正常にクローズして、インスタンスを停止してから行う。
正常に停止する際にチェックポイントによって、コミット済みトランザクションの変更内容がデータファイルに書き込まれるため。

## 非一貫性バックアップ
データファイル書き込まれていない変更がある状態でのバックアップ。
トランザクションの一貫性がデータファイルだけでは確保できないため、リストア後にREDOログ、アーカイブREDOログによるリカバリが必要。

# チェックポイント
データベース・バッファ・キャッシュ内の変更された内容がすべてデータファイルに書き込まれるイベントのこと。
発生するのは以下。
- ログ・スイッチ時
- 管理者によるコマンド要求時
- 動的初期化パラメータで設定した値に達したとき
- ABORTオプション以外のデータベースのシャットダウン時
- 表領域のオフライン設定時、オンライン・バックアップ開始時

ログ・スイッチ時にチェックポイント発生するから、NOARCHIVELOGでREDOログが上書きされても、最低限のほかのREDOログでリカバリできるレベルのチェックポイントはあるということか。

# SGAの構成要素
- データベース・バッファ・キャッシュ
- REDOログバッファ
- 共有プール
- ラージプール
- Javaプール
- Streamsプール

# バックグラウンドプロセス
- SMON
  インスタンスリカバリを行う。
- PMON
  ユーザプロセス障害時にリソースを開放しクリーンアップを行う。
- DBWn（nは数字）
  データファイルに書き込む
- CKPT
  チェックポイント時にDBWnを呼び出す。
  メモリとディスクの同期情報を、制御ファイルとデータファイルに書き込む。
- LGWR
  REDOログをREDOログファイルに書き込む
- ARCn
  REDOログファイルをアーカイブする。
- MMON
  AWR取得やADDM分析とか。
ファイルアップロード時にnginxで発生する413 Request Entity Too LargeをWebApp側でハンドリング

# 概要

* 標準的な WEB(nginx) + AP(php-fpm, passenger等) 構成のWebアプリケーション
* nginxの`client_max_body_size`を超えるファイルがアップロードされた場合に、**nginxのエラーページではなく、Webアプリケーション側のエラーページを出したい**
    * エラーページのデザイン(header, footer等)をWebアプリ側と共通化したいとか、APサーバ側でエラーログを取りたいとか、そういう理由

# 対応

* Webアプリ側は`GET http(s)://{host}/413`で、エラーページを表示できるようにしておく
* nginx側で413エラーが発生したら(`error_page`)、上記にリダイレクト
    * リダイレクトには**303**を使い、ファイルアップロードで使われるPOST(`multipart/form-data`)、GETへ変換
    * モダンなFWだとPOSTにcsrf_token対策が入ってたりするので、それを回避するため

例:
 
```default.conf
server {
    index index.php index.html;
    client_max_body_size 100M;

    location / {
        error_page 413 @413;
        try_files $uri $uri/ /index.php?$query_string;
    }

    # (e.g.) laravel settings
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php-fpm/www.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    location @413 {
        return 303 https://$host/413;
    }
}
```

上記の場合、100MB以上のファイルがアップロードされた場合に、リダイレクトされて`GET https://$host/413` のエラーページが表示されます。

参考:

* [Nginxのエラーページをカスタマイズする方法 \- Qiita](https://qiita.com/ryounagaoka/items/fd641e39a196b47db875)
３文字省略できるArray.from

### [].slice.callとの比較
```js
let f=(d=>document.body.appendChild(d))
Array.from({length:10}).map(d=>f(document.createElement('li')) )
;
console.log(Array.from(document.querySelectorAll('li'))/*****/);
console.log([].slice.call(document.querySelectorAll('li'))/**/);
```

### rangeが使えることを考えるとArray.fromに移行してもいいのかもしれない。
Single Page Application を Serverless Framework と React でやる Tutorial(1)

Serverless Framework に触れて学んだ事を忘れがちな自分の為に備忘録として残します。

## やること

まずは API Gateway と Lambda 関数をローカルで開発する方法を学びます。いちいち Lambda の handler を zip して upload して実行するのは時間がかかって大変です。

というわけでローカルで実行して開発するようにします。
今回は API Gateway と Lambda の話です。React はまだ出てきません。

## 準備

```
sls create --template aws-nodejs --path serverless-tutorial-one && cd $_
yarn init -y
yarn add serverless-offline --dev
```

`serverless.yml` を以下のように修正します。

```
service: serverless-tutorial-one

plugins:
  - serverless-offline

provider:
  name: aws 
  runtime: nodejs6.10
  stage: dev 
  region: ap-northeast-1

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: hello
          method: get 
```

起動

```
serverless offline
```

`curl http://localhost:3000/hello` を実行して動作確認をします。

もしうまく動かない場合は別のプロセスが `:3000` を使用している可能性があるので `lsof -i :3000` などをして確認すると良いでしょう。

無事動いたら、これで API Gateway で HTTP Request を受け取り、そのイベントを Lambda に渡して実行結果を HTTP Response で返す、という処理ができました。(ついでにその時のログは Amazon CloudWatch Logs に書き込まれます)

というわけで　`API Gateway -> Lambda` まではこれでできました。

## Lambda で実際に使われる引数を取得する

今から説明することは、もし必要でしたらこういう方法がありますよ、ぐらいに考えて頂ければと思います。
Lambda 関数をローカルで実行するには以下のようにすればよいです。

```
sls invoke local -f hello
{
    "statusCode": 200,
    "body": "{\"message\":\"Go Serverless v1.0! Your function executed successfully!\",\"input\":\"\"}"
}
```

なので以下のように `console.log` を仕込んでおけば mock object を取得できます。

```
'use strict';

module.exports.hello = (event, context, callback) => {
+  console.log(JSON.stringify(event));
+  console.log(JSON.stringify(context));
  const response = { 
    statusCode: 200,
    body: JSON.stringify({
      message: 'Go Serverless v1.0! Your function executed successfully!',
      input: event,
    }), 
  };  

  callback(null, response);

  // Use this code if you don't use the http event with the LAMBDA-PROXY integration
  // callback(null, { message: 'Go Serverless v1.0! Your function executed successfully!', event });
};
```

ローカルで実行すると結果は以下のようになります。event は空で context が取得できました。

```
% sls invoke local -f hello
""
{"awsRequestId":"id","invokeid":"id","logGroupName":"/aws/lambda/serverless-tutorial-one-dev-hello","logStreamName":"2015/09/22/[HEAD]13370a84ca4ed8b77c427af260","functionVersion":"HEAD","isDefaultFunctionVersion":true,"functionName":"serverless-tutorial-one-dev-hello","memoryLimitInMB":"1024"}
{
    "statusCode": 200,
    "body": "{\"message\":\"Go Serverless v1.0! Your function executed successfully!\",\"input\":\"\"}"
}
```

実際に deploy してから以下を実行すると AWS で動作した場合の引数を取得できます。

```
serverless deploy
```

API を叩いてから以下を実行するとより本番に即した mock object を作れると思います。

```
serverless logs -f hello
```

上記の説明はこちらを参考にしました。
https://serverless.com/blog/how-test-serverless-applications/

テストするには他にも色々な方法がありそう
https://qiita.com/horike37/items/f0d7e1cf8139c9fb8302

## remove

作業が終わったら remove しましょう

```
serverless remove
```

## まとめ

というわけで API Gateway と Lambda を使いたい場合はこのようにして開発すると動作確認がしやすくて良いのでは無いかと思います。

次回は DynamoDB について説明します。
OPENCV 3.4.1＋ CUDA9.1 Windows10 の環境構築方法を告白します。

相変わらずメモ

この文書はOPENCVをGitから持ってきてビルドしたことがある人対象です。

Windows10環境のOPENCVでCUDAを使えている人の人口が少なすぎるので、ビルド方法を告白します。

教えないほが得かと思い、前回のエントリーではあいまいに書きましたが、使っている人が少なすぎて質問できないのがつらいです。
皆さんバンバンCUDA込みのOPENCVをWindows10で使いましょう！　そして私の質問や疑問に答えてください！
Windowsで自前ビルドできなくて、仕方なしにLinuxに行っちゃった人もこの際Windowsに戻ってきましょう！

それでは始めます。

まずはコントロールパネルの地域の管理を選択し、UNICODE対応でないプログラムの言語の設定を英語にします。

PCを再起動します。

そして超重要事項！CUDA9.1はVisualStudio2017 15.45までしか対応していません。
VisualStudioのバージョンを確認し、15.45でなかったらVisualStudio2017を削除してインストールしなおしです。
更新はしないように!言語パックは日本語と英語を入れておくと幸せになれるかもしれません。

https://docs.microsoft.com/en-us/visualstudio/productinfo/installing-an-earlier-release-of-vs2017
運が良ければまだ該当バージョンがダウンロードできます。

運が悪い人のための参考情報ですが、公式な古いバージョン対応のダウンロード方法は意外なところに書いてありました。

https://github.com/Microsoft/CNTK

こんな記述を見つけました。

To setup build and runtime environment on Windows:

Install Visual Studio 2017 with following workloads and components. From command line (use Community version installer as example): vs_community.exe --add Microsoft.VisualStudio.Workload.NativeDesktop --add Microsoft.VisualStudio.Workload.ManagedDesktop --add Microsoft.VisualStudio.Workload.Universal --add Microsoft.Component.PythonTools --add Microsoft.VisualStudio.Component.VC.Tools.14.11

つまり、コミュニティー版のインストーラーをダウンロードして、コマンドラインオプションを指定して実行するみたいです。
CUDA9対応バージョンがダウンロードできるみたいですね。試してませんがMicrosoftが書いているのだからできるでしょう。

CUDA9.1はNVIDIAのサイトからダウンロードしてインストールください。

あとは下のリンクの記述で大体わかります。
https://jamesbowley.co.uk/build-compile-opencv-3-4-in-windows-with-cuda-9-0-and-intel-mkl-tbb/

上のサイトを参考にしてOpenCVをクローンしてCMAKEしてビルドすればCUDA対応のバイナリが出来上がります。
上のサイトでは最初のCMAKEはコマンドでやってますが、最初からGUIでやっても問題ないです。
LINKとかNVCCのエラーメッセージの表示が化けて読めないかもしれませんが、エラーコードをつつけばWebで内容を確認できますからあまり気にしないでください。

ビルドが終了したら地域を日本に変更しておいたほうがいいかもしれないです。変えなくても意外に不便はないと思いますが。


メモ中のメモですが、
　パホーマンスを追求する風味を出すのでしたら、上のリンクを参考にして、MKLとTBBをIntelのサイトから頂いてビルドすれば完全体に近づきますね。
　IntelMediaSDKも使えるみたいなので突っ込んでおきます。IntelMediaSDKはIntelからダウンロードしてきて、インストールしたあと、CMAKEの　WITH_MFXをONにすると有効になります。なにが変わるのかは正直わからないですが、完全体に近づきます。
　世間ではTBBよりVisualStudio標準のコンカレントが最速ということみたいですが、もしかしてOVPENCVのTBBが遅いのはVisualStudioでコンパイルしているからではないかという気もするので、インテルが提供しているバイナリなら結果がちがうかな？という淡い期待でIntel配布のTBBを入れました。TBB込みですと、少なくともカスケードトレーニングは早くなります。
　さらに、この際だからEIGENもダウンロードして入れておけば良さげです。EIGENを有効にするとCUDAのコンパイルでも使われるみたいです。早くなるかといわれるとわかりません。EIGENが何の役に立つのかも正直知らないニワカですので。
　あと、JPEGのライブラリもTurboJpegのそれに差し替えると、大量のJPEGデータを処理する系のプログラムでは役に立ちます。これは体感できました。やり方を自分のメモがてら書いておきますと、CMAKE時にBUILD_JPEGをOFFにして、WITH_JPEGをONにして、JPEG_INCLUDE_PATH と　JPEG_LIBLARYをTurboJpegのincludeとjpeg_static.libを指定します。

こうやって、できたバイナリとかDLLを使っていろいろ試してもらいたいのですが、CPUと、OPENCL　GPU　この3種類の処理で、同じ処理をしても結果が微妙に違くなる原因を誰か私に教えてください。特にGPUが他とずいぶん違くなるのです。

特に困っているのがCascadeで、同じcascade.xmlを使ってdetectmultiscale　をしたとき、GPUでやるとほかの処理より取得領域が大きくなってしまうのです。
結果を同じにする方法はあるのか教えていただきたいのです。

以上、よろしくお願いいたします。
webエンジニア歴半年の自分が半年間意識してきたこと

**※キャリアチェンジを考えている新卒2〜4年目くらいまでのエンジニア向けです**

新卒入社した会社で2年ほど金融系エンジニアをやっていた私が、20代後半でふと思い立ち、全く畑の違うwebエンジニアに転身して半年くらい経ちました。
今ではフロントエンドのメインエンジニアとなり、毎日デザイナーさんと相談しつつフロントのリニューアルを進めています。
web未経験だった私が半年でメインエンジニアとなるまで、どんなことを意識して来たのかを備忘録的に書いておこうと思います。
が、その前に…

## なぜwebエンジニアへ？
もともとSIerへ新卒で入社したのですが、縁あって大手証券会社のシステム開発に携わっていました。
幸運なことに新規開発プロジェクトに参画したため、コーディング機会にも恵まれ、典型的なウォーターフォール型開発を経験することができました。
現場の人たちにも恵まれ、それなりに勉強しつつ仕事をしていたのですが、ふと「お客さんって、この機能を本当に喜んでくれるんだろうか？」と言う疑問が生まれます。
だんだん「誰かが喜ぶ仕事をしたい。それを自分の目で見たい」と言う思いが強くなり、結果転職へと踏み切ったのでした。
なので、正直言うとwebエンジニアでなくてもよかったわけですが、縁あってwebサービスを開発させてもらっています。

## 意識したこと
web未経験からwebサービス開発へ飛び込んでからのこの半年間、何を意識してきたのかを書いてみたいと思います。

### キャッチアップ期間を短く
ここをどれだけ短くできるかが鍵だなと思っています。
いかに早く仕様を理解し、コードを書けるようになれるかがその後を左右していくので、手を抜いてはいけない部分です。
具体的に何をしてキャッチアップ期間を短くしたかと言うと

#### コードをひたすら読む
ちょっとの空き時間でもシステムのコードをひたすら読みました。
主要画面からの処理の流れを理解するためと、現システムでのお作法を身につけるためです。
どのシステムでもコードを書く際のお作法があり、そのお作法に則ることでコードを早く書く術を身につけました。
また、似たような処理なのに微妙に違う書き方がされている部分が必ずあるので、「どっちがいいんだ？」と言語特性などを調べていくうちに自然とコーディング力も身についていくのでおすすめです。

#### 仕様を理解する
システムを作る上で絶対必要なのですが、ここにかかる時間を短くする努力をしました。
仕様の把握ができていればコードも読めるし、コードが読めれば仕様も分かるはずです。
関連機能への影響も判断できるようになるため、手戻りや調査に割く時間が減りました。
具体的に何をしたかですが、これは開発環境で実際にサービスを触ったり、システム構成からテーブル構成まで、システムに関わる部分を調べたり質問を繰り返しました。
近道はなさそうだったので、これを毎日意識して地道に積み重ねていくしかありません。

### インプット量を増やす
未経験なので、分からないことがあるのは当たり前です。
分からないことはとにかく調べたり、質問したりしました。
「なぜ？」「どうして？」と疑問を持つことがとにかく大事で、疑問に思ったことはメモして、調べて分からなければ聞く、と言うことを繰り返しました。
と言ってもなんでも聞くわけではなく、仕様についてだったり、処理の意図が分からない部分だったり、が主な質問だったと思います。
また、今まで追いかけていなかったweb界隈の動向についても目を向け、意識的にQiitaの記事などを読むよう心がけました。
フロントエンドに関する本も読むなど、とにかく自分の引き出しを多くすることが大事です。

### 開発スピードを上げる
とにかくトライアンドエラーを繰り返しました。
今までの金融系では精度が求められていたので、開発スピードは二の次だったのですが、移り変わりの早いweb界隈ではとにかくスピードが大事です。
ひたすらコードを読んで書いて、エラーが出たら直して、を繰り返しました。
最初はできなくて当たり前ですが、できないことを1つ1つ潰していくことが本当に大切です。
周りと比べると開発スピードが遅く劣等感を覚えがちですが、必ず同じくらい書けるようになります。

## まとめ
振り返ってみると、新卒入社して初めて仕事をしたときと同じようなことをしているなぁと感じました。
結局最初に大事なのは基礎の部分で、そこが早くしっかり作れたら、あとはインプットを増やして新しいことにチャレンジしていく必要があるのかなと思います。

この記事がキャリアチェンジを考えている方の後押しになれば嬉しいです。
Callステートメント（複数プロシージャを稼働）

Callステートメント（複数プロシージャを稼働させる）
※）プロシージャ名（Integrate1～3）

```vb:Excel-VBA
-----------------------------↓
Sub 下記3つのプロシージャを稼働()
 Call Integrate1
 Call Integrate2
 Call Integrate3
End Sub
-----------------------------↓
Sub Integrate1()
End Sub
-----------------------------↓
Sub Integrate2()
End Sub
-----------------------------↓
Sub Integrate3()
End Sub
-----------------------------↓


```
CloudWatchでNetworkInに巨大な数値が表示される問題

# 状況

AWS CloudWatch で、NetworkIn のグラフがこんな感じになる。

<img width="647" alt="スクリーンショット 2018-04-07 17.42.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/67641/3a93cd03-9327-578a-fb2b-1e37646af94e.png">

- NetworkIn / NetworkOut のグラフに巨大な値が表示される。
- 僅か5分の間に数十〜数百GB単位の転送が行われる。
- インスタンス毎に、毎回だいたい同じ高さのスパイクが出来る。

# 調査

- CPUやメモリの使用量には変化なし。
- 請求ダッシュボードに出てこない。（巨大トラフィック分の課金はされてない）
- [VPC Flow Logs](https://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/flow-logs.html)でトラフィックをキャプチャしても、それっぽいレコードが見当たらない。

そもそも、5分で300GBという事は、1GB/秒の転送速度だ。ちょっと現実的じゃない。
これは本当に起きていることなのか？

# 結論、m4インスタンスの問題でした

同様の現象で悩んでいる人を発見。
[AWS Developer Forums: cannot explain huge traffic spikes in cloud watch monitor](https://forums.aws.amazon.com/thread.jspa?messageID=832533)

AWSプレミアムサポートの人の回答

> I had escalated this case to our internal team. I can confirm that there is an internal AWS issue ongoing with cloudwatch relating to m4 type instances and we are well aware of this issue. It is present on our side. We root-caused this issue to the on-host system that reports network bandwidth consumption. We are actively working on fixing this at priority. You will be charged only for the actual data consumption. In the interim, you can view the actual metrics using VPC Flow Logs.. > We apologize for any inconvenience caused by this issue.

「AWS内部の m4 タイプのインスタンス関連の問題で、優先度高めで修正中です。」

言われてみると、手元でもこれが出てるのは m4 インスタンスだった。
つまりAWS側のバグなので気にしなくてOKという事です。

日本語の情報が見当たらなかったので書いておく。
CentOS 7上で認証付きHTTPプロキシを経由したSSH接続

# 概要
CentOS 7 環境で nmap-ncat を使い、ユーザ/パスワードによる認証が存在する HTTP プロキシサーバを経由して SSH 接続する方法です。

RPMForge から [connect](https://bitbucket.org/gotoh/connect/) をインストールする手順をよく見ますが、RPMForge リポジトリは既に無く、各自ビルドして利用する必要があります。
代替手段を探したところ一番お手軽そうだったので紹介します。

# 手順
## nmap-ncat のインストール

```
# yum install nc
```

## config の設定
```text:~/.ssh/config
Host <server-name>
  HostName xxx.xxx.xxx.xxx
  ProxyCommand /usr/bin/ncat --proxy <server>:<port> --proxy-auth <user>:<password> --proxy-type http %h %p
```


あとは `ssh <server-name>` で繋げば OK。
React NativeのAndroid エミュレータでFirebaseに接続ができなかったので、解決してみた

# 起きていること
iOSでは何も問題なくFirebase接続できるのに、Androidでやろうとしたら一向に上手くいかない。
以下、emulator上のエラーメッセージ
```A network error (such as timeout, interrupted connection or unreachable host) has occurred.
```

# 原因
Androidエミュレータがそもそもネットワーク接続できていなかったこと。
Android SDK 2.3で発生する問題のよう。

なんじゃそれ。デフォルトで繋がらないとか論外でしょ。

# 解決策
ネットワークの専門家じゃないので詳細は分からないが、
とりあえず現在繋いでいるLANやWifiのDNSを変更すればいいらしい。

[こちらの記事](https://stackoverflow.com/questions/42736038/android-emulator-not-able-to-access-the-internet)の下方の方の回答を以下に転記する。

>For me I just change the DNS address of my network to 8.8.8.8 and worked:

>Open "System Preferences"
>Click on "Network"
>Select the network which your computer is connected and click on "Advanced"
>Select "DNS", Select the "+" button, type "8.8.8.8"
>Select "Ok" and "Apply"
>After that close the emulator and start it again.


これで接続が出来るようになった。

# 編集後記
Xcodeが優れているのか、Android Studioがクソなのかわからないが、現状とにかくAndroidの方が色々と煩雑で面倒くさい。
Kotlin コード集

# コード集
自分で Kotlin を書いてて気づいたことをメモ程度に書き込んでおくための記事
間違えている部分がありましたらコメントでの指摘をよろしくお願いします。

## for() と .map{}
```kotlin
val inputList = mutableListOf<Int>()
for (i in 0..1) {
    inputList.add(readLine()!!.toInt())
}
```

```kotlin
val inputList = (0..1).map { readLine()!!.toInt() }
```

上二つは同じこと。２つ目の方が変数定義・代入をいっぺんにできるので便利。

## 重複なし組み合わせ
プロシージャテスト

Sub テスト()

'指定列でセルブランクであれば0に置換

```
Range("AO:AO,AQ:AQ,AS:AS,AU:AU,AW:AW,AY:AY").Select
Selection.Replace What:="", Replacement:="0"
```

'不要行（A列ブランク以降行）を削除　※）10000行まで

```
  Dim 最終行 As Long
  最終行 = Cells(Rows.Count, 1).End(xlUp).Row + 1
  Range(最終行 & ":10000").Delete
```

'デスクトップPATHを取得

``` 
  Dim Path As String, WSH As Variant
  Set WSH = CreateObject("WScript.Shell")
  Path = WSH.SpecialFolders("Desktop") & "\"
    Application.DisplayAlerts = False 'アラートウィンドウ機能停止
```

'csv形式でファイルをデスクトップPATHに保存

```
  ActiveWorkbook.SaveAs Path & "テスト" & Format(Date, "yymmdd") & ".csv", _
  FileFormat:=xlCSV, Local:=True
```

'ファイルクローズ

``` 
 Application.Quit
  ThisWorkbook.Close
    Application.DisplayAlerts = True 'アラートウィンドウ機能再開
```

End Sub
オフラインリアルタイムどう書くE23の実装例

問題 : http://nabetani.sakura.ne.jp/hena/orde23nokoch/
イベント : https://yhpg.doorkeeper.jp/events/71800
実装リンク集 : https://qiita.com/Nabetani/items/77e7e2c749767f197c0e

で。

# 最初に書いた実装

最初に書いたのは

```ruby:ruby2.5
def dir_at( seq, pos )
  dirs = seq.reverse.chars.map{ |x| { "a"=>[0,5,1,0], "b"=>[0,5,0,1,0] }[x] }
  r=0
  dirs.each do |d|
    r += d[pos % d.size]
    pos /= d.size
  end
  return pos!=0 ? nil : r % 6
end

def solve(src)
  num, rules = src.split(",")
  dir = dir_at(rules, num.to_i - 1 )
  return "x" unless dir
  return "0-+"[dir % 3 ]
end

DATA.map do |line|
  num, src, expected = line.split(/\s+/ )
  actual = solve(src)
  okay = actual == expected
  p [ (okay ? "ok" : "**NG**"), src, actual, expected ]
  okay
end.all?.yield_self{ |ok| puts( ok ? "ok" : "something wrong" ) }

__END__
0 120,aabb  0 
1 100,a x 
2 3,a - 
3 3,b 0 
4 9,aa  - 
```

こんな感じ。
テストデータの大半は省略。

5 または 4 で割ったあまりが一番細かい部品の、線分の番号になる。
5 または 4 で割ることで、細部を無視した図形の、線分の番号になる。
ということ。

# 再帰を使って書き直した

フラクタルなんだから再帰だよね。ということで、再帰を使って `dir_at` を書き直した。

先ほどの実装は 細部→概要 という順に計算したけど、今回は 概要→細部 という順に計算した。

```ruby:ruby2.5
M={ "a"=>[0,5,1,0], "b"=>[0,5,0,1,0] }
L=M.keys.each.with_object({}){ |k,o| o[k]=M[k].size }

def dir_at( seq, pos )
  return 0 if seq.empty?
  baselen, subpos = pos.divmod( seq.chars.drop(1).map{ |x| L[x] }.inject(1, :*) )
  base = M[seq[0]][baselen]
  base && dir_at(seq[1..-1], subpos )+base
end
```

こんな感じ。
概要を先に計算する都合で、 `inject` で掛け算している。

会場では、実際に線分の向きのリストを生成している方が多かった。
処理系によって 10秒で終わったり(Haskell)、2時間を超えたり(SQL)、エラーで死んだり(node.js)とさまざまだった。
contenteditableの文章をキャレット位置で分割する

### よく枯れているキャレット位置取得コード 
```js
fn.gcp= function getCaretPosition(editableDiv) {
//https://stackoverflow.com/questions/3972014/
  var caretPos = 0,
    sel, range;
  if (window.getSelection) {
    sel = window.getSelection();
    if (sel.rangeCount) {
      range = sel.getRangeAt(0);
      if (range.commonAncestorContainer.parentNode == editableDiv) {
        caretPos = range.endOffset;
      }
    }
  } else if (document.selection && document.selection.createRange) {
    range = document.selection.createRange();
    if (range.parentElement() == editableDiv) {
      var tempEl = document.createElement("span");
      editableDiv.insertBefore(tempEl, editableDiv.firstChild);
      var tempRange = range.duplicate();
      tempRange.moveToElementText(tempEl);
      tempRange.setEndPoint("EndToEnd", range);
      caretPos = tempRange.text.length;
      //console.log(tempRange.text)
    }
  }
 // console.log(caretPos,sel,range)
  return caretPos;
}
```
### ctrl+enterが押されたタイミングで、新しいcontenteditableを生成
```js
function fac(text){
 let el=temp.cloneNode(true),ed=fn.q('[contenteditable]',el)
 ;
 ed.textContent=text;
 ed.onkeydown=calc;
 return el;
}

```
### 全部 ctrl+enterで分割
```html
<outline temp style="display:none">
 <div f><div contenteditable="plaintext-only"></div></div>
</outline>
<style>
[contenteditable]{
 padding:0.5rem; margin:2rem 0;
 outline:none; border:2px solid;
} 
</style>
```
```js
let fn={}
fn.q=(s,doc=document)=>{return doc.querySelector(s)};
fn.as2 =function(me,p){p.parentNode.insertBefore(me,p.nextSibling);return me}
fn.gcp= function getCaretPosition(editableDiv) {
//https://stackoverflow.com/questions/3972014/
  var caretPos = 0,
    sel, range;
  if (window.getSelection) {
    sel = window.getSelection();
    if (sel.rangeCount) {
      range = sel.getRangeAt(0);
      if (range.commonAncestorContainer.parentNode == editableDiv) {
        caretPos = range.endOffset;
      }
    }
  } else if (document.selection && document.selection.createRange) {
    range = document.selection.createRange();
    if (range.parentElement() == editableDiv) {
      var tempEl = document.createElement("span");
      editableDiv.insertBefore(tempEl, editableDiv.firstChild);
      var tempRange = range.duplicate();
      tempRange.moveToElementText(tempEl);
      tempRange.setEndPoint("EndToEnd", range);
      caretPos = tempRange.text.length;
      //console.log(tempRange.text)
    }
  }
 // console.log(caretPos,sel,range)
  return caretPos;
}
;
let temp=fn.q('[temp] [f]')
,calc=function(ev){
 if(!(ev.ctrlKey&&ev.keyCode===13))return
 ;
 let me=this,splits=me.textContent.slice(fn.gcp(me))
 me.textContent=me.textContent.replace(splits,'')
 let el=fac(splits)
 fn.as2(el,me.parentElement);//me.parente.. is [f]
 fn.q('[contenteditable]',el).focus();
}
;
function fac(text){
 let el=temp.cloneNode(true),ed=fn.q('[contenteditable]',el)
 ;
 ed.textContent=text;
 ed.onkeydown=calc;
 return el;
}
;
document.body.appendChild(fac('ctrl+enter is split text'))
;
```