OmniAICreator/Qiita-1.07M huggingface dataset:
phpMyAdmin on docker が便利すぎる

Docker使ってWEBシステムを開発している場合、コンテナでMySQLサーバーを起動することが定石だと思います。
で、このDBの中身をGUI的に操作したい場合、3306ポートをEXPOSEしちゃう？

**....そんな必要はありません！**

DBをGUI的に操作するコンテナ、つまりphpMyAdminコンテナがあればいいんです！

phpMyAdminの公式Docker imageのページはこちら
https://hub.docker.com/r/phpmyadmin/phpmyadmin/

公式ならほぼ安心ですが、Docker imageには危険なexploitが埋め込まれていたりすることもあるので、Dockerfileも念のため確認しておきます。

https://hub.docker.com/r/phpmyadmin/phpmyadmin/~/dockerfile/

やっぱalpineベースなんですね〜。万全を期すならばこのDockerfileを自前でビルドでしょう。
Dockerfileをダウンロードしてしかるべきところに格納し、``docker build`` 、もしくはdocker-compose.ymlに追記して``docker-compose build``するだけなんでまったく面倒ではありません。
でも公式イメージなんで、pullするだけでも大丈夫ですね。:smile:


# docker-compose.ymlにphpMyAdminの定義を追加する

ではさっそく使ってみましょう。
たとえば、docker-compose.ymlでMySQLをこんな風に定義している場合

```docker-compose.yml

# その他のコンテナの定義
 .
 .
 .

# MySQLコンテナ
mysql:
  image: mysql:5.7
  volumes:
    - "./mysql:/var/lib/mysql"
  environment:
    - MYSQL_ROOT_PASSWORD=password

```

これに、ちょちょいとphpMyAdminのコンテナを追加

```docker-compose.yml
mysql:
  image: mysql:5.7
  volumes:
    - "./mysql:/var/lib/mysql"
  environment:
    - MYSQL_ROOT_PASSWORD=password

phpmyadmin:
  image: phpmyadmin/phpmyadmin
  environment:
    - PMA_ARBITRARY=1
    - PMA_HOST=mysql
    - PMA_USER=root
    - PMA_PASSWORD=password
  links:
    - mysql
  ports:
     - 8080:80
  volumes:
     - /sessions

```
蛇足：一応公式の指示どおりにcompose.ymlを書きましたがこのままだとdata volumeの残骸が増え続ける可能性があるので、sessionsは明示的にホストのディレクトリに結びつけた方いいかもしれません。たとえば

```
  volumes:
     - "./phpmyadmin/sessions:/sessions"
```
とか。ここではこのままいきます。

composeでコンテナ起動

```sh
docker-compose up -d
```

ブラウザで``http://localhost:8080``にアクセス

![php.png](https://qiita-image-store.s3.amazonaws.com/0/74328/3e5c5143-72fb-1c12-df43-f929adc87e0f.png)


無事localhostでphpMyAdminが表示されました！

なにが素晴らしいって思い立ってからここまで到達するのに10分も経っていないということ。
PCやMacにMySQLのクライアント入れるよりお手軽ではないでしょうか。Docker以降、WEBサービスを手元で動作させるハードルが劇的に下がっていると感じます。

**Dockerって素晴らしいですね〜。**
php://inputを使い受け取ったJSONをそのまま返す

```php
<?php
echo file_get_contents('php://input');
```

## もうちょっと細かいことやった版

```php
<?php
sleep(1);
$data = json_decode(file_get_contents('php://input'), true);

header('Content-Type: application/json');
echo json_encode($data);
```

## 条件で失敗する版

わざと失敗する状況を作りたい場合に。

```php
<?php
sleep(1);
$data = json_decode(file_get_contents('php://input'), true);

if ($data['bad']) {
  http_response_code(400);
  header('Content-Type: application/json');
  echo json_encode($data);
}
else {
  header('Content-Type: application/json');
  echo json_encode($data);
}
```

## 参照

- [receive json post with php - Stack Overflow](http://stackoverflow.com/questions/18866571/receive-json-post-with-php) ここから。
- [PHP: php:// - Manual](http://php.net/manual/ja/wrappers.php.php)
- [PHP: file_get_contents - Manual](http://php.net/manual/ja/function.file-get-contents.php)
- [PHP: json_decode - Manual](http://php.net/manual/ja/function.json-decode.php)
- [PHP: json_encode - Manual](http://php.net/manual/ja/function.json-encode.php)
- [PHP: http_response_code - Manual](http://php.net/manual/en/function.http-response-code.php)
【初心者向け】はじめてGitを使う人の為のイメージ図


## :hatching_chick: はじめに :hatching_chick:

これは Git を初めて使う人の為のイメージ図です
[RailsGirls](http://railsgirls.jp/) などで初めて Git を知る人に対して図を書いて説明する事が多いので、説明文付きでイラストにしました。なるべくわかりやすい説明文にしたつもりですが、皆さんのフィードバックを受けてこれからも改訂していきます。

![Git-基本のキ.gif](https://qiita-image-store.s3.amazonaws.com/0/11074/385ed68e-3431-4135-0569-e058480866ce.gif)

印刷用 [初心者向けGit図解.png](https://springaki.github.io/blog/2016/12/14/for_beginners_git_images/)


## :santa_tone1: 参考

その他にも色んな例えで説明してくれている人もいるので自分にあった例えで理解すると良さそうです。

###### 郵便局の例
- デザイナーがこうやってGit覚えて大好きになったよ♡ - Qiita
  - http://qiita.com/yunico-jp/items/87bdd13971e82833f6bb

###### 猫がかわいい説明

- Git初心者に捧ぐ！Gitの「これなんで？」を解説します。
  - http://kray.jp/blog/git-why-explanation/
- git pull と git pull –rebase の違いって？図を交えて説明します！
  - http://kray.jp/blog/git-pull-rebase/
ruby 複数の区切り記号で区切られたデータを取り出す

#はじめに
rubyで複数の区切り文字でデータが与えられ時,
例えば`1->2 3`のように`->`と' 'で区切られているとき
**`str.split("->").split(" ")`ではだめです**
なぜなら`String.split("->")`で`["1","2 3"]`となり
配列に対して`split`メソッドは定義されていないのでエラーとなるからです

#解決案
単純に区切り文字を統一してからsplitすればいいので
`str.gsub("->"," ").split(" ")`
とすればよいでしょう
ただしこれは,どの区切り文字であろうと,どこにあろうと自由です
つまり以下のものなども対応します
`1->2->3`
`1 2 3`
`1 2 3 4 5 6->7 8->9->10`

形式が決まっているのなら
`str.match(/(\d)->(\d)\s(\d)/)`
と書いてもよいでしょう**(返り値の形式に注意)**

数字だけとか取り出したいものが決まっていれば
`str.scan(/\d/)`
と書けます
冬にオススメmagic-filetypeで関連付け

こんにちは、私のEmacsを再起動する[.emacs Advent Calendar 2016](http://qiita.com/advent-calendar/2016/dot-emacs)です。メジャーモードとファイルの関連付けにべんりなEmacs Lispパッケージを作成、メンテナンスしてるので布教がてら紹介していきますヾ(〃＞＜)ﾉﾞ ~~undocumentedな機能も溜まってきたことだし…~~

## [magic-filetype](https://github.com/zonuexe/magic-filetype.el)とは何か

なんか、メジャーモードっぽいべんり機能を寄せ集めるつもりで作ったパッケージです。

## 言語とメジャーモードの関連付け

基本的なことは[拡張子の関連付け：ファイル名ごとにモードを設定する](http://qiita.com/tadsan/items/a21c268021b46b8a6b33)をお読みください。`auto-mode-alist`にファイル名のパターン(拡張子など)を登録していくのが基本です。

例として、JavaScriptの編集に(標準の`javascript-mode`の代りに)[js2-mode](https://github.com/mooz/js2-mode)を利用する場合は`.emacs`ファイルに以下のように記述します。

```init.el
(add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))
```

## `magic-filetype-major-mode-of`

上記の方式には若干の問題があります。俺は`javascript-mode`を捨てて`js2-mode`に移行したぞ！ と思っても、Emacsの標準設定では`.json`ファイルは`js2-mode`ではなく`javascript-mode`が起動されることになります。……これではおいしくないぞ？

そんなときに利用するのが`magic-filetype-major-mode-of`です。これは言語名のシンボルからメジャーモードを返す函数です。

```init.el
;; 長いから短くエイリアスにする
(defalias 'major-mode-of 'magic-filetype-major-mode-of)

;; .jsonファイルをJavaScriptと同じモードで開く
(add-to-list 'auto-mode-alist `("\\.json\\'" . ,(major-mode-of 'javascript)))

;; composer.lockファイルを .json と同じモードで開く
(add-to-list 'auto-mode-alist `("/composer\\.lock\\'" . ,(major-mode-of 'json)))
```

これで上記に設定したモードはすべて`js2-mode`で開くことになったわけです。めでたい。

しかし、JSONに特化したメジャーモードとして[json-mode](https://github.com/joshwnj/json-mode)が存在することを知ったのでこちらに移行しようとしたい！ と思ったとします。

心配ご無用です。

```init.el
;; .jsonファイルをjson-modeモードで開く
(add-to-list 'auto-mode-alist '("\\.json\\'" . json-mode)))

;; composer.lockファイルを .json と同じモードで開く
(add-to-list 'auto-mode-alist `("/composer\\.lock\\'" . ,(major-mode-of 'json)))
```

そうです。「JSONっぽいファイル」の定義をいちいち全部置換しなくて済むのです。

## magic-filetype-set-auto-mode

もっと短く書きたい… そんなあなたのために`magic-filetype-set-auto-mode`があります。

これは、以下のように利用します。

```init.el
(add-to-list 'auto-mode-alist '("\\.json\\'" . json-mode)))
(magic-filetype-set-auto-mode 'json)

(add-to-list 'auto-mode-alist '("\\.rb\\'" . enh-ruby-mode)))
(magic-filetype-set-auto-mode 'ruby)
```

これで、「JSONっぽいファイル」「Rubyっぽいファイル」の多くにメジャーモードの設定を施すことができます。たとへば、世の中には`Gemfile`やら`Puppetfile`やら多くのRubyっぽいコンフィグファイルがありますが、それらひとつひとつを設定するのは骨が折れるのでまとめて面倒見てやるよ、ってのが`magic-filetype-set-auto-mode`の発想です。

RubyとかJSONとか触ることの多い型はご検討ください。

## あとがき

なんか気になったことがあれば意見ください。
TensorFlow v0.12でtf.train.Saverのチェックポイント・フォーマットが変更

最新版（v0.12.0rc）にてチェックポイントが読み込めない事による不具合が発生。

v0.12では`tf.train.Saver`によって`*.meta`だけでなく`*.index`などが生成されるなど、生成物の名前にも違いが出る。これにより既存の`tf.train.Saver`により生成したチェックポイントを読み込む際に失敗する可能性がある（特に、チェックポイントをファイル名で直接参照しているプログラム）。

## 対応策

プログラムでは、きちんと`tf.train.Saver.last_checkpoints`によりチェックポイントのリストを取得する、または`tf.train.latest_checkpoint`によりlatestに指定されたチェックポイントのパスを取得すること。

なお、暫定の対応として`tf.train.Saver`のコンストラクタに`write_version=1`を指定することで既存(V1)のフォーマットを使用できる（v0.12ではデフォルトで`write_version=2`が指定されるように変更されている）。既存コードを移植する際にチェックポイント周りでエラーが起きた場合は`write_version=1`により解決する場合がある。

ちなみに、数日前にTensorFlowのAPIリファレンスのデザインが一新された。

Saverは[こちら](https://www.tensorflow.org/api_docs/python/state_ops/saving_and_restoring_variables)。

## References

[ISSUE] seq2seq checkpoints not working #6274 https://github.com/tensorflow/tensorflow/issues/6274
GStreamer アプリを書くなら GNOME Builder で。

## GNOME Builer って?

![GNOME Builder](https://wiki.gnome.org/Apps/Builder?action=AttachFile&do=get&target=splash.png)

[GNOME Builder](https://wiki.gnome.org/Apps/Builder) (正しくは Builder)は GNOME のための IDE (統合開発環境) です。

去年の3月リリースされたばかりの IDE なので、機能の豊富さは Eclipse や Visual Studio に劣ります。
しかし、`for GNOME` なだけあって、GStreamer アプリなどの書きやすさは抜群です。

今日はこれを紹介します。

## どんな機能があるの?

エディタでやりたことの、だいたいの機能は実装されています。

- Snippets (C/Javascript/Python/Vala に対応)
- Split views
- Auto Indentation
- Project Management (Autotools, Meson などに対応)
- Auto Completion
- Markdown Preview
- **Vim Engine**
- Mini map
- ... and more!
 
すでに実装されているもの、実装予定のあるものは↓こちらから見ることができます。

  https://wiki.gnome.org/Apps/Builder/Features

## 他のエディタからの移行

Vim と Emacs のエミュレーションがあります。私のように `:w` や `i` を無意識のように打ってしまう人にも安心です。

ただ、Vim のエミュレーションに関して `Virtual Line mode` だけは実装が少々甘い気がする...

## 推せるところ

**Auto Completion がいい**

![Screenshot 2016-12-15 02:42:55.png](https://qiita-image-store.s3.amazonaws.com/0/97187/9e8ea029-f987-f3fd-d86a-e933936b74c3.png)


入力補完はなかなか高速です。ファイル内補完はコードに限らずMarkdownなどでも使用することができます。
また、`meson.build` などの*プロジェクトファイル*を作成しておくと、関数やマクロを補完することもできます。


**GNOMEならではのドキュメント参照**

![Screenshot from 2016-12-15 02-56-23.png](https://qiita-image-store.s3.amazonaws.com/0/97187/50ea2a8c-3589-0bd3-06e3-25acb57fbaee.png)

Debian の GStreamer や GLib のパッケージの中に `-doc` が付くパッケージがあります。
これは `devhelp` などから読むことができるリファレンスマニュアルたちです。

Builder ではカーソルの下にある文字列からこのリファレンスを引くことができます。(Shift+k)

**最終兵器ターミナル**

![Screenshot from 2016-12-15 02-41-37.png](https://qiita-image-store.s3.amazonaws.com/0/97187/3bb972e7-ac8a-cf94-c953-8a0e1d201ac7.png)

スクリーンショットを見るとわかりますが、普通のターミナルがIDE内にいます。
いざとなれば、このターミナルでVimを開くことだってできます。無敵です。

## おわりに

私は1年前、Builderがリリースされた数カ月後に試したのですが、そのときにはこんな記事を書きたくなるほどの雰囲気ではありませんでした。しかし、今はどうでしょう。私の貧弱な vimrc よりもリッチで vim のようにつかえるものなっていたのです！素晴らしい。。

`apt-get install gnome-buidler` で一度試してみてはいかがでしょう。
lambdaでGoogleAnalyticsを定期的にSlackにレポートする

##nodeからGoogleAnalyticsにアクセスする方法
[こちら](http://qiita.com/ryot_a/items/e7bbefef5049697cbc60#google-analytics%E3%81%AE%E6%83%85%E5%A0%B1%E3%82%92%E5%8F%96%E5%BE%97)を参考に

###ざっくり説明すると・・・
####Google Developers Console から下記を設定
(0. プロジェクト作成)
1. APIを有効にする
2. サービス アカウント キーを作成(※1)

####Google Analytics
1. ビューIDの確認
2. ユーザー管理から「表示と分析」が可能なメールアドレスを追加(※1のアドレス)

Developer Consoleから取得したJSONのclient_emailを利用します。

##パラメータの説明、取得できるデータ
####Core Reporting API
[Core Reporting API - 一般的なクエリ](https://developers.google.com/analytics/devguides/reporting/core/v3/common-queries)
[Core Reporting API - リファレンス ガイド](https://developers.google.com/analytics/devguides/reporting/core/v3/reference#metrics)

####Dimensions & Metrics
[本家のサイト](https://developers.google.com/analytics/devguides/reporting/core/dimsmets#cats=user)
[日本語で説明があるサイト](http://info-i.net/ga-analytics)


##Lambdaの定期実行
「Configure triggers」の設定で「CloudWatch Events - Schedule」を指定します。
中身の指定の仕方は下記を参照して下さい。
[Rate または Cron を使用したスケジュール式](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/tutorial-scheduled-events-schedule-expressions.html)


##Slackへの通知
Select blueprintの設定で「cloudwatch-alarm-to-slack」を選択してください。
slack側の設定やkmsを利用してURLを暗号化する方法など、
ほぼソースのコメントに書いてありますので読んでください。

[ここ](http://blog.serverworks.co.jp/tech/2016/02/16/lambda-cloudwatch-alarm-to-slack/)とか参考になるかな。
Webhook URLの暗号化はAWSコンソール上でワンクリックでできるので上記通りにやる必要はないです。
LXDのコンテナ中でホストのホームディレクトリを読み書きする方法

LXD 2.0.8/2.6から、LXDコンテナとホストのUID/GIDを設定コマンドからremapできるようになりました。これにより「コンテナの中からホストのホームディレクトリを読み書きする」ための手順が非常に簡単になります。

詳しいことは以下の記事を参照してください。

https://insights.ubuntu.com/2016/12/08/mounting-your-home-directory-in-lxd/

## 必要なパッケージのインストール

最新のLXDをインストールしてください。Ubuntu 16.04 LTSであれば、パッケージを更新すればLXD 2.0.8になるはずです。

```
$ sudo apt update
$ sudo apt install lxd
```

`lxd`グループに所属するために、一度ログインしなおしてください。

LXDを使いはじめる前にLXDの初期設定を行います。基本的に次のコマンドを実行して、提案される設定をそのまま適用していくだけです。

```
$ sudo lxd init
```

LXDの使い方については[LXDの公式サイトのヘルプ](https://linuxcontainers.org/ja/lxd/getting-started-cli/)や[LXD Blog post series](http://qiita.com/m-shibata/items/029b19d90af2a79116c2)を参考にすると良いでしょう。[LXDの試用ページにあるチュートリアル](https://linuxcontainers.org/ja/lxd/try-it/)も参考になります。


## `subuid`と`subguid`の変更

ここからが今回の機能に関する説明です。

まずコンテナ起動時に実行される`newuidmap/newgidmap`において、ホストのUID/GIDをマッピングできるように`subuid/subgid`ファイルを編集します。

Ubuntuの標準の設定だと、インストール時に作ったユーザーのUIDとGIDはどちらも1000になりますので、次のコマンドで設定できます。

```
$ echo "root:1000:1" | sudo tee -a /etc/subuid /etc/subgid
```

これはrootが`newuidmap/newgidmap`を使って、ホスト上のUID/GIDをユーザー名前空間のマッピングに使えるすることを意味しています。各フィールドの意味は「`USER NAME:START ID:NUM`」です。

もし異なるUIDやGIDを許可したい場合は、次のように個別に設定しましょう。

```
$ echo "root:$(id -u):1" | sudo tee -a /etc/subuid
$ echo "root:$(id -g):1" | sudo tee -a /etc/subgid
```

ここまでは一度設定するだけです。


## コンテナの作成とUID/GIDのマッピング

次にコンテナを作成します。Ubuntu 16.04 LTSのコンテナを「`xenial`」という名前で作成しています。

```
$ lxc init ubuntu:16.04 xenial
```

`xenial`コンテナに対してUID/GIDのマッピングを設定します。これは`raw.idmap`設定を変更するだけです。

```
$ lxc config set xenial raw.idmap 'both 1000 1000'
```

「`both`」はUID/GID両方に同じ値を設定するパラメーターです。書式は「`both HOST_ID CONTAINER_ID`」となります。`HOST_ID`にはホスト上のUID/GIDを、`CONTAINER_IDにはHOST_IDをコンテナの中にマップした時のIDを記述します。言い換えると「ホスト上のUID/GID 1000をコンテナ上のUID/GID 1000として扱う」ということです。これでコンテナからホストのUID/GID 1000のファイルを扱えることになります。

もしUID/GIDを異なる値にしたい場合は`both`のかわりに`uid`や`gid`を使います。`raw.idmap`に複数の値を設定する場合は、改行を入れます。しかしながら`lxc config`コマンドは直接改行を扱えません。そこで設定内容を標準入力から受け付けるようにして、そこにパイプで設定内容を流し込みます。たとえばホスト上のUIDが1010、GIDが1011のIDをコンテナ上のUID/GIDともに1000にマッピングしたい場合は、次のようにコマンドを実行します。

```
$ echo -e "uid 1010 1000\ngid 1011 1000" | lxc config set xenial raw.idmap -
```

ハイフンをつないで範囲を指定することも可能です。この場合、マッピング元とマッピング先の個数が同じになるようにしてください。

`lxc config show xenial`と実行すると、設定結果が表示されるはずです。

ちなみに`lxc config`ではなく`lxc profile`を使えば、この設定を複数のコンテナで共用できます。プロファイルに関する詳細は[こちら](http://qiita.com/m-shibata/items/3308bb7724749ba9e0f1#設定プロファイル)を参照してください。

おそらく起動中の既存のコンテナにも上記設定は可能です。ただし設定が反映されるためには、一度コンテナの再起動が必要です。


## ホームディレクトリのマウント

最後にホストのホームディレクトリをコンテナの中にbind mountしてみましょう。

```
$ lxc config device add xenail homedir disk source=/home/shibata/ path=/home/ubuntu/
```

この状態でコンテナを起動すると、コンテナの中でホストのホームディレクトリの読み書きが可能になっているはずです。また、コンテナで書き込んだファイルのオーナーIDは、ホストから見るとホストのユーザーのオーナーIDになっているはずです。

```
$ lxc start xenial
$ lxc file push ~/.ssh/id_rsa.pub xenial/home/ubuntu/.ssh/authorized_keys
$ lxc list
（コンテナの情報表示）
$ ssh ubuntu@コンテナのアドレス

xenial$ ls ~/
（ホストのホームディレクトリと同じ結果になる）

xenial$ echo "test" > abc.txt
（書き込める）

xenial$ exit
$ cat abc.txt
test
$ ls -l abc.txt
（オーナーがホストのUID/GIDに一致している）
```
jQuery 仮想HTMLでanimate

タイトルの通り、アホな事なことを思いついたので試してみた。

```javascript:test2.htm
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script>

$(function(){
	$("#start").on('click', function(){

		var virtual = $("<div style='width:0px'/>");
		
		virtual.animate({width: "100px"}, {
			duration: 2000,
			step: function(now, tween){
				$('#step').text(now);
			}
		});
	});
});


</script>

<head>

<body>

<button id='start'>開始</button><br>
step: <span id='step'>0</span><br>

</body>
</html>
```

``virtual``のセレクタはdocument内には存在しない。なんせ生HTMLだもの。

なので普通に考えてこれは動きそうにない。

でも実際は・・・

![test.gif](https://qiita-image-store.s3.amazonaws.com/0/102207/854211dc-2ab4-851c-3e7f-e9d1f9b6b716.gif)

うおおおおおおｗｗｗｗｗｗ

これは何か色々捗りそうな気がする！！！

<span class='label label-default'>追記</span>
興奮しすぎて何も考えずに投稿してしまいましたが、結局わたしが何に興奮して鼻血を出してたかというと

要はanimateで作り出される数値を使えば、直接cssプロパティを変更させるだけでなく、それを元に自由にいろんな動きを生み出せるということなのです( *ﾟωﾟ)=3 ﾌﾝｽ

![test.gif](https://qiita-image-store.s3.amazonaws.com/0/102207/9e72d21d-8766-aec9-7908-1acefc096e4b.gif)

こんな感じの永久ループなスクロールなんかも、Easing付きで簡単にアニメーションできちゃうのです。

これはワクワクしませんか？ね？ね？
webpackでelectronを使う時にはまったこと


この前から構築してたgulp環境上でelectronアプリ作ろうと思って、とりあえず公式の[クイックスタート](http://electron.atom.io/docs/tutorial/quick-start/)でもやってみるかって思ってやったらどん詰まりした。

起動すると

```
TypeError: Cannot read property 'on' of undefined
    at Object.<anonymous> (/Users/…/dist/js/client-bundle.js:75:5)
    at Object.<anonymous> (/Users/…/dist/js/client-bundle.js:88:31)
    at __webpack_require__ (/Users/…/dist/js/client-bundle.js:20:30)
    at /Users/…/dist/js/client-bundle.js:40:18
    at Object.<anonymous> (/Users/…/dist/js/client-bundle.js:43:10)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
```
とかいう感じで怒られた。

importやrequire等、読み込み方をかえてみたりしたけど全然読み込めない。

## 解決
調べてみたらwebpackにはelectronをtargetとするコンパイルにするってオプションが存在しててそれを書いたら行けた。

```
export default {
  output: {
    filename: 'client-bundle.js',
  },
// 省略
  target: 'electron', //　←これ
};
```
【FuelPHP】mysql接続でこけた話

#- 開発環境
OS: X EI Capitan 10.11.6
PHP: 5.5.36
FuelPHP: 1.7.3
MySQL: 5.7.16

結論としてはFuelPHPでMySQLを使うための設定に抜けがあったことが原因.
今回は、拡張モジュール mysqli を使用した.

#- 作業内容
localhostで開発をしていてDB接続するために,
fuel/app/config/development/db.php を下記でセット.

```php
return array(
   'default' => array(
      'connection'  => array(
         'hostname' => 'localhost',
         'port'     => '3306',
         'database' => 'test_db',
         'username' => ‘user',
         'password' => ‘xxxx',
      ),
        'profiling' => true,
   ),
);
```

次にfuel/app/config/db.php を下記でセット.

```php
return array(
    'default' => array(
        'type'        => 'mysqli',
        'connection'  => array(
            'persistent' => false,
        ),
        'identifier'   => '`',
        'table_prefix' => '',
        'charset'      => 'utf8',
        'collation'    => false,
        'enable_cache' => true,
        'profiling'    => false,
        'readonly'     => false,
    ),

);
```

DB設定はこれだけであとは DB保存するための Model を作って、
Controller でデータを save( ) してあげればイケると思ったけどエラーでた.
>Fuel\Core\PhpErrorException: mysqli::mysqli(): (HY000/2002): No such file or directory

この設定が必要だった.
fuel/core/classes/database/mysqli/connection.php

```php
// Extract the connection parameters, adding required variables
extract($this->_config['connection'] + array(
   'database'   => 'test_db',
   'hostname'   => 'localhost',
   'port'       => '3306',
   'socket'     => '/tmp/mysql.sock',
   'username'   => ‘user',
   'password'   => ‘xxxx',
   'persistent' => false,
   'compress'  => true,
));
```

これで無事解決！
オートスケール環境におけるFluentdのログ重複・欠損対策

この記事は  [Akatsuki Advent Calendar 2016](http://qiita.com/advent-calendar/2016/aktsk) の15日目です。


# はじめに

今やログ収集ソフトウェアのデファクトスタンダードとなったFluentdですが、オートスケール環境においては思わぬログの重複や欠損が発生する可能性があります。今回は私の所属するプロジェクトで行ったログ重複・欠損対策について紹介したいと思います。

# 前提

今回前提とするシステムは下図のような構成になっています。

<img width="991" alt="architecture" src="https://qiita-image-store.s3.amazonaws.com/0/135075/36ba0a50-2b10-da3f-d610-e1c9c7e61483.png">

ELB配下にオートスケーリンググループに属するEC2インスタンスのアプリサーバが複数台あり、各インスタンス上では Rails と Fluentd (sender) が動作しています。各アプリサーバから出力されたログは Fluentd (aggregator) により集約され、最終的に DB に保存されます。

Fluentd を利用したログ収集の構成としては一般的なものかと思います。
(バックエンドのDBは色々な選択肢がありますが...)

# Fluentdの基本的な動作と注意点

アプリサーバ上で動作しているFluentdはRailsから出力されたログをログアグリゲータに送信しますが、送信タイミングは即時ではありません。一時的にローカルファイルとして保存してから送信を行います(以降送信バッファと呼びます)。これは、アプリサーバやFluentdが落ちたり、ログアグリゲータと通信が不能になった場合であってもログ欠損を起こさないようにするための仕組みなのですが、この送信バッファの取り扱いに気をつけないと、スケールアウト時にログを重複して送ってしまったり、スケールイン時にログを欠損させてしまったりといった問題を起こすことがあります。

# スケールアウト時のログ重複送信対策

AWSのオートスケール機能は予め起動設定で指定したAMIからインスタンスを起動します。このとき、指定したAMIにFluentdの送信バッファが含まれているとログの重複送信が発生してしまいます。

## 送信バッファがAMIに含まれてしまう原因

AMIを作成する方法は多くありますが、この問題が起きるのは「稼働しているインスタンスからAMIを作成する場合」です。私の所属するプロジェクトではこの方法でAMIを作成しています。

(補足ですが、Chefによる Infrastructure as Code は実践しています。ただ、インフラ構築時間を短縮する等の理由により、稼働しているインスタンスからAMIを作成する運用をしているところは他にもあるのではないかと思います。)

## 既存インスタンスからAMIを作成する場合の送信バッファ対策

既存インスタンスからAMIを作成する場合の送信バッファによるログ重複送信を防ぐための方法としては以下の方法が考えられます。

1. ログアグリゲータへの送信が終わるのを待ってからAMIを作成する
2. 起動スクリプト(userdata)に送信バッファを削除する処理を入れる

1 の方法は、送信が終わる時間が読めないことや、ログアグリゲータが落ちていた場合はいつまでたってもAMI作成が開始できない可能性があるため、良い方法とは言い難いです。

2 の方法は、起動スクリプトへの変更が必要になりますが、ログの送信完了を待つ必要がなく、確実かつ即時AMIの作成を開始することができます。

今回は2の方法を採用することにしました。

## 起動スクリプトによる送信バッファ削除処理の詳細

まず、以下のステップでAMIを作成します。

1. AMIを取得するインスタンスをELBから外す
2. インスタンスにログインし、Fluentdを落とす
3. 起動スクリプトによる送信バッファ削除処理が完了するより先にFluentdが立ち上がってしまわないよう、chkconfigでFluentdの自動起動をOFFにする
4. AMIの作成を開始する
5. AMIの作成が完了したら、インスタンスにログインしFluentdを再度起動し、chkconfigの設定を復元する
6. インスタンスをELBに戻す

こうして作成したAMIをオートスケールの起動設定に登録し、起動スクリプトに送信バッファを削除する処理を追加することでスケールアウト時のログ重複送信を防ぐことができます。

(なお、上記処理はすべてスクリプトにより自動化しています。また、起動スクリプトは送信バッファの削除処理の他に、Fluentdの起動、chkconfigによる自動起動設定の復元等も併せて行う必要があります。)


# スケールイン時のログ欠損対策

もう一点。スケールイン時のログ欠損対策も必要です。

スケールイン時、送信バッファが残った状態でインスタンスが終了されてしまうとログ欠損につながります。
私の所属するプロジェクトでは５分待ってからインスタンスを終了するよう設定ししのいでいますが、 [Instance Lifecycle Hook](http://docs.aws.amazon.com/ja_jp/autoscaling/latest/userguide/lifecycle-hooks.html) を使えば、送信バッファが無くなったことを確認してからインスタンスが終了できるのではないかと考えています。
(まだ着手できていません...)

# 最後に

オートスケール環境におけるFluentdのログ重複・欠損対策、特に送信バッファの取り扱いについて紹介させていただきました。今回はFluentdが対象でしたが、これ以外にも遅延送信(処理)を行うソフトウェアには同様の注意が必要になると思われます。

ご参考になれば幸いです。
Spring MVCで繰り返し項目の値を受け取るForm

String[] でも受け取れるみたいだけど、lazyListで実装すればPHPっぽく扱えて便利じゃね？という。
※以下、commons-collectionsは3系を使用。4系だとインターフェースが変わっている（良くなっている）っぽい。

```java:SampleForm.java
public class SampleForm {
    private List<String> valueList = ListUtils.lazyList(new ArrayList(), new Factory() {
        public Object create() {
            return new String();
        }
    });

    public List<String> getValueList() {
        return valueList;
    }

    public void setValueList(List<String> valueList) {
        this.valueList = valueList;
    }
}
```

```jsp:sample.jsp
<form:input path="valueList[0]"/>
<form:input path="valueList[1]"/>
<form:input path="valueList[2]"/>
```
職業プログラマを25年以上続ける秘訣

どうも、うらかわです。今テレビでFIFA CLUB WORLD CUP 2016のMatch5(アトレティコ・ナシオナル対鹿島アントラーズ)を見ながらこれを書いてます。VAR(Video Assistant Referee)の判定で鹿島アントラーズのPKになるという場面がありました。歴史が変わる瞬間を見た思いです。ちなみにこの大会のメインスポンサーは Alibaba YunOS Auto です。覚えておきましょう。
それはそれとして、アドベントカレンダーに予定を入れたはいいが何書こうかなってな感じでしたが、今年はQiitaに怒られない程度にエモいことを書くことにしました。会社員プログラマを25年以上続けてきた自分の振り返り的なやつ。
状況は人それぞれだと思うので抽象的な感じにしておきます。

## お前誰よ？
1991年に高校を卒業してから、会社員プログラマとしていろいろやってきて、ドワンゴには2010年11月に入社しました。


# 「今動いている」ことが大事。動き続けるためには？
## 健康第一
続けるためには続けられる状態でいるのが前提です。最大の敵は、肉体そして精神の病です。死んでもやり遂げなければいけない仕事なんてものはそうそうありません。体の声に耳を傾けて、壊れる前に休みましょう。
若くて優秀なプログラマが病んで去っていくのを何人か見てきました。あなたは病まないでください。
でも若いうちにギリギリまでやって自分の限界を知るというのも後々役に立つことがあるかもしれません(ハイリスクローリターンなのでお勧めはしません)

## 完璧なクオリティの動かないコードよりクオリティの低い動くコード
プログラマがフィードバックを得てプログラムを改善していくサイクルを小さく早く回転させていくためには、クオリティはともかく「動くプログラム」が必要です。新しい、独自の、真に取り組むに値する問題に取り組んでいるならば完璧な設計で完璧なコードを一発で生成するというのは人間業ではないです。試行錯誤しましょう。

## 今何してる？進んでる？
仕事の話として、「今何してる？」という質問に答えられないようではいけません。コードを書くだけが仕事ではないのですが、どんな問題をどのように解決しているところなのかを把握し、伝えられるようにしましょう。
また、コードのコミット単位を小さくしたり、こまめにドキュメントを更新したりして、「少しずつでも進んでいる」ことを共有すると安心感マシマシ。

# 「プログラムを書くことは手段である」ことを忘れない
## 「ハンマーを持つ人には全て釘に見える」
自分が持っている技術にむりやり問題をあてはめて解決しようとしてしまうこと、ありませんか？必要な手段を適切に選ぶことも大事な技能です。
あとプログラマの仕事で言えば、昔の道具が役に立たなくなることが多いです。使える道具の手入れをしたり、道具を増やしたりするのは大事です。あんまりいろいろやり過ぎても収拾つかないですし、「みんなが使える」が重要なことも多いので選球眼大事。僕なんか最初の仕事で使った言語は68000のアセンブラですからね。忘れましたよそんなもんｗ 万が一必要になれば思い出しますけどね。

## 要件・仕様を作る人と喧嘩しない
プログラマの仕事はプログラムによって問題を解決することです。解決したい問題と向き合うために、問題を持ってきた人ときちんとコミュニケーションをとり、「本当の問題」を見つけ出す必要があります。そのために円滑なコミュニケーションを妨げる要素は可能な限り排除する必要があります。喧嘩している場合ではないです。
でもまあ、いろいろありますよね。

## 可能なら書かずに済ませる
既存のプログラムやツール、アナログな道具で解決することを、「自分が解決した」と言いたいためにプログラムを書こうとしてはいけません。「車輪の再発明」は学習目的以外では避けましょう。

# 向上心に折り合いをつける
## 頑張るけど無理しない
前述の「健康第一」につながりますが、病むまでは頑張らないの大事です。
直接的に効率を求めるより努力を楽しめる構造を作れると結果効率が高まったりします。

## 他人と比べない
自分の強みは他の人とは違ったりすることが多いです。いろんな人がいるからチームに幅ができます。プログラマ以外を含めて「みんなちがってみんないい」のです。自分の強みを磨きましょう。
他人の強みを自分のものにしようとするのは良いですが、前述通り無理はいけません。

## ルーティンを持つ
仕事に関するルーティンを取り入れることで、結果として作業効率が上がったり、集中力が増したり、やり忘れが減ったりします。出勤時と退勤時にメールチェックは必ずするとか。
僕の場合は提出をするでもない日報を書いています。割と細かめにどんな事をしたか、どんなことを考えたか、どんな資料を参照したかをメモしたり。時々見返したり、共有できｋるものはまとめて共有したり、たまーにQiitaに投稿したりなんかもできるので便利ですね。

# ダメな時もある
## ダメな時はどうする
ダメになった原因を取り除く必要があります。取り除けない場合は原因を遠ざけるという手もあります。比較的短絡的な手法で言うと上の立場なら組織変更をしたり、下なら会社辞めちゃったりという手があります。組織hackのために出世することを選ぶ人もいます。すごいよね。

## クビになるときだってある
会社が潰れたりリストラになったり開発チーム解散で全員解雇になったりとか、よくある話です。僕は全部経験しました(笑)
自分ではどうにもできないこともあります。それでも若ければどうにかなりますし、若くなくても今までやってきたことが身になっていればそれを役立てる機会はあります。それもまた経験として今後の糧としましょう。
こんな僕でもドワンゴは雇ってくれました(笑)

## 反省したらクヨクヨしない
自分が悪くてダメなこともあります。反省はしましょう。改善しましょう。技術が足りなければ積み上げていきましょう。しかし、過ぎたことにずっととらわれていたら精神が病みます。そうなるとパフォーマンスは落ちますし、最悪キャリアが終わってしまいます。

# まとめ
続けろ。死ぬな。人とは仲良くしろ。
UCP-45060 ライフサイクルの状態が無効です。ユニバーサル接続プールの状態を確認してください

ucp.jarを使おうとしてハマった件。
getConnectionの時点でUniversalConnectionPoolExceptionが発生して落ちてしまう。
例外のメッセージは以下。

> ライフサイクルの状態が無効です。ユニバーサル接続プールの状態を確認してください

デバッガで追ってみたりしたものの原因がさっぱり分からず、辛うじて分かったのはエラーコード45060のみ。
で、エラーコードをもとに調べてみたところ、以下の記事を発見。

> [JDBC: Oracle Universal Connection Pool Error UCP-45060 Invalid life cycle state](http://stackoverflow.com/questions/39720350/jdbc-oracle-universal-connection-pool-error-ucp-45060-invalid-life-cycle-state#comment67024790_39720350)
> This could be a bug in the UCP and JDBC version you're using.

…そういえば、OracleクライアントとJDBCのバージョンいくつだ？←

ここでまさかのOracle 10g（ojdbc14.jar）登場。
Oracle 11g（ojdbc6.jar）に切り替えたところ、正常に動作することが確認できた。
[MEMO] Raspberry pi 3 初期設定まとめ

## 最初に

```
$ sudo apt-get update
$ sudo apt-get upgrade
```

## リモート関連設定

Raspberry Piの設定から
システムタブで，パスワードとホスト名を変更する.（デフォルトパスワードは「raspberry」）
インターフェイスタブで，SSHやその他必要に応じてEnableにする．
リブートする．

```
$ sudo apt-get install tightvncserver
$ vncserver
# passward設定
$ sudo apt-get install xrdp
```

## terminalからユーザネームを消す

~/.bashrcの60行目を

```
PS1='${debian_chroot:+($debian_chroot)}S\[\033[01;34m\]\w\$\[\033[00m\] '
```

に変更．

## 日本語環境
メニュー→設定→raspberrypiの設定
から
ローカライゼーションタブで
ロケール・タイムゾーン・キーボード
を設定

```
$ sudo apt-get install ibus-mozc fonts-ipa*
```

IMUのアイコンを右クリック→設定
から
入力メソッドタブ
で
入力メソッドを「日本語 - Mozc」だけにする
（「英語」は消す）


## CapsLockのCtrl化
~/.config/lxkeymap.cfgを作って

```
[Global]
layout = jp
variant = 
option = ctrl:nocaps
```

を入れる．

```
$ lxkeymap -a
```

で確認できる．

~/.config/autostart/lxkeymap.desktopを作って，

```
[Desktop Entry]
Name=lxkeymap
Exec=lxkeymap -a
```

を入れる．再起動してもできるようになる．


## Node.jsを最新にする

```$ sudo apt-get install nodejs```だと，最新版が入ってくれない．

```
$ sudo npm cache clean
$ sudo npm install n -g
$ sudo n stable
```
とする．
（cf: http://qiita.com/setouchi/items/437e4b62e4210871496f）
Wordpress4.6マルチサイトでネットワークの更新をしそびれた顛末

#Wordpress4.7に上げたとたん、管理画面から参加サイトが一切消えてしまった
各々のマルチサイト自体は存在しているのだけど、いつものように左上のプルダウンから参加サイトが一切消えてしまった。

#わかったこと
参加サイトの取得は wp-includes/user.php のget_blogs_of_userという関数が担っている。
ひとつづつデバッグして調べたところ、656行目でget_sitesを実行すると結果が一切かえってこなくなったことがわかった。

get_sitesは、640行目で現状存在するblog_idを配列site_idsに収め、650行目あたりの条件を加えて、$wpdb->blogを読み出していた。

650行目あたり

		if ( ! $all ) {
			$args['archived'] = 0;
			$args['spam']     = 0;
			$args['deleted']  = 0;
		}

どうやらこの条件が引っかかっていた。
しかし、DB見てもarchived,spam,deletedはどのサイトも0が表示されていたのでしばらく悩んだあと、phpmyadminで見るとarchivedだけ数字が左寄せに表示されていた。ここで、データ型が合っていないことにやっと気づいた。

#対処
$wpdb->blogに相当するテーブルのarchivedのデータ型がenum('0', '1')になっていた。
Wordpress4.7マルチサイトで問題なく動作しているDBを見るとarchivedのデータ型はtinyintだった。
それにならって、tinyint(2)NOT NULL DEFAULT '0'に変更したところ、通常通り参加サイト一覧が表示されるようになった。

#原因の考察
4.6にあげたときにネットワークの更新をしそびれたからだと考えられる。つくづく反省。。。
【Python】tqdmを使ったプログレスバーによる進捗表示

インストーラ・ファイルダウンローダなど、何かしら反復処理の進捗状況を可視化したいときに、プログレスバーを手軽に実装できたら便利です。

僕も反復処理における進捗状況をもう少しマシな感じに表示したいなぁと思っていたところ、
[tqdm](https://github.com/noamraph/tqdm)というライブラリがあり、実際に使ってみたところとてもシンプルに実装を行うことができました。

### 使い方

```python
import time
import tqdm

# 反復処理と同時にプログレスバーを標準出力
for _ in tqdm.tqdm(xrange(10)):
    time.sleep(1)
```
使い方は、```tqdm.tqdm```関数にiteratorを渡すだけです。
返戻されたiteratorオブジェクトを反復させるたびに、標準出力に進捗状況が表示されます。

### 結果

```
 0%|          | 0/10 [00:00<?, ?it/s]
10%|█         | 1/10 [00:10<01:30, 10.00s/it]
20%|██        | 2/10 [00:20<01:20, 10.00s/it]
30%|███       | 3/10 [00:30<01:10, 10.00s/it]
40%|████      | 4/10 [00:40<01:00, 10.00s/it]
50%|█████     | 5/10 [00:50<00:50, 10.00s/it]
60%|██████    | 6/10 [01:00<00:40, 10.00s/it]
70%|███████   | 7/10 [01:10<00:30, 10.00s/it]
80%|████████  | 8/10 [01:20<00:20, 10.00s/it]
90%|█████████ | 9/10 [01:30<00:10, 10.00s/it]
100%|██████████| 10/10 [01:40<00:00, 10.00s/it]
```
これでプログレスバー実装完了です。非常に簡単ですね。

なお、上の結果では一巡ごとの進捗表示を全て表示していますが、実際は次の表示が前の表示を上書きする形で表示されます。
コンソールで動くエディタを作る(15日目) v0.0.1完成！

本稿は[自作エディタをつくる Advent Calendar 2016](http://qiita.com/advent-calendar/2016/make_editor)の15日目です、レポジトリは[こちら](https://github.com/tinyco/tiny_code_editor)

# ver0.0.1をつくるぞ！

単体テスト・ncurses対応・制御文字と文字コード対応・カーソルの仕様の微妙さ・・・。

やりたいことは色々ありますが、ロマンのひとつである「自作エディタを使ってエディタを作る」ところを今日は目指します。

それができたら、とりあえずはver0.0.1ということにします(๑•̀ㅁ•́๑)✧


# ファイルを上書き保存する

キーバインドは悩んでますが(13日目参考)、とりあえず`Ctrl + S (0x13)`を上書き保存にします。

いつも通り、まずは内部DSLの構造体の定義から作っていきます。

ここもenumとはいえ混沌の気配が生まれつつあります。十字キーが予想よりやっかいなやつでしたね。

いったん目をそらしながら内部DSLを継ぎ足して、2日目のファイル読み込み部分を参考に書き込みも作っていきます。

読むときはマルチバイト文字に苦しみましたが、書くときは文字コードを気にせず1バイトずつ書いていけばいいので楽です。

```write.c
while(current_text)
{
  current_line = current_text->line;
  while(current_line)
  {
    i = 0;
    while(i < current_line->byte_count)
    {
      fputc(current_line->string[i], fp);
      i++;
    }
    current_line = current_line->next;
  }
  current_text = current_text->next;
}
```

なんか、あっさり書き込めました！

# 本文を、真面目に表示する

いままで、エディタとかカッコつけたことをいっても多機能なprintfでしかなかったので、
画面に収まらない、テキストが長いファイルを開くと困ってしまいます。
そこで、カーソルを中心に画面に収まるように本文を表示するようにします。
ヘッダー部分(画面上部)にファイル名を表示しているのですが、
本文をどこまで書いたかわかりやすいように、画面の下部にもヘッダーと同じものを出すようにながら進めました。
フッターと呼ぶことにします。

カーソルが画面下端から飛び出ると表示開始行を足していき、上端から出た場合は表示開始行を減らすようにしました。

なんか画面がチラつくのですが、いちおう表示できるようになりました。

文字列の幅とかを結構な頻度で再計算するのでチラつくのかもしれません。

# せっかくなので、フッターになにか表示する

試しに`getcwd`をつかってファイルパスを表示してみました。

なんとなくそれっぽい感じがします

# 空行でもカーソルを表示する

ちょっとアドホックな修正ですが、カーソル位置が空行の時はカーソル色付きの空白文字をprintすることで
カーソルを空行でも表示できるようにしました。

# linuxでビルドしてみる

なんとなく、AWSのLinux上でビルドしてみました。
`‘for’ loop initial declarations are only allowed in C99 mode`
どうやら`for(int i = 0; i < bytes; i++)`があるとgccではコンパイルがすんなり通らないようです。
そのあと動かしてみましたが、ssh上では普通に動きました。
ビルドとコンソールはLinuxですが、端末エミュレータはMacだからかもしれません(たぶん)

# readmeをちょっぴり親切にする

まだ使う人がいないと思いますが、いちおうビルド方法を書いておきます。

# ver0.0.1完成！

これで、自作エディタを使ってエディタを作れますね٩(๑❛ᴗ❛๑)۶

なんとなくgithub issueをonにして、git tagを打ちました。
25日までに出来そうなことをまとめたいです。


# 今日のまとめ

- ファイルの上書き保存
- 本文の表示
- ver0.0.1できたよー！

正直なところ、このあたりの完成度で25日目を迎えるような気がしていました。

けっこう動いてて感動がありますね！画面がチラつくけど、それはそれ！

![b7b54fbb2b131d8acfcb4112a4be0562.gif](https://qiita-image-store.s3.amazonaws.com/0/151926/2c8cbf07-aed4-8bb7-2aae-53c6420d9eb7.gif)
bashに !' で event no found と怒られた理由を考えてみる

先日の遭遇した下のエラーについて調べてみた。

```bash
$ ruby -e "puts 'Hello, World!'"
bash: !': event no found
```

# 「!」とは？

>!に続く文字列に一致する最新のコマンドの再実行。
[Bashでエクスクラメーションマークで始まるコマンドはどういう意味でしょうか... - Yahoo!知恵袋](http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q13147860248)

>Bashにはヒストリ展開という機能がある。
この機能によって、コマンド中の!fooのような文字列は、実行したことのあるfooから始まるコマンドの中で最も最近のものに置き換えられる。
[[Bash] ダブルクォートで囲んだコマンド置換中で!を使うとエラーになる（例: echo "$(echo '!')"） - Qiita](http://qiita.com/anqooqie/items/785f46a8cc5f10ba7abb)

直近のコマンドを再実行されることが分かったので、ちょっと試してみる。

```
$ 'uname'
Linux
$ "arch"
x86_64
```
このコマンドを「!」で再実行

```
$ !'
'uname'
Linux
$ !"
"arch"
x86_64
```
なるほど

# ということで

```bash
$ ruby -e "puts 'Hello, World!'"
bash: !': event no found
```

この原因はこのコマンド以前に「'」から始まるコマンドを実行していないから、エラーが発生したことを理解。

では、「'」から始まるコマンドがあった場合、どう処理されるのか？

```bash
$ 'uname'
Linux
$ ruby -e "puts 'Hello, World!'"
ruby -e "puts 'Hello, World'uname'"
-e:1: syntax error, unexpected tIDENTIFIER, expecting end-of-input
puts 'Hello, World'uname'
                        ^
```

`'uname'` が展開されて実行。そして、構文エラー

ちなみに、履歴を辿ると構文エラーのコマンドで残っている。(当然か)

```bash
$ ruby -e "puts 'Hello, World'uname'"
```

ただ、

```bash
$ ruby -e 'puts "Hello, World!"'
Hello, World!
```
こっちのパターン(`!"`)で、展開されない理由が良く分からない…。
`''` に囲まれていることによってエスケープされた？

# おまけ
```bash
$ 'uname'
Linux
$ echo '!'
!
$ echo '"!"'
"!"
$ echo "'!'"
echo "''uname'"
''uname'
```

最後のコマンドの展開
`"` `'` `!'` `"`
　　　↓
`"` `'` `'uname'` `"`
SSHポートフォワーディングを知った話

### はじめに
新しいわけでも使うのが難しいわけでもないですが、単純に知らなかったので共有。。

### ポートフォワーディングとは
複数のサーバーの管理をする時に使える技術。

AとBというサーバーを接続したいが、セキュリティやネットワークの問題で、直接接続できない時に使う。
AとBの間にCというサーバーを置き、Cを経由して間接的に接続できる。


### どう使うのか？

- ローカルのポートをリモート先に転送したい時

例えば、自分のPCから、ネットワークの都合上、直接接続できないAというwebサーバにBというサーバを経由して接続するとき

```sh
ssh hostB -L 8080:hostA:80 -N
```
-LオプションはLocalのことを表します。
-Nオプションはリモートのコマンドを実行せずに待機状態にするためのもの。ポートフォワーディングをする時によく使われます。

- リモート側のポートをローカルに転送したい時

例えば、Cという外部のネットワークにあるサーバーの1010というホストから、ローカルを経由してhostDに接続するとき

```sh
ssh hostC -R 1010:hostD:22 -N
```
-RオプションはRemoteのことを表す。


- 実際にやってたことは

実際にはネットワーク1にあるwebサーバからネットワーク1にあるtestサーバーを経由して、ネットワーク2にあるDBに接続する、
みたいなことをやっていて、調べるきっかけになりました。

なので、以下のような内容をwebサーバーからやっていたんだとわかりました。
(testサーバーのhostをTEST、DBサーバーのhostをDBとすると)

```sh
ssh -L TEST 3000:DB:3306 -N
```
※3000っていうのは適当、3306はmysqlのデフォルトのポート


### セキュリティ的に大丈夫？と疑問になった
セキュリティ的にOKなのって思いましたが、心配は無用でした。

上記の場合ですと、testサーバーの自分自身が3000ポートに対して行う通信だけが、DBサーバーに転送されるようになっています。
つまり、testサーバーから操作をしないと受け付けないわけで、testサーバーを経由したら転送されるというわけではないようです。
そして、これをローカル通信と呼ぶそうです。

とはいえ、データの受け渡しの間(testサーバーからDBサーバーの間)はセキュアではないので、大事な内容のものはなるべくやらないほうが良さそう。やるにしても期間限定。

### その他のオプション
その他、sshの様々なオプションを組み合わせて接続することが多いので、この際によく使いそうなものは覚えておこうと思います。

-i ： 秘密鍵の指定をします。
-C : 圧縮して転送します。データが大きいものとかは圧縮したほうが通信がはやそう。
-f : バックグラウンドで実行させます。


### 実際にサーバーに設定を保存しておくには？
一時的にコマンド打つなら上記のような感じで問題ないのですが、長いコマンド打つの面倒ですし、覚えてないよっていう場合は~/.ssh/configの中とかに書いておけばいいようです。
例えばこんな感じ

```
Host [中継させるサーバーのIPアドレス]
LocalForward [転送先のポート] [転送先のIPアドレス]
```

### 最後に
身近にsshコマンドは使っていましたが、恥ずかしながらこういうことができるのを全然知らなかったので、勉強になりました。
何度も頻繁に使うものではないですが、たまに使えるし、知らないと使えないので、きちんと覚えておこうと思います。

参考にした記事
[SSHポートフォワード（トンネリング）を使って、遠隔地からLAN内のコンピュータにログインする](http://www.clear-code.com/blog/2014/9/12.html)
[SSHによるポートフォワーディング](http://blue-red.ddo.jp/~ao/wiki/wiki.cgi?page=SSH%A4%CB%A4%E8%A4%EB%A5%DD%A1%BC%A5%C8%A5%D5%A5%A9%A5%EF%A1%BC%A5%C7%A5%A3%A5%F3%A5%B0)
ETロボコンで使われている倒立振子APIについて

本記事はETロボコン[Advent Calendar 2016](http://qiita.com/advent-calendar/2016/etrobo)のエントリです。
自分は2008年からETロボコンに関わっています。初年度は業務多忙でメンバーリストに名前が載っていただけでしたが、2009年から本格参戦をしました。
2009年はETロボコンに2輪倒立走行体NXTwayがデビューした年になります。
以来、結果的に2輪倒立走行体一筋で毎年開発を行っています。(2012年以降はダミーカー)
![131120_0920_IMAG1451.jpg](https://qiita-image-store.s3.amazonaws.com/0/123504/e89cb63d-ebe0-18a0-325f-d5b3b0b4b06a.jpeg)

#ETロボコンで使われている倒立振子APIの歴史
古くはMindstorms RCXの光センサーを用いて地面との距離を測ることで2輪倒立を実現させるなどさまざまな試みがなされてきましたが、ETロボコンでは[NXTway-GS 2輪型倒立振子ロボット C API] (http://lejos-osek.sourceforge.net/jp/nxtway_gs.htm)を使用しています。

- 2009年 NXTwayデビュー [ナロウトレッド](https://www.youtube.com/watch?v=v1p5NCEiKKQ)
- 2010年 [ワイドトレッド化](https://www.youtube.com/watch?v=kbE6Q3KNXVQ)　木板を使用した難所登場　板厚**14mm**
この年からワイドトレッド化に合わせて旋回角度係数が変更されています。
`float K_PHIDOT = 25.0F*`**2.5F**`;`

- 2011年 [尻尾追加](https://www.youtube.com/watch?v=yR-zLM2Hh-I) 2016年も使用されている倒立走行体の形が完成
倒立APIを使用しない尻尾走行が誕生　競技上位チームは倒立走行を行わなくなりました。
- 2012年 [尻尾走行全盛](https://www.youtube.com/watch?v=REX-5si7IiM)
- 2013年 倒立義務化　タイム計測区間の尻尾走行が禁止されました。
- 2014年 アドバンストクラスがスタートし、NXTwayはプライマリークラス用走行体となりました。 
- 2015年 [EV3way](https://www.youtube.com/watch?v=Fg_LZ0F9sQA)デビュー
EV3wayに合わせて**車輪平均回転角速度係数**が変更されています。
`float K_F[4] = {-0.870303F, -31.9978F, -1.1566F*`**0.6**`, -2.78873F};`
- 2016年 木板難所の板厚が**9mm**に変更されました。

ここまで走行体の形状変更、NXTからEV3への変更などハードの大きな変更を経ていますが、パラメーターに係数を掛けるだけで済ませています。
# 倒立が不安定になったら
開発を進めていくと倒立が安定しなくなったりすることがありますが、電池の出力低下や処理の増加により倒立振子APIを実行する間隔4[msec]を維持できなくなることが原因であることが多いです。まずはサンプルプログラムに戻して挙動を確認してください。処理時間の問題はリアルタイムOSの機能を活用することによりある程度改善する手段があります。そもそもの設計に問題がある場合はモデルの再検討を行ってください。
# バランス制御実行周期が5[msec]になっている！？
サンプルプログラム`balancer.h`で実行周期が5[msec]に設定されてしまっています。
`#define EXEC_PERIOD                    0.00500000000F            /* バランス制御実行周期(秒) *//* forEV3 20141102koji */`
これはEV3wayで倒立が実現できるのか？とあれもこれもいじりながら試行錯誤していた頃の痕跡が残ってしまっています。戻すのを忘れてファイルを展開してしまいました。
よく質問に出てくる内容で大変申し訳ないのですが、上で紹介した**車輪平均回転角速度係数**の調整がこの状態で行われおりサンプルプログラムの多言語展開までされていますので、このままでご利用いただければ幸いです。
js 一番文字の多い単語を見つける

##配列の中から一番文字数の大きい単語をみつけてその数を返す

```script.js
function findLongestWord(s) {
 //write your code.
}
findLongestWord("The quick brown fox jumped over the lazy dog");
```

出力結果　例

```script.js
("May the force be with you")// 5
("Google do a barrel roll") //6
("What is the average airspeed velocity of an unladen swallow")// 8
("What if we try a super-long word such as otorhinolaryngology")//19
```

一番最初に試したコード

```script.js
function findLongestWord(s) {
  var i = s.split(' ');
  var b = i[0];
  for( var a = 0; a < i.length; a++){
    if( b.length<i[a].length){
      b = i[a];
    }
  }
  return b.length;
}
findLongestWord("The quick brown fox jumped over the lazy dog");
```

##教えていただいたコード

```script.js
function findLongestWord(str) {
  var longestWord = str.split(' ').sort(function(a, b) { return b.length - a.length; });
  return longestWord[0].length;
}
```

##考え方
str.split(' ')で単語に切り分ける。
.sort(function(a,b){ return b.length - a.length; }
で配列に文字数の多い単語順にならべかえる。
{ return a.length - b.length; }にすると少ない順になる。
並べ替えた単語の添字0を返り値にすると一番文字の多い単語の数値を取得できる。

別のコードを思いついた方、コメントお待ちしてます。

##参考リンク
[.sort()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)
electron-oauth-twitterでElectronでのTwitter OAuth認証を手軽に行う

## はじめに

※翌日の人とネタ被りしてしまったので、後日また別の記事を上げる予定です。

この記事は[Electronアドベントカレンダー](http://qiita.com/advent-calendar/2016/electron)14日目の記事です。遅刻してしまってすみません＞＜

現在開発中のElectronアプリ内で使っているNPMモジュールについて、まとめられたのでこれを14日目の記事とします。

ElectronでTwitterに投稿するタイプのアプリケーションを作る際、どうしてもOAuth認証の複雑さがネックになってきます。
認証後のコールバックURLの問題や、コールバックURLを指定しない場合はPINコードでの入力になる点などによって、どうしても複雑な処理になりがちです。

そこの欠点を解決してくれるelectron-oauth-twitterというパッケージになります。

## electron-oauth-twitter

このパッケージは、Electronのプラグインとなり、たった数行のコードで、煩雑なTwitterのOAuth処理を全て行ってくれるものとなります。

Electronのウィンドウシステムを利用しているため、Electronに依存する形となりますが、その中では非常に重宝するのでご紹介いたします。

[uraway/electron-oauth-twitter](https://github.com/uraway/electron-oauth-twitter)

### 導入

npm経由で使用します。

```bash:terminal
$ npm i -S electron-oauth-twitter
```

### 事前準備

![スクリーンショット 2016-12-15 0.23.44.png](https://qiita-image-store.s3.amazonaws.com/0/75633/c83c7856-3074-dafe-9026-58bc087b4e67.png)

dev.twitter.comにアクセスし、My appsから新しくアプリケーションを登録し、コンシューマーキーおよびシークレットキーを取得しておきます。

### 利用方法

以下のように利用します。
なお、このコードはメインプロセス(非Chromium上)にて実行もしくは、Electronの[remote](https://github.com/electron/electron/blob/master/docs/api/remote.md)モジュールを経由して利用します。


```js:oauth.js
const dialog = require('electron').dialog;

const OauthTwitter = require('electron-oauth-twitter');

const twitter = new OauthTwitter({
  key   : "YOUR_TWITTER_KEY",
  secret: "YOUR_TWITTER_SECRET",
});

twitter.startRequest()
.then((result) => {
 dialog.showErrorBox('Status', 'Token: ' + result.oauth_access_token + '\nSecret: ' + result.oauth_access_token_secret);
}).catch((error) => {
  console.error(error, error.stack);
});
```

実際実行すると、以下のように、TwitterのOAuth認証の画面が表示されます。

![スクリーンショット 2016-12-14 23.12.32.png](https://qiita-image-store.s3.amazonaws.com/0/75633/499e2a0e-0d51-77cc-0f9f-6211c0586c94.png)

いつものアカウント情報を入力し、ログインをすると、Electron側のモーダルが表示され、無事認証が完了となりました。
あとは、これをlocalStorageに入れるなどして永続化することで利用が可能となります。

### 実際にツイートするには

electron-oauth-twitterには、OAuth以外の機能はありませんので、別途twitterモジュールなどを利用してツイートなどの操作を行う必要があります。

[desmondmorris/node-twitter](https://github.com/desmondmorris/node-twitter)

## おわりに

electron-oauth-twitterを利用することで、非常に簡単にElectronアプリケーション内にTwitterのOAuth認証を埋め込むことができました。

既にあるWebサービスなどのクライアントでは自分のサービス内の認証があるため不要かもしれませんが、Twitterクライアントなど、Twitterに密接に紐づくツールの作成では非常に重宝するため、利用してみると良いかもしれません。

最後になりますが、Electron製のスクリーンキャプチャツールを現在開発中です。Retina環境のMacにも対応し、高画質の画像を2ステップでTwitterに投稿できる、いわばTwitter版のGyazoのようなものを開発しておりますので、完成した暁には、また内部の構造などをQiitaに書きたいと思います。
AWS Lambdaのデバッグ方法

## 概要
AWS Lambdaのデバッグ方法をまとめる。
※この記事ではNode.jsの利用を想定。

## コード上でログを出力する（基本）

以下のメソッドが利用出来る。

- console.log()
- console.error()
- console.warn()
- console.info()

出力されたログはLambdaコンソールの[Log output]に出力される。

```js:ログ出力基本
console.log("🐱");
```

🐱が出ている事が確認出来るかと思う↓

<img width="669" alt="log1.png" src="https://qiita-image-store.s3.amazonaws.com/0/71899/69c0a802-1ce4-379b-ebc3-61501615216d.png">

このあたりは[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/nodejs-prog-model-logging.html)にも記載されている基本的な内容。

## 出力したログをCloudWatchで確認する

LambdaはCloudWatchにもログを書き込むようになっている。
console.logで出力したログはCloudWatchでも確認出来る。

CloudWatchの管理画面から、ログ → /aws/lambda/{lambda関数名}/{ログストリーム} とページ遷移していくとログが確認出来る。

/aws/lambda/{lambda関数名}という部分がCloudWatchのロググループ名となる。
私の場合「customAuthorize」という名前の関数を定義していたので、ロググループ名は「/aws/lambda/customAuthorize」となる。

ログストリームに関しては見た感じLambda関数の実行毎に作られるようだった。

ちなみに、この2つはLambdaのcontextオブジェクトの中に情報があるので以下のコードで取得出来る。

```js:ロググループとログストリームの確認
// ロググループ名
console.log(context.logGroupName);
// ログストリーム名
console.log(context.logStreamName);
```

それぞれ下記のように出力されていたので、ログ → /aws/lambda//aws/lambda/customAuthorize/2016/12/14/[$LATEST]26b5469427e449349dbda15096c88e0b にアクセスすれば該当リクエストのログを確認出来る。

- console.log(context.logGroupName)
    - /aws/lambda/customAuthorize
- console.log(context.logStreamName)
    - 2016/12/14/[$LATEST]26b5469427e449349dbda15096c88e0b

<img width="991" alt="log3.png" src="https://qiita-image-store.s3.amazonaws.com/0/71899/35b2c192-6e94-a860-5e8d-2c5452e3ddd4.png">

## 何度実行してもCloudWatchにログが出力されない場合

[公式のトラブルシューティング](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/monitoring-functions.html)にも記載されているが、Lambda関数の実行ロールでログデータをCloudWatch Logsに書き込むアクセス権限が付与されていない可能性がある。

※少なくもとポリシーが以下のように設定されている必要がある。

```json:ポリシードキュメント
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    }
  ]
}
```

## おまけ（オブジェクトの中身の詳細を表示する）

エラー発生時のerrorオブジェクトの中身を詳細に見たい時はutil.inspect()を利用する。
※これはLambdaの話というよりは、Node.jsの話。

```js:utilのロード
const util = require('util');
```

```js:util.inspect()利用
console.log("🐱" + util.inspect(error, false, null));
```

上記のようにログ出力するとCloudWatchのログ上に詳細な"error"の中身が表示される。

<img width="985" alt="log4.png" src="https://qiita-image-store.s3.amazonaws.com/0/71899/68b5cc1a-bd44-f08a-c2e3-8dee2d35c731.png">
Twitter Streaming APIを使った【夢】のクローリング

# はじめに

Twitter Streaming APIを使って人間の夢をクローリングをしました。

朝起きてからすることと言ったらTwitterです。
ある朝、フォロワーさんがとても面白い夢の内容をツイートしており、正直ニヤけました。
それを見て「人の夢ってユニークだよなあ」と思い、ピンときてクローリングにいたったものです。

# 作ったもの

バクくん - Twitter Bot
https://twitter.com/yumewomita_baku

# コード

全てのコードは[こちら](https://github.com/yuta17/yumewomita_baku)

# 説明

夢の内容を持ってくる方法として、夢ツイートは大抵文章の終わりに「夢を見た」か「夢を見ました」を書くため、それらをキーワードにそれ以前の文章を取ってくるようにします。
これには[Twitter Straming APIのtrack](http://www.rubydoc.info/gems/tweetstream/TweetStream/Client#track-instance_method)メソッドを用いています。

スクレイピングをしていると、取ってきた情報の中に不要なキーワードや記号を含んでいる場合があります。
そこで、あらかじめそれらをストップワードとして決めておき、省く方法を取りました。

今回の場合だと、とある歌詞Botが「夢を見た」などとつぶやき散らかしていたため、名前かスクリーンネームに「Bot」を含まないツイートを取るようにしています。

後は取得したツイートの空白・改行、リプライの宛名等を消した後、ツイートします。

# しかし...

Botを実際に見てみると、動いてはいるものの１つ問題点があります。
それは「夢を見た」のキーワードの前に空白がないと、該当するツイートを取得してこないことです。

推測するに、デフォルトでは英語での利用を想定して作られたため、trackメソッドでは取得の際にキーワードの前後に空白があることの判定をしているのかと思います。

[該当のコード](https://github.com/tweetstream/tweetstream/blob/master/lib/tweetstream/client.rb#L104)

前後に空白がないようなおもしろ夢ツイートを持ってくるようにしたいので、なんとかできないかなと思っています。(強い人助けて下さい)

# おわりに

ツイッター上にはまだメディアが取り上げていないような有益なコンテンツが眠っている。
と偉い人が言っていました。

ピンときたらツイッターのクローリングをしていきましょう。
IMEを使う（iOS編）

# はじめに
これまでは主にデスクトップ向けのIMEを扱ってきましたが、本日はモバイル向けのOSであるiOSのIME APIについてです。
（UWPは例外的にモバイルも含むプラットフォームでしたが）

モバイルでも日本語入力という枷からは逃れることはできないので、iOSにもIME APIが用意されています。
とはいえ、サードパーティのIME自体は比較的最近（iOS 8）までは存在しませんでしたね。

# UITextInput
iOSのIME APIの中心となるのが`UITextInput`なのは間違い無いのですが、その実装はひどく面倒なものになっています。
[`UITextInput`](https://developer.apple.com/reference/uikit/uitextinput)は[`UIKeyInput`](https://developer.apple.com/reference/uikit/uikeyinput)を、[`UIKeyInput`](https://developer.apple.com/reference/uikit/uikeyinput)は[`UITextInputTraits`](https://developer.apple.com/reference/uikit/uitextinputtraits)を、[`UITextInputTraits`](https://developer.apple.com/reference/uikit/uitextinputtraits)は[`NSObjectProtocol`](https://developer.apple.com/reference/objectivec/nsobjectprotocol)を継承しています。

1. `UIView`, `UITextInput`を継承したViewを作る
    - `becomeFirstResponder()`
    - `canBecomeFirstResponder: Bool = true`
2. **基本実装**: [macOS編](http://qiita.com/496_/items/4ad166f4104d0bb24e80)の`NSTextInputClient`と同様の実装をこちらでも行う
3. `UITextPosition`を継承したテキストの位置を保持するクラスを作る
4. `TextRange`を継承したテキストの範囲を保持するクラスを作る
5. 3.と4.で作ったクラスのインスタンス同士の比較関数を作る
    - `UITextPosition`同士を比較したり、`UITextPosition`が`TextRange`に含まれるかを返したりする関数
    - （この辺はWindowsのIAnchorに近いものがある）
6. 音声入力周りの実装がある
    - 音声入力中のPlaceholderを作って返す
    - Placeholderのディスプレイ上の位置を返す
    - 不要になったPlaceholderを削除する
    - 結果を挿入する

# おわりに
iOSのIME APIは基本実装自体はmacOSとほとんど変わらないのですが、とにかく周辺実装がたくさん増えてて大変という感じです。
一番大変そうなのが`var tokenizer: UITextInputTokenizer`の実装ですね。
テキストの切れ目などをいい感じに返すやつです。
（多分サードパーティのキーボードとかで文節単位で移動できたりするのはここを叩いてるのかな）

## 縦書きに関するメモ
縦書きに関連するのは`func selectionRects(for range: UITextRange) -> [Any]`で返す`UITextSelectionRect`に`isVertical: Bool`がある程度です。
来年にはiOS版のTATEditorも作るので、そのときに何かわかるかなあと祈ってます。
（標準のキーボードだと活用されてなさそうな気が……？）
[tmux] ターミナルの画面サイズが変更された際に stty で再設定

# 背景
tmux はとっても便利な端末多重化ソフトですが、ひとつのウィンドウ内に複数のペインを追加したり削除したり、ペインサイズを変更したり等していると正確な画面サイズが反映されない場合があります。（Teraterm で ssh ログイン後 tmux を起動し、更に別のサーバへ ssh ログインを行っている場合等）

正確な画面サイズが各ペインに反映されていないと、vim 等でファイルを編集しようとした際に画面が崩れて表示されてしまいとっても困ってしまいます(´・ω・`)。

# 対策
そんな時のためにあらかじめ `.tmux.conf` に以下のような設定をしておき、正確な画面サイズを簡単に反映できるようにします。

## 現在選択しているペインのみ再設定する場合

```conf:.tmux.conf
bind R run-shell "tmux send-keys -t #{session_name}:#{window_index}.#{pane_index} \"stty rows #{pane_height}; stty columns #{pane_width}\" C-m"
```

これで「prefixキ-」-> R で

```bash
$ stty rows 26; stty columns 228
$ 
```

と、現在のペインに自動入力され、正確な画面サイズが反映されます。

## 他のウィンドウも含む全てのペインに再設定する場合

```conf:.tmux.conf
bind C-r run-shell "echo #{session_name} | ~/bin/tmux-stty.sh"
```

更に以下のシェルスクリプトを用意します。

- **~/bin/tmux-stty.sh**

```bash
#!/bin/bash

read var_session_name
while read var_target_pane var_pane_height var_pane_width; do
  tmux send-keys -t ${var_target_pane} "stty rows ${var_pane_height}; stty columns ${var_pane_width}" C-m
done < <(
 tmux lsw -F '#{session_name}:#{window_index}' -t ${var_session_name} | \
 xargs -I% tmux lsp -F '#{session_name}:#{window_index}.#{pane_index} #{pane_height} #{pane_width}' -t %
)
```

これで「prefixキ-」-> C-r で

```bash
$ stty rows 26; stty columns 228
$ 
```

と、全てのペインに自動入力され、正確な画面サイズが反映されます。
CakePHP2: queryでプレースホルダ

LIKEを使う場合にプレースホルダが効かずに悩んでいました：

ダメな例1：

```ng1.php
$sql = "SELECT * FROM shops WHERE name LIKE '%?%'";
$results = $this->query($sql, array('原宿') );
```

ダメな例2：

```ng2.php
$sql = "SELECT * FROM shops WHERE name LIKE %?%";
$results = $this->query($sql, array('原宿') );
```

正しい書き方：

```ok.php
$sql = "SELECT * FROM shops WHERE name LIKE ?";
$results = $this->query($sql, array('原宿') );
```
Tools to implement DevOps in your organization

We have seen a trend. Many organizations talk about best practices but fail to practice them properly. DevOps is one such thing that is getting more attention, but we see a lot of negligence in adopting it properly. To embrace DevOps, you need to make sure, your engineers have that knowledge and capability with a set of tools to foster this change in the organization.

You need to have processes that support DevOps to streamline shipping of software and they should be:

Integrated. You need to have a unified platform with one view across deployment pipelines for all applications

Heterogenous. You need a polyglot that supports all languages, tools, and clouds.

Secure. You need to have policy-driven permissions enabled and have end-to-end audit tracking of who is doing what.

Let’s go in depth, what else you need to make your DevOps the real deal?

You need a version control system and a code repository tool that helps developers make changes easily and collaborate well. You should use tools such as GitHub and Bitbucket.

You need a Continuous Integration platform/tool to make integrations faster whenever any developer commits code. It consists of a workflow that helps software teams ensure that their changes are built and tested with the latest version of the entire codebase.

You can use tools such as Shippable, Codeship, Travis CI, GO CD, and XebiaLabs.

You need a cloud computing platform to help do Continuous Integration and Continuous Deployment. AWS is an amazing platform that you can make use of.

You need a containerized platform to package and ship programs. This helps developers run their apps and test in isolated environments with different OS which are very light in weight.

Docker (https://www.docker.com) is the platform for you to use here

You need to have a Continuous Deployment platform that integrates teams and processes to streamline shipping of software.

Tools you can use include Shippable (https://app.shippable.com) and GO CD (https://www.go.cd).

You also need to have some third-party integration tools to notify you the status of the project or anything. Slack (https://slack.com) will help with notifications.

Making DevOps real in any organization requires patience, enthusiasm to change, accepting the change, and putting in place a set of practices and tools that make it possible.