OmniAICreator/Qiita-1.07M huggingface dataset:
Windows版TensorFlowのインストールメモ

公式サイトの「[Installing TensorFlow on Windows](https://www.tensorflow.org/install/install_windows)」を参考にしつつ、自分の環境にインストールを行った内容を記録しておきます。

・OS：Windows 7 Professional Service Pack 1 64bit
・GPU：NVIDIA GeForce GTX 650
　→compute capabilityが「3.0」なので、いろいろと危険

#CUDA等のインストール
実はこちらは既にインストール済みであったため、わざわざこのためにインストールしませんでした。
とりあえずインストール済みのモジュールのメモ。
・[CUDA 8.0](https://developer.nvidia.com/cuda-downloads)
・[cuDNN 5.1](https://developer.nvidia.com/rdp/cudnn-download)
　※ログインが必要

#Pythonのインストール
すでに、Python 3.6（32bit版）が入っていたが、Python 3.5（64bit版）ではないとダメだということで、[ここ](https://www.python.org/downloads/release/python-350/)からインストールしました。
（3.5（32bit版）、および、3.6（32bit版、64bit版）でエラーになるのは確認済み）

その後、TensorFlowをインストールしようとすると、「Pipが古いよ」といわれるので更新しました。

```
Python -m pip install --upgrade pip
```

#TensorFlowのインストール
ようやくTensorFlowのインストールです。
Pipを使用します。

```
pip3 install --upgrade tensorflow-gpu
```

GPU版をインストールしました。

#ハマったこと（ハマっていること）
・環境変数「PATH」が長すぎて、CUDA/cuDNNのパスが追加できなかった
　→TensorFlowのimport時にエラーが表示されます

・実行ログが表示される

```
I c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\core\common_runtime\gpu\gpu_device.cc:885] Found device 0 with properties:
name: GeForce GTX 650
major: 3 minor: 0 memoryClockRate (GHz) 1.0585
pciBusID 0000:01:00.0
Total memory: 1.00GiB
Free memory: 190.88MiB
```
　→未解決
　　→そういうもの？

・エラーが表示される（実行はされている）

```
E c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\core\framework\op_kernel.cc:943] OpKernel ('op: "BestSplits" device_type: "CPU"') for unknown op: BestSplits
E c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\core\framework\op_kernel.cc:943] OpKernel ('op: "CountExtremelyRandomStats" device_type: "CPU"') for unknown op: CountExtremelyRandomStats
E c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\core\framework\op_kernel.cc:943] OpKernel ('op: "FinishedNodes" device_type: "CPU"') for unknown op: FinishedNodes
E c:\tf_jenkins\home\workspace\release-win\device\gpu\os\windows\tensorflow\core\framework\op_kernel.cc:943] OpKernel ('op: "GrowTree" device_type: "CPU"') for unknown op: GrowTree
...
```

　→未解決（[こちら](https://github.com/tensorflow/tensorflow/issues/7500)を確認中）
　　→CPU版は直っているが、GPU版はまだ？

★その後、pipで持ってくるTensorFlowが最新ではないことが判明
★最新のwhlを[ここ](http://ci.tensorflow.org/job/tensorflow-master-win-cmake-py/)から持ってきて、そのファイルをpipすることで、上記エラー等はなくなる

```
pip3 install tensorflow-1.0.0-cp35-cp35m-win_amd64.whl
```

#その他
チュートリアルとか欲しくなるので、GitHubから[ソース一式](https://github.com/tensorflow/tensorflow)持ってきておいた方がよい。
JAVA:jar, aar, ファイルの中身を見る

１）このツールをダウンロードして、Buildしてください。
https://github.com/leilu/jd-gui
２）その後に　build/libs/jd-gui-x.y.z.jar　を開いてください。
３）aar  jar ファイルをそのまま開けます。


経緯
Unity3D　Android　Buildする時に、重複libがある時に、一番オススメな調査方法です。
PhaserをWebPackで使うときのwebpack.config.js

Webpack+Phaserで作ろうと思って、
https://github.com/lean/phaser-es6-webpack
を参考に、とりあえず、できる限りの最小で書いていますので、
上記URLにあるようなBrowserSyncの設定とかは入っていませんので、
適宜設定していただければと思います。
ファイル構成は、

dist（書き出し用)、src（ソース用）のファイルだけ、作ってもらえればと思います。

```package.json
{
  "devDependencies": {
    "babel-cli": "^6.23.0",
    "babel-core": "^6.23.1",
    "babel-loader": "^6.3.2",
    "babel-preset-es2015": "^6.22.0",
    "expose-loader": "^0.7.3",
    "phaser-ce": "^2.7.3",
    "webpack": "^2.2.1"
  }
}
```


```webpack.config.js
//pathに関するいろいろができるものです。
var path = require('path');
//ローカルインストールじゃないと動かない気がする
//グローバルでも動かす方法教えてください
var webpack = require('webpack');

//ここらへんは、Phaser-ceのnpmのページに書いてるのと、ほぼ一緒。
//ただ、
//path.join(__dirname, '/node_modules/phaser/');
//こうなってる。phaser-ceでしょっていう
var phaserModule = path.join(__dirname, '/node_modules/phaser-ce/');
var phaser = path.join(phaserModule, 'build/custom/phaser-split.js');
var pixi = path.join(phaserModule, 'build/custom/pixi.js');
var p2 = path.join(phaserModule, 'build/custom/p2.js');

module.exports = {
  entry: {
    app: [
      'babel-polyfill',
      path.resolve(__dirname, 'src/main.js')
    ],
    vendor: ['pixi', 'p2', 'phaser']
  },
  module: {
    loaders:[
      { test:/\.js$/,
        loader: 'babel-loader',
        include: path.join(__dirname, 'src') ,
        //.babelrcに書く場合は不要
        query:{presets: ['es2015']}
      },
      { test: /pixi\.js/,
        loader: 'expose-loader?PIXI'
      },
      { test: /phaser-split\.js$/, loader: 'expose-loader?Phaser' },
      { test: /p2\.js/, loader: 'expose-loader?p2' }
    ]
  },
  output:{
    filename: './dist/[name].js'
  },
  //これは入れないと動かなかった。よくわかってない
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({name:"vendor", filenam:"vendor.bundle.js"})
  ],
  //ここもnpmのページに書いてあるとおり
  resolve: {
        alias: {
            'phaser': phaser,
            'pixi': pixi,
            'p2': p2,
        }
  }
}
```
macOS Sierra で sudo -ufoo brew したい

# 前提

筆者の PC のスペック。

*   OS: macOS Sierra
*   ユーザーアカウント: 以下の2つ
    *   管理者 (以下 admin) ※ root とは別物
    *   通常使用 (以下 myuser)
*   Homebrew: Yosemite 時代にインストールした(と記憶している)ものを使い続けてます

Homebrew 使用時だけ、通常使用アカウントのターミナルから `sudo -uadmin brew` などとして使用していました。

----

# 悩み事

Sierra にアップグレードして久しいある日、 `brew install` しようとしたら以下のエラーが発生しました。

```bash
$ sudo -uadmin brew install bar
Error: Permission denied - /Users/myuser/Library 
```

エラー文でググっても有力な情報が見つからなかったので formulae をメモって再インストール。

```bash:note-formulae
brew list > ~/Desktop/formulae.txt
```

```bash:reinstall
sudo -uadmin ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"
sudo -uadmin ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

(※最新のインストールコマンドは[公式](http://brew.sh/)を参照)

アンインストールはうまくいったっぽいのですが、(再)インストール時に以下のようなエラーが出て失敗してしまいました。

```
warning: unable to access '/Users/myuser/.config/git/attributes': Permission denied 
```

----

# 原因

ググって出てきた情報を改めてじっくり眺めていたら、以下の記事が参考になりました。

http://stackoverflow.com/a/27151021/7509299

どうやら `sudo` するときに環境変数 `$HOME` が元のユーザーのままだったのがいけなかったらしいです。
`sudo` するときに `$HOME` の定義が元のままだと、 admin ユーザーの権限で myuser のホームディレクトリを参照しちゃうってことですね。

```bash
$ echo 'echo $HOME' | sudo -uadmin bash
/Users/myuser
```

----

# 解決方法

なんとかする方法ないかと `man sudo` して 'HOME' を検索…っと、ありました!

(以下 `man 8 sudo` から引用)

> <dl><dt>-H, --set-home</dt><dd>Request that the security policy set the HOME environment variable to the home directory specified by the target user's password database entry.  Depending on the policy, this may be the default behavior.</dd></dl>

つまりはこういうこと


```bash
$ echo 'echo $HOME' | sudo -uadmin bash
/Users/myuser
$ echo 'echo $HOME' | sudo -H -uadmin bash
/Users/admin
```

というわけで brew するとき以下のようにしたらちゃんと動きました。

```bash:install
sudo -H -uadmin ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

(※最新のインストールコマンドは[公式](http://brew.sh/)を参照)

```bash:use
sudo -H -uadmin brew doctor
```
pyenv-virtualenvの使い方

はじめに
--------------------

めもです。

参考：[pyenvのインストールと簡単な使い方 - Weekly Report](http://arairyoya.hatenablog.jp/entry/2015/01/24/031158)

使い方
--------------------

### pyenv

```shell-session
$ pyenv version # 現在のバージョンの確認
$ pyenv versions # インストールされているバージョンの確認
$ pyenv install 3.4.5 # version 3.4.5 をインストール
$ pyenv local 3.4.5 # 現在位置で 3.4.5 を使う
$ pyenv global 3.4.5 # デフォルトを 3.4.5 に変更
```

### pyenv-virtualenv

```shell-session
$ pyenv virsions # バージョンを確認
$ pyenv virtualenv 3.4.5 virtualenv-name # 3.4.5 から 仮想環境 virtualenv-name を作成
$ pyenv local virtualenv-name # 現在位置で virtualenv-name を使う
$ pyenv uninstall virtualenv-name # 削除
```
SQLite【自分用】


##接続
```
$ sqlite3 db/development.sqlite3
```
##テーブル一覧

```
sqlite> .tables
```
##テーブル定義参照
```
sqlite> .schema table1
```
##SQL文はそのまま打つだけ
```
sqlite> select * from table1;
```
##対話ではなくコマンドからSQLを入力したい場合（バッチとかで使うとき）
```
$ sqlite3 db/development.sqlite3 "select id, login from users;"
```
##新しいDB作るとき
```
$ sqlite3 page.sqlite3
sqlite> create table tasks (id integer primary key, title string, body string);
sqlite> .quit
```
ansible playbook開発時にgitにコミットする前にSyntax Errorをチェックする

# 概要

ansibleのplaybookを書いてリポジトリにcommit、pushしてさあ動かすぞって思ったらにSyntax Errorになってしまい、泣く泣く恥ずかしい修正を追加でコミットした経験はありませんか？

「yamlのSyntax Error修正」とか「fix typo」みたいなコミットが溢れかえるのは嫌ですよね。
そこで、gitのpre-commitを使って事前にチェックしてしまいましょう。

# Makefile

自分はタスクランナー代わりにMakefileを良く使っています。
site.ymlと同じディレクトリに以下のようなMakefileを作成します。

```bash:Makefile
all: test

INVENTORY_PATH = inventories
INVENTORIES    = $(shell git ls-files "$(INVENTORY_PATH)/*")

syntax:
    $(foreach inventory,$(INVENTORIES),ansible-playbook --syntax-check -i $(inventory) site.yml;)

test: syntax

```

# pre-commit

pre-commitは、git commitが実行される際に呼ばれるファイルです。
.git/hooks/ に以下のようなpre-commitを作成します。

```bash:pre-commit
#!/bin/bash
if git rev-parse --verify HEAD >/dev/null 2>&1
then
    against=HEAD
else
    # Initial commit: diff against an empty tree object
    against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
fi
# Redirect output to stderr.
exec 1>&2

IS_ERROR=0
if ! make syntax; then
  echo "Syntax Error"
  IS_ERROR=1
fi
exit $IS_ERROR
```

make syntax の結果がエラーの場合、commitをしないようになってます。
実行権限を忘れずにつけておきましょう。

```
$ chmod +x .git/hooks/pre-commit
```

# まとめ

ためしにsyntax errorがある状態でコミットしてみると...

```
$ git commit -m "test commit"
ansible-playbook --syntax-check -i inventories/production.yml site.yml;
ERROR! A malformed role declaration was encountered.
Syntax Error
```

という具合にコミット前にチェックすることができました。
事前にチェックするする仕組みがあると安心して開発ができますね。
便利なので試してみてください。
PYNQ-Z1 にホスト名でアクセスできるようにするには

# はじめに

本記事では、 [pynq.io](http://www.pynq.io/) から PYNQ-Z1 ボード向けに提供されている PYNQ イメージにおいて、 HTTP や SSH にてアクセスする際にホスト名を利用できるようにする方法を示します。

なお、ここで紹介する方法は、特に PYNQ イメージやそのベースになっている Ubuntu 15.10 に固有の方法、というわけではありません。様々な Linux 環境でも同様に実現できると思われます。また、 Raspberry Pi も同様の設定されているようです。

# Samba の設定

Samba の WINS 機能を利用すると、ホスト名と IP アドレスの組をローカルネットワークに周知できます。

幸い PYNQ のイメージには Samba 4.x が標準で含まれており、動作しています。この Samba の設定を変更し利用します。

## /etc/samba/smb.conf の設定

/etc/samba/smb.conf の `global` セクションに下記の内容を追加します。

```
[global]
   netbios name = pynq    # NetBIOS コンピュータ名を指定
   wins support = yes
```

## サービス再起動

下記コマンドにて Samba を再起動します。

```
$ sudo systemctl restart smbd
$ sudo systemctl restart nmbd
```

## Windows PC からのアクセス確認

* PowerShell もしくはコマンドプロンプトから `ping pynq` を実行し、名前解決および ICMP Echo Reply が返送されてくるか確認します。
* ネットワーク上のコンピュータ `\\pynq` にアクセスし、既定のファイル共有にアクセスできるかを確認します。
* http://pynq:9090/ にアクセスし、 Jupyter Notebook にアクセスできるか確認します。


# avahi-daemon の設定

avahi-daemon は Apple による Zeroconf の実装です。これを設定することにより、 macOS (MacOS X) からの名前解決が可能となります。

## avahi-daemon のインストールと起動

PYNQ で下記操作を行います。

```
$ sudo apt install avahi-daemon
$ sudo systemctl start avahi-daemon
$ sudo systemctl enable avahi-daemon
```

## Mac からのアクセス確認

macOS (MacOS X) から名前解決する場合は `pynq.local` という名前で引く必要があるようです。

* Terminal から `ping pynq.local` を実行し、名前解決および ICMP Echo Reply が返送されてくるか確認します。
* Finder で Cmd-K (Connect to Server) ダイアログウインドウを開き、 `smb://pynq.local/` にアクセスし、既定のファイル共有にアクセスできるかを確認します。
* http://pynq.local:9090/ にアクセスし、 Jupyter Notebook にアクセスできるか確認します。

## Linux からのアクセス確認

私は Linux 環境からのアクセス試験をしていませんが、 Avahi を使えば Linux からも名前解決ができるようです。
The magic words are squeamish ossifrage

日本語でおk？
と思って調べたのに、結局知りたかったことは英語のソースにしかなかったので書きました。

# はじまり
Railsのattr_encryptedを調べていたはずが、[RSA暗号のWiki](https://ja.wikipedia.org/wiki/RSA%E6%9A%97%E5%8F%B7)にまで逸れたときにそれを見つけました。
> 1977年、マーティン・ガードナーがコラムを連載していたScientific American誌に129桁の鍵を使ったRSA方式で暗号化されたメッセージを掲載。
> (中略)
> 答えは「The magic words are squeamish ossifrage」（MITのジョークで“骨折り”の意）

？

# 直訳
「魔法の言葉は気難しいヒゲワシです」

？？

# ググる
「映画サマーウォーズの～」

あの映画好きだけど今はそうじゃないんだ…。

# 答え
実は検索結果の2件目に出てました。
[英語版Wiki](https://en.wikipedia.org/wiki/The_Magic_Words_are_Squeamish_Ossifrage)。
(筆者は英語が得意でないので無意識にスルーしてました)

> Ossifrage ('bone-breaker', from Latin) is an older name for the bearded vulture, a scavenger famous for dropping animal bones and live tortoises onto rocks to crack them open.

頑張って訳すと
> Ossifrage(ラテン語で「骨を折る者」の意)はひげの生えたハゲワシの旧称で、動物の骨や生きた陸亀を岩に落として割る腐食動物としても有名。

といった感じでしょうか。
なるほど。

つまり、「squeamish ossifrage」とは「骨折り損のくたびれ儲け」に近い意味合いなのかなと。
(squeamishは「相当面倒なもの・こと」のニュアンスで捉えました)

暗号の解読に「骨を折った」人たちにこれを見せつけるあたり、皮肉の利いた面白いジョークですね。

一瞬見ただけでは何のこっちゃ、となるあたりも向こうの狙い通りな感がありますね。

# さいごに
技術者たるもの英語は避けて通れないということを痛感させられた一件でした。

どこかで話のタネにでも使ってもらえれば幸いです。

「その訳おかしいよ！」等あればコメントしていただけると勉強になるので助かります。
Googleの入社試験(非公式)にチャレンジしてみた[java]

[Googleの入社試験(非公式)にチャレンジしてみた](http://yasigani-ni.com/every-day/google%E3%81%AE%E5%85%A5%E7%A4%BE%E8%A9%A6%E9%A8%93%E9%9D%9E%E5%85%AC%E5%BC%8F%E3%81%AB%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/)

javaでやってみた．

#コツ
1の現れる個数を数える関数を使うと数が大きくなるにつれて，計算量が増えるので，関数化せずに逐次計算すると効率がいい．

```hoge.java
class hoge{
	public static void main(String[] args) {		
		int ret =0;
		for(int j=1;j<Integer.parseInt(args[0]);j++){
			ret +=((" "+j+" ").split("1").length-1);
			if(j<=ret){
				System.out.println(ret);
			}
		}
	}
}
```

#結果

```
>java hoge 200000
1
199981
199982
199983
199984
199985
199986
199987
199988
199989
199990
199992
199993
199994
199995
199996
199997
199998
199999
200000
```

#答え
199981

#感想

計算があるため，数字の入れ替えとかで高速化出来る気がするが，定式で現れないでやめた．

あるいは，近似式導き出して，それから推測した方が早いのかもしれない．がライブラリ使わないと時間かかりそう．
ランチェスターの法則上での軍運用の最適化

# これなに
[ランチェスターの法則](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%B3%E3%83%81%E3%82%A7%E3%82%B9%E3%82%BF%E3%83%BC%E3%81%AE%E6%B3%95%E5%89%87)が成り立つときに、どのように軍を移動したらよいかを最適化で求めます。

# 前提
- 武器性能比は1とする
- 終了時の敵軍は0にする
- 終了時の自軍を最大化する
- A, B, C の3地点を考え、敵は B と C にいて、動かない。
- [時空間ネットワーク](http://qiita.com/Tsutomu-KKE@github/items/e153db5ed89e5f28598d#-%E8%80%83%E3%81%88%E6%96%B9)上で考える。
- 人数は、便宜上、実数とする

# 第1法則「一騎打ちの法則」に従う場合

敵よりわずかでも多くぶつければ勝利です。ここでは、簡単のため、ある時刻までに同数になるようにしましょう。

- 自軍はAに5人、敵軍はBに2人、Cに3人とする
- A-Bは2時間、B-Cは2時間、A-Cは3時間で移動できる
- A-Cは1時間当たり0.5人しか移動できない
- 時刻2までにBに2人、時刻5までにCに3人移動させる

[最小費用流問題](http://qiita.com/Tsutomu-KKE@github/items/41d625df63f1946c7216)として解きます。

```py3:python3
import networkx as nx
g = nx.DiGraph()
g.add_node('A0', demand=-5)
g.add_node('B2', demand=2)
g.add_node('C5', demand=3)
for t in range(5):
    g.add_edge('A%d'%t, 'B%d'%(t+2), weight=2)
    g.add_edge('B%d'%t, 'C%d'%(t+2), weight=2)
    g.add_edge('A%d'%t, 'C%d'%(t+3), weight=3, capacity=0.5)
    g.add_edge('A%d'%t, 'A%d'%(t+1), weight=0)
    g.add_edge('B%d'%t, 'B%d'%(t+1), weight=0)
    g.add_edge('C%d'%t, 'C%d'%(t+1), weight=0)
r = nx.min_cost_flow(g)
for k1 in sorted(r.keys()):
    for k2, f in r[k1].items():
        if f:
            print(k1, '->', k2, f)
>>>
A0 -> C3 0.5
A0 -> B2 3.5
A0 -> A1 1.0
A1 -> A2 0.5
A1 -> C4 0.5
A2 -> C5 0.5
B2 -> B3 1.5
B3 -> C5 1.5
C3 -> C4 0.5
C4 -> C5 1.0
```

「A0 -> C3 0.5」は、時刻0にAを0.5人出発し時刻3にCに着くことを意味しています。

# 第2法則「集中効果の法則」に従う場合

- 自軍はAに8人、Bに1人、Cに1人、敵軍はBに2人、Cに3人とする
- A-B、B-C、A-Cは1時間で移動できる
- 1時間後に、敵の人数の20%分、自軍は損耗する

最大流問題っぽいですが、損耗するので、定式化して解きます。

```py3:python3
import numpy as np
from pulp import *
from ortoolpy import addvars
T, rt = 4, 0.2
m = LpProblem(sense=LpMaximize)
vx = np.array(addvars(2,2,3,T)) # Me|You, In|Out, A|B|C, Time
vy = np.array(addvars(3,3,T-1)) # From, To, Time
m += lpSum(vx[0,1,:,-1]) # Objective(Remain)
vx[:,0,:,0] = [[8.,1,1],[0,2,3]] # Initial
for t in range(T):
    for p in range(3):
        if t < T-1:
            m += vx[0,1,p,t]   == lpSum(vy[p,q,t] for q in range(3))
            m += vx[0,0,p,t+1] == lpSum(vy[q,p,t] for q in range(3))
            m += vx[1,0,p,t+1] == vx[1,1,p,t]
        m += vx[0,1,p,t] <= vx[0,0,p,t] - rt*vx[1,0,p,t]
        m += vx[1,1,p,t] >= vx[1,0,p,t] - rt*vx[0,0,p,t]
for p in range(3):
    m += vx[1,1,p,-1] == 0
m.solve()
print(m.status, value(m.objective))
np.round(np.vectorize(value)(vx), 2)
>>>
1 7.283200000000001

array([[[[ 8.  ,  0.  ,  0.  ,  1.6 ],
         [ 1.  ,  1.17,  7.83,  0.  ],
         [ 1.  ,  7.83,  0.25,  5.92]],

        [[ 8.  ,  0.  ,  0.  ,  1.6 ],
         [ 0.6 ,  0.81,  7.52,  0.  ],
         [ 0.4 ,  7.27,  0.  ,  5.68]]],


       [[[ 0.  ,  0.  ,  0.  ,  0.  ],
         [ 2.  ,  1.8 ,  1.57,  0.  ],
         [ 3.  ,  2.8 ,  1.23,  1.18]],

        [[ 0.  ,  0.  ,  0.  ,  0.  ],
         [ 1.8 ,  1.57,  0.  ,  0.  ],
         [ 2.8 ,  1.23,  1.18,  0.  ]]]])
```

最終時刻に全地点の敵軍は、0になっています。
また、最初に敵軍の多いCに投入してますが、次にちょっと多いBに、最後に残ったCに投入して、最終的に、Aに1.6人、Cに5.68人残っています。
(1時間で移動ではなく、0時間で移動して1時間ごとに損耗計算していることになっていますね。面倒なのでこのままにします)

以上
PYNQ の PL Server を systemd から起動する

# はじめに

本記事では、 [pynq.io](http://www.pynq.io/) から PYNQ-Z1 ボード向けに提供されている PYNQ イメージにおいて、 PL Server を systemd 経由で管理するように変更する例を示します。

PL Server は bitstream をロードした際に、同時に handoff 用 tcl ファイルを読み込んで、各種ブロックの MMIO アドレスを保持するために使われています。ただ、私の手元では度々 PL Server がクラッシュなどして居なくなってしまい、手動で立ち上げなおしていました。

# systemd によるプロセス管理のメリット

今回は、 PL Server を systemd 経由で起動するようにイメージを修正し、下記のメリットを得ることを目標としています。

* PL Server がクラッシュした場合に自動的に再起動させる <br>
  ※ ロード済みの IP のレジスタマップが復元されるわけではない
* systemd のユニットとして管理する他のプロセスが PL Server のユニットの起動後に起動するよう、順序を制御できる

PL Server の起動方法を変更するだけですので、基本的にはオリジナルの PYNQ イメージと同等に利用でき、特に不自由はないはずです。

# 設定方法

## /etc/rc.local からの PL Server 起動をやめる

PYNQ では PL Server を /etc/rc.local から起動していますが、これを無効化します。

```
#!/bin/sh -e
#
# (snip)

# Adding Jupyter scripts to bring up network and start Jupyter server
/root/0_resizefs.sh
/root/1_network.sh >/dev/null 2>&1 &
/root/2_jupyter_server.sh
# /root/3_pl_server.sh    # この行をコメントアウトもしくは削除
/root/4_boot_leds.sh

exit 0
```

## /usr/local/sbin/pl_server.sh を作成する

PL Server をフォアグラウンドで実行する下記スクリプトを作成します。

```
#!/bin/bash

/bin/rm -rf /home/xilinx/pynq/bitstream/.log
exec /usr/bin/python3 /home/xilinx/scripts/start_pl_server.py
```

本スクリプトには実行可能なようパーミッションを設定しておきます。（例:  rwxr-xr-x ）

```
$ sudo chmod 755 /usr/local/sbin/pl_server.sh
```

## /etc/systemd/system/pl_server.service ファイルを作成する

systemd 用 unit ファイルを作成します。

```
[Unit]
Description = PL Server

[Service]
ExecStart = /usr/local/sbin/pl_server.sh
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target
```

## pl_server ユニットを起動、有効化する

ここまでの作業で PL Server を自動起動する準備はできています。続いて systemd を介して下記のとおり操作します。

```
$ sudo systemctl start pl_server      # とりあえず起動してみる
$ sudo systemctl status pl_server     # 起動後問題がないか確認
$ sudo systemctl enable pl_server     # 問題なければ次回以降、システム起動時に自動起動
```
AppBarLayoutでenterAlwaysCollapsedのときの下flingのWorkaround

## 概要

enterAlwaysCollapsedに設定されたAppBarLayoutとRecyclerViewで下方向にflingすると、
RecyclerViewの端でスクロールが止まってしまうときのWorkaroundです。

ソースコードはこちら https://github.com/cattaka/AndroidSnippets/pull/38

<font color="red">
このWorkaroundはSupport Library 24.2.1にて動作確認しています。
将来Support Library側で修正される可能性があります。
</font>

## 動画

### Before
![ezgif-1-cd673f6ed2.gif](https://qiita-image-store.s3.amazonaws.com/0/55138/613f4b7f-73f3-b972-0d4c-b7de36b7b3f6.gif)

### After
![ezgif-1-9c39feaa5f.gif](https://qiita-image-store.s3.amazonaws.com/0/55138/c7cc552b-539b-2801-4d0e-be491614944a.gif)


## 解説
RecyclerViewを下方向にflingしたとき、RecyclerViewがスクロールを始めます。
そしてRecyclerViewの端、つまり先頭までスクロールしたとき、スクロールは止まります。
現状のCoordinatorLayoutはこのときのイベントをハンドリングしていないため、そこで終わりになります。

このWorkaroundでは、RecyclerView.OnScrollListenerを利用して**最後のスクロールイベントの速度**を計測し、スクロールが終わったタイミングでAppBarLayoutに**flingイベントを投げ直す**ことで対応しています。
PythonでWaveを再生するための環境設定  PyAudio と PortAudio

# Abstract

Python を使って `wav` ファイルの再生を行うプログラムを作成する機会があったので, 環境設定をすることになってハマったので備忘録がてらメモをします. 

# 始めにやったこと
[PyAudioの公式](https://people.csail.mit.edu/hubert/pyaudio/) に Mac OSX 向けのインストール方法が紹介されていたので

```sh
$ brew install portaudio 
$ pip install pyaudio
```

と実行したところ `pyaudio` をインストールしようとしたところで

```sh

esrc/_portaudiomodule.c:29:10: fatal error: 'portaudio.h' file not found
    #include "portaudio.h"
             ^
    1 error generated.
    error: command 'cc' failed with exit status 1
    
    ----------------------------------------
Command "/usr/bin/python -u -c "import setuptools, tokenize;__file__='/private/tmp/pip-build-vceQ5Y/pyaudio/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-ugKOpS-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /private/tmp/pip-build-vceQ5Y/pyaudio/Q5Y/pyaudio/
```

というエラーが出てしまいました. 
`portaudio.h` を見つけることができていないみたいです. ~~ちゃんと入れたのに.~~

# 解決

明示的に依存関係にあるファイルを指定してあげればいいみたいでした. 

```sh
$ sudo pip install --global-option='build_ext' --global-option='-I/usr/local/include' --global-option='-L/usr/local/lib' pyaudio
```
# Reference
- [【Qiita】pipでpyAudioインストール時にはまった回避策。](http://qiita.com/yutakau@github/items/975d3aba64f22ad43110)
    - mac port を使っての portaudio のインストール
- [【StackOverflow】when installing pyaudio, pip cannot find portaudio.h in /usr/local/include](http://stackoverflow.com/questions/33513522/when-installing-pyaudio-pip-cannot-find-portaudio-h-in-usr-local-include)
    - 自分と全く同じだったので, こちらを主に参考に

- [【Qiita】Qiitaでコンソール(シェル)のコマンド実行を書くときとかのコードブロック](http://qiita.com/5t111111/items/8bf740e5d1e013c415b1)
    - コードブロックの記法を...
GCPのFree Trialでは暗号通貨の採掘が禁止されている

GCPの利用規約を読んでいたら面白い内容を見つけたので紹介します。

Google Cloud Platformの無料トライアルに関する利用規約を読んでいたら次のような記述を見つけました。

> 2.2 Customer may not use the Services to engage in mining cryptocurrency;
>
> （拙訳）顧客は本サービスを暗号通貨の採掘に利用してはいけません。
>
> https://cloud.google.com/terms/free-trial/

無料トライアルで使えるCPUリソースをビットコイン採掘などで換金するのは禁止だそうで、「そりゃそうよね」という感想です。とはいえ、他にもリソースを浪費する行為はたくさんある中で、暗号通貨の採掘が明示的に禁止されてるのは面白いですね。該当するユーザーが無視できないくらい存在するということなんでしょう。
Firebase Boltでセキュリティルールを記述する

# Firebase Bolt とは

https://github.com/firebase/bolt

Firebase リアルタイムデータベースのセキュリティルール用のコンパイラです。

例えば以下のコードは

```bolt:all_access.bolt
path / {
  read() { true }
  write() { true }
}
```

次のjsonのセキュリティルールと同じ意味になります。

```json:all_access.json
{
  "rules": {
    ".read": "true",
    ".write": "true"
  }
}
```


現在はBeta版で言語仕様は確定しているようですが本番にデプロイする前にjsonの出力をチェックしたほうが良いそうです。

# インストール

boltはTypeScriptで書かれているツールなのでnpmでコンパイラが配布されています。

以下のコマンドでインストールできます。

```bash
$ npm install --global firebase-bolt
```

# 使い方

以下のようにルールを記述したファイルを作成します。

```bolt:database.rules.bolt
path / {
  read() { false }
  write() { false }
}
```

以下のコマンドでコンパイル結果を標準出力に書き出せます。

```bash
$ firebase-bolt < database.rules.bolt
{
  "rules": {}
}
```

第一引数にファイルを指定することでjsonを書き出してくれます。

```bash
$ firebase-bolt database.rules.bolt
bolt: Generating database.rules.json...
$ cat database.rules.json
{
  "rules": {}
}
```

# コメント

boltではJavaScriptのようにコメントを書くことができます。
jsonではコメントは書けないのでこれだけでも かなり嬉しいですね。

```bolt
// Single line

/*
Multi
Line
*/
```

# 型

boltにはTypeScriptのような型を定義することができます。
型を継承することも可能です。

```bolt
type Group {
  validate() { members != null }

  members: Map<TenKeys, User>
}

type User {
  uid: String,
  name: String
}

type TenKeys extends String {
  validate() { this.length == 1 && this >= '0' && this <= '9' }
}
```

Mapや配列もありますしUnion型やジェネリクスもあります。

# Path

`path`を指定したところにアクセス権や型を適応します。

```bolt
// 全ての人が読み書きできる
path / {
  read() { true }
  write() { true }
}
```

```bolt
// /users/{uid}をUser型にする。
path /users/{uid} is User {
  // 誰でも読み込める
  read() { true }

  // 認証した人だけが書き込める
  write() { auth != null && auth.uid == uid }
}
```

`create`、`update`、`delete`のエイリアスもあります。

```bolt
path /docs/{uid} {
    /create { create() { true } }
    /update { update() { true } }
    /delete { delete() { true } }

    /create-or-update {
      create() { true }
      update() { true }
    }
}
```

# prior()

`prior()`で書き込みされる前の値を取得できます。

# 関数

boltでは関数を定義することができます。
処理をひとまとめにして意味のわかる名前を付けることができます。

```
function isUser(uid) {
  return auth != null && auth.uid == uid;
}

// 上と下の関数は同じ意味

isUser(uid) {
  auth != null && auth.uid == uid;
}
```

# グローバル変数

`root`はデータベースのrootのリファレンスにアクセスできます。
`auth`は認証情報が入っています。認証されていなければnullになります。
`now`には現在時刻のUnixタイムスタンプが入っています。

ここはjsonでも同じですね。

# まとめ

セキュリティルールを書くのが辛くてついつい雑にしてしまいがちですが型を定義できるなら
楽に書けそうな気がします。
VSCodeでシンタックスハイライトしてくれそうなやつはあるのですが 僕の環境では何故か上手く行かなかったので 今後の課題かなと思います。

最新の内容は[GitHub](https://github.com/firebase/bolt/blob/master/docs/language.md)を確認してみてください。

また[サンプル](https://github.com/firebase/bolt/tree/master/samples)も色々あるのでそちらを見てみるのも良いと思います。
bookdown_ja_template でpdf出力を改善する

この記事は 
https://miyazakikenji.wordpress.com/2017/02/20/bookdown_ja_template/
を転記したものです. 

# bookdown

bookdown で日本語の PDF ファイルを出力できるテンプレートを作成しました.

> <https://github.com/kenjimyzk/bookdown_ja_template/> 

基本的には

> <https://github.com/kazutan/bookdown_ja_template/> 

をフォークしたものです. kazutan さんは主に html ファイルにおいていろいろ貢献しています. わたしの貢献は日本語 PDF を作るための設定です.

主な違いは以下です:

-   lualatex でなく xelatex にしている.
-   IPA font でなく IPAex font にしている
-   pdf で bxjsbook を使用していている
-   日本語付きの図表の例を示している.
-   日本語の索引と参考文献の例を示している.

使い方は全く同じで, 先のサイトや index.Rmd にかかれています. ここでは色々補足をします.


## bxjsbook

PDF のためのスタイルファイルで bxjsbook を使いました. これについて

> <http://qiita.com/naqtn/items/7469a07ea797df5e2ecc>

が参考になりました. ただ, このままだとなぜかコードの内の日本語が明朝体になってしまいます. 原因不明なので, 冗長ですが `preamble.tex` に

    \usepackage[ipa]{zxjafont}

をつけています. 

また bxjsbook だと上手く章立てできないので,

    pandoc_args: --chapters

を pandoc の引数にしております. ただこれは最新の pandoc だと機能が古いと怒られ

    pandoc_args: --top-level-division=chapter

とするようにいわれますが, 現在の windows の RStudio に同封の pandoc ではバージョンが古いため後者は設定できません.


## texlive 2016

texlive 2016 が導入されているのが前提になっています. 現在の最新版 2016 でないとスタイルファイル `bxjsbook` やユニコードに対応した索引作成ソフト `upmendex`  が使えません. 

Ubuntu で `apt-get install` でインストールした場合だと上手く動きません. これを機にこちらでインストールすることをオススメします:

> <https://github.com/scottkosty/install-tl-ubuntu>


## jeconunicode.bst

bibtex のスタイルファイルは 

> <http://shirotakeda.org/ja/tex-ja/jecon-ja.html>

にある `jcon.bst` のユニコード版 `jecon_unicode.bst` を使います. 最近第７版が出版された有名な「LaTeX2 ε美文書作成入門」技術評論社で bibtex の章の最後の文章で `natbib` に対応した日本語パッケージがないといっていますが, それは間違いです.

この武田さんの `jcon.bst` でバッチリ `natbib` に対応して 著者 (年) という社会科学で標準的に使われる表記で参考文献が作れます.
なお現在 texlive 20126 での upbibtex にバグがあるために一部機能がうまくいかないのですが, バグが直り, texlive 2017 で反映されるようです.

> <http://oku.edu.mie-u.ac.jp/tex/mod/forum/discuss.php?d=2006>

あと YAML がうまく  `jecon_unicode.bst` を読み込んでくれないので `jeconunicode.bst` にファイル名を変更してフォルダにおいています. 
さらにこのファイルは自分用に少しだけ修正しております (Pull Request 中).


## ipaex

日本語のフォントを R で表記するために IPAex フォントを使用しています. 
古い IPA フォントとの違いは欧米フォントがプロポーシャルになってることです. 
以下からダウンロードしてください。

<http://ipafont.ipa.go.jp/>

作図の際, 日本語フォントを含めた各種のフォントを作図に用いると警告が出る場合があります.
警告無しで使用するために `extrafont` というパッケージを用います. まず最初に

    install.packages("extrafont")
    extrafont::font_import(prompt=FALSE)

として読み込みます. 実際に使えるフォントは

    extrafont::fonts()

で確認できます. その上でセッションごとに

    extrafont::loadfonts(quiet=TRUE)

と実行するとよいでしょう.

R での日本語付きの作図について, いろいろ情報が錯綜し, 私自身いろいろ試行錯誤しました.

現時点の結論として, html 出力では `png` をデバイスとし, pdf 出力では `cairo_pdf` をデバイスとし, `grDevices` の設定を直接いじるのでなく, グラフィクパッケージごとにフォントファミリーを指定するのがよい考えております. そのために IPA フォントは事前にインストールするのが不可欠で, 環境依存になっていまいますが&#x2026;


## まとめ

以上 bookdown で日本語の pdf を作成するための紹介をしました. この bookdown が広まれば, 編集者にチェックをまかせていた参考文献や索引づくりが自分でできるようになり, ますます出版の敷居が下がってくるのではないでしょうか.

<http://www.kyoritsu-pub.co.jp/series/205/>

をみると, 「RStudio による Reproducible Research」高橋康介著が予定されています. きっと「ドキュメント・プレゼンテーション生成」の続編で, bookdown が言及されていると思いますので楽しみです.

現在, OS や環境依存を避けるための Docker 環境を構築することを模索しています. それが上手くいけばまた報告させていただきます.
td-agent から Elasticsearch にデータを流す。というのをローカル Mac で試す自分用メモ。

# 事前に用意しておくもの

- Mac に td-agent を入れておく
- Mac に Elasticsearch と Kibana を入れておく

# fluentd のプラグインを入れる

ref. https://github.com/uken/fluent-plugin-elasticsearch

```zsh:インストール
# td-agent-gem のパスは環境によって変わると思うので、調整してください。
$ sudo /opt/td-agent/usr/sbin/td-agent-gem install fluent-plugin-elasticsearch
```

```zsh:入ったことを確認
$ sudo /opt/td-agent/usr/sbin/td-agent-gem list fluent-plugin-elasticsearch

*** LOCAL GEMS ***

fluent-plugin-elasticsearch (1.9.2)
```

# 設定ファイルを書く

ref. https://github.com/uken/fluent-plugin-elasticsearch#usage

```vim:/etc/td-agent/td-agent.conf
<source>
  type forward
</source>

<source>
  type     tail
  tag      lograge
  format   json
  path     /Users/mochizuki/Developments/project/log/lograge_development.log
  pos_file /Users/mochizuki/Developments/project/log/lograge_development.log.pos
  time_key time
</source>

<match lograge>
  @type copy
  <store>
    @type stdout
  </store>
  <store>
    @type elasticsearch
    host localhost
    port 9200
    index_name fluentd
    type_name fluentd
  </store>
</match>
```

# Elasticsearch と kibana を立ち上げて動かしてみる

ref. https://www.elastic.co/jp/videos/getting-started-elasticsearch

起動については、上動画に詳しく書かれてあります。

Kibana の Dev Tools から、確認してみます。

![スクリーンショット 2017-02-20 15.36.03.png](https://qiita-image-store.s3.amazonaws.com/0/45822/0080591e-4ae7-5d40-d96d-a0b8d4840ebb.png)


無事、終了でございます。

ありがとうございました。
ExcelからExchangeの配布リストのメンバーのデータを再帰的に取得する

Excelで簡単な部署内電話帳みたいなものが作成したくて以下のような感じでスクリプトを組んでみました。
すごーく動作が遅いですが、当方の環境がOutlookの住所録に10万件以上登録されているような環境だからかもしれないし、そのわりにインフラが絶望的に酷いからかもしれません。
しかし、根本的に裏方の仕組みを考えれば当然遅いのは自明の理なので、使用してみる際にはサーバへの負荷等を考慮して試してみてください。

### 環境
* Excel 2010
* Outlook 2010  
※Excel VBA上にて、参照設定でOutlookを追加してください

### コード - code
ほしい情報をユーザ定義型でまとめます。

```
Option Explicit

Private Type tdata
    Dept As String      '組織
    Jt As String        '役職
    Name As String
    Inline As String    '内線
    Tel As String       '外線
    Mobile As String
End Type
```
一部Exchangeのデータ外のものが含まれていますが、こちらのExchange登録情報の問題です。

```
Public Sub getdata()

    ' https://msdn.microsoft.com/ja-jp/library/office/bb645998.aspx

    ' グローバルな Outlook の Application および NameSpace 変数を宣言します。
    ' namespace("MAPI")とsessionは同じらしい
    Dim objSession          As Object
    Dim glbAdressList       As Outlook.AddressList
    Dim oAEs              As Outlook.AddressEntries
    Dim oAE                 As Outlook.AddressEntry
    Dim i As Long, j As Integer
    Dim data() As tdata

    Set objSession = CreateObject("Outlook.Application").Session
    Set glbAdressList = objSession.GetGlobalAddressList
    Set oAEs = glbAdressList.AddressEntries
    Set oAE = oAEs("配布リスト")

    ReDim Preserve data(0) '仮で0になるはず
    
    Debug.Print Time
    Call DLexpand(oAE, data)
    Debug.Print Time
    
    For i = 1 To UBound(data)
        Debug.Print data(i).Name
    Next i

End Sub
```
グローバルアドレス帳からほしい配布リストを指定します。
動的配列は例によってVBAでは検知できないので今回は0番目は空と決め打ちします。

以下が再帰関数です。配布リストの中に配布リストがある度に呼び出されます。

```
Private Sub DLexpand(oAE As Outlook.AddressEntry, data() As tdata)

    Dim oExUser As Outlook.ExchangeUser
    Dim oAEs As Outlook.AddressEntries
    Dim oEDL As Outlook.ExchangeDistributionList
    Dim i As Integer
    Dim tmp As Variant

    Set oEDL = oAE.GetExchangeDistributionList
    Set oAEs = oEDL.GetExchangeDistributionListMembers

    For i = 1 To oAEs.Count
        Set oAE = oAEs(i)
        If oAE.DisplayType = olUser Then
            Set oExUser = oAE.GetExchangeUser
            ReDim Preserve data(UBound(data) + 1)
            With data(UBound(data))
                .Dept = oExUser.Department
                .Jt = oExUser.JobTitle
                tmp = Split(oExUser.Name, "(")
                .Name = tmp(0)
                .Mobile = oExUser.MobileTelephoneNumber
                If InStr(oExUser.BusinessTelephoneNumber, "/") Then
                    tmp = Split(oExUser.BusinessTelephoneNumber, "/")
                    .Inline = tmp(0)
                    .Tel = tmp(1)
                ElseIf oExUser.BusinessTelephoneNumber <> "" Then
                    .Tel = oExUser.BusinessTelephoneNumber
                    .Inline = ""
                End If
            End With
        'addressentry dysplaytypeがolRemoteUserがいるので省く
        ElseIf oAE.DisplayType = olDistList Then
            Call DLexpand(oAE, data)
        End If
    Next
    
End Sub
```
ユーザ定義型に代入してるところはそれぞれの環境に合わせてください。

#### その他
Excelだとマクロの記録とかがあって参考になるけど、今回はガッツリとOutlookのヘルプを見て考えました。より楽な方法とか高速な方法があれば教えていただければ助かります。  
2017/3/3 少しコードを更新しました。想定外のユーザがいたため、Elseifではじきます。
Go で関数の引数用構造体のバリデーションと初期化をするメソッドをタグから生成するツールを作った

# はじめに

* Go では小さい構造体を関数の引数にすることで名前付き引数のようなことが実現できる。

```go
type MyParam struct { X, Y int }
func MyFunc(m MyParam) {}
func main() {
  MyFunc(MyParam{X: 1, Y: 2})
}
```

* この引数用の構造宣言の各フィールドのタグでバリデーションのオプションやデフォルト値を指定できると便利だと思いツールを作ってみた。

# レポジトリ

* https://github.com/nirasan/argumenter

# 使い方

* 基本的に [README](https://github.com/nirasan/argumenter/blob/master/README.md) のとおり

## 構造体宣言

* 引数として扱う構造体の宣言を行う
* タグの `arg:""` 部分で argumenter 用の設定をする
  * `default=VALUE` でデフォルト値の指定
  * `min=VALUE` で最小値の指定
  * ...

```go
package main

type MyType struct {
    I  int          `arg:"default=5,min=0,max=10"`
    S  string       `arg:"default=hello"`
    SI []int        `arg:"required,lenmin=1,lenmax=4"`
    M  map[int]bool `arg:"required"`
    F  func()       `arg:"required"`
    IN interface{}  `arg:"required"`
    P  *int         `arg:"required"`
}
```

## 関数生成

* `argumenter` コマンドに対象の構造体名と記載のファイルを指定する
  * 出力ファイル名を指定しないと `元のファイル名_argumenter.go` が生成される

```
argumenter -type MyType file.go
```

## 生成される関数

```go
// Code generated by "argumenter -type MyType"; DO NOT EDIT
package main

import "errors"

func (m *MyType) Valid() error {

    if m.I == 0 {
        m.I = 5
    }

    if m.I < 0 {
        return errors.New("I must greater than or equal 0")
    }

    if m.I > 10 {
        return errors.New("I must less than or equal 10")
    }

    if m.S == "" {
        m.S = "hello"
    }

    if m.SI == nil {
        return errors.New("SI must not nil")
    }

    if len(m.SI) < 1 {
        return errors.New("SI length must greater than or equal 1")
    }

    if len(m.SI) > 4 {
        return errors.New("SI length must less than or equal 4")
    }

    if m.M == nil {
        return errors.New("M must not nil")
    }

    if m.F == nil {
        return errors.New("F must not nil")
    }

    if m.IN == nil {
        return errors.New("IN must not nil")
    }

    if m.P == nil {
        return errors.New("P must not nil")
    }

    return nil
}
```

## 生成された関数の使い方

* `Valid() error` 関数が生成されるので引数として受け取った直後に実行して必要ならエラー処理を行う
* `Valid()` を実行するとデフォルト値が挿入される

```go
func AnyFunc(m *MyType) {
    if e := m.Valud() {
        // エラー処理
    }
    num := m.I // デフォルト値が取得できる
}
```

# おわりに

* Go は実装が固くて遊びが少ないという印象だったが、コード解析や生成まわりのツールがそのぶん最初から充実していて面白かった。
* 次は goyacc あたりを試してみたい。
性能を上げるには

システムの性能を上げるにはどうしたらいいか。を考えてみる。

まだメモです。このあと、精査したり、まとめたり、例示したりしたい。編集リクエストはこの時点から歓迎します。

#　攻め方

- プロファイルを取る: 対処すべき、時間が長い処理の整理のため

# テクニック

- 分散させる: マルチスレッド、MapReduce、グリッドコンピューティング
- 待ち合わせを減らす: 
- 待つ順番を揃える: P5352421
- できるだけ手前で刈り込む: SQLチューニングで、効果の高いインデックスを先に使うやつ
- できるだけ手前で打ち返す: 
- なめる量を減らす: SQLのインデックス
- なめる速さを上げる: 
- 薄くする: 
- 短くする: 
- 一度にやっつける:　ベクトル、SIMD、GPGPU、 
- 事前にまとめる: マイクロバッチ、ネッティング
- 粗くざっくりやる: 
- 速いやりかたにする: バイナリサーチ、51EB851F、FPGA
- 事前に分けておく
- 前倒し着手する: 
- 投機的に実行する: HFTの応答
- 同時並行で処理する: CPUパイプライン
- 速いやつを使う: フラッシュストレージ
- 近くする: キャッシュ、レジスタ
- 待たない: HTTPパイプライン
- やりすぎない
- 簡単にやる、手抜きする
- そもそもやらない
- 必要なことだけやる
- 捌き屋を入れる
- エンジンを増やす
- 無駄を省く

# 引用元、参考資料

- トヨタ、リーン、アジャイルの無駄
- データベースの高速化
- YAGNI、KISS、
- アルゴリズムの高速化、枝刈りとか
- ハードウェアの高速化
- キャッシュ
- GPGPU、FPGA、SIMD命令、HFTでの投機的応答
- 51EB851F
[C#][.NET] モックライブラリNSubstitute使い方メモ

.Net向けのモックライブラリは数あります。そのうちNSubstituteは、staticクラスや拡張メソッドをモック化できて便利なのです。

:::note warn
2024-10-02 追記

> staticクラスや拡張メソッドをモック化できて

上記の部分について、@laughter さんのコメントを参照してください。

https://qiita.com/sengoku/items/48f58f778a05f13f922e#comment-8cfd13436bf81b4b14a4
:::


# インストールの仕方

Visual Studioであれば、プロジェクトを右クリック > Manage NuGet Packages... メニューを選択、あとは「NSubstitute」を検索してインストールするだけです。

# モックの生成

まずはモックの生成から。

```csharp:
var mock = NSubstitute
    .Substitute
    .For<モック対象クラス>();
```

# メソッド戻り値の定義

## 引数がない場合

```csharp:
mock.SomeMethod()
    .Returns(戻り値);
```

## 引数を指定する場合

```csharp:
mock.SomeMethod(NSubstitute.Arg.Is(引数))
    .Returns(戻り値);
```

## 引数はなんでもいい場合

```csharp:
mock.SomeMethod(NSubstitute.Arg.Any<型>())
    .Returns(戻り値);
```

# プロパティ戻り値の定義

```csharp:
mock.SomeProperty
    .Returns(戻り値);
```

# メソッド呼び出しのベリファイ

メソッドが呼び出されたかどうかテストします。

```csharp:
mock.Received()
    .SomeMethod();
```

## 呼び出し回数もベリファイ

3回呼び出されたかどうかテストします。

```csharp:
mock.received(3)
    .SomeMethod();
```

## 余計な呼び出しが行われていないか

```csharp:
mock.DidNotReceived()
    .SomeMethod();
```

# メソッド呼び出し時の引数を捕まえる (capture arguments)

このようなテスト対象のクラスがあったとしまして、

```csharp:
class Foo
{
    Result Bar(Baz baz)
    {
        // some stuff
    }
}
```

こうします。

```csharp:
var capturedArgs = new List<Baz>();

mock.Bar(Arg.Do<Baz>(x => capturedArgs.Add(x)));
```

`capturedArgs`に引数がたまります。

:warning: 引数のインスタンスが変化するようなときは、クローンを作らないとテストが期待通りにならないかもしれません。
AtomでSQLを見やすく整形する ~ atom-beautify ~

ログなどから発行したSQLをコピーしてきて手元のテキストエディタでみるようなことってありますよね？
そんな時、長いSQLだと見やすく整形してやるのを自動でできないかなと思ったところ、
Atomにはatom-beautifyというPackageがあるようなので入れてみました。

http://naremo.jp/2016/02/atom-beautify/

こいつをインストールして実行！
しかし実行してみるとエラーが。。

どうもSQLの整形にはsqlparseというコマンドを利用しているようです。
pipで入れられるので早速導入してみました。

```
$ pip install --upgrade sqlparse
```

https://github.com/andialbrecht/sqlparse

これで実行し直したら、、できました！
これで捗りますね。
Unquoted fields do not allow \r or \n

# やりたかったこと
改行コードがCRLFのCSVの読み込みを行いたい...with ruby

# 問題点
CSV.foreachを使用すると以下のエラーが発生

Errorメッセージ
`Unquoted fields do not allow \r or \n`

対象ソース

```ruby:sample.rb
# オプションは各タイミングで適切な値を設定
CSV.foreach('file_path', headers: true, encoding: 'encoding', quote_char: 'quote_char', col_sep: splitter) do |row|
    # なんか処理
   puts row
end
```

## 原因
~~[RubyでのCSV処理のエラー](http://kaworu.jpn.org/kaworu/2015-09-24-1.php)
上記の記事に書いてあるとおりに、CSVの改行コードが問題っぽい
(参考記事のとおりに改行コードをLFに変換するとうまく読み込んでくれます。)~~

~~ただし、今回はCRLFの改行コードも読み込めるようにします。~~

※@scivola さんよりコメントをいただきました。
> 何も考えなくても csv ライブラリーは改行コードが CRLF の CSV ファイルを期待どおり読んでくれますよ。

とのこと...
ふならば何が原因なのだろうか？(CSVファイルにCRLFがまざると現象が起きるのは確認ずみ)
ひとまずは下記の解決策にて一応はやりたいことは実現できているので、同じ現象がおきても何とかはなるはず。。。
ただし、具体的な原因やCSV.foreachを使っての解決策がわかりましたら追記or記事の投稿を行います...



# 解決策
ここに解決策が書いてありました
[CSV - Unquoted fields do not allow \r or \n (line 2)
](http://stackoverflow.com/questions/11548637/csv-unquoted-fields-do-not-allow-r-or-n-line-2)
一度File.readを使ってファイルを読み込んで、中のテキストの改行コードをまとめて書き換えてしまいます。

```ruby:sample2.rb
# オプションは各タイミングで適切な値を設定
csv_text = File.read('file_path', encoding: 'encoding')
csv_text = csv_text.gsub /^$\n/, ''
i = 0
@csv = CSV.parse(csv_text, headers: true, skip_blanks: true, quote_char: 'quote_char', col_sep: 'splitter')
@csv.each do |row|
    # なんか処理
   puts row
end
```

もっとよさそうな方法も有る気もしますが、いったん解決したのでOKということに...

## その他 (TODO)
[singleton method CSV.new](https://docs.ruby-lang.org/ja/2.0.0/method/CSV/s/new.html)
ここに改行コードの指定ができるような記載があったんだけどもなぜかうまくいかなかったので上記解決策をとっています。(row_sep)
暇があれば、singleton method CSV.newの記事の内容でどうにか実現できないか調べてみるのもありかも
SPFレコードの設定

### 前提
* DNSサーバーはお名前.comやムームーなどで取得をしてレコードの管理をしている。
* グループのメールプラットフォームは、google suiteを使っている。
* DNSレコードで、googleのMXを設定している。

このような状況で、たまにグループ使用しているドメインが、相手先の迷惑メールホルダに入ってしまうことがあったので、DNSレコードにspfの設定を追記しました。

### SPFとは
* Sender Policy Frameworkの略
* もともとSMTPの仕様で、メールのヘッダーエンベローブのFROMと、メールを受信した際に表示されるFROMは同じである必要がない。
* よって悪意ある送信者は任意でヘッダーエンベローブを偽造することができる。
* そのため受信側のSMTPサーバーは、送信側のSMTPサーバーが本当に証明されているものなのかをDNSレベルで判断する必要がある（昔はやりたい放題でした）。
* 受信側SMTPサーバーは送信側SMTPサーバーから送られてきた、MAIL FROM:コマンドの引数に指定されているドメインのDNSサーバーに対して、spfが設定されているかを確認し認証する。

詳しくは[こちら](http://salt.iajapan.org/wpmu/anti_spam/admin/tech/explanation/spf/)を確認頂ければと思います。

### SPFレコードの手順
1. googleのspf設定を確認。[こちら](https://support.google.com/a/answer/178723?hl=ja)の、「v=spf1 include:_spf.google.com ~all」が、それにあたります。
2. 使っているDNSサービスのコントロールパネルを開き、対象のドメインを選択。
3. DNSレコードの追加で、以下のように設定し登録。

|ホスト名(サブドメイン）  |タイプ    |内容                               |
|:----------------:|:------:|:---------------------------------:|
|                  |TXT     |v=spf1 include:_spf.google.com ~all|

これで、このドメインで指定しているMXサーバー（送信側SMTP）から、受信側SMTPサーバーにMAIL FROM:コマンドが送られた際に、受信側SMTPサーバーは、送信側SMTPのドメインが正当と判断し、迷惑メール扱いをしないようになります。

個人的には、メールっていつまで続くんだろーって思っているんですが(´・ω・｀)
【おすすめ勉強法】Progateを使って新しくプログラミング言語を習得!!

※こちらの記事は、プロスタ編集部がプログラミングの学習法を公開することで、皆様のお役に立ちたい意図で投稿しております。

参考サイト：[【おすすめ勉強法】Progateを使って新しくプログラミング言語を習得!!](http://programming-study.com/case/progate-study/)

#【おすすめ勉強法】Progateを使って新しくプログラミング言語を習得!!



progateで新しく複数のプログラミング言語を習得してきた方の体験談です。

プログラミングを勉強しようとすると、何から手を付ければ良いか分からないことがありますね。
「どのプログラミング言語を勉強しよう」と迷うこともあるでしょう。
そういう時は、各言語の「基礎編」が無料で学べるオンライン学習サービス「Progate（プロゲイト）」を利用するのは如何でしょうか。

学びたい言語をじっくり学ぶのにもProgateはオススメです。
至れり尽くせり！Progate利用時に用意するのはPCだけ！私は、HTML/CSS、PHP、Rubyをこのサイトで学びました。
準備するのはPCだけで良いので、気軽に始められます。



##Progateはオンラインで学習が完結

カリキュラムは幾つかの章とレッスンに分かれており、各レッスンは、そのレッスンで覚える内容を解説したスライドと、そのスライドを参考に、実際のコードを打ち込む演習で構成されています。
「演習」で使用するエディタも、要素ごとの色分け、閉じタグの補完、エラー箇所の表示などの機能を揃えており、「このエディタを開発時にも使いたい」と思わせる出来です。
プログラミング学習に集中できる学習環境がオンライン上に用意されているのです。
Progateでの勉強が捗るのは「成長が実感できる」から！

##Progate学習のメリット

Progateでは、学習が行き詰まらないよう、様々な工夫が用意されています。

1.いつでもスライドに戻って復習できる
2.演習中に「ヒント」が閲覧できる
3.「回答を確認」する時に、間違っている箇所を具体的に指摘してくれる
これらの工夫により、ほとんどの演習はスライド画面と演習画面を行き来すれば自力で解答できる内容になっていたと感じました。
また、解答が終わると「経験値」が入り、一定数貯まると「レベルアップ」するという遊び心もあり、そのレベルを見ていると自分の成長が実感できます。
Progateでプログラミングだけでなく開発現場で必要な知識も学ぶことができます。

##progateのカリキュラム

Progateのカリキュラムはリリース当初より増えており、現在はプログラミング初心者が満足できるボリュームが揃っています。
従来からあった「HTML & CSS」「JavaScript」「jQuery」「PHP」「Ruby」などは、「基礎編」「中級編」「上級編」と、各カリキュラムで勉強した内容をノーヒントで復讐する「道場コース」が追加されています。
また、2016年には新たに「Ruby on Rails」「Python」などの言語カリキュラムや、「Command Line」のコースも用意され、学習したプログラミング言語を実務で役立てるための学習もできるようになりました。
2017年1月には、ソースコードのバージョン管理や共同開発を可能にするツール「Git」について学べるコースも開講する予定だそうです。



##躓いた時にprogateに戻って復習する

Progateでは、カリキュラムに載っていない内容は勉強が出来ないので、ある程度学習を進めたら、離れてしまうかもしれません。
しかし、Progateの学習記録が消えてしまうわけではありませんので、何かに躓いた時や、久しぶりに触る言語が出てきた時に、復習教材としても十分に使えます。
ある仕事で久しぶりにHTMLを触ることになったので、「HTML & CSS 基礎編」を受講しましたが、30分くらいで一通りの復習を効率よく行え、とても便利だと感じました。

##Progateの有料プランに入るべきか

Progateの各カリキュラムで、「基礎編」「初級編」以上の学習を行いたい場合は、「有料プラン」に入る必要があります。
また、「Command Line」だけは、有料プランだけのカリキュラムとなっています。
有料プランは、全てのコースを受講できる「プラス会員（980円/月）」と、更にチャットでアドバイスが受けられる「プレミアム会員（2.980円/月）」の2種類があり、私は、PHPのオブジェクト指向をしっかり学びたかったので、「プラス会員」として使っています。
中級以上のコースは、覚えることが多く、たまに「Progate」以外のサイトや書籍で内容を確認しながら演習をこなすこともありましたが、その分、PHPに対する理解は深まりました。
他のオンライン学習の教材を利用することも考えられるのですが、手軽且つマイペースで学習を進められる「Progate」以外のサービスを探し、比較検討したり、登録したりする手間を考えると、「Progate」の「プラス会員」に絞って、学習を続けるというのは、良い選択だったと考えています。

##おわりに

さあ、Prog-8でプログラマーの扉を開こう！
プログラミング初心者だった私ですが、ProgateでPHPやHTMLなどを学んだ結果、簡単なランディングページやWordPressのテーマ編集ができるようになり、とても自信が持てました。
プログラミングを学習する方法やリズム、コツなども見えてきたので、現在は、Progateで学んだ知識を元に、サイト運営に必要なWordPressプラグインを自作したり、実践を通してBootstrapやPHPのフレームワークについての学習を続けています。皆さんもぜひProgateでプログラミングの腕を磨いていきましょう！

おすすめ

➡[Progate CEO加藤氏が目指す〜オンラインで、初心者から創れる人を輩出する〜](http://programming-study.com/interview/masanorikato/)
➡[初心者が最短でプログラミングを習得するための効率的な勉強法8選](http://programming-study.com/trouble/how-to-study/)
C言語で三項演算子の偽の値を省略(？)する

「可読性なんかどうでもいい！何が何でも三項演算子を使わせてくれ！」
「if文なんてもう書きたくない！」
という全国1億3000万人の三項演算子ファンの皆さま、お待たせいたしました。

例えば、

``` c
if(flag == 1) {
  result = NUM;
}
```

というようなコードは三項演算子にはせず（する必要もないですので）、1行で済ませたい場合も以下のように記述するのが普通かと思います。

``` c
if(flag == 1) result = NUM;
```

たしかに可読性も悪くならずにそれなりにスマートにはなっていると思いますが、三項演算子ファンの皆さまにはifが邪魔くさく感じられていると思います。
三項演算子は真と偽の結果を用意するのが通例ですが、特に入れるものが無い場合には数値を入れてしまいましょう。

``` c
(flag == 1) ? result = NUM : 0;
```

ifを使った場合より長いとか可読性が微妙とかは置いておいて、少なくとも自分の環境では期待通りの動作が行えています。
タイトルには「偽の値を省略」と書きましたが真の値に入れることも可能です。

``` c
(flag == 0) ? 1 : result = NUM;
```

C++や\#defineなどでTRUE、FALSEが使える場合は置き換えると可読性も上がりますね。

``` c
(flag == 1) ? result = NUM : FALSE;
```

## 実行時間比較
このままだとクソpostなので、時間計測をすることによりそれっぽい体裁を保ちます。
環境はCentOS 6.7(x86_64) + gcc4.4.7です。
以下のコードを実行してtimeコマンドで計測しました。

``` test1.c
int main() {
  int result, i;
  for(i = 0; i < 2000000000; i ++) {
    if(i % 5 == 0) result = i;
  }
  return 1;
}
```

``` test2.c
int main() {
  int result, i;
  for(i = 0; i < 2000000000; i ++) {
    (i % 5 == 0) ? result = i : 0;
  }
  return 1;
}
```

### 結果
timeコマンドにおけるユーザ時間の10回分の平均です。

    if文 | 三項演算子
:------:|:---------:
4.379s | 4.379s

なんと20億回のループで平均時間が同じという結果でした。
これで三項演算子ファンの皆さまも大手を振って記述できますね。

実際GPU上とかだとワープダイバージェンスの関係で結果が変わるかもしれないですが、計測してないのでわかりません。
おしまい。
プログラミングに向いている人、向いてない人


※こちらの記事は、プロスタ編集部がプログラミングの学習法を公開することで、皆様のお役に立ちたい意図で投稿しております。

参考サイト：[プログラミングに向いている人、向いてない人](http://programming-study.com/case/programming-people/)



#プログラミングに向いている人、向いてない人


プログラミングスクールで講師を勤めていた方の実体験に基づく話です。

「プログラミングに向いている人、いない人」について、考えてみましょう。向いている＝長所、向いてない＝短所として洗い出せば、単に自分がどちらなのかということだけでなく、「（自分は）向いていないと思ったけど、こういう点（短所）を改善すれば、プログラムが作れる人になれる！」と気づくことができるかも知れません。

##プログラミングスクールの授業の実態

私は一時期、社内の教育でプログラミングを教える仕事をしていました。

それは、いわゆる「プログラミング実習」の授業で、とある電気メーカの工場のラインで、将来、監督する立場にある10代の若い人たちを中心に、教えるという仕事でした。具体的には、フローチャートの書き方やプログラムを作っていくコツについて一通り説明をするといった作業です。その説明が一通り終わると、そのままの流れで、「実習」になるのですが、大半の生徒は、固まってしまいます。

「分からないことがあったら、遠慮せずに、何でも聞いてください」

必ず最後に、そう付け加え、生徒たちの間をねりあるきます。でも、遠慮をしているという訳ではないらしいのですが、手が動き出す生徒というのは、ほとんどいません。先生業務を始めた頃は、「少しでも理解を深めてほしい」という一心で

「では、私に分からないところを教えてください」

そう問い合わせると、彼らの回答は、ほぼ、間違いなく「全部・・・」という答えが返ってきます。つまり、彼らにとって、「プログラミング」とは、「何が分からないか、分からない、分からないところが、どこだか、よく分からない」のです。なんだか哲学書みたいな話になってきましたが、よくよく、思い出すと、確かに自分も、始めた頃は、そうでした。


##プログラミングの世界とは

プログラミングの世界は、学校の勉強と違います。それは「一つの問題」に対して、「一つの答え」が用意されている数学の公式のようなものではなく、たとえ、同じ答えに到達するとしても、沢山のルートがあります。もっとも、近年のプログラミング言語の進歩により、そういった「ばらつき」は抑えられる傾向にあります。これは、プログラムの生産性（可読性、再編、追加編集、デバッグなど）に大きく寄与する要素だからです。

それでも、やはり、個性が出ます。特に、私が教鞭をとっていたころは、最も原始的でシンプルな「アセンブラ」という完全に機械よりな言語でしたので、特にその差が著しかった…という記憶があります。現在は、そういった「個人的なばらつき」が出にくく、生産性の高い「オブジェクト指向」と言われる言語が主流です。

代表はJava、MSだとC#などが挙げられます（C++はオブジェクト指向の強い言語とも言われていますが、私はC言語をむりくり「オブジェクト指向」にしたもののように思えて、むしろ、複雑で、プログラミングの入門者には向かないかと考えています）。C言語もどちらかというと、OSなどのシステムを構築するために開発されたものなので、オブジェクト指向とは程遠く、同様にこれからプログラミングを始めたい人にはあまりお勧めでありません。

今までの学校教育ではそういった、「アルゴリズム」という考え方について学ぶという、ことはなかったように思います。だから、彼らも面食らってしまったのでしょう。もっとも最近では、これらを子供たちに学ばせようという動きがあるらしく、義務教育でも政府は「プログラミング」をコンピュータ教育の一環としてやっていく方針を固めたようです。



また、別の例を考えてみましょう。例えば、よく、人を「理系」「文系」で分けますが、「理系」は向いていて、「文系」は向いてないのでしょうか？

確かに、数学が得意な人だったら、その、プログラミング言語の仕様を理解して、「方程式を解く」ように、プログラムをすらすら書けるのかもしれません。これらを踏まえ、簡単に「プログラミングに向いている人、いない人」について、まとめてみましょう。

##プログラミングに向いている人/向いていない人

###プログラミングに向いてる人の特徴

・理系に限らず、様々な「もの」に対して興味を持つ人
・文書を書いたり、よんだりするのが好きな人

###プログラミングに向いていない人の特徴

・論理的に考えるのが嫌いな人
・物事にたいして、粘り強さがない人


【おすすめ記事】

➡[1人でのプログラミング学習。効率を良くする5つの方法とは？](http://programming-study.com/trouble/programming-efficiency/)
➡[【プログラミング学習法】QiitaやStudyplusを使って学習モチベーションを高める](http://programming-study.com/case/qiita-studyplus/)
➡[初心者にオススメ！プログラミングを学習できるスマホアプリ7選](http://programming-study.com/trouble/smartphone-app/)
【学習のコツ】Airbnbを使って気分転換してプログラミングしよう！

※こちらの記事は、プロスタ編集部がプログラミングの学習法を公開することで、皆様のお役に立ちたい意図で投稿しております。

参考サイト：[【学習のコツ】Airbnbを使って気分転換してプログラミングしよう！](http://programming-study.com/case/airbnb/)

#【学習のコツ】Airbnbを使って気分転換してプログラミングしよう！


机の前で何時間も過ごしていると、集中したいのにできないことがあるので、たまにカフェに行き、環境を変えてプログラミング作業や勉強をすることがあります。
作業環境を少し変えるだけで、以下のような効果があると思います。

・気分転換になる
・集中力が高まる
・美味しいコーヒーがある

３番目はともかく、カフェや図書館など、気分転換に使える場所を幾つか見つけておくと、行き詰まった状況を突破する手助けになるのかもしれません。
また、思い切って、どこかに宿泊して、一日中作業をすると、よりリフレッシュ効果が高まるとも感じています。

私の場合、Airbnbという、宿泊施設や民宿を貸し出す人向けのウェブサイトを利用して部屋や一軒家を借りることもあります。

Airbnbなら、3,000円前後で一晩集中できる環境が用意できるので、徹夜で作業する時に使うことがあります。
また、広めの部屋や一軒家を借りて、エンジニア合宿を企画することもあります。
ホテルの会議室や一般の合宿施設とAirbnbで借りられる部屋を比較すると、Airbnbの方がリーズナブルに会場を借りられるような印象があります。

##Airbnbで合宿会場を選ぶ理由

金銭面以外では、以下の点もAirbnbを利用する決め手になっています。

・一軒家、複数のベッドルームがある施設が見つかった
・オーナーと直接連絡がとれ、柔軟に対応してもらえた
・リゾート地でも都内でも集中できる部屋がたくさんあった

ホテルや会議室がある施設を借りると、様々なサービスが追加されていたり、複雑なメニューから選ばなければならず、価格も気になるし、予約も煩わしいと感じていました。
Airbnbは「部屋を借りるだけ」というシンプルさがとても良かったです。

##予めオーナーに「エンジニア合宿」の旨を説明すること！

オーナーによっては、「イベントみたいなことに使わないで欲しい」と考えている方も多いため、予約する際に「エンジニア合宿で使いたい」旨を説明すると良いでしょう。
オーナーによって、利用時に気をつけてほしいことが異なっていることがあり、主旨を伝える時に一緒に伺っておくと、お互いに気持ちよく利用できると思います。

##備品はできるだけ自分で持ち込むのが良い！

初めて利用する部屋の場合、wi-fi機器や延長コードなどは、自前で用意した方が良さそうです。
延長コードを忘れ、慌てて近くのお店で購入することになってしまいました。
「ワイヤレスインターネット設備」がある場合でも、初めて使う部屋の場合は、念のため、ポケットwi-fiなどを持っていくのが良さそうです。

##場所を予めGoogle Mapで確認しておく

伊豆にある部屋を借りて、数人で合宿をした時のことですが、その部屋に向かうための公共の交通機関がないことが判明し、レンタカーで向かいました。
場所の検討はついたのですが、道が分かりづらそうだったので、Google Mapで近くの建物や風景を確認してから出発しました。
Airbnbの部屋は、分かりづらい場所や、似たような建物が並んでいる場所にあることも少なくないので、出発前にきちんと確認しておきましょう。

##実際にやってみての感想

実際に、伊豆と都内で、Airbnbを利用したエンジニア合宿を行い、一晩でのネットサービス作りに挑戦しました。
特に伊豆では、メンバーの思い出を作ろうと、観光兼ねて合宿を行ったのですが、Airbnbを利用したことで、かなりプライベートな環境で合宿や親睦ができ、とても満足できました。
また、都内では、夕方頃から古民家風の部屋に集まり、終電まで勉強会を行い、帰れない、もしくは、帰らない人だけ宿泊するという形式の「プチ合宿」を行いました。
Airbnbを利用することで、会場費を安くおさえられたので、今後も気軽に、その様なエンジニア勉強会や合宿を行いたいと思っています。

【おすすめ記事】

➡[【初心者必読】独学で勉強するのにおすすめプログラミング書籍5選](http://programming-study.com/trouble/adventure-book/)
➡[学習サイトでプログラミングを独学して営業からエンジニアに転職](http://programming-study.com/case/change-job/)
➡[独学で勉強！プログラミング学習サイト18個まとめ](http://programming-study.com/trouble/programming-site/)
➡[1人でのプログラミング学習。効率を良くする5つの方法とは？](http://programming-study.com/trouble/programming-efficiency/)