OmniAICreator/Qiita-1.07M huggingface dataset:
AWSで稼働中のEC2とRDSのインスタンスの一覧を取得できると管理が捗りました

<img width="936" alt="Screen Shot 2018-12-01 at 0.01.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/47327/1c47f2bf-dae7-9057-5d84-896bdcc46b09.png">

AWS便利ですね！re:Inventも盛り上がっているようで楽しそうです。
便利な半面AWSのインスタンス管理は大変です。
インスタンスの一覧を簡単に取得することで管理しやすくならないかなということで取得してみました。

https://github.com/yousan/aws_instance_list


```bash:aws_instance_list.sh
#!/usr/bin/env bash

PROFILE=${1:-default}

# 手動でのコマンド

# ヘッダー行書き出し
echo -e "リージョン\tタイプ\tIDや名前\tIPアドレスや作成者\tインスタンスタイプ\t状態"

for REGION in ap-northeast-1 us-east-1 us-east-2 us-west-1 us-west-2 ca-central-1 eu-central-1 eu-west-1 eu-west-2 eu-west-3 ap-northeast-2 ap-northeast-3 ap-southeast-1 ap-southeast-2 ap-south-1 sa-east-1 ; do
  # EC2のリスト取得
  aws --region ${REGION} --profile ${PROFILE} ec2 describe-instances --output text \
      --query 'Reservations[].Instances[].[Tags[?Key==`Name`].Value|[0],PublicIpAddress,InstanceType,State.Name]' \
      | sed -e 's/^/'${REGION}$'\tEC2\t''/g'
  # RDSのリスト取得
  aws --region ${REGION} --profile ${PROFILE} rds describe-db-instances --output text \
      --query 'DBInstances[].[DBInstanceIdentifier,MasterUsername,DBInstanceClass,State.Name]' \
      | sed -e 's/^/'${REGION}$'\tRDS\t''/g'
done

```

上記のコードを動かすと、CSV（タブ区切り）でEC2とRDSのインスタンスのリストを取得できます。

```bash
$ bash aws_instance_list.sh
リージョン	タイプ	IDや名前	IPアドレスや作成者	インスタンスタイプ
ap-northeast-1	EC2	hoge.l2tp.org redmine	192.0.2.1	t2.micro
```

`pbcopy`に渡してGoogleスプレッドシートなどに貼ると見やすいです。

```bash
$ bash aws_instance_list.sh | pbcopy
```

<img width="716" alt="Screen Shot 2018-12-01 at 0.06.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/47327/5d8394f6-761d-70a8-17d1-4732bb1499c2.png">

引数にリージョンとAWS CLIのプロファイルを渡せます。

```bash
$ bash aws_instance_list.sh ap-northeast-1 l2tp | pbcopy
```

GitHub上のコードを実行する場合には`| bash -s`で引数を渡します。

```bash
curl -s https://raw.githubusercontent.com/yousan/aws_instance_list/1bd5e0bae20de6201bf161b55b95e6059ece2f02/aws_instance_list.sh | bash -s ap-northeast-1 default | pbcopy
```

# 起動と修了
## RDS
RDSインスタンスの停止コマンドです。

```
aws default rds stop-db-instance --db-instance-identifier my-great-aurora-instance
```

インスタンス名がEC2のようなハッシュ値じゃないです。

# 出ている項目
現在はインスタンス名、IPアドレス（RDSならMasterUsername）、インスタンスタイプを出しています。AWS CLIの`--query`を調整することでカラムを変更できます。

# もっとやりたいこと

1. 料金の管理をしたいのでインスタンスタイプから概算料金を出したいです。
2. リージョン決め打ちなのでそこのループを回したいです。（現在は手動でループ）-> 解決しました

上記その他にヒントやアイディアがあれば是非教えてください！


# 参考サイト
[AWS CLIを使ってEC2インスタンスの情報を取得する - Qiita](https://qiita.com/toshiro3/items/37821bdcc50c8b6d06dc "AWS CLIを使ってEC2インスタンスの情報を取得する - Qiita")
2018年11月第5週　今週気になった記事まとめ

# 今週気になった記事まとめ
##■MicrosoftがAppleを抜いて「アメリカで最も価値の高い企業」に
https://gigazine.net/news/20181127-microsoft-apple-valuable-company/
MSのサービスや製品をOS除くとあまり意識させられる機会は無いので意外なニュース。
Appleの失速は知っていたけど、それをまくるのがMSってのはイメージしていなかった。

##■たった7行でテトリスを実装「七行プログラミング」とは
https://qiita.com/ryuichi1208/items/f9e6ac2b99bbe4fc82d3?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_itemshttps://qiita.com/ryuichi1208/items/f9e6ac2b99bbe4fc82d3?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_items
マジで動いた。
技術解説を見ても全然わからない。。。
ただ難解なことをやっているというよりはシンプルなことをひたすら効率的に詰め込んだって感じに見えるがどうなのだろう。


##■エンジニアがコミュニケーションを取るにあたってしてはいけないこと
https://qiita.com/hiroking815/items/194e95ff9040a85b7b96?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_items
幸いこういう上司にあたった経験はない。
自分自身もあまりこういう感じではないと思うけど、気を付けていきたい。
Swift：幅と高さを扱うときによくやってること

幅と高さを扱うときにいちいち`self.view.frame.width`とか書くのは嫌だし，かといってスコープごとに変数宣言するのもやなので，クラス内変数でよくやっていること

```swift
lazy var w: CGFloat = { return self.view.frame.width }()
lazy var h: CGFloat = { return self.view.frame.height }()
```
`lazy`をつけることで，初めて呼ばれたときに代入処理が行われる．`init`前に代入が行われないので良い．
ChromeDriver利用時の "EOFError: end of file reached" の対処

## 概要
RailsのSystemTestCaseや　RSpecのfeature specでChromeDriverを利用している時
`EOFError: end of file reached`
というエラーでテストが落ちる場合がある。
この対処法について記載する。

## 原因
Chromeのバージョンに対してとChromeDriverのバージョンが低すぎる可能性がある。
最新のChromeDrverを入れて再実行すると直る。

## Mac でのChromeDriverのアップデート

もしMacで、Homebrewを利用してChromeDriverをインストールしているなら、
一度ChromeDriverをアンインストールして、公式から入れ直す必要がある。
Homebrewでは最新のChromeDriverをインストール出来ないためだ。
下記コマンドで一度ChromeDriverをアンインストールする。

```console
brew uninstall chromedriver
```

その後、公式からChromeDriverのバイナリを適切な場所に配置してやることで、表題のエラーを解消できる。
http://chromedriver.chromium.org/downloads


## 参考
https://stackoverflow.com/questions/5244887/eoferror-end-of-file-reached-issue-with-nethttp
https://stackoverflow.com/questions/17243225/eoferror-end-of-file-reached-error-using-selenium-android-webdriver%60
https://stackoverflow.com/questions/16864579/watir-chrome-driver-eoferror-end-of-file-reached-error
ndenvを利用してnodeのバージョンを管理する

> [Deprecated] nodenv is better alternative
https://github.com/riywo/ndenv

**(追記)ndenvの代わりにnodenvを利用することをおすすめします。**


===========






nodeのバージョンをプロジェクトごとに管理したい場合があると思います。
nodeのバージョンが対応しておらずgulpの実行エラーが起きるときなどがいい例でしょう。

nodeのバージョン管理マネージャーには色々なものがあります。
その中のひとつに、Rubyのバージョン管理マネージャーで有名なrbenvに似た仕様をもつndenvというものがあります。

今回はndenvのインストール方法とndenvでnodeのバージョンを変える手順について説明します。

## [ndenv](https://github.com/riywo/ndenv)のインストール

```
$ git clone https://github.com/riywo/ndenv ~/.ndenv
```

もしくはHomebrewでもインストール可能です。

```
$ brew install ndenv
```

## ndenvのパスを追加
以下をシェルの設定ファイルに追加します。

```
echo 'export PATH="$HOME/.ndenv/bin:$PATH"'
echo 'eval "$(ndenv init -)"'
```

シェルの設定ファイルを変更したらシェルを再起動しましょう。

## [node-build](https://github.com/riywo/node-build)をインストール
node-buildはnode自身をインストールするためのnbenvのプラグインです。
node-buildをインストールすることで`nbenv install`コマンドが利用できます。

インストールは以下のようにします。

```
$ git clone https://github.com/riywo/node-build.git $(ndenv root)/plugins/node-build
```

## 利用するバージョンのnodeをインストールする
ndenvでインストールできるnodeの一覧を確認します。

```
$ ndenv install -l
```

インストールは`ndenv install`、ndenvで管理されているnodeの一覧は`ndenv versions`で確認できます。

```
### インストール前
$ ndenv versions
* system (set by /Users/toshiharu.nishina/.ndenv/version)

### インストール
$ ndenv install v8.1.0

### インストール後
$ ndenv versions
* system (set by /Users/toshiharu.nishina/.ndenv/version)
  v8.1.0
```

インストールしたらrehashをしておきます。

```
$ ndenv rehash
```


## nodeのバージョンを変更する

プロジェクト単位で管理する場合は`ndenv local`、グローバルで設定する場合は`ndenv global`とします。

```
### 変更前
$ node -v
v11.1.0

### バージョンの変更
$ ndenv local v8.1.0

### 変更後
$ node -v
v8.1.0

$ ndenv versions
 system
* v8.1.0 (set by /Users/toshiharu.nishina/git/legacy_design/.node-version)
```
本番環境での検証データをリセットしよう[Heroku]

# **はじめに**
アプリケーションを本番環境にデプロイした際、ユーザに使い始めていただく前に、バグが出ないかなど、色々と検証するためにデータを登録することがあると思います。
しかし、レコードとしてデータベースに登録されたデータを削除してからユーザには使い始めてもらいたいですよね。

私は、ユーザのid番号が途中から中途半場に始まるのを懸念してSQL文などで各テーブルレコードを削除しておりましたが、idを1から登録できることを今になって知ったので、備忘録として記録に留めておきます。

# **環境**
サーバー：heroku(ヘロク)
データベース: postgresql
利用アドオン：Heroku Postgres :: Yellow

# **データをリセット**

## **1. herokuにログイン**
<img width="1420" alt="postgresql-adjacent-51318___Heroku_Data.png" src="https://qiita-image-store.s3.amazonaws.com/0/269862/027df1d4-f3f6-2df5-b820-8f166631a285.png">

　`Reset Database...`をクリックして`アプリ名`を入力して、データを全て削除することができます。

## **2. コマンドを実行**

マイグレーションファイルを実行する

```
$ heroku run rake db:migrate
```

`csv`ファイルに初期データを入力している場合に限り、次のコマンドを実行

```
$ heroku run rake db:seed
```

下記コマンドのどちらでもデータベースにアクセスできます。

```
$ heroku pg:psql HEROKU_POSTGRESQL_YELLOW_URL

// datastores_nameは上の画像に表示位置が示されています
$ heroku pg:psql datastores_name --app アプリ名
```

アクセス後、次のコマンドでテーブルが表示されれば成功です。

```
$ \dt
```

PostgreSQLの利用を終了するために、データベースからの切断の操作を行なう。

```
$ \q
```

# **終わりに**
今回初めてPostgesqlを利用しました。
PostgesqlはSQL文全てをサポートしているわけではないので、あれ、うまくいかない。。なんてこともありましたが、
これから、実行可能なコマンドなどを含めキャッチアップしていこうと思います。
SQLで最急降下する

[信州大学 kstm Advent Calendar 2018](https://qiita.com/advent-calendar/2018/kstm)の4日目です

最近BigQueryやSQLServerに機械学習系のアルゴリズムが追加されてますね．
今回はSQLの再帰クエリを使って最急降下して遊びました．

## 最急降下法

関数$f(x)$について，以下の更新式で極値となるパラメータの値を求めます．

$$
x \leftarrow x - \eta \frac{\partial\mathcal{f}}{\partial x}
$$

ためしにSQLで次の関数を最小化してみましょう．

$$
y(x) = x^2 - 6x + 9
$$

$y' = 2x - 6$，学習率を$\eta=0.01$とするとこんなかんじ

```sql
with
    recursive gd(iter, x, y) as (
        select
            0, cast(0.0 as decimal(6,3)), cast(9 as decimal(6,3))
        union all
        select
            iter+1, x-0.01*(2.0*x-6.0), pow(x-0.01*(2.0*x-6.0),2)-6*(x-0.01*(2.0*x-6.0)) + 9 
        from
            gd
        where
            iter < 1000
            and y - (pow(x-0.1*(2.0*x-6.0),2)-6*(x-0.1*(2.0*x-6.0)) + 9) > 0.001
    )
select * from gd order by iter desc limit 1
```

結果は．．．

| iter | x | y |
|--:|--:|--:|
| 197  | 2.941  | 0.003 |

できた！


## 線形回帰もやってみる

$y \sim \mathcal{N}(a + bx, \sigma)$のようなデータを適当に作っておきます．
ここでは$a=1, b=-3$にしました．

![plot.png](https://qiita-image-store.s3.amazonaws.com/0/122937/ada4c3a3-3f5d-3fbc-6416-e4280ef5752a.png)




誤差関数と更新式は以下．
$$ \mathcal{L} = \frac{1}{2N} \sum_{i=1}^{N}(a+bx_i-y_i)^2 $$

```math
\begin{align}
\frac{\partial\mathcal{L}}{\partial a} &= \frac{1}{N} \sum_{i=1}^{N}(a+bx_i-y_i) \\
\frac{\partial\mathcal{L}}{\partial b} &= \frac{1}{N} \sum_{i=1}^{N}(a+bx_i-y_i)x_i
\end{align}
```

学習率$\eta=0.01$で，誤差の変化が$0.01$以下になったら終了するようにしました．

```sql

with
    recursive agg as (
        select
            sum(x) s_x,
            sum(y) s_y,
            sum(x*x) s_x2,
            sum(y*y) s_y2,
            sum(x*y) s_xy,
            count(*) n
        from lr
    ),
    gd(iter, a, b, loss) as (
        select
            0, cast(1.0 as decimal(10, 5)), cast(1.0 as decimal(10, 5)), cast(100.0 as decimal(10, 5))
        from lr
        union all
        select
            iter+1,
            a-0.01*(n*a+b*s_x-s_y)/n,
            b-0.01*(a*s_x+b*s_x2-s_xy)/n,
            (n*pow(a-0.01*(n*a+b*s_x-s_y)/n,2)
             +pow(b-0.01*(a*s_x+b*s_x2-s_xy),2)*s_x2
             +s_y2
             +2*(a-0.01*(n*a+b*s_x-s_y)/n)*(b-0.01*(a*s_x+b*s_x2-s_xy))*s_x
             -2*(a-0.01*(n*a+b*s_x-s_y)/n)*s_y
             -2*(b-0.01*(a*s_x+b*s_x2-s_xy))*s_xy)/(2*n)
        from
            gd, agg
        where
            iter < 5000
            and loss > 0.1
            and abs(
                loss-(n*pow(a-0.01*(n*a+b*s_x-s_y)/n,2)
                +pow(b-0.01*(a*s_x+b*s_x2-s_xy),2)*s_x2
                +s_y2
                +2*(a-0.01*(n*a+b*s_x-s_y)/n)*(b-0.01*(a*s_x+b*s_x2-s_xy))*s_x
                -2*(a-0.01*(n*a+b*s_x-s_y)/n)*s_y
                -2*(b-0.01*(a*s_x+b*s_x2-s_xy))*s_xy)/(2*n)) > 0.01
    )
select * from gd order by iter desc limit 1
```

結果はこちら


| iter | a | b | loss |
|--:|--:|--:|--:|
| 18 | 0.34115 | -2.84881 | 3.31067 |

![plot.png](https://qiita-image-store.s3.amazonaws.com/0/122937/0925c380-6b48-e2d4-368d-85814ae056c9.png)


いいかんじですね．

今回の実装を実行したnotebookは[こちら](https://gist.github.com/altescy/5731095e8b26507937d27fbf65ba0254)です．
【Rails5.2】プログラミング初心者(１ヶ月)がシンプルチャットアプリを作ってみた

プログラミング学習を始めて１ヶ月の超初心者が勉強のために自作のチャットアプリを作ってみたので、記録も兼ねて、作成までのプロセスを書き綴ろうと思います。

制作したアプリケーション↓
GitHub (https://github.com/f-tk-ttshp77/MeetPro)
HerokuURL (https://meetpro-v01.herokuapp.com)
※PC(Chrome推奨)のみで動作確認済
(その他解像度では激しく表示崩れしますのでオススメしません・・・)

# 最低限のプログラミング学習
初心者とは言っても、実はC言語やJavascriptなどを書籍での学習経験があったが、どちらも作ってみたい「モノ」（目的）が無いままに勉強してたので途中でモチベが保てずに挫折。
今回は作りたい「モノ」があったので以前のように途中で挫折することなくモチベも維持して勉強できた。
よく言われていることだが、プログラミング初学者にとって一番重要なのは、どの言語から学ぶが？どんな学習ツールを使うか？とかではなく、「何を作りたいか？」をよく考えることだということを実感した。
「モノ」ができるなら、どんなツールを使うかなどあまり関係ないと思う。
ということで、挫折しないなら十分独学でもイケると思い、使用した無料の学習ツール使うことにしたのでちょっとだけ紹介します。
#### Progate (https://prog-8.com)
開発環境を整える必要がなく、スグに学習し始めることができるe-learningって感じ。スグ動いてるとこを見れるし、ポップなスライドで説明してくれるとこが非常にナイス。一定数以上のレッスンを受けると有料会員登録(980円/月)しないといけないが、忙しい人でも１ヶ月で全レッスンやり切れる分量なのでコスパも良い。ただ、網羅性は高いとは言えないので本格的に学びたい人には向かないかも・・・
あと、言語によってレッスンの充実度に乖離があるのが難点
#### RailsTutorial (https://railstutorial.jp)
Rails勉強する人は誰でも知ってる基本無料のやつ。ブラウザ上で超分厚いRailsの学習本を読んでる感じの学習ツールで、なかなか詳しい。TwitterっぽいWebアプリの制作を通して本格的にRailsの勉強をしていく流れ。Progateでは教えてくれなかったテスティングの説明までしてくれるお節介な良いやつ。ただ、原著者の英語を翻訳したってこともあり、特に名詞の訳し方が微妙で少し分かりにくい部分があるのは否めなかった。
# チャットアプリ実装までの道のり
掲示板を作るのが勉強には良い(バックエンドも、フロントエンドもでいるという意味で)ということを聞いたので、それに少しオリジナリティを加えたツールを作ろうかなと思った。
日頃から、日本語特有の問題なのか、会議などの話し合いが上手くいっていないなと思う場面がよくあった。
事実を述べているのか、単なる感想や妄想を喋ってるだけなのかよく分からなかったり、くどくど言ってるけど結局賛成なんかよっ！みたいなこととか・・・
そういうことがなく、できるだけ建設的に会議ができるようになったらなぁと思っていたので、自分の発言に要約タグのようなものをつけながら会議ができたら少しはマシになるだろうと思って、タグをつけながらチャットできるツールを作ろうと思った。
あとはこれに必要な機能を実現するためにはどうしたらいいかをググって作った。

1. **リアルタイムチャットシステム**
→　どうやらリアルタイムチャッットのような非同期の双方向通信技術の一つに　WebSocketなるものがあるらしく、Rails5.0からそれの実装をシンプルに行えるActionCableなるものがあるらしい。いくつか記事も落ちてたのでこれでイケそう。
◆参考
[Action Cableでリアルタイムチャットアプリの作成方法 （Rails 5.1.4にて）（その１）　herokuで動かす！](https://qiita.com/Hijiri-K/items/c3774c72a2cb68e1a720)
[【Rails5.2】ActionCableとDeviseの欲張りセットでリアルタイムチャット作成](https://qiita.com/eRy-sk/items/4c4e983e34a44c5ace27)

2. **特定の人だけがチャットの閲覧権限を持つ**
→　各メッセージ、各ユーザー、各チャットルームを紐付けできれば表示の切り分けができそう。どうやらDBの紐付けは参照カラムを用意してあげればイケるらしい。
◆参考
[railsで多対多のアソシエーションの作り方と、出来ること](https://qiita.com/Kohei_Kishimoto0214/items/cb9a3d3da57708fb52c9)

3. **自前のユーザー管理セキュリティは不安**
→　どうやらDeviseなる便利なツールがあるらしい。これをベースにしてユーザー画像も設定できるようにしよう。
◆参考
[[*Rails*] deviseの使い方（rails5版）](https://qiita.com/cigalecigales/items/f4274088f20832252374)

・
・
・
みたいな感じで作った。

# 感想
### よかったこと
+ 公開までしようと考えていたおかげで、HerokuやらAWSのことについても知れた。ローカル環境と本番環境の仕様の違いを学べた。
+ 実際にモノを作ることでエラーとのお付き合いを知った。Qiita、teratail、StackOverflowは偉大。
+ 少ない知識でも実装までやりきる力が身についた感はある。(１個やばいif文書いたので親切な人が教えてくれたら嬉しかったりする)


### 反省点
+ テスティングを舐めて作らなかったのでエラー解決にかなり手間取った。（公開したものの、どこかでバグるんじゃないかと不安でしょうがない。）
+ メッセージが１行ものしか送れない仕様になってしまった。（気づくのが遅すぎた）
+ ところどころ非同期通信にできてない。
pythonを使ってdockerを操作

ゆるっとアドベントカレンダー Advent Calendar の1日目です
# Pythonでdockerを操作するためのライブラリ
基本的には[ここ](https://docker-py.readthedocs.io/en/stable/)を見れば解ると思います

```bash
$ pip install docker
```
をやったあとに

```python
import docker
```
をやれば読み込めると思う

# 使い方
```python
cli = docker.DockerClient(base_url="tcp://<dockerが動いてるホスト>")
```
これで使うことができる
あとは`cli`のメソッドを呼んで行く

## docker images
dockerのimageを取得する

```python
cli.images.list()

# [<Image: 'sasenomura/nginx:latest'>]
```
ちなみにオブジェクトがリストで渡ってくるため
各コンテナに対して操作をしたいときは
下の例ではtagを撮ってきている

```python
object_list = cli.images.list()
for i in iobjects_list:
            print(i.tags)
# ['python:latest']
# ['sasenomura/nginx:latest']
```
idを取りたいときは`i.id`とすれば取得することができる

## docker ps
コンテナの一覧を取得したいときは下の例
オブジェクトのリストが取得できる

```python
cli.containers.list()
```
すべてのコンテナを取得したいときは引数に'all=True'を入れて上げると'docker ps -a'のような結果になる
ちなみにコンテナのIDを取得したいときは

```python
container_list = cli.containers.list()
for i in container_list:
            container = print(i.id)
```
で取得することができる

# docker run

```bash
cli.containers.run(image="sasenomura/nginx:latest",
                                auto_remove=True, name="user_name_nginx")
```

引数を説明する
imageにはdocker imageを指定してあげる 
auto_removeにTrueを入れると`--rm`をつけたのと一緒になる

## docker exec

```python
container = cli.containers.get(<コンテナのid or コンテナのname>)
container.exec_run(cmd=cmd)
```
コンテナ内でコマンドを実行するにはあらかじめ`cli.containers.get`でコンテナのオブジェクトを取得しておく必要がある
オブジェクトからexec_run(cmd=cmd)をすることでコマンドを実行することができる
cmdには以下のようにするといいだろう

```python
cmd = "コマンド"
```
## docker rm

```python
container = cli.containers.get(<コンテナのid or コンテナのname>)
container.stop()
container.remove()
```
上と同様にコンテナのオブジェクトを取得してオブジェクトのremoveを呼び出す
念の為stopを呼び出している

以上です.

# おまけ

## docker rm $(docker ps -aq)

```python
container_list = cli.containers.list(all=True)
for i in container_list:
            container = cli.containers.get(i.id)
            container.stop()
            container.remove()
```
すべてのコンテナを消し去るときは↑のようにやるといいよ
Python で FPGA/Polyphony のインストール

# Polyphony をインストールしよう
Polyphony (ポリフォニー) はオープンソースです。誰でも自由に使えますし、改変できます。実際に仕事につかっても OK! です。

実際にインストールしてみましょう。Linux だとほらかんたん pip3 でインストールできます。

```text:インストール
shell$ pip3 install polyphony
shell$ polyphony -V
polyphony 0.3.3
```

2018 の最新の Polyphony は 0.3.3 です。-V でバージョンが出るので確かめてみましょう。

## 必要な環境は Python3.4 以降
インストールに必要な環境は Python3.4 以降です。他に依存していないので pip でインストールしても他の余計なライブラリはインストールされません。

## Windows でも大丈夫!!
Windows で Polyphony を使いたい場合は Windows 用の Python をまず最初にインストールしてみましょう。
Python3 のインストールは次の URL に詳しいのでそちらに譲りましょう。

https://www.python.jp/install/windows/install_py3.html

この例では Python 3.4 になってますね。

## Windows で Polyphony をインストール

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99921/7d6f28e9-acec-c398-ff4b-1b9ed1e9b28f.png)

Windows 10 で pip3 を使うには cmd をつかえばいい（のかな？。Windows を使いこなす人はもっといいほうほうをしっているかも。)

すでに Python がインストールされていたら py -V でそのバージョンが見れます。

```text:py-Vの例
C:\Users\user> py -V
Python 3.6.3
```

そしてインストール

```text:pipでインストール
C:\Users\user> py -m pip install polyphony
```

うまくいけば
C:\Users\<ユーザ名>\AppData\Local\Programs\Python\Python36\Scripts
の下に polyphony.exe がインストールされてます。


## polyphony のアンインストールと venv
試しに入れてみたけど消そうとおもったときは pip3 uninstall polyphony でアンインストールできます。

Linux や cygwin なら venv という方法で仮想環境を作る事も出来ます。
venv についてはこちらの記事を参照してください。
https://qiita.com/ryos36/items/7e7fce9078a79f782380
ncコマンドで作る簡易webhookデプロイサーバ


## ncコマンドとは
ncはnetcatの略で、TCP,UDPの生パケットを読み書きするコマンドである。
例えば、netcatでHTTPのリクエストを発行するには`echo “GET / HTTP/1.0\n”`とHTTPのリクエストをncコマンドにリダイレクトすることで実行できる
<img width="599" alt="Screen Shot 2018-11-30 at 22.59.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/65198/160eba67-7cbd-6543-a8c0-95166aa08bc6.png">
ncコマンドはクライアント側だけでなく、`-l`オプションでTCPサーバとして実行することができるのでここではこれを用いる

## webhookとは
Webhookは異なるサービス間でアプリケーションの更新情報などをリアルタイムで提供する概念である。
例えば、GitHubにはリポジトリにpushされたときに、指定したWebhook URLにHTTP POSTリクエストを送ってくれる機能などがある。

## GitHubにpushされた時に自動でデプロイする
`nc -l`はリクエストを受けた時にリクエストを標準出力しexitするため、nc -lに続けてコマンドを書くことで、リクエストを受けたタイミングでコマンドを実行することができる。
これを使って、
`nc -l 8080 && git pull origin master && docker-compose down && docker-compose up -d —build`という風に実行すると8080番ポートにhttpのリクエストが来ると最新のコミットを取得し、再起動することができる。
あとは8080に対するURLをGitHubリポジトリのWebhookに追加すれば自動デプロイが完成する。

## masterブランチだけ自動デプロイしたい
Masterブランチだけデプロイしたい場合は少し手順が面倒になる。`nc -l`が標準出力する内容は生のTCPなのでHTTP HeaderとHTTP Bodyが改行で区切られているだけのものが出力される
![Screen Shot 2018-11-30 at 23.17.33.png](https://qiita-image-store.s3.amazonaws.com/0/65198/7e51a3ec-c098-a83a-81b0-cd16face96dd.png)
そのため、HTTP HeaderとHTTP Bodyを分割し、HTTP Bodyをjqでパース(GitHubから送られてくるBodyはJSONなため）、ブランチ名を取得してmasterかどうか判断する必要がある。
布団乾燥機を分解修理

# 布団乾燥機
日立の布団乾燥機(HFK-VH500)のホースが壊れたので修理した記録です。
おそらくHFK-Vシリーズで同じような構造になってるかと思われます。

## 注意事項
* この記録はあくまで個人の記録でつけたものです
* よって、修理を保証するものではありません
* また、布団乾燥機は機械の性質上、高温の温風を出す機械です
* よって、分解や修理によって生じたいかなるトラブル・損失・損害についても責任を負いませんのでご了承ください
* 自己責任において参考にしてください。

# 直した経緯
* ホースが壊れたため
* テープで補強したけど次々にバラけていったので仕方なく修理を検討
* kakaku.comを見ても結構な人がホース壊れてた

## ホース購入
* https://hasiden.ocnk.net/product/1767 ここでホースを購入しました。
* 説明書っぽいのついてるかな？って思ったら業務用らしくホースだけ梱包されて届きました。

## 分解
![IMG_1124.jpg](https://qiita-image-store.s3.amazonaws.com/0/210754/d4662205-3669-3dde-e439-a6581b67f554.jpeg)
まず、表のフロントパネルを外します。
はめ込みになってるので力を入れなくても外せます。

![IMG_1125.jpg](https://qiita-image-store.s3.amazonaws.com/0/210754/523fe675-f406-e89a-4964-fd3eeea8e2d3.jpeg)
四方に円状のネジ穴があります。
少し長いドライバーじゃないと届かないかもしれません。
100円均のお得用ドライバーでギリギリ届くぐらいでした。

![IMG_1102.jpg](https://qiita-image-store.s3.amazonaws.com/0/210754/a22cf71a-8ee1-21a3-bcbd-37dce4c2856b.jpeg)
そうすると本体がごっそり外せます。
すごいホコリの量です。掃除機でそこそこ簡単に取れました。
この量のホコリを通して布団乾燥してたと考えると少し怖い、、、

![IMG_1103.jpg](https://qiita-image-store.s3.amazonaws.com/0/210754/2e995812-1aa8-dac0-8725-b94b6b1e4ed0.jpeg)
四方のネジを全部外すとまたカバーが外せます。
ようやく本体っぽいのが見えてきました。

![IMG_1104.jpg](https://qiita-image-store.s3.amazonaws.com/0/210754/a55189d8-fcd0-306c-17b2-6038eb7d284b.jpeg)
鉄板上のネジを4箇所はずします。
そして、ダクト近くから出てるケーブルを外します。


![IMG_1106.jpg](https://qiita-image-store.s3.amazonaws.com/0/210754/093b1dde-4fb0-bfcf-8c07-70564c188982.jpeg)
するとごっそり外せます。

![IMG_1105.jpg](https://qiita-image-store.s3.amazonaws.com/0/210754/82fbb674-5fc1-2a4e-c16d-cc40ce1aa458.jpeg)
あとはホース部分の黒い四角い所のネジを4箇所外します。
するとホース部分が外せます。
ダクト中央のケーブルは温度センサーっぽいので火事防止のためにも元通りつけ直してください。
決して外したままとかにしないでください。

あとは分解通りに戻すだけです。


# 総括
ホース壊れると自分で直すの面倒だけど直せなくはない。
メーカーさんはホースの着脱がもう少し楽になるように設計してほしい。
か、ホース壊れないようにしてほしい。

HEPAフィルターうたってるけど、実際ほとんどの空気は表じゃなくて内側から空気吸ってるなと。。。
だからホース壊れてなくても定期的に分解掃除が必要だなっと思った次第でした。
「行列式」を参考にWolframAlphaとSymPy Liveでやってみたい。


(オリジナルポスト)

https://qiita.com/sukapontan/items/be0c53867b4015c302ea

##WolframAlphaで
https://www.wolframalpha.com/input/?i=det%28%5B%5Ba%5B1%2C+1%5D%2C+a%5B1%2C+2%5D%2C+a%5B1%2C+3%5D+%5D%2C+%5Ba%5B2%2C+1%5D%2C+a%5B2%2C+2%5D%2C+a%5B2%2C+3%5D%5D%2C+%5Ba%5B3%2C+1%5D%2C+a%5B3%2C+2%5D%2C+a%5B3%2C+3%5D%5D%5D%29&lang=ja

#SymPy Liveで
勉強中



# 旧タイトル：sympyで「行列式(determinant)」をやってみた

リンク切れ
~~(参考)やっぱり線形代数は必要 #6 行列式=体積拡大率(2)~~


~~https://qiita.com/Jingorho/items/453fd5623ea396892ddb~~


(参考)Julia+SymPyで行列式が正しく求められなかった件
https://qiita.com/nyoi/items/b52bd5baefc2902812cf

#sympy

```fullscript.py
from sympy import *
M=Matrix([[2,1, 3,2],
          [6,6,10,7],
          [2,7, 6,6],
          [4,5,10,9]])
print(M)
print(det(M))
# Matrix([[2, 1, 3, 2], [6, 6, 10, 7], [2, 7, 6, 6], [4, 5, 10, 9]])
# -12
```

#Wolfram|Alpha
https://www.wolframalpha.com/input/?i=Matrix(%5B%5B2,+1,+3,+2%5D,+%5B6,+6,+10,+7%5D,+%5B2,+7,+6,+6%5D,+%5B4,+5,+10,+9%5D%5D)
Python で FPGA

#Python で FPGA を学ぼう、そして楽しもう
FPGA に興味があるけどちょっと敷居が高いかも、と思っている人向けに、Python をつかって FPGA を扱える方法 Polyphony（ポリフォニー) を紹介します。

今回は紹介の紹介です。インストールは次の日ね。

#FPGA を学ぶって？
FPGA に興味がある人はその向こうに”なにか”したいことがあるのだと思います。そのために FPGA を道具として使えるとよいですよね。FPGA で何ができるのでしょう？

##なんとなくハードウェア
ハードウェアや IoT が身近になるでしょう。"Lチカ"って言葉はご存じでしょうか？LED がチカチカ点滅するからそう呼ばれます。はじめてハードウェアにふれたひとが最初にトライする第一歩が"Lチカ"です。
FPGA を学ぶと"Lチカ"から始まるハードウェアよりのプログラミングを楽しむことが出来るでしょう。

##FPGA 難しそうだけど
Python がかければ FPGA が扱えます。Polyphony(ポリフォニー)はそういうツールです。FPGA のスタートに是非 Polyphony をつかってください。
実際の使い方も込みで紹介していきます。

##FPGA 持ってないんですが
大丈夫です。シミュレータで動きます。安価に手に入る FPGA も紹介したいと思います。
RaspberryPi 3 B(CentOS7)において、永続的な外部HDDのマウントをfstabなしで行った備忘録

#はじめの前に
以下の話はたぶんfstabを使えばなしで大丈夫です。
fstabをお使いください。
fstab参考: [uuidによるデバイスのマウント]( http://qpshinqp.hateblo.jp/entry/20110214/1297698515)

#はじめに
親がRaspberryPi3 Bを1年半ぐらい前に購入してきてたので、それでSambaを動かそうと思った。
そのためには外部HDDを持ってきて、そこへ読み書きするのが適切だろうということで、
弟用PCと化した旧鯖機でそのために使っていてこのために残していたHDDを、もってきてこれに繋いだ。
(記事の初稿は8月終盤だったのに、いつか投稿しようと思っていたらもう年末だった気持ちです。覚えてない…。)

#マウント方法
##手順
### マウント先フォルダの作成
`mkdir (マウント先フォルダ)`
`mkdir /data/` (←例)

### 接続ディスク名の確認
下記のどっちでも良いが、partedの方が見やすいと思います。
`fdisk -l`
`parted -l`

### マウントの実行
一般的な方法は下記だが、今回は永続的に行うためUUIDを用いる。
`mount /dev/(ディスク名) (マウント先フォルダ)`

####UUIDを利用したマウント

```
ls -al /dev/disk/by-uuid/ | grep sda
UUID: (UUID)
#UUIDの取得

mount /dev/disk/by-uuid/(UUID) /(マウント先フォルダ)
# または、
mount -U (UUID) (マウント先フォルダ)
```
<!-- UUIDを用いたマウントの参考: わすれちゃいました -->

### マウントの確認
~~書きたいけど忘れてしまった…。~~

### アンマウント
dfコマンドでアンマウントされているかを確認してから、
`umount (マウント先フォルダ)`

##再起動後のアンマウント
rebootするとアンマウントされ、再びマウントのコマンドを使わなければならなかった。

###autofs (使わなかった)
そこで検索をかけてみると、autofsを使うと良いと書かれた記事を発見したため、
これを用いたところ、/misc/の下にマウントされたが、トップレベルの階層を指定できなかったため使わないことにした。

```
yum install autofs

vi /etc/auto.master
# → miscのコメントアウトを外す。

vi /etc/auto.misc
data -fstype=ext4 :/dev/disk/by-uuid/(UUID)

ls -al /misc/(マウント先フォルダ)
```

##mount_data.serviceの利用
(面倒になったので省略します…)

```mount_data.service
[Unit]
Description=Mount Data.
After=network.target local-fs.target

[Service]
Type=forking
User=root
ExecStart=/bin/bash /～/mount.sh
ExecStop=/bin/bash /～/umount.sh
WorkingDirectory=/～/～

[Install]
WantedBy=multi-user.target
```

```mount.sh
#!/bin/bash
mount -U (UUID) /data
```

```umount.sh
#!/bin/bash
umount /data/
```
PySparkを試す 1日目

[gist](https://gist.github.com/kangaechu/28eeb5bf860d069981280cb51f240470)

## 動機

仕事でAWS Glueを使っている。、GlueはSparkが内部で動いており、PySparkで処理を記述することができる。
まだコードが満足に書けない中、実行に何分もかかると辛いのでローカルで動かないかなという感じ。

## やったこと

### PySparkの実行

ローカルにいろいろ入れたくないのでDockerから実行。

```bash
$ docker pull jupyter/pyspark-notebook
Status: Downloaded newer image for jupyter/pyspark-notebook:latest

$ docker run -p 8888:8888 -v /tmp/pyspark-notebook:/home/jovyan/work jupyter/pyspark-notebook start-notebook.sh
    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://(xxxxxxxxxxx or 127.0.0.1):8888/?token=34602879dbd346bbb1febcce60fb6558141fe707e639a1d7
```

Webブラウザで先ほど表示された http://localhost:8888/?token=34602879dbd346bbb1febcce60fb6558141fe707e639a1d7 (Tokenは毎回異なる)にアクセスする。

### PySparkの実行

`New->Terminal` で新しいノートを開く。

https://yubessy.hatenablog.com/entry/2016/12/11/095915
によると

- RDD
- DataFrame
- Dataset

の３つのAPIがあるらしい。DatasetはDataFrameの型安全版のため、PythonではDataFrameがメインみたい。

#### RDD

MapReduce?

```python
from pyspark.context import SparkContext
sc = SparkContext.getOrCreate()
rdd = sc.textFile("README.md").flatMap(lambda line:line.split("　"))
wordCount = (rdd.map(lambda word: (word, 1))
             .reduceByKey(lambda v1, v2: v1 + v2)
             .sortBy(lambda x: x[1], ascending=False))
wordCount.take(5)
```

```
[('', 9),
 ('  environment:', 3),
 ('  ports:', 3),
 ('  depends_on:', 2),
 ('    - spark-master', 2)]
```

#### DataFrame

Pandasみたい。

```python
from pyspark.sql import SparkSession

spark = SparkSession.builder.getOrCreate()
df  = spark.createDataFrame([(1,0), (0,3),(3,2),(4,8),(5,9),(3,3), (4,5),(4,4),],['col1', 'col2'])
df.filter(df.col1>0).groupBy(df.col1).count().show()
```

```
+----+-----+
|col1|count|
+----+-----+
|   5|    1|
|   1|    1|
|   3|    2|
|   4|    3|
+----+-----+
```


## 参考
http://cloudfish.hatenablog.com/entry/2017/12/23/001604
データの加工レイヤーとメッセージングの考え方



考えがまとまってないのですが重要だと思うことについて殴り書きます。
忘れてしまわないようにメモみたいな記事です。


##課題意識

ウェブアプリケーションの場合、最終的に画面にデータを表示します。
そのためには

データを取得 -> データの加工 -> データの表示
というプロセスを経ます。

もう少し細かくかくと、例えばAngularなどでは以下のようなプロセスを経ます

DB定義 -> クエリ -> Model -> Modelに対する処理 -> Controller -> Angularのモデル定義 -> AngularのService -> データ処理 -> コンポーネント -> Template

と長い経路を渡ります。

どの部分でどのようなデータ処理をするかを考えることがアプリケーション開発を考える上で肝となる部分です。

このデータ処理のロジックをどこに持つかの考え方に指針を提示する事は、開発効率を大幅に改善するきっかけになると思いました。なので、その事について思ったことを書いてみます。

##どのレイヤーでデータを処理するべきか

どのレイヤーでデータを処理するべきかについてですが、可能な限りDBに近い場所でデータを加工した方がシンプルになります。

必要なデータ処理がDBのレイヤーで行われていれば、後のレイヤーはただそれを Key ValueのペアのオブジェクトとしてそのままViewに返し、Viewに表示すれば良いだけです。

##じゃあ何故複雑になるの？

DBのレイヤーでデータが加工できれば一番楽です。

しかし、何故それが出来ないのでしょうか？

###理由1 DBの中に複雑なロジックを持つのが難しいため
一つ目は、DBの中で複雑で動的な処理を記述するのが難しいためです。
例えば、Mysqlで一つのrowでfirstNameとlastNameを参照したfullNameというgetter的なカラムを定義することはできません。getter的な挙動ができるのはクエリ文か、もしくはクエリを発行するためのModelにロジックを定義する事になります。

この時点で、DBに対してクエリを発行する事で得られる値と、モデルに対してメソッドにメッセージを送る事で取得できる値の2パターンのが存在する事になります。

Modelで持つには複雑すぎるロジックの場合は、更にコントローラーなどのレイヤーにロジックが登ってきます。

上で書いたようなレイヤーのどこでロジックを書くか、常にそれを頭に入れないといけない事になり収集がつかなくなります。

###理由2 メッセージを送るのがビューからになるため
取得したいデータ形式を決めるのはDBじゃありません。Viewです。DBから一番遠くにいるViewです。

データの加工をよりDBに近いレイヤーで実行するためにはクライアントで定義した情報が可能な限りDBのレイヤーまでシンプルに届く必要があります。

しかし、クライアント、ルーティング、コントローラー、モデルまでがシンプルで汎用性のある設計になっていなければ、取得したいデータの定義に関する情報は途中のレイヤーに止まってしまいます。サーバーサイドで処理することもあればクライアント側で処理するデータもあるといった歪な状態になってしまいます。


##解決のための設計方針
クライアントからのメッセージを可能な限りDBに近いレイヤーに届くためのインターフェイスを作る事です。

クラアイアントからのメッセージング(どのテーブルのフィールドを取得したいか、どのような件数を取得したいか、どのようなステータスのデータを取得したいかといった情報)がDBのクエリに届くように反映され、かつセキュリティー要件が満たされる事。

##そんな夢のような事できないよ
その通りだと思います。仮にセキュリティーを全く考慮しなくて良いならば世界に一つのDBに対してクライアントから直接クエリを発行するだけで済むかもしれません。

しかし、現実はそうではないので幾重にもレイヤーを重ね、各レイヤーで汎用的な処理を記述できるように頑張るのだと思います。

簡単ではないですが、基本的な方針としてはメッセージングが可能な限りDBの近いレイヤーに届くようにAPIを設計する事を考え、それを実現するための設計手法を得ていく必要があるのではないでしょうか。

##終わりに

殴り書きなのに読んでいただきありがとうございます。

CSSだけ、HTMLだけ、などの一つの機能を見ると処理の抽象化などが不要に見えるのですが、複数の機能の関係性を扱うと指数関数的に問題が難しくなります。

最初の頃はあまりプログラミングの設計力に意識が向かないかもしれないですが、少しでもいい設計への問題意識が高まると良いなーと思います。
Swift：左右のCommandキー同時押しを検出する方法

#はじめに
常駐型アプリを作っている際に左右のCommandキーやControlキーの同時押しでイベントを発火したくなった．
公開されているフレームワークでいいものが見つからなかったので，自作してみた．

#実装例
```swift:AppDelegate.swift
import Cocoa

let LEFT_COMMAND: UInt16 = 0x37
let RIGHT_COMMAND: UInt16 = 0x36

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    private var monitors = [Any?]()
    private var flagL: Bool = false
    private var flagR: Bool = false

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        func setMonitor() {
            monitors.append(NSEvent.addLocalMonitorForEvents(matching: NSEvent.EventTypeMask.flagsChanged, handler: { (event) -> NSEvent? in
                self.judge(keyCode: event.keyCode)
                return event
            }))
            monitors.append(NSEvent.addGlobalMonitorForEvents(matching: NSEvent.EventTypeMask.flagsChanged, handler: { (event) in
                self.judge(keyCode: event.keyCode)
            }))
        }
    }

    func applicationWillTerminate(_ aNotification: Notification) {
        for monitor in monitors {
            NSEvent.removeMonitor(monitor!)
        }
        monitors.removeAll()
    }

    func judge(keyCode: UInt16) {
        if !flagL && !flagR {
            if keyCode == LEFT_COMMAND {
                flagL = true
            } else if keyCode == RIGHT_COMMAND {
                flagR = true
            }
        } else if flagL && !flagR {
            if keyCode == LEFT_COMMAND {
                flagL = false
            } else if keyCode == RIGHT_COMMAND {
                flagR = true
            }
        } else if !flagL && flagR {
            if keyCode == LEFT_COMMAND {
                flagL = true
            } else if keyCode == RIGHT_COMMAND {
                flagR = false
            }
        } else {
            if keyCode == LEFT_COMMAND {
                flagL = false
            } else if keyCode == RIGHT_COMMAND {
                flagR = false
            }
        }
        if flagL && flagR {
            Swift.print("hello!")
        }
    }

}
```

どちらのCommandキーを先に押してもイベントが発火されるが，別の修飾キーも同時に押した場合でも発火してしまう（shift + left-command + right-commandなど)．
ReactのPortalを使ってみた

React 16では、[Portal](https://reactjs.org/docs/portals.html)という新機能が登場しています。

## 何ができるのか

Portalは、ReactのDOMノードの一部を、実際のDOMでは別な箇所にマウントできる機能です。使い方としては、

* ポップアップ・モーダルなど、全く別個でDOM上の位置を取りたいもの
* [バラバラな位置に入るサブコンポーネントをまとめて管理したい場合](https://qiita.com/tkrkt/items/7ce25a3afe07320af142)

などが考えられます。

## 使い方

ポータルは、`ReactDOM.createPortal`から作成します。

```js
ReactDOM.createPortal(コンポーネント, DOMノード[, key])
```

`コンポーネント`には、ポータルの中にセットするコンポーネント（単なるJSXでももちろんOK）を書きます。そして、`DOMノード`として、そのコンポーネントが実際に描画されるDOMノードを指定します。`key`は、他のReactエレメントにつける`key`と同じもので、大量のポータルを`.map`で一括生成する場合などに必要となります。

なお、`ReactDOM.createPortal`の結果自体も一種のReact DOMであって、**他のReactコンポーネントに埋め込んで描画する必要があります**。Reactの公式サイトには直接`render()`の返り値にする例がありますが、特にそれに限られません。


```jsx
render() {
  return (
    <div>
      {
        /* このように、子要素として埋め込むことも可能 */
        ReactDOM.createPortal(....)
      }
    </div>
  );
}
```

## 便利な点

上に挙げた記事のように、内部から`ReactDOM.render`を使うことでも、別の位置に出すコンポーネントを制御することは、できなくもないです。ただ、ポータルを使うと、いろいろ便利な点があります。

* ふつうに`render()`するだけでいいので、今表示中だったか非表示だったかなどを自前で管理する必要がない
* Reactの扱い上は、別な位置にあっても子コンポーネントになる
 * コンテキストもそのまま子で使える
 * イベントも親コンポーネントへバブリングする
 * Reactのデバッガでも、子コンポーネントとして表示される
１０年後も現場に必要とされるエンジニアになるために

# はじめに

最新の技術のキャッチアップに疲れてしまったあなた。
若い新人がすごく優秀で、抜かれるんじゃないかと毎日ビクビクしてるあなた。

朗報です。

この記事を読んで忠実に実践すれば、同僚から認められ、尊敬の眼差しで見られ
10年後も今の現場に必要不可欠な人材となることが出来るだろう。

もう辛い毎日とはおさらばだ。
さあ、始めよう。

# 第1章 名前

## 1.1 一般的ではない単語を使う

名前をつけるときは一般的ではない単語を使おう。
そうすれば、同僚に「あいつは英語の素養がある」と思わせて、あなたの株を上げることが出来るはずだ。

単語を調べる時にWeblioを使っていると、画面を見られた時に調べてることがバレてしまう。
なので、[Reverso Context](https://context.reverso.net/翻訳/日本語-英語/データを取得する)を使うことをお勧めする。

同僚からネーミングの相談を受けた時も、こっそりと使うことができれば完璧だ。

## 1.2 より抽象的に

他人に知的と思わせるには、本人にユーモアも必要だろう。

なので、名前をつけるときはその事柄を連想させる別の単語を使おう。


例を挙げると、

```scss

$gray: #8e8e8e;
$green: #0fa573;
$orange: #e3780c;
```

ではなく

```scss

$mouse: #8e8e8e;
$python: #0fa573;
$lion: #e3780c;
```

のように動物の名前を使った方が良い。

たとえ仕事中であっても、同僚にあなたが純粋に楽しんでプログラミングしてると思わせることが出来れば成功だ。

# 第2章 関数

## 2.1 ネストは出来るだけ深く

ネストは出来るだけ深くしよう。

```
function(a, b, c) {
  if (a === 1 && b === 2 && c === 3) {
    return 'it's bad code'
  }
}
```

よりも

```
function(a, b, c) {
  if (a === 1) {
    if (b === 2) {
      if (c === 3) {
        return "it's so good code"
      }
    }
  }
}
```

の方が良い。

同僚は、深すぎるネストを目の前にしても、微動だにしないあなたの姿を見て尊敬の眼差しを向けてくることだろう。

# 第3章 コメント

## 3.1 TBD


# 最後に

これまで紹介してきた手法も、リファクタリングという名目で直されそうになることもあるだろう。
もしプルリクエスト内でそういう変更を見かけたら、「リファクタリングは別PRで対応しましょう！」とコメントすることで回避することができる。
ChromeのシークレットウィンドウでCookieやLocalStorageが消えないとき

#クリーンな状態で閲覧できるはずなのに
CookieやLocalStorageを利用した開発・テストをしている際、
何度シークレットウィンドウを開き直しても、Cookie・LocalStorageのデータが残った状態になっており
作業にならなくなって困った事件……

#複数のシークレットウィンドウを開いていたのが問題だった
別のアプリケーションウィンドウの裏に、さっき自分で開いたシークレットウィンドウが残っていることに
しばらく気づいていなかったのだがこれが犯人だった。

#まとめ
シークレットウィンドウを複数立ち上げた状態で同じページを閲覧すると、
CookieやLocalStorageは残ったままになる。
自作ゲーム（HHK）で使用した技術共有

この記事は[Unreal Engine 4 (UE4) その2 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/ue4_zwei)の1日目です

１日目ですので軽めの話題にしましょうね


---

今年10月に行われた[ボイスロイドゲームジャム](https://itch.io/jam/voiceroid-game-jam)にて作成した、**Hyper Highspeed Kiritan**で作った処理のうち、応用がききそうなやつをいくつか紹介しようかと思います

ゲームは[こちら](https://t-sumisaki.itch.io/hyper-highspeed-kiritan)。
無料ですのでぜひ
![HHK   2018_10_21 0_05_30_Moment(2).jpg](https://qiita-image-store.s3.amazonaws.com/0/117589/f53cf68b-a493-1600-e5e6-b9fb25f8bb84.jpeg)

なお年末に[第2回](https://itch.io/jam/voicegamejam2)が行われます
興味がある方はこちらもよろしくおねがいします


以上、宣伝終わり！！
本編に入ります

---


# パイプ用プロシージャルマテリアル

パイプの模様（リング、ライン）は、プロシージャルなマテリアルを使用しています

HHKで要求した仕様としては以下の通りでした

- リング、ラインの数と幅は調節可能であること
- ゲームの進行に合わせて色を変化させられること

全体像はこちら
![image.png](https://qiita-image-store.s3.amazonaws.com/0/117589/56b069c4-d7e0-2579-760e-ea8bddd1778b.png)

リング、ラインの幅調整部分は以下の通り。
くっきりした形状が欲しかったので、ValueStepを使用して２値化しています
TilingScale、LineScaleのParameterを調整することで数と幅を調節できるようにしています
![image.png](https://qiita-image-store.s3.amazonaws.com/0/117589/e0ab4ad6-6978-3c25-7e81-012e752ce38e.png)

色の変化はMaterialParameterCollectionを使用しました
これ一つでパイプ全体の色を変更できるので、DynamicMaterialInstanceを使用するより楽に処理ができます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/117589/3ac2d017-b63f-2984-fbda-81a69b72e8df.png)


# パラメータのカーブ化

加速、減速時に使用する加速度パラメータは、直感的な調節が可能になるように、FloatCurveを使用しました。
カーブアセットを使用することで、
「低速状態から加速しやすくしたい」
「高速状態からの減速をしやすくしたい」
などの、感覚的な要求を満たしやすくなります。

0~1の範囲に収めるのは、Lerpと同じ感覚で使えるようにするためです。
この方法はわりとおすすめです
![image.png](https://qiita-image-store.s3.amazonaws.com/0/117589/d68f94c7-bf35-3437-983f-5b76601995fd.png)

また、カーブアセットは「変化量」を扱うパラメータに対してであれば広く応用がききます
下図のCurveはコースの最大湾曲率を指定するカーブアセットです（横軸はセクション数）
ちょっとコースが難しいな、と思ったときはこのカーブアセットを修正するだけで難易度調整を行うことが出来ます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/117589/3bdfaaf5-e6b8-cde2-3315-c9af54213799.png)


# 最適化関連

このゲームは一応最低限の最適化を施していますので、手持ちのAndroid端末に放り込んでも60FPSをキープすることが出来ています
（なお機種はGalaxyS9です。もうちょっと弱い端末でもたぶん大丈夫）

PCでも最低動作環境を満たしていない環境以外では正常に実行できています
（こちらはプロファイリング出来ていませんが…）

実行した最適化対応は以下のとおりです

- 可能な限りActorのTickを止める
- 事前生成するActor数を減らす
    - 事前生成して保持するセクション数を調節可能にしておく
    - SphereMaskを併用して、いきなり生成されたように見えないように工夫する
- 画面に映らなくなったActorを速やかにDestroyする
    - 後ろに通り過ぎた後は再表示することはまずないので

本当に最低限ですが、これだけでも十分に効果は出ます（特にDrawCall）


---

非常に軽い内容でした。

明日は我らがボス、[alwei](https://twitter.com/aizen76)さんの記事です
Ubuntu版VSCodeでPlantuml


使っていなかったノートPCにUbuntuを入れてみた。Windowsと異なる部分が多いため、これからなれて行きたいと考えている。
ノートPCの用途としては、軽いプログラミングの他に、ドキュメントの作成・編集(Qiita等を含む）を想定している。
これらの用途に便利な環境として、VSCodeが挙げられる。VSCodeならば、プログラミングのほか、plantumlを使ったドキュメントの作成もできる。そこで、


##VSCodeのインストール
ターミナルで以下のコマンドを打つ。

```
sudo apt -y install code
```
これで、VSCodeがインストールできる。

##javaのインストール
PlantUMLはJavaベースで動いているようだ。そこで、Javaもインストールする必要がある。

```
sudo apt -y install default-jre 
```

##Graphvizのインストール
次に、グラフ構造を描画する[Graphviz](https://ja.wikipedia.org/wiki/Graphviz)をインストールする。VSCode上でもインストールできるが、以下のようなエラーが発生し、plantumlが動作しない。

```
Dot Executable: /opt/local/bin/dot
File does not exist
Cannnot find Graphviz. You should try

@startuml
testdot
@enduml

or

java -jar plantuml.jar -testdot
```

そのため、きちんとaptからインストールしてあげる必要がある。

```
sudo apt -y install graphviz
```

あとはWindowsと同様にVSCode上でplantumlとgraphvizをインストールすれば良い。
具体的な方法は、以下の記事を参照してほしい。

##参考文献
[Ubuntu / DebianにコマンドでVSCode (Visual Studio Code) をインストールする方法](https://www.karelie.net/ubuntu-debian-command-install-vscode/)
[apt-getでJavaをインストールしよう(Ubuntu)](https://www.linuxmania.jp/apt-install-java.html)
[UbuntuのVimでGraphvizをプレビューする](https://qiita.com/mitsugu/items/96d4ce5878bee918102a)
なぜユニコーンは必要なのか

# この記事はOIC ITCreate Club Advent Calendar 2018の1日目の記事です。

こないだ
僕「なんでunicornは必要なん？nginxとrailsだけじゃあかんの？(幼女風」
と疑問をもち質問をしたところ
「一言では説明できない」
「なくてもいい」
「ラプラスの箱を探すため」
と幼女な僕にはわからなかったため、幼女でもわかるように自分で調べて解説してみようと思います。

## まずunicornとは

Unicorn is a Rack HTTP server to serve Ruby web applications on UNIX environment.　from [wiki](https://en.wikipedia.org/wiki/Unicorn_(web_server))

Unicornは、UNIX環境でRuby Webアプリケーションを提供するRack HTTPサーバです。

## Rack HTTPサーバとは
Rack is the magic that lets any of these app servers run your Rails app. (Or Sinatra app, or Padrino app, or…) from [Justin Weissさんの記事 A Web Server vs. an App Server](https://www.justinweiss.com/articles/a-web-server-vs-an-app-server/)

Rackは魔法です。Rackを使えばどのアプリケーションサーバーであってもあなたのRailsアプリケーションを動かすことができます。（Railsに限らず、SinatraやPadrinoであっても同じです）

## 考察
webサーバを置いてリクエストを捌くのが主流になっている。
rubyには多数のwebアプリフレームワークがあり、それら一つ一つをwebサーバに対応するとなるとwebサーバ側もwebアプリフレームワーク側も大変。
だったら中間者を置こう。 => Rack誕生
みんなRackと話せたらいいよね？
unicorn「Rackをよりよくしてやったぞ」 => unicorn誕生
多分こんな感じ、みんなハッピー

## 結論
unicorn is magic.
hide is youjo.
q.e.d

## 知見
Rackから静的コンテンツ返せるのか...どう使うんや？

### 参考リンク様
[Unicorn_(web_server) wiki](https://en.wikipedia.org/wiki/Unicorn_(web_server))
[Rackとは何か](https://qiita.com/k0kubun/items/248395f68164b52aec4a)
[第23回　Rackとは何か（1）Rackの生まれた背景](http://gihyo.jp/dev/serial/01/ruby/0023)
[Rack 実践 （Rack-based Application）](http://d.hatena.ne.jp/komiyak/20130418/1366276385)
[webサーバー、アプリケーションサーバー、Rackといった仕様や概念と、WEBrick、Unicorn、Pumaといった実装の関係が頭の中で結びつきません](https://ja.stackoverflow.com/questions/17813/web%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-rack%E3%81%A8%E3%81%84%E3%81%A3%E3%81%9F%E4%BB%95%E6%A7%98%E3%82%84%E6%A6%82%E5%BF%B5%E3%81%A8-webrick-unicorn-puma%E3%81%A8%E3%81%84%E3%81%A3%E3%81%9F%E5%AE%9F%E8%A3%85%E3%81%AE%E9%96%A2%E4%BF%82%E3%81%8C%E9%A0%AD%E3%81%AE%E4%B8%AD%E3%81%A7%E7%B5%90%E3%81%B3%E3%81%A4%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93)
[ApacheとNginxとPassengerとUnicornの違い【すごい初心者向け】](http://fujiike.hateblo.jp/entry/2015/08/20/170751)
[5分でわかるRack](https://route477.net/d/?date=20080716)
[Unicorn!](https://blog.github.com/2009-10-09-unicorn/)
[defunkt/unicorn](https://github.com/defunkt/unicorn)
GoogleEarthから3Dモデルをあっという間に生成する。(openMVG + openMVS)


 - きっかけ
 - データ用意
 - つくる
 - 見る

---

## きっかけ
はぁ。aphex twinのT69 CollapseのMVかっこいいなぁって思うことありますよね。はいあります。
そうすると、はぁ。街のモデルほしいなぁって思う事ありますよね。はいあります。(渋谷とかは街のfreeモデル配布されてたりします。)
正攻法としては[OpenStreetMap](https://www.openstreetmap.org/)を使うんだろうけど、OpenStreetMapではモデルデータない事とかあります。
そんなときに、「GoogleEarthの3Dモデル入手できないんか？？」って思いますよね。
どうやらUnityでGoogle Maps APIが使えるようになるらしいんだけど、問い合わせしないといけないしお金かかりそうだしとかで、お手軽じゃなさそうな感じです。
[リアルなゲーム \| Google Maps Platform  |  Google Maps Platform  |  Google Cloud](https://cloud.google.com/maps-platform/gaming/)

そういやAutoDeskのRemakeってアプリで画像データから3Dデータ生成できたな？
え？もうMac版のアプリ存在してない？（windows使えよ）まじかよ。
そんならそんなプログラムどっかにあるのでは。
あるんですよね。世の中の偉い方々ありがとうございます。

[openMVG(Open Multiple View Geometry](https://github.com/openMVG/openMVG/))
複数視点画像から3次元の点群を推定するぞってライブラリらしいです。
Structure from motionっていう手法らしい。

[openMVS](https://github.com/cdcseacave/openMVS)
そしてopenMVGで作った点群からさらに精密な点群を生成するのが
Multi-View Stereoってのらしくてそのライブラリ。

もろもろ詳しくはこのブログが参考になりましたありがとうございます。
NegativeMindさんありがとうございます。
[NegativeMindException | Multi-View Stereoによる3次元復元ライブラリ『OpenMVS』](https://blog.negativemind.com/2016/06/03/openmvs/)
[NegativeMindException | 複数視点画像から3次元形状を復元するライブラリ『openMVG』](https://blog.negativemind.com/2015/09/11/openmvg/)

こいつらを使って生成していきます。


## データの用意
google earthからquicktimeで雑に一周画面を録画します。

![anime.gif](https://qiita-image-store.s3.amazonaws.com/0/13338/3127ffa0-908b-a50e-a10f-b1523f569cf4.gif)


そして連番で画像ファイル作ります。作り方はなんでもok

```
ffmpeg -i tokyo_tower.mov -vcodec mjpeg -r 1 image_%03d.jpg
```

## つくる
こういうライブラリは環境作りが大変です。変なところで詰まると1日とか平気で消えます。
ぼくは専門家じゃないので詳しく知らなくて良いからとりあえず3Dデータくれっていう悪いエンジニア的思想から
「環境作るの面倒臭いなぁ。。せやDockerで環境ないんか」
あるんですありがとうございます。
[GitHub - rennu/dpg: OpenMVG + OpenMVS Pipeline](https://github.com/rennu/dpg)

まずclone

```
git clone git@github.com:rennu/dpg.git
cd dpg
```
そのあとはreadme通りに

```
docker build -t dpg .
```
します。

そして

```
mkdir images
```
imagesディレクトリ作って先ほどの素材を入れます。

```
.
├── Dockerfile
├── images
│   ├── image_001.jpg
│   ├── image_002.jpg
│   ├── image_003.jpg
│   ├── image_004.jpg
│   ├── image_005.jpg
│   ├── image_006.jpg
│   ├── image_007.jpg
│   ├── image_008.jpg
│   ├── image_009.jpg
│   ├── image_010.jpg
│   └── image_011.jpg
├── install
├── pipeline.py
├── scripts
   └── colmap_sparse_reconstruct.sh
```
こんな感じかな

```
docker run -v $(pwd):/datasets --rm -it dpg
```
でdockerを動かす。

```
/opt/dpg/pipeline.py --input /datasets/images --output /datasets/output_dense --flength 2553 --sfmtype incremental --geomodel f --runopenmvg --runopenmvs --densify
```
__※[2020/05/01] 最新のバージョンではoption名に変更があったようです。コメント欄を参照ください。__

でコマンド打って待ちます。画像多いと時間かかる。今回は5min待ちました。
--flength 焦点距離を指定するんだけど、カメラの場合はcmodel指定する。
とりあえず width * 1.2でも良いみたい。今回はそれで。

```
output_dense/omvs/scene_dense_mesh_refine_texture.ply
```
うまくいくとこいつができています。

## 見る。
MeshLabで見てobjとmlt吐き出して、
houdiniでみて見るとこんな感じ。

![anime.gif](https://qiita-image-store.s3.amazonaws.com/0/13338/e761e2fa-7a06-7de8-a77d-f5be28ebe00a.gif)

あ、あんまり綺麗でない。。
うまくできたりできなかったりするから色々調整して綺麗にできる方法探りたいですね。。教えてください。

はい。ではまた。
メソッドとレシーバについてのまとめ #golang

この記事は[Gopher道場アドベントカレンダー](https://qiita.com/advent-calendar/2018/gopherdojo)の1日目の記事です。

## ポインタをレシーバにする場合

Goでは次のように`type`で型を定義し、
レシーバを指定することでメソッドを定義することができます。

```go
type T int
func (t *T) M() {
    fmt.Println("method")
}
```

メソッドを呼び出すためには、次のようにセレクタでアクセスし呼び出します。

```go
type T int
func (t *T) M() {
    fmt.Println("method")
}

func main() {
    var t T
    p := &t
    p.M()
}
```

レシーバの型がポインタであれば、次のように呼び出しても構いません。
次の例では、`t.M()`は`(&t).M()`と同じように解釈されます。

```go
type T int
func (t *T) M() {
    fmt.Println("method")
}

func main() {
    var t T
    t.M() // (&t).M()と同じ
}
```

この例では`T`型にメソッド`M`が紐付いているわけではありません。
そのため、次のコードを実行すると`102030`ではなく`303030`が表示されます。

```go
package main

type T int
func (t *T) M() {
    fmt.Print(int(*t))
}

func main() {
    ts := []T{10, 20, 30}

    ms := make([]func(), 0, len(ts))
    for _, t := range ts {
        ms = append(ms, t.M)
    }

    // 303030と表示される
    for _, m := range ms {
        m()
    }
}
```

このコードを分かりやすく書き直してみると次のようになります。
`for`の中で`t`のポインタは常に同じなので、`(&t).M`もずっと同じメソッド値を
スライスに`append`していることになります。

```go
package main

type T int
func (t *T) M() {
    fmt.Print(int(*t))
}

func main() {
    ts := []T{10, 20, 30}

    ms := make([]func(), 0, len(ts))
    for _, t := range ts {
        // tはforの中でずっと同じポインタ
        ms = append(ms, (&t).M)
    }

    // 303030と表示される
    for _, m := range ms {
        m()
    }
}
```

元ネタ：https://twitter.com/inukirom/status/1065520332411363328

## メソッドセット

型`T`が持つメソッドセットと型`*T`の持つメソッドセットは次のようになっています。

* 型`*T`のメソッドセットには、型`T`のメソッドも含む
* 型`T`のメソッドセットには、型`*T`のメソッドセットは含まない

例えば、次の例の場合型`T`のメソッドセットは`f`のみですが、
型`*T`のメソッドセットは`g`だけではなく、型`T`の`f`も含みます。

そのため、`(&T{}).f()`などは実行できますが、`(T{}).g()`は実行できません。

```go
func (t T) f()  {}
func (t *T) g() {}
func main() {
	(T{}).f()
	(&T{}).f()
	(*&T{}).f()


	(T{}).g() // <- できない
	(&T{}).g()
	(*&T{}).g()
}
```

一方で、次のように`T{}`を一度変数に入れることにより、
`&t`のようにポインタを取れるようになるため、`t.g()`は`(&t).g()`と解釈されます。
しかし、あくまで型`T`のメソッドセットには、`g`は含まれないということには注意しましょう。

```go
func (t T) f()  {}
func (t *T) g() {}
func main() {
	// できない
	(T{}).g()

	// できる
	t := T{}
	t.g() // (&t).g()と解釈
}
```

Goではあるインタフェースのメソッドセットがある型のメソッドセットの部分集合のとき、
その型はそのインタフェースを実装していることになります。

そのため、次の例では、型`T`はメソッドセットに`g`を含まないため、
インタフェース`I`を実装していることにはなりません。

```go
type I interface { g() }
func (t T) f()  {}
func (t *T) g() {}
func main() {
	t := T{}
	// (&t).g()と解釈されるので呼べる
	t.g()

	// 型Tはgを持たないので代入できない
	var i I = t
}
```

## まとめ

このように、レシーバとポインタにまつわる問題は発見しづらいため、
レシーバをポインタにした場合は変数（ゼロ値で扱いたい時を除き）やスライスの要素はポインタにすべきでしょう。

[Gopher道場](https://mercan.mercari.com/entry/2018/06/14/113329)では、このように実際の業務でハマりやすいポイントを解説を踏まえながら説明するようにしています。
興味を持たれた方は次回の開催ではぜひ参加してみてください。
これだけ覚えろ！TOP7 コンテンツモデル（HTML5）

主要なコンテンツモデルは７つ。（HTML5）

#１.メタデータ・コンテンツ
ヘッドタグの中で使われる。

#２.フロー・コンテンツ
bodyタグの中で使われる。
bodyの中に配置出来るタグはほとんどこのフロー・コンテンツに該当する。

#３.セクショニング・コンテンツ
アウトラインを表す為のタグ。
HTML5ではとっても重要なコンテンツ。

#4.ヘディング・コンテンツ
h1-h6の見出しタグを指す。
※古い本などにはhgroup要素が記載されているが、実際はないので注意。

#5.フレージング・コンテンツ
主にテキストの一部の単語などに意味や役割を与えるコンテンツ。

#6.エンベディッド・コンテンツ
埋め込み型コンテンツを扱う要素。
ex)img要素,object要素

#７.インタラクティブ・コンテンツ
ユーザーが何かしらの操作が出来るコンテンツ。
ex)ハイパーリンクやクリックで状態が変わるものが該当する。
FuelPHPとプレゼンタとSmarty

プレゼンタを使うと、必要な処理をviewごとにコンパクトにまとめることができる。共用の処理と分離することができるので、デバッグもしやすくなる。

## Smartyで書かれたviewをプレゼンタと紐付ける

パーサとしてSmartyを採用しているケースで、ちょっと納得がいかない部分があった。

```php
View_Smarty::forge('default/index');
```
たとえば上記のようなコードをプレゼンタに置き換えるなら、

```php
Presenter::forge('default/index');
```

普通はこう書き変えるだけ。プレゼンタは`default/index.php`、viewも`default/index.php`となる。

でもSmartyを使う場合は、

```php
Presenter::forge('default/index.php','view',null,'default/index.smarty');
```
こう書く。Smartyなどのパーサを使う場合はプレゼンタとviewファイルの拡張子が違うため、引数ひとつですませることができない。

## 引数ひとつですませる方法

Viewを継承した形で使える`View_Smarty`があるように、Presenterを継承した`Presenter_Smarty`を作ると拡張子の違いを吸収できる。

```php
class Presenter_Smarty extends Presenter {
    public static function forge($presenter, $method = 'view', $auto_filter = null, $view = null)
    {
        return parent::forge(
                $presenter,
                $method,
                $auto_filter,
                \View_Smarty::forge($view.'.smarty'));
    }
}
```

coreの[Presenter](https://github.com/fuel/core/blob/1.8.1.6/classes/presenter.php#L36)を参考にして上記のようにPresenter_Smartyを作り、

```php
\Autoloader::add_classes(array(
    'Presenter_Smarty' => APPPATH.'xxx/presenter/smarty.php',
));
```

bootstrap.phpのadd_classesでフックする。これで完了。

```php
Presenter_Smarty::forge('default/index');
```

こう書ける。

## そもそも

公式のparserバッケージがプレゼンタに対応していないことがそもそもの問題なので、いずれプルリクを書いたりとかしたい。
PHP + Xdebugの表示が崩れたときのその場しのぎ

phpでの開発中、偶にXdebugのエラー出力がhtmlタグの中に入り込んでうまく表示されない場合があるので困る。
なので↓のhtmlを作ってみた。
https://salty-eyrie-60368.herokuapp.com/

ソース【[gistはこっち](https://gist.github.com/nanananamememe/4e887083d3e034faa1f9d86287ee3953)】

```html:xdebug.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta http-equiv="content-language" content="ja">
        <!-- 各自の環境に合わせて調整してね meta http-equiv="Content-Type" content="text/html; charset=UTF-8" -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
        <script>
            $(function(){
                $('#error_text').on('change, keyup', function(){
                    $('#error_view').html($('#error_text').val());
                });
            });
        </script>
        <title>HTML出力</title>
    </head>
    <body>
        <div>
            <textarea id='error_text' style="width:100%; height:500px;" placeholder="ここにエラーを貼り付ける"> 
            </textarea>
        </div>
        <div id='error_view'></div>
    </body>
</html>
```

たとえばこんなクソコード

```php:test.php
<p>これはテストです</p>
<p class="<?php array_merge(1,2); ?>">たとえばclass名をphpで出力したときエラーになると</p>
<p>困る</p>
```

勿論エラーになる。可読性低し。
![SS 4.png](https://qiita-image-store.s3.amazonaws.com/0/151490/df24af6c-975d-9498-ac72-db3da3ea31d3.png)

なのでhtmlソースを表示してエラー部分をコピー。
![SS 6.png](https://qiita-image-store.s3.amazonaws.com/0/151490/823f91a8-3014-d20a-c605-f416a3c7bfe6.png)

[さっきのサイト](https://salty-eyrie-60368.herokuapp.com/)でペーストしてみる。
![SS 7.png](https://qiita-image-store.s3.amazonaws.com/0/151490/e91bb68c-e194-609d-7414-d1fd3375bedd.png)

それっぽく表示されました。ハッピー。
Aidemy Premium Planで提供する仮想環境の仕組み

#概要
Aidemy Premium Planで受講生が使っている機械学習向けの仮想環境「Fastpyter」の仕組みについて説明します。
**本記事ではソースコード等は一切出てきません。**

#Fastpyterって？
Aidemy Premium Planで受講生が使っている機械学習向けの仮想環境です。
機械学習向けのスペックを持ち、機械学習でよく利用されるpythonのパッケージの大部分と、jupyter notebookがインストールされています。
また、 **各受講者ごとに個別のデータを保持することができます。**

#システムの概要
![資料ベース.jpg](https://qiita-image-store.s3.amazonaws.com/0/153926/64086ea8-7360-e5b2-9f69-e6f372d74197.jpeg)
この図をベースに説明します。

1. まずユーザーはインターネット上に公開されたフロントサーバーにアクセスします。
2. フロントサーバーで認証を行います。
3. 認証されたユーザーであれば、パブリックIPを持たない各自のVMにアクセスします。

Fastpyterの基本は、この３ステップで成り立っています。

#VMの制御
各個人が利用するVMのスペックは機械学習向けということもありとてもいい性能のものを利用しています。
そのため、インフラに詳しい方はお気づきかもしれませんが、維持費もものすごくかかってしまうのです。
（ずっと起動したままの場合月々およそ75,000円かかってしまいます。）

なので費用を抑えるため、必要な時だけVMを立ち上げ、不要になったらVMを削除する、という制御を行っています。
これはAzure Active Directoryを利用して実現しています。

#VM消したらデータはどうなるの？
さて、必要ないときはVMを削除するとなると、データの保存方法を考えなければなりません。
Fastpyterでは、起動時に各受講者専用の仮想ディスクドライブをマウントし、VMを削除してもそのディスクだけは削除せずに残しておくことで各受講者ごとのでデータを保持しています。

実物で例えると、毎回パソコンを組み立てて起動して外付けハードディスクを接続して、シャットダウンして外付けハードディスクを取り外してパソコンを分解する。そのようなイメージが近いです。

#今後の展望
Kubernetesに移行したい。
現在Fastpyterが抱えている１番の課題はVMの作成・削除の時間の長さです。Kubernetesのようなコンテナ技術を利用することで、VM作成・削除をより高速化してより快適な学習環境を提供できるようにしていきたいです。