OmniAICreator/Qiita-1.07M huggingface dataset:
Symfony 複数項目に依存したvalidationの作成

# はじめに
自分の備忘録をかねて、symfonyの機能(特にform)関連をまとめています。
今回はcallback validatorを利用して、複数の複数項目に依存した場合のvalidationを作成していきたいと思います。

### 今まで書いたsymfonyの記事
- symfony でのform作成の基本
	- http://qiita.com/yutaChaos/items/0ae0d1797db4cb16466c
- symfony validation処理の方法
	- http://qiita.com/yutaChaos/items/95e70ef96608809bf475
- symfony カスタムバリデーションの作り方 
	- http://qiita.com/yutaChaos/items/e7b42589253d3235ae6c
        
# 環境
- symfony 2.8
- PHP 7.0

## callback制約の作り方

### validateメソッド

Callbackのannotionを付与した引数にExecutionContextInterfaceを利用したメソッドを書く、entityに直接書いているので$thisから結びつくentityの値をとることから出来、
引数に受けた$contextにaddViolationすることでvalidationエラーを付与することができる。
buildViolationにメッセージを入力、atPathに表示したいメンバの名前を設定することができる。

```php
    /**
     * @Assert\Callback
     */
    public function validate(ExecutionContextInterface $context)
    {
        if (!empty($this->getMemo()) && !empty($this->getTask())) {
            $context->buildViolation('メモとタスクは両方入力してください。')
                ->atPath('memo')
                ->addViolation();

        }
    }
```

### static method
staticメソッドとして、書くことも出来ます。
その場合は最初の引数でobjectの値を受けます。

```php
    /**
     * @Assert\Callback
     */
    public static function validate($object, ExecutionContextInterface $context)
    {
        if (!empty($object->getMemo()) && !empty($object->getTask())) {
            $context->buildViolation('メモとタスクは両方入力してください。')
 　　　　　　　　　　　　　　        ->atPath('memo')
                ->addViolation();

        }
    }
```

# External Callbacks and Closures
closureとして書くことも出来ます。

```php
    public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $callback = function ($object, ExecutionContextInterface $context)
        {
                $context->buildViolation('メモとタスクは両方入力してください。')
                    ->atPath('memo')
                    ->addViolation();


        };
        $metadata->addConstraint(new Assert\Callback($callback));
    }
```

## まとめ
- symfonyでは複数項目に依存したvalidationもentityに記述することで簡単に記述することが出来ます。validationの処理だけを簡単に切り出すことができるので、決まった書き方をすることでよりすっきり整理して書くことができると思います

# 参考URL
- http://symfony.com/doc/2.8/reference/constraints/Callback.html
Git for Windows の設定ファイルの場所

Git for Windows の設定ファイルの場所について調べました。
（下記の「system レベルの設定ファイル」の場所に関して、 web 上の情報が古いようだったので、このエントリを書きました。）

動作確認したバージョン・環境は以下です。

* Git for Windows v2.9.0 
* Windows 10


## Git の設定ファイルについて

Git の設定ファイルには、

* system レベル (当該マシンの全ユーザに関する設定)
* global レベル (当該ユーザに関する設定)
* local レベル (特定のディレクトリ (リポジトリ) に関する設定)

の3種類があります[^1]。

[^1]: 「レベル」と書いていますが、これは公式の用語ではなく、私が勝手に使っている言葉です。

## 各設定ファイルの場所

### system レベルの設定ファイル

設定ファイルは次の場所にあります。

* `{gitインストール先}\mingw64\etc\gitconfig`
* `%PROGRAMDATA%\Git\config`  (Git for Windows v2.x 以降)

1つめの設定ファイルについては、
`git config -l --system` で現在の設定内容が見れます。

2つめの設定ファイルについては、
`git config -l --file={設定ファイルの場所}` で現在の設定内容が見れます。


※1つめの設定ファイルは以前は `{gitインストール先}\etc\gitconfig` だったらしく、web検索するとその情報ばかり出てきます。が、いつからかは知りませんが、上記のように変わったようです。

なお、公式ドキュメントの以下のページには「Git は、 "MSys root" にある etc/gitconfig を探す」という内容が書いてあります。

[Git - First-Time Git Setup](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup)

>It also still looks for `/etc/gitconfig`, although it’s relative to the MSys root, which is wherever you decide to install Git on your Windows system when you run the installer. 

(↑ここの冒頭の It は Git のこと)
MSYS とか MinGW のことはよく知らないのですが、この "MSys root" が `{gitインストール先}\mingw64` ということでしょうか？
でも後半部分からすると、 "MSys root" は `{gitインストール先}` である、と読める。
ということは、このドキュメントの説明も古いのかもしれません。


※2つめの設定ファイルの場所は、 Windows Vista 以降ならば `C:\ProgramData\Git\config` です。

[Git - First-Time Git Setup](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup)

>If you are using version 2.x or later of Git for Windows, there is also a system-level config file at `C:\Documents and Settings\All Users\Application Data\Git\config` on Windows XP, and in `C:\ProgramData\Git\config` on Windows Vista and newer. 



### global レベルの設定ファイル

`git config -l --global` で現在の設定内容が見れます。
設定ファイルは次の場所にあります。

* `C:\Users\{username}\.gitconfig`

[Git - First-Time Git Setup](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup)

>On Windows systems, Git looks for the `.gitconfig` file in the `$HOME` directory (`C:\Users\$USER` for most people). 



### local レベルの設定ファイル

`git config -l --local` で現在の設定内容が見れます。
設定ファイルは次の場所にあります。

* 当該リポジトリ直下の `.git\config`
Dockerを使ったMastodonを1.3.2から1.4.3にバージョンアップした

Dockerを使ったMastodonを1.3.2から1.4.3にバージョンアップしました。

#念のためにディレクトリを退避
※/opt/mastodonにdocker-compose.yml以下を配置しているとします。

```
cd /opt
cp -R mastodon mastodon_bak
```

#1.4.3をgitで取得する

```
git stash
git fetch --tags
latestTag=$(git describe --tags `git rev-list --tags --max-count=1`)
git checkout $latestTag
git stash pop
```

ここで、 Google アナリティクス用のスクリプトを設定しているので、app/views/home/index.html.hamlでコンフリクトが発生したので手動で修正しました。

#buildしてupする

```
docker-compose build
docker-compose up -d
```

#プリコンパイルする

```
docker-compose run --rm web rails assets:precompile
```

#マイグレーションする

```
docker-compose run --rm web rails db:migrate
```

ここで、外部キーに関するエラーがでたので下記を実行しました。

```
docker-compose run --rm web rails mastodon:maintenance:prepare_for_foreign_keys
```

再度、マイグレーションを実行します。

```
docker-compose run --rm web rails db:migrate
```

#次回アップデートのために修正した「app/views/home/index.html.haml」をリポジトリに追加してコミットする。

```
git add app/views/home/index.html.haml
git commit -m "V1.4.3" ...　とりあえず現在のバージョンをコメントにする。
```

以上でバージョンアップは終了です。

#参考にした情報

- [Create a script for easy updates on docker-compose](https://github.com/tootsuite/mastodon/pull/2396/files)
- [Upgrade to 1.4.3 failed (docker)](https://github.com/tootsuite/mastodon/issues/3788)
Visual Studioの標準出力設定変更に関する質問です。

Visual Studioの標準出力設定変更に関する質問です。

フォームアプリケーションとして作成したプロジェクトに対して、
System::Console::WriteLine("XXXX");をコマンドプロンプトに出力する為には、
プロジェクトのプロパティのどの設定箇所を変更すれば良いのでしょうか？

コマンドプロンプト上でYYY.exeを叩いて実行して、
コマンドプロンプト上に標準出力する為のプロパティ設定を教えて下さい。

なお、はじめからコンソールアプリケーションで作る、というのはＮＧです。
フォームアプリケーションとして作成する理由があるのです。
フォームアプリケーションをあたかもコンソールアプリケーションのように標準出力を変更する設定箇所がどこかにあるはずですが、見つけられません。
※以前、同じことをした事があるので、出来るはずです。
iOSでの各回転検知方法とその結果

iOSで回転検知方法が複数あり、用途によっては向き不向きがあるようなので、回転検知方法と検知タイミングごとの結果をまとめてみました。
# 検証時環境
開発環境：Xcode9beta
iOSバージョン：11beta
言語：Swift4
# 端末の縦横状態取得
端末の縦横状態は以下の2種類で取得しました。
###### UIInterfaceOrientation
```
let isPortrait = UIInterfaceOrientationIsPortrait(UIApplication.shared.statusBarOrientation))
let isLandscape = UIInterfaceOrientationIsLandscape(UIApplication.shared.statusBarOrientation))
```
###### UIDeviceOrientation
```
let isPortrait = UIDeviceOrientationIsPortrait(UIDevice.current.orientation))
let isLandscape = UIDeviceOrientationIsLandscape(UIDevice.current.orientation))
```
# 回転検知方法
## viewDidLoad
![image.png](https://qiita-image-store.s3.amazonaws.com/0/53273/64cfa63d-4f10-a9b1-d033-c8bf1b5e2671.png)
アプリ起動直後を想定した結果です。
- UIInterfaceOrientationとの組み合わせのみ検知は正確
## NSNotification
```
override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(MainViewController.onOrientationDidChange(notification:)), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}
    
@objc
func onOrientationDidChange(notification: NSNotification) {
    // ここに回転時の処理
}
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/53273/80a95a0e-a113-7090-8737-1efba566c0ad.png)
- 検知は正確
- アプリ起動直後に処理される
- バックグラウンド移行後2回処理される
- ViewControllerが重なった状態でも検知される
## viewWillLayoutSubviews
![image.png](https://qiita-image-store.s3.amazonaws.com/0/53273/ec3d1d3a-d9b3-1abd-f4c2-95b70bfbddf2.png)
- 検知は正確
- ViewControllerが重なった状態では検知されない
## viewDidLayoutSubviews
```
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    // ここに回転時の処理
}
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/53273/66276271-3dae-58b5-a19b-64b3a98ad08a.png)
- 検知は正確
- ViewControllerが重なった状態では検知されない
## viewWillTransition
```
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
    // ここに回転時の処理
}
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/53273/6a0ab8c4-38bc-74e5-17e1-ac40dd5bd3a0.png)
- UIDeviceOrientationとの組み合わせのみ検知は正確
- 回転時のみ処理される
- ViewControllerが重なった状態では検知される
# 予定
- ~~ViewControllerが重なっている状態での検知結果を追加予定~~
- CollectionViewの各処理タイミングと回転検知タイミングを追加予定
【Swift】JSONのお手軽パース方法【はてな】

# お手軽にJSONをパースする

今回は[株式会社はてな](http://hatenacorp.jp/)の研修に使用されている(?)[教科書](https://github.com/hatena/Hatena-Textbook)の一部を紹介したいと思います。
その教科書のiOSパートで紹介されているリポジトリ内の[`JSONObject.swift`を修正したもの](https://github.com/snowman-mh/my-block-ios/blob/master/my-block/Model/JSONObject.swift)を利用すれば、とてもお手軽にJSONをパースすることができます。

# やり方

## `JSONObject.swift`の用意

[`JSONObject.swift`](https://github.com/snowman-mh/my-block-ios/blob/master/my-block/Model/JSONObject.swift)に置いてあるコードをそのままコピーしたファイルを自分のプロジェクト内に作成します。
リンク先は僕のリポジトリのファイルですが、これは上記の[教科書](https://github.com/hatena/Hatena-Textbook)にある`JSONObject.swift`の内容をSwift4.0でビルドできるように修正したものです。

## パースしたいJSONデータのモデルを作成

次のように、受け取るJSONデータに応じてパース結果を保持するデータモデルを作成します。
受け取るJSONデータを提供するAPIのリファレンスなどをよく読み、存在しないかもしれないデータはオプショナル型を採用します。
また、`DateFormatter.dateFormat`の形式が受け取るJSONデータの日付の形式と合致しているかをしっかり確認しておきましょう。

```json:受け取るJSONデータ
{
    "id": 1,
    "name": "repository-name",
    "private": false,
    "html_url": "https://github.com/MasayaHayashi724/repository-name",
    "description": "This is description."
}
```

```swift:データモデル
struct Repository: JSONDecodable {
    let id: Int
    let name: String
    let isPrivate: Bool
    let htmlURL: URL
    let description: String?

    init(json: JSONObject) throws {
        id = try json.get("id")
        name = try json.get("name")
        isPrivate = try json.get("private")
        htmlURL = try json.get("html_url")
        description = try json.get("description")
    }
}
```

## JSONデータをパースする

APIなどから受け取ったJSONデータを次のようにパースすることができます。

```swift
do {
    guard let data = data else { return } // dataはサーバから取得したバイナリデータ
    guard let dic = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else { return }
    let jsonObject = JSONObject(json: dic)
    let response = try Repository(json: jsonObject)
    print(response.name)  // 例えばこんな感じで使えます
} catch let error {
    print(error)
}
```

# さいごに

簡単なプロジェクトでのJSONのパースであれば、このミニライブラリで十分です。
[紹介したリポジトリ](https://github.com/hatena/swift-Sample-GitHubSearch-2016)の他のコード(APIの利用方法など)もとても参考になるので参考にするといいと思います。
このへんのコードの書き方もいつか紹介できたらと思います。
vimのコードジャンプをgtagsでやってみるぞい

# 概要
- ctagsって全然メンテされてなくね。後継とかないわけ？
- GNU global とかいうのがあるらしい
- Vimで飛べるようにしたら快適だよぉ

*注意：ただのメモ*

# インストール(mac)

brewでズン

```
$ brew install global --with-ctags --with-pygments
```

# 設定ファイル作成
設定ファイルをデフォルトからコピー

```bash
cp /usr/local/Cellar/global/6.5.7/share/gtags/gtags.conf ~/.globalrc
```

globalのビルトインのファイル形式以外をpygmentで処理するように修正

これを

```ini:~/.globalrc
default:\
	:tc=native:
```

こう

```ini:~/.globalrc
default:\
	:tc=native:tc=pygments:
```


## 参考
[GNU GLOBALの対応言語を大幅に増やすPygmentsパーサーを導入する](http://qiita.com/yoshizow/items/9cc0236ac0249e0638ff)
[ソースコードを快適に読むための GNU GLOBAL 入門](https://www.machu.jp/diary/20090307.html)
# プラギン導入


## gtags.vim
カーソル下の文字列に対して定義、参照をそれぞれquickfixで表示。
deinでズン。ちなみにgithubリポジトリに、公式プラグインの最新版が公開されてなかったので、リポジトリ作っといた。

```vim

[[plugins]]
repo = 'lighttiger2505/gtags.vim'
hook_add = '''
    " Options
    let g:Gtags_Auto_Map = 0
    let g:Gtags_OpenQuickfixWindow = 1
    " Keymap
    " Show definetion of function cousor word on quickfix
    nmap <silent> K :<C-u>exe("Gtags ".expand('<cword>'))<CR>
    " Show reference of cousor word on quickfix
    nmap <silent> R :<C-u>exe("Gtags -r ".expand('<cword>'))<CR>
'''
```

## gen_tags.vim
gtagsを非同期で自動更新してくれる。
deinでズン。

```vim
[[plugins]]
repo = 'jsfaint/gen_tags.vim'
hook_add = '''
    let g:gen_tags#gtags_auto_gen = 1
'''
```

## denite-gtags.vim
denite表示用のソース。
deinでズン。期待した挙動をしてくれなかったので暇があったらプラグイン作りたい。

```vim
[[plugins]]
repo = 'ozelentok/denite-gtags'
hook_add = '''
    " Prefix key
    nmap [denite] <Nop>
    map <C-j> [denite]
    " Keymap
    nmap <silent> [denite]<C-D> :Denite -buffer-name=gtags_completion gtags_completion<cr>
'''
```
CloudStackーAPIを試してみた(準備編)

#勉強がてら・・
まずとてつもなくCloudStackというのはクラウドサービスを構築するためのソフトウェアのことです。最近はオープンソース化し、Apache CloudStack略してACSとか言われており、最近はぶっちゃけどうなのかなって思いきや、クラウドサービスでは以外にもCloudStackを使っているサービスが多いように感じます。私が無料につられてアカウントを作成した「IDCF Cloud」さんもCloudStackをベースに作っておりました。ということなんでわざわざ構築しなくとも**API**が試せるということで、さっそくマニュアルを基に「仮想マシンを作成」をめどにAPIを使ってみました。

#自宅のサーバ準備
イメージとしては自宅のサーバ⇒IDCFクラウド上の自分のユーザアカウント上でAPIをたたくイメージ
当然ながら自宅のサーバでちょいちょい準備することはある

[ここのサイト](http://docs.idcf.jp/cloud/introduction/?_ga=2.163276793.49876944.1497706680-56523736.1483205952#s_fid=7368C2E7CEF1BF98-23ECBA8D7B62E73A)をメインに進めていくがちょいちょい引っかかるので補足を加えながら進める。

尚、自宅のサーバはCentOSなのでそれをベースに話を進めます

gitとpipのインストール

```ruby:gitのインストール
sudo yum install git
```
これは普通にうまくいきました。

次のpipがうまくいきませんでした・・なので
[ここのサイト](http://qiita.com/value-urano/items/fda44734648388f7ba06)を参考にして以下の手順でpipをインストール

```ruby:pipのインストール
yum install epel-release
yum install python-pip
```

これでうまくいきました。
次にコマンドラインツールインストールを行います。

```ruby:コマンドラインツールインストール
sudo pip install git+https://github.com/idcf/cloudstack-api
```

こちらも問題なくいけたが、新しいのにしろと言われた。
You are using pip version 8.1.2, however version 9.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

バージョン古いんで新しいのにしてねーとのことpip install --upgrade pipを実行すればよい

```ruby:pipの最新版インストール
sudo pip install --upgrade pip
```

次にホームディレクトリーに .idcfrcというファイルを作成してファイルの中身の編集をする。

```ruby:ファイル作成
vi ~/.idcfrc
```

.idcfrcのファイルの中身はあらかじめ指定されている

```ruby:~/.idcfrc
[account]
host=${idcf_end_point}
api_key=${your_api_key}
secret_key=${secret_key}
```

それぞれの項目はIDCFのユーザ画面のAPIから確認することができる
$の部分はいらない
idcf_end_pointはサービス項目のコンピューティングのエンドポイントのこと

これでようやく設定は完了でAPIが使用できるようになる。

CloudStackAPIのドキュメントは[こちら](https://cloudstack.apache.org/api.html)で公開されているのでそれを基にたたくのがベスト

次回は、具体的にAPIを叩き「仮想マシン作成」と削除を行うために手順をみていきます
OwnCloudを使って4TBのファイルストレージを構築してみた(その1)

# 構築してみたー
今時、DropBoxとかGoogleDriveで無料で使えるものもあるしわざわざ自分で構築するオタクなんてどこにいるんだって話だが、はい私です。~~彼女なしの外出るのもめんどく~~GW中はやることもなくせっかく中古のHDDが有り余っていたため5個あったDiskをRAIDを組ませてサーバにマウントしてみた。

# 全体概要
![キャプチャ3.PNG](https://qiita-image-store.s3.amazonaws.com/0/187693/8797072c-f8d3-7707-e2fb-fa8897fca962.png)
ざっくりとした構成は、図を見ていただければわかると思いますが
MariaDBを用いたのは、なんとなくです。OwnCloudを構築するために何が必要かは次章ぐらいに話しますが、Apache,PHP,DBは必要です。


# ハードウェアコンポーネント・OSの概要

サーバは、HP micro Serverを用いました。中古で買ったんですがDiskなしで1万ぐらいでした。
かなりコスパのよい製品として有名です。ただKVM(キーボードバーチャルなんとか)ができると書いていたがなぜか途中でできなくなった。あんま使わないので別に良かったが・・OS領域は200GBのDiskを突っ込んでます。

OS：Ubunchu Serverを入れました。CentOSが良かったが鯖が対応していないとのこと(何度やってもダメでした。ググったところなんかダメそうな感じがして、Ubunchuだけ成功)
と言ってもメモリを無駄に消費をしてしまうため、気になっていたLubunchuを入れてみた。ベースはUbunchuとなるので余計な作業は要らない。GUI操作もサクサクでうれしい限りです。

今回はここまで、次回はOwncloudについて話をしていきます。
PM2でNode.jsのパスを指定して実行するメモ


BLEやGPIOを扱うRaspberry PiだとNode.jsやPM2の実行に`sudo`実行を求められる場合があります。

ただsudo実行をすると今までに自分(piユーザなど)が使っていたNode.jsやPM2のパスだと使えなかったりします。

https://github.com/Unitech/pm2/issues/1034 にあるように`--interpreter=<PATH>`を指定すると良さそう。

* 例

```
$ pm2 start app.js --name app1 --interpreter=~/.nvm/versions/node/v0.12.0/bin/node
```



通常

```
$ pm2 start app.js --name "ble"
```

sudo実行

```
$ sudo /home/pi/.nodebrew/current/bin/pm2 start /home/pi/n0bisuke/findble/app.js --name "ble" --interpreter=/home/pi/.nodebrew/current/bin/node
```

nodebrew経由でインストールしているので`/home/pi/.nodebrew`内を指定します。
jQueryを使ったffmpeg変換処理の進行状況チェック

#ffmpegを利用して動画エンコードするときに進捗チェックしたい
以前作ったWebUIの操作で動画を作成するスクリプトが出て来たので役に立つか不明だがメモ代わりに。ちなみに2014年頃に作ったものらしいのでffmpegの最新ビルドで動くかどうか未確認。

##ffmpeg変換用スクリプト
指定された静止画像をmp4に変換。変なパラメータがいくつか残っているが重要では無いので説明省略。
肝はwhile()内で標準出力から処理済みのフレーム数を取得して進捗率を計算しているところ？

```php:encode.php
<?php

if (ob_get_level() == 0) ob_start();

//　なんかいろいろ省略

$progress = new stdClass;
$progress->hash = $param->hash;
$progress->status = "encode";
$progress->percentage = 0;
$progress->file = 0;
$progress->totalfile = 0;

// export initial value
echo json_encode($progress,  JSON_NUMERIC_CHECK) . "\n";
@ob_flush();
@flush();

$command = "/usr/local/bin/ffmpeg -y -r {$param->real_frame_rate} -i {$tempdir}/%08d.jpg " .
           "  -f mp4 -movflags +faststart ".
           "  -c:v libx264 -r {$CFG->logicalframerate} -pix_fmt yuv420p -s 640x480 -b:v 800k -minrate 800k -maxrate 800k " .
           "  -an " .
           "  -coder ac -refs 8 -threads 0 {$tempdir}/movie.mp4";
$handle = popen($command . " 2>&1",'r');

while (!feof($handle)) {
    $line = stream_get_line($handle, 1024, "¥r");
    if (preg_match('/frame=\s*([0-9]+)/', $line, $match)) $progress->frame = $match[1];
    $progress->percentage = floor(($progress->frame/$progress->totalframe) * 100);
    if ((preg_match('/overhead/', $line)) == 1) $progress->percentage = 100;
    
    echo json_encode($progress,  JSON_NUMERIC_CHECK) . "\n";
    @ob_flush();
    @flush();
}
pclose($handle);

unset($progress->percentage);
unset($progress->frame);
unset($progress->totalframe);

$progress->status = "finish";
echo json_encode($progress) . "\n";
array_map('unlink', glob($tempdir . "/*.jpg"));
rename($tempdir . "/movie.mp4", $CFG->dataroot . "/movies/" . $param->hash . ".mp4");

die();
```

##WebUI側

```js
$.ajax({
    type: 'POST',
    url: '/encode.php',
    data: param,
    dataType: 'json',
    timeout: 0,
    xhrFields: {
        onloadstart: function() {
            var xhr = this;
            $.xhrtimer = setInterval(function() {
                var lastlogs = xhr.responseText.replace(/(^\n+)|(\n+$)/g, "").split('\n');
                var lastlog = lastlogs.pop();
                if (lastlog !== null) {
                    lastlog = eval("(" + lastlog + ")");
                        switch (lastlog.status) {
                            case false :
                           alert(lastlog.result);
                           clearInterval($.xhrtimer);
                           break;
              
                           // 進捗管理用の表示処理
                }
            }, 2000);
        }
    }
});
```
Pretzoでzsh-syntax-highlightingを有効にする方法

# Why
[Pretzo](https://github.com/sorin-ionescu/prezto "Pretzo")を導入している[zsh](http://zsh.sourceforge.net "zsh")で[zsh-syntax-highlighting](https://github.com/zsh-users/zsh-syntax-highlighting "zsh-syntax-highlightin")を有効にする方法がすこし分かりづらかったので書きました。

# Result
結果はこんな風にコマンドの色が変わります。
<img width="569" alt="Screen Shot 2017-06-17 at 9.22.23 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/78600/cf4778aa-20b0-d038-3a47-cae83d466feb.png">

# How

1. `open ~/.zpreztorc`　でPretzoの設定ファイルを開きます。

1. `# Set the Prezto modules to load (browse modules).`のとこに`'syntax-highlighting' \`を追加します。
こんな感じ。

```dotfile:.zpreztorc
# Set the Prezto modules to load (browse modules).
# The order matters.
zstyle ':prezto:load' pmodule \
  'environment' \
  'terminal' \
  'editor' \
  'history' \
  'directory' \
  'spectrum' \
  'utility' \
  'completion' \
  'syntax-highlighting' \
  'prompt'
```

3.`zstyle ':prezto:module:syntax-highlighting' color 'yes'`を`.zpreztorc`に追加したら完成です。
Node-REDで、ブラウザにメッセージを表示するアプリを作ってみた

## はじめに
Node-REDとは、オープンソースの開発プラットフォームです。
IBMの提供するBluemixというクラウドがあれば、簡単に使えます。
今回は、Node-REDを初めて使う人に、Node-REDでのアプリを掴んでいただきたいと思います。

## 今回使用するノード
httpノード:ブラウザでアプリを開くノード
templateノード:ブラウザに表示されるされる内容を記述
http responseノード:ブラウザに出力するノード

### アプリの完成図
![rehello6.png](https://qiita-image-store.s3.amazonaws.com/0/185050/e32b2b91-df78-8c4a-0dc8-3cd0a1f7ecb6.png)

## アプリの実装方法
1. Bluemix上で、Node-RED Starterを選択し、Node-REDのアプリを作成します。  
Bluemixへの登録、ログインは、下記URLから行ってください。  
https://console.bluemix.net/  
　　
2. Node-REDのアプリが開始中になったら、Node-REDの編集画面を開きます。  
 　
3. 左のノード一覧の入力カテゴリーから、httpノードをフロー上にドロップ&ドラッグします。 
![hello1.png](https://qiita-image-store.s3.amazonaws.com/0/185050/4c67c4b6-b91e-e0d4-88ec-f006840af930.png)
　　
4. httpノードをダブルクリックし、httpノードの設定をします。  
Methodの「GET」を選択し、URLに「/hello」を入力し、完了ボタンをクリックします。  
これで{アプリ名}/helloのURLにアクセスすることができます。

![rehello1.png](https://qiita-image-store.s3.amazonaws.com/0/185050/0c019cc4-aa70-64d4-3a6a-27e8d719cd2f.png)
  
　　
5. ブラウザにメッセージを表示するためには、templateノードを使います。  
左のノード一覧の機能カテゴリーから、templateノードをフロー上にドロップ&ドラッグします。
![rehello2.png](https://qiita-image-store.s3.amazonaws.com/0/185050/8f633dc3-8949-0477-b515-cc1625872642.png)

　　
6. templateノードをダブルクリックし、Template欄に「Hello World!!」と記述し、完了ボタンをクリックします。  
![ug9.png](https://qiita-image-store.s3.amazonaws.com/0/185050/b01cbfc3-20d5-6aeb-2db1-5646ff3ace09.png)  
　　
7. 左のノード一覧の出力カテゴリーから、http responseノードをフロー上にドロップ&ドラッグします。
http responseノードは設定不要です。

![rehello3.png](https://qiita-image-store.s3.amazonaws.com/0/185050/72618832-bf87-df71-d8c2-e44332f2342e.png)

　　
8. httpノード、tempalateノード、http responseノードの順でノードを結びます。
ノードを結合したら、右上のデプロイボタンをクリックします。

![rehello4.png](https://qiita-image-store.s3.amazonaws.com/0/185050/0f9091c1-be9c-7bc3-e69f-2d5fc80ac4db.png)
　　
9. Node-REDのアプリの語尾に「/hello」を入力し、ブラウザでアクセスします。
下記のようにブラウザに、「Hello World!!」と表示されたら、完成です。

![rehello5.png](https://qiita-image-store.s3.amazonaws.com/0/185050/9bba747b-6220-99cd-2609-ed8e9a3f0b07.png)
Node-REDで時刻を画面表示するアプリを作ってみた

## はじめに

Node-REDとは、オープンソースの開発プラットフォームです。
IBMの提供するBluemixというクラウドがあれば、簡単に使えます。
今回は、Node-REDを初めて使う人に、Node-REDでのアプリを掴んでいただきたいと思います。

### 今回使用するノード
1. ingectノード:処理のトリガーとなるノード
2. debugノード:debugタブに文字列などを出力するノード
3. functionノード:Node.jsのコードで、何らかの処理を書くノード

### アプリの完成図
![ug1.png](https://qiita-image-store.s3.amazonaws.com/0/185050/c8ae1c91-262b-cbad-7022-1f818b7d2bd9.png)


## アプリの実装方法
1. Bluemix上で、Node-RED Starterを選択し、Node-REDのアプリを作成します。  
Bluemixへの登録、ログインは、下記URLから行ってください。  
https://console.bluemix.net/  
　　
2. Node-REDのアプリが開始中になったら、Node-REDの編集画面を開きます。  
　　
3. 左のノード一覧の入力カテゴリーから、ingectノードをフロー上にドロップ&ドラッグします。 
![jikoku1.png](https://qiita-image-store.s3.amazonaws.com/0/185050/e84d2255-d0ab-a66e-1edb-d2558a5c0f1b.png)
　　
4. injectノードをダブルクリックし、injectノードの設定をします。  
「Payload」の「timestamp」を選択することで、タイムスタンプをdebugタブに出力することができます。
![jikoku7_1.png](https://qiita-image-store.s3.amazonaws.com/0/185050/2afbcc72-eec7-90e0-bf53-d6434414c9a2.png)


　　
5. 同様に、左のノード一覧の出力カテゴリーから、debugノードをフロー上にドロップ&ドラッグします。
![jikoku2.png](https://qiita-image-store.s3.amazonaws.com/0/185050/1fe9fccb-04d5-b1c0-e307-a08ec41c85ed.png)
　　　
6. フロー上のingectノードの右の点と、debugノードの左の点を線で結びます。
ノードを結合したら、右上のデプロイボタンをクリックし、フローの変更をアプリに反映します。
![jikoku3.png](https://qiita-image-store.s3.amazonaws.com/0/185050/64254ee1-90a3-96fe-4ebd-a81eb2cee602.png)
　　
7. ingectノードの左側のボタンをクリックすることで、右側のdebugタブにingectノードをクリックしたタイムスタンプを取得することができます。
![jikoku6.png](https://qiita-image-store.s3.amazonaws.com/0/185050/7d1974b2-a98d-beed-0a01-d3c20741cf9e.png)
　　
8. 今debugタブに表示されているタイムスタンプを時刻に変換する処理を加えます。
左のノード一覧の機能カテゴリーから、functionノードをフロー上にドロップ&ドラッグします。
![jikoku8.png](https://qiita-image-store.s3.amazonaws.com/0/185050/8b75ff11-6b43-725a-0abb-03c34d6de68f.png)
　　
9. functionノードをダブルクリックし、functionノードの設定をします。
functionノードでは、「Function」にNode.jsのコードを記述できますので、この中に下記のコードを記入し、「完了」をクリックしてください。
![jikoku9.png](https://qiita-image-store.s3.amazonaws.com/0/185050/13a9786c-1e4f-f016-fdf2-fe757afb906c.png)


```ruby:functionノードの「Function」に記述するコード
var date = new Date();
date.setTime(msg.payload);
msg.payload = date.toString();
return msg;
```

10.ingectノードとdebugノードを繋げた線をマウスで選択し、deleteキーを押します。
マウスで選択し、deleteキーを押すことで、ノード、ノードをつなぐ線を消すことができます。
　　
11. ingectノード、functionノード、debugノードの順にノードを繋げ、右上のデプロイボタンをクリックし、フローの変更をアプリに反映します。
![jikoku10.png](https://qiita-image-store.s3.amazonaws.com/0/185050/3b98ff3f-2e73-d6eb-7db4-99a331f86841.png)
　　
12. 再度ingectノードの左側のボタンをクリックし、世界標準時刻が表示されたら完成です。
![jikoku11.png](https://qiita-image-store.s3.amazonaws.com/0/185050/c8d02fbe-2331-4895-5b46-1c8084ac2bba.png)
sublimeをターミナルから開きたいんだ

`EL Capitain`からRootlessという機能が備わって、システムに大きな影響を与えてしまいそうな操作はできなくなりました。

例えば`/user`などにはファイルやディレクトリを任意に削除や作成はできません。

`/usr/local/bin`には作れるそうです

```ruby:terminal
$ sudo ln -s "/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl" /usr/local/bin/subl
```

```ruby:Terminal_Sublime_textの起動
$ subl
```

```ruby:Terminal_Sublime_textをカレントディレクトリをTREEリストとともに起動
$ subl .
```
ソフトウェアにおける「設計」とは何か？

私は絵を描くのが好きなエンジニアです。デザイン的な観点から、ソフトウェア設計が語られることが少ないのかなと思い、自分の考えを整理してみました。

# 「設計」に対するイメージ
![job_kenchikuka_woman.png](https://qiita-image-store.s3.amazonaws.com/0/116939/698ec0b4-1874-e99e-7c6f-7a6b38bb0742.png)
「設計」と言われると精密な設計図を描くような高度なイメージが湧きませんか？
より高度な人材が上流工程で設計し、下流工程でそれに沿って実装を行うような、工業製品を作るような印象です。

# ソフトウェアにおける「設計」の本質
![art_live_painting.png](https://qiita-image-store.s3.amazonaws.com/0/116939/34f42aef-1664-b015-2031-3ad97034ca0b.png)
英語では「Software Design」ですけど、私は「デザイン」の話だと思います。
これは、UIデザイナー等が行う「デザイン」と同じ内容になります。

そもそも「デザイン」とは、絵を描けること等とはあまり関係がなく、状況を分析し構築することを指します。
噛み砕いて言うと、『使い易さを考え続けること』、これをしていればデザインをしていると言えます。あまり難しい話ではありません。

# 誰が為にデザインをする？
デザイナーの場合は、顧客の要求に合わせてデザインを検討するのですが、エンジニアは「隣で働くエンジニア」に向けてデザインをします。

デザインの範囲は広く、アーキテクチャの選択からif文1行に至るまで、デザインを必要とします。
その為の体系的なノウハウとして、デザインパターンやMVC、MVPアーキテクチャ、エクストリームプログラミングなどなど・・数え切れない程の技術が生まれています。

# 「デザイン」センスを磨くには？
![bijutsu_paint_woman2.png](https://qiita-image-store.s3.amazonaws.com/0/116939/96c2d72d-9174-1ed8-32fb-4edbae686bc7.png)
デザインをするにはセンスが必要です。そして、センスは日々の鍛錬により鍛えられます。
その為に効果が大きい技術として、「ユニットテスト」、「TDD/BDD」が挙げられます。

鍛える為の手っ取り早い方法は、「失敗」の数を増やすことです。
まずはユニットテストで仕様を描き、あとは大雑把にロジックを書いたり、新しく学んだデザインパターンを採用してみたりと大胆に挑戦していきます。
絵を描く人が、まず当たりを付けて、デッサンを行って鍛えるのと同じです。

業務の場合でもテストがあれば、大胆なリファクタリングもし易い為、ある程度の罪は許されるのではないでしょうか。
むしろ、テストのない仕様をしっかりと固めたコードよりも、テストがあって作り変え易いコードが、ソフトウェアの設計には求められています。

# 最後に
良いプログラマとは、たとえ意識的じゃなくても、デザインをしている人です。
デザインは奥深く、楽しいものです。是非皆さん1文字1文字に思いを込めて、キーを叩きましょう！
GoogleSpreadSheetBackEndにbyteデータを格納する＋機能追加

## まずはじめに
こちら[UnityのWebGL出力に簡単に無料でグローバルランキングを実装できる仕組みを考えてみた](http://qiita.com/divideby_zero/items/50897a2695aa04bfeb69) の補足（追加）に記事になります。　
できれば先にそちらをどうぞ。

## 調べたところ
正式な情報がどこに書いてあるかわからないんですが、とあるところにGoogleSpreadSheetの1セルに書ける文字列の長さが**50000文字**って書いてあったんですよね。

ということは・・・。　よほど大きいデータじゃなければ、**BASE64で文字列にして格納**すれば結構なサイズのbyteデータもアップロードできるのでは！？　というひらめき（？）

ということで、以前作った某ゲームのクローンのグローバルなリプレイ機能を追加してみました。
https://unityroom.com/games/1umines

なお、byte[]からBase64文字列への変換、およびBase64文字列からbyte[]への変換には
`System.Convert.ToBase64String( byte[] )`と `System.Convert.FromBase64String(string )`を使用しました。ラクちんだなぁ。

## そこで分かった問題点
ただ、一つ問題があります。
普通にランキングの箇所にBASE64でリプレイデータを付けてしまうと、リプレイが必要ない場合（ただランキングが表示したい場合など）に無駄なデータが大量に降ってきてしまう事です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37184/9b3c34f8-f206-9c6b-451e-e0b509b12d22.png)


そのため、**ほしいデータだけを先に指定してあげる機能**が必要です。
すなわちSQLで言うところの**Select構文**を追加することにしました。

## 追加① Select機能
`Select(params string[] selects);`
を`SpreadSheetQuery`に追加しました。

```csharp
    var query = new SpreahSheetQuery("scoreRank");
    query.Select("id,name,hiscore");
```

のように返却してほしい列の列名を,区切りで列挙する感じです。
なお、

```csharp
    query.Select("id","name,hiscore");
```
のようにしても解釈されるようにしてあります。

このSelect機能を使うことで、とりあえずのランキング取得ではreplayDataを省いた列名だけを列挙してFindAsyncして、リプレイ再生するときにはidを指定してまたFindAsyncする。といった使い方ができるわけです。ﾍﾞﾝﾘｰ。

## 追加② Distinct機能
ついでに前からほしいと思っていた**Distinct機能**も追加しました。
これはざっくり言うと「重複を省く」機能です。

`Distinct(string distinctKey);`
を`SpreadSheetQuery`に追加しました。

```csharp
    var query = new SpreahSheetQuery("scoreRank");
    query.Distinct("id");
```

のようにしておくと、返却されるデータで同じidがある場合は先頭データのみ取得されます。

例えばランキング処理で


| id   | score | date     |
|------|-------|----------|
| 0001 | 100   | 20170512 |
| 0001 | 120   | 20170601 |
| 0005 | 80    | 20170505 |
| 0001 | 140   | 20170404 |
| 0005 | 99    | 20170504 |
| 0004 | 30    | 20170504 |

のように1ユーザーがスコアを複数登録している場合、scoreのTOP3を出そうとした場合全てid=0001が取れてしまうわけです。
時にそれが望ましい場合もありますが、**ユーザーの重複を除いたTop3**が欲しいという事は普通にありうるとおもいます。

そんな時に
`Distinct("id");`

と指定してあげることで、idの重複がなくなり、socreやdateは上から見ていって先に見つかったほうを使用するので

| id   | score | date     |
|------|-------|----------|
| 0001 | 100   | 20170512 |
| 0005 | 80    | 20170505 |
| 0004 | 30    | 20170504 |

このようなデータが返却されることになります。
これではTOP3ではなくなってしまうので、通常は**何かしらをキーに整列**させたものが対象になるはずです。

例えば、各人のhiscoreのTop3なのであれば

```csharp
    var query = new SpreahSheetQuery("scoreRank");
    query.OrderByDescending("score").Distinct("id");
```

とすれば、

| id   | score | date     |
|------|-------|----------|
| 0001 | 140   | 20170404 |
| 0005 | 99    | 20170504 |
| 0004 | 30    | 20170504 |

のように、id=0001のデータは最高点である140点のScoreになりますし、Scoreはどうでもいいから、各ユーザーの最新（一番最後のデータ）がほしい。という場合は

```csharp
    var query = new SpreahSheetQuery("scoreRank");
    query.OrderByDescending("date").Distinct("id");
```

のように日付(date)を指定すればよいということです。

よかったら使ってみてください。
テーブル結合についての備忘録 その2

こんにちは。

2度目の投稿になります。

今回も前回の記事の続きとして、
SQLによるテーブル結合についてまとめさせていただきます。

**前回の記事**
[テーブル結合についての備忘録](https://qiita.com/mounntainn/items/c6ca4184acc4839f9679)

前回のまとめは

**SQLのテーブル結合時の順番は、　ONで結合　→　WHEREで抽出**
**LEFT OUTER JOINはONで抽出はできない**

といった内容でした。

今回はこれらの続きとしてのTOPICをまとめさせていただきます。
**環境:SQL Server 2012**

**ただし、今回の記事については一概にそうとはいえない内容も含まれています。**
**環境次第では異なる結果が得られる可能性もあります。**


#INNER JOINについて
前回の記事で内容に触れたのはLEFT OUTER JOINでした。

RIGHT OUTER JOINはLEFT OUTER JOINを左右反転させただけのもので、
使う機会としてはあまり無いと思いますので説明は割愛します。

今回説明させていただく、
INNER JOINの特徴は以下になります。

**INNER JOINでは結合する左右両テーブルで、**
**条件が満たされていない不要な行を削ぎ落とします。**

LEFT OUTER JOINでは問答無用で左側の行を全て呼び出ししていました。
比べて、INNER JOINでは
左右両側で条件が満たされているカラムのみを呼び出しして
不要な行を削ぎ落としします。

また、
両側のテーブルで共通して条件が満たされていないカラムを持つ行は
削ぎ落としされる為に
**WHEREの結合条件でも、ONの抽出条件でも、**
**得られる結合結果は同じものとなります。**

つまり、

```SQL:①
SELECT
    a.name
    , b.name
FROM a
    INNER JOIN b
        ON a.b_cd = b.cd
WHERE 
    b.cd = '1'
```

```SQL:②
SELECT
    a.name
    , b.name
FROM a
    INNER JOIN b
        ON a.b_cd = b.cd
        AND b.cd  = '1'
```

以上の①、②の2パターンでどちらも得られる結果は
同じなんですね。

**では、この内どちらの方がベターなんでしょうか？**

ここからは、個人的な推測も入ってきます。
環境にもよる為に、ケースバイケースなので、
100％とは言えないと思います。

結論から述べると、

**可読性を重視するなる①、**
**パフォーマンスを重視するなら②**

になるのかなと思います。

前回の記事で、
結合の際の処理の流れと、
ONとWHEREに書かれるべき条件を示しました。

そう、まずONの条件で結合して、
WHEREの条件で抽出するんでしたね？

仮に大量の10万件ものデータ同士で結合させるとしましょう。
その際にはまず②のパターンのように、
ONで結合する時点で、
不要なデータは取り除いていた方が効率的ですよね。

実際には抽出をかける
テーブルのインデックスの構成に左右されたり
DBMSのオプティマイザが仕事をしてくれる為に
一概に必ず速いとも言えないようです。

個人的な意見としてはロジカルに考えるなら
ONでデータの件数を減らしておいた方がいいのかな
と思います。

しかし、本来はONに書かれるべき条件は結合条件であるべきです。
条件が多く書かれて、テーブルのデータ件数もそんなに無いような時には
結合条件はONへ、抽出条件はWHEREへ書き分けるべきでしょう。

結論が着地できたのか怪しいところですが
大事なところは
**INNER JOINではONでも、WHEREでも得られる結果は**
**共通して条件が満たされていない行は削ぎ落とされる為に変わらない。**
ってところですね。

#抽出条件を含むLEFT OUTER JOINの最適な結合方法

さて、前回の記事だけでは未解決の部分があります。
前回の記事の冒頭であったこの会話の部分です。

SE1「*WHERE句でテーブル結合なんかしたら駄目だよ！
 　　　10万件のデータと10万件のデータのテーブル同士をくっ付けるとすごく無駄になるよ！*」
 私「*なるほど！　先に結合のときに件数を減らしとくわけですね！*」

そう。結局、前回の記事の結論ではLEFT OUTER JOINの場合、
ON句では抽出が出来ない為にWHEREへ書くと終わりました。

それでは一週回ってしまってこの問題が解決できていないままですよね。
LEFT OUTER JOIN時にあらかじめ結合の件数を減らしておく為には
どうすればいいのでしょうか？

その答えは**サブクエリ**を使う方法があります。

結合時の処理の順番は

**ONの結合条件　→　WHEREの抽出条件**

となっていましたが、
サブクエリが含まれるSQLの場合は、

**サブクエリの()内の処理　→　ONの結合条件　→　WHEREの抽出条件**

というような流れで処理が行われていきます。

具体的な例をあげてみます。
①のSQLをサブクエリを使って書き直したものが②になります。
(更新しました。サブクエリにはWITH使いましょう。)

```SQL:①
SELECT
    a.name
    , b.name
FROM a
    LEFT OUTER JOIN b
        ON  a.b_cd = b.cd
WHERE
    b.cd = '1'
```

```SQL:②
WITH aaa AS(
    SELECT * FROM a
    WHERE a.b_cd = '1'
)

SELECT
    aaa.name
    , b.name
FROM aaa
    LEFT OUTER JOIN b
        ON aaa.b_cd = b.cd
```

②のSQLであれば

**①サブクエリの()内の処理　(この時点でa.b_cd = '1'に抽出済み)**
**②ONによる結合**

といった処理の流れとなります。

これにより、
無駄な件数のテーブル結合を防ぐことが出来るうえ、
左側のテーブルはサブクエリによって既に抽出済みのために
LEFT OUTER JOINによって左側のテーブルの行が全て呼び出されたとしても
最終的に呼び出される結果も1行に抽出がされたテーブルとなってくれています。

可読性は著しく落ちてしまいますが
ロジカルに考えるとこれが最も効率的な結合方法になるのかなというのが
今回の件で至った結論になります。

しかしこれまた、
実際には抽出をかける
テーブルのインデックスの構成に左右されたり
DBMSのオプティマイザが仕事をしてくれる為に
一概に必ず速いとも言えないようです。
~~DRY原則に違反してますね。コードならメソッド化しましょう。~~

業務で使う場合には実際の環境で各SQLを試してみて、
パフォーマンスにどれほどの差が出るかを確認したうえで
最適なSQLを組んでみるのがいいと思います。
Upverterで回路・PCB設計して、基板を起こしてみた。

# はじめに
- 最近知ったんですが、プリント基板の試作が1000円（10枚）くらいでできてしまうらしいです。
- ググるとよく引っかかる、Fusion PCBのサイトを見たら4.9$だったので、ついその気になってしまった、というのが今回の記事です。

---
# 回路設計について
- [UART通信のキャプチャ](http://qiita.com/katsumin/items/27fbae6b61edd1fa8167)をするのに、簡単な回路を作りました。
- この回路をベースに、バリエーションを加えて回路図を整理し、ラズパイ拡張ボードとして使えるようにPCB設計まで行いました。
- 回路図は、[LineMonUsb](https://upverter.com/katsunog/9f5c79469f5721c0/LineMonUsb/)で公開しています。

---
# PCB設計について
- 今まで、仕事で多くの回路設計をしてきましたが、PCB設計は基板屋さんにお任せでした。
- 初めてPCB設計ツールを使ってみたわけですが、思いのほかツールが使いやすく、ほとんど迷うことはありませんでした。
- ちょっとハマったのは、以下のようなところくらいです。
    1. ベタパターンは、どう作る？
        - 「Pour」で作ります。
        - [こちらのブログ記事](http://fukuno.jig.jp/1302)が、とても参考になりました。
    1. 基板外形は、どう書く？
        - 「Path」で書きます。
        - 「Edit Points」の方が自由度が高いですが、四角なら「Generate Rectangle」の方が書きやすいと思います。
    1. 取り付け穴は、どう書く？
        - 「Through Hole」で書きます。
        - 「Through Hole Inspector」（スルーホールの設定画面）で、チェックを全部外して、Generalの「Internal Diameter」（内径）を2.6mmとしました。

---
# 基板発注
- 前述のFusion PCBに、基板発注しました。
    - かかった金額は約2600円で、内訳は基板代が4.9$（約550円）で、残りは送料（DHL）です。
        - 選択肢がSingapore Post（だったかな。ちょっと記憶が怪しい）、DHL、FedExの３つでしたが、DHLが一番早く、二番目に早いFedExとの金額差が数百円だったのでDHLにしちゃいました。
        - Singapore Postについては、トラッキングできない的なコメントが付いていたので、ちょっとやめました。
- 発注から、基板到着までの流れ
    1. ガーバーデータのエクスポート
        - Upverterで「Gerber Format (RS-274X extended)」とすると、zipファイルがダウンロードされます。
    1. Fusion PCBのサイトで注文しますが、ここで上記のガーバーデータを指定します。
        - zipファイルは、何の加工もせずにそのままアップロードしました。
        - アップロードすると、ガーバ・ビューアで基板のイメージを確認できます。
        - 多くの設定がありますが、外形寸法（56×64.5）を変えて、レジスト色を黒にしたくらいで、他はデフォルトのままにしました。（変えると、金額が上がります）
    1. PayPalで支払いを済ませたら、あとは到着を待つだけです。大体の時間経過は、以下のような感じでした。
        - 5/27（約13時）に注文
        - 約２時間後に製造開始
        - 6/1に発送
        - 6/5に佐川急便に委託
        - 6/6に自宅到着
        
        ![fusionpcb_tracking.png](https://qiita-image-store.s3.amazonaws.com/0/166435/a74921ae-c07a-d7a8-f1b5-4fc7d5f31297.png)

---
# 回路の機能説明
- 基本的には、RS-232Cのレベル変換になります。
- ただ、ラズパイのUARTをレベル変換するだけではつまらないので、下記の２つも載せられるようにしました。（ラズパイのUARTと合わせて、３種の排他利用です）
    - 秋月電子製ＵＳＢ－シリアル２ｃｈ変換モジュール（前述のUARTキャプチャに使ったもの）
        - 2chで送受信する使い方と、2chで受信（UARTキャプチャ）する使い方の２通り。
    - LPC810（自作のI2C-UARTコンバータ）
        - I2C-UARTコンバータのソースは、[LPC_i2c_uart(GitHub)](https://github.com/katsumin/LPC_i2c_uart)で公開しています。
        - ラズパイとはI2C接続され、UART送受信ができます。

- ジャンパ設定（○は、ショート）

|UART|方向|J1|J2|J3|J4|J5|J6|備考|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|ラズパイのUART|DTE||||○|○|○||
||DCE|○|○|○|||||
|USB（2ch送受信）|DTE||||○|||chBが送信、chAが受信|
||DCE|○||||||chAが送信、chBが受信|
|LPC|DTE||||○|||PIO0_5とJ5を接続、PIO0_1とJ6を接続|
||DCE|○||||||PIO0_5とJ2を接続、PIO0_1とJ3を接続|
|USB（2ch受信）||||||||送信側は未使用|

- LPC810のデバッガ接続
    - トランジスタ技術2014年3月号付属のARMライタを接続できます。
    - 下の写真は、デバッグ中のものです。（直立している基板が、ARMライタです）
    ![IMG_1994.JPG](https://qiita-image-store.s3.amazonaws.com/0/166435/775b37cc-620f-29be-09a0-b1685b9868e8.jpeg)
Cプログラムを異なるマイコンで動作させる際のエンディアンとビットフィールドの取り扱い

# エンディアンについて

例えばH8用のCプログラムの一部をWindowsで動作させたいとする。

H8はビッグエンディアン、Intel CPUはリトルエンディアンなので
外部のバイナリファイルを読み込むときなどに問題になる。

```C:sample1.c
UB	ReadFile[100];	//外部のバイナリファイルを読んで1バイトずつ格納するための配列

typedef struct test{
	UH	Code;		// コード(2byte)
	UB	yobi[14];	// 予備
}TEST;

TEST	*file_ptr;

//（中略:ReadFileに外部のバイナリファイルを1バイトずつ格納する処理)
	
	file_ptr = (TEST*)&ReadFile[0];


```

ReadFileの値が以下であったとする。

> ReadFile[0]=0x01
> ReadFile[1]=0x02

このとき、**"file_ptr->Code"**の値は以下のようになる。

| H8               | Intel             |
|:-----------------|:------------------|
| 0x0102           | 0x0201            |

　
　

```C:sample2.c
UH	code;	//2バイト
UB	*ptr;

ptr = (UB*)&code;
*ptr = 0x01;
ptr++;
*ptr = 0x02;

```

このときも、**"code"**の値は以下のようになる。

| H8               | Intel             |
|:-----------------|:------------------|
| 0x0102           | 0x0201            |



# ビットフィールド

実は**共用体のビット定義も逆**になっている。

```C:sample3.c
typedef union {
	UH	data; //2バイト
	struct {
		UH	bf1:7;
		UH	bf2:5;
		UH	bf3:4;
	} bit;
} BIT_TEST1;

```

sample3.cはCPUによって先頭メンバのビットフィールドが逆順になる。

|H8    |     |     | 
|:-----|:----|:----|
| bf1 :7bit  | bf2 :5bit | bf3 :4bit |
| bit15~9 | bit8~4 | bit3~0 | 

| Intel |      |     |
|:------|:-----|:-----|
| bf3 :4bit   | bf2 :5bit  | bf1 :7bit  |
| bit15~12 | bit11~7 | bit6~0 |

 
　 


ただし**先頭メンバが配列**のときは、配列の要素ごとにビットフィールドが逆になる。

```C:sample4.c
typedef union {
	UB	data[2]; //1byte×2の配列
	struct {
		UB	bf1:4;
		UB	bf2:4;

		UB	bf3:4;
		UB	bf4:4;
	} bit;
} BIT_TEST2;


```

| H8   |     |   |  | 
|:-----|:----|:--|:--|
| **data[0]**|      | **data[1]**|  
| bf1 :4bit   | bf2 :4bit  | bf3 :4bit | bf4 :4bit |
| bit7~4 | bit3~0  | bit7~4 | bit3~0 | 

| Intel |      |  |   |
|:------|:-----|:--|:---|
| **data[0]**|      | **data[1]**|   |
| bf2 :4bit   | bf1 :4bit  | bf4 :4bit | bf3 :4bit |
| bit7~4 | bit3~0  | bit7~4 | bit3~0 |
git addしたらCRLF will be replaced by LFなエラー


###git addした時にこんなwarning
```
$git add .
warning: CRLF will be replaced by LF in cakephp/blog_app/vendor/seld/cli-prompt/res/hiddeninput.exe.
The file will have its original line endings in your working directory.
```

Gitが改行コードをCRLFへ変更しようとしているらしい

以下を実行する

```
$git config --global core.autoCRLF false
```

これで改行コードをCRLFへ変更しなくなる
UnityのScrollViewの子オブジェクトにEventTriggerをアタッチしてスクロールしなくなった時の対処法

UnityのScrollViewの子オブジェクトにEventTriggerをアタッチしたら、子オブジェクト上でクリック開始されるとスクロールしなくなったので以下のように対応しました。

子オブジェクトのEventTriggerコンポーネントを削除して、次のスクリプトを追加します。

```C#
using UnityEngine.EventSystems;
using UnityEngine;

public class ClickableContent : MonoBehaviour, IPointerClickHandler {

	public void OnPointerClick (PointerEventData eventData) {
		print ("クリック");
	}

}
```

今回はScrollViewの子オブジェクトのクリックが取得したかったので、これでクリックの取得とスクロールの両方を実現できました。
もう少し複雑な処理がしたければ、こちらが参考になると思います。
http://answers.unity3d.com/questions/902929/scroll-not-working-when-elements-inside-have-click.html
foundation-rails で select 要素の▼が二重に表示される場合の解決方法

# 現象
[foundation-rails](https://github.com/zurb/foundation-rails) で select 要素を定義した際に、特定の環境で▼が二重に表示されます。

![double_triangle.png](https://qiita-image-store.s3.amazonaws.com/0/36122/af538c0c-0254-a9e4-24ac-969096489eb5.png)

自分が確認したところ、次の環境で発生しました。

- Chrome 53.0.2785.135 on Android 7
- 標準ブラウザ on Android 6/5
- Windows7 Enterprise
  - IE11
  - Chrome 59.0.3071.104

また、macOS Sierra 10.12.4 での Firefox 54.0 では次の様に微妙な▼が表示されました。

![firefox_select.png](https://qiita-image-store.s3.amazonaws.com/0/36122/1531ff88-20cf-26b9-f33d-303fe378381a.png)

ただし、次の環境では発生しませんでした。

- macOS Sierra 10.12.4
  - Chrome 59.0.3071.86
  - Safari 10.1

# 解決方法
## 方法1. autoprefixer-rails の導入
ブラウザのサポート状況によってベンダープレフィックスをよしなに自動挿入してくれる [autoprefixer-rails](https://github.com/ai/autoprefixer-rails) を導入します。

Gemfile に定義を追加します。

```rb
gem "autoprefixer-rails"
```

インストール。

```
bundle install
```

最後に Rails を再起動します。

開発初期段階であればこの方法がベターだと思います。ただし、影響範囲が大きく、開発フェーズが後半以降だと他のスタイルへの影響がないか確認する必要があり、難しいかもしれません。

その場合は次の方法2の検討をしてください。

## 方法2. CSSを手動上書き
次の定義を適当な CSS に追加します。

```css
select{
  -webkit-appearance: none;
  -moz-appearance: none;
}
```

手軽ですね。影響は select 要素のみに限定されます。

# 原因
ブラウザの標準スタイル定義とは別に、Foundation が `background-image` を定義しているためのようです。

次は foundation-rails による select 要素の CSS 定義を Chrome の Developper Tools で確認した画面です。appearance はサポートしていないようで無効化されています。
![select_css.png](https://qiita-image-store.s3.amazonaws.com/0/36122/cd0d5616-1219-a752-8f14-5b212282d5c9.png)

Issue によると、そもそもこれはバグではなく、Autoprefixer を付けない Sass を使ったバージョン（foundation-rails がこれに該当）に発生する現象との事です。

- [select icon in chrome · Issue \#9968 · zurb/foundation\-sites](https://github.com/zurb/foundation-sites/issues/9968#issuecomment-303176453)

Foundation のドキュメントにもベンダープレフィックスは Sass に含めていないという内容が記述されています。
> We don't include vendor prefixes in our Sass files—instead, we let Autoprefixer handle it for us. 
[Sass \| Foundation for Sites 6 Docs](http://foundation.zurb.com/sites/docs/sass.html#autoprefixer-required)
Twilioで在宅勤務の外線電話をステキな感じにする３(SIPクライアント+Twilio番号で発信)

# これまでのもの
Twilioで在宅勤務の外線電話をステキな感じにする(一斉呼び出し・時間外非応答)(前置き編)
http://qiita.com/chabose/items/2dc18db77bdf14c2738f
Twilioで在宅勤務の外線電話をステキな感じにする(一斉呼び出し・時間外非応答・Slack通知)(実装編)
http://qiita.com/chabose/items/f098aa4ff28ad5492fa3

# 今回作るもの
前回までに着信部分を作ったので、今回は発信を実装します。
Twilioで取得した電話番号で着信できても、その番号で折り返しができなければあまり意味がありません。
なので、前述のSIPクライアントから発信した場合、Twilioで取得した番号で発信先に電話がかかるようにします。

イメージはこんな感じです。
![outgoing.png](https://qiita-image-store.s3.amazonaws.com/0/59725/f47f0388-629d-91d0-d266-312eaba4f63d.png)

## フロー
1. SIPクライアントから電話番号に発信する
2. **TwiMLが呼ばれ、発信先番号を解釈する**
3. **Twilio番号を発番にして外部に発信する**

太字部分が今回実装する部分です。

## 実装

### 電話番号の解釈
SIPクライアントを利用した場合、通常のように番号入力して発信すると、宛先が`090XXXXXXXX@sipdomain.example.com`のような形でSIPサーバーに送られます。

一方、Twilioが発信のときに使う番号は、`+国番号(日本:81)と国内番号の先頭0を取ったもの`、つまり`+8190XXXXXXXX`のような形式なので、これを合わせてあげる必要があります。

1. 電話番号の先頭が0の場合は国内電話なので、@よりあとを削除、先頭の0を削除し、+81をつけて発信先番号を作成する(ex. 09012345678@sipdomain.example.com)
2. 先頭の番号が+の場合は、国際電話なので、@よりあとを削除し、発信先番号を作成する(ex. +18001234567@sipdomain.example.com)
3. それ以外の場合はSIPの内線の可能性があるので、そのまま発信先番号として利用する(ex. 1001@sipdomain.example.com)

### コード


```PHP:outbound.php
<?php
header("content-type: text/xml");
echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
    
$to = $_POST['To'];
$endpos = strpos($to,"@");
$number = substr($to,4,$endpos-4);
$firstletter = substr($number, 0,1);
 
switch($firstletter){
	case "+":
		$dial = "<Number>${number}</Number>\n";
		break;
		
	case "0":
		$number = substr($number, 1);
		$dial = "<Number>+81${number}</Number>\n";
		break;
		
	default:
		$dial = "<Sip>${to}</Sip>";
}
?>	
<Response>
		<Dial callerId="+8150XXXXXXXX">
			<?=$dial?>
		</Dial>
</Response>
```

こんな感じですかね。
callerIdには必ずTwilioで購入した番号を記載します。

これをおいたURLを
[プログラマブルVoice]-[SIPドメイン]-設定画面-[REQUEST URL]に設定すれば発信については完了です。

## 次は
Lambda+API Gatewayですね。
日時を手軽に特定形式の文字列に変換する方法のメモ

日時を手軽に特定形式の文字列に変換する方法のメモ



```JavaScript:sample.js

/**
 * 日時を特定形式の文字列に変換します。
 *
 * <p>date.toLocaleString() で取得される文字列について、
 * 日時の構成要素が年,月,日,時,分,秒となっていること。
 * また、日時の構成要素が数字のみで表現されていること。
 * 
 * @param date 変換対象のDateオブジェクト
 * @param delim1 日付の区切り文字。省略時は""(空文字)
 * @param delim2 日付と時刻の区切り文字。省略時は""(空文字)
 * @param delim3 時刻の区切り文字。省略時は""(空文字)
 * @return 変換した文字列
 */
function datetimeFormat(date, delim1, delim2, delim3) {

    var d1 = delim1 || "";
    var d2 = delim2 || "";
    var d3 = delim3 || "";

    var rgx1 = /\b(\d)\b/g;
    var rgx2 = /^\D*(\d+)\D+(\d+)\D+(\d+)\D+(\d+)\D+(\d+)\D+(\d+).*$/;

    // ロケールに従った日付書式文字列を取得する
    // (書式例) 2017/1/1 0:00:00
    var s = date.toLocaleString();

    // 数字1桁のみのものはゼロ埋めして2桁にする
    s = s.replace(rgx1, "0$1");

    // 数字のみを抽出して好みの形式に置き換える
    // (注) 年,月,日,時,分,秒の順に並んでいること
    s = s.replace(rgx2, "$1" + d1+ "$2" + d1 + "$3" + d2 + "$4" + d3 + "$5" + d3 + "$6");

    return s;
}


// 以下、テストコード
var dt = new Date(2000, 0, 2, 3, 4, 5);

// まずは toLocaleString メソッドの実行結果をコンソールに出力
// [出力結果] 2000/1/2 3:04:05
console.log(dt.toLocaleString());

// [出力結果] 2000-01-02 03:04:05
console.log(datetimeFormat(dt, "-", " ", ":"))

// [出力結果] 2000/01/02_03.04.05
console.log(datetimeFormat(dt, "/", "_", "."))

// yyyyMMddHHmmss 形式に変換する
// 最後の3つの引数に空文字を指定
// [出力結果] 20000102030405
console.log(datetimeFormat(dt, "", "", ""))

// yyyyMMddHHmmss 形式に変換する
// 最後の3つの引数を省略
// [出力結果] 20000102030405
console.log(datetimeFormat(dt))
matplotlibでよく使うコマンドまとめ

IPython & matplotlib でグラフを書く時の細かい部分をよく忘れてしまうのでまとめました。
何番ぜんじだよって話ですが、ご参考になれば幸いです。

## 毎回使うモジュールのインポート
~/.ipython/profile_default/startup/の下に00_import.pyなどを作成しておくと
IPythonの起動時に自動で実行してくれる。

```py:00_import.py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import re
```
## plotで線グラフを書く
よく使うのはこんなところではないでしょうか。

```py:sample_1.py
x = np.arange(-10, 10, 0.1)
y = x**3

plt.figure(figsize=(6, 4))  # set aspect by width, height

plt.xlim(min(x), max(x))
plt.ylim(min(y), max(y))  # set range of x, y

plt.xticks(np.arange(min(x), max(x)+2, 2))
plt.yticks(np.arange(min(y), max(y)+200, 200))  # set frequency of ticks

plt.plot(x, y, color=(0, 1, 1), label='y=x**3')  # color can be set by (r, g, b) or text such as 'green'

plt.hlines(0, min(x), max(x), linestyle='dashed', linewidth=0.5)  # horizontal line
plt.vlines(0, min(y), max(y), linestyle='dashed', linewidth=0.5)  # vertical line

plt.legend(loc='upper left')  # location can be upper/lower/center/(none) and right/left/(none)
plt.title('Sample 1')
plt.show()
```
![graph_sample1.png](https://qiita-image-store.s3.amazonaws.com/0/187660/7d42845b-fa49-26f3-8b1d-20dbaa2b42d0.png)

## 第1軸と第2軸に分けて描く
これも必要なとき多いけど、毎回忘れていたので・・・。
axeオブジェクトを操作するときはplt.うんたらのときと比べて少しメソッド名が変わります（set_ が要る）
figureオブジェクトとaxeオブジェクトの関係は下のリンクがわかりやすいです。
http://ailaby.com/matplotlib_fig/

```py:sample_2.py
# just prepare data
x = np.arange(0, 10, 0.1)
y1 = np.sin(x)
y2 = x

fig, ax = plt.subplots(figsize=(5,5))  # create figure and axes object
ax.plot(x, y1, label='sin(x)', color='red')  # plot with 1st axes

ax.set_ylabel('y=sin(x)')  # set label name which will be shown outside of graph
ax.set_yticks(np.arange(-1, 1+0.2, 0.2))

ax2 = ax.twinx()  # create 2nd axes by twinx()!
ax2.set_ylabel('y=x')
ax2.plot(x, y2, label='x', color='blue')  # plot with 2nd axes

ax.set_xlim(0, 5)  # set range

ax.legend(loc='upper left')
ax2.legend(loc='upper right')
plt.title('Sample 2')
plt.show()
```
![graph_sample2.png](https://qiita-image-store.s3.amazonaws.com/0/187660/c24f06df-e811-67f1-03cb-cbcac3cc3ec1.png)

## 文字入り散布図を描く
個人的には散布図の各点に番号とかスコアをアノテーションすることが多いのでそれを入れてます。

```py:sample_3.py
pos_x = [1.0, 1.5, 2.1, 2.7, 3.0]  # x of positions
pos_y = [0.7, 0.9, 1.0, 1.3, 1.5]  # y of positions
time = [1, 2, 3, 4, 5]  # time of each positions

# draw points
plt.scatter(pos_x, pos_y, color='red', label='Position')

# annotate each points
for i, t in enumerate(time):
    msg = 't=' + str(t)
    plt.annotate(msg, (pos_x[i], pos_y[i]))  # x,y need brackets

plt.title('Sample 3')    
plt.legend(loc='upper left')
plt.show()
```
![graph_sample3.png](https://qiita-image-store.s3.amazonaws.com/0/187660/b3fa7b7c-80ac-4f36-450b-db76c167b4af.png)

おしまいです。
今後思いついたらまた追記させていただきます。それでは。
【C#】正規表現を使ってメールアドレスを抽出する

自分用。
文字列の中からメールアドレス部分を抽出する必要があったので、正規表現を使ってメールアドレス部分を抽出するメソッドを作成。

# メソッド
```csharp:メソッド
/// <summary>
/// メールアドレス取得
/// </summary>
/// <param name="str">抽出対象文字列</param>
/// <returns>一致する文字列</returns>
private string[] ExtractionMailAddress(string str)
{
    string pat = @"\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b";
    System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(pat, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    System.Text.RegularExpressions.MatchCollection matchCol = regex.Matches(str);

    List<string> result = new List<string>();

    foreach(System.Text.RegularExpressions.Match m in matchCol) {
        result.Add(m.Value);
    }

    return result.ToArray<string>();
}
```

# 解説
特段なし。
一応、自分の環境で入力される想定の文字列を複数与えてうまく検出できた。
戻り値は文字型の配列なので、文字列に複数のメールアドレスを含んでいた場合にも対応する。
当然だけど、スペースやタブ記号などを含まずに2つ以上のメールアドレスが連なっている場合などはそもそもメールアドレスとして破綻しているので検出できない。

【2017/06/28 追記】
[juner氏からご指摘頂いたとおり](http://qiita.com/PaperFace1000/items/b80d2b1e8c6f363038c4#comment-94a239e07c9e4ab8b905)、RFC5321とRFC5322に準拠していないメールアドレスも抽出してしまいます。
docomoとかauとかの一部キャリアメールが非準拠なメールアドレスが使えるようで、これを弾くかどうかという点については利用ケースで考える必要がある。

# 参考にしたサイト
[正規表現を使って文字列を検索し、抽出する: \.NET Tips: C\#, VB\.NET](http://dobon.net/vb/dotnet/string/regexmatch.html)
[正規表現サンプル\(メールアドレスを検索する\)](http://hodade.com/seiki/page.php?s_mail)

[NTTドコモ／auの連続ドット／@前ドットメールアドレスの問題 \- The blog of H\.Fujimoto](http://www.h-fj.com/blog/archives/2009/03/01-100125.php)
Visual Studio Code の設定 setting.json

なかなか面倒くさくて設定していなかった。
Visual Studio Codeのsetting.jsonを設定してみた。
メモ書き程度に残す。尖った設定はしていないため汎用的だと思われる。
自由にカスタマイズしてどうぞ～

#設定

```json:setting.json
// 既定の設定を上書きするには、このファイル内に設定を挿入します
{
    // フォントのサイズ
    "editor.fontSize": 16,
    // フォントの変更 事前にMyrica MM というプログラミングしやすい視認性の高いフォントをインストールして適用しています。
    "editor.fontFamily": "Myrica MM, Consolas, Courier New",
    // Tabを押したときスペース何個分に相当するか
    "editor.tabSize": 2,
    // 半角スペースを「・」で表す
    "editor.renderWhitespace": "all",
    // カーソルの形を変える
    "editor.cursorStyle": "line-thin",
    // 行の折り返し設定
    "editor.wordWrap": "on",
    // このファイル形式には、この言語。という関連付けの設定
    "files.associations": {
        "*.txt": "markdown",
        "*.json.txt": "json"
    },
    // プレフィックスが一致する場合、Tabを押したときにスニペットを挿入するかどうか
    "editor.tabCompletion": true,
    // 文字の間隔
    "editor.letterSpacing": 0.5,
    // 何列目に縦線を入れるか　1行何文字以内という規定がある場合に便利
    "editor.rulers": [
        80,
        100
    ],
    // 最後の行を超えてスクロールするかどうか
    "editor.scrollBeyondLastLine": false,
    // 折り返しの行を左端をどう揃えるか
    "editor.wrappingIndent": "indent",
    // 入力中に補完候補をだすかどうか　以下の設定でコメントの中でもどこでも補完候補を出せるようになる
    "editor.quickSuggestions": {
        "other": true,
        "comments": true,
        "strings": true
    },
    // 自動フォーマット
    "editor.formatOnType": true,
    // 貼り付け時に自動でフォーマットしてくれる
    "editor.formatOnPaste": true,
    // カーソルが点滅するようになる
    "editor.cursorBlinking": "expand",
    // 今いる行が強調される
    "editor.renderLineHighlight": "all",
    // 選択した部分のドラッグアンドドロップを許可するかどうか
    "editor.dragAndDrop": false,
    // ファイル保存時にフォーマットする
    "editor.formatOnSave": true,
    // ファイルを開いたときエンコードを自動で推測するかどうか
    "files.autoGuessEncoding": true,
    // 配色テーマ
    "workbench.colorTheme": "Monokai"
}
```

##あとがき
おすすめの設定などあれば教えてください:relaxed:
[rails][gretel]パンくずを構造化データにする。と、その注意。

# gretelでパンくず生成している時、構造化データにする方法。



gretel使っていれば、これだけ！

[before]

```
== breadcrumbs
```

[after]

```
== breadcrumbs semantic: true
```

# 注意
gretelのオプションで構造化データすると、
ボキャブラリーにdata-vocabularyが使われる。
問題なくスニペットが適用されるが、現在googleが推奨しているのはschema.org。
data-vocabularyは今後使えなくなるかもしれないので注意:moyai:
ただ、gretelでschema.org使おうとすると一苦労なので、
過去主流だったボキャブラリーをアナウンスなしに対応しなくなるとは思いにくい上に、
構造化データ自体、googleの検索上位になるアルゴリズムには関係ないので、
使えなくなった時に対応でいいと思います:hugging_face:
ちなみに、web担とかはdata-vocabularyを使っています。