OmniAICreator/Qiita-1.07M huggingface dataset:
mbedで無線DualShock2を使う

#1.はじめに
PS2のコントローラーを無線で使いたかったので、大阪日本橋でそれっぽいのをかってきました。が、逆電圧をかけてすぐに受信モジュールを殺しました。そこで、amazonにて[こういうもの](https://www.amazon.co.jp/Playstation2-ワイヤレスコントローラー-DUALSHOC2-（オートスリープ機能-１年保証付き『クリスタル』/dp/B07DNRPY9C/ref=sr_1_26?ie=UTF8&qid=1548531028&sr=8-26&keywords=PS2+コントローラ)をプライムして使ったときにちょっと詰まったので、その話。
mbedで有線のPS2を使うとき、[pspad.h](https://os.mbed.com/users/kurt/code/pspad/)というライブラリをいつも使っていましたが、それがそのまま使えなかった(ちょっとずれて値が出力されると言える)ので、それの解決策です。
オシロスコープなどで波形を見たり，入力されたデータなどを保存していたのですが，写真とかをまったく残していなかったので省略します．需要があれば，コメントをいただけると何らかの対応をするかもです．

#2.理論
PS2コントローラーは、SPI通信でデータを送信しています。SPI通信には4種類のモードがあり、PS2のはMode3が使われています。このモードの違いによって，クロックの立ち上がり/立ち下がりや，正論理/負論理の違いがあります．モードの詳細な内容は[しなぷすさんのページ](https://synapse.kyoto/glossary/glossary.php?word=SPI)が参考になります．購入したコントローラのSPI通信のモードが違ったようなので，クロックのタイミングを変更することで解決を試みました．

#3.解決方法
pspad.hの56行目から82行目までを↓のように書き換えることで，クロックのタイミングを変更します．

```cpp
    for(i=0; i<8; i++){
        // 送信データ
        if(send_data & 0x01) PS_CMD_H;
        else PS_CMD_L;

        PS_CLK_H; // クロックをHIGHに
        while(tm.read_us()/TM_PERI <= 2*i); //待機

        PS_CLK_L; // クロックをLOWに
        while(tm.read_us()/TM_PERI <= 2*i+1); // 待機
        recv_data |= (PS_DAT<<i); // 受信データ
        
        send_data >>= 1; // 送信データを１ビットずらす
    }

    PS_CMD_H; // CMDをHIGHに戻す
    PS_CLK_H; // CLKをHIGHに戻す
```

#4.おわりに
ここに書いた解決方法は，あくまでもamazonでぽちったやつを動かす方法なので有線や，ほかのコントローラで有効か知りません．ベースとして使わせていただいたpspad.hの製作者の 太郎 九大 さん，ありがとうございます(SPI通信をすべて自力で実装はイケメン)．

##参考文献
- pspadのライブラリ：https://os.mbed.com/users/kurt/code/pspad/
因数分解をやってみた

## はじめに
中学生で習う２次関数の因数分解を、中学生が考えるであろう考え方の手順で、プログラムで解く方法を考えてみました。最近流行りのプログラミング的思考で、数学の問題を解く、ってことでしょうか。こういう自由研究があってもいいかなと思います。

解きたい問題はa,b,c が与えられた時
$$ax^2 + bx+c = 0\tag{1}$$
を
$$(px+q)(rx+s) = 0 \tag{2}$$
の形に変形する時のp,q,r,sを求める問題です。ここでは中学生が解く時の考え方に近づけないので、解の公式は使いません。

##アルゴリズム概要
a,b,c が与えられたとき、p,q,r,sを求めます。
(2)の式より
$$prx^2+(ps+qr)x+qs=0\tag{3}$$
(3) = (1) ですので、
$$a = pr\tag{4}$$$$b=(ps+qr)\tag{5}$$$$c=qs\tag{6}$$
となります。たぶん中学生が習うときは、aの約数としてのpとrを見つける。cの約数としてのqとsを見つける。たすき掛けで、ps+qrを計算してみて、bを一致するものを見つける。といった手順かと思います。この方法を愚直に実行してみます。下にフォローチャトで考え方の概要を示します。

![因数分解.jpg](https://qiita-image-store.s3.amazonaws.com/0/58417/f841d584-441f-851d-1f60-37be78834212.jpeg)

## 詳細説明
###第１段階
a,b,c が与えらられたとき、もしaが負であった場合、(1)式の両辺に-1をかけて、x^2の係数を正にします。
$$ ax^2+bx+c=0$$$$a<0$$
$$ (-a)x^2-bx-c=0$$$$-a>0$$
-a を改めて a と置きます。
$$ ax^2-bx-c=0$$ 
と書くことにします。aがマイナスだったことは覚えておいて、答えが出た後に結果にマイナスを付けます。
$$-(px+q)(rx+s) = 0$$

###第２段階
(4)式、(5)式より、aとcの約数を求めます。aは必ず正、cはその絶対値の約数を求めます。例えば、$$12x^2+24x+9=0\tag{7}$$とします。$$ a = 12 $$ であれば、約数は$$ 1,2,3,4,6,12 $$です。約数 の数はm=6、それぞれの約数を$$a_0, a_1, ..., a_{m-1}$$
と書いておきます。
$$ a = a_i a_{m-1-i}\tag{8}$$
と書けます。

次にcの約数を求めます。$$ c = 9$$ですので、約数の数は$$n=3$$約数は$$1,3,9$$となりまず。(8)式は、$$c=c_i c_{n-1-i} $$と書けます。i=1の時は$$c=c_1 c_1={c_1}^2$$ となります。

###第３段階
a の約数がm個で、$$a_0, a_1,..., a_{m-1}$$ c の約数がn個で$$c_0, c_1,..., c_{n-1}$$です。c>0 であれば、(7)式は$$(a_ix+c_j)(a_{m-1-i}x+c_{n-1-j})\tag{9}$$もしくは$$(a_ix-c_j)(a_{m-1-i}x-c_{n-1-j})\tag{10}$$$$i=0,1,...m-1$$$$j=0,1,...n-1$$のいずれかと一致します。教科書にもある<b>たすきがけ</b>で一致するbの値を求めます。$$a_ic_{n-1-j})+c_ja_{m-1-i}$$$$-a_ic_{n-1-j}-c_ja_{m-1-i}$$

一方、c<0であれば、(7)式は$$(a_ix+c_j)(a_{m-1-i}x-c_{n-1-j})\tag{9}$$もしくは$$(a_ix-c_j)(a_{m-1-i}x+c_{n-1-j})\tag{10}$$$$i=0,1,...m-1$$$$j=0,1,...n-1$$のいずれかと一致します。こちらも<b>たすきがけ</b>で一致するbの値を求めます。$$-a_ic_{n-1-j}+c_ja_{m-1-i}$$$$a_ic_{n-1-j}-c_ja_{m-1-i}$$

###最後に
一致した、a,c の約数をp,q,r,sとします。もし、最初に与えられたaが負の場合にはp,q を負にします。（r,s を負にしても同じ）

中学生が教科書通りに答えを見つける方法はこんな手順かな、と思います。

###プログラム
TBD
【2019年版】Windowsで始めるDeep Learning環境構築

こんにちは。今日は自分が新しくDeepLearning用のマシンを購入したので、それの環境構築が意外とすんなりいったので、メモとして記録していきます。
昔のCUDAといえばおぞましく入れるのが面倒な必須ライブラリでしたが、今となっては結構簡単に入るようです。

# WindowsでDeep Learningしたい！！

Windows上で動く快適なDeepLearningを楽しむ基本的な手順としては

- Visual Studio C++環境をインストールし、CUDAを迎える準備を整える
- CUDA10を迎え入れる
- 必要なpythonパッケージを迎え入れる
- Visual Studio Codeを迎え入れる
- Visual Studio CodeをJupyter化

といった形を行うことで、コード生成や実験の早いDeepLearningの研究用の環境が整います。

# 今回使用した環境

今回、自宅で仕事を処理するために使おうと思い、新しくPCを新調しました！大体のスペックは以下の通りです。

- Intel i9-9900K 8core 16thread.
- RTX 2080 Ti 11GB GDDR6.
- 32GB DDR4 RAM
- 500GB NVMe SSD(正直1TBにすればよかった) 

新調するために2013年に自作PCした時の知識を更新したのは

- 最新高性能GPUはRTX 2080Tiになって価格は18万円近くする
- RAMは規格がDDR4になってる。価格はサイズあたりそんなに下がってない。これから下がるらしい。速度も早くなってるらしい。
- SSDがPCIeで接続するようになって超高速化。10倍近い進化。
- 更にM.2規格でGPUを挿すPCIeの場所とは別の場所ができてる。
- SSDにSATA使うのはもはや時代遅れ。
- 価格がめちゃくちゃ安くなってる。1TB 2万円とか。早いのに大容量で安い。
- 一方でNVMeのSSDはめちゃ発熱するのでヒートシンクが必要

ご参考までにどうぞ。

# 1. Visual Studioを迎える

Visual Studioを迎える準備をします。CUDAを迎える前に、まずC＋＋ビルドできる環境にする必要があります。

詳しくは[こちら](https://qiita.com/kekekekenta/items/a46a899956b1c756ddce)の記事も有用なので参考にしてください。

## Visual Studio をダウンロード

![InkedSnapCrab_NoName_2019-1-27_1-29-17_No-00_LI.jpg](https://qiita-image-store.s3.amazonaws.com/0/182970/96c324f6-038a-be26-520c-a121e11c7333.jpeg)

ここから、Community版をダウンロードし、インストール。

## Visual Studioをインストール

ここ、画像が用意できなくて申し訳ないんですが、重要な点を記載しておきます。

- そのままインストールするとVisual Studio**だけ**をインストールされてしまうので意味ない。
- 必ず**C++の開発オプションをつける**
- 必ず**Python開発オプションをつける**
- C++は大枠をCheckすれば大丈夫。Python開発のオプションではAnaconda3 64bit版などの必要なオプションをインストールするのも忘れないようにしよう。

しっかりと設定を行ったら、インストールを行いましょう。

# 2.CUDAを迎え入れる

[ここから](https://developer.nvidia.com/cuda-downloads)CUDA10をダウンロードしてインストールを行いましょう。
手順を進めていけばOKですが

- しっかり出てくる文章を読むこと。
- Visual Studioがインストールされていないけど大丈夫か？という英語メッセージが出たら**C++系が入っていないので**1番をもう一度確認しましょう。

# 3.必要なパッケージを入れる

![SnapCrab_NoName_2019-1-27_1-43-56_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/182970/d2ab4260-9b4c-7149-c9c0-40fd6760bcfc.png)

このAnaconda Promptをどうにかして**管理者権限**で開きます。
このAnacondaはVisual Studioのオプションで入ったものですが、Python Versionは3.6.5になります。


## Chainerを入れる

とりあえずChainerを入れてみましょう。

```
C:\Windows\system32> pip install msgpack
C:\Windows\system32> pip install cupy
C:\Windows\system32> pip install chainer
```
をそれぞれ入力しましょう。
msgpackはcupyに必要なパッケージです。

# PyTorchを入れる

PyTorchは[公式サイト](https://pytorch.org/)を参考にやるとすんなり行きます。（行かなかったらコメントください）

```
C:\Windows\system32> pip install https://download.pytorch.org/whl/cu100/torch-1.0.0-cp36-cp36m-win_amd64.whl
C:\Windows\system32> pip install torchvision
```


# 4.Visual Studio Codeを迎え入れる。

![a.jpg](https://qiita-image-store.s3.amazonaws.com/0/182970/70f3d979-49de-782f-1a83-8ad108ec1eaa.jpeg)

Visual Studio Codeを迎え入れましょう。

# 日本語化

拡張機能でJapaneseと検索すると、日本語化パッケージがあるのでこれを選択。

# Python対応

拡張機能でPythonと検索すると、Python対応パッケージが出るのでそれをインストール

# Jupyter対応

詳しくは[こちら](https://qiita.com/surei/items/9f25d7efa7c67d55d98f)が非常に参考になります。
Visual studio CodeのJupyterについては[こちら](https://qiita.com/suudon0014/items/dbf0237d90922275af1c)が参考になります。


# 5.Enjoy!

Let's 研究ライフ！
そのうちベンチマーク的なコードを載せれたら載せたいと思います。
機械学習でLog Lossとは何か

本記事はfast.aiのwikiの[Log Lossページ](http://wiki.fast.ai/index.php/Log_Loss)の要約となります。
筆者の理解した内容で記載します。

**一言でいうと、クロスエントロピー。0~1の予測値を入力してモデルの性能を測る指標を出力する。**

## 概要
**Logarithmic Loss**のこと
分類モデルの性能を測る指標。(このLog lossへの)入力は0~1の確率の値をとる。
この値を最小化したい。完璧なモデルではLog lossが0になる。
予測値が正解ラベルから離れるほどLog lossは増加する。

## Accuracyとの違い

* **Accuracy**は予測した値と正解が一致していた数のカウント。正解/不正解しかないのでいつも良い指標とは限らない（惜しかった、などが測れない）
* **Log Loss**は実際のラベルからどのくらい違っていたのかを考慮できる

## 可視化
下記のグラフは正解ラベルが例えば犬＝1の場合にLog lossが取りうる値を示す

* 予測値が１に近づくとLog lossはゆっくり減少する
* 予測値が0に近づくと急増する

Log lossはモデルが間違ったラベルを、高い確信度で出力したときに、特に高くなる
![Log lossのグラフ](http://wiki.fast.ai/images/4/43/Log_loss_graph.png)

## コード
pythonの場合。
関数の入力が0~1に収まるように`np.clip()`を通す

```python:logloss.py
import numpy as np
import math

def logloss(true_label, predicted, eps=1e-15):
  p = np.clip(predicted, eps, 1 - eps)
  if true_label == 1:
    return -math.log(p)
  else:
    return -math.log(1 - p)

```

## 数学的なこと
1つの出力値に対するlog lossの計算式を示す。データセットに対してモデルを評価するときは単にすべての出力でlog lossを計算して平均する。

### 以降で使用する変数の定義

* $N$ : データ数
* $M$ : 全クラスラベル数
* $\log$ : 対数関数（底は$e$）
* $y$ : クラスラベル。0または1をとる。（観測$o$がクラス$c$に属している場合は1を設定している）
* $p$ : モデルによって出力された、観測$o$がクラス$c$に属する確率

### 2値分類の場合
2値分類(M=2)の場合の式は、

```math
-(y\log p +(1-y)\log(1-p) ) \tag{1}
```

####例1：
クラスラベルが1で予測値0.25が出力されたとき、$(1)$式よりlog lossは

```math
\begin{align}
&-(1\log 0.25 +(1-1)\log(1-0.25) ) \\
&=-(\log 0.25 +0\log(0.75) ) \\
&=-\log0.25
\end{align}
```

####例2：
同様にクラスラベルが0で予測値0.25が出力されたときは

```math
\begin{align}
&-(0\log 0.25 +(1-0)\log(1-0.25) ) \\
&=-(1\log (0.75)) \\
&=-\log(0.75)
\end{align}
```
  

####＊
ちなみに２番目の例は元記事では
<img src=https://qiita-image-store.s3.amazonaws.com/0/296108/3915856e-2336-8fac-0da5-3fd95081a4b3.png>
となっており、第二項目のlogの中が$0-.25$と表記されているが、
$(1)$式で第２項目のlogの中身は$1-p$であるのでこれは誤りで、$1-.25$が正しい。
(2019/1/27現在)


### 多クラスの場合
クラス数M>2の場合、各クラスの予測に関するlog lossの和になる。

```math
-\sum_{c=1}^M y_{o,c} \log(p_{o,c})
```

###log lossに負号がついているのは、
**$\log n (0<n<1)$が負の値を返すから。**
負号をつけないといつも戻り値が負になって、２つのモデルの性能を比較するときとかによくわからない。

##MinMaxルール
上記式$(1)$では、予測値が0または1の時に未定義となるので、予測値の調整をすることがある。

```
max(min(p, 1−10^−15), 10^-15)
```
###予測値p=0の場合
1. min関数を適用。`max(0,10^-15)`になる
2. max関数を適用。`10^-15`になる
3. 予測値**0**は`10^-15`(~**0.0000000000000001**)
に変換された。

###予測値p=1の場合
1. min関数を適用。`max(1-10^-15,10^-15)`になる
2. max関数を適用。`1-10^-15`になる
3. 予測値**1**は`1-10^-15`(~**0.9999999999999999**)に変換された。

##Log LossとCross-Entropyは
ほぼ同じものである。
特に機械学習で0~1の範囲で誤り率を計算するときは同じものを解いている。

```math
p \in \bigl\{y, 1-y \bigr\}, q \in \bigl\{ \hat{y}, 1-\hat{y}\bigr\}
```
とすれば、

```math
H(p,q)=-\sum p_i \log q_i = -y log \hat{y} - (1-y)log(1-\hat{y})
```
と書くことができ、一致している。
ここで

* $p$: 正解ラベルの集合
* $q$: 予測の集合
* $y$: 真のラベル
* $\hat{y}$: 予測値

である。
AWSアカウントのMFAは端末に登録されている

AWSアカウントのMFAは、格安SIMに変えて、電話番号が変わっても大丈夫。
#MFA（Multi-Factor Authentication）とは
多要素認証。IDとパスワードだけでの認証ではなく、別の端末（電話番号やスマホアプリなど）を使って認証する方式。
万が一情報流出等によってアカウントが乗っ取られた際、高額請求などの危険性があるため、AWSアカウントを作ったらすぐ設定すべきとよく言われている。

#この記事で伝えたいこと
私はAWSのMFAにGoogleAuthenticatorを使っている。
この認証情報はアプリに登録されているので、電話番号が変わっても、（スマホが変わらなければ）大丈夫。

##経緯
そもそもなんでそんなことを（しかも記事投稿に使っていなかったQiitaで）書こうと思ったかという経緯を軽く説明したい。

昨年末、きっかけがあって格安SIMに変更した。
MNPを利用して電話番号を持って移動すると手数料3240円がかかってしまうこと、番号に特に執着がなかったため、新規でSIM変更。
使っている **機種（iPhone）はそのまま** で。
流れでわりと突然の変更だったため、電話番号変更による影響は整理しないまま手続きをした。



AWSについては、駆け出しのエンジニアとしては最低限履修しておくべきと思ったため、以前、アカウントを作成していろいろ遊んでいた。が、しばらく放置していたので忘れていた。

ついさっきふと、CloudFrontにhtmlファイルを置きっぱなしだったことを思い出し、ログインを試みた。
IDとパスワードの後、MFAの認証コードを入力したところ、認証エラーになった。

パスワード入力後、MFAの画面に推移しているので、MFAの問題と思い、そこで青ざめた。
電話番号が変わったのが原因ではないかと思ったのだ。

いろいろ調べたが、AWSのMFA関連のQAには、デバイスの故障紛失による端末変更の際の対応が書かれていたものの、**電話番号の変更**については記載がなかったので、カスタマーサポートに問い合わせをしようと思ったが、MFA関連は **英語の電話** がかかってきて云々とあり、ためらった。

IAMユーザのMFAで、キーなどがテキストとしてPC内にあったりする場合は、CLIなどでできるらしいが、ルートアカウントでそういう方法があるのかはわからなかったし、そもそも使っていないアカウントなのでEC2も止めてあるし、すぐにAWS_CLIが使える環境が用意できるわけではない。

いろいろ考えているうちに、
「トークンはスマホアプリ以外にも存在する[^1]」＝「電話番号は関係ないのでは」
という（よく考えれば）至極当たり前のことに気づき、「パスワードを間違えていた」という可能性にかけてパスワードを再設定。
新しいパスワードと、アプリに表示されている認証コードでログインができた。

…そもそもパスワード間違えなければこんなことにはならなかったのだけれど。

[^1]: トークンにはカードタイプなど専用の端末もある。企業などでは鍵のかかるロッカーにトークン端末を入れておいて管理していることもあるとかないとか。
【Unity】木に衝突すると爆発のパーティクルを発生させ、プレイヤーを爆風で飛ばす

環境メモ

⭐️Mac OS Mojave バージョン10.14
⭐️Unity 2018.2.15f1

実際に動かした動画はこちら↓↓
https://twitter.com/nonnonkapibara/status/1089212339746877440

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">🌲木🌲に衝突すると🔥爆発🔥のパーティクル🎇を発生させ<br>プレイヤーを爆風で飛ばす💨💨💨<br>を作ってみたよぉ。😍<br>💕Ｏ(≧∇≦)Ｏ💕<br>木の方に爆発パーティクルそして終わったらDestroyする😊<br>プレイヤーに衝突イベントと元の場所に戻る‼️処理を入れてみたよぉ<a href="https://twitter.com/hashtag/Unity?src=hash&amp;ref_src=twsrc%5Etfw">#Unity</a> <a href="https://twitter.com/hashtag/Unity3d?src=hash&amp;ref_src=twsrc%5Etfw">#Unity3d</a> <a href="https://t.co/3DKLGMPMmu">pic.twitter.com/3DKLGMPMmu</a></p>&mdash; non (@nonnonkapibara) <a href="https://twitter.com/nonnonkapibara/status/1089212339746877440?ref_src=twsrc%5Etfw">2019年1月26日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


<font color="Magenta">Qiitaの容量オーバーで画像が貼り付けられなくなりました。（errorとなる）</font>

続きは、「はてなブログ」に記載してます↓
[かぴばらさんの覚書ブログ nonkapibara](https://nonkapibara.hatenablog.com/entry/2019/01/27/030115)
組み込みエンジニアでなくても週末にArduinoを使って遊ぶ

Arduinoの環境構築には組み込み経験がないと意外と手間が掛かりがちです。
ここでは自身の環境構築経験を記載します。
# 事前準備
・Arduino 
例えば下記のArduino UNO R3
https://www.amazon.co.jp/スイッチサイエンス-SSCI-GettingStartedArduinoKit-Arduinoをはじめようキット/dp/B0025Y6C5G/ref=sr_1_4?s=toys&ie=UTF8&qid=1548518133&sr=1-4&keywords=Arduino+正規品

※他にももっとお手頃価格のArduino UNOが沢山Amazonで見つかりますが、互換品のものが多いです。互換品の場合はシリアルドライバが見つからない問題に遭遇する場合があります。解決方法は下記等が参考になと思います。
https://qiita.com/seigot/items/1515082a09224563b148
最初から不要なトラブル解決に時間を掛けたくない場合は正規品を購入するのも手かもしれません。

・Arduino IDE (Integrated Development Environment)
コーディング用の環境です。
Arduino Software (IDE)https://www.arduino.cc/en/main/software

・LEDと220Ω程度の抵抗
上記のはじめようキットに入っているものが使えればそれでも問題ありません。


# 環境構築
IDEを下記からダウンロードします。
![001.png](https://qiita-image-store.s3.amazonaws.com/0/344880/3a5a9c70-6169-306a-bd18-acf77fa8e7f2.png)

# Arduinoを入手、環境構築の後の初めのstep
Arduinoを使いモノを動かしてこそ楽しさがあると思います。初めのstepとしてはArduinoとLEDを接続し、LEDを光らせます。

#### ArduinoからLED点灯させるコード作成
入手したArduino IDEを開きます。
![002-1.png](https://qiita-image-store.s3.amazonaws.com/0/344880/77bff5d4-2d89-8515-deef-4b069241a587.png)

ファイル→スケッチ例→01.Basics→Blinkを選択します。
![002-2.png](https://qiita-image-store.s3.amazonaws.com/0/344880/8048a6b9-59e9-849c-8423-40ea12acaa04.png)
コンパイルします。
![003.png](https://qiita-image-store.s3.amazonaws.com/0/344880/3c01d06a-f86e-bc41-9e04-33dbce7ec1a9.png)
「コンパイル完了」と表示されればOKです。
![004.png](https://qiita-image-store.s3.amazonaws.com/0/344880/5910ad56-6ada-4d3b-3e11-264c3c24d8f0.png)
ここで、コードの意味は下記の通りです。PIN13の信号をHIGH/LOWにすることでLEDの点灯を行います。
![005.png](https://qiita-image-store.s3.amazonaws.com/0/344880/b80b9bf3-c68e-72f9-8ab1-3abe6dc5d388.png)
#### Arduino配線
ArduinoとLEDと抵抗は下記の通り接続します。ArduinoのPIN13とGNDの２本を使います、またLEDには向きがあり、足の長い方をPIN13側に繋いで下さい。

![005-2.png](https://qiita-image-store.s3.amazonaws.com/0/344880/1c9294b7-0c8b-3ff7-ffa2-b7331a54788d.png)

#### Arduinoコード書込み
ボードとシリアルポートを選びます。ボードはArduino UNO、ポートはusbserialを選択して下さい。（※ポートを選べない場合は、Arduinoが繋がっていないか、USBドライバをインストール必要がある可能性があります。）
![008.png](https://qiita-image-store.s3.amazonaws.com/0/344880/b3246df9-7977-bcbe-9d3f-eaaa093e340a.png)
マイコンに書き込みを行います。
![009.png](https://qiita-image-store.s3.amazonaws.com/0/344880/9597df85-8dec-086a-fd74-1aa499c9c9fc.png)
#### テスト
これまでの内容が正しく行えている場合は、LEDが点灯します。
（LEDが点灯しない場合は必ず何か間違いがあります。むしろ繋いだけど動かない事はよくある事であり、間違いを見つけて解決するスキルはArduinoで遊び続けるために必要です。）

# まとめ
週末にArduinoを使って遊ぶことを思い立ってから実際に遊び始めるまでの手順を記しました。
事前準備は時間がかかりますが、準備が整ってからは、3時間程でLEDを光らせるまで辿り着けると思います。平日にAmazonで購入し、休日3時間でLEDを光らせる事が出来る事がゴールです。

Arduinoを使った遊び方例については必要に応じて更新を行いたいと思います。

# 参考
Arduino互換品を使用している場合のご参考
・[Arduino Uno 互換品を使おうとした際に、Mac(OS:Siera)上のArduino IDEからシリアルデバイスが見つからない問題を解決した件について](https://qiita.com/seigot/items/1515082a09224563b148)
連除法・すだれ算の書き方【TeX】

# すだれ算TeX

何かに書いてあったのものを書き残します。

\cline{*-*}　特定の列から列までの横線（下側）が引けます。\kernは微調整用のスペースです。

```tex
\begin{tabular}{rlrr}
2 & \kern-5pt \Big) & 54 & 90
\\
\cline{2-4}
3 & \kern-5pt \Big)& 27 & 45 
\\
\cline{2-4}
3 & \kern-5pt \Big)& 9 & 15
\\
\cline{2-4}
& & 3 & 5
\end{tabular}
```

<img src="https://texclip.marutank.net/render.php/texclip20230705043611.svg?s=%5Cbegin%7Btabular%7D%7Brlrr%7D%0A%092%26%20%5Ckern-5pt%20%5CBig)%20%26%2054%20%26%2090%0A%09%5C%5C%0A%09%5Ccline%7B2-4%7D%0A%093%20%26%20%5Ckern-5pt%20%5CBig)%26%2027%20%26%2045%20%0A%09%5C%5C%0A%09%5Ccline%7B2-4%7D%0A%093%20%26%20%5Ckern-5pt%20%5CBig)%26%209%20%26%2015%0A%09%5C%5C%0A%09%5Ccline%7B2-4%7D%0A%09%26%20%26%203%20%26%205%0A%5Cend%7Btabular%7D&f=c&r=600&m=s&b=f&k=f">
A-Frameで始めるWebVR  公式HPのExampleをみてみよう．

#公式のExampleは相当面白い．
A-Frameは，Three.jsよりも簡単にWeb3Dをか使うことのできるプラットフォームです．
その反面，複雑なものは作れませんがA-Frameでこんなものが作れるんだと参考にしてもらえるとよいです．



##Hello Metaverse![HelloMetaverse.PNG](https://qiita-image-store.s3.amazonaws.com/0/274029/18ac58b1-30ba-694a-985a-aa3a2dc2e57a.png)

メタバース は、SF作家・ニール・スティーヴンスンによる1992年の著作『スノウ・クラッシュ』の作中で登場するインターネット上の仮想世界のこと。 転じて、将来におけるインターネット環境が到達するであろうコンセプトモデルや、仮想空間サービスの通称としても用いられる。
[参考動画]
https://youtu.be/4nixOLPpZzo


##360° Image Gallery
![360ImageGallery.PNG](https://qiita-image-store.s3.amazonaws.com/0/274029/158841a3-268d-76cc-7f10-e3325cd849b3.png)
[参考動画]
https://youtu.be/6ofkyEoTlaQ


##360° Video
![360 Video.PNG](https://qiita-image-store.s3.amazonaws.com/0/274029/7659af2e-25f2-afdb-215e-99a9eadfe18d.png)
[参考動画]
https://youtu.be/8xZlFqYC_-Q



##A Saturday Night
![SaturdayNight.PNG](https://qiita-image-store.s3.amazonaws.com/0/274029/e19c9b2d-aad4-293a-55cb-b6509ae17a42.png)
個人的にはこのExampleがお気に入りです．
[参考動画]
https://youtu.be/ggczPtr9V3Q

##クリスマスツリー
公式のExampleではないですが，A-Frameで作成されたおもしろい作品がありましたので紹介します．
@tspringkj さんによるクリスマスツリー
https://codepen.io/tspringkj/full/QzvXxm
![ChristmasTree.PNG](https://qiita-image-store.s3.amazonaws.com/0/274029/68bcdbac-55e3-a406-fcb5-7b63cb579d18.png)

QRコードを読み込んで，スマホで見ることもできます．
![CristmasQR.PNG](https://qiita-image-store.s3.amazonaws.com/0/274029/b0f2a433-7f1d-621f-c545-757f44ea6034.png)

3Dをこんなにも手軽に扱えるというのはとても新鮮ですね．ぜひ何か作ってみましょう．
PyCharm + TensorFlow + Virtualenv/pyenvの環境構築

TensorFlowの環境を作ろうとして、ハマったのでメモ。 ポイントだけ書いておく。

##用語
さらっとおさらい

###統合開発環境PyCharm
PythonのIDE。有名なので使います。今回はCE版
https://qiita.com/yamionp/items/f88d50da8d6b548fc44c

###pyenv
Pythonのバージョン切り替えに使用
基本的にPythonのバージョンごとに管理
同一バージョンで複数のPython環境を管理不可能（パッケージが混在する）
数値計算用のpython2.7.10と自然言語処理用のpython2.7.10にはならずpython2.7.10として数値計算ようのパッケージと自然言語処理用のパッケージが混在

###virtualenv
仮想環境の構築に使用
基本的にディレクトリ単位でPythonのバージョン，パッケージを管理
数値計算用のpython2.7.10と自然言語処理用のpython2.7.10分けて使用可能
https://qiita.com/niwak2/items/5490607be32202ce1314


##インストール

###brew cask
GUIまでインストールできちゃうhomebrew。便利なので入れておくことをおすすめします。

```
brew install caskroom/cask/brew-cask
```

なお、PyCharmはこんな感じでインストールできちゃいます。
https://qiita.com/ryurock/items/1432578d364985f6cb06

```
brew cask install pycharm-ce
```

###pyenvとpyenv-virtualenvをインストール
https://qiita.com/KazaKago/items/587ac1224afc2c9350f1
pyenv-virtualenvのインストール

```
$ brew install pyenv-virtualenv
```

###Pythonをインストール
例は3.5.2。TensorFlowではPythonのバージョンは「Requires Python 3.4, 3.5, or 3.6」と指定があった
https://www.tensorflow.org/install/pip

インストールできる一覧を表示するにはpyenv install -lと打ち込んで下さい

```
$ pyenv install 3.5.2
$ pyenv rehash
```

###xcode-select --installがうまくいかない場合（ここでハマった！！）
Pythonがインストールできない場合、xcode-select --installを打てというサイトが多いので、
やってみたがうまくいかない。
https://qiita.com/zreactor/items/c3fd04417e0d61af0afe

xcode-selectの最新バージョン(2354)にMojave用のmacOS SDK headerがデフォルトで入っていないのが原因のようです。マニュアルで以下をインストールする必要あるとのこと。

以下で解決しました

```
sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
```


###TensorFlowの実行環境を作る
こうすることでローカルを汚さずに環境が作れます（例は環境名が"TensorFlow"。適宜変更）

```
$ pyenv virtualenv 3.5.2 TensorFlow
$ pyenv rehash
```

###作成したTensorFlow用の環境へ切り替え

pyenv globalを使って、作成したTensorFlow環境へ変更

```
$ pyenv global TensorFlow
$ python -V
Python 3.5.2
```
うまくPythonのバージョンが切り替わらない場合は、bash_profileに追記

```
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
```

反映するのを忘れずにね。

```
$ source ~/.bash_profile
```


####元に戻したいと時
```
$ pyenv global system
```
環境の指定は後述するPyCharmで行うので、ここでTensorFlow環境になっている必要はない

###pipのインストール
次にPython向けのプラグイン管理ツールであるpipをインストール

```
$ sudo easy_install pip
$ sudo pip install --upgrade pip
```

###TensorFlowのインストール

TensorFlowのインストール。適宜公式を参考に。
https://www.tensorflow.org/install/

```
$ pip install tensorflow
```

###PyCharmにて指定。
***ここの説明があまり書いていないものが多くハマりました。***
Preferences>Project Interpreter>設定ボタンから、先ほど作ったTensorFlow環境を「Add」すると、
以下のように追加される。追加されたら、New Projectで新規プロジェクト作成時に、環境として選べるようになる。<img width="1009" alt="スクリーンショット 2019-01-27 2.11.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/210201/9fcabdcc-5593-4a18-04fa-57981d66a958.png">
docker-composeでシンプルにvue.js環境構築

#はじめに
今回はdocker-composeでvue.jsの開発環境をシンプルに構築してみます。

#環境
Dockerとdocker-composeは用意できている前提です。

- Docker version 20.10.0
- docker-compose version 1.27.4

#構成
以下の構成を想定しています。
project/web/ 以下にvue.jsのプロジェクトが作成されます。

```
project
├── docker
│   └── web
│       └── Dockerfile
├── docker-compose.yml
└── server
```


#構築
環境構築の手順を解説を簡単に交えながら紹介していきます。

## 1. docker-compose.yml作成

```docker-compose.yml
version: '3.8'

services:
  web:
    container_name: web
    build: ./docker/web
    ports:
      - 8080:8080
    privileged: true
    volumes:
      - ./server:/app:cached
    tty: true
    stdin_open: true
    command: /bin/sh
```

【備考1】
vue.jsはデフォルトでポート8080を使用するようになっているため、それに合わせてます。
必要な場合は以下のように変更することもできます。

```docker-compose.yml
ports:
 - 9000:9000
```

【備考2】
MacのマウントシステムとDockerのマウントシステムの相性がよくないみたいなので、
ボリュームの`:cached`（ホスト上の更新がコンテナ上に反映するまで、遅延が発生するのを許容）オプションをつけています。オプションはつけなくても動作は問題ないですが、webpackのwatchでファイル変更を検知するようにするとPCのファンが回り続けてうるさいです(笑)

## 2. Dockerfileの作成
dockerディレクトリを作成します。

```Dockerfile:Dockerfile
FROM node:14.15.0-alpine

WORKDIR /app

RUN apk update && \
    npm install && \
    npm install -g npm && \
    npm install -g vue-cli
```

## 3. Docker起動&コンテナに入る

```bash
# Docker構築&起動
docker-compose up -d

# コンテナに入る
docker-compose exec web sh
```

## 4. vue.jsプロジェクト作成または更新
新規構築と更新(gitで共有された場合など)でコマンドが変わりますのでご注意ください。

### 新規作成の場合

```bash
/app # vue init webpack
# y/nで質問されますが、こだわりなければ基本yesまたはEnterでOKです。
```

#### 環境設定
hostやポートを変更しましょう。
今回は、hostを'localhost'から'0.0.0.0'に変更します。

```js:server/config/index.js
// Various Dev Server settings
host: '0.0.0.0', // can be overwritten by process.env.HOST
```

#### ファイル変更を検知するように設定
`dev.poll`をfalse => trueに変更

```js:server/config/index.js
poll: true, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
```

### 更新の場合
```bash
/app # npm update
```

### npm実行(共通)
```bash
/app # npm run dev
```

## 5. 確認

http://0.0.0.0:8080 にアクセスしましょう。
下記の画面が表示されればOKです。

<img width="681" alt="スクリーンショット 2019-01-27 2.10.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/290840/7465cb8f-4b3c-50a9-d35f-f7c3e614fa62.png">

参考
- [ローカルを汚さずdockerを使ってvue.jsの開発環境を作る[vuecli4]](https://qiita.com/rh_taro/items/ca08b930f704275286a4)
- [Docker内で Webpack の watch でファイルの変更を検知する](http://hironemu.hatenablog.com/entry/20170909/1504966556)
- [consistent、cached、delegated 設定のチューニング](https://docs.docker.jp/docker-for-mac/osxfs-caching.html#consistentcacheddelegated)
JavaでZabbix API

今回はなるべく自力でZabbixサーバーとやり取りするためのプログラムを作成.
用意するものを少なくするために, httpclientのコーディングは標準ライブラリで何とかする.

#用意するもの
[ここ](https://github.com/alibaba/fastjson)のDownloadのthe latest JARからjarファイルをダウンロード

 HttpClient
--- 
[ここ](https://kazuhira-r.hatenablog.com/entry/20131026/1382796711)を参考にした.
 ZabbixサーバーにJsonRPCの規則に従ってJSONオブジェクトを投げると, jsonrpc, result, idで構成されたJSONオブジェクトが返ってくる.

```java
public class Api {
    public String Post(JSONObject json) {
        try {
            URL url = new URL("http://127.0.0.1/zabbix/api_jsonrpc.php");

            HttpURLConnection connection = null;

            try {
                connection = (HttpURLConnection) url.openConnection();
                connection.setDoOutput(true);
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");

                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(),
                        StandardCharsets.UTF_8));
                writer.write(json.toString()); //ここでJSONデータを投げる
                writer.flush();

                if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    try (InputStreamReader isr = new InputStreamReader(connection.getInputStream(),
                            StandardCharsets.UTF_8);
                         BufferedReader reader = new BufferedReader(isr)) {
                        String line;
                        while ((line = reader.readLine()) != null) {
                                return line; //ここでJSONデータを受け取る
                        }
                    }
                }
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return "";
    }
}
```

JSONオブジェクトの作成
---
クライアントは, jsonrpc, method, params, id, authで構成されるJSONオブジェクトをサーバーに投げる.今回は, バージョンの取得とログインをする.

```java
public class Main {
    public static void main(String[] args) {
        String result;

        Api api = new Api();
        JSONObject json = new JSONObject();
        JSONObject param = new JSONObject();

        json.put("jsonrpc", "2.0");
        json.put("method", "apiinfo.version");
        json.put("params", param);
        json.put("id", 1);
        json.put("auth", null);//バージョンの取得の際は必要ない
        result = api.Post(json);
        System.out.println(result);

        param.put("user", "name");//ユーザー名
        param.put("password", "pass");//パスワード

        json.put("jsonrpc", "2.0");
        json.put("method", "user.login");
        json.put("params", param);
        json.put("id", 1);
        json.put("auth", null);
        result = api.Post(json);
        System.out.println(JSON.parseObject(result).get("result"));
    }
}
```

実行結果 
---
バージョンの取得は生のJSONデータが返ってくるようにした.authはresultから抽出した.

```
{"jsonrpc":"2.0","result":"4.0.3","id":1}
012225192b38d347ddf6098d291f30df
```

次はきれいにまとめます.
fishでvirtualenvを起動する

# virtualenv activeteをfishで
`python3 -m venv myvenv`
`source myvenv/bin/activate`とすると仮想環境が立ち上がり、シェル上にもカレントディレクトリ左に環境名(ここでは`myvenv`)が表示される

fishで実行したが立ち上がっていない感じ

`myvenv/bin/`の中身を確認してみると
`activate.fish`というfish用のファイルがある。
したがって以下で起動できる。
`source myvenv/bin/activate.fish`

# 環境
virtualenv v16
[Virtualenv — virtualenv 16.3.0 documentation](https://virtualenv.pypa.io/en/latest/)
Pythonで株価情報を取得して、MySQLに格納する

## やりたいこと

データ分析用に永続データとして日本の株価情報を取得して、MySQLに格納します。
MySQLの環境は、[MetabaseとMySQL環境をDockerで作る](https://qiita.com/ITNewcomer/items/73173f032af29175dacd)で作成したMySQLに格納します。

## データソース

データソースは[Quandl](https://www.quandl.com/)というサイトを利用します。
有料データもありますが、無料でも使えます。
今回はQuandlで収集されているデータの中から、東京証券取引所が提供しているデータを利用します。

## 環境

* Mac OS X 10.14.2
* Python 3.7.1
* Quandl 3.4.5

## 手順

### アカウント登録

APIキーを取得するために[Quandl](https://www.quandl.com/)のアカウント登録を行います。
登録は無料です。

### APIキーの確認

アカウントを作成したら、右上のメニューから[ACCOUNT SETTINGS]を選択します。
プロフィール画面に遷移すると、[YOUR API KEY]にAPIが記載されているのでメモします。

### データの取得

実際にデータを取得してみます
※必要なライブラリは適宜インストールしてください。

```Python
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-

import datetime
import quandl
import pandas as pd

# 各種設定
## 取得したい日付レンジの指定
start = datetime.datetime(2007, 1, 1)
end = datetime.datetime(2019, 1, 19)

# 取得したい会社のティックシンボルを記載します。
## 例えばの武田薬品工業の場合　TSE/4502 となります。
## https://www.quandl.com/data/TSE/4502-Takeda-Pharmaceutical-Co-Ltd-4502
company_id = 'TSE/4502'

# APIキーの設定
quandl.ApiConfig.api_key = '前の手順で確認したAPIキーをここに記載'

# データ取得
df = quandl.get(company_id ,start_date=start,end_date=end)
```

データが以下のように取得できていることを確認します。

```Python
>>> df.head()
              Open    High     Low   Close     Volume
Date
2007-01-04  8180.0  8210.0  8170.0  8180.0  1401400.0
2007-01-05  8180.0  8180.0  7970.0  8010.0  3020100.0
2007-01-09  8000.0  8010.0  7940.0  7950.0  2696200.0
2007-01-10  7950.0  7960.0  7760.0  7760.0  3807700.0
2007-01-11  7820.0  7890.0  7710.0  7760.0  3286800.0
```

### MySQLにデータを格納する。

取得したデータをMySQLに格納します。
上の続きと思ってください。

```Python
import sqlalchemy as sa

## Indexが日付なので行に取り込んで、データ型を変更する。
df = df.reset_index()
df['Date'] = pd.to_datetime(df['Date'])

## 表名の指定
table_name = 'TAKEDA'

## 接続情報設定
engine = sa.create_engine('mysql+mysqlconnector://stock:stock@127.0.0.1/stock', echo=True)

# MySQLにデータを格納
df.to_sql(table_name, engine , index=False, if_exists='replace')
```

### データの確認

MySQLにアクセスして、データを確認します。

```bash-session
$ mysql --host=127.0.0.1 --user=stock --password

mysql> use stock
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

mysql> show tables;
+-----------------+
| Tables_in_stock |
+-----------------+
| AAPL            |
| TAKEDA          |
+-----------------+

mysql> desc TAKEDA;
+--------+----------+------+-----+---------+-------+
| Field  | Type     | Null | Key | Default | Extra |
+--------+----------+------+-----+---------+-------+
| Date   | datetime | YES  |     | NULL    |       |
| Open   | double   | YES  |     | NULL    |       |
| High   | double   | YES  |     | NULL    |       |
| Low    | double   | YES  |     | NULL    |       |
| Close  | double   | YES  |     | NULL    |       |
| Volume | double   | YES  |     | NULL    |       |
+--------+----------+------+-----+---------+-------+
6 rows in set (0.00 sec)

```
GAEでのhttps化

今更ですがGAEのhttps化について

1. メニューの設定を選択
2. カスタムドメインをチェック
3. 「マネージドセキュリティを有効にする」ボタンを押下
4. 10分ほど待つ

すると、SSLセキュリティの表示が「Googleが管理、自動更新」になります。
<img width="865" alt="ssl.png" src="https://qiita-image-store.s3.amazonaws.com/0/100746/88910b31-9082-4181-dd1c-b256066c19a9.png">

追加料金なしで、google以外で取得した独自ドメインでも可能でした。
iPhoneで撮影した動画をwindowsで再生させる手順で罠にハマった話。

# iPhoneで撮影した動画がwindows10で再生できない
友人がiPhoneで撮影した動画を編集する機会があったので、受け取った動画をwindowのPCに取り込んだところ
windows10に搭載されている「映画＆テレビ」ではでなぜかいくつかの動画が再生できない。。。

この状態だと動画編集ソフトでも動画が再生できないため解決を試みていたところ
罠にハマったので同じ被害者が出るのを防げれば、ということで忘備録として残します。

# 再生しようとしたらこんなアラートが出た

「ビデオを再生するには、コーデックが必要です。」

アラート内にインストールすると解決できるらしい「HEVC　ビデオ拡張機能」というアプリが表示されていた。
![20190126_store.png](https://qiita-image-store.s3.amazonaws.com/0/349451/e3cdd480-ab7d-fc38-da16-bd6e5e0f3da7.png)

# なぜ再生できないのか？
色々原因をさぐっていたら、こんな記事をみつけた。
https://appllio.com/ios-photo-video-formats-heif-hevc-iphone-ipad

どうやら、iOS11以降に動画のエンコード方式が「HEVC」方式というものに変わったことが原因のよう。
だからHEVCを見れるようにするための拡張機能をおすすめされていたのか。。

自分の環境で拡張機能が動作するかチェックができるようなので確認したところ、
「この製品はこのデバイスで動作します」とのことなので購入。

![20190126_system.png](https://qiita-image-store.s3.amazonaws.com/0/349451/cde3fb57-f5b8-b132-832b-733b36b22425.png)

# これが罠だったとは

インストールして解決だ！と意気揚々とインストールボタンをクリック。
すると。。。
![20190126_error.png](https://qiita-image-store.s3.amazonaws.com/0/349451/85652bd7-3817-68aa-1563-145f714f58fa.png)

何度再試行してもインストールできない。

心の中の藤原竜也がどうしてだよと叫びながらこの拡張機能について調べたところ、
なんとintel corei7じゃないと動かないらしい。。
システム必要条件にはそんな記載なかったのだが、被害が120円で良かった。。

# 解決方法
なんとこの拡張機能、無料版が出ているらしい。
「デバイス製造元からの HEVC ビデオ拡張機能」というもの。
![20190126_device.png](https://qiita-image-store.s3.amazonaws.com/0/349451/687f513f-d2e5-850f-23aa-cc9670903642.png)

これをインストールしたところ、無事に動画が再生できるようになった。
解決法にたどりつくまで2～3時間ほどかかってしまい動画編集の気力が消えてしまった。
長かった。。

# 補足
「デバイス製造元からの・・・」をMicrosoft Storeで検索しても出てこないがググるとでてきた。
どうやらwebからじゃないとたどりつけないらしいので注意。
![20190126_search.png](https://qiita-image-store.s3.amazonaws.com/0/349451/efc8bf63-e47d-35c5-3273-24c7da85942d.png)
STM32F103 + Arduino 開発環境で SPI A/Dコンバータ MCP3008 をつなぐ

SPI の基準環境を作る必要があったので、使い慣れた MCP3008 で作ってみました。


# 環境

- RobotDyn STM32 MINI (Blue Pill 互換)
- Microchip MCP3008
- Arduino 1.85 ＋ STM32Duino 
 
# 接続

|信号|MCP3008|STM32F103|
|:---:|:---:|:---:|
|CS|10PIN /CS|PA4|
|SCK|13PIN CLK|PA5|
|MISO|12PIN DOUT|PA6|
|MOSI|11PIN DIN|PA7|

![IMG_20190127_002451.jpg](https://qiita-image-store.s3.amazonaws.com/0/139524/7a0a62d5-7a74-2b14-1306-7e11f4a24bd5.jpeg)
![IMG_20190127_002207.jpg](https://qiita-image-store.s3.amazonaws.com/0/139524/772193b1-b295-604f-d8d8-a508be6aeabe.jpeg)

テストなので適当な抵抗で分圧すればいいのですが、面白くないのでタッチセンサを作ってみました。
CH0 2.2MΩでプルダウンをし、更に虫ピンを接続して空中に立てています(ブレッドボード上の11b)。
虫ピンに触ると人体のノイズを取得するということになります。

# スケッチ

ハードウェアSPIをつなぎます。
シリアルモニタで値を見ます。
PA9,PA10に繋いだUSBシリアルに出力しています。


```

#include <SPI.h>
#define SPI_CS_PIN PA4
int counter=0;
byte data;
  
void setup() {
  Serial1.begin(9600);
  SPI.begin(); 
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV16);
  pinMode(SPI_CS_PIN, OUTPUT);
}

void loop() {
  digitalWrite(SPI_CS_PIN, LOW);
  SPI.transfer(0b00000001); 
  byte data1 = SPI.transfer(0x80);  // ch 0
  byte data2 = SPI.transfer(0x00);
  digitalWrite(SPI_CS_PIN, HIGH);
  unsigned int CH0 = ((data1 & 0x03) << 8) + data2;

  Serial1.println(CH0);

  delay(1000);
}

```

# 実行結果
![image.png](https://qiita-image-store.s3.amazonaws.com/0/139524/34f3534b-feb4-664d-7e62-360b9beb0671.png)

虫ピンに触ったのがうまく検出できました。乾燥している冬だったのでうまくいったのかも知れません。湿度の高い夏などでもうまく行くかどうかは？



# おまけ

nRF52840につなぐ場合は、標準では以下のようになります。


|SPIデバイス側|信号名|Define定義|MDBT50Q DB(nRF52840)側|
|:---:|:---:|:---:|:---:|
|CLK|SDC_SDK_PIN|ARDUINO_13_PIN|P1.15|
|DI|SDC_MOSI_PIN|ARDUINO_11_PIN|P1.13|
|DO|SDC_MISO_PIN|ARDUINO_12_PIN|P1.14|
|CS|SDC_CS_PIN|ARDUINO_10_PIN|P1.12|
|VCC|||適当なVCC|
|GND|||GND|
PHPのスカラー型


こんばんは。

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている者です。

今回、私がPHPを学ぶ中で、注意しておいた方が良いと思ったことについて紹介します。

##PHPでの注意点
PHPで注意しないといけないことがスカラー型についてです。スカラー型とはプログラミング言語におけるデータ型の一つであり、PHPにおけるスカラー型には論理値(boolean)、整数(integer)、浮動小数点数 (float, double)、文字列 (string)の4種類があります。C言語の場合、スカラー型は変数を宣言する時点で型を決めますが、PHPでは変数の文脈に応じて型が決まります。下記ではC言語とPHPの場合の例を紹介します。

```practice.c
int x;
x=9/2;  //a=4になる
```

```practice1.php
$x = 9/2;  //x=4.5になる
```

この時、注意しないといけないことがあります。それはPHPで割り算を行う場合、整数値を求めても勝手に浮動小数点
数になってしまうことです。PHPで割り算をして整数値を求める場合、`intval()`を使用します。これは指定した変数を整数型に変換して値を取得する関数です。

```practice2.php
$x = intval(9/2);  //x=4になる
```

このことを理解しておかないと、エラーにつながります。
実際、プログラミング初心者の私はこの部分でエラーが起こり、何時間も苦しみました。

##まとめ
プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

####参考資料
http://php.net/manual/ja/language.types.php
AWS Lambda Goで画像アップローダを作る

AWS Serverless Uploader
デモ https://aws-serverless-uploader.netlify.com/
フロントエンドソース https://github.com/dyoshikawa/aws-serverless-uploader-frontend
バックエンドソース https://github.com/dyoshikawa/aws-serverless-uploader-go

# フロントエンド

- React
- Netlify

ReactプロジェクトをNetlifyにデプロイ。
CSSフレームワークはBulma。
API通信はAxiosを使用。

# バックエンド

- AWS Lambda Go
- API Gateway
- S3
- DynamoDB
- SAM CLI

Serverless frameworkかSAM CLIかは好きな方で良さそう。
自分的にはAWS謹製という点に惹かれてSAM CLIを選定。

```
sam init --runtime go
```

でプロジェクトの雛形をバッと作ってくれてすぐにデプロイできるのと、AWS上の構成をコード管理できる（=infrastructure as code）ので重宝した。

## GoでS3

aws-sdk-goを使用。

```Go
package main

import (
	"bytes"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
)

func s3Put(img []byte) error {
	svc := s3.New(session.New(), &aws.Config{
		Region: aws.String("ap-northeast-1"),
	})
	if _, err := svc.PutObject(&s3.PutObjectInput{
		Bucket:               aws.String("バケット名"),
		ACL:                  aws.String("private"),
		ServerSideEncryption: aws.String("AES256"),
		Key:                  aws.String("キー名"),
		Body:                 bytes.NewReader(img),
	}); err != nil {
		return err
	}
	return nil
}
```

## GoでDynamoDB

素のaws-sdk-goだけの実装はダルいようなので[gregu/dynamo](https://github.com/guregu/dynamo)ライブラリを使用。

```go
package main

import (
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/guregu/dynamo"
)

type Image struct {
	Name      string `json:"name" dynamo:"Name"`
	URL       string `json:"url" dynamo:"Url"`
	CreatedAt string `json:"createdAt" dynamo:"CreatedAt"`
}

// 書き込み
func dynamoPut(data Image) error {
	db := dynamo.New(session.New(), &aws.Config{Region: aws.String("ap-northeast-1")})
	if err := db.Table("テーブル名").Put(data).Run(); err != nil {
		return err
	}
	return nil
}

// 全件取得
func dynamoGetAll(data *[]Image) error {
	db := dynamo.New(session.New(), &aws.Config{Region: aws.String("ap-northeast-1")})
	if err := db.Table("テーブル名").Scan().All(data); err != nil {
		return err
	}
	return nil
}
```

次はAPIGateway+Lambda(Go)+Cognitoで認証処理を検証する予定。
Windows 10 Pro x64 + Excel2016 x86 VBA + DTPicker を試してみる

#目的
Excel 2016 VBA でカレンダーコントロールを使用するときに
Microsoft Date and Time picker control 6.0 (SP6)　を使う
という例があるけれど、試そうと思っても見つからないのはなぜ？
と思ったんだけど、そういう事か！？　と思ったのでメモ
##VB6SP6 Runtime のインストール
[Visual Basic 6.0 Service Pack 6 Runtime Set](https://www.vector.co.jp/soft/winnt/util/se152941.html)
よりDLした v6s6r135.zip v6s6r135.zip を適当なフォルダに解凍後、setup.exe を実行してデフォルトのままインストールする。
※ C:\Windows\System32 にインストールされる
※Excelが64Bit版の時は、どうなるのかな？？
##ocxを参照設定に追加する
VBAの画面より
・ツール
　　->参照設定
　　　->参照ボタンをクリック
　　　　->C:\Windows\System32\mscomct2.ocx を選択後OKをクリック
##サンプルコード作成手順
・ユーザーフォームで フォームを追加する
・ツールボックスを表示
　　->ツールボックス上で右クリックして その他コントロール を選択する
　　　->表示/選択された項目のみ のチェックを外す
　　　　->Microsoft Date and Time picker control 6.0 (SP6) をチェック後OKをクリックする
・ツールボックスより DTPicker を選択して　フォームにドロップする
※最低限のサンプルになるのかな？
※まぁ色々な状況で使ってみないとな

```vb

'
'   DTPicker、TextBox、CommandButtonを適当に UserForm に配置した状態
'
Option Explicit

Private Sub UserForm_Initialize()
    '
    '   必要に応じてデフォルト表示を行う
    '   ・入力画面の初期設定とか
    '   ・DBから取込んだ日付とか
    '   ・あくまで例なので仕様に応じた箇所で
    '
    TextBox1.Text = "2019/01/27"
End Sub

Private Sub CommandButton1_Click()
    '
    '   TextBoxの日付をDTPickerに設定できるかの確認
    '
    DTPicker1.Value = CDate(Trim(TextBox1.Text))
    
End Sub

Private Sub DTPicker1_CloseUp()
    '
    '   ドロップダウン後、指定した日付が
    '   TextBoxに出力できるかを確認
    '
    TextBox1.Text = Format(DTPicker1.Value, "yyyy/mm/dd")
End Sub
```
##参考にしたのは以下のサイト
[Excel VBAでDatepicker（日付選択）コントロールを使う方法](https://surleconomiejp.blogspot.jp/2015/11/excel-vbadatepicker.html)
[VBA Datepickerを使うための参照設定の方法](https://surleconomiejp.blogspot.jp/2017/07/vba-datepicker.html)
[VB6(Visual Basic 6.0)ランタイムのインストール方法](http://nonsoft.la.coocan.jp/Chinamini/20100001/20100717.html)
ネットワーク設定の永続化

# きっかけ
GCPにはInternal DNSやCloud DNSといったDNSがあるのですが、それらを使わずvm上にBIND9を立ち上げて、それをDNSとして使おうとしたときにハマりました。どうやっても、DNSが上書きされてモヤモヤしたので、落ち着いて調べてみることにしました。

普通に`/etc/resolv.conf`を編集しても、再起動すると上書きされてしまいます。原因としては、

- DHCP client
- resolvconf
- NetworkManager

が考えられます。それぞれの原因に対する対策をまとめてみました。

ここでは、上書きを禁止するのではなく、思い通りの値で上書きさせることで問題を回避する方法も解決法として紹介します。

# 環境

GCP(Google Cloud Platform)上のDebian GNU/LINUX 9 (stretch)です。

# DHCP client (ifupdown)が上書きしているとき

DHCP clientの設定を変更します。設定ファイルは、/etc/dhcp/dhcpclient.confです。
そこに、以下の内容を追加します。

```:/etc/dhcp/dhcpclient.config
prepend domain-name-servers <dns1> <dns2>
supersede domain-name "<domain>";
```
この設定は/etc/resolv.confファイルでは、

```:/etc/resolv.conf
domain <domain>
nameserver <dns1>
nameserver <dns2>
nameserver <dhcp dns>
```

として反映されます。DHCPサーバーから得られるDNSサーバー情報は、上書きせずに残しておきます。
そうすることで、ローカルDNSが落ちても、一般ドメインの名前解決ができます。

もしくは、DHCPを使わないよう、`/etc/network/interfaces`ファイルを編集します。

```:/etc/network/interfaces
#iface eth0 inet dhcp #コメントアウト
iface eth0 inet static
address <ip addr>
dns-name-servers <dns1> <dns2>
```

# resolvconfが上書きしているとき

https://unix.stackexchange.com/questions/174349/what-overwrites-etc-resolv-conf-on-every-boot などを参考にしてください。記事が書けるほど僕は詳しくない(というか、使ったことがない)ので、ここでは省略します。

# NetworkManagerが上書きしているとき

DNSの設定にDHCPを使わないよう設定した上で、DNSを登録します。

```shell
nmcli c down eth0
nmcli c m eth0 ignore-auto-dns yes
nmcli c m eth0 +ipv4.dns <dns1> +ipv4.dns <dns2>
nmcli c up eth0
```

もしくは、NetworkManagerを無効にします。

```shell
service network-manager stop
update-rc.d network-manager disable
```
# どのサービスが上書きしているかを調べる方法

とはいっても、愚直な方法です。

以下のように、各サービスの起動状況によって状態に名前をつけます。

|resolvconf|NetworkManager|state|
|:-:|:-:|:--|
|o|o|A|
|o|x|B|
|x|o|C|
|x|x|D|

このとき、各状態とその時に上書きが起こるかを調べることで、どのサービスが悪さをしているかわかります。Dの状態の時に書き換わるなら、それはDHCP clientが書き換えているということです。ただし、複数のサービスが書き換えを行っていることも考慮してください。

# 僕の場合

僕はDHCP clientが曲者でした。Googleのサイトに説明があります。

>Compute Engine instances are configured to renew DHCP leases every 24 hours.
(https://cloud.google.com/compute/docs/internal-dnsより引用)

また、GCPでは`/etc/hosts`ファイルも上書きされるので、FQDNの設定が通常のやり方ではできませんでした。

FQDNを設定するには、`/etc/dhcp/dhcpclient.conf`に

```:/etc/dhcp/dhcpclient.conf
supersede host-name "<fqdn>";
```

を追加する必要がありました。この結果を用いて、`/etc/dhcp/dhclient-exit-hooks.d/google_set_hostname`スクリプトで`/etc/hosts`を上書きしていました。

ここで設定したhost-nameは、`hostname --fqdn`の結果に影響します。これは、SSHでKerberos認証を行うときなどに使われる値なので、重要な人もいると思います。

# 余談
ifupdownは昔からある仕組みらしいです。Debian系では`/etc/network/interfaces`、CentOS系では`/etc/sysconfig/network-script/ifcfg-ethx`が設定ファイルです。NetworkManagerはifupdownと競合する部分については、ifupdownの設定を尊重するみたいです。ifupdown でお世話をしているインターフェースを`nmcli d show`でみると、Unmanagedとなります。

NetworkManagerを無効化する記事はたくさんあるのですが、ifupdownを無効化する記事はあまり見ません。NetworkManagerも結構便利でいいんですが。。

# 感想

ネットワークはJUST WORKで良いのですが、それがなかなか難しい。。。
Vagrantで開発環境を構築（1.仮想マシン作成編）

## 目的

- 勉強の一貫で記事をまとめる．
- VagrantとVirtualBoxで仮想環境を作成できるようになる．

前回：[Vagrantで開発環境を構築（0.事前準備編）](https://qiita.com/koukibuu3/items/1f5867b8f7939d2bbfb2)
今回：Vagrantで開発環境を構築（1.仮想マシン作成編）
次回：[Vagrantで開発環境を構築（2.仮想環境設定編）](https://qiita.com/koukibuu3/items/8056d23219784587a90f)

## boxの追加

[Vagrant](https://www.vagrantup.com)では，構築する仮想マシンのOSのイメージファイル等をまとめたboxを用いる．

**1. ターミナルで下記のコマンドを実行．**

```Bash:ターミナル
$ vagrant box add <box名> https://github.com/CommanderK5/packer-centos-template/releases/download/0.7.2/vagrant-centos-7.2.box # CentOS7.2のboxをインストールして追加

$ vagrant box list # 確認
```

## 定義ファイルの作成

先ほど追加したboxを用いて仮想マシンの定義ファイルを作成．

**1. プロジェクトディレクトリに移動して，下記コマンドを実行．**

```Bash:ターミナル
$ vagrant init <box名(任意)>　# Vagrantfileを作成

$ ls # 確認
```

参考：[Vagrantの使い方](https://qiita.com/skinoshita/items/57ac059ff8b1008f5e1d)

**2. Vagrantfileを編集．**

先ほどのコマンドを実行すると，プロジェクトディレクトリに仮想マシンの定義ファイルであるVagrantfileが作成されている．
今回はこのVagrantfile に対して最低限の下記の編集を行う．
（細かい設定はよく分からないので要勉強．）

```Bash:Vagrantfile
# config.vm.network "private_network", ip: "192.168.33.10"
  ↓
config.vm.network "private_network", ip: "192.168.33.10" # 35行目辺り

# config.vm.network "forwarded_port", guest: 80, host: 8080
  ↓
config.vm.network "forwarded_port", guest: 80, host: 8080 # 26行目辺り

# config.vm.synced_folder "../data", "/vagrant_data"
  ↓
config.vm.synced_folder "./", "/var/www" # 46行目辺り
```

参考：[VagrantコマンドとVagrantfileの設定メモ](https://qiita.com/pugiemonn/items/bcd95a35c3ec7624cd61)

**3. 仮想マシンの起動**

ターミナルで下記のコマンドを実行．

```Bash:ターミナル
$ vagrant up # 仮想マシンを起動

$ vagrant status # 確認
```

（仮想マシンを終了させるには，`$ vagrant halt` を実行．）

**4. Vagrantプラグインのインストール**

`$ vagrant up` で仮想マシンを起動するときに下記のエラーメッセージが出て，共有フォルダのマウントに失敗することがある．

```Bash:エラーメッセージ
Failed to mount folders in Linux guest. This is usually because
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:

mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3`,dmode=777,fmode=666 vagrant /vagrant
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant`,dmode=777,fmode=666 vagrant /vagrant

The error output from the last command was:

/sbin/mount.vboxsf: mounting failed with the error: No such device
```

これは，VirtualBoxのアップデート後に起きる可能性があり，フォルダ共有機能を提供している**Guest Additions**をvagrant up時に自動的に更新してくれるプラグイン`vagrant-vbguest`をインストールしておくことで解決できる．
なので，エラーが起きなくてもインストールしておくのがオススメ．

ターミナルで下記のコマンドを実行．

```Bash:ターミナル
$ vagrant plugin install vagrant-vbguest
```

再び`$ vagrant up` することで更新がされる．

参考：[Vagrantで共有フォルダのマウントに失敗するときの対処方法](https://qiita.com/ozawan/items/9751dcfd9bd4c470cd82)

## 仮想マシンにssh接続する

とうとう仮想マシンに接続する．

**1. ターミナルで下記のコマンドを実行．**

```Bash:ターミナル
$ vagrant ssh # 仮想マシンにssh接続する

# 192.168.33.10 ssh でもOK
```

## まとめ

以上で仮想マシンの作成が完了．
次回から実際に仮想マシンの環境を整えていく．

前回：[Vagrantで開発環境を構築（0.事前準備編）](https://qiita.com/koukibuu3/items/1f5867b8f7939d2bbfb2)
今回：Vagrantで開発環境を構築（1.仮想マシン作成編）
次回：[Vagrantで開発環境を構築（2.仮想環境設定編）](https://qiita.com/koukibuu3/items/8056d23219784587a90f)
FFmpegを使用したHLS形式への動画変換の仕方

# はじめに
HLS形式を使用すると動画配信を簡単に行えるようなので、配信用動画の作成方法をまとめてみる。

# やること
Lubuntu16.04にFFmpegをインストールし、動画ファイルをtsファイルとm3u8ファイルに変換する。

# FFmpegのインストール
まず、以下のコマンドを実行し、リポジトリの追加とFFmpegのインストールを行う。

```
$ sudo add-apt-repository ppa:jonathonf/ffmpeg-3
$ sudo apt update
$ sudo apt install ffmpeg libav-tools x264 x265
$ ffmpeg -version
```
# 動画の変換
以下のコマンドを実行し、動画を変換する。

```
$ ffmpeg -i ファイル名 -codec copy -map 0 -f segment -vbsf h264_mp4toannexb -segment_format mpegts -segment_time チャンク秒数 -segment_list プレイリスト名.m3u8 チャンクファイル名-%03d.ts
```
「ファイル名」、「チャンク秒数」、「プレイリスト名」、「チャンクファイル名」には、それぞれ環境にあったものを入力する。
MariaDBのインストールでERROR 1045 (28000)

先日、MariaDBをインストールしたとき、エラーとなってしまう事がありました。
エラーの内容は下の通り。

> ERROR 1045 (28000): Access denied for user ‘root’@‘localhost’ (using password: NO)

このあとは、なぜかmariadb-client辺りの依存関係が壊れたみたいで、apt remove —purgeでアンインストールもできなくなってしまいました。
という事があり、復旧方法です。

## 依存関係を直す

とりあえず、依存関係を直すために、dpkgコマンド。

```
$ sudo dpkg --configure -a
```

そして、MariaDBを再インストール

```
$ sudo apt remove —purge  -y mariadb-server
$ sudo apt install -y mariadb-server
```

ERROR 1045が出ても無視してインストールを進めます。
インストールが終わったら、セーフモードでMariaDBを起動させます。

```
$ sudo service mysql stop
$ sudo mysqld_safe --skip-grant-tables
```

他のターミナルに切り替えて、rootのパスワードを設定します。

```
$ mysql -u root -p

MariaDB> update mysql.user set password=password(‘rootのパスワード') where user = 'root';
MariaDB>exit;
```

MariaDBを通常モードで起動すれば完了です。
セーフモードで動いているターミナルでCtrl+C。その後startさせる。

```
$ sudo service mysqld start
```
Postgre SQL　なんと外部キーでJOINできない状況に遭遇！！


中規模な学習塾でデータ分析などをしています。塾で授業を受けている科目のテスト結果を抽出したい。ということが多々あります。
しかし、なんと、塾で授業を受けている科目のテスト結果を抽出する際に、外部キーでJOINできないという不思議な現象に出会いました。


# テーブル
テーブルの中身はこんな感じになっています。
**科目マスタ**

|　科目ID|科目名|  
|:-----------------|------------------:|
|1|英語| 
|2|算数| 
|3|国語|
|...||   
|10|英語|  
|11|数学| 
|12|国語| 



**授業テーブル**

|授業ID| 生徒ID |生徒区分| 講師ID  |科目ID|...|
|:-----------------|------------------:|:------------------:|:------------------:|:------------------:|:------------------:|
| 1|            123 |中学生|987       |1|
| 2|            456|中学生|654       |1|
| 3|            789 |中学生|321       |1|
| 4|            135 |中学生|975       |2|
| 5|            791 |中学生|864       |2|
| 6|            246 |中学生|310       |2|



**テスト結果テーブル**

|テスト結果ID| 生徒ID |科目ID|点数|...|
|:-----------------|------------------:|:------------------:|:------------------:|:------------------:|
| 1|            123 |10|50|
| 2|            456 |10|60|
| 3|            789 |10|60|
| 4|            123 |11|70|
| 5|            123 |12|80|
| 6|            456 |12|30|


生徒が、何の授業を取っていて担当講師が誰なのかは「授業テーブル」にしかありません。
もちろんテスト結果は「テスト結果テーブル」にあります。
「テスト結果テーブル」と「授業テーブル」をJOINすれば、塾で授業を受けている科目のテスト結果を抽出できます。
# 問題発生
生徒IDと科目IDをKEYにしてJOINするんですが、「授業テーブル」の科目IDはつねに1桁のID、「テスト結果テーブル」の科目IDは常に2桁のIDになってます。
なぜかはわかりませんが、「授業テーブル」では中学生でも高校生でも小学生の科目IDが入るようになっています。「テスト結果テーブル」では中学生は中学生用の科目IDがふられています。
なぜこんな仕様になっているのか、作った人に小一時間問い詰めたい。(笑)
理由が分かる方は、ぜひ教えてください。
# 解決編
中学生は「国・数・理・社・英・音・体・美・技家」の9科目あります。どうも、「授業テーブル」の科目IDに+9をすると「テスト結果テーブル」の科目IDになるようです。
ということで、こんなSQLを書いてみました。

```sql:subject.sql
SELECT * FROM 授業テーブル 
INNER JOIN テスト結果テーブル 
    ON 授業テーブル.生徒ID = テスト結果テーブル.生徒ID　
    AND　授業テーブル.科目ID+9 = テスト結果テーブル.科目ID
```

これで、無事にテーブルをJOINできました。ON句の中で演算できるとは。
いやいや、きちんとシステム設計できていればこんな危ない解決策を取らなくてもいいのだけれど。
というか、普通はもっときちんとしたシステムだよね？

「もっと良い解決策あるよ。」という方、「間違いあるよ。」と指摘してくださる親切な方、ぜひコメントください。
よろしくお願いいたします。
ARCore SceneformのKotlinサンプルコード「ARCore Kotlin Sampler」作りました

ARCore Sceneformを使った実装をKotlinでやっているサンプルが無かったので作ってみました。([GoogleのSceneformのサンプル](https://github.com/googlesamples/sceneform-samples)はJavaではあるのですが、Kotlinでは無かったです。)

ということで作ったのが「[**ARCore-Kotlin-Sampler**](https://github.com/kboy-silvergym/ARCore-Kotlin-Sampler)」

# ARCore-Kotlin-Sampler

https://github.com/kboy-silvergym/ARCore-Kotlin-Sampler

- Sceneformの基本のサンプル
- Augumented Imagesのサンプル
- Could Anchorsのサンプル

があります。

## Sceneform

Google Polyのオブジェクトを空間に表示するだけのサンプルです。Sceneformでは、最初から拡大縮小の機能や平面認識の表示などがついてるのでARKitに比べてサクッと本格的なARが実装できます。

|chair|lamp|couch|
|:-:|:-:|:-:|
|<img src="https://github.com/kboy-silvergym/ARCore-Kotlin-Sampler/raw/master/gifs/chair.gif" width=200>|<img src="https://github.com/kboy-silvergym/ARCore-Kotlin-Sampler/raw/master/gifs/lamp.gif" width=200>|<img src="https://github.com/kboy-silvergym/ARCore-Kotlin-Sampler/raw/master/gifs/couch.gif" width=200>|

## Augumented Images

飛行機の画像マーカーを見せたら飛行機のオブジェクトを表示するサンプル。これもPolyの素材です。ARKitの画像マーカーと同じくらいの実力です。

<img src="https://github.com/kboy-silvergym/ARCore-Kotlin-Sampler/raw/master/gifs/airplane.gif" width=200>

## Could Anchors

Cloud AnchorsはiOSでもAndroidも同じように使えます。AndroidはFirebaseの導入がAndroid Studioから簡単に出来るので良いですね。

|Host|Resolve|
|:-:|:-:|
|<img src="https://github.com/kboy-silvergym/ARCore-Kotlin-Sampler/raw/master/gifs/host.gif" width=200>|<img src="https://github.com/kboy-silvergym/ARCore-Kotlin-Sampler/raw/master/gifs/resolve.gif" width=200>|

# まとめ

ということで、

[ARCore-Kotlin-Sampler | Github](https://github.com/kboy-silvergym/ARCore-Kotlin-Sampler)

良ければスターください！
誰かの参考になれば幸いです。

# 参考にした教材

https://developers.google.com/ar/develop/?hl=ja
https://www.udemy.com/arcore-and-sceneform-for-android-ar
TDDの難しさ

人に伝えようとするとなかなか理解してもらえず、こんなのうまく行くはずがない、普通に開発した方が速い、といったご意見をいただきやすいのがTDD。

すごくいいやり方なのにも関わらずなんでこんなことが発生してしまうのか？
今までを振り返ると2つの理由があると思う。

1つ目は、そもそも仕様をコードに変換することに慣れていないという点。
一般的な請負開発では、上流とか下流とかいう言葉でソフトウェアの仕様と実装が分断され開発が行われる。これにより２つを行き来きするという活動が存在しないのだ。TDDはまさに仕様をテストコードとして最初に定義して進める開発手法だが、まずロジカルに仕様を捉えられないと、最初の時点で手が止まる。要は作りたいもののインプットとアウトプットを定義するだけなのだが、それに慣れてないのだ。ただそれは慣れの問題で、ある程度開発してきた人なら徐々に出来てくると実感としてある。

2つ目がなかなか厄介で、TDDで開発スピードが上がらない人が陥ってるところ。コーディングという作業のミスのしやすさ、そして覚えにくさを甘くみている点だ。
面白いことに初心者ほど甘くみている傾向がある。実際のTDDを行う際にどういうことをやりがちなのかというと、テストコードとプロダクトコードの行き来が少ない、もしくは行き来するまでが長いのだ。その結果、どこでミスしたかわからなくなるということが発生する。短い期間で行き来すればどこから失敗したかすぐわかるのに、そのタイミングを逃したために修正にとんでもない時間を使うのだ。
早く終わらせたいと思うが故に舐めてかかってしまうのだ。ここに関しては間違いなく「急がば回れ」だ。
この問題はテスト実行のやりやすさ、スピードも関係するかもしれない。
1+1は2であるという確証はあるかもしれないが1/2になると得意な言語以外はやってみないと、調べてみないとわからない人がほとんどではないだろうか？ならテストを書く必要があるのだ（流石に後から消すレベルのテストだけど）。
TDDを世に送り出したケントベック先生もハッカソンの時でさえなるべくTDDでやるのだとか。そんな人が急ぐ時でもやってるのに素人から少し毛が生えた程度の我々がどうしてテストも無しに開発が行えるのだろうか？

最後はなんか違う話な気がするが、この2点は今までの経験が邪魔をして自分は違う、自分はやれてると思いがちな部分だと思う。もちろん自分も含めてです。やれてない時多々あります！