OmniAICreator/Qiita-1.07M huggingface dataset:
Dockerデータ専用コンテナを活用してバックアップとリストアを実現

Dockerでは、データ専用のコンテナを作成することができます。
本投稿では以下の図のようにデータの可搬性向上のために、データ専用コンテナを活用し、以下の処理を実現します。

## 実現する処理とイメージ

![DockerDataContainer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69983/a1d5b132-a2c1-b8a1-453d-bbafa3f8900f.png)

### 処理

* 通常のコンテナ c0004 からデータコンテナ d0001 のファイルを参照
* d0001のファイルをホストOSにバックアップ
* ホストOSにバックアップしたファイルをリスト用コンテナ c0005 でリストア

## 1.busyboxイメージの入手

Dockerでは、データ専用コンテナを作成するためには、通常のOSイメージではなく **busybox** と呼ばれるイメージを利用します。
busyboxは必要最低限のシェル環境を提供する場合によく利用されます。

```bash:shell
$ docker image pull busybox:latest
latest: Pulling from library/busybox
53071b97a884: Pull complete
Digest: sha256:4b6ad3a68d34da29bf7c8ccb5d355ba8b4babcad1f99798204e7abb43e54ee3d
Status: Downloaded newer image for busybox:latest
```

## 2. データ専用コンテナの生成

busyboxのイメージを活用してデータ専用コンテナ **d0001** を生成します。

```bash:shell
$ docker container run -it -v /data0001 --name d0001 busybox /bin/sh
/ # pwd
/
/ #
```

## 3. テスト用ファイルの作成

d001のコンテナの **/data0001/** ディレクトリ配下にテストファイルを作成します。

```bash:shell
$ docker attach d0001
/ # ls -a /data0001/
.   ..
/ # echo "Hello data container" > /data0001/datafile01.txt
/ # cat /data0001/datafile01.txt
Hello data container
/ #
```

## 4. 別コンテナからテスト用ファイルを参照

centos 7.5 イメージ生成した通常のコンテナからデータ専用コンテナ d0001 のテスト用ファイルが参照可能なことを確認します。

```bash:shell
$ docker container run -it --volumes-from d0001 --name c0004 -h 0004 centos:7.5.1804 /bin/bash
[root@0004 /]# cat /data0001/datafile01.txt
Hello data container
[root@0004 /]#
```

## 5. データ専用コンテナを活用してボリュームのバックアップ

busybox と tar コマンドを組み合わせることでデータ専用コンテナに保管されているデータをホストOS上にバックアップすることができます。
以下は、上記手順3で作成したテストファイルをホストOSのディレクトリにバックアップとして保存するバックアップの実行コマンドの例です。
**run --rm** コマンドでコンテナを起動することによりホストOSへのバックアップ終了後にコンテナが自動的に削除されます。

```bash:shell
$ mkdir hostdir
$ docker container run --rm --volumes-from d0001 -v /${host-os-dir}/hostdir:/ctdir busybox:latest tar cvf /ctdir/backup.tar /data0001
tar: removing leading '/' from member names
data0001/
data0001/datafile01.txt
$ ls hostdir  # ホストOS上にバックアップとして保存されているのを確認します。
backup.tar
$ tar tf hostdir/backup.tar
data0001/
data0001/datafile01.txt
```

## 6. ホストOSにバックアップしたデータを別コンテナにリストア

手順5でホストOS上にバックアップしたデータを別のコンテナにリストアします。

### リストア先コンテナの生成

```bash:shell
$ docker container run -it -v /data0001 --name c0005 -h c0005 centos:7.5.1804 /bin/bash
[root@c0005 /]# ls -l /data0001/
total 0
[root@c0005 /]#
$ docker container run -it -v /data --name c0005 -h c0005 centos:7.5.1804 /bin/bash
```

### リストアの実行と確認

```bash:shell
$ docker container run --rm --volumes-from c0005 -v /${host-os-dir}/hostdir:/ctdir busybox:latest tar xvf /ctdir/backup.tar -C /
data0001/
data0001/datafile01.txt
$ docker container attach c0005
[root@c0005 /]# cat /data0001/datafile01.txt
Hello data container
[root@c0005 /]#
```


## 参考文献

1. 古賀政純, "Docker実践ガイド 第２版", pp.112-117 (2019).
2. busybox _ Docker Documentation, https://docs.docker.com/samples/library/busybox/, Online; accessed 8-June-2019.
Pythonの変数名で避けた方がいい名前は？

##はじめに
[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている松井です。
＊プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

##変数名で避けた方がいい名前は？
変数名で避けた方がいい名前は``予約語``と``組み込み関数``です。

>予約語（よやくご、英: reserved word）とは、プログラミング言語において字句的には識別子（変数名、関数名、クラス名など）としてのルールを満たしているにもかかわらず、識別子にならない字句要素。
出典：[Wikipedia](https://ja.wikipedia.org/wiki/%E4%BA%88%E7%B4%84%E8%AA%9E)

予約語は上記の通りで、変数名に使えことができません。

Python(3.6.5)の時点で予約語は

```
 >>__import__('keyword').kwlist

['False','None','True','and','as','assert','break','class',
 'continue','def','del','elif','else','except','finally',
 'for','from','global','if','import','in','is','lambda','nonlocal',
 'not','or','pass','raise','return','try','while','with','yield']
```

の33個です。

しかし、変数名には使えるが、使わない方がいい名前もあります。
それが、``組み込み関数``です。

Python(3.6.5)の時点で組み込み関数は

```
>> print(len(list(name for name in vars(__builtins__) if (name[0].islower() and name not in ('quit', 'exit', 'copyright', 'credits', 'license',)) or name=='__import__')))

['__import__', 'abs', 'all', 'any', 'ascii', 'bin', 'callable', 'chr', 'compile', 'delattr',
 'dir', 'divmod', 'eval', 'exec', 'format', 'getattr', 'globals', 'hasattr', 'hash', 'hex',
 'id', 'input', 'isinstance', 'issubclass', 'iter', 'len', 'locals', 'max', 'min', 'next', 
'oct', 'ord', 'pow', 'print', 'repr', 'round', 'setattr', 'sorted', 'sum', 'vars', 'bool', 
'memoryview', 'bytearray', 'bytes', 'classmethod', 'complex', 'dict', 'enumerate', 'filter',
 'float', 'frozenset', 'property', 'int', 'list', 'map', 'object', 'range', 'reversed', 'set', 
'slice', 'staticmethod', 'str', 'super', 'tuple', 'type', 'zip', 'open', 'help', 'display', 
'get_ipython']
```

の70個です。

これらは変数名として、使えますが使わない方がいいとされています。
もし、変数名として使うと、衝突を起こしてコードが動かなくなるかもしれません。
KVM(WebVirtMgr)のWindowsへのUSBメモリのパススルーがうまくいかない

我が家ではUbuntu上にKVMの環境を用意して遊んでいるのですが、このKVMのWindowsにUSBメモリをパススルーで渡そうとしたらうまくいかなくしばらく悪戦苦闘することになったのでその時の解決方法を残しておきます。

# WebVirtMgr

WebVirtMgr: https://github.com/retspen/webvirtmgr/wiki/Install-WebVirtMgr

WebVirtMgrはKVMをWebUIから管理できるツールでoVirtとかの仲間です。微妙に機能が充実していなかったりもするのですが、軽量で、UIも今時のクラウドっぽいので気に入って使っています。

- VMのconfig画面
![スクリーンショット 2019-06-08 23.30.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86684/c02ac5b9-e120-e96b-a723-7dc6c5e55554.png)

- 新規VM作成画面
![スクリーンショット 2019-06-08 23.30.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86684/23671edd-0ceb-5bdd-bde9-d7606846a545.png)

# WebVirtMgrでUSBパススルー

残念ながらWebVirtMgrはWebUIからのUSBパススルー機能のようなものはありません。しかしVMのxmlの編集をWeb上からできるのでここでxmlに設定を追加して行います。

![スクリーンショット 2019-06-08 23.35.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86684/1a29f567-5fa6-e841-e004-2f50e919b6b9.png)

# USBパススルーがうまくいかない

xmlを編集してパススルーをする場合以下のような設定を`<device>`の中に追記すると思います。

```
  <device>
    <!-- ここから下のhostdevをdevice内に追記(要vendor id, product id編集) -->
    <hostdev mode='subsystem' type='usb' managed='no'>
      <source>
        <vendor id='0x****'/>
        <product id='0x****'/>
      </source>
    </hostdev>
    <!-- ここまで -->
  </device>
```

ここまでWindowsのVMを起動すると以下のように正しく認識されませんでした。

![スクリーンショット 2019-06-08 23.46.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86684/7d058602-9be8-dee2-d137-2aa225184cd1.png)

# 解決方法
xmlの中に`type='usb'`の`controller`の記述があります。

```
<controller type='usb' index='0' model='piix3-uhci'>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
```

これを一度VMを停止してからxmlを編集し上記の`controller`を削除して(削除しなくても良いかも)
同じ場所に

```
<controller type='usb' index='0' model='nec-xhci'>
</controller>
```

を追記します(中身は保存すれば勝手に追記される)。
これでVMを再起動するとUSBメモリが見えるようになっているはずです。

これは、USBが2.0ではなく3.0であることが原因のようです。詳しくは
- https://samuel.dalesjo.net/?p=57
- https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/virtualization_administration_guide/sect-guest_virtual_machine_device_configuration-configuring_device_controllers
あたりが参考になると思います。
VirtualBoxとUbuntuとArduinoでLチカ

#概要
最終的にはROS+Arduinoを試したかったのですが、まず第一歩として、VirtualBox上でUbuntuを起動、ArduinoをつないでLチカのやり方のメモ。
同じような道を進む人の参考になれば幸いです。
(ESPr Developer(ESP-WROOM-02)の場合を追記しました。(2020/05/09))

#マシン構成
windows10(ホスト側) + VirtualBox + Ubuntu16.04 + Arduino UNO

#進め方
実施した項目は以下の通りです。
※VirtualBox,Ubuntu,Arduino IDEのインストールは済んでいるものとします

1. VirtualBoxのUSBの設定
2. Arduinoと接続するポート番号の確認(Ubuntu側)
3. 2.で確認したポートのパーミッションの変更(Ubuntu側)
4. スケッチの作成(Ubuntu側)
5. 動作確認(Ubuntu側)

## 1. VirtualBoxのUSBの設定
* VirtualBoxを起動する前にArduinoをマシンに接続します。
* 次にVirtualBoxを起動して、  
`設定`→`USB`  
で、USBコントローラーを有効化、にチェックを入れます。
* USB1.1(OHCI)コントローラーで、右側の上から2番目、+がついたボタンを押すと、現在ホストマシンに接続されているUSB機器が表示されるので、Arduinoを選択するとデバイスフィルターに追加されます
　※Arduinoを接続してすぐには認識されません、ちょっと待つと出てきます
* OKを押して、マネージャーの画面に戻り、Ubuntuを起動します
* なお、ESPr Developer(ESP-WROOM-02)を接続した場合は、「FTDI FT231X USB UART」と表示されます、Arduinoとは表示されないので注意が必要です。

## 2. Arduinoと接続するポート番号の確認
* ArduinoをUSBでPCと接続します
* 以下のコマンドで、USBに接続されているポート名を確認します  
`ls -l /dev/serial/by-id/`  
 USBに何も接続されていない場合は、"アクセスできません"、と言われてしまいますが、Arduinoが接続されていれば、私の場合は以下の名称が出てきました  

`../../ttyACM0` (Arduino UNOの場合)
`../../ttyUSB0` (ESPr developerの場合)

## 3.　2.で確認したポートのパーミッションの変更
Ubuntu(Linux)ではwindowsと違ってポートを使用するのにパーミッションを変更する必要があります。

* 下記コマンドで、Arduinoを接続しているUSBのパーミッションを確認します  
※Arduinoと接続した状態でないとアクセスできないと怒られます  
`ls -la /dev/ttyACM0` 
* 書き込み権限がなければchmodコマンドでパーミッションを変更します  
`sudo chmod 666 /dev/ttyACM0`  
* 最初のコマンドでパーミッションを確認します  
`crw-rw-rw-`となっているはずです

## 4. スケッチの作成(Ubuntu側)
3.でパーミッションが正しく設定されていれば後はArduinoIDEで作業するのみです。
今回はLチカなので以下のスケッチを書き込みました、1秒毎に点灯と消灯を繰り返す例のやつ。
使用したピンは13番とGNDです。

```
void setup() {
  // put your setup code here, to run once:
  pinMode(13,OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(13,HIGH);
  delay(1000);
  digitalWrite(13,LOW);
  delay(1000);
}
```

あとは`ツール`→`シリアルポート`でArduinoを接続しているポートを選び、スケッチを書き込めばOK。

## 5. 動作確認
1秒毎に点灯、消灯が繰り返されればOKです。



Windowsをメインで使っている方(私も)は、ポートのパーミッションが最大の落とし穴かもしれません。
次回はいよいよROSを使用してのLチカになります(はず)、それでは。
Minikube内にDockerイメージを用意する

DockerイメージをビルドしてMinikubeから利用できるようにする。

```
$ eval $(minikube docker-env)
$ env | grep DOCKER
```
```
DOCKER_HOST=tcp://192.168.XXX.XXX:2376
DOCKER_TLS_VERIFY=1
DOCKER_CERT_PATH=/home/[ユーザ]/.minikube/certs
```

このMinikube内のDockerを参照している状態でDockerイメージをビルドすればよい。

元の状態に戻すには、

```
$ eval $(minikube docker-env -u).
```

で環境を元に戻す。
SQLのGROUP BY句で混乱したので考えをまとめてみる


#GROUP BY句
まずはちょっと今回のサンプルテーブルを、、、
下記の表は、4人の名前と国語と数学のテストの点数とクラスをまとめた表を使います！

```table:student_scores
|     name | jp_score | math_score | class_cd |
|----------|----------|------------|----------|
|   tanaka |       60 |         80 |      1-A |
|    satou |       70 |         70 |      1-B |
|   suzuki |       80 |         60 |      1-A |
| yamamoto |       50 |         30 |      1-A |
```

#ハマったこと

GROUP BYしてみよっと！

``` sql:group_by.sql
SELECT
  class_cd
  ,jp_score
  ,math_score
FROM
  test_score
GROUP BY
  class_cd
;
```

察しのいい方はお気づきかもしれませんが、出力結果はこんな感じになります！

```result:result
| class_cd | jp_score | math_score |
|----------|----------|------------|
|      1-A |       60 |         80 |
|      1-B |       70 |         70 |
```

あれ？？？？
GROUP BY句でまとめた1-Aクラスのレコードって***tanakaさんの点数になってるよ？？***
どうしてこうなるんだろ？っていうのがなかなか理解できなかった！


#GROUP BYしたときの表の形（自分なりの考え）
リファレンスとかサイトとかいろいろ流し読みしてみたけどなかなか理解できなかったので、2次元配列的に考えてみることにした。

test_scoreテーブルを2次元配列にするとこんな感じ

```java:table
Array[[]] table = [ 
	            ["tanaka",   60, 80, "1-A"]
	           ,["satou",    70, 70, "1-B"]
	           ,["suzuki",   80, 60, "1-A"]
	           ,["yamamoto", 50, 30, "1-A"]
	           ];
```
わかりやすくしたくて、内包型配列で書いちゃったけど、、、笑


これをGROUP BYしたらどうなるのかっていうのを自力で考えました！
こちらです！

```java:group_by
Array[[[]]] table = [
  [["tanaka", 60, 80], ["suzuki", 80, 60], ["yamamoto", 50, 30] ,"1-A"]
 ,[["satou", 70, 70]                                            ,"1-B"]
];
```
GROUP BYで選択したカラム以外のカラムをひとつの配列にまとめてるのかな？
それで
>SELECT
  jp_score, math_score

したときは`table[0][1]`と`table[1][0]`だけが出力されるイメージなのかな？
これなら1-Aグループがtanakaくんしか表示されなかった理由も納得だし！

#結論
group by したら、選択したカラムの値1 要素として選択されなかったカラム値群は配列になる！（と考えた）

#終わりに
初学者なので間違っているかもしれませんが、厳しくご指摘してくださったら幸いです！
つたない内容でしたが、ここまで読んでいただきありがとうございました☆

（、、、もしかしてプロパティ配列位にしたほうがよかったかな？でも書き方わからないなあ、、、）
UE4のコードプラグイン「Path Follow」が便利！

#「Path Follow」とは？
UE4のマーケットプレイスで￥2334で購入できるコードプラグインで、スプラインに沿って何かを動作させる処理を作るときにお役立ちです。
[Path Follow by Cooper in Code Plugins - UE4 Marketplace](https://www.unrealengine.com/marketplace/ja/slug/path-follow)

ちなみに2019年6月の無料アセットに含まれています。急いで入手しましょう！
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325493/8016e5e3-ff10-3bc8-62ae-03285031d467.png)

#何ができるの？
- 標準のスプラインと互換性がある
- スプラインに沿って移動させられる
- プレイヤーの入力でも移動させることができる
- 移動速度を正確に制御できる
- 位置のみや回転のみスプラインに合わせることができる
- スプライン自体を実行時に変更することができる
- ループ、逆再生などの機能がある
- エディタに表示されるスプラインの色が変更できる

だいたいこんな感じのことができます。さらに詳しく知りたい方は以下のサイトを参照してください。
[ドキュメント](https://docs.google.com/document/d/1NzWqKRJAKdzB5Ogm0jdPHfNX2wJRTW8qRQ4mEJ3Bs9w/edit)
[サンプルプロジェクト](https://mega.nz/#F!ylJU2ZaJ!stqaE3xz_MhYhCm1-e9oyA)
[マーケットプレイス：新着プラグイン情報 - Unreal Engine](https://www.unrealengine.com/ja/blog/new-free-and-paid-plugins-arrive-inside-the-unreal-engine-marketplace)
[チュートリアル動画](https://www.youtube.com/watch?v=S_wtvuyZi08)

#とりあえず使ってみた
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ボールが奥に転がってくエンドレスランでスプラインに追従させるところで色々悩んでたんだけど、今月の無料コンテンツのPathFollowを使ってみたらすごく簡単に実装できた。<br>エディタに表示されるスプラインの色が変えられたりして便利！<a href="https://twitter.com/hashtag/UE4?src=hash&amp;ref_src=twsrc%5Etfw">#UE4</a> <a href="https://t.co/hpIktT8gAu">pic.twitter.com/hpIktT8gAu</a></p>&mdash; Naotsun@C++&amp;UE4勉強中 (@Naotsun_UE) <a href="https://twitter.com/Naotsun_UE/status/1137359540612059136?ref_src=twsrc%5Etfw">2019年6月8日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

こんな感じのものを作りました。

###手順
1. スプラインのクラスを作成します。（Actorクラス）
2. コンポーネントの追加から「PFPath」を追加します。これがスプラインの代わりになります。
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325493/4261183f-b849-0244-656b-04c9b5c6f138.png)
3. 次にスプライン上を移動するクラスを作成します。（ActorクラスでもPawnクラスでもOK）
4. コンポーネントの追加から「PFPathFollower」を追加します。
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325493/06d6a422-7c5b-caa8-7810-e3badaf1d21c.png)
5. 作成したものをレベルに配置します。スプラインをお好みの形に伸ばしてください。
![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325493/3ef1504d-6ca8-b017-a8e3-9369f0ccdc42.png)
6. 配置したものの詳細から「PFPathFollower」コンポーネントを選択し、その中の[General] - [PathOwner]にスプラインを指定します。
![5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325493/d82cc61d-d68d-4a86-7a08-872f5cdba765.png)
7. 再生してスプライン上を移動するのを確認します。

###移動速度を変えたい
「PFPathFollower」コンポーネントを選択し、その中の[Speed] - [Speed]の値を変更し、移動スピードを調節します。
![6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325493/a16d6625-fd45-da39-2557-53b75f3807b3.png)

###エディタに表示されるスプラインの色を変えたい
「PFPath」の[Path] - [PathColor]からスプラインの色を変更できます。
[Path] - [Draw if Not selected] はオンにすると、選択されていない時に指定した色で描画します。
[Path] - [Draw if selected] はオンにすると、選択されている時に指定した色で描画します。
![7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325493/be66492a-a932-03f7-b8f3-330b2ed56d9f.png)



私も少ししか触っていないのであまり機能を把握できていないですが、かなり多機能なようなので皆さんも色々と試してみてください！
サーバーの背景画像をPowerShellで作る

サーバーの種類×環境数で作らないといけないので、書き捨てPowerShell。

```PowerShell
#.NETの機能を呼び出す
Add-Type -AssemblyName System.Drawing
#画像サイズ指定
$image = New-Object System.Drawing.Bitmap(1600, 900)
$g = [System.Drawing.Graphics]::FromImage($image)
#背景用ブラシ（#006400）
$bg = New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(0, 100, 0)) 
#背景を塗りつぶし
$g.FillRectangle($bg, 0, 0, 1600, 900)

#文字用ブラシ（アルファ値100）
$b = New-Object System.Drawing.SolidBrush([System.Drawing.Color]::FromArgb(100, 255, 255, 255))
#フォントの指定
$font = New-Object System.Drawing.Font("Yu Gothic Medium", 50) 
#左50px、上50pxに描画
$g.DrawString("検証環境 XXサーバー", $font, $b, 50, 50)

#デスクトップにPNG形式で保存
$image.Save($Home + "\Desktop\Wallpaper.png", [System.Drawing.Imaging.ImageFormat]::Png) 
```

完成品
![Wallpaper.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53651/bf67a112-7ae8-c538-fb23-d89e3fe2c840.png)
mysqlの起動エラー対応 in mac

# Hello, mysql

（忘備録）

久しぶりにmysqlに接続しようと、声を掛けると無視されることがある。それどころか`[ERROR]`と怒られる。


## mysqlの怒り1

だいたい最初はこんな感じでやってくる。

```terminal
$ mysql -uuser -ppassword
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
```


はいはい、ファイルを作成すればいいのね、毎回作ってあげます。

```terminal
$ touch /tmp/mysql.sock 
```


## mysqlの怒り2

もう大丈夫かなと、再度mysqlに繋げようとする。

```terminal
$ mysql -uuser -ppassword
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38)
```


が、こんな感じでまだ怒る。怒り心頭なのか、レベルが19倍になってしまった()。

*※この数値の違いについては全く把握および理解できておりません。申し訳ありません。*

## mysqlの怒り3

もしかして、mysqlsサーバが立っていないのでは？
mysqlサーバを立ち上げようとする。

```terminal
$ mysql.server restart
 ERROR! MySQL server process #72998 is not running!
Starting MySQL
. ERROR! The server quit without updating PID file (/usr/local/var/mysql/xxxxnoMacBook-Pro.local.pid).
```

彼女の欲している`/usr/local/var/mysql/xxxxnoMacBook-Pro.local.pid`なるものがないから駄々をこねているのかと思い、作ってあげる。

```terminal
$ touch /usr/local/var/mysql/xxxxnoMacBook-Pro.local.pid
```

さすがにこれでもう問題ないだろう。。


## mysqlの怒り4

```terminal
$ mysql.server restart
 ERROR! MySQL server process #72998 is not running!
Starting MySQL
. ERROR! The server quit without updating PID file (/usr/local/var/mysql/xxxxnoMacBook-Pro.local.pid).
```

、、、変わらない。
何がいけないのか、はっきり言ってくれているのか確認するため
`/usr/local/var/mysql/xxxxnoMacBook-Pro.local.err`を覗いてみた。

が、さっき行ったはずのERRORログは追記されておらず、前回実行した１ヶ月前ほどのログしか残っていない。。


ようやくわかった。
**`/usr/local/var/mysql/`配下は彼女が扱えない**ようになっていたのだ。


## 大事なのはパーミッション

mysqlがどのユーザでどのグループなんだっけ？`Homebrew`でインストールしたから覚えてない。
ええい、めんどくさい。とりあえずこうしてやれ！

```terminal
$ sudo chmod -R 777 /usr/local/var/mysql/ 
```

からの

```terminal
$ mysql.server start
 ERROR! MySQL server PID file could not be found!
Starting MySQL
.. SUCCESS! 
```

PIDファイルが見つからないと怒られはしたものの、無事起動はできた。めでたし。

（*PIDファイルは結局なくてもよいのだろうか、、？*）


### 補足

ちなみに、ユーザとグループ一覧を確認するには、それぞれ以下のコマンドで可能なようです。

```terminal
$ dscl . list /Users
$ dscl . list /Group
```

色々なサイトを参考にしましたが、提示されている解決策は結構バラバラで、というのもmysqlが起動時エラー発生する理由も様々で、、

例えば、`/usr/local/var/mysql/`配下を再帰的に、ファイル所有者とグループを`mysql`に変えろだの、自身のユーザ名に変えろだの、色々書かれていました。
あと、既に動いているプロセスがあればそれをkillするのも鉄則ですね。

これと言ったベストプラクティスみたいなものは特に見つかりませんでしたが、どんな事をするにも共通して言えますが、とにかくエラーログを確認するのが１番早いです。
（今回でいえばこれ -> `/usr/local/var/mysql/xxxxnoMacBook-Pro.local.err`）


### 参考サイト

https://qiita.com/carotene4035/items/e00076fe3990b9178cc0
http://d.hatena.ne.jp/ksaito11/20110508/1304756757
MYSQLをCDせずに呼び出す

偶然他の人のところで見つけたので覚書


コマンドプロンプト、管理者権限で実行

```
SETX /M PATH "%PATH%;C:\Program Files\MySQL\MySQL Server 5.7\bin"
```

```
SETX /M PATH "%PATH%;(パス名)"
```

参考）
https://qiita.com/ka215/items/ecb8eddc4fd392d0e9bd
https://qiita.com/rohinomiya/items/cf5236678b3459da9017




ついでに止め方と起動の仕方）

```
sc stop MySQL57
sc start MySQL57
```
DOMを操作するJavaScriptのエラー

#調べるきっかけ
HTMLのDOMを操作するJavaScriptを書いていて、エラーが起きたから

#エラーの原因
・操作したいDOMの構築の前に、そのDOMを操作するJSを書いていたから
・JavaScriptの実行は、htmlがパース中にscriptタグがあった時に実行される。

```html:index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <!--ここで読み込んでいたからエラーだった-->
    <!--<script type="text/javascript" src="sample.js"></script>-->
</head>
<body>
    <div id="inner"></div>

    <!--操作対象のDOMが構築し終わったここで呼び出すべき-->
    <script type="text/javascript" src="sample.js"></script>
</body>
</html>
```
```javascript:sample.js
i =  document.getElementById("inner");
i.innerHTML = "Hello";
```
#defer属性とasync属性
- defer属性：非同期で読み込みDOM構築後に実行。
 - この場合スクリプトの位置は関係ない
- async属性：非同期で読み込み完了次第実行
Svelte3 配列の操作方法の色々をメモる


[ドキュメント](https://svelte.dev/docs#script)のReactiveの説明によると
Svelteは`push()`とか`splice()`での配列操作では画面の自動更新されないので
配列要素の追加・更新・削除で画面自動更新したいときの実装をメモっていきます。

> Because Svelte's reactivity is based on assignments, using array methods like .push() and .splice() won't automatically trigger updates. Options for getting around this can be found in the tutorial.


ここに書いてあるコードは ↓ に貼り付ければ動きます。
https://svelte.dev/repl/hello-world?version=3.4.4

# ダメなやり方
`push()`, `splice()` 等々の関数を呼び出しただけでは画面は自動更新されません。

```html
<script>
	let array = [1, 2, 3, 4, 5];
	
	function ng() {
		array.push(array.length + 1)
	}
</script>

<div>[{array.join(', ')}]</div>
<button on:click={ng}>ng</button>
```


# 要素の追加
## 先頭に要素を追加する
```html
<script>
	let array = [];

	function ok1() {
		array.unshift(array.length + 1)
		array = array
	}

	function ok2() {
		array = [array.length + 1, ...array]
	}
</script>

<div>[{array.join(', ')}]</div>
<button on:click={ok1}>ok1</button>
<button on:click={ok2}>ok2</button>
```

## 末尾に要素を追加する
```html
<script>
	let array = [];

	function ok1() {
		array.push(array.length + 1)
		array = array
	}

	function ok2() {
		array = [...array, array.length + 1]
	}

	function ok3() {
		array[array.length] = array.length + 1
	}
</script>

<div>[{array.join(', ')}]</div>
<button on:click={ok1}>ok1</button>
<button on:click={ok2}>ok2</button>
<button on:click={ok3}>ok3</button>
```

## 指定位置にN個の要素を追加
おとなしく`splice()`した後に変数上書きするのが簡単そう・・・。

```html
<script>
	let array = [1, 2, 3, 4, 5];

	function ok1() {
		array.splice(1, 0, array.length)
		array = array
	}
</script>

<div>[{array.join(', ')}]</div>
<button on:click={ok1}>ok1</button>
```

# 要素の更新
あえて`splice()`を使うメリットはないが。

```html
<script>
	let array = [1, 2, 3, 4, 5];
	let cnt = 0;

	function ok1() {
		array.splice(1, 1, ++cnt)
		array = array
	}

	function ok2() {
		array[2] = ++cnt;
	}
</script>

<div>[{array.join(', ')}]</div>
<button on:click={ok1}>ok1</button>
<button on:click={ok2}>ok2</button>
```

# 要素の削除
## 先頭を削除
`splice()`で先頭以外を取り除いた戻り値を詰め直してもよい。

```html
<script>
	let array = [1, 2, 3, 4, 5];

	function ok1() {
		array.shift()
		array = array
	}

	function ok2() {
		array = array.splice(1)
	}
</script>

<div>[{array.join(', ')}]</div>
<button on:click={ok1}>ok1</button>
<button on:click={ok2}>ok2</button>
```

## 末尾を削除
`splice()`で先頭〜後ろから２番目を取り除いた戻り値を詰め直してもよい。

```html
<script>
	let array = [1, 2, 3, 4, 5];

	function ok1() {
		array.pop()
		array = array
	}

	function ok2() {
		array = array.splice(0, array.length - 1)
	}
</script>

<div>[{array.join(', ')}]</div>
<button on:click={ok1}>ok1</button>
<button on:click={ok2}>ok2</button>
```

## 指定位置からN個の要素を削除
おとなしく`splice()`した後に変数上書きするのが簡単そう・・・。

```html
<script>
	let array = [1, 2, 3, 4, 5];

	function ok1() {
		array.splice(1, 1)
		array = array
	}
</script>

<div>[{array.join(', ')}]</div>
<button on:click={ok1}>ok1</button>
```
素数判断をしてみよう

はい、インターン先でプログラミングを勉強しているものです。
今回はHacker Rankで素数かどうか判断するプログラムを作らなければいけなかったので、そのメモ程度に投稿したいと思います。

##素数判断をしてみよう
まず、Hacker Rankで「Prime」という謎の英単語出てきて困惑しました。
こちらをGoogleさんに翻訳してもらったところ、素数という意味っぽいです。
そして、問題としては、入力された数字が素数かどうか判断し、素数であれば「Prime」と出力し、そうでなければ、Not primeと出力せよ、というものでした。
自分が実際に調べながら作ったコードが以下のものです。

```
class Prime_Number:
    def Prime_determine(self,data):
        if data==1:
            print('Not prime')
        elif data==2:
            print('Prime')
        else:
            for i in range(2,data):
                if data%i==0:
                    print('Not prime')
                    break
                if i==data-1:
                    print('Prime')
                
                 

T=int(input())
my_prime=Prime_Number()
for i in range(0,T):
    data=int(input())
    my_prime.Prime_determine(data)
```

##しかし、問題が・・・
こんな感じになりました。
ほぼ初めてクラスというものを使いました。
ここまでくぐりぬけてきたカリキュラム地獄が意外と役に立ち、思ったよりも理解していました。
そして、使ってみてこんな感じに実装できました。
ただ、このコードだと処理回数が多くなり、データが大きくなると処理できなくなってしまい、Hacker Rankの問題でもデータが大きいとダメでした。
答えを見てみるとimport mathを利用しており、まだ未知の世界なので今回はこんなもんにしておきます。
最後まで読んでいただきありがとうございます。

##参考にさせてもらったもの
素数判断のコード　https://kconputing.hatenablog.com/entry/2017/02/19/190421
MySQLのストアドプロシージャでページャー作成


プロシージャ削除

```sql
DROP PROCEDURE IF EXISTS PAGER;
```

プロシージャ作成

```sql
DELIMITER //
CREATE PROCEDURE PAGER(
 IN PAGE   INT(10), /* 表示したいページ */
 IN LIMITCNT  INT(10), /* ページ表示件数 */
 IN TOTALITEM  INT(10), /* トータルアイテム数 */
 OUT FIRSTLIMIT  INT(10), /* 最初の件番 */
 OUT TOTALPAGE  INT(10)  /* トータルページ数 */
)
BEGIN
 DECLARE EXIT HANDLER FOR SQLWARNING, NOT FOUND, SQLEXCEPTION
 BEGIN
  SET FIRSTLIMIT := 0;
  SET TOTALPAGE := 0;
 END;

 SET FIRSTLIMIT  := 0;
 SET TOTALPAGE  := CEIL(TOTALITEM / LIMITCNT);

 IF PAGE > 1 THEN

  SET FIRSTLIMIT  := (TOTALITEM / TOTALPAGE) * (PAGE - 1);

 END IF;

END;
//
DELIMITER ;
```

使い方

 - @FIRSTLIMIT に最初の件数
 - @TOTALPAGE にトータルのページ数

```sql
CALL PAGER(2, 10, 100, @FIRSTLIMIT, @TOTALPAGE);
SELECT @FIRSTLIMIT AS FIRSTLIMIT, @TOTALPAGE AS TOTALPAGE FROM DUAL;
```
macのバッチファイルの拡張子をexeと思っていた件

# macでバッチファイルを作成するには
mac exe で検索をかけていたけどそんな必要なかったらしいのでメモ。
.exeではなくこう。

``````
hogehoge.command
```



mac のバッチファイルは拡張子を.commandにすればいいらしい。
exeファイルを作ろうと悩んでいた時間が無駄に感じた...

mac赤ちゃんなのでお勉強が必要でちゅね〜
よく遭遇する文字コードと、その罠

文字コードの世界はUTF-8全盛ですが、他の文字コードもまだまだ使う機会があります。

まぁ、誰でも知っていることだと思いますが、最近後述する「罠」にハマったので、この機会にドキュメント化しておこうと思います。

# よく遭遇する文字コード


| 文字コード名 | 文字集合 | 遭遇する場所 | 備考 |
|:-- |:-- | :-- | :-- |
| [UTF-8](https://ja.wikipedia.org/wiki/UTF-8)  | ユニコード文字集合（≒あらゆる文字） | どこでも | 現在のデファクトスタンダード |
| [UTF-16](https://ja.wikipedia.org/wiki/UTF-16) | ユニコード文字集合（≒あらゆる文字） | 一部のプログラムの内部表現 | | 当初本命だったが、サロゲートペア問題によって廃れた | 
| [UTF-32](https://ja.wikipedia.org/wiki/UTF-32) | ユニコード文字集合（≒あらゆる文字） | 一部のプログラミング言語の内部表現 | 文字種にかかわらず1文字=4バイト。シンプルだが、メモリ効率は悪い |
| [Punycode](https://ja.wikipedia.org/wiki/Punycode) | ユニコード文字集合（≒あらゆる文字） | 日本語ＵＲＬ | ユニコードの文字をアルファベット・数字・ハイフンで表す |
| [Shift_JIS（sjis）](https://ja.wikipedia.org/wiki/Shift_JIS) | 英数字+日本語 | 古いWindows周り | ASCII前提のプログラムがバグる「ダメ文字」という問題がある |
| [CP932](https://ja.wikipedia.org/wiki/CP932) | Shift_JISの文字 + 人名漢字など | 古いWindows周り | 後述の罠がある |
| [EUC-JP](https://ja.wikipedia.org/wiki/EUC-JP)  | 英数字+日本語 | 古いUnix周り |
| [ISO-2022-JP](https://ja.wikipedia.org/wiki/ISO-2022-JP) | 英数字+日本語（半角カナを含まない） | メール | 
| [CP50221](https://ja.wikipedia.org/wiki/CP50221)  | ISO-2022-JPの文字 + 半角カナなど | メール | 後述の罠がある |

なお、新規コードでは基本的には、**どこでもUTF-8を使えば問題ありません**。扱える文字種は多く、ASCIIの上位互換であり、Shift_JISのダメ文字のような罠もありません。

 もし、他に重要な文字コードがあれば、コメント欄でご指摘いただければと思います（マイコン時代の各社独自の文字コードなど、マイナーな文字コードはたくさんあると思いますが、流石に現在扱うことはないので無視します。）。

# 罠：Shift_JISが実際にはCP932だったり、ISO-2022-JPが実際にはCP50221だったりする

CP932はMicrosoftがShift_JIS人名漢字などを追加した文字コードです。

別に新しい文字コードを作るのはいいのですが、Windows界隈では**Shift_JISと表示されているのに実際にはCP932**が使われていることがしばしばあります。

ISO-2022-JPとCP50221も同様。メーラーで文字コードをISO-2022-JPと設定しているのに半角カナや人名漢字を使えることがあるのは、実際にはCP50221でエンコードしているからです。

そして、さらに混乱するのは人々がShift_JISとCP932を混同している（Shift_JISに人名漢字が含まれると思っている）ことがしばしばある一方、Pythonなどのプログラミング言語では`Shift_JIS`を本来の文字コードとして扱い、CP932のファイルを`Shift_JIS`でデコードしようとするとエラーになることです。

「Shift_JIS」「ISO-2022-JP」を見たときは、実際の文字コードはなんなのか確認しましょう。
よくある記法のスプリットタイムをラップタイムにする

##経緯
Googleスプレッドシートにて。
スプリットタイム→ラップタイムを計算させたいのに、分未満の *ss.00* は浮動小数点扱いになり、分超えの *m:ss.00* は文字列扱いになっていた。
これを数式ゴリ押しでシリアル値計算に揃えて計算させてみた。
##注意点
- 50Mスプリット=M6、100Mスプリット=N6 として、50M-100Mのラップを算出
- どちらかが空欄だったときの対応も入れている
- Googleスプレッドシートで作成 → Excelで動作確認しているので両対応のはず
- **Excelは *m:ss.00* と入力した値をシリアル値として認識してくれるようです**
 - 引く側引かれる側両方がそうなっていれば下記の数式を使わなくとも普通に計算できますが、片側が *s.00* (つまり分未満）だった場合、 `シリアル値 - 浮動小数点値` となるため、下記の数式ごときではマトモな結果になりません。

##数式
```VB
=IF(
    N6=0,
    "",
    TIME(
        IF(
            LEN(N6)-LEN(SUBSTITUTE(N6,":",""))>1,
            LEFT(N6,FIND(":",N6)-1),
            0
        ),
        IF(
            LEN(N6)-LEN(SUBSTITUTE(N6,":",""))>1,
            MID(N6,FIND(":",N6)+1,FIND(":",N6,FIND(":",N6)+1)-FIND(":",N6)-1),
            IF(
                LEN(N6)-LEN(SUBSTITUTE(N6,":",""))>0,
                LEFT(N6,FIND(":",N6)-1),
                0
            )
        ),
        IF(
            LEN(N6)-LEN(SUBSTITUTE(N6,":",""))>1,
            RIGHT(N6,FIND(":",N6,FIND(":",N6)+1)),
            IF(
                LEN(N6)-LEN(SUBSTITUTE(N6,":",""))>0,
                RIGHT(N6,LEN(N6)-FIND(":",N6)),
                N6
            )
        )
    )
    +TIMEVALUE("0:00:00"&RIGHT(N6,LEN(N6)-FIND(".",N6)+1))
    -IF(
        M6=0,
        0,
        TIME(
            IF(
                LEN(M6)-LEN(SUBSTITUTE(M6,":",""))>1,
                LEFT(M6,FIND(":",M6)-1),
                0
            ),
            IF(
                LEN(M6)-LEN(SUBSTITUTE(M6,":",""))>1,
                MID(M6,FIND(":",M6)+1,FIND(":",M6,FIND(":",M6)+1)-FIND(":",M6)-1),
                IF(
                    LEN(M6)-LEN(SUBSTITUTE(M6,":",""))>0,
                    LEFT(M6,FIND(":",M6)-1),
                    0
                )
            ),
            IF(
                LEN(M6)-LEN(SUBSTITUTE(M6,":",""))>1,
                RIGHT(M6,FIND(":",M6,FIND(":",M6)+1)),
                IF(
                    LEN(M6)-LEN(SUBSTITUTE(M6,":",""))>0,
                    RIGHT(M6,LEN(M6)-FIND(":",M6)),
                    M6
                )
            )
        )
        +TIMEVALUE("0:00:00"&RIGHT(M6,LEN(M6)-FIND(".",M6)+1))
    )
)
```
##結果
| M6(50M Split)       |  N6(100M Split) |    O6(50-100M Rap)    |
|-----------------:|------------------:|-------------------:|
| 32.38             |          1:08.17     |        35.79        |
※上記はあくまで参考値であり、私のタイムではありません
go getした時にno import meta tagsのエラーが出た時の対処法



```shell

$ go get code.google.com/p/whispering-gophers/hello
package code.google.com/p/whispering-gophers/hello: unrecognized import path "code.google.com/p/whispering-gophers/hello" (parse https://code.google.com/p/whispering-gophers/hello?go-get=1: no go-import meta tags ())
```

このエラーが出た時は`code.google.com/p/whispering-gophers/hello`の部分を`code.google.com/p/whispering-gophers/hello.git`にすると解決する。

`go get`するときにVersion Control Systemのメタ情報が得られないのが原因らしいです。
SSL/TSL通信の理解があいまいだったのでまとめ

タイトルの通りですが、
業務中若干不安を覚えたので改めてまとめました。
認識異なる点あればご指摘いただけますと幸いです。

# 前提となる知識
## HTTPとHTTPS通信
HTTPはいうまでもなく、クライアントとサーバーが通信を行うためのプロトコルですが、
HTTPSとはSSLを利用したHTTP通信のことです。

## 公開鍵暗号化方式と共通鍵暗号化方式
SSLが行っていることの１つに暗号化がありますが、
暗号化には主に２つの手段があります。
それが公開鍵暗号化方式と共通鍵暗号化方式です。
### 共通鍵暗号化方式とは
名前の通りですが、暗号化と復号化に同じ鍵を用いる通信です。
クライアントとサーバーで共通鍵暗号化方式で暗号化して通信する場合は、
クライアント、サーバーともに１つだけの鍵を使って、
暗号化と復号化を行います。

そのため、共通鍵を知られてしまうと誰でも復号化が可能なため、
鍵は第三者に知られないように共有する必要があります。

### 公開鍵暗号化方式とは
共通鍵暗号化方式では鍵を第三者に知られてはいけませんが、
そのためには物理的に共通鍵を知らせるなど、
手間がかかります。
そのため、この公開鍵暗号化方式が使用されます。

公開鍵暗号化方式で登場する鍵は４つ（２人の通信時）となります。
通信者毎に１対の「公開鍵」と「秘密鍵」を保有しており、
どちらかで暗号化したものはもう一方でしか復号ができません。
つまり、「公開鍵」で暗号化したものは「秘密鍵」でしか復号化できず、
「秘密鍵」で暗号化したものは「公開鍵」でしか復号化できません。

「公開鍵」は常にOPENで誰でも閲覧が可能です。
公開鍵暗号化方式で通信をする場合、
メッセージ送信者は、相手の公開鍵を使ってメッセージを暗号化し送付、
受信者は自身の秘密鍵を使ってメッセージを復号化します。
返信時は相手の公開鍵を使って暗号化し、送付という前と同じ流れとなります。

公開鍵、秘密鍵は一方の鍵でしか復号化ができないため、
秘密鍵が知られない限り、暗号の復号は困難となります。

ただ、公開鍵暗号化方式は処理に時間がかかるため、
通常は初回通信時のみ公開鍵暗号化方式で暗号化した「共通鍵」をやりとりし、
２回目以降は共通鍵で暗号化して通信を行います。


## 電子署名
電子署名は日常生活での印鑑と同様で、
その人によるものと証明するためのもの。
例えばメッセージに署名をつけるためには、
メッセージをまずハッシュ関数でハッシュ値に変換し、
それを秘密鍵で暗号化し相手に送付。
受け取った側は送付者の公開鍵で暗号化されたメッセージをハッシュ値に変換したものと
メッセージを自身がハッシュ関数によってハッシュ値に変換したものを比較します。

送付者がなりすましの場合、
公開鍵が本来の送付者と異なるため、
本来の送付者の公開鍵で暗号化されたメッセージをハッシュ値に変換したものと
メッセージを自身がハッシュ関数によってハッシュ値に変換したものは異なる値となるため、
なりすましと判断できます。


# SSL/TSL通信とは
やっと本題ですが、
まずSSLとTSLは同一のものと考えて問題ありません。
SSLがアップデートに伴い、名称がTSLに変更になったもののため、
バージョンが異なるSSLと捉えてOKです。
そのため、以後SSLと名称を統一して説明しますが、TSLも概要は同じです、

## SSL通信で行っていること
以下の３つを行っています。
・暗号化によるメッセージ漏洩の防止
・暗号化によるメッセージ改ざんの防止
・SLL証明書によるなりすましの防止

です。

## SSLサーバー証明書とは
SSLでメッセージをやりとりする際には、
まずクライアントがこれから通信を行うサーバーが、
信頼できるサーバーかどうかを確認ものとなります。

クライアントはサーバーからSSLサーバー証明書をもらい、
上記を確かめます。
サーバー証明書には暗号化に必要な公開鍵も含め、
以下のような情報が記載されています。

・コモンネーム
・公開鍵の所有者情報
・証明した認証局の署名
・有効期限
など

クライアントはこのサーバー証明書に記載のコモンネームと
接続先のサーバーが一致しているかを確認し、
一致している場合は記載の公開鍵を使って共通鍵の交換を実行します。
【人工知能学会2019】聴講してきました。

2019年6月4日～7日に「第33回人工知能学会全国大会」が開催されました。

今回、運よく聴講することができたので、簡単にまとめておきます。
私が聞いたのは3日目と4日目だけです。

#インタラクティブセッション
+ ポスターを張り出して、議論するポスターセッション形式
+ 解説は一部しか聞けなかったので、詳細が気になる方は予稿をご覧ください。

##OpenPose × 転倒リスク
[非接触センサーを活用した転倒リスク予測の検討](
https://confit.atlas.jp/guide/event-img/jsai2019/4Rin1-39/public/pdf?type=in)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/162c90f6-92a2-acde-02ae-aa763e2381c8.png)

※画像は予稿より転載

+ 歩行の動画をOpenPoseで解析することにより、高齢者などの転倒リスクを予測する研究
+ 特徴量は「歩幅」や「目線の高さ」など、決まったものを使う。
+ 歩行の研究の歴史は長く、研究され尽くされた分野であるため、**特徴量の探索は特に行っていない。**
+ 転倒リスクの予測は80％ほどの精度になった。

##Triplet lossによる人物同定
[屋内空間を巡回するロボットのための協調型転移深層学習に基づく人物再同定とそのTA業務支援への適用]
(https://confit.atlas.jp/guide/event-img/jsai2019/4Rin1-18/public/pdf?type=in)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/da5ec158-f377-4961-9078-171a96b00776.png)

※画像は予稿より転載

+ 移動ロボットのための人物同定を行う研究
+ Triplet Lossを使うことで、80％の精度で人物を同定できる。
+ **かなり軽いモデルにもかかわらず**、高精度になっている。

#一般セッション
+ 発表15分、質疑応答5分の形式。
+ 私が聞いたセッションは質問が多く、なかなか質問するチャンスがなかった。

##掘削くずの検知
[機械学習による杭施工時のスライム検知]
(https://confit.atlas.jp/guide/event-img/jsai2019/3Q3-J-13-02/public/pdf?type=in)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/cb396b29-e0cf-7371-1cf4-7f76ec068637.png)

※画像は予稿より転載

+ 掘削くず（スライム）を検知し除去したいが、現状は職人の感覚に頼っている。
+ 力センサで波形を取得し、機械学習により検知させる試み。
+ SVMや1DのCNNなどで学習した結果、CNNで93％の精度が出た。
+ 波形のラベル付けは職人が付けたものであり、**人間の精度を超えられないのでは？**という質問があった。

##FPGAによるSSDの実装
[Circle SSDを用いたFPGA搭載ドローンでの農作物生育状況計測]
(https://confit.atlas.jp/guide/event-img/jsai2019/3N4-J-10-01/public/pdf?type=in)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/b098a800-378d-3144-f2cb-233359c9d63d.png)

※画像は予稿より転載

+ SSD×ドローンでパイナップルのカウント
+ 自作SSDを作りMobileNet SSDliteよりも高速化
+ ドローンはSSDを処理し、パイナップルの座標を送るだけ。
+ 最終的な、パイナップルの同定とカウントはクラウド上で行う。
+ 上記のように分けて処理を行っているのは、**電力消費を抑えるため。**
+ SSD(FPGA)の処理速度は0.95FPS。

##キリンビールによるデザイン評価

[畳み込みニューラルネットワークを用いたビール缶パッケージの好意度予測及び要因の可視化](https://confit.atlas.jp/guide/event-img/jsai2019/3N4-J-10-02/public/pdf?type=in)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/7adb56a6-697a-eec2-930a-b42230ab52d9.png)

※画像は予稿より転載

+ ビールのデザイン（画像）を入力とし、出力は「好意度（回帰）」及び、「良否（分類）」の1入力2出力CNNを構築
+ 新たなデザインができたときの評価に活かしたい。
+ また、GradCAMの可視化によりデザインの「良いところ」及び「悪いところ」を可視化し、デザイナーへフィードバックしたい。
+ 結論は、回帰はあまりうまくいかなかった。
+ **可視化はうまくいったが、**デザイナーへのフィードバックは「文字を大きくし過ぎない」など既知のものであった。

#NEDOのセッション

+ ロボット×AIのお話
 + ドア開けロボットのお話
 + テレビでも紹介されたお茶会ロボットのお話
+ 「データを公開しているから、皆活用してね」とのこと。リンク先は[こちら](https://www.airc.aist.go.jp/achievements/ja/ML-datasets.html) 
 + STAIR - 動画+日本語キャプション付きのデータセット（世界最大規模）
 + Part-Function - スプーンやフォークなど機能別に色分けされた3Dデータセット
 ![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/aa776d30-40df-404f-48cd-82f8efe48764.png)

 ※画像はNEDOのHPより転載

#その他
+ 会場では、企業展示ブースも設けられており、「Nvidia」 vs 「Intel」のGPU展示も見られた。展示場所の影響もあるのか、**Intel（メイン通路）の方が見学者が多かった。**
+ また、「インターシップ募集中！」など、学生向けの積極的な採用活動も行われていた。

#まとめ
+ ディープラーニング一辺倒かと思いきや、ロジスティクス回帰やSVMなどの従来の手法も多く用いられていた。
+ ディープラーニングは、「GradCAMによる可視化」や「歩幅の計測」など特徴量抽出のために用いられている点も勉強になった。
Arch Linux の neovim でクリップボードにヤンクした内容を保存できるようにする

## はじめに

Arch Linux を使い始めています。エディタは neovim を使っているのですが、neovim 上でヤンクした内容をクリップボードに保存できず困っていました。

解決方法を調べたので、こちらにまとめます。

## tl;dr

以下で実現できました。

* xclip をインストールする
* neovim の設定で以下の設定をする

```vim
set clipboard+=unnamedplus
```

## 調べたこと詳細

詳細は neovim の help で確認できました。

```vim
:help clipboard
```

以下、ヘルプの内容を引用します。

```vim
 ==============================================================================
Clipboard integration 			      *provider-clipboard* *clipboard*

Nvim has no direct connection to the system clipboard. Instead it depends on
a |provider| which transparently uses shell commands to communicate with the
system clipboard or any other clipboard "backend".

To ALWAYS use the clipboard for ALL operations (instead of interacting with
the '+' and/or '*' registers explicitly): >
    set clipboard+=unnamedplus

See 'clipboard' for details and options.

							      *clipboard-tool*
The presence of a working clipboard tool implicitly enables the '+' and '*'
registers. Nvim looks for these clipboard tools, in order of priority:

  - |g:clipboard|
  - pbcopy, pbpaste (macOS)
  - wl-copy, wl-paste (if $WAYLAND_DISPLAY is set)
  - xclip (if $DISPLAY is set)
  - xsel (if $DISPLAY is set)
  - lemonade (for SSH) https://github.com/pocke/lemonade
  - doitclient (for SSH) http://www.chiark.greenend.org.uk/~sgtatham/doit/
  - win32yank (Windows)
  - tmux (if $TMUX is set)

```

ヘルプの内容を簡単に抜粋します。

* neovim はシステムのクリップボードと直接連携していない
* 代わりに、システムのクリップボードと透過的に連携するシェルコマンドを扱う provider と依存している
* ヘルプに記載されているクリップボードツール(xclip, pbcopy,...)が存在していれば、暗黙的にレジスターに登録される

Mac などでは標準で pbcopy が導入されていたので、クリップボードを有効にする設定をすればすぐ使えていたのですが、Arch Linux ではまだクリップボードのツールをインストールしていなかったため、動作しなかったのかなと思います。

## 終わりに

マニュアル読んで学習するの大事ですねー。解決はしたのですが、まだ理解しきれてない部分も多いので、概念を改めて確認していきたいと思います。

## 参考

* [No command for the clipboard](https://github.com/neovim/neovim/issues/1696)
* [What is difference between Vim's clipboard “unnamed” and “unnamedplus” settings?](https://stackoverflow.com/questions/30691466/what-is-difference-between-vims-clipboard-unnamed-and-unnamedplus-settings)
【IFTTT】WebhooksのPOST先URLを確認する方法

### はじめに
IFTTTでWebhooksをよく使うのだが、POST先のURLを良くどこにあったかわからなくなるので、備忘録として残しておく。

### 方法
「My Applet」を選択。
![MyApplet選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431401/aef80f3a-9430-35ae-6efb-a1dd5002da2b.png)

「Services」を選択。検索窓でWebhooksと入力し、「Webhooks」を選択。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431401/ce8912dd-fff7-a1de-d323-5f5b46ad223f.png)

「Settings」を選択。
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431401/0c8a6a6f-0175-93f8-2067-66a1c4b3a65b.png)

URLに記載されているのがPOST先です。
![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431401/b94acbd3-564c-031e-40fa-6efe8836a808.png)
guard let self = selfするとLLDBでpo等できない問題が直った (Xcode 11 beta)

Xcode 10までは以下のようなコードを書くと、closure内で`self`を再定義するせいでLLDBが思うように変数を認識してくれなくなる。

```swift
class SomeClass {
    private func someFunction(someClosure: ()->Void) {
        someClosure()
    }

    func doTask() {
        let greeting = "Hi"
        someFunction { [weak self] in
            guard let self = self else { return }
            // ここで po greeting とかしてもちゃんと出力されない
            // (frame variable greeting だと問題ないけど)
            print(greeting) //-> "Hi"
        }
    }
}
```

こんな感じのエラーが出てた：

```
error: warning: <EXPR>:12:9: warning: initialization of variable '$__lldb_error_result' was never used; consider replacing with assignment to '_' or removing it
    var $__lldb_error_result = __lldb_tmp_error
    ~~~~^~~~~~~~~~~~~~~~~~~~
    _

error: <EXPR>:19:5: error: value of type 'SomeClass' has no member '$__lldb_wrapped_expr_4'
    $__lldb_injected_self.$__lldb_wrapped_expr_4(
    ^~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
```

報告もある：[[SR-6156] LLDB: warning: initialization of variable '$__lldb_error_result' - Swift](https://bugs.swift.org/browse/SR-6156)

`self = self` じゃなくて `strongSelf = self` とかにすればこの問題は起きないけど、せっかくだから `self = self` がいいし・・・っていうか今更書き換えるのやだし・・・


と思ってたら、この間リリースされたXcode 11 (beta) ではそれが直ってます！

[Xcode 11 Beta Release Notes | Apple Developer Documentation](https://developer.apple.com/documentation/xcode_release_notes/xcode_11_beta_release_notes):

> Redeclaring self in Swift code works properly with LLDB. (39611934)

🙌🙌🙌
DockerでDjangoを扱う方法

Dockerのことと、DockerでDjangoを扱う方法をアウトプットします。

#Dockerとは

Docker(ドッカー)とはDocker Inc.(旧DotCloud社)によって開発されたコンテナ仮想化ツールです。
アプリ操作をコンテナに分けて実行することや、別のOS上にコンテナを移しても動作するよう働きます。
軽快さ、保存と再利用のしやすさが一番の特徴です。
**dockerイメージ**
コンテナを立ち上げるために必要なミドルウェアなどの設定やコマンドが、ひとまとめになったテンプレートです。
通常はソフトウェアをインストールして、その後初期設定を行い、さらには細かな設定をカスタマイズする必要がありますが、このDockerイメージを使えばそれらの作業を省略することができます。
**コンテナ**
Dockerイメージをもとに作られたWebサーバやDBサーバなどが動く仮想環境のことです。
**VM(Vagrant+VirtualBox)との違い**
・OSのバージョンの違い、仮想環境ツールの違い、仮想環境ツールの設定の違いなどで、構築に手間がかかるということがない。
・VagrantとVirtualBoxのバージョンの相性によってバグがあるという懸念がない。
・仮想環境がコンテナ型である(VMはホストOS型)

#Docker+Djangoの構築方法
Dockerを使い、「django_app」というフォルダに、「hello」というアプリケーションを作ります。
###*Djangoコンテナの作成
####1.Dockerfileを作成
```
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code
```
####2.requirements.txtを作成
```
django
```

####3.Dockerイメージの作成
1と2で作成したファイルを「django_app」に配置した後の作業です。

```
$ cd django_app
```
**以下、django_appでの作業であることに注意**

```
docker build -t my-django-app .
```

###*Djangoの実装
####4.docker django startproject の実行
```
docker run --rm -v "$PWD":/code/ my-django-app django-admin.py startproject django_app .
```

####5.docker django startapp の実行
```
docker run --rm -v "$PWD":/code/ my-django-app django-admin.py startapp hello
```

####6.runserver の実行
```
docker run --rm -v "$PWD":/code/ -p 8000:8000 my-django-app python manage.py runserver 0.0.0.0:8000
```
####7.http://127.0.0.1:8000 にアクセス

![](https://leben.mobi/wp-content/uploads/2019/03/Screen-Shot-2019-03-06-at-12.56.49-768x424.png)

この画面が出ればOK
次開くときは6->7の手順。

#まとめ
DockerとDjangoの操作をしました。
Dockerでコンテナを使っていない意味や、コマンドの意味はまだ理解が曖昧な部分はありますが、一応Djangoは使えます。
誤りがあればご指摘ください。
オンラインエディターrunstantが初心者に良い3つの理由

[Runstant](http://runstant.com/)はCodepenのような、ブラウザ上でHTML,CSS,JavaScriptのコーディングができるサービスです。
## オンラインエディターrunstantが初心者に良い3つの理由

1 日本語対応している
日本語対応しているオンラインエディターは少ないです。
2 UIがシンプルで使いやすい
複数ファイルに対応していないため、UIがシンプルになっていてとても使いやすいです。
3 全て無料
こんなに機能があって無料なのは素晴らしいです！
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
Atomで使うatom-runnerのショートカットキーを変更する方法

## 本記事はMacを用いています。

## atom-runnerを実行するショートカットキー
デフォルトでは「ctrl(alt)-r」で実行できます。
僕は基本、Macbook Proで操作するので、Controlキーの位置が悪いです。
そのため、ショートカットキーを変更しようと思います。

## 変更方法
- 「Welcome Guide」をクリックして、「Install a Package」をクリックします。
- 「設定ファイルを開く」を選択し、「.atom/packages/atom-runner/keymaps/atom-runner.cson」ファイルを開きます。
- ```'.platform-darwin atom-text-editor':``` という記述の下に、```'ctrl-r': 'run:file'```というのがあるので、この２行をコピーします。
- メニューバーの「Atom」「キーマップ」を選択し、最下行にペーストします。
- ```'ctrl-r': 'run:file'```の前部分を変更します。(僕は```ctrl-enter```としました)
- ファイルを保存して、Atomを再起動します。
- 指定したショートカットキーで実行できるか確認してください。
【IFTTT】Webスクレイピング×IFTTTでプロ野球の試合結果をLINE通知する（2/2）

## はじめに
前回の記事は[こちら](https://qiita.com/ykoba16/items/b7e916960898f816588c)からどうぞ。
全体構成はこんな感じ。IFTTT的に表現すると「DeNAの試合が終わったら、結果をLINEに通知する」ということになる。
①DeNAの公式サイトの試合結果を監視
②試合結果が終了になったことを検知
③IFTTTのWebhookに試合結果を通知
④Webhookの検出（Thisの部分）
⑤LINEに試合結果を通知（Thatの部分）
![図1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431401/ca8c861a-5a3c-6deb-a26a-d8e2dc6df7ff.jpeg)
前回は"Webスクレイピングにより、DeNAの試合結果が終了になることを検出"の部分（①〜③）を作りました。今回は④、⑤の部分を作っていきます。
※本稿では前回記事に読了、IFFFTのサービスアカウント、LINEのデベロッパーアカウントを作成済み前提で話を勧めていきます。

## IFFFTのサービスを作成
③で通知されたPOSTの内容の受け口の部分を作っていきます。「作る」と言ってもWebサービス上からポチポチと選択していくだけの作業です。以下、画像多めです。
まずは、IFFFTのトップページから「My Applet」>「New Applet」の順で選択。
![MyApplet選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431401/7b0a16aa-36be-0e33-1a70-16674244d3d5.png)
![NewApplet選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431401/4c3f3e7d-a43f-3e60-4db0-3da8a1804aab.png)

前回記事で言う「あることが起きたら」のあることを設定していきます。
「This」を選択。
![This選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431401/0fd5b701-cf9a-6ab1-8527-b533f6a122b5.png)

検索窓に"Webhooks"と入力し、「Webhooks」を選択。WebhooksとはIFFFTにおけるPOSTの受け口になるサービスです。
![Webhook選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431401/ec6b8522-d659-cb65-e1e2-1eff0c7bfd7c.png)

「Reveive a web request」を選択。
![ChooseTrigger選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431401/c75f42e9-4190-4292-3a16-b1fcaaaa5dd4.png)

続いて、「That」を選択。
![That選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431401/c866c730-bfc3-936e-c577-60f03bd2dcea.png)

 「LINE」を選択。
![LINE選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431401/837208ee-2cbc-e1fb-f144-2cae9a4ca271.png)

「Send Message」を選択。
![SendMessage選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431401/1a5abdce-9861-16c5-1494-b8c1a6000a8e.png)

「Recipient」に投稿したいグループを作成する。「Message」にLINEに通知したいメッセージのフォーマットを設定します。今回は以下のように選択。<br>は改行を指します。通知の最初に<br>を入れているのは、IFFFTで通知するとメッセージの先頭にデフォルトで[IFTTT
]がつき、そのまま入れると[IFTTT]~~~のように、メッセージが汚くなるからです（笑）
![Action選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431401/245a0042-8fb4-3641-5837-f41a300f14cd.png)

最後に「Finish」を押して完了です。

## おわりに
あとはDeNAの試合が終わると遅くとも30分以内には自分のLINEに試合結果の通知が来るようになります。IFTTTは他にも応用効かせていろんなことができるようになりますので、みなさんも良かったら自分なりのオリジナルを作ってみてください！
読んでいただきありがとうございました！
直線の一部が軌跡となる例

軌跡の十分性の証明を省略しないシリーズの第４弾です。最後はパラメータです。

## 問題

実数$t$の値が変化するとき，点$\text{P}(x,\,y)$の軌跡を求めます。
$\displaystyle x=\frac{1}{1+t^2}\cdots\text{①},\,y=\frac{t^2}{1+t^2}\cdots\text{②}$


## 解答
①，②より，$m$を消去して，
$\begin{aligned}[t]
\displaystyle x+y&=\frac{1}{1+t^2}+\frac{t^2}{1+t^2}\\\
&=\frac{1+t^2}{1+t^2}\\\
&=1
\end{aligned}$
$\therefore x+y=1$
点$\text{P}$は直線$x+y=1$上にあることがわかりました。
しかし，この直線上全体を動けるかどうかはわかりません。
そこで，直線上の点$\text{P}$を$\text{P}(k,\,1-k)\quad k\in\mathbb{R}$とおくと，
①より
$\displaystyle k=\frac1{1+t^2}$
です。$t$が実数のとき，$1+t^2\geqq1$なので，
$\displaystyle0<\frac1{1+t^2}\leqq1$
となります。
②は
$\displaystyle 1-k=\frac{t^2}{1+t^2}$
$\displaystyle k=1-\frac{t^2}{1+t^2}=\frac{1}{1+t^2}$
となり同じ式になります。

よって，$0<k\leqq1$のときにかぎり，実数$t$が存在することがわかりました。


以上より、点$\text{P}$の直線$x+y=1$の$(0<x\leqq1)$の部分となります。
rspec実行時にundefined method `visit' が吐き出されてしまう

Qiita初投稿です。分かりにくい記述等ありましたらご指導の程宜しくお願いしますm(_ _)m

rails tutorialのテストをminitestからrspecに変更しようと、@fuqdaさんの投稿(https://qiita.com/fuqda/items/61e6b39d43733cd19802) に沿って準備。

以下の実行コマンドでテスト開始。

```
$ bundle exec rspec spec/features/static_pages_spec.rb
```
すると次のようなエラーメッセージが表示されてしまう。

```
NoMethodError:undefined method `visit' for <RSpec::ExampleGroups::Help:0x0000000003f45ad0>
```
Qittaの先人の方々やGoogle先生に泣きついて、capybaraのバージョンを変更したり色々イジってみるも解決せず。。
すったもんだやった挙句、spec/spec_helper.rbに下記コードを追加することで無事テストスタート、パスしました。

```spec_helper.rb
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
```
```
Finished in 0.23741 seconds (files took 2.08 seconds to load)
2 examples, 0 failures
```
正直なぜこれが必要だったのかまだ分かっていません。テストファイルがspec_helperをrequireしているので、spec_helper.rbにてrspecをrequireしておく必要があった...か？
雑魚すぎてすみません、もう少し理解を深めて分かったら追記します。。
海上自衛隊のHPが阿部寛のライバルとして名乗りをあげた

## はじめに
※技術的な記事ではありません。
多少、技術的な話は出てきます。

## 海上自衛隊第101掃海隊のHPがなかなか早い

まず、そのページは[こちら](https://www.mod.go.jp/msdf/mf/other/butai/hp/101md/101home.html)

・https対応
・2019.6.4　ホームページ再開設（以前のサイトはどこなのか）
・ロゴとタイトルが被っている
・Failed to load resource: the server responded with a status of 404 (Not Found)というコンソールエラーがある。（1211.jpgがロードエラー）
・インラインでCSSを記載
・```<meta name="GENERATOR" content="JustSystems Homepage Builder Version 15.0.2.0 for Windows">```という記述があるため、[ジャストシステムさんのホームページビルダー](https://www.justsystems.com/jp/products/hpb/index.html)を使っている模様
・ながしま、ゆげしまのリンクから飛んでいくページはプレーンなHTML
・装備品のページはjpgファイルのみという潔さ

## パフォーマンスを比較

まずは阿部寛から。
ここではChrome Dev Toolを使います。

<img width="977" alt="スクリーンショット 2019-06-08 21.53.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76779/096df9a7-aa42-6502-525c-f90c5b60acb3.png">

**Finish: 116ms
DOMContentLoaded: 43ms
Load: 348ms**

続いて、海上自衛隊第101掃海隊

<img width="1019" alt="スクリーンショット 2019-06-08 21.55.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76779/97bfefae-b477-4112-a1d1-7b8bf0ee2520.png">

**Finish: 134ms
DOMContentLoaded: 133ms
Load: 329ms**

ほぼ互角です。

念のため、Performanceパネルも見てみました。

阿部寛のページは
<img width="400" alt="スクリーンショット 2019-06-08 21.58.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76779/0b4d177d-4d83-ad58-86c5-78905acf9d0c.png">

そして、海上自衛隊第101掃海隊
<img width="450" alt="スクリーンショット 2019-06-08 21.57.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76779/f0610e59-dd75-661b-c86a-c9509a5d927d.png">

これだけを見ると、若干海上自衛隊第101掃海隊の方がパフォーマンス良さそう・・・？

あとは、海上自衛隊第101掃海隊の方はhttps対応しているので、Auditsでスコアを計測してみました。

<img width="1249" alt="スクリーンショット 2019-06-08 22.15.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76779/363e57bc-d30f-60fa-9e4e-6cc61f6118c3.png">

Performace 100を達成しています。

国内屈指の高パフォーマンスサイト、[r.nikkei.com](https://r.nikkei.com/)ですらスコア87です。

新しい爆速サイトが爆誕したといってもいいのではないのでしょうか。
SophoxでOSMタグの一覧を作ってみた

# [Sophox](https://wiki.openstreetmap.org/wiki/JA:Sophox)とは
ひとことでいえば[WDQS](https://query.wikidata.org/)(Wikidata Query Service)のOSM向け拡張版だ。[ウィキデータ](https://www.wikidata.org/wiki/Wikidata:%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8)では[Mediawiki](https://www.mediawiki.org/wiki/Manual:What_is_MediaWiki%3F/ja)のエクステンションである[Wikibase](https://www.mediawiki.org/wiki/Wikibase/ja)を使って対話的にデータ入力ができるようになっているが、[OSMWiki](https://wiki.openstreetmap.org/wiki/JA:Main_Page)もまたMediawikiを使っており、Wikibaseも設置されているため、各記事（タグの説明ページ）のメタデータをbotや人力で入力して、構造化データとして保存している。そのメタデータやOSMデータを関連付けながら[SPARQL](https://en.wikipedia.org/wiki/SPARQL)を使って対話的に呼び出したり可視化する仕組みが[Sophox](https://sophox.org/)である。

# OSMWikiからタグ一覧を取得するクエリ
[こちら](http://tinyurl.com/y58c83gl)がSophox経由でタグ/キー一覧を取得するクエリ。左パネルにある▶ボタンで実行すると下部のブロックに結果が表示され「ダウンロード」から出力形式を指定して出力する。
![](https://i.imgur.com/2CYFLgX.png)
（SPARQLの詳しい内容は[Sophoxの解説](https://wiki.openstreetmap.org/wiki/JA:Sophox)や[「例」の解説](https://wiki.openstreetmap.org/wiki/SPARQL_examples)を参照。）

OSMWikiにはタグやキーの説明ページからリンクする形でOSM項目ページが作られている。（[レストランの例](https://wiki.openstreetmap.org/wiki/Item:Q4819)）これはほとんどがbotにより[こちらの手順](https://wiki.openstreetmap.org/wiki/JA:Data_items#.E9.A0.85.E7.9B.AE.E3.81.AE.E4.BD.9C.E6.88.90.E3.83.97.E3.83.AD.E3.82.BB.E3.82.B9)でOSMWikiのinfoboxや[Taginfo](https://taginfo.openstreetmap.org/)から作られたものである。
上記7行目でQ2（タグ）を指定しているのはタグの項目ページを指していて実行結果は2019/6/8現在で**2,434件**。Q2の部分をQ7（キー）に変えるとキーの説明ページを指し、2019/6/8現在で**1,578件**。基本的には日本語ページがあるものは日本語が、無いものは英語ページの内容が出力される。タグとキーの項目ページを合わせると**4,012件**となり、これがSophox的なカウントによるタグの件数ということができる。（ステータスが非推奨のものは除外）なお、OSMWiki上のtag:（メインキー＋値）とkey:（サブキー＋値）のページは正しく区別されていないものも多く、その区別は正確ではない。

# iDプリセット
iDのプリセットはTaginfoでしか拾えない文書化されていないタグであっても使いたい人がどんどん登録申請（プルリクエスト）してくるため、ニーズのある新しいタグがいちはやく登録される。その一覧は[transifexの翻訳ファイル](https://www.transifex.com/openstreetmap/id-editor/presets/ja/download/for_translation/)から拾うことができる。2019/6/4現在のタグ登録件数は**1,204件**。

# タグ一覧
前述の下記3種類の一覧をspread sheet上に落としたものが[こちら](https://docs.google.com/spreadsheets/d/1KpWrNBmYisgLpP5_fHOQXHCKFFxeoy9Oy275qwhtipY/edit#gid=2007880954)。
- OSMWikiに文書化されたタグ（メインキー＋値）
- OSMWikiに文書化されたキー（サブキー）
- iDのプリセット

# OSMタグ検索アプリ（ひな型）
上記タグ一覧をWebアプリで検索できるようにしてみたものが[こちら](https://osmtag.glideapp.io/)。
日本語や英語の文字列でタグを検索するもの。よろしけれお試しください。「iD内タグ一覧」には関連キーワードが多数登録されており、例えば「食事」や「スポーツ」といったざっくりとしたキーワードでもタグを検索できます。

## 注意制限事項
- Sophoxの制約でOSMWiki上の画像URLを直接取得することができません。そのため[spread sheet](https://docs.google.com/spreadsheets/d/1KpWrNBmYisgLpP5_fHOQXHCKFFxeoy9Oy275qwhtipY/edit#gid=2007880954)上の「画像URL」列は「ウィキの項目」ページから手動で画像をたどり、そのURLをコピペしています。数が多いためアルファベット順に先頭を少しコピペしただけです。もし画像URLを追記してみたい方がおられましたらsheetからアクセス権限をリクエストしてください。