OmniAICreator/Qiita-1.07M huggingface dataset:
Qiita Markdown 記述メモ


Qiitaに投稿するに当たってどのように書けばいいかわからなかったので、
投稿の仕方も兼ねて、個人的に使いそうな書き方をピックアップし、まとめた。

以下を参考
[Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d#format-text---%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%81%AE%E8%A3%85%E9%A3%BE)

## コード挿入

> (空行)
> \`\`\`{言語}:{ファイル名}
> コード内容
> \`\`\`
> (空行)

言語を指定することでシンタックスハイライトが適用される。


#### コード挿入 例

> \`\`\`java:test.java
> System.out.println("hoge");
> \`\`\`


```java:test.java
System.out.println("hoge");
```

## 見出し

* `#` H1タグ
* `##` H2タグ

右側に出てくる目次にも影響が出てきそうなので、
基本的には、

`##` で1ブロックの見出し、
`###` でブロック内での見出しとするのが適切そうか。

## 強調・打ち消し線

### 強調

`__` か、 `**` で囲むと、**太字**になる。

### 打ち消し線

`~~` で囲むと、~~打ち消し線~~  となる。


## リスト

### Disc型

* 文頭に `*`, `+` , `-` いずれかを入れる。
* `tab` キーでスペースを挿入すれば、入れ子構造にもできる。

#### Disc型 例

* hoge
    * huga
    * piyo
        * ほげ
            * ふが
                * ぴよ

### Decimal型

* 文頭に `数値. ` を入れる
* 後から追加するなどを考慮して 1.2.3 のようにするのではなく、 1.1.1 のように同じ数字にしておくのが良い書き方らしい。(補完機能でインクリメントされるみたいだが...)

#### Decimal型 例

1. hoge
    1. ほげ
    1. ふが
1. huga
1. piyo 

## 引用

* 文頭に `>` を置くことで引用となる。
* ~~複数行にまたがる場合は、改行のたびに `>` を置く必要あり~~
    * 上記は誤り。改行のたびに `>` は不要 
    * 途中空行が含む場合のみ `>` を置く

```
> 1行目
2行目
3行目
```

> 1行目
2行目
3行目

```
> 1行目
2行目
3行目
>
5行目
```

> 1行目
2行目
3行目
>
5行目

## 水平線

下記はすべて水平線として表示される。

`* * *`
`***`
`*****`
`- - -`
`---`

---

## リンク

* `[リンクテキスト](URL "タイトル")`

### リンク 例

> `[Qiita](http://qiita.com "Qiita")`
> [Qiita](http://qiita.com "Qiita")


## 画像埋め込み

* `![代替テキスト](画像のURL "画像タイトル")`

### 画像埋め込み 例

> `![Qiita](https://qiita-image-store.s3.amazonaws.com/0/45617/015bd058-7ea0-e6a5-b9cb-36a4fb38e59c.png "Qiita")`
> ![Qiita](https://qiita-image-store.s3.amazonaws.com/0/45617/015bd058-7ea0-e6a5-b9cb-36a4fb38e59c.png "Qiita")

Qiita上であればドラック＆ドロップで自動で生成してくれるのであまり気にする必要無いかも。

## テーブル

参考サイトによると、入力補完できるらしいが、動かなかった。

手動で入力する方法

```
| Left align | Right align | Center align |
|:-----------|------------:|:------------:|
| This       | This        | This         |
| column     | column      | column       |
| will       | will        | will         |
| be         | be          | be           |
| left       | right       | center       |
| aligned    | aligned     | aligned      |

```

| Left align | Right align | Center align |
|:-----------|------------:|:------------:|
| This       | This        | This         |
| column     | column      | column       |
| will       | will        | will         |
| be         | be          | be           |
| left       | right       | center       |
| aligned    | aligned     | aligned      |


## 注釈

文中に`[^1]`や`[^example]`のように文字列を記述することで、脚注へのリンクを表現できます。注釈内容は、同じく本文中に `[^1]: ... `というように記述します[^1]。


[^1]: 注釈内容を記述する位置は、本文の途中でも末尾でも構いません。
bookmarks（20180701-20180731）

#コーディング
■Chromeデベロッパーツールの機能が、すごく簡単で便利！ローカルサーバーを1分もかからずにすぐ構築できる
https://coliss.com/articles/build-websites/operation/work/local-server-using-chrome-devtools.html
ルート相対パスで納品が必要な案件、この方法使えばローカルでパス合ってるかの確認できるよ！

■1行追加でOK！CSSだけで画像をトリミングできる「object-fit」プロパティー
https://www.webcreatorbox.com/tech/object-fit

■サーバー移転時の確認に必須のhosts書き換えに便利な「HostAdmin Apps」の使い方
http://primarytext.jp/blog/1545

・AndroidにHostsを書き換えずにPCのHostsを反映させる
　http://saburesan.hatenablog.com/entry/2017/11/02/094343
・Android3.1以降ではWi-Fiアクセスポイントごとにプロキシサーバの設定が可能
　http://android-smart.com/2012/03/android3-1%E4%BB%A5%E9%99%8D%E3%81%A7%E3%81%AFwi-fi%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E3%81%94%E3%81%A8%E3%81%AB%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E3%82%B5.html
・iPhoneやAndroidでドメイン開通前のサイトにアクセスする、結構簡単な方法
　http://iga-ninja.hatenablog.com/entry/2015/07/25/211935
・OS X の hosts ファイルを編集、切り替えが楽になるアプリ iHosts
　https://loumo.jp/wp/archive/20160511120017/

#アップデート
■WordPressブログをAMP対応させる公式プラグインのバージョン1.0ベータ版が公開。“ネイティブAMP”が実現
https://www.suzukikenichi.com/blog/amp-plugin-v-1-0-makes-native-amp-possible/

■Google 画像検索の参照元 URL の変更について（Googleウェブマスター向け公式ブログ）
https://webmaster-ja.googleblog.com/2018/07/an-update-to-referral-source-urls-for.html
→こちらは8月下旬から徐々に反映されてきたようです
　画像検索の新しいリファラーにGoogleアナリティクスが対応、参照元/メディアは google images/organic
　https://www.suzukikenichi.com/blog/google-images-reports-in-google-analytics/

#デザイン
■文字を入力すると日本語フリーフォント55種類を一覧比較できる無料サイト「ためしがき」
https://www.mdn.co.jp/di/newstopics/59726/

■色に頼らないビジュアル表現を考える
https://mkasumi.com/thinking-visual-without-color.html

#読みもの
■おばあちゃんの家にあった40年前のコンピュータが懐かしすぎて「おおお!」使い方が分からず皆で試行錯誤→【追記】ついに…!
https://togetter.com/li/1242906
なかなかの感動巨編なので読んで

■住所に革命？ what3words　地球上を57兆分割し3単語で表現
https://japanese.engadget.com/2018/07/09/what3words-57-3/

■Internet Explorer の今後について
https://blogs.technet.microsoft.com/jpieblog/2018/07/18/internet-explorer-support/
生みの親にも死を願われてしまうIEくん…哀れすぎる

8月のうちにまとめられなかったことを反省…
例外勉強メモ

# 例外の書き方を1時間で勉強してまとめたメモ
## 一般
どういった基準で例外を書くべきなんだろう？
>
+ 例外を乱用しない

> 例外は呼び出す側がINPUTの条件を満たしているが、呼び出された側でOUTPUTの条件を満たせなくなったときに投げる
>
by [業務でWebサービス開発をする際に気をつけたいこと（新卒向け)](https://qiita.com/zaru/items/71900d0e4b2afaaa955b)

　
> + コードの可読性が上がる
>
正常系と異常系の処理が混じっている ためコードが読みにくい。
by [もう少し例外を使用しても良いのではないか...](https://qiita.com/MasayaMizuhara/items/98c0d490f1633d9b636f)

### null安全
>null 安全 （または null 安全性 ）は null safety の訳語です。 null safety という用語は主に Kotlin コミュニティで使われているもので、言語によって Optional や Option, Maybe, nullable type などの型で実現できる、 null が原因で実行時エラーを起こさない性質のことを表します。そのような性質を表す言葉として null 安全 はぴったりだと思うので、本投稿では null 安全 という呼び方を採用します。
by [null安全でない言語は、もはやレガシー言語だ](https://qiita.com/koher/items/e4835bd429b88809ab33#fn1)

つまり…どういうことだってばよ？
↓
>本来「nullが渡されるケースは設計上意味を持たない」にもかかわらず、万が一のNullPointerExceptionを避けるためだけに、nullが渡された場合の処理を何かしら書かなければならないのです。
by [「null安全」とは――Javaプログラマーが血と汗と涙を流さなくてすむ理由](https://qiita.com/koher/items/e4835bd429b88809ab33#fn1)

なるほど！たしかに、単体テストの時にcatchに入るためにnull代入とかしてた時、「でもここにnull入るわけないよなぁ…」とか思ってました。
null安全は冗長な例外設計を避けることに寄与する技術なんですね（それだけではないでしょうが）。


## C++
### 基本的な例外処理

```
try {
	//例外が発生する可能性のあるプログラムコード
}catch (type arg) {
	//例外処理
}
```
`try` ブロックないで例外が発生した場合 `catch` ステートメントでそれを受け取ります
`catch` ステートメントが適切な例外を受け取り、用意された例外処理を行います

### 例外の投げ方
`throw exception;`
exceptionは例外の値を指定する。
⇒catch側の例外の型と合わせる必要がある。

例：

```
try {
	throw Exception(1);
}catch (Exception e) {
	//例外処理
}
```

### デフォルトの例外

`catch(...)`
全ての型の例外を受け取ることが可能。

### ~~例外指定(C++11で非推奨, C++17で削除)~~
>C++では、関数に例外指定というものが記述できる。これはC++98からある機能で、throw(T1, T2, ...)という文法で、関数が外に投げる例外を指定する機能だ。
もし、関数が例外指定に指定された以外の型を投げた場合、std::unexpectedが呼ばれる。

```
void f() throw( int ) 
{
    throw 0 ; // OK
    throw 0.0 ; // 実行時エラー: call std::unexpected() 
}
```
by [C++の例外指定](https://cpplover.blogspot.com/2014/10/c.html)

### void unexpected()

>
何らかの理由で例外を破棄する必要がある場合に呼び出されます
この関数は、abort() を呼び出してプログラムを以上終了させます
by [例外処理](http://wisdom.sakura.ne.jp/programming/cpp/cpp35.html)

### noexcept
```
void f() throw( ) ;
```
> ある主要なC++コンパイラーは、この記述を、関数は例外を外に投げないという意味にみなし、最適化のためのヒントに使い始めた。

> C++11では、無例外保証の指定機能だけに特化した、noexceptが追加された。noexceptを指定すると、関数は外に例外を投げないと指定したことになる。
by [C++の例外指定](https://cpplover.blogspot.com/2014/10/c.html)

>大部分の関数は現実にはnoexcept宣言しない。(例外は投げるかもしれない)
by [Effective Modern C++ メモ](https://qiita.com/ktsujino/items/39c8bc23dcdc1f7b17ab#14-%E4%BE%8B%E5%A4%96%E3%82%92%E5%90%90%E3%81%8B%E3%81%AA%E3%81%84%E9%96%A2%E6%95%B0%E3%81%AFnoexcept%E3%81%A8%E5%AE%A3%E8%A8%80%E3%81%9B%E3%82%88)

自然な実装で例外が発生しない場合は、noexceptによって呼び出し元に迷惑をかけない事を保証出来る。

>C++17 からは noexcept は関数の型の一部という扱いになる (noexcept が付いているのとついていないのとでは異なる型と認識される) ので、関数が例外を投げるか否かについて従来よりも厳密な運用が要求されることになります。
by コメント(SaitoAtsushiさん)より

C++17からは関数型の一部になるということなので、知らないとコンパイルエラーを量産することになりそうです。例外の有無についてはちゃんとメリハリつける必要がありますね。

### std::optional
C++17~でのnull安全モジュール


# その他
初心者が1時間で調べたことをまとめているだけなので、すっからかんだと思われます…

有識者の方、ご指摘頂ければ大変有り難く思います。
Excel で Power BI にレポートを発行する

Power BI レポートを作成発行するとき Power BI Desktopを使用することが多いけれども、Excel でレポートを作ってもよいのです。で、Excel ならではというところもあるのでいい感じに使ったらよいと思うのです。

**手順に違いはない**
Power BI Desktop であろうが Excel であろうが手順には変わりがなく、Power Query エディターでデータソースから必要なだけ抽出し加工、そして データモデルにロードすること。モデリングで集計できるように整えレポートにする。だた、ビジュアルが Excel のピボットテーブル/PivotTable, ピボットグラフ/PivotChart になるだけの話。

**シンプルに表示するだけでよいなら、ここまでしなくてもよい**
Excel の レポートでは Power BI Service に統合された Excel Online が使用されるので 表示だけで要件を満たすのであればそれでよし。ワークシート上の範囲とかチャートをダッシュボードに追加することができる。

# いざ
## 必要なもの
- Power BI Service
- Power BI Pro / (Free) いずれでも
- Excel 2016
- OneDrive for Business / SharePoint Online ドキュメントライブラリ

## 実現すること
**Power BI Service の機能 [スケジュールされた更新] でデータを更新する。**
**レポートのソースとした Excel ワークブックも更新する。**

## 手順
・**Power Query エディター** を使ってデータを取得とし必要な加工をする
・データは Excel データモデル にロードする
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193509/5c2519b5-0b98-792e-8b71-6c14d06fb862.png)
[このデータをデータ モデルに追加する]は必須。"ピボットテーブル" もしくは "ピボットグラフ"を選択してもよい。"テーブル"を使ってもよいけれどもワークシートの行数の制限を留意。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193509/a87838fb-e183-db8e-a95e-ae88b206bda5.png)

・データモデルをソースにするピボットテーブルやピボットグラフを作成
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193509/e7852da5-fce2-7e19-192e-685dcc197480.png)

・OneDrive for Business などにExcel ブックを保存し、Power BI に Publish
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193509/4694a332-66d2-e21c-a728-4dd395c6ebdc.png)

・統合された Excel Online でレポートは表示される
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193509/ee2ffc47-c422-c6b8-c182-01df367b6781.png)

・データソース接続に使う資格情報と更新スケジュール
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193509/97b0a92b-33e7-bf44-be97-b60a2b3a7537.png)

・Excel ブックが更新されている
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193509/cf239056-b0b3-df49-26fb-63a25f6d0a5d.png)

ソースにした該当の Excel ブックは共有などしてもよいが、ファイルが開かれた状態にあるとPower BI Service の更新に失敗するので、"読み取りのみ"で共有すればよい。

・Power BI Service で Excel ブックをアップロードしても同じ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193509/c5908f97-afc6-e338-afd2-fdd8479f0a3e.png)

# 情報
[Excel 2016 から Power BI へ発行する](https://docs.microsoft.com/ja-jp/power-bi/service-publish-from-excel)
[Power BI で表示する Excel ブックのサイズを減らす](https://docs.microsoft.com/ja-jp/power-bi/reduce-the-size-of-an-excel-workbook)
私的ふりかえりの教科書

## ふりかえりの構成

|構成要素|割合|
|:-:|:-:|
|場を設定する|5%|
|データを収集する|30-50%|
|アイデアを出す|20-30%|
|何をすべきか決定する|15-20%|
|ふりかえりを終了|10-15%|

## 進め方の注意点

- 進め方の概要を説明する
- チームの約束を決めておく
- 時間を管理する

## 各構成要素

### 場を設定する

- ふりかえりの目的と今回の目標を再確認
- チームの約束の確認
- 一言二言口を開いてもらう
- 導入しやすそうなアクティビティ
  - チェックイン

### データを収集する

- 事実と感情のデータを収集する
- データがないとチームは何を改善すれば良いか推測するしかない
- 導入しやすそうなアクティビティ
  - カラーコードドット
  - 喜怒哀
  - チームレーダー

### アイデアを出す

- データを評価してアイデアを出す
- 導入しやすそうなアクティビティ
  - 学習マトリクス

### 何をすべきか決定する

- フォーカスを次のイテレーションに向ける
- アクションを提案し、優先順位をつける
- 導入しやすそうなアクティビティ
  - SMARTな目標
  - 短い話題

### ふりかえりを終了

- ふりかえりのふりかえりを実施
- 導入しやすそうなアクティビティ
  - プラス/デルタ
  - 役立った、邪魔だった、仮定した

# 参考資料

- [アジャイルレトロスペクティブズ　強いチームを育てる「ふりかえり」の手引き](http://amzn.asia/1MN9U4W)
- [Ryuzee.com ふりかえり](http://www.ryuzee.com/tags/%E3%81%B5%E3%82%8A%E3%81%8B%E3%81%88%E3%82%8A/)
[tips]タイプ時に`p`が`*`になって困った時と解決

## 症状

キーボードで`p`をタイプすると画面に`*`が出ちゃって少しちびる

## 私の対処

NumLockを解除する

### 手順(Windows10)：
1. スクリーンキーボードを立ち上げる[^1]  
**ログイン済み**：左下Windowsロゴ -> `Windows 簡単操作` -> `スクリーンキーボード`  
**ログイン画面**：右下にある時計？みたいな謎のマーク(マウスあればマウスオーバーで`Windows 簡単操作`)と出ます -> `スクリーンキーボード` ※ログイン画面のひとつ前の謎の画面でなく、ログイン画面なので注意。謎画面はクリックとかするとログイン画面に遷移します。  
※スクリーンキーボードについて分からなければ以下も参照  
https://121ware.com/qasearch/1007/app/servlet/relatedqa?QID=018025
2. スクリーンキーボードの`オプション` -> `テンキーを有効にする` -> `NumLock`を解除

## 私はどうしてこうなった

前提：Chrome リモートデスクトップで遠隔作業する。リモート先はノートPC1、テンキー無し。リモート元はノートPC2、ただし外部キーボードでテンキーあり。

1．リモートでノートPC2から意気揚々とノマドぶって作業(このときNumLockを有効にしていた)
2. ノートPC1に戻って意気揚々とログインしようとする
3. ノートPC1上でpから始まる堅牢なパスワードを入力するもログインできず
4. パスワードを表示してみると`p`が`*`になっていて少しちびる
5. スマホから必死に検索し、解決策に気づく

## 似たような問題

入力おかしいのは以下も可能性あり。

- `CapsLock`
   - Shift + `CapsLock`
      -  [CAPSキーロック状態の解除方法を教えてください](https://answers.microsoft.com/ja-jp/ie/forum/ie10-windows_7/caps%E3%82%AD%E3%83%BC%E3%83%AD%E3%83%83%E3%82%AF/b06da60b-4f64-4de2-919a-da075264fbe7)
- 英語配列キーボードと日本語配列キーボードの併用時
   - `Windowsボタン` + `Space`

## 友達の友達みたいな問題

- Excelで上下左右キーを押すとセル移動じゃなくてスクロールしてまう
   - `ScrLk`キー押して解除(場合によりスクリーンキーボードで)

## ひとこと

初めての投稿がこんなしょぼいことですみません。

[^1]: この症状に困ってる人はおそらくスクリーンキーボードでないと解決できないため、スクリーンキーボードでの手順を記載
UNet(系)で、マルチクラスセグメンテーション(3)

# はじめに
この記事は、[前前記事](https://qiita.com/taashi/items/1214f7aaf704e5507482)、[前記事](https://qiita.com/taashi/items/bf0ddd7356d0ce234675)からの続きです。
詳しい話は、そちらを。

## 改良 (2)
前回は、未使用なGチャンネルに、無視できる小さな値を入れて学習させてみたがうまくいかず、
全体で値がフラットになっているのが問題なのかと思ったので、
今回は、教師データに強制的に値の差をつけてみたらどうかということで、
教師データ(画像)の4辺を最大値で埋めてみることにした。

## 学習 (2)
前回からの変更点は、
教師画像に対して、各4辺の1pixel幅を255(/255)で埋めて、学習する様にした点。

それ以外は、前々回と同じにして学習。

## 結果 (2)
loss曲線は、こんな感じ
UNet:
![LearningCurve_loss_3.png](https://qiita-image-store.s3.amazonaws.com/0/162097/9c1c2990-f7ed-0ba6-5e9f-4fe5cb192f4b.png)
DeepUNet:
![LearningCurve_loss_Deep_3.png](https://qiita-image-store.s3.amazonaws.com/0/162097/c9246d7c-d20a-6c7f-40fd-47c8b5fc94da.png)

そして、出力結果はこんな感じ (一部抜粋)
![Cond_3_Train.png](https://qiita-image-store.s3.amazonaws.com/0/162097/6d462206-3b5e-e042-a0da-0ca34cabbe5f.png)
![Cond_3_Test.png](https://qiita-image-store.s3.amazonaws.com/0/162097/6b9ce542-0d4b-f3b8-2a08-fa06b03b720e.png)

目標通りに近い感じの出力になった。
この方法で、うまくいきそう。
ただし、今回の方法では、教師データの周囲4辺1pixelの情報が落ちるので望ましくない。

## 改良 (3)
ということで、上記の
>教師データの周囲4辺1pixelの情報が落ちるので望ましくない。

ここを改善すべく、入力データと教師データを
周囲4辺を1pixel分拡大して、そこを上記のようにMax値で埋めて学習してみることに。


## 学習 (3)
前回からの変更点は、
教師画像に対して、周囲4辺を1pixel拡大((256, 256, 3) -> (257, 257, 3))し、
拡大した点を255(/255)で埋めて、学習する様にした点。

それ以外は、最初と同じにして学習。


## 結果 (3)
loss曲線は、こんな感じ
UNet:
![LearningCurve_loss_4.png](https://qiita-image-store.s3.amazonaws.com/0/162097/b3917d25-2442-50f9-e5c0-0576a6c17687.png)
DeepUNet:
![LearningCurve_loss_Deep_4.png](https://qiita-image-store.s3.amazonaws.com/0/162097/27a30fe5-36ae-95ee-4e0c-67cf324f109e.png)

そして、出力結果はこんな感じ　(一部抜粋)
![Cond_4_Train.png](https://qiita-image-store.s3.amazonaws.com/0/162097/e1512651-82c8-e1e3-bcdb-aefd1505ffa2.png)
![Cond_4_Test.png](https://qiita-image-store.s3.amazonaws.com/0/162097/607be19b-b697-7ead-29b7-a8a6f4deecb4.png)

ということで、期待通りの出力になった。
出力データが、周囲1ピクセル分大きくなっているので、その分をカットして出力すればいい感じなるはず。

## さいごに
今回は、ちょっと違った感じでマルチセグメンテーションをしてみた。
最終的には、入力データを拡大し、少し手を入れることで、うまくいった。
このように、入力と教師に何か処理を加えることでうまくいくようになることもあることを覚えておきたい。
ただし、データをいじることで、元データを破壊してはいけないので、
その辺は、気を付けていきたい。

最終的な結果のTest dataに関しては、ある程度学習したデータに似たように推論されているが、まだまだ結果がよくない。
これは、今回認識しようとしたものが、比較的緩い条件(広義的な物体。ある程度形が決まっているが、色や細かい形に自由度が高い)のものであるのに対して、学習に使用したデータの数が少なかったことに起因していると思う。
学習データを十分に増やすor対象物をもう少し厳しい条件にすれば、十分良い結果になっていくだろう。

また、UNetとDeepUNetを使ってみたが、
今回の条件では、UNetの方が良い結果に見える。
学習データが少なかったりと条件が悪いので、もう少ししっかりとした条件で比べたら、DeepUNetの方がよくなるのだろうか...


## おまけ
今回使用したUNet, DeepUNetは、自分でKerasで実装してみたものを使用した。
リポジトリは、こちら([UNet](https://github.com/taashi-s/UNet_Keras/tree/StationarySegmentation_cond1), [DeepUNet](https://github.com/taashi-s/DeepUNet_Keras/tree/StationarySegmentation_Cond1))。

それぞれのブランチは、
(1)の記事：StationaryDetection_cond1
(2)の記事の改良(1)：StationaryDetection_cond2
この記事の改良(2):StationaryDetection_cond3
この記事の改良(3):StationaryDetection_cond4

※参考にされる方へ：masterブランチは、調整中なので、動かない可能性があります。無視してください。
UNet(系)で、マルチクラスセグメンテーション(2)

# はじめに
この記事は、[前記事](https://qiita.com/taashi/items/1214f7aaf704e5507482)からの続きです。
詳しい話は、そちらを。


## 改良 (1)
ということで、惜しい感じにはなったが、
今回の条件では、2クラスしか対象にしておらず、そこに対して、RGBの3channelを出力しようとしており、どのクラスにも対応していない(=対象物がない)G channelが、うまく学習できなかったんじゃないだろうか

2クラスでも、この2クラスでRGBの全channelを使う様な設定
(例えば、1クラス目を(255, 255, 0)、2クラス目を(0, 255, 255)にするなど)
すれば、うまく行くのかもしれないが、なんかそれは、嫌だった(ほんとになんとなく、負けた気がして。)
RGBの3色出力にするとして、クラス数が3以上でも、使わない色素があるかもしれないじゃないか！
という思いもあった。(たぶん)

ということで、
なんとかならないものかと思い
まず考えたのが、そもそも全体が0だと、領域計算ができないので、lossが(ちゃんと)計算できないじゃん
ということで、無視できる値を決めて、教師データの全体が0のchannelに対して、その無視できる値で埋めてしまって学習してみたらどうだろうか。
出力時に、その無視できる値以下の点を0に抑えてしまえばいけそうな気がする。

## 学習 (1)
前回からの変更点は、
教師画像に対して、NNへの入力前に、全体が0のchannelに、無視できる値(10（/255）)を入れて学習する様にした点。
それ以外は、同じにして学習。

## 結果 (1)
loss曲線は、こんな感じ
UNet:
![LearningCurve_loss_2.png](https://qiita-image-store.s3.amazonaws.com/0/162097/5bbf7adc-65aa-b5d9-def5-57e2bf8bd32c.png)

DeepUNet:
(またもや紛失...すみません)

そして、出力結果はこんな感じ
(一部抜粋。各チャンネル10以下の出力は、0に変換。)
![Cond_2_Train.png](https://qiita-image-store.s3.amazonaws.com/0/162097/97b19d60-8947-8833-24e2-081582fcd9ae.png)
![Cond_2_Test.png](https://qiita-image-store.s3.amazonaws.com/0/162097/87201648-9958-0194-cb97-4ed06f450686.png)


元画像の形が、Gチャンネルに残ることはなくなったが、
無視できる量に学習できていない。

結局、対象物がいないchannelは、全体が(前回は、0, 今回は、10(/255)で)フラット(全体に対して値の差がない)なので、
それがいけないのかもしれない。
(後から思えば、もしかしたら、教師画像のGチャンネルに無視できる値を入れたつもりで失敗して大きな値を入れてしまっていたのかもしれないが...)

考えてみれば、dice lossを使用しているが、（この計算方法がいけないかもしれないが）
領域そのものが重なっていなくても、領域範囲が一致していて、トータル値が一致してしまえば、lossが一致しそう。

実際、以下の様に確認すると

```dice_coef_loss_chk.py
def dice_coef(y_true, y_pred):
    y_true = KB.flatten(y_true)
    y_pred = KB.flatten(y_pred)
    intersection = KB.sum(y_true * y_pred)
    denominator = KB.sum(y_true) + KB.sum(y_pred)
    if denominator == 0:
        return 1
    if intersection == 0:
        return 1 / (denominator + 1)
    return (2.0 * intersection) / denominator


def pt(t):
    val = KB.get_value(t)
    print(val)

gt = KB.cast(tf.constant([1,1,1,1,0,0,0,0]), 'float32')
a = KB.cast(tf.constant([1,1,1,1,0,0,0,0]), 'float32')
b = KB.cast(tf.constant([0,0,2,2,0,0,0,0]), 'float32')
c = KB.cast(tf.constant([1,2,0,1,0,0,0,0]), 'float32')


a_loss = 1 - dice_coef(gt, a)
b_loss = 1 - dice_coef(gt, b)
c_loss = 1 - dice_coef(gt, c)

pt(a_loss)
pt(b_loss)
pt(c_loss)
```

出力↓

```
a_loss :  0.0
b_loss :  0.0
c_loss :  0.0
```

ってな感じで一致してしまう。

([つぎ記事へつづく。。。](https://qiita.com/taashi/items/1070134db4cd628a06a5))
UNet(系)で、マルチクラスセグメンテーション(1)

# マルチクラスのセグメンテーション
複数クラスのセグメンテーションを行おうと思って調べてみたが、
多くのモデルが、pixel単位に対して、各クラスの確率を出力し、
そこから、ピクセル毎に、「この位置は、〇〇だ」という形式をとる実装だった。

が、よく考えてみると、
自分たちって画像や風景をみた際に、「おっこの位置は、〇〇。あの位置は、△△」なんて言わなくね？
どっちかって言うと、
「あの辺に〇〇があって、あの後ろには、△△」みたいな、ある種レイヤー的な捉え方しない？
と思い、
`pixel単位に対して、各クラスの確率を出力`
ではなく、
`クラス毎のセグメンテーションマップを出力`
って形でできないかとやってみた。

>`クラス毎のセグメンテーションマップを出力`

これの場合、うまくいって、学習データをちゃんと用意できれば、重なり合った領域に対しても、(おそらくこうあるはずという形式になるかもしてないが、)セグメンテーションができるんじゃないだろうかという期待もあった。

## UNet系のモデルで、実験
ちょうど実装してみていたUnet, DeepUNetで実験することに。
変更点としては、
マルチクラスセグメンテーション時、最終レイヤーで、channel軸に対してsoftmaxするところを、全体に対してsigmoidをかける様に変更。
また、loss計算は、各チャンネル毎に、dice coefficentを使ったlossを出し、sumする様に変更した。

## 学習
カラー画像を入力として、同一サイズのクラス数分のchannelを持つベクトルを出力にしようかと思ったが、
今回は、対象物(クラス)を2種に絞ったので、各クラスをそれぞれchannel対応させて、出力もそのままRGBをもつカラー画像(にそのまま変換できるベクトル)にした。
ノート : 青
ペン : 赤

学習データは、
　オリジナル　: 50枚
を用意し、
data augmentationで、
　フリップ(水平 = 1 + 1) * 回転(60度ずつ = 1 + 5) * スケーリング(1.5 = 1 + 1) = 24 倍
に、水増しして
　合計 50[枚] * 24[倍] = 1200[枚]
を使用した。(20%(=240枚)をvalidationに回した。)


Epoch数：1000、
Batch：80(UNet), 60(DeepUNet)
で、学習した。


## 結果
loss曲線は、こんな感じ
UNet：
![LearningCurve_loss_1.png](https://qiita-image-store.s3.amazonaws.com/0/162097/b43a5834-2827-42fb-4234-b482a7bf5ad5.png)
DeepUNet：
(紛失してしまった....)


そして出力結果は、こんな感じ (一部抜粋)
![Cond_1_Train.png](https://qiita-image-store.s3.amazonaws.com/0/162097/9d6c24dc-e410-976e-2a39-aa3caf4f045b.png)
![Cond_1_Test.png](https://qiita-image-store.s3.amazonaws.com/0/162097/d633ce0e-64bb-6d17-122c-7b9c8614ecfe.png)

うまくいかない。
今回の場合、未使用channel（緑）があり、このchannelのみ、教師データに1枚もないので、学習できない？
それで、緑の画素が、全体に混ざって入り、こんな感じになった？
理想は、この緑が、なくなること。

([つぎ記事へつづく。。。](https://qiita.com/taashi/items/bf0ddd7356d0ce234675))
Junosでコマンド履歴を触りたい

 
# 概要
* 検証環境： ```Junos: 17.4R1-S4.2```
    * クライアント： Ubuntu 18.04

* junosのルーター機器(MX,SRX)は:arrow_up:キーでコマンド履歴を遡れない。(EXなら出来たりする)
* とっても困る。


# じゃあどうするか
- **Emacs**風キーボードショートカットが使えた！！

```
# ↑キーと同じ。コマンド履歴を一個ずつ遡る
Ctrl + p
```

```
# ↓キーと同じ。コマンド履歴を一個ずつ進む
Ctrl + n
```


# ちなみに
```history``` 的なコマンドもある。

```
user@router>show cli history
  10:20:36 -- show configuration
  10:20:48 -- ping 8.8.8.8
  10:20:56 -- show configuration
  10:26:41 -- show version
  10:47:42 -- show cli history
```








# Reference
[どのようなショートカットキーが利用可能ですか?](http://support.jscom.jp/support/maker/juniper/srx/knowledge/management/s063/)
bekeh+pythonでリアルタイムプロット

## 数値計算をブラウザでリアルタイムプロットしたい
bokehを利用していい感じのリアルタイムプロットが出来るようになったのでメモ
jsを用いてやろうとしていましたが、あまりうまくいかなかったので少し回り道してみました
![bokeh_plot.png](https://qiita-image-store.s3.amazonaws.com/0/214036/53a50489-1b7c-67c4-d66d-9cb6ffc9aa92.png)

## コード全文
こちらを実行すれば動きます


```python:myplot.py
# myplot.py
from bokeh.plotting import figure, curdoc
from bokeh.driving import linear
import numpy as np
import random

p = figure(plot_width=400, plot_height=400)
######重要###########
p.x_range.follow="end"
p.x_range.follow_interval = 20
p.x_range.range_padding=0
#####################
r1 = p.line([], [], color="firebrick", line_width=2)
r2 = p.line([], [], color="navy", line_width=2)

ds1 = r1.data_source
ds2 = r2.data_source

@linear()
def update(step):
    ds1.data['x'].append(step)
    ds1.data['y'].append(np.sin(step/10))
    ds2.data['x'].append(step)
    ds2.data['y'].append(np.cos(step/10))
    ds1.trigger('data', ds1.data, ds1.data)
    ds2.trigger('data', ds2.data, ds2.data)

curdoc().add_root(p)

# Add a periodic callback to be run every 500 milliseconds
curdoc().add_periodic_callback(update, 100)

```

##解説
###必要なライブラリを用意

```python
from bokeh.plotting import figure, curdoc
from bokeh.driving import linear
import numpy as np
import random
```

###figureを定義(400×400)
```python
p = figure(plot_width=400, plot_height=400)
```

###x軸の設定（重要）

```python
p.x_range.follow="end"
p.x_range.follow_interval = 20
p.x_range.range_padding=0
```
follow...x軸をある値で追従する。今回はendなので、最大値を追従。
interval...ストリーミング間隔
padding...ストリーミング速度を加える？今回は0なので特に意味なし。

documents
https://bokeh.pydata.org/en/latest/docs/reference/models/ranges.html

###データフレームの生成
```python
r1 = p.line([], [], color="firebrick", line_width=2)
r2 = p.line([], [], color="navy", line_width=2)

ds1 = r1.data_source
ds2 = r2.data_source
```
**p.line()**...figureの".line(x,y,...)"メソッドを利用することで線を描写(pはfigureのインスタンス)
**r1.data_source**...生成したデータセットをここにぶち込めばいいみたい

###デコレータ
```python
@linear()
```
**@linear**...decoratorというらしい。連続データを生成している？以下のドキュメントを参照してください。おそらくですが、bokeh内ですでにlinearという関数が定義されていて、@linearで呼び出して続く関数を修飾しているのだと思われます。

おすすめ：Pythonのデコレータについて(Qiita)
https://qiita.com/mtb_beta/items/d257519b018b8cd0cc2e
デコレータのdocument(Bokeh)
http://bokeh.pydata.org/en/0.11.1/docs/reference/driving.html

###データの生成＆更新
```python
def update(step):
    ds1.data['x'].append(step)
    ds1.data['y'].append(np.sin(step/10))
    ds2.data['x'].append(step)
    ds2.data['y'].append(np.cos(step/10))
    ds1.trigger('data', ds1.data, ds1.data)
    ds2.trigger('data', ds2.data, ds2.data)
```
updateという関数を定義します。引数はstepで。triggerはよくわかりません。
trigger("名前", x, y)のような感じ？

###ブラウザに反映
```python
curdoc().add_root(p)

# Add a periodic callback to be run every 500 milliseconds
curdoc().add_periodic_callback(update, 100)
```
現在のPを返す
**curdoc().add_root(p)**...現在のfigureを表示
**curdoc().add_periodic_callback(update, 100)**...updateを実行して、100msでコールバック
curdoc()のdocument
https://bokeh.pydata.org/en/latest/docs/reference/io.html

###感想
やはりpythonで完結しているものは理解しやすいです。jsの勉強もコツコツ頑張ります。
On Error GO TOをした後にプログラムを閉じる処理をしたいとき

手前味噌ですが…。

まず
#ON Error Go To とは…
 * エラー処理ルーチンの開始を示すもの
 * これを記載された処理はエラーが起こると定義したところまでGOTOしますって感じだと思っています。

記載例>

```vb
Sub Main OyaHoge()

On Error GoTo OyaHoge_Eroor
    Call KoHoge1()
    Call KoHoge2()

Debug.Print("処理完了したヨ")    
Exit Sub

OyaHoge_Eroor:
 Debug.Print("エラーダヨ")

End Sub
```
上記のように書けば良いと思っているがどうでしょうか？
このままでは`OyaHoge()`と`KoHoge1()`、`KoHoge2()`の処理の中でエラーが起きると`Debug.Print`で`("エラーダヨ"）`と記載してMainの処理を完了する。

このままでは、正常処理に記載されている、`("処理完了したヨ")`が表示しない(処理完了のフラグとかを立てなければいけないときとかも該当する)

#エラーのときエラー処理と完了処理を行いたいとき
はどうすれば良いか。

・・・単純にエラー処理の後に完了処理を呼んでしまえば良い!!
つまり以下のようになると思う。

記載例>

```vb
Sub Main OyaHoge()
Dim ErrorFlg As Boolean
'ErrorFlag初期化
ErrorFlg = False
On Error GoTo OyaHoge_Eroor
    Call KoHoge1()
    Call KoHoge2()

Hoge_End:
If ErrorFlg = True Then
    Debug.Print("エラーあり")
End If

Debug.Print("処理完了したヨ")    
Exit Sub

Hoge_Eroor:
 Debug.Print("エラーダヨ")
 ErrorFlg = True
 GoTo Hoge_End

End Sub
```

上記のように再度呼びたい処理をエラー処理の後に呼んでやれば良いと思っている。
正常のときはそのまま完了処理を通して、エラーのときはエラー処理を解してから完了処理(ErrorFlagがTrueなので("エラーあり")のコメント出す)を通す感じです。
~~なんかエラーのお知らせ重なって気持ち悪い…~~

動き例>
**正常のとき**
→OyaHoge()→KoHoge1()→KoHoge2()→"処理完了したヨ"

**KoHoge2()でエラーが出たとき**
→OyaHoge()→KoHoge1()→KoHoge2()→Hoge_Eroor:→"エラーダヨ"→エラーあり→"処理完了したヨ"

#最後に
以下の文言でググッた方が有意義と思います。
 
* On Error Go To
* エラー処理

以上。
Angular5でDatePipeを使う。LOCALEセットしてね。


## バージョン

- ionic 4.1.1
- Angular 5.2.11

## LOCALE設定

[Angular 5 Breaking change \- manually import locale \- Stack Overflow](https://stackoverflow.com/questions/46564972/angular-5-breaking-change-manually-import-locale)

- app.module.ts

providerにセットして、かつ、registerLocaleDataをしてやる必要がある

```javascript

import { SplashScreen } from '@ionic-native/splash-screen';
import { StatusBar } from '@ionic-native/status-bar';

import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import localeJa from '@angular/common/locales/ja';
import { registerLocaleData } from '@angular/common';

registerLocaleData(localeJa);

@NgModule({
    declarations: [
        MyApp,
        HomePage
    ],
    imports: [
        BrowserModule,
        IonicModule.forRoot(MyApp)
    ],
    bootstrap: [IonicApp],
    entryComponents: [
        MyApp,
        HomePage
    ],
    providers: [
        { provide: LOCALE_ID, useValue: 'ja-JP' },
        StatusBar,
        SplashScreen,
        { provide: ErrorHandler, useClass: IonicErrorHandler }
    ]
})
export class AppModule { }
```

## DatePipe

[Angular \- DatePipe](https://angular.io/api/common/DatePipe)

- html

```
<span class="msg-date">{{chat.send_at | date:'yyyy/MM/dd HH:mm'}}</span>
```

- 表示

```
2018/09/03 09:20
```
Ruby 2.5.1 をインストールしたのに Your Ruby version is 2.4.2 と言われた際の対処

## 環境
- Windows7 Professional SP1 のパソコン
- Ruby 2.4.2 をインストール済み
- ローカルで Rails アプリケーションを動作

ちなみに Ruby 2.4.2 はインストーラで入れました。
https://rubyinstaller.org/downloads/

## 事象
前述の環境で Ruby の 2.5.1 をインストールしてから bundle install を実行した際にこんなエラーが出ました。インストールは 2.4.2 のときと同様にインストーラで行いました。

```bash
$ bundle install
Your Ruby version is 2.4.2, but your Gemfile specified 2.5.1
```

ちなみに ruby -v ではちゃんと 2.5.1 が出る状態にも関わらずです。

```bash
$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x64-mingw32]
```

bundle も2.5のbinから実行されています。

```bash
$ which bundle
/c/Ruby25-x64/bin/bundle
```

bundle のバージョンは 1.16.4 です。

```bash
$ bundle -v
Bundler version 1.16.4
```

## 対処
ruby 2.5 のインストーラ実行時、パスも通してくれるのですがユーザー環境変数のPATHが以下のようになっていました。
2.4 の環境変数も残っています。

```:ユーザー環境変数のPATH(before)
C:\Ruby25-x64\bin;%JAVA_HOME%\bin;C:\Ruby24-x64\bin;...(省略)
```

この場合、左から処理され `C:\Ruby25-x64\bin;` が採用されるはず(`ruby -v` 実行時は実際2.5.1が表示)なんですが、rubyのパスが2つあるのが気持ちわるかったので念のため2.4は削除して下記のようにしました。

```:ユーザー環境変数のPATH(after)
%JAVA_HOME%\bin;C:\Ruby25-x64\bin;...(省略)
```

プロンプトを立ち上げなおして再度 bundle install を実行したら今度はうまくいきました。

```bash
$ bundle install
Fetching gem metadata from https://rubygems.org/..........
Fetching gem metadata from https://rubygems.org/..

(省略)

Bundle complete! 19 Gemfile dependencies, 80 gems now installed.
```

## 備考
- 別の端末で同じことをしてみたらそっちでは再現しなかったので、環境依存もありそうです。
- 調査のために環境変数の設定を戻しても再現できなくなっていました。
- そのため、根本的には別の原因があり、環境変数の設定を変えたことでたまたまそれが解消されてしまった可能性もありそうです。

## まとめ
正直、何故これで解決できたのかまだ原因がはっきりと理屈で説明はできないのですが、あまり Windows での事例も見当たらなかったのでもし誰かがここを見かけた際に参考にしてもらえればと思って記事に残しました。
今後、もし何か新しいことがわかりましたらこの記事に追記、もしくは新しい記事に書いてこの記事へのリンクを貼るようにします。

## ちなみに
エラーメッセージで検索した際にヒットしたのは rbenv の事例が多かったです。そもそも Windows で Rails の開発をしている人があまり多くないんでしょうね。**Mac欲しい。**
Azure 開発・運用担当者のための ID 管理と権限制御

<p>この投稿は東京渋谷ヒカリエ 8 階にある <a href="http://aka.ms/aajp" target="_blank">Azure Antenna</a> で実施された「Azure 開発・運用担当者のための ID 管理と権限制御」で使われた資料のご案内です。</p>

- <strong>Azure 開発・運用担当者のための ID 管理と権限制御</strong><br />
https://www.slideshare.net/AyumuInaba/azure-id-and-rbac-v05180824

<p>:satellite:&nbsp;&nbsp;新しいイベントの情報は、Connpass の <a href="http://aka.ms/aajp" target="_blank">Azure Antenna サイト</a>よりご確認いただけます。</p>

<p>:arrow_backward:&nbsp;<a href="https://qiita.com/AzureAntenna/items/71f394c100fbfa8ddcc8">「Azure Antenna 実施イベント資料（カテゴリ別）」に戻る</a></p>
ログローテーションの設定方法（Apache、Laravel）

# きっかけ
これまでWEBアプリの開発を結構やってきたけど、本番でのログローテーションの設定は自分でやったことなかったのでメモ。

# Apache
## 大まかな設定は以下のURLの通り
https://qiita.com/na0AaooQ/items/ff2dad51b2b70d69ce87

## だいたいのコマンドの一覧（全てではない）
http://www.atmarkit.co.jp/flinux/rensai/linuxtips/747logrotatecmd.html

なぜかdateextがない。
dateext：ローテーションするファイル名フォーマットに日付を使う。

## 私の思うポイント
* logrotateというコマンドはCentOS6系にはデフォルトで入っている様子。
* このコマンドはcronのデイリーで設定されていた。
* `/etc/logrotate.d/httpd` もデフォルトにはあった。
    * 今回は私はこの設定が気にくわないので変えた。
* `logrotate -d` の `-d` での実験は絶対やるべき。（ログファイル消す設定もあるので）

# Laravel
## 大まかな設定は以下のURLの通り
https://readouble.com/laravel/5.3/ja/errors.html
v5.3だけど、どのバージョンもだいたい同じではないかな？

## 私の思うポイント
* Laravelの場合、自分でログローテーションを設定できる。
* その時 `config/app.php` を設定するように～とあるが、それをそのままやるとよくない。
* 既存のv5.4では `.env` を参照するような指定が記載されていて、それをまねする方がスマートだと思う。（.envファイルなら本番と開発で変えやすい）
this参照

##this参照とは
* JSのどこでも使える読み込み専用の変数
* this参照はオブジェクトを参照する

###this参照の規則4種
| thisが使用される場所   | 参照されるオブジェクト     |
| ---------------------- | -------------------------- |
| トップレベルコード     | グローバルオブジェクト     |
| コンストラクタ呼び出し | インスタンスオブジェクト   |
| メソッド呼び出し       | レシーバオブジェクト       |
| apply,call呼び出し     | 引数で指定したオブジェクト |

一番わかりやすいのはこちらの記事
[JavaScriptの「this」は「4種類」？？](https://qiita.com/takeharu/items/9935ce476a17d6258e27)


##メソッド呼び出し
```js:js
const obj = {
  value: 10,
  show: function() {
    console.log(this.value);
  }
}
obj.show(); // 10
//thisはobjのことを指す。
```
##トップレベルコード

トップレベルコードのthis参照はグローバルオブジェクト
関数内で呼ばれていも、thisはグローバル変数を参照する

```js:js
const str = "global";
console.log(this.str);
//global

function fn() {
    const str = "local";
    console.log(this.str); 
    console.log(str); 
}
fn();
//global
//local 
```

##コンストラクタ呼び出し

生成されたインスタンス自身がthisにsetされる

```js:js
function MyClass(x, y) {
  this.x = x;
  this.y = y;
}

const obj = new MyClass(5, 10);
const obj2 = new MyClass(1, 2);

console.log(obj.x)//5
console.log(obj2.x)//1
```

##apply call

引数に指定したオブジェクトをthis参照にできる。
好きにthisを設定できる。

```js:js
function MyClass(x, y) {
  this.x = x;
  this.y = y;
}

MyClass.prototype.show = function() {
  console.log(this.x, this.y);
}

const obj = new MyClass(5, 10);
const obj2 = new MyClass(1, 2);

obj.show.call(obj2);
//1 2
```

###applyとcallの違い

* applyは第二引数に配列を取る
* callは第二引数以降がそのまま渡される。

```js:js
var myObject = {
  add: function(value1, value2) {
    console.log(this.value + value1 + value2);
  }
};
var yourObject = {
  value: 3
};

myObject.add.apply(yourObject, [2, 10]); // 15
myObject.add.call(yourObject, 2, 10); // 15
```
gitのコード早見表

#git基本使用コマンド
※見にくいので下に別形式あり

|コマンド|変更可能オプション|説明|
|:--|:--|:--|
|**基本**|||
|init　　　||リポジトリを初期化(新規作成)|
|add|ファイル名 、 * 、 -A　|ワークツリーからインデックスへ追加。ファイル名を指定すると、指定ファイルのみを追加可能|
|commit -m|"コメント"|インデックスからローカルリポジトリへ追加|
|push|-u,origin|ローカルリポジトリをリモートリポジトリに追加|
|**確認**|||
|status||インデックスの中を確認|
|diff||ワークツリーとインデックスの差分を確認|
|log||過去のコミット履歴を表示|
|**取り消し**|||
|reset|詳細欄参照|コミットの取り消し、ワーキングツリーの内容を指定のコミットまで戻す|
|**ブランチ**|||
|branch|(ブランチ名)|新規ブランチ作成。現在のブランチ確認|
|checkout|-b,(ブランチ名)|ブランチを切り替える|
|**その他**|||
|clone|(url)|リモートリポジトリの複製を取得|
|fetch|origin|ローカルにあるリモートリポジトリのコピーに最新情報をダウンロードする|
|merge|(ブランチ名)|現在のブランチに指定したブランチを合わせる|
|pull|(url)|fetch, mergeの動作を行う|

## 見にくいので書き換え（追記）
###基本コマンド
`init` ー　リポジトリを初期化(新規作成)
`add`　ー　ワークツリーからインデックスへ追加。ファイル名を指定すると、指定ファイルのみを追加可能
`commit -m` ー　インデックスからローカルリポジトリへ追加
`push` ー　ローカルリポジトリをリモートリポジトリに追加

### リポジトリ内容の確認
`status` ー　インデックスの中を確認
`diff`　ー　ワークツリーとインデックスとの差分を確認
`log` ー　過去のコミット履歴を表示

### 取り消し
`reset` ー　コミットの取り消し、ワーキングツリーの内容を指定のコミットまで戻す

### ブランチ関係
`branch`　ー　作成ずみのブランチのリストを表示
`branch (ブランチ名)` - 新規ブランチ作成。現在のブランチ確認
`checkout` ー　ブランチを切り替える
`checkout -b (ブランチ名)` ー　ブランチを新規作成して、そのブランチに切り替える

### その他
`clone (url)` ー　リモートリポジトリの複製を取得
`fetch`ー　ローカルにあるリモートリポジトリのコピーに最新情報をダウンロードする
`merge`　ー　現在のブランチに指定したブランチを合わせる
`pull` - fetch, mergeの動作を行う
`rebase` ー　[参考サイト](https://qiita.com/KTakata/items/d33185fc0457c08654a5)
今更FizzBuzz問題？ファンファンのファン問題やろうぜ

## はじめに

この記事は新人プログラマ向けに問題と回答例を紹介するものです。
これを読んで少しでもプログラムに造詣が深まれば幸いです。
ベテランの方からの別解もお待ちしています。
今回は個人的好みで`ruby`で書いています。
言語は特に問いません。

## FizzBuzz問題とは

[wikipedia](https://ja.wikipedia.org/wiki/Fizz_Buzz)から引用して説明すると

> 3で割り切れる場合は「Fizz」、5で割り切れる場合は「Buzz」、両者で割り切れる場合（すなわち15で割り切れる場合）は「Fizz Buzz」

を表示するようなプログラムを組むことです

例えば以下のような感じですね（今回はこっちは焦点じゃないのでツッコミはなしの方向で）

```rb:fizzbuzz.rb
def fizzbuzz(num = 0)
  num.times do |i|
    i+=1
    if i % 15 == 0
      puts "fizzbuzz"
    elsif i % 5 == 0
      puts "buzz"
    elsif i % 3 == 0
      puts "fizz"
    else
      puts i
    end
  end
end

num = ARGV[0].to_i
fizzbuzz(num)
```

```bash:結果
$ ruby fizzbuzz.rb 20
1
2
fizz
4
buzz
fizz
7
8
fizz
buzz
11
fizz
13
14
fizzbuzz
16
17
fizz
19
buzz
```

プログラマ界隈では常識的な問題として誰もが1度は解いたことのある問題のはずです（多分）
僕も新人教育などで度々例題として挙げますが、いい加減古臭いし新鮮な問題を出したい…

## ファンファンのファン問題とは

そこで「ファンファンのファン問題」です
これは皆さんご存知の某アイドルユニットの曲からヒントを得て考えてみました

> 「ファンファンファン ファンファンのファン」の形をできるだけスマートに表示せよ

規則性としては

* はじめに「ファン」を3回表示
* 次に半角スペースを表示
* 更に「ファン」を2回表示
* 「の」を1回表示
* 「ファン」を1回表示
* 改行する

という順序です

## 例1

何のひねりもなく書いたらこんな感じ

```rb:fanfannofan1.rb
(1..10).each do |i|
  puts 'ファンファンファン ファンファンのファン'
end
```

```bash:結果
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
```

ベタ書きで全くスマートじゃない
「ファン」という同じワードを何回も書いているのでDRYじゃない

## 例2

```rb:fanfannofan2.rb
(1..5).each do |i|
  print 'ファン'

  if i%3 == 0
    print ' '
  end

  if i%5 == 0
    puts 'のファン'
  end

end
```

```bash:結果
ファンファンファン ファンファンのファン
```

「のファン」の部分がスマートじゃない
またこれは1回目しかうまくいかずこれ以降ループまわしていくとズレてしまう

```bash:結果
ファンファンファン ファンファンのファン
ファン ファンファンファン ファンのファン
ファンファン ファンファンファン のファン
ファンファンファン ファンファンのファン
```

## 例3

```rb:fanfannofan3.rb
(1..10).each do |i|
  (1..6).each do |j|
    print 'ファン'

    if j%3 == 0
      print ' '
    end

    if j%5 == 0
      print 'の'
    end
  end

  puts
end
```

```bash:結果
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
```

無事に規則に沿った形を表示できています
が、2重ループで表現している部分がスマートではないですね

## 例4

```rb:fanfannofan4.rb
# 「の」が入るタイミングを事前に配列に確保
threshold_array = Array.new
(1..20).each do |n|
  # 「の」が挟まるタイミングは等差数列の式により
  # an = a + (n-1)d
  # an = 5 + (n-1)6
  # an = 6n-1
  threshold_array.push((6 * n) - 1)
end

(1..60).each do |i|
  print 'ファン'

  # 3の倍数の時に半角スペース or 改行が挟まる
  if i%3 == 0
    if i%2 == 0
      puts
    else
      print ' '
    end
  end

  if threshold_array.include?(i)
    print 'の'
  end
end
```

```bash:結果
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
ファンファンファン ファンファンのファン
```

事前に判定配列を作っておくことで2重ループがなくなりました:smile:

## おわりに

自分で問題を考えておいて、全然スマートな解答が思いつかず四苦八苦しました:sweat:
結構色んな解法がありそうだなーと思うので是非みなさんポジティブなパッションで挑戦してみてください！
Qiitaの通知一覧から、いいねしてくれたユーザーのページに直リンするUserscriptを作った 非jQuery版

[Qiitaの通知一覧から、いいねしてくれたユーザーのページに直リンするUserscriptを作った - Qiita]

~~:oncoming_police_car:Qiita警察だ！！:oncoming_police_car:~~

とっても便利な機能！なのですが、一身上の都合によりネイティブで使いたいため書き換えさせてもらいます。

[Qiitaの通知一覧から、いいねしてくれたユーザーのページに直リンするUserscriptを作った - Qiita]:https://qiita.com/Sinhalite/items/892d4c972aeed6d1dcaf

# 動作検証環境

* Firefox 61.0
* Tampermonkey 4.7.5788

# コード

```qiita-user-link.user.js
// ==UserScript==
// @name         Qiita user link
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Qiitaの通知欄から直接ユーザページに遷移できるようにする。
// @author       khsk
// @match        https://qiita.com/notifications*
// @grant        none
// ==/UserScript==

// https://qiita.com/Sinhalite/items/892d4c972aeed6d1dcaf

(function() {
    'use strict';

    // queryをspan.bold:first-child指定にしてtextContentがツイートを弾くでもよさそう
    document.querySelectorAll('.notification_actionWrapper > span:first-child').forEach((node) => {
        // nextSiblingではテキストノードの「が」が引っかかるのでElementを
        if (node.nextElementSibling.textContent == 'ツイート') {
            return;
        }
        const link = document.createElement('a');
        link.href = node.textContent;
        link.target = '_parent';
        link.appendChild(node.cloneNode(true));
        node.parentNode.replaceChild(link, node);
    });
})();
```

`next(Element)Sibling`なんておそらく初めて使いました。
勉強になりますねー

***

見やすく短いのはjQueryでしょうかー
便利ですねー

***

こういう場合にauthor書き換えるべきか少し悩みます。
テストケースの作成

## よくある失敗

### 1. 不必要なテストパターンが多すぎる

「全ての組み合わせを網羅しなくては」と考えてしまうあまり、意味のないテストケースをたくさん作り込んでしまうタイプです。先ほどの例で示したように、組み合わせが多くなるとあっという間に天文学的なパターン数になってしまいます。

### 2. 異常系テストが足りていない

　「数値の項目にカタカナを入力したら」、「データベースに接続出来なくなったら」のような、異常なパターンのテストがそもそも足りていないタイプです。実際のシステム運用では、想定していない事態は頻繁に起こります。異常系テストが足りていないと、そのような時にすぐ壊れる脆弱なアプリケーションになってしまいます。

## テストケース4つの考え方

### 1. 正常系と異常系
　正常系とは、「その対象が想定している入力に対して期待どおりの出力を行なうかどうか」という考え方です。
　対して異常系は、「その対象が想定していない入力に対してきちんと対処できるかどうか」という考え方です。

### 2. 同値分割
　同値分割とは、「入力を意味のあるグループ（同値クラス）に分け、各グループから代表値を選ぶ方法」です。 同じような意味を持つ入力値によるテストを避けることができたり、意味のある入力値によるテストを見逃さないというメリットがあります。
　
　例として、以下のような仕様を持ったアプリケーションがあるとします。
　

・ユーザの年齢をテキストボックスに入力する。
・年齢は0～200までの数値が入力可能である。
・入力後、「チェック」ボタンを押す。
・入力された値に応じて、異なるメッセージボックスが画面上に表示される。

```
0～19が入力された場合：「未成年です」というメッセージボックス
20～99が入力された場合：「成人しています」というメッセージボックス
100～200が入力された場合：「とても長生きですね」というメッセージボックス
```

このアプリケーションにおいて、入力可能な数値の種類はたくさんありますが、実はそのグループは3つしかないことが分かります。同値分割では、これら各グループの中からそれぞれ10、80、150のように代表値を選び、テストを実施します

### 3. 境界値分析
　境界値分析とは、「同値クラス間の境界の値を入力とする方法」です。 メソッドの実装ミスは、一般的に境界値で生じやすいため、境界値分析を行なうことでミスを防ぐことができます。
　先ほどのアプリケーションですと、19と20、99と100がその境界値にあたります。
仕様書の「以下」と「未満」を取り違えたり、プログラムのif文中で不等号「＜」と「≦」を誤るなどして混入したバグは、この手法を用いて検出することが出来ます。

### 4. エラーの推測
　エラー推測は、エラーが発生しそうなデータパターンを推測し、テストケースを作成する手法です。このようなデータパターンというのは、ある程度形式知化されています。具体的には、以下のようなものがよく用いられます。

#### 1. 最大値・最小値、最大値より大きい値・最小値より小さい値
　言語やアプリケーションの仕様によって、入力可能な数値や文字長の最大値・最小値は決まっています。
　その値を超えた場合に、どのような動作となるかを検証します。
※このパターンは、エラー推測ではなく境界値分析に分類されることもあります。

#### 2. 小数
　浮動小数点数のように、桁数が大きなデータを扱うと丸め誤差が生じてしまうものをテストします。

#### 3. 空文字・スペース・ゼロ・NULL
　プログラムは「データが存在しない場合」や「NULLを参照した場合」に誤動作が発生しやすくなります。

#### 4. 入力されることを意図していない文字種
　数値の項目に漢字を入力する、氏名の項目に記号を入力するなど、本来は入力されるべきでない文字種に対しバリデーションが機能していることを検証します。

#### 5. うるう年、存在しない日付・時刻
　日付の項目にうるう年を入力し、正しく扱えることを確認します。また、「2015/14/12」、「26:00:00」のように存在しない日付・時刻を入力してみることもあります。

## テストケースを洗い出す手順

以上の観点を踏まえて、次のような手順でテストケースを洗い出します。

1. 正常系はどういうケースが考えられるか
2. 異常系はどういうケースが考えられるか
3. 1, 2について、同値分割するとどのような入力値が考えられるか
4. 1, 2について、境界値分析するとどのような入力値が考えられるか
5. 1~4を踏まえ、サービスが要求する品質と工数を考慮してテストケースとする

テストケースを洗い出す際は、正常系よりも異常系をしっかりと考えることで、安定したアプリケーションを構築することができます。

## テストケースの粒度

 前章で「サービスが要求する品質と工数を考慮して……」と示しました。

 たとえば、開発中のサービスが顧客から費用をもらう性質のプロダクトの場合、可能な限りテストケースを網羅すべきでしょう。 決済機能といったクリティカルな部分であれば、なおさらです。

 この場合、ドメイン/アプリケーション層だけでなく、インタフェース層（Viewなど）までも十分にテストを行なうことも検討した方がよいかもしれません。

 一方で、広告だけで成り立ち、かつ機密情報を扱わないtoCサービスの場合、テストの実装に時間を割くよりも、ユーザのために機能開発にコストをかけた方がよいかもしれません。
　
 テストは書こうと思えばいくらでも書けますが、その粒度はサービスの性質に応じて柔軟に決めます。
WordPressのオリジナルテーマにtitleタグを表示させる

## はじめに
ワードプレスに初めから用意されているテーマを使う場合は、管理画面よりタイトルを記入すれば自動的に表示されます。

今回はオリジナルでhtmlやcssを作成したものを、ワードプレスに組み込む（自身でテーマを作る）場合を想定しています。


## 手順

１. ワードプレス管理画面メニューの「外観」→「テーマの編集」より、
テーマのための関数（function.php）を選択して下さい。


２. function.phpに以下のコードを記述し、ファイルを更新して下さい。

```php
<?php
function my_setup_theme() {
    add_theme_support( 'title-tag' );
}
add_action( 'after_setup_theme', 'my_setup_theme' );
```
３. テーマヘッダー(header.php)を選択して下さい。
４. 以下の<?php wp_head(); ?>の記述がなければ`<head></head>`の間に記述して更新して下さい。

```php
<?php wp_head(); ?>
```

以上でワードプレスのオリジナルテーマにもタイトルタグが自動的に表示されるようになります。

以下を参考にさせていただきました。
http://smallville.jp/wordpress/194
作業速度があがる！覚えておくと便利なGoogleChromeショートカットキー

私の個人的経験より、覚えておくと便利なショートカットキーをまとめます。


#環境
OS：Windows10
Chrome：68.0.3440.106

#まずは覚えておくとよいベスト5

##1．検索　Ctrl + F
開いているページ内での検索時に使用します。

##2．新規タブを開く　Ctrl + T
新規タブを開き、開いたタブに移動します。

##3．アドレスバーに移動する　Ctrl + L
アドレスバーに移動することができます。
検索を繰り返し行っているときに便利です。

##4．開発者ツールを開く　F12 
開発者ツールを開きます。

##5．リンク先を新しいタブで開く　Ctrl を押しながら リンクをクリック
リンク先を新しいタブで開くことができます。
ただし、開いたタブに移動はしません。

以下、一覧です。

| 内容 | ショートカットキー |
|:--|:----|
| 検索 | Ctrl + F |
| 新規タブを開き、開いたタブに移動する | Ctrl + T |
| アドレスバーに移動する | Ctrl + L |
| 開発者ツールを開く | F12 | 
| リンク先を新しいタブで開く(移動はしない) | Ctrl を押しながら リンクをクリック |


#次に覚えておくと便利な5個

| 内容 | ショートカットキー |
|:--|:---|
| 次のタブに移動する | Ctrl + Tab |
| 現在のタブを閉じる | Ctrl + W |
| 閉じたタブを開き、そのタブに移動する | Ctrl + Shift + T |
| ダウンロードページを新しいタブで開く | Ctrl + J |
| ブックマークに登録 | Ctrl + D |

#その他
| 内容 | ショートカットキー |
|:--|:---|
| 別ウィンドウで開く | Ctrl + N |
| 現在のウィンドウを閉じる | Ctrl + Shift + W |
| ページ内検索で、検索内容に一致する次の部分に移動する | Ctrl + G |
| ページ内検索で、検索内容に一致する前の部分に移動する | Ctrl + Shift + G |
| ページ内拡大 | Ctrl を押したまま ＋キー |
| ページ内縮小 | Ctrl を押したまま －キー |
| 現在のウィンドウを最小化する | Alt + Space + N |
| 現在のページを印刷するダイアログを開く | Ctrl + P |
| リンク先を新しいタブで開き、移動する | Ctrl + Shift を押しながら リンクをクリック |
this

https://qiita.com/hp_kj/items/9ffe03bf2919c99b964a
https://qiita.com/hp_kj/items/789a7fb7e922745f8bd9
自分が最初の頃、仮引数と実引数さえしっかり理解していたらもっと理解が早く進んだ気がする。


```java

public class Monster {
	int hp = 100;
	int mp = 20;
	Monster(int hp ,int mp){
		this.hp = hp;//1
		this.mp = mp;
	}
```

//1のthis.hp = hp
this.hpはこのクラスから作られるインスタンスのhpです。int hp = 100;の部分のことです。

= hpは仮引数のhpです。
このクラスのhp = 仮引数のhpなので
Monster(int hp ,int mp)を呼んだときに実引数に入っていた値を読み出します。

なので、まとめると
このクラスから作られたインスタンスのhpに、仮引数のhpが入ります。
Opusmodusの基本。

# はじめに
[Opusmodus](http://opusmodus.com/)はCommon Lispベースの環境で簡単にMIDIやMusic XMLを生成することのできる統合開発環境です。
手前味噌ですが、Opusmodusを作って[こんな曲](https://youtu.be/BfuqA2U1WvQ?t=4m51s)とかを作ったりしました。
公式サイトにも色々サンプルがあります。
mac専用で有料ですが、色々実験的なアルゴリズム作曲をしたい時は便利です。

すごく便利なんですが、基本的に日本人のユーザーは今は僕しかいないので、せっかく興味があるのに英語のドキュメントに阻まれてハンズオンできない人を救済するために、簡単なことだけまとめます。


# 基本のキ
⌘+eでカーソル以下を評価し、コンソールに出力します。⌘+Eでファイル全体を評価します。  
OMNという単位で音価、音高、ダイナミクス、奏法を指定します。（以下、[公式サイト](http://opusmodus.com/ )よりキャプチャ）
![OMN](https://qiita-image-store.s3.amazonaws.com/0/148589/2a29166c-f983-9416-546f-81aa86907835.png)

ダイナミクスと奏法は省略することもできます。

例えば以下のように作ったOMN上にカーソルがあった時、
![Screenshot 2018-09-03 05.23.14.png](https://qiita-image-store.s3.amazonaws.com/0/148589/17e29df4-1c2d-990a-4d60-d22f3a3d6057.png)

⌘+1でMIDI再生、  
⌘+3で以下のように簡易楽譜の表示、
![eval.png](https://qiita-image-store.s3.amazonaws.com/0/148589/be45fa42-5200-76bb-f610-903b5cb143bf.png)
⌘+2で簡易楽譜を表示してMIDIを再生します。

# スコアについて
⌘+2で簡易楽譜を表示することはできるのですが、これは単一のOMNを表示できるだけなので、デバッグ向きの機能です。
複数の楽器や長いセクションを書くときは、一度scoreと呼ばれる単位にコンパイルします。
ここでいうscoreは総譜のようなものです。  
Opusmodusには`def-score`というマクロがあり、以下のように呼び出すことでscoreを定義することができます。

```clojure
(def-score qiita-tutorial
 (:time-signature '(4 4)
  :key-signature '(c major)
  :tempo 120)
 (piano :omn motif)
)
``` 

このマクロを呼び出すと`*last-score*`というグローバル変数に評価されたスコアのデータが入るので、

```clojure
(display-midi *last-score*)
(display-musicxml *last-score*)
```
こうするとスコアの再生や表示ができます。

# まとめ
Opusmodusを立ち上げワークスペースを一つ作りその中にファイルを一つ作って、以下のように書いて⌘+Eすると、とりあえずhello world完了です。

```clojure
(setf motif '(q c4 d4 e4))

(def-score qiita-tutorial
 (:time-signature '(4 4)
  :key-signature '(c major)
  :tempo 120)
 (piano :omn motif)
)

(display-midi *last-score*)
(display-musicxml *last-score*)

```

とりあえずこれだけだとアルゴリズムもへったくれもないので、[次の記事](https://qiita.com/Yuichi_Yogo/items/bf53d822dbdfea48e1ea)で強力な関数を紹介します。

あと、[Twitter](https://twitter.com/yuichi_yogo)でよく作ったものとかプロトタイプとかあげてるので、興味あったらぜひフォローしてください！
テスト用にダミーデータを用意する手段色々

会員制サービスのテストデータとして、いい感じの個人情報を入力したい。
また、クチコミや問い合わせメッセージなど、ある程度長文もダミーで用意したい。
姓名の欄が「あああ あああ」とか「テスト テスト」はやめたい。
実際にありそうなものは本物を使っていると誤解されかねないので、ある程度嘘っぽいのが良いかも

##ダミー個人情報の取得

###本番データを加工

本番データを特定の文字列で置換する。
「山田太郎」→「＊田＊郎」にする。
「山田太郎」→「黄井田太郎」と苗字だけ変える。
「山田太郎」→「鈴田次郎」とランダムで数文字変える。

ありえない文字が入ってしまっては、現実的ではない。
また、完全に個人情報を隠しきるのは難しいので漏れがある。
そもそも本番データを流用するのは厳しい場合が多い。

### 数字の連番にする

会員IDもしくは出力順に数字で「山田一郎」〜「山田一二三郎」と振っていく。
この場合、名前が長くなってしまうか。短く切ってしまうとダブりやすくなる。

###Fakerを使う

https://faker.readthedocs.io/en/master/locales/ja_JP.html

```python

from faker import Factory
fake = Factory.create('ja_JP')

print(fake.name())
print(fake.last_name())
print(fake.first_name())
print(fake.last_kana_name())
print(fake.first_kana_name())

```

手軽にできるのがいい
パターンが少ないので被りやすいかも
それぞれランダムなので、氏名のふりがなと漢字が一致しない

###ダミーデータ一覧サービスから取得

以下のようなダミーデータを提供しているサービスからデータを取得する
https://hogehoge.tk/personal/


```python

import pandas as pd
import random

df = pd.read_csv('personal_information.csv') 
# ランダムで行番号を取得
no = random.randint(0, len(df)-1) 
# 2列目 氏名
name = df.iloc[no, 1] 
# 3列目 氏名（カタカナ）
kana_name = df.iloc[no, 2]
print(name)
print(kana_name)

```

組み合わせが多い
氏名のふりがなと漢字が一致する
ただし、提供されているサービスがいつまであるかわからない
実際にありそうな内容なので、本番データと誤認されるかも

###本番データに見えないデータを使う

実際にありそうな名前を使うと、個人情報が雑に扱われていると誤解される恐れがある。
同姓同名の人がたまたま居て不快に思われるかもしれないので、ありそうにないデータを使う必要が出てくるケースもある。

[すごい名前生成器](https://namegen.jp/)
珍しい名前をランダムで生成してくれる。珍しいけど不自然でない名前を出してくれる。

[三国志演義の人物の一覧](https://ja.wikipedia.org/wiki/%E4%B8%89%E5%9B%BD%E5%BF%97%E6%BC%94%E7%BE%A9%E3%81%AE%E4%BA%BA%E7%89%A9%E3%81%AE%E4%B8%80%E8%A6%A7)
総計で1192人でいるらしい。データ量が多いのは良いが、日本の名前とかけ離れているので使い所が難しい。

[Category:架空の人物の一覧](https://ja.wikipedia.org/wiki/Category:%E6%9E%B6%E7%A9%BA%E3%81%AE%E4%BA%BA%E7%89%A9%E3%81%AE%E4%B8%80%E8%A6%A7)
著作権問題があるし外には出せないかもしれないが、もしかしたら使うときがあるかもしれない。
＜dt＞〜＜／dt＞の中に名前がある場合が多い。

```python

import requests
from bs4 import BeautifulSoup

url = "https://ja.wikipedia.org/wiki/%E9%80%B2%E6%92%83%E3%81%AE%E5%B7%A8%E4%BA%BA%E3%81%AE%E7%99%BB%E5%A0%B4%E4%BA%BA%E7%89%A9"
response = requests.get(url)
bs = BeautifulSoup(response.content, "lxml")
items = bs.find_all("dt")

for item in items:
   if  item.string is not None:
    print (item.string)
```


##ダミー長文の取得

###Fakerを使う

https://faker.readthedocs.io/en/master/locales/ja_JP.html

```python

from faker import Factory
fake = Factory.create('ja_JP')

print(fake.text())
print(fake.sentence())

```


###RSSフィードから取得する

```python

import feedparser
import random
import re

# RSS ページのURL
url = "https://rss.msn.com/ja-jp/"
feed = feedparser.parse(url)
# ランダムで記事を取得する
index = random.randint(0, len(feed.entries)-1)
# 記事タイトル
title = feed.entries[index].title
print(title)
# リンク
link = feed.entries[index].link
print(link)
# 記事
description = feed.entries[index].description
# HTMLタグを除いて出力
print(re.compile(r"<[^>]*?>").sub("",description))




```

ダミーじゃない文章なので、リアリティがある。
納品物とか第三者に渡すデータには適していない。


### 青空文庫から取得

青空文庫のような著作権フリーのデータを使う。
取得方法は下記を参考
http://newtechnologylifestyle.net/711-2/

著作権フリーの内容なので安心。
50年以上前の文章なので、日本語の文体がちょっと古い。
マルコフ連鎖と組み合わせて、LoremIpsumのジェネレーターぽく出来るかも。

WikiPediaを利用する手もあるが、第三者に提供する場合は、著作権の確認が必要。
https://webtan.impress.co.jp/e/2014/04/11/16643

英語の情報を丸パクリで和訳するのも
https://sirabee.com/2014/09/03/2404/
サーバアプリケーション終了時にlogbackのログが出力されない

背景
システムリプレースに伴い各種プラグインのバージョンを最新化
動作確認中にシステム終了時のログが出力されていないことに気付く。

構成
java9、Tomcat9、logback+slf4j、Springframework

発生の要因
logbackのバージョンを1.0.13から1.2.3への変更

発生箇所
javax.servlet.ServletContextListener#contextDestroyedをimplementsしたリスナークラスでシステム終了時にログを出していた。

対処１
logbackコンテキストの停止
logbackのサイトに従いコンテキストの停止を追加
https://logback.qos.ch/manual/configuration_ja.html#stopContext

しかし、これだけでは解決せず。

対処２
web.xmlへlogbackDisableServletContainerInitializerの追加
日本語訳のページには無かったが英語のページに答えが有った
https://logback.qos.ch/manual/configuration.html#webShutdownHook

対処２の設定を追加したら無事ログが出力されるようになった。
firewalldとiproute2でポートフォワーディング

# はじめに
特定のポートの通信を、特定のゲートウェイを通して行わせようと思います。

以前「[nginxをminecraftのプロキシとして使う](https://qiita.com/ttk1/items/007bf1623519dc614c1b)」という記事を書きました。
表に置くサーバーと、アプリケーションを動かすサーバーを分けるという話ですが、TCPレイヤーのプロキシを使用しているため、アプリケーション側から見ると接続元のIPアドレスがプロキシのものになってしまいます[^1]。
[^1]: Minecraftの場合はBungeeCord(Minecraftのプロキシアプリケーション)が独自のIP Forwardingでこれを解決しています。
今回は、IPパケットをフォワーディングさせることで、この問題を回避してみます。

# ネットワーク構成
![port_forwarding.png](https://qiita-image-store.s3.amazonaws.com/0/126305/faa056c6-633e-3fcd-6750-c898a6b8acd5.png)


minecraft: VM（VirtualBox）, Minecraft（25565番ポート）を動かす想定のサーバー
gateway: VM（VirtualBox）, clientからのパケットを直接受け取るサーバー
client: ホストマシン, Minecraftのクライアントを動かす

gatewayのネットワークアダプタはブリッジアダプタを使用して、ホストマシンと同じネットワークに置きます(DHCPなので、ルータの設定でgatewayのIPを192.168.0.101に固定しておきます)。
minecraft-gateway間は内部ネットワークで接続します。

# 設定内容
## 内部ネットワークの設定
### gateway
```bash
nmcli c add type ethernet ifname enp0s8 con-name enp0s8
nmcli c m enp0s8 ipv4.method manual ipv4.addresses 10.0.0.101/24 connection.autoconnect true
```
### minecraft
```bash
nmcli c add type ethernet ifname enp0s8 con-name enp0s8
nmcli c m enp0s8 ipv4.method manual ipv4.addresses 10.0.0.102/24 connection.autoconnect true
```

## ポートフォワーディングの設定
### gateway
```bash
# ip_forwardを有効化
echo 1 > /proc/sys/net/ipv4/ip_forward

firewall-cmd --direct --add-rule ipv4 nat PREROUTING 0 -p tcp --dport 25565 -j DNAT --to 10.0.0.102
firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -p tcp --sport 25565 -j SNAT --to 192.168.0.101
firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -p tcp --dport 25565 -j ACCEPT
```

デフォルトではカーネルの設定でip_forwardが無効になっているので、有効にします。

(firewalld) PREROUTINGチェインで25565番ポート宛てのパケットの送り先を10.0.0.102に書き換えます。
(firewalld) FORWARDチェインで25565番ポート宛てのパケットが別のホストへ通過する許可設定を入れます。
(firewalld) POSTROUTINGチェインで送り元が25565番ポートのパケットの送り元を10.0.0.102に書き換えます。

### minecraft
```bash
# 経路フィルタの設定
echo 2 > /proc/sys/net/ipv4/conf/enp0s8/rp_filter

firewall-cmd --direct --add-rule ipv4 mangle OUTPUT 0 -p tcp --sport 25565 -j MARK --set-mark 1

ip rule add fwmark 1 table 1
ip route add default via 10.0.0.101 dev enp0s8 table 1
```

経路フィルタに引っかかるようになるので、緩いフィルタ"2"に変更します。

(firewalld) OUTPUTチェインで、送り元が25565番ポートのパケットにマーク"1"を付けます。
(iproute2) マーク"1"を付けたパケットに適用するルートテーブルをテーブル"1"に変更し、テーブル"1"にgateway(10.0.0.101)を通過するルールを加えます。

以上の設定を入れることで、minecraftサーバーから見たclientのIPアドレスがgatewayのものではなく、本来のものとして通信することができるようになりました。

# まとめ
* ip_forwardとrp_filterの設定に気が付くのが遅れ結構な時間を無駄にした
* Linuxでルーターを作れるようになった
* デバッグでtcpdumpとかnetcatつかえるようになった
* BungeeCordを使おう

こんなことをやろうとする人が他にいるかわかりませんが、とりあえずまとめました。
Minecraftに限った話だとBungeeCordを使うのが最善かと思います。