OmniAICreator/Qiita-1.07M huggingface dataset:
株取引レコメンデーションシステムの女の子を2人、修士学生の時に作っていた話

# 概要
そういえば株取引アルゴリズムを修士学生の時に作っていました。デイトレードのシステムは日々乃ちゃん、スイングのシステムは待鳥すいちゃんという名前がついてました。

試しにもう一回動かせるかと思ったのですが、流石に3年前のプログラムなので動きませんでした。
https://github.com/hamko/stocks

# 日々乃ちゃんと待鳥ちゃん
日々乃ちゃんは、デイトレード用の売買レコメンデーションシステムです。デイトレードを1分足で観測して、順張りブレイクアウトをLevenberg-Marquardtアルゴリズムで検出します。これによって天井を突破した時のタイミングをいち早く検出することができます。お金が余っていれば、そのタイミングで株を買うことを提案します。逆に天井をした方向に突破したタイミングを検出して、株を売ることを提案します。損切り・利食いにも対応しています。以下の画像のように、毎日5, 6通のメールをこまめに送ってきます。元気な子ですね。

![範囲を選択_111.png](https://qiita-image-store.s3.amazonaws.com/0/115641/229238b0-7450-cbc1-3fa5-9f19aef7f956.png)

待鳥すいちゃんは、全銘柄のファンデメンタル解析を行います。PBR, PER基準の妥当株価から、割安な株を毎日報告します。市場全体の過熱感や、優良な成績を出している企業の過熱感も解析して報告します。一日一回、場が開く前に報告してくれます。知的な子ですね。

![範囲を選択_109.png](https://qiita-image-store.s3.amazonaws.com/0/115641/50a380a2-8c98-71e8-2c59-f52975159545.png)

# どれくらい儲かる提案ができるのか
日々乃ちゃんは、100万円元手で、1/21-2/7で44000円の儲けがでる提案ができているそうです。まあこの間暴落とかなかったので何とも言えないですね。

![範囲を選択_110.png](https://qiita-image-store.s3.amazonaws.com/0/115641/9324a19c-82ab-4354-c31c-9cba5e1044ee.png)


待鳥ちゃんの方は解析していないです。

# システム
日々乃ちゃんのシステムは、1分ごとにYahoo Financeからスクレイピングしてデータを得ます。その後、30分程度のデータから下限・上限の包絡線を計算します。計算方法は、コスト関数e(x)=y-(ax+b)*(y>ax+b?10:1)に対してLevenberg-Marquardtアルゴリズムを使ってフィッティングさせます。これを繰り返し、傾きaの微分がしきい値以上であればブレイクアウト、といった要領で天井突破を検知します。下限検知というのは、こんな感じのものを想定してください。

![11898695_732478400189884_3889530265211424778_n.jpg](https://qiita-image-store.s3.amazonaws.com/0/115641/2d07f39c-4df9-cb4a-00dc-a0b4a1450286.jpeg)


待鳥ちゃんのシステムは、1日ごとにPERによる妥当株価と現在の株価を比較して、現在の株価が標準偏差σに対してどれくらい乖離しているかを解析します。いろいろな株価と妥当株価と標準偏差を観察しつづけると、市場に出ている総額が大きい場合、大体2σを超えるとほぼ過熱状態で1ヶ月単位で妥当株価か悪くても+1σまで戻ることがわかりました（確か日経平均は1週間くらいだったような）。従って、このような基準でスイングトレードの提案システムを組みました。

# モチベーション
昔から不労所得には興味がありまして。

修士学生の時、僕はロボット製作販売で個人事業主で開業していました。小銭を稼ぐループが回ってきたところで、数百万円が銀行口座に入っている状態でした。昔から不労所得には興味がありまして、ぜひこれを株で増やしたくなるのは自然なことです。そこで松井証券に200万円ほど突っ込んで、現物の株取引をしていました。ものすごく1日中張り付いていればデイトレで損する気はしないのですが、一日中グラフを見ているというのも問題です。スイングでもファンデメンタルをインターネットで探しまくって、指標を眺めるというのはアレですし、僕は忘れっぽいのでこの日に売ろうと思っても忘れてしまいます。一番効いたのは、ギリシャ崩壊に伴う株暴落に2日ほど気づかず、30万ほど失ってしまった経験です（当時の収入的にはそこまで痛くなかったので、まあ勉強代だねと思っていたのですが、今はお金が欲しいです）。

そういえば僕はプログラミングが少しできるのでした。このような時間的金銭的ロス、機会損失を最小化するために、自動取引ないしは売買レコメンデーションシステムを構築すればよいと思ったのは自然なことだと思います。

最近機械学習を勉強しているのですが、どうしても応用が見えずにモチベーションが保てずにいました。いろいろ応用はあるだろうと思いますが、どう考えても、株自動取引にしか僕は興味が無いようです。それで思い出して、こんなポエムを書くに至りました。
 
# 本当はこの記事は書くべきではない
個人的には、技術ブログというのは一定の成功を持って発信すべきだと思います。本当は、この記事を書くことでインターネット上に無意味なゴミが溢れてしまうという罪悪感があります。一方で、ブログというものは成功をしていなくても書いてもよいだろうと思いますし、僕がどういうハムスターなのかを発信することは、今後意味があるだろうと思ってこのブログを書きました。ある種の日記です。

こういう都合があるので、僕はこの記事を真面目に書いていません。タイピングゲームだと思って書きました。
spring cliのコマンド補完を高速化しました

spring cliの`spring hint`を使ったコマンド補完がもっさりしているので、ハードコーディングして高速化しました。`spring hint | awk '{print $1}'`でspring cliのサブコマンド一覧は得られるので、commandsのcatしている部分をファイル参照に変えて、versionを変えたときに参照先ファイルを更新してあげれば、割と実用的じゃないかと思っています。

```bash
_spring()
{
        local cur prev words cword commands

        _get_comp_words_by_ref cur prev words cword
        commands=$(cat <<-FIN
                help
                version
                run
                test
                grab
                jar
                war
                install
                uninstall
                init
                shell
        FIN)
        COMPREPLY=($(echo "$commands" | xargs -n 1 | grep -o "^${cur}.*"))

        if [ $cword -ne 1 ]; then
                _filedir
        fi

} && complete -F _spring spring
```
Swift - UIActivityViewControllerで特定の方法でシェアされたのを判定する

[シンプル家計簿 - Moneybook](https://itunes.apple.com/jp/app/moneybook/id1159345509?mt=8) で、特定の方法でシェアしてくれた時にだけなにかしてあげるというのをUIActivityViewControllerを使って実装してました。
ブレークポイントを使って`UIActivityType.rawValue`で対象の方法を調べれます。


```swift
    let url = URL(string: "https://itunes.apple.com/jp/app/APP_ID?mt=8")!
    let activityVC = UIActivityViewController(activityItems: ["このアプリいいよ！", "シンプル家計簿 - Moneybook", url], applicationActivities: nil)
    present(activityVC, animated: true, completion: nil)
    
    // シェアしてくれたかの判定
    activityVC.completionWithItemsHandler = { (activityType: UIActivityType?, completed: Bool, returnedItems: [Any]?, activityError: Error?) in
        guard completed else {
            return
        }
        
        // シェア対象の一覧
        let targets = [
            "com.apple.UIKit.activity.PostToTwitter",
            "com.apple.UIKit.activity.PostToFacebook",
            "jp.naver.line.Share"
        ]
        
        // シェアされた方法は対象の方法か判定
        if let type = activityType, targets.index(of: type.rawValue) != nil {
            // 対象の方法でシェアしてくれた、なにかしてあげる
            print("ありがとう！これあげる！")
        } else {
            // 対象外の方法でシェアされた
            print("TwitterかfacebookかLINEでシェアしてね！")
        }
    }

```
チラ裏: online-metrix.net/fp/〜.js?〜とは何か調べてみた

ログインページに`online-metrix.net/fp/〜?〜`という指定があったので調べてみたところ、xss対策用のサービスの様子。(fpはfingerprintの略)

## session_idが正しい場合、ページが表示される。

![ok.png](https://qiita-image-store.s3.amazonaws.com/0/25728/080e2e1c-5bf7-2df2-2ef7-e604af28bbcf.png)

## session_idが不正な場合

![err.png](https://qiita-image-store.s3.amazonaws.com/0/25728/c15fc35e-d3ec-67ac-e794-5802a04e220b.png)


## 参考

* [Website blocked messages concerning online-metrix.net - Website Blocking - Malwarebytes Forums](https://forums.malwarebytes.com/topic/207616-website-blocked-messages-concerning-online-metrixnet/)
* [How to set up the device fingerprint for Braspag/CyberSource? - VTEX Help](https://help.vtex.com/en/faq/how-to-set-up-the-device-fingerprint-for-braspagcybersource)
SQLAlchemy を使って Pandas のデータをDBに保存する

## 概要

Python の O/R マッパー SQLAlchemy に関するメモ。

## 前提
- Python 3
- [SQLAlchemy + MySQL を使ってみる（その１）](https://qiita.com/nskydiving/items/88377d57040db17281fe)

```shell-session
$ pip install SQLAlchemy
$ pip install PyMySQL
```

## コード

[pandas.DataFrame.to_sql](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_sql.html)を使用する。

```python
import pandas as pd
import sqlalchemy as sa

df = pd.DataFrame({'point': [100]})
print(df)
url = 'mysql+pymysql://root:@localhost/test_db?charset=utf8'
engine = sa.create_engine(url, echo=True)

df.to_sql('test1', engine, index=False, if_exists='append')
```

これで MySQL の test_db データベース上で test1 テーブルの point カラムに 100 という数値が挿入される。`if_exists` を指定しないと、データベース上でテーブルを新規作成するように試み、すでにテーブルが存在するときには失敗する。

INSERT ではなく UPDATE はできるのだろうか？引き続き調べてみたい。
UIColorのRGBの数値を取得するExtension

# はじめに
こんにちは。:leaves:
UIColorのExtensionなどで

```swift
let color = UIColor(r: 70, g: 185, b: 200)
```

のように作成することはよくあるかもなのですが、その逆の
**UIColor**からRGBの値を1〜255の**正数**で取得したくなりました。
至らぬ点などあるかもしれないのですがコメント頂けたら幸いです。

# サンプル

![Group.png](https://qiita-image-store.s3.amazonaws.com/0/128250/82cfff51-b234-9c2b-643b-34c69f4dbbc9.png)

# コード
```swift
extension UIColor {
    
    var r: Int { return Int(self.cgColor.components![0] * 255) }
    
    var g: Int { return Int(self.cgColor.components![1] * 255) }
    
    var b: Int { return Int(self.cgColor.components![2] * 255) }
    
    var a: Int { return Int(self.cgColor.components![3] * 255) }
    
    convenience init(_ r: Int, _ g: Int, _ b: Int, a: CGFloat = 1.0) {
        self.init(red: CGFloat(r) / 255.0, green: CGFloat(g) / 255.0, blue: CGFloat(b) / 255.0, alpha: a)
    }
}
```

それだけです^^;

見て頂いてありがとうございます
Rails：コントローラーの分割 > カスタムアクション

そんなに新しい記事じゃないけどメモとして

カスタムアクション作るより、コントローラー分割してデフォルトのアクションだけの方が良くね？
ってDHHが言ってるよって記事。
http://postd.cc/how-dhh-organizes-his-rails-controllers/

> カスタムアクションの追加は、全く”Railsらしいやり方”ではないのでは？

> コントローラはデフォルトのCRUDアクションindex、show、new、edit、create、update、destroyのみを使うべきだということです。その他のアクションはどれも専用の（それ自体はデフォルトのCRUDアクションしか持たない）コントローラの作成につながるのです。

らしいですが、そんなプロジェクトに未だ出会ったことがない。実際どうなんでしょか。
axiosのヘッダーにJSON Web Tokenを埋める

JSON Web Token を毎回ヘッダに埋めるのが嫌だったのでつくってみました。

```http.js
import axios from 'axios'

const http = axios.create({
  baseURL: `${process.env.API_URL}/api/v1/`
})
http.interceptors.request.use((config) => {
  if (token) {  
    config.headers.Authorization = `Bearer ${token}`
    return config
  }
  return config
}, function (error) {
  return Promise.reject(error)
})

http.post('/hogehoge')
```

http.interceptors.request.use で、リクエストを投げる前にインターセプトしてリクエストヘッダにアクセスできるので、それを利用します。
Token を Cookie やローカルストレージなど、環境に合わせて取得し、それを　**Authorization : `Bearer token`** の形になるように埋めています。
あとはそのインスタンスを使い回すだけ、最高。
zsh の起動を500%高速化した話

# 高速化の敵

1. **外部スクリプトロード** (最も遅い)
1. zsh 関数定義
2. zsh スクリプト実行

# 高速化の味方

1. 分離された実行可能ファイル
1. `autoload` による遅延ロード
1. 複数 zsh ファイルの統合

# 実践したテクニック集

## tmux の起動を高速化

`tmux` を起動するのに zsh プラグインは不要。

```zsh:.zshrc
if [[ -z "$TMUX" ]]; then
  tmux new-session
  exit
fi

# プラグインのロード処理
```

## 遅延ロード

```zsh:.zshrc
zplug 'zsh-users/zsh-completions', use:'src/_*', lazy:true
```

```zsh:.zshrc
zplug 'mollifier/anyframe', \
    use:'anyframe-functions/{actions,selectors,sources,widgets}/*', lazy:true

zle -N anyframe-widget-cd-ghq-repository
# ...
bindkey '^x^g' anyframe-widget-cd-ghq-repository
# ...
```

## 実行ファイルとしてロード

特に補完定義ファイルは分離されていることが多い! ( `compdef` の埋め込み忘れに注意)

```zsh:.zshrc
zplug 'simonwhitaker/gibo', use:'gibo', as:command
```

```zsh:.zshrc
zplug 'motemen/ghq', dir:"${GOPATH}/src/github.com/motemen/ghq", \
    use:'zsh/_ghq', as:command

compdef _ghq ghq
```

(2020/02/02 追記) zplugin を使っているのであれば、補完ファイルは lazy load してしまえば良い。

```zsh:.zshrc
zplugin ice wait''
zplugin snippet motemen/ghq/zsh/_ghq
```

## コマンド実行時にロード

```zsh:.zshrc
zplug 'supercrabtree/k', use:'!*'

k() {
  unfunction k
  . "${ZPLUG_REPOS}/supercrabtree/k/k.sh"

  k "$@"
}
```

(2020/02/02 追記) これも zplugin であれば `trigger-load` を使えば楽。

```zsh
zplugin ice trigger-load'!k'
zplugin supercrabtree/k
```

## zplug のプラグインチェックをスキップ

新規プラグインを追加した際に手動で `zplug install && zplug load` する必要があるので注意。

```zsh:.zshrc
# if ! zplug check --verbose; then
#     printf "Install? [y/N]: "
#     if read -q; then
#         echo; zplug install
#     fi
# fi
```

## zsh ファイルをコンパイル

上のテクニックを実践するとコンパイラが追えない処理が少なくなるはずなので相性がいいはず (?)

```shell-session
$ zcompile ~/.zshrc; zcompile ~/.zsh/rc/plugins.rc.zsh
```

こちらもおすすめです。
https://github.com/robbyrussell/oh-my-zsh/tree/master/plugins/zsh_reload

# 後書き

測るのを忘れてしまったのですが、体感的に 5s 以上かかっていた zsh の起動が 1s 以内で起動するようになりました。 (ほとんどのプラグインが oh-my-zsh から引っ張ってきた補完ファイル)
もっと良い方法や「それもっと簡単に書けるよ!」などがあれば教えてください。
Relying On a Modern App-Based Laundry Service Can Be Beneficial

<p>In this fast paced world, where people are so busy and don’t have much time, washing clothes can be difficult; let alone drying them or ironing them. A laundry service can be very helpful during such situations. Laundry services can save the precious time and money of people and provide them with proper clean and tidy clothes. Apart from washing, laundry services can provide ironing, dry cleaning and a wide variety of curtains washing (<a href="https://bebarobeshoor.com/product"><b>خشکشویی پرده</b></a>) services.</p>

<p>Taking into service of such laundry care can be:</p>

<ul>
<li><p>Affordable: Getting clothes clean and ironing them can be very affordable through laundry services as they are quite cheap and can provide proper cleaning services as opposed to at home. Including the free pick up, ironing, folding and delivery; laundry services can be very affordable.</p>

</li>
<li><p>Speedy: Most of the laundry services offer a margin of 24 hours-48 hours for their pick-up and drop off services; which is quite fast than other local cleaners and home cleaning at a fraction of cost.</p>

</li>
<li><p>Convenient: Upon the convenience of the customer, the laundry services can pick up and drop off the laundry thereby completely removing the barriers of time and hassles that are associated by doing laundry at home.</p>

</li>
<li><p>Cost: Adding up the costs of buying high-quality washing detergents and powders, costs of running the washers and dryers and the costs of time wasted during the entire process; in almost all the situations, getting laundry done by a service is always cheaper than doing by oneself.</p>

</li>
<li><p>Quality: People don’t have the expertise, knowledge, products or techniques to deal with tough stains. But laundry services possess everything to provide a gentle cleaning and stain removals of the clothes to their customers in a perfect condition.</p>

</li>
</ul>

<p>There are many clothes which require a different style of cleaning or maintenance, which is simply not the case with home cleaning. In fact those delicate clothes might get destroyed if cleaned at home. And Bebarobeshoor is a Tehran app-based internet laundry (<a href="https://bebarobeshoor.com/aboutus"><b>خشکشویی اینترنتی</b></a>) company that offers a variety of affordable laundry services from washing, cleaning stain relieving, dyeing, steaming, ironing or sewing or repairs for a variety of men and women clothes as well as for bags, dolls, bed sheets, cushions, shoes and much more. With easy sign-in on the app, easy and convenient pick up, professional work and speedy 24-48 hour drop off; Bebarobeshoor is a name to trust.</p>

<p><b>About Bebarobeshoor:</b></p>

<p><a name="_GoBack"></a> Bebarobeshoor is an app-based cleaning company in Tehran who specialize in a variety of laundry online (<a href="https://bebarobeshoor.com/"><b>خشکشویی</b></a> ) services in a much affordable way.</p>

<p>For more information, please visit <a href="https://bebarobeshoor.com/"><b>Bebarobeshoor.com</b></a>.</p>
ESLint v4.10.0

前 [v4.9.0] | 次 [v4.11.0]

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">ESLint v4.10.0 has been released: <a href="https://t.co/gBvDBlhA7v">https://t.co/gBvDBlhA7v</a></p>&mdash; ESLint (@geteslint) <a href="https://twitter.com/geteslint/status/924022227644727296?ref_src=twsrc%5Etfw">2017年10月27日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ESLint 4.10.0 がリリースされました。
今回はバグ修正のみです。

質問やバグ報告等ありましたら、お気軽にこちらまでお寄せください。

> 🏢 [日本語 Issue 管理リポジトリ](https://github.com/eslint/eslint-jp)
> 👫 [日本語サポート チャット](https://gitter.im/eslint/eslint-jp)
> 🏢 [本家リポジトリ](https://github.com/eslint/eslint)
> 👫 [本家サポート チャット](https://gitter.im/eslint/eslint)

----

[v4.9.0]: http://qiita.com/mysticatea/items/ae0081b3da453b8a3304
[v4.11.0]: http://qiita.com/mysticatea/items/b7efa8286c2fabc3267f
[#9999]: https://github.com/eslint/eslint/issues/9999
[xxxx]: http://eslint.org/docs/rules/xxxx

<!-- 
![JSCS Icon](http://jscs.info/favicon.ico) JSCS 互換ルールです。
-->
エンジニアとしてやっていく上で大切なこと

先日、t_wadaこと和田卓人さんの講演で、「エンジニアとしてこの先生き残るために」という話を聞いてきたので、内容をまとめてみました。
すごくためになるお話だったので、自分の今後の行動指針にしていきたいと思っています。(願望)

# 大事なこと
1. 学ぶ姿勢を持つ
2. 手を動かして身につける
3. アウトプットをしていく
4. 刺激を忘れない

## 学ぶ姿勢を持つ
日々新しい技術が生まれていくこのご時世、常に学んでいくことはとても大事。（わかってはいるのですがなかなか大変）
そんな中で学んでいく指標としては、
**・四半期ごとに技術書を読む　＝　３ヶ月ごとに技術書を読むことを続けていく**
**・毎年少なくとも１つの言語を学ぶ**
言語は仕事で使ってるものかそれに近い言語が良いそうです。（でも枯れた言語は避けてナウい言語の方がベター）
目標としては、**動くものアプリケーションを作成するか他の人に使ってもらえるライブラリを作成するまで！**

## 手を動かして身につける
[デールの円錐](https://www.ladea.jp/b-gak-006/)というものがあるらしく、ざっくり言うと**見たり聞いたりするだけでなく、話したり手を動かしたりする方が頭に入るよ**ということらしい。
取り組み方としては、以下のようなものがあります。

- 写経<br>
技術書のサンプルコードを写して実行<br>
実行したらコミット（コミットログにページ番号を書き込む）<br>
疑問点があったらコミットログや本に合わせてメモする<br>
章ごとにタグを打つ<br><br>
- 毎日コードを書く<br>
毎日書く、ブログ、ドキュメントなどはコードを書いてから<br>
意味のあるコードを書く、インデントやフォーマットの修正、リファクタリングは含めない<br>
２４時までに書く<br>
Githubに載せる<br>

## アウトプットをしていく
**正のフィードバックループ**という考えがあり、アウトプットをすることでそれに対しフィードバックがあり、そのインプットを受けてさらに良いアウトプットができるようになっていくというもの。
アウトプットのチャネルとしても、以下のように様々なものがあるので、できるところからやっていくのが良いでしょう。

- Twitter
- blog,Qiita
- 雑誌
- 書籍
- 講演
- ライブコーディング
- Github

ライブコーディングがエンジニアの極み（和田談）とのことなので、最終目標はライブコーディングになるでしょう。

## 刺激を忘れない
同じものをずっと続けていても依存化しています。

- 定期的に自分のスキルを棚卸する
- 外部に出て自分のスキルを相対化する
- 使う道具を定期的に変える
- 未知のコミュニティ
- ペアプログラミングをする

など外部からの刺激を受け取るようにしましょう。
プログラマを続ける上で、年下の人から技術を学んでいくことは、自分にはない新しい発想を得られるなどとても重要のようです。

# おわりに
エンジニアとして続けていくには、とてつもない努力が必要だということはよくわかりました。
毎日コーディングや講演などハードルが高いものもありますが、写経やqiitaへの投稿など自分のできるところからコツコツ進めていきたいと思います。

# おまけ
和田さんが影響を受けたという書籍を紹介します。
[プログラマが知るべき９７のこと](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%81%8C%E7%9F%A5%E3%82%8B%E3%81%B9%E3%81%8D97%E3%81%AE%E3%81%93%E3%81%A8-%E5%92%8C%E7%94%B0-%E5%8D%93%E4%BA%BA/dp/4873114799)
[達人プログラマー 職人から名匠への道](https://www.amazon.co.jp/%E6%96%B0%E8%A3%85%E7%89%88-%E9%81%94%E4%BA%BA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC-%E8%81%B7%E4%BA%BA%E3%81%8B%E3%82%89%E5%90%8D%E5%8C%A0%E3%81%B8%E3%81%AE%E9%81%93-Andrew-Hunt/dp/427421933X/ref=pd_lpo_sbs_14_img_1?_encoding=UTF8&psc=1&refRID=CWV2902MNQKJ5G2DSJEX)
vivadoのマルチスレッド設定


vivadoでsynth,impleするときにスレッド数を設定できますが、general設定により最大スレッド数が制限されているため、ここでいくら大きな数を設定しても制限されてしまいます。この値は、windows版vivadoの最大スレッド数は2です。
tclコンソールでこの値を大きくする必要があります。

```tcl:Roaming¥Xilinx¥Vivado¥init.tcl
set_param general.maxThreads 8
```

<!--※役にたちましたら"いいね"してくれると喜びます。-->
PCやり過ぎ防止！Macを指定した時間に強制シャットダウンする方法

**※注意！：以下は古い方法です。最新の方法を記載しましたのでこちらを見てください！**
[【2021年版】Macを指定した時間に強制シャットダウンさせる方法](https://qiita.com/kanatano_mirai/items/ab9bff5bd7fe0228f73b)

僕はまだ意志が強くないので、PCが起動していればずっとPCを使ってしまいます。
なので、毎日指定した時間にPCを強制シャットダウンさせることでPC中毒や寝不足を防いでいます。

Windowsでは、標準アプリ「タスクスケジューラ」を使えば割と簡単に指定した時間に強制シャットダウンを行えます。

ですが、Macにはそのような標準アプリはありません。
システム環境設定にある「省エネルギー」の中のスケジュールがそうなのではないか？と思うかもしれませんが、このスケジュール機能は

- スリープ中はシャットダウンしない
- ダイアログ内でキャンセルするとシャットダウンしない
- ダイアログが出ている時点で強制ではない

という理由により、省エネルギーの中のスケジュール機能を使うのは良い選択とはいえません。

僕が求めているのは、「指定した時間に、有無を言わさず強制的にPCをシャットダウンさせる」方法です。
ググっても方法が見つからなかったので、ここに公開します。

# 指定した時間に強制シャットダウンする方法

## 環境

- MacBookAir
- MacOSX 10.12.6

## 手順

### 1.Automatorを起動
アプリケーションフォルダの中にある「Automator」を起動します。
![スクリーンショット 2017-10-28 12.22.47.png](https://qiita-image-store.s3.amazonaws.com/0/154305/348502ba-5509-0fcf-5be4-2bbf9ce7aa9e.png)

### 2.カレンダーアラームを選択
起動するとこの画面が出てくるので、「カレンダーアラーム」を選択します。
![スクリーンショット 2017-10-28 12.24.39.png](https://qiita-image-store.s3.amazonaws.com/0/154305/af73eb7e-1753-127a-6e61-8797430c28b1.png)

### 3.AppleScriptを選択
手順2が終わると、この画面になります。
![スクリーンショット 2017-10-28 12.27.03.png](https://qiita-image-store.s3.amazonaws.com/0/154305/f603d0e0-ead9-a89c-2fe9-93a4a5ebca05.png)

左側のリストの中から「AppleScriptを実行」をドラッグして右側のエリアに持って行きます。
すると、この画面になります。
![スクリーンショット 2017-10-28 12.28.22.png](https://qiita-image-store.s3.amazonaws.com/0/154305/82c8dd3a-5cc2-b93d-1730-762c8c021b49.png)

### 4.コードを書く
AppleScriptのコードを書きます。といっても、この1行だけです。
``` tell application "System Events" to shut down ```

これを右枠にコピペします。最初からあるコードは消して大丈夫です。
![スクリーンショット 2017-10-28 14.11.03.png](https://qiita-image-store.s3.amazonaws.com/0/154305/d92402df-1056-f672-4b5b-6716df181e98.png)

### 5.保存する
メニューのファイル→保存で保存します。名前はわかりやすいように。
![スクリーンショット 2017-10-28 14.15.36.png](https://qiita-image-store.s3.amazonaws.com/0/154305/5ea0d71f-1a98-d07f-2c00-1a7b332a8aae.png)
**保存すると、コードが正常に動作する場合シャットダウンされます。保存前にシャットダウンしても大丈夫か確認を忘れずに。**

### 6.スケジュールを組む
カレンダーを開くと、保存した日にちにAutomatorのスケジュールが追加されています。
![スクリーンショット 2017-10-28 14.31.22.png](https://qiita-image-store.s3.amazonaws.com/0/154305/7a55c905-bafd-3c33-84cf-a9fdd875a176.png)

開始時刻をシャットダウンさせたい時刻に変更することで強制シャットダウンが可能になります。
また、通常のスケジュールと同じく繰り返しもできるので、毎日指定した時間に強制シャットダウンができるようになります。
スリープ中でもスリープから復帰後数秒でスケジュールが実行され、シャットダウンされます。

# 欠点
この方法にはいくつか欠点がありまして。

- Macがおやすみモードになっている場合は動作しない 
- スリープから復帰後にスケジュールが実行されないときがある
- テキストファイルの未保存状態などで、シャットダウンが中断される場合がある

など、この方法は万能ではありません。あくまでやり過ぎを補助するものとして使ってください。

# さいごに
これで快適なPCライフが実現できますね。
最初はきついかもしれませんが、習慣化していけばPC中毒も自然に治ると思います。
わからないことがあれば、お気軽に質問してください。

（本当は自制できれば一番いい！）
VALID-READYハンドシェーク AXI-Stream風


##はじめに
　フィルタやパケットなど、ストリームデータを扱うモジュールを開発するにあたって、インターフェースはなやみどころ。
　クロックbyクロックのパラレルインターフェースならラッチするだけで悩みはないのですが、パケットのようなバースト伝送や、非同期サンプリングを行うモジュールでは、有効データが間歇的になります。パケット処理など一旦キューに蓄積しバッチ型の処理を行う場合には、ハンドシェークも必要です。
　いろいろ設計してきましたが、個別設計では間違いを起こしやすいので、定番のAXI-Streamを使うためいろいろ試したメモです。

##信号構成
フロー制御を行うため、CLOCK,DATA,VALIDに加えて、READY,LASTを追加することにしました。

##出力側(Master)の動作
1)データが完成したら、データ出力と共にVALIDをアサート
2)クロックのエッジで、READYを検査しアサートされていれば、（取り込めるといっているので）出力処理完了。（可能なら）データを更新し連続出力。
　そうでなければ、データとVALIDをホールド
3)LASTは適宜

<!--
```VHDL:状態遷移マシンの例 
U:process(...) begin
 tvalid <='0';
 tlast  <='0';
 tdata  <=data(count_reg);
 case state_reg is
 when S2_WAIT=>
 		いろいろ
 when S3_RUN=> 
 		tvalid <= '1';
		if tready='1' then
			count_nxt <= count_reg +1;
			if count_reg = LENGTH_1 then
				state_nxt<= S4_LAST;
			end if;
		end if;
  when S4_LAST=>
  		...  		
```
-->
##受信側(Slave)の動作
Clock by Clockで連続受信したい場合
1)連続受信の準備ができたらReadyをアサート
2)クロックのエッジでvalidであればラッチ

<!--
```vhdl:連続受信の例
U:process(CLK) begin
	if rising_edge(CLK) then
		if state_reg=S3_RUN and tvalid='1' then
			dat_reg <= tdata;
		end if;
	end if;
end process;
```
-->
受信途中で停止する場合
1)Readyをデアサートしておく
2)データ取り込んだらReadyをアサート

<!--
```vhdl:一時停止する場合の例
U:process(...) begin
 tready<='0';
 state_nxt <= state_reg;
 case state_reg is
 when S2_PAUSE=>
 	if 解除条件 then
 		state_nxt<=S3_RUN;
 	end if;
 when S3_RUN=>
 	tready<='1';
 	if tvalid='1' then
 	  ...入力データを処理
 	end if;
 	if 停止条件 then
 		state_nxt<=S2_PAUSE;
 	end if;
 end case;
```
-->
##まとめ
Ready信号を受信確認(ACK)と考えると失敗します。
Valid信号は"Here you are." Ready信号は"Next Data please!"という感じでしょうか。

###参考記事
[VALID 信号と READY 信号によるハンドシェイクの注意点](https://qiita.com/ikwzm/items/9736b5547cb15309af5c) [ikwzmさん](https://qiita.com/ikwzm)

<!--※役にたちましたら"いいね"してくれると喜びます。またネタをかくかもしれません。-->
CPU使用率100%は悪なのか？

2019/9/29 部分改訂

==========================================================================

# 0. はじめに
[前回の投稿](https://qiita.com/zd6ir7/items/abbb1e92701992d32b88)については、本当にたくさんの方々に見ていただいたようでありがとうございます。前回からだいぶ時間がたってしまいましたが、今回は最近(2017年9～10月時点)読んだ以下の本から、私が非常に興味をそそられた話題を紹介したいと思います。

Scott Oaks著、Acroquest Technology株式会社監訳、寺田佳央監訳、牧野聡訳
『Javaパフォーマンス』　オライリー・ジャパン発行
https://www.oreilly.co.jp/books/9784873117188/

# 1. 「CPU使用率100%」の意味
CPU使用率が100%という状態と聞いてどのように思い浮かべるでしょうか？「パフォーマンスに悪影響を与えているのでは？」と良いイメージは持たないのではないかと思います。この本では、必ずしもそうではないことが述べられています。

文章を引用しますが、まずこの本の筆者は、

>仮にあるプログラムの実行に10分かかり、その間のCPU使用率が50%だったとします。もしこれを100%に上げるようなチューニングを行えたら、パフォーマンスは2倍になり、5分で実行できるようになるでしょう。ここでさらにパフォーマンスを2倍にできたとしたら、CPU使用率は100%のままで実行時間は2分半ということになります。

という例を挙げたのち、「CPU使用率とは、プログラムがどの程度効率的にCPUを使えているかということを」示すものであり、「この値は大きければ大きいほど望ましい状態」と結論づけています。

それはそうですよね。プログラムが実行されるとき、プログラムモジュールはディスクからメモリへ展開され、メモリに入った情報は順次CPUが読み取って実行されるわけです。そのCPUを休ませることなくプログラムを実行させることができればパフォーマンスの観点上望ましいわけです。

# 2. 「CPU使用率100%」ではないケース
では逆に、プログラムを実行させるとき、CPUが休んでいる、言い換えると100%使い切っていない場合、CPUを稼働させない何らかの原因があるわけであり、それに対する解析、ときにはチューニングが必要になってくるわけです。

この本の筆者はCPUが100%使われていないケースとして、以下3つの原因を挙げています。
>
- （中略） アプリケーションがブロックされ、ロック解放まで実行が中断されている。
- アプリケーションが何か（例えば、データベースからのレスポンス）を待っている。
- アプリケーションにとって、行うべき処理がない。

上記1つ目と2つ目の原因に対しては、「ロックに対する競合を減らしたり、データベースからのレスポンスをより速くするチューニングを行ったりできれば、（中略）プログラムの実行は高速化しCPUの使用率は上がる」ことを述べています。一方、3つ目の原因については、例えば「クライアントからのリクエストを待ち受けるサーバアプリケーション」が「処理待ちのHTTPリクエストをすべて処理し、次のリクエストまで待機するといった状態」が想定されるとしています。この場合、CPUは休んでいるわけであり、まだHTTPリクエストが来ても受け付けられる状態にあることを示しています。

# 3. CPU使用率の意味を考える
ところで、CPU使用率とは一般的に、所与の時間に対してどれだけCPUが稼働したかを占める割合を指します。1秒という所与の時間に対して450ミリ秒稼働していればCPU使用率は45%を意味します。見方を変えると、1秒のうち450ミリ秒はフル稼働していたしていたわけであり、この本から引用すれば、

>つまり、1秒のうち450ミリ秒はCPU使用率が100%で、残りの550ミリ秒は0%ということになります。このような状態を指して、CPU使用率が45%であると表現しています。

というわけです。CPU使用率45%(1秒中550ミリ秒はCPUは動いていなかった)という数値を見て、それは妥当なのか？妥当でない場合どこを直すべきなのか？ということを考える必要があります。

# 4．終わりに
プログラムを実行させるときの究極の目標は、CPUをフルに使って短時間で終えることです。つまりCPU使用率100%で最大限のパフォーマンスを上げることです。そのために、CPUが休んでいる時間があるのであれば、上述の通り必要に応じて適宜チューニングしていくわけです。
ここで勘違いしてはいけないのが、CPU使用率100%は、パフォーマンスを上げるための手段であり目的ではないことです。プログラムを実行しようとして、CPU使用率100%の状態が長く続いてしまえば短時間での終了はおろか、他のプログラムが実行されるのを妨げてしまうことになり、悪い結果をもたらしてしまいます。逆にCPU使用率が70%であっても要件を満たすパフォーマンスが得られているのであれば問題ないと考えられるでしょう。
「CPU使用率100%」は悪ではありません。ただしそれは、良いパフォーマンスが得られている前提の上で語られるべきです。


# 5. 余談
Javaの本というと、「Javaとは何？」から始まる入門書や、Webアプリケーションを作りながら解説する本、デザインパターンについて紹介した本などを思い浮かべる人が多いと思います。この本はJavaのパフォーマンス面にフォーカスした本です。Javaのパフォーマンスを上げるためのノウハウや解析方法、JavaVMのオプションにガベージコレクションの仕組み等が解説されています。翻訳本ですが、この観点について着目した日本で唯一の本ではないかと思います。興味のある方はぜひ手に取って見てください。

ここまで読んでくださりありがとうございました。
ツイートをChangeLogっぽい形式でSpreadsheetに記録する


一日分のツイートを1エントリ（？）にまとめて ChangeLog っぽい形式でSpradsheetに保存する。

```
2017-10-28 (土)

* tweet [Diary]:

00:00 hoge
01:15 fuga
02:30 MT @name @h0k0r0bi hogefuga
03:45 FV fugahoge
```

# 記録

IFTTT で自分のツイート、リプライ、ライクを spreadsheet に記録

- Trriger
    - Twitter
       - New Tweet by you (retweets, @replies)
       - New mention of you
       - New liked tweet by you

- Action
  トリガーそれぞれに対して設定

    - Google drive
        - Add row to spreadsheet

# 整形

GAS で整形。

- inputFormula(): ツイートの先頭に時間を付加する形式になる式を3列目に追加
- copyTweets(): 別シートに3列目をコピー
- clearSheet(): 記録シートをクリア
- inputDate(): 日付とエントリのタイトルを3列目に追加

```js
function executePerDay() {
  inputFormula();
  copyTweets();
  clearSheet('Sheet1');
  inputDate();
}

function inputDate() {
  var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1');
  var d = new Date();
  var year = d.getFullYear();
  var month = d.getMonth() + 1;
  var day = d.getDate();
  var youbi = d.getDay();
  var youbis = ['日', '月', '火', '水', '木', '金', '土'];
  sheet.appendRow(["", "Sep"]);
  sheet.appendRow(["", "", year + "-" + month + "-" + day + " (" + youbis[youbi] + ")"]);
  sheet.appendRow(["", "Sep"]);
  sheet.appendRow(["", "", "* tweet [Diary]:"]);
  sheet.appendRow(["", "Sep"]);
}

function inputFormula() {
  var sheet = SpreadsheetApp.getActive().getSheetByName('Sheet1');
  var lastRow = sheet.getLastRow();
  var range;
  for (var i = 1; i <= lastRow; i++) {
    range = sheet.getRange(i, 1);
    if (range.getValue() == "") {
      continue;
    }
    range = sheet.getRange(i, 3);
    if (range.getValue() == "") {
      range.setValue("=text(value((REGEXEXTRACT(A" + i + ",\"[^ ]+$\"))),\"HH:mm \") & B" + i);
    }
  }
}

function copyTweets() {
  var fromSheet = SpreadsheetApp.getActive().getSheetByName('Sheet1');
  var lastRow = fromSheet.getLastRow();
  var fromRange = fromSheet.getRange(1, 3, lastRow);
  var values = fromRange.getValues();
  
  var toSheet = SpreadsheetApp.getActive().getSheetByName('Sheet2');
  var toLastRow = toSheet.getLastRow();
  var toRange = toSheet.getRange(toLastRow + 2, 1, lastRow);
  toRange.setValues(values);
}

function clearSheet(sheetName) {
  var sheet = SpreadsheetApp.getActive().getSheetByName(sheetName);
  sheet.clearContents();
}
```

# 整形の実行トリガー

1日1回0時くらいに実行。

![image](https://qiita-image-store.s3.amazonaws.com/0/24711/fb139f76-6774-595c-adc6-19f9408b87db.png)
【ubuntu】ImportError: No module named '_sqlite3'とでたときの対処法【Python】

作ったツールをubuntuにcloneしたときにこんな風に怒られたのです。

## 原因

OS自体にsqlite3を使うためのライブラリが入っていないことが原因です。

pythonでsqliteをインストールしてても無駄です。
結局pythonもOSのライブラリを参照しているので。

## 解決方法

というわけで必要なものをインストールすればOKです

`sudo apt-get install libsqlite3-dev libbz2-dev libncurses5-dev libgdbm-dev liblzma-dev libssl-dev tcl-dev tk-dev libreadline-dev`


よし。これで大丈夫だと思ってしまいそうですが実はまだ駄目です。

ハマりどころなのですが、例えばpython3.4.3をインストールするときにすでにsqliteを使わない形でビルドされています。（インストール時にはライブラリが入っていないので自動でそうなるんだと思う）
っていうかインストールするときにメッセージがでているはず。


というわけで上記ライブラリをインストールしたら、pythonもインストールし直しましょう。

もし、すでに色んなものをpip install しているとしたら、

`pip freeze > requirements.txt`

で吐き出しておきます。

僕はこれで解決しました。

めでたしめでたしです。
UIButton をタップした時の背景色を UIColor で指定する

[UIButtonハイライト時の色を指定する \- Qiita](https://qiita.com/akatsuki174/items/c0b8b5126b6c12f62001) と内容はほぼ同じです。

UIButton をタップした時の背景色を変えたくても、メソッドとしては `setBackgroundImage` があるだけで使い勝手が良くありません。
`setBackgroundColor` があると嬉しいですよね。

というわけで Extension です。

```swift
extension UIButton {
    func setBackgroundColor(_ color: UIColor, for state: UIControlState) {
        let image = color.image
        setBackgroundImage(image, for: state)
    }
}

extension UIColor {
    var image: UIImage? {
        let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
        UIGraphicsBeginImageContext(rect.size)
        guard let context = UIGraphicsGetCurrentContext() else {
            return nil
        }
        context.setFillColor(self.cgColor)
        context.fill(rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}
```

UIColor から UIImage を作って、それを `setBackgroundImage` しています。

### 使い方

```
let button = UIButton(type: .system)
button.setTitle("button", for: .normal)
button.setBackgroundColor(.gray, for: .highlighted)
```

![Screen.gif](https://qiita-image-store.s3.amazonaws.com/0/5678/12cf77c1-81d7-0e6b-feef-5a8da642d29e.gif)

背景色が変わりました :tada:
【Rails】Heroku経験者がApp Engineでアプリを動かそうとする際の最初のハマりどころ

# はじめに
HerokuでRailsアプリを動かしたことがある経験者がGoogle App Engineでアプリを動かそうとする際、最初に遭遇することが多いエラーの解決方法について記録しておきます。

# 問題点
デプロイ成功後にブラウザからAppEngineのURLにアクセスすると「An unhandled lowlevel error occurred. The application logs may have details.」と表示される。

![AppEngine01.png](https://qiita-image-store.s3.amazonaws.com/0/141934/57b19cfd-512b-9f3b-2e5a-456716d5848c.png)

# 調査

AppEngine上で動作するアプリのログは`STACK DRIVER > ロギング > ログ`から確認することが出来ます。

![AppEngine02.png](https://qiita-image-store.s3.amazonaws.com/0/141934/e4bcdf04-0523-ee4f-c627-07cf499be445.png)

![AppEngine03.png](https://qiita-image-store.s3.amazonaws.com/0/141934/05c132d7-bb9d-778a-c022-7546b57f680f.png)

# 原因
ログの内容を確認すると、

```
#<RuntimeError: Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml`>
```

という一文が見つかるため、`secret_key_base`の設定漏れであることがわかります。

Herokuでは環境変数`SECRET_KEY_BASE`が自動的に設定されますが、AppEngineでは自分で設定する必要があります。

# 解決方法

secret keyを生成して、`app.yaml`に環境変数`SECRET_KEY_BASE`として追記します。

```shell-session
$ bundle exec rails secret
37e96b793ded332380ddbbf55f3435506af415fc1100ac34ab1a185c7e971a6b2f270143f2c714c33a4c376ebfacae09b4d96f0392b633c1e0326ba369ce88c2
```

```yaml:app.yaml
entrypoint: bundle exec rackup -p $PORT
env: flex
runtime: ruby
env_variables:
  SECRET_KEY_BASE: '37e96b793ded332380ddbbf55f3435506af415fc1100ac34ab1a185c7e971a6b2f270143f2c714c33a4c376ebfacae09b4d96f0392b633c1e0326ba369ce88c2'
```

再度デプロイを実施して他に設定漏れなどがなければアプリへアクセス可能になります。

![AppEngine04.png](https://qiita-image-store.s3.amazonaws.com/0/141934/0f4c3288-a32b-5788-5319-9ce9cf60b710.png)

# 公式ドキュメント
RailsアプリをAppEngineにデプロイする手順については公式ドキュメントにも詳しい解説があります。

[Running Rails 5 on the Google App Engine flexible environment  \|  Ruby  \|  Google Cloud Platform](https://cloud.google.com/ruby/rails/appengine?hl=ja)
Circle Ci + Node.js + Postgresql セットアップ


## Circle Ci 実行時の流れ
1. Environment　 : 環境変数を設定
2. Container postgres　: postgres コンテナを立てる
3. Checkout code　: github リポジトリからクローン
4. Restoring Cache　: キャッシュがあれば node_modules をリストア
5. node -v : node.js のバージョン確認
6. yarn --varsion : yarn のバージョン確認
7. yarn install : node module の インストール, キャッシュがある場合はスキップ
8. Saving Cache : キャッシュの保存

## 設定ファイルの解説

※の部分を解説していきます。

```config.yml
version: 2
jobs:
  build:
    docker:
      - image: node:8.5.0 ※1
      # specify the version you desire here
      - image: postgres ※1
        environment: ※2
          POSTGRES_DB: root
          POSTGRES_PASSWORD: root
          POSTGRES_USER: root

    working_directory: /var/www/html　　※3

    steps:
      - checkout　※4
      # Download and cache dependencies
      - restore_cache:　※6
          keys:
          - v1-dependencies-{{ checksum "package.json" }}
          # fallback to using the latest cache if no exact match is found
          - v1-dependencies-

      - run: node -v
      - run: yarn --varsion
      - run: yarn install

      - save_cache:　　※5
          paths:
            - node_modules
          key: v1-dependencies-{{ checksum "package.json" }}
```

### ※1 docker image の取得
node.js のバージョン8.5.0と postgres のイメージを取得してコンテナを立ててくれます。
### ※2 環境変数の設定
アプリケーションが postgres にアクセスする時に必要な環境変数の設定　
### ※３ steps に書かれたコマンドを実行するディレクトリ
checkout や run その他のコマンドを working_directory に指定したディレクトリで Circle Ciが実行します。
### ※4 リポジトリをクローン
先ほど指定したworking_directoryにリポジトリをクローンしてきます。

### ※5 キャッシュの保存
paths に書いたフォルダをキャッシュします。(今回はnode_modules)
key はキャッシュ保存時の package.json を hash 化しています。
この key は ※6 で使います。

### ※6 キャッシュのリストア
先ほど設定した key と実行時の key が同じであれば、キャッシュされた node_modules を使用します。
AndroidのMemory Analyzer用のhprofファイルをサクッと取る

メモリリークの調査のときは[Memory Analyzer(MAT)](https://www.eclipse.org/mat/)がやっぱり強力なので使いたい。でもAndroid StudioのProfilerからダンプしてhprof-convを叩くのは面倒。だからスクリプトにした。

```sh
#!/bin/sh

if [ -z "$1" ]; then
  echo "USAGE: dumphprof <package_name> [<out_file>]"
  exit 1
fi

date=`date '+%Y%m%d%H%M%S'`
temp_file="$1_${date}_orig.hprof"
output_file="$1_${date}.hprof"

if [ -n "$2" ]; then
  output_file=$2
fi

echo "dumpheap to /data/local/tmp/${temp_file}"
adb shell am dumpheap $1 /data/local/tmp/${temp_file}
while [ `adb shell run-as $1 lsof --  /data/local/tmp/${temp_file} 2>/dev/null| wc -l` -gt 0 ]; do
  sleep 1
done

echo "pull /data/local/tmp/${temp_file}"
adb pull /data/local/tmp/${temp_file}
adb shell rm /data/local/tmp/${temp_file}

echo "hprof-conv to ${output_file}"
hprof-conv ${temp_file} ${output_file}
rm ${temp_file}

echo "hprof file is pulled : ${output_file}"
```
GTX10series CUDAコア数まとめ

新しいGPU、1070Tiが新しくリリースされるらしいので、個人的に気になったことを調べてまとめてみました。

|プロセッサ|CUDAコア数|補助電源コネクタ|TDP|
|:-----:|:--:|:-------:|:--:|
|TITAN X|3584|8pin+8pin|250W|
|1080 Ti|3584|8pin+8pin|250W|
|1080   |2560|6pin+8pin|180W|
|1070 Ti|2432|?????????|180W|
|1070   |1920|6pin+8pin|150W|
|1060 6G|1280|     8pin|120W|
|1060 3G|1152|     8pin|120W|
|1050 Ti| 768|     6pin| 75W|
|1050   | 640|     6pin| 75W|
|1030   | 384|     None| 30W|

こういう表をたまに見たくなるんだけど、掲載しているサイトをブクマすることがなく、探し出すのに時間がかかるため作成しました。

補助電源コネクタが公式発表のものと、巷に出回っている製品で異なる場合があったので、ここでは価格.comで高いシェア率を誇るMSIのGAMING Xシリーズの補助電源を掲載しました。

**参考にしたもの**

NVIDIA公式
[Compare GeForce Graphics Card Specifications  | GeForce](http://www.nvidia.co.jp/graphics-cards/geforce/pascal/jp/compare)

価格.com  

[価格.com - MSI GTX 1080 Ti GAMING X 11G [PCIExp 11GB] スペック・仕様](http://kakaku.com/item/K0000956467/spec/)
[価格.com - MSI GTX 1080 GAMING X 8G [PCIExp 8GB] スペック・仕様](http://kakaku.com/item/K0000880927/spec/)
[価格.com - MSI GTX 1070 GAMING X 8G [PCIExp 8GB] スペック・仕様](http://kakaku.com/item/K0000884357/spec/)
[価格.com - MSI GTX 1060 GAMING X 6G [PCIExp 6GB] スペック・仕様](http://kakaku.com/item/K0000895014/spec/)
[価格.com - MSI GTX 1060 GAMING X 3G [PCIExp 3GB] スペック・仕様](http://kakaku.com/item/K0000902458/spec/)
[価格.com - MSI GeForce GTX 1050 Ti GAMING X 4G [PCIExp 4GB] スペック・仕様](http://kakaku.com/item/K0000919131/spec/)
[価格.com - MSI GTX 1050 GAMING X 2G [PCIExp 2GB] スペック・仕様](http://kakaku.com/item/K0000921006/spec/)

[価格.com - MSI GTX 1080 GAMING X+ 8G [PCIExp 8GB] スペック・仕様](http://kakaku.com/item/K0000960872/spec/)
[価格.com - MSI GTX 1060 GAMING X+ 6G [PCIExp 6GB] スペック・仕様](http://kakaku.com/item/K0000960873/spec/)
Wio LTE 開発で知っておいた方がいい話と、EC21-JへATコマンドを送る方法

先日から[発売が開始](https://soracom.jp/press/2017102501/)された [Wio LTE](https://soracom.jp/products/wio_lte/) の開発で知っておいたほうがいい話と、載っている [LTE Cat.1 モデム EC21-J](https://soracom.jp/products/ec21-j/) をチョットいじりたい人向けのエントリーです。

## Wio LTE について

Wio LTE は [Seeed Studioさん](http://wiki.seeed.cc/) が作っている

* STM32F4マイコン
* LTE Cat.1 モデム && nanoSIMスロット && 技適OKアンテナ
* Grove コネクタ 6つ (Digital:2 Analog:2 I2C:1 UART:1)

を搭載しているIoTのプロトタイプ向けデバイスです。

![Wio LTE](https://blog.soracom.jp/images/2017-10-25-wiolte/wiolte.jpg) 

※「Wio Tracker」や「Wio Node」じゃないです。お間違いなく。

## Wio LTE 開発で知っておいたほうがいい事

### シリアルコンソールの使い方

Arduino UNO では `Serial` を使って、例えば `Serial.println(String);` のようにシリアルコンソールに出力していましたが、Wio LTE は `SerialUSB` を使います。
`SerialUSB.println(String);` というように、メソッドは同じモノが使えます。

### LTE Cat.1 モデム(EC21-J)の扱い方

EC21-J は `Serial1` として扱うことができます。電源ONの後、初期化処理を行った後であればATコマンドを入れることができます。(それまでは受け付けてくれません)

初期化処理は https://github.com/SeeedJP/WioLTEforArduino で定義されているメソッドを使うのが一番楽です

* [`#PowerSupplyLTE`](https://github.com/SeeedJP/WioLTEforArduino/wiki/Reference-ja#powersupplylte)
* [`#TurnOnOrReset`](https://github.com/SeeedJP/WioLTEforArduino/wiki/Reference-ja#turnonorreset)

また、上記二つのメソッドを実行するとエコーバックがOFFになるため `ATE1` でエコーバックをONにしておくと色々捗ります
ATコマンドリファレンスは[QUECTELさん](http://www.quectel.com/)から入手してください(たぶんIDとか作る必要がある...かな?)

## 上記をやってくれるスケッチ

用意しておきました。

6/1/2020: [WioLTEforArduino/src/WioLTEHardware.cpp](https://github.com/SeeedJP/WioLTEforArduino/blob/aa7bd3a4836688e5354d91b521bed245356211b1/src/WioLTEHardware.cpp) で `SerialModule` を参照するようになっていたので追従。

```c:WioLTE-J_EC21-J_AT_debug.ino
#define BAUDRATE 9600

#define CONSOLE SerialUSB
#define EC21J SerialModule

#include <WioLTEforArduino.h> /*  https://github.com/SeeedJP/WioLTEforArduino */
WioLTE Wio;

void setup() {
  CONSOLE.begin(BAUDRATE);
  Wio.Init();
  Wio.PowerSupplyLTE(true);
  delay(5000L);
  if (!Wio.TurnOnOrReset()) {
    CONSOLE.println(F("### ERROR! ###"));
    return;
  }
  delay(3000L);
  EC21J.write("ATE1"); // echo back ON
  EC21J.write(0x0d); // send CR
  CONSOLE.println(F(">> Waiting for AT command"));
}
void loop() {
  if (EC21J.available()) {
    CONSOLE.write(EC21J.read());
  }
  if (CONSOLE.available()) {
    EC21J.write(CONSOLE.read());
  }
}
```

同じもの → https://gist.github.com/ma2shita/8a3a977223fd7f3154d4f38c75e29e49

### 実行結果サンプル

モデム内に格納されているAPN一覧を見る `AT+CGDCONT?` を実行した時の様子

```
>> Waiting for AT command

+CPIN: READY

+QUSIM: 1

+QIND: SMS DONE

+QIND: PB DONE

OK
AT+CGDCONT?
+CGDCONT: 1,"IPV4V6","internet","0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",0,0,0,0
+CGDCONT: 2,"IPV4V6","","0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",0,0,0,0
+CGDCONT: 3,"IPV4V6","ims","0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",0,0,0,0
+CGDCONT: 4,"IPV4V6","","0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0",0,0,0,1

OK
```

※Waiting for AT command の後の `+CPIN... ` とかを抑制できないものか。。。ちょっとカッコ悪いですよねぇ。。。

## あとがき

今日は土曜日。
Python | Numpy > xs, ys: np.array() に対してxsをソートする | ysもそれに合わせて並び替える

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
```

globを使用して複数のdirectoriesからファイルを読むとき、その並びが予想通りではなかった。
そのため、処理結果のリストを並替えする必要がある。

例として、以下を考える。

```
xs = [3, 1, 4, 2, 5]
ys = [1, 2, 3, 4, 5]
```

xsでソートして、それに合わせてysも並び替えるという処理。

### リンク

参考: https://stackoverflow.com/questions/9764298/is-it-possible-to-sort-two-listswhich-reference-each-other-in-the-exact-same-w


以下でできた。
(np.array()を使っているのは補間処理でnp.array()を処理するため）。

```test_cosort_171028.py
import numpy as np

xs = [3, 1, 4, 2, 5]
ys = [1, 2, 3, 4, 5]

xns = np.array(xs)
yns = np.array(ys)

xns, yns = zip(*sorted(zip(xns, yns)))

print(xns)
print(yns)

```

```txt:run
$ python3 test_cosort_171028.py 
(1, 2, 3, 4, 5)
(2, 4, 1, 3, 5)
```
Kubernetes on Bluemix のk8sバージョンアップメモ

# 概要
Kubernetes on Bluemixのクラスタを触っているタイミングで、Kubernetes APIのバージョンアップが利用可能という表記を横目で見つつも、テストの方が先で先延ばしにしてたバージョンアップをしてみました。

今後もkubernetesはどんどん進化しているので、今後も期待です。

※2017/10/28 なんかおかしいなーと思ってみてたら、worker nodeはアップデートされていませんでした。GUIでできるのはkubernetes APIのみで（ここではMasterAPIと呼びます）worker nodeは更新されません。CLIでの手順が必要なので追記です。

## Master API バージョンアップ手順
バージョンアップ対象となったクラスタにはダッシュボードで表示されます。
#### 1. バージョンアップの確認
更新ボタンをクリックする
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126158/bf821fda-fd12-f27a-c111-f1cb4b53bd7c.png)

#### 2. 更新の確認
デプロイメント用YAMLの更新が必要な旨表示される。
kubernetsのバージョンアップにともなって記述が変わるため、今までのものは使えなくなる場合があるよ。というお話。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/126158/fd25ca73-399c-9a34-174a-1d40f4d2ac42.png)

#### 3. 更新中
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126158/76aba2d2-4c2c-6e0b-9bc4-1d9a3af38ffe.png)

#### 4. 更新完了
きちんと計測してないですが、コーヒー入れてちょっとSNS覗くくらいの時間でデプロイ終わりました。（２～３０分？）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126158/3f180d5e-95e4-040a-c8e9-48d1fe943eef.png)

## CLIでのバージョンアップ確認
cliでの確認方法は以下のとおりです。が、pluginのバージョンが低くて最初表示されませんでした。

```bash
bx cs cluster-get {クラスタ名}
```
#### バージョンが表示されたパターン

![image.png](https://qiita-image-store.s3.amazonaws.com/0/126158/8757b6a4-1f69-fdf2-2901-69a78216f884.png)

#### バージョンが表示されないパターン
※プラグインアップデートするように表示が出ていますね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126158/15387560-b14e-cf9a-c8b8-ecff21c3ca5b.png)


## Worker nodeのバージョンアップ手順
#### 1. バージョン確認
ここで表示される「ID」部分をメモする。

```bash
bx cs workers {クラスタ名}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/126158/ed68f064-6ad2-d2b7-b4ea-318d2486c833.png)

#### 2. バージョンアップ
以下コマンドを入力しバージョンアップを行う。

```bash
bx cs worker-update {クラスタ名} {ワーカーノード名（ID）}
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126158/730a0e57-9d59-515e-8d13-ecf24ece1893.png)

#### 3. バージョン確認
ここで表示される「ID」部分をメモする。

```bash
bx cs workers {クラスタ名}
```


![image.png](https://qiita-image-store.s3.amazonaws.com/0/126158/8b78e376-53cf-294a-5eee-0e288dbee74e.png)



## メモ）bxコマンド container-serviceプラグインのアップデート
プラグインのアップデートを行います。
書くほどではないですが、、やったことメモということで。

```bash
bx plugin update container-service -r Bluemix
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/126158/c3764a2c-7f24-c19b-f957-3c8912f40dca.png)


## 最後に
やってみたよメモなので、内容が無いのですが、
1. kubernetesのバージョンアップ時にデプロイメントYAMLなどまわりが変わること
2. pluginのアップデートは恩恵を受けるものが多いことから見つけたらアップデートする
3. master側だけでなく、workerノードもちゃんとバージョンを確認すること（追記）
というところでしょうか。
テストコードの勉強などに役立つ記事・書籍

# はじめに

- 社内でテストコードを推進していこうという流れがあるので、 面白い、役立ったと思った本や記事のメモしました。
- 筆者のスキルセット
    - 今までテストコードやテスト自動化をしたことがなく、今の会社に入ってテストコードを書き始めて半年ちょっと
    - 言語はphp,javascript(node)が中心
- 前回まとめた記事
    - https://qiita.com/yutaChaos/items/857472c7d3c65d3cf316  
- まだまだ勉強中なので、テストに関する良い本や記事があったら是非教えて欲しい。（というかテスト本の情報をまとめた記事が欲しい）、随時更新予定

## 書籍

### テストコードの書き方

- テスト駆動開発
    - https://www.amazon.co.jp/dp/B077D2L69C
- レガシーコード改善ガイド
    - https://www.amazon.co.jp/dp/B01AN97W08 
- 実戦テスト駆動開発
    - https://www.amazon.co.jp/dp/4798124583  
- 初めての自動テスト
    - https://www.oreilly.co.jp/books/9784873118161/

### TDDやテストコードを取り入れた開発手法、チームビルディングの本

- Extreme Programing
    - https://www.amazon.co.jp/dp/B012UWOLOQ/
- アジャイルサムライ
	- https://www.amazon.co.jp/dp/B00J1XKB6K

## インターネット

### テストに関する記事
- TDDのこころ (t_wada)
	- https://www.slideshare.net/t_wada/the-spirit-of-tdd
- ［動画で解説］和田卓人の“テスト駆動開発”講座
	- http://gihyo.jp/dev/serial/01/tdd
- TDD is dead. Long live testing.
	- http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html

### 公式マニュアル
- phpunit マニュアル
	- https://phpunit.de/manual/current/ja/index.html  
- フレームワークの公式ドキュメント
	- laravel 
		- https://readouble.com/laravel/5.1/ja/testing.html 
	- symfony 
		- https://symfony.com/doc/current/testing.html  

### CIに関する記事
- GitLab CIでテスト・ビルド・デプロイを自動化する
	- https://qiita.com/toe/items/f47f383b9931a840a25c
- CircleCI 2.0 Beta における Docker イメージのビルド
	- http://lambdar.hatenablog.com/entry/2017/04/18/084900 

### テストに関する団体
- TDD Boot Camp(TDDBC)
	- http://devtesting.jp/tddbc/
- ソフトウェアテストシンポジウム (JaSST) 
	- http://www.jasst.jp/
twitter api で エラーコードを取得 invalid or expired token

twitterapi を使っていると、連携を解除される場合がある。
連携解除されているのに強引に動かすと


```

Exception: Invalid or expired token. in [/var/www/html/twitube.jp/vendor/mpyw/cowitter/src/Helpers/ResponseBodyDecoder.php, line 94]

```

といういんやらしいエラーに遭遇する。

これは laravel でも使える。

#解決する方法は？

try catch を使いましょう。
まずは、try catch を使いたい場面で

```

use \Exception;

```

を読みこみ。
で続いて処理

```

//  エラーだったらそのユーザーの expired を 1にする
    public function checkToken($option)
    {
        try{
            $res = $this->show($option);//ここで users/show の処理
        } catch (Exception $e) {
            $hoge = $e->getCode();
            print_r($hoge);//89なら expired
            die;
        }
    }


```

ってな感じですね。
さくらサーバーのPHPでftp拡張を使う

## 状況
[【さくらレンタルサーバー】基本仕様](https://help.sakura.ad.jp/hc/ja/articles/206053142--%E3%81%95%E3%81%8F%E3%82%89%E3%81%AE%E3%83%AC%E3%83%B3%E3%82%BF%E3%83%AB%E3%82%B5%E3%83%BC%E3%83%90-%E5%9F%BA%E6%9C%AC%E4%BB%95%E6%A7%98)にあるようにPHPのFTP関数はデフォルトで使用不可になっています。

phpinfo()やget_loaded_extensions()を使っても同様にFTPが利用できないことがわかります。

今回、ftp拡張を使う必要があったのでその方法を書きます。

## 方法
頑張ってグーグルで検索して、ここ[^1]とここ[^2]を見つけました。結論としてはphpizeというビルドツールが使えるということみたいです。

まずは[PHP:Releases](https://secure.php.net/releases/)からさくらサーバーのphpのバージョンのものをダウンロードします。(自分の場合2017-10-28現在で標準がPHP 7.1.9)

とりあえずそれを/home/[user name]/tmpへ入れたとしておきます。

まず展開して移動します。

```
% cd /home/[user name]
% mkdir php_modules
% cd tmp
% tar -xzvf php-7.1.9.tar.gz
% cd php-7.1.9/ext/ftp
```

次にビルドを行い、作られたmodulesフォルダのなかのftp.soファイルを先程用意しておいたphp_modulesフォルダに入れます。

```
% phpize
% ./configure
% make
% cd modules
% cp ftp.so /home/[user name]/php_modules
```

最後に、php.iniに追加して無事終了です。

```
extension_dir = /home/[user name]/php_modules
extension = ftp.so
```
## 参考資料
[^1]:[PHPにモジュールを追加するコマンドphpize-のぶろく](http://nob-log.info/2010/08/10/phpize/)
[^2]:[さくらのスタンダードプランでPHPのNet_FTPが動くようにする-Vimとボクと、ときどき、PHP](http://tti.matrix.jp/blog/2016-05-12/%E3%81%95%E3%81%8F%E3%82%89%E3%81%AE%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%80%E3%83%BC%E3%83%89%E3%83%97%E3%83%A9%E3%83%B3%E3%81%A7php%E3%81%AEnet_ftp%E3%81%8C%E5%8B%95%E3%81%8F%E3%82%88%E3%81%86%E3%81%AB/)
Numpy > Error > TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe'' > 対処

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
```

### 関連

[link > Python で 1 変量データ補間 > SciPy > interpolate.*](https://qiita.com/7of9/items/dbd21f4190fc3c0ee3e6)
[ADDA + Matplotlib > InitField-Y for various values of Re{m}](https://qiita.com/7of9/items/80db74708b4908745f09)

### エラー

ADDAの計算結果を補間しようとしたらエラーになった。

再現コードは以下。

```test_interpolate_171028.py
import numpy as np
import sys
from scipy import signal, interpolate

# on Python 3.5.2

xs = ['1.33', '1.41', '1.25', '1.69', '1.05', '1.85', '1.17', '1.37', '1.49', '1.65', '1.77', '1.53', '1.09', '1.81', '1.13', '1.61', '1.57', '1.29', '1.73', '1.21', '1.45']
ys = [-0.026233794340000002, -0.022115366130000001, -0.023346986680000001, 0.0098408259539999998, -0.0039200259860000001, 0.045906058600000001, -0.016363607209999999, -0.025000819000000001, -0.015049274919999999, 0.0016250158680000001, 0.031175279090000001, -0.01194725152, -0.0078601925140000008, 0.041183378409999999, -0.01215601187, -0.0044200969, -0.0086785273040000006, -0.02554396125, 0.019991008380000001, -0.020176115410000001, -0.018504119140000001]

print(xs, ys)

xns = np.array(xs)
yns = np.array(ys)

tt = np.linspace(1.1, 1.8, 51)
print(tt)

f3 = interpolate.interp1d(xns, yns, kind="cubic")
y3 = f3(tt)
```

```txt:run
Traceback (most recent call last):
  File "test_interpolate_171028.py", line 18, in <module>
    f3 = interpolate.interp1d(xns, yns, kind="cubic")
  File "/usr/local/lib/python3.5/dist-packages/scipy/interpolate/interpolate.py", line 488, in __init__
    if np.isnan(self.x).any():
TypeError: ufunc 'isnan' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

```

### 対処

参考: https://stackoverflow.com/questions/40809503/python-numpy-typeerror-ufunc-isfinite-not-supported-for-the-input-types

```
xns = np.array(xs)
```
を以下にすることでエラーを回避できる。

```
xns = np.array(xs, dtype=float)
```
Angularのapp.module.tsとは

実は知らず、有用な参考書に書いてあったのでまとめます(転記します)

<img width="960" alt="1.png" src="https://qiita-image-store.s3.amazonaws.com/0/201155/926fb96a-c6de-2530-626c-40b06a6af14e.png">

・import分：モジュールやクラスを読むこむ
・@NgModule：@NgModuleデコレーターを使い、構成要素を登録
・declations：declationsプロパティにコンポーネントを登録
・imports：@NgModuleに定義した他モジュールを読み込む
・bootstrap：最初に起動するコンポーネントを指定
・export class AppModule { }：NgModuleの設定情報をAppModuleとして公開

他に上の画像にはありませんが、
・providers：DI元となるクラス(Serviceとか)を登録
もありますね。

declations：components
imports：外部から取り込んだモジュール
providers：service
といったくくりでしょうか、、、、

[この本](https://www.amazon.co.jp/Angular2%E3%81%AB%E3%82%88%E3%82%8B%E3%83%A2%E3%83%80%E3%83%B3Web%E9%96%8B%E7%99%BA-TypeScript%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E5%9F%BA%E6%9C%AC%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E6%9C%AB%E6%AC%A1-%E7%AB%A0/dp/4822296539/ref=sr_1_5?ie=UTF8&qid=1506909588&sr=8-5&keywords=angular)を参考にしました。
「Vagrant」と「Virtual Box」の違い

プログラミングをやるにあたって避けては通れない環境構築ですが、最近やっと「Vagrant」と「Virtual BOX」の違いが分かったので書いておこうと思います。いろいろ自分なりに調べて、「Virtual BOX」は野球場で「Vagrant」は野球のチームのマネージャーという例えが書いてあったりしてしっくりきませんでしたが、すごく分かりやすい記事を発見しました。自分ではこれを見たら一発で理解したのでやっぱり書いている人によって全然違うなと感じました。

●初心者のための Vagrant, Chef, VirtualBox の関係
https://qiita.com/tomoemon/items/d4c4fe0c5afcb2482ee8

●この春エンジニアなった君に使って欲しいVagrant
http://tech.furyu.jp/blog/?p=2317

●・vagrantのネットワークについて
https://qiita.com/ftakao2007/items/0ec05c2ef3c14cdbea11

<h1>Vagrantについて</h1>
Vagrantは、「Virtual BOX」をいじるためのツールである。
<del>本当は、起動やシャットダウンをするのにはとても時間がかかるのだが、「Vagrant」というツールを使うことによってそれを簡素化できスピーディーにできて、なおかつ簡単である。</del>

指摘があり、修正させていただきます。

<blockquote>ちょっと高速化と誤解しそうなので補足します。
起動やシャットダウンにかかる時間が直接減るわけではありません。
周辺設定の手間を減らせるという意味で間接的に、時間がかからなくなるということは言えると思いますが。
Vagrantはざっくりいうと仮装マシンの設定自動化ツールです。
仮装マシンを使う場合、ダウンロードしたり仮装ネットワークの設定したり、RAM/ストレージの設定したり、必要なパッケージをインストールしたり、ファイアウォールやサーバーの設定したり、SSH設定したりと、色々やることがありますが、これらを設定ファイルに基づいて自動実施してくれます。</blockquote>
設定ファイルに基づいて自動的に実施してくれるということですね。
勘違いしていましたが、「直接的に高速化してくれるわけではない」ということですね。

<h2>vagrant fileについて</h2>
vagrant fileはどのBoxを使うのかどの Provisioner　を使うのかなどの設定するファイル
<h2>vagrant Box</h2>
Virtual Machine　の元となるテンプレートを追加できる。
Boxファイルは自分で作ることも出来る
<h1>Virtual Boxについて</h1>
仮想のPC。PCの中に仮想のPCを入れることが出来る。
持っているPCが壊れていてもすぐに復旧が出来たり、違うOSを動かせたりできることがメリット。