OmniAICreator/Qiita-1.07M huggingface dataset:
Android NDK + CMake で C/C++ 11 コンソールプログラムを Android 実機で実行する

漢なら, Android でも Gradle や実機上の Java モジュールに依存せずにコンソール C/C++ アプリを実機でユニットテストし, Linux での CMake で C/C++ 開発と同じような開発スキーム確立したいですね!

やりましょう!
 
## 背景

普段 IDE は使わず, macOS or Linux でターミナル(vim, cmake)で C/C++ 開発をしているので, Android 向けも同様な環境で開発できるようにしたい. 

Gradle を使わず, Makefile or Ninja だけでビルドできるようにしたい

Java レイヤーをエントリポイントとしても良いが, Java 部分を書くのがめんどい.

Android は ARMv8(64bit)が主流であるし, NEON 命令を使ったりもするかもなので, エミュレータではなく実機で動かす必要性が高い.
(ARM 環境だけであれば, ラズパイのように ARMv8 Linux box を使うというてもあるかも. また, 最新 ARM64bit エミュレータは NEON 命令も扱えるようになったかも?)
 
## 要件

* 最新 Android SDK/NDK(Android 3.0.1 経由でインストールされる SDK/NDK を使いました)
* **root の取れる** Android 実機
  * 今回は HiKey 960 を使いましたhttps://www.96boards.org/product/hikey960/ . 最近だと 4 GB 版が出ています https://www.switch-science.com/catalog/3545/ )
* C++11 でコンパイル


## CMake bootstrap

CMakeLists.txt は, だいたい今までの C/C++ アプリと同じように記述できます.
(Android に特化した設定が必要な場合は別途記述)

Android SDK に cmake(+ ninja)が含まれているので, それを使って Android 用の設定を cmake configure のオプションに指定します.

https://developer.android.com/ndk/guides/cmake.html

にオプションのリストがあります.
最低限, 以下のような感じにすればビルド用 Makefile が生成されます.

```
# bootstrap-android.sh

## Please edit android sdk/ndk/cmake path
ANDROID_SDK_ROOT=$HOME/Android/Sdk/
ANDROID_NDK_ROOT=$HOME/Android/Sdk/ndk-bundle
CMAKE_BIN=$ANDROID_SDK_ROOT/cmake/3.6.4111459/bin/cmake

rm -rf build-android

$CMAKE_BIN \
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=arm64-v8a \
-DANDROID_NATIVE_API_LEVEL=24 \
-DANDROID_STL=c++_static \
-Bbuild -H.
```

## STL の選択

`c++_shared` だと, Android 実機側の C++ STL ランタイム .so と互換性が無く実行時エラーが出ます.

`c++_static` でコンパイルするようにします. 静的 STL リンクだとコンパイルエラーが出るような C/C++ アプリは今回は Android で動かすのはあきらめましょう...

`gnustl` も, ものによってはコンパイルエラーになります(e.g. json.hpp など https://github.com/nlohmann/json ). サードパーティライブラリを使うときは,
 Android でもコンパイルでき, 各種 STL 環境でも動くものを選びましょう.

## 実行する

Android 実機を USB でつなぎ,

`adb push` で `/sdcard` あたりにバイナリを開発 PC から Android 実機に転送します.

`adb shell` で Android 実機になり,
 
su で root にになり, バイナリを `/data/local/tmp` に移動して `chmod +x a.out` と実行権限を付けて, 動かします.

```
$ su
# cd /data/loca/tmp
# ./a.out
```
これで Android 実機で C/C++ プログラムが動きます!

## TODO

* OpenGL みたいな画面を出すようなアプリは別途考える. https://qiita.com/syoyo/items/85f01123c7d43298a85d
  * Vulkan offscreen ならいけるかも?
* Jenkins あたりで CI ビルドするようにしたい.
* HiKey 960 のアップデートを極めてくれる, 優秀な Android 開発ボード若人を探す旅に出たい.
* `ANDROID_STL` を `system` にし, `NanoSTL` https://github.com/lighttransport/nanostl を使うようにして STL 非依存な Android C++ アプリに挑戦したい.
ductでbasic認証をかける

正直よくわかってないけど動いたからメモしておきます。

# 依存関係にbuddyを追加する
https://github.com/funcool/buddy-auth

```project.clj
[buddy/buddy-auth "2.1.0"]
```

# middlewareを設定する

```config.edn
:duct.core/handler
{:middleware [#ig/ref :foo.auth/basic-auth]}

:foo.auth/basic-auth {}
```

# basic認証の処理を定義する

```auth.clj
(ns foo.auth
  (:require [integrant.core :as ig]
            [buddy.auth :refer [authenticated?]]
            [buddy.auth.accessrules :refer [restrict]]
            [buddy.auth.backends.httpbasic :refer [http-basic-backend]]
            [buddy.auth.middleware :refer [wrap-authentication wrap-authorization]]))

;; 入力が正しければtrueを返す関数を用意する
(defn authfn [_ {:keys [username password]}]
  (and (= username "a") (= password "a")))

(def auth-backend (http-basic-backend {:authfn authfn}))

(defmethod ig/init-key ::basic-auth [_ options]
  (fn [handler]
    (-> handler
        ;; サイト全体にbasic認証をかけたいのでrestrictを使う
        (restrict {:handler authenticated?})
        (wrap-authorization auth-backend)
        (wrap-authentication auth-backend))))

```
git remote addでエラー「fatal: remote origin already exists.」

# git remote addエラー
次のようなエラーが出る

```
#git remote add origin https://github.com/ユーザ名/レポジトリ名.git
fatal: remote origin already exists.
```

# 対処法
originがすでに設定されているので以下のコマンドで削除してから再度`git remote add`を行えば良い

```
$ git remote rm origin
```

#git originの設定を確認
以下で確認が可能

```
$ cat .git/config
```
固定エリアの中に可変画像を中央寄せ＋長い方で縮小して配置をimgタグのままCSSのみで行う方法

あまりないかもしれませんが、サイズ指定されたエリアの中に、様々なサイズの画像を縦横中央＋長い方で縮小して設置する方法です。

`background-image`を使用すれば簡単ですが、ここではimgタグのまま行う方法を紹介します。

下記のjQueryプラグインを使用すると簡単ですが、imgタグをbackground-imageに変換することで可能にしています。
https://github.com/karacas/imgLiquid

僕は、以前はこちらをよく使用していましたが、flexboxが使用できるようになった今ではCSSのみで対応できます。

## 対応方法

下記のような200×200のエリアを例に説明したいと思います。

<img width="208" alt="スクリーンショット 2018-01-21 22.22.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/155990/86f453f0-9c3e-d704-400c-46f9f2c16a2e.png">

```html
<div class="imageBox"></div>
```

```scss
.imageBox {
  $areaSize: 200px;
  width: $areaSize;
  height: $areaSize;

  border: solid 1px #ccc;
  background: #eee;
}
```

## 対応方法

HTMLを以下のようにして、画像を設置します。

```html
<div class="imageBox">
  <img arc="" alt="" />
</div>
```

CSSは下記のように修正します。

```scss
.imageBox {
  $areaSize: 200px;
  width: $areaSize;
  height: $areaSize;

  border: solid 1px #ccc;
  background: #eee;
  
  display: flex;
  align-items: center;
  justify-content: center;

  > img {
    max-width: $areaSize;
    max-height: $areaSize;
    width: auto;
    height: auto;
  }
}
```

まず、`.imageBox`（画像を入れる要素）に、`display: flex;`, `align-items: center;`, `justify-content: center;`を指定します。
これによって、子要素のimgタグを縦横中央に設置します。

さらに、子要素のimgタグに縦横サイズの指定を追記ます。
縦横の最大を、親要素のサイズになるように、`max-width: $areaSize;`, `max-height: $areaSize;`を指定します。
これによって、縦横のより長い方が縮小され、もう片方（縦／横）も同じ比率で縮小されます。
明示的に`width: auto;`, `height: auto;`を指定していますが、なくても問題ないです。
また、サイズは変数化しておいた方が、修正漏れなども置きなくなるので、変数化をおすすめします。

### 縦がエリア以上の場合

<img width="208" alt="スクリーンショット 2018-01-21 22.40.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/155990/b4605f46-4596-12a8-c65d-1009537b8cfe.png">

### 横がエリア以上の場合

<img width="206" alt="スクリーンショット 2018-01-21 22.41.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/155990/0d0790da-35f0-f9e0-78fd-a539a0f8e124.png">

### 縦横がエリア以下の場合

<img width="210" alt="スクリーンショット 2018-01-21 22.42.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/155990/bfe7a1e8-3dc2-3256-9b8b-a2b91a67405f.png">

### 縦横がエリア以上の場合

<img width="209" alt="スクリーンショット 2018-01-21 22.43.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/155990/e44c7f13-19d9-b031-2bc5-5bf8149419d1.png">

この場合、横の方がよりエリアより大きかったので、横ベースで縮小されています。

## まとめ

以上が、固定エリアの中に可変画像を中央寄せかつ、長い方で縮小して設置する方法でした。
【PHP】受け取った可変長引数を別の関数に可変長引数として渡す

使用したPHPのバージョン: 7.1.12

PHPでも他の多くの言語と同様に可変長の引数を受け取ることができます。
その場合、引数リストに...トークンを含めます。

```php
function func($arg1, ...$args) {
    // $argsには2つ目以降の引数が配列として入る
}
```

※ PHP5.5までは func_get_args() で引数を受け取っていました。

可変長の引数を受ける関数のラッパー関数を作る場合などに、単純に

```php
function func($arg1, ...$args) {
    // do something
}

function wrapper_func($arg1, ...$args) {
    // do something
   
    func($arg1, $args); // これでは上手くいかない
}

```

とするわけにはいきません。

~~このような場合、[call_user_func_array](http://php.net/manual/ja/function.call-user-func-array.php)関数で呼び出します。~~
####（2018/1/22追記）コメントで教えていただきました。
このような場合、関数呼び出しで...トークンを用いると可変長の引数を渡すことができます。

```php

function wrapper_func($arg1, ...$args) {
    // do something
   
    func($arg1, ...$args); // ...トークンで引数を展開できる
}

```

##（2018/1/22追記）以下は修正前の記事です。

### 関数の場合

```php
function func($arg1, ...$args) {
	// do something
}

function wrapper_func($arg1, ...$args) {
	// do something

	call_user_func_array("func", array_merge([$arg1], $args));
}
```

### メソッドの場合

```php
class Test {
	function method($arg1, ...$args) {
		// do something
	}

	function wrapper_method($arg1, ...$args) {
		// do something

		call_user_func_array([$this, "method"], array_merge([$arg1], $args));
	}
}
```

クラス外からは同様に

```php
$obj = new Test();

function wrapper_func($arg1, ...$args) {
	// do something

	call_user_func_array([$obj, "method"], array_merge([$arg1], $args));
}
```

### 静的メソッドの場合

```php
class Test {
	static function method($arg1, ...$args) {
		// do something
	}

	static function wrapper_method($arg1, ...$args) {
		// do something

		call_user_func_array([get_called_class(), "method"], array_merge([$arg1], $args));
	}
}
```

静的メソッドをクラスの外から呼び出す場合は

```php
call_user_func_array(["ClassName", "method_name"], array_merge([$arg1], $args));
```

または

```php
call_user_func_array("ClassName::method_name", array_merge([$arg1], $args));
```

で呼び出せます。

## 参考
 [引数を可変長引数で受け取り、可変長引数で渡す](https://qiita.com/msysyamamoto/items/744fa3006c72fcfaa6a6)
CygwinのPython(2.7)でmatplotlibを使う

Cygwinでmatplotlibを使えるようになるまでに、いくつかハマりどころがあったので、過程を記しておきます。

#環境
諸事情により、Cygwin 32bit + Cygwin版Python2.7 + matplotlib 2.1.1 です。

#手順
Cygwin自体の導入は省略します。

###1. Pythonとpipのインストール
Python本体の他、python-develパッケージも必要です。
pipは、python-pipというパッケージに入っています。

###2. matplotlibのインストール
上記でインストールしたpipは、python2系なら「pip2」というコマンド名で呼び出します。

```
$ pip2 install matplotlib
```

**途中でエラーメッセージが出たら**
"gcc: error: spawn: No such file or directory" → gcc-g++が入っていないのでインストールします。
"Perhaps you need to install ..." → 必要なパッケージをインストールして再試行します。

###3. importとバージョンの確認
インストール完了したら、Pythonを対話モードで起動して、matplotlibのバージョンを確認してみます。


```
$ python
>>> import matplotlib
>>> matplotlib.__version__
'2.1.1'
```

###4. グラフ描画の準備
X11カテゴリのパッケージを一通りインストールしておきます。
Xサーバを起動して、ディスプレイを指定します。

```
$ run xwin -multiwindow -noclipboard
$ export DISPLAY=:0.0
```

###5. グラフ描画のテスト
何の変哲もないグラフを出力してみます。

```
$ python
>>> import matplotlib.pyplot as plt
>>> plt.plot(range(10))
[<matplotlib.lines.Line2D object at 0xfd8fae2c>]
>>> plt.show()
```
<img src=https://qiita-image-store.s3.amazonaws.com/0/118239/5ff900a6-3117-004f-a0ad-6f2dcc0dd6e7.png width=50%>

###6. (※出力されない場合) バックエンドの確認・変更
matplotlibのバックエンドを確認します。

```
>>> import matplotlib
>>> matplotlib.get_backend()
u'agg'
```
'agg'等、GUI非対応の設定になっていたら変更します。
使用可能なバックエンドと、必要なライブラリについては、公式ドキュメントの表を参照ください。
[matplotlib Usage - What is a backend?](https://matplotlib.org/faq/usage_faq.html#what-is-a-backend)

ここでは、Qt4Aggを使うように変更してみます。
qt4パッケージをインストール

```
$ apt-cyg install python-pyqt4
```
matplotlibrcファイルの場所を確認する

```
>>> matplotlib.matplotlib_fname()
u'/usr/lib/python2.7/site-packages/matplotlib/mpl-data/matplotlibrc'
```
matplotlibrcを開いて、backendを書き換えて保存する
`backend : Qt4Agg`



#さいごに
バックエンドの問題は、エラーメッセージが出るわけでもないので、結構手こずりました。

ちなみに Cygwin 64bit + Windows版AnacondaのPython3.6 + matplotlib 2.1.1 という環境も併用していますが、
そちらは最初からpipも入っているし、バックエンドの問題もなかったです。
ただ余談ですが、Windows版のPythonをCygwinから対話モードで起動するときは、`python -i`と明示的にオプションをつけないといけないのですね。

以上、個人的につまづいた箇所を中心に、Cygwin+matplotlib導入手順でした。
ご指摘等あれば、よろしくお願いします。
Kotlin コード規約（ Document comments, Avoiding redundant constructs ）

[公式](http://kotlinlang.org/docs/reference/coding-conventions.html)の和訳（意訳）です．

- [IDEでスタイルを設定する, ソースコード構成](https://qiita.com/hmiyado/items/2531be40b3369173a2cd)
- [命名規約](https://qiita.com/hmiyado/items/feea2cdd196ef53b1a1a)
- [フォーマット 前半](https://qiita.com/hmiyado/items/2ad86df1d0cb842beee6)
- [フォーマット 後半](https://qiita.com/hmiyado/items/4667994ea71fe4c76484)
- ドキュメントコメント，冗長な記述を避ける(この記事)
- [慣用表現の使用](https://qiita.com/hmiyado/items/94792e428e5993bc8fc6)
- [ライブラリのコード規約](https://qiita.com/hmiyado/items/f1e84c7870b8a5864a7b)

# ドキュメントコメント

ドキュメントコメントが長いときは，`/**` だけの行を書き，それぞれの行はアスタリスクを最初に書く．

```kotlin
/**
 * This is a documentation comment
 * on multiple lines.
 */
```

短いコメントは1行で書いてもよい．

```kotlin
/** This is a short documentation comment. */
```

一般的に， `@param`と`@return`は使わないようにする．
代わりに，パラメータや返り値の説明をドキュメントコメントに直接埋め込んで書く．
パラメータにはリンクを付ける．
`@param` と `@return` は，それらにとても長い説明が必要で，本文に埋め込んで書くのも難しいときだけ使う．

```kotlin
// Avoid doing this:

/**
 * Returns the absolute value of the given number.
 * @param number The number to return the absolute value for.
 * @return The absolute value.
 */
fun abs(number: Int) = ...

// Do this instead:

/**
 * Returns the absolute value of the given [number].
 */
fun abs(number: Int) = ...
```

# 冗長な記述を避ける

一般に，あるKotlinコードの記述がオプショナルで，IDEに冗長であることを指摘されているときは，そのコードを修正するべきである．
"明確さのため"だけにコードに不要な記述を残さない．

## Unit

関数が Unit を返すときは，返り値の型を省略する．

```kotlin
fun foo() { // ": Unit" is omitted here

}
```

## セミコロン

セミコロンは出来る限り書かない．

## String テンプレート

String テンプレートにある変数だけを挿入するときは，波括弧を書かない．
波括弧は，長い式を書くときだけ使う．

```kotlin
println("$name has ${children.size} children")
```
Railsで曜日検索をする

# Railsで曜日検索を行う
下記のようなチェックボックスでupdate_atでの曜日検索機能を実装したのでメモ。
もっといい方法がありましたらコメントにて教えていただけますと幸いです。

<img width="447" alt="スクリーンショット 2018-01-04 23.37.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/107187/2dad9e0d-7070-9784-48f0-edd83863e7eb.png">

##環境
Rails 5.0.3
Ruby 2.4.0
SqlLite3 1.3.13

```erb:index.html.erb
<label class="weekday">曜日</label>
<div class="checkbox">
    <% @weekdays.each_with_index do |weekday, i| %>
        <label><%= check_box_tag 'condition[weekdays][]', i, @weekdays_index.include?(i.to_s), id:"condition_weekdays_#{i}"  %><%= weekday %></label>
    <% end %>
</div>
```

```rb:users_controller.rb
def index
  @weekdays = %w[日 月 火 水 木 金 土]
  @weekdays_index = ['0','1','2','3','4','5','6']
  @user = Search::User.new
  
  unless params[:condition].nil?
    @weekdays_index = params[:condition][:weekdays]
  end
  
  @users = @user
    .matches(@weekdays_index)
end
```

```rb:user.rb
class Search::User < Search::Base
  def matches(cwdays)
    t = ::User.arel_table
    results = ::User.all
    results = results.where(%(strftime('%w', update_at) in (?)), cwdays)
    results
  end
end
```
nginxでLaravelを動かす時に困った

#概要
nignxでLaravelを動かす時にLaravelでroutingした通りに動いてくれなくて困ったので、同じ思いをしている人へメモ。
私の環境ではnginxのdockerコンテナとphp-fpmのdockerコンテナを用意して、nginxコンテナからphp-fpmコンテナへリダイレクトする方式をとっていますが、なかなかLaravelで行なっているルーティングの通りに動かすことができませんでした。そもそもnginxの使い方もあまり知っていないため、設定値を変えまくって、考察して、これで動く！ということを今回の記事の成果物としています。ベストプラクティスを知っている方は教えてください。

#実際にどんなことが起きたのか
・ちゃんとルーティングしているつもりなのにnginxから「file not found」が返される
・nginxから「file not found」は返されないものの真っ白な画面が出てくる
・「localhostで接続が拒否されました。」と言われて接続すらできない
と、いろいろ苦労しました。

#nginxの設定値について
まず、たぶんこの記事を読んでいる人は以下の設定値がなんなのかわからなくて、どうすれば正しい設定になるのか、ということやLaravelのルーティングのされ方についてあまりわからなくて、ダメだぁ、となっているのではないかと思います。

```default.conf
root /var/www/html;
~ いろいろと略 ~
location /hoge/ {
    fastcgi_split_path_info ^(.+\.php)(\.+)$;
    fastcgi_pass php_docker:9000;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
}

```
こんな風な設定をおそらく書いているものと思いますので、まず＄document_rootとか$fastcgi_script_nameに何が入っているのかを見てみます。
この変数の中身を確認するためには、nginxでadd_headerというやつをくっつけてあげて、curlで確認してあげれば、何が入っているかわかります。以下を参考にしてください。

```default.conf
root  /var/www/html;
~ いろいろと略 ~
location /hoge/ {
    add_header my_string 'start'; # <- これを追加
    add_header my_document_root $document_root; # <- これを追加
    add_header fastcgi_script_name $fastcgi_script_name; # <- これを追加
    add_header my_fastcgi_path_info $fastcgi_path_info; # <- これを追加
    add_header my_string_2 ‘end’; # <- これを追加

    fastcgi_split_path_info ^(.+\.php)(\.+)$;
    fastcgi_pass php_docker:9000;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
}
```
そしてcurlを実行します(ポートは8888ですが自分用に変えてください)。

```
curl --head http://localhost:8888/hoge
もしくは
curl -I http://localhost:8888/hoge
```
そうすると、 `add_header` に記載した値が出力されます。(変数が空の場合は出力されないみたいなのと、400系のエラーが出ている場合も変数は出力されないので注意)

```
~ いろいろと略 ~
my_string: start
my_document_root: /var/www/html
fastcgi_script_name: /hoge
my_string_2: end
```
こんな値が入っているので、`default.conf`のSCRIPT_FILENAMEの設定値は以下のように展開されることがわかります。

```default.conf
fastcgi_param SCRIPT_FILENAME /var/www/html/hoge;
```

Laravelは、`public/index.php`(artisanがある場所と同階層)がエントリポイントであるためnginxがをfastcgiとして`public/index.php`を実行するように指定します。

そのため、私はこうしました！

```default.conf
fastcgi_param SCRIPT_FILENAME /var/www/html/hoge/public/index.php;
```
直接指定しました！w

これで、”一応”いきますw

ちなみに、$document_rootの値はrootコマンドで上書きすることができるので、以下みたいにしても動くと思います(やっていないけど)。

```default.conf
root  /var/www/html;
~ いろいろと略 ~
location /hoge/ {
    root /var/www/html/[Laravelへのパス];
    add_header my_string 'start';
    add_header my_document_root $document_root;
    add_header fastcgi_script_name $fastcgi_script_name;
    add_header my_fastcgi_path_info $fastcgi_path_info;
    add_header my_string_2 ‘end’;

    fastcgi_split_path_info ^(.+\.php)(\.+)$;
    fastcgi_pass php_docker:9000;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root/index.php; # ここを変更
    fastcgi_param PATH_INFO $fastcgi_path_info;
}
```

私からはこのくらいです。
gvim(kaoriya版)のquickfixで日本語が文字化けするときの対策

環境設定のたびに忘れて何度も調べたりするのでメモ。

#問題
`fileencoding=UTF-8`, `fileformat=unix`でファイルを開いているのに、quickfixウインドウは
`fileencoding=cp932`, `fileformat=dos`になってしまい、日本語が文字化けする。

#対策
\$VIM/switches/catalog/utf-8.vim を、\$VIM/switches/enabled/utf-8.vim にコピーする。
それでもなんとか続けられる理由

#何をしているか
RubyonRailsの学習をして二か月実働にして、20時間も行っていないが、先の記事でふれたように、まったくやる気を失う日もあった。

#それでも続けられる理由
それは。[先の記事](https://qiita.com/rinren/items/c41c60491d35d122fc21)でふれた対策を真面目にやってきたから。と言いたいところだが、実は気が付いたことがあるので、同じ思いをしている方がいれば励ましになるかと思い、書いてみる。


#使っているテキストがとても親切。
例えば、私が参考にしている本では、よくこんな言い回しが出てくる

>「コマンドは配布サンプルにも掲載しています。いちいちタイプするのが面倒という方は、こちらをコピーして利用しても構いません」
私⇒え、いいんすか？親切ですねーラッキー。コピペ

>「具体的な動作は配布サンプルからでも確認できます」
私⇒おー動くじゃーん。へぇー

>「完全なコードはダウンロードサンプルを参照しつつ、学習を進めることをお勧めします」
私⇒コードあるんんじゃんコピぺ


#ねえ・・本当に親切でしょ・・・・！？ねえ！？

よーくみるとなんか・・・
・・・なんかちくちく刺さってこない?・・こんな感じどっかで味わったことあるよね！？
・・・ツンデレな妹！？メイドさん!?こんな会社の嫌味な上司・先輩いたら嫌だよね!?

>「コマンドは配布サンプルにも掲載しています。いちいちタイプするのが面倒という方は、こちらをコピーして利用して**も**構いません」

>「具体的な動作は配布サンプルから**でも**確認できます」

>「完全なコードはダウンロードサンプルを参照**しつつ**、学習を進めることをお勧めします」

#男達よ!ここでコピペしたら負けな気がしないか？

そう。このテキストは愛情ゆえに、挑発気味に食って掛かってくるんだ。

**ここで眺めているだけで本当にいいのか!?
このまま進んで何が得られるんだ！？**

そんなメッセージを暗黙的に投げかけてきているのだ！！
そんな作者はきっと、ツンデレに違いない！！

#おかげでエラー祭り
自前のコードがエラーを吹いた時だけサンプルを見るようにしている私。もちろんコマンドもテキストガン見で打ちますとも!!おかげで、「ルートが通っていませんよ」とか「そんなビューありませんよ」的なやつとか「データベースの関係が設定されてないがために起こるエラー」とか、**エラー祭りじゃ！！**

#でもエラーを解決するたびに強くなっていく気がするんだ本当に。
実際にこのテキストを読むレベルの人は、エラーが出ないコード眺めても、何も得しないんじゃないか？
むしろ自分なりの理解で書いたコードが、火を噴いたときはチャンスだ！！理解に至る、扉がまた一つ増えたのだから。あとは自分で開くだけ。

そんなかっこよく決めたつもりでいる私なんだが、恥ずかしながら**そろそろエディタにrails補完機能は入れよう**と思っているよ(今更か？むしろ先にやれよ)・・・ビューヘルパーの名前・・・長いから。！！
Flask,requestsでファイルアップロード、ファイルダウンロードのまとめ


## 1. ファイルアップロード、ダウンロードの基本

<img src="https://qiita-image-store.s3.amazonaws.com/0/195748/f36d66f0-e79e-78b8-e412-26c2fa157071.jpeg" width="100%">

| 項番 | 方向 | 区分 | 詳細/記事 |
|:----:|:----:|:----:|:----------|
| ① | :arrow_up: アップロード | クライアント<br>（requests） | [Pythonのrequestsを利用してmultipart/form-dataのFormにファイルアップロードする方法](https://qiita.com/5zm/items/92cde9e043813e02eb68) |
| ② | :arrow_up: アップロード | クライアント<br>（requests） | [Pythonのrequestsを利用してRest API(json形式)にファイルアップロードする方法](https://qiita.com/5zm/items/8dc6189940b42e241210) |
| ③ | :arrow_up: アップロード | サーバ<br>（Flask） | [Flaskでmultipart/form-dataのファイルアップロードを実現する方法](https://qiita.com/5zm/items/ac8c9d1d74d012e682b4) |
| ④ | :arrow_up: アップロード | サーバ<br>（Flask） | [FlaskでRest API(json形式)のファイルアップロードを実現する方法](https://qiita.com/5zm/items/ef95b17ab80d7dbee981) |
| ⑤ | :arrow_down: ダウンロード | クライアント<br>（requests） | [Pythonのrequestsを利用してファイルダウンロードする方法](https://qiita.com/5zm/items/366f10fcde5d3435b417) |
| ⑥ | :arrow_down: ダウンロード | クライアント<br>（requests） | [Pythonのrequestsを利用してRest API(json形式)でファイルダウンロードする方法](https://qiita.com/5zm/items/d62df0e7b1d98348f983) |
| ⑦ | :arrow_down: ダウンロード | サーバ<br>（Flask） | [Flaskでファイルダウンロードを実現する３つの方法](https://qiita.com/5zm/items/760000cf63b176be544c) |
| ⑧ | :arrow_down: ダウンロード | サーバ<br>（Flask） | [FlaskでRest API(json形式)のファイルダウンロードを実現する方法](https://qiita.com/5zm/items/8fe746e2c5c8083bfc04) |

### 1.1. マルチパートによるファイルアップロード

`multipart/form-data`による、いわゆる普通のファイルアップロードの方法です。
この方法のポイントはHTTPの仕様に準拠しているため、クライアント（requests）およびサーバ（Flask）にファイルアップロードを考慮した便利なAPIが用意されていることです。
サンプルでは`requests`をクライアントにしていますが、もちろんWebブラウザの標準機能でアップロードすることができます。

### 1.2.  Rest API(json形式)

`Rest API(json形式)`のjsonの1フィールドにファイルデータを格納する方法です。
jsonにバイナリデータを設定できないため、バイナリデータをbase64でエンコードしたascii文字列を設定する方法が多いです。
jsonのデータ構造はAPIに依存するため、利用する`Rest API(json形式)`毎に仕様を確認する必要があります。

```json:サンプルで利用するAPIのデータ構造
{
    'fileName': 'ファイル名',
    'contentType': 'mimetype',
    'contentData': 'バイナリデータをbase64でエンコードしたascii文字列'
}
```

### 1.3. 普通のファイルダウンロード

HTTPレスポンスヘッダにファイルのコンテントタイプやファイル名を設定し、HTTPレスポンスボディにファイルのデータを設定する普通のファイルダウンロードの方法です。
こちらもHTTPの仕様に準拠しているため、クライアント（requests）およびサーバ（Flask）にファイルダウンロードを考慮した便利なAPIが用意されています。

## 2. 応用

### 2.1. Flaskで巨大ファイルのダウンロードを実現する方法（予定）

データサイズが数百MBから数GBのファイルをダウンロードさせる場合、サーバのリソース（主にメモリ）を考慮した実装を行う必要があります。
バッファリング処理を行うことで、データサイズに関わらずリソース消費が一定になる方法について説明します。

### 2.2. Pythonのrequestsを利用して巨大ファイルをダウンロードする方法（予定）

データサイズが数百MBから数GBのファイルをダウンロードする場合、サーバと同様にクライアントのリソース（主にメモリ）を考慮した実装を行う必要があります。
バッファリング処理を行うことで、データサイズに関わらずリソース消費が一定になる方法について説明します。

### 2.3. FlaskをRangeリクエストに対応させ、ダウンロードの再開（レジューム）を実現する方法（予定）

Rangeリクエストとはリソースの一部を取得する要求でHTTP 1.1で定義（[RFC7233](https://tools.ietf.org/html/rfc7233)）されています。
巨大ファイルのダウンロードでは、全てのデータのダウンロードが完了する前に通信が切れてしまう場合が想定されます。
その際、未ダウンロードのデータを取得するために利用されるがRangeリクエストです。
FlaskのファイルダウンロードでこのRangeリクエストに対応する方法について説明します。
メモ

#ajax

```javascript:index.js
$("#init").on('click', function(){
    $.ajax({
           type: "GET",
            url: "/init",
      dataType : "json"
    }).then(
        function(data){
            $("#foodList").empty();

            for (var i = 0; i < data.length; i++) {
                $("#foodList").append(
                    "<tr>"
                     +"<td> <a class='btn btn-default' href='/actor/detail?id='" +data[i].id+ "'>" + data[i].name + "</a></td>"
                     +"<td class='item-price'>" + data[i].price + "</td>"
                     +"<td class='item-category'>" + data[i].classification + "</td>"
                     +"<td>" + data[i].vendor + "</td>"
                     +"<td>"
                     +"<form action='/delete/' method='post'>"
                     +"<input class='btn btn-warning' type='submit' value='delete'>"
                     +"</form>"
                     +"</td>"
                     +"</tr>"
                );
            }
        }
    )
});

```
```java:FoodController.java
	public Result init() {
		FoodService service = new FoodService();
		return ok(Json.toJson(service.findByIdLimitNum()));
	}
```
```file:routes
GET		  /init						  controllers.FoodController.init
```


#getのパラメータ取得

```java:Controller.java
  String id = request().getQueryString("id");
```
Gitを使ってVSCodeの設定を複数の環境で使いまわす(Win/Linux)

WindowsとLinuxでそれぞれVSCodeを使っていたのですが，個別に設定を整えるのが面倒なので"[dotfilesをGitHubで管理](https://qiita.com/okamos/items/7f5461814e8ed8916870)"のように設定ファイルをGitホスティングサービス経由で他の環境,OSでもすぐに同じ設定を適用できるようにしてみました

# 目的
`git clone` して， コマンドを1つ叩くと同一の設定が適用される

# 準備
privateでもいいので適当にリポジトリを作ります．
参考に自分のは[こんな感じ](https://github.com/WGGSH/vscode-setting)です

## ディレクトリ構成
以下のようになっています  

``` :ディレクトリ構成
vscode-setting
  ├─ linux.sh
  ├─ windows.bat
  ├─ extension-list
  └─ User/
      ├─ keybindings.json
      ├─ settings.json
      └─ snippets/
```

このうちUser/以下はVSCodeによって生成される設定ファイルで，これを指定の場所にシンボリックリンクを貼り付けるために`linux.sh`と`windows.bat`があります．
`extension-list`はインストールしたい拡張機能をまとめたファイルです

## extension-list
拡張機能の**ID**を1行毎に書いていきます．
拡張機能の名前ではダメなようです.
↓画像の<font color="Red">赤枠</font>部分が拡張機能のIDになります
![image.png](https://qiita-image-store.s3.amazonaws.com/0/170422/c11fd442-cf16-c620-e31d-0e58e91c1cc1.png)
とりあえず自分の場合はこんな感じで
(VSCode初心者なので便利な拡張機能があれば教えてくださると助かります)

``` :extension-list
naumovs.color-highlight
oderwat.indent-rainbow
shardulm94.trailing-spaces
Tobiah.language-pde
ms-vscode.csharp
Unity.unity-debug

```


## `windows.bat`
``` bat:windows.bat
@echo off
rem User以下の設定ファイルのリンクを生成
mklink /D C:\Users\%USERNAME%\AppData\Roaming\Code\User %CD%\User

rem 拡張機能のインストール
for /f %%a in (extension-list) do (
  code --install-extension %%a
)
```
`mklink`コマンドでシンボリックリンクを作成し,ユーザディレクトリ内の設定ファイルが置かれるディレクトリにリンクを繋げます
また,先に作成したextension-listから1行ずつ読み込んで, vscodeの`--install-extension`オプションに流し込みます.

## `linux.sh`
Linux版もWindowsとやることは変わりません
設定ファイルの保存先が違う程度です
Macは使ってないのでわかりませんが,基本はLinux版と同様のコマンドで,パスを変えるぐらいでできるのではないでしょうか(違っていたらすみません)

``` sh:linux.sh
#!/bin/sh

# User以下の設定ファイルのリンクを生成
ln -s "`pwd`/User" ${HOME}/.config/Code/

# 拡張機能のインストール
filename="./extension-list"
cat ${filename} | while read line
do
  code --install-extension ${line}
done
```

# 完成
これで,新しい環境でVSCodeを入れ直すことになっても,すぐにセッティングが終わります.
ActionMailer::Prevew を利用してプレビューする際に、途中で作ったDB内の情報をロールバックする


https://blog.bearandgiraffe.com/rails-email-previews-e2c7b79839a0
上記のようなPreview内でロールバックする実装でいけるのかと思ったのですが、自分の手元ではどうもロールバックできなかったです。

多分これでいいんじゃないかなーと思うんだけど、やったことを残しておくために一応エントリ作っておく。もしも上手く動かなかったら教えてください。手元ではいい感じに思っています。下記のクラスを基底にすればいけると思う。


```rb
class BasePreview < ActionMailer::Preview
  # メールのプレビューを作る際に作ったDB内の情報はロールバックする
  def self.call(email)
    ret = nil
    ActiveRecord::Base.transaction do
      ret = super
      raise ActiveRecord::Rollback
    end
    ret
  end
end
```
チームがうまくまわるようにAnsibleのPlaybookでGitHubプルリクテンプレートを使いたい話

# 背景 
最近インフラを触り始めた人と一緒に働くことが多くなってきた。みんなに効率よく経験を積んでもらいつつ、インフラチームをうまく回すための施策を細々考えている。この記事はその中の一つについてのメモ。
私は「こういう内容が良いのではないか」と思って作ったものなので今後チーム内外の意見をもらって内容が書き換わる可能性は大いにある。

# GitHubのテンプレート機能はどう使うか
レポジトリのルートディレクトリに PULL_REQUEST_TEMPLATE.md という名前でファイルを置くと、プルリクを作るときに自動的にその内容が書かれる。
詳しい置き方や仕様についてはググれば出てくるのでここには書かない。

# テンプレートを作るにあたり気をつけたこと

* 後からプルリクを見直したときに、何をやっているか分かるか。後から新人が入ってきたときにプルリクをトレースして学ぶことができるようにしたい。
* 開発環境や本番環境に全て（半）自動反映になっていれば最高だが、今のところそうなっていない。　反映漏れ事故をなくしたい。
* コードだけ書いて本番に反映せず満足してしまう人もたまに居るので、きちんとデリバリーしようという意識を持ってもらうために、それを促す記述を入れたい。
* プルリクを出した後のネクストステップを意識するとスムーズに仕事が回るので、それを考えてもらいたい。
* 時間は無限ではないので緊急度や重要度を意識して、やらなくて良い仕事はやらない。ネクストステップがない場合もある。
* よく分からないことをプルリク出してもレビュアが気がつかなければプルリクが通ることがある。事故の元なので曖昧なことは表明してもらってみんなで解決したい。


# テンプレート内容
```
# 概要
### 経緯
issueやconflenceリンクがある場合にはそれを張っても良い。

### このprの目的
課題は何か

### 変更点概要
この変更によりどう解決されるのか

# 本番/開発環境更新
### 反映タイミング
開発環境と本番環境への反映を行うタイミングを記述する。以下の選択肢から1つ選択して詳細を記述する。

* 開発環境に反映済み
  * 対象サーバを記述する
* マージ後開発環境にのみすぐ反映する
  * しばらく開発環境で動作を確認したい場合に選択。もしくは緊急度が低く、本番へは次のサーバリプレイス時に入れば良いという場合
  * 反映すべきサーバを書いておく
* マージ後すぐに本番に反映する
  * 緊急度が高い場合
  * 本番更新チケットを作成して、リリースタグを切って反映する。参考： http://hogehoge.jp
  * 反映すべきサーバを書いておく

### 動作確認手順
更新後に行う動作確認の手順を記述する。すでに開発環境で動作確認を行っている場合にはその内容を書く。
できるだけprを出した本人以外でも動作確認ができるように書く。自明な場合には記述しなくてもよいが、レビュアーはレビューをする段階で分からなかったら確認するのが望ましい。

# 関連issue/pr/外部リンク

# その他
### 今後の課題
次に解決すべき課題があれば書く。

### 実装に関する留意点
困ったことやイマイチな点など。
```

# やってみた結果
今のところいい感じ。
とくに「今後の課題」の項目があることで、次にどんなものをやったら大タスク全体として解決に向かうかというのが分かりやすくなった（気がする）
box model反映の方法

プロフィール画像をページの真ん中に設置したくてbox modelを使いコードを書いてみたのですが、うまく画像が真ん中に反映されません。何回も編集したりネット検索して試したのですができないので、どなたかアドバイス宜しくお願いします。![スクリーンショット 2018-01-21 11.44.55.png](https://qiita-image-store.s3.amazonaws.com/0/232693/62a06739-a4e7-a804-34de-e7eb970439c9.png)

![スクリーンショット 2018-01-21 11.45.33.png](https://qiita-image-store.s3.amazonaws.com/0/232693/ea84adc0-a79f-7a18-f503-308ffbfa0d70.png)
JSCOM (JavaScript Client Side Object Model) メモ

色々と忘れるので個人的メモ

## リストのパスを取得

```js
(function () {
    var ctx = new SP.ClientContext('{your site path}');

    var lists = ctx.get_web().get_lists();
    ctx.load(lists, "Include(RootFolder.ServerRelativeUrl)");

    ctx.executeQueryAsync(
        function(){
            var enumLists = lists.getEnumerator();
            while(enumLists.moveNext()) {
                var current  = enumLists.get_current();
                console.log(current.get_rootFolder().get_serverRelativeUrl());
            }
        },
        function(sender , args) { console.log(args); }
    );
})();
```
リスト全件のパスを取得している。

> ctx.load(lists, "Include(RootFolder.ServerRelativeUrl)");

RootFolder から取るのをよく忘れるのでメモ。
あと、なにげに getEnumerator の使い方も忘れる。

## CAML Query

別で纏めている

* [SharePoint CAML Query メモ](https://qiita.com/miyamiya/items/fc53bea1d6555fbbcc3f)
AWS RDS勉強まとめ

・RDSの制限事項
バージョンが限定
キャパシティに上限
OSログインやファイルシステムへのアクセス不可
など

上記が許容できない場合はOn EC2かオンプレミスで構築

・`Multi-AZ`
同期レプリケーションと自動フェイルオーバー
インスタンスやハードウェア障害時など

・`リードレプリカ`
デフォルトで5台増設可能
マルチAZやクロスリージョン対応も可能
マスタと異なるタイプに設定可能
読み取り専用などに設定し、スループット向上

・スケールアップ、スケールダウン可能

・ストレージタイプ
`汎用SSD`
`プロビジョンドIOPS`
`マグネティック`

・バックアップ
自動スナップショット＋トランザクションログをS3に保存
1日1回設定した時間に自動スナップショット取得、保存期間は0日～35日、手動スナップショットも可能

・リストア
スナップショットをもとにDBインスタンス作成
指定した時刻の状態にすることも可能（Point-in-Time）

・スナップショットはDBインスタンスのサイズと同サイズまでコスト無料
・自動スナップショットはDBインスタンス削除と同時に削除
※手動スナップショットは削除されないので、削除前に最終スナップショットをとること推奨
・スナップショット実行時にI/Oが停止するが、マルチAZの場合はスタンバイから取得するためアプリへの影響なし

・`リネーム`
RDSに接続する際のエンドポイントを切り替える機能
旧本番インスタンスをリネーム→新本番インスタンス（スナップショットからリストア）をリネーム

・リネームの注意点
DNSはすぐに切り替わるわけでない
CloudWatchのMetricNameは引き継がない
マスターをリードレプリカの関係、タグ、スナップショットは引き継ぐ

・RDSにかかわる制限事項
RDSインスタンス数：40
1マスターあたりのリードレプリカ数：5
手動スナップショット数：100
DBインスタンスの合計ストレージ：100TB
必要に応じて上限緩和申請

・デフォルトではDBインスタンスに対するネットワークアクセスはオフ
→セキュリティグループで制御し、アクセス許可のポートなどを指定

・DBインスタンスとスナップショットの暗号化可能

・`オンデマンドDBインスタンス`VS`リザーブドインスタンス`
`リザーブドインスタンス`：予約金を支払うことで価格割引

参考URL：https://www.slideshare.net/AmazonWebServicesJapan/20170510awsblackbeltrds
仮想通貨NEMのAPIでハーベスティングの状態を取得する

#はじめに
　[NEM APIのリファレンスはこちら](https://nemproject.github.io/)

　NEMのAPIを利用して指定のアカウントがハーベスティングを行っているかどうかを検査するためのフローを書きます。

#/account/get (/account/status)
　ハーベスティングの状態は /account/get 又は /account/status で取得できます。その時に見るべきフィールドは"status"と"remoteStatus"です。各ステータスとアカウントの状態の関係につい図にしました。下記参照。
![20180121.png](https://qiita-image-store.s3.amazonaws.com/0/216882/7c7973f2-1474-b786-fec4-82cbdc0c9df5.png)


#リモートアカウントでハーベスティングしている時はどうすればよいか
　最も確実なのは直接リモートアカウントのアドレスを指定して調べることです。ハーベスティングをしているリモートアカウントで同様に /account/get 又は account/status をしてstatusフィールドを確認すれば良いということになります。この時、remoteStatusフィールドの値は"remote"になっているはずです。

　委任元アカウントのアドレスしか情報が無い場合、そのアドレスのTx送信履歴を見て最も新しいインポータンストランスファートランザクションを探せば分かりますが、この方法は確実ではありません。(APIでは最大25件までしか取得できないので)

#注意点
　ハーベスティングの情報を取得するときは**そのアカウントがハーベスティングを行っているノードに問い合わせをしないと正しい結果が返ってきません。**
　というのも、アカウントのハーベスティングデータ(その時点でどのアカウントがハーベスティングに参加しているか)はNEMネットワーク上では情報交換を行っておらず、ローカルハーベスティング、委任ハーベスティング共に、各ノードが個別に管理しているのです。

　もし、委任していないノードに問い合わせをすると、そのアカウントが正常に委任ハーベスティングを行っていたとしても、statusフィールドはLOCKEDとなった返事が来るでしょう。

#さいごに
　リファレンスは便利ですが表現が厄介(しかもちゃんと更新されていない？)なので、ちょっとしたことでも描いておけば誰かの役に立つかも知れないと思って書いておきました。

　APIでの検索機能強化してくれー。
MacのMACアドレスを一時的に変える方法

いろいろな事情で一時的にMACアドレスを変えたいときの方法です。

# 今のMACアドレスの確認
```shell
ifconfig en0 | grep ether
```

で出力される。
今回の手順でMACアドレスを変えてもMacの再起動で元に戻るのであまり心配はいらないが、再起動せずに元に戻す場合はこの結果をメモっておく。


# Wi-Fiの接続を切る
Wi-Fiをオフに**するわけではなく**、Wi-Fiの接続を切る。
MacのWi-FiのマークをOptionを押しながらクリックし、`[Wi-Fi名]との接続を解除`をすることでWi-Fiの接続を切る。

# MACアドレスを変える
下記コマンドで変更ができる。
最後の引数が変更後のMACアドレスとなる。
MACアドレスとして妥当なものを入れる。

```shell
sudo ifconfig en0 ether aa:aa:aa:aa:aa:aa
```

完了。

戻すときは、同じ手順で元のMACアドレスへ変更すればOK.
Mac の Visual Studio Code で 「the .net cli tools cannot be located...」と出たときの対処法

# 起動時に「the .net cli tools cannot be located...」

起動時に、.NET SDK をインストールしているのに、上記のアラートが出てきた時は dotnet cli が実行できていないだけの時があります。

実行できればいいだけなので、これで OK
```
ln -s /usr/local/share/dotnet/dotnet /usr/local/bin/
```

# その他、似たような現象のときに確認したらよさそうな資料

- [Visual Studio Code for Mac C# 試したら、インテリセンスが効かずエラーが出たのでその対処 - Qiita](https://qiita.com/TsuyoshiUshio@github/items/7cd5634a66efe32b7aa7)

# 参考資料

- [dotnet: command not found mac OS X, dotnet-osx-x64.1.0.0.001598.pkg · Issue #2544 · dotnet/cli · GitHub](https://github.com/dotnet/cli/issues/2544)
marked.jsでemoji

#概要
marked.jsでemojiやってみた。

#写真
![image](https://qiita-image-store.s3.amazonaws.com/0/18104/024da3a1-2261-9f32-9765-966a5f9ec140.png)


#成果物
http://jsdo.it/ohisama1/wIhx


以上。
AWS EBS勉強まとめ


2017年新しい機能追加
＝＝
・起動ボリュームの暗号化をサポート

>・`スループット最適化HDD`
高スループットを必要とするワークロード(MapReduce、Kafka、ETL処理、ログ処理、データウェアハウスなど）向けのタイプ; 1GBあたり月額0.054ドル
・`コールドHDD`
同様のワークロードでアクセス頻度が低いユースケース向け; 1GBあたり月額0.03ドル
`プロビジョンドIOPS SSD`
I/O性能に依存するNoSQLデータベースやリレーショナルデータベース
`汎用SSD`
起動ボリューム、低レイテンシを要求するアプリケーション、開発・テスト環境
`マグネティック`
アクセス頻度の低いデータ
参考URL：https://aws.amazon.com/jp/blogs/news/amazon-ebs-update-new-cold-storage-and-throughput-options/

・汎用SSDボリュームのバーストクレジットの残高がCloudWatchで確認可能（残高はパーセンテージ）

・稼働中のEBSをオンラインのまま、ダウンタイムなく、変更することを可能にするエラスティックボリューム機能をリリース

・現行世代のインスタンスに関しては下記可能
①容量の拡張
②IOPS値の変更（PIOPSボリュームのみ）
③ボリュームタイプの変更（汎用SSD→コールドHDDなど）
→CloudWatchとCloudFormationやAWS Lambdaなどで自動化も可能
>参考URL：https://aws.amazon.com/jp/blogs/news/amazon-ebs-update-new-elastic-volumes-change-everything/

・EBSスナップショットにコスト配分タグをサポート
→コスト集計ができるようになった
＝＝

・EBSスナップショットはS3に保存
・AZごとに独立。同一AZのインスタンスのみから利用可能
→しかし、Snapshotから任意のAZに復元可能
・EC2に複数のEBSを接続可能だが、反対は不可

・EBSはレプリケートされているので、冗長化は不要
・セキュリティグループによる制御の対象外。全ポートを閉じてもEBSは利用できる

・インスタンスストアVSEBS
`インスタンスストア`：揮発性。EC2のローカルディスク。仮想マシンが止まるとデータ消去。一時的なデータの置き場所などに利用。
`EBS`：永続化ストレージ。OSやDBのデータなど永続化のデータ用。

・スペックは下記の順
プロビジョンドIOPS→汎用SSD→スループット最適化HDD→コールドHDD→マグネティック

SSDの種類は下記2種類
①`汎用SSD`
I/O機能を一時的に3000IOPSまで上げるバースト機能付き
→I/O Creditが必要。CloudWatchで監視可能。上限（540万I/Oクレジット）に対するパーセント
容量：1GB～16TB
IOPS：ベースは100IOPS。最大10000IOPS
スループット：128MB/秒～160MB/秒

②`プロビジョンドIOPS`
容量：4GB～16TB
IOPS：50IOPS/1GB。最大20000IOPS
スループット：最大320MB/秒

HDDの種類は下記2種類
→小さいデータのランダムアクセスになりがちな処理、起動ボリューム、データベース、ファイルサーバー等への利用は非推奨
→ログ処理などのシーケンシャルアクセス用途。アクセス頻度が低いもの

①`スループット最適化HDD`
容量：500GB～16TB
IOPS：最大500IOPS
スループット：40MB/秒がベース

②`コールドHDD`
容量：500GB～16TB
IOPS：最大250IOPS
スループット：12MB/秒がベース

`マグネティック`
磁気ディスクタイプ
容量：1GB～1TB
IOPS：100IOPS
スループット：40MB/秒～90MB/秒
I/Oリクエスト回数による課金が唯一ある

`EBS最適化インスタンス`
EC2とEBSの独立した帯域を確保し、I/O性能の安定化

`事前ウォーミング`
Snapshotから復元したボリュームへの初回アクセス時に設定

・EBSのパフォーマンス改善
①EC2インスタンス側のスループット
EBS最適化を有効にする
EBSからのスループットの上限値に到達していないかをCloudWatchのVolume Read/Write Bytesの合計値で確認

②EBSが処理できるIOPS
CloudWatchのVolume Read/Write Opsを参照

③各EBSボリュームのスループット
CloudWatchのVolume Read/Write Bytesの合計値で確認

・Snapshot
EBSのバックアップ機能
S3に保管。2世代目以降は増分バックアップ。1世代目を削除しても復元可能
ブロックレベルで圧縮して保管するため、圧縮後の容量に対して課金
データ整合性を保つため、静止点を設けることを推奨
別AZに移動したい場合や、容量変更などもSnapshot経由で行う

・バックアップと静止点
EBSへのI/O停止→Snapshot作成指示→作成指示レスポンス→EBSへのI/O再開
※Snapshotの作成完了前にEBSへのI/O再開してよい

・Snapshotの削除
1世代目を削除しても、1世代目にしかないデータは削除されない

・リージョン間コピーをサポート
リージョン間でのコピーも可能

参考URL：https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-amazon-elastic-block-store-ebs
tmux メモ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/25325/25f841de-25ee-3c08-88ef-da6858c98da9.png)

## 参考サイト
- https://github.com/jsk-ros-pkg/jsk_common/pull/625/files
- https://qiita.com/jyotti/items/70a3a8035d767f99f93d
- https://qiita.com/satococoa/items/5e3e047569aa15187c49
- https://qiita.com/zwirky/items/adbf22abad7d7822456b

## はじめに
ステータスバーの設定などを自分でやりたくないので，素の``screen``や``tmux``を使わずに，ラッパーの``byobu``を使う．
``byobu-tmux -V``すると，``tmux``のversionが分かるが，mouse-modeの設定が2.1から変わっているので注意．
以下は2.1だとして進める．

## 4分割してそれぞれにコマンドを送る
```bash
byobu-tmux new-session -d -s "test-session" -n "aiueo"
byobu-tmux set-option prefix C-t
byobu-tmux set-option mouse on
byobu-tmux set-option mode-keys emacs
byobu-tmux split-window -h
byobu-tmux split-window -v -t aiueo.0
byobu-tmux split-window -v -t aiueo.1
```

した状態で``byobu-tmux``すると
![image.png](https://qiita-image-store.s3.amazonaws.com/0/25325/25f841de-25ee-3c08-88ef-da6858c98da9.png)
となる．

```bash
byobu-tmux send-keys -t test-session:aiueo.0 'echo 0' C-m
byobu-tmux send-keys -t test-session:aiueo.1 'echo 1' C-m
byobu-tmux send-keys -t test-session:aiueo.2 'echo 2' C-m
byobu-tmux send-keys -t test-session:aiueo.3 'echo 3' C-m
```

とすると，それぞれのpaneにコマンドが送れる．

残念ポイントとしては，

- paneにユニークな名前を付けられないこと
- status barが1行であること

前者については，

```
byobu-tmux kill-pane -t test-session:aiueo.0
```
でpaneを消すこともできるが，一旦消すとpaneのIDが0から振り直されるので，

- pane 0: program A
- pane 1: program B
- pane 2: program C
- pane 3: program D

としたときに，program Cを消してから，program Dを消す，というときに

```
byobu-tmux kill-pane -t test-session:aiueo.2
byobu-tmux kill-pane -t test-session:aiueo.3
```

ではなくて

```
byobu-tmux kill-pane -t test-session:aiueo.2
byobu-tmux kill-pane -t test-session:aiueo.2
```

としないといけない．
C言語でもa == 1 && a == 2 && a == 3をtrueにしてみたい


先日、こんな記事を書いて、Rubyで `a == 1 && a == 2 && a == 3` をtrueにしてみましたが、Cのようなレガシーな言語でも同様のことに成功しました。

https://qiita.com/shiozaki/items/53c66cea655bef08b9ea

```c
#include <stdio.h>

int main(void)
{
    int a = 1;

#define a 1 || a

    if(a == 1 && a == 2 && a == 3) {
      printf("true\n");
    } else {
      printf("false\n");
    }
    return 0;
}
```
MovableTypeを移行したら文字化けした。

#はじめに
プライベートクラウドからパブリッククラウドへMTで公開しているWebサイトを移管しました。フロント画面のほうはうまくいってそうでしたが、管理画面のほうが文字化け（「?????」になる）してしまいました。。。。


#移行時に行ったこと（この時は文字化けしてます。）
①移行元で/var/www/配下（MTの素材たち）をtarで固める。
②移行元でMT用のDBダンプファイルを取得する。
③移行先で上記を展開・インポートする。
※Apacheの設定やパーミッションも移行元と移行先で合わせます。


#文字化けの原因
**移行元と移行先のDBの文字コードが異なってました。**
MTではUTF8しか対応していないようです。


#解決策
**DBの文字コードをUTF8にしてから移行元で取得したダンプファイルを移行先のDBへインポートする。**
インポートしたあとにDBの文字コードを変更(my.cnf内に追記、mysql再起動)しても管理画面上では文字化けしたままでした。。。


#やったこと
①移行元でDBのダンプファイルを取得。
②移行先ですでに文字化けしているDB（インポート先）を削除。
③移行先のmy.cnfにUTF8になるように追記（[mysqld]と[client]の2つに明記）し、mysqldを再起動。
④移行先でDB（インポート先）を作成。
⑤移行先のDBへ取得したダンプファイルをインポート

上記①～⑤の後に管理画面を確認すると、文字化けが治っていました！！！！
vagrantとVirtualBoxを外付けSSDに移動する

# macbookの空き容量問題
先日OSのアプデをしようとしたら途中で止まり、原因を調べたところ空き容量が足りなかったためと判明。慌てて外付けSSDを購入し、容量を食っているものをそちらに移すことにした。
で、その際にVirtualBoxが思いの外、大きかったので移したのだがドラッグドロップでは（やっぱり）うまく行かなかったのでググって解決した話。

## 1.外付けSSDにディレクトリを作成
vagrant用とVirtualBox用のデータディレクトリを作成。

```
$ cd /Volumes/外付けSSD名
$ mkdir vagrant
$ mkdir virtualbox_vms
```

## 2.VirtualBoxのVM保存場所を外付けSSDに変更し、　VMデータを移動する
VirtualBoxを起動し、設定 - 一般 - デフォルトの仮装マシンフォルダーを外付けSSDに作ったvirtualbox_vmsに変更する。
そうしたらVMデータを外付けSSDに移動させる。ターミナルでちゃちゃっと移動してもいいし、ドラッグドロップで移動してもいい。
その場合、ユーザ > ホーム > VirtualBox VMsから必要なディレクトリを移動した。

## 3.VirtualBoxでVMを再設定
これでVirtualBoxを起動させると、inaccessibleと表示されている。なので、一度VMを削除して、外付けSSDに移したVMを追加して再設定する。
除去を選択し、なくなったら仮想マシン - 追加から外付けSSDから必要なVMを選択して、.vboxというファイルを選ぶ。これで再設定は完了。

## 4.vagrantのデータを外付けSSDに移動
ついでなのでvagrantデータも外付けSSDに移動した。
ただターミナルを利用せず、ドラッグドロップをしていたので該当の.vagrant.dが見つからず…。
隠しファイルを表示するように設定し直して発見し、そのまま外付けのvagrantに突っ込んだ。

## 5.vagrantの環境変数VAGRANT_HOME の設定
上記のままだと動かないので、環境変数を設定し直す。

```
export VAGRANT_HOME=/Volumes/外付けSSD名/vagrant/.vagrant.d
export PATH=$VAGRANT_HOME:$PATH
```

これで問題なく動いたが、ログアウトすると無効になると書いてあるものもあった。問題があった場合は、.bash_profileに記述した方がいいようだ。
参考：http://kiraba.jp/change-save-point-vagrant-box-and-virtual-machine/

## 6.VM起動と停止の確認
vagrantfileを作成済みのディレクトリで、いつも通りにvagrantが起動するか確認して問題なければOK。
参考：
http://easyramble.com/move-virtual-box-vms-to-external-storage.html

## 余談
今回はOKではなかったので追記。
vagrant upでなぜかvirtualboxのダウンロードが始まり、うまく行かない問題が発生。
どうやらバージョンの組み合わせが悪かったようで、vagrantをアプデし、VirtualBoxもアプデして解決した。
参考：https://hacknote.jp/archives/20991/

起動は問題なかったがmountエラーが出たのでそちらの対処にも時間がかかった。
最終的に、プラグイン「vagrant-vbguest」をインストールしてguest側が古かったのでvbguestでアプデして解決した。
参考：
https://qiita.com/ozawan/items/9751dcfd9bd4c470cd82
Phoenixのeexでindex番号を表示する方法

Enum.with_indexを利用すれば番号を表示することができる

```elixir
# ~ 略 ~
<%= for {content, i} <- Enum.with_index(@list) do %>
        <tr>
            <th scope="row"><%= i %></th>
            <td><%= content.name %></td>
            <td><%= content.experience %></td>
        </tr>
<% end %>
# ~ 略 ~
```
地域メッシュをブラウザ上で作成するライブラリを作成した話

## どういったものか
ブラウザ上で簡単に指定した地域メッシュをGeoJSON/esri JSON/Shapefileで作成するライブラリです。  

![動作イメージ](https://user-images.githubusercontent.com/35097962/35183353-e1ca036e-fe27-11e7-90bb-a3b040464a0e.gif "動作イメージ") 

[https://github.com/MALORGIS/jisX0410](https://github.com/MALORGIS/jisX0410)  
  
  
サーバ側/クライアント側/WebWorkerとして動作することができます。
(全メモリ展開なのでサーバ側で使用する機会はほぼないと思いますが。)  

## なぜ作成してどういったときに使用するのか
出来ることは下記のリストの通りです。
- 地点→指定種別のメッシュ作成
- 範囲→指定種別のメッシュ作成
- メッシュコード→メッシュコードの種別のメッシュ作成

インストールソフトが普段使っているものと違う時やプラグインが入っていない時にすぐに確認用のメッシュデータが欲しいと言う非常に起きにくい状況で役に立ちます。
本来は統計データと合わせて色塗りや即時消費される使い方でループを回すべきですがその時の参考コードとなるのではないかと思います。

## 実装について
一応テストコードとコード網羅率とる程度はしています。
APIリファレンスも生成できて、しばらく触っていなくてもインテリセンスが効くTypescriptの実装のお勉強用でもあります。

と言いつつ、Require.js/WebPack/Browserify使っていないのは趣味です。
コードを小分けにしてexport/importで使用するのが通常系だと考えた上で参考になりそうなら参考にしてください。

UIは割と手抜きなのであまり参考になりませんが、一応Leaflet.jsに地理院地図を使用しています。

[ちょっとした中身の話と修正](https://qiita.com/MALORGIS/items/78289086877b4a8f87ce)
Arduino＋IRカメラ＋ダンボール工作でニンテンドーLABOモドキ

##すごいぜ任天堂
ムービーを見た瞬間、やっぱり打ちのめされた。
[NINTENDO LABO](https://www.nintendo.co.jp/labo/)
![キット](https://www.nintendo.co.jp/labo/kit/img/box_variety.jpg)
さすが任天堂。

だけど4月20日までとてもまちきれないので、自分で作ってみた。

##どうやって動いているのか
ムービーを見ると、switchのリモコン側に組込まれたIRカメラとダンボールに貼り付けた反射材を使っているらしい。同様のIRカメラはWiiにも搭載されていて、世界中でハックされている。有名なのが[ジョニー・リー氏](https://www.youtube.com/watch?v=QgKCrGvShZs)。必見！

WiiリモコンはBluetoothとしてPCから認識できるので、こちらを使う方法もあるが、今回はDFRobotで入手できる同等のカメラモジュールを使用します。

##部品その１:IRポジションカメラ
[IR Positioning Camera For Arduino](https://www.dfrobot.com/product-1088.html)

![IR Positioning camera](http://image.dfrobot.com/image/cache/data/SEN0158/IMG_0091e-900x600.jpg)

こちらは1ｍ〜3m先に光っている赤外線LEDのXY位置を取得できるカメラで、最大4点の位置が抽出できる。インターフェースはI2Cなので大抵のものに接続できる。ただしアドレスは固定なので複数のカメラを接続出来ないのが残念。


##部品その2:反射シール(失敗）
当初、本家と同じようにカメラ側から赤外線LEDを何灯か点灯して、ダンボールに反射材シールを貼って動きを検出しようとしました。ところがホームセンターで販売しているものが反射率が良くなく、検出がかなり不安定でした。恐らくモーションキャプチャのターゲットに使うような、銀色の反射材が手に入ればうまくいくと思います。

結局、今回はボタン電池と赤外線LEDを動かす対象に固定して、動きを検出する方式に変更しました。

##部品その3:Arduino
僕は大好きArduino。今回はArduinoMicroを使用した。基本的に大抵のArduinoが使えるはず。流行のESP-WROOMモジュールを使ってWifiに情報を流したり、ラズパイをつないでも面白いと思います。
今回Microを使ったのは、ライブラリを使ってMIDIキーボードを作ろうと思いました。

##接続
ArduinoとIRカメラは以下のように接続します。他のボードでもI2Cポートがあれば簡単に接続できると思います。
![Connection](https://github.com/NaohiroIIDA/IRCameraMidi/blob/master/image/connection2.png?raw=true)

##Arduinoライブラリ
以下の2点を使用しました。
[DFRobotIRPosition](https://www.arduinolibraries.info/libraries/df-robot-ir-position)
[MIDIUSB](https://www.arduinolibraries.info/libraries/midiusb)

##Arduinoスケッチ
こちらにおいておきます。
https://github.com/NaohiroIIDA/IRCameraMidi

ライブラリのサンプルにほぼ書いてありますが、

```arduino:IRCameraMidi.ino
if (myDFRobotIRPosition.available()) {
  
    for (int i = 0; i < 4; i++) {
      positionX[i] = myDFRobotIRPosition.readX(i);
      positionY[i] = myDFRobotIRPosition.readY(i);
    }

    now_ch = map(positionX[0], 0, 650, 35, 85);

    if (positionX[0] == 1023) {
      now_ch = 0;
    }
```

positionX[i],positionY[i]に赤外線の光点のXY座標が取得できます（見つからない場合は1023が入ります）。
このIRセンサは最大4点の光点を、検出範囲（H:33°／V:23°）の間でで取得することが出来ます。
このデータをmap関数で音程に変換しています。これをMIDIデータとして出力すれば、ダンボールを動かすと楽器のようにコントロールが出来ます。

##実演
![youtube](https://github.com/NaohiroIIDA/IRCameraMidi/blob/master/image/youtube.png?raw=true)(https://youtu.be/CBqcIZDoV9w)

##応用
LeonardやMicroなど32u4を搭載したarduinoでは、USBキーボードやマウスのエミュレートが出来るので、同じ仕組みをつかって入力装置を作るのも面白いと思います。IRセンサはターゲットが赤外線LEDと電池を使って自光する方式だと3m位先でも検出できるので、より広い範囲を見渡す事ができます。
###皆様、よいハッキングを！！
【Chrome Developer Tools】JavaScriptでデバッグログを出力する【console.log()】

以前、[【バグ発見のコツ】二分探索でバグ発生個所を特定する](https://qiita.com/mtanabe/items/91f93b236b89cf11057a)という記事で、「printデバッグするとよい」的なことを書きました。
そんなわけで、JavaScriptのprintデバッグを、ChromeのDeveloperToolsを使ってやってみようと思います:mushroom:

# console.log()を使う
Javaでいうところの```System.out.println()```、Rubyでいうところの```print```のように、JavaScriptにも同等の機能を持つメソッドが用意されてます。
それが

```javascript
console.log()
```
です。
引数に何でも入れられるので、

- 文字列を入れてif文の分岐条件の通過状態を見る
- 変数を入れて値の代入状態を見る

など、デバッグでやりたいことのほとんどが```console.log()```で対応可能だと思います。

では、実際にコンソールに出力してみましょう。

# 検証用プログラム
```HTML
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
  <title></title>
  <script type="text/javascript">
    function button2Push() {
      if (document.getElementById("vesi1").checked) {
        console.log("なす");
      }
      if (document.getElementById("vesi2").checked) {
        console.log("ピーマン");
      }
      if (document.getElementById("vesi3").checked) {
        console.log("かぼちゃ");
      }
      if (document.getElementById("vesi4").checked) {
        console.log("えだまめ");
      }
      console.log("-----------------------");
    };
  </script>
</head>
<body style="margin: 30px;">

  <p style="font-size: 120%;margin: 0px;"><b>お題</b></p>
  <p>すきな野菜を選んでください。</p>

  <form name="test2">
    <input type="radio" id="vesi1" />なす
    <br />
    <input type="radio" id="vesi2" />ピーマン
    <br />
    <input type="radio" id="vesi3" />かぼちゃ
    <br />
    <input type="radio" id="vesi4" />えだまめ
    <br />
    
    ----------------------------------------------------------------------------
    <br />
    <input type="button" id="button2" name="button2" value="押してみる。" onclick="button2Push();">
  </form>

</body>
</html>
```
ブラウザに表示されたラジオボタンを適当に選択し、「押してみる。」ボタンを押下すると、button2Push()メソッドが実行される・・・という、簡単なHTML＆JavaScriptです。
選択したラジオボタンによって通過するif文が変わるので、それをconsole.log()で観察してみます。

# １．consoleタブを開く
Chrome Developer Toolsについての記事なので、まずはF12キーでChrome Developer Toolsを起動してください。
その後、consoleタブを開きましょう:pig:
![001_075.png](https://qiita-image-store.s3.amazonaws.com/0/188980/974725f5-53fc-b42f-a8b5-2be2ae64e3f2.png)

# ２．JavaScriptを実行する
適当にラジオボタンを選択し、「押してみる。」ボタンを押下します。
すると、button2Push()メソッドの実行結果がconsoleタブの中に出力されます。
![002_075.png](https://qiita-image-store.s3.amazonaws.com/0/188980/1aaf721f-e7bf-e013-cc46-8adef3b44bc4.png)
実行結果の右側には、

- どのHTMLファイルの
- 何行目のconsole.log()なのか

が出力されます。

# まとめ
JavaScriptでprintデバッグしたいときは、```console.log()```を使う。

変数をあれこれ加工していても、```console.log()```を片っ端から書いていけば、変数の状態がわかりやすくなりますね:hibiscus:
Webpackでの一括読み込み（その2）

以前に[Webpackでフォルダ内の全ファイルを一気にrequireする](https://qiita.com/jkr_2255/items/d23e66323857d3189a00)という記事（以下、「前記事」とします）を書いたのですが、これでは微妙に気になる点が出てきました。

今回は、その点をクリアするための別な手法を紹介します。

# メリットとデメリット

前記事で挙げた、`require.context`を使う手法のメリットは、以下のようなものとなります。

* Webpackの標準機能で片付いて、他のライブラリを使う必要がない
* ファイル名もJavaScriptで取得できるので、「`require`した結果をフォルダ構造に従って変数に代入する」というような操作も、そのまま実装できる

一方で、上2つのメリットはそのままデメリットに転じえます。

* `require.context`はWebpack独自仕様なので、Webpackにロックインされてしまう
* 「読み込みの副作用だけが必要で、結果は使わない」というような事例を代表として、ファイル名が全く不要な場面でも、ファイル名までバンドルに含まれてしまい、容量を消費する

今回は、後者の「不要なファイル名が容量を消費する」という点が気になったので、改善のために別手法を取ってみることにしました。

# globという「共通言語」

Unix系で、複数のファイルを一気に選択するための手法として、ワイルドカードを拡張した「glob」が一般に使われます。そして、このglobを読み込みに使えれば…ということはみんな考えるもので、Browserifyには[require-globify](https://www.npmjs.com/package/require-globify)が、Rollupには[rollup-plugin-glob-import](https://www.npmjs.com/package/rollup-plugin-glob-import)があるなど、各ツールで使えるようになっています。そして、もちろんWebpackにも[import-glob-loader](https://www.npmjs.com/package/import-glob-loader)のようなglob対応ローダーがあります[^1]。

Webpackの`import-glob-loader`は、プレローダーとして仕掛ける、あるいは必要箇所だけ`import-glob-loader!./path/to/import.js`のようにして呼び出すこととなります。

```webpack.config.js
module: {
    rules: [{
        test: /\.js$/,
        enforce: "pre",
        loader: 'import-glob-loader'
    }]
}
```

## 注意点

使う上で、いくつか注意点があります。

* 名前の通り、デフォルトでは`import`のみに対応します。設定すれば`require`に反応させられなくもないかもしれませんが、どうなるかはわからないです。
* `import`のある行で、ファイル名以外の部分はすべてコピーされますので、JavaScriptで使う場合は、副作用のみを拾う`import '(glob-pattern).js';`の形以外は事実上使えません（変数名が衝突してしまいます）。
* CSS系の`@import`にも使えます。
* これは`import-glob-loader`に限らないWebpackの挙動だと思われるのですが、`import`で書いたものは宣言だからかモジュールの最上部に移動します。ロード順を管理する必要がある場合に`import`と`require`を混ぜると、思わぬ挙動になりかねないので、そんなことは避けましょう。

## 実際にやってみた効果

200個ほど`require`しているものを`require.context`から移行してみたところ、バンドル全体で90.0KB→88.2KBと、1.8KBほどの削減になりました。

# 参考

* [Laravel-MixでSASSのglob importを使う](https://qiita.com/kimama1997/items/f8f448ef6b14245e8a9d)

[^1]: なお、これらはすべてglob部分を[node-glob](https://github.com/isaacs/node-glob)に依存しているので、対応するglob文法も同じです。
【AWS SDK for PHP】1000以上のファイルがあるS3バケットの内容を取得する

# やりたいこと
PHPでS3バケットにあるファイルのリストを取得する際、AWS SDK for PHPの[ListObjectsメソッド](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#listobjects)や[ListObjectsV2メソッド](https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#listobjectsV2)が使えます。v1とv2ではパラメーターの設定方法や返り値が若干異なるだけで中身は同じです。どっちでもいいのですが今回はv2でいきます。

しかし困ったことに一度に1,000件までしか取得できない...さすがにそれは不便すぎる



# 解決策
バケットにオブジェクトが1000より多く存在する時、ListObjectV2の返り値の```IsTruncated```がtrueになることを利用します。
_ちなみに'truncated'は**切り捨て**という意味で、取りこぼしたやついるよ〜っていう主張でしょうね。_
さて、```IsTruncated```がtrueの時、返り値の```NextContinuationToken```に、今取得したリストの次から取得するためのトークンが入っています。これをリクエストパラメーター```ContinuationToken```に入れてあげてもう一回1000件取得...を繰り返していけばいいわけです。

結果的にコードは次のようになりました。

```php
use Aws\S3\S3Client;

$config = [
	'credentials' => [
		'key' => '*** アクセスキー ***',
		'secret' => '*** シークレットキー ***',
	],
	'region' => '*** リージョン ***',
	'version' => '2006-03-01'
];
$bucket = '*** バケット名 ***';
$prefix = '*** プレフィックス ***';


$client = S3Client::factory($config);

$object_list = GetObjectList($client, $bucket, $prefix);



function GetObjectList($client, $bucket, $prefix, $continuous_token=null)
{
	$result = $client->ListObjectsV2([
		'Bucket' => $bucket,
		'Prefix' => $prefix,
		'ContinuationToken' => $continuous_token
	]);

	$object_list = [];
	if (isset($result['Contents'])) {
		foreach ($result['Contents'] as $object) {
			// 名前がxxxx/のオブジェクト(フォルダ)はリストに含めない
			if(substr($object['Key'], -1, 1) !== '/') {
				$object_list[] = 's3://'.$bucket.'/'.$object['Key'];
			}
		}

		if($result['IsTruncated'] === true) {
			$object_list = array_merge($object_list, GetObjectList($client, $bucket, $prefix, $result['NextContinuationToken']));
		}
	}

	return $object_list;
}
```