OmniAICreator/Qiita-1.07M huggingface dataset:
画面作成①『画面項目定義』

![wfc20161109057.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/81901607-d7c4-a2ac-c906-591e119786c2.jpeg)

SaaSForceの場合、テーブル項目定義の作業が終わったら画面の作成に入ります。

ここでは2ステップあります。

一つは「画面項目定義」、もう一つは「画面レイアウト作成」です。

今回は画面作成①として、「画面項目定義」の作業をご紹介します。

まずは左側のボタンの中から画面作成を押し、その下に出てくる「画面項目定義」を選びます。

![wfc20161109058.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/3b9f14fa-6f6b-ff09-c0db-4a147a72f7f8.jpeg)

このような画面に切り替わりますが、初めての方は前回の記事「テーブル項目定義.作成」で作ったテーブルだけが表示されます。

![wfc20161109059.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/fc8d475d-4013-3ed9-b99f-fd946e100c11.jpeg)

「検索条件」をクリックすると、このような画面がスライドしてくるので、「新規」を押します。

![wfc20161109060.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/a8ab41c4-c6d8-dd15-e2eb-a96931197fa5.jpeg)

「画面項目定義新規」の画面が開かれるので、まずは「画面名」と「管理ID」を入力しておきます。

私は、編集情報にあるテーブルIDをそのままコピペしてつかっています。

![wfc20161109061.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/d651b053-3ccf-f47e-136f-7774ca10bc22.jpeg)

左にあるテーブル項目定義で作ったテーブルの「選択」にチェックを入れると、右側に画面項目が自動生成されます。

![wfc20161109062.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/f1d3c4cc-2f8c-512e-ca1e-5a74842a103c.jpeg)

右側にできた画面項目の一番上の「選択」にチェックを入れると、項目全てのチェックが埋まります。

グリッドなどの設定をしない限りは、この画面での作業はこれで終わりなので、「保存して次へ」を押します。

![wfc20161109063.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/14083c01-975b-2fb4-1f98-fee129f6e8aa.jpeg)

そうすると、このような表示がされて、今作った画面項目がフォルダに保存されます。

![wfc20161109064.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/96e44973-4545-bda3-f41d-59735b822b43.jpeg)

「OK」を押すと、このようなポップアップ画面が出てきて、このSaaSForceの開発環境とは別のテストサーバーにあるフォルダに登録する作業に入ります。

ただし、「フォルダID」や「フォルダ名」は無視してもかまわないようで、下のフォルダ名のところにあるチェックボックスを埋めて、緑色の「登録」ボタンを押すだけです。

登録完了に「OK」をすると、次の画面に変わります。

![wfc20161109065.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/84739c33-3afe-c437-298c-d4c7bd214b53.jpeg)

この画面では、いろいろな作業もできなくはないのですが、例えばパーツの枠のサイズなどを決めることができますし、表示する文字の揃えなども変えることができますが、私は何もせずに「保存」します。

![wfc20161109066.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/b4858884-2ada-6e7d-f37f-091eb17b4664.jpeg)

するとこのようなポップアップ画面が現れるのですが、「スキップ」を押すだけで言いようです。

最後に、更新が完了したというポップアップがありますので、「OK」を押して、この『画面項目定義』の作業は終了です。
Ansibleでディレクトリがあるか判別して作成する処理

# 概要

Ansibleでディレクトリがないか判別して、もしなければ作成する処理を書いてみました。

# メモ

~~resultで返り値を返してあげて、その値を元にwhenで判別してます。~~
~~resultの値はstdoutで文字列として読み取ってます。~~

~~もっとかっこいい方法あるかもですが。~~

state: directoryでディレクトリがなければ作成になります。

# ソースコード

```
- name: make dir
  file:
    path: /tmp/test
    state: directory
    owner: root
    group: root
    mode: 0700
  when: result.stdout == "1"
```

https://github.com/handa3/study/blob/master/ansible/playbook/roles/test/tasks/make_dir.yml
Kubernetes Pythonクライアントの使い方

## job + secret

secret作成

```python
secret_name = "kubedt-pytest"
secret = V1Secret(metadata=V1ObjectMeta(
    name=secret_name
), data={
    "accesskey": access_key.encode('base64'),
    "secretkey": secret_key.encode('base64'),
})
resp = v1.create_namespaced_secret(namespace=namespace, body=secret)
print(resp)
```

```
memory_size = '64Mi'
memory_usage = {"memory": memory_size}
```

```
access_key_env_src = V1EnvVarSource(
    secret_key_ref=V1SecretKeySelector(
        name=secret_name,
        key="accesskey"
    )
)
access_key_env = V1EnvVar(
    name="ACCESS_KEY",
    value_from=access_key_env_src
)

secret_key_env_src = V1EnvVarSource(
    secret_key_ref=V1SecretKeySelector(
        name=secret_name,
        key="secretkey"
    )
)
secret_key_env = V1EnvVar(
    name="SECRET_KEY",
    value_from=secret_key_env_src
)
```

```
args = [
    "--bucket", bucket,
    "--object-key", object_key,
    "--parallelism", str(parallelism),
    "--s3-endpoint", s3_endpoint,
    "--namespace", namespace,
]

pod_template_spec = V1PodTemplateSpec(
    metadata=V1ObjectMeta(name="kubedt-pytest-master", labels={"app": "kubedt-pytest-master"}),
    spec=V1PodSpec(restart_policy="Never", containers=[
        V1Container(args=args,
                    image="mumoshu/kubedt-pytest-master", image_pull_policy='IfNotPresent',
                    name="kubedt-pytest-master", env=[access_key_env,
                                                      secret_key_env],
                    # it fails like "oci runtime error: write /proc/26452/oom_score_adj: invalid argument" without resource req
                    resources=V1ResourceRequirements(limits=memory_usage, requests=memory_usage), )]))

job = V1Job(
    api_version="batch/v1", kind='Job',
    metadata=V1ObjectMeta(
        name='kubedt-pytest-master',
    ),
    spec=V1JobSpec(
        active_deadline_seconds=30,
        completions=1,
        parallelism=1,
        template=pod_template_spec
    )
)

resp = batchv1.create_namespaced_job(
    namespace=namespace,
    body=job
)

print("Job created. status='%s'" % str(resp.status))
print(resp)
```

jobによって作られたpodには、controller-uidというラベルが付与される。
jobのmetadata.uidがpodのcontroller-uidラベルに対応するので、job.metadata.idをとっておけば後でそのjob管理下のpodを検索するために利用できる。

```
job_uid = resp.metadata.uid
```
webpackを利用した開発環境にLAN経由でアクセスすると何も表示されない問題を解消する

webpackを利用した環境では`webpack-dev-server`と`rails server`を走らせる形になりますが、例えばモバイルの実機からデザインなどを確認したい場合 `http://192.168.0.13:3000` みたいな感じで、LAN内部で他の端末から開発環境にアクセスしたいケースがあるかと思います。

その場合、webpackの読み込みがされず、白紙のページが表示されてしまいます。
この問題は`webpack-dev-server`の起動時に、開発環境のipアドレスを指定することで解消します。

```shell-session
$ bin/webpack-dev-server --host 192.168.0.13
```

そもそもrailsに繋がらない場合は

```shell-session
$ bin/rails server -b 0.0.0.0
```

とすれば大丈夫です。
GithubとBitbucketで使うSSHキーを別々に作ってみる

#### 手順

##### <i class="fa fa-key" aria-hidden="true"></i> SSHキー作成
※ `mail@address.com`の部分は自分が登録したメールアドレスでお願いします。

ターミナルで以下の各Github用、Bitbucket用のコマンドを実行するしてSSHキーを作成する

```zsh
ssh-keygen -t rsa -C mail@address.com -f ~/.ssh/id_rsa_github
```

```zsh
ssh-keygen -t rsa -C mail@address.com -f ~/.ssh/id_rsa_bitbucket
```

各コマンドを実行すると、

```
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
```
と聞かれるのでパスフレーズを設定。
（設定しないでエンターキーだけ押してもできます）

lsコマンドでちゃんと作成されているか確認

```
$ ls ~/.ssh
config               id_rsa_bitbucket.pub    id_rsa_github.pub
id_rsa_bitbucket     id_rsa_github        
```

##### <i class="fa fa-pencil-square-o" aria-hidden="true"></i> .ssh/configの設定を追加

以下を追加する

```:.ssh/config
  Host github.com
    User git
    HostName github.com
    IdentityFile ~/.ssh/id_rsa_github
    IdentitiesOnly yes

  Host bitbucket.org
    User git
    HostName bitbucket.org
    IdentityFile ~/.ssh/id_rsa_bitbucket
    IdentitiesOnly yes
```

##### <i class="fa fa-github" aria-hidden="true"></i> SSHキーを登録 

各SSHキーの公開鍵を以下のコマンドでコピーして各Github、Bitbucketに登録

```
cat ~/.ssh/id_rsa_github.pub | pbcopy
```
```
cat ~/.ssh/id_rsa_bitbucket.pub | pbcopy
```


#### special thanks <i class="fa fa-heart" aria-hidden="true"></i>
以下を参考にさせていただきました。
http://www.task-notes.com/entry/20150210/1423537200
http://umi-uyura.hatenablog.com/entry/2016/05/17/233545
Linuxコマンド[ps]

　下記のようなエラーが出た場合。
別で正しくrails serverのshutdownが行われずプロセスが残っているために起こる。
```
[vagrant@vagrant-centos65 railbook]$ rails s
=> Booting WEBrick
=> Rails 4.0.2 application starting in development on http://0.0.0.0:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
A server is already running. Check /home/vagrant/rails/railbook/tmp/pids/server.                                                                                        pid.
Exiting
```
### Linuxコマンドにて
#### ps
---
* 実行中のプロセスを表示する。 

#### ps aux
---
*  a = 自分以外のユーザーのプロセスも表示
*  u = ユーザー名と開始時刻を表示
* x = 制御端末のないプロセス情報も表示

#### ps aux | grep rails
---
* grepより自身以外のプロセスの表示にする。
   よって上記のコードよりrailsの別のプロセスのみを表示できるため、shutdownがきちんと行われていないプロセスを見つけることができる。

``` 
[vagrant@vagrant-centos65 railbook]$ ps aux | grep rails
agrant   1332  0.8  7.0 494220 72072 ?        Sl   01:22   0:02 /usr/local/bin/ ruby bin/rails server -d -b 0.0.0.0
vagrant   1373  0.0  0.0   8388   856 pts/0    S+   01:27   0:00 grep rails
``` 

今回は1332が残っているプロセス、1373は今実行しようとしているプロセス。
```
[vagrant@vagrant-centos65 railbook]$ kill 1332
```
よって上記コマンドより1332をキルする。
```
[vagrant@vagrant-centos65 railbook]$ ps aux | grep rails
vagrant   1375  0.0  0.0   8388   856 pts/0    S+   01:27   0:00 grep rails
```
無事消えました。
これによりrails sから通常通りサーバーを起動可能となる。

>※追加
>　teratermを再起動しても解決可能。
Gitってなんじゃらほいだった私が読んだ読み物メモ

#VCSについて読んだよ
Gitについて読む前にバージョン管理システム(VCS)ってなんじゃってことで

https://github.com/masaru-b-cl/introduction-to-vcs
読んだのはこちら、概念的お話なので業務経験なくても何となくわかるはず

#Gitについて読んだよ
https://github.com/takanabe/introduction-to-git
読んだのはこちら、練習用のリポジトリもついてて丁寧簡単色褪せない

以上、Qiitaに書くのは初めてだけどこんなんでいいのかな？かな？
C++ における const をつける位置の違い

[ブログ記事](http://secret-garden.hatenablog.com/entry/2015/12/24/230224)からの転載です。

<del>この記事は[初心者 C++er Advent Calendar 2015](http://www.adventar.org/calendars/922)の6日目の記事になります。  
今日はクリスマス・イブ！！ってことで、せっかくなので穴が空いていた6日目の記事を書きました。   </del>  
と、書いたんですが、[すでにいなむさんがに先をこされて](http://qiita.com/_EnumHack/items/430da105a541f9ecd774)いました・・・。  
まぁでもせっかくなので公開することに。  
<del>それはそれとしてカップルとか永遠と爆発してほしい</del>  

## const とは

`const` は C++ を学び始めると最初の方に出てくるキーワードだと思います。  
`const` 自体はそんなに難しくなく、`const` をつけることで、定義した変数を不変（後から別の値を代入することができない）にするだけです。

```cpp
int value = 0;          // const を付けないで定義した変数は
value = 42;             // 後から変数の値を変更できる

const int value2;      // const を付けて定義した変数は
value2 = 42;           // Error: 後から変数の値を変更することができない
```

主に『定数』など、後から値を変更しない（されない）ような変数を定義したいときに使用します。  
また、`const` をつける位置は『型の前』でも『型の後』でも動作は変わりません。

```cpp
const int value;	// int const value でも動作は同じ
```

## 参照型やポインタ型を絡めて const を定義する場合

`const` 自体の意味はそこまで難しくないのですが、参照型やポインタ型を含めて定義したい場合には `const` をつける位置に注意する必要があります。  
これは、ポインタと `const`を組み合わせる場合に

* `*` の前に `const` を付けた場合はポインタを指してる先が不変になる
* `*` の後に `const` を付けた場合はポインタ変数そのものが不変になる

と、いう違いがあるためです。

```cpp
int value = 42;

// ポインタが指してる実体を変更することができない
const int* p = &value;
p = &value;                   // OK
*p = 10;                      // NG


// ポインタ変数そのものを変更することができない
int* const p2 = &value;
p2 = &value;                  // NG
*p2 = 10;                     // OK
```

簡単にまとめると

* const int* → ポインタが指してる実体を書き換えることができない
* int cosnt* → cosnt int* と同じ
* int* const → 定義したポインタ変数を書き換える事ができない

というような違いになります。  
ちなみに `cosnt int* const` という風に両方に `const` を付けた場合は『変数』も『実体』も不変になります。

```cpp
int value = 42;

// ポインタが指してる実体もポインタ変数自体もを変更することができない
const int* const p = &value;
p = &value;                      // NG
*p = 10;                         // NG
```

これは参照型でも同じになります。  
このようにポインタ型や参照型で `const` をつける場合には『何を不変にしたいのか』を意識して `const` をつける必要があります。
テーブル項目定義.作成の手順

![wfc20161109042.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/230801d0-957c-31c9-e699-4adbaf322412.jpeg)

以前、SaaSForceの一連の作業はご紹介したのですが、長いので「テーブル項目定義.作成」の手順だけ別にここでご紹介したいと思います。

個人的には、「テーブル項目定義.作成」のピリオドと「ビュー定義･作成」のナカテンの微妙な違いが一番気になるのですが。

![wfc20161109043.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/9b0bef1b-7849-26af-7e8b-cce45a761b52.jpeg)

さて、SaaSForceのバージョン6（2017年6月現在)は、ログインをするとこのような画面です。

![wfc20161109044.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/b716c826-6635-3d52-286f-a1fce9eb82f8.jpeg)

左側にある「テーブル」と言うボタンを押すと、ドロップダウンリストが出てきます。

そのなかで「テーブル項目定義.作成」を選択します。

![wfc20161109045.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/a2058865-4c67-38b8-1d85-c147200243e8.jpeg)

既にいくつかテーブルを作っているのでこのようになっていますが、初めての場合はこのページはほとんど空白です。

![wfc20161109046.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/4e6b7309-1f85-55b2-6c6f-35d6e35f2794.jpeg)

「検索条件」を押すと、スライドしてこのような画面に変わります。

![wfc20161109047.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/1aca78be-e817-31f3-f744-ee0c2cdfd8a4.jpeg)

ここで緑色の「新規」のボタンを押します。

![wfc20161109048.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/b3015d26-aa50-08a4-3a04-d5a9a9856a27.jpeg)

画面が切り替わり、「テーブル項目定義」のページになります。

ここで、先に「テーブルID」と「テーブル名称」を先に名称して、「マスタ情報」と「データーベース反映」にチェックを入れます。

なお、「テーブルID」は英文字がいいようです。

数字の場合は次のようなエラーメッセージが出てきます。

![wfc20161109049.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/8abda960-5d41-a62c-fc81-caf1f541af08.jpeg)

「テーブル名称」は日本語などで大丈夫ですが、個人的にはIDと同じ物を使っています。

![wfc20161109050.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/982b4015-430e-4a43-79e2-61230e02ea5f.jpeg)

この、「項目追加」と言うボタンを押すと、次の画面がポップアップされます。

![wfc20161109052.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/daaf07f3-8e9f-c05c-6616-90e7b7fd664e.jpeg)

これがアプリケーションのパーツ、つまり項目を作る機能です。

![wfc20161109053.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/cfde5cb5-16b1-6a7c-7698-1de619f0f501.jpeg)

「デフォルト表示形式」のドロップダウンリストでさまざまなパーツを選択することができます。

![wfc20161109054.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/8033cf9b-7e0f-f8b5-bc08-3de82b3f8bb3.jpeg)

「データー型」で、入力のスタイルを選択できます。

なお、理由はよくわからないのですが「長さ」の項目は日付や整数以外は入力しないと「このフィールドは必須です」と言うメッセージが出ます。

![wfc20161109055.JPG](https://qiita-image-store.s3.amazonaws.com/0/184885/9ac9f476-69ae-bf54-2a52-74f9472574cc.jpeg)

今回は、紹介と言うことなので、全てので「フォルト表示形式」でパーツを作ってみました。

いくつかは、私もまだ使ったことがないものなので、どのような結果になるか分かりません。

最終的に、みどりの「保存」ボタンを押せば、テーブル項目定義.作成の作業は終了です。
Swift3 UserDefaults 覚え書き

# 追記 2017/10/28

これのが簡単でいい

```
        //定義
        let defaults:UserDefaults = UserDefaults.standard

        /保存
        defaults.set("Totally True", forKey: "HasAppBeenOpenedBefore")
        
        //出力
        for (key, value) in UserDefaults.standard.dictionaryRepresentation() {
            print("\(key) = \(value) \n")
        }
```

# 説明


`UserDefaults`は気軽にデータを永続化することができる便利な機能です。データベースを使うほどでもない永続化したいデータなどに活用されます。割と安易に実装が出来るのでお手軽で便利です。設定画面の実装などに使えますね。備忘録として、使い方をサラッと書き残しておくことにします。



# step1 structを定義する

`struct`に定義された定数に永続化される対象のデータが入ります。`struct`の中に、データが保存されていると思っていいです。謂わば最初に定義された`struct`の中の変数はデータを保存する箱です。

```swift
struct Constants {
    static let TupacAmaruShakur = "Tupac "
    static let NotoriousBig = "Biggie"
}
```

# step2 変数を定義する

永続化したいデータの実態を保存する変数を定義しましょう。のちに出てくる`set`メソッドでこの変数を使います。この変数を`struct`に保存する感じです。

```swift 
var Tupac  = "californialove"
var Biggie  = "BigPoppa"
```

# step3 セットする
準備ができたので値を永続化させてみましょう。先ほど定義した変数にStringの値を代入して、その変数をstructにセットしています。セットした時点でストラクとは永続化されています。

```swift
UserDefaults.standard.set(Tupac, forKey: Constants.TupacAmaruShakur)
UserDefaults.standard.set(Biggie, forKey: Constants.NotoriousBig)
```

# step4 出力する

セットした値を取り出したければ下記のように書きます。`print()`などでそのまま下記のコードをデバックしてみれば、保存したデータが出力されるはずです。

```swift

UserDefaults.standard.string(forKey: Constants.TupacAmaruShakur)
UserDefaults.standard.string(forKey: Constants.NotoriousBig)

```

#  Swift3 UserDefaults 覚え書き 其の二


```swift

// Create UserDefaults
let defaults = UserDefaults.standard

// Save String value to UserDefaults
// Using defaults.set(value: Any?, forKey: String)
defaults.set("Some string you want to save", forKey: "savedString")

// Get the String from UserDefaults
if let myString = defaults.string(forKey: "savedString") {
    print("defaults savedString: \(myString)")
}

```
ソシャゲ開発経験から学んだゲームに Redis を使う際の Tips

近年の KVS では割と Redis が覇権を取っていることもあり(当社比), 
社内の多くのプロジェクトで Redis を使用するようになりました. 
ということでノウハウ的なのも溜まってきたのでまとめたいと思います.

(大量のユーザーデータを扱うソシャゲにしか当てはまらない部分もあるかと思います)

## 単純にパフォーマンスを RDB < Redis と思い込んでとりあえずでキャッシュしない
「Redis は速い」と言われますが, インデックスをちゃんと貼った RDB のクエリも
そこまで遅いわけではありません. 結局通信コストの方が遥かに大きいので内部の
取得時間差はトータルで考えると多くの場合誤差です.
特に RDB の主キーのみで取得できるようなデータを Redis にキャッシュすることに
メリットはありません. キャッシュするコードを書くコストの方が高くつきます.
キャッシュするのは RDB の複数テーブルを参照しなければならないような時間のかかる
かつアクセス頻度が高いクエリに対してしましょう. 

## 基本的に Expire はつける
Redis はデータを永続化できることも特徴ですが, 逆に言えば消えないためディスク容量は
どんどん圧迫していきます. 永続性が必要ないものについては Expire を付けることにより
ディスクが食いつぶされるのを幾分か防ぐことができます. 特にキャッシュの場合は必須.

## そもそも容量を圧迫しないように設計する
Expire はあくまで有効期限なので短期間に大量アクセスが来ればデータ設計によっては
やはり容量不足になることもあります. なのでそうそうデータが爆発しないように設計しておきましょう. 
ユーザーが何かアクションする度にレコード増えるような設計は NG です.
(ユーザーがクエストに行く度に1レコード増えるとか)

基本的にユーザーと機能に対してデータ量が 1:1 になるようにしておけば, データ量が一気に
増加しにくいしデータ量の把握もしやすいです.
(少し前のゲームによく見られた, 「1日1回フレンドにあいさつする」, という機能で
1あいさつ1レコード作っていたのでKVSの容量がヤバいことになった, という事例があったそうな)

# 永続データ
## Redis と RDB のデータを同時一括更新しないようにする
Redis のデータと RDB のデータの同時更新でエラーが起きた場合, RDB のデータは
トランザクションに守られていますが, Redis のデータは手動ロールバックが必要になります.
実装的にもメンテナンス性にしてもよろしくないので最大限避けるべきです.

そもそもエラー時にロールバックしなければならないようなデータを Redis に入れるのを
避けるべきかもしれません. エラーが出たらそのデータは一旦削除, くらいの気軽さがあった方がいろいろ楽.

## Redis にユーザーの永続データを入れるのを避ける
前項目に若干関係しますが, ユーザーの永続データは入れない方がいいです. ユーザー数は
広告効果等である日大量に増加したりするので思わぬところで負債が産まれたりします. 

(RDB の負荷分散はバッチリだったけど Redis の負荷分散は考えてなかった！ とか. 
負荷分散するにはデータを一旦消さなきゃ！でもユーザーデータだから消せないorz！とか)
 
そもそも RDB があるのにわざわざ Redis を永続データの保存先に使う必要は基本的にないはずです. 
(でもちょっとしたパラメータが気づいたらなぜか Redis のみに保存されるようになってたりする. ~~git blame しなきゃ~~)

ユーザーデータでない永続データは設定系ですかね...(例が出ない)
ユーザーデータ以外なら開発側である程度データ量の制御ができるので便利に使えるなら使ってもよいかと. 

# ゲームにおける Redis の使い所
#### キャッシュ
KVS なのでキャッシュが一番に思いつきますが, 前述の通りキャッシュ対象は吟味しましょう. 
もちろん Expire 必須！
あと負荷が高い時はスケールアウトできるようにしておくといいです. Redis はスケールアップより
スケールアウトの方が効果が高い気がします. 
(シングルスレッドだからかコア数とか増やしてもそこまでパフォーマンス上がらなかった経験)
各言語の Redis ライブラリも割とシャーディング対応してます. 大体がキーのハッシュ値から
各シャードに振り分ける実装になっているためキャッシュサーバーの増減もしやすいです.


#### ランキング
ソート済みセットを使ったランキング実装は Redis の有効な使い方です. 
各ユーザーのポイントは DB に保存してあるはずなので何かあったら
ランキングは集計し直せばいいだけという点も good !
~~同点問題？管轄外です~~

#### レイド(みんなでボスを殴るやつ)
複数ユーザーで一体のボスを倒すようなのはボスの体力減少のレースコンディションがやっかいですが, 
Redis の incrby, decrby はアトミックなためみんなで一斉に殴っても大丈夫. やったぜ.

# 最後に
以上になります. Redis は便利ですがデータの保存先としては RDB に寄せた方が運用しやすいです.
Redis の中身は吹っ飛んでも最悪作り直せば OK という設計にしておくと精神的に楽です.
(別にRedis のデータが吹っ飛びやすいとか言ってるのではなく, 死守しなきゃならないものが多いと大変ということです)
mac で sudo時に非常に時間がかかるんだよね

結局設定はきちんと内容を把握した上で行わないと痛い目を見るという私の経験に基づく事例を一件紹介させていただくというものです。

# そもそも
　何をしたかったかというと、会社では、在宅でも外出先でも仕事ができる環境を提示していただいておりまして、その一つにVPNアクセスがあります。会社側では、Windows環境を想定したコマンド・アプリ・設定情報の提供はするものの、macについては使いたければ使っても良いが、自己責任でというものです。
openvpnを利用するのですが、やはり実行時にはsudoが欠かせません。それも面倒なので、当該コマンドのみsudoパスワードなしで楽をしたいというヨコシマな考えが発端となりました。

# sudoers
上記、特定コマンドのみsudoのパスワードを入力せずに実行するには、sudoersファイルの設定が必要となります。
$ sudo visudo
 上記により編集するわけですが、その設定ファイルのフォーマットが以下となります。
who where = (as_whom) what
* man sudoers
whoの部分に%を先頭につけて、グループ名を指定すると、グループが対象になり、そのグループに所属しているユーザ全てに許可することとなります。
元のsudoersには、以下の行が有効になっています。

```sudoers
root    ALL=(ALL) ALL
%admin  ALL=(ALL) ALL
```

以下の行はコメントになっているのでデフォルトでは無効ですが、コメントを外す（先頭＃を取り除く）と、wheelグループに属しているユーザーは誰にでもsudoを許可するということになります。

```sudoers
# Uncomment to allow people in group wheel to run all commands
# %wheel   ALL=(ALL) ALL
```

以下のコメントを外すことで、wheelグループに属しているユーザーはパスワードなしにsudoコマンドを実行可能となります。

```sudoers
# Same thing without a password
# %wheel   ALL=(ALL) NOPASSWD: ALL
```

サンプルとして提示されている以下の行は、usersグループに属しているユーザーは指定したコマンドについて、sudoを許可するということになりますが、ここにワナが仕込まれていました（ワタシだけ）

```sudoers
# Samples
# %users  ALL=/sbin/mount /cdrom,/sbin/umount /cdrom
# %users  localhost=/sbin/shutdown -h now
```

# ワナ
何も考えずにサンプルを鵜呑みにして私は以下のような設定をしてしまいました。

```sudoers
%users   ALL=NOPASSWD: /Users/user/.vpn/my_vpn.sh
```

上記の記載について、フォーマットは間違っていないので、visudoコマンドでも問題なく編集できます。しかし、想定した動作となっていませんでした。（上記コマンドであっても必ずパスワードが問われる）
うまく動作していないにも関わらず、設定をそのまま放置してしまったため、さらにひどい状況になってしまいました。
sudoを行おうとすると、上記で指定したコマンドに関係なく、全ての場合に、パスワードの問い合わせが行われるまでに2分程度の時間がかかり、やっとsudo以下で指定したコマンドが実行できるようになるという状況でした。

何度かsudoの仕組み上何かネットにアクセスしてタイムアウトの結果なのかと思い調べてみたりしたのですが、何もわからず、いく日が過ぎ、やっと原因がわかりました。

## 時間がかかった原因とは
**macにはusersというグループはデフォルトでは存在していない**のです。
存在するグループ（やユーザー）を指定することで問題なく動作しました。

## 余談
ちなみに、サンプルには、whereに該当する部分にlocalhostが指定されておりますが、これもマニュアルによるとマッチしないため、指定してはいけないようです。指定してもフォーマット的に動作はしますが、想定通り動きません。
残念ながら、dhcpなどの環境の場合、どのように自機だけに制限したら良いのかわかりませんでした。（2017/6/14現在）

## さらに余談

以下のようにすることで、設定ファイルを局所化することが可能です。例えば、所定のホスト向けの設定だけとか、所定のユーザー・グループ向けの設定だけとかに分割することで、設定ファイルの見通しをよくすることができます。（先頭の#はコメントを示すものではありません）

```sudoers
#includedir /private/etc/sudoers.d
```

編集する場合、visudoでは、最初に/etc/sudoersが開かれるので、:e により所定のファイルを開き、編集して保存するときちんとフォーマットチェックしてくれます

# 最後に
念のため、私のmac環境について記述いたしますが、今回の件は、usersがグループに存在しないOSについて該当するかと思います。sudoersの記述については、現時点のもので、実際に設定する場合には、manなどでご自身で確認してみることをお勧めいたします。
https://linuxjm.osdn.jp/html/sudo/man5/sudoers.5.html

- my環境
 - mac OS Sierra ver 10.12.5
 - MacBook (Retina, 12-inch, Early 2015)
 - Processor 1.2GHz Intel Core M
 - Memory 8GB 1600 MHz DDR3


イジョ
Androidでの正しいログ出力方法（標準Logクラス vs AnkoLogger）

## 背景

Java->Kotlin移行にあたり、JetBrainsがOSSとして開発している[AnkoLogger](https://github.com/Kotlin/anko/wiki/Anko-Commons-%E2%80%93-Logging)を導入してみましたが、verboseやdebugログ出力してもAndroidStudioのlogcatに出力されませんでした。
原因を調べていると、AnkoLoggerの問題というよりは、標準Logクラス`android.util.Log`の挙動をそもそも勘違いしていたことに気づきました。。

## ログレベルと各ライブラリの挙動

今までの自分の認識だと、`Log.d(TAG, "foo")`と書くと、ログレベルがdebug以下（つまりdebug,　verbose）の場合にログ出力されて、いつも開発環境でverbose/debugログを見ているのはログレベルがverboseになっているからなのかな、と何となく思っていました。
結論から言うと、↑の認識は間違いで、デフォルトのログレベルはinfoでした。
ではなぜverbose/debugログが出力されているかというと、**`Log.d(TAG, "foo")`と書いても実はログレベルに関わらずログ出力される仕様のようです**。
ログレベルの判定は別メソッドで行う必要があり、出し分けるには以下のようにif文で制御する必要があります。（ちなみにログレベルはタグ毎に設定されています）

```
if ( Log.isLoggable(TAG, DEBUG) ) Log.d(TAG, "foo");
```

何でこんな冗長な仕様になっているんだろう。。

一方のAnkoLoggerですが、

```
debug("foo") // タグはデフォルトで呼び出し元のActivity名
```

と書くと、[内部でログレベルを判定](https://github.com/Kotlin/anko/blob/master/anko/library/static/commons/src/Logging.kt#L259)してくれるので、利用する側はif文を書かなくてもログレベルに従って出力されます。個人的には断然こちらの方が直感的です。
[GithubのIssueにも同じ疑問があがっていた](https://github.com/Kotlin/anko/issues/104)ので、標準Logクラスの仕様を勘違いしていたのは自分だけではないはず。

## まとめ

改めて整理すると、

* 標準のLogクラス
  - `Log.isLoggable`で明示的に制御しないと、本番（ログレベル:info)でも全てのログを出力するので、パフォーマンス低下につながる
  - `Log.isLoggable`で明示的に制御しないと、何もしなくてもlogcatでログを確認できるのである意味開発時は楽
  - 正しい使い方は[こちら](https://mobiarch.wordpress.com/2012/05/11/proper-logging-from-android-application/)
  - 他にもProGuardでreleaseビルドだけログを出さないようにする方法もあるようです
* AnkoLogger
  - 本番（ログレベル:info)ではinfo以上のログしか出力されないので、無駄なパフォーマンス低下がない
  - 開発時にadb等でログレベルを変更しないとlogcatでログが見れないのでちょっと面倒。ex.`$ adb shell setprop log.tag.MainActivity VERBOSE`
    
コードのわかりやすさとセキュリティを考えると、個人的にはAnkoLoggerを使っておこうと思います。
Javaを使っている場合や無駄な依存ライブラリを入れたくない場合は、AnkoLoggerライクな標準Logのラッパークラスを作るのもアリかと思います。
【Swift】Firebase Cloud MessagingでクライアントからHTTP POSTで特定のユーザーにプッシュ通知を送るコード

プッシュ通知を利用するための設定等は割愛します。

```.swift
// コンソールから確認できます
let serverKey: String = "xxxxxxxxx"
// プッシュ通知を送るユーザーのトークン
let token: String = "xxxxxxxxx"

let post: [String: Any] = ["to": token,
                           "priority": "high", // highにするとアプリが非起動時・バックグラウンドでも通知が来る
                           "notification": [
                              "badge": 1,
                              "body": "お笑いコンビ「インパルス」の堤下敦さんが１４日午前２時半ごろ、東京・狛江市で睡眠薬を飲んだあとに車を運転していたことが警視庁への取材でわかりました。",
                              "title": "インパルス堤下さん謝罪「湿疹で眠れず睡眠薬」"]
                           ]

var request = URLRequest(url: URL(string: "https://fcm.googleapis.com/fcm/send")!)
request.httpMethod = "POST"
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.setValue("key=\(serverKey)", forHTTPHeaderField: "Authorization")

do {
   request.httpBody = try JSONSerialization.data(withJSONObject: post, options: JSONSerialization.WritingOptions())
   print("Succeeded serialization.: \(post)")
} catch {
   print("Failed serialization.: \(error)")
}

let task = URLSession.shared.dataTask(with: request) { data, response, error in
   
   if let realResponse = response as? HTTPURLResponse {
       if realResponse.statusCode == 200 {
           print("Succeeded post!")
       } else {
           print("Failed post: \(realResponse.statusCode)")
       }
   }
   
   if let postString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue) as String? {
       print("POST: \(postString)")
   }
}

task.resume()


```
AWS CLIで今俺どのアクセスキー使ってるんだ？を調べる方法

aws cliを利用している際に複数のAWSアカウントやアクセスキーを使っていると、どのアクセスキーを使っているのかわからなくなることがある。

そんな時にこれを打ちましょう。

```:bash
aws configure list --profile test
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                     test           manual    --profile
access_key     ****************xxxx shared-credentials-file
secret_key     ****************xxxx shared-credentials-file
    region                us-east-1      config-file    ~/.aws/config
```

幸せになれました。
TypeScriptでこれは設定しとけっていうコンパイラーオプション

最近ギョームで使用したので転記

# 何がしたいか
* 型チェックによる安全性を最大化したい
* 不要なコードも怒ってくれるとうれしいなー

# 対象
TypeScript2系
(1系もいくつか使えるオプションもあると思うが未検証…というか2系にあげましょう！)

# 追加したオプション
* 型チェックによる安全性を最大化したい
  * `strictNullChecks`
  * `noImplicitAny`
  * `noImplicitThis`
  * `noImplicitReturns`
* 不要なコードも怒ってくれるとうれしいなー
  * `noUnusedLocals`
  * `noUnusedParameters`

## 「型チェックによる安全性を最大化したい」系
### `strictNullChecks`オプション
nullやundefinedが「一人前の型」になります。
指定前はnullやundefinedで以下のようなことができましたが、このオプション指定によりエラーとなります。

```ts
const num: number = null; // Type 'null' is not assignable to type 'number'.
```
nullやundefinedで初期化が必要な場合は、型を明示しましょう。ただし、考えなしにnullable/undefinedableな変数を量産するのもあまりオススメできません。
nullable/undefinedableな変数を扱う場合、常に型のハンドリングが必要になります。

```ts
const num: number | undefined = undefined;
if (typeof num !== 'number') {
  return "Error Happens";
}
num.toString();  // チェックロジックをコンパイラが評価し、numは正しくnumber型と判断される
```

要件によると思いますが、型が同じ初期化値でコードをすっきりさせて行きたいところです。

```ts
const num = 0; // 右辺のリテラルを型推論してくれて、型宣言もいらない
```

#### nullable/undefinedableな変数のキャスト
`!`を使うことで、nullable/undefinedableな型を、値がある風にキャストできます

```ts
const num: number | undefined = 123123;  // number | undefined型の変数が…
num!.toString();  // numberにキャストされる
```

あくまでコンパイラーをだましているだけなので、ランタイムエラーの可能性が残ります。どうしようもない時だけ使いましょう。

```ts
const num: number | undefined = undefined;
num!.toString();  // ぬるぽ！  TypeError: Cannot read property 'toString' of undefined
```

### `noImplicitAny`オプション
TSでは型定義がない変数は`any`型になってしまいます(暗黙のany型)。それを禁止します。

```ts
const hoge; // any => コンパイルエラー！
```

明示的にany型を宣言すると、コンパイルは通ります。

```ts
const hoge: any; // コンパイルOK
```

ですが、基本的にanyの変数はJS時代に戻るようなもので、TSを使ってる意味がないので、よほど型をつけにくい事情がない限り、避けましょう！

#### 配列の初期化
設定前までは、型宣言なしで配列を初期化することができました

```ts
const array = [];  // any[]になる
```

`noImplicitAny`オプションにより、「なんの配列か」をコンパイラーに教えてやらないといけないため、型宣言が必須となります。
(静的型付けなら当然ですが)

```ts
const array: string[] = [];
```


### `noImplicitThis`オプション
JSのthisのキモさは有名なのですが、thisに型を指定していない場合にエラーを発生させることができます。
普通にクラス内でthisを使う場合は、TSが型を判断できるので問題になりません。

### `noImplicitReturns`オプション
関数内のすべての経路で、返り値の型があっているかをチェックしてくれます
(静的型付けなら当たり前ですが…)

## 「不要なコードも怒ってくれるとうれしいなー」系
### `noUnusedLocals`オプション
宣言して、一度も使われないローカル変数があると、コンパイルエラーになります。

```ts
const num = 123123; // 	'num' is declared but never used.
return;
```

import文にも効いてくれます。

```ts
import { Router, Component } from '@angular/router'; // 'Component' is declared but never used.
```

### `noUnusedParameters`オプション
一度も使われないパラメータがあると、コンパイルエラーになります。

```ts
(num: number) => { // 'num' is declared but never used.
  return "return";
}
```

フレームワークに呼ばれる関数などで、シグネチャーを合わせないといけない場合がありますが、パラメータ名を`_`で始めればunusedチェックの対象外になります。
`_`パラメータを使えば簡単にエラーを止められるのですが、自前の関数であれば当然パラメータの削除を検討しましょう！

```ts
(_num: number) => {
  return "return";
}
```

# コンパイルを通すために…！
これだけ設定すると、意識の低いnode_moduleからコンパイルエラーが上がってくる可能性があります。
その場合、`skipLibCheck`オプションの使用を検討するとよいでしょう。

# 参考記事
* 公式
* TypeScript2系のコンパイラのオプション一覧
http://qiita.com/IganinTea/items/f88bea469bff56cfbda6
* Revised 型の国のTypeScript
http://typescript.ninja/typescript-in-definitelyland/
(必読!)
mysqlのダンプ及びローテーションのシェル


```
#!/bin/sh -xeu

# バックアップファイルを何日分残しておくか
period='0'
# バックアップファイルを保存するディレクトリ
dirpath='/home/xxxx/bkup/'
#オブジェクトストレージのバケット名
bucket=s3://xxxx-xxxx
#エラー出力ファイル名
errorfilename="db_bkup_error.txt"
#sqldumpエラーファイル名
sqldumperror="sqldumperror.log"
#conf
conffilename="test_bkup.conf"

#エラー出力
function error
{
echo `date +%Y/%m/%d-%H:%M:%S`":$@" 1>>$errorfilename
}

#エラー出力して処理終了
function abort
{
echo `date +%Y/%m/%d-%H:%M:%S`":$@" 1>>$errorfilename
exit 1
}

#作業フォルダに移動
cd $dirpath

#設定ファイルを読み込み
test -r $conffilename || abort "設定ファイル読込エラー"
. ./$conffilename

for ((i=0; i<${#users[@]}; i++)){
    # バックアップするユーザー
    backupuser=${users[i]}
    # バックアップするスキーマ
    backupschema=${schemas[i]}
    # バックアップするスキーマパスワード
    backuppass=${pass[i]}

    # ファイル名を定義
    mydate=`date +%Y%m%d%H%M%S`
    filename="${backupschema}##${mydate}.sql"
    echo $filename

    #backup実行
    mysqldump --user=$backupuser -p$backuppass $backupschema --single-transaction --default-character-set=utf8mb4 --result-file=$filename --log-error=$sqldumperror
    echo "mysqldump完了"

    #作成されたファイルを圧縮
    gzip $filename || error "gzip error:${filename}"
    echo "圧縮完了"

    #オブジェクトストレージに転送
    s3cmd put $filename.gz $bucket || error "s3cmd put:${filename}"
    echo "オブジェクトストレージに転送完了"
    
}

#カレントから不要なファイルを削除
find . -name '*' | grep `date +'%Y%m%d'` | xargs rm

#オブジェクトストレージから不要ファイル削除
s3cmd ls $bucket | awk '{ print $4 }' | grep `date +'%Y%m%d' --date "${period} day ago"` | xargs s3cmd del

echo "バックアップ完了"
```
```
users=(
user1
user2
user3
)
schemas=( 
schema1
schema2
schema3
)
pass=(
pass1
pass2
pass3
)
```
Ansibleの導入と簡単な使い方


Ansibleのインストールと簡単な使い方。
前提条件としてpythonのバージョンが2.7以上であること。
また、easy_installが使用可能であること。

### Ansibleのインストール
yumとpipで必要なライブラリをインストール。

```
sudo yum install -y epel-release
sudo yum install -y sshpass
sudo yum install -y python-devel
sudo easy_install pip
sudo pip install paramiko PyYAML Jinja2 httplib2
```

続いてAnsibleをインストール。

```
sudo pip install ansible

```

Ansibleコマンドでバージョンが表示できればインストール完了

```
ansible --version

```

### PlayBookを使用する

接続情報を記述したhostsファイルを作成。
下記の例はtargetsという接続先グループにホスト名serverのホストを定義。

```hosts
[targets]
server
```

続いてplaybookのファイルを作成。
下記の例はtargetsグループ全てのホストを対象にしてplaybookを実行。
ユーザーはec2-user、sudoしてrootでコマンドを実行。
タスクは/home/ec2-userの配下にtestディレクトリを作成する。

```operation.yml
- hosts: targets
  user: ec2-user
  become: yes
  tasks:
  - file: path=/home/ec2-user/test state=directory owner=ec2-user group=ec2-user mode=0755
```

下記のコマンドでplaybookを実行するとディレクトリが作成される。
-Dオプションは変更した差分をコンソールに出力するものである。

```
ansible-playbook -i ./hosts ./operation.yml -D
```

差分だけを確認したいときは下記のように-Cオプションを使用する。

```
ansible-playbook -i ./hosts ./operation.yml -D -C
```
TCPとUDP

<TCPとUDP>
昨日の続きで投稿させていただきます。
今日はTCPとUDPについて簡単に書きたいと思います。
TCP(Transmission Control Protocol)はコネクション型プロトコルで信頼性の高い通信を実現する。
UDP(User Datagram Protocol)はTCPと違い、コネクションレス型プトロコルで通信の信頼性は保証しない。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/161833/f0c2c454-c6cb-b51f-de5a-a6d62fe0a21b.png)

 
TCPはデータの送信前に上記の図のような3ウェイハンドシェイクによってコネクションを確立する。


 ![image.png](https://qiita-image-store.s3.amazonaws.com/0/161833/baef2a81-2a7d-19bb-8bb4-28c0c7ddac83.png)

TCPでは上記の図のようにしてデータの転送、コネクションの終了を行います。

一方、UDPはコネクションの確立やフロー制御などの機能がなく、音声通話やテレビ通話などのようには速さが求められる通信に使用されます。
Jupyter notebookファイルを単に見る

### Jupyter notebookなどのipynb形式のファイルを、Jupyterを開かずに単に見たい。

Githubはipynb形式を解釈できるため、Github上のファイルは[閲覧できます]((https://github.com/blog/1995-github-jupyter-notebooks-3))。ただし、Bitbucketではその機能はまだないようです（[Issueへのリンク](https://bitbucket.org/site/master/issues/11318/enable-rich-rendering-of-jupyter-notebooks)）。

ローカルにあるipynbファイルがある場合、下記のコマンドで内容をブラウザで閲覧できます。

```bash
jupyter nbconvert filename.ipynb --stdout > tmp.html; firefox tmp.html
```

- `nbconvert`コマンドを使ってHTMLファイルを生成し、それをブラウザで開いています
- `filename.ipynb`というところは閲覧したいファイルに変えてください
- `tmp.html`というファイルが作られるので適宜削除するなどしてください
- `firefox`の部分はお好きなブラウザに変えてください


なお、Jupyterは必要です。インストールには[こちらなど](http://jupyter.readthedocs.io/en/latest/install.html)を参照ください。
ESLintで特定ルールの警告だけ修正する

既存警告の多いプロジェクトで [ESlint](http://eslint.org/) を使う場合のTipsを紹介します。

## 背景

JavaScriptの静的解析ツール [ESlint](http://eslint.org/) には、警告を自動修正してくれる [--fixオプション](http://eslint.org/docs/user-guide/command-line-interface#--fix) があります。次のように

```shell-session
$ eslint --fix src/js
```

とするだけで、スタイル違反などの警告を自動的に修正してくれる優れものです。修正対象となる警告は、検出だけする場合と同様に、 `.eslintrc` で設定されたルールに従います（すべてのルールが自動修正に対応しているわけではありません）。

ここで、既存警告の少ない新規プロジェクトや、コードベースがクリーンなプロジェクトでは、一括ですべて修正してもしれていると思います。しかし、総警告数が数千・数万規模の既存プロジェクトになってくると、個別のルールごとに修正したいことがあります。

## 解決策

[--no-eslintrcオプション](http://eslint.org/docs/user-guide/command-line-interface#--no-eslintrc) と [--ruleオプション](http://eslint.org/docs/user-guide/command-line-interface#--rule) を組み合わせることで、特定のルールの指摘だけを修正できます。例えば、 `indent` ルールだけ修正したい場合は、次の通りです。

```shell-session
$ eslint --fix --no-eslintrc --rule 'indent: ["error", 2]' src/js
```

## 補足

前述の方法で `--fix` オプションを外せば、特定のルールの警告だけを検出することができます。自動修正に対応していないルールなど、特定のルールにフォーカスして個別に修正したい場合に便利です。

```shell-session
$ eslint --no-eslintrc --rule 'indent: ["error", 2]' src/js
```

また、 [eslint-nibble](https://github.com/IanVS/eslint-nibble) をインストールすると、ルールごとの警告数を一覧し、特定のルールにドリルダウンして確認することができます。

![画面イメージ](https://github.com/IanVS/eslint-nibble/raw/master/docs/eslint-stats-screenshot.png)

こちらも全体を俯瞰したり、個別のルールに着目したりする場合に便利です。

## まとめ

`eslint --fix` を特定のルールだけに絞って実行する方法として、 `--no-eslintrc` オプションと `--rule` オプションで実現する方法を紹介しました。これであなたも警告数が数千・数万の既存プロジェクトと闘えます。
CFn Custom Resource でハマりがちな罠

[cloudpack あら便利カレンダー 2017](https://cloudpack.github.io/benri2017/) の11日目です。

追加されたのはだいぶ前ですが、 [Lambda Backed Custom Resource](http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-custom-resources-lambda.html) のおかげで[カスタムリソース](http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-custom-resources.html)を使う敷居がだいぶ下がりました。

カスタムリソースは CloudFormation でネイティブサポートされていないリソース（AWS のリソースでなくても構わないです）を作成・更新・削除する仕組みですが、 Lambda Backed カスタムリソースは大まかに言うと以下のような流れでリソースを操作します（話を単純にするため、ここでは `Create` の例のみ）。

1. リソースの操作を行う Lambda Function をあらかじめ用意しておくか、カスタムリソースを含めるテンプレート内で作成する（この Function が `custom resource provider` となる）
1. テンプレートにカスタムリソースの定義を含める
    - `ServiceToken` として上で用意した Lambda Function の ARN を指定する
    - そのリソースの操作に必要なプロパティもここに指定する
1. カスタムリソースを含めたテンプレートで `CreateStack` を実行する
1. custom resource provider が [Custom Resource Request](http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/crpg-ref-requests.html) を与えられ起動される
1. custom resource provider がリクエストの内容に基づきリソースを作成する
1. custom resource provider はリソースが作成できたことを CFn に通知する必要があるため、前述のリクエストに含まれている `ResponseURL` （S3 オブジェクトの署名済み URL）に対して、 [Custom Resource Response](http://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/crpg-ref-responses.html) の JSON を HTTPS PUT する

前置きが長くなりました。今回のネタはこの最後の段階についてです。

# 罠って何

Custom Resource Response の PUT で、 **`Content-Type` ヘッダーに `application/json` を指定すると `403 Forbidden` で失敗します**。

**`Content-Type` を指定しつつ、内容は何も設定しない（空文字）のが正解です**。使用するライブラリー等によっては自動で付加されることもあるので要注意。

地味にハマる仕様なので気をつけましょう。
【Kotlin】@MustBeDocumentedアノテーションは何に使う？

# [**@MustBeDocumented**](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.annotation/-must-be-documented/#mustbedocumented)

## ざっくり概要

> This meta-annotation determines that an annotation is a part of public API and therefore should be included in the generated documentation for the element to which the annotation is applied.

つまり、`@MustBeDocumented`を適用した`annotation class`を公開APIとみなし、
その`annotation class`を適用した要素(クラスや関数）のドキュメントに`annotation class`の情報を含めますよ〜
という宣言に用いるみたいです（ややこしい）

Javaでいうところの[@Documented](https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Documented.html)ですね
>参考：[@Documented アノテーションの意味](http://qiita.com/opengl-8080/items/1cc996d9e8bb5c811567)

## ざっくり使ってみる

以下のように、`@MustBeDocumented`を適用したアノテーションと
適用していないアノテーションクラスを作成し、それぞれを通常のクラスに付与します

```Kotlin:TestClass.kt
@MustBeDocumented
annotation class A_Annotation()

annotation class B_Annotation()

@A_Annotation
@B_Annotation
class TestClass()
```

〜

Kotlinのドキュメントの生成には[dokka](https://github.com/Kotlin/dokka)というJetBrains製のライブラリを使います
公式のガイド通りにビルド設定をし・・・

```Gradle
buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.9.14"
    }
}

apply plugin: 'org.jetbrains.dokka'

dokka {
    outputFormat = 'html' 
    outputDirectory = "$buildDir/html"
}
```

えいや！

```
> ./gradlew dokka
```

〜

すると、
以下のようなドキュメントが生成されました

> <img width="675" alt="" src="https://qiita-image-store.s3.amazonaws.com/0/181056/01384966-5fad-493d-8e4d-694e514fd1ec.png">

`@MustBeDocumented`を適用した`A_Annotation`クラスのみドキュメントに出力されてますね

## 余談

ちなみに**dokka0.9.14**で"Javadoc"を出力すると、アノテーションは表示されませんでした:cry:

```
dokka {
    outputFormat = 'javadoc' 
    outputDirectory = "$buildDir/javadoc"
}
```

><img width="550" alt="" src="https://qiita-image-store.s3.amazonaws.com/0/181056/cab63cc7-965f-959d-a8c4-e1a7ad6ca8c2.png">
VMwareにRancherOSインストール（固定IP、パスワード認証）

## 目的
プライベートな環境のvmwareにコンテナの勉強用でRancherOSを建てたい。
vSphere上に固定IPで建てるときは鍵認証の設定が面倒くさいので、とりあえずパスワード認証でログイン出来るようにする。
RancherOSとは何ぞやってのは割愛

## 手順
iso起動する。
自動でログインしてShell入力できるようになる

### cloud-config作成（固定IP設定）
今回はcloud-configを利用して固定IPの設定を行う

1. `ifconfig`とか`ip addr show`で固定IPを設定するインタフェース名を確認 → 今回は"eth0"
1. cloud-config.ymlを作成

```yaml
#cloud-config
rancher:
  network:
    interfaces:
      eth0: # ← 確認したインタフェース名を指定
        address: 172.68.1.100/24
        gateway: 172.68.1.1
        mtu: 1500
        dhcp: false
```

### インストール
インストールコマンドを打つ際に、パスワード認証設定の情報を付与する

```sh
# --append "rancher.password=[password]"で鍵認証ではなくパスワード認証でログインできるようになる
# 以下の例は"rancher"をパスワードに設定している(user:rancher、pass:rancherでログイン可能)
sudo ros install -c cloud-config.yml -d /dev/sda --append "rancher.password=rancher"
```

インストール完了後、RancherOSが固定IP、パスワード認証な状態で自動起動する。
GitBookのHTMLをminifyするplugin

GitBookのHTMLをminifyするプラグインを紹介します。

## GitBook HTML minify Plugin

[GitBook HTML minify Plugin](https://github.com/hiroki-uchida/gitbook-plugin-html-minifier)

HTMLをminifyするGitBook Pluginです。

[html-minifier](https://github.com/kangax/html-minifier)をそのままGitbbok Plugin化しています。

インストールするだけでビルドされるHTMLがminifyされるようになります。

## 使い方

### インストール

`book.json`に`html-minifier`を追加して`$ gitbook install`を実行します。

```json
{
  "plugins": ["html-minifier"]
}
```

```bash
$ gitbook install
```

### 設定

[html-minifier](https://github.com/kangax/html-minifier)で用意されている設定をそのまま使用できます。

[Options Quick Reference](https://github.com/kangax/html-minifier#options-quick-reference)を参考に`book.json`を調整すると思い通りのminifyが可能です。

```json
{
  "plugins": ["html-minifier"],
  "pluginsConfig": {
    "html-minifier": {
      "caseSensitive": true,
      "collapseBooleanAttributes": true,
      "collapseInlineTagWhitespace": true,
      "collapseWhitespace": true,
      "conservativeCollapse": true,
      "customAttrAssign": [],
      "customAttrSurround": [],
      "decodeEntities": false,
      "html5": true,
      "includeAutoGeneratedTags": true,
      "keepClosingSlash": true,
      "minifyCSS": true,
      "minifyJS": true,
      "minifyURLs": false,
      "preserveLineBreaks": false,
      "preventAttributesEscaping": false,
      "processConditionalComments": false,
      "processScripts": [],
      "quoteCharacter": null,
      "removeAttributeQuotes": false,
      "removeComments": true,
      "removeEmptyAttributes": false,
      "removeEmptyElements": true,
      "removeOptionalTags": false,
      "removeRedundantAttributes": false,
      "removeScriptTypeAttributes": false,
      "removeStyleLinkTypeAttributes": false,
      "removeTagWhitespace": true,
      "sortAttributes": true,
      "sortClassName": true,
      "trimCustomFragments": false,
      "useShortDoctype": false,
    }
  }
}
```

## License

MIT License
超簡潔なGitHubのリポジトリ作成とクローン

# 前提条件
1. 自分のPCでGitコマンドが使える。
2. GitHubのアカウントを持っている。

# step 1
![図1.png](https://qiita-image-store.s3.amazonaws.com/0/187152/c1e10e9c-cec0-1b79-86e0-18abebea11f1.png)
https://github.com/
に入って[+]から[New repository]

# step 2
![図2.png](https://qiita-image-store.s3.amazonaws.com/0/187152/954a0ef7-9c45-ac5e-495b-27f01e381a78.png)
矢印のあるとこだけ設定するよ！

# step 3
![image.png](https://qiita-image-store.s3.amazonaws.com/0/187152/490a7c06-b175-eaac-5c4b-e1558ca28a3a.png)

シェルを開いて

```

$ cd [お好みのディレクトリ]
$ git clone [URLをコピペ]

```

# step 4
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/187152/d12f7d69-1e6e-ece0-be43-7aa5fe2afd65.png)

クローン成功
任意のTwitterアカウントのタイムラインを取得

## はじめに
この文章は基本的に自分の備忘録と成長記録として書いたものであるが、もしかしたら誰かの役に立つかもしれないのでここに記したいと思う。
なお投稿者は生粋の初心者(未だにAPIあたりの単語の使い方も曖昧)なのでご容赦を。

## 本記事の対象者
自分(開発・プログラミング経験全くなし、JavaScript勉強中)

## 目標
今回は任意のアカウントのTLを自分のリストとして取得するプログラムを書く。

## 準備
- node, npm のインストール
- 自分のTwitterアカウントのアクセストークンの取得(「twitter アクセストークン」でググる)


## リストの作成・メンバーの登録
[Twitter Developerの公式サイト](https://dev.twitter.com/index)を参考にリストを作成し、メンバーを登録するプログラム(下記)を書く。
なお、同じディレクトリ上に`npm install twit`でtwitモジュールをインストールしておく。

```js
const Twit = require('twit');
// 以下、正しいキーを設定してください
const T = new Twit({
  consumer_key: '自分のカスタマーキー',
  consumer_secret: '自分のシークレットカスタマーキー',
  access_token: '自分のアクセスキー',
  access_token_secret: '自分のシークレットアクセスキー',
});

// リストの作成
T.post(
  'lists/create',
  {name: 'test', mode: 'private', description: 'てすと'},
  function (err, data, response) {console.log(data)}
)

// リストへのメンバーの登録
T.get(
  'friends/ids',
  {screen_name: 'TLが欲しいTwitterのアカウント名', stringify_ids: true},
  function (err, data, response) {
    for(let i = 0; i < data.ids.length/100; i++) {
      let followers = data.ids.slice(0 + 100*i, 100*(i+1) - 1)
      T.post(
        'lists/members/create_all', 
        {
          slug: 'リスト名', // 上記で作成したリストを使うなら'test'
          owner_screen_name: 'リスト所有しているアカウント名',
          user_id: followers,
        },
        function(err, data, res) {console.log(data)}
      )
    }
  }
)
```

これを node で実行すれば自分のアカウントにリストが自動生成されている。
ちなみに`T.get`の第1引数を`'followers/ids'`にすると、フォロワーを全部リストに追加することができる。
ただしTwitterの仕様のためか、リストに反映されるまでには時間がかかる。
今回は以上。
UIImagePickerControllerでフォトライブラリから画像を選ぶサンプル

UIImagePickerControllerを使ってフォトライブラリから画像を選ぶサンプルプルグラムを書いてみました。
フォトライブラリから画像を選択するために、プロジェクトの `info.plist`にフォトライブラリを使用する旨を記述します。これを書いておかないとUIImagePickerControllerは使えません。
キーの値は以下の値を使います。`Type`は`String`で`Value`の中に使用理由を書きます。
使用理由を書かないと審査の時に落とされるらしいです。下の画像のような感じです。
<img width="1155" alt="スクリーンショット 2017-06-14 23.12.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/63855/12d6335b-428e-efe0-a316-a4a72f4cb92e.png">


```swift:ViewController.swift

import UIKit

class ViewController: UIViewController,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
    
    var imagePickUpButton:UIButton = UIButton()
    var picker: UIImagePickerController! = UIImagePickerController()

    override func viewDidLoad() {
        super.viewDidLoad()

        //押されるとUIImagePickerControllerが開くボタンを作成する
        imagePickUpButton.frame = self.view.bounds
        imagePickUpButton.addTarget(self, action: #selector(imagePickUpButtonClicked(sender:)), for: .touchUpInside)
        imagePickUpButton.backgroundColor = UIColor.gray
        imagePickUpButton.setTitle("Toupe Me!!", for: UIControlState.normal)
        self.view.addSubview(imagePickUpButton)
    }
    
    //basicボタンが押されたら呼ばれます
    func imagePickUpButtonClicked(sender: UIButton){

        //PhotoLibraryから画像を選択
        picker.sourceType = UIImagePickerControllerSourceType.photoLibrary
        
        //デリゲートを設定する
        picker.delegate = self
        
        //現れるピッカーNavigationBarの文字色を設定する
        picker.navigationBar.tintColor = UIColor.white
        
        //現れるピッカーNavigationBarの背景色を設定する
        picker.navigationBar.barTintColor = UIColor.gray
        
        //ピッカーを表示する
        present(picker, animated: true, completion: nil)
    }
    
    //UIImagePickerControllerのデリゲートメソッド
    
    //画像が選択された時に呼ばれる.
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        
        if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
            
            //ボタンの背景に選択した画像を設定
            imagePickUpButton.setBackgroundImage(image, for: UIControlState.normal)
        } else{
            print("Error")
        }
        
        // モーダルビューを閉じる
        self.dismiss(animated: true, completion: nil)
    }
    
     //画像選択がキャンセルされた時に呼ばれる.
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        
        // モーダルビューを閉じる
        self.dismiss(animated: true, completion: nil)
    }
}
```

実行すると以下のようになります


<img width="423" alt="スクリーンショット 2017-06-15 0.06.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/63855/701bd0aa-8d1e-2bb8-1bc1-999d1257b1e1.png">
<img width="423" alt="スクリーンショット 2017-06-15 0.07.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/63855/0844b9f5-4fc1-3bf1-6eaf-fe18a9c80642.png">
OS:Hyper-V Server 2012 R2についての個人的まとめ

#この記事について#
自宅に仮想サーバーを立てて、色々な環境を使ってみる目的でMicroSoftが提供してる本OSをマシンに入れてみました。この記事は使っているうちに気づいたことなどを書き留める備忘録として使っていく予定です。

#環境構成
以下の構成が目標です。

■ローカル環境
ローカルPC(Windows8.1)>VirtualBox(WindowsServer2012R2)>Hyper-Vマネージャー
↓
■リモート環境
リモート上のHyper-V Server 2012 R2>仮想マシン(CentOS7)

#そもそもHyper-V Server 2012 R2って何に使うのか#
1台の物理マシン上で複数の仮想マシンを動かすために使います。
OSが入っている環境に入れるホストOS型の仮想化技術ではなくて、ハードウェアそのものにOSとして入れてあげて使うハイパーバイザ型というものだそうです。

<b>利用図</b>
http://ascii.jp/elem/000/000/847/847570/index-2.html

#用意するもの#
システム要件は以下のURL先に載っていますので、要件を満たすマシンを選んでください。
http://ascii.jp/elem/000/000/847/847570/

また、OSとして入れてあげる必要があるので、OSが入っていないマシンを用意してあげる必要があります。
私はOSレスモデルのサーバー用マシン(激安)をヤフオクで手に入れて、取り敢えずインストールまでは出来ました。

<b>マシン参考</b>
[富士通 PRIMERGY TX100 S3](http://pc.usy.jp/wiki/354.html)
静音サーバーですが起動しているときに寝るのはちょっとむずかしいかな・・・、ぐらいの音は出ます。(処理してなければ、もっと静かかもしれませんが。)

#Hyper-V Server 2012 R2のインストール手順#
とりあえず、以下のURL先を見れば、おおよそのことは片付きます。ダウンロード元ページも載っています。

[Hyper-V Serverを知り、インストールと初期設定をする](http://ascii.jp/elem/000/000/847/847570/)

<b>1.</b>Hyper-V Server 2012 R2をDVD-RWに書き込む
<b>2.</b>インストールするマシンのドライブにいれて起動する
<b>3.</b>Windowsロゴの画面に続けて、インストール設定の画面が表示される
<b>3-1.</b>Hyper V Serverのインストールする場所を選んでください の画面で
	    ドライブを選んだとき、
	    ドライブ0 パーティーション1にMicrosoft Hyper-V Server をインストールすることができません
	    このパーティションは小さすぎます。パーティションのサイズを4180MB以上にするか、別のパーティションを選んでください
	    と出たのですが、4180MB以上あるパーティションを選択すれば、問題無いです。

<b>4.</b>インストール後の設定
Hyper-V Server 2012 R2自体にはGUIが無く、CUIしかインターフェイスがありません。
(コマンドラインとログイン後に毎回出るsconfigツールのみ。
sconfigツールは終了しても、コマンドラインでsconfigと打てば、再度表示されます。)
	
そのため、詳細な設定はGUI管理ツールを使って、マシンにリモート接続を行い、管理していくのが便利です

#管理ソフト Hyper-V マネージャーの導入

この管理ソフトは素で使おうとするとWindows 8.1 Proや8.1 Enterprise、Windows Server 2012 R2
が必要になります。通常のWindows 8.1では使用できませんでした。

そのため、ローカル環境からHyper-V マネージャーを使うため、ローカルPCにVirtualBoxを入れ、その中に
WindowsServer 2012 R2を入れ、Hyper-V マネージャーを使います。

手順は以下を参考にすればできると思います。
[Hyper-V Server 2012 R2　その①](http://miz.blue/hyper-v-server-2012-r2_note1/)

#Hyper-V マネージャーからリモート上のHyper-V Server 2012 R2にアクセスする

手順は以下を参考にすればできると思います。

[Windows Server 2012 > 非ドメイン環境におけるHyper-Vのリモート管理](http://yamanxworld.blogspot.jp/2013/03/windows-server-2012-hyper-v.html)

#リモート上のHyper-V Server 2012 R2から仮想マシン(CentOS7)にアクセスする

Hyper-V マネージャー>リモート上のHyper-V Server 2012 R2から仮想マシン(CentOS7)につなごうとした際に
『RPCサーバーを使用できません。○○と○○との間の通信を確立できません。』
とエラーが出ましたが、VirtualBoxのネットワーク設定をNATからブリッジアダプターに変更したら、接続することできました。

エラーの解決参考
[Hyper-V Server 2012 R2　その①](http://miz.blue/hyper-v-server-2012-r2_note1/)
改行コードをCR+LF（Windows）からLF（Linux）に変更する方法

- Windowsの改行コードはCR+LF
- Linuxの改行コードはLF
- メールとかで添付されたファイルをMacのemacsで開くと"^M"が表示されてうざい（時がある）
- コマンドラインですっきり解決

```
$ tr -d '\r' < original_file > edited_file
```

- 上のコマンドだと改行が無くなっちゃうときがある
- そんな時はこれ

```
$ tr '\r' '\n' < original_file > edited_file
```

- そもそもメールでコードのやり取りとかはうざい
- gitとか使ったほうがいい
みなさま、食後のrubyクイズでございます。

みなさま、食後のrubyクイズでございます:ice_cream:

# 問題
### 第1問

```ruby
:hoge.size
# => ?
```

### 第2問

```ruby
!true
# => ?

! true
# => ?
```

### 第3問

```ruby
[3,4,5].map do |hoge|
     next hoge if hoge>4
end
# => ?

array = [3,4,5]
array.map do |hoge|
     next hoge if hoge>4
end
puts array

# => ?

```

.
.
.
.
.
.


# 答え
### 第1問

```ruby
:hoge.size
# => 4
```

シンボルをsizeにしたら、文字数が返ってきます:innocent:

### 第2問

```ruby
!true
# => false

! true
# => false
```

`!true`は演算子の"!"でtrueがfalseになり、
~~`! true`はメソッドの"!"でtrueがfalseになります。~~
「`! true`はメソッドの"!"を使える」と思っていたのですが、どうやら違うみたいです。
なぜスペース空けてもできるのか、鋭意調べ中でございます。少々お待ちください:moyai:
とりあえず、スペース空けてもfalseになるよとだけ。

### 第3問

```ruby
[3,4,5].map do |hoge|
     next hoge if hoge>4
end
# => [nil, nil, 5]

array = [3,4,5]
array.map do |hoge|
     next hoge if hoge>4
end
puts array

# => [3, 4, 5]
```

`map`は返り値がないとnilになってしまいます。
そして、`map`は元の配列には影響を与えません。
レシーバの配列を変更したい場合は`map!`を使いましょう。

```ruby
array = [3,4,5]
array.map!{|hoge| next hoge if hoge>4}
array

# => [nil, nil, 5]
```

# みなみなさま
Have a nice day ! :innocent:
漸化式

数学２・Bの範囲ではじめて聞く単語、漸化式。
単なる再帰関数のことと考えてよい。


```js
function a(n){
  if(n == 1){
    return 2;
  }
  return a(n-1) + 3;
}

function b(n){
  if(n == 1){
    return 2;
  }
  return 3 * b(n-1);
}

for(i=1; i<5; i++){
  console.log(a(i));
}

console.log('-----------------');

for(i=1; i<5; i++){
  console.log(b(i));
}
```

```
~ % node hoge.js
2
5
8
11
-----------------
2
6
18
54
```