OmniAICreator/Qiita-1.07M huggingface dataset:
NHK番組表APIからJSONデータを取得してjqで編集する（データ編集編） 

# はじめに
[前回](https://qiita.com/Aco-gt/items/44c7bdb6cd2dfb645dc0)は、NHK番組表APIからJSONデータを取得する方法を説明しました。
今回は、JSONデータをjqコマンドで編集して必要な情報（開始日時、番組時間、番組タイトル）を取得したいと思います。

# 1. JSONデータをjqで編集するスクリプト
``` 
edit_sample_json.sh

#!/bin/sh

title_str="基礎英語３|ラジオ英会話"

cat ./sample.json \
 | jq -r --arg reg_str $title_str '

    def mk_sec(t): t | strptime("%Y-%m-%dT%H:%M:%S+09:00") | mktime;
    def mk_attime(s): mk_sec(s) | strftime("%H:%M %m/%d/%y");

    .list.r2[]
      | select(.title | test($reg_str))
      | [ mk_attime(.start_time),
          mk_sec(.end_time) - mk_sec(.start_time),
          .title ] | @csv
' 
```
#2. スクリプト実行結果
```
$ ./edit_sample.json
"06:30 11/03/17",900,"基礎英語３「Ｒｅｖｉｅｗ２４」"
"06:45 11/03/17",900,"ラジオ英会話「スペシャル・ウィーク」（復習）"
"12:25 11/03/17",900,"ラジオ英会話「スペシャル・ウィーク」（復習）"
"15:45 11/03/17",900,"ラジオ英会話「スペシャル・ウィーク」（復習）"
"19:15 11/03/17",900,"基礎英語３「Ｒｅｖｉｅｗ２４」"
"21:30 11/03/17",900,"基礎英語３「Ｒｅｖｉｅｗ２４」"
"21:45 11/03/17",900,"ラジオ英会話「スペシャル・ウィーク」（復習）"
``` 
※再放送を識別する情報は、提供されるJSONデータには含まれていません。重複を除外したい場合は、タイトルをuniqにする処理が必要です。

#3. スクリプト解説
* 特定の番組情報取得

APIで取得したJSONには
"title": "基礎英語３「Ｒｅｖｉｅｗ２４」"
のように放送日固有のタイトルが格納されているので、「基礎英語３」の情報を毎日取得したいと思ったらタイトル行と部分一致させて情報取得する必要があります。（番組をシリーズで識別するためのキーがあるはずと探してみましたが見つかりませんでした。）
jqの組み込み関数にtest()があり、正規表現が使用できるのでこれを使用しています。
「基礎英語３」と「ラジオ英会話」のデータを取得したかったのでパイプ「|」でつないで正規表現文字列を作っています。
title_str="基礎英語３|ラジオ英会話"
オプション --argを使用して、jqスクリプト内で使用可能な変数を指定しています。

正規表現文字列の部分は、引数で受け取るようしてもいいし、対象の番組がたくさんある場合は、以下のやりかたでファイルから作成するようにしてもいいと思います。

```
1.データを取得したい番組名を入れたファイルを作成する
cat ./title.txt

基礎英語３
ラジオ英会話
番組３
番組４
番組５
```
```
2.ファイルを読み込んでパイプでつなぐ
title_str=$(echo $(cat ./title.txt) | sed -e "s/\s/|/g")

echo $title_str
基礎英語３|ラジオ英会話|番組３|番組４|番組５
```

* 番組時間の取得

開始時間と終了時間は以下のようにiso形式で保存されています。
"start_time": "2017-11-03T06:45:00+09:00",
"end_time": "2017-11-03T07:00:00+09:00",

時刻のフォーマット変換と計算が必要なのでiso形式をjqの組み込み関数でUNIX時間に変換します。
スクリプトが長くなるので関数として定義しました。

UNIX時間（秒）の算出を関数化しました。
def mk_sec(t): t | strptime("%Y-%m-%dT%H:%M:%S+09:00") | mktime;

UNIX時間（秒）を元に必要な時刻フォーマットに変更しています。（atコマンド用のフォーマット）
def mk_attime(s): mk_sec(s) | strftime("%H:%M %m/%d/%y");

* 文字列フォーマット

@csvを指定して出力される文字列をCSV形式にして出力しています。
csvにしておけば、このあとそれぞれの値が扱いやすくなると思います。

#4. さいごに
当初、JSONの編集をawkでやっていたのですがスクリプトが思いのほか長くなってしまいました。iso形式の扱いがひとつのネックでした。その点、jqは時刻の扱いが楽にできたのでかなり短くまとめることができました。jqに慣れてしまえば、JSONデータの編集がかなり楽になると思います。スクリプトの説明がかなりおおざっぱになってしまったので質問があれば気軽にコメントしてください。
VirtualBox 5.0.28でWindows 10を実行するときの3Dアクセラレーションの問題

# 問題
- VirtualBoxのVMにWindows 8.1をインストールし、Windows 10にアップグレードしていた。
- VMにはVirtualBox Guest Additionsをインストールしていた。
- VMのWindowsをバージョン1709(Fall Creators Update)にアップデートした。
- 「管理者権限で実行」を試みるとUACで「はい」を選んだ後に「ファイル システムのエラーです (-1073741819)。」と言われ、実行できなくなった。
- あらゆるインストーラが使用できず、VMの使用の継続が困難となった。

# 環境
macOS 10.13 + VirtualBox 5.0.28 + Windows 10 Version 1709

# 解決策
1. VMのWindowsをシャットダウン
2. VirtualBoxの仮想マシン一覧から対象のVMを選択し、VMの設定の画面を開く
3. 設定画面の「ディスプレイ」>「スクリーン」>「アクセラレーション」>「3Dアクセラレーションを有効化」のチェックを外し、「OK」を押して設定を終了。
![Uncheck3DAcceleration.png](https://qiita-image-store.s3.amazonaws.com/0/143071/3cffccf0-551a-3fc2-27bf-65d9da942a86.png)

4. VirtualBoxをバージョン5.0.30以上にアップデート
5. VMを起動し、Guest Additionsをインストール
6. VMをシャットダウンし、「3Dアクセラレーションを有効化」の設定を元に戻す

# 原因
この節には調べたことを書くだけなので、読まなくても良いと思います。

## 「ファイル システムのエラー」
- -1073741819は32ビット符号付整数で表すと0xC0000005。([参考](https://answers.microsoft.com/ja-jp/windows/forum/windows8_1-performance/ファイルシ/9aae9497-beb8-4658-86df-3ec79f00129b?auth=1))
- 0xC0000005はSTATUS_ACCESS_VIOLATION([参考](https://msdn.microsoft.com/en-us/library/cc704588.aspx))
    - ここからは何もわからなさそう

## エラーログを見る
- Windowsでエラーログを見る方法を知らないので[検索](https://www.google.co.jp/search?q=windows+%E3%83%AD%E3%82%B0+%E7%A2%BA%E8%AA%8D&ie=UTF-8)
    - 「イベントビューア」というのを使うらしい
- 左下のWindowsボタンを右クリックすると「イベントビューア」があったので開く
    - 結構いろいろできるのでこの機能は便利。なんで左クリックと右クリックを逆にしないのか……。
- 右ペイン「Windows ログ」>「Application」を見ると、「ファイル システムのエラー」のたびにエラーが出ていた
    - 「タイプ1000 Application Error」「鍾愛が発生しているモジュール名: VBoxOGLpackspu.dll」
    - VirtualBox Guest Additionsが悪さをしてそう。

## VBoxOGLpackspu.dll
- ともかく「VBoxOGLpackspu.dll」で検索
    - [VirtualBox 5.0.28で管理者権限が使えない](https://www.virtualbox.org/ticket/17082)というそれっぽいバグを発見
- [バグの最新のコメント](https://www.virtualbox.org/ticket/17082#comment:19)より3Dアクセラレーションをオフにすれば回避できると判明

# 参考にしたページ（再掲・解決までに見たもののみ）
https://answers.microsoft.com/ja-jp/windows/forum/windows8_1-performance/ファイルシ/9aae9497-beb8-4658-86df-3ec79f00129b
https://www.google.co.jp/search?q=windows+%E3%83%AD%E3%82%B0+%E7%A2%BA%E8%AA%8D&ie=UTF-8
https://www.virtualbox.org/ticket/17082

# コメント
Guest Additionsが怪しいのは初めから分かっていたが、Guest Additionをアップグレードするのにもアンインストールするのにも管理者権限が必要なのでどうしようもないと思ってしまった。
迷いながらクリーンインストールまでしてしまった。（しかもそれでもVirtualBox Guest Additionsは消えなかった。）
再構築めんどくさい。
改めてWindowsにTomcatインストールするメモ

# 目的
- 仕事だけでなく、単純な趣味として、勉強として家で使うため。
    - Webアプリ試したい
    - Webアプリ開発したい
    - 個人ブログ（ローカル）つけたい
- tomcat7ばっかり使ってたので9を試してみる
- 一から設定を思い出す。<small>そしてQiitaへの投稿を習慣づける</small>

# 準備
1. [Java 1.9](http://www.oracle.com/technetwork/java/javase/downloads/jdk9-downloads-3848520.html)  Accept icense AgreementしてWindowsを落とす
1. [Tomcat9バイナリ](https://tomcat.apache.org/download-90.cgi) Windows 64bitあたりを

# Javaインストール
- インストーラを起動してインストール
    - 場所をD:\dev\runtime\java\jdk1.9.*_***にしておくと便利そう
- 環境変数設定
    - システムのプロパティ→環境変数設定からPathとJAVA_HOMEを設定
    - Pathは%JAVA_HOME%\binにしておくとあとからバージョン変えやすくて便利
    - 念のためjava -versionやecho %JAVA_HOME%で正しいかを確認

# Tomcatインストール
- zip解凍
    -  場所をD:\dev\container\tomcat9にしておくと便利そう
    -  tomvat9w.exeを起動してブラウザでlocalhost:8080を開いて確認
-  サービス化
    -  コマンドプロンプトでtomcatインストール場所まで移動（dならd:とかした後cd）
    -  service.bat install tomcat9
-  メモリなどの設定
    -  コマンドプロンプトでtomcat9wと入力してGUI画面起動
        -  StartupTypeとかも決めておく
        -  なにはともあれJava設定
            -  InitialとMaximumを4GBぐらいでしたり
            -  引数に色々入れて、チューニング

```
-server
-XX:MaxPermSize=512m -XX:PermSize=512m -XX:SurvivorRatio=2 -Xmn2048m -Xmx4096m -Xms4096m
-XX:+PrintGCDetails -Xloggc:${CATALINA_BASE}/logs/gc.log.${DATE}
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=3333 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=true
```

# Tomcat Managerを使えるようにする
賛否はあるだろうけど便利だし
confフォルダにあるtomcat-users.xmlの最後の行あたりに以下を追加

```
<role rolename="manager-gui"/>
<user username="tomcat" password="s3cret" roles="manager-gui"/>
```


# 他、設定とか参考

- [Tomcat ( For Windows ) 環境構築 IT専科](http://www.itsenka.com/contents/development/environment/windows/tomcat/)
- [Tomcatをツールで運用し、設定の基礎を知る (1/3)](http://www.atmarkit.co.jp/ait/articles/0711/20/news125.html)
- [連載 :  いまさら聞けないTomcat〜JSPサーバ構築のキソ Tomcatのサーバ設定](https://thinkit.co.jp/free/article/0708/2/8)
- [Tomcat の初期設定まとめ](https://qiita.com/hidekatsu-izuno/items/ab604b6c764b5b5a86ed)
EdgeRoute Xの購入とファームウェアアップデート


# Edge RouterXを購入
海外からの輸入も考えたけれど、送料とか色々考えるとamazon.co.jpで買っても値段はそんなに変わらないため、amazonでポチッと。

# 初期設定
ER-Xのeth0にLANケーブルを接続する。
初期はDHCPが無効なためclientの端末のIPアドレスを手動で変更する。
今回だと下記で設定した。ちなみにER-Xの初期IPは192.168.1.1/24

```
IP: 192.168.1.10
netmask: 255.255.255.0
gateway: なし
```

edgegrouterにsshでアクセスする。
先程書いたとおり、edge routerの初期IPは192.168.1.1/24でuser,passともにubnt

```
~ » ssh ubnt@192.168.1.1                                         onodes@Capser2
Welcome to EdgeOS

By logging in, accessing, or using the Ubiquiti product, you
acknowledge that you have read and understood the Ubiquiti
License Agreement (available in the Web UI at, by default,
http://192.168.1.1) and agree to be bound by its terms.

ubnt@192.168.1.1's password:
Linux ubnt 3.10.14-UBNT #1 SMP Mon Nov 2 16:45:25 PST 2015 mips
Welcome to EdgeOS
ubnt@ubnt:~$
```

# Firmware update
届いたEdgeRouterがv1.7.1だったので、最新にupdateする。せっかくなのでCLIで実施

公式サイトから最新版のfirmwareをダウンロードする。tarファイルになってるけど、特に解凍せずにそのままscpでERに送りつける。
送りつけた後は、EdgeRouterの中で適用を行う。

```
Linux ubnt 3.10.14-UBNT #1 SMP Mon Nov 2 16:45:25 PST 2015 mips
Welcome to EdgeOS
Last login: Thu Jan  1 01:17:03 2015 from 192.168.1.10
ubnt@ubnt:~$ ls
ER-e50.v1.9.7+hotfix.4.5024279.tar (←このファイルが送ったやつ）
```

## 実際に適用する

```
ubnt@ubnt:~$ add system image ER-e50.v1.9.7+hotfix.4.5024279.tar
Checking upgrade image...Done
Preparing to upgrade...Done
Copying upgrade image...Done
Removing old image...Done
Checking upgrade image...Done
Copying config data...Done
Finishing upgrade...Done
Upgrade completed
```

## 適用後system imageを確認する。
```
ubnt@ubnt:~$ show system image
The system currently has the following image(s) installed:

v1.9.7+hotfix.4.5024279.171006.0255 (default boot)
v1.7.1.4821926.151103.1114     (running image)

A reboot is needed to boot default image
```

rebootすれば、1.9.7がで立ち上がるとのことなので、rebootする。

```
ubnt@ubnt:~$ reboot
Proceed with reboot? [confirm]y

Broadcast message from root@ubnt (pts/0) (Thu Jan  1 01:22:49 2015):

The system is going down for reboot NOW!
ubnt@ubnt:~$
ubnt@ubnt:~$ packet_write_wait: Connection to 192.168.1.1 port 22: Broken pipe
```

再起動後再びER-Xにログインする。

```
ubnt@192.168.1.1's password:
Linux ubnt 3.10.14-UBNT #1 SMP Wed Aug 30 02:34:16 PDT 2017 mips
Welcome to EdgeOS
ubnt@ubnt:~$ show system image
The system currently has the following image(s) installed:

v1.9.7+hotfix.4.5024279.171006.0255 (running image) (default boot)
v1.7.1.4821926.151103.1114
```
running imageがv1.9.7に変わっていることがわかる。
RaspberryPi で AWS CLI を使う方法

RaspberryPiに、

```bash
sudo apt install awscli
```

でインストールしたものは、バージョンが古いので、パラメーターが最新のものと異なります。そこで最新の AWS CLI をインストールする方法です。

```bash
sudo pip3 install awscli --upgrade
```

バージョンを確認すると

```text
aws --version
aws-cli/1.20.40 Python/3.7.3 Linux/5.10.60-v7l+ awscrt/0.12.1 botocore/1.21.40
```

最初に aws コマンドを実行すると、

```text
You must specify a region. You can also configure your region by running
 "aws configure".
```

というコマンドが出てきます。

そうしたら、

```bash
aws configure
```

を実行して、
AWS Access Key ID
AWS Secret Access Key
Default region name
Default output format
を入れます。
region name は東京ならば、ap-northeast-1
output format は、json
と入れて下さい。
blenderで非表示のUVマップを全削除するスクリプト

このようにいつの間にか不要なUVマップがついていて、すべてのオブジェクトから非表示のUVマップを消す場合に使えます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69889/12b8c334-32b8-3abd-225b-4a2f5ed97f02.png)

```py:deleteAllInactiveUvmaps.py
impoprt bpy

scene = bpy.context.scene
for obj in scene.objects:
  if obj.type == 'MESH':
    uv_textures = obj.data.uv_textures
    for uv in uv_textures:
      if uv.active_render == False and uv.name !='NGon Face':
        print('remove uv :'+uv.name+' of '+obj.name)
        uv_textures.remove(uv)
```
blender上のPythonコンソールなどから実行してください
コマンドが失敗したときにシェルの顔文字があわててたら、可愛いしわかりやすいよね

どうも、かちおです。突然ですが、シェルのプロンプトって普段味気ないですよね。カスタマイズしている人でも、色やgitブランチ表示していたりする程度だと思います。
そこで、今回は、直前のコマンドのリターンコードが0かそれ以外か(True or False)を判断し、失敗していたらプロンプトの顔文字が慌てるようにしようと思います。

※この記事の方法はzshのみに対応しています。

## 結果
![k.png](https://qiita-image-store.s3.amazonaws.com/0/154157/6b3b3649-6739-1971-41fc-2af373091c1c.png)

コマンドが正常に動いているときは

```
（」・ω・）」うー▶~ $ ❯
```

と表示されていますが、コマンドの返り値が0以外だと

```
＼（・ω・＼）SAN値！~ $ ❯
```

に変わります。また、右のプロンプトもそれぞれ`＼（・ω・＼）にゃー！`と`（／・ω・）／ピンチ！`に変化します。

# 方法

zshのプロンプトの文字は、`$PROMPT`という環境変数で設定されています。既にpowerline等のテーマを導入シている場合は、既に登録されていると思うので、テーマを読み込んだあとに、テーマが設定した文字列を変更してみてください。上書きしてしまうと、せっかくのテーマが表示されなくなってしまいます。

基本的には、`$PROMPT`に入れた文字がそのままシェルのプロンプトに表示され、その中で特殊文字だけが変換されます。

特殊文字は`%`で始まり、文字色を変更、背景色を変更、コマンドの実行結果を取得、環境変数を取得などができますが、ここでは「直前のコマンドの返り値によって分岐する」という記法を使います。特殊文字については http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.html に詳しく乗っているので参考にしてください。

コードとしては、以下のようになっています。

```zsh:zshrc
if [ ${UID} -eq 0 ]; then
        PROMPT="%K{green}%B%F{black}ROOT%b%k %F{cyan}%~ %f$ "
else
        UUU="%B%F{white}（」・ω・）」うー▶%b"
        NYA="%B%F{white}\（・ω・\）にゃー！%b"
        SAN="%B%F{red}＼（・ω・＼）SAN値！%b"
        PIN="%B%F{red}（／・ω・）／ピンチ！%b"
        PROMPT="%K{green}%(?,${UUU},${SAN})%k%F{cyan}%~ %f$ ❯ "
        RPROMPT="%K{green}%(?,${NYA},${PIN})%k${vcs_info_msg_0_}"
fi
```

最初に`$UID`がゼロかどうか確認しているのは、ROOTだったらプロンプトを変えたいからです。rootユーザーなんてめったになりませんが、もしその場合はパット見分かるようにしています。

まず、`$UUU`、`$NYA`、`$SAN`、`$PIN`には、それぞれ表示したい顔文字を代入しています。%Bで太字、%F{color}で文字色指定、%bで装飾リセットです。
こうやって分けている理由は、単純に見やすいからです。

そして、最終的に`$PROMPT`に代入をしています。%(?,a,b)で、直前のコマンドの返り値が0ならa、そうじゃないならbを表示することができます。そしてそこに先程設定した`$UUU`や`$SAN`を指定しています。`$RPROMPT`もやっていることは変わりません。
また、%Kで背景色の変更、%~でカレントディレクトリのパスを表示させています。

これで、コマンドが失敗するとプロンプトが慌てて可愛くなります。

![k.png](https://qiita-image-store.s3.amazonaws.com/0/154157/ff3fbcbf-b6c3-22ae-dd6e-ea3ec5c61526.png)

----

grepやシェルスクが失敗しても、これならひと目でわかりますね。ぜひ有効活用してください。
scl python27でcertbot-autoがpython 2.6 DeprecationWarning を出してくる


```
# scl enable python27 "/opt/certbot/certbot-auto renew --no
-self-upgrade"                                                                
/opt/eff.org/certbot/venv/lib/python2.6/site-packages/cryptography/__init__.py:26: DeprecationWarning: Python 2.6 is no longer supported by the Python core team, please upgrade your Python. A future version of cryptography will drop support for Python 2.6
  DeprecationWarning

# scl enable python27 "python -V"                             
Python 2.7.13 

# scl enable python27 "which python"
/opt/rh/python27/root/usr/bin/python
```

- certbot-auto初回起動時のbootstrapがpython26で動いていた？
- `/opt/eff.org` を一度消すと再度bootstrapが走るのでパッケージを入れ直す
    - 他にbootstrapを起動する方法があればそちらでもOK

```
# sudo rm -rf /opt/eff.org
# scl enable python27 "/opt/certbot/certbot-auto renew --no-self-upgrade"
Bootstrapping dependencies for RedHat-based OSes... (you can skip this with --no-bootstrap)
yum is /usr/bin/yum
.
.
（略）
.
.
-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/xxx.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal

-------------------------------------------------------------------------------

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/xxxx/fullchain.pem (skipped)
No renewals were attempted.
-------------------------------------------------------------------------------
```
SDAccelを用いた回路設計について　その１

#概要
現在，CPUやGPU，FPGAなどの異なる演算デバイスを組み合わせた並列計算機を構成して，演算能力を向上させ，数値シミュレーションを高速化する手法が取られています．

開発環境が並列計算機を構成するプロセッサのベンダに依存しており，ソフトウェアの可搬性を維持しつつより高性能なデバイスへの乗り換えが困難であるといった問題があります．

この問題を解決する手法の一つにOpenCL(Open Computing Language)を用いる事が挙げられます．

OpenCLはCベースの言語を使用して，FPGA，GPU，CPUなど様々なプラットフォームで，実行可能なコードを開発できますが，開発対象となるターゲットボードにより開発工程が異なります．

例えば，Intel社（旧Altera社）のボードをターゲットボードとする場合は，Intel SDK for OpenCLという開発ツールを使うことでFPGAで実行可能なコードを開発できます．

一方，Xilinx社のFPGAを用いる場合は，SDAccelという開発ツールを使う必要があります．

本記事では，SDAccelを用い，FPGA上でOpenCLを実行する方法について紹介します．

#開発環境について
SDAccelを使うには，2つ条件があります．

1.　SDAccelに対応したxilinx社製のボードを購入する．
2.　SDAccelのライセンスを購入する．

本記事掲載日（2017/11/3）現在，SDAccelを使ってFPGAボードを開発するには，SDAccelに対応したボードを購入する必要があります．SDAccelに対応したボードは以下のサイトに載ってます．

[SDAccelに対応したボード一覧](https://japan.xilinx.com/products/design-tools/software-zone/sdaccel.html#boardskits)

本記事では，Xilinx社製 Kintex UltraScale FPGA KCU1500を使用しました．

![kintex.PNG](https://qiita-image-store.s3.amazonaws.com/0/153905/a2ace970-28ed-9c20-ce00-4786a7e4a77a.png)

[Kintex UltraScale FPGA KCU1500の詳細](https://japan.xilinx.com/products/boards-and-kits/dk-u1-kcu1500-g.html#overview)

開発キットを購入すると，Vivado Design Suite Design Edition，SDAccel開発環境，パーシャルリコンフィグレーションのライセンスが付いてきます．


#開発環境の構築
SDAccelを導入した，PCの環境は以下の通りです．
・System
OS:CentOS Linux release 7.4.1708 (Core)
Kernel:3.10.0-693.5.2.el7.x86_64
・Hardware
CPU:Intel Core i7 6700k
MEM:16GB

Centos7にSDAccelをインストールする方法を紹介します．

Step1. Xilinx社のサイトからSDAccelフル製品インストール版（SDx 2017.2 SFD）をダウンロードします．
[SDAccelダウンロード](https://japan.xilinx.com/support/download/index.html/content/xilinx/ja/downloadNav/sdx-development-environments.html)

Step2. ダウンロードしたファイルを解凍します．
例）tar fvzx Xilinx*.tar.gz

Step3. 解凍したフォルダ内にある，xsetupを実行します．
例）sudo ./xsetup
xsetupを実行し，ウィザードを進めていき，インストールしてください．
それなりに時間がかかります．

Step4. SDAccelのライセンスを取得します．
~~ライセンスがない場合は，下記のサイトからライセンスを取得できます．
無償評価版なので，60日の制限がかかっています．
[SDAccelライセンス](https://japan.xilinx.com/getlicense)~~

SDAccelのインストールは以上で終了です．
次回は，デバイスドライバのインストール，コンフィグレーションファイルの書き込み方法を紹介します．
11/17 [SDAccelを用いた回路設計について　その2](https://qiita.com/misaka0717/items/ae5b90f94b08fc17808a)
node.js で簡単にファイルコピーができるようになってました。

確か、Node.js の昔のバージョンではファイルのコピーってマニアックな書き方をする必要があったかと思います。
v8.9.0 LTS を入れたら簡単にファイルコピーができるようになっていました。
(v8.5.0から可能なようです。)

####fs.copyFile(src, dest[, flags], callback)#
Added in: v8.5.0

fs.copyFile を試してみたソースが下記。

```JavaScript:
/* ファイルのコピー */
const fs = require('fs');

fs.copyFile('data.txt', 'data.bak', (err) => {
    if (err) {
        console.log(err.stack);
    }
    else {
        console.log('Done.');
    }
});
```
【ARKit】ARでVR空間を作成する

# ARKitを使ってVR空間を作成する

## 完成品
宇宙空間へつながるどこでもドアを作成した。
ドアから覗くと太陽系を確認することができるが、別の角度からは何も見えない。
ドアをくぐると宇宙空間にいるような錯覚を覚える体験ができる。

[Movie]クリックすると動画が再生されます
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/6GWVwolzFBI/0.jpg)](https://www.youtube.com/watch?v=6GWVwolzFBI)

[アプリのダウンロードはこちら](https://itunes.apple.com/jp/app/ar宇宙旅行/id1306923658?mt=8)

## 作成手順
各手順の詳細はそれぞれ別記事にて説明をしているので
必要に応じて参考にすること。

## SceneKitでバーチャル空間を作成する
宇宙空間を作成する。
この空間は立方体の表面にミルキーウェイの画像を貼り付け、
ドアの3Dオブジェクトを入り口にドッキングしている。

以下に記載済み。
＜Qiitaリンク＞

## ARオブジェクトの作成する
今回は太陽系の構成要素がこれに該当する🌎

オブジェクトの作成方法は以下を参照。
https://qiita.com/shunp/items/a50194bcf99bc5daf286

## 表示されるオブジェクトの優先順位をつける
ここまでの状態だと、ドアを覗かずとも太陽系の惑星が見えてしまう。
ドアを覗いた時のみ、宇宙空間が見えるようにしたいので
表示されるオブジェクトの優先順位をつける。

```Swift:sample.swift
SCNNode node1 = SCNNode()
SCNNode node2 = SCNNode()
SCNNode node3 = SCNNode()

node1.renderingOrder = 100 // 1番目
node2.renderingOrder = 300 // 3番目
node3.renderingOrder = 200 // 2番目
```

今回の優先順位は
①宇宙空間
②太陽系
になるので、宇宙空間Nodeの値を太陽系Nodeの値より小さい数値に設定する。

## 参考資料
以下ソースコード
https://github.com/shunp/solar-system
【正規表現】個人的備忘

正規表現を未だに使いこなせず、ちょっとしたマッチ処理も度々苦戦するので、ノウハウを蓄積するためにまとめておく。

※表記の誤りや、もっとスマートに表現できる等のアドバイス等ございましたら、ご遠慮なくご指摘頂ければ幸いです。

###1. 最後に出現する指定文字までマッチ
ex) `/hoge/fuga/foobar.txt`というパスについて、ファイル名のパスまで取得する。

【考え方】
最初の文字から最後のスラッシュをマッチングさせて抽出させれば良い。

```bash
echo /hoge/fuga/foobar.txt | grep -oe ".*\/" # /hoge/fuga/
```
【解説】
grepの-oオプションはonly matching(一致した部分のみ抽出)の意味。-eは正規表現使用のオプション。
`.*`で0文字以上の任意の文字列を表現。最後に`\/`(`\`はエスケープ文字)でスラッシュまでマッチ。

###2. 最初に出現する指定文字までマッチ
ex) `aaa/bbb/ccc/ddd`という文字列について最初の`/`(スラッシュ)まで抽出したい。

【考え方】
事例1のパターンでは最長一致でマッチさせているため、最後のスラッシュまで抽出してしまう。
今回のパターンだと、最短一致によって最初に出現したスラッシュまでを抽出したいが、grepで最短一致を使用するにはテクニックが必要。というより対応していないらしいので、-Pオプションの使用によりPerl正規表現を有効にして最短一致を表現する。

```bash
echo aaa/bbb/ccc/ddd | grep -oP "^.*?\/" #aaa/
```
【解説】
`^`は先頭文字の意味。これをつけないと`aaa/ , bbb/ , ccc/`の3つがマッチしてしまう。`?\/`の表現は、`?`の直後の文字について、最短で出現した文字をマッチさせる。すなわち、`aaa`の直後のスラッシュが最短一致する。

###3. sedによる後方参照(これ便利) <font color=‘red’>※2018/10/20修正</font>
ログ解析をするときに、特定の値をマッチさせて後処理で演算を行いたいシュチュエーションがある。
例えば下記のようなGCログがあったとする。このログからFullGC直後のメモリ使用量(下記例の1行目で言うと、`FullGC: 3328K->384K(3712K)`の384K)の数字384だけを抽出することを考える。

```logos

[GC 3.125: [FullGC: 3328K->384K(3712K), 0.0112500 secs] 8168K->5998K(16000K), 0.0113291 secs]
[GC 4.539: [FullGC: 3712K->4K(3712K), 0.0032661 secs] 9326K->5999K(16000K), 0.0033515 secs]
[GC 10.669: [DefNew: 3332K->3K(3712K), 0.0015267 secs] 9327K->5999K(16000K), 0.0015929 secs]
[GC 12.103: [DefNew: 3331K->3K(3712K), 0.0003727 secs] 9327K->5999K(16000K), 0.0004336 secs]
[GC 13.539: [DefNew: 3331K->4K(3712K), 0.0003766 secs] 9327K->5999K(16000K), 0.0004347 secs]
[GC 18.199: [FullGC: 3332K->10K(3712K), 0.0012516 secs] 9327K->6005K(16000K), 0.0013153 secs]
```

私の従来のやりかただと、例えば抽出したい数値のの前後に記号があるとき(ex: <12345>)や特定のキーワードが数値の前にあるとき(ex: Total:12345)はその特定の記号やキーワードをトリガーにして下記のようにマッチ条件を書いていた。

```bash
echo "foo123<12345>123bar" | grep -oe \<[0-9]*\> # <12345>
```
当然だが、これだと抽出したい数値の前後にトリガー文字が必然的についてきてしまう。
数値だけを抽出したい場合はどうすれば良いのだろうか。


<font color=‘red’>※2018/10/20修正</font>
そこで便利だと感じたのがsedで後方参照を使用する方法である。~~後方参照とは、マッチした部分文字列を後で再利用することができる機能である。後方参照させたい部分は( ) で囲んで表現し、参照時は \1, \2,,,,とし、何番目の部分文字列を参照したいかを指定することができる。~~

後方参照の定義の理解に誤りがございました。
パターンにマッチし記憶された部分文字列をパターン内でも参照することが可能 な機能が本来の使われ方となります。
https://www.javadrive.jp/perlregular/ref/index5.html

従って下記の例において、置換前に()で囲み、置換後パターンに後方参照\1,\2,,,として参照して文字列を取り出すということは、本来の後方参照の用途からは逸れるものとなります。
norisuke3@githubさん、ご指摘ありがとうございました。
<font color=‘red’>※修正ここまで</font>

sedは置換機能に優れており、基本的な使い方は次の通り。

```bash
sed -r 's/置換前文字/置換後文字/' # -rは拡張正規表現

# ex)
echo hogefuga | sed -r 's/hoge/fuga/' # fugafuga
```
以上を踏まえると、抽出したい文字列を自由自在に操ることができる。
例えば`123<999>456<888>789`という文字列から`< >`内の`999, 888`だけを抽出する場合は次のように書ける。

```bash
echo "123<999>456<888>789" | sed -r 's/^.*<([0-9]*)>.*<([0-9]*)>.*$/\1 \2/' # 999 888
```

上記の例では抽出したい数値以外の任意文字列は`.*`で一括マッチさせ、トリガー文字列(この場合は`<`と `>`)は明示的に記述している。抽出したい文字列は数値であるから後方参照の括弧で囲い、`([0-9]*)`とした。そして、最後に抽出したい数値を後方参照`\1 \2`で取り出している。

最後にこれらの基本を押さえると最初のGCログの例ではFullGCの数値は下記のように抽出できる。

```bash
cat GClog | grep FullGC | sed -r 's/^.*FullGC:\s[0-9]*K->([0-9]*)K.*$/\1/'
384
4
10
```
【参考】上記の演算結果で最大値を取得したいときはawkで下記のように書ける。よく使うが忘れるのでメモ。

```bash
| awk '{if(max<$1) max=$1} END{print max}'
```
Javascript：半角混じり文章を全て全角にするスクリプト（習作）

できるだけ見通しよくって言うか，素人なのでそういうのしか書けないのだが，
一旦元の文章を文字の要素で区切って（半角カナは濁点半濁点含め１文字扱い）
Alleyに突っ込んで，次にAlleyの要素を順に評価して半角英数記号ならこう，
半角カナ記号ならこう，残りはこうじゃ，って全角に変換して

```javascript:半角⇒全角変換習作
function CnvHtoF(str){
    HarfArray = ["ｧ","ｨ","ｩ","ｪ","ｫ","ｯ","ｬ","ｭ","ｮ","ｱ","ｲ","ｳ","ｴ","ｵ","ｶ","ｷ","ｸ","ｹ","ｺ","ｻ","ｼ","ｽ","ｾ","ｿ","ﾀ","ﾁ","ﾂ","ﾃ","ﾄ","ﾅ","ﾆ","ﾇ","ﾈ","ﾉ","ﾊ","ﾋ","ﾌ","ﾍ","ﾎ","ﾏ","ﾐ","ﾑ","ﾒ","ﾓ","ﾔ","ﾕ","ﾖ","ﾗ","ﾘ","ﾙ","ﾚ","ﾛ","ﾜ","ｦ","ﾝ","ﾞ","ﾟ","ｶﾞ","ｷﾞ","ｸﾞ","ｹﾞ","ｺﾞ","ｻﾞ","ｼﾞ","ｽﾞ","ｾﾞ","ｿﾞ","ﾀﾞ","ﾁﾞ","ﾂﾞ","ﾃﾞ","ﾄﾞ","ﾊﾞ","ﾋﾞ","ﾌﾞ","ﾍﾞ","ﾎﾞ","ｳﾞ","ﾊﾟ","ﾋﾟ","ﾌﾟ","ﾍﾟ","ﾎﾟ","ｰ","｡","､","｢","｣"];

    FullArray = ["ァ","ィ","ゥ","ェ","ォ","ツ","ャ","ュ","ョ","ア","イ","ウ","エ","オ","カ","キ","ク","ケ","コ","サ","シ","ス","セ","ソ","タ","チ","ツ","テ","ト","ナ","ニ","ヌ","ネ","ノ","ハ","ヒ","フ","ヘ","ホ","マ","ミ","ム","メ","モ","ヤ","ユ","ヨ","ラ","リ","ル","レ","ロ","ワ","ヲ","ン","゛","゜","ガ","ギ","グ","ゲ","ゴ","ザ","ジ","ズ","ゼ","ゾ","ダ","ヂ","ヅ","デ","ド","バ","ビ","ブ","ベ","ボ","ヴ","パ","ピ","プ","ペ","ポ","ー","。","、","「","」"];

    strarray=[];
    CnvStr="";

    for(i=0; i<str.length; i++){
        if(str.substr(i,1)=="ﾞ"||str.substr(i,1)=="ﾟ"){
            strarray.pop();
            strarray.push(str.substr(i-1,2));
            continue
        }

        strarray.push(str.substr(i,1));
    }

    for(i=0; i<strarray.length; i++){
        if(/[ -~]/.test(strarray[i])){
            CnvStr = CnvStr + String.fromCharCode(strarray[i].charCodeAt(0)+0xFEE0);
        }else if(HarfArray.indexOf(strarray[i])!=-1){
            CnvStr = CnvStr + FullArray[HarfArray.indexOf(strarray[i])];
        }else{
            CnvStr = CnvStr + strarray[i];
        }
    }

    return CnvStr;
}
```
半角カナはこの糞ったらしい変換テーブル用意するしか無いのか知らん．
PHPの「アプリケーションサーバー」について

Webサーバーの3構造の「Webサーバー」「アプリケーションサーバー」「データベースサーバー」についてなのですが、Javaにはtomcatという「アプリケーションサーバー」があり、RubyにはRuby用の「アプリケーションサーバー」があります。

ですが、PHPには「アプリケーションサーバー」が存在していないことに気づき「なぜないのだろう？」とずっと疑問に思っていたのですが、解決したのでまとめておきます。

<h1>PHPのアプリケーションサーバー</h1>
今までは、Apachaを使っていましたがApacheには<b>モジュールを追加することでアプリケーションサーバの役割を持てるようになります。</b>それが<b>mod_php</b>というモジュール。

以前は、
```LoadModule php5_module modules/libphp5.so
AddType application/x-httpd-php .php
```
こんな記述をして設定していたわけですが、今ではPHPをインストールするだけでデフォルトで最初から記載されているのでわざわざインストールする必要がないということです。

<h1>Apacheインストール・起動</h1>
```
$ sudo yum -y install httpd
$ sudo service httpd start
```

<h1>PHPのインストール</h1>
```
$ sudo yum -y install php
```

<h1>mod_phpの設定</h1>
特に設定することはありません。
```/etc/httpd/conf.d/php.conf
```
ここにデフォルトで記載されているからです。

<h2>Apacheを再起動</h2>
```
$ sudo service httpd restart
```

Apacheを使う場合はこんな感じで大丈夫です。

<h1>CGIを使う場合</h1>
<h2>CGIとは</h2>
<blockquote>Common Gateway Interfaceは、ウェブサーバ上でユーザプログラムを動作させるための仕組み。現存する多くのウェブサーバプログラムはCGIの機能を利用することができる。 ウェブサーバプログラムの機能の主体は、あらかじめ用意された情報を利用者の要求に応じて送り返すことである。</blockquote> 
https://ja.wikipedia.org/wiki/Common_Gateway_Interface

<h2>FastCGIとは</h2>
<blockquote>FastCGIとは、Webサーバ上でユーザプログラムを動作させるためのインタフェース仕様の一つである。CGIの問題を解決するためにOpenMarket社によって1990年代中頃に開発されたもので、仕様は公開されている。</blockquote>
https://ja.wikipedia.org/wiki/FastCGI

<h2>PHP-FPM とは</h2>
<blockquote>FPM ( FastCGI Process Manager ) は PHP の FastCGI 実装のひとつで、 主に高負荷のサイトで有用な追加機能を用意しています。 </blockquote>
http://php.net/manual/ja/install.fpm.php

<h3>CGIについてまとめると</h3>
PHPはphp-fpmという別のプロセスを後ろで動かしておいて、Webサーバーに来たリクエストをそっち側に転送したりする。別のプロセスで動いているので、<b>切り離されている別々の道</b>とイメージしたら良いかと思う。

だけど、必ずしも同じWebサーバー内とは限らないので「Apache+mod_php」の場合は一元化されているが、CGIは別のプロセスなので切り離すこともでき、別々のサーバーを用意できたりする。
NHK番組表APIからJSONデータを取得してjqで編集する（データ取得編）

# はじめに
* NHK番組表APIを使えば番組のJSONデータの取得が可能。
* NHKラジオ第二放送の語学番組（英語）を録音するために必要な情報（開始日時、番組時間、タイトル）を取得したい。
* APIで取得したJSONデータをjqコマンドで編集したらわりと簡単に必要な情報が取得できた。

# 1. NHK番組表API
http://api-portal.nhk.or.jp/ja
# 2. 今回使用するAPI
Ｐｒｏｇｒａｍ Ｌｉｓｔ ＡＰＩ （Ｖｅｒ．２）
http://api-portal.nhk.or.jp/doc_list-v1_con

いくつかAPIが用意されてますが結局編集が必要になるので一日分のデータを取得できる上記APIを使用します。
APIを使用するためには、ユーザ登録が必要です。
APIで何ができるのか確認してからユーザ登録したいという方は、「5. WEBページからJSONデータを取得する方法」の手順を実施して取得データを確認してください。
# 3. jq インストール
jqのインストールは、以下から実施し、パスを通しておいて下さい。
https://stedolan.github.io/jq/
# 4. APIを使用してJSONデータを取得するシェル
---
``` 
get_sample_json.sh

#!/bin/sh

# 取得する番組表年月日を取得（スクリプト実行日）
date_s=$(date "+%Y-%m-%d")

# サービスID　NHKラジオ第二放送
service="r2"

# ユーザ登録で払いだされるIDを指定
myid="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

url=http://api.nhk.or.jp/v2/pg/list/130/${service}/${date_s}.json?key=${myid}

# 取得したJSONデータをファイルに保存する。
curl ${url} | jq '.' > ./sample.json
``` 
---
上記、スクリプトでNHKラジオ第二放送一日分のJSONデータが取得できます。

# 5. WEBページからJSONデータを取得する方法
まず、どんな情報が取得できるのか確認してからユーザ登録したいという方は、[APIページ](http://api-portal.nhk.or.jp/doc_list-v1_con)で出力されたJSONデータをファイルに保存することで「4. APIを使用してJSONデータを取得するシェル」と同様のデータを取得することができます。

![select.png](https://qiita-image-store.s3.amazonaws.com/0/60838/739984e6-de6f-e01f-11c7-6a13d7d726ff.png)
パラメータ（area,service,date）を指定して「指定したパラメータで試してみる」をクリックすると下図のJSONデータが取得できます。

![program.png](https://qiita-image-store.s3.amazonaws.com/0/60838/bd4e702c-0876-450f-4024-720f70be05ef.png)

ユーザ登録せずに後編 [NHK番組表APIからJSONデータを取得してjqで編集する（データ編集編）](https://qiita.com/Aco-gt/items/a477517c8146ec60293a) のスクリプトを試す場合は、Response Exampleに表示されたJSONデータすべてをコピーしてファイル（sample.json）に保存してください。行番号は削除してください。

今回はここまでで、後編[NHK番組表APIからJSONデータを取得してjqで編集する（データ編集編）](https://qiita.com/Aco-gt/items/a477517c8146ec60293a)  に続きます。
Amazon AlexaとAWS Lexを比較したメモ

### 背景
 - 以下の動機から、Alexaを使い始めようと考えたため。
    - Amazon Echo が日本で発売されるらしい。
    - Custom Skillというので一儲けできるらしい。
    - Lexで作った対話アプリをAlexaに移行しちゃえばいいのでは。

### Alexaとは
  - AlexaはAmazonが開発したAIアシスタント。
 音声交流や音楽再生、予定表リストの作成、アラームの設定、ポッドキャストのストリーミング、オーディオブックの再生と天気や交通情報、リアルタイム情報などの提供ができる。
 2017年10月時点では、英語とドイツ語のみ対応。日本語も年内対応予定。
 Amazon Echo等、Alexa対応デバイスにSkill（アプリケーション）をセットし、音声入力によって起動することで動作する。

 ![Alexa概念図](https://qiita-image-store.s3.amazonaws.com/0/25355/69ea0116-1979-f329-b327-ae947e6ad5c0.jpeg)

### Lexとは
  - Amazon Lex は、音声やテキストを使用して、任意のアプリケーションに対話型インターフェイスを構築するAWS上のサービス。SDKを用いて任意のアプリケーションで動作する。
  - 2017/10末時点では、日本語対応はしていない。

  ![Lex概要]![Lex.JPG](https://qiita-image-store.s3.amazonaws.com/0/25355/28f360ff-7232-d4c1-8047-fbb7f1416c84.jpeg)




### 機能比較
 - 大きく違うのはアプリのインストール。AlexaはechoなどのAlexa対応デバイスにSkillをインストールすることで利用可能になるが、Lexは独自でアプリケーションを組む必要がある。（AlexaもSDKを提供しており、アプリケーションを組むことは可能）
  - ただしLexについても、Facebook MessangerとSlack用のChatbotに関してはマネジメントコンソール内で作成できる。
 - よって、LexとAlexaでは基本的な仕組みは同じものの、用途が異なる。
 - また、Alexa対応デバイスを利用する場合、Alexaに対し特定の起動コマンド（"Alexa,ask ◯◯"）を発話することでSkillが起動する。
 - Amazon Echoの2017年内の日本語対応を発表しているため、独自Skillも日本語版が年内に作成できるようになるはずだが、Lexに関しては明確な発表は今のところない。
 - Alexa SkillはAmazonアカウントに紐付いており、一方でビジネスロジックはAWS Lambdaを利用するため、CustomSkillを使うならAmazonとAWSの両方のアカウントを持つ必要がある。
 - AlexaのビジネスロジックもLexのビジネスロジックもLambdaだが、Lambdaのインターフェースは異なるので、同一のLambdaFunctionを共有することはできない。よって同一の対話アプリをLexとAlexaで組むというのは難しい。また、Lexで作ったLambdaFunctionをAlexaに移行するにはソースコードの修正が必要。


|機能|Alexa|Lex|
|:--|:--:|:--:|
|アプリ起動方法|"Alexa, ask ◯◯（Skill名） XX（Utterance）" と発話|対話アプリ内でSDK、APIのパラメータに指定|
|アプリインストール方法|Alexa対応デバイスにインストール|独自アプリを作成。（facebook Messanger,Slack用チャットボットはLex内で作成可能）|
|想定するアプリケーションの種類|Amazon Echo, および同様のアシスタント|チャットボットアプリ|
|対応言語|英語、ドイツ語、（もうすぐ）日本語|英語（日本語対応予定は不明）|
|アプリ作成アカウント|Amazonアカウント（Lambdaを動かすのにAWSアカウントが別途必要）|AWSアカウント|
|ビジネスロジック|AWS Lambda|AWS Lambda|

### 結論
 - Alexaは音声アシスタントとして、Lexはチャットボットとして使うのが正当パターン。
 - それ以外の使い方ができないわけではない。
 - Lexで作った対話システムをAlexaに移行するにはそれなりに移行作業が必要。

### 用語
 - ほとんど同じ。

|機能|Alexa|Lex|
|:--|:--:|:--:|
|アプリケーション|Skill|Bots|
|（アプリケーションの持つ）機能|Intent|Intent|
|意図理解のための発話サンプル|Utterance|Utterance|
|変数|Slot|Slot|
eager_load = false の環境でサブクラスなどを読み込む

# どのような問題が起きるのか

`config/environments/development.rb` など

```ruby
config.eager_load = false
```

が指定された環境で STI のサブクラスなどは親のクラスを呼んでもロードされません。

```ruby
class Animal < ApplicationRecord
end

class Cat < Animal
end

class Dog < Animal
end
```

`rails c` で確認すると

```
irb(main):001:0> Animal.subclasses
=> []
```

このようにサブクラスは空になります。

# 何故なのか

config.eager_load が false だからなのですが、もう少し詳しく説明すると eager_load を使わない環境ではクラスが呼ばれたタイミングでロードを行うためです。

なので `config/environments/development.rb` に

```ruby
require_relative "../../app/models/cat"
require_relative "../../app/models/dog"
```

と書くと一見うまく動きそうですが Ruby の require は 1 回読んだファイルは再ロードしないため初回しかうまくいきません。

例えばビューに

```erb
<% Animal.subclasses.each do |animal| %>
  <%= animal.new.type %>
<% end %>
```

と書いて `rails s` でサーバを起動すると、一度アクセスしたページをリロードした際などにサブクラスが表示されなくなると思います。

# どうすればいいのか

`require_dependency` を使います。これは Rails が提供しており、何度でもファイルの読み込みを行ってくれます。

```ruby
require_dependency "cat"
require_dependency "dog"
class Animal < ApplicationRecord
end
```

確認のためにサブクラスに適当なメソッドを用意します。

```ruby
class Cat < Animal
  def cry
    "うみゃみゃ"
  end
end
```

ビューを変更して適宜確認してみます。

```erb
<%= Cat.new.cry %>
```

一度「うみゃみゃ」が表示される事を確認したらモデルのファイルを書き換えます。

```ruby
class Cat < Animal
  def cry
    "騒ぐほどでもないか"
  end
end
```

更新を保存してサーバをリロードすると「騒ぐほどでもないか」に表示が変更されると思います。
webpacker:install:reactでWebpack binstubs not foundエラーが出たときの緊急対処方法



# 概要
* `webpacker:install:react` or `webpacker:install:react`が`Webpack binstubs not found.`で失敗したときの暫定対処方法
* エラーの原因は`webpack`と`webpack-dev-server`インストールされていないこと
* 応急措置として、該当ファイルをwebpackerのソースからダウンロードして、適切な場所にコピーして、再度実行したら解決できた

# 環境
* Docker: Version 17.09.0-ce-mac35 (19611)
* ruby: 2.4.2 (2.4.1でも同様の状況を確認)
* rails: 5.1.4
* node: 8, (6, 7, 9でも同様の状況を確認)
* webpacker: 3.0.2
* mac: 10.13.1

# 詳細

## 事前内容
* [Dockerでwebpacker 3.0 が動かない時にやったこと](http://qiita.com/KazuyaHara/items/17c0e2f745ad48b0f0f3)を参考にdockerをbuildしていたところ`rails webpacker:install:react`で最終的に下記のエラーが発生。
* 結果、vue（react）のインストールに失敗した

## エラーログ抜粋
```
Installing binstubs
         run  bundle binstubs webpacker from "."
Skipped webpack and webpack-dev-server since they already exist.
If you want to overwrite skipped stubs, use --force.

省略

Done in 44.63s.
Webpacker successfully installed 🎉 🍰
       rails  webpacker:install:react
Webpack binstubs not found.
Have you run rails webpacker:install ?
Make sure the bin directory or binstubs are not included in .gitignore
Exiting!
         run  bundle exec spring binstub --all
* bin/rake: spring inserted
* bin/rails: spring inserted
```

## 原因
ログを見ると原因は、`webpack`と`webpack-dev-server`が`bin/`にコピーされていないことだとわかった。

## 対処法

* ファイルが足りないのが原因なので、[webpackerのマスター](https://github.com/rails/webpacker/tree/master/exe)から`webpack`と`webpack-dev-server`をダウンロードして`bin/`にコピーし、再度`webpacker:install:react`を実行したら解決した。

* なお、ログで勧められている`bundle binstubs webpacker --force`をしてもうまくいきませんでした。

# その他
* 数ヶ月前は特に問題なかったので、webpackerのバージョンの原因かも
* docker以外でエラーが発生するかどうかは試していない。
[Swift] guard を１行で書きたい。ただそれだけなんです！


## これは何？
guardを使って早期リターンをするとき、一緒にログを出力したいことがあります。

```swift
guard let data = optionlData else { return print("dataが取れない") }
```
短いログならこうしたいのですが、値を返す必要がある場合は

```swift    
guard let data = optionalData else {
    print("data がとれない")
    return ""
}
```
こうなってしまいます。

これをなんとか１行にしたい。ただそれだけのためのクラスを作りました。

###参考
コピーされててどれがオリジナルかわかりませんが、[この辺り](https://github.com/sysatom/OSC/blob/3324814a68bfaf1a9754912f7ae1fb9bfc1bae75/OSC/Logger.swift)を参考にしています。



## 普通のログ出力
### 値を返さない場合
上のリンク先のログ出力部分抜粋です。

```swift
class Logger {

    func log(_ message: String, function: String = #function, file: String = #file, line: Int = #line) {
        
        let logMessage = stringRepresentation(message, function: function, file: file, line: line)
        
        printToConsole(logMessage)
        printToDestination(logMessage)
    }
}
```

まずこれに簡単に使えるようにstaticなインスタンスを用意します。

```swift
extension Logger {
    static let shared = Logger(URL(fileURLWithPath: "/path/to/log"))
}
```

これで値を返す必要がない場合は

```swift
guard let data = optionlData else { return Logger.shared.log("dataが取れない") }
```
と書けるようになりました。

### 値を返す必要がある場合

同じ書き方で値を返せるようにします。

```swift
extension Logger {
    func log<T>(_ message: String, value: T, function: String = #function, file: String = #file, line: Int = #line) -> T {
        
        log(message, function: function, file: file, line: line)
        
        return value
    }
}
```
ジェネリクスで返す値を渡すだけです。
こうすることで、値を返す必要があるときでも

```swift
guard let data = optionlData else { return Logger.shared.log("dataが取れない", value: "") }
```
とほぼ同じ書き方ができるようになります。


## 問題点

失敗する可能性のあるイニシャライザでこれを使ってnilを返すことができません。

```swift
init?(_ index: Int) {

   guard case 0..<4 = index else { return Logger.shared.log("out of bounds.", value: nil) }
    
   // do something.
}
```
これはコンパイルエラーになります。
fish-shellでズンドコキヨシ

一年前くらいに流行っていたこれを唐突にやりたくなったので．
[ズンドコキヨシまとめ](https://qiita.com/shunsugai@github/items/971a15461de29563bf90)

べつにシェル芸でもなんでもなく，fishのビルトインだけで素直に書いた．というか，fish shellならビルトインコマンド・ビルトイン関数だけで書ける．

変わったことをしているのは，配列を文字列に埋め込むと空白区切りになる，ということくらい．

```sh
function zundoko
    set -l stack
    while true
        test (count $stack) -gt 4
        and set -e stack[1]

        set -l call (random choice "ズン" "ドコ")
        echo $call
        set stack $stack $call
        
        test "$stack" = "ズン ズン ズン ズン ドコ"
        and echo "キ・ヨ・シ！"
        and break
    end
end
```
映像コーデックH.264の動画ファイルを、iOS11以降で再生可能な映像コーデックH.265の動画ファイルに変換する

# iOS11から映像コーデックH.265に対応
iOS11から、新しく映像コーデックH.265に対応するようになりました。

[iOS11はHEIC/HEVC(H.265)で写真と動画のデータ容量を50%縮小する事が可能 | IT Strike](https://itstrike.biz/apple/ios/39683/)


H.265はiOS10以下で使用されていたH.264と比べて、**動画のファイルサイズがおよそ半分くらいになります。**
動画によりますが、試してみて一番軽くなった事例としては、H.264で27MBだった動画をH.265に変換したら4.2MBになりました。

H.264からH.265にコーデックを変えるだけなら、画質はほとんど変わりません（種々のパラメータの違いにより変わることもある気がしますが）。

ちなみにmacOSはHigh SierraからH.265に対応しているので、それよりも古いバージョンだと再生できません。


# H.264からH.265への変換

ffmpegのオプションを繋いだら一発で変換可能でした。

## インストール

ffmpegと、H.265用のライブラリが必要です。
本体と一緒にインストールします。

```
$ brew install ffmpeg --with-x265
# 〜省略〜
$ ffmpeg -version
ffmpeg version 3.4 Copyright (c) 2000-2017 the FFmpeg developers
built with Apple LLVM version 9.0.0 (clang-900.0.38)
configuration: --prefix=/usr/local/Cellar/ffmpeg/3.4 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-gpl --enable-libmp3lame --enable-libx264 --enable-libx265 --enable-libxvid --enable-opencl --enable-videotoolbox --disable-lzma
libavutil      55. 78.100 / 55. 78.100
libavcodec     57.107.100 / 57.107.100
libavformat    57. 83.100 / 57. 83.100
libavdevice    57. 10.100 / 57. 10.100
libavfilter     6.107.100 /  6.107.100
libavresample   3.  7.  0 /  3.  7.  0
libswscale      4.  8.100 /  4.  8.100
libswresample   2.  9.100 /  2.  9.100
libpostproc    54.  7.100 / 54.  7.100
```

## 変換実行

変換は下記のコマンドです。

```
$ ffmpeg -i input.mp4 -c:v    libx265 -tag:v hvc1 output.mp4

# もしくは
$ ffmpeg -i input.mp4 -vcodec libx265 -vtag  hvc1 output.mp4
```

処理はどちらも同じです。

`-c:v libx265`でコーデックをH.265に指定しています。
さらに、**iOS11で再生できるのはFourCCがhvc1である動画ファイル**なので、`-tag:v hvc1`で指定しています。
tagを指定しないで変換するとFourCCがhev1になるので、iOS11で再生できません。

⌘iでファイルの情報を見たとき、詳細情報のコーデックが「hvc1, AAC」となっていれば大丈夫です。
【Docker】Jenkins からdockerで Hello worldするまで一通り設定した(dind)

Jenkins 便利そうなので設定してみた、初めてJenkins触ってみる
インストールから docker run Hello world まで設定した。


#インストール
Kitematic から official な Jenkinsイメージ 入れたけど Dockerコマンドが入ってなかった
なのでdind(Docker in docker)な Jenkins repo を探した。

いくつか試してみてこれが良い感じだった

- [tvial/jenkins2-dind](https://hub.docker.com/r/tvial/jenkins2-dind/)

初期設定はこの記事を見た

- [Jenkinsを使った自動テスト環境を作る（前編）](https://knowledge.sakura.ad.jp/5293/)


#プラグイン
- プラグインはおすすめ設定「Install suggested plugins」を選択
- ThinBackup

#設定 

何か起きたときにお知らせするgmailの設定

 >```
 >JenkinisのTOPページより
 >[Jenkins の管理] - [システムの設定] - [E-mail 通知]
 >
 >[SMTP サーバー] に smtp.googlemail.com
 >[E-mail のサフィックス] に @gmail.com
 >[SMTP 認証] にチェック
 >[ユーザ名] と [パスワード] に Gmail のメールアドレスとパスワード
 >[SSL] にチェック
 >[SMTP ポート] に 465
 >```
　   [Jenkinsでビルド失敗時にメール送信](http://toriaezu-engineer.hatenablog.com/entry/2016/11/20/132341)

dockerできるようになったけどdocker service 上がってない
  >docker: Cannot connect to the Docker daemon. Is the docker daemon running on this host?.

　このdockerイメージはsudoコマンドも入ってなかったので
　Kitematicの左下の DockerCLIボタンで Jenkins-dockerの外側から
　rootでsh起動してサービス上げた

  ```
  docker exec -u root -it jenkins2-dind sh
  ```
  ```
  service docker start #Docker daemon起動
  [ ok ] Starting Docker: docker.
  ```
  ```
  systemctl enable docker #Docker をブート時に自動起動
  Synchronizing state for docker.service with sysvinit using update-rc.d...
  Executing /usr/sbin/update-rc.d docker defaults
  Executing /usr/sbin/update-rc.d docker enable
  ```

ついでに時間がずれていたので、タイムゾーン(Timezone)変更

>```
>### オリジナルをバックアップ
>cp /etc/localtime /etc/localtime.org
>
>### タイムゾーンファイルの変更
>ln -sf  /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
>```
  [【Linux】タイムゾーン(Timezone)の変更](https://qiita.com/azusanakano/items/b39bd22504313884a7c3)

ついでに/usr/share/jenkinsの書き込み権限が無いので、Jenkinsの自動アップデートができない件

>```
>chown -R jenkins:jenkins /usr/share/jenkins
>```
[Jenkinsの自動アップデートができないなら、書き込み権限を見なおそう](https://qiita.com/yoshi-taka/items/c59b90576e5cce897398)

JenkinsのGUIから新規ジョブを作成してビルド手順の追加

設定画面からシェル実行を選択して以下のコマンドを設定

```
docker run ubuntu:14.04 /bin/echo 'Hello world'
```

ビルド実行


```
Status: Downloaded newer image for ubuntu:14.04
Hello world
Finished: SUCCESS
```

できた！
Pythonスクリプトからパッケージをインストールして利用する方法

PythonのパッケージをPyPIからインストールする場合、`pip`や`easy_install`などのシェルコマンドを利用すると思いますが、Pythonのスクリプトからパッケージをインストールし、続けて新たにインストールしたパッケージを利用する方法を紹介します。

どのような場合に役に立つかというと、オンラインシェルでデフォルトで入っていないパッケージを使いたい場合です。[PythonAnywhere](https://www.pythonanywhere.com/)を使えば、[Pythonの公式サイト](https://www.python.org/)にあるような、ウェブページにPythonのシェルを埋め込むことができます。この[PythonAnywhereのオンラインシェル](https://www.pythonanywhere.com/embedded3/)ですが、メジャーなパッケージは利用可能できる状態ですが、デフォルトで入っていないパッケージを使用したい場合があります。

そのような場合、そのオンラインシェルで次のコードを実行します。`modelx`はPyPIにあるインストールしたいパッケージ名です。以下の例はPython3の場合ですが、Python2.7では`reload`が組み込み関数なので`importlib`をインポートする必要はなく、3行目は単に`reload(site)`になります。


```py3
import pip, site, importlib
pip.main(['install', '--user', 'modelx'])  # pip install --user modelx を実行
importlib.reload(site)                     # sys.pathをリフレッシュする
import modelx
```
[PythonAnywhere](https://www.pythonanywhere.com/)では、自動的にgistを実行する機能があるので、gistにこのコードを書いておけば、使いたいパッケージをインストールした状態でコンソールが利用可能になると思います。

*参考*

* https://www.pythonanywhere.com/forums/topic/2933/
* https://stackoverflow.com/questions/437589/how-do-i-unload-reload-a-python-module
* https://stackoverflow.com/questions/25384922/how-to-refresh-sys-path
Google App ScriptでDriveにあるファイルの最終更新者を取得する

Google Driveのファイルを更新した日時はわかるが更新者がわからない。
`DriveApp.getEditors()`はファイルの編集者リストを取得できるだけで、更新した人ではない。
他にもユーザーを取得できるAPIがありますが、どれも更新者ではないので調べました。

## Advanced Google ServiceのDriveAPIを使う

### Resources > Advanced Google services
<img width="444" alt="img1.png" src="https://qiita-image-store.s3.amazonaws.com/0/26883/58331248-356f-a4ef-3f6e-53e5d8f9ec6f.png">

### Drive APIを有効にする
<img width="690" alt="img2.png" src="https://qiita-image-store.s3.amazonaws.com/0/26883/59578b47-2e68-128a-99c3-914fdd68e6c9.png">

### `Drive.Files`から指定したファイルの最終更新者を取得する

```sample.gs
...
//最終更新者の名前を取得
Logger.log("name:" + Drive.Files.get(file.getId()).lastModifyingUserName);
//ユーザーから取得
Logger.log("name:" + Drive.Files.get(file.getId()).lastModifyingUser.displayName);
...
```

`Files`のAPIリファレンスはこちら。
https://developers.google.com/drive/v2/reference/files
他にも`DriveApp`では取得できなかった色々な情報が取得できます。
ファイルの更新確認などを自動化したいときに使えそうです。

---
以上。
AWS 管理コンソールのヘッダーをリージョン別で色分けする Stylish を作った

こんな感じ。

![ss-ap-northeast-1.png](https://qiita-image-store.s3.amazonaws.com/0/12745/f8fd51c0-5f7b-1c14-a78f-494addbab791.png)

![ss-us-east-1.png](https://qiita-image-store.s3.amazonaws.com/0/12745/ffb7250c-8920-2b0b-69ac-c4c1f776aead.png)

![ss-us-east-2.png](https://qiita-image-store.s3.amazonaws.com/0/12745/84d2ba96-d9ea-1bda-d033-662c6edab77d.png)

AWS マネージメントコンソールを触っている人なら必要性はわかってもらえると思う。

色はリージョン名から機械的に作った。
似た色になって異なるリージョンを区別しづらいのが難点だが、リージョンが増えたときに頭を悩ませるのもバカバカしいのでザックリ決めた。

インストールは [Stylish ページ](https://userstyles.org/styles/150583/aws-navbar-color-by-region) より。

[GitHub](https://github.com/KoharaKazuya/aws-navbar-color-by-region)
GASでrssやatom(Google News)を読み込む

##RSS

```js
var rss = XmlService.getNamespace('http://purl.org/rss/1.0/')
var dc = XmlService.getNamespace('dc', 'http://purl.org/dc/elements/1.1/')

function readRss(url) {
  var sheet = SpreadsheetApp.openById(SHEET_ID).getSheetByName('シート1')

  // フィードを取得
  var response = UrlFetchApp.fetch(url).getContentText()
  
  // XMLをパース
  var xml = XmlService.parse(response)
  var root = xml.getRootElement()
  var items = root.getChildren('item', rss)
  
  // 読み込んだデータをスプレッドシートに出力
  sheet.clear()
  for (var i = 0; i < items.length; i++) {
    var title = items[i].getChild('title', rss).getText()
    var link = items[i].getChild('link', rss).getText()
    var date = Utilities.formatDate(new Date(items[i].getChild('date', dc).getText()), 'Asia/Tokyo', 'yyyy/MM/dd')

    sheet.getRange(i + 1, 1).setValue(title)
    sheet.getRange(i + 1, 2).setValue(link)
    sheet.getRange(i + 1, 3).setValue(date)
  }
}
```
※SHEET_IDにはスプレッドシートのIDをつかってください。

##atom
ここではGoogle Newsを例にとります。

```js
function getATOM(query) {
  var sheet = SpreadsheetApp.openById(SHEET_ID).getSheetByName('シート2')

  var feedURL= 'https://news.google.com/news/?hl=ja&ned=us&ie=UTF-8&oe=UTF-8&output=atom&num=30&hl=ja&gl=JP&ceid=JP:ja&q=' + query

  var xml = UrlFetchApp.fetch(feedURL).getContentText()
  var document = XmlService.parse(xml)
  var root = document.getRootElement()
  var atom = XmlService.getNamespace('http://www.w3.org/2005/Atom')

  var entries = root.getChildren('entry', atom)
  sheet.clear()
  for (var i = 0; i < entries.length; i++) {
    var title = entries[i].getChild('title', atom).getText()
    var link = entries[i].getChild('link', atom).getAttribute('href').getValue()
    var updated = entries[i].getChild('updated', atom).getText()
    var date = Utilities.formatDate(new Date(updated), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm')

    sheet.getRange(i + 1, 1).setValue(title)
    sheet.getRange(i + 1, 2).setValue(link)
    sheet.getRange(i + 1, 3).setValue(date)

    // 画像があれば抽出
    var content = entries[i].getChild('content', atom).getText()
    var start = content.indexOf('img src="')
    if (start >= 0) {
      var end = content.indexOf('"', start + 9)
      var imageUrl = content.substring(start + 9, end)
      sheet.getRange(i + 1, 4).setValue('https:' + imageUrl)
    } else {
      sheet.getRange(i + 1, 4).setValue('');
    }
  }
}
```
Composer.jsonを書いてみよう

#はじめに
4ヶ月ほど前に初めてComposerを触る機会があり、それ以来お世話になりっぱなし。
よくわからないまま使うのも良くないので、[テスト駆動開発](https://estore.ohmsha.co.jp/titles/978427421788P)を購入して、TDDを実践してみるときにどうせならcomposer.jsonを自分で書いてみようと思ったので備忘録として残します。

#Composerとは
公式ドキュメントによると「Composerとは依存管理ツールです。」とのことです。
昔の私にはこの日本語がよくワカラナカッタ。

依存管理、というのはあるライブラリAで別のライブラリBを使っているため、ライブラリAをインストールしただけでは実行できず、ライブラリBもインストールする必要がある。というような関係性のことです。
これらを手動で1つずつ入れていくのは非常に面倒なので、それらの関係をツールを使って管理しましょう。ということ。
Composerを使ってライブラリAをインストールするとライブラリBも同時にインストールされます。便利。

#composer.jsonの作成
適当なプロジェクトのディレクトリで

```
composer init
```

を実行。

設定を色々聞かれますが、今回は全部デフォルト。

```
Welcome to the Composer config generator


This command will guide you through creating your composer.json config.

Package name (<vendor>/<name>) [package-name]:
Description []:
Author [user-name <email>, n to skip]:
Minimum Stability []:
Package Type (e.g. library, project, metapackage, composer-plugin) []:
License []:

Define your dependencies.

Would you like to define your dependencies (require) interactively [yes]?
Search for a package:
Would you like to define your dev dependencies (require-dev) interactively [yes]?
Search for a package:
```

実行したディレクトリの配下にcomposer.jsonが作成されていることを確認。

```json:composer.json

{
    "name": "tabtt/test",
    "authors": [
        {
            "name": "user-name",
            "email": "email"
        }
    ],
    "require": {}
}
```

#Composerを使ってPHPUnitをインストール
composer.jsonを以下のように変更する

```json:composer.json

{
    "name": "tabtt/test",
    "authors": [
        {
            "name": "user-name",
            "email": "email"
        }
    ],
    "require": {
        "phpunit/phpunit": "3.7.*"
    }
}
```

保存したら

```
composer install
```

PHPUnitのモジュールがインストールされた。

```
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 8 installs, 0 updates, 0 removals
  - Installing symfony/yaml (v2.8.28): Loading from cache
  - Installing phpunit/php-text-template (1.2.1): Loading from cache
  - Installing phpunit/phpunit-mock-objects (1.2.3): Loading from cache
  - Installing phpunit/php-timer (1.0.9): Loading from cache
  - Installing phpunit/php-file-iterator (1.4.2): Loading from cache
  - Installing phpunit/php-token-stream (1.2.2): Loading from cache
  - Installing phpunit/php-code-coverage (1.2.18): Loading from cache
  - Installing phpunit/phpunit (3.7.38): Loading from cache
phpunit/php-code-coverage suggests installing ext-xdebug (>=2.0.5)
phpunit/phpunit suggests installing phpunit/php-invoker (~1.1)
Writing lock file
Generating autoload files
```

ディレクトリ配下にモジュールがインストールされたのが確認できれば完了

```
vendor
├── autoload.php
├── bin
├── composer
├── phpunit
└── symfony
```

以上です。
world bankのデータを視覚化

#概要
　world bankは国際の財務データ等を取得できるのだが、なかなか視覚化が難しい。まあ、excelだと時間がかかるのでなんとかしようという話
#api
 日本の総務省なんかはまだ、excelだったりするんだが、さすがアメリカweb apiをサポートしている。
　だもんで、これを使うつもりなんだが、まだインフラを決めきれていない

　pythonのラッパーがあったので、これとjuputerの利用ということにしようかと思っているのだが
　microsoftのpower biというのもあるらしい。でも有料だしなあ・・

　node周辺もあるんだろうけど、まだ検索が足りないですかなあ
#wbdata
 どうも、ググるとpythonのwbdataというのがよさそうである。

 pip install wbdata
 でインストールしましょう

　ちょっと動かすとエラーがでるので
　windows環境の場合
　set PYTHONIOENCODING=cp932:xmlcharrefreplace
　というおまじないを実行してから
　pythonでインタープリターへ
　import wbdata
  wbdata.api.get_source()
  とすると
<pre>
11      Africa Development Indicators
36      Statistical Capacity Indicators
31      Country Policy and Institutional Assessment
41      Country Partnership Strategy for India (FY2013 - 17)
1       Doing Business
30      Exporter Dynamics Database &#8211; Indicators at Country-Year Level
12      Education Statistics
</pre>
 こんな感じである。このsourceというのは情報源でいろんな分類がある
 私はno2のWorld Development Indicatorsがほしいのだが、それ以外にも上のような山のようなデータがアクセスできる。

#GDPのデータ
GDPに関するデータを調べると
wbdata.api.search_indicators('GDP',source=2)
で下みたいなデータを参照するということである。
<pre>
GC.XPN.TOTL.GD.ZS       Expense (% of GDP)
GC.TAX.TOTL.GD.ZS       Tax revenue (% of GDP)
GC.REV.XGRT.GD.ZS       Revenue, excluding grants (% of GDP)
GC.NLD.TOTL.GD.ZS       Net lending (+) / net borrowing (-) (% of GDP)
GC.NFN.TOTL.GD.ZS       Net investment in nonfinancial assets (% of GDP)
GC.LBL.TOTL.GD.ZS       Net incurrence of liabilities, total (% of GDP)
GC.DOD.TOTL.GD.ZS       Central government debt, total (% of GDP)
GC.AST.TOTL.GD.ZS       Net acquisition of financial assets (% of GDP)
GB.XPD.RSDV.GD.ZS       Research and development expenditure (% of GDP)
FS.AST.PRVT.GD.ZS       Domestic credit to private sector (% of GDP)
FS.AST.DOMS.GD.ZS       Domestic credit provided by financial sector (% of GDP)
FS.AST.DOMO.GD.ZS       Claims on other sectors of the domestic economy (% of GDP)
FS.AST.CGOV.GD.ZS       Claims on central government, etc. (% GDP)
FM.LBL.BMNY.GD.ZS       Broad money (% of GDP)
</pre>

#実際にデータを取得
d=wbdata.api.get_data('NY.GDP.MKTP.CD',country=('JPN','US'))
で、データを取得できる。
ここでは、国に日本とアメリカを設定したが、なにも指定しないと、全世界の
1960年からのデータを持ってくる。まあ、データがちゃんとあるのはOECD諸国ぐらいだが、このデータをpandaに食わせて、分析するというわけである。

#結論
というわけで
以下のソースで
<pre>
# coding:utf-8

import wbdata
import pandas
import matplotlib.pyplot as plt
cc = ["JPN","US","CHN"]
ic = {"NY.GDP.MKTP.CD":"GDP"}
df = wbdata.api.get_dataframe(ic,country=cc,convert_date=False)

dfu = df.unstack(level=0)
dfu.plot();
plt.legend(loc='best');
plt.show()
</pre>
これがでる！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/60225/d32a9e54-15a2-8e2d-44be-1a97033bdc05.png)

すんばらしい！