OmniAICreator/Qiita-1.07M huggingface dataset:
Python - スクレイピングと自然言語処理(簡単に)

Python - スクレイピングと自然言語処理


###▼目的：
記事の類似度を記事内の単語から簡単に評価したい。


###▼ステップ
①urllibを使ってURLからHTMLを取得
②BeautifulSoupを使って、HTMLから記事を取得(スクレイピング)
③Mecabを使って、名詞を抽出(形態素解析)
④TF-IDFを使って、単語の出現頻度、単語の希少度を判定
⑤TF-IDFベクトルを使ってコサイン類似度を計算し、記事ごとの類似度を計算


#####▼準備

```python:python
import urllib.request
from time import sleep
from bs4 import BeautifulSoup
import MeCab
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
```


#####▼ステップ
①urllibを使ってURLからHTMLを取得
②BeautifulSoupを使って、HTMLから記事を取得(スクレイピング)

```python:python

def url2text(urls):
    article = []
    for url in urls:
        print(url+"のデータを取得しています")
        html = urllib.request.urlopen(url)
        soup = BeautifulSoup(html,"html.parser")
        soup_article = soup.find("div", class_="mw-parser-output")#Wikipediaの文書部分を抽出
        soup_article= soup_article.get_text()#タグの削除
        article.append(soup_article)
        sleep(3)  #マナーとして3秒間隔以上あける
    return article

```


③Mecabを使って、名詞を抽出(形態素解析)

```python:python
def mplg(article):
    word_list = ""
    m = MeCab.Tagger ()
    m_article = m.parse (article)
    for row in m_article.split("\n"):
        word =row.split("\t")[0]#タブ区切りになっている１つ目を取り出す。ここには形態素が格納されている
        if word == "EOS":
            break
        else:
            pos = row.split("\t")[1]#タブ区切りになっている2つ目を取り出す。ここには品詞が格納されている
            slice = pos[:2]
            if slice == "名詞":
                word_list = word_list +" "+ word
    return word_list

```


④TF-IDFを使って、単語の出現頻度、単語の希少度を判定

```python:python
def tfidf(word_list):
    docs = np.array(word_list)#Numpyの配列に変換する
    #単語を配列ベクトル化して、TF-IDFを計算する
    vecs = TfidfVectorizer(
                token_pattern=u'(?u)\\b\\w+\\b'#文字列長が 1 の単語を処理対象に含めることを意味します。
                ).fit_transform(docs)
    vecs = vecs.toarray()
    return vecs
```


⑤TF-IDFベクトルを使ってコサイン類似度を計算し、記事ごとの類似度を計算

```python:python
def cossim(v1,v2):
    return np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))
```

①~⑤の処理をまとめて計算する

```python
def main():
    article = url2text([
            "http://mensnote.boy.jp/document/html.html",
            "http://mensnote.boy.jp/document/python.html",
            "http://mensnote.boy.jp/document/R.html"
            ])
    word_list = []
    for article in article:
        word_list.append(mplg(article))
    vecs = tfidf(word_list)
    
    print("HTMLとPython")
    print(cossim(vecs[1],vecs[0]))
    print("RとPython")
    print(cossim(vecs[1],vecs[2]))
    print("RとHTML")
    print(cossim(vecs[0],vecs[2]))

main()
```

#####▼実行結果：
HTMLとPython
0.23880015353328762
RとPython
0.2699773736163584
RとHTML
0.1691580768168567



#####メモ：課題
・pythonの基本構文の部分
・URLを代入するのをなくしたい
・結果の出力をもっと見やすい形にしたい
・各工程の結果も出力したい
Xcode 他クラスのメソッドを使う その２ シングルトン

前回、AppDelegateを使った方法をあげましたらアドバイスを頂き、実際に、シングルトンを使ってやってみました。

備忘録を含めた意味でも再投稿。

前回の記事
https://qiita.com/gurensouen/items/0f11c80c10afbc36653a

開発環境
Xcode 9.0
Swift 4.0

Storyboardはこんな感じ
<img width="1368" alt="スクリーンショット 2018-05-04 22.25.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/246668/aa5d0888-5bef-d680-9f97-7758f8bdf6e2.png">

ボタンを押したら、「Label」と「View」が変わります。
ViewControllerには、「ViewController.swift」
nextViewControllerには、「nextViewController.swift」

コードは以下になります。

```ViewController.swift


    import UIKit
    
    class ViewController: UIViewController {
    
     @IBOutlet weak var buttonOut: UIButton!
    
     @IBOutlet weak var blackView: UIView! 
    
     let sin: Singl = Singl.sh
    
     override func viewDidLoad() {
        super.viewDidLoad()
        sin.viewCon = self
     }

     override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
     }

     @IBAction func butoon(_ sender: Any) {
        sin.moji = "文字渡します"
        sin.nextView?.mojichenge()
        blackView.backgroundColor = UIColor.black
     }
    
     func redView(){
        blackView.backgroundColor = UIColor.red
     }
    }
```

```nextViewController.swift

    import UIKit

    class nextViewController: UIViewController {

     @IBOutlet weak var label: UILabel!
    
     let sin: Singl = Singl.sh
    
    
     override func viewDidLoad() {
        super.viewDidLoad()
        sin.nextView = self
     }

     override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
     }
    
     func mojichenge(){
        label.text = sin.moji
     }
    
     @IBAction func button(_ sender: Any) {
        sin.viewCon?.redView()
        label.text = "色変えます"
     }
    }
```

```File.swift

    import Foundation

    class Singl {
     var moji:String?
     var viewCon:ViewController?
     var nextView:nextViewController?
     static let sh: Singl = Singl()
    }
```

今回はこんな感じで仕上げました。
誰かの参考になったら幸いです。

ご指摘、ご意見がありましたら、コメントいただけると嬉しいです。
M5stackで遊んでみる(音を鳴らしてみる)

# 音声の再生

何回か前の投稿で画像を表示することはできているので、
今回はそれに合わせて音を出して見ようと思います。

# 音声ファイルの準備

M5stackのフラッシュは具体的な容量はよくわからなかったんですが、
サイズがあまり大きくないらしく、音声ファイルもある程度サイズがあると溢れてしまいそうなので、
SDカードに保存しておきます。フォーマットとかは何も考えずに、買ってきた奴をそのままMacにブッ刺して
ルートのディレクトリに音声を放り込でおきます。

今回は `super-dry.wav` というファイルを保存しておきます。

# wavファイルを再生する関数を用意。

https://github.com/m5stack/M5Cloud/tree/master/examples/wav_player

↑ここにwavを再生する関数があったので丸パクリしてmain.pyに書き写します。

```python

from m5stack import lcd, buttonC, speaker
from machine import I2S
import os, wave

# スーパードライの画像表示
lcd.clear()
lcd.setCursor(0, 0)
lcd.setColor(lcd.WHITE)
# lcd.print("Hello world!")
lcd.image(0,0,'super-dry.jpg')

i2s = I2S(  mode = I2S.MODE_MASTER | I2S.MODE_TX | I2S.MODE_DAC_BUILT_IN,
            rate = 16000,
            bits = 16,
            channel_format = I2S.CHANNEL_ONLY_RIGHT,
            data_format = I2S.FORMAT_I2S_MSB)

# 音声の再生
def wav_player(fname):
    wav = wave.open(fname)
    i2s.set_dac_mode(I2S.DAC_RIGHT_EN)
    i2s.sample_rate(wav.getframerate())
    i2s.bits(wav.getsampwidth() * 8)
    i2s.nchannels(wav.getnchannels())
    i2s.volume(20)

    while True:
        data = wav.readframes(1024)
        if len(data) > 0:
            i2s.write(data)
            print('.', end='')
        else:
            wav.close()
            break
        if buttonC.isPressed():
            wav.close()
            break;

os.mountsd()

# Playing WAV audio file
wav_player('/sd/super-dry.wav')
i2s.volume(0)
i2s.stop()
lcd.setBrightness(0)
```

wav再生のコード自体はちょっとよく理解していませんが、
SDをマウントしてルートディレクトリに置いてあるwavを再生する関数を呼ぶだけなので、
全体としては簡単な作りにはなっています。

I2SというのはInter-IC SoundといってIC間でデジタル音声データをシリアル転送するための規格みたいです。
(出典: [Wikipedia](https://ja.wikipedia.org/wiki/Inter-IC_Sound)) 
勉強になりますね。さっぱり理解できてないですが。

再生中、再生後のボリュームがうるさかったので、
再生する際のボリュームと終わった後のボリュームを調整していたり、
終わった後のlcdの明るさを０にして真っ黒にしているのは再生後にボリュームを0にしているのに
何か音がなっているのを抑えようとして失敗した跡だったりするので、あんまり気にしなくても良いです。

# ファイルをアップロード

できたmain.pyをampyを使ってアップロードし、音声を入れて置いたSDカードをM5stackに刺して
電源ボタンを押して再起動すると、うまいこと再生されました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">無事に音が鳴った<br>次はボタンを押して何かさせたい <a href="https://t.co/1ME2OpVaPQ">pic.twitter.com/1ME2OpVaPQ</a></p>&mdash; 中鉢 洋介 (@cyubachi) <a href="https://twitter.com/cyubachi/status/992395305424318464?ref_src=twsrc%5Etfw">2018年5月4日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Androidエミュレータ(AVD)のCPU使用率を下げる

Androidのエミュレータ(AVD)を使用していたら、大したこともしていないのに
macbook proのCPU使用率が100を超えていたのが嫌だったのでその際のメモ

下記をエミュレータのconfigファイルに記載すると改善する

```
hw.audioInput=no
hw.audioOutput=no
```
Configファイルの場所は下記
Mac, Linux: ~/.android/avd/<AVD_Name>.avd/config.ini
Windows: C:\Users\<username>\.android\avd\<AVD_Name>.avd\config.ini
(Macは確認したが、Windows/Linuxは未確認)

## 参考資料

https://stackoverflow.com/questions/37063267/high-cpu-usage-with-android-emulator-qemu-system-i386-exe
サーバーの基本（４.RAIDについて）

サーバーやネットワークについて勉強したことをまとめます。

1.サーバーとは何か
2.サーバーの種類
3.パーミッションについて
4.RAIDについて
5.TCP/IPについて

長くなるので、投稿を分けます。
この記事では、4.RAIDについてを記載していきます。

##RAIDとは
RAIDとは、サーバー用のハードディスクに使われる技術です。
具体的には、ハードディスクを複数台用意し、1台が故障してもサーバーの技術を止めないように
する技術のことをいいます。
また、この技術により、容量や速度の向上ができるメリットもあります。
　　
※ハードディスクとは
　PCやサーバーの部品のひとつで、電源を切ってからも保持し続ける情報を記憶する装置。
 （メモリは電源を切ると情報が消える。）

サーバーは、複数の人が利用しています。
そのため、ハードディスクが故障してデータを紛失してしまったり、停電などでサーバーがダウンしたりすると多大な迷惑が掛かってしまいます。
そこで、データを消失せずにサーバーを継続稼働させるため、複数台のハードディスクを用意しておき、1台が故障しても問題ない状態にしておく技術を備えています。
このように、安全性のために機器を多重化しておくことを、「<strong>冗長化</strong>」といいます。

##RAIDの種類
<dl>
<dt>● RAID0 （ストライピング）</dt><br>
<dd>高速化と大容量化に特化したRAIDです。<br>
複数台のハードディスクをRAIDコントローラーで束ね、1台のハードディスクのように見せかけることで、データの読み書きを分散します（分散処理）。<br>
データを細切れにして、ハードディスクの台数分に分割して書き込むため、高速な処理が可能となります。<br>

このように、データを分散して複数台のハードディスクに書き込む操作を「<strong>ストライピング</strong>」といいます。<br><br>

また、複数のハードディスクを連結して１台のように扱うため、<br>
<strong>１台の容量ｘハードディスク台数＝合計容量</strong>

<br>として利用できるため、大容量化できます。<br><br>

デメリットは、複数台のハードディスクのうち、1台でも故障すると全てのデータが失われることです。<br>
（複数のハードディスクを連結しているため）
</dd><br>

<dt>● RAID1（ミラーリング）</dt><br>
<dd>安全第一のRAIDです。<br>
1台のハードディスクの複製を丸ごともう1台用意することで、1台が壊れてもデータが消失することはありませんが、人間が使用できるのは1台だけのため、容量も速度も変わりません。<br>

このように、データ対のディスクに複写する動作を「<strong>ミラーリング</strong>」といいます。</dd><br>


<dt>● RAID5（パリティ付きストライピング）</dt><br>
<dd>速度、大容量化向上＋最低限の保証対策をもったRAIDです。<br>
RAID0やRAID1は、最低2台のハードディスクで構成できますが、RAID5は最低<strong>3</strong>台のハードディスクが必要です。<br>
3台のうち、1台が故障してもデータは損失せず、2台めの故障でデータが全損します。<br><br>

ハードディスクが故障した場合に、故障したハードディスクのデータを修復するための「<strong>パリティ</strong>」というデータを分散処理の過程で生成します。<br>
ハードディスクの台数分分散処理するので、処理速度は高まりますが、パリティデータを書き込む分、RAID0より速度は低下します。<br><br>

RAID0と同様にハードディスクを連結し、1台のハードディスクとして扱うため容量は増えますが、パリティデータを書き込む分、RAID0よりは少なくなります。</dd><br>

<dt>● RAID6（ダブルパリティ）</dt><br>
<dd>RAID5の安全性が増したバージョンのRAIDです。<br>
RAID6は最低**4**台のハードディスクを必要とします。<br>
4台のうち、2台が故障してもデータは損失せず、3台めの故障でデータが全損します。<br><br>

安全性はRAID5よりも高いですが、RAID0と同様にハードディスクを連結し、1台のハードディスクとして扱うため容量は増えますが、安全対策用にディスクの容量を多く使うため、人間が使える容量はRAID5よりも少なくなります。</dd><br>

<dt>● RAID10（RAID01）</dt><br>
<dd>RAID1とRAID0を組み合わせたRAIDです。<br>
RAID10は最低4台のハードディスクを必要とします。<br>
そのうちの2台ずつを1つのペアにしてRAID1でミラーリングします。<br>
この2つのペアをRAID0でストライピングすることで、安全性と高速化を両立しています。<br><br>

各ペアの中で1台ずつ、計2台が故障してもデータは損失せず、1つのぺア内で2台が故障すると、<br>データが全損します。<br>
RAID6がどのディスクでも2台までの故障は耐えられるのに対し、RAID10は故障するディスクを選ぶため、安全性は少し劣ります。<br><br>

2つのペアが連結されて1つのハードディスクとして扱うため、容量は増加しますが、<br>
分散データをミラーリングするため、容量はRAID0の半分しか使用できません。<br>
安全性・容量はRAID6に劣りますが、復旧の際にはRAID5やRAID6よりもサーバーやハードディスクの<br>負担が少なくすみます。<br><br>

※RAID5、RAID6はパリティデータを利用しますが、RAID10は使用しません。<br>
  パリティデータを取り扱う際は、「パリティ計算」という作業を行って復旧データを書き戻すことになり、復旧時には、それがサーバーやハードディスクの負担となります。<br>
（故障したハードディスクを交換し、復旧させることを「<strong>リビルド</strong>」といいます。）<br><br>

ハードディスクの台数が増える分費用がかさむので、RAID6、RAID10はこの中では最も高額になります。
</dd><br>
</dl>

＜各RAIDの比較＞

|  | 大容量化 | 高速化 | 安全性 | 復旧の負荷の少なさ |費用|
|:-:|:-:|:-:|:-:|:-:|:-:|
|RAID0|◎|◎|×|〇|◎|
|RAID1|×|×|◎|〇|◎|
|RAID5|〇|〇|〇|△|〇|
|RAID6|△|△|◎|△|△|
|RAID10|△|◎|◎|◎|△|

※比較のために中間のものを△で表していますが、向上が見込めないわけではありません。
　価格は◎が安いものを表しています。

##参考資料
・「おうちで学べるサーバのきほん」著：木下肇　翔泳社出版　2017年
centOS7にrbenvとruby2.5.1いれたよ

ruby on rails使いたいから、[前回たてた仮想サーバー](https://qiita.com/nyanyamo/items/153bb8bc752359ee31cf)にruby導入。
バージョン切り替えの為にrbenvもね。

仮想サーバーにssh繋いだ状態からキロク

## 環境
OS：centOS7

## Git、rbenv、rubyの導入手順

#### 1.Gitのインストール
```cmd:コマンド
# インストール
$ sudo yum -y install git

# 入ったか確認
$ git --version
```

#### 2.rbenvインストール
```cmd:コマンド
# インストール
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv

# pathの設定
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

# 反映
$ source ~/.bash_profile

# 入ったか確認
$ rbenv -v
```

#### 3.ruby-buildのインストール
ruby-build = rbenvのプラグイン。
※ これ入れないと [rdenv install] がコマンド使えない

```cmd:コマンド
# インストール
$ git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ sudo ~/.rbenv/plugins/ruby-build/install.sh

# インストールできるrubyのバージョンの確認コマンド
$ rbenv install -l
```

#### 4.rubyのインストール
今回は最新の安定版2.5.1をいれたよ

```cmd:コマンド
# rubyインストールに必要なものを先にインストール
$ sudo yum install -y bzip2 gcc openssl-devel readline-devel zlib-devel

# ruby本体のインストール 
$ rbenv install 2.5.1

# 入ったか確認
$ ruby -v
```

#### 5.使用するrubyのバージョンを指定
rubyのバージョン切り替えの為にrbenvをいれてるので、
rbenvにどのバージョンを使うか指定する。

```cmd:コマンド
# rbenvで2.5.1を使うように設定
$ rbenv global 2.5.1

# 確認
$ ruby -v
```

で、おしまい
TinkerboardとWebCamで720p 30fpsでライブ配信をする

# ラズパイでできなくてtinkerboardでできること

ラズパイではUSBのWebcamからの映像入力だと性能がでませんでした。私はこれをメモリ帯域が足りないためと推測しています。tinkerboardではメモリが LPDDR3のデュアルチャネルになっているのでメモリ帯域が広くなっています。これによってWebCamからの映像入力が余裕をもってできるようになっています。

この記事ではtinkerboardとWebcamでYouTube Liveにライブ配信する例を示します。
WebcamにはLogitec のC270を使用しています。

# 準備

tinkerboadのハードウェアエンコーダはgstreamerから使用可能です。
gstreamerのインストール。

```
sudo apt install gstreamer1.0-*
```

YouTubeLiveのlive_dashboardのページで自分のアカウントのstream_keyを調べておきます。


# ライブ配信のスクリプト

普及価格のWebcamは最大で1280x720 30fps の映像が入力できます。このときの映像はmjpegで圧縮された状態で出てくるので、それをソフトウェアでデコードします。
H.264へのエンコードはハードウェアエンコーダを使用します。
音声はWebcam内蔵のマイクから入力して、ソフトウェアでAACにエンコードします。

`STREAM_KEY`のところは自分のstream_keyに修正してください。

```sh:livestream.sh

#!/bin/sh

RTMP_URL=rtmp://a.rtmp.youtube.com/live2
STREAM_KEY=your_stream_key

gst-launch-1.0 -v -e \
	flvmux streamable=true name=mux ! \
		rtmpsink sync=false location="$RTMP_URL/$STREAM_KEY" \
	v4l2src ! image/jpeg,width=1280,height=720,framerate=30/1 ! \
		jpegdec ! videoconvert! queue ! mpph264enc ! queue ! h264parse ! mux. \
	alsasrc device=plughw:1 ! audio/x-raw,width=16,depth=16,rate=48000,channels=1 ! \
		queue ! voaacenc bitrate=32000 ! queue ! mux. 
```

# CPUの負荷

H.264のエンコードはハードウェアで行っています。
CPUでやっているのはwebcamから取得したmjpegのデコードと音声のAACエンコードです。
ライブ配信中のhtopの画面は以下の通り。まだ余裕があります。

<img width="831" alt="スクリーンショット 2018-05-04 21.45.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/13271/d173a528-67cd-b608-cadf-fda67b8c2cd4.png">

mjpegのデコードもハードウェアでできるかもしれないのですが、まだ成功していません。
それができればさらにCPUの負荷が減ります。

CPU、メモリともにまだ余裕があるので、ライブ配信画面に何か重ね書きしたりエフェクトを入れたりすることもできそうです。

ラズパイだと専用カメラモジュールを使えば最大1080p 30fpsのライブ配信ができますが、この場合はカメラとH.264エンコーダを直結して使うことになるので、カメラから来た映像に何かソフトウェアで加工するということはできません。

今回はまだ試していませんが、tinkerboardでラズパイ用のカメラモジュールをつないで使用することもできるようです。これなら1080p 30fpsいけそうです。

# 参考

[Multimedia User Guide(Rockchip Linux)](https://blog.iotwrt.com/media/2017/05/04/VIDEO/)
[gstreamer-rockchip-extra](https://github.com/rockchip-linux/gstreamer-rockchip-extra)
[rockchip-linux](https://github.com/rockchip-linux)
[「Raspberry Pi Zeroと カメラモジュールで作るライブ配信実験機」の話をしました](https://qiita.com/tetsu_koba/items/a0f930efa33ac7d1aee2)
[ラズパイ3よりもパワフルなTinkerboardを試す](https://qiita.com/tetsu_koba/items/6af74b2a842f3549f77c)
Gradle 日本語訳

Gradle 関連の英文マニュアルをどこまで訳したか覚えておく為のインデックス。

* [Java Quickstart](https://qiita.com/JhonnyBravo/items/0a81e6a2ba73177c0d2e)
* [build.gradle](https://qiita.com/JhonnyBravo/items/8c470f21c8ff8770396e)
* [settings.gradle](https://qiita.com/JhonnyBravo/items/5aeefc6b68ff07748e4b)
* [gradle tasks](https://qiita.com/JhonnyBravo/items/4468ad29c908260f8612)
デザインが好き！　pixelドット絵でデザイン　Fantastic💘

　こどもの日スペシャル
　（親子でファミリーで楽しめる＊簡単ドット絵）

　春の連休は、みなさまいかがお過ごしでしょうか？　お子様とこどもの日に何をしましょう！　柏餅を食べたり、菖蒲湯に入ったり、こいのぼりを紙工作を作ったり。　そこで　遊んでみました。
　　
　東京タワーを描いてみる！
　　東京タワーを写真を撮り、
　　イメージを頭にいれて
東京タワーを描いてみる！
　今回IchigoJam のドット絵機能で　IchigoJamを使ってみました。
　＜簡単ドット絵デザイン＞（私の発案）　のお勧めは
＊　TOKYO TOWER を　遊びながら作れます。
もちろん、簡単でなく、ピクセルを埋めて、もっと細かくもできますが、それはアニメや写真をそのままに作るのが主流で時間がかかります。　
　そこで、今回考えたのが、簡単ドット絵デザインです！
　　　　　　　　
![IMG_4047 2.jpg](https://qiita-image-store.s3.amazonaws.com/0/248242/224613e5-4f5f-745d-d936-c26dc54530c8.jpeg)

　＜ドット絵は、点描 ＞
絵画などにおいて線ではなく点の集合や非常に短いタッチで表現する技法である。
点描画、点描法、点画、スティップリング（Stippling）という画像の表現方法・作成方法の形態です。表層的には通常の目視でピクセルが判別できる程度に解像度が低いビットマップ画像と捉えます。 実際には、限られたピクセル数の中で表現し、デザインがを作っていく手法の一つですね。　（PC Designで、始まりに習うことです。）
　
　遊ぼう！！　　
それを・子ども用に　簡単に　こういう風にもできるよ！と、
こちらを利用して見ました。
　![image.png](https://qiita-image-store.s3.amazonaws.com/0/248242/93813f79-656b-e808-9e42-6650fc7b4325.png)
　
　今回IchigoJam のドット絵機能を見て　これから始めたら良いと思ったのは、
点字へ　繋がると思ったからです！　ハンディのない社会へ
　で　IchigoJamのfukuno一日一創のドット絵機能を使いました。
　　https://fukuno.jig.jp/1887

パリのエッフェル塔と並ぶ　、赤色が輝くと　TOKYO TOWER 
夜の輝く時に東京タワーの写真も生で撮ってね。
![IMG_3623.jpg](https://qiita-image-store.s3.amazonaws.com/0/248242/696ffe78-3898-1213-cb1b-b11c30e1b6df.jpeg)

コーチするときの　＜追加＞大事なことは、
　創造力を楽しく、学びにつなげる好奇心を育てることです！
　そして、ブーや貶さない！　
　修正はしないでそのままをやらせてあげる。でもアドバイスは成果よりも、かけた時間や工夫の経過を大事に、どこを頑張ったかをみつけて褒めて育てる！　大人でも同じ。　
　　好奇心の王様より（笑）


![IMG_4295.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248242/7972ecc6-2271-cbb6-1878-724857615828.jpeg)
Ubuntu on Windows にRubyをインストール

BitcoinウォレットのサンプルソースがRubyで記述されていたために、実行環境を作ることを思い立ちました。同じ環境の事例があまりなかったので、細かいところも含めて最初から順番に説明します。

# Windows Subsystem for Linuxのインストール
使用しているOSは、Surface Pro (2017)のWindows10を最新にしたものです。
エディション　Windows 10 Pro
バージョン　　1709
OSビルド　　　16299.309


**Windowsの機能の有効化または無効化**

を起動して、

Windows Subsystem for Linux

にチェックを入れます。
OKを押すと再起動となります。

![2018-05-04 (2).png](https://qiita-image-store.s3.amazonaws.com/0/212141/12dd05f9-403b-d31a-5822-0582661626be.png)


# Ubuntuのインストール
Microsoft Store でUbuntuを検索します。見つけたら入手をクリックしてインストールします。

![2018-05-04 (1).png](https://qiita-image-store.s3.amazonaws.com/0/212141/3baf2098-152b-ec37-d1de-ecad531f8ab0.png)

# rbenv をインストール
gitはデフォルトでインストールされているので、rbenvをgitからインストールします。ネットを調べると、ユーザーのローカル環境にインストールしている例が多いようだったので、そうします。

```
~$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
```

~/.bashrc の最後に以下の2行を追加

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

# ruby-build をインストール

```
~$ mkdir -p .rbenv/plugins
~$ git clone https://github.com/rbenv/ruby-build.git .rbenv/plugins/ruby-build
```

# 環境整備
ここまでは、ローカル環境にファイルをコピーして、環境変数を変えるという作業だけだったが、インストール直後のUbuntuは少し実行環境を整備する必要がある。

```
~$ sudo apt update
~$ sudo apt install gcc
~$ sudo apt-get install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev
```

# Ruby のインストール
最新のRubyを入れます。

```
~$ rbenv install 2.5.1
~$ rbenv rehash
~$ rbenv local 2.5.1
```

# 環境の更新
インストールしても実行できなかったので、いろいろ試しましたが、おそらくこれが必要だろうと思い、やってみたらうまくいきました。

```
~$ source .bashrc
```
aws-cliでAWS CloudWatchにログを書き込む


ちょっとしたテストの際、コマンドラインでサラッとログが書きたい時があります。
そんなときは、aws put-log-events が使えます。

PHPで書きたいときは[こちら](https://qiita.com/zaburo/items/2841e6a28e913d410d17)を参照にしてください。

## 準備

### aws-cliのインストールとセットアップ

aws-cliを利用できるようにします。Macなら、

```bash
brew install awscli
```

でインストール可能なようです。便利。
インストールしたら、

```bash
aws configure
```

を実行し、Key, Secret, Region, formatを設定します。

>もちろん、CloudWatchに書き込み権限のあるユーザーである必要があります。

### ロググループとストリームを事前に作成しておく

put-log-eventsでは、指定したグループやストリームが存在しない場合に勝手に作成してくれることはないようなので、事前に作成しておきます。ここでは、

* グループ : test
* ストリーム : app1

を作成し、利用します。

### タイムスタンプを出力する

コマンドの引数として13桁のmillisecondのUnixTimestampを付与する必要がありますが、その出力はnodeで行うこととします。

```bash
node -e 'console.log(Date.now())'
1525438246400
```

>date +%s でも出力できますが、11桁なので。。。


## ログを書き込む

コマンドは1回目と2回目以降では、実行の際のオプションが少し異なります。

2回目以降の実行には、実行の戻り値として返される nextSequenceTokenを --sequence-token オプションで渡してやる必要があるようです。

### 1回目

下記を実行すると、nextSequenceTokenが返されます。

```bash
aws logs put-log-events --log-group-name "test" --log-stream-name "app1" --log-events timestamp=$(node -e 'console.log(Date.now())'),message='Hello1'

{
    "nextSequenceToken": "495802684308768944976731644967294124703722208857969xxxxx"
}
```

### 2回目以降

返されたToken情報を --sequence-token で指定して実行します。

```bash
aws logs put-log-events --log-group-name "test" --log-stream-name "app1" --log-events timestamp=$(node -e 'console.log(Date.now())'),message='Hello2' --sequence-token 495802684308768944976731644967294124703722208857969xxxxx
```

延々と繰り返します。。。

### nextSequenceTokenを忘れたら

ずっとTokenを追い続けるのはしんどいです。忘れた場合でも、グループを指定して、aws log describe-log-strems を実行すれば、uploadSequenceToken として次に添付すべきtoken値を返してくれるようです。

>なお、複数のストリームがある場合はストリーム毎に値が返るようです。

```bash
aws logs describe-log-streams --log-group-name "test"
```

```bash
    "logStreams": [
        {
            "logStreamName": "app1",
            "creationTime": 1525436712803,
            "firstEventTimestamp": 1525436741548,
            "lastEventTimestamp": 1525436767883,
            "lastIngestionTime": 1525436768309,
            "uploadSequenceToken": "495802684308768944976731645408177281858981340448628xxxxx",
            "arn": "arn:aws:logs:ap-northeast-1:051990479xxx:log-group:test:log-stream:app1",
            "storedBytes": 0
        },
```

とりあえずはこんな感じ。

## 参考

以下、参考にさせていただきました。ありがとうございます。

* https://qiita.com/toshihirock/items/7e4168b5ecea61955bc2
* https://dev.classmethod.jp/cloud/aws/put-cloudwatchlogs/
VS Code1.23の新機能 - Gitクローンコマンドの改善

# Visual Studio Code 1.23の新機能
## Gitクローンコマンドの改善

https://code.visualstudio.com/updates/v1_23#_git-clone-improvements
**Git: クローン**コマンドにいくつかの改善があった（っていうか、いつの間にかコマンド化されていたんだねー）。

### その１
クローンするリポジトリの保存先(親フォルダ)の指定方法が、いままでは手打ち(デフォルト値としてユーザーフォルダのパスは表示されている)だったが、システムのフォルダ選択ダイアログが表示されて選べるようになった。

### その２
前回のリリースで採用になった新しい通知ダイアログが使用されるようになった。

今まで
![gitclone.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/efed5a52-85d6-873d-c4a6-7c0b7c5c0946.gif)

今回
![gitclone_new.gif](https://qiita-image-store.s3.amazonaws.com/0/181011/bd1db35f-4d1a-cf85-69dd-1dee6ee7d36c.gif)

### その３
クローン後、今まではリポジトリフォルダを単独で開くことしか選択できなかったが、すでにフォルダを開いている場合はそこにフォルダを追加することもできるようになった。
Ubuntu18.04LTSでSlack日本語入力が出来ないときの対処方法

記念すべきQiita初投稿は自分用メモを．何かあればご指摘ください．
2020/07/09 追記 20.04LTSでも上手くいった例が確認されているようです。（コメント欄参照、報告ありがとうございます。）


#どうしたの
何も知らないUbuntu初心者がウキウキで16.04LTSから18.04LTSにアップデートしてSlack入れたら日本語入力受け付けてくれなくなった．つらい．

#環境
```shell

$ uname -a
Linux hostname 4.15.0-20-generic #21-Ubuntu SMP Tue Apr 24 06:16:15 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04 LTS"
```

#原因と対応
ソフトウェアセンターからSlackをインストールしたせいっぽい．ということで
0. ソフトウェアセンターからSlackをアンインストール (m4saka 様コメントありがとうございました．)
1. [公式サイト](https://slack.com/intl/ja-jp/downloads/linux)からdebファイルをダウンロードする
2. 端末を開く
3. debファイルをダウンロードしたディレクトリに移動して以下を実行

```shell

$ sudo dpkg -i slack-desktop-*.deb
```
これで何も言われなかったら以上です．日本語入力できるようになってるはず．

#依存関係が云々

私の場合はこんなんが出てきてて，インストールしたあとにトップバーにも警告マークが出てました．

```shell

$ sudo dpkg -i slack-desktop-3.1.1-amd64.deb 
以前に未選択のパッケージ slack-desktop を選択しています。
(データベースを読み込んでいます ... 現在 388168 個のファイルとディレクトリがインストールされています。)
slack-desktop-3.1.1-amd64.deb を展開する準備をしています ...
slack-desktop (3.1.1) を展開しています...
dpkg: 依存関係の問題により slack-desktop の設定ができません:
 slack-desktop は以下に依存 (depends) します: libcurl3 ...しかし:
  パッケージ libcurl3 はまだインストールされていません。

dpkg: パッケージ slack-desktop の処理中にエラーが発生しました (--install):
 依存関係の問題 - 設定を見送ります
bamfdaemon (0.5.3+18.04.20180207.2-0ubuntu1) のトリガを処理しています ...
Rebuilding /usr/share/applications/bamf-2.index...
mime-support (3.60ubuntu1) のトリガを処理しています ...
desktop-file-utils (0.23-1ubuntu3) のトリガを処理しています ...
gnome-menus (3.13.3-11ubuntu1) のトリガを処理しています ...
処理中にエラーが発生しました:
 slack-desktop
```
なんかエラーでててよくわかんない…となっていたのですが，[こちらの記事](http://mickey-happygolucky.hatenablog.com/entry/2017/08/05/062959)を参考にgdebiを入れてみました(aptみたいに依存関係を解決してくれるらしい…?)．つまり，一度slack-desktopを`apt --fix-broken install`などで削除し，以下を実行します．

```shell

$ sudo apt install gdebi

$ sudo gdebi slack-desktop-*.deb
```
「ソフトウェアパッケージをインストールしますか？」にyで進むといい感じにインストールされます．トップバーの警告マークも消えて安心．
macでfirebaseを利用できる環境構築からデプロイまでの備忘録

# ローカルでの環境を構築する
とりあえず動かすとこまでのメモ

## node.jsをインストールする

ターミナルを起動して以下のコマンドを実行

```
node -v
```

インストールされていない（バージョンが表示されない）場合は、[homebrew](https://brew.sh/index_ja.html)をインストールする。
インストール用のコマンドは公式サイトに乗っているので確認する。
2018/4/21時点では以下のコマンドを実行した。

```
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

nodebrewをインストールする。

```
brew install nodebrew
```

node.jsをインストールする

```
nodebrew install-binary latest
```

使用するバージョンを有効化する

```
nodebrew use latest
```

実行パスを通す

```
echo 'export PATH=$PATH:/Users/[ユーザー名]/.nodebrew/current/bin' >> ~/.bashrc
```
*[ユーザー名]の部分は書き換えが必要

ターミナルを再起動して、以下のコマンドを実行する。
実行パスの設定が読み込まれていないので、再起動して読み込ませる必要がある。

```
node -v
```

```
npm -v
```

両方ともバージョンが表示されればインストール完了。
もしバージョンが表示さればい場合は書き換えた実行パスが正しいか確認する。

## firebaseを利用できるようにする
[firebase](https://console.firebase.google.com/)から、新規プロジェクトを作成する。

ターミナルから以下のコマンドを実行する。

```
npm install -g firebase-tools
```

```
firebase login
```

googleにログインする
ログインできたら、ターミナルから以下のコマンドを実行する

```
firebase init
```

何を選択するか聞かれるので、とりあえず以下を選択
Hosting: Configure and deploy Firebase Hosting 

あとは適当に全部enter

以下のコマンドを実行

```
firebase serve
```

でローカルでページが開けるようになる。

## 公開する
デプロイするときは以下のコマンドを実行

```
firebase deploy
```

以下のコマンドで、ページを開く

```
firebase open hosting:site
```
ffmpegでサブタイトルのスタイルを指定する


```
ffmpeg -i a.mp4 -vf "drawtext='borderw=2:fontsize=32:fontfile=/System/Library/fonts/ヒラギノ角ゴシック W6.ttc:x=32:y=16:fontcolor=white:text=タイトル',subtitles=./captions.srt:force_style='Fontsize=32,PrimaryColour=&H00FF00&,OutlineColour=&HFFFFFF&,Outline=2,Bold=1'" b.mp4
```

スタイルの指定に関する参考資料
https://github.com/mitio/useful-ffmpeg-commands/blob/master/ass-specs.pdf
技術書典4にサークル参加してきた

4/22に開催された技術書典4に人工片吟でサークル参加してきました。
[技術書典](https://techbookfest.org/)

初めて、同人誌を出す中で色々と~~ぐだぐだだった~~学べたので記載しておく。
#参加動機
エンジニアとしてアウトプットを増やしたいなと考えたこと。また、同人誌をどのように作成するかを知りたかった。

#テーマ選定
同人誌を記載するに辺り、どのようなテーマで作成するかが悩んでいたが
サークルメンバーと話し合う中で伝えたいことや自分が自信を持ってか書けることが良いとの
話があった。
そのため、自分が主に専門している領域のセキュリティで
最近よく参加しているHardeningプロジェクトの話を書くことにしました。
https://wasforum.jp/hardening-project/

#同人誌作成
テーマが決まったら、同人誌を記載していく。
中綴じのコピー本を作成する関係上、ページ数に関しては４の倍数で作成すること、また、想定する読者を意識した上で記載を心がけた。

同人誌を印刷するに辺り、印刷サービスとして今回はキンコーズを利用した。
今回は、製本サービスは利用せず、自身でコピー本を印刷する以下の手順で行なった。
https://www.kinkos.co.jp/guide/recommend/feature/dojinshi-copybon.html
USBメモリから直接印刷できる便利なコピー機も設置している。
しかし、USBメモリのせいか直接印刷できなかったので、
一度コンビニで紙に印刷してからコピー本の印刷を行うという一手間かける形になった。
※おそらく、オンライン入稿することで解決する？と思われるため、次回以降は利用したい。

#書典当日
4/22当日秋葉原UDXに行き、サークルでの参加登録を行い、参加した。
参加スペースの場所の関係上、二つ椅子を並べることができず、一人立った状態でなったり
また、当日になってコインケースが用意できてなかったため、近くの量販店に買いに行ったり、お釣りの準備等を行うなど準備が大変だった。
実際に始まってみると想像以上に多くの人が手に取ってくれて、14時までに印刷した内の半分が売れた。
その後、値下げをするもなかなか売れずに疲労もピークに達したため、切り上げし、会場を後にした。

#振返
今回、初めて自分で同人誌を作成したが、やはり自分の作成したものがその場で売れるのは非常に達成感があり、休日に頑張ったかいがあったと感じた。
ただ。周りの参加者と比較してみると以下のような差異があり、自身の準備不足が浮き彫りとなり、売り残りが出てしまったと考える。

| 比較項目 　　　　| 他の参加者が作成 |自身が作成したもの|
|:-----------|------------|:------------|
| 見た目    | 製本しているため、綺麗<br>しっかりしているので一般的な技術書に似ている        | コピー本のため、見た目があまり良くない  |
| 宣伝     | 予めSNS（主にtwitter?)で宣伝<br>会場内でものぼり等で分かりやすく説明しているため手に取りやすい  | 特になかったため、そもそも何の本が売られているか分からず手に取りにくい     |
見た目は非常に大事だと感じており、せっかくの休日に参加したのであれば、良い書籍が欲しいと考えるのが当然のことである。そこで、見た目を綺麗にしてまず手に取ってもらうことや宣伝をすることの重要性は学べた。

また、友人のサークルに相乗りする形だったので本来いるべきジャンル（セキュリティ）にいなかった。参加者はサークルの一覧表から興味のあるジャンルを探すことから正しいジャンルづけをしないと認知がされない。ただ、中にはサークル内で複数のジャンルを出している所もありどのようにジャンルづけをしているかが気になった。

同人誌の内容に関しても様々な内容があることがわかった。
例えば、セキュリティでは、ハニーポットの構築、マルウェアの構築などサイバーセキュリティの実践本から有名なハッカードラマの解説、果てはセキュリティの歴史本など思いもよらない観点があったのが驚きであった。

また、IT系だけではなく、ハードや生物系の出版もあるなど多種多様なジャンルがあり非常に盛り上がっていたのが印象だった。
今回の技術書典は来場者も６０００人を超えるなど、技術書の需要が多くある中で今回の反省をバネにしてまた技術同人を出してみたい。
Windows10(WSL)で、2018年的Pythonプロジェクト（②入力環境の整備）

#はじめに
一身上の都合により、WSL版debianで、日本語を扱うpythonプロジェクトを立ち上げなければならない。

pythonの方は、pipenvを入れた方がいいよというアドバイスを受けてモダーンな感じにできそうなことが分かった（[前回](https://qiita.com/Nimimal/items/72c2e2a6a566d1f5d2a2)）。
WSL版debianは、windows10から見るとストアアプリ。英語キーボードで親指シフトを使っている私にとっては、日本語入力がハマりポイントになるかも。

...と思っていたけれど、結果としては、日本語の扱いは問題なくできるようになった。
普通にローマ字入力な人ももっと変わった入力方法な人にも同様にいけるはず。あとは、AWS周りなツールが動けば仕事になるかも。

# WSL版debian/ubuntuでspacemacsなコーディング＆日本語入力親指環境ができるまで。

①　外部リポジトリを使うために、add-apt-repositoryを使用可能とする。

```.sh
sudo apt install apt-file
sudo apt-file update
sudo apt upgrade
sudo apt-file update
sudo apt-get install software-properties-common
```
はじめに入れるapt-fileは、ビルド時に足りないライブラリを探したりすることに使える
http://linuxserver.jp/linux/debian/apt-file

次いで入れるsoftware-properties-commonでadd-apt-repositoryが使えるようになる。software-properties-commonの導入過程でpython3.5.xが導入されるが、pyenvは影響を受けない。

②　emacs2.5系をXなしで導入して、spcemacsも導入。

```.sh
sudo add-apt-repository ppa:kelleyk/emacs
sudo apt-get update
sudo apt-get install emacs25-nox
emacs --version
git clone https://github.com/syl20bnr/spacemacs ~/.emacs.d
emacs
```
emacsの初回起動時に、spacemacsが立ち上がってくれればオーケー。
spacemacsがなにかはぐぐってくださいませ。

③日本語環境を用意


```.sh
sudo apt-get install task-japanese
sudo dpkg-reconfigure locales
```

親指シフトその他、windowsストアアプリで苦しい日本語入力方法を取る人は
以下に習って、Cygwin用のmittyターミナルのWSL対応版WSLttyを導入しよう。
https://scratchpad.jp/debian-on-windows10-3/

問題なく動作する。ありがたや。

#付記
WSL版debianは、sshサーバーを立てれば、ssh経由でもアクセスデキルのだか、なぜだか日本語入力が通らなかった。当面はWSLttyでいこう。
Vue.jsでローカルのコンポーネントの中で別のコンポーネント(子コンポーネント)を使う

コンポーネントAの中でコンポーネントBを使いたい

```html
// コンポーネントA
<template>
    <component-b></component-b>
</template>
<script>
    // コンポーネントBをインポート
    import ComponentB from './ComponentB.vue';

    export default {
        // componentsでコンポーネントBを登録(ここで登録してないと、エラーになる)
        components: {
            'component-b': ComponentB
        },
    }
</script>
```

ちなみに、
こんな感じで定義してもコンポーネントBはコンポーネントAの中では認識されなかった。

```javascript
import Vue from 'vue'
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';

let App = new Vue({
    el: '#app',
    components: {
        ComponentA,
        ComponentB
    }
});
```
擬似変数$this

何となくPHPを使ってきて慣れ始めた頃、殆どPHPに触らない同期に「$thisって何？」と訊かれ上手く答えられなかった。

気になるのでちょっと調べてみた。

結論から言うと『$thisとはクラス定義内部でプログラムがアクセス可能なオブジェクト名（インスタンスメソッド）』の事。

以下に例を示す。

```
<?php

class MyClass
{
    // プロパティ（クラスのメンバ変数）の宣言
    public $public = 'Public ';
    protected $protected = 'Protected ';
    private $private = 'Private ';

    // メソッド（クラスのメンバ関数）の宣言
    function print()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
  }
}

$obj = new MyClass(); // new <クラス名>で、クラスの中身を使用できる状態にする
echo $obj->public;
$obj->print();
```

（出力結果）

```
Public Public Protected Private
```
上記の例では、クラス`MyClass`内においてオブジェクト`$public,$protected,$private`それぞれを`function print()`内部で呼び出すよう定義をしている。

この例では`$this`を使用しているが、これは後に記した`$obj = new MyClass();`　`echo $obj->public;`と同じことを、
`echo $this->public;`だけで行なっている。

メソッド内で前者の様に書いてもプロパティを呼び出す事はできるが、
擬似変数`$this`を使えばより簡潔に記述する事ができる。

P.S.ちなみに`echo $obj->public;`で`$public`は呼び出せるが、`$protected`と`$private`は呼び出せない。
クラスの中と外とでは『名前空間』が異なるからだ。

クラスの外から`private`や`protected`要素は呼び出せない。`function print()`内で定義して、そのファンクションそのものを後から呼び出せば上記出力例のように呼び出す事ができる。
Unity+VRTKでWindows MRを動かす

VRTK (Virtual Reality Toolkit)が，Windows MRに対応したためセットアップ方法をまとめておきます．

# 動作を確認した環境
- Windows 10 Home バージョン1709
- Unity 2017.3.1f1
- Visual Studio Community 2017 Version 15.6.2

# 必要なアセット
- [VRTK](https://github.com/thestonefox/VRTK "VRTK")
- [VRTK-Windows-MR-Extention](https://github.com/Innoactive/VRTK-Windows-MR-Extension "VRTK-Windows-MR-Extention")

2018/05/02現在，Windows MRに対応したバージョンのVRTKがAsset Storeで公開されていないため，
GitHubのリポジトリを`Clone or download`で直接ダウンロードする必要がある．

VRTK-Windows-MR-Extentionは，`README.md`の'How To Use'セクションにある'releases'リンクからUnityパッケージをダウンロードする．

# セットアップ方法
## 下準備
予め，Windows MRヘッドセットをPCで使えるようにセットアップしておく．
また，UnityとVisual Studioには，Universal Windows Platform (UWP)を開発するのに必要なパッケージをインストールしておく必要がある．

## プロジェクトの作成とアセットの導入
1. Unityで新規プロジェクトを作成．
2. 上記リンクから必要なファイルをダウンロードする．
3. VRTKリポジトリの`Assets`フォルダーの中身を，作成したプロジェクトの`Assets`フォルダーにコピーする．
4. Unityで，VRTK-Windows-MR-ExtentionのUnityパッケージをインポートする．

## プロジェクト設定
1. `Build Settings`を開き，`Universal Windows Platform`を選択して，`Switch Platform`でプラットフォームをUWPに変更する．
2. `Player Settings`を開き，`Other Settings`の`Scripting Backend`が`.NET`であることを確認する．
3. また，`XR Settings`で`Virtual Reality Supported`にチェックが入り，`Virtual Reality SDKs`に`Windows Mixed Reality`が入っていることを確認する．

## 動作確認
1. `VRTK/Examples/VRTK_SDKManager_Constructor.unity`シーンを開き，再生する．
2. ヘッドセットで映像が見えればここまでOK．
3. シーンに含まれる`[VRTK_SDKManager]`オブジェクトをコピーする．
4. 適当なシーンを作成してコピーしたオブジェクトをシーンに貼り付ける．
5. SDKを切り替える必要がなければ，シーン中の`[VRTK_SDKManager]/SDKSetupSwitcher`を無効にする．
6. シーンに適当にオブジェクトを配置し，再生して，ヘッドセットで映像が見えれば完成．

## その後
以降は，Oculus RiftやHTC Viveを用いたときと同様にVRTKを用いて開発できる．
VRTKを使うと，簡単に手を使ってものを掴んだり投げたり出来るので便利．具体的には，参考リンクを参照．

## 参考リンク
- https://github.com/thestonefox/VRTK
- https://github.com/Innoactive/VRTK-Windows-MR-Extension
- https://vrtoolkit.readme.io
- http://negi-lab.blog.jp/tag/VRTK解説まとめ
Mac のターミナルで Git のブランチ名を表示する手順


## 事前準備

```
$ git version
```

Git のバージョンを確認し、Apple git の場合は、homebrew の git にアップデートしておく。

```
$ brew install git
```
##  gitcomprication.bash を移動する

gitcomprication.bash を 指定のディレクトリに移動する。

```
$ mkdir -p /usr/local/git/contrib/completion/
$ cd usr/local/Cellar/git/{gitのversionの数字}/etc/bash_completion.d
$ mv git-completion.bash /usr/local/git/contrib/completion/
```
##  ~/.bashrc に設定する
```
# git settings
source /usr/local/git/contrib/completion/git-completion.bash
GIT_PS1_SHOWDIRTYSTATE=true
export PS1='\[\033[32m\]\u@\h\[\033[00m\]:\[\033[34m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]\$ '
```

##  ~/.bashrc を反映させる

```
$ source ~/.bashrc
```

#### ※-bash: __git_ps1: command not found エラーが出た場合

```
# git-completion.bash の前に追加で git-prompt.sh を読み込ませる
source /usr/local/etc/bash_completion.d/git-prompt.sh
source /usr/local/etc/bash_completion.d/git-completion.bash
```

この手順でGit のブランチ名が出るようになりました＼( ^０^ )／


## 参考
http://38ch.hateblo.jp/entry/2017/02/12/180145
https://sue445.hatenablog.com/entry/2012/08/30/005627
VirtualBoxでWin10のVMを使おうとして Fatal: INT18: Boot failure が出る場合

[Microsoft Edge Develope](https://developer.microsoft.com/en-us/microsoft-edge/)から落としたzipをMacで普通にダブルクリックで解凍した場合、表題のエラーが出ることがある。

```bash
 Fatal: INT18: Boot failure
```

<img width="832" alt="スクリーンショット 2018-05-04 19.49.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/50056/a622a48b-d151-7316-27d2-23337410a901.png">

# 対策
ターミナルからzipを解凍し、生成された `.ova` をクリックすればOK。

```bash
unzip MSEdge.Win10.VirtualBox.zip
```

# 利用
- デフォルトユーザのパスワードは: `Passw0rd!`

# 参考
- https://qiita.com/studio15/items/26bfb665aa024c5a5568
chainerの作法　その8

#概要
chainerの作法を調べて見た。
saveして、loadしてみた。

#サンプルコード
save_npzするやつ。


```
import chainer
import chainer.functions as F
import chainer.links as L
from chainer import training, datasets, iterators, Chain
from chainer.training import extensions

class MLP(Chain):
	def __init__(self, n_units, n_out):
		super(MLP, self).__init__()
		with self.init_scope():
			self.l1 = L.Linear(None, n_units)
			self.l2 = L.Linear(None, n_units)
			self.l3 = L.Linear(None, n_out)
	def __call__(self, x):
		h1 = F.relu(self.l1(x))
		h2 = F.relu(self.l2(h1))
		return self.l3(h2)

def main():
	train, test = datasets.get_mnist()
	train_iter = iterators.SerialIterator(train, 100)
	test_iter = iterators.SerialIterator(test, 100, repeat = False, shuffle = False)    
	model = L.Classifier(MLP(1000, 10))
	optimizer = chainer.optimizers.Adam()
	optimizer.setup(model)
	updater = training.updaters.StandardUpdater(train_iter, optimizer, device = -1)
	trainer = training.Trainer(updater, (5, 'epoch'), out = 'result')
	trainer.extend(extensions.Evaluator(test_iter, model, device = -1))
	trainer.extend(extensions.LogReport())
	trainer.extend(extensions.PrintReport(['epoch', 'main/loss', 'main/accuracy', 'elapsed_time']))
	trainer.run()
	chainer.serializers.save_npz('mnist3.model', model)


if __name__ == '__main__':
	main()



```

#サンプルコード
load_npzするやつ。


```
import chainer
import chainer.functions as F
import chainer.links as L
from chainer import training
from chainer.training import extensions

class MLP(chainer.Chain):
	def __init__(self, n_units, n_out):
		super(MLP, self).__init__()
		with self.init_scope():
			self.l1 = L.Linear(None, n_units)
			self.l2 = L.Linear(None, n_units)
			self.l3 = L.Linear(None, n_out)
	def __call__(self, x):
		h1 = F.relu(self.l1(x))
		h2 = F.relu(self.l2(h1))
		return self.l3(h2)

def main():
	model = L.Classifier(MLP(1000, 10))
	train, test = chainer.datasets.get_mnist()
	chainer.serializers.load_npz('mnist3.model', model)
	for i in range(10):
		x, t = test[i]
		print ('label:', t)
		x = x[None, ...]
		y = model.predictor(x)
		y = y.data
		print ('predicted_label:', y.argmax(axis = 1)[0])

if __name__ == '__main__':
	main()



```

以上。
Bashのベル音を無効にする

Windows 10 Home バージョン 1709

Bashでタイプしてると、やたらとピロリーンってなるのが鬱陶しいので無効化する方法を探しました。

解決策はこちらにありました。
https://linuxfan.info/bow-stop-beep

＄HOME/.inputrcに

```
set bell-style none

#↑を設定するとHome,Endキーが機能しなくなる場合がある。
#その場合、以下のキーバインド設定を追加する。
"\e[1~": beginning-of-line
"\e[4~": end-of-line


```
を追記するというもの。.inputrcがなければ作成してください。


ちなみにコマンドプロンプトでベル音を無効化する方法はこちらです。
https://errorfixer.co/disable-cmd-powershell-beep-sounds/

PowerShellを「管理者として実行」で開いて下記を実行します。

```
Set-Service beep -StartupType disabled
```

サービスを停止するってことですかね。ベル音すべてが鳴らなくなるのかな？
その辺は未確認です。

参照
https://wiki.archlinux.jp/index.php/Home_%E3%82%84_End_%E3%82%AD%E3%83%BC%E3%81%8C%E6%A9%9F%E8%83%BD%E3%81%97%E3%81%AA%E3%81%84
【Elm】特定のキーボードキーを押した時にイベントを発火させる

## Enterを押した時にイベントを発火(JavaScript)
例えばJavaScriptだと以下のように書ける。

```html
<textarea class="button"></textarea>
```
```javascript
let obj = document.querySelector('.button')
obj.addEventListener('keypress', onKeyPress)


function onKeyPress(e) {
  if ( e.keyCode === 13) {
    alert(e.keyCode)  
  }
  return
 }
```

## Enterを押した時にイベントを発火(Elm)
Elmの[Html.Events](http://package.elm-lang.org/packages/elm-lang/html/2.0.0/Html-Events)ではkeypressのようなイベントハンドラがない。

代わりにCustom DecodersであるKeyCodeを使うことで実現することが出来る。

```elm
-- Json Decodeをimport
import Json.Decode as Json


type Msg = Enter Int


update : Msg -> Model -> ( Model, Cmd Msg)
update msg model =
      case msg of
            Enter key ->
                 case key of
                     13 -> ...


view : Model -> Html Msg
view model =
    textarea [ onKeyPress Enter ] []


-- onKeyPressはInt（押されたキー）とMsg（Enter）を引数にとりMsg（Enter）を発行
onKeyPress : (Int -> Msg) -> Attribute Msg
onKeyPress tagger =
    Html.Events.on "keypress" (Json.map tagger Html.Events.keyCode)
```
[初期設定]Rails開発における初期設定5項目

# 目次

1. アプリケーション全体の日本語化(i18n)
2. アプリケーションのタイムゾーンの日本語化
3. 開発環境の設定
4. テスト環境の設定
5. generate時の生成ファイルの設定

# 1. アプリケーションの日本語化

アプリケーションを日本語化することで、ビューで時間などを表示する際に、日本語の辞書を参照してくれるようになります。

まず、設定ファイルで日本語を設定します。

```ruby:config/application.rb
config.i18n.default_locale = :ja
```

次に、日本語の言語ファイルを作成します。 内容は、[rails-i18n](https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.yml)のものをダウンロードします。

```yml:config/locales/ja.ymlにダウンロード
curl -s https://raw.githubusercontent.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml -o config/locales/ja.yml
```

# 2. アプリケーションのタイムゾーンの日本語化

アプリケーションにタイムゾーンを設定することで、ActiveRecordのタイムスタンプを日本時間で表示するなどの処理を行なってくれます。

```config/application.rb
config.time_zone = 'Tokyo'
config.active_record.default_timezone = :local　　＃　DBのタイムゾーンを変更
```

# 3. 開発環境の設定

開発用のGemを導入・設定しておくことで、開発をスムーズを行なえるようになります。 以下を参考に、必要なものを導入します。(順次追加予定)

```ruyb:Gemfile
  gem 'annotate'            # 現状のスキーマの注釈をコメントとしてファイルの上部や下部に追記してくれる。
  gem 'better_errors'       # エラー画面をデバッグしやすい形に整形してくれる
  gem 'binding_of_caller'   # better-errorsのエラー画面でirbができる
  gem 'bullet'              # 「N+1 問題」を検出してくれる
  gem 'hirb'                # コンソールのModelの出力結果を表形式で分かりやすく表示する
  gem 'hirb-unicode'        # 日本語などマルチバイト文字の出力時の出力結果のずれに対応
  gem 'letter_opener_web'   # 送信したメールを確認できる
  gem 'pry-rails'           # コンソールをirbからpryに置き換える。
  gem 'pry-byebug'          # ソースコードにブレークポイントを埋め込んで、所定のポイントでpryを起動
  gem 'quiet_assets'        # developmentログへのアセットパイプライン関連のログ出力を抑制
```

# 4. テスト環境の設定

テスト環境を構築する手順については、下記を参照↓

[RailsでRSpecによるテスト環境を構築する手順](http://post.simplie.jp/posts/40)

# 5. generate時の生成ファイルの設定

```rails generate```コマンドでコントローラやモデルを生成する際、ヘルパーやビュー、テストといった、関連するファイルが自動で生成されます。

これを生成しないようにするには、以下のように設定します。 生成する必要ないものは、事前に無効化しておきましょう。

```ruby:config/application.rb
config.generators do |g|
  g.assets false           # assetsの無効化
  g.helper false           # helperの無効化
  g.test_framework false   # testの無効化
end
```

---

```ruby:config/application.rb
module BoardApp
  class Application < Rails::Application
    config.time_zone = 'Tokyo'
    config.active_record.default_timezone = :local
    config.i18n.default_locale = :ja

    config.generators do |g|
      g.assets false
      g.helper false
      g.test_framework false
    end
  end
end
```
Ruby Objectモデル(メタプログラミングruby　2章まとめ)

## オープンクラス
Rubyでは標準で用意されているclassでも、その場で再オープンして、メソッドを追加することができる。
->うまく使ったgemの例が2.1.2にある。

```ruby:sample.rb
class String
  def to_alphanumeric(s)
    s.gsub(/[^\w\s]/, '')
  end
end
```
今回はString型にto_alphanumericというメソッドがなかったため問題なくいったが、もし、to_alphanumericが既存のメソッド名と被ってしまっていたりしたらコンフリクトを起こして、他のコードにも影響を与えてしまうという問題もある。

また、Rubyでは言語要素として、classを定義するだけでは実際にclassが存在していることにはならない。Rubyでは定義したclassにRubyが入った時に初めて、classが定義される。

## インスタンス変数
Rubyのオブジェクトのクラスとインスタンス変数にはなんの繋がりもない。インスタンス変数は値が代入された時に初めて出現する。そのため、同じクラスのインスタンスを生成しても、インスタンス変数を呼び出していなければ、そのインスタンス変数は存在しないし、呼び出していれば、インスタンス変数が存在する。また、同じクラスのインスタンス変数であっても、値が異なることもある。
class|{@v=2}{@v=1}{}{@v=3}|
{}一つ一つはインスタンス
図にするとこんなイメージ。

##メソッド
classの中にメソッドを定義しているが、実際にそのメソッドを持っているのはそのclassから作られたインスタンスであり、class自体がメソッドを持っている訳ではない。classの中に定義されているメソッドはそのインスタンスが参照できるメソッドということで、インスタンスメソッドと呼ぶ。

## classもオブジェクト
Rubyではクラスもオブジェクトである。なので、オブジェクトに当てはまるものはクラスにも当てはまる。クラスもオブジェクトなので、当然クラスがあって、それはClass クラスである。

```ruby:sample.rb
"hello".class # => String
String.class # => Class 
```
つまり、StringやArrayといったクラスはClassクラスのインスタンスであるということができる。よってClassクラスに定義してあるメソッドはStringやArrayのインスタンスメソッドであるということができる。

## Rubyにおける変数と定数の違い
rubyでは警告が出るものの、定数を置き換えるという事ができてしまう。定数が置き換えれてしまうなら、定数と変数の違いってないにも等しいのではないのだろうか。

変数と定数の大きな違いはスコープ。定数と変数のスコープのルールは異なっている。

定数のスコープのルールはファイルシステムと同じようにツリー状に配置されている。モジュールやクラスがディレクトリで、定数がfileといった感じ。異なるディレクトリだったら、同じ名前のfileを複数持つ事が可能である。

また、定数はfileやディレクトリのようにネストする事が可能。

```ruby:sample.rb
module M
  class C
    X = 'ある定数'
  end

  C::X # => "ある定数"
end

M::C::X # => "ある定数"
```
また、ツリーの奥の方にいる場合は、

```ruby:sample.rb
Y = "ルートレベルの定数"
module M
  Y = 'Mにある定数'
  Y # => "Mにある定数"
  ::Y # => "ルートレベルの定数" 
end
```
## ネームスペースを使う
自分で新しくclassを定義したときに使っているライブラリのclass名と被っていることにきずかずに拡張してしまったり、module名と被っていることにきずかずにエラーが吐かれてしまう場合がある。このような場合ネームスペースを使えば解決をすることができる。
例えば、自分の書いたclass TextがAction Mailerのmoduleと被ってしまった場合

``` ruby:sample.rb
module Myclass
  class Text
```
とすることで、Textクラスへの参照をMyclass::Textと書き直すことで対象することができる。

## メソッドを呼び出すときにおきていること
### メソッド探索
メソッドを呼び出したとき、まずはそのレシーバのクラスにメソッドを探しにいく。その後、見つからなければそのsuper　classへ見に行く。途中でmoduleをincludeしていた場合はincludeしているclassとsuper classの間にmoduleを差し込んで、メソッドを見に行く。 同じmoduleを多重includeしていた場合には先にincludeされた方が有効になり、後からincludeされた方は無効化される。
### self
メソッドを呼び出すときはそのメソッドを呼び出すレシーバがselfになる。他のオブジェクトを明示してメソッドを呼び出したときはそのオブジェクトがレシーバになる。

```ruby:sample.rb
class Myclass
  def testing_self
    @var = 10
    my_method #self.my_methodと同じ
    self 
  end

  def my_method
    @var = @var + 1
  end
end
```

```
obj = Myclass.new
obj.testing_self # => <Myclass:~~~ @var = 11>
```
### private
privateメソッドはレシーバを明示的に書くことができないので、selfをレシーバにしないと呼び出すことができない。

##classの意図しない書き換えを防ぐために
String　classを拡張したいけど、変更が全てに及ぶと予期せぬエラーがおきそうで怖い場合、変更が及ぶ範囲を限定することができる。それがrefineとusing
ただ、refineはまだ、仕様が変わりうるメソッドなので、気をつけて使わなくてはならない。

##まとめ
・オブジェクトは複数のインスタンス変数とclassへのリンクでできている
・オブジェクトのメソッドはオブジェクトのclassにある。クラス側から見れば、インスタンスメソッドと呼ばれる。
・定数はfileシステムのようなツリー状で配置されている。
Apache HttpPostでslackAPIを使ってファイルアップロードする話

Slack APIでファイルをアップロードしようとしていたときに見つけたstackoverflowの記事がちょっと消化不良だったので書いておく。
[How to upload a file using Apache HttpPost
](https://stackoverflow.com/questions/35228317/how-to-upload-a-file-using-apache-httppost)
上記の通りに書いても200 OKにはなるものの、"no file data"
になるので、ファイルアップロードには成功していない。
事前にこの記事を読んでいたので、
[HttpURLConnectionでmultipart/form-dataをPOSTする](http://ria10.hatenablog.com/entry/20121222/1356153903)
InputStream使えばいいのかなーと公式ドキュメントのメソッドの引数確認したらやはりありました。
[MultipartEntityBuilder](https://hc.apache.org/httpcomponents-client-ga/httpmime/apidocs/org/apache/http/entity/mime/MultipartEntityBuilder.html)

APIに使うtokenは事前にインジェクト済みです。

```java
public String post(File file) {
		CloseableHttpClient client = HttpClientBuilder.create()
		        .build();
		HttpEntity requestEntity=null;
		try {
			requestEntity = MultipartEntityBuilder.create()
					.addTextBody("token", token)
					.addTextBody("filetype", "jpg")
.addBinaryBody("file", new FileInputStream(file),ContentType.IMAGE_JPEG,"graph")
			        .build();
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
		HttpPost post = new HttpPost(URL);
		String result = null;
		try {
			post.setEntity(requestEntity);
			HttpResponse response = client.execute(post);
			logger.info("Status: {}", response.getStatusLine());
			result = collectResponse(response);
	
		} catch (IOException e) {
			logger.error("While posting", e);
		}
		return result;
	}
```


```xml
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.5</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpmime</artifactId>
    <version>4.3.1</version>
</dependency>
```

参考リンク：https://github.com/salahsheikh/jpushbullet/blob/master/src/main/java/com/github/silk8192/jpushbullet/PushbulletClient.java
ラズパイ3よりもパワフルなTinkerboardを試す

# Tinkerboard とは

https://www.asus.com/jp/Single-Board-Computer/Tinker-Board/

ラズベリーパイと形状とピン配置が互換！
なので入手しやすいラズパイ用のケースや周辺パーツがそのまま使えます。
SoCはRockchip RK3288。GPUによるH.264, H.265のデコードとH.264のエンコードができます。
CPUはCortex A17x4 最大1.8GHz。32bitのARMですが、32bitの中でもハイパフォーマンスなものです。ラズパイシリーズのCPUは低消費電力型のものが採用されているので、それよりずっとパワフルです。
RAMは2GB。デュアルチャネルになっているのでラズパイ3よりもメモリ帯域が広いです。

というわけで、画像処理をするにはラズパイ3よりも向いているだろうということで購入しました。

# 電源

パワフルであるということは電気を食うということでもあります。
2.5A供給できるACアダプタを使わないと起動できませんでした。

# シリアルコンソールを使う

![IMG_0976.jpg](https://qiita-image-store.s3.amazonaws.com/0/13271/05bdf3e4-2983-7d34-5b38-f6430b845b9f.jpeg)

TinkerOS_Debian V2.0.5 からシリアルコンソールにはUART3を使うように変わりました。
カーネルログをシリアルコンソールに出すにはSDカードのFATのパーティションの`extlinux/extlinux.conf` のconsole= の部分を以下のように変更します。

```/boot/extlinux/extlinux.conf
label kernel-4.4
    kernel /zImage
    fdt /rk3288-miniarm.dtb
    append  earlyprintk quiet splash plymouth.ignore-serial-consoles console=ttyS3,115200n8 rw init=/sbin/init
```

ブートログはgistに貼りました。
https://gist.github.com/tetsu-koba/a6745db57e58e43b0412a855c803b910


# 参考

[[メモ] ASUS TinkerBoard : シリアルコンソールを使う](https://qiita.com/mt08/items/5ee45b47d0ef9c3a6863)
[[メモ] ASUS TinkerBoard: TinkerOS_Debian V2.0.5 関連](https://qiita.com/mt08/items/7582faef93eb9065edb2)
【Elm】前置記法

演算子を操作対象の前に記述することが出来る。
前置記法（prefix notation）と呼ぶ。

例えばElmは以下のように書ける。

```elm
-- 中置記法で定義したタプル型
main =
  ( 3 ,4 )
  |> toString
  |> text -- => (3, 4)
```

```elm
-- 前置記法で定義したタプル型
main =
  (,) 3  4
  |> toString
  |> text -- => (3, 4)
```

加算も以下のように書ける。

```elm
main =
  (+) 3  4
  |> toString
  |> text -- => 7
```
Arduino互換機でシリアルポートを認識しなくなった場合の対処


複数のArduino互換機をMacBookAirにUSBケーブルで接続し、Arduino IDEで作業をしています。シリアルポートを認識しない度に、場当たり的に、USBシリアル変換モジュール(CH340/CH340G)のドライバーをinstallしていたら、どのArduino互換機でもシリアルポートを認識しなくなったので、対処方法を確認しました。

結論としては、Arduino互換機で使われているUSBシリアル変換モジュールの古いドライバを削除して、最新のドライバをinstallすることで、シリアルポートを正常に認識するようになりました。

# 環境
* MacBookAir MacOS 10.13.4
* Arduino IDE 1.8.5
* USBシリアル変換モジュールドライバCH340/CH340G最新版(v1.4)
	* http://www.wch.cn/download/CH341SER_MAC_ZIP.html
* 利用したArduino互換機
	* [Arduino UNO互換機](https://www.aliexpress.com/item/NEW-UNO-R3-ATmega328P-CH340-Mini-USB-Board-for-Compatible-Arduino-Hot-sale/32374958769.html?spm=2114.search0204.3.64.d7c772a08nMN9D&ws_ab_test=searchweb0_0,searchweb201602_3_10152_10151_5711320_10065_10344_10068_10342_10343_10340_10341_10698_10696_10084_5722520_10083_10618_10307_5711220_10059_5722620_5722920_308_5722720_5722820_100031_10103_10624_10623_10622_10621_10620,searchweb201603_25,ppcSwitch_5_ppcChannel&algo_expid=2dbbb86a-ceff-4070-8be9-977a8075274a-9&algo_pvid=2dbbb86a-ceff-4070-8be9-977a8075274a&priceBeautifyAB=0)
	* [Arduino Nano互換機](https://www.aliexpress.com/item/1PCS-Nano-3-0-controller-compatible-with-nano-CH340-USB-driver-NO-CABLE-NANO-V3-0/32684621397.html?spm=a2g0s.9042311.0.0.OOJz6v)
	* [ESP-WROOM-32 DEV KIT](https://www.aliexpress.com/item/Official-DOIT-ESP32-Development-Board-WiFi-Bluetooth-Ultra-Low-Power-Consumption-Dual-Core-ESP-32-ESP/32799253567.html?spm=a2g0s.9042311.0.0.Ahij0l)


# 対処
* 古いドライバの削除

```
$ sudo rm -rf /System/Library/Extensions/usb.kext
```
もしくは

```
$ sudo rm -rf /Library/Extensions/usbserial.kext
```

* 念のためMacを再起動
* 新しいドライバのinstall
	* 今回は、ver1.4をinstall。	「下载」をクリックして、download。
		* http://www.wch.cn/download/CH341SER_MAC_ZIP.html
	* ドライバinstall時に、再起動を要求される。
* MacとArduino互換機をUSBケーブルで接続、Arduino IDEを起動し、[ツール]-[ボード]にて、適切なボードを選択後、[ツール]-[シリアルポート]にて、適切なシリアルポートが表示されることを確認。
	* Arduino Nano互換機については、[ツール]-[ボード]で「Arduino Nano」を選択、[ツール]-[プロセッサ]で「ATmega328P(Old Bootloader)」を選択することで、[ツール]-[シリアルポート]にて、適切なシリアルポートが表示されるようになりました。


# 参考
https://qiita.com/BlueTone/items/fe5063b1b0cb9a0739e7
https://qiita.com/ryusukefuda/items/5b2edea6b62794069209
https://qiita.com/sugasaki/items/f3258a8138c69d73069f
https://www.dorapro.co.jp/engineerblog/?p=720


以上