OmniAICreator/Qiita-1.07M huggingface dataset:
イケてる報告書の書き方

以前いわゆる大きな会社で管理職をやってた頃に後輩たちへの指導のために作った資料がみつかったのですが、結構有用だと思うので（自画自賛w）、記事にしてみました。

# はじめに

みなさんは、報告書を**読む人の立場に立って**書いているでしょうか？

読んだ人に「よくわからん」と言われた場合、おそらく90%以上は**報告者に責任があります**。ダメな報告書によって、内容を誤解されて怒られ、報告者は「なにゆってんねん！」とストレスが溜まるというネガティブスパイラルに陥ります。時間も、心身もすり減りますので、そんな無駄を少しでも減らすことができれば、とても幸せではないでしょうか。

# 報告書とは

報告する相手に、読んで**理解してもらう**ためのものです。報告者が言いたいことを云うためのものではありません。

では、何を理解してもらうべきなのか？変な言い方ですが、それは**報告する相手が知っておくべきこと**です。堂々巡りですね。もうちょっと噛み砕くと、報告する相手が**何のためにその報告を必要としているか**を報告者が理解して、対処する必要があります。

つまり、報告する**相手に応じて**内容、記述レベルを変更する必要があります。

# いい報告書とは
記載されている内容について、**客観的事実**と、**主観・推測**がはっきり**区別**できなければなりません。まあこれは、報告書の必須条件ですが、、

そして、話の**趣旨**が**すぐに分かる**ことが重要です。話の趣旨というのは、トピック（何の案件のどういう事項について）と、それにまつわる何らかの結果のセットのことです。読む側の立場に立つと、これが分からなかったら「何が言いたいねん！」とか「だからなんやねん！」と腹が立ちますよね。

知りたいことが**過不足なく**書かれていることも大事です。知りたいこととは、その報告の利用用途に合う情報です。無意味に長い報告書はダメです。

わかりやすさに直結しますが、**用語が統一**されていなければなりません。つまり、同じ概念を複数の言葉で表現してはいけません。

ダメな報告書はこれらの裏返しです。

## 「知りたいこと」はどのように表現されているべきか
案件や利用目的によってバリエーションはありますが、多くの場合、以下の構成になっているといいと思います。

* 結論
 - 行った取り組みとその結果
 - 「いつ」のことなのか
 - 客観的事実（誰の発言なのか、誰の考えなのか）
* 課題
* なぜその取り組みを行ったのか
  - 行った取り組みの内容の詳細
* （もしあれば）将来の展望、考察、推測（スケジュールなども含む）

# 知ってもらう必要の「ない」こと
多くの場合、以下の点は主要な要素にはなり得ません。

* どんな苦労をしたか
  - 細かい手続き的なこと(手続きそのものが重要な時はもちろん必須)
* 報告者自身の身の上話
  - 能力やバックグラウンド

もしどうしても入れたいなら、他と区別して最後に入れましょう。途中に入れてしまって訳が分からなくなると、心証を悪くするだけです。

# 報告書を「うまく」使う

主観や推測を入れてはいけないというわけではありません。入れるなら効果的に入れましょう。もちろん入れるのは**他と区別できる場所**です。

では、何のために主観や推測を入れるのか？それは、**報告する相手にうまく動いてもらうため**です。その狙い(戦略)がないなら入れない方がいいです。絶対に。

# チェックポイント
* 以下のような構成になっていますか？
 - 結論
     * 行った取り組みとその結果
     * 「いつ」のことなのか
     * 客観的事実（誰の発言なのか、誰の考えなのか）
 - 課題
 - なぜその取り組みを行ったのか
     * 行った取り組みの内容
 - (もしあれば)将来の展望、考察、推測
* 客観的事実と主観・推測は別々の段落に書かれていますか？
 - 主観・推測を書くなら最後の付け足しです
* だらだら長くなっていませんか？
 - もっと短くできるはず、と思って見返してください。
* 用語は統一されていますか？

# 心構え
当たり前のことばかり書いてるだけなのですが、いい報告書だなー、と思うものに出会うのは稀です。誰にでもわかる報告書がもちろんベストですが、特定の相手（報告する相手）がわかる報告書であれば十分です。そこを意識するだけでも、結構レベルアップすると思います。

うまくかけている報告書だと、それを読んだ人から来るコメントが建設的だったり、報告者自身が腑に落ちていないことなどを突っ込まれることが多くなります。（何のコメントも質問もないというのは、ちゃんと読んでくれてない可能性があります）また、自分が書いた報告書がほぼそのまま転記されて、更に上層への報告書になることが多くなります。

報告に意味があるかよく分からないことが多いのは確かです。でも、適当に書いてその報告書を読む人の時間を奪っていいという話ではありません。

報告書はこの世からなくなりません。うまく書けるようになれば、自分も周りもhappyになれます。だから、しっかり練習しましょう！
MyBatisネタ

# MyBatisネタ

例によってざっくり備忘録メモ

## Springと連携させている時の注意点

DBの接続先はMapperScanがBeanをDIコンテナに登録した時の、データソースの設定が使用される。
＠TransactionalのtransactionManagerを切り替えても、切り替えたtransactionManagerで設定されているデータソースのDBに接続しに行くわけではないので注意

まったく同じテーブル構成で、DBの接続先だけが違うようなケース（データソースを2つ用意してそれぞれに個別でアクセスしたい場合）では、
データソース１用のMapperScanと、データソース２用のMapperScanを両方用意し、データソースの片方は、sessionFactoryRefとnameGeneratorを別で指定する必要あり。
※そもそもやり方間違ってる可能性もあるけど。。

nameGeneratorは、生成されるBean名が被らないようにするために必要。
※HogeMapper.java に対してのBeanが生成される際に、何も指定しないと、データソース１用も２用もhogeMapperというBean名で生成しようとするため、名前被りで落ちる。

DIする時（Autowiredする時）もBean名を指定すること。

## MyBatis を利用した web application 開発についてのご紹介
https://www.slideshare.net/tokuhirom/mybatis-web-application


## eclipse plugin
eclipseマーケットプレイス > Mybatipse
xml書く時に補完が効くようになるので、ほぼ必須

## 分かりやすい使い方
エンティティクラスにリレーになるエンティティのプロパティを定義して、マッピングさせると幾らか感覚的になる。。？
※GitHubのTest1のtest2プロパティ参照。同様にTest1Mapper.xml の selectTest1Test2c も参照


##  別xmlに記述した定義(resultMap等)を呼び出す
http://kamatama41.hatenablog.com/entry/20130409/1365483365


## 自動生成
Enum対応はColumnOverride使う
http://blog.zaq.ne.jp/oboe2uran/article/1180/
http://tech-blog.tsukaby.com/archives/205

※GitHubのmyBaitsGeneratorConfig.xml参照


pluginを使用する場合は、generatorConfig.xml 右クリック>  実行の構成 > クラスパス > プロジェクトの追加 > でPluginクラスのプロジェクトを追加する

出力javaファイルの文字コードの指定は

```
<context>
    <property name="javaFileEncoding" value="UTF-8" />
～
</context>
```

## 自動生成されたエンティティのフィールドをprotectedにする
サンプルコードの FieldVisibilityProtectedPlugin.java と myBaitsGeneratorConfig.xml 参照
※自前のpluginを作り（FieldVisibilityProtectedPlugin）、自動実行のpluginとして呼び出す（myBaitsGeneratorConfig.xml の pluginタグ）


## LocalDateTime用のTypeHandler
https://github.com/javaplugs/mybatis-types

※mybatis-config.xml参照
※https://github.com/javaplugs/mybatis-types から必要なタイプハンドラのソースを自プロジェクトにコピーし、xmlのtypehandlerのパスに通す


## cacheを切る
http://www.mybatis.org/mybatis-3/ja/configuration.html
のsettingsのcacheEnabled

デフォルトだとcacheが効いているため、1トランザクション？（細かい単位は忘れた）の中で1度実行させているクエリをもう一度投げてもDBまでいかない。

※参考 キャッシュの設定としてはlocalCacheScopeもある


## MyBatisGeneratorがjavaファイルを上書きしてくれない（上書き設定にすると、＠mbggenerated以外のコードを消してしまう）
eclipseのプラグインを入れ、それを使うと上書きが上手いこといく。
※javaファイルのマージ機能が使えるのが、eclipseプラグインだけらしい。。(1.3.1時点)
http://blogj.harawata.net/2012/05/mybatis-generator.html
http://intink.blogspot.jp/2012/11/mybatisibatismybatis-generator.html

pluginの場所は下記参照
http://www.mybatis.org/generator/running/runningWithEclipse.html


## MyBatis で生SQLを叩きたい
http://qiita.com/kumazo@github/items/72ecdb2923b77aaa0c94


## [Java]MyBatisの動的SQLでパフォーマンスを改善する
http://atuweb.net/201602_java-mybatis-dynamic-and-fast-sql/
VSCodeでnRF52840環境のインクルードパスを通す

VSCodeでnRF52840環境を快適に使うためにインクルードパスを通します。

nRF52環境 : nRF5_SDK_15.2.0_9412b96

# 結論：gistを参考にc_cpp_properties.jsonへコピペすればOK

gist参考にincludePath, browse, definesあたりをコピペしてみてください。

https://gist.github.com/ksksue/ecebba6beed80a74bed5a4fdb77600aa

以下、**c_cpp_properties.jsonって何？**って人向け詳細

# VSCodeでディレクトリを開いてプロジェクト開始

例えば、以下のディレクトリをVSCodeで開きます。

```
nRF5_SDK_15.2.0_9412b96/examples/ble_peripheral/ble_app_hids_keyboard
```

<img width="1406" alt="スクリーンショット 2018-10-11 1.08.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/11626/3176af76-f613-443e-3650-d2eea0e4dc7b.png">


# デフォルトでは「定義へ移動」ができない

すると、インクルードパスが指定されていないため include errors detected となります。

<img width="751" alt="スクリーンショット 2018-10-11 0.52.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/11626/953cd512-f014-6060-4bfe-bc6ccc912799.png">

ボクがよく使う「定義へ移動」などの操作ができません。
解決するためにインクルードパスの設定をしていきます。

# c_cpp_properties.json の includePath 要素を編集

インクルードパスを設定するには .vscode/c_cpp_properties.json を編集します。
c_cpp_properties.json は画面右下ポップアップのConfigurationHelpなどをクリックすると**自動生成**されます。
ファイルを開くとincludePathの要素があるのでここにパスを羅列していきます。

例

```json
    "configurations": [{
        "name": "Mac",
        "includePath": [
            "/path/to/arm-none-eabi/include",
            ...
        ],
        ...
```

ただ、nRF52環境はディレクトリ毎にインクルードパスを指定しなければならないので**かなりの量のインクルードパス**があります。
ということで、gistにまとめました。

https://gist.github.com/ksksue/ecebba6beed80a74bed5a4fdb77600aa

gist内のenv要素は自身の環境に合わせてください。

```json
    "env": {
        "gccArmPath": "/usr/local/gcc-arm-none-eabi-6-2017-q2-update",
        "nrf5SdkPath": "~/Documents/Nordic/nRF5_SDK_15.2.0_9412b96"
    },
```


# その他
- インクルードパスはexample内にあるMakefileを参考にしています
- 参照エラーを少なくするためにdefinesの値がかなり多くなってます。こちら参考。
VS Code c_cpp_properties.json example for arm-none-eabi toochain
https://gist.github.com/kbumsik/52ce3f41a62f2485c3da1a585674e550

- 上記gistの c_cpp_properties.json でも **uint8_t など一部参照エラーが取り除けていません**

# 参考URL

USING VISUAL STUDIO CODE FOR NORDIC NRF5 BLE DEBUGGING
https://electronut.in/vscode-nrf52-dev/

VS Code c_cpp_properties.json example for arm-none-eabi toochain
https://gist.github.com/kbumsik/52ce3f41a62f2485c3da1a585674e550
datetimeで定義される「先発グレゴリオ暦」について

他記事（[日付→西暦0年からの総日数や総時間数への変換](https://qiita.com/HidKamiya/items/dc61d8d0de19c4d402e9#comment-206c95856f47c1510989)）にて西暦0年からの日数計算を取り上げた際，暦に関するご指摘をうけたため本記事を作成．

簡単にまとめると．．．

- Julian暦（旧暦）・・・400年間に100回の閏年
- Gregorian暦（新暦）・・・400年間に97回の閏年．ルールは下記のとおり．
 - 4n年は閏年
 - 例外１：100n年は平年
 - 例外２：400n年は閏年
- 改暦（主に10日ほどの太陽暦ずれ修正）時期やルールは地域によって異なる．

python（および自然科学系数値計算業界？）では，Gregorian暦を時間軸全域に反映させた理想的な暦（先発グレゴリオ暦）を仮定する．（[datetimeモジュールに関する公式ドキュメント](https://docs.python.jp/3/library/datetime.html)より引用）．
> 
date オブジェクトは日付 (年、月、および日) を表します。日付は理想的なカレンダー、すなわち現在のグレゴリオ暦を過去と未来の両方向に無限に延長したもので表されます。 1 年の 1 月 1 日は日番号 1, 1 年 1 月 2 日は日番号 2,となっていきます。この暦法は、全ての計算における基本カレンダーである、 Dershowitz と Reingold の書籍 Calendrical Calculations における先発グレゴリオ暦 (proleptic Gregorian) の定義に一致します。

試しに閏年の確認

```py:leap_year.py
ystart=1
yend=2018
for y in range(ystart,yend):
     t1 = datetime.datetime(y,1,1,0,0)
     t2 = datetime.datetime(y+1,1,1,0,0)
     if (t2-t1).days != 365:
         print (t2-t1).days
         ylist.append(y)
```

結果（ylist）は以下の通り．
[4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48,
 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, **96, 104**,
 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148,
 152, 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, **196, 204**,
 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248,
 252, 256, 260, 264, 268, 272, 276, 280, 284, 288, 292, **296, 304**,
 308, 312, 316, 320, 324, 328, 332, 336, 340, 344, 348,
 352, 356, 360, 364, 368, 372, 376, 380, 384, 388, 392, **396, 400, 404**,
 408, 412, 416, 420, 424, 428, 432, 436, 440, 444, 448,
 452, 456, 460, 464, 468, 472, 476, 480, 484, 488, 492, **496, 504**,
 508, 512, 516, 520, 524, 528, 532, 536, 540, 544, 548,
 552, 556, 560, 564, 568, 572, 576, 580, 584, 588, 592, **596, 604**,
 608, 612, 616, 620, 624, 628, 632, 636, 640, 644, 648,
 652, 656, 660, 664, 668, 672, 676, 680, 684, 688, 692, **696, 704**,
 708, 712, 716, 720, 724, 728, 732, 736, 740, 744, 748,
 752, 756, 760, 764, 768, 772, 776, 780, 784, 788, 792, **796, 800, 804**,
 808, 812, 816, 820, 824, 828, 832, 836, 840, 844, 848,
 852, 856, 860, 864, 868, 872, 876, 880, 884, 888, 892, **896, 904**,
   :   :   :
 1852, 1856, 1860, 1864, 1868, 1872, 1876, 1880, 1884, 1888, 1892, **1896, 1904**,
 1908, 1912, 1916, 1920, 1924, 1928, 1932, 1936, 1940, 1944, 1948,
 1952, 1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992, **1996, 2000, 2004**,
 2008, 2012, 2016]

ということで，Gregorian暦のルールが西暦元年から適用されていることを確認できた．
QiitaにGoogleAnalyticsの設定する。数字を眺めて楽しい

# はじめに
自分のマイページに[GoogleAnalytics](https://developers.google.com/analytics/?hl=ja)を設定して2週間が経過しました。
数字を見て楽しかったので記事に。

# GoogleAnalyticsをQiitaに設定すると
- リアルタイムの状況がわかる
- ユーザーの属性がわかる
- ユーザーがどこから来たかわかる
- ユーザーの動きがわかる
- Webサイトの成果がわかる

# つまり、自分(の記事)のことがもっとわかって楽しい
Qiitaの機能でも日々「View数」が増えたり、「いいね」が増えたりと情報はあります。
私にとってこの情報は次の記事を書くためのモチベーションです。
これがもっと他の情報が手に入ると自分の記事に対して振り返る事が増え、よりモチベーション向上に繋がりました。

# [設定方法(5分以内で完了)](https://qiita.com/Qiita/items/c7f704e3786df3aa7a11)

![2018-10-11_00h28_34.png](https://qiita-image-store.s3.amazonaws.com/0/216527/990b5eb4-a300-68f7-c2d1-10524dde7446.png)
![2018-10-11_00h29_31.png](https://qiita-image-store.s3.amazonaws.com/0/216527/42217c20-d7af-3ab8-d81a-beb9060b358a.png)

# 私のGoogleAnalytics画面

2週間投稿せず静観しました。(特に面白いと思った箇所を数個抜粋)

- 平日の午後にアクセスが多いようです。技術記事を職場で閲覧して頂けているのでしょうか。

![2018-10-11_00h41_35.png](https://qiita-image-store.s3.amazonaws.com/0/216527/ed61fe5b-918d-143d-f6cd-0127da3e09b6.png)

- PCからアクセスが圧倒的。職場から？の予測あたってるかも？

![image.png](https://qiita-image-store.s3.amazonaws.com/0/216527/30c71e52-0e34-95e0-5577-3fe3bf78f49f.png)

- 日本語で記事を書いていますが、海外からもアクセスがある事にビックリ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/216527/6bb24d44-f627-39de-ed1b-582a327730b4.png)

- 日本では想像通り都内が多い比率に。Minatoが多い理由はなんなのでしょうか。

![2018-10-11_00h53_22.png](https://qiita-image-store.s3.amazonaws.com/0/216527/39ab52f1-7aeb-81e9-9119-d6779734eb7f.png)



- 自分の「いいね」が一番多い記事にアクセスが集中していました。これを超えれるようになりたいです。


![2018-10-11_00h56_59.png](https://qiita-image-store.s3.amazonaws.com/0/216527/4717ffbd-0810-4a2b-1419-98cc52a4a436.png)

# さいごに
 
繰り返しになりますが5分以内で設定は完了します。
とっても簡単なので、まずは設定して使ってみる事をオススメします。使ってみて私は楽しめました。
カスタム機能やAPIなど、使い込んで行けばもっと楽しい世界が待っているかもしれません。
MacのMicrosoft Office製品でEmacsライクなキーバインドを実現する

# 問題点
普段Microsoft Officeをあまり使わないのですが、所属している研究室の指示でスライドだけはPowerPointを利用して作成しています。Microsoft Office製品はMacのEmacsライクなキーバインド(<kbd><kbd>Ctrl</kbd>+<kbd>f</kbd></kbd>とか<kbd><kbd>Ctrl</kbd>+<kbd>h</kbd></kbd>とか)に独自のショートカットが上書きされており、僕のようにEmacsライクなキーバインドに慣れている人にとっては非常にストレスフルです。ほとんどOffice製品を使わない僕にとって、重要度は「慣れ親しんだキーバインド」>>>「Officeのショートカット」だったのでショートカットを犠牲にしてEmacsライクなキーバインドを取り戻すことにしました。

# 解決策
Karabiner-Elementsというアプリを使ってOffice製品でもEmacsライクなキーバインド実現します。

### 1． Karabiner-Elementsのダウンロード
[ここ](https://pqrs.org/osx/karabiner/)からKarabiner-Elementsをダウンロードします。

### 2. Emacs key bindingsのimport
```Complex Modifications```→```Add rule```→```Import more rules from the Internet (open a web browser)```の順に選択するとブラウザにimport可能なruleの一覧が出るので、Emacs key bindings(執筆時点でrev12)をimportします。

### 3. ruleを適用
Emacs key bindingsの中にはEmacsライクなキーバインドを実現するためのruleがいくつか入っていますので、好みのものを選んで```Enable```を押すと選んだruleが適用されます。僕はとりあえずPowerPoint内でのカーソル移動が快適にできればよかったのでEmacs key bindings [control+key]のみ適用しました。これで無事Office製品でもEmacsライクなキーバインドが使えるようになります。

# おわりに
Karabiner-Elementsはキーバインドをかなり自由にカスタマイズにできるアプリなので、今回の件に限らずいろいろといじってみると面白いと思います。
Angular Materialのsidenavをコンポーネントとして実装する

# この記事で書くこと
Angular MaterialのsidenavをAngularプロジェクトに実装する方法を説明します。

## Angular Material, Angular CDKのインストール
**既にAngularプロジェクトを作成されていると仮定して話を進めます。**
プロジェクトフォルダにて以下のコマンドを入力してインストールを実行します。

```
npm install --save @angular/material @angular/cdk
```

### Angular Materialをプロジェクトに追加させる
以下のコマンドを続けて入力して、プロジェクトにAngular Materialライブラリを追加します。

```
ng add @angular/material
```
このコマンドを実行することで、Angular Materialライブラリの依存関係をプロジェクトに追加してくれます。

## sidenavコンポーネントの実装

### コンポーネントの生成

以下のコマンドを実行することで、Angular Materialのsidenavをコンポーネントとして生成して追加します。

```
ng generate @angular/material:material-nav --name=test-sidenav
```

`test-sidenav`の部分はコンポーネントの名前なので、好きな名前にしてください。
`ng generate @angular/material:material-nav`は、[Angular 6から実行できるようになりました](https://blog.angular.io/version-6-of-angular-now-available-cc56b0efa7a4)。

### コンポーネントの埋め込み
コンポーネントを作成したらHTMLにコンポーネントを埋め込みます。

```(例)app.component.html
<app-test-sidenav></app-test-sidenav>
```

上記を埋め込んで試しに`ng serve`を行いローカル環境で確認すると、このようなバーが表示されます。
![sample.PNG](https://qiita-image-store.s3.amazonaws.com/0/300336/fc5e8228-47d7-0414-6ae6-380f2c2a455b.png)

デフォルトでレスポンシブデザインとなっているので、PCディスプレイ等の横幅の大きな画面では以下のようになります。
![sample2.PNG](https://qiita-image-store.s3.amazonaws.com/0/300336/af36c7b3-f22b-16e4-1bfc-10c43ed91fc7.png)


## テーマの読み込み
Angular Materialが用意しているテンプレートを使用することが出来ます。
使用するには、`style.css`に以下の一行を追加します。

```style.css
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
```
テンプレートは以下の4種類あり、好きなものを選ぶ事が出来ます。

- `deeppurple-amber.css`
- `indigo-pink.css`
- `pink-bluegrey.css`
- `purple-green.css`

# 参考文献
- [Angular Material - Get started](https://material.angular.io/guide/getting-started)
raspberry pi のwifiを無効化する方法

#無効化する理由
wifi使わない(有線やCandy pi liteを使うとき)
無駄に電流が流れる(0.02Aくらい)

##Wifi無効化
以下のコマンドを実行して、ラズパイを再起動すればwifiを無効化できます
`sudo iwconfig wlan0 txpower off`

##Wifi有効化
再び有効化したいときは以下のコマンドを実行して再起動
`sudo iwconfig wlan0 txpower auto`
pythonでの文字列の扱い

#　はじめに
pythonの基礎として、文字列の扱いについて記載します。

#　環境
python3.6
anaconda1.8.2
macOS

#　やってみる

- シングルクォーテーション（一重引用符）: '
- ダブルクォーテーション（二重引用符）: "
- トリプルクォーテーション（三重引用符）: ''', """


###　シングルクォーテーションとダブルクォーテーション

```python
>>> "hello"
'hello'

>>> 'hello'
'hello'

#同じ文字列だということがわかる
>>> a = "hello"
>>> b = 'hello'
>>> a == b
True
```

以下のコードは大丈夫

```python
>>> "he said 'hello'" 
"he said 'hello'"
```
ダブルクォーテーションの中でダブルクォーテーションを使うとエラーがでる。

```python
>>> "he said "hello""
  File "<stdin>", line 1
    "he said "hello""
                  ^
SyntaxError: invalid syntax
```
バックスラッシュ(winなら¥)でエスケープするとエラーが消える

```python
>>> "he said \"hello\""
'he said "hello"'
```

さらに以下も同様にエラーが発生してしまう

```python:
>>> 'this isn't my apple'
  File "<stdin>", line 1
    'this isn't my apple'
              ^
SyntaxError: invalid syntax
```
同様にバックスラッシュ(winなら¥)でエスケープできる

```python
>>> 'this isn\'t my apple'
"this isn't my apple"
```

print関数を使うと、クォーテーションを落として表示してくれる

```python
>>> print('this isn\'t my apple')
this isn't my apple
```
もしそのままバックスラッシュ等を表示させたい場合はクォーテーション前にrをつける。


```python
>>> print(r'this isn\'t my apple')
this isn\'t my apple
```
\nで改行ができる

```python
>>> print("abc\ncde")
abc
cde
```
### 　トリプルクォーテーション
トリプルクォーテーションの場合は改行が反映される

```python
>>> print('''abc
... cde
... efg
... ghi''')
abc
cde
efg
ghi
```

改行させない場合にはバックスラッシュを末尾につける

```python
print('''abc\
... cde\
... efg\
... ghi''')
abccdeefgghi
```

###　文字の連結と計算

文字列は「+」で連結でき、文字列同士は半角スペースで連結できる

```python
>>> "hello"+"world"
'helloworld'

>>> "hello" "world"
'helloworld'

#「＋」を使えば変数を使っていてもOK
>>> a = "hello"
>>> a + "world"
'helloworld'

#半角スペースはあくまでリテラル同士
>>> a "world"
  File "<stdin>", line 1
    a "world"
            ^
SyntaxError: invalid syntax

```

### 　インデックスの指定をして文字の取得

その前に文字数を取得

```python
>>> word = "helloWorld"
>>> len(word)
10
```
インデックス指定

```python
>>> word = "helloWorld"
>>> word[1]
'e'
>>> word[7]
'r'
>>> word[-3]
'r'
>>> word[0:5]
'hello'
>>> word[3:]
'loWorld'
>>> word[:3]+word[3:]
'helloWorld'
```
当然、文字数より大きいものをインデックス指定するとエラーが出ます。

```python
>>> word[100]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: string index out of range
>>> word[:100]
'helloWorld'
```
でもレンジとして指定する場合はエラーが出ません

```python
>>> word[:100]
'helloWorld'
```
文字列は変更できません。

```python
>>> word[:5]="goodmornig"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
```
変更ではなく、別に文字列を作成する必要があリます。

```python
>>> "goodmornig"+word[5:]
'goodmornigWorld'
```

#　おわり
AWSのSESのDNS設定を、ValueDomainにて行った記録

#AWSのSESを、Value-DomainでDNS設定
AWS(Amazon Web Service)のSES(Simple Email Service)は非常にスケーラブルで便利なメール発信サービスですが、
Value-DomainにてDNS設定した際、設定に難航したので、同様の方に向けてメモを残します。
特にDKIMやSPF,MAIL FROM設定でハマったので、その記録です。

SES公式マニュアルがあるので、基本的な進行はこちらでの確認をお勧めします。
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/Welcome.html

##最初にサンドボックス外へ出られるようリクエスト
これは、Value-domainの話ではないのですが、
最初に「サンドボックス」から出られるよう申請する必要がありました。
以下の手順通りに進めば問題ないはずですが、私は読み飛ばしました（汗
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/quick-start.html

サンドボックスから出ないと、任意のアドレスに送信できません。
しばし私ははまりましたので、念のため。

DNS設定の他、いろいろ手間がかかりましたが、そこは他にたくさん良記事があるので割愛します。

##成功した記載法（DNS設定）
まずは、結果的に全てverifiedになったValue-DomainでのSES設定を記載します。

```
txt _amazonses.example.com hogefugafoobaa=
cname cname1txt._domainkey cname1txt.dkim.amazonses.com.
cname cname2txt._domainkey cname2txt.dkim.amazonses.com.
cname cname3txt._domainkey cname3txt.dkim.amazonses.com.
mx feedback-smtp.us-west-2.amazonses.com. 10 ses 
txt ses v=spf1 include:amazonses.com ~all
```

この中で特に、私はcnameの設定と、mxレコードの設定ではまりました。

以下の部分はほぼそのままなのですんなりいけました。

```
txt _amazonses.example.com hogefugafoobaa=
```
これ以外の部分を以下、記載してゆきます。

##Value-DomainにおけるSESのDKIM,cname設定
3つのcnameを設定する必要がありました。
(設定は、左ペインの「Domains>domain-name」の下の「DKIM」にあります)

cnameの記述方法は、

```
cname cname1txt._domainkey cname1txt.dkim.amazonses.com.　("cname1txt"は上記ページに記載されている値)
```
というものでした。

cnameの後に、_domainkeyまで書き、その後に自ドメイン名の記載は必要なしでした。
その次は、DKIMの設定欄に書かれている通りの「cname1txt.dkim.amazonses.com.」といったものを記載し、
最後に「.(ピリオド)」を打つのが必要でした。

これを、3つ分記載してverifiedに。

##Value-DomainにおけるSESのmxレコード設定
mxレコード設定も私はverifiedが出るまで試行錯誤してしまいました。

最終的に以下のような形にして、verifiedとなりました。

```
mx feedback-smtp.us-west-2.amazonses.com. 10 ses 
```
mxの後に、「feedback-smtp.us-west-2.amazonses.com.」を、最後にピリオド付きで。
（リージョンによって、ここのアドレスは異なるはずです）
半角を開けて、優先順位の数字を記載し、
また半角を開けて、利用するサブドメイン名を記載（ここでは「ses」）。

これで通りました。

以下のページにヒントがありました。
http://perl.no-tubo.net/2011/01/31/dnsのmxレコードでハマる%E3%80%82valuedomain編/


##SPF設定
SPFの設定は、以下のように記載しました。(これはほぼそのままでした)

```
txt ses v=spf1 include:amazonses.com ~all
```
（ただ、試しに送信したメールのヘッダーソースを見ると、
sender-id=softfail
とあり微妙ですが、まだ私は改善方法をわかっていません。）

##最後に、Email AddressesでMAIL FROM Domainを設定
上記までの設定をDomainに対して行うと、私のSES管理画面では、すべてverifiedとなりました。
（verifiedにたどり着くまで、結構苦労しました）

そして最後に、SES管理画面左ペインのDomainsの下の、Email Addressesの画面に行き、
「MAIL FROM Domain」設定欄で、先にDomain設定にて設定したサブドメインを入力して、無事そこもverifiedとなりました。

##終わりに
DNS設定は、これまで曖昧に記載していたところがあったので、
これを機会にいろいろ勉強し、理解が深まりました。

この記事もどなたかの参考になれば幸いです。
OracleとSQL Serverの相違点についての備忘録

簡単なメモ書き

①Oracle
・テーブル名のエイリアス利用時にAS使用不可
→ハマりました。気をつけましょう。
・読込時、空文字とnullを区別しない。どちらもnull扱い。
→SQL Serverでは区別されます。


②SQL Server
・プロシージャでselectの結果を返せる(注1)
・truncateをロールバック可能
→それぞれSQL Server特有。MS製品はお金かけてるだけあって便利ですね
(注1)コメントいただきました。
Oracleでも12cよりselectの結果返せるそうです。


他にもあればご教授くださいませ
Unityの便利機能を使いこなそう #2 CharacterControllerでプレイヤーの移動とジャンプを実装しよう

![6](http://getabakoclub.com/wp-content/uploads/2018/10/6.png)

Webページ開設しましたので[こちら](http://getabakoclub.com/2018/10/10/unity%E3%81%AE%E4%BE%BF%E5%88%A9%E6%A9%9F%E8%83%BD%E3%82%92%E4%BD%BF%E3%81%84%E3%81%93%E3%81%AA%E3%81%9D%E3%81%86-2-charactercontroller%E3%81%A7%E3%83%97%E3%83%AC%E3%82%A4%E3%83%A4%E3%83%BC%E3%81%AE/)でご覧下さい
お手数おかけして申し訳ございません
電子部品店舗リスト（秋葉原）

## 電子部品店舗リスト（秋葉原）

秋葉原の中央通りのセガ店裏に大体集結しています。

# 千石電商（せんごくでんしょう）
![IMG_6552.JPG](https://qiita-image-store.s3.amazonaws.com/0/299088/5bcf5b0e-6abc-ea39-cd97-4d2d1af4d3fc.jpeg)
電子部品取扱店舗

# 秋月電子（あきづきでんし）
![IMG_6553.JPG](https://qiita-image-store.s3.amazonaws.com/0/299088/b742c064-e611-9477-3268-bcb70a7f8b5d.jpeg)
電子部品取扱店舗

# マルツパーツ　本店
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3239393038382f31613165626532382d333965342d646132392d636135622d3366613931353131366332302e6a706567.jpg](https://qiita-image-store.s3.amazonaws.com/0/299088/c2732d5f-2d1b-fc15-0cce-3ba78830d5f3.jpeg)

電子部品取扱店舗
# マルツパーツ 支店
![IMG_6555.JPG](https://qiita-image-store.s3.amazonaws.com/0/299088/9a1da3c3-ef7a-fd81-172f-a9b8978004c9.jpeg)
電子部品取扱店舗

# 西川電子部品　ネジ
![IMG_6560.JPG](https://qiita-image-store.s3.amazonaws.com/0/299088/a284bd09-0597-ffbe-7639-e56c4e7f6521.jpeg)
ネジ専門取扱店舗

# （有）エスエス無線
ラジオデパートの２Fにあります。
![IMG_6567.JPG](https://qiita-image-store.s3.amazonaws.com/0/299088/9d6d7bb1-0718-abce-d20e-9ffae5eb3bb4.jpeg)
![mst013.jpg](https://qiita-image-store.s3.amazonaws.com/0/299088/ded7b2e1-bd2e-a6ea-4ad3-b96001c13863.jpeg)
ケース専門取扱店舗

# aitendo
ビルの３Fにあります。
※こちらの店舗は離れたところにあります。
http://www.aitendo.com/page/31
![IMG_6592.JPG](https://qiita-image-store.s3.amazonaws.com/0/299088/ad8fdf90-04ea-e153-9ddd-2f0abef40c0a.jpeg)
モジュールパーツ取扱店舗
機械学習初学者向け　参考書の学習順序　高卒、文系含む

#概要
機械学習はじめたいけど何の本をやればよいか、という質問を未だに受けることがあるのでここに書いておきます。
高卒程度を対象として含むので理系大学一年生程度の数学的基礎ができている人は該当部読み飛ばしてください。

#数学的準備
以下の本は並列して学ぶことができます。順序はなんでもいいです。

[![416Y67BQBPL.jpg](https://qiita-image-store.s3.amazonaws.com/0/175440/38f52f5b-1ea3-c0bc-99e7-975a4693c5c2.jpeg)](https://amzn.to/2C7xqaD)
微分積分―理工系の基礎 　石原 繁  (著), 浅野 重初  (著)
　微分、積分まで

[![415Q+7Pj6UL.jpg](https://qiita-image-store.s3.amazonaws.com/0/175440/ba96438c-ef61-98bd-9eaf-25f0e872ef51.jpeg)](https://amzn.to/2C6umvn)
[![41CXuUWNQBL.jpg](https://qiita-image-store.s3.amazonaws.com/0/175440/bed9e1fd-4154-9748-677d-29bb7491bfc7.jpeg)](https://amzn.to/2C5GsoG)
マセマ　線形代数1,2
　工学的にとりあえず線形代数を解けるようにする本です。

[![419COfyU7BL.jpg](https://qiita-image-store.s3.amazonaws.com/0/175440/94f19015-8767-2510-e21e-14323676bb57.jpeg)](https://amzn.to/2yrDjfr)
線型代数学―基礎課程 　永井 治 (著), 佐藤 正次 (編さん)
　マセマより詳しい線形代数の解説が知りたい時はこちら。

[![4194F6S3M7L.jpg](https://qiita-image-store.s3.amazonaws.com/0/175440/ce2bb584-c0d0-7f68-9456-d5e615883a37.jpeg)](https://amzn.to/2QHjDvn)
ベクトル解析入門　小林 亮  (著), 高橋 大輔  (著)
　ベクトル解析の記号と演算規則まで。複雑な定理はほぼ使うことはないと思います。


#最適化問題
[![41Pr7ATl6FL.jpg](https://qiita-image-store.s3.amazonaws.com/0/175440/e424a91a-7030-e6b9-05a4-0d2ccd011f9b.jpeg)](https://amzn.to/2QDRllB)
これなら分かる最適化数学　金谷健一
　勾配法、最小二乗法など最適化問題の基本が理解できます。
　画像をベクトルと見なして固有ベクトルを求める固有顔の解説なんかもあります。数理工学の本です。

#計測工学
[![51ZChLwwxML.jpg](https://qiita-image-store.s3.amazonaws.com/0/175440/0b8abcf2-082c-1246-972b-0995a71d8fa1.jpeg)](https://amzn.to/2QHmEvQ)
計測工学　鈴木 亮輔 
　数理工学を学ぶなら測定については概論として知っておくべきです。誤差とは何か、誤差の伝搬など。誤差についてわかっていないと数理工学の目指すところの理解が浅くなります。


#機械学習
[![41j86wF23xL.jpg](https://qiita-image-store.s3.amazonaws.com/0/175440/efd95445-2887-8337-8987-08b2dbf5ffe5.jpeg)](https://amzn.to/2NA0Q3p)
深層学習　岡谷 貴之  (著)
　ニューラルネットの基本的なことが書いてあります。

[![51-OLhh9n+L.jpg](https://qiita-image-store.s3.amazonaws.com/0/175440/1ed223fa-bba3-6b75-195b-9bbddd164c81.jpeg)](https://amzn.to/2ytmDnD)
深層学習 Deep Learning  監修:人工知能学会
　ニューラルネットの中級者向けの内容。resnet発表以前くらいの情報でまとまっています。

[![41O0QFyTHJL.jpg](https://qiita-image-store.s3.amazonaws.com/0/175440/5d701544-aa6f-7c18-7403-53a82bcb2e2b.jpeg)](https://amzn.to/2QK1RIb)
[![418MuoJetFL.jpg](https://qiita-image-store.s3.amazonaws.com/0/175440/94145237-e40a-5792-38dc-337c18d5c1d2.jpeg)](https://amzn.to/2yvID1h)
PRML 上 下 パターン認識と機械学習
　機械学習アルゴリズムを辞典的に解説している本。かなり古いので現在はまったく使われなくなった技術も多いですが一応。

#追記
機械学習の書籍はいささか古い内容もかなり含んでしまいました。ごく工学的な技術というものは、進歩するとまったく顧みられなくなるものは多々あります。しかし、比較的理学的な知見というものは、将来的にも役に立ち続けるものです。できるだけそういった普遍性のある知識を身につけていきましょう。

統計学については機械学習向けの良書がちょっと思い当たりませんでした。
統計学、及び機械学習に関連する良書がありましたら教えてください。
Unityの便利機能を使いこなそう #1 Terrainでステージを作ろう

![15](http://getabakoclub.com/wp-content/uploads/2018/09/15.png)
Webページ開設しましたので[こちら](http://getabakoclub.com/2018/09/21/unityの便利機能を使いこなそう-1-terrain-skyboxでステージを作/)でご覧下さい
お手数おかけして申し訳ございません
「ゴミ記事は書くな」はゴミ記事を増やすことにつながるから避けるべきでは？

最近、端的にいうと「クソ記事を書くな」という投稿が話題になっている。

[日本人ITエンジニアの90％に記事を書いてほしくない](https://anond.hatelabo.jp/20181007145044)

私としてはもっと気軽に記事が書けるようになることが結果としてゴミ記事が減ることにつながると考えているため、それについてまとめていきたいと思う。

# ゴミ記事が多い理由と、その解決策
まずゴミ記事が目に入ることは、ゴミ記事の絶対量が多いことと全く関係がない。

- この世には検索でヒットする数よりはるかに多い記事が存在する
- Googleはユーザの行動を元に、どの記事を表示するかを決めている

したがって検索で良い記事をヒットさせるためには、

- 良い記事が評価されていない
- 良い記事を書ける人が少ない
- 良い記事を書ける人が書かない

これらの問題を解決する必要がある。

## 良い記事が評価されるために　

今はほとんど統計で回っていて、数が多いほうが正解となる。
したがって良い記事かどうかは、「その記事を評価する読者の数」が重要になってきやすい。

そしてプログラミングブームの影響もあり「初心者」の母数が今増えてきている。
そのためか、初心者エンジニア向けの記事が評価されやすくなっているように感じる。

特に「未経験営業からプログラミング勉強始めました」といったような人々も増えており、「ディレクトリという単語を知らない」「コピペという単語を知らない」というレベルの人も多い。
そのため専門用語を使わず噛み砕いた表現を使う記事の方がより多くの人に支持され、結果として上位表示されやすくなっているように見える。

こういった背景から、「日本語の記事はレベルが低い」という感覚を覚える人がいると推測する。

[日本人ITエンジニアの90％に記事を書いてほしくない](https://anond.hatelabo.jp/20181007145044)

### 解決策１：皆がどんどん記事を書く

結局のところ良い記事を評価させるためには読者のレベルを底上げし、良い記事を良いと思う人を増やす必要がある。
そのための手段は色々あると思うが、1つとして「記事を書く」ことが成長に繋がることは間違い無く、少なくともそれを否定するべきではないだろう。

### 解決策２：良い記事を評価する

良い記事として評価することは、個人でもできる。
たとえば「いいねをつける」「SNSやBlogで拡散する」などだ。
これによりQiitaやGoogleでの評価が高まり、人々の目につく確率が高くなる。

## 良い記事を書ける人を増やすために
例えば100人の村に、良い記事を書ける人が10人いたとする。
そこで90人のゴミ記事を書く人が書くのを辞めたとしても、良い記事は増えない。
これを日本語圏全体に広げて考えると、日本語圏全体で良い記事が書ける人を増やす必要があるということになる。

### 解決策１：皆がどんどん記事を書く

文章を書く能力がつくのももちろん、書くことで知識が体系化し理解が深まる側面もある。
したがって皆がどんどん記事を書くことが「良い記事を書ける人を増やす」ということにつながっていくわけだ。
これについては他記事でまとめられているため、詳細は省く。

[エンジニアは全員技術記事を書くことを習慣化した方がいいぞ](https://qiita.com/HiromuMasuda0228/items/a71dea7ef4d77a30b118)

### 解決策２：間違った記事があったら訂正してあげる

間違った記事があったときにそれを訂正してあげることも重要だ。
その記事を見て間違った理解をする人が減るのはもちろん、記事を書いた人の理解も深まるからだ。
弁証法的に議論が進んでいくことで、より良い答えを導き出せるようになることが重要である。

[「空気を読む人」が海外で評価されない、実はとても哲学的な理由](http://piano-tree.hatenablog.com/entry/2016/02/01/212558)

## 良い記事が書ける人に書いてもらうために

良い記事が書ける人が書かない理由は色々あるが、日本語圏全体の心理的安全性が低下すると書く意欲がなくなってしまうのではないだろうか。

どんな記事であっても、いざ書こうとすると何時間もかかってしまったりする。
それを世の中に出したときに、仮に「こんな記事を書くな」という空気感があると、記事を書くという意欲が失われてしまってもおかしくない。
「外にアウトプットをだす」という行為は心理的ハードルが高いため、そういう経験があると内に閉じてしまいがちになってしまうと推測する。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">「いい会社にしても、それが外に伝わらないんです！！」<br><br>本当に？<br><br>多くの場合、それって社内の人がぬるま湯にいて、社外を見てない<br><br>外に発表したりしないくらい自信がなく、オープンマインドがない。<br><br>いい人がいる会社がいい会社じゃない。常に学習してラーニングゾーンにいる会社がいい会社では？ <a href="https://t.co/mWLkbDHMxd">pic.twitter.com/mWLkbDHMxd</a></p>&mdash; 広木 大地/ エンジニアリング組織論への招待 (@hiroki_daichi) <a href="https://twitter.com/hiroki_daichi/status/1047838549381279744?ref_src=twsrc%5Etfw">2018年10月4日</a></blockquote>

このツイートは社内の話だが、これは社外との相対的な話でもあるだろう。
仮に日本語圏全体が心理的安全性と責任の高い環境なのであれば、日本語圏全体がラーニングゾーンにいき、スキルレベルの底上げにも繋がってくるかもしれない。

### 解決策１：敬意を持つ

少なくとも「記事を書く」という時点で、基本的には誰かのために時間をかけて行なっている行為である。
良い記事には感謝をするべきだし、意見が対立したとしても安易に悪意を向けるべきではないんじゃないだろうか。
（もちろん批判するなということではない）

### 解決策２：良い記事を評価する

良いものを良いと評価することで、良いものを生み出せる人のモチベーションにもつながってくる。
そのため「いいねをつける」「SNSやBlogで拡散する」などで評価することは、結果として良い記事を増やすことにもつながってくるだろう。

# おわりに

ということで、結局のところシンプルに**ゴミ記事が多いなら、日本語圏全体の技術力を底上げする必要があるんじゃないの？**という話だと思う。

そのためには個人個人が成長していく必要があり、「ゴミ記事を書くな」という空気感は形成するべきではないんじゃなかろうか。

---

とまあ長々と書いてきたけど、経験上「自分用メモ」みたいな内容でも役立ったことはなんどもあるので、みなさんどんどん記事を書いてくれると助かります。
Illustrator CC で ai ファイル内のすべてのアートボードを複数サイズのPNG出力するスクリプト

# 概要

検索してもまとまった形では見つからなかったのでメモしておきます。

例えば `foo.ai` というファイルの中に `board1, board2` というアートボードがあり、それらをサイズ 48x48, 96x96, 192x192 のPNG形式で `Desktop/Icons` 以下に出力したい場合を考えます。

```
Desktop
|- Icons
    |
    |- foo (<== 新規フォルダ作成)
        |
        |- 48 (<== 新規フォルダ作成)
        |   |- board1.png
        |   |- board2.png
        |
        |- 96 (<== 新規フォルダ作成)
        |   |- board1.png
        |   |- board2.png
        |
        |- 192 (<== 新規フォルダ作成)
            |- board1.png
            |- board2.png
```

#### 前提

* 各アートボードの width, height は同じ値とします

#### 変更履歴

* 2018/10/18
  * コードセクションの `TrimLast` 関数のインデックスがずれている問題を修正

# コード

好きな名前のテキストファイル（下例では "export_png.jsx"） を作成してテキストエディタを以下のように編集します。

```js:export_png.jsx
/// --- 関数定義 (＊エラー処理とかは無視) ---

// path で指定された新規フォルダ作成
function CreateFolder(path)
{
    var f = Folder(path);
    if(!f.exists) { f.create(); }
}

// inStr 末尾から lastStr で指定された文字列を取り除く
function TrimLast(inStr, lastStr)
{
	var idx = inStr.lastIndexOf(lastStr);
	if(idx > 0)
	{
		return inStr.substr(0, idx);
	}
	else
	{
		return inStr;
	}
}

function SavePNG(expFolderPath, doc)
{
	app.activeDocument = doc;
	
	opts = new ExportOptionsPNG24();
	// アートボード毎に処理しますよというフラグ
    opts.artBoardClipping = true;
    // その他の出力オプション（お好みで）
	opts.matte = false;
	opts.transparency = true;

	const ORG_SIZE = doc.height;

    // 48, 96, 192 出力サイズそれぞれについて処理
	var sizes = [48, 96, 192];
	for(var j = 0; j < sizes.length; j++)
	{
		// エクスポートする画像サイズと同じ名前のサブフォルダを作成
		var size = sizes[j];
		var subFolder = expFolderPath + "/" + size;
		CreateFolder(subFolder);

        // エクスポートするサイズをオプション設定
		opts.horizontalScale = opts.verticalScale = 100 * (size / ORG_SIZE);

        // 各アートボードそれぞれについて処理
		for (var i = 0; i < doc.artboards.length; i++ )
		{
			doc.artboards.setActiveArtboardIndex(i);

            // '[expFolderPath]/[size]/[fName].png' というPNG画像エクスポート
			var fName = doc.artboards[i].name;
			var expFile = File(subFolder  + '/' + fName);
			doc.exportFile ( expFile, ExportType.PNG24, opts );
		}
	}
}

/// --- 以下メイン処理 ---

// 読み込む ai ファイルのパス指定
var fileRef = File("path/to/foo.ai");

// Illustrator で ai ファイルを開く
var docRef = app.open(fileRef);

// エクスポートフォルダパス指定
var expFolderPath = "~/desktop/Icons" + "/" + TrimLast(docRef.name, ".ai");

// エクスポート先フォルダが存在しないときは新規フォルダを作成
CreateFolder(expFolderPath);

// PNG画像をエクスポート
SavePNG(expFolderPath, docRef);

// 保存せずに ai ファイルを閉じる
docRef.close(SaveOptions.DONOTSAVECHANGES);
```

# スクリプトの使い方

Illustrator を開いて `[ファイル] > [スクリプト] > [その他のスクリプト] (or Ctrl+F12キー)` を選ぶとファイル選択ダイアログが出てきます。上記のスクリプトファイルを選択してください。
選択するとスクリプトが直ちに実行されます。

# 併せて読みたい？

[Illustrator CC で指定フォルダ以下のすべての ai ファイルを開いて何かするスクリプト](https://qiita.com/_meki/items/8d1b62f4ad7c99591fac)
How To Use Materialized Views In Ruby On Rails With Scenic?

Materialized views are not something widely used in Ruby on Rails applications. However, we have recently tried to use it and the results were very satisfying.

In this case study we would like to present a simple application using Ruby 2.4.1, Rails 5.1.4, PostgreSQL 10 and the [scenic gem](https://github.com/thoughtbot/scenic).

#What are database views?

[From PostgreSQL documentation:](https://www.postgresql.org/docs/10/static/tutorial-views.html)

Suppose the combined listing of weather records and city location is of particular interest to your application, but you do not want to type the query each time you need it. You can create a view over the query, which gives a name to the query that you can refer to like an ordinary table:

```
|  |
|:--|
| CREATE VIEW myview AS |
|  SELECT city, temp_lo, temp_hi, prcp, date, location |
|  FROM weather, cities |
|  WHERE city = name; |
|   |
| SELECT * FROM myview; |
```
Making liberal use of views is a key aspect of good SQL database design. Views allow you to encapsulate the details of the structure of your tables, which might change as your application evolves, behind consistent interfaces.

Views can be used in almost any place a real table can be used. Building views upon other views is not uncommon.

This is just a very handy method not to write complicated queries. It does not help with performance – the complicated query is still executed every time.

# Materialized views
 
Fortunately the views can be materialized. Again, let’s take a look into [PostgreSQL documentation:](https://www.postgresql.org/docs/10/static/rules-materializedviews.html)

Materialized views in PostgreSQL use the rule system like views do, but persist the results in a table-like form. The main differences between:

```
CREATE MATERIALIZED VIEW mymatview AS SELECT * FROM mytab;
```
and:

```
CREATE TABLE mymatview AS SELECT * FROM mytab;
```

are that the materialized view cannot subsequently be directly updated and that the query used to create the materialized view is stored in exactly the same way that a view’s query is stored, so that fresh data can be generated for the materialized view with:

```
REFRESH MATERIALIZED VIEW mymatview;
```

Simply speaking, the results of the view query are stored in the database – just like any other table. The only difference is that we can not update the view directly but it can be refreshed using records from its source tables.

This way, instead of executing expensive queries, we can use data organized in a more simple way in a materialized view.

** We have also prepared a full case study - you can find it here: https://ideamotive.co/blog/materialized-views-ruby-rails-scenic/ **
等幅フォントなど自由にフォントを変更できるChrome Extension「Font Swap - for Google Fonts」

# 前提

- ローカルのエディタではなく、ブラウザ上でコードを書くケースがある
- 例えばBigQueryのQuery Editorなど
- その際に、ブラウザのフォントを自分の見やすいフォントに変えたい。等幅フォントなど

# 対策

- 自由にフォントを変更できるChrome Extension「Font Swap - for Google Fonts」を導入
- サイトごとに、デフォルトのフォントから、自分の好きなフォントに変更できる

# 方法

- まず、Extensionを追加する。[Font Swap \- for Google Fonts \- Chrome ウェブストア](https://chrome.google.com/webstore/detail/font-swap-for-google-font/onhgmcpflfncjkdbclmhnfondmindgbg/related?hl=ja)
- つぎに、Extensionアイコンをクリックして、"Search"という検索窓で、等幅フォントなど好きなフォントを英字で検索して、フォント名をクリックする
- 例：Ubuntu Monoなど
- 他にはGoogle Fontsを検索👉[Google Fonts](https://fonts.google.com/)

# 結果

before
<img width="519" alt="スクリーンショット 2018-10-10 23.20.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/210660/a1693d18-e34e-e0e1-8e66-13159c207124.png">

after
<img width="550" alt="スクリーンショット 2018-10-10 23.19.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/210660/960f63c8-4ef5-6f0b-a07c-10198946c8a0.png">

等幅フォントを入れたら、SQL文を書くQuery Editor内が良い感じになった。

ドメインごとにフォントを変更していけるので便利。
GCPのCloud Functionsでの、関数の外の変数について

CloudFunctions便利ですよね。
デプロイの通知からpuppeteerを使ってみたりまで、色々と遊べる範囲が広いのです。

そんなCloud Functionsなんですが……ふと、呼び出される関数の外に定義してある変数を操作したらどうなるのだろうという疑問が出てきたので試してみました。

# 対象のプログラム！

```cf_var.js
let count = 0;

/**
 * Responds to any HTTP request.
 *
 * @param {!express:Request} req HTTP request context.
 * @param {!express:Response} res HTTP response context.
 */
exports.addCount = (req, res) => {
  count += 1;
  res.status(200).send(`count ${count}`);
};
```

# 対象のCloud Functions！
https://asia-northeast1-neko-tech-test.cloudfunctions.net/global-var

踏めば踏むほど加算されていくので、F5を連打する甲斐があるッ！

一度起動したら、そのコンテナの中で処理を実行させ続けているからかな？
ある程度、時間が経過したりしたら消えそうな気がする:thinking:

これを使って何か……できそうな気がするんだけど思い浮かばない。
Pythonでスポーツ動作分析（野球・バッティング編その②）

# はじめに

スイングをした際にバットがどのような軌道を通ったか（スイング面）を可視化したいと思います。
セグメント検出が可能なMask-RCNNを使って、画像からバットを自動検出しスイング面を推定します。

**イメージ図**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/170139/67af98cd-36a9-aa6a-a431-eeaa0e1781d3.png)

スイング面はスイングプレーンと言ったりもするそうです。
出典：https://blogs.yahoo.co.jp/kinegawareds/21073734.html


# 環境
- 撮影カメラ　自分のスマホ（HTC U11）
- 解析環境
    - windows10 home（64bit/CPU）
    - Google Colaboratory（python3/CPU）
- ライブラリ（https://github.com/matterport/Mask_RCNN）

# Mask-RCNN
Masc R-CNNは、下図のように物体の境界を識別できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/170139/aa0480c5-495a-78b4-bb7e-c34696620eb2.png)

今回使うライブラリは画像にある全ての物体を検出してしまうので、バッドのみを検出するよう少し手を加えます。

## クラス分類
Microsoft COCO が提供する画像データセットを使って、画像の物体を以下に分類しているようです。
「baseball bat」ありました。

```
# COCO Class names
# Index of the class in the list is its ID. For example, to get ID of
# the teddy bear class, use: class_names.index('teddy bear')
class_names = ['BG', 'person', 'bicycle', 'car', 'motorcycle', 'airplane',
　　　　　　　　～途中略～
               'kite', 'baseball bat', 'baseball glove', 'skateboard', ##  ←　ありました。
               'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup',
　　　　　　　　～途中略～
               'keyboard', 'cell phone', 'microwave', 'oven', 'toaster',
               'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors',
               'teddy bear', 'hair drier', 'toothbrush']
```

## バットのみを検出するよう修正

検出した物体がclass_names中の35番目（baseball bat）の場合のみ、画像に色をつけるように修正

```visualize.py
def display_instances(payerName, image_base, image, boxes, masks, class_ids, class_names,
                      scores=None, title="",
                      figsize=(16, 16), ax=None,
                      show_mask=True, show_bbox=True,
                      colors=None, captions=None):
　　～途中略～
        if class_ids[i] == 35: ## ←　この条件を追加
　　　　　　～途中略～
            for verts in contours:
                p = Polygon(verts, facecolor="#FFFF00", edgecolor="#FFFF00") ## ← 修正（黄色で描画）
                ax.add_patch(p)
```

# バットを自動検出

以下のように画像からバッドを検出していきます。

1. OpenCVを使って、動画から画像を切出し
1. Microsoft COCO画像を使って、画像判定モデルを学習させる
1. 画像からバッドを検出⇒スイングの一番最後の画像に描画
1. 「3」をスイングの全画像分繰り返し

**実行ソース**

https://github.com/nanako-ut/analyze-motion2/blob/master/maskRnn_keras_swingPlane_ipynb.ipynb

# スイング面を推定
ここも自動化したかったのですが・・・
描画されたバッドから人手でスイング面を推定します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/170139/7f67ed8a-e3c1-bca4-274c-dcb2942a6820.png)

# スイングタイプを推定
複数の選手を解析していったところ、３つのタイプに分類できそうでした。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/170139/7966ae38-9cb5-52eb-7f92-8d4dd59f7b8c.png)
 

# 関連記事
 - [バッティングフォーム解析その１](https://qiita.com/nanako_ut/items/1a9ce5d4eca672b38d2d)
 - [ピッチングフォーム解析](https://qiita.com/drafts/30b2bed9d102b0707ec2/edit)
Apple製のアプリのView Hierarchyを見る方法

iOSにデフォルトで入っているAppleのマップやニュースなどのアプリがどのような作りでできているのか気になりませんか？
実はXcodeのデバッグ機能を利用すると、シミュレータに入っているアプリ限定ですが、それらのアプリのView Hierarchyなどを見ることができます。

# 手順
1. XcodeとiOSのSimulatorを起動します。
2. SimulatorでView Hierarchyを見たいアプリを起動します。
3. Xcodeのメニューから「Debug」→「Attach to Process」を選び、一覧から先程起動したアプリを選びます。
4. 下のバーにある「Debug View Hierarchy」をクリックします。
5. 見放題 :eye: :eye: 

## こんな感じで見れます

### マップ
![Map](https://qiita-image-store.s3.amazonaws.com/0/91631/18935c0c-4133-041f-d40c-045bc1b559c4.png)

### ニュース
![ニュース](https://qiita-image-store.s3.amazonaws.com/0/91631/bbaa9502-0e71-18f2-1a03-6b09cfe93c53.png)

### 設定アプリ
![設定](https://qiita-image-store.s3.amazonaws.com/0/91631/7f9fb032-52c4-0ceb-ea8f-5f5809fa5ef4.png)

※載せてよいのかわからないのでモザイク処理をしました。

# まとめ
「Attach to Process」を使うと、Simulator内のアプリのデバッグが可能です。
また、デバッグコンソールからlldbの`po`コマンドなどを利用して、Viewを操作することで、挙動を観察することもできます。

ContainerViewの使い方・粒度、Viewの命名、半モーダルビューはどう実現しているのかなど、とても参考になるので、気になる方は試してみてはどうでしょうか。
CI上のyarnの設定

yarnをCI上で実行する場合、`yarn`とするよりも`--frozen-lockfile`を利用した方が安全です。
こうすると、`yarn.lock`を生成せず、更新がある場合に落ちる挙動をします。これによりCIと結果が異なることということが避けられます。

```
$ yarn --frozen-lockfile
```

https://yarnpkg.com/lang/en/docs/cli/install/#toc-yarn-install-frozen-lockfile

似たようなオプションで`--pure-lockfile`がありますが、こちらはlockファイルを生成しないだけです。

また、`--ignore-optional`を使ってローカルでしか使わないライブラリ(アプリとビルドとテストに不要なライブラリ)を除外してインストールするのも便利です。

```
$ yarn --frozen-lockfile --ignore-optional
```

## enginesの指定

CIでyarnの最新をダウンロードするようにしておくと、いつの間にかyarnのバージョン更新されていることがあります。(ローカルとCIのバージョンがずれる)
これは嬉しくないので、`package.json`の`engines`を指定してチームで同じバージョン以上を使うようにしておくとよさそうです。

https://yarnpkg.com/lang/en/docs/package-json/#toc-engines

```
{
  "engines": {
    "node": ">=10",
    "yarn": "^1.10.0"
  }
}
```

またすぐ`v1.12`がきそうな気もするので固定する`yarn`のバージョンについては議論がありそうです。
Datalabで簡易webクローリングし、GoogleCloudStorage(GCS)にアップロードする方法

#はじめに
GCP Cloud Datalab(Python3)で、requestsライブラリを利用してcsvを特定サイトから取得し、取得したデータをGoogle Cloud Storage(GCS)に格納するコードを説明します。

こんなユーザが対象です。

* ローカルでJupyterNotebookを使っていたが、クラウドでいつでもどこからでも利用したい
* WEBのデータ(csv)を簡単に取得してGCSへアップロードしたい

##環境

* Cloud Datalab(Python3) 



##[Cloud Datalab](https://cloud.google.com/datalab/?hl=ja)とは
「データの探索、分析、可視化と機械学習のための使いやすいインタラクティブなツール」で、実態はGCE上にあるJupyterNotebookです。ネットに繋がればいつでもどこからでもJupyterを利用可能なので大変便利です。

複数ユーザで共有したいNotebookがある場合は、--no-user-checkingオプションを入れて、connectすればOK。（詳細な起動方法は他サイトを参照）

```Python:Datalab起動方法(複数ユーザ同時接続)
datalab connect --no-user-checking <VM名>
```

## Datalab上でのPythonコード詳細
まず、必要なライブラリ読み込みます。

```Python:
import requests
import sys
import google.datalab.storage as storage
```

適宜、変数を定義します。

```Python:
## バケットの定義、適宜変更
bucket_name = '<bucket name>' // バケット名
bucket_path = 'gs://' + bucket_name //バケットのPATH
bucket_dir = '<bucket directory>/' //GCSの保存先フォルダ名
access_url = 'https://<replace to site>/sample.csv' //ダウンロードしたいサイトのcsv
upload_filename = 'sample_upload.csv'
```

対象のURLからrequestsを利用して、ファイルを取得。response.contentにコンテンツが格納されます。typeはbytes。

```Python:
## URLからダウンロードする  
def download(url):
  data = ""
  response = requests.get(url)
  #print(type(response.content))
  ## <class 'bytes'>
  
  if response.status_code == 200:
    data = response.content
    return data
  else:
    print('download error')
    exit()
    return data
```

GCSにアップロードする関数は以下です。main関数(後述)で、
bucketインスタンスを作成しておき、コンテンツタイプを指定(必須)して、
write_streamにてアップロードします。[参考サイト](https://googledatalab.github.io/pydatalab/google.datalab.storage.html)によると、uploadと、write_streamの二つが、datalabのstorageモジュールで利用可能なアップロード関数ですが、テキストコンテンツの場合は、write_streamを利用するようです。

```Python:
## GCSにアップロードする
def upload_gcs(bucket, uploadObject, data):
  upload_object = bucket.object(uploadObject)
  upload_object.write_stream(data,content_type='text/csv')
```

mainは、以下です。決め打ちでアップロード時のファイル名を、sample_upload.csvにしていますが、利用環境に合わせ適宜、変更してください。

```Python:
if __name__ == "__main__":
  
  ## アクセスする先のURL
  url = access_url

  ## バケットインスタンスの作成
  bucket = storage.Bucket(bucket_name)
  
  ## URLにGETアクセスした結果のコンテンツを取得
  data = download(url)
  if data != "":
    ## 正常に取得できたら、指定したGCS(かつ、uploadフォルダ配下)へアップロード。ファイル名も指定。
    upload_gcs(bucket, bucket_dir + upload_filename, data)
    print('Success!')
  else:
    print('not Success!')
```

## 参考サイト

*[https://googledatalab.github.io/pydatalab/google.datalab.storage.html](https://googledatalab.github.io/pydatalab/google.datalab.storage.html)
*この記事に触発されて記事を書きました。→[エンジニアは全員技術記事を書くことを習慣化した方がいいぞ](https://qiita.com/HiromuMasuda0228/items/a71dea7ef4d77a30b118)



## おわりに
エラー処理などは、簡単に記載しましたが、基本的な部分はこれで分かると思います。
アクセスするURLを変更・繰り返しをすることで複数サイトクローリングも、もちろんできます。

Datalabは、インターネットアクセスさえあればいつでも、どのPC環境でも利用できますし、もっと活用していきたいと思います。実際には複数ファイルをWebクロール、スクレイピングしてBigQueryへ入れてみましたので、別記事でまとめようと思います。
Pythonのこと何も知らないけどエンジニア半年目が色々調べてみた

この記事は僕自身のQiita初投稿であると同時にエンジニア系で初の記事になります。javaのエンジニアになって半年、そろそろ違う言語にも手をつけようかというところでずっと気になっていたのがPythonでした。

何となくこう、字面かっこ良くないですか？？（最初はフィソンと読むのかなと思ってたのは内緒です）

講師のIさんから研修時代にJavaのインデントを注意された時に、「それじゃあPythonなんて絶対無理だよ」みたいなことを言われたのを覚えています。何でもPythonはインデントでブロックを表現するのだとか。いまでもインデント間違えてCheckStyleに怒られる僕には耳が痛いですね...

ところでPythonって何ができるんだろう？
有名どころだとYouTubeやInstagramの開発に使われていたり、機械学習関連の話題でもちょくちょく耳にしますよね。調べたところSNSだったりのwebページに投稿されたデータを抽出して解析してみたりできるらしく、データサイエンティストにも人気だそうです。

（将来これで楽できたらいいなあ。。。）

というわけで前置きですが、本記事はPythonの導入について初心者目線で調べたことを簡潔にまとめたものになリます。ほとんどの方には既視感ばかりの内容かもしれません。突っ込みどころ満載だとは思いますが、そこはコメントでお待ちしておりますー。

Macをお持ちの方はターミナルを起動して"python"と打ち込んでみましょう。早速pythonのコードが入力できる状態になります。

そうです。Macには最初からpythonが入っています。（実際に開発するには様々な追加設定やライブラリが必要）

```Python
Last login: Wed Oct 10 21:53:21 on ttys000
$ python
Python 2.7.10 (default, Oct  6 2017, 22:29:07) 
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print("Hello Python")
Hello Python
>>> 
```
print()は文字列を標準出力する関数です。Javaと違って行末に";"が必要なかったりするのは個人的に楽でいいなあと思ってます。

というわけでJavaと何となく共通点はありそうだけど差分を体に染み込ませないとコードはかけそうにありません。そこで入門としてネットで学べる学習サイトについて調べて実際にやってみたのでそれについて紹介します。ちなみに無料で受講できるものを選びました（一部有料）。

1. progate
https://prog-8.com/languages

![progate-service1.png](https://qiita-image-store.s3.amazonaws.com/0/245035/753bf72b-18e5-895c-df5d-a85795e8611f.png)

株式会社 Progateが運営しているプログラミング学習サービスです。
シンプルなスライド形式で説明を受けた後に入力欄とコンソールが出て来て実技演習が受けられるようになっています。Googleなどのアカウントでログインするだけで始められるので、面倒な環境構築から初めてそこでつまづいて終わってしまったりする心配がありません。（もちろん勉強した後は頑張って環境構築しなきゃですが）

基本的な関数の扱い方、リストやfor文、continueなどまで学べて簡単な買い物プログラムを作るまでサポートしてくれます。

無料で受けられるpythonの講座はそこまで多くないですが、最初に気軽に始めるならすぐ終わるのでオススメですー。別の言語の講座も多く取り揃えがありますし言語の他にgitなどの講座もありました。

スマホでは流石にやりづらいですが大きめのタブレットだと普通にできるのが嬉しいですね。

２. paizaラーニングhttps://paiza.jp/works/courses

![スクリーンショット 2018-10-10 23.09.45.png](https://qiita-image-store.s3.amazonaws.com/0/245035/76116155-f4eb-440d-fda2-6331ee81ad4f.png)
 
こちらが個人的にオススメの学習サービスです。動画でコーディングの例を見てから実技演習をやるのですが、動画のナレーションをしてくれるお姉さんがいいキャラしてて飽きずに読み進めることができます！
（是非こちらは実際に試して見てください！！）

おまけにprogateと比較して、こちらではPythonをHTMLで出力して見たり、クラスの継承やライブラリの読み込みなど込み入った内容も無料の講座で受けることができます。

いかがだったでしょうか？
初めての記事はこの辺で終わりにしたいと思います。紹介した学習サービスはPythonに限らずその他の言語の学習にも役立つと思います。皆さんもこれを機に馴染んだ言語以外にも手を伸ばして見てはどうでしょうか？

最後まで読んでいただいてありがとうございます！
それではー。
TeraTermにおけるマクロの基本的な書き方

#はじめに
初めてTeratermでマクロを使う機会があったので忘れないようにメモ
内容はいたって初歩的なものです。
#マクロの書き方
マクロはテキストエディタなどで記述し、保存時にファイルの拡張子を".ttl"に変更する。
".txt"で保存すると動作しないので注意する。
コードは１行ずつ記述していく。２行にわたってはいけない。
#記述例
```:test.ttl
i = 5
s = 'q'
while i>0
send s#13#10
i = i -1
endwhile
```

このマクロを実行すると'q'が５回、Teratermで送信される。

簡単に解説すると、
whileは繰り返し文でwhileの後に書いてある条件が成り立つ間、endwhileまでの処理を繰り返す。
sendはteratermに対して文字を送信する。
 #13はCR, #10はLFを表している。

なおコメントを書く場合は、コメントの手前に';'をつける

#まとめ
マクロの書き方についての備忘録
他にも色々コマンドがあるみたいなので、今後色々と使っていく予定。
日付→西暦0年からの総日数や総時間数への変換

検索しても出てこなかったので．
あまりスマートじゃないです．
カレンダーの定義をうまく使えばできそうですが．．．

```py:datetime2total_hours.py
import datetime

t  = datetime.datetime(2000,1,1,0,0) # 対象とする日付
t0 = datetime.datetime(   1,1,1,0,0) # 定義可能な一番古い日付
dt = datetime.timedelta(days=366) # 西暦0年が存在したとしたらの日数

total_days  = (t-t0 + dt).days
total_hours = total_days*24
```
NodeJSについて基本的な情報

最近はNodeJSの勉強を始めました。この作文は私の学んだことのメモと日本語の練習です。
Udemyで勉強しています。[NodeJS Course](https://www.udemy.com/the-complete-nodejs-developer-course-2/learn/v4/overview)

##NodeJSは何ですか？
JavaScriptは「Interpreted Language」という「Interpreter/Engine」が必要な言語です。このエンジンはマシンの言語までコードを翻訳します。実行の時、翻訳する。「Compile」が必要じゃありません。
JavaScriptのエンジンで「Google Chrome V8 Engine」は一番有名です。Nodeのエンジニアはバクエンドサーバの特徴のために「V8 Engine」をパッケージして、APIとLibrariesのコードを作って、NodeJSをできました。

NodeJSはサーバサイドのJavaScriptの「Runtime Environment」です。

##「Event Loop」は何ですか？
イベントループというAsynchronousのタスクのリストです。Asynchronousのコードをインスタントの実行しません。

ーつづく
macを初期化したらインストールするもの

xcodeをinstall

```bash
# homebrewをインストール
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

# GUIのアプリを入れるためにcaskを入れる

brew tap caskroom/cask
brew tap caskroom/homebrew-versions

brew cask install visual-studio-code
brew cask install google-japanese-ime
brew cask install iterm2
brew cask install sourcetree
brew cask install mapture
brew cask install docker
```
Ruby on Railsでよく出てくる<%= %>をすばやく入力する方法(Atom)

# Atomのスニペット機能
開発をしていると、しばしば同じようなコードを書く機会が出てきます。
頻出の書き方はスニペットを利用したほうが、ストレスが少なく且つすばやくコーディングできます。
この記事では私が毎回入力に手間取っている「<%= %>」について、スニペット登録する方法をまとめます。

## 設定方法
Atomを起動し、ファイルメニューから「Snipets...」を選択します。
「snipets.cson」というファイルが開くので、その中身を編集していきます。
このファイルの中には定義の例が記載してあります。

```ruby
# '.source.coffee':
#   'Console log':
#     'prefix': 'log'
#     'body': 'console.log $1'
```

| 行       |       カラム |    説明    |
|:-----------------|:------------------|:------------------|
| 1             |'.source.coffee' |セレクタ|
| 2           |'Console log' |スニペット名|
| 3             |'prefix'|トリガーとなる文字列|
| 4               |body|展開する内容|

上記に沿って定義して上げる必要があります。
今回は「<」と入力した際に「<%=%>」と表示されるように設定します。
下記のようになります。

```ruby
'.text.html.erb':
  '<':
    'prefix': '<'
    'body': '<%=$1%>'
```
１つずつ説明していく。

### セレクタ

```ruby
'.text.html.erb':
```
今回は、拡張子が「.html.erb」となっているファイルにコーディングする際にスニペットとして表示されるようにします。
セレクタは[Autocomplete Providers](https://github.com/atom/autocomplete-plus/wiki/Autocomplete-Providers)で確認することができます。
セレクタに入力する文字列は決まり事なので、このリンクに記載されている中から該当する文字列を入力しましょう。

### スニペット名
```ruby
  '<':
```
スニペット名は、他のスニペット名とカブらなければなんでもOK。
困ったらPrefixと同じ文字列を入力しておけばよいです。

### Prefix
```ruby
    'prefix': '<'
```
今回は「<」と入力したときに発動してほしいため、上記のように入力しています。
ここは自分の入力しやすいように設定してもらえればよいです。

### body
```ruby
    'body': '<%=$1%>'
```
表示したい内容を登録します。
「\$1」と入力しておくと、スニペットが入力したあと「\$1」の位置にカーソルが移動します。
入力後にカーソルを移動させたい部分まで指定することで、効率よくコーディングすることが可能です。

## 設定情報反映
設定を反映させるには、「snipets.cson」を保存すれば良いです。
Atomを再起動させる必要はありません。
繰り返し何度も入力するような文字列がある場合は、積極的にスニペットを活用して効率よくコーディングしましょう！