OmniAICreator/Qiita-1.07M huggingface dataset:
S3の暗号化

S3でのデータ保護は2パターン

- 転送時(S3との間での送受信)
    - SSLを使用
    - [クライアント側で暗号化](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/UsingClientSideEncryption.html)
        - AWS KMSで管理されたCMK(カスタマーマスターキー)を使用
            - KMS CMK IDを使用
        - クライアント側のマスターキーを使用
- 保管時(S3データセンター内のディスクに格納されている時)
    - S3で管理されたキーによるサーバー側の暗号化[SSE-S3](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/UsingServerSideEncryption.html)
        - キーが定期的に更新されるマスターキーで暗号化
        - AES-256を使用して暗号化
        - オブジェクトデータのみが暗号化。オブジェクトメタデータは暗号化されない
        - x-amz-server-side-encryptionというリクエストヘッダーを使用
    - KMSで管理されたキーによるサーバー側の暗号化[SSE-KMS](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/UsingKMSEncryption.html)
        - SSE-S3と同様だが下記の利点がある
            - エンベロープキーを使用するための個別アクセス制限がある。
                エンベロープキー: データの暗号化キーを保護するキー
            - いつ、誰によってキーが使用されたか監査証跡も提供されている
            - 暗号化キーを自分で作成し管理したり、ユーザー、サービス、リージョンごとに一意のデフォルトキーを使用できる
    - 自前で用意した暗号化キーによるサーバー側の暗号化[SSE-C](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html)
        - S3側でAES-256を使用し暗号化される
        - S3側で暗号化キーを保存しない。代わりにランダムなSALT値を付加したHMAC値を保存する。
        - httpsを使用する必要がある
        - レスポンスのETagはオブジェクトデータのMD5ではない
            - ETag(エンティティタグ): レスポンスヘッダの1つ。キャッシュの有効性確認の手段の1つ
        - 使用した暗号化キーと暗号化したオブジェクトのマッピングはクライアント側で行う
          - バージョニングが有効時、各バージョンに独自の暗号化キーを使用出来る。
        - コンソールでオブジェクトをアップロードした場合は使えない。またSSE-Cで保存したオブジェクトの更新をコンソールですることは出来ない。
      
SSE = Server Side Encryption
バケット内オブジェクトを一覧表示するときに、リストAPIは暗号化されていても表示する
SalesforceにTableauのダッシュボードを表示するときにハマったこと

SalesforceにTableauのダッシュボードを表示したいという要望がありいくつかハマったのでそのメモ。

##環境
・Salesforce → Classic
・Tableau → Windowsサーバー(オンプレ)
・Sparkler → EC2(Amazon Linux)

##前提
・あくまでもハマりポイントを書くので、細かい手順は[こちら](https://www.tableau.com/sfdc-canvas-adapter)でダウンロードすると、英語のDocumentがありますので、そちらを参照ください
・Salesforceのデータを連携するということではなく、Tableauのダッシュボードをそのまま表示するという要件です。
・Salesforce Canvasを使用します。

##システム構成

##はまりポイント1：Javaのバージョン
EC2でJavaがデフォルトで入っていたので、何も考えずに進んでいたらSSL認証のところでつまりました。ちゃんとバージョンは確認しましょう（←当たり前）

```bash:ec2
[ec2-user ~]$ java -version
java version "1.7.0_111"
OpenJDK Runtime Environment (amzn-2.6.7.2.68.amzn1-x86_64 u111-b01)
OpenJDK 64-Bit Server VM (build 24.111-b01, mixed mode)

##1.8をインストール
[ec2-user ~]$ sudo yum install java-1.8.0-openjdk.x86_64

#もう一度バージョンを確認
[ec2-user ~]$ java -version
java version "1.7.0_111"
OpenJDK Runtime Environment (amzn-2.6.7.2.68.amzn1-x86_64 u111-b01)
OpenJDK 64-Bit Server VM (build 24.111-b01, mixed mode)

#1.8を採用
[ec2-user ~]$ sudo alternatives --config java
```

##はまりポイント2：キーストアの名前(CN)
「Task 3: Enable HTTPS for Tomcat」でCNの名前をSparklerとするように書いているが、「Task 5: Configure Sparkler to Use a Tableau Server Self-Signed SSL Certificate (If Required)」で自己証明の場合は、Tableauサーバーのホスト名にするようにと記載があった。

```bash:ec2
[root tomcat7]$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA -keystore /usr/share/tomcat7/.keystore
Enter keystore password:
Re-enter new password:
What is your first and last name?
[Unknown]: {Tableauのホスト名}
What is the name of your organizational unit?
[Unknown]: {Your Organization}
What is the name of your organization?
[Unknown]: {Your Company}
What is the name of your City or Locality?
[Unknown]: {Your City}
What is the name of your State or Province?
[Unknown]: {Your State}
What is the two-letter country code for this unit?
[Unknown]: {Your Country Code}
Is CN={Tableauのホスト名}, OU={Your Organization}, O={Your Company},
L={Your City}, ST={Your State}, C={Your Country Code} correct?
[no]: y
Enter key password for <tomcat>
(RETURN if same as keystore password):
```

##ハマりポイント3:自己証明の場合の手順
今回Tableau、SparklerいずれもSSL認証の必要がありますが、検証環境でわざわざ認証局に申請をするとお金がかかるので、自己証明（おれおれ証明）をしています。
Tableauの自己証明の手順とかいろいろと省略されていたので、「Task 5: Configure Sparkler to Use a Tableau Server Self-Signed SSL Certificate (If Required)」でかなりハマりました。

まずTableauの自己認証の方法はクラメソさんが詳しく書いていますので、こちらを参照ください。
[Tableau Serverに対するSSL設定を行う](https://dev.classmethod.jp/business/business-analytics/tableau-server-setting-ssl/)

次に自己証明の場合、SparklerとTableauの証明書が同一である必要があります。
手順書では証明書をPEMフォーマットからDERフォーマットに変換する必要があるので、上の手順で作成した証明書「tableauserverssl.crt」をSparklerサーバーで変換する必要があります。

```bash:ec2
openssl x509 -in tableauserverssl.crt -inform PEM -out tableau.der -outform DER
```

# あとがき
もう少しありましたが、時間もないので後ほど追記します。
CanvasのImageDataをもっと簡単に扱うクラス

# 概要
Canvasオブジェクトの関数の一つに getImageData 関数というものがあります。ImageDataは、1ピクセルを(赤, 緑, 青, 透明度) の4つの要素で表わし、配列の総数は、4 × 幅 width × 高さ height です。この値を書き換えることで、Canvasに描画されている内容を変えることができます。
仕組みは簡単ですが、実際処理を書こうとすると配列番号をいろいろ考える必要がありスマートではなかったので、より簡単に書けるクラスを作りました。

# クラス
```SimpleImageData.js
class SimpleImageData{
	constructor(canvasId, x = 0, y = 0, width, height){
		const canvas = document.getElementById(canvasId);
		this._context = canvas.getContext("2d")
		
		this._offset = {x: x, y: y};
		if(typeof width  === "undefined") width  = canvas.width;
		if(typeof height === "undefined") height = canvas.height;
		
		this._image = this._context.getImageData(x, y, width, height);
		this._x = -1;
		this._y = 0;
	}
	get hasNext(){
		if(++this._x >= this.width){
			this._x = 0;
			this._y++;
		}
		return this._y < this.height;
	}
	get r(){
		return this._image.data[this._index + 0];
	}
	set r(newValue){
		this._image.data[this._index + 0] = newValue;
	}
	get g(){
		return this._image.data[this._index + 1];
	}
	set g(newValue){
		this._image.data[this._index + 1] = newValue;
	}
	get b(){
		return this._image.data[this._index + 2];
	}
	set b(newValue){
		this._image.data[this._index + 2] = newValue;
	}
	get a(){
		return this._image.data[this._index + 3];
	}
	set a(newValue){
		this._image.data[this._index + 3] = newValue;
	}
	setRGB(r, g, b){
		this.r = r;
		this.g = g;
		this.b = b;
	}
	load(){
		this._context.putImageData(this._image, this._offset.x, this._offset.y);
	}
	get x(){
		return this._x;
	}
	get y(){
		return this._y;
	}
	get width(){
		return this._image.width;
	}
	get height(){
		return this._image.height;
	}
	get _index(){// private
		return (this._x + this._y * this.width) * 4;
	}
}
```

## 使い方

例として、黄色(`#FFFF00`)を X軸、青色(`#0000FF`)を Y軸の増加に沿ってグラデーションしてみましょう。for文よりも、hasNextとwhile文を用いた方が短縮できます。

```javascript.js
const data = new SimpleImageData("canvas");
while(data.hasNext){
	const yellow = data.x / data.width;
	const blue = data.y / data.height;
	
	data.r = 255 * yellow;
	data.g = 255 * yellow;
	data.b = 255 * blue;
	data.a = 255;
}
data.load();
```

結果はこのようになります。
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/231330/0a115aec-0d4d-f261-1271-2cec9a43e7a2.png)

----
もしこのコードをクラスなしで書くとしたら。このようになります。

```javascript.js
const canvas = document.getElementById("canvas");
const image = canvas.getContext("2d").getImageData(0, 0, canvas.width, canvas.height);
const data = image.data;

for(let i=0; i<data.length; i+=4){

	const index = i / 4;
	const x = index % image.width;
	const y = Math.floor(index / image.width);

	const yellow = x / image.width;
	const blue = y / image.height;
	
	data[i + 0] = 255 * yellow;
	data[i + 1] = 255 * yellow;
	data[i + 2] = 255 * blue;
	data[i + 3] = 255;
}
canvas.getContext("2d").putImageData(image, 0, 0);
```
MemoryEnhancer > MEDC > test_get_list_180130.py > GitHub上のMarkdownファイル名(*.html.md)リストを取得する | GitHub REST API v3 | JSONモジュール | BeautifulSoup

```txt:動作環境
Ubuntu 16.04.3 LTS desktop amd64
tmux 2.1-3build1
Python 2.7.12
Python 3.5.2
```

### 処理概要

- GitHub上の`/data`以下のMarkdownファイル名リストを取得する

MEDC(Memory Enhancer Data Collectorの意味)に使う。

### code


```test_get_list_180130.py
import requests as rq

#IN_URL = "https://github.com/yasokada/TechEnglish_170903/blob/master/data/5290.html.md"
IN_URL = "https://github.com/yasokada/TechEnglish_170903/tree/master/data"

res = rq.get(IN_URL)
for elem in str(res.content).split('\\n'):
    if "html.md" in elem:
    	wrk = elem.replace(">", " ")
    	wrk = wrk.replace("<", " ")
    	wrk = wrk.split(" ")
    	print(wrk[-5])
```

```txt:run
$ python3 test_get_list_180130.py  | head -n 5
10.html.md
1096.html.md
1097.html.md
1098.html.md
1099.html.md
```

### 関連

- [MemoryEnhancer > MEDC > test_get_markdown_180126.py > Markdownをとってくる](https://qiita.com/7of9/items/2eb0f21a0f931cbbb04f)
- [Python > split > 二つのデリミタ(=と空白) > 実装: 'R1=0.5000D+01 R2=0.5000D+01 R12=0.1000D+02 LAM=0.6283D+01'から数値を取り出す](https://qiita.com/7of9/items/bf5530e981ceb7fcb185)


### 教えていただいた事項
(追記 2018/01/30)

@SaitoAtsushi さんの[コメント](https://qiita.com/7of9/items/a02ed74c95a136423143/#comment-9ebfa1eb51d772e5c9c1)にてGitHub APIについて紹介いただきました。

情報感謝です。

@shiracamus さんの[コメント](https://qiita.com/7of9/items/a02ed74c95a136423143/#comment-1b4652ae2a6578990351)にてBeautifulSoupの紹介と具体的なコードを紹介いただきました。

情報感謝です。
SourceTreeの内臓Gitのバージョンが上がらなかった話

## SourceTreeの脆弱性が見つかったのでアップデートを行うことに

[Sourcetree Security Advisory 2018-01-24](https://confluence.atlassian.com/sourcetreekb/sourcetree-security-advisory-2018-01-24-942834324.html)

SourceTreeのアップデートを行い、内臓GitのバージョンもSourceTreeから上げようとしたところ以下のエラーがでて更新ができず戸惑う



![SnapCrab_NoName_2018-1-30_12-22-31_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/82250/bad7a875-4e6a-deb4-701a-72d15c17e2d4.png)
![SnapCrab_NoName_2018-1-30_12-18-30_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/82250/584a1113-aedb-7577-f6b6-e4fb92c68eaf.png)


## エラー全文
```

7-Zip [32] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21

Scanning the drive for archives:
1 file, 37727272 bytes (36 MiB)

Extracting archive: C:\Users\****\AppData\Local\Atlassian\SourceTree\PortableGit.7z
WARNING:
C:\Users\****\AppData\Local\Atlassian\SourceTree\PortableGit.7z
Can not open the file as [7z] archive
The file is open as [PE] archive

--
Path = C:\Users\****\AppData\Local\Atlassian\SourceTree\PortableGit.7z
Open WARNING: Can not open the file as [7z] archive
Type = PE
Physical Size = 37727272
CPU = x86
Characteristics = Executable 32-bit
Created = 2017-04-06 07:33:08
Headers Size = 1024
Checksum = 37781750
Name = 7zS.sfx.exe
Image Size = 503808
Section Alignment = 4096
File Alignment = 512
Code Size = 382976
Initialized Data Size = 106496
Uninitialized Data Size = 0
Linker Version = 14.10
OS Version = 6.0
Image Version = 0.0
Subsystem Version = 6.0
Subsystem = Windows GUI
DLL Characteristics = Relocated NX-Compatible TerminalServerAware
Stack Reserve = 1048576
Stack Commit = 4096
Heap Reserve = 1048576
Heap Commit = 4096
Image Base = 4194304
Comment = FileVersion: 16.4.0.0
FileVersion: 16.04
ProductVersion: 16.4.0.0
ProductVersion: 16.04
CompanyName: Igor Pavlov
FileDescription: 7z Setup SFX
InternalName: 7zS.sfx
LegalCopyright: Copyright (c) 1999-2016 Igor Pavlov
OriginalFilename: 7zS.sfx.exe
ProductName: 7-Zip
----
Path = [0]
Size = 37242768
Packed Size = 37242768
Virtual Size = 37242768
Offset = 477184
--
Path = [0]
Type = 7z
Offset = 515
Physical Size = 37242246
Tail Size = 7
Headers Size = 61691
Method = LZMA:27 BCJ2
Solid = +
Blocks = 2


Sub items Errors: 6

Archives with Errors: 1

Sub items Errors: 6
```
## 解決方法
##### `git_local`フォルダを消すことで解決
[Unable to update embedded Git](https://jira.atlassian.com/browse/SRCTREEWIN-7687)

1. PC再起動
2. 
```
C:\Users\ユーザー名\AppData\Local\Atlassian\SourceTree\git_local
```
をフォルダごと削除
3. SourceTree起動
4. オプションのGitから内臓Gitを更新
\bはバックスペースでなく単語境界なので正規表現でうまく動作しない

検索したけど見つからなかったので自分用メモ

※追記 コメントありがとうございます
[\b]を使えばうまくいきまいした

```JavaScript:JavaScript
str = str.replace(/[\b]+/g, '');
```

---------------

- バックスペースを削除

```JavaScript:JavaScript
str = str.replace(/\x08+/g, '');
```

- バックスペースやタブ、改行などを削除

```JavaScript:JavaScript
str = str.replace(/[\x08-\x0D]+/g, '');
```

### ASCII制御文字
https://ja.wikipedia.org/wiki/ASCII#ASCII%E5%88%B6%E5%BE%A1%E6%96%87%E5%AD%97
git cherry-pickで特定のコミットを完全取り消す

## 背景
ローカルでいくつかのコミットから、一つのコミットを無くしたい

```
$ git log -10 --oneline
84a0ea816 commit4
3259ea98b commit3
a7d8e5594 取り消したいcommit
7a1b94742 commit2
7a1b94741 commit1
7a1b94743 Merge pull request xxx(from develop)
```

期待する結果

```
$ git log -10 --oneline
84a0ea816 commit4
3259ea98b commit3
7a1b94742 commit2
7a1b94742 commit1
7a1b94743 Merge pull request xxx(from develop)
```

## 対応方法
### revert
```
$ git revert a7d8e5594
d88adea80 Revert "xx commit"
84a0ea816 commit4
3259ea98b commit3
a7d8e5594 取り消したいcommit
7a1b94742 commit2
7a1b94742 commit1
7a1b94743 Merge pull request xxx(from develop)
```
ただ、これではcommitの内容を取り消しされて、コミット履歴は残ってる

### cherry-pick
いい方法がなくて
developからブランチを切る
commit1,2を入れる
commit3,4を入れる

```
$ git co -b feature/new origin/develop
$ git cherry-pick 7a1b94743..7a1b94742
$ git cherry-pick a7d8e5594..84a0ea816
```
結果

```
$ git log -15 --oneline
84a0ea816 commit4
3259ea98b commit3
7a1b94742 commit2
7a1b94742 commit1
7a1b94743 Merge pull request xxx(from develop)
```

もっと簡単な方法がご存知の方はぜひコメントお願いします。(あるはず)

### rebase
twitte_raruさんからコメントいただいた方法が一番良さそうです。

```
$ git rease -i 7a1b94743
```
出てきた画面で消したいcommitを消して保存する

```
pick 7a1b94743 Merge pull request xxx(from develop)
pick 7a1b94742 commit1
pick 7a1b94742 commit2
pick a7d8e5594 取り消したいcommit
pick 3259ea98b commit3
pick 84a0ea816 commit4
```
完了！一番簡単の気がします。
コピペで使えるELBのアクセスログ解析による事象分析 (ShellScript, Athena)

本記事について、以下のURLへ移行させていただきました。

[コピペで使えるELBのアクセスログ解析による事象分析 (ShellScript, Athena)](https://hayashier.gitbook.io/article/top-contents/elb-accesslog-analysis)
自ディレクトリ以下から bin, obj ディレクトリを全て削除するスクリプト

おそらく3億人の .NET プログラマが書いたであろうスクリプト、 PowerShell で書いてみました。

```powershell:clean.ps1
$dirs = Get-ChildItem -Recurse * | ? { $_.PSIsContainer} | % { $_.FullName} `
 | grep -e bin$ -e obj$ 

foreach ($dir in $dirs) {
    # echo $dir
    rm -rf $dir
}
```

## Mac でも動くぞ!

[PowerShell Core](https://docs.microsoft.com/en-us/powershell/scripting/setup/installing-powershell-core-on-macos-and-linux?view=powershell-5.1) を入れると、 macOS でも動きます。 Visual Studio for Mac と併せてどうぞ(Linux でも動くはｚ)。

```sh:
#!/bin/sh

cd `dirname $0`
pwsh clean.ps1 
```

※実は、 Xamarin.Android のビルド出力には ``obj/Release/android/bin`` みたいなのが含まれることがあるので、完全に ``obj``, ``bin`` を抹消するには ``clean.ps1`` を2回実行します。
Macでlaravelコマンドのパスを通す

## はじめに

Laravelについて検索していると現在の最新バージョンとはexportするパスが違っているので、書いておきます。

## インストールとパスを通すまで

```
$ composer global require "laravel/installer"
```

以上でlaravelがインストール出来るので、お使いのシェルに合わせて設定ファイルに記述をしていく。

#### bashの場合

`.bash_profile` or `.bashrc`の最終行らへんに以下を追加
`username`の部分を適宜変更してください。

```
export PATH="$PATH:/Users/username/.config/composer/vendor/bin"
```

追記したら、`source .bash_profile` or `source .bashrc`をします

#### zshの場合

`.zshrc`の最終行らへんに以下を追加
`username`の部分を適宜変更してください。

```
export PATH="$PATH:/Users/username/.config/composer/vendor/bin"
```

追記したら、`source .zshrc`をします

## 確認

laravelコマンドが使えるか確認をしておきます。

```
$ laravel -v
```
以上でバージョン情報が出ていれば成功です
Pythonでお手軽かつ速めなngram

言語処理100本ノックなど、NLPの基礎的な勉強でngramを実装する場面は多かろうと思います。
`zip` 関数を使うととても簡単に、結構速い実装ができそうなので比べてみました。

```python3
import this
# zen of python が出てくるが無視して良い（適宜眺める）

# 昔思いついたやつ・似たような例はよく見かける
def ngram_(words, n):
    return [tuple(words[i:i+n]) for i in range(len(words)-n+1)]

# 最近思いついたやつ
def ngram(words, n):
    return list(zip(*(words[i:] for i in range(n))))

words = (this.s * 100).split() # 単語の配列

%timeit ngram_(words, 2)
# => 6 ms ± 211 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit ngram(words, 2)
# => 818 µs ± 42.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
```

比較はipythonで適当にやってみましたが、速そうに見えますね。
個人的にはテスト用のテキストが欲しくて呼んだ`this`モジュールのソースの方が面白かったです（参考：[Zen of Pythonの核心に触れよ -- thisでわかるPythonのimportの仕組み](http://bugrammer.g.hatena.ne.jp/nisemono_san/20111205/1323053038)）
Project Euler Q70 【トーティエント関数の置換】

Project Eulerをワンライナーで解いてみる。
間違っていたらコメントください。


## 問題
オイラーのトーティエント関数 $φ(n)$ (ファイ関数とも呼ばれる) とは, $n$ 未満の正の整数で $n$ と互いに素なものの個数を表す. 例えば, $1, 2, 4, 5, 7, 8$ は$9$未満で$9$と互いに素であるので, $φ(9) = 6$ となる.
$1$ は全ての正の整数と互いに素であるとみなされる. よって $φ(1) = 1$ である.

面白いことに, $φ(87109)=79180$ であり, $87109$は$79180$を置換したものとなっている.

$1 < n < 10^7$ で $φ(n)$ が $n$ を置換したものになっているもののうち, $n/φ(n)$ が最小となる $n$ を求めよ.

## アプローチ
$φ(n)$の導出

$n=p_1^{a_1}p_2^{a_2}...p_k^{a_k}$　　$p_1<p_2<...<p_k$
と素因数分解できるとき、$φ(n)$は下記式で表せる。

```math
φ(n)=n(1-\frac{1}{p_1})(1-\frac{1}{p_2})...(1-\frac{1}{p_k})
```

以上、引用元：[Project Euler 69 - maple0705のブログ](http://maple0705.hatenablog.jp/entry/2017/08/11/230611)

## 解答

```bash
time seq 2 10000000 |
factor |
awk '{delete a;printf $1*1" ";for(i=2;i<=NF;i++){a[$i]=1};for(k in a){printf k" "};print ""}' |
awk '{a=$1;for(i=2;i<=NF;i++){a*=(1-1/$i)};print $1,a}' |
awk 'length($1)==length($2)' |
awk '{split($1,a,"");split($2,b,"");n=asort(a);m=asort(b);printf $0" ";for(i=1;i<=n;i++){printf a[i]};printf " ";for(i=1;i<=m;i++){printf b[i]};print ""}' |
awk '$3==$4{printf("%d %1.10f\n",$1,$1/$2)}' |
sort -k2,2n |
head -1 |
awk '$0=$1'
8319823

real    1m19.407s
user    2m27.063s
sys     0m1.186s
```

数学的なアプローチがよく分からなかったので全件計算した。
$n/φ(n)$を計算する処理で四捨五入の関係がある為、有効数字を増やして計算しないと同じ値になってしまい、結果取得する$n$が変わってしまう現象が起きた。

計算に時間がかかっているが、対象が多い為よしとする。

## 答え合わせ
こちらのサイト様と一致していればOKとした。
[Project Euler 70 _ ファイ関数の置換 - PEをMathematicaで](http://variee.hatenadiary.com/entry/2017/04/13/195642)
別のディレクトリで、同じディレクトリ構造の同じ名前のファイルを削除する

同じディレクトリ構造でトップのディレクトリ名が異なる場合の、同じ日のログをまとめて削除するシェル。
想定しているのは以下のファイル。これがカレントディレクトリの以下に、[pc名]\LOG\[日付名].txt で入っている。
pc1/LOG/2018-01-20.txt
pc2/LOG/2018-01-20.txt

`ls -F|grep /| sed "s/$/LOG\/2018-01-20.txt /g" |sed "s/^/rm /g" | sh`


ls -F|grep / → ディレクトリの一覧を表示(ファイルは表示しない)
sed "s/$/LOG\/2018-01-20.txt →ディレクトリの後ろに、子ディレクトリとファイル名を追加する
sed "s/^/rm /g" → ディレクトリの前に、コマンドを追加する
ffmpeg で mp4 や webm などの動画ファイルから mp3 VBR に変換して抽出する

- `-i` でファイル指定
- `-vn` で video 要素を消す
- `-qscale:a 0` で圧縮時の音質レベルを調整しつつ、VBR にする
  - 参考: https://trac.ffmpeg.org/wiki/Encode/MPEG-4
  - `You can select an audio quality level with -qscale:a (or the alias -q:a).`
  - brew で入れた ffmpeg であれば `libmp3lame` が利用されるため、lame のライブラリの仕様に準拠した挙動になる
  - qscale 指定がなければデフォルトの音質設定（圧縮係数）になる、およそ平均 `128kbps` 付近になるように圧縮される
- `<outputfile>` を末尾で指定する

```bash
ffmpeg -i <inputfile> -vn -qscale:a 0 <outputfile>
```

- `for do ... done` で回す時は、拡張子の置き換えを行うと良い

```bash
for file in *.mp4
do
    ffmpeg -i ${file} -vn -qscale:a 0 ${file/%mp4/mp3}
done
```
RStudioでTerminalが使えない時

最近のRStudioやRStduio ServerではTerminalにアクセスできる。
しかし、なんらかの要因でアクセスできない場合がある。

そんなときは、

- RStudioのToolsメニュー
    - Global Options
        - Terminal
            - Connection
                - Connect with WebSockets

のチェックマークを外してみるといい


参考までに私の環境

R version 3.4.3 (2017-11-30)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Linux Mint 18.3

RStudio version 1.1.419 

丁度、Guake Terminalを導入した頃だったのもあり、PATHがうまく通ってないのかと思って

- RStudioのToolsメニュー
    - Global Options
        - Terminal
            - Shell
                - New terminals open with: Bash
       
から、BashをCustomにしてPATHを指定してみるも、WebSocketsを使っている限りはうまくいかなかった。
会社で少し盛り上がった Project Euler をやってみる 007

# Problem 007
> 素数を小さい方から6つ並べると 2, 3, 5, 7, 11, 13 であり, 6番目の素数は 13 である.
> 10001 番目の素数を求めよ

---

# Answer 007 (Python)

```python3
class Problem7:

    LIMIT = 10001
    PRIME = []

    def main(self):
        i = 1
        while(len(self.PRIME) < self.LIMIT):
            i = i + 1
            if self.isPrime(i):
                self.PRIME.append(i)
        print(self.PRIME[-1])

    def isPrime(self, num):
        for i in self.PRIME:
            if num % i == 0:
                return False
            if i * i > num:
                break
        return True


if __name__ == '__main__':
    p = Problem7()
    p.main()
```
---

# (参考) Project Euler とは

[Project Euler](https://projecteuler.net/) はプログラミングで数学の問題を解くサイトです。問題は600問以上あるので、勉強に使うのも良し、楽しむのも良しです。

サイトに登録すれば、解答を submit することができ、その場であっているか判定してくれます。

また、問題だけであれば、日本語に翻訳された Wiki もあるのでそちらを見ながらやると捗ると思います。

[Project Euler(日本語訳)](http://odz.sakura.ne.jp/projecteuler/)
Elasticsearch のバージョンアップではまった事

Elasticsearch のバージョンアップが激しすぎて少し目を話していたら大幅において行かれていました
現在、本番環境で動いているのは1.5なのですが、これを5.6系 にアップデートしようと思います
なお、記事執筆時点で6.1系がリリースされていますが、1.5系から一気に6.1系にアップデートするよりも、5.6系にアップしてから6.1系にアップデートする方が良いだろうという判断で5.6系を選択しております

# リクエストパラメータが変更されている

## リクエストヘッダの明示的な指定

- リクエストヘッダに「Content-Type: application/json」を明示的に指定してください。

```
[誤]  curl                                     -XGET "http://gessy0129.com:9200/results/auction/_search" --data '{"query":{"match_all":{}}}'
[正]  curl -H "Content-Type: application/json" -XGET "http://gessy0129.com:9200/results/auction/_search" --data '{"query":{"match_all":{}}}'
```

+ 「Content-Type: application/json」を指定しないと elasticsearchのログに下記「warnning」が記載されます。
    + 次のバージョン（6.0）からは指定が必須となり、未指定の場合はエラーになります。

```
----------------------------------------------------------------------------------------------------------------
Content type detection for rest requests is deprecated. Specify the content type using the [Content-Type] header
----------------------------------------------------------------------------------------------------------------
```

## 使用しなくなったオプション

+ zero_terms_query
+ operator

## 便利になったこと

+ 検索結果が不要でヒット件数だけ取得したい場合は `_search` ではなく `_count` にリクエストを投げれば件数取得ができる

```
curl -H "Content-Type: application/json" -XGET "http://gessy0129.com:9200/results/auction/_count" --data '{"query":{"match_all":{}}}'
```


# 補足

今回記載した内容はあくまでもバージョンアップしたプロダクトではまった事なので、
これが全てではないです
Docker上でjetbrains製品を起動する方法

メモ書きです。

DockerはGUIインストール済み、dockerユーザーでGUI立ち上げを想定  

# 設定

```bash:.bashrc

# jetbrains製品の場所を指定
CLHOME=$HOME/.local/share/JetBrains/Toolbox/apps/CLion/ch-0/173.4301.33
CLCONF=.CLion2017.3
PYCHOME=$HOME/.local/share/JetBrains/Toolbox/apps/PyCharm-P/ch-0/181.3007.3/
PYCCONF=.PyCharm2018.1


function jb_gui() {
  docker run --privileged -it --rm  \
  -e DISPLAY=$DISPLAY \
  -v /tmp/.X11-unix:/tmp/.X11-unix:rw \ #Xソケットを共有
  -v $HOME/.gitconfig:/home/docker/.gitconfig \ # git設定
  -v $CLHOME:/home/docker/clion \ # clion
  -v $HOME/${CLCONF}:/home/docker/${CLCONF} \ # clion設定
  -v $PYCHOME:/home/docker/pycharm \ # pycharm
  -v $HOME/${PYCCONF}:/home/docker/${PYCCONF} \ # pycharm設定
  -v $HOME/.java:/home/docker/.java \ # ライセンス情報
  -v /work:/work \ # プロジェクトディレクトリをホストと同じ位置にマウントするととても捗る
  IMAGE_TAG /bin/bash
}

```

# 起動

```bash
eliza@eliza-pc:~$ jb_gui
docker@eliza-pc:~$ ~/clion/bin/clion.sh &
```
【pyenv】Ubuntu16.04にPython環境を構築する【2018年】

Ubuntu16.04にpyenvを使ったPython環境を、
できるだけ最小限で構築する。
(執筆時期：2018年1月30日)

*※ gitは予めインストールしておく*
➠ `sudo apt-get install -y git`

| 環境 | バージョン |
| :--: | :--: |
| macOS High Sierra | 10.13.2 |
| VirtualBox | 5.2.6 |
| Vagrant | 2.0.1 |
| box | ubuntu/xenial64 |


### 1. pyenvをホームディレクトリに `.pyenv` としてクローンする

```shell
$ git clone git://github.com/yyuu/pyenv.git ${HOME}/.pyenv
```

### 2. pyenvの環境変数を設定する

```shell
$ cat << EOF >> ${HOME}/.profile
export PYENV_ROOT=\${HOME}/.pyenv
export PATH=\${PYENV_ROOT}/bin:\${PATH}
eval "\$(pyenv init -)"
EOF
$ source ${HOME}/.profile
```

*※ bash以外のシェルを利用する場合はその環境に合わせて `.profile` を置換する*
*➠ 例: zshの場合は `${HOME}/.zshenv`*

### 3. Pythonのインストールに必要なパッケージをインストールする

```
$ sudo apt-get install -y \
    zlib1g-dev \
    libbz2-dev \
    libreadline6 \
    libreadline6-dev \
    libsqlite3-dev \
    libssl-dev
```

### 4. Pythonをインストールする

```
# Python2.7のリストを表示
$ pyenv install --list | grep 2.7

# 表示されたリストからインストールしたいバージョンを選びインストール
$ pyenv install 2.7.14

# 使用するPythonを設定
$ pyenv global 2.7.14

# Pythonのバージョンを確認
$ python --version
```

*※ インストールするPythonのバージョンは各自変更する*

以上でUbuntu16.04にPythonの環境を構築できる
Docker上でWebカメラ(UVC)を使う方法

Docker上でWebカメラを使って開発したいなーを実現します。
メモ程度です。

Docker上でGUIを起動する方法についてはこちらの記事を参照してください。
[DockerでポータブルなLinux開発環境(GUI付き)を構築する](https://qiita.com/gitcell/items/8b1f154edc26def7ecce)

```Dockerfile:Dockerfile
# 前略
# webcam 確認用 GUI必要です。
RUN apt-get update && apt-get install -y \
  uvccapture \
  guvcview \
  cheese
```

```bash:launch.sh
function launch_docker() {
  local image_tag=$1
  # GUI不要の場合、--deviceのみでOK
  # GUI用にすべてのX接続を受け入れる
  xhost +
  docker run --privileged -it \
  -e DISPLAY=$DISPLAY \ # Xの宛先をホストと同一に
  -v /tmp/.X11-unix:/tmp/.X11-unix:rw \ # Xソケットを共有
  --device /dev/video0:/dev/video0:mwr \ # カメラデバイスを共有
  --device /dev/video1:/dev/video1:mwr \ # 複数指定も可能
  ${image_tag} /bin/bash
  }
launch_docker image_tag
```

後はdocker内で ```cheese``` などを実行するとホストと同じようにカメラ映像を確認できます。
Package inputenc Error が起こったら一度試してほしいこと

※簡単なトラブルシューティングです。


```console
! Package inputenc Error: Unicode char ． (U+FF0E)
(inputenc)                not set up for use with LaTeX.
```

と怒られた時はどうすればいいか。
このコンソールの場合、ユニコード文字(Unicode char)`U+FF0E`をGoogleなどで調べてみます。

すると、[FULLWIDTH FULL STOP](http://www.fileformat.info/info/unicode/char/ff0e/index.htm)と出てきます。
これで、全角ピリオドが悪さをしていたことがわかります。
該当する部分に全角ピリオドがないか確かめて、消せば解決するはずです。

実は、コンソール上に全角ピリオドが表れているのですが、気づかずに解決に時間がかかってしまいました。
ワイヤーフレームツール5選

画面設計書を書くのが面倒なのですがオフショアやリモートワークを推奨していくとどうしても設計書の壁にぶち当たります。
純和風にExcelに画面を一個一個コピペしてくというやり方もできるのですが、画像の中に表示された日本語が読めなかったり色々な不都合がありました。
WireFrameツールとウェブアノテーションの組み合わせである程度業務を効率化できないかなと思って有望なツールを選出します。

### [Prott](https://prottapp.com/ja/plans/)
1.WebベースのGUI
2.30日間無料で使える
3.共有とスライドショーの見栄えがいい
![スクリーンショット 2019-06-27 14.54.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89997/0e3da737-27d3-471d-59d5-4bf0fad09457.png)

[価格表](https://projects.invisionapp.com/d/main#/upgrade/plans?openedDueTo=plans%20page)

### [Adobe XD](https://www.adobe.com/jp/products/xd.html?sdid=19SCDRPN&mv=search&ef_id=EAIaIQobChMI4LK2gf2I4wIVl3ZgCh2SPgl9EAAYASAAEgK7UfD_BwE:G:s&s_kwcid=AL!3085!3!341513906623!b!!g!!%2Badobe%20%2Bxd)

1.ネイティブベースのGUI
2.Adobe製品との互換性
3.prototypeモードとdesignモードがあり
prototypeモードでpublishするとURLを共有できてコメントなどをつけられるannotationの機能がついている
4.上記のProttよりも使用感がプロユース

https://helpx.adobe.com/jp/xd/how-to/make-a-prototype-easy.html

![スクリーンショット 2019-06-27 14.56.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89997/2064c33c-10ca-3e4f-347e-6214df12efc0.png)


### [Invision](https://www.invisionapp.com/)
1.WebベースのGUI
2.SketchやPhotoShopからインポート可能
3.どちらかというとアノテーションツールのNotable Extensionに近いのでデザイン自体を揉んで行くのには利用できそう
4.ワークフローなど管理できるのでいい
5.画面設計書としてはちょっと向いていない
6.モックアップ用にはInvisionStudioを使うといいらしい

[価格表](https://projects.invisionapp.com/d/main#/upgrade/plans?openedDueTo=plans%20page)

![スクリーンショット 2018-01-29 16.01.36.png](https://qiita-image-store.s3.amazonaws.com/0/89997/9141d6b5-afec-60ba-be4a-abe003328831.png)
![スクリーンショット 2018-01-29 16.08.48.png](https://qiita-image-store.s3.amazonaws.com/0/89997/451203f4-d531-077e-127e-5626952f0b05.png)


### [Justmind](https://www.justinmind.com/)
1. GUIツールはMAC/Windowsのネイティブがそれぞれ選択できる
2. 作成したものがURLで共有/HTML出力可能
3. シュミレータがついてる
4. シュミレータで見られるのと同じものを共有できる
5. JIRAのチケット管理にエクスポートできる

[価格表](https://www.justinmind.com/pricing)

<img width="1440" alt="スクリーンショット 2018-01-30 10.50.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/89997/0f8bda0f-1d39-cf3d-ac68-6bea0868b63a.png">
<img width="1245" alt="スクリーンショット 2018-01-30 10.51.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/89997/0f098718-c5b9-df01-c1e8-799dcf0a090a.png">


### [Sketch](https://www.sketchapp.com/)
1. MACネイティブのGUI
2. チームで共有できる
3. プラグインがたくさんある(SVG/ビットマップ圧縮,フォント作成補助）
4. コミュニティサイトがある

[価格表](https://www.sketchapp.com/pricing/)

![スクリーンショット 2018-01-29 16.17.03.png](https://qiita-image-store.s3.amazonaws.com/0/89997/9a264dc3-2f4d-1329-1304-ae4219ecbd11.png)

### [Axture](https://www.axure.com/?gclid=EAIaIQobChMIjeiDrsP82AIViZO9Ch3TEQZjEAAYASAAEgIUuPD_BwE#a=features)
1. GUIツールはMAC/Windowsのネイティブがそれぞれ選択できる
2. 作成したものがURLで共有/HTML出力可能 
3. ボタンイベントなどを設定できて機能的なモックアップの作成ができる
4. フローチャート,ワイヤーフレーム,モックアップ,ユーザージャーニー,ペルソナ,アイデアボードを追加できる

[価格表](https://www.axure.com/buy)

![スクリーンショット 2018-01-29 15.29.09.png](https://qiita-image-store.s3.amazonaws.com/0/89997/9ca1d0ac-56c3-3901-f1b3-706c2be695f7.png)
tmuxpの導入

## 概要
tmuxでのsession-managerを探していたらtmuxinatorとtmuxpを見つけたものの, tmuxinatorはruby導入してgemから, tmuxpはpython導入してからpipからと, どちらも言語依存. ただでさえ管理が面倒な言語パッケージ(早く全言語統合パッケージを作ってくれ)だが, pythonはよくお世話になってる言語なので, tmuxpを自分の環境に導入した. qiitaというか日本語記事が一切合切tmuxpには存在してなかったのでちょうどいい機会なので記事を書くことにする.

---
###### 補足情報
repository

- tmuxinator: <https://github.com/tmuxinator/tmuxinator>
- tmuxp: <https://github.com/tony/tmuxp>

環境

- tmux -V -
tmux 2.6
- pyenv version -
anaconda3-5.0.1
- pip -V -
pip 9.0.1

## 導入方法
基本的に例によってtmuxpのリポジトリにそって導入

### 1. Installation
```zsh
❯ pip install --user tmuxp
❯ tmuxp
Usage: tmuxp [OPTIONS] COMMAND [ARGS]...

  Manage tmux sessions.

  Pass the "--help" argument to any command to see detailed help. See
  detailed documentation and examples at:
  http://tmuxp.readthedocs.io/en/latest/

Options:
  -V, --version     Show the version and exit.
  --log_level TEXT  Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  --help            Show this message and exit.

Commands:
  convert  Convert a tmuxp config between JSON and YAML.
  freeze   Snapshot a session into a config.
  import   Import a teamocil/tmuxinator config.
  load     Load tmuxp workspaces.

```
--userオプションはuser環境だけにインストールできるやつ.
インストール後ちゃんとコマンド動いてることを確認.
command not foundの場合は, --userオプションのPATH関係通ってるか確認をば.

### 2. TMUX sessionのロード.
ここのスタイルはtmuxinatorと同じYAMLを使う様子.
[teamocli](https://github.com/remiprev/teamocil)使えば自動でYAML履いてくれるらしいがやはりgem依存.
rubyのgemはrailsによるトラウマでdocker以外でいじりたくないから仕方なく手作業.

内容はtmuxpリポジトリ除いても[tmuxinator](https://github.com/tmuxinator/tmuxinator)と同じって書いてあるだけなので, tmuxinatorのREADMEを見ながら書こう.
自分はtmuxinatorにあるsample.yamlをいじって書いた. 作ったものをgistに一応あげとく
<https://gist.github.com/take-sei/d051fe227cbb98dc83b19e94e35a5f37>

こいつを~/.tmuxp/の中においてあげて, 以下のコマンドを実行. (filenameは.yamlつけずにいける.)

```zsh
❯ tmuxp load filename
```

とすると立ち上がるのを確認できる.

#### 詰まりかけた点
##### 1. layoutってなんや
色々デフォルトでセットされているようですが, 一番気に入ったlayoutを対応させるには,

``` zsh
❯ tmux list-windows
1: dev_window* (4 panes) [318x61] [layout a3bc,318x61,0,0{135x61,0,0,1,135x61,136,0[135x45,136,0,2,135x15,136,46,3],46x61,272,0,4}] @1 (active)
```
とでてきたやつの, layout ~ ]@1までの間の数字を入れる様子. kwskは[ここ](https://wiki.archlinux.jp/index.php/Tmux#X_.E3.82.AF.E3.83.AA.E3.83.83.E3.83.97.E3.83.9C.E3.83.BC.E3.83.89.E3.81.AE.E7.B5.B1.E5.90.88)に.

##### 2. panesでerrorをはく
どうやら, 何かしらのコマンドを各paneで実行させないとエラーがおきる模様. 仕方がないのでclearを実行させた.
Auroraのメンテナンスイベントについて

Auroraのメンテナンスイベントについて知らなければ！という衝動に突き動かされたわけではなく
意図しないアップグレードで少しやられてしまったので必要に迫られた故、メモ書きする。


# メンテナンスの種類

RDSのマネージメントコンソールのクラスターのメンテナンス列で確認できる模様。
確認時に気づいたけれど大幅にUIが変更されたなー。Lambdaは頻繁に変わっているイメージだけど。。。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/143580/e097c3f7-896f-4a66-8fa5-d41594ab2a2c.png)

利用可能(Available)と必須（Required)がある。  

Availableなイベントは延期が可能で、Requiredなイベントはメンテナンスウィウンドウで自動実行される。  

Requiredなイベントについて、事前に知る必要がある。

# describe-pending-maintenance-actions

Auroraのメンテナンス通知はメールで届いたりしないので、自分でAPIを叩いてメンテナンス情報を取得する必要がある。


[describe-pending-maintenance-actions](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-pending-maintenance-actions.html)


上記APIを叩くと、以下のようなレスポンスが取得できる。

```
{
    "PendingMaintenanceActions": [
        {
            "PendingMaintenanceActionDetails": [
                {
                    "Action": "system-update", 
                    "Description": "Aurora 1.16 release"
                }
            ], 
            "ResourceIdentifier": "arn:aws:rds:ap-northeast-1:XXXXXXXX:cluster:XXXXXXXXXXXXXX"
        }
    ]
}

```

Requiredや、Available等表示されない。
どのように知るか？  
# API Output

## Action  

Auroraクラスタのメンテナンスの場合、基本的には"os-upgrade"あるいは"system-update"が返される。  

* os-upgrade:   
AuroraクラスタのOS更新
* system-update:  
AuroraクラスタのDBエンジン更新
* db-upgrade:  
主にRDS DBインスタンスにおけるDBエンジンの更新

## AutoAppliedAfterDate, ForcedApplyDate  
* AutoAppliedAfterDate:   
更新が適用されるメンテナンスウィンドウの指定。この項目で指定された日付以降の最初のメンテナンスウィンドウでアクションを実行される。
* ForcedApplyDate:   
指定された場合、メンテナンスウィンドウ外でも指定された日時でメンテナンスが実行される。  

####「メンテナンスウィンドウ外でも」　
これは絶対チェックやな。

## OptInStatus  
AutoAppliedAfterDate, ForcedApplyDateが指定されない場合や、指定された日時よりも早くメンテナンスを実行したい場合はapply-pending-maintenance-actionを--opt-in-typeオプションを指定して実行することができる。
メンテナンスに対する選択(opt-in)状態を示す。
opt-in とは「事前許可を求めるやりかた」というようなことらしい。
この項目は明示的にapply-pending-maintenance-actionを実行した場合にのみ追加される。

[apply-pending-maintenance-action](https://docs.aws.amazon.com/cli/latest/reference/rds/apply-pending-maintenance-action.html)
ステータスは以下。

* next-maintenance:
次のメンテナンスウィンドウ
* immediate: 即座
* undo-opt-in: next-maintenanceの指定がキャンセルされた

## CurrentApplyDate  
CurrentApplyDateは、AutoAppliedAfterDate, ForcedApplyDate, OptInStatusのすべてを考慮したうえで、「現時点で実際にメンテナンスの自動適用が予定されている日時」


# 結論
AutoAppliedAfterDate 、ForcedApplyDateが設定されているものがRequiredなイベントなので、事前にちゃんと知るようにする。

## 参考サイト
- [Amazon RDSのメンテナンスについて調べてみた](http://blog.jicoman.info/2017/01/rds_maintenance/)
Unity ARKit Pluginを動かすだけの記事

arの勉強会をしたのでメモ。
細かいことは他の記事へ。


# アセットをインポートする

<img width="578" alt="スクリーンショット 2018-01-29 22.41.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/64334/3cc3de96-e96a-d28f-fe9a-4c82343ce072.png">

# シーンを選択する

UnityARkitRemoteを選択
<img width="645" alt="スクリーンショット 2018-01-29 22.42.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/64334/02e58696-3d04-6ff9-db97-8585475c68bd.png">

# ビルドする
Build押下
xcodeが吐かれる
<img width="634" alt="スクリーンショット 2018-01-29 22.42.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/64334/dbdb4db5-3970-b70b-a846-86d1cb6004b6.png">

# xcodeをビルド
実機でビルド
<img width="448" alt="スクリーンショット 2018-01-29 22.48.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/64334/c7457476-e223-0a2f-ffd2-47c59838ae3e.png">

# 動かす

実機側でアプリを起動する
unity側で実行ボタンを押し、remote start buttonぽいのをクリックすると動く。


# ちなみに

ちょっとしたデバッグならarkit remote使うと楽
https://lilea.net/lab/how-to-use-arkit-remote/
arkit1.5で壁検出もできるようなったよ
http://japanese.engadget.com/2018/01/25/arkit-1-5/
Serverless Framework v1.26.0リリースノート

[Serverless Framework](https://serverless.com/framework/)v1.26.0がリリースされました。その内容を機能毎にまとめています。

## Shared API
新たにShard APIという機能がリリースされました。これは既存のCloudFormation StackでデプロイされているAPI Gatewayを別のStackから参照することで、既存のAPIの配下に新たにAPIリソースを追加するという機能です。

Serverless Framework、というかCloudFormationには1つのStackにつき、200個までしかリソースが上げられないという制限があります。そしてAPI Gatewayのエンドポイントを大量に作ってその制限に引っかかるケースが多いようです。これに対応するための機能となります。

具体的には以下のようにprovider配下に参照したいAPI Gatewayの情報を定義することで機能が使えるようになります。


```yaml:serverless.yml

service: service-b
provider: 
  apiGateway:
    restApiId: xxxxxxxxxx # REST API resource ID. Default is generated by the framework
    restApiRootResourceId: xxxxxxxxxx # Root resource, represent as / path

functions:
  create:
    handler: posts.createComment
    events:
      - http:
          method: post
          path: /posts/{id}/comments
```

## AWS Go support
Go用のスターターテンプレートがFramework内部に内包されました。複数functionにも対応できるようにディレクトリ毎にmain.goを分離するような仕組みとなっています。

使いたい場合は以下のコマンドで出来ます。

```
$ serverless create -t aws-go 
$ serverless create -t aws-go -p service-path
```

## serverless.js configuration file support
Frameworkの設定は、serverless.ymlで記述しますが、今回serverless.jsという形式の設定ファイルをサポートしました。

要は設定ファイル内にJavaScriptを直接記述できるので、動的な値を取得して設定値とするといったことが可能になります。例えばShard APIの機能を使うにはAPI GatewayのID情報をserverless.yml内にハードコーディングしなければなりません。しかし、serverless.jsを使うことで動的にその部分を処理することが可能となります。

具体的には以下のように`module.exports`に設定値のJsonを渡す形になります。

```js:serverless.js

- JavaScriptコード -

module.exports = {
  provider:
    name: "aws"
  ....
}
```

## logRetentionInDays config
serverless.ymlのproviderセクションにCloudWatchLogsのログ保持期間のデフォルト値を設定できるようになりました。今まではデフォルト値が30日でその設定を上書きしたい場合は以下のようにresourcesセクションで上書きをしていたかもしれません。

```yaml:serverless.yml
resources:
  Resources:
    WriteDashPostLogGroup:
      Type: AWS::Logs::LogGroup
      Properties:
        RetentionInDays: "10"
```

しかし、これからは以下の設定で済みます。

```yaml:serverless.yml
provider:
  logRetentionInDays: 10
```

## `serverless create`コマンドへの`--template-path`オプションの追加

このオプションを使うことでローカルにあるServerless projectをコピーして新規プロジェクトがセットアップできます。以下のような形です。

```
serverless create --template-path /usr/local/src/sls-project --path my-service
```

## Java用にPOJO input typeへの対応

Javaを使用する際にPOJO (Plain Old Java Object) 型が可能となりました。
具体的にはAWSのドキュメントを参照： https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/java-programming-model-req-resp.html
AWS IAM勉強まとめ

・Identity and Access Management
AWS操作をセキュアに行うための認証・認可・アクセスポリシーの仕組み

「IAM ユーザー」単位に発行できるアクセスキーは最大2個
3個目を発行しようとすると "Cannot exceed quota for AccessKeysPerUser: 2" とエラーになる

・ユーザ
5000ユーザまで作成可能

・グループ
100グループまで作成可能

・MFA（Multi-Factor Authentication）
多要素認証

・ルートアカウントは極力利用しない

・`Credential Report`
認証情報のレポート

・パスワードローテーション
パスワードの有効期限設定可能

・`管理ポリシー`
独立したポリシー。`AWS管理ポリシー`と`カスタマー管理ポリシー`が存在
→再利用可能。変更管理の一元化。複数のIAMエンティティにアタッチあk脳

・`インラインポリシー`
従来のIAMポリシー。1つのポリシーを共有できない

・デフォルトdeny

・ポリシーはユーザーベースとリソースベースで設定可能
特定のIPからのみ接続可能のような設定も可能

・CloudTrailでユーザのアクティビティのログ収集。S3上に保管

・最小限の特権。Service Ladr Accessed Data
未使用または最近使われてないユーザとサービスを特定。グループに分ける

・IAMロール
サービスやアプリケーションなどのエンティティに操作権限を付与
ユーザやグループに紐付かない
認証情報は自動的にローテーション
認証情報はSTSで作成
→EC2に認証情報がないため、安全
SDK, CLIに対応

・AWSアカウント: ドアキー
IAMユーザ: 従業員カード
Temporary Security Credential, IAM Role: ホテルキー

・クロスアカウントアクセス

・ID連携
LDAP認証したユーザにはS3権限を与えるなど。
ユーザにはTemporaryキーを与える
SAML2.0(Security Assertion Markup Language)と互換性

・SAML認証
ユーザ→Idpに認証情報リクエスト→認証情報受け取り→AWS STS(Security Token Service)に問い合わせ→一時的な認証情報受け取り→AWSサービスにアクセス

・SSOエンドポイントを利用
サインインURLをクライアントに返答
→クライアントはリダイレクトでコンソールにアクセス
コンソールが使用できる時間や時間帯を制御可能

・既存のIdpを利用
IdpとSTSで通信。ユーザはコンソールへリダイレクトできる

・ルートアカウントは使用しない
・個々のIAMユーザ作成
・ユーザへのアクセスはグループ
・最小限の特権
・強度の高いパスワードポリシー
・特権ユーザにはMFA
・認証情報を共有せず、ロールを使用
・監視も大事に

参考URL：
https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-aws-identity-and-access-management-aws-iam
[メモ] Raspberry Pi3でUSBブートする

開発機としてのRaspberry Pi3に、HDD（SSD使いたいけど、HDDがあったから）を繋いでHDDからブートして使うためのメモ書きです。もちろんswapもHDDに設定してるので安心とかです。

2018/08/18 ファイルシステムへのラベル付を追記。

# 1. オリジナルの情報

[How to Boot from a USB Mass Storage Device on a Raspberry Pi3](https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/msd.md)
[Pi3 Booting Part I: USB Mass Storage Boot Beta](https://www.raspberrypi.org/blog/pi-3-booting-part-i-usb-mass-storage-boot/)

まだベータ状態でしたっけ。

# 2. ラズパイの更新

```
$ sudo apt update
$ sudo apt install -y rpi-update
$ sudo rpi-update
```

# 3. /boot/config.txtの修正

```
$ echo "program_usb_boot_mode=1" | sudo tee -a /boot/config.txt
$ echo "program_usb_boot_timeout=1" | sudo tee -a /boot/config.txt
$ vcgencmd otp_dump | grep 17:
> 17:1020000a
$ sudo reboot
$ vcgencmd otp_dump | grep 17:
> 17:3020000a
```

# 4. USBデバイスの準備
## 4.1 パーティション作成

ここでは`/dev/sda`としていますが、もちろん正しいデバイス名にしましょう。

```
$ sudo parted /dev/sda
(parted) mktable msdos
Yes
(parted) mkpart primary fat32 0% 100M
(parted) mkpart primary ext4 100M 100%
(parted) print
(parted) quit
```

## 4.2 ファイルシステム作成

```
$ sudo mkfs.vfat -n boot -F 32 /dev/sda1
$ sudo mkfs.ext4 /dev/sda2
$ sudo e2label /dev/sda2 rootfs
```

## 4.3 mSDからのコピー

```
$ sudo mkdir /mnt/target
$ sudo mount /dev/sda2 /mnt/target/
$ sudo mkdir /mnt/target/boot
$ sudo mount /dev/sda1 /mnt/target/boot/
$ sudo apt update; sudo apt install -y rsync
$ sudo rsync -ax --progress / /boot /mnt/target
```

一応 sshの鍵を再作成。

```
$ cd /mnt/target
$ sudo mount --bind /dev dev
$ sudo mount --bind /sys sys
$ sudo mount --bind /proc proc
$ sudo chroot /mnt/target
$ rm /etc/ssh/ssh_host*
$ dpkg-reconfigure openssh-server
$ exit
$ sudo umount dev
$ sudo umount sys
$ sudo umount proc
```

## 4.4 ブートデバイスの設定

```
$ sudo sed -i "s|root=/dev/mmcblk0p2|root=/dev/sda2|" /mnt/target/boot/cmdline.txt
$ sudo sed -i "s|/dev/mmcblk0p|/dev/sda|" /mnt/target/etc/fstab
```

## 4.5 USBデバイスをアンマウントして再起動

```
$ cd
$ sudo umount /mnt/target/boot
$ sudo umount /mnt/target
$ sudo shutdown -h now
```

停止後にmSDを抜いてUSBデバイスだけにしてから電源を入れ直してみましょう。
Github の草を取得して自分のサービスに表示する

# 概要
[こちらの記事](https://qiita.com/longtime1116/items/2181bc63dbc68193b39f)で失敗したのでリベンジ。

# どんな感じになる？
![スクリーンショット 2018-01-30 9.41.28.png](https://qiita-image-store.s3.amazonaws.com/0/183649/34e69bc3-7c5e-e66f-264a-ba4b32f69cc9.png)
# ソースコード

vue ファイルは以下

```html:App.vue
<template>
  <div>
    <input type="text" v-model="msg" >
    <button @click="getGarden()">get the garden!</button>
    <p v-if="msg.length > 0 && svg.length > 0">
      user: {{msg}}
      <br/>
      <span v-html="svg"></span>
    </p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      msg: 'longtime1116',
      svg: '',
    };
  },
  methods: {
    getGarden() {
      const XHR = new XMLHttpRequest();
      const query = `http://localhost:8081/getGarden.php?url=https://github.com/users/${this.msg}/contributions`;
      XHR.open('GET', query, true);
      XHR.onreadystatechange = (() => {
        if (XHR.status === 200) {
          this.svg = XHR.responseText;
        }
      });
      XHR.send(null);
    },
  },
};
</script>
```
以下の php を、`php -S localhost:8081` で起動しておきます。

```php:getGarden.php
<?php
//$data = file_get_contents("https://github.com/users/longtime1116/contributions");
$data = file_get_contents($_GET['url']);
header("Access-Control-Allow-Origin: *");
header("Content-Type: text/plain");
print $data;
```

# 解説

## vue.js 側
axios や fetch で php サーバからの応答を取得すると、ReadableStream 型で response が返ってきて処理が面倒くさいので、XMLHttpRequest を使いました。
(なんでXMLHttoRequestならうまくいくのかいまいちよくわかっていない。。。Promise形式だとReadableStreamを使うようになっている？)

また、取得した文字列を javascript 側で SVG として展開するために、[テンプレート構文](https://jp.vuejs.org/v2/guide/syntax.html)を使っています。


## PHP側
CORS対策として、間に1枚PHPサーバをかませるようにしています。
PHP の方で`Access-Control-Allow-Origin`を付与しているのがそれです。

# その他メモ
変数名に改善の余地あり。
URL そのままではなく user_name だけ php に渡すようにした方がいい。

# Github リポジトリ
https://github.com/longtime1116/github_gardener
apacheでVirtualNameが一致しないと言われる

# はじめに
apacheのエラーログ(`/etc/httpd/logs/error_log`)にこんなメッセージが出てました。

```
Misconfiguration of certificate's CN and virtual name. The certificate CN has localhost4.localdomain4. We expected <ip-address> as virtual name.
```
このエラー解決方法を調べました。

# 環境
Red Hat Enterprise Linux Server release 6.8 (Santiago)
Apache/2.2.15

# 調査結果
エラーメッセージ内にcertificate's CNと出ているので、ssl関連のエラーでしょう。
というあたりをつけて調べます。

## apacheのssl通信用のモジュール
webで調べるとどうやらmod_sslとmod_nssというモジュールがあるようです。
実際に確認。

```
# httpd -M |grep -e 'nss' -e 'ssl'

httpd: Could not reliably determine the server's fully qualified domain name, using <ip-address> for ServerName
 dnssd_module (shared)
 nss_module (shared)
 ssl_module (shared)
Syntax OK
```
ありました。

## エラー出しているのはどっち？
[この記事](https://qiita.com/tomluck/items/79cd978f4b56815d0dc8)を参考にmod_nssの方を調べたらビンゴ。

```
Certificate:
    Data:
        Subject: "CN=localhost4.localdomain4,O=example.com,C=US"
```
CNにlocalhost4.localdomain4の記載がありました。

## 念のためにmod_sslの方も確認
まず証明書ファイルの場所を確認。

```
# cat /etc/httpd/conf.d/ssl.conf | grep -e 'SSLCertificateFile'

SSLCertificateFile /etc/pki/tls/certs/localhost.crt
```
証明書の内容を確認

```
# openssl x509 -text -noout -in /etc/pki/tls/certs/localhost.crt

Certificate:
    Signature Algorithm: sha256WithRSAEncryption
        Subject: C=--, ST=SomeState, L=SomeCity, O=SomeOrganization, OU=SomeOrganizationalUnit, CN=localhost.localdomain/emailAddress=root@localhost.localdomain
```

こっちじゃないことを確認。

## 修正方法
mod_nssの方のエラーということがわかりました。
この修正の方法は検索すれば出てくるので割愛。
mod_nssの方のモジュールをアンインストールするなり、mod_nssの証明書のCNを書き換えて証明書ストアに保存するなりすればエラーが出なくなります。
linux > システム起動時 > /proc/kmsg started > Link:UbuntuとCentOSのメッセージ例 (シャットダウン | 起動時)

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.9を使用。
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
date (GNU coreutils) 8.4 
tmux 1.6-3.el6
```

数値計算に使用していたPCのtmuxセッションが切れていた。
その時刻あたりから数値計算の結果ファイルの更新も停止している。
sshで再ログインはできる。

再起動があったか気になり`/var/log/messages`を見ていると`/proc/kmsg started`というログが見つかった。

```/var/log/messages
Jan 29 18:42:53 XXXX kernel: imklog 5.8.10, log source = /proc/kmsg started
```

http://q.hatena.ne.jp/1193893387
> その後、起動時に
>
>`Oct 29 17:18:55 svname kernel: klogd 1.x.x, log source = /proc/kmsg started.`
>
`Oct 29 17:18:55 svname kernel: Linux version （以下略`
>
>という、起動した旨のメッセージがでます。

再起動したようだ。

以下には「シャットダウン時」と「起動時」のメッセージ例が紹介されている(Ubuntu + CentOS)。
http://s.webry.info/sp/vogel.at.webry.info/201611/article_4.html
echoでpprof, flame graph

## 概要

goの軽量web frameworkであるechoを使ってpprofをやる手順について

## 手順

### echoにpprofをbindしてくれるラッパーあるのでそれを使った  
https://github.com/sevenNt/echo-pprof

コードを編集(github　のサンプルより)

```go

package main

import (
	"github.com/labstack/echo"
	"github.com/sevenNt/echo-pprof"
)

func main() {
	e := echo.New()

	e.GET("/ping", func(c echo.Context) error {
		return c.String(200, "pong")
	})

	// automatically add routers for net/http/pprof
	// e.g. /debug/pprof, /debug/pprof/heap, etc.
	echopprof.Wrap(e)

	// echopprof also plays well with *echo.Group
	// prefix := "/debug/pprof"
	// group := e.Group(prefix)
	// echopprof.WrapGroup(prefix, group)

	e.Start(":8080")
}
```

起動してpprof画面を開く

```
http://127.0.0.1:8080/debug/pprof/
```

### profileは下記のコマンド叩いたあとに本体プログラムを動かす
あるいはベンチマークを起動する

```
go tool pprof -raw -seconds 30 http://localhost:8080/debug/pprof/profile
```

30秒間メトリクスを取った後、コンソールが立ち上がる

```bash
Fetching profile over HTTP from http://localhost:8080/debug/pprof/profile
Saved profile in /Users/aptpod-misu/pprof/pprof.samples.cpu.006.pb.gz
Type: cpu
Time: Jan 29, 2018 at 9:01pm (JST)
Duration: 30s, Total samples = 490ms ( 1.63%)
Entering interactive mode (type "help" for commands, "o" for options)
(pprof)
```

webコマンドでtrace graphが保存される
go
```
(pprof)　web
```

### frame graphをみる

uberの[go-torch](https://github.com/uber/go-torch)使う

```
$ go get github.com/uber/go-torch
$ cd $GOPATH/src/github.com/uber/go-torch
$ git clone https://github.com/brendangregg/FlameGraph.git
```

コマンド叩けばpprofを起動してくれるので何かしらプログラムを動かす

```
$ go-torch -u http://localhost:8080/ -f test.svg
INFO[00:44:21] Run pprof command: go tool pprof -raw -seconds 30 http://localhost:8080/debug/pprof/profile
```

あとは、保存された__svgファイル__を開くだけ

__なんか色々操作できたりするので便利__

![b529f2ec7e177fdc3f15ccd09c232b36.gif](https://qiita-image-store.s3.amazonaws.com/0/47896/8e84d26f-4596-a808-728c-4614292cfff8.gif)
AtomでNim

# やりたいこと
Nimで遊んでみようと思ったので、AtomでNimを書けるようにする。

# 結論
nimのパッケージをインストールするだけ
![スクリーンショット 2018-01-30 08.15.51.png](https://qiita-image-store.s3.amazonaws.com/0/114828/03bae894-9ad0-1824-bf65-bf53d2abea26.png)

# もう少し詳しく（経緯とか）
NimのGithub Wikiを見ると、Atomのサポートについて書かれていました。
https://github.com/nim-lang/Nim/wiki/editor-support

リンク先を見てみると、`Nimble`と`Nimsuggest`をインストールする必要があると書いてあります。
https://github.com/russpowers/nim-atom

ただし、それぞれのReadmeを読んでみると、「Nimインストールしたら一緒にインストールされるよ」とのことなので、`brew install nim`したら、Atomで`nim`のパッケージを探してインストールするだけ。
https://github.com/nim-lang/nimble
https://github.com/nim-lang/nimsuggest

# Hello Worldしてみた
`hello_world.nim`を任意の場所に作って

```nim
echo "Hello, world"
```

`-r`(実行)オプションを付けてコンパイルするだけ。

```
$ nim c -r hello_world.nim
Hint: used config file '/usr/local/Cellar/nim/0.17.2/nim/config/nim.cfg' [Conf]
Hint: system [Processing]
Hint: hello_world [Processing]
CC: hello_world
CC: stdlib_system
Hint:  [Link]
Hint: operation successful (10984 lines compiled; 0.863 sec total; 17.938MiB peakmem; Debug Build) [SuccessX]
Hint: /Users/username/work/study/hello-nim/hello_world  [Exec]

Hello, world
```

Atomの画面上ではこんな感じです。

![スクリーンショット 2018-01-30 08.18.40.png](https://qiita-image-store.s3.amazonaws.com/0/114828/b1bf2f4f-c29a-f65c-412e-6e75848508d9.png)

アイコンの色がいい感じで好きです。（ミルククラウン？ただの王冠？）
Androidアプリケーション技術者認定試験ベーシックの試験範囲の知識をまとめた(2)

# システムアーキテクチャ

## Androidアーキテクチャ

- アプリケーション
- アプリケーションフレームワーク
- ライブラリ
- Androidランタイム
- Linuxカーネル

### アプリケーション

いわゆる通常のアプリケーションのこと

### アプリケーションフレームワーク

API群のこと

- Activity Manager アプリケーションのライフサイクル／画面遷移の管理
- Content Provider アプリケーションでデータを共有するための機能（新しく作ることも可能）
- Location Manager GPSなどを利用した位置情報を管理する機能
- Notification Manager ユーザーへの通知を管理する機能
- Package Manager APKファイルのインストール管理をする機能
- Resource Manager アプリケーションで利用するリソースを管理する機能（言語の切り替えなど）
- Telephony Manager 電話機能（通話／着信／電波状態）
- View System UIの提供とその表示の管理
- Window Manager 画面の管理をする機能（Ｃ／Ｃ＋＋で作成）

### ライブラリ

C/C++言語で作成されている。フレームワークを通じてライブラリの機能を使用することとなる

- Free Type フォントエンジン
- libc BSDベースの標準Ｃライブラリ
- Media Framework 音声、動画、静止画の再生と記録をするためのメディアライブラリ機能
- OpenGL ES OpenGLの組み込み機向けライブラリ（OpenGL ES2.0はAndroid2.2(APIレベル8)からサポート
- SGL 2D描画のためのライブラリ
- SQLite 軽量なRDB
- SSL データ暗号化して通信するための機能
- Surface Manager 2Dと3Dのグラフィックレイヤーを合成して描画するための機能
- WebKit HTMLのレンダリングエンジン コア部のライセンスはLGPL

### Androidランタイム

ランタイムそのもの

- Core Library JavaSE5.0のコアライブラリからSwing等を除いて、Android独自の機能などを追加したもの
- Dalvik Virtual Machine レジスタベースの仮想マシン。複数のVMを同時に起動できる。Javaバイトコード(Classファイル)ではなく、Dalvikバイトコード(dexファイル)に変換してから実行する

### レジスタベースとスタックベース

レジスタベースとはCPU内部のレジスタといわれる領域にデータを読み込んで処理を実行する方式
スタックベースとはメインメモリ（主記憶装置）にデータを読み込んで処理を実行する方式
レジスタベースの方がCPUだけで処理できるので高速に実行できる場合がある。

### Linuxカーネル

OSの中核部分、当初は2.6ベースだったがAndroid 4.0では3.0ベースのカーネルを採用している

## ライセンス

**Android Open Source Project**ソースを公開しているプロジェクト
Androidのソフトウェアに適用されているのはほとんどがApache License 2.0
LinuxカーネルはGPLで、WebkitはLGPL

##　各ライセンスの要点

- Apache Licence 2.0

Apache財団によって規定されたライセンス。
自由に使用、複製可能
著作権、特許権、ライセンス表記によって、適用／派生ソフトウェアは自由に配布可能
その場合、派生ソフトウェアに異なるライセンスを適用可能
その場合、ソースコードの公開義務無し。

- GPL（GNU General Public License)

フリーソフトウェア財団(FSF)が公開、管理しているライセンス
GPL適用ソフトウェアの実行や実行結果もGPL対象外
複製と頒布は、著作権表示と無保証であること、ライセンスの条文（または条文の入手方法）を表記することで可能
GPLを適用したプログラムを一部分でも含む派生のプログラムにはGPLを適用する必要がある。
上記の為、ソースコードの公開義務が発生する。（コピーレフト）
AndroidではLinuxカーネルで使われている。

- LGPL(GNU Lesser General Public License)

FSFが公開、管理しているライセンス
LGPLのライブラリにリンクしたプログラムはLGPLを適用する必要はない。
ソースコードの公開義務もない。
ただし、デバッグのためのリバースエンジニアリングを禁止することはできない。
ライブラリの著作権表示とライブラリの仕様を表記し、GPLとLGPLのライセンスについて表記する必要あり。
LGPLのライブラリを改変した場合、LGPLかGPLのどちらかをてきようする必要があり、ソースコードを公開する義務が発生する。
AndroidではWebkitのコア部分で使われている