OmniAICreator/Qiita-1.07M huggingface dataset:
three.jsで特定のオブジェクトの頂点にオブジェクトを配置する。

![スクリーンショット 2017-03-06 23.50.50.png](https://qiita-image-store.s3.amazonaws.com/0/108368/fde6d1c9-a711-5b0a-baa5-45c2a4e381b2.png)

本当は3DCGデータの周りに頂点をオブジェクトで打ちたかったのですが、夜遅くなったのでとりあえずここまでってやつ。

参考にしたサイト

http://qiita.com/edo_m18/items/ea34ad77238d0caf5142

#コード

```html:qiita.html

<html>
  <head>
  <title>My first Three.js app</title>
  <style>
    body { margin: 0; }
    canvas { width: 100%; height: 100% }
  </style>
  </head>
  <body>
    <script src="../build/three.js"></script>
<script>

var cube;
var renderer;
var scean;
var camera;



Init();

function Init(){



	const far = 2000;
	const w = window.innerWidth/10;
	const h = window.innerHeight/10;
	scene = new THREE.Scene();
	camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, far);
	camera.position.z = 0;
	renderer = new THREE.WebGLRenderer();
	renderer.setSize( window.innerWidth, window.innerHeight );
	document.body.appendChild( renderer.domElement );

	var geometry = new THREE.BufferGeometry();



var vertexPositions = [
    [-10.0, -10.0, 10.0], 
    [ 10.0, -10.0, 10.0], 
    [ 10.0,  10.0, 10.0], 
    [-10.0,  10.0, 10.0] 
];

var vertices = new Float32Array(vertexPositions.length * 3);
for (var i = 0; i < vertexPositions.length; i++) {
    vertices[i * 3 + 0] = vertexPositions[i][0];
    vertices[i * 3 + 1] = vertexPositions[i][1];
    vertices[i * 3 + 2] = vertexPositions[i][2];
}

var indices = new Uint16Array([
    0, 1, 2,
    2, 3, 0
]);

geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.addAttribute('index',    new THREE.BufferAttribute(indices,  1));

const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );

var mesh = new THREE.Mesh(geometry, material);
mesh.position = new THREE.Vector3(0,0,0);

mesh.position.x = 0;
mesh.position.y = 0;
mesh.position.z = 0;
scene.add(mesh);


for(var i =0; i<vertexPositions.length; i++ ){
const geometry = new THREE.PlaneBufferGeometry( 1, 1 );
  const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
  const plane = new THREE.Mesh( geometry, material );
  plane.position.x = vertexPositions[i][0];
  plane.position.y = vertexPositions[i][1];
  plane.position.z = vertexPositions[i][2];
  scene.add( plane );	
}


camera.position.z = +50;

};


const render = function () {
  requestAnimationFrame( render );
	
  renderer.render(scene, camera);
};

render();


</script>
 
  </body>
  </body>
```

緑色の正方形を作って、その周りに赤い長方形をうってます。

やってることは、簡単で、上でつくった緑いろのジオメトリの頂点の座標データを赤い長方形に渡しているだけです。

早く続きが描きたい。
AKIBA.swift×Swift愛好会 vol2 @ 渋谷 21cafe / 心得小記

*（講者後補）*

今天有點想睡覺，不過還是跑去 Swift 的聚會了。得到了還滿大的知識量，需要回家慢慢消化

首先是開場。

因為前三天是 try! Swift 2017 ，所以今天有著濃濃的 try! Swift 味道。開場還特別英日文交錯，還滿有趣的。

### LT #1

第一個是講了 Sequence/Collection 更延伸的東西
像是 RandomAccessCollection MutableCollection 等等一般比較不會注意到的東西。
了解這些的好處是可以知道要怎麼讓 Swift 加速

### LT #2

講了 iOS 新手要怎麼開始
包含推薦了一些書的章節，以及可以做什麼
最後還提到 mentor 其實是要領導和建議方向，而不是直接給新手答案
然後最重要的還是新手要自己會學習和研究

### LT #3

推薦了 try! Swift 的三個議程

- Isolating your Data Layer
- Color Me Surprised!: Architecting a Robust Color System with Swift
- Minimizing Decision Fatigue to Improve Team Productivity

### LT #4

講了怎麼自己新增看看 Swift 的 method 、compile 後，可以在 console 來試試自己新增的東西。
雖然沒有辦法真的成為 Swift 的 committer ，不過自己玩玩的話也滿有趣的，改天也來試試看。

### LT #5

很厲害的帶過所有的 initializers ，包含 class (reference type), struct (value type)以及在 extension 裡面要注意什麼。
甚至在 conforming 的同時，可以加上 required 這個屬性。
我自己對於 Swift 的 initialize 雖然是都有在用，不過這麼整合性的資料分享還是第一次聆聽到，非常受用，日後也可以更加活用。

### LT #6

講了 MVA ，是我自己以來追求的東西
全名是最小可行性架構
還有提到怎麼透過 MVP 的方式，幫 view controller 瘦身
覺得還滿受用的，等簡報出來再進一步複習

### LT #7
講了利用 Message Forwarding 的特性，隱藏 Namespace 的方法
改善過的程式碼的確拔掉了一些冗長的東西
對於用 RxSwift 說不定可以用到（？待實驗）
總之是一個滿有趣的東西

### LT #8

最後一個分享是 try! Swift 的工作人員
雖然這個研討會只有第二年，會眾人數竟然也從 300 成長到了 700 人
各種準備，像是紀念品袋子、名牌配發、發便當等等都變成很大的數量，
真的是辛苦了。
明年自己應該也會想要報名志工或是工作人員，盡一份心力。

### 結尾

每個聚會聽的題目，都可以聽到不同的人目前的心得和方向
也可以看見自己不足的地方
繼續加油唄！
Storm vs. Heron

まず、最初に書いておくがタイトルは釣りです。

[TwitterによるHeronの論文](http://dl.acm.org/citation.cfm?id=2742788)にて結構ボロクソに言われていたStormなのだが、最近調べてみたら実は結構しっかりと成長をしていることがわかってきた。

特に、StormにおいてはHeron論文がネガキャンになってしまっている気配があるので、Heron論文があげている当時のStormの問題点が最近のStormではどうなっているかを中心にメモを起こしておこうと思う。

ちなみに、 [TwitterによるHeronの論文](http://dl.acm.org/citation.cfm?id=2742788) が 2015/6 で、その当時の Storm 最新版は0.9.5くらいだった。なお、論文をちゃんと読んでないので論文中のStormの正確なバージョンを特定できていない（というか、Stormのバージョン表記を論文内から見つけられず..。だが、Twitterの論文の比較対象Stormは0mq利用のように読めるので0.8系相当のStormの可能性が高い。)

なお、今回の調査対象 Storm バージョンは v1.0.x。（xは調査ソースにおいてマチマチ。あしからず）

以下に、 [TwitterによるHeronの論文](http://dl.acm.org/citation.cfm?id=2742788) のStormへの問題意識とそこへのStorm現状という感じで書いておく。

# バックプレッシャー機能が無い

Heron論文当時には無かったがすでに実装されている。Heronの論文にあるSpout Backpressure に近い動きのものが実装されているような気配。

[Storm 1.0.0 release note] (http://storm.apache.org/2016/04/12/storm100-released.html) の Automatic Backpressure 参照。

# タスク単位の利用リソースを意識したスケジューリングが無い

新Stormでは、Spout/Bolt単位でのリソース要求に対応したResource Aware Schedulerが登場し、この問題に対応している模様。

Stormでは1つのWorkerプロセス内に多数のタスクを動作させるが、各BoltやSpoutのタスクのリソース(CPU、Memory)利用量を考慮したスケジューリングが昔はできなかった。
この影響でJVMやサーバサイジング時にTwitterでは非常に安全率を高くとらざるを得ず効率が悪かったらしい。

[Storm 1.0.0 release note] (http://storm.apache.org/2016/04/12/storm100-released.html) の Resource Aware Scheduler 参照。

# NimbusがSPOF

新StormではNimbus HAが実装されており、N重化が可能となっている。

[Highly Available Nimbus Design](http://storm.apache.org/releases/1.0.1/nimbus-ha-design.html)

# ZooKeeper負荷が高い

最新Stormでは、ZooKeeperを使わずに各Workerのheartbeatを処理できるようになっている。

[Storm 1.0.0 release note] (http://storm.apache.org/2016/04/12/storm100-released.html) の Pacemaker - Heartbeat Server 参照。

# 性能が出ない

特に v1.0がリリースされたタイミングで大幅な性能向上があった模様。

内部的な情報もあるけど出せないので、以下の公知の情報を参照されたい

[MICROBENCHMARKING APACHE STORM 1.0 PERFORMANCE (v0.9.0.1 vs. v1.0.1)](https://jp.hortonworks.com/blog/microbenchmarking-storm-1-0-performance/)

一応 v0.9.0.1 でも Netty 対応をしているはずなのだが、v1.0.1 では

* メッセージ数のスループットで約1.7～5倍性能向上
* レイテンシで 13倍～242倍向上

とかなりチューンナップがされた模様。

この数字自体はHeron論文の対Storm(0.8系?)の性能比と比較しても遜色無い数値に思える。


# その他

ほかにも、

* sliding window処理が trident 使わなくてもかける
* Redis連携によるステート処理がかける
* Debugやボトルネック解析のための細かい機能追加

等、さまざまな機能が追加されていてだいぶ使いやすくなっている。

（書いてて思ったが、ほとんど storm release note v1.0.0 をサマっただけだった。）
compassを利用したSkype勉強会ベースの勉強法

##compassを利用したSkype勉強会ベースの勉強法
Skype勉強会を利用した勉強が快適なので、ここにノウハウを書こうと思います。
Skype勉強会による勉強は、プログラミングから数学、学術まで、場合によっては受験も、すべての分野で使えるでしょう。
まずは、何を勉強したいかを決めます。まあ、iOSアプリケーションを作りたいでもいいし、暗号数学をマスターしたいでもいい。英語、フランス語勉強したいでもいいし、なんでもいいです。
現代において、専門学校行ってお金使うよりは、Skype勉強会を開いて、教えあいながら勉強した方が１００万倍賢いです。就職したときの評価も高まるでしょう。
では、方法を書こうと思います。

##compassにアカウントを作る。

ここを見ていただけたら分かる通り、Skype勉強会は日夜開かれています。

https://connpass.com/search/?q=Skype

compassにアカウントを作るのは、タダでできます。アカウント作りましょう。
セミナー開きたい内容は、自分が勉強したいことです。
全く理解できないのは問題ですが、この文章読める人なら、本を音読ぐらいできるでしょう。
わからなくても構いません。むしろ、わからないからセミナーを開くのであって、教える、または、一方的に教わるという意識より、共に学んでいくという意識でセミナーを開きましょう。
不安があれば、「質問されてもわからないことがあるかもしれません」という一文を加えましょう。
勉強したい内容を決めたら、本を指定しましょう。
僕の経験ですが、フリーの教材を使うより、本を買った方が人が集まりやすいです。
では、SkypeをPCにインストールし、アカウントを作成しましょう。
アイコンを設定し、
メニュー→ファイル→新規会話
で会話を作成すると、リンクがコピーできるようになると思うので、Skypeグループのリンクをcompassに貼りましょう。
「入室したら挨拶をお願いします」
という一文を添えると、挨拶してくれます。

プログラミング系のセミナーの場合は、実行しているところをSkypeの画面共有で共有できます。
本を読み進め、コードを書き写し、実行しているところを画面共有で共有しましょう。
join meと言うアプリを使ってもいいでしょう。

数学系セミナーの場合は、数式エディタを使うのもいいですが、Whiteboad foxも使えます。

https://whiteboardfox.com/

寛大にも開発者がタダで公開してくれてます。
ウェブベースのホワイトボードアプリで、手書きで書いたものを共有できます。
SurfaceかiPad Proにペンを使うと、書きやすいです。ペンタブを使っても構いません。

はっきり言うと、いろんな学習プラットフォームを僕はいくつか試しました。Courseraとか、University of the Peopleも試しました。Udemy、Udacityも試しましたね。
Skype勉強会以外の勉強プラットフォームは、はっきり言うと微妙なんですよね。コンテンツが古かったり、微妙だったり。動画は見てるとイライラするし。しかも高いし。

Skype勉強会は、マサカリ投げてくる人がいるかもしれませんが、基本はみんな優しいです。(マサカリは投げてきます）
個人的には、Skypeコミュニティはどんどん作って欲しいです。
教科書代はかかるかもしれませんが、基本はタダです。
フリーの教科書を使えば、全部タダでいけます。
専門学校行く金があれば、それでMac買って、Skype勉強会で勉強して、アプリ作るべきでしょう。
では、良い開発ライフを。
Geek Women x Microsoft - Geek になりたい人のためのミニカンファ - に行ってきた

# この記事について
参加レポート＆メモです。
技術的な考察や補足は出てきません。

## Geek Women Japanって？
技術を嗜む女性のコミュニティだそうです。
[Geek Women Japan](http://geekwomenjapan.github.io/20170304/gwjpms/index.html)

○○女子部みたいな言語単位の女性コミュニティもありますが、こちらは言語などを限定しない集まりみたいですね。
女性のコミュニティだからか、このイベントには託児サービスが用意されていて驚きました。

##参加の動機
わりと規模が大きなイベント(3トラック)だったことと、興味あるキーワードがいくつか入ったセッションだったからです。

## 内容メモ
### ビジネス現場におけるデータ活用 〜Pythonを添えて〜
[@a_macbee](https://twitter.com/a_macbee)さん

- データ分析の大まかな流れ
- データ分析をするために障壁になること
	- そもそもデータ取ってなかった
	- 上司の理解がなくてデータ分析させてもらえない
	- データを見たはいいけど、ああそうだよねで終わる

などなど。
今までデータ分析とは無縁の仕事で、最近少し関わり始めたところだったので、なるほどという感じでした。
なお、Pythonは出てきませんでした。

### AI を簡単に使える時代がやってきた！開発者のための AI 活用入門　
[@ayako_omori](https://twitter.com/ayako_omori)さん　　[スライド](https://docs.com/ayako-omori/3379/geekgirlsjapan-microsoft-20170304)

簡単って言っても数学分からないと使えないやつでしょ…？と思いながら参加しましたが、紹介されたCognitive Servicesは本当に簡単そうでした。
WebAPIでいろいろ遊べそうで、いい世の中になりました。

### IT業界で働くためのtips
**知識のなかの隙間を埋める**
[@omame19861](https://twitter.com/omame19861)さん
仕事をしていくだけだとできてしまう「知識のスキマ」をどう埋めていくかという話。登壇者の体験談として興味深く聞きました。　

**これからも Geek な女性であるために - Sheryl Sandberg が教えてくれた 3 つの事 -**
[@NahoInuyama](https://twitter.com/NahoInuyama)さん
Geekに限らず、働く女性なら関係がありそうなお話でした。 
女性は男性に比べて自分に自信を持ちづらく、ライフイベントで仕事を辞めてしまうことも多い、というのはなるほどと思いました。
紹介されたLeanInという本はぜひ読んでみたいです。

###LT大会
**自作有害コンテンツ検知してみよう**　[スライド](https://slides.com/maaya/201703gwjpms/)
[@maaya8585](https://twitter.com/maaya8585)さん
CognitiveServiceとGoogleChromeExtentionを使ってエロフィルターを作る話。LTでこんな実用的なものが出てくるとは…！面白かったです。

**エンジニアじゃないけどエンジニア向けイベントに紛れ込んでみた**
[@GOCCI](http://qiita.com/GOCCI)さん
勉強会に参加した話かと思ったら、コミュニティ運営の話でした。
エンジニアのコミュニティもエンジニアだけじゃ成り立たないんだなということが分かりました。事務スキル(運営スキル？)って大事ですね。

**エンジニア界隈の歩き方 ～未経験から始めるエンジニア生活～**
[@tokutoku393](https://twitter.com/tokutoku393)さん
LT登壇歴などのお話でした。エンジニアは産後復職もしやすいというお話は自分にとって新説でした。(男性社会かつ残業当たり前なイメージしかなかった)
会社により、という感じなのでしょうか。

**画像ファイルを使わずにHTMLとCSSでGeekWomanJapanロゴを描く**
[@se_lina08](https://twitter.com/se_lina08)さん
HTML5+CSS3でロゴ画像を再現するという試みでした。
こういう、技術と根気の無駄遣い(すみません、褒め言葉です)は個人的に大好きです。

**MVPのここが凄い！**
[@ayatokura](https://twitter.com/ayatokura)さん
Most Valuable Professionalアワードという、Microsoftさんの認定制度(?)の
お話。こういうのがあるとは知りませんでした。

## 参加してみて
登壇者はほぼすべて女性、参加者も9割くらい？女性という勉強会でした。
こういう環境だと女性も安心して参加できるのでしょうか。
女性ならではのお話もあり、技術の話もあり、よいバランスで楽しませていただきました。
参加後、コードを書きたくなりました。
現場からは以上です。
[memo] よく使うGIT 

##GitHubでFork/cloneしたリポジトリを本家リポジトリに追従する
参考：http://qiita.com/xtetsuji/items/555a1ef19ed21ee42873

* merge先：youraccount/Renshu.git
* merge元：example/Renshu.git

### 1.merge先のレポジトリをクローン

```
$ git clone git@github.com:youraccount/Renshu.git
$ cd Renshu
```
Branchの確認

```
$ git branch -a 
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
```

### 2.Remote Repository作成: upstream

```
$ git remote add upstream git://github.com/example/Renshu.git
$ git fetch upstream
remote: Counting objects: 1, done.
remote: Total 1 (delta 0), reused 1 (delta 0)
Unpacking objects: 100% (1/1), done.
From git://github.com/DQNEO/Renshu
 * [new branch]      develop    -> upstream/develop
 * [new branch]      master     -> upstream/master
```
Branchの確認

```
$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/upstream/master              #追加された
```
### 3. Merge

```
$ git merge upstream/master
Updating fe579f8..a1e70ae
Fast-forward
``` 

## Bashコンソールに現在のブランチを表示
~/.bashrc に追記

```
# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# User specific aliases and functions
#------------- insert for git start-----
function parse_git_branch {
    git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ [\1]/'
}
function promps {
    local  BLUE="\[\e[1;34m\]"
    local  RED="\[\e[1;31m\]"
    local  GREEN="\[\e[1;32m\]"
    local  WHITE="\[\e[00m\]"
    local  GRAY="\[\e[1;37m\]"

    case $TERM in
        xterm*) TITLEBAR='\[\e]0;\W\007\]';;
        *)      TITLEBAR="";;
    esac
    local BASE="\u@\h"
    PS1="${TITLEBAR}${GREEN}${BASE}${WHITE}:${BLUE}\W${GREEN}\$(parse_git_branch)${BLUE}\$${WHITE} "
}
promps

#-------insert for git end ---------

```

## Reset Pull from remote : リモートからのPullをリセット
```
# リモートから更新を取得
$ git pull origin <branch>

# やっぱりpull(fetch + merge)のうちmergeをやめたい
$ git reset --hard ORIG_HEAD
```

[Reference]
Gitでやらかした時に使える19個の奥義
http://qiita.com/muran001/items/dea2bbbaea1260098051


##リモートのgitブランチをローカルにチェックアウトする
現状のブランチ確認

```
$ git branch -a
* master
  remotes/origin/master
  remotes/origin/other_branch
```

最新の状態に更新
`$ git fetch`

リモートブランチからローカルブランチへチェックアウト
`
git checkout -b other_branch origin/other_branch
`



### Ref
http://sessan.hatenablog.com/entry/2012/11/04/132746

## .gitignore が反映されない時の対応
.gitignoreにあとから追加したファイルは反映されない
対応：キャッシュ削除
`git rm  --cached <target file>`

## Undo working files:作業ファイルの変更取消
one file
`# git checkout [filename]`
all files
`# git checkout .`

## How to change Git editor to vim. GitのエディタをVimにする 

`
git config --global core.editor 'vim -c "set fenc=utf-8"'
`
http://hikm.hatenablog.com/entry/20110323/1300887533

## git :: git rm で削除したファイルを復活させる
http://tm.root-n.com/unix:command:git:operation:reset_rm_recover
JSONのString型はNULL(になることないから)安全です

題名通り、JSONのStringはNULLとなることはありません。

参考： RFC7159, RFC8259,

# JSONの型

JSONは以下形があるとRFC7159で定められています。
>    A JSON value MUST be an object, array, number, or string, or one of
>   the following three literal names:
>
>      false null true
https://tools.ietf.org/html/rfc7159#page-5

また、RFC8259では以下のように書かれています。
>   A JSON value MUST be an object, array, number, or string, or one of
>   the following three literal names:
>
>      false
>      null
>      true
https://tools.ietf.org/html/rfc8259#section-3

とのことより、StringとNULLは別の型であることがわかります。
型が違うのだからStringといったらNULLが入ることは絶対にありません。

## でも、往々にして入ってくるし

結局は決めの問題で、システムがー...、案件がー...、担当者がー...、言語仕様がー...、値が無いときにどうするかという仕様でNULLを選んだんだとおもいます。[^1]

しかし、「XXXのJSONのAというValueはString」と決めただけであれば、NULLが入ってくることは偽りようのない不具合で、
もし値が無いことを表現したいのであらば、「値が無い場合はNULLとする」や「何からのFlagで値が無い事を示す」という仕様をつくるべきだと思います。


以上、JSONレスポンスの仕様にString型なのに「NULLが入ることは無い」と書いてしまった、自戒の念を込めて。


[^1]: PHPの`json_encode`とかで作ると、Stringとして作っててもNULLが入るとnullって入っちゃうと思います。 sample_php: `$arr = array('a' => null, 'b' => 2, 'c' => "3", 'd' => 4, 'e' => 5);echo json_encode($arr);`
初心者向け Vimでカーソルの移動速度を速くする方法

## 概要
- Vimはキーボードで自由自在に移動しますが、Macのデフォルトの設定では若干モッサリしており、ストレスを感じます。
- ちょこっと設定を変えるだけで快適に移動できるので、紹介します。

## 手順
- まず「システム環境設定」を選択します。

![スクリーンショット 2017-03-06 22.25.36.png](https://qiita-image-store.s3.amazonaws.com/0/142810/8772a38e-942b-f21c-f583-c680277afeb5.png "スクリーンショット 2017-03-06 22.25.36.png")

- 次に「キーボード」を選択します。

![スクリーンショット 2017-03-06 22.25.49.png](https://qiita-image-store.s3.amazonaws.com/0/142810/576eaaf7-5612-33e5-1be3-369ceb8fb5d8.png "スクリーンショット 2017-03-06 22.25.49.png")

- ここに「キーのリピート」と「リピート入力認識までの時間」の2つがあります。

![スクリーンショット 2017-03-06 22.19.34.png](https://qiita-image-store.s3.amazonaws.com/0/142810/8534c08f-3a8d-638b-3b48-ed9f3fe5e433.png "スクリーンショット 2017-03-06 22.19.34.png")

- この2つを共に一番右側に移動させます。

![スクリーンショット 2017-03-06 22.19.54.png](https://qiita-image-store.s3.amazonaws.com/0/142810/2165ce88-7ea6-1b7a-17d4-9fd258d92c76.png "スクリーンショット 2017-03-06 22.19.54.png")

- そして、設定を閉じてください。
- たったこれだけですが、驚くほどカーソルの移動が早くなります。ぜひお試し下さい。
ROS初心者がノード作成時に役立ったROSツール

#はじめに
初めてROSでノードを作成してみたので、その時に役に立ったツールを紹介します。
tutorialにも書いてあることですが、備忘録代わりに記事にします。

#実行環境
* OS：Ubuntu 14.04 LTS
* ROS：Indigo
* 言語：C++

#作成したノード
ROSのtutorialsにあるtf listenerを参考にノードを作成してみました。
http://wiki.ros.org/ja/tf/Tutorials/Writing%20a%20tf%20listener%20%28C%2B%2B%29

#役に立ったツール
##ノードの立ち上がり確認
```
rqt_node list
```
自分で作ったノードが表示されていることで確認できます。

##ログ確認
```
rqt_console
```
別のノードが立ち上がっている場合、設定ボタンでログを確認したいノードを選択しないとログが表示されないことに注意が必要です。

##ノード間の接続確認
```
rqt_graph
```
publish、subscribeが意図通りに設定できている場合、ノードとノードがトピックを挟んで矢印で接続されます。
逆に、どちらかが、設定できていないと、ノード名のみのグラフとなっています。
ノードが楕円、トピックが長方形で表現されています。

##pulishできているか確認する
```
rostopic info <topic-name>
```
advertiseでトピックを登録できているとPublishersのノードを見ることで確認できます。

##subscribeできているか確認する
subscribeの場合は実際にトピックをpublishしないとsubscribeできているか確認できないです。

```
rostopic pub <topic-name> <topic-type> [data...]
```
上記のようにコマンドラインでpublishして、rqt_graphを見ればsubscribeできているか確認できると思います。
jsdoでcytoscape.js

#概要
jsdoでcytoscape.jsを試して見た。

#grid

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/s/L/j/sLjt.jpg?t=1488799108)

http://jsdo.it/ohisama1/sLjt

#circle

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/g/V/d/gVdj.jpg?t=1488799293)

http://jsdo.it/ohisama1/gVdj

#breadthfirst
![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/m/E/v/mEvn.jpg?t=1488799412)

http://jsdo.it/ohisama1/mEvn

#concentric

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/C/S/R/CSRr.jpg?t=1488800456)

http://jsdo.it/ohisama1/CSRr

#random

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/E/K/E/EKEQ.jpg?t=1488800497)

http://jsdo.it/ohisama1/EKEQ

#サンプルコード

```
var cy = cytoscape({
    container: document.getElementById('cy'),
    style: cytoscape.stylesheet().selector('node').css({
        'content': 'data(id)',
        'background-color': 'darkorange'
    }).selector('edge').css({
        'content': 'data(id)',
        'color': 'blue'
    }),
    elements: {
        nodes: [{
            data: {
                id: 'A'
            }
        }, {
            data: {
                id: 'B'
            }
        }, {
            data: {
                id: 'C'
            }
        }, {
            data: {
                id: 'D'
            }
        }, {
            data: {
                id: 'E'
            }
        }, {
            data: {
                id: 'F'
            }
        }],
        edges: [{
            data: {
                id: 'ab', 
                source: 'A',
                target: 'B'
            }
        }, {
            data: {
                id: 'ac', 
                source: 'A', 
                target: 'C'
            }
        }, {
            data: {
                id: 'ad', 
                source: 'A',
                target: 'D'
            }
        }, {
            data: {
                id: 'be', 
                source: 'B',
                target: 'E'
            }
        }, {
            data: {
                id: 'df',
                source: 'D', 
                target: 'F'
            }
        }]
    },
    layout: {
        name: 'random',
        roots: ['A'],
        strictHierarchy: true
    }
});
```
CSS設計（Sassファイルの管理）についてぼんやりと考えていること

#CSS階層モデル
土台の部分から順に
1. リセット/ノーマライズ
2. グリッドシステム（レイアウトモジュール）
3. ベース（要素の設定・装飾）
4. モジュール（クラスの設定・装飾、各種パーツ）
5. 微調整用CSS（マージン調整など）

WordPress案件が多いのでそれに合わせてネーミングとかは行う。
1~5の階層でそれぞれパーシャルSassファイルを作ってstyle.scssで統合してコンパイルする。
1~3をまとめたものはeditor-style.scssでまとめてeditor-style.cssに出力する。

#Sassファイル構成
## _parameter.scss
サイトで使う変数をまとめる。ブレイクポイントやテーマカラー、フォント関連など。

## _reset.scss
基本的にNormalize CSSをコピペ。
重複/上書きがノーマライズCSS自体に結構あるのでその辺整理しといたものを作っておくといいかもしれない。
これに追加で、

```scss
* {box-sizing: border-box;}
a img {border: none;}
```
を入れておく。`a img`は古いIE対策。さすがにIE11時代に入ってからは不要だと思うけど。

## _grid.scss
レイアウトを制御するグリッドシステムを入れる。
BootstrapやFoundationのような巨大フレームワークよりはPure.cssなど、グリッドシステムのみに絞ったフレームワークを採用する方がいい。
Bootstrapからグリッドのところだけを抽出するのも良いけど、保守を受け継いだ人がフルスペックのBootstrapを使っていると勘違いしてしまうのもよろしくないかなーと。
私の場合は自家製の[lecss](https://github.com/akinori-kawamitsu/lecss)を使っている。
ここまでの階層はすべてのウェブサイトで共通に使える。
リセットとグリッドは大体いつも一緒に使うので、１ファイルにまとめるのもいい。

## _base.scss
h1～h6など、クラス名を付けない状態での要素の装飾などを規定する。
WordPressではここまでのscssをeditor-style.scssにまとめ、editor-style.cssにコンパイルする。

## _module.scss
個々のウェブサイト全体のパーツなどの設定はここに書く。
今までこのファイルは1つのファイルにしていたが、最近は細分化した方がよいのではないかと考えている。
メディアクエリごとに分けた場合、コンパイル後のファイルサイズが小さくできる。これには欠点もあって、PCサイズの装飾を変更する際、間違ってスマホサイズ用のファイルを編集してしまう、といった取り違えのリスクがある。

保守のしやすさを追求するのなら、WordPressの案件の場合、各テンプレート（home, archive, page, singleなど）毎に分割し、同一ファイル内でメディアクエリを設定するとよいと思う。
現在1ファイルでやっているが、行数が多くなると修正のたびに該当箇所を探し出すのに時間がかかる。

## _utility.scss
マージン、フォント、色など、1ヶ所だけ特別に調整したいという用途用に作られたクラスをまとめる。

#クラス名のネーミング問題
今のところ、（機能）（使用箇所）（装飾）の順でハイフンつなぎ、というやり方をしているけど、100%ちゃんと運用できているわけでもなくて悩みの種になっている。
もうちょっと厳密なルールを検討しなければと感じている。
また、リストや表など、構造ががっちり決まっているものに対しては、`.class li {}`という感じで、詳細度を上げてもよい例外としている。これは、確実かつ大量に存在する子要素の一つ一つの項目にクラス名を付けるのはhtml側の負担が大きいと考えているため。

ただ、最近はこれが必ずしも正解とは言えないような気がしている。リストや表などの特定の箇所のみ、他と違うスタイルを適用したい場合に詳細度地獄が待っている。
Androidで複数レイアウトが重なっているものをタッチした時の挙動について

#やりたいこと
以下のレイアウトで、TextViewをタッチした時にRelativeLayoutのタッチ処理を呼ぶ方法を調べます。
- RelativeLayout
- - LinearLayout
- - - TextView

##前提
クリックと同様に、レイアウトの重複部分をタッチした時に実行される処理は一番上のレイアウトの処理です（今回の場合でいえばTextView)。
しかし、クリックと違うところがあります。それは、タッチの場合は親要素の処理を実行するか否かを指定できるという点です。

クリック：　一番上のレイアウトの処理のみ行われる。
タッチ：　親要素に対して処理を実行させるか指定できる。

###前提の検証
上の内容だと何を言っているのかわかりづらいですね。笑
実際にソースを書いて処理の動きを見て見たいと思います。

```MainActivity.java
        TextView textView = (TextView) findViewById(R.id.textView);
        LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
        RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.relativeLayout);

        relativeLayout.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                System.out.println("RelativeLayout");
                return false;
            }
        });

        linearLayout.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                System.out.println("LinearLayout");
                return false;
            }
        });

        textView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                System.out.println("textView");
                return false;
            }
        });
```
画面はこんな感じになっています。
![Screenshot_1488667440.png](https://qiita-image-store.s3.amazonaws.com/0/146508/f981df89-d695-857f-d532-831ccf12c97b.png)

SAMPLE001をクリックするとconsoleには
**textView**
**LinearLayout**
**RelativeLayout**
が表示されました。

次は各処理を以下の通り変更します。
```return true;```

SAMPLE001をクリックするとconsoleには
**textView**
のみ表示されました。

つまり、onTouchの返り値によって以下のように処理の仕方が異なっています。
trueの場合は処理を親要素に渡さない。
falseの場合は処理を親要素に渡す。

##検証
さっきのソースを以下のように書き換えると、RelativeLayoutのタッチイベントを実行することができました！

```MainActivity.java
        textView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                System.out.println("textView");
                RelativeLayout grandParent = (RelativeLayout) v.getParent().getParent();
                grandParent.onTouchEvent(event);
                return true;
            }
        });
```


## 別のやり方
onTouchにはこれ以外にも親要素のtouchイベントを呼び出す方法があります。
それが、ActivityクラスのdispatchTouchEventをOverrideする方法です。

touchイベントって一番子供のレイアウトの処理から始まりますよね。
dispatchTouchEventは子レイアウトに処理を渡すかどうかを決定し、自分のtouchイベント処理を実行させる二つの機能を持っています。
つまり、touchイベントが発生すると。
A（親レイアウト）のdispatchTouchEventが呼ばれる。
↓
・子レイアウトが存在する場合は、子レイアウト（B）のdispatchTouchEventを呼ぶ。
・子レイアウトが存在しない場合は、onTouchイベントを呼ぶ。


なのでActivityクラスのdispatchTouchEventをOverrideすると、子レイアウトのonTouchイベントを呼び出す前に処理を行うことができます。
また、このメソッド内でreturn true;を返すと子レイアウトに処理を行わせないこともできます。

例えば、

```MainActivity.java
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        // RelativeLayoutがクリックされた時に行いたい処理を書く
        return false;
    }
```

こうすると、子レイアウトのonTouchが呼ばれる前にRelativeLayoutがタッチされた時に行いたい処理を行うことができます。

と基本的なことを書きました。
今度はもう少し実際に直面した問題に近い内容で書いてみようと思います。
Bashで正規表現マッチした文字列を取り出す

```sh
#!/bin/bash

version="4.10.1"

if [[ ${version} =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
  all=${BASH_REMATCH[0]}
  major=${BASH_REMATCH[1]}
  minor=${BASH_REMATCH[2]}
  patch=${BASH_REMATCH[3]}

  echo ${all}    # 4.10.1
  echo ${major}  # 4
  echo ${minor}  # 10
  echo ${patch}  # 1
fi
```

## ポイント

- 比較部分は `[[ ]]` で囲う
- 比較部分は `=~`
- 右辺の正規表現部分は `""` で囲わない
- 右辺の正規表現部分でマッチさせて取り出したい部分をカッコで囲う
- `${BASH_REMATCH[0]}` にはマッチした文字列全体が入る
- カッコで囲った部分が `${BASH_REMATCH[1]}` 以降順番に得られる
swiftサーバーサイドであるperfectの入門についてのまとめ

#はじめに
本家の[Getting standard](https://github.com/PerfectlySoft/PerfectDocs)を元にやっていきます

##実行環境

|PC|MacBook Pro (Retina,13-inch,Mid 2014)|
|:-:|:-:|
|swift version | 3.0.2|
|OS|macOS Sierra 10.12.3|
|XCode|8.2.1|

#導入方法

まず[PerfectTemplate](https://github.com/PerfectlySoft/PerfectTemplate)をクローンします

```terminal
git clone https://github.com/PerfectlySoft/PerfectTemplate.git
```

その後ディレクトリを移動し、ビルドをしてソケットを解放します

```terminal
cd PerfectTemplate
swift build
.build/debug/PerfectTemplate
```

おそらく

```terminal
[INFO] Starting HTTP server localhost on 0.0.0.0:8181
[INFO] Starting HTTP server localhost on 0.0.0.0:8080
```

と出てくると思うので、

[0.0.0.0:8080](http://0.0.0.0:8080/)に移動し、`Hello, world!`とブラウザに表示されれば成功です

いままのままではXCodeで開けないので、クローンしてきたプロジェクトをXCodeのプロジェクトにします


```terminal
swift package generate-xcodeproj
```

と実行すると`PerfectTemplate.xcodeproj`を作成されます

##XCodeでの実行

まず`.build/debug/PerfectTemplate`の実行を止めます

次にXCodeで開いたものを実行します

ビルドターゲットが２つありますが、
![スクリーンショット 2017-03-06 21.59.08.png](https://qiita-image-store.s3.amazonaws.com/0/96484/c77e37b2-25ec-4fd6-3aed-83b9661eb8f3.png "スクリーンショット 2017-03-06 21.59.08.png")

上の方はただのビルド？で下のexecの方は`.build/debug/PerfectTemplate`の実行まで行ってくれます

よって、カバンの方でビルドした場合、改めて`.build/debug/PerfectTemplate`を実行する必要があります
vimで閉じタグを挿入するpluginを作ってみた

## tl;dr
 　Vimのpluginを作りました。コマンド(InsertClosingTag)を使用するとカーソル位置に閉じタグが挿入されます。下の図のようなものです。INSERTモード中に呼び出してご利用ください。
リポジトリはこちら https://github.com/rchaser53/insertclosetag

![insertclosingtag.gif](https://qiita-image-store.s3.amazonaws.com/0/99025/c2fbf1f5-e9e8-b8f4-66e9-45c8e11f7de6.gif)


## いきさつ
　そういえば開発でVimを使ったことない…
=> とりあえず趣味の開発に使ってみよう
=> React使ってるから閉じタグ入れるplugin入れよう
=> vim-closetagがあるじゃん。これ使おう。
![nya-n2.gif](https://qiita-image-store.s3.amazonaws.com/0/99025/47c243a0-fdb4-096b-c061-31fd7f041618.gif)


　:innocent::innocent::innocent:

　諦めて自作しようか…


##　開発メモ

　というわけでVimの勉強にもなるし、大して難しくもないだろうととりあえず挑戦してみました。こっからは開発のメモになります。これからVimのplugin作ってみたいという~~奇特な~~方はご参考にどうぞ。

### insert modeの行末
　どうやら文字や文章を挿入するなどして関数中でカーソル位置を移動させてしまった場合は、基本的にcol('.')とline('.')で位置を取得し、cursorで元に戻るというパターンが多いようです。通常なら特に問題がないわけですが、insert modeで行末にカーソルがある状態でcursorで元の位置に戻ろうとすると次の行に勝手に移動します。おそらく改行コードの後ろにcursorで移動しようとした結果、次の行に送られてしまうのだと思われます。気づくのに結構時間を取られました。しんどい。

### 正規表現
 普段JavaScriptとかの正規表現しか触っていないので結構苦戦しました。「\zs」と「\ze」がすごい便利でした。「<12345>」を「<\zs1\(.*\)5\ze>」で検索すると「12345」が取得できるのとても良いです。（例は良くない。)

### 細かい文法の皆様
　.variable.とか（変数の結合に使用）とか変数のスコープとか、大なり小なりハマりどころが多い文法に感じました。いちいち罠にかかりながら進んだので結構時間がかかりました。


## むすびに
　いやいいですねVim。色々と好きなように設定ができて男心をくすぐります。今回は文字列を操作するpluginを作ってみたので、次はスニペットとか外部アプリの呼び出しとかやってみようかなと思います。もう少し他の方のpluginを見て書き方やテストの方法を学習して次に挑もうと思います。
NLogでログを記録する

.NET Frameworkを使っていてログを記録するときに使用できるライブラリNLogの使い方をメモします。

# NLogの特徴
NLogはログ収集のプラットフォームであり、.NETのほか、NETSTANDARD、Xamarin、Silverlight、Windows Phoneなどをサポートしています。
ログ出力先や出力フォーマットの定義はconfigファイルにより指定可能です。
また、自分で好きな出力先(Target)をコーディングして追加することも可能です。

# NLogの導入
* 環境
 - Visual Studio 2015 Community
 - NLog 4.4.3

にて試しました。

1. サンプルプロジェクト作成
今回はC#にて任意のプロジェクトを作成しました。
フォームをひとつ持つWindowsアプリケーションです。

2. NLogライブラリの導入
プロジェクトを右クリック→NuGetパッケージの管理からNLogを検索し、**NLog.Config**を選択して、右側のインストールボタンにてインストールします。
このとき、必要とされるライブラリが同時にインストールされます。
![NLog-fig1.jpg](https://qiita-image-store.s3.amazonaws.com/0/52878/d1666c32-f8c9-ff79-1a37-2e6160641a7d.jpeg)

3. ロガー設定
ログを出力したいクラスにて、ロガーを設定します。
`private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();` 
4. ログ出力
ログを出力したい箇所で、設定したロガーを用いて次のように記述。 

```c#:Program.cs
        static void Main()
        {
            logger.Info("===== Program Start =====");
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
            logger.Info("===== Program End =====");
        }
``` 

# 設定ファイル
NLogの出力先や出力フォーマットを設定するのは、NLog.ConfigというXML形式のファイルです。
NuGetにてNLogライブラリをプロジェクトにインストールすると、自動的にプロジェクトに追加されています。
これを編集して、以下のようにすると、
実行モジュールの存在するフォルダに`log`という名前のフォルダを作成し、その中に日付ごとの名前のログファイルを作成します。

```xml:NLog.Config
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
      autoReload="true"
      throwExceptions="false"
      internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">

  <targets>
    <target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
                layout="${longdate} [${uppercase:${level}}] ${message}" />
  </targets>

  <rules>
    <logger name="*" minlevel="Debug" writeTo="f" />
  </rules>
</nlog>
```

# 実行例
上記のサンプルに追加して、フォームにボタンを1つおき、そのクリックイベントハンドラにてログを出力するようにします。

```csharp:Form1.cs
    public partial class Form1 : Form
    {
        private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            logger.Info("button1 Pushed!");
        }
    }
```

プロジェクトをビルドし、実行してボタンを何回か押してアプリケーションを終了すると、以下のようなログファイルが出力されます。

```
2017-03-06 21:32:06.0151 [INFO] ===== Program Start =====
2017-03-06 21:32:07.5155 [INFO] button1 Pushed!
2017-03-06 21:32:08.0780 [INFO] button1 Pushed!
2017-03-06 21:32:08.4531 [INFO] button1 Pushed!
2017-03-06 21:32:09.3127 [INFO] ===== Program End =====
```

# 参考
[Configファイルの記載方法](https://github.com/nlog/NLog/wiki/Configuration-file)
[ログの記載フォーマット](https://github.com/nlog/nlog/wiki/Layout-Renderers)
Golangでプレミアムフライデーかどうか判定する

[PHPでプレミアムフライデーかどうか判定する](http://qiita.com/qube81/items/9d17ddc4aa8ffb276bc9) のGolang版。

Goは日付の扱いが難しいですね。もっといい方法がありそうです。

```go
package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Println(IsPremiumFriday("2017-02-24")) // true
	fmt.Println(IsPremiumFriday("2017-02-25")) // false
	fmt.Println(IsPremiumFriday("2017-03-31")) // true
	fmt.Println(IsPremiumFriday("2017-12-29")) // true

}

// IsPremiumFriday returns bool
func IsPremiumFriday(datestr string) bool {

	// 入力日付
	d1, err := time.Parse("2006-01-02", datestr)
	if err != nil {
		return false
	}

	// 翌月の初日を得る
	d2 := d1.AddDate(0, 1, 0)
	d2 = time.Date(d2.Year(), d2.Month(), 1, 0, 0, 0, 0, time.UTC)

	// 一日ずつ減らして最初の金曜日を設定
	for d2.Weekday() != time.Friday {
		d2 = d2.AddDate(0, 0, -1)
	}

	return d1.Equal(d2)
}
```
iTunes - App Storeで公開したアプリのURLについて


# URL

## Link Maker
国とMedia Type(アプリなので"App"を指定)を選択し、
アプリ名で検索すると、
アプリバナーやリンクを生成してくれる、iTunesのサービス。
https://linkmaker.itunes.apple.com/


## アプリURL
一般にアプリのURLは、以下のような形式になっている。

https://itunes.apple.com/{参照国コード}/{アプリ名}/{アプリid}?l=ja&ls=1&mt=8


## 短縮アプリURL
以下の形式で短縮URLが用意されている。  

http://appstore.com/{アプリ名}
http://appstore.com/{開発者名}/{アプリ名}


# Smart App Banner

以下のmetaタグを設定すると、
Mobile Safariでアプリバナーを表示してくれる。  
 
![smartbanner_2x.png](https://qiita-image-store.s3.amazonaws.com/0/6968/1a75803b-db67-1160-84c2-bf3fdfce0a7d.png "smartbanner_2x.png")

~~~index.html
<meta name="apple-itunes-app" content="app-id=myAppStoreID, affiliate-data=myAffiliateData, app-argument=myURL" />
~~~


# 参考

App Store公開前にアプリURLを知る方法
http://qiita.com/akatsuki174/items/92bcf53d04a77cf293c0


Creating easy-to-read short links to the App Store for your apps and company
https://developer.apple.com/library/content/qa/qa1633/_index.html


Promoting Apps with Smart App Banners
https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html
Basic Operators - Logical Operator


*論理演算子 logical operator* は Bool型の値 *true* または *false* を以て条件判断を行う。Swift では下記3つが用意されている。

* 論理 NOT (!a)
* 論理 AND (a && b)
* 論理 OR (a || b)

## 論理 NOT 演算子
*論理 NOT 演算子 (!a) は与えられたBool型の値を反転させて判断を行う。
与えられた値が true ならば false として、false が与えられたならば true として判断を行う。

論理 NOT 演算子は接頭演算子なので、対象の値のすぐ前に、スペースなど無しで記述する。これは "a ではない" と読める。

```swift
let allowedEntry = false
if !allowedEntry {
     print("ACCESS DENIED"
}
// false が反転され、true になるので、"ACCESS DENIED"がプリントされる。
```

論理 NOT 演算子は "a ではない" という働きなので、 `if !allowedEntry` は "もし allowedEntry ではないならば" となる。
上記サンプルでは allowedEntry に 格納された false が反転して true として判断されるため、if文最初の処理が実行され、 "ACCESS DENIED" がプリントされる。

## 論理 AND 演算子
*論理 AND 演算子 (a && b)* は a, b どちらも true である場合のみ、判定結果を true とする。
もし a もしくは b どちらかが false の場合、論理 AND 演算子の判定結果は false となるが、もし a が false だった場合、そもそも b が true か false かの判定は一切おこなわれない。

```Swift
// ドアのパスワードが入力されている(true)
let enteredDoorCode = true

// 網膜スキャン通過に失敗(false)
let passedRetinaScan = false

if enteredDoorCode && passedRetinaScan {
     print("Welcome!")
} else {
     print("ACCESS DENIED")
}
// passedRetinaScan が false なので "ACCESS DENIED" がプリントされる。
```

上記サンプルがもし、`if passedRetinaScan && enteredDoorCode` だった場合、passedRetinaScan がすでに false なので、enteredDoorCode が true か false かの判定すらされずに、論理 AND 演算子の結果としては false となり、"ACCESS DENIED" がプリントされる。

## 論理 OR 演算子
*論理 OR 演算子 (a || b)* は、a と b どちらかでも true ならば、判定結果を true とする演算子。

論理 AND 演算子がそうであるように、もし a がすでに true ならば、b が true か false か判定せずに true を返す。

```swift
let hasDoorKey = false
let knowsOverridePassword = true

if hasDoorKey || knowsOverridePassword {
     print("Welcome!")
} else {
     print("ACCESS DENIED")
}
// knowsOverridePassword が true なので、"Welcome!" がプリントされる。
```

## 論理演算子を複合させて使う
下記のように、複数の論理演算子をつなげて使うことができる。

```swift
if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {
     print("Welcome!")
} else {
     print("ACCESS DENIED!")
}
// "Welcome" がプリントされる
```

複数の論理演算子がある場合左から判定していくので、

* 最初に enteredDoorCode && passedRetinaScan が判定される。enteredDoorCode = true, passedRetinaScan = fales なので false が返る。
* enteredDoorCode && passedReticaScan の結果が false なので、 false || hasDoorKey という式になり、hasDoorKey が false なので false となる。
* false || knowsOverridePassword という式になり、 knowsOverridePassword = true なので true が返る。
* 複数の論理演算子の判定結果は true となるので、Welcome! がプリントされる。

## Explicit Parentheses
複数の論理演算子が続く場合、コードを読みやすくするために式を *()* で括ることができる。

```swift
if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword {
     print("Welcome!")
} else {
     print("ACCESS DENIED!")
}
// "Welcome" がプリントされる
```

上記のように ( ) で括ることで、最終結果に影響することなく式を読みやすくすることができる。
ownCloudにiPhone(icloud)から動画をアップロードできない問題の解決方法

#ownCloudにiPhoneから動画をアップロードできない問題
RasPiでownCloudサーバを立てるときに、ドハマりした失敗？例です。
ネットで調べても情報がなかったのでなにかの参考なればと。
（アップロード時のサイズ上限は超えていないのにアップロードできない問題）
![Photo-2017-02-26-09-38-05_5602.PNG](https://qiita-image-store.s3.amazonaws.com/0/168808/bc4597bc-040e-d2f4-045c-7100b1520fd6.png)


#【試した環境】
・RasPi3 + ownCloud + 外付けHDD
・携帯（iPhone6（容量一杯） + iCloud（写真共有設定）)　←　これが元凶

#【現象】
・ownCloud へ携帯に保存してある古い動画がアップロードできない（エラーになる）
 （直近取ったファイルはアップ可能。時間がたつとアップロード出来なくなる）
　**（ファイルサイズやファイル形式は関係無いようで、撮影してからの時間といつ再生したのかが影響するようです）**

#【推定原因】
・iPhoneでiCloudを使用している場合、携帯の空き容量が少なくなると、使用頻度の低いファイルをiCloudへ保存している。
 （サムネイル用の画像だけiPhoneに残しておいて、再生の度にローカルへダウンロードしている）
　このため、ownCloud に **「手元にファイルがあるように見えるファイル」**をアップロードしようとすると、実際にはローカルにデータがないためエラーになるようです）

#【対策】
・一度再生して手元にデータをダウンロードした状態から、アップロードすることで回避できます。

#【注意点】
iPhoneの[写真]からiCloudへ共有を使うとファイル名が**撮影した日付**ではなく、**再生した日付**になってしまいます。
ローカルにデータを持った状態で、ownCloud（アプリ）からアップすると**ファイル名は撮影日**にすることができます。
phpでプレミアムフライデーかどうか判定する

今更ですが。もっと短く書けそう。

```php
<?php
function is_premium_friday(Datetime $date) {
	return $date->diff(new DateTime(sprintf('last Fri of %s', $date->format('Y-m'))))->format('%d') == 0;
}


var_dump(is_premium_friday(new Datetime('2017-02-23'))); // false
var_dump(is_premium_friday(new Datetime('2017-02-24'))); // true
var_dump(is_premium_friday(new Datetime('2017-02-25'))); // false
var_dump(is_premium_friday(new Datetime('2017-03-31'))); // true
```
UnityでListの中身をDebug.Logに表示する

ListをそのままDebug.Log(List);とすると、型を教えてくれるだけだ。

```C#:ListDebugLog.cs
// Use this for initialization
void Start(){
    for(int i = 0; i < 10; i++)
    {
        list.Add(i);
    }

    SwhoListDebugLog(list);
}

public void ShowListDebugLog<T>(List<T> list)
{
    Debug.Log(list);
}
```

![ListDebugLog1.png](https://qiita-image-store.s3.amazonaws.com/0/58864/cf55df5a-c256-e8cf-3234-25ac279c2872.png)


とても不便なので、こんな感じに実装したことを備忘録代わりにここに記述しておく。

```C#:ListContentsDebugLog.cs
List<int> list = new List<int>();

// Use this for initialization
void Start () {
    for(int i = 0; i < 10; i++)
    {
        list.Add(i);
    }

    ShowListContentsInTheDebugLog(list);
}

public void ShowListContentsInTheDebugLog<T>(List<T> list)
{
    string log = "";

    foreach(var content in list.Select((val, idx) => new {val, idx}))
    {
        if (content.idx == list.Count - 1)
            log += content.val.ToString();
        else
            log += content.val.ToString() + ", ";
    }

Debug.Log(log);
}
```

これよりも、もっと便利な書き方があれば是非教えて頂きたい。
rootアカウントに設定したMFAデバイスが時刻ずれした時の再同期方法

#はじめに
IAMユーザーのMFAデバイスを再同期する方法はドキュメントに載っている。
http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_mfa_sync.html

rootアカウントのMFAデバイスが故障した時の対応も載っている。
http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_mfa_lost-or-broken.html

でもrootアカウントのMFAデバイスの再同期の方法が載っていない。（はず）

rootアカウントのMFAデバイス設定はrootアカウントでしかできない。
もちろんコンソール上でrootがroot自身のMFAデバイスを再同期することは可能。

問題はコンソールにサインインする時点で時刻ずれが起こっていた時。
IMAユーザーのMFAデバイスなら、時刻ずれしても、違うユーザーで再同期できるので問題ない。

rootアカウントだと困る。
なので調べました。

#1.rootアカウントでサインインを試みる
- MFAデバイスが設定済みの前提です。
- https://console.aws.amazon.com/console/
- メールアドレスとパスワードを入力し、「Sign in using our secure server」で画面遷移。

#2.認証コードを入力しないで画面下部のリンクへ飛ぶ
- 赤枠で囲っている箇所からリンクで飛びます。
- ちなみに画面上部のエラーは同期がずれてるデバイスで認証コードを生成してサインインしようとした時に（も）出ます。
    - 「There was a pronlem」
    - 「The authentication code you entered is invailid. Please make sure that you have correctly entered your authentication code.」
- 私の環境だと8ヶ月くらいぶりにデバイスを使おうとしたらずれていました。

![rootのMFA再同期1.JPG](https://qiita-image-store.s3.amazonaws.com/0/155963/9708a2c7-d34f-6c47-7840-b4a27d4dbded.jpeg)

#3.もう一回アドレスとパスワードを入力する
- 1.と同じ画面に飛びます。
- 「あれ？」と思いますが、再度メールアドレスとパスワードを入力し、「Sign in using our secure server」で画面遷移。

#4.認証コードを2回入力して再同期
- MFAデバイスで2回コードを生成し、「Re-sync...」をクリックすれば完了。
- ちなみに右側の「Contact Us」をクリックすれば、故障時等のサポートページに飛ぶ。
    - https://aws-portal.amazon.com/gp/aws/html-forms-controller/contactus/aws-token-support-v2
    - 電話番号を入力して、コールしてもらって口頭対応のようです。
    - 英語でかかってくるので、「日本語でお願い」と英語で頼む必要があるそうです。

![rootのMFA再同期2.JPG](https://qiita-image-store.s3.amazonaws.com/0/155963/b55ecbb4-96d1-ccf2-3e20-c25786583d40.jpeg)


#おわりに
物理MFAデバイスは時刻ずれが怖いですね。
仮想MFAデバイスなら大丈夫なものなのかは知りません。

以前行ったOpsJAWSで聞いた話。
ソフトウェアMFAには3種類ある。

- Saasタイプ
- モバイルタイプ
- ローカルアプリタイプ（New!）

某社ではローカルアプリタイプであるWinAuthをEC2上で動かして、
必要時にだけEC2を立ち上げて認証して…という仕組みにしているらしい。
うろ覚えです。

以上です。
BiopythonでFASTAファイル操作　その２：reverse complementをとる

BiopythonのSeqIOを用いて、fastaファイル中の配列の相補配列を一気に書き出してみます。

まずは、標準出力に打ち出してみます。区別のため、def lineの頭に'RC_'が付くようにします。

```py3

# revComp_stdout.py

import sys
from Bio import SeqIO

mfa_in = sys.argv[1]

for record in SeqIO.parse(mfa_in, 'fasta'):
	rc_desc = 'RC_' + record.description # add 'RC_' to the def line
	rc_seq = record.seq.reverse_complement()
	print('>' + rc_desc)
	print(rc_seq)
```

結果をファイルに保存するには、リダイレクトを使います。
```
python revComp_stdout.py input_fasta > RC_result.mfa
```

これでも便利なのですが、毎回結果ファイルに名前を与えなければいけないので、'RC_'を入力ファイル名につけたものをカレントディレクトリに出力するようにしてみます。


```py3
# revComp_file.py

import sys
import os
from Bio import SeqIO

records = []
for record in SeqIO.parse(mfa_in, 'fasta'):
    record.id = 'RC_' + record.id
    record.description = record.id + ' ' + record.description.split(' ', 1)[1]
    record.seq = record.seq.reverse_complement()
    records.append(record)


rc_file = 'RC_' + os.path.basename(mfa_in) # remove upper path

SeqIO.write(records, rc_file, 'fasta')

```
ここでは、SeqIOの'O'のほうも使いました。SeqRecord objectをため込んで、一気に書き込んでいます。同名のファイルがある場合には上書きされてしまいますので、注意が必要です。
IUPACのmixed base一文字表記（R=A/G, M=A/C, B=C/G/Tなど）やgap ('-')もうまく扱ってくれるので、便利です。
named profiles を使って aws-cli の複数の認証情報を管理する方法

会社と個人用のプロファイルを分けたい場合などに

# (おさらい)aws-cli で認証する方法

```
$　aws configure
```

# プロファイルに名前を付けたい場合

```
$　aws configure --profile #{name}
```

# プロファイルの一覧を確認したい場合

~/.aws に格納されているファイルを見る

```
$ cat ~/.aws/config

[default]
[profile name]
```

- `[default]` は、 `profile` オプションを付けずに `aws configure` したプロファイル

```
$ cat ~/.aws/config

[default]
aws_secret_access_key = ....
aws_access_key_id = ....
[profile name]
....
```

# デフォルトのプロファイルを設定したい場合

環境変数 `AWS_DEFAULT_PROFILE` にプロファイル名を設定する

# 参考

- [Configuring the AWS Command Line Interface - AWS Command Line Interface](http://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-getting-started.html#cli-multiple-profiles)
testssl.sh の Secure Client-Initiated Renegotiation チェック

自分が現象を忘れないようにするためのオチの全くないメモです。

[testssl.sh](https://testssl.sh/) はとても便利に使えるサーバの SSL/TLS 関連のセキュリティチェックのツールです。

ですが、このチェックの中で "Secure Client-Initiated Renegotiation" と呼ばれるチェック (おそらくは CVE-2011-1473 ではないかと) が一部のサーバで脆弱であると報告されます (`VULNERABLE (NOT ok), potential DoS threat` と出る)。

ここで行っているチェックはこんなコマンドを実行しています。

```
echo R | openssl s_client -legacy_renegotiation -starttls smtp -msg -connect server:port 
```

脆弱なホストの場合、この返り値が 0 に、そうでない場合は 1 になるようです。

Apache の mod_ssl の場合はこれでうまくチェックがいくようですが、以下のサーバの場合、対策されているバージョンであっても、ここで 0 が返る (つまり openssl s_client が成功する) ようです。

* postfix
* exim (の一部?)
* vsftpd
* proftpd (公式では "not" と書かれてる気がするけど手元では脆弱と報告される)

手元の postfix (2.11.8) に対してやってみると

```
$ ./testssl.sh -R -t smtp myserver.example.com:587

  : (snip)

 Using "OpenSSL 1.0.2-chacha (1.0.2i-dev)" [~183 ciphers]

  : (snip)

 Testing for Renegotiation vulnerabilities 

 Secure Renegotiation (CVE-2009-3555)      not vulnerable (OK)
 Secure Client-Initiated Renegotiation     VULNERABLE (NOT ok), potential DoS threat

  : (snip)
```

proftpd 1.3.5 も同じでした。

* [False positive generated by Secure Client-Initiated Renegotiation? #234](https://github.com/drwetter/testssl.sh/issues/234)
    * ここで問題は認識されているが、フツーダメなサーバはダメと出て、良いサーバは良いと出るみたいで終わってる。ただし…
* [Understand Secure Client-Initiated Renegotiation results for STARTTLS/smtp #465](https://github.com/drwetter/testssl.sh/issues/465)
    * 問題は認識されていて、なぜ NG になるのかちゃんと理解しないとね、となっている (2017-03-06 現在)
シンプルなlightlineのcolorscheme


vimのstatuslineを楽しくするlightline
同系のプラグインはpowerlineやairlineも有名でしょうが
作者が日本の方で哲学にも共感したので私はlightlineを使っています
そのlightlineの簡素なカラースキームを書きました

ターミナルでグレー背景を使用している方向けです
完全な黒背景だとstatuslineと同化してしまいますのでご注意を

[simplicity.vim](https://github.com/kmtoki/lightline-colorscheme-simplicity)

![スクリーンショット 2017-03-06 19.30.02.png](https://qiita-image-store.s3.amazonaws.com/0/154291/5ac50465-aa01-3ac5-9268-ceea020f3889.png "スクリーンショット 2017-03-06 19.30.02.png")
![スクリーンショット 2017-03-06 19.24.17.png](https://qiita-image-store.s3.amazonaws.com/0/154291/d0a7a8ff-9826-12ea-fe83-964e9e27a962.png "スクリーンショット 2017-03-06 19.24.17.png")
![スクリーンショット 2017-03-06 19.24.31.png](https://qiita-image-store.s3.amazonaws.com/0/154291/8fe92330-452d-1388-d76e-558707d90985.png "スクリーンショット 2017-03-06 19.24.31.png")
![スクリーンショット 2017-03-06 19.24.52.png](https://qiita-image-store.s3.amazonaws.com/0/154291/529f83eb-97e8-e64d-d005-40049e73812f.png "スクリーンショット 2017-03-06 19.24.52.png")

## Install
お使いのプラグインマネージャーでインストールできます

```vim
Plug 'kmtoki/lightline-colorscheme-simplicity'
```


さらに.vimrcに以下のようにしてください

```vim:.vimrc
let g:lightline = {
\ 'colorscheme': 'simplicity',
\ 'component': { 'readonly': "%{ &readonly ? '' : '' }" },
\ 'separator': { 'left': '', 'right': '' },
\ 'subseparator': { 'left': '', 'right': '' }
\ }

command! -nargs=1 -complete=custom,ListLLCS LightlineColorscheme 
\ let g:lightline.colorscheme = <q-args>
\ | call lightline#init()
\ | call lightline#colorscheme()
\ | call lightline#update()

function! ListLLCS(A,L,P)
return system("ls $HOME/.config/nvim/plugged/lightline.vim/autoload/lightline/colorscheme/ | perl -pe 's/(.+)\.vim/$1/' ")
endfunction
```

私のlightline設定はこんな感じ
コマンドでlightlineのcolorschemeを変えられるようにしています
vim力が低いのでperlを呼び出す有様

## 最後に

せっかくのカラフルなstatuslineを地味にしてしまうものですが
できるだけ簡素にモードの色分けができれば十分という方にはいいんじゃないでしょうかね
Google Map API を使うときはAPIKEYが必須になった

<REf>
Google Mapsの表示にはAPI登録が必須になりました
詳細は下記サイトへ
http://design-plus1.com/tcd-w/2016/06/google-maps.html

-------------
# Google Developper's page
https://developers.google.com/maps/web/
Click"キーを取得"
![image](https://qiita-image-store.s3.amazonaws.com/0/158724/c66e5c48-2235-cbe7-bfa0-1f4f0336c242.png)

## Google API Manager
APIキーの管理など
https://console.developers.google.com/
得意科目は金融です。九十九蘭（QUICK）は、LINE Botサービスを開発しました

![helpyou.jpg](https://qiita-image-store.s3.amazonaws.com/0/168963/34c227de-b692-e005-6dbc-96c47b8f0066.jpeg)

# 何ができるの？
美少女キャラによる会話型金融情報サービスです。
上場企業の株価をお伝えするだけじゃなく、株式天気予報の発信や、証券・金融用語の解説なども頑張っちゃいます。　
株や金融に関わることならなんでも聞いてくださいね♪

- 株価のいまを即座にリプライ。企業名やブランド名、商品名から、その企業の株価・前日比・配当利回りを答えます。
- これまで（過去）の株価も一発振り返り。日付を送信するだけで、過去のある日にさかのぼります。
- 上場企業のワンポイント解説。どんな企業なの？を1行にまとめます。
- 手が届きそうな狙いの銘柄を探します。いまの予算で購入できる類似企業も一発検索。
- その日の日本市場のトップ10をお伝えします。
- 今朝の株式天気を予報。登録すると7:30に自動でお届け。
- 登録するとマーケットのいまを11:50過ぎと15:20過ぎに自動でお届け。
- 金融証券用語を詳しく解説。いろいろな用語を知っています。
- ライフイベントにかかる費用など、身の回りの金融の話題を答えます。
- 上場企業から見た都道府県の魅力、日本市場の業種の特長なども簡単解説します。

# ここが開発のポイント
## 4つのAPIマッシュアップ
利用したAPIは次の4つ。
1. LINE Messaging API
2. Microsoft Cognitive Services LUIS API
3. IBM Watson NLC API
4. QUICK APIs
 （金融情報サービス会社「QUICK」のAPIシリーズです。一般公開は行っていません）

## 金融会話の意図解釈には2つのニーズがある
### **特長1： 意図は各々1つだけれど、会話の中に変数がある**
- 上場企業者数は3,500以上。正式名称のほか、略称や通称、社名より有名なブランド名、親しまれている商品名を加えるとどんどん数が膨らみます。膨大な名称×いろんな聞き方を学習しています。
- 日付や購入予算を加えると無限の組み合わせに。企業・商品・ブランド名に加え、日付の聞き方や購入予算（金額）の様々な組み合わせを学習しています。
 
こうした意図解釈にはLUISのIntent定義と学習を利用しました。
### **特長2： 豊富なQ&Aパターンと導き出す会話**
- 例えば公的年金受給額の厚労省モデル。質問文には様々なバリエーションがあっても答えは1つ。
- 例えば旅行に掛かる費用。国内なの？海外なの？ 国内だとどこの都道府県？ 目的や狙いを導き出す会話が必要。

こうした意図解釈には回答データと質問データによるNLCの学習モデルを利用しました。


九十九蘭（QUICK）の自然言語対話は、LUISとNLCのハイブリッドで実現しています。

## 友だちステータスもしかっり保持
### **省略会話を実現**
友だちとの自然な会話で欠かせないのはあうんの意図解釈。
企業名（銘柄名）を省略しても会話が成立するよう、話題にしている企業名（銘柄名）は常に覚えています。

- 「今日の任天堂は？」に続いて「もっとく詳しく教えて」 ・・・ 任天堂の詳細をリプライ
- 「今日の任天堂は？」に続いて「2017/1/4は？」 ・・・ 2017/1/4の任天堂の終値をリプライ

### **Push通知の有無も選択できます**
株式天気予報は平日の7:30に配信。マーケットデータは平日の11:50過ぎと15:20過ぎに配信。
Push配信の有無は友だち自身が選択できます。

これらステータスの保持はAzure DocumentDB（NoSQL DB）を利用しました。

## ショートカットも用意
上場銘柄には”証券コード”が付番されています。
例えばLINEは3938、日立製作所は6501、ソニーは6758、任天堂は7974
@+証券コードでショートカット問い合わせもできます。（各銘柄の証券コードは株価リプライでお伝えしています）

# 会話のサンプル
### **株価や会社の聞き方はいろいろ**
「今日のトヨタ自動車の株価は」「いまのトヨタは？」「レクサスはいくら」「@7203」
・・・ いずれもいまの株価をリプライします
### **いまの予算で購入できる類似企業（銘柄）は**
「20万円で購入できるホンダ型の株」「ホンダと似ている20万円で買える銘柄」
・・・ いずれも、ホンダと類似型で予算20万円を目安に購入できる銘柄をリプライします

# LINE@
LINEの友だち追加で体験が始まります。
![qr_code.png](https://qiita-image-store.s3.amazonaws.com/0/168963/0e7dec52-420f-73da-6c24-616f91aac30d.png)

---
[QUICKからのお知らせ](http://corporate.quick.co.jp/news/?post=2284)
[IRroid](http://ir-roid.com/)
ScalaScalableProgramming 03章 ふりかえり Set

# Scala 03章　Set

## Setでやる

```scala:Set.scala
    var jetSet = Set("hoge", "hoge2")
    jetSet += "hoge3"
    println(jetSet.contains("hoge9"))
```

```scala:けっか
    false
```

ミュータブル変数に、イミュータブルのSetをいれる
jetSetの変数はイミュータブルだから、 += のメソッドを持っていない。
なので、新しいオブジェクトを生成し、var であるjetSetを上書きしている

```scala:Set.scala
    val movieSet = mutable.Set("hoge", "hoge2")
    movieSet += "hoge3"
    println(movieSet)
```

```scala:けっか(例)
    Set("hoge", "hoge2", "hoge3")
```

イミュータブル変数に、ミュータブルのSetをいれる
movieSetはミュータブルだから、 += のメソッドを持っている
なので、変数(イミュータブル)の中身がミュータブルなSetに追加する形で生成される
※Setの中身は順不同
ScalaScalableProgramming 03章 ふりかえり List

# Scala 03章　List

## Listでやる

```scala:array.scala
    val oneTwo = List(1, 2)
    val threeFour = List(3, 4)
    val oneTwoThreeFour = oneTwo ::: threeFour
    println(oneTwo + " + " + threeFour)
    println(oneTwoThreeFour)
```

```scala:けっか
    List(1, 2) + List(3, 4)
```

::: は、List同士を連結できる。

```scala:array.scala
    val twoThree = List(2, 3)
    val fourTwoThree = 4 :: twoThree
    println(fourTwoThree)
```

```scala:けっか
    List(4, 2, 3)
```

:: は、Listに要素を追加できる。先頭に。
Rubyの開発環境の構築

## 環境設定

★ 参考にさせて頂きました ★
【macOS Sierra】Mac OSX 10.12 macOS Sierra にRuby + Rails4 開発環境の構築 【初心者必見】
http://qiita.com/keneo/items/e81bad87995fae566234

ほぼこの内容です。

### Xcodeをインストールします
Mac App Storeからインストールします。超時間かかります。

### Command Line Tools for Xcodeをインストールします

```
Xcode → Open Developer Tool → More Developer Tools
```

Downloads for Apple Developerページが開くので、そこのリストから”Command Line Tools(OS X 10.12) for Xcode 8”をダウンロードしてインストールします。
事前に認証していないと、認証を求められます。
認証に成功すると、該当ページに飛ばないので、再度"More Developer Tools"から遷移します。

### Homebrew本体をインストールします

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

PATHを設定します

```
$ echo 'export PATH=/usr/local/bin:$PATH' >> ~/.bash_profile
$ source ~/.bash_profile
```

インストールできたことを確認します

```
$ brew doctor
Your system is ready to brew.
```

最新パッケージリストを取得します

```
$ brew update
Already up-to-date.
```

rbenvでrubyをビルド・管理するためのパッケージをインストールします

```
$ brew install ruby-build
$ brew install rbenv
```

pathを設定します

```
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
```

### rubyをインストールします

公開されているrubyのバージョン一覧を確認します。

```
$ rbenv install -l
```

ここで最新のバージョンがわかるので、それを指定（ここでは安定版2.4.0）してインストールします

```
$ rbenv install 2.4.0
```

標準で使うrubyのバージョンを切り替えます

```
$ rbenv global 2.4.0
$ rbenv versions
  system
* 2.4.0 (set by ...)
$ ruby -v
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin16]
```

### Bundlerをインストールします
Bundlerは、Railsアプリケーションに必要となるGemパッケージの種類やバージョンを管理し、複数のPCで必要なGemパッケージをインストールする仕組みを提供してくれます。

```
$ gem install bundler
$ rbenv rehash
$ source ~/.bash_profile
```