OmniAICreator/Qiita-1.07M huggingface dataset:
LinuxコマンドをPythonから上手に扱う方法

LinuxコマンドをPythonから扱う方法は多数ありますが、標準出力と標準エラー出力を構造的に扱える `Popenクラス` を利用する方法が一番しっくりきます。


# 登場する関数
|関数名  |分類  |型  |
|---|---|---|
|Popen().stdout.readline()  |標準出力 結果から1行だけ出力  |str  |
|Popen().stdout.readlines()  |標準出力 結果を配列で全て出力  |list[str]  |
|Popen().stderr.readline()  |標準エラー出力 結果から1行だけ出力  |str  |
|Popen().stderr.readlines()  |標準エラー出力 結果を配列で全て出力  |list[str]  |

# 標準出力と標準エラー出力をPythonから扱う

```py:output.py
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from subprocess import PIPE, Popen


def cmdline(command):
    """
    コマンドを実行する。shell=Trueの場合シェル経由で実行する。
    :param command: str
    :return: Popen
    """
    return Popen(
        args=command,
        stdout=PIPE,
        stderr=PIPE,
        shell=True
    )


# 標準出力
print '標準出力:' + cmdline('date').stdout.readline()

# 標準エラー出力
print '標準エラー出力: ' + cmdline('echo 2015|xargs wc -l').stderr.readline()
```

```shell-session:実行結果
>>> python output.py
標準出力:2015年 12月 7日 月曜日 18時47分09秒 JST
標準エラー出力: wc: 2015: open: No such file or directory
```

# gitの最新commitハッシュを取得
```py:git.py
# git の最新commitハッシュをprint
print cmdline('git log --oneline').stdout.readline()

# 別リポジトリの最新commitハッシュをprint
print cmdline('cd ~/pypi/cf_recommender/ && git log --oneline').stdout.readline()
```

```shell-session:実行結果
>>> python git.py
6a2ae0a xlsx update by automatic
a2febc4 update readme
```

# 標準エラー出力が存在するときchatでエラー通知

```py:chat.py
# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals
from subprocess import PIPE, Popen


def cmdline(command):
    """
    コマンドを実行する
    :param command: str
    :return: Popen
    """
    return Popen(
        args=command,
        stdout=PIPE,
        stderr=PIPE,
        shell=True
    )


def chat(message):
    # ダミー実装
    print 'ERROR:' + message


# 標準エラー出力時にエラー内容をchatで通知
cmd = [
    'python manage.py test_json',
    'python manage.py test_battle',
]

# コマンド実行時の接頭語, && で複数コマンドをチェインする
prefix = 'cd ~/application/ && {}'

for _cmd in cmd:
    command = prefix.format(_cmd)
    p = cmdline(command)
    print 'command:' + command

    # 標準エラー出力が存在するときはchatで通知
    errors = p.stderr.readlines()
    if errors:
        error_message = ''.join(errors)
        chat(error_message)
```

```shell-session:実行結果
command:cd ~/application/ && python manage.py test_json
ERROR:Traceback (most recent call last):
  File "manage.py", line 10, in <module>
  ...
IOError: [Errno 2] No such file or directory: u'..../test.json'

command:cd ~/application/ && python manage.py test_battle

```


もっと便利な方法を知っている人がきっといるはず( ・ㅂ・)و
初めてAnsibleに触れた際、playbookで少し解決に悩んだ点。（複数指定、ユーザ関連など）


Ansibleを使い始めてから、少し考えた点などをメモとして残しております。適宜、追記。


###[Best Practices](http://docs.ansible.com/ansible/playbooks_best_practices.html)でRole使用時のtask, handler, varsに関して


```yaml:playbook.yml
- hosts: all
  remote_user: root
  vars:
	admin_name: admin
  tasks:
    - name: Add a new user
      user: name={{admin_name}} groups="wheel" state=present
```

このようなansibleの`playbook`があったとする。これを[Best Practices](http://docs.ansible.com/ansible/playbooks_best_practices.html)の構成に従って、Role使用時のtask, handler, varsにそれぞれ分割する。


```
roles/common/tasks/main.yml
roles/common/handlers/main.yml
roles/common/vars/main.yml
```
このような場合、各tasks, handlers, varsにmain.ymlが存在すれば自動的にこれらの内容が読み込まれる。


以下は、`task`を`roles/common/tasks/main.yml`に移した場合だが、これだとエラーが出る。

```yaml:roles/common/tasks/main.yml
tasks:
    - name: Add a new user
    user: name={{admin_name}} groups="wheel" state=present
```

発生するエラー

```
ERROR: expecting dict; got: tasks, error in /your/tasks/path/main.yml
```

#####解決

```yaml:roles/common/tasks/main.yml
- name: Add a new user
  user: name={{admin_name}} groups="wheel" state=present
```

roles以下の各tasks, handlers, varsのmain.ymlはroleを使用時に自動的に読みこまれるため、`-tasks`などの記述は不要になる。vars, handlersに関しても、同様。

###[Best Practices](http://docs.ansible.com/ansible/playbooks_best_practices.html)でRole使用時のgroup_vars/host_varsの変数の利用に関して

以下のように、`group_vars/all.yml`に`user`という変数が設定されている場合

```yaml:group_vars/all.yml
user: hoge
```

直接、`{{user}}`として、変数の内容を利用することができる。

```
- name: Add a new user from group_vars:all
  user: name={{user}} groups="wheel" state=present
```

今回は、`users`として１ユーザに各変数を持たせた場合を考える。

```yaml:group_vars/all.yml
users:
  - { name: hoge, password: "fuga", groups: "wheel" }
```

この場合、以下のようにリスト変数を利用することで各変数の内容を取得可能だった。

```
- name: Add a new user from group_vars/all.yml
  user: name={{item.name}} groups="wheel" state=present
  with_items: users
```

###Ansibleで対象を複数指定をしたい場合
例えば、ユーザ作成時にグループに複数のグループを指定する

```
- hosts: localhost
  task
    - name: Add a new user
      user: name=hoge groups="wheel,fuga" state=present
```

例えば、`groups`で複数のグループを指定したい場合は、`,(カンマ)`を利用。
※注意： `,(カンマ)`の前にスペースが入ると、それが認識されるので注意！！

####通常はrootユーザで実行し、特定のタスクのみ指定のユーザで実行
例えば、ユーザ作成時にグループに複数のグループを指定する

```
- hosts: localhost
  become: on
  task
    - name: Create test file
      file: path=/home/hoge/test.txt state=touch mode="u=rw,g=r,o=r"
      become_user: hoge
```

例えば、hogeユーザでtest.txtというファイルを作成する場合、
`become_user`で実行ユーザを指定する。


###ファイルの転送にSFTPではなく、sshを利用する

```yaml:ansible.cfg
[defaults]
transport=ssh

[ssh_connection]
ssh_args=
scp_if_ssh=True
```

###対象サーバの設置情報を取得する

対象のサーバの設定状況を知りたい場合は、以下のコマンドで取得可能

```
ansible -i hosts -m setup
```
シェルで複数ファイルのリネーム

ファイルが1、2個ならデスクトップでやるけど、10個くらいになってくると面倒だし間違いそうなので1発でガッとファイルをリネームしたかった。



`sed` とパイプを使って:

```zsh
for a in *; do b=`echo "${a}" | sed -e "s/^/prefix-/"`; mv "${a}" "${b}"; done
```

でファイルの先頭に `prefix-` という文字列を追加してる。

読みやすくすると:

```zsh
for a in *; do # カレントディレクトリのファイル一覧を取得
  b=`echo "${a}" | sed -e "s/^/prefix-/"` # sed で `prefix-` という文字列を追加
  mv "${a}" "${b}" # 移動
done
```

sed の置換は vim と同じなので sed 初めて使ったけどサクッとできた。

---
追記:

コメントでもっとシンプル + 安全にやる方法を教えていただきました。

>```bash
for a in * ; do
    mv -i "${a}" "prefix-${a}"
done
```

ディレクトリを除外したい場合は、

> ```bash
for a in * ; do
    [ -f "${a}" ] && mv -i "${a}" "prefix-${a}"
done
```

とするといいようです。
JUnitの徒然

設計、製造と終わってJUnitに着手している。

JUnitもほぼ未経験なので、言葉の理解とトライアンドエラーとなった部分をメモ。

- DBUnit
Excelに書いたデータをDBに入れてくれる便利な部品。
今のPJでは、テストclassの親になるAbstractClassを作っていて、initializeDatabase、finalizeDatabaseと書くだけで
実行できるような工夫がされててさらに便利。

- DataPoints、Theory
テストケースを書くのに便利なアノテーション。
@DataPointsで、パターン化したテストケースの型(fixture)を用意し、
@Theoryで、メソッド引数に入れる事で自動的にパターン数分の呼び出しがされる。
fixtureには、「テストメソッドの引数+期待値」を全部定義しておくと、IN・OUTが1箇所に集められるので見やすい。

```java:サンプル
@RunWith(Theories.class)
public class ServiceImplTest extends AbstractClass {
public static class MethodFixture {// 内部クラス
        public final Long input1;
        public final Long input2;
        public final String return;
        
        MethodFixture(Long input1, Long input2, String return) {
            this.input1 = input1;
            this.input2 = input2;
            this.return = return;
        }
    }

@DataPoints
    public static MethodFixture [] METHOD_FIXTURE = {
            new MethodFixture (10L, 100L, true), // OKパターン
            new MethodFixture (10L, 500L, false), // NGパターン1
            new MethodFixture (40L, 100L, false), // NGパターン2
            new MethodFixture (40L, null, false),// 例外パターン
    };// テストケースが一覧化できる

@Theory
    public void testMethod_検証(MethodFixture fixture) {
        String actual = service.method(fixture.input1, fixture.input2,fixture.return);
        
        assertThat(actual, is(fixture.return));
    }
}
```

内部クラスを使ったテストケース設計は、パラメータにクラスを持ったメソッドだと手間だな～と感じた。
内部クラスのコンストラクタには配列化して渡して、内部でうまくくっ付ける、とか、小細工してどうにか切り抜けてる。
iPhoneの実機ログを確認する方法

通常アプリのログを確認するときにはXcodeのデバッグモードでログ出力を行いますが、AdHoc版であったり、リリース版でもログを確認したいときがあります。

そういう時のログ出力をして確認する方法を紹介したいと思います。

### Xcodeのログ出力機能を使用する
まず、iPhoneをMacに接続します。
そして、Xcodeを起動して、Devices画面（ツールバー・Window > Devices）を表示します。

Devicesの画面下部のところにあるこのボタンをタップします。

![スクリーンショット_2015-12-07_18_20_02.jpg](https://qiita-image-store.s3.amazonaws.com/0/40009/275c414a-3d3d-244a-3ad3-74fdd017ebc8.jpeg)

すると、ログがこのように出力されます。

![スクリーンショット_2015-12-07_18_19_42.jpg](https://qiita-image-store.s3.amazonaws.com/0/40009/e8013570-b718-ae5c-dc20-b2564758889e.jpeg)

NSLogで出力されるログはもちろんですが、それ以外にもシステムメッセージなども表示されます。
アプリのエラーなどを確認するときにはアプリのBundle IDで検索すれば、該当のアプリのメッセージを抽出できるかと思います。

### ログ出力アプリ「iOS Console」を使う
Xcodeを起動するのが面倒な人はこちらも。

フリーのアプリで「iOS Console」というアプリがあります。
http://lemonjar.com/iosconsole/

接続されたiPhoneのログを出力し続けるというアプリです。
上記で説明したXcodeでのログ出力とほぼ同じログが出力されます。

<img width="730" alt="スクリーンショット 2015-12-07 18.20.14.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/40009/72e33070-9f8a-1971-45a4-97570d89a53e.jpeg">

このアプリのいいところは右上の検索窓でキーワードで絞り込みができます。

<img width="730" alt="スクリーンショット 2015-12-07 18.20.25.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/40009/f3f76799-79ef-a769-310d-81e5cb26b73d.jpeg">

アプリのBundle IDでフィルターすれば、かなり快適に絞り込みできると思います。

Xcodeのログ出力画面は小さくて、フィルターできないので自分はこっちを使っています。


Wi-FiスポットをキャッチするログとかiPhoneでの1つ1つの動作でのログが出力されるのはなかなか興味深いです。
[UITextView] How to count Lines of Text

Counting Lines of Text


1.Counting hard line breaks

```
    NSString *string;
    unsigned numberOfLines, index, stringLength = [string length];
    for (index = 0, numberOfLines = 0; index < stringLength; numberOfLines++){
        index = NSMaxRange([string lineRangeForRange:NSMakeRange(index, 0)]);
    }
```
    
    
2.Counting lines of wrapped text

```

    NSLayoutManager *layoutManager = [textView layoutManager];
    unsigned numberOfLines, index, numberOfGlyphs = [layoutManager numberOfGlyphs];
    NSRange lineRange;
    for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){
        (void) [layoutManager lineFragmentRectForGlyphAtIndex:index
                                               effectiveRange:&lineRange];
        index = NSMaxRange(lineRange);
    }
```


Reference:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/TextLayout/TextLayout.pdf
MasonryをAngularで使う際に注意すること



kotaziです。
- [kotazi.com](http://kotazi.com)


Masonryのstampが正しく動かないことがあったのでメモ。

<hr>

Angularプロジェクトで[Masonry](https://github.com/desandro/masonry)と[AngularJS Masonry Directive](https://github.com/passy/angular-masonry)を利用している。  
その際にMasonryのstampが動いていなかったのでメモ。
なんで動かなかったかというと[MyInclude](http://qiita.com/ukyo/items/0aa47142020c07874415)とngIfがよくなかった。  
とりあえずサンプル


### ■ ng-ifバージョン(動かない)

<p data-height="266" data-theme-id="15717" data-slug-hash="ojRRmP" data-default-tab="result" data-user="kotazi" class='codepen'>See the Pen <a href='http://codepen.io/kotazi/pen/ojRRmP/'>【AngularJS】Masonry Directive Behavior with Stamp(ng-if)</a> by Kohei  Saeki (<a href='http://codepen.io/kotazi'>@kotazi</a>) on <a href='http://codepen.io'>CodePen</a>.</p>
<script async src="//assets.codepen.io/assets/embed/ei.js"></script>

### ■ ng-showバージョン(動く)

<p data-height="266" data-theme-id="15717" data-slug-hash="EVBZeG" data-default-tab="result" data-user="kotazi" class='codepen'>See the Pen <a href='http://codepen.io/kotazi/pen/EVBZeG/'>【AngularJS】Masonry Directive Behavior with Stamp(ng-show)</a> by Kohei  Saeki (<a href='http://codepen.io/kotazi'>@kotazi</a>) on <a href='http://codepen.io'>CodePen</a>.</p>
<script async src="//assets.codepen.io/assets/embed/ei.js"></script>

ngIfの場合がDOMが再生性されているので、stampが毎回解除されてしまう。
HugoブログとGithub Pagesと独自ドメイン


kotaziです。
- [kotazi.com](http://kotazi.com)

Wordpressで続けていたブログをやめて、Hugoでブログを作りなおした。
以前の記事は削除した。
[Hugo](https://gohugo.io/)はGoで書かれた静的サイトジェネレータだ。早くて便利。

<hr>


## Hugoブログの立ちあげ

基本的には公式サイトの[Quickstart](https://gohugo.io/overview/quickstart/)に従う。

```
# Hugoをローカルで立ちあげ
hugo server --theme=hugo-cactus-theme --buildDrafts -w

# 新しく投稿
hugo new post/newpost.md
```

## Github Pages

Github PagesもHugo公式の[Hosting on GitHub Pages](https://gohugo.io/tutorials/github-pages-blog/)を参考にする。  

- `git subtree`を使う
- 全体のコンテンツは`master`ブランチに、公開ファイルを`gh-pages`ブランチで運用
- `deploy.sh`の作成
  
  
チュートリアルに沿えばGithub Pagesにサイトができる。

## 独自ドメイン

僕はもともとムームードメインで取得したドメインと、ロリポップのレンタルサーバーを使ってWordpressブログを使っていた。  
それにあたりこちらの記事を参考にした。  

[Hugo + GitHub Pagesでブログを作る#2|TANKSUZUKI.COM](http://tanksuzuki.com/post/hugo-github-pages-2/)  

- サブドメインと`Zone Apex`(kotazi.com)で公開するのでは手順が異なる
- ムームードメインでは`Apex Alias`が使えない
- そのため[Gehirn DNS](https://www.gehirn.jp/)などを使う必要がある

##### 　
そんな感じでブログの移行が完了しました。
Mac Bookを買い換えた時に作業したことリスト


## 概要

エンジニアを始めて1年程度ですが、先日、Mac Book Airの11インチから、Mac Book Proの15インチに買い換えました。
（快適すぎてやばいです。なんだかんだ持ち運びも慣れますし。）

その時に作業したことのまとめです。
買い換えた人でなはなく、初めてMacを買った人にも参考になるかと思われます。


## Time Machineを使わなかった理由

Macを買い換えると、Time Machineという機能で、一気にデータ移行することが出来ます。
しかし、僕は手作業でやることを選びました。

その理由は、

1. 初心者の時にインストールした余計な様々なものや不要なものがコピーされるのがイヤだった
2. 大事な資料、アプリなど、頭の整理になる気がした
3. 結局Time Machineを使っても、手作業でやらないといけない部分がある（らしい）

といったところでした。


## 実際手作業で移行してみて

所要時間はぜんぶで3時間程度でした。

新しいMacで作業して1ヶ月程度経ちますが、なんの不自由もありません。

今までいかに不要なアプリケーションやらよく分からない書類に溢れていたのかを思い知る結果となりました。


## 実際の作業内容

### 1. 前のMacの中身を整理する

特にDocumentsディレクトリにある大事っぽそうなものをピックアップしていきます。

具体的には、

* 大事な書類
* pdf形式の電子書籍
* プレゼン資料

あたりです。

これらはUSBメモリーに入れておくか、軽めのファイルはgoogledriveとかにアップロードして、必要に応じて新しいMacにも移行しました。

### 2. Appをインストールする

僕がデスクトップでよく使用していたアプリは、

* Chrome
* LINE
* Slack
* Evernote
* Sequel Pro
* Twitter
* Kobito

この辺でしたので、順次インストールしていきました。

Kobito以外はクラウドなので一瞬で使えるようになります。

### 3. Kobitoの内容を移行する

メモ系のアプリとして圧倒的にKobitoを利用しており、しかも大半はローカルにしか無かったので、どうしても移したかったという経緯があります。

実はkobitoのデータは、

```bash
~/Library//Containers/com.qiita.Kobito/Data/Library/Kobito/Kobito.db
```

というファイルに保存されています（知らなかった〜）。

なので古いMacの方で、

```bash
cp ~/Library//Containers/com.qiita.Kobito/Data/Library/Kobito/Kobito.db ~/Desctop/kobito_copy
```

とコピーして、コピーした```kobito_copy```をAirdropで新しいMacに渡します。

そして新しいMacで、

```bash
cp ~/Downloads/kobito_copy ~/Library//Containers/com.qiita.Kobito/Data/Library/Kobito/Kobito.db
```

とコピーします。Kobitoを開いて確認するとちゃんとデータが反映されていて、めでたしめでたしです。

### 4. sshの鍵

基本的に開発しているアプリケーションは全てクラウド上にあるので、sshのための鍵だけコピーすれば事足ります。

これもkobitoのデータ移行と大体同じで、

1. ```/.ssh/```以下のファイルをコピー
2. Airdropで送る
3. 新しいmacで```/.ssh/```に置く

という手順で問題なく行けます。

### 5. ターミナルとvimの設定

ターミナルは開いた瞬間、色やフォントを今までのように変更しました。
またメインのエディタとしてvimを使っていたので、これも前Macの```./vimrc```の内容をコピペして終了。

### 6. Githubと通信できるかのチェック

自分のリポジトリとかで、ちゃんとclone, pull, commitあたりをできるかチェック。
僕の場合はここまでの過程で```./gitglobal```のメールアドレスの設定のみ上手くいっていなかったので、そこだけ設定したら、あとは今まで通り使用可能でした。

### 7. Railsまわりの設定

通常の開発環境設定と同じです。
mysql、rbenv、gemなど順次設定していきました。
OSがEI Capitanになって```bundle install```で今まで遭遇しなかったエラーに遭遇して多少時間ロスしましたが、特に問題なく、１年前に苦労して環境設定していた頃からの成長を感じました。


## まとめ

他にも細かい内容はあった気がしますが、大体ここまで述べた感じで、調べる時間も込みで3時間程度で開発再開できました。

余計なものが色々なくなり頭の中も整理された気がするので、ぜひ、新しいMacを購入された方は手作業でデータ移行してみてください。
カバレッジ100%を目指す

オレオレルールを晒す第二弾。

ソースコード内のどの程度の割合を自動テスト出来るか、という指標を、テストカバレッジといいます。カバレッジの定義を真面目にやろうとするとC0とかC1とかいろいろ出てきますが、ここでは「とりあえず一通り動かす」という雑な理解で話を進めます。

# ruby の弱点
よく言われる ruby の弱点の1つとして、「動的言語なので、他の言語ではコンパイル時にわかるエラーが事前に発見できない」というものがあります。
例えば以下のコードを御覧ください。

```ruby
def edit
  @post = Post.find(params[:id])
  raise RestfulError::Forbiden unless @post.user_id == current_user.id
end

RSpec.describe 'edit' do
  subject { get :edit, id: post.id, session }
  let(:post){ FactoryGirl.create(:post, user_id: user.id) }
  it { is_exptected.to render_template('edit') }
end
```
編集しようとする post が自分の post じゃなければ例外を投げる、という処理です。テストを雑に用意しましたが、このテストは ``raise RestfulError::Forbiden`` の部分を通りません。
実は ``Forbiden`` の部分でスペルミスをしているのですが、 ruby は動的言語ゆえ、実際にスペルミスの箇所を実行しない限り、エラーが起きません。 Java や C のようなコンパイル畑からやってきた方には「これだからrubyちゃんは信用できないのよね」と陰口を叩かれがちです。

そこで。
自動テストで「とりあえず全てのコード片を一通り評価させる」というのを目指すわけです。

(ちなみに [RestfulError](/kuboon/items/b1c82d13f0e2c3373240) は拙作の gem です。ぜひご利用ください！)

# 条件分岐にそって context を書く
状況によって挙動が変わるメソッドのテストを書くときには、取りうる値を全部テストせよとか境界条件をテストせよとかこれもいろいろ理論があるのですが、とりあえず置いといて、ここではとにかく「カバレッジ100%を目指す」ことだけを考えます。

上述のコードを、条件分岐にそって context を書くと以下のようになります。

```ruby
RSpec.describe 'edit' do
  subject { get :edit, id: post.id, session }
  let(:post){ FactoryGirl.create(:post, user_id: post_user_id) }
  context '@post.user_id == current_user.id'
    let(:post_user_id){ user.id }
    it { is_exptected.to render_template('edit') }
  end
  context '@post.user_id != current_user.id'
    let(:post_user_id){ 0 }
    it { exptect{subject}.to raise_error }
  end
end
```
([describe の次行に subject を、 context の次行に let を書く](http://qiita.com/kuboon/items/a3726dd865702f6f7e35) も参照ください)

もう少し複雑に条件分岐している例はこちら。条件分岐にそって context を書くようにすると、構造化のルールが一定し、100％カバーテストを記述しやすくなります。

```ruby
def fizzbuzz(num)
  if num % 3 == 0
    ret = 'Fizz'
    if num % 5 == 0
      ret << 'Buzz'
    end
  elsif num % 5 == 0
    ret = 'Buzz'
  else
    ret = num.to_s
  end
  ret
end

RSpec.describe 'fizzbuzz' do
  subject { fizzbuzz(num) }
  context 'num % 3 == 0' do
    let(:num){ 3 }
    it { is_expected.to eq 'Fizz' }
    context '&& num % 5 == 0' do
      let(:num){ 15 }
      it { is_expected.to eq 'FizzBuzz' }
    end
  end
  context 'num % 3 != 0 && num % 5 == 0' do
    let(:num){ 5 }
    it { is_expected.to eq 'Buzz' }
  end
  context 'num % 3 != 0 && num % 5 != 0' do
    let(:num){ 4 }
    it { is_expected.to eq '4' }
  end
end
```