OmniAICreator/Qiita-1.07M huggingface dataset:
【Python】matplotlib の「TypeError: Input z must be a 2D array.」でお困りの方へ【3次元プロット】

# 「x, y, z 座標を適当に Matplotlib の関数に渡したらエラー吐いた」

誰もが通る道です。
以下のようにしてデータを変換しましょう。

```python
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from scipy.interpolate import griddata

# x, y, z をそれぞれ1次元配列やリストに格納してしまった！
x = []
y = []
z = []
for i in range(-10, 10):
    for j in range(-10, 10):
        x.append(j)
        y.append(i)
        z.append(i ** 2 + j ** 2)

# そのままプロットしようとしてエラー！
# plt.contourf(x, y, z)  # --> TypeError: Input z must be a 2D array.

# そういうときは、scipy.interpolate.griddata() でサンプリングしなおしましょう。
x_new, y_new = np.meshgrid(np.unique(x), np.unique(y))
z_new = griddata((x, y), z, (x_new, y_new))

# これでちゃんと描画できます
ax = Axes3D(plt.figure())
ax.plot_surface(x_new, y_new, z_new)
plt.show()
```

![index.png](https://qiita-image-store.s3.amazonaws.com/0/154890/57ae0ae8-2714-9432-f88a-8b9ba6eeb5e3.png)

# `x`, `y`, `z` をそれぞれ2次元配列で用意できたら

## 等高線

```python
plt.contour(x, y, z)
plt.colorbar()
```

![](https://qiita-image-store.s3.amazonaws.com/0/154890/9cd70871-ad5f-5206-1099-c9b42eed466c.png)

## 等高線を塗りつぶす

```python
plt.contourf(x, y, z)
plt.colorbar()
```

![](https://qiita-image-store.s3.amazonaws.com/0/154890/3456f482-2b45-93d9-2b9c-76985edced54.png)

## 勾配

```python
dx = np.c_[np.gradient(x)]
dy = np.c_[np.gradient(y)]
dz = np.c_[np.gradient(z)]
dz_dx, dz_dy = np.linalg.solve(np.c_[[dx, dy]].T, dz.T).T

plt.contour(x, y, z)
plt.quiver(x, y, dz_dx, dz_dy)
```

![](https://qiita-image-store.s3.amazonaws.com/0/154890/bebd9214-8e3b-3c97-dcf6-3b8b085f18ae.png)

```python
plt.contour(x, y, z)
plt.streamplot(x, y, dz_dx, dz_dy)
```

![](https://qiita-image-store.s3.amazonaws.com/0/154890/83102fe5-8a65-005a-e776-407c756b0352.png)


# 補足: 2変数関数をプロットするときに2次元配列が3つ必要な理由

例えば、放物線の方程式 $y = x^2$ をプロットするとき、x 座標と y 座標を1次元配列で用意しますよね？
実はこれ、曲線上の点 $(x, y)$ を、次式のように配列の添字 `i` で[媒介変数表示](https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%A9%E3%83%A1%E3%83%88%E3%83%AA%E3%83%83%E3%82%AF%E6%96%B9%E7%A8%8B%E5%BC%8F)していることに相当します。

$$
\begin{cases}
x(i) = i \\\\
y(i) = i^2
\end{cases}
$$

```python
import numpy as np
import matplotlib.pyplot as plt

x = np.empty([10])
y = np.empty([10])

for i in range(10):
    x[i] = i
    y[i] = i ** 2

plt.plot(x, y)
plt.show()
```

![](https://qiita-image-store.s3.amazonaws.com/0/154890/667df047-9ed8-09ae-bd5d-2b61f0e04bdf.png)


では、空間曲面を描画するときはどうするかというと、点 $(x, y, z)$ を2つの媒介変数 $i$ と $j$ で表現します。x, y, z をそれぞれ2次元配列で渡すのは、これが理由です。

$$
\begin{cases}
x(i, j) = j \\\\
y(i, j) = i \\\\
z(i, j) = i^2 + j^2
\end{cases}
$$


```python
import numpy as np
import matplotlib.pyplot as plt

x = np.empty([10, 10])
y = np.empty([10, 10])
z = np.empty([10, 10])

for i in range(10):
    for j in range(10):
        x[i, j] = j
        y[i, j] = i
        z[i, j] = i ** 2 + j ** 2

plt.contourf(x, y, z)
plt.colorbar()
plt.show()
```

![](https://qiita-image-store.s3.amazonaws.com/0/154890/3456f482-2b45-93d9-2b9c-76985edced54.png)
TeXで\ifdefinedの使いかた

# TL;DR
```tex
\newcommand{\A}{test}
\ifdefined\A
	\verb|\A| は ``\A''　と定義されています
\else
	\verb|\A| は未定義です
\fi
```
コンパイルすると以下のようになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/45682/ba639285-5288-0ba6-88b3-411cf0dd918c.png)
先頭の\newcommandを消すと以下のようになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/45682/3c21bf1f-dc61-3c1c-d02a-b2aa6e100bc5.png)
# 何がうれしいの?
[subfiles](https://qiita.com/sankichi92/items/1e113fcf6cc045eb64f7)を用いて以下のような構造でM個のpdfの組成をしていました。

```text
共通プリアンブル(preamble.tex)
├── 課題1(main1.tex)
│   ├── 設問1(section1.tex)
│   │   ︙
│   └── 設問N(sectionN.tex)
├── 課題2(main2.tex)
│   ├── 設問1(section1.tex)
│   │   ︙
│   └── 設問N(sectionN.tex)
│   ︙
└── 課題M(mainM.tex)
    ├── 設問1(section1.tex)
    │   ︙
    └── 設問N(sectionN.tex)

```
section1.texをコンパイルすると、subfilesの機能でmain.texのプリアンブルを読みに行き、そこで指定されているpreamble.texに読みに行く。という2回のファイルアクセスが起きていました。
冗長だと感じたので以下のようにリファクタリングしました。

```text
共通プリアンブル(preamble.tex)
├── 課題1(main1.tex)
├── 設問1(section1.tex)
│   ︙
├── 設問N(sectionN.tex)
│   ︙
├── 課題N(main1.tex)
├── 設問1(section1.tex)
│   ︙
└── 設問N(sectionN.tex)
```
この木構造はプリアンブルの参照を表しています。ファイル名が競合しているように見えますが、実際にはディレクトリを分けています。

しかし、section1.texを個別のコンパイルするときpreamble.texを読み込んだ段階で\titleが未定義だと怒られてしまいます。
section1.tex本文では一度も\titleを使わないのですが困ります。
今まではmain.texで定義されていたために問題は起こりませんでした。
解決として\ifdefinedで未定義かチェックをするようにpreamble.texを書き換えました。

# 感想
TeX言語あまり詳しくないですが、使いこなしたいですね。
Mac でgitコマンドもlsコマンドも何もできない時の対処法

# 概要
git コマンドを叩こうとしたら、以下のようなエラーが出力されて困ったので、自分用の備忘録として。

```
-bash: git: command not found
```
ちなみにlsコマンドとかの主要コマンドも叩けなくなってしまっていたので、
色々調べたら以前にPATHの設定を弄くり回していたのが原因らしい。

# 直接PATH指定をする
```
/usr/bin/vi ~/.bash_profile
```
上記コマンドを叩いてエディタを開いて、

```
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
```
PATH指定をしてあげて、PCを再起動してあげる。
これで今の所は問題なしっと！！！！
QUICの仕様におけるアンプ攻撃対策

HTTP over QUIC (HTTP/3) がUDPベースとなるニュースを見て、いわゆるAmplification攻撃(アンプ攻撃, 増幅攻撃などとも)について気になってる人もいるようなので、初心者ながら簡単に調べる。

なお、トランスポートプロトコルであるQUIC側の機能であり正確にはHTTP3で提供される対策機能ではない。

IETF版QUIC draft-16ベースの説明になります。

## QUICについて
手前味噌ですが、前提となるQUICに関する資料は下記を参照

- [QUICの話 (QUICプロトコルの簡単なまとめ)](https://asnokaze.hatenablog.com/entry/2018/10/31/020215)
- [HTTP over QUICと、その名称について (HTTP3について)](https://asnokaze.hatenablog.com/entry/2018/11/06/025016)
- [QUICのコネクションマイグレーションについて](https://asnokaze.hatenablog.com/entry/2019/09/16/021413)


## アンプ攻撃とは
そもそもアンプ攻撃とは、送信元アドレスを攻撃対象となる対象のIPに偽装したUDPパケットをサーバに送信することによって、サーバからの応答を攻撃対象のサーバに送信させる攻撃手法である。

特に、サーバに送信したデータ量よりもレスポンスのデータ量が大きくなる場合、攻撃対象に大量のトラフィックを生み出すことができ、攻撃対象者のサービスを妨害することができる(DDoS攻撃)。

このときのトラフィックの増幅率は攻撃手法によっては10倍~100倍のトラフィックを生み出します。

## QUICにおけるアンプ攻撃対策
QUICでは届いたパケットが本当にそのIPを持つ相手から送信されているか確かめる`Address Validation`という手順があります。これによって偽装されたIPアドレスに大量のトラフィックが流れることはありません。

前提として、最初のコネクション確立時など、**サーバ側で届いたパケットの送信元IPが正しいか確証が得られてない段階では、クライアントは1200オクテット以上のパケットしか送信してはいけません**（適宜パディングする）。

もしそうでないパケットに対してはサーバは応答しません。こうすることで増幅率が低く抑えられ、アンプ攻撃を緩和します。

### Address Validation
コネクション確立時の`Address Validation`は、送られて来たパケットの送信元IPアドレスに
サーバが返信し、それが確かにIPアドレスの所持者であるクライアントに届き、処理が続行されることを持ってして確認が行われます。

以下のどちらかによって確認が行われます

- 暗号ハンドシェイクによって暗黙的に、そのパケットの送信元アドレスを持つ相手と通信できていることが確認されます。サーバからInitialパケットをクライアントがちゃんと受信できていることを確認できます。
- クライアントからのInitialパケットに対して、Tokenを含むRetryパケットを送り返します。その後クライアントはそのTokenを持って再度ハンドシェイクを行います。これによって、Tokenが正しくクライアントに渡せたことが確認できます。

### Path Validation
QUICではコネクションのマイグレーションする機能があります。QUICのコネクションはQUICレイヤで管理されているため、IPアドレスやポート番号が変わってもコネクションを維持することができます。
(ただし輻輳制御のウィンドウサイズ等は小さくなります)

IPアドレスやポートは様々な理由で変わります。キャリア回線からWi-Fi接続への移行に伴う、エンドポイントの意図的な変更や、NATリバインディングや中間装置によるエンドポイントの非意図的な変更などです。

このとき送信元IPアドレスが代わりうるわけですが、そのIPアドレスを攻撃対象者に設定できれば、トラフィックを偽装したIPアドレスに送信させることが来ます。しかし、QUICではコネクションのマイグレーション時にはお互いのインターフェースを含むそのパスの検証(`Path Validation`)を行い、送信元IPアドレスが偽装されていないことを確認します。

相手のIPアドレスが変わった（コネクションIDと鍵は正しい）場合、ランダムなデータを含む`PATH_CHALLENGE`フレームを送信し、同じデータを含む`PATH_RESPONSE`フレームがそのIPアドレスから帰ってきた場合、そのIPアドレスが正しい相手であることが確認できます。

この確認が済むまで新しいIPアドレスへのデータ送信量は制限されます。具体的に仕様で定義されている最小輻輳ウィンドウサイズです(kMinimumWindow)。

## おわり
QUICは通信相手がIPアドレスの所持者であることを確認します。

確認できてない場合は、増幅できないようになっているか、サーバから生成するトラフィック量が制限されます。

そのためアンプ攻撃でQUICを使用するのは他のプロトコルより効率的ではないでしょう。
【Unity】ARCoreでHelloARを動かしてみた。

【Unity】ARCoreでHelloARを動かしてみた。

環境メモ
⭐️Mac OS Mojave バージョン10.14
⭐️AndroidStudio3.2.1
⭐️Unity 2018.2.15f1
⭐️Android8.1.0

実際に動かした動画はこちら↓↓
https://twitter.com/nonnonkapibara/status/1062743276149596160

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ARCoreで<br>⭐️HelloAR⭐️を動かしてみたよぉ。<br>これからARCoreもやってみよ〜🎵<br>(o^^o)<a href="https://twitter.com/hashtag/Unity?src=hash&amp;ref_src=twsrc%5Etfw">#Unity</a> <a href="https://twitter.com/hashtag/Unity3D?src=hash&amp;ref_src=twsrc%5Etfw">#Unity3D</a> <a href="https://twitter.com/hashtag/ARCore?src=hash&amp;ref_src=twsrc%5Etfw">#ARCore</a> <a href="https://t.co/LkIA3W2jRG">pic.twitter.com/LkIA3W2jRG</a></p>&mdash; non (@nonnonkapibara) <a href="https://twitter.com/nonnonkapibara/status/1062743276149596160?ref_src=twsrc%5Etfw">2018年11月14日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


#<font color="Magenta">Qiitaの容量オーバーで画像が貼り付けられなくなりました。（errorとなる）</font>

続きは、こちらに記載してます↓
[かぴばらさんの覚書ブログ nonkapibara](https://nonkapibara.hatenablog.com/entry/2018/11/15/020019)
OnsenUI何故かうまく動かないリスト

v-forで何故か追加されない(追加はされてるけどpage__contentと同じ階層のところに追加されるので変なことになってしまう)
何故かだめ(v-ons-page直下でv-for使ったらだめ？？？)

```html:index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/onsenui/css/onsenui.css">
<link rel="stylesheet" href="https://unpkg.com/onsenui/css/onsen-css-components.min.css">
<script src="https://unpkg.com/onsenui/js/onsenui.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<script src="https://unpkg.com/vue-onsenui"></script>
<script>
	ons.ready(function() {
		new Vue({
			el: '#app',
			template: '#main',
			data() {
				return ({
					count: 3,
					todos: [
						{text: 1},
						{text: 2},
						{text: 3},
					],
				});
			},
			methods: {
				addList() {
					this.count++;
					this.todos.push({text: this.count});
				}
			}
		});
	});
</script>
</head>
<body>
<template id="main">
	<v-ons-page>
		<ons-button @click="addList">
			リストを増やす
		</ons-button>
		<div v-for="data in todos">
			{{ data.text }}
		</div>
	</v-ons-page>
</template>
<div id="app"></div>
</body>
</html>
```
こうするとOK

```html:index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/onsenui/css/onsenui.css">
<link rel="stylesheet" href="https://unpkg.com/onsenui/css/onsen-css-components.min.css">
<script src="https://unpkg.com/onsenui/js/onsenui.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<script src="https://unpkg.com/vue-onsenui"></script>
<script>
	ons.ready(function() {
		new Vue({
			el: '#app',
			template: '#main',
			data() {
				return ({
					count: 3,
					todos: [
						{text: 1},
						{text: 2},
						{text: 3},
					],
				});
			},
			methods: {
				addList() {
					this.count++;
					this.todos.push({text: this.count});
				}
			}
		});
	});
</script>
</head>
<body>
<template id="main">
	<v-ons-page>
		<ons-button @click="addList">
			リストを増やす
		</ons-button>
		<div>
			<div v-for="data in todos">
				{{ data.text }}
			</div>
		</div>
	</v-ons-page>
</template>
<div id="app"></div>
</body>
</html>
```

---
TECHSCOREのFlyweight パターンをSwiftでかく

#はじめに
こちらのページで紹介されているFlyweight パターンをSwiftで書いてみたときのメモ
http://www.techscore.com/tech/DesignPattern/Flyweight.html/

```swift

class HumanLetterFactory {

    var dic = [String: Target]()

    static let singleton = HumanLetterFactory()
    
    func printHumanLetter() {
        for (key, value) in dic {
            print("dictionary key is \(key), value is \(value)")
        }
    }
    
    
    func getHumanLetter(letter: String) -> Target {
        var humanLetter = dic[letter]
        if humanLetter == nil {
            humanLetter = Target(str: letter)
            dic[letter] = humanLetter
        }
        return humanLetter!
    }
    
    
}

class Target {
    let str: String
    
    init(str: String) {
        self.str = str
    }
    
    func output() {
        print(str)
    }
}
let test = HumanLetterFactory.singleton
test.getHumanLetter(letter: "あ").output()
test.getHumanLetter(letter: "い").output()
test.getHumanLetter(letter: "あ").output()
test.getHumanLetter(letter: "う").output()
test.printHumanLetter()

//シングルトンパターンを使っているから辞書に入っている値を取り出すと、前に作ったインスタンスに入れた値が出てくる
let test2 = HumanLetterFactory.singleton

test2.printHumanLetter()

```

# 実行結果
```
あ
い
あ
う
dictionary key is あ, value is Main.Target
dictionary key is い, value is Main.Target
dictionary key is う, value is Main.Target
dictionary key is あ, value is Main.Target
dictionary key is い, value is Main.Target
dictionary key is う, value is Main.Target
```

## 参考文献
[Swiftで学ぶデザインパターン20 (Flyweightパターン)](http://www.cl9.info/entry/2015/08/15/120032)
Rubymineをターミナルから開く方法

<img width="1680" alt="スクリーンショット 2018-11-15 0.42.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/199666/eba14d30-862b-318f-935e-dad3567d0477.png">

Tools>Create Command-line Lancher...を選択して

<img width="1680" alt="スクリーンショット 2018-11-15 0.42.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/199666/2ad1ad06-f797-adaf-a4d8-ed9bb1563bf1.png">

勝手にパスが作成されるのでOKを押すだけ

あとはターミナルで開きたいフォルダまで移動して

```bash
mine
```

これだけです。
めっちゃ簡単。
Rubyの基礎（「クラスの継承」の観点からオブジェクト指向を考えてみた）

##Rubyって？##
まつもとゆきひろ氏（通称Matz）によって開発されたオブジェクト指向スクリプト言語。
2004年にはRubyを使ったWebアプリケーションフレームワークのRuby on Railsが登場して一気に世界に普及

##オブジェクト指向って？##

オブジェクト指向とは、オブジェクト同士の相互作用として、システムの振る舞いをとらえる考え方
（Wikipedia）

オブジェクト指向プログラミング（Object Oriented Programming: OOP）とは、プログラムを手順ではなくて、モノの作成と操作として見る考え方だ。
https://eng-entrance.com/what-oop

明確な定義は決まってないっぽい。、まだプログラミング学習始めて1ヶ月で理解が浅すぎるが、クラスの継承の観点から自分なりに**「全てのデータはObjectクラスのオブジェクト・インスタンスだから」**と解釈した。

以下、頭の中を整理してみた。

##クラスとメソッド##

###クラス###
クラスは自身で定義した設計図に基づいて生成されたデータ（オブジェクト）を内部に持っており、そのデータを利用するための独自の使用方法（メソッド）を持つことができる。つまり、データの設計図の役割とその使用方法を整理できる便利ツール。クラスは設計図に基づいたデータ（オブジェクト）を作成することができる。**全てのデータ（オブジェクト）は何かしらのクラスの設計図に基づいて作られたものなので、必ず何かしらのクラスに属している。**

###オブジェクト（インスタンス、レシーバ）###
クラスに定義された設計図に基づいて作られたデータをオブジェクト（インスタンス、レシーバ）と呼ぶ。同じ設計図（クラス）から作られたデータは同じ属性（データ項目、オブジェクトが持つ情報の種類）やメソッド（使用方法）を持つ。データ内容自体はクラス外で付与するので、作られたデータによってそれぞれ異なるデータ内容を持っている。
呼び方が複数あるが、「インスタンス」はクラスの視点から見た用語で、「レシーバー」はメソッドの視点から見た用語。
「インスタンス」と呼ぶ場合は，（たとえあらわに書いてなくても）必ず何らかのクラスが想定されていて、「○○のインスタンス」として使われる。また、「レシーバー」と呼ぶ場合は必ず何らかのメソッドが想定されていて、そのメソッドが呼び出される対象のオブジェクトを指している。

「オブジェクト」「インスタンス」「レシーバー」はそれぞれ「物（ブツ）」「クラスから生成された具現物」「メソッドの受け手」のようなイメージ

```ruby
class Review

end
review = Review.new（引数） # Reviewクラスのオブジェクト・インスタンスを生成
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/298093/19755b3f-7afc-1626-48eb-c8927a417dcd.png)

###メソッド（使用方法）###
使用方法、処理をひとまとめにして名前を付けて、何回も再利用できるようにしたもの。

###メソッド（使用方法）の定義###

■クラスメソッド：クラス自身（self）が持っているメソッド。

```ruby
class クラス名
  def self.メソッド名
    # 処理
  end
end

# メソッドの呼び出し
クラス名.メソッド名(引数)
```

■インスタンスメソッド：クラスから生成されたインスタンスが使用できるメソッド。**インスタンスごとの個別の情報（属性値）を使った処理に使用**。
例えば「レビューの内容を表示する」メソッドは、各レビューのインスタンスの個別の情報（（属性値）を使用するので、インスタンスメソッドとして定義。

```ruby
class クラス名
  def メソッド名
    # 処理
  end
end

# メソッドの呼び出し
インスタンス.メソッド名(引数)
```
###変数###

■クラス変数（＠＠変数名）：クラス全体で使用できる変数。クラス内であればどこでも使えるのでクラスメソッド、インスタンスメソッドの両方で使うことが出来る。クラスを通して、値が共通の情報に使用。

■インスタンス変数（＠変数名）：共通の属性としてインスタンスに定義できる変数。値は、個々のインスタンスによって別々に設定できる。例えばタイトルや感想は、各レビューごとに内容が異なる。つまり、インスタンスごとに値が異なる情報。よってインスタンス変数を使用

```ruby
class クラス名
  def write_review
    puts "タイトルを入力してください"
    @title = gets.chomp
    puts "ジャンルを入力してください"
    @genre = gets.chomp
    puts "感想を入力してください"
    @impression = gets.chomp
  end
end
```

##クラスの継承##

あるクラスに定義されたメソッドを、別のクラスで利用出来るようにすることを**継承**と言う。

クラスの継承には、親クラスと子クラスの関係があり、元となるクラスを**親クラス（スーパークラス）、親クラスのメソッドを引き継ぎ新しく作成するクラスを子クラス（サブクラス）**と呼ぶ。

```ruby
継承方法
class 子クラス名 < 親クラス名
```

継承するかどうかのポイントは性質や概念が共通しているか、**「is-aの関係」が成立するかどうか**
言い換えると**「サブクラスはスーパークラスの一種である」**、もっと具体的に言うと、**「犬は動物の一種である」**という関係がスーパークラスとサブクラスの間に成立しているかどうかが継承の判断基準になる。

基本的にRubyの継承は単一継承で、継承できるスーパークラスは1つだけ。
クラスはRubyに標準装備されているものがある。例えば**文字列はStringクラス、数値はNumericクラス、配列はArrayクラス、ハッシュはHashクラス**である。これらは標準装備されているので、クラスを定義せずとも、オブジェクトやそれに付随したメソッドを使用することができる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/298093/d8c14543-edb9-f91f-02de-f10b5a790c75.png)

これら標準装備のクラス（ライブラリ）の継承関係を見ると、トップに君臨しているのが**BasicObjectクラス**。
これはRuby1.9から導入されたクラスでそれまでは、**Objectクラス**がトップに君臨していた。図を見ると、一目瞭然だが、Stringクラス、Numericクラス、Arrayクラス、Hashクラスは全てObjectクラスをスーパークラスとして継承したサブクラスである。この図を言い換えると、**Rubyにおける全てのデータはObjectクラスのオブジェクト・インスタンス**と言える。

だから、Rubyはオブジェクト指向の言語って言うのかな？　と勝手に考えてました。
Jupyter lab / notebookで argparseそのままで実行する方法



#はじめに
Jupyter labやJupyter notebookが非常に便利なツールであることは言うまでもないことです。
しかし、落ちているブログラムをJupyterで編集しようとして、

```python:

def main():
    parser = argparse.ArgumentParser(description='ChainerMN example: MNIST')
    parser.add_argument('--batchsize', '-b', type=int, default=100,
                        help='Number of images in each mini-batch')
    parser.add_argument('--communicator', type=str,
                        default='hierarchical', help='Type of communicator')
    parser.add_argument('--epoch', '-e', type=int, default=20,
                        help='Number of sweeps over the dataset to train')
    parser.add_argument('--gpu', '-g', action='store_true',
                        help='Use GPU')
    parser.add_argument('--out', '-o', default='result',
                        help='Directory to output the result')
    parser.add_argument('--resume', '-r', default='',
                        help='Resume the training from snapshot')
    parser.add_argument('--unit', '-u', type=int, default=1000,
                        help='Number of units')
    args = parser.parse_args()

......

```


```
usage: ipykernel_launcher.py [-h] [--batchsize BATCHSIZE]
                             [--communicator COMMUNICATOR] [--epoch EPOCH]
                             [--gpu] [--out OUT] [--resume RESUME]
                             [--unit UNIT]
ipykernel_launcher.py: error: unrecognized arguments: -f /run/user/1218/jupyter/kernel-662a3733-81e6-4d71-9647-27185d96086a.json
An exception has occurred, use %tb to see the full traceback.

SystemExit: 2
```
この様なエラーメッセージに出くわしたことはありませんか？

コマンドライン引数は　jupyter では対応できないんだ、なんて思っていませんか？


#解決策
これを、

```python:
args = parser.parse_args()
```

こう変えます。

```python:
args = parser.parse_args(args=[])
```


なんとこれだけで、同様のエラーが出なくなり、
コマンドラインで実行しているようにJupyter上で実行できます。

ちなみに上の状態では全く引数を指定してない状態を示します。




##引数の指定がある場合は

引数の指定がある際は、arg=[ ]の[ ]内に
コマンドラインで打ち込む順にリストに入れます。

例えば以下の様に引数を指定プログラム実行するとします。

```shell

$ python test.py --batchsize 200 --epoch 100 -g
```

この実行と同じ引数指定をして、jupyter上で実行する場合は、該当部分を、

```python:
args = parser.parse_args(args=['--batchsize','200','--epoch','100','-g'])
```

とすれば、実行できます。

皆さんよき**Jupyter**生活を!!



####reference
https://blog.csdn.net/u012869752/article/details/72513141
Azure AD B2Cを触る -ディレクトリの作成-

ID管理で[Auth0](https://auth0.com/jp9)や[Okta](https://www.okta.com/)を使うか悩んでいたのですが、Azure AD B2Cも良さそうなので触ってみました。

Azureは公式ドキュメントが充実しているので、まずは以下をみるのがおススメです。
https://docs.microsoft.com/ja-jp/azure/active-directory-b2c/

以下は自分向けのメモです。

テナントとディレクトリの違いがイマイチよくわかっていない[^1]のですが…~~規定のディレクトリでは以下のようにAzure AD B2Cで何もできないので、~~Azure Active Directoryで新しくディレクトリを作成しました。

---

**追記**
Marketplaceのメニューからいくと「作成」が出てきました。
![2018-11-15_09h03_25.png](https://qiita-image-store.s3.amazonaws.com/0/47737/1951983e-2999-7f8b-aca9-e20cec5c200d.png)
![2018-11-15_09h03_54.png](https://qiita-image-store.s3.amazonaws.com/0/47737/ec0f79d9-c1f8-a8a6-012c-5233bcdf8168.png)

規定のディレクトリのままでもテナント作成はできますね…失礼しました。

---

![2018-11-13_22h42_03.png](https://qiita-image-store.s3.amazonaws.com/0/47737/9a0bb9a5-382e-7676-bb92-6f3b930234f4.png)

[^1]: https://serverfault.com/questions/701098/difference-between-an-azure-ad-directory-and-an-azure-ad-tenant

「ディレクトリの作成」メニューの位置がわかりにくいのですが…右下です。
![2018-11-13_22h46_53.png](https://qiita-image-store.s3.amazonaws.com/0/47737/0920ba2e-ddfb-0be9-2667-81335e8c239e.png)

組織名とドメイン名を入れて、リージョンは東京を選択しました。
![2018-11-13_22h48_25.png](https://qiita-image-store.s3.amazonaws.com/0/47737/276c5e6c-0462-b890-bc57-39f0970294fc.png)

少し時間がかかりますが、新しくディレクトリが作成されると、次のようにダッシュボードがまるっと新しい状態になります。
![2018-11-13_23h12_45.png](https://qiita-image-store.s3.amazonaws.com/0/47737/6fd069a5-6cea-90ce-5906-83a7aab2bb84.png)

ディレクトリの切替は右上のメニューをクリックして出てくるパネルでできます。
![2018-11-15_00h33_14.png](https://qiita-image-store.s3.amazonaws.com/0/47737/47195cc8-8609-48a7-8190-a5b8b388ac8d.png)

ディレクトリを作成した状態だとサブスクリプションがないため何もいじれません。そこでサブスクリプションを追加します。
![2018-11-14_01h03_12.png](https://qiita-image-store.s3.amazonaws.com/0/47737/efef6783-e1f1-b214-78fb-da3eb91b123a.png)
![2018-11-14_01h03_35.png](https://qiita-image-store.s3.amazonaws.com/0/47737/c0ff6992-a458-b5f0-9a5a-52d7dceef0d9.png)

以下のように追加されれば完了です。セッションの関係なのか、規定のディレクトリ側にできることが多々ある気が…。サブスクリプションを付け替えることも可能でした。
![2018-11-14_23h19_11.png](https://qiita-image-store.s3.amazonaws.com/0/47737/2cf45655-f117-9021-3fb3-6c7fd1cc5c45.png)

次はAzure AD B2Cを触っていきたいと思います。
WorkboxでRailsのAPIから受け取ったコンテンツをキャッシュできない時

[Workbox](https://developers.google.com/web/tools/workbox/)はService Worker使うなら使って損なしの最強ツールですが、Railsで作成したAPIサーバーからのデータが、chromeのdevツールではキャッシュされていることが確認できるのに、データをfetchするときにそのキャッシュを使用してくれなくて困った。

結論としては、ごく単純なCache-Controlの話であった。

[Rails側でブラウザキャッシュを有効にする](https://qiita.com/7kaji/items/98d5875cf91f0e3f904f)必要がある。

どうやらRailsでは、キャッシュヘッダーがデフォルトで`Cache-Control: max-age=0, private, must-revalidate`を返すらしい。

Workbox使ってるけど、なぜかキャッシュ効かねぇとお悩みの方は、devツールのNetworkタブからheader情報を確認し、変なCache-Controlがかけられていないかをまず確認することをおすすめする。

特に内容がないような記事ですが、「Workbox」と「Rails」の2ワードで悩める人の助けになるかもわからんので、書きました。
vueでwebpackを使わないけど、ファイルの分割はやりたいという人向け


内容はタイトルどおり。

環境を特に準備することなく、さらっと書きたいとか。
ちょこっとだけ書きたいけど、vue.componentは使いたいとか。。。
なにが嬉しいかは人それぞれなので。

簡単なんで、前振りはここまでで実物の全容を見ればよいかと。

# Vue Componentでファイル分割

```html:サンプル
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<div id="components-demo">
    <hello-world></hello-world>
    <hello-world2></hello-world2>
</div>


<script src="https://unpkg.com/vue"></script>
<script src="addComponent.js"></script>
<script>

    addComponent({
        name: "hello-world",
        url: "./vuetest_template.html",
        props: [],
    });
    addComponent({
        name: "hello-world2",
        url: "./vuetest_template2.html",
        props: [],
    });

    new Vue({el: '#components-demo'});

    }

</script>
</body>
</html>
```

```html:vuetest_template.html
<div>
    test
</div>
```

```html:vuetest_template2.html
<div>
    test2
</div>
```


こんな感じです。特に難しいことない。
addComponentは、今回特別に作った所。
嬉しい（？）ことに、個々に分割されたファイルの内容は必要な時のみ読み込みが発生する。




で、addComponentの実装がこちら。
(細かなjsのテクニックは自分で追記してください)

```js:addComponent.js
function addComponent(p) {
    Vue.component(p.name, function (resolve, reject) {
        fetch(p.url)
            .then((response) => {
                if (response.ok) {
                    return response.text();
                } else {
                    resolve({template: "<p>template not found</p>"});
                    throw new Error();
                }
            })
            .then((text) => resolve({template: text, props: p.props, data: p.data}))
            .catch((error) => {
            });
    });
}
```

マニュアルでは、こんな感じで書いてある
https://jp.vuejs.org/v2/guide/components-dynamic-async.html


# Vue router でファイル分離

テンプレートを非同期でセットしても良い。

```js
const Bar = {template: ''};
fetch("bar.html")
    .then(res => res.text())
    .then(text => {
        Bar.template = text
    })
    .catch(err => {
        alert(err)
    });
const router = new VueRouter({
    routes: [
       {path: '/bar', component: Bar}
    ],
});
const app = new Vue({
    el: '#app',
    router,
    data: {},
});

```
Redminea APIとSlack APIをpythonで連携してみた

## 概要
前回の記事( [Docker環境でRedmineを立ち上げてslackと連携させてみた](https://qiita.com/mgmgOmO/items/b439bbb8796537942f33) )ではプラグインを使用してRedmineとSlackの連携を行いましたが、
今回はSlack APIとRedmine APIを使用してpythonで連携する方法を紹介します。
自分でAPIを操れるようになると自由度が格段にあがります。

ざっくりとしたイメージとしては、SlackとRedmineをpythonが仲介しており、APIとライブラリがインターフェースを担っているような感じです。
[Slack] ⇔ Slack API ⇔ python-slackclient ⇔ [python] ⇔ python-redmine ⇔ Redmine API ⇔ [Redmine]

## 使用ライブラリ
- python-redmine 
 - https://github.com/maxtepkeev/python-redmine (GitHub)
 - https://python-redmine.com (公式リファレンス)
- python-slackclient
 - https://github.com/slackapi/python-slackclient (GitHub)
 - https://slackapi.github.io/python-slackclient (公式リファレンス(多分))

## 事前準備

ここではあまり詳しく解説しません。検索すれば見つかると思うので他の記事をご参照ください。

#### Slack側の設定

- Slack API( https://api.slack.com/apps )のサイトからSlack Appを作成し、認証設定(authorization)を行う
- Slack APIの設定画面 > OAuth & Permissions から、OAuth Access Tokenを取得する

![スクリーンショット 2018-11-14 23.44.35.png](https://qiita-image-store.s3.amazonaws.com/0/140953/22c533b1-4aae-70a3-c90a-56e70da4899a.png)

#### Redmine側の設定

- 管理者権限でRedmineにログインし、管理 > 設定 > API の画面で「RESTによるWebサービスを有効」にチェックして有効にする
- 個人設定 > APIアクセスキーの画面で、 APIアクセスキーを取得する

![スクリーンショット 2018-11-14 23.44.54.png](https://qiita-image-store.s3.amazonaws.com/0/140953/2233e51d-f28f-1d5a-6322-a962e1315099.png)

#### 環境変数にトークンを設定する

トークンはコードにベタ書きでも使用できますが、環境変数に設定する方がセキュリティ面で安全です。
python-slackclientの公式ドキュメントではこの方法を推奨しています。

環境変数を設定する方法やコマンドはOSに合わせて適宜変えてください。
Linux,Macの場合

```shell
$ export SLACK_TOKEN='your token'
$ export REDMINE_TOKEN='your token'
```

WindowsのPowerShellの場合

```shell
> $env:REDMINE_TOKEN = 'your redmine token'
```

Windowsのコマンドプロンプトの場合

```shell
> set REDMINE_TOKEN=your redmine token
```

## 内容

Redmineから取得してきたチケットの情報を、Slackへ投稿します。

```python
import os
from redminelib import Redmine
from slackclient import SlackClient

# 環境変数からトークンを取得
slack_token = os.environ["SLACK_TOKEN"]
redmine_token = os.environ["REDMINE_TOKEN"]

# クライアントインスタンスの作成
redminecliant = Redmine('http://your_redmine_url', key=redmine_token)
slackclient = SlackClient(slack_token)

# 投稿用パラメータを設定
channel = "general"
message = dir(redminecliant.issue.get(ticketNumber))

# 投稿
slackclient.api_call(
  "chat.postMessage",
  channel=channel,
  text=message
)
```

以下のようにSlackに投稿されれば成功です。

![スクリーンショット 2018-11-14 23.53.47.png](https://qiita-image-store.s3.amazonaws.com/0/140953/cf2d7545-98d2-4130-abee-79aff03b031b.png)

Slack APIやRedmine APIはそれぞれ様々な関数が用意されているので、リファレンスなどをご参照ください。

## 最後に

何か間違いや不明な点があればご指摘ください。
iOSでNSLogをフックする

NSLogはOSからの警告などが表示されるので非表示にしたくないが、3rd partyのライブラリのdebug logなどノイズが多いのでfilterしたい。
_NSSetLogCStringFunctionというprivate APIがあるようだが、Xcode上ではうまくいかなかった。
代替案としてstderrをpipeにリダイレクトしてみた。
元のstderrのハンドルを保存しておけば、Xcodeのconsoleに出力しつつ端末のファイルに残す、みたいなことができると思う。
以下の例では+loadにより明示的にnewしなくても勝手に起動する。

```objc:StdErrFilter.m
#import <UIKit/UIKit.h>

#ifdef DEBUG
static dispatch_source_t dispatchSource;

@interface StdErrFilter : NSObject
@end

@implementation StdErrFilter
+ (void)load
{
    NSPipe *pipe = [NSPipe new];
    int stdErrHandle = dup(STDERR_FILENO);
    dup2(pipe.fileHandleForWriting.fileDescriptor, STDERR_FILENO);
    dispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ,
                                            pipe.fileHandleForReading.fileDescriptor,
                                            0,
                                            dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0));
    dispatch_source_set_event_handler(dispatchSource, ^{
        NSData *data = pipe.fileHandleForReading.availableData;
        const char *bytes = data.bytes;
        size_t length = 0, remainBytes;
        for (remainBytes = data.length; remainBytes > 0; remainBytes -= length) {
            const char *lf = strchr(bytes, '\n');
            length = lf ? lf - bytes + 1 : remainBytes;

            // TODO: filter

            write(stdErrHandle, bytes, length);
            bytes += length;
        }
    });
    dispatch_resume(dispatchSource);
}
@end
#endif
```
Linuxコマンドメモ

# Linuxコマンドメモ

随時更新

## ネットワーク

### ホスト名を調べる
```bash
host ホスト名
```


### IPアドレス確認

```bash
hostname -I
```
```bash
ifconfig
```
```bash
ip a
```

### nc（コマンドでTCP/UDP接続）
#### ポートスキャン
```bash
nc -zv localhost 1-1000
```

※参考 [nc コマンド 使い方メモ](https://qiita.com/yasuhiroki/items/d470829ab2e30ee6203f)
ChromebookにCrostiniでOctaveをインストール

# はじめに
ChromebookでMATLABが使いたくて、AndroidアプリのMATLAB Mobile入れたり、Octave Online入れたり試行錯誤中。
今回、ChromebookにCrostiniでOctave入れてみた。まあまあ、ネイティブアプリっぽく動かせる。

# インストール

CrostiniのTerminalから下記コマンドうつだけでインストールできた。

```
sudo apt-get install octave
```

# 実行

こんな感じ。ちゃんと、ファイルはCrostiniのディレクトリに保存できる。
日本語は打てなかった。別の所からコピペしたら、一応入力はできた。
ショートカットキーのF5とかF9で実行するときは、検索キー押しながら上の方のキーを押すと入力できた。検索キーがファンクションキー相当っぽい。まあまあいい感じ。

![Screenshot 2018-11-14 at 11.04.26 PM.png](https://qiita-image-store.s3.amazonaws.com/0/184221/37bbc51f-2aa6-7630-97bf-b814db432486.png)

# おわりに

結構いい感じ。MATLAB MobileとかOctave Onlineよりもいい感じに使える。
しばらく使ってみよ。
Vim/ALE/PHP-CS-FixerでPHPソースを自動整形する

VimでPHPを書く際、ファイル保存時に自動でコードフォーマットして欲しくなったのでそのときの備忘録です。
# 利用するツール
- [ALE](https://github.com/w0rp/ale)
- [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer)

# 設定手順
## ALE
vim/nvimの非同期コードチェックプラグインであるALE(Asynchronous Lint Engine)を導入します。
[GitHubに記載の導入手順](https://github.com/w0rp/ale#3-installation)に沿って導入します。

## PHP-CS-Fixer
次にPHPのコード整形ツールであるPHP-CS-Fixerをお使いのPCにインストールします。
手順は同じく[GitHubに記載のインストール手順](https://github.com/FriendsOfPHP/PHP-CS-Fixer#installation)に従ってインストールします。ComposerやHomeBrewでインストール可能です。

## Vimの設定
あとはお使いの環境に沿って.vimrc等に以下の設定を加えてvimを再起動すれば、保存時に自動的にソースが整形されます。

```
let g:ale_fixers = {}
let g:ale_fixers['php'] = ['php_cs_fixer']
let g:ale_fix_on_save = 1
```

# まとめ
記載内容に誤りなどございましたら、ご指摘頂けると助かります。
閲覧いただき、ありがとうございました。
Ubuntu 18.04にNVIDIAドライバを入れようとしてハマった（原因はUEFIセキュアブート）

# ハマったところ
`nvidia-smi`が失敗する。ドライバのインストールには成功しているはずなのに。

```shell-session
$ nvidia-smi
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. 
Make sure that the latest NVIDIA driver is installed and running.
```

```shell
$ dpkg -l | grep nvidia
ii  libnvidia-cfg1-390:amd64                   390.87-0ubuntu0~gpu18.04.1                  amd64        NVIDIA binary OpenGL/GLX configuration library
ii  libnvidia-common-390                       390.77-0ubuntu0.18.04.1                     all          Shared files used by the NVIDIA libraries
...
ii  nvidia-390                                 390.87-0ubuntu0~gpu18.04.1                  amd64        Transitional package for nvidia-driver-390
...
```


`lsmod`でも無反応。


```shell
$ lsmod | grep -i nvidia
```


加えて、無効にしておいたはずの`nouveau`が復活している。


# 環境
- Ubuntu 18.04.1 LTS
  - kernel: 4.15.0-39-generic
- GeForce GTX 1070

# 解決法

### **BIOS(UEFI)でセキュアブートを無効化する**


:warning:  **Windowsとのデュアルブートの場合：Windowsが起動しなくなる可能性があるようなので、その他の解決法（署名なしドライバを読み込めるように設定を変える、など）を試してみてください。  ->  [参考になる記事](https://qiita.com/chiral/items/3105c52fc9fdb528dbd7)**

- BIOS(UEFI)画面を開く
  - 筆者の環境では起動時に`F2`か`DEL`キーを押す
- `Advanced Mode(F7)`-> `Boot` -> `Secure Boot` -> `OS Type`で、OS Typeを`Windows UEFI mode`から`Other OS`に変更する

- 設定を保存して終了

これで解決しました。

# 原因

[こちら](https://askubuntu.com/questions/762254/why-do-i-get-required-key-not-available-when-install-3rd-party-kernel-modules)の情報によると、`Ubuntu kernel 4.4.0-20`以降はUEFIセキュアブートが有効になっている場合に署名なしのドライバをロードしなくなったとのこと。

> Since Ubuntu kernel 4.4.0-20 the EFI_SECURE_BOOT_SIG_ENFORCE kernel config has been enabled. That prevents from loading unsigned third party modules if UEFI Secure Boot is enabled.

> The easiest way to fix this issue is to disable Secure Boot in UEFI (BIOS) settings.

# 参考

- [ubuntu16でNVIDIAのドライバインストールでハマった時 - Qiita](https://qiita.com/chiral/items/3105c52fc9fdb528dbd7)

- [Why do I get “Required key not available” when install 3rd party kernel modules or after a kernel upgrade?](https://askubuntu.com/questions/762254/why-do-i-get-required-key-not-available-when-install-3rd-party-kernel-modules)
Raspberry PiでSoftEther VPN Serverを動かす

## 準備するもの

- Raspberry Pi 3 Model B+ (無線LAN内蔵なので便利です）

## インストール

- bridge-utilsをaptでインストールする
- [SoftEther VPN](https://softether-download.com/ja.aspx)（VPN Server, Linux ARM EABI 32bit）をmakeしてinstallする
- SoftEther VPNのvpnserverデーモンをinit.dで自動起動させる

###サーバの設定
 [SoftEther VPN](https://softether-download.com/ja.aspx) Server Manager for Windows (or for Mac OS X)でサーバを設定します。

- 管理者パスワードの変更
- リモートアクセスVPNを選択
- VPN Azureを有効にする
- 仮想HUB VPNを定義し、仮想ネットワークインタフェースsoftetherをブリッジ先とする

### ネットワーク設定
ネットワーク設定は、色々なページを参考にしましたが、決め手がありませんでした。結局、

- 無線LANと有線LANのデュアルホームにする
- 無線LANには静的IPアドレスを付与する
- ブリッジインタフェースはDHCPをもらうようにして、eth0とSoftEtherのTAPデバイスとブリッジさせ、家のブロードバンドルータとRaspberry PiをLANケーブルで接続する

ことでうまくいきました。

```bash:/etc/network/interfaces
source-directory /etc/network/interfaces.d

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet manual

auto wlan0
iface wlan0 inet static
address 192.168.102.2
netmask 255.255.255.0
gateway 192.168.102.1
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

auto br0
iface br0 inet dhcp
bridge_ports eth0 tap_softether
bridge_maxwait 10
```

##接続
 [SoftEther VPN](https://softether-download.com/ja.aspx) クライアント接続マネージャで、接続先にVPN Azureのホスト名を指定すると接続できます。
これで、リモート環境から自宅に設置したVPN ServerにVPN接続できました。
Helmを触ってみようと思ったらそこまでたどり着かなかった

最近Kubernetesを会社でも使い始めていて、HelmというKubernetes用のパッケージマネージャーなるものがあると聞いたので、調べようと思ったんだけど、いろいろ寄り道してしまい結局たどり着かなかったという話。

# Helmって？
[Helmの概要とChart(チャート)の作り方](https://qiita.com/thinksphere/items/5f3e918015cf4e63a0bc) に詳しくいろいろ書いてある

# Kubernetes on local (Mac)

Docker for MacにはKubernetesも付いてるんだけど、有効にしてなかったので有効にして使えるようにした。

# サンプルアプリのデプロイ
[Docker for MacでKubernetes インストールからデプロイまで](https://qiita.com/uni-3/items/a4f2afa0973bfc35b498) を見ながら[kubernetes-dashboardのyaml](https://github.com/kubernetes/dashboard/blob/master/src/deploy/recommended/kubernetes-dashboard.yaml)を落として、デプロイしてみた。
てか一つのyamlに複数のリソース書いて一気にApplyできるの知らなかった。。しかも`kubectl delete`でも一気に消せる。

# docker-compose.ymlを使ってKubernetesにデプロイ

さっきのQiitaの記事を見てたらできるって書いてあったんだけど、そんなの知らなかった。。

```bash
docker stack deploy STACK_NAME --compose-file docker-compose.yml
```

で、できるらしい。なんか時間はかかったけど、VolumeMountもできてるし、自動でlocalhostのLoadBalancerが作られててすぐにアクセスできる状態になってた。

# docker-compose.ymlをKubernetes Resourceに変換する

もうちょっと調べて見たら、公式ドキュメントに、[Kompose](http://kompose.io/)をつかって、docker-compose.ymlをKubernetes Resourceに変換できるよって書いてあった。
[Official Document: Translate a Docker Compose File to Kubernetes Resources](https://kubernetes.io/docs/tasks/configure-pod-container/translate-compose-kubernetes/)

てか、`kompose up`で直接実行できるのね。なんか起動が`docker stack`より早い。ただし、VolumeMountサポートしてないよみたいなWarningがでるのと、デフォルトではLoadBalancerやノードポートのサービスを作ってくれないのでアクセスできない。。

VolumeMountについては[Issue](https://github.com/kubernetes/kompose/issues/599)をみると、手動で作成する必要ある（？）みたい。LoadBalancerは公式ドキュメントのページに書いてあったけど、

```yml
    labels:
      kompose.service.type: LoadBalancer
```

を書いておくと`kompose up`のときに作ってくれた！

# `docker stack`と`kompose up`の違いは？

ちょっと探してみたけど、違いに言及されている記事は見つかんなかったな。（ちゃんと調べれば出てくるかも。）ただ、`docker stack`はdocker側で作られていて、`kompose up`はKubernetes側で作られているから、同じ目的で違う方向から作られたって感じなのかなー。

# 最後に
てな感じで、いろいろ寄り道してたら結構時間が経ってしまったので、Helmはまた今度。。
Docker で JupyterLab を起動し、token 入力なしでアクセスする

# JupyterLab を起動する方法

事前にカレントディレクトリ下に「workspace」という名前のディレクトリを作っておきます。ノートブックをホストとコンテナで共有するためです。

そのあと、次のコマンドでコンテナを起動します。

```shell
$ docker run --rm --name jupyter -d -p 8888:8888 \
    -v `pwd`/workspace:/workspace -w /workspace \
    continuumio/anaconda3 \
    jupyter-lab --no-browser --port=8888 --ip=0.0.0.0 \
    --allow-root --NotebookApp.token=''
```

この状態で http://localhost:8888 にアクセスすることで、token 入力なしで JupyterLab を利用できます。

![jupyter.png](https://qiita-image-store.s3.amazonaws.com/0/48133/b3065835-2ffb-0ca3-1018-4e80f764e13c.png)

アクセス時のカレントディレクトリが /workspace にセットされており、ホストのディレクトリとマッピングされています。

なお、解説欄で詳細を書きますが、**セキュアではない起動方法です**。そのため、他のユーザがアクセスできる環境で使用する場合はご注意ください。

# コンテナの終了

次のコマンドでコンテナを終了します。

```shell
$ docker kill jupyter
```

# 前提

上記手順は Docker for Mac で確認しました。
（恐らく他の Docker 環境でも同手順で対応できると思いますが未検証です）

# 解説

先ほどの起動コマンドのオプションを解説します。

### docker run のオプション

まずは、docker run のオプションから。

```shell
# コンテナ終了時にコンテナを削除します
--rm

# コンテナを jupyter という名前で起動します
--name jupyter

# バックグラウンドで起動
-d

# ホストの 8888 番ポートとコンテナの 8888 番ポートをマッピング
-p 8888:8888

# カレントの workspace ディレクトリとコンテナの /workspace ディレクトリをマッピング
-v `pwd`/workspace:/workspace

# /workspace をワーキングディレクトリに設定
-w /workspace

# イメージ continuumio/anaconda3 から起動。
# イメージがないときは pull してくれますが、イメージサイズが大きいので少々時間がかかります・・
continuumio/anaconda3
```

### JupyterLab のオプション

次に JupyterLab のオプションです。
JupyterLab を root で起動しており、ノートブックアクセス時のパスワードを無しにしています。よって、他ユーザのアクセスがない環境でご利用ください。

```shell
# ブラウザを起動しない
--no-browser

# ポート 8888 で起動
--port=8888

# サービスを IP アドレス 0.0.0.0 で LISTEN させる
# (この指定がないと、JupyterLab 起動時に例外が送出されて起動失敗します)
--ip=0.0.0.0

# root での実行は非推奨のため、このオプションをつけないと起動に失敗します
--allow-root

# Notebook アクセス時の token 文字列を設定できます。ここではパスワードなしにします。
--NotebookApp.token=''
```

token を設定する場合は、--NotebookApp.token='' オプションを外してください。
token 文字列は、コンテナ起動後に次のコマンドで確認できます。

```
$ docker logs jupyter
```

# 備考 - 無料で利用できる Jupyter Notebook

単に Jupyter Notebook を使用したいだけでしたら、無料のオンラインサービスもありますので、そちらの方が手軽かもしれません。例えば、Google の [Colaboratory](https://colab.research.google.com/notebooks/welcome.ipynb) というサービスがあります。


# 参考

[docker run](https://docs.docker.com/engine/reference/commandline/run/)
[Github:Run notebook without requesting for stupid token #2254](https://github.com/jupyter/notebook/issues/2254#issuecomment-345549234)
Vimの標準文字コードを設定する方法

## Vimの文字コードを設定する方法

```terminal
> echo "set encoding=utf-8" > ~/.vimrc ; source ~/.vimrc
```
※次回以降は自動的に設定される


環境変数の文字コードを設定する場合

```terminal
echo "export LANG=ja_JP.UTF-8" > ~/.bashrc ; sourch ~/.bashrc
```

その他含む設定全般

```vim:.bashrc
color_conf="dircolors.ansi-dark";
if [ -f ~/Library/dircolors-solarized-master/${color_conf} ]; then
    if type dircolors > /dev/null 2>&1; then
        eval $(dircolors ~/Library/dircolors-solarized-master/${color_conf})
    elif type gdircolors > /dev/null 2>&1; then
        eval $(gdircolors ~/Library/dircolors-solarized-master/${color_conf})
    fi
fi
alias ls='gls --color=auto'
alias lsa='gls -a --color=auto'
alias lsl='gls -l --color=auto'
alias lsla='gls -la --color=auto'
alias ll='gls -ltr --color=auto'
alias vi='vim'
export LANG=ja_JP.UTF-8
```
MongoDBの"No hostname or hostnames provided in connection string"エラーにハマったお話

# 問題発生
MongoDBもといMongooseでDBに接続しようとしたところ以下のようなエラーが出てきて接続ができなかった。
※MongoDBでもMongooseでもこの現象は起こります。

```
MongoParseError: No hostname or hostnames provided in connection string
```

# 解決
以下のように接続しようとしたが上記エラーになった。

```
var mongoose = require('mongoose');
mongoose.connect('mongodb:///localhost:27017/db_name');
```

これだけ見るとすぐ気づくと思われるが、ドメイン前の「/」が一個多かったのだ。
ものすごい初歩的なミスだがハマったのでメモとして残しておきます。
Unityでタイトルバーの文字列を動的に変更する

# はじめに
![image.png](https://qiita-image-store.s3.amazonaws.com/0/105021/26f57dd2-0494-638d-4560-0750ef19d289.png)
UnityでWindows用アプリを開発する場合、タイトルバーに表示されるのはPlayerSettingsのProduct Nameになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/105021/9737b33e-f8bc-7eb8-36a3-ebb05592a36e.png)

タイトルバーにバージョン番号などを表示させたい場合は、その都度Product Nameを書き換えることになります。
しかし、UnityのProduct Nameは[Player Prefs](https://docs.unity3d.com/ja/current/ScriptReference/PlayerPrefs.html)の保存先を決める役割を持っているため
バージョンごとに変更していると、Player Prefsに保存されているデータもその都度吹っ飛んでしまいます。
セーブデータをPlayer Prefsに保存しているようなゲームではタイトルバーの文字を気軽に変えられなくなってしまいます。

そこで、Product Nameを変えずにタイトルバーに表示される文字列を変更する方法を紹介します。

# ソースコード
いきなりソースコードです

```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;

public class TitleBarSample : MonoBehaviour 
{
//Windowsのみに限定
#if UNITY_STANDALONE_WIN
        [DllImport("user32.dll", EntryPoint = "SetWindowText")]
        public static extern bool SetWindowText(System.IntPtr hwnd, System.String lpString);
        [DllImport("user32.dll", EntryPoint = "FindWindow")]
        public static extern System.IntPtr FindWindow(System.String className, System.String windowName);
        private void Start()
        {
			//Product NameのWindowを探す
            var windowPtr = FindWindow(null, Application.productName);
			//名前をセットする
			SetWindowText(windowPtr, "newName");
        }
#endif
}

```
↑のコンポーネントを適当なGameObjectにAddComponentしてビルドすると・・・
![image.png](https://qiita-image-store.s3.amazonaws.com/0/105021/401c35a3-f037-3578-d93a-34812b446840.png)
Product Nameを変更することなくタイトルバーを変更することができました。
処理としてはWindowsのAPIを直接叩いてタイトルバーの内容を変更しています。

# 応用
上の例だと1回しか書き換えていないので、実行中ずっと書き換え出来るようにします。

```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;

public class TitleBarSetter : MonoBehaviour 
{
	static TitleBarSetter instance = null;

	public static TitleBarSetter Instance { get { return instance;} }

//Windowsのみに限定
#if UNITY_STANDALONE_WIN
	[DllImport("user32.dll", EntryPoint = "SetWindowText")]
	public static extern bool SetWindowText(System.IntPtr hwnd, System.String lpString);
	[DllImport("user32.dll", EntryPoint = "FindWindow")]
	public static extern System.IntPtr FindWindow(System.String className, System.String windowName);
	
	System.IntPtr hWnd;
	private void Start()
	{
		instance = this;
		DontDestroyOnLoad(this.gameObject);

		//Product NameのWindowを探す
		hWnd = FindWindow(null, Application.productName);
	}
#endif

	public void SetTitleBar(string text)
	{
#if UNITY_STANDALONE_WIN
		SetWindowText(hWnd, text);
#endif
	}
}
```

↑のコンポーネントを適当なGameObjectにAddComponentして
別のスクリプトからタイトルバーを更新したいタイミングで呼び出します

```c#
TitleBarSetter.Instance.SetTitleBar("表示したい文字列");
```

↓こんな風にFPS表示に使うこともできます。
![fps2.gif](https://qiita-image-store.s3.amazonaws.com/0/105021/a7ee494d-e99d-02f6-2bba-b4bfcb727b28.gif)
他にはゲームの進行状況を表示したり、時刻を表示したり応用がいろいろ効きます。
Raspberry Piで温度記録Webサーバを作る

## 準備するもの
- Raspberry Pi 3 Model B+ あるいはRaspberry Pi Zero
- ACケーブル
- Bosch BME280 気温・湿度・気圧センサ（千石電商で購入）
- ジャンパピン　メス-メス 4本
- USB接続キーボード
- Raspbian OSインストール用のMicroSDカード（今回は32GBのものを利用しました）

### Raspberry Pi Zeroで動かすなら、更に下記を準備
- USB接続の無線LANドングルとUSB On-The-Goケーブル（Raspberry Pi Zero WかWHを買えば不要です）
- HDMI変換コネクタ

## Raspbian Liteのインストール、初期設定
- PCで[Noobs](https://www.raspberrypi.org/downloads/noobs/)をダウンロードし、ZIPファイルの内容をFAT32フォーマットされたMicroSDカードにコピーします。
- MicroSDカードを挿入して起動します
- Raspbian Liteをインストール
- Wi-FiのSSIDとパスワードも登録しておくと楽です
- 再起動後、user:pi, password:raspberryでログイン

```bash
% sudo raspi-config
```

- hostnameを設定
- SSHサーバを起動
- timezoneを設定
- ユーザpiのパスワードを変更

これ以降、sshによるリモートログインで作業を続行できます。

## Apache2とMuninのインストール
```bash
# apt update && apt upgrade
# apt install apache2 munin i2c-tools python-smbus
# ln -s /etc/munin/apache.conf /etc/apache2/sites-enabled/munin.conf
```
### Munin動作設定
```bash:/etc/munin/apache.conf
18c18,20
<         Allow from localhost 127.0.0.0/8 ::1
---
>         Allow from all
>       Require all granted
>       Allow from localhost 127.0.0.0/8 ::1
```

### BME280の動作設定
Raspberry PiのGPIOとセンサを接続します。
Vcc - Pin01(3.3V DC)
SDA - Pin03(I2C Data)
SCK - Pin05(I2C Clock)
GND - Pin06(GND)
※スイッチサイエンス社のBME280の場合、SDOをPin09(GND)に落とします。

### センサの認識状態を確認する

```bash
# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- 76 --
```

BME280のセンサが0x76にて認識されていることを確認できました。

次に、[スイッチサイエンス社のWebサイト](https://github.com/SWITCHSCIENCE/BME280/tree/master/Python27)から、サンプルコードをダウンロードします。ファイル冒頭のSMbus2は、SMbusに書き換えておきます。

```bash
$ python bme280_sample.py
temp : 23.37  ℃
pressure : 1015.26 hPa
hum :  52.59 ％
```
無事、センサから情報を取得できました。

### Muninのプラグイン
[こちらのサイト](http://non2nrp.blogspot.com/2015/10/bme280.html)を全面的に参考にさせていただきました。なので、Muninプラグインについてはあまり書くことがありません。すみません。
ちなみに、スイッチサイエンス社のサンプルコードでは、UTF-8で単位がつけられていますが、Muninにわたす場合には単位を付けずに浮動小数点の値をそのまま出力させてやります。

## おまけ：IFTTTでGoogle Spreadsheetに出力させる
温度取得のスクリプトに少し手を加えます。IFTTTのWebhookによりPOSTしたデータをGoogle Spreadsheetに格納させるスクリプトにします。動作にはurllib3が必要ですので、aptでpython-urllib3をインストールしておきます。特にpipなどを入れる必要はありませんでした。

```bash
  url ="https://maker.ifttt.com/trigger/（イベント名）/with/key/（取得したKEY）"
  method = "POST"
  headers = {"Content-Type" : "application/json"}
  obj = {"value1" : result_temperature, "value2" : result_humidity, "value3" : result_pressure}
  json_data = json.dumps(obj).encode("utf-8")
  http = urllib3.PoolManager()
  r = http.request(
    'POST',
    url,
    body = json_data,
    headers = headers)
```
## おまけ２：Twitterに投稿する
（作成中）

## 終わりに
念の為、1日毎にリブートするようにします。

```bash
% sudo crontab -e 
01 5 * * * /sbin/reboot
```

## Raspberry Pi OS更新にあわせて
- print文の引数に()をつける必要があります。
- apt install python3-smbus でPython3用のSMBUSを追加インストールします
ReactとReduxを利用した開発環境をwebpack4とbabelで用意する

検証用のサンドボックスを手元で簡単に立ち上げるとき使っているサンプルをアップデートする。[以前書いたメモ](https://qiita.com/ma2saka/items/5b88387c7decebe9e925)が webpack-serve の失速によりちょっと残念な感じなので。なお typescript で似たような感じなのは[こちら](https://qiita.com/ma2saka/items/5def17634ce226d75f36)。

```
npm init -y
npm install --save react react-dom redux react-redux
npm install --save-dev webpack webpack-cli webpack-dev-server
npm install --save-dev @babel/preset-env @babel/cli @babel/core @babel/preset-react
npm install --save-dev babel-loader style-loader css-loader html-webpack-plugin
npm install --save-dev @babel/plugin-proposal-class-properties
```

## babel.config.js

class-properties は

```
module.exports = {
  presets: [
    "@babel/preset-env",
    "@babel/preset-react"
  ],
  plugins: ["@babel/plugin-proposal-class-properties"]
}
```

## webpack.config.js

```
const path = require('path')
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    mode: process.env.WEBPACK_SERVE ? 'development' : 'production',
    entry: {
      main: path.resolve(__dirname, './src/', "index.js")
    },
    output: {
        path: path.resolve(__dirname, './dist/'),
        publicPath: '/',
        filename: '[name]-[hash].js'
    },
    module: {
      rules: [
      {
        test: /\.jsx?$/,
        exclude:[ /node_modules/ ],
        loader: 'babel-loader'
      },
      {
        test: /\.css$/,
        exclude: [/node_modules/],
        use: ["style-loader", { loader: "css-loader", options: { url: false, modules: true } }]
      }]
    },
    devtool: 'source-map',
    devServer: {
       contentBase: path.join(__dirname, "public"),
       watchContentBase: true,
       open: true
    },
    plugins: [new HtmlWebpackPlugin({ template: "src/index.html" })]
}
```

## src/

```
mkdir src
```

## src/index.js

redux アプリとしてはだいぶ最小構成くらい。

```
import React from "react";
import { render } from "react-dom";
import { connect, Provider } from 'react-redux';
import { createStore } from 'redux';

const initialState = { message: "hello redux." }
const store = createStore(
  (state = initialState) =>({ ...state }), initialState
);

const App = (props) => (<div>{props.message}</div>)

const ReduxApp = connect((state) => ({ message: state.message }))(App)

render(<Provider store={store}><ReduxApp /></Provider>, document.getElementById("content"));

```

## src/index.html


```
<div id="content"/>
```

## 起動

```
npx webpack-dev-server --mode development --open
```

## 余談

こんな小さい構成でも、production 設定で起動すると、バンドルサイズ大きすぎるぞと警告を出してくる。

```
WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
Entrypoints:
  main (266 KiB)
      main-edda3e4c88bd69be072f.js
```
深さ優先探索を実装してみる。

基礎中の基礎ですが、せっかく実装したので。

#深さ優先探索とはなんぞや
進めるところまで進んで、行き止まったら直前の分かれ道に戻り他の道を模索するという、探索アルゴリズムの初歩となります。

#深さ優先探索は何に使えるのか
行ける場所全てを探索するという性質上、**ある地点とある地点がつながっているかを判定することができます。**
また、ゴールにたどり着かなかった場合は、取りうる全ての間を途中で試すという関係上、全状態の列挙にも使えたりします。

ただし、深さ優先探索によって見つかったルートが最短とは限りません(地図を見ずに行き当たりばったりで目的地に歩いていくルートが最短とは限らないのと同じです。)

#深さ優先探索はどう実装するのか。
主に2つの方法があります。スタックを利用する方法と再帰関数を利用する方法です。このうち、再帰関数を使った実装は(なれれば)簡単にかけるので、**再帰関数で簡単に実装できることが深さ優先探索の利点の一つとなっています。**

※スタックとは
先に入れたものほど、あとに取り出されるデータ構造です。ものを積み上げておいて、取るときは上からとるイメージです。(stack自体に積み上げるの意味があります。)

*再帰関数とは
その関数の中で自分自身をよんで繰り返し処理をさせるような関数です。

#実際の実装

以下のような道を探索していきます。このようにどの頂点がどこにつながっているかを表したリストを頂点隣接リストとよんだりします(今回上から下の道のみを考えています。)

```.cpp
std::vector<std::vector<int>> tree = {{1,2},{3,4},{4,10},{},{5,6},{7},{8,9},{},{},{},{};

//                 0
//               /   |
//              1    2
//             /  \ / |
//            3    4   10
//               /  |    |
//              5   6    |
//             /   / |  /
//            7   8   9
//
```

## 再帰関数

```.cpp
bool dfs_func(int state, int goal){
  if (state==goal){
    return true;
  }
  for (auto next:tree[state]){
    if (dfs_func(next,goal) == true){
      return true;
    };
  }
  return false;
}
```

自分のいる場所がゴールかどうか判断し、もし違った場合はつながってる道に対して判断することを繰り返して行きます。もし、途中でゴールに行き着いた場合、trueがどんどん連鎖的に返ってきて最終的に大本の関数がtrueになるような構造になっています。

## stack

```.cpp
bool dfs_stack(int start, int goal){
  std::vector<int> stack;
  stack.push_back(start);
  bool is_goal=false; 
  while(!stack.empty()){
    int now = stack.back();
    stack.pop_back();
    for (int next:tree[now]){
      stack.push_back(next);
      if (next == goal){
        is_goal = true;
        break;
      }
    }
    if(is_goal){break;}
  }
  return is_goal;
}
```

stackでの実装です。つながっている頂点をstackに入れきって、stackの一番上を見てgoalか判定することを繰り返します。しかし、こちらは少々トリッキーな実装になっており、stackの一番上をみて隣接頂点をstackに積む前にstackから一番上を取り出してしまっています。これをしないと、どこまでいってもgoalにいきつかなかったときの判定が面倒になります。

## 再帰関数(通った道を表示)

```.cpp
bool dfs_func_root(int state, int goal){
    if (state==goal){
      std::cout << state;
    return true;
  }
  for (auto next:tree[state]){
    if (dfs_func_root(next,goal) == true){
      std::cout << state;
      return true;
    };
  }
  return false;
}
```

再帰関数で、通った道を表示するのは簡単で、trueを返すたびに今いる場所も一緒に捉えればよいです。
stackの実装で道順を表示するのは自分が思いついた限りでは結構面倒な方法しかなく、今回は諦めました。


#上記のコードのテスト

```.cpp
int main (void){
  int s,g;
  std::cin >> s >> g;
  std::cout << "stack ver" << std::endl;
  show_res(dfs_stack(s,g));
  std::cout << "func ver" << std::endl;
  show_res(dfs_func(s,g));
  std::cout << "root ver" << std::endl;
  dfs_func_root(s,g);
  std::cout << std::endl;
}
```

```
0 9
stack ver
true
func ver
true
root ver
96410

0 20
stack ver
false
func ver
false
root ver
```

この通り、場合によっては遠回りをしてしまっていますし、つながっていない場合にはつながっていないことがわかります。

#おわりに
今までずっとstackの方で実装してたのですが、再帰で実装したら思ったより楽だったので今度からこっちで実装しようと思っています。