OmniAICreator/Qiita-1.07M huggingface dataset:
[初心者向け] Ruby on Rails デバッグ方法まとめ

### 内容
伊藤淳一さんの[プログラミング初心者歓迎！「エラーが出ました。どうすればいいですか？」から卒業するための基本と極意](https://www.youtube.com/watch?v=5fyrGslhUcY) という動画の内容を自分なりにまとめたものです。
とても分かりやすくまとまっており、特に初心者にとっては有益な情報だと思ったので文字に起こしてみました。

### エラーでチェックする項目
- エラーメッセージ
     - `Comment(#XXXXXX) expected, got String (#XXXXXX)`、のようなもの。
     - 英語がわからないなら翻訳してでもまずは何がいけないのかエラーメッセージを見ることでちゃんと確認する。
- エラーのタイプ確認
     - `ActiveRecord::AssociationTypeMismatch`、のようなもの。
     - ネットで調べると、どういった場合におこるエラーなのかがわかる。
- ユーザーが操作した手順
     - サーバーのログを確認して、どのような操作や画面遷移によってエラーが発生したか確認する。
     - 操作とは例えば、トップページにきた、あるページをクリックした、SQLが発行された、など。

### エラー画面に出てくるトレースの種類とその説明
- Full Trace
     - 自分が書いたコードからgemやrailsがどのような動作をしているかを確認できる
     - 読み方としては、一番下がスタートで上に向かってどんどん呼ばれていく
     - 一番上がエラーが起きているところ
- Application Trace
     - 自分が書いているコードに関する内容
- Framework Trace
     - フレーム側のみのトレース
     - あまりデバッグをする際には使わない

### 便利なgem
- better_errors
     - Railsの標準のエラー画面よりも使いやすい画面を提供してくれる
     - 併せてbinding_of_callerというgemもインストールしておくといい。
- byebug
     - デバッグ実行を行うことができる。
- pry-byebug
    - デバッグを行いたい部分に`binding.pry`と書くとそこでアプリの実行が中断し、パラメーターなどをpryで確認することができる。

### デバッグの具体的な方法
- putsコマンドを利用
     - 例えば、`puts params[:comment]`などをコードに記述することでparamsに渡された値をターミナルのログから確認できる
     - いわゆる原始的な方法
- byebugを利用する
     - デバッグをしたいところ(エラーが起きているところ)でbyebugと書くとそこで実行がとまり、ターミナル上から確認したい変数などの中身を確認できる
     - `params[:commnet]`や`params[:commnet].class`など
     - byebugの機能はhelpコマンドで確認できる
     - デバッガ使ってない人はbyebugを利用するといい
- ブレークポイントをつける(RubyMineなどのIDEを利用している場合)
     - デバッグをしたい箇所にブレークポイントをつける
     - Rubymineにある虫マークのついた実行ボタンからサーバーを起動するとデバッグ実行できる。
     - console から確認したい変数などの中身を確認できる
- better_errorsで表示されたエラー画面を利用する
     - 画面上にコンソールがあるので(>>と出ている部分)、そこからパラメーターの値などを確認できる
- テストコードを書く
     - エラーが起きるステップをテストコードに落とし込み、エラーを再現させる。
     - 実際に画面上でエラーを再現するよりも、テストコードに落とし込んだほうが「修正→再実行」のサイクルを早く回すことができる。
- エラーが起きるかを確認するためだけの簡単なアプリを別で作る
     - エラーでどうしても詰まってしまった場合や、アプリ自体が巨大な場合などに行う方法。
     - 別アプリとして作成しエラーが再現するか確認することで、エラーが発生する場所を特定することができる。

### その他、デバッグ時に行うこと
- 自分のコードに問題がなさそうなのであればgemのバグを踏んでしまった可能性もある。その場合は、エラーに関係していそうな怪しいgemの見当をつけてgithubで検索し、issueがあがってないか確認する。併せて、Readmeやwikiも確認するとよい。
- 公式ドキュメントを読む
- エラーメッセージで検索して、質問サイトやブログなどを確認。ただし、公式ページとは違い、当たり外れがあるので要注意。
- 同僚に聞いたり、ネット(Teratail, Stack Overflow, QA@ITなど)で質問してみたりする。

### デバッグの心構え
- やみくもにデバッグしない。
     - まずは仮説を立ててから検証を行う。
     - 「仮説->検証」のサイクルを繰り返すことで徐々に原因を絞り込んでいく。
- 新しい知見はQiitaやBlogで共有する。
     - 自分と同じことで悩んでいる人たちの助けになる
     - さらに良い解決策のフィードバックがもらえるかもしれない
- 時間を区切る
     - 例えば30分なら30分と決めて、無理だったら誰かに聞く。誰かに聞くと一瞬で解決するケースがよくある。

### 補足
個人的な経験としては、どうしても詰まった場合、その日は思い切って諦めて次の日に持ち越すと意外とすぐに簡単に解決することがよくあるのでおすすめです。
また、デバッグ時に例えば`current_user`というオブジェクトの中身を確認したいときは、modelやcontroller上で確認したければ`logger.debug(@current_user.to_yaml)`や`logger.debug(@current_user.inspect)`を、view上で確認したければ`<%= debug @current_user %>`と記述すると確認できます。原始的な方法ですが自分は結構利用しています。

### まとめ
自分は開発をする際は我流でデバッグをすることが多かったのですが、デバッグについてちゃんと理解する良いきっかけになりました。
動画は1時間にわたる大作となっております。実際にデバッグを行なっているデモがありますし、説明も丁寧なので是非一度見てみるといいと思います。
MacにつないだAndroidスマホからデータをコピーする

#課題
Windowsだと，Androidスマホを接続して外部ストレージとして参照できるけど，Macだとそのままではスマホの中が見れない．

#解決法
Android file transferというアプリをMacに入れる．かんたん．

#手順
1. 公式のDLページからアプリをダウンロード．https://www.android.com/filetransfer/
2. インストール
3. スマホを接続すると，ファイルが参照できる！コピーもできる！

#注意
コピーできるのは4GBまでなので，大きなファイルは扱えない・・・
備忘録：HTMLタグの動的に振られた id 操作

下記のように、HTMLタグの id を末尾インクリメントして動的に振るような場合でよくやるTips。

```html
<input type='text' id='inputbox-1' />
<input type='text' id='inputbox-2' />
<input type='text' id='inputbox-3' />
...
```
```javascript
$("input").click(function(){
    console.log($(this).attr('id'));
});
```

'inputbox-1'のように取得できるので、そこから文字列末尾を採取。
その値を他のHTMLタグに紐付けて使用します。

```javascript
var text = $(this).attr('id');
var suffix = text.substr( text.length -2, text.length );
$('#myModal'+ suffix).modal('show');
```
WKWebViewが一定時間後に真っ白になる現象への対策

WKWebViewを表示してから一定時間後放置すると(?)表示が真っ白になっていることがあったので、firefox-iosのissueを参考に以下のコードを置いたところ、真っ白な表示を見ることがなくなりました。

``` Swift
func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
    webView.reload()
}
```

参考: https://bugzilla.mozilla.org/show_bug.cgi?id=1205004
組み込みMySQLを使ったSpockによるSpringBootのユニットテスト

# 概要

[組み込みMySQL（wix-embedded-mysql）](https://github.com/wix/wix-embedded-mysql) をSpringBootTest、Spockと組み合わせて使う際に、少しハマったのでその対応方法。

# ハマりどころ

サンプルで動かしてみるところまではうまく行ったが、複数のテストケースを動かそうとするとうまくいかない。
元々やろうとしてたのは下記の通り。

- 各テストクラスの実行前にMySQLを起動（setupSpec）
- テスト終了時に停止（cleanupSpec）

ところがこれをやろうとするとクラスが増えるとうまくいかない。
どうも下記のようなところで不都合が出る模様。

- SpringBoot(Test) 起動と組み込みDBの起動停止の兼ね合い
- 組み込みDBをテスト実行の中でいつ起動するか停止するかで組み込みDBのプロセス管理を考える必要が出て来る
  - 例えばSpringBootの起動前にDBは立ち上がっている状態にしておかないと、dataSourceやflywayなどのDBマイグレーションが動かない

setupSpecじゃなくてDIコンテナに登録しておくとか、色々試してみたものの、最終的に下記の対応に落ち着いた。

# 対応

- 組み込みMySQLインスタンスはテストフェーズの中でひとつにする
- 全てのテストの中で最初に実行されるテストで起動し、テスト中はそのインスタンスを使い続ける
- 具体的にはSingleton(staticファクトリーメソッド方式)で組み込みMySQLインスタンス提供するUtilityを用意
- setupSpecで、そのインスタンスを明示的にロード
   - 最初にロードされた時点で組み込みMySQLが起動し、以降は使いまわされる
   - どのsetupSpecが最初に呼ばれるかは保証されないので全テストクラスに必要
   - setupSpecはSpringBootの起動より前に呼ばれる

# サンプル

## MySQLインスタンス提供ユーティリティ

```java
public final class EmbeddedTestMysql {

  private EmbeddedTestMysql() {
  }

  // プロジェクトに合わせた組み込みMySQLの設定
  private static final Version VERSION = Version.v5_5_40;
  private static final Charset CHARSET = Charset.UTF8;
  private static final int PORT = 13306;
  private static final String SCHEMA_NAME = "sample";

  private static final MysqldConfig MYSQLD_CONFIG = MysqldConfig.aMysqldConfig(VERSION)
      .withCharset(CHARSET)
      .withPort(PORT)
      .build();

  private static final SchemaConfig SCHEMA_CONFIG = SchemaConfig.aSchemaConfig(SCHEMA_NAME)
      .withCharset(CHARSET)
      .build();

  private static final EmbeddedMysql SINGLETON_INSTANCE = EmbeddedMysql.anEmbeddedMysql(MYSQLD_CONFIG)
      .addSchema(SCHEMA_CONFIG).start();

  // staticファクトリーメソッドによるシングルトンインスタンスを提供
  public static EmbeddedMysql getInstance() {
    return SINGLETON_INSTANCE;
  }
```

## 実際のテストクラス

```groovy
@Unroll
@SpringBootTest
class SampleRepositorySpec extends Specification {

    @Shared
    EmbeddedMysql mysql;

    @Autowired
    DataSource dataSource

    @Autowired
    SampleRepository sampleRepository

    def setupSpec() {
        // Bootの起動より前に呼ばれる
       // 初回にどこのテストが呼ばれるか分からないので、必ず書く
        mysql = EmbeddedTestMysql.getInstance()
    }

    def cleanupSpec() {
        // インスタンスを使いまわすので、mysql.stop()はしない
    }

    def setup() {
        // この時点でDBは起動している
        // Bootも起動している
        // 初期データの登録などが可能
    }

    def "何かしらのテスト"() {
        // データベースが必要なテストを実施      
    }
}
```

# 参考

- [組み込みMySQLを使ったユニットテスト](http://takezoe.hatenablog.com/entry/2016/05/26/100052)
- [Spring TestでEmbedded MySQLを使う方法](http://qiita.com/Iju/items/c36937efb7e2da605f7b)
Active Supportのsquishが文字列中の空白削除に便利

いつもメソッド名を忘れてしまうのでメモ。
Active Supportの`squish`を使うと、文字列の先頭と末尾の空白文字が削除され、文字列中の連続した空白文字を1つにしてくれて便利です。

``` Ruby
" foo   bar    \n   \t   boo  ".squish # => "foo bar boo"
```

ちなみに`activesupport-5.0.0.1`では、実装の中身が正規表現が1つだけの以下のような実装変わってます。

``` Ruby
def squish!
  gsub!(/[[:space:]]+/, ' ')
  strip!
  self
end
```
【Ruby】よく使う、CSVライブラリを使ったCSV操作


Ruby標準ライブラリの[csv](https://docs.ruby-lang.org/ja/2.3.0/library/csv.html)を使ったCSV操作で、個人的によく使うものを整理した。

次の`future_gadgets.csv`という名称のCSVファイルを例として使う。

```future_gadgets.csv
number,name,function
1号機,ビット粒子砲,おもちゃの光線銃にテレビのリモコンを合体させたもの
2号機,タケコプカメラー,軸の部分に小型カメラを仕込んだ竹トンボ
3号機,もしかしてオラオラですかーっ！？,ウソ発見器と称した発汗検知装置
```
出典: https://ja.wikipedia.org/wiki/STEINS;GATEの用語一覧

## CSVファイルから1行ずつ読み取りたい
[`CSV#foreach`](https://docs.ruby-lang.org/ja/2.3.0/method/CSV/s/foreach.html)を使う。
1行は1つの配列として表現される。

```ruby
require 'csv'

CSV.foreach('/path/to/future_gadgets.csv') do |fg|
  # fgはArrayクラス
  puts "[#{fg[0]}] #{fg[1]}: #{fg[2]}"
end
```

1行ずつ処理をするため、行数が多いCSVファイルを扱う場合でもメモリ使用量を気にしないで使える。

```txt:実行結果
[number] name: function
[1号機] ビット粒子砲: おもちゃの光線銃にテレビのリモコンを合体させたもの
[2号機] タケコプカメラー: 軸の部分に小型カメラを仕込んだ竹トンボ
[3号機] もしかしてオラオラですかーっ！？: ウソ発見器と称した発汗検知装置
```

## CSVファイルから1度に読み込みたい
[`CSV#read`](https://docs.ruby-lang.org/ja/2.3.0/method/CSV/s/read.html)を使う。
1行は1つの配列として表現され、全体として配列の配列が返り値となる。

```ruby
require 'csv'

future_gadgets = CSV.read('/path/to/future_gadgets.csv')
future_gadgets.each do |fg|
  # fgはArrayクラス
  puts "[#{fg[0]}] #{fg[1]}: #{fg[2]}"
end
```

```txt:実行結果
[number] name: function
[1号機] ビット粒子砲: おもちゃの光線銃にテレビのリモコンを合体させたもの
[2号機] タケコプカメラー: 軸の部分に小型カメラを仕込んだ竹トンボ
[3号機] もしかしてオラオラですかーっ！？: ウソ発見器と称した発汗検知装置
```

## CSV文字列から読み取りたい
ファイルではなく文字列としてのCSVを受け取りたい場合は、[`CSV#parse`](https://docs.ruby-lang.org/ja/2.3.0/method/CSV/s/parse.html)を使う。
`CSV#foreach`と同じく、ブロックには行が配列として渡される。

```ruby
require 'csv'

CSV.parse('foo,bar,baz') do |fg|
  puts fg[0] # => 'foo'
  puts fg[1] # => 'bar'
  puts fg[2] # => 'baz'
end
```

## ヘッダのフィールド名をキーにして操作したい
`CSV.foreach`や`CSV.parse`の第2引数にはHash形式でオプションを渡すことができ、ここに`headers: true`を与えることで、先頭行をヘッダして読み取ってくれるようになる。

これにより、ブロックに渡されるオブジェクトのクラスが`Array`から`CSV::Row`になる。
`CSV::Row`はフィールド名をキーとして使えるようになるのでコードが読みやすくなる。

```ruby
require 'csv'

CSV.foreach('/path/to/future_gadgets.csv', headers: true) do |fg|
  # fgはCSV::Row
  puts "[#{fg['number']}] #{fg['name']}: #{fg['function']}"
end
```

```txt:実行結果
[1号機] ビット粒子砲: おもちゃの光線銃にテレビのリモコンを合体させたもの
[2号機] タケコプカメラー: 軸の部分に小型カメラを仕込んだ竹トンボ
[3号機] もしかしてオラオラですかーっ！？: ウソ発見器と称した発汗検知装置
```

## 空行を読み飛ばしたい
`skip_blanks: true`をオプションとして渡す。
指定しない場合空行は空の配列などになるが、このオプションを指定することでスキップできる。

```ruby
require 'csv'

CSV.foreach('/path/to/future_gadgets.csv', skip_blanks: true) do |fg|
  # ...
end
```

空行があるとエラーになってしまったり面倒なチェック処理が必要になる場合が多いので、とりあえず指定することが多い。

## TSVを読み取りたい
RubyのCSVライブラリは、名前からCSVしか操作できないような印象を受けるがそうではない。
`col_sep`オプションで区切り文字を自由に設定できるので、TSVでも同じように扱うことができる。


```ruby
require 'csv'

CSV.foreach('/path/to/future_gadgets.tsv', col_sep: "\t") do |fg|
  # ...
end
```
Rustの文字列で、1文字ずつ大文字/小文字の変換をする

* Rustの勉強を始めて3日目ぐらいでハマりました。より良い方法を教えていただきたいので投稿します。普段はPythonです。
* 間違っているところ、Rustの理念に反しているところがたくさんあると思いますので、ご指摘よろしくお願いします。


##何をやりたいか
* yukicoderの[No.163](http://yukicoder.me/problems/no/163)
* 文字列中の小文字を大文字に、大文字を小文字に変換したい
* Ex) CapsLock -> cAPSlOCK

##TL;DR
皆様のコメントを受けて以下のようになりました。
(@takayahiltonさん、@tatsuya6502、@woxtuさんありがとうございました。)

```
fn capslock(c: char) -> char {
    if c.is_uppercase() {
        c.to_ascii_lowercase()
    } else {
        c.to_ascii_uppercase()
    }
}

fn convert(string: &str) -> String {
    string.chars().map(capslock).collect()
}
```

##はまった箇所
* 1文字ずつ変換を行わなければいけないのでとりあえずmap関数にかけたい。
* 文字列をchar型のiteratorに変換するのはchars()を使うらしい
* char型にはis_uppercase()やto_uppercase()などがあるのでこれは使えそう
* 簡単のために一文字ずつ大文字に変換するコードを素直に書くと

```
// エラー
fn convert(string: &str) -> String {
	string.chars().map(|x| x.to_uppercase()).collect::<String>()
}
```

* これがなぜエラーになるかというとto_uppercase()がiteratorを返すから
* なぜiteratorを返すかというと大文字のコードポイントが複数になる場合があるかららしい([参照](http://stackoverflow.com/questions/35432199/convert-a-char-to-upper-case))
* 複数のコードポイントを返すのは```'ﬁ' -> "FI"``` や ```'ß' -> "SS"```などの合字が返ってくる可能性があるから(@takayahiltonさんありがとうございました。)
* このiteratorをstring/&strに変更する方法がよくわからなかったので、charをstringにしてから大文字に変更する戦略へ
* **mapをflat_mapに変更するとこのまま動きます。**(@takayahiltonさんありがとうございました。)

##皆様のコメントを受けて
* 英語のみに対応するのであれば、char型のto_uppercase()ではなくto_ascii_uppercase()を利用するのが楽
* 

##コード
```
use std::ascii::AsciiExt;

fn getline() -> String{
    let mut ret = String::new();
    std::io::stdin().read_line(&mut ret).ok();
    ret
}

fn capslock(c: char) -> char {
    if c.is_uppercase() {
        c.to_ascii_lowercase()
    } else {
        c.to_ascii_uppercase()
    }
}

fn convert(string: &str) -> String {
    string.chars().map(capslock).collect()
}

fn main() {
    let s = getline();

    println!("{}", convert(s.trim()));
}
```

##感想
* 本当はchars()を使ってはいけないんだと思う(コードポイントが1つになるとは限らないので)
* しかしgrapheme関連のAPIがunstableなので断念
* C++をやりたくがないために勉強をしているが、Rustのありがたみを知るためにはC++の知識が必要そうです。
* Rubyに近い？
e-Stat 小地域のデータの読み方

総務省 e-Stat のデータ「平成２２年国勢調査（小地域）　2010/10/01」の「年齢別（５歳階級、４区分）、男女別人口」で「千代田区(10KB)」のヘッダの意味を読み解いてみる。間違ってたらコメントいただけるとありがたい。

基本的には「定義書」に書かれているべきな気がするが、定義書も意味がよく分からないところが多々…。「連番」とか「階層」とか説明が必要が見当たらない。

データを眺めると、次のような `MultiIndex` のカラムになっているように読める。

|0|1|
|:---|:---|
|KEY_CODE||
|HYOSYO||
|CITYNAME||
|NAME||
|HTKSYORI||
|HTKSAKI||
|GASSAN||
|T000573001|総数、年齢「不詳」含む|
|T000573002|総数０～４歳|
|T000573003|総数５～９歳|
|T000573004|総数１０～１４歳|
|T000573005|総数１５～１９歳|
|T000573006|総数２０～２４歳|
|T000573007|総数２５～２９歳|
|T000573008|総数３０～３４歳|
|T000573009|総数３５～３９歳|
|T000573010|総数４０～４４歳|
|T000573011|総数４５～４９歳|
|T000573012|総数５０～５４歳|
|T000573013|総数５５～５９歳|
|T000573014|総数６０～６４歳|
|T000573015|総数６５～６９歳|
|T000573016|総数７０～７４歳|
|T000573017|総数１５歳未満|
|T000573018|総数１５～６４歳|
|T000573019|総数６５歳以上|
|T000573020|総数７５歳以上|
|T000573021|男の総数、年齢「不詳」含む|
|T000573022|男０～４歳|
|T000573023|男５～９歳|
|T000573024|男１０～１４歳|
|T000573025|男１５～１９歳|
|T000573026|男２０～２４歳|
|T000573027|男２５～２９歳|
|T000573028|男３０～３４歳|
|T000573029|男３５～３９歳|
|T000573030|男４０～４４歳|
|T000573031|男４５～４９歳|
|T000573032|男５０～５４歳|
|T000573033|男５５～５９歳|
|T000573034|男６０～６４歳|
|T000573035|男６５～６９歳|
|T000573036|男７０～７４歳|
|T000573037|男１５歳未満|
|T000573038|男１５～６４歳|
|T000573039|男６５歳以上|
|T000573040|男７５歳以上|
|T000573041|女の総数、年齢「不詳」含む|
|T000573042|女０～４歳|
|T000573043|女５～９歳|
|T000573044|女１０～１４歳|
|T000573045|女１５～１９歳|
|T000573046|女２０～２４歳|
|T000573047|女２５～２９歳|
|T000573048|女３０～３４歳|
|T000573049|女３５～３９歳|
|T000573050|女４０～４４歳|
|T000573051|女４５～４９歳|
|T000573052|女５０～５４歳|
|T000573053|女５５～５９歳|
|T000573054|女６０～６４歳|
|T000573055|女６５～６９歳|
|T000573056|女７０～７４歳|
|T000573057|女１５歳未満|
|T000573058|女１５～６４歳|
|T000573059|女６５歳以上|
|T000573060|女７５歳以上|

`KEY_CODE`, `HYOSYO`, `CITYNAME`, `NAME`, `HTKSYORI`, `HTKSAKI`, `GASSAN` は先ほどの定義書に載っていない。
これらの意味が重要。

## KEY_CODE

行政コード。桁数に応じて区画の大きさが変わる。桁数は 5, 9, 11 とあり、行政コードのコード体系から始めて組み立てられている。大きい区画と、それに含まれる小さい区画も両方行として存在している。並行して存在しているときは、大きい区画には合計値が入っている。

## HYOSYO

`KEY_CODE` の組み立てられたコード体系の深さ？

## CITYNAME

一番大きな単位での土地の名前

## NAME

一番小さな単位での土地の名前

## HTKSYORI

「秘匿処理」が行われているかどうか。「秘匿地域」と「合算地域あり」の二種類があり、これらは相互の関係にある。

## HTKSAKI

`HTKSYORI` が「秘匿地域」になっている場合に値が入っている。
該当行の `KEY_CODE` 先頭　5 文字と連結して使う。

## GASSAN

`HtKSYORI` が「合算地域あり」になっている場合に値が入っている。
該当行の `KEY_CODE` 先頭　5 文字と連結して使う。
複数の地域を合算している場合はセミコロンで複数が連結されている。


# pandas

こんな感じ？

```
import pandas as pd

opts = dict(
    header=[0,1],
    converters={i:str for i in range(7)}
)
txt_ = pd.concat([pd.read_csv(open(f, encoding="CP932"), **opts) for f in glob.glob("tblT000573C27*.txt")])
txt_columns = txt_.columns
txt_.columns =  [c[0] if c[1].startswith("Unnamed:") else c[1] for c in txt_.columns]
txt = pd.concat([txt_[txt_.columns[:7]],
    txt_[txt_.columns[7:]].applymap(lambda s: 0 if s in ("-","X") else int(s))], axis=1)

for ri,r in txt.iterrows():
    for s in r["GASSAN"].split(";"):
        if not s:
            continue
        t = r["KEY_CODE"][:5]+s
        assert txt[txt["KEY_CODE"]==t].shape[0] == 1
```
atom-beautifyでJSXを整形する


ネイティブアプリ開発者がReact Nativeに入門してみて、慣れないAtomの設定をしたときのメモです。

# 背景

React Nativeでは基本的にindex.ios.jsやindex.android.jsをいじっていきます。
拡張子はjsですが、JSX（JavaScriptの拡張）を使っていくので、AtomでJSXで整形できるようにします。

環境は下記で試しました。

- Atom: 1.11.1
- atom-beautify: 0.29.13
- react: 0.16.1

# atom-beautifyをインストール

コードを整形するために`atom-beautify`というパッケージをインストールします。

下記のコマンドか、Preferences -> Installで`atom-beautify`を検索してinstallします。

```
apm install atom-beautify
```

これで`Ctrl-Alt-B`のショートカットか、ファイル編集部分で右クリックして`Beautify editor contents`でコードが整形できるようになります。

ただし、index.ios.jsなどのファイルを整形しようとするとデフォルトのJavaScriptで整形してしまうので次の手順でJSXで整形できるようにしていきます。

# reactをインストール

JSXでコードを整形するために`react`というパッケージをインストールします。

下記のコマンドか、Preferences -> Installで`react`を検索してinstallします。

```
apm install react
```

インストールできたらAtom画面の右下のファイルタイプにて`JavaScript(JSX)`を選択できるようになっているの変更します。

![Screen_Shot_2016-10-16_at_3_57_43_PM.png](https://qiita-image-store.s3.amazonaws.com/0/8868/aca7ff37-88ae-2e3c-5391-4b8ed3c4b8b9.png "Screen_Shot_2016-10-16_at_3_57_43_PM.png")


# 整形！

`Ctrl-Alt-B`のショートカットか、ファイル編集部分で右クリックして`Beautify editor contents`でJSXコードが整形。

以上で快適に開発ができるようになりました^^/

※ちなみにreactパッケージをインストールすると右クリックで`Reformat JSX`って項目も出てくるのですが動かず。。。
HSP3 のチェックサム計算

HSP3 (Hot Soup Processor 3) では、実行ファイルに含めるアーカイブにチェックサムが付与されていて、アーカイブの内容を改変するとチェックサムエラーで起動できないようになっています。

しかし、HSP3 のチェックサムは非常に簡単に計算できます。

## チェックサム計算スクリプト

以下、チェックサムを計算する HSP3 のソースです。

```
; ファイル読み込み
dialog "exe", 16
if (stat == 0) {
	end
}
filename = refstr
exist filename
filesize = strsize
sdim buf, filesize + 1
bload filename, buf, filesize

;; 実行ファイルか
;if (peek(buf, 0) != 'M' | peek(buf, 1) != 'Z') {
;	dialog "実行ファイルではありません"
;	end
;}
;
;; PE (Portable Executable) Header の位置を取得
;peOffset = lpeek(buf, 0x3c)
;
;; PE か
;if (peek(buf, peOffset) != 'P' | peek(buf, peOffset + 1) != 'E' | peek(buf, peOffset + 2) != 0 | peek(buf, peOffset + 3) != 0) {
;	dialog "PE ではありません"
;	end
;}

; 実行時オプション領域(HSPHED)を検索
; 先頭に DPM offset - 0x10000 が10進数で書かれているので
; ここではしらみつぶしにそれらしい箇所を探す (適当)
hedoffset = -1
repeat filesize
	offset = cnt
	c = peek(buf, offset)
	if ((c >= '0' & c <= '9') | c == '+' | c == '-') {
		getstr offsetstr, buf, offset, 0, 10
		tmpoffset = int(offsetstr) + 0x10000
		if (tmpoffset >= 0 & (tmpoffset + 3) < filesize) {
			if (peek(buf, tmpoffset) == 'D' & peek(buf, tmpoffset + 1) == 'P' & peek(buf, tmpoffset + 2) == 'M' & peek(buf, tmpoffset + 3) == 'X') {
				hedoffset = offset
				dpmoffset = tmpoffset
				break
			}
		}
	}
loop
if (hedoffset < 0) {
	dialog "HSPHED が見つかりません"
	end
}

sumHED = wpeek(buf, hedoffset + 0x14)
cryptKey4 = peek(buf, hedoffset + 0x17 + 3)

sumDPM = 0
dpmsize = filesize - dpmoffset
; (DPM 以降のバイナリの) チェックサムを計算
repeat dpmsize, dpmoffset
	offset = cnt
	sumDPM += peek(buf, offset)

	; ループ外で足しても問題ないはずなので
	; ループ外で加算
	; sumDPM += (cryptKey4 / 7)
loop
sumDPM += (cryptKey4 / 7) * dpmsize
sumDPM = sumDPM & 0xffff

if (sumDPM == sumHED) {
	dialog "チェックサムが一致しました " + strf("%04X", sumDPM)
}
else {
	dialog "チェックサムが一致しません " + strf("%04X", sumHED) + " / " + strf("%04X", sumDPM)
}
end
```
LaTeXで長い単語を入力する方法

## 問題点
LaTeXでメソッド名や関数名など，長い英単語を入力すると，うまく改行されずに枠からはみ出してしまう．

## 解決方法
seqsplitパッケージを利用して，`\seqsplit`コマンドを用いる．

```latex:sample.tex
% seqsplitパッケージを読み込む
\usepackage{seqsplit}
% \seqsplitコマンドを利用する
\seqsplit{veryveryveryverylongword}
```
tmuxのコピーモードを使わずに任意の範囲選択をする

## 環境
- MacOS 10.9.5
- iTerm2
- vim8.0

## こんなシーンありませんか
tmuxなどを使って画面を縦分割しているときに、左半分の画面をマウスを使ってコピーしたい。でもマウスからコピーすると右側の画面も選択範囲になってしまう。
<img width="1267" alt="Screen Shot 2016-10-16 at 15.18.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/2813/8e8dc2f3-ae8d-ddbd-a311-96b02f4704fa.png">

`def foo` ~ `end`だけをコピーしたいのに！！

## 解決策
`Command + option`を押しながら範囲選択をする。
すると次のように`def foo` ~ `end`だけを選択できる。
![a3420d3c866be6aba9c4ad63a88e20d0.gif](https://qiita-image-store.s3.amazonaws.com/0/2813/53509519-8499-a57b-8e3f-199ebf3c626d.gif)
GitLab で OpenStack Swift 上にバックアップ

GitLabのバックアップ先をOpenStack Swift（オブジェクトストレージ）に設定してみました。

# 動作環境
+ CentOS 7.2
+ GitLab 8.4.4

# OpenStackのSwiftにアクセスできるユーザとコンテナを作成

省略

# gitlabの設定ファイル変更

`/etc/gitlab/gitlab.rb`

```
gitlab_rails['backup_upload_connection'] = {
  'provider' => 'OpenStack',
  'openstack_auth_url' => 'https://xxxxxx/v2.0/tokens',
  'openstack_username' => 'gitlab',
  'openstack_api_key' => 'password',
  'openstack_tenant' => 'test',
}
gitlab_rails['backup_upload_remote_directory'] = 'gitlab'
```


# gitlabの設定更新とバックアップ

```
gitlab-ctl reconfigure
gitlab-rake gitlab:backup:create
```

OpenStack Swift上にtarで固められたファイルを確認できます。

# cronに登録

省略


# GitLabでバックアップ先に指定できるクラウドストレージ

GitLabはfogというライブラリを利用しています。
fogのサポートしているクラウドストレージを下記から確認できます。
http://fog.io/about/supported_services.html


# バックアップの保持期間

`backup_keep_time`はローカルバックアップだけでしか機能しません。
このままでは、クラウドストレージの容量が圧迫されてしまうため、削除さるように変更してみました。

```
/opt/gitlab/embedded/service/gitlab-rails/lib/backup/manager.rb
```

```rb
77c77
<       $progress.print "Deleting old backups ... \n"
---
>       $progress.print "Deleting old backups ... "
83,91d82
<         remote_directory = Gitlab.config.backup.upload.remote_directory
<         connection_settings = Gitlab.config.backup.upload.connection
<         if connection_settings.blank?
<           $progress.puts "skipped".yellow
<           return
<         end
<         connection = ::Fog::Storage.new(connection_settings)
<         directory = connection.directories.get(remote_directory)
<
98,102d88
<               if directory.files.get("#{timestamp}_gitlab_backup.tar").destroy
<                 puts "#{timestamp}_gitlab_backup.tar removed".red
<               else
<                 puts "#{timestamp}_gitlab_backup.tar failed".red
<               end

```

設定ファイルに下記を追記します。(保存期間１週間）

```
gitlab_rails['backup_keep_time'] = 7 * 24 * 60 * 60
```

再度`gitlab-ctl reconfigure`します。

## 参考
https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/raketasks/backup_restore.md
ファイルの変更日時をExifの撮影日時に設定する

スマホの写真をPCに取り込んだ場合などにファイルの変更日時が取り込んだ日時になることがあります。
Windowsだと[F6 Exif](http://www.ryouto.jp/f6exif/index.html)などで復元することができますがMacでも同様のことができないか調べてみると[ExifTool](http://www.sno.phy.queensu.ca/~phil/exiftool/)で同様のことができました。


# 0. 環境

- macOS Sierra 10.12
- Homebrew
- exiftool 10.20


# 1. ExifToolのインストール

HomebrewでExifToolをインストールします。

```bash
$ brew update
$ brew install exiftool
```


# 2. 変更日時を復元

あとは個々のファイルの撮影日時を変更日時に流し込みます。

```bash
$ find pic/ -type f -iname "*.jpg" -print0 | \
  xargs -0 exiftool "-filemodifydate<datetimeoriginal"

あるいは

$ exiftool "-filemodifydate<datetimeoriginal" pic/
```


# x. 関連

- [ExifTool by Phil Harvey](http://www.sno.phy.queensu.ca/~phil/exiftool/)  
- [ExifTool FAQ](http://www.sno.phy.queensu.ca/~phil/exiftool/faq.html)  
- [ExifTool Tag Names](http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/index.html)
C#でビルダーパターンを使う場合、使わない場合

#はじめに
　ビルダーパターンを使うと、インスタンスの生成が分かりやすく行えるということで、愛用されている方も多いと思います。今回はC#のインスタンス生成でビルダーパターンを使う場合と使わない場合を個人的に考えてみました。
　ビルダーパターンと言っても複数種類あるようなのですが、今回は下記リンクで言うところのEffective Java Builderのようなインタフェースの記述をしていきます。私はEffective Java読んだことがないんですけど。

参考：Javaで書くBuilderパターンのパターン
http://qiita.com/disc99/items/840cf9936687f97a482b

#ビルダーパターンを使わない場合
　使わない場合の方が多いので先に説明します。

##生成方法が1種類のみ[^1]

```csharp:インスタンス生成部分
  var imageSize = new ImageSize(height: 50, width: 60);
```

　生成方法が1種類の場合はビルダーパターンは使用しません。
　なぜかと言うと、C#では**名前付き引数**で渡すパラメータを把握できるからです。今回の場合、ImageSizeコンストラクタに高さと横幅を渡していることが、直感的にわかります。

+ 名前付き引数を使う場合は、メソッド定義の引数名が変わると呼び出し側の名前付き引数の修正が必要になるので、注意が必要です。

　今回は引数の数が少ないですが、多くなりそうならリファクタリングを行います。
　書籍：リファクタリング「第10章メソッド呼び出しの単純化」あたりが参考になると思います。

##生成方法が複数種類あるがどれも単純
```csharp:インスタンス生成部分
  var point1 = new Point(x: 50, y: 60);
  var point2 = new Point(dw: 0x0003C0032);
```

　上と同じく、名前付き引数で生成方法が分かるため。

#ビルダーパターンを使う場合

##生成方法が複数あり、複雑な生成方法を含む

```csharp:インスタンス生成部分
  // 複雑な生成方法のつもり
  WebRule webRule1 = Rule.WebInfo(webConfig).And.Config(myConfig).Build();
  WebRule webRule2 = Rule.LocalPolicy;
```

　コンストラクタが複数種類あり、複雑な生成方法を含む場合は、ビルダーパターンの使用を検討したほうが良いでしょう。
　例では、WebRuleクラスの生成をRuleクラスに任せることで、WebRuleのコンストラクタを書かなくていいような実装をしています。
　実装者によっては下記のような実装になったりと、ここらへんは人によっていろいろな考えが出る部分だと思います。

```csharp:インスタンス生成部分
  // 複雑な生成方法のつもり
  WebRule webRule1 = WebRule.Rule.WebInfo(webConfig).Config(myConfig);
  WebRule webRule2 = WebRule.LocalPolicy();
```

[^1]: コンストラクタが1種類の場合と考えてもらっていいです。たまに1つのコンストラクタで複数種類の生成を行おうとする人がいるので注意が必要ですが…
今更oculus Rift(DK2)を導入するときの方法

oculusRift CV1が発売されて半年以上たつのに2年以上も会社に放置されていたoculusRift(DK2)をwindows10にセットアップした時(2016年10月)の話です。

##　環境
windows10　Home 64bit
グラボ　GeForce GTX 970
Oculus rift　DK2


##　基本的な流れ
ここに書いてある感じで最新のoculus　setuptoolを入れればいいだけです。

参考)
Oculus Homeの設定方法はコレ！ DK2でも 「Henry」や「Lucky&#8217;s Tale」が遊べるぞっ
http://panora.tokyo/6578/

##　絶対にやってはいけないこと
oculus　Homeのデバイス設定から「ResetDefaultView　in　VR」を選択すると、「Set Your View in VR」と表示されたままでCV1に付属するXboxOneのコントローラーから動作入力するまでどうやっても動かなくなります。
(アンインストール→再インストールでもダメです)
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/110257/525d70cb-1f30-037b-6316-effbfb7ea23a.jpeg)



##　やっちゃった！

僕もやってしまいました・・・
アンインストール→再インストールでも「Set Your View in VR」のままで動けなくなります。

対策は以下のサイトを参考に
https://forums.oculus.com/vip/discussion/33245/dk2-permanently-stuck-in-continue-in-vr-set-your-view-in-vr-press-the-a-button-to-continue

1. oculus関係のアプリを落とす
2.タスクマネージャーからオキュラスサーバーを落とす(たぶんこの辺)
![キャプチャ2.JPG](https://qiita-image-store.s3.amazonaws.com/0/110257/3b374d5a-2a95-0272-54a4-2b653fa9d188.jpeg)

3．セッションを消す
ここの_oafをバックアップします
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/110257/e5316646-4c53-2955-eee4-ef00a2ae7275.jpeg)

4． C:\Program Files (x86)\Oculus\Support\oculus-runtime\ OVRServer_x64.exe
を実行します(コマンドプロンプトが立ち上がりますのでそれは小さくしておいてください)

5．もう一度oculushomeのアプリを立ち上げると、サインインに戻っているので無事さっきの状態からは脱出成功です！

6．あらためてoculushomeのアンインストールと再インストール
→サーバーを落としてしまったせいか、再起動しても立ち上がらなかったので念のためもう一回インストール、これでようやく、oculusを動かせる環境ができました
SEIL/x86 と Cisco(IOS) でIPsec VPN(IPv4)

# はじめに
異機種間でVPNを張ったりするとき、若干パラメータ調整が必要になることがあるので、その調査もかねてSEIL/x86 と Cisco(IOS) で IPsec VPNを張ってみました。
固定IPアドレスであることを前提とした設定になっています。

# 構成

[SEIL/x86(192.168.3.1)]  -  L3Network - [(192.168.1.1)Cisco(IOS)]

[SEIL/x86(10.0.1.2)] - IPsec tunnel - [(10.0.1.1)Cisco(IOS)]


# 設定

## 注意
バージョンによって、dh-groupやencryptionなど、選択できないものがありますので、それぞれの機器で同じものが設定できることを確認しておきます。

## 調整すべきパラメータ
* IKE  
SEILの`ike proposal`とCisco(IOS)の`crypto isakmp policy`が一致する必要があります。  
ここではSEIL側で`lifetime-of-time 1d`として設定し、Cisco(IOS)では設定していませんが、
SEILのデフォルト値が8時間、Cisco(IOS)のデフォルト値が24時間となっているため、SEIL側をCisco(IOS)側に合わせる設定としているからです。  
Cisco(IOS)側で設定する場合は`lifetime 28800`等、秒単位で設定します。  
* pre-shared key  
事前共有パスフレーズSEIL側の`ike preshared-key`とCisco(IOS)側の`crypto isakmp key`が一致する必要があります。
* IPsec  
SEILの`ipsec security-association`で指定する`ipsec security-association proposal`とCisco(IOS)の`crypto ipsec profile`で指定する`crypto ipsec transform-set`が一致する必要があります。    
ただしlifetimeとpfs-groupについては、一致していなくてもネゴシエーションして決めることができるため、不一致でも通信が可能です。  

## SEIL/x86
```
interface lan0 add 192.168.3.1/24
interface ipsec0 tunnel 192.168.3.1 192.168.1.1
interface ipsec0 add 10.0.1.2/24 remote 10.0.1.1

ike auto-initiation enable
ike preshared-key add "192.168.1.1" "test"
ike proposal add IKEP encryption aes256 hash sha256 authentication preshared-key dh-group modp2048 lifetime-of-time 1d
ike peer add PEER01 address 192.168.1.1 exchange-mode main proposals IKEP my-identifier address peers-identifier address tunnel-interface enable
ipsec security-association proposal add IPSA pfs-group modp2048 authentication-algorithm hmac-sha256 encryption-algorithm aes lifetime-of-time 06h
ipsec security-association add IPSA01 tunnel-interface ipsec0 ike IPSA esp enable
```

## Cisco(IOS)
```
crypto isakmp policy 1
 encr aes 256
 hash sha256
 authentication pre-share
 group 14

crypto isakmp key test address 192.168.3.1

crypto ipsec transform-set TS esp-aes esp-sha256-hmac

crypto ipsec profile VTI
 set transform-set TS
 set pfs group14
 set security-association lifetime seconds 28800

interface Tunnel1
 ip address 10.0.1.1 255.255.255.0
 tunnel source GigabitEthernet0/1
 tunnel mode ipsec ipv4
 tunnel destination 192.168.3.1
 tunnel protection ipsec profile VTI

interface GigabitEthernet0/1
 no switchport
 ip address 192.168.1.1 255.255.255.0
```

上記設定にて、それぞれnext-hopを10.0.1.x に指定することで、その通信はすべてIPsec-VPN tunnel経由となり、暗号化されます。
# 参考
[IPSec Virtual Tunnel Interfaceを用いたLAN-to-LAN接続設定例](http://www.cisco.com/cisco/web/support/JP/100/1006/1006245_ipsec_vti.html)
[ルーティングベースIPsec（IPsecインタフェース）の設定手順](https://www.seil.jp/doc/index.html#fn/ipsec/use/vpn/ipsec_interface.html)
HTTPトリガーを使ってWebAPIを作成する

#やりたいこと
DataSpiderのHTTPトリガーを使って、DataSpider上で作成した処理スクリプトを外部アプリケーションからHTTPで処理を呼び出します。
ResponseはJSON、XML等のデータ形式を選択することができます。
今回はJSON形式で返却する処理を作成しました。

#事前準備
- 処理スクリプトがサービス登録されていること
- スクリプト出力変数が設定されていること
- ↓サンプルスクリプト
![sample.png](https://qiita-image-store.s3.amazonaws.com/0/35843/a3f38177-31df-d5c2-4960-13de79e37320.png)

#HTTPトリガーの設定
1.Studio for Webのメニューバーからマイトリガーを選択
![mytrigger.png](https://qiita-image-store.s3.amazonaws.com/0/35843/aec2a2e9-628f-b007-591c-442206d3c0a9.png)

2.HTTPトリガーを選択
![httptrigger.png](https://qiita-image-store.s3.amazonaws.com/0/35843/0f1646a0-29d7-0b2f-72e1-628e18d232c9.png)

3.HTTPトリガーの設定を行います。
　1.実行パスの設定。ここがリクエストを行うURLになります。
　2.今回はJSON形式のレスポンスが必要なので、Conten-Typeに`application/json`を選択します。
　![httptrigger02.png](https://qiita-image-store.s3.amazonaws.com/0/35843/dcc9f1fe-87a7-6c3a-b429-c74ca5c76153.png)
　3.リクエストURLを確認します。
　　今回は`search`としたので
　　　`http://<DataSpiderServer稼働OSのホスト名またはIPアドレス>:<DataSpiderServerのポート番号>/dataspider/trigger/search}`
　　がリクエストURLになります。確認が終わったら`次へ`をクリックします。
　4.実行したいサービスとスクリプトを選択し、スクリプト出力の`値`に`出力データ`を選択します。
　![httptrigger03.png](https://qiita-image-store.s3.amazonaws.com/0/35843/8c646329-96a8-f8c7-3255-d7e9bdec98b8.png)
　5.`完了`をクリックして設定は完了です。

#Responseの確認
- ブラウザを起動し、HTTPトリガーで生成されたURLにリクエストを送信します。
- 正しく結果が表示されることを確認します。

　 ![httptrigger04_01.png](https://qiita-image-store.s3.amazonaws.com/0/35843/0d5dc597-fa2d-8d00-c554-35f52be129c4.png)


- 出力するjsonフォーマットの設定方法については[こちら](http://qiita.com/appresso_wakino/items/d8fa8c3cd77531e2f371)から
VisualSFM環境構築

Structure from Motion(SFM) を試すために、最初openMVGやopenMVSを入れて試行錯誤していたけれど、「VisualSFM」を使えば複数の写真から簡単に3Dモデルを作ることができました。
環境構築方法を記録しておきます。

構築した環境は、MacbookAir、VirtualBox上のLinux Mint17.3です。

### VisualSFMインストール
1. [リンク先](http://memo.tsukuba.ch/e276835.html)に記載のある必要なパッケージをインストール。バージョンは V0.5.26 。

上記のページ通りやればほぼ構築できますが、依存パッケージの中で存在しないものはバージョン番号を抜いて、```apt-cache search```の後に名前を入れて検索して、すべての依存パッケージをインストールします。

また、Multicore Bundle Adjustmentのビルドにおいて、CUDAがない場合のビルドを実行すると記載とは違うファイル名のライブラリが作成されるので、ファイル名を```libpba.so```にリネームしてください。

また、PATHを通してコマンドラインからVisualSFMを立ち上げないと、解析中にライブラリがないと怒られました。

### VisualSFMによるplyファイル作成
2.　VisualSFMが起動できたら、[FIle] - [Open+ Multi Images]を選択して対象の写真を選びます。写真は同じ部分を含む異なる角度から撮影された写真です。

3.　GPU使用の場合は、[Enable GPU] - [Match using CUDA]を選択します。

4.　4方向の矢印ボタン[Compute Missing Match]をクリックすると、特徴点の抽出とマッチングが開始されます。CUDAなしだとSIFTの計算に時間がかかる模様。サイズ1.5MB/1枚程度の画像10枚で1分程度でした。

5.　横のボタン[Compute 3D Reconstruction]をクリック。

6.　処理が終わったら、その３つ横の[Run Dense Reconstruction]をクリック。[View] - [Dense 3D Points]にチェックを入れると画面が以下のように切り替わります。

![Screenshot at 2016-10-16 13:15:56.png](https://qiita-image-store.s3.amazonaws.com/0/133093/cb813288-4d54-c3d3-93ec-bed4d986376e.png)

![Screenshot at 2016-10-16 13:17:00.png](https://qiita-image-store.s3.amazonaws.com/0/133093/fc74c6e6-4ed3-42c6-3480-b8827a54ab4f.png)

写真から構成した立体ボブ人形。特徴点のないところはスカスカになっています。

7.　処理後にできたファイルの中で、
modelsフォルダの中のoption-0000.ply(Polygon Model File)が作成されています。これをMeshLabというソフトにてメッシュ再構成していきます。

### MeshLabのインストール

8.　[こちらのページ](http://meshlab.sourceforge.net/)からMeshLabのソースをダウンロードしてビルド。

9.　メッシュ再構成の方法は[こちら](http://www.pointcloud.jp/blog_n22/)のページを参考にしました。

MeshLabで先ほど作成されたPLYファイルを開く。
![Screenshot at 2016-10-16 13:20:24.png](https://qiita-image-store.s3.amazonaws.com/0/133093/1e240bcc-6b4f-54cc-7aaa-4a40f619b147.png)

設定値の理解が甘いのでうまくメッシュ再構成ができないので、調査して追記予定。
【Swift】QiitaAPIクライアントライブラリを作成しました


# はじめに

Swift3で[QiitaAPI](http://qiita.com/api/v2/docs)のクライアントライブラリを作成してみました（iOS）。
今回、[APIKit](https://github.com/ishkawa/APIKit)を利用させて頂き手早く作ることができました。

##### [QiitaKit](https://github.com/ykyouhei/QiitaKit)

# インストール方法
[Carthage](https://github.com/Carthage/Carthage), [CocoaPods](https://github.com/cocoapods/cocoapods)に対応しています。

# 使い方

## セットアップ
[Qiita設定ページ](https://qiita.com/settings/applications)で登録したアプリケーションのClientID, ClientSecretを設定してください。

```Swift
import UIKit
import QiitaKit

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    let clientID     = "xxxx"
    let clientSecret = "xxxx"
        
    AuthManager.sharedManager.setup(
        clientID: clientID,
        clientSecret: clientSecret)
        
    return true
}

```

## OAuth

本ライブラリはOAuth認証にも対応しています。QiitaAPIでは一部エンドポイントは認証なしでも利用できますが、認証している状態ではユーザごとに1時間に1000回まで、認証していない状態ではIPアドレスごとに1時間に60回までという制限があるため、アプリ等で利用する場合は認証を行ったほうが良いと思います。

```Swift
import QiitaKit

// 認証済み判定
let authorized: Bool = AuthManager.sharedManager.authorized

/*
OAuth認証を行う。認証を行うためのWindowが表示されます

- parameter scopes:  アプリで利用可能なスコープ
   - readQiita:      Qiitaからアクセストークンに紐付いたユーザに関連したデータを読み出す
   - readQiitaTeam:  Qiita:Teamからデータを読み出す
   - writeQiita:     Qiitaにデータを書き込む
   - writeQiitaTeam: Qiita:Teamにデータを書き込む

- parameter redirectURL: 登録アプリケーションで設定したリダイレクト先のURL

- parameter webViewType: OAuth認証を行うWebViewの種類

- parameter completion:  認証後に呼ばれるハンドラ

*/
AuthManager.sharedManager.authorize(withScopes: scopes,
                                    redirectURL: redirectURL,
                                    webViewType: .uiWebView)
{ result in
    switch result {
    case .Success:
        // 認証成功

    case .Failure(let error):
        // 認証失敗
    }
}
```

## リクエスト

QiitaAPIの各種リクエストに対応ています。リクエストに対して対応するレスポンスオブジェクトが返ってくるタイプセーフな作りになっています。


* [いいね](./QiitaKit/Classes/Requests/Like)
* [コメント](./QiitaKit/Classes/Requests/Comment)
* [投稿とタグとの関連](./QiitaKit/Classes/Requests/Tagging)
* [タグ](./QiitaKit/Classes/Requests/Tag)
* [Qiita:Team上でのチーム](./QiitaKit/Classes/Requests/Team)
* [投稿のテンプレート](./QiitaKit/Classes/Requests/Template)
* [Qiita:Team上でのプロジェクト](./QiitaKit/Classes/Requests/Project)
* [Qiita上のユーザ](./QiitaKit/Classes/Requests/User)
* [投稿](./QiitaKit/Classes/Requests/Item)

```Swift
import QiitaKit
import APIKit
import Result

// 認証中ユーザ情報を取得するリクエストオブジェクト
let request = QiitaAPI.User.GetAuthenticatedUserRequest()

// リクエスト送信
Session.sendRequest(request) { result in
    switch result {
    case .Success(let authenticatedUser):
        print(authenticatedUser)
        
    case .Failure(let error):
        print(error)
    }
}

```

# さいごに

QiitaTeam向けリクエストなど一部リクエストは動作確認できていないので、不具合などあればPullRequestお待ちしています。
https://github.com/ykyouhei/QiitaKit
cd でシンボリックリンク先の実体のパスに移動する

# 概要
bash で cd コマンドでディレクトリ移動する際、移動先がシンボリックリンクだった場合、シンボリックリンク先のディレクトリパスに移動する方法。

一言で言うと `-P` オプションでシンボリックリンク先のディレクトリに移動できます。

# 例
```
# こういう状態
[vagrant@vagrant-centos65 test]$ ls -la /tmp/test
total 12
drwxrwxr-x  3 vagrant vagrant 4096 Oct 14 02:15 .
drwxrwxrwt. 5 root    root    4096 Oct 14 02:15 ..
drwxrwxr-x  2 vagrant vagrant 4096 Oct 14 02:15 real-dir
lrwxrwxrwx  1 vagrant vagrant   18 Oct 14 02:15 virtual-dir -> /tmp/test/real-dir

#通常の cd
[vagrant@vagrant-centos65 test]$ cd /tmp/test/virtual-dir 
[vagrant@vagrant-centos65 virtual-dir]$ pwd
/tmp/test/virtual-dir

# -P 付きの cd
# /tmp/test/real-dir へ移動している
[vagrant@vagrant-centos65 virtual-dir]$ cd -P /tmp/test/virtual-dir 
[vagrant@vagrant-centos65 real-dir]$ pwd
/tmp/test/real-dir
```
WSH で、外部プログラムの終了を待ってから次の行に進む

Windows でバッチ処理をしたり、簡単な処理をおこなうツールを作るときに WSH (Windows Script Host) というのをよく使います。

JScript や VBScript で気軽に書けてコンパイルも要らないので地味ながら結構便利なんですよね。

で、この処理の中で外部プログラムの実行をすることが多いのですが、そのときの同期・非同期処理のやり方をよくド忘れするので、簡単にメモ。

環境
----

- Windows 7
- JScript

参考
----

- [Run メソッド (MSDN)](https://msdn.microsoft.com/ja-jp/library/cc364421.aspx)

比較
----

### 待たないほう

```javascript
var shell = new ActiveXObject('WScript.Shell');

shell.Run('notepad');
WScript.Echo('メモ帳が終了する前にダイアログ表示');
```

- 待たないし、エラーコードも必ず `0` になる。

### 待つほう

```javascript
var shell = new ActiveXObject('WScript.Shell');

shell.Run('notepad', 1, true);
WScript.Echo('メモ帳が終了してからダイアログ表示');
```

- 2 番目の引数はウィンドウの表示に関するオプションで `1` は標準値。
- 3 番目の引数が `true` のときに終了を待つ。標準値は `false` 。
- エラーコードは、きちんとプログラムの実行結果が返る。
Emacs - Helmとは

# Description
Helmは何が出来るのか?

# 簡易説明
- ある情報源(集合)を検索する機能
    - また, 同機能でEmacsでの検索手法を統一する
- 情報源(集合)とは
    - current dir以下の全ファイル
    - buffer内
    - buffer list
    - git project内の全ファイル (file名, grep検索)
    - 過去に開いたfile群 (recent file)
    - Emacs command (M-x)
    - など, 様々な情報源を検索可能 (packageで拡張可)
        - 情報源を複数組み合わせての検索も可能

# 実例
## git project : File検索
以下, 手順と動画.

- Helm git interfaceを開く (C-;)
- 検索 wordを入力
- 絞込結果 List up
    - C-mで対象を開く
    - C-zでtemp bufferで一時閲覧
![2016_10_16_1241.gif](https://qiita-image-store.s3.amazonaws.com/0/118627/3da76c6c-3e15-1913-c17c-5af528fd4e08.gif)


## git project : 全FileへGrep検索 
手順は, ほぼ前項と同じ.
// なお, commandを内部で指定可能. (ag, ripgrepなど)
(git-grep C-')

![2016_10_16_1250.gif](https://qiita-image-store.s3.amazonaws.com/0/118627/0f36d50c-9463-1bda-4fec-187682eb9370.gif)


## recent file : 過去に開いたfile群
(recent C-x C-r)

![2016_10_16_1255.gif](https://qiita-image-store.s3.amazonaws.com/0/118627/1bf063a0-d671-8419-2106-dfa126335856.gif)


## buffer内検索と置換
例として, buffer内の変数をList upし, 一括変換を掛ける.

- (C-x C-c) でカーソル上のシンボルをbuffer内検索
- 絞り込み結果 List up
    - (M-i) でopen中のbufferを全て検索対象に追加可能
    - 置換ではなく, その箇所へ飛ぶ事も可能.
- (C-c C-e) で edit modeへ移行
- (replace-string) で対象を置換
- (C-x C-s) で反映.
![2016_10_17_0427.gif](https://qiita-image-store.s3.amazonaws.com/0/118627/b04303ac-19e5-df42-2cef-29e3d8490705.gif)


以上, 簡単な実例となる.

# install
以下, Install手法及び, 説明記事.
[Emacs に革命を起こすパッケージ「helm」](http://emacs.rubikitch.com/sd1503-helm/)
@rubikitch 


# 類似 Package
以下で紹介されています
[君は誰とEmacsる](http://qiita.com/tadsan/items/33ebb8db2271897a462b)
PHPで超簡単自作フレームワーク

#目的
フレームワークは、LaravelやRails、Djangoなど、機能満載な物ばかりが出ています。
その障害か、まるでフレームワークはすごい人が作った魔法かのように感じる初心者が多いかと思いますので、もっと身近にフレームワークを感じて頂けるようになれたらと思います。

##1. メリット
frameworkの仕様に沿ってコードを書くだけで、保守運用性と開発効率を上げる

##2. どうやって？
frameworkの開発者が幸せになる様にと願いを込めて使いやすい仕様とパワフルなライブラリを書いたから

##3. 事前準備
1. urlパースがよくわからない人はURLを取得できる<a href="http://php.net/manual/ja/reserved.variables.server.php">$_SERVER['PATH_INFO']</a>
2. 動的言語機能が良くわからない人は動的に呼ぶクラスを変更できる<a href="http://php.net/manual/ja/language.namespaces.dynamic.php">動的言語機能</a>

##4. 作ってみよう

###今回実装する内容

1.urlの初めに来るurlに相対したmodelとviewを呼ぶオートローダー機能

例：localhost/blogでリクエスト

```php:index.php
include('./models/blog.php');
```

```php:index.php
include('./views/blog.php');
```

2.modelはファイル名と同じクラスで作成し、その中のindex(@params)メソッドが呼ばれる
例：localhost/blogでリクエスト

```php:models/blog.php
<?php
class blog {
    function index($params) {
        return array('str'=>'Hello World!');
    }
}
```
3.リクエストに対してのviewファイルが存在しなかった場合、定番の404 Not Foundを見せる
4.トップページはどーん！とカッコよく宣伝する！

###ソースコード全容

```php:index.php
<?php

if (empty($_SERVER['PATH_INFO'])) {
    //紹介ページを表示
    include('./views/index.php');
    exit;
}

//スラッシュで区切られたurlを取得します
$analysis = explode('/', $_SERVER['PATH_INFO']);
$call;

foreach ($analysis as $value) {

    if ($value !== "") {
        $call = $value;
        break;
    }
}

//modelをインクルードします
if (file_exists('./models/'.$call.'.php')) {

    include('./models/'.$call.'.php');
    //$call名のクラスをインスタンス化します
    $class = new $call();
    //modelのindexメソッドを呼ぶ仕様です
    $ret = $class->index($analysis);
    //配列キーが設定されている配列なら展開します
    if (!is_null($ret)) {
        if(is_array($ret)){
           extract($ret);
        }
    }
}

//viewをインクルードします
if (file_exists('./views/'.$call.'.php')) {
    include('./views/'.$call.'.php');
} else {
    include('./views/error.php');
}
```

##解説
1.パラメーター１つ目が呼ばれるmvと相対します。 

```php
//スラッシュで区切られたurlを取得します
$analysis = explode('/', $_SERVER['PATH_INFO']);
$call;

foreach ($analysis as $value) {
    if($value !== ""){
        $call = $value;
        break;
    }
}

```
2.モデルを呼び、viewに渡す値があれば展開する事で実現します

```php
//modelをインクルードします
if (file_exists('./models/'.$call.'.php')) {

    include('./models/'.$call.'.php');
    //$call名のクラスをインスタンス化します
    $class = new $call();
    //modelのindexメソッドを呼ぶ仕様です
    $ret = $class->index($analysis);
    //配列キーが設定されている配列なら展開します
    if (!is_null($ret)) {
        if(is_array($ret)){
           extract($ret);
        }
    }
}
```

3.viewを呼んで終わり

```php
//viewをインクルードします
if (file_exists('./views/'.$call.'.php')) {
    include('./views/'.$call.'.php');
} else {
    include('./views/error.php');
}
```
ポイントはelse文かなぁ

4.localhost/やlocalhost////って入力された際の対策

```php
if(empty($_SERVER['PATH_INFO'])){
    //紹介ページを表示
    include('./views/index.php');
    exit;
}
```
##結論
頑張って皆が使ってくれる凄いもの作りたいなぁ。
あ、私はLaravel派ですよ！

##GitHub
https://github.com/k-okina/FirstMVFramework

##参考しまくったサイト
* http://choilog.com/katty0324/blog/6
* http://php.net/manual/ja/reserved.variables.server.php
* http://php.net/manual/ja/language.namespaces.dynamic.php
Android 7.1 NougatのApp shortcuts APIについて

Android 7.1 Nougat（APILevel 25）がリリースされるようですね。
http://android-developers.blogspot.jp/2016/10/android-71-developer-preview.html

いくつか機能が追加されるようですが、アプリのUXの向上に一役買いそうなApp shortcuts APIについて、どのように使えば良さそうなのか考えてみたいと思います。

# App shortcuts APIとは
```
lets you surface key actions directly in the launcher and take your users deep into your app instantly.
You can create up to 5 shortcuts, either statically or dynamically.
```
英語が得意ではないのですが、surface key actionsをすることで、最大５つまでアプリ内のコンテンツへ直接遷移できる一覧を表示させることができるようです。公式ページの画像を見るとiOSの3D Touchのようなものでしょうか。

※実際にさわってないので、surface key actions というのがどういうアクションなのか・・・。

# 使い道
実際に使うとしたら、どういったコンテンツを置けばいいでしょうか。いくつか考えてみました。

### オススメを表示
アプリで提供している機能の中で、オススメのものとか。例えば、LINEだと、スタンプショップ画面、友達追加画面、設定画面といったところでしょうか。
例えが悪いだけかもしれませんが、これらの画面はそんな頻度よく開くものでもないだろうし、わざわざショートカットを使わなくてもそんなに手間なく遷移できますね。
もし、頻度よく開く、かつ、遷移に手間だ、なんて場合は、今回のAPIで提供するのではなく、アプリ本体の導線をもう一度考えた方が良いかなと思います。

### dynamicallyに表示
dynamicallyの特徴を使うとか。iOSの3D Touchと違って、動的に変更できるみたいです。ですので、例えば、最後に開いていた画面とか、使用頻度が高い画面、ユーザーに登録させた画面といったところでしょうか。
これは少しアリな気がしますね。ただ、ビューアーアプリといった階層を掘っていくアプリでしか本領が発揮しなさそうですし、たいていそういうアプリには履歴とかお気に入りがあるので、あまり効果は出ない気がします。

### ゲーミフィケーション要素として表示
ゲーミフィケーション要素として使うとか。dynamicallyの特徴を活かして、ランダムに特典ページに飛べるショートカットが作成されるとか、利用状況に応じてバッジをつけてあげるとかでしょうか。

### ウィジェット替わり
ウィジェットのように使うとか。もうショートカットでなくなっているのですが、例えばニュースアプリだと最新記事5件が出るとか、天気アプリだとそこに天気予報が出るとかでしょうか。

# 結局どうすればいいか
手を出さないのが一番。

あとは、dynamicallyがどこまで柔軟さを持っているかによるでしょうか。ショートカットを表示するさいに処理を走らせることができるのか、それともapp indexingのようにアプリを開いたタイミングで登録処理を走らせるのか。
もう少し様子見が必要かなと思います。

# おわりに
Android 7.0ですらそんなに浸透している様子はなく、最近はiOSの機能を真似したのかなという機能を追加してる印象を受けてます。
Googleといえば、もう少しインテリジェンスに機能改善・追加をするイメージが強いのですが、ディープラーニングの台頭により人工知能に力を入れてスマホへはあまり力を入れなくなってきてるのかな。今は自動車とかIoTとか次のデバイスが出てますしね。

あと、ちらっと見た記憶だけですが、7.0が出るときにmulti windowはユーザーがもっとも求めていた機能の１つみたいだったのですが、リリースしてからユーザーの評価はどうなんでしょうか。まったくといっていいほど聞いたことがない。。。このmulti windowもiOSのマルチタスクの後追いですね。
SpringBoot MessageSourceの拡張

#SpringBoot MessageSourceの拡張
MessageSourceが使いにくいのでMessageSourceを拡張して使いやすくしてみる。
（お手軽に拡張するならMessageSourceAccsessorを使うと良い）

MessageSourceを拡張することで、引数にEnumを指定したりメッセージの取得先をDBに変更したりと色々と好き放題出来るようになります。

#MessageSourceをそのまま使った場合
MessageSourceは引数が多く、しかもLocale.getDefaultの構文の書き方も覚えておく必要があって面倒。


```java:TestController.java
@Controller
public class TestController {

    // @Autowired
    MessageSource message;

    @RequestMapping("/xxx")
    public String init() {

        String msg = message.getMessage("info001", null, Locale.getDefault());
        System.out.println(msg);

        return "/yyy";
    }
}
```

#MessageSourceを拡張した場合
拡張したMessageSourceを使用することで、
引数が１つだけになってコーディングがかなり楽になる。

```java:TestController.java
@Controller
public class TestController {

    // @Autowired
    MessageSourceImpl message;
//    MessageSource message;

    @RequestMapping("/xxx")
    public String init() {

        String msg = message.getMessage("info001");
//        String msg = message.getMessage("info001", null, Locale.getDefault());
        System.out.println(msg);

        return "/yyy";
    }
}
```

#MessageSourceを拡張方法
MessageSourceの拡張クラスを作成してBean登録する。

```java:MessageSourceImpl.java
/**
 * MessageSource拡張クラス
 */
public class MessageSourceImpl implements MessageSource {

    /** MessageSource */
    private MessageSource message = new MessageSourceAutoConfiguration().messageSource();

    /**
     * メッセージの取得
     * @param code
     * @return
     */
    public String getMessage(String code) {
        return message.getMessage(code, null, Locale.getDefault());
    }

    /**
     * メッセージの取得
     * @param code
     * @param args
     * @return
     */
    public String getMessage(String code,
                             Object[] args) {
        return message.getMessage(code, args, Locale.getDefault());
    }

    @Override
    public String getMessage(String code,
                             Object[] args,
                             String defaultMessage,
                             Locale locale) {
        return message.getMessage(code, args, defaultMessage, locale);
    }

    @Override
    public String getMessage(String code,
                             Object[] args,
                             Locale locale) throws NoSuchMessageException {
        return message.getMessage(code, args, locale);
    }

    @Override
    public String getMessage(MessageSourceResolvable resolvable,
                             Locale locale) throws NoSuchMessageException {
        return message.getMessage(resolvable, locale);
    }

}
```

```java:AppConfig.java
@Configuration
public class AppConfig {

    /**
     * MessageSourceの拡張クラスのBean登録
     * @return
     */
    @Bean
    public MessageSourceImpl messageSourceImpl() {
        return new MessageSourceImpl();
    }

}
```
Yoctoを使ってみた時のメモ

Yoctoを使ってみました。

その時のメモです。 

# ビルド
* 環境変数を設定する。 (デフォルトのbuildディレクトリを使用)

```
$ source poky/oe-init-build-env
```

* bitbakeで特定のパッケージpackage_nameをビルドする

```
$ cd build
$ bitbake package_name
```

# パッケージを追加

* build/conf/local.confに下記を追加する
* package_nameの前にスペースが必要なことに注意

```
IMAGE_INSTALL_append = " package_name"
```

# パッケージのリスト表示

```
$ bitbake -s
```



* reference: [Yocto Project Development Manual ver1.8, 5.2.1. Customizing Images Using](http://www.yoctoproject.org/docs/1.8/dev-manual/dev-manual.html)


# カーネルを修正してビルド

レシピを使わずにカーネルソースを修正をビルド

まずなにかしらの手順でカーネルをビルドしておく

必要ならmenuconfigする

```
$ bitbake カーネル名　-c menuconfig 
```

menuconfigすると、tmp/work-shared 以下のあたりにカーネルソースが展開されるので、
必要なら修正します。

強制的にビルドする

```
$ bitbake カーネル名　-c compile -f
```

ひさしぶりにyoctoで作業したので追加(2021-01)

ビルド時にクロスコンパイル用のインクルードパスが足りない時にレシピに下記を追加。

```
CFLAGS += "${RECIPE_SYSROOT}/usr/include/hoge"
```
WindowsでUnityを起動すると、画面が真っ暗でログインできない場合

WindowsでUnityをインストール後、起動しても画面が真っ暗という状況が発生することがあります(Windows10 64bit/ Unity 5.4.2f1で確認)。これは、どうやら必要なファイルが正常に展開されないことが原因のようで、手動で整えてやることで解決できます。

`C:\Users\(ユーザー名)\AppData\Roaming\Unity\Packages`のフォルダを見ると、`package.json`だけがありモジュールがインストールされていないことがわかります。

この`package.json`の中身をのぞくと以下のようになっています。

```json
{
  "name": "unity-editor",
  "version": "5.3.0",
  "description": "Unity is a powerful cross-platform 3D engine and a user friendly development environment. Easy enough for the beginner and powerful enough for the expert; Unity should interest anybody who wants to easily create 3D games and applications for mobile, desktop, the web, and consoles.",
  "author": "Unity Technologies",
  "dependencies": {
    "unity-editor-home": "0.1.35",
    "unityeditor-cloud-hub" : "0.0.13",
    "unityeditor-collab-history": "0.0.27",
    "unityeditor-collab-toolbar": "0.0.46"
  }
}

```

`dependencies`の4つのモジュールは、以下の場所にダウンロードされています。

```
C:\Program Files\Unity\Editor\Data\Resources\Packages
```

よって、以下の作業を行うことでブラックスクリーン現象を解決できます。

1. `C:\Users\(ユーザー名)\AppData\Roaming\Unity\Packages`に`node_modules`というフォルダを作る
2. `node_modules`の中に、`unity-editor-home`というフォルダを作る
3. `C:\Program Files\Unity\Editor\Data\Resources\Packages`の中にある`unity-editor-home.0.1.35.tgz`を展開し、中の`package.json`と`dist`フォルダを取り出す
4. 3で取り出した`package.json`と`dist`を2で作成した`unity-editor-home`に配置する
5. 他のモジュール(`unityeditor-cloud-hub`、`unityeditor-collab-history`、`unityeditor-collab-toolbar`)についても同様に行う

これでOKです(冷静に考えると、nodeが入っていれば`npm install`だけでいいかも)。UnityにWelcomeしてもらえると思います。

![unity_welcome.PNG](https://qiita-image-store.s3.amazonaws.com/0/25990/7cff1489-2f42-97c4-b13b-6e18d68b6223.png)