OmniAICreator/Qiita-1.07M huggingface dataset:
PowerShellでpyenvもどき（未完成）

#更新
H31.2.4 現在設定中のPythonのデータ保存場所を、スクリプトのあるディレクトリになるように変更しました。

#使い方
pythonはC:\Program Files\Pythonに、バージョンごとにインストール。もしくはコードの一行目の$PYTHON_ROOTを変更。

インストールされているバージョンをリストアップ:

```PowerShell
pyenv versions
```

現在選択中のバージョンを表示:

```PowerShell
pyenv version
```

バージョン選択

```PowerShell
pyenv global [version]
```
※pyenv local は実装されていません。
※各バージョンのパイソンのインストールは手動です。

#コード
```PowerShell:pyenv.ps1
$PYTHON_ROOT = [string]"C:\Program Files\Python"
$VERSION_INFO = [string]((Split-Path -Parent $MyInvocation.MyCommand.Path) + "\pyenv_current_version.dat")


function get_versions_installed(){
	return Get-ChildItem $PYTHON_ROOT
}

function get_current_version(){
	if ( $(test-path $VERSION_INFO) -ne $True ){
		Write-Error("ERROR: current python version may not be defined")
		return $False
	}else{
		return Get-Content $VERSION_INFO
	}
}

function set_version($new_version){
	delete_python_path

	if ( $(test-path $VERSION_INFO) -ne $True ){
		New-Item "$VERSION_INFO" -itemType File
	}
	Set-Content -Path $VERSION_INFO $new_version

	set_python_path $new_version
}

function delete_python_path(){
	$paths = $env:path -split ";"
	#foreach($path in $paths){Write-Host $path}
	[int[]]$indices_to_delete = @()
	for ($i = 0; $i -lt $paths.Length; $i++){
		if ($paths[$i].Contains($PYTHON_ROOT)){
			$indices_to_delete += $i
		}
		if ($paths[$i] -eq ""){
			$indices_to_delete += $i
		}
	}
	$indices_to_delete = $indices_to_delete | Sort-Object -Descending
	foreach($i in $indices_to_delete){
		$paths[$i] = $null
	}
	$env:path = $paths -join ";"
}

function set_python_path($version){
	$env:path += "$PYTHON_ROOT\$version;"
	$env:path += "$PYTHON_ROOT\$version\Scripts;"
}

if ($args.Length -eq 0){
	Write-Host("usage: pyenv [version, versions, global (python version)]")
}else{
	switch ($args[0]){
		"version" {
			$current_version = get_current_version
			Write-Host($current_version)
		}
		"versions" {
			foreach ($ver in get_versions_installed){
				Write-Host($ver)
			}
		}	
		"global" {
			if ($args.Length -eq 2){
				$present_versions_data = get_versions_installed
				$present_versions = [string[]]@()
				foreach ($ver in $present_versions_data){
					$present_versions += [string]$ver
				}
				if ($present_versions -contains $args[1]){
					$ver = $args[1]
					set_version($ver)
					Write-Host("pyenv version has been set to $ver")
				}else{
					$ver = $args[1]
					Write-Error("python version $ver is not installed")
					exit $False
				}
			}
		}
		<#
		"test" {
			#delete_python_path
			#set_python_path $args[1]
		}
		#>
		

	}
}

```

#バグ
delete_python_path関数で既存のパスを消す際に空白の処理がうまくできてないので、使っていると$Env:Pathにセミコロンがたまっていく。
Görliテストネットを触る

PoAのクロスクライアント・テストネットである[Görli](https://goerli.net/)が動き出したので触ってみます。
ベルリンのGörlitzer Park(ゲルリッツァー・パーク)から名前をとったらしいので、**ゲルリ**と読むのが正なのかな？

手順は概ね以下の記事の通り。

- https://mudit.blog/getting-started-goerli-testnet/

# FaucetからGörli用のETHを取得
手順はRinkebyと同じです。
[Faucet](https://faucet.goerli.mudit.blog/)にも書かれていますが、こんな感じにアドレスを含むツイートをTwitterでつぶやいて、そのツイートのURLを[Faucet](https://faucet.goerli.mudit.blog/)に貼り付けてEnter。
![スクリーンショット 2019-02-04 15.19.05.png](https://qiita-image-store.s3.amazonaws.com/0/50056/e4d6d6b1-4a9f-80d3-5d02-67d9e92615d8.png)

# Metamaskでつないでみる
`Goerli Test Network` を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50056/e1931624-03ba-7de9-b90d-253bd0ce05cc.png)


FaucetでもらったETHが確認できます。

![スクリーンショット 2019-02-04 15.24.18.png](https://qiita-image-store.s3.amazonaws.com/0/50056/74262187-97f4-6d80-d106-b504015192f6.png)



ETHの送受信も滞りなく可能でした。
Contractのデプロイ等はまた今度。

---

GörliはクラスプラットフォームなのでGethでもParityでもPantheonでも利用できます。
このまま安定稼働するようであれば開発時のテストネットの有用な選択肢となりそうです。

# メモ
- ノードを立てる場合： https://github.com/goerli/testnet
- [Stats](https://stats.goerli.net/)
- [Etherscan](https://goerli.etherscan.io/)
Cognos Analytics のポータル画面で複数のコンテンツを選択して削除とかコピーする

#はじめに
どうも体感的に、世の中のCognosユーザーの半分くらいの方が気がついて無いような気がしますので、気がついて無い方向けに投稿します。
知っている人は無視して下さい。

Cognos 10 BI では、こんな感じにレポート等のコンテンツの左側にチェックボックスがあり、複数のコンテンツにチェックを入れて、「×」アイコンなどを選択する事により、一気に複数コンテンツの削除やコピーなどができました。
![001.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/9193ad84-f038-741e-1ebf-46461696c537.jpeg)

Cognos Analyticsでは、こんな感じにコンテンツの左側にチェックボックス無いので、同じ事はできないよね、と思っている方が、半数くらいいるのではないかと感じています。
![002.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/d5911407-731b-3d93-eb81-5b4f6f513402.jpeg)

#Cognos Analytics での複数選択のやり方
やり方はなんて事無いのですが、まず「レポート01」の文字以外のところを選択すると、赤枠の様に、コンテンツの左側に青棒が入ります。
![007.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/f7e87061-4868-7911-4a80-493d080d0c26.jpeg)

その後、Shiftボタンを押しながら、赤枠の「レポート07」の文字以外をクリックしてみると、この様に青棒がレポート01～07まで全て入ります。
![003.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/89ffb71e-b894-14ea-1dd5-f9a79fb90b39.jpeg)

Ctrlボタンを押しながら各コンテンツの文字以外をクリックすると、こんな感じに飛び飛びで選択できます。
![004.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/6be5e6b7-7291-7513-be46-588a3964781d.jpeg)

この状態で赤枠の「・・・」から「削除」すると、
![005.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/63c421f0-b1af-d2c9-3e12-f6c6322b9ed5.jpeg)

一気に複数のコンテンツを削除できます。
![006.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/f58ba5db-33c1-818c-db94-cd8806966dc2.jpeg)

知っていれば当たり前ですが、意外と知らなくて損してる方が多いので、これ読んで実は初めて知ったよという方は、今日から当たり前の顔して使って下さい！
Python 環境構築

# Python インストール

- [python.org]() 執筆時点での最新版がPython 3.7
- [Anaconda]()

# 仮想環境構築 venv 

複数のプロジェクトを並行開発する際、ライブラリのバージョン衝突を回避するため、仮想環境で開発する。

下記のように、python の `venv` を呼び出し、`myvenv` という名前の仮想環境を構築する。

```
C:\User\username>python -m venv myvenv
```

仮想環境 `myvenv` をアクティベートする。

```
C:\User\username> myvenv\Script\activate
```

myvenv がアクティブになると、コマンドプロンプト上に下記のように表示される。

```
(myvenv)C:\User\username>
```


# pip

pip は、python のライブラリをインストール・バージョン管理するためのツール。


## `pip install`

コマンドプロンプトで、下記コマンドで `package name` というパッケージをインストールできる。

```
C:\User\username>pip install [package name]
```

- 例1 Twitter API をインストールする。

```
(myvenv)C:\User\username>pip install TwitterApi
```

- 例2 Twitter API を仮想環境 `myvenv` にインストールする。

```
(myvenv)C:\User\username>pip install TwitterApi
```

## Proxy配下での`pip install`

- 例3 Twitter API をプロキシ配下で仮想環境 `myvenv` にインストールする。

```
(myvenv)C:\User\username>pip install --proxy http://username:password@proxy:port TwitterApi
```

または、`myvenv`ディレクトリに `pip.ini` ファイルを作成する。これで毎回 `--proxy` を指定しなくても `pip install` コマンドが使える。

```ini
# myvenv/pip.ini
[global]
proxy = http://username:password@proxy:port
```

```
(myvenv)C:\User\username>pip install TwitterApi
```


# Jupyter notebook

Jupyter notebook は、ブラウザ上でのインタラクティブな開発環境を提供している。

まず、Jupyter notebook をインストールする。

```
C:\User\username>pip install jupyter
```


インストール完了後、jupyter notebook を起動する。

```
C:\User\username>jupyter notebook
```
RDSで時間指定によるオートスケールを実現する

# はじめに

RDS（Aurora）ではオートスケールの設定が可能なのですが、トリガに利用できるのが

- Aurora レプリカの平均 CPU 使用率
- Aurora レプリカの平均接続数

の2つで、予めRDSの負荷が高い時間帯を狙ってオートスケールするのが難しかったので代替案を模索しました。

|RDSの負荷（CPU使用率）のイメージ|
|:--|
|![03a7edb9-a4bf-ebaa-1955-24b282617a62.png](https://qiita-image-store.s3.amazonaws.com/0/55290/651ac384-84fe-2c78-4603-c41503215859.png)
|

# 検討したこと

対象のRDS構成は以下の通りです。

```text:RDS構成
Cluster
┣ Writer
┣ Reader1
┗ Reader2
```

- Readerを予め追加した上で必要に応じて起動・停止をコントロールする。<br>
→そもそもClusterにぶら下がるインスタンスを停止状態にできませんでした。
- 全インスタンスをスケールアップする。<br>
→特定の時間以外はリソースが足りているため、不採用としました。

# 今回採用した案

- RDSの負荷（CPU使用率）が高い時間帯にReaderを一台追加する。
- 追加する時間帯はCloudWatchのイベントルールに設定する。追加するのは所定の時刻になったらReaderを追加するものと、削除するものの2つ。
- Readerの追加削除はLambda関数を使って実行する。

# 具体的な対応内容

## IAM

Lambda用にRDSに対しフルアクセスできるロールを作成します。

## Lambda

Reader追加と削除の関数をそれぞれ準備します。
今回はPython3.7を採用しました。

```python:追加
import boto3

def lambda_handler(event, context):
    # TODO implement
	rds = boto3.client('rds')
	response = rds.create_db_instance(
		Engine='aurora',
		DBClusterIdentifier='[対象クラスタ]',
		DBInstanceIdentifier='[追加するインスタンス名]',
		DBInstanceClass='[他のReadeのインスタンスクラスで良いかと]',
		PubliclyAccessible=False, #外部接続OKであればTrueで
		DBParameterGroupName='[他のReaderのパラメータグループ名で良いかと]',
		PromotionTier=15 #フェイルオーバー優先度は最も低くします
	)
	print(response)
	return 0
```

```python:削除
import boto3

def lambda_handler(event, context):
    # TODO implement
	rds = boto3.client('rds')
	response = rds.delete_db_instance(
		DBInstanceIdentifier='[追加時のインスタンス名]',
		SkipFinalSnapshot=True
	)
	print(response)
	return 0
```

## CloudWatch

イベントルールからルールを作成します。

- 追加用のルール：スケジュールからCron形式を選び追加する時刻を指定、ターゲットは先に作成したLambda関数（追加）を指定します。
- 削除用のルール：スケジュールからCron形式を選び追加する時刻を指定、ターゲットは先に作成したLambda関数（削除）を指定します。

# 確認

リアルタイムで確認可能であれば、RDSのデータベース一覧から確認でき、
リアルタイムで確認が難しければ、通知メール（RDS Notification Message）で確認が可能です。

# おわりに

今回はRDSの設定のみで対応が難しかったので力技になりましたが、他に良い対応方法などありましたらコメントのほどお願いいたします。
Tensorflowを使って足し算から始める

# インポート
```python
import tensorflow as tf
```

# 定数と変数を作ってみる
```python
a = tf.constant(3, name='const1')#定数: 一度決めたら後で変更できない
b = tf.Variable(0, name='val1')#変数： 値を変更できる
```

# 計算グラフを作ってみる
```python
tf.add(a,b)
# Tensor("Add:0", shape=(), dtype=int32)
```
ここでは計算グラフが定義されただけで、printするとオブジェクトが返ってきてしまう。

# 実行
```python
#変数の初期化
init = tf.global_variables_initializer()

with tf.Session() as sess:
  #初期化を実行
  sess.run(init)
  #足し算を実行
  print(sess.run(add))
```
変数を使うときは計算グラフを実行する前に、変数を初期化してあげなければならない。
定数を使うときは、初期化しなくても問題ない。
Angular[メモ] AOTコンパイル `Destructured variable or constant not supported`でエラーになる場合

#### AOTコンパイルに切り替えたときにエラーがでたのでメモ。

`typescript` 的にはOK(?)でもaotコンパイルでは、NG な書き方がいろいろとあるみたいです。

> https://github.com/angular/angular/blob/master/aio/content/guide/aot-compiler.md


その中で今回エラーが出たのは下記。(**非構造化変数または定数はサポートされていません**)

```text

{@a destructured-variable-not-supported}

Destructured variable or constant not supported
Referencing an exported destructured variable or constant is not supported by the template compiler. Consider simplifying this to avoid destructuring.

The compiler does not support references to variables assigned by destructuring.

For example, you cannot write something like this:

// ERROR import { configuration } from './configuration';
// destructured assignment to foo and bar const {foo, bar} = configuration; ... providers: [ {provide: Foo, useValue: foo}, {provide: Bar, useValue: bar}, ] ...

To correct this error, refer to non-destructured values.

// CORRECTED import { configuration } from './configuration'; ... providers: [ {provide: Foo, useValue: configuration.foo}, {provide: Bar, useValue: configuration.bar}, ] ...
```

## 下記のように、`AppRouteConstant` としてルーティング用の定数の中から必要なものを `const {...} = AppRouteConstant` で取り出して、`@NgModule`などのangular用のデコレータにimport(参照させること)はできない

```typescript


/**
 * ルーティング設定
 */
const {HOGE, FUGA} = AppRouteConstant; // これがNG

const routes: AppRoute[] = [
  // HOGE
  {
    path: HOGE.INDEX.path,
    component: HogeIndexPageComponent,
    data: HOGE.INDEX.data,
  },
  // FUGA
  {
    path: FUGA.INDEX.path,
    component: FUGAIndexPageComponent,
    data: FUGA.INDEX.data,
  },
];

export const routing = RouterModule.forChild(routes);

// ----略

@NgModule({
  imports: [
    CommonModule,
    //---------略
    routing,
  ],
  declarations: [
   // ----------略
  ],
})
export class HogePageModule {
}

```


## おとなしく個別に書く。

```typescript

/**
 * ルーティング設定
 */

const routes: AppRoute[] = [
  // HOGE
  {
    path: AppRouteConstant.HOGE.INDEX.path,  // 少し冗長になるがAOTコンパイルOK
    component: HogeIndexPageComponent,
    data: AppRouteConstant.HOGE.INDEX.data,
  },
  // FUGA
  {
    path: AppRouteConstant.FUGA.INDEX.path,
    component: FUGAIndexPageComponent,
    data: AppRouteConstant.FUGA.INDEX.data,
  },
];

export const routing = RouterModule.forChild(routes);

// ----略

```
符号なし基数変換in C

#Cで、符号なしの基数変換（n進数）をします。

n進文字列から値へ、値からn進数文字列への変換を行う関数です。

ここでは、2~36進数まで扱えるようにしています。
nrdigitの値を変えると、扱える基数の範囲が変わります。

```nradix.c
//
//  符号なし基数変換
//
#include  <stdio.h>
#include  <stdlib.h>
#include  <string.h>
#include  <ctype.h>

char  nrdigit[]="0123456789abcdefghijklmnopqrstuvwxyz";

//
// 値から文字列へ
//
//    引数：val 値
//            r n進数のn
//          str 出力する文字バッファへのポインタ
//
//    返り値：strの長さ
//
int val2str(unsigned long val,int r,char *str) {
  int d,l,i;
  char  stack[1024];
  int   sp;

  if (val==0) {
    str[0]='0';
    str[1]='\0';
    return(1);
    }

  sp=0;
  l=0;
  while(val!=0) {
    d=val%r;
    val/=r;
    stack[sp++]=d;
    l++;
    }

  for(i=0;i!=l;i++)
    str[i]=nrdigit[stack[--sp]];

  str[i]='\0';
  return(strlen(str));
}

//
// 文字列から値へ
//
//    引数：inval n進数の数が入った文字列
//          radix n進数のn
//
//    返り値： unsigned long の値
//
//
unsigned long  str2val(char *inval,int radix) {
  int   s=0;
  char  *p;
  unsigned long  n=0;

  while(*inval!='\0') {
      p=index(nrdigit,tolower(*inval++));
      if (p==NULL)
        break;
      n=n*radix+(int)(p-nrdigit);
      }
  return(n);
}

int main(int argc,char *argv[]) {
    unsigned long  n;
    int   r;
    char  inval[1024];
    char  word[1024];

    if (argc!=3) {
      fprintf(stderr,"Usage %s <値> <基数>\n",argv[0]);
      exit(1);
      }

    sscanf(argv[1],"%s",inval);   //  get input value
    sscanf(argv[2],"%d",&r);      //  get radix

    if (r<2 || r>strlen(nrdigit)) {
        fprintf(stderr,"invalid radix.\n");
        exit(1);
        }
    n=str2val(inval,r);

    val2str(n,2,word); printf("%s binary\n",word);
    val2str(n,8,word); printf("%s octal \n",word);
    val2str(n,10,word); printf("%s decimal\n",word);
    val2str(n,16,word); printf("%s hexadecimal\n",word);
    val2str(n,24,word); printf("%s 24進数\n",word);
}

```
Array.newを使って2次元配列を作るときに注意すべきこと

#はじめに
Array.newで作った2次元配列で少しハマったので、
その時に調べた内容をメモとして残します。

#何が起こったか
現在、研修で[Google Tech Dev Guide](https://techdevguide.withgoogle.com/paths/foundational/find-longest-word-in-dictionary-that-subsequence-of-given-string)の[マインスイーパーを作る課題](https://techdevguide.withgoogle.com/paths/foundational/coding-question-minesweeper/#!)を解いており、
マスを表現するために2次元配列を使ったところ、事件が起きました。。
今回は10✖10のマスを作りたかったので、下記のようにマスを作りました。

```irb:irb
irb(main):001:0> a = Array.new(10,Array.new(10,"-"))
irb(main):002:0> pp a
[["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"]]
```

なんとなく上手く作れたように見えます。
次に左上のマスに「9」を格納してみます。

```irb
irb(main):003:0> a[0][0] = 9
irb(main):004:0> pp a
[[9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 [9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 [9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 [9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 [9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 [9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 [9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 [9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 [9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 [9, "-", "-", "-", "-", "-", "-", "-", "-", "-"]]
```

ん？なぜか他の箇所まで「9」になっています。
この時点でお気づきの方もいるかと思うのですが、
`Array.new(10,Array.new(10,"-"))`で2次元配列を作成すると、
2次元目の配列は1次元目の配列を参照してしまうみたいです。。

それを確認するために、オブジェクトIDを見てみます。
（オブジェクトIDが分からない方は[こちら](https://ref.xaio.jp/ruby/classes/object/object_id)を参照してください）

```irb:irb
irb(main):005:0> puts a[0][0].object_id
19
irb(main):006:0> puts a[1][0].object_id
19
```

やはり、同じオブジェクトIDになっていますね。
どうするかいろいろ考えた結果、下記のような形になりました。

```irb:irb
irb(main):007:0> b = Array.new(10).map{Array.new(10,"-")}
```
Array#mapはブロックの実行結果を新しい配列にして返してくれます。
この状態で、再度オブジェクトIDを確認してみます。

```irb:irb
irb(main):008:0> puts b[0][0].object_id
46928456320740
irb(main):009:0> puts b[1][0].object_id
46928456320660
```

異なるオブジェクトIDになりましたね。
次に値を入れてみます。

```irb:irb
irb(main):010:0> b[0][0] = 9
irb(main):011:0> pp b
[[9, "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"],
 ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"]]
```

左上だけ値が変わりましたー！

#まとめ
Array#mapすごく便利！！！
Hyperledger Fabricの簡易的な用語説明（公式ドキュメントのGoogle和訳）

## これはなに？

* 下記の内容を日本語（Google翻訳）にしたもの＝備忘録です
    * https://hyperledger-fabric.readthedocs.io/en/release-1.4/blockchain.html
    * 説明がまだまだ不足していて、頭の整理も出来ていないです・・・

## 用語の簡易的な説明
* Hyperledger Fabric
    * Linux Foundation が2015年にHyperldgerプロジェクトを設立。
    * Fabricは、そのうちブロックチェーンプロジェクトの一つ。
    * コンソーシアム（許可）型
* PKI（公開鍵基盤）
    * デジタル証明書
        * 証明書の所有者に関する一連の属性を保持している文書
        * X.509証明書 ≒ 変更が不可能なデジタルIDカード
    * 公開鍵と秘密鍵
        * 安全な通信を可能にする暗号の魔法
        * 鍵間の独特の数学的関係は、対応する公開鍵だけが一致することができ、かつ同じメッセージについてのみ、秘密鍵を使用してメッセージに署名を作成できる
    * 認証局（CA）
        * デジタル証明書を発行する
            * アクターを、そのアクターの公開鍵と結びつけて、証明書を発行している
        * Fabric CA：組み込みのCAコンポーネント
    * 証明書失効リスト（CRL）
        * 何らかの理由で失効された証明書の参照リスト
* Membership Service Provider（MSP）
    * 組織内の有効なIDを管理し、規則を定義するコンポーネント
    * PKI（公開鍵基盤階層モデル）を採用
    * どのネットワークに参加している特定の組織のメンバーであるかを示す
    * 組織（Organizations）
        * メンバーの管理グループ
        * X.509証明書で定義されている組織とは異なる
        * 組織に対して、MSPを複数定義することができる
        * 組織単位（OU：organizational units）
            * 組織はOUに分割される
    * チャンネルMSP
        * チャンネルレベルで管理者権限と参加者権限を定義する
            * →チャンネルに参加しているすべての組織にMSPを定義
    * ローカルMSP
        * クライアント（ユーザ）とノード（PeerとOrderer）に定義
            * ノードローカルMSP：そのノードに対するアクセス権を定義
            * ユーザローカルMSP：チャンネルのメンバ、システムへの特定ロールの所有者として認証出来る
    * 要素（9つ）
        * ルートCA
        * 中間CA
        * 組織単位
        * 管理者
        * 失効した証明書
        * ノードの識別情報
        * キーストア（秘密鍵の場合）
        * TLSルートCA
        * TLS中間CA
* 共有元帳（Shared Ledger）
    * world state
        * 特定時点の元帳の状態を表す。≒ DB
    * transaction log
        * world stateの更新履歴（トランザクション）を記録する
    * DB
        * デフォルト：LevelDB
* スマートコントラクト
    * チェーンコードで記述
    * 外部のアプリケーションが元帳と対話するときに呼び出される
    * 基本的に、トランザクションログとは対話しない
    * Golang、Node.jsがサポート（2019/02/04現在）
* アイデンティ
    * 各アクター（Peer、Orderer、管理者など）は、「X.509デジタル証明書」にカプセル化されたデジタルIDを持つ。
    * デジタルID
        * プリンシパル（柔軟に設定可能なパーミッション）を持つ

## 必要な技術
* Docker
    * 3種類のノード（Peer、CA、Orderer）を、1台のサーバで動かすために必要
    * 最小構成
        * Peer：2台
        * CA：1台
        * Orderer：1台
* Golang、Node.js、Java
    * チェーンコード（≒スマートコントラクト）の記述に必要
    * V1.4でJavascript（Node.js）のSDKとチェーンコードのプログラミングモデルの改善が行われ、より直感的に開発できるようになった。

## まとめ
細かく説明されすぎていて、結局よくわからない〜(；´∀｀)という事象に陥る罠。
シンプルに説明できるようになりたい。
自分の言葉で説明できるようになりたい。

今回はここまでです。
ありがとうございました。
Ethereumで特定のアドレスから特定のERC20トークンが送信されたらガンガン電話をかける

**特定のEOAからとあるERC20トークンが送信された際に1秒でも早く、是が非でも察知したい**というニッチなニーズに応える通知システムを突貫で構築したメモです。
(諸事情で監視、通知機能が急遽必要になりました)

# 作るもの
- 特定のEOAから特定の種類のERC20トークンが送信されたら、登録しておいた複数の電話番号にガンガン電話をかけて通知するシステム。
- 今回の構成であれば、各種ツールの感覚がわかる方なら3〜5時間で構築可能と思われる。各種ツールは無料枠でいけます

# 通知の経路
通知は以下のような経路で通知されます。

- etherscan => Gmail => AWS SES => AWS SNS => AWS Lambda => Twilio => 関係者全員に電話コール

以下で説明してゆきます。
各要素の詳細はWeb上にいくらでも情報がありますので割愛いたします。

## Twilio

- アカウントを作成して、**account_sid**、**auth_token**、**電話をかけられる番号**を用意する
- **電話をかける**こと(=深夜でも叩き起こされること)が重要なので、何を伝えるかは考慮しない。デフォルトのサンプル音声そのままで充分。

## AWS Lambda
以下、AWSはすべてオレゴンリージョンで捜査。現状、SESが東京リージョンで使えないため。

- https://github.com/sot528/twilio-lambda-python
- 使い方
    - `twilio-python` という名前のPython3.6のLambda関数を作成
    - AWSアカウント設定
    - [アカウント周りの情報]((https://github.com/sot528/twilio-lambda-python/blob/master/lambda_functions.py#L4L7)
)を書き換える
    - デプロイスクリプトを叩く
        - `./deploy.sh`


## AWS SES

- 適当なドメインを認証して、メール受付をしたら `fizzbuzz` というSNSトピックを叩くようにしておく。
    - ここでは `foobar@example.com` を設定したと仮定する
- ドメインが無い場合は無料ドメインなどを利用する。

## AWS SNS
- `fizzbuzz` というトピックにLambda関数 `twilio-python` を叩くsubscriptionを作成

## GMail
GMailはフィルタの機能を使うためだけに経由している。突貫で作ったのでこうなったが、本来はLambdaに乗せるべきか。

- `noreply@etherscan.io` というアドレスからのメールで、 任意のトークン名を含むメールを `foobar@example.com` へ転送するフィルタを設定。


## Etherscan

- [EthereumでETHやERC20のトランザクションを監視する](https://qiita.com/sot528/items/2044cea2cf2a2c79b14c) を参照。これでGMailのアドレスにメールを送信する。

# 所感
- これにより、アラは多いがひとまず特定アドレスからのERC20トークンの送信を即座に察知するシステムが短時間で構築できました。そしてとりあえず十分に機能しました。
- この手の需要はそれなりにあると思われるので、今後良いツールが出てきそうです。
    - [catabira](https://www.catabira.com/)の中の人とお話したらTwilio対応も検討するとのことでした。
[Tips]AngularDartのフォームバリデーション（Model Driven）

# はじめに
フォームバリデーションの方法を備忘録的に残します。
Template drivenなフォームバリデーションは[公式](https://webdev.dartlang.org/angular/guide/forms)に載っていたので、Model drivenなフォームバリデーションについて調べました。

# 実装内容
ログイン時の簡単なバリデーションです。
![sample.gif](https://qiita-image-store.s3.amazonaws.com/0/199445/8a6ed8e7-490d-4155-7463-0b1587a48b08.gif)


# 実装例
```dart:signin_component.dart
import 'package:angular/angular.dart';
import 'package:angular_components/material_input/material_input.dart';
import 'package:angular_components/material_button/material_button.dart';
import 'package:angular_forms/angular_forms.dart';
import 'package:materia_dart/materia_dart.dart';

@Component(
    selector: 'signin',
    templateUrl: 'signin_component.html',
    styleUrls: [
      'signin_component.css'
    ],
    directives: [
      coreDirectives,
      formDirectives,
      materialInputDirectives,
      MaterialInputComponent,
      MaterialButtonComponent,
      NgForm,
      NgFormControl,
      NgFormModel,
    ],
    providers: [
    ])
class SigninComponent {

  SigninComponent(
    ) {
      form = FormBuilder.controlGroup(
        {
          'email': ['', (AbstractControl c) {
            if (c.value == '') return {'error': 'メールアドレスは必須です'};
          }],
          'password': ['', (AbstractControl c) {
            if (c.value == '') return {'error': 'パスワードは必須です'};
          }]
        }
      );
    }

  ControlGroup form;
  
  void signIn() async {
    print(this.form.value);
  }
}

}
```

```html:signin_component.html
<h1>SignIn</h1>
<div class="signin-form">
  <form [ngFormModel]="form">
    <material-input floatingLabel label="メールアドレス" type="text" ngControl="email"
      required></material-input>
    <material-input floatingLabel label="パスワード" type="text"
      ngControl="password" required></material-input>
    <material-button raised [disabled]="!form.valid" (click)="signIn()">ログイン</material-button>
  </form>
</div>
```

下記の行ですが

```dart
'email': ['', (AbstractControl c) {
            if (c.value == '') return {'error': 'メールアドレスは必須です'};
          }]
```

Validators.requiredを使って表現できます。ただこれだとエラー文が英語になってしまいます。自分は日本語化する方法が見つけられなかったため、自由にかける関数の形で定義しました。

```dart
'email': ['', Validators.required]
```

# おわりに
もっと色々と深掘りしたい
[Tips]AngularDartのルーティング

#はじめに
備忘録として残しておきます。
事前にWebのプロジェクトを作っていることを前提に書いています。

## 前準備
例としてsigin inするための画面のコンポーネントを作成し、そのコンポーネントに対してルーティングできるようにします。

```dart:lib/src/signin/signin_component.dart
import 'package:angular/angular.dart';

@Component(
  selector: 'signin',
  templateUrl: 'signin_component.html',
  directives: [coreDirectives],
)
class SigninComponent {
}

```

```html:lib/src/signin/signin_component.html
<h1>SignIn</h1>
```


## 1. pubspec.yamlにangular_routerを記述
```yaml:pubspec.yaml
dependencies:
  angular: ^5.2.0
  angular_router: ^2.0.0-alpha+19 #追加
```

```
$ pub get
```

## 2. main.dartを編集
```dart:web/main.dart
import 'package:angular/angular.dart';
import 'package:personal_web/app_component.template.dart' as ng;
import 'package:angular_router/angular_router.dart';
import 'main.template.dart' as self;

const useHashLS = false;
@GenerateInjector(
  routerProvidersHash,
)
final InjectorFactory injector = self.injector$Injector;

void main() {
  runApp(ng.AppComponentNgFactory, createInjector: injector);
}


```

## 3. routes.dartを新規作成
```dart:lib/src/routes.dart
import 'package:angular_router/angular_router.dart';
import 'signin/signin_component.template.dart' as signinComponent;

class RoutePaths {
  static final signIn = RoutePath(path: 'signin');
}

class Routes {
  static final all = <RouteDefinition>[
    RouteDefinition(
      routePath: RoutePaths.signIn,
      component: signinComponent.SigninComponentNgFactory,
    ),
  ];
}
```

signin_component.template.dartというファイルは存在しないんですが、ビルド時に生成されるコンポーネントファクトリなるものらしいです。[参考文献はこちら。](https://webdev.dartlang.org/angular/tutorial/toh-pt5)

## 4. app_component.dartとapp_component.htmlの変更
URLが変わったらそれぞれのページを表示するように変更します。

```dart:lib/app_component.dart
import 'package:angular/angular.dart';
import 'package:angular_router/angular_router.dart'; //追加
import 'src/routes.dart'; //追加

@Component(
  selector: 'app-component',
  templateUrl: 'app_component.html',
  directives: [routerDirectives], //追加
  exports: [RoutePaths, Routes] //追加
)
class AppComponent {}
```

```html:lib/app_component.html
<router-outlet [routes]="Routes.all"></router-outlet>
```

これであとは実行するだけ
http://localhost:8080/#/signin
でアクセスできます。
プロキシ環境内からのAWS IoT デバイスへのメッセージ送信

#結論
mosquitto コマンドによるMQTTのpublishではなく、curl コマンドでHTTPS POST すればいい。

AWS IoT のデバイスは、Rest API エンドポイントで、MQTTだとポート8883番、 HTTP だと8443番で同じようにメッセージ受信できる。
curl なら、Linux やMac 上で、https_proxy/http_proxy/HTTPS_PROXY/HTTPS_PROXYの環境変数にプロキシサーバの値を設定すれば稼働する。
mosquitto は、これらの環境変数を設定しても動作せず。

#方法
以下のように記述する。

ルート証明書ファイル名  < rootCA >
デバイス証明書ファイル名 : < crt >
プライベートキーファイル名 : < private_key >
エンドポイント : < endpoint >
トピック名 : < topic >
デバイス名称 : < device_name >
JSON 形式のメッセージ : < message >

```mosquitto
$ mosquitto_pub \
      --cafile <rootCA> --cert <crt> --key <private_key> \
      -h < endpoint > -p 8883 -q 1 -d \
      -t gauge/1 -i <device_name> \
      -m '<message>'
```

```curl
$ curl -D - --tlsv1.2 -X POST \
      --cacert <rootCA> --cert <crt> --key <private_key> \
      "https://<endpoint>:8443/topics/<topic>?qos=1" \
      -d <message>
```
[Tips]AngularDartのguardについて

# はじめに
未認証で見せたくないページとかありますよね？それを見せない方法として本家Angularではguardという仕組みがあります。AngularDartにおけるGuardをどう書くのか調べました。

# pubspec.yamlにangular_routerを記述
```yaml:pubspec.yaml
dependencies:
  angular: ^5.2.0
  angular_router: ^2.0.0-alpha+19 #追加
```

# コンポーネントのライフサイクルにcanActivateを実装する

```dart
import 'package:angular/angular.dart';
import 'package:angular_router/angular_router.dart';

@Component(
  selector: 'sample-component',
  templateUrl: 'sample_component.html',
)

class SampleComponent implements CanActivate{
  @override
  Future<bool> canActivate(RouterState current, RouterState next) async{
    // ここに処理を書く return trueであれば画面表示する
    return false;
  }
}
```

これでOK
jQueryを使用してinputで入力したテキストをブラウザバック or リロードした際に表示させたい

## 記述内容
   
### HTML

    <p>入力：<input type="text" name="test" size="40"></p>
    <p><input type="submit" value="格納"></p>
    <div class="add_txt"></div>

### JavaScript


    $(function(){
        $('input[type="submit"]').click(function(){
            let url = location.href;
            let target = $('input[name="test"]').val();
            history.pushState(target, '', url);
        })
    });

    $(window).load(function(){
        if ('pushState'in history) {
            $('.add_txt').text("前に入力したテキスト→"+history["state"]);
        }
    });

  
  ※jQueryのバージョンは環境によって変更が必要かも。

## Github Repository
https://github.com/TK-bone/HistoryAPI_input
Goland で revel アプリケーション のデバッグ方法（ debug run config）

# Goland で revel アプリケーション のデバッグ方法（　debug run config）

## はじめに

公式のドキュメント見て、それらしく入力してもデバッグできるようにはならず結構ハマったので念の為、残しておく

## バージョン等

* Goland 2018.3.3

## 含まれるもの

* Goland の起動設定（ Run Configuration ）

## 起動設定

### 公式のドキュメント

公式のドキュメントは https://revel.github.io/manual/debug.html#intellij_debugging_(goland)

### 動作確認できた設定方法

アプリケーション名: revel-debug

1. Go Build を選択
![スクリーンショット 2019-02-04 14.27.29.png](https://qiita-image-store.s3.amazonaws.com/0/112497/07ca6d0a-23f0-b1b2-26c0-85094d4a0181.png)

2. Run Kind: File
3. Go tool arguments: -i
4. Program arguments: -importPath github.com/xxxx/revel-debug github.com/revel/revel -srcPath /src -runMode dev
![goland debug.png](https://qiita-image-store.s3.amazonaws.com/0/112497/b43b05f0-04cc-48af-3501-5c128b4f63d6.png)


5. External tool
    6. Program: bin/revel
    7. Arguments: build github.com/xxxx/revel-debug github.com/xxxx/revel-debug
![goland build.png](https://qiita-image-store.s3.amazonaws.com/0/112497/9f82f112-b226-aae3-91fd-c55dcaf188f6.png)

## 最後に

最近になって既存のGoアプリケーションを触ることになったのでよくわからないことが多いので似たような方の参考になれば幸いです
【開発メモ～C++で正規表現を勉強してみた。～】

##開発環境:　
・Visual Studio 2015
・C/C++
・コンソールアプリケーション

##はじめに
　どうも、はじめましての方は初めまして。ぐっちーです。
最近技術テストで正規表現使えるところがあったので、勉強してみました。
実際、技術テストでは使うことができなかったので、これからですね...。
正規表現自体、全くの無知なのでメモ程度で残しておきます。

##①正規表現って何？

　端的に言えば、「いくつかの文字列を一つの形式で表現するための表現方法」です。

猿でもわかるさんの内容を引用させていただきました。
引用元(https://www.mnet.ne.jp/~nakama/)

例えば...

「今日は<b>肉</b>を食べます！」

と表示したいです。

しかし、<b>魚</b>も食べたいけどな。というときもわざわざ、素直に書きますか？
そうしてしまうと面倒ですよね？その分セリフを用意しないといけません。

そこで「正規表現」の登場です。

「今日は<b>.</b>を食べます！」

「<b>.</b>」を書けば、好きな一文字として扱うことができます。
なので、
「今日は<b>肉</b>を食べます！」
「今日は<b>魚</b>を食べます！」
と両方に対応できます！

このような特殊な文字を使い、文字列の式を作っていくのが<b>正規表現</b>です！

この記事では正規表現のさきっぽまでしか説明しませんが、興味がある方は勉強してみてください。
ネットワーク系ではよく使われるので覚えていて損はないです。

##②実際にC++のコードでやってみましょう
###インクルード
```cpp:main.cpp
// 正規表現のインクルードヘッダー
#include <regex>

```

この「regex」を使用し、正規表現を再現します。

###正規表現の条件を作る
```cpp:main.cpp
// regex reg(条件)
regex reg1(1234);      // 「1234」という文字ならばTRUE
regex reg2(R"(\d+)"); // 全体が数列ならTRUE
regex reg3(R"(\D+)");  // 全体が文字ならTRUE
```
特殊な記号文字だたくさんありますが、これらを使って表現します。
簡単に説明します。
「\d」　・・・　数字
「\D」　・・・　数字以外（文字）
「＋」　・・・　直前の文字の1回以上の繰り返し

###判定する
```cpp:main.cpp
String str = "1234"
// regex_math(判定したい文字,条件)
regex_match(str, reg)
```
regex_match ・・・　「reg」の条件で一致するとTRUEを返してくれます。

なので、今回は
「reg1 → TRUE」
「reg2 → TRUE」
「reg3 → FALSE」

になります。

##②文字と数の分解

文字と数字の判定はこの正規表現でやれば簡単にできます！

とりあえず、分解はGithubに載せておきますので、よかったらみてください。

https://github.com/HiguchiRyuya/RegexFuncs-memo-/blob/master/main.cpp


#☆思ったこと
c++では需要とかってどうなんだろ（笑）
でもまた一つ勉強になりました。(*´ω｀*)

参考
===============================
https://qiita.com/jnchito/items/893c887fbf19e17d3ff9
http://gimite.net/help/devas-ja/all_regex.html
http://artteknika.hatenablog.com/entry/2016/11/07/132827
https://www.mnet.ne.jp/~nakama/
Azure Cloud Shell を JupyterNotebok に埋め込む

# 状況

Azure のドキュメントの中で、Azure Cloud Shell を使って、その場でいろいろとコマンド実行できる便利なものがあります。これは、任意の Markdown や HTML に埋め込めるので、その簡単な手順をメモ書きしておきます。

    参考: Azure Cloud Shell の埋め込み
    https://docs.microsoft.com/ja-jp/azure/cloud-shell/embed-cloud-shell

# 注意点

Jupyter Notebook と一緒に使うと、何でもシームレスに使える気がしますが、実際にはそうではありません。あくまで、別サーバーで動いている Shell ですので、ご注意ください。

こちらのドキュメントをご一読することをお勧めします。

    Azure Cloud Shell の概要:
    https://docs.microsoft.com/ja-jp/azure/cloud-shell/overview

# Step 1. Jupyter Notebook のファイルを作成

もし、お持ちでなければ。
個人的なおススメは、無料で使える Azure Notebook です！！！

Azure Notebooks:
https://notebooks.azure.com/

# Step 2. Azure Cloud Shell 起動用のマークダウン文字列を設定

ドキュメントにもありますが、こちらの文字列をそのまま貼り付けます。

```
[![Launch Cloud Shell](https://shell.azure.com/images/launchcloudshell.png "Launch Cloud Shell")](https://shell.azure.com)
```

<img width="829" alt="AzureCloudShell-JupyterNotebookEmbedded.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/108143/aeb6c21f-88b5-4a9d-814a-11511cc1ad69.jpeg">

完了!

# Step 3. Cloud Shell 実行

<img width="655" alt="LaunchCloudShell.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/108143/e3b4dea4-b6df-736b-68d4-d5bf984e449f.jpeg">
後は、Shift + Enter で実行あるのみ。
<img width="560" alt="AfterLaunchCloudShell.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/108143/ce7faec2-8794-b7a9-bbd4-5ada247449ab.jpeg">


# おまけ
Qiita は Markdown 対応していますから、このまま起動できるでしょう😎

[![Launch Cloud Shell](https://shell.azure.com/images/launchcloudshell.png "Launch Cloud Shell")](https://shell.azure.com)
Angular[メモ]  ViewEncapsulation.Noneのとき `:host`は使えない

## コンポーネント自身にスタイルを当てたい場合、`:host` が使うことがある

```scss
:host{
 display: inline-block;  // コンポーネントの中の要素に応じた幅にしたいときとか
}

```

でも、下記のようにスタイルのカプセル化を解除していると `:host` のスタイルが当たらない

```typescript

@Component({
  selector: 'hoge',
  templateUrl: './hoge.component.html',
  styleUrls: ['./hoge.component.scss'],
  encapsulation: ViewEncapsulation.None,  // スタイルのカプセル化をしない
})

// 上記 :hostで書かれたスタイルは効かない

```

考えてみると当然かも知れない・・・

## `encapsulation: ViewEncapsulation.None`でコンポーネント自身にスタイルをあてたい場合はコンポーネント名で(普通に)あてる

```scss
hoge{
 display: inline-block;
}
```
MSYS2のホームディレクトリを変更する

きっかけ
=======
標記が必要となる事例があまりないのか探すのに苦労した。
>私のWin10環境は、初めにユーザ作る際にミスって日本語の入ったユーザ名になっている。

その時直せって話なのだろうが。。。
なぜかその時はまぁいっかでその後、特段問題になることは無かったのだけど、MSYS2を使うことになってから辛いことに。。。。

WinのファイルシステムはSJIS、LinuxはUTF-8なので日本語ファイル名をどう表示するが問題に。
Windowを見ているときはSJISにしてLinux見るときはUTF-8にして、、なんてこともあった。

これは辛すぎなので、せめてMSYS2のホームディレクトリは半角英数にしようと思った次第。

対応方法
========
環境変数に以下を追加。

```
HOME=C:\msys64\home\myhome
```

### 2019/2/5
上記の対応・・・・何も考えずにWindowsのシステム環境変数を直したら、Vagrantが起動しなくなったorz

なので、MSYSのショートカットを右クリック→エディタで編集で次の行を一番上に追加。

```
set HOME=C:\msys64\home\myhome
```


最後に
======
こんなに簡単なのになかなかたどり着けずに時間使った。。
MSYS2のドキュメント一切読んでないからなぁ。
Qiitaにしろ他のブログにしろ、MSYS2の情報は結構多いから本家見ることないのだけれど、どんな情報載ってるんだろ？？
Python 3 > データを8bitのリスト形式で返す | PEP8: do not assign a lambda expression, use a def | 失敗: LSBからの出力の前にMSBを追加していた

```txt:動作環境
ideone (Python 3.5)
```

### 処理概要

- 8bitをI2C通信に使う
- 任意のデータ(例: 0x33)のビットをリスト形式で取得

### 参考

- [printing bit representation of numbers in python](https://stackoverflow.com/questions/1054116/printing-bit-representation-of-numbers-in-python)
    - answered Jun 28 '09 at 3:00 by gahooa
    - を参考に使う
    - 8bit固定にならないため、先頭の0となるビットは追加するように実装した


### 実装 v0.1

ideone
https://ideone.com/DlqVTx

```py
MAX_BIT = 8  # for 8 bit I2c communication
adat = 0x33  # data to be sent

binary = lambda n: n > 0 and [n & 1] + binary(n >> 1) or []

res = binary(adat)
num = MAX_BIT - len(res)
cmbnd = [0 for idx in range(num)] + res  # combined 8bit

print(cmbnd)

```

```txt:実行結果
[0, 0, 1, 1, 0, 0, 1, 1]
```

### 備考

上記のコードはPEP8で通すと以下のようになる

http://pep8online.com

> do not assign a lambda expression, use a def

### 関連

- [Python > [[0.0], [0.0], [0.0], [0.0], [0.0]]を簡略表記する > [[0.]]*5 > ***やってはいけない*** / Pythonインタープリタがプログラムを解釈しながら値や変数をメモリに展開していく様子を作図していただきました / 内包表記](https://qiita.com/7of9/items/d03d099b400d9a067086)

### 失敗: LSBからの出力にMSBを追加していた
(追記: 2019-02-04)

LSB: Least Significant Bit
MSB: Most Significant Bit

上記のコードを使っていてI2C通信をしていたが、失敗をしていた。

StackOverflowのコード: LSBからの出力順番
先頭に0を足す: MSBからの順番

両者を混在したため、失敗していた。

0x34 (Binary: 110100)での出力
https://ideone.com/lGLx5n

> [0, 0, 1, 0, 1, 1]

LSBからの出力順番であることが分かる

- 失敗
    - 1. 0x33 (Binary: 110011)という反対からも同じ数値を使っていた
    - 2. LSBかMSB順番かの確認の怠り
    

### 実装 v0.2: MSB, LSBの順番を訂正 (MSBからLSBの順番)

https://ideone.com/xjdQ3o

```py
MAX_BIT = 8  # for 8 bit I2c communication
#adat = 0x33  # data to be sent
adat = 0x34  # data to be sent

binary = lambda n: n > 0 and [n & 1] + binary(n >> 1) or []  # LSB to MSB

res = binary(adat)
res.reverse()
#print(res)

num = MAX_BIT - len(res)
cmbnd = [0 for idx in range(num)] + res  # combined 8bit
print(cmbnd)

```

```txt:結果
[0, 0, 1, 1, 0, 1, 0, 0]
```
設定ファイルで環境変数を使用したい

## 前提
環境変数を設定ファイルで使いたかったので汎用的に使えそうなものを作ってみました。
コマンドとGoライブラリとして使えます。

https://github.com/nissy/envexpand

## 使い方
YAML JSON TOMLフォーマットでないと使えません。
使い方は書き換えたいファイルのパスを指定するだけです

変換前

```
$ cat example.yaml
glossary: 
  title: "example glossary"
  GlossDiv: 
    title: S
    GlossList: 
      GlossEntry: 
        ID: "$ID"
        SortAs: "$ID"
        GlossTerm: "Standard Generalized Markup Language"
        Acronym: "$ID"
        Abbrev: "ISO 8879:1986"
        GlossDef: 
          para: "A meta-markup language, used to create markup languages such as DocBook."
          GlossSeeAlso: 
            - GML
            - XML
        GlossSee: markup
```

変換後

```
$ export ID=SGML
```

```
$ envexpand example.yaml
glossary:
  title: "example glossary"
  GlossDiv:
    title: S
    GlossList:
      GlossEntry:
        ID: "SGML"
        SortAs: "SGML"
        GlossTerm: "Standard Generalized Markup Language"
        Acronym: "SGML"
        Abbrev: "ISO 8879:1986"
        GlossDef:
          para: "A meta-markup language, used to create markup languages such as DocBook."
          GlossSeeAlso:
            - GML
            - XML
        GlossSee: markup
```

ライブラリとしても使用できます
再帰的に文字列のFieldを探して置換処理をします

```
    data := ABC{
        A: "$A",
        B: []string{
            "$B",
            "$B",
            "$B",
        },
        D: &D{
            F: &F{
                I: []*I{
                    {
                        J: "$J",
                    },
                    {
                        J: "$J",
                        K: []map[int]string{
                            {
                                1: "$K",
                                2: "$K",
                            },
                        },
                        L: []string{
                            "$L",
                            "$L",
                        },
                    },
                },
            },
        },
    }
```

```
$ echo A=$A B=$B J=$J K=$K L=$L
A=AAAAA B=BBBBB J=JJJJJ K=KKKKK L=LLLLL
```

```
main.ABC{
    A: "AAAAA",
    B: []string{
        "BBBBB",
        "BBBBB",
        "BBBBB",
    },
    C: map[int]string{},
    D: &main.D{
        E: "",
        F: &main.F{
            G: 0,
            H: "",
            I: []*main.I{
                &main.I{
                    J: "JJJJJ",
                    K: []map[int]string{},
                    L: []string{},
                },
                &main.I{
                    J: "JJJJJ",
                    K: []map[int]string{
                        map[int]string{
                            1: "KKKKK",
                            2: "KKKKK",
                        },
                    },
                    L: []string{
                        "LLLLL",
                        "LLLLL",
                    },
                },
            },
        },
    },
}
```
2019年2月頭に Pipenv で新規環境作ろうとしたら出来なかった件の対応

タイトルの通り。先週頭は問題無かった気がするのだが、今日(2019年2月4日)になって新規でPipenvで環境作ろうとしたら以下のエラー

```sh
$ pipenv install --python 3.5 argparse tabulate
Creating a virtualenv for this project...
Pipfile: /Users/user/project/Pipfile
Using /Users/user/.anyenv/envs/pyenv/versions/3.5.6/bin/python3.5m (3.5.6) to create virtualenv...
〜中略〜
Locking [packages] dependencies...
lib/python3.7/site-packages/pipenv/utils.py", line 402, in resolve_deps
    req_dir=req_dir
  File "/usr/local/Cellar/pipenv/2018.7.1/libexec/lib/python3.7/site-packages/pipenv/utils.py", line 250, in actually_resolve_deps
    req = Requirement.from_line(dep)
  File "/usr/local/Cellar/pipenv/2018.7.1/libexec/lib/python3.7/site-packages/pipenv/vendor/requirementslib/models/requirements.py", line 704, in from_line
    line, extras = _strip_extras(line)
TypeError: 'module' object is not callable
```

これは、俗に言う pipenv と pip のバージョンが合ってない問題だなーと思い、いつも通り[これ](https://github.com/pypa/pipenv/issues/2924) で見た `pipenv run python -m pip install -U pip==18.0` を実行したがNG

確認すると下記の通り。

```sh
$ pip --version
pip 18.0 from /Users/user/.anyenv/envs/pyenv/versions/3.6.6/lib/python3.6/site-packages/pip (python 3.6)

$ pipenv run pip --version
pip 19.0.1 from /Users/usre/project/.venv/lib/python3.5/site-packages/pip (python 3.5)
```

多分バージョンだろうなーと思い、以下のようにしてvenv上のpipを一旦削除してから18.0を再インストールした。

```sh
$ pipenv run python -m pip uninstall pip
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ pipenv run python get-pip.py pip==18.0
```

これでちゃんと18.0になり、インストールもできた。

```sh
$ pipenv run pip --version
pip 18.0 from /Users/user/project/.venv/lib/python3.5/site-packages/pip (python 3.5)
```

対処療法ではあるんですが、備忘録。
UnityのEnumのフラグチェックをC#6っぽくしてみる


#概要

Flag属性つけてビットフラグのようにEnumを使うことが出来るが、チェック方法が若干冗長的でした。
Unityのバージョンが上がって.Net 4.x以降が使えるようになったことでデフォルトで使えるメソッドが増えました。
そんなわけで試しに使ってみる。

**環境**
Unity 2018.3.4f1


#やること

### プロジェクトの設定
UnityのProjectSetting>Playerで動かす.Netのバージョンを指定する必要があります。
これが3.x以前だと今回のサンプルプログラムのコンパイル通らないと思います。
ちなみに3.x以前が選択されていると「近々3.x消すからヨロシクね」みたいなことが警告として表示されるので、適当なタイミングで移行するのがいいでしょう。

![UnityNetFrameworksVersionSetting](https://raw.githubusercontent.com/KTA552/MediaUploader/master/img/UnityNetFrameworksVersionSetting.png)


**3.x以前**

フラグチェック時、下記のようにする必要があるため、フラグ１つのために書かなければいけないコード量が正直多くて冗長的でした。

```csharp
if ((_exportCollectColumn & columnValue) == columnValue)
{
    isToggle = true;
}
```

そのため、下記リンク先のように拡張メソッドを用意してシンプルにするのがベターでした。

[【Unity】HasFlag 関数を Unity でも使用できるようにする拡張メソッド \- コガネブログ](http://baba-s.hatenablog.com/entry/2014/08/10/130145)


**4.x以降**

下記のようにHasFlagのメソッド呼ぶだけでOKです。シンプル。

```csharp
if (_outputFlag.HasFlag(flagValue))
{
    isToggle = true;
}
```


#サンプルコード

サンプルコードのリポジトリは下記。
[UnitySandbox/EnumFlagSample\.cs at develop · KTA552/UnitySandbox](https://github.com/KTA552/UnitySandbox/blob/develop/UnitySandbox/Assets/Scripts/Debug/EnumFlagSample.cs)

## サンプルを実行した結果
![UnityEnumFlagSampleOverview.png (340×309)](https://raw.githubusercontent.com/KTA552/MediaUploader/master/img/UnityEnumFlagSampleOverview.png)

## コード部分

```csharp

    [Flags]
    enum OutputFlag
    {
        Flag0 = 1 << 0,
        Flag1 = 1 << 1,
        Flag2 = 1 << 2,
        Flag3 = 1 << 3,
        Flag4 = 1 << 4,
    }

    OutputFlag _outputFlag = OutputFlag.Flag0 | OutputFlag.Flag3;

    private void OnGUI()
    {

        using (new EditorGUILayout.VerticalScope())
        {
            EditorGUILayout.Space();

            EditorGUILayout.LabelField("GUI Toggle:");

            foreach (var item in Enum.GetValues(typeof(OutputFlag)))
            {
                var flagName = Enum.GetName(typeof(OutputFlag), item);
                bool isToggle = false;
                var flagValue = (OutputFlag)item;

                if (_outputFlag.HasFlag(flagValue))
                {
                    isToggle = true;
                }

                // 確認したフラグが違ってたら反転
                var toggleResult = EditorGUILayout.Toggle(flagName, isToggle);
                if (toggleResult != isToggle)
                {
                    _outputFlag ^= flagValue;
                }
            }

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("GUI EnumFlagsField:");
            EditorGUILayout.EnumFlagsField(_outputFlag);

            EditorGUILayout.Space();

            // 今のフラグの状態の表示
            EditorGUI.BeginDisabledGroup(true);
            {
                EditorGUILayout.LabelField("CurrentFlag", _outputFlag.ToString());
                EditorGUILayout.LabelField("FlagHexValue", _outputFlag.ToString("X"));
            }
            EditorGUI.EndDisabledGroup();
        }
    }

```
【Rails】カラムのデータ型変更方法

#経緯
Railsでの開発の際、modelのカラムのデータ型を間違えて実行してしまった。そこでデータ型の変更を試みた。以下に示す方法で無事に変更できたので、メモ。恐らく初心者向けの投稿である。

#環境
・Mac OS 10.14.3
・ATOM　1.34.0
*Macでの開発のため、Windowsでは分かりかねます。

#変更方法
以下、変更の手順である。
##1.空のマイグレーションファイルを作成する
以下の名称を持つ空のマイグレーションファイルを作成する。

```
$ rails g migration change_data_title_to_article
```

上記の場合、`article`がテーブル名、`title`がデータ型を変更したいカラム名である。

##2.作成したマイグレーションファイルに追加入力する
作成したマイグレーションファイルは/db/migrate内に存在する。ファイルを開き、class内に以下のメソッドを追加する。

```change_data_title_to_article.rb
def change
  change_column :article, :title, :text
end
```

上記の場合、`text`が新しいデータ型である。そして保存する。

##3.マイグレーションファイルをDBに反映させる
ターミナルで以下を打ち込み、DB（データベース）に反映させる。

```
$ rails db:migrate
```

これでデータ型の変更が完了である。
確認する場合は

```
$ rails c
```

でコンソールを起動して、`テーブル名.all`等で可能である。

#まとめ
割とシンプルな変更方法な気がする。仮に複数カラムのデータ型を変更する際は同様のマイグレーションファイルを作成するのだろうか。

#参考
以下の関連記事を参考にした。
[マイグレーションを使ったカラムの追加、削除、データ型の変更　[ 自分用メモ ]](https://qiita.com/dawn_628/items/13fa64dc6d600e921ce3)
[【備忘録】Rails-カラム名を変更する方法](https://qiita.com/kaito-chiba/items/723da8627438b67cc02c)
OpenCVで基本的な画像処理

[前回](https://qiita.com/int_main_Nick/items/4f3cc42cb67496ef12b4)のつづき.
今回は基本的な画像処理をまとめてメモ. 

#画像の読み込み, 書き込み, 表示
```cpp:
	cv::Mat img;
	//画像の読み込み第2引数が1であればカラー, 0であればグレースケール
	img = cv::imread("./sample.jpg", 1);
	//画像の書き込み
	cv::imwrite("filename.jpg", img);
	//画像の表示, cv::waitKey(0)などで,入力待ち状態にする必要がある
	cv::imshow("Window name", img);

```

#カラー画像のグレースケール化
カラー画像をグレースケールで読み込み

```cpp:
	cv::Mat img;
	img = cv::imread("sample.jpg", 0);
```

カラー画像をグレースケールに変換

```cpp:
	cv::Mat img = cv::imread("sample.jpg", 1);
	cv::cvtColor(img, img, cv::COLOR_BGR2GRAY);
```

#トリミング

```cpp:
	cv::Mat img;
	img = cv::imread("./sample.jpg", 1);
	//x, y(第1, 2引数)から幅, 高さ(第3, 4引数)で切り取る
	cv::Mat img_out(img, cv::Rect(100, 100, 100, 100));
```

# 直線を引く

```cpp:
	//縦横500ピクセルの真っ暗な画像を生成.第３引数で濃淡画像, カラー画像などを指定.
	//CV_8UC3は8bitRGBをあらわす
	cv::Mat img = cv::Mat::zeros(500, 500, CV_8UC3);
	//生成した画像の(0, 0)から(500, 500)まで青い線を引く.第５引数で線の太さを指定.
	//Scalar()で色の指定. Blur, Green, Redの順番で色を0 ~ 255で調節できる.
	cv::line(img, cv::Point(0, 0), cv::Point(500, 500), cv::Scalar(0, 0, 255), 5);
```

#セグメンテーション
```cpp:
	//2値化するときはグレースケールで読み込む必要がある
	cv::Mat img = cv::imread("sample.jpg", 0);
	//第3, 4引数で閾値を0 ~ 255で指定. CV_THRESH_OTSUを使うことで特に指定する必要がなくなる.
	//THRESH_BINARY_INVで白黒反転
	cv::threshold(img ,img, 0, 255, CV_THRESH_BINARY_INV | CV_THRESH_OTSU);
	//画像をぼかす
	cv::blur(img, img, cv::Size(3, 3));
```
#射影変換

```cpp:
	cv::Mat img = cv::imread("sample.jpg", 1);
	//画像サイズを縦640横480ピクセルに変更
	cv::resize(img, img, cv::Size(640, 480), 1);
	//読み込んだ画像の四角形の頂点
	cv::Point2f pts1[] = { cv::Point2f(160, 479), cv::Point2f(480,479), cv::Point2f(480, 240), cv::Point2f(160, 240) };
	//出力画像に対応する四角形の頂点
	cv::Point2f pts2[] = { cv::Point2f(160, 479), cv::Point2f(480, 479), cv::Point2f(400, 240), cv::Point2f(240, 240) };
	//射影変形行列を代入
	cv::Mat pmat = cv::getPerspectiveTransform(pts1, pts2);
	//射影変換第３引数は変換行列
	cv::warpPerspective(img, img, pmat, img.size(), cv::INTER_LINEAR);
```

#カメラの使用
画像の撮影

```cpp:
	cv::Mat img;
	//初期化
	cv::VideoCapture cap(0);
	if(!cap.isOpened()){
		std::cout << "カメラが見つかりません." << std::endl;
	}

	//カメラを読み込む
	while(cap.read(img)){
		cv::imshow("camera", img);		
		int key = cv::waitKey(0);
		//sを押すと撮影, qを押すと終了
		if(key == 's'){
			cv::imwrite("camera.jpg", img);
		}else if(key == 'q'){
			break;
		}
	}
```

動画

```cpp:
	cv::Mat img;
	//初期化
	cv::VideoCapture cap(0);
	if(!cap.isOpened()){
		std::cout << "カメラが見つかりません." << std::endl;
	}

	//カメラを読み込む
	while(cap.read(img)){
		cv::imshow("Video", img);	
		//qで終了
		if(cv::waitKey(1)=='q'){
			break;		
		}
	}

```


とりあえずはここまで.
オブジェクト指向で書いてみたいと思う今日この頃.
今スク　レイヤーソースの置き換え

#今日のスクリプトはどんなもの？
今回はレイヤーのソースの置き換えです。（複数可）

#どんな時に使う？
今回のケースはコンポジションに大量の写真があり、その写真全て差し替えたいと思ったときに。

#使い方
スクリプトを起動させるとボタンが２つあり
まずはプロジェクトパネルから置換する予定のフッテージを選択します。（配列に入る）
そして次に置換したいレイヤーを選択して実行ボタンを押せばソースが置き換えられます。

ちなみに置換する素材はランダムで設定しています。

#コード

```jsx
var winObj = (this instanceof Panel) ? this : new Window('palette', 'フッテージ置き換え', undefined, {resizeable: true});

    var contentsGrp = winObj.add('group',undefined,'contentsGrp');
    contentsGrp.orientation = 'row';
        try{
        var myBannerPath = new File (thisFolderPath+'/youtool_common/Ae_Script_banner.png');
        var banner = contentsGrp.add('image',undefined,myBannerPath);
        banner.alignment = [ScriptUI.Alignment.LEFT,ScriptUI.Alignment.CENTER];
        //~     banner.alignment = [ScriptUI.Alignment.LEFT,ScriptUI.Alignment.CENTER]
        }
        catch(e){
        }

    var button1 = contentsGrp.add("button",undefined,"置換するフッテージを配列にイン");
    var button2 = contentsGrp.add("button",[120,20,200,50],"実行");

winObj.onResizing = winObj.onResize = function () {this.layout.resize();};  

if (winObj instanceof Window) {  
winObj.center();  
winObj.show();  
} else {  
winObj.layout.layout(true);  
winObj.layout.resize();  
} 

button1.onClick = function(){
PushToArray()
}

button2.onClick = function(){
okikae()
}


//グローバル変数
var array = [];


//プロジェクトアイテムを配列に
function PushToArray(){
var selectItems = app.project.selection;
    array = [];
    for (var i = 0; i < selectItems.length; i++) {
        var myItem =  selectItems[i];//選択したオブジェクト
        var myComp = selectItems[i]; // 選択したオブジェクトの名前を取得
            array[i] = myComp;
    }
}

//選択したレイヤー
function okikae(){
var myComp =  app.project.activeItem;
var myLayer = myComp.selectedLayers;
app.beginUndoGroup("アンドゥ");
    for (var i = 0 ; i < myLayer.length ; i ++ ){
        myLayer[i].replaceSource(array[Math.floor( Math.random() * array.length+1 )],false)
    }
app.endUndoGroup();
}
```