OmniAICreator/Qiita-1.07M huggingface dataset:
せっかくなのでAndroid N Previewの問題報告をしてみる

結論として、リアクションを受けるまではそんなに難しくなかったので、みんなやってみようよという意味で投稿

## 動機

AndroidのMulti-Windowモード対応についていろいろやっていると、Toolbar回りでいろいろ怪しい動きをしていた。
に加えて、こないだAndroid Developers Summit in Tokyo 2016? で積極的に[Issue Tracker](https://code.google.com/p/android/)に報告上げてほしい(英語が拙くてもスクリーンショットくらいあればなんとかなる)とGoogleの人が話していた。
実際やり方あんまりわからないからといって報告する機会を逃すのももったいない気もした。（迷惑な話だ！笑）

せっかくなので

よし、やってみよう！と一気奮発し

"Developer preview report"をしてみることにした。


## 準備としてやったこと

・問題の発生源の特定
・問題の再現方法の特定
・問題が再現しているときのスクリーンショットを撮影
・撮ったスクリーンショットをGoogleDriveに上げる作業


## レポートの投稿方法

１、[Android Open Source Project - Issue Tracker](https://code.google.com/p/android/issues/list)へアクセス
２、既存のレポートにないかどうかを確認
　検索対象を"All issues"に設定、検索キーワードを入力し"search"ボタンを押下
３、既存のレポートに似たようなレポートが無い事を確認できたら、"new issue"ボタンを押下
４、テンプレート"Developer preview report"を選択
５、テンプレートをしっかり読む
　"https://developer.android.com/intl/ja/preview/support.html "と
　 "https://code.google.com/p/android/issues/list?can=1&q=label%3ADevPreview-N "で
　似たような事書かれてないかチェックしてと書かれているので、後者はもうやったと思うけど、前者も確認しよう。
６、レポートをテンプレに従って英語で記述（題名"[developer preview]概要"、端末モデル、ビルド番号、発生手順）
７、GoogleDriveにあげたスクリーンショットの共有先をandroid-bugreport@google.comにして共有リンクを取得
　画像右クリック→共有可能なリンクを取得→共有設定→”リンクを知っているユーザ全て…”の設定をオフ（特定のユーザ…）→「名前かメールアドレスを入力」とかかれている入力欄に対してandroid-bugreport@google.comを入力→リンクをコピー→issueのレポートにコピーしたリンクを張り付ける
８、もう一度全体を見直す！
９、Word Verificationと書かれた横にある画像の数字を入力
１０、submit issueを押下（これで投稿される）

１１、あとは応答をひたすら待ち、追加の情報を求められているなら、その内容をコメントに追加したりする。
※応答があるとレポートする際にログインしているGoogleアカウントのメールアドレスに対して、応答があった旨のメールが届きます。

僕の場合は、一つ目のレポートはStatus: WorkingAsIntended（意図した動き＝仕様動作）とすぐにステータスが変更され、簡単なコメントがついただけでした。
WorkingAsIntendedとなってしまうと、その内容に若干の不服があってコメントを追加してもたぶん取り合ってくれないので、その時はまた新しいissueを上げましょう。不服とする内容なら、先のレポートのリンクも付加するなどして説明を淹れましょう（もちろん英語で）。


## おまけ

ちなみにAndroid Developers Summit in Tokyo 2016でGoogleの中の人曰く

現在はAndroid N preview 2の段階でpreview 4くらいまでやるとか。
後半になればなるほど、変更しづらいのでAndroidデベロッパーの皆さんにはN preview 2の期間に
問題報告や要望をガンガン出してほしいということでした。

おたくの会社の実装がNになると動かない！ってことが無いように！とか、こうなるとおたくの会社の開発で都合がいいのに！とか、そんな内容でも積極的に報告してほしい！採用されるかはわからないけど、採用されたら言ったもん勝ちだよ！

という感触（あくまでも個人的な感想）でおっしゃられておりました。


## お詫び
Googleの中の人、本当につたない報告してごめんなさい！！



# 追記
[追加で僕が報告したissue](https://code.google.com/p/android/issues/detail?can=1&start=0&num=100&q=toolbar&colspec=ID%20Status%20Priority%20Owner%20Summary%20Stars%20Reporter%20Opened&groupby=&sort=-id&id=209663)に応答があったので、とりあえずこんな感じということで、報告しておきます。
すでに内部でリリースされているバージョンでは問題が再現しないみたいです。Future Releaseで改善される旨のご報告をいただきました。

Googleの中の人ありがとうございました。
ElasticsearchのデータをChromeアプリ: dejaVu で編集できるようにする


## elasticsearch.yml に設定を追加

```yaml:/etc/elasticsearch/elasticsearch.yml
http.port: 9200
http.cors.allow-origin: "*"
# http.cors.allow-origin: "http://127.0.0.1:9200"
# http.cors.allow-origin: "http://appbaseio.github.io"
http.cors.allow-methods: OPTIONS,HEAD,GET,POST,PUT,DELETE
http.cors.allow-headers: X-Requested-With,X-Auth-Token,Content-Type,Content-Length,Authorization
http.cors.allow-credentials: true
http.cors.enabled: true
```

```bash
$ /usr/share/elasticsearch/bin/elasticsearch --version
Version: 2.3.2, Build: b9e4a6a/2016-04-21T16:03:47Z, JVM: 1.7.0_99
```

## Chromeアプリをインストール

Chromeアプリ dejaVu: https://chrome.google.com/webstore/detail/dejavu/lcanobbdndljimodckphgdmllahfcadd

参考:

* https://github.com/appbaseio/dejaVu
* http://appbaseio.github.io/dejaVu/

dejaVuをローカルインストールしたり、Elasticsearchのプラグインとしてインストールしたんだが、どうにも最新バージョンはバグっている？？ようだったので、最終的にChromeアプリで動かすことに...。
一応、9200はIPで制限しているので良いんだが..。Chromeアプリの場合に Origin って、どうなるんだ？
allow-origin: * が気持ち悪い...。
Android Support Design 23.2で追加されたBottomSheetでメッセージ送信フォームを作ってみる

※ あらかじめことわっておきます。どう考えても[用法・用量](https://www.google.com/design/spec/components/bottom-sheets.html)を守っていない使い方を紹介しています。

![test](https://cloud.githubusercontent.com/assets/11763113/15190642/f98e924a-17eb-11e6-8ced-6c79d20ead06.gif)


## Bottom Sheetとは？

Google Play Music使ってる自分はそうと知らずに無意識に使ってたこのコンポーネントのことをいいます。
![Slice 1.png](https://qiita-image-store.s3.amazonaws.com/0/74571/e77db4d9-9bd5-d263-052b-32a9f9ea953d.png)

DroidKaigi 2016で「そろそろSupport Libraryにいれるよー」ってGoogleの人が言われていたのですが、どうやらv23.2で実装されたのですね。[Googleのブログでも紹介](http://googledevjp.blogspot.jp/2016/03/android-support-library-232.html)されています。


## Bottom Sheetでメッセージフォーム？

私は普段、クラウドワークスって会社でアプリやってるんですが、「ある程度の長文も苦にならず打てるUIってどんなのだろうか」と考えて、ちょっと凝ったUIを設計・実装した経緯があります。

LINEとかFacebookとか、だいたいメッセンジャーアプリって、メッセージフォームが下固定じゃないですか。あれってたぶん、「短文で済ませたくなるUI」ですよね。それじゃだめなんです。
（たとえば、ブログ記事作成画面がこんなUIしてたら、多くの人は発狂して「PCでやる！」ってなりますよね？）

![従来のUI](https://qiita-image-store.s3.amazonaws.com/0/74571/272b7e68-14dd-36b0-8a27-7f10770c4d2e.png)

とはいえ、Gmailのように画面を全く分けちゃうのもそれはそれで課題があって、「相手のメッセージを見ながらレスをする」ことができないんですね。

![従来のUI２](https://qiita-image-store.s3.amazonaws.com/0/74571/c922c1bf-39cf-d6e7-22c6-d90621ff23e4.png)
　
　

これらを両立すべく、クラウドワークスアプリでは「引き出せるメッセージフォーム」を作りました。
![CrowdWorks AndroidApp](https://qiita-image-store.s3.amazonaws.com/0/74571/11728314-50eb-cc11-d186-a9cceecf906a.png)


**が！**

いかんせんめちゃくちゃ複雑なコードになってまして、たぶん私以外に誰もメンテができないんじゃないか、という漠然とした不安があり、「ライブラリに頼れるなら頼りたいなー」と思っていた所なのでした。

そこに現れたBottom Sheet。「なんか似たようなUIしてるなぁー」→「これ使えるんじゃね？」→「とりあえず触ってみよう！」→　からの今回の記事です。


## 試してみたもの

冒頭のgifアニメで動かしてたやつそのものなんですが、一応ソースコードも上げておきます。
https://github.com/YusukeIwaki/BottomSheetPlayground

結論からいうと、[たったこれだけ](https://github.com/YusukeIwaki/BottomSheetPlayground/commit/8ed87bc108e7cf5e002fd7eef4318214b8213387)の変更量で、「引き出せるメッセージフォーム」が作れちゃうんですね。

ポイントとしては、非編集モード時には HIDDEN状態にしておき、

```java:メッセージフォームを非表示
bottomSheet.setHideable(true);
bottomSheet.setState(BottomSheetBehavior.STATE_HIDDEN);
```

編集モードに入ったら、 **hidden状態への遷移をしないようにしつつ** 、COLLAPSEDやEXPANDEDの状態に遷移

```java:メッセージフォームを表示
bottomSheet.setState(BottomSheetBehavior.STATE_COLLAPSED);
bottomSheet.setHideable(false);
```

とすることです。こうすることで、 **ビューを一切いじること無く** ビヘイビアだけで「引き出せる」という要件が実装できちゃうんです。
我ながら、「こんな簡単でいいの？？」ってかんじで割と感動しましたｗ


## まとめ

とりあえず、BottomSheetを変な使い方しました。
メッセージフォームじゃなくても、下からニョキッと出てきたり引っ込んだりする系の画面をつくりたいなら、本当に簡単に作れると思います。

みなさん、一度は用法・用量を守らずSupport Libraryを使ってみてはいかがでしょうか？（違ｗ
JavaScriptでFORMを作って送信するサンプル

```html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<script><!--
  window.onload = function() {
    var form = document.createElement('form');
    form.action = 'https://www.google.co.jp/search';
    form.method = 'get';

    var q = document.createElement('input');
    q.value = 'weather';
    q.name = 'q';

    form.appendChild(q);
    document.body.appendChild(form);

    form.submit();
  }
//-->
</script>

</head>
<body>

</body>
</html>
```

ですが、サーバからのレスポンスが遅いとわかるのですが、レスポンスが返ってくるまでの間、スクリプトで追加した要素がページに追加されて見えてしまいます。これを回避するのに、非表示のDIV要素の中にFORMをおく方法が思いつき、効果があることを確認しました。

それよりも、パラメータを格納する要素をINPUTからHIDDENにするのが手っ取り早い、というか正解なのだと思います。
DebianでDDNSを使う（No-IPとddclient）

#はじめに
外から自宅にアクセスしたくなったためDDNSをセットアップすることにしました。調べてみるとddclientという更新デーモンがDebianのパッケージにあり、ddclientに対応しているDDNSの中ではNo-IPが一番一般的なようでしたので、今回はこの二つを使ってみます。

#No-IPでアカウントを作成
普通にサインアップしてください。

#ddclientをインストール
```
apt-get install -y ddclient
```

#/etc/ddclient.confを編集
```
protocol=dyndns2
use=web, web=checkip.dyndns.com/, web-skip='IP Address'
max-interval=22d
server=dynupdate.no-ip.com
login=<username>
password=<password>
<myhostname>.hopto.org
```
hopto.orgは将来別のドメインになっているかもしれません。また、これらの設定のデフォルト値は/etc/default/ddclientに書かれており、daemon=300で5分間隔の更新になっているようです。30日間更新がないと削除されてしまい、その通知が1週間前に届くため、22日で強制更新するように設定してあります。

#/etc/ddclient.confへのアクセスを制限
```
chmod u=rw,g=,o= /etc/ddclient.conf
```
パスワードを書いているので。

#ddclientを再起動
```
/etc/init.d/ddclient restart
```

#テスト
```
ddclient -daemon=0 -verbose
```
/var/cache/ddclient/ddclient.cacheがうんたらかんたらの場合はこのファイルをいったん削除してみてください。
無料でGitHubのprivateリポジトリを作る方法

[追記 2019/01/18]

GitHubが全てのユーザに対してprivateリポジトリ作成権限を解放しましたね。
privateリポジトリが欲しいだけなら、諸々の手続きは必要なくなります。

[追記終わり]

---

学校のメールアドレス(ac.jpドメインなど)を持っている方限定で可能です。

##　サイトアクセス

それでは早速始めていきましょう。
まず、下記サイトにアクセスします。

[GitHub Education](https://education.github.com/)

サイトにアクセスするとこのような画面になると思います。

![スクリーンショット 2016-05-11 23.15.14.png](https://qiita-image-store.s3.amazonaws.com/0/69911/1ddfe7e9-71a5-71d8-9e85-e2e801cc7931.png)

上記写真中央にあるRequest a discountをクリックします。

## Step 1
Step 1 では  必要なものを教えてください(Tell us what you need)と聞かれます。

### 1. Which best describes you?　
自分の職業を

 - 学生(Student)
 - 先生（Teacher）
 - 研究者（Researcher）
 - 管理者/スタッフ（Administrator/staff）
 - その他(Other)

の中から選択します。

### 2. What are you looking to get a discount for? 
 - 個人アカウント(Individual account)
 - 団体アカウント(Organization account)

のどちらか一方を選択します。

　個人アカウントを作成すると5つのprivateリポジトリを作成できるPlanに加入することになり、利用期限は2年間となります。2年を経過するとprivateリポジトリを作成できなくなります。しかし、終了した時点でまだ学生の場合には再度申請することも可能で、privateリポジトリが勝手に公開されるようなことはないそうです。
 団体アカウントは、研究室やゼミ、クラブ活動などの単位で申請することが出来るものになっており、privateリポジトリの利用予定数を申請することが出来ます。

今回は個人アカウントの場合について進めていきます。
選択できたら、Next でStep2に移りましょう。

## Step 2
Step 2では、主に個人情報の入力を行います。


 - 名前(Name)
 - 学術状態の証明（Verify academic status）
 - 学校名(School name)
 - 卒業年度(Graduation year)
 - GitHubを使う理由(How do you plan to use GitHub?)

をそれぞれの項目に**全て英語**で記入/選択を行います。


#### **学術状態の証明（Verify academic status）に関して**

ここでは、学校のメールアドレスを使用しなければ認証がなされません。

もしも、学校のメールアドレス(ac.jpなど)を設定していない場合は、
[GitHub メール設定](https://github.com/settings/emails)のページより Add email address で学校のメールアドレスを追加すれば、選択できるようになると思います。
ちなみに筆者は、2回メールアドレスのミスで拒否されてしまったので気をつけましょう!

####**GitHubを使う理由に関して**

この手順の中では少し障壁の高い部分となります。
勿論、適当な理由では弾かれる可能性もありますし、英語で書かなければなりません。
私は、
>大学でプログラミングを学んでおり、研究でも使用するが公開されてしまうと困るため、このプランを使用したい。

という風に記入しました。
2,3行でも大丈夫なようですね!!

以上全ての項目を記入した後、Submit Request で送信しましょう。

## GitHubからの返事
さて、一定時間の後、登録したメールアドレスに返事が来ます。
上手くいけば下記のような返事が来て、希望のプランを使用できるようになります。

> Hey "Your Name", we have some awesome news

>We've upgraded you to a Micro plan, which will be free for the next two years. After that, you'll get an email saying that your coupon is expiring. You can reapply for another coupon if you still have academic status. We don't have any collaboration limits, so any group projects you may encounter can be hosted via your account.

>... (略)

>The GitHub Education Team

これで今日からあなたもprivateリポジトリを使用できるようになります！
おめでとうございます！


残念ながら申請が通らなかった方は以下のスクショのようなメッセージが帰ってきます。

![スクリーンショット 2016-05-12 1.31.11.png](https://qiita-image-store.s3.amazonaws.com/0/69911/1d6ee80b-4428-fd22-37a4-afcfdd87c756.png)

よくある間違いとして指摘されるのは、やはりメールアドレスです。
学校のメールアドレスを使用しているのか、今一度確認してみましょう。

## 終わりに
GitHubのprivateリポジトリを無料で作成する方法を紹介しました。
今回はその方法がQiitaにはなかったので記載することにしました。
誤字、脱字や指摘があればお気軽にコメントして頂ければと思います。
最後までお読み頂きありがとうございました。

## 参考サイト
めちゃくちゃ助かりました。

[大学におけるGitHub／GitHub Educationの活用事例 〜慣れることがソーシャルコーディングの道を拓く](http://gihyo.jp/lifestyle/column/newyear/2016/case-study-of-github-education)
[無料でGitHubのプライベートリポジトリを使う方法（$7 Microプラン）【学生限定】](http://www.mocchiblog.com/?p=10516)
mackerel エラー：<command> Error while updating host specs: API error. status: 404, msg: api request failed

#　概要
webからホストを退役させて、もう１度登録しようとしたところ
「<command> Error while updating host specs: API
error. status: 404, msg: api request failed」
とログがでてうまく新規ホスト追加が出来なかった。

# 環境

|OS|Debian|
|-----|-----|
|mackerel|0.30.0-1|
|||
|||
|||
|||
|||
|||
|||
|||
|||
|||

# 解決
## 最初やってみたこと。。。。

```bash:file
sudo apt-get purge mackerel-agent
```
上記して削除。そしてエージェントのインストール('https://mackerel.io/orgs/"プロジェクト名"/instruction-agent')してみたが、だめだった。
ログに
「
<command> Error while updating host specs: API
error. status: 404, msg: api request failed
」
とあり、mackerelのダッシュボードに新規追加されなかった。

## なんとか解決した方法
web側で退役済みの状態で、

```bash:file
sudo mackerel-agent retire #退役させる
sudo rm /var/lib/mackerel-agent/id #ホストIDを削除
```
上記を行う。
そして、エージェントの削除とインストールを行う。
すると新規追加された(たぶん、別のホストIDになったおかげ)
ライブラリ管理のススメ（概要）

# このページについて
SVNやGitを使ってバージョン管理をしているPJは殆どだと思います（稀に行っていないPJが未だにありますが。。。）が、
ライブラリ管理までしているPJは稀なので、布教も兼ねて書いてみるページです。

間違った認識があるかもしれないので、間違っていると感じましたらコメントお願いします！

## 想定読者
突然ですが、質問です。
「ライブラリ管理」していますか？

上記を聞かれて何を言っているのか判らない人がこのページの対象読者です。

## ライブラリ管理とは何か
「何かのチェックポイント時点（例えば、タグ付けしたときや、本番環境にデプロイしたとき）」の成果物をいつでも自由に引き出せる状態にしておくことです。
「何かのチェックポイント時点」の成果物とは、実行可能ファイル(.exe)やライブラリファイル(.jar,.so,.lib)などのコンパイルして生成されたファイルと、
コンパイル時に参照していた外部のライブラリファイル(libcやapache-commonsのjarなどバージョンも含めて)を１セットとしたものです。

## バージョン管理と何が違うのか
バージョン管理はソフトウェアの成長過程を記録しておき、
* 必要なときに履歴を閲覧して変更の意図をトレースしたり、
* ときにはバグが混入したタイミングを確認したり、
* はたまたバージョンを元に戻してビルドし直して配ったり、
と云ったものです。

ライブラリ管理には上記のような使い方はなく、
単純にある時点・バージョンの成果物を自由に切り替えて使えるようにしておく、
と云ったものです。
インターネット上のMaven Repositoryはライブラリ管理の代表格です。

## ライブラリ管理のメリット
思うことを羅列してみます。

* ソフトウェアの階層ごとに、プロジェクトファイルが作れる。<BR>
業務系のプロジェクト、共通的に使用したいユーティリティ群のプロジェクトと云った具合にプロジェクトファイルを分けて作ることができる。
* プロジェクトファイルが分けられると、挙動の債務が明確に別れるため、品質が上がりやすい。<BR>
よくあるオールインワンの失敗としては、全てが１つのプロジェクトにで含まれているため、共通機能が業務機能を使っているなど、参照がめちゃくちゃになっていてソフトウェアの運用つら〜直すのこわ〜という状況。これを改善できます。
* プロジェクトの都合の良いタイミングで、使用するライブラリのバージョンを上げることができる。<BR>
これは、業務系のプロジェクトの都合の良いタイミングで、ユーティリティ群のプロジェクトでコンパイルした成果物を取り込みできると云った具合です。
* 今迄に見たことがないエラーが突然出た際に、すぐに以前のバージョンではどのような動きをしていたかを確認できる。<BR>
バージョン管理のみであれば、バージョンを元に戻してコンパイルして、ときには配って・・・など余計な作業が多いですが、ライブラリ管理をしていれば必要な成果物が一式あるので、すぐにバージョンを元に戻して確認を行えます。
* 上記のものに被りますが、本番リリース後に重大な不具合が見つかってしまった場合に、すぐに元のバージョンに戻すことができます。<BR>
本番リリースであれば、どこか同じロケーション上にバックアップが取ってあるでしょうからそこから元せば良いじゃんと言われてしまいそうですが、ライブラリ管理を行っていれば機械的に元に戻すことが可能になります。よく、継続的デプロイメントとか継続的デリバリーとか云われているものです。これとライブラリ管理は非常に相性が良いと感じています。

## ライブラリ管理のデメリット
特にないです。（と思っています）

## ライブラリ管理をどうやるか
手段は何でも良いです。
成果物がコンパイルしたファイルと、そのときの参照ライブラリ一式あればファイルサーバにバージョン番号のディレクトリでも作ってその中にでもひょいっと置いておけば良いです。
が、そんな怠いことはしたくないので、ツールを使います。

### ライブラリ管理に使用するツール
* リポジトリマネージャ<BR>
Maven Repositoryみたいなインターネット上のサービスに業務アプリの成果物を置く訳にはほぼほぼいかないと思います。
そんなときは社内のサーバにリポジトリマネージャを立ち上げて使います。
リポジトリマネージャの代表としては以下のようなものがあります。
* Nexus
* Maven Archiva
* Artifactory

比較は以下にまとまってるのでリンク貼っておきます。
[アーティファクトリポジトリマネージャの比較 Nexus/Archiva/Artifactory](http://qiita.com/shrkw/items/fbd0aeb3bcaf4dd006ba)

私はNexus使ってます。
どれを使ってもミラーサーバとしての役割もあるため、むやみやたらにインターネット上のセントラルリポジトリにファイルを取りにいきません。
会社のプロジェクトでMavenか何かを使うときは、こういうのを使わないと不正アクセスか何かと勘違いされてアク禁になるそうです。
そりゃ、リポジトリサーバからすれば見えているIPアドレスは一緒だろうから、そうなりますよね。
ってことでアク禁解除はめんどうらしいので、必ずリポジトリマネージャを入れてミラーの設定も入れましょう。

* リポジトリマネージャにアクセスするツール<BR>
最近のビルドツールには、リポジトリマネージャにアクセスしてライブラリを自動ダウンロードして参照まで紐づけてくれるものが一般的です。
（今の私の環境は、antばかりですが。。良い加減やめようよant使うの）
利用言語、ライブラリに合わせて使うツールを選定しましょう。
リポジトリマネージャが対応していることの確認もお忘れなく！

JavaならばMavenを使っておけばとりあえず間違いはないです。

# 2017/4/6追加
りぽじとりマネージャの分について記載したので、ページのリンクを添付。
http://qiita.com/sh-ogawa/items/401a89da868a233c87ab
Java 7 以降で導入された、より厳密な型チェックによる「例外再スロー」を理解する

##はじめに
この記事は、私の[別記事](http://qiita.com/daylife/items/b977f4f29b1f8ced3a02#comment-23f001294d7e7064cc89)でコメント頂いた内容をもとに書きました。@tag1216 さん、コメントありがとうございました。
この記事は、[Java SE Documentation](https://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html#rethrow) で述べられている内容を、別のサンプルコードを用いてよりわかりやすく示しま（したつもりで）す。
##例外再スローとは
文字通り、catch ブロックで捕捉した例外を再度 try-catch 節の外側にスローすることである。

```java
try {
    return new java.io.File("./miracle.txt").getCanonicalPath();
} catch (IOException e) {
    throw e; // re-throw e
}
```

例外をメソッド内で re-throw しても誰も catch しない場合は、その例外はそのメソッドの throws 節で宣言されなければならない（以下、非検査例外については議論しない）。

```java
public String getMiracle() throws java.io.IOException {
    try {
        return new java.io.File("./miracle.txt").getCanonicalPath();
    } catch (IOException e) {
        throw e; // re-throw e
    }
}
```
##Java 7 以降で導入された例外再スロー
Java 7 以降では、以下の書き方が ok になったのであった。

```java
public String getMiracle() throws java.io.IOException {
    try {
        return new java.io.File("./miracle.txt").getCanonicalPath();
    } catch (Exception e) { // !?
        throw e; // re-throw e
    }
}
```
 
最初にこのコードを見たとき、throws 節が保証しているのは java.io.IOException のスローだけなのにもかかわらず、再スローでは（任意の）Exception をスローしているので、コンパイルエラーになるのではと思った。
Java 7 以降では、コンパイラが try 節内で throw されうる例外の型を厳密に調べるようになったので、上のコード内の Exception e のインスタンス e は実際は java.io.IOException （かそのサブクラス）しか来ないことをコンパイラは知っている。なのでこの書き方でも問題ない、というわけである。
　
この新しい書き方が可能な条件の詳細は [Java SE Documentation（再掲）](https://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html#rethrow) をご覧頂くとして、以下では再スローする例外の見た目が java.lang.Exception でない例をひとつ挙げる。

```java:RethrowTest.java
public class RethrowTest {
	
	@SuppressWarnings("serial")
	public static class Base extends Exception {}
	
	@SuppressWarnings("serial")
	public static class Extension extends Base {}
	
	private void throwExtension() throws Extension {}
	
	private void throwBase() throws Base {}
	
	public void rethrowOK() throws Extension {
		try {
			throwExtension();
		} catch (Base e) {
			throw e; // ok because this e is guaranteed to be an instance of Extension.
		}
	}
	
	public void rethrowNG() throws Extension {
		try {
			throwBase();
		} catch (Base e) {
			throw e; // Compilation error: Unhandled exception type RethrowTest.Base
		}
	}
	
}
```

ふたつの public メソッド rethrowOK と rethrowNG がある。前者はコンパイルできて、後者はコンパイルエラーになる。
rethrowOK では、try ブロック内で呼ばれる throwExtension メソッドが Extension （とそのサブクラス）のみをスローすることをコンパイラが理解できるので、Extension のスーパークラスである Base を catch ブロックで再スローすることが問題ないわけである。言い換えると、そのスローする「もの」は、見かけ上は Base であるが実は常に Extension のインスタンスであることが保証されているため、rethrowOK の throws 節の宣言と矛盾しない。

rethrowOK 内の catch (Base e) を catch (Exception e) に変更しても、同じ理由で問題なくコンパイルできる（web上で目にする記述のほとんどが後者のように見受けられる）。

一方、rethrowNG は再スローのコード throw e; の箇所でコンパイルエラーになる。try ブロック内で呼ばれる throwBase は Base をスローすることがわかっているため、再スローすると rethrowNG の throws 節の宣言の条件を満たさなくなるからである。
n次元空間内回転

こんにちは。
$n$次元空間内回転の代数を調べました。下記の乗法的ノルムの代数（[ノルム多元体](https://ja.wikipedia.org/wiki/ノルム多元体)）を使う回転表現は、行列表現に比べると積計算が楽ですね。また三角関数を避ける使い方をすると計算効率が有利ですね。

| $n$次元空間内回転 SO($n$) | 自由度 | 等価な代数 | [ケーリー＝ディクソンの構成法](https://ja.wikipedia.org/wiki/ケーリー＝ディクソンの構成法) |
|:------------|:--|:------------|:------------|
| SO(2) |1 | ノルム1の複素数 $z$ | 複素数は実数２つの組と等価 |
| SO(3) | 3| ノルム1の四元数 $q$ | 四元数は複素数２つの組と等価 |
| SO(4) | 6| ノルム1の四元数２つの組 $(q_1\, q_2)$ | 八元数は四元数２つの組と等価[^1] |


[^1]: 八元数同士の積は、四元数２つの組の表示を使えば、$\ (a,b)\ (c,d)=(ac-d^\ast b,\ da+bc^\ast)$
NullPointerExceptionの防止にデフォルト@Nullableにしよう

### 前提
Support Annotationというライブラリ(Support Libraryについてくる)にあるアノテーションの`@Nullable`をつけたメンバ変数などのメソッドなどにアクセスしようとするとAndroid Studio上で警告が表示されます。(逆に`@NonNull`がついていれば警告は表示されません。)
これを使っていけばある程度NullPointerExceptionを防止できます。
![image](https://qiita-image-store.s3.amazonaws.com/0/27388/44849315-2c06-f2f2-21a8-3cabf103b7db.png)




### 動機
`@Nullable`や`@NonNull`をつけようと思っても癖にならずサボってしまっていて自分には面倒で続いていませんでした。。
そこで、**いろんな変数がデフォルトで`@Nullable`扱いになれば警告が出まくって、気をつけるようになるのでは**ということで、そのオプションを探してみました。

### 設定方法
File | Settings | Editor | Inspections | Probable bugs | Constant conditions & exceptionsで
`Treat non-annotated members and parameters as @Nullable`にチェックを付けます
![image](https://qiita-image-store.s3.amazonaws.com/0/27388/d84969a7-9faa-bc4f-7a3a-2c2eaef104b7.png)


### 適用

|  |  |
|---|---|
| 適用前 | ![image](https://qiita-image-store.s3.amazonaws.com/0/27388/f921e3a6-e574-805b-30ec-ec7cb7972a74.png) |
| 適用後 | ![image](https://qiita-image-store.s3.amazonaws.com/0/27388/a8e9735f-81d5-7242-f832-332f3b3675ab.png) |

### まとめ
この警告が出ないように直していくことでNPEが少しは改善していけるのではないかと思います。
ただAndroidのフレームワークのメソッドも`@NonNull`などを導入してくれていないメソッドが結構あるので、防止しきれない部分や冗長なNullチェックが必要になる部分もあるようなので、そこは気をつけていく必要があります。
Analyze | Infer Nullity Annotationでうまく自動で@Nullableや@NonNullのアノテーションを入れられるようなのですが、自分の環境ではなぜか読み込みが終わらずうまく動かなかったです。
Kotlinを使えばこういうのも言語仕様的に解決してくれているようなので、Kotlinが利用できる人はKotlinを利用するのをおすすめします。
NPEをこうやって防いでいるなどの知見がほしいのでもっといい感じの方法を知っている方はお教えください。
Excelをいじる感覚でお手軽ヘルスチェック

Google Apps ScriptとGoogle Sheetsを使えば、誰でもExcelをいじる感覚でお手軽にヘルスチェックを登録、編集することができます。

![screenshot1.gif](https://qiita-image-store.s3.amazonaws.com/0/55173/6f70a991-43e6-6cec-1b36-b6f5cefd6e36.gif)

[github.com](https://github.com/kei-sato/gas-health-check)

具体的には次のようなことが出来ます。

- **インターネット上に公開**されていて、http(s)でアクセスできるWebサイト・Webサービスの死活監視
- HTTPメソッドはGET, POST, PUT, DELETEのいずれかを指定可能
- 任意のContent-Type, Header, およびbodyを指定可能
- **期待する結果**（HTTPステータスコードとbody）を指定可能
- リクエストと期待する結果が異なる場合、 **Slackに通知**（Google Apps Script自体の失敗はメールで通知可能）
- **シートを閉じても**（PCをシャットダウンしても）定期的にチェック

# インストール

1. `git clone https://github.com/kei-sato/gas-health-check && cd gas-health-check && pbcopy < main.js`
2. `Google Drive > NEW > Google Sheets` 適当な名前でスプレッドシートを作成
3. `Tools > Script editor...` Google Apps Scriptを開く
4. `main.js`をペーストして保存
5. `Select function > onOpen`を指定して、実行（この時求められるパーミッションを許可しないと動作しません）
6. シートに戻ると、メニューバーに`Custom Menu`が追加されている
7. `pbcopy < sample-sheet.txt`でサンプルシートの内容をコピーしてシートに貼り付ける
8. `Custom Menu > check right now` 正常に動作することを確かめる

## 定期実行

1. Google Apps Script（Tools > Script editor...）側で、`Resources > Current project's triggers > Add a new trigger`を選択して、実行関数に`healthCheck`を指定
2. 実行感覚はお好みで
3. `notifications`から、以上終了時のメール通知を設定することも出来ます

## Slack通知設定

リクエストの結果が期待と異なる場合に、Slackに通知するよう設定することが出来ます。

1. `https://slack.com/apps > Build > Make a custom integration > Incoming Webhooks`を選択して、画面にしたがって、入力する
2. 得られた`Webhook URL`をコピーする
3. `Custom Menu > Slack notifications`を選択して、`Webhook URL`を貼り付ける
4. ルーム名は必要に応じて

以上で設定は完了です
Struts2.5←2.3.xの移行について

# GAリリース

Struts2.5 GA リリースされましたので、さっそく移行＆検証しました。

公式アナウンス：
https://struts.apache.org/announce.html#a20160509

## 移行における変更必須のもの
2.5へ移行する際に変更が必須となるものです。

### Javaランタイム
7.0以降が必須です。

### リリース対象外のプラグイン
次のプラグインは **2.5から存在しません**。これらのプラグインを利用している場合は2.5への移行はかなり難しいでしょう。（そもそも2.3.xあたりで動作しなくなるものもあります）別プラグインの検討ないしは変更が必要でしょう。

 * Dojo Plugin - 2.3時代から非推奨にマークされていました。jQueryプラグインが登場したため、切り替わっています。
 * Codebehind Plugin - 2.0時代に使われていましたが、Conventionプラグインが正式採用されると更新されなくなりました。
 * JSF Plugin - 途中で更新が停止
 * Struts1 Plugin - 2.0.xでは使われていましたが、Action/ActionFormを2のActionへ内部的に置き換えてくれるだけで、JSPの対応は一切ないため、使われなくなりました

### フィルタのパッケージ変更
web.xmlにて定義する、Struts2用フィルタクラスの **パッケージ名が変更** になりました。

- 新：org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
* 旧：org.apache.struts2.dispatcher **.ng** .filter.StrutsPrepareAndExecuteFilter

他にもパッケージ移動したクラスたちがあります。
引用元：http://struts.apache.org/docs/version-notes-25.html

|新|旧|
|:---|:---|
|org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter|org.apache.struts2.dispatcher **.ng** .filter.StrutsPrepareAndExecuteFilter|
|org.apache.struts2.dispatcher.filter.StrutsExecuteFilter|org.apache.struts2.dispatcher. **ng** .filter.StrutsExecuteFilter|
|org.apache.struts2.dispatcher.filter.StrutsPrepareFilter|org.apache.struts2.dispatcher. **ng** .filter.StrutsPrepareFilter|
|org.apache.struts2.dispatcher.listener.StrutsListener|org.apache.struts2.dispatcher. **ng** .listener.StrutsListener|
|org.apache.struts2.result.ServletRedirectResult|org.apache.struts2.dispatcher.ServletRedirectResult|
|com.opensymphony.xwork2.interceptor.ValidationAware |com.opensymphony.xwork2.ValidationAware |

下の2つは本来の用途とパッケージが合致していなかったですね…。

## その他プラグインで注意するところ

### Java8-Supportプラグイン

Webwork2(xwork)のパッケージが、すべてstruts2-coreに移動しました。（クラスやパッケージの変更は **ほぼ** ありません)
そのためJava8-supportプラグインを利用されているプロジェクトの場合は、pom.xmlでasmのバージョンを5.0にしているかと思いますので、pom.xmlの修正が必須です。

```xml:pom.xml(抜粋)
<dependency>
	<groupId>org.apache.struts</groupId>
	<artifactId>struts2-core</artifactId>
	<version>2.5</version>
	<exclusions>
		<exclusion>
			<groupId>asm</groupId>
			<artifactId>asm</artifactId>
		</exclusion>
		<exclusion>
			<groupId>asm</groupId>
			<artifactId>asm-commons</artifactId>
		</exclusion>
	</exclusions>
</dependency>
```

### Springプラグイン

Struts2.5ではSpringのバージョンを4.1.6で指定しており、4.1.6以降ないしは4.2.xが必須です。

# 検証環境

私の検証済み環境とバージョンを列挙します。参考までに。

* JDK8
* Tomcat 8.0,33
* Struts2.5.2
    * Struts2-Spring plugin
    * Struts2-Convention plugin
* Spring framework 4.2.4.RELEASE
* Thymeleaf 3.0.2.RELEASE
    * Struts-Thymeleaf plugin(自前) 3.0.2対応
* Mybatis 3.4.0
* Log4J 2.7
* lombok 1.16.6
Taskerでスマホの状態をM2Xに記録してみよう

#はじめに

なんでも可視化するのが楽しくなってきたので、androidに[Tasker](https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm&hl=ja)を導入して、[M2X](https://m2x.att.com/)でバッテリーの変化具合を記録するというネタをやってみたので、その記録です。

#手順
今回もいつものごとく、IFTTTを使い倒す方向で実現。

1.対象となるandroidデバイスにTaskerをインストール
2.TaskerのプラグインであるRESTaskをインストール
3.RESTaskを使って、バッテリーの残量をIFTTTのMakerチャンネルに飛ばす
4.IFTTTでレシピを作り、M2Xにバッテリー残量をプロットする

#Taskerの設定

`PROFILES`から`Battery Changed`を選択して、バッテリーの変化がトリガになるようにする。
`TASK`から`RESTask`を設定する。

![Screenshot_2016-05-10-13-15-46.png](https://qiita-image-store.s3.amazonaws.com/0/95484/98ae41e0-ef18-bc4f-c38d-228f32da106c.png)

送り先はIFTTTのMakerチャンネル。
Makerチャンネルの使い方は[こちら](http://qiita.com/FePlus/items/734f61d1cfd68f70d2ed)で記事を書いているので参考にしてください。

Custom bodyは以下のような感じで、value2とvalue3は今後なにか送ろうと思ってるので、今は0を埋めてるだけにしている。WiFiのon/offやBluetoothのon/offなどの情報を合わせて送ってもいいかも。
![Screenshot_2016-05-10-13-15-59.png](https://qiita-image-store.s3.amazonaws.com/0/95484/d1911711-cf61-1c0d-6110-0d7d88e4ba2d.png)

あと忘れがちな設定。
Content-Typeの設定はしっかりやっておきましょう。
設定しなくてもレスポンスで200が返ってくるのが残念な所。（しかも動かないｗ）
![Screenshot_2016-05-10-13-16-05.png](https://qiita-image-store.s3.amazonaws.com/0/95484/3dfcbe61-cdd2-49a2-2ff7-3431b616d0fe.png)

#M2Xの設定

[M2X](https://m2x.att.com/)はAT&Tが提供しているIoT向けのサービス。
非常に使い勝手がよく、色々な場面で使ってます。
[M2X Pricing](https://m2x.att.com/pricing)に無償なら１デバイスあたり10万/月のデータ投入ができると書いてあります。この程度の使い方なら問題なしです。
使いはじめるまでのアカウント登録の説明はカットします。

使えるようになったら、デバイスをまず登録しましょう。
`Create New`から`Device`を選択して、新規デバイスを登録します。
M2XがIoTを意識しているので、名前がデバイスになっていますが、デバイスじゃなくても、何でもOKです。

ただ単に、データを投げ込む場所を作っているようなイメージでいいと思います。
`Device`の下には`STREAM`がぶら下がるようになっています。
`STREAM`はデータを記録する最小単位なので、curlなどでデータを投げ込むときには、`Device`を特定するDEVICE IDと、STREAM名を指定する感じになります。
詳しくは[チュートリアル](https://m2x.att.com/developer/tutorials/retrieving-data)を参考にしてください。

今回はIFTTT経由で投げ込むので、`Device`と`STREAM`を作っておくだけで準備としてOKです。
![FireShot Capture 3 - AT.png](https://qiita-image-store.s3.amazonaws.com/0/95484/4c4a9ee2-6d67-353f-fe28-723aef440fe4.png)
登録例としてはこんな感じです。

#IFTTTのレシピ

![ifttt.png](https://qiita-image-store.s3.amazonaws.com/0/95484/555b7fc7-90b8-7e12-8bb8-981127ab95fa.png)
IFTTTでは上記のようなレシピを作っていきます。
MakerチャンネルにTaskerから投げ込まれたバッテリー情報をM2Xに流していきます。
流し先を変えるだけで、違う所に出力できるのがIFTTTの良い所。
Google Driveのスプレッドシートに記録することも可能です。

M2X側の設定はこんな感じです。
`Which device?`に先ほど、M2Xで作った`Device`のDEVICE IDを入れましょう。
IDはすぐわかるはずです。

お次に`Which stream?`に上記の設定例で示した`STREAMS`に表示されているstream名を入れましょう。
本例の場合は`xperiaz3compact`になります。

![Screenshot_2016-05-10-13-17-31.png](https://qiita-image-store.s3.amazonaws.com/0/95484/a02880f6-e66e-7c28-1d4d-9abf464cff5f.png)

#さいごに

設定が万事うまくいけば、以下のようにバッテリーの変化がトリガになりTasker→IFTTT→M2Xとデータが流れて自動的に記録されるようになります。
![FireShot Capture 2 - AT.png](https://qiita-image-store.s3.amazonaws.com/0/95484/78806d15-770c-7289-30e2-84a56426c82c.png)

今回はTaskerによるバッテリーの変化を記録するという役に立つんだか、立たないんだかというよくわからないものを可視化してみましたが、有意義なデータを見つけて、同じように記録すると面白いかもしれません。
個人的には「Wolfram Data Drop」にバッテリー、WiFi、Bluetooth、CPU速度、バッテリー温度、GPSデータ、セルラー情報等々を流し込み、そのデータ群から何かしらの分析ができるようになると、ちょっと本格的になるかなと思っています。
時間が取れたら試してみる予定です。
condaによるパッケージ管理に関するメモ

## condaによるパッケージ管理

基本的に下記を参照して、condaでパッケージ管理をする事にした。

[conda で python の環境つくり](https://gist.github.com/aphlysia/d5fcee79ff81b8272faf)

基本的には上記に習って、conda install　で見つからないパッケージなどは
下記のようにビルド用のレシピを作って、ローカルでビルドして、そこから
インストールすれば全てのパッケージがconda配下で管理出来るようだった。

```shell-session:shell
$ conda skeleton pypi <パッケージ名>
$ conda build <パッケージ名>
$ conda install --use-local <パッケージ名>
```

ただし、いくつかのパッケージで上手くビルドが出来ないなど
すんなりいかない事が合った。

## basemapがインストール出来ない

matplotlibのtoolkitであるbasemapパッケージを入れようとしたところ、
レシピ作り（conda skeleton pypi basemap）までは上手く行くのだが、
ビルド時に、numpyが無いよと怒られた。

```shell-session:shell
ImportError: No module named numpy
```

numpyは当然入っている。
色々調べた所、同様の事象にあっている下記を見つけた。

[conda build - ImportError: No module named numpy](https://groups.google.com/a/continuum.io/forum/#!topic/conda/_RKztl0rE5s)

これによれば、meta.yamlファイルを編集すれば良いと書いてあったので、
conda skeleton pypi basemap を実行したディレクトリ配下の
basemap ディレクトリ配下にあった　meta.yaml ファイルの以下

```yaml:meta.yaml
requirements:
  build:
    - python
  run:
    - python
```

だった部分を

```yaml:meta.yaml
requirements:
  build:
    - python
    - numpy
  run:
    - python
    - numpy
    - matplotlib
```

と修正してあげたところ、無事ビルドしてインストールする事が出来た。
（※run に matplotlib を書いているのは、numpyだけでビルドまでは通ったけど、
その後、matplotlib が無くてテスト時に失敗したため）

日本語だとあまり情報が無かったのでひとまずメモ。

---------20161204追記---------

ある日

```shell-session:shell
$ conda skeleton pypi <パッケージ名>
```

でエラーが出るようになった。

[conda skeleton pypi throws xmlrpc.client.Fault]
(https://github.com/conda/conda-build/issues/1207)

のエラーと同様のもので、conda-buildのバグのようだった。
すでに修正済みのバグだったので、

```shell-session:shell
$ conda install -n root conda-build
```

でcondo-buildを最新版にアップデートしたら、無事解決。
OpenStack Client を使用してGMO ConoHa にポート設定 (Windows編)

# ConoHa でサーバー
少し前からConoHa のサーバーをレンタルし、ゴニョゴニョ立ち上げようかと思ってます。
(ConoHaはこちらから。https://www.conoha.jp/)

今回は家からConoHaサーバーに立ち上げてある Redis サーバーに接続しようとしたときの作業ログようなもの。

ちなみにConoHaに入れたOSは Arch Linux。

# ConoHa サーバー のネットワークのポート
デフォルトで設定されているポートは、ConoHa の管理画面上から簡単に管理出来ます。
しかし、デフォルトに無いポートは設定をする方法がGUIには用意されていません。

ここでポートを追加する方法は二つあって、
1. curlを使用し、ConoHaのWebApiを叩く
2. OpenStack Clientを使用する

今回はOpenStack自体が初めてだったので2.の方法で作業を行います。

# OpenStack Clientのインストール
OpenStack Clientは、Pythonのpipで簡単にインストールが可能となっています。

```bash
pip install python-openstackclient
```
※ 私が構築したときにはpyvenvの仮想環境内で作業を行いました。

# ConoHa 管理画面から必要なデータを取得
まず準備としてApiを使用するための各種情報が必要です。
OpenStackを使用する場合、下記の情報を管理画面から取得しておきます。

<dl>
  <dt>コントロールパネル > API</dt>
  <dd>"テナント情報": テナント名</dd>
  <dd>"エンドポイント": Identity Service</dd>
  <dd>"APIユーザー": ユーザー名とパスワード</dd>
</dl>

# OpenStackへ接続するための環境設定
Windows コマンドプロンプトの一時的な環境設定方法。
先に取得しておいたAPIの情報を下記のように設定。

```bash
set OS_USERNAME=APIユーザー名
set OS_PASSWORD=APIパスワード
set OS_AUTH_URL=Identity Service
set OS_TENANT_NAME=テナント名
```
よくある例ではLinuxのbashで設定するように書かれています。
その際、OS_PASSWORDにシングルクオートで文字列が囲まれているが、Windowsでは必要なし。むしろ書いてしまうとおそらく繋がらないかも(繋がらなかった)。

また、5/8現在だとneutron等の各機能別のアプリケーションは非推奨となり、neutron等一部のアプリケーションはインストールされなくなっています。

# neutronは必要だ
だがしかし、ConoHaの制限でSecurity Groupはポート(NIC)に対してのみ設定が行えます[^1]。
そのため、neutronでしか使えない(と思われる[^2]) port-updateコマンドが必要なため、neutronも別途インストールする必要があります。

```bash
pip install python-neutronclient
```

# セキュリティグループの作成～サーバーへの紐付け
ここからは実際にOpenStackのコマンドを使用して行う作業になります。
例としてRedisで設定を行う場合を上げておきます（gropuがredisになっているだけなので、そこは好きに変更を）

```bash
> openstack
> security group create redis --description "allow Redis connect"
> security group list
> security group rule create --dst-port <from-port:to-port> <Security group Id>
> security group rule show <Security group Id>
> port list
> port show <Port Id>
> neutron port-update --security-group <Security group Id> <Port Id>
> port show <Port Id>
```

流れは以下。
1. openstack クライアントを立ち上げる
2. Security Groupの作成
3. Security Group listでIDを確認
4. Security Group ruleの作成
5. Security Group ruleを確認
6. port list, port show でポートを割り当てるサーバー等を確認
7. neutron port-update でポートに対してSecurity Groupを割り当てる。
8. port show でポートがアップデートされているかを確認

5.のneutron port-updateは、security-groupを追加ではなく、上書きする仕様になっています。なので、現在のものも含めて必要な分を追加する必要があります。

複数同時にsecurity-groupを追加する方法は、
--security-group \<Security group Id\>
このオプションを必要な分だけ繋げていけば良いです。

また、各種コマンドのヘルプを見るとSecurity Groupの名前でも設定できるような解説がされていますが、私がやったところでは一部のコマンドで受け付けませんでした。
そのため今回は全てID形式で指定しています。

# 確認
残念ながらAPIで追加したポートは、ConoHaのGUIから確認は出来ないようです。
ポートが空いてるかの確認は、実際にポートを使用してみるのが早そうです。

以上。

# 注釈
[^1]: [第5回　OpenStack APIを使ったCLI操作をConoHaでやってみる：個人利用から大規模開発までConoHaで始めるクラウド開発入門｜gihyo.jp … 技術評論社](http://gihyo.jp/dev/serial/01/conoha/0005?page=2)
[^2]: ConoHaのサポートに問い合わせても「neutron使ってね」と来たのでおそらくOpenstack clientにはまだ方法がないのだろう。
型を表示する関数

型を表示して何か嬉しいんだろうかと思ったけど、意外と面白かったので載せておきます。

<del>一般的な型に対してログへの出力なんてことは出来ないので型クラスを作りました。
あとは出力出来る型を増やしたかったらTemplateHaskellとか使って頑張ってください。</del>
Typeable使ったらできました。後述。

```hs
#!/usr/bin/env stack
-- stack --resolver lts-5.8 runghc

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE PolyKinds #-}

import Data.Proxy
import System.IO

class ShowType (t :: k) where
    showType :: Proxy t -> String

instance ShowType () where
    showType _ = "()"
instance ShowType Int where
    showType _ = "Int"
instance ShowType Double where
    showType _ = "Double"
instance ShowType String where
    showType _ = "String"
instance ShowType Bool where
    showType _ = "Bool"
instance ShowType IO where
    showType _ = "IO"
instance ShowType Maybe where
    showType _ = "Maybe"
instance ShowType [] where
    showType _ = "[]"
instance ShowType (->) where
    showType _ = "(->)"


instance {-# OVERLAPPABLE #-} (ShowType a, ShowType b) => ShowType (a, b) where
    showType _ = "(" ++ showType (Proxy :: Proxy a) ++ ", " ++ showType (Proxy :: Proxy b) ++ ")"
instance {-# OVERLAPPABLE #-} ShowType a => ShowType [a] where
    showType _ = "[" ++ showType (Proxy :: Proxy a) ++ "]"
instance {-# OVERLAPPABLE #-} (ShowType b, ShowType c) => ShowType (b -> c) where
    showType _ = showType (Proxy :: Proxy b) ++ " -> " ++ showType (Proxy :: Proxy c)
instance {-# OVERLAPPABLE #-} (ShowType b, ShowType c, ShowType d) => ShowType ((b -> c) -> d) where
    showType _ = "(" ++ showType (Proxy :: Proxy b) ++ " -> " ++ showType (Proxy :: Proxy c) ++ ") -> " ++ showType (Proxy :: Proxy d)

instance {-# OVERLAPPABLE #-} (ShowType f, ShowType t) => ShowType (f t) where
    showType _ = showType (Proxy :: Proxy f) ++ " " ++ showType (Proxy :: Proxy t)
instance {-# OVERLAPPABLE #-} (ShowType a, ShowType b, ShowType c) => ShowType (a b c) where
    showType _ = showType (Proxy :: Proxy a)
        ++ " " ++ showType (Proxy :: Proxy b)
        ++ " " ++ showType (Proxy :: Proxy c)

logType :: forall t. ShowType t => t -> IO ()
logType _ = hPutStrLn stderr $ showType (Proxy :: Proxy t)

main = do
    logType (1 :: Int)
    logType (3.4 :: Double)
    logType getLine
    logType putStrLn
    logType (Just "Heyhey")
    logType (even :: Int -> Bool)
    logType ((+) :: Int -> Int -> Int)
    logType [True, False]
    logType (map :: (Int -> String) -> [Int] -> [String])
    logType (undefined :: [Int -> IO String] -> [Int] -> IO [String])
    logType (undefined :: ([(Int -> Int) -> IO String] -> [Int] -> IO [String]) -> Maybe Bool)
    logType (True, "hey")
```

関数渡すとその型が表示されるとか面白いですね。
型パラメータが残っているようなものは表示できません。

## Typeableを使う

`showsTypeRep`という便利なものがあるそうです（一応探したつもりだった）
sarコマンドにおけるサマリ（随時追記）

基本的にはググって見つけた内容を集めています。
sosreportからvar/log/sa/sar○○ファイルを確認するイメージで書いているので、sarコマンドについては触れていません。


# 凡例
## ブロック
### サマリのヘッダ名
説明（日本語ゲットできたら転載、英語の場合は原文）
> 英語の場合は翻訳（自分で訳しているので間違っていたらごめんなさい）


# サマリ内容

## CPU関連

### %user
ユーザーレベル（アプリケーション）の実行によるCPU利用の割合。
このフィールドは仮想プロセッサ上で実行された時間も含む事に注意。

### %usr
ユーザーレベル（アプリケーション）の実行によるCPU利用時間の割合。
このフィールドは仮想プロセッサで実行された時間を含まない事に注意。

### %nice
Niceプライオリティで実行された、ユーザーレベルのCPU利用時間の割合。

### %system
システムレベル（カーネル）の実行によるCPU利用時間の割合。
このフィールドは割り込みやソフト割り込みの処理に使われた時間も含まれる事に注意。

### %sys
システムレベル（カーネル）の実行によるCPU利用時間の割合。
このフィールドは割り込みやソフト割り込みの処理に使われた時間を含まない事に注意。

### %iowait
システムがI/Oリクエストの処理のためCPUがアイドルになった時間の割合。

### %steal
ハイパーバイザーが他の仮想プロセッサを処理している間の仮想CPUの非自発的な待ち時間の割合。

### %irq
割り込みを処理するために使われたCPU時間の割合。

### %soft
ソフト割り込みを処理するために使われたCPU時間の割合。

### %guest
仮想プロセッサを実行するのに使われたCPU時間の割合

### %idle
CPUがアイドルで、かつI/Oリクエストの処理完了を待っていない時間の割合。

**注意：[SMPマシン](https://ja.wikipedia.org/wiki/%E5%AF%BE%E7%A7%B0%E5%9E%8B%E3%83%9E%E3%83%AB%E3%83%81%E3%83%97%E3%83%AD%E3%82%BB%E3%83%83%E3%82%B7%E3%83%B3%E3%82%B0)では、アクティビティの全く発生していない（全項目が0.00）プロセッサは、無効化されたプロセッサである。**

## メモリスワップ関連

### pgpgin/s
1秒間にディスクからページインされているブロック数(KB)

### pgpgout/s
1秒間にディスクからページアウトされているブロック数(KB)

### pgswpin/s
1秒間にディスクからページインされているページ数

### pgswpout/s
1秒間にディスクからページアウトされているページ数

**1秒間に100ページをスワップ・アウトした場合、pswpout/sは100となり、pgpgout/sは400となる。これは1ページが通常4KBであるため。**
**スワップが多発しているかどうかを判断する指標はpswpout/s(およびpswpin/s)であり、pgpgout/s(およびpgpgin/s)ではない。**

## ディスクIO関連

### tps
物理デバイスに対し発行された１秒あたり総転送数。転送とは、物理デバイスに対してのi/Oリクエストの事である。複数の論理リクエストは単一のI/Oリクエストとして結合される場合がある。各転送のサイズは不定である。

### rtps
物理デバイスに対し発行された1秒あたり総読み取りリクエスト数。

### wtps
物理デバイスに対し発行された1秒あたり総書き込みリクエスト数。

### bread/s
デバイスから1秒間に読み取られた総ブロック数。ブロックはカーネル2.4以降ではセクタと同じであり、512バイトの大きさである。それより古いカーネルについては、ブロックのサイズは不定である。

### bwrtn/s
デバイスに対し1秒間に書き込まれた総ブロック数。

## ページキャッシュ関連

### frmpg/s
1秒あたりのシステムが開放したメモリページ数です。 マイナスの値はシステムが割り当てたページ数を表します。 1 ページのサイズはマシンのアーキテクチャによって 4kB または 8kB となります。

### bufpg/s
1秒あたりのシステムが新たにバッファとして使用したメモリページ数です。 マイナスの値はシステムがバッファとして使用したページが殆ど無いことを意味します。

### campg/s
1秒あたりのシステムが新たにキャッシュしたメモリページ数です。 マイナスの値はキャッシュにページが殆ど無いことを意味します。

## 物理メモリ関連

### kbactive
Amount of active memory in kilobytes (memory that has been used more recently and usually not reclaimed unless absolutely necessary).
> アクティブなメモリの量(KB)
※直近で使用されたメモリ、必要のない限り再利用されない（開放されない）メモリ

### kbinact
Amount of inactive memory in kilobytes (memory which has been less recently used. It is more eligible to be reclaimed for other  purposes).
> アクティブでないメモリの量(KB)
※直近で使用していないメモリ、その他の用途が必要な場合に使用する（開放する）メモリ

### kbdirty
Amount of memory in kilobytes waiting to get written back to the disk.
> ディスクに書きもどされるのを待っている（スワップ対象？）メモリの量(KB)

# 参考

自作データベース環境で各種実験
http://backslash0134.blog.fc2.com/blog-entry-63.html

SYSSTAT
http://sebastien.godard.pagesperso-orange.fr/man_sar.html

sar の pgpgout/s と pswpout/s の関係
http://d.hatena.ne.jp/incarose86/20110712/1310496747

kSarでsysstat(sar)をグラフ化したのはいいのだが、読めないので解読してみる
http://d.hatena.ne.jp/japanrock_pg/20090415/1239795768
cakephp3 移設ログ


備忘録。
cakephp3をローカルからvpsに移設した際に発生したバグ。

General error: 8 attempt to write a readonly database
=

app/tmp/debug_kig.spliteを書き込み可にすることで解決。

```
chmod 777 app/tmp/debug_kit.sqlite
```


その後、

General error: 14 unable to open database 
=

と出たので、次は app/tmp を書き込み可にすることで解決した。

```
chmod -R 777 app/tmp/
```
apkバージョンとサイン設定を環境変数で設定する

# 目標

- リリースビルドのバージョンを自動的に設定する。
- 同じコミットが同じバージョンになる ("再現できるビルド")。
- サインキーなどをコミットに残さない。
- これらの設定を必須としない: 開発者がcloneしてからすぐ実行できる。

# 原理

- コミット自身の情報で、バージョンを生成する
- バージョンとサイン設定を環境変数としてインジェクトする
- 上記環境変数がない場合、暗黙的にデフォルト設定を使う

# コード

### `build.gradle`:
```groovy
// 環境変数をString / Integerに読み込む関数
def env = { System.getenv it }
def envInt = { Integer.parseInt(env(it)) }

android {
    defaultConfig {
        if (env("ANDROID_VERSION_CODE")) {
            // 環境変数のバージョンを優先に使う
            versionCode envInt("ANDROID_VERSION_CODE")
            versionName env("ANDROID_VERSION_NAME")
        } else {
            // 環境変数がなければデフォルト設定を使う
            versionCode 1
            versionName "1.0"
        }
    }
}

if (env("ANDROID_SIGN_APK"))
// サイン設定: 環境変数がある場合のみ適用される
android {
    signingConfigs {
        releaseSigning {
            storeFile file(env("ANDROID_KEYSTORE_PATH"))
            storePassword env("ANDROID_KEYSTORE_PASS")
            keyAlias env("ANDROID_KEY_ALIAS")
            keyPassword env("ANDROID_KEY_PASS")
        }
    }

    buildTypes {
        release {
            signingConfig signingConfigs.releaseSigning
        }
    }
}
```

### CIサーバのビルドコマンド:
```bash
#!/bin/bash

# JDK & SDKパス
export ANDROID_HOME=/somewhere/android-sdk-linux
export JAVA_HOME=/somewhere/jdk1.8.0_65

# サイン設定
export ANDROID_KEYSTORE_PATH=/somewhere/keys.jks
export ANDROID_SIGN_APK=yes
export ANDROID_KEYSTORE_PASS=secret
export ANDROID_KEY_ALIAS=secret
export ANDROID_KEY_PASS=secret

# バージョン設定
# versionCode: 現在のコミットからたどり着けるコミットの数 (=== 先祖コミット数+1)。
# リリースブランチであればたいてい単調増加する。連続ではないが。
export ANDROID_VERSION_CODE="$(git rev-list HEAD --count)"
# versionName: 現在のコミットSHA1の最初の8文字
export ANDROID_VERSION_NAME="${GIT_COMMIT:0:8}"

exec sh gradlew assembleRelease
```
PHP7でphpMyadminの設定につまずく

# 環境

- OS: Ubuntu 14.04 LTS
- Web Server: Apache 2.4.7
- PHP: PHP 7.0.6-6+donate.sury.org~trusty+1 (cli) ( NTS )

# 問題

PHP7でphpMyadminを使おうとしたら、

>localhost ページは機能していません
>localhost では現在このリクエストを処理できません。
>HTTP ERROR 500

とエラーが表示された。

エラーログを確認。

```zsh
cat /var/log/apache2/error.log

...
[Wed May 11 22:13:47.598181 2016] [:error] [pid 3388] [client ::1:36156] PHP Fatal error:  require_once(): Failed opening required './libraries/php-gettext/gettext.inc' (include_path='.:/usr/share/php') in /usr/share/phpmyadmin/libraries/select_lang.lib.php on line 395
```

php-gettextがないと怒られているようだ。PHP7ではphp-gettextがデフォルトではインストールされないそう。

# 解決策
ということで、

```zsh
sudo apt-get install php-gettext
```

で解決。

# 参考文献
1. [phpmyadmin symlinks error after ubuntu upgrade](http://superuser.com/a/1067765)
golang: ファイル分割したソースコードを同じディレクトリにおいて、go runしても起動できなかったが、buildなら動いた話


まずは、テスト用のディレクトリを作る

```bash
$ mkdir golang-test && $_
```

このようなファイルがあったとする

```go:main.go
package main

import "fmt"

func main(){
  fmt.Println("Execute main")
  subfunc()
}
```

```go:ub.go
package main

import "fmt"

func subfunc(){
  fmt.Println("Execute sub function")
}
```

ここで、goを起動しようとして、以下を実行する

```bash
$ go run main.go
```

すると、見事にエラー

```
# command-line-arguments
./main.go:7: undefined: subfunc
```

情報を検索していると、どうやら、`go run <go src>`は使えないらしい
ただし、`go build`ならば、うまくいくらしい

```
$ go build
$ ls
golang-test  main.go  sub.go
$ ./golang-test
Execute main
Execute sub function
```

うまくいった
Raspiで動かすvalue-domainのDDNSスクリプト

Raspi君でValue-domainのDDNSの更新させるためにスクリプト探したら良いのが有りました。

[シンプルだけどIP変更チェック付きのValue DomainのDDNSアップデートスクリプト](http://qiita.com/yuya_presto/items/cd6bcd36c6bb18dac8bf)

こちらを参考にさせていただいて、若干カスタマイズしたので将来の自分の為に載せておきます。

主にCron定期実行時のログをSyslogに出す為にちょこちょこっといじりました。loggerの部分とか、Update用のWgetの結果をteeしてる所とかです。
あ、あと、設定ファイル名にハイフン使わずアンダースコアにしました。

```bash
#!/bin/bash

CONFIG_FILE='/etc/update_ddns.conf'
IP_CACHE_FILE='/tmp/update_ddns_ip'
DDNS_CACHE_FILE='/tmp/update_ddns_result'

# sources DOMAIN= , PASSWORD= and HOST=
source $CONFIG_FILE

old_ip=`[ -e $IP_CACHE_FILE ] && cat $IP_CACHE_FILE || echo ''`
new_ip=`wget --quiet -O - 'http://dyn.value-domain.com/cgi-bin/dyn.fcg?ip'`
if [ "$old_ip" = "$new_ip" ]; then
    echo "NO CHANGE ($new_ip)"
    logger -t UPDATE_DDNS "INFO: NO CHANGE ($new_ip)"
    exit 0
fi

url="http://dyn.value-domain.com/cgi-bin/dyn.fcg?d=$DOMAIN&p=$PASSWORD&h=$HOST"
result=0
wget --quiet -O - "$url" 2>/dev/null | tee $DDNS_CACHE_FILE | grep 'status=0' >/dev/null && result=1

if (( !$result )); then
    echo `date` 'FAILED'
    logger -t UPDATE_DDNS "ERROR: FAILED result:" `cat $DDNS_CACHE_FILE`
    exit 1
fi

echo $new_ip > $IP_CACHE_FILE

echo "UPDATED ($new_ip)"
logger -t UPDATE_DDNS "INFO: UPDATED with new IP:$new_ip"
exit 0
```

設定ファイルの中身は[参考にさせて頂いたもの](http://qiita.com/yuya_presto/items/cd6bcd36c6bb18dac8bf)と同じです。

運用としては、１０分毎にでもRootのCronとして動かそうと思ってます。
あ、標準出力も残したままなので、Cron入れる際は` > /dev/null`とかしといたほうが良いと思います。
Emacsでも愛が生まれた


![live_and_death.gif](https://qiita-image-store.s3.amazonaws.com/0/4121/133ebcc5-81a5-60a5-97a2-1af029fd8b43.gif "live_and_death.gif")

```el:live_and_death
(progn
  (kill-region (point-min) (point-max))
  (insert (logand ?生 ?死)))
```

私からは以上です。
C#の課題・・泣

![DSC_0040.JPG](https://qiita-image-store.s3.amazonaws.com/0/125156/7c2f8685-4392-14e6-cc40-d9c1a9c7d2c7.jpeg)

3秒が経って、ボタンが押せないようになり
labelの部分に何回クリックしたのか表示されるようにするにはどうしたらいいですか？

※できればリセットボタンについても教えて頂けたらありがたいです！


よろしくお願いいたします！
Rust "recursion limit reached while expanding the macro `lazy_static`" でエラーになった場合の対処方法

## はじめに
タイトルの通りなのですが、Rustでコンパイル時にタイトルのエラーが出たときの回避方法です。

## 前提条件
| 項目 | 説明 |
|------|------------------|
| 検証日 | 2016.05.10 |
| OS   | Mac OS X 10.11.4 |
| Rust | Stable 1.8.0 |

## エラー
[woothee-rust](https://github.com/hhatto/woothee-rust/)実装時に[lazy_static.rs](https://github.com/rust-lang-nursery/lazy-static.rs)を使っていたのですが、
以下のようなコードを書いたときにコンパイルエラーが発生しました。

```parser.rs
use std::collections::HashMap;
use regex::Regex;
use dataset;
use woothee::VALUE_UNKNOWN;

lazy_static! {
    static ref RX_CHROME_PATTERN: Regex = Regex::new(r"(?:Chrome|CrMo|CriOS)/([.0-9]+)").unwrap();
    static ref RX_DOCOMO_VERSION_PATTERN: Regex = Regex::new(r#"DoCoMo/[.0-9]+[ /]([^- /;()"']+)"#).unwrap();
    static ref RX_FIREFOX_PATTERN: Regex = Regex::new(r"Firefox/([.0-9]+)").unwrap();
    static ref RX_FIREFOX_OS_PATTERN: Regex = Regex::new(r"^Mozilla/[.0-9]+ \((?:Mobile|Tablet);(?:.*;)? rv:([.0-9]+)\) Gecko/[.0-9]+ Firefox/[.0-9]+$").unwrap();
    static ref RX_FIREFOX_IOS_PATTERN: Regex = Regex::new(r"FxiOS/([.0-9]+)").unwrap();
    static ref RX_FOMA_VERSION_PATTERN: Regex = Regex::new(r"\(([^;)]+);FOMA;").unwrap();
    static ref RX_HEADLINE_READER_PATTERN: Regex = Regex::new(r"(?i)headline-reader").unwrap();
			:
	static ref RX_MAYBE_CRAWLER_OTHER: Regex = Regex::new(r"(?:Rome Client |UnwindFetchor/|ia_archiver |Summify |PostRank/)").unwrap();
}
```
[ファイル全体](https://github.com/hhatto/woothee-rust/blob/4c7dcca9fb0ca940175d8a1beb6eeb9b7ae03e17/src/parser.rs)


以下コンパイルエラーの内容

```
$ cargo build --release
   Compiling woothee v0.2.0 (file:///Users/hattori-h/work/woothee-rust)
<lazy_static macros>:14:1: 14:67 error: recursion limit reached while expanding the macro `lazy_static`
<lazy_static macros>:14 lazy_static ! ( @ MAKE TY , $ VIS , $ ( # [ $ attr ] ) * , $ N ) ; impl $
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Could not compile `woothee`.

To learn more, run the command again with --verbose.
```

## 回避方法
`#![recursion_limit="xxx"]` を記述して再起呼び出し上限を変更して対処しました。woothee-rustでは100にしました。
（ざっくり調べてみたところデフォルト値はおそらく64です。）

## おわりに
なぜ `lazy_static!{}` 内に大量の定義をすると再起上限に引っ掛かるのか理由はわかりませんでした。
小さなコードで `rustc -Z unstable-options --pretty expanded example.rs` を試してみてもよくわからず。
今後、詳細な理由がわかったら追記する予定です。とりあえずメモを残しておきます。

詳しい方いたら教えてください！！
大量のホスト名に対して名前解決した結果をCSVにしたい

# やりたいこと
大量のホスト名に対して、名前解決してIPv4アドレスを取得して、一覧をCSVにしたい。
環境はWindows7標準のPowerShell 2.0。

# コード
```ps1:nslookuplist.ps1
# nslookupしたいホスト名を
#     www.yahoo.co.jp
#     www.google.co.jp
# のようにファイルにリスト化しておく。ここではファイル名「hostnames.txt」。 
$hostnames = (cat "hostnames.txt")    #  ★1

# 配列の定義（初期でヘッダの設定）
$rows = @("hostname,ip")
$ips  = @()
$result = $false
foreach ($hostname in $hostnames) {
   
    try {
        # IPv4アドレスのみ取得
        $ips = [System.Net.Dns]::GetHostAddresses($hostname) | ? { $_.AddressFamily -eq "InterNetwork" }
    } catch [Exception] {
        # 名前解決できなかったら空欄
        $ips = @("")
    }

    foreach ( $ip in $ips) {
        # 1行の結果をカンマ区切りで追記
        $rows += $hostname + ","  + $ip
    }

}

# result.csv に結果をCSVで出力する 
$rows | ConvertFrom-Csv | Export-Csv "result.csv" -NoTypeInformation  # ★2

```

＜おまけ1＞
★1の箇所で対象ホスト名を別のファイルにしておくのが面倒なときは
以下のように定義します。

```ps1:★1の箇所をコード内で定義する場合
$hostnames = @"
www.yahoo.co.jp
www.google.co.jp
"@ -split "`r`n"
```

＜おまけ2＞
★2の箇所でファイルに出力せず、
グリッドビュー（結果例は後述）に表示したい場合は以下のようにします。

```ps1:★2の箇所をグリッドビューで表示する場合
$rows | ConvertFrom-Csv | Out-GridView
```

# 結果例
```text:result.csv
"hostname","ip"
"www.yahoo.co.jp","183.79.75.234"
"www.yahoo.co.jp","183.79.43.200"
"www.yahoo.co.jp","183.79.139.228"
"www.yahoo.co.jp","118.151.235.191"
"www.google.co.jp","216.58.197.195"
```

★2の箇所でグリッドビューに表示するようにした場合は以下のようになります。
![Image1.png](https://qiita-image-store.s3.amazonaws.com/0/113577/fd838819-c77d-3321-e1ed-cf4d106e2d9e.png)


以上です。
Cの共用体で愛が生まれた


http://ideone.com/J0Bw6Y

```c:
#include <stdio.h>
#include <string.h>

int main(void) {

  union {
    long l;
    char s[sizeof(long)];
  } t1, t2, t3;
  strcpy(t1.s, "死");
  strcpy(t2.s, "生");
  t3.l = t1.l & t2.l;
  printf("%s + %s = %s\n", t1.s, t2.s, t3.s);

  return 0;
}
```

```sh:output
死 + 生 = 愛
```

[愛が生まれた](http://qiita.com/dongri/items/041ff3e7dde6c99beeb0)
[なんで愛が生まれるのか](http://qiita.com/tienlen/items/44daf3a52eb872085556)
Rubyでも愛が生まれた

http://qiita.com/dongri/items/041ff3e7dde6c99beeb0

```rb
using Module.new {
  refine(String) do
    def &(other)
      [ord & other.ord].pack('U*')
    end
  end
}

puts '生' & '死'
# 愛
```
HTML,CSS勉強メモ#24' ～原因は`script`の順番～

やっと`popover`の泥沼から抜け出しました。

##**メモ**##
###`script`の順番

色々いじってる間に`script`の順番を変えてしまっていたようです。

・Befor

```html
<script src="bootstrap/js/bootstrap.min.js"></script>  <!-- JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>  <!-- jQuery -->
<script>
   $(function) {
       $('[data-toggle="tooltip"]').tooltip();
       $('[data-toggle="popover"]').popover();
   });
</script>
```

・After

```html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>  <!-- jQuery -->
<script src="bootstrap/js/bootstrap.min.js"></script>  <!-- JavaScript -->
<script>
    $(function) {
        $('[data-toggle="tooltip"]').tooltip();
        $('[data-toggle="popover"]').popover();
</script>
```

JavaScriptが最初に読み込まれるようになっていたんですね。
この辺のところがまだよくわかっていないようです。もう一度JavaScriptとかの勉強しなおそうかな。
ひとまずこれでbootstrap 3.0入門は完全に終了です。

[試行錯誤のあと](https://github.com/marin-takagi/responsiv_lesson/commit/68276dddddc80077c6d7b1835cebddc15e8c9d8e)