OmniAICreator/Qiita-1.07M huggingface dataset:
（ポエム）今風のソフトウェアプロジェクト構成の常識観

※ ここでいうプロジェクトは、組織の課題遂行の単位の話ではなく、GitHubにたっている何らかのプロジェクトとか、そういう単位のプロジェクトのことを言っています。有り体にいうと `.git` があるフォルダのことを言っています。

## プロジェクトの単位

マイクロサービスであれば、マイクロサービスの単位。ほか、適当に区切りのいい単位で「プロジェクト」を作る。

普通の開発プロジェクトという総体は、複数の「プロジェクト」の成果物からなるシステムを構築・維持することになる。

## プロジェクトのファイル構造

下記のように構成するのが普通。

```
# もはや今の時代はgitをSCMとして用いるのが標準になった
.git/
.gitignore

# いわずもがなREADME。プロジェクトの設定や開発環境の上げ方などを記載。
README.md

# プロジェクトのCI定義。ビルド → 単体テスト → パッケージング → どこかにパッケージを保管 まで一続きに記述。
# ただし、あくまでこのプロジェクト固有のCIしか扱わない。他プロジェクトとの部品の絡めは書かないのが原則。
# ビルドは「あまり環境に依存しない」で、「全自動」で行えることが大事。
Jenkinsfile, .travis.yml などなど

# もっと詳細なドキュメントがあればこちら。
/docs

# ライブラリプロジェクトの場合のライブラリ利用のサンプル
/examples

# ソース。テスト用のソースフォルダは別途あるかもしれない。
/src

# プロジェクトレベルの各種設定ファイル類
.editorconfig, .babelrc などなど

# プロジェクトの依存性記述ファイルとロックファイル
Gemfile, Gemfile.lock などなど

# ビルダースクリプト。ビルドツールインストール不要でビルドを可能にさせてくれるもの。
gradlew, mvnw, lein などなど

# プロジェクトワークスペースレベルのエディタの設定ファイル
.vscode/

# Dockerビルド定義
Dockerfile

# 即時プロジェクトを立ち上げたい人用。もっぱら私はDockerfileのビルド定義を書いている。
docker-compose.yml

# ほか必要なものがたくさんあるだろう。明示的に管理しておこう。
```

## プロジェクトの依存性モジュールは？ビルドは？

プロジェクトの依存モジュールはちゃんとファイルなどに記述して管理される。

ビルド手順は特定マシンに依存しないように専用のファイルに記述される。

なるべくまっさらなマシンから簡単にゼロからビルド成功にたどり着けるのが理想的。

## プロジェクトの成果物は？

たとえば、Javaであればjarやwarなどのパッケージ化されたバイナリがビルド成果物になるが、**今の時代であればDockerイメージが一番プロジェクト成果物として利用しやすいと思う。**

基本的に [The Twelve-Factor App](https://12factor.net/ja/)に従って構成されており、安心してローカル→結合→検証→本番というように複数環境で同じものを使い回せるようになっている。

## プロジェクト成果物の保存方法

プロジェクトの成果物はビルドがすべて成功したら（コンパイル、ビルド、バンドルなどが成功したら）、バージョン番号が付与され下記のようなアーティファクトリポジトリに収められることになっている。（別に必須ではない。）

* [Docker registry](https://docs.docker.com/registry/)
* [Sonatype Nexus](https://blog.sonatype.com/)
* [JFrog Artifactory](https://jfrog.com/)

プロジェクトの成果物を使って環境を構築する時は、上記のリポジトリから直接成果物を持ってくるように構成することとなる。

## プロジェクトのバージョニング

何も指針がなければ、[セマンティックバージョニング](https://semver.org/lang/ja/)を用いればよい。

複数プロジェクトを組み合わせている場合は、複数プロジェクト間で統一した番号を用いるとかのほうがわかりやすいこともある。

## プロジェクト開発環境

* Slackのような近代的なチャット
* GitHubやGitLabなどのWeb画面付きの近代的なSCM
* CI。最近のはDocker特化型が多い。
* アーティファクトリポジトリ（上記に書いた）
* ITS。RedmineやJIRAなどの課題追跡システム。
* （LDAP。いろいろな開発環境のプロジェクトメンバ定義は一括で管理できると楽。）
* 頻繁にデプロイでき、結合検証、本番前検証できるサーバやクラスタ、クラウド環境

## git リポジトリの用い方

以下のフローか、もしくはもっとシンプルにするとかで複数人ないし一人が並列して開発できるように配慮する。

* git-flow
* GitHub Flow

そもそも複数人並列で開発するのは、無料ではできない話で、採用しているソフトウェアアーキテクチャが複数人並列開発に寛容じゃなければ、上記のフローを用いたところでまったく役に立たない。

## おわりに

このエントリに書いたようなことは、今の時代であれば、特に話題にされることがない常識だと思うが、その常識が掴みきれずに空回りしてしまう人も多いと思い、書いた。

つまり、自分のために書いた。

あとはプロジェクトメンバーを巻き込んで、SCRUMをやったり〜などと書きたいところだが、そっち方面は全然かけそうにないので、やめる。
Wio LTE の消費電力 (何もしない場合、モデムがONになってるだけの場合)

[USB型パワーメーター(電圧計/電流計) CT-2](https://qiita.com/ma2shita/items/cb024692995178a6295e) を買ったので、 [Wio LTE](https://soracom.jp/products/wio_lte/) の消費電力を計ってみました

### なにもしない状態

全く何も行わないパターンです

* 約 55mA (0.275W) で落ち着きます

![noop.png](https://qiita-image-store.s3.amazonaws.com/0/22754/a24e438a-c9ce-b7ef-0126-1b05eedf9a99.png)

```c++:スケッチ
void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}
```

### LTE モデムを ON にして PDP Context を開いた状態

PDP Context を Active 状態 (= IP 通信が可能) にして、それ以降は何もしないというパターン

* PDP Context を Active にしたあたりで瞬間的に 350mA (1.75W) まで行きます
* その後、約 85mA (0.41W) を基準に周期的に瞬間 180mA (0.90W) ぐらいまで上がる形を取ります

![modem-on.png](https://qiita-image-store.s3.amazonaws.com/0/22754/88e54b89-17ba-3ec1-5cdb-fd5c6abeef20.png)

```c++:スケッチ
#include <WioLTEforArduino.h>
WioLTE Wio;

void setup() {
  Wio.Init();
  Wio.PowerSupplyLTE(true);
  delay(500);
  if (!Wio.TurnOnOrReset()) { SerialUSB.println("TurnOnOrReset Error"); return; } 
  if (!Wio.Activate("soracom.io", "sora", "sora")) { SerialUSB.println("Activate Error"); return; }
}

void loop() {
  // put your main code here, to run repeatedly:

}
```

# あとがき

何もしなくとも 6700mAh なバッテリーで 121 時間 (5 日) という事がわかります。

次に打てる手は
* [`WioLTE#Sleep()`](https://github.com/SeeedJP/WioLTEforArduino/wiki/Reference-ja#sleep) & [`WioLTE#Wakeup`](https://github.com/SeeedJP/WioLTEforArduino/wiki/Reference-ja#wakeup) でモデム制御
* [`pwr_enter_standby_mode()`](https://github.com/Seeed-Studio/stm32f4ArduinoCore#mcu-enter-standby-mode) + RTC で MCU 制御
以上２点を検証しようと思います。

EoT
render先に変数が上手く渡らないときに確認すること

## render時の変数はパラメーター渡しが基本
パラメーターを指定することで部分テンプレートの使い回しができます

```index.html
= render 'template', group: @group
= render 'template', group: @gp
= render 'template', group: data
```
collectionで渡すと勝手にeachして、asで指定した変数に入れてくれます
変数名の指定はシンボルでも""でも可

```index.haml
= render partial: 'template', collection: @group, as: :group
= render partial: 'template', collection: @group, as: 'group'
= render partial: 'template', collection: @gp, as: :group
```
ちなみにcollectionは何も指定しないと、eachされた変数は参照先テンプレートの名前になります

```index.haml
= render partial: 'template', collection: @groups
```

```_template.haml
%p #{template.name}
```
<br />
以下renderで変数が渡らなかったとき、意外とその原因が潜む場所が多いなと思ったのでメモ
<br />
## 部分テンプレート名とインスタンス変数が違う

localsとobjectは何も指定しないと部分テンプレート名の変数に入ります
collectionの場合はeachされたものが部分テンプレート名の変数に入ります

```index.haml
= render partial: 'groups', collection: @groups
= render partial: 'groups', locals: @groups
= render partial: 'groups', object: @groups
```
```_groups.haml 
%p #{group.name}
```
この場合であれば`#{groups.name}`にする、もしくはファイル名を`_group.haml`にする
<br />
## partialだけを省略していないか？

`locals:` `object:` `collection:`は`partial:`とセットで使う
あるいは、@変数の中身が１つの場合は本記事冒頭に記載の両方省略形にする

```index.haml
= render partial: 'groups/group', locals: { group: @group }
= render partial: 'groups/group', object: @groups
= render partial: 'groups/group', collection: @groups
```
<br />
## `locals` `object`で配列を渡した時はeachしないといけない
勝手にeachしてくれるのはcollectionだけです
localsとobjectで渡された変数は配列のままなので参照先でeachしないといけない

```index.haml
= render partial: 'template', locals: {group: @groups}
= render partial: 'template', object: @groups, as: :group
```
```_template.haml
- group.each do |g| 
  %p #{g.name}
```
なので配列の時はcollectionで渡す
<br />
## @変数だけで渡している場合
参照先は同じディレクト下の@変数単数形の部分テンプレート
@変数はeachされて部分テンプレート名に入る

```groups/index.haml
= render @groups
```
```groups/_group.haml 
%p #{group.name}
```
<br />
## 同じ部分テンプレートを別の場所でもrenderしていないか？  
どこを修正してもエラーがなおらない！！
そんな時は別の場所で同じ部分テンプレートをrenderしている可能性あり

```index.haml
.contents
  %h1 人気のグループ
  = render partial: 'sample', collection: @groups, as: :group

= render 'sample2'
= render 'sample3'

.contents
  %h1 人気のアーティスト
  = render 'sample' 　◀︎◀︎◀︎◀︎ ここだ〜〜〜！！
```
<br />
<br />
#### 参考文献
Qiita [[Rails] 部分テンプレート使用時のrenderの書き方](https://qiita.com/kojiro3/items/4ce52494a4e69bc443a2)
書籍 [Ruby on Rails 5アプリケーションプログラミング](https://www.amazon.co.jp/Ruby-Rails-5%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/4774188832)
Pythonで配列をつくる（配列の動的確保と静的確保）

メモ用です

Pythonで配列を作るときの方法を自分用に
####`配列を作る際にあるのが動的確報と静的確保`####
####*動的確保*####
動的確保とは配列のサイズを自由に操作でき、後からでも増やしたり減らしたりできる。*(リストというらしい)*
Listに4*4の配列を作る

```py
List=[]
for i in range(4):List.append([0,0,0,0])
```
このやり方しか動的で4*4の配列の作り方が思い浮かばなかったです
####*静的確保*####
静的確保とはループを回すことによって、配列を作ることができる。*(タプルというらしい)*
Listに静的確保で4*4の配列を作る

```py
List = [[0 for i in range(4)] for j in range(4)]
```

やってる感じだと綺麗な配列を作るなら静的で問題はないと思う
もし特殊な形,例えば

```
List=[1,[2,5,6,7][3][3[3,5],5]]
```
みたいな配列（かなり適当だし多分使わないw）を作るなら動的でいいとおもう
numpyでも作れるらしいけど普段から配列作るのにこのやり方で特に問題はないので使ったことないです
今度使う機会があれば追加しとこうと思います
RxSwift で Reactive

# Reactive とは

変更を監視し続けられる的な感じ?

今まで、delegateや、何やらでやっていた処理を Reactiveでは違う感じでよろしくやってくれます。

公式では

Rx is a generic abstraction of computation expressed through Observable<Element> interface.

[you tube interview](https://www.youtube.com/watch?v=looJcaeboBY&feature=youtu.be)

ナイスミドルが作りました。

例えば、

UISegmentedControlでUITableViewの値を切り替える場合の処理は下記のようになります。

```swift


//
//  ViewController.swift
//  RxDemo
//
//  Created by Shichimitoucarashi on 2018/06/02.
//  Copyright © 2018年 keisuke yamagishi. All rights reserved.
//

import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {
    
    @IBOutlet weak var tableView: UITableView!    
    @IBOutlet weak var segment: UISegmentedControl!

    var items = Variable(["DEDE","LOL","LPL","DIE"])

    var disposeBag = DisposeBag()
    
    override func viewDidLoad() {
        
        super.viewDidLoad()

        let result = self.segment.rx.selectedSegmentIndex.bind { (val) in
            if Int(val) == 0 {
                self.items.value = ["DEDE","LOL","LPL","DIE"]
            }else{
                self.items.value = ["SWS","SIS","SPS","LPOP","QAQ"]
            }
        }

        self.items
            .asObservable()
            .bind(to: tableView.rx.items(cellIdentifier: "Cell")) {row,element,cell in
            
                cell.textLabel?.text = element
                
        }.addDisposableTo(self.disposableBag)
        

    }
}
```

このような感じになります。

tableViewに表示させてる、 items　変数の値を更新するだけで、切り替わります。

Reactive!
#### Reactive!
###Reactive!
# Reactive!

<img src="http://53labo.net/anzai/im/3757">

こんな感じです。
【Unity入門】Unity⇐Flask連携；Textをもらって表示する♬

これある意味、応用が無限大。。。

このところ、Flaskで物体検出Webまでやってきたので、それと今回のUnity+OculusGo連携をさらに連携しない手は無い。。。
画像までできるようになれば、リアルタイムな直接OculusGoでのリアルVR物体検出（意味不明？？）ができる。。。♬

できるのか。。

とりあえず、以下の先行事例がありました♬
【参考】
（１）[Pythonと連携する方法](https://sharkattack51.github.io/post/cs_py/)
（２）[[超初心者向け]UnityのuGUIでの文字の出し方](https://qiita.com/JunShimura/items/864054bb9710b63c1a3b)

ということで、今回はTextの受け渡しを実施してみました。
※少し苦戦しましたが、。。。

**(1)+(2)=「Flaskで```http://localhost:5000/```にアップした文字列をUnityで画面に表示する」**
ができました。

###コードは以下のとおり
flask側

```app.py
# python
from flask import Flask
app = Flask(__name__)
@app.route("/", methods=['GET'])
def index():
	return "Hello Unity"
if __name__ == "__main__":
	app.debug = True
	app.run()
```
Unity側のscript 

```GetText.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;  ////ここを追加////

public class GetText : MonoBehaviour {
    // Use this for initialization
    IEnumerator Start () {
        WWW www = new WWW("http://localhost:5000/");
        yield return www;
        Debug.Log(www.text);
        this.GetComponent<Text>().text = www.text;
    }
    // Update is called once per frame
    void Update () {
    }
}
```
Buildが通らないので、Unity側は少しコード変えています。

###ちょっとプロパティ
![gettext_properties.jpg](https://qiita-image-store.s3.amazonaws.com/0/233744/57a4f4fc-87f8-abe7-78fe-e4fdfd3de7ed.jpeg)

Unityの説明はこのPropertiesに影響するので、ここ抑えておきたいところです。
今回は、上記のようにGameObject-UI-TextをCameraPivotに張り付けました。
こんなイメージです。
![GameObject_text.jpg](https://qiita-image-store.s3.amazonaws.com/0/233744/5afa9d0d-873e-caac-90fa-8168341fc906.jpeg)

###そしてOculusGoでのイメージは。。。

画面上にHello Unityがちゃんと表示出来ました！
Log出力も出ている！
![HelloQuery.jpg](https://qiita-image-store.s3.amazonaws.com/0/233744/19b7c881-3736-296d-f1e8-34e237b5ac00.jpeg)

そしていよいよOculusGoの画面では。。

無いHelloUnityが無い。。。。
HelloUnityの文字がどこにも無い。。。トホホ

さてさて、。。。またバグ探しの旅が始まるぅ。。。
###まとめ
・Unity+Flask連携が出来た

・Unity+Flask＋OculusGo連携は失敗
・OculusGoでのText表示の仕方一からやり直し。。そういえばやってなかった
・画像も挑戦したい。。。
anyenv のススメ。開発環境のバージョンを一括管理。node や python など。

## １．はじめに
今更ですが Qiita 作成のため、記念投稿。

[anyenv](https://github.com/riywo/anyenv) は **env をまとめて管理できるお気に入りのツール。

**env は開発環境のバージョン管理ツールで、Python、Ruby、Node.js などなどあり、
これらをまとめて管理できる。詳しくは、作者の [ブログ](https://blog.riywo.com/2013/06/22/155804/) 等をどうぞ。

---

## ２．さっそくインストール
環境は Lubuntu 18.04 i386 (32bit、64 bit で特に差はない) 
.bashrc にパスと作業フォルダの設定

```~/.bashrc
export PATH=$HOME/.anyenv/bin:$PATH

if which anyenv > /dev/null; then eval "$(anyenv init -)"; fi
```

.bashrc を再読み込み。

```
source ~/.bashrc
```
---

必要なコードを git から適当に。

```
git clone https://github.com/riywo/anyenv ~/.anyenv
anyenv install --init
```

確認

```
anyenv --version
anyenv versions
```
---

## ３．インストール可能な **envs

```
anyenv install -l
```

|**envs|language|**envs|language|**envs  |language|
|:-----|:-------|:-----|:-------|:-------|:-------|
|Renv  |R       |hsenv |Haskell |pyenv   |Python  |
|crenv |Crystal |jenv  |Java    |rbenv   |Ruby    |
|denv  |D       |luaenv|Lua     |sbtenv  |sbt     |
|erlenv|Erlang  |nodenv|Node.js |scalaenv|Scala   |
|exenv |Elixir  |phpenv|PHP     |swiftenv|swift   |
|goenv |Go      |plenv |Perl    |        |        |

---

せっかくなので全部インストール。

```
anyenv install -l | grep -I  env$ | xargs -I{} anyenv install {}
```

まとめてアップデート

```
anyenv versions
anyenv update
```
---

.bashrc 更新

```
source ~/.bashrc
```
---

## ４．**envs の root

```
echo $(anyenv root)
echo $(Renv root)
echo $(crenv root)
echo $(denv root)
echo $(erlenv root)
echo $(exenv root)
echo $(goenv root)
echo $(hsenv root)
echo $(jenv root)
echo $(luaenv root)
echo $(nodenv root)
echo $(phpenv root)
echo $(plenv root)
echo $(pyenv root)
echo $(rbenv root)
echo $(sbtenv root)
echo $(scalaenv root)
echo $(swiftenv root)
```

以上。 **env の用法は各 **env の解説記事を参照のこと。
rhel7 + zabbix3.4 + MariaDB on AWS

#使用したコマンド
`sudo su -
cat /etc/system-release
cat /proc/version
passwd root`

`setenforce 0`

`cp -p /usr/share/zoneinfo/Japan /etc/localtime
vi /etc/locale.conf`
*NG=ja_JP.UTF-8*

`reboot`

`setenforce 0`

`rpm -ivh http://repo.zabbix.com/zabbix/3.4/rhel/7/x86_64/zabbix-release-3.4-2.el7.noarch.rpm
vi /etc/yum.repos.d/redhat-rhui.repo`
*enabled=1*

```yum-config-manager --enable rhel-7-server-optional-rpms
yum install zabbix-server-mysql zabbix-proxy-mysql zabbix-web-mysql
vi /etc/yum.repos.d/mariadb.repo```
*# MariaDB 10.3 RedHat repository list - created 2018-06-11 13:28 UTC*
*# http://downloads.mariadb.org/mariadb/repositories/*
*[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.3/rhel7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1*

`yum install MariaDB-server MariaDB-client
systemctl enable mariadb
systemctl start mariadb
systemctl status mariadb`
`mysql -uroot -p
create database zabbix character set utf8 collate utf8_bin;
grant all privileges on zabbix.* to zabbix@localhost identified by 'zabbix';
quit;`

`zcat /usr/share/doc/zabbix-server-mysql*/create.sql.gz | mysql -uzabbix -p zabbix
vi /etc/zabbix/zabbix_server.conf`
*DBPassword=zabbix*

`systemctl enable zabbix-server
systemctl start zabbix-server`

`vi /etc/httpd/conf.d/zabbix.conf`
*php_value date.timezone Asia/Tokyo*

`systemctl enable httpd
systemctl start httpd`

http://18.182.6.117/zabbix/
![スクリーンショット 2018-06-12 00.26.50.png](https://qiita-image-store.s3.amazonaws.com/0/207810/b5a43dc9-4fda-7f6c-7efc-930e1491b46a.png)

#参考文献
EC2 RHEL 7 へZabbix Server 3.4 をインストール
https://qiita.com/130cmWolf/items/ef9f172e3cca6f38d584
Zabbix Documentation 3.4
https://www.zabbix.com/documentation/3.4/manual/installation/install_from_packages/rhel_centos
Downloads Setting up MariaDB Repositories
https://downloads.mariadb.org/mariadb/repositories/#mirror=yamagata-university&distro=RedHat&distro_release=rhel7-amd64--rhel7&version=10.3

#ログ
https://docs.google.com/document/d/1OZHyVwHfz3Qyu-KgJ3akEAngAMji6OpGXUk6hyZDcvI/edit?usp=sharing
USB型パワーメーター(電圧計/電流計) CT-2 の使い方

[Wio LTE](https://soracom.jp/products/wio_lte/) 君の消費電力を実測するために USB 型の電圧/電流計を何個か買ってみたのですが、残念なことに電流が 30mA くらいを下回ると自動的に OFF になってしまったり、積算してくれないといった問題がありました。

そこで一念発起して探してみたら [AVHzY 社の CT-2](http://amz.avhzy.com/index.php/2017/12/11/avhzy-usb-power-meter-tester-usb-multimeter-usb-load-current-tester-voltage-detector-dc-6a-26v-0-0001a-test-speed-of-chargercablescapacity-of-power-bankpd-2-03-0-qc-2-03-04-0-or-pps-trigger/) という製品を [Amazon.co.jp で見つけた (7777 円)](https://amzn.to/2JvvoWQ) のでレポートします

## 使ってる様子

まずは使ってる様子をご覧ください。2行目が電流ですが 100 μA までの単位まで取れています[^1]
[^1]: 精度はどの程度か正直分かりませんが、mAの1桁台まで出てくれるのはうれしい

![ct-2/ct-2](https://docs.google.com/drawings/d/e/2PACX-1vT8S7r_9Llr1eNK5wgrLmscusdXWXJHKplI4f48XbkW8XrQTTOoHqUoKnZtzJI7L3IRyyLjy3KtsRdD/pub?w=399&h=299)

また PC に接続してデータを見ることができる microUSB ポートもあります

![ct-2/with-pc](https://docs.google.com/drawings/d/e/2PACX-1vR7_ElMozYQ_VF_sTwlGj9xKc3uLPCCuIUB4PxtW_sLKymlxbeST-3zuMurXuKVjA_P8dqQELcDxKxN/pub?w=621&h=468)

## 使い方

https://www.avhzy.com/forum/ からマニュアル PDF や CT-2 のファームウェア＆Windows 用ソフトウェアがダウンロードできます。登録など不要なのが素敵です。
ここでは Getting Start 的な紹介をします。

### ともかく CT-2 本体で計測したい

USB Type-A に挿すだけです。それだけで画面表示してくれます。

### PC で計測したい

* [AVHzY CT-2 Download Manuals Firmware PC software V1.79.1(18.5.21)](https://www.avhzy.com/forum/forum.php?mod=viewthread&tid=1&extra=page%3D1) の中にある `AVHZY CT-2 App V1.79.1 Build 180521.zip` をダウンロードします
* ZIP を展開した先の `KotomiApp.exe` を実行します
    * ※SmartScreen ダイアログが出てきた場合は "詳細情報" をクリックした後に実行してください (自己責任でお願いします)
* AVHzY CT-2 ソフトウェアの [ドライバ] -> [ドライバのインストール] で STM32 Virtual COM Port driver をインストールします

これで接続すれば計測データを PC で見ることができます。CSV での出力も可能です。
ちなみに電流が小さめのデバイスを計測する場合は「開始電流」「終了電流」を 1mA 程度にしておかなと計測してくれません。

![ct-2/software](https://docs.google.com/drawings/d/e/2PACX-1vTkgDuVwH3ij_8UNWiX4qJY5WzRjNychdYMM80Kf_oagcIGbnYYwc4J--ZBmUjkGmCt-4U3esS0r5QP/pub?w=580&h=309)

### ファームウェアをアップデートしたい

* あらかじめ *PC で計測したい* を参考に、 **AVHzY CT-2 ソフトウェア** のセットアップを済ませておいてください
* CT-2 を PC から抜いておいてください
* AVHzY CT-2 ソフトウェアの [高度なオプション] -> [ファームウェア更新] を選択して CT-2 の接続待ちにします
* CT-2 の Multi-Key を左に押したまま CT-2 の microUSB と PC を接続するとアップデートが自動的に始まり、リセットまで行ってくれます
    * 注意1: CT-2 の USB-A を挿しても何も起こりませんのでご注意を。
    * 注意2: Mbed が入っているらしく、左を押したまま接続すると USB ディスクとして見えます。この状態で fw ディレクトリの `fw.KotomiPremium` を USB ディスクへコピーすれば動くよ、と forum には書いてあるのですが、私はうまく行きませんでした。 `invalid firmware` とか表示されても大丈夫です。慌てず AVHzY CT-2 ソフトウェアからアップデートしましょう

## アクリルカバーの取り付け方

アクリルカバーがついています。が、これは自分でネジを取り外したうえで取り付けるという仕組みです。
頑張りましょう。

![ct-2/cover](https://docs.google.com/drawings/d/e/2PACX-1vSN4iT6f7vJcfOhaIZw9_DoHMB0oS7W0R5vuXZyou8CNCd3LiWUhL5HBCPGVevytQ_t8J0TmbweBP4D/pub?w=535&h=401)

## 付属の謎 USB デバイス

ファンがついた謎の USB デバイスが同梱されています。
これは USB 機器に電流的負荷をかける罪づくりなデバイスです。

CT-2 に接続してつまみを調節するとで負荷量が調節できます。(以下、動画)
[![](http://img.youtube.com/vi/V1ZVjYzzzkA/0.jpg)](http://www.youtube.com/watch?v=V1ZVjYzzzkA)

その後は、たとえば CT-2 と共にモバイルバッテリーに取り付けて、実際の容量を確認するといったことに使えます。

# ちなみに：いままで買った USB 型電圧/電流計

* [Route R / RT-USBVACT1](http://route-r.co.jp/?p=2690) / 1400 円くらい
* [RT-USBVATM](http://route-r.co.jp/?p=2244) / 1200 円くらい

# あとがき

非常に良かった。最初からこれ買っておけばよかった。。。

EoT
WSL のデフォルトシェルを切り替える

# 結論
少なくとも Fall Creators Update 以降では `chsh -s` が使用できる。

例:

```sh
chsh -s $(which zsh)
```

# 注意点

## WSL の起動方法の違い
PowerShell など他のシェルから WSL を起動する方法は主に3つある。
`bash(.exe)` , `wsl(.exe)` , `ubuntu(.exe)` (ディストリビューション名.exe)
がある。
このうち `bash(.exe)` で起動した場合、強制的に `/bin/bash` で起動されるため、 `chsh -s` で設定した後でも `/bin/bash` で起動される。
コマンドを引数で渡したい場合、 `bash` と `ubuntu` の場合

```shell
> bash -c $command
> ubuntu -c $command
```

と `-c` をつけるが、 `wsl` の場合

```shell
> wsl $command
```

と何もつけず直後にコマンドを書く。
また、 `bash` / `wsl` で起動した場合はカレントディレクトリで起動される。
`ディストリビューション名.exe` で起動した場合は Linux におけるホームディレクトリで起動される。

# トラブルシューティング
いくつか切り替えを繰り返している内にWSL が起動直後に落ちるようになってしまった。
自分の場合、 `ubuntu` で `chsh -s $(which fish)` で `fish` に切り替えた後、 `chsh -s (which zsh)` で `zsh` に戻そうとしたら発生することがあった。
シェルによるかもしれないしディストリビューションによるかもしれないし、原因不明。

## 起動できなくなった場合の対処法
PowerShell などから

```shell
> bash
> wsl /bin/bash
> ubuntu -c /bin/bash
```

と起動シェルを指定すれば起動できる。( `/usr/bin/zsh` などでも可)
しかし、 `chsh -s $(which zsh)` で `zsh` に切り替えようとしても、
password を求められ、入力しても `PAM Authentication failure` で失敗し、切り替えられなかった。
その時は、 `sudo vim /etc/pam.d/chsh` のうち `auth required pam_shells.so` の行をコメントアウトした後
`sudo chsh -s $(which zsh)` でデフォルトシェルを `zsh` に戻すことができた。

# 参考
- [Medium - Set and use Zsh as default shell in WSL on Windows 10 the right way](https://medium.com/@uniqvinh/set-and-use-zsh-as-default-shell-in-wsl-on-windows-10-the-right-way-4f30ed9592dc)
- [GitHub.com/robbyrussell/oh-my-zsh - chsh: PAM authentication failed on Ubuntu 12.04 #1224](https://github.com/robbyrussell/oh-my-zsh/issues/1224)
[python] データ数を指定してCryptowatchからデータを取得する Get a specified num of data from Cryptowatch


Cryptowatchから(a)のようにデータをリクエストすると500データしか取得できないので、500データ以上取得するためのコード＋pandasに落とし込むコードを書いたのでシェアします。
If you send request code to cryptowatch like below(a), you get 500 data but I assume a lot of people want more data. so I am going to share the code to get more than 500 data at a time and put them in padas dataframe.

######参考
> Cryptowatch API: https://cryptowat.ch/docs/api#price




**(a) 500データ取得時 When getting 500 data**
※paramsには欲しい時間足を入れます　(e.g 1分足 = "60", 5分足 = "300")

```python:price.py
import json
import requests
price = json.loads(requests.get("https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc",params="60").text)["result"]
print(price)
```

price.py実行結果　result of execution
<img width="441" alt="3.png" src="https://qiita-image-store.s3.amazonaws.com/0/227427/80ecfcac-7cad-dbee-56e1-9948262060ef.png">





**(b)全体のコード the whole code**
6000 data from Cryptowatch -> remove unnecessary data -> pandas

```python:crypto.py
import json
import requests
import pandas as pd
import datetime
import time

def crypto_watch(candle,before,size):
    url="https://api.cryptowat.ch/markets/bitflyer/btcfxjpy/ohlc?periods="
    candle=candle*60
    period=("%s"%(candle))
    period=[period]
    beforeurl="&before="
    afterurl="&after="
    #The maximum size of data is 6000 depending on a timing (sometimes you get less than 6000)
    after= before-(candle*size)
    URL=("%s%s%s%s%s%s"%(url,candle,afterurl,after,beforeurl,before))
    #e.g https://api.cryptowat.ch/markets/bitflyer/btcjpy/ohlc?periods=86400&after=1483196400
    res=json.loads(requests.get(URL).text)["result"]
    data = []
    for i in period:
        row = res[i]
        for column in row:
            if column[4] != 0:
                column = column[0:6]
                data.append(column)
    date = [price[0] for price in data]
    priceOpen = [int(price[1]) for price in data]
    priceHigh = [int(price[2]) for price in data]
    priceLow = [int(price[3]) for price in data]
    priceClose = [int(price[4]) for price in data]
    date_datetime = map(datetime.datetime.fromtimestamp, date)
    dti = pd.DatetimeIndex(date_datetime)
    df_candleStick = pd.DataFrame({"open" : priceOpen, "high" : priceHigh, "low": priceLow, "close" : priceClose}, index=dti)
    return df_candleStick

print(crypto_watch(1,round(time.time()),6000))
```


crypto.py 実行結果　result of execution
<img width="246" alt="6_11.png" src="https://qiita-image-store.s3.amazonaws.com/0/227427/1aa15478-ecb5-0225-1125-2ab63dba098b.png">







**このモジュールの使い方　How to use this module**
`crypto_watch(candle,before,size)`
candle = 時間足 (e.g 1分足 = 1, 5分足 = 5) Timeframe of candlestick (e.g 1min = 1, 5min =5) 
before = 今のUNIXTIME current unixtime
size = data size (e.g 6000 data = 6000)


他にもきれいな書き方、もしくは他のコードを使用した取得方法がありそうなので、ご存じの方がいらっしゃいましたらコメントを頂ければ幸いです。
Please leave your comment if there is any ways to make the code better or any other ways to get more than 500 data
because it does not look like a perfect to me in some ways.
WinActorの動作が遅くなったときに確認すること

#ファイルサイズを確認する
最近、シナリオの起動と保存が異常に遅くなっていた。
PCのスペック的にこんなもんかと思っていたのだが、気づくとシナリオファイルが100MBを超えており、それはないだろと調べたところ、画像認識ターゲットのイメージ（スクリーンショット）が大量に残っていた。
テスト後にフローチャートの要らないノードを整理したつもりでも、そこで使用されていたイメージはノードとは切り離されたまま消されず残るようだ。

フローチャートのイメージの管理![image.png](https://qiita-image-store.s3.amazonaws.com/0/141560/f729092e-a5f6-ba27-066e-4e6b98ba804a.png)から、ノードで使用されていないイメージ（+表示のないもの）は残さず削除してあげましょう。

#イメージを消す際の注意
~~大量にあるイメージを消すのがめんどくさくなっても全削除で楽をしてはいけません。たぶん。
使われていない画像（+表示のない）のみを丁寧に消しましょう。~~
※![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141560/df58ad43-e4bb-5510-22f3-10cb2a01dc2b.png)『未使用イメージ削除』で消せば一発完了でした！
vue-cli で作成したプロジェクトを最小限？の編集でHerokuにデプロイするメモ

# 概要
vue-cli で作成したプロジェクトをベースに技術検証をして同僚にデモをしたかったのでHerokuにデプロイしたくなりました。
デフォルトの状態ではうまく動かないので調査した結果をメモします。

基本的には [こちら](https://medium.com/netscape/deploying-a-vue-js-2-x-app-to-heroku-in-5-steps-tutorial-a69845ace489) の記事を参考にさせていただきました。
しかしビルドした成果物をリポジトリにコミットしているため、コミットしないように改善しました。

# 結果
[こちら](https://github.com/skta3569/vue-cli-heroku)

# 環境
各種環境とツールのバージョンはこちらです。

```bash:環境
vue-cli-heroku> node -v
v8.11.1
vue-cli-heroku> npm -v
6.1.0
vue-cli-heroku> vue -V
2.9.6
```

**【重要】**
こちらの設定を行わないと成果物をビルドする際に必要なライブラリがダウンロードされず動きません。

```bash:Heroku環境変数設定
vue-cli-heroku> heroku config:set NPM_CONFIG_PRODUCTION=false
```

# 変更点
[こちら](https://github.com/skta3569/vue-cli-heroku/commit/e3d0961565ddbe46ad00394d32978f61fa71e049)

## package.json 修正
nodeプロジェクトをHerokuにデプロイすると「npm start」が実行されるため、
production用のビルドと成果物を配信するサーバーを立ち上げる処理に変更します。

```diff:package.json
diff --git a/package.json b/package.json
index ae062d4..e49b481 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
   "private": true,
   "scripts": {
     "dev": "node build/dev-server.js",
-    "start": "node build/dev-server.js",
+    "start": "npm run build && node server.js",
     "build": "node build/build.js",
     "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
     "e2e": "node test/e2e/runner.js",
```

## 配信用サーバー新規作成

```diff:server.js（新規作成）
diff --git a/server.js b/server.js
new file mode 100644
index 0000000..7023599
--- /dev/null
+++ b/server.js
@@ -0,0 +1,11 @@
+var express = require('express');
+var path = require('path');
+var serveStatic = require('serve-static');
+
+app = express();
+app.use(serveStatic(path.join(__dirname, "/dist")));
+
+var port = process.env.PORT || 5000;
+app.listen(port);
+
+console.log('server started '+ port);
```

# 参考サイト
[Easily deploy a Vue + Webpack App to Heroku in 5 Steps [tutorial]](https://medium.com/netscape/deploying-a-vue-js-2-x-app-to-heroku-in-5-steps-tutorial-a69845ace489)
[Heroku Node.js Support](https://devcenter.heroku.com/articles/nodejs-support#package-installation)
CLIでもスクショをScrapboxにアップしたい

# これは何？
WebページのスクリーンショットをCLIから[Scrapbox](https://scrapbox.io)へアップロードできます

**GithubのTwitterページのスクショをアップロードしている例**
![scrapbox.gif](https://qiita-image-store.s3.amazonaws.com/0/144707/d2ff629a-00b5-7ef0-3c6a-bacf0efcf03c.gif)

CLIですべて完結するので，`crontab`などと組み合わせて 自動監視bot みたいなものもできます

※最新版はここに置いておきます
[blue0513/upload-image-to-scrapbox](https://github.com/blue0513/upload-image-to-scrapbox)

# セットアップ

### 0. git clone

Githubからprojectファイルをcloneします
以降このディレクトリで作業します

```sh
$ git clone git@github.com:blue0513/upload-image-to-scrapbox.git
$ cd upload-image-to-scrapbox
```
### 1. gemのインストール

[rbscreenshot](https://github.com/kaiinui/rbscreenshot)というWebページのスクショを取ることができるrubyのgemを導入します

```sh
$ bundle install
```
### 2. configの編集

[gyazo](https://gyazo.com/oauth/applications)経由でscrapboxへ画像のリンクを貼り付けるため， [ここから](https://gyazo.com/oauth/applications)gyazoの`Access Token`を取得します
（注：gyazoへのユーザ登録が必要です）

```config
project=[YOUR_SCRAPBOX_PROJECT_NAME]       <== scrapboxのproject名
title=[YOUR_SCRAPBOX_TITLE]                <== scrapboxの記事タイトル
access_token=[YOUR_SCRAPBOX_ACCESS_TOKEN]  <== gyazoのaccess token
base_file_path=[YOUR_WORKING_DIRECTORY]    <== 作業ディレクトリ
```

# 使い方

めっちゃシンプル！

```sh
$ ./main.sh [URL]
```
GSONでLocalDateTime型をserialize,deserializeする方法

GSONを使用して、LocalDateTime型をserialize,deserializeする場面にあったので、使用方法をメモします。

#対象クラス
SampleDtoのなかにLocalDateTime型のメンバーがあります。

```java:SampleDto.java
public class SampleDto implements JsonSerializer<SampleDto>, JsonDeserializer<SampleDto> {
	private static final long serialVersionUID = 8349420239867344581L;

	private String key;
	private LocalDateTime localDateTime = LocalDateTime.now();

	public SampleDto(String key, LocalDateTime localDateTime) {
		this.key = key;
		this.localDateTime = localDateTime;
	}

	@Override
	public JsonElement serialize(SampleDto src, Type typeOfSrc, JsonSerializationContext context) {
		DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
		JsonObject result = new JsonObject();
		result.add("key", new JsonPrimitive(key));
		// LocalDateTime Serialize
		result.add("localDateTime", new JsonPrimitive(formatter.format(localDateTime)));
		return result;
	}

	@Override
	public SampleDto deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
			throws JsonParseException {
		DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
		final JsonObject jsonObject = json.getAsJsonObject();
		String key = jsonObject.get("key").getAsString();
		// LocalDateTime Deserialize
		LocalDateTime localDateTime = formatter.parse(jsonObject.get("localDateTime").getAsString(),
				LocalDateTime::from);

		return new SampleDto(key, localDateTime);
	}

	public LocalDateTime getLocalDateTime() {
		return localDateTime;
	}
}
```

# テストクラス
テストクラスも以下のように作成しました。

```java:SampleDtoTest.java
ublic class SampleDtoTest {
	private static Gson gson;
	private static final GsonBuilder gsonBuilder = new GsonBuilder();
	private static SampleDto sampleDto;

	@BeforeClass
	public static void createGson() {
		gsonBuilder.registerTypeAdapter(SampleDto.class, new SampleDto("test", LocalDateTime.of(2018, 06, 11, 00, 00)));
		gson = gsonBuilder.create();
	}

	@BeforeClass
	public static void generateData() {
		sampleDto = new SampleDto("test", LocalDateTime.of(2018, 06, 11, 00, 00));
	}

	@Test
	public void testJSON() {
		String json = gson.toJson(sampleDto);
		SampleDto fromJson = gson.fromJson(json, SampleDto.class);
		assertTrue(fromJson.getLocalDateTime().equals(sampleDto.getLocalDateTime()));
	}
}
```
Railsの複数チェックボックスで必須チェック

collection_check_boxesで生成したチェックボックス群で一つでもチェックが入ってなかったらエラーにする方法を紹介します。

```erb
<% #erbで %>
<%= form.collection_check_boxes :my_check_boxies, ..., include_hidden: false %>
```

```rb
# モデルで
validates :my_check_boxies, presence: true
```

collection_check_boxesはデフォルトでチェックの入ってない時、空文字を送信します。何もチェックしないで送ると`[""]`が送信されてきます。これを必須チェックするには独自バリデーションを作らないと無理そうです（もしできるなら教えてください）。

そこで、チェックが入っていない時、何も送られてこないように`include_hidden: false`で設定します。そうするとチェックを入れてない時何も送られてこないので`presence`でチェックが可能です。

私の検索方法が悪かったのか、意外に見つからなかったので共有します。
初心者のためのdockerでRuby on Railsを動かす方法

DockerもRubyも全く知らない初心者が、Docker for Windowsで色々弄ってみて何とかサマになったので、一緒に作業している同期に共有するためにもメモとしてまとめる感じの記事

Windowsでdockerを動かそうとしたものの、色々手こずって時間を無駄にしてしまったので、システムとして必要な部分が用意できるまでの作業手順をメモ代わりに投稿

# Docker for Windowsで「Yay! You're on Rails!」を出すまで
## 1. docker for Windowsをインストール
導入手順はこの記事では省略。
注意点としてはHyper-Vの有効化を忘れないでください。

--追記--
どうやらdocker for windowsに必要なHyper-Vは、windows proでしか有効化できないようです。proではない方はdocker toolboxを使ってください。

## 2. RubyとMySQLのイメージをインストール
Dockerが動いていれば、イメージは以下のコマンドで落とせます。

```
docker pull ruby:2.5.0
docker pull mysql
```

詳しい説明はこちらの記事で
https://qiita.com/togana/items/30b22fc39fe6f7a188ec

## 3. Dockerの環境構築
Dockerfile・docker-compose.yml・Gemfile・Gemfile.lockが必要

詳しい書き方は、この記事が分かりやすかったです
https://qiita.com/wMETAw/items/8cb41425a5d0bdace2df

## 4.Railsアプリを作成
```
docker-compose run web rails new [app_name] --database=mysql --skip-bundle
```

## 5.Docker起動
build & 起動

```
docker-compose build
docker-compose up -d
```

build時にbundle installで詰まった場合は、SettingsからShared Drivesを有効化したり、firewallを無効にしたり、Dockerを再起動したり、色々試してみてください。

## 6.Yay! You're on Rails!
(3で紹介した記事通りにdocker-compose.ymlを設定した場合は)localhost:3000にアクセスすれば「Yay! You're on Rails!」の画面が出るはず

サーバーの起動が確認できた後は、

```
docker-compose down
```
でキチンとコンテナを停止させましょう。

# ページを作成するまで
localhost:3000にトップページを作る場合の話
## 1.controllerの作成
これでlocalhost:3000/home/topが自動生成される

```
rails g controller home top
# rails g controller コントローラ名 アクション名
```

## 2.viewの作成
./app/views/homeの中にあるtop.html.erbがHTMLソース(厳密にはHTMLではないが)
表示したいようにtop.html.erbを編集する

## 3.routingの設定
./configの中にあるroute.rbを以下のように編集する

```
Rails.application.routes.draw do
  get "/" => "home#top"

end
```

これでlocalhost:3000/homeにアクセスした時に、top.html.erbが表示されるようになる

# データベースが使えるようになるまで
※参考
https://qiita.com/nak1114/items/1f7d48ff661555726427
https://www.rubylife.jp/rails/ini/index6.html
特に二つ目は凄く分かりやすい記事なので、初学者は読んだ方が良いです。

## 1. Databaseの永続化
Databaseを永続化させないと、buildする度にデータが吹っ飛びます。
永続化は、docker-compose.ymlのdatabaseコンテナの設定に以下を追加する。

```
volumes:
    - mysql-data:/var/lib/mysql
```

portsの設定も追加しましょう

## 2. Databaseの作成
まずはDBの作成

```
docker-compose run --rm web rake db:create
```

これで./dbに色々ファイルが作成される

--追記--
今はrakeコマンドを使うのは古いそうなので、railsコマンドで叩いた方が良いそうです。

```
docker-compose run --rm web rails db:create
```

次にmodelの作成

```
docker-compose run --rm web rails g model [model_name]
```

これで./db/migrateに**マイグレーションファイル**が作成される

次にテーブルの定義
作成されたマイグレーションファイルに、テーブルの定義を追記する。

```
class CreateBooks < ActiveRecord::Migration[5.1]
  def change
    create_table :model_name do |t|
      t.string :name  //ココ
      t.timestamps
    end
  end
end
```

t.timestampsは色々便利なので、消さない方が良いです。

最後に、マイグレーションファイルに従ってマイグレーション

```
docker-compose run --rm web rails db:migrate
```

# おわりに
他にも必要そうな事があったら追記しようと思います。

追記　2018/06/13
https://qiita.com/chocode/items/61b91aa0e08637a8ad91
続編を書きました。DBにデータを入力するための入力フォームの作り方です。
はじめてのfuserコマンド


portからそれを呼んだコマンド、ユーザがわかるのすごい！！！

![スクリーンショット 2018-06-11 23.55.02.png](https://qiita-image-store.s3.amazonaws.com/0/24737/cba2a965-6b3f-e836-f23f-e92e014ebbb8.png)

> http://www.atmarkit.co.jp/flinux/rensai/linuxtips/239portuserchk.html
Exception


# 独自の例外クラスの定義
```
/// <summary>
/// Timeoutにより発生する例外クラスです。
/// </summary>
public class TimeoutException : Exception
{
    public int Timeout { get; }

    public TimeoutException(string msg) : base(msg)
    {
    }

    public TimeoutException(string msg, int timeout) : base(msg)
    {
        Timeout = timeout;
    }
}
```

# 例外をスロー
* ExceptionにはStackTraceというプロパティが含まれている。
* StackTraceでコード上のどの部分から例外が発生したかわかる。
* "throw ex"よりも"throw"のほうが情報が多い。
* "throw ex"と書くと、throwした時点のStackTraceに置き換わる。

```
try
{
    // test.txtが存在しない場合、例外が発生する
    using (StreamReader sr = new StreamReader("test.txt"))
    {
        while (sr.EndOfStream)
        {
            System.Diagnostics.Debug.WriteLine(sr.ReadLine());
        }
    }
}
catch(FileNotFoundException ex)
{
    //throw ex;
    throw;
}
```

* "throw ex"と書くと、下記がStackTraceに含まれない。"throw"には含まれる。

```
場所 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
場所 System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
場所 System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
場所 System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean checkHost)
場所 System.IO.StreamReader..ctor(String path)
```
エンジニアの存在意義と IT 技術の潮流

# 何これ
ポエムです。一応Qiitaに載っけても強制削除はされないくらいギリギリな感じの。読んでもいいけどオチも教訓もないよ。私から見た IT技術の見え方がわかるくらい。

あと、とっちらかってます。どちらかというと（一般のスキルを持った）エンジニアの存在意義に悲観的な立場。なので反論コメントが欲しいかも。


# プラットフォーマの囲いこみを想う
クラウドなんかが一番わかりやすい。プラットフォームがあって便利な機能を提供してくれるので、システムを構築するのはとても楽になっている一方、プログラマはAPI叩くだけのお仕事になりつつあるなあ、と。しかもAPIの使い方は日進月歩で変わる(改善される）ので覚えても強みにならないなあ、と感じる次第。当然覚えないよりは覚えた方がいいに決まっているけれど。

例えば、Ciscoのスイッチ設定ができたり、PostgreSQLの冗長構成組んだりすることができることって手に職って感じだし、今でも勿論大事なんだけど、そんな人材を 200万/月 で雇うよりクラウドでさくっと作った方が安いし、なにより手離れがよい（属人化を避けられる）ので負債になりにくいよね。AWS, Azure, GCPの中の人なんかはその分すごい大変なんだろうけど、使う側はそんなの気にしないし。

API叩くだけなら仕事が楽になったのか？といえばあんまりそうでもなくて、使い方のドキュメントもそこそこ読まなきゃいけないし、標準化とかされてないので同じようなことを違うプラットホームでは別の流儀で実装しなくちゃいけなかったり。何か振り回されているだけでスキルアップっていうイメージじゃないんだよなあ。

まあ、プログラミングを道具として捉えるなら、一人の人間ができる範囲が一気に拡がったと言えるので、なんというか俺つえー感を醸し出せたり（例えばWebサービスを作ってみた）するのは仕事じゃなければいい時代なのだとは思う。

結局価値をどこに置くかなんだろうな。色々便利になった分、顧客の要望をきっちり満たす提案ができるともいえるわけで（例えばバックアップを日本、アメリカ、ヨーロッパに多重において置くとか）そういうところに価値を見出すようにしないと競争力は得られないんだろうな。ただの技術オタクはお呼びでないって感じで。

プログラム書いて動いたのみてすげーって思った原体験をモチベーションに業界に入った人とか結構いると思うし、自分もそのクチだけど、なんかそんな単純なモチベーションではやっていくのが難しいのかな、と。

# ITはビジネスのはしためなのか？
どの業界も程度の差こそあれ、IT、特にインターネットを基盤とした技術が業務に完全に組み込まれてるよね。ホテル・飛行機の予約とかWebサイトなしでやるのもう考えられないし。

その結果なのかはわからないけど、ITシステムにどうしても技術以外の要素が入ってくる。何とか退会させないような UI を作っているエンジニアとか本当に気の毒に思うよ。

自分の価値観は「技術的に面白いか？」＞「エンドユーザが使いやすいか？」＞「顧客の謎の意思決定」だったりするし、そういう人も少なくはないんじゃないかと想像するけど、世知辛いものよ。

それ以上に腹立たしいのはITを使って悪をなすことだよ。アフィサイトを作りまくってインターネットをゴミの山みたいにしたり、目的と手段が入れ替わったSEO対策(の一部)とか。フィッシングメール/サイトとか。

希望はデータサイエンスとかなのかな？イメージだけど予算あげるから好きに作ってみなっていう、IT技術者が主役になれそうな分野という感じがする。あと、最近は景気がいいせいなのかVCが元気だよね。スタートアップとかに入ればもっと伸び伸びできるのかな？

# この世界の片隅で
日本って、IT技術では先進国ではない。少なくとも中心ではない。まあ自分が世界のトップクラスと渡り合える人材でないのは百も承知なんだけど、日本で働くのはモチベーション下がるよね。

いや、日本のITが発展途上国の振る舞いをするなら全然いいんだよ。「最新技術をバリバリ輸入して先進国に追いつこう！」みたいに熱くなれるんだけど、現実はアメリカのやり方とかを積極的に取り入れよう、とかそこまでしてなくない？商習慣や法律とかの違いはあるんだろうけど、さ。

例えば、アメリカの企業って継続的デリバリとかイテレーションとかアジャイルっていうのか専門用語はよくわかんないけど、リーンだよね。顧客とのコミュニケーションも頻繁だし、なんかシステマティックなシステム構築論がどんどん進化してる気がする。一方、日本の企業システムの構築の現場は・・・

はてブとかのコメントを見ると技術者の怨み言がすごい。派遣業界のせいかな、という側面もあるけど、F,N,H の正社員でも同じようなこと言っているからやっぱり日本の業界の特徴だよね。ガラパゴス化する文化でスキルをつけてもなあ、という気がする。ガラパゴスには外来種はいないけど、日本はそんなことないので。

# さいごに
愚痴ばっかになっちゃった。偏差値50のプログラマ（である私）はあと10年後も生きて行けるのだろうか？と不安になった。生きてはいるかもしれないけど痩せ細ってそう。
Python3でdocomoの自然対話：雑談apiを動かす

docomoの自動応答botをPython3で動かしてみようとトライしたらサンプルソースコードを見つけられなかったというか全て動かなかったので書いた。


#docomo自然対話（雑談対話）
[docomo Developer support](https://dev.smt.docomo.ne.jp/?p=index)が提供する自然対話api。少し使う分には無料。

>
>###雑談対話APIの特徴
>・ユーザの何気ない一言にバリエーション豊富な応答を返す、コンピュータと雑談を楽しむことができる機能です。雑談対話APIはユーザのどんな発話に対しても必ず応答します。
>・対話における話題と文脈を認識し、大規模発話データから応答文を選択し発話します。
>
[docomo Developer support : API 自然対話（雑談対話）](https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=natural_dialogue&p_name=api_4_usage_scenario#tag01)


#コード書く前にやること
・[docomo Developer supportのアカウント登録](https://dev.smt.docomo.ne.jp/?p=account.input)
　法人情報など、ほぼ何も登録しないミニマムなアカウントでも可能。
・[新規API利用申請](https://dev.smt.docomo.ne.jp/?p=mypage.api.index)
　利用開始は本日から。
　雑談対話のapiにチェックがついていさえすれば良い。
　
API申請が済んだらマイページに行き、Apikeyをコピーしてくる。
#雑談対話する

2回目以降の実行は52-54行目をコメントアウトし、1回目で得られたappIdを55行目記載すると情報が引き継がれる。


```python
# -*- coding: utf-8 -*-

import requests
import json
from _datetime import datetime

# your APIKEY
KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'

# リクエストクエリ
endpoint = 'https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/dialogue?APIKEY=REGISTER_KEY'
url = endpoint.replace('REGISTER_KEY', KEY)


#　user registration
def register():
    r_endpoint = 'https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/registration?APIKEY=REGISTER_KEY'
    r_url = r_endpoint.replace('REGISTER_KEY', KEY)
    r_headers = {'Content-type': 'application/json'}
    pay = {
        "botId": "Chatting",
        "appKind": "Smart Phone"
    }
    r = requests.post(r_url, data=json.dumps(pay), headers=r_headers)
    appId = r.json()['appId']
    return appId


def reply(appId, utt_content):
    headers = {'Content-type': 'application/json;charset=UTF-8'}
    payload = {
        "language": "ja-JP",
        "botId": "Chatting",
        "appId": appId,
        "voiceText": utt_content,
        "appRecvTime": "2018-06-11 22:44:22",  # 仮置き。これで動いてしまう。
        "appSendTime": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    }
    # Transmission
    r = requests.post(url, data=json.dumps(payload), headers=headers)
    data = r.json()
    # rec_time = data['serverSendTime']
    response = data['systemText']['expression']

    print("response: %s" % response)
    return response



if __name__ == "__main__":
    # appIdを取得した2回目以降、コメントアウトして55行目に記載
    appId = register()
    print(appId)
    # appId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx'
    while True:
        utt_content = input('>>')
        reply(appId, utt_content)

```
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/250945/3584c268-8293-b412-9a1d-6a7f724a697f.png)


#おわりに
32行目以下の内容がサーバーに送られるjsonファイルの中身になる。
[機能別リファレンス](https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=natural_dialogue&p_name=api_4#tag01)にある属性を追加して記載できる。

docomoの方でアップデートがあったんじゃないだろうか。たぶん。
2018年6月11日現在これで動く。

##参考
[uepon日々の備忘録](http://uepon.hatenadiary.com/entry/2016/11/19/103556)
はじめてのfingerコマンド

なんなんだこのコマンド・・・

![スクリーンショット 2018-06-11 23.51.38.png](https://qiita-image-store.s3.amazonaws.com/0/24737/56d1bd04-e99f-ccbd-eaac-223d5d2e5c57.png)

ttyがconsole直で、pts/がterminal(ssh接続）。

いつ使うんだ・・・・・
Jersey 2.26でDIの`AbstractBinder#bindFactory`の扱い方が少し変わってたのでメモ

TL;DR
-------------------

今まで、`AbstractBinder#bindFactory`を使う時に`org.glassfish.hk2.api.Factory`を実装していましたが、今後は`java.util.function.Supplier`や`org.glassfish.jersey.internal.inject.DisposableSupplier`を使うようになっています。

しかし、巷に転がっているサンプルコードは`Factory<T>`を実装する例が多く、Jersey 2.26以降はコンパイルが通らなくなっています。

この点に触れている情報がなかなか見つからず、コンパイル通らない点で少し苦しんだのでメモします。
（皆ドキュメントをちゃんと読んでいるから引っかかってないのかもしれない。）




出典
------------------------

ドキュメントに書いてあります。今回の件以外にも色々DI回りの修正が入っているようです。

https://jersey.github.io/documentation/latest/user-guide.html#mig-2.27-injection-manager

> HK2 Factory support is replaced by java.util.function.Supplier and Jersey-specific DisposableSupplier.




コード例
------------------------

例えば、こんな感じにMyBatisを使って、SqlSession(DBコネクション)をDIするアプリケーションを作ることを考えます。


``` java:MyApplication.java
@ApplicationPath("/rest")
public class MyApplication extends ResourceConfig {
	public MyApplication() {
		packages(getClass().getPackage().getName());
		register(new AbstractBinder() {
			@Override
			protected void configure() {
				bindFactory(MyBatisSqlSessionFactoryProvider.class).to(SqlSessionFactory.class).in(Singleton.class);
				bindFactory(MyBatisSqlSessionProvider.class).to(SqlSession.class).in(RequestScoped.class);
			}
		});
	}
}

```

MyBatisSqlSessionFactoryProviderやMyBatisSqlSessionProviderは以下のような感じです。
要点はimplementsするときのインタフェースがFactory以外に変わっている、というだけです。


```java:MyBatisSqlSessionFactoryProvider.java

public class MyBatisSqlSessionFactoryProvider implements Supplier<SqlSessionFactory> {

	private final SqlSessionFactory sqlSessionFactory;

	public MyBatisSqlSessionFactoryProvider() {
		try {
			String resource = "mybatis-config.xml";
			InputStream inputStream = Resources.getResourceAsStream(resource);
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		} catch (IOException e) {
			throw new RuntimeException(e); // 雑
		}
	}

	@Override
	public SqlSessionFactory get() {
		System.err.println("SqlSessionFactory get");
		return sqlSessionFactory;
	}

}
```

``` java:MyBatisSqlSessionProvider.java
public class MyBatisSqlSessionProvider implements DisposableSupplier<SqlSession> {

	private final SqlSessionFactory sqlSessionFactory;

	@Inject
	public MyBatisSqlSessionProvider(SqlSessionFactory sqlSessionFactory) {
		this.sqlSessionFactory = sqlSessionFactory;
	}

	@Override
	public SqlSession get() {
		System.err.println("SqlSession get");
		return sqlSessionFactory.openSession();
	}

	@Override
	public void dispose(SqlSession instance) {
		System.err.println("SqlSession dispose");
		instance.close();
	}
}
```

使い分けはdisposeメソッド（後始末処理）を使いたいか否かです。


~~なおFactoryのままにしておき、bindFactory→bindにしたらコンパイルは通りますが、MyBatisSqlSessionProviderとSqlSessionの型が一致しないのでInjectionに失敗(コンストラクタインジェクションの場合はコンストラクタが見つからない)して実行時エラーになります。bindの意味を考えれば当たり前なんですが、エラーにしてほしい・・・~~
【Go】A Tour of Go 1日目


タダです。


A Tour of Goをやってみたくて、ついでに学んだ記録を残していこうと思います。

# Packages
GoはPackageで構成されている
プログラムは`main`から始まる

```
package main
```

# Imports
括弧でパッケージのインポートをグループ化し、factoredインポートステートメントとしている

```
import "fmt"
import "math"
```

# Exports names
Goでは、最初の文字が大文字のものは外部のパッケージから参照した名前(expoers names)である

# Functions
関数は０個以上の引数を取ることができる
以下の例は、add関数がint型のデータを二つ引数にとっている
変数の後ろに型を描く点は注意

```
func add(x int, y int) int {
	return x + y
}
```

# Named return values
Goでは戻り値を変数化が可能

# Variables
変数は、varで定義可能
変数名の最後に型を宣言で定義できる

```
var hoge,fuga string
```

変数の初期化は次のように行う

```
var hoge,fuga string = test1, test2
```

# Short variable declarations
関数の中ではvarの宣言の代わりに `:=` の代入文を使うと暗黙的な方宣言が可能になる

```
func main() {
	var i, j int = 1, 2
	k := 3
	c, python, java := true, false, "no!"

	fmt.Println(i, j, k, c, python, java)
}
```

# Basic Types
Go言語の基本型は以下のもの

```
bool

string

int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr

byte // uint8 の別名

rune // int32 の別名
     // Unicode のコードポイントを表す

float32 float64

complex64 complex128
```

# Type Conversions
型変換について
変数iをint型からfloat型、変数fをunit型へと変換する


```
var i int = 42
var f float64 = float64(i)
var u uint = uint(f)
```

今回はここまでです。
カイ二乗検定の結果を評価する言葉を考える

# 何
- カイ二乗検定を行った際に、結果をどのように見れば良いのか難しかったため、日本語でクドく説明する

## 検定内容
- kaggleのタイタニック号のデータを使い、乗船者の年代ごとに性別による生存率に差があるかを調べる
- 帰無仮説(H0)：性によって生存率は変わらない
- 対立仮説(H1)：性によって生存率は変わる

```python

import numpy as np
import pandas as pd
from scipy import stats
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

def chi_test(min_age, max_age):
    # kaggleのタイタニックデータを参照
    df = pd.read_csv('train.csv')
    # 対象を限定する
    df = df[(df.Age >= min_age) & (df.Age <= max_age)]
    # sns.countplot(x='Sex', data=df, hue='Survived')
    survive_count = len(df[df.Survived == 1])
    dead_count = len(df[df.Survived == 0])
    male_count = len(df[df.Sex == 'male'])
    female_count = len(df[df.Sex == 'female'])

    # 帰無仮説が正しい時の期待結果（[男性生存者数, 女性生存者数]）
    survive_rate = survive_count/(survive_count+dead_count)
    expected = [male_count*survive_rate, female_count*survive_rate]
    
    df_survived = df[df['Survived'] == 1]
    # 実際の人数（[男性生存者数, 女性生存者数]）
    actual = [len(df_survived[df_survived.Sex == 'male']), len(df_survived[df_survived.Sex == 'female'])]
    
    chisq,p = stats.chisquare(actual,expected)
    print('----------------------------')
    print('age=[{:d}-{:d}]'.format(min_age, max_age))
    print('ecpected=', end='')
    print(expected)
    print('actual=', end='')
    print(actual)
    print('カイ二乗統計量= {:0.2f}'.format(chisq))
    print('P値 = {:0.2f}'.format(p))
    
chi_test(0,5)
chi_test(0,10)
chi_test(11,15)
chi_test(16,20)
chi_test(21,100)
```

## 結果
```
----------------------------
age=[0-5]
ecpected=[16.204545454545457, 14.795454545454547]
actual=[15, 16]
カイ二乗統計量= 0.19
P値 = 0.66
----------------------------
age=[0-10]
ecpected=[19.59375, 18.40625]
actual=[19, 19]
カイ二乗統計量= 0.04
P値 = 0.85
----------------------------
age=[11-15]
ecpected=[4.052631578947368, 6.947368421052632]
actual=[2, 9]
カイ二乗統計量= 1.65
P値 = 0.20
----------------------------
age=[16-20]
ecpected=[21.3125, 11.6875]
actual=[8, 25]
カイ二乗統計量= 23.48
P値 = 0.00
----------------------------
age=[21-100]
ecpected=[136.32958801498128, 71.67041198501873]
actual=[64, 144]
カイ二乗統計量= 111.37
P値 = 0.00
```

## P値と検定結果の関係
- P値大：カイ二乗統計量が小さく（=帰無仮説を想定した予想データと実体の乖離が小さく）、P値が大きい(=たまたまこれくらい以上乖離することもP値%くらいありえる)。帰無仮説は棄却されず、「性によって生存率は変わらない」のかもしれない。（それが正しいとは言っていない）

- P値小：カイ二乗統計量が大きく（=帰無仮説を想定した予想データと実体の乖離が非常に大きく）、P値が小さい(=たまたまこのように乖離することはP値%くらい低い確率)。帰無仮説は棄却され、「性によって生存率は変わる」と言える

- P値大と小の境目は0.05を使うのが慣例らしい

## 評価のつけたし
- 10歳以下では期待結果と実際が似ており、「生存率に差がなくても、これくらいの数の差は出るんじゃないか」とP値が言っている。
- 11-15歳では期待結果と実際の差が出てきて「10歳以下と比較すると、乖離がひろがって、たまたまと言える確率が下がってきたが、まだ生存率の差があると言える水準ではない」。
- 16歳以上では「これだけ乖離があれば、もう生存率の差があるといわざるを得ない」。

## jupyterのソース
- https://github.com/ystkr/my-python-learning/blob/master/chi-squared-test.ipynb

## その他
- pandasのDataFrameの扱い方が下手くそなので、改善方法があれば教えてください。
LevelDBを良いものだと思ったのでクライアントコマンドをGo言語で作った

ふと、SQLiteのようにライブラリとして使えるKVSがないかを探してみたところ、LevelDBにたどり着いた。（https://github.com/google/leveldb）

PythonのLevelDB用ライブラリの`plyvel`を使ってご機嫌だったが、一覧やキーのリストを取得したり、いらないキーを消すのにいちいちPythonを書いていられないので、クライアントコマンドを作ることにした。Goで。

そして出来上がったものがこちら。

https://github.com/yuuichi-fujioka/go-leveldbctl

go getでインストールすると使える。

```
$ go get github.com/yuuichi-fujioka/go-leveldbctl/cmd/leveldbctl
$ leveldbctl -h
NAME:
   leveldbctl - A new cli application

USAGE:
   leveldbctl [global options] command [command options] [arguments...]

VERSION:
   0.0.0

COMMANDS:
     init, i    Initialize a LevelDB
     walk, w    Walk in a LevelDB
     keys, k    Search all keys in a LevelDB
     put, p     Put a value into a LevelDB
     get, g     Gut a value from a LevelDB
     delete, d  Delete a value from a LevelDB
     help, h    Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --dbdir value, -d value  LevelDB Directory (default: "./") [$LEVELDB_DIR]
   --help, -h               show help
   --version, -v            print the version
```

## 使い方

カレントディレクトリをLevelDBのディレクトリとみなし、初期化、CRUD操作ができる。（オプション`--dbdir`、`-d`で特定のディレクトリをLevelDBとすることも可）

`init`で初期化し、あとは`put`で作成、`get`で取得、`delete`で削除する。

```
$ leveldbctl init   # 初期化。いろいろファイルができる。
./ is initialized as LevelDB
$ leveldbctl get aaa  # aaaがキー。からっぽなので、ないと言われる。
aaa is not found.
$ leveldbctl put aaa bbb  # aaaにbbbを入れると...
put aaa: bbb into ./.
$ leveldbctl get aaa  # getでbbbが取れる
bbb
$ leveldbctl delete aaa  # 消す。
aaa is deleted
```

他には`walk`で全キーバリューの出力、`keys`で全キーの出力ができる。

```
$ leveldbctl keys
egg
foo
hoge
$ leveldbctl walk
egg: spam
foo: bar
hoge: fuga
```

## 他

* Mac OS High Sierra、Ubuntu 16.04.4 LTSで動作確認しました。
* コマンドは`github.com/urfave/cli`を使って実装しています。
* LevelDBの操作は`github.com/syndtr/goleveldb/leveldb`を使っています。