OmniAICreator/Qiita-1.07M huggingface dataset:
PCの電源を入れてWindowsデスクトップが表示されるまでの仕組みを説明してみる

Twitterでフォローしてる方からこんな投稿があったので
自分なりに調べてみました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">面接の質問で「PCの電源を入れてデスクトップが表示されるまでのWindows仕組みを全て知ってる限り説明してください」ってのをやると結構Windows10の知識どれだけあるか分かると思ってる。</p>&mdash; 松屋りょう🍚月30回の牛めし (@RY0_JPN) <a href="https://twitter.com/RY0_JPN/status/1039518595515002881?ref_src=twsrc%5Etfw">2018年9月11日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## Step1 : 電源を入れる
![icon_157000_32.png](https://qiita-image-store.s3.amazonaws.com/0/143735/f8a288de-223f-2579-ef06-3b2768d3fbd0.png)
このマークがついてるボタンをポチる。
ノートPCはスライドして電源ONするタイプもあります。

## Step2 : UEFI BIOS 起動

### UEFI BIOSとは

マザーボードに記録されている、電源を入れたら最初に起動するプログラム。
読みはそのまま UEFI BIOS（ゆーいーえふあい ばいおす）でいいそうです。

Windowsを起動するときのUEFI BIOSの役割は大きく2つあって、1つはPC内部のハードウェアが正しく取り付けられているかチェックすること、もう1つは起動デバイスを設定すること。

1. POST パワーオンセルフテスト（正しく取り付けられていないと音で知らせる）
2. 起動デバイスを設定

Windows10 をクリーンインストールしたとき、EFIシステムパーティションという区画が自動的に作られて、このなかにある Windows Boot Maneger（実体は\EFI\Microsoft\Boot\bootmgfw.efi）を UEFI BIOS が見つけて起動する
UEFI BIOS の画面を開くと、ちゃんと Windows Boot Maneger が見えてます。
![IMG_1252.JPG](https://qiita-image-store.s3.amazonaws.com/0/143735/ad666c07-095b-74ea-7885-6b7dfbaa8be2.jpeg)
EFIシステムパーティションはこちら
![UEFI_01.png](https://qiita-image-store.s3.amazonaws.com/0/143735/799d9635-bcb3-f4f4-9572-0237dd27f05b.png)
※ BIOSの画面で Windows Boot Maneger が見えないときは UFEIがオフの状態。 旧BIOSとの違いについては今回は割愛。

## Step3 : ブートマネージャー と ブートローダー
ブートマネージャーの役割は、OSが複数インストールされているとき、どのOSを起動するか選択画面を表示すること。
Windows Boot Manager は選択された Windows のブートローダー（Winload.efi）を読み込んでOSを起動する
マルチブートのときのブートマネージャーとブートローダーはこんな感じ
![cm01.png](https://qiita-image-store.s3.amazonaws.com/0/143735/099ace3f-53dc-f025-e514-a3190baee007.png)

## Step4 : カーネル（ntoskrnl.exe）起動
カーネルの起動に必要な最低限のドライバが読み込まれた後に、カーネルが起動

- 各種デバイスの初期化
- ブートに必要なレジストリの読み込み
- ブートに必要なドライバの読み込み
- セッション マネージャー プロセス（Smss.exe）に制御を渡す

## Step5 : セッション マネージャー（Smss.exe）起動
たくさんのプロセスが動き始める

- 各種セッションの初期化
- 残りのレジストリの読み込み
- 残りのドライバの読み込み
- ログオン処理（winlogon.exe）に移行

## Step6 : ログオン画面（winlogon.exe）
- おなじみのログオン画面（LogonUI.exe）を表示
- ユーザー認証
    - ユーザー名とパスワードの入力を受け付ける
    - 入力された情報は LSASS（ローカルセキュリティ認証サブシステムサーバー、lsass.exe）に渡され、ローカルアカウントなら「SAM（Security Authentication Manager）」、ドメインアカウントなら Active Directory のドメインコントローラーから取得したユーザー情報と照合して、正しいログオン情報であるかどうか検証される
- 認証されたらユーザーログオンアプリケーション（Userinit.exe）を起動

## Step7 : デスクトップ表示
- ログインユーザーのセッション作成（Userinit.exe）
    - Explorer.exe が起動
        - ユーザー固有（HKCU）のレジストリ読み込み
        - ログオンスクリプト、スタートアッププログラム実行
        - デスクトップの表示
        
Process Monitor でログを取ってみたりしたのですが、いまいち使い方が…:thinking:
間違いがあれば、ご指摘いただけたら幸いです。

# 参考リンク
- PCと解
https://pctrouble.net/
- Windows 10 PC UEFI BIOS(UEFI)の役割としくみ
http://dxr165.blog.fc2.com/blog-entry-256.html
- 誰でもわかるデバイスドライバ講座
https://sciencepark.co.jp/device_driver/dvdr/report-14/
- PC・Windowsの起動についてメモ
http://lsair.html.xdomain.jp/a/e/g13_128_pcwindows.html
- ＠IT > Windows Server Insider > 第7回　特権的な操作を制限するUAC（ユーザーアクセス制御）
http://www.atmarkit.co.jp/ait/articles/1503/19/news131_2.html
- Windows 8 でお届けする高速な起動
https://blogs.msdn.microsoft.com/b8_ja/2011/09/14/windows-8-17/
Selenium のサンプル 予約フォーム (Node.js)

Selenium のサンプルです。

次のページをテストに使いました。
[予約フォーム](http://example.selenium.jp/reserveApp/)

```js:reaerve_form.js
#! /usr/bin/node
// ---------------------------------------------------------------
//	reserve_form.js
//
//					Sep/21/2018
//
// ---------------------------------------------------------------
console.error ("*** 開始 ***")

var webdriver = require('selenium-webdriver')
var By = require('selenium-webdriver').By

var driver = new webdriver.Builder().forBrowser('firefox').build()
const url = 'http://example.selenium.jp/reserveApp'
driver.get(url)

driver.findElement(By.id('reserve_month')).clear()
driver.findElement(By.id('reserve_month')).sendKeys('11')

driver.findElement(By.id('reserve_day')).clear()
driver.findElement(By.id('reserve_day')).sendKeys('10')

driver.findElement(By.id('reserve_term')).clear()
driver.findElement(By.id('reserve_term')).sendKeys('3')

driver.findElement(By.id('headcount')).clear()
driver.findElement(By.id('headcount')).sendKeys('2')

var str_select = "input[type='radio'][name='bf'][value='off']"
var item=driver.findElement(By.css(str_select))
item.click()

str_select = "input[type='checkbox'][id='plan_b']"
item=driver.findElement(By.css(str_select))
item.click()

driver.findElement(By.id('guestname')).sendKeys('明智小五郎')
driver.findElement(By.id('goto_next')).click()

console.error ("*** 終了 ***")

// ---------------------------------------------------------------
```
bedtoolsのインストール

https://bedtools.readthedocs.io/en/latest/content/installation.html

に書いてある通りにインストールを行うべくターミナルを叩いたら

```
brew tap homebrew/science
```
`Error: homebrew/science was deprecated. This tap is now empty as all its formulae were migrated.`

なくなってる。。
試しに、次の行を打ってみた。

```
brew install bedtools
```

だけでいいらしい。
よかった。
L2CAP (Logical Link Control and Adaptation Protocol) を調べてみた

# CID
CID = channel identifier
16ビット(2バイト)の値

|CID|BR/EDR|LE|備考|
|---|---|---|---|
|0x0000| Null identifire | Null identifire |使用不可|
|0x0001| Signal channnel | RFU ||
|0x0002| Connectionless channel | RFU ||
|0x0003| AMP Manager Protocol | RFU ||
|0x0004| RFU | Attribute Protocol ||
|0x0005| RFU | Signal Channel ||
|0x0006| RFU | Security Manager ||
|0x0007| Security Manager | RFU ||
|0x0008～0x001F| RFU | RFU ||
|0x0020～0x003E| RFU | Assinged Number ||
|0x003F| AMP Test Manager | RFU ||
|0x0040～0x007F| Dynamically allocated | Dynamically allocated ||
|0x0080～0xFFFF| Dynamically allocated | RFU ||

0x0002
Sequel Proを超えるGUIツールが出てきたぞ

## 悲報

2019年6月26日現在、TeamSQLのサポートがなくなってしまったようでダウンロードできなくなくなりました。。
> TeamSQL has retired and is not available for download anymore.

---

今までSequel Proを重宝してきましたが、それを超えるGUIツールが出てきました。

その名も、[TeamSQL](https://teamsql.io/)

現状サポートしているものだけでもかなり豊富
今後、elasticやmongoDBにも対応されるようです。
<img width="522" alt="スクリーンショット 2018-09-21 16.49.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/239829/17bcf62b-ec50-8fdd-0f59-52c2438a707e.png">

# 機能

## クエリ保存
<img width="724" alt="スクリーンショット 2018-09-21 16.50.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/239829/27deb315-5ec0-54aa-175e-6e3f76dde6a4.png">

## 履歴保持
<img width="724" alt="スクリーンショット 2018-09-21 16.51.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/239829/c7ec4af6-b388-6c38-cf8b-7955bd59d087.png">

## ファイル出力
抽出した結果をボタン１つでcsvやjson形式に保存可能。
<img width="520" alt="スクリーンショット 2018-09-21 17.14.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/239829/a7ce01ed-3eee-eef2-4d25-5d7f4642542a.png">


## 共有
データをエクスポートしなくても共有が可能。  
グループの作成が可能なため、特定のユーザー同士で簡単に共有ができるとこがメリット。
<img width="805" alt="スクリーンショット 2018-09-21 17.00.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/239829/bd1c82b8-1151-38c4-9df4-dc920a7fe0b4.png">


## 可視化
様々なチャートでクエリの可視化が可能。
<img width="698" alt="スクリーンショット 2018-09-21 16.55.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/239829/21523ba2-5080-abe8-89af-bc248ee1e5e0.png">

そのままイメージとして保存も可能。
<img width="421" alt="スクリーンショット 2018-09-26 12.22.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/239829/b0a73f27-596c-b607-d1c6-71e23572350a.png">


## テーマ選択
<img width="939" alt="スクリーンショット 2018-09-21 16.55.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/239829/b2f542f2-6467-ab90-96a6-dad69cc3412b.png">

## 拡張
<img width="1439" alt="スクリーンショット 2018-09-25 18.25.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/239829/303b0f38-a1c5-2bd7-4967-f9decbfaff3d.png">


## スニペット
長いクエリを作成するのに便利。

# 全て無料！！
これは使うしかない

# 追記
日本から多大なアクセスの影響より、TeamSQLの方から感謝のお言葉を頂きましたよ:clap:
<img width="722" alt="スクリーンショット 2018-09-24 21.14.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/239829/c71e75a2-4043-ba4e-e005-84695866951c.png">
リモートサーバ上の複数ファイルをローカルのVSCodeで一気に開くシェルスクリプト

# 環境
リモートサーバ: Ubuntu 16.04.3 LTS
ローカル: macOS High Sierra

# VSCodeでリモートサーバのファイルを編集する
[このブログ記事](http://memo-pad.hatenadiary.jp/entry/2017/10/08/205326)を参考に、VSCodeでリモートサーバのファイルを編集する環境を整えました。

```
rmate -p 52698 [編集したいファイル名]
```

このコマンドをサーバ上で叩くとローカルのVSCodeでファイルが開かれ、編集できるようになります。

# 問題点
以下のように複数ファイルを一気に開こうとするとうまくいきません(詳しく調べていませんが、先頭の1ファイルのみ開かれるようです)。

```
rmate -p 52698 hoge1.py hoge2.py
rmate -p 52698 ~/hoge/*.c
```

# 解決策
ローカルでは、ターミナル上で

```
code hoge1.py hoge2.py
code ~/hoge/*.c
```

といったコマンドを叩くと複数ファイルを一気に開いてくれるので、リモートでも同じ挙動にするために以下のシェルスクリプトを書きました。

```shell:code.sh
#!/bin/bash
argv=("$@")
for i in `seq 1 $#`
do
    rmate -p 52698 ${argv[$i-1]}
done
```
実行時の引数(ファイル名)をリストとして受け取り、for文で一つ一つのファイルを開いています。このシェルスクリプトに

```
chmod +x code.sh
```

で実行権限を与えてパスの通った場所に置けば、

```
code.sh hoge1.py hoge2.py
code.sh ~/hoge/*.c
```

といったコマンドで複数ファイルを一気に開けるようになります。ついでに.zshrcに

```shell
alias code='code.sh'
```

と書き足しておけば、ローカルと完全に同じコマンドが叩けるようになります。
Redmineのバックアップ・リストア

# 概要
- Redmineを別のホストに移動
- （Vagrant上の）Redmineを日次でバックアップ

## 構成
|H/S        |Name   |Version|Memo            |
|:----------|:------|------:|:---------------|
|OS         |CentOS |6.7    |                |
|Web Server |Apache |2.2.27 |ソースインストール|
|Database   |MariaDB|10.1.36|ソースインストール|
|Application|Redmime|3.2.9  |                |

## 参考手順
http://redmine.jp/faq/system_management/backup/

# 手順
## Redmineを別のホストに移動
- 移動先のホストにRedmineをインストール（[手順](https://qiita.com/fkmi/items/fe99dd6ee1867a773af9)）
- 移動元ホストのデータベースをバックアップ

```
(移動元ホスト)# mysqldump -uredmine -predmine redmine > /tmp/db_redmine.dmp
```

- バックアップファイルを移動先ホストにコピー

```
(移動元ホスト)# scp /tmp/db_redmine.dmp <移動先ホスト>:/tmp
```

- filesディレクトリを移動先ホストにコピー

```
(移動前ホスト)# scp -r /var/lib/redmine/files/* <移動先ホスト>:/var/lib/redmine/files/
```

- 移動先ホストでデータベースをリカバリ

```
(移動先ホスト)# mysql -uredmine -predmine redmine < /tmp/db_redmine.dmp
```

- 移動先のホストでデータがインポートできているか確認
    - http://移動先ホスト/

## （Vagrant上の）Redmineを日次でバックアップ
### バックアップ
- バックアップ用ディレクトリを作成

```
# mkdir /tmp/redmine_bk /vagrant/redmine_bk
```

- バックアップ用のスクリプトを作成

```
# vi /root/redmine_bk.sh
```
```/root/redmine_bk.sh
#!/bin/bash

mysqldump -uuser_redmine -predmine db_redmine > /tmp/redmine_bk/db_redmine.dmp
cp -pr /var/lib/redmine/files /tmp/redmine_bk
cd /tmp
tar -czf redmine_bk_`date "+%Y%m%d"`.tgz redmine_bk/*
mv /tmp/redmine_bk_`date "+%Y%m%d"`.tgz /vagrant/redmine_bk/
```

- cron設定

```
# vi /etc/cron.d/redmine
```
```/etc/cron.d/redmine
0 10 * * * root /root/redmine_bk.sh >> /dev/null 2>&1
```

- cron設定を反映

```
# service crond reload
```

### リストア

- バックアップファイルをコピー（YYYYMMDDは対象ファイルに合わせて変更)

```
# cp -p /vagrant/redmine_bk/redmine_bk_YYYYMMDD.tgz /tmp
```

- バックアップファイルを解凍

```
# cd /tmp
# tar zxvf redmine_bk_YYYYMMDD.tgz
```

- filesディレクトリをコピー

```
# cp -pr /tmp/redmine_bk/files/* /var/lib/redmine/files/
```

- データベースをリカバリ

```
# mysql -uredmine -predmine redmine < /tmp/redmine_bk/db_redmine.dmp
```

- データがインポートできているか確認
    - http://ホスト名/
activerecord-importでon_duplicate_key_updateを忘れたときの挙動

**2019/07/11 追記**
この挙動ですが、v1.0.0以降のversionでは修正されているようです。
記事作成時に利用していたversionは0.27.0でした。

@kikunantoka さん ご指摘ありがとうございました！

---


RailsでRDBのレコードを一括処理したいときに[activerecord-import](https://github.com/zdennis/activerecord-import)を使っていたのですが、
うまくデータ更新されてないものが見つかったので調査した結果の覚書です。
(RDBMSがMySQLの場合の話です)

## on_duplicate_key_update
bulk_insertする際、新規レコードは作成、そうでないものは更新してくれるオプション。
activerecord-importでも対応しています。
https://github.com/zdennis/activerecord-import/wiki/On-Duplicate-Key-Update

>which allows you to specify fields whose values should be updated if a primary or unique key constraint is violated.

とあるように、主キー / ユニークキー制約に引っかかった場合、対象レコードの指定したカラムの値だけ更新してくれます。

```rb
Foo.import [foos], on_duplicate_key_update: [:col1, :col2]
```


## 間違っていた部分とその結果
作成 / 更新の両方があり得るテーブルに対して、`on_duplicate_key_update`オプションを指定せずにimportしていました。

```rb
Foo.import [foos]
```

この場合、例外処理が起きるか、更新されずに放置されるかだと思っていたのですが、最終更新日時(updated_at)のカラムだけが更新されるようです。

```sql
INSERT INTO `foos` (`id`, `col1`, `col2`, ..., `created_at`, `updated_at`)
VALUES (...)
ON DUPLICATE KEY UPDATE `foos`.`updated_at` = VALUES(`updated_at`)
```

結果として、更新はされている(ように見える)がカラムの値は何も変わっていないレコードが生まれていました。
`on_duplicate_key_update`オプションを指定したら正常に更新されるようになりました。一安心。
git - インタラクティブリベースしたコミットのタイムスタンプを戻す


# アジェンダ

ローカルでコミット整理のために interactive rebase を行うと、コミットのタイムスタンプが **リベースを行った日時になってしまう。**


変わらないようにするか、タイムスタンプを元に戻したい。

## 方法論

`git rebase -i` 自体には元のタイムスタンプを維持するオプションは無いらしい。

代わりに `rebase` に `--committer-date-is-author-date` というオプションがあるので、`push` 前にこれで再 `rebase` すれば、元に戻せる（ローカルなので通常 Author date と Commit date は同じ）。

インタラクティブリベース時に squash したコミットのタイムスタンプとしてどれが選択されるのかは未確認。


## 結論

```bash
$ git rebase --committer-date-is-author-date <commit-hash>
```

これで `<commit-hash>` より後ろのコミット日時は Author date に更新される。

SourceTree のインタラクティブリベースは本当便利。

## 参考 URL

- [“git rebase without changing commit timestamps - Stack Overflow”](https://stackoverflow.com/questions/2973996/git-rebase-without-changing-commit-timestamps)
Jetson AGX Xavier Dev. KitをWiFiに繋げるには

## はじめに
先日のGTC Japanから販売が開始されたNVIDIAの組み込みAIプラットフォーム [Jetson AGX Xavier](https://developer.nvidia.com/embedded/buy/jetson-xavier-devkit)ですが、この開発者キット、実は素の状態だとWiFiに接続できません。（接続するためのHWを持ってません。）
ちゃんとデータシートを読むと確かにXavierがWiFi非搭載ということはわかるのですが、[Jetson TX1/TX2](https://www.nvidia.com/ja-jp/autonomous-machines/embedded-systems-dev-kits-modules/)（モジュール側にWiFiとBluetoothが搭載されている）に慣れていると最初結構戸惑います。

WiFiに繋がるようにするためにすべきこと自体は非常にカンタンなのですが、意外と情報がまとまってないようなので整理しました。

## 手順
### 1. 無線LANカードを購入する
[Xavierが対応しているコンポーネントリスト](https://developer.nvidia.com/embedded/dlc/jetson-xavier-supported-components-list)（NVIDIA Developerサイトへのログインが必要です）を見ると、**Intel 8265NGW**という無線LANカードが動作確認済みのようなので私は[これをAmazonでポチりました](https://www.amazon.co.jp/Wireless-AC-802-11ac-867Mbps-Bluetooth-%E7%84%A1%E7%B7%9ALAN%E3%82%AB%E3%83%BC%E3%83%89/dp/B075ZVKKM7)。なお、手元に余ってるWiFiアンテナがあるという場合以外にはアンテナも必要になりますので、**MHF4コネクタ**で**2.4GHz/5GHz**に対応したアンテナを買って無線LANカードに取り付けましょう。私が買ったのは[こちら](https://www.amazon.co.jp/gp/product/B06ZZX719L/ref=oh_aui_detailpage_o06_s00?ie=UTF8&psc=1)です。

### 2. 無線LANカードを組み付ける
Xavierのキットを裏返すと左下にM.2 E-keyのソケット（下図赤枠）があるので、ここに先ほどの無線LANカードを取り付けます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/168480/f56a7332-89b7-593b-fe84-7e22bc345da1.jpeg" width=400/>
取り付け後。差し込んでねじ止めするだけです。
<img src="https://qiita-image-store.s3.amazonaws.com/0/168480/23f6bfd7-f5e2-67f9-f027-5f2e1bc4bff1.jpeg" width=400/>

### 3. ファームウェアをインストールする
最初からファームウェアが入っていることもあるようですが、私の場合は念のため[Intelのサポートページ](https://www.intel.com/content/www/us/en/support/articles/000005511/network-and-i-o/wireless-networking.html)から最新のものをダウンロードしてきました。
ダウンロード後は、READMEにも書いてありますが

```shell-session
sudo cp iwlwifi-8265-22.ucode /lib/firmware
```
でファームウェア本体を移動し、その後は
`sudo reboot`でも`sudo modprobe iwlwifi`でもお好きな方で。

### 4. 動作確認
`ifconfig`すると、晴れて`wlan0`が立ち上がっているのが確認できるはずです。

## おわりに
同様に困ってる人が沢山いるんじゃないかとTwitterやNVIDIAのForumも見てみたのですが、皆さん意外と困ってらっしゃらないんですね。
有線接続で皆さんお使いなのでしょうか。（それか、無線LANカード挿すのが周知の事実なのか。）

以上です。良いXavierライフを。
sklearnのclassification_reportの結果がうまく表示されない

sklearnのclassification_reportをよく使うのだが、一つハマったことがあったのでメモ。

# classification_reportとは
以下sklearnの[公式ドキュメント](http://scikit-learn.org/stable/modules/generated/sklearn.metrics.classification_report.html)からの抜粋ですが、簡単に言うと予測ラベルと正解ラベルからprecision,recall,f1-scoreを算出しまとめてくれる機能です。

```python
from sklearn.metrics import classification_report
y_true = [0, 1, 2, 2, 2]
y_pred = [0, 0, 2, 2, 1]
target_names = ['class 0', 'class 1', 'class 2']
print(classification_report(y_true, y_pred, target_names=target_names))
```
この場合の結果は以下になる。

```
             precision    recall  f1-score   support

    class 0       0.50      1.00      0.67         1
    class 1       0.00      0.00      0.00         1
    class 2       1.00      0.67      0.80         3
avg / total       0.70      0.60      0.61         5
```

# ハマったこと
実際作成したモデルに対して一部のテストデータを使って検証する場合、ラベルが『綺麗に』揃っていない場合がある。

以下のようなケースです。

```python
from sklearn.metrics import classification_report
y_true = [1, 1, 2, 1, 1]
y_pred = [2, 2, 2, 2, 2]
target_names = ['class 0', 'class 1', 'class 2']
print(classification_report(y_true, y_pred, target_names=target_names))
```
この場合の結果は以下のようになる。

```
             precision    recall  f1-score   support

    class 0       0.00      0.00      0.00         4
    class 1       0.20      1.00      0.33         1

avg / total       0.04      0.20      0.07         5

```

class 1・・・・・・ ラベルが２なのでclass 2となるはずだが、class 1となってしまい、target_namesで定義したものと合わなくなってしまう。

また、以下のような警告が表示される。

```
UserWarning: labels size, 2, does not match size of target_names, 3
```

#解決策

以下のように、あらかじめclassification_reportの引数labels=にラベルとなる数字のリストを用意しておく。この場合は実際、labels=[0,1,2]が入っている。

```python
from sklearn.metrics import classification_report
import numpy as np
y_true = [1, 1, 2, 1, 1]
y_pred = [2, 2, 2, 2, 2]
target_names = ['class 0', 'class 1', 'class 2']
print(classification_report(y_true, y_pred, labels = np.arange(len(target_names)),target_names=target_names))

```
結果は

```
             precision    recall  f1-score   support
    class 0       0.00      0.00      0.00         0
    class 1       0.00      0.00      0.00         4
    class 2       0.20      1.00      0.33         1
avg / total       0.04      0.20      0.07         5
```

直りました。
【Python NumPy】コサイン類似度の求め方

## 算出式
![download.png](https://qiita-image-store.s3.amazonaws.com/0/64293/1f538a5f-abb8-c52e-8f21-713618638170.png)
コサイン類似度は、2つのベクトル間の角度のコサインを使用して、ベクトルの類似性を測定する方法です。値は-1（完全に逆）から1（完全に一致）までの範囲で、0は無関係を意味します。

## 具体例
|   | **X(vector)** | **Y(vector)** |
|  :------: | :------: | :------: |
|  **属性値a** | 0.789 | 0.832 |
|  **属性値b** | 0.515 | 0.555 |
|  **属性値c** | 0.335 | 0 |
|  **属性値d** | 0 | 0 |


```
cos(X, Y) = (0.789 × 0.832) + (0.515 × 0.555) + (0.335 × 0) + (0 × 0) ≒ 0.942
```

## 対応コード

関数

```py
import numpy as np

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

実行

```py
X = np.array([0.789, 0.515, 0.335,0])
Y = np.array([0.832, 0.555,0,0])

# cos(X,Y) = (0.789×0.832)+(0.515×0.555)+(0.335×0)+(0×0)≒0.942
print(cos_sim(X, Y))  #=> 0.9421693704700748
```

### numpyを使用しない版
※要動作確認

```py

# Define a function to calculate the dot product of two vectors.
def dot_product(a, b):
    return sum(x * y for x, y in zip(a, b))

# Define a function to calculate the magnitude (norm or length) of a vector.
def magnitude(vector):
    return sum(x**2 for x in vector) ** 0.5

# Define a function to calculate the cosine similarity between two vectors
# using the dot product and magnitudes.
def cosine_similarity(a, b):
    dot_prod = dot_product(a, b)
    mag_a = magnitude(a)
    mag_b = magnitude(b)
    similarity = dot_prod / (mag_a * mag_b)
    return similarity

# Example vectors
vector_a = [1, 2, 3]
vector_b = [4, 5, 6]

# Calculate cosine similarity
similarity = cosine_similarity(vector_a, vector_b)
print(f"Cosine similarity between 'vector_a' and 'vector_b': {similarity}")

```
Selenium のサンプル 予約フォーム (Java)

Selenium のサンプルです。

次のページをテストに使いました。
[予約フォーム](http://example.selenium.jp/reserveApp/)

```java:reserve_form.java
// -----------------------------------------------------------------------
/*
	reserve_form.java

				Sep/21/2018
*/
// ----------------------------------------------------------------------- 
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.By;
 
public class reserve_form {
 
// ----------------------------------------------------------------------- 
public static void main(String[] args) {
	System.err.println ("*** 開始 ***");

	String url = "http://example.selenium.jp/reserveApp/";

	WebDriver driver = new FirefoxDriver();
	driver.get(url);

	driver.findElement(By.id("reserve_month")).clear();
	driver.findElement(By.id("reserve_month")).sendKeys("11");

	driver.findElement(By.id("reserve_day")).clear();
	driver.findElement(By.id("reserve_day")).sendKeys("10");

	driver.findElement(By.id("reserve_term")).clear();
	driver.findElement(By.id("reserve_term")).sendKeys("3");

	driver.findElement(By.id("headcount")).clear();
	driver.findElement(By.id("headcount")).sendKeys("2");

	String str_select = "input[type='radio'][name='bf'][value='off']";
	WebElement item=driver.findElements(By.cssSelector(str_select)).get(0);
	item.click();

	str_select = "input[type='checkbox'][id='plan_b']";
	item=driver.findElements(By.cssSelector(str_select)).get(0);
	item.click();

	driver.findElement(By.id("guestname")).clear();
	driver.findElement(By.id("guestname")).sendKeys("明智小五郎");

	driver.findElement(By.id("goto_next")).click();

	System.err.println ("*** 終了 ***");
}

// ----------------------------------------------------------------------- 
}

// ----------------------------------------------------------------------- 
```

```text:Makefile
reserve_form.class: reserve_form.java
	javac reserve_form.java -cp ./client-combined-3.14.0.jar 
clean:
	rm -f reserve_form.class
```

実行方法

```bash
export CLASSPATH=.:./client-combined-3.14.0.jar:./guava-26.0-jre.jar:./okhttp-3.11.0.jar:./okio-2.0.0.jar:./kotlin-stdlib-1.2.60.jar:./commons-exec-1.3.jar
#
java reserve_form
```
Xcode 10 で外部ライブラリーなどの利用による自動生成のファイルがある場合、ビルドが通らず CI でコケる場合の対応

# TL;DR
要するにビルドシステムが変わってファイル管理の仕様が変わったからです

# 説明
Xcode 10 の移行により、今まで何の問題もなく動くし、ローカルでもビルドやテストが無事成功するのに、CI 側だけなぜか通りませんでした（もちろん CI 側の設定はすでに Xcode 10 に移行済み）。

通らない理由は `Build input files cannot be found: '.../Xxx.xxx'` でした。

もし上記の `Xxx.xxx` の部分は外部ライブラリーによる自動生成するファイルで、このファイルは `.gitignore` の設定によりバージョン管理外に置いてあるのでしたら、それはすなわちこのファイルがまだ生成されていないのに、Xcode が先に入力ファイル確認し始め、ファイルが見つからないことによってビルドがコケると言うことです。

この仕様に関しては [Xcode 10 のビルドシステムリリースノート](https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes/build_system_release_notes_for_xcode_10) に書かれてあります：

> If an output file which is generated by a shell script is used as an input elsewhere in the build (for example, to another shell script), then that output must be declared as an explicit output by the script that generates it; otherwise the build system may attempt to search for the file before it has been generated, causing the build to fail.
（訳：もしシェルスクリプトによって生成されるファイルがビルド時の別のどこかで入力ファイルとして使われる場合（例えば別のシェルスクリプトとか）、その生成されるファイルは明示的に「出力」としてそのシェルスクリプトの設定に記載しなければなりません；でなければビルドシステムはファイルが生成される前にサーチしますので、ビルドエラーが発生します。）

まあ言ってることはわかるが「明示的に記載」ってどう言うことやねん？っと色々ググってみたけど特に有益な情報が見つからず、しゃーないなと思ってとりあえずその設定のところで出力先のパスを追加してみたら、無事 CI が通りました（ローカルでも自動生成されるファイルをビルド前に手動で消せば確認できます）。

具体的にどこかと言うとここです：
![スクリーンショット 2018-09-21 15.49.02.png](https://qiita-image-store.s3.amazonaws.com/0/63998/c79a5e23-5632-5c6d-923c-9e3b32527477.png)

今やってるプロジェクトで [DIKit](https://www.github.com/ishkawa/DIKit) を利用していますが、これもまさに依存を自動生成で書き出しています。

と言うわけで皆さんも Xcode 10 対応頑張りましょう :muscle:
【Android】TimingLoggerを使ってAPIの処理時間を計測する

とりあえずシュッっと計測したい時にどうぞ。:rocket:

## `TimingLogger`
https://developer.android.com/reference/android/util/TimingLogger

## 実装例
`SampleApi()`の処理時間を計測する例です。

- TimingLoggerのインスタンスを作る。
- APIの`onSuccess`でdumpする。

```kotlin
val sampleApiLogger = TimingLogger("TIMING_LOGGER",
                                   SampleActivity::class.java.simpleName)
getSampleApi()
        .subscribe(
                { sampleData ->
                    sampleApiLogger.run {
                        addSplit("getSampleApi")
                        dumpToLog()
                    }
                },
                { e ->
                    e.printStackTrace()
                }
        ).let { disposables.add(it) }
```

## 計測の実行前にshellコマンドを叩く
shellコマンドでsetpropしてログ出力の設定をします。
`log.tag.TIMING_LOGGER`の部分を、先程の実装例にある`TimingLogger("TIMING_LOGGER", ...`のラベルと一致させてください。

```
$ adb shell
# setprop log.tag.TIMING_LOGGER VERBOSE
```

## 出力例
Android StudioのLogcatでログを確認できます。
ログレベルを`Verbose`に設定してラベルでフィルタ（今回の場合は`TIMING_LOGGER`）すると見やすくて便利です。

```
09-21 12:23:06.863 7867-7867/com.sample.sampleApp.debug D/TIMING_LOGGER: SampleActivity: begin
    SampleActivity:      861 ms, getSampleApi
    SampleActivity: end, 861 ms
```

## 参考リンク
- 処理時間の計測をAndroidで簡単に行う  
https://qiita.com/datsnet/items/1b868ced7c2fa8b4dcb0
Rubyのメソッドの引数でデフォルト式を与える場合は、通常の引数ではなく「キーワード引数」を使おう

# 概要

Ruby のメソッドの引数でデフォルト式を与える場合は、キーワード引数を使いましょう。
キーワード引数を使うことで、デフォルト式によって達成したい目的である、**関心の分離**が達成され、コードの見通しがよくなります。

```ruby
def foo(bar = 'baz'); end # 悪い例
def foo(bar: 'baz'); end # 良い例
```

実際にキチンとした例を見ていきましょう。

## 悪い例

```ruby
def hello(from = 'Me', to = 'World')
  puts "#{from}: Hello, #{to}!"
end
hello('Me', 'My World') #=> Me: Hello, My World!
hello('Tom') #=> Tom: Hello, World!
```

## 良い例

```ruby
def hello(from: 'Me', to: 'World')
  puts "#{from}: Hello, #{to}!"
end
hello(to: 'My World') #=> Me: Hello, My World!
hello(from: 'Tom') #=> Tom: Hello, World!
```

キーワード引数によるメリットを分解すると、以下の2つに分類できます。

* キーワード引数の場合は、必要な引数だけ指定できる
* キーワード引数の場合は、実引数の意味が分かりやすい

# 必要な引数だけ指定できる

概要で例としてあげた `hello` 関数の呼び出し方に注目してみましょう。
自分が作った `My World` に対して hello と呼びかけたいことをコードで表現してみましょう

```ruby
# 悪い例
hello('Me', 'My World')

# 良い例
hello(to: 'My World')
```

通常の引数を利用した場合は、我々の関心事は、 `My World` に対して hello したいということであるのに、 `Me` も指定する必要が出てきています。一体、`Me` って何のことなのでしょうか？
これでは、関心の分離が出来ていませんね。しかも、メソッド定義を変更した場合にリファクタ

これは、Rubyの仕様上、引数は個数と位置によって識別されている為、逃れられないことです。

一方、キーワード引数を利用した場合は、 `My World` のみを指定すればよく、関心の分離が達成されています。


# 実引数の意味が分かりやすい

概要で例としてあげた `hello` 関数の呼び出し方に注目してみましょう。
`Tom` に `Hello, World!` と喋ってもらいたいことをコードで表現してみましょう。

```ruby
# 悪い例
hello('Tom')

# 良い例
hello(from: 'Tom')
```

通常の引数の場合は、呼び出し側のコードを見るだけでは、実行される処理が分かりづらいですが、キーワード引数を利用することによって、呼び出し側のコードを見るだけで、何が実行されるかが明確です。


通常の引数では、`Tom` に対して hello しているのかな？ って勘違いしちゃいますよね。
しかし、通常の引数の場合、メソッド定義としては、 `from`, `to` という順序で引数を定義するのはごく自然なのです。

どうしてこのような事故が起きてしまうのでしょうか。

まず、一般的に、デフォルト式をもたせるメソッド名は、省略された状態で完全性を担保する必要があります。完全性が担保されるということは、メソッド名にもその完全性は現れます。つまり、 `hello_from` というような、目的語を取る複合動詞ではなく、`hello` というような、目的語を取らない複合動詞のメソッド名が選択されます。そして、選択されるべきです。この状態では、動詞たるメソッド名と、目的語たる引数の関係性は、メソッドというI/Fからは失われています。

更に、デフォルト式をもたせるメソッドは、デフォルト式を指定されない状態で呼ばれることが殆どです。それは、開発者がコードを書く時に、デフォルト式はコードの関心の外であるためです。しかし、このような状況が継続した場合、開発者の頭の中からはメソッドの定義は消えています。そう、関心の外になっているからです。当然、メソッド定義を読めば良いということですが、これは開発時（特にコードリーディング時）のオーバーヘッドになるので、コードがキチンと処理を表現する状態が望ましいです。

逆に、キーワード引数を利用した場合には、メソッドと引数の関係が `from` というキーワードによって明確になるので、メソッド定義に関心を向ける必要がなくなります。また、その関係性が呼び出し側のコードに明示されるため、開発者もメソッド定義まで立ち戻る必要はなくなるのです。

# まとめ

通常の引数を使うか、キーワード引数を使うか。
些細な違いが、コードの品質や開発効率に大きな違いを与えてしまうので、デフォルト式としてはキーワード引数を使うことをオススメします。
[GAE] 現在のリージョンを確認する方法

# 1. リージョン確認コマンド
以下のコマンドで現在のリージョンを確認できる。

```bash
> gcloud app describe --project <プロジェクトID>
```

* `<プロジェクトID>`にはGCP上のプロジェクトに割り当てられたIDを指定する

```bash
authDomain: gmail.com
codeBucket: staging.****.appspot.com
defaultBucket: ****.appspot.com
defaultHostname: ****.appspot.com
featureSettings:
  splitHealthChecks: true
gcrDomain: us.gcr.io
id: ****
locationId: us-central
name: apps/****
servingStatus: SERVING
```

# 2. 海外リージョンだと遅い

Firebaseでプロジェクト作成すると`locationId`が`us-central`になってた。
`us-central`リージョンだと日本からのアクセスでTTFB 531.93msかかる。遅い。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/67192/40caa7cc-9435-d93e-d87f-84508c136246.png)

# 3. 東京リージョン(asia-northeast1)にする

GAE側からプロジェクトを作成する際に`asia-northeast1`などの東京リージョンすると爆速になる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/67192/b97c019b-f813-da30-c8e4-661a99c63a62.png)
LINE Messaging API の署名検証で、AzureFunctions+Node.jsではまった所

# AzureFunctions上でMessagingAPIを使ったBOTを試す際に、署名の検証ではまった所
今までAzureFunctionsを使ったことのなかったので
@yorifuji　さんの
[LINE Messaging APIでX-Line-Signatureの署名検証を行う(AzureFunctions/Node.js）](https://qiita.com/yorifuji/items/71e31baf896adb69f567 "LINE Messaging APIでX-Line-Signatureの署名検証を行う(AzureFunctions/Node.js）")
とかを参考にLineのMessaginAPIを使ってBOTを作るにあたり、メッセージの署名検証ではまった所を記載します。

# request内のbodyではなくてrawBodyを使う
上記の記事ではrequestのbodyを利用して検証をしていましたが、bodyではなく、rawBodyの方（bodyの文字列）を利用しないと、最終的なhashがメッセージ内のsignatureと一致しないため、検証失敗することがわかりました。
細かなところですが、かなりはまったので、備忘録てきなメモで。
まぁ、素直に、LINEのnode.js用のsdkでも使っておけって言われそうですけどね。
[Ruby]integer 型カラムの値を to_s する際は encoding を確認しよう(更新：しなくてもよさそう)

※9/25：コメントを踏まえてタイトルを追記しました。とりあえずこの記事自体はこのまま残しておきます。

## 概要
例えばDBにこんな `sample_model` というテーブルがあったとします。

```ruby
def change
  create_table :sample_model, id: :integer, unsigned: true, options: 'ENGINE=InnoDB DEFAULT CHARSET=utf8mb4' do |t|
    t.string :name, null: false
    t.string :kind, null: false
    t.integer :sequence, default: 0, null: false
  end
end
```

そして、`sample_model` のレコードから取得した id を下記のように取得してみます。

```ruby
SampleModel.find(some_pkey).id
```

このとき、id を文字列に変換すると、文字コードはなんと **US-ASCII** になります。

```ruby
SampleModel.find(some_pkey).id.to_s.encoding
=> #<Encoding:US-ASCII>
```

string 型のカラムから値を取得した場合は **UFT-8** になります。

```ruby
SampleModel.find(some_pkey).kind.encoding
=> #<Encoding:UTF-8>
```

## 結論
今回の環境の場合、DB、テーブルではUTF8を使うように定義をしています。
対象のカラムが数値型であった場合でも、文字列に変換した場合に UTF-8 になることを期待していましたが
今回のように ASCII 文字になるケースがあることがわかりました。Ruby ~~もしくは Active Record~~ の仕様~~？なのかもしれません。~~みたいです。

あまりこういうケースも無さそうですが頭の片隅に置いておくと何かの役にたつかもしれません。

## 検証環境
- Ruby 2.4.2p198 (2017-09-14 revision 59899) [x64-mingw32]
- Rails 5.2.0
- MySQL 5.6.31
Generated Headerで定義が見つからないエラーの回避方法

割と限定的な条件で起こる問題ですが、いつか誰かの役に立つかもしれないので記事にしておきます。

## 問題
Generated Headerでモジュールがimportされているのに、クラスやプロトコルが見つからない旨のエラーが出る。

**Generated Headerとは**

 - SwiftコードのインタフェースをObjCに公開するためのファイル
 - ビルド時に自動的に生成される（クリーンしたら消えます）
 - デフォルトの命名では[プロジェクト名]-Swift.hとなっている

```objc:HogeProject-Swift.h
@import HogeModule;
```

```:エラー文言
Cannot find protocol declaration for 'HogeDelegate'
```

## 原因
Generated HeaderがObjective-C++（.mm）ファイルで読み込まれていると、Generated Headerに記載された`@import`は無効化されるようです。

Objective-C++（.mm）ファイルでSwiftコードを実行したい場合は、Generated Headerをインポートするための別クラス（別ファイル）を作成し、そのクラスを介してSwiftコードを実行すると回避できます。

## 学び
 - Objective-C++（.mm）ファイル　では直接Generated Headerをインポートしてはいけない
 - 別クラス（別ファイル）を作成し、そのクラスを介してSwiftコードを実行する
5分でScalaの特徴を把握する（Scala入門）

#はじめに
「Scala(スカラ)って知ってる？」
「ああ、守備力上げる呪文でしょ？」
「( ﾟДﾟ)ﾊｧ?」
ってならないように、Scalaを知らない人のために特徴をまとめました。

#scalaとは
- オブジェクト指向言語と関数型言語の特徴を併せ持ったプログラミング言語。
- 名前は「scalable language」に由来する。
- Java上で動作し、既存のJavaプログラムとの連携も可能。
- ライバルはgroovy？ パフォーマンスではScala圧勝・・・らしい。

#特徴
- すべてがオブジェクト。プリミティブ型はない。
- 静的型付けのため、コンパイル時点でエラーが検出される。
- 強力な型推論で自動的に、型を判断。なので宣言は変数か定数かを決めるだけ。

```
// 変数宣言
var user = getUser()		
var user: User = null　　　　nullはさすがに推論できないので型宣言が必要

// 定数宣言
val str = "TEST"	
```

- nullは使えるけど、できるだけ使わないほうが良いという方針。(Option型を使用。SomeかNoneか)
- 純粋関数型プログラミングが可能。(val(定数)と不変コレクション(List, Set,Map)を使う)
- 手続き型プログラミングも可能。(var(変数)と可変コレクション(List, Set, Map)を使う)
- 関数もオブジェクトとして扱うことが可能。
- 既存クラスの拡張も可能。(自動型変換宣言をすることによってメソッドを追加したようにみせることができる。)
- トレイトがある。(実装やフィールドを持ったインタフェース)
- クロージャの利用が可能。
- Buildツールが用意されている。(SBT)
- Javaのクラスの利用も可能。（Javaライブラリも利用可能)  ※ただしJavaとScalaのコレクションは異なるので変換する必要があり注意。けっこうめんどくさい。
- XML(HTML)を直接プログラム内部に記述可能。

```
var html =
<HTML>		
	<Body>	
		getcontent()
	</Body>	
</HTML>		
convert(html)
```
- 複数行文字列がある。
- 頑張れば、Androidアプリの開発も可能。

#デメリット
- 言語規約がとても多く、言語自体も割りと難しいので学習コストが高い。
- Webアプリ開発だと、Playフレームワーク 一択かも。(一応ほかにもある。)
- break, continueがない。(一応あるけど、try-catchで無理やり実装しているため、使いにくい。)

#その他
- javaの創設者(James Gosling)や、JRubyの開発者(Charles Nutter)が　「Scalaはjavaの後継者である」と言っている。
- Groovyの創作者(James Strachan)もScalaへの賛意を表明している。
- Twitterで2009年にバックエンドをRubyからScalaに移行した。
- PlayフレームワークはScalaをサポート。
- Scalaでは物足りないという人達が作ったScalazという狂ったライブラリもある。（Scalaのライブラリを補うライブラリ）
- scalaのeclipse用プラグインやscala用eclipseもある。


#最後に
上記の特徴を覚えておけば、いつか素敵な女性に「Scalaにお詳しいんですね。」
と言われるかもしれません。

ちなみに私は現場で「Scala使おうよ」と言ったら却下されました。
よってScalaの実務経験はなく、趣味でちょっと触っただけの素人ですが
いつか業務でも使ってみたいです。

でもほんとはkotlinがいいです。
Unityで行うGPU instancingについて

## はじめに
UnityではInstancingの方法が何パターンかあります．Instancing自体はそこまでハードルが高いものではありませんが，毎回1から書くのはめんどくさいと思うので，簡単なインスタンシングを実装したプロジェクトを作りました．よかったら[GitHub](https://github.com/KeitoTakaishi/GPUBatchExperiment)からcloneしてみてください．(Instancing_Surfの中身を見てみてください)また今回はComputeShader, ComputeBufferを平行して使用することを前提としております．

# コード解説(C#)

```C#
Graphics.DrawMeshInstancedIndirect(Mesh instanceMesh, int subMeshIndex, Material instanceMaterial, Vector3 bounds, ComputeBuffer argsBuffer);
```

このメソッドを用いることでInstancingを行うDrawCallを発行するすることが出来ます．これからひとつずつ必要な引数のデータについて見て行きましょう．

- Mesh instanceMesh : InstansingしたいMesh
- int subMeshIndex : 何番目のsubMeshかを指定する.
- Material instanceMaterial : Instansingするmeshに適応させるShader
- ComputeBuffer argsBuffer : InstancingするためのMesh情報を詰め込んだ配列情報．(↓を参考にしてみてください)

```C#
argsBuffer = new ComputeBuffer (int count, int stride, ComputeBufferType type);
args[0] = (uint)instanceMesh.GetIndexCount(subMeshIndex);
args[1] = (uint)instanceCount;
args[2] = (uint)instanceMesh.GetIndexStart(subMeshIndex);
args[3] = (uint)instanceMesh.GetBaseVertex(subMeshIndex);
argsBuffer.SetData(args);
``` 
# コード解説(Shader)
Shader側では`VertexShader+FragmentShader`と`VertexShader+Surface Shader`の２つの型があります．

# VertexShaderとFragmentShaderを用いる方法

##実行画像
![Unity 2019.1.1f1 Personal - [PREVIEW PACKAGES IN USE] - Instancing_Frag.unity - DrawMeshInstancedIndirect-Example - PC, Mac & Linux Standalone _DX11_ 2020_08_14 22_22_03 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184790/5c6b3ade-75bf-0d64-8f1a-d97b76bdc0b9.png)


## Target
Shaderは使用するバージョンによってGeometryやComputeShaderが使える使えないなど，使用出来る機能に差があります．Targetを指定することで，どのバージョンのShaderを使用するかを決定することが出来ます．
Targetについては[ここ](https://docs.unity3d.com/ja/2018.4/Manual/SL-ShaderCompileTargets.html)に詳しく書かれていますが，`#pragma target4.5`以上にすることでComputeShader，つまりComputeBufferを使用することが可能です．(今回はComputeShaderを使用するのでこの設定で)


## VertexShader
### 変換について
VertexShaderではComputeBufferに詰められた情報をもとに座標変換を行います．またここでの変換は通常の変換通り，Projection座標系までの変換を行います．

### InstanceIDの取得
Instanceをした際には個々のユニークなIDを取得することが出来ます．例えば，1万個MeshをInstanceした際には座標などを格納するComputeBufferも同じ数だけ用意し，このIDを頼りにアクセスしていけば個々の座標を動かしたり．．みたいなことが出来ます．
以下の例ではVertexShaderの引数に`uint instanceID : SV_InstanceID`を渡すことで参照可能となります．

```instancing_frag.shader
#if SHADER_TARGET >= 45
	StructuredBuffer<float4> positionBuffer;
#endif

//====================================================
//省略
//====================================================
v2f vert(appdata_full v, uint instanceID : SV_InstanceID)
{
#if SHADER_TARGET >= 45
	float4 data = positionBuffer[instanceID];
#else
	float4 data = 0;
#endif
	v2f o;
    float3 localPosition = v.vertex.xyz * data.w;
    float3 worldPosition = data.xyz + localPosition;
	o.vertex = mul(UNITY_MATRIX_VP, float4(worldPosition, 1.0f));
	return o;
}
```


## FragmentShader

```instancing_frag.shader
fixed4 frag(v2f i) : SV_Target
{
    return _Color;
}
```
armでアセンブラ

#概要
armでアセンブラやってみた。
hello worldやってみた。

#サンプルコード


```
.text
.global _start
_start:
 	mov 	r0, #1
 	ldr 	r1, = msg
 	mov 	r2, #13
 	mov 	r7, #4
 	svc 	0
_exit:
 	mov 	r7, #1
 	svc 	0
msg:
	.asciz "Hello World!\n"

```

以上。
Railsの開発環境でhttpsを使う

注意：puma前提

これをリファクタリングした
https://gist.github.com/tadast/9932075#gistcomment-2283895

この手法のメリットは、puma起動時にRubyスクリプトで証明書を発行するので、一度導入すれば開発者個人で証明書を作る必要がないこと

## 証明書置き場作成
```
$ mkdir config/certs && touch config/certs/.keep
```

```:.gitignore
/config/certs/*
!/config/certs/.keep
```

## 証明書作成・参照

`config/puma.rb` に以下を追加して、サーバー起動時に証明書を参照するようにする。
証明書がないなら勝手に作るようにする。

```ruby:config/puma.rb
if Rails.env.development?
  key_file = Rails.root.join("config", "certs", "localhost.key")
  cert_file = Rails.root.join("config", "certs", "localhost.cert")

  unless key_file.exist?
    root_key = OpenSSL::PKey::RSA.new(2048)
    key_file.write(root_key)

    root_cert = OpenSSL::X509::Certificate.new.tap do |root_ca|
      root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate
      root_ca.serial = 0x0
      root_ca.subject = OpenSSL::X509::Name.parse "/C=BE/O=A1/OU=A/CN=localhost"
      root_ca.issuer = root_ca.subject # root CA"s are "self-signed"
      root_ca.public_key = root_key.public_key
      root_ca.not_before = Time.now
      root_ca.not_after = root_ca.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity
      root_ca.sign(root_key, OpenSSL::Digest::SHA256.new)
    end
    cert_file.write(root_cert)
  end

  ssl_bind "0.0.0.0", "8443", {
    key: key_file.to_path,
    cert: cert_file.to_path
  }
end
```

## （Chromeのみ）localhostでSSLの警告を出ないようにする

やらなくてもいいですが、やっておくと便利

Chromeで以下にアクセス
`chrome://flags/#allow-insecure-localhost`

`Allow invalid certificates for resources loaded from localhost.` をEnabledにする。
<img width="757" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/15402/8597bc84-35da-e263-331f-ee0a5bde10a3.png">

## `rails server`

いつも通り`rails server`でサーバーを起動して、`https://localhost:8443/` にアクセスする。
何も間違えていなければ、これでhttpsで繋がるはず。
MySQL の Slow Log の log_output=table でも mysqldumpslow で解析したい

mysqldumpslow は log_output=file で出力されたファイルしか受け取りません。

[私が今使っている GCP の Cloud SQL だと、slow log をlog_output=table でしか受け取れません。](https://cloud.google.com/sql/docs/mysql-flags?hl=ja#tips-general-log)

そこで、`mysql.slow_log` テーブルからデータを取得して、log_output=file で吐くログと同じ形式にします。

```bash
mysql -h [host] -u[user] -p -D mysql -s -r -e "SELECT CONCAT( '# Time: ', DATE_FORMAT(start_time, '%y%m%d %H%i%s'), '\n', '# User@Host: ', user_host, '\n', '# Query_time: ', TIME_TO_SEC(query_time), ' Lock_time: ', TIME_TO_SEC(lock_time), ' Rows_sent: ', rows_sent, ' Rows_examined: ', rows_examined, '\n', sql_text, ';' ) FROM mysql.slow_log" > /tmp/mysql.slow_log.log
```

これで、以下のようにして slow log を解析できます。

```bash
mysqldumpslow /tmp/mysql.slow_log.log
```


https://cloud.google.com/sql/docs/mysql-flags?hl=ja#tips-general-log

# 参考資料

[MySQLでmysql\.slow\_logテーブルをslow queryログファイル形式でダンプする\|てくめも@ecoop\.net](https://www.ecoop.net/memo/archives/dump-mysql-slow_log-table-to-slow_query-log-file.html)

このサイトのコマンドは↑"や'が置換されてしまっていてコピペすると動きません。そのためこちらの記事を追加しました。


[mysql\.slow\_logテーブルからmysqldumpslowする \- Qiita](https://qiita.com/DianthuDia/items/d235f8fb563ffed89884)

こちらの記事のコマンドは私の環境ではうまく動きませんでした。
シェルスクリプトのエラー処理として -e を使うときに、エラーコードが取れるか？

シェルスクリプトのエラー時の処理としては、

1. シェルスクリプト内部でエラーハンドリングする
2. 「set -e」で、エラー発生時にスクリプト自体を止める

とか、いくつか方法があると思います。

今回、「2. の方法で、後からエラーコードって取れるのか？」が気になったので、ちょっと試してみました。

## 今回の記事の実行環境

* CentOS 7.5

## 用意したスクリプト

```sh:test.sh
#!/bin/bash
ls NULL # NULL は存在しないディレクトリ
ret=$?
[ "$ret" -eq "0" ] || echo "errorcode: $ret"
```

## 実行

まずは、普通に実行。

```sh
$ ./test.sh
ls: NULL にアクセスできません: そのようなファイルやディレクトリはありません
errorcode: 2
$ echo $?
0
```

エラー処理である echo が正常に完了しているので、`echo $?` は `0` ですね。エラーコードはスクリプト内で出力しているので、そちらの出力を見れば分かります。

次に、`-e` オプションを付与して実行してみます。

```sh
$ sh -e ./test.sh
ls: NULL にアクセスできません: そのようなファイルやディレクトリはありません
```

と、スクリプト内のエラー出力コードまで行かず、スクリプトは停止します。直後に `echo $?` を実行すると

```sh
$ echo $?
2
```

と。きちんと取れました。しかし、お分かりの通り、直後に同一のシェルで `echo $?` を実行しないと、エラーコードは取れません。

## おわりに

ということで、シェルスクリプトの実行時に「set -e」でエラー時に処理を止めた場合でも、そのあとで `echo $?` を実行すればエラー番号はちゃんと確認できることが分かりました。

この `-e` オプション、「ファイルの作成やデータ更新、削除」などの後続処理に入らずに止めてくれるので便利といえば便利ですが、~~「エラー時に一時ファイルを削除する」といった処理もできなくなってしまうので、「正常系だけ実行できればよく後処理なども無い (アトミックな処理) もしくは、割り切って後処理は手動でやる」ってくらいのスクリプトなら、いい感じにマッチしそうです。~~「特定の後続処理は残したい」場合には、スクリプト内でひと工夫が必要になります。[^1]

[^1]: コメント欄の @uasi さんのコメントが参考になります。ありがとうございます。
ECMWFのデータをNCLで読み込む時の注意点（scale_factor,add_offset）

ERA-interimのデータをNCLで描画するのにいろいろと手こずってしまっていて。苦笑
一つ解決したのでメモ

##参考URL
What are NetCDF files and how can I read them - Copernicus Knowledge Base - ECMWF Confluence Wiki https://confluence.ecmwf.int/display/CKB/What+are+NetCDF+files+and+how+can+I+read+them

##例
ERA-interimの相対渦度(Relative Vorticity）
※ある領域で切り取ったP面データ

```:ncl
printVarSummary(rv)
Variable: rv
Type: short
Total Size: 1487402072 bytes
            743701036 values
Number of Dimensions: 4
Dimensions and sizes:	[time | 124] x [level | 37] x [latitude | 337] x [longitude | 481]
Coordinates: 
            time: [1016832..1017570]
            level: [1..1000]
            latitude: [21..-21]
            longitude: [150..210]
Number Of Attributes: 7
  scale_factor :	1.571946344201145e-08
  add_offset :	-0.0001068763029856368
  _FillValue :	-32767
  missing_value :	-32767
  units :	s**-1
  long_name :	Vorticity (relative)
  standard_name :	atmosphere_relative_vorticity
```

桁が多くなるようなパラメータは、データ容量を少なくするためにscale_factorとadd_offsetを使うようになっている。

##対処法
scale_factorを掛け、add_offsetを加える。

```
正しい値 = (元の値 * scale_factor) + add_offset
```

##この処理が必要ない場合
参考URLには

```:https//confluence.ecmwf.int/display/CKB/What+are+NetCDF+files+and+how+can+I+read+them
●Matlab (ncread, ncwrite) applies Scale_factor and Add_offset automatically
●R (ncvar_get) applies Scale_factor and Add_offset automatically
●Panoply applies Scale_factor and Add_offset automatically. It also displays the values of Scale_factor and Add_offset, causing many users to believe they have to calculate something - no, you don't.
●Metview from version 5 onwards applies Scale_factor and Add_offset automatically; Metview 4.x does not.
●The Unidata NetCDF4 module for Python (which is an interface to the NetCDF C library) applies Scale_factor and Add_offset automatically
```

と書いてある。これらを使ったことがないのだけど…これらのツールの場合自動的に計算されるので、この処理は必要ない。
また、みんな大好きgradsも同様に自動的に処理されるので、不要。
R言語を用いたIIRフィルタの作成

初心者向きにR言語を用いたIIRフィルターの作成方法をまとめました。記事が冗長ですが、お許しください。
IIRフィルターは、ノイズ除去や特定の周波数帯域の信号抽出でよく用いられます。ローパスフィルターやバンドパスフィルター等として使うことができます。今回はR言語を用いて実装しました。


## パッケージの準備  
今回は signal パッケージ[1]を使用し、IIRフィルターを作成します。まず、パッケージをインストールします。

```R
#signalパッケージのダウンロード
install.packages('signal')
#ライブラリーの読み込み
library('signal')
```

入力データは10Hzと50Hzの正弦波の合成波を使用します。  

```R
#入力データの作成（周波数が10Hzと50Hzのサイン波のデータの合成、サンプリング周波数：1kHz、１０秒間のデータ）
time <- seq(from=0, by=1/1000, length=10000) #時間軸
data <- sin(2*pi*10*time) + sin(2*pi*50*time)
#入力データの図示
plot(time, data, t="l", xlim=c(1, 1.5))
```  

<img src="https://qiita-image-store.s3.amazonaws.com/0/293436/afe3ee6c-4af8-342c-526d-6d58e9578bd7.png" width=50%>

上図より、2つの周波数の合成波になっています。また、周波数解析を行うと、

```R
data_fft <- fft(data)
data_psd <- abs(data_fft)^2
plot_fft <- seq(from=1/10000, by=1000/10000, to=500)

#入力データの周波数特性の図示
plot(plot_fft, data_psd[1:(length(data_psd)/2)], t="l", log="x", xlab="frequency (Hz)", ylab="PSD (1/Hz)")
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/293436/6d9d9659-b211-2713-0422-91217dedb448.png" width=50%>


ピークが2つ（10Hzと50Hz）になっていることがわかります。

## IIRフィルターの設計
今回はIIRフィルターの一種であるButterworth filterを実装するために、signalパッケージのbutter()を使用します。帯域通過周波数が5〜15Hzのバンドパスフィルターを実装します。

```R
#バンドパスフィルタの設計
#バターワースフィルターの各パラメータ
fil_N <- 2 #フィルターの次数
fs <- 1000  #サンプリング周波数
fn <- fs/2  #ナイキスト周波数
fc <- c(5,15) #帯域通過周波数
#fc <- 5 #ローパスフィルターやハイパスフィルターでは、周波数の指定は一つの値のみ
fc_norm <- fc/fn  #周波数の正規化

butterworth_filter <- butter(fil_N, fc_norm, type="pass", plane="z")
```

butter()では、帯域周波数をナイキスト周波数で割った正規化周波数を使います。typeは、pass, low, high, stopの指定により、様々な種類のフィルターを実装できます。

## フィルター特性の確認

```R
freqz(butterworth_filter, Fs=fs)  #フィルター特性の図示
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/293436/65ba523c-574b-32fe-6e08-6b5c002cf460.png" width=70%>


5〜15Hzのバンドパスフィルターを設計できました。

## 設計したフィルターを入力データに通す

```R
#設計したフィルターを入力データに適応
data_fil <- filtfilt(butterworth_filter, data)
```

フィルターによる位相遅れを防ぐためにfiltfilt()を使用し、順方向と逆方向の両方の処理を行うゼロ位相デジタルフィルター処理を実装します。

## フィルターを通したデータの確認

```R
#フィルターを通したデータの図示
plot(time, data_fil, t="l", xlim=c(1, 1.5))
#周波数特性の図示
data_fft <- fft(data_fil)
data_psd <- abs(data_fft)^2
plot(plot_fft, data_psd[1:(length(data_psd)/2)], t="l", log="x", xlab="frequency (Hz)", ylab="PSD (1/Hz)")
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/293436/fad753f7-de2f-f381-c76b-75e13c82c5a7.png" width=50%><img src="https://qiita-image-store.s3.amazonaws.com/0/293436/c609c7f9-ebd8-792d-af72-31424f6ce668.png" width=50%>


フィルターにより50Hz成分がなくなりました。

### 参考文献
[1] Uwe Ligges et al. "Signal Processing", ver. 0.7-6, https://cran.r-project.org/web/packages/signal/signal.pdf, 参照Sept 21, 2018.
Goでビルドしたバイナリに製品名やファイルバージョンを追加する方法

# 概要

Go言語でWindowsのバイナリをビルドすると製品名やファイルバージョンなどがすべて空欄になってしまいます。
これらの値を設定してビルドする方法について記載します。

# 通常ビルド時

GoでWindowsのバイナリをビルドすると以下のようにexeのプロパティの詳細タブの値がすべて空欄となります。

![001.png](https://qiita-image-store.s3.amazonaws.com/0/278145/11da967d-b83a-d027-b529-6e3df546a113.png)

# 値の設定方法

[GoVersionInfo](https://github.com/josephspurrier/goversioninfo) を利用することで値を設定できます。

はじめに、GoVersionInfoのパッケージをダウンロードします。

```
go get github.com/josephspurrier/goversioninfo/cmd/goversioninfo
```

`GOPATH` にパッケージが配置されるので、パスを通しておきます。

```
set PATH="%GOPATH%\bin";%PATH%
```

Goのソースが配置されているフォルダに以下のファイルを配置します。
ファイル名は `versioninfo.json` 文字コードは `UTF-8` にしておきます。

```json:versioninfo.json
{
    "FixedFileInfo": {
        "FileVersion": {
            "Major": 1,
            "Minor": 0,
            "Patch": 0,
            "Build": 0
        },
        "ProductVersion": {
            "Major": 1,
            "Minor": 0,
            "Patch": 0,
            "Build": 0
        },
        "FileFlagsMask": "3f",
        "FileFlags ": "00",
        "FileOS": "040004",
        "FileType": "01",
        "FileSubType": "00"
    },
    "StringFileInfo": {
        "Comments": "",
        "CompanyName": "会社名",
        "FileDescription": "ファイルの説明",
        "FileVersion": "1.0.0.0",
        "InternalName": "test",
        "LegalCopyright": "Copyright (C) 2018 会社名",
        "LegalTrademarks": "",
        "OriginalFilename": "test.exe",
        "PrivateBuild": "",
        "ProductName": "製品名",
        "ProductVersion": "1.0.0.0",
        "SpecialBuild": ""
    },
    "VarFileInfo": {
        "Translation": {
            "LangID": "0411",
            "CharsetID": "04B0"
        }
    },
    "IconPath": "",
    "ManifestPath": ""
}
```

Goのソースの先頭に以下の行を追加します。

```golang:test.go
//go:generate goversioninfo
```

以下のコマンドでビルドを行います。

```
set GOARCH=amd64
set GOOS=windows
go generate
go build -ldflags "-s -w" -i
```

ビルドに成功すると `resource.syso` というファイルが生成され、バイナリには製品名やバージョンが埋め込まれます。

![002.png](https://qiita-image-store.s3.amazonaws.com/0/278145/8dd852c9-c339-7048-d313-cf51b1e54673.png)

---

まだ試してはいませんが、Goのソースの先頭を以下のようにするとアイコンやマニフェストも埋め込むことができるようです。
詳しくは [GoVersionInfo](https://github.com/josephspurrier/goversioninfo) のマニュアルを参照してみてください。

```golang
//go:generate goversioninfo -icon=icon.ico -manifest=goversioninfo.exe.manifest
```
SketchToolをインストールする方法

Sketch.app のなかに `install.sh` というファイルがある時期があるんだけど、バージョン 48 から、そのファイルがなくなるようになりました。 2018/9/21 現在使ってる最新バージョン (51.3) にもそういうファイルはもう存在していない。

試したことと解決方法は下記のようになります。

#### 手動でバイナリーファイルを移動してみる :x: 

cli ツールのローケーションはここに収納されています。

> /Applications/Sketch.app/Contents/Resources/sketchtool/

```
.
├── README.txt
├── bin
│   ├── sketchmigrate
│   └── sketchtool
└── share
    └── sketchtool
        └── resources.bundle
```

次のコマンドでコピーするのができます：

``` sh
cp bin/* /usr/local/bin/
cp share/* /usr/local/share
```

が、 `sketchtool` を実行してみると、こういう問題が出てきました：

``` sh
dyld: Library not loaded: @rpath/BCFoundation.framework/Versions/A/BCFoundation
  Referenced from: /usr/local/bin/sketchtool
  Reason: image not found
Abort trap: 6
```

Sketch社の人によると：

> Yes sorry about that. Since 48, we changed how we organize some stuff in our repo and the Libraries are now frameworks so when you install `sketchtool`, the frameworks are missing because they are not copied.
> 
> We are looking a nice solution but in the meantime, you can use `/Applications/Sketch.app/Contents/Resources/sketchtool/bin/sketchtool` directly

(https://sketchplugins.com/d/502-dyld-library-not-loaded/4)

とにかく、今は直接そのバイナリーファイルを使ってくださいっていうことになりました。

#### バイナリーのローケーションを `PATH` に追加する :o:

毎回フルパスを使ったらちょっとアレなんで、 `PATH` に追加して見みました。

``` sh
cat << EOF >> ~/.zshrc
# Add Sketch related tools
export PATH="\$PATH:/Applications/Sketch.app/Contents/Resources/sketchtool/bin/sketchtool"
EOF
```

＊ zsh 使ってない人は `./zshrc` を  `./bash_profile` とかに書き換えてください。

そして次のコメントを実行するとこの変更がすぐに反映してくれます。

``` sh
source ~/.zshrc
```

下記のように、実行して、問題なければこういうようなバージョンのアウトプットがプリントアウトしてくれます。

```
$ sketchtool -v
sketchtool Version 51.3 (57544)
```

以上です！

## 資料

- https://developer.sketchapp.com/guides/sketchtool/
- https://qiita.com/narikei/items/cc4cf9a649d9a138b1fd
- https://github.com/konifar/sketch-export-sample