OmniAICreator/Qiita-1.07M huggingface dataset:
Atomのあいまい補完を少し厳密にする

# 本記事の概要
大した内容ではないが、どこで設定するのか迷ったのと、設定したらすごく快適になったので、備忘録として記載する。（あくまで個人の好みです！）Atomを使い始めたばかりの人のお役に立てば〜
※本記事で使う例は、全てRubyのソースです。

# 1.現状の動き
autocomplete-plusというパッケージを入れておくと入力補完を行うことができるが、デフォルト設定のあいまい補完では、目的の単語と部分一致すれば候補として出てくる。
「Contro」まで入力すると下記のように各コントローラが候補として出てくる。
<img width="182" alt="image5.png" src="https://qiita-image-store.s3.amazonaws.com/0/174425/3438048b-2ff4-571a-ed5e-880b3938cb61.png">

「en」を入力した場合も、同様に候補が出てくる。
<img width="263" alt="image4.png" src="https://qiita-image-store.s3.amazonaws.com/0/174425/2fcaaafe-9e53-4d2b-2ef6-3d3e403c99b2.png">

タイプが少なくて済むので非常に便利だが、不便なこともあった。例えば、endのような短い単語を入力した際に下記のように「end」を含む単語が候補に上がってしまう。間違ってEnterを押してしまうことがあったり、Escを押さなきゃいけなかったり地味に面倒だった。
<img width="347" alt="スクリーンショット 2018-06-01 0.13.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/174425/5cabbfde-262b-a2b9-b34c-fc143220e826.png">

# 2.設定変更
下記設定を行うと、あいまい補完のマッチングが「先頭の文字が一致する」ものだけとなる。
環境設定 > パッケージ > autocomplete-plus > settingsから設定画面を開き、「Use Strict Matching For Built-In Provider」にチェック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/174425/e9308ca5-0d08-df28-7434-0f524476fc58.png)

# 3.設定変更後の動き
余計な候補は出なくなる。
<img width="88" alt="image1.png" src="https://qiita-image-store.s3.amazonaws.com/0/174425/6ce59cbf-f842-e2a4-c70c-c249463be45f.png">

入力した文字から始まるあいまい補完は有効なまま。
<img width="257" alt="image3.png" src="https://qiita-image-store.s3.amazonaws.com/0/174425/e9ed5d3a-1d4c-0922-aa12-3cd8d1df0fc2.png">

ただし、「contro」のように目的の単語の途中の文字と部分一致する候補は出なくなるので注意！
あくまで、先頭から合致する候補を出すだけになる。
<img width="175" alt="image6.png" src="https://qiita-image-store.s3.amazonaws.com/0/174425/07ba6b56-2f15-0662-c1fa-43d7f1b0caa2.png">
JavaScript にも "マルチスレッド プログラミングの頻出問題" がある。

元ネタ: [eslint/eslint#10405](https://github.com/eslint/eslint/issues/10405)

このルール提案は「アトミックではない変数の更新を警告したい」というものです。

アトミックではない変数の更新というのは、マルチスレッド プログラミングの最初の方に出てくるアレです。または、RDB のトランザクションの説明で出てくるアレです。

JavaScript のコードはシングルスレッドで動くのに、アトミックではない変数の更新なんてあるの? と思ったらありました。スレッドを自由に作成できる言語と違って、どこでも自由に別処理が割り込んでくるわけではありません。しかし、`yield`や`await`によって、式の途中で別処理が割り込んでくることがありえるのです。

<p data-height="512" data-theme-id="dark" data-slug-hash="RJWLqw" data-default-tab="js,result" data-user="mysticatea" data-embed-version="2" data-pen-title="Threading problem" class="codepen">See the Pen <a href="https://codepen.io/mysticatea/pen/RJWLqw/">Threading problem</a> by Toru Nagashima (<a href="https://codepen.io/mysticatea">@mysticatea</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

肝はここです。

```js
total += await getFileSize(file)
```

次のように動作します。

1. 変数`total`の値をメモリに読み込む。
2. 処理`await getFileSize(file)`を実行して、結果をメモリに読み込む。
3. 手順 1 と手順 2 の値を足し合わせた結果で変数`total`の値を書き換える。

手順 2 が`await`式を持っているため、ここに別処理が割り込むことができます。そして、その別処理の中で変数`total`の値が変更された場合に意図しない結果になるのです。

この例では、`reduce`関数を使うなどして共有変数を持たないようにすべきですね。

```js
function getTotalFileSize(files) {
    return Promise.all(files.map(getFileSize)).reduce((a, b) => a + b, 0)
}
```

別の例です。

```js
const pattern = /\d{3}/g

// 文字列`test`の中にある特定パターンを列挙する関数。
function* iteratePattern(text) {
    let match = null

    pattern.lastIndex = 0
    while ((match = pattern.exec(text)) != null) {
        yield match
    }
}
```

この関数は`yield`式を持つため、`yield match`の部分に別処理が割り込むことができます。すると、`pattern.lastIndex`がめちゃくちゃになってしまって、意図しない結果が生成される可能性があります。
simple-twitter

#概要
　twitterというのは、APIを公開していて、なかなか面白いです。
　これをベースにnode pugでクライアントを作りました。
　これは、「広告」もはいらず、特定の人のツイートのフィルタ等もありません。

#ダウンロード
 https://github.com/hideume/simple-twc
 でございます。
 windowsでもlinuxでも動作確認しました。nodeは必須です。

#screenshot
![image.png](https://qiita-image-store.s3.amazonaws.com/0/60225/640eeb0e-8565-e30e-e2af-e0d97b33e636.png)
 こんな感じ

#特徴
　普通のtwitterだとapiはあるんだけど、メニューの奥底にあるので使いにくい
というのがありますね。まだまだ、APIは対応していないのもあるんですが、おいおい
作ろうと思います。
　retweetの速度計測なんてのもあって、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/60225/404adf7e-f423-865f-25c2-396e687a8670.png)
　こんな感じになります。最新の80tweetを時間毎に表示しているもんです。

　その他、userのリストとかの一覧が簡単にでるので、user分析を今後は充実したいかなあ・・とか、analysticをもう少し簡単に見れるようにしたいなあ・・とか考えております。
Swiftで実装するデザインパターン 「Strategy」


条件分岐などの戦略部分をクラス化しちゃおうぜ！っていうパターン


```swift:strategy.swift
//: Playground - noun: a place where people can play

import UIKit

struct Human {
    let age: Int
    let height: Int
    let weight: Int
}

// Strategy
protocol Comparator {
    func compare(h1: Human, h2: Human) -> Int
}

// ConcreteStrategy
struct AgeComparator: Comparator {
    func compare(h1: Human, h2: Human) -> Int {
        if h1.age > h2.age {
            return 1
        } else if h1.age == h2.age {
            return 0
        } else {
            return -1
        }
    }
}

// ConcreteStrategy2
struct HeightComparator: Comparator {
    func compare(h1: Human, h2: Human) -> Int {
        if h1.height > h2.height {
            return 1
        } else if h1.weight == h2.weight {
            return 0
        } else {
            return -1
        }
    }
}

struct WeightComparator: Comparator {
    func compare(h1: Human, h2: Human) -> Int {
        if h1.weight > h2.weight {
            return 1
        } else if h1.weight == h2.weight {
            return 0
        } else {
            return -1
        }
    }
}

struct MyClass {
    let comparator: Comparator
    
    func compare(h1: Human, h2: Human) -> Int {
        return comparator.compare(h1: h1, h2: h2)
    }
}

```
PHPの空白文字（\s）には全角スペースが含まれる

正規表現で検索して\sを調べると全角スペースは含まれないというところが多い。
とりあえずPHPで試したら以下のようになりました。

```
$str = ' あいうえお　';

$result = mb_ereg_replace('\s', '', $str);

var_dump($result);
```

全角スペースが対象（ver 5.6.2）

```
string(15) "あいうえお"
```

全角スペースが対象外（ver 5.5.34）

```
string(18) "あいうえお　"
```
AlibabaCloudのAuto Scalingを触ってみる

# はじめに
今回は、AlibabaCloudの
**Auto Scaling**
に触れます。

# 準備
[AlibabaCloudのResource Orchestration Service(ROS)を触ってみる。](https://qiita.com/wa-ta-ru/items/244596cbb7403c65f566)
の、ROSを使用してVPCを作っておきます。
　
# コンソールでポチポチしくだけでできます。
![93a56313.png](https://qiita-image-store.s3.amazonaws.com/0/241104/72254064-639d-f859-81c0-40f5bd15c06e.png)

![acbeca00.png](https://qiita-image-store.s3.amazonaws.com/0/241104/2225fcd0-97b3-9adb-2766-b3144c9ba786.png)

![09a57e15.png](https://qiita-image-store.s3.amazonaws.com/0/241104/484421b9-e30e-195c-4346-42d9de67934e.png)

# そのまま、スケーリングの設定に進みます。

![b127bf91.png](https://qiita-image-store.s3.amazonaws.com/0/241104/114ea38a-32ab-eb71-0482-f0293e44f8cb.png)

![24754eed.png](https://qiita-image-store.s3.amazonaws.com/0/241104/8e64b1e3-9d98-7908-258a-7de5de9f02b8.png)

![b9d1548d.png](https://qiita-image-store.s3.amazonaws.com/0/241104/44644348-cbba-b7ed-a872-1c3acf641fa0.png)

![c7cdf7d4.png](https://qiita-image-store.s3.amazonaws.com/0/241104/c274da1a-379e-2ee8-1946-26a47cbc60cd.png)

![0ffbff75.png](https://qiita-image-store.s3.amazonaws.com/0/241104/388cfdf8-6931-d482-451a-dbfefc68dac2.png)

# 有効にします。

![c0f52d8e.png](https://qiita-image-store.s3.amazonaws.com/0/241104/ce4b410b-56ff-8b68-996d-d1ca270c9802.png)

![0989b14d.png](https://qiita-image-store.s3.amazonaws.com/0/241104/05166d90-c7c6-5482-f3b1-9e7bd1d98aba.png)

# しばらく待つと、2台起動します
![8868e357.png](https://qiita-image-store.s3.amazonaws.com/0/241104/21655f16-cf60-1055-c7f1-e2a5cbd0825c.png)

![80712364.png](https://qiita-image-store.s3.amazonaws.com/0/241104/bae550e0-5712-3447-071b-1a81791b7a51.png)

ECSのコンソールに行くと

![e194c138.png](https://qiita-image-store.s3.amazonaws.com/0/241104/be6599ee-2c56-29ff-33cf-c8e4a9dbb46f.png)

# せっかくなので、インスタンスを一つダウンさせてみます。

![81c12be7.png](https://qiita-image-store.s3.amazonaws.com/0/241104/d1e74672-9274-ac9b-0ca3-03f2422890cb.png)

![d30c4e40.png](https://qiita-image-store.s3.amazonaws.com/0/241104/bf6f1acb-3dc7-73c9-996a-d8751ca1e063.png)

![50902f74.png](https://qiita-image-store.s3.amazonaws.com/0/241104/ec80bd55-45ca-4961-73fd-0219bbd9ab67.png)

![7c4be93f.png](https://qiita-image-store.s3.amazonaws.com/0/241104/1fe2f6a1-dbff-11d8-f05a-37f41c9da9bb.png)

![e36b592c.png](https://qiita-image-store.s3.amazonaws.com/0/241104/b9a80946-73fd-87b6-2c16-7774958663e0.png)

# さいごに
とても簡単に仮想サーバの冗長化ができました。
自宅のラズパイからメール送信する(NURO光)

表題の通り。

# 前提

 - プロバイダはNURO光(G2V マンションミニ)
 - OS: CentOS 7
 - メールクライアント: Postfix
 - [OP25B対策がなされている](https://support.so-net.ne.jp/supportsitedetailpage?id=000012073)ので 必要な設定を行う

# 手順

```shell-session:1.main.cfの設定
# vim /etc/postfix/main.cf

下記の内容を追記/編集する
mydomain = (取得しているドメイン)
relayhost = [mail.so-net.ne.jp]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/relay_password
smtp_sasl_security_options = noanonymous
```
replayhost で指定するリレーホストはSo-netのものに、サブミッションポート(587番)を利用していることに注意

```shell-session:2.SMTP-AUTHの設定
# yum install cyrus-sasl-plain
# touch /etc/postfix/relay_password
# vim /etc/postfix/relay_password
```

```shell-session:/etc/postfix/relay_password
[mail.so-net.ne.jp]:587    [ユーザ名]:[パスワード]
# ユーザ名、パスワードは申し込み後に到着するハガキに書いてある!
```

```shell-session:3.relay_password.dbの設定、再起動
# chmod 600 /etc/postfix/relay_password ※パスワードが記載されてるのでパーミッション変えておく
# postmap /etc/postfix/relay_password
# systemctl restart postfix.service
# systemctl enable postfix.service
```

```shell-session:4.テスト送信
$ mail hoge@sample.com
Subject: hoge

hogehoge
.
EOT
```
無事に送信成功。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/154711/d6862f30-3563-cc7b-7624-6894e0bc3944.png)


SPFレコードは各自で対応してください。私はMyDNS使ってます。
自宅の動的IPアドレスではなく 以下のアドレスになる様子。
202.238.84.151(ms-somxout01.so-net.ne.jp)
202.238.84.152(ms-somxout02.so-net.ne.jp)

以上
docker-composeやesc-cli composeのcommandでデーモン起動したいシェルコマンドを叩くときはstart-stop-daemonが便利じゃないかという話

最近になってやっとEC2原人からコンテナ猿人になりつつある俺です。
1コンテナ1プロセスな原則に逆らわなきゃいけないことがでてきてしまったとき
`bash -c` を改行しながら書くと可読性が向上しますよねと。

で、そのときに&起動すると構文エラーになるので、
start-stop-daemon先生を使って俺の最愛のシェルコマンドをダエモンにして、
最後に実行するシェルコマンドをフロントエンド起動してDockerコンテナを動かしましょう。
という話です。

ubuntuベースなimageで叩いた例です。
alpineとかもっと軽量ミニ四駆なlinuxをベースにしてる場合はstart-sop-daemonがあるのかは知らんですよ。

# yarn watchしつつRailsを動かしたい例

- docker-compose.yml

```
 rails-app:
    image: orenosaikyouime-ji:latest
    command: >
      /bin/bash -xc 
      "start-stop-daemon --start --quiet --background --exec yarn -- --cwd /app/js  watch
      && bundle exec rails assets:precompile
      && bundle exec puma -C config/puma.rb"
    environment:
      ..省略..
```

完
Gitコマンドユースケース

# gitコマンドユースケース
よく質問されるコマンドやたまにしか使わないので忘れやすいコマンドをメモ

## ブランチを新規作成したい
```
# ベースになるブランチに切り替える
git checkout ${base branch}
# 新規作成
git checkout -b ${branch name}
```

## ファイルがいつ削除されたか確認したい
```
git log --diff-filter=D --summary
```

## 指定したキーワードを含む修正がいつされたか確認したい
```
git log -p -S${keyword}
```

## 一時的に変更を退避したい
```
# 退避
git stash
# add前のファイルも退避
git stash -u
# 退避した一覧を見る
git stash list
# 直前の退避を戻す
git stash pop
# 退避した変更を反映
git stash apply # 全て
git stash apply stash@{ID} # ID指定
# 削除(直近)
git stash drop
```

## 特定のコミット(*)を今のブランチに反映したい
(*)リモートブランチに存在していること

```
git fetch
git cherry-pick -rn ${commit hash} # commitしない
```

## masterをマージしたい
```
git fetch
git merge origin/master
```

Fast-Forwardできればする。できなければNon Fast-Forward(マージコミットが作られる)

常にマージコミットを作りたい場合

```
git merge --no-ff origin/master
```

常にFast-Forwardしたい場合（できない場合はエラーになる）

```
git merge --ff-only origin/master
```

## コンフリクトしたファイルをマージ元(マージ先)の変更だけ反映したい
```
# チェックアウトしているブランチの変更を反映
git checkout --ours ${file}

# マージもとのブランチの変更を反映
git checkout --theirs ${file}
```

## マージを取り消したい
```
git reset --hard ORIG_HEAD
```

## addを取り消したい
```
git reset HEAD ${file}
```

## Untracked filesを消したい
```
# 削除対象ファイルの確認
git clean -n

# 削除対象ディレクトリの確認
git clean -nd

# ファイル削除
git clean -f

# ディレクトリ削除
git clean -fd
```

## 一部のファイルやディレクトリだけ別ブランチから取得したい
```
git fetch
git checkout ${branch} ${directory/file}
```

## 直前のコミットメッセージを修正したい
```
git commit --amend
```

## コミットを取り消したい(履歴は残す)
```
git revert ${commit hash} -n # commitしない
# プルリクのマージをリバートしたいとき
# -m ${N} 1: マージされた側のブランチ , 2: マージする側のブランチに戻す
git revert -m 1 ${commit hash} -n # commitしない
```

## 間違ってPUSHしてしまった変更を取り消したい
※ブランチを破壊してしまう可能性もある危険なコマンドなので注意  

```
# ログ確認
git log --oneline
# 指定コミットまで戻す
git reset --hard ${commit hash}
# force push
git push origin ${branch} -f
```

## プルリクのcommit履歴を消したい
※ブランチを破壊してしまう可能性もある危険なコマンドなので注意

```
# ログ確認
git log --oneline
# 指定コミットまで戻す
git reset --soft ${commit hash}
# force push
git push origin ${branch} -f
# ローカルには変更が残っているので必要に応じて再commit & push
```

## ローカルのコミットを取り消す

```
# ログ確認
git log --oneline
# 指定コミットまで戻す
git reset --soft ${commit hash}
# stagから下げる
git restore --staged <file>...
```
What is the difference between Q-learning, TD-learning and TD-lambda?

In Q-Learning, you keep track of a value Q(s,a)for each state-action pair, and when you perform an action a in some state s, observe the reward r and the next state s′, you update Qnew(s,a)=(1−α)Qold(s,a)+α(r+maxa′Q(s′,a′)).

In TD-learning, instead of just updating the Q-value of your last step, you also update the previous steps.

TD-λ uses a discounting factor λ to make changes to predictions made further in the past smaller relative to changes in the immediate past. This accounts for any uncertainty about the dynamics of the world and the possibility that the policy being followed is not optimal, for example: the decision we made 10 steps ago might have been right, but afterwards we made a mistake, which we are now correcting, so we should not change our prediction from 10 steps ago too much.
標準化回帰係数。Standardize regression coefficient。python。

標準化回帰係数について、調べたこと、リンク先をメモ。

ロジスティック回帰（教師有り学習）
http://www.tsjshg.info/udemy/Lec76-79.html

重回帰分析　SPSSを使用。標準回帰係数の説明がある。
http://www.u-gakugei.ac.jp/~kishilab/spss-mra.htm

よくお世話になっているサイト。やはり記載が親切。
https://bellcurve.jp/statistics/blog/14077.html

日本語、標準回帰係数の説明。
方法は二つあることが判明。
１、説明変数を先に標準化（平均０、分散1)して、回帰分析を行い、回帰係数を求める。
２、回帰分析を用いた後に、偏回帰係数から標準化回帰係数を求める。
https://www.weblio.jp/content/%E6%A8%99%E6%BA%96%E5%8C%96%E5%81%8F%E5%9B%9E%E5%B8%B0%E4%BF%82%E6%95%B0

英語、Python、logstic回帰で標準回帰係数を求めるコードがある。(
が、それが正しいやり方には見えない）
http://enhancedatascience.com/2017/04/23/tutorial-logistic-regression-python/
https://github.com/AntoineGuillot2/Logistic-Regression-Python/

英語、詳しい説明。理解し難い。
https://think-lab.github.io/d/205/

英語、You tube。SPSSとエクセルを利用して、標準化回帰係数を計算している。論拠となる論文の題名も書いてあり、好印象。
https://www.youtube.com/watch?v=z9ltC4tniYY
こちらは論文へのリンク
http://www.ccitonline.org/jking/homepage/standardized_paper.doc

Appendix A
A Microsoft Excel Function for Calculating a Standardized 
Logistic Regression Coefficient

Cell A1 = Enter the mean predicted probability for the dataset.
Cell A2 = Enter the unstandardized beta weight for X.
Cell A3 = Enter the sample standard deviation for X.

Cell A4:  Calculate a standardized coefficient for X by typing:

=(1/(1+EXP(-(LN(A1/(1-A1))+0.5*A2*A3))))-(1/(1+EXP(-(LN(A1/(1-A1))-0.5*A2*A3))))

Repeat for additional predictor variables.
nuxtで"No parser and no filepath given..."というエラーが出る件

nuxtでコンパイル時に"No parser and no filepath given..."というメッセージのエラーが出てくるけど原因や対処方法がどこにも見つからなかったので記録しておきます。

#エラー内容

nuxt実行時に以下のエラーが複数回表示される（昔は出なかった気がした）

> No parser and no filepath given, using 'babylon' the parser now but this will throw an error in the future. Please specify a parser or a filepath so one can be inferred.

特にエラー（警告）が表示されているだけで、実行に問題はなさそうだが気になる。

##確認したパッケージバージョン

nuxt 1.4.0
vue-loader 13.7.0
prettier 1.13.4

#原因

調べてみるとvue-loaderがtemplate-compilerを実行する時にprettierというパッケージを呼びに行ってそこでエラーが出ている模様

prettierを見に行くと1.13.0以降はdefault値がbabylonからundefinedに変更になっている

```js:core-options.js
  ....
  parser: {
    since: "0.0.10",
    category: CATEGORY_GLOBAL,
    type: "choice",
    default: [
      { since: "0.0.10", value: "babylon" },
      { since: "1.13.0", value: undefined }
    ],
    .....
  }
```
https://github.com/prettier/prettier/blob/1.13.0/src/main/core-options.js#L89

修正が入ったのがこれを書いている9日前くらい(2018/5/24前後?)の変更のようだ。

https://github.com/prettier/prettier/commit/5c6e0802af4b2096a65c432c22209625bd26bc79

#対処方法

ということでそのうち対応されると思うけど、prettierを1.12などにダウンレードするか、暫定的に以下のようにparserを指定するとエラーは消える。

node-modules/vue-loader/lib/template-compiler/index.js:80

```js:index.js
...
code = prettier.format(code, { semi: false, parser:'babylon' })
...
```

わざわざ選択できるようになったparserを固定値にしてしまうのが良いかは議論があるかと思いますし、インストールしたパッケージを上書き修正するわけにはいかないですのでforkするしか無いですが。

pull-requestするならちゃんとオプション値を渡せるようにしたほうがいいと思うしな...。
配列とリンクリストについて

配列とリンクリストの違いについて、それぞれのメリット・デメリットをまとめる:thumbsup:

# 配列
## メリット:angel_tone2:
・**ランダムな値の読み取りが高速**
配列はインデックスを持つので、ランダムな値を検索する時に非常に高速。そのインデックスの要素に飛ぶだけでいい。
その性質のため二分探索などとも相性がいい。

## デメリット:imp:
・**メモリ上の連続したスロットを使用する**
どういう事かと言うと、配列の長さ分の連続したスロットが空いていないとその配列は作成できない。
例えば長さが10の配列を生成する場合、メモリには10個の連続したスロットがないといけない。
（10個のスロットが点々としていたり、離れていたらダメ）

また要素を追加した結果、スロットが足りなくなった場合は
必要な分の連続したスロットが存在する場所に行き配列を作り直す。

・**要素の追加、削除が遅い**
追加や削除がされた要素から、後の要素のインデックスは全て修正する必要がある。
そのため**要素の先頭に追加や削除をした場合、全ての要素のインデックスを再計算することとなる。**
~~情報処理技術者試験の午前問題でよく出てたのはこれ~~


# リンクリスト　~~（基本的に配列と逆の特徴を持つ）~~
## メリット:angel_tone2:
・**リストの要素は、メモリ上のどこにでも配置可能**
配列と違いリストは次の要素へのアドレスを持つ。
そのため次の要素が必ずしも連続したスロットに存在する必要はなく、点々としたスロットに存在することが可能。
また要素が追加されてもリストを再生成する必要はない。

・**要素の追加、削除が高速**
要素の追加や削除がされても、**その前の要素が持つ次要素へのアドレスを修正するのみでいい。**

## デメリット:imp:
・**ランダムな値の読み取りが遅い**
配列と違いインデックスを持たないため、**最初の要素から読み取りたい要素まで順番に検索する必要がある。**
つまり5つ目の要素を読み取りたい場合、1 > 2 > 3 > 4 と次の要素のアドレスを追わなくてはならない。
~~ただしすべての要素を読み取る場合は、配列と性能差はない。~~

# まとめ
【配列】
・ランダムな読み取りが高速。*O(1)*
・要素の追加、削除が遅い。*O(N)*
・メモリ上の連続したスロットが必要。

【リスト】
・ランダムな読み取りが遅い。*O(N)*
・要素の追加、削除が高速。*O(1)*
・メモリ上に連続したスロットは必要なく、要素分の空きスロットがあればいい。
GASで好きな歌詞をSlackにつぶやくBotを作ってみた

#作ったもの
自分の好きな歌詞をスプレッドシートに書いて、それをSlackにつぶやいてくれるBot。
仕事中に見たらテンションあがるかなー、と思って。

#ソース
とりあえずソース。
はじめてGASを触ったので、ほぼ↓の記事を参考に作成しました。
[早く出社した人を早く帰らせてあげるSlackチャネル&botを作った](https://qiita.com/kyogom/items/7d29eb6eb7a288cfd141)

```js:コード
function myFunction(){
  var lyric = getLyric();
  postSlack(lyric);
}

function getLyric() {
  // スプレッドシートを参照し、シートを取得
  var spreadsheet = SpreadsheetApp.openByUrl("スプレッドシートのURL");
  var sheet = spreadsheet.getSheetByName("対象のシート名");  

  // シートの最終行番号を取得
  var lastrow = sheet.getLastRow();
  
  // 最大行までのうち、ランダムで数字を生成
  var randomnum = Math.floor( Math.random() * (lastrow + 1) + 1 ) ;

  // getRangeでセルを取得して、getValueで値を取得
  var artist = sheet.getRange(randomnum, 2).getValue();
  var title = sheet.getRange(randomnum, 3).getValue();
  var lyric = sheet.getRange(randomnum, 4).getValue();
  
  var data = "Artist:" + artist + "\n" + "Title:" + title + "\n" + "Lyric:" + lyric;
  
  return data;
}

function postSlack(data) {
  // プロパティに設定したトークンを取得
  var prop = PropertiesService.getScriptProperties().getProperties();
  var slackApp = SlackApp.create(prop.token);
  var postChannelId = "SlackのチャンネルID";
  var option = {
    username: "投稿するときのユーザー名"
  };

  var response = slackApp.postMessage(postChannelId, data, option);
  Logger.log(response);
}
```

#ポイント
##Slackのトークン取得
API連携するためのトークンを発行する。
[Legacy token generator](https://api.slack.com/custom-integrations/legacy-tokens)

発行したトークンは、GASのプロパティに設定する。
[GASにSlackのtokenを教える](https://qiita.com/kurapy-n/items/9677f7d41cc274044964#gas%E3%81%ABslack%E3%81%AEtoken%E3%82%92%E6%95%99%E3%81%88%E3%82%8B)

##POSTするチャンネルのID
↓で取得することができる。
[channels.list](https://api.slack.com/methods/channels.list/test)

#参考URL
- [Google Apps Script 入門](https://qiita.com/t_imagawa/items/47fc130a419b9be0b447)
- [早く出社した人を早く帰らせてあげるSlackチャネル&botを作った](https://qiita.com/kyogom/items/7d29eb6eb7a288cfd141)
- [初心者がGASでSlack Botをつくってみた](https://tech.camph.net/slack-bot-with-gas/#sub2)
- [GoogleSpreadSheet / GoogleAppsScript のススメ](https://qiita.com/kurapy-n/items/9677f7d41cc274044964)
- [【保存版】初心者向け実務で使えるGoogle Apps Script完全マニュアル](https://tonari-it.com/google-apps-script-manual/)
MongoClient.connect()時にuseNewUrlParserオプションを与える

Node.jsでMongoDBの接続を得るときにこんなエラーが出たときの対処法メモ。

```console
(node:2368) DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.
```

エラーメッセージに従い、`{useNewUrlParser: true}`を第二引数に与える。

```javascript
async connect() {
  if(this.conn) {
    return this.conn;
  } else {
    this.client = await MongoClient.connect(this.url, {useNewUrlParser: true});
    this.conn = this.client.db();
    return this.conn;
  }
}
```

同じこと書いてる人が海外にいた。
https://www.thanhphu.tech/2018/05/23/about-mongos-usenewurlparser-warning/
nkfでCP932←→UTF-8の変換をする

# 入力文字コードを自動判別させる場合

デフォルトではCP932←→UnicodeではなくShift_JIS←→Unicodeの変換をしてしまう。
CP932←→Unicodeの変換をさせるには`--cp932`オプションを指定すれば良い。

```
# CP932 → UTF-8
$ nkf -w --cp932 cp932.txt > utf8.txt

# UTF-8 → CP932
$ nkf -s --cp932 utf8.txt > cp932.txt
```

ただしこの`--cp932`は`man nkf`に説明が書いていない。

# 入力文字コードを明示的に指定する場合

```
# CP932 → UTF-8
nkf --ic=CP932 --oc=UTF-8 cp932.txt > utf8.txt

# UTF-8 → CP932
nkf --ic=UTF-8 --oc=CP932 utf8.txt > cp932.txt
```

# 参考：cp932からunicodeへ変換した場合に異なる文字

```
          CP932→Unicode     Shift_JIS→Unicode
0x8160    ～    U+FF5E      〜    U+301C
0x8161    ∥    U+2225      ‖    U+2016
0x817C    －    U+FF0D      −    U+2212
0x8191    ￠    U+FFE0      ¢    U+00A2
0x8192    ￡    U+FFE1      £    U+00A3
0x81CA    ￢    U+FFE2      ¬    U+00AC
```
https://sites.google.com/site/fudist/Home/vim-nihongo-ban/mojibake/utf8-cp932conv
Pandas データフレーム。欠損値とinteger型。Chi-square。

本日学んだことをメモ。

・Pandasのデータフレームの数値型の列に欠損値があると、その列は自動的にfloatになってしまう。Astypeでキャストを試みても、Round関数で四捨五入使用としても、Integerにしようとするとエラーが帰ってくる。「Nanはintegerにできない。」と。不便。
結局Str型に変更して、strの編集をする方針とした。

・pandasの列への関数の適応方法については、理解できていない。あとで整理する。

・pythonのScypiよりもRのChi-squareの方が欠損に関し、エラーが出ずらい（堅牢）だと考え、pandas dataframeをRのdataframeに変更しようと試みたが、できず。rpy2はバージョンの違いなのかうまくいかず。pypeRではやり方自体発見できず。Rのコードに慣れていれば、pypeRを使用し、リストを渡してRのベクトルにして、データフレームを作れば良いのだろうが、、、結局、Try exception構文を利用し、pythonのChi-squareのエラーを補足して、対応することとした。

pandas integerとNan
https://stackoverflow.com/questions/21287624/convert-pandas-column-containing-nans-to-dtype-int

Rとpythonのデータフレームの受け渡し
http://sinhrks.hatenablog.com/entry/2014/10/16/224948

pandasの列への関数の適応方法について
https://note.nkmk.me/python-pandas-map-applymap-apply/
各言語の環境構築と簡易確認と腕試し

#はじめに
最近よく使う言語の環境構築やさっと動作確認する方法をざっくりとまとめています。
とにかくちょっと試したいならば、『Ideone』(イデオン)「[Ideone.com - Online Compiler and IDE >> C/C++, Java, PHP, Python, Perl and 40+ other compilers and interpreters](https://ideone.com/)」辺りがすごいですし、それで十分かもしれません。

#開発環境
色々インストールしたくない場合、Docker（ドッカー）なりを入れて、各種環境のイメージを入れるという手もあるかもしれません。
コマンドラインレベルでちょっとコードを確認したい場合などは、意外とこの方が早いのかもです。
（参考）
[Dockerインストールメモ - Qiita](https://qiita.com/n-yamanaka/items/ddb18943f5e43ca5ac2e)

##全般
個人的好みは『Visual Studio Code』
[Download Visual Studio Code - Mac, Linux, Windows](https://code.visualstudio.com/download)

##C# 
とりあえず『Visual Studio Community 2017』で
[ダウンロード | IDE、Code、Team Foundation Server | Visual Studio](https://www.visualstudio.com/ja/downloads/)

## Java, Scala
とりあえず『IntelliJ IDEA Community』で
[Download IntelliJ IDEA: The Java IDE for Professional Developers by JetBrains](https://www.jetbrains.com/idea/download/#section=windows)

##Python
（参考）
[Python3のインストール - python.jp](https://www.python.jp/install/windows/install_py3.html)

##PHP
（参考）
[PHPのダウンロードとインストール | PHPインストールと初期設定](https://www.phpbook.jp/tutorial/install/index1.html)

#簡易確認
##全般
（参考）
[ブラウザー上でサクッとコードの動作テストができるWebサイトいろいろ | Webクリエイターボックス](https://www.webcreatorbox.com/webinfo/code-playgrounds)

##C# 
『Visual Studio Community 2017』なりで適当にプロジェクトを作ってで

##Java, Scala
『IntelliJ IDEA Community』 なりで適当にプロジェクトを作ってで

##JavaScript
ちょっと使っていたのは『JSFiddle』
[Create a new fiddle - JSFiddle](https://jsfiddle.net/)

##python
そのままコンソールでやってた・・・
`python`

##PHP
そのままコンソールでやってた・・・
`php -a`

#腕試し
（参考）
[ITエンジニアのレベルアップに最適！競技プログラミングサイト10選 - paiza開発日誌](https://paiza.hatenablog.com/entry/2015/04/16/IT%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E3%83%AC%E3%83%99%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E3%81%AB%E6%9C%80%E9%81%A9%EF%BC%81%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9)

以前はCodeIQとかもあったけど、サービス終わったようなので。
日本語ならとりあえず『AtCoder』とか？
[AtCoder](http://atcoder.jp/)


以上。
Linux: プロセスが起動して終了するまでの最大メモリ使用量を調べる

# やりたいこと

ピークメモリ使用量、つまりプロセスが実行中に一番メモリを使っていた時点での使用量を調べたい。

## 現在起動中のプロセスを調べる方法（/procを利用）

`grep 'Peak' /proc/$PID/status` コマンドを実行。

例：

```console
$ grep 'Peak' /proc/409/status
VmPeak:	  216940 kB
```

## プロセス起動前に指定する方法（timeコマンドを利用）

`/usr/bin/time -v`を使って`Maximum resident set size`のところを見れば良い。

`/usr/bin/time`は

- CentOSなら`yum install time`
- Arch Linuxなら`pacman -S time`

でインストールできる。

例えば`du -h`のメモリ使用量を調べたい場合は次のようにする。

```console
$ /usr/bin/time -v du -h > /dev/null
        Command being timed: "du -h"
        User time (seconds): 0.02
        System time (seconds): 0.08
        Percent of CPU this job got: 98%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.12
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 2236
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 0
        Minor (reclaiming a frame) page faults: 130
        Voluntary context switches: 1
        Involuntary context switches: 37
        Swaps: 0
        File system inputs: 0
        File system outputs: 0
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0
```

`Maximum resident set size (kbytes): 2236` なのでピークメモリ使用量は約2MiBだったと分かる。

# See Also

https://stackoverflow.com/questions/774556/peak-memory-usage-of-a-linux-unix-process
UVMでの正規表現


テストプログラムを作成していると、正規表現での文字列マッチングの機能が欲しくなることがあります。残念ながらSystem Verilogはその機能を提供していませんが、UVMにはサポートがあります。ここではその使用方法と注意点を説明します。

#使い方

```verilog
function int uvm_re_match(string re, string str);
```

reが正規表現、strがマッチングの対象となる文字列です。ちょっと注意が必要なのが戻り値で、マッチした場合に0 それ以外の場合に非0のエラーコードを返します。本メソッドの内部ではDPI経由でCの正規表現ライブラリのregcomp()/regexec()を呼び出しており、この関数の作法に従っているためです。Cの標準関数では、多くの場合成功の場合0、それ以外の場合は非0のエラーコードを返すのが通例になっています。

サンプルプログラムとその実行結果を以下に示します。

サンプルプログラム:

```verilog
import uvm_pkg::*;
`include "uvm_macros.svh"

program top();
  initial begin
    string orig[$] = {"fizz",
                      "buzz",
                      "fizz buzz"};
    string sel[$];

    `uvm_info("", "==== All Items ====", UVM_NONE);
    foreach (orig[i]) begin
      `uvm_info("", orig[i], UVM_NONE);
    end

    sel = orig.find with (!uvm_re_match("^f.*z$", item));
    `uvm_info("", "==== Selected Items ====", UVM_NONE);
    foreach (sel[i]) begin
      `uvm_info("", sel[i], UVM_NONE);
    end   
    
  end
endprogram
```

実行結果:

```plaintext
UVM_INFO testbench.sv(11) @ 0: reporter [] ==== All Items ====
UVM_INFO testbench.sv(13) @ 0: reporter [] fizz
UVM_INFO testbench.sv(13) @ 0: reporter [] buzz
UVM_INFO testbench.sv(13) @ 0: reporter [] fizz buzz
UVM_INFO testbench.sv(17) @ 0: reporter [] ==== Selected Items ====
UVM_INFO testbench.sv(19) @ 0: reporter [] fizz
UVM_INFO testbench.sv(19) @ 0: reporter [] fizz buzz
```

用途の一例としては、名前が特定の法則に合致するレジスタクラスのオブジェクトのリストを取得するのに使えます。以下はmy_uvm_reg_mapに登録されているレジスタクラスのオブジェクトのうち、名前がMPUで始まる全てのハンドルを取得してmirror()するコードです。

```verilog
uvm_reg all_regs[$];
uvm_reg selected_regs[$];

my_uvm_reg_map.get_registers(all_regs);
selected_regs = all_regs.find with (!uvm_re_match("^MPU_", item.get_name()));
foreach(selected_regs[i]) begin
  selected_regs[i].mirror();
end
```


#注意点
上記の通り、正規表現の取り扱いはSystem Verilogやシミュレータが行っているのではなく、DPIでリンクされているCのライブラリが行っています。正規表現にはさまざまな拡張表現がありますが、それらを使用すると同じシミュレータを使用していても、異なるライブラリがリンクされた場合に互換性の問題が発生する可能性があります。

また、コンパイル時にdefineでUVM_NO_DPIを定義した場合、DPIが使用されず、代わりにSystem Verilogの同名メソッドが使用されます。uvm_re_matchメソッドもDPI経由ではなく、純粋なSystem Verilogのメソッドに置き換えられます。ただしこのメソッドではマッチング文字列が正規表現ではなく、globとして解釈されます。本defineの有無で動作が変わりますので、この点にもご注意ください。

#リファレンス
本メソッドはドキュメント化されていません。UVM_Class_ReferenceManualのuvm_resource_baseの説明で少し名前が出ている程度です。

dpi/uvm_regex.ccが本メソッドのソースコードとなりますのでそちらを参照ください。dpi/uvm_regex.svhというファイルもありますが、こちらはDPIを使用しない場合に適用される純粋なSystem Verilogのメソッドとなっています。UVM_NO_DPIをdefineしてコンパイルした場合はこちらが使用されます。
Introducting TensorFlow Probability 要約

以下の記事の要約です。

[Introducting TensorFlow Probability](https://medium.com/tensorflow/introducing-tensorflow-probability-dca4c304e245)

2018 TensorFlow Developer Summit で TensorFlow Probability (確率的プログラミングのツールボックス) が発表されました。

TensorFlow Probability を使くべき場面:

- 生成モデルを作り潜在プロセスを推論したいとき
- 不確実性を評価したいとき
- データ点の数と比べて多数の特徴量を持つとき
- データが構造化されているとき (例：グループ、空間、グラフ、language semantics)  そしてこの構造を事前知識として使いたいとき
- 逆問題を解くとき (注：Deep Learning でない)

これらを CPU, GPU, TPU どれを使っても実行できます。

## TensorFlow Probability の構成要素

1. Layer 0: TensorFlow  
2. Layer 1: Statistical Building Blocks  
  - Distributions
  - Bijectors (変数変換するときに使う)
3. Layer 2: Model Building  
  - Edward2 (`tfp.edward2`)
  - Probablistic Layers (`tfp.layers`)
    Neural network のレイヤー
  - Trainable Distributions (`tfp.trainable_distributions`)  
  1 つの Tensor でパラメタライズされた確率分布。これは確率分布を出力とする Neural Network を作ることを容易にします。
4. Layer 3: Probablistic Inference
  - MCMC
  - 変分推論
  - Optimizers
  - Monte Carlo (注：MCMC でなく)

## コード例

(注：以下の IPython Notebooks が参考になります。Python 2 系のコードなので注意)
[examples/jupyter_notebooks](https://github.com/tensorflow/probability/tree/master/tensorflow_probability/examples/jupyter_notebooks)

- Linear Mixed Effects Models (階層線形モデル)
- Gaussian Copula (ガウシアン コピュラ)
- Variational Autoencoder (変分AE)
- Bayesian neural Networks
AngularJSのdateフィルタで date string がパースできない問題

# なにがしたい？

AngularJS に備わっている date フィルタ。

```:IN
{{ date_to_show | date:'y年M月d日' }}
```

```:OUT
2018年6月2日
```

日付や時刻（タイムスタンプ）をあらゆる書式に手軽に変換できてとても便利なのですが、これ、**date_to_showがDateオブジェクトじゃないとダメ**という制約があります。つまり事前にこうしておかないとダメ。

```javascript
date_string = '2018-06-02';
date_to_show = new Date( date_string );
```

いわゆる date string (日付書式の文字列）を与えたらどうなるか？

```:IN
{{ date_string | date:'y年M月d日' }}
```

```:OUT
2018-06-02
```

dateフィルタはうまく扱えず、何も言わずにそのまんま出てきます。これは不便。日付だけ事前にJSで```new Date```しないとダメ？ なんとかフィルタだけで解決したい。**Googleさん助けて！**と思ったのに、Googleさんが助けてくれなかったので、僭越ながら穴埋め係させていただきます…。

# 結論

## new Date するフィルタを定義

```javascript
app.filter('parsedate', [
  function() {
    return function(date_string) {
      return new Date(date_string);
    };
  }
]);
```

こんなものを作っておいて、かまします。

```:IN
{{ date_string | parsedate | date:'y年M月d日' }}
```

```:OUT
2018年6月2日
```

Googleさんたちに聞いてまわったところ、フィルタを作るところまでは教えてくれたのですが、そのフィルタで書式の変更までしていたので、いや書式の変更は既存のdateフィルタに任せるとかできないのかなと思ったけど、できちゃいました、というお話でした。

## Coffeeでの適用例

app は対象の controller でも大丈夫です。また、お世話になっているプロジェクトだと CoffeeScript なので、こんな感じ。~~上記JSでもそうですが、引き渡す関数が **配列** なのがささやかなハマりポイントです。~~ 

```coffeescript
mainControllers.filter 'parsedate', [() ->
    ( date_string ) ->
      new Date date_string
  ]
```

**追記** すみません。配列じゃなくても大丈夫でした。

```coffeescript
mainControllers.filter 'parsedate', () ->
    ( date_string ) ->
      new Date date_string
```
Android Support LibraryのAPI Level 27でListViewCompat削除

Android Support Libraryのandroid.support.v7.widget.ListViewCompatがAPI Level 27（compileSdkVersion 27）から削除されました。

ListViewCompat自体は[android.support.v4.widget.ListViewCompat](https://developer.android.com/reference/android/support/v4/widget/ListViewCompat)として残っていますが。

なぜListViewComaptを利用していのか記憶がありませんが、ListView+ActionModeで利用していた関係でListViewCompatを利用していたのか…。minSdkVersionは14（Android OS 4.0以上）としています。

とりあえず、普通にListViewの利用に切り替えることでビルドは通ります。
スキルアップ目的：「等加速度運動（加速度を計算）」

参考にさせて頂きました。
https://keisan.casio.jp/exec/system/1161228700
作成物。
https://jsfiddle.net/ghost7492/ungkxyow/

htmlを大まかなところ、から、細かなところへと
書くように心がけた。
classやidは後で降ったり。
ただ、あまり効果は実感できない。
その都度、降るのがいいのか？

jsは、
グローバル変数を無くし、関数内に閉じ込めるようにした。
しかし、関数が膨らんでしまった。
後は、関数をできるだけgetで始まるようにしてみた。
次からは、試しに関数を使わず、書いてみようかな。
関数の必要性を感じられるかもしれない。関数とは、何なのか？

実装方法を今までとは少し変えたので、少し時間がかかりすぎた。
ただ、作り方を変えるのは、例えgoodな効果が得られなくても、面白い気がする。
ArrayListを効率的に使う3つのポイント

よく使うListの実装クラスはやっぱりArrayList。
せっかく使うなら効率的に使いましょうということで押さえておくべきポイントを3つ紹介します。

# 基本となる考え
ArrayListは可変長な配列を実現するためのクラスです。
内部で配列を使って実装されていますが、通常の配列は固定長です。
では、どのようにして可変長を実現しているかというと、最初に用意した配列が足りなくなったらより大きいサイズの配列を新しく作り、そこにデータをコピーするということをしています。
また、途中にデータを挿入する場合、後続の要素をすべてコピーしてずらすという処理を行っています。
配列のサイズが大きくなってくると、このような配列の再生成やコピーする処理が非常に遅くなるのでArrayListを効率的に使うためにはこのような処理の発生を防ぐことが重要です。

# 3つのポイント
## 初期サイズの設定
ArrayListのコンストラクタでは初期サイズを指定することができます。
指定した初期サイズで最初に配列が生成されるため、そのサイズを超えるまでは配列の再生成が発生しなくなります。

例えば、要素の数が多くても100個というときは以下のようにすることで初期容量100でArrayListを生成します。

```java
List<String> list = new ArrayList<String>(100);
```

## ensureCapacity
ensureCapacityはArrayListのサイズを確保するメソッドです。
コンストラクタで指定した初期サイズを大きく超えそうなときに使います。
例えば、初期サイズ100で初期化したArrayListに1000個要素を追加する場合、普通に1000回addすると途中で何度か再生成が発生する可能性がありますが、ensureCapacityであらかじめ1000にサイズを拡張しておけば1回だけですみます。

## trimToSize
trimToSizeはArrayListのサイズを現在の要素数で切り詰めるメソッドです。
例えば、初期サイズ1000で初期化したArrayListに100個だけしか要素が入らない場合、900個分の領域が無駄になるので切り詰めることでその領域を解放します。
もちろん、サイズが小さくなるのでそのあとに要素を追加しようとすると配列の再確保が発生します。
そのため、それ以降の処理で要素を追加しないような場合に使うとよいでしょう。
laraveleのEloquentでテーブルを明示的に定義する（使用するテーブルを変更）

## 説明
laravelのEloquentにおいて、モデル作成時にテーブルを明示的に記すことでモデルと結びつくテーブルを自由に設定できます。

## テーブル名を指定しない場合
Testモデルにどのテーブルを使用するか、Eloquentに指定していません。他の名前を明示的に指定しない限り、クラス名を複数形の「スネークケース」にしたものが、テーブル名として使用されます。今回の例で、EloquentはFlightモデルをtestsテーブルに保存します。

```
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Test extends Model
{
    //
}
```

## テーブル名を指定
モデルのtableプロパティを定義し、カスタムテーブル名を指定することもできます。
以下の場合`my_homes`というテーブルがモデルと結びついた設定になります。

```
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
    /**
     * モデルと関連しているテーブル
     *
     * @var string
     */
    protected $table = 'my_homes';
}
```

## 参考
https://readouble.com/laravel/5.3/ja/eloquent.html
laravelでテーブルの主キーをid以外にしたい場合

## 説明
Eloquentは更にテーブルの主キーがidというカラム名であると想定しています。そのためidをオーバーライドする場合はprimaryKeyプロパティを明示的に定義しないといけません。

```:Eloquentoとは
Eloquentとはデータベースとモデルをシンプルに美しく対応づけることができる機能です。
モデルやコントローラに記述します。データベースやテーブル自体に関する設定はモデルに記述します。レコードの出し入れに関してはコントローラに記述します。
```

```:オーバーライドとは
親クラスのメソッドを子クラスで上書きすること
```
## 方法
このように書くことで`id`以外の主キーを定義できます。

```
class Hoge extends Piyo {

    protected $primaryKey = 'test_id';

}
```

## 参照
【Eloquentoについて】
http://laraweb.net/knowledge/748/
https://readouble.com/laravel/5.4/ja/eloquent.html
【オーバーライドについて】
http://wa3.i-3-i.info/word138.html
機械学習論文読みメモ_126


[Meta Learning Shared Hierarchies](https://arxiv.org/abs/1710.09767)
階層的のpolicy構造を学習するためのmeta-learning手法を提案する。
この時に様々なタスクに共通して用いられるpolicyを共有して使う条件を加える事でsample efficiencyを改善した。
この事実は一般的な強化学習の最適化手法を用いる事で実験的に示せた

[Progressive Growing of GANs for Improved Quality, Stability, and Variation](https://arxiv.org/abs/1710.10196)
GANの新たな学習手法を提案する。
提案手法では、generatorとdiscriminatorを学習の過程で順々に大きくしていく。
つまり、最小は低解像度の画像を用いてGANを学習し、その学習されたモデルに対し
高解像度化を行う層を追加し、それに合わせた解像度の画像を用いてモデルを学習していく。
このプロセスを経る事で学習を高速化し、さらに安定させる事も出来る。
結果高解像度の画像に対するGANで高性能な結果を出す事が出来た。

[Distributed Prioritized Experience Replay](https://arxiv.org/abs/1803.00933)
分散型の強化学習を考える。
この枠組みでは大きなスケーラビリティの改善が見込める。
提案手法ではactorをlearningから切り離す。
actorは共有されたネットワークを利用し与えられた環境とやり取りをする。
そして得られた経験は共有されたexperience replay memoryへスタックされる。
この構造ではprioritized experience replayを用いる事で重要なデータに集中を行う。
ツイッターで2つ以上のホームページを設定する方法

# Twitterで2つ以上のホームページを設定する
ツイッターアカウントを持つとホームページの設定がひとつしかできないことに気づきます。
ツイッターを活用する上では１テーマ　１アカウントがいいと思うので、複数のアカウントを運用しているのですが、ここでこまるのはホームページの設定です。
オフィシャル感のでるブログやプラットフォーム系を一つ、理論のまとめとして、はてなブログを更に持っていてさらに、ワードプレスでも作成しているので、どうしても複数のホームページを載せたくなります。
こうやってのせることで、自分自身も管理しやすいですし、フォローしているファンの方も簡単にいろんな情報を探せるので便利かと思います。それを解決する方法は自己紹介文にリンクを貼ることです。

## 複数ホームページは自己紹介文に短いリンクにして貼り付けよ
ホームページをたくさん貼るわけですから、なるべく短いリンクを貼り付けることが求められています。近々グーグルのショートカットリンクが終了するらしいですが、ひとつの回答がありますのでこちらを確認ください。
英語ですね。
[ツイッターホームページ複数設定](https://www.quora.com/How-can-I-include-two-URLs-on-my-Twitter-profile)
Quoraをみて調べることができました。まさに海外の情報を英語ベースで習得できたことがいい流れを持ってきたのだと思います。

こちらがURLを短くする方法です。このサイトを使うといいですよ。
[リンクを短くする方法](https://bitly.com/)
とりあえずしばらくはこの組み合わせで取り組んでいきましょう。
スキルアップ目的：「回転速度」

参考サイト
https://keisan.casio.jp/exec/system/1305265056
出来上がったもの
https://jsfiddle.net/ghost7492/jsjyrngt/

参考サイトに公式が記載されていることに気が付き、
それをそのまま、関数にすれば早いことに気がついた。
なぜ、その公式になるのかは、ひとまず、考えないようにしてみる。

よく、普段の仕事でも、作業手順を最後の方から考えることがあるが、
プログラミングでもそれが生かせそう。

今回の場合でいえば、最終的に答えを画面上に書き出したいので、
書き出す、
そのためには、答えを計算しなければならない、
そのためには、ユーザの入力値を取得しなければならない、
みたいな感じ。
これを大枠として、それらに付随する単位変換とかは、
必要に応じて作っている、「小物系」と言えるか。


どれだけ、頭の中で論理的にブロックを積み上げられるかがポイントかな。
FOR文の向きを意識する必要性

皆様初めまして。
タイトルの通り、繰り返し処理の方向を考えないと
ハマる（何が悪いか分からない）と言う話しです。

コンパイルは通るけど動作がおかしい！と
3,4時間苦悩してました。

DXライブラリを一部使っているので軽く説明を交えながら。
（全部載せると無駄も長いので一部）
以下問題のソース↓
                                                                        
```c++:bad.cpp
while(1){
       if (CheckHitKey(KEY_INPUT_DOWN) == 1) {
			count++;
			if (count % 5 == 0) {
				for (i = 0; i < 20; i++) {
					for (j = 0; j < 10; j++) {
						if (masu[i][j] == 1 && masu[i+1][j] == 0) {
							masu[i + 1][j] = 1;
							masu[i][j] = 0;
						}
					}
				}
			}
		}
        if (CheckHitKey(KEY_INPUT_UP) == 1) {
			count++;
			if (count % 5 == 0) {
				for (i = 0; i < 20; i++) {
					for (j = 0; j < 10; j++) {
						if (masu[i][j] == 1 && masu[i - 1][j] == 0) {
							masu[i - 1][j] = 1;
							masu[i][j] = 0;
						}
					}
				}
			}
		}
		if (CheckHitKey(KEY_INPUT_RIGHT) == 1) {
			count++;
			if (count % 5 == 0) {
				for (i = 0; i < 20; i++) {
					for (j = 0; j < 10; j++) {
						if (masu[i][j] == 1 && masu[i][j+1] == 0) {
							masu[i][j+1] = 1;
							masu[i][j] = 0;
						}
					}
				}
			}
		}
		if (CheckHitKey(KEY_INPUT_LEFT) == 1) {
			count++;
			if (count % 5 == 0) {
				for (i = 0; i < 20; i++) {
					for (j = 0; j < 10; j++) {
						if (masu[i][j] == 1 && masu[i][j-1] == 0) {
							masu[i][j-1] = 1;
							masu[i][j] = 0;
						}
					}
				}
			}
		}
}
```

上下左右キーで配列内の数値を入れ替える物で、
上から各キーが押されたら、カウントする変数に加算し、
一定時間押されたら自分（この場合0)を全配列から探し、
0が見つかったら移動先が移動できる条件(この場合0)
なら、移動先と現在の数値を入れ替えるというもの。

ぱっと見は違和感がない。（最初は自分の配列の上下左右を入れ替えればいいと思ってたため向きなどを考えてなかった）
だが　実行してみると上キーと左キーは動くのだけれども
下キーは一回押したら現在の位置から真下に
右にいたっては右下に必ずいってしまう。

考えていたら、ある事に気が付いた。
```masu[i][j+1] = 1;```
```masu[i+1][j] = 1;```
右キーと下キーのどちらも、現在の配列より+で移動先に入れていた。
そこから繰り返し処理の流れ（方向)と現在の配列より一歩先を変更する処理が重なり、ぶっとんだ移動のしかたをしているのではと予測した。

イメージ　↓














![a.png](https://qiita-image-store.s3.amazonaws.com/0/261256/5ce6d01a-5831-718f-bd0b-676289e7de21.png)


これを回避するためには、
Iの向きとJの向きを変えてやれば、解決する。
具体的には右と下に行きたいときは、データの入れ替えと逆にしてやれば解決する。

イメージ2　↓


![image.png](https://qiita-image-store.s3.amazonaws.com/0/261256/872592b6-06e9-a050-a73b-7522ce05563c.png)

以上のことを踏まえて直すと右キーと下キーはこうなる。


```c++:good.cpp
    if (CheckHitKey(KEY_INPUT_DOWN) == 1) {
			count++;
			if (count % 5 == 0) {
				for (i = 20; i >= 0 ; i--) {
					for (j = 10; j >= 0; j--) {
						if (masu[i][j] == 1 && masu[i+1][j] == 0) {
							masu[i + 1][j] = 1;
							masu[i][j] = 0;
					    }
					}
				 }
			 }
    }
    if (CheckHitKey(KEY_INPUT_RIGHT) == 1) {
			count++;
			if (count % 5 == 0) {
				for (i = 20; i >= 0; i--) {
					for (j = 10; j >= 0; j--) {
						if (masu[i][j] == 1 && masu[i][j+1] == 0) {
							masu[i][j+1] = 1;
							masu[i][j] = 0;
						}
					}
				 }
			 }
     }
```

これで上下左右すっきり移動することができました。
このように注意しないとどこかではまるかもしれません。
（そもそもこんな考えのもの使う機会がない)


【まとめとか感想】

画像とか後半しんどくなって適当になってきた。

この記事書くのに初めてとはいえ
一時間半かかっているので
いいねください。
Bashシェルのhistoryの保存件数を増やす

# 概要

Bashシェルでhistoryコマンドを実行すると、ユーザーのコマンドの実行履歴が表示される。
その際の履歴の表示件数（履歴の保存件数）を変更する。

```
$ history
  1  ll
  2  cd -
  ...
  500   history
```

historyコマンドの実行結果はこんな感じ。
macだと、デフォルトで500件保存される模様。linuxだと1000件らしい。ディストリビューションにもよるかと思われる。
いずれにせよ、忘れたコマンドを呼び出したりするには少々心もとない。

# 環境

- macOS Sierra 10.12.6

# 手順

今回は保存件数を100000件にしてみる。

1. ~/.bashrcにHISTSIZE=100000を追記する

```
$ echo "HISTSIZE=100000" >> ~/.bashrc
```

これで保存件数が変更される。
Xcodeでbits/stdc++.hをインクルードする

XcodeでC++を書いていて、`#include <bits/stdc++.h>`を使ったら`'bits/stdc++.h' file not found`というエラーが出て、意外と詰まったので解決法を載せときます。私のようにターミナルの扱いにも慣れていない方向けに丁寧めに書きました。
未熟者なのでもっと良い方法あったら教えてください。
#bits/stdc++.hとは
これはC++の標準ライブラリを一括でインクルードできるヘッダーファイルです。

```
#include <bits/stdc++.h>
```
と初めに書いておくだけで標準ライブラリが全て使えるようになります。
特に競技プログラミングではかなり便利です。

#1. stdc++.hのダウンロード
ここから`stdc++.h`をダウンロードします。
[https://gist.github.com/reza-ryte-club/97c39f35dab0c45a5d924dd9e50c445f](https://gist.github.com/reza-ryte-club/97c39f35dab0c45a5d924dd9e50c445f)

#2. Xcodeのincludeフォルダに置く
あとはXcodeの標準ライブラリがあるフォルダに置くだけなのですがパーミッションやらのエラー対策も合わせて説明します。

まずターミナルでbitsフォルダを以下のディレクトリに作ります。

`/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1`

```
cd /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1

mkdir bits
```

この時、`Permission denied`と出てしまった場合はsudoを付けましょう。

```
sudo mkdir bits
```

そしてダウンロードした`stdc++.h`をここに移動します。
`stdc++.h`が置いてあるフォルダに移動し、以下のコマンドを実行します。

```
mv stdc++.h /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/bits
```

これでXcodeで`#include <bits/stdc++.h>`を使ってもエラーが出ないようになりました。

#参考
[How can i include <bits/stdc++> in xcode](
https://stackoverflow.com/questions/28994148/how-can-i-include-bits-stdc-in-xcode?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa)

[もうPermission deniedなんて怖くない！〜linuxのパーミッションについてかなり丁寧に説明してみる〜](http://karoten512.hatenablog.com/entry/2017/12/23/021821)
ProofGeneral と ssreflect のインストール

# はじめに

coqide + ssreflect のインストール方法は調べても分からなかったので、ProofGeneral を選択。
ssreflect は opam でもインンストールできて ProofGeneral との連携もできると思うが、そもそも ProofGeneral との連携方法が分かっていない時にインストールしたので、実際にはチャレンジしていない。

# インストール成功手順

- homebrewでcoqをイントール

- math-comp-mathcomp-1.7.0のソースを落として来て、INSTALL.md 通りにインストール

```
	展開して、coqcのパスがあることを確認して、mathcompに移動。make
```

- ProofGeneral を Quick installation とおりにインストール

```
	git clone https://github.com/ProofGeneral/PG ~/.emacs.d/lisp/PG
	cd ~/.emacs.d/lisp/PG
	make
```
	
- .emacsに以下を記入

```
	;; Open .v files with Proof General's Coq mode
	(load-file "~/.emacs.d/lisp/PG/generic/proof-site.el")
	(load-file "/Users/hogehoge/math-comp-mathcomp-1.7.0/mathcomp/ssreflect/pg-ssr.el")
	(setq coq-prog-name "/usr/local/bin/coqtop")
```

- ソースコード(0529.v)と同一ディレクトリに _CoqProject ファイルを作成し中身に以下を記入

````
	-R "/Users/hogehoge/math-comp-mathcomp-1.7.0/mathcom" mathcomp
````

- ソースコード上に From mathcomp の記述があるとだめなようなので、以下のみ記述

```
	Require Import ssreflect.
```

以上
ソース中に変更履歴をコメントで残すことについて考えてみた

# この問題を考えてみようとした背景
私が所属する組織にはソースを修正する場合には古いソースをコメントアウトし、
修正日付、修正内容（Redmineのチケット番号）の改定履歴をコメントで入れる
暗黙のルールがある、私が知っている限り社内のプロジェクトは全てこのルール
で運用されている。

今日若手でご飯を食べに行ったときに

***コメント入れないでソースのいらない行削除したら注意されたのだけど。
Subversionで履歴管理してるのにソース中に残す必要があるのかね。***

という話になった、私は残す必要ないと思っていると解答して、その場はみんなで、だよねーとなって
会話が終わってしまったのだが、残すメリットと残さないメリットを改めて考えてみようと思った。

# コメントを残しておくといいこと

Subversionに凄い勢いでコミットしてしかも毎回同じコメントを入れる人がいると
障害番号ｘｘｘｘの修正
でコミット履歴が埋めつくされる。
一個ずつ見てくの凄いめんどくさいのでgrepしたほうが早いときがある。

障害番号ｘｘｘｘ、ｘｘｘｘ、ｘｘｘｘの修正と関連性のない修正を一気にコミットしたときに
どの修正がどのチケット番号のかよくわからないことがある。そんな時ソースを障害番号でgrep
したら修正箇所がわかる。

※私のプロジェクトで実際に起こっていてあってよかったと思ったことを書いてみた。
　このようなことをすること事態を防げばよいのだが。

# コメントを残さないといいこと

ソースの８割コメントアウトなんてソースがある、コメントアウトされていない箇所を探
すのが大変、ていうか汚い。


# まとめ

改めて考えてみるとなかなか思いつかないが、残しておくといいことは運用で防げる
ので残さなくてもいいんじゃないかなと思った。
2018/05/30 AWS Summit Tokyo

# Amazon Aurora under the hood
## 講演概要
* AuroraをAWS側のプロダクト担当より技術的な、実はここまでやってます的な、説明
* Auroraの使用ストーリーよりも内部のアーキテクチャにフォーカスした説明
* ターゲットはAuroraをすでに知っていてより深くの技術まで知りたい人向け
* 40分の講演だが、かなり内容は盛りだくさんで早口

## Aurora概要
#### テーマ：RDBをもう一度考える（今DBを再実装するとどうなるか？）
 * スタックの分割
 * 以下を実装
     * ディスクの自動スケールアウト10GB~64TB
     * セルフヒーリング
     * 分散サービスの活用
 
### 特徴：Amazonがクラウド時代に再設計したDB
* スケーラビリティ
 * フルマネージドサービス
 * SOAアーキテクチャ
      * 過去からあるRDBの大半はモニシリックなサービス 
      * ログはS3、監視はCloudWatch、、、などのようにAWSのサービスを個々に使用するシステム構成としてる
 * キャッシュレイヤの分割
     * データベースとは別プロセスで管理されるためデータベース障害時にも最新の状態を保持可能
 * cluster volumeは3AZに6CPされる
 * Auroraエンドポイント
 * auroraストレージ
      * スケールアウト可能な分散ストレージ
      * 3AZに6つにデータCPされる
      * 継続的にS3へバックアップを行う
* セキュリティ
 * SSL接続
 * VPCでネットワーク分割
 * ノードへは直接接続不可能

## Aurora under the hood
* 分散ストレージ
 * マスタへの更新を複数のスタンバイへの転送しレプリケーション
     * 同期レプリ(Aurora)→レイテンシ低下の恐れ
         * RDS:マスタノード→EBS→EBSミラー→レプリカノード→EBS→EBSミラー
         * Aurora:3AZ6つのディスクへAckを送り、Rは3つ、CUDは4つから応答があれば完了とみなす。
     * 非同期レプリ→データロストの可能性
* クォーラムモデル
 * レプリケーション管理のためのルール
     * Vr+Vw > V
     * Vw > V/2
  * 2つのCPに障害が発生してもRead, Write可能
  * 3つのCPに障害が発生してもRead可能
  * 自動修復されていく
* なぜ6つのCPが必要なのか？（4/6クォーラム）
 * AWSは大規模環境、AZ障害は障害が広域
 * AZ+1の二重障害を考慮して修復の必要（AZ障害時に他の障害が発生すると2/3クォーラムではダウンしてしまう）
 * よって3AZに6CPが必要
* MTTRの短縮
 * Auroraは10GBセグメントで論理ブロックを構成（プロテクショングループ）→正確にはこれを6CPしている
 * いいところ
     * フォールトトレランスでパッチ適用に影響を及ぼさない
     * メンバーシップ（6つのCPの組み合わせ）の入れ替えができる
     * 1ノードに異常が検知されると健全なノードと代わりの新ノードでコォーラムグループが新規に構成され、交換が必要だと認識されると新クォーラムに切り替わる
 * 長時間のAZ障害のために3/4コォーラムに切り替えることもできる（AWS側の運用）
* 一般的なコォーラムシステムの課題
 * RWコスト、ネットワーク負荷が高くなる傾向にある
     * AuroraはSQL発行の同期通信ではログレコードのみストレージに送信されるためネットワーク負荷は最小
     * データページは読み込まず、別プロセスで非同期で行っている
  * Auroraはどのノードが最新でレイテンシが少ないかの情報を持っている→各ブロックの最低4つは最新のデータを保持している（4/6コォーラムを形成しているため）
* コスト工夫
 * 6つのコピーが必要だが物理ストレージとして必要なのは実際に6つコピーするのと比較し3倍くらい

# まとめ
* Amazonがクラウド時代に再設計したDB
* AWSのサービスを内側の技術として使用している
* アーキテクチャはフォールトトレランスの考えを元に堅牢に構築されている

# 所感
* 障害時の動作として、内部アーキテクチャではあるが正しく理解することは重要なため非常にためになった
* 以前学習したが忘れてしまっている用語や概念があったので合わせて再度学び直すことができた
* AWSにサービスとはいえ、DBを作ってしまうAWSの技術力に感心した。。。

# 参考資料
https://aws.amazon.com/jp/blogs/news/amazon-aurora-under-the-hood-quorum-and-correlated-failure/
GitHub Educationに登録

GitHubでPrivateリポジトリを作成するのは通常有料ですが、学生なら無料で使用できるのでそのために「GitHub Education」に登録が必要です。

まずは下のリンクから「Join GitHub Education」を選択
https://education.github.com/　　

職業、アカウントの用途を選択
<img width="837" alt="スクリーンショット 2018-06-01 23.00.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/248971/77a18f5f-493f-b220-8493-637dcc5e062b.png">

続いて名前、メールアドレス、学校名、卒業年、GitHubをどう使うかを入力。

<img width="731" alt="スクリーンショット 2018-06-01 23.10.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/248971/baceefe4-11fa-cda9-e408-58d9ba39b630.png">

ここでは学校のメールアドレスを選択する必要があります。
もし学校のメールアドレス以外で登録してしまった場合は「Personal settings」から追加できます。

入力が終わって、「Submit Request」を押すと申請完了です。
結果はメールで送信されます。（自分は数分できましたが、もっとかかる場合もあるみたいです）
scalaのlazy valが非同期処理間で共有する小さなキャッシュを作るのに便利だよって話

非同期間で共有して使う、DB等からfetchしてくる値があるけど条件によっては一切参照されない、みたいな時に便利 :rabbit: 

```scala
object Dao {
  lazy val get = {
    println("dbアクセス処理とか…")
    "get value"
  }
}

(1 to 10).par.foreach { i =>
  val v = Dao.get
  println(s"$i < $v")
}

/* => 
dbアクセス処理とか…
7 < get value
2 < get value
1 < get value
9 < get value
5 < get value
6 < get value
4 < get value
8 < get value
3 < get value
10 < get value
*/
```

`lazy val` はコンパイル後に `synchronized` ブロックになるので非同期での参照に使える
当然だけど初回アクセスはlockされるのでデータの取得完了までは待ちが発生する
なので( `synchronized` はタイムアウト設定とかできないので) `Duration.Inf` とかしちゃう処理に使わないようにだけ注意しよう

### おまけ
cats使うと更に簡潔に書けます( `Eval.later` は会社の人に教えてもらった 😊)

```scala
val get = Eval.later {
  println("dbアクセス処理とか…")
  "get value"
}

(1 to 10).par.foreach { i =>
  val v = get.value
  println(s"$i < $v")
}
```
インフラ ド初心者がAlibaba cloudの体験会に行ったのでまとめてみる

##イントロダクション

※ Alibaba cloudの回し者ではないです！
クラウドを触り始めたド初心者が勉強の機会に恵まれたので、レポートを書いてみました:bow:

※ 業務の範囲で使うことはあまりないですが、~~イベント直前に参加者枠にねじ込んでくださった~~弊社CTOに感謝の意を込めて書き連ねます。


## Alibabaの強み


>中国を中心としたリージョンとアベイラビリティゾーン

・世界に18リージョンの拠点がある。
中国の8拠点が中心となっており、アジア圏のエンドユーザーとのレイテンシの減少が望めそう。

・被災時対応の為、データセンターは各リージョンに2拠点設置される予定。

>パッケージングされたサービスの提供

・オンプレミスな環境でサーバを構築すると、物理サーバの購入〜ホストOSの運用〜DB設計なども工数として含める必要があるが、RDSではDBの冗長化、オートスケーリングまで自動的に行ってくれる。

・また、MasterDBとSlaveDBの高可用な構成も自動的に作成される。

>料金形態

・時間決めの使用料金が発生する。
・APIなどの利用内容についても同様に追加課金される。
・エキスパート向けが月額3,000円、ビギナー向けのテスト用向けなパッケージは2,000円程度から始められる。




>Alibaba cloudで何が出来るか（気になったものを抜粋）

・HybridDB for PostgreSQL
　 -> 曖昧文字列の分析・検索に強い
・AntiDDos
 　-> リアルタイムに通信量、DDoS攻撃がモニタリングできる

>VirtualPrivateCloudの構築

・Cloud上にプライベートなサーバを立てることが出来る。
・オンプレミス環境をクラウドにリプレースしたい場合など、アクセスできるプロセスを限定することが出来る。


## 愉快なサーバの仲間たち

***ServerLoadBalancer***
・冗長化済のロードバランサーを設定できる。
・1つのLBに対してインスタンスは2つ下がっている。

***ObjectStorage***
・静的なコンテンツを返すのに適している。画像処理が得意。
・動的な処理、log用に用いる役割はアプリケーションサーバに投げる運用が出来る。
つまりReadやWriteの動きは得意ではない。

***Express Connect***
・VPC間を内部ネットワークで接続することが出来る。
・セキュアにデータをやり取りしたい事例に最適。オンプレミスの環境からcloudに移行したいときなどに用いられる。
・いわゆるサーバ同士をつなぐパイプ。

## ハンズオン
手順は省略。所感を連ねていきます。


・実際にセキュアなインスタンス（サーバの最小単位のこと）を立てることをやりました。基本的にはGUIの操作で完結しますが、物理のサーバを意識させるような項目が多かったです。

・コンソールからテクニカルサポートへチケットを切ることが出来ます。他のクラウドサービスには見られない機能です。

・サーバの構成はリージョン > VPC > VSwitch になっており、VPCにアクセスするには踏み台サーバを経由する構成を取ります。
（これは一般的なサーバ構成について同様のことが言えます）

・インスタンスを立てる際に、マシンスペックを選ぶことが出来ます。これはイメージから作成することも可能ですし、Alibabaが用意したものを選択することも可能です。
（ちなみに物理のマシン性能についてもTipsで上げています。マニアック。）


・インスタンスへのアクセスはssh鍵かパスワード方式を選択できます。

・インスタンスの起動時の設定をshellで書くことが出来ます。

```
   #!/bin/sh
   yum install -y httpd
   systemctl enable httpd
   systemctl start httpd
```
これは新鮮でした。上の内容はアパッチをインストールして毎回起動する、みたいな意味だったと思います。

##まとめ

・中国を拠点とした、地盤の強いサーバについて学ぶことは無駄でないかなあと思います。
今関わっているサービスがアジア圏へ進出する予定は特にないのですが、~~個人的なコンテンツをアジアの方々へ晒してみてもいいのかもしれません~~

・GCPとAWSでインスタンスを立てるなどはしてきましたが、操作感は二つと兼色なかったです。
むしろコンソールにカスタマーサポートがついているなんて、かなり親切なのでは…？
個人的にUIはGCPの方が好きです:relaxed:

・これは単なる無知でしかないのですが、オンプレミスで用意するサーバのコストが高すぎてビビりました。
ロードバランシングにうん１００万円…:joy:
クラウドで立てれば月額700円:joy::joy::joy:



・もっとインフラ触ってみます。興味とモチベが続く限り。
Jupyterにパスワードを設定する

# tl;dr
これで終わり

```console
$ jupyter notebook --generate-config
$ jupyter notebook password
```

# tokenつらい
どっかのマシンでjupyterを立てておいて，遠くからsshしようとしたらtokenわからないみたいなシチュエーションありますよね
パスワードがあればいいけどググると`jupyter_notebook_config.json`とかいじらなきゃいけない感じでめんどくさいみたいなのありますよね
ドキュメント見てみたら普通に専用のコマンドがありました

dockerで立てるときも，`~/.jupyter`をコンテナの`$HOME/.jupyter`にアタッチしてやれば完璧です