OmniAICreator/Qiita-1.07M huggingface dataset:
Web3.js で ERC20 トークンの残高を取得

* この記事のサンプルで使用している Web3.js のバージョンは `0.20.6` です。

# Contract を扱うための ABI を用意
- ABI は、スマートコントラクトがどのような関数や状態変数を持っているかといった情報をもったインタフェースです。
- Web3.js のプログラムからスマートコントラクトを扱う際は、このABIの情報に基づいて関数を読んだりや状態変数の値を読みます。
- 通常、ABI にはあるスマートコントラクトが持っているすべての関数や状態変数の情報が記載されますが、ERC20 トークンの残高を取得するには、getBalance という関数と decimals という状態変数の値を読むことができればいいので、この記事ではその2つのみを ABI に記載します。

## getBalance と decimals の情報のみを持つABI

```js
let minABI = [
       // balanceOf
       {
         "constant":true,
         "inputs":[{"name":"_owner","type":"address"}],
         "name":"balanceOf",
         "outputs":[{"name":"balance","type":"uint256"}],
         "type":"function"
       },
       // decimals
       {
         "constant":true,
         "inputs":[],
         "name":"decimals",
         "outputs":[{"name":"","type":"uint8"}],
         "type":"function"
       }
     ];
```

# サンプルコード
- 任意のERC20トークンのアドレスと、そのERC20トークンの残高を知りたいウォレットアドレスから、ERC20トークンの残高を取得するサンプルコードです。

```js
let tokenAddress = "REPLACE_WITH_ERC20_TOKEN_ADDRESS";
let walletAddress = "REPLACE_WITH_WALLET_ADDRESS";

// ERC20 トークンの残高を取得するための最小限のABI
let minABI = [
  // balanceOf
  {
    "constant":true,
    "inputs":[{"name":"_owner","type":"address"}],
    "name":"balanceOf",
    "outputs":[{"name":"balance","type":"uint256"}],
    "type":"function"
  },
  // decimals
  {
    "constant":true,
    "inputs":[],
    "name":"decimals",
    "outputs":[{"name":"","type":"uint8"}],
    "type":"function"
  }
];

//  ABI とコントラクト（ERC20トークン）のアドレスから、コントラクトのインスタンスを取得 
let contract = web3.eth.contract(minABI).at(tokenAddress);

// 引数にウォレットのアドレスを渡して、balanceOf 関数を呼ぶ
contract.balanceOf(walletAddress, (error, balance) => {
  // ERC20トークンの decimals を取得
  contract.decimals((error, decimals) => {
    // 残高を計算
    balance = balance.div(10**decimals);
    console.log(balance.toString());
  });
});
```

# デモ
- [https://piyolab.github.io/playground/ethereum/getERC20TokenBalance/](https://piyolab.github.io/playground/ethereum/getERC20TokenBalance/)

# Note
- Ethereum 関連の情報は https://scrapbox.io/sushiether/ に集約することにしました。
- この記事の内容に変更・更新がある場合は、以下の URL を更新します。
- https://scrapbox.io/sushiether/Web3.js_で_ERC20_トークンの残高を取得
jQueryの$ってDOM扱ってるっぽくて安心するのでVannila JSに導入する

## $はとても安心する

今回は`$はとても安心する`を主題に執筆を開始しますが、そのなぜ安心するかというのは主に

- 長期間のjQuery使用による ~~刷り込み~~ 慣れ

だとは思います。
今回はVannila JSで`$`を素敵に扱っていきたいと思います。

## やり方

Mac をお使いの皆様は `⌘ + ⌥ + I` (コマンド　&& オプション && アイ) をおもむろに打ち込み開発者ツールを開いてください。

次に以下のスクリプトを流し込んでください。

```js
const $ = identifier => {
  if (identifier.substr(0,1) === '#')
    return document.getElementById(identifier.substr(1))
  else 
    return document.querySelectorAll(identifier)
}
```

もしES6対応していない環境をお使いのみなさまは、

```js
var $ = function(identifier) {
  if (identifier.substr(0, 1) === '#')
    return document.getElementById(identifier.substr(1));
  else
    return document.querySelectorAll(identifier);
};
```

こんな感じでいいと思います。

```js
$("h1")[0].innerText = "jQuery最高！！！！"
```

いかがでしょうか。これでjQueryで作られている環境に`jQueryっぽい何か`の導入ができました。社内からjQueryを撲滅するためにこっそり新機能のページはES6で置き換えるのもいいかもしれませんね！！！

> VanillaJS の公式ドキュメント http://vanilla-js.com/


それではよいJSライフを！！
[Java]インタフェースで内部クラスが定義できるのを知らなかったこと

インタフェースで定義できるのはメソッドの定義と定数の定義だけだと思って
いたが違ってたのでメモ程度に

``` Hoge.java
public interface Hoge{

  public int A = 10; // 定数の定義
  
  public void hoge(); // メソッドの定義

  public class InnerClass{  // 内部クラスの定義   
  }
}

```

内部クラスが定義できるとは知らなかったです。

### 参考
http://yuroyoro.hatenablog.com/entry/20080707/1215431467
https://teratail.com/questions/36600
http://www.atmarkit.co.jp/ait/articles/1007/27/news103.html
rails で作成したアプリの削除

勉強がてらやってると潰して作り直しとか、いらんもん作ったりとかよくやるのでキロク。

## 削除するもの

1. データベース
2. gem
3. アプリ本体

##　データベースの削除

```cmd:コマンド
$ rake db:drop
```
これで関連DB一括削除。
多分普通にDROP文書いてもいいはず。
楽だけどこればっか使ってるとSQL忘れそう。

## gem

bundler使って、アプリ内のGemfileからインストールしてるので何もしない。
こーゆーことがあるので、グローバルgemはDB接続アダプタとrailsくらいしか置かないようにしよっと。

## アプリの削除

```cmd:コマンド
$ rm -rf アプリフォルダ
```

おしまい。
静的変数の動的呼出し




# TL;DR

下書きが埋まったので小ネタ解放。
動的にコード(可変変数)を呼び出したい。

```PHP:setting.php
class Setting {
  public static $testNumber = array(
    "1" => "1",
    "3" => "2",
    "3" => "3",
    "4" => "4",
    "5" => "5",
  );
}

$className = "Setting";
$name = "test";
$myVarious = $name."Number";
$className::${$myVarious}[3];// 3
```

ことの詳細はあいまいさの回避。
$$myVarious[3]だと、$myVarious[3]が変数なのか$myVariousが変数で添え字が[3]なのかが判断できないのでエラーが起こる。
なのでそこを{}でくくり `$myVarious`が変数である事を教えてやる。

・[可変変数](http://php.net/manual/ja/language.variables.variable.php)
CloudWatch Event Rule Targets Configure input の種類

- 公式 [Amazon CloudWatch Events ルールターゲット \- AWS CloudFormation](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-events-rule-target.html)

<img width="1055" alt="20180521_cw_event_input_01.png" src="https://qiita-image-store.s3.amazonaws.com/0/89680/ff1b31bd-1732-c78b-2d2e-67dab298cb6b.png">

# Matched event (一致したイベント)

イベント全体をそのまま渡す。

# Part of the matched event (一致したイベントの一部)

- CloudFormation property: InputPath

イベントの一部をJSONPath形式で指定して渡す。複数指定不可。

```
$.detail
```

# Constant (JSON text) (定数 JSONテキスト)

- CloudFormation property: Input

任意のJSON文字列をJSON形式で渡す。

```
{ "key": "value", "hoge": [ 1, true, "fuga" ] }
```

# Input Transformer (インプットトランスフォーマー)

- CloudFormation property: InputTransformer
	- InputPathsMap
	- InputTemplate

テンプレートに基づいた <b>文字列</b> を渡す

## Input Path

Key-Value形式でJSONPath(ドット表記)を記述。

```
{ "state": "$.detail.state", "instance": "$.detail.instance-id" }
```

## Input Template

渡される<b>文字列</b>のテンプレート。Input Path 定義(プレースホルダ)は "<>" で囲む。

```
"The state of Instance <instance> is <state>"
```

## Lambda 内でJSON形式で利用する

Input Template に JSON文字列 を定義し、
JSON<b>文字列</b> として渡し、Lambda側で変換する。

- ダブルクォーテーションで囲む
- 内部のダブルクォーテーションをエスケープ
- 改行不可

```
"{ \"DetailType\": \"<DetailType>\", \"Source\": \"<Source>\" }"
```

### Python

- Input Transformer 以外は <i>dict</i> で渡る

```
import json
def lambda_handler(event, context):
    if type(event) == str:
        event = json.loads(event)
```

### Node.js

- Input Transformer 以外は <i>object</i> で渡る

```
exports.handler = async (event) => {
    if (typeof(event) == "string") {
        event = JSON.parse(event);
    }
};
```
yum で Error: File contains no section headers. って出たときの対応

## はじめに
- ちょっとした問題に合ったのでメモとして。
- yumできるものを確認しようとして、listされなくなったときの対処法です

## 問題
```
$ yum list available 'HOGE*'
Loaded plugins: fastestmirror
Error: File contains no section headers.
file: file:///etc/yum.repos.d/HOGE.repo, line: 2
'<!DOCTYPE html>\n'
```

- どうやら、repoの中を覗こうにもhtml形式になってしまっている

## 期待
- 下記のように利用できるパッケージをlist形式で見たかった

```
Available Packages
HOGE.x86_64                          2.28.0-1.el5           HOGE-stable 
HOGE-doc.x86_64                      2.28.0-1.el5           HOGE-stable 
:
```

## 解決方法
- vi /etc/yum.repos.d/HOGE.repo
- とりあえずviで開いて、問題箇所を手打ちで修正する

## 原因
- と viで直ればいいのだが、htmlはそもそもおかしい（正常にlistできるものをviで開けば分かる）
- この場合、そもそも rep が正しくダウンロードできていない可能性がある。
- htmlをviで開けば分かるが、404のページを.repoでダウンロードするみたいなことになっている

## ので、本当の解決方法
- もう一度 rep がリンク切れしていないか確認したほうが良い
- 最悪ソースからbuildする
個人的な校正用スクリプト collar.vim

昨日エントリ書きながらこういうのあったらいいなと思ったものをとりあえずこさえてみました。「襟を正す」イメージですね…オシャレのつもりで関数名が衣類に関わるものになってます。

## ソース

```vim:collar.vim
let g:collar_marks = [ [
			\   '`',  '~',  '!',  '@',  '#',  '$',  '%',  '^',
			\   '&',  '*',  '(',  ')',  '_',  '-',  '+',  '=',
			\   '[',  ']',  '{',  '}',  ';',  ':',  '''', '"',
			\   '<',  '>',  ',',  '.',  '/',  '?',  '|',  '\',  ' '  ],
			\[  '｀', '￣', '！', '＠', '＃', '＄', '％', '＾',
			\   '＆', '＊', '（', '）', '＿', 'ー', '＋', '＝',
			\   '［', '］', '｛', '｝', '；', '：', '’', '”',
			\   '＜', '＞', '、', '。', '／', '？', '｜', '＼', '　' ]
			\]

function! s:deStain() abort
	let char = matchstr(getline('.'), '.', col('.')-1)
	let isFullMark = char2nr(char) < 128 ? 0 : 1
	let m = 0
	try
		while char2nr(g:collar_marks[isFullMark][m]) != char2nr(char)
			let m += 1
		endwhile
		execute 'normal r'.g:collar_marks[!isFullMark][m]
	catch /E684/
		echo 'no match.'
	endtry
endfunction

function! s:getBasteFile(...) abort
	let l:toBaste = expand('%:p')
	let newBaste = [ expand('%'),'v1', 'baste' ]
	let dup = 1
	while filereadable(join(newBaste,'.'))
		let dup += 1
		let newBaste[1] = 'v'.dup
	endwhile
	let basteFile = join(newBaste, '.')
	execute('new '.basteFile)
		put! = l:toBaste
	write
endfunction

function! s:getBasteList(basteList) abort
	let l:returnList = []
	let l:currentList = []
	for b in a:basteList
		if b != ''
			call add(l:currentList, b)
		else
			if len(l:currentList) > 0
				call add(l:returnList, copy(l:currentList))
				let l:currentList = []
			endif
		endif
	endfor
	return len(l:currentList) > 0 ? add(l:returnList, copy(l:currentList)) : l:returnList
endfunction

function! s:goBaste() abort
	let l:toBaste = getline(1)
	let bufLine = 2
	while getline(bufLine) == '' && bufLine < line('$')
		let bufLine += 1
	endwhile
	try
		if bufLine >= line('$')
			throw 'noreplace'
		endif
		let l:toBasteBuf = bufwinnr(bufnr(l:toBaste))
		if l:toBasteBuf > 0
			execute(l:toBasteBuf.'wincmd w')
		elseif filereadable(l:toBaste) == 1
			execute('split '.l:toBaste)
		else
			throw 'nofile'
		endif
	for b in l:basteList
		execute('%s/\v%('.join(b[1:],')|%(').')/'.b[0].'/gc')
	endfor
	catch /nofile/
		echo 'no such file '''.l:toBaste.''''
	catch /noreplace/
		echo 'no replace.'
	endtry
endfunction

command! <silent> DeStain call s:deStain()

command! -nargs=? -complete=file BasteFile call s:getBasteFile(<f-args>)
command! Baste call s:goBaste()
```

## ナニコレ

今やることは2つだけです。

### 記号の半角/全角を入れ替える`deStain()`関数[^1]

更新前のスクリプトは正規表現のエスケープ考えずに`match()`を使うという頭の悪いことをしていたので、変換リストの兼ね合いで一番簡単そうな`char2nr()`を使う方法に変えました。適当に`:DeStain`をリマップして使ってやってください。筆者は`<Space><Space>`で使ってます。[^2]

[^1]: destain : \[他動\] ～から汚れを除く。
[^2]: リーダーキーを`<Space>`にすると捗るとかなんとか…

### 表記揺れを一気に修正する`baste()`関数[^3]

`:BasteFile`をすると表記揺れ修正用のバッファが開きます。見つけた表記揺れを空行区切りでどんどん書いていってください。一応Very Magicモードの正規表現で書けるようになっていますが、スクリプト上では`|`でまとめてヒットするようにしてあるので見つけたらどんどん追加していくほうが手っ取り早いとおもいます。チェックが終わったら`:Baste`とすると、区切った表記揺れの最初の行の単語に置換されます。

```:例
個人的な校正用スクリプト collar.vim.md

表記ゆれ
表記揺れ

他動
動詞
  :
  :
```

[^3]: baste : \[他動\] ～に仮縫いをする。、～を仕付けする。

## 既知のバグ

全部潰してるはずです…正規表現周りは想定してないのでなにかあるかも…

ところでこういうの、もうあったらどうしよう…
Raspberry Pi 3 Model B+ の USBメモリからのブート

Raspberry Pi 3 Model B+ から USBブートが標準で可能となりましたが、Windowsからインストールする手順について。
特別なことは何も無いです。

PC以外で必要のもの
・Raspberry Pi 3 Model B+
・USBメモリ（16GB以上/MLC推奨）
・最新版のraspbian
・Win32DiskImager

１．最新版のraspbianをダウンロード。
https://www.raspberrypi.org/downloads/raspbian/
２．USBメモリをWindowsPCに挿入。フォーマットはしなくてもOKぽい。
３．イメージファイルを Win32DiskImager でUSBメモリに書き込む。
４．USBメモリをRasPIに挿入して、電源をつないで立ち上げる。多少時間がかかります。

以上！
SceneKitのメモ

SceneKit関連のスニペットや、単体の記事にするほどでもないメモをここに随時書き足していく予定です。

## 3次元計算

### ランダムな3次元単位ベクトルを生成

```swift:Swift
func randomVector3() -> SCNVector3 {
    let rand = SCNVector3(random(min: -1.0, max: 1.0),
                          random(min: -1.0, max: 1.0),
                          random(min: -1.0, max: 1.0))
    return rand.normalized
}
```

いろんなアプローチがあるみたいだが、下記記事を読んだ感じだととりあえずこのシンプルなのでもよさそう。

- http://nbeloglazov.com/2017/04/09/random-vector-generation.html


### 複数軸方向に回転

```swift:swift
let rotX = SCNMatrix4MakeRotation(Float.pi, 1, 0, 0)
let rotZ = SCNMatrix4MakeRotation(Float.pi/2, 0, 0, 1)
node.pivot = SCNMatrix4Mult(rotZ, rotX)
```

```objective_c:objc
SCNMatrix4 rotX = SCNMatrix4MakeRotation(M_PI, 1, 0, 0);
SCNMatrix4 rotZ = SCNMatrix4MakeRotation(M_PI/2, 0, 0, 1);
node.pivot = SCNMatrix4Mult(rotZ, rotX);
```

回転行列の積を`SCNMatrix4Mult`で計算する。

- https://developer.apple.com/documentation/scenekit/1409697-scnmatrix4mult

pivotは**オブジェクトを回転、スケールする際に基準となる点**のこと。型は`SCNMatrix4`。上記の例ではx軸まわりに180°、z軸まわりに90°の回転をpivotとして与えている。

- https://developer.apple.com/documentation/scenekit/scnnode/1408044-pivot


## ヒットテスト

### サーチモード

`SCNHitTestOptionSearchMode`（Swiftでは`SCNHitTestOption.searchMode`）のデフォルトは`SCNHitTestSearchModeClosest`（Swiftでは`.closest`）なので**一番近いのしか返してくれない**。（ドキュメントには書いてないが、実際に値をみてそうなっていた）

- https://forums.developer.apple.com/thread/83700
- https://developer.apple.com/documentation/scenekit/scnhittestoption/2866222-searchmode

全結果を取得には`SCNHitTestSearchModeAll`（.all）を指定する。

```objective_c:objc
NSDictionary<SCNHitTestOption, id> *options = @{SCNHitTestOptionSearchMode: @(SCNHitTestSearchModeAll)};
NSArray<SCNHitTestResult *> *results = [self.renderer hitTest:pos options:options];
```
Rails-erbに<%%= %>こういう書き方あるみたい

# Rails erbの`<%%= %>`の意味



> 「eRuby テンプレートを生成するための eRuby テンプレート」を記述するのに使う 
> by @scivola さん

って感じみたいです！

```bash
$ bin/rails c
[1] pry(main)> ERB.new("<%%= 'hoge' %>").result
=> "<%= 'hoge' %>"
[2] pry(main)> ERB.new("<%= 'hoge' %>").result
=> "hoge"
```

`<%%= %>`はerbを一度展開しても、erbファイルが壊れないようにするためだったみたいです。弊社の開発ではCMSで、設定ファイルをユーザーごとのDBに一度いれたりしているので（適当な理解）何度か展開するみたいです〜

~~詳しい方はコメント欄にコメントください~~

scivolaさんがいい感じにまとめてくれたので引用しました！！！！

以下の内容はポエムです。

## 2週間前くらいにこんなくだりがありました。

> 私の`コピペ`が発掘される

ことの発端はこうです。 

私が意味を知らずに使っていた `<%%= %>` というイディオムを、別の人がPR出したときに話題になりました。。。

（意味わからずコピペしてたのは私だけで、PR出した人は知ってた）

「ふ〜ん。調べても出てこないし、なんかわかんないけど動いてるからこうしておかなきゃ。」

<img width="760" alt="スクリーンショット 2018-05-19 1.20.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/112929/22680566-53d9-e52d-95f4-07f397b6a362.png">

で、今回やっとちゃんと調べました〜〜（エンジニアの風下）

## 参考資料

この記事を書いていたら [erb に Lodash.js (or Underscode.js) の _.template を書くときのエスケープ - Qiita](https://qiita.com/oieioi/items/2ec856e61af20ffcc51b) すでに投稿されてたのでこちら参考にするといいかもです！

こちらの`<%%= %>`が書かれた公式っぽいところはこちらが詳しいみたいです。 [標準添付ライブラリ紹介 【第 10 回】 ERB](https://magazine.rubyist.net/articles/0017/0017-BundledLibraries.html)

## 最後に

普段はコピペしてないですよ（？）
curl で redis のキーの一覧を取得

ローカルの Redis サーバーにアクセスする例です。

次のようなコマンドのスクリプトを用意します。

```text:command.txt
keys *

quit
.
```

## curl で実行した例

```text
$ curl -s telnet://localhost:6379 < command.txt 
*8
$5
t1857
$5
t1851
$5
t1858
$5
t1854
$5
t1853
$5
t1855
$5
t1859
$5
t1852
+OK
```

## redis-cli で実行した例

```text
$ redis-cli < command.txt 
1) "t1857"
2) "t1851"
3) "t1858"
4) "t1854"
5) "t1853"
6) "t1855"
7) "t1859"
8) "t1852"
```

次のコマンドでもキーの一覧が取得できます。

```bash
redis-cli --scan
```

## 確認したバージョン

```text
$ curl --version
curl 8.9.1 (x86_64-pc-linux-gnu) libcurl/8.9.1 OpenSSL/3.3.1 zlib/1.3.1 brotli/1.1.0 zstd/1.5.6 libidn2/2.3.7 libpsl/0.21.2 libssh2/1.11.0 nghttp2/1.62.1 librtmp/2.3 OpenLDAP/2.6.8
Release-Date: 2024-07-31, security patched: 8.9.1-2ubuntu2.2

$ redis-cli --version
redis-cli 7.0.15
```
Installing Truffle(Memo)

I was really stuck to install Truffle. Speaking more, I could completely install Truffle however it did not work at all with obtaining this error:

`command not found: truffle .`

I thought that the pass is missing somehow.

# Measure
### Step 1
To confirm the directly pass of npm.
It would be probably popped up `/usr/local` with execution of `npm config get prefix`.

### Step 2
to change the default directly of npm to another one.
I made a directly for global install
`mkdir ~/.npm-global`

Setting to use a new directly with npm 
`npm config set prefix '~/.npm-global'`

Open or create a `~/.profile` and add below,
`export PATH=~/.npm-global/bin:$PATH`

#Issue
I could not make it with execution above and I obtained same error again.

`command not found: truffle .`

#Solution
It worked correctly with sudo install beta version.
After just uninstall all of package which I have installed and executed below
`sudo npm install -g truffle@beta`

I have already amended the global install directly then, I must make it back to initial setting.

`npm config set prefix '/usr/local'`

It should be checked whether it corrected just in case.
`npm config get prefix.`
【PHP】文字列を繰り返し表示（_/_/_/_/_/_/...など）したい！→str_repeat()関数を使おう

###文字列を繰り返し表示するには？→str_repeat()関数
str_repeat()関数→**指定した文字列を指定回数分繰り返した文字列を出力。**

```php5:repeat_string.php

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>文字列を繰り返し表示する</title>
	<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
</head>
<body>
<?php
echo "<p>「*」を15回繰り返す</p>";
// str_repeat(繰り返す文字列, 繰り返す回数)
echo "<p>".str_repeat('*', 15)."</p>";
// 出力結果→「***************」
echo "<p>「_/」を10回繰り返す</p>";
echo "<p>".str_repeat('_/', 10)."</p>";
// 出力結果→「_/_/_/_/_/_/_/_/_/_/」
 ?>
</body>
</html>
```
以上です。押忍！
カスタムジオメトリに法線やテクスチャ座標の情報を追加する／SCNProgramをカスタムジオメトリを持つノードに適用する際の注意点

## "Vertex attribute {index} is not defined in the vertex descriptor."エラー

SCNProgramをあるマテリアルに適用しようとしたところ、こんなエラーが出た。

> Error Domain=AGXMetalA11 Code=3 "Vertex attribute 6 is not defined in the vertex descriptor."

「Vertex attribbute 6がvertex descriptorで定義されてない」とのこと。「Vertex attribute」（Vertex属性）の一覧は[SCNProgramのドキュメント](https://developer.apple.com/documentation/scenekit/scnprogram)内にある。


- SCNVertexSemanticPosition
- SCNVertexSemanticNormal
- SCNVertexSemanticTangent
- SCNVertexSemanticColor
- SCNVertexSemanticSkinJoints
- SCNVertexSemanticSkinWeights
- SCNVertexSemanticTexcoord0
- SCNVertexSemanticTexcoord1
- SCNVertexSemanticTexcoord2
- SCNVertexSemanticTexcoord3

リストを0から数えていって6にあたるものを見ると、`SCNVertexSemanticTexcoord0`が該当する。

で、確かに自分のコードではSCNProgramで処理するシェーダ内で

```cpp:Shaders.metal
float2 texCoords [[attribute(SCNVertexSemanticTexcoord0)]];
```

を頂点シェーダの入力の構造体の要素に指定していた。

```cpp:Shaders.metal
struct VertexInput {
    float3 position [[ attribute(SCNVertexSemanticPosition) ]];
    float2 texCoords [[attribute(SCNVertexSemanticTexcoord0)]];
};
```

```cpp:Shaders.metal
vertex ColorInOut vertexShader(VertexInput in [[ stage_in ]],
                               ...
```

## 原因はカスタムジオメトリ

試しに`SCNVertexSemanticNormal`属性の要素を追加してみると、

```cpp:Shaders.metal
struct VertexInput {
    float3 position [[ attribute(SCNVertexSemanticPosition) ]];
    float3 normal   [[ attribute(SCNVertexSemanticNormal) ]];
};
```

それに準じたインデックスのエラーが出る。

> "Vertex attribute 1 is not defined in the vertex descriptor."

問題発生要因を切り分けていった結果、どうやらこの**Vertex属性がカスタムジオメトリでは効いてない**ようだった。

ドキュメントで明言されているかはわからないが、`SCNGeometrySource`, `SCNGeometryElement`を使用して独自のジオメトリを形成している場合に、法線情報やテクスチャ座標情報を自動でシェーダに渡してくれない、というのは確かにそれはそうだろうな、という挙動ではある。


## 対策: 必要なセマンティックのジオメトリソースを用意する

上にも載せた`SCNVertexSemanticNormal`の解説をちゃんと読むと、

> The surface normal vector at the vertex, **provided by the geometry source for the normal semantic**.

とあって、ジオメトリソースから供給されるようだ。

試しに

```swift
let source = SCNGeometrySource(vertices: vertices)
print("semantic: \(source.semantic)")
```

をやってみると

> semantic: Semantic(_rawValue: kGeometrySourceSemanticVertex)

と出力されたので、normal semanticなGeometrySourceを追加しないといけないということらしい。


## 実装

法線ベクトルを自前で計算し（ここはまた別の長い話になるので割愛）、`SCNGeometrySource`を作成する。

```swift
let sourceNormal = SCNGeometrySource(normals: normals)
```

`SCNGeometry`を初期化する歳にジオメトリソースとして渡す。

```swift
geometry = SCNGeometry(sources: [sourceVertices, sourceNormal], elements: [element])
```

## 所感

3Dプログラミングに慣れている人には「何を当たり前なことを。。」という話なのかもしれないが、SceneKitが知らないうちにどういうことをやってくれているのか、というところへの理解が進んだのでなかなか良いエラーに出会えたなと。

## 関連記事

- [MetalシェーダでSceneKitのマテリアルを描画する - Qiita](https://qiita.com/shu223/items/b5729fdf1d95721d07b7)
multiagent-competitionの手入れ

使ったパソコン：windows7
　

※この文書はテストで書いてる
https://qiita.com/oruchin1122/items/33d862d064954b330a7d から続きます
#####コンソールのDRAG
コンソール右クリックしてメーニュからコンソールのテキストをドラッグすることが出来る
また右クリックをすると、ドラッグが終わり、ドラックしていたテキストがctrl+cをした（コピーした）状態と、
同じになる

##gym[atari]ダウン
前回の文書ではwindows10の場合、あれで終わるが
windows7はバグが出ちゃう。設定しよ で、gym[atari]ダウンしよ

　
```pip install gym[atari]```これwindows7だったらバグってダウンできん
バグってすぐ、
```pip install -U git+https://github.com/Kojoley/atari-py.git```
zlibとかでバグ出ると ```conda install -c anaconda zlib```した後やる
他の時も、zlibとかでバグると、やる
gymバグ出ると```pip install gym```
atari-pyがダウン終わると、完　　　　　```pip install gym[atari]```でバグ出ないと、この話は無視
　
##mujocoつかう
ライセンス
https://www.roboti.us/license.html 　ここでstudent版でlicense持ったり、proの30日版を体験するとか
licenseを手に入れ、License.txtとmjkey.txtが入れる
**mjpro**
https://www.roboti.us/ 　ここで、mjpro150自分のOSのをダウン(32bit(86bit)もあるが、64bitもある)
C:/Users/○○/のフォルダに.mujocoの名前のフォルダを.mujoco.と名前で書いて作れるので、作り
mjpro150を入れて.mujoco/mjpro150/bin/フォルダにLicense.txtとmjkey.txtを入れる

PATH設定

unix系コマンドで```export PATH="C:/Users/emiya/.mujoco/mjpro150/bin;$PATH"```
PATH問題があるので書く。バグ出る場合```export PATH="C:/Users/emiya/.mujoco/mjpro150/bin:$PATH"```
も書いてみる。このコマンドはPATHを追加するコマンド


なんか出来なかったら```pip install tensorflow==1.1.0.```をやる
```bash demo_tasks.sh all self```で
```python not found```が出ると
完
PATHバグが出るとmjpro○○○が欲しいとか言ったりするとそれダウンしてPATH設定も同じくする


##次は使い方やるねー
demo_tasks.sh中、の全demoがmain.pyになってgymになっていて、gym,mujocoを参考するのも良い
Prism入門 その2 - NavigationService

## はじめに

Prism入門2回目です。

今回は画面遷移を行うためのNavigationServiceについて説明します。

Xamarin.Formsでは画面遷移にNavigation.PushAsyncを使用します。
ただ、このメソッドはContentPageクラスのメソッドであり、MVVMの層でいうとViewに存在します。
Viewは画面を描画する機能しか持たないのに画面遷移の機能をViewで行うのはおかしいです。

そこで、XamarinにはNavigationServiceという機能が存在します。
これはViewModelで画面遷移を行えるようにする機能です。

一旦、画面遷移はViewModelでやるべきか、という話は置いておきましょう。

今回はNavigationServiceについて説明します。

### NavigationServiceの生成と使用

NavigationServiceはコンストラクタの引数に 
```INavigationService navigationService``` と記述すると
自動的にクラスが生成された時にNavigationServiceも生成されます。

コンストラクタ内で画面遷移を行うことはまずないので、メンバー変数に保存しておきます。

```cs
public class MainPageViewModel : BindableBase, INavigationAware
{
    INavigationService navigationService = null;

    public MainPageViewModel(INavigationService navigationService)
    {
        this.navigationService = navigationService;
    }
}
```

画面遷移する時は引数に遷移する先のViewのクラス名を指定します。
今回はNextPageに遷移するとします。

```cs
navigationService.NavigateAsync("NextPage");
```

これだけでは動きません。NextPageを遷移先として登録する必要があります。
登録はAppのRegisterTypes(IContainerRegistry containerRegistry)で行います。

```cs
public partial class App : PrismApplication
    {
        public App(IPlatformInitializer initializer = null) : base(initializer) { }

        protected override void OnInitialized()
        {
            InitializeComponent();

            NavigationService.NavigateAsync("MainPage");
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<MainPage>();
            containerRegistry.RegisterForNavigation<NextPage>();
        }
    }
```

登録すると、NavigationServiceで画面遷移を行えるようになります。
文字列で画面遷移を行なっているため、画面同士は疎であると言えます。
（実際のところ文字列で指定しているので完璧に疎かと言われると微妙ですが）

## 遷移イベントとデータの受け渡し

画面遷移する時に下記のメソッドが呼び出されます。
画面Aから画面Bに移動しようとすると、
AのOnNavigatedFrom、BのOnNavigatingTo、Bの画面表示、BのOnNavigatedToの
順番に呼び出されます。
遷移するときの初期化や終了処理をここに書くと便利でしょう。
ただ、特定の条件（物理バックキー等）で遷移した時は呼び出されないので注意してください。
それらの条件については、OnNavigatingTo等のキーワードで検索すると見つかります。

```cs
public void OnNavigatedFrom(NavigationParameters parameters) {}

public void OnNavigatedTo(NavigationParameters parameters) {}

public void OnNavigatingTo(NavigationParameters parameters) {}
```

これらのメソッドはINavigationAwareのインターフェースで定義されています。
テンプレートでは最初からインターフェースが適用されてますが、自分でゼロから
書くときは、INavigationAwareを書き忘れないようにしましょう。

画面遷移するときに画面間でパラメーターを渡すこともできます。

遷移元ではnavigationParametersに値を加えます。

```cs
var navigationParameters = new NavigationParameters();
navigationParameters.Add("Key", "Value");
navigationService.NavigateAsync("NextPage", navigationParameters);
```

遷移先のOnNavigatedToやOnNavigatingToで受け取ります。

```cs
if (parameters.ContainsKey("Key")) {
    // なんらかの処理
}
```

遷移するときのアドレスの文字列に値を指定することもできます。

### 最後に

今回は機能の一部のみを紹介しました。
紹介してない機能として戻るの実装や画面遷移のキャンセルといった機能もあります。
興味あったら他の資料を探してみてください。
ライセンスについて

# はじめに
OSS-DB取得を目指してPostgreSQLの勉強を本格的に始めました。技術とは少し違いますが、ライセンスについて知っておくが必要があったためまとめます。

# ライセンスとは何か
一般的には許可や権利のことを指しますが、コンピュータソフトウェアの世界では「利用者が守らなければいけない項目を記した文書」をライセンスと呼びます。

# PostgreSQLのライセンス
https://www.postgresql.org/about/licence/
公式Webページの一行目には「BSDあるいはMITに類似の（訳注：しかし別物の）PostgreSQL License」に準拠していると記述があります。二行目以降が実際のライセンス文面です。著作権表示に続いて、六行目には以下のように記載されています。
・本ライセンス文書全体を残すことを条件に、自由に利用、複製、改変、再配布を行っても良い。
（注：少し意訳しています。）
七行目以降は免責事項です。

これがなぜ「BSDあるいはMITに類似の」と敢えて記載されているについては、BSDライセンスを勉強する必要があります。

# BSDライセンス
詳細はWikipedia等に。単にBSDライセンスと書く場合には、「修正BSDライセンス」のことであると思っておけば良さそうです。利用条件、免責事項ともにほぼ同等の内容に見えます。違いがあるのかどうか良くわからないレベルです。。。

# GPLライセンス
BSDライセンスと比較されることの多いGPLライセンスについては、以下の特徴があります。
・プログラム（バイナリ）だけではなく、ソースコードを提供しなければならない
・オリジナルのプログラムを改変する場合、改変後のプログラムもGPLライセンスに従わなければならない

ソースコード提供の義務、および改変後のライセンス制限のため、BSDライセンスよりも制限が厳しいものとなっています。
SBCLでバイト列から文字列への変換で詰まった話

SBCLでバイト列から文字列への変換で詰まった。

```common_lisp:octets-to-string_test_error.lisp
(sb-ext:octets-to-string #(102 111 111) :external-format :utf-8)
```
そうすると以下のエラーが出る。

```
#<THREAD "main thread" RUNNING {10005605B3}>:
  The value
    #(102 111 111)
  is not of type
    (VECTOR (UNSIGNED-BYTE 8))
  when binding VECTOR
```

どうもunsigned-byte型のベクトルじゃないとダメらしい。

```common_lisp:octets-to-string_test.lisp
(sb-ext:octets-to-string (concatenate '(vector (unsigned-byte 8)) #(102 111 111)) :external-format :utf-8)
```
古くからあるBitBucketのGitリポジトリをコピーしたら劇的に早くなった話

# まとめ
Gitのremote通信が重くなって困っていたのですが
repositoryを新規作成して、コピーしてから元のrepositoryと名前を差し替えると
劇的に軽くなり、repository利用者側での再取得も不要でした。

**2019/8/24追記**
BitBucketのバグで、pull-requestをdeleteした場合に場合に参照が残り続けてしまう、というのが原因でした。
リモート側リポジトリに残っている参照情報を消す権限があればそれだけで解決します。
修正後のBitBucketバージョンであれば新規に発生はしませんが、過去に消しそびれた参照情報は残り続けるようです。
https://jira.atlassian.com/browse/BSERV-10708


# 背景
BitBucketをJira, Confluenceと連携して、git-flowで運用しています。
運用4年ほどで20,000 commitに8000 pull-request程度。
最近重くなって来ており、fetchで10秒かかることもあったので調査することにしました。

# 原因の切り分け
- git commitやgit log、その他ローカルで完結する作業は問題無し
- git fetch、push、その他remote通信する作業は重い
- git gc --aggressive 目に見える効果無し
- git prune 普段からやっているので当然効果無し
- 新規pull-request作成時、branch候補の表示が重いが、少しでも絞り込むと軽い
- 同じプロジェクトの別のrepositoryは、remote通信も軽い

# アプローチ
とりあえずネットワークの問題ではなさそうと判断し
正攻法のsub module化、あるいは大きめファイルのgit-filter削除を検討。
検証用repositoryを作成し、既存repositoryのremoteを切り替えてpushしたところ圧倒的に早い！

# 移行実施
1. 関係者にremote repositoryを触らないように連絡
1. pull-requestを全部消化
1. 不要なremote branchがあれば削除
1. 移行先repositoryを作成
1. [atlassianの手順](https://developer.atlassian.com/blog/2016/01/totw-copying-a-full-git-repo/)通りにコピー
1. 移行元repositoryの名前をバックアップ用に変更
1. 移行先repositoryを移行元repositoryの元の名前に変更
1. 関係者に解禁のお知らせ出して終わり

# 速度変化
git fetch(2回目): 0m13.386s -> 0m0.400s
git push(新規ファイル追加その１): 0m27.705s -> 0m0.749s
git push(新規ファイル追加その２): 0m40.340s -> 0m0.983s

# 注意点
pull-requestは移行できませんでした。
JIRAからの参照時、旧repositoryを残しておけばそちらへのpull-requestの参照は残りますが、
逆にcommitへの参照は二重に残ってしまいます。

~~また、早くなった原因が不明です。
推測としてはremote側のrepositoryに何かしらのゴミが溜まってる、
あるいはpull-request自体が非常に重い、のどちらかだとは思うのですが。~~

あやふやで恐縮ですが、何かのお役に立てば幸いです。

# 参考
[How to move a full Git repository](https://developer.atlassian.com/blog/2016/01/totw-copying-a-full-git-repo/)
セキュリティ関連文書・リンクのまとめ

# 目的
設計、プログラミング、顧客説明等、様々なタイミングでセキュリティに関する調査を行います。
その都度、探さずに済むようリンクをまとめます。

2021/06/21 CCPA欄を追加、個人情報保護委員会(PPC)の役立ちそうなページを追加

# セキュリティ設計
IPA 情報セキュリティ対策
https://www.ipa.go.jp/security/measures/index.html
ISMS(情報セキュリティマネジメントシステム)
https://isms.jp/
NIST CSF(IPA 翻訳版)
https://www.ipa.go.jp/files/000071204.pdf
PPCビジネスサポートデスク（要予約）
> 個人情報保護委員会では、事業者における個人情報の保護及び適正かつ効果的な活用についての啓発の一環として、新技術を用いた新たなビジネスモデル等における個人情報保護法上の留意事項等について、相談を行っています。

https://www.ppc.go.jp/personalinfo/business_support/


# 脆弱性対策
IPA 脆弱性対策(脆弱性対応ガイドライン等)
https://www.ipa.go.jp/security/vuln/index.html#section1
日本ネットワークセキュリティ教会
http://www.jnsa.org/

# プログラミング
JPCERT/CC セキュアコーディング
https://www.jpcert.or.jp/securecoding/
IPA セキュアプログラミング講座(掲載が少し古い)
https://www.ipa.go.jp/security/awareness/vendor/programmingv2/index.html
IPA 普及啓発資料(安全なウェブサイトの作り方、安全なSQLの呼び出し方、等々)
https://www.ipa.go.jp/security/vuln/index.html#section20

# ペネトレーションテスト
PCI DSS Penetration Testing Guidance(ペネトレーションテストと脆弱性診断の違い、必要資格、等)
https://www.pcisecuritystandards.org/document_library

# 脆弱性情報の収集
JVN
https://jvn.jp/
IPA 脆弱性対策(脆弱性の新着情報)
https://www.ipa.go.jp/security/vuln/index.html#section2
＠police(警察庁)(インターネット定点観測情報がある)
https://www.npa.go.jp/cyberpolice/
OWASP TOP 10
https://www.owasp.org/images/2/23/OWASP_Top_10-2017%28ja%29.pdf
LAC（注意喚起）
https://www.lac.co.jp/lacwatch/alert/



# 文書体系
NISTのSPシリーズ（SPシリーズ以外もあり気になる）
https://csrc.nist.gov/publications/sp
IPAの日本語翻訳済みNIST文書
https://www.ipa.go.jp/security/publications/nist/index.html
PCIDSS（Payment Card Industry Data Security Standard）※日本語版あり
https://www.pcisecuritystandards.org/document_library
日本カード情報セキュリティ協議会
http://www.jcdsc.org/index.php

# セキュリティーブログ
Microsoft 日本セキュリティチームのブログ
https://blogs.technet.microsoft.com/jpsecurity/
NIST サイバーセキュリティフレームワーク
https://www.secure-sketch.com/blog/nist-cybersecurity-framework

イギリス NCSC https://www.ncsc.gov.uk/
オーストラリア ACSC https://www.cyber.gov.au/acsc/

警察庁 https://www.npa.go.jp/cyber/
総務省 http://www.soumu.go.jp/menu_news/s-news/01cyber01_02000001_00001.html
経産省 https://www.meti.go.jp/policy/netsecurity/mng_guide.html
有名なOSS界隈だと
OWASP https://owasp.org/

# CCPA

個人情報保護委員会
[米国「カリフォルニア州消費者プライバシー法  2018年」](https://www.ppc.go.jp/enforcement/infoprovision/laws/CCPA/)

後で見るメモ
https://www.jnsa.org/result/incident/2018.html
https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-858-computer-systems-security-fall-2014/index.htm
https://www.ipa.go.jp/security/publications/hakusyo/2019.html
Data Protection Best Practice (IIC)​
<https://www.iiconsortium.org/pdf/Data_Protection_Best_Practices_Whitepaper_2019-07-22.pdf>
pandasノススメ -一行ずつ処理させないでください、死んでしまいます-

# はじめに
pandasはcsvやexcelを扱うのに非常に便利なものである。
過去記事にも書いてる（ステマ）
https://qiita.com/open_cans/items/c1568eaf497bd82cdf29

pandasが得意なことは上記記事にある内容だが、苦手なこともある。
pandasが苦手な処理を知らずに書いてしまうと処理時間が非常に遅くなったりするのでちゃんと知っておくといいですよ。というのと私のやってる対処策をtipsとして紹介しようというお話。

# df[df["hoge"]==hoge]を毎行するのは苦手
例えばユーザーのリストがあってpandasに読み込んだcsvから各ユーザーのデータを抽出したい場面は結構ある。

以下にやってはダメな例を書く
ここにユーザーのログがまとめられたcsvがあるとする。
中身はuser_id列とその他の列があり全体の行数は1452000である。

```python
import pandas as pd

data = pd.read_csv("log.csv")

start = time()
user_list = list(set(data["user_id"]))
check_pd=[]
for user in user_list:
    check_pd.append(data[data["user_id"]==int(user)])
print(time()-start)

```
> 145.19093585014343

上記のような死が待っている。

## 対処. groupbyを使う
groupbyを使う対処を示す。

``` python
import pandas as pd

start = time()
check_pd=[row for index, row in data.groupby("user_id")]
print(time()-start)

```
> 6.244393348693848
圧倒的じゃないか我が軍は！

groupbyの中身がDataFrameの集合だと気付いてから色々捗るようになった。

# iterrowsを使って毎行処理をする
死ぬ

``` python
start = time()
for index,row in data.iterrows():
    pass
print(time()-start)
```
>43.601510524749756

そもそもpandasは一行ずつ処理をするのに向いていない説がある。

## 対処 numpyにする
numpy配列に一度変換し、処理を行い、またpandasに戻したほうがはやいこともある。

``` python
import numpy as np
start = time()
data_np = np.asarray(data)
for row in data_np:
    pass
data = pd.DataFrame(data_np)
print(time()-start)
```
>0.4787719249725342

100倍速
iTerm2で新しいTabでコマンドを実行するやり方

調べたから出なかったので、AppleScriptが初心者すぎるけど書いてみたらなんとか動いたのでシェア

```bash
osascript -e 'tell application "iTerm2" to tell current window \
           to set TAB to create tab with default profile'\
          -e 'tell application "iTerm2" to tell current window\
           to tell current session of TAB to write text \
           "***SOME COMMAND***"'

```

もっと良い書き方を教えて欲しいので書きました。。
mp3をdownloadせずにPythonからGoogleHomeを喋らせる

Python から GoogleHome を喋らせようと調べたところ、こちらの記事が見つかりました。
　[Pythonを使って、Google Homeに喋らせてみる](https://qiita.com/attakei/items/c5de47f3c1f53992c353)
しかし使用する `gTTS` は指定したテキストを mp3 ファイルとして download するライブラリであるため、
それを `bottle` や `Flask` などのWebフレームワークを使って URL としてアクセスできる状態にして
GoogleHome に渡す、という形になっています。
もちろんそれでも喋りますが、RaspberryPi の場合に SDカードへの書き込みを増やしたくなかったので、
gTTS のコードを参考に mp3 を download する前の URL を直接 GoogleHome に渡すコードを書いてみました。
# 必要なライブラリ
* pychromecast
* gTTS_token

gtts_token は gTTS からも使っているライブラリで、google翻訳用のトークンを生成してくれます。
# 実行用コード
```python
import pychromecast
from gtts_token import gtts_token
import urllib.parse

googlehome_name = "MyDevice"

chromecasts = pychromecast.get_chromecasts()
cast = next(cc for cc in chromecasts if cc.device.friendly_name == googlehome_name)

def play_tts(text, lang='ja'):
    token = gtts_token.Token()
    tk = token.calculate_token(text)

    payload = {
        'ie' : 'UTF-8',
        'q' : text,
        'tl' : lang,
        'total' : 1,
        'idx' : 0,
        'textlen' : len(text),
        'tk' : tk,
        'client' : 't',
        'ttsspeed' : 1.0
    }

    params = urllib.parse.urlencode(payload, quote_via=urllib.parse.quote)
    url = 'https://translate.google.com/translate_tts?{}'.format(params)

    cast.wait()
    mc = cast.media_controller
    mc.play_media(url, 'audio/mp3')
```
# 使い方
説明するまでもないですが、`googlehome_name` に喋らせたい GoogleHome の名前を入れた上で
play_tts() を呼び出せばそのとおりに喋ります。
google翻訳の制約か何かで gTTS は 100文字ずつに分解してリクエストしてファイルに書き出すことを
繰り返していますが、このコードはそんなことはしていませんので、適切な長さの文章を都度渡して
喋らせる必要があります。
Redashに登録したクエリの結果をSlackで展開して表示する

# 背景
定期的に確認したいデータを取得するクエリをRedash(https://redash.io/) に登録したものの、 
リマインド登録されたURLに毎度アクセスするのがめんどくさくなってしまった人向けのもの。

# やりたいこと
### before:
<img width="786" alt="68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3230373634352f31633731343034302d636261622d343238322d663963642d6334383830613939343435612e706e67.png" src="https://qiita-image-store.s3.amazonaws.com/0/207645/593d8a63-8103-b1c9-8bb9-ca032fd2894e.png">

↑のようにURLがリマインドされても内容は展開はされない。

### after:
<img width="775" alt="Slack_-_valus2.png" src="https://qiita-image-store.s3.amazonaws.com/0/207645/b6d61b76-5185-e585-9f10-b2086298ef8a.png">
リマインドされたURLを元にredashAPPが画像を展開してくれる。
サイトにアクセスせずに済んで嬉しい :)

#　やりかた
### slackにRedashAppを追加する
https://redash.io/slack
からRedashAppをSlackのチームに追加する。
<img width="1165" alt="Make_Your_Company_Data_Driven___Redash.png" src="https://qiita-image-store.s3.amazonaws.com/0/207645/6f5eb42b-c108-7131-355f-f7f2166019c0.png">
<img width="491" alt="Authorize_access_to_your_account___valus_Slack.png" src="https://qiita-image-store.s3.amazonaws.com/0/207645/ed88bdef-bcbd-f25b-ae53-a6294e495ddc.png">

### slcakから対話形式に設定をする
RedashのURLとAPIを答えます。
<img width="607" alt="Slack_-_valus.png" src="https://qiita-image-store.s3.amazonaws.com/0/207645/96c03b52-5e0d-15e7-4fd1-7a129bcb575f.png">

以上の設定をするだけでグラフの結果を展開してくれるようになります、便利ですね:)
ブラウザのJavascriptでクラス＋継承＋モジュールを使う（2018.05）

[主要ブラウザの進化](https://caniuse.com/#feat=es6-module)によって、Babelのようなトランスパイラ無して、ブラウザ上のJavaScriptでもクラス＋継承＋モジュールが使えるようになりました。

これは、動作確認のためのサンプルコードです。

## 親クラス（module_animal.js）

```javascript
// module_animal.js
export class Animal {
    constructor(name) {
        this._name = name;
    }
    set name(name) {
        this._name = name;
    }
    get name() {
        return this._name;
    }
    sayHello() {
        return `BARK ${this.name}`;
    }
}
```

## 子クラス（module_cat.js）

親クラスのモジュールを、ここで読み込んでいる。変数と関数も定義してみた。

```javascript
// module_cat.js
import { Animal } from "./module_animal.js";

export { message };

const message = "hello world,";

export class Cat extends Animal {
    constructor(name) {
        super(name);
    }
    sayHello() {
        return `Nyaa ${this.name}`;
    }
}

export function sayGoodby() {
    return "Goodby Baby";
}
```

## index.js(個別にインポート)

モジュールの変数・クラス・(関数)をインポート。インポート時に指定した名前で呼び出しできる。

```javascript
// index.js
import { message } from "./module_cat.js";
import { Cat } from "./module_cat.js";
import { sayGoodby } from "./module_cat.js";

const el_1 = document.getElementById('box1');
const el_2 = document.getElementById('box2');

const tama = new Cat("tama");
tama.name = "タマ";
alert(tama.sayHello());

el_1.textContent = message + tama.name;
el_2.textContent = sayGoodby();
```

## index.js(モジュールでまとめてインポート)

モジュール全体を一括してimport。モジュール名(mcat)を名前空間にして、アクセスできる。

```javascript
// index.js
import * as m from "./module_cat.js";

const el_1 = document.getElementById('box1');
const el_2 = document.getElementById('box2');

const tama = new mcat.Cat("tama");
tama.name = "タマ";
alert(tama.sayHello());

el_1.textContent = mcat.message + tama.name;
el_2.textContent = mcat.sayGoodby();
```

## HTML

scriptタグで、type="module"を指定する

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>JavaScript Class-Object example</title>
    <link rel="stylesheet" href="style.css"></link>
  </head>

  <body>
    <p id='box1'></p>
    <p id='box2'></p>
    <script type="module" src="./index.js"></script>
  </body>
</html>
```

## 感想

JSに付き物のツールチェーンが、いくつか不要になって、いやー便利。

ダウンロードするファイルがひとつにまとまっていないけど、そこはHTTP/2の多重化でお願いしたい(そうでも、ないらしい)。

- Using JavaScript modules on the web  |  Web Fundamentals  |  Google Developers
 - https://developers.google.com/web/fundamentals/primers/modules

## 参考になるページ

- ブラウザで覚えるES Modules入門 - JavaScriptでモジュールを使う時代 - ICS MEDIA
 - https://ics.media/entry/16511

- import - JavaScript | MDN
 - https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/import

- export - JavaScript | MDN
 - https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/export
EMアルゴリズムを実装した

## EMアルゴリズムを実装したました。
[GitHub](https://github.com/be-kan/em_algorithm)にソースコードをあげています。

EMアルゴリズムは、混合ガウスモデルの生成に用いられます。
簡単にまとめると、ある標本をN個のガウスモデルが混合したものとみなし、それぞれのモデルの重み/平均/分散を求めることでその標本を説明しようというものです。

パラメータ（重み/平均/分散）に適当な初期値を設け、それを評価するような関数(Q関数)を定め、Q関数がモデルに近づいていくようにパラメータを更新して行くのがEMアルゴリズムであり、その更新の過程が以下のExpectationステップとMaximizationステップなのでEMと呼ばれています。

・Expectationステップ： 隠れ変数（負荷率）の事後確率を推定するステップ
・Maximizationステップ： Eステップで求めた事後確率から、Q関数を最小化するようなパラメータを求めるステップ

僕が行った実装では、以下の標本を、33回のEMステップでモデルを生成できました。

<img width="400" alt="スクリーンショット 2018-05-21 1.15.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/196673/1a5e24f4-0c88-e897-a9e6-783c560ccc09.png">

<img width="400" alt="スクリーンショット 2018-05-21 1.15.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/196673/ad03f3a1-292f-0203-c00b-b1b7643b90cb.png">

## 参考
[pythonで混合正規分布実装](https://qiita.com/ta-ka/items/3e8b127620ac92a32864)
RaspberryPi3上にMattermostをインストールする方法


#はじめに
クローズドな開発環境にて、RaspberryPi3にチャットサーバをインストールした際の手順を、以下に残します。
チャットサーバは、SlackクローンであるMattermostを選択したのですが、公式にはARM対応がされていませんでした・・。
色々サイトを見て回り、ARM版をgithubに載せているかたがいらっしゃいました。本当に感謝です。
他の方の参考になればと思います。

#環境
>Hardware : RaspberryPi3
>OS : Ubuntu MATE 16.04
>DB : MySQL 5.7

#インストール手順
詳細なインストール手順は、Mattermostの公式サイトをご参照ください。
インストールの最短ルートを以下に示します。
※DBのIDやパスワード、DB名は暫定として記入していますが、別途ご検討ください。

##0.事前準備
```
$ sudo apt-get update
$ sudo apt-get upgrade
```

##1.必要なパッケージのインストール
```
$ sudo apt-get install wget
$ sudo apt-get install mysql-server
※mysqlのインストール中に、rootのパスワードを入力します。暫定として「mysqlroot」とします。
```

##2.MySQLの設定
```
$ mysql -u root -p
※rootパスワードを要求されます。mysqlrootと入力します。
```

```
mysql> create user 'mmuser'@'%' identified by 'mmuser-password';
※mmuserの登録、mmuserのパスワードを設定します。
 パスワードは暫定として「mmuser-password」とします。
```

```
mysql> create database mattermost;
※DB名は、暫定として「mattermost」とします。

mysql> grant all privileges on mattermost.* to 'mmuser'@'%';

mysql> GRANT ALTER, CREATE, DELETE, DROP, INDEX, INSERT, SELECT, UPDATE ON mattermost.* TO 'mmuser'@'%';

mysql> exit
```


##3.Mattermostをインストール
こちらのファイルを使わせていただきました。
https://github.com/SmartHoneybee/ubiquitous-memory/releases

```
$ cd ~/

$ wget https://github.com/SmartHoneybee/ubiquitous-memory/releases/download/untagged-e5b3d8052fc39cbf9f41/mattermost-4.10.0-arm.tar.gz

$ tar -xvzf mattermost*.gz

$ sudo mv mattermost /opt

$ sudo mkdir /opt/mattermost/data

$ sudo useradd --system --user-group mattermost

$ sudo chown -R mattermost:mattermost /opt/mattermost

$ sudo chmod -R g+w /opt/mattermost
```

##4.Mattermostの設定ファイル変更
DBの接続設定変更

```
$ sudo vi /opt/mattermost/config/config.json
```

"sqlSettings"を探し、以下を変更します。

```
	"DriverName" : "mysql"
	"DataSource" : "mmuser:<mmuser-password>@tcp(<host-name-or-IP>:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s&writeTimeout=30s"
         ↓
	"DriverName" : "mysql"
	"DataSource" : "mmuser:mmuser-password@tcp(localhost:3306)/mattermost?charset=utf8mb4,utf8&readTimeout=30s&writeTimeout=30s"
```

##5.Mattermostの実行

```
$ cd /opt/mattermost
$ sudo -u mattermost ./bin/platform
```

初回起動には時間がかかりますので、しばらく待ちます。

RaspberryPi3上のブラウザから、「http://localhost:8065」、
他のPCのブラウザから、「http://RaspberryPi3のipアドレス:8065」にアクセスし、
Mattermostの画面が表示されれば成功です。

以上となります。
webpack で TypeScript プロジェクトをビルドする際の設定

[TypeScript](https://www.typescriptlang.org/) で記述されたプロジェクトを [webpack](https://webpack.js.org/) でビルドする際に利用するパッケージや webpack のプラグインについて。

## [ts-node](https://github.com/TypeStrong/ts-node)
webpack の設定ファイルも TypeScript で記述可能になる。詳細は [こちら](https://webpack.js.org/configuration/configuration-languages/#typescript) を参照。

## [tslint](https://palantir.github.io/tslint/)
TypeScript 用の lint ツール。

## [tslint-react](https://github.com/palantir/tslint-react)
TypeScript を利用した [React](https://reactjs.org/) プロジェクト用の tslint 用ルール。

## [tslint-config-prettier](https://github.com/alexjoverm/tslint-config-prettier)
[prettier](https://github.com/prettier/prettier) と tslint の設定がコンフリクトしないように tslint 側の prettier と被る設定を無効にしてくれるルール。

## [ts-loader](https://github.com/TypeStrong/ts-loader)
TypeScript を JavaScript に変換する webpack プラグイン。型チェックはこれにやらせずに、下記の [fork-ts-checker-plugin](#fork-ts-checker-plugin) で行う。型チェックを別プロセスで行い速度を早めた同様のものに [awesome-typescript-loader](https://github.com/s-panferov/awesome-typescript-loader) というのがあるが、 [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/integrating-with-build-tools.html#webpack) や Microsoft謹製 [TypeScript-React-Starter](https://github.com/Microsoft/TypeScript-React-Starter) などではこちらが利用されている。

## [fork-ts-checker-webpack-plugin](https://github.com/Realytics/fork-ts-checker-webpack-plugin)

TypeScript の型チェックを行う webpack プラグイン。 上記 ts-loader との組み合わせで利用。 組み合せでの設定方法は [こちら](https://github.com/Realytics/fork-ts-checker-webpack-plugin#installation) を参照。
[tslint](#tslint) もこれから呼び出せる。呼び出し方は [こちら](https://github.com/Realytics/fork-ts-checker-webpack-plugin#tslint) を参照。

## [tsconfig-paths-webpack-plugin](https://github.com/dividab/tsconfig-paths-webpack-plugin)

`tsconfig.json` の `paths` に記述されたモジュールを解決するための webpack プラグイン。 これ入れとかないと `paths` で設定したエイリアスでのモジュール解決ができない。

## [ts-jest](https://github.com/kulshekhar/ts-jest)
[Jest](https://facebook.github.io/jest/) でテストする際のトランスパイラ。設定方法は [こちら] (https://github.com/kulshekhar/ts-jest#usage) を参照。
Flaskのsessionを使ってショッピングカートを実装してみる

まずは、application.pyにAPI routeを新規作成します。

```python
from flask import Flask, jsonify, render_template, make_response, request, session
from flask_cors import CORS
import json

@application.route('/api/add_to_cart', methods=['POST'])
def add_to_cart():
    item = json.loads(request.data.decode('utf-8'))
```
POSTでクライアントサイドからデータ（カートに入れる商品）を受け取ります。
日本語が入っている場合は、`decode('utf-8')`でデコードしてあげる必要がありますが、デコードするとString型になってしまった、キーで値を取得できなくなってしまうので、`json.loads`でJSONに戻してあげます。

```python
    # セッションの中に'cart_items'が無かったら初期化してあげる
    
    if 'cart_items' not in session:
        session['cart_items'] = []
    cart_list = session['cart_items']
```
この時点で、変数`cart_list`は、以下のどちらかの値が入っています。

⑴ カートに何も入っていなかった場合：`[]`が代入される。
⑵ カートにすでに何か入っていた場合：`[{item_id: 99, color: 'red', size: 'XS'}]`のような値が代入される。


```python 
    cart_list.append(item)
    session['cart_items'] = cart_list
```
変数`cart_list`を初期化した後は、クライアントサイドから受け取った`item`をappendして、`session['cart_items']`に入れてあげます。

基本的にはこんなシンプルな感じですが、いざ実装しようとすると意外に悩んだりするので、参考までに。

## 参考
[How to add more than item to the session in Flask
](https://stackoverflow.com/questions/34630709/how-to-add-more-than-item-to-the-session-in-flask)
ついてくるMobの設定について

**ついてくるmobについて**

MobをAssetStoreからもってきてフィールドに置いたが、動かなくてどうすればいいのかわからない。という人に向けて書いていきます。（初心者向け）

順序としては
1. 動いてほしいフィールドに対して、NavMeshというものをBakeする。
2. 動かしたいいもの（Mob）に対してNav Mesh Agentというものをアタッチする。
3. 行動（移動）に関するスクリプトを書く。
4. Mobにscriptをくっつける。

おそらく、初心者にはわからない単語もあると思うので、一つ一つ書いていきたいと思います。

1．まず、左上のメニューからWindowをクリック、出てきた中のNavigationをクリック。
　 そうするとNavigationタブというのが右に表示されるので下にあるBakeというボタンをクリック。
　 するとエリアに青い面が現れるのでこれがMobの移動範囲になる。
   上のBakeというところをクリックすると詳細設定画面にできるので、そこで行動範囲を制限したい場　 合、調整できる。

2．MobをMob選択し、右に出てくる詳細のAddComponentを押して、Nav Mesh Agentというものを探し
　 てクリック。

3．行動に関するscriptを書く

![bandicam 2018-05-19 17-15-11-531.jpg](https://qiita-image-store.s3.amazonaws.com/0/257079/4c532c6a-498d-8042-6c2a-a804ee071d53.jpeg)

このようなscriptを書いてください。
POINT1.using　Unity.Engine.AI；を忘れずに
　　　　これはtargetについてくるAIのようなもの。と考えればOK。
POINT2．target(追われるもの)の宣言
　　　　これを書かないと、Update以下に書いてあるtargetがエラーを起こしてしまいます。
POINT３．void Update以下
　　　一文目でNavMeshAgent(２番でAddComponentAddComponentしたもの)をagentとして考えて
　　　二文目でagent（Mob)のスピードを設定
　　　三文目でtargetを座標に向かって行く設定(＊startに入れると最初の一回だけ試行するので、　　　　　　そういう設定をしたい人はvoid　start以降に入れてみると良い）

4．Mobniscriptをくっつける
　 Mobに、書いたscriptをドラック＆ドロップ

これで完成！


*ちなみにこのやり方だと、地面がないとだめなので、ミサイルなどに追尾機能を入れたいのならば、ほかに色々考える必要がある。*
Vagrantでlocalが全て同じサイトに飛んでしまう時の解決法

Vagrantでlocalが全て同じサイト（ディレクトリ）に飛んでしまう時の解決法。
# 環境
- MacOS
- vagrant
- vagrantのboxはubuntu17
- vagrant内ではapacheが動作

# 現状
local.hogehoge.comでディレクトリを作成すると自動でlocal.hogehoge.comでアクセスできるようにVagrantFileを作ったのにも関わらず、ある日新しくディレクトリを追加するとlocalが全てそのディレクトリに繋がってしまうようになった。

- local.hogehoge.com
- local.hugahuga.com
- local.exsample.com ← New!

# 解決法

```apache:/etc/apache2/sites-enabled/exsample.conf
<VirtualHost *:80>
    ServerName local.exsample.com
    DocumentRoot /share/local.exsample.com/htdocs
    <Directory "/share/local.exsample.com/htdocs">
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>
```
新しい環境のためにvagrant内のapacheに設定を追加していた。

```sh
$ ls

exsample.conf shared-virtual-hosts.conf
```
名前の順番（優先順位）の問題でshared-virtual-hosts.confより先に読み込まれている。

```sh
$ mv shared-virtual-hosts.conf 001-shared-virtual-hosts.conf
```
そのためshared-virtual-hosts.confが先に読み込まれるようにrenameする。

```sh
$ ls

001-shared-virtual-hosts.conf exsample.conf
```

これでひとまずは解決。
さくらVPSのKUSANAGIでドメイン変更した

# 経緯
なんかKUSANAGIが速いらしいと聞いたので，一ヶ月ほど前，試しにさくらのVPSでKUSANAGIを使ってwordpressのブログを開設してみました。

↓コレ。2018/5/21現在３記事しかありませんが。
[barlog](https://barlog.tech)

なんやかんやあって，なんとなくちゃんとブログ運営し始めようかなという気になってきたのですが，もともとお試しのつもりだったので，[freenom](http://www.freenom.com/ja/index.html?lang=ja)の無料ドメインを利用していました。

しかし，freenomで取得したドメインは更新が面倒で（更新できる期間が限られていて，しかも手動更新のみだったような），期限満了になるとfreenomの広告ページにリダイレクトされるようになるという代物なので，まともなドメインを取得してそちらに移行することにしました。

# ドメインを取得
ドメインは[ムームードメイン](https://muumuu-domain.com/?mode=conpane)で取得しました。
ムームーDNSを利用して，さくらのネームサーバーを登録します。
さらに，さくら側でもドメイン新ドメインを追加します。

このあたりは[『さくらのVPS+ムームードメイン』〜独自ドメインを利用する方法〜](http://vdeep.net/sakuravps-muumuu)を参考にすれば良いと思います。

# ドメインの変更
KUSANAGIでドメインを変更するのは実は非常に楽チンで，

```
$ kusanagi setting --fqdn <new_domain> <profile>
```
基本的にこれだけです。

これで新ドメインにアクセスすれば，wordpressの画面が…

![nginx-top.png](https://qiita-image-store.s3.amazonaws.com/0/168667/07eb4ef0-496c-4d93-3d2b-7f6078936e96.png)

**??**


# KUSANAGIは全てをよしなにやってくれるわけではなかった
どうやらnginxの*.confの内容は一切変更されていなかったようです。

というわけで自力で書き換えます。

```
$ vi /etc/nginx/conf.d/<profile_name>_http.conf

server_name <new_domain>;
rewrite ^(.*)$ https://<new_domain>$request_uri permanent;

$ nginx -t
$ nginx -s reload
```

わたしはHTTPSリダイレクトを設定したためこんな感じ。

次に新ドメインの証明書を発行。

```
$ kusanagi ssl --email my_email_address@email.com
```

楽ちん。

最後に，新ドメインに証明書を設定するついでに，旧ドメインからもリダイレクトされるようにする。

```
$ vi /etc/nginx/conf.d/<profile_name>_ssl.conf

server {
  listen 443 ssl http2;
  server_name <old_domain>;
  rewrite ^(.*)$ https://<new_domain>$request_uri permanent; # SSL ONLY
  ssl_certificate /etc/letsencrypt/live/<old_domain>/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/<old_domain>/privkey.pem;
}
 
server {
  listen 443 ssl http2;
  server_name <new_domain>;
 
  ssl_certificate /etc/letsencrypt/live/<new_domain>/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/<new_domain>/privkey.pem;
  .
  .
  .

$ nginx -t
$ nginx -s reload
```

これで新ドメインでwordpressにアクセス可能になりました。めでたしめでたし。

# 教訓？
エンジニアの基本と言ってしまえばそうですが，「なんか勝手に良い感じにやってくれてるんだろう」の裏を覗くことですね。作業効率とのトレードオフな気がしますが，たいてい裏を調べるほうが急がば回れ的に速く目的を達成できることが多い気がします。
SSH接続時のLANGについて

会社で仕事しているときに、「LANGの設定は接続元のSSHが設定してしまっている」時があって私としては「SSHでLANGの設定ってできるの？」とかだったのでどういうことか調べました。備忘も兼ねて以下に記載します。

※以下のページを参考にさせていただきました
https://dev.classmethod.jp/server-side/os/changed-lang-by-ssh/

・環境
ローカル：maxOS High Sierra バージョン 10.13.4
リモート：CentOS release 6.9 (Final)

・設定方法
OpenSSHのクライアント設定ファイルである「~/.ssh/config」に以下のように記載するとSSHで接続先に環境変数を引き継がせることが出来る。

~/.ssh/config
 Host *
     SendEnv LANG LC_*

上記の通り、「SendEnv」に接続先に引き継がせたい環境変数を記載する。