OmniAICreator/Qiita-1.07M huggingface dataset:
Retrive the list of databases on UCSC


[UCSC Tables](https://genome.ucsc.edu/cgi-bin/hgTables) allows MySQL access.

- https://genome.ucsc.edu/goldenpath/help/mysql.html

```
Host: genome-mysql.cse.ucsc.edu
Port: 3306
User: genomep
Pass: password
```

- However, for database name, you need to use genome assembly name (e.g. **hg38**). Usually retriving assembly name is hard work, especially for specific case.
- For example, Gorilla gorGor5 has only refSeq genes but gorGor3 has only Ensembl genes. If you want only Ensembl genes data, this can be problematic.
- For this purpose, you might want to get the table for `[clade, organism, assembly]` triplets.
- You can use the following script. But *never use it too frequently.*

```rb:ucsc_dbs.rb
#!/usr/bin/ruby
require 'mechanize'
UCSC='http://genome.ucsc.edu'
agent=Mechanize.new
agent.get(UCSC+"/cgi-bin/hgTables")
hgsid=agent.page.form_with(action:'/cgi-bin/hgTables').field_with(name:'hgsid').value
clades=agent.page.form_with(action:'/cgi-bin/hgTables').field_with(name:'clade').options.map(&:value)
clades.each{|clade|
	agent.get(UCSC+"/cgi-bin/hgTables?hgsid=#{hgsid}&clade=#{clade}")
	organisms=agent.page.form_with(action:'/cgi-bin/hgTables').field_with(name:'org').options.map(&:value)
	organisms.each{|organism|
		agent.get(UCSC+"/cgi-bin/hgTables?hgsid=#{hgsid}&clade=#{clade}&org=#{organism}")
		dbs=agent.page.form_with(action:'/cgi-bin/hgTables').field_with(name:'db').options.map(&:value)
		dbs.each{|db|
			#agent.get(UCSC+"/cgi-bin/hgTables?hgsid=#{hgsid}&clade=#{clade}&org=#{organism}&db=#{db}&hgta_group=genes")
			puts [clade,organism,db].inspect+','
		}
	}
}
```
Natural Language Classifier Toolkit 

![nlc01.png](https://qiita-image-store.s3.amazonaws.com/0/145508/5204fc8a-2195-1fd5-053b-47507d76f8c6.png)
![nlc02.png](https://qiita-image-store.s3.amazonaws.com/0/145508/9fc93d1e-a6e8-8527-88e8-b87b4e2e9833.png)
![nlc03.png](https://qiita-image-store.s3.amazonaws.com/0/145508/71da2425-4ce8-1b0b-b677-4c5fb8ae6e4d.png)
![nlc04.png](https://qiita-image-store.s3.amazonaws.com/0/145508/82c098f6-16b8-375d-8ef7-9c0b80078c57.png)
![nlc05.png](https://qiita-image-store.s3.amazonaws.com/0/145508/9dd763f3-a071-d6ed-b794-f48ce4ed5039.png)
![nlc05-1.png](https://qiita-image-store.s3.amazonaws.com/0/145508/1bd771fa-cedf-cdf5-3eef-619f111e1176.png)
![nlc06.png](https://qiita-image-store.s3.amazonaws.com/0/145508/0e780ed5-cd1f-3072-d1b9-1f5a66961485.png)
![nlc07.png](https://qiita-image-store.s3.amazonaws.com/0/145508/7e062a3a-355b-590b-2d92-549dbb9271d0.png)
![nlc08.png](https://qiita-image-store.s3.amazonaws.com/0/145508/53097669-66e2-d6ae-1ebd-10ab81159ba0.png)
![nlc09.png](https://qiita-image-store.s3.amazonaws.com/0/145508/f1d9a129-0392-d5da-5b61-4ea8c07e5c4d.png)
![nlc10.png](https://qiita-image-store.s3.amazonaws.com/0/145508/c42de93c-30fd-e173-ae7d-c6e37312739a.png)
![nlc11.png](https://qiita-image-store.s3.amazonaws.com/0/145508/5cb8bcf7-c4b7-4e91-22f7-3ec9997e859a.png)
LCD 利用を2種類



電源のON/OFFのような2値の状態の場合は、LEDのON/OFFを使えばよいのですが、何か情報（IPアドレスとか）を表示しようとすると LED は足りません。かといって、いちいち液晶モニタを繋げないと内容がわからないのでは大げさすぎるので、LCD を使います。液晶 LCD はキャラクタ表示のものを使います。

[Basic LCD 16x2](https://www.hackster.io/rvoltr/basic-lcd-16x2-48482b?ref=part&amp;ref_id=9417&amp;offset=73 "Basic LCD 16x2")

![](https://hackster.imgix.net/uploads/cover_image/file/50483/WP_20150611_10_45_50_Pro.jpg?auto=compress%2Cformat&w=900&h=675&fit=min)

[Character LCD over I2C - Hackster.io](https://www.hackster.io/dzerycz/character-lcd-over-i2c-ba8ee9?ref=part&amp;ref_id=9417&amp;offset=76 "Character LCD over I2C - Hackster.io")

![](https://hackster.imgix.net/uploads/cover_image/file/70898/Facebook-20150909-081631.jpg?auto=compress%2Cformat&w=900&h=675&fit=min)

HDMI で接続できる液晶モニタと違って、LCD の場合はジャンパーワイヤーの繋げ方がややこしい...というかきちんと回路図を組まないと表示できないので、なかなか初心者にはたいへんなのですが（Easyになってるけど）、慣れると手軽に組めるようになるのかもしれません。

ただし、液晶モニタよりも電力が各段に電力が少なくて済むので、低電力化には必須かなと。


実装コードは以下に公開されています。

[Voltrr1/LCDWin10: Alphanumeric LCD (16x2 and other) for Windows 10 IoT Core](https://github.com/Voltrr1/LCDWin10 "Voltrr1/LCDWin10: Alphanumeric LCD (16x2 and other) for Windows 10 IoT Core")

[DzeryCZ/Character-LCD-over-I2C: Connect HD44780 LCD character display to Windows 10 IoT devices via I2C and PCF8574](https://github.com/DzeryCZ/Character-LCD-over-I2C "DzeryCZ/Character-LCD-over-I2C: Connect HD44780 LCD character display to Windows 10 IoT devices via I2C and PCF8574")
[VBA]作成したクラスをアドインとして利用する

複数のプロジェクトで使いまわしたいクラスは、アドインとして外部に置いておいて別のExcel VBAから参照できると便利です。（たぶん）

#やり方
##1. ふつうにクラスモジュールを作成する
ここでは```ClassInXlam```という名称にします。

```vbnet:ClassInXlam(クラスモジュール)
Option Explicit

Public str As String

' strの中身を表示する
Public Sub ShowStr()
    Debug.Print "str=" & str
End Sub
```

##2. 外部からインスタンスを取得するための関数を追加する
外部からは直接Newできないため、標準モジュールを追加し、外部からインスタンスを取得するための関数を書きます。
ここではモジュールは```Root```という名称にしています。

```vbnet:Root(標準モジュール)
Option Explicit

Public Function CreateClassInXlam(str As String) As ClassInXlam
    Dim tmpClass As ClassInXlam
    
    Set tmpClass = New ClassInXlam
    tmpClass.str = str
    
    Set CreateClassInXlam = tmpClass
End Function
```

##3. クラスのプロパティをPublicNotCreatableにする
プロパティウインドウから、クラスのInstancingプロパティを```2 - PublicNotCreatable```にします。
（完全なPublicには設定できません。）
これで外部からクラス名が使えるようになります。

##4. プロジェクトの名称を変更する
デフォルトのVBAProjectのままでは、他ファイルから参照したときに名称が競合してエラーになります。
プロジェクトエクスプローラから対象のプロジェクトを右クリックして適当な名称に変更します。

##5. Excelアドイン形式で保存する
名前を付けて保存で、「.xlam」形式を選択して保存します。
ここまででアドイン側の準備は終了です。

#外から参照してみる
新しいブックを開いて、そこから参照してみます。

##1. アドインへ参照設定をする
VBEの 「ツール」>「参照設定」ダイアログの「参照」から、先ほど作成したxlamファイルを選択します。
「OK」を押すと、プロジェクトエクスプローラの「参照設定」のところに参照先として追加されています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/133716/f3a6601c-3be2-a42e-d5c6-46876369b3db.png)

##2. 使う

こんな感じで使えます。
Intellisenseも使えます。

```vbnet:標準モジュール
Option Explicit

Sub test()
    Dim instanceOfClass As ClassInXlam
    
    Set instanceOfClass = CreateClassInXlam("test")
    
    instanceOfClass.ShowStr ' => str=test
End Sub
```

#外からインスタンス化するインターフェースについて

以下のようにすると、```ClassInXlam.Create()```と書けてStaticメソッドから作成できているように見えてかっこいいです。

##1. クラスモジュールにCreateメソッドを作成する

Createメソッドは、外部ファイルからインスタンスを作れるようにするためです。

```vbnet:ClassInXlam(クラスモジュール)
Option Explicit

Public str As String

' strの中身を表示する
Public Sub ShowStr()
    Debug.Print "str=" & str
End Sub

' ちなみにCreateには引数も渡せる
Public Function Create(str As String) As ClassInXlam
    Dim tmpClass As ClassInXlam
    
    Set tmpClass = New ClassInXlam
    tmpClass.str = str
    
    Set Create = tmpClass
End Function
```

##2. インスタンス生成用のパブリック変数をつくる

アドイン側のRootモジュールの内容を以下のようにします。

```vbnet:Root(標準モジュール)
Option Explicit

Public ClassInXlam As New ClassInXlam
```

このパブリック変数を経由して外部からインスタンスを取得します。
```As New```としているので常にインスタンスが入っている（Nothingになっていない）ことが保証されています。
変数名はクラス名と同じでも問題ないようです。

##3. 使う
これで外部から以下のように使えます。

```vbnet:標準モジュール
Option Explicit

Sub test()
    Dim instanceOfClass As ClassInXlam
    
    Set instanceOfClass = ClassInXlam.Create("test")
    
    instanceOfClass.ShowStr ' => str=test
End Sub
```

##注意点
実際には```ClassInXlam```というパブリック変数に入っているインスタンスのメソッドを使っているだけです。
生成のためだけの余計なインスタンスが1つ存在しているわけなので、問題になる場面もあるかもしれません。
python基礎学習（コード書き方編）

# 基礎固め
今まで、コード書く経験といえば、VBAでちょこっと業務効率化するため、既存コードのミニ改修くらいなもので、０から書くことなかった。

ということで、0から書くための基礎体力作りを始めた。
ここでは、そこで生まれた課題やちょっとした疑問、それらへの回答や解決策を、備忘録として残しておく。
随時追加予定。


## `if __name__ == '__main__':`
よく見るけど、これ何？と思い、ググってみる。

ifの中身は、スクリプトとして実行された時のみ、実行されるらしい。
いや、わからん。

### 実行の仕方の違い
どうやらこういうこと？

スクリプトとして実行　↔︎　`import`で実行

以下のようなスクリプトを作り、実行してみる。

```python:test1.py
# -*- coding: utf-8 -*-

print('import')

if __name__ == '__main__':
    print('スクリプト')
```

まず、Terminalで実行。

```
$ python test1.py
```

```
import
スクリプト
```

次に、インタープリタで実行。

```
$ python
>>> import test1
```

```
import
```

ほう。

自分で作ったクラスなり関数を`import`で取ってくるなんてしたことなかったから、とっさに理解できなかった。

以下疑問点。
・そもそも、分解して`import`で取ってくることの利点ってなんだろ、改修しやすいとかかな？
・なんのためにこんな仕組み（スクリプトとしてと`import`時とで、制御を分けること）があるのか？これは仮説も浮かばん。

### `__name__`って何？`__main__`って何？
次に引っかかるのがこれ。何これ。
ググった結果・・・

・`__name__`を使って、モジュール名を取得できる
・スクリプトのメインモジュールは、常に`__main__`と呼ばれる

ん？
メインモジュールって何？
メインとそれ以外との違いは？

ということで、メインとそれ以外の違いを検証。

以下のようなスクリプトを作成、実行。

```python:test2.py
# -*- coding: utf-8 -*-

print(__name__)
```

```
$ python test2.py
```

結果は

```
__main__
```

次は、上記スクリプトを`import`した、以下のようなスクリプト。

```python:test3.py
# -*- coding: utf-8 -*-

import test2
print(__name__)
```

実行。

```
$ python test3.py
```

結果は

```
test2
__main__
```

`import`した`test2.py`は、モジュール名が出力された。
どうやら`__name__`という関数（？）は、自スクリプトが実行されるときは`__main__`、それ以外はモジュール名を取ってくる、という解釈でいいのか？

使い道がわからん・・・
macOS Sierraでpip install tweepyしたらエラー出たので対処した

# 解決策

`pip`に`--user`オプションをつける

```shell-session
% pip install tweepy --user
```

# 作業履歴

PyCharmでインストールしようとしたらエラー

`sudo`で実行してみる

```shell-session
% sudo pip install tweepy                                                                                                               Password:
You are using pip version 7.1.0, however version 9.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
The directory '/Users/Artemis/Library/Caches/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
You are using pip version 7.1.0, however version 9.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
The directory '/Users/Artemis/Library/Caches/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
.
.
.
OSError: [Errno 13] Permission denied: '/Library/Python/2.7/site-packages/pygments'
```

pipのバージョンで注意される -> 前回バージョンアップしてめんどくさいことになったので無視
所有権で注意される
権限で怒られる

`sudo`に`-H`オプションをつけてみる

```shell-session
% sudo -H pip install tweepy                                                                                                            
.
.
.
OSError: [Errno 1] Operation not permitted: '/tmp/pip-SMqSdl-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/six-1.4.1-py2.7.egg-info'
```

エラーが変わったが解決しない

`/tmp/pip-SMqSdl-uninstall`はroot権限だけど`sudo`つけてるし...

`pip`に`--user`オプションをつけたらインストール先を変えられるようだ

```shell-session
% pip install tweepy --user                                                                                                             You are using pip version 7.1.0, however version 9.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
Collecting tweepy
  Downloading tweepy-3.5.0-py2.py3-none-any.whl
Requirement already satisfied (use --upgrade to upgrade): requests>=2.4.3 in /Library/Python/2.7/site-packages (from tweepy)
Collecting six>=1.7.3 (from tweepy)
  Downloading six-1.10.0-py2.py3-none-any.whl
Collecting requests-oauthlib>=0.4.1 (from tweepy)
  Downloading requests_oauthlib-0.7.0-py2.py3-none-any.whl
Collecting oauthlib>=0.6.2 (from requests-oauthlib>=0.4.1->tweepy)
  Downloading oauthlib-2.0.1.tar.gz (122kB)
    100% |████████████████████████████████| 126kB 938kB/s
Installing collected packages: six, oauthlib, requests-oauthlib, tweepy
  Running setup.py install for oauthlib
Successfully installed oauthlib requests-oauthlib six-1.4.1 tweepy
```

できた！

間違いがあればご指摘ください。

# 参考文献

http://qiita.com/tmsanrinsha/items/d7b69bde61a55038c054
http://qiita.com/ronin_gw/items/cdf8112b61649ca455f5
http://tdoc.info/blog/2014/01/15/pip.html
簡単な Watson NLC 入門


## はじめに

Watson サービスの中で分類器として用意されている NLC(Natural Language Classifier) 試してみた私のメモです。

まずは、簡単に試すために、Toolkit からテストしてみます。
以下を作業する前に、Bluemix 上で、NLC サービスをカタログから選択して、サービスを作成していることを前提とします。


## ToolKit から、NLC の学習を行う

サービスを選択すると以下の画面になります。「Access the beta toolkit」を選択します。

![Watson-2017-01-03-12.49.jpg](https://qiita-image-store.s3.amazonaws.com/0/73831/482aadc3-1fed-df0b-0bdc-c828e6fa751e.jpeg "Watson-2017-01-03-12.49.jpg")

「Sign in with Bluemix」を選択して、サインインします。許可を求められたら、「確認」を選択します。

![Watson-2017-01-03-13.03.jpg](https://qiita-image-store.s3.amazonaws.com/0/73831/ab5d281c-51fb-ca87-6197-12cd40ab2983.jpeg "Watson-2017-01-03-13.03.jpg")

「Add training data」を選択します。

![Watson-2017-01-03-13.12.jpg](https://qiita-image-store.s3.amazonaws.com/0/73831/ee4765db-2bb1-faba-c723-eb072c0cac72.jpeg "Watson-2017-01-03-13.12.jpg")

訓練用のCSVのカンマ区切りデータを用意して、Create classifier の横にあるアップロードを選択します。

![Watson-2017-01-03-13.14.jpg](https://qiita-image-store.s3.amazonaws.com/0/73831/87816bcd-c3d2-9b0f-5fac-a8ce3785c105.jpeg "Watson-2017-01-03-13.14.jpg")

テストなので以下のようなデータを準備
(後述書籍より)

![Watson-2017-01-03-13.41.jpg](https://qiita-image-store.s3.amazonaws.com/0/73831/56914f6d-7031-8e44-c04c-b9100c87c00c.jpeg "Watson-2017-01-03-13.41.jpg")

アップロードが完了すると以下のようになります。「Create Classifier」を選択します。

![Watson-2017-01-03-13.45.jpg](https://qiita-image-store.s3.amazonaws.com/0/73831/08531545-46ee-262b-9c68-ac939593cd5f.jpeg "Watson-2017-01-03-13.45.jpg")

「Create」を選択します。

![Watson-2017-01-03-13.49.jpg](https://qiita-image-store.s3.amazonaws.com/0/73831/68a84cbe-9d39-4283-84cb-69bdead6fd14.jpeg "Watson-2017-01-03-13.49.jpg")

## 学習した内容のテスト

右下の矢印ボタンを選択します。

![Watson-2017-01-03-13.55.jpg](https://qiita-image-store.s3.amazonaws.com/0/73831/f83081e4-38c8-6771-f7b6-b1262ae97c1f.jpeg "Watson-2017-01-03-13.55.jpg")

下記の画面になるので値を入れて、「Classify」を選択すると、結果が表示されます。下記の例ですと、Theater の分類の可能性が高いことになります。

![Watson-2017-01-03-14.02.jpg](https://qiita-image-store.s3.amazonaws.com/0/73831/d7ebe9eb-80c4-b5cd-1e3a-836f34aecb31.jpeg "Watson-2017-01-03-14.02.jpg")

## コマンドラインで試す

コマンドラインでは、以下のように入れて扱います。

- NLC分類器の作成

> curl -u "{username}":"{password}" -F training_data=@{CSVのファイル名} -F training_metadata="{\"language\":\"ja\",\"name\":\"My Classifier\"}" "https://gateway.watsonplatform.net/natural-language-classifier/api/v1/classifiers"

- NLC分類器の学習状況の取得

> curl -u "{username}":"{password}" "https://gateway.watsonplatform.net/natural-language-classifier/api/v1/classifiers/{classifier_id}"

- NLC分類器のテスト
	- 質問文はエンコードされている必要があります

> curl -G -u "{username}":"{password}" "https://gateway.watsonplatform.net/natural-language-classifier/api/v1/classifiers/{classifier_id}/classify?text={質問文}"

## あとがき

Conversation に引き続き、NLC をやってみました。NLC は、それほど難しくなかったです。次に、R&R をやってみたいと思います。

## 参考

書籍: [初めてのWatson](https://www.amazon.co.jp/%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AEWatson-API%E3%81%AE%E7%94%A8%E4%BE%8B%E3%81%A8%E5%AE%9F%E8%B7%B5%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E4%BA%95%E4%B8%8A%E7%A0%94%E4%B8%80/dp/4865940529/ref=sr_1_1?ie=UTF8&qid=1482120101&sr=8-1&keywords=Watson)

## 変更履歴

2017/01/03 公開
Air Hockey Robot in Hackster.io（物体認識とステッピングモーター制御）

[Air Hockey Robot - Hackster.io](https://www.hackster.io/windowsiot/air-hockey-robot-7d7a24?ref=part&amp;ref_id=9417&amp;offset=60 "Air Hockey Robot - Hackster.io")

![](https://hackster.imgix.net/uploads/cover_image/file/79578/AirHockey1200_900.jpg?auto=compress%2Cformat&w=900&h=675&fit=min)

この手の自動装置のものは <a href="https://www.youtube.com/watch?v=FCIH7mwUddE">オムロン 卓球ロボット FORPHEUS CEATEC2016</a> が有名だと思いますが、エアーホッケー版です。

カメラでエラーホッケーのパックを物体認識して、ステッピングモーター2個（x軸とy軸）を動かしてホッケーを動かします。得点などは、液晶モニタに表示させています。

このあたりの複合技も Windows IoT Core の得意とするところで、<a href="http://cmucam.org/projects/cmucam5/wiki/Teach_Pixy_an_Object_2">Teach Pixy an Object 2 - CMUcam5 Pixy - CMUcam: Open Source Programmable Embedded Color Vision Sensors</a> を使ってパックを物体認識させて、その位置にステッピングモーターで動かしています。

コードは <a href="https://github.com/ms-iot/samples/tree/develop/AirHockeyRobot">samples/AirHockeyRobot at develop · ms-iot/samples</a> にあります。
VisualStudioでＣ言語

Windows環境になると気軽ベタなＣ言語を使うことはできません。そこでちょっとメモ。
まずVisual Stduioをインストールします。Ｃ言語でコンパイルするためには、VisualStudioの命令（clコマンド）をお借りします。そのコマンドを使うために、環境変数を登録します。
まず、Ｃ言語のソースを入力して任意の位置に保存します。Ｃドライブの直下でもいいでしょう。次に、バッチファイルを作ります。
cd c:\src
%windir%\system32\cmd.exe /k "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat"
上をテキストエディタで編集し任意の名前で保存、クリックして実行します。
環境変数が設定され、clコマンドが任意の場所から実行できます。
Ｃのソースファイルをコンパイルします。
>cl helloworld.c
を実行します。コンパイルに成功すると実行ファイルが作成され
>helloworld.exe
と入力すればＯＫ。
[VBA]スタックトレース(呼び出し履歴)を使う

「呼び出し履歴」という名前がついています。英語では「Call Stack」です。
エラーの起きたプロシージャがどこから呼び出されたかがわかります。

#表示の仕方
どこかでブレークした状態で、

+ ツールバー領域を右クリックして「デバッグ」ツールバーを表示した中のボタン
+ メニューの「表示」>「呼び出し履歴」
+ Ctrl+L

のどれかで表示されます。

↓こんな感じで見られます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/133716/f7a44cbd-fa37-359d-9654-ee407d4a0440.png)
C# .NET Quadcopter in Hackster.io（ドローン製作、PID制御）

[C# .NET Quadcopter - Hackster.io](https://www.hackster.io/Biscuits24_/c-net-quadcopter-ead82c?ref=part&amp;ref_id=9417&amp;offset=37 "C# .NET Quadcopter - Hackster.io")

![](https://hackster.imgix.net/uploads/cover_image/file/132068/DSC_0098%5B1%5D.JPG?auto=compress%2Cformat&w=900&h=675&fit=min)

リアルタイム制御が苦手な Windows IoT Core と言いましたが、ドローンを作っている強者がいました。

ゲームパッドは、Logitech F710 Wireless Controller <a href="http://gaming.logicool.co.jp/ja-jp/product/f710-wireless-gamepad">F710 Wireless Gamepad - Logicool</a> を使っているそうです。PID 制御とカルマフィルタの実装あるので、倒立ロボットを作るときに参考になるかもしれません。

コードは <a href="https://github.com/tswanepoel/pilotgadgetry">tswanepoel/pilotgadgetry: C# .NET Quadcopter</a> で公開されています。
[VBA]コンパイルは実行前にした方がいいという話

VBAでは、あるプロシージャにコンパイルエラーがあっても、それが呼ばれるまで構文をチェックされないためエラーになりません。

↓例

```vbnet
Option Explicit

Sub test()
    Debug.Print "A" ' ここは実行される
    
    test2
End Sub

' test2が呼び出されたタイミングでエラー！
Public Sub test2()
    コンパイル エラー になるよ
End Sub
```

バグの発見が遅れる原因になるので、実行前にコンパイルをしたほうがいいと思います。

VBEの、デバッグ>(プロジェクト名)のコンパイル で実行できますが、頻繁に使うのでショートカットキーを割り当てておくと便利です。

まれにコンパイルしたいのにメニューがグレーアウトしていて実行できないことがありますが、そのときはコメントを一回入れて削除するなどしてコードを変更すると、押せるようになります。
[ネタ記事] 私が「部屋の」環境構築で考えていること

# 開発環境は快適であるべき
会社や職場ではシングルディスプレイですか？デュアルディスプレイですか？
BYOD出来ますか？十分なスペックがあるPCを使っていますか？開発用スマートフォンが配布されていますか？
会社に求めるものって福利厚生もありますが、エンジニアとしては開発環境が重要であると考えています。

でも、会社に開発環境を良くしてほしいと言っても声は届かないものですね。
そもそもその気持ちを理解する上長がいないからですね。

**じゃあ！！！プライベートの開発環境だけでも快適にしようじゃないか！！！**と5年前から実行しています。

プライベート開発環境は自宅ですか？それとも家を出て喫茶店等々ですか？
私は自宅派なので、部屋を快適にします。
ということで2016年9月時点の自室です。
![CsntTSqUAAE7bUT.jpg](https://qiita-image-store.s3.amazonaws.com/0/65675/4597cb43-0afa-ee94-1697-5ca373ce8306.jpeg)


プライベート開発環境を快適にすることによって何が良いのかを、私が思っている点を挙げます。

# 快適にすることによるメリット
1. 家（プライベートな空間）に帰りたくなる
2. 帰りたくなるから会社で無駄に残業しない
3. 調べものする速度がプライベートのほうがが早いので会社ではアウトプット出すことに集中する
4. X〇ideos観ながら仕事ができる

残業が減るのは会社にもメリットがある。


# 快適にすることによるデメリット
1. お金がかかる
2. 意外とスペースが必要
3. 重いものを持ち上げたりするので、普段の運動不足がたたって筋肉痛になる

お金がかかるのは間違いない。望む環境とのバランスを見て調整するしかないですね。

# 良いものを作るためではない。が、良いものを考えたい
メリットもデメリットもあります。私の給料も悪いほうですから。
だけれど私は、これからも快適な環境構築をしていきたいと考えてます。
良いものを生み出すには良いものに囲まれていなければとか甘っちょろい学生気分の社会人なんて滅びてほしいです。ひきこもり最高です。
たまには外でやる開発もオープンなところだと気持ちいいですけどね。

それに、2020年に向けてだんだんと日本もリモートワークが導入されるはずです。
どこでも仕事することになるなら、快適な環境が用意されている家で速度出せるのではないでしょうか。

でも、とにかくこれにつきます。
* **資料や書籍を置くスペースがある**
* **資料を見れる画面スペースがある**
これが満たせればいい環境だと思います。
資料も広げられないような場所でやってもかなりの非効率です。
**デザインでスペースが重要なように、仕事する場所もスペースが重要なのです。**

みなさんもそれぞれの快適な開発環境を構築しましょう。

# おまけ
2016年9月時点環境状態こちらです。
* PC3台
* ディスプレイ4枚
* ダイニングテーブル
* ベンチ
* YSP-2500

### PC3台
PCは用途で分けています、普段使いするPCとゲーム用、サーバ用です。
分けることで負担を分けつつ、ソフトウェア管理が楽ですが、ドライバ等々ばらばらで面倒です（ぁ

### ディスプレイ4枚
4枚ある理由は主にレースゲームを3画面で楽しむためです。
あともう1枚がレースゲー楽しんでる時にほかの情報もそのままで入れられるように設置しています。
開発をしているときはデュアルディスプレイ的な使い方をしています。
49インチのテレビをサンコーレアモノショップのポールで吊るしてます。

### ダイニングテーブル
IKEAのダイニングテーブル。27インチを3枚置くことを想定したらちょうど良かったので。
あと、画面とキーボードが同じ場所になることが結構普通なので、こっちのほうがすっきりすることがわかってます。

### ベンチ
オフィスチェアって寝ちゃうんですよね。あと、意味もなくぐるぐる回れる。要らないじゃないですか。
机とは逆にPCにはオフィスチェアって誰が決めたんですか。座りたいものに座りましょう。
unicoのダイニング用ベンチを使ってます。

### YSP-2500
これもゲーム用ですね、スピーカーを複数置ける部屋でもないのでサウンドバーという選択。
ちょうどディスプレイの下に潜り込ませられます。
Home Automation using Raspberry Pi 2 and Windows 10 IoT in Hackster.io （Arduinoとの組み合わせ、I2C通信）

[Home Automation using Raspberry Pi 2 and Windows 10 IoT - Hackster.io](https://www.hackster.io/AnuragVasanwala/home-automation-0dcefc?ref=part&amp;ref_id=9417&amp;offset=7 "Home Automation using Raspberry Pi 2 and Windows 10 IoT - Hackster.io")

![](https://hackster.imgix.net/uploads/cover_image/file/62262/g9328.png?auto=compress%2Cformat&w=900&h=675&fit=min)

実は、Windows IoT Core on Raspberry Pi だとリアルタイム処理には向いていません。これは CPU のクロック数の問題ではなくて、Windows や Linux という OS が機器との間に挟まっている問題です（リアルタイムOSだとこれが解決できます）。100msec単位の制御ならば Windows IoT Core でも大丈夫なのですが、10msec 単位ぐらいになると、Arduino のような組み込み用の CPU を使います。

Arduino には OS がないので機器を扱うときのタイムラグがないのですが、逆にデータを保存するためのメモリが少なかったり、それなりにややこしいコードを書かないと動かなかったります。

そこで、

- 中央制御のところに Raspberry Pi / Windows IoT Core を使う
- 各種センサーや駆動部分を Arduino を使う

という使い分けをします。それぞれのデータ通信は、I2C を使います、というのがこの「 Home Automation using ...」の主旨です。Windows IoT Core には I2C 通信用のライブラリが用意されているので、それなりに実現しやすいですよ。と言いつつ、私はまだ実装したことはないんですけど。ちょっと試してみないといけないと思っているところです。
【紹介】「検索エンジン自作入門」を読んでみて

#１．概要
「[検索エンジン自作入門](https://www.amazon.co.jp/dp/B00NUZ32MU/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)」を読んだので、簡単な内容と感想を投稿します。

![51FCcJCQTUL.jpg](https://qiita-image-store.s3.amazonaws.com/0/67649/421b54bf-8249-49c3-86f7-8b2c1154e08d.jpeg)

#２．背景
自社サービスの検索エンジンの運用を担当しており、先日、AWSのCloudSearchへの移行を実施しました。
フルマネージドサービスで提供されている検索エンジンの仕組みに興味を持ったので、購読することにしました。

#３．内容
Yahoo!Japanの検索エンジン開発チームを担当されていた山田浩之氏と，全文検索エンジンSenna／Groongaの開発に携わってきた末永匡氏による、検索エンジンの仕組みを記載した１冊です。技術的な紹介はもちろん、合わせてサンプルプログラムも紹介されているので、実装レベルで検索エンジンの仕組みを理解することが出来ます。

#４．参考になった内容
①検索エンジンのインデックス（転置インデックス）の作成方法　
　_※「第1章　検索エンジンはいかにして動くのか」参照_

検索エンジンでは、大量の文書から検索キーワードに一致した文書を返却するために、転置インデックスを作成しています。それがどのようなアルゴリズムで作成されているかについて、知識を深めることが出来ました。

②検索の高速化を実現するために　その１　
　_※「第3章　転置インデックスを作ろう」参照_

検索エンジンでは、インデックスされた文書を高速で検索して返却する必要があります。
すべてのインデックスと文書をメモリ上に乗せれないため、インデックス情報をメモリ上にのせて、文書をファイルシステムに保存します。そのため、ブロック型記憶装置での効率的データ検索に効果がある、「[B＋木](https://ja.wikipedia.org/wiki/B%2B%E6%9C%A8)」を利用して管理します。
自分の業務で、アルゴリズムを利用した開発をすることはないですが、高速化するために、
アルゴリズムを利用することが必要なときもあることを知れてよかったです。

③検索エンジンに必要な機能　
　_※「第7章　これからより深く学ぶために」を参照_

検索エンジンに必要な、文書のランキング（関連度の算出）、表記ゆれの吸収（シノニム）、ファセット、文字列処理などに関する要素を理解することが出来ました。業務で利用しているの多くのことは知っていましたが、開発する前に読めているとよかったなと思いました。

#５．総括
これから業務で検索エンジンを導入する人や、検索エンジンの理解を深めた人にお勧めです。
導入をする人は、あまりコードなどは読まずに概要だけを押さえる様にするとよいと思いました。
[VBA]クラスモジュールの中でブレークする

VBAのデフォルトの設定ではクラスモジュール（やユーザフォーム）の中でエラーが発生すると、その呼び出し元で止まります。

つまり、実際にエラーが起きた部分にたどり着くには、さらにステップ実行して、クラスモジュール内のコードを順次実行していく必要があります。

これの動作は設定で変更できます。

VBEのツール>オプションを開いて、「エラートラップ」の下の図の部分を選択します。
（日本語では「クラスモジュールで中断」です。）
![ErrorTrappingOption.png](https://qiita-image-store.s3.amazonaws.com/0/133716/7fd60894-edfc-d881-e706-09d3126ae4c5.png)

デフォルトでは、一番下の「エラー処理対象外のエラーで中断」になっているはずです。

ちなみに、その上の「エラー発生時に中断」にすると、On Error Gotoとかでハンドルしているエラーでも止まるようになります。
スライサー（FDM式３Ｄプリンタ向け）の作成　其の６（層の構成）

* [スライサー（FDM式３Ｄプリンタ向け）の作成　目次](http://qiita.com/isTwt/items/5d40286eec73296ea790)

-----

# １．はじめに
　今回は出力結果のうち、モデル本体についての構成になります。

# ２．モデルの構成
　３Ｄプリントする本体であるモデルを縦割りにした絵です。（立方体）

自作ソフト
![my-tblayers3.jpg](https://qiita-image-store.s3.amazonaws.com/0/157557/6e92c395-7323-2a23-4d79-329d6a43d1bd.jpeg)

　スライス面外周にあたるモデル外壁の厚みはループ数で指定可能で、上下面（今回の立方体の場合）の厚みは、以下で指定します。
　本ソフトでは、Print.xml内の｢Layer/topSolidLayers,bottomSolidLayers｣要素で指定します。なお、本ソフトでは、積層の分解能（レイヤー高さ）の変更による影響を受けにくい様に、積層数または、高さ(mm)で指定可能にしています。
　Simplify3Dでは、[Layer]タブの｢Top Solid Layers/Bottom Solid Layers｣で指定します。

# ２．１．外周(Outer Perimete)
　モデルの最も外側（スライス面に対し）になります。

自作ソフト
![my-layer-A3.jpg](https://qiita-image-store.s3.amazonaws.com/0/157557/8e5d2ba0-4bde-9aff-9972-6010b0f84381.jpeg)

[Simplify3D](https://www.simplify3d.com/)
![s3d-layer-A.JPG](https://qiita-image-store.s3.amazonaws.com/0/157557/07ffc85c-6690-5241-a17d-c825a6ba3261.jpeg)

# ２．２．内周(Inner Perimete)
　モデルの外側を構成するループ形状のうち外周１周を除いた部分になります。
　※スライサーによっては、内側の穴に当たる部分を内周と呼ぶこともあるようです。

　本ソフトでは、Print.xml内の｢Layer/perimeterOutlines｣要素で指定します。外周／内周を合わせた数になります。（内周は指定－１）なお、本ソフトでは、ノズルサイズの変更による影響を受けにくい様に、ループ数または、幅(mm)で指定可能にしています。
　Simplify3Dでは、[Layer]タブの｢Outline/Perimeter Shells｣で指定します。

自作ソフト
![my-layer-A4.jpg](https://qiita-image-store.s3.amazonaws.com/0/157557/95a50947-c7fd-86fc-9195-81f8d45df718.jpeg)

# ２．３．インフィル(Infill)
　モデルの内側を構成する内側になります。
　本ソフトでは、Print.xml内の｢Infill｣要素で指定します。まだ形状は１種類しかありません。
　Simplify3Dでは、[Infill]タブで指定します。

自作ソフト
![my-layer-A2.jpg](https://qiita-image-store.s3.amazonaws.com/0/157557/161f6210-f86b-b019-9c67-0674e9835eb2.jpeg)

# ２．３．１．モデルの内部
　前記絵のインフィルは、モデル内部の状態です。この場合、指定された充填率(Interior Fill Percentage)により軽量化／フィラメントの節約などの目的により肉抜きされた状態です。

# ２．３．２．モデルの外部
　下記絵のインフィルは、モデルの外側になる部分になります。この場合、インフィルの充填率は100%となります。
 
 自作ソフト
 ![my-layer-B2.jpg](https://qiita-image-store.s3.amazonaws.com/0/157557/a02772c5-f4c4-0c2d-be56-61c04831c0b7.jpeg)

[Simplify3D](https://www.simplify3d.com/)
![s3d-layer-B.JPG](https://qiita-image-store.s3.amazonaws.com/0/157557/785600b0-a6bf-6eac-0a38-d89954ae9049.jpeg)

# ６．おわりに
　前置きが長くなりましたが、次回からは、アルゴリズムの説明になります。
スライサー（FDM式３Ｄプリンタ向け）の作成　其の５（出力結果の構成）

* [スライサー（FDM式３Ｄプリンタ向け）の作成　目次](http://qiita.com/isTwt/items/5d40286eec73296ea790)

-----

# １．はじめに
　本ソフトは[Simplify3D](https://www.simplify3d.com/)をリスペクトしているため、出力結果の構成はSimplify3Dとほぼ同じです。
　”ほぼ”というのは私の認識している範囲ということですので、Simplify3Dと同じとは限りません。

# ２．ラフト(Raft)
　本ソフトでは、Print.xml内の｢Raft｣要素で指定します。また、ラフトを自動生成する他、STLファイルでオリジナル形状を指定出来ます。
　Simplify3Dでは、[Additions]タブの｢Use Raft｣によってラフトが生成されます。
 
　ラフトはモデルがベットに張り付きやすくするためと考えています。またベット上のゴミや小さな凹凸などを無視できるようなものでもあるようです。
　私はあまり利用しません。

自作ソフト
![my-raft2.jpg](https://qiita-image-store.s3.amazonaws.com/0/157557/103615cf-85b0-e08e-db1d-e5d0a063bf0e.jpeg)

[Simplify3D](https://www.simplify3d.com/)
![s3d-raft.JPG](https://qiita-image-store.s3.amazonaws.com/0/157557/f2b468ca-7295-4b9e-9a21-3524bfdacd15.jpeg)

# ３．スカート／ブリム(Skirt/Brim)
　本ソフトでは、Print.xml内の｢SkirtBrim｣要素で指定します。また、スカート／ブリムを自動生成する他、STLファイルでオリジナル形状を指定出来ます。
　Simplify3Dでは、[Additions]タブの｢Use Skirt/Brim｣によってスカート／ブリムが生成されます。
 
　スカートとブリムの差は、モデルに密着（密着するとブリム）するか否かと考えています。ただしスライサーソフトによっては、別物扱いの物もあるかもしれません。
 
　スカートは、フィラメントを吐出させるため、モデル出力前に吐き出しを行う領域で、ブリムは、モデルのベットへの接地面積を増やし剥がれにくくする目的があるようです。
　私は両方の用途でブリム（密着）を多用します。

自作ソフト：スカート
![my-skirt2.jpg](https://qiita-image-store.s3.amazonaws.com/0/157557/ceb8a4cf-742e-48bb-1673-2ff7d88c8a9f.jpeg)
自作ソフト：ブリム
![my-brim2.jpg](https://qiita-image-store.s3.amazonaws.com/0/157557/72a7fd60-00d4-b4da-de0c-c5a69a96d14c.jpeg)

[Simplify3D](https://www.simplify3d.com/)：スカート
![s3d-skirt.JPG](https://qiita-image-store.s3.amazonaws.com/0/157557/8609d112-8c5d-b874-214c-da2465df2e32.jpeg)
[Simplify3D](https://www.simplify3d.com/)：ブリム
![s3d-brim.JPG](https://qiita-image-store.s3.amazonaws.com/0/157557/0bdadccf-f05f-8ac6-b687-c2a4d87902be.jpeg)

# ４．サポート(Support)
　本ソフトでは、Print.xml内の｢Support｣要素で指定します。また、サポートを自動生成する他、STLファイルでオリジナル形状を指定出来ます。（自動生成はまだ実装途中）
　Simplify3Dでは、[Support]タブの｢Generate Support Material｣によってサポートが生成されます。
 
　サポートは、FDM式（積層方式）では下から積み上げて行く方式なため、オーバーハング部や接地しない面などがあると、空中に出力することになります。このため、サポートにより出力面の下に台をつくることになります。

自作ソフト
![my-support2.jpg](https://qiita-image-store.s3.amazonaws.com/0/157557/6844c51f-f5a0-b04b-5d4a-640102b0eeca.jpeg)

[Simplify3D](https://www.simplify3d.com/)
![s3d-support.JPG](https://qiita-image-store.s3.amazonaws.com/0/157557/8f85b869-d4e6-829c-5425-981efe67666e.jpeg)

# ５．モデル
　３Ｄプリントする本体。

自作ソフト
![my-brim3.jpg](https://qiita-image-store.s3.amazonaws.com/0/157557/21308fdf-e17d-752b-7277-9d82e03f5747.jpeg)

[Simplify3D](https://www.simplify3d.com/)
![s3d-brim.JPG](https://qiita-image-store.s3.amazonaws.com/0/157557/ad0ed229-ad93-7079-0068-73816f00a1a8.jpeg)

# ６．おわりに
　スライサーの出力結果（求める物）は、Simplify3Dを基準にしています。今後は独自の構成にするのも良いかもしれません。（まずは、既存同等を目指して）
MagicMirror in Hackster.io（鏡と液晶モニターを使った未来っぽい表示）

[MagicMirror - Hackster.io](https://www.hackster.io/Emmuss/magicmirror-cb222b?ref=part&amp;ref_id=9417&amp;offset=14 "MagicMirror - Hackster.io")

![](https://hackster.imgix.net/uploads/cover_image/file/128363/IMG_1113.JPG?auto=compress%2Cformat&w=900&h=675&fit=min)

一時期、キッチンか居間のコンピュータ化でテレビに出ていたものです。最近は Hololens のほうなヘッドマウントディスプレイ型の VR が主流ですが、モニタに鏡をのせて「未来っぽい」演出をつけることができます。

確か、でかいモニタを使って Microsoft 社がやっていたようなが気がします。

電子工作的には、特別なことをやっているわけではなくて、普通の PC でも作れるような工作です。が、PC の場合には消費電力による維持費が掛かったり、PC 自体の値段が上乗せされてしまうのですが、Raspberry Pi だと安価にすみ、消費電力が抑えられるというメリットがあります。あります...が、この場合、モニタの消費電力のほうが多いので、貢献度は低いかも。

画面を XAML で書くことができるので、ここが Windows IoT Core の最大メリットですね。
Windows IoT Raspberry Pi Sense HAT in Hackster.IoT（既存の RPi ハットを使う）

[Windows IoT Raspberry Pi Sense HAT - Hackster.io](https://www.hackster.io/laserbrain/windows-iot-sense-hat-10cac2?ref=part&amp;ref_id=9417&amp;offset=15 "Windows IoT Raspberry Pi Sense HAT - Hackster.io")

![](https://hackster.imgix.net/uploads/cover_image/file/77247/Raspberry%20Pi%20Sense%20HAT.jpg?auto=compress%2Cformat&w=900&h=675&fit=min)

Raspberry Pi で Windows IoT Core を使うときの利点は、元の Raspberry Pi のハット（あらかじめ電子工作の部品が乗っかっている基板）が使えることです。これは、Raspberry Pi Sense HAT というものを使っています。リンク切れになっているので、

[Raspberry Pi Sense Hat (element14) :RASPBERRYPI-SENSEHAT:梅本合同会社 - 通販 - Yahoo!ショッピング](http://store.shopping.yahoo.co.jp/electronics/raspberrypi-sensehat.html?sc_e=slga_pla "Raspberry Pi Sense Hat (element14) :RASPBERRYPI-SENSEHAT:梅本合同会社 - 通販 - Yahoo!ショッピング")

なところで、6,000円位しますが、加速度センサーとか LED マトリクスとかが全部はいっているので、実験としてはいいんですよね。工作するとなかなか大変ですから。でも、その「大変さ」を乗り越えるのが、<a href="https://www.amazon.co.jp/dp/B00LP8GDKW/">Amazon.co.jp: ハルロック（１） (モーニングコミックス) 電子書籍: 西餅: Kindleストア</a> まとな楽しみだったりします。そこは、目的に合わせて使い分けてください。
Plant App in Hackster.io（湿度センサー、フォトセンサー）

![](https://hackster.imgix.net/uploads/attachments/181408/CoverPhoto.JPG?auto=compress%2Cformat&w=900&h=675&fit=min)

[Plant App - Hackster.io](https://www.hackster.io/windowsiot/plant-app-1167ed?ref=part&amp;ref_id=9417&amp;offset=13 "Plant App - Hackster.io")

湿度センサー、フォトセンサーなどを使って観測データを記録する製作例です。

モニターは液晶モニタをそのまま使っていて、センサーは可動部分がないので結構楽にできるパターン...というか、Windows IoT Core の王道っぽいものです。出力を XAML を使って液晶モニタに手軽に出力できるのが Windows IoT Core のいいところです。

難点は、Raspberry Pi が HDMI でモニタに直結しているので、雨にあたるような外に置くことはできないのですが、この部分は WiFi を使うとか、有線 LAN で引っ張ってきて PC のほうのモニタで出力する方法があります。

あと、Raspberry Pi 3 のほうだと、リモート出力ができるので、これを利用するとよいでしょう。<a href="http://www.moonmile.net/blog/archives/7933">Windows IoT Core にリモートで接続する | Moonmile Solutions Blog</a> あたりを参考にしてください。
Robot Kit in Hackster.io（サーボモーターとXBOXコントローラー）

<a href="https://www.hackster.io/">Hackster.io - The community dedicated to learning hardware.</a> というモ電子工作サイトがあって、このなかに Windows IoT Core の製作物があるのでいくつか拾って紹介しましょう。

![](https://hackster.imgix.net/uploads/cover_image/file/44579/RobotDone.jpg?auto=compress%2Cformat&w=900&h=675&fit=min)

[Robot Kit - Hackster.io](https://www.hackster.io/windowsiot/robot-kit-6dd474?ref=channel&amp;ref_id=4087_trending___&amp;offset=21 "Robot Kit - Hackster.io")

# 解説

最初の Windows IoT Core が発表されたときに、サンプルとして Microsoft 社が出した作品例です。レーザーカッターで切ったボードを売ってくれれば、もうちょっと盛り上がったんじゃないかなと思うのですが、まあ、普通のタミヤのキットでも作れるでしょう。

Windows IoT Core でこの手のモバイルもの（コンセントから離れているという意味で）を作るときに問題になるのが、

- モニタの問題
- 電源をどうするか

があります。Arduino と違って起動に時間がかかる Windows IoT Core の場合、モニタがないときちんと起動しているかどうかが分かりづらいんです。別途 LED をつけるか LCD 液晶をつけるのがベターかなと（私もまだやってないのですが）。

電源のほうは、スマートフォン用のモバイルバッテリーを使うと手軽です。2,000円位でちゃんとしたものを買うか、電池式のものを買って充電式の電池を使います。ただし、サーボモーターのような駆動系が入ると電圧降下を起こして、OS ごと落ちてしまうのが難点です。

ちなみに、この Robot Kit は XBOX のコントローラーで操作するのですが、Bluetooth 方式の無線には対応していなくて（今だと可能かも）、USB ケーブルでつながっている古めの XBOX コントローラーを使う必要があります。
iOS10でアクセス許可設定しないとアプリが落ちる問題への対応

# 問題の内容
iOS10でカメラを使用するアプリをビルドして走らせると下記のようなエラーが出て落ちる。

```
[access] This app has crashed because it attempted to access privacy-sensitive
 data without a usage description.  The app's Info.plist must contain an
 NSCameraUsageDescription key with a string value explaining to the user how the 
app uses this data.
```

# 対応内容
Info.plistにPrivacyの設定を追加する

```
<dict>
<key>NSCameraUsageDescription</key>
	<string>おげほげ</string>
 
    ...
 
</dict>
```

Xcodeの編集画面からAdd Rowで追加することも可。
macOS SierraでSSH鍵のパスフレーズの件

今日SierraにアップデートしたところSSHの鍵を毎回聞くようになりました。
簡単にググったところ割とトラブルになってるようですが、海外のサイトでSSHのconfigに追加すればいいという記載があり、その通りにすればできたので、備忘録がてら。

## ssh_config

```text
man ssh_config
```
と実行し終わり頃を見ると下記のように書いてあります。

```man
UseKeychain
             On macOS, specifies whether the system should search for passphrases in the user's keychain when
             attempting to use a particular key. When the passphrase is provided by the user, this option also speci-
             fies whether the passphrase should be stored into the keychain once it has been verified to be correct.
             The argument must be ``yes'' or ``no''.  The default is ``no''.
```

追加でAddKeysToAgentも追加します。これを追加しておかないとForwardAgentが有効に動作しませんでした。

```man
     AddKeysToAgent
             Specifies whether keys should be automatically added to a running ssh-agent(1).  If this option is set to ``yes'' and a key is loaded from
             a file, the key and its passphrase are added to the agent with the default lifetime, as if by ssh-add(1).  If this option is set to
             ``ask'', ssh will require confirmation using the SSH_ASKPASS program before adding a key (see ssh-add(1) for details).  If this option is
             set to ``confirm'', each use of the key must be confirmed, as if the -c option was specified to ssh-add(1).  If this option is set to
             ``no'', no keys are added to the agent.  The argument must be ``yes'', ``confirm'', ``ask'', or ``no''.  The default is ``no''.
```

defaultが`no`のようなので`.ssh/config`に以下のように追記します。（どこでもいいと思いますが、自分は `Host *` に追加しました）

```diff
 Host *
   ServerAliveInterval 1200
   ServerAliveCountMax 12
   TCPKeepAlive yes
   Compression yes
+  AddKeysToAgent yes
+  UseKeychain yes
   GSSAPIAuthentication no
   UseRoaming no
```

## 参考にしたページ

[http://apple.stackexchange.com/questions/254468/macos-sierra-doesn-t-seem-to-remember-ssh-keys-between-reboots](http://apple.stackexchange.com/questions/254468/macos-sierra-doesn-t-seem-to-remember-ssh-keys-between-reboots)
Swift 3でDictionaryのキーだけの配列を作る

```swift
var dictionary = [
    "key1": "value1",
    "key2": "value2"
]

print(dictionary.keys)
```

↓

`LazyMapCollection<Dictionary<String, String>, String>(_base: ["key2": "value2", "key1": "value1"], _transform: (Function))` とかいうの出てきた

## `[String]`でイニシャライズすればいいっぽい

```swift
var keys = [String](dictionary.keys)
print(keys)
```

↓

`["key2", "key1"]`

:tada: （※Dictionaryでは順番は保証されません）

参考

http://stackoverflow.com/questions/32242876/array-is-unavailable-please-construct-an-array-from-your-lazy-sequence-array
SVGをお手軽に出力するならQtが最強のライブラリではないか？

PythonでSVGファイルを出力する方法を調べていたが、python最強のSVGライブラリ[svgwrite](https://pypi.python.org/pypi/svgwrite)よりも、Qt(PySide)の方がお手軽さでは最強なのではないかという結論に達した（異論は認めます）。

## SVGとは？
SVGを知らないという方はまずいないと思うが、一応説明しておく。

SVGとはベクター画像形式の代表的な形式の1つである。従来のラスター形式の画像と比べ拡大縮小してもジャギが出ないため、ウェブブラウザ等の環境により表示サイズが変動する場所でも美しい表示ができる。

## Qtを使ったSVGの出力
Qt（PySide）を使用したSVGの出力は、QSvgGeneratorを使う。
PySideでSVGを出力する簡単なサンプルを見てみよう。

```python
#! usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function, absolute_import
import sys
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtSvg import *

app = QApplication(sys.argv)

svg_gen = QSvgGenerator()
svg_gen.setFileName("hello.svg")
svg_gen.setSize(QSize(200, 80))
svg_gen.setViewBox(QRect(0, 0, 200, 80))
svg_gen.setTitle("hello svg")
svg_gen.setDescription("this is sample svg.")

painter = QPainter()
painter.begin(svg_gen)

rect = QRect(0, 0, 200, 80)
painter.fillRect(rect, Qt.yellow)

painter.setPen(Qt.blue)
painter.setFont(QFont("Arial", 30))
painter.drawText(rect, Qt.AlignCenter, "Hello SVG")

painter.end()
```
表示結果（※SVGが貼り付けられないためPNGで表示）
![g5039.png](https://qiita-image-store.s3.amazonaws.com/0/140075/9218f0b2-4e93-7208-9bce-5c30f5368f55.png)

注意点は```from PySide.QtSvg import *```でSVG関連のモジュールをインポートしている事のみ。

QSvgGeneratorにSVGの設定を入力するだけで、後はQPainterを使って従来通りの描画をするだけである。
SVGのエレメント操作などは一切していないが、これだけでSVGファイルが作成されるのだ。
（もちろん完全なSVGの変換ではない、テキストのwrapなどSVGにそもそもない機能は無視される）

ちなみにSVGの描画はQSvgWidget、またはQGraphicsSvgItemでQGraphicsViewで表示もできる。

## QGraphicsSceneからのSVG出力(2017-01-05 追記）

QGraphicsSceneからもSVG出力が可能である。

```python
scene = QGraphicsScene()

rect = QRect(0, 0, 200, 80)

scene.setSceneRect(rect)
scene.addRect(rect, QPen(Qt.transparent), QBrush(Qt.yellow))
text_item = scene.addText("Hello SVG", QFont("Arial", 30))
text_item.setDefaultTextColor(Qt.blue)

painter = QPainter()
painter.begin(svg_gen)

scene.render(painter)

painter.end()
```

QGraphicsSceneを出力できるのは大きい、QGraphicsViewでマウスなどでアイテム位置を調整し、そのままSVGに出力できるのである。
お手軽にSVGのライブプレビュー環境が出来上がるのだ。


## svgwriteへの優位性
svgwriteは柔軟性があり、非常に使いやすいライブラリである。
しかし、Qtを使った場合と比較してsvgwriteに対しての優位性を挙げていきたい。

#### svgwriteはgetBBoxが存在しない
svgwriteは良くも悪くもXMLのラッパー的な存在であるため、表示時のバウンティボックスを求める```getBBox```が存在しない。
これはテキストを扱う場合、テキストの大きさがわからないため非常に困る。

#### SVGエレメントの知識が不要
SVGを出力するのだから、エレメントに対する知識が必要なのは当然であるのだが、Qtを使えばエレメントに対する知識が一切なくてもSVGを出力できる。

#### 作成過程のプレビューが容易
プログラム上でSVGを出力する場合、トライ＆エラーが必要である。
Qtを使えばQPainterの描画がそのままSVGになるため、必然的にプレビュー環境が出来上がっているのである。
SVGに変換後もQSvgWidgetで確認ができるため、プログラムさえ組んでしまえばライブプレビューで修正と作成が同時に行える。


## SVGのバージョンについて
Qt5が扱えるSVGのバージョン1.2である、しかしPySideを使った場合Qt4.8であるのでSVGのバージョンは1.1なので注意。
PySide2が一刻も早く正式リリースされるの祈るばかりである。

## まとめ
Qtを使ったSVGの出力は非常にお手軽である。
Qtを知っていればSVGの知識がほぼなくても良いのは、SVG初心者にとっては大きなアドバンテージである。

HTML5との連携やスタイルシートの適用など、柔軟性のあるSVGの作成はsvgwriteに譲らざるをえないが、表示のみのSVGであればQtは大きな選択肢となる。

### SVGの自動生成の使いどころ
ちなみに、私はC言語の構造体を自動解析してブロック図（という名称なのだろうか？）をSVGで出力している。
BITMAPINFOHEADER構造体は以下のような図が出力される。

![g4863.png](https://qiita-image-store.s3.amazonaws.com/0/140075/f000421a-e626-0be5-76a3-691c352ecca3.png)

Sphinxなどのマニュアルに、自動生成で埋め込めばパティングなどの構造が分かるため便利である。
自分用Macの初期設定メモ

対象 macOS Sieera 10.12.2

## システム設定

### Dock

* サイズ  真ん中より左（2/8くらい）
* 拡大 真ん中より右（3/4くらい）
* Dockを自動的に隠す/表示 チェック入れる

### ディスプレイ

* 解像度を変更、スペースを拡大

### キーボード

*  入力ソースことえり削除
  * GoogleIME後
* F1、F2などのキーを標準のファンクションキーとして使用 チェック入れる


### トラックパッド

* 調べる&データ検出 チェック入れる
* アプリケーションExpose チェック入れる

### サウンド 

* メニューバーに音量を表示

### iCloud

* iCloudDrive チェック入れる
* Safari チェック入れる
* Mac探す チェック入れる

### App Store

* 無料ダウンロード: パスワードは不要

### Blutooth

* メニューバーにBluetoothを表示

### 共有

* コンピューター名を変更する

### ユーザーとグループ


### 日付と時刻

* 秒を表示 チェック入れる
* 日付を表示 チェック入れる

### Time Machine

* バックアップディスクを選択
  * アカウントが `TimeMachine` ユーザーになる

## Finder環境設定

### 一般
* ハードディスク チェック入れる
* 接続中のサーバ  チェック入れる
* 新規Finderウィンドウで次を表示 コンピューター

### サイドバー
* マイファイル チェック外す
* ムービー チェック入れる
* ミュージックチェック入れる
* {HOME}チェック入れる
* マイファイル チェック外す
* {コンピュータ}チェック入れる

### 詳細

* すべてのファイル名拡張子を表示 チェック入れる

### 表示メニュー

* ステータスバー表示
* パスバー表示
rails consoleでDB接続に失敗するようになった

備忘録。
突然？`rails console`時に以下のようなエラーが出るようになった。

``` sh
irb(main):004:0> User.all
  User Load (0.5ms)  SELECT "users".* FROM "users"
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  relation "users" does not exist
LINE 1: SELECT "users".* FROM "users"
```

環境変数に`DATABASE_URL`が設定されている状態で　`database.yml` は以下のような設定。

``` config/database.yml
development:
  <<: *default
  url: <%= ENV['DATABASE_URL'] %>
```

`rails server`や`rake task:do`では正常に接続される。
この辺で泣きそうになっていたところ、[こんな解決法](https://github.com/rails/rails/issues/19256#issuecomment-102980786)を見つけて試したらちゃんと動くようになった。

ホッ。
情報処理技術者試験　プロジェクトマネージャー　平成26年度午後１問1

#始めに
情報処理技術者試験　プロジェクトマネージャー　平成26年度午後１問1を自分なりに問題を解析した後、IPAが公表している回答のGAP解析もしてみました

#問題の解析
![image](https://qiita-image-store.s3.amazonaws.com/0/136860/7aeec2fe-cf07-d013-2857-163eafb7aabf.png)
chibi:bit(micro:bit) 加速度センサーテスト

# はじめに

chibi:bit(micro:bit)には加速度センサーが搭載されています。
単位はmGとの事ですがどのぐらいのGが測定出来るのか検索しても見つけられませんでした。
（詳しいデータシートのありかをご存知の方いらっしゃいましたら教えてください)

# 各軸の最大値の確認

![名称未設定-4.jpg](https://qiita-image-store.s3.amazonaws.com/0/44523/27525fa7-e225-0508-8e7e-e6e72e0793b0.jpeg)

のように各軸を試したところ、

- x,y軸 2048mG
- z軸 2032mG
- 絶対値 3547mG

が最大値のようでした。

ただ、なんとなく納得できないのが、仮に3軸共に2048mGとした場合、絶対値は2048*sqrt(3)≒3457になりそうな気がするのですが、違うようです。
（追記）また「入力」の「ゆさぶる」には「8g」という選択肢がありました。私が何か勘違いをしているのかもしれませんが、矛盾があるようです。

# スピード測定器には使えない...

リストバンドを作って
https://www.microbit.co.uk/blocks/lessons/the-watch/activity
子供達の野球のバットのスイングや投球の速さ、テニスのスイング測定等に使えないかと思ったのですが、すぐに最大値に達してしまうのでガチではつかえなさそうです。

グラフ表示機能を付加した絶対値表示バージョン
![名称未設定-5.jpg](https://qiita-image-store.s3.amazonaws.com/0/44523/d7b543b8-3080-27a6-100e-d68cdbb3996f.jpeg)

- Aボタンでグラフ(3547を最大値として設定)
- Bボタンで値
- A+Bボタンで最大値のリセット

にしてみました。

ビニールテープで腕につけてパンチを測定してみた動画です
[![](http://img.youtube.com/vi/ZH74bJTBflw/0.jpg)](https://www.youtube.com/watch?v=ZH74bJTBflw)
https://www.youtube.com/watch?v=ZH74bJTBflw

試しに子供にやらせてみたら、結構、楽しんで遊んでいました。
これはこれで面白いようです。
clojureでFizzBuzz


文法も何もわからなかったので大変でした…(ヽ´ω`)

```clj:src/fizzbuzz/core.clj
(ns fizzbuzz.core
  (:gen-class))

(defn fizzbuzz
  "引数が3の倍数ならFizz、5の倍数ならBuzz、
   3と5の公倍数ならFizzBuzzに変換する"
  [n]
  (cond
    (= (rem n 15) 0) "FizzBuzz"
    (= (rem n 3) 0) "Fizz"
    (= (rem n 5) 0) "Buzz"
    :else (str n)))

(defn -main
  "メイン"
  [& args]
  (println (clojure.string/join " " (map fizzbuzz (range 1 101)))))
```

##覚えたこと
関数を定義するには`defn`を使う

```
(defn [関数名] [関数の説明] [引数リスト] [戻り値])
```

関数は頭から評価されていくのか、fizzbuzz関数をmain関数の後ろに置いたらエラーになってしまいました。


比較は`=`

剰余は`rem`
cmakeでCould NOT find Libcurl (missing: CURL_LIB CURL_INCLUDE_DIR)が出て詰まった話

とあるオープンソースのプログラムのビルドにcmakeが必要だったので導入して

%cmake -DCMAKE_BUILD_TYPE=Release ..

と実行したところ
CMake Error at /usr/share/cmake-3.5/Modules/FindPackageHandleStandardArgs.cmake:148 (message):
  Could NOT find Libcurl (missing: CURL_LIB CURL_INCLUDE_DIR)

こんなエラーを吐いた

libcurlが見つからないとのことだけど

%curl -V

で見てみると
curl 7.47.0 (x86_64-pc-linux-gnu) libcurl/7.47.0 GnuTLS/3.4.10 zlib/1.2.8 libidn/1.32 librtmp/2.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets 

ちゃんと入ってる

apt-get updateとかcurl入れなおしとか試したけどうまく行かず
調べたら海外のフォーラムでlibcurl4-openssl-devを入れたら動いたって話があった

%sudo apt-get install libcurl4-openssl-dev

提案パッケージ:
  libcurl4-doc libcurl3-dbg libidn11-dev libkrb5-dev libldap2-dev librtmp-dev
以下のパッケージが新たにインストールされます:
  libcurl4-openssl-dev

libcurl4-openssl-devがインストールされたらしい

これでcmakeでのビルドに成功した
初心者のためのbundle identifier(独自ドメイン)の設定とUnity上でのトラブル

#Bundle Identifierと独自ドメイン
初心者がUnityでアプリを出そうと思うと

Androidでもiphone(iOS)向けでも 
「Bundle Identifier(iOSではiPhoneBundleIdentifier)を独自のものにしなさい」
という指示を受ける。

私のようなプログラミング初心者からすれば「職業プログラマーじゃないし趣味レベルだから知ったことではない」と言いたくなるが
よそ様に迷惑をかける可能性があると聞けば、流石にそういうわけにもいかない。

そういうわけで、独自のidentifierを用意する必要がある。
通常これは、自分の所有しているドメインを使う。

たとえば、www.dokuzi-domain.comというドメインを所有しているなら
com.dokuzi-domain.wwwという名前で設定する。

しかし、企業ならともかく趣味プログラマーが独自ドメインなど持っているわけがない。

そういう人には、以下の素晴らしい善意のサービスを感謝して利用する。
http://www.java-conf.gr.jp/
http://www.java-conf.gr.jp/Package/naming/index.html

jp.gr.java_conf.yourname

というドメインを使わせていただくことが可能になる。

#Unity上でのトラブル
ところが、このサービスを利用するとUnityで１つだけ問題に陥る。

それは、Android/iOSで以下のルールが異なるということだ。

Android : bundle identifierに ‐(ハイフン) を認めていない
iOS : iphonebundleidentifierに _(アンダーバー) を認めていない

つまり、
Android向けに作るならばjp.gr.java_conf.yourname
iOS向けに作るならばjp.gr.java-conf.yourname
と書き分ける必要がある。

Android向けを作った後にiOS向けとして移植すると
iphonebundleidentifier has not been setup correctly
といったエラーメッセージを受ける。

私はコレを知らなかったので
「com.example.wwwなら通るぞ。iOS版だとjp.grがダメなのかな？」と勘違いしてしまった。

実は単にハイフンとアンダーバーではじかれていただけ・・・。


#追記
ちなみに初歩的な質問として「bundle identifier ってどこで設定するの？」という質問がありそうなので書いておくと

(1)Unity上側メニュー File -> Project SettingsでBuild Settingsを開く
(2)下側の小さなボタンPlayer Settingsを押してInspecterビュー(画面右側にある情報画面)を切り替える
(3)Android/iOSのタブを押して、Other Settingsという項目を見たら、設定場所がある
(Android/iOSタブがないという人はUnityインストール時に、Android向け/iOS向けの追加パッケージをインストールしてないかも？）
【jasmine + Karma】 による AngularJs 単体テストをしてみた

AngularのUnitTestをjasmineで行ってみました。
環境としては、前回の
[【jasmine + Karma】 による javascript 単体テストをしてみた](http://qiita.com/TKR/items/14ab1b410614e6527633)
をベースとして、これにAngularJsを追加していこうと思います。


# 前回からの変更内容

AngularJs と angular-mocks をPackage.jsonに追加します。

注意) 
 angular-mock ではなくて、 angular-mocks 複数形なのに注意してください。 
  始め、angular-mockというものをnpm installしてしまい、ハマってしまったので共有します。

```pacakge.json
+  "dependencies": {
+    "angular": "^1.6.1",
+    "angular-mocks": "^1.6.1"
+  }
```

Karmaで読み込むJSファイルにangularライブラリを追加します。

```karma.conf.js
 files: [
 +      "node_modules/angular/angular.js",
 +      "node_modules/angular-mocks/angular-mocks.js",
        "src/script/js/*.js",
        "spec/*.js"
 ],		      
```

これで準備がととにましたので、次にプロダクトコードを作成していきます。

# プロダクトコードの作成

プロダクトコードは、demoAngular.jsとし、簡単なcontrollerとfilterを作成します。
テストは、このcontrollerとfilterについて行うことにします。

filterは、既存のnumberFilterを拡張したものを作成しました。
値が、0以上の時は既存のfilterを適応、それ以外は"-"となるようなfilterとなっています。

```demoAngular.js
angular.module('demoApp', [])
  .controller('demoAppCtl', ['$scope', function($scope) {
      $scope.name = "angular-unit-test";

      $scope.demoFunction = function(num) {
          return num * num;
      };
  }])
  .filter('numberCustomFilter', ['$filter', function ($filter) {
     return function (num) {
         if (num != null) {
             if (num >= 0) {
                 return $filter('number')(num);
             }
         }
         return "-";
     }
  }]);
```

# テストコードの作成

Angularの単体テストの場合は、まず、angular.moduleをloadを行します。

```AngularSpec.js
// load the angular module
beforeEach(module('demoApp'));
```

## Controllerのテストコードを作成

### DIのMock化を行う

Directiveについては、[inject()](https://docs.angularjs.org/api/ngMock/function/angular.mock.inject) でmock化します。

各ケースで共有してcontrollerのmockを使用するので、beforeEachでcontrollerのmock化を行います。

```AngularSpec.js
// inject angular directive
beforeEach(inject(function(_$rootScope_, _$controller_) {
    var rootScope = _$rootScope_;
    $scope = rootScope.$new();
    $controller = _$controller_;

    // $controller('コントローラ名', { injectしているDirective: mock化したDirective変数名} )
    demoAppCtl = $controller('demoAppCtl', { $scope: $scope });
}));
```


### テストケースの作成

Controllerで定義した$scopeのパラメータと関数についてテストケースを以下のように作成します。

```AngularSpec.js
it('$scope パラメータ テスト', function() {
    expect($scope.name).toEqual("angular-unit-test");
});

it('demoFunction テスト', function() {
    expect( $scope.demoFunction(3) ).toEqual(9);
});
```

# テスト実施

```
  demoAngularUnitTest
    controller test
      ✓ $scope パラメータ テスト
      ✓ demoFunction テスト
```

# おわりに

カスタムフィルターについての単体テストも作成しましたが、やり方はcontorllerと同じなので省略します。
[ソースをgithub上に公開](https://github.com/yohei-takara/jasmine-angular)しているのでそちらを見てください。
Raspberry Piでcrondは動いているのにcron.hourlyが動かない？

#問題の起きた環境
ハード：Raspberry Pi 2 Model B
OS：debian 8

#起きた問題の詳細
定期的に実行したいコマンドがあったので、`hogehoge.sh`を作成して`/etc/cron.hourly`内に配置したのですが何時間待っても、実行されないという問題が発生しました。

###とりあえず、情報収集して、以下のことは判明しました。
・crondが動作していることを確認
　→動いている。
・`hogehoge.sh`のパーミッションは755
　→実行権限はちゃんと与えられている。
・`hogehoge.sh`のシバンは`#!/bin/sh`になっているので、`/bin/sh hogehoge.sh`を実行
　→`hogehoge.sh`に記述したコマンドは実行された
　→→`hogehoge.sh`内の記述がおかしいわけではない。

以上の事から、crondは動いているのにcron.hourlyが動いてないようだと考えました。
debian8でもcronのログはデフォルトでは出力されないため以下のサイトを元にログ有効化に
[みざるきかざるいわざる Debian 6.0 (squeeze) での、cronのログ有効化](http://ikamayo2011.blog.fc2.com/blog-entry-11.html)　

cronのログを見ると、

```text:cron.log
︙
Jan  2 19:17:01 raspberrypi CRON[2321]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)
Jan  2 20:17:01 raspberrypi CRON[2337]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)
Jan  2 21:17:01 raspberrypi CRON[2361]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)
Jan  2 22:17:01 raspberrypi CRON[2377]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)
Jan  2 23:17:01 raspberrypi CRON[2393]: (root) CMD (   cd / && run-parts --report /etc/cron.hourly)
︙
```

#原因・解決策
cronのログを見て、run-partsというコマンドが何らか問題になっているのではないかと思い、ググりました。
[run-partsが認識するファイル名ではまった - うまいぼうぶろぐ](http://hogem.hatenablog.com/entry/20090331/1238456018)

debian系ではファイル名に"."が入っていると。
redhat系ではファイル名の末尾が"~"か","であると。
実行されないそうです。

ファイル名を`hogehoge.sh`から`hogehoge`に変更したところ、無事にコマンドが走りました。

##著者の所感
これまでredhat系しか使った頃がなかったので知りませんでした。
入門書などでは基礎的な知識なのかもしれませんが、基本独学なのでまったくしらずはまってしまいました。
SNS のイベントをSLACKに投稿する Serverless アプリケーションの作成


## 背景

複数の Serverless アプリケーションで SlackBot を作成していた際に、
Slack のWebhook設定等を複数のアプリケーション間で持ち回すの面倒だったので、
SNS イベントで共通化できないか、という試みを。

## Serverless アプリケーションのテストデプロイ

注意点はファイル名を dispatcher.js に設定すること。

serverless webpack を使用している場合は output 設定で出力ファイル名を調整する必要がある。

http://qiita.com/ysk_1031/items/31a21afa1a93e31a6125

## Slackにデータを送信する

SNS Trigger のLambdaイベントでは、 `event.Records`に配列形式で次のようなフォーマットのデータが送られてくる。 

````
{
    "EventSource": "aws:sns",
    "EventVersion": "1.0",
    "EventSubscriptionArn": "arn:aws:sns:xxxxxx",
    "Sns": {
        "Type": "Notification",
        "MessageId": "xxxxxxxx",
        "TopicArn": "arn:aws:sns:xxxxxxx",
        "Subject": ".....",
        "Message": ".....",
        "Timestamp": "2016-12-29T17:30:12.629Z",
        "SignatureVersion": "1",
        "Signature": "xxxxxx.....",
        "SigningCertUrl": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-xxxxxxx",
        "UnsubscribeUrl": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:xxxxxxxx",
        "MessageAttributes": {}
    }
}
````

Slack ではコレを受け取ってイベント発行すれば良い。Message の中にJSON形式で `channel` `text` `attachments` を受け取れるようにしておくと便利 

配列で来るので Promise.all などを使って効率的に処理する。

## SNS にデータを追加する

他のLambda から SNS へメッセージを発行するには TOPIC ARN の文字列さえあれば足る

`serverless.yml` に次の記述を追加して…

```
provider:
  environment:
    SLS_TOPICARN: ${env:SLS_TOPICARN}
  iamRoleStatements:
    - Effect: Allow
      Action:
        - "sns:Publish"
      Resource: ${env:SLS_TOPICARN}

```

コード側で次のような記述を加えればOK

```
const AWS = require('aws-sdk')
const sns = new AWS.SNS()

sns.publish({
    Message:"....",
    Subject: "....",
    TopicArn: process.env.SLS_TOPICARN
}, done)
```