OmniAICreator/Qiita-1.07M huggingface dataset:
PCにGPUを導入した後にやること

## 条件
2017/07/25
Ubuntu 16.04
GeForce GTX 970

## GPUのドライバ
もし，ディープラーニングをやらないのであれば，

```bash
sudo apt-get install nvidia-375
sudo reboot
```
でおしまい．
数字が一番大きい（＝最新のドライバ？）ものを選んどけば間違いない．

もし，ディープラーニングをやるのであれば，aptで入れてはダメで，手順としては

1. もしaptで入れていたら消す
2. cudaを入れる: https://developer.nvidia.com/cuda-downloads
3. cuDNNを入れる： https://developer.nvidia.com/rdp/form/cudnn-download-survey
4. ``.bashrc``に設定を書く

が必要で，
2に関してはInstaller Typeをdeb(network)にした．この時同時にGPUのドライバ（？）も入るので，1を先にやっておく必要がある．
3に関しては，tensorflowが対応しているv5.1を入れた．v6.0だとtensorflowが動かなかったので．

4に関しては以下を追記．

```bash
export PATH="/usr/local/cuda-8.0/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda-8.0/lib64:$LD_LIBRARY_PATH"
```

### 2018/07/04 追記
- https://www.tensorflow.org/install/install_sources#tested_source_configurations

ここにtensorflow向けのCUDAとcuDNNのversionのオススメ対応表が載っているので，都度確認してからインストールする．
CUDAはaptで入れたり消したりすればよいが，
cuDNNは消すときは手動で消す必要があって，[ここ](https://qiita.com/JeJeNeNo/items/05e148a325192004e2cd#cudnn-51%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%A8%E3%82%A2%E3%83%B3%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)が分かりやすい．

具体的には，``sudo rm /usr/local/lib/libcudnn* /usr/local/include/cudnn.h``をすればよい．

また，cudaをaptで新しいversionを入れるときは，

```bash
sudo apt autoremo # 一旦綺麗にする
sudo aptitude cuda-X-X # aptitudeで関連パッケージ(?)も消す
sudo apt install cuda-Y-Y # 新しいversionを入れる
```

という手順でやる．aptでなくてaptitudeで消すと安心できる．

## virtualenvの導入
環境を汚したくないので，virtualenvを使う．
virtualenvよりも良い方法があるかもしれないし，時代遅れかもしれないが，とりあえずこれで．

```bash
sudo pip install virtualenv
sudo pip install virtualenvwrapper
```

で入れて，

```bash
if [ -f /usr/local/bin/virtualenvwrapper.sh ]; then
    export WORKON_HOME=$HOME/.virtualenvs
    source /usr/local/bin/virtualenvwrapper.sh
fi
```
と``.bashrc``に追記．

そのあと，

```bash
mkvirtualenv dnn
```
で環境構築が出来る．``workon dnn``で入れる．

## virtualenv上にDNNのフレームワークを入れる

- tensorflow
- chainer

を入れる．

```bash
pip install tensorflow-gpu
pip install chainer
pip install cupy
```

としたら入る．
``cupy``は``chainer``でGPUを使うのに必要で，installが上手く行かないかもしれないが， https://docs-cupy.chainer.org/en/latest/install.html とかをちゃんと読むと普通にpipで入る．何を苦労したかは忘れたが，pipで普通に入る．

```py
chainer.cuda.available
chainer.cuda.cudnn_enabled
```

で確認できるとのこと．

今後は``workon dnn``で進める．

## OpenAI Gymを入れる
流行っているっぽいので入れる．

```bash
workon dnn
cdvirtualenv
mkdir src
cd src
git clone https://github.com/openai/gym
cd gym
pip install -e .[all]
```

でハマりポイント無く入る．

```py
import gym
env = gym.make('CartPole-v0')
env.reset()
for _ in range(1000):
    env.render()
    env.step(env.action_space.sample())
```

で動作確認可能．
[メモ] (らずぱい) Raspbian: Jessie から Stretchへアップグレード


(2017/8/18): 公式イメージがStretchになった模様
> [RASPBIAN STRETCH HAS ARRIVED FOR RASPBERRY PI](https://www.raspberrypi.org/blog/raspbian-stretch/)


## 概要
- Raspbianを Jessie(Debian 8)から、Stretch(Debian 9)にアップグレード 
- 参考元記事: [Raspbian GNU/Linux upgrade from Jessie to Raspbian Stretch 9](https://linuxconfig.org/raspbian-gnu-linux-upgrade-from-jessie-to-raspbian-stretch-9) 
- 素のままのらずびあん(他のパッケージをインストールしない)からの、Stretchへのアップグレードのみ確認。

## 環境
- Raspberry Pi 2 
- Raspbian:
    - `2017-07-05-raspbian-jessie-lite`

<!--    - `2017-07-05-raspbian-jessie`
-->

## 手順
1. Raspbianを焼いて、起動。
2. 現状のパッケージを更新・再起動

	```bash
	# 現状のパッケージを更新・再起動
	sudo sh -c 'apt update && apt upgrade -y && reboot'
	```
3. Stretchへアップグレード

	```bash
	# パッケージレポジトリを `jessie` から、`stretch`へ変更
	sudo sed -i 's/jessie/stretch/g' /etc/apt/sources.list
	sudo sed -i 's/jessie/stretch/g' /etc/apt/sources.list.d/raspi.list #2017.8.18追記
	
	# パッケージ情報更新
	sudo apt update

	# シミュレートモードで、様子見
	apt --simulate upgrade -y

	# パッケージ更新・再起動 ... 途中、設定とかどうするかとか、きかれる。。とりあえず、Y.
	time sudo sh -c 'apt upgrade -y && apt dist-upgrade -y && reboot'
	```


4. 再起動後

	```bash:お好みで
	# 不要なパッケージ削除
	sudo apt-get autoremove --purge -y
	```
	- 再起動後、IPアドレスが変わっている場合もあるよ.


## その他
- `ssh`経由でもできた。
- `/etc/os-release`

	```shell-session
	pi@raspberrypi:~ $ cat /etc/os-release
	PRETTY_NAME="Raspbian GNU/Linux 9 (stretch)"
	NAME="Raspbian GNU/Linux"
	VERSION_ID="9"
	VERSION="9 (stretch)"
	ID=raspbian
	ID_LIKE=debian
	HOME_URL="http://www.raspbian.org/"
	SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
	BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
	pi@raspberrypi:~ $ uname -a
	Linux raspberrypi 4.9.35-v7+ #1014 SMP Fri Jun 30 14:47:43 BST 2017 armv7l GNU/Linux
	pi@raspberrypi:~ $
	```
- `raspbian-lite`にて、

	```
	real    39m59.530s
	user    8m40.870s
	sys    7m9.640s
	```
爆速 grep「ripgrep」をラズパイにインストールする【実測値あり】

## TL;DR

通常の `grep` や `ag` よりも圧倒的に早いという**「[RipGrep](https://github.com/BurntSushi/ripgrep)」（`rg`）を Raspbian にインストールする**方法と簡単な使い方です。

[MacOSX へ入れてみた](https://blog.keinos.com/20170910_2893)り、[さくらのVPS（CentOS7）に入れて見た](https://blog.keinos.com/20170724_2840)ところ非常に早かったのですが、 RaspberryPi3 ＋ Raspbian（Jessie, Debian8.0）にインストールする場合の情報が少なかったので、軽いストレス・テスト（実測）をかねて記事を書いてみました。

結論を言うと **10.5GB のファイルを全文検索して`grep` と比較して 30 秒以上の差**が出ました。

## TS;DR

### RipGrepとは

RipGrep（`rg`）は、`grep` に似た**コマンドライン・ベースの UTF-8 対応テキスト検索ツール**です。

[BurntSushi](http://blog.burntsushi.net/ripgrep/) 氏によって [`Rust`](https://ja.wikipedia.org/wiki/Rust_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E)) で書かれており、[`Silver Searcher`](http://qiita.com/tags/ag)（`ag`） の使いやすさと `GNU grep`（`grep`）の本来のスピードを兼ね備えています。 Windows, Mac, Linux などの OS で動作します。

### インストール

Raspbian Buster では `apt` でインストールできます。`ARMv6l`（ラズパイ Zero W）アーキテクチャでも動作しました。

```bash
sudo apt install ripgrep
```

```shell-session:簡易インストール
$ sudo apt install ripgrep
...
$ rg --version
ripgrep 0.10.0
-SIMD -AVX (compiled)
```

上記でインストールできない場合は下記でお試しください。

```shell-session:本来のインストール方法
cd ~/
# 依存ファイルのインストール（基本デフォルトのまま進んでOK）
curl https://sh.rustup.rs -sSf | sh
sudo apt-get install debhelper
sudo apt-get install devscripts
sudo apt-get install quilt

# cargoのパスを通す
source $HOME/.cargo/env

# ripgrepのインストール
cargo install ripgrep
```

### 使い方

```shell-session
rg 'メキシコ'
```
正規表現も使えます

```shell-session
rg '1[^7][0-9[0-9]年'
```

詳しくは`rg --help`コマンドで[ヘルプをご覧ください](https://blog.keinos.com/20170724_2840#help)。

### 実測してみた

Wikipediaからダウンロードした **10 ギガバイト**の XML のテキストファイルから「メキシコ」という単語を検索して、その結果をファイルに書き込み終えるまでの速度を比較してみました。

||ファイルサイズ|検索単語|平均秒数|差分|
|:----:|:---:|:----:|:----:|:----:|
|grep|10.5GB|'メキシコ'|502|+35|
|rg|10.5GB|'メキシコ'|467|0|

#### 測定方法

コンマ何秒というレベルの差ではないため、linux の `$SECONDS` を使って経過時間を測定します。

検索開始前に `$SECONDS` のカウンターをリセットし、検索結果をファイルに書き込んだ時点までの秒数を測定しています。

留意点として、データ量が大きいため USB2 の外付けハードディスクに保存しての測定なので本来はもう少し早いと思います。

#### 検証データの準備

Wikipedia の日本語データを、外付け HDD(`/mnt/hdd1/wikipedia`) にダウンロード＆展開します。10.5 ギガバイト程度あるのがわかります。

```shell-session
$ cd /mnt/hdd1/
$ wget https://dumps.wikimedia.org/jawiki/latest/jawiki-latest-pages-articles.xml.bz2
$ bunzip2 jawiki*
$ ls -la
合計 10285620
drwxr-xr-x 3 root root        4096  7月 24 17:38 .
drwxr-xr-x 3 root root        4096  7月 15 01:36 ..
-rw-r--r-- 1 root root 10532457736  7月 22 02:23 jawiki-latest-pages-articles.xml
```

#### 測定

##### grep

```shell-session
$ cd /mnt/hdd1/
$ SECONDS=0 && grep 'メキシコ' *.xml > ~/result_grep.txt && echo ${SECONDS}
```

|秒|分：秒|
|:----:|:----:|
|502|8:22|
|502|8:22|
|500|8:20|
|504|8:24|
|501|8:21|
|平均|---|
|502|8:22|

##### rg

```shell-session
$ cd /mnt/hdd1/
$ SECONDS=0 && rg 'メキシコ' > ~/result_rg.txt && echo ${SECONDS}
```

|秒|分：秒|
|:----:|:----:|
|455|7:53|
|463|7:43|
|463|7:43|
|478|7:58|
|475|7:55|
|平均|---|
|467|7:47|
Processingによる花火

# Processingによって花火を打ち上げる

夏です。花火の季節です！今回はProcessingで花火を演出してみました！

# 概要

[先ほど投稿した記事](http://qiita.com/mikittt/items/22671e1a4c35a90ea028)でも発光表現を扱いましたが、今回はオリジナルを紹介します。

キー入力によって花火が打ち上がるようになっています。
加速度センサなど、各種センサと連携して花火を打ち上げるのも面白いです！

ソースコードも貼っておきます。(※当初より少し整理しました)

```
ArrayList<Fireworks> fireworks=new ArrayList<Fireworks>();           
  
void setup () {
  fullScreen(P3D);
  frameRate(50); 
  hint(DISABLE_DEPTH_TEST);
  blendMode(ADD);
  imageMode(CENTER);
}
 
void draw () {
  background(0,0,40);
  for(int i=0;i<fireworks.size();i++){
     Fireworks art=fireworks.get(i);
     if(art.centerPosition.y-art.radius>height){
       fireworks.remove(i);
     }
     art.display();
     art.update();
   }
}

void keyPressed(){
  fireworks.add(new Fireworks(80));
}



//発光表現の元となるクラス
PImage createLight(float rPower,float gPower,float bPower){
  int side=64;
  float center=side/2.0;
  
  PImage img=createImage(side,side,RGB);
  
  for(int y=0;y<side;y++){
    for(int x=0;x<side;x++){
      float distance=(sq(center-x)+sq(center-y))/10.0;
      int r=int((255*rPower)/distance);
      int g=int((255*gPower)/distance);
      int b=int((255*bPower)/distance);
      img.pixels[x+y*side]=color(r,g,b);
    }
  }
  return img;
}

//花火クラス
class Fireworks{
  //花火の火の数
  int num=512;
  //花火の中心の初期位置
  PVector centerPosition=new PVector(random(width/8,width*7/8),random(height/2,height*4/5),random(-100,100));
  //花火の中心の初期速度
  PVector velocity=new PVector(0,-22,0);
  //重力
  PVector accel=new PVector(0,0.4,0);
  PImage img;

  float radius;
  
  PVector[] firePosition=new PVector[num];
  
    
  Fireworks(float r){
    float cosTheta;
    float sinTheta;
    float phi;
    float colorchange=random(0,5);

    radius=r;
    for (int i=0;i<num;i++){
      cosTheta = random(0,1) * 2 - 1;
      sinTheta = sqrt(1- cosTheta*cosTheta);
      phi = random(0,1) * 2 * PI;
      firePosition[i]=new PVector(radius * sinTheta * cos(phi),radius * sinTheta * sin(phi),radius * cosTheta);
      firePosition[i]=PVector.mult(firePosition[i],1.12);
    }
    //色をランダムで初期化(綺麗な色が出やすいように調整)
    if(colorchange>=3.8){
      img=createLight(0.9,random(0.2,0.5),random(0.2,0.5));
    }else if(colorchange>3.2){
      img=createLight(random(0.2,0.5),0.9,random(0.2,0.5));
    }else if(colorchange>2){
      img=createLight(random(0.2,0.5),random(0.2,0.5),0.9);
    } else {
      img=createLight(random(0.5,0.8),random(0.5,0.8),random(0.5,0.8));
    }
  }
  
  void display(){
    for (int i=0;i<num;i++){
      pushMatrix();
      translate(centerPosition.x,centerPosition.y,centerPosition.z);
      translate(firePosition[i].x,firePosition[i].y,firePosition[i].z);
      image(img,0,0);
      popMatrix();
      
      firePosition[i]=PVector.mult(firePosition[i],1.015);
    }
  }
  
  void update(){
    radius=dist(0,0,0,firePosition[0].x,firePosition[0].y,firePosition[0].z);
    centerPosition.add(velocity);
    velocity.add(accel);
  }
}
```

# 結果
![結果](https://media.giphy.com/media/3o8dFAB1CVuhyJorXW/giphy.gif)

皆さんもアートの力でこの夏をより一層盛り上げましょう！
学校のメールアドレスがない高校生がGitHub Educationを使う方法

学校のメールアドレスがない高校生がGitHub Educationを使うための方法のメモです。
###結論
質問に答えるページにある**Verify academic status**という質問で`I don't have a school-issued email`を選択します。そうすると、生徒手帳の写真をアップロードする場所が出てくるので、それを使って生徒手帳の写真をアップロードします。これで学校のメールアドレスを持っていない場合でもRequestが送ることができます。この時あなたが現在学生であることを証明できる少なくとも一つの日付がはっきりと見えることを確認してください。

#順序
###GitHub EducationのWebページにアクセス
[GitHub Education](https://education.github.com)
<img width="1280" alt="スクリーンショット 2017-07-25 1.11.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/70429/c10e6252-0693-fcb7-73aa-412bf08bf239.png">
真ん中にある**Request a discount**というボタンをクリックします。そうすると、自分の情報を入力するページに移ります。（ GitHubへのログイン画面が出る場合もあります。その場合はそこでログインしてください。）

###質問に答える
そのページで
**Which best describes you?** という質問で **Student**
**What are you looking to get a discount for?** という質問で **Individual account**
を選択します。

そうしたら**Next**をクリックし、次のページに移ります。

次のページでは自分の個人情報を入力します。
**Name**には自分のユーザ名が入力されています。
**Verify academic status**では学校のメールアドレスを持っているかどうかで、やることが変わります。

**持っている場合**
学校のメールアドレスを選択して次に進んでください。(GitHubにそのメールアドレスが登録されている必要があります。)

**持っていない場合**
`I don't have a school-issued email`を選択します。そうすると、生徒手帳の写真をアップロードする場所が出てくるので、それを使って生徒手帳の写真をアップロードします。この時あなたが現在学生であることを証明できる少なくとも一つの日付がはっきりと見えることを確認してください。

**School name**には現在通っている学校の名前を英語で入力してください。
**Graduation year**は卒業予定年を選択してください。
**How do you plan to use GitHub?**にはどのようにGitHubを使う予定かを英語で入力してください。１〜２行程度で友人と開発をするなどのようなことを入力すれば大丈夫です。

全て完璧に入力したら**Submit Request**をクリックして完了です。承認されるとメールが来るので、それを待ちましょう。
fish-shellでcsv読み込み

fish-shellでカンマでsplitを行うには
`string split , $var`
でおこなうことができる

以下のcsvがあったとすると

```csv:syukujitsu_utf8.csv
国民の祝日月日,国民の祝日名称
2016-01-01,元日
2016-01-11,成人の日
2016-02-11,建国記念の日
2016-03-20,春分の日
2016-04-29,昭和の日
2016-05-03,憲法記念日
2016-05-04,みどりの日
2016-05-05,こどもの日
...
```


```fish:csv_read.fish
for line in (cat syukujitsu_utf8.csv)
  set -l syuku (string split , $line)
  echo "$syuku[1]は$syuku[2]です"
end
```

```
$ fish csv_read.fish
国民の祝日月日は国民の祝日名称です
2016-01-01は元日です
2016-01-11は成人の日です
2016-02-11は建国記念の日です
2016-03-20は春分の日です
2016-04-29は昭和の日です
2016-05-03は憲法記念日です
2016-05-04はみどりの日です
2016-05-05はこどもの日です
2016-07-18は海の日です
....
```

下の書き方でもいける

```fish
while read -l line
  set -l syuku (string split , $line)
  echo "$syuku[1]は$syuku[2]です"
end < syukujitsu_utf8.csv
```
Rakeの終了時に実行したtaskの成否の通知を送る方法

[`at_exit`](https://docs.ruby-lang.org/ja/latest/method/Kernel/m/at_exit.html)を使うと終了時に処理を実行できる。
通知を送る処理を`at_exit`で登録するRakeタスクを定義し成否を通知したいタスクの依存タスクに追加するとべんり。

```ruby:Rakefile
desc "notify the tasks finished successfully or not"
task :notify_tasks_finished do
  at_exit do
    tasks = Rake.application.top_level_tasks.join(", ")
    if $!.nil? || $!&.success?
      puts "success: #{tasks}"
    else
      puts "fail: #{tasks}"
    end
  end
end

desc "hey"
task hey: :notify_tasks_finished do
  puts "hey"
end


desc "yo"
task yo: :notify_tasks_finished do
  yo
end
```

```console
% rake hey
hey
success: hey
% rake yo
rake aborted!
NameError: undefined local variable or method `yo' for main:Object
/home/sei/tmp/rake.rb:22:in `block in <top (required)>'
Tasks: TOP => yo
(See full trace by running task with --trace)
fail: yo
```
食べログのWebページから店舗のURLと点数を抽出するrubyプログラム

#rubyと食べログ初心者です!
#タグ付けの部分はスペース区切りなのか... ruby,はNG

「食べログからWebページから店舗のURLと点数を抽出するrubyプログラム」
未完成だけどいちおう動く
コメントアウトしたところは勉強用とデバグ用に残してます

```ruby:tabe_test.rb
require "uri"
require "pp"

href = []
score = []
shop_name = []
url = ""





File.open("./tabe_test.txt").each do |line|
	if line =~ %r|list-rst__rst-name|
#		score << line.scan(%r|\d.\d{2}|).to_s
		url = line.scan(%r|/">.+</a|).to_s
		url.gsub!(%r|/">|, "")
		url.gsub!(%r|</a|, "")
#		url.chomp!
		shop_name << url
	end
end



File.open("./tabe_test.txt").each do |line|
	if line =~ %r|"list-rst__rst-name-target cpy-rst-name"|
		href << URI.extract(line, ["https"]).to_s
	end
end

File.open("./tabe_test.txt").each do |line|
	if line =~ %r|list-rst__rating-val|
		score << line.scan(%r|\d.\d{2}|).to_s
	end
end




shop_name.each do |shop_n| puts shop_n end

shops = [score, href].transpose
#shops = [shop_name, href].transpose

#shops = [href, shop_name].transpose

#pp shop_name
pp shops

shops.each do |shop|
	if shop[0].to_f > 3.5
		puts shop[1]
	end
end

#File.open("tabe_test_result.txt", "w+") do |f| 
 # f.puts(str)
#end



#keys = ["募集", "残り", "キャンセル待ち"]
#values = [20, 0, 2]
# pairs = [keys, values].transpose
```
wikipediaのタイトル一覧にhrefをつけてhtmファイルにするrubyプログラム

#Qiitaとruby初心者です！

「タイトル数を数えて経過時間を測定するrubyプログラム」の続きです
http://qiita.com/taroyanaka/items/8d301c8c7ac54de21e8a

wikipediaのタイトル一覧にhrefをつけてhtmファイルにするrubyプログラムです
コメントアウトした+での文字連結をすると50分以上かかるところが重要
適当に作ったけど動くには動く


```ruby:title_add_href.rb
title = ""
title_num ||= 0
all_title_length ||= 0
average_title_length ||= 0


file_name = "./title_NoTitle.txt"

per ||= 0
File.open(file_name).each do |line|
	title_num += 1
end
one_per = title_num / 100
ten_per = title_num / 10

title += <<'EOS'
<html>
<body>
EOS

start_time = Time.now

File.open(file_name).each do |l|

	title_num += 1
	if title_num % one_per == 0
  	per += 1
		print("<")
		per.times do print("-") end
		(100-per).times do print("|") end
		print(">")
		puts

end_time = Time.now
colapsed_time = end_time - start_time
puts "経過時間" << colapsed_time.to_s << "s"


	end
	l.chomp!
#	title << %Q{<a href="https://ja.wikipedia.org/wiki/} + l + %Q{">} + l + %Q{</a></br>}
	title << %Q{<a href="https://ja.wikipedia.org/wiki/} << l << %Q{">} + l << %Q{</a></br>}

	if per == 10 then break end

end


title += <<'EOS'
</html>
</body>
EOS


File.open("test_title_NoTitle.htm", "w+") do |f| 
  f.puts(title)
end
```
タイトル数を数えて経過時間を測定するrubyプログラム

#Qiita初利用です

wikipediaのタイトルの数を数えるために作ったrubyプログラム
wikipediaのタイトル一覧の.txtファイルをtest_title_NoTitle.txtに張り付けて利用する


```ruby:word_counter.rb
title = []
title_num ||= 0
all_title_length ||= 0
average_title_length ||= 0
per ||= 0


File.open("./title_NoTitle.txt").each do |line|
	title_num += 1
end
one_per = title_num / 100


start_time = Time.now
File.open("./test_title_NoTitle.txt").each do |line|
		title_num += 1
		if title_num % one_per == 0

			  per += 1
				print("<")
				per.times do print("-") end
				(100-per).times do print("|") end
				print(">")
				puts
end_time = Time.now
colapsed_time = end_time - start_time
puts "経過時間" + colapsed_time.to_s + "s"

		end
		line.chomp!
		all_title_length += line.length
end




average_title_length = all_title_length / title_num

puts "title_num " + title_num.to_s
puts "all_title_length is " + all_title_length.to_s
puts "average_title_length " + average_title_length.to_s


```
Raspbianにtmuxを導入する

## やりたいこと
Raspbianでもtmux使ってハッピーになりたい

## 導入を行った環境
* Raspberry Pi 3 Model B+
* Raspbian 8.0

## 手順

### 準備
セットアップ用にフォルダを作成

```bash
mkdir ~/tmp
cd ~/tmp
```
### libeventの導入

`libevent`のversion2以上が必要になるので，自前でソースからビルドします．
`apt-get`で`libevent-dev`を入れても可能かもしれませんが，試していないのでわかりません．

```bash
wget https://github.com/downloads/libevent/libevent/libevent-2.1.8-stable.tar.gz
tar xvfz libevent-2.1.8-stable.tar.gz 
cd libevent-2.1.8-stable

./configure 

make
sudo make install 

sudo ldconfig
```

### ncuresesの導入

tmuxのconfigureで`ncureses`が必要なのでこちらも導入します．
こちらは`apt-get`から導入します．

```bash
sudo aptitude install libncurses5-dev
```

### tmuxの導入
tmuxの導入準備が整いました．
`libevent`のときと同様にtmuxもソースからビルドします．

```bash
cd ~/tmp
wget https://github.com/tmux/tmux/releases/download/2.5/tmux-2.5.tar.gz
tar xvfz tmux-2.5.tar.gz
cd tmux-2.5/

./configure

make
sudo make install
```
これで導入は終わりです．
Raspberry Piでも良いtmuxライフを．

## 参考
* [tmux のインストール](http://ja.528p.com/linux/centos6/B012-tmux.html)
* [Debian Lennyにtmuxをインストールする。 - 目の前に僕らの道がある](http://masasuzu.hatenablog.jp/entry/2013/01/15/221632)
超高速仮想ルーター/仮想スイッチ FD.io vppで1対1NATを設定する。

# 今までの作業
[超高速仮想ルーター/仮想スイッチ FD.io vppをVirtualBoxで動かす](http://qiita.com/hirofumimatsu/items/766a8d608fadeb87caaf)
[超高速仮想ルーター/仮想スイッチ FD.io vppの使い方](http://qiita.com/hirofumimatsu/items/d46c93459762e82ef6d6)

# NAT設定内容
100.127.253.54を192.168.10.102に変換する。

# 設定方法

## NATを有効化
外側のインターフェースはGigabitEthernet0/3/0、内側のインターフェースはGigabitEthernet0/4/0とする

```shell-session
vpp# set int snat in GigabitEthernet0/4/0 out GigabitEthernet0/3/0
```

## NAT address poolの追加

```shell-session
vpp# snat add address 100.127.253.54
```

## 1対1NATの追加 

```shell-session
vpp# snat add static mapping local 192.168.10.102 external 100.127.253.54
```
[クイズ]javascriptと仲良くなるための一歩　第８話「文字列と数値」

#第1問
```js
"100" - "1"
//=> ?
"100" + "1"
//=> ?
```

#第2問

```js
typeof +"100"
//=> ?
```

#第３問

```js
"100"+NaN
//=> ?
100+NaN
//=> ?
```

:mouse:
:cow:
:tiger:
:rabbit:
:dragon_face:
:snake:
:horse:
:sheep:
:monkey_face:
:bird:
:dog:
:boar:
:mouse:
:cow:
:tiger:
:rabbit:
:dragon_face:
:snake:
:horse:
:sheep:
:monkey_face:
:bird:
:dog:
:boar:

#第1問 文字列の数の計算

```js
"100" - "1"
//=> 99
"100" + "1"
//=> "1001"
```

`-`演算子を使った時は数値に変換し計算し、
`+`演算子を使った時は文字列として結合する。

#第2問 符号つけたときのtypeof

```js
typeof +"100"
//=> number
```

`+`演算子をつけることで数値に変換され、typeofはnumberになる

#第３問

`+`演算子を使った時は、文字列として結合します。
`-`演算子を使った時は、数値に変換し計算するのでNaNになります。

```js
"100"+NaN
//=> "100NaN"
100+NaN
//=> NaN
```
Djangoでモデル保存時（初回）に実行されるSQLを確認する

# はじめに

自サイトで[Djangoを読む](http://www.dzeta.jp/~junjis/code_reading/index.php?Django%E3%82%92%E8%AA%AD%E3%82%80)というソースコード読解をやっています。
その中で、モデル保存の部分を読んでいるときに「これってなんかのメソッド呼んだら実行されるSQL表示できないのかな」と思ったのですがなさそうなので「こうやれば表示できる」という方法を投稿しておきます。

# チュートリアル確認

[Djangoチュートリアル その2](https://docs.djangoproject.com/ja/1.11/intro/tutorial02/#playing-with-the-api)では次の手順でモデルをDBに保存しています。

```py
>>> from polls.models import Question, Choice
>>> from django.utils import timezone
>>> question = Question(question_text="What's new?", pub_date=timezone.now())
>>> question.save()
```

が、ここでsaveメソッドを呼ぶとSQLを構築してDBへの保存まで一気にされてしまいます。というわけでsaveメソッドを呼ぶのではなく、saveメソッドの中で行われていることの重要部分だけを手動で再現して実行されるSQLを出力しました。

# 準備その1：保存先DBの決定

まずはsaveメソッドで行われている処理の抜粋。

```py
>>> cls = question.__class__
>>> from django.db import router
>>> using = router.db_for_write(cls, instance=question)
```

モデルのクラス（クラスオブジェクト）はこの後も使うので変数に入れておきます。
django.db.routerというのはDBを分散している場合にどのDBに保存するかの決定する仕組みです。分散していなければ普通は'default'になります。

# 準備その2：フィールド情報とかの取得

saveメソッドから処理が進んでいくと_save_tableというメソッドに着きます。この中でSQLを構築するために必要なものだけ取り出すと、

```py
>>> from django.db.models.fields import AutoField
>>> meta = cls._meta
>>> fields = meta.local_concrete_fields
>>> fields = [f for f in fields if not isinstance(f, AutoField)]
>>> manager = cls._base_manager
```

metaというのはdb.models.optionsモジュールのOptionsクラスで、この中にフィールド情報とかが全部入っています。からくりについてはご興味があれば[私の読解記事](http://www.dzeta.jp/~junjis/code_reading/index.php?Django%2F%E3%83%A2%E3%83%87%E3%83%AB%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88%E6%99%82%E3%81%AE%E5%87%A6%E7%90%86%E3%82%92%E8%AA%AD%E3%82%80%EF%BC%88%E3%83%A1%E3%82%BF%E6%83%85%E5%A0%B1%E6%A7%8B%E7%AF%89%EF%BC%89)を参照してください。
managerは大雑把に言うとモデルに関する処理を取り仕切っているクラスです。

初回（INSERT）なのか更新（UPDATE）なのかで分岐しますが今回はINSERTなので、do_insertで行われている処理をしておきます。

```py
>>> objs = [question]
```

# INSERT SQLの表示

というわけで準備が整ったので、以下を実行するとSQLが表示されます。なお、managerの属性のmodelはModelインスタンスではなくModelクラスです。

```py
>>> from django.db.models import sql
>>> query = sql.InsertQuery(manager.model)
>>> query.insert_values(fields, objs)
>>> compiler = query.get_compiler(using=using)
>>> compiler.return_id = True
>>> compiler.as_sql()
[('INSERT INTO "polls_question" ("question_text", "pub_date") VALUES (%s, %s)', ["What's new?", '2017-07-24 13:35:55.856747'])]
```

これらのコードはModelクラスではなく、django.db.models.managerモジュールのManagerクラスに書かれています。というのは半分嘘で、Managerクラスは継承関係がめんどくさく、下記の処理（_insertメソッドの抜粋）はdjango.db.models.queryモジュールのQuerySetクラスにあります。

# おまけ

上記の処理を一度に行う関数を作りました。

```py:sql_dumper.py
from django.db import router
from django.db.models.fields import AutoField
from django.db.models import sql

def show_insert_sql(instance):
    cls = instance.__class__
    using = router.db_for_write(cls, instance=instance)
    meta = cls._meta
    fields = meta.local_concrete_fields
    fields = [f for f in fields if not isinstance(f, AutoField)]
    manager = cls._base_manager
    objs = [question]
    
    query = sql.InsertQuery(manager.model)
    query.insert_values(fields, objs)
    compiler = query.get_compiler(using=using)
    compiler.return_id = True
    return compiler.as_sql()
```
Montgomery Multiplication

# Montgomery Multiplication とは

* 大きな数同士の積やべき乗の剰余を計算機上で高速に求めることができるアルゴリズム
  * $ab \mod n, a^m \mod n$
  * ※ 条件： $n$ は3以上の奇数である必要がある
* 暗号分野では欠かせない

----

# Montgomery Multiplication 概略

演算する値を Montgomery Representation に変換し、
その上で計算した後に Montgomery Representation から元に戻す。

----

# アルゴリズム

$ab \mod n$ について

1. $r > n$ かつ、 $\gcd (r, n)$ な自然数$r$を選ぶ
2. $k = \frac{r(r^{-1} \mod n) - 1}{n}$ を求める
3. $\overline{a} = ar \mod n, \overline{b} = br \mod n$
4. $s = xk \mod r$
5. $t = x + sn$
6. $u = \frac{t}{r}$
7. $\overline{c} = if (u < c) then (u) else (c - n)$
8. $c = \overline{c}r^{-1} \mod n$

なるほど、わからん。

----

# 式だと分からないので、実際の値で計算

$x=43, y=56, n=97$ のときの$xy \mod n$を求める。

* nより大きく、互いに素となる数として、$r=100$を選ぶ
* a1) $\overline{x} = xr \mod n = 43 * 100 \mod 97 = 32$
* a2) $\overline{y} = yr \mod n = 56 * 100 \mod 97 = 71$
* b) $a := \overline{x} \overline{y} = 32 * 71 = 2272$
* c) $a := a + 24n = 4600$ （$a$が$r$ の倍数になるまで$n$を逐次足していく）
* d) $a := a / r = 4600 / 100 = 46$
  * ※ このとき、$a$ は $xy \mod r$ のMontgomery Representationである
* e) $a * r^{-1} \mod n = 46 * 85 \mod 97 = 80$

----

# 計算機上で高速化できる理由

$r$として2の累乗を選ぶと、a1), a2), d) の演算をビット演算にできる
※ この場合は10進だけどわかるよね？

* a1) $\overline{x} = xr \mod n = 43 * 100 \mod 97 = 32$
* a2) $\overline{y} = yr \mod n = 56 * 100 \mod 97 = 71$
* d) $a := a / r = 4600 / 100 = 46$

**整数の除算は非常に重い** ので、
d)で除算をせずに済むことで、計算コストを大幅に削減できる

言い換えれば、
これは **剰余を求める演算から除算を取り除くアルゴリズム** である。

----

# 参考

* https://www.nayuki.io/page/montgomery-reduction-algorithm
* https://alicebob.cryptoland.net/understanding-the-montgomery-reduction-algorithm/
* https://www.scwirq.com/index.php/2016/10/11/%E3%83%A2%E3%83%B3%E3%82%B4%E3%83%A1%E3%83%AA%E4%B9%97%E7%AE%97/
Ruby on Railsのルーティングについて

#はじめに
RubyOnRailsについてネットで色々調べてみたが、どれも記述がくどくてRailsの各要素の関連がよくわかりにくい
自分なりにRubyOnRailsのルーティングについて簡単にまとめてみた

#Railsのルーティング
##表形式でまとめる
Railsのルーティングにはつまるところ、
(要求,URL,コントローラーのクラス名,コントローラーのメソッド名,viewのフォルダ,viewのファイル名)
が必要ようだ
個人的にはルーティングは

要求|URI|コントローラーのクラス名|コントローラーのメソッド名  |viewのフォルダ|viewのファイル名|
|:-------:|:-----|:------------------|:-------------|:------------|:-------------|
(1)       |(2)　　|(3)                |(4)            |(5)              |(6)            |
のように表形式でまとめるほうが理解しやすいと思う
上記の表に従えば、routes.rbにGet要求のルーティングを記載したいとき、
  (1) '(2)', to: '(3)から_controlerを除外したもの#（4）'
の形式で記載すれば、ブラウザ上で
http://localhost:3000/(2)/
と入力すれば、(6)のViewが表示されることになる

##具体例
###Getの具体例
まずはGetの具体例を示す

要求|URI|コントローラーのクラス名|コントローラーのメソッド名|viewのフォルダ|viewのファイル名
|:-------:|:-----|:------------------|:-------------|:------------|:-------------|
get|nikkyuusan|sample_controller|sayhelloToNyukkyusan|sample|sayhelloToNyukkyusan.html.rb
の場合だと
routes.rbには
  get '/nikkyuusan/', to: 'sample#sayhelloToNyukkyusan'
の形式で記載すれば、ブラウザ上で
http://localhost:3000/nikkyuusan/
と入力すれば、sayhelloToNyukkyusan.html.rbの記述が表示されることになる

###postの具体例
次にPostの具体例を示す

要求|URI|コントローラーのクラス名|コントローラーのメソッド名|viewのフォルダ|viewのファイル名
|:-------:|:-----|:------------------|:-------------|:------------|:-------------|
post|nikkyuusanpost|sample_controller|sayhellopost|sample|sayhellopost.html.rb
の場合だと
routes.rbには
  post '/nikkyuusanpost/', to: 'sample#sayhellopost'
と記載する
そして、htmlファイルを例えば

```非同期.html
<!DOCTYPE html>
<html>
<script>
function doPost(){
    var req = new XMLHttpRequest();
    req.open('POST', 'http://localhost:3000/nikkyuusanpost/', true);
    req.setRequestHeader('content-type',
    'application/x-www-form-urlencoded;charset=UTF-8');
    req.send('name='+f('nikkyu'));
    req.onload =  r(req,
        function(){f('result').innerText=req.responseText ;});
}

function r(req,caller){
  return function (event){
    if (req.readyState === 4 && req.status === 200) 
      caller();
  };
}
function f(str){
    return document.getElementById(str);
}
</script>
<body>
<input type='text'id='nikkyu'><input type='button' onclick='doPost();'>
<div id='result'></div>
</html>
```
のように作成し、postメソッドを投げれば、画面上にHTMLのレスポンス内容が表示される

#規約でプログラムを縛る
上記の表を見ると
コントローラーのクラス名（の一部）→viewのフォルダ
コントローラーのメソッド名→viewのファイル名（の一部）
の対応付けさえ守っていれば、後はフレームワークで自動的にHTTPリクエストのルーティングをしてくれることが分かる。
プログラムの自由度は下がるが、その分、ロジックの記載がシンプルですむ。
この「規約を守ってプログラミングする」というのがRuby on Railsの大きな特徴でもあり、同時に足かせでもある。
設定ファイルでガチガチに定義を行うJavaのWebフレームワークとはこの部分で大きく思想が違っている
[iOSアプリ開発] 開発に必要なものいろいろ

iOSアプリの開発に必要なものいろいろ

#Apple ID
App StoreへのアクセスやApple Developer Programへの登録に必要になるので、[Apple IDを作成](https://appleid.apple.com/account)する

#Apple Developer Program
iCloud, APNsなどを利用するアプリの開発、ベータ版のダウンロードする場合は、
[Apple Developer Program](https://developer.apple.com/programs/jp/)登録する

# Xcode
[Mac App Store](https://itunes.apple.com/jp/app/xcode/id497799835?mt=12)からインストール、または、インストーラー(.xip)を[ダウンロード](https://developer.apple.com/download/more/)

# Java 8
インストーラー(.dmg)を[ダウンロード](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)

# Doxygen
インストーラー(.dmg)を[ダウンロード](http://www.stack.nl/~dimitri/doxygen/download.html)

# Homebrew
[Homebrew](https://brew.sh)

```
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

brew -v
```

#Gcovr
[Gcovr](http://gcovr.com)

```
curl -O https://bootstrap.pypa.io/get-pip.py
sudo python get-pip.py --proxy="proxy.example.com:8080"
sudo pip install gcovr
 
gcovr --version
```

# CocoaPods
[CocoaPods](https://cocoapods.org)

```
sudo gem install cocoapods
```
自分用メモ@PHPのPOSTとGETとか

#概要
phpでは外部からデータを受け取る際に、htmlのフォームから受け取れたりする。
その際に<code>$_POST</code>とか<code>$_GET</code>みたいな<font color="red">スーパーグローバル変数</font>を使う。
##$_POST変数
$\_POST変数の使い方はとても簡単で、以下に例を示す。<code>post.html</code>と<code>post.php</code>を用いる。

```html:post.html
<html>
  <body>
    <form action="post.php" method="post">
      <input type="text" name="postdata" /><br />
      <input type="subimit" name="submit" value="Send Data" />
    </form>
  </body>
</html> 
```
```php:post.php
<?php
  echo $_POST['postdata'];
?>
```

以上。<code>post.html</code>にアクセスし、formのtextboxに文字を入力してsubmitボタンを押すと<code>post.php</code>へとジャンプする。その際に、php側の<font color="green">$\_POST</font>変数に自動的にデータが代入される。
そのデータを用いる際には<code>$_POST['inputのname']</code>とすれば良い。
例えば、inputに"Hello, World"と入力すればphp側で"Hello, World"と出力される。
ちなみにこれで動く事は動くのだが、POSTデータは偽装できたりするのでそのままだとセキュリティ面でかなり危険。
どうしたらいいかは調べてください。私は機会があれば調べようと思います。
##$_GET
$_GET変数も使い方は簡単。これはURLで変数を指定する。
例えば、次のような<code>get.php</code>というphpプログラムを用いるとする。

```php:get.php
<?php
  echo "inputData -> ".htmlspecialchars($_GET['input_data']);
?>
```
アクセスする際のURLを<code>sample.com/get.php</code>とすると、<code>sample.com/get.php?input_data=inputString</code>と言った感じに末尾に<font color="red">?変数名=値</font>と入力してアクセスすると、<code>$_GET</code>変数に値が格納される。
上記の例だと、<code>$_GET['input_data']</code>に<code>inputString</code>という文字列が格納されることになる。
ちなみに、<code>htmlspecialchars</code>関数は、コードと読み取れてしまう特殊文字を変換してくれる関数。って認識でいいと思う。厳密には少し違うけど。
##まとめ
外部から入力を受け取る方法として、html経由とかになってしまうが、\$_GETとか$_POSTみたいなスーパーグローバル変数を使うと良い。
セキュリティ面では改ざんが容易だからかなり危ない。対策は調べれば出てきたはず。
でも、ローカルで回すだけなら正直気軽にさくっと扱えるから優秀だと思う。そもそもローカル以外でphp使いたくないと思うし割と関係ない・・・

今回は以上。前から言ってはなかったけど掲示板プログラムを組んでみたいと思っているのでそれに必要な知識を書き溜めています。あくまでも独学で知識を伸ばす事が目的なので意見は受け付けていません。
コメントは一応参考にはします。でも答えは勘弁してください。
[iOSアプリ開発] API Reference & Programming Guide & Sample Code

iOS開発者向けのAppleのドキュメント

#API Reference

[Apple Developer Documentation](https://developer.apple.com/documentation)

#Programing Gude & Sample Code

~~[Documentation Archive](https://developer.apple.com/library/content/navigation/)~~

~~[日本語ドキュメント](https://developer.apple.com/jp/documentation/)~~
~~※基本的に英語版の方が新しいので、最新の情報は英語版を参照。~~


[Apple Developer Documentation](https://developer.apple.com/documentation)
※こちらが最新になったようです。

#Guidelines
AppleのAppStoreで開発したアプリを公開する際には、Appleの審査があり、以下のガイドラインに準拠する必要があります。ガイドラインは審査にパスする為だけでなく、ユーザーが使いやすいUI/UXを実現する為にも、理解しておくことは重要です。

[アプリケーション審査ガイドライン](https://developer.apple.com/app-store/review/jp/)

[App Store審査ガイドライン](https://developer.apple.com/app-store/review/guidelines/jp/)

[iOS Human Interface Guidelines](https://developer.apple.com/ios/human-interface-guidelines/overview/design-principles/)
Rails5.1on Ubuntu16.04の開発環境を手っ取り早く用意する(enpit2017用)

# はじめに
enPiTのPBL基礎で使う開発環境を手っ取り早く用意するための手順です。
minajunが書いてくれた開発環境構築手順
http://qiita.com/Minajun/items/e58d95bdbb9b05e46e65
の仮想マシン上でのインストール作業を全部やった仮想マシンをクラウドに
おいたのでこれを使います。

## 仮想環境構築の手順
1. Virtualboxをインストールする
　　https://www.virtualbox.org/wiki/Downloads 

2. Vagrantをインストールする
    https://www.vagrantup.com/downloads.html

3. ターミナルを立ち上げて作業用ディレクトリを作る

    ```command:ディレクトリを作る
% mkdir 作業用ディレクトリ 
% cd 作業用ディレクトリ
    ```

4. 仮想マシンを取得する
    仮想マシンファイルをクラウドから取ってくる場合と、USBメモリ等でローカルの仮想マシンファイルを使う場合と二つの場合を書いておきます。enPiTの教室でみんながクラウドから巨大なファイルを
ダウンロードするのは大変だと思いますので、適宜使い分けてください。
    * （その１） クラウドから仮想マシンファイルを取ってくる場合
        * ファイルVagrantfileを作成する    

            ``` txt:Vagrantfile
      Vagrant.configure("2") do |config|
        config.vm.box = "chiemi627/ubuntu16.04_rails5.1"
        config.vm.network "forwarded_port", guest: 3000, host: 3000
        config.vm.synced_folder "workspace", "/home/vagrant/workspace"
      end    
            ```
    * （その２） USBメモリ等でローカルの仮想マシンファイルを使う場合
        * (仮想マシンファイルのパスを /home/hoge/package.box とします)
        * 仮想マシンファイルをvagrantのboxリストに追加する
    
            ```command:boxリストに追加する
            % vagrant box add ubuntu16.04_rails5.1 /home/hoge/package.box
            % vagrant init ubuntu16.04_rails5.1
            ```
       * ファイルVagrantfileを書き換える
       
            ``` txt:Vagrantfile
            Vagrant.configure("2") do |config|
               config.vm.box = "ubuntu16.04_rails5.1"
               config.vm.box_version = "0.1"
               config.vm.network "forwarded_port", guest: 3000, host: 3000
               config.vm.synced_folder "workspace", "/home/vagrant/workspace"
            end    
            ```

5. ゲストOSとで同期するディレクトリを作成する

    ```command:同期するディレクトリを作る
    % mkdir workspace
    ```

6. ゲストOSを立ち上げる

    ```command:ゲストOSを立ち上げる
    % vagrant up
    ```
これで終わりです

## 作成した仮想マシンでrailsを動かす

1. sshでゲストOSに入る


    ```command:ゲストOSに入る
    % vagrant ssh
    ```
   vagrantアカウントでログインされます。
  
2. railsアプリケーションを作成する

    ```command:ゲストOS内でrailsアプリケーションを実行する
    > rails new hello_app
    ```
3. railsサーバを立ち上げる

    ```command:ゲストOS内でrailsアプリケーションを実行する
    > cd hello_app
    > rails s
    ```
4. ホストOSのブラウザでhttp://localhost:3000 を開く
【AndroidStudio】よく使うショートカット01(インデント整形、インポート整理)

AndroidStudioでの便利な機能について

■インデントの整形（修正）

```
Option (⌥ オプション) + Command (⌘ コマンド) + l(エルキー)
```

■インポート整理（不要なインポートの削除）

```
Ctrl　+ Alt + o(オーキー)
```
拡張命令セットでTensorFlowをコンパイルする方法

macOSで構築したPython環境でTensorFlowのチュートリアルのサンプルを実行したら、以下のワーニングメッセージが表示しました。

```
2017-07-23 23:59:04.998330: W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE4.2 instructions, but these are available on your machine and could speed up CPU computations.
2017-07-23 23:59:04.998353: W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use AVX instructions, but these are available on your machine and could speed up CPU computations.
2017-07-23 23:59:04.998361: W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use AVX2 instructions, but these are available on your machine and could speed up CPU computations.
2017-07-23 23:59:04.998369: W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use FMA instructions, but these are available on your machine and could speed up CPU computations.
```
「TensorFlowはSSE4.2, AVX, AVX2, FMAでコンパイルされていないが、このマシンならこれらにより加速することができる。」ということらしいです。

## SSE4.2, AVX, AVX2, FMAって何？
調べてみれば、これらはINTELが開発したCPUの拡張命令セットです。これらの拡張命令は結構前の世代からサポートされてきたみたいですが、初めて知りました。拡張命令セットの内容はよくわからないが、これらでTensorFlowのライブラリをコンパイルすれば実行時間を短縮できるらしいので、やり方を調べ、ここにメモを残しておきます。

参考:
https://stackoverflow.com/questions/41293077/how-to-compile-tensorflow-with-sse4-2-and-avx-instructions

## Python仮想環境管理のためのcondaインストール
以下のところでanacondaをダウンロードし、インストールします。anacondaはPythonで開発するためのパッケージは最初からいろいろ入っているので、anacondaでPythonをインストールし直しました。

https://www.continuum.io/downloads

参考
https://gist.github.com/aphlysia/d5fcee79ff81b8272faf

## HomebrewでBazelをインストール
Bazelとは、Googleが開発したビルドツールです。makeのようなものです。
まだBazelのいいところわからないから、これから勉強したいです。
とりあえずここでインストールして使用していきます。

```
brew install bazel
```

## TensorFlowのソースコードをgit cloneで取得
普通は、pip install tensorflowでTensorFlowのライブラリをPythonにインストールできますが、そうしたら冒頭のあのワーニングメッセージが表示されます。その為、ここは敢えてソースコードをダウンロードして、拡張命令セットを使用するように設定してライブラリをビルドして、インストールします。

```
git clone https://github.com/tensorflow/tensorflow
```

## コンフィグレーション & コンパイル
### コンフィグレーション
対話式で、コンパイル設定を行う。ここでとりあえず全部デフォルトで最後までENTER切っていいです。

```
cd tensorflow
./configure
```
#### コンパイル
以下の命令を実行すればコンパイル開始。自分のマシンにサポートされる拡張命令セットを一つずつ"--copt="の後ろに付けて、コンパイル実行。マシンの性能によりますが、自分のマシン（Core i5-4285U 2.4GHz）は40分ぐらい時間かかりました。

```
bazel build -c opt --copt=-mavx --copt=-mavx2 --copt=-mfma --copt=-msse4.1 --copt=-msse4.2  -k //tensorflow/tools/pip_package:build_pip_package
```

## 配布パッケージ作成
コンパイル完了後、インストールするためのパッケージを作成します。

```
bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
```
パッケージは /tmp/tensorflow_pkg に生成されます。

## condaでPython仮想環境作成
仮想環境を使わずに直接pip installでPythonにライブラリ追加してもいいですが、使用する目的によって環境を分けたほうがいいと思うので、仮想環境内で拡張命令セットでコンパイルしたライブラリをインストールすることにしました。

```
conda create -n tensorflow python=3.6 anaconda
```
-nの後ろは{仮想環境名}

## 仮想環境に切り替え
```
source activate tensorflow
```

## 仮想環境内でコンパイルしたパッケージをインストール
```
pip install /tmp/tensorflow_pkg/{パッケージ名}.whl
```
インストール完了後もう一度冒頭のサンプルを実行したらワーニングメッセージが出なくなりました。

## まとめ
拡張命令セットでコンパイルしたライブラリがインストールされた仮想環境でもう一度、TensorFlowのサンプルを実行したら、ワーニングメッセージが出てこなくなりまりました。簡単なサンプルなので、結局、あまり「速くなった」という感じはしませんでした。また後日複雑なもので比較してみたいと思います。
MACで小文字のUUIDを生成する

# 小文字のUUID
デフォルトのUUID(uuidgenコマンド)は大文字。
tr コマンドで小文字のUUIDを小文字に変換します。

```
$ uuidgen | tr [:upper:] [:lower:]
695aa125-0d92-403b-ae42-23eecac21663
```
入門: golangでAndroid用のライブラリ(aar)を書く

# golangでAndroid用のライブラリ(aar)を書く

golangでAndroid用のライブラリ(aar)が作れるのですが、公式サイト( https://github.com/golang/go/wiki/Mobile )じゃいまいちわからなかったのでざっくりとまとめます。

**gomobileは現時点でexperimental(実験的）です。自己責任で手を出しましょう。**

## やった環境

Ubuntu 16.04 Server
ほかは知らない。大体一緒だと思う。

## 必要なもの

* Android SDK
* Android NDK
* golang 1.7以上

これらのインストール方法がわからない人はこの先を見ても分からないと思います。あなたには他に知らなければならないことがあるはずです。

## ざっくりとしたやり方（本編）

環境変数はこれくらい

```
GOROOT=/path/to/goroot
GOPATH=~/go
PATH=$PATH:~/go/bin
ANDROID_HOME=~/android-sdk-linux
```

まず、`gomobile`をインストールしましょう。

```
go get golang.org/x/mobile/cmd/gomobile
```

`gomobile`の初期化をします。私の環境ではここが公式サイトと違うところでした。`-ndk`でNDKへのパスを指定しないとダメだった。

```
gomobile init -ndk /path/to/android/ndk
```

あとは適当にgolangでライブラリを作って、ビルドするだけ。

* $GOPATH/src/github.com/foo/libhello/hello.go

 ```go
package hello

func HelloWorld() string {
  return "Hello World"
}
```

ポイントはパッケージ名。mainパッケージではダメです。
複数ファイルを作ってもいいけど、package名は同じにしないとダメです。

ライブラリを書いたらビルドしましょう。

```
gomobile bind -target android
```

これで`hello.aar`が生成されました。あとは適当にandroid側でつかうと良いでしょう。

使うときはこんな感じになるっぽいよ。

```java

import hello.hello;

class Foo {
    void Bar() {
        String text = hello.helloWorld();
    }
}
```

`hello.hello`はせめて`libhello.hello`であってほしいと思うのは私だけじゃないと信じたい。
node(electron)でwebm配信を作ってみました。その１

# 概要

配信ツールをelectronを使えば簡単につくれるのでは？と思ってたのでtakcastというツールを作ってみました。

まぁ、こんな感じです。
動作するデモはこんな感じ

https://taktod.github.io/takcast/src/html/main.html

html5でもある程度動作します。

![スクリーンショット 2017-07-24 21.05.41.png](https://qiita-image-store.s3.amazonaws.com/0/6246/087a485a-4bee-d812-67a9-632f698f93ca.png)

electronでの動作のスクリーンショットはこんな感じ。

## 必要なもの

node v7.10.0
npm 4.2.0
を使っています。

```
$ git clone git@github.com:taktod/takcast
$ cd takcast
$ npm install
$ npm run setup
$ npm test
```

これで起動できます。
rtmpはないのか？
という人には、別のpluginでrtmp出力ができるものを一応用意してありますので
takcastのディレクトリ内で

```
$ npm install --save taktod/takcast.output.rtmp
$ npm run setup
$ npm test
```

と実行してもらえれば、rtmp出力のpluginが入って配信できるようになるはずです。

## 目標

javascriptを使うことで、なるべく簡単にいろんな人が映像の動作に触れるようになればいいなと考えています。
なので、それぞれの動作をいくつかのpluginに分解してプログラム組んでみました。
いろんな人がforkしたり、pluginをつくって、機能拡張したりして楽しんでくれればうれしいなと思います。

ま、このプログラム自体は3月の終わりにつくったわけですが・・・

# 今回いじろうと思ったきっかけというか、今回やりたいこと

http://apiv2-doc.twitcasting.tv/#get-webm-url
ずばり、これです。
ツイキャスがwebmでの配信サポートしてるっぽいんですよね。

どうやらwebsocketでwebmのデータを投げてやれば、それで配信できるみたいです。
ということはサーバーをchromeやfirefoxだったら、ブラウザだけで配信ができるっぽい。

配信可能なことはわかっていて
http://qiita.com/taktod/items/24e59c4790ed8ac20cc1

こちらの記事にかきましたが、webmを受け取って解析してやれば、如何様にでも処理できるみたいです。
すばらしい・・・この方式が広まってくれれば・・・と思っています。

## で、つくってみた結果

しくじりました。
githubのpageとしてアクセス可能にした初めのデモですが、httpsでアクセスできるところにあるため
wssでwebsocketを接続しないとだめみたいですね。
(前の記事のでも、よく考えたらwssでないと配信できませんね :sweat: )

そしてテスト動作として自分が準備したgoのプログラムだとwsしかサポートしていない・・・
という点でしくじりました。

余裕があれば、golangのプログラムでhttpsをサポートしたサーバーを書くか、nodeでもつかってhttpsをサポートしたサーバー書くかしたいところですね。

一応この記事はその１としてみました。
https可能なサーバーでも書いたらその２とか書きたいです。

# webm + websocketによる配信が広まったらいいな

と思ってます。
fswebcamのエラー回避策

#fswebcam

fswebcamは簡単にコマンドラインからUVCカメラのキャプチャができて便利なツールです。
```
fswebcam tst.jpg
```
とすると静止画をキャプチャしてファイルに落としてくれます。便利。

しかし、、

```
fswebcam foo.jpg  
--- Opening /dev/video0...
Trying source module v4l2...
/dev/video0 opened.
No input was specified, using the first.
Adjusting resolution from 384x288 to 320x240.
--- Capturing frame...
GD Error: gd-jpeg: JPEG library reports unrecoverable error: Not a JPEG file: starts with 0x08 0x0aCaptured frame in 0.00 seconds.
--- Processing captured image...
Writing JPEG image to 'foo.jpg'.
```
こんな感じで出力ファイルが破損していることが環境により起こりました。Ubuntu16.04で確認。

#対応
```
fswebcam tst.jpg -D 1
```
-Dオプションで撮影までの待ち時間(秒)を指定できます。待ち時間を入れてあげると回避できました。初期化が間に合わないといったことが起こっているんでしょうか。。

#参考リンク
PythonでBMI指数を測定する。

手探りでBMI指数を計測するアプリ?プログラム?を作りました。

未入力の箇所(特に身長・体重)があるとエラーになってしまいます。

というわけでまだ未完成です、すみません。

```py
# coding: utf-8

class bodyData:
    uName = ''
    uSex = 0
    uAge = 0
    uHeight = 0
    uWeight = 0
    uBmi = 0

    def __init__(self, uName = '中村', uSex = 0, uAge = 26):
        self.uName = uName
        self.uSex = uSex
        self.uAge = uAge

        print('これより氏名: ' + str(self.uName))
        #'性別: ' + str(self.uSex))
        if (self.uSex == '0'):
            print('性別: 男性')
        elif (uSex == '1'):
            print('性別: 女性')
        else:
            print('性別: わかりません!!')
        print('年齢: ' + str(self.uAge) + '\n' +
        'のBMI指数を計測します。')

    def set_bodyData(self, uHeight, uWeight):
        self.uHeight = uHeight
        self.uWeight = uWeight

    def result_bodyData(self, uBmi):
        self.uBmi = uBmi

        print('結果をおしらせします。' + '\n' +
        '氏名: ' + (self.uName))
        if (self.uSex == '0'):
            print('性別: 男性')
        elif (self.uSex == '1'):
            print('性別: 女性')
        else:
            print('性別がわかりません!!')
        print('年齢: ' + str(self.uAge) + '\n' +
        '身長: ' + str(self.uHeight) + 'cm' + '\n' +
        '体重: ' + str(self.uWeight) + 'kg' + '\n' +
        '以上の者のBMI指数は...' + '\n' +
        '\n' +
        str(round(self.uBmi,1)) + '\n')

    def result_Bmi (self):
        if (self.uBmi < 18.5):
            print('痩せすぎです。' + '\n' +
            '太りましょう。')
        elif (18.5 < self.uBmi < 25):
            print('適正体重です。' + '\n' +
            'このまま維持していきましょう。')
        elif (25 < self.uBmi < 30):
            print('太りはじめています。' + '\n' +
            '気にしましょ。')
        elif (30 < self.uBmi < 35):
            print('太っています。' + '\n' +
            '自覚しましょ。')
        elif (35 < self.uBmi < 40):
            print('気づかないですか?' + '\n' +
            'あなたは太っています。')
        elif (self.uBmi >= 40):
            print('大変ですよ。')
        else:
            print('どっかで入力が間違っています。' + '\n' +
            'ごめんなさいね。')

uName = input('名前を入力してください。' + '\n' +
'=> ')
uSex = input('性別を入力してください。0 = 男性、 1 = 女性' + '\n' +
'=> ')
uAge = input('年齢を入力してください。' + '\n' +
'=> ')

bd = bodyData(uName, uSex, uAge)

uHeight = input('身長をcmで入力してください。' + '\n' +
'=> ')
uWeight = input('体重をkgで入力してください。' + '\n' +
'=> ')

bd.set_bodyData(uHeight, uWeight)

uBmi = int(uWeight) / ((int(uHeight) / 100) ** 2)

bd.result_bodyData(uBmi)

bd.result_Bmi()
```

以上です。
組合せ最適化で鯨を見に行く

# これなに
あなたは、夏休みに鯨を見に行くことになりました。[組合せ最適化](http://qiita.com/SaitoTsutomu/items/bfbf4c185ed7004b5721)を使って、8か所のポイントのどこを選べばよいか考えてみましょう。

```py3:pythonでポイント情報の表示
import numpy as np, pandas as pd
from pulp import *
from ortoolpy import addbinvars
n = 8 # ポイント数
np.random.seed(639)
df = pd.DataFrame(np.random.rand(n,2).round(2)*[0.2,100], columns=['Prob','Time'])
df.insert(0,'Place', [chr(i+65) for i in range(n)])
print(df)
```

<table>
  <thead>
    <tr>
      <th></th>
      <th>Place</th>
      <th>Prob</th>
      <th>Time</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>A</td>
      <td>0.082</td>
      <td>57.0</td>
    </tr>
    <tr>
      <th>1</th>
      <td>B</td>
      <td>0.182</td>
      <td>93.0</td>
    </tr>
    <tr>
      <th>2</th>
      <td>C</td>
      <td>0.184</td>
      <td>89.0</td>
    </tr>
    <tr>
      <th>3</th>
      <td>D</td>
      <td>0.108</td>
      <td>51.0</td>
    </tr>
    <tr>
      <th>4</th>
      <td>E</td>
      <td>0.104</td>
      <td>5.0</td>
    </tr>
    <tr>
      <th>5</th>
      <td>F</td>
      <td>0.152</td>
      <td>83.0</td>
    </tr>
    <tr>
      <th>6</th>
      <td>G</td>
      <td>0.178</td>
      <td>83.0</td>
    </tr>
    <tr>
      <th>7</th>
      <td>H</td>
      <td>0.156</td>
      <td>16.0</td>
    </tr>
  </tbody>
</table>

Placeがポイントの**名称**を、Probが鯨を見れる**確率**を、Timeがポイントへの移動と観測にかかる**時間**(分)を表しています。

# 問題その1

> 総時間 **140分**以内で**確率の和**を最大化せよ

## 答えその1
[ナップサック問題](http://qiita.com/SaitoTsutomu/items/d3c07494e7ba992bf19d)になりますので、ササっと解いてみましょう。

```py3:python
m = LpProblem(sense=LpMaximize)
df['Var'] = addbinvars(n)
m += lpDot(df.Prob,df.Var)
m += lpDot(df.Time,df.Var) <= 140
m.solve()
df['Val'] = df.Var.apply(value)
print('%s found. Ave prob. = %.3f, Any prob. = %.3f'%(LpStatus[m.status],
      df[df.Val>0].Prob.sum(), 1-(1-df[df.Val>0].Prob).prod()))
print(df[df.Val>0])
```

```text:結果
Optimal found. Ave prob. = 0.450, Any prob. = 0.381
  Place   Prob  Time    Var  Val
0     A  0.082  57.0  v0001  1.0
3     D  0.108  51.0  v0004  1.0
4     E  0.104   5.0  v0005  1.0
7     H  0.156  16.0  v0008  1.0
```

鯨を見れる回数の期待値は、0.45回になりました。でも、1回以上見れる確率は0.381です。

# 問題その2

> 総時間 **140分**以内で**1回以上見れる確率**を最大化せよ

## 答えその2

1回も見れない確率は、$\prod_i{(1- Prob_i)}$ です。このままでは、非線形ですが、(単調関数である)$\log$を使って線形化しましょう。

```py3:python
m = LpProblem(sense=LpMaximize)
df['Var'] = addbinvars(n)
m += -lpDot(np.log(1-df.Prob),df.Var)
m += lpDot(df.Time,df.Var) <= 140
m.solve()
df['Val'] = df.Var.apply(value)
print('%s found. Ave prob. = %.3f, Any prob. = %.3f'%(LpStatus[m.status],
      df[df.Val>0].Prob.sum(), 1-(1-df[df.Val>0].Prob).prod()))
print(df[df.Val>0])
```

```text:結果
Optimal found. Ave prob. = 0.444, Any prob. = 0.383
  Place   Prob  Time    Var  Val
2     C  0.184  89.0  v0011  1.0
4     E  0.104   5.0  v0013  1.0
7     H  0.156  16.0  v0016  1.0
```

1回以上見れる確率が、0.381から0.383にちょっと増えました。

以上
Windows 10の表示言語の切り替えができないとき

Windows 10の表示言語を切り替える必要があった場合、
最近のWindows 10では、設定からの切り替えができません。(入力言語の切り替えは成功します)

その場合、コントロールパネルの言語設定を見ると、言語パックのインストールができるようになります。
merge commitをcherry-pickしようとしたら門前払いされた

# tl;dr
conflictがあるとcherry-pickはできない

#背景
前年と同様のイベントを開催することになったので、1年前のソースコードを復活させて使いまわしたい。
関連するブランチのマージコミットをごっそり持ってきちゃえないか、という話になったのでトライ。

#トライ
cherry-pickを初めて使ったので公式ページ見て把握。
https://git-scm.com/docs/git-cherry-pick

以下、cherry-pickしたいマージコミットのハッシュ値を`9ef7ae9`とする。

```bash
$ git cherry-pick 9ef7ae9
error: commit 9ef7ae91f7c2fabb54633c5b7646c2c027bbb5f4 is a merge but no -m option was given.
fatal: cherry-pick failed
https://git-scm.com/docs/git-cherry-pick#git-cherry-pick--mparent-number
```

マージコミットは親が2ついるから、どちらの親を辿るのかわからないよーと怒られたので、`-m`オプションをつけて、追ってほしいブランチの一つ前のコミットのハッシュ値`e6ead5f`を指定。

```bash
$ git cherry-pick -m e6ead5f 9ef7ae9
error: switch 'm' expects a numerical value
usage: git cherry-pick [<options>] <commit-ish>...
```
`-m`オプションの後に指定するのはコミットのハッシュ値ではないようだ。
公式ページに戻って[`-m`オプションの説明ページ](https://git-scm.com/docs/git-cherry-pick#git-cherry-pick--mparent-number)を読む。
いや、parent numberの調べかたこのページに載ってないんかい。

困ったときのstack overflow。ジャストミートなトピックが高確率である。
https://stackoverflow.com/questions/7211092/how-do-i-find-out-the-numbering-of-merge-commit-parents

`git rev-parse`コマンドで、あるコミットのある親番号のコミットハッシュ値を取得。

```bash
$ git rev-parse 9ef7ae9^1 #親番号1
7e7975d876af44cf92c2368b5b45060ac5304046

$ git rev-parse 9ef7ae9^2 #親番号2
e6ead5ffacc3ac96b887a1d6a90a7eb13485e734
```
今回は親番号2番が追いたいブランチのコミットだったので、`-m`オプションの後ろには2番を指定。

```bash
$ git cherry-pick -m 2 9ef7ae9
On branch feature/hogehoge
You are currently cherry-picking commit 9ef7ae91f7.

nothing to commit, working tree clean
The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:

    git commit --allow-empty

Otherwise, please use 'git reset'
```


```bash
$ git st
On branch feature/hogehoge
You are currently cherry-picking commit 9ef7ae91f7.
  (all conflicts fixed: run "git cherry-pick --continue")
  (use "git cherry-pick --abort" to cancel the cherry-pick operation)

nothing to commit, working tree clean
```

conflict直さないとcommitデキナイヨー
conflict全部直した後`git cherry-pick --continue`シテネー
とのお告げ

・・・merge時のconflict修正っぽくできないの？
conflictしない状態にしてからcherry-pickしろよーって感じ？
おととい来やがれクソヤロー的な？

https://stackoverflow.com/questions/19830464/git-cherry-pick-and-conflicts
どうやらconflictがない状態じゃないとcherry-pickはできないらしい。

そもそもcherry-pickは同時並行で開発が進んでいるブランチ間で、特定のコミットのみ取り出したいという場合に用いるもので、
1年も前で、そこからかなり変更が加えられた大量のファイルを取ってくるのは間違った使い方なのかもしれない。

つらみ。

#結論
conflictがあるとcherry-pickはできない。

#参考
どうにかconflictしててもcherry-pickできて、あとでconflictをまとめて修正（merge時のconflictのように）できないか、と調べたところ、
https://stackoverflow.com/questions/19830464/git-cherry-pick-and-conflicts
`meld`というmergeツールをlinuxに導入してgitと連動させると、できるっぽい。
今回はここまでせず、違う方法で昔のソースコードを使いまわすことを考えた。