OmniAICreator/Qiita-1.07M huggingface dataset:
MATLAB > 手順 > 3次元データを可視化 | 複数の結果を比較表示

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04.4 LTS desktop amd64
TensorFlow v1.7.0
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
gnustep-gui-runtime v0.24.0-3.1
PyMieScatt v1.7.0
```

### 処理概要

- x,y,zの座標値を読込む
- 3D表示する
    - マウスでviewing directionを変更できるように

### 参考

https://jp.mathworks.com/matlabcentral/answers/247689-how-can-i-plot-x-y-z-coordinates

### データ

```shell-session
$ head matlabx.out
0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.17536733E+00 0.23226991E+00 0.10276314E-16 0.10276314E-16 -.20934324E+00 -.16312109E+00 -.16312109E+00 -.23666834E+00 -.31929038E-16 -.31929038E-16 0.23245306E+00 0.17536733E+00 0.33663496E+00 0.40839916E+00 0.23226991E+00 0.21858906E+00 0.18862306E-16 0.18862306E-16 -.19882824E+00 -.20934324E+00 -.35089117E+00 -.30080166E+00 -.30080166E+00 -.41640760E+00 -.23666834E+00 -.25940337E+00 -.62403703E-16 -.62403703E-16 0.22289327E+00 0.23245306E+00 0.39509753E+00 0.33663496E+00 0.47950224E+00 0.56979045E+00 0.40839916E+00 0.40328764E+00 0.21858906E+00 0.19217304E+00 0.24569526E-16 0.24569526E-16 -.17257152E+00 -.19882824E+00 -.34605412E+00 -.35089117E+00 -.47538725E+00 
...
```

上記のような座標値xがある。
同様にmatlaby.outとmatlabz.outがある。

### 手順

```matlab
trix = load('matlabx.out');
triy = load('matlaby.out');
triz = load('matlabz.out');
plot3(trix, triy, triz, 'o')
```

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/5eabb494-3ed8-1a3f-3774-343deeb16acf.png)

viewing directionを変更できる。

### スクリプト

スクリプトにして再生ボタンで実行すると、別の形状を確認しやすい。

スクリプトの作成
https://jp.mathworks.com/help/matlab/matlab_prog/create-scripts.html

```view_siris_matlabout_180414.m
trix = load('matlabx.out');
triy = load('matlaby.out');
triz = load('matlabz.out');
plot3(trix, triy, triz, 'o')
```

### 複数の結果の比較

Figureウィンドウには「保存」機能がある。
この機能を利用して、複数の結果を比較できる。

1. Figureウィンドウで保存 (例: `180414_t1025.fig`)
2. 次のデータを`plot3()`などで表示
3. ファイル > 開く にて手順１のファイルを開く
    - 新しいFigureウィンドウで表示される

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/2ece1ba2-d46a-2bba-5e72-45bc56d28f98.png)

- カーソル上下: zenith angle (viewing angle)の変更
- カーソル左右: azimuth angleの変更
- マウス右クリック > 元の表示にリセット > zenith, azimuth angleが初期化される
ネットワーク機器の情報をtelnetで取得する。

# はじめに
スクリプトを使ってネットワーク機器をhogehogeすることが流行っていますが、プログラミングができないネットワーク管理者でも簡単に使えるものを作りました。
記述したコマンドを順番に実行し、その結果を標準出力とホスト名.txtというファイルに出力します。

#動作を確認したサーバー環境
- Ubuntu 16.04.4
- Perl 5.22.1
    - Net::Telnetモジュールが必要です。

#動作を確認したネットワーク機器
- Alaxala AX2430S、AX2530S
- NEC QXシリーズ

#ちょっとしたコツ
多くのネットワーク機器のデフォルトの状態ではshowコマンドを実行するとページャーが動作します。ページャーが動作するとスペースキーなどを押さないと先に進めない状態になるので、スクリプトで何かを行うときには不向きです。スクリプトで何かを行うときは**ページャーを必ず無効**にしましょう。
各ネットワーク機器でページャーを無効にするコマンドは以下の通りです。

- Alaxala：set terminal pager disable
- NEC QXシリーズ：screen-length disable

#使い方
この例ではAlaxalaのスイッチに自動的にログインし、以下のコマンドを順番に実行します。これらのコマンドは管理者に昇格(enable)しなくても実行できます。管理者でしか実行できないコマンドをスクリプトで実行する例はまた別の機会に...(^^;;;

1. set terminal pager disable
2. show port
3. show port vlan
4. show vlan

実行時には引数でホスト名、もしくはIPアドレスを指定します。

./nw-command.pl <ホスト名>

#スクリプト

```perl:nw-command.pl
#!/usr/bin/perl

use strict;
use Net::Telnet;

my $host = $ARGV[0];
my $user = 'myuser';
my $pass = 'mypassword';
my $prompt = '/>.*$/';
my $log = $host .".txt";

my @comm = (
        "set terminal pager disable",
        "show port",
        "show port vlan",
        "show vlan"
);

my $telnet = new Net::Telnet(
    Timeout => 10,
    Prompt => $prompt,
    Input_log => $log,
    );

$telnet->open($host);

$telnet->login($user, $pass);

my $result;
foreach my $line(@comm){
        $telnet->print($line);
        ($result) = $telnet->waitfor($prompt);
        print $result;
}

$telnet->print("quit");

$telnet->close;
```

#実行例
実行結果は標準出力とログファイルに出力されます。

```text
login: myuser
Password:

Copyright (c) 2005-2016 ALAXALA Networks Corporation. All rights reserved.

olexala> set terminal pager disable
olexala> show port
Date 2018/04/14 09:38:13 JST
Port Counts: 48
Port  Name           Status   Speed           Duplex     FCtl FrLen ChGr/Status
 0/ 1 geth0/1        up       1000BASE-T      full(auto) off   9234   -/-
 0/ 2 geth0/2        up       1000BASE-T      full(auto) off   9234   -/-
：
<中略>
：
 0/47 geth0/47       dis      -               -          -     -      -/-
 0/48 geth0/48       dis      -               -          -     -      -/-
olexala> show port vlan
Date 2018/04/14 09:38:13 JST
Port Counts: 48
Port  Name           Status Type        VLAN
 0/ 1 geth0/1        up     Access      100 (VLAN0100)
 0/ 2 geth0/2        up     Access      100 (VLAN0100)
：
<中略>
：
 0/47 geth0/47       dis    Access      111 (VLAN0111)
 0/48 geth0/48       dis    Access      111 (VLAN0111)
olexala> show vlan
Date 2018/04/14 09:38:14 JST
VLAN counts:4
VLAN ID:1     Type:Port based      Status:Disable
  Learning:On            Tag-Translation:
  BPDU Forwarding:       EAPOL Forwarding:
  Router Interface Name:VLAN0001
：
<中略>
：
  Description:VLAN0834
  Spanning Tree:
  AXRP RING ID:      AXRP VLAN group:
  GSRP ID:      GSRP VLAN group:
  IGMP snooping:     MLD snooping:
olexala>
```

# NEC QXシリーズの場合
コマンドの記述部分を変えれば、基本的に動きます。
ServiceNowで回帰テストを作成し定期実行の設定を行う

# 概要

[ServiceNowでBusinessRuleをテストする
](https://qiita.com/sukkyxp/items/1136c15c9fd26d7c0089)で作成したテストを定期的に実行する設定を行う。回帰テストとは、一度作成したプログラムをメンテナンス時に、メンテナンスした箇所以外の動作が、メンテナンスによる修正前と修正後で動作が変わらないことを確認するために実施する。全てのソースに対して回帰テストがあれば、メンテナンスによるソース修正の思わぬデグレードを防げる。
## 環境
ServiceNow:KINGSTONE

## TEST Suiteの作成
回帰テストは、TEST単体ではなく、複数のテストをまとめて行うTEST Suiteを指定して実施するため、TEST Suiteをあらかじめ作成しておく。
TEST Suiteの作成にはStudioではなく、ServiceNowのアプリケーションブラウザーのナビゲターから「Automated Test Framework」の「Suites」を選択して行う。
Newをクリックすると、設定画面が表示されうのでまずはNameに適当に名前を入れて保存する。そうすると画面の下部に「Test Suites Tests」のリストが表示される。

![TestSuite.png](https://qiita-image-store.s3.amazonaws.com/0/197947/b0d52ea3-fd3f-7de3-babb-340d4a24e0d6.png)

このリストの「New」をクリックするのではなく、「Insert a new row...」となっている部分をクリックする。入力可能な状態となり虫眼鏡のアイコンが表示されるのでくりっくしてTESTを選択する。ここで選択したテストがTEST Suiteの実行時に連続して実行される。

![TestSuiteSetting.png](https://qiita-image-store.s3.amazonaws.com/0/197947/d2938889-ee77-8722-dad0-7c3614917cc2.png)


## 自動実行スケジュールの設定

次に「Automated Test Framework」カテゴリの「Schedules」を選択し、表示された設定画面でまずはNameを入力して保存する。

![SuiteSchedule.png](https://qiita-image-store.s3.amazonaws.com/0/197947/d2e69b28-5052-17b2-0ae1-11b616a928a2.png)

「Insert a new row...」をクリックして行を入力可能な状態にし、虫眼鏡アイコンをクリックし、Test Suiteを選択する。
今回はRun(実行スケジュールの設定）に「Periodically」を設定し時間間隔を１分としている。毎日定時に実行などのスケジュールも設定可能だ。
（注意：１秒おきなどに実行のスケジュールを設定するのは、システムに過負荷をかける恐れがあるので、短かすぎる間隔を設定しないこと）

![SuiteScheduleSetting.png](https://qiita-image-store.s3.amazonaws.com/0/197947/bc6f2da1-98fe-3fd7-f6a7-a791db2fb25b.png)

## 実行結果の確認

SuiteScheduleを保存すると、スケジュールされたテストが自動実行されている。
Automated Test Resultsの「Suite Result」をクリックして確認しよう。

![TestLog.png](https://qiita-image-store.s3.amazonaws.com/0/197947/98c456b3-7f99-8a95-a8fe-e5a837261d2d.png)

テストが１分おきに実行されていることが分かる。
実際に１分ごとにテストすることはないが、ここでは実行結果を早く得るために１分間隔で設定した。

スケジュールの設定としては「Periodically」の他に「Daily」「Monthly」「Weekly」「Once」「On Demand」が選択可能だ。
ISUCON7の予選問題で使うUbuntu 16.04がThe box 'bento/ubuntu-16.04' could not be foundとなる時の対応

[ISUCON7の予選問題](https://github.com/isucon/isucon7-qualify)に沿って環境を作ろうとした際に、Ubuntu 16.04の環境構築でエラーが出たのでそれについて調べた内容のまとめ

## エラー内容
[Vagrant に VirtualBox 用の Ubuntu 16.04 LTS の box を入れる方法](https://obel.hatenablog.jp/entry/20161029/1477706066)を参考にコマンドを実行したところ下記のエラーが出た
タイトルにあるように、could not be foundとなっている

```
$ vagrant init bento/ubuntu-16.04
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'bento/ubuntu-16.04' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
The box 'bento/ubuntu-16.04' could not be found or
could not be accessed in the remote catalog. If this is a private
box on HashiCorp's Atlas, please verify you're logged in via
`vagrant login`. Also, please double-check the name. The expanded
URL and error message are shown below:

URL: ["https://atlas.hashicorp.com/bento/ubuntu-16.04"]
Error: The requested URL returned error: 404 Not Found

```

## 原因

いくつか調べてみたところ、下記の記事にこのような記載が
> The Trellis docs say that “Vagrant >= 1.8.5” is required

[“The box ‘bento/ubuntu-16.04’ could not be found” error when spinning up a new Trellis project](https://grantnorwood.com/box-bento-ubuntu-16-04-not-found/)

バージョンを確認してみたら低かったので、これが問題らしい

```
$ vagrant -v
Vagrant 1.7.4
```

## 対応
[Mac で vagrant をバージョンアップする](https://qiita.com/satoshi_iwashita/items/7791b9e2c64dd660a13d)を参考に一番新しいバージョンに変更

```
$ vagrant -v
Vagrant 2.0.3
$ vagrant plugin repair
```

これでできるようになりました

```
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'bento/ubuntu-16.04'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'bento/ubuntu-16.04' is up to date...
==> default: Setting the name of the VM: isucon_default_1523664078122_50761
==> default: Fixed port collision for 22 => 2222. Now on port 2201.
```

(追記)
isucon7の環境を作る場合には[allinone (ALL in One) 用 Playbook](https://github.com/isucon/isucon7-qualify/tree/master/provisioning/allinone)があるので、こちらで作成をすると楽です
Geometry > Link > Gaussian random sphere > 手法とコードへのリンク

Gaussian Random Sphereという球形状に凹凸を加える手法とコードへのリンク。

### SIRIS

https://wiki.helsinki.fi/display/PSR/SIRIS

Fortranコード。
SIRISのパッケージ内にG-sphere/がある。

- 環境
    - スクリプトがtcshのShebangになっている
    - 実行内容を見るとbash Shebangに変更して、nice +2を取ることで実行可能
    - g77は適宜f77に変更

### How can I coded Gaussian random sphere model in Matlab?

https://www.researchgate.net/post/How_can_I_coded_Gaussian_random_sphere_model_in_Matlab

Hilam AlquranによるPDFにてequationが紹介されている。

### Examples of Gaussian random spheres

論文のFig. 1.に形状例がある。
https://www.researchgate.net/figure/Examples-of-Gaussian-random-spheres-with-fixed-r-0-175-m-a-c-Gaussian-spheres_fig1_3409990


### Light scattering by atmospheric mineral dust particles

論文のFig 9.に形状例がある。
論文はfull-text PDFが取得可能。

https://www.researchgate.net/figure/Complex-particle-shapes-adapted-in-light-scattering-considerations-Gaussian-random_fig5_268153980

下記の形状も扱っている。

- random blocks
- deformed spheroids
- deformed aggregates
- concave fractal polyhedra
- spatial Poisson-Voronoi tessellation
- agglomerated debris particles
- irregular flakes
- irregular rhombohedra
- inhomogeneous stereogrammetric sphaes

(Note: 下記の太字は強調のため)
> Homogeneous, isotoropic models
> ...
> , but one notable exception is the Gaussian random sphere (GRS) geometry by **[106]**, which is a stocastic geometry based on deforming a sphere by a series expansion of spherical harmonics in a statistically controlled way. The statistical shape is defined by **the covariance function** of radius or logradius, from which individual particles are obtained by randomizing the weights of the spherical harmonics expansion, **following** the statistics set by the covariance function.

...
> `106. K. Muinonen, T. Nousiainen, P. Fast, K. Lumme, J.I. Pletoneimi (1996). Light scattering by Gaussian random particles: Ray optics approximation. J. Quant. Spectorsc. Radiat. Transfer, 55, 577-601. [[link](https://www.sciencedirect.com/science/article/pii/0022407396000039)]

### how to generate new points as offset with gaussian distribution for some points in spherical coordinates in python

下記はGaussian distributionを使用しているが、形状生成の点ではGaussian random sphereとは異なるかもしれない（未確認)。

https://stackoverflow.com/questions/22439193/how-to-generate-new-points-as-offset-with-gaussian-distribution-for-some-points


### Qiita link

- [geometry > 論文 > 六角柱の表面のざらつきを考慮した形状モデル > Gaussian random surface | ADDAによる粒子の散乱特性](https://qiita.com/7of9/items/54602e3219ac1ff45a95)
お手軽にデータ処理を高速化するライブラリ

# はじめに

この記事では、機械学習などで膨大なデータ処理する際、
お手軽に高速化するための、便利なライブラリについてまとめます。


なお、機械学習などでは、numpy, pandasを使うことが多いと思います。
ここでは書きませんが、これらは書き方次第で高速化が可能です。

もしデータ処理に時間がかかっているなら、
**先にnumpy, pandasの書き方を
見直すべきです。というより、見直さないと、便利なライブラリを使っても、満足いく結果が得られないと思います。**


# ライブラリ

## メモ化

関数の入力と戻り値の対応をメモリに保存し、処理を高速化します。

### [functools.lru_cache](https://docs.python.jp/3/library/functools.html)

計算を行う関数calcを何度も実行します。

``` python
import time
import random

def calc(x):
    y = 0
    for _ in range(100):
        y += x + x^2
    return y

# 実行
s = time.time()
for _ in range(10000):
    calc(random.randint(0, 10))
print(time.time() - s)
```

この関数calcにfunctools.lru_cacheというデコレータを付与するだけで、メモ化できます。

``` python
import time
import random
from functools import lru_cache

@lru_cache(maxsize=1024)
def calc(x):
    y = 0
    for _ in range(100):
        y += x + x^2
    return y

s = time.time()

# 実行
for _ in range(10000):
    calc(random.randint(0, 10))

print(time.time() - s)

print(calc.cache_info()) # cache状況の表示
calc.cache_clear()       # cacheのクリア
print(calc.cache_info()) # cacheの状況の表示
```

この処理では、おおよそ、5倍程度早くなります。

- 不要になったらcacheをクリアしておきましょう。
- maxsizeは、直近の呼び出しをどこまで記録するかです。Noneの場合は無制限なので注意。2の累乗が好ましいらしい。


## numpyの実行を高速化

### [numba.jit](https://numba.pydata.org/)

PythonのコードをJIT(just-in-time)コンパイルすることで高速化します。

numpyの計算calcを実行します。あえて、forを回す必要がある処理にしておきます。

``` python
import numpy as np
import time

def calc(arr):
    result = 0
    for i in range(arr.shape[0]):
        for j in range(arr.shape[1]):
            result += arr[i, j]
    return result

s = time.time()
calc(np.random.rand(10000, 1000))
print(time.time() - s)
```

この関数calcにnumba.jitというデコレータを付与するだけで、jitコンパイルされます。

``` python
import numpy as np
import time
from numba import jit

@jit
def calc(arr):
    result = 0
    for i in range(arr.shape[0]):
        for j in range(arr.shape[1]):
            result += arr[i, j]
    return result

s = time.time()
calc(np.random.rand(10000, 1000))
print(time.time() - s)
```

この処理では、おおよそ、10倍程度早くなります。

- pandasは無効なので、一旦numpyにして使いましょう。

## 並列処理

複数のcpuで並列処理を行うことで高速化します。

### [joblib.Parallel](https://pythonhosted.org/joblib/generated/joblib.Parallel.html)

``` python
import numpy as np
import time

def sleep(arr):
    for _ in range(arr.shape[0]):    
        time.sleep(0.01)
    return arr

s = time.time()
sleep(np.random.rand(100, 10000))
print(time.time() - s)
```

引数を並列数に応じて分割した上で、それぞれを並列処理します。

``` python
import numpy as np
from joblib import Parallel, delayed, cpu_count
import time

def sleep(arr):
    for _ in range(arr.shape[0]):    
        time.sleep(0.01)
    print(arr.shape)
    return arr

def split_arr(arr, n):
    for _arr in np.array_split(arr, n):
        yield _arr

s = time.time()

cpus = cpu_count()
print(cpus)

results = Parallel(n_jobs=cpus)(
    [delayed(sleep)(x) for x in split_arr(np.random.rand(100, 10000), cpus)]
)

y = np.vstack(results)
print(y.shape)
print(time.time() - s)
```

この処理では、cpuを4つ使っており、おおよそ、4倍程度早くなります。


# 以上
他に何か見つかったら追加していこうと思います。
kerasでConv2DTranspose

#概要
kerasのConv2DTransposeを理解したかった。
autoencoder書いてみた。


#写真

![auto13.png](https://qiita-image-store.s3.amazonaws.com/0/18104/5e4fc211-c8d4-9d84-8d25-93c97c0dfce1.png)


#サンプルコード


```
from tensorflow.contrib.keras.python.keras.models import Model
from tensorflow.contrib.keras.python.keras.datasets import mnist
from tensorflow.contrib.keras.python.keras.layers.convolutional import Conv2D, Conv2DTranspose
from tensorflow.contrib.keras.python.keras.models import Sequential
import numpy as np
import matplotlib.pyplot as plt

(x_train, _), (x_test, _) = mnist.load_data()
x_train = x_train.reshape(-1, 28, 28, 1).astype('float32') / 255.
x_test = x_test.reshape(-1, 28, 28, 1).astype('float32') / 255.

input_shape = (28, 28, 1)
model = Sequential()
model.add(Conv2D(filters = 8, kernel_size = (3, 3), strides = (1, 1), padding = 'same', activation = 'relu', input_shape = input_shape))
model.add(Conv2DTranspose(filters = 1, kernel_size = (3, 3), strides = (1, 1), padding = 'same', activation = 'relu'))
model.summary()
model.compile(optimizer = 'adadelta', loss = 'binary_crossentropy')
model.fit(x_train, x_train, epochs = 1, batch_size = 256, shuffle = True, validation_data = (x_test, x_test))
decoded_imgs = model.predict(x_test)

n = 10
plt.figure(figsize = (20, 4))
for i in range(n):
	ax = plt.subplot(2, n, i + 1)
	plt.imshow(x_test[i].reshape(28, 28))
	ax = plt.subplot(2, n, i + 1 + n)
	plt.imshow(decoded_imgs[i].reshape(28, 28))
plt.savefig("auto13.png")
plt.show()



```

以上。
続・SkyWay IoT SDKでのカスタム遠隔監視カメラ

# これは何？

以前書いた https://qiita.com/komasshu/items/5042c1e18eb4589b977a の続編。[SkyWay IoT SDK](https://github.com/nttcom/skyway-iot-sdk) がv0.1.0にあがって、使い方が若干変わったのでそれのイントロ

# 構成

全体構成はこんな感じ。グローバルなリレーサーバー使わなくても、宅内のカメラや MQTT 話すIoTデバイスをリモートからあれこれできるようになる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/83466/b8483af4-e5b4-a85d-797a-558810a1d197.png)

宅内の Linux Box（ラズパイとか）の中で以下が稼働。

* [gstreamer](https://gstreamer.freedesktop.org/)
    * 外部カメラ映像からRTPストリームを生成
* [Janus-gateway](https://janus.conf.meetecho.com/)
    * WebRTC ゲートウェイ。RTP映像ストリームや各種データをWebRTCに変換してくれる便利な子
* SSG
    * SkyWay Signaling Gateway。Janus-gatewayだけだと、NATとか越えてくれないので、SSGでSkyWayとのシグナリング変換処理をしてグローバルアクセス可能にする。今回からMQTT Relay over WebRTC の機能もつけたので、宅内MQTT機器の制御が、リレーサーバー（グローバルなMQTTブローカー）なしで簡単に実現できるようになった。

# SkyWay APIKEYの取得

ここについては、[前回記事](https://qiita.com/komasshu/items/5042c1e18eb4589b977a#apikey%E3%81%AE%E5%8F%96%E5%BE%97)を参照ください。

# SDKインストール

以下のインストーラーを動かすだけ

* Raspbian stretchの場合

```bash
$ curl https://nttcom.github.io/skyway-iot-sdk/install_scripts/raspbian_stretch/installer.sh | sudo -E bash -
$ ssg setup # プロンプト表示されたら、上記で取得したAPIKEYを入力する
```

* Ubuntu 16.04の場合

```bash
$ curl https://nttcom.github.io/skyway-iot-sdk/install_scripts/debian_based/installer.sh | sudo -E bash -
$ ssg setup # プロンプト表示されたら、上記で取得したAPIKEYを入力する
```

# プロセス起動

Janus gateway と SSG を動かす

* Janus gateway

```bash
$ /opt/janus/bin/janus
```

* SSG

```bash
$ ssg start
```

# gstreamerを起動する

USBカメラの映像から RTP/H.264ストリームを生成

```bash
$ gst-launch-1.0 v4l2src device=/dev/video0 ! \
  video/x-raw,width=640,height=480,framerate=30/1 ! \
  videoscale ! videorate ! videoconvert ! timeoverlay ! \
  omxh264enc target-bitrate=2000000 control-rate=variable ! \
  h264parse ! rtph264pay config-interval=1 pt=96 ! \
    udpsink host=127.0.0.1 port=5004
```

# サンプルWebアプリで見る

https://nttcom.github.io/skyway-siru-client/examples/ で、`apikey`に取得したAPIKEYを入力後、`start` をクリックする

![image.png](https://qiita-image-store.s3.amazonaws.com/0/83466/2c7f2667-39bc-913e-cee9-f1a091d49731.png)

# MQTT Relayは？

これについては、次回記事として書きますー
ドットインストールで『PICO-8入門』を作ったときの学習ログ

Qiitaといふものを書いてみようか...とふと思い立ち、先日追加した『[PICO-8](https://dotinstall.com/lessons/basic_pico8)』の学習ログを書いてみます。

![p8_jelpi.gif](https://qiita-image-store.s3.amazonaws.com/0/30/63fbd4bc-f8ff-8473-9f6a-5595736aff25.gif)
*8ビット的なピコピコゲームが作れる仮想的なコンソール＆開発環境です*

# PICO-8の特徴

- 8ビット的なゲームが作れる
- Windows/macOS/Linux/Raspberry Pi対応の**有料アプリ（$15ほど）**。
- サウンドエディタ、スプライトエディタがまるっとついてくる。これだけで開発OK。
- ソースコードは外部エディタで編集も可能。
- 開発言語はLua。
- **公開されているゲームのすべてのソースコード＆素材が見られる。**
- ソースコードはサウンド、スプライト含め、一つのテキストファイルにまとめられるので簡単に共有可能。
- Export機能がよくできていて、スプライトだけExport、サウンドだけExport、**HTML5ゲーム形式でExport**といったことができます。

# PICO-8の可能性

できることが限定されているだけにプログラミング入門ツールとしてかなり優れていると思うのですが、惜しむらくは有料版しかないことですかね...（体験版とか機能限定無料版とかあればいいのですが）。

英語オンリー＆デバッグが若干しずらいのが難ですが、スプライトとサウンドをちゃちゃっと作れてテンションがあがりやすい、という点は素晴らしいと思うのですよね...。

# これをコンプリートしたら完璧...

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">PICO-8のチュートリアルはこれをやれば完璧ですな... <a href="https://twitter.com/hashtag/PICO8?src=hash&amp;ref_src=twsrc%5Etfw">#PICO8</a> <a href="https://t.co/tKRFWe1D3v">https://t.co/tKRFWe1D3v</a></p>&mdash; Gen Taguchi (@taguchi) <a href="https://twitter.com/taguchi/status/984910539225624576?ref_src=twsrc%5Etfw">2018年4月13日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

一番参考になったチュートリアル。かなり長大ですが、8-bit的ゲーム制作のいろいろが詰め込まれています。全67回。

<img width="620" alt="breakout.png" src="https://qiita-image-store.s3.amazonaws.com/0/30/574be75a-8a1a-4dad-54f8-a8c9ec5f16bb.png">
*かなり本格的ですよ...*

- 作るものはブロック崩し
- **パワーアップアイテム**もあるよ！
- **パーティクルでド派手なエフェクト**！
- 細かいけど「画面が震える！」といったエフェクトも！
- 効果音も作っていくよ！
- もちろん**マルチレベル対応！**

単純なブロック崩しからどんどん機能が実装されていく様子には感動すら覚えますね...。PICO-8は（内蔵フォントだと）ソースコードが見づらいのですが、その時点でのソースコードがPasteBinで公開されているのも素敵です。

- [Pico-8 Overview/Tutorial - Pico-8 Hero - YouTube](https://www.youtube.com/watch?v=M7azf71z0QE&list=PLYND9uft5u_1YCkmXiMrPU7tiBG3hIKAZ)

# 参考になるリンク集

勉強する際にはきっと役に立つはず。

- [PICO-8 Fantasy Console](https://www.lexaloffle.com/pico-8.php)
    - 公式サイト。PICO-8の購入はこちらから。
- [PICO-8 Fantasy Console Manual](https://www.lexaloffle.com/pico-8.php?page=manual)
    - マニュアルです（英語）。
- [PICO–8って何？ - PICO–8ゲーム開発入門(1) | AUTOMATON](http://jp.automaton.am/devlog/technical/pico-8-for-beginners-vol1/)
  - 日本語で入門するならまずはこちらですかね。
- [kitao/pico8-jp: Japanese version of the PICO-8 official manual (pico8.txt)](https://github.com/kitao/pico8-jp)
  - 日本語マニュアル＆早見表。とてつもなく便利...。
- [PICO-8 Tutorials - YouTube - YouTube](https://www.youtube.com/playlist?list=PLjZAika8vyZkyOjoCp0EbHeIFZ8MLlhvg)
    - サウンドエディタのチュートリアル。音作りに迷ったらこちらから。
-[Pico-8 Music Tutorial #1 - Creating a Drum Beat - YouTube](https://www.youtube.com/watch?v=Pzt0h0ErNAM)
    - 音楽に特化したチュートリアル。かなり本格的。

# Qiitaで記事を書いた感想

- YouTube動画、埋め込めないのか
- Cmd+Bで太字になるかと思ったらならなかった
- うっかりブラウザタブを閉じてしまって血の気がひいたが、ちゃんと自動保存されていて最高だと思った
- また書こう
SCSSとは？

今、playcode.ioでCSSを書いていたら文法は合っているのに、黄色い三角の警告エラーが出ました。
それでCSSの画面の下三角のボタンをクリックして、プルダウンメニューを出していたところSCSSと言うのが一覧に出てきました。
これを選択してみたら、エラーが消えました。

![スクリーンショット 2018-04-14 6.19.05.png](https://qiita-image-store.s3.amazonaws.com/0/20977/504065fe-369d-3537-db65-7a678d14bade.png)

SCSSとは何だろうとネットで検索したら、下記の記事をはじめ色々と出てきました。

https://big-mac.jp/recommend/coding/i-know-why-everyone-uses-itthe-basic-functions-of-the-sas-scss-are-summarized/

https://qiita.com/m0nch1/items/b01c966dd2273e3f6abe

今回見つけた記事は、分かりやすかったので、ご紹介します。
この記事を読むと、私は知らない間にSCSS的な文法で書いていたようです。

Sass(SCSS)のすごい点は、変数が使えたり、関数が使えることです。
さらに、ネスト（入れ子）で要素を獲得にも、簡素化して書くことができることです。

SCSSの方が括弧を使って記述するので、私は馴染みやすいので、この方法で書いていきたいと思います。
でも、playcode.ioは、新しいサービスだけあって、色々と便利ですね。

書いたコードは、下記のフリーソフトを使ってコンパイルが、必要となります。
http://koala-app.com/

こうした書き方を知っていると、生産性の向上に繋がりますね。
Linuxのファイルシステムレイアウト

Linuxのファイルシステムは[FHS](https://ja.wikipedia.org/wiki/Filesystem_Hierarchy_Standard)という標準化されたレイアウトに従っている。

よく見るものをまとめる。

# /bin

基本的なコマンドが置かれる場所。
例:cat, chmod, cpなど

```sh:catの場所
% which cat
/bin/cat
```

# /sbin

システム管理のコマンドが置かれる場所。
例:ifconfig, shutdownなど

```sh:ifconfigの場所
% which ifconfig
/sbin/ifconfig
```

# /etc

システムやアプリケーションの設定情報が置かれる。
例:hosts,nginxの設定ファイルなど

```sh:nginxの設定ファイル
% cd /etc
% ls
nginx
```

# /var

頻繁に置き換えられるファイルが置かれる。
ログやキャッシュなど。

```sh:nginxのログファイル
% cd /var/log
% ls
nginx
```

# /home

ホームディレクトリが置かれる場所。

```sh:ホームディレクトリ
% cd ~/
% pwd
/home/negi
```

# /tmp

一時ファイルが置かれる場所。

# /usr

複数のマシン間で共用することができる実行可能ファイルが置かれる。
参考:https://www.ibm.com/support/knowledgecenter/ja/ssw_aix_72/com.ibm.aix.osdevice/fs_usr.htm
外部キー制約でパフォーマンスが上がるパターンとその知見

# 基本説明

外部キー制約は参照整合性(Referential Integrity)のためのRDBMSの機能です。他のテーブルのIDなどを参照している場合に、存在しないIDを誤ってレコードに入れてしまわないように制限します。

この制約を定義すると新しいレコードを入れたり既存のレコードを更新・削除する時に参照が正しいかどうかチェックするため、一般的にパフォーマンスが低下してしまいます。

しかしSQL Serverではパフォーマンスが上がる場合があります。以下は参考記事。

参考
1. https://explainextended.com/2009/10/15/constraints-and-the-optimizer-in-sql-server-foreign-key/
2. https://www.experts-exchange.com/articles/4293/Can-Foreign-key-improve-performance.html
3. https://stackoverflow.com/questions/507179/does-foreign-key-improve-query-performance

この記事では、参考記事の解説と実際に試してみた知見を共有します。


# 解説

参考記事1と名前を合わせて、以下のようなテーブルがあるとします。

<dl>
  <dt>t_primary</dt>
  <dd>参照される側のテーブル</dd>
  <dt>t_primary.id</dt>
  <dd>t_primaryのPRIMARY KEY</dd>
  <dt>t_foreign</dt>
  <dd>参照する側のテーブル</dd>
  <dt>t_foreign.pid</dt>
  <dd>t_primary.idを参照するt_foreignのカラム。外部キー制約付き</dd>
  <dt>db</dt>
  <dd>t_primary、t_foreignを持つDB</dd>
</dl>

外部キー制約が信用できるのであれば、t_foreign.pidに出現する値は全てt_primary.idに存在することがわかります。

この時、次のようなクエリを実行プラン付きで実行します。

```sql
SELECT f.*
FROM db.t_primary p
JOIN db.t_foreign f
ON p.id = f.pid
```

このクエリは、t_foreign.pidの値がt_primary.idに存在するt_foreignのレコードを抽出します。

実行プランを見てみると確かにt_foreignだけをスキャンしており、t_primaryを見に行っていません。これはわざわざJOINしなくとも、t_foreign.pidの中にはt_primary.idに存在する値のみが入っていることが保証されているからです。特に難しいことなんてなく、人間から見てもごく自然な話ですね。

この後にt_foreign.pidの外部キー制約を外してから再度実行すると、t_primaryも見に行く実行プランになります。もしかしたらt_foreign.pidにはt_primary.idに存在しない値が入っており、JOINでレコードが減る可能性があるからです。

再度外部キー制約を付けてさらに*信頼できる状態*にすると実行プランはまたt_primaryを見に行かない最適されたものに戻ります。

ちなみに、外部キー制約を付けただけでは元に戻りません！　制約自体は付けたり外したりできるので、それだけでは既存のデータが制約を守られているかは保証されないからです。後述しますが、信頼できるかどうかは別にフラグを持っています。

次の二つのクエリも上と同様の処理を表現しているクエリです。これも実行プランが最適化されます。

```sql
SELECT f.*
FROM db.t_foreign f
WHERE f.pid IN
(
    SELECT id
    FROM db.t_primary
)
```

```sql
SELECT f.*
FROM db.t_foreign f
WHERE exists
(
    SELECT *
    FROM db.t_primary p
    WHERE f.pid = p.id
)
```


# 知見

上記のことを実際に再現しようと試行錯誤していてわかったこといくつかがあります。

## t_primaryのカラムをSELECTすると最適化されない

t_primaryの方もSELECTするのであれば当然そっちも見に行くので、外部キー制約が付いていない場合と実行プランが変わりません。

```sql
SELECT *
FROM db.t_primary p
JOIN db.t_foreign f
ON p.id = f.pid
```

ただそうなると最初のクエリって要するにt_foreignだけをSELECTするのと一緒だってことですよね。

```sql
SELECT *
FROM db.t_foreign
```

つまりこの最適化とは、JOINやWHEREをスキップしているだけです。

人間がわかり切っていることを最適化してくれるということは、自分でクエリ書いている（クエリビルダーを使っている場合も）ならあまり恩恵なさそうな…。ORMとかなら効いてくるんでしょうか？　ただ本当に外部キー制約が信頼し得るかどうかわからない場合はJOINした方が確実という意味では、最初の書き方の方がいいですね。

## 「外部キー制約を適用」が「はい」でなければ制約が働かない

本題と関係ないんですが、これを試している時にSQL Server Management StudioでキーにFKが入っているので制約が効いているのかと思ったらこのオプションがONでないと動きませんでした。当然最適化も働きません。

## 「レプリケーションに対して適用」が「はい」でなければ制約が信頼できる状態にならない

同じくManagement Studioの話。これが無いと最適化が働かないようです。

## 「作成または再度有効化するときに既存データを確認」が「はい」でなければ制約が信頼できる状態にならない

同じくManagement Studioの話。外部キー制約を戻す際はこれを「はい」にして既存データもチェックしてもらわないと最適化が働きません。

## 外部キーが信頼できる状態かどうか確認する方法

```sql
USE db
SELECT name, is_not_trusted
FROM   sys.foreign_keys
```

is_not_trusted=0なら最適化が働きます。

参考元：https://stackoverflow.com/questions/35892500/sql-server-foreign-key-still-not-trusted-after-check-check


# 雑感

もともと「外部キー制約を足すとパフォーマンスが上がる」と言われたので調査していたんですが、これだけなら最適化が効いてくるパターンってあまり無いような気がします。実際はもっと別のところで速くなっていたりするんでしょうか？　多くのデータを入れたり別パターンで試してみるとまた違うのかもしれません。
cakePHP3で複数フィールドにまたがるカスタムバリデーション

#cakePHP3で複数フィールドの日付を比較するカスタムバリデーション
カスタムバリデーションに設定している関数の第二引数には入力されたデータがそのまんま入っているのでそれを利用する。

入力された日時データは配列になっているのでFrozenTimeに変換。
あとはChronosで日付の比較が使えるようになるのでそれを使ってバリデーションの正否を返す。

```php:AppTable.php
use Cake\Database\Type;

$validator
            ->add('end_date', 'custom',
            [
                'rule' => function($value, $data){
                        //終了日が開始日より前になっていないかチェック
                        $end = Type::build('date')->marshal($value);
                        $start = Type::build('date')->marshal($data['data']['start_date']);
                        return $end->gt($start);
                 },
                 'message' => '期間が正しくありません'
            ]);
```
Chronos超便利で感動した

##参考
[CakePHP3のChronosの機能紹介](https://qiita.com/ishizuki/items/96f268a46c09136ba4dc)
[Converting array to string for date format in CakePHP 3.x
](https://stackoverflow.com/questions/42438180/converting-array-to-string-for-date-format-in-cakephp-3-x)
Slinkyを使ってみる

# Slinkyとは
Scala.js用のReactインターフェースのようです。
詳細は下記にあります。
https://slinky.shadaj.me/

# 作成と動作確認
Slinkyを使用するにあたって、以下が必要です。
- sbt
- npm


## 作成
それでは、sbtを使用して作成してみます。適当なディレクトリで、下記を入力します。

**sbt new shadaj/create-react-scala-app.g8**

入力後に、アプリケーション名を入力するように促されるので、任意の名前を設定します。
デフォルトでは、**my-app**と設定されているようです。
自分はとりあえず、 **slinky** と設定しました。
アプリケーション作成後、入力したアプリケーション名のディレクトリが作成されるので、そのディレクトリに移動します。

## 動作確認
移動後、下記を入力し、localhost:8080にアクセスすると以下の画像のように表示されることが確認できます。

**sbt ";fastOptJS::startWebpackDevServer;~fastOptJS"**

![React App1.jpg](https://qiita-image-store.s3.amazonaws.com/0/183906/73075359-5afd-152d-fe3e-2e3cca9b39a8.jpeg)


これで、作成と動作の確認ができました。

# Hello Slinky
動作確認で表示されたページに、**Hello Slinky!！**を追加してみます。
まず、src/main/scala/hello/world/Main.scalaを編集します。

```Main.scala
中略,,,

object Main {
  val css = IndexCSS

  @JSExportTopLevel("entrypoint.main")
  def main(): Unit = {
    if (LinkingInfo.developmentMode) {
      hot.initialize()
    }

    val container = Option(dom.document.getElementById("root")).getOrElse {
      val elem = dom.document.createElement("div")
      elem.id = "root"
      dom.document.body.appendChild(elem)
      elem
    }

    ReactDOM.render(App(), container)

    //　Hello Slinky!!表示用のDivを追加
    val helloSlinkyContainer = Option(dom.document.getElementById("hello")).getOrElse {
      val elem = dom.document.createElement("div")
      elem.id = "hello"
      dom.document.body.appendChild(elem)
      elem
    }
    //　Divに、Hello Slinky!!を描画する処理
    ReactDOM.render(Hello(), helloSlinkyContainer)
  }
}
```


続いて、Hello Slinky!!を描画する処理を追加していきます。
src/main/scala/hello/world/Hello.scalaを追加します。

```Hello.scala
package hello.world
import slinky.core._
import slinky.core.annotations.react
import slinky.web.html._

import scala.scalajs.js
import scala.scalajs.js.annotation.{JSImport, ScalaJSDefined}

// スタイルシートをimport
@JSImport("resources/Hello.css", JSImport.Default)
@js.native
object HelloCSS extends js.Object

@react class Hello extends StatelessComponent {
  type Props = Unit

  private val css = HelloCSS

  // Hello Slinky!!を描画
  def render() = {
    div(className := "Hello-Slinky")(
      h1(className := "Hello-Slinky-intro")(
        "Hello Slinky!!"
      )
    )
  }
}
```

そして、スタイルシートを追加します。
src/main/resources/Hello.cssを追加します。

```Hello.css
.Hello-Slinky {
    text-align: center;
}

.Hello-Slinky-intro {
    font-size: large;
}
```

## 再度、動作確認
先程と同様に動作確認をすると、**Hello Slinky!！**が追加されていることが確認できます。

![React App2.jpg](https://qiita-image-store.s3.amazonaws.com/0/183906/3a1dc3be-e9ba-eeb6-1aae-902496d33df1.jpeg)
Prebid.js取り敢えずlocalで動かしたい。のお話

まあ完全に誰得情報なんですけども。備忘＆布教になれば。
ここに書いた事は公式見れば全て書いてあります。(自衛)
公式 (http://prebid.org/)
github (https://github.com/prebid/Prebid.js/)
## Prebid.jsって何？
- 沢山のADNWが一斉に `Pre` `bid`して一番単価が高い広告をクライアントサイドでオークションして出す仕組み(ちょっと語弊生むかも知れないけど大体そんな感じ)

## どうやって動かすの？（local）
手っ取り早いのは、公式にも書いてあるけど下記実行

- 導入

```
$ git clone https://github.com/prebid/Prebid.js.git
$ cd Prebid.js
$ npm install
```
- 実行

```
$ gulp serve
```

- ブラウザで確認
    - 下のURLを追っていくと適当に動作が見られます。

`http://localhost:9999/integrationExamples/gpt`

## なんかLog出ないんだけど
- テストしてるURLの後ろに `?pbjs_debug=true`を付けよう

## 各ADNWがcpmいくらとか見たいんだけど
`ChromeDevTool` 内で `Sources` → `Snippets` → `new Snippets` → `下記js保存&実行`

```js
var responses = pbjs.getBidResponses();
var output = [];
for (var adunit in responses) {
    if (responses.hasOwnProperty(adunit)) {
        var bids = responses[adunit].bids;
        for (var i = 0; i < bids.length; i++) {
            var b = bids[i];
            output.push({
                'adunit': adunit, 'adId': b.adId, 'bidder': b.bidder,
                'time': b.timeToRespond, 'cpm': b.cpm, 'msg': b.statusMessage
            });
        }
    }
}
if (output.length) {
    if (console.table) {
        console.table(output);
    } else {
        for (var j = 0; j < output.length; j++) {
            console.log(output[j]);
        }
    }
} else {
    console.warn('NO prebid responses');
}
```


この辺まで分かればあとは本家js＆document読むだけです。
ありがとうございました。
Pythonのクロージャについて

# クロージャ(Closure)
関数の中の関数のこと
外の関数のスコープである変数にアクセスできる。

``` python
def outer():
  val = "Hello World!!"
  def inner():
      print(val)  # 関数'outer'外の変数'val'にアクセス可能
  inner()

outer()
# >>> Hello World!!
```

### 注意点
スコープに注意しなければならない。
pythonでは現在の関数のスコープから変数を参照する。


``` python
# "Goodbye World??"出力したい
def outer():
  val = "Hello World!!"  # スコープ: 'outer'
  def inner():
      val = "Goodbye World??"  # スコープ: 'inner'
  inner()
  print(val)  # 'outer'のvalを参照する
              # innerのvalは新しく生成されたため別のオブジェクト

outer()
# >>> Hello World!!
```

### 解決方法
nonlocalを入れるだけ

``` python
def outer():
  val = "Hello World!!"
  def inner():
      nonlocal val  # nonlocalを入れる
      val = "Goodbye World??"
  inner()
  print(val)

outer()
# >>> Goodbye World??
```
LaravelでAPIを叩き、連想配列要素一つを取り出す方法。

あまりにも簡単なことすぎて、書いてる方がいらっしゃらなかったので、プログラミング歴１ヶ月の僕が書いて見ました。

<h3>APIの中身</h3>
```json
[
    {
        "id": "hoge", 
        "name": "HOGE"
    }
]
```
<h3>HogeController
のAPIを叩くHogeインスタンス</h3>

```php


public function hoge() 
{
 //叩きたいAPIを持ってくる
 $base_url = 'https://apihogehoge';

//file_get_contents関数で、$base_urlの配列を読み込む
 $json = file_get_contents($base_url);

//json_decodeで、phpで扱えるような変数にする
 $json = json_decode（＄json,  JSON_PRETTY_PARTY);

//array関数を思い出しながら、一つの要素を指定する
 $hoge = $json[0]["name"];

//変数をもちながら、viewに展開する

return view('/hoge', compact('hoge'));

}
```

これで、"HOGE"がでるようになります。
ここでlaravel特有の変数の持っていきかたに習って変数を定義します。

```php
{{ $hoge }}
```

{{}}でechoのような役割を果たすようです。

あとは、上記の変数をhtml内のどこで入れるべきかを考えるべきです。
TensorFlow.jsで線形回帰してみた

#はじめに
TensorFlow興味あるんだけど触ってないみたいなところにTensorFlow.jsがリリースされていたので触ってみました。
今回は[多分もっともわかりやすいTensorFlow 入門 (Introduction)](https://qiita.com/junichiro/items/8886f3976fc20f73335f)で紹介されている線形回帰のサンプルをTensorFlow.jsで実装してみました。

~~下記にDEMOを用意しました。~~
DEMOはクローズしました(2019/08/28)

#コード全体
```javascript
let randomData = [];
for(let i=0;i<=100;i++){
  randomData[i] = Math.random();
}
let xData = tf.tensor1d(randomData);


let yData = tf.add(tf.mul(xData,tf.scalar(0.1)),tf.scalar(0.3));


let W = tf.variable(tf.zeros([1]));
let b = tf.variable(tf.zeros([1]));
//y = W * x + b
let y = x => tf.add(tf.mul(W,x),b);


let loss = (y,yd) => y.sub(yd).square().mean();
let optimizer = tf.train.sgd(0.5);


for (let i = 0; i <= 200; i++) {
  optimizer.minimize(() => loss(y(xData),yData))
  if(i % 20 == 0){
    console.log(`step: ${i}, W: ${W.dataSync()}, b: ${b.dataSync()}`);
  }
}
```
**※上記コードはメモリの開放を行っていないためメモリリークします。実際にTensorFlow.jsを使う際はdispose()やtidy()を使用してメモリを開放するようにしてください**
**参考:[https://js.tensorflow.org/tutorials/core-concepts.html](https://js.tensorflow.org/tutorials/core-concepts.html)の「Memory Management: dispose and tf.tidy」の項**

#やってること
ちゃんとした解説は[多分もっともわかりやすいTensorFlow 入門 (Introduction)](https://qiita.com/junichiro/items/8886f3976fc20f73335f)を参照してもらうとして、ざっくり下記のようなことをしています。
1. $ y = 0.1 \times x + 0.3 $からトレーニングデータを作成
2. $ y = W \times x + b $をモデルとして用意したトレーニングデータで線形回帰して$W$と$b$を求めます。それぞれが$0.1$と$0.3$位になれば成功です。

#コード解説
##注意
下記は[多分もっともわかりやすいTensorFlow 入門 (Introduction)](https://qiita.com/junichiro/items/8886f3976fc20f73335f)に載ってるソースコードと見比べながら読む感じを想定してます。
##トレーニングデータ生成

```javascript
let randomData = [];
for(let i=0;i<=100;i++){
  randomData[i] = Math.random();
}
let xData = tf.tensor1d(randomData);
```

randomな値を一気に100個用意できないのでforで回して作りました。
TensorFlow.jsでは生の値のまま使わず、tf.tensor1dやtf.tensor4dなどを一度通して扱う必要があるみたいです(Pythonは勝手にその辺やってるんでしょうか？)

```javascript
let yData = tf.add(tf.mul(xData,tf.scalar(0.1)),tf.scalar(0.3));
```

オペレータをオーバーロードできないので普通の四則演算のように書けないのでちょっと書きづらいです。addやmulなどが用意されているのでそれを使って計算していきます。

##モデル定義
```javascript
let W = tf.variable(tf.zeros([1]));
let b = tf.variable(tf.zeros([1]));
//y = W * x + b
let y = x => tf.add(tf.mul(W,x),b);
```
Wとbの部分はほぼ同じです。Wの方もbと同じtf.zeros([1])で構わないとのことだったのでそのようにしています。
yの部分はxを引数とした関数になりました

##コスト関数を定義
```javascript
let loss = (y,yd) => y.sub(yd).square().mean();
let optimizer = tf.train.sgd(0.5);
```
lossもy同様関数として定義しています。
optimizerはtf.train.GradientDescentOptimizerではなくtf.train.sgdでした。[tf.train.sgdのドキュメント](https://js.tensorflow.org/api/0.9.0/#train.sgd)をみるとstochastic gradient descentって書いてたので多分同じ処理してくれてるはず。

##実行
```javascript
for (let i = 0; i <= 200; i++) {
  optimizer.minimize(() => loss(y(xData),yData))
  if(i % 20 == 0){
    console.log(`step: ${i}, W: ${W.dataSync()}, b: ${b.dataSync()}`);
  }
}
```
tf.Session()などは見当たらずちょっと途方にくれたのですが、初期化などは必要なく実行してもいいのかなとやってみたら動いた感じです。

#実行例
![test.PNG](https://qiita-image-store.s3.amazonaws.com/0/150472/404975eb-93d0-c46c-9b72-f6152377d0d4.png)

#おわりに
ちょっと謎な部分もあったので[公式ページ](https://js.tensorflow.org/)をちゃんと読まないとなと思いました。
modelとかlayerとかをまったく使わなかったので、気が向いたらそのあたりを使うようなのを作れたらいいかなと思います。
dataプロパティに登録したオブジェクトの変更を検出する方法

##はじめに

Vue.jsはインスタンスが持つプロパティ（dataやprops）の変更を検知して、DOMの内容を変更したり、イベントの発火を行うことができます😇
しかし、Vue.jsの[ドキュメント](https://jp.vuejs.org/v2/guide/reactivity.html)に以下のようなことが書いてあります。

>モダンな JavaScript の制限(そして Object.observe の断念)のため、Vue.js はプロパティの追加または削除を検出できません。Vue.js はインスタンスの初期化中に、getter/setter 変換処理を実行するため、プロパティは、Vue がそれを変換しそしてそれをリアクティブにするために、data オブジェクトに存在しなければなりません。

**Vue.jsはプロパティの追加または削除を検出できません。**👈コレ

Vueはすでに作成されたインスタンスに対して動的に新しいルートレベルのリアクティブなプロパティを追加することはできません。
簡単に説明すると、JavaScriptの制限(`Object.observe`)によって、dataやprops配下のオブジェクトの変更を検知することができないということです😷💦
つまり、いつものようなやり方でオブジェクトを変更すると、変更が検出されません😩


##オブジェクトの変更検出の注意

以下のような処理では、動的に追加したプロパティは無視されてしまいます😷

```vue:
<script>
  export default {
    data: () => ({
      tags: {
        name: 'タグ'
      }
    }),
    methods: {
      addColor () {
        this.tags.color = '#E84B3C'
      }
    }
  }
</script>
```




##変更を検出する方法

先ほど、「Vueはすでに作成されたインスタンスに新しいルートレベルのリアクティブプロパティを動的に追加することはできません。」とあったのですが、
以下の方法でネストされたオブジェクトにリアクティブなプロパティを追加することが可能です✌️

###1.`vm.$set`をつかう

`vm.$set`インスタンスメソッドを使えば、
オブジェクトにリアクティブなプロパティを追加することができます😇

```vue:
<script>
  export default {
    data: () => ({
      tags: {
        name: 'タグ'
      }
    }),
    methods: {
      addColor () {
        this.$set(this.tags, 'color', '#E84B3C')
      }
    }
  }
</script>
```
※`vm.$set`は`Vue.set`のエイリアスです。

###2.`Object.assign()`をつかう

複数のプロパティを割り当てたい場合は、`Object.assign()`が便利です😇
このような場合、変更を検知するのではなく、元のオブジェクトと、追加するオブジェクトの両方のプロパティを持つ**新たなオブジェクト**が作られることになります。

```vue:
<script>
  export default {
    data: () => ({
      tags: {
        name: 'タグ'
      }
    }),
    methods: {
      addColor () {
        this.tags = Object.assign({}, this.tags, {id: 1, color: '#E84B3C'})
      }
    }
  }
</script>
```

※`Object.assign()`は、IE非対応なので注意してください💦
ブラウザ実装状況は[こちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)

###3.`vm.$delete`をつかう

逆にプロパティを削除する場合は`vm.$delete`を使います。

```vue:
<script>
  export default {
    data: () => ({
      tags: {
        name: 'タグ',
        color: '#E84B3C'
      }
    }),
    methods: {
      deleteColor () {
        this.$delete(this.tags, 'color')
      }
    }
  }
</script>
```
※`vm.$delete`は`Vue.delete`のエイリアスです。


##まとめ
Vueが`Object.defineProperty`を使用して、
オブジェクトをgetter/setterに変換することでリアクティブを実現しているんですね😇

しかし、Vueインスタンスに渡したオブジェクトは、
プレーンなJavaScriptオブジェクトのように扱ってはいけないことには注意が必要ですね😷
Installing powershell, nodejs, typescript kernels for jupyterlab on Windows.


# environment check
```
conda env list
which jupyter-lab
jupyter lab path
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/30d5407a-485b-68ee-88c2-c010a2fa4bfd.png)

# install powershell kernel
```
which pip
which python
pip install powershell_kernel
python -m powershell_kernel.install
```
ref https://github.com/vors/jupyter-powershell
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/9e2da34a-549a-921e-ebaf-654a1a3f5139.png)

# check powershell console
`jupyter lab`
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/ad98cbd6-7e84-6d0d-1d11-38cea4ace9aa.png)

# install typescript kernel
```
which tsc
tsc --version
node --version
npm install -g itypescript
which its
its --ts-install=global
```
ref https://github.com/nearbydelta/itypescript
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/41fb844c-5748-cb6c-7614-2124bff85c20.png)

# check typescript notebook
`jupyter lab`
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/94028be1-bfcb-3be1-b227-bb1e42946693.png)

# nodejs kernel
```
npm install -g ijavascript
ijsinstall
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/e045a4ab-c5ce-bc73-c9eb-4a015bb93482.png)

# check javascript notebook
`jupyter lab`
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12587/f7f552de-e199-6797-1c5b-4c86a430597f.png)

```

# ref
kernel list https://github.com/jupyter/jupyter/wiki/Jupyter-kernels
EC2にSFTPさせる

外部の接続元から自分で管理しているEC2にSFTPしてもらう想定で書いていますが、もちろん自分で接続する用でも良いです。

# SFTPとFTPSの違い
まず、両者は全く違います。
SFTPは基本はSSHだと思って頂ければいいです。SSHで接続してファイルの転送だけFTPを使う感じです。
FTPSはFTP+暗号化してSecureにします。HTTPにSが付くパターンと同じです。

# サーバ側でやること
- まず ```useradd``` コマンドで接続用のユーザを用意しましょう
- 次に公開鍵認証用に ```ssh-keygen -t rsa``` で公開鍵と秘密鍵を作成します。デフォルトなら **id_rsa.pub** と **id_rsa** が出来るので、秘密鍵である後者をSFTPさせたい相手に、圧縮してパスワードつけるなどして渡しましょう
- 前者の公開鍵は、 ```/home/{useraddで追加したユーザ}/.ssh/authorized_keys``` という名前で配置しましょう
- ```/home/{useraddで追加したユーザ}/.ssh``` ディレクトリのパーミッションは **700** にしましょう
- ```authorized_keys``` のパーミッションは **600** にしましょう
- 必須ではないですが、接続元のGIPなどをEC2のセキュリティーグループのインバウンド設定に入れると良いかと思います。仮に秘密鍵とこちらのホスト名(IP)が漏れても、接続を防げます

あとはお茶でも飲みながら「接続出来ました！」という返事を待つのみなのですが、なぜか繋がらない。。

よく出る ```permission denied``` のエラー。-vvv で詳細表示してもよく分かりません。
通常は上記の手順で繋がるのですが、実は接続ユーザのホームディレクトリを ```usermod -d``` で 変更している場合、修正が必要な箇所があります。
SSHの設定ファイル ```/etc/ssh/sshd_conf``` で、公開鍵のファイル名を設定している以下の箇所がありますが、

```
AuthorizedKeysFile     .ssh/authorized_keys
```
ログイン直後からの相対パスで設定されているため、ホームディレクトリを変更した場合は公開鍵が見つからずにエラーになります。（Not Foundとか出して欲しい）

なので

```
AuthorizedKeysFile     /home/%u/.ssh/authorized_keys
```

と絶対パスに書き換えて ```sudo service sshd restart``` で再起動する必要があります。

SFTPもSSHも基本同じなので例はSFTPでしたが、SSHでももちろん繋げます。
あと、サーバ側のエラー情報などは ```/var/log/secure``` に出たりします。今回の例では全く役に経ちませんでしたが。
60秒待つときに“.......”というように出したい

# 60秒待つときに“.......”というように出したい

　目からうろこだったのでメモ。

　インストールのときに、

```
...
......
.........
```

　というように“.......”で経過を表すプログラムがありますが、あれをやりたい時のヒント。

```bash:LoopCount.sh
#! /bin/ksh

# 60秒以内にhoge.txtというファイルが同じディレクトリに生成されたかどうかチェックし、
# 生成されたらメッセージを返す

LoopCnt=0
LoopMax=60

while true
do
	sleep 1
	# 必ずさせる処理
	echo -n "."

	if [[ -e hoge.txt ]] ; then
		echo ""
		echo "File was Created!"
		break
	fi

	# 条件を満たしたか毎秒チェック
	(( LoopCnt = ${LoopCnt} + 1 ))
	if [[ ${LoopCnt} -ge ${LoopMax} ]] ; then
		echo ""
		echo "End"
		break
	fi
done
```

```bash:実行結果
# ファイルが60秒以内に生成できた場合
$ ./LoopCount.sh 
..............
File was Created!

# ファイルが60秒以内に生成できなかった場合
$ ./LoopCount.sh 
............................................................
End
```

　他にも「60秒以内に～～したら」というようなときにも使える。うっかり```sleep 60```とか書いてしまいそうだが、こう書いておけば早く次の処理に移れてクール！
swagger-codegen-cliで生成したコードが好みでなかったときの対処法

## 困ったこと
外部サービスが提供しているSwagger Specでjava-clientのコードをswagger-codegen-cliで生成して使っていました。
swagger-codegen-cliのバージョンを上げて再作成したところ、Booleanのgetterが`getXXX`ではなく`isXXX`に変わってしまいました。

## 状況
- swagger-codegen-cliのv2.2.3を以前使ったが、新しいSwagger Specでは正しく生成できない。(ビルドエラーになる)
- v2.2.3 -> v2.3.1に変更（current stable）

## テンプレートをカスタマイズ

実行する際に`-t`をつける

```shell
# 例
# -t: templateがあるフォルダを指定. templateに存在するテンプレートファイルを優先して作成してくれる
java -jar swagger-codegen-cli.jar generate -l java -t ./template -o swagger-java-client
```

元々のテンプレートファイルの場所はgithubの`swagger-codegen/modules/swagger-codegen/src/main/resources/Java/`にあります

今回上書きしたいテンプレートファイルはpojo.mustacheです。getter部分の箇所を見ると

```mustache

  public {{{datatypeWithEnum}}} {{#isBoolean}}is{{/isBoolean}}{{getter}}() {
    return {{name}};
  }
  {{^isReadOnly}}

```

となっている場所があるので、次のように直します

```mustache
{{#isBoolean}}
  public {{{datatypeWithEnum}}} get{{getter}}() {
    return {{name}};
  }
{{/isBoolean}}

{{! Boolean以外はgetを書かなくてもgetが設定される }}
{{^isBoolean}}
  public {{{datatypeWithEnum}}} {{getter}}() {
    return {{name}};
  }
{{/isBoolean}}
  {{^isReadOnly}}
```

## まとめ
今回は生成したコードでは困るので、テンプレートを上書きするようにしました。
同様に自分の好みにカスタマイズすることも可能です。

## 補足
v2.3.1ではテンプレートファイルで上書きするしかありませんが、次のバージョンでconfigでBooleanのprefixが決められるようになるかもしれません。（2018/04/13時点）
JUnitでprivateメソッドのテストをする場合に注意すること

JUnitでどうしてもprivateメソッドをテストしなければならない時のために。
実装方法を定期的に忘れるので、一回しっかり記事で書けば忘れないだろう。という動機で書き残しておきます。

# 一般的なケース

以下のようなプライベートメソッドを持つクラスをテスト対象に考えます。

```java
public class MyClass {
    private String introduceMyself(String name){
        return "my name is " + name + ".";
    }
}
```
MyClassのprivateなintroduceMyselfメソッドに対するテストは、以下のようにリフレクションを使うことで行えます。

```java
import com.example.MyClass;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Method;
import static org.assertj.core.api.Assertions.assertThat;

public class MyClassTest {
    @Test
    void testIntroduceMyself01() throws Exception {
        MyClass targetClass = new MyClass();
        // テスト対象メソッドの情報を取得する
        Method method = MyClass.class.getDeclaredMethod("introduceMyself", String.class);
        // メソッドをアクセス制限を解除
        method.setAccessible(true);
        // メソッド呼び出し
        String selfIntroduction = (String) method.invoke(targetClass,"John");
        // 結果をアサーション
        assertThat(selfIntroduction).isEqualTo("my name is John.");
    }
}
```

# privateメソッドがスローする例外のアサーション
正常系のテストケースは上記で問題ないのですが、privateメソッドから例外がスローされるケースは注意が必要です。

Method#invoke内で発生した例外は、InvocationTargetExceptionクラスにラップされてしまいます。その為、原因例外を取り出してからアサーションする必要があります。


```java
public class MyClass {
    private String introduceMyself(String name){
        // 引数が空文字の場合は例外をスローする
        if(name.isEmpty()){
            throw new IllegalArgumentException("argument must not be empty.");
        }
        return "my name is " + name + ".";
    }
}
```

```java
public class MyClassTest {
    @Test
    void testIntroduceMyself02() throws Exception {
        MyClass targetClass = new MyClass();
        Method method = MyClass.class.getDeclaredMethod("introduceMyself", String.class);
        method.setAccessible(true);

        try {
            method.invoke(targetClass, "");
            fail("this code should not has been reached.");
        }catch (InvocationTargetException e) {
            //　getCauseで原因例外を取り出してからアサーション
            assertThat(e.getCause()).isInstanceOf(IllegalArgumentException.class);
        }
    }
}
```

# privateメソッドの引数にnullを渡す
リフレクションで呼び出すメソッドの引数としてnullを渡したい場合は、nullを要素として持つObject配列を渡す必要がある為、こちらも注意が必要です。

```java
method.invoke(targetClass, new Object[]{null});
```

```java
// これではダメ
method.invoke(targetClass, null);
```

# そもそもprivateメソッドを単独でテストすべきではない
ここまで書いといてあれですが、privateメソッドは原則としてユニットテストすべきではありません。

privateメソッドは、言ってみればpublic(protected)メソッドから切り出された内部処理です。内部処理を強引にリフレクションでテストすることで、テストコードが内部実装に依存することになり、リファクタリングや機能追加の際に障壁となります。

適切に設計されたprivateメソッドであれば、呼び出し元のメソッド経由で網羅性はテスト可能です。
仮にprivateメソッドを個別で呼び出さなければ通らない分岐があるとしたら、それは実質的にデッドコードですから、実装を見直したほうが良いでしょう。

# まとめ

- privateメソッドを呼び出すにはリフレクションが必要
- 例外のテストは、InvocationTargetExceptionからgetCauseする事
- invokeにnullを渡す場合は、nullを要素として持つObject配列を渡す
- privateメソッドをテストする必要が出たら、設計を見直してみること
- privateメソッドは、呼び出し元のメソッド経由でテストするのが原則
新人にはヒントを与えるより答えを示す方がいい

※ポエムです
※技術的な話は皆無です
※結論ありません

# イントロ
4月になって新人が配属された現場も少なくないと思います。
そんな中でいつも頭を悩ますのが新人への仕事の振り方。

ざっくり2つのやり方に大別されるかなと思います。

1. ゴールと仮説を伝えて手順を考えるところからやってもらう（ヒントを与える）
2. 検討済の手順を伝えてそれに沿ってやってもらう（答えを示す）

これのどちらが良いのか悩みどころです。
（すみません、タイトルは釣りです）


# 先日、現場でこんな依頼がありました。

```
依頼内容
AWSのS3に保存してあるファイルを指定の規則に従ってリネームして欲しい。
```

経験のあるエンジニアならこの依頼を受けたときにいろいろ考えが浮かぶと思います。
- ファイル数はどれくらいだろう？
- コンソール操作だけで済むのかAWS CLIを使ったほうが良いのか？
- AWS CLIでリネームできるのか？ローカルで加工したほうがいいのか？
- リネームの方法、複数のコマンドを組み合わせないとできないのか？
- 1つのコマンドで実現できないのか？
etc...

これが新人だとこのようにはいかないのかなと思います。
試行錯誤して効率悪いものの要望を満たせたら良いですが、
出来上がった手順が要望を実現できないかもしれません。

スケジュールに余裕がある場合は、
**考えてもらう→レビュー**
を繰り返せば良いですが。。。

また、新人には
**考えるためのネタ**
がありません。

何も知らないところから最適な解を導き出すことは難しいと思います。
なので、最初のうちは**答えを示して、考えるためのネタを蓄えてもらう**というのも必要なアプローチなのかなと思いました。

# まとめ
## 1.ヒントを与える
### 良い点
- 問題解決力が身につく(ざっくり)
 
### 悪い点
- スケジュールに余裕が無いとキビシイ

## 2.答えを示す
### 良い点
- ある程度確立された手法を蓄積できる

### 悪い点
- やりすぎると具体的な作業指示がないと動けない人になっちゃう

グダグダですみません。
新人教育について考える1つのネタになれば幸いです。