OmniAICreator/Qiita-1.07M huggingface dataset:
Oculus Goのブラウザで日本語入力する

# はじめに

以前までは、Oculus Goのブラウザでは日本語入力を行うことができなかったが、
現在はいくつか代替方法があるようなので、これらの方法について備忘録として残す。

# 前提

* iPhoneのOculusアプリを使用
    * バージョン38.0
* Oculus Goの標準ブラウザを使用
    * 不明
* Firefox Realityを使用
    * バージョン7

# Oculusアプリのリモートキーボードを使う方法

* Oculus Goの標準ブラウザを起動する。
* URLや入力フォームにフォーカスを当て、キーボードを立ち上げる。
* キーボード上のスマートフォンのアイコンをクリックする。
* アイコンをクリックすると、Oculusアプリに通知が行くので、通知をクリックしてリモートキーボードを起動する。
    * 通知をクリックしない場合は、お知らせ画面に表示されるリンクをクリックする。
* アプリのリモートキーボード画面で日本語を入力 あるいは 貼り付けて、入力ボタンを押下する。
    * 入力内容がOculus Goにペーストされる。

# Firefox Realityを使用する方法

* Oculus GoのFirefox Realityを起動する。
* URLや入力フォームにフォーカスを当て、キーボードを立ち上げる。
* キーボードの地球儀アイコンを押下し、日本語を選択する。
    * ローマ字入力で日本語を入力できる。

# さいごに

Oculusアプリのリモートキーボードを使用する場合は、MacからiCloudのクリップボード経由でiPhoneにテキストをコピーし、リモートキーボードにテキストを貼り付けると長文のテキスト入力がより簡易的になる。

また、Firefox Realityを使用する場合は、リモートキーボードでテキスト入力することができない。ただし、MacにFirefoxをインストールしておき、Oculus GoのFirefox RealityとMacのFirefoxで同一のアカウントを設定しておくと、表示中のタブを同期できて便利である。
大量の点の 2 次元プロット（regl-scatterplot）

こんにちは。
[regl-scatterplot](https://github.com/flekschas/regl-scatterplot/) (GitHub) を見つけ、そっくりそのままを動かしてみました。

* [WebGL-based Scatterplot build with Regl ](https://flekschas.github.io/regl-scatterplot/)(regl-scatterplot demo)

100万点（a million）をプロットした場合もスクロール・ズームのレスポンスについては良いようです[^1]。

[^1]: なお、[regl](https://github.com/regl-project/regl) をシンプルに用いて大量プロット性能をより向上させる試みは、「[大量の点の 2 次元プロット（regl）](https://qiita.com/kkdd/items/8b46c5e7362397a9c627)」。

<img width="120" alt="scatter.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54617/c8227c30-207e-cdbf-5986-5ff3e9d1f8cb.jpeg">

```index.html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>regl-scatterplot</title>
  <style type="text/css">
    #canvas-wrapper {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
    }
    #canvas {
      position: absolute;
      width: 100%;
      height: 100%;
    }
  </style>
</head>
<body>
  <div id="canvas-wrapper"><canvas id="canvas"></canvas></div>
  <script src="https://www.unpkg.com/pub-sub-es@2.0.1/dist/pub-sub-es.js"></script>
  <script src="https://npmcdn.com/regl@2.0.1/dist/regl.js"></script>
  <script src="https://www.unpkg.com/regl-scatterplot@0.17.0/dist/regl-scatterplot.js"></script>
  <script>
    const pointSize = 3;
    const nPoints = 10000;
    const colors = ['#00ff00', '#ff8080', '#8080ff'];

    const canvas = document.getElementById('canvas');
    const scatterplot = createScatterplot.default({canvas});
    scatterplot.set({pointSize});
    scatterplot.set({colorBy: 'category', pointColor: colors});

    const resizeHandler = () => scatterplot.set(canvas.getBoundingClientRect());
    resizeHandler();
    window.addEventListener('resize', resizeHandler);

    const rng = () => Math.random() * 2 - 1;
    const points = new Array(nPoints)
      .fill()
      .map(() => [
        rng(),  // x
        rng(),  // y
        Math.floor(Math.random() * colors.length)  // category
      ]);
    scatterplot.draw(points);
  </script>
</body>
</html>
```

#### Highcharts

なお、[Scatter plot with 1 million points](https://www.highcharts.com/demo/scatter-boost) (Highcharts demo) （大量の点をプロット）も調べました。各点を色指定する機能（```colorByPoint```）は、 ```boost.js``` 内（WebGL 利用の場合）で現状無効化されているようです[^2]。

[^2]: [Scatter Plot Points don't retain individual color values when using boost.js](https://github.com/highcharts/highcharts/issues/5999) (highcharts issue, GitHub)
【R】Hardy-Weinberg平衡（Fisherの正確確率検定）

#はじめに
仕事で統計遺伝学が必要になりそうなので、[実践でわかる!Rによる統計遺伝学](https://www.amazon.co.jp/%E5%AE%9F%E8%B7%B5%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8B-R%E3%81%AB%E3%82%88%E3%82%8B%E7%B5%B1%E8%A8%88%E9%81%BA%E4%BC%9D%E5%AD%A6-%E3%82%A2%E3%83%B3%E3%83%89%E3%83%AC%E3%82%A2%E3%83%BBS-%E3%83%95%E3%82%A9%E3%83%AB%E3%82%AF%E3%82%B9/dp/4621300059)を始めた。

備忘録的に記していく。

#使用するデータ
使用するデータは本で指定されたURLから。

**FAMussデータ**
http://pub.maruzen.co.jp/book_magazine/support/r_toukeiidengaku/FMS_data.txt

#必要なパッケージ
**genetics**パッケージをインストールしておく。

```R
install.packages("genetics")
```
そして読み込む。

```R
library(genetics)
```

#データの読み込み
FAMuSSデータを読み込む。
**read.delim()**関数は、データ区切りがタブの場合。

参考
[ファイルからデータを読み込むとき](http://cse.naro.affrc.go.jp/takezawa/r-tips/r/40.html)


```R
fms <- read.delim("http://pub.maruzen.co.jp/book_magazine/support/r_toukeiidengaku/FMS_data.txt",fileEncoding="cp932")
```

**attach()**関数を使うことで、データフレーム名を使わず変数名だけを用いて変数を指定する。

```R
attach(fms)
```

#Fisherの正確確率検定を用いたHardy-Weinberg平衡の検定
**genetics**パッケージの**HWE.exact()**関数を使って求める。

5未満の期待度数が全セルの20%以上ある場合はピアソンのχ二乗検定を使わずにFisherの正確確率検定を使う。

民族が`African Am`だけを用いる。

```R
Akt1SNPAfricanAm <- genotype(akt1_t10726c_t12868c[Race == "African Am"], sep = "")
HWE.exact(Akt1SNPAfricanAm)
```

実行結果。

```R
> Akt1SNPAfricanAm <- genotype(akt1_t10726c_t12868c[Race == "African Am"], sep = "")
> HWE.exact(Akt1SNPAfricanAm)

	Exact Test for Hardy-Weinberg Equilibrium

data:  Akt1SNPAfricanAm
N11 = 18, N12 = 18, N22 = 1, N1 = 54, N2 = 20, p-value = 0.2353
```

この結果から*p*値は0.2353で、この集団では帰無仮説のHardy-Weinberg平衡を棄却できない。

#最終的なスクリプト

```R
#Rをきれいにする
rm(list = ls())

#データの読み込み
fms <- read.delim("http://pub.maruzen.co.jp/book_magazine/support/r_toukeiidengaku/FMS_data.txt",fileEncoding="cp932")

#ライブラリの読み込み
library(genetics)

#attach()関数でデータフレームを指定
attach(fms)

#Fisherの正確確率検定を用いたHardy-Weinberg平衡の検定
#変数Raceの水準の確認
table(Race)

Akt1SNPAfricanAm <- genotype(akt1_t10726c_t12868c[Race == "African Am"], sep = "")
HWE.exact(Akt1SNPAfricanAm)
```
diskpartコマンドでHDDを初期化する

## 環境

- windows 10 Home

## 管理者権限でcmdを開く

- ```Win + R```で「ファイル名を指定して実行」を開く
- ```cmd```と入力
- ```Ctrl + Shift + Enter```

## diskpartコマンドを実行する

```
> diskpart

Microsoft DiskPart バージョン 10.0.18362.1

Copyright (C) Microsoft Corporation.
コンピューター: XXXXX

DISKPART>
```

## ディスクを選択する

```
DISKPART>list disk

  ディスク      状態           サイズ   空き   ダイナ GPT
  ###                                          ミック
  ------------  -------------  -------  -------  ---  ---
  ディスク 0    オンライン          xxxx GB  xxxx KB
  ディスク 1    オンライン          xxxx GB  xxxx KB       <-今回はこのディスクを初期化する
  ディスク 2    オンライン          xxxx GB  xxxx KB

DISKPART> select disk 1

ディスク 1 が選択されました。

DISKPART> list disk

  ディスク      状態           サイズ   空き   ダイナ GPT
  ###                                          ミック
  ------------  -------------  -------  -------  ---  ---
  ディスク 0    オンライン          xxxx GB  xxxx KB
* ディスク 1    オンライン          xxxx GB  xxxx KB       <-選択すると"*"が表示される
  ディスク 2    オンライン          xxxx GB  xxxx KB
```

## 消去する

選択中のディスクが処理対象になります。
データ含めパーティションも全て消去されるので注意。

```
DISKPART> clean

DiskPart はディスクを正常にクリーンな状態にしました。
```

## GPT形式にする

```
DISKPART> convert gpt

DiskPart は選択されたディスクを GPT フォーマットに正常に変換しました。
```

## パーティション作成

```
DISKPART> create partition primary

DiskPart は指定したパーティションの作成に成功しました。

DISKPART> list partition

  Partition ###  Type                Size     Offset
  -------------  ------------------  -------  -------
  Partition 1    予約                  15 MB    17 KB
* Partition 2    プライマリ             xxxx GB    16 MB
```

今回は1パーティション構成にしましたが
複数パーティンを作成する場合はサイズを指定しましょう。

```
DISKPART> create partition primary size=xxxxx
```

## フォーマット

今回はファイルシステムにNTFSを指定しています。
quickを付けないととても時間がかかります。

```
DISKPART> format fs=ntfs quick

  100% 完了しました

DiskPart は、ボリュームのフォーマットを完了しました。
```

## ドライブ割り当て

今回はGドライブに割り当てました。

```
DISKPART> assign letter=g

DiskPart はドライブ文字またはマウント ポイントを正常に割り当てました。
```

割り当てた結果は```list volume```で確認できます。

## 終了

```
DISKPART> exit
```

## 参考

https://euc-access-excel-db.com/tips/ct07_se/ct070610_ready_hdd/diskpart
ガンタンクをRaspberry Piで動かすことを目指す#2 ガンタンク作成編 V作戦

[ガンタンクをRaspberry Piで動かすことを目指す#1 準備編](https://qiita.com/never_nothing/items/0c26515a7a3a7590c734)
の続き

#ガンタンク本体組み立て
今回はガンタンクの組み立てだけで、まだプログラミングも電子工作も関係ない。
(消さないで)

##普通にMG(1/100)ガンタンクを組み立て
このMGガンタンクはほぼ接着剤なしではめ込みで組み立てることができる。
もちろんちゃんと綺麗に仕上げるには接着剤を使用したほうがいいが、
今回は内部にモーターなどを組み込む為にまたバラすことになるので
極一部を除いて基本的に接着剤なしで組み立てた。
デカールもシールも貼っていないし
スミ入れも塗装もしていないしトップコートも吹いていないまったくの素組み状態である。

![GUNTANK10.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125160/768231c4-a3ea-71cb-02f9-f86251ff4228.jpeg)
![GUNTANK11.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125160/aabde497-4828-a33f-4265-6d24eb8488e5.jpeg)
![GUNTANK12.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125160/55198a91-0731-db95-27af-79dd4c17cec8.jpeg)
![GUNTANK13.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125160/79d6e892-c053-72b3-64a4-64534e3def1c.jpeg)
![GUNTANK14.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125160/75ec8f02-b5b7-6c24-485a-c370637d02e9.jpeg)
![GUNTANK15.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125160/491bfaf1-2a55-d3d1-1843-61653aeb98c5.jpeg)

##そしてバラして内部構造の取り出し
MGシリーズはHGシリーズと違って内部構造を再現した「中身」が存在する。
これはリアルさを求めるのならばカッコいいが
中にモーターなどを詰め込むのにはジャマである。
よって組み立てたガンタンクをバラして外装と内部構造を分ける。

以下が今回必要のない「中身」
![GUNTANK20.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125160/deb39d45-7015-32af-fdfb-47c17c672385.jpeg)
![GUNTANK21.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125160/59e30e9b-aa32-45e5-b59b-d5f069c05588.jpeg)

せっかくのコアブロック(コアファイター)だが今回はジャマなのでオミットする。
ちなみにこのコアファイターのコクピットにいるのはリュウ・ホセイである(察し)南無

履帯(※無限軌道もしくはキャタピラとも言うが「キャタピラー」はアメリカの会社のことを指すことが多く商標などのややこしいことを避けるためか?、履帯(りたい)と呼ぶことが多い)も別途タミヤのキットのものを使う為、付属のものは使わない。というかすぐ外れてばらけるので使い物にならない。

背中にはバッテリーを乗せるつもりなので背中のダクトもオミットする。

右下に写っているのはLEDユニットで頭のコクピットを光らせることができる。
これもジャマなのでオミットする。

##外部装甲など使用する部分
残った外部装甲とキャノン砲、腕、頭部が以下の写真
![GUNTANK22.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125160/35304946-ad58-637f-18fb-51ca19a937f1.jpeg)

腰回りが本来は内部構造にはめ込みで付ける方式なので
内部構造が無いとバラバラである。
これはプラ板とパテで内側から補強してくっ付けるしかないか。
それは後で追々やっていく。

##次は
次はモーターとギアボックス、履帯を受け持つタミヤのキットを組み立てる。

[ガンタンクをRaspberry Piで動かすことを目指す#3 タミヤキット作成編](https://qiita.com/never_nothing_jp/items/c62fb219c1ec42a0b7cc)へ続く
GrovePi GPS をRaspberry Pi Zeroで使う

# やること
http://wiki.seeedstudio.com/Grove-GPS/
このSeeedのGPSモジュールを、ラズベリーパイZero用ベースハットに接続して動かす。
このSeeedのWikiの情報が古いのでハマった。のでメモ。

# 手順
ラズベリーパイZero用ベースハット（緑色の基板）だと、RPISERという口は無い。代わりにUARTのところに、GPSのモジュールを接続する。
以下でgrovepiを入れる。

```sh
ssh pi@yourhost
# login to raspi zero
sudo curl -kL dexterindustries.com/update_grovepi | bash
```
以下のREADMEに沿って、config.txt、cmdline.txt のコンフィグレーションを行う。
https://github.com/DexterInd/GrovePi/blob/master/Software/Python/grove_gps/README.md
そして、

```sh
git clone https://github.com/DexterInd/GrovePi.git
cd GrovePi/Software/Python/grove_gps
sudo python3 dextergps.py
```

結果、READMEにあるような、

```
['$GPGGA', '150954.000', '4520.7858', 'N', '02557.6659', 'E', '1', '5', '2.84', '76.9', 'M', '36.1', 'M', '', '*6E']
```
という値が取得できました。緯度経度がほしいので、 `dextergps.py` のmainに、

```py
        if in_data != []:
            # print (in_data)
            print(gps.latitude)
            print(gps.longitude)
```
とすると、無事緯度経度がとれました。
【Python】scheduleを使ってモジュールを定期実行させよう

モジュールを定期的に実行させるのに便利なscheduleモジュールを紹介します。scheduleは一定の間隔(数分・数時間・数日おき)に同じ作業を実行するような場合に便利なモジュールです。webスクレイピングで情報収集を行う場面などで便利なモジュールとなります。

今回は基本的なscheduleモジュールの使用法をまとめた後、スクレイピングを定期的に実行するモジュールを実装例としてご紹介します。

# scheduleのインストール
scheduleモジュールはpipコマンドで入手可能です。コマンドプロンプト上で以下のコマンドを実行するとインストールされます。

```
pip install schedule
```

# サンプルコード

```python:sample_schedule.py
import schedule
import time

# 実行job関数
def job():
    print("job実行")


#1分毎のjob実行を登録
schedule.every(1).minutes.do(job)

#1時間毎のjob実行を登録
schedule.every(1).hours.do(job)

#AM11:00のjob実行を登録
schedule.every().day.at("11:00").do(job)

#日曜日のjob実行を登録
schedule.every().sunday.do(job)

#水曜日13:15のjob実行を登録
schedule.every().wednesday.at("13:15").do(job)

# jobの実行監視、指定時間になったらjob関数を実行
while True:
    schedule.run_pending()
    time.sleep(1)
```

scheduleのサンプルモジュールです。ある間隔ごとにjob関数が実行され、「job実行」が表示されるモジュールとなります。```schedule.every```は実行するjobと実行間隔を登録する記述となります。数分ごとや数時間ごと、さらに特定日時の実行も可能です。

```python
# 1分毎にjobを実行
schedule.every(1).minutes.do(job)
```

上記の```schedule.every```で登録したjobは以下の```schedule.run_pending()```で実行されます。普通に```schedule.run_pending()```を呼び出しただけでは、一度jobを実行した時点で、モジュールが終了してしまうため、**while文で無限ループ状態**にする必要があります。無限ルール状態にすることで、同じ処理を一定間隔で実し続けることが可能です。


```python
while True:
    schedule.run_pending()
    time.sleep(1)
```

# scheduleを使ってYahooニュースの採取を定期実行
今回紹介したscheduleモジュールを使用して、定期的にスクレイピングを実行するようなモジュールを作成しました。１時間ごとにYahooニュースにアクセスし、ニュースのタイトルとURLを取得するようなモジュールです。

```python:scraping_schedule.py
from urllib.request import urlopen
from urllib.error import HTTPError
from urllib.error import URLError
from bs4 import BeautifulSoup
import re
import schedule
import time

def job():
    try:
        html = urlopen('https://news.yahoo.co.jp/topics')
    except HTTPError as e:
        print(e)
    except URLError as e:
        print(e)

    else:

# Yahooトピックスにアクセスし、ニュース情報を採取
        bs = BeautifulSoup(html.read(), 'lxml')
        newsList = bs.find('div', {'class': 'topicsListAllMain'}).find_all('a')

# 取得したListからニュースのタイトルとURLを取得して表示
        for news in newsList:
            if re.match('^(https://)', news.attrs['href']):
                print(news.get_text())
                print(news.attrs['href'])

#1時間毎にjobを実行
schedule.every(1).hours.do(job)

while True:
    schedule.run_pending()
    time.sleep(1)
```

# まとめ
今回は定例的ないjobを一定間隔で実行させることができるscheduleモジュールをご紹介しました。私は主にスクレイピングなどで活用することが多いですが、作業の定期実行にも使えるモジュールではあるので、使用用途はとても広いと思います。

# 参考文献
[Python Scheduleライブラリでジョブ実行](https://qiita.com/Kai-Suzuki/items/0c5c0e5cbdb4075fe482)
[scheduleライブラリを使ってPythonスクリプトを定期実行しよう](https://tadaken3.hatenablog.jp/entry/python-schedule)
mac環境でfindとxargsを使う時は-print0と-0を必ずつける(戒め

Mac OSの場合はディレクトリ名及びファイル名に空白(0x20)を入れることができるため、`find`及び`xargs`の区切り文字をデフォルトの空白のままにしておくと、想定外のフォルダやファイルを処理してしまう可能性があります。



例えば、こういうディレクトリがあったとして

```bash
$ tree
.
├── a
├── a\ b
└── b

3 directories, 0 files
```

`a b`ディレクトリを削除するために以下のコマンドを実行するとする

```bash
$ find . -name 'a b' | xargs rm -rf
```

`a b`ディレクトリが削除され、`a`ディレクトリと`b`ディレクトリはそのままになってて欲しいが、結果は以下のように`a`ディレクトリと`b`ディレクトリが削除されてしまう。

```bash
$ tree
.
└── a\ b

1 directory, 0 files
```

対策としては、タイトルにも書いてあるとおりfindコマンドの-print0及びxargsに-0をつけることで対処できます。

```bash
$ tree
.
├── a
├── a\ b
└── b

3 directories, 0 files

$ find . -name 'a b' -print0 | xargs -0 rm -rf

$ tree
.
├── a
└── b

2 directories, 0 files
```

まあディレクトリ名にスペースが入ってる時点でちょっとあれなんですけど。。。
PythonでABC100のA~C問題を解く

### はじめに
[tax_free](https://twitter.com/taxfree_python)です。今回から、ABC(AtCoder Beginner Contestの略)をPython3で解いていきたいと思います。モチベーションは、単純にAtCoderが楽しいというのとCまで安定して解けるようになりたいからです。  ~~レートを上げたい~~
現在のレートは<img width="952" alt="スクリーンショット 2019-12-30 19.02.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273421/0f741c19-dded-9326-105b-67694cd5317c.png">
です。がんばって緑になりたい。モチベーションが続くかぎり記事を書いていきます。

### A問題
[問題](https://atcoder.jp/contests/abc100/tasks/abc100_a)  
**考えたこと**
A,Bは入力値  
直感的にA,Bのどちらかが9以上だと必ず隣合うことが分かる。また、A,Bが共に8以下ならば、交互にケーキを取ることで条件を満せることが分かる。  

```python

a, b = map(int,input().split())
if a < 9 and b < 9:
    print('Yay!')
else:
    print(':(')
```
これで、ACでした。

### B問題
[問題](https://atcoder.jp/contests/abc100/tasks/abc100_b)  
**考えたこと**
D,Nは入力値  
問題文のちょうど100でD回割り切れるというのは、$100^D+N$と同じと思い、

```python

d ,n = map(int,input().split())
if d == 0:
    ans = []
    for i in range(1,101):
        ans.append(i)
    print(ans[n-1])
else:
    a = 100 ** d * n
    print(a)
```
このコードは2ヶ月前の自分が書いたものなので、どういう意図で書いたのか理解できません。(この頃はまだ初めて1週間とか)。しかし、この書き方だと、**$n≥100$**の時の処理がうまくいきません。理由は、$n≥100$になるともう一回100で割ることができるようになるからです。ここまで、nが100以上と言いましたが、問題文より**$n≤100$**なので、$n=100$のときだけ繰り上げればよいです。

```python

d ,n = map(int,input().split())
if n == 100: n+=1
print(n*(100**d))
```
ずいぶんスッキリしました。if文を使うことによって$n=100$を考えることができるようになりました。これでACでした。


### C問題
[問題](https://atcoder.jp/contests/abc100/tasks/abc100_c)  
**考えたこと**
N,aは入力値  
a[i]は1≤i≤Nと満たすaのi番目の値
最初に問題を見た時に、a[i]は整数でなければならないと書いているので最小値は1になりそうだと思いました。また、aの要素が全て奇数だった場合は例2のように出力は0になります。なので、aをlistで受け取ってすべてのa[i]が1になるまで2で割っていけばよいのではと思いました。

```python

n = int(input())
a = list(map(int,input().split()))
ans = 0
for i in range(0,n):
    if a[i] % 2 == 0 :
        while a[i] % 2 == 0:
            a[i] //= 2
            ans += 1
print(ans)
```
while文でa[i]が1になるまで2で割り続けています。

###まとめ
今回は、解説を見ることなくA~Cを解けたのでうれしかったです。今後も精進して緑に行けるようにがんばります。
Hero7 on DISCO

####DISCOで真俯瞰の写真を撮る
オルソフォトを作成するための写真は真俯瞰で撮るのが一番つなぎやすい。
もちろん斜めや角度、高度の異なる写真を使っても作成することは可能だが、処理をシンプルにするためには真俯瞰がいい。ParrotDISCOはノーズに20度ほど傾斜をつけたカメラが（主に操縦とその様子を撮影するため）あるのみ。
上位グレードのDiscoAGは同社のマルチスペクトラルカメラのSequoiaを機体中央に載せている。DISCOとDiscoAGはボディ形状は、背中の太陽光センサー窓とおなかのSequoiaのレンズ窓くらいだ。
今回DISCOにアクションカメラのご本家「GoProHERO7」を載せようと目論む。
GoproHeroシリーズはHero5からGPS内蔵であり、Discoのペイロード、前後バランスはAGでのSequoiaを載せているくらいだから、大丈夫であろう。
youtube上でいくつかの同様例を見ているので、そのまんま真似てみようと思う。
####開胸手術
ということで、Hero7埋め込み手術である。Hero7のサイズを測ると72mm*45mmにレンズカバー部分の出っ張りが32mm*29mm。DISCOのボディは二層に分れており、上の段にボディ、下の段にレンズの出っ張りを位置させると収まりがよい。で、そのサイズを切り取る。。
![IMG_2565 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539556/d3ad67e1-2146-0a52-cfa6-4bce6d0ed701.jpeg)

切り取ったあとがコレ
![IMG_2559 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539556/441dda37-ba0b-7bec-0653-220bca670028.jpeg)
![IMG_2560 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539556/b51b1cce-f710-5bf0-01a6-2bb98e79981c.jpeg)

Hero7を埋め込むとこんな感じ
![IMG_2561 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539556/19ad2b87-59c2-c68a-ba74-21722e0b3afc.jpeg)
![IMG_2562 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539556/afb66674-37f7-817e-ba62-4325e9dfdbd5.jpeg)
ボディの厚みからレンズ部分は結構引っ込むが、ケラレはないのを確認。
バッテリーを立てて少しでも前後バランスの変化を抑えようと思ったが、CHUCKのバッテリーコネクタ部分と干渉するので断念。
見た目よろしくないが、まあ良しとしよう。
（テストフライトに続く）
pigzでプログレスバーを表示させる

pvコマンドを使えば出せる。

### pvコマンドのインストール

```sh
sudo apt install pv
```

### 圧縮

```sh
pv hoge.fastq | pigz -p 8 > hoge.fastq.gz
```


備考

ディスクの書き込み速度をmonitorで見ていると、`-p 8` でもせいぜい10MiB/s 程度のようある。
おおざっぱに、HDDの書き込み速度が 60〜120 MiB/s 程度、SSDの書き込み速度が 400〜500 MiB/s 程度だとすると、HDDを使っている場合でも `-p 16` としても書き込み速度が律速になることはなく、安心してプロセスの数を増やせる気がする。
TensorflowのFreezeGraph済み.pbファイルのINPUTのPlaceholderを置き換えつつモデルを再生成するTips [置換・置き換え・変換・変更・更新・差し替え]

**`[1, ?, ?, 3]`** の入力サイズで定義されている .pbファイル の **`Placeholder`** を **`[1, 513, 513, 3]`** の **`Placeholder`** に強制的に置き換えて、.pbを再生成するサンプルプログラム。

**`name='image'`** の部分は置き換え後のPlaceholderの名前を自由に指定する。
**`input_map={'image:0': inputs}`** の **`image:0`** の部分は、変換前のモデルのPlaceholder名を指定する。

```python:replacement_of_input_placeholder.py
import tensorflow as tf
from tensorflow.tools.graph_transforms import TransformGraph

with tf.compat.v1.Session() as sess:

    # shape=[1, ?, ?, 3] -> shape=[1, 513, 513, 3]
    # name='image' specifies the placeholder name of the converted model
    inputs = tf.compat.v1.placeholder(tf.float32, shape=[1, 513, 513, 3], name='image')
    with tf.io.gfile.GFile('./model-mobilenet_v1_101.pb', 'rb') as f:
        graph_def = tf.compat.v1.GraphDef()
    graph_def.ParseFromString(f.read())

    # 'image:0' specifies the placeholder name of the model before conversion
    tf.graph_util.import_graph_def(graph_def, input_map={'image:0': inputs}, name='')
    print([n for n in tf.compat.v1.get_default_graph().as_graph_def().node if n.name == 'image'])

    # Delete Placeholder "image" before conversion
    # see: https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/graph_transforms
    # TransformGraph(
    #     graph_def(),
    #     input_op_name,
    #     output_op_names,
    #     conversion options
    # )
    optimized_graph_def = TransformGraph(
                              tf.compat.v1.get_default_graph().as_graph_def(),
                              'image',
                              ['heatmap','offset_2','displacement_fwd_2','displacement_bwd_2'],
                              ['strip_unused_nodes(type=float, shape="1,513,513,3")'])

    tf.io.write_graph(optimized_graph_def, './', 'model-mobilenet_v1_101_513.pb', as_text=False)
```

```console:Result
[name: "image"
op: "Placeholder"
attr {
  key: "dtype"
  value {
    type: DT_FLOAT
  }
}
attr {
  key: "shape"
  value {
    shape {
      dim {
        size: 1
      }
      dim {
        size: 513
      }
      dim {
        size: 513
      }
      dim {
        size: 3
      }
    }
  }
}
]
```
- **変換前**
![Screenshot 2019-12-30 23:39:02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194769/b49cf2b7-82fc-0a94-b4b3-8560481a2fea.png)
- **変換後**
![Screenshot 2019-12-30 23:38:04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194769/29745097-f565-4016-5e90-3f9c8c44ecb0.png)



**Graph Transform Tool**
**https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/graph_transforms**
Railsのデータベースをポスグレに指定して、プロジェクトを立ち上げる方法



①ポスグレのインストール

```
$ brew update
$ brew install postgresql
```

②ポスグレを起動するとエラーがでる

```
$ postgresql
postgres does not know where to find the server configuration file.
You must specify the --config-file or -D invocation option or set the PGDATA environment variable.
```

③エラーの解消
コンフィグファイルの設定をして下さいと書いている。
ホームディレクトリに戻る

```
$ cd ~
```

ホームディレクトリに設定用のファイル".bash_profile"、".bashrc"があるか下記コマンドで確認

```
$ ls -a
```

ない場合は、下記コマンドで作る

```
$ touch ~/.bash_profile
$ touch ~/.bashrc
```

再度確認すると、ある。

```
$ ls -a
```

.bash_profileと、.bashrcの説明は下記URLを参照
https://qiita.com/takutoki/items/021b804b9957fe65e093

先ほど作った、~/.bash_profileに環境変数を設定してパスを通す

④下記コマンドで、ターミナルをコマンドモードに切り替る

```
$ vi .bash_profile
```

⑤コマンドモードに入ったらiを押してインサートに切り替える

```
i
```

⑥下記、環境変数を追記する

```
export PGDATA='/usr/local/var/postgres'
```

⑦保存してコマンドモードを終了する

```
キーボード【ESC】
```

↓

下記コマンドを入力

```
:wq
```

⑧下記コマンドを入力して変更を反映させる

```
$ source .bash_profile
```

⑨下記コマンドにて、postgresqlが立ち上げれば設定完了

```
$ postgres
```

⑩データベースをポスグレに指定し、好きなバージョンも指定し、Railsプロジェクトを作成して終了

```
$ rails _5.1.7_ new アプリ名 -d postgresql
```
テストで使いたくて，DinD (Docker in Docker) でk8sの環境を整えた

# TL;DR
- こちらのDockerfileを見納めください
- kindとアプリケーションのコンテナを分けても良かったのですが，kubeconfigの受け渡しが面倒だったので妥協しました
- https://github.com/tozastation/kw/blob/master/Dockerfile.test

## 事の経緯
- Kubernetesを制御するツールを書きたい．
- テストのために，KubernetesクラスタをホストPCに建てるの面倒だし，環境を汚したくない．．．
- [kind](https://github.com/kubernetes-sigs/kind) (kubernetes in docker) なるものを発見   
- しかし，アプリの開発をDocker内で行っていると，  
kindとアプリのコンテナは同一ネットワークに参加していないため，ネットワーク的に参照できないという問題が  

> [クラスタを作るときにネットワークを指定する系のissueを見つけた](https://github.com/kubernetes-sigs/kind/issues/273)

## そこで，DinD (Docker in Docker)
クラスタの作成をホスト側でなく，コンテナ内のDockerで行うことによってネットワーク的に参照可能にする．  
### kind in DinD
- `docker:dind`というベースイメージがAlpineなので追加パッケージがある場合は，`apk`を使います．
- [使い方はこちらの記事が参考になります](https://qiita.com/sugiyasu-qr/items/85a1bedb6458d4573407)

```dockerfile
FROM docker:dind
RUN apk --no-cache add curl
RUN curl -Lo /usr/local/bin/kind https://github.com/kubernetes-sigs/kind/releases/download/v0.6.1/kind-$(uname)-amd64 && chmod +x /usr/local/bin/kind
```
#### kindでクラスタ作成 (Docker Deamonの起動を待つ必要あり)
以下をコンテナ内で実行すれば環境構築完了です！

```sh 
# クラスタの作成
 kind create cluster
# KUBECONFIGに，作成したクラスタのkubeconfigパスを登録
 export KUBECONFIG="$(kind get kubeconfig-path --name="kind")"
```

#### dindコンテナを立ち上げるときに詰まった点
- 問題
    - docker run 時に，コマンドを渡すとdocker deamonが起動しなく，kindを実行できなかった
- 解決策
    - docker run 実行後，execでコマンドを渡すようにする

## まとめ
- kubernetesの環境構築は，[minikube](https://kubernetes.io/ja/docs/tutorials/hello-minikube/)なりkindが，Dockerで構築するオプションを提供してくれていて非常に便利だなと思いました．お試しで気軽に建てるときには自分も重宝しようと思います．
- DinDは初めて使いましたが，プロジェクトごとにDockerが作れるためホストから見たときのコンテナが散らからなくて管理しやすそうという印象です．
- Kubernetesアプリとかプロバイダー作っている世の方々はテスト用のクラスタ構築とかどうされているのかなと気になりました．
RubyとRailsのバージョンの変更方法

#Rubyのバージョン変更方法

①利用中のRubyバージョン確認

```
$ ruby -v
```


②インストール可能なRubyバージョン確認

```
$ rbenv install --list
```


③目的のバージョンをインストール（1-2時間かかります）

```
$ rbenv install 2.6.3
```

④利用するバージョンを変更

```
$ rbenv global 2.6.3
```

⑤現在コンソール上で利用しているRubyバージョン確認

```
$ rbenv versions
```

⑥rehashしてあげる　※ファイルの場所を変更して使えるようにする

```
$ rbenv rehash
```

#指定したRailsのバージョンでプロジェクトを立ち上げる方法

①現在インストールされていて、使用できるRailsの確認

```
$ gem list rails
```

②Railsの使用したいバージョンをインストール（使用したいバージョンが無かった場合）

```
$ gem install rails -v 5.1.7
```

もう一度、使用できるRailsの確認をすると追加されている

```
$ gem list rails
```

③バージョンを指定してプロジェクトを立ち上げる

```
$ rails _5.1.6_ new sample_app
```
眺めて覚えるGo言語 その7 GO言語の中にC言語

##GO言語の中にC言語を書いてみよう。
###準備　GCCをインストールしておきます。

- Windows 10 64bitの場合
- [mingw-w64-install.exe](https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/installer/mingw-w64-install.exe/download)をインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/9920ed7d-c90c-6709-6f5e-16a1e81ac0f6.png)
**x86_64**を選択します。
最初の一歩は、いつもの **Hello World**

```cPrint.go
package main

// #include <stdio.h>
// #include <stdlib.h>
//
// static void cprint(char* s) {
//   printf("%s\n", s);
// }
import "C"
import "unsafe"

func main() {
	cs := C.CString("Hello World C")
	C.cprint(cs)
	C.free(unsafe.Pointer(cs))
}

```
# //のコメント部分にC言語でコーディングします。

- 上記の例は、cprint関数を定義してprintfを呼び出しています。
- Cのfree関数を呼んでいます。
- 上記に必要なincludeを

1 stdio.h  printf
2 stdlib.h free
で行っています。

```
>go run cprint.go
Hello World C
```
#配列を渡して合計を求める。(int *)版

```sum.go
package main

// int cal_sum(int *x,int n) {
// int sum=0;
//	for(int i=0;i<n;i++){
// 		sum+=x[i];
//  }
// return sum;
//}
import "C"
import "fmt"

func main() {
	x := []C.int{1, 2, 3, 4,5,6,7,8,9,10}
	a:=C.cal_sum((*C.int)(&x[0]),(C.int)(len(x)))
	fmt.Println("sigma x=",a)
}

>go run sum.go
sigma x= 55
```
#配列を渡して合計を求める。(float *)版

```sigma.go
package main

// float cal_sum(float *x,int n) {
// float sum=0.0;
//	for(int i=0;i<n;i++){
// 		sum+=x[i];
//  }
// return sum;
//}
import "C"
import "fmt"

func main() {
	x := []C.float{10.0, 20.0, 30.0, 40.0,50.0,60.0,70.0,80.0,90.0,100.0}
	a:=C.cal_sum((*C.float)(&x[0]),(C.int)(len(x)))
	fmt.Println("sigma x=",a)
}
```
##配列を渡して平均を求める。(float *)版

```avr.go
package main

// float cal_sum(float *x,int n) {
// float sum=0.0;
//	for(int i=0;i<n;i++){
// 		sum+=x[i];
//  }
// return sum/n;
//}
import "C"
import "fmt"

func main() {
	x := []C.float{10.0, 20.0, 30.0, 40.0,50.0,60.0,70.0,80.0,90.0,100.0}
	a:=C.cal_sum((*C.float)(&x[0]),(C.int)(len(x)))
	fmt.Println("avr a=",a)
}

>go run avr.go
avr a= 55
```

#[CGO](https://golang.org/cmd/cgo/)は、なかなか便利な仕組みです。

- C言語が使えれば容易にI/Oなどにアクセスするインターフェースを書くことができる。
Electronで「要素の検証」を再現する方法

##本文
初投稿です。
Chromeで右クリックすると出てくる「検証(I)」。
押すとデベロッパーツール内でカーソル直下の要素にジャンプします。
Electron内でも使えると開発中なにかと便利なので、この機能を再現してみます。

##openDevTools

Electronで単にデベロッパーツールを開く場合は`webContents.openDevTools([options])`を使います。

```javascript
const { remote } = require('electron')
const webContents = remote.getCurrentWindow()
webContents.openDevTools()
```
modeオプションで表示位置の指定ができます。

| mode |状態|
|:-:|:--|
|right|画面右に表示|
|bottom|画面下に表示|
|detach|別ウィンドウに切り離して表示|
|undocked|別ウィンドウに切り離すが画面内に戻すこともできる|
```javascript
webContents.openDevTools({ mode: 'undocked' })
```
※webviewタグによって作られたwebContentsにはmodeの指定ができないようです。（detachのみ）
https://electronjs.org/docs/api/web-contents#contentsopendevtoolsoptions

##inspectElement
一方、`webContents.inspectElement(x, y)`は指定された位置の要素をデベロッパーツール内で開きます。

以下はマウス右クリックで「要素の検証」メニューを表示するサンプルです。
右クリックを使うアプリだと、イベントが干渉してしまうので僕は中央ボタンに割り当てています。

```javascript
  const { remote } = require('electron')
  const { Menu, MenuItem } = remote
  const webContents = remote.getCurrentWindow()
  
  // 2 にするとマウス中央ボタンでメニュー表示
  const triggerButton = 3

  let clickPosition = null

  const contextMenu = new Menu()

  const inspectElement = new MenuItem({
    label: '要素の検証',
    click () {
      webContents.inspectElement(...clickPosition)
    }
  })

  contextMenu.append(inspectElement)

  const onclick = ({ x, y, which }) => {
    if (which === triggerButton) {
      event.preventDefault()
      clickPosition = [x, y]
      contextMenu.popup(webContents)
    }
  }

  window.addEventListener('auxclick', onclick)
```
webpackを使っている場合は以下のif文で囲み、プロダクションビルドで除外することをおすすめします。

```javascript
if (process.env.NODE_ENV !== 'production') {
...
}
```
https://electronjs.org/docs/api/web-contents#contentsinspectelementx-y

##参考
https://electronjs.org/docs/api/web-contents
https://stackoverflow.com/questions/32636750
(C, C++)ソースコードのテンプレ生成スクリプトを書いた

# 経緯

せっかくの年末なので，
「AtCoderに挑戦してみるか〜」
「蟻本の問題解いてみるか〜」
などなど，何かアルゴリズムを書こうと思い立つのですが，CやC++は，ヘッダをいちいち書くのが面倒臭い，main関数を書くのが面倒くさい，-oオプション付けてコンパイルするのも面倒くさい，書き始めるまでただただ面倒くさい．
そこで，shell スクリプトでソースコードと Makefile のテンプレートを生成したい．

# やったこと

作りたいファイル名を標準入力で読み込んで，ソースコードと Makefile をリダイレクトで生成するだけ．

## C

### スクリプト

```gencode.sh

#!bin/sh

echo 'enter file name'
read filename

mkdir $filename
cd $filename

#generate a C source code
cfile=$filename'.c'
echo '#include <stdio.h>\n' > $cfile
echo 'int main(void){\n\n\tputs("hello");\n\treturn 0;\n}' >> $cfile

#generate a Makefile
MAKE='Makefile'
echo 'PROGRAM = '$filename > $MAKE
echo 'OBJS = '$filename'.o\n' >> $MAKE
echo 'CC = gcc\nCFLAGS = -Wall -O2\nLFLAGS = \n' >> $MAKE
echo '.SUFFIXES: .c .o\n' >> $MAKE
echo '$(PROGRAM): $(OBJS)\n\t$(CC) -o $(PROGRAM) $^\n' >> $MAKE
echo '.c.o:\n\t$(CC) $(CFLAGS) $(LFLAGS) -c $<' >> $MAKE
echo '.PHONY: clean\nclean:\n\t$(RM) $(PROGRAM) $(OBJS)' >> $MAKE

```

### 使い方

```console
$sh gencode.sh
enter file name
test
```

### 出力

```test.c
#include <stdio.h>

int main(void){

	puts("hello");
	return 0;
}

```

```:Makefile
PROGRAM = test
OBJS = test.o

CC = gcc
CFLAGS = -Wall -O2
LFLAGS = 

.SUFFIXES: .c .o

$(PROGRAM): $(OBJS)
	$(CC) -o $(PROGRAM) $^

.c.o:
	$(CC) $(CFLAGS) $(LFLAGS) -c $<
.PHONY: clean
clean:
	$(RM) $(PROGRAM) $(OBJS)

```

## C++（クラスファイルを生成）
### スクリプト
```genclass.sh
#!bin/sh

echo 'enter file name'
read filename

mkdir $filename
cd $filename

#generate a C++ source code
cppfile=$filename'.cpp'
echo '#include <stdio.h>\n' > $cppfile
echo 'class '$filename'\n{\nprivate:\n\npublic:' >> $cppfile
echo '\tvoid sayhello();\n};\n' >> $cppfile
echo 'void '$filename'::sayhello()\n{' >> $cppfile
echo '\tputs("hello");\n}' >> $cppfile
echo 'int main(void){\n\n\t'$filename' obj;\n\n\tobj.sayhello();\n\treturn 0;\n}' >> $cppfile

#generaete a Makefile
MAKE='Makefile'
echo 'PROGRAM = '$filename > $MAKE
echo 'OBJS = '$filename'.o\n' >> $MAKE
echo 'CC = g++\nCFLAGS = -Wall -O2\nLFLAGS = \n' >> $MAKE
echo '.SUFFIXES: .cpp .o\n' >> $MAKE
echo '$(PROGRAM): $(OBJS)\n\t$(CC) -o $(PROGRAM) $^\n' >> $MAKE
echo '.cpp.o:\n\t$(CC) $(CFLAGS) $(LFLAGS) -c $<' >> $MAKE
echo '.PHONY: clean\nclean:\n\t$(RM) $(PROGRAM) $(OBJS)' >> $MAKE

```
### 使い方

Cと同じ

### 出力

```test.cpp
#include <stdio.h>

class test
{
private:

public:
	void sayhello();
};

void test::sayhello()
{
	puts("hello");
}
int main(void){

	test obj;

	obj.sayhello();
	return 0;
}
```

```:Makefile
PROGRAM = test
OBJS = test.o

CC = g++
CFLAGS = -Wall -O2
LFLAGS = 

.SUFFIXES: .cpp .o

$(PROGRAM): $(OBJS)
	$(CC) -o $(PROGRAM) $^

.cpp.o:
	$(CC) $(CFLAGS) $(LFLAGS) -c $<
.PHONY: clean
clean:
	$(RM) $(PROGRAM) $(OBJS)
```

# 参考

[Makefile の書き方](http://www.ie.u-ryukyu.ac.jp/~e085739/c.makefile.tuts.html) wtopia 様
【R】Hardy-Weinberg平衡（ピアソンのχ二乗検定）

#はじめに
仕事で統計遺伝学が必要になりそうなので、[実践でわかる!Rによる統計遺伝学](https://www.amazon.co.jp/%E5%AE%9F%E8%B7%B5%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8B-R%E3%81%AB%E3%82%88%E3%82%8B%E7%B5%B1%E8%A8%88%E9%81%BA%E4%BC%9D%E5%AD%A6-%E3%82%A2%E3%83%B3%E3%83%89%E3%83%AC%E3%82%A2%E3%83%BBS-%E3%83%95%E3%82%A9%E3%83%AB%E3%82%AF%E3%82%B9/dp/4621300059)を始めた。

備忘録的に記していく。

#使用するデータ
使用するデータは本で指定されたURLから。

**FAMussデータ**
http://pub.maruzen.co.jp/book_magazine/support/r_toukeiidengaku/FMS_data.txt

#必要なパッケージ
**genetics**パッケージをインストールしておく。

```R
install.packages("genetics")
```
そして読み込む。

```R
library(genetics)
```

#データの読み込み
FAMuSSデータを読み込む。
**read.delim()**関数は、データ区切りがタブの場合。

参考
[ファイルからデータを読み込むとき](http://cse.naro.affrc.go.jp/takezawa/r-tips/r/40.html)


```R
fms <- read.delim("http://pub.maruzen.co.jp/book_magazine/support/r_toukeiidengaku/FMS_data.txt",fileEncoding="cp932")
```

**attach()**関数を使うことで、データフレーム名を使わず変数名だけを用いて変数を指定する。

```R
attach(fms)
```

#ピアソンのχ二乗検定を用いたHardy-Weinberg平衡の検定
**genetics**パッケージの**HWE.chisq()**関数を使って求める。

**FAMussデータ**の**akt1_t10726c_t12868c**SNPについて、ピアソンのχ二乗検定を用いてHardy-Weinberg平衡の検定を行う。

```R
Akt1SNP <- genotype(akt1_t10726c_t12868c, sep = "")
HWE.chisq(Akt1SNP)
```

実行結果。

```R
> Akt1SNP <- genotype(akt1_t10726c_t12868c, sep = "")
> HWE.chisq(Akt1SNP)

	Pearson's Chi-squared test with simulated p-value (based on 10000 replicates)

data:  tab
X-squared = 26.539, df = NA, p-value = 9.999e-05
```

Hardy-Weinberg平衡に関する検定結果が統計的に有意なら、そのSNPはHardy-Weinberg不平衡となる。

#最終的なスクリプト

```R
#Rをきれいにする
rm(list = ls())

#データの読み込み
fms <- read.delim("http://pub.maruzen.co.jp/book_magazine/support/r_toukeiidengaku/FMS_data.txt",fileEncoding="cp932")

#ライブラリの読み込み
library(genetics)

#attach()関数でデータフレームを指定
attach(fms)

#ピアソンのχ二乗検定を用いたHardy-Weinberg平衡の検定
Akt1SNP <- genotype(akt1_t10726c_t12868c, sep = "")
HWE.chisq(Akt1SNP)
```
VS CodeでSSH先のDockerを開発環境に使う

# 前置き
`VS Code`に`Remote Development`が追加されしばらくが経ちました。
開発環境を`Docker`に載せることで、別の端末やメンバー間で環境が手軽に統一できるのでメリットが大きいのですが、いくつか問題があるせいか利用してるところをあまり見たことがありません。

ホストOSに`MacOS`を使っていると`Docker`のファイルシステムの読み書きが遅くて、私は`JavaScript`の開発を行うことが多いのですが`npm`周りのインストールやビルドがホストOS上で実行するのと比べ物にならないぐらい遅くなります。

これは`Linux`上の`Docker`がホストOSのカーネルを共有してるのに対し、`MacOS`の場合はホストOSの上に軽量な`Docker`の実行環境を載せて動かしているせいで、`Docker`のコンテナ側でファイル変更する度にホストOSに通知される2重管理になってるせいのようです。
`MacOS`の場合の対応は`docker-sync`を入れたり、`cached`オプションを設定したり、いくつかあるのですが試してみた限りだとどれも多少早くはなるのですがあまり改善されないなって印象でした。

## 今回の対応
根本的な解決はホストOSに`Linux`を用意するしかなさそうなので別マシンで用意しました。
私の場合はちょうど昔使っていた`Mac mini`があったので`Arch Linux`を入れて`Docker`用マシンにしました。
クラウド上に用意すればいつでも使える便利な環境が用意できると思います。
(そこまでするのは大掛かり過ぎるし、この記事に需要があるかは不明です)

#### Dockerサーバ(Arch)の準備
`SSH`接続できる`Linux`端末を用意して`Docker`の`Server API`を設定します。

```bash
vim /etc/systemd/system/docker-tcp.socket
```

```:docker-tcp.socket
[Unit]
Description=Docker Socket for the API

[Socket]
ListenStream=2375
BindIPv6Only=both
Service=docker.service

[Install]
WantedBy=sockets.target
```

```bash
systemctl enable docker-tcp.socket
systemctl stop docker
systemctl start docker-tcp.socket
systemctl start docker
```

#### Dockerクライアント(MacOS)の準備

`Docker`の`CLI`をインストールします。
`MacOS`上で動作する`Docker`環境は要らないので`Docker for Mac`は入れずに`Homebrew`からCLIだけをインストールします。`Docker for Mac`が入ってる場合はそのままでも問題ないです。

```bash
brew install docker
```

環境変数に`Docker`サーバの接続先を指定します。
任意のIPと上記の`docker-tcp.socket`で設定したポートを指定します。

```zsh:.zshrc
export DOCKER_HOST=tcp://192.168.2.2:2375
```

`VS Code`の設定ファイル`setting.json`に`Docker`サーバのSSH情報を設定します。

```:setting.json
"docker.host": "ssh://username@192.168.2.2"
```

## あとがき
これで`VS Code`の`Remote Development`に`Docker`サーバー上のコンテナが表示されて接続できるようになりました。
結果的に`Docker`を動かす端末が別になったのですが環境を意識せず`VS Code`と`Docker CLI`をインストールするだけで環境が整うようになったのでアリなのかなと思います。


## 参考
https://knowledge.sakura.ad.jp/2401/
https://code.visualstudio.com/docs/remote/containers-advanced
UnityWebGLでスマホか否かを判別する

# はじめに

UnityのWebGLにおいてアクセスしている端末がスマホかどうか知りたい。~~そんなことするの自分だけかもしれないが。~~
そんなとき`Application.platform`やプラットフォーム依存コンパイルでは使っている端末がパソコンなのかスマホなのかが取得できないのでブラウザースクリプトとの相互作用を利用して取得する。

#環境

* Unity 2019.2.17f1

#UnityとJavaScriptで互いに関数/メソッドを呼ぶ
UnityWebGLではUnityのC#からJavaScriptを呼び出したりその逆が可能。 
[WebGL: ブラウザースクリプトとの相互作用 - Unity マニュアル](https://docs.unity3d.com/ja/2019.2/Manual/webgl-interactingwithbrowserscripting.html)
詳しくは公式マニュアルを参照。

そこでこの記事ではC#からJavaScriptにユーザーエージェントを取得させ、それを元にUnityのメソッドを呼ぶことでスマホであるかをUnityに知らせる。

#実際のコード

ファイル名や関数名などは各々のプロジェクトに合わせた形に書き換える。

`Assets/Plugins`以下に拡張子がjslibのファイルを作る。

```CheckPlatform.jslib
mergeInto(LibraryManager.library, {
    CheckPlatform: function () { 
        //ユーザーエージェントを取得して全て小文字に変換する
        var ua = window.navigator.userAgent.toLowerCase(); 
        //ユーザーエージェント文字列にandroidかiosが含まれているか
        if(ua.indexOf("android") !== -1 || ua.indexOf("ios") !== -1){
            //今開いているシーンにあるGameManagerというオブジェクトにアタッチされているスクリプトのsetSmartPhoneModeというメソッドを呼ぶ
            unityInstance.SendMessage('GameManager', 'setSmartPhoneMode')
        }
    },
});
```

```GameManager.cs
    //スマホかどうかを保存しておく
    public static bool IsSmartPhone { get; private set; } = false;

    //JavaScriptから呼び出すメソッド
    public void setSmartPhoneMode()
    {
        IsSmartPhone = true;
    }
```

そして、以下のようにすることでJavaScriptを呼びC#にスマホであることを知らせることができる。

```cs
    [DllImport("__Internal")]
    private static extern void CheckPlatform();

    //Startではなくてもいい
    void Start()
    {
//こうしておかないとUnityEditorでCheckPlatformを呼ぼうとしてエラーになる
#if (UNITY_WEBGL && !UNITY_EDITOR)
        CheckPlatform();
#endif
    }
```

#最後に
今回の記事では端末がAndroidかiOSであるとしか判別していないが、ユーザーエージェント文字列をそのままUnityに送るなどすればブラウザやOSの種類も取得できる

#参考リンク
[WebGL: ブラウザースクリプトとの相互作用 - Unity マニュアル](https://docs.unity3d.com/ja/2019.2/Manual/webgl-interactingwithbrowserscripting.html)
[JavaScriptでブラウザとOSを判定する2つの方法 - Qiita](https://qiita.com/TD12734/items/671064e8fce75faea98d)
【備忘録】プロセッサユニット

#はじめに#
ここら辺知らないとなんかアレかなっと思ったのでまとめます。

#CPU#
おなじみ**中央処理装置(Central Processing Unit)**です。
コンピュータの頭ですね。アプリ動かしたり、入力に対して何かしたり、ラジバンダリともうこの子がいなかったら何もできないってかんじですね。

#GPU#
最近耳にしたりしなかったりでCPUよりはなじみない**Graphics Processing Unit**です。
画像処理に特化したプロセッサです。大規模な並列演算処理だけを担当する画像職人です。
CPUにくらべて単純な作業をめっちゃ速く処理するってところですね。
この子がいなかったら最近のゲームはできませんね。

#GPGPU#
ぜんぜんおなじみじゃない**General-Purpose computing on GPU**です。
GPUの特徴である並列演算処理速めってのを画像処理以外にも使いたいってので生まれたらしいですね。最近はやりの深層学習とかはこの子がいないとなかなか厳しいですね。
>http://e-words.jp/w/GPGPU.html

#CPUメーカーといえば#
**Intel**と**AMD**が有名ですね。
有名とか言っちゃいましたけど、実際PC自作とかしたことないんでIntel以外知らなかったんですけどね。世の中に出回ってるのほぼIntelハイッテルんですもん。


#GPUメーカーといえば#
**NVIDIA(エヌディビア)**と**AMD**が有名ですね。
いっちょ前に有名とか言いましたけど、正直さっきNVDIAの読み方知ったくらいには無知でしたね。気を抜いたらナブディアとか言っちゃうかもしれません。~~いやでもよく考えたらエヌディビアじゃなくてエンビィディアの方があってない？~~

ちなみに、
NVIDIAといえば**GeForceシリーズ**
AMDといえば**Radeonシリーズ**
らしいです。これもさっき知りました。


>http://e-words.jp/w/NVIDIA.html
>https://tech-camp.in/note/technology/43109/

#内蔵GPUとグラフィックボード#
GPUがどこにあるのかって違いですね。後も性能も違うとか。

内蔵GPU →　CPUに内蔵されている
グラボ  →  専用のボードにある

グラボの方が強いけど幅取るし小型化には向いてないよってところでしょうか。

>https://pcfreebook.com/article/built-in-gpu-spec-about.html
>https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%B3%E3%83%9C%E3%83%BC%E3%83%89%E3%82%B0%E3%83%A9%E3%83%95%E3%82%A3%E3%83%83%E3%82%AF
>https://ja.wikipedia.org/wiki/%E3%83%93%E3%83%87%E3%82%AA%E3%82%AB%E3%83%BC%E3%83%89


#SoC#
これはなんか聞き覚えあるかなってくらいの感じでした、**System on Chip**です。
ソックとかエスオーシーとか言うらしいです。
CPUとかGPUとか必要なシステムを全部1つのチップにまとめたよってやつですね。
どおりでスマホで高画質なゲームができるわけだなるほどなって感じでスマホにも入ってるらしいですよ。

>https://www.ssaits.jp/blog/system/system-on-a-chip.html
>https://k-tai.watch.impress.co.jp/docs/column/keyword/698801.html
>http://e-words.jp/w/SoC.html




#よくみるマイクロプロセッサ#
普段見にすると思われるやつをメモ程度にまとめます。

##Intel Core X シリーズ##
たぶんこれが一番目にするんじゃないかってやつですね。
PentiumとかCeleronとかはあんまり見かけない気がするんで今回は割愛します。
まぁ家で眠っていたPCはCeleronだったんで見かけないわけではないかなって感じですけどね。

###最新の世代###
第10世代(令和元年現在)

###コアとスレッドの数###

|Core X|コア数|スレッド数|
|:--:|:--:|:--:|
|Core i3|2|4|
|Core i5|4|4|
|Core i7|4|8|
|Core i9|10・12・14・16・18|20・24・28・32・39|

##Apple Aシリーズ##
iPhoneとかiPadにのってるSoCです。
もうCPUとかGPUとかがえらいこっちゃって感じです。
Appleが自前でつくってるんやって、すごいね。


#上に乗ってない参考#
https://www.tel.co.jp/museum/exhibition/principle/microprocessor.html
JavaScript / Setオブジェクトで文字列を１文字単位でまとめて格納する

JavaScriptのSetオブジェクトに、文字を1文字ずつ簡単に格納する方法について書いておきます。
後者の書き方で記載すれば、１文字ずつカンマで区切る必要がなくなります。

#### 1. 標準的な書き方

```sample.js
const kans = new Set(['〇', '一', '二', '三', '四', '五', '六', '七', '八', '九']);

console.log(kans.has('一'));
// 表示結果 true

console.log(kans.has('四'));
// 表示結果 true

console.log(kans.has('百'));
// 表示結果 false
```

#### 2. 簡単な書き方

```sample.js
const kans2 = new Set('〇一二三四五六七八九');

console.log(kans2.has('一'));
// 表示結果 true

console.log(kans2.has('二三'));
// 表示結果 false

console.log(kans2.has('十'));
// 表示結果 false
```

pythonでできる方法なので、試してみたら上手くいきました。
記事が見当たらなかったので（探せばあると思いますが）、備忘として残しておきます。

●参考とした記事
[MDN Web Docs - Set](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set)
自前のシーンで Oculus Quest でハンドトラッキングする方法

自前のシーンで Oculus Quest でハンドトラッキングする方法です。とても簡単。

こんな感じで動かせます。
![tracking.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/7275d547-0a96-8031-9eb2-1e0848774383.gif)

# 前提
Unity 2019.3.0f3
Oculus Integration 12.0

# 手順
1. シーンを作成する

2. MainCamera を削除する
<img width="298" alt="スクリーンショット 2019-12-30 21.51.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/046654de-14bc-8d3d-254b-433c6357d928.png">

3. OVRCameraRig をシーンに追加する
<img width="364" alt="スクリーンショット 2019-12-30 21.52.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/333e2a15-0e90-ae0b-fce2-0965ae2ff903.png">

4. OVRCameraRig の OVRManager の HandTrackingSupport の設定を Controllers and Hands(HandsOnlyでも可)に変更する
<img width="378" alt="スクリーンショット 2019-12-30 22.03.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/fe437028-2672-0150-25b8-62049e124b1e.png">

5. OVRCameraRig の LeftHandAnchor/RightHandAnchor に OVRHandPrefab を追加する
<img width="625" alt="スクリーンショット 2019-12-30 21.53.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/c1943004-811c-87bc-652c-1a7919303e04.png">

6. 右手側がの設定が左になっているので、OVR Hand、OVRSkelton、OVRMesh をそれぞれ Hand Right に設定する
<img width="380" alt="スクリーンショット 2019-12-30 21.54.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/77c6b845-1fb3-dcbe-f9c8-7ba7beba0a24.png">

# 注意
* Oculus Link 経由での Editor 実行では手は出ません
    * adb コマンド経由でインストールしてください
* Oculus Quest で手を使う設定にしていないと手は出ません
* アプリを終わりたいときは、最初の動画の最後みたいに、OKのようなポーズを作り、自分の顔に向けたまま2秒ほど停止しさせます
document.designMode の値、 on と off を切り替えるブックマークレット

ドキュメントを編集可能にするかどうかを切り替えるブックマークレット。

## ブックマークレット

```js
javascript:(function(){document.designMode = document.designMode === 'on' ? 'off' : 'on';})();
```

三項演算子を使って、`document.designMode`の値が`on`の場合は`off`に、`off`の場合は`on`に変更している。

## document.designMode プロパティ

`document.designMode`プロパティは、ドキュメント全体を編集可能にするかどうかを制御する。
`on`で編集可能にする。
ソフトウェアテストにおけるテストプロセスについて

#はじめに
この記事では、ソフトウェアのテストプロセスについて説明していきます。

なお、内容についてはJSTQB(ISTQB)シラバス2018 に準じています。


# テストプロセス
テストプロセスについてですが、ISTQBおよびJSTQBでは
**「テストの準備段階から終了段階までの一連の作業」**
とされています。テストは開発全体を通して行われるものであり、プロセスを定義しておくことは最も重要なテストの活動の１つです。
本記事では以下の３つの観点からテストプロセスについて説明します。
・テストの活動とタスク
・テスト作業成果物
・作業成果物とのトレーサビリティ

## テストの活動とタスク
テストの具体的な活動とタスクについてです。
テストは主に下記の7つの活動およびタスクから成り立ちます。

1. 計画 
テストの目的をテストレベルごとに明らかにし全体の計画を立てます。

2. モニタリングとコントロール
テストのアクティビティやタスク状況を把握し、テストの一連のプロセスをコントロールします。


3. 分析　　
テストを行うための情報を（機能用件や非機能用件、構成構造、設計情報）を収集し、現テストレベルおよびテスト対象に応じて必要な情報を取捨選択、再収集、新規作成することでどのようなテストをどのように行うことができるか判断する。

4. 設計
分析によって明らかにしたテスト条件を満足するためにより高位に具体的なテスト内容を考える。
テスト分析は「何をテスト」するかを決定し、設計で「それをどうテストするか」を決定する。
5. 実装
設計で作成された物をより詳細にテストに使えるようにまとめます。主に環境や手順、確認項目、テスト担当者のスキルなどをまとめます。
6. 実行
テスト実行者が作成されたテストケースをもとにテストを行います。
7. 完了
テストにおける 全体的な活動から得られた成果物(テスト実行レポート、欠陥レポート、プロジェクトにおける該当テストの情報)をまとめる。その上でテストの目的を達成しているか分析します。

これらの活動及びタスクはシーケンシャルに行うこともあれば、同時に進行することもあります。
各開発モデルに応じて省略されたりします。

##テスト作業成果物
上述したテストの活動とタスクでは全ての工程で**作業成果物**を残します。
具体的な内容は組織や工程によって異なりますが、テストの手順や結果、状況これらを残しておくことで
後に、網羅性の分析、テストの良し悪しの分析、バグの偏在箇所の分析等様々な場面で有用になります。

##作業成果物とのトレーサビリティ
最後にトレーサビリティについてですが、作業成果物と実際のテストにおける様々な情報の間には相互にトレーサビリティを確保しておかなければなりません。
これを怠ると、開発全体を通して一貫性と整合性を保つことは難しく、どの機能がどのテストで担保されるかなど情報が錯綜する可能性もあります。
品質の担保やステークホルダーへの情報提供などテストにおけるあらゆる情報は、参照しやすいようにしておく必要があります。

#まとめ
今回は、テストのプロセスについてざっくり書きました。
ざっくりすぎるので、今後追記していこうと思います。
【備忘録】初心者がNode.js使って指定時間毎にツイートを取得してみた。

# 「指定時間毎にツイートを取得」の記事が意外となかった。
TwitterAPIの記事はいっぱいあるのだが、ツイートを取得する記事が意外と見当たらなかったので、備忘のために書き記す。（もう常識だったりするのだろうか。。。）

## 使ったモジュール
使ったモジュールは[`twitter(node-twitter)`](https://www.npmjs.com/package/twitter)
インストール方法などは検索すると日本語の記事が出てくるので割愛。

## 目的を達成するために何をすればいいのか。
`twitter(node-twitter)`の[サンプルコード](https://github.com/desmondmorris/node-twitter/tree/master/examples)には、`Tweet`、`Retweet`、`Search`、`Streams`等が出てきて、勉強不足な自分はどれを使えば良いか迷った。
自分が選んだのは、`Search`。

```javascript
client.get('search/tweets', {q: 'node.js'}, function(error, tweets, response) {
   console.log(tweets);
});
```

`{q: 'node.js'}`の部分に検索したいワードや時期を指定すると、`tweets`へJSON形式で格納される。

```javascript
client.get('search/tweets', {q: 'ホゲホゲ since:2019-12-30_20:00:00_JST until:2019-12-30_21:00:00_JST'}, function(error, tweets, response) {
   console.log(tweets);
});
```

これで2019年12月30日20時～21時まで`ホゲホゲ`とつぶやかれたツイートを取得してくる。ちなみに`_JST`は日本時間を表す。
もっと効率の良い取得方法があれば、教えてください。m(_ _)m

#出典
- [npm twitter](https://www.npmjs.com/package/twitter) https://www.npmjs.com/package/twitter
- [node-twitter](https://github.com/desmondmorris/node-twitter/tree/master/examples) https://github.com/desmondmorris/node-twitter/tree/master/examples
Python3でCSVコード変換プログラム

#Python3でCSVコード変換プログラム


[Python3でcsvから対応表を作る](https://qiita.com/code2545Light/items/97cdbaf29c83eb54aee1)
の続き


###考え

データ移行などの作業で
コード変換 新旧の対応表を作って順次置換
って作業あるかと思う。

その関数を作ってみた

###ソースコード
```csv_code_conv.py
#コード変換

import csv

#指定したCSV(2列限定)を順次読み込み。新旧対応表を作る
def getcsvconv(fname:str)->dict:
    with open(fname, encoding="shift_jis") as f:
        reader = csv.reader(f)
        conv_dic = {row[0]:row[1] for row in reader} #リスト内包表記 旧コードをkeyに、新コードをValue
        return conv_dic

#指定されたファイル(CSV)の指定位置のコードを変換する。
def code_conv(fname:str,rownum:int,converter:dict):
    #ファイル名生成
    outfname = fname.replace("exp","imp")
    with open(outfname, "w", newline="",encoding="UTF-8") as f:
        writer = csv.writer(f, delimiter=",", quotechar='"')
        with open(fname, encoding="UTF-8") as f:
            reader = csv.reader(f)
            for row in reader:
                #指定位置をコード変換
                convafterrow = row
                convafterrow[rownum] = converter[row[rownum]]
                writer.writerow(convafterrow)

#本体処理
#コード変換辞書の準備
conv_dic = getcsvconv("対応表.csv")

#変換対象の2次元リスト ファイル名,変換列位置(0スタート)
conv_pre_flist = [
    ["ほにゃらら.csv",2], #
    ["なんちゃら.csv",2],  # 3列目
    #["ごにょごにょ.csv",2], #変換対象外
]

for row in conv_pre_flist:
    code_conv(row[0],row[1],conv_dic)

```
HitogataモデルをVRChatへアップロード①

###Hitogataで作成したモデルをVRChatへアップロードします（参考：http://yananann.hatenadiary.jp/entry/2018/10/08/204438）

#準備（2019/12/30）
＊Hitogata_b2_21
公式：https://sites.google.com/site/vhitogata/
＊Blender v2.81.16
参考：https://blender-cg.net/download-install/
公式：https://www.blender.org/download/
＊Unity 2017
＊Steam
＊VRChat

#①Hitogataでモデルの作成

Hitogata_b2_21\Hitogata.exeを開く
ツール>キャラメイキング
キャラクターの作成ができる

ファイル>キャラクタ保存，キャラ構成ファイルを保存，モデルのエクスポート
出力は：「Hitogata_b2_21\Models\User」に保存される

#②Blenderでpmxファイルをfbxファイルに変換（参考：https://noshilog.com/blender-avatar-mmd-pmx-fbx）

###Cats Blender Pluginの導入
Cats Blender Plugin：https://github.com/michaeldegroot/cats-blender-plugin

###~~blender_mmd_toolsの導入~~（今はCats Blender Pluginwのみ導入で大丈夫らしい）
blender_mmd_tools：https://github.com/sugiany/blender_mmd_tools
blender_mmd_toolsフォルダ内の「mmd_tools」を
こちらのフォルダ内に追加
「Steam\steamapps\common\Blender\2.81\scripts\addons」

blender-2.81a-windows64\blender.exeを開く
Edit>Preferences>Add-ons>
mmd_toolsを検索し☑

###pmxファイルをインポート
File>Import>(.pmd.pmx)
ここからHitogataで作成したモデルを選択

Types：Me/Ar/Morのみ選択
Scale：0.08
こちらを変更したらインポート

インポートが完了したら
Misc>MMDShading>Shadelessをクリック
モデルに色が付きます

###モデルの最適化
テトラポッドのようなアイコンの3Dモデルデータを選択して
CATS>FixModelをクリック

###ポリゴン数の削減（https://noshilog.com/blender-avatar-polygon-decimate）
VRChatにはポリゴン数の制限があるので、2万以下にしていく

####パーツを解体
逆三角▽のアイコンのBodyを選択して
CATS>ModelOptions>Separateby:「Materials」をクリック

####ポリゴン数の削減
モデルを選択した状態で，ModifierPropertiesタブ（レンチのアイコン）を選択
AddModifier>Decimateをクリック
「Collapse」を選択した状態で、「Ration」を1.0より小さくし、「Apply」をクリック
表情などに影響するので服などのポリゴン数を減らすほうがいい

####パーツを結合
CATS>JoinMashes：「All」をクリック

###FBX形式でエクスポート
以下の3つを（Shiftを押しながら）選択し
＊Armature（オレンジ色の人型アイコン）
＊Armature（細い人型アイコン）
＊Body（逆三角形アイコン）
File>Export>(.fbx)

選択したオブジェクトにチェックをいれます。
カメラとランプのチェックを外します。
上部の[ジオメトリ][アーマチュア][アニメーション]のタブを開き
項目のチェックを全部外してエクスポートします。
Microsoft Learn 30日目

12月より、Advent Calendar を使って Microsoft Learn で学んでいく...と試みてなんとか完遂した([記事はこちら](https://qiita.com/advent-calendar/2019/d01tsumath_learn))。
しかし、スローペースだったのもあり25日間毎日受講しているとは言え、コースの半分しか終わってない。
そこで、「Azure の基礎」コースが終わるまで続けていこうと思う。毎日できるかは不明、でもがんばる。

と、いうことで。以下、受講記録のはじまりはじまり～。

12/30は
Azure におけるセキュリティ、責任、信頼
 - Azure 証明書の概要
を受講した。

# Azure におけるセキュリティ、責任、信頼
## Azure 証明書の概要
TLS では、データの暗号化と暗号化の解除に"証明書"が使用される。
ただし、証明書にはライフサイクルがあり、管理者はそれを管理する必要が出てくる。
Web サイトでよくあるセキュリティに関する問題は、期限切れの TLS 証明書によってセキュリティの脆弱性が発生することだ。

Azure で使用される証明書は [x.509 v3](https://www.atmarkit.co.jp/ait/articles/0401/01/news098.html) であり、信頼された証明機関によって署名することも、自己署名することもできる(自己署名証明書は、作成者自身が署名するため既定では信頼されない)。

### 証明書の種類
#### サービス証明書
クラウドサービスに接続されそれによってサービスとの間で、セキュリティで保護された通信が可能になる。
Azure portal またはクラシックデプロイモデルを使用して、サービス証明書を Azure にアップロードすることができる。
#### 管理証明書
クラシックデプロイモデルで認証を行うことができる。
これらの証明書を使用して、さまざまな Azure サービスの構成とデプロイを自動化できるが、クラウドサービスに関連付けられていない。

### 証明書での Azure Key Vault の使用
他のシークレットと同様に証明書も Azure Key Vault に格納できる。 
ただ、Key Vault では通常の証明書管理には備わっていない追加機能が提供されている。
・Key Vault で証明書を作成したり、既存の証明書をインポートしたりすることができる
・秘密キーマテリアルを操作することなく、証明書を安全に保存および管理することができる
・証明書のライフサイクルを管理するよう Key Vault に指示するポリシーを作成できる
・証明書の期限切れや更新のライフサイクルイベントを通知するための連絡先情報を指定できる
・選択した発行者(Key Vault パートナー X509 証明書プロバイダー/証明機関)で証明書を自動的に更新できる