OmniAICreator/Qiita-1.07M huggingface dataset:
TensorFlowとKerasをWindowsに導入

## Pythonのインストール
TensorFlowは最新の3.6に対応していないので3.5以前のバージョンをダウンロードする。(2017/09/25現在)
[Pythonダウンロードページ](https://www.python.org/downloads/)

## TensorFlow CPU版とCPU版
CPU版とGPU版の2種類があり、Nvidia製グラフィックボードを搭載している場合はGPU版が使用できる。
(2017/09/25現在、AMD製GPUは対応していない模様)
CPUでは、学習処理にかなり時間がかかるためGPU版がおすすめ。


## 前準備
必要なライブラリをインストール
※pipからの通常インストールではエラーが出るため下記を使用
wheel
` pip install wheel `
[numpy+mkl](http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy)
` pip install numpy‑1.13.1+mkl‑cp35‑cp35m‑win_amd64.whl `
[scipy](http://www.lfd.uci.edu/~gohlke/pythonlibs/#scipy)
` pip install scipy‑0.19.1‑cp35‑cp35m‑win_amd64.whl `

#### GPU版を使用する場合
1. [CUDA](https://developer.nvidia.com/cuda-downloads)をインストール  
ver.8をインストール
2. [cuDNN](https://developer.nvidia.com/cudnn)をインストール  
ダウンロードにはNVIDIA Developer Programへの登録が必須  
TensorFlowは最新版のcuDNNに対応していないようなので5.1をインストール

## TensorFlowをインストール
CPU版
` pip install tensorflow `
GPU版
` pip install tensorflow-gpu `

## Kerasをインストール
` pip install keras `

## 構築した環境
Windows 10 64bit
Nvidia Geforce GTX 1050Ti

Python(x64) 3.5.4
wheel 0.30.0
numpy 1.13.1+mkl
scipy 0.19.1
TensorFlow-gpu 1.3.0
Keras 2.0.8
iPhoneのsysdiagnoseの取得方法

備忘録です
OSのバグのようなものを業務で踏み抜いてしまってAppleにバグレポートを挙げた際に
sysdiagnoseの提出も求められたのでその取得方法と注意点です

#取得方法
取得方法はここに書いてます
https://developer.apple.com/bug-reporting/profiles-and-logs/?name=sysdiagnose
iPhoneのsysdiagnoseが欲しいので
sysdiagnose for iOS
となっているところを見ましょう
まぁいろいろ書いてあるのですがここが重要なところです

```
iOS 11+: Long press (250ms) both volume buttons + sleep/wake (power) button simultaneously
iOS 10.x: Press and release both volume buttons + sleep/wake (power) button simultaneously
Note: On an iPhone you will feel a short vibration when a sysdiagnose is successfully triggered
```
ざっくりいうと
iOS11以上は音量ボタン２つと電源を0.25秒同時押し
iOS10.xは音量ボタン2つと電源を押して離す
正常にsysdiagnoseの取得が成功すると端末が震えるよ

って感じです。

たったこれだけの操作ですが僕はiOS11環境のsysdiagnoseが欲しかったのですが詰まりました

##詰まったところ
指をボタンからはなした時に震えます。押しっぱなしにすると電源が落ちます。
0.25秒なんてわかんねぇからずっとおしっぱでいいや！！って思っておしっぱすると
別の診断メニューがでてきます(<-僕はこれで勘違いした
sysdiagnoseの取得ですが特に「開始します」や見た目に変化はありません**震えるだけです**
もう一度言います**震えるだけです**
行き過ぎたUIにAppleは一石を投じたわけですね
ボタンを押した後ちょうどいいタイミングで指を離すとぶるるって震えるのでそれでsysdiagnoseの取得は開始されるのでしばし待ちましょう

#sysdiagnoseの場所
そうしてできるsysdiagnoseですがApple公式の手順書(上のurl)にあるように成果物がでるまで10分ほどラグがあります。実際は2~3分で出る気がしますが...

さて、場所ですがドキュメントを見ると

```
Log Locations
macOS:
Note: “~/Library/…” actually translates to: /Users/[Your User Name]/Library/…
The “/Users/[Your User Name]/Library/…” folder is hidden by default in macOS.
To expose the folder, hold the option key while clicking the Finder’s Go menu and the Library folder will appear in the menu. Any time you see a
placeholder like “[Your Device Name]” or, “[Your User Name]” you should replace that part of the path with your actual device’s name, or your computer
user name.
```
こんな感じで書かれてます。
ですがここ行ってもありませんでした。(環境のせいなのか？

なのでいろいろ探した結果ここにありました。

iPhoneの設定から(iOS11.0での情報です)
プライバシ- > 解析 > 解析データ > sysdiagnose

解析データの下にいくつかログデータがぶら下がってると思います。
その中にsysdiagnoseも一緒に置かれています。
名前にタイムスタンプがついてるのでよしなに実行した日付を選んで取得すればいいと思います。
Macへの移動ですが送りたいsysdiagnoseのcellをタップするとドリルダウンしてシェアメニューからAirDropできるのでそれでMacへおくれます


#あとがき
以上になります。
あまり使い所ない情報かつ個人環境によるかもしれませんが誰かの、何かの役に立てば...
【社内勉強会】Tensorflowチュートリアル（Deep MNIST for Experts）を試してみて



## 前提知識

* [MNIST For ML Beginners](https://www.tensorflow.org/get_started/mnist/beginners) の内容

---------
## 参考サイト

* [Deep MNIST for Experts（公式）](https://www.tensorflow.org/get_started/mnist/pros)
* [TensorFlowチュートリアル和訳(Deep MNIST for Experts)](http://biz-and-deep.hatenablog.com/entry/2017/05/07/001501)
    - 翻訳サイトはいくつかあるが、他のサイトだとTensorflowのバージョンが古く、サンプルコードに差異がある。Tensorflowのバージョンアップ激しすぎ。

* 『ゼロから作るDeep Learning』オライリー

---------
## 「Deep MNIST for Experts」は難しい
* 最初のチュートリアル「MNIST for ML Beginners」に比べると、難しい
* 特に「Build a Multilayer Convolutional Network」の章から、急に難しくなる
* CNNを知っていること前提のためか、知らない用語がたくさん出てくる

---------
## 「Deep MNIST for Experts」で新たに出てきた用語・内容

### CNN(畳み込みニューラルネットワーク）
* ReLU
* Convolution（畳み込み）
* pooling(max pooling)
* stride size

### 学習
* 初期化の方法（微小な正の初期バイアス）
* Dropout
* ADAMオプティマイザー

### Tensorflow
* `tf.truncated_normal`
* `tf.nn.conv2d`
* `tf.nn.max_pool`
* `tf.summary.FileWriter` (TensorBoard用）


---------
## 「MNIST for ML Beginners」の問題点

縦横の2次元データを1次元のデータに変換したことにより、
形状に関する情報（空間的に近い値はピクセル値も近い）が無視されている 

⇒ 畳み込みを使って形状を維持する！

※ 『ゼロから作るDeep Learning』7.2.1章 参考




---------
## CNNに関する参考サイト

* [定番のConvolutional Neural Networkをゼロから理解する](https://deepage.net/deep_learning/2016/11/07/convolutional_neural_network.html)
   - 畳み込みなどのアニメーションあり
* [Convolutional Neural Networkとは何なのか](https://qiita.com/icoxfog417/items/5fd55fad152231d706c2)
* [写真加工(フィルタの確認）](http://www.photo-kako.com/convolution.cgi)

上記サイトが分かりやすいので、説明は省略します。




---------
## TensorBoard
Tensorflowの可視化ツール

* [TensorBoard: Visualizing Learning（公式）](https://www.tensorflow.org/get_started/summaries_and_tensorboard)
* [あらゆるデータを可視化するTensorBoard徹底入門](https://deepage.net/tensorflow/2017/04/25/tensorboard.html)
* [TensorBoardでビギナー向けMNISTチュートリアルを可視化する](https://qiita.com/kozenumezawa/items/f97dc334ebe05b6c7eef)

---------
## mnist_deep.pyで、Tensorboard用のコード

[mnist_deep.py](https://github.com/tensorflow/tensorflow/blob/r1.3/tensorflow/examples/tutorials/mnist/mnist_deep.py) の以下のコードは、Tensorboardが参照するデータを出力する


```python:mnist_deep.py
  graph_location = tempfile.mkdtemp()
  print('Saving graph to: %s' % graph_location) 
  #⇒ Saving graph to C:\Users\yuji3\AppData\Local\Temp\tmps8xk5yjw
  train_writer = tf.summary.FileWriter(graph_location)
  train_writer.add_graph(tf.get_default_graph())
```    


---------
### Tensorboard起動

1. 以下のコマンドを実行する

```bat
> tensorboard --logdir=C:\Users\yuji3\AppData\Local\Temp\tmps8xk5yjw
```

2. `localhost:6006`にアクセス
3. "Graph"で計算グラフを確認

![image](https://qiita-image-store.s3.amazonaws.com/0/37903/b01ad5aa-874f-9369-61a8-138f19fdecec.png)
Powershell2.0でハマッたCountプロパティの使い方

# Powershell2.0でハマッたCountプロパティの使い方

「プロセスが1個しかない場合Get-Processの数を数えようとして失敗します！　どうしましょう！？」という相談があったので、対応をまとめました。


## 状況
　以下のような状況のとのこと。（プロセスは適当に1個のものでテスト）

```Powershell:問題の環境（Powershell2.0）
PS C:\> (Get-Process -ErrorAction 0 | select MainModule | findstr -i "dwm.exe").Count
PS C:\> 		←応答を返さない
```


## 最新バージョンで再現するかどうか？

「まずバージョンを確認して、古かったら上げてみよう」。試してみたところそれなりのバージョンならきちんとプロセス数が返ってきます。

```Powershell:Powershell5.1ならきちんと返ってくる
PS C:\> (Get-Process -ErrorAction 0 | select MainModule | findstr -i "dwm.exe").Count
1		←1を返す
```


## 暫定対応
　とはいえ、諸般の事情からすぐバージョン上げられない…ということで調べてみたところ、以下のやり取りがヒット。

> 　コマンドレットの出力が一つの場合は、配列ではなく単一のオブジェクトとして返却されます。
> 　その場合出力されるオブジェクトは配列ではないので、countプロパティが存在せず、値を返しません。
> 　この問題の対処方法はコマンドレットの出力に@()をつけることです。[^TechMS]

　試してみたところうまくいきました。

```Powershell:問題の環境（Powershell2.0）
PS C:\> @(Get-Process -ErrorAction 0 | select MainModule | findstr -i "dwm.exe").Count
1		←1を返す
PS C:\> 
```

　@()のメンバをみてみると、Count = Lengthと定義されています。このように定義されているため、@()をつけてやるとCountが使えるようです。[^Si]

```Powershell:@()のメンバ
PS C:\> Get-Member -InputObject @() -View Extended

   TypeName: System.Object[]

Name  MemberType    Definition
----  ----------    ----------
Count AliasProperty Count = Length
```

　Powershell2.0依存の話ではないですが、パイプラインを使って大量のオブジェクトを渡してCountすると遅くなるという事象も。こちらはSystem.Linq.Enumerable を使うことで処理時間を短縮させることが可能です（参考文献が詳しい）。[^Gu]

　Windows7環境下だと最初からPowershell2.0が入っていて、そのままシェルが動いてしまうからなかなかバージョン違いに気付かなかったりしますが、なるべく最新のバージョンを用意しておいたほうがよいですね。


## 参考

[^TechMS]: [変数に格納されている項目が１つの時, countプロパティで １を返さない](https://social.technet.microsoft.com/Forums/ja-JP/230719ec-e5a8-4b32-9cf9-b7bdec0b50c3/-count-?forum=powershellja)
[^Si]: [PowerShellのCountプロパティについてあれやこれや \- しばたテックブログ](http://blog.shibata.tech/entry/2015/11/06/212944)
[^Gu]: [PowerShell で オブジェクトの数を計測するんです？ \- tech\.guitarrapc\.cóm](http://tech.guitarrapc.com/entry/2015/01/17/071137)
vimを使い始めて2ヵ月たったので経過を纏めてみた。

#目的
vimを使い始めてから、約2ヵ月立った。ある程度vimの操作に慣れてきたので、ここまでの経験を纏めておきたいと考えた。

#使い始め
大学のコンピュータリテラシーの教員がvimを好きだといっていたので、vimに興味を持った。
vs codeを使っていたが、好奇心から7月の終わりにkaoriya vimを導入した。vimに初めて触り、hjklの移動に感動した。
このころは、vim adventureやvim snakeで遊び、カーソルの移動を覚えた。まだ、vimを自分のメインのエディターにする気はなかったが、初めはつんつんしているが使い方に習熟するとものすごくデレてくれる高機能なエディターらしいのでいつかは使いこなしたいと思っていた。
また、[僕がサクラエディタからVimに乗り換えるまで](http://blog.jnito.com/entry/20120101/1325420213)や、[Big Sky :: Learn Vim Progressively](https://mattn.kaoriya.net/software/vim/20110902125512.htm)を参考にしてvimの操作を覚えていった。
ある程度、hjklの移動とw, qコマンドを使えるようになったところで、「vim&Emacsエキスパート活用術」についてきたチートシートを持ち歩き、さらにコマンドを覚えようとした。また、自動補完のためのプラグインやおすすめと書かれていたunite.vimやquickrun.vim等を入れた。vimrcが一気に大きくなった。


#kaoriya版vimに不満を持つ
kaoriya板のvimには独自のプラグインやvimrcがあり、どんな設定がされているのかわからないことが不満になった。
なので、vimのソースをgitから持ってきて自分でビルドした。vs 2017でおこなったので+python, +luaでのビルドはできなかった。それに伴い、neocompleteが使えなくなり、neocomplcacheに切り替えた。
また、vimrcを見直して、わかっていないけど入れていた設定を消していった。

#スパルタンvimを読み、プラグインなしのvim使いにあこがれる。
とりあえず入れてみたけど使っていなかったプラグインを消した。
ただ、自動補完が利かなくなるのは不安だったので、neocomplcacheだけは残しておいた。
このあたりからプラグインなしでvimを使えるように調べ始めた。

vimをレポートの作成やメモにも使うようになり、新しいコマンドを積極的に使おうとするようになった。
ウィンドウの分割やインデントを作るコマンド、モーションが増えた。

#標準でついている補完の力を知る。
Ctrl-n, Ctrl-p補完から使い始め、行補完、辞書補完と試していった。これだけでも意外と快適にjs, pythonを書けることがわかった。
より補完のことを調べ始めた。
オムニ補完があまりによかったので、vimrcからneocomplcacheの設定を消した。
「実践vim」を買った。よりvimvimできるとモチベーションが上がった。
また、このころマクロ漁船を知りjavascriptでbrainfuckのインタプリタを組んだ。

#現在netrwの存在を知る。
標準のファイラーが予想を上回って使いやすかった。
使えるコマンドやモーションが増え、vimに慣れてきた。しかし、いまだにtagsやマクロ、ジャンプ等が使えていないので徐々に使える機能を増やしていきたい。
vimに対する印象が時々デレてくれる子に変わった。
vimrc 116行（2017/09/28）

vimを選んだ理由
-動作が早い
-ホームポジションを崩さないで操作ができる
-自分のレベルによって機能を増やしていける
-日本人のコミュニティが盛ん
-キーバインドが短く簡単
-かっこいい
Laravelでローカル環境でのメール送信テストに便利なMailtrapが個人的に想像以上に便利だった

Laravelアプリでメール送信の機能を実装したのですが、
ロカールでのメール送信テストってどうやるんだ？と思って、
Laravelの公式リファンレンス( https://readouble.com/laravel/5.4/ja/mail.html )を見た所、「Mailtrap」というサービスが便利そうだったので実施に使ってみました。

#■Mailtrap概要
Mailtrapとは「smtpドライバで本当のメールクライアントにより内容を確認できる「ダミー」のメールボックスへメールメッセージを送る」ことが出来るサービスです。

要は、
・ダミーのメールアドレスをサクッと作れて
・その設定情報をLaravel等のアプリケーションの設定にサクッと反映させると
・ダミーのアドレス宛にメール送信テストを行えて
・送信されたメールをダミーのメールボックスで実際に確認出来る
というものです。

以前はlogドライバを使っていたため、`laravel.log`ファイルで送信結果を確認していたのですが、それだとメールテンプレートの確認が出来ずテンプレートのスタイルを調整したりするのが面倒だったので、「良さげなの見つけた！」と思い早速試してみました。

#■Mailtrapの設定
###1.以下のサイトから「Sign Up」します。
https://mailtrap.io/

###2.こんな感じのページが表示されます
こがダミーのメールボックスになります。

<img width="1180" alt="スクリーンショット 2017-09-26 0.11.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/121811/5578c9a7-6c13-b3cb-1de3-56068a800ed6.png">

###3.Demo inboxをクリックします
ページ右下の「Integrations」という項目の下にあるプルダウンから自分が使っているフレームワークを選択すると、その下に必要な設定情報が表示されます。
Laravel以外にもCakePHPやFuelPHP、Rails等色んな言語の色んなフレームワークが選択出来ます。

<img width="215" alt="スクリーンショット 2017-09-26 0.14.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/121811/e08319e1-0373-151d-f0bc-42a80aa29512.png">

###4.表示された設定情報を.envファイルにコピペ

以上でメール送信テストを行うとメールがDemo inboxに届いて、実際にどんなメールが届くか確認できます。
届いたメールは別ダブで表示出来るので、Chromeのデベロッパーツール等を使ってCSSをあててデザインを調整することも可能です。

メール送信のテストを行う際に、
ドライバを何にしようとか、`MAIL_HOST`、`MAIL_PORT`は何にすればいいのかとかよくわかってなかったので、設定情報を全部見せてくれるのはとても助かりました。

以上です。

何かしらお役に立てれば幸いです^^
Javaのお勉強#1(代表的な型)

#予約語の存在
**代表的な型の存在**

- long            　大きな整数　
-   int            　 普通の整数
-   short           　小さな整数
-   byte          　 更に小さな整数
-   double           普通の小数
-  float　          少し曖昧でもいいような小数
-   boolean          真偽値（true or false)
-   char             一つの文字
-   String　         文字の並び
   
     整数なら　int
    小数なら　double
    なお小数はお金の計算などの誤差が許されない正確な計算には適していない

```java   

   int a = 0;         ←　変数の初期化
   
   int　a　=　0;

   int　a   =　1;　　　←変数の再代入（上書き）

```
   
   final型は定数と呼ばれ、書き換えられることは無い
   
   とりあえず第一章終わり・・・？
   練習問題も終わったけれど、整数が頭にパッと出てこないから、本にもあった通り、しばらくは口に出して覚えてみようと思う。
   明日は復習したほうがいいかな(^o^)
備忘録　Atomエディタで文字検索+文字列置換

###Atomエディタで文字検索と文字列置換

Atomエディタ上で
```
cammand + F
```
下の図のようになる↓
<img width="509" alt="Screen Shot 2017-09-26 at 0.01.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/203998/a9abcad3-390e-0f77-61c8-860b89fd54f3.png">

「Find」に検索したい文字列を入力すると検索してくれる

「Replace」に置換したい文字を入力すると全て置換してくれる

(例)
ここでは
文字列「goback」→文字列「back」に置換
Unity Edit Colliderのハンドルが出てこない時

###以下のような緑の点が出てこない時
<img width="744" alt="スクリーンショット 2017-09-26 0.04.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/70748/8ecbb750-aae0-6be6-19e3-f826a52796bc.png">

再起動しても治らない時は、
<img width="186" alt="スクリーンショット 2017-09-26 0.06.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/70748/5e01bd66-1fcd-6e81-0f22-f99c734b68a9.png">

右上のレイアウトを一回変えれば治る。

以上、メモでした。
VeeValidateで最初のフィールドがinvalidになってしまう問題の対処法

## TL;DR

```js
created() {
  this.$validator.reset();
},
```

## 概要

VeeValidateを使ってバリデーションを書いていると、フォームの最初のinput要素がはじめからinvalidになっていることに気づくでしょう。

たとえば、下記のようなコンポーネントとテンプレートがあるとします。

```js
export default {
  data() {
    return {
      field1: '',
      field2: '',
    };
  }
}
```


```html
<form action="">
  <input type="text" name="field1" v-model="field1" v-validate="'required'">
  <input type="text" name="field2" v-model="field2" v-validate="'required'">
</form>
```

このとき、 `errors.has('field1')` は `false` を返す状態ですが、field1の `aria-invalid` 属性は `true` になっているはずです。これはなぜかというと、最初のフィールドの `flags.invalid` が `true` になっているからです。

実際に動かして確認したい方は https://jsfiddle.net/ft1z8aqs/2/ を参照してください。

最初の要素の `flags.invalid` が `true` になるのは、ブラウザのオートフォーカスによって最初の要素のfocusイベントが発生して、バリデーションが行われるからだと思われます。

この挙動の影響で、 `aria-invalid` 属性や `.invalid` というCSSクラスに頼ったバリデーション状態のスタイリングが難しくなっています。

VeeValidateのバグなのか仕様なのかは不明です。

## 対処方法

冒頭にも記述したとおり、コンポーネントのcreatedのフックで、バリデーションをリセットすればOKです。

```js
created() {
  this.$validator.reset();
},
```

jsfiddleにも、修正前後の状態を載せているので、実際に動かしてみてください。

修正前：初期表示でfield1の `aria-invalid` がtrueになっている
https://jsfiddle.net/ft1z8aqs/2/

修正後：初期表示でfield1の `aria-invalid` がfalseになっている
https://jsfiddle.net/ft1z8aqs/3/
ofxMSATensorflow + win10 ビルドに手間取ったのでメモ

ofxMSATensorflowを動かすためにやったことのメモ。
GPUは今度試すとしてとりあえずCPUのみ記憶が新しいうちにメモ

Anaconda4(Pythonの仮想環境？よくわからない)をインストール
　
環境構築
>\conda create -n tensorflow python=3.5 numpy git cmake swig zlib

全部入りみたいな感じでcreate後activate
Pythonは3.5が必要ポイ
>\activete tensorflow
>\git clone https://github.com/tensorflow/tensorflow.git
>\git checkout r1.1
>\mkdir camke/build
>\cd build
>\cmake .. -A x64 -DCMAKE_BUILD_TYPE=Release ^
-Dtensorflow_BUILD_SHARED_LIB=ON
>\cmake --build . --config Release

オプションの
>-Dtensorflow_BUILD_SHARED_LIB=ON

を入れるのがきも。これを入れないとtensorflow.dllができない
アドオンが1.1だったのでr1.1で試そうとしてたら、シェアドライブラリはr1.2からだった模様。
ビルドには一時間くらいかかった
tensorflow/cotrib/cmake/build/release/
内の出来立てのライブラリ
>tensorflow.dll
tensorflow.exp
tensorflow.def
tensorflow.lib

達をアドオンフォルダにコピー
ofxMSATensorFlow\libs\tensorflow\lib\win
\winフォルダは勝手に作った。
>
libprotobuf.lib

もついでにコピー(リンクしないとビルドが通らなかったので)
ofxMSATensorFlow\libs\tensorflow内のgoogle/tensorflowそれぞれのincludeフォルダの中身は削除して
cmakeでのbuild時にできるファイルに置き換え

vs2015側は
プロジェクトのプロパティのC/C++プリプロセッサに
>COMPILER_MSVC

を追加

>リンカーの入力に
tensorflow.lib
libprotobuf.lib

を追加

\binの.exeができる階層に
>tensorflow.dll

を追加

おしまい

参考にさせていただいたサイト
https://www.tensorflow.org/install/install_sources
https://joe-antognini.github.io/machine-learning/build-windows-tf
https://qiita.com/kat_out/items/695a91f13bfc992f70ef
C言語マクロで配列をフィルターする

# C言語マクロで配列をフィルターする

## 概要

久しぶりのC言語との邂逅でマクロに触れることができた。
配列(begin, end)に対してfirstとfilterしてみたメモ。

## 実装

テストコードはGitHubにあります。
https://github.com/takayoshiotake/qiita/tree/master/C%E8%A8%80%E8%AA%9E%E3%83%9E%E3%82%AF%E3%83%AD%E3%81%A7%E9%85%8D%E5%88%97%E3%82%92%E3%83%95%E3%82%A3%E3%83%AB%E3%82%BF%E3%83%BC%E3%81%99%E3%82%8B/src

### first

配列を捜査して条件にマッチする最初の要素のポインタを取得します。

`_Type`には型名が入ります。`_begin`, `_end`は配列の先頭と末尾の次を指すポインタです。C++のイテレータと捉えていただければ。
`_first`には結果が格納されます。型は`_Type**`になります。残りの`_Match`と`_arg`は要素のチェックに利用します。

**bb_algorithm.h**

```C
#define BB_list_first(_Type, _begin, _end, _first, _Match, _arg) \
do { \
    _Type* _ptr; \
    for (_ptr = _begin; _ptr < _end; ++_ptr) { \
        if (_Match(_ptr, _arg)) { \
            *_first = _ptr; \
            break; \
        } \
    } \
} while (0)
```

このマクロで

```C
static int test_first(int* lhs, void const* arg) {
    return *lhs >= *(int*)arg ? 1 : 0;
}

int main(int argc, const char * argv[]) {
    int list[5] = { 2, 3, 5, 7, 11 };
    int* first = NULL;
    int arg = 5;
    BB_list_first(int, &list[0], &list[sizeof(list)/sizeof(*list)], &first, test_first, &arg);
    if (first) {
        printf("  index: %d\n", (int)(first - list));
    }
    return 0;
}
```

すると

```shell-session
index: 2
```

になります。(GitHubのコードから簡略化してます)

`_Match`にブロックスやラムダを利用したいのですが関数ポインタで妥協します。マクロに正しい引数を渡せるようになるまでコンパイラーと格闘が必要です。

### filter

基本はfirstと同じ。条件にマッチする要素を`_filtered`が指す配列に格納していく。

**bb_algorithm.h**

```C
#define BB_list_filter(_Type, _begin, _end, _filtered, _Match, _arg) \
do { \
    _Type* _ptr; \
    for (_ptr = _begin; _ptr < _end; ++_ptr) { \
        if (_Match(_ptr, _arg)) { \
            *_filtered = *_ptr; \
            ++_filtered; \
        } \
    } \
} while (0)
```

このマクロで

```C
static int test_apple_filter(char const** lhs, void const* arg) {
    return strstr(*lhs, "apple") != NULL ? 1 : 0;
}

int main(int argc, const char * argv[]) {
    char const* list[4] = { "I have a pen", "I have an apple", "ugh", "apple pen" };
    char const* filtered[4];
    char const** filtered_end = filtered;
    BB_list_filter(char const*, &list[0], &list[sizeof(list)/sizeof(*list)], filtered_end, test_apple_filter, NULL);
    {
        char const** ptr;
        for (ptr = filtered; ptr < filtered_end; ++ptr) {
            printf("  %s\n", *ptr);
        }
    }
    return 0;
}
```

すると

```shell-session
I have an apple
apple pen
```

になります。(GitHubのコードから簡略化してます)

firstよりもマクロの引数が難しいです。`filtered_end`を初期化してから渡すことが要求されてます。

## まとめ

マクロをC++のテンプレートのように利用したかったのですが、コンパイルエラーを解消するのが難しいです。
CarrierWaveとPaperclipの違い

Railsの画像アップロードのGemにはCarrierWaveとPaperclipの両方が使用できる。これらの違いを調べたのでまとめる。

#どっちを使えばいいの？
画像アップロードに拘りたいならCarrierWave、シンプルな機能を求めているならPaperclipを使用する。ちなみに、「Rails Tutrial」や「パーフェクトRuby on Rails」ではCarrierWaveを使用している。

#どんなところが違うの？
- CarrierWaveはRails以外にもSinatraなどのRubyフレームワークでも動作する。
- CarrierWaveでは添付ファイルとその処理をするクラスが異なる。
- CarrierWaveではRMagickを使うことができ、凝ったことができる。
- Paperclipでは画像保存ディレクトリがバージョン毎に分かれている。
- PaperclipではPDFのアップロードにも対応している。
- Paperclipではアップロード時に自動的に縮小画像やサムネイルを生成してくれる。
SchemeでFizzBuzz

関数型プログラミングができるようになりたい
今まで書いてたJavaとかPythonとかと勝手が違うから書いてて脳みそがちぎれそうになる
参照できるサイトがあまり多くないので自分で考えることが重要になりそうである


```scheme:fizz-buzz.scm
(define (main args)
    (fizz-buzz 1)
    0)

(define (fizz-buzz x)
    (if (<= x 100)
        (cond 
          ((= (modulo x 15) 0) (print "FizzBuzz") (fizz-buzz (+ x 1) ))
          ((= (modulo x 3) 0) (print "Fizz") (fizz-buzz (+ x 1) ))
          ((= (modulo x 5) 0) (print "Buzz") (fizz-buzz (+ x 1) ))
          ((= x 100) (print "Finish"))
          (else (print x) (fizz-buzz (+ x 1) )))))
```

無駄ばかりあるような気しかしない
標準入力はどう受け取ったらいいのだろう…
AngularのサービスクラスでEventEmitterを使ってはいけない

## TL;DR
テンプレート以外からイベントの購読処理を行うケースでは，`rxjs`を使いましょう．
**EventEmitterを使うのは危険です**

## EventEmitterについて
`EventEmitter`は，**コンポーネント**からその**上位コンポーネント**への，任意の値の通知を提供します．
つまり，

```child.component.ts
   @Output()
   someAction = new EventEmitter<SomeObject>();
   
   func() {
     this.someAction.emit({ foo: 'bar' })
   } 
```
のようにしておけば，その上位コンポーネントで

```higher.component.html
<app-child (someAction)="onSomeAction($event)"></app-child>
```
のように値を受け取れる，というわけです．

## サービスクラスでの通知処理
では，コンポーネントではなく，サービスクラス等から，何らかの値を通知したい場合を考えます．
先程との違いは，実際の購読処理を行う責務が誰にあるかです．
先程での例では，開発者はテンプレート内で通知の処理方法を記述し，実際の購読処理を行う責務はAngularにありました．
今回の場合，実際の購読処理を行う責務は開発者にあります．

これを踏まえて，先程の`EventEmitter`を使うと，以下のように書けそうです．

**以下は間違った例です**

```test.service.ts
class TestService {
  someChange = new EventEmitter<SomeObject>();
}
```
```typescript
testService.someChange.subscribe(obj => ...)
```

確かに[`EventEmitter`は`Subject<T>`を継承しています](https://github.com/angular/angular/blob/4.4.3/packages/core/src/event_emitter.ts#L58)が，**このように書くのは間違いです．**
`EventEmitter`の購読方法はあくまで内部的なもので，これからも同じ方法で購読できる保証はありません．
https://stackoverflow.com/a/36076701/3094842

つまり，`EventEmitter`の購読処理を行う責務を，開発者が負うことはできない，ということです．
これについて，このようなケースでは，単に`rxjs`を使うと良いようです．

先程のコードを`rxjs`を使用して書き直すと，以下のようになります．

```typescript
class TestService {
  private internalSomeObject: SomeObject;
  someChange$ = new BehaviorSubject<SomeObject>(undefined);

  get someObject() { return this.internalSomeObject; }
  set someObject(someObject: SomeObject) {
    this.someChange$.next(someObject);
    this.internalSomeObject = someObject;
  }
}
```

これで，コンポーネントから認証情報の変更を検知できるようになります．

```typescript
testService.someChange$.subscribe((someObject: SomeObject) => {
  // 変更を検知したときの処理
}); 
```
ローカルフォルダ上のファイルをGitHubで共有する（自分用メモ）

GitHubにファイルをアップロードする方法がよくわからなかったので、自分用にまとめました。

1. [Github.com](https://github.com/)でログインして、マイページに移動する（https://github.com/ + （ユーザー名） のURLになっていたら大丈夫です）。
2. 画面右上の+ボタンを押して、New repositoryを選択する。
3. Create a new repositoryのページが表示される。Repository nameを入力する。
4. Initialize this repository with a READMEにチェックを入れる（任意）。
5. Upload Filesを選択する。
6. Drag files here to add them to your repositoryと書いてある枠内にアップロードしたいファイルをドラッグアンドドロップするか、choose your filesを押してローカルフォルダからアップロードしたいファイルを選択する。
7.  新しいブランチを作らないならCommit directly to the master branch.を選択し、新しいブランチを作りたいならCreate a new branch for this commit and start a pull request.を選択する。
8.  Commit changesボタンをクリックする。
9.  アップロードできました。
Qiita APIで投稿一覧を取得するときに、検索クエリをORでつなぐ時の注意点

Qiita APIで投稿一覧を取得するときに、検索クエリをORでつなぐ場合は優先順位に注意が必要だったいうメモです。詳しく書かれたドキュメントが見つからなかったので、間違っているようでしたらコメントいただけると助かります。

# ORを使わない場合
例えば、

- iOSタグが付いた記事
- 2017-09-20以降に作成された記事
- ストックが5件より多い記事

をすべて満たす記事は、検索クエリに「tag:iOS created:>2017-09-20 stocks:>5」を指定した、

```
https://qiita.com/api/v2/items?page=1&per_page=10&query=tag%3AiOS+created%3A%3E2017-09-20+stocks%3A%3E5
```

で、JSONフォーマットで一覧が取得できます。それぞれの条件はANDでつながります。
（:が%3A、スペースが+などになっているのは、URLエスケープのためです。）

# ORを使う場合

次に、iOSとAndroidの両方のタグのそれぞれ調べたくなったので、

- iOSタグかAndroidタグが付いた記事
- 2017-09-20以降に作成された記事
- ストックが5件より多い記事

を条件にしてみます。

検索クエリに「( tag:iOS OR tag:Android ) created:>2017-09-20 stocks:>5」としたいところですが、残念ながら()に非対応なため、それぞれのタグに対して日付とストック数の条件をつけてあげる必要があるようです。

「 tag:iOS created:>2017-09-20 stocks:>5 **OR** tag:Android created:>2017-09-20 stocks:>5」

```
https://qiita.com/api/v2/items?page=1&per_page=10&query=tag%3AiOS+created%3A%3E2017-09-20+stocks%3A%3E5+OR+tag%3AAndroid+created%3A%3E2017-09-20+stocks%3A%3E5
```

長いです。

# 長すぎる場合は502?なので注意

あと、20~30タグのそれぞれにストック数と日付を指定した場合(検索クエリの文字列だけでも1500〜2000文字くらい)でリクエストした場合、JSONではなくHTMLの502: Bad Gatewayのページが返ってきました。
たくさん条件をつけるのは良くないようです。

# 参考ページ
APIの詳細や、その他の検索条件については次のドキュメントを参照。投稿ユーザでも検索できたり便利です。

- GET /api/v2/items
   - https://qiita.com/api/v2/docs#get-apiv2items
- 検索時に利用できるオプション
   - https://help.qiita.com/ja/articles/qiita-search-options
post_max_sizeの値の設定ミスで$_POSTが空に

# 現象
設定を色々いじっていたら、WordPressのログインフォームに何を入力してログインしてもまたログインページに戻されるだけで、ログインすることができなくなった。

試しに以下のtest.phpをサーバに設置してcurlでリクエストを送ってみたところ、以下のログのように$_POSTに何も入っていないことがわかった。

```php:test.php
<?php
print_r($_POST);
```

```shell-session:curlのログ
$ curl -v -F a=b http://192.168.0.12:8080/test.php
*   Trying 192.168.0.12...
* TCP_NODELAY set
* Connected to 192.168.0.12 (192.168.0.12) port 8080 (#0)
> POST /test.php HTTP/1.1
> Host: 192.168.0.12:8080
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Length: 137
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=------------------------8fead5c0cbafb9b2
>
< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
< Date: Mon, 25 Sep 2017 14:19:12 GMT
< Server: Apache/2.4.10 (Debian)
< X-Powered-By: PHP/7.1.9
< Content-Length: 10
< Content-Type: text/html; charset=UTF-8
<
Array
(
)
* Connection #0 to host 192.168.0.12 left intact

```

# 原因
今回の場合、php.iniで`post_max_size=20M`と書くべきところに`post_max_size=20MB`とBを付けていたことが原因でした。以上です。
mavenプロジェクトで依存関係を含んだjarファイルを作成する際に「メイン・マニフェスト属性がありません」と言われる際の対処法


タイトルの通りですが…。

## 依存関係を含んでパッケージングする
依存関係もろともパッケージングをするには`maven-assembly-plugin`プラグインを用います。

`pom.xml`のproject->build->pluginsの下に追加します。

```pom.xml
<build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
            <archive>
              <manifest>
                <mainClass>com.example.App</mainClass>
              </manifest>
            </archive>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>
```
  
こんな感じ。

## jar実行時に「メイン・マニフェスト属性がありません」と言われる  
  
  （少なくとも私が試した中では）`configuration`->`archive`-`manifest`->`mainClass`を指定しないと、タイトルにある「メイン・マニフェスト属性がありません」とjar実行時に言われてしまいました。
openssl_random_pseudo_bytesでランダムな文字列を作りたい

## 実装方法
```PHP
substr(base64_encode(openssl_random_pseudo_bytes(32)),0,8)
```
でたとえば`a5+1SQOd`みたいな文字列が生まれる。
## 疑問
### **openssl_random_pseudo_bytesで何ビット生成するべきなのか？**
上記の例だと32ビット生成され、`base64_encode`をすることで44文字の文字列が生成される。
つまり44文字以上のランダムな文字列は作れない。(正確には末尾に1文字`=`が確定で入るので43文字)

### そもそもbase64ってどうやるんだっけ
[Wikipedia先生によると](https://ja.wikipedia.org/wiki/Base64#.E5.A4.89.E6.8F.9B.E4.BE.8B)
1. 32ビットのビット列(？)が来たときに
`1000 1111 1101 1111 1011 1001 1011 1010 (4*8)`
2. 6ビットずつにして
`100011 111101 111110 111001 101110 10`
3. 足りないところを0で埋めて
`100011 111101 111110 111001 101110 100000`
4. 文字にする
`j 9 + 5 u g`
5. 4の倍数文字になるまで`=`を入れる
`j9+5ug==`

**あれ…？8文字しか生成されないぞ…？**

### なぜ44文字も生成されるのか
ヒント1
`32*1.3333 = 42.56`
ヒント2
> Base64 でエンコードされたデータは、エンコード前のデータにくらべて 33% 余計に容量が必要です。
[PHPマニュアル](http://php.net/manual/ja/function.base64-encode.php)

たぶん生成された0、1の**文字列**を`base64`でエンコードしている。
乱数生成器で生成されたものを単純に文字列にしてるだけなので安全性には問題はない**はず**。

## 結論
`floor(欲しい文字数 / 1.3333)`ぐらいのビット数は最低限生成すべきだと思う(適当)
安全側に振るなら`ceil`の方が良いかも
暗号よくわかんないや(放棄)
URLの指定で毎回同じネームスペースを書くのがだるいときに有用な resolve メソッドの使用例

```rb
require "action_controller/railtie"
require "active_model"
ActionPack::VERSION::STRING     # => "5.1.4"

class User
  include ActiveModel::Model
  def id; 1; end
  def persisted?; true; end
end

Class.new(Rails::Application).routes.draw do
  namespace :admin do
    resources :users
  end
  resolve "User" do |user|
    [:admin, user]
  end
end

include Rails.application.routes.url_helpers
default_url_options.update(only_path: true)

user = User.new
polymorphic_path(user)          # => "/admin/users/1"
```

user は admin ネームスペースの下にしかないのに :admin ばっかり書きとーないわってときに上の例のようにひっかけておくと User クラスに反応して :admin を指定していないにもかかわらず /admin/users/1 になってくれたりします。

別の使い方としてフロント側のユーザーの「ホーム」を意味する場所が `/` なのか `/users/1` なのか `/home` なのか `/profile` なのか `/my_page` なのか `/mypage` なのかぐだぐだでよくわからなくなってしまう場合でも routes.rb の一箇所で定義しておけば、あとは抽象的にビューで `link_to("ホーム", current_user)` と書くだけでよくなったりします。
PostgreSQL の設定値の項目ごとに reload で反映できるか確認する

## tl;dr
以下のSQLをpostgresユーザーで叩いて context が 
sighup なら その項目は reload で反映される

```
select name, context from pg_settings;
```



## はじめに
* walログのサイズなど運用が始まってから値を修正したい場合があると思います。
* レプリケーションを組んでいる場合、おいそれとPostgresを再起動できません。
* そこで、postgres.conf に記述するような設定値の中でも適用するのに再起動が必要なのか reload で問題ないのかを知る方法を調べました。

## pg_settings
参考: https://www.postgresql.jp/document/9.6/html/view-pg-settings.html
* 上記リンク先にあるとおり、 pg_settings view で postgres 各種の設定値は管理されています。
* そこで、context カラムの値を確認することで、 適用に再起動が必要かどうか確認できます。

## 備考
なお、以下のように setting の値も出力させれば 今どのような値が設定されているかも確認できます。

```
select name, setting, context from pg_settings;
```
ABC06CとD問題

問題はhttp://abc006.contest.atcoder.jp/
#C問題
##解答の方針
N人すべてを利用しないといけない、4本が人単位でとれる値の最大値なので
2*N<M,M<4*Nの場合は不可能

a,b,c = （大人の人数、老人の人数、子供の人数）とする

老人二人と大人一人,子供一人は足の本数的に同値なので、
老人が0人と一人の時のみ考えればよい。
つまり、Mが奇数なら老人が一人必要で、偶数なら老人は必要ない。

M-3*b,Nは常に偶数となり、その差の数だけ、子供が必要だと考えられる。
よって子供の数を求めた後、N-b-cにより大人の数も求められる。


##コード
```python:abc06c.py
N,M = list(map(int,input().split()))
 
if 2*N>M or 4*N<M:
    a = -1
    b = -1
    c = -1
else:
    b = M%2
    c = int(((M-3*b)-2*(N-b))/2)
    a = N-b-c
print(a,b,c)
```
#D問題
##部分点1
###解答の方針
配列cのそれぞれの値をどのように残すのかを全探索する。
深さ優先探索による再帰関数を作成して探索を行った。

###コード
```python:abc06dver1.py
N = int(input())
c = []
for i in range(N):
    c.append(int(input()))
v = []
res = 0


def dfs(v,k=0):
    global res
    if k == N:#kが最後尾に来た時にvの長さが前回の探索より長ければ更新
        if v == sorted(v):
            res = max(res,len(v))
            
    else:
        v.append(c[k])
        dfs(v,k+1)#k番目のcを含む配列としてk+1番目へ
        v.pop()
        dfs(v,k+1)#k番目は含まずにk+1番目へ

dfs(v)
print(N-res)

```
     
    

##部分点2
動的計画法によって探索を行う。
左から順に、そのカードを使ってできる最大の列の長さを保持し、
次の値はその前の値から参照して最大値を計算する。


長さがNの配列vを作成する。
左から順に探索を行い、参照するc[i]、c[i]より左に存在するc[j]の中で、
c[i]-c[j](増加関係）にあるものの中から、もっとも大きなv[j]の値を取得し、
v[i]=v[j]+1とする



###コード
```python:abc06dver2.py
N = int(input())
c = []
for i in range(N):
    c.append(int(input()))
v = [1 for i in range(N)]

for i in range(1,N):

    for j in range(i):
        if 0 < c[i]-c[j]:
            v[i] = max(v[i],v[j]+1)



print(N-max(v))
```

##満点解法
###解答の方針
queue[n]がn個の部分増加列のうちの最後の要素の最小値となるようにデータを持たせる。
（解説を見たほうが分かりやすい,最長部分増加列という問題らしい）

自分の場合、配列を小さいものに書き換えるところが直感的な理解を妨げていたが、
長さのみを取得したいので、
1=>3=>5が1=>2=>5になったとしても情報は損失しないと考えると理解ができた。

書き換えの際のindexの探索にはbisectを使用したら楽だった。

###コード
```python:abc06dver3

from bisect import bisect

N = int(input())
c = []
for i in range(N):
    c.append(int(input()))
queue = [c[0]]

for i in range(1,N):
    if queue[-1] < c[i]:#最後尾よりもc[i]が大きいなら数列が大きくなる
        queue.append(c[i])
    else:
        n = bisect(queue,c[i])#queueの中でc[i]がある場所を探索
        queue[n] = min(queue[n],c[i])

print(N - len(queue))
    
```
pythonにおけるstackoverflow問題(Cannot recover from stack overflow)

# 問題
先日、自分が作ったpythonプログラムで下記のようにエラーが出ていた
発生原因と対処法等わかったので、備忘もかねて投稿

```
Fatal Python error: Cannot recover from stack overflow.

Current thread 0x00007f434f650700 (most recent call first):
  File "***.py", line 4 in ...

  File "***.py", line 7 in ...
  File "***.py", line 7 in ...
  ...
```

# 原因
ログにも記載されているようにスタックオーバーフローという問題が発生していた。
（初歩的な問題な気がぷんぷんしますが）筆者は知らなかった…。

`スタックオーバーフロー (stack overflow) は、プログラム中での関数呼び出しが多すぎる時に発生する、バッファオーバーフローの一種である。`

by wikipedia
(https://ja.wikipedia.org/wiki/%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%95%E3%83%AD%E3%83%BC)

では、なぜ上記が発生したのか、解決策は？と思いさらに
自分の（へぼ）スクリプトを見直してみると下記のような構造になっていたことが問題であった。

```
def hoge()
    try:
        (正常処理)
    except Exception as e:
        (eの表示など)
        hoge()

```

通常の正常処理中に以上処理が走ると、エラーメッセージ等を表示した上で、
再度、自分自身を呼び出していた。
自分自身を呼び出すも、スタックオーバーフローが発生しているため、
例外に入って、再度`hoge`関数を呼び出し、という無限ループに...
（悲しいことにプログラムのプロセスは落ちずにエラーをはいてしまうだけになっていた）
 
# 回避策

```
def hoge()
    try:
        (正常処理)
    except Exception as e:
        (eの表示など)

def main():
    try:
        while True:
            hoge()
    except Exception as e:
        (eの表示など)
```

というように例外が発生したら、いったん関数を終了させて、
メイン関数で`hoge`関数で呼び出すようにする（だけでした…）
なお、上記は簡単のため、エラーが発生したときに表示しかしていないですが、
ちゃんとエラーによって適切に処理を行う必要がある場合が多いと思うので
ご注意ください

# その他参考
なお、pythonでは再帰的に呼び出せる関数の数はデフォルトでは1000になっているとのことだった。

```
import sys
print(sys.getrecursionlimit()) # 再起呼び出しの最大値を表示 -> 1000

sys.setrecursionlimit(20000) # 再起呼び出しの最大数をセット
```
というように呼び出し最大回数をセットできるみたいであるが、
再起的に呼び出すつくりは危ないので、要注意（やと思ってます）


# 参考記事
- Python で再帰読み出し
    http://xwave.exblog.jp/6539098/

- スタックオーバーフロー
    https://ja.wikipedia.org/wiki/%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%95%E3%83%AD%E3%83%BC
GPU を使ったデータベース MapD を使ってみる まだまだ入門です

これからは、GPU で XXX ができる。やった方が良いとか聞いたり、思ったりするけどどんなことができるのか？が具体的に分からなかったのと、今回 MapD に出会い試してこれからのサービスに結び付けれる知識をつけていきたいと思い、まずは、初歩からスタートしてみたいと思います。

# 動機
先日、[[9月22日@札幌] Sapporo Tech Bar #12](http://www.db-tech-showcase.com/events-seminars/db-tech-salon/20170922_sapporo_tech_bar)に参加して MapD を初めて知りました。
GPU を使ったデータベースなんだろうと・・・・
はじめはすごく敷居が高く試すことはできないのかな？と思いました。
しかし、Linux を使えれば簡単に動作確認できますと言われた一言で自分で試してみてこれから使ってみたいと思うきっかけを受け取ることができました。

### 参考にさせていただいたサイト
- https://www.mapd.com/

# いつも通り Vagrant で仮想環境を構築（準備）
```rb:Vagrantfile
  config.vm.define "web3" do |node|
      node.vm.box = "centos7"
      node.vm.network "forwarded_port", guest: 9090, host: 9090
      node.vm.network "forwarded_port", guest: 9091, host: 9091
      node.vm.network "forwarded_port", guest: 9092, host: 9092
      node.vm.network :private_network, ip: "192.168.33.103", virtualbox__intnet: "intnet"
  end
```

# ここからは、公式HPから下記のコマンドを実行
```
$ sudo docker run -d -v $HOME/mapd-docker-storage:/mapd-storage -p 9090-9092:9090-9092 mapd/mapd-ce-cpu
$ sudo docker ps -a
$ sudo docker exec -it <container-id> bash
```
```
# ./insert_sample_data
# ./bin/mapdql
pass : HyperInteractive
mapdql> SELECT origin_city AS "Origin", dest_city AS "Destination", AVG(airtime) AS
"Average Airtime" FROM flights_2008_10k WHERE distance < 175 GROUP BY origin_city,
dest_city;
```

# WEBから MapD のコンテナへアクセス
## ホストのブラウザからコンテナにWEBでアクセス
- http://localhost:9092
<img width="1190" alt="スクリーンショット 2017-09-25 22.02.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/174596/7cec3f15-97ed-6142-e618-30259eef3335.png">

## ブラウザから下記の操作を実行
1. Click New Dashboard.
1. Select the flights_2008_10K table as the datasource.
1. Click Connect to Table.
1. Click Add Chart.
1. Click Table.
1. Click Add Measure.
1. Choose arrdelay.
1. Click Add Measure.
1. Choose depdelay.

## 公式HPの画面と同じような画面の出来上がり
<img width="1193" alt="スクリーンショット 2017-09-25 22.10.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/174596/ef84082e-7289-8c42-962a-957fca747f8e.png">

# 最後に
本当に、簡単に初期の画面から何かを表示するところまではすぐにできました。
あとは、このダッシュボードを使って色々なデータを可視化できるようにダッシュボードの操作方法を勉強していきたいと思います。

MapD は初めてなのでもう少し情報がほしいのもあります。是非良い情報があれば教えてください。
Controller以外でServletContextを取得するには？

spring-web-4.3.8.RELEASE

Spring Web Applicationならば、Controller以外でも、request,sessionなどなくても、ServletContextインスタンスをゲットすることができます。

```java
private static ServletContext getContext() {
	return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()
				.getServletContext();
}
```
Windows10にバージョン違いのXAMPPを混合させて導入する時の注意

自分の覚書になってしまって申し訳ないですが、
XAMPPの7.1.9と5.6.12を混合して入れたいと思い何故か7.1.9だけが導入に失敗する。
まずなぜバージョン違いを混合したいのか

WEB系は古いPHPの環境や新しいPHPの環境など様々あった。
XAMPPがMySQLをサポートしなくなったことがある・・・などなど
現在はまたサポートされたみたいでMySQLが入っている。
古いバージョンのXAMPPも入れておくと何かと便利だったためである。

結論としては、
xamppフォルダ名に7_1_9などアンダーバー(アンダースコア)を入れてはいけない。
xampp5_6_12は大丈夫だったが何故か2017/09/25の最新の7.1.9ではエラーが起きる。

フォルダ名は暫定だがxamppとしてある。
忘れがちなMongoDBの操作メモ


#ユーザを作成する

ユーザ情報例

```
Database:somedatabase
ID: user
PW: password
```

somedatabaseにユーザを作成する。

```　
use somedatabase
db.createUser(
  {
    user:"user",
    pwd:"password",
    roles:[
       { 
           "role" : "dbOwner",
            "db" : "somedatabase"
       }
    ]
  } 
);
```


##ユーザに足りないroleを追加する。
adminにDB管理をつけておく。

```
db.grantRolesToUser( "user", [ "dbAdmin" ])
```

### 後で困るのでrootもつけておく。
```
db.grantRolesToUser( "user", [ "root" ])
```


##同時に付けることも可能。
```
db.grantRolesToUser( "user", [ "root", "dbAdmin",  { role: "read", db: "comment" }])
```




他付けるroleに迷ったら全Role値を参考：https://docs.mongodb.com/manual/reference/built-in-roles/#built-in-roles

#ユーザを削除する。
削除したいデータベースをuseして、dropUserをかけていく。

```
use somodatabase
db.dropUser('useraname')
```
vagrant上のcentosにansibleでdocker-ceをインストールする

ansibleを勉強していく上でvagrant上に環境を作っておくと、さくさくとテストできます。
今回はansibleでdocker-ceのインストールに挑戦しました。

# 環境

+ vagrant centos72
+ ansible 2.4.0

# ソースコード

作成するのは以下の３ファイル

+ Vagrantfile
+ hosts
+ playbook.yml

dockerはcentos6系にはインストールができないので、7系で。
Vagrantfileにあるcentos72は適当にcentos7のBOXを追加してください。

```:Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "centos72"
  config.vm.network "private_network", ip: "192.168.33.10"
end
```


```:hosts
[vagrants]
192.168.33.10 ansible_ssh_user=vagrant ansible_ssh_private_key_file=.vagrant/machines/default/virtualbox/private_key
```

ポイントはdockerグループの追加です。

```yaml:playbook.yml
- hosts: vagrants
  user: vagrant
  become: yes
  tasks:
    - name: install yum-utils
      yum: name=yum-utils state=present

    - name: add docker repo
      shell: "yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo"
      args:
        chdir: "/etc/yum.repos.d"
        creates: docker-ce.repo

    - name: install docker-ce
      yum: name=docker-ce state=present

    - name: add group
      user: name=vagrant groups=docker append=yes
      tags: dockerhost
      become: True

    - name: restart docker
      systemd:
        name: docker.service
        state: restarted
        daemon_reload: yes
        enabled: yes
```


# 実行

```
$ vagrant up
$ ansible-playbook -i hosts playbook.yml
```

これで、vagrant上のcentosにdockerをインストールできます。

[github サンプル](https://github.com/va034600/sample-server/tree/master/ansible/docker-install)
[Kotlin]扱いやすいenum

# TODO
- シンプルで扱いやすいenumを作る

# 実装
enum class

``` RecyclerType.kt
enum class RecyclerType constructor(val int: Int) {
  BODY(1),
  HEADER(2)
  FOOTER(3);

  companion object {
    // enumへの変換を行う
    fun fromInt(index: Int): RecyclerType {
      return values().firstOrNull { it.int == index } ?: BODY
    }
  }

  val isBody: Boolean
  get() = this == BODY

  val isFooter: Boolean
  get() = this == FOOTER
}
```

呼び出し

```RecyclerAdapter.kt
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
  if(RecyclerType.fromInt(getItemViewType(position)).isBody){
    // 処理
  }
}
```

# おまけ
enumで指定した値以外が来ないという場合は
first {} としても良い。

想定外の値が来た場合はexceptionで落ちる。

``` RecyclerType.kt
    fun fromInt(index: Int): RecyclerType {
      return values().first { it.int == index } 
    }
```
TensorFlowのサンプルを動かしてみた(iOS)

## ディープラーニングとTensorFlow

* ディープラーニングはニューラルネットワークと呼ばれる機械学習手法の一種
* Tensorflowは、GoogleがOpenSourceとして公開しているディープラーニング技術を使った機械学習ライブラリ

## モバイルデバイス向けのサンプルコード

Android, iOS, Raspberry Pi向けのサンプルコードが用意されています
https://www.tensorflow.org/mobile/

## iOSサンプルアプリケーションの実行手順
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/ios/

iOS向けのTensorFlowのSampleとしては以下のプロジェクトが用意されています。

* benchmark
* camera
* simple

セットアップ手順はREADMEに記載の通りですが、簡単に説明すると下記の通りで簡単にセットアップできます。

1. 学習済みモデル(Inception)をサンプル(benchmark or camera or simple)内のdataフォルダを入れる
2. CocoaPodsで`pod install`してTensorFlowライブラリを導入
3. 作成されたxcworkspaceファイルを開いて実行

<img width="375" alt="IMG_0003.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/86399/c817fad1-5644-fbae-3efc-5e7e119e41ca.png">
(うまく認識できているようです)

※ 動作環境はXcode7.3以上となってますが、現時点(2017/09/25)で最新のXcode 9.0で動作確認しました。
※ 上記の説明はCocoaPodsを使用した手順ですが、もちろんTensorFlowコードをコンパイルするセットアップも可能です。
wysiwygエディタについての学習5


## draft-jsを使ってみる続き

### エディタの状態は状況を追跡する

エディタ状態の変更は上位の状態に伝播しつつ行われる
ペーストなどの処理の際にも`onChange`イベントハンドラを発火させることでテキストを解析して構造化できる

構造化する処理は、非同期なので、アトミックではないために競合状態を生み出してしまうかもしれない
異なる２つのハンドラーが同時に書き換えをした場合に、お互いが非同期なので最初の処理を後の処理が無視して上書きしてしまう
setTimeoutを使っても同様になる
データのロストが起きる場合にはこれを疑ってください

不可分操作 - Wikipedia
https://ja.wikipedia.org/wiki/%E4%B8%8D%E5%8F%AF%E5%88%86%E6%93%8D%E4%BD%9C

> 不可分操作（ふかぶんそうさ）あるいはアトミック操作 (英: atomic operation) とは、情報工学においていくつかの操作を組み合わせたもので、システムの他の部分から見てそれらがひとつの操作に見えるものをいう。
> * 全操作が完了するまで、他のプロセスはその途中の状態を観測できない。
> * 一部操作が失敗したら組合せ全体が失敗し、システムの状態は不可分操作を行う前の状態に戻る。

スレッドセーフ - Wikipedia
https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%AC%E3%83%83%E3%83%89%E3%82%BB%E3%83%BC%E3%83%95

> 共有データを何らかのアトミックな操作でアクセスすることで他のスレッドから同時アクセスされないことを保証する。これは一般に特別な命令を必要とするが、ライブラリがそのような機能をサポートしている場合がある。アトミック操作は多くの排他機構の基盤となっている。

### ベストプラクティス

非同期の問題があるので、`this.state`を参照する時には疑いをもち、`EditorState`を扱うハンドルを利用してください

	なるほどー。
	ペーストの時には、一旦レンダリングを待って同期してからonChangeするってことかな。。
	今ひとつ内部的な動きが理解できていないが、イベントを区別してハンドル関数を活用すればひとまずいいってことかな。

### イシューと落とし穴

#### 遅延状態の更新

setTimeoutなどで状態を更新するのは一般的
ただ、エディタでは更新が頻繁で競合が起きるため問題
このため、並列的な処理を切り出して、状態の更新に影響がないように、別プロセスにする必要がある

#### CSSの行方不明

デフォルトの挙動に関わるのでDraft.cssを使わない場合には同様のスタイル指定を独自記述する必要がある

	これは別に落とし穴でもない気もするけど

#### カスタムOSXキーバインディング

キーバインドをカスタマイズしている場合には上手く動かなくなる

	これも、問題っていうより普通だろうな

#### ブラウザ拡張

ブラウザ拡張により想定外の動きをすると、、

	そりゃそうだ

#### IE問題

IE11だとなんかおかしいよ

	そうか。。

#### モバイル対応

対応がまだ不完全
詳しくはiosとかandroidのタグのイシューをみてね

#### ポリフィル

babelでの変換によってポリフィル対応があるよ
ポリフィルはできるだけ早くロードしてね
Prologのテキスト

学校でプログラミング教えています．
　
Prologのテキスト公開します．
[Prologのテキスト（PDF形式, 72ページ, 711KB）](http://www.k-techlabo.org/www_prolog/prolog_main.pdf)　2020/04/14更新
　今では話題になることも少ないですが，うちのゼミでは推論エンジンとしてPythonプログラムのバックエンドシステムとして使いはじめています．
 
対象の処理系は[SWI-Prolog](http://www.swi-prolog.org/)です．
PrologはISOで標準化されているとはいえ，動作（推論処理）は処理系毎にかなり違います．それで特に "[SWI-Prolog](http://www.swi-prolog.org/)" に限定しています．（若干ですがGNU Prologについても説明しています）
　
ご意見いただけたら嬉しいです．
　
参考）[Pythonの教材（テキスト作っています）](https://qiita.com/KatsunoriNakamura/items/b465b0cf05b1b7fd4975)
　こちらもご意見いただけたら嬉しいです．
　
－－－－－－－－－－－－－－－－－－－－－
##更新に関することなど
【補足】(2020/04/07-14)
　SWI-Prolog処理系の起動時の初期設定に関して解説を加えました．それと，有理数の扱いについても解説を入れました．
　
－－－－－－－－－－－－－－－－－－－－－
【補足】(2018/11/30)
　事実や規則の定義をコンソールから直接入力する方法についての解説を追加しました．
　
－－－－－－－－－－－－－－－－－－－－－
【補足】(2018/11/08)
　module, includeに関する説明を加えました．
　
－－－－－－－－－－－－－－－－－－－－－
【補足】(2018/10/20-26)
　Prologのテキストを久しぶりに更新しました．SWI-Prologでソースプログラムを読み込む際の文字コードの指定方法など，いくつか解説を追記しました．

-----
written by 中村勝則
wysiwygエディタについての学習4


いまのところドキュメントを読んでるだけ。。

## draft-jsを使ってみる続き

### ブロックスタイリング

blockStyleFnを定義することで実現する。これはキーバインドと同じだな。

デフォルトcssが用意されている。
このcssの指定に「/」の文字が使われているけど、cssってこんな指定できるんだな。

[HTML, CSS, JavaScript] id名/class名に使用できる文字の種類
https://gist.github.com/think49/d8fbcf7f1c743e21bc79bb7d16178cad

> HTML Living Standard (通称 HTML 5) ではid属性値、class属性値に対して空白文字を除く全ての文字を使用できます。 id属性値の「名前が一意でなければならない」のは HTML 4.01 と同様です。

CSSの変態向き - ID, classを顔文字でコーディングする方法｜Web Design KOJIKA17
http://kojika17.com/2013/03/kaomoji_selectors.html

> HTMLのID, classを顔文字、または日本語で書きます。


blockStyleFnで定義して、ハンドルはなくてcssファイルに記述されたスタイルを適用する。。
domのタグやclassで指定するわけじゃなくここで指定する？？いまいちわかってない。

### カスタムブロックのレンダのマップ

convertFromHTMLで変換された時、コピペで貼り付けされたとき、マップを照合して変換処理が行われる。
このマップにも、デフォルトのマップがある。これにマッチしないとスタイルなしとして処理される。
実装は、blockRenderMap属性に`Immutable.Map`を指定して上書きできる。

デフォルトのマップにマージして拡張することもできる。
`Draft.DefaultDraftBlockRenderMap.merge(blockRenderMap);`

あるタグが貼り付けられた時に未定義ではなく別のタグにマップするには`aliasedElements`で指定できる。

### カスタムブロックのラッパー

https://draftjs.org/docs/advanced-topics-custom-block-render-map.html#content

若干、自信ないけど、、
liをulで包むようなラッパー処理やもっと複雑な処理を書くときにクラスを定義して、
`wrapper`として指定することで実行させることができるってことかな。

### カスタムブロックコンポーネント

https://draftjs.org/docs/advanced-topics-block-components.html#content

マッピングだけじゃなくて、レンダリングの処理自体を拡張したいときに使うのかな

`blockRendererFn`に指定することで、レンダリングの処理を拡張できる
デフォルトは`DraftEditorBlock`が使われている

カスタムブロックコンポーネントでのテキスト処理は`DraftEditorBlock`を内部で定義することで可能

### カスタムブロックコンポーネントの定義

render()メソッドの内部でメタデータを状態を取ってくる処理を記述する
面倒な手続きだが、踏む価値がある

### 注意など

マウスイベントをつかうときには読み込み専用にしてエディタ編集をとめましょう

ノートのエディタでは画像メディアの編集などはサポートせずに、画像メディアのコンポーネントに実装する
（翻訳がわからん）

### 複雑なインラインスタイル

文字レベルでオブジェクトを定義して行く、便宜上、配列として考えられる
挙動としては、同じ不変オブジェクトを使いまわす実装になっている
また、同じスタイルの文字を探し出して、まとめてレンダリングする

	なるほど、、スタイルデータが実態データと分けて定義されているわけか。
	わざわざそうしてみたいなので、効果的なのかなあ。。

スタイルの拡張や、マップの定義の上書きができる。

	文字ごとにスタイルを指定した状態を保たせる感じかな。
	でも、レンダリングではまとまったものをまとめてくくる？

```
<span data-offset-key="8g65c-0-2" style="font-weight: bold;">
<span data-text="true">ぇ</span>
</span>
```

### ネストされたリスト

onTabメソッドをつかってTabまわりのキーボード入力の処理を処理できる

### テキストの方向

言語によって、RTLとLTRがあり、それらを判別してテキストの方向を処理します。

### テキストの寄せ

textAlignmentを使って明示的に指定できる。（デフィルトは言語と文字セットで判別）
Scalaプログラマがjavascriptのasync/awaitを勉強したメモ

# はじめに
Scalaプログラマである僕のjavascriptのasync/awaitの勉強メモです。
で、ScalaプログラマにとってはFutureがasync/await(Promise)に似たモデルなので、それに絡めて理解したことをまとめようと思った次第です。

# 本編
async/awaitの説明を読むと「asyncをつけるとPromiseを返すfunctionになる。awaitするとそれの値をとり出せる」みたいな説明が出てきます。まぁ言われることはわかるんだけど、何となく心の底から理解できてない感じがありました。

で、以下の説明を読んでいるとScalaのFutureと絡めてとても理解しやすい例がありました。

[非同期関数 - Promise をわかりやすくする  |  Web  |  Google Developers](https://developers.google.com/web/fundamentals/getting-started/primers/async-functions?hl=ja#_8)

引用します。

    同期的に見えるコードを記述している場合でも、並列で実行するチャンスを見逃さないようにしてください。

```javascript
async function series() {
  await wait(500);
  await wait(500);
  return "done!";
}
```

    上記は完了するのに 1000 ミリ秒かかります。

```javascript
async function parallel() {
  const wait1 = wait(500);
  const wait2 = wait(500);
  await wait1;
  await wait2;
  return "done!";
}
```

    一方、上記は両方の待機が同時に発生するため、完了までにかかる時間は 500 ミリ秒です。

これを見ると以下のようなプログラムと非常に似ているなとかんじます。

```scala:1000msecかかる
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import scala.concurrent.{ Await, Future }

def wait(msec: Int) = {
  Future(Thread.sleep(msec))
}

def series() = {
  Await.result(wait(500), Duration.Inf)
  Await.result(wait(500), Duration.Inf)
  "done!"
}
```

```scala:500msecかかる
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import scala.concurrent.{ Await, Future }

def wait(msec: Int) = {
  Future(Thread.sleep(msec))
}

def series() = {
  val wait1 = wait(500)
  val wait2 = wait(500)
  Await.result(wait1, Duration.Inf)
  Await.result(wait2, Duration.Inf)
  "done!"
}
```

ただ、大きく違う部分が2点あります。

* javascriptの`series`はそれ自身がasync functionなのでscalaの`series`の`Future`を返すべき
    * というかasync functionの中でしかawaitを使えない
* javascriptの実行エンジンはシングルスレッドであり、`await`はブロックしない[^1]。 `await`以降の行は`await`の引数の処理が終わった後に実行されるコールバック処理になっている。
    * scalaの方は`wait`の処理を別スレッドが実行し、`Await.result`では別スレッドの実行終了をメインスレッドがブロックして待っている。

この2つの事実からより近いプログラムは以下のような、`await`処理のところを`for`式で置き換えたようなものだと理解しました。

```scala:1000msecかかる
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

def wait(msec: Int) = {
  Future(Thread.sleep(msec))
}

def series() = {
  for {
    _ <- wait(500)
    _ <- wait(500)
  } yield "done!"
}
```

```scala:500msecかかる
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

def wait(msec: Int) = {
  Future(Thread.sleep(msec))
}

def series() = {
  val wait1 = wait(500)
  val wait2 = wait(500)
  
  for {
    _ <- wait1
    _ <- wait2
  } yield "done!"
}
```

さすがに`wait`の処理が別スレッドで実行されるところはjavascriptとは違いますが、こういうふうに理解しておくとjavascriptのasync/awaitのコードが理解しやすくなりそうです。

[^1]: 関数定義の前に async キーワードを使用すると、その関数内に await を使用できます。 Promise を await する場合、この関数は、ブロックすることなく Promise が完了状態になるまで一時停止します。 ( https://developers.google.com/web/fundamentals/getting-started/primers/async-functions?hl=ja )
素のCentOS（EC2）にGDALをインストールする場合の手順

## 取得 
http://trac.osgeo.org/gdal/wiki/DownloadSource
からstableのVerを探してwgetで取得

## インストール
以下はrootで作業。

```
tar xvzf gdal-2.2.2.tar.gz
cd gdal-2.2.2
./configure
```

と思ったら、gccが入ってなかった…。

`yum install gcc`

で入れたと思ったら今度はg++が入ってなかったので、configureを叩いたら"You don't have a working C++ compiler"というエラーメッセージが…。

`yum install gcc-c++`

でg++をインストール

`make` 
結構時間かかる。
`make install`

## 動作確認

`ogrinfo --help`

## MySQL対応
これだけだとMySQLには全く対応できていない…。
というわけでもう一度。

```
yum install epel-release
yum update
yum install mysql
```

でMariaDB Connectorを入れる。
`yum install mysql++-devel.x86_64`
結果的に必要だと思うのだが、検証までしていない。
`./configure --with-mysql=/usr/bin/mysql_config`
で
`  MySQL support:             yes`
になっていることを確認。して再Make

```
make clean
make
make install
ogr2ogr --version
GDAL 2.2.2, released 2017/09/15
```

これでOK。

###心残り
epel入れたんだから、yumでgdal入れてもよかった気もするけど。
Facebook Pixel Code を読み込むと、 外部から読み込んだ js 内の日本語が文字化けする。

とてもハマったので共有。
# 結論

外部から読み込む js には charset をキチンと指定しましょう。。。

```diff
-<script type="text/javascript" src="/js/bundle.js"></script>
+<script type="text/javascript" charset="UTF-8" src="/js/bundle.js"></script>
```

# 事象
今まで何の問題もなく webpack でビルドした js が動いていましたが、 facebook のアド用コードを追加した途端、ファイルが文字化けしました。以下のようなコードです。

```js:index.html
<!-- Facebook Pixel Code -->
<script>
!function(f,b,e,v,n,t,s)
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t,s)}(window,document,'script',
'https://connect.facebook.net/en_US/fbevents.js');
</script>
...
<script type="text/javascript" src="/js/bundle.js"></script>
```

`charset="UTF-8"` を外部から読み込む js に明示すると、文字化けが直りました。
原因は深く追求できていないですが、文字コードの指定などはしっかりしておくべきだと反省しました。

# 追記
さらに上記の修正をした後でも `<meta charset="UTF-8">` を`<head>`直下に書かないと、不具合が出ていました。


```diff
<head>
+  <meta charset="UTF-8">
   <!-- Facebook Pixel Code -->
   <script>
    ...
   </script>
-  <meta charset="UTF-8">
```

具体的には、`/url?tags[]="あいうえお"` などの日本語クエリを含む api リクエストがなぜか shift-js に変換されて `unable to decode value` という状態になっていました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/26095/8b298207-c85b-4042-f98b-da5fc09f9bdc.png)

`<meta charset="UTF-8">` を`<head>`直下(Facebook Pixel Code より上)に書くことで回避できました。
UIViewをプルンプルンにしてみた

## 押したくなるアニメーション
押したくなるボタンを作るにあたって、
デザイナーから「おっぱいっぽくプルンプルンするアニメーションを作ってくれ」と言われたので頑張りました。

![screenshot](https://github.com/malt03/JellyAnimationView/raw/master/screenshot.gif?raw=true)

おっぱいっぽいかは置いておいて、まぁ気持ちの良いアニメーションにはなったかなと思います。

## 解説
iOS9から追加された、`CASpringAnimation`というのを使っています。
で、プルプル感を出すために高さと幅のアニメーションを分けて、dampingをズラすという超高等テクニックです。
名前は、Oppaiにするわけには行かず、Jellyにしました。

## 肝心のフレームワーク
フレームワークのリンク書き忘れました
https://github.com/malt03/JellyAnimationView
別のbranchで独立にガンガン進めちゃってmergeしようとすると確実にコンフリクトする件

1. **マージの単位がでかすぎる。小さくハーケンを打って、細かくmasterにマージしてもらう。**
2. 「逆マージ」（場合によってはcatch up/upstreamと呼ばれたりする）は、各自頻繁に行って、最新のmasterの動向についていく。