OmniAICreator/Qiita-1.07M huggingface dataset:
エンジニアが非エンジニアのためにプログラミング言語の役割をまとめてみた

#はじめに
これからプログラミングを学習していくにあたり、まず言語それぞれの意味や役割を非エンジニアの僕が非エンジニアの方でもわかるようにまとめてみました！！

#HTML   *(Hyper Text Markup Language)*
Webページを作るための最も基本的な言語のひとつ。
HTMLでWebページに文字を表示したり、画像を貼り付けたりできる。
実は、いつも観ているWebページのほとんどが、HTMLで作られています。


#CSS *(Cascading Style Sheets)*
HTMLで作ったものに色や大きさや背景などを加えて見栄えを良くする言語。
Webサイトのデザイン担当。

#Javascript
スクリプト言語※のひとつ。
主にWEBサイトやWEBアプリ・サービスなどを開発するために広く使用されているプログラミング言語。
特徴としては、JavaScriptに対応したブラウザソフトがあれば、サーバーに負担をかけることなく実行できる事と特別な開発環境は要らず、HTMLファイルに書き込むだけで簡単に行える事。

※　スクリプト言語
コンピュータを制御する為のルールをまとめたもので、このルールに従って記述された命令の集まりのことです。

#Ruby
Rubyもスクリプト言語のひとつ。
Rubyは他のプログラミング言語に比べてシンプルで書きやすいのが特徴。
例えば、「こんにちは」という文字を画面（ブラウザ）に表示させるというプログラムをJavaとRubyで比較してみます。

【Javaの場合】

```java

public class Main {
             public static void main(String[] args){
              System.out.println("こんにちは")
        }
}
```



【Rubyの場合】

```ruby
puts "こんにちは"

```

このようにRUBYの方がJavaよりもソースコードの記述量が圧倒的に少ないですね。


#Ruby on Rails
Rubyで作られた、Webアプリケーションの骨格部分(フレームワーク)。
Ruby on Railsに機能や処理を追加するだけで、一つのWebアプリケーションを簡単に制作することができます。

#おわりに
僕は今プログラミングを絶賛勉強中なんですが、これから確実に学んでいくために、学習したことをじぶんなりにまとめ、こういった投稿を頻繁に行っていきアウトプットしていきたいと思いますので、よろしくお願いします！！
【AWSでサイト制作1】レンタルサーバーを選択

# ★ AWSでサイト制作シリーズ

1. [レンタルサーバーを選択](https://qiita.com/HitomiHoshisaki/items/033933f344a59e398b1f) **←今ココ**
2. [IAMを設定](https://qiita.com/HitomiHoshisaki/items/e5d738dbc72a990f6105)
3. [Cloud9×RailsでHello World！](https://qiita.com/HitomiHoshisaki/items/6a0cd17cbe57eb03277e)
4. [CodeStar×Railsで自動デプロイ](https://qiita.com/HitomiHoshisaki/items/b07c3788da7db7632656)
5. [独自ドメイン設定](https://qiita.com/HitomiHoshisaki/items/7d7345eb67390f16fed4)
6. [無料SSL化](https://qiita.com/HitomiHoshisaki/items/94c80e07a08efbee4c24)

※ 「Railsでサイト制作」シリーズから「AWSでサイト制作」シリーズに改名しました😌





# ■ あらすじ

私がWEBエンジニアになる前に、FC2で1つサイトを作りました。
「FC2ホームページ」「FC２ブログ」「FC2カート」の3サービスを使い、
デザインを無理やりそろえて一つのサイトに見せかけています。

▽ これな
http://kozuehp.web.fc2.com/

正直、とっても使いにくいです。。。
更新を頼まれても、ズルズルと先延ばしにしてしまっています:persevere:

せっかくWEBエンジニアを名乗るようになったわけですし、自前ですべて作り直したいと思います。
来月から転職先で Ruby on Rails を使うことになるので、その学習も兼ねたいところです！




# ■ 現状

以前はレンタルサーバーはロリポップを使っていましたが、
1年くらい前かな？同じ系列のヘテムルに変更しました。

ところがヘテムル、Ruby on Rails 非対応です:sob:
【参考】https://heteml.jp/support/manual/cgi/

今のところヘテムルを学習用に触ることはありますが、稼働中のサイトやサービスはありません。





# ■ 今回のゴール

んじゃ思い切って Ruby on Rails 対応のレンタルサーバーに引っ越してしまおうじゃないか！
私の利用目的に合ったレンタルサーバーはどこなんだぜ？と調べるところまでが、当記事のゴールです。





# ■ サーバーの種類

まずは「ruby on rails レンタルサーバー」でざっくりGoogle先生に質問。
おおまかな理解は以下のような感じになりました。

RailsでWEBサービスを作るなら、サーバーは大きく分類すると「VPS」とクラウドの2種類。
さらに、クラウドは「PaaS」と「IaaS」に細分化できる。
3パターンの中から選ぶことになる。

【参考】https://www.sejuku.net/blog/7117
【参考】http://find-server.net/ruby-on-rails-server/



## ◆ PaaS

Platform as a Service の略。
代表的なPaaSは「Heroku」。

アプリ公開がとっても簡単。
特別な設定をしないとサブドメインが必須になる。
細かい設定ができないので、大規模サービスだと使い勝手が悪くなることもある。



## ◆ IaaS

Infrastructure as a Service の略。
代表的なIaaSは「AWS」。

PaaSより細かく設定ができる。
でも専門知識がないと面倒くさい。



## ◆ VPS

Virtual Private Server の略。
代表的なVPSは「さくらのVPS」「GMOクラウド VPS」。

PaaSとIaaSのいいとこどり。
比較的安い&定額なことが多く、金銭的に分かりやすい。
細かく設定できる分、初心者だと面倒くさい。
あと、負荷分散や障害発生時の対策までは単独でできない。





# ■ 決めた！

結局「転職先がAWS使ってるっぽいから」って動機でAWSに決めました:relieved:
突然サービス停止になったりしなさそうなのもいいですね。
ちょっと学習が面倒臭そうだけど、がんばろっ。





# ★ AWSでサイト制作シリーズ

1. [レンタルサーバーを選択](https://qiita.com/HitomiHoshisaki/items/033933f344a59e398b1f) **←今ココ**
2. [IAMを設定](https://qiita.com/HitomiHoshisaki/items/e5d738dbc72a990f6105)
3. [Cloud9×RailsでHello World！](https://qiita.com/HitomiHoshisaki/items/6a0cd17cbe57eb03277e)
4. [CodeStar×Railsで自動デプロイ](https://qiita.com/HitomiHoshisaki/items/b07c3788da7db7632656)
5. [独自ドメイン設定](https://qiita.com/HitomiHoshisaki/items/7d7345eb67390f16fed4)
6. [無料SSL化](https://qiita.com/HitomiHoshisaki/items/94c80e07a08efbee4c24)
C++で画像を作る用のライブラリサーベイ

## 概要

C++でグラフや、スペクトログラムや、美麗な画像とかを作りたかったので、サーベイしました。

### 対象読者
- C++で美麗な画像を作りたい方

### 結論

[CImg](https://github.com/dtschump/CImg)を使えばOK
※ 実際に使ってみたら変わるかもしれませんが

### 成果物

さっそく美麗なスペクトログラムを作りました。導入が簡単ではかどりました。
![test.png](https://qiita-image-store.s3.amazonaws.com/0/115870/e1be8f04-2f16-c828-6aaa-56c99fc86e63.png)


## 要件

- 必ずやりたいこと
  - ピクセル単位で画像をいじれる
  - pngかbmpで出力できる
- できればやりたいこと
  - テキスト描画
  - 各種美麗なエフェクト
  - アンチエイリアスのかかった美麗な線を引く
  - 簡単にグラフを描ける
- 導入が楽
- ライセンスはサーバー側で使った場合に、ソースコードを公開しなくても良いやつ

## サーベイ

### OpenCV

導入がめんどくさそうなのでなしです。

### cairo

https://www.cairographics.org/

ホームページがダサくてgithubがメインになっていないので、古そう。

### Ion

https://github.com/google/ion

github star 1325
かっこよさそうですが、今回の要件に必要ない依存が増えそう。

### libigl

http://libigl.github.io/libigl/
https://github.com/libigl/libigl
github star 1257

3Dのメッシュとかをいじる系で、今回の要件にあわなそう。

### PANDA3D

http://www.panda3d.org/
3D系。要件にあわなそう。

### partio

https://github.com/wdas/partio
A library for particle IO and manipulation。要件にあわなそう。

### libgd

https://github.com/libgd/libgd
github star 367

なにかで2011年頃に使った記憶がある。なんだっけ？
C++かRubyで使った記憶がある。
独自Captchaだっけ？

使用感は普通
https://libgd.github.io/manuals/2.2.5/files/preamble-txt.html

### CImg

https://github.com/dtschump/CImg
http://cimg.eu/
github star 537

>CImg is self-contained, thread-safe and highly portable. It fully works on different operating systems (Unix,Windows,MacOS X,*BSD,...) and is compatible with various C++ compilers (Visual C++,g++,clang++,icc,...).

導入のしやすさでは良さそう。

使用感
http://cimg.eu/reference/group__cimg__tutorial.html
表示機能も内包しているみたい。

http://cimg.eu/CImg_slides.pdf
できることが紹介されているスライド。
pngにも対応しているらしい。

### Generic Image Library

https://www.boost.org/doc/libs/1_56_0/libs/gil/doc/index.html
boostに含まれているのか。
CImgより優れたポイントがないなら、調べる必要なさそう。

### Magick++

http://www.imagemagick.org/script/magick++.php
CImgより優れたポイントがないなら、調べる必要なさそう。

## まとめ

[CImg](https://github.com/dtschump/CImg)が以下の点で良さそう。

- 導入しやすい
- 最低限やりたいことを満たしている
- 線とかテキストとかも描ける
PythonでWikipediaの表を2行でスクレイピング

# HTMLの表をスクレイピングして行列データにする処理

今回は行列計算ライブラリはPandasを利用します。
そうすると、なんと`read_html()`関数が用意されています。

https://note.nkmk.me/python-pandas-web-html-table-scraping/

これを使うと、2行でスクレイピングができます。

```py
import pandas as pd
pd.read_html( <URL> )
```

ただ一つ難点があり、ヘッダがデフォルトでは読まれず、単なる行として例えば1番目の行に読み込まれてしまいます。
なので、**単なる行ではなくヘッダです**と指定する必要があり、下記のようにします。

```py
dfs = pd.read_html(<URL>, header=<行番号>)
```

たとえば、[Wikipediaの日本の都市の表](https://en.wikipedia.org/wiki/List_of_cities_in_Japan)をスクレイピングするには、こうします。

```py
WIKI_URLWIKI_UR  = "https://en.wikipedia.org/wiki/List_of_cities_in_Japan"
dfs = pd.read_html(WIKI_URL, header=0) # set header with row #0
```

[サンプル](https://github.com/onelittlenightmusic/python_graphql_scraping_example/blob/master/scraping%20to%20GraphQL.ipynb)

この関数は内部で有名なスクレイピングツールbeautifulsoup4を利用しています。
生でbeautifulsoup4を使う方法はこちら。

https://qiita.com/Azunyan1111/items/9b3d16428d2bcc7c9406

# Pandas行列を整形して利用しよう

行や列を追加する方法は以下。`dataframe['列名']=値`を使う。
http://sinhrks.hatenablog.com/entry/2014/11/12/233216

行や列を削除する方法は以下。`drop`関数を使う。
https://note.nkmk.me/python-pandas-drop/

# ソースコード

https://github.com/onelittlenightmusic/python_graphql_scraping_example
【Unity】コマンドライン引数で単一ビルドに複数ビルドの振る舞いをさせる


# はじめに

この記事は[Unityゆるふわサマーアドベントカレンダー 2018](https://qiita.com/splas_boomerang/items/e6619fb1e6dd92fd231f)の18日目です！
(あと2枠余っているのでぜひ！)

あるUntiyプロジェクトからビルドしたアプリを、複数の設定で立ち上げたい場合がありました。
例えば、起動直後のシーンを異なるものにしたり、デバッグモードで起動したいような場合です。

コマンドライン引数とショートカット（エイリアス)を利用することで、単一のビルドで複数のビルドがあるような振る舞いに出来るので、その方法を紹介したいと思います。

製品として出すようなものへの使用は難しいと思うので、あくまで開発効率化の方法としてご覧ください。

# 手順

Windowsを例に紹介しますがMacでも同様のことが可能です。

## 動作環境

Unity2018.2.1f1
Windows

## コマンドライン引数で設定を変える

ビルドの起動時にスペース区切りで任意の引数を与えることができます。
test.exeがあるディレクトリでコマンドラインを開き、以下のようにすることで`-mode`と`1`という引数を渡すことができます。

```
./test.exe -mode 1
```

この引数をUnityで取得するためには、`System.Environment.GetCommandLineArgs()`というメソッドを利用します。以下はサンプルです。

``` Test.cs
public class Test : MonoBehaviour
{
    void Start()
    {
        string[] args = System.Environment.GetCommandLineArgs();
        for (int i = 0; i < args.Length; ++i)
        {
            switch (args[i])
            {
                case "-mode":
                    int mode = 0;
                    if (i + 1 < args.Length && int.TryParse(args[i + 1], out mode))
                    {
                        // do something
                    }
                    break;
            }
        }
    }
}
```

今回の例では`-mode`の後ろに値(`1`)を入力する形にしました。こうすることで、コマンドライン引数の順序に依存せずに値を指定できるようになります。順番が決まっているようなら、`./test.exe 1`というような指定でも良いかと思います。

また、コマンドライン引数を渡さずに起動する場合もあると思うので、渡されなかった場合の挙動は想定しておいた方が良いと思います。

## コマンドライン引数付きのショートカット(エイリアス)の作成

毎回コマンドラインを叩くのは面倒だと思うで、ショートカットを作っておくと便利です。
ビルドしなおしてもパスが変わらなければ大丈夫なので、初めに一度作って置くだけです。

まずExplorerでビルドのあるフォルダを開きます。
world-client.exeの上で右クリックをしてショートカットを作成を選択します。

ショートカット上で右クリック→プロパティを開くと、「リンク先」という項目にビルドのパスが書かれているので、そこにコマンドライン引数を追加していきます。
スペース区切りで任意のコマンドライン引数を設定しましょう。

ショートカットの名前は、設定を表すものにしておくと良いかと思います。


# おまけ：便利そうな起動時のコマンドライン引数

フルスクリーンにするかどうかの指定
例: `-screen-fullscreen false`

ウィンドウサイズの指定
例: `-screen-height 114 -screen-width 514`

スクリーンの品質の指定
例: `-screen-quality Beautiful`

同時に起動できるインスタンスを1つにする指定
例: `-single-instance`


参考：[コマンドライン引数 - Unity マニュアル](https://docs.unity3d.com/ja/current/Manual/CommandLineArguments.html)
RaspberryPiでPython3とMatplotlib使ってリアルタイムグラフ描画

# はじめに
このサイト見て試してみたらすんなりは動かなかった。
[【Matplotlib】リアルタイムグラフの速さ（更新間隔） | アルゴリズム雑記](https://algorithm.joho.info/programming/python/matplotlib-realtime-change-speed/)

# 試行錯誤
まず、こんなエラーメッセージがでた。

```
/usr/local/lib/python3.5/dist-packages/matplotlib/backends/backend_gtk3agg.py:16: UserWarning: The Gtk3Agg backend is known to not work on Python 3.x with pycairo. Try installing cairocffi.
  "The Gtk3Agg backend is known to not work on Python 3.x with pycairo. "
TypeError: Couldn't find foreign struct converter for 'cairo.Context'
```

`cairocffi`って何なのかわからんけど、とりあえず入れてみた。

```
sudo pip3 install cairocffi
```

まだ、エラー出る。

```
TypeError: Couldn't find foreign struct converter for 'cairo.Context'
```
調べると、こんなんひっかかる。
[TypeError: Couldn't find conversion for foreign struct 'cairo.Context' · Issue #221 · rbgirshick/py-faster-rcnn](https://github.com/rbgirshick/py-faster-rcnn/issues/221)
[ノート - FrstGt](https://sites.google.com/site/frstgt/note)
[Python で matplotlib を試そうとしたら 'cairo.Context' ってナニソレ - Qiita](https://qiita.com/5ara5treamer/items/4bf82ada81a3cb30beed)

環境によって対応策違うのかもしれないけど、
`python3-gi-cairo`入れたら良さそうだったので試した。

```
sudo apt-get install python3-gi-cairo
```

これで、実行できた。よかったよかった。

# おわりに
どういう依存関係かよくわからんけど、とりあえず動いてよかった。
TODO: 以外のアノテーションコメントをまとめた

# アノテーションコメントとは
- コメントにメタデータを付加するものです。
- コードの欠陥がわかりやすくなります。

~~~python
# TODO: 変数aがNoneの時、呼び出すときにエラーを吐くことの対応
~~~

# まとめの経緯
アノテーションコメントを書くときに`TODO:`ばかり使用していて、`TODO:`ほどじゃないんだけどなぁ...みたいなことがありまして、他にわかりやすいアノテーションコメントはないだろうかと思いまとめました。
微妙に解釈が異なる可能性があります...


# よく使われる記法と意味

|記法|意味|
|:--:|:--:|
|TODO:|あとで追加、修正するべき機能がある。|
|FIXME:|既知の不具合があるコード。修正が必要。|
|HACK:|あまりきれいじゃないコード。リファクタリングが必要。|
|XXX:|危険！動くけどなぜうごくかわからない。|
|REVIEW:|意図した通りに動くか、見直す必要がある。|
|OPTIMIZE:|無駄が多く、ボトルネックになっている。|
|CHANGED:|コードをどのように変更したか。|
|NOTE:|なぜ、こうなったという情報を残す。|
|WARNING:|注意が必要。|

## VS Codeだと
https://github.com/Gruntfuggly/todo-tree
ファイルに点在しているTODOなどのメモを一覧で見ることができます。
Todo tree: Add Tagを設定するだけで、タグを追加できます。デフォルトでは`TODO`,`FIXME`のみですが、簡単にアレンジすることができます。

![image2](https://raw.githubusercontent.com/Gruntfuggly/todo-tree/master/resources/screenshot.png)

## Atomだと
`TODO`, `FIXME`, `CHANGED`, `XXX`, `IDEA`, `HACK`, `NOTE`, `REVIEW`, `NB`, `BUG`, `QUESTION`, `COMBAK`, `TEMP`, `DEBUG`, `OPTIMIZE`, and `WARNING`がアノテーションコメントとして認識されて、ハイライトされます。

さらに、todo-showというパッケージをインストールすると、ファイルに点在しているTODOなどのメモを一覧で表示してくれます。
https://atom.io/packages/todo-show
JupyterNotebook　プログレスバー・進捗確認Tips

私は営業ですが、提案材料や各数値の分析でJupyterNotebookを使うことがあります。

スクレイピングする時なんかは進捗具合が分かると作業が楽になるので、確認の方法をまとめておきます。

エンジニアの方だと当たり前すぎる内容だと思いますが、非エンジニアだとプログレスバーという言葉すら知らずに触っていると思うのでご参考まで。

他にいいやり方があれば、是非教えて下さい！

#進捗確認Tips
まず下準備

```python
import time
```


###1.　printで処理ごとに表示
僕のような初学者はこれで十分かもしれません。笑

```python
for i in range(100):
    time.sleep(0.1)
    if i % 10 == 0:
        print(i)
```
▼　JupyterNotebook
<img width="353" alt="スクリーンショット 2018-08-18 22.39.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/244525/e653dcce-91da-1f33-f26f-a52478b96eb8.png">


###2.　tpdmを使う
tqdmが一番使われているプログレスバーかと思いますが（知らんけど）、range部にtqdm（）します。
ノーマルのものとリッチなものを、2つ紹介。

```python
from tqdm import tqdm

for i in tqdm(range(100)):
    time.sleep(0.1)
```
▼　JupyterNotebook
<img width="425" alt="スクリーンショット 2018-08-18 22.39.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/244525/569f1bdb-6f4b-0891-8472-acdd4bf6c5d3.png">



```python
from tqdm import tqdm_notebook as tqdm

for i in tqdm(range(100),desc='進捗具合', leave=False):
    time.sleep(0.1)
```
desc='進捗具合', leave=False　このオプションでラベル付けと、処理が終わった時にプログレスバーが非表示になります。

その他オプションは、画像つきのコチラで見れます。
https://github.com/tqdm/tqdm/tree/master/images

▼　JupyterNotebook
<img width="532" alt="スクリーンショット_2018-08-19_13_10_30.png" src="https://qiita-image-store.s3.amazonaws.com/0/244525/c0c43380-6926-2443-7ebf-b14a7600b80b.png">


###3.　FloatProgressを使う
FloatProgressは、min-maxで枠を作って、valueでiずつ動かしてdisplayで表示しているので、ちょっとめんどくさい。

色を変えたり、その他引数はコチラを参照。
https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20List.html

```python
from IPython.html.widgets import FloatProgress
from IPython.display import display

fp = FloatProgress(min=0, max=100, description='進捗具合:')
display(fp)

for i in range(100):
    time.sleep(0.1)
    fp.value = i
```
▼　JupyterNotebook
<img width="465" alt="スクリーンショット 2018-08-18 22.50.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/244525/27cc5b44-35e6-0595-654e-c8965e201f09.png">

###4. 分割した処理の時間を計算して、目安時間を出す
これはちょっと色が違いますが、マジックコマンドで1/10ぐらいに分割した処理の時間を測って、おおよその全体時間を予想する。

```python
%%timeit
for i in range(10): #1/10の処理
    time.sleep(0.1)
```
▼　JupyterNotebook
<img width="474" alt="スクリーンショット 2018-08-18 22.56.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/244525/235975df-24e6-7dc4-2fcf-5e8d23ad3d5a.png">
予想...（この処理で1秒ぐらい...全体で10秒ほどかな...?）


※マジックコマンドについてはこちらの記事を参考にさせていただきました。
http://www.procrasist.com/entry/6-jupyter




順次更新予定です!
Keras/Tensorflowをimportしたら"Illegal instruction (コアダンプ)"と出た時の対処法

##症状
```python

import keras #バックエンドがTensorflow
#もしくは
import tensorflow
```
と打つと

```
Illegal instruction (コアダンプ)
```
と言われてPythonインタプリタごと落ちる。

##発生環境
ある程度古いCPUを搭載したマシン（AVX命令をサポートしていないCPU)で
Tensorflowバージョン1.6以上を使用
私の環境ではAMD A8-3850 with RadeonHD 6550D

##原因
おそらくTensorflow==1.6からpipで降ってくるものがAVX命令に対応したCPUのものになってしまった。
##対処方法
Tensorflowのバージョンを1.5にダウングレードします。

既存のTensorflowをアンインストールします。

```
pip uninstall tensorflow
```

tensorflow v1.5(以下)を指定してインストールします。

```
pip install tensorflow==1.5
```

##確認
Pythonのインタプリタに入って

```python

import keras #バックエンドがTensorflow
#OR
import tensorflow
```
と打ち、前述した症状が現れなければ成功です。

##追記
condaを使ったインストールならTensorflow 1.5以降でも大丈夫なようです。
conda(anaconda,Miniconda)をインストール済みの方は以下のようにしてください。

```
pip uninstall tensorflow #既にTensorflowをインストール済みの方はこちらも実行

conda install tensorflow #バージョンを指定しなくても良い
```
AWS Cloud9 で IDE画面へ接続できなくなった場合の対処法（Connecting...から遷移しない）

#環境

* windows10 64bit 
* AWS Cloud9　(無料枠使用)

    * EC2 instance type : t2.micro
    * Memory : 1 GiB
    * vCPU : 1 

#症状
Cloud9のIDE画面を開こうとするも、ずっと「Connenting...」が表示され続けてIDE画面へ遷移しない。

#条件（原因、トラブル前の操作、状態など）
終了直前にIDEのコンソールでシャットダウン処理を試みた痕跡あり。

1. Cloud9を使用（Rubyの学習）
2. Cloud9を操作後、休憩のため操作中のファイルを保存。  
コンソールでIDE終了できるかな？と思って`sudo shutdown now`を試みるも失敗  
（「ここだとシャットダウンできないよ」見たいなポップアップを見た気がする。）
3. よくわからなくなったので、３０分後の自動シャットダウンを期待してブラウザを閉じる。
4. 約1時間後、作業再開のためCloud9へアクセス。
5. 症状発生。（Cloud9のIDE画面が開かない）

#解決策
**⇒インスタンスの再起動**
1. コンソールのホーム画面＞EC2＞インスタンス
2. 動作がおかしいインスタンスの”ステータスチェック”の項目に異常マークを確認
3. インスタンスを選択して、右クリック＞"停止"
（初めに”再起動”を試みたが反応なし）
4. インスタンスが停止するまで待つ（約5分かかった）
5. インスタンスのステータスがStopしたことを確認して、”開始”を実行
6. しばらく待って、Cloud9へ接続でIDE画面が現れる。

#参考
[【turorial】AWS Cloud9で作成したEC2インスタンスにSSH接続](https://qiita.com/d778980/items/c115a7d1a5b6177666e0)

Cloud9へSSH接続を試みようと上記の記事を参照。
ES2のインスタンス画面を開いたところステータスの異常に気が付いた。
Visual Studio Code の CSS を見やすくカスタマイズしてみました (2)

普段、Visual Studio Code を Markdown エディタとして利用していますが、見出し (特に、h2 と h3) がちょっと判別しにくいのが気になっていました。

[以前の記事](https://qiita.com/08thse/items/205eea7ed85188ae38bf)で、markdown.styles で CSS を読み込ませていたんですが、セキュリティ的な事情で思うような動作ができなくなってしまったので、後継を考えてみました。

## Markdown Preview Enhanced

https://shd101wyy.github.io/markdown-preview-enhanced/#/

追加のカスタマイズも容易だし、すごく便利。便利なのですが、欠点がひとつだけ。

ネットワーク共有 (例：\\\\fireserver\folder\file.md) 上のファイルは、ネットワークドライブを割り当て (例：Z:\\folder\file.md) てやらないと、上手く動作しない[制約](https://github.com/shd101wyy/markdown-preview-enhanced/issues/751)がありました。

本記事の公開時点では、まだ改修はされていない様子。ちょっと仕事では直接ネットワーク共有指定で書くことが多いので、出番は少なめ。上記の制約が関係ない人にとっては、かなり良い拡張機能かも。

## Markdown Preview Github Styling

https://marketplace.visualstudio.com/items?itemName=bierner.markdown-preview-github-styles

上記の制約を回避しつつ、妥協できるくらいの見た目。とりあえずのプレビューはコレで良さそうです。

しかし、この拡張機能だけでは、エクスポート (HTML) 時の出力ファイルには反映されません。

## Markdown All in One (CSS 編集)

さて、前述の HTML 化には、[Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one) を利用しています。

この拡張機能は、カスタマイズした CSS の読み込みには対応していないようでしたので、使っている CSS を探してみました。

`C:\Users\<UserName>\.vscode\extensions\yzhang.markdown-all-in-one-1.6.0\media\markdown.css` がそれっぽいですね。

ということで、そのファイルを一部追記してみました。個人的好みですが、下記の通り。

```css

h2 {
  padding-bottom: 0.3em;
  line-height: 1.2;
  border-bottom-width: 1px;
  border-bottom-style: solid;
  border-bottom-color: whitesmoke;
}

h3 {
  text-decoration: underline;
}

pre, code {
  background-color: whitesmoke
}

```

h2 は長めの下線、h3 はテキストの下線、あとは引用のブロックに背景色をつけました。網羅的な確認はしてないので、へんなところに影響が出たらすみません ^^;
StanとRでベイズ統計モデリング(アヒル本)をPythonにしてみる - Chapter 6 練習問題

[実行環境](https://qiita.com/shngt/items/ce6f2c3ef348cd80f432)

### インポート

```python
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
```

## (1)

```python
np.random.seed(123)

bernoulli_rng = np.random.binomial(1, 0.2, size=10)

categorical_rng = np.random.randint(1, 6, size=10)
```

## (2)

```python
np.random.seed(123)

beta_rng = np.random.beta(2.0, 2.0, size=5)

dirichlet_rng = np.random.dirichlet((0.3, 1.0, 1.0), size=5)

gamma_rng = np.random.gamma(3.0, 1.0, size=5)

bivariate_normal_rng = np.random.multivariate_normal((0, 1), np.array((2, 1, 1, 3)).reshape((-1, 2)), size=5)

cauchy_rng = stats.cauchy.rvs(loc=1, scale=2.5, size=5)
```

## (3)

```python
np.random.seed(123)

y1 = np.random.normal(loc=50, scale=20, size=2000)
y2 = np.random.normal(loc=20, scale=15, size=2000)
y = y1 - y2

sns.kdeplot(y)
plt.show()
```
![chap06ex3.png](https://qiita-image-store.s3.amazonaws.com/0/103085/a04ddfbb-4c57-ceb1-c481-d4c8fa1e752a.png)
opensslのTLS1.3のDraftの対応状況を調べてみた

TLS1.3のRFCが発行されましたね。
せっかくなのでTLS1.3での通信を手元の環境で構築してみたいと思い、opensslのTLS1.3の対応状況を見てみたのですが、まだopensslは対応していないみたいです。代わりにdraft版では対応しているみたいなので、こちらでやってみようと思い、対応状況を今回は記事にまとめてみます。
opensslのTLS1.3の正式対応はopenssl 1.1.1にて対応するようです。

以下の表にまとめます。

| バージョン | draft |
| :---: | :---: |
| openssl 1.1.1 pre1 |23|
| openssl 1.1.1 pre2 |23|
| openssl 1.1.1 pre3 |26|
| openssl 1.1.1 pre4 |26|
| openssl 1.1.1 pre5 |26|
| openssl 1.1.1 pre6 |26|
| openssl 1.1.1 pre7 |28|
| openssl 1.1.1 pre8 |28|

## 参考にしたサイト
[ OpenSSL ](https://www.openssl.org/)
StanとRでベイズ統計モデリング(アヒル本)をPythonにしてみる - 7.9 外れ値

[実行環境](https://qiita.com/shngt/items/ce6f2c3ef348cd80f432)

### インポート

```python
import numpy as np
import pandas as pd
import pystan
import matplotlib.pyplot as plt
from matplotlib.figure import figaspect
%matplotlib inline
```

### データ読み込み

```python
outlier = pd.read_csv('./data/data-outlier.txt')
```

# 7.9 外れ値

```python
ax = outlier.plot.scatter('X', 'Y')
fig = plt.gcf()
plt.setp(fig, size_inches=figaspect(3/4))
plt.setp(ax, xlim=(-0.2, 11.2), ylim=(-25, 75))
plt.show()
```
![fig7-11.png](https://qiita-image-store.s3.amazonaws.com/0/103085/6349e0c7-fd8a-f006-266b-15ac98009521.png)

```python
X_new = np.linspace(0, 11, 100)
data = dict(
    N=outlier.index.size,
    X=outlier['X'],
    Y=outlier['Y'],
    N_new=X_new.size,
    X_new=X_new
)

fit1 = pystan.stan('./stan/model7-8.stan', data=data, seed=1234)

ms1 = fit1.extract()
d_est1 = np.percentile(ms1['y_new'], (2.5, 25, 50, 75, 97.5), axis=0)

fit2 = pystan.stan('./stan/model7-9.stan', data=data, seed=1234)

ms2 = fit2.extract()
d_est2 = np.percentile(ms2['y_new'], (2.5, 25, 50, 75, 97.5), axis=0)
```

```python
_, axes = plt.subplots(1, 2, figsize=figaspect(3/8), sharex=True, sharey=True)
for ax, d_est in zip(axes, [d_est1, d_est2]):
    outlier.plot.scatter('X', 'Y', color='w', edgecolor='k', ax=ax)
    ax.fill_between(X_new, d_est[0], d_est[-1], color='k', alpha=0.2)
    ax.fill_between(X_new, d_est[1], d_est[-2], color='k', alpha=0.4)
    ax.plot(X_new, d_est[2], color='k')
plt.setp(ax, xlim=(-0.2, 11.2), ylim=(-25, 75))
plt.show()
```
![fig7-12.png](https://qiita-image-store.s3.amazonaws.com/0/103085/fa7acf47-3a54-24f4-9d08-6abb9a8cc6ed.png)
SVOをKineticでオフラインで動かす

# Environment
Windows10 inter corei7 7500U
Virtual box 5.2
Ubuntu16.04 (ROS kinetic)
# ROS
` $ sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'`
` $ sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116`
`$ sudo apt-get update`
`$ sudo apt-get install ros-kinetic-desktop-full`
`$ echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc`
`$ source ~/.bashrc`

# Sophus
`$ mkdir workspace`
`$ cd workspace`
`$ git clone https://github.com/strasdat/Sophus.git`
`$ cd Sophus`
`$ git checkout a621ff`
`$ mkdir build`
`$ cd build`
`$ cmake ..`
`$ make`

# fast
workspaceに移動
`$ git clone https://github.com/uzh-rpg/fast.git`
`$ cd fast`
`$ mkdir build`
`$ cd build`
`$ cmake ..`
`$ make`

# SVO
ホームに移動
`$ mkdir catkin_ws`
`$ mkdir catkin_ws/src`
`$ cd catkin_ws/src`
`$ git clone https://github.com/uzh-rpg/rpg_vikit.git`
`$ git clone https://github.com/uzh-rpg/rpg_svo.git`

catkin_wsに移動
`$ catkin_make`
`$ catkin_make install`
`$ echo "source /path to current directory/devel/setup.bash" >> ~/.bashrc`
`$ source ~/.bashrc`

# オフラインデータの取得
`$ wget http://rpg.ifi.uzh.ch/datasets/airground_rig_s3_2013-03-18_21-38-48.bag`

# Rviz
`$ cp src/rpg_svo/svo_ros/rviz_config.rviz ~/.rviz/default.rviz`

# ROSを動かす
- 端末1  
`$ roscore`
- 端末2  
`$ rosbag play airground_rig_s3_2013-03-18_21-38-48.bag`
- 端末3  
`$ roslaunch svo_ros test_rig3.launch`
- 端末4  
`$ rosrun rviz rviz`

# 参考
http://cvl-robot.hateblo.jp/entry/2014/07/03/162709
http://kivantium.hateblo.jp/entry/2014/07/01/000651
http://wiki.ros.org/ja/kinetic/Installation/Ubuntu
StanとRでベイズ統計モデリング(アヒル本)をPythonにしてみる - 7.8 打ち切り

[実行環境](https://qiita.com/shngt/items/ce6f2c3ef348cd80f432)

### インポート

```python
import pandas as pd
import pystan
```

### データ読み込み

```python
protein = pd.read_csv('./data/data-protein.txt')
```

# 7.8 打ち切り

```python
idx = protein['Y'].str.contains('<')
Y_obs = protein.loc[~idx, 'Y'].astype(float)
L = protein.loc[idx, 'Y'].str.replace('<', '').astype(float)[0]

data = dict(
    N_obs=Y_obs.index.size,
    N_cens=idx.sum(),
    Y_obs=Y_obs,
    L=L
)
fit = pystan.stan('./stan/model7-7.stan', data=data, seed=1234)
```
StanとRでベイズ統計モデリング(アヒル本)をPythonにしてみる - 7.5 交絡

[実行環境](https://qiita.com/shngt/items/ce6f2c3ef348cd80f432)

### インポート

```python
import pandas as pd
import pystan
import matplotlib.pyplot as plt
from matplotlib.figure import figaspect
from matplotlib.markers import MarkerStyle
%matplotlib inline
```

### データ読み込み

```python
d = pd.read_csv('./data/data-50m.txt')
d['Age'] = pd.Categorical(d['Age'])
```

# 7.5 交絡

```python
_, (ax1, ax2) = plt.subplots(1, 2, figsize=figaspect(3/8), sharex=True, sharey=True)
ax1.scatter('Weight', 'Y', data=d)
for i, age in enumerate(d['Age'].cat.categories):
    ax2.scatter('Weight', 'Y', data=d.query('Age==@age'), marker=MarkerStyle.filled_markers[i], label=age)
ax2.legend(title='Age')
for ax in [ax1, ax2]:
    plt.setp(ax, xlabel='Weight', ylabel='Y')
plt.show()
```
![fig7-8.png](https://qiita-image-store.s3.amazonaws.com/0/103085/0e336dd1-aefe-5d63-296d-d03362e8899c.png)

```python
data = {col: d[col] for col in d.columns}
data['N'] = d.index.size
fit = pystan.stan('./stan/model7-5.stan', data=data, seed=1234)
```
スペース・空文字除去

スペースとか改行コードとかの空文字を除去

```csharp
    public static class StringsConvert
    {
        /// <summary>
        /// 空文字除去
        /// </summary>
        /// <param name="chars"></param>
        /// <returns></returns>
        public static string RemoveSpace(this string chars)
        {
            var newChars = new char[chars.Length];
            int length = 0;
            foreach (var c in chars)
            {
                if (spaceList.IndexOf(c) < 0)
                {
                    newChars[length] = c;
                    length++;
                }
            }
            return new string(newChars, 0, length);
        }
        private static List<char> spaceList = new List<char>
        {
            (char)0x200B,
            (char)0x200C,
            (char)0x200D,
            (char)0xFEFF,
            (char)0x2028,
            (char)0x2029,
            (char)0x0009,
            (char)0x000A,
            (char)0x000B,
            (char)0x000C,
            (char)0x000D,
            (char)0x0085,
            (char)0x0020,
            (char)0x00A0,
            (char)0x1680,
            (char)0x180E,
            (char)0x2000,
            (char)0x2001,
            (char)0x2002,
            (char)0x2003,
            (char)0x2004,
            (char)0x2005,
            (char)0x2006,
            (char)0x2007,
            (char)0x2008,
            (char)0x2009,
            (char)0x200A,
            (char)0x202F,
            (char)0x205F,
            (char)0x3000,            
        };
    }
```
Javascript 二次元配列の追加、結合

二次元配列の操作で

+ 二次元配列に二次元配列を追加（破壊的/push）
+ 二次元配列と二次元配列を結合（非破壊的/concat）

する方法がわからなかったので関数を作成した。

縦方向と横方向に追加、結合が可能。

# 追加（破壊的/push）
一次元配列に値をpushする際と同様に、二次元配列に二次元配列を破壊的に追加する。

[第3引数]
axis≠1: 縦方向に追加
axis=1: 横方向に追加

```Javascript:追加（破壊的/push）
function pushTwoDimensionalArray(array1, array2, axis){
  if(axis != 1) axis = 0;
  if(axis == 0){  //　縦方向の追加
    for(var i = 0; i < array2.length; i++){
      array1.push(array2[i]);
    }
  }
  else{  //　横方向の追加
    for(var i = 0; i < array1.length; i++){
      Array.prototype.push.apply(array1[i], array2[i]);
    }
  }
}
```

# 結合（非破壊的/concat）
一次元配列に値をconcatする際と同様に、二次元配列と二次元配列を非破壊的に結合する。

[第3引数]
axis≠1: 縦方向に結合
axis=1: 横方向に結合

```Javascript:結合（非破壊的/concat）
function concatTwoDimensionalArray(array1, array2, axis){
  if(axis != 1) axis = 0;
  var array3 = [];
  if(axis == 0){  //　縦方向の結合
    array3 = array1.slice();
    for(var i = 0; i < array2.length; i++){
      array3.push(array2[i]);
    }
  }
  else{  //　横方向の結合
    for(var i = 0; i < array1.length; i++){
      array3[i] = array1[i].concat(array2[i]);
    }
  }
  return array3;
}
```

# 縦方向の追加（破壊的/push）
```Javascript:使用例
var arr1 = [['A1','B1','C1'],['A2','B2','C2'],['A3','B3','C3']];
var arr2 = [['A4','B4','C4'],['A5','B5','C5']];

pushTwoDimensionalArray(arr1, arr2);
```

`pushTwoDimensionalArray()`実行後のarr1は下図の`arr1(push後)`のようになる。
第1引数の`arr1`の下側に、第2引数の`arr2`を追加(push)する。

![push_axis=0.png](https://qiita-image-store.s3.amazonaws.com/0/79218/91e052f1-653c-b9d3-1e52-8e860de34cec.png)

# 横方向の追加（破壊的/push）
```Javascript:使用例
var arr3 = [['A1','B1','C1'],['A2','B2','C2'],['A3','B3','C3']];
var arr4 = [['D1','E1'],['D2','E2'],['D3','E3']];

pushTwoDimensionalArray(arr3, arr4, 1);
```

横方向に追加する場合は`第3引数(axis)を1`に指定する。
`pushTwoDimensionalArray()`実行後のarr3は下図の`arr3(push後)`のようになる。
第1引数の`arr3`の右側に、第2引数の`arr4`を追加(push)する。

![push_axis=1.png](https://qiita-image-store.s3.amazonaws.com/0/79218/055d1e70-9e8c-b9e4-dda5-ad1ad24d4731.png)

# 縦方向の結合（非破壊的/concat）
```Javascript:使用例
var arr1 = [['A1','B1','C1'],['A2','B2','C2'],['A3','B3','C3']];
var arr2 = [['A4','B4','C4'],['A5','B5','C5']];

var arr12 = concatTwoDimensionalArray(arr1, arr2);
```

非破壊的に配列と配列を結合する場合は`concatTwoDimensionalArray()`を使用する。

![concat_axis=0.png](https://qiita-image-store.s3.amazonaws.com/0/79218/a6bf5a23-2ac3-a966-2614-2443372309fd.png)

# 横方向の結合（非破壊的/concat）
```Javascript:使用例
var arr3 = [['A1','B1','C1'],['A2','B2','C2'],['A3','B3','C3']];
var arr4 = [['D1','E1'],['D2','E2'],['D3','E3']];

var arr34 = concatTwoDimensionalArray(arr3, arr4, 1);
```

横方向に結合する場合はpushと同様に`第3引数(axis)を1`に指定する。

![concat_axis=1.png](https://qiita-image-store.s3.amazonaws.com/0/79218/ec7a75bf-b6b4-2e21-5af8-7e54ef8d2a4c.png)

# まとめ
pythonのpandasのように二次元配列の追加、結合する関数を作成して使用例をまとめた。
使用例と図をまとめると直感的でわかりやすい。

# 参考
[Python pandas 図でみる データ連結 / 結合処理](http://sinhrks.hatenablog.com/entry/2015/01/28/073327)
StanとRでベイズ統計モデリング(アヒル本)をPythonにしてみる - 7.3 非線形の関係

[実行環境](https://qiita.com/shngt/items/ce6f2c3ef348cd80f432)

### インポート

```python
import numpy as np
import pandas as pd
import pystan
import matplotlib.pyplot as plt
from matplotlib.figure import figaspect
%matplotlib inline
```

### データ読み込み

```python
aircon = pd.read_csv('./data/data-aircon.txt')
conc = pd.read_csv('./data/data-conc.txt')
```

# 7.3 非線形の関係

```python
N_new = 60
X_new = np.linspace(-3, 32, N_new)
data = dict(
    N=aircon.index.size,
    X=aircon['X'],
    Y=aircon['Y'],
    N_new=N_new,
    X_new=X_new
)
fit = pystan.stan('./stan/model7-3.stan', data=data, seed=1234)
```

```python
ms = fit.extract()

d_est = np.percentile(ms['y_new'], (2.5, 25, 50, 75, 97.5), axis=0)
_, (ax1, ax2) = plt.subplots(1, 2, figsize=figaspect(3/8), sharex=True, sharey=True)
for ax in [ax1, ax2]:
    aircon.plot.scatter('X', 'Y', color='w', edgecolor='k', ax=ax)
ax2.fill_between(X_new, d_est[0], d_est[-1], color='k', alpha=0.3)
ax2.fill_between(X_new, d_est[1], d_est[-2], color='k', alpha=0.5)
ax2.plot(X_new, d_est[2], color='k')
plt.setp(ax2, yticks=np.arange(0, 101, 50))
plt.show()
```
![fig7-5.png](https://qiita-image-store.s3.amazonaws.com/0/103085/15ff7b93-062d-f46c-ba0c-7a1973c4a7f7.png)

```python
T_new = 60
Time_new = np.linspace(0, 24, T_new)
data = dict(
    T=conc.index.size,
    Time=conc['Time'],
    Y=conc['Y'],
    T_new=T_new,
    Time_new=Time_new
)
fit = pystan.stan('./stan/model7-4.stan', data=data, seed=123)
```

```python
ms = fit.extract()

d_est = np.percentile(ms['y_new'], (2.5, 25, 50, 75, 97.5), axis=0)
_, (ax1, ax2) = plt.subplots(1, 2, figsize=figaspect(3/8), sharex=True, sharey=True)
conc.plot.line('Time', 'Y', marker='o', color='k', ax=ax1)
ax2.scatter('Time', 'Y', data=conc, color='k')
ax2.fill_between(Time_new, d_est[0], d_est[-1], color='k', alpha=0.3)
ax2.fill_between(Time_new, d_est[1], d_est[-2], color='k', alpha=0.5)
ax2.plot(Time_new, d_est[2], color='k')
plt.setp(ax2, xlabel='Time (hour)', ylabel='Y', xticks=conc['Time'], yticks=np.arange(0, 16, 5), ylim=(-2.5, 16))
plt.show()
```
![fig7-6.png](https://qiita-image-store.s3.amazonaws.com/0/103085/0f4d0984-be79-1970-f793-2aaf3f66c8f4.png)

```python
x = np.linspace(0, 5, 60)
plt.figure(figsize=figaspect(3/4))
ax = plt.axes()
ax.plot(x, 2*np.exp(-1*x), linestyle='solid', label=1)
ax.plot(x, 1.8/(1+50*np.exp(-2*x)), linestyle='dashed', label=2)
ax.plot(x, 8*(np.exp(-x) - np.exp(-2*x)), linestyle='dotted', label=3)
ax.legend(title='Model')
plt.setp(ax, xlabel='Time', ylabel='Y')
plt.show()
```
![fig7-7.png](https://qiita-image-store.s3.amazonaws.com/0/103085/940a60e0-1f73-efc2-dd61-15ec26290bf3.png)
JavaScript 自動排程 By 彭彭 22


	8. 自動排程 功能

![WS000018.JPG](https://qiita-image-store.s3.amazonaws.com/0/280122/c9899246-9026-1afe-87ad-d275fd97a8c5.jpeg)


```ruby

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"></meta>
	<title>自動排程 Schedule</title>
	<script type="text/javascript">
	//alert("hello");
	// 一秒鐘之後 排程動作的基本
	// setTimeout only執行一次countdown 倒數
	// setInterval 每秒鐘執行一次countdown 倒數
	var timer;
	function init(){
		timer = document.getElementById("timer");
		//window.setInterval(countdown,1000);
		window.setInterval(countdown,1000);
	}
	function countdown(){
		timer.innerHTML = timer.innerHTML-1;
		if(timer.innerHTML > 0){
		//window.setTimeout(countdown,1000);
		}else{
		document.location="http://www.sina.com";
		}
	}
	</script>
</head>
<body onload = "init();">
	<span id = "timer">3</span>
</body>
</html>
【Xcode】iOS実機確認時における「This iPhone 6 is running iOS 11.4.1 (15G77), which may not...」の対処方法


<img width="429" alt="Route_xcodeproj-3.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/fd549238-ede3-aeb5-3053-23f9a037f03f.png">
Xcodeにおいて、実機接続後のビルド実行時に
「**This iPhone 6 is running iOS 11.4.1 (15G77), which may not be supported by this version of Xcode.**」
が発生する。 
→ 実機iPhoneのOSに対応したデバイスサポートファイルが存在しない言われる。

# 環境
- 実機 iPhone6 iOS 11.4.1(15G77)
- macOS HighSierra 10.13.4
- Xcode 9.3

# 原因
- 自身の実機iPhoneのOSがXcode側でサポート外である場合
- 以前使用可能であった実機iPhoneのOSをアップデートしたことにより、Xcode側でサポート外となった場合

# 対処
Xcode側に**実機OSに対応したデバイスサポートファイルを配置**し、サポート対象であること明示する。

## 1. 対応したデバイスサポートファイルの確認
### 1-1. 実機OSを確認する。
1. 実機iPhoneのOSを確認する。 
`設定 > 情報 > バージョン` 
⇒　例）11.4.1(15G77)

2. 自身のXcodeデバイスサポート内容を確認する。
`/Users/<USER_NAME>/Library/Developer/Xcode/iOS DeviceSupport/`配下のディレクトリに、実機OSと同等ではないディレクトリ名が存在するかを確認する。 
⇒　例）ディレクトリ名 : 11.3.1 (15E302)
<img width="837" alt="iosDeviceSupport_15E302.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/0bb29f95-965d-eb20-e0d8-e234285e2bc1.png">
### 1-2. 実機OSに対応したデバイスサポートファイルを確認する。
[Ghibli / iOS-DeviceSupport](https://github.com/iGhibli/iOS-DeviceSupport/blob/master/README.md)より、実機OSに対応したデバイスサポートファイルを確認する。

## 2. デバイスサポートファイルのDL
先程のGithubリポジトリ [iOS-DeviceSupport](https://github.com/iGhibli/iOS-DeviceSupport/tree/master/DeviceSupport) から対象のzipファイルをDLする。

→ 今回は、実機OSが**11.4.1(15G77)**なので、**11.4(15F79).zip**ファイルをDLしました。

※ はじめに **11.4(15F5061c).zip** をDLしましたが、上手く動作しなかったので`()`内のバージョンも意味があるみたいなので、実機OSに近しいものを選んだほうがいいかと思います。

## 3. デバイスサポートファイルの配置
DLしたzipファイル解凍後、
`/Users/<USER_NAME>/Library/Developer/Xcode/iOS DeviceSupport/`配下に解凍されたディレクトリを配置する。 
※ もともと`~/iOS DeviceSupport/`配下にある既存ディレクトリの削除は不要です。
<img width="849" alt="11_4_1__15G77__と_ダウンロード.png" src="https://qiita-image-store.s3.amazonaws.com/0/183618/c24cdd6e-99f6-6244-c7a8-8a36f19c4199.png">



## 4. 再ビルド
デバイスサポートファイル配置後、再度ビルドし直す。
※ うまく動作しない場合は、Xcodeを再起動することおすすめします。
Python 環境構築 windows 

#Pythonの開発環境（Windows）
業務の休憩中にPythonの勉強がしたかったので、休憩中に書いたWindowsでのPython開発環境構築のメモ

【Macの方はこちら】
[Python環境構築 Mac](https://qiita.com/Daara_y/items/d7cf7c859342984b6e1c)

Windows:10
Python:3系

# Pythonのインストール
まずは公式サイトにアクセス
【公式サイト】
https://www.python.org/

公式サイトにいったら、**Download**の部分にカーソルを合わせて、Windowsを選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253969/e643558f-a6f3-a764-0fe8-d244bd36ae72.png)

バージョンを選ぶ画面に遷移するので、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253969/6346d320-8d3e-9f9a-075a-de93341917ad.png)

今回は、**Python 3.6.5**をインストール
※2系は20年にサポートが終了するらしいので、3系を入れるようにする
ctl + F で「3.6.5」を検索
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253969/c53d35a7-587c-7c3d-0021-93513bc4028e.png)

このファイルの中の
**Download Windows x86-64 executable installer**
をダウンロード

zipファイルを解凍すると、以下の画面が出るので、
**Install Now**を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253969/d1ac9b9a-0998-8a7a-d42d-202b0acc856e.png)

インストール完了、Closeボタンで閉じちゃってください
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253969/f5424046-1ab2-0353-9be4-658813088b5a.png)

#Pythonがきちんとインストールされたか確認する
Windows10の人は、メニュー検索から**powershell**と検索しPowerShellを起動
![image.png](https://qiita-image-store.s3.amazonaws.com/0/253969/fd967fb7-ff7b-dc9c-00a0-acac008bf6f3.png)

powershellで　*Python --version*と入力

- きちんとインストールされている場合
![スクリーンショット (3).png](https://qiita-image-store.s3.amazonaws.com/0/253969/7affe777-8eff-9d7d-1f46-de972d2af06a.png)


- きちんとインストールされていない場合
![スクリーンショット (2).png](https://qiita-image-store.s3.amazonaws.com/0/253969/12a67e17-9720-7bc3-d58e-d71c9c368a54.png)

### コマンドを打ってもエラーと出てしまう対処法
- ログアウトする
    - 一回、ログアウトして、もう一度PowerShellを起動して*Python --version*と入力
- PCの再起動
    - PCを再起動して、あとは上記同様
- 環境変数にPythonのインストール先のPathが通っているか確認する
    ![スクリーンショット (4).png](https://qiita-image-store.s3.amazonaws.com/0/253969/23fe702b-f8a1-fb0f-12db-a79d292187d9.png)
Javascript 事件處理 - Event Object 事件物件 By 彭彭 21


	7. 
		a. 事件物件 Event Object
![WS000017.JPG](https://qiita-image-store.s3.amazonaws.com/0/280122/6a8d835b-4b44-b1f7-240c-1a42a6c14a0e.jpeg)

鍵盤keyCode

```ruby
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"></meta>
	<title>事件物件 Event Object</title>
	<script type="text/javascript">
	//alert("hello");
	function init(e){
		var btn = document.getElementById("btn");
		var handler = function(e){
			// 滑鼠坐標位置 clientX,clientY
			alert(e.clientX + "," + e.clientY);
		}
		btn.addEventListener("click",handler);
	}
	/*	想象以上的代碼含義
		1. 使用者點擊了按鈕,出發click事件
		2. 瀏覽器主動收集和事件有關的資訊,並製造出event object 事物事件
			var eventObj = 事物事件
		3. 呼叫已經注冊的時間處理器(事件處理函式)
			handler(eventObj);
	*/
	
	// 注冊鍵盤事件處理器 (取得使用者的按鍵code) 鍵盤keyCode
	document.addEventListener("keydown",function(e){
		alert(e.keyCode);
	});

	</script>
</head>
<body onload = "init();">
	<button id = "btn">florence</button>
</body>
</html>
Slackで使用されていないアカウントを探した時の話

某部活の季節外れ突発AdventCalendar n日目です(TODO:あとで書き換える)。
以前にslackでスクリプト組んだのでその時の話をvTuberの動画を見ながら書きます。

僕はnodejsで書きましたが、この記事では具体的なスクリプトの書き方とかには触れないのでご了承ください。

# はじめに
うちの部活では連絡やコミュニケーションにslackを使用しています。現在、部のチームには結構な人数なメンバーが所属しています。しかしこの中にはOBや幽霊部員さんなども多く含まれていたのでそういった非アクティブなアカウントを一掃して整理することにしました。

### 理想
- slackのapiで各アカウントの最終ログイン日時を取得し、使われていないアカウントを見つける

### 現実
- 最終ログイン日時を取得できるapiの[team.accessLogs](https://api.slack.com/methods/team.accessLogs)が有料プランじゃないと使えない。
- 弊部のslackは無料版を使用
- つらい

### 解決策
- 管理用のアカウントからチームに所属している全アカウントに対してDMを送り、一定期間返信が無いアカウントを非アクティブなアカウントと判断。

というわけで今回行なった「各ユーザーにDMを送信」と「そのユーザーからの返信を確認」について軽く解説します。

#各ユーザーにDMを送信
任意のアカウントにDMを送るにはまず、そのアカウントのユーザーネームを知る必要があります。[users.list](https://api.slack.com/methods/users.list)を使用することでチームに所属している全ユーザーのユーザーネームを含んだ様々な情報を取得できます。レスポンスの"name"がユーザーネームに当たります。

次に[chat.postMessage](https://api.slack.com/methods/chat.postMessage)を使用してDMを送信します。チャンネルにメッセージを送るときにも使用するapiですが、引数の"channel"を「@ユーザーネーム」とするとそのユーザーにDMを送ることが出来ます。同じく引数の"as_user"をtrueにしておくとメッセージの送信者がapiに使用しているtokenの発行ユーザーになります。falseだとbotが送信者になります。

送信するテキストに返信を促すようなメッセージを入れておくと良いかもしれません。

#ユーザーからの返信を確認
DMを送るのは簡単にできましたがそのユーザーから返信が来ているかを確認するのにはちょっと面倒な手順が必要です。

まず、ユーザーID(ユーザーネームとは別)が必要となります。ユーザーIDはslack上では確認できないのでapiを使用して取得する必要があります。取得にはDMを送信したときと同じように[users.list](https://api.slack.com/methods/users.list)を使用します。レスポンスに含まれる"id"がユーザーIDです。

次にユーザーとのDMのID(以下、DM-ID)を取得します。DM-IDは[im.open](https://api.slack.com/methods/im.open)で取得できます。引数の"user" にさっき取得したユーザーIDを入れます。レスポンスの"id"がDM-IDです。

そしてようやっとDMの履歴取得です。[im.history](https://api.slack.com/methods/im.history)を使います。引数の"channel"には DM-IDを入れます。レスポンスでチャット履歴が返ってくるのでこれで返信が来ているかどうかの判断を行います。

# おわり
以上の方法で非アクティブなアカウントを見つけました。ちなみにアカウントの削除はapiからでは行えなかったので手動でやりました（辛かった）。
Let's Encryptをcrontabで自動化した時に実行されない時の対処法

# Let's Encryptとは
日本語ではレッツ・エンクリプトと読みます。無料ですぐに利用可能なSSLサーバー証明書で、アメリカの非営利団体ISRG (Internet Security Research Group) が、2016年から提供しているサービスです。
それまでSSLといえば個人情報を入力するフォームなどには必要な手段にもかかわらず、高く(数万円～数十万円)、手続きが面倒でした。ところがLet’s Encrypt誕生のおかげで誰でも、いつでも、かなり簡単にSSLが利用できるようになります。画期的なサービスの登場です。
この記事ではわかりやすくするために、単に「SSL」と表記していますが、実際は少し複雑です。より詳しくお知りになりたい方は、下記の記事をご覧ください。

## 環境
Apache/2.4.33
aws-cli/1.14.8 Python/2.7.14 Linux/4.14.42-61.37.amzn2.x86_64 botocore/1.8.12

## crontabを使用した自動化
```terminal:terminal
# vim /etc/cron.d/letsencrypt
```
```terminal:/etc/cron.d/letsencrypt
00 16 * * 2 root /usr/bin/certbot-auto renew --post-hook "service httpd restart"
```
※この書き方だと毎週火曜日の16:00に実行されるようになっています。
詳しいことは[Let's Encrypt](https://letsencrypt.jp/)の方を参照してください。

これで上手くいけばなんも心配はないのですが。
ここからはLet's Encryptを自動化しようとした時に見るべき項目を書いていこうと思います

## トラブルシューティング

### (1)cronがそもそも動いているのか

```terminal:terminal
# /etc/rc.d/init.d/crond status
crond (pid  xxxx) を実行中...
```

### (2)runlevelに合わせてonになっているか
(2~5がonになっていればok)

```terminal:terminal
# chkconfig --list crond
crond           0:off   1:off   2:on    3:on    4:on    5:on    6:off
```

### (3)Pathがしっかりしているか。（自分はこれが原因でした。）

```terminal:terminal
# echo $PATH
/opt/rh/python27/root/usr/bin:/usr/local/rbenv/shims:/usr/local/rbenv/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
```
```terminal:/etc/cron.d/letsencrypt
PATH=/opt/rh/python27/root/usr/bin:/usr/local/rbenv/shims:/usr/local/rbenv/bin:/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
00 16 * * 2 root /usr/bin/certbot-auto renew --post-hook "service httpd restart"
```
※Pathは自分の環境に合わせて変更の方してください。

### (4)それでもダメならlogで確認してみてください。

```terminal:terminal
# touch /tmp/analog.log && touch /tmp/analog-err.log
```
```terminal:/etc/cron.d/letsencrypt
00 16 * * 2 root /usr/bin/certbot-auto renew --post-hook "service httpd restart" >>/tmp/analog.log 2>>/tmp/analog-err.log
```

これで作成した。analog.logとanalog-err.logを確認してみましょう。

##　まとめ
いかがだったでしょうか？
自分が主に思いつく解決方法や起こりうるトラブルを書きました。
何か質問や気になる事があればTwitterなどでも良いので声をかけてくれれば、出来る範囲で対応します。

```Twitter:TwitterID
@uechan9220
```
AppLaunchCheckerでAndroidの初回起動判定

これまでSharedPreferenceで判定していたのですが、AppLaunchCheckerで簡単に制御できたので使ってみました。

参考URL => https://qiita.com/inuko/items/399a4431941dd6b3160b

```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_sub)
    val before = AppLaunchChecker.hasStartedFromLauncher(applicationContext)
    AppLaunchChecker.onActivityCreate(this)
    val after = AppLaunchChecker.hasStartedFromLauncher(applicationContext)
}
```

ちょっとしたハマりポイントになりますが、`AppLaunchChecker.onActivityCreate(this)` は `android.intent.category.LAUNCHER` のActivityでしか動作しません。
当初奥の階層の画面で初回起動判定の処理が必要だったので、そこで処理後に更新をする予定でしたがうまく行かず・・・

私は `AppLaunchChecker.onActivityCreate(this)` は最初のActivityで行い、
`AppLaunchChecker.hasStartedFromLauncher(applicationContext)` の結果はApplicationクラスで保存することで、対応しました
【Androidアプリ開発勉強】Activityって何?

[前回](https://qiita.com/fortegp05/items/7945b5ea3e8e1a3d79b9)でAndroidアプリのHello World!をやりましたが、
その中でActivity(アクティビティ)という知らない単語が出てきたので意味を調べてみました。

# 調べてみた結果
[こちら](https://developer.android.com/guide/components/activities?hl=ja)の公式サイトを御覧ください(2回目)

では味気ないので…。
自分に必要そうな内容をちょっと簡単にまとめてみました。


## アクティビティとメインアクティビティ
アクティビティとはユーザーに操作を提供する画面のことを指します。
つまりボタンとかラベルとかじゃなくて、
画面そのものの事らしいです。

通常、アプリは複数のアクティビティ(画面)で構成されているので、
どれか1つのアクティビティが「メイン」アクティビティとして指定されます。
このメインアクティビティがアプリ起動時に表示されるアクティビティ(画面)になるようです。

## アクティビティのライフサイクル
アクティビティから新しいアクティビティが呼ばれた場合、
呼び元のアクティビティは停止します。
この時、停止するアクティビティの状態変化がコールバックメソッド経由で通知されます。
そこでNW接続やDB接続などの大きなリソース開放を行うが出来ます。
(同じアプリであればDBは繋ぎっぱなしで良い気もするけども…)

新しいアクティビティで戻るボタンを押下するなどして操作が完了した場合、
そのアクティビティは破棄されてスタックに積んでいた呼び元のアクティビティが再開します。
この時も状態変化がコールバックメソッド経由で通知されます。
(NW接続などリソースの再取得などができるように)

## アクティビティ作成時の注意点
- onCreateメソッドは必須。
- さらにその中でsetContentViewメソッドを叩いてUI[^1]のレイアウトを定義する必要がある。
- アクティビティがシステムにアクセス出来るようにするにはマニフェストに宣言する必要がある。


## アクティビティの表示とインテントについて
マニフェストに宣言する際にはInten(インテント)[^2]を定義します。

インテントとはアクティビティを呼び出すときに使用されるメッセージオブジェクトのことらしい。
アクティビティを開始する際にはこのインテントをContext.startActivity()に渡せば良いらしい。
このContextはアクティビティやApplicationの親クラスだそうで。

たぶんApplicationオブジェクトのstartActivityにわたすと新しいアクティビティが実行される、みたいな感じ?
実装の例を見ると暗黙で実行されるのがApplicationオブジェクトっぽい。

インテントの指定には正確にアクティビティを指定するかその動作を指定するかの2種類があります。
後者の動作を指定するタイプでは他のアプリケーションも呼び出せるらしい。
例えばメールを送るみたいな動作で呼び出すとメールアプリが立ち上がるみたい。
(複数あれば選択も可能だが無いとハングするらしい…)

# 終わりに
Activityとは?というところで調べ始めましたが、
結果的にアプリの画面まわり(の基礎)の勉強になりました。

いま作ろうとしているアプリは最大4画面になりそうなので、
アクティビティは4つになるのかなぁ。

次はアクティビティに乗せるUIの勉強になりそう。

ViewModelはこのアクティビティのJavaファイルの事なのか、
他にオブジェクトを作ったほうが良いのか…。
こういうのが書いてある資料が無い(あるいは見つからない)んだよなぁ…。


[^1]: UI作成方法の詳細は別の[ドキュメント](https://developer.android.com/guide/topics/ui/?hl=ja)があるみたいだがまだ読んでいない…
[^2]: インテントについては[こちら](https://developer.android.com/guide/components/intents-filters?hl=ja)
psコマンドでタスクのスケジューリングクラスを確認する

# 環境
* Ubuntu 17.10

# 方法
`-c`オプションで見れるようになる。`CLS`のカラムに着目。

```
$ ps -c 
  PID CLS PRI TTY          TIME CMD
 3926 TS   19 pts/0    00:00:01 bash
 9386 TS   19 pts/0    00:00:00 ps
```

取りうる値は下記。（`man ps`から抜粋）

```
 -   not reported
 TS  SCHED_OTHER
 FF  SCHED_FIFO
 RR  SCHED_RR
 B   SCHED_BATCH
 ISO SCHED_ISO
 IDL SCHED_IDLE
 ?   unknown value
```

各スケジューリングクラスの概要は、`man sched`を見ると良い。
Django Girls TutorialでHerokuのデプロイでエラーとなるときの解決方法

# Django Girls Tutorial
Djangoチュートリアルを進めていたところ、デプロイ！でエラーとなってしまいました。
https://djangogirlsjapan.gitbooks.io/workshop_tutorialjp/content/deploy/

## デプロイする
チュートリアルの「Deploy to Heroku!」のところでアプリケーションをデプロイしようとすると失敗します。

```
$ git push heroku master
```

## ログを確認する
下記のログが出力されます。（エラー情報のみ抜粋）

```
remote:        Collecting psycopg2==2.5.4 (from -r /tmp/build_d1bbbafb62fca475e7098fdd83d9df07/requirements.txt (line 20))
remote:          Downloading https://files.pythonhosted.org/packages/63/c3/802668cb3cfc2880c2a8364623e7105a0257724a2612bb66ec733aaddb8c/psycopg2-2.5.4.tar.gz (682kB)
remote:            Complete output from command python setup.py egg_info:
remote:            running egg_info
remote:            creating pip-egg-info/psycopg2.egg-info
remote:            writing dependency_links to pip-egg-info/psycopg2.egg-info/dependency_links.txt
remote:            writing pip-egg-info/psycopg2.egg-info/PKG-INFO
remote:            writing top-level names to pip-egg-info/psycopg2.egg-info/top_level.txt
remote:            writing manifest file 'pip-egg-info/psycopg2.egg-info/SOURCES.txt'
remote:            Error: could not determine PostgreSQL version from '10.5'
remote:            
remote:            ----------------------------------------
remote:        Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-7lkslusa/psycopg2/
remote:  !     Push rejected, failed to compile Python app.
remote: 
remote:  !     Push failed
```

## psycopg2をアップデートする
psycopg2のバージョンが原因でした。チュートリアルの手順に従ってインストールするとバージョンが古いようです。下記コマンドでインストールします。

```
$ pip install psycopg2
```

## requirements.txtを修正する
requirements.txtのpsycopg2のバージョンを修正します。（下記はインストールされたバージョンで修正してください。）

`psycopg2==2.7.5`

最後に、Gitで変更を保存、プッシュします。

## 補足
事前にインストールしていたPythonのバージョンが合っていないと思い込み、runtime.txtを何度も修正していましたが、これは原因ではなかったようです。

```
(venv)$ python --version
Python 3.6.5
```

下記のログが出力されていました。

```
remote: -----> Python app detected
remote:  !     The latest version of Python 3.6 is python-3.6.6 (you are using python-3.6.5, which is unsupported).
remote:  !     We recommend upgrading by specifying the latest version (python-3.6.6).
remote:        Learn More: https://devcenter.heroku.com/articles/python-runtime
remote: -----> Installing python-3.6.5
```
selfの意味

よく見かける"self"の意味について。

#結論
selfを付けた変数は、プロパティ
selfを付けない変数は、引数

同じクラス内で、プロパティとメソッドの引数に同じ名前を使えるため、selfで区別する必要があると理解した。

#実例
##例1 イニシャライザ
```swift
class Iphone {
    var language :String
    var passcode :String
    init(language :String, passcode:String){
        self.language = language
        self.passcode = passcode
}
```

##例2 クラス
```swift
class SampleClass{
  var num : Int = 1
  func sampleFunc(){
    let num = 2
    print(String(self.num)) // 1
    print(String(num)) // 2
  }
}
```
Unityでのリフレクションプローブを使用しない鏡の実装

#1.初めに
　Unityで鏡を実装してみたくなり、ちょっと調べたところ、鏡面反射を実装するためにリフレクションプローブというものを用いるとありました。ところが、このリフレクションプローブにはカメラが６個含まれ、処理が重そうです。
　球体や立方体等の反射ならともかく、平面の鏡にそこまでたくさんのカメラは必要ないと思われます。そこで、リフレクションプローブを使用せず、カメラ１個で鏡を実装してみました。

#2.用意するもの
###a.鏡として用いるオブジェクト
平面でも、ほぼ平面状のでこぼこしたものでもいいです。反射面が一方向を向いているものしか対応できません。
###b.鏡用のカメラ
鏡に映る景色用のテクスチャをレンダリングするためのカメラです。
aの前に置いて、鏡の子にします。
###c.レンダーテクスチャ
bのカメラでレンダリングした風景が格納されます。
###d.鏡用のマテリアル
bのカメラから得たテクスチャcをaに貼り付けます。
###e.鏡用のカメラを反射方向に向けるスクリプト
bのカメラを反射方向に向けて鏡を再現します。

#3.作業手順
###(1)鏡用のオブジェクト(a)を設置
ここではヒエラルキーでマウスの右ボタンを押して、3D Object>Planeを選びます。
必要なら、適当にスケールを変えたり、移動させたり、回転させたりしてください。
###(2)レンダーテクスチャ(c)を作成
プロジェクトウインドウでマウスの右ボタンを押し、Create>Render Textureを選びます。
###(3)鏡用のカメラ(b)を設置
ヒエラルキーでマウスの右ボタンで作成します。Target Textureにレンダーテクスチャ(c)を指定してください。また、Target Displayはメインカメラとは異なるものを選択してください。
鏡用のオブジェクト(a)の前に置き、鏡用のオブジェクト(a)の子にします。![q20188181.png](https://qiita-image-store.s3.amazonaws.com/0/245844/bf3565af-f9df-47e2-630d-12cc6ff59e3c.png)

###(4)鏡用のマテリアル(d)の作成と適用
プロジェクトウインドウでマウスの右ボタンを押し、Create>Material。テクスチャとしてレンダーテクスチャ(c)を指定してください。
このマテリアル(d)をヒエラルキーの鏡用のオブジェクト(a)にドラッグ＆ドロップします。
この時点で、鏡用のカメラ(b)からみた風景が鏡用のオブジェクト(a)に映っているはずです。
###(5)鏡用カメラのスクリプト(e)を作成
このスクリプトで鏡用のカメラ(b)をメインカメラから鏡に向かうベクトルが鏡で反射される方向に向けます。

```C#:MirrorCam.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MirrorReflectionCam : MonoBehaviour {
    public Transform mainCam;
    public Transform mirror;


	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
        Vector3 A = mirror.position - mainCam.position;
        Vector3 refVec = Vector3.Reflect(A, mirror.up);

         
        Quaternion rot = Quaternion.LookRotation(refVec,mainCam.up);
        gameObject.transform.rotation = rot;

        
	}
}
```
このようなスクリプトを鏡用のカメラにアタッチします。インスペクタから、mirrorに鏡用のオブジェクト(a)を指定し、mainCamにメインカメラを指定します。
Vector3.Reflectは、入射ベクトルと反射面の法線を指定すると、反射ベクトルを返してくれる便利な関数です。


これで実行させれば、鏡用のオブジェクト(a)が鏡のように機能しているはずです。
![q20188182.png](https://qiita-image-store.s3.amazonaws.com/0/245844/7de60895-8838-06f8-addf-0d686366d709.png)

上のスクリーンショットのメインカメラと鏡、及び、その他のオブジェクトの位置関係は下のスクリーンショットのようになっています。移動用のピボットが出ているのが鏡用のカメラ(b)で、右下のカメラがメインカメラです。このスクリーンショットは実行中に一時停止したもので、鏡用のカメラ(b)が反射方向に向いていることがわかります。
![q20188183.png](https://qiita-image-store.s3.amazonaws.com/0/245844/8c645d25-a163-69ad-3f2f-8073b8151980.png)