OmniAICreator/Qiita-1.07M huggingface dataset:
音声合成としての StreamRelay.NET.exe

.NET Framework では、[System.Speech.Synthesis 名前空間](https://msdn.microsoft.com/ja-jp/library/system.speech.synthesis(v=vs.110).aspx)で、標準で音声合成エンジンへのアクセス手段(API)を提供している

よって、StreamRelay.NET.exeでは、標準入出力(-LocalPort=0 or -RemotepPort=0)の出力側オプション(-LocalSpeachVoiceName or -RemoteSpeachVoiceName)として実装した

### コマンドの実行例

日本語の文章ファイル **a.txt** を用意する

`C:\>type a.txt`
`こんにちは、明日は天気が良いようですよ。`
`C:\>StreamRelay.NET.exe -localport 0 -localinputfile a.txt -remoteport 0 -RemoteSpeachVoiceName "Microsoft Haruka Desktop"`
とすると、「Microsoft Haruka Desktop」音声エンジンを用いて、スピーカーから音声が再生されるだろう

### オプション

- 音声合成エンジン
- -LocalSpeachVoiceName "EngineName"
- -Remote]SpeachVoiceName "EngineName"
- 音声の再生速度
- -LocalSpeachVoiceRate "-10～+10"
- -RemoteSpeachVoiceRate "-10～+10"
- 音量
- -LocalSpeachVoiceVolume "0～+100"
- -Remote]peachVoiceVolume "0～+100"

### インストールされている音声合成エンジンの一覧

オプション
`StreamRelay.NET.exe -ListVoice`

### 日本語音声合成エンジン

- MS-Offilce をインストールすると、日本語音声合成エンジンがインストールされるようだ
- MS-Windows10 には既定で、日本語音声合成エンジンがインストールされているようだ

---
### 目次へ戻る

[目次というか最初の一歩](http://qiita.com/tomoki0sanaki/items/85f20cbe18378e33cd6f)
ベアメタル ファームウェアの更新のメモ

ベアメタルサーバーのRAIDコントローラでエラーが出ると、サポートからRAIDコントローラーのファームウェアを最新版へ更新してくださいとのコメントをもらう事がある。　

Bluemix Infrastructure のカスタマーポータルから、クリック操作だけで以下のファームウェアを選択して更新できる事が意外と知られていないので、実際に更新した記録です。

* IPMI
* RAIDコントローラー
* BIOS
* ハード・ディスク

# 操作方法
デバイスの詳細に進んで、アクションのメニューから、**ファームウェア更新** を選択します。

![スクリーンショット 2017-05-29 22.42.45.png](https://qiita-image-store.s3.amazonaws.com/0/42829/86dcedf8-9ec1-7ce6-eff0-b8babe39193e.png)

次に確認画面が表示されます。 IPMIしか表示されていないのですが、このウィンドは、スクロールできるので、下へ移動してみましょう。
![スクリーンショット 2017-05-29 22.43.07.png](https://qiita-image-store.s3.amazonaws.com/0/42829/9d1298a9-2a31-9924-a349-0c41334f39ba.png)

下へスクロールすると、さらに、３つ表示されました。 必要な項目にチェックを入れて、ファームの更新を実行します。
![スクリーンショット 2017-05-29 22.44.05.png](https://qiita-image-store.s3.amazonaws.com/0/42829/d6ee02c1-f56e-6a37-116d-51e08c0e4392.png)

確認画面が表示されるので、Yes を選択して先へ進めます。
![スクリーンショット 2017-05-29 22.44.17.png](https://qiita-image-store.s3.amazonaws.com/0/42829/e2b1274e-225d-d0b7-2e4c-34ea674ad1f7.png)

「少なくとも20分」ですから、それ以上停止する事がわかります。　やはり実測では、RAIDコントローラの更新に48分かかりました。 作業を計画する場合は、十分な余裕を持って作業時間の計画を立てる必要があります。
Git Townが割と便利かもって話

Gitのプラグイン的なコマンドを提供するGit Townを試してみました。
http://www.git-town.com/

ドキュメントや動画を見る限り、Git Townのコマンド一つで複数のGitコマンドを実行することでワークフローをもっとシンプルにしようということらしいです。
すぐ陳腐になってしまうのでinstall方法とかは公式をみましょう。（いやコマンドもそうなんですけどね）

個人的にリモートの変更を取り込む際にローカルの変更を一旦stashしてpullするみたいなワークフローが辛くなってきたのでそこらへんが改善すればいいなぁって思って試してみました。

# ブランチを作る

```
git town hack <branch name>
```

するとGit townがまずmainのbranchを聞いてきます。で今回はmasterを選択
そのあとperennialブランチを聞かれるのですが今回はmasterと同じで

するとデフォルトでmainブランチを追随するようになります。

mainブランチから新たなブランチを作成。同時にremoteにもブランチを作成してくれます。
途中`git add -A`を行うのでローカルにあるファイルは問答無用にaddされます。ここら辺は郷に入っては郷に従へということで。

# featureブランチでメインブランチに追随する

作ったfeatureブランチからmainブランチに追随する

```
git town sync
```

個人的にはfeatureブランチでmainブランチを追随するときには単なるマージではなくて`rebase`を使用したいので、ちょっと自分のワークフローとは違うと感じました。
**が**git townでは最終的にsquash mergeするので大勢に影響はないです。

ちなみにconflictが起きた時は通常のマージをする時のように直してcontinueすれば大丈夫です。

# Pull Request

```
git town new-pull-request
```

最新のmainブランチを反映した上でremoteのfeatureブランチへpushしてブラウザ上でPRページを開きます。

# ブランチをマージする

```
git town ship
```

mainのブランチにsquash mergeされます。のでコミットメッセージが汚くてもキニシナイキニシナイ。まだここで綺麗なメッセージにできるチャンスがあります。

流れとしては

```
mainブランチを最新 -> squash merge -> mainブランチにpush -> 該当ブランチの削除　
```

が行われます。
今まで色々考えてめんどくせぇってなってたんですが、このようにある程度何にも考えずにワークフローを進めることができます。

# ブランチを消す

```
git town kill <branch name>
```

なぜremoveではなくkillを採用したのかは割と謎ですが、remoteのブランチも同時に消してくれる便利。
undoオプションがあるので消えたブランチの復活もreflog確認してみたいなことをする必要がないです。

# ブランチをrenameする

```
git town rename-branch [<old_branch_name>] <new_branch_name> [-f]
```

どうやってやってるのかなぁって思って見てみたら。単純にブランチを消して、新たに作り直しているだけでした。でも便利だ。

# その他

ブランチのpullはデフォルトはrebaseのようです。
pushのデフォルトはtagも含めます。

# 感想

正直今からコマンド覚え直すのだるいヨ。って思ってたんですが、普段のワークフローはブランチ作成して、mainブランチを追随して、マージするということしかやってないにもかかわらずrebaseしたり、stashしたりと結構煩雑だったので基本のコマンドが3つで済むというのは大変便利だと感じました。

各コマンドがそれぞ何やってるか概ね理解したら安心して普段使いできそうな予感です。

# Git Townみてて知らなかったgitコマンド/オプション

使ってるだけだと偉そうにGit Townを評価しているような気持ちになってしまったので、残りはGit Townから学んだことを列挙します。
普段Source Treeどっぷりなので基本的なコマンド知らなかったりします。。。

## git fetch --prune

`--prune`をつけることですでにremoteでは存在していないブランチをトラッキングしなくしてくれる。localからブランチが消えるわけではないです。

## git merge --no-edit

`--no-edit`自動的にマージメッセージを付与するオプション。

## git push origin :<branch name>

リモートブランチの削除
もしくは

```
git push --delete origin <branch name>
```

## git push -u 

`-u`はlocalとremoteのブランチを参照させるオプション。このオプションがないと`git pull <remote> <branch>`と毎回remoteとbranchを指定しなければならなくなります。
Windows 10にVagrantでRails開発環境を構築する

諸事情により、WindowsマシンでRailsの開発環境を構築する必要が発生したのでVagrantを利用して仮想環境を構築しました。同じような境遇を迎える後世の人々のためにその手順をここに記しておきます。

## 構築する環境(2017年5月29日時点)
* Ubuntu 16.04
* Ruby 2.4.1
* Rails 5.0.3
* DBはPostgreSQL(Windowsにインストール済)

### 実行したマシンのスペック
Windows 10 Home
バージョン: 1607
OSビルド: 14393.1198

VirtualBox: 5.1.20
Vagrant: 1.9.2
PostgreSQL: 9.5.4

※Vagrantのインストール手順は割愛します。

### 1. VagrantのVM作成
ubntu 16.04のboxからVMを作成します。

```bash
vagrant box add ubuntu1604 https://atlas.hashicorp.com/bento/boxes/ubuntu-16.04/versions/2.3.6/providers/virtualbox.box

mkdir ubuntu1604
cd ubuntu1604

vagrant init ubuntu1604
vagrant up
vagrant ssh
```

VM内に作業用のディレクトリを作成する。

```bash
mkdir -p /home/vagrant/rails
```

いったんWindowsに戻って、Vagrantfileに以下の設定を追記します。
Windows側に作業用のディレクトリを作成してください。

```ruby
config.vm.network "private_network", ip: "192.168.33.10"

# ディレクトリは任意
config.vm.synced_folder "c:/rails", "/home/vagrant/rails"
```

設定を反映させます。

```bash
vagrant reload
```

### 2. 基本ライブラリのインストール
以下はVagrantのVM内での作業になります。

```bash
sudo apt-get install -y g++ make git build-essential libssl-dev libffi-dev libreadline-dev zlib1g-dev libreadline-dev libyaml-dev libxml2-dev libxslt-dev libpq-dev
```

### 3. rbenvのセットアップ
```bash
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

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

source ~/.bash_profile
```

### 4. Rubyのインストール
```bash
rbenv install 2.4.1
rbenv rehash
rbenv global 2.4.1
```

#### 基本的なgemとRailsのインストール
```bash
gem update --system
gem install bundler
gem install pg -v '~> 0.20.0'
gem install rails --version='~> 5.0.0' --no-ri --no-rdoc
```

### 5. Windows側のPostgreSQLの設定変更

WindowsにインストールされているPostgreSQLサーバーに接続するための設定です。
Windows側の `[PostgreSQL HOME]\data\pg_hba.conf` に以下を追記してPostgreSQLサービスを再起動します。

```
host	all	 all	 192.168.0.0/16	 password
```

### 6. Railsアプリケーションの作成

```bash
cd /home/vagrant/rails
rails new rails-pg -d postgresql
```

`C:\rails\rails-pg` に作成したRailsアプリケーションのソースが同期されるのでWindows側で編集が可能です。

`config/database.yml` に以下を記述します。

```ruby
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  url: <%= ENV["DATABASE_URL"] %>
```

次にPostgreSQLへの接続設定として環境変数 `DATABASE_URL` を設定します。
`DATABASE_URL` は以下の書式で記述します。

```
postgres://[user_name]:[password]@[host]:[port]/[database_name]
```

```bash
export DATABASE_URL=postgres://[user_name]:[password]@[host]:[port]/[database_name]
```

Railsアプリケーションを起動し、 `http://192.168.33.10:3000/` でRailsのトップ画面が表示されることを確認します。

```bash
rails s
```

## おまけ
Vagrantのprovision機能でRailsのインストールまでを自動化しているので興味がある人は以下のリポジトリを覗いてみてください。

https://github.com/cobot00/vagrant-config
【自分用】rubyリファレンス

#インデックス
- 文字列
- 設定

---
###️文字列

文字列内にある空白の操作

```ruby:strip.rb
#例）
str = "  Hello World   "
str.gsub(" ", "")   # => "HelloWorld"
str.strip           # => "Hello World"

#補足：　lstrip, rstrip
```
参考：http://qiita.com/ntakuya/items/1153940f3e9c6282b4c5
　

文字列の数字を0埋めする

```ruby:zero-ume.rb
#例）
puts format('%02d', 7)  #=> 07
puts format('%02d', 12) #=> 12

puts printf('%02d', 7)  #=> 07
puts printf('%02d', 12) #=> 12

puts '%02d' % 7  #=> 07
puts '%02d' % 12 #=> 12

#例)
str = "7"
str.rjust(2, "0") #=> "07"
str = "12"
str.rjust(2, "0") #=> "12"

#補足：　ljust, center
```
参考：
http://ref.xaio.jp/ruby/classes/string/rjust
http://qiita.com/tksmaru/items/0f9283d0c5f0ee716f2f　

引数で指定した文字を文字列から削除する

```ruby:deleteメソッド
str = "hello world"
puts str.delete('l') # => "heo word"
```

参考：http://ref.xaio.jp/ruby/classes/string/delete

---
###設定
rbenvの切り替え

使用中のrubyのバージョン確認

```
rbenv version
```

インストールしているrubyのバージョン一覧

```
rbenv versions
```

rubyの切り替え

```
rbenv gloval バージョン
```

切り替え確定

```
rbenv rehash
```

カレントディレクトリのみrubyのバージョンを変更したい場合は

```
rbenv local バージョン
```
参考：http://qiita.com/a_ishidaaa/items/8cc14453289dba1413dd
Angular2を使ってWebアプリを作ってみる#1(導入編)

# はじめに
Angular2を使ってWebアプリを作る機会があったから、勉強かつ自分のまとめようとしてまとめる。
適当に調べたことをまとめてくから間違えてるかも。

# 前提条件
JSP + JavaScriptでのWebアプリは触れていたことがあった。
JavaScriptは軽くしか知らない。
Javaは少しわかるくらい。
TypeScriptもAngularも全く聞いたことが無いところからのスタート。

# 使うもの
* Angular2
* TypeScript

## [Angular2](https://angular.io)
Google製のjsFW。AngularJSの後継バージョン。
AngularJSが色々問題あったから出た後継らしい。
以下、公式サイトから引用。

1. 全てのプラットフォームで開発できる！
2. スピードとパフォーマンスに優れる！
3. 信じられないツーリング！
4. 多くの人に愛されてる！

バージョン2からJSが消えてるのは、推奨されてる言語がTypeScriptだからだそう。
2016年9月15日にリリースされた新しいFW。
[これ](https://www.amazon.co.jp/exec/obidos/asin/4822296539/yuhiisk03-22/)が割りと新しい本。
調べた中では新しめかつ評判のいいAngular2の本はこれしか見つからなかった。
最近(2018年末)では[Angularアプリケーションプログラミング](https://www.amazon.co.jp/dp/B074M54GM5/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)とか[公式の日本語ドキュメント](https://angular.jp/)とかあってとっつきやすくなっていると思う。

## [TypeScript](https://www.typescriptlang.org)
AltJSの1つ。
Microsoftが開発したオープンソースのスクリプト言語。
JavaScriptに型付けとクラスベースのオブジェクト指向を組み合わせたもの。
JavaScriptでも一応型付けとかは出来るけど、すごく面倒くさいらしい。
C#、Delphi、Turbo Pascalの開発者でもあるアンダース・ヘルスバーグが TypeScript の開発に関わってるとのこと。

```javascript

// こんな感じで型付けられる
var hoge: String = null;

// 型なしにするとノーチェックでコンパイル通るから気をつけて
var huga: any;

// なにも指定しないとanyと同じになるよ
var x;

// アロー関数も使えるよ
var add = (x: number): number => x + 1;

// コンストラクタとかも作れるって
class A{
    myNum: number = 0;
    constructor(id: number){
        //このthisは付けないとエラーになる
        this.number = id;
}

// オーバーロードも出来るって
class A{
    f(x:string): string;
    f(x:number): number {
        if (typeof x === 'string') {
            return x + ' abc';
        } else {
            return x + 1;
        }
    }
}

// ただし、コンストラクタのオーバーロードは出来ないらしい。
class A{
    myNum: number = 0;
    constructor(id: number){
        //このthisは付けないとエラーになる
        this.number = id;
    }
    // こいつはエラーを吐かれる
    constructor(){
        this.number = 10;
    }
}
```

他にもジェネリクスとか継承とかJavaとかC#で出来ることは基本的にできそう。

# 終わりに
環境設定とかしようと思ったけど、思ったより書いたからまた次回にする。
ドメイン駆動設計（DDD）について書きます


エリック・エヴァンスさんが提唱しています。

[QCon Tokyo 2011 アーキテクチャパネルディスカッション＋DDD雑多ネタ](http://hibituredure.blogspot.jp/2011/04/qcon-tokyo-2011-ddd.html)

上記記事を見て、僕も思うところを書いていきます。DDD系の話は、議論になったりすることもありますが、１エンジニアのつぶやきと思ってみてください。（文中の引用文は、上記記事から引用させていただいています。）

### 基本概念
---

作成するシステムのプログラムコードと、ドメイン（現実の業務）が一致することによって、

> 主にコアドメインへの注力によって競争上の優位、市場優位につなげる

という。

### ドメイン駆動設計を実践するための方法
---

#### レイヤードアーキテクチャ

ドメインロジックと、それ以外（DBやViewなど）を切り離すのが目的

最近のシステム設計もレイヤードアーキテクチャを採用していたりするので、DDDじゃなくても採用したほうが良いと思っています。

#### ドメインはオブジェクト指向言語が表しやすい？

ドメインロジックは、オブジェクト指向言語が一番表しやすいらしい。
個人的には、関数型言語でもエッセンスだけ取り入れるとかは、出来ると思う。

#### ユビキタス言語

全員で業務の言葉だけを統一して使い、技術用語や社内用語など統一されていない用語は使わない。

チーム内でドメインの言葉を使うように統一することにより、人によって同じ意味のものを違う単語で話しているとかなくなる。

そして、ドメインの言葉をコードにそのまま落とし込むことで、ビジネスパーソンの理解率向上が見込める。
（英語圏の人はドメインの言葉とコードが共に英語なので完全に一致する。日本人どうしようか？問題はある。）

### ドメイン駆動設計で車について語ると？
---

#### 一般的な車の仕様

- 燃料計やガソリンタンクを見ると、車のガソリン量を知ることが出来る。
- タイヤを見ても、車のガソリン量を知ることは出来ない。

#### システムに落としこんだ場合

- 燃料計クラスとか、ガソリンタンククラスのみが、ガソリン量を取得出来る
- タイヤクラスは、ガソリン量を知ることは出来ない。

ドメインと実装を合わせるのであれば、ガソリン量を知っていて良いのは、燃料計クラスとガソリンのタンククラスぐらいだと思います。

なので、下記はやりがちではありますが、駄目なパターンです。

```
タイヤクラスからでも、DBにガソリン量を取得に行けるので、取れます(^q^)
```

ちゃんと作っていくと、ドメインを知っている人は、かなりスッとコードベースの理解が進むと思います。

また実際に、現実のドメインと、ソースコードが一致していた場合、現実で難しい変更は、ソースコードでも難しい変更となるはず（逆も然り）。ビジネスパーソンに理解を得られる工数を言えるようになるかも？です。

### ユビキタス言語と日本語の壁
---

エヴァンス氏の回答

> 「ドメインエキスパートがこの言葉（日本語コメントで書かれたクラス名）を使っているのなら、なぜクラス名にこれを使わない？」とのこと。「日本語でJava等を書くと、Java慣習にかたっぱしから違反してしまうので問題なんだ、コードも読みづらいし」と反論（？）してみたものの、「重要なのはドメインの概念であって、技術的な問題はそれに比べれば瑣末なものだろう？」と言われてしまい、もう納得するしかなかった。

徹底しているなぁと。でもやっぱり日本人は厳しそう。クラス名とかメソッド名は英語で、docコメントでユビキタス言語と合わせるというのが出来る限界なのでは無いかなぁ？と思います。

### まとめ
---

DDDやりすぎると、

- コードが複雑化してしまった
- 普通に実装するよりも工数が掛かる

とかあるみたいです。

でも、DDDのドメインとコードの一致というものは、わかりやすいコードになるはずです。
結構、対極的な位置にある「[Rich Hickeyさんの記事](http://eed3si9n.com/ja/simplicity-matters)」の話も踏まえつつ、うまいことシステムを設計できたらいいなぁと思います。
Mac OS X tmux環境でSolrを起動するときにnohup: can't detach from console: Inappropriate ioctl for deviceでERRORになったら

MacでSolrを起動しようとしたときにエラーが発生して起動できなかった。
logファイルには
```
nohup: can't detach from console: Inappropriate ioctl for device
```
tmux を使っていると発生することがある模様。
https://stackoverflow.com/questions/23898623/nohup-cant-detach-from-console#comment36832429_23898623
tmux をつかっていないウインドウで起動したら通りました。
anyenvを導入して、既存のpyenv, rbenv, jenvも読み込めるようにsymlinkを貼った


rbenvやpyenvを使っている人は多いと思いますが、それぞれインストールしていくと、.bashrcや.zshrcに書く内容が少しずつ増えていきますよね。
[anyenv](https://github.com/riywo/anyenv)を使うと、書くべきはたったの2行で済みます。

```.zshrc
export PATH="$HOME/.anyenv/bin:$PATH"
eval "$(anyenv init -)"
```
便利ですね。今回はコレを入れます。

##1. anyenvのインストール
```Terminal
$ git clone https://github.com/riywo/anyenv ~/.anyenv
```

`.zshrc`を編集します。もしbashを使っているなら `.bashrc`や`.bash_profile`などになるでしょう。

```.zshrc
export PATH="$HOME/.anyenv/bin:$PATH"
eval "$(anyenv init -)"

#今まで書いていたコメントアウトしてもよくなります↓

# Ruby Env
#export PATH="$HOME/.rbenv/bin:$PATH"
#eval "$(rbenv init -)"

# Python Env
# export PATH=$PYENV_ROOT/bin:$PATH
# eval "$(pyenv init -)"
# eval "$(pyenv virtualenv-init -)"

# Java Env
#export PATH="$HOME/.jenv/bin:$PATH"
#eval "$(jenv init -)"
```

シェルを再起動します。

```Terminal
$ exec $SHELL -l
```

anyenvが使えるか試してみます。

```
$ anyenv
anyenv
Usage: anyenv <command> [<args>]

Some useful anyenv commands are:
   commands            List all available anyenv commands
   local               Show the local application-specific Any version
   global              Show the global Any version
   install             Install a **env
   uninstall           Uninstall a specific **anv
   version             Show the current Any version and its origin
   versions            List all Any versions available to **env

See `anyenv help <command>' for information on a specific command.
For full documentation, see: https://github.com/riywo/anyenv#readme
```
お、もう使えるようです。

## 2. 新しく〇〇envを使いたいときは
新しくenv系をインストールしたいときはコマンド一つで簡単に入れることができます。例えば、`ndenv`を入れたいと思ったら、以下のようにします。


```Terminal
$ anyenv install ndenv
```

これだけで、もうすぐに`ndenv`が使えます。便利〜。

```Terminal
$ ndenv
ndenv 0.4.0-4-ga339097
Usage: ndenv <command> [<args>]

Some useful ndenv commands are:
   commands    List all available ndenv commands
   local       Set or show the local application-specific Node version
   global      Set or show the global Node version
   shell       Set or show the shell-specific Node version
   install     Install a Node version using the node-build plugin
   uninstall   Uninstall a specific Node version
   rehash      Rehash ndenv shims (run this after installing executables)
   version     Show the current Node version and its origin
   versions    List all Node versions available to ndenv
   which       Display the full path to an executable
   whence      List all Node versions that contain the given executable

See `ndenv help <command>' for information on a specific command.
For full documentation, see: https://github.com/riywo/ndenv#readme
```

## 3. 既にrbenv, pyenv, jenvなどを使っていた人向け
すでに、pyenvやrbenvなど、使っていたものがある場合は、symbolic linkを貼ってあげないと読み込んでくれないので貼ります。

```Terminal
$ ln -s ~/.rbenv ~/.anyenv/envs/rbenv
$ ln -s ~/.pyenv ~/.anyenv/envs/pyenv
$ ln -s ~/.jenv ~/.anyenv/envs/jenv
```

簡単でした。終わり。

参考にしたのはこちらの記事です。
http://qiita.com/luckypool/items/f1e756e9d3e9786ad9ea
http://d.hatena.ne.jp/riocampos+tech/20141019/install_anyenv
RxSwiftのExamplesにしれっと入ってる双方向データバインディングの演算子がイケてた

こんばんは！:octocat:

[RxSwift](https://github.com/ReactiveX/RxSwift) (RxCocoa)を使ってモデル←→ビューのお互いの更新を伝え合う双方向データバインディングをやってみます。

[SwiftBond](https://github.com/ReactiveKit/Bond) では双方向データバインディングがサポートされているのですが RxSwiftのドキュメントにはそのような記述はなく、綺麗に書く方法ないかな〜とExamplesを眺めていたらそれっぽいものを見つけたのでご紹介します。

## やってること

![hoge.gif](https://qiita-image-store.s3.amazonaws.com/0/15144/72e977f4-c8a9-a3eb-d604-438ecbb3a195.gif)

* 登場人物
    * ラベル
        * 最新の値を表示し続ける
    * **テキストフィールド** ←こいつに双方向bindを実装します
        * 最新の値を表示し続ける
        * 値を入力できる
    * ボタン
        * 値を初期値に変更できる

このUIにおいて、

* **テキストフィールド**で入力した内容が即時ラベルに反映される。
* ボタンの押下で書き換わった内容が即時**テキストフィールド**に反映される。

という点において双方向のデータバインディングを実現してみます。

## Before

```swift
import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {
	private var item = Variable<String?>("Hello!")
	private let disposeBag = DisposeBag()

	@IBOutlet weak var label: UILabel!
	@IBOutlet weak var textField: UITextField!

	@IBAction func resetButtonHandler(_ sender: UIButton) {
		item.value = "Hello!"
	}

	@IBAction func textFieldHandler(_ sender: UITextField) {
		item.value = sender.text
	}

	override func viewDidLoad() {
		super.viewDidLoad()
		setup()
	}

	private func setup() {
		// モデルからビューへ
		item.asObservable().bind(to: textField.rx.text).disposed(by: disposeBag)
		// ビューからモデルへ
		textField.rx.text.subscribe(onNext: { [weak self] text in
			self?.item.value = text
		}).disposed(by: disposeBag)

		// 最新の値をラベルで表示しておく
		item.asObservable().bind(to: label.rx.text).disposed(by: disposeBag)
	}
}
```

ここで [Bidirectional Operator](https://github.com/ReactiveX/RxSwift/blob/master/RxExample/RxExample/Operators.swift) `<->` の登場です。

左辺にビュー、右辺にモデルが来るように書きます。
さらにそのままだと返り値が未使用と言われるので `_ = ` を先頭につけておきます。
（一応例にもそう書いてあったのですが、万が一メモリリークの危険性踏んでたら教えて頂きたく...! :bow:）

## After

```swift
import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {
	private var item = Variable<String?>("Hello!")
	private let disposeBag = DisposeBag()

	@IBOutlet weak var label: UILabel!
	@IBOutlet weak var textField: UITextField!

	@IBAction func resetButtonHandler(_ sender: UIButton) {
		item.value = "Hello!"
	}

	@IBAction func textFieldHandler(_ sender: UITextField) {
		item.value = sender.text
	}

	override func viewDidLoad() {
		super.viewDidLoad()
		setup()
	}

	private func setup() {
		_ = textField.rx.text <-> item // ここ（´∀｀ ）
		item.asObservable().bind(to: label.rx.text).disposed(by: disposeBag)
	}
}
```

ユーザID＋パスワードや、住所氏名年齢電話番号・・・のような設定するコンポーネントが多い画面で活躍してくれそうです！
だんだんRxSwiftが面白くなってきた今日このごろです:relieved: おやすみなさい。
【ssmtp】CentOSでログイン通知【rsyslog】

CentOS にログインしたらGメールで通知を受け取れるように設定します
　　gmail が使えない場合は [【ommail】CentOSでログイン通知【rsyslog】](http://qiita.com/nobu-maple/items/0c4cb06b3426ad726772) を参照


もし、意図しないタイミングでメールが来たら。。ヤバイ状況です
が、メール通知を仕掛けておかないと気が付きもしないかも

ちょっと設定ファイルを書いて、数行の簡単なシェルを組むだけ
手間をかけずにログインメール通知を仕掛けてみます

ここに書いた手順は centos ですが、他Linuxでも似たようにできると思います
（未確認）


#送信専用メール ssmtp 設定

sendmail とか postfix とかメールサーバ立ち上げるのはめんどくさいのとセキュリティ上の穴になる可能性があるので、簡易なメール送信専用サーバ？　ssmtp を設定しときます


## ssmtp インストール

インストールは yum で簡単に

```bash
yum install  ssmtp
```


## ssmtp 設定（gmail利用設定）

gmail のログイン設定を入れておきます

```bash:/etc/ssmtp/ssmtp.conf
mailhub=smtp.gmail.com:587
AuthUser=■ ■ ■ ■ ■@gmail.com
AuthPass=▼▲▼▲▼▲▼▲▼▲▼▲▼▲
UseSTARTTLS=YES
root=■ ■ ■ ■ ■@gmail.com
rewriteDomain=gmail.com
hostname=gmail.com
AuthMethod=LOGIN
FromLineOverride=YES
TLS_CA_File=/etc/pki/tls/certs/ca-bundle.crt
```

■ ■ ■ ■ ■ は、メールアドレス
▼▲▼▲▼▲▼▲▼▲▼▲▼▲　は、パスワードを設定です


## ssmtp 送信テスト

設定がきちんとできてるかメールを送信して確認してみます

```bash
echo -e "From: ■ ■ ■ ■ ■@gmail.com\nTo: ■ ■ ■ ■ ■@gmail\nSubject: test\n\ntest mail\n" | ssmtp -s ■ ■ ■ ■ ■@gmail.com
```

どうでしょう
ちゃんとメール届きました？
ここでメール届かないと、ログイン通知も届かないのでしっかり確認が必要です


# システムログ設定

OSがログインしたことをsyslog に残すので、syslogに記録されたタイミングでメール送信をできるように設定を追加です

## rsyslog 設定

```bash:/etc/rsyslog.d/login2mail.conf
$template login_msg, "%fromhost%  %msg%"

if \
      ( $msg contains 'pam_unix(' ) \
  and ( $msg contains 'session opened' ) \
then ^/etc/rsyslog.d/login2mail.sh;login_msg
```

login_msg という変数？に ログイン元のfromhost と、syslogに記録されたメッセージを設定

もし（if） syslog に記録されたメッセージ（$msg）に 
　'pam_unix(' っていう文字列と
　'session opend' っていう文字列があったら
/etc/rsyslog.d/login2mail.sh っていうファイルを実行！　引数に login_msg を指定♪

っていう設定になってます。
カンタンですね


## rsyslog からメールを送るシェル

文字列が見つかった時に呼び出されるシェルはこんな感じ

```bash:/etc/rsyslog.d/login2mail.sh
#!/bin/bash
ADDR="■ ■ ■ ■ ■@gmail.com"
SUBJ="SERVER Login : `hostname`"

echo -e "From: ${ADDR}\nTo: ${ADDR}\nSubject: ${SUBJ}\n\nServer Login\n${1}\n" | \
ssmtp -s ${ADDR}
```


# 動作確認

ログイン、もしくは su で、syslogにログインが記録されるので実行してみる

```bash
$  su  -  
```

すると、syslogにはこんなログが

```bash:/var/log/messages
・・・
May 29 22:51:27 server001 su: (to root) user01 on pts/0
May 29 22:51:27 server001 su: pam_unix(su-l:session): session opened for user root by user01(uid=1000)
・・・
```

キーワード 'pam_unix(' と 'session opened' が存在するので、メールが送られているはず


受信メール：

```
From: <■ ■ ■ ■ ■@gmail.com>
日付: 2017/05/29 午後10:51
件名: SERVER Login : server001
To: <■ ■ ■ ■ ■@gmail.com>

Server Login
server001  pam_unix(su-l:session): session opened for user root by user01(uid=1000)
```


うまく届かない場合はメールアドレスが間違っていないかとか、
サーバの指定とか、パスワードとか
もう一度確認を
でも、ダメな場合はこの辺を見てみるとか
 ※ これはうまく送信できている例

```bash:/var/log/maillog
May 29 22:51:27 server001 sSMTP[32057]: Creating SSL connection to host
May 29 22:51:28 server001 sSMTP[32057]: SSL connection using ECDHE-RSA-AES128-GCM-SHA256
May 29 22:51:31 server001 sSMTP[32057]: Sent mail for ■ ■ ■ ■ ■@gmail.com (221 2.0.0 closing connection l297sm12446578pgd.35 - gsmtp) uid=0 username=root outbytes=555
```


以上
許可なくパスワードとか知ってるベンダーがログインしたとか、すぐ気が付くし
受信したメールは消すのが困難なので、サーバログを改ざんされても記録残せるとか
設定追加するだけで特に開発なく仕込めるのが良いかな♪
学んだこと

# なるほどと思った指摘事項
**ファイル入出力時の例外出力**
ファイル入出力時には例外をcatchすることは当然，finallyで開いたままのファイルを閉じる処理を入れなければファイルが開いたまま．
**ファイル上書き時のバックアップ**
ファイルを1から上書きしなおす際は，ファイルの書き込み中に例外が発生すると中身のデータが失われてしまう．
そのため，あらかじめバックアップを取ってから上書きを開始し，もし失敗したらバックアップで復元を行う．
正常に書き込みが終了したら，バックアップは削除する．
以上のような処理を入れておかないとやばい．
**エラー表示と番号**
エラー表示はエラーIDを設定して，設定したID基にエラー表示を行うべき．
エラーIDは，400番台はファイル出力に関するエラーのように，種類ごとにまとめておく．
**変数として保持するデータ形式**
一般的なデータ形式で持つ．
特殊な形式で保存されていたら，保持するのはデータ値のみ．
例：データ[4000][50000] 　→　　4000と50000を保持する
**クラス名とメソッド名**
基本的に，名前の機能のみを提供するように．
**例外発生後の帰還経路**
例外が発生しても，強制終了を起こさないようにする．
例えば，プログラム中のどこかで例外が発生した場合，正規の処理をすべて行った後に帰る経路に一気に飛び，プログラムを安全に終了させよう．

`IT戦士になったばかりのぺーぺーなので，「これは違うんじゃない？」などの指摘は大歓迎です！`
Express.jsはexpress-generatorを入れてnpm startで実行

#はじめに
技術評論社「<a href="http://gihyo.jp/dev/serial/01/nodejs">基礎から学ぶNode.js</a>」がとてもわかりやすく重宝している。ただ、執筆時点（2012年）から5年経っておりチュートリアル通りに動作しなかった箇所があったので、修正した手順を記録する。

#「第3回 Express.jsを使ったWebアプリケーションを構築」でハマった
<a href="http://gihyo.jp/dev/serial/01/nodejs/0003">第3回の記事</a>はExpressフレームワークを使ったWebアプリのチュートリアルなのだが、最新のExpress.jsでは以下のように手順を置き換える必要がある。

まず、expressだけでなくexpress-generatorもインストールすること。

```
npm install -g express
npm install -g express-generator
express --version
4.15.0
```

このexpressコマンドはexpress-generatorを実行するプログラムである（ややこしい）。次にEJS(Embedded JavaScript)をテンプレートとしてfirstappアプリを作成し、npm install -dでモジュールをインストールする。ここは元記事の通りでOK。

```
express -t ejs firstapp
cd firstapp
npm install -d
```

そしてアプリを実行する訳だが、元記事のように

```
node app.js
```

と打っても何も起きない( ；∀；) そうではなく、

```
npm start
```

と打てば、無事にアプリが実行される。ブラウザーから http://127.0.0.1:3000/ にアクセスすれば動作確認が可能。

以上
【ネタ】SmalltalkでスレッドセーフなSleepSort

流行りに乗って(^^; 、Smalltalk でスレッドセーフなSleepSortを書いてみました。

参考：[【ネタ】Pythonでスレッドセーフな Sleep Sort関数 (threading編)](http://qiita.com/shiracamus/items/76fa50ad8aa0c0de8c3c)

処理系は [Pharo](http://pharo.org/) を使用しました。

```smalltalk
| N queue result |
N := 1000.
queue := SharedQueue new.
(1 to: N) asArray shuffled do: [:x |
   [(Delay forMilliseconds: x * 5) wait. queue nextPut: x] fork
].
^[result := (queue next: N) asArray] timeToRun -> result isSorted
```
```
=> 0:00:00:05.002->true
```

処理は簡単で、1 から N := 1000 までの整数の配列（(1 to: N) asArray）をランダムに並び替え（shuffled）てから、それぞれの整数 x について x * 5 ミリ秒待ってから（(Delay forMilliseconds: x * 5) wait）、キューに x を追加する作業（queue nextPut: x）を別スレッドで動かします（[...] fork）。

その後、メインスレッドでキューに N 個要素がたまるのを待って結果とします（result := (queue next: N) asArray）。

念のため、そのときにかかった時間（[...] timeToRun）が、N * 5 ミリ秒、つまり 5 秒を大きく越えていないことと結果がソート済み（result isSorted）であることを確認しています。
IEを起動するとOffice IME 2010が保護モードで開かれるという警告が表示される

ある時からIEを起動すると以下の警告が表示されるようになりました。

![capture1.png](https://qiita-image-store.s3.amazonaws.com/0/42710/7c776f24-1035-3349-c33a-a249c6fb7041.png)

要は「Microsoft Office IME 2010を保護モードの外で実行するけどいい?」という警告です。つまりMicrosoft Office IME 2010が保護モードに対応していないということなのでしょう。今まで出ていなかったのになぜ? と思ったら、Offce 2011をインストールしたので、その時にIMEの設定が変えられてしまったようです。

Office 2011をインストールしたWindows 7にはMicrosoft IMEが入っているので古いMicrosoft Office IME 2010を使う必要はありません。今まで大丈夫だったのはMicrosoft IMEを使っていたからでしょう。

ということで設定を開くと、Microsoft IMEが無い。

![capture2.png](https://qiita-image-store.s3.amazonaws.com/0/42710/f8d795b6-b812-4ea2-2d4a-e962e02f59bb.png)

でも存在はしているので「追加…」から追加することができます。

![capture3.png](https://qiita-image-store.s3.amazonaws.com/0/42710/4a9e7a2e-c42f-d9d1-bc55-303abbe7acb3.png)

Microsoft IMEにチェックを入れて、Microsoft Office IME 2010のチェックを外せば完了です。

![capture4.png](https://qiita-image-store.s3.amazonaws.com/0/42710/9a22592a-2a1e-2f87-be93-c5b951d72d02.png)
数GB以上の巨大なXMLをPythonで読むときのメモリ節約法

# はじめに

機械可読なデータをやり取りするときはJSONが主流になって久しい世の中ですが、XMLでデータが配布されることは時々あります（古くからある機関が公開してくれているデータとか）。
あるいは自然言語処理をしていると、たとえば構文解析機の `CaboCha` には解析結果をXML形式で出力するオプション (`-f 3`) があるので、結果の処理がいわゆる `lattice` の形式より楽になるという意味で使ったりすることがあるのではないでしょうか。

私は後者のクチで、大きめのコーパスの構文解析結果をXMLに落としてあれこれしようとしていたのですが、その8GBのXMLを手元にあるメモリ64GBのマシンで処理しようとしたところ、メモリがいっぱいになって途中から進まなくなってしまいました（エラーすら吐かない）。
がんばってメモリを増やしたぞーというつもりで64GBにしたのでちょっとびっくりしました。

問題のXMLは、`<root>` のタグの下に、`<item>` というタグが何個もぶら下がっている、リスト形式状のものです。レコード形式ということもあるようです。

```xml
<root>
    <item>...</item>
    <item>...</item>
    ...
    <item>...</item>
</root>
```

一つ一つの `item` を処理するときは他の `item` とは無関係で、順々に見ていけたらよいものとします。そういうタイプのデータが巨大なときには `iterator (generator)` を使うとメモリにやさしいというのは多くの方がご存知かと思います。
もちろん XML を扱うライブラリにも、XMLファイルを `iterator` で読み込めるメソッドはあるのですが、ちょっとコツが必要でした。

# Python 標準ライブラリ で XML

Python で XML を処理するときは標準の `xml.etree.ElementTree` を使うのが手軽です。他にも有名ドコロで [BeautifulSoup](https://www.crummy.com/software/BeautifulSoup/bs4/doc/) というのもありますが、HTMLに特化している関係で私が扱いたいXMLでは解析エラーになる箇所があり[^1]、ハマってしまったので標準ライブラリに落ち着いています。
本稿ではこの標準ライブラリ `xml` で `iterator` なXMLパースをするときの注意について述べます。

## ふだんの使い方（全部メモリに入れる）

`iterator` とかしないで普通に使うときはこうです。

```python
import xml.etree.ElementTree as ET

tree = ET.parse('path/to/xml')

for item in tree.iterfind('item'):
    # do something on item
```

`.iterfind()`でXMLツリーのなかの `<item>` タグを `iterator` しながら読み込んでいますね。でも、その直前の `ET.parse()` はいうなれば `file.readlines()` みたいなものです。メモリをたくさん食べます。

## iter するとき（でもメモリは食べる）

`iter` しながら読みたいときはこうです。

```python
import xml.etree.ElementTree as ET

context = ET.iterparse('path/to/xml')

for event, elem in context:
    if elem.tag == 'item':
        # do something on item
```

`ET.parse()` を `ET.iterparse()` にすると、引数のパスにあるXMLを `iterator` 形式で読み込みます。1タグごとに読んでいくのですが、タグの終わりに差し掛かったときにだけ `context` は `event` と `elem` を返します。`event == "end"`で、`elem`は エレメントですね。

これで省メモリに処理ができる！と思ったら大間違いなのです。実は `# do something on item`のところが`pass`であっても、**「ふだんの使い方」と同じくらいのメモリを使います**。

**`iter`しながらも、それまで読んだタグを `context` はすべて保存しているんです**。

どこかというと、`context.root` というローカル変数が iterator の中に隠れているんです。そんなことは公式ドキュメントにすら書いてなかったので知りませんでした。普通の `generator` と違って、あとから繰り返しアクセスできるという意味ではうれしい人もいるかもしれないでしょうか。まぁXMLの入れ子構造を読みながら保持するためにはそういう仕組みも必要そうなのは言われてみれば想像できます。

## iter するとき（メモリを食べない）

ではどうすればよいかというと、その昔 `ElementTree` という名前のライブラリとして Python 2.5 で標準に組み込まれる前までの[公式ページ](http://effbot.org/zone/element-iterparse.htm)に Tips がありました。Pythonは3からの新参者だったので全然しりませんでした。

```python
import xml.etree.ElementTree as ET

context = ET.iterparse('path/to/xml', events=('start', 'end'))

_, root = next(context)  # 一つ進めて root を得る

for event, elem in context:
    if event == 'end' and elem.tag == 'item':
        # do something on item
        root.clear()  # 用が済んだらrootを空に
```

`ET.iterparse()`には`events`というキーワード引数を指定できて、これに`'start'`を指定すると開きタグを教えてくれるんだそうです。最初の開きタグは`<root>`なので、これを変数にとっておきます。このとき`_`で捨てている値には件の文字列`'start'`が入っています。

`root` さえ取ってしまえば[^2]、都度中身を`.clear()`すればエレメントの情報がメモリから退散します。めでたいですね。


---

[^1]: HTMLで予約されている `<link />` などの単独タグがXMLで使われていると、中にテキストがあっても消されてしまう。対処法はたぶんあったけどうまく行かなった記憶があります。

[^2]: 一昔前のAndroidみたいな響きで素敵ですね。
Android Studio 3.0でのGradleプラグインの非互換性

まとめ: Gradleプラグイン作者の皆様におかれましては、 Gradle Android Plugin 3.0.0-alpha2 において出力APKファイルに依存するプラグインがだいたい動かなくなりましたので、一度動作を検証されることをお勧めします

# 高速化のため挙動が変わった部分

Android Plugin からプロジェクトがビルドで出力するAPKファイルを取得したいときは、 variant の outputs から outputFile を参照するってことをやりますが、 3.0.0 から高速化の兼ね合いでこれが参照できなくなりました。

```groovy
android.applicationVariants.all { variant ->
    variant.outputs.all { output ->
        file = output.outputFile // outputFile が参照できない
    }
}
```

configuration フェーズだけかと思いきや、ビルドに入っても(実際にそのタスクが走らない限り)参照できないままです。

# 発生する現象

大体において大変に不幸な感じで、例えば DeployGate の Gradle プラグインだと configuration するだけでも

```
Error:Could not get unknown property 'variantOutputData' for ApkVariantOutputImpl_Decorated{apkData=Main{type=MAIN, fullName=prodDebug, filters=[]}} of type com.android.build.gradle.internal.api.ApkVariantOutputImpl.
```

なんてエラーで止まって原因の切り分けが困難で(なおこういうときは `./gradlew --stacktrace` でスタックトレースが出るので原因を探しやすくなります)、別の例で Fabric Beta にアップロードしようとしてみると、

```
Error:Execution failed for task ':app:crashlyticsUploadDistributionProdDebug'.
> Not valid.
```

といった感じで、どちらにしてもとても人間に優しくないエラーメッセージが出ます。

# 既知の問題で、まだ新APIが実装されてない

ソース: https://developer.android.com/studio/preview/features/new-android-plugin-migration.html#variant_api

> ### API change in variant output
Using the Variant API to manipulate variant outputs is broken with the new plugin.

てなわけで壊れて(broken)ます。壊れてるのは一時的な問題ですが、

> As an alternative, we will introduce new APIs to provide similar functionality.

将来的には新しいAPIで対応してねって話になるようなので、更新され次第対応する必要があります。今は大人しく次のバージョンを待つしかない😇

# その他参考情報

- [dexcount-gradle-plugin も動かないので新API待ち](https://github.com/KeepSafe/dexcount-gradle-plugin/issues/161)
ド素人のための Travis CI の使い方 (公式ガイドより)

[Travis CI for Complete Beginners - Travis CI](https://docs.travis-ci.com/user/for-beginners) より

# 動作確認用のレポジトリをForkする

https://github.com/plaindocs/travis-broken-example で Fork ボタンを押すだけ

( * Forkは好きなレポジトリを自分のレポジトリとして、まるまるコピー出来る機能)

# ForkしたレポジトリをCloneする

手元に持ってくる

```
$ git clone git@github.com:YOUR_USER_NAME/travis-broken-example.git
$ cd travis-broken-example
```

# Travisの設定ファイルを見てみる

何やらいろいろ書かれているが、複数の php バージョンでテストしようとしてるのが分かる。
hhvm というのも php 環境のひとつらしい。

```yaml:.travis.yml
language: php # テスト言語
php:
- 5.5 # 環境その1
- 5.4 # 環境その2
- hhvm # 環境その3
script: phpunit Test.php # この処理がCIとして走る
```

# テストスクリプトを確認

あえて失敗するテストが書かれている。

`1+1=1` を期待しているテストなので、失敗するのが正しい状態。

```php:Test.php
<?php
class Test extends PHPUnit_Framework_TestCase
{
	public function testOnePlusOne() {
		$this->assertEquals(1+1,1);
  	}
}
?>
```

# Travis CI に登録する

https://travis-ci.org/ より。

# Travis でレポジトリを有効化する

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/f08fb971-a3ee-567a-2c63-0fd5c7ef9141.png)

## ブランチが表示されない場合

「Sync account」を試す。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/257198b1-cfb4-9164-f7b1-1c7dba872a90.png)



# 適当なコミットを作ってプッシュする

```
$ git add -A
$ git commit -m 'Testing Travis CI'
$ git push
```

# テストが回り始める

複数のPHP環境で、それぞれテストが動くのが分かる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/eee1d468-5bc8-6c48-d9f9-46b24cd91e8b.png)

# やがてテストが落ちる

これも期待通りの動作。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/469b3129-3891-8944-f387-ca35729af0fe.png)

# テストファイルを修正する

`1+1=2` にする。

( 1+1 って 2 ですよね？ 皆さん！ )

```diff:Test.php
<?php

class Test extends PHPUnit_Framework_TestCase
{
	public function testOnePlusOne() {
-		$this->assertEquals(1+1,1);
+		$this->assertEquals(1+1,2);
  	}
}

?>
```

# git push する

# 新しいテストが回り、今度は成功する

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/3e08a710-524c-879c-445f-2326b809cd8d.png)

やったぜ！

# バッジを付けてみる

ちょっと分かりにくいが、Travis CI に表示されている「バッジボタン」を押すと埋め込みコードを取得できる。

画面に見えてるこいつ => ![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/0c46969a-5fa6-e221-4217-6d32c3e16ba3.png)

形式は Markdownを選ぶ。

これを Github のREADMEなどに貼り付ければ良い。
(お試しにIssueやWikiに貼っても良いと思う)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/148931c8-1e9f-9536-9600-578d04841425.png)

## Github の README に埋め込みコードを追加

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/a52bb2a7-aace-4856-69ff-4315d5b4446e.png)

## 表示例

このバッジでCIが通っているか、落ちているかを確認できるようになる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/fc48826f-8577-79ed-4113-a2722398ba09.png)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Tips : [Python] fastaファイルから配列を無作為復元抽出する

　大量の配列から無作為抽出したくなるときは時々あります。
　今回はそんなときに使うコードを紹介します。

　やり方は単純にファイルを開き、配列を乱数で選んでアクセスしていきます。

```py3:配列を乱数で選んでアクセス
#配列取得
seqnum=random.randint(1,seqnumMAX)
name = linecache.getline(infn, seqnum*2-1) #配列名
seq = linecache.getline(infn, seqnum*2)　 #配列
#書き込み
outfdl    =   open(outfn, 'w')
outfdl.writelines(name+seq)
outfdl.close()
linecache.clearcache() #キャッシュをクリア
```

　このとき読み込みには```linecache.getline（入力ファイル名, 行数）```を使います。
　これを使うと指定した行の読み込みを内部で最適化してくれます。
　Bioinformaticsでは大きな配列ファイルを扱いがちなので便利かもしれません。

　この処理を取得したい回数分だけループしていけば無作為復元抽出ができます。


　以上をちゃんとした処理としてまとめると以下のようになります。

```py3:randsampleFasta.py
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-

"""
fastaファイルから配列を無作為復元抽出する。
"""
__author__  = "Kazuki Nakamae <kazukinakamae@gmail.com>"
__version__ = "0.00"
__date__    = "29 May 2017"

import sys
import mmap
import linecache
import random

def randsampleFasta(infn,outfn,n):
    """
    fastaファイルから配列を無作為復元抽出する。
    @param  infn 読み込むfastaファイル名{string} 
    @param  outfn 出力するfastaファイル名{string} 
    @param  n 復元抽出する配列数{int} 
    """

    infdl     =   open(infn, 'r')
    #入力ファイルの配列数確認
    print('Checking how many sequences are in a FASTA format sequence file....(1/2)')
    buf = mmap.mmap(infdl.fileno(), 0, prot=mmap.PROT_READ)
    seqnumMAX= 0
    readline = buf.readline
    while readline():
        seqnumMAX += 1
    seqnumMAX = int(seqnumMAX / 2)
    infdl.close()
    print(str(seqnumMAX)+' sequences')
    #配列を無作為復元抽出
    print('random sampling from a sequence with replacement....(2/2)')
    outfdl    =   open(outfn, 'w')
    random.seed(a='hoge', version=2)    #シード設定
    seqi=1
    while seqi<=n:
        seqnum=random.randint(1,seqnumMAX)
        name = linecache.getline(infn, seqnum*2-1)
        seq = linecache.getline(infn, seqnum*2)
        outfdl.writelines(name+seq)
        seqi += 1
    outfdl.close()
    linecache.clearcache() 
    print('done.')

if __name__ == '__main__':
    argvs = sys.argv  # コマンドライン引数
    argc = len(argvs) # 引数の数

    if (argc != 4):   # 引数チェック
        print("USAGE : python3 randsampleFasta.py <INPUT.fa> <OUTPUT.fa> <NUMBER_OF_SEQUENCES>")
        quit()

    randsampleFasta(argvs[1],argvs[2],int(argvs[3]))
quit()

```

実施例
---

　入力するファイル

```text:test.fa
>1
CCGTATTGGAAAGCTC
>2
AGGATTATCGGATACT
>3
ATCCGGACGGGGGGTT
>4
GACCTCGTTATCATCC
>5
AGTCAGGTTACCCGCA
```

　Bash上での入力

```bash:入力
python3 randsampleFasta.py test.fa out.fa 4
```

　Bash上での出力

```bash:標準出力
Checking how many sequences are in a FASTA format sequence file....(1/2)
5 sequences
random sampling from a sequence with replacement....(2/2)
done.
```

　出力ファイル

```text:out.fa
>3
ATCCGGACGGGGGGTT
>2
AGGATTATCGGATACT
>4
GACCTCGTTATCATCC
>3
ATCCGGACGGGGGGTT
```

コードの利用
---
自由です。
Azure で Webサーバーに HTTP リクエストを送るだけのスケジューラ候補

表題のことをやりたいと思ったときに Azure にはいくつもの候補が出てきます。
そのうちどれを選ぶべきかで3時間消耗したので、まとめておきます。

## [Scheduler](https://azure.microsoft.com/ja-jp/services/scheduler/)
- たぶん真っ先に選択肢に上がる
- ポータルで簡単に作成
- 費用が安定
- 分、時間、日、週、月単位での実行

## [Automation](https://azure.microsoft.com/ja-jp/services/automation/)
- PowerShell で実装
- スクリプト(Runbook)とスケジューラを別に管理できてわかりやすい
- 時間、日、週、月単位での実行

## [Functions](https://azure.microsoft.com/ja-jp/services/functions/)
- 好きな言語で実装
- 頻度次第でかなり安い
- タイマートリガーを使ってCRON式でスケジュール実行

## [Logic Apps](https://azure.microsoft.com/ja-jp/services/logic-apps/)
- ポータルで簡単作成
- あまり頻繁だとそれなりの金額になる(毎分で¥4000弱)
- [アクセス元のIPアドレスが限定されている](https://docs.microsoft.com/en-us/azure/logic-apps/logic-apps-limits-and-config)
- 秒、分、時間、日、週、月単位での実行
自作コマンドラインツールでオートコンプリートする

自作のコマンドラインツールでも `tab` 補完はできないと，ということで，どうやるかを調べてみたら意外と簡単だった．

## コマンドの仕様
`git` みたいなサブコマンドがあるタイプがいいので，ここでは例として，レンタカーを借りる時に使うコマンドとしてこんな感じに `car-rental` コマンドとしてみる

```bash
car-rental  book    car            sedan
                                   mini-van
                                   suv
            option  navi
                    booster-sheet
            cancel  car            <reservation_id>
                    option         <option_id>
```
## 最初の引数の補完

こんな感じで，スクリプト `auto-complete-car-rental` を書いて

```bash
#!/bin/bash

first="book cancel"

# auto complete function
_auto_complete()
{
  local cur=${COMP_WORDS[COMP_CWORD]}
  COMPREPLY=( $(compgen -W "$first" -- $cur) )
}

# map the function to the target command - 'car-rental'
complete -F _auto_complete car-rental
```

読み込む

```bash
. auto-complete-car-rental
```

これで `car-rental` +`<tab>`で一つ目の引数の補完ができるようになる

```bash
$ car-rental # press <tab> here
book    cancel
```

## 二番目の引数の補完   

`$COMP_CWORD`に引数が何番目のものなのかを示す番号がはいっているっぽい．引数の順番（番号）に応じて候補を出すために， `case` 文で分岐する．

```bash
#!/bin/bash

first="book cancel"
second="car option"

_auto_complete()
{
        local cur=${COMP_WORDS[COMP_CWORD]}

    case "$COMP_CWORD" in
        1) COMPREPLY=( $(compgen -W "$first" -- $cur) ) ;;
        2) COMPREPLY=( $(compgen -W "$second" -- $cur) ) ;;
    esac
                
}
complete -F _auto_complete car-rental
```

## 三番目の引数の補完

三番目の引数は，二番目の引数`$prev`が`car`なのか`option`なのかで変わるので，その分岐をいれる．

```bash
#!/bin/bash

first="book cancel"
second="car option"
third_after_car="sedan mini-van suv"
third_after_option="navi booster-sheet"

_auto_complete()
{
        local cur=${COMP_WORDS[COMP_CWORD]}
        local prev=${COMP_WORDS[COMP_CWORD-1]} # previous argument

        case "$COMP_CWORD" in
        1) COMPREPLY=( $(compgen -W "$first" -- $cur) ) ;;
        2) COMPREPLY=( $(compgen -W "$second" -- $cur) ) ;;
        3)
          case $prev in
            car)
              COMPREPLY=( $(compgen -W "$third_after_car" -- $cur) ) ;;
            option)
              COMPREPLY=( $(compgen -W "$third_after_option" -- $cur) ) ;;
          esac
        esac
                
}
complete -F _auto_complete car-rental
```
あとは，引数が増えてもこの繰り返しでいけそうな感じ．

## 参考にしたサイト

- [How to extend bash completion in other directory?](https://stackoverflow.com/questions/38285872/how-to-extend-bash-completion-in-other-directory)
- [Bashの補完について](https://rcmdnk.com/blog/2015/05/14/computer-linux-mac-bash/)
- [bash なんて書いたことない人が補完関数をとりあえず自作する](http://qiita.com/sosuke/items/06b64068155ae4f8a853)
phpで2つの配列のキーと値が同じであることを確認する

以下のように、キーと値が同じであるが、順序が違う配列があるとします。

```php
$array1 = [1 => 'apple', 2 => 'orange'];
$array2 = [2 => 'orange', 1 => 'apple'];
```

上記```$array1 === $array2```では同じと判定されません。

これをksortなどでソートしていたのでは処理が複雑になります。

１回で判定するには、

```php


$array1 = [1 => 'apple', 2 => 'orange'];
$array1 = [2 => 'orange', 1 => 'apple'];
if (!array_diff_assoc($array1, $array1)) {
    echo '２つの配列のキーと値に差分はありません';
}

```

~~array_diff_assocは２つの配列のキーと値に差分が無ければ空の配列を返します。~~

上記のようにキーと値が同じであるが順序が違う配列であれば、同じであることの検証に使えます。

ただし以下のように、

```php

$array1 = [1 => 'apple', 2 => 'orange'];
$array2 = [2 => 'orange', 1 => 'apple', 3 => 'banana'];
var_dump(array_diff_assoc($array1, $array2));
// []
```

キーと値が同じではない配列を比較する場合は同一であることの確認には使えません。

array_diff_assocは、array1の要素のうち、 その他の配列のいずれにも含まれないものだけを残した配列を返します。

詳細は以下よりご確認頂けます。
https://www.php.net/manual/ja/function.array-diff-assoc.php
[Swift 5]キーボードを閉じるボタン（画像）をキーボード上部に追加する

#概要
TextView等の入力欄がキーボードに重なってしまう等で閉じるボタンが欲しいさい、画像（アイコン）で表示できたら余分なスペースを取られなくて済むと思い実装しました。

#実装コード例

```swift:ViewController.swift
   @IBOutlet weak var textView: UITextView!

   override func viewDidLoad() {
        super.viewDidLoad()
        
        // 任意の数値
        let buttonWidth: CGFloat = 70
        let buttonHeight: CGFloat = 44
        // ボタンを表示するためのViewを作成
        let keyboardToolView = UIView()
        keyboardToolView.frame.size.height = buttonHeight
        keyboardToolView.backgroundColor = .clear
        // キーボードを閉じるボタンを作成する（画像は任意のものを）
        let closeKeyboardButton = UIButton(
            frame: CGRect(x: UIScreen.main.bounds.size.width - buttonWidth,
                          y: 0,
                          width: buttonWidth,
                          height: buttonHeight
            )
        )
        // 通常時のボタン設定
        closeKeyboardButton.setImage(UIImage(named: "DismissKeyboardButton"), for: .normal)
        // タップした時のアクションを指定
        closeKeyboardButton.addTarget(self, action: #selector(closeKeyboard), for: .touchUpInside)
        // Viewに閉じるButtonを追加する
        keyboardToolView.addSubview(closeKeyboardButton)
        // システムキーボードの上にViewを追加する
        textView.inputAccessoryView = keyboardToolView
    }
```
`UIImage(named: "DismissKeyboardButton")` の　DismissKeyboardButton　を任意の画像名に変えてください。
自分の場合は Assets.xcassets に PDFで入れています。
画像単体で入れている場合は DismissKeyboardButton.png のようになるかと思います。
CentOS7上でSeleniumからGoogle Chromeのヘッドレスモードを利用する


Google Chrome 59より実装されたヘッドレスモード(--headless)を利用したSeleniumの環境をCentOS7上に構築する。

## 環境
- CentOS 7.3
	- `yum install epel-release`をしておく。
- Google Chrome 60以上
- ChromeDriver 2.29

## ChromeDriverのインストール

EPELに登録されているバージョンが2.27なので、[Downloads - Chrome Driver - WebDriver for Chrome](https://sites.google.com/a/chromium.org/chromedriver/downloads)よりダウンロードして展開する。
展開先はPATHが通っているとやりやすい。

```bash
wget https://chromedriver.storage.googleapis.com/2.29/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
sudo mv chromedriver /usr/local/bin/
sudo chown root:root /usr/local/bin/chromedriver
```

動作に必要なライブラリを入れる。

```bash
sudo yum install -y libX11 GConf2 fontconfig
```

## Google Chromeのインストール

`/etc/yum.repos.d/google-chrome.repo`を作る。

```
[google-chrome]
name=google-chrome
baseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearch
enabled=1
gpgcheck=1
gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub
```

59はウィンドウサイズの指定が効かなかったので60(2017-05-30時点でunstable)のほうをインストールする。

```bash
sudo yum install -y google-chrome-unstable libOSMesa google-noto-cjk-fonts
```

libOSMesaはCentOS7におけるクラッシュへの対応のため。
https://bugs.chromium.org/p/chromium/issues/detail?id=695212

## 接続確認

Python版のSeleniumで動作を確認。

```python
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service


options = Options()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--window-size=1280,1024')
service = Service(executable_path='/path/to/chromedriver')
driver = webdriver.Chrome(service=service, options=options)
driver.get('https://www.google.co.jp/')
print(driver.title) #=> Google
driver.save_screenshot('test.png')
driver.quit()
```

test.pngが文字化けしていなかったら恐らく正常。
apex try-catchブロックのテスト

本当にこれでいいのか正直自信がないのですが、他の人の意見も聞いてみたいので、私の普段のやり方を投稿してみます。

基本的にApexでの開発の場合、try-catchしなくても、最低限のエラー情報はメールとかでとれるので、そんなガバガバとtry-catch入れる必要はないのかなぁと思ってるのですが、DML文の発行などでは、行ロックの可能性なんかを考えて、一応try-catchするようにしてます。
ただ、そういうtry-catchは、テストコードの中でExceptionを狙って出せないので、簡単にはカバーできません。

ではどうするのかというと、私の場合は以下のような方法で無理やり狙ったExceptionを発生させてカバーしてます。

```java
public class pageController
  List<Account> accounts {get; set;}
  @testVisible private isDMLExceptionTest;

  public pageReference doSaveAll() {
    if(this.accounts != null && !this.accounts.isEmpty()) {
      try {
        update this.accounts;
        //テスト中に限り、強制的にDmlExceptionを発行させる
        if(Test.isRunningTest() && this.isDMLExceptionTest){
          insert new Account();
        }
      }
      catch(DmlException e) {
        ApexPages.addMessages(e);
        return null;
      }
    }
    return null;
  }
}
```
Test.isRunningTest()はテストコードの中での実行されているとき、trueになります。
これを、@testVisibleで修飾したprivateなメンバ変数とくみあわせ、Exceptionを発生させたいテストコードの中でフラグ立てをし、狙ったExceptionが発生する適当なコードを実行させて、無理やりExceptionをキャッチしてます。
一応、これでExceptionが発生した場合の挙動を再現できます。

ただ、本当はもっとスマートな方法があったりするんじゃないかといつも悩んでるので、もし良い解決方法(あるいは、そもそもそんな時はtry-catch使うべきではないとか、そういうコードのカバーはあきらめる等)があればご意見いただけると幸いです。
デバイストークン取得（Unity）

１：Apple Developer Program　から　プッシュ通知サービスのチェックを付けて、AppIDsを作成
２：１で作成したAppIDsを使ってプロビジョニングプロファイルを作成
３：Unityを開き、１で作成したバンドルIDをセットする。
４：下記コードを実装してボタンから呼べるようにする。

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GetToken : MonoBehaviour {

	// Use this for initialization
	void Start () {

		UnityEngine.iOS.NotificationServices.RegisterForNotifications(
			UnityEngine.iOS.NotificationType.Alert | 
			UnityEngine.iOS.NotificationType.Badge | 
			UnityEngine.iOS.NotificationType.Sound);
	}

	public void GetTokenString()
	{
		GetTokenData ();
	}


	private void GetTokenData ()
	{
		#if UNITY_IPHONE

		string deviceToken = "";
		// デバイストークン取得
		byte[] token = UnityEngine.iOS.NotificationServices.deviceToken;
		if (token != null)
		{
			deviceToken = System.BitConverter.ToString(token).Replace("-", "");
		}
		else
		{
			deviceToken = "Nothing";
		}

		// ベンダーID取得
		string identifierForVendor = UnityEngine.iOS.Device.vendorIdentifier;

		Debug.Log("deviceToken=" + deviceToken);
		Debug.Log("identifierForVendor=" + identifierForVendor);

		#endif

	}
}
```


　
５：ビルドする。
６：Xcodeを開いて、**Capabilities**タブを選択して Push Notifications を **ON** にする。
７：Generalタブを選択して、Singingの**Automatically manage sigining** のチェックを外す
８：Signing（Release）等のプロビジョニングプロファイルの設定を2で作成したものに設定する。
９：実行する。
１０：実機にて通知を許可するか聞かれるので、「はい」を選択
１１：ボタンをタップして、Xcodeのログにデバイストークンが表示される事を確認
[Swift5] iOSアプリのバージョンとビルドを取得し、ラベルに表示する

#概要
SwiftでiOSアプリのバージョンとビルド情報を取得する方法の備忘録。
VersionとBuildとは、TARGETS -> General -> Identity の下２行のこと。

#バージョンとビルド情報を取得
```Swift:ViewController.swift
let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
		
let build = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String
```

#ラベルに表示する場合
```Swift:ViewController.swift
// Storyboard上のLabel等にOutletを繋ぐ
@IBOutlet weak var versionLabel: UILabel!

override func viewDidLoad() {

    versionLabel.text = "\(version) (\(build))"
    // こんな風に表示されます -> 1.0.0 (1)
}
```
僕はTableViewCellのラベルで表示するのに使いました。

適宜、心配な方はオプショナルにしてデフォルトを設定するなどするとより安全かもしれません。

```swift
(Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String) ?? "Unknown"
```

#Androidでは？
FlutterでAndroidも調べたところ、以下のような対比になっているようですね。

versionName = CFBundleShortVersionString
versionCode = CFBundleVersion

#参考元
[iOSアプリのバージョンを取得する](http://qiita.com/arthur87/items/802d17387ae46fb44fc2)
[AndroidとiOSのアプリバージョン周りについてまとめてみた](https://qiita.com/tarappo/items/6d20d2f4bc03135ed9c7)
ノンプログラマーがMastodon BotをIFTTTとかRSSあたりで作ったドン

僕はエンジニアでもプログラマーでもありませんがQiitadonの中を見たくてQiitaアカウント作ったので、そのついでにQiitaへ記事を1本書いておきます。

# RSS更新をIFTTTで取得してMastdonへ自動投稿するbotを作る
↑これを作ります。
参考にすればツイッター連携でも何でも作れるはず。

マストドンは、自動投稿とか嫌うインスタンスや住民が多いので、Twitterみたいな使い方はしない方がいいんじゃないかなーと個人的には思いますが、地域インスタンスにその地域メディアの更新情報とか流してローカルタイムラインでワイワイやったりするのに使えます。
宣伝とかしまくるのはオススメしませんし、止めてほしいドン。


さて、僕はノンプラグラマーなのでコード書かずにbot作ります。
前提としてIFTTT が何だか分かる、それなりに操作くらいはできるという方なら誰でも作れます。多分。


# 1. Mastodonのアクセストークン取得する
いきなりアクセストークンとか言われると何のことやら分からず怖いですが、Mastodonのインスタンスに外部からのアクセス許可証的なものをいただくんだと思ってください。

本当はCurlコマンドとかでアレコレするらしいのですが、僕はそういうの怖いんでブラウザでフォーム埋めるだけでアクセストークンが取得できる @takahashim さんのAccess Token Generator for Mastodon APIを使います。

https://takahashim.github.io/mastodon-access-token/


- 事前にMastodonでトゥートするアカウントを作っておきます
- [Access Token Generator for Mastodon API](https://takahashim.github.io/mastodon-access-token/)にアクセス

| 項目 |入力するもの| 
|:-----------|:------------|
| Mastodon URL|トゥートしたいインスタンスのURLを入力|
| Client Name|この連携アプリの名前です。適当に決めます。(例:Rss2Mstdn)|
| Web site|tootにつくリンクらしいけど、設定は任意なので僕は空欄にしときます|
| Scopes|権限です。トゥートする(書き込み)ので write にしておきます。|

- 上記のように埋めて「Publish access_token」ボタンをポチっとするとMastodonのインスタンスにログインが求められるのでトゥートするアカウントでログインします
- アクセストークンが表示されます
- showボタンを押して、取得した「access_token」をどこかにメモっておきます

これでMastodonのアクセストークン取得は完了。



# 2. IFTTTにアプレット作る
アプレットっていうのは「RSSの更新をとって」「Mastodonにトゥートする」みたいなのを自分で設定した簡易アプリみたいなもののことです。

とりあえず下記の通りにすれば何となくわかるはず。
(UIの表記とか変わるかもしれないけど、そこらへんは上手く感じとってください)

https://ifttt.com

- IFTTTにアクセスしてログイン(IFTTTアカウントは作成してね)　
- My Applets > New Applets と移動
- 「if✚this then that」と書かれてるとこの「✚this」をポチッとな
- RSS更新でトゥートするなら「RSS Feed」を選びます。Twitterでも何でもお好きなのを。
- RSS更新でトゥートする場合は「New feed item」を選択して取得するRSS FeedのURLを入れます。まあ、ここらへんはよしなに。「Create trigger」をクリックしてトリガーセット完了。


トリガー(何があったら動くか)がセットされたので、
次にアクション(トリガーが起動したら何をするのか)を決めます。

- 「if then ✚that」と書かれてるとこの「✚that」をポチッとな
- 検索するか選択するかして「Maker Webhooks」を探して選択します。
- 「Make a web request」をクリック

| 項目 |入力するもの| 
|:-----------|:------------|
| URL|https://■マストドンのドメイン■/api/v1/statuses|
| Method|`POST`を選択|
| Content Type|`application/x-www-form-urlencoded`を選択|
| Body|アクセストークンとトゥートする内容が入る。下記を参考に。|

Bodyには、下記のような感じで入力します。
よく分からないという人は、下記のグレーの部分をコピーして■だけ書き換えれば動くと思います。
`
access_token=■&visibility=public&status=【ブログ更新】{{EntryTitle}} {{EntryUrl}}
`

- 上記のaccess_token=■....は事前に取得したアクセストークンに書き換える
- 【ブログ更新】の部分は適当に書き換えるなり消すなりしてください。
- 言うまでもないと思うけど、 `{{EntryTitle}}` はRSSから取得したタイトル
- ` {{EntryUrl}}`はRSSから取得したURLです


- 色々終わったら「Create Action」的なボタンを押して確認などする
- 「Finish」ボタンもポチっとなしておく


# 3. Feedから適切にトゥートされてるか確認
おわり。

# 繰り返すけれど

マストドンに宣伝トゥートしまくるbotはいらない。
ローカルタイムラインを楽しく盛り上げるために使ってほしいドン。