OmniAICreator/Qiita-1.07M huggingface dataset:
[C#]Singletonパターン実装方法（備忘録） 


デザインパターンについて勉強している時に、Singletonパターンに出会ったので、実装してみました。

## Singletonパターンの定義
> Singleton パターンとは、そのクラスのインスタンスが1つしか生成されないことを保証するデザインパターンのことである。
引用先 [Wikipedia:Singletonパターン](https://ja.wikipedia.org/wiki/Singleton_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3)


## 実装コード
 基本的なクラスのインスタンス生成はコンストラクタで行われますが、Singletonパターンでは、コンストラクタのアクセス修飾子をprivateにしているため、他のクラスでのインスタンス化ができません。そのため、他のクラスでSingletonパターンクラスのインスタンスを得るためには、GetInstanceメソッドというインスタンスを返すstaticメソッドを使用します。Singletonパターンクラスのインスタンス自体は静的に持ち、GetInstanceメソッドが最初に呼ばれたときに生成し、二度目以降は最初に生成したインスタンスを返すようにすることで、インスタンスが1つしか生成されないことを実現しています。

```csharp:TestSingleton.cs
public sealed class TestSingleton
{
    //静的なインスタンスとして持つ
    private static TestSingleton _instance;
    private static readonly object _lockObject = new object();

    //コンストラクタはprivate
    private TestSingleton(){}

    //インスタンス取得のためのstaticメソッド
    public static TestSingleton GetInstance()
    {
        lock(_lockObject)
        {
            if ( _instance == null)
            {
                //インスタンス生成
                 _instance = new TestSingleton();
            }
            return  _instance;
        }
    }
}
```

## 注意点
+ 静的にインスタンスを保持する。
+ スレッドセーフな実装をしなくてはいけない。

一つ目の理由としては、インスタンスを静的(static)にしているため、適切なインスタンス破棄処理を書かない限り、プログラムが終了するまでインスタンスが残り続けてしまいます。そのため、便利だといって、色々なクラスで乱用してはいけないと思いました。

二つ目の理由としては、マルチスレッドでの注意点になりますが、別スレッドで同時にインスタンス取得メソッド（上記の実装ではGetInstanceメソッド）を呼び出した場合、インスタンスが複数生成されてしまう可能性があります。それを防ぐため、今回はSingletonパターンの実装に[lockステートメント](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/lock-statement)を使用して、スレッドセーフな実装にしましたが、ベストな実装というわけではありません。
Singletonパターンの実装には、他にも[volatile](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/volatile)キーワードを使用したり、[Lazy&lt;T&gt; クラス](https://msdn.microsoft.com/ja-jp/library/dd642331(v=vs.110).aspx)を使用した実装やインスタンス生成をstatic変数宣言時に行なうなど多くの実装方法があり、どの方法を使用するか考える必要があります。
※シングルスレッドで動作させる場合には、これらの実装はなくても問題ないと思います。

## その他
デザインパターンを勉強し始めたばかりなので、間違っている部分等があれば、コメントで指摘していただけるとありがたいです。


## 参考
+ [Wikipedia: Singletonパターン](https://ja.wikipedia.org/wiki/Singleton_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3)
+ [C# in Depth: Implementing the Singleton Pattern](http://csharpindepth.com/Articles/General/Singleton.aspx)
+ [TECHSCORE: Singleton パターン](http://www.techscore.com/tech/DesignPattern/Singleton.html/#dp5-1)
+ [Microsoft: lockステートメント (C# リファレンス)](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/lock-statement)
+ [Microsoft: volatile (C# リファレンス)](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/volatile)
+ [MSDN: スレッドセーフ コンポーネント](https://msdn.microsoft.com/ja-jp/library/a8544e2s(v=vs.120).aspx)
+ [MSDN: Lazy&lt;T&gt; クラス](https://msdn.microsoft.com/ja-jp/library/dd642331(v=vs.110).aspx)
Ruby: 配列からすべての要素を番号つきで取り出す (3パターン)

配列オブジェクトpostsのすべての要素を番号つきで取り出したいときの、3パターンの書き方です。

##1. eachメソッド

・シンプルな書き方

```.rb
posts = ["こんにちは", "たのしい", "さようなら"]

number = 0
posts.each do |text|
  puts "#{number}番目の投稿：#{text}"
  number += 1
end

#結果
0番目の投稿：こんにちは
1番目の投稿：たのしい
2番目の投稿：さようなら

#番号を1からスタートさせたい場合は、

number = 1
posts.each do |text|
  puts "#{number}番目の投稿：#{text}"
  number += 1
end

#結果
1番目の投稿：こんにちは
2番目の投稿：たのしい
3番目の投稿：さようなら
```

##2. each_with_indexメソッド

・eachメソッドよりソースコードが少なくて済む
・番号は0から開始する

``````.rb
posts = ["こんにちは", "たのしい", "さようなら"]

posts.each_with_index do |text, i|
  puts "#{i}番目の投稿：#{text}"
end

#結果
0番目の投稿：こんにちは
1番目の投稿：たのしい
2番目の投稿：さようなら

#番号を1からスタートさせたい場合は、

posts.each_with_index do |text, i|
  puts "#{i+1}番目の投稿：#{text}"
end

#結果
1番目の投稿：こんにちは
2番目の投稿：たのしい
3番目の投稿：さようなら
```

##3. each.with_indexメソッド

・開始したい番号を簡単に指定できる

``````.rb
posts = ["こんにちは", "たのしい", "さようなら"]

posts.each.with_index(5) do |text, i|
  puts "#{i}番目の投稿：#{text}"
end

#結果
5番目の投稿：こんにちは
6番目の投稿：たのしい
7番目の投稿：さようなら
```
Python3 Webスクレイピング 自分用忘備録

# Python3でWebスクレイピング

ちょっと触ってるとエラーの連続で何もさせてもらえなかったので、解決法などを載せ、自分用の忘備録とすることにしよう。
まず、なぜエラーが出たのか。
これは、SSL証明書の問題であるので、sslをimportする必要がある。
申し訳ないが、その先のWebサイトのURLを忘れてしまった。
import ssl
ssl._create_default_https_context = ssl._create_unverified_contextの部分はその神様からの引用です。

コードの解説
import系は上からhttpリクエストを送るために使用,成形するために使用,sslを書かないとエラーになったので使用

変数urlには任意のurlを指定。
変数htmlに、requestなどを書き、htmlを丸ごと入れる
soupにhtmlを入れる
成形作業をする

って感じ。

```python

import urllib.request
from bs4 import BeautifulSoup

import ssl

ssl._create_default_https_context = ssl._create_unverified_context

url = input()

html = urllib.request.urlopen(url).read()

soup = BeautifulSoup(html, 'html.parser')

tables = soup.findAll('#', class_='multicol')


print(soup.title)

```

# BeautifulSoup4のコマンドのリンク先

BeautifulSoup4のコマンドで重宝させて頂きました。感謝感謝です。

http://python-remrin.hatenadiary.jp/entry/2017/05/01/152455


#追記

SSLとか使わずにこんな感じでもできたから追記しておく。

```python

# ↓のようにモジュールを読み込む

from urllib.request import urlopen
from bs4 import BeautifulSoup

# html = urlopen("") ←のようにして内容を開く.参考例↓
html = urlopen("Http://www.pythonscraping.com/pages/page1.html")

# soupに内容を取得
# soup = BeautifulSoup(#↑で指定した変数名(htmlなど),"lxml")
soup = BeautifulSoup(html,"lxml")

# 表示
 print(soup)

 # タグの取得("a")の場合
 soup.find_all("a")

 # タグの取得(先頭の一つだけ欲しい場合)
 soup.find("a")



```
jqコマンドをCentOS6.8にインストールした際のメモ

#環境
CentOS6.8

#要求

- jsonデータを整形したいので、jqコマンドをCentOSにインストールしたい。
- 複数ファイルを一括整形したいので、ターミナルで実行する必要がある。
- 数が少なかったら、ネット上のjsonデータ整形サービスを使用するのがおすすめ。例えば、
https://lab.syncer.jp/Tool/JSON-Viewer/ など


#まず、yumでインストールを試してみる

```
sudo yum -y install jq
読み込んだプラグイン:fastestmirror, priorities, refresh-packagekit, security
インストール処理の設定をしています
Loading mirror speeds from cached hostfile
パッケージ jq は利用できません。
エラー: 何もしません
```

パッケージには入っていないようです。
CentOS7以降だといけるんですかね。
https://qiita.com/wnoguchi/items/70a808a68e60651224a4

#では、公式サイトからインストールを試してみる

- 公式サイトにアクセス
- https://stedolan.github.io/jq/
- Downloadボタンをクリックし、Linux(64bit)を選択
- jq-linux64のバイナリがダウンロードされるので、/binにコピーして実行権限を付与

```
mv jq-linux64 /bin/jq
chmod 755 jq
```

#インストールできたかな

```
[root@localhost xxxxx]# jq
jq - commandline JSON processor [version 1.5]
Usage: jq [options] <jq filter> [file...]

	jq is a tool for processing JSON inputs, applying the
	given filter to its JSON text inputs and producing the
	filter's results as JSON on standard output.
	The simplest filter is ., which is the identity filter,
	copying jq's input to its output unmodified (except for
	formatting).
	For more advanced filters see the jq(1) manpage ("man jq")
	and/or https://stedolan.github.io/jq

	Some of the options include:
	 -c		compact instead of pretty-printed output;
	 -n		use `null` as the single input value;
	 -e		set the exit status code based on the output;
	 -s		read (slurp) all inputs into an array; apply filter to it;
	 -r		output raw strings, not JSON texts;
	 -R		read raw strings, not JSON texts;
	 -C		colorize JSON;
	 -M		monochrome (don't colorize JSON);
	 -S		sort keys of objects on output;
	 --tab	use tabs for indentation;
	 --arg a v	set variable $a to value <v>;
	 --argjson a v	set variable $a to JSON value <v>;
	 --slurpfile a f	set variable $a to an array of JSON texts read from <f>;
	See the manpage for more options.
```

- インストール出来ているようです。
Unityでスマートフォン向けゲームを開発する(Part 1)

勉強会で得た知識を備忘録がてら記録します。

## 参考書籍紹介
以下の書籍を参考にする。

[Unityの教科書 Unity2018完全対応版](https://www.sbcr.jp/products/4797397659.html
)
![](https://qiita-image-store.s3.amazonaws.com/0/279475/857bb8df-c82d-03be-0eb4-cb3166c8a15e.jpeg)


---
## アジェンダ
1. 準備
2. ゲームの設計を考える
3. プロジェクトの作成
4. オブジェクトの配置
5. スクリプト製作
6. スマートフォンで動かしてみる
7. 次回内容紹介

---
## 1. 準備

iPhoneでゲームを動かすには...XCodeが必要
Androidでゲームを動かすには...JDKとAndroid Studioが必要

設定方法は割愛する

---
## 2. ゲームの設計を考える

### 2-1. ゲームの企画を作る
占いルーレットを製作する。
画面上にルーレットが表示されており、画面をタップするとルーレットが回転をはじめ、時間が経過するにつれて回転速度が遅くなる。

---

### 2-2. ゲームの部品を考える
本書では以下のステップに沿って設計を考える。

1. 画面上のオブジェクトを全て書き出す
2. オブジェクトを動かすためのコントローラスクリプトを決める
3. オブジェクトを自動更新するためのジェネレータスクリプトを決める
4. UIを更新するための監督スクリプトを用意する
5. スクリプトを作る流れを決める

今回製作したゲームでは3と4不要のため、省略する。

---
### 2-2. ゲームの部品を考える(画面上のオブジェクトを全て書き出す)
今回は針とルーレットを使用する。
![](/Users/hiranotomomi/Desktop/UnityNoKyoukasyo2018_sample/ゲーム素材/chapter3/needle.png)
![](/Users/hiranotomomi/Desktop/UnityNoKyoukasyo2018_sample/ゲーム素材/chapter3/roulette.png)

---
### 2-2. ゲームの部品を考える(オブジェクトを動かすためのスクリプトを決める)

今回はルーレットオブジェクトを動かす。
動かすオブジェクトにはオブジェクトの動きを制御するスクリプトが必要となる。
オブジェクトを動かすためのスクリプトを"コントローラスクリプト"と呼ぶ。

---
### 2-2. ゲームの部品を考える(オブジェクトを自動更新するためのジェネレータスクリプトを決める)

このステップではゲームプレイ時に生成されるオブジェクトを探す。
プレイヤの移動や時間経過によって出現するものが当てはまる。

例) 敵キャラ、ステージの足場

ゲームプレイ時にオブジェクトを生成するスクリプトを"ジェネレータスクリプト"と呼ぶ。
ジェネレータスクリプトはオブジェクトを生成する工場のようなものである。

---
### 2-2. ゲームの部品を考える(UIを更新するための監督スクリプトを用意する)

ゲームのUIを操作したり、進行状況を判断したりするためにゲーム全体を見渡せるスクリプトが必要になる。
そういったスクリプトのことを"監督スクリプト"と呼ぶ。

---
### 2-2. ゲームの部品を考える(スクリプトを作る流れを決める)

以上のステップで洗い出したスクリプトからどのようにゲームを作っていくかを考える。
基本的には「コントローラスクリプト」→「ジェネレータスクリプト」→「監督スクリプト」の順番で製作する。

今回はルーレットを動かすためのルーレットコントローラのみ作れば良い。

---
## 3. プロジェクトの作成

## 4. オブジェクトの配置

省略。

---
## 5. スクリプト製作


"マウスのクリックに応じてルーレットを回転させ、減速して止まる仕組み"を作成する。

---
## 5-1. クリックすると一定の速さの回転するスクリプト

~~~C#
public class RouletteController : MonoBehaviour {

	//回転速度
	float rotSpeed = 0;

	void Start () {	
	}
	
	void Update () {
		//マウスが押されたら回転速度を設定する。
		if(Input.GetMouseButtonDown(0)){
			this.rotSpeed = 20;
		}

		//回転速度分、ルーレットを回転させる
		transform.Rotate(0,0,this.rotSpeed);
	}
}
~~~

---
## 5-2. ルーレットを減速させる処理を追加する

~~~C#
public class RouletteController : MonoBehaviour {

	//回転速度
	float rotSpeed = 0;

	void Start () {
		
	}
	
	void Update () {
		//マウスが押されたら回転速度を設定する。
		if(Input.GetMouseButtonDown(0)){
			this.rotSpeed = 20;
		}

		//回転速度分、ルーレットを回転させる
		transform.Rotate(0,0,this.rotSpeed);

		//ルーレットを減速させる
		this.rotSpeed *= 0.99f;
	}
}
~~~

---
## 6. スマートフォンで動かしてみる

iOSの場合、Unityのプロジェクトを一旦iOSのプロジェクトへと変換し、iOS用のコンパイラ（Xcode）を利用して、iPhoneに書き込む必要がある。

---
## 7. 次回内容紹介

車の旗をギリギリ手前で止める「寸止めゲーム」を作成する。
vagrantでLAMP環境構築する PHP7


vagrantでPHP7用の環境を作成。
プロビジョニングはシェルで。手順は`Hou to use`を参照。
https://github.com/carrry0209/vagrant_lamp

## 環境はこんな感じ

* CentOS 7
* PHP 7.2
  * Xdebug
* Composer
* PHPUnit
* FuelPHP(oilコマンド)
* Apache
* Git
* MySQL 5.6

## 問題点

SELinuxの設定変更を反映させるために、`vagrant up`した後に、`vagrant reload`しなければならないようになってる部分。
プロビジョニングのシェルにリブートのコマンド入れるとうまくいかなかったので諦めてそうしてしまっているが、どうにかしたいです。

## あとがき

次はプロビジョニングツール使ってやりたいです。（いつの日か）
PHPでPOSTデータを取り扱う際の処理の流れと参考記事

# 1.本文
## 1-1.Postデータは$_POSTで受け取る 
特に説明は必要ないと思いますが、phpでpost内容を取得したい場合、$_POSTという特殊な変数を介して取り扱います。

## 1-2.Postの内容は「信用しない」（バリデーションを行う）
postの内容は、クライアントから送信されてきたデータです。このため、基本的に「信用できないデータ」が送信されてくることを前提として、内容のチェックを行うのが正しい作法です。

内容のチェックを行う処理を、バリデーションと呼びます。バリデーションを通過したデータは、「信用できるデータ」として扱います。

つまり、どのような処理を行うにしても、以下のフローチャートような流れに沿って、プログラムを実装するべきです。
![フローチャート.png](https://qiita-image-store.s3.amazonaws.com/0/77380/356efd00-c6e2-0f76-5d56-d77ab17b0f5b.png)

## 1-3.バリデーションについて
多岐に渡るため、別途まとめます。


## 1-4.出力時のエスケープ
アプリケーションの実行結果としてPOSTデータを出力する場合、必ず適切エスケープ処理を行ってください。（適切なエスケープを行わない場合、アプリケーションに脆弱性が生じる可能性があります。）


# 2.参考記事
## 2-1.HTTPリクエストに関連する参考記事
下記の記事では、リクエストをJAVA（サーブレット）に処理させる場合の一連の流れが非常にわかりやすく説明されています。
https://qiita.com/shuntaro_tamura/items/ae55b99deb9e2a170754

HTTPリクエスト、HTTPレスポンスの具体的内容については、下記を参照してください。
https://qiita.com/gunso/items/94c1ce1e53c282bc8d2f


## 2-2.関連するPHPのドキュメント
POSTデータを取り扱う前に、以下のPHPドキュメントに目を通しましょう。

$_POST
http://php.net/manual/ja/reserved.variables.post.php

外部から来る変数
http://php.net/manual/ja/language.variables.external.php

データのフィルタリング
http://php.net/manual/ja/book.filter.php

## 2-3.PHPでPOST、GETを取り扱う場合の参考記事
\$_GET、$_POSTなどを受け取る際の処理
https://qiita.com/mpyw/items/2f9955db1c02eeef43ea

【PHP超入門】HTTP（GET・POST）について
https://qiita.com/7968/items/4bf4d6f28284146c288f
ubuntu install 困った点いろいろ

# はじめに
一度一から環境構築をしたはずなのにはまってしまったので確認のため。

# 突然GPUを認識できなくなった。
おそらくドライバーが自動更新されてしまい、tensorflowでドライバーが認識されなくなった。ドライバーのバージョンを下げようと思い変更して見るとエラー。仕方なく再インストールへ。

# インストール時
CD　or　USBから起動し、起動時にe
https://qiita.com/bohemian916/items/8c7f0c4b3d3ea0958559

http://christina04.blog.fc2.com/blog-entry-162.html

# パーティションの振り分け
https://www.abten.net/2015/05/444/ 
これにしたがってやって見たが、grubがインストール出来ないエラーが発生。
どうやら/bootのパーティションに問題があるようだった。
https://www.geek.sc/archives/1404
を参考に
- /boot/efi
- 200MBで
- FAT32

# boot menuに出てこない
一度offにしていたので確認していなかったが、セキュアブートがオンになっていた。

# deb fileのインストール
```
 sudo dpkg -i <filename>
```


# GTK tweak tool
``` 
sudo apt install gnome-tweak-tool
```
CustomVisionでエクスポートしたモデルをAndroidスマホで動かす

# はじめに
AzureのCustomVisionServiceでは、トレーニングしたモデルをエクスポートすることができます。このモデルをAndroideスマホで動かせるのか試してみましたっというメモです。

# モデル作成
詳細は割愛しますが、CustomVisionServiceで画像をアップロードし、ラベルづけを行い、トレーニングしました。
モデルが出来上がったら、「Performance」の「Export」でTF(Android)を選択し、モデルをダウンロードしました。zipファイルの中にラベルが記載されたテキストファイルと拡張子がpbのモデルが入っています。

# Azureサンプルを使ってみる
以下の記事を拝見したので、Androidでもてっきり簡単にできるものだと思っていました。

「Custom Vision Serviceを使ってお花判定カメラアプリを作る」
https://blog.nextscape.net/archives/Date/2018/02/customvision_ios

Android用のサンプルはGithub上で見つけました。
https://github.com/Azure-Samples/cognitive-services-android-customvision-sample

これをAndroidStudioで読み込んで、apkファイルを作成し、自分のスマホ(Huawei p20 lite)に入れてみました。

が、起動してすぐに落ちてしまい、うまく動きません。

なんでかなーと色々調べていたところ、まさしくなissueが上がっていました↓ 
「i am trying to develop android app but the app keeps on crashing #8」
ちょっとコードに手を加えてOK!という感じではないことはわかりました。

# Tensorflowデモを使ってみる
というわけで、Azureサンプルを使うのは諦めて、Tensorflowのデモアプリを試してみることにしました。
やり方は以下のページに詳しいので割愛します。
https://www.tensorflow.org/mobile/android_build

こちらは問題なく動かすことができました。

ちなみに、CustomVisionでエクスポートしたモデルをこのデモアプリで使う場合は、ちょっとソースコードをいじる必要があります。
一応動くことは確認できたのですが、もうちょっと調べてから記載しようと思います。

以上
NanoPIをRouterにする

# 摘要

在进行Linux SBC应用程序开发（如NanoPI，RPi）时连接到Internet并不罕见。 （真的吗）
在这种情况下，如果智能手机以USB网络共享模式连接，设备可以轻松地发布到互联网，但是从这个设备，通过有线局域网连接的设备可以访问NanoPI，但可以发布到互联网没有。
在这里，我将向您展示如何配置NanoPI，以便连接到LAN的设备也可以发送到Internet。

# はじめに
NanoPI, RPiといったLinux SBCの応用開発を行う際にInternetに接続されてないことはよくあることです。（ほんとかな）
こうした場合、スマホをUSBテザリングモードにして接続すれば、当該機器は簡単にインターネットに出られるのですが、この機器から、有線LANで繋がった機器はNanoPIにはアクセスできるものの、インターネットには出られません。
ここでは、NanoPIを設定して、LANに接続した機器もインターネットに出られるようにする方法を紹介します。

# DNSをたてる
いきなりちょっとそれますが、[NanoPI上でdeadwoodを動かす](https://qiita.com/maclineto/items/1fb65d908f830098a6df) に従い自前のDNSを立てましょう。NanoPI1台ならスマホのDNSを使うという手もありますが、パフォーマンスが違いますし、LANにつながった機器から参照するとなればなおさらです。

# fowardingを有効にする
Linuxのdefaultでは無効になっている、fowardingを有効にします。

```/etc/sysctl.conf
# Controls IP packet forwarding
#net.ipv4.ip_forward = 0
net.ipv4.ip_forward = 1
```

設定を有効化します。

```
sysctl -p /etc/sysctl.conf
```

iptablesを操作してMASQUERADEを設定します。

```
iptables -F
iptables -t nat -F
iptables -t nat -A POSTROUTING -s 192.168.0.0/16 -o usb0 -j MASQUERADE
iptables -A FORWARD -i usb0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o usb0 -j ACCEPT
iptables-save -c > /etc/iptables.rules
```

起動時この設定が有効になるようfileを作ります。

```file:/etc/network/if-pre-up.d/iptables_start
#!/bin/sh
/sbin/iptables-restore < /etc/iptables.rules
exit 0
```
intaerfacesを設定し、default routeがスマホを向くようにします。

```file:/etc/network/interfaces
allow-hotplug eth0
no-auto-down eth0
iface eth0 inet static
address 192.168.254.80
netmask 255.255.255.0
dns-nameservers 127.0.0.1

allow-hotplug usb0
no-auto-down usb0
iface usb0 inet dhcp
post-up route add -net default dev usb0
dns-nameservers 127.0.0.1
```

rebootで繋がるはずです。

# dhcpdをたてる
これでインターネットにはつながりましたが、LANにつながった機器からインターネットに出るのは容易ではありません。default routeを向け、dns-serversを指定しなくてななりません。開発中は接続も頻繁に変わるのでいっそ、dhcpdをたてて、全自動化してしまいましょう。[NanoPIにUdhcpdをたてる](https://qiita.com/maclineto/items/840195c1392c2c65d306) に別記事を書きました。

# 結論

二つ以上のインターフェースがあれば設定次第でRouter化することができるが、その操作は意外と面倒で難しい。
ParityのRPCリクエストでParse errorが返る

ParityでJSON-RPCリクエストを送った際にParse errorが返ることがある。

# 現象

## リクエスト
```bash
curl --data \
  '{"method":"personal_unlockAccount","params":["0xbdb5232157860e22120cd9b9b847ca1024cdb95f","password", 0x3E8],"id":1,"jsonrpc":"2.0"}' \
  -H "Content-Type: application/json" -X POST localhost:8545
```

## エラー
```bash
{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":null}
```

# 原因と対策
hexの値は文字列として渡す必要がある。

## 修正後のリクエスト
```bash
curl --data \
  '{"method":"personal_unlockAccount","params":["0xbdb5232157860e22120cd9b9b847ca1024cdb95f","password", "0x3E8"],"id":1,"jsonrpc":"2.0"}' \
  -H "Content-Type: application/json" -X POST localhost:8545
```

# 環境
- Parity: `Parity/v1.11.0-beta-62ccdd7-20180508/x86_64-linux-gnu/rustc1.25.0`
- Ubuntu 16.4 LTS: `Linux ip-10-1-0-38 4.4.0-1041-aws #50-Ubuntu SMP Wed Nov 15 22:18:17 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux`
【Unity×ARkit】AR空間にある3Dオブジェクトを持ち上げる

3D空間にあるオブジェクトを持ち上げるような処理を作りたかったのですが、参考にできる記事が見当たらなかったので、自分のメモがてら残しておきます。

画面のタッチ処理は別で行ったので、ここには記載していません。

![watch.gif](https://qiita-image-store.s3.amazonaws.com/0/254171/784c8570-be04-555d-241b-79b4b2e553f6.gif)

```c#:

 Ray ray = new Ray(); ray = Camera.main.ScreenPointToRay(Input.mousePosition);

 //rigidbodyの重力を消しておかないと持ってる最中に落ちていく
 MoveObject.GetComponent<Rigidbody>().useGravity = false; 

 //カメラの方向にオブジェクトを向かせる
 MoveObject.transform.LookAt(MainCamera.transform);  
 
 //持ち上げる際のカメラからの距離と方向の計算
 //Distanceで持ち上げた時の距離の調整　inspectorで調整
 Vector3 velocity = ray.direction * Distance; 
 
//カメラの位置にvelocityを足す
 Vector3 ObjectMovePosition = velocity + ray.origin;
}
```

<h3>余談</h3>
記事を調べても調べても、カメラをオブジェクトに追従させるものばかりで、オブジェクトをカメラに追従させるってものが見当たらなかったです。

確かに今まではオブジェクト中心でしたが、ARによるカメラ（人物）中心に物事が動いていくってことで新鮮でした。

<h3>以前書いたUnityでARKitに関わる記事</h3>
[【Unity×ARkit】3D空間でアナログ時計を画面入力で回転](https://qiita.com/Tanktop_in_Feb/private/8b019872e0dddb9a5c79)
Zsh — 日本語を bindkey して自動変換チックにする遊び

```
 bindkey -s "にほんご" "日本語"
```

バインド後に「にほんご」と入力してみよう。


## Version

- zsh 5.5.1 (x86_64-apple-darwin17.5.0)
- Mac OS X High sierra

## あわせて読みたい？

- [Zsh—bindkeyの魔法 ( aを入力して bを出力する ) - Qiita](https://qiita.com/YumaInaura/items/4dfd9a18fb8aec8f8ff0)

## Links

- [Gist](https://gist.github.com/YumaInaura/27bb1f79881a63bed2fb9635cbaed73b
)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Linuxのセキュリティに関する基礎知識

Linuxに関する基礎知識
超基礎よりはちょい突っ込んだ内容

##セキュリティに関する知識 


まずはセキュリティの現状を確認する方法について
:primates> ls -l
-rw-r--r-- keeper prim 547 9:31 chimps
-rw-r--r-- keeper prim 983 9:32 gorillas
-rw-r--r-- keeper prim 485 9:34 sq_monks

この左端に書いてある-rw-r--r--などが現在のセキュリティを表している
---　---　---
rwx　rwx　rwx
rはreadable(閲覧可能性）、wはwriteable（書き換え可能性）、xはexecutable(実行可能性）を表し、左のブロックから順にユーザー、グループ、他人を表す。例えば、世界中誰しもコードを書き換えられるようにしたいならば、---------を-------w-とすればよい。

##実際に変える時のコード
　　では、実際にセキュリティ設定を変えたい時はどうしたらいいのか

設定を変える時はchmodコマンドを使う。また、ユーザーはu,グループはg,世界中のユーザーはoと定義する。

もし、世界中のユーザーにexecuteの権限を与えるとすると、
chmod o+xと打つ。
(others[o]に、execute[x]の権限を与える[+]という意味）
全部一気に与えたい場合は
chmod ugo+rwx
みたいな感じで打てば良い。
名古屋で勉強会を開く　場所をしらべてみた

## はじめに
ここのページでは、名古屋で、社外勉強会をやりましょうといった場合のノウハウを記録していこうかと。

## 話の前提　念頭にあるもの
1. 目的。IT関連の勉強会。別にITにこだわっているわけではないけど、その領域しか知らないので。将来的には全然分野がちがう 保護猫とか歴史関連の勉強会とかも 視野にはいれる。
2. 場所。当然 名古屋市内。
3. 時間。平日の場合 19:00開始で余裕みて 22:00まで借りれるのが望ましい。
4. 広さ。まあ、３人～多くて１５人くらいじゃね。何をやるにしてもバス一台分が一番たのしい。それ以上のスケールになると、それなりのシステム化が必要。
5. 金額。有料のセミナーやるほどエラクないので、つまむお菓子と会場代で、一人当たり1000円まで。東京からなど外部講師の方を別途呼ぶとか やるコンテンツで縛りがあるとか の場合は別途。人はカスミをくっては生きていけないのもまた事実なので。

## で、リンクはっておく
　[名古屋勉強会ラムダ](https://nagoya-benkyokai.com/)や[Google先生で「名古屋 勉強会 場所」](https://www.google.com/search?q=%E5%90%8D%E5%8F%A4%E5%B1%8B+%E5%8B%89%E5%BC%B7%E4%BC%9A+%E5%A0%B4%E6%89%80&ie=utf-8&oe=utf-8&client=firefox-b)で、まずは探してみた。
　また、ほかに過去いったセミナーの記録をヒントに場所の候補をピックアップする。

### [名古屋国際センターNIC 貸し施設](http://www.nic-nagoya.or.jp/japanese/nicnews/kashishisetsu)
　きれいそうだし場所はよい。でも、お高いでしょう？と時間が 21:00

### [ベースキャンプ名古屋](https://basecamp-nagoya.jp/)
　コワーキングスペースは ２回ほど利用したことがある。[無料勉強会支援](https://basecamp-nagoya.jp/service/freeEvent.html)もあり。

### [名古屋市民活動センター](http://www.n-vnpo.city.nagoya.jp/shisetsu/)
　いまいち予約方法がわからない。まず市民団体になる必要がありそうだ。

### [愛知NPO交流プラザ](https://www.aichi-npo.jp/1_annai/1_NPO_plaza/1_shisetsu_annai/sinplazagaiyou.htm)
　ここもいまいち予約方法がわからない。21:00までがネックか。

### [中電不動産東桜会館](http://www.chudenfudosan.co.jp/bunka/higashisakura/kaigi)
　ここも 21:00までだなぁ。

### [ウィンクあいち](http://www.winc-aichi.jp/conference/rates.html)
　ここも 21:00までだなぁ。

### [いーぷるなごや](https://e-able-nagoya.jp/utilization/apply/)
　名古屋アジャイル勉強会で使っている場所。ここも 21:00

### [名古屋市中区 中生涯学習センター](http://www.city.nagoya.jp/naka/category/263-1-3-0-0-0-0-0-0-0.html)
　和室がある。すげー。

### [江口光ビル貸会議室](http://www.baby-kids.net/pg24.html)
　利用時間が 9:00～18:00、１時間1500円
　価値観ババ抜きはここでやってくれた。

### [フジコミュニティセンター](http://www.fujicommunitycenter.jp/)
 利用時間 8：30～21：00
 最初の2時間が4000円より。大会議室もある

### [格安で借りられる名古屋市のレンタルスペース・会場まとめ](https://www.spacemarket.com/features/Cnr_fyMpN03A10Ny/cities/nagoya-shi--aichi)
　トランプ会議室とストーリー会議室が 900円/時間

### [日本システム開発 OPEN INNOVATION BASE](http://www.nskint.co.jp/think/)
　名古屋駅近くで利用料金は無料だけど、社員さんの紹介が必要。つまりまずコネをつけないと。

### [大須フリースペース](https://bodoge.hoobby.net/spaces/osu-free-space)
　平日 18:00-22:00で 500円とお買い得。モニター・プロジェクタあり、Wi-Fiあり、お菓子持ち込みOK。ボードゲームな用途のフリースペースと、コワーキングスペースな大須クリエイトスペースがある。
　名古屋で22:00までOKなのは魅力的だなぁ。

### [Misocaセミナールーム 木曽川](https://tech.misoca.jp/entry/2016/07/01/140723)
　ここも名古屋駅近くで利用料金無料。ただし、IT関連技術、話題に関する勉強会/イベント限定。運営が社員の方のボランティアのようなので、最低限ご迷惑をおかけしないように。ビジネス的なつながりができてくると お互い幸せになれるだけど。

### 参考：弊社の場合
　場所は名古屋駅から20分くらいの堀田です。弊社従業員が過半をしめないといけないという縛りがきついですねぇ。。

## おわりに
　公共の会議室は 21:00までがどうやら主流。22:00までとなると意外とない。Misocaさんが一番魅力的だけど、どうかなぁ。
　いずれにしても候補の日時をきめて先方に問い合わせすることになりそうだ。

　なお、この記事は予告なく随時アップデートしようかとおもっております。
vue-cli 3.0で立ち上げたアプリに複数のエントリーポイントを用意する

# 概要
エントリーポイントを分けることで、コードの見通しは良くなり、余分なコードのダウンロードを避けることができます。
今回、vue-cli 3.0 で立ち上げた趣味アプリに複数のエントリーポイントを用意したのですが、 思いの外苦戦したので設定方法を共有したいと思います。

# 設定方法
vue-cli の2系までは `webpack.config` に `entry` を記述することで、複数のエントリーポイントに対応する事ができました。[^1]
しかし、vue-cli 3.0でセットアップしたプロジェクトには `webpack.config` が生成されません。

その代わりに `vue.config.js`に vue-cli の設定を記述することができます。[^2]
この中で `pages` オブジェクトとして、複数のエントリーポイントを定義することができます。
この状態を `multi-page mode` と呼びます。

# vue.config.js の用意
ルートディレクトリに `vue.config.js`を作成します。

```js:vue.config.js
module.exports = {
  pages: {
    index: {
      entry: 'src/entry-point/index/main.js', // エントリーポイントとなるjs
      template: 'public/index.html', // テンプレートのHTML
      filename: 'index.html' // build時に出力されるファイル名
    },
    signin: {
      entry: 'src/entry-point/signin/main.js',
      template: 'public/signin.html',
      filename: 'signin.html'
    }
  },
  devServer: {
    historyApiFallback: {
      rewrites: [
        { from: /\/index/, to: '/index.html' }, // index.html に飛ばす
        { from: /\/signin/, to: '/signin.html' }
      ]
    }
  }
}
```

今回は `index` と `signin` の2つをエントリーポイントとして設定しています。

# vue.config.js の適用
`multi-page mode` では　`html-webpack-plugin` と `preload-webpack-plugin` を必要としています。
よって、`pages` の変更時には `vue inspect` を実行する必要があります。

**これは忘れがちなので気を付けましょう。**

`baseUrl` を設定していない場合は、これで複数のエントリーポイントに対応することができました。

# baseUrl を設定している場合
baseUrl を指定している場合は注意が必要です。
ドキュメントの `devServer` の項目には以下の文章が記載されています。[^3]

> Some values like publicPath and historyApiFallback should not be modified as they need to be synchronized with baseUrl for the dev server to function properly.

`historyApiFallback` などの値は、devサーバーが正常に機能するために `baseUrl` と同期する必要があるようです。

対応策として `<base>` タグをテンプレートに差し込んで上げる必要があります。

- `baseUrl` が `vue-app` の場合  

```html
<!DOCTYPE html>
<html>
  <head>
    <base href="/vue-app/">
    ...
  </head>
  <body>
    ...
  </body>
</html>
```

# その他
`devServer` を用いて設定を行なっているので、本番環境へのデプロイは別途設定が必要なことに注意してください。
Firebaseだと [ここら辺](https://firebase.google.com/docs/hosting/url-redirects-rewrites?hl=ja) が参考になりそうです。


[^1]: この方のブログが参考になります: http://okamuuu.hatenablog.com/entry/2017/02/17/180628
[^2]: https://cli.vuejs.org/config
[^3]: https://cli.vuejs.org/config/#devserver
Alexaスキルでおうむ返し

発話内容をAlexaにおうむ返しさせるサンプル。Alexaは任意の発話を受けるスロットタイプが無いようだが、適当なスロットタイプでいけた。

#インテントの設定
インテント名は適当にCopyIntentとし、スロットタイプはAMAZON.Colorを指定。
![スクリーンショット 2018-08-26 18.57.38.png](https://qiita-image-store.s3.amazonaws.com/0/77444/ac0f6415-3bd7-446d-e29a-f77bd02c76c8.png)

AMAZON.Colorが任意の文字列を受けられるという情報は、この書籍を参考にした。
> おもしろまじめなAIスピーカーアプリをつくろう -Google Home（アシスタント）&Amazon Echo（Alexa）音声アシスタント開発
https://www.shuwasystem.co.jp/products/7980html/5273.html

# Lambda関数
CopyIntentHandlerメソッドで、 スロットのmessageを取り出す。

```
const CopyIntentHandler = {
    canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'IntentRequest'
            && handlerInput.requestEnvelope.request.intent.name === 'CopyIntent';
    },
    handle(handlerInput) {
        let value = handlerInput.requestEnvelope.request.intent.slots.message.value;
        const speechText = value + 'って言いましたね！';

        return handlerInput.responseBuilder
            .speak(speechText)
            .getResponse();
    },
};
```
とりあえず、これでうまくいった。
AngularのInputについてのノウハウ（メモ）

## ハマった問題

Angularのコンポーネントで以下のように`@Input()`を使うとき、変数`x`を読み取り専用にしたければObservable化して渡せばよいという話を見たことがあったので試していたが、気を付けないといけない点がある（気づいたら当たり前…）。

```ts
@Component({
  selector: 'app-my-component'
  ...
})
export class MyComponent implements OnInit {
  @Input() x!: string;

  ...

}
```

↓（Observable化）

```ts
@Component({
  selector: 'app-my-component'
  ...
})
export class MyComponent implements OnInit {
  @Input() x$!: Observable<string>;

  ...

}
```

［補足］
'!'は初期化チェックを回避するためのDefinite Assignment Assertionというもので、`@Input()`を付ける変数のようにコンストラクタで初期化できない変数に対して付ける必要がある。

---


`x`をObservable化する場合、`app-my-component`要素が親コンポーネントで`*ngIf`などで消えているときに`x$`が発火してもapp-my-component内ではsubscribeされていない（`*ngIf`で消えているコンポーネントは単に隠されているのではなく消えている（参考：[Why remove rather than hide?](https://angular.jp/guide/structural-directives#why-remove-rather-than-hide)））ので、子コンポーネントがObservableの初期値発火の後に生成されたときなどに、初期値を取得できなくなってしまう。

## 解決策

読み取り専用にするにはObservable化はせず、単にreadonly修飾子を付ければよい。

```ts
@Component({
  selector: 'app-my-component'
  ...
})
export class MyComponent implements OnInit {
  @Input() readonly x!: string;

  ...

}
```

## 子コンポーネントにObservableを渡したいときについて

子コンポーネントがObservableを受け取りたいときも、ただの値で受け取って子コンポーネント内部でObservable化する方が、ただの値を渡したいときも柔軟性があって良さそう（Observableからただの値を取り出すには親template内でasync pipeを使えばよいが、逆は親template内で完結させることができない）。

Inputの値の変化を傍受するには`ngOnChanges`を使うしかないかと思っていたが、少なくともAngularの現在のバージョン(v6.1.1)ではInputはsetterに対して以下のように使えるらしく、この中でSubjectへ値を送るという使い方ができるらしい。（参考：[Angular 日本語ドキュメンテーション - コンポーネントの相互作用 「セッターによって入力プロパティの変更を傍受する」](https://angular.jp/guide/component-interaction#%E3%82%BB%E3%83%83%E3%82%BF%E3%83%BC%E3%81%AB%E3%82%88%E3%81%A3%E3%81%A6%E5%85%A5%E5%8A%9B%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3%E3%81%AE%E5%A4%89%E6%9B%B4%E3%82%92%E5%82%8D%E5%8F%97%E3%81%99%E3%82%8B)）
これくらい簡単にInputのObservable化ができるのであればあまり苦にならない。

```ts
// 最終版
import { Subject } from 'rxjs';

@Component({
  selector: 'app-my-component'
  ...
})
export class MyComponent implements OnInit {

  private xSource = new Subject<string>();

  @Input() set x( value: string ) {
    this.xSource.next(value);
  }
  
  x$: Observable<number> = this.xSource.asObservable();

  ...

}
```

そもそも、Observableを渡すというやりかたは親コンポーネントと子コンポーネントが疎結合にならないのであまりよろしくないという気がしてきた。Observableベースな実装にするどうかをコンポーネント単位で考えればよいというメリットは大きい。
親子コンポーネントの値のやり取りはただの値に統一してやるのがシンプルで良さそう。
Amazon EFSのパフォーマンスモードとスループットモードについて

# パフォーマンスモード？　スループットモードって？？
EFSを作成する際に、以下のようにパフォーマンスモードとスループットモードを選択する必要ある。
今回はパラメータの選定目安について記載してみます。

![FireShot Capture 8 - Elastic File System M_ - https___ap-northeast-1.console.aws.amazon.com_efs_home.jpg](https://qiita-image-store.s3.amazonaws.com/0/282630/8789c3f1-7ba2-469a-0e2f-a66a37f0d4c7.jpeg)


# パフォーマンスモードの選び方
それぞれ「General Purpose」と「Max I/O」が指定されているが、ほとんどケースではGeneral Purpose（汎用モード）でよさそう。

汎用モードでは1秒あたりのファイルシステムオペレーションは7000回に制限されているがIOPS要件が7000未満であれば汎用モードで十分。
https://docs.aws.amazon.com/ja_jp/efs/latest/ug/limits.html#limits-fs-specific

運用開始後CloudWatchメトリクスのPercentIOLimitを確認し、100％に届くことが発生すれば
そのときにMax I/Oモードを検討すればよい。

なおMax I/Oモードを選択するとスループットが高まる代わりにレイテンシも高まるので注意。

# スループットモードの選び方
秒間どれだけのデータをStorageに書き込む必要があるかによって変わってくる。
一度に相当巨大なファイルの書き込みが発生する場合には、プロビジョンドスループットを有効にする必要があるが、ファイルシステムサイズが1TiBにおいてベースで50MiB/s、バースト時には100MiB/sまでのスループットを発揮するので、よっぽどのことがない限りBurstingでも問題ない。


#　注意点
~~一度、EFSを作成するとパフォーマンスモードとスループットは変更できない。（2018年8月時点）~~
一度、EFSを作成するとパフォーマンスモードは変更できない。（2018年8月時点）
なので、パフォーマンスモード、スループットモードを変更する際は、別のEFSを作り直して、ファイルを
EFS File Syncなどで移行する必要がある。

EFS File Sync
https://aws.amazon.com/jp/blogs/news/efs-file-sync-faster-file-transfer-to-amazon-efs-file-systems/


スループットは変更できるとのご指摘いただきました。
ただし前回のスループット変更から24時間経過している必要があるのでご注意を。
https://docs.aws.amazon.com/ja_jp/efs/latest/ug/performance.html
関西オープン優勝しました。

本日8月26日に行われた、関西ブロック主催の関西オープンに出場し、レスキューメイズ部門の3チーム中1位でした。
どこも似たり寄ったりでしたので、あんまりですね……
まぁ、良しとしましょう。

![IMG_-o5b81r.jpg](https://qiita-image-store.s3.amazonaws.com/0/283010/050853fc-04af-c328-2e3e-a3c3add5e416.jpeg)
Objection.jsでtimestampカラム(createdAt/updatedAt)を自動更新する

## やりたいこと

Sequelizeの[timestamps](http://docs.sequelizejs.com/manual/tutorial/models-definition.html#timestamps)機能を[Objection.js](https://vincit.github.io/objection.js/)で実現する。

* insert時に、createdAtとupdatedAtカラムに現在日時を設定する。
* update時に、updatedAtカラムに現在日時を設定する。

## 前提

DBはPostgreSQL、Objection.jsはv1.2.2を使用しています。

## 方法1. カラムにデフォルト値を設定する

Knex.jsのマイグレーションファイルで、カラムに対してデフォルト値を設定します。

```javascript
exports.up = function(knex, Promise) {
  return knex.schema.createTable('tasks', t => {
    t.increments('id').primary();
    t.string('name').notNullable();
    t.string('description').nullable();
    t.integer('assignedTo').nullable();
    t.integer('projectId').notNullable();
    t.foreign('assignedTo').references('id').inTable('users');
    t.foreign('projectId').references('id').inTable('projects');
    t.datetime('deadline').nullable();

    // デフォルト値を設定
    t.timestamp('createdAt').defaultTo(knex.fn.now());
    t.timestamp('updatedAt').defaultTo(knex.fn.now());
  });
};

exports.down = function(knex, Promise) {
  return knex.schema.dropTable('tasks');  
};
```

ただし、この方法だと、

insert時はSequelizeのようにcreatedAtとupdatedAtの両方が更新されますが、

update時にupdatedAtが自動更新されない問題が発生してしまいます。

```javascript
  const createdTask = await Task.query()
    .insertAndFetch({
      assignedTo: 1, 
      projectId: 1,
      name: 'hoge'
    });

  // insert時は、createdAtとupdatedAtが自動で設定される。
  console.log(createdTask.createdAt != null); // true
  console.log(createdTask.updatedAt != null); // true

  const updatedTask = await Task.query()
    .patchAndFetchById(createdTask.id, {
      name: 'fuga'
    });

  console.log(updatedTask.name === 'fuga'); // true ・・・ nameは更新されている
  console.log(updatedTask.updatedAt.valueOf() === createdTask.updatedAt.valueOf()); // true ・・・ 更新されていない
```

## 方法2. hookメソッドを利用する

Objection.jsのModelクラスには、hookメソッドが定義されていて、

サブクラスでオーバーライドすることで、クエリ実行時の挙動をカスタマイズできます。

レコードのinsert前は`$beforeInsert`、update前は`$beforeUpdate`が実行されるので、

以下のように処理することで、方法1の問題を解決することができます。

* `$beforeInsert`でcreatedAtとupdatedAtを更新
* `$beforeUpdate`でupdatedAtを更新

```javascript
const { Model } = require('objection');

class Task extends Model {
  static get tableName() { return 'tasks'; }

  $beforeInsert() {
    const now = new Date().toISOString();

    this.createdAt = now;
    this.updatedAt = now;
  }

  $beforeUpdate() {
    const now = new Date().toISOString();

    this.updatedAt = now;
  }
}
```

## 参考

https://vincit.github.io/objection.js/#timestamps
ProjectAquila機体紹介

# **Project Aquila機体紹介**

![IMG_20180826_184629.jpg](https://qiita-image-store.s3.amazonaws.com/0/283010/5b3820bf-e811-27f4-8861-eba625d631d9.jpeg)




- **CPU**
    - ~~ATxmega128a1u~~
    - ~~ATmega328p~~
    - `STM32F429vgt`
- **駆動系**
    - Pololu製100:1ギアードモーター
    - Pololu製VNH5019デュアルモータードライバー
- **センサ**
    - 超音波センサ
    - MLX90614
    - s9706
    - ~~(MPU9250)~~ `JY901` ([編集])
    - OpenMVm7
- **機体**
    - 基本MDF製で所々ジェラルミンを使用

---

こんにちは。
レスキューメイズ部門であまりこういう機体紹介がネット上に少なく、初めての出場者は困ると思い、まずこの記事を書いています。(実際自分達も困ってました。)

レスキューメイズといえば何をしなければいけないかといえば、
***1. 迷路探索***
***2. 被災者発見***
***3. レスキューキット投下***
基本的に上の3点だと思います。

順番に話していきましょうかね。



## ***1. 迷路探索***

まずは最も大事というかなんというか迷路探索から。
30cm*30cmの正方形が沢山繋がったコートを走り回り、帰還ボーナスを貰うためにはマッピングもしなければいけません。基本的にその場合に思いつくのが一マスずつ進むということですね。
その場合最も大事になってくるのが、まっすぐ正確に一ます進むということです。
ご存知かも知れませんがこれがほんとに難しい。
練習用コートと本番のコートと床の摩擦が違いますし、場所によっても違います。
距離センサなどで前後左右の壁との距離などを使用して進むのもありですが、自分たちは***モーターにそれぞれひとつの制御用マイコン***を搭載しています。それはなんのためか、PID制御のためです。(またPID制御についても書いていきたいです。)
>([追記]書きました[こちら](https://qiita.com/Shunk_/items/fe2e8f73abb1dabeffd6))
>(STM32一個に変更しました 2019/4/10)

~~自分たちはAVRを使って制御しているのですが、処理が重く、1台のマイコンですると処理落ちしてしまうのでそれぞれ搭載しています。~~

STM32の180MHzという驚異的なシステムクロックでマイコン1個でのPID制御を可能にしました。

また、自分たちの機体で特徴的なのは下のギアボックスですね。自分たちはモーターが大きいので、2つのモーターで超信地旋回がしたくて、ギアボックスも自作しました。あまりおすすめはできません。
ギアボックスがとてつもなく重く、メンテナンス性を阻害してる存在です。
![IMG_20180826_184647.jpg](https://qiita-image-store.s3.amazonaws.com/0/283010/6eb8b388-8d58-45f6-9228-5e703310d9b4.jpeg)



また、PID制御だけではどうしてもズレてしまうので、左右前後の距離を使ってズレを調整しています。本当は走りながら距離を使って修正するのがいいのですが、モーター制御用のマイコンとの通信の関係上実現出来ていません。

アルゴリズムに関しては相方が担当していて、自分はいまいち分かっていません😅
左手法ベースのアルゴリズムってことぐらいです笑

>相方がアルゴリズム(主にマッピングについて)記事にしたのでどうぞ
[こちら](https://hexagon-emile.hatenablog.com/entry/2019/01/24/013606)
(2019/02/08 追記)



## ***2. 被災者発見***
迷路を探索出来たら、次にするのは被災者探索です。
被災者は***2種類***あります。
***1. 熱源被災者***
***2. 文字型被災者***
自分たちは探索時間削減のため画像処理用のボード(OpenMV)と温度センサー(mlx90614)を前左右の3方向につけています。

~~これについて特に言うことは無いのですが、OpenMVには170°広角レンズをつけています。~~
`つけてもあまり変わらなかったので外しました`(2018/12/21追記)
`壁にとても近いとき高さの関係で読めなかったので斜めに、見下ろすような感じで固定されています`(2019/02/08追記)

温度センサーのしきい値は結構シビアですが、とりあえずはこんな感じ。
~~ただ、現状はモーターを動かしながらの検出ができていないので、文字、熱源共に壁の真ん中のものしか発見できないという問題点があります。~~
`温度センサーをOpenMVの方で制御して、視覚的、熱源被災者のいずれかをモーター回転時に見つけた際に、途中でモーターを止めて被災者を見つけられるようにしました`(2018/12/21編集)
`しきい値の調整として気温と対象物の表面温度の差を計測する方式に変更しました`(2019/02/08追記)


## ***3. レスキューキット投下***

被災者を見つけたらレスキューキット投下です。
ほとんどのチームは縦に積んで落としていく仕組みですが、ロボットの構造上横に配置したかったため、~~リボルバー拳銃のリボルバーのようなものを回転させ落としています。お陰様でしっかり落ちてくれるのですが、場所を取るというのがありますね😅メンテナンス性もないですし……~~
>スライドレールの仕組みを応用したものに変更しました。後日編集します(2019/4/24)

![IMG_20180826_184711.jpg](https://qiita-image-store.s3.amazonaws.com/0/283010/a25d82a8-45ce-6a60-010d-b7eec5fe2d16.jpeg)

## ***[追記]JY901について(2018/12/21 22:05:28)***
編集中……


とりあえずはこんな感じで切り上げましょうかね。
では、また。

##なにか質問等あれば [Twitter](https://twitter.com/shun_k_tech) まで
【Xcode】Xcode10からの変更で、右下のアイツがいない

Xcode10からの変更で、新しいプロジェクトを立ち上げて実装しようかとしたときに、Storyboardを開き右下から、アセットとかViewControllerを追加したいときに、 **いつものアイツ** がいなかったので、書きました。
UIViewControllerとかUIViewとかUIButtonとかをつまんで、持ってくるあいつです。

~~(この記事は、執筆時betaであるXcode10のスクリーンショットは載せていません。)~~
Xcode10が公開されたので追記します

## 今までのXcode9のアイツはこれ

(Xcode9)
<img width="691" alt="Screen Shot 2018-08-26 at 18.17.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/62822/59bf2ce1-217b-05c4-20ce-06eeef4f7579.png">

### この人らの正式名称
- File Template Library　　(ctrl + opt + cmd + 1)
- Code Snippet Library　　(ctrl + opt + cmd + 2)
- Object Library　　　　　(ctrl + opt + cmd + 3)
- Media Library　　　　　(ctrl + opt + cmd + 4)

というらしいです

(Xcode9の画像です)
<img width="479" alt="Screen Shot 2018-08-26 at 18.20.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/62822/09d1a56d-e0be-6a4c-1121-cdb56a534eb5.png">

それぞれコマンドが決まっているようでしたが


## Xcode10からは変わっているようです
- **cmd + shift + L** を押すと Library が開きます
- **cmd + shift + M**　を押すと　Media Library が開きます

と２つに減ったようで、更にショートカットも変わっています

更に表示も、右下固定でなく、ショートカットを叩くと全面に出てきてサクッと使えるように工夫されているみたいです。


<img width="526" alt="スクリーンショット 2018-09-18 9.39.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/62822/fc7ad1a8-5381-d89d-86a1-e70e2d40890a.png">


## まとめ
- File Template Library　　(ctrl + opt + cmd + 1) => 廃止？
- Code Snippet Library　　(ctrl + opt + cmd + 2) => 廃止？
- Object Library　　　　　(ctrl + opt + cmd + 3) => **Library (cmd + shift + L)**
- Media Library　　　　　(ctrl + opt + cmd + 4) => **Media Library (cmd + shift + M)**
CentOS起動関連ファイル

#はじめに
自分用にCentOSの起動に関連する主なファイルを一覧化しています。
確認に使用した環境はCentOS7.5です。

#ブートローダー関連ファイル一覧
UEFIやBIOSから呼び出されるブートローダー関連ファイル。
CentOS7で使用しているブートローダーはGRUB2になります。
格納場所は以下の通りです。

UEFI:/boot/efi/EFI/centos/
BIOS:/boot/grub2/

|ファイル名|内容|
|:--|:--|
|grub.cfg|GRUB2が呼び出す設定ファイル。ブートイメージの配置場所などの情報が記載されている。|
|device.map|GRUB2が認識するデバイス名(hd0)とカーネルが認識するデバイス名(/dev/sda)の対応関係を記載しているテキストファイル。|
|grubenv|前回起動したメニュー名などが格納されている。|

#カーネル関連ファイル一覧
ブートローダーから呼び出されるカーネルに関連するファイル。
格納場所は/bootになります。

|ファイル名|内容|
|:--|:--|
|vmlinuz-[バージョン名]|圧縮されたカーネルを含む、ブートイメージファイル。GRUB2からはこちらが呼び出される。|
|Sytem.map-[バージョン名]|メモリアドレスとシンボル名の対応関係を記載するテキストファイル。上述のブートイメージファイル作成時に生成される。|
|initramfs-[バージョン名].img|カーネルがrootファイルシステムをマウントする前に使用する、メモリ上に展開する最小限のLinux環境とディレクトリ構造をcpio圧縮ファイルにしたもの。|


#終わりに
今回はざっくりとCentOS起動関連のファイルを一覧にしました。
時間あるときにsystemd関連の情報も追加していきたいと思います。

以上
bundle updateの後にはbundle installをしよう

railsチュートリアル第1章でのメモ。
超初歩的なミスです。

初投稿なので読みにくいかもしれませんが、ご勘弁を。

「1.5 デプロイする」でHerokuにデプロイしようとしても、アプリの画面が
```
Heroku | Welcome to your new app!
Refer to the documentation if you need help deploying.
```
という初期画面？から表示内容が変更されない。

また
`$git push origin master`
を実行すると、

```
remote:  !
remote:  !     Failed to install gems via Bundler.
remote:  !
```
というエラーが赤字で表示される。

どうやらgemのインストールが失敗しているのが原因みたい。
いろいろ調べてみたところ、なんと`$bundle update`の後に`$bundle install`をしていない（チュートリアルの1.3.1 Bundler）事が原因らしい。

実際に`$bundle uupdate`の後に`$bundle install`を実行したところ、無事エラーが出ずに成功。

`$bundle update`がインストールも兼ねてるのかと思ってた。。

確かにチュートリアル（1.3.1）には以下の記述があり、「**まず**bundle updateを実行しろ」と書いてあったが、僕はこの2文字を読み流してしまった。。
---
ちなみに、bundle installを実行すると「**まず**bundle updateを実行してください」というようなメッセージが表示される場合があります。その場合は、メッセージのとおりにbundle updateをまず実行しましょう (マニュアルどおりに行かない場合に慌てず落ち着いて対応することもスキルの１つです。こうしたエラーメッセージにはその場で問題を解決する方法が含まれているものなので、よく読んでおきましょう)。
---

プログラミングはやっぱり、**日本語力**が大事ですね！！笑
再帰処理を組み立てるときの考え方

ちんぷんかんぷんだった再帰処理の組み立て方について、少しつかめた気がするのでメモ。
##方針
「この関数はこういう引数を受け取ったらこういう値を返す」ということを、何も書かないうちに決めつけて、それに基づいて組み立てていくのがポイントな気がする。

例えば、f(n)の処理の中でf(n-1)を呼び出した場合、「あれ？f(n-1)ってどういう値を返すんだっけ？」と思ってしまってはダメだ。なぜなら、いままさにfを書いている途中なので、画面上のどこを見てもf(n-1)の挙動を表現するコードは完成していない。
（いままで僕はいつもここで混乱してしまっていた。）

そうではなく、「f(k)はこういう値を返すのだ」ということを、あらかじめ決めつけてから作業を始める。
そうすれば、f(n)の処理の中でf(n-1)を呼び出した場合にも、「f(n-1)はこういう値を返すはずだ」という決めつけに基づいて組み立てていくことができる。

そしてそのように組み立てていけば、最後にはその決めつけが実現するような関数を完成させることができる。

##例１：階乗
nを引数としてn!を返す関数f(n)を定義してみる。
考え方は以下のとおり。

まだ何も書かないうちから、「f(k)=k!である」と決めつける。
↓
n!を求めたい。n!=n*(n-1)!なので、(n-1)!が求められればn!も求められるな…
↓
「f(k)=k!である」という決めつけにより、(n-1)!=f(n-1)じゃん
↓
よし、n!=n*f(n-1)と書けるな

```python
def f(n):
    return n* f(n-1)
```

このままだと、引数がn→n-1→n-2→n-3→…と小さくなりながら永遠に再帰が続いてしまう。どこかでストップさせたい。
↓
「f(k)=k!である」という決めつけにより、f(1)=1!である。そして、1!=1であることは知っている。
↓
n=1となったときは、f(1)=1!=1として、再帰呼び出しをせずに直接値を返すことにする。

```python
def f(n):
    if n == 1:
        return 1
    else:
        return n* f(n-1)
```
これで完成。

##例２：マージソート
準備として、昇順ソート済みのleft,rightという2つのリストを引数として、それらを昇順ソートしつつ統合したarrayというリストを返すような、merge関数を用意する。merge関数自体には再帰処理はない。

```python

def merge(left,right):
    array = []
    while left!=[] and right!=[]:
        if left[0] < right[0]:
            array.append(left[0])
            left.pop(0)
        else:
            array.append(right[0])
            right.pop(0)
    if left == []:
        array.extend(right)
    else:
        array.extend(left)
    return array
```
準備が済んだので、mergesort関数をつくっていく。

①「mergesort(ソートされていないリスト)=ソートされたリスト」
と決めつける。
↓
最初に受け取る引数をarrayとする。ソートされたarrayを返したい。
↓
merge関数をつかえば、
②「ソートされたarray=merge(ソートされた左半分,ソートされた右半分)」
として求めることができる。
↓
ソートされた左半分と右半分をどこからもってくればよいか…。
↓
①「mergesort(ソートされていないリスト)=ソートされたリスト」
という決めつけを思いだす。
↓
③ソートされた左半分=mergesort(ソートされていない左半分)、
　ソートされた右半分=mergesort(ソートされていない右半分)ではないか
↓
②と③をくっつければ、
「ソートされたarray=merge(mergesort(ソートされていない左半分),mergesort(ソートされていない右半分)」
と書けるので、これをmergesort関数の返り値としよう。


```python
def mergesort(array):
    left  = array[:ceil(len(array)/2) ]
    right = array[ ceil(len(array)/2):]
    return merge(mergesort(left),mergesort(right))
```



しかしこのままでは、引数となるリストがどんどん短くなってゆき、長さが1になったところで引数のリストを左右に分割できなくなる（rightをつくるときのインデックス参照がエラーになってしまう）。
↓
引数となるリストの長さが1になった時点で左右分割をせずに直接値を返したい。
↓
①「mergesort(ソートされていないリスト)=ソートされたリストである」
という決めつけを思い出す。
↓
決めつけにより
「mergesort(長さ1のソートされていないリスト)=長さ1のソートされたリスト」
であるが、一般的に
「長さ1のソートされたリスト=長さ1のソートされていないリスト」
なので、
「mergesort(長さ1のソートされていないリスト)=長さ1のソートされていないリスト」
である。
↓
つまり、引数のリストの長さが1になったら、引数をそのまま返せばよい。

```python
def mergesort(array):
    if len(array) == 1:
        return array
    else:
        left  = array[:ceil(len(array)/2) ]
        right = array[ ceil(len(array)/2):]
        return merge(mergesort(left),mergesort(right))
```

##まとめ
以上、冒頭の「方針」に基づいて、2つの再帰処理を組み立ててみた。
考え方の順番がやや技巧的だと感じる。
まだ関数ができていないのに、その関数の返り値がどんなものになるかを決めつけてから関数をつくっていく。
そうすると最終的に、想定していたような返り値をだす関数が実現する。

コードの構造は一般的に以下のようになる。

```python
def f(para):
    if 終了条件:
        return f(para)の値を直接返す
    else:
        return f(paraとは異なる引数)を用いて、f(para)を返す
```
初学者による我流の理解なので誤り等あればご教授ください。
perl実行時にCertificate Authoritiesが無いと怒られた

環境：
macOS hight sierra
perl 5.18.2

connpassのAPIを叩いてくれるソースコードを実行したところで、次のエラーが起きました。

```
Fetch error: 500 Can't verify SSL peers without knowing which Certificate Authorities to trust at XXXXXXXXXXXXXXXXXXXXX
```

オレオレ証明書が足りないということなので、証明書を入れてあげましょう

```
#cpanmがインストールされている前提で、 Mozilla::CAのモジュールをインストールします
$ cpanm　Mozilla::CA
#モジュールがインストール成功か確認します。エラーがなければ成功です。
$ perl -MMozilla::CA
```

[Mozilla::CA](https://metacpan.org/pod/Mozilla::CA)はどんなことをしているかの原文を次のように記述されています。（理解はできていません）
>Mozilla::CA provides a copy of Mozilla's bundle of Certificate Authority certificates in a form that can be consumed by modules and libraries based on OpenSSL.

>The module provide a single function:

>SSL_ca_file()
>Returns the absolute path to the Mozilla's CA cert bundle PEM file.
Amazon WorkSpaces で開発をするためのまとめ (自分用)

開発環境の完全リモート化を目指して、Amazon WorkSpaces を使い始めました。
環境を整えていく過程の備忘録を自分用にまとめていきます。
ちなみに私の端末は Mac/Windows で、リモート側も Linux/Windows 両方使います。

* [Amazon WorkSpaces で Mac の英数キーとかなキーを有効化する](https://qiita.com/mosop/items/b2c9f81f891ef2d22023)
* [Amazon Linux WorkSpaces US イメージでシステムの起動時に日本語入力を有効化する](https://qiita.com/mosop/items/5cec4c64966bbd7c57ee)
* [Mac と Amazon Linux WorkSpaces の組み合わせでアンダーバーを入力する](https://qiita.com/mosop/items/c0170d31e910c76c8e43)
* [Amazon Linux WorkSpaces でシェルのプロンプトを短くする](https://qiita.com/mosop/items/08731e3d9b804b1eacef)
* [Amazon Linux WorkSpaces でマカーがつまづいたこと: (1) シェルのスタートアップの設定は .bashrc に書く](https://qiita.com/mosop/items/9c871c9ae50f9b59a013)
* [Amazon Linux WorkSpaces に Docker をインストールする](https://qiita.com/mosop/items/3784e1bf56b0d518e2c3)
* [続・Amazon Linux WorkSpaces US イメージでシステムの起動時に日本語入力を有効化する](https://qiita.com/mosop/items/d1b301c9b9fd23fa4c83)
* [Amazon Linux WorkSpaces で既定のフォントを Noto にする](https://qiita.com/mosop/items/c5ec8792988f6faeec71)
* [Linux で Web サービスをデスクトップアプリ風にする](https://qiita.com/mosop/items/859c4004717518be6c26)
* [Amazon Linux WorkSpaces でメニューのカスタマイズを GUI で行う](https://qiita.com/mosop/items/39d4cdbf482ee3759893)
* [Amazon Linux WorkSpaces 環境で使っているアプリ一覧 (自分用)](https://qiita.com/mosop/items/5d333ca060cdefac8355)
* [Amazon Linux WorkSpaces デスクトップ系 Tips](https://qiita.com/mosop/items/fce5615b7aa368414a93)
* [Amazon Linux WorkSpaces で CopyQ をセットアップする](https://qiita.com/mosop/items/c49fdc0c52a7756000f2)
* [Amazon Linux WorkSpaces で 2 段階認証が必要な Office 365 のメールアカウントを設定する](https://qiita.com/mosop/items/d9f8e2da95ee456ab973)
* [Amazon Linux WorkSpaces に最新の Evolution をインストールする](https://qiita.com/mosop/items/7abbe8717fc1b8402396)
* [続・Amazon Linux WorkSpaces でメニューのカスタマイズを GUI で行う](https://qiita.com/mosop/items/fb6bcc9390246c743520)
* [Amazon Linux WorkSpaces でデフォルトブラウザを Chrome に変更する](https://qiita.com/mosop/items/daa94bbe06a382b72948)
Amazon WorkSpaces で Mac の英数キーとかなキーを有効化する

2020 年 2 月 5 日追記

少なくともクライアントバージョン 3.0.2.928 から、英数キー・かなキーのいずれのキーもリモート側では全角/半角キーとして認識されるようになった模様です。根本的な解決方法はないと思われます :confused:

回避策として、Karabiner-Elements で英数キー・かなキーを空いているキーに強引にマップすることにしました。

---

Mac から Linux や Windows にリモート接続するときにハマるのが英数キーとかなキーの問題。ほとんどのリモートクライアントが対応していないので、Karabinar-Elements のようなアプリを使って、空いてそうなキーコンビネーションに無理やり割り当てるなどの荒療治が必要です。

それでは、件の Amazon WorkSpaces はどうかと言うと…。WorkSpaces のクライアントは Mac の英数キーとかなキーにネイティブで対応しています:heart_eyes:

マカーとしてはこれだけで WorkSpaces を選ぶ価値を感じますね！

キーを有効化するには、メニューの [オプション] → [詳細設定] から日本語を選択します。

![workspacesoptionsjp.png](https://qiita-image-store.s3.amazonaws.com/0/63688/070fb6e7-adfb-72fa-1d00-42cf85cbbd11.png)

キーボードの種類で自動判別してくれるわけではないので、せっかくの神対応に気づきづらくなってるのがもったいない…。

ちなみに、リモート側が Linux の場合、次のような感じでキーが割り当てられます。[^3]

| Mac のキー | Linux でのキーコード |
| --- | --- |
| 英数 | 49 (Zenkaku_Hankaku) |
| かな | 99 (Hiragana) |

もちろん、Windows OS でもちゃんとキーが割り当てられます！

[^3]: キーボードレイアウトの設定によって異なる可能性があります。
MacBook Air をリストアしたはなし


# やったこと
[macOSでの開発環境を全部Docker化したらリストア時間が1時間半になった](http://saboyutaka.hatenablog.com/entry/2018/08/23/023925)
この記事を見て、おっ出来そうだなぁ〜と思ったのがきっかけです。
３年半使ったMacBookはガタがきていたので以下の問題を解決するためにリストアを敢行しました。

- ディスクの容量が不足
- 使っていないアプリケーションが結構ある
- 動作が重たくなってきた

初めてのことで手間取り、気づけば朝だったので、次の時のためにも何をどの順番で行ったか記録しておこうと思います。開発環境を全部Docker化する余裕はありませんでした。

## バックアップを取る
これが一番時間とります。

- リストア後すぐに使いたいデータをGoogleDriveにアップロードしておく。
- 外付けハードルディスクを使ってTimeMachineでバックアップを取る。

記憶装置たくさん持ってないひとはクラウドドライブにリストア後すぐに使いたいデータをアップしておくと良いと思います。設定用スクリプトとか簡単にダウンロードできて便利です。

次は、環境を復元する準備よしましょう。やり方はいくつかあると思います。

- 利用しているアプリケーションを全て書き出す。
- 利用しているアプリケーションをダウンロードするスクリプトを書く。
- brew-fileで一括管理する。

自分はbrew-fileを利用しました。
システム環境設定はMacならdefaultsコマンドで設定できます。このコマンドは再起動しないと効果を確認できない点が不便ですが。調べると使い方がたくさんでいてくるので設定したい項目に関するコマンドをスクリプトにまとめて実行すると楽です。

## ディスクを初期化する
手順は次の通りです。

1. 「command + r」を押したままMacBookを起動する
2. ディスクユーティリティを開く
3. ディスクを選んで消去ボタンをクリック
4. ディスクユーティリティを閉じる
5. OSをインストールする

ディスクを初期化するとWifiの情報も一切消えます。パスワードなりをあらかじめ控えておきましょう。

## 環境を整える
まずHomebrewをインストールしましょう。
brewでbrew-fileをインストールします。
brew-fileで利用していたアプリケーションを全てインストールします。
システム環境設定を整えたら終わりです。

#　考察
リストアは慣れていないと半日かかります。注意しましょう。
因果分析を考える -その広告は本当に効果があったと言えるのか？-

#広告の効果を考えてみる
アプリを使ったWebサービスを提供するA社で、ある日このような会話が話されていました。あなたはこの会話を聞いてどう思いますか。

Xさん：「Yさん聞いてください！**Twitterに広告を掲載したことでDL数が倍以上に増えました！**」
Yマネージャー：「**広告の効果が出ているようですね。**引き続ぎ実施していきましょう。」

これだけを見ると、広告は非常に効果的であり、その広告による影響としてDL数が非常に増えたものと判断できそうです。しかし、このグラフを見るとどうでしょうか。
<img src="https://qiita-image-store.s3.amazonaws.com/0/212045/b4400bc3-ccae-12a6-1841-c1f5d6a290d8.png" width=75%>
Xさんの言うDL数の増加がa1からa2への変化であるとしましょう。確かに、a1からa2へのDL数の増加は一見すると著しいものであり、倍以上伸びていることもわかります。ただ、これが本当に**広告による効果といえるのでしょうか**。以降で説明する手法を用いるならば、**今回のケースは「広告による影響はない」と判断されます。**
Xさんはa1（前）とa2（後）を単に比較して広告の効果を語っていましたが、このような前後比較には欠陥がありそうです。次の節で考えていきましょう。

#単純な前後比較の問題
Xさんはa1とa2という二つの"点"を比較しました。このような点の比較ではDL数の推移の傾向がわかりません。グラフを見ると、A社のDL数の増加率は広告掲載前後で変化がないことがわかります。**傾向を無視した点の比較では因果関係を正しく分析することはできません。**

また、広告に効果があったことを示すためには以下を比較する必要があります。

- 広告を掲載した場合のDL数
- 広告を掲載していない場合のDL数

しかしながら、**実際に広告を掲載した以上、二つ目の「広告を掲載していない場合のDL数」を結果として確認することは不可能です。**
では、どうやって因果関係を分析すればよいのでしょうか。

#因果分析手法 -差分の差分法-
ここで登場する手法が差分の差分法(Difference-in Difference)です。その名の通り、差分の中の差分を分析することである事象の影響を分析します。
今回のケースでは、測定した2時点(a1, a2)という"差分"を明らかにしたうえで、「広告を掲載した場合のDL数」と「広告を掲載していない場合のDL数」との"差分"を明らかにすることで広告による影響がどれほどのものであったかを導き出すのです。以上の説明を踏まえて、グラフを見てみましょう。
※説明のため1つ目のグラフと異なる数値になっています
<img src="https://qiita-image-store.s3.amazonaws.com/0/212045/0e1c3524-4e6c-9515-64e5-6dca3f91e0af.png" width=77%>
差分の差分法では、「広告を掲載した場合のDL数」（処置群）と「広告を掲載していない場合のDL数」（統制群）の差分を算出します。しかし、先に述べた通り、実際に広告を出した以上は「広告を掲載しなかった場合」のデータを取得することは不可能です（反事実）。
そこで使われる方法として、**分析対象となる会社と類似する同業他社のDL数を「広告を掲載しなかった場合のDL数」とみなして分析対象（統制群）とします**。このとき、統制群が満たすべき条件は処置群と同様の傾向でアウトカム(DL数)が推移していることです。これは、差分の差分法の前提条件でもあり、**「平行トレンドの仮定」**と呼ばれます。

実際に差分の差分法で広告による影響を導き出してみましょう。本来は難しい公式が出てきますが、ここでは省略します。
まず、処置群と統制群それぞれで広告掲載前後の差分を算出します。特に難しいことはなく、処置群はa2-a1、統制群はb2-b1となります。次に、差分の"差分"を算出し、(a2-a1)-(b2-b1)が求められます。この**(a2-a1)-(b2-b1)**が広告の効果を示すことになります。グラフでは「広告による効果」と記載された部分がこれにあたります。

#最後に
統計学ガチ勢に見られたらぶん殴られそうな内容ではありますが、生暖かい目で見守っていただければ幸いです。
mysql2/promiseでnamedPlaceholdersオプションを有効にする

`createConnection()`または`createPool()`の引数に渡すオブジェクトの中に`namedPlaceholders = true`を記述する。

```javascript

const mysql2 = require("mysql2");

(async () => {
    const conn = await mysql2.createPool({
        host: 'localhost',
        user: 'root',
        database: 'mysql',
        namedPlaceholders: true, // <- ここ
    }).promise();

    const query = "SELECT User FROM user WHERE Host = :param"
    const param = "localhost";
    try {
        const [row, fields] = await conn.query(query, { param });
        console.log(row);
    } catch (e) {
        console.log(e);
    }
    return;
})();
```

promise化しない場合は上の方法でも[公式リファレンス](https://github.com/sidorares/node-mysql2/blob/master/documentation/Extras.md)通りでもどちらでもOKです。  
  
また、プレースホルダを有効にすると`?`や`??`は使えなくなります。  
ですが`?`や`??`をプレースホルダに置き換えて上げれば2重配列やINSERT文のSET句は同様に展開されるので問題ないはずです。