OmniAICreator/Qiita-1.07M huggingface dataset:
PowerShell を利用して Office 365 からメールを送信する

# PowerShell を利用して Office 365 からメールを送信する

[ブログからの転載です。](http://1bed.allright.life/?p=2448)

以前 [Ruby を使って Gmail 経由でメール送信](http://qiita.com/miyamiya/items/951f6a19096e5e30e639) というブログを書きましたが、今度は Windows で定期実行される処理(PowerShell)からレポートメールを送る必要があったのでメモ。


## 環境

* Windows 10 Pro
* PowerShell 5.1

## サンプルコード

自分のメールアドレス(差出人)が miyamiya@example.com 、宛先のメールアドレスが misono@example.jp としてサンプルコードを書いてみる。ここでは miyamiya@example.com が Office 365 のアカウントとする。

```ps1

# Office 365 の認証情報
$o365User = 'miyamiya@example.com';
$o365Pass = Read-Host -Prompt "Enter the password for ${o365User}(Office365)" -AsSecureString
# 差出人
$from    = 'miyamiya@example.com';
# 宛先
$to      = 'misono@example.jp';
# メールのタイトルと本文
$subject = 'メールのタイトル';
$body    = 'メールの本文';

# MailMessage インスタンス作成
$msg = New-Object System.Net.Mail.MailMessage($from, $to, $subject, $body);

# Office 365 の SMTP サーバーを設定して SmtpClient インスタンスを作成
$SMTPClient = New-Object Net.Mail.SmtpClient("smtp.office365.com", 587) ;

# SSL を True に設定
$SMTPClient.EnableSsl = $true;

# Office 365 への認証
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential($o365User, $o365Pass);

# メール送信
$SMTPClient.send($msg);
```

## 参考

* [【PowerShell】Windows PowerShell を使用して GMail や Office 365 からメールを送信する](https://blogs.technet.microsoft.com/junichia/2011/12/08/powershellwindows-powershell-gmail-office-365/)

* [一般法人向け Office 365 用の Outlook POP および Outlook IMAP の設定](https://support.office.com/ja-jp/article/%25E4%25B8%2580%25E8%2588%25AC%25E6%25B3%2595%25E4%25BA%25BA%25E5%2590%2591%25E3%2581%2591-Office-365-%25E7%2594%25A8%25E3%2581%25AE-Outlook-POP-%25E3%2581%258A%25E3%2582%2588%25E3%2581%25B3-Outlook-IMAP-%25E3%2581%25AE%25E8%25A8%25AD%25E5%25AE%259A-7fc677eb-2491-4cbc-8153-8e7113525f6c?ui=ja-JP&rs=ja-JP&ad=JP)
NginxのLTSV形式のログから、アクセス数が多いIPを抽出する

Webサービスを運用していると、特定のIPから大量のアクセスを受けるときがあります。
それを確認するための方法の一つして、NginxのLTSV形式のログから集計するという方法を紹介します。


```
cat access.log  | awk '{print $3}' | sort -n | uniq -c | sort -n
```

以下のように集計してい表示されます。Google Botが多いですね。


```
   6561 host:66.249.79.154
   7476 host:66.249.79.130
   9889 host:66.249.79.150
  12882 host:66.249.77.27
  15508 host:66.249.79.190
  35061 host:66.249.77.26
  63317 host:66.249.77.25
```
Mastodonの優先度の低いカスタムのメモ

# はじめに
このブームに乗ろうとして私もマストドンインスタンスを作成しました
その際に行った割と優先度の低いカスタムのめもです
**素人仕事ですので最善の方法では無いかもしれません**

# やったこと
## Twitterカードの設定
Twitterにリンクを張った際に内容がカードで表示されるようにしました
以下のようなリンクの内容を表示してくれるしくみです、わかりやすいですね
![SnapCrab_NoName_2017-4-15_19-24-36_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/124002/ba8af580-516e-0b0b-76d5-a76d401aacff.png)

以下の手順を参考にしてください

- https://dev.twitter.com/ja/cards/overview にアクセスし、好きなTwitterカードを選択します
- Mastodonの管理者権限*1を持たせたユーザーからサイト設定を行い先のサンプルコードを参考にして適宜記述します
- http://cards-dev.twitter.com/validator から設定がうまくいっているか確認します

*1 https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Administration-guide.md

## トップ画面の変更
サイトの名前をMastardから取っているせいでドメイン名がややこしいのでトップ画像を変更しました
docker-compose.ymlからわかるように永続化されているのでファイルを差し替えるだけです
結果こうなりました
![SnapCrab_NoName_2017-4-15_19-9-8_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/124002/2e01e835-0d3a-c153-b8ce-b820e96ccf7d.png)

## おわりに
ユーザー全く居ないのでおいでませ
Flow & Redux で Reducer の実装パターンを考える

## 背景

段階的に片付けしていく、というFlowのコンセプトで、最も需要が高いのは、純粋なJSで済む状態管理、 とくに Redux の Reducer の部分であると考えられる。

## 実際のコード

とりあえずこうなるだろうというのを書いてみた。

```js
/* @flow */

// constants
const INCREMENT = 'increment'
const ADD = 'add'

export const Actions = {
  INCREMENT, ADD
}

// actions
export type IncrementAction = {
  type: typeof Actions.INCREMENT
}

export type AddAction = {
  type: typeof Actions.ADD,
  payload: number
}

export type CounterAction = IncrementAction | AddAction

// reducer
type CounterState = { value: number }
export default (state: CounterState = { value: 0 }, action: CounterAction) => {
  switch(action.type) {
     case Actions.INCREMENT:
      console.log(action.payload) //failed
       return { value: state.value + 1 }
     case Actions.ADD:
       return { value: state.value + action.payload }
  }
}

// action creator
export function increment(): IncrementAction {
  return {type: Actions.INCREMENT}
}

export async function incrementAsync(): Promise<IncrementAction> {
  return {type: Actions.INCREMENT}
}

export function add(n: number): AddAction {
  return {type: Actions.ADD, payload: n}
}
```

switch 式の中の failed と書いてある部分が一番コケてほしい部分。INCREMENTにpayolad はない。で、ちゃんとコケてくれる。

ACTION名の生成にredux-actionsみたいな関数を挟んだりすると、うまくいかない。諦めた方がいい。

## ファイルの分割

```
reducers/
  counter/
    index.js
    actions.js
    constants.js
```

人次第。なんか規約がほしい。constants.js は actions.js の中に移動しても良さそうだけど、reducer と actions の主従関係が、書いてる人次第だと思う。とりあえず外出した。

フラット派ならこっちだろうか。

```
actions/
  counter-actions.js
reducers/
  counter.js 
```

Flowの推論機を壊さない範囲で綺麗にしたい。
MobaXtermを使いBash On Windowsで簡単にX11を使う

[軽量多機能なUNIXライク環境 MobaXterm](http://qiita.com/nullsnet/items/78ad406b7a414fba27f4)を使ってBash On WindowsでGUIを動かします
MobaXtermはターミナルとX11 Serverを内蔵してるのでMobaXtermだけあれば完結します

# 使い方
まずは以下からMobaXtermを落として下さい
Portable版でもインストーラ版でもどちらでも
[MobaXterm Xserver with SSH, telnet, RDP, VNC and X11 - Home Edition](http://mobaxterm.mobatek.net/download-home-edition.html)

MobaXtermを起動すると勝手にX Serverも立ち上がります
初回起動時はWindowsファイアウォールにブロックされるので許可してあげて下さい

Ctrl+Shift+Nを押すか左上のSessionボタンをクリックして新しくセッションを作成します

![image](https://qiita-image-store.s3.amazonaws.com/0/125525/eb8c191c-dfdf-4f32-821c-a722b69a4766.png)

ありがたいことに最初からUbuntu Bash(WSL)を起動するための設定があるので選択します

![image](https://qiita-image-store.s3.amazonaws.com/0/125525/c87ad31d-b085-f464-bbb8-e4912596de7a.png)

Bashが立ち上がりました
この状態でもう既にXが使えます

![image](https://qiita-image-store.s3.amazonaws.com/0/125525/0ed33708-6096-5b05-23ed-c132d64bd627.png)

試しに適当なX11なプログラムを動かしてみます

```bash
$ sudo apt-get install x11-apps
$ xeyes
```

![image](https://qiita-image-store.s3.amazonaws.com/0/125525/b61b6a6b-2db5-7350-f956-600b5e2cf244.png)

かんたん
機械学習と人工知能との違い

機械学習に関する基本的な内容をまとめてみたものです。機械学習に関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
[機械学習と人工知能との違い] (https://www.techcrowd.jp/machinelearning/ai/)

#[機械学習と人工知能の違い] (https://www.techcrowd.jp/machinelearning/ai/)

IT技術の発達と共に機械学習や人工知能にも注目が集まるようになりましたが、機械学習や人工知能について十分に理解をしていない人が少なくありません。

・機械学習はデータを解析して、その結果から反復パターンを見付けて、判断や予測に役立てる技術
・人工知能は、人間と同じような考える力を持ったコンピュータの実現を目指すもの。現在では、まだ一部の分野において、人間を凌駕する処理速度のものが実現できているに過ぎません。

機械学習は人工知能を実現する技術のひとつとも言えますが、このように、機械学習と人工知能は基本的に異なる技術です。


# [機械学習と統計学の違い] (https://www.techcrowd.jp/machinelearning/ai/)

統計学も大量のデータから将来の動向を予測する事もあり近い分野ですが、機械学習と統計学は次のような点で視点が異なる分野です。

・機械学習は大量のデータを分析して、今後の事を予測するのが主な目的
・統計学は、データがどのようなものであるのか説明するのが主な目的


# [教師あり学習と教師なし学習] (https://www.techcrowd.jp/machinelearning/ai/)

機械学習に使用されるアルゴリズムは、
・教師あり学習
・教師なし学習
に分類する事が出来ます。

Amazon Machine Learningなどで実行できるのは、教師あり学習の「分類」や「回帰分析」などで、一般的に「機械学習」といったときのイメージとしても、教師あり学習をイメージされることが多いかもしれません。

### 教師あり学習
・学習用のデータから学習モデルを作り上げる
・出力する内容があらかじめ決まっている (ex. 予測するデータ項目があらかじめ決まっている)

### 教師なし学習
・データを分析して本質的な内容を導き出す
・出力する内容があらかじめ決まっていない (ex. いくつの種類に分類されるかあらかじめわからない)


# [機械学習で行われる分析] (https://www.techcrowd.jp/machinelearning/ai/)

### 回帰分析
・連続した量的データを予測する場合に使用される
・独立変数と従属変数の関係を数式によって表現し、どのような値を取るかを予測する
・教師あり学習

### 分類
・データが所属するグループを調べる
・2種類のグループに分類する事を2項分類と呼ぶ
・3種類以上のグループに分類する事を多項分類と呼ぶ
・教師あり学習

### クラスタリング
・データが持つ特徴を分析して、グルーピングを行う
・教師なし学習

### 相関分析
・2つ以上の変数間の関係性を分析する
・教師なし学習
HTMLで要素の横幅を画面幅いっぱいに広げる

方法は単純。

```CSS
body {
    margin: 0;
}

#hoge {
    width: 100%;
}
```
と書けば、`#hoge`の横幅が画面幅いっぱいに広がる。`body`の`margin`を0にするのがミソ。
API GatewayからEC2のSecurity Groupを更新する

### 動機

セキュリティの懸念から、22番ポートをフルオープンしたくないけど、モバイル環境からEC2インスンタンスにログインしたいことってありますよね。
Security Groupを空けるために、自分の端末が使っているグローバルIPアドレスを調べてAWS Cliを叩くのも手間ですし、スマホのsshクライアントからログインしたいときはそれすらもできません。特定のURLにアクセスするだけで、Security Groupを更新したいです。

そこでAPI Gatewayを使います。リクエストヘッダのX-Forwarded-ForからクライアントのIPアドレスが分かるので、Lambdaファンクションを呼び出してSecurityGroupを書き換えます。
ブックマークにこのAPIのURLを登録しておけば、ブラウザアクセス一発で、22番ポートに穴を空けれます。

### 手順

- Security Groupを新規に作成(sg-XXXXXXXXX)して、EC2インスンタンスに紐づける。管理を考えると、普段使いのSecurity Groupとは別に分けておいた方がいいかと思います。

- API GatewayのBody Mapping Templates として下記を指定して、X-Forwarded-ForヘッダをLambdaに渡します。

```json
{
  "ipinfo" : "$input.params('X-Forwarded-For')"
}
```

- Lambdaファンクションは下記です

```javascript
var AWS = require('aws-sdk');
var EC2 = new AWS.EC2();
console.log('Loading function');
exports.handle = function(event, context) {
    console.log('Received event:', JSON.stringify(event, null, 2));
    var sourceip = event.ipinfo.replace(/,.*/, '') + '/32';
    var params = {
	GroupId: 'sg-XXXXXXXXX',
	CidrIp: sourceip,
	IpProtocol: 'TCP',
	FromPort: 22,
	ToPort: 22
    }
    EC2.authorizeSecurityGroupIngress(params, function(err, data) {
	if (err) console.log(err, err.stack); // an error occurred
	else     context.succeed("added:" + sourceip);
    });
};
```

### 注意

- クライアント認証をしてないので、URLはバレないようにしましょう
- 一回設定したIPアドレスは自動で削除してくれません。定期的にエントリを整理するか、お掃除のためのLambdaファンクションを書いて定期実行しましょう。
- 今のコードは X-Forwarded-For のネストには対応してません(そういう環境になったことがないので手抜きした)
VPS借りてCentOS7でRails本番環境を構築するまでのメモ　Passenger + MySQL + Rails

Railsで本番環境を構築したときの手順をまとめました。
毎回やってるので面倒なのでもうここにメモします。

# SSHポート変更
	vi /ssh/sshd_config

# SELinux
最初から止まってた
	
# firewall設定
	firewall-cmd --add-port=[変えたポート]/tcp --zone=public --permanent
	firewall-cmd --add-port=80/tcp --zone=public --permanent

# OS日本語化
	yum -y install ibus-kkc vlgothic-*
	localectl set-locale LANG=ja_JP.UTF-8
	source /etc/locale.conf 
	
# Apacheとかいろいろインストール
	sudo yum install -y httpd git zipopenssl-devel readline-devel zlib-devel

# MySQLインストール
	wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm
	sudo rpm -ivh mysql-community-release-el7-5.noarch.rpm
	yum update
	
	sudo yum -y install mysql-server mysql-community-devel
	sudo systemctl start mysqld

```
mysql -u root
	update mysql.user set password=password('[パスワード]') where user = 'root';
	flush privileges;
	exit;
```

	create database [データベース名];
	
# SQLite3のインストール
	yum install -y sqlite sqlite-devel

# Ruby インストール
	git clone https://github.com/rbenv/rbenv.git ~/.rbenv
	echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
	~/.rbenv/bin/rbenv init
	echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
	source ~/.bash_profile
	type rbenv
	
	git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
	rbenv install 2.3.0
	rbenv global 2.3.0
	

# Rails インストール
	gem install rails --version="4.2.5"
	rbenv rehash

# Passengerインストール
	yum -y install libcurl-devel httpd-devel apr-devel apr-util-devel
	gem install passenger

	passenger-install-apache2-module
	sudo chmod o+x "/root"


Apacheに以下の設定をいれる
```
LoadModule passenger_module /root/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/passenger-5.1.2/buildout/apache2/mod_passenger.so
<IfModule mod_passenger.c>
	PassengerRoot /root/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/passenger-5.1.2
	PassengerDefaultRuby /root/.rbenv/versions/2.3.0/bin/ruby
</IfModule>

<VirtualHost *:80>
  DocumentRoot /var/www/html/

  RailsEnv production
  PassengerEnabled on

  <Directory /var/www/html/>
     AllowOverride all
     Options -MultiViews
  </Directory>

</VirtualHost>
```

# アプリインストール
	git clone [gitのURL]
	bundle install
	bundle update rails
	bundle update rake

   # DB初期化
	bundle exec rake db:migrate RAILS_ENV=production
	
	mkdir /var/www/html/tmp
	chmod 777 /var/www/html/tmp
	chmod 777 -R /var/www/html/public
過学習を防ぐ正則化

機械学習に関する基本的な内容をまとめてみたものです。機械学習に関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
[過学習を防ぐ正則化] (https://www.techcrowd.jp/machinelearning/regularization/)

# [過学習を防ぐために用いられる正則化とは] (https://www.techcrowd.jp/machinelearning/regularization/)

機械学習では大量のデータを扱いますが、偏り過ぎたデータにまで対応してしまう過学習の状態に陥る事があります。
学習する期間が長過ぎたり、データが典型的データから外れている場合に過学習が起こります。
過学習によって、典型的なデータに適切な対応が出来なくなる可能性があるので、注意しなくてはなりません。

そのため、機械学習では過学習になるのを防ぐために、極端な重みのデータに対してペナルティを与える正則化が用いられます。


# [過学習は未知のデータに対応出来ない原因を作る] (https://www.techcrowd.jp/machinelearning/regularization/)

機械学習で学習モデルを構築する時は、過学習に陥る事を避けなくてはなりません。

単に大量のデータを使って学習モデルを訓練したのでは、訓練用データに対してだけ正確な予測をする事になってしまいます。
それでは訓練で正確な予測がされているように見えても、訓練以外の未知のデータでは適切な予測が出来なくなります。


# [L1正則化とL2正則化] (https://www.techcrowd.jp/machinelearning/regularization/)

機械学習で一般的に使用されるのは、L1正則化とL2正則化です。

・L1正則化　特定のデータの重みを0にする事で、不要なデータを削除する
・L2正則化　データの大きさに応じて0に近づけて、滑らかなモデルとする

データの内容を検討して適切な正則化をすると、機械学習をより有効に行う事が出来ます。
GitHub への push で毎回ユーザー名とパスワードを聞かれるのはもうコリゴリなのです


## 背景

タイトルのとおり、GitHub への push の際に
ユーザー名とパスワードを効かれるのがダルくなったんので書き残しておくことにした
※ 2段階認証を設定してからパスワード周りが面倒くさいってのもあった

## 原因

### origin で指しているリモートリポジトリが `http` で通信を行うため

以下のように `https://github.com/ryysud/golang-crud-api.git` へ push するとユーザー名とパスワードが聞かれる

```bash
$ git remote -v
origin	https://github.com/ryysud/golang-crud-api.git (fetch)
origin	https://github.com/ryysud/golang-crud-api.git (push)

$ git push origin develop
Username for 'https://github.com':
Password for 'https://github.com':
remote: Anonymous access to ryysud/golang-crud-api.git denied.
fatal: Authentication failed for 'https://github.com/ryysud/golang-crud-api.git/'
```

## 解決方法

### リモートリポジトリとの通信を `ssh` で行う

`ssh` で通信するように変更してあげればいいだけ

```bash
$ git remote set-url origin git@github.com:ryysud/golang-crud-api.git
```

これでも良いがリポジトリをクローンしてくる度に設定するのはとてもダルい
それを避けるためにも以下の設定を `~/.gitconfig` に書くととても幸せになれる

```bash
[url "github.com:"]
	InsteadOf = https://github.com/
	InsteadOf = git@github.com:
```

いい感じ(๑•̀ㅂ•́)و✧

```bash
# ユーザー名とパスワードを聞かれる
$ git push origin develop
Username for 'https://github.com':
Password for 'https://github.com':
remote: Anonymous access to ryysud/golang-crud-api.git denied.
fatal: Authentication failed for 'https://github.com/ryysud/golang-crud-api.git/'

# https での通信を行うようになっている
$ git remote -v
origin	https://github.com/ryysud/golang-crud-api.git (fetch)
origin	https://github.com/ryysud/golang-crud-api.git (push)

# .gitconfig に URL の置換処理を追記 =======================
$ vi ~/.gitconfig
... 略
[url "github.com:"]
	InsteadOf = https://github.com/
	InsteadOf = git@github.com:
# =======================================================

# ssh での通信を行うように置換されていることがわかる
$ git remote -v
origin	github.com:ryysud/golang-crud-api.git (fetch)
origin	github.com:ryysud/golang-crud-api.git (push)

# ユーザー名とパスワードを聞かれることがなくなった
$ git push origin develop
Everything up-to-date
```

## 参考資料

- [git パスワード を毎回聞かれる問題の解決方法
](http://qiita.com/rorensu2236/items/df7d4c2cf621eeddd468)
- [GitHubのremote URLにはどのプロトコルを使えばよいのか？](http://qiita.com/chroju/items/67da13c672efcd2bc787)
機械学習における回帰分析

機械学習に関する基本的な内容をまとめてみたものです。機械学習に関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
[機械学習における回帰分析] (https://www.techcrowd.jp/machinelearning/regression/)

# [機械学習における回帰分析の応用] (https://www.techcrowd.jp/machinelearning/regression/)

機械学習では大量のデータを分析して、今後の事を予想します。
二項目分析や多項分析を用いる事もありますが、具体的な値の予想をする場合に使われるのが回帰分析です。

回帰分析は基礎的なデータ分析方法で、目的変数と説明変数間の関係式を求めて将来の事を予測します。

変数の数によって、単回帰分析と重回帰分析に分類されます。

・単回帰分析　目的変数と説明変数が、一つだけの回帰分析
・重回帰分析　一つの目的変数と複数の目的変数を使う回帰分析


# [回帰分析の処理内容] (https://www.techcrowd.jp/machinelearning/regression/)

回帰分析は、複数の変数間の関係を明確にするために行います。

変数がxとy の2つの場合は、
y＝ax＋b
という関数によって、変数間の関係を表します。

このように、データ間の関係を直線で表現する事を、特に線形回帰と呼びます。


# [回帰分析の評価方法] (https://www.techcrowd.jp/machinelearning/regression/)

学習により回帰分析のモデルを構築した後は、モデルが有効なものであるかを評価する必要があります。

回帰分析のモデルを評価する方法として、
・決定係数: 説明変数を使って、目的変数をきちんと説明出来ているかを評価
・F検定:     モデルが妥当性であるかを評価する指標
・t検定:      使われたパラメータが適切であるか評価する指標
などがあります。
機械学習における二項分類と多項分類

機械学習に関する基本的な内容をまとめてみたものです。機械学習に関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
[機械学習における二項分類と多項分類] (https://www.techcrowd.jp/machinelearning/classifications/)

# [機械学習に用いられる二項分類と多項分類] (https://www.techcrowd.jp/machinelearning/classifications/)

機械学習には複数の学習アルゴリズムが存在しますが、特定の属性に注目してデータを分類する方法として、二項分類と多項分類があります。

### 二項分類
・属性によって、二種類に分類する
・具体例　奇数か偶数か、0か1かなど

### 多項分類
・属性に応じて、三種類以上に分類する
・具体例　色による分類、商品の種類による分類など


# [二項分類による予測] (https://www.techcrowd.jp/machinelearning/classifications/)

データを二種類のグループに分類する二項分類では、判断の材料として使われるのが分類閾値(カットオフ)です。
閾値とデータを比較した結果を元にして、予測が行われます。

二項分類の結果を評価するために用いられる精度メトリクスには、
・Accuracy(正確度)
・Precision(精度、適合率)
・Recall(再現率)
・False Positive Rate(偽陽性率)
・F1-measure(F1値)
などがあります。
これらの値を検証する事で、より正確に二項分類出来るように修正する事が出来ます。


# [多項分類による予測] (https://www.techcrowd.jp/machinelearning/classifications/)

多項分類は、単にデータと閾値を比較するのではなく総合的なスコアによって、分類を行います。
状況によっては、一定の値以上のスコアにならない時は、予測出来ない事もあります。

多項分類でも二項分類と同じように、Accuracy(正確度)やPrecision(精度、適合率)などの精度メトリクスを使って、予測した結果を評価します。
Dropbox/.ssh/の鍵ファイルを全て~/.sshにシンボリックリンクを貼るスクリプトを書いた

まずDropboxの任意のディレクトリに鍵を全て置いてください。
僕は以下のような感じで配置しました。

```sh:
$ pwd
/path/to/Dropbox/.ssh
$ tree .
.
├── config
├── id_hoge_rsa
├── id_hoge_rsa.pub
└── hoge.pem
```

この `/path/to/Dropbox/.ssh` ディレクトリに以下の `setup.sh` を配置します。

```sh:
$ pwd
/path/to/Dropbox/.ssh
$ touch setup.sh
$ chmod 755 setup.sh
$ vim setup.sh
```

```sh:setup.sh
#!/bin/sh

files=`find . -maxdepth 1 -type f | sed "s!^.*/!!" | grep -vE "setup.sh|.DS_Store"`

for file in $files; do
  file_path=`pwd`/$file
  target_dir_path=$HOME/.ssh/

  ln -s $file_path $target_dir_path

  target_file_path=$target_dir_path/$file
  if [[ $file =~ '.pem' ]]; then
    chmod -h 400 $target_file_path
  elif [[ $file =~ '.pub' ]]; then
    chmod -h 644 $target_file_path
  elif [[ $file =~ 'config' ]]; then
    chmod -h 644 $target_file_path
  else
    chmod -h 600 $target_file_path
  fi
done
```

**注意) シンボリックリンクを貼りたくないファイルについて**
`setup.sh` や `.DS_Store` のようなシンボリックリンクを貼りたくないファイルは、3行目の `grep -vE` の引数に例にならって追加してください。

最後にこのスクリプトファイルを実行します。既にリンク先に同名のファイルが存在する場合でも上書きなどはされません。
もし上書きする場合は、 `ln -f -s` のように書き換えてください。（危険なのでオススメしません。）

```sh:
$ pwd
/path/to/Dropbox/.ssh
$ ./setup.sh
```

以下について確認すれば良いでしょう。
1. `ls -la` で参照先とパーミッションが問題ないか
2. ファイル内がきちんと参照されているか

```sh:
$ cd ~/.ssh
$ ls -la
lrw-r--r--   1 me  staff    42  4 15 18:24 config@ -> /path/to/Dropbox/.ssh/config
$ vim config
Host hogehoge
...(中略)...
```
機械学習における特徴抽出処理

機械学習に関する基本的な内容をまとめてみたものです。機械学習に関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
[機械学習における特徴抽出処理] (https://www.techcrowd.jp/machinelearning/feature-extraction/)

# [品質の高いデータの重要性] (https://www.techcrowd.jp/machinelearning/feature-extraction/)

正確な予測モデルを構築するためには品質の高いデータが不可欠ですが、データの送受信時に内容が欠けてしまったり単純な入力ミスによって、低品質のデータが含まれる事がほとんどです。

そのような低品質のデータによって、予測モデルの性能が悪化するのを防ぐために、データを修正する必要が出て来ます。

機械学習を行う時は使用するデータの中身を検査して、必要であれば修正しなくてはなりません。


# [適切なデータに変換する特徴抽出処理] (https://www.techcrowd.jp/machinelearning/feature-extraction/)

一つのデータに複数の情報が含まれる場合、全ての情報が必要な情報とは限りません。
そのようなデータの中から必要な情報内容だけを取り出したり、有意義な情報に置き換えたりするのが特徴抽出処理です。

特徴抽出処理を行う事で、機械学習で扱う予測モデルの内容をより有効なものに改善する事が出来ます。


# [特徴抽出処理の具体的な内容] (https://www.techcrowd.jp/machinelearning/feature-extraction/)

### 意味のない情報を有効な情報に変更
破損した情報が含まれる場合などは、適切な情報に置き換える

### 非線形変換
より数値の特徴が分かりやすくなるように、数値をグループによって表す

### 情報の内容に応じた処理を施す
個別の情報の特徴に応じた処理をする

適切な特徴抽出処理を選ぶためには、データの内容を十分に理解しておかなくてはなりません。
軽量マークアップ言語記法チートシート(Org,Markdown,Asciidoc)

## 目的
「普段はorg-modeしてるけどたまにmarkdown書く用事があるんだよね……ええと、コードブロックはどうやって書いたっけ……」みたいなことがあるので一覧にしてまとめた。ついでにAsciidocも便利そうなので後学のためにまとめた。

え、pandocで変換しろ?まあまあそう言わずに……

## 早見表
|                 出力                 |            Org        |        Markdown        |             Asciidoc            |
|:------------------------------------:|:------------------------:|:----------------------:|:-------------------------------:|
|                *斜体*                |         `/斜体/`         |        `*斜体*`        |             `_斜体_`            |
|               **太字**               |         `*太字*`         |       `**太字**`       |             `*太字*`            |
|                 下線                 |         `_下線_`         |            -           |       `[underline]#下線#`       |
|              ~~打消し~~              |       `+打消し+`       |      `~~打消し~~`      |     `[line-through]#打消し#`    |
| 文中にコマンドとか入れるときに使うの | `=code=` or `~code~`                 | \`code\`               | \`code\`                        |
| 文章タイトル                         | `#+TITLE: TITLE`         | -                      | `= TITLE =`                     |
|                見出し                |  `* Level1`<br>`** Level2`  | `# Level1`<br>`## Level2` | `== Level1 ==`<br>`=== Level2 ===` |
|            番号付き見出し            |     `1. 1st`<br>`2. 2nd`    |    `1. 1st`<br>`2. 2nd`   |        `1. 1st`<br>`2. 2nd`        |
|               箇条書き               | `+ abc`,`- abc`, `* abc` |         `* abc`        |             `* abc`             |
| 定義リスト                           | `DEF :: Something`       | ?                      | `DEF:: Something`               |
|                リンク                | `[[リンク][http://---]]` | `[リンク](http://---)` |     `link:http://---[リンク] `   |
|                水平線                |          `-----`         |   `***`, `---`, `___`  |              `'''`              |
|           脚注(インライン)           |   `[fn:: インライン脚注]`  |            -           |                ?                |
|               コメント               |       `# コメント`       |   `<!-- コメント -->`  |          `// コメント`          |

後から追加したり直したりするかも。
機械学習で行われる分析

機械学習に関する基本的な内容をまとめてみたものです。機械学習に関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
[機械学習で行われる分析] (https://www.techcrowd.jp/machinelearning/analysis/)

# [教師あり学習と教師なし学習] (https://www.techcrowd.jp/machinelearning/analysis/)

機械学習に使用されるアルゴリズムは、
・教師あり学習
・教師なし学習
に分類する事が出来ます。

教師あり学習
・学習用のデータから予測モデルを作り上げる
・出力する内容が決まっている

教師なし学習
・データを分析して本質的な内容を導き出す
・出力する内容が決まっていない


# [機械学習で行われる分析] (https://www.techcrowd.jp/machinelearning/analysis/)

機械学習で行われる分析には、
・回帰分析
・分類
・クラスタリング
・相関分析
などがあります。

回帰分析
・連続した量的データを予測する場合に使用される
・独立変数と従属変数の関係を数式によって表現し、どのような値を取るかを予測する
・教師あり学習

分類
・データが所属するグループを調べる
・2種類のグループに分類する事を2項分類と呼ぶ
・3種類以上のグループに分類する事を多項分類と呼ぶ
・教師あり学習

クラスタリング
・データが持つ特徴を分析して、グルーピングを行う
・教師なし学習

相関分析
・2つ以上の変数間の関係性を分析する
・教師なし学習


# [実際に機械学習をする時の注意点] (https://www.techcrowd.jp/machinelearning/analysis/)

用途に合った適切な分析方法を選び、
・機械学習のプラットフォーム
・データ
を用意して機器学習を行う事になります。

但し、機械学習を行う予定のプラットフォームでは、希望する分析方法やアルゴリズムが使えない事もありますので、事前にプラットフォームの調査をしておく必要があります。
[Monaca][ビルドエラー] Androidビルドで認識できない文字について

Monacaは、Cordovaを内包したHTML5ハイブリッドアプリ開発プラットフォームです。
Monacaビルドサーバーを通じてAndroidやiOSアプリをビルドすることができます。

今回は、Androidビルドでの原因がわかりづらいエラーについて書いてみたいと思います。
Monacaビルドサーバーから出力されるビルドログは、正直分かりやすいとは言えません。
ビルド時に出力されるログのため、よく見るとエラーの原因となる内容は出力されていますが、その中で特に分かりづらいのが、

```
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':processDebugResources'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/data/android-sdk/build-tools/23.0.3/aapt'' finished with non-zero exit value 1
```

ではないかと思います。

#Androidビルドツールが認識できない文字
このエラーの原因は、対象プロジェクトのリソースで使用されているファイル名にAndroidビルドツールが認識できない文字が使用されている場合に出力されます。

Androidビルドツールが認識できない文字は、下記になります。

| 認識できない文字 |
|:------------:|
| 日本語等のUnicode文字 |
| < |
| > |
| : |
| * |
| ? |
| " |
| / |
| \ |
| &#124; |


#さいごに
エラーログの中に`Resources`の文字が隠れているので、対象プロジェクトで使用しているリソースに原因があるところまではたどり着けますが、`finished with non-zero exit value 1`で、`Androidビルドツールが認識できない文字`にたどり着くのは、なかなか難しいと思います。

今後も、分かりづらいビルドログについて残していけたらと思います。
AirPrintするためだけにUbuntuでAvahi-daemonを動かしてみました。

# WiFiルーターと異なるLANセグメントにあるプリンターにiPadからAirPrintしたい。

iOSから「印刷」を選ぶとプリンタが検索できますが、WiFiルーターと同じLANセグメントにプリンターを設置していないと一覧に表示されません。

ポリシー上、あるいはトポロジー上、WiFiセグメントとLANセグメントを同一にしたくない場合もあるかと思います。

そこで、WiFiルーターのLAN側ポート(WiFi接続と等価な側)にpcDuinoを繋いで、Avahi-daemonを使ってプリンターのIPアドレスを告知するようにしてみました。

（普通にRaspberryPiとか、型落ちして使わなくなった昔のRaspberryPiとかでいいとおもいます）

# Avahi-daemonのインストール
~~~
$ sudo apt-get install avahi-daemon
~~~
まあ、これだけなんですが。

# 設定とか

設定ファイルは /etc/avahi/ にあります。
プリンタサービスは、/etc/avahi/services/ 以下に、適当なプリンタ名.service というxmlファイルを置きます。

~~~
<?xml version="1.0" ?>
<!DOCTYPE service-group SYSTEM 'avahi-service.dtd'>
<service-group>
  <name replace-wildcards="yes">AirPrint DocuCentre-V C5585</name>
  <service>
    <type>_ipp._tcp</type>
    <subtype>_universal._sub._ipp._tcp</subtype>
    <host-name>xeroxcolor.local</host-name>
    <port>631</port>
    <txt-record>txtvers=1</txt-record>
    <txt-record>qtotal=1</txt-record>
    <txt-record>rp=ipp/print</txt-record>
    ・・・中略・・・
    <txt-record>Transparent=T</txt-record>
    <txt-record>Binary=T</txt-record>
    <txt-record>TBCP=F</txt-record>
    <txt-record>URF=none</txt-record>
  </service>
</service-group>
~~~

# *.localに対する hosts の記述

*.local というドメイン名は、AppleのBonjour(zeroconf)固有のローカルドメイン名になります。これもAvahi-daemonが知らせてくれますので、
/etc/avahi/hosts というファイルにIPアドレスを書いておきます。

~~~
# This file is part of avahi.
#
# avahi is free software; you can redistribute it and/or modify it
# ・・・
192.168.1.2  xeroxcolor.local
~~~

ここで、192.168.1.2 は、実際に設置されているAirPrint対応のプリンタの、到達可能なIPアドレスの一例です。
WiFiルーターが端末に割り振るアドレスは192.168.1.x ではない、と仮定します。
（同一LANセグメントであれば、そもそもAvahi-daemonを入れなくてもプリンタが勝手にBonjourを喋ります）

# Avahi-daemonを再起動します。
~~~
 $ sudo service avahi-daemon restart
~~~

# デバッグ
~~~
$ avahi-browse -r -a
~~~

同一LAN上にあるBonjour(zeroconf)のサービス一覧（自分のマシンも含む）が表示されます。


# 補足

ここまでの説明で、プリンタ名.serviceをどうやって作成するかの説明が抜けています。
作成方法としては、

(1) AirPrint対応プリンタと同じLANセグメントにこのLinuxを接続して、
~~~
$ avahi-browse -r -a
~~~
の表示結果から*.service を書く。
（上記の

~~~
    <txt-record>・・・</txt-record>
~~~
のところを全部埋めていく。）という感じになります。


(2) AirPrintしたいPrinterがもともとAirPrint非対応の場合はCUPS経由でのprintを行うようにします。

CUPSサーバーを先にインストールして、LinuxからCUPS経由で印刷できることを確認しておきます。

そのあとでAvahi-daemonをインストールすれば、わりと自動でそのCUPSプリンタ.serviceファイルが作られます。
AWS EC2 と RDS のオンデマンド料金行を console.log に吐き出すスクリプト


# 何に使うの？

Reserved の Blended rate で計算されてしまった料金をオンデマンドレートに計算し直す際に使うためだよ。

## なんでそんなことするの？

リザーブドを買っていない案件がリザーブドの恩恵を最も享受してしまって、リザーブドを買った案件のPMさんとかが怖い顔をするからだよ。

子アカウントの総額だけなら必要ないんだけど、エンドユーザに提出する明細が無駄に子細に書かれているためだよ。

## なんでわざわざ Javascript で書いたの？

Excel から実行するためだよ。
あと Pricing API の JSON が扱いにくいからだよ。
あと公式から情報を拾いたいからだよ。


# どうやって使うの？

EC2料金： https://aws.amazon.com/jp/ec2/pricing/on-demand/
とか
RDS料金： https://aws.amazon.com/jp/rds/pricing/
を開いて

下記のスクリプトを開発者ツールのコンソールに貼り付けて実行するだけだよ。

```js
(function() {

var trClass = '.sizes';
if(String(location).match(/rds/i)){ var trClass = '.tiers'; }    

var idList = [];
var idTabs = $('.tabs.tab-default .a-tabs:eq(0) li a').each(function(){ 
  idList.push(String(this.href).replace(/^https?.*\#/,'') + ', ' + this.textContent)
});

for( var i=0, l=idList.length; i<l; i++) {
  var osArr = String(idList[i]).split(', ');
  $('#' + osArr[0] + ' .pricing-table.section:eq(0) .puretmpl .content').each(function(){
    var t = $(this);
    var reg = String(t.prop('class')).replace(/content reg\-/,'');
    var list = t.find(trClass)
    console.log(osArr[1] + " : " + reg);
    console.log('-=-=-=-=-=-');
    console.log(list);
    console.log('-=-=-=-=-=-');
    console.log('');
  });
}
})();
```

console で出力しているところを適宜変更すればいいと思うよ。

上記のページで async で読み込まれる json を拾うという方法もあるよ。

※ただ、そのURLを集めるのが億劫だったので、私はsetTimeoutで間を置いてからスクリプトが実行される様にしました。タイミングによっては要素を拾い損ねるので、拾った要素を確認して undefined の場合は再帰する様にしました。収集した要素は一つのtableにしてからExcelのgetElementでシートに落とし込みます。

## 実行結果イメージ

![](https://qiita-image-store.s3.amazonaws.com/0/20877/4244cd63-891b-3cf5-e090-7edbcef234b3.png)

# なんでかなしいかおをしているの？

多くのエンジニアが事務作業とかに忙殺されているからだよ。

※ 半分くらい冗談です。苦笑いでも笑っていただけると幸いです。
Ubuntu 18.04 LTSにNode.js 10.xをインストールする方法

Ubuntu 18.04 LTSにNode.js 10.xをインストールする方法についてまとめます。

#インストール方法
1. `curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -`コマンドを実行し、リポジトリを追加します。
2. `curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -`コマンドを実行し、リポジトリを追加します。
3. `echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list`コマンドを実行し、リポジトリを追加します。
4. `sudo apt update`コマンドを実行し、リポジトリ一覧を更新します。
2. `sudo apt install nodejs yarn build-essential`コマンドを実行し、Node.js 10.xをインストールします。

#参考文献
* [Ubuntuでaptを使って最新のnode.jsをインストールする | cupOF Interests](http://co.bsnws.net/article/121)
* [How To Install Node.js on Ubuntu 16.04 | DigitalOcean](https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-16-04)
* [Ubuntu – xenial の build-essential パッケージに関する詳細](https://packages.ubuntu.com/ja/xenial/build-essential)
Ubuntu 18.04 LTSでのVirtualenvを用いたPython環境構築方法

私はこれまでpyenv信者だったのですが、[pyenvが必要かどうかフローチャート - Qiita](http://qiita.com/shibukawa/items/0daab479a2fd2cb8a0e7)を読んで考えを改めることにしました。
というわけで、Ubuntu 18.04 LTSでのVirtualenvを用いたPython環境構築方法についてまとめてみたいと思います。

#想定している読者
以下に該当する人向けの記事となっています。

* システムにインストールされているPython環境を汚したくない。
* プロジェクトごとに環境を分けたい。
* Python 2.xと3.xは使い分けたいけれど、それ以上細かく使い分ける必要はない (`3.5.0`と`3.6.0`といったレベルでの使い分けは必要ない)。

#Virtualenvとは
プロジェクトA用の環境, プロジェクトB用の環境 ...... etc といった感じで環境を分離するためのツールです。
システムにインストールされているPython環境を汚すことなく、それぞれの環境に合わせた実行環境やライブラリを用意することができるという利点があります。

#インストール方法
`sudo apt install virtualenv virtualenvwrapper`コマンドを実行し、Virtualenvをインストールします。

#環境作成方法
`mkvirtualenv --python=/usr/bin/{pythonの実行コマンド} {環境名}`コマンドを実行します。
※Pythonのバージョンと実行コマンドの対応関係は以下のようになります。

|Pythonのバージョン|実行コマンド|
|:--:|:--:|
|Python 2.x|`python`|
|Python 3.x|`python3`|

#環境使用方法
##環境に入る
`workon {環境名}`コマンドを実行します。
※コマンドラインの先頭に`({環境名})`が付けば成功です。

##環境から出る
`deactivate`コマンドを実行します。

#環境削除方法
`rmvirtualenv {環境名}`コマンドを実行します。

#関連記事
* [pipで一括アップデート - Qiita](http://qiita.com/manji-0/items/d3d824d77c18c2f28569)

#参考文献
* [virtualenvを使っていろいろなライブラリを手軽にためそう ｜ Developers.IO](http://dev.classmethod.jp/server-side/language/python-virtualenv-tutorial/)
* [Virtualenvwrapperの導入 - Qiita](http://qiita.com/_rdtr/items/5f3a9a9e2cb5a24f284e)
クラウドの機械学習ツール

機械学習に関する基本的な内容をまとめてみたものです。機械学習に関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
[クラウドの機械学習ツール] (https://www.techcrowd.jp/machinelearning/cloud/)

# [クラウドで利用出来る機械学習] (https://www.techcrowd.jp/machinelearning/cloud/)

・Amazon Machine Learning
・Azure Machine Learning
・Google Prediction API
などのサービスは、クラウド上で利用出来る機械学習です。

入力変数を送信すると、目的変数を予測する値が受信出来るAPIが用意されているので、クライアントアプリケーションを開発して独自の機械学習システムを構築する事も可能となっています。


# [クラウド型機械学習サービスの特徴] (https://www.techcrowd.jp/machinelearning/cloud/)

各社の機械学習サービスには、次のような特徴があります。

### Amazon Machine Learning
・AWSのS3、Redshift、RDSなどと連携可能
・1つのアルゴリズムだけを使用するようになっている

### Azure Machine Learning
・Microsoftの各種ストレージサービスを利用する事が出来る
・フローチャート式のデータフローが用意されている

### Google Prediction API
・Google Cloud StorageやBigQueryなどのデータが利用出来る
・APIが提供されているだけで、ユーザーインターフェースは存在しない


# [機械学習サービスを選ぶ時にチェックするポイント] (https://www.techcrowd.jp/machinelearning/cloud/)

本格的な機械学習が可能なクラウド型サービスでも、運営する各社によって機能などが違いますので、

・使いたいアルゴリズムが提供されているか
・希望するアプリケーションを開発出来るか
・機能に制限があるか
・利用料金はいくらかかるのか

などの内容を比較検討して、利用するサービスを決める必要があります。
zshでコマンドの完了時に通知音を鳴らす設定

# 概要
最近使っているOSSのgradleビルドが10分以上かかるので、ビルドコマンドの完了時に通知音を鳴らしたい。

# 要求機能
- Macローカルでtmuxを立ち上げた状態で動く
- Macローカルでtmuxを立ち上げ、sshでlinuxサーバに潜った先でさらにtmuxを立ち上げた状態でも動く
- 追加コマンドの呼び出しは出来る限り簡略化したい

# 実現方法
調べてみると、[ターミナルコマンドの完了時にサウンドを鳴らす](http://qiita.com/akira-hamada/items/ec01b81c6db000e0f9b3) という記事を見つけた。
この記事のとおり、`tput bel`というコマンドで音が出るので、`$ gradle build; tput bel`とすると、やりたいことはほぼできた。

しかし`; tput bel`と打つのが少々長いので、簡略化したい。
そこでzshのグローバルエイリアスの機能を使って、.zshrcに以下の設定を追加する。
`alias -g F=";tput bel"`

この設定をしておくと、`$ gradle build F`で同様のことが実現できる。
時間のかかるコマンドを実行するときは末尾にFをつけるだけで通知音が鳴らせるようになった！

# 補足
- tmuxやzshの設定でbeep音を切る設定をいれている場合は音が鳴らないので注意。
- `$ tput bel`の他に`$ echo -e '\a'`でも同様の音が出せる。
- Macでビルドコマンドを叩く場合はsayコマンドで`$ say ビルドが終わりました`とするとよりわかりやすい。
Golangをgoenvを使ってインストールしてみた

# version
macOS: 10.12.4
goenv: 1.0.0

# goenv とは
goenvは、go言語のバージョンを管理するやつ。
早速インストールする。
リポジトリは、[こちら](https://github.com/syndbg/goenv) です。

# goenv インストール
Homebrewでインストールする。

```shell-session
$ brew install goenv
```

以下の設定を追記する。

```shell-session:~/.bash_profile
export PATH="$HOME/.goenv/bin:$PATH"
eval "$(goenv init -)"
```

ターミナルを再起動する。

以上で、goenvのインストール＆設定終了。簡単。

# go言語(golang)のインストール
golangはまだインストールしていないので、早速インストールする。
まず、ダウンロード可能なgolangバージョンを調べてみよう。
以下のコマンドで、現在ダウンロード可能な、golangバージョンがわかる。

```shell-session
$ goenv install -l
Available versions:
  1.2.2
  :
  1.7.4
  1.7.5
  1.8.0
```

今回は、1.7.5をインストールしてみよう。

```shell-session
goenv install 1.7.5
```

# golangの設定
インストールが終わったら、設定を行う。
以下のコマンドで、使用するgolangバージョンを設定する。

```shell-session
goenv global 1.7.5
```

以上で、設定完了。ちゃんと読み込まれているか、確認してみる。

```shell-session
$ go version
go version go1.7.5 darwin/amd64
```

完璧。

# その他コマンド
## 切り替え可能なバージョンの確認

```shell-session
$ goenv versions
* 1.7.5 (set by /Users/hogehoge/.goenv/version)
  1.8.0
```

`*` が付いているのが、現在読み込まれているgolangのバージョン。

## バージョン切り替え

```shell-session
goenv global 1.8.0
```

## アンインストール

```shell-session
goenv uninstall 1.7.5
```

## コマンドの確認

```shell-session
goenv --help
```

以上、goenvの説明でした。golang開発をエンジョイしましょう。
機械学習とは

機械学習に関する基本的な内容をまとめてみたものです。機械学習に関する、Web上にすでにある解説コンテンツをまとめたサイトの抜粋です。
[機械学習とは] (https://www.techcrowd.jp/machinelearning/machinelearning/)

# [データを分析して将来の事を予測する機械学習] (https://www.techcrowd.jp/machinelearning/machinelearning/)

機械学習とは全ての処理をプログラムに依存せずに、得られたデータから学習して将来の予測をするシステムです。
データを分析して新たな関係性を見出すデータマイニングの手法として、注目を集めています。

機械学習の応用分野としては、
・ネットワークへの不正侵入の検知
・パターンマッチングや画像の認識
・有効な価格設定モデルの提案
・テキストを分析して消費者の感情を分析する
・設備不良の発生などに関する予測
など多岐に渡ります。

# [手軽に機械学習が利用出来るクラウド型サービス] (https://www.techcrowd.jp/machinelearning/machinelearning/)

将来について予測する機械学習は大変有望なツールとして期待されていますが、
・未知のデータへの対応能力
・機械学習の精度
などについて、理解しておかなくてはなりません。

機械学習は大規模なデータを分析して、その結果から将来の事を予測するので、未知のデータに対しては有効な予測をしにくい傾向があります。

機械学習の精度は、
・適切ではないデータを使用してしまう偽陽性
・使用するべきデータを捨ててしまう偽陰性
などの問題によって、100％とはならない事に注意が必要です。
機械学習も必ず間違う訳ですから、その対策を立てておかないと、大きな損失の発生する可能性が出て来ます。

しかし、このような機械学習の課題について十分な理解をして対応策を検討しておけば、適切な予測を利用してビジネスなどで大きな利益を得る事が出来ます。
【はじめての kubernetes】オリジナルイメージをデプロイする。（コマンド編）

オリジナルのイメージをつくるための Dockerfile はこちらです。[php -S するだけの小さな Docker イメージ](http://qiita.com/mochizukikotaro/items/958afc74593719035e5c)

# ステップをまとめてみます。

1. GCPコンソールでプロジェクト作成
2. イメージをビルドして、レジストリにアップ
3. cluster を作成
4. pod を作成
5. つくった pod を expose
6. パブリックな IP でアクセスができるようになります。完。

事前準備として以下の２つのコマンドは打てるようにしておいてください。
- gloud
- kubectl


# Step.1 GCPでプロジェクトを作成

ここは頑張って作成してみてください。課金とかも許容する大きな心が必要かもしれません。がんばってください。


# Step.2 イメージをビルドして、レジストリにアップ

上で登録したプロジェクトIDを、`<PROJECT-ID>` の部分にいれてください。以下、hello-なんちゃらの部分も、任意で設定できますので。

```bash
$ gcloud config set project <PROJECT-ID>
$ PROJECT_ID="$(gcloud config get-value project)"

# イメージ作成
$ docker build -t gcr.io/${PROJECT_ID}/php-server:v1 .

# イメージプッシュ
$ gcloud docker -- push gcr.io/${PROJECT_ID}/php-server:v1
```

※ 参考キャプチャ（名前は適当）
<img width="721" alt="スクリーンショット 2017-04-15 16.54.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/45822/7711c86c-a1fc-5189-be72-6d6b9f4fed24.png">

無事、Container Registry に上がりました。


# Step.3 クラスタ作成

```bash
$ gcloud container clusters create hello-cluster

# Check
$ gcloud container clusters list
$ gcloud compute instances list
```


# Step.4 ポッド作成

```bash
$ kubectl run hello-world --image=gcr.io/${PROJECT_ID}/php-server:v1 --port 7788
```


# Step.5 Expose する

```bash
$ kubectl expose deployment hello-world --type=LoadBalancer --port 7788
```

# Step.6 アクセス！

```bash
# まずは、IP を確認
$ kubectl get service hello-world
NAME        CLUSTER-IP      EXTERNAL-IP      PORT(S)          AGE
hello-world   10.43.248.115   35.187.210.206   7788:32718/TCP   53m
```

無事アクセスできました。

<img width="403" alt="スクリーンショット 2017-04-15 17.07.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/45822/af86d2ba-b8e5-0536-64dd-cdbf38bd1250.png">


# あとかたづけ

```bash
$ kubectl get all
```

```bash
$ gcloud container clusters delete <CLUSTER-NAME>
$ kubectl delete deploy <DEPLOY-NAME>
$ kubectl delete service <SERVICE-NAME>
```

以上、入門メモでございます。 🙂
ubuntu周りで困った話

■apt-get update でうまく IPv6 できない
apt-get update すると返ってこない時があるので、調べたらこんな感じだった。

[IPv6で応答するの勘弁してください](http://ytooyama.hatenadiary.jp/entry/2016/06/20/111500)

■日本語のホームディレクトリ周りを英名に変えたい
[Ubuntuでホームディレクトリの中身を英語にする](http://qiita.com/taiko19xx/items/d1a001bfc25245b91354)

■最新のnode.js ubuntuに入れるには

どうも apt-get install nodejs だと古いものしか入らない
https://deb.nodesource.com/setup が現状非推奨とのこと。
なので、色々方法があるけど、下記が一番簡単だと思う。

[Ubuntuに最新のNode.jsを難なくインストールする](http://qiita.com/seibe/items/36cef7df85fe2cefa3ea)
Javascriptのスライドショー(cameraとか)で、MacのSafariで一瞬次の画像がでてしまう！時の対処方法

Safariだけですけど、スライドショーでアニメーション後に次の画像が表示される前に、一瞬だけ画像が表示されることがありました。
apacheでキャッシュが無効化されている場合に再現できたので、対処方法メモです。

レンタルサーバだとapacheの設定変更ができないので、htaccessで書きます。

```htaccess
<Files ~ ".(gif|jpe?g|png|ico)">
	Header unset Pragma
	Header unset Cache-Control
</Files>
```

Filesの正規表現で、下記の様に

```htaccess
<Files ~ ".(gif|jpe?g|png|ico)$">
```

\$を付けると、hoge.jpg?123353666のようにJS側で勝手にキャッシュされないようにしている場合対象にならないので、さくっと\$を外しました。

・apacheのヘッダーで「pragma no-cache」「Cache-Control: no-cache」がデフォ
・htaccessでHeaderが有効になっている
・Safariで一瞬画像がでてしまう！

の条件の人は、試してみる価値はあると思います。
Laravelのchunk()で指定した条件を更新したい時の代替方法

Laravelのchunkは便利だけど、クエリ条件を更新するような処理の場合に挙動がおかしくなり、切ないことになったので、そう言った時の代替案を考えてみた。

どんな問題が起きるかについては、すでに書いている方もいるが、一応書いておく。

[Laravelでchunkする際の注意点](http://qiita.com/aooni_kun/items/5427e5fab19936628a13)

# 前提
+ タスクというデータを一括で完了にしたい
+ 完了はis_completedが1の状態の時

# Chunkで起きる問題
is_completedが０のレコードを取得するような条件にしていて、クロージャー内でis_completedを更新すると更新分の取得件数が除外されてしまい、処理がずれてしまう。

## 不具合の起きるコード
```php
// 未完了のタスクを３件ずつ取得して完了にする
Task::where('is_completed', 0)->chunk(3, function ($tasks) {
    foreach ($tasks as $task) {
        // 完了タスクに更新
        $task->is_completed = 1;
        $task->save();
    }
});
```

## 起きる不具合のイメージ
+ task1:最初のループで処理される
+ task2:最初のループで処理される
+ task3:最初のループで処理される
+ task4:１〜3が更新されたことによって、indexがずれ、２回めのループ対象にならない
+ task5:１〜３が更新されたことによって、indexがずれ、２回めのループ対象にならない
+ task6:１〜３が更新されたことによって、indexがずれ、２回めのループ対象にならない
+ task7:２回めのループ対象になり更新される。
+ task8:２回めのループ対象になり更新される。
+ task9:２回めのループ対象になり更新される。

task1〜3がクエリ条件から消えたので、task4〜6のindexがtask1〜3に昇格してしまった感じ。

# 代替案
limit()->get()->isEmpty() + whileにするだけ。これだけで対象のレコードに対して全件処理できる。

```php
// 未完了のタスクを３件ずつ取得して完了にする
while(!($tasks = Tasks::where('is_completed', 0)->limit(3)->get())->isEmpty()) {
    foreach ($tasks as $task) {
        // 完了タスクに更新
        $task->is_completed = 1;
        $task->save();
    }
}
```


# まとめ
+ 事前に対象のレコードをチェックせずにすむので、データ量を意識せずに解決できる
+ whileはこういう処理が向いている。

# 備考
+ 変数の初期化とか$loop=trueみたいなことをしても解決できるけど、めんどくさかった。
+ ただ単にwhileの条件や変数定義をワンライナーにしたかっただけ。
Selenide(fastSetValue=true)でSeleniumのフォーム入力を高速化できる！？

今回は、Seleniumのフォーム入力を高速化する方法を紹介します。
Seleniumを使ってフォーム入力を行なう場合は、通常は`WebElement`の`clear`や`sendKeys`メソッドを使いますが、入力文字数に比例して入力速度が遅くなる傾向があります。少ない文字数だと入力速度が遅くなることを体感するのは難しいですが、テキストエリアなどに大量の文字を入力すると、入力速度が遅くなることを体感することができます。

# 一般的なフォーム入力の方法

Seleniumでの一般的なフォーム入力の方法は、以下のような感じです。

```html:HTMLの入力フォーム例
<textarea name="note" cols="100" rows="30"></textarea>
```

```java:Seleniumを介した入力フォームへの値の設定例
WebElement element = webDriver.findElement(By.name("note"));
element.sendKeys("foo...");
```

# 高速化＝JavaScriptを使う！！

SeleniumはJavaScriptをサポートしており、JavaScriptを使用してフォーム入力を行なうことができます。JavaScriptを使用すると、`sendKeys`メソッドを使う方法に比べて入力速度の向上が望めます。

JavaScriptを使用してフォーム入力する方法は、以下のような感じです。

```java
WebElement element = webDriver.findElement(By.name("note"));
((JavascriptExecutor) webDriver).executeScript("arguments[0].value = arguments[1];", element, "foo...");
```

ポイントは・・・

* `WebDriver`インスタンスを`JavascriptExecutor`にキャストする
* `JavascriptExecutor`の`executeScript`メソッドの第１引数にJavaScriptコードを指定する
* `JavascriptExecutor`の`executeScript`メソッドの第２引数以降にJavaScriptコードへのパラメータを渡す

という点です。

JavaScriptコードの中では、JavaScriptコードへのパラメータを「`arguments[n]`」という形式(nは0〜)で指定できるため、上の例だと・・・

* `arguments[0]`には`WebElement`のインスタンス( = `webDriver.findElement(By.name("note"))`の結果)
* `arguments[1]`には入力値( = `"foo..."`)

がJavaScriptコードに渡され、入力フォームの`note`に入力値を設定することができるのです！！
ただ・・・ちょっとコード量が増える（煩雑なコードになる）ので、ユーティリティメソッドなどを用意する方がよさそうですね。

# SelenideでJavaScriptを使う！！

[Selenide](https://github.com/codeborne/selenide)はSeleniumのラッパーライブラリで、jQuery LikeにSeleniumの`WebElement`を操作することができます。

Selenideを使用してフォーム入力する方法は、以下のような感じです。

```java
$(By.name("note")).val("foo...");
```

Selenideのデフォルト動作はSeleniumの標準的な入力方法と同様に、`WebElement`の`clear`や`sendKeys`メソッドを使いますが、この動作はSelenideのオプション指定でJavaScriptを使用する方法に変更することができます。（＝入力値を設定するコードを直す必要はありません！！）

強制的にJavaScriptして入力値を入力したい場合は、以下のようにテストケースクラスでオプションを指定しましょう。

```java
...
import static com.codeborne.selenide.Configuration.*; // オプション指定するためにstaticフィールドのインポート
...
public class UITest {

    @Before
    public void setupSelenide() {
        // ...
        fastSetValue = true; // 値の設定を高速化するオプションを有効にする (JavaScriptを使用したフォーム入力が使われる)
    }

    // ...

}
```

入力方法を実行時に切り替える場合は、テストケース内で指定するのではなく、Javaのシステムプロパティを使用してオプションを指定(`-Dselenide.fastSetValue=true`)してください。

# 実践アプリの紹介

以下のアプリで、Selenide＋JavaScriptを使用したフォーム入力を実践しています。（参考までに・・）

* https://github.com/kazuki43zoo/mybatis-spring-boot-jpetstore/blob/master/src/test/java/com/kazuki43zoo/jpetstore/JpetstoreApplicationTests.java


# まとめ

Seleniumを使用して大量の文字をフォームに入力する場合は、JavaScriptを使用する方法に変更することを検討してみるとよいと思います。１項目単位でみると速度差は体感しずらいと思いますが・・・フォーム内の入力項目数やテストケース数が増えるにつれて（チリツモで）速度差を体感できると思います。


# 参考サイト

* http://selenide.org/2014/09/28/selenide-2.13-and-2.14/#fast-method-setvalue
ESRテスタを活用して555回路で実験

ESRテスタキット kitpochete
https://xshell.io/portfolio/kitpochette/

![IMG_20170306_172427.jpg](https://qiita-image-store.s3.amazonaws.com/0/139524/1285b215-eb05-8930-305b-eb09ab2442c8.jpeg)


を使った電子工作のテキストです。


# Lチカするには

ArduinoでもRaspberryPiでもLEDを点滅させるLチカというのが定番工作になっています。

LチカはマイコンなどのCPUにプログラムして制御しますが、プログラムなしでIC１つで点滅することができます。ここでは、555 という便利なICを使ってみましょう。

# 555 とは

タイマーICです。使いやすく、昔からいろんな用途に使われてきました。
ON/OFFをタイマーで制御することができます。

ON→一定時間でOFFという回路を作ることができます。

ON→一定時間でOFF→一定時間でON→・・・

という動作もすることができ、これを非安定モードといいます。

今回は、555を非安定モードで使い、Lチカをやってみます。

## 555のバリエーション
1972年に米国のシグネティクス社で開発され、NE555という名前となりました。その後RA555、XR-555などの名前で世界中の様々な会社からコピー品や改良品が作られています。

そのうち、CMOS版の555は LMC555,TLC555 と言う名前になっていて今回はそれを使います。

## バイポーラ版とCMOS版の違い

通常はバイポーラ版。CMOS版は低消費電力で、電圧も1.5Vで動くものもある。

## 556,558

また、1つのICに1回路の555が入っているのが標準ですが、1つのICに2つや4つの555回路が入っているのがあり、そのICは556、558という名前になっています。


# 配線

ブレッドボードに555回路を構築します。
![image](https://qiita-image-store.s3.amazonaws.com/0/139524/eec0415a-8c92-65ca-f861-65d0aebdc82d.png)

この回路を以下のページを参考に作成して下さい

## 電源のとりかた

![IMG_20170415_150307.jpg](https://qiita-image-store.s3.amazonaws.com/0/139524/2a7e5246-45de-7f88-3602-8d3fd49b60e1.jpeg)
![IMG_20170415_150426.jpg](https://qiita-image-store.s3.amazonaws.com/0/139524/5915e835-1851-49f0-ac05-1dfd484ba89f.jpeg)
![IMG_20170415_150440.jpg](https://qiita-image-store.s3.amazonaws.com/0/139524/4691fafd-5f7c-213b-cdd9-8314e29a91c8.jpeg)

# パラメータ計算

## 時定数の計算

![image](https://qiita-image-store.s3.amazonaws.com/0/139524/eec0415a-8c92-65ca-f861-65d0aebdc82d.png)

ここのR1,R2,Cで時定数が決まります。

ON／OFFの間隔tとすると、

$ t=\dfrac {\left( R1+R2\right) C} {1.44} $ 

このうち、t のうちLoの比率は $ D=\dfrac {R2} {R1+2R2} $ ​で求まります。

以下に、Webで計算してくれるサイトがあります。
http://www.zea.jp/audio/schematic/sc_file/018.htm

まずは、LEDでチカチカしてみましょう。

## 時定数変えてみる

Rの値を大きくしたり、Cの値を大きくすると点滅の時間が短くなります。

1/100よりも小さくなると、目で見てもわからなくなります。

そうなったら圧電スピーカをつないで音で聞いてみましょう。

## ラの音を出す

440Hz 原音のドの1つ下のラ
880Hz 原音のドの1つ上のラ

です。この音を出してみましょう。

## サーミスタの計算

サーミスタは、温度で抵抗値が変わります。
R1ないしR2をサーミスタに変えて、音で音が変わるようにしてみましょう。

http://keisan.casio.jp/exec/user/1248569182

# 555回路を２つ組み合わせたもの

![IMG_20170308_202008.jpg](https://qiita-image-store.s3.amazonaws.com/0/139524/841347fc-1e7d-9c1d-3466-0682d00f0e20.jpeg)

555回路1 を、1秒程度で点滅する回路、
555回路2 を、880Hz程度で音を出す回路とします。

回路1の出力を回路2につなげてみると、
音を断続的に出したり、ピーポー音になったり。

## アナログシンセサイザーをつくってみよう

いろんなところにつなげると、音の高低や周波数をアナログ的に制御できるようになります。
php -S するだけの小さな Docker イメージ

テストように、サーブするイメージを使いたくて、書きました。

```yaml:Dockerfile
FROM php:7
WORKDIR /myapp
ADD index.php /myapp/index.php
CMD php -S 0.0.0.0:7788
```
上で、`CMD php -S localhost:7788` と書いてしばらくハマっておりました。 😓

```html:index.php
<html>
  <body>
    kuririn
  </body>
</html>
```

```html

$ tree
.
├── Dockerfile
└── index.php
```

いかのコマンドを叩くと `localhost:7766` でアクセスができるようになります。

```bash:Command
$ docker build --tag php-sample .
$ docker run -d -p 7766:7788 php-sample
```

以上です。😬

<img width="243" alt="スクリーンショット 2017-04-15 15.20.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/45822/9ef93fc7-e6d5-f597-35ed-fc720e3a7b00.png">
毎日たくさんのWebサイトを定期的に見ている人へ送るスクリプト

# はじめに

毎日30個くらいのWebサイトをチェックしているので、それをターミナルから操作するスクリプトを書きました。

# かんたんなやり方

いつも同じページで、10ページくらいしかみない人
> 1. フォルダーにブックマークする
1. すべてのブックマークを開くを選ぶ
1. すべてのリンクが同時に開きます

<img width="439" alt="スクリーンショット 2017-04-15 15.03.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/112929/b7313f14-8b57-d5ad-0ce2-ec70094bf29b.png">


# 今回のスクリプト

## 仕様

* たまに更新される
* テキストファイルでリンクが渡される
* 5ページくらいずつ開きたい
* たまにhttpすらついてないやつが来る
* LINES_NUM = 2のとこをいじると、何ページずつ開くか選べる

## コード

```python

# coding: utf-8

import webbrowser

LINES_NUM = 2

urls = """
https://www.google.co.jp/
https://github.com/

qiita.com
"""

urls = [url for url in urls.split("\n") if url]

for i, url in enumerate(urls, 1):

    # correct url
    if not url.startswith("http"):
        url = "http://" + url

    webbrowser.open_new_tab(url)

    # stop each line by standard input
    if i % LINES_NUM == 0:
        raw_input("type something >> ")

```

コメント欄でいい感じに直していただいたので感謝ですm(_)m

<img width="651" alt="スクリーンショット 2017-04-15 15.09.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/112929/eaa47b9e-4567-f08f-4600-5ab883b53f55.png">

こんな感じで[type something >> ]とくるので適当にEnterを押してやると、次の指定行(LINES_NUM = 2)が読まれます。


# 参考
空行削除: [リストから空の要素を削除する](http://haru.moo.jp/2015/07/%E3%83%AA%E3%82%B9%E3%83%88%E3%81%8B%E3%82%89%E7%A9%BA%E3%81%AE%E8%A6%81%E7%B4%A0%E3%82%92%E5%89%8A%E9%99%A4%E3%81%99%E3%82%8B/)
Mastodon+SendGridでSMTP_OPENSSL_VERIFY_MODEをpeerで動作させる

MastodonのメールサーバにSendGridを使った場合に少しだけハマったので解決策をメモ。

## 現象

MastodonのメールサーバにSendGridを使った際、以下のようなエラーが出てメール送信できない場合があります。エラーの意味は「SSL証明書の検証に失敗した」というもの。Herokuにデプロした環境で確認しました。

```
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
```

## 原因

Mastodonのメール周りの設定は以下の通りです。他の設定については[ドキュメント](https://github.com/tootsuite/documentation)を参照してください。

| 変数       | 値 |
|:-------------|:------------------|
| SMTP_AUTH_METHOD | plain |
| SMTP_ENABLE_STARTTLS_AUTO | true |
| SMTP_FROM_ADDRESS | ***送信元メールアドレス*** |
| SMTP_LOGIN | apikey |
| SMTP_OPENSSL_VERIFY_MODE | peer |
| SMTP_PASSWORD | ***[Mail Sendパーミッションを与えたSendGridのAPIキー](https://sendgrid.kke.co.jp/docs/Tutorials/A_Transaction_Mail/manage_api_key.html)*** |
| SMTP_PORT | 587 | 
| SMTP_SERVER | smtp.sendgrid.net |

ポイントは`SMTP_OPENSSL_VERIFY_MODE`を**peer**に設定している点。この設定にすることでSMTPサーバのSSL証明書の有効性を検証して、接続先がなりすまされていないことを確認できます。冒頭のエラーはこの検証に失敗したことを意味しています。
原因として考えられるのは次のようなものがあります。

1. 証明書の有効期限が切れている
2. 証明書が失効リストに登録されている
3. クライアント側に対応するCA証明書がない、もしくは適切に設定されていない

1と2はSendGrid側で証明書の管理が適切に行われていれば発生することはないので、可能性として一番高いのは**3**です。

## 解決策
一応、前提条件として、Mastodon〜SendGrid間はTLSを使って暗号化するものとします。

１． **証明書の検証をしない方法**（非推奨）
一番手っ取り早いのが`SMTP_OPENSSL_VERIFY_MODE`を`none`にして証明書の検証をスキップする方法です。この設定にしても通信はTLSで暗号化されますが、サーバ側がなりすまされていた場合に情報が漏えいする危険性があります。とりあえずの対処と考えてください。
2. **証明書の検証をする方法**（推奨）
CA証明書のパスを設定すればちゃんと検証できるようになります。こっちの方が前向きですね。MastodonはActionMailerを使ってメールを送信しています。

まず、`mastodon/config/environments/production.rb`を編集して、config.action_mailer.smtp_settingsに`:ca_file`の設定を加えます。この変更は、production.rbと同じディレクトリ内にあるCA証明書をca_fileに指定する、という内容です。後で用意するCA証明書のパスを変更する場合は、適当に修正してください。

```
  # E-mails
  config.action_mailer.smtp_settings = {
    〜省略〜
    :ca_file => File.expand_path(File.dirname(__FILE__)) + '/gd_bundle-g2-g1.crt', # <=この行を加える
  }
```

次に、CA証明書を準備します。SendGridではGoDaddyというCAが発行した証明書を利用しているので、GoDaddyのCA証明書(ファイル名：gd_bundle-g2-g1.crt)を[ここから](https://certs.godaddy.com/repository)ダウンロードして、先程編集したproduction.rbと同じディレクトリに保存します。

以上で完了です。再度デプロイしてユーザー登録すると以下のようなログが出てメールが送信されはずです。

```
Performed ActionMailer::DeliveryJob from Sidekiq(mailers) in 884.5ms
```
TSファイルを安直にトランスコーディング

家のTV録画環境はTS抜きで撮り、生TSファイルのまま貯めている。
しかしながら最近放送大学全録はじめたら、あっという間にHDDが埋まってゆく。
放送大学なんてワンセグで十分なんだけれど、ワンセグ放送やっていないのでフルセグをトランスコーディングする。

# 環境
チューナのドライバの問題で録画環境はWindowsで構築している。
Windows 10 Pro 64bit

# インストール
A's Video Converter
http://bluesky23.yukishigure.com/AsVideoConv.html
(ライセンス：フリーソフト、オリジナルライセンス、再配布禁止、非OSS)

K-Lite Codec Pack Mega
https://www.codecguide.com/download_k-lite_codec_pack_mega.htm
(ライセンス：不明)

どうせWindowsだしドメスティックなところでツールの検証は安直でいいかな。


# 設定

エンコーダをMicrosoft H.264 Encoderと設定。
ビデオエンコードのレートコントロールは初期値VBR。
このままトランスコードすると、
元ファイル1.6Gがトランスコードして1.7Gに増えてしまった。

ビデオエンコードのレートコントロールをCBRに変更し、目標ビットレートを128kbpsとすると
トランスコード後のファイルは87MBytes。

目標ビットレートを300kbpsにすると
トランスコード後のファイルは162MBytes。

上記だけだと割と変換失敗が発生したので、
Marumo ISDB Splitter
をGigazineで紹介されている手順でインストールした
http://gigazine.net/news/20170311-as-video-converter/

こんなところでいいかな。

# コード

A's Video Converterいろいろ設定できるようだが、バッチ機能は弱いようで外部コードで補完。

ファイルをトランスコードした後に元ファイルは消すバッチファイル

```
"c:\Program Files\A's Video Converter\AsVideoConv.exe" "%1" | more
del 
```
見積もりの重要性3

先日に引き続き、過去のイベントで使用した資料をslideshareにアップしました。

https://www.slideshare.net/MasashiNamba/3-75041733
<img width="904" alt="3-1.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/23404/6315612a-3ff8-bdee-61f7-b9b408662b25.jpeg">

規模見積もりや生産見積もりについてです。
<img width="904" alt="3-2.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/23404/955b76e9-0796-1365-970a-514fbe50af69.jpeg">