OmniAICreator/Qiita-1.07M huggingface dataset:
springのxml configurationでファイルをstringのプロパティに入れる

最近はjava configurationが普通なのであまり困る事はないのだけど。たとえば、spring-batchをxmlで書いていて、sqlのプロパティにファイルへ外出ししたSQLの文字列を設定したい場合を考える。

### FileCopyUtils
[java - How do I load a resource and use its contents as a string in Spring - Stack Overflow](https://stackoverflow.com/questions/14022839/how-do-i-load-a-resource-and-use-its-contents-as-a-string-in-spring) に書いてあるやり方。

```xml
	<bean id="sql" class="java.lang.String">
		<constructor-arg>
			<bean class="org.springframework.util.FileCopyUtils"
				factory-method="copyToByteArray">
				<constructor-arg value="classpath:a.txt"
					type="java.io.InputStream" />
			</bean>
		</constructor-arg>
	</bean>
```

### ファイルから読み込んでstring返すクラスを作る
上はXMLですべて完結するのだがちょっと長ったらしい。なので、それをするだけのbeanを自前で作ることを考える。

```java
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.stream.Collectors;

import org.springframework.util.ResourceUtils;

public class ResourceToStringUtils {
	
	public String to(String location) throws IOException {
                ApplicationContext ctx = ...;
                BufferedReader in
                    = new BufferedReader(new InputStreamReader(resource.getInputStream(), Charset.defaultCharset()));
                return = in.lines().collect(Collectors.joining(System.lineSeparator()));

                // 2017/0/02 追記 前は下のように書いてたけど環境によってはFileNotFoundExceptionになる。
                //詳細は別途書く。かも。
                //File file = ResourceUtils.getFile(location);
                //return Files.lines(file.toPath(), Charset.defaultCharset()).collect(Collectors.joining(System.lineSeparator()));


	}
}
```

springのlocationを受け取ってそのファイルの中身をすべて読んで文字列をして返すだけのクラスを作る。

```xml
<bean id="resourceToStringUtils"
  class="kagamihoge.hogehoge.ResourceToStringUtils"></bean>

...
<property name="p" value="#{resourceToStringUtils.to('file:hoge.txt')}"></property>
...
<property name="p" value="#{resourceToStringUtils.to('classpath:foo.sql')}"></property>

```
VideoPlayerにスクリプトで音をつけたい

[VideoPlayerで動画再生](http://qiita.com/gshirato/items/1500f61b408e7af69453)の続き

[http://justcode.me/unity2d/how-to-play-videos-on-unity-using-new-videoplayer/](http://justcode.me/unity2d/how-to-play-videos-on-unity-using-new-videoplayer/)←こちらとかを参考に

##スクリプト

*最低限スクリプトで必要なところだけ(基本は前回記事参考)*

```csharp:Video&Audio
VideoPlayer videoPlayer;
AudioSource audioSource;
VideoClip videoClip;
videoPlayer = camera.AddComponent<VideoPlayer>();
//動画読み込み
videoClip = Resources.Load(__path) as VideoClip;
audioSource = gameObject.AddComponent<AudioSource>();

//下の2つは念のための程度の設定です
//AudioのOutputModeを選択
vp.audioOutputMode = VideoAudioOutputMode.AudioSource;
//audioTrack[0]を有効に
videoPlayer.EnableAudioTrack(0,true);

//audioSourceにaudioTrack[0]を設定？？
videoPlayer.SetTargetAudioSource(0,audioSource);
//コレが最後に来るのが大事(直感)
videoPlayer.clip = videoClip;

//再生
videoPlayer.Play();
```

##疑問

動画には音声ファイルがトラックとして含まれていて、そのトラックをaudioSourceに代入し、あとでaudioSourceを同時再生するのかなと思っていました。

事実[ソース元](http://justcode.me/unity2d/how-to-play-videos-on-unity-using-new-videoplayer/)(上記リンクと同じ)では`audioSource.Play()`を動画の再生と同時に行っていたのですが、実際にはその部分がなくても再生可能でした。

可能性として考えているのは、クリップを入れる前に`VideoPlayer.SetTargetAudioSOurce(0,audioSource)`などで動画のセッティングをし音声を受け容れる態勢を整えなければいけないということです。この場合audioSourceの何のために感がすごいですが。

##とりあえず

*音　出　る*

下の二行の順番は大事そうです。


>videoPlayer.SetTargetAudioSource(0,audioSource);
>videoPlayer.clip = videoClip;

具体的根本的に解決するために精進します。



##HoloLens開発記事一覧
[こちら](http://qiita.com/gshirato/items/6c026f2c67dc332f829b)から
Twitterのアカウントロックの謎

※おことわり この記事は2017年6月ごろの状況で描いてあるため、仕様の変更等でかわることがあります。またアプリ等で異なる場合があります。

#Twitterの使用環境
Win10 + Firefox
#アカウントのロック画像
なんでもツィートがツィッターのルールに違反しているということで、不徳の致す限りである。
![2017-06-23.png](https://qiita-image-store.s3.amazonaws.com/0/126919/a49f66a0-9872-e8b3-94b7-c7869b43a3ac.png)
>
問題の詳細
ご利用のアカウントはTwitterルールに違反していることが確認されたため、一時的に機能が制限されています。この状態でもTwitterを参照できますが、ダイレクトメッセージを送信できるのはフォロワーのみです。ツイート、リツイート、いいねはできません。詳細はこちら。次の期間、Twitterの機能が制限されます: 12 時間と0 分.

この12時間ロックというルールは今年の2月からのようだ
Published: 13:23 BST, 16 February 2017
[Twitter's time out: Site's new tool BLOCKS users for 12 hours for abusive behaviour - Mail Online](http://www.dailymail.co.uk/sciencetech/article-4230460/Twitter-blocking-users-12-hours.html)
http://archive.is/UWCzE
英語版の記事では単語で縛りをかけているようだ。比較的わかりやすい。もっとも伏字になっているのでどういう単語なのかはわからない。日本語よりは明確なようだ。

###日本語版ヘルプでは
>***アカウントがTwitterルールに違反している可能性があることを理由に制限された場合***

>Twitterルールに違反している可能性があることを理由にアカウントが制限された場合、引き続きTwitterを利用できますが、フォロワーにダイレクトメッセージを送ることしかできません。ツイート、リツイート、いいねなどを行うことはできず、あなたの過去のツイートを見ることができるのはフォロワーのみになります。*1

>制限された状態を解除する前に、所定の対応を行うようお願いすることがあります。お願いする対応としては、メールアドレスの認証、アカウントへの携帯電話番号の追加、Twitterルールに違反しているツイートの削除などがあります。*2

>アカウントを復元する場合は、ログインしてアカウントの一部の機能が一時的に制限されていることを知らせるメッセージを見つけます。[スタート] をクリックまたはタップし、手順に沿って必要な対応を行ってください。注記: Twitterルールの違反を繰り返す場合は、アカウントを永久凍結することがあります。*3

*1についてはロック後もいいねなどの通知がくるので見えているようだ。ようだというのはアカウントが１つしかないのでわからないからである。

*2実際に上記の画像のように削除の指示がある。最初は携帯電話番号の追加があったがそれは消えたようだ。

*3メールによってリンクに入ると確かに上のような画像になる。当初と違うのは℡番号の追加がないことくらいである。12時間ルールの時間は短くならない。

#制限どころか実質的に凍結
###理由1
おそらく上記の画像の「始める」を押さないと携帯電話番号の登録、ダイレクトメッセージ、ツィートのブラウズができないようだ。というのも写真をクリックしてもヘルプとログアウトしか表示されないからだ。
よって携帯電話番号を入力しろと言われてもツィートを削除しようとしてもボタンが押せないため、絶対に操作が不可能なのである。ブラウザの設定が原因としてもほかのサイトのボタンは押せるので設定が原因とはいいがたい。

###理由2　メールのやり取りが不毛で通常は断念するレベル
件名：ご利用のTwitterアカウントはロックされています	
こんにちは、[HN]さん 
ご利用のアカウント[@アカウント名]はロックされています 
Twitterにアクセスしてアカウントの問題を解消してください。 
Twitterへ       ボタン画像

ボタン画像をクリックすると上記画像ページへ行く。

件名Case# 番号: Appealing a locked account - [@アカウント名]   [ ref:_番号:ref ]
ご利用ありがとうございます。
ご利用のアカウントは、Twitterルール（https://twitter.com/rules）、具体的には攻撃的な行為に関するルールに違反したため、ロックされるかご利用が制限されます。
 よろしくお願いします。
Twitter

とにかくボタンが押せないということをいくら書いてもこのような自動応答しか返ってこないのである。

さらに英語のメールも来る。異議申し立てのせいだろうか
RE: Case# 番号: Appealing a locked account - [@アカウント名]  [ref:番号.番号:ref]
Hello,

Your account features will remain locked or limited for the allotted time due to violations of the Twitter Rules (https://twitter.com/rules), specifically our rules around abuse.
Thank you,

Twitter 

早速次のように返信をした（英語で）
こんにちは。サポート感謝します。
しかし、ボタンが押せないのでツィートを削除できません。
今日本語の人間のサポートが必要です。

このように英語と日本語で交互に来るメッセージに返信しても何も返ってこない。返ってくるメッセージは自動返信で意味が分からない。制限とツィッターは言っているが事実上なにもできないのでロックというか凍結に近い。（ツィートは他人は見られるが）。日本語や英語でメッセージがやってくる上に微妙に意味が異なっており、ユーザーは混乱を来たしてしまう。

###まとめ（現段階）
とりあえずツィッターでルール違反をしてしまったのはよくないが、なにがルール違反かもわからないし、スタートボタンも押せないため操作が不可能、メールを送っても自動返信でわけがわからない、という状態で、普通はあきらめるのが常識的な態度と思われる。しかし技術的にボタンがクリックできないのでは話にならないので、引き続き調査を行う。
仮想ゲストOSにコンテナのLXDを選ぶ理由

どのようにサーバOS環境を作るかは、システム戦略で非常に重要です。
正しい選択をすることによって、システムの信頼性が高くなり、コストをかなり抑えることができます。
作業効率・スピードが全然違ってきます。


#LXDとは

- LXD（レックスディーまたはエルエックスディー）と読みます。
- LXDはKVMやXenの代わりになるシステムコンテナです。
 - コンテナで有名なDockerは、１アプリケーションを起動させることを目的としたアプリケーションコンテナと呼ばれています。

<br>

- 簡単にOSのコピーができます。 
  - `lxc copy 元コンテナ 新コンテナ`  #Macアドレスは自動で変わります。
- コンテナをイメージ化できます。
  - `lxc publish コンテナ名 --alias イメージ名`
- OS状態を残しておくスナップショットも簡単です。
  - スナップショットをイメージ化することで、OS停止なくイメージ化できます。
- 別ホストに仮想ゲストOSを移動させるライブマイグレーションも可能です。
- コンテナごとにCPU使用率、メモリー使用量、IO負荷制限ができます。


#KVMやXenやVMwareのハイパーバイザーではなく、LXDコンテナの理由

- LXDは起動が高速です。
- LXDはスナップショットやクローンのバックアップが高速で実現できます。
- ハイパーバイザーのようなオーバーヘッドがありません。
- LXDは事前にリソースを割り当てておく必要がありません。★
  - LXDは、HDD50GB、CPU 4Core、メモリー4GB を割り当てようという設計不要です。
  - 開発からかなりのハイスペックを言われても、実際に使った分しか消費されません。
  - LXDは、使い過ぎたら困る場合に、リソース制限をするだけです。
- CPUやメモリーやHDDの増減が、制限を変更するだけなのでOS停止は不要です。★
- 高機能な有料版VMwareは、非常に高額です。LXDなら無料です。
- LXDなら、CPUやメモリーやHDDのリソースを変更するために、OS停止が必要ということはないです。

#Dockerコンテナではなく、LXDコンテナの理由
アプリケーションコンテナのDockerは、LXDの上で動かします。DockerとLXDは利用目的が違うと考えています。

- Dockerと違い、LXDは、KVMやXenの代わりに使えます。
- Dockerと違い、LXDは、アプリケーションの変更が不要です。
- LXDと違い、ブリッジ接続が簡単にできます。
- LXDなら、スナップショット、イメージ化、ライブマイグレーションができます。★
- LXDと違い、ポート変換やiptablesは不要にできます。
- Dockerのように、IPとポートの組み合わせでコンテナ間を接続するのは、リプレースとしては非常に難しいです。
  - 仮想ホストしかルーティングできなかったり、FWのグループという概念がなくなります。
- LXDには、Dockerのように、1コンテナ１プロセスにするべきというベストプラクティスはありません。
- LXDには、コンテナにデータは保存しないべきというベストプラクティスはありません。

#LXCではなく、LXDを使う理由

- LXCの機能強化版が、LXDです。
  - `LXC + 現代的機能 = LXD`
- LXCでできることは、LXDでもできる。
- LXDはライブマイグレーションができる
- 複数ホストのコンテナを管理できる。
- 今から新しくコンテナを導入するなら、LXD


#ベアメタル(物理サーバ)ではなく、LXDコンテナの理由

- LXDなら、サーバ構築依頼がきても、1ヶ月待ってくださいということがないです。★
  - LXDなら、今ある環境に作ることによって、すぐにサーバを引き渡せます。
- OSが停止してしまう問題が起きてしまった時にもゲストOSを別のハードにもっていけますので、ハードが問題かソフトが問題かの切り分けができます。
- LXDにすることによって、数十個の仮想ゲストコンテナを動かせます。
  - 圧倒的にコスト圧縮できます。
- １ホストで、１サーバ分のCPU、メモリーを使い切れるアプリケーションはありません。
  - LXDにすることによって、余っているリソースの有効活用ができます。
- 物理サーバはかなりの場所をとりますが、LXDなら節約できます。
- LXDなら、必要なディスクサイズ、CPU、メモリーを正確に算出する必要はありません。
  - 想像以上に使っても、使われなくても問題ありません。
- LXDはリソースの設計ミスがありません。 
  - リソースが余っていたら、もう１つ仮想ゲストを作ればいいだけです。
  - リソースがひっぱくしたら、別の仮想ホストに移動させればいいだけです。
- LXDは起動が高速なので、何か問題が発生している際にも、プロセスを再起動する感覚で、OS再起動できます。★


#AWSなどのクラウドではなく、オンプレのLXDコンテナを使う理由

- ソフトだけでなくハードも含めて最適化ができる★
- 優秀なエンジニアがいればクラウドよりすごいことがしやすい★
- オンプレでLXDを使うことによって、クラウドよりかなり費用が抑えられます。
- オンプレのLXDなら、要求に応じて、高可用性物理サーバを使えます。★
- LXDなら、CPUやメモリーやHDDのリソースを変更するために、OS停止が必要ということはないです。
- LXDは、ゲストOSが起動したまま、別のホストに移動させるライブマイグレーションができます。
  - OS停止しないで、ホストのメンテナンスが可能です。
- LXDは、OS作るのが、数秒です。
- LXDは、OS起動も一瞬です。
- LXDは、スナップショット、イメージ化、コピーも数秒です。
- LXDは、物理設計による高速化、高信頼性が可能です。
  - 例えば、お互いに通信が多いWebとAPは同じホストに配置する。
  - 例えば、2台構成のサーバは、1ホストが故障しても問題ないように、別のホストに配置する。


#LXDを使うために注意すること

- 仮想ホストは、Ubuntuにしましょう。CentOSやRHELでは動かないと考えた方がよいです。
  - Ubuntuの開発元のCanonicalがLXDを開発しているので、Ubuntuがもっともテストされている環境になります。
- 仮想ゲストは、Ubuntu以外にも、日本でユーザの多いCentOSやOracle Linuxもあります。
- 仮想ゲストにRHELはないです。CentOSを使いましょう。
- 仮想ゲストにWindowsは使えないです。Windowsを使いたい場合は、同じホスト上にKVMで動かしましょう。
- １サーバに数十コンテナをのせるということは、サーバが故障した時の影響が大きいです。
  - しっかりコンテナの配置を考えましょう。
  - 要求に応じて、できる限り壊れにくいサーバ、ファームアップデートなどで停止が少ないサーバを選びましょう。
Swiftでのエラー、Type ‘ViewController’ does not conform to protocol ‘UITableViewDataSource’

Swiftでのエラー、Type ‘ViewController’ does not conform to protocol ‘UITableViewDataSource’の解決方法です

Swiftで、TableViewControllerを利用して、新しく対応クラスを作成し、編集して行く時ですが、
デフォルトで組み込んである、2つのメソッドを正しく書かないと、このエラーが出ます

ここまではいろんなサイトに書いてあります

が、


その後の細かい注意点が、ほとんど日本語情報がないので書いておきます


<h1>「コピペだと上手くいきません
直打ちで打ち直して、出てくる候補をクリックして、きちんと打ち直してください」


以上です


おそらく必須メゾットに関しては、細かい察知機能があるんじゃないでしょうかね
Squeak SmalltalkでMinesweeperを500文字プログラミングしようとして挫折した

恒例のシリーズ第三弾。

- [KotlinでMinesweeperを500文字プログラミングしようとして挫折した](http://qiita.com/enu7/items/a8747835d1be02c22e0c)

今回はテンプレに従い、ちゃんと(?)挫折しました。ｗ　アルゴリズムも @enu7 さんのをほぼ踏襲したので直訳版も省略。^^;

```smalltalk
| out H W X map input bombs check |

out := Transcript.
H := W := X := 10.
map := (Array new: H withAll: (String new: W withAll: $.)) deepCopy.

input := [:msg |
   out cr; show: msg.
   (FillInTheBlank request: msg) ifEmpty: [^self] ifNotEmpty: [:ans |
      out show: ans.
      ans asInteger]
].

bombs := Set new.
X timesRepeat: [bombs add: W atRandom @ H atRandom].

check := nil.
check := [:pos |
   (pos >= (1@1) and: [pos <= (W@H)] and: [((map at: pos y) at: pos x) = $.]) ifTrue: [
      | count |
      count := (bombs intersection: pos eightNeighbors) size.
      (map at: pos y) at: pos x put: count asHexDigit.
      count = 0 ifTrue: [pos fourNeighbors do: check]
   ]
].

[:exit |
   [(map concatenation occurrencesOf: $.) > X] whileTrue: [
      | x y |
      x := y := 0.
      out cr; showln: map asStringWithCr.
      [x between: 1 and: W] whileFalse: [x := input value: 'x? '].
      [y between: 1 and: H] whileFalse: [y := input value: 'y? '].
      (bombs includes: x@y)
         ifTrue: [out cr; showln: 'BOM!'. exit value]
         ifFalse: [check value: x@y].
   ]
] valueWithExit.

bombs do: [:pos | (map at: pos y) at: pos x put: $*].
out cr; showln: map asStringWithCr
```

```
..........
..........
..........
..........
..........
..........
..........
..........
..........
..........
x? 1
y? 1

0000000000
1100011100
.10001..11
11001.....
00001.....
00001.....
111001....
..1001....
11101.....
00001.....
x? 10
y? 4

BOM!

0000000000
1100011100
*10001*.11
11001....*
00001*....
00001.....
111001**..
.*1001....
11101.....
00001**...
```

</br>
Smalltalk、特に無駄に API が充実している Squeak Smalltalk のよいところは、仕様をそれっぽくコードに書き下すことができるところ。

```smalltalk
bombs := Set new.
X timesRepeat: [bombs add: W atRandom @ H atRandom].
```

とか、

```smalltalk
count := (bombs intersection: pos eightNeighbors) size.
```
```smalltalk
count = 0 ifTrue: [pos fourNeighbors do: check]
```

とか、ほれぼれしませんか？　そうですか、しませんか。　はい…。
TravisでAndroidNDKを使っているプロジェクトをビルドする

TravisCIでAndroidNDKをビルドする必要に迫られてそれなりにハマったのでそのメモになります
できるのであればNDKを使うのはやめた方がいいですが、政治的に使わざるを得ない、レガシーを使っているから仕方ない、など抜き差しならぬ事情に追われている方達にお送りします

# 失敗パターン

適当にググると下記が出てきました

https://github.com/googlesamples/android-ndk/blob/master/.travis.yml

なんかけったいなところからNDKを落としています、嫌な予感がします
他にもいろいろスクリプトを実行したりいろいろやったりしてみましたが、リンカのエラーやら何かしらのエラーが発生して、 `.travis.yml` は複雑化していくもの、正しくビルドできなかったという悲惨な結果でした

# 成功パターン

部分的にですが、うまくいった例を掲載しておきます
androidなんですが、MacOSXでビルドするためにlanguageを `objective-c` にしているのがミソです
これによって `brew install` が使えるようになり、シンプルかつ最大限安全にAndroidNDKをCI環境に入れ込むことができます

```　.travis.yml
language: objective-c
sudo: true
cache:
  directories:
    - $HOME/Library/Caches/Homebrew
before_install:
  - brew update
  - brew tap caskroom/cask
  - brew install caskroom/cask/android-sdk caskroom/cask/android-ndk
  - export ANDROID_HOME=/usr/local/share/android-sdk
  - export ANDROID_NDK_HOME=/usr/local/share/android-ndk
  - sdkmanager --package_file=[sdkmanagerのドキュメントを参照して依存を書いたファイルを指定して下さい]

```
WindowsのAlt空打ちで日本語入力

# WindowsのAlt空打ちで日本語入力

[karakaram-blog](http://www.karakaram.com/alt-ime-on-off) さんの alt-ime-ahk.exe を便利に使わせていただいていました。でも、Firefox 54.0 から 動作しない。悪夢のようです。IME.ahkをいじりましたが、できない。
だれか、やり方わかる人教えてください。

# とりあえず簡単な解決策

* MS-IMEのONを F15に割り当てる。
* MS-IMEのOFFを F16に割り当てる。
* alt-ime-ahk.ahk の `IME_SET(0)` を `send {F16}` に。
* alt-ime-ahk.ahk の `IME_SET(1)` を `send {F15}` に。

だれか修正していただけるまで、これで乗り越えます。
Firefox 使う人少ないですかね。
vCSA 6.x で Web Client からアラームアクションを設定するとメールアドレスのTLDにlocalの文字列が含まれると設定ができない

タイトルが長いですがタイトル通り。

>※2018年3月3日追記
>vCenter Server 6.5 1dのリリースノートで解決された問題と思われます。
>
>https://docs.vmware.com/jp/VMware-vSphere/6.5/rn/vsphere-vcenter-server-65u1d-release-notes.html
>vSphere Web Client のアラーム設定ウィザードの [メール アドレス] フィールドで、特定のトップ レベル >ドメインを指定できない
>vSphere Web Client のアラーム設定ウィザードの [メール アドレス] フィールドには、5 文字のトップ レベル ドメイン、または 7 文字以上のトップ レベル ドメインを持つメール アドレスは指定できません。指定できるのは、トップ レベル ドメインが 2 文字、3 文字、4 文字、および 6 文字のメール アドレスのみです。これは、Flex アプリケーションによるメール アドレスのデフォルト検証です。admin@example.systems や admin@example.services などのメール アドレスは入力できません。
>
>本リリースで、この問題は修正されました。

## 環境
vCenter Server Appliance 6.5(build-5705665)


## 現象
検証環境のドメイン名を mylab.local としています。

Web ClientからvCenter Serverのアラームアクションを設定しようとしました。
アクションとして[通知電子メールの送信]を指定し、宛先メールアドレスのTLDに "local" が含まれるメールアドレスを
指定すると"メールアドレス****@mylab.local"が無効ですと言ったエラーが出力されて、宛先に指定できませんでした。

<img width="480" alt="ドメイン名がlocal.png" src="https://qiita-image-store.s3.amazonaws.com/0/150727/c8d6a251-62a7-b205-9c78-1e6301189c3d.png">

tld は "local" だけではなく、"hogelocal" や "localhoge" のような文字列の中に local を含むとこのようなエラーが出ます。

vCSA 6.0 での同じ現象を確認しました。
また、vCSA 6.0 の場合vSphere Client（C#版）で試すとこのようなエラーは出ませんでした。
（実際にメールが送信できるかどうかまでは未確認）

## 対処方法
VMwareのKBとかコミュニティを見ても回避方法は見つけられず、、、
とりあえず mylab.test というドメイン名でメールが送信できるようにして回避しました。
laravel-ide-helperがLaravel5.4で動いてくれない時

どうも。最近typoが多くて困ってるh1y0r1nだよ。
laravel書いてるんだけど、magic methodを補完してくれないんだよね。
scopeActiveとか書いてるとき、scorpActiveって書いてて30分詰まった結果、なんとか保管する方法を探すことにしたよ。

# laravel-ide-helperとの出会い
https://github.com/barryvdh/laravel-ide-helper 
こんなのを見つけて、流し読みで設定を終わらせた。<-原因

# 結果動かない。
そうだ、@attakei先生に聞いてみよう。

# 翌日、プルリクが来た。

```composer.json
"post-update-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postUpdate",
            "php artisan clear-compiled",
            "php artisan ide-helper:generate",
            "php artisan ide-helper:meta",
+           "php artisan ide-helper:models -N",
            "php artisan optimize"
        ]
```

scopeActiveを書いてるModelでmagic methodの補完をしたい場合は


```
php artisan ide-helper:models -N
```
を実行して_ide_helper_models.phpを生成する必要があった。

ちなみに-NオプションはPhpDocを書き込まない-nowriteオプションだから、日本語コメントとかをDocに書いてる時はつけておかないと消えるみたいだよ！

それでは良いTypoライフを！


special thanks @attakei
mysqldump: Got errno 28 on write

# はじめに
mysqldumpをしていたところ`mysqldump: Got errno 28 on write`というエラーでdumpが止まってしまいました。。。。

少し調べてすぐ原因がわかりました。。。容量が。。。

```bash:
$ df -h
Filesystem          サイズ  使用  残り 使用% マウント位置
/dev/mapper/mysqlvg-sysmte
                       30G   30G     0 100% /
```

# 原因
dumpしているディスクがフルになった場合に発生。

# 対処
・不要なファイルがあれば削除して頑張って容量を空けましょう。
・容量に余裕のある他のサーバを使ってdumpしましょう。
・ボリュームの追加をしてあげましょう。

# おわりに
検証で利用していたサーバーであったため、あまり空き容量を意識してませんでした。
ですがディスクフルにするなんて絶対やってはいけないことです。自分への戒めも兼ねて。
cakephp2のHasAndBelongsToManyでjoinTableだけでwithを指定しないとbeforeDeleteやafterDeleteが効かない

habtmの削除でjoinTableを指定して、withを指定しないとAppModelのdelteが呼び出されます。そのためbeforeDeleteとafterDeleteを通りません。

Model::_deleteLinks()
https://github.com/cakephp/cakephp/blob/2.x/lib/Cake/Model/Model.php#L2797

```php
/**
 * Cascades model deletes through HABTM join keys.
 *
 * @param string $id ID of record that was deleted
 * @return void
 */
	protected function _deleteLinks($id) {
		foreach ($this->hasAndBelongsToMany as $data) {
			list(, $joinModel) = pluginSplit($data['with']);
			$Model = $this->{$joinModel};
			$records = $Model->find('all', array(
				'conditions' => array($Model->escapeField($data['foreignKey']) => $id),
				'fields' => $Model->primaryKey,
				'recursive' => -1,
				'callbacks' => false
			));

			if (!empty($records)) {
				foreach ($records as $record) {
					$Model->delete($record[$Model->alias][$Model->primaryKey]);
				}
			}
		}
	}
```
TwilioのFunctionを使った機能の実装


TwilioのFunctionは電話番号を購入した後でしか使えませんが、サーバーを自作する必要が無いので簡易なシステムを素早く作る事ができます。
今回は簡単に作れるHelloWorldを作ってみます

### 準備 ###
１）電話番号を購入する
２）[メニュー]→[Runtime]→[Function]を選択する。
３）Functionsからプラスを選択、[+Blank]を選択し、Createを押す

![Untitled01.png](https://qiita-image-store.s3.amazonaws.com/0/142008/af09922f-630f-8ae7-b733-da95c66d28da.png "Untitled01.png")

　PropertiesのFunctionNameを「HelloWorld」とする
　Pathに「/helloworld」と設定
　
　ConfigurationのAccess Controllの「Check for valid Twilio signature」をチェックし、
　EVENTをIncoming Voice Callsとする
　コードは以下のコードを記述し、Saveを選択
　成功すればコードがDeplyされる

　　![GroupHelloWorld.png](https://qiita-image-store.s3.amazonaws.com/0/142008/30cab124-ce40-9c1f-15f0-049cac4ff5bf.png "GroupHelloWorld.png")


```HelloWorld
exports.handler = function(context, event, callback) {
	let twiml = new Twilio.twiml.VoiceResponse();
	twiml.say("Hello World");
	console.log("Debug:Hello World");
	callback(null, twiml);
};
```

### 電話番号にFunctionを設定 ###

メニューから電話番号を選択し、Functionを設定したい電話番号を選択
A CALL COMES INをFunctionにし、Select a Functionから今作成したHelloWorldを選択する

![Group04.png](https://qiita-image-store.s3.amazonaws.com/0/142008/196d6140-44f1-604b-3ee0-f67fed7d6166.png "Group04.png")

指定した電話番号に電話をかけて動作をチェックする。
「Hello World」と聞こえて電話が切れれば成功

Functionの実装によりサーバーレスでシステムが組めるようになりました。
大規模なシステムであれば外部サーバーを作成しそちらで処理をするのが定石とは思いますが
Twimlで作業していた程度の事は、これで事足りると思います。
TwimlのコードをFunctionに実装するメモとして内容を追加していきたいと思います。

あくまで自分メモなのでコードの改善などありましたら　ご指摘いただければと思います。

- - -

参考までに公式リファレンスよりTwiML動詞の一覧をメモします

|動詞      |説明             | 詳細 |
|:--------|:---------------------------|:-----------|
| Say     |テキストを読み上げます          |         |
| Play    | 発信者に音声ファイルを再生します |       |
| Dial    |通話に参加者を追加します         |   |
| Record  | 発信者の声を録音します         |   |
| Gather  | 発信者がキーパッドでダイヤルした数字を収集します |   |
| Sms     | 通話中に SMS メッセージを送信します |   |
| Hangup  | 通話を終了します              |   |
| Queue   | 発信者をキューに追加します      |   |
| Redirect| コールフローを別の TwiML 文書へリダイレクトします |   |
| Pause   | 次の指示を実行する前にポーズを挿入します |   |
| Reject  | 着信通話を拒否します。通話は課金されません |   |
| Message | MMS もしくは SMS メッセージに返信します |   |
PhpStormを日本語化したい 2017初夏

#UPDATE (2017.10)
↓の日本語化がベストだと思いますので、こちらをご参照ください。

- https://www.willbrains.jp/page/4

#以下、昔のやりかた

##はじめに
個人的にはとっくに日本語化して使ってましたが、部署にPhpStormを布教する一環で、selfishまとめ。

##必要なもの
- PhpStorm
- 日本語化リソースファイル

##やり方
###日本語化リソースファイル
有志の方が翻訳された日本語リソースファイルがgithubにあるので、見つけましょう。

今回はこちらを利用させていただきました。
https://github.com/2ch774/IDEA_resources_jp


### buildのためにgradleをインストール
```
brew install gradle
```

### git clone
```
cd ~/hoge
git clone https://github.com/2ch774/IDEA_resources_jp.git
```

### build
```
cd IDEA_resources_jp
gradle build
```

### PhpStormにコピー
build/libs/resources_jp.jarが出来てるので、PhpStormの `Contents/lib/` にコピー

```
cp build/libs/resources_jp.jar /Applications/PhpStorm.app/Contents/lib/
```


### PhpStormを再起動
すべて保存して再起動しましょう。
以上。


## Windowsは?
知らん

##参考
- http://raichel.hatenablog.com/entry/2016/09/21/003151
デストラクタで Regex.Replace を使ってはいけない

すごくレアケースですがハマったのでメモ。


## やったこと

メモリリークの疑いがあったので調査の過程でデストラクタに警告ログを出した。

```csharp
public class SomeClass : IDisposable {

  // GC発生時にこちらで回収された
  ~SomeClass() {
    // ログ出力の自作クラス、内部で自作のロガーに警告ログを転送している
    FinalizeLog.Warning(nameof(SomeClass));
    Dispose(false);
  }

  // ロジックのバグで呼ばれなかった
  public void Dispose() => Dispose(true);

  void Dispose(bool disposing) {
    ...
  }

}
```


## 何が起きたか

- `FinalizeLog.Warning` の呼び出しで `InvalidOperationException` で落ちていた。
    - ロガー内でログの改行整理のために `Regex.Replace` を利用していた。

```
 場所 System.WeakReference.set_Target(Object value)
 場所 System.Text.RegularExpressions.Regex.Replace(String input, String replacement, Int32 count, Int32 startat)
 場所 System.Text.RegularExpressions.Regex.Replace(String input, String replacement)
 場所 System.Text.RegularExpressions.Regex.Replace(String input, String pattern, String replacement)
```

## 原因

- `Regex.Replace` 内で通る `SharedReference` では内部で `WeakReference` を使用している。
    - Replace処理のパーサーキャッシュを保持
- ファイナライザでWeakReference内のインスタンスが破棄されているので、新しいReplaceのパーサーを作成してキャッシュする。
    - `WeakReference.set_Target` が呼ばれる。


- [WeakReference.Target プロパティ](https://msdn.microsoft.com/ja-jp/library/system.weakreference.target(v=vs.110).aspx)
    - 例外
        - `InvalidOperationException`

> The reference to the target object is invalid. This exception can be thrown while setting this property if the value is a null reference or if the object has been finalized during the set operation.

----

ちゃんと読めば書いてあるけど、RegexがWeakReference使ってるとか普段意識しないですよね(ㆁωㆁ;)
Pepperが歩いたわ！ 〜SLAMトレーニングに行ってきた〜


ソフトバンクロボティクス主催の、「SLAMトレーニング」に出て、Pepperの自律歩行をちょっとだけかじったので私に分かる範囲でまとめ。

# 前提
書いてる人の属性

- Pepperアプリの開発はするけど、モーションとかは殆ど触ってない
- もちろん歩かせたことなどない
- でも本当は「ロボットは移動してなんぼだよね」と思っている

# トレーニングの内容
SoftBank Robotics EuropeのNavigation Software Engineerが直々にSLAMについて教えてくれるよ！
詳しくは → https://pepper.doorkeeper.jp/events/61547


# SLAMってなーに？(超ざっくり)
Simultaneous Localization and Mapping の略。別にPepperの用語ではなくロボット的には一般的な言葉らしい。
じゃあ Simultaneous Localization and Mapping ってなに？というと

- Simultaneous → 同時に
- Localization → 位置を特定する
- And → と
- Mapping → 地図作成

てことなので、つまり、地図を作りつつ自分の位置も特定するよ！ということ…らしい。

余談だけど、私が Localization の意味を理解したのはトレーニングが終わってこの原稿を書いたとき(つまり今)。いや、なんとなく話の内容的にそんな感じかなぁとは思ったけど。この辺の基礎用語は調べとくべきだった。

本題に戻る。そんなわけでSLAMてのはどうやら「地図を作って自分がその地図の中のどこにいるのか」を行う仕組みのことらしい。一番頭のSimultaneousが気になるんだけど、少なくとも今時点のPepperにおいてはこれは「同時」ではない、という認識で良さそう。この辺は後ほど。


# SLAMは何が嬉しいの？
…ということを考えるためには、「SLAMでないもの」について考える必要がある。トレーニングで使った資料においては、SLAMと比較されている手法はオドメトリ(Odometry)という奴。
これは何かというと、「タイヤで動くロボット」に(多分)限定した話なんだけど、つまりはタイヤがどっちの方向を向いて何回転がったかがわかったら、元々の位置からの相対的な位置がわかるよね、というコンセプト。
オドメトリは考え方がシンプルなのはいいのだけど、そんなに理想的に現実はできていないわけで、主にタイヤの滑りが問題になるっぽい。資料では Odometry Driftと表現されていた。
つまり、タイヤの回転数と方向から自分の位置を推定する場合、ちょっとちょっとの誤差が蓄積していくので、A地点とB地点を往復するような運動をすると、だんだん位置がずれていってしまう。

でも、SLAMは、最初に自分で地図を作って、自分がその中のどこにいるのかを地図の中の特徴点(壁とか障害物の類。多分動かないことを前提にしている。これは後で重要な意味を持つ。)との位置関係から判断するので、2地点を往復してもズレがでないのが嬉しいところ。だということになっている。


# PepperにおけるSLAMの実績
2017年のPepperWorldでSLAMの実演をしていたんだけど(私も見たけどすごかった←小並感)、1日10時間稼働、2日間の運用で、クラッシュ(物理的な？ソフト的な？)もスワップ(こっちは多分物理的な交換…というか代打への交代かな)も発生しなかったと。ほほぅ…。


# 実際どうするの？
ここからがトレーニング前半の本題。
そして私が本当にわかってるのかどうかとても怪しい部分(なので間違ってたらどなたか詳しい方ツッコんで下さい)。

SLAMは

- 地図を作る過程 → explore(探索)
- 地図を読む過程(つまり探索の結果としての地図は保存しておける)
- 読み込んだ地図の中で自分がどこにいるのかを指定する過程 → relocalization(日本語訳難しい)
- ナビゲーションする過程

のようなプロセスを踏むみたいなんだけど、少なくとも現時点のPepperにおいてはこれらは同時に実行するのではなく、それぞれ別個のプロセスとなるっぽい。

で、大変にお恥ずかしい話なんだけど、具体的に各プロセスで使うアプリの開発についての技術的なとこは今回は追っかけきれなかった。個人的には今回は「Pepperを自律歩行させてみる」ことに重きをおいていたので、https://github.com/aldebaran/naoqi_navigation_samples にあるサンプルアプリ(を今回のトレーニング用に改変したもの)をそのまま実行してみて、上記のプロセスを実際に手を動かしてみる、というところまでとなった。

サンプルアプリについては、おそらく

- 3つのアプリをすべてインストールする
- explore を実行して地図を作る
- patrol を実行して地図を読み込んでrelocalizationしてナビゲーションする

という手順を踏めば問題なく実行できる。
最後の「ナビゲーションする」がまさに自律歩行の部分で、「こうやって歩いていってね」という指示はない。あくまでも行き先を指定するだけ。ショートカットできるなら勝手にするし、障害物を検知すれば一生懸命避けようとする。これはなかなかすごい。


# 知らなかったこと(1)
現時点のPepperは、目で(カメラで)見た映像から地図を作っているのではなく、足元のレーザーセンサーを使っている。
このため、おそらく机みたいな「足元はスカスカで腰高に張り出している障害物」は認識できない気がする。あと、透明な壁は見えず、その先にある障害物を検出する(…とNicolasさんが言ってた)。

で、赤外線は比較的低い位置から斜めに照射されている関係で、あんまり遠くにあるものは認識できないとのこと。で、SLAMは障害物を目印にするしくみなので、例えばなにもないだだっ広い部屋みたいなところでは使えないらしい。オフィスの廊下みたいな、両側に壁がしっかり生えているものがお好みっぽい。

# 知らなかったこと(2)
これが一番衝撃的だったんだけど、「スタート時点で自分が地図のどこにいるか」は現時点では「手作業で」指定してやる必要がある。確かに、障害物しか見えていない事を考えたうえでPepperの気持ちになればそりゃそうなんだけど、とはいえ、Pepperが生成したフワフワした地図の中で「キミは今ここにいるのよ」と教えてあげるのはなかなか難易度高いし未来度低いｗ この辺はきっと今後進化するはず。


# まとめ
そんなわけで、今の時点でPepperが一人でひょいひょい歩けるようになったのかというとそうではない。そりゃそうだ。まだSLAM機能はβ版だしね。で、アプリ側での実装も今の時点ではなかなか難しそう。
ただ、実際にアプリを実行して、Pepperがなんとかして歩こうとしている(そしてまがりなりにもちゃんと歩けている)のはすっごく感動する。未来感ある。ていうか「Pepperが歩いたわっ！」みたいな気持ちになる。いずれちゃんと自分の目で見て地図が作れたりするようになるともっとスムーズに歩けるようになるんだろうなぁ。あとは、ご家庭版PepperでSLAM試せるように早くなるといいなぁと思う次第。
Cognos BI でログインユーザーの所属するグループ・役割を簡単に確認する

##概要
Cognos BI で、あるユーザーがどのグループや役割に所属しているか、さらっとわかるTipsです。

##内容
こんなレポートをReport Authoringで作成します。

クエリーアイテムに、以下を記載します。
\#sq(CSVIdentityNameList())#
![002.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/13885c23-cf97-6792-a958-0c5031d4f079.png)

クエリーアイテムを、シングルトンの上に置きます。
![003.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/343be458-4059-9b7d-45e5-d89333152f89.png)

レポートを実行すると、以下のような表示になります。
ApacheDSとCognosはネームスペースなので無視、coguser2もユーザー名なので無視、すべてのユーザーと全認証済みユーザーも勝手に入るので無視、すると、このユーザーがRole01、TESTGRP、システム管理者、作成者、に所属している事がわかります。
![001.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/fa4e4f14-6d8b-1f1b-c97a-f0316d8a8b8c.png)

簡単ですが、ちょっとした時に役立ちます。
今さらRailsに手を出すのもしゃくなのでHanamiの開発環境をDockerで作ったった

# はじめに

1. 新人が研修でRubyを勉強している
2. でも俺はRubyをちゃんと触ったことがない
3. なんか恥ずかしい
4. せや、開発環境構築してなんかしたろ!!

というわけでDocker-composeを使って今話題らしいHanamiの環境を作ってみました。

完成品は[こちら](https://github.com/Mic-U/hanami-docker-compose-template)

# Hanamiってなんぞ?

RubyのWebフレームワークです。公式サイトは[こちら](http://hanamirb.org)。
公式サイトで謳っている文句を信じるなら

- 速い
- 軽い
- 安全
- 簡単

の4拍子が揃っているようです。多分Rails触ったことある人なら割とすんなり飲み込めそうです。
個人的にはRailsは使うコマンドが`rails`だったり`rake`だったりするのが辛かったのですが、こちらは`bundle exec hanami`でだいたいなんとかなるみたいです。
あ、Railsの5.0以降だと`rails`コマンドに統合されてるみたいですが、私は4系までしか触ったことがありません。

# 構成

`hanami new`で作成されるテンプレートにDockerfileとdocker-compose.ymlを足しています

```Dockerfile:Dockerfile
FROM ruby:2.3.3
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /app
WORKDIR /app
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN echo 'gem: --no-document' > ~/.gemrc \
  && bundle install

ADD . /app
```

まあ、Rails使うときと同じです。

```yaml:docker-compose.yml
version: "3" 
services:
  mysql:
    image: mysql
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - ./containers/mysql:/var/lib/mysql
  adminer:
    image: adminer
    ports:
      - 8080:8080
    links:
      - mysql
  app:
    build:
      context: .
      dockerfile: ./Dockerfile
    command: "bundle exec hanami server --host 0.0.0.0 -p 2300"
    volumes:
      - .:/app
      - ./containers/bundle_install:/app/vendor/bundle
      - ./containers/bundle:/app/.bundle
      - ./containers/node_modules:/app/node_modules
    ports:
      - 2300:2300
    links:
      - mysql

```

[こちら](http://qiita.com/shibabuki_yuta/items/0239aaa21d3b92b8e06c)の記事を参考にしていますが、DBのコンテナは一つにして、DBの中身を確認できるようにadminerも用意しています。

# コンテナ解説

用意したコンテナは下記の通りです

- mysql
- adminer
- app

本当はキャッシュとしてredisも入れたかったのですが、Hanamiのどこに仕込めば良いのかよくわからなかったので...
これから勉強してわかったら追記します。

## mysql

MySQLのコンテナです。
それ以上説明することは特にありません。

## adminer

adminerのコンテナです。
コンテナ起動後、localhost:8080にアクセスすれば見られます。
DBのホストはmysql、ユーザー名とパスワードはどちらもrootでログインできます。
DBホストがmysqlでログインできるのはdocker-composeがymlに記載されたコンテナ名で名前解決できるようにネットワークをよしなに設定してくれているからです。

なので、別にdocker-compose.yml以外のファイル内でもdocker-composeのネットワーク内であれば、mysqlとかadminerで名前解決できます。

## app

Hanamiの本体です。
起動したらlocalhost:2300にアクセスしたら画面を見れます。

参考ページではdocker-compose.yml内で環境変数DATABASE_URLを定義していますが、これだと開発環境でもテスト環境でも同じDBを参照してしまいます。
(参考にした記事では開発用とテスト用でDBコンテナを分けてますが、投稿した@shibabuki_yuta さんも改善の余地はあると感じている模様)

色々試して見たところ、.env.developや.env.test内でもコンテナ名で名前解決できることがわかったので、それぞれにこんな設定を書きました。

```.env.develop
DATABASE_URL="mysql2://root:root@mysql:3306/development"
```

```.env.test
DATABASE_URL="mysql2://root:root@mysql:3306/development"
```

# 使い方

とりあえずREADME読んで見てください。
不足や誤りがありましたらご一報いただけると幸いです。

よーし、頑張ってRuby勉強するぞー。

# 参考

- [DockerでHanami(旧名Lotus)の開発環境構築](http://qiita.com/shibabuki_yuta/items/0239aaa21d3b92b8e06c)
- [開発しやすいRails on Docker環境の作り方](http://qiita.com/joker1007/items/9f54e763ae640f757cfb)
[Unity] StreamingAssets内に直接インポートすると[不具合]

HoloLens開発にあたってStreamingAssetsはいまや必須。[[参考]HoloLens上でスクリプトを用いて外部ファイルの読み込みをしたい] (http://qiita.com/gshirato/items/dbefd28b570d98cb4da9)
しかし環境的な問題なのか仕様なのかわかりませんが、StreamingAssets内に外部フォルダから直接D&Dでファイルをインポートしようとすると必ず不具合が起きます。

##Version

Unity 5.6.1f1 Personal

##例
![assets.png](https://qiita-image-store.s3.amazonaws.com/0/186209/8422a419-e59a-11a1-bd15-8d4940f58ee0.png)
通常、Unity内のファイルはUnity用のアイコンと共に表示されます。
(左からmp4,cs,png,jsonファイル)
イメージファイルであればサムネイルが必ず表示され、Unity上で扱うことのできるファイルだとわかります。

![StAssets.png](https://qiita-image-store.s3.amazonaws.com/0/186209/3f04e801-353a-5c55-0815-e8d333ec3d1e.png)
しかし、これをStreamingAssets上に直接インポートするとこうなります。
アイコンはWindows上のファイルエクスプローラーのものと同じになり、それだけならまだ良いのですが案の定全く存在を認識されなくなります。

##対処法
幸い対処法があり、それは
*StreamingAssetsに直接インポートしない*
です。

インポートはStreamingAssetsの支配下でないファイルにまずしましょう。
尚、インポート後であればD&DでStreamingAssets内にファイルを移しても不具合は基本起きないです。

##注意点
また、気をつけないければいけないことは
*StreamingAssets内でファイルの操作をしない*
ということです。


##以上を踏まえて
インポートはStreamingAssetsと関係のないフォルダにまずして（それ専用のフォルダを作っておくのもいいかもしれません。）もしコード変更などの必要がある場合は適宜StreamingAssets外に避難させましょう。すべての準備ができたらStreamingAssets内に入れましょう。

##まとめ
ここまでインポート時の不具合について書いてきましたがこれが自分だけに起きている問題なのか、一般的に起きがちな問題なのか謎なのでこの投稿がどれだけ役に立つかわかりません。ここで上げた対処法かなりめんどうなうえに柔軟性が殆どありません。もしよりよいアイデアや根本的な解決策をお持ちの方がいればぜひコメントお願いします。


##HoloLens開発記事一覧
[こちら](http://qiita.com/gshirato/items/6c026f2c67dc332f829b)から
Cognos TM1 Webのセッションタイムアウト

##内容
久々にTM1環境構築しましたが、自分でもすっかり忘れてたので、自分へのメモの兼ねて投稿です。

Cognos TM1 10.2.2で、構築してそのままだと、TM1 Webのタイムアウトはデフォルトで20分に設定されています。

別に20分で良いよ、という環境もあるかと思いますが、今日の環境では指摘を受けました。

タイムアウトの指定は、tm1web_config.xml ではなくて、web.xml です。

以下のファイルの、
C:\Program Files\ibm\cognos\tm1_64\webapps\tm1web\WEB-INF\web.xml

一番下にある、この箇所を変更し、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/36bfad8d-e8fe-cd71-d558-300ddd25ee7f.png)

TM1 Application Serverプロセスを再起動しましょう。

早まって、N/W経路の途中のFirewallとかのせいじゃないでしょうか、とか言うと恥かきますので、ご注意を！

**How can I change the session-timeout for TM1Web (default 20 minutes)**
http://www-01.ibm.com/support/docview.wss?uid=swg21659941
serverless-chromeのためLambdaデプロイメント制限を突破する

# まえおき

[AWS Lambda の制限](http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/limits.html)にある通り、Lambdaは一つの関数につき250MB、圧縮して50MB以内のソースしかデプロイすることはできません。また、制限緩和申請で解除されることもありません。

しかしLambdaの便利さにどっぷり漬かり、もうサーバ管理には戻れない体になってしまうと、「いや、素直にEC2使えよ」って処理も、全てLambdaで完結させたくなってきます。

そう、[serverless-chrome](https://github.com/adieuadieu/serverless-chrome)とかね、、


# どんな問題が起きたか

```json:package.json
"dependencies": {
    "@serverless-chrome/lambda”: "^1.0.0-4",
    "aws-sdk”: "^2.76.0",
    "chrome-remote-interface": "^0.23.2",
    "fs-extra": "^3.0.1"
}
```

できるだけシンプルになるよう頑張ったのですが、これでnode_modulesが220MB越えました。圧縮して70MB。
そしてその殆どはserverless-chromeにある大きなバイナリファイル、、、

詰んだ。

serverless-chromeを使ってちょっと何かやろうとすると、容易に制限を越えてしまう模様です。

「諦めてEC2使う」がベストプラクティスであろうとは思いつつも、サービス的に常に稼働するものではなく、たまに動くだけのものでしたので、「多少処理が遅延してでもLambdaに載せたい」という気持ちがいっぱいです。

# 対処方法

結論として、もっとも大きいファイルである

`@serverless-chrome/lambda/dist/headless_shell`

をデプロイ対象から外し、Lambda起動時にS3から動的に取得することで対応できました！

## 実装上のコツ

* s3からheadless_shellを/tmpに保存します。その際fs.writeFileSync等でそのまま書き込むと実行権限が無くエラーになるため、取得後にchmodします。

```javascript
const exec = require('child_process').exec;
exec('chmod 777 ' + CHROME_PATH, (err, stdout, stderr) => {
// 何かの処理
});
```

* コンテナが消えなければ/tmpにこのバイナリは残るため、存在チェックをつけておきます。
 
* [@serverles-chrome/lambda](https://www.npmjs.com/package/@serverless-chrome/lambda)はchromePathというパラメータでchromeのバイナリを指定できるので、ここで先ほどDLしたバイナリを渡します。

```javascript
launchChrome({ chromePath: '/tmp/headless_shell' });
```

* [serverles-chrome](https://github.com/adieuadieu/serverless-chrome)のサンプルはasync/awaitで書かれているので、Node6.10で動くようPromiseで書き換えます。


# 応用の可能性

まだ試していませんが、多分同種の問題に引っかかった時、特定のバイナリだけではなくライブラリ丸ごとS3において、/tmpにDLした後$NODE_PATHに/tmpを加えれば何とかなる気がします。

いや、デプロイ制限が緩和されればこんなこと全く気にする必要はないので、早く制限解除される未来が来てほしいですね。
Dropwizardにおける無料SSL証明書の使い方

個人的には他のJavaフレームワークよりも学習コストが低くて最高だと思っているけど、国内ではイマイチ流行らない「Dropwizard」というJavaフレームワークを使っている場合の無料SSL証明書(Let's Encrypt)を使う手順をメモしておく(ほとんど身内向け)


## 動作確認環境

OS: Ubuntu 16.04 LTS
M/W: OpenJDK1.8,Dropwizard 0.9.1

## 構築手順

構築手順は以下の通り

## 1) ドメイン取得

ドメインを持ってない場合は、以下のサイトからフリーのドメイン(www.mamemame.ml等)を取得する
http://www.freenom.com/ja/index.html?lang=ja

※登録後しばらく時間が経過しないと名前引けないので注意

## 2) 証明書取得

以下の手順で無料のSSL証明書(Let's Encrypt)を取得する

○Let's Encryptについて
https://letsencrypt.jp/

```
$ sudo apt-get install letsencrypt
$ sudo letsencrypt certonly --standalone -d www.mamemame.ml --email mamemame@mamezou.com
```

## 3) keystore(jks)作成

以下のコマンドでJava Key Storeを作成する

```
$ sudo openssl pkcs12 -export -passout pass:mamemame123 -in /etc/letsencrypt/live/www.mamemame.ml/fullchain.pem -inkey /etc/letsencrypt/live/www.mamemame.com/privkey.pem  -out mame.p12 -name mame
$ sudo keytool -importkeystore -deststorepass mamemame123 -destkeypass mamemame123 -destkeystore mame.keystore -srckeystore mame.p12 -srcstoretype PKCS12 -srcstorepass mamemame123 -alias mame
```

## 4) keystoreの内容確認

以下のコマンドでkeystoreに正しく登録されているかを確認する

```
$ sudo keytool -v -list -keystore mame.keystore
```

## 6) dropwizardの設定と再起動

設定ファイル(config.yml)を確認(変更)して再起動する
(以下~mamezou/mameにdropwizardのモジュールがインストールされている想定)

```
$ vi ~mamezou/mame/mame-config.yml
---
applicationConnectors:
  - type: https
    port: 443
    keyStorePath: ssl/mame.keystore
    keyStorePassword: mamemame123
    certAlias: mame
    validateCerts: false # これがないと起動時にエラーになった
    trustStorePath: ssl/mame.truststore
---
```

## 5) keystoreの配置

作成したkeystoreをdropwaizardのkeystoreに配置する

```
$ cp -p mame.keystore ~/mamezou/mame/ssl/
```

## 6) Dropwizardサーバ起動

```
$ cd ~mamezou/mame
$ java -jar mame.jar server mame-config.yml
```

SSL証明書の期限は90日ですが、期間が限定される検証環境(PoC)やデモ環境には最適なソリューションですね

---
以上
Swift文字列分割で空文字列を除く

Swift3で文字列をseparatorでsplitするには、以下の2つがありますが、結果は異なります。

```swift
"a,,b".components(separatedBy: ",")
// => ["a", "", "b"]

"a,,b".characters.split(separator: ",").map(String.init)
// => ["a", "b"]
```

特に、空文字列自体をsplitして空配列を期待しがちなので、注意。

```swift
"".components(separatedBy: ",")
//=> [""]
```

split関数は、引数で制御可能。

```swift
"a,,b".characters.split(separator: ",", maxSplits: 1, omittingEmptySubsequences: false).map(String.init)
// => ["a", ",b"]
```

結論: split関数を使う。
VM上でHigh Sierraを動かす


VM上でHigh Sierraを動かそうとしてみました。

[失敗したVirtual Boxでの手順](#失敗したvirtual-boxでの手順)
[成功したAnkaで起動](#ankaで起動)

# 失敗したVirtual Boxでの手順
## 1.VM上でHigh Sierraの入手

（割愛）
Apple Developer > Downloadsから
macOS High Sierra 10.13 beta2をDownloadします。
**macOSDeveloperBetaAccessUtility.dmg**を入手し、
App SotreからHigh Sierraをダウンロードします。

## 2.再起動

自動的に立ち上がった `Install macOS High Sierra Beta`の手順に従います。
再起動まで進めて、画面が暗くなったタイミングで
F12キーを入力します。
VirtualBox EFIに画面が切り替われば成功です。
※NGならもう一度、アプリケーションディレクトリにある`Install macOS High Sierra Beta`からスタートです。

`Boot Manager` を選択
![Kobito.hVwo9f.png](https://qiita-image-store.s3.amazonaws.com/0/94745/0b4db852-58ce-3be2-332a-0c492ec17337.png "Kobito.hVwo9f.png")



`EFI Internal Shell`を選択し、以下を入力
![Kobito.v9ZWrw.png](https://qiita-image-store.s3.amazonaws.com/0/94745/09661fb1-7743-bec3-1353-3d5e6114065c.png "Kobito.v9ZWrw.png")

```
Shell> fs1:
FS1:\> cd "macOS Install Data"
FS1:\macOS Install Data\> cd "Locked Files"
FS1:\macOS Install Data\Locked Files\> cd "Boot Files"
FS1:\macOS Install Data\Locked Files\Boot Files\> boot.efi
```
![Kobito.qlVBvR.png](https://qiita-image-store.s3.amazonaws.com/0/94745/5e7913f1-8214-8f2c-268a-93f2a873fe3b.png "Kobito.qlVBvR.png")

※シェル打ってる最中に大文字小文字が勝手に切り替わるのってどうにかできるんでしょうか・・・。

後は自動的に処理が進むのでしばらく待機です。

### 作業メモ

私はインストール中と、インストール終わった後でGoogle Chrome Helperが原因？でPC本体が強制終了しました・・・。
Chromeを終了してプロセスが走っていない状態で処理を進めてなんとかなりましたが・・・。

やり直しは時間かかるので、スナップショットの機能を活用して効率よく作業することをオススメします；

## 起動したけれど・・・。

High Sierra 10.13で起動しましたが、
マウスとキーボードが効かない状態で先に進めず詰みました。

以下導入してみたりして解決を試みましたが、解決せず。
- Extension Pack
- Virtual box(5.1.23 beta)


原因が操作にあるのか、beta2にあるのか、Virtual Boxにあるのか・・・。

# Ankaで起動

http://applech2.com/archives/20170609-how-to-build-macos-10-13-high-sierra-vm-on-anka.html

Ankaを使用したらすべての悩みが吹き飛んで快適に10.13が動いてます。
Swift：配列で全てに同じ初期値を入れて初期化する方法

# 背景

Swiftは配列が便利ですよね。けれどC言語のように簡単に初期値を格納した大きな配列を宣言できないと思っていました。いやぁ、できるんですね。

# 今までやっていた方法

```swift
var intArray = [Int]()
for _ in (0 ..< 100) {
	intArray.append(5)
}
```

# 一行で済む方法

```swift
var intArray = [Int](repeating: 5, count: 100) //[5, 5, 5,...,5]

var strArray = [String](repeating: "hello", count: 50) //["hello", "hello",...,"hello"]
```
repeating:とcount:を使えば同じ値を一気に繰り返し格納できるんですね。

# 注意点

[Swift：配列に初期要素を複数セットする時の罠](https://qiita.com/Kyome/items/695efb82d78c8029f04b)
こちらの記事にも書いてありますが、`repeating:count:`を使う場合、クラスインスタンスを初期値として使うと、全部同じ参照になってしまいます。つまり、配列のどれかのインスタンスをいじると、配列全体の要素にも変更が加わってしまいます。
いい感じにインストールされたアプリのバージョンをトラッキングしてくれるSwiftyVersionTrackerを作った

# サマリ
GitHubはこちら[SwiftyVersionTracker](https://github.com/notohiro/SwiftyVersionTracker)

- [GBVersionTracking](https://github.com/lmirosevic/GBVersionTracking)を元にしています。
- インストールされたアプリのバージョンを時系列に保存します。
- Protocol Orientedな実装なので、バージョン番号のルールはプロジェクトに応じて柔軟に実装できます。
- とはいえ、殆どのプロジェクトは1.0.0(整数繰り上げ)とかのルールだと思いますので、すぐに使えるよう整数用の構造体を実装済みです。
- 便利なプロパティを用意しています。
- 下記、基本的にはREADME.mdの日本語訳です。

# Quick Look
```Swift
let tracker = try! SwiftyVersionTracker<SwiftyVersionIntInt>()

if tracker.isFirstLaunchEver {
  // do something
  // e.g. shows welcome screen
}

if tracker.isFirstLaunchForVersion {
  // do something
  // e.g. shows release note
}

if tracker.last?.major == 1 {
  // do something
  // e.g. migrate database
}
```

# 使い方
## プロパティ
|プロパティ|用途|
|:--|:--|
|`isFirstLaunchEver: Bool`|インストール後初回起動かどうかを返します|
|`isFirstLaunchForVersion: Bool`|今回起動のバージョンで初めての起動かどうかを返します|
|`isFirstLaunchForBuild: Bool`|今回起動のビルドで初めての起動かどうかを返します|
|`current: T`|現在のバージョンを返します|
|`previous: T?`|一つ前にインストールされていたバージョンを返します|
|`first: T`|最初にインストールされたバージョンを返します|
|`last: T?`|最後に起動されたバージョンを返します|
|`history: [T]`|これまでインストールされたバージョン履歴を返します|

## `T`？
`SwiftyVersionTracker`はプロトコル指向プログラミングで実装されています。バージョンを表すルールは会社やアプリに応じて様々あると思います。`SwiftyVersion`プロトコルに準拠していれば、バージョンを表す構造体/クラス`T`を自由に実装できますので、要件に応じて柔軟に対応出来るようになっています。

## `SwiftyVersion`
`SwiftyVersion`は下記で表されるシンプルなプロトコルです。

```Swift
public protocol SwiftyVersion: Equatable {
	associatedtype VersionLetters: Comparable
	associatedtype BuildLetters: Comparable

	var major: VersionLetters { get }
	var minor: VersionLetters { get }
	var release: VersionLetters { get }
	var build: BuildLetters { get }

	init(versionString: String?, buildString: String?) throws
}
```
バージョニングの考え方は[Wikipedia](https://en.wikipedia.org/wiki/Software_versioning)をご参照下さい:grinning:

## `SwiftyVersionIntInt: SwiftyVersion`
ただインストールバージョンをトラッキングしたいだけなのに1から実装するのはめんどくさい！という方(ほとんどだとおもいますが:sweat_smile:)のために、`SwiftyVersionIntInt`を同梱しています。`IntInt`という名前の通り、バージョン番号にもビルド番号にも整数しか使わないユースケースで利用できます。具体的には下記をご覧ください。

```Swift
let version = try! SwiftyVersionIntInt(versionString: "1.2.3", buildString: "4")

XCTAssertEqual(version.major, 1)
XCTAssertEqual(version.minor, 2)
XCTAssertEqual(version.release, 3)
XCTAssertEqual(version.build, 4)
```

## `SwiftyVersionTracker`
`T: SwiftyVersion`が実装できたら、ようやく`SwiftyVersionTracker`の出番です。`SwiftyVersionTracker`を初期化する際は、2つの選択肢があります。

### 1. Bundleを使う方法
1つ目はバンドルを使う方法で、殆どのアプリケーションに最適です。`SwiftyVersionTracker`を引数なしで初期化すると、ターゲットに設定した`Version`と`Build`を使って、ジェネリクスで指定した`SwiftyVersion`を初期化します。

<img src="https://raw.githubusercontent.com/notohiro/SwiftyVersionTracker/master/VersionStrings.png" width="640">

サンプルは下記の通りです。

```Swift
let tracker = try! SwiftyVersionTracker<YourVersion>()
```

### 2. 独自バージョン管理を使う方法
バージョン情報をそれ以外の方法で管理している場合は、初期化時に`versionString`と`buildString`パラメータに指定できます。

```Swift
let tracker = try! SwiftyVersionTracker<YourVersion>(versionString: "1.2.3", buildString: "a123")
```

### App Extensionsの中で使う場合
アプリ本体とExtensionsで共通して使いたい場合は、初期化時に`userDefaults`パラメータを指定することで、App Groupに対応した保存先を使えます。
VB.NETでMySQLからデータセット経由でデータをXMLで保存する

#なんで今更
私用のメモ兼なんかググってもやりたいことがパッとでなかったので書いちゃいます。

#環境
OS :Windows10 Pro 64bit
IDE:Visual Studio 2015
DB :MySql 5.7.18 

#MySQL導入
####MySQLインストール
https://www.dbonline.jp/mysqlinstall/
このページ見てインストールとPATHの確認にあるコマンドプロンプトで実行できるかまでやってください。
あとインストール時のパスワードを忘れないようにしましょう。

#テーブル作成
MySQL導入後コマンドプロンプトを管理者モードで起動し下記を打ち込みます。

```mysql:startup

mysql-u root -p

```

そうするとパスワードを入力してねと出ると思うのでインストール時に入力したパスワードを入力し、MySQLに入ります。
次にデータベースとテーブルを作ります。私は下記な感じで作りました。

```mysql:create.sql

#データベースを新しく「testdb」との名前で作って、
#その中にusersってテーブルを作ってデータを入れる。
create database testdb; 
create table testdb.users(
id int not null auto_increment primary key,
name varchar(255),
email varchar(255) unique,
password char(32)
);
INSERT INTO users (id, name, email,password)
  VALUES (1, 'hoge', 'hoge@hoge','fuga');

```

#コードを書く・・・前に
VisualStudioそのままだとMySQLに接続できないのでMySQL Connector/Netを入れましょう。
VSを立ち上げて「新規プロジェクトを作成」を選択、WindowsフォームアプリケーションとかでOKを押下しプロジェクトを作成します。
その後ソリューションエクスプローラーから作ったプロジェクトを右クリックし「ソリューションのNuGetパッケージの管理」を選択します。
出てきたNuGetウィンドウの参照を選択して検索窓に「MySQL.Data」と入力して一番上(多分)に出てきたMySQL.Dataをインストールしてください。

#XMLを作成するコード
あとはコードを書くだけです、私はこんな感じでボタンを押したら任意のパスにXMLが出力されるような感じにしました。
コードが汚いのは仕様ですご理解していただきたく。
エラーキャッチしてないのは見ないふりしていただきたく。

```VB.NET:XMLCreate

Imports System
Imports MySql.Data.MySqlClient

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim constr As String
        Dim conn As MySqlConnection
        Dim da As MySqlDataAdapter
        Dim ds As DataSet
        Dim sql As String
        Dim filePath As String

        constr = "userid=root;password=(設定したパスワード);Host=localhost"
        conn = New MySqlConnection(constr)

        Try
            conn.Open()

            sql = "SELECT * FROM testdb.users"
            filePath = "出力したいパス\test.xml"

            da = New MySqlDataAdapter(sql, conn)
            ds = New DataSet("users")
            da.FillSchema(ds, SchemaType.Source, "users")
            da.Fill(ds)

            ds.WriteXml(filePath)

            conn.Close()

        Catch ex As Exception

        End Try


    End Sub
End Class

```

#終わりに
MySQLからデータを受け取ってXML出力をする。という目標で検索しつつ上記のようになりました。
すぐ忘れそうなのでメモりましたが誰かの役に立てれば幸いです。

#参考
[MySQLインストール](https://www.dbonline.jp/mysqlinstall/ "MySQLインストール")
[Mysqlコマンド](http://qiita.com/fukumone/items/2c75bd4a11a7817e6c9e "Mysqlコマンド")
[Visual Studio で MySQL データベースに接続する](http://d.hatena.ne.jp/hilapon/20151215/1450166056 "Visual Studio で MySQL データベースに接続する")
[方法 : データセットを XML として保存する](https://msdn.microsoft.com/ja-jp/library/ms233698.aspx"方法 : データセットを XML として保存する")
【Swift】array.indices.contains(index)

配列の中身にindexがあるかをチェックする

~~~Swift3.swift
let array: Array
let isIndexValid = array.indices.contains(index)
~~~

中身があるかどうかのチェックなどは、行えると良いですね

Swift になってから型やnilの厳密化 になってきたからですね

---

## 関連記事

【About】(http://qiita.com/sunstripe) - サンストライプ

---

## 制作チーム：サンストライプ

[![sunstripe_logo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80600/322f2d60-f19d-af9e-2b6f-7290ca546848.png)](http://sunstripe.main.jp/)
http://sunstripe.main.jp/

(月１WEBコンテンツをリリースして便利な世の中を作っていくぞ！！ボランティアプログラマー/デザイナー/イラストレーター/その他クリエイター声優募集中！!)

### 地域情報 THEメディア
THE メディア 地域活性化をテーマに様々なリリース情報も含め、記事をお届けしてます！！
https://the.themedia.jp/

### ゼロからはじめる演劇ワークショップ
多様化の時代に向けて他者理解を鍛える

https://workshop.themedia.jp/

### プログラミングワークショップ・ウェブ塾の開講！！！
様々なテーマでプログラミングに囚われずに取り組んでいきます。
詳しくはこちら　↓　↓　↓　↓　↓　↓　↓　↓
[プログラミングサロン 月１だけのプログラミング学習塾](https://workshop.themedia.jp/posts/7057553?fbclid=IwAR32CfRQ7RvDOhvuogoSwqxDLMOU7Jvuzljlnx-TMc27qBPX1BnWsfLcBR8
)

### 協力応援 / 支援者の集い
## チーム：サンストライプ
#### プログラミングラボ
https://twitter.com/sunstripe2011

一緒にポートフォリオを作りませんか？現場の体験やそれぞれの立場から年齢関係なく作品を作りたい方々と一緒にチームを作って、作品を作っています。現場に行きたい人には、職場紹介や職場の体験や悩み相談なども受けております。
様々な職種からプログラミングの知識を得たい、デザインの知識を得たい、データーベースの知識を得たいという人が集まっております。
週１のミーティングにそれぞれの近況と作業報告して、たまにリモート飲み会などをしております！！

興味がある方は、DMに話しかけてみてください。

## トラストヒューマン
http://trusthuman.co.jp/
私たちは何よりも信頼､人と考えてます｡

｢コンサルティング｣と｢クリエイティブ｣の両角度から｢人材戦略パートナー｣としてトータル的にサポートします！！

キャリア教育事業
広域学習支援プラットフォーム『のびのび日和』
https://slc-lab.amebaownd.com/

#スポンサー募集
Amazon Kinesis Streamの監視方法

Kinesis Streamのシャードには以下のような制限がある。

* 書き込み 1シャード　最大1秒あたり1,000レコードまたは1MBまで
* 読み込み 1シャード　最大1秒あたり5回の読み込みまたは2MBまで

シャードへの流入・流出量を上記の値を超えないように・または超えたことを検知できるように
監視していかないといけない。

そのため、CloudWatchでのKinesisの監視項目をまとめる。

## どのメトリクスを見るべきか
CloudWatchでどういうメトリクスが見れるかは公式ドキュメントに記載がある。
<http://docs.aws.amazon.com/ja_jp/streams/latest/dev/monitoring-with-cloudwatch.html>

その中でも以下の項目を見ると、シャードを増やすしきい値が見えてきそう。

### WriteProvisionedThroughputExceeded
シャードの書き込み上限の超過が発生しているか否かを判定するのなら、この項目を見ればよい。
これは指定された期間中にストリームの上限超過が発生した件数が出力される。

これが定常的に1以上になった場合は、シャードを増やしたほうが良さそう。

#### AWS CLIでの取得方法

```
profile=hoge
stream_name=hoge

aws --profile ${profile} cloudwatch get-metric-statistics \
--namespace AWS/Kinesis \
--metric-name WriteProvisionedThroughputExceeded \
--start-time 2017-06-20T12:00:00 \
--end-time 2017-06-20T13:00:00 \
--period 60 \
--statistics Maximum \
--dimensions Name=StreamName,Value=${stream_name}
```

### ReadProvisionedThroughputExceeded
これは上記に記載した「WriteProvisionedThroughputExceeded」の読み込み版。
こちらも合わせて見たい。

### PutRecords.Bytes / PutRecords.Records
これは指定期間内にストリームに送信されたバイト/レコード数を確認することが出来る項目。
周期の最小単位が1分となっているため、指標として使うならこの値を使って1秒あたりの数値に計算しなおすとわかりやすい。

この項目を見ることにより、シャードの上限の超過の発生前に事前にシャードを増やすことができる。

PutRecordというのもあるが、KPLを使用している場合はPutRecordsを使う。

#### AWS CLIでの取得方法

```
profile=hoge
stream_name=hoge

aws --profile ${profile} cloudwatch get-metric-statistics \
--namespace AWS/Kinesis \
--metric-name PutRecords.Bytes \
--start-time 2017-06-22T12:00:00 \
--end-time 2017-06-22T12:05:00 \
--period 60 \
--statistics Sum \
--dimensions Name=StreamName,Value=${stream_name} | jq .
```

```json:response
{
  "Datapoints": [
    {
      "Unit": "Bytes",
      "Timestamp": "2017-06-22T12:02:00Z",
      "Sum": 4777677
    },
    {
      "Unit": "Bytes",
      "Timestamp": "2017-06-22T12:01:00Z",
      "Sum": 4241130
    },
    {
      "Unit": "Bytes",
      "Timestamp": "2017-06-22T12:00:00Z",
      "Sum": 5064734
    },
    {
      "Unit": "Bytes",
      "Timestamp": "2017-06-22T12:04:00Z",
      "Sum": 4647186
    },
    {
      "Unit": "Bytes",
      "Timestamp": "2017-06-22T12:03:00Z",
      "Sum": 4581718
    }
  ],
  "Label": "PutRecords.Bytes"
}
```

```
# 1分周期で取っているので、60(秒)で割って、1秒あたりのByteを計算
profile=hoge
stream_name=hoge

aws --profile ${profile} cloudwatch get-metric-statistics \
--namespace AWS/Kinesis \
--metric-name PutRecords.Bytes \
--start-time 2017-06-22T12:00:00 \
--end-time 2017-06-22T12:05:00 \
--period 60 \
--statistics Sum \
--dimensions Name=StreamName,Value=${stream_name} | jq -r '.Datapoints[].Sum' | xargs -i expr {} / 60
```

```json:response
79627
70685
84412
77453
76361
```

### GetRecords.Bytes / GetRecords.Records
上記の「PutRecords.Bytes / PutRecords.Records」の読み込み版。
こちらも合わせて見たい。
右クリックからJupyter notebook/termialを立ち上げる 【Win/Linux】

# はじめに

今でこそAnacondaを使ってる私ですが、以前はPython (x,y)という科学計算向けに特化したWindows向けPython distributionを使っていました。

入ってるパッケージ的にはAnacondaとあんまり変わりないのですが、一つ便利なのがインストールするとエクスプローラーの右クリック（コンテクストメニュー）に「**IPythonターミナルをここで立ち上げる**」というメニューを登録してくれる事(実際は英語メニューですが)。まあそんな事しなくてもIPythonターミナルを立ち上げて`cd <ディレクトリ>`すればいいんですが、面倒くさがりの自分にとってはデータがあるフォルダから右クリックでサクッとIPythonを立ち上げサクッと解析する事ができて、なかなか重宝する機能でした。

Anacondaを入れた時におんなじような事をやってくれる機能がないか調べていた時に見つけたのが [start_jupyter_cm](https://github.com/hyperspy/start_jupyter_cm) というパッケージ。以下のような感じでコンテクストメニューに「ここでJupyter notebookを立ち上げる」というメニューと、「Jupyter qtconsoleを立ち上げる」というメニューを追加してくれます。

![jupyter in context menu](https://github.com/hyperspy/start_jupyter_cm/raw/master/images/jupyter_cm_windows.png)

# インストール

Githubに書いてあるし、解説するほどのものでもないかもしれませんが、pipからインストールできます。

```py
 pip install start_jupyter_cm
```
その後、管理者権限でコマンドプロンプトなり、Anacondaプロンプトなり、Cygwinターミナルなりを立ち上げ、以下

```bash
 jupyter_context-menu_add
```

これだけです。

ちなみにWindowsだけじゃなく、Linuxでも動くそうです（未検証）。

参考になれば幸いです。