OmniAICreator/Qiita-1.07M huggingface dataset:
tensorflow-gpuを動かすまで



# 環境構築概要
ubuntu : 17.10
GPU : GTX 1080
nvidia : 384
CUDA : 9.0
cudnn : 7.1.4
tensorflow-gpu : 1.12.0


今までMATLABでGPUを使用していましたが、tensorflowの方でGPUを動かしたので今回はバージョンをtensorflow-gpuに合わせました。

以下参照

<img width="880" alt="スクリーンショット 2019-05-07 12.21.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223559/4ac0a028-acd4-4a45-b78d-b988912ded8b.png">

これを見る限り、cudnnのversionは 7 ですが、上手く動かなかったので 7.1.4 を使用しました


# nvidia-driver のインストール

[Ubuntu17.10にNVIDIAドライバをインストールしてみた。](https://qiita.com/tatsuya11bbs/items/be6ceb85eee074c57b71)
*以前に書いた記事があるので参照してください。

# cudnn のインストール

[UbuntuにcuDNNをインストール](https://qiita.com/tatsuya11bbs/items/70205b070c7afd7dd651)
*以前に書いた記事があるので参照してください。
# CUDA のインストール

[UbuntuにCUDAをインストールする方法](https://qiita.com/tatsuya11bbs/items/9e7ce195ce900b33f979)
*以前に書いた記事があるので参照してください。

#cudnn の version確認コマンド
```
$ cat /use/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2
```
![Screenshot from 2019-05-07 12-05-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223559/5469b454-4ad6-01aa-a7ad-ab7ed7bad132.png)

```
$ cat /usr/include/cudnn.h | grep CUDNN_MAJOR -A 2
```

![Screenshot from 2019-05-07 12-04-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223559/8f061b28-eefb-a15f-6a63-9e63911330be.png)

# CUDA の version確認

```
$ nvcc  -V
```

![Screenshot from 2019-05-07 12-03-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223559/021e30d0-7962-8425-6e1f-4e03fd12f368.png)


# Nvidia driver の情報

```
$ nvidia-smi
```

![Screenshot from 2019-05-07 12-03-29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223559/897d046a-2304-cd09-28f1-a5d40bcbed06.png)


# tensorflow-gpu のインストール

```
$ sudo pip3 install tensorflow-gpu
```

でインストールすると最新版がインストールされます。
バージョンを指定する場合には

```
$ sudo pip3 install tensorflow-gpu==1.12.0
```

のように ==X.X.Xでバージョンを指定してください。


# +α

nvidia と　cuda の削除

```
$ sudo apt-get --purge remove nvidia-*
$ sudo apt-get --purge remove cuda-*
```


削除できているかの確認

```
$ dpkg -l | grep nvidia
$ dpkg -l | grep cuda
```

何も出てこなければ削除できています。

nvidia install

```
$ sudo apt-get install nvidia-384
```


インストール可能なnvidia driver 一覧

```
$ sudo add-apt-repository ppa:xorg-edgers/ppa -y
$ sudo apt-get update
$ apt-cache search "^nvidia-[0-9]{3}$"
```

#最後に

この作業にかなりの時間を費やしてしましました、、
cudaのバージョン違うものをたくさん入れていたので
一旦全て削除してやり直しました。
少しでも、参考になればと思います！

#参照

1. [Ubuntuでnvidiaドライバーが動作しない
](https://qiita.com/bohemian916/items/7637b9b0b3494f447c03)

2. [環境構築 - Ubuntu 16.04 に NVIDIA ドライバをインストールする方法について](http://pynote.hatenablog.com/entry/env-install-nvidia-driver-on-ubuntu1604)
obnizのブロックプログラムで抵抗入りLED3色の信号機を作る

この記事は、[obnizを中心にプログラミング教育の教材を作ったりする（1人アドベントカレンダー）](https://gw-advent.9wick.com/calendars/5)のために作成されました。
#概要
[obniz](https://obniz.io/ja/)はクラウド利用のマイコンボードです。HTML/CSS, JavaScriptによるコーディングのほかに「ブロックプログラム」も使えます。この記事では「ブロックプログラム」を使って、3色のLEDを順番に点灯・消灯させる信号機の作成を紹介します。

#抵抗入りLED3色（緑・黄・赤）の信号機の作成
##できあがり
以下のような実行結果になるように作ってみます。LEDが緑→黄→赤と点灯しくり返します。その際にobnizの液晶画面にも「わたれ」→「注意」→「とまれ」と表示されるようにします。
![信号機](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/7fa04a58-cf7a-6bcc-b267-6ec50a2ccd4f.png)

点灯時間は以下の様にしてみます。
![点灯時間](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/6ce5350c-3806-e872-0c1e-ce429e7a2231.png)

##ブロックプログラムで緑・黄・赤のLED（抵抗入り）をつなぐ
緑・黄・赤の抵抗入りLEDを以下の図の様に接続します。さし込むピンの番号は、プログラムで指定されるanode（アノード：陽極）/cathode（カソード：陰極）のピン番号と一致している必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/4145e8c7-f632-d1cb-3535-ba35c94c0325.png)

**抵抗入りのLEDを必ず使うようにしてください。抵抗が入っていない普通のLEDを同じように差し込むと、焦げた匂いがして、すぐにLEDが壊れます。**
さし込んだら以下の様になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/9e684d43-bff3-8cc6-86a0-aaa5e6a24d6d.png)
接続したら、電源を接続します。

## ブロックプログラムの作成
###初期化
まずは[obniz]カテゴリと[光る]カテゴリから以下のブロックを配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/1df8c57f-635e-a116-4e9b-81b58e1b4472.png)
obniz id:は自分のobnizの8桁の番号を入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/6a783056-2ef2-f65f-b6ec-23a0bf6c2782.png)
また「みどり」「きいろ」「あか」といったLEDがありませんので[LEDの作成]ボタンから新たにLEDを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/952a8d82-f104-e7e7-e4bd-4f122fefe0b5.png)
これらは、obnizそのものの接続とobnizとLEDとの接続を設定する初期化作業になります。

###メインループ
先ほどの初期化のためのブロックの下に以下のループ（くり返し）を行うブロックをつなぎます。信号機の点滅をくり返すメインループになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/f1426acb-250a-24fd-95c5-f93980f8ba58.png)

###プログラム全体
初期化とメインループのプログラム全体は以下の様になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/ec42ae39-20d0-30d3-1649-32eb44698dc3.png)
完成したら、実行してみましょう。できあがりと同じ動きになればうまくいっています。

##SeesawのActivityにしてみました
LMSの[Seesaw](https://web.seesaw.me/) [^1] を使って[小学生向けにobnizを教えるレッスン](https://8x9.jp/2019/05/05/iot-lesson-190505/)を始めています。 
Seesawでは、レッスン内の実習課題は**Activity**という単位になります。この記事の実習は以下のActivityです。これはSeesawを使う教師たちに共有されるように設定しました。

* [オブナイズで信号機を作る](https://app.seesaw.me/pages/shared_activity?share_token=A5mYGRabQMuvDEdbNP0Quw&prompt_id=prompt.73ff1042-fd7e-411e-9d74-2255daccdd91)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4092/f9dc463d-faab-57c2-d28e-c2f65385afd9.png)
Seesawで授業をしている方・してみたい方がいましたら是非使ってみてください。


[^1]: Seesawの良いところは、保護者もFamily userとして登録してもらい、学習の成果を閲覧してもらえることです。特にIoT・電子工作での成果物を画像やムービーで収録して見てもらえるのがGoodです。
Progateで「HTML & CSS 中級編」を終了して

#Progateで「HTML & CSS 中級編」を終了

10連休の間に少しずつProgateでHTMLとCSSの学習を進めようやく中級編まで到達しました。
初級編と比べると、確かに少しレベルが上がったような気がします。
また、自分のスピードとしても慣れてきたのか少し生産性が上がった気がします。
ボタンの動きや立体感など初級編よりもワクワクする動きやおしゃれな見た目になっていき、とても楽しく学習できました。

#Progateでの注意点

Progateは前評判通りで初心者にオススメのサイトであると思います。
スライドが非常にわかりやすく、楽しく学んでいくことができます。
しかし、Progateで学習する上で注意しなければいけない点があると感じました。
それは、**「振り返ると意外に覚えられていない」**ということです。
Progateでは、解説が丁寧で、間違えてもヒントが与えられるなど、スラスラと進めていくことができます。
だがしかし、それゆえに作業のようになってしまい、主体的に吸収するという姿勢が必要なくなるのです。
だからこそ、一つ一つのポイントを吸収し、自分のものにしていくという姿勢を心がけながら取り組もうと思います。

#今後について

HTMLとCSSについて初級編・中級編で学習したことが身についているか確かめるため、道場コースで特訓してみようと思います。
Docker Composeで起動したコンテナのログを、Amazon CloudWatch Logsに送る

# TL;DR

* Docker Composeで起動したコンテナのログを、Amazon CloudWatch Logsに送るようにしたい
    * 要するに、AWS環境で起動したコンテナのログを集約したい
    * AWS上のコンテナサービスの話は、ここでは置いておく
* Dockerのlogging driverでAmazon CloudWatch Logs用のドライバがあるので、それを使用するように`docker-compose.yml`に設定する


# Dockerのlogging driver

Dockerコンテナには、ログをどこに出力するかを設定できる、logging driverの仕組みがあります。

[Configure logging drivers](https://docs.docker.com/config/containers/logging/configure/)

デフォルトは、`json-file` logging driverで、これはホスト側の`/var/lib/docker/containers/[コンテナID]/[コンテナID]-json.log`に出力されます。

[JSON File logging driver](https://docs.docker.com/config/containers/logging/json-file/)


# Dockerコンテナのログを、Amazon CloudWatch Logsに出力する

Dockerコンテナが使うlogging driverを、Amazon CloudWatch Logs logging driverに変更することで、DockerコンテナのログをAmazon CloudWatch Logsに送信することができます。
※なお、Amazon CloudWatch Logsにログ出力できるように、EC2へのIAMロールの付与は必要になります

[Amazon CloudWatch Logs logging driver](https://docs.docker.com/config/containers/logging/awslogs/)

あとは、これを`docker-compose.yml`に設定すればOKです。

[Compose file reference / logging](https://docs.docker.com/compose/compose-file/#logging)

以下のように、`services`内の各コンテナに対して`logging`設定を書いていきます。指定する`driver`は、`awslogs`です。

```yaml
services:
  xxx:
    ...

    logging:
      driver: awslogs
      options:
        awslogs-region: ap-northeast-1
        awslogs-group: my-log-group
```

少なくとも、リージョン（`awslogs-region`）とロググループ（`awslogs-group`）は指定する必要があります。

また、**あらかじめロググループは作成しておく必要があります**。

ログストリームは、デフォルトではコンテナのID（先頭12桁）が利用されます。

これを変更する場合は、`awslogs-stream`や`tag`で指定して変更するとよいでしょう。

以下では、`tag`を使用して「イメージ名.コンテナ名.コンテナID（フル）」がログストリームとなるようにしています。

```yaml
    logging:
      driver: awslogs
      options:
        awslogs-region: ap-northeast-1
        awslogs-group: my-log-group
        tag: "{{.ImageName}}.{{.Name}}.{{.FullID}}"
```
sudo不要のコマンドインストール （unrarの場合）

Linux系サーバにrar形式のファイルを展開するためのコマンドをlinux環境に非su権限でインストールする．
インストール先を変更するだけで済む事例．

# なぜPermission deniedされるのか

今回の場合は，単に保護されたディレクトリ内に新しくファイルを作ろうとしたから．
ファイルを作る場所を変え，かつその場所が環境変数PATHに登録されていれば，この問題を避けることができる．

# 準備

ホームディレクトリなどに次のディレクトリを作成する．

- ソースコード保存先（/home/{username}/packagesなど）
- 実行ファイルインストール先（/home/{username}/binなど）

# ソースコードのダウンロード

ソースコード保存先に，[このサイト](http://lfsbookja.osdn.jp/BLFS/svn-ja/general/unrar.html)にあるtar.gz形式ファイルのダウンロード．

```bash:
wget http://www.rarlab.com/rar/unrarsrc-{version}.tar.gz
```

# tar.gz解凍

保存先にてtarコマンドの実行．解凍用オプション（zxvf）は定型文のように覚えてしまう．

```bash:
tar zxvf http://www.rarlab.com/rar/unrarsrc-{version}.tar.gz
```

unrarディレクトリが作成されているので，そこに移動．

# makefileの編集

makeコマンドによってmakefileを用いたコマンドの作成がされるので，一度unrar内のファイルmakefileをテキストエディタで開く．DESTDIR=の部分だけ下記のように編集して保存する．

```bash:makefile
#DESTDIR=/usr ###←もともとの文コマンドの文頭に#をつける．
DESTDIR=/home/{username} ###←/binを除く部分を書く．
```

# 実行ファイル作成

makeで実行．

```bash:
make
```

これにより，makefileで:の前に定義されるターゲットのうち，一番初めに書かれているものかつドットから始まっていないものを実行する．unrarのmakefileの場合，次が該当．

```bash:makefile
# ↓飛ばす
.cpp.o:
	$(COMPILE) -D$(WHAT) -c $<

# ↓実行される
all:	unrar

:   :   :

# ↓allで指定されたunrarターゲット
unrar:	clean $(OBJECTS) $(UNRAR_OBJ)
	@rm -f unrar
	$(LINK) -o unrar $(LDFLAGS) $(OBJECTS) $(UNRAR_OBJ) $(LIBS)	
	$(STRIP) unrar
```

make後，コマンド出力の末尾に"unrar"と書かれている（＝unrarが正常に生成された）ことを確認して次へ．

# 実行ファイルのインストール

こちらもmakeで実行．

```bash:
make install
```

makefile内の次のターゲットが実行される．

```bash:makefile
# ↓makeコマンドで指定されたターゲット
install:	install-unrar

# ↓installで指定されたターゲット
install-unrar:
			install -D unrar $(DESTDIR)/bin/unrar
```

ここでDESTDIRを用いていることが分かる．
実行後，/home/{username}/bin内にunrarが生成される．

# PATHの登録（.bashrcの編集）

/home/{username}/binをPATHに登録し，unrarコマンドが使えるようにする．
homeディレクトリに.bashrcがあることを確認．ドットから始まる隠しファイルなので，lsコマンドに-aオプションをつける．

```bash:
ls -a
```

このファイルをテキストエディタで開き，次の一行を追加して保存する．

```bash:.bashrc
export PATH="$PATH:/home/{username}/bin"
```

.bashrcはユーザがログイン時に自動的に実行されるコマンドを記載するもの．ターミナルのスタイルを変えたり，長いコマンドを簡略化するエイリアスを登録したり，そして何より環境変数の変更・追加を行うなどの目的で使われる．
今回は，ログイン時に元々のPATHに/home/{username}/binを追記するために使う．

# 動作確認

再ログインするか，.bashrcを強制的に実行する．

```bash:
source ~/.bashrc
```

コマンドが使えるか（＝どこにコマンドがあるかを教えてくれるか）を確認．

```bash:
which unrar ###→ /home/{username}/bin/unrarと返せばOK.
```

unrarでrarファイルを解凍する．

```bash:
unrar e xxx.rar
```

以上．
Visual Studio Codeのショートカット（よく忘れる）

よく忘れるので備忘録

## Plant UML
`a.puml`の拡張子で保存した後に、以下のショートカットキーを押す。

```
alt + D
```

## Markdown

`a.md`の拡張子でで保存した後に、以下のショートカットキーを押す。

```
Command + K -> V
```

## openで開くようにすると便利

拡張子を関連付けておくと、Macのターミナルで `open <filename>` を入力するとエディタが開くので便利。
Azureコンテナーインスタンスのテスト環境について考える

開発したアプリケーションを、Azureコンテナーインスタンスで稼働させています。
Azureコンテナーインスタンスとして、以下のものを準備しています。

|名称|用途|
|:--|:--|
|テスト環境|1つの開発が完了したタイミング(Pull Request作成時)に、Azure上での動作を確認する環境。主に開発者が利用する|
|ステージング環境|テスト環境で動作確認が終わったタイミング(Pull Requestのマージ)に、Azure上での動作を確認する環境。主にお客様が利用する|
|本番環境|本番用|

Azureコンテナーインスタンスは、CPU、メモリ、GPUの使用時間(秒)で課金されます。
てっきり、実際に使った時間での課金なのかと思っていたら、コンテナーが起動している時間での課金らしい･･･。
本番環境はいいとして、テスト環境とステージング環境は使い終わったら削除しておかないと、料金的に大変な事になります。

Azureポータルで削除しても全然いいのですが、いちいちめんどくさいので、何かいい方法はないかと考えました。

そうだ、**Azure DevOps**を使おう！

# Azure DevOpsの設定
Azure DevOpsのPipelinesのReleaseを使って、Azureコンテナーインスタンスを削除します。

## Releaseの作成
NewのNew release pipelineでReleaseを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334727/bf984eab-88fc-b3c5-1879-a7d54c75a198.png)

## テンプレートの選択
テンプレートはEmpty Jobを使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334727/0344a188-ffa8-35e9-804c-be95f21cc589.png)

## タスクの追加
タスクとして、Azure CLIを追加します。
ポイントは、azコマンドのオプションに「--yes」を付けておくことです(削除してもいいかの確認メッセージが入るのを抑止します)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334727/537db2f2-611f-29af-5b7f-67601f3a8913.png)

## スケジュールの設定
テスト環境は、開発者用なので毎晩3時に自動的に削除するようにします。これで削除のし忘れを防止します。
ステージング環境は、お客様用なので手動で削除するようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334727/2bed43c9-dfc9-66c4-a188-59c16e4c53e8.png)

## Releaseの作成
Releaseを削除したのち、Create ReleaseでReleaseを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334727/7d256fa0-927f-b3ce-c43e-e1d445f525c2.png)

ちょっと変わった使い方ですが、これで知らない間に課金されていたという事件を防止できます。
#vim でコンソールのテキストをHTML化する ( :TOhtml ) ( 色や行番号も保存される )

# いつもの画面

![image](https://user-images.githubusercontent.com/13635059/57264830-39092880-70af-11e9-81fd-589d701dc8cd.png)


# `:TOhtml` を入力

# な、なんじゃこりゃー！

![image](https://user-images.githubusercontent.com/13635059/57264725-8df86f00-70ae-11e9-8b4a-629a850b6286.png)

# 保存

`:w` で元のファイル名 + .html で保存されるっぽい。
# HTML

い、色や行番号も保存されているだと…？

![image](https://user-images.githubusercontent.com/13635059/57264793-f6dfe700-70ae-11e9-8ea2-6e602b3c454e.png)

# HTML source

```
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>/private/tmp/html.html</title>
<meta name="Generator" content="Vim/8.1">
<meta name="plugin-version" content="vim8.1_v1">
<meta name="syntax" content="none">
<meta name="settings" content="number_lines,use_css,pre_wrap,no_foldcolumn,expand_tabs,line_ids,prevent_copy=">
<meta name="colorscheme" content="none">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #ffffff; background-color: #000000; }
body { font-family: monospace; color: #ffffff; background-color: #000000; }
* { font-size: 1em; }
.LineNr { color: #ffff00; }
-->
</style>

<script type='text/javascript'>
<!--

/* function to open any folds containing a jumped-to line before jumping to it */
function JumpToLine()
{
  var lineNum;
  lineNum = window.location.hash;
  lineNum = lineNum.substr(1); /* strip off '#' */

  if (lineNum.indexOf('L') == -1) {
    lineNum = 'L'+lineNum;
  }
  var lineElem = document.getElementById(lineNum);
  /* Always jump to new location even if the line was hidden inside a fold, or
   * we corrected the raw number to a line ID.
   */
  if (lineElem) {
    lineElem.scrollIntoView(true);
  }
  return true;
}
if ('onhashchange' in window) {
  window.onhashchange = JumpToLine;
}

-->
</script>
</head>
<body onload='JumpToLine();'>
<pre id='vimCodeElement'>
<span id="L1" class="LineNr">1 </span>
<span id="L2" class="LineNr">2 </span>Yes
<span id="L3" class="LineNr">3 </span>
<span id="L4" class="LineNr">4 </span>Oh
<span id="L5" class="LineNr">5 </span>
<span id="L6" class="LineNr">6 </span>yes
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->
```


# ref

[Vimテクニックバイブル～作業効率をカイゼンする150の技 | Vimサポーターズ | 工学 | Kindleストア | Amazon](https://www.amazon.co.jp/dp/B00OIDI7SW/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1684








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
fstream EOFで例外が発生

# C++ の例外処理

こんな感じで、`exceptions`を定義することで例外を発生させることができ、Javaのように`try-catch`で捕捉することができるらしい。

```c++:sample1.cpp
    std::fstream file;
    file.exceptions(std::fstream::failbit | std::fstream::badbit);
```

# EOFでも例外が発生してしまう

一行ずつ読み込んで出力するだけの簡単なプログラムを作成。ファイルの読み込みはできたものの、EOFで例外が発生。
EOFのときに`eofbit`だけでなく`failbit`も立ってしまっているのが原因。

```c++:sample1.cpp
#include <fstream>
#include <iostream>
#include <string>

int main(int argc, char *argv[])
{
    std::fstream file;
    file.exceptions(std::fstream::failbit | std::fstream::badbit);

    try {
        file.open("test.txt");
        for (std::string buf; getline(file, buf);) {
            std::cout << buf << std::endl;
        }
        file.close();

    } catch (std::exception& e) {
        std::cerr << "Exception" << std::endl;
    }

    return 0;
}
```

# 解決方法

`fail`を検出したいのはファイルオープン失敗時のみなので、`fail`の部分だけ自前で処理する（といっても判定して例外投げて終わり）[^1]。

```c++:sample2.cpp
#include <fstream>
#include <iostream>
#include <string>

int main(int argc, char *argv[])
{
    std::fstream file;
    // failbitは自前で判定するようにした
    file.exceptions(std::fstream::badbit);

    try {
        file.open("test.txt");
        if (file.fail()) {
            // TODO: お作法がわからないのでとりあえず実行時エラー
            throw std::runtime_error("Cannot open file.");
        }

        for (std::string buf; getline(file, buf);) {
            std::cout << buf << std::endl;
        }
        file.close();

    } catch (std::exception& e) {
        std::cerr << "Exception" << std::endl;
        std::cerr << e.what() << std::endl;
    }

    return 0;
}
```

# 検証に使用した環境

* Windows 7 + Cygwin 
* gcc (GCC) 7.4.0

[^1]: [c++ - fstream EOF unexpectedly throwing exception - Stack Overflow](https://stackoverflow.com/questions/25213540/fstream-eof-unexpectedly-throwing-exception)
view_contextにしてやられた話

# なんだかよく分からないレシーバとの邂逅
不具合がとあるサイトで起きてその改修作業をしていたところ、問題のコードに妙なレシーバを発見した。

view_context

これはなんなんだ？よく分からない。ファイルに対してこの文字列にgrep検索かけても定義された箇所が全く出てこない。おいおい、オメーさんよぉ、一体なんなんだよぉ〜ええ？（ミスタ風）

## こいつ、独自にヘルパーメソッド作ったやつ呼ぶのに使われるってよ

独自にヘルパにーメソッドを作るには、

アプリケーション全体で使う場合は、app/helpers/application_helper.rb に書くことができる

app/views/hogehoge/ で使う場合は、app/helpers/hogehoge_helper.rb に書くことができる

ということで、このディレクトリパスに調べに行ったら問題のメソッドを発見することができた。
JavaのWebアプリケーションでサーブレットが読み込めなかった話

ちょっとしたデータ編集作業の用が生じ、簡易的なWebアプリケーションを作成してGUIで進めることにした。
個人的に使うので、保守性も何も気にする必要がない。とにかくさくっと作れればよい。
端末にEclipseが入っていたので、EclipseでJavaで動的Webアプリを作るぞ。ポチポチポチっとプロジェクトやServletをテンプレートから作成して、あとはにょろにょろっとコーディングじゃい。

しかしjspからajaxでJavaサーブレットにアクセスしようにも応答しない。これはおおいに困った。

~~~web.xml
<web-app>
<servlet>
<servlet-name>test</servlet-name>
<servlet-class>TestServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
</web-app>
~~~

~~~test.js
$ajax({
	url:'/testapp/test',
	type:'POST',
	data:{
		'param1':'aaa',
		'param2':'bbb'
	}
})
.done((data)=> {console.log("done!");})
.fail((data)=> {console.log("fail!");})
.always((data)=> {console.log("always!");})
~~~

~~~TestServlet.java
@WebServlet("/TestServlet")
public class TestServlet extends HttpServlet {
	public TestServlet() {...}
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {...}
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {...}
}
~~~

~~~console.log
fail!
always!
~~~


どうやってもTestServletに届かず、何が原因かさっぱりわからない。
で、よくよく見たところ、TestServlet.javaを自動生成した際に入っていた `@WebServlet("/TestServlet")` が気になった。
やれやれ。僕は検索した。

[@WebServletでURLパターンを指定]
(https://code-examples-ja.hateblo.jp/entry/2015/10/22/%40WebServlet%E3%81%A7URL%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E3%82%92%E6%8C%87%E5%AE%9A)


げろげろ。web.xmlってわざわざ書く必要ないのね……。
web.xmlの記述を削除して、ajaxのurlを `'/testapp/TestServlet'` にしたら難なく動いた。

普段フレームワークやテンプレートに頼りっきりだと化石エンジニアになってしまいますね。日頃の研鑽はいざという瞬間の開発速度に如実に現れますな。
SOLIDまとめ表


SOLIDを考える度に、どの原則がどんなものだったかで、いつも頭がこんがらがってしまう。
とっかかりとして、一目で確認するための表が欲しくて、作ってみた。

**こんな人向け**

- オブジェクト指向言語を使っている
- SOLIDは一通り見聞きした事がある
- SOLIDがいつもわからなくなる


# SOLIDまとめ表

|この構成の場合|このトリガーによって|この問題が発生する|対応策|原則名|
|---|---|---|---|---|
|一つのコードを、複数のアクターが使用している|あるアクターの文脈で、コードの修正が必要になる|異なるアクターから見ると、期待していた振る舞いでは無くなってしまう可能性がある|コードは、一つのアクターにのみ責任を負う様にする|SRP（単一責任の原則）|
|機能の具体的な処理と呼び出しとが、分割されていない|機能が増える（もしくは差し替えになる）|既存コードの、直接修正（追加機能用の分岐・処理詳細等）が必要になる|機能の追加は新規のモジュールを追加するだけで行える様に、機能の呼び出しと実装を分割する|OCP（オープン・クローズドの原則）|
|継承やIFが使用されている|新しく追加するサブクラス・IFの実装の振る舞いを、スーパークラスやIFと異なる様にする ※1|既存コードの、直接修正（異なる振る舞いを吸収する分岐など）が必要になる|サブクラスやIFの実装の振る舞いは、スーパークラスやIFそのものとしても問題が無い様にする|LSP（リスコフの置換原則） ※2|
|依存先のモジュールに、自分が使用しないコードが存在している|自分が使用していないコードの修正|無関係な修正に対して、再コンパイルが必要になる ※3|依存先を、自分が使う機能のみを定義したインターフェースにする|ISP（インターフェース分離の原則）|
|依存先が、変更されやすいモジュールになっている|変更が発生する|依存元の修正や再コンパイルが必要になる|依存先を、変更されやすいモジュールではなく、インターフェースにする ※4|DIP（依存関係逆転の原則）|

※1 静的型付け言語ならそもそも出来ない気もするけど
※2 LSPに違反するとOCPにも違反する
※3 動的型付け言語ならこの問題は発生しない。
※4 この際、処理の流れと実際の依存の方向を逆にする必要があるため、「依存関係逆転の法則」と名付けられている
Ubuntuでキーバインドを変更する

# 1. 経緯
普段Macを使ってるからUbutuでもMacっぽくキーを押したい

# 2. キーバインドのマッピング
|変更前        |変更後        |備考                                            |
|:------------|:------------|:----------------------------------------------|
|Caps Lock    |Ctrl         |使わないCaps LockキーをCtrlにしてCtrlを押しやすくする|
|無変換        |半角/全角     |Mac風                                           |
|変換          |半角/全角     |Mac風                                          |
|カタカナひらがな|Alt         |使わないのでAltにしてみる                          |

# 3. defaultの設定をバックアップ
### 3.1. defaultをバックアップ取っておく。
ちょこっといじって作らないとならない。

```bash
$ xmodmap -pke > ~/.Xmodmap_default
```
### 3.2. .Xmodmap_defaultの頭とお尻に追記する
頭には`clear shift`〜`clear mod5`までを。
お尻には`add shift = Shift_L Shift_R`〜`add mod5 = ISO_Level3_Shift Mode_switch`

```bash
clear shift
clear lock
clear control 
clear mod1
clear mod2 
clear mod3 
clear mod4 
clear mod5

(中略)

add shift = Shift_L Shift_R
add lock = Caps_Lock
add control = Control_L Control_R
add mod1 = Alt_L Alt_R Meta_L 
add mod2 = Num_Lock 
add mod4 = Super_L Super_R Super_L Hyper_L 
add mod5 = ISO_Level3_Shift Mode_switch
```
# 4. 変更したいキーコードを全て調べる

```bash
$ xev
```
キーを押すと番号が出てくる。   
なにやらいっぱい表示されるがいるのはこれ。

```bash:半角/全角キーは49
KeyRelease event, serial 37, synthetic NO, window 0x3200001,
    root 0x13c, subw 0x0, time 1255787, (131,139), root:(2101,246),
    state 0x10, keycode 49 (keysym 0xff2a, Zenkaku_Hankaku), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

```
### 4.1. キーコード
|キー           |キーコード|
|:-------------|:--------|
|Caps Lock     |66       |
|無変換         |102      |
|変換           |100     |
|カタカナひらがな|101      |

# 5. 実際にやりたい設定ファイルを作成
`!`でコメントを打てる

```bash:~/.Xmodmap
! Caps_Lockはモディファイアキーなので削除しないと駄目
clear lock
clear control
clear mod1

! Caps_Lock -> Ctrl
keycode 66 = Control_L
! 無変換 -> 半角/全角
keycode 102 = Zenkaku_Hankaku
! 変換 -> 半角/全角
keycode 100 = Zenkaku_Hankaku
! カタカナひらがな -> Alt
keycode 101 = Alt_R

! これでモディファイアキーを適用できる
add control = Control_L Control_R
add mod1 = Alt_L Alt_R
```

# 6. スタートアップに登録
`.xinitrc`や`.xinputrc`に

```bash
[[ -f ~/.Xmodmap ]] && xmodmap ~/.Xmodmap
```
と記載する。   
だが動かず。。。
なんで、アプリケーションの`自動的に起動するプログラムの追加`を起動してスクリプトを登録した。

# 7. refs.
[Xmodmap - ArchWiki](https://wiki.archlinux.jp/index.php/Xmodmap#CapsLock_.E3.82.92_Control_.E3.81.AB.E3.81.99.E3.82.8B)
[キーバインドの変更 Xmodmapの基本的な設定方法](https://qiita.com/macinjoke/items/746c0c0adb74cfdeb9e7)
[起動時に xmodmap の設定を反映させる](http://secret-garden.hatenablog.com/entry/2016/10/15/000000)
ひとり情シスに役立つVBAコードのサンプル

**ひとり情シス**にも役立ちそうな **Excel VBA** のサンプルコード。

# 実行方法
1. 新規Excelファイルのコードウィンドウ（`[Alt]+[F11]`で起動）に貼り付けて保存。
2. 対象シートをアクティブにし、`[Alt]+[F8]` でマクロを呼び出して実行する。

## ファイル参照パスを一括変更
ファイルサーバの更改などで、サーバのホスト名やドライブレターが変わってしまった場合に使う。
VLOOKUPなどの関数式で別ファイルにリンクしているときでも一括で変更できる。

### 例
- 変更前
`=VLOOKUP(B8, '\\ECSV31\人事総務部\[社員一覧.xls]Sheet1'!$A$3:$B$15, 2, FALSE)`

- 変更後
`=VLOOKUP(B8, '\\ECGSV01\人事総務部\[社員一覧.xls]Sheet1'!$A$3:$B$15, 2, FALSE)`

```vb
Dim r As Range, str1 As String, str2 As String

If ThisWorkbook Is ActiveWorkbook Then
    MsgBox "シートが選択されていません", vbCritical
    Exit Sub
End If
    
Application.ScreenUpdating = False  ' 画面更新を停止
Application.DisplayAlerts = False   ' 確認メッセージを表示しない
    
For Each r In ActiveSheet.UsedRange
    str1 = r.Formula
    str2 = Replace(str1, "\\ECSV31\", "\\ECGSV01\", , , vbTextCompare)  ' 置換
        
    If str1 <> str2 Then r.Formula = str2
Next

Application.DisplayAlerts = True
Application.ScreenUpdating = True
```

## 無効な図形オブジェクトを一括削除
行や列の削除を繰り返していると、図形の幅や高さがゼロの無効なオブジェクトが残ってしまう場合がある。
Excelが重くなるだけなので一括で削除しよう。

```vb
Dim wb As Workbook, ws As Worksheet, shp As Shape

Set wb = ActiveWorkbook
If ThisWorkbook Is wb Then
    MsgBox "シートが選択されていません", vbCritical
    Exit Sub
End If

For Each ws In wb.Sheets
    ws.Select
    For Each shp In ws.Shapes
        If shp.Height = 0 And shp.Width = 0 Then shp.Delete
    Next
Next
```

## セルの値が変わったら改ページ
機器管理資料などで、特定の列の値が変わったら改ページを挿入し、見易くするときに使う。

```vb
Dim ws As Worksheet, nRow As Long, nCol As Long, str As String

nRow = 28  ' チェック対象の開始行番号
nCol = 7   ' チェック対象の列番号

Set ws = ActiveSheet
Do Until ws.Cells(nRow, nCol) = ""
    If str <> ws.Cells(nRow, nCol) Then
        str = ws.Cells(nRow, nCol)
        ws.HPageBreaks.Add ws.Rows(nRow)
    End If
    nRow = nRow + 1
Loop
```
#vim のエンターキー ( CR / return ) の効果って何なの？ -> ノーマルモードのコマンド確定じゃないらしい

# たとえば、この1行を全部小文字にしたい

![image](https://user-images.githubusercontent.com/13635059/57261790-4e2c8a00-70a4-11e9-83c6-16ab0d0064ac.png)

# `gu` `Enter(CR)` を押す

# 2行分が小文字になるじゃん！

![image](https://user-images.githubusercontent.com/13635059/57261791-54226b00-70a4-11e9-8eb7-b846cd9c45e0.png)

# ふだんから Enter 押すと1行下に進むでしょ？ 1行下まで効果が及びますよ？ 

ってことだと理解した。

ちなみに `gu` `矢印キーの下` でも同じことが起こる。

# たとえば `gu$` だと

行末まで効果が及ぶ。

![image](https://user-images.githubusercontent.com/13635059/57261800-669ca480-70a4-11e9-8d49-9ad5411117a1.png)

# NOTE

- "vim エンターキー" って検索してもめぼしい記事が見つからなかった
- エンターキーひとつでここまで悩まなければいけない vim こわいよ
- vim の偉い人ごめんなさい

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1683








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
AWSの資格期限が2年から3年に変更されていた

# AWSの資格期限が2年から3年に変更されていた

自分の資格の更新期限が近づいたので、重い腰を上げて勉強しようかなーと
思っていた時に、令和始めのショッキングな事があったのでカキカキしておきます。


[公式　AWS 再認定](https://aws.amazon.com/jp/certification/recertification/)

上記サイトより


> AWS 認定は 3 年間有効です。AWS 認定を維持するため、定期的な再認定プロセスにより、引き続き専門性を有しておられることを実証していただきます。再認定によって、お持ちの AWS 認定の全体的な価値が高まり、認定において最新の AWS についての知識、スキル、およびベストプラクティスがカバーされていることを個人や雇用主に対して実証できます。

以前は２年間が有効で、1年過ぎたら再試験(初回よりは出題数が少ないやつ)を
受けられる感じだったと記憶しています。
しっかり3年と明記されていますね。

そして、よくよくみたらメールがきていました。
※件名に**重要**と書いてあったのに、しっかり見逃していました m(_ _)m

> 2019年2月末までに、現在および将来のAWS認定はすべて、2年間ではなく3年間有効となります。つまり、AWS認定アカウントにおいて、「有効期限」と「再認定のための最終日」が同じになります。
> 
> また、2月末までに、個別の再認定試験の実施を廃止します。認定を更新するために、50%割引で完全な試験を受験するか、または同じく50%割引でソリューションアーキテクト - プロフェッショナル試験にアップグレードすることができます。ソリューションアーキテクト - アソシエイトまたはプロフェッショナルベータ試験（利用可能な場合）への参加結果が合格の場合も、再認定要件が満たされます。



## 再認定方法

> 再認定ポリシーの変更により、次のオプションが提供されます。
> 
> 再認定のためにもう1年待機する：2月末まで、有効期限を「再認定のための最終日」に一致させるために、有効期限が1年間延長されたことを確認できるようになります。今から1年後、有効期限が近付いていることについて再度リマインダー通知を受け取ります。その時点で、50%割引でソリューションアーキテクト - アソシエイト試験を受験するか、または、50%割引でソリューションアーキテクト – プロフェッショナルへアップグレードする準備を整えることができます。



## 試しに自分のを証明書をみてみた

たしかに伸びている　！

<img width="347" alt="スクリーンショット 2019-04-26 11.30.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344266/42d19330-1741-8ae9-0eab-59723dd7ec3d.png">

しかも、期限内であれば半額でプロが受験できるぞい！

ということで、直近で再認定試験を受ける必要がなくなりホッとしていますw
それまでにプロとるぞー！！！



ということで、良い AWS ライフを！
[OSX] Chrome version 74以降、headlessでページの表示が出来ない（about:blankから移動出来ない）対処法

# 問題

1. OSXだ
1. Chromeのバージョンが74以降
1. chromedriverもバージョンが74以降
1. headlessで動かしている
1. capybaraなどで`session.visit`しても`session.current_url`が`about:blank`で、`session.save_screenshot`の内容が空白ページになっている

# 解決方法 ( --use-mock-keychain )

https://bugs.chromium.org/p/chromedriver/issues/detail?id=2870
https://groups.google.com/forum/#!topic/chromedriver-users/ktp-s_0M5NM


```rb

Capybara.register_driver :chrome do |app|
  args = [
    "--headless"
    "--disable-gpu"
    "--use-mock-keychain"  # !!! 74からはheadlessでこれが要る
    ...
  ]

  caps = Selenium::WebDriver::Remote::Capabilities.chrome(
    "goog:chromeOptions" => {
      args: args,
      ...
    }
  )

  Capybara::Selenium::Driver.new(
    app, 
    browser: :chrome, 
    desired_capabilities: caps,
  )
end

```
MITライセンスを明記する

## 概要
Githubにてコミットする際に自分が使うであろうメモです
コピペする際は文中の「hogehoge」を変更してお使い下さい。

## 記述内容

### README.mdの文末に明記

        ## License
        MIT

### コードの先頭に明記

        /**
        hogehoge Library v0.0.0
        Copyright (c) 2019 hogehoge
        This software is released under the MIT License.
        http://opensource.org/licenses/mit-license.php
        */

この記事は以下の情報を参考にさせて頂きました。

- [自作ソースコードに、MITライセンスを適用する３つのやり方](https://www.catch.jp/oss-license/2013/09/27/mit_license/)
SwiftGenとR.swift 導入するにあたって

# はじめに
[SwiftGen](https://github.com/SwiftGen/SwiftGen)と[R.swift](https://github.com/mac-cain13/R.swift)はiOS開発上でリソース管理を楽にできるライブラリ。というより、ツールと言った方がしっくりくるかと思います。
コードに存在するハードコーディングをなくし、運用保守しやすくなります。
そして今回弊社の新規プロジェクトでどちらか採用しようと考え、いろいろ比較したのをまとめます。

# 対応しているリソース比較
以下のように対象プロジェクトの欲しい部分は両方ありました。
プロジェクトによっては**CoreData**扱えるSwiftGenは良いですね。(CoreData扱ったことないので、詳しくわかりませんがw)

|  | SwiftGen | R.swift |
|:-:|:-:|:-:|
| image | ◯  | ◯  |
| font |  ◯ |  ◯ |
| color  | ◯  | ◯  |
| localize string | ◯  | ◯  |
| storyboard | ◯  | ◯  |
| segue  | ◯  | ◯  |
| nib  | ◯  |  ◯ |
| reusable cell  | ◯  | ◯  |
| core data  | ◯  | ×  |
| plist  | ◯  | △(※1)  |
| file  | △(※2)  | ◯  |
※ 2019 4月時点

※1. File読み込みまでは簡潔にできる。
※2. jsonとyamlは設定できる。

# 導入比較
Xcodeの設定上でBuild Phaseに各々のshellを追加し、走らせる点は同様ですね。
両者の導入方法を見てみましょう。

## SwiftGen
https://github.com/SwiftGen/SwiftGen/blob/master/README.md#installation

以下の`swiftgen.yml`ファイルでカスタマイズできますので、汎用性が高いですね。

```yaml:swiftgen.yml
strings:
  inputs: Resources/Base.lproj
  filter: .+\.strings$
  outputs:
    - templateName: structured-swift4
      output: Generated/strings.swift
xcassets:
  inputs:
    - Resources/Images.xcassets
    - Resources/MoreImages.xcassets
  outputs:
    - templateName: swift4
      output: Generated/assets-images.swift
```

加えてbrewでも用意されているため、xcodeでいちいちビルドして、リソースファイル生成という手間がありません。

```sh
$ brew update
$ brew install swiftgen
```

## R.swift
https://github.com/mac-cain13/R.swift/blob/master/README.md#cocoapods-recommended

特に設定ファイルもなく、ライブラリをプロジェクトに導入し、Build Phasesで設定し、ビルドすれば、リソースファイルが生成されます。

一律`R`prefixで呼び出せるのは一意性があって、良いですね。

# まとめ
- SwiftGen
  - カスタマイズできる
  - コマンド実行でき、ビルドの手間が省ける
  - CoreDataが扱える

- R.swift
  - 導入が簡単
  - カスタマイズできないため、プロジェクト間の揺れはない
  - 対応リソース間の呼び出し方に揺れがない

結局今回のプロジェクトでは知見がないSwiftGenの方をお試し採用しました。

今回は導入するにあたっての比較となりましたが、いかがでしょうか?ぜひ皆さんの今後の開発のてだすけになれば、幸いです。
PHP/Laravel5のRequestクラス覚え書き

Webアプリケーションフレームワーク **Laravel** の `Illuminate\Http\Request` の書き方メモ。
リファレンス的なものです。

```php:Controller基本形
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function store(Request $request)
    {
        $name = $request->input('name');
        //
    }
}
```

```php:View基本形
@extends('layouts.app')
@section('body')
<form method="POST" action="{{ route('XXXX') }}">
  @csrf
  <input type="text" name="name" value="">
  // 
</form>
@stop
```

# 入力の取得

- 動的プロパティで入力を取得
`$name = $request->name;`

- 全入力を連想配列で取得
`$input = $request->all();`

- アップロードファイルを除いて、全入力を連想配列で取得
`$input = $request->input();`

- すべてのクエリストリングを連想配列で取得（上記のallやinputにもクエリストリングは含まれる）
`$input = $request->query();`

- アップロードファイルの取得
`$file = $request->file('csv');`

- "name" の入力を取得
`$name = $request->input('name');`

- デフォルト値を指定して取得
`$request->input('name', 'Tom');`

- "name" と "password" のみ取得
`$input = $request->only('name', 'password');`

- "password" 以外を取得
`$input = $request->except('password');`

- リクエストに値が存在するか判定
`$request->has('name')`

- すべて存在するか判定
`$request->has(['name', 'email'])`

- リクエストに値が存在し、かつ空でないか判定
`$request->filled('name')`

# フラッシュデータ（次のリクエストの間だけ利用できるデータ）の保存
- すべてをフラッシュデータに保存
`$request->flash();`

- "name" と "email" のみフラッシュデータに保存
`$request->flashOnly(['name', 'email']);`

- "password" を除いてフラッシュデータに保存
`$request->flashExcept('password');`

# セッション

- "key" をセッションから取得
`$request->session()->get('key');`

- デフォルト値を指定してセッションから取得
`$request->session()->get('key', 'default');`

# その他

- リクエストURIを返す
`$uri = $request->path();`

- HTTPメソッド名（GET、POST等）を返す
`$method = $request->method();`

- POSTメソッドか判定
`$request->isMethod('POST')`

- リクエストURIがパターンに合致するか判定
`$request->is('admin/*')`

- User-Agentを返す
`$request->header('User-Agent');`
OXYPlotで"System.InvalidOperationException"の例外が発生したときの対応

OXYPlotでリアルタイムにグラフを更新していると以下の画像のような例外がplotmodelから発生することがあります。
![OXYPlot.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172499/bc1c8e25-c39d-b530-d45d-d13117fd2e51.jpeg)

この例外を発生させないようにするには、以下のようにInvalidatePlotにfalseを設定します。

```charp:
InvalidatePlot(false)
```

[以前の記事](https://qiita.com/mac8/items/035a39a2a01102ce248f)から少しアップデートです。プログラムの最後の行が変更点です。

#プログラム例
```csharp:PlotViewRefreashExample.cs
var myPlotModel = new PlotModel(); //PlotModelの生成
myPlotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = 0.0, Maximum = 1.0 }); //x軸の設定
myPlotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = 0.0, Maximum = 1.0 }); // y軸の設定

plotView1.Model = myPlotModel; // plotView1はPlotViewコントロール

LineSeries myLine = new LineSeries(); //データインスタンスを生成

myPlotModel.Series.Add(myLine); //データをPlotModelへバインド

for(int i = 0; i < 10; i++)
{

   myLine.Points.Add(new DataPoint(i, i)); //データの変更

   plotView1.Invalidate(); // PlotViewが更新される

   myPlotModel.Axes.Clear(); // 軸の変更のため、以前の設定をクリア
   myPlotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, Minimum = 0.0, Maximum = i }); //x軸の設定
   myPlotModel.Axes.Add(new LinearAxis { Position = AxisPosition.Left, Minimum = 0.0 , Maximum = i }); //y軸の設定
   myPlotModel.InvalidatePlot(false); // -- 変更点 ---
}
```

InvalidatePlotの値はtrueでもfalseでも問題無いようです。

ちなみにですが、リアルタイム更新は5msecくらいでもプログラム的には可能です。しかし、FPSの観点から60FPS(約16msec間隔)にとどめておく方が良いです。
install nodebrew, node and yarn

今さらですが、nodebrew, node (npm), yarn のインストール手順をまとめておきます。

mac で zsh が前提です。
bash の人は .zshrc => .bashrc に読み換えるなどお願いします。

※ nodebrew から nodenv に移行しました (2019-12-01)
https://qiita.com/morikiyo/items/cf265968e0447c57e473

## その前に

私の環境がちょっと汚れていたので掃除から始めます。

まず、インストールされていた yarn, node をアンインストール。

```zsh
$ brew uninstall yarn
$ brew uninstall node
```

以前にインストールした nodebrew も、一旦、アンインストール。

```zsh
$ brew uninstall nodebrew
```

.zshrc から nodebrew に関する環境変数の設定も消しておきました。

```zsh
export PATH=$HOME/.nodebrew/current/bin:$PATH
export NODEBREW_ROOT=...
```

~~環境変数を削除したら source しておきます。~~
(source しても NODEBREW_ROOT はクリアできないため、訂正)
ターミナルに入り直します。


/usr/local/var/nodebrew ディレクトリも残っていたら消します。

```zsh
$ rm -rf /usr/local/var/nodebrew
```

brew update もしておきます。

```zsh
$ brew update
```

## インストール

### nodebrew のインストール

node は homebrew ではなく nodebrew で管理することにしました。

```zsh
$ brew install nodebrew
```

nodebrew ディレクトリのセットアップをします。

```zsh
$ nodebrew setup
```

環境変数に NODEBREW_ROOT が設定されていなければ、$HOME/.nodebrew がセットアップされるはずです。

.zshrc に PATH の設定を追記しておきます。

```zsh
export PATH=$HOME/.nodebrew/current/bin:$PATH
```

パスを通すために source しておきます。

```zsh
$ source ~/.zshrc
```

### node のインストール

続いて Node.js をインストールします。

```zsh
$ nodebrew install-binary stable
```

```zsh
$ nodebrew use stable
use v12.1.0
```

```zsh
$ nodebrew list
v12.1.0

current: v12.1.0

$ node -v
v12.1.0
```

npm や npx もインストールされているはず。

```zsh
$ npm -v
6.9.0

$ npx -v
6.9.0
```

### yarn のインストール

Yarn は homebrew でインストールします。

```zsh
$ brew install yarn --ignore-dependencies
```

yarn は node に依存しているため homebrew で node がインストールされていないと依存関係のエラーになります。

しかし node は nodebrew で管理しているので homebrew ではインストールしません。

そこで `--ignore-dependencies` オプションを指定します。

以前は `--without-node` オプションを指定していたようですが、現在は無効になっているみたいです。

```zsh
$ yarn -v
1.15.2
```

以上でインストール完了です。

## 参考
- [hokaccha/nodebrew: Node.js version manager](https://github.com/hokaccha/nodebrew/blob/master/README.md)
- [インストール | Yarn](https://yarnpkg.com/ja/docs/install)
#vim で現在行のアルファベットすべてを大文字にする ( gUU ) / 小文字にする ( guu )

本文の通り。
# ref
[突然キレるVIMMER - Qiita](https://qiita.com/tboffice/items/d7c5bba56930216fdee6)

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1682








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
#vim で現在の行全体をヴィジュアルモードで選択する ( V )

本文の通り。
[Switching case of characters | Vim Tips Wiki | FANDOM powered by Wikia](https://vim.fandom.com/wiki/Switching_case_of_characters)
# 応用
- `Vu` 現在行のアルファベットをすべて小文字にする
- `VU` 現在行のアルファベットをすべて大文字にする

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1681








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
読書メーターのバグ修正の記録と予測

読書メーターという読書記録サービスがある。
https://bookmeter.com/

ちょっと前に、角川系列になった。

システムの切り替えがあり、バグがいっぱい残ったままサービスを移行した。

バグが多すぎて、しばらくはバグ報告しなかった。

先月、イベントの招待が全くできないバグを報告した。

約１週間で治った。

先々週、ナイスの一覧を見ると未読が一つもないのに、未読数が１００以上になっていることを報告した。

先週、少し減った版になり、
今週、未読一覧の数と、一覧表示が同等の状態になった。

だいたい、１週間で見直して、作り直し、試験して、提供している周期が予測できた。

今、直近で困っているバグはない。

困っているバグがあれば、今、報告すると直してもらえるかもしれない。

他のサービスでもそうですが、貢献度の高い利用者から連絡すると、直してもらいやすいかもしれません。

お知り合いでナイス数が多い人、感想数、おきにいられ数が多い人から連絡してもらうのも手かも。

p.s.
「おきにいられ」数は数年前からランキングがメニューからは表示しなくなった。
# 文書履歴(document history)
ver. 0.01 初稿 20190507 早朝
ver. 0.02 おきにいられ訂正 20190507 朝
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
mysql -u root -p でERROR 1045 (28000)に遭遇する

## 「mysql -u root -p」コマンドでmysqlにログインすると以下のエラーが発生

```
$ mysql -u root -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
```

## 対処方法

[こちら](https://qiita.com/dev-masaki/items/76946c76923f99b85f8e)の記事を参考に以下のコマンドを打っていく

<br>

まずmysqlを一旦停止

```
# service mysql stop
```

<br>

次に権限システムを起動せずにMySQLを起動

```
# mysqld_safe --skip-grant-tables &
```

<br>

上のコマンドを打った後に再度mysqlにログインを試みると...

```
# mysql -u root -p
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
```

<br>

エラーが発生。一旦DBサーバからexitして```mysql```を打つとこちらでも似たようなエラーが発生。

```
$ mysql
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
```

<br>

そこで次は[こちら](https://qiita.com/carotene4035/items/e00076fe3990b9178cc0)の記事を参考に対処していく。mysqlサーバに接続する際にはmysql.sockファイルを使っているがそのファイルが消えている可能性が。そこでmysql.sockファイルを作り、mysqlを再起動する

```
$ sudo touch /tmp/mysql.sock
$ sudo mysql.server restart
 ERROR! MySQL server PID file could not be found!
Starting MySQL
.Logging to '/usr/local/var/mysql/[ホームディレクトリ名].local.err'.
 ERROR! The server quit without updating PID file (/usr/local/var/mysql/[ホームディレクトリ名].local.pid).
```


権限を確認してみる

```
$ ls -la /usr/local/var/mysql
```

<br>

それでも権限は正常にユーザー名だったので、[こちら](https://easyramble.com/mysql-server-pid-file-error.html)を参考にmysqlのプロセスを確認してみる

```
$ ps -ef | grep mysql
```

確認するとmysqldのプロセスが稼働していたので、こちらは大丈夫なよう。


## 結果
以下のコマンドでmysqlサーバをrestartし、socketのエラーは解消しました！

```
$ mysql.server restart
 ERROR! MySQL server PID file could not be found!
Starting MySQL
. SUCCESS!
```

<br>

ただ他の問題は解決せず

```
# mysql -u root -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
```

```
# service mysql stop
$ mysqld_safe --skip-grant-tables &
[1] 2643
[ホームディレクトリ名]:project [ユーザー名]$ 2019-05-06T23:35:44.6NZ mysqld_safe Logging to '/usr/local/var/mysql/[ホームディレクトリ名].local.err'.
2019-05-06T23:35:44.6NZ mysqld_safe A mysqld process already exists
```

<br>

プロセスがすでに走っているとのことなので再度プロセスを調べてみる

```
$ ps aux| grep mysqld
```

3つのプロセスが走っていたのでこれらを全てkillする（[参考](https://www.takafumitaba.com/mysql-already-exists)）

<br>

その後

```
$ mysql.server start
Starting MySQL
 SUCCESS!
```

これで行けた！！

```
$ mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.25 Homebrew

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```
RubyでWeather Hacksを使って天気を取得してみた

# はじめに
前回の記事にて、天気情報取得にAPIキーが必要だったため、APIキーが不要な天気情報取得をやってみました。
[RubyでOpenWeatherMapを使って天気を取得してみた](https://qiita.com/M-Yamashii/items/ba54d7556c58feb3b86a)

# 環境
macOS Mojave(10.14.4)

# Livedoor Weather Web Service
こちらで公開されています。
[お天気Webサービス仕様]
(http://weather.livedoor.com/weather_hacks/webservice)
このサイト内のURLと地域別IDを使用することで、以下情報をJSON形式で取得できます。

>お天気Webサービス（Livedoor Weather Web Service / LWWS）は、現在全国142カ所の今日・明日・あさっての天気予報・予想気温と都道府県の天気概況情報を提供しています。

# 取得処理
今回も東京の天気情報取得をやってみます。
地域別IDは以下サイトにまとめられていたので、そこから参照します。
[livedoorお天気webサービス地域ID一覧](http://www.nankuma.com/etc/livedoor-weather-id.html)

上記サイトを見ると東京のIDは130010のようです。
そのため東京の天気情報取得には以下URLを使用します。
http://weather.livedoor.com/forecast/webservice/json/v1?city=130010

RubyでのJSON取得コードは以下になります。

```ruby
require 'open-uri'
require 'json'

response = open(url)
@parse_text = JSON.parse(response.read)
puts JSON.pretty_generate(@parse_text)
```

# 取得結果
取得できた東京の天気情報がこちらです。
※取得日：2019/5/7

```
{
  "pinpointLocations": [
    {
      "link": "http://weather.livedoor.com/area/forecast/1310100",
      "name": "千代田区"
    },
・・・略・・・
  ],
  "link": "http://weather.livedoor.com/area/forecast/130010",
  "forecasts": [
    {
      "dateLabel": "今日",
      "telop": "曇時々晴",
      "date": "2019-05-07",
      "temperature": {
        "min": null,
        "max": {
          "celsius": "19",
          "fahrenheit": "66.2"
        }
      },
      "image": {
        "width": 50,
        "url": "http://weather.livedoor.com/img/icon/9.gif",
        "title": "曇時々晴",
        "height": 31
      }
    },
・・・略・・・
    }
  ],
  "location": {
    "city": "東京",
    "area": "関東",
    "prefecture": "東京都"
  },
  "publicTime": "2019-05-07T05:00:00+0900",
  "copyright": {
    "provider": [
      {
        "link": "http://tenki.jp/",
        "name": "日本気象協会"
      }
    ],
・・・略・・・
```

取得ができたので、必要な部分だけ取り出して、今日の天気を出すようにしました。
ついでに関東地方の地域IDがある地点の天気を取得してみました。

```
City: 東京, 　 Weather: 曇時々晴
City: 大島,　  Weather: 曇時々晴
City: 八丈島,  Weather: 曇時々晴
City: 父島, 　 Weather: 曇のち雨
City: 横浜, 　 Weather: 曇時々晴
City: 小田原,  Weather: 曇時々晴
City: さいたま, Weather: 晴時々曇
City: 熊谷, 　 Weather: 晴時々曇
City: 秩父, 　 Weather: 晴時々曇
City: 千葉, 　 Weather: 曇時々晴
City: 銚子, 　 Weather: 曇時々晴
City: 館山, 　 Weather: 曇時々晴
City: 水戸,　  Weather: 曇時々晴
City: 土浦, 　 Weather: 曇時々晴
City: 宇都宮,  Weather: 曇のち晴
City: 大田原,  Weather: 曇のち晴
City: 前橋, 　 Weather: 晴時々曇
City: みなかみ, Weather: 晴時々曇
City: 甲府, 　 Weather: 晴時々曇
City: 河口湖,  Weather: 晴時々曇
```

比較のため、気象庁の天気と比較してみます。
[気象庁](https://www.jma.go.jp/jp/yoho/206.html)
※前回はヤフー天気を比較対象に挙げましたが、精度が公表されていないようでした。
そのため精度を公表している気象庁を選択しました。
[天気予報の精度検証結果](http://www.data.jma.go.jp/fcd/yoho/kensho/yohohyoka_top.html)

![スクリーンショット 2019-05-07 8.07.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406773/867f5315-7619-4c1d-af4e-637570a97a6e.png)

おおー、あまり外れていないように見えますね。

# まとめ
偶然近い結果になったのか分かりませんが、天気予報第２弾はなかなかよい結果でした。
明日、明後日の天気も出して比較すると、さらに面白そうですね。
Amazon AthenaのワークグループとIAMによるデータベース単位のアクセス管理をやってみた

# 背景
Athenaが良い感じに女神様なので、他チームに展開したいと考えました。
しかし、そのまま使うとデータベースやら何やらすべて見えてしまうようで、おおっと...と思っていたら最近ワークグループという機能で実装されたらしいのでこれを使って見ました。


# まとめ
ワークグループ単位でAthenaを分けられ、データベースやテーブル単位まで（今回はやってませんが）、アクセス管理が出来るようになり、安心してチームごとにAthenaが使えるようになって熱いです。
またチームごとに容量制限が行えるので、心理的なハードルが低い状態で試行錯誤がしやすいのが熱いです。


# 流れ
ワークグループを作成し、IAMで適用します。

## ワークグループの作成
Athenaの画面上部のタブというかメニューの「ワークグループ：」をクリックするとワークグループの画面に移動できます。「ワークグループを作成する」から作成できます。

# 主な設定項目

## ◆ワークグループ名
変更出来ないので少し注意。いやかなり注意。

## ◆説明
日本語で書けるのが地味に嬉しいです。

## ◆クエリの結果の場所、暗号化
クエリを保存する場所や暗号化を指定できます。
OutputLocationなどを指定しない場合に指定した場所にクエリ結果が出力されます。

## ◆クライアント側の設定を上書きする
こちらにチェックをすることで、上述の「クエリの結果の場所、暗号化」が強制的に適用されます。
試したところ、ようは以下のような挙動になりました。


### ↓設定ONの挙動
OutputLocationを指定してもスルーされ（エラーにはならない）、ワークグループで指定した場所にクエリ結果が出力される


### ↓設定OFFの挙動
OutputLocationを指定すると、ワークグループの設定を無視してOutputLocationで指定した場所にクエリ結果が出力される。


今回やろうとしていることを考えると、設定ON一択ですね。

## データの制限
一度ワークグループを作成後、「詳細を表示する」から「データ使用状況の制御」というタブに行くことで、そのワークグループで実行（スキャン）出来る最大データサイズを指定することができます。

この機能により、他チームに展開するうえで「えっ、ミスるとお金掛かるんでしょ・・・？」みたいなハードルを下げることが出来るのは相当熱いです。
実際、SQL自体をすらすら書ける人は多くとも「データのスキャン量まで事前に正確に考えてSQLを書ける人」となるとデータ構造やデータ設計側のスキルを要する事となり、相応にハードルが上がると思います。

# IAMまわり

## IAMでワークグループ用ポリシーを作成する
こちらを参考にポリシーを作成します。
リソースを「指定」とし、上記で作成したワークグループを指定します。
https://docs.aws.amazon.com/ja_jp/athena/latest/ug/workgroups-iam-policy.html
基本的にこの通りで問題ありません。
記載の通り、arnにはリージョンとアカウントも必要です。
> arn:aws:athena:\<region\>:\<user-account\>:workgroup/\<workgroup-name\>

## IAMでワークグループ用ポリシーに、データベースへのアクセス制御を入れる
上記の手順の他に実際にデータベースやテーブルへのアクセスを制御するためには AWS Glue側のポリシーが必要となります。
https://docs.aws.amazon.com/ja_jp/athena/latest/ug/fine-grained-access-to-glue-resources.html

そんな感じで、以下のような「特定のワークグループの特定のデータベースのみ操作が行える」ポリシーを作成しました。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "glue:UpdateDatabase",
                "glue:CreateTable",
                "glue:GetTables",
                "glue:DeleteTable",
                "glue:DeletePartition",
                "glue:GetTable"
            ],
            "Resource": [
                "arn:aws:glue:<region>:<accountid>:table/<データベース名>/*",
                "arn:aws:glue:<region>:<accountid>:database/<データベース名>",
                "arn:aws:glue:<region>:<accountid>:catalog"
            ]
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "athena:*",
            "Resource": "arn:aws:athena:<region>:<accountid>:workgroup/<ワークグループ名>"
        }
    ]
}
```

これで、やろうとしていたことが出来るようになりました。



# その他、絶妙にハマったこと
## IAMの反映ラグ
IAMのポリシーの反映には絶妙に（～数分？）のラグがあるようで、これだ！と思った反映をしたあとは一旦コーヒー休憩などをして確認すると良いです。比較的即時反映の時もあるような気がするのでハマります。また、キャッシュを持っているようで、連続で実行すると成功→失敗→成功みたいな感じにもなるようです。

## Athenaの画面へのIAMの反映
Athenaの画面に対しては、時間を置いてもIAMの設定が反映されない現象が起きました。
これはサインアウト→再度サインインによって見えるようになりました。
freee APIを使ってみました（準備：登録～アクセストークンの取得と、事業所IDの取得、ユーザーIDの取得、アクセストークンのリフレッシュ）

# やりたいこと
クラウド会計ソフトで有名なfreee、およびfreee APIを利用すれば経理チーム的な業務改善に繋がるのではないかと思いました。そのためにとりあえずどういうことが出来そうかを試してみます。
今回は基本的な使い始める準備までをやってみました。

# APIを扱えるまでの準備

ドキュメントが豊富ですが、以下をスタートにすると良さそうです。
[freee アプリストア チュートリアルガイド](https://app.secure.freee.co.jp/developers/tutorials/2-%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B#%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B)

## アプリ作成
https://app.secure.freee.co.jp/developers/applications
より、案内のまま簡単に作成できました。

## アクセストークンの取得
流れとしては
1. Webアプリ認証用URLへのアクセス
2. 認可コードの取得
3. アクセストークン
となります。

手元のGit Bashなどでcurlベースで試してみます。

``` sample.sh
curl -i -X POST \
 -H "Content-Type:application/x-www-form-urlencoded" \
 -d "grant_type=authorization_code" \
 -d "client_id=(★画面からコピーした「Client ID」)" \
 -d "client_secret=(★画面からコピーした「Client Secret」)" \
 -d "code=(★さっきブラウザで取得した認可コード)" \
 -d "redirect_uri=urn:ietf:wg:oauth:2.0:oob" \
 'https://accounts.secure.freee.co.jp/public_api/token'
```

取得できました。

> {"access_token":"XXXXXXXXXXXXXXXXXXXXXXXXX","token_type":"bearer","expires_in":86400,"refresh_token":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX","scope":"read write default_read","created_at":1556711794}


# 事業所IDや自分のIDの取得
ここからはリファレンスも一緒に見てゆくと良さそうです（Swagger UIでしょうか。見やすいですね！）。
→ [リファレンス](https://developer.freee.co.jp/docs/accounting/reference#/Deals/post_api_1_deals)

色々試すにあたり、自身の事業所IDや自分自身のユーザーIDが必要そうなので取得してみます。

## 事業所IDの取得

``` sample.sh
curl -i -X GET \
  -H "Authorization:Bearer (★さっき取得したアクセストークン)" \
  -H "Content-Type:application/json" \
'https://api.freee.co.jp/api/1/companies'
```

↓結果を確認します。

> {"companies":[
    {"id":(数値),"name":"株式会社ヴァリューズ","name_kana":"ヴァリューズ","display_name":"株式会社ヴァリューズ","role":"read_only"}]


## ユーザーIDの取得
``` sample.sh
curl -i -X GET \
  -H "Authorization:Bearer (★さっき取得したアクセストークン)" \
  -H "Content-Type:application/json" \
'https://api.freee.co.jp/api/1/users/me'
```

↓結果を確認します。

> {"user":{"id":(数値),"email":"(メアド)","display_name":null,"first_name":null,"last_name":null,"first_name_kana":null,"last_name_kana":null}

# アクセストークンのリフレッシュ
ところで、アクセストークン取得時の
> "expires_in":86400,

から分かる通り、86400秒（24時間）で破棄されます。24時間を過ぎてアクセスすると
> 401 Unauthorized
> {"message":"アクセスする権限がありません"

とエラーとなります。
アクセストークンを取得した時についてくるリフレッシュトークンを利用し、新たなアクセストークンを取得する必要があります。

``` sample.sh
curl -i -X POST \
 -H "Content-Type:application/x-www-form-urlencoded" \
 -d "grant_type=refresh_token" \
 -d "client_id=(★画面からコピーした「Client ID」)" \
 -d "client_secret=(★画面からコピーした「Client Secret」)" \
 -d "refresh_token=(★アクセストークンを取得した時に一緒についてきた「refresh_token」)" \
 'https://accounts.secure.freee.co.jp/public_api/token'
```

取得できました。

> {"access_token":"YYYYYYYYYYYYYYYYYYYY","token_type":"bearer","expires_in":86400,"refresh_token":"YYYYYYYYYYYYYYYYYYYYYYYYYYY","scope":"read write default_read","created_at":1556954721}

リフレッシュトークンも更新されます。前のリフレッシュトークンでやろうとすると

> {"error":"invalid_grant","error_description":"指定された認可グラントは不正か、有効期限切れか、無効か、リダイレクトURIが異 なるか、もしくは別のクライアントに適用されています。"}

といったエラーになります。そらそうですね。


という訳で、色々とAPIを使って行ける準備が出来ました。