OmniAICreator/Qiita-1.07M huggingface dataset:
Elasticsearchのaggregationを試す。

## Description
SQLで言うところの「group by」に相当するElasticsearchの「aggregation」機能を使ってみたので、それについてまとめた。

## Environment
* Elasticsearch: 6.3.2

## Setup
今回はdocker環境のElasticsearchを使用し、公式のサンプルデータで試してみた。
これらについては以下の記事を参照。

* [Install Elasticsearch with Docker        | Elasticsearch Reference 6.3      | Elastic](https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#docker-cli-run)
* [Loading Sample Data        | Kibana User Guide 6.3      | Elastic](https://www.elastic.co/guide/en/kibana/current/tutorial-load-dataset.html)

## Usage
aggregation機能はsearch apiに対して、「aggs」というキーの条件をつけると実行できる。
サンプルデータの場合、`logstash-*`インデックスがextensionというキーを持っているので、これを対象にしてaggregationを実行してみた。

```bash
curl -X POST -H "Content-Type:application/json" "localhost:9200/logstash-*/_search" -d '
{
  "aggs": {
    "by_extension": {
      "terms": {
        "field": "extension.keyword"
      }
    }
  }
}'
```

これを実行すると以下のような結果が返ってくる。

```json
{
  "took": 26,
  ...
  },
  "hits": {
    "total": 14005,
    ...
  },
  "aggregations": {
    "by_extension": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "jpg",
          "doc_count": 9165
        },
        {
          "key": "css",
          "doc_count": 2253
        },
        {
          "key": "png",
          "doc_count": 1303
        },
        {
          "key": "gif",
          "doc_count": 887
        },
        {
          "key": "php",
          "doc_count": 397
        }
      ]
    }
  }
}
```

この場合、extensionキーの値ごとにドキュメント数がカウントされている。
今回実行したものは、SQLで言うところの`SELECT extension, count(*) FROM logstash-* GROUP BY extension;`に相当する。

aggregation機能には、日付を元に一定間隔で含まれるドキュメントを集計したり、計算方法もカウント以外に数値データの合計や平均、最大を求めることもできる。
また、複数の集計条件を指定することも可能。
queryやfilterと組み合わせて「特定の条件で検索した結果に対して集計を実行する」ということもできる。

注意点としては、stringタイプのものを集計の基準に選ぶ場合は「xxx.keyword」を指定する必要がある。
集計が必要なインデックスについては、集計のキーをどれにするか、どのようなタイプで登録するかを予め考慮して設定しておいたほうが良い。

基本的な文法は上記のようになるが、詳細は公式サイトを参照が詳しい。

## Reference
* [Aggregations        | Elasticsearch Reference 6.3      | Elastic](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html)
Rubymine RSpec install 後、generatorコマンドの一覧にrspecコマンドが表示されない

1. `Gemfile`にRSpec追加
2. Terminalウィンドウから`bundle install`実行
3. Rubymineのgeneratorコマンド（`command+alt+G`）の一覧に`rspec:xxx`系のコマンドが表示されない


![image.png](https://qiita-image-store.s3.amazonaws.com/0/2883/929251f4-b194-5a90-090a-903d09332715.png)

**右上の`include hidden`にチェックを入れます。**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/2883/f4579f97-3e89-d528-792a-9e3816a29c55.png)
DCT (Discrete Cosine Transform)をPure Rubyで実装したgemを作りました

## 概要

DCT (Discrete Cosine Transform, 離散コサイン変換)をPure Rubyで実装し、gem化しました。

ソースコード: https://github.com/contribu/dct

## お願い

現状、O(N)の遅い実装なので、
O(log N)の高速な実装にしていただける方いませんか？

## 使い方

### インストール

以下をGemfileに追加

```ruby
gem 'dct'
```

bundle install

```bash
bundle install
```

### DCTII

```ruby
# prepare input
input = (1..3).map { |i| i}

# transform
output = Dct.dct_type2(input)
```

### DCTIII
```ruby
# prepare input
input = (1..3).map { |i| i}

# transform
output = Dct.dct_type3(input)
```
Volumio2を使用開始／再構築する際にハマったこと

Volumio、音楽サーバーにとても重宝です。

RaspberryPiにインストールして、NASに置いた音楽ファイルを再生したり、世界各国のWebRadioを聴いたり、AirPlayサーバーとしてスマホの音楽を家の再生装置で聴けたりするのです。

しかし、セットアップや再構築の時に、『簡単な手順なのに、分からなくてハマる』という事が起きます。
１年ちょっと使ったVolumioの調子が悪くなって、再構成しようとしたら、思いの外ハマってしまいました。

ここでは、そのポイントと解決法を紹介しましょう。


１．家のWifiに繋いでくれない

VolumioのSDカードを焼く時に、家のWifiに接続する設定を入れたつもりでした。
『だから、家のWifiにdhcpで接続してくれるはず』と、僕は思い込んでいました。

しかし、繋がってきません。

ARPを打ったり、モニターとキーボードに繋いでIPアドレスを見たりしました。

家のWifiネットワークに属さず、とんでもないアドレスを使っているのです。
家のWifi: 192.168.xx.0
VolumioのIPアドレス： 192.168.211.1

なんだこれ？
第３オクテットの２１１って、誰が指示してこんな値を使ってんの？
どこで指定するんだこんなの・・・・

と思いましたが、あれ？と思いました。
『Volumio』というSSIDがあるのです。VolumioがWifiを飛ばしている・・・

結論を言うと、まずクライアントPCがVolumioの提供するWifiに乗ります。
SSID: Volumio
接続キー： volumio2
この接続キーは、公式サイトに地味に書いてあります。
https://volumio.github.io/docs/User_Manual/Quick_Start_Guide

そして、volumio.localにアクセスすると、初回セットアップが始まり、ここでWifiクライアントの設定をすると、始めて家のWifiに乗ってきてくれるのでした。


２． NASを認識しない

NASのマウントが、うまくできませんでした。
まず、「共有フォルダを追加」ボタンを押した際に、『共有フォルダが見つかりません』という表示が出る時点で、少しテンションが落ちます。

気を取り直して、NASのホスト名、ここでは仮に『nas.local』としましょう。
接続待受方式はSMB、ユーザー名とパスワードはなしでOKでNASの共有フォルダを構成しています。
SMBの場合はCIFS、それ以外はNFSを選ぶようです。

しかし、次のようなエラーが表示されます（しかも一瞬だけ）。
`
(112): Host is down Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) 
`

現行のVolumioでは、SMBのバージョンはデフォルトでは３を使うそうです。
我が家のようにNASが古いと、新しいバージョンに対応していないため、接続エラーが発生します。

このような場合には、CIFS接続のオプションに、「vers=1.0」と書くと、SMB version1で接続を試みるので、うまく行く場合があるようです。

参考資料
https://efloral.jp/blog/archives/340
VB.net(WinForms)でのCefsharpの基本的な扱い方について

#はじめに
こんにちは。@masteralice3104こと「ますたー。」です。
Qiita初投稿です。

拙作の艦これ専用ブラウザ"[Admiral's Desk](https://ux.getuploader.com/masteralice3104/)"の開発にあたってCefsharpを採用しようとコーディングしていたのですが、そもそもVB.netでの資料が余りに(悲しいほど)少なかったので書き残すことにします。


#そもそもCefsharpとは
CefsharpとはChromiumの.NET用ラッパーみたいなものです。
でもWebbrowserコントロールの完全代替になるかというと「否」ですが、限定的な用途であれば十分実用となりそうです。




#ここでの前提

Visual Studio Community 2017 version 15.6.4
VB.net(.NET 4.6.2)でかつWinFormsを使用
Cefsharp.WinForms 65.0.0

#下準備

nugetでCefSharp.WinFormsをインストール

![スクリーンショット (216).png](https://qiita-image-store.s3.amazonaws.com/0/280107/d6a0cf04-3052-aa4e-b71b-952be0157bf3.png)

#基本

```vb:form1.vb

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    InitializeComponent()

    Dim settings = New CefSharp.CefSettings
    CefSharp.Cef.Initialize(settings)

    Dim browser = New CefSharp.WinForms.ChromiumWebBrowser("http://www.google.co.jp")
    Controls.Add(browser)
    browser.Dock = DockStyle.Fill

End Sub

Private Sub Form1_Exit() Handles MyBase.Closed

        CefSharp.Cef.Shutdown()

End Sub
```

細かいところは省略したが特に問題はないはず。

<br><br><br>


```vb
Dim settings = New CefSharp.CefSettings
CefSharp.Cef.Initialize(settings)
```

ここで作ったsettingでCefsharp自体をセットするのですが、設定の仕方は後ほど説明する予定です。
<br />

```vb
Dim browser = New CefSharp.WinForms.ChromiumWebBrowser("http://www.google.co.jp")
```

Cefsharpコンポーネントによるブラウザが(裏で)起動します。
感覚としてはwebBrowserコントロールのwebBrowser1.Navigate("URL")みたいな感じでしょうか。
ポイントは、この時点では表示がなされていないことです。(当然ですね)
<br />

```vb
Controls.Add(browser)
```

ここでようやくChromiumWebBrowserコントロールとして追加されます。が、表示にバグが有るようで
<br />

```vb
browser.Dock = DockStyle.Fill
```

としないと表示してくれない模様です。
<br />

```vb
CefSharp.Cef.Shutdown()
```

そしてCef.Shutdown()はMyBase.Closed時(つまりウインドウが閉じられる時)に呼ばれる関数です。れがないと暴走します。(あっても暴走するときがありますが)
後片付けはしっかり行いましょう。


#さいごに
ざっくりした解説なので補足等随時掲載します。
コードの間違いやバグなどあれば、教えていただけるととても嬉しいです。
Node.jsのMySQLでAsync/Awaitする方法

Node.jsのMySQLでAsync/Awaitする方法の日本語記事が見当たらなくて苦戦したので備忘録として残しておきます。

以下のように書けばAsync/Awaitがちゃんと効きます。

```hoge.js
var mysql = require('mysql');
const util = require('util');
var pool = mysql.createPool({
  connectionLimit: 10,
  host: 'hoge',
  user: 'hoge',
  password: 'hoge',
  database: 'hoge',
})
pool.query = util.promisify(pool.query) // この行がポイント！
try {
  var results = await pool.query('SELECT * FROM myDB')
  pool.end(); // mysqlのコネクションのプロセスを終了させる。（2018-11-07追記）
} catch (err) {
  throw new Error(err)
}
console.log(results)
```

ちなみにpool.query()はpool.getConnection() + connection.query() + connection.release()のショートカットらしいです。

ではでは。

参考記事
[Create a MySQL Database Middleware with Node.js 8 and Async/Await](https://medium.com/@matthagemann/create-a-mysql-database-middleware-with-node-js-8-and-async-await-6984a09d49f4)


（2018-11-07追記）
すみません、`pool.end();`がないとプロセスが終了しないということで追記しました。
@saoshi さん、ありがとうございました。
参考：[Node.jsのMySQLでAsync/Awaitしたらプロセスが終わらない](https://qiita.com/saoshi/items/728c11a55e99dfb8ad8e#_reference-ff561ff83a595f93a5d5)
オブジェクトのプロパティが更新されるまで待つ


ジョブにできたら `wait-job` が使えるんだけど。。。

```powershell
Function Wait-Status {
    Param(
        [Parameter(ValueFromPipeline=$True)]
        [object[]]$InputObject,
        [string]$Property,
        [object]$Value,
        [int]$Timeout = 3600 * 24,
        [int]$CheckInterval = 1,
        [string]$Indicator
    )
    Process {
        foreach($o in $InputObject){
            while($o.$Property -ne $Value){
                if($Indicator) { Write-Host -NoNewline "." }
                Start-Sleep -Seconds $CheckInterval
            }
        }
    }
}
```

`[object[]]$InputeObject` にしてるけど、並列では動かないので注意が必要。
elasticsearch利用例 Kibanaにて


##POST
###Curl
curl -XPOST "http://localhost:9200/product/default" -H 'Content-Type: application/json' -d'
{
  "name": "processing event with logtash",
  "instructor":{
   "firstname":"Taro",
   "lastname":"Yamada"
  }
}'

###kibana
POST /product/default
{
  "name": "processing event with logtash",
  "instructor":{
   "firstname":"Taro",
   "lastname":"Yamada"
  }
}

###Curl
curl -XPUT "http://localhost:9200/product/default/1" -H 'Content-Type: application/json' -d'
{
  "name": "wonderful kibana",
  "instructor":{
   "firstname":"Taro",
   "lastname":"Yamada"
  }
}'

###kibana
PUT /product/default/1
{
  "name": "wonderful kibana",
  "instructor":{
   "firstname":"Taro",
   "lastname":"Yamada"
  }
}

##GET

###Curl
curl -XGET "http://localhost:9200/product/default/1"

###kibana
GET /product/default/1

##Update(doc property)
###Curl
curl -XPOST "http://localhost:9200/product/default/1/_update" -H 'Content-Type: application/json' -d'

###kibana
POST /product/default/1/_update
{
  "doc":{ "price":99, "tags":["Elasticsearch"] }
}


##Update(script property)
###Curl
curl -XPOST "http://localhost:9200/product/default/1/_update" -H 'Content-Type: application/json' -d'
{
  "script": "ctx._source.price += 10"
}'


###kibana
POST /product/default/1/_update
{
  "script": "ctx._source.price += 10"
}



##Delete

###Curl
curl -XDELETE "http://localhost:9200/product/default/1"

###kibana
DELETE /product/default/1


##Delete Query

###Curl
curl -XPOST "http://localhost:9200/product/_delete_by_query" -H 'Content-Type: application/json' -d'
{
  "query":{
    "match":{
      "name": "wonderful kibana"
    }
  }
}'

###kibana
POST /product/_delete_by_query
{
  "query":{
    "match":{
      "name": "wonderful kibana"
    }
  }
}

##JSONデータをCurlで登録

事前にjson形式のファイルを、curl実行するディレクトリに置く
<img width="662" alt="スクリーンショット 2018-08-11 12.55.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/210201/e2854226-d498-e2ac-18f6-81991fbfa2db.png">

実行

```
$ curl -H "Content-Type: application/json" -XPOST "http://localhost:9200/product/default/_bulk?pretty" --data-binary "@products-bulk.json"

```
firebase入門をやってみた

下記のgoogleが出している入門に沿ってリアルタイムチャットサービスをあげてみた。
https://codelabs.developers.google.com/codelabs/firebase-web/index.html#14

もともとこの記事は日本語翻訳兼、要約されて出されていた下記から見つけたのだが、firebaseコンソール側の設定についての記述がなかった為だが、僕の読解力の問題かで、つまづいてしまったので元記事を参考に１からやり直したらすんなりいけた。
https://qiita.com/st5757/items/9e651e8cffaa90681426

作ったのはデフォルトそのままのものだが、こちら。
https://friendly-chat-930d2.firebaseapp.com/

少しUIデザインとコンセプトを変えるだけでもそのままポートフォリオアプリにできそうな感じなので、時間のあるときにいじってみようと思う。
elasticsearchのKibanaセットアップ

##前提
Mac OS 10.13.6

##Kibanaをダウンロード

elasticsearchのサイトからDL。https://www.elastic.co/products/kibana

<img width="1317" alt="スクリーンショット 2018-08-11 2.15.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/210201/9cd775d1-5be9-52ce-53f1-5fb9ab52c20c.png">

##kibana起動
適当なディレクトリにて解凍。ディレクトリに移動して起動する

```
MacBook-Pro:elasticsearch hitoshimurakami$ cd kibana-6.3.2-darwin-x86_64/
MacBook-Pro:kibana-6.3.2-darwin-x86_64 hitoshimurakami$ bin/kibana
```

なんやら色々エラーがでる。。セキュリティのPlugin X-Packがインストールされていないことが原因のようです。後ほど入れるとして今回は無視。

```
log   [17:21:38.734] [error][status][plugin:xpack_main@6.3.2] Status changed from red to red - X-Pack plugin is not installed on the [data] Elasticsearch cluster.
  
```

##ブラウザで確認
http://localhost:5601

kibanaの画面が立ち上がった
<img width="1590" alt="スクリーンショット 2018-08-11 2.31.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/210201/5da361fd-db99-b87c-d402-46af34432403.png">


###前提
　elasticsearchをkibanaと同じディレクトリ(elasticsearch)にてインストールしています。
<img width="599" alt="スクリーンショット 2018-08-11 2.33.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/210201/4f60c195-7f68-ad43-e6d9-8c1b904b04cf.png">
Macにelasticsearchをインストール


##JDKインストール
`
$ brew cask install homebrew/cask-versions/java8
`


##elasticsearchインストール
```
$ brew update
$ brew install elasticsearch
```

```
$  brew info elasticsearch
```

```
elasticsearch: stable 6.2.4, HEAD
Distributed search & analytics engine
https://www.elastic.co/products/elasticsearch
/usr/local/Cellar/elasticsearch/6.2.4 (112 files, 30.8MB) *
  Built from source on 2018-08-11 at 01:40:17
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/elasticsearch.rb
==> Requirements
Required: java = 1.8 ✔
==> Options
--HEAD
	Install HEAD version
==> Caveats
Data:    /usr/local/var/lib/elasticsearch/elasticsearch_hitoshimurakami/
Logs:    /usr/local/var/log/elasticsearch/elasticsearch_hitoshimurakami.log
Plugins: /usr/local/var/elasticsearch/plugins/
Config:  /usr/local/etc/elasticsearch/

To have launchd start elasticsearch now and restart at login:
  brew services start elasticsearch
Or, if you don't want/need a background service you can just run:
  elasticsearch


```

##~~パスを通す~~←今回はパス通す必要がなかったのでやめました。

`
vim ~/.bash_profile
`

```
bash_profile
export ELASTICPATH=/usr/local/var/elasticsearch/plugins/
export PATH=$PATH:$ELASTICPATH

```

##elasticsearch起動
```
$ cd /usr/local/Cellar/elasticsearch/6.2.4
$ bin/elasticsearch
```

実行確認。curlしてjsonが正常に返ってきた。

```
MacBook-Pro:6.2.4 hitoshimurakami$ curl http://localhost:9200
{
  "name" : "tnvsi2-",
  "cluster_name" : "elasticsearch_hitoshimurakami",
  "cluster_uuid" : "CkNLBgkgTvK3gioWuPTKWg",
  "version" : {
    "number" : "6.2.4",
    "build_hash" : "ccec39f",
    "build_date" : "2018-04-12T20:37:28.497551Z",
    "build_snapshot" : false,
    "lucene_version" : "7.2.1",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
```

###参考URL
https://qiita.com/y-temp4/items/ffafe1c0ea8a29ce8707
https://qiita.com/nbkn/items/01a11392921119fa0153
org.json.JSONObjectを使う際の注意点

Androidの開発でorg.json.JSONObjectを使った際にハマったことをまとめます。

# ①put(String key, java.util.Map value)
下記のテストをJUnit(Java)とAndroid test(Android）で行うと結果に違いがあります。

```java:JSONObjectTest.java
    @Test
    public void testJson() throws JSONException {
        Map<String, String> map = new HashMap<String, String>();
        map.put("key", "value");

        JSONObject json = new JSONObject();
        json.put("map", map);

        System.out.println(json.toString());
    }
```

```terminal:JUnit
{"map":{"key":"value"}}
```
```terminal:AndroidTest
{"map":"{key=value}"}
```

これはAndroidの[org.json.JSONObject](https://developer.android.com/reference/org/json/JSONObject)にput(String key, **java.util.Map value**)がないためです。
そのためAndroidではput(String key, **Object value**)が呼ばれます。

またパラメータ[value](https://developer.android.com/reference/org/json/JSONObject.html#put(java.lang.String,%20java.lang.Object))の制約として下記があります。
> Object: a JSONObject, JSONArray, String, Boolean, Integer, Long, Double, NULL, or null. May not be NaNs or infinities

このため、AndroidでMapをputすると上記のような結果となります。

# ②JSONObject(java.util.Map map)

①の解決方法としてJSONObjectへの詰め替えがありますが、これにも注意が必要です。

①のテストを下記のように修正して行うと。

```java:JSONObjectTest.java
    @Test
    public void testJson() throws JSONException {
        Map<String, String> map = new HashMap<String, String>();
        map.put("key", "value");

        JSONObject json = new JSONObject();
        // Map -> JSONObject
        // json.put("map", map);
        json.put("map", new JSONObject(map));

        System.out.println(json.toString());
    }
```

```terminal:JUnit
{"map":{"key":"value"}}
```
```terminal:AndroidTest
{"map":{"key":"value"}}
```

同じ結果になります。
ただし、MapのvalueをStringからnullに変更した場合問題が起きます。

```java:JSONObjectTest.java
    @Test
    public void testJson() throws JSONException {
        Map<String, String> map = new HashMap<String, String>();
        // String -> null
        // map.put("map", map);
        map.put("key", null);

        JSONObject json = new JSONObject();
        json.put("map", new JSONObject(map));

        System.out.println(json.toString());
    }
```

```terminal:JUnit
{"map":{}}
```
```terminal:AndroidTest
{"map":{"key":null}}
```

この違いの原因は正確にはわかりませんでしたが、おそらくリファレンスの

> In particular, calling put(name, null) removes the named entry from the object but put(name, JSONObject.NULL) stores an entry whose value is JSONObject.NULL.

という仕様が関係していると思われます。

そもそも、リファレンスには

> Values may be any mix of JSONObjects, JSONArrays, Strings, Booleans, Integers, Longs, Doubles or NULL. Values may not be null, NaNs, infinities, or of any type not listed here.

と書いてあるのでMap、nullあとListの扱いには注意（詰め替え）が必要です。
ボタン要素のinnerHTMLをクリップボードにコピーする奴

HTAで使う奴なのでコピー部分はwindow.clipboardData.setDataで実装。

    <button type="button" onclick="tagCopy(this.innerHTML)">hoge</button>


```javascript:js
function tagCopy(tags){
      window.clipboardData.setData( 'text', tags );
}
```
これでボタン毎にIDふったりしなくすむぞ(´^ω^｀)
php-master-changes 2018-08-10

PR の方はもうちょい動いてたりもして、本当の先端はそっちではあるんだよなー、などと思いつつ、とにかく今日も 1 コミットのみ！

# 2018-08-10
## weltling: Fixed bug #74484 MessageFormatter::formatMessage memory corruption
- https://github.com/php/php-src/commit/45a05f38410d4a67c8c83c09906e2cfb42fc6e4c
- ext/intl で、ICU のバグにより 11 以上のプレースホルダ指定を MessageFormatter::getFormats() に与えるとメモリ破壊でクラッシュする問題のワークアラウンド
- 実際に 11 以上与えるとタイムゾーンの設定必要な時ぶん投げてるのがだめそう……
- バグは[コレ](https://unicode-org.atlassian.net/browse/ICU-12584)かな
【初心者向け】USBカメラで撮影した動画をリアルタイムで顔検出

#はじめに
前回OpenCVを用いて静止画に対して顔検出を行なった．
　↓↓
[【初心者向け】OpenCVで顔検出を行う](https://qiita.com/yutoakaut/items/e813f9c05a02bcc7e996)

それを応用し，今回はUSBカメラから動画を取得してリアルタイムで顔検出を行なってみたいと思います．

#環境
- OpenCV v3.4.2
- VisualStudio2017
- 顔検出に用いるカスケード分類器（[ここからダウンロードしてください](https://github.com/opencv/opencv)）
- USBカメラ

※正面の顔を検出するカスケード分類器は，上記の GitHub からダウンロードしたファイルの
 "opencv-master\opencv-master\data\haarcascades"の中に入っている【haarcascade_frontalface_alt.xml】を使います．

#ソースコード
```cpp:detectFacefromCamera.cpp
#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"
#include <vector>

using namespace cv;
using namespace std;

int main()
{
    Mat frame; //USBカメラから得た１フレームを格納する場所
    CascadeClassifier cascade; //カスケード分類器格納場所
    cascade.load("ファイルまでのパス/haarcascade_frontalface_alt.xml"); //正面顔情報が入っているカスケード
    vector<Rect> faces; //輪郭情報を格納場所
    
    VideoCapture cap(0); // USBカメラのオープン
    if(!cap.isOpened()) //カメラが起動できなかった時のエラー処理
    {
        return -1;
    }
    
    while(1)//無限ループ
    {
        cap >> frame; //USBカメラが得た動画の１フレームを格納
        cascade.detectMultiScale(frame, faces, 1.1, 3, 0, Size(20, 20)); //格納されたフレームに対してカスケードファイルに基づいて顔を検知
        for(int i = 0; i<faces.size(); i++) //検出した顔の個数"faces.size()"分ループを行う
        {
            rectangle(frame, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), Scalar(0, 0, 255), 3, CV_AA); //検出した顔を赤色矩形で囲む
        }
        
        imshow("window", frame);//画像を表示．
        
        int key = waitKey(1);
        if(key == 113)//qボタンが押されたとき
        {
            break;//whileループから抜ける（終了）
        }
    }
    destroyAllWindows();
    return 0;
}
```
#実行結果
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">OpenCVを用いてUSBカメラから得た動画で顔検出 <a href="https://t.co/bZizivSoil">pic.twitter.com/bZizivSoil</a></p>&mdash; Yuto (@yutoakaut) <a href="https://twitter.com/yutoakaut/status/1027932409075970049?ref_src=twsrc%5Etfw">2018年8月10日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

顔は検出できていますが，誤検出がちらほらありますね．
他にもOpenCVを用いて色々試してみたいと思います．
Node.jsにてSyntaxError: Unexpected token  in JSON


JSONのパースでハマったのでメモ

connpassのAPIから情報取得していて、特定のイベントだけJSONのパースエラーが発生しました。

`SyntaxError: Unexpected token < in JSON`とかでも
`SyntaxError: Unexpected token } in JSON`とかでもなく
`SyntaxError: Unexpected token  in JSON`でした。

![](https://i.gyazo.com/66bf37fe26876d107be862e6389a9b2d.png)

文字変換などをするときに変な空白が入ることがあって、それが悪さしてしまっている模様。

`SyntaxError: Unexpected token  in JSON at position 418`って感じのエラーだったので

[文字カウントサイト](http://www1.odn.ne.jp/megukuma/count.htm)でカウントしつつ原因箇所を特定。

![](https://i.gyazo.com/4b2dc429bd8eeb0b8701d1d0b103dfe0.png)

確かにタイトルの`勉強会`の後ろに見えない空白が入ってました。ちなみに`trim()`では消えない模様。

![](https://i.gyazo.com/88ee87751f2f279b8f860450e009a242.gif)

空白でよくわからない状態でも`position 418`って出るのは優しいかな。。
グローバルスコープになっているユーザー定義のJavascript変数、オブジェクトを取得したい

複数のJavascriptが埋め込まれるようになってくると、ユーザー定義の変数やオブジェクトがグローバルに定義されているか知りたくなってきたんだけれども、
それらしい方法が見つからなかった。

window、top、selfオブジェクトからグローバルスコープのオブジェクトは参照できるので
下記のオブジェクトから

```js
for (item in window) {
  console.log(item);
}

```

とやればいいんだけれど、
windowオブジェクトの標準に備わっているプロパティ（onclick等々）も出力されてしまう。
https://developer.mozilla.org/ja/docs/Web/API/Window

なんとかして、ユーザ定義のだけ抽出したいということで、
苦肉の策で、空のウィンドウのwindowオブジェクト以下のプロパティ、メソッドの値を取得して、
それを除外したものがユーザ定義の変数、オブジェクトになるということでいけるじゃないかと思って
下記のスクリプト作ってみた。

```js

var n1 = 1;
let n2 = 2;
const n3 = 3;
n4 = 4;

function doSomething() {
   return true;
}

(function() {
// 即時関数を使うことで、この処理の変数がグローバルスコープにならないようにする。
　　　　　　　// ダミーのウィンドウを開く。これが邪魔なので本当は無くしたい。
    var win = window.open("","sample");
    for (item1 in window) {
      var userDefined = true;
      for (item2 in win) {
        if (item1 == item2) {
　　　　　　　　　　　　　　　　　　　　// 標準のプロパティで名前が存在したら出力しない
          userDefined = false;
          break;
        }
      }        
      if (userDefined) {
　　　　　　　　　　　　　　　　// 標準のプロパティでなかったものだけ出力する
        console.log(item1);
      }
    }        
}());


```

これを適当なサイトのブラウザのconsole上で実行する。
最初に、空のウィンドウが開いてしまうので、それは閉じてconsoleの結果を見ると、
ユーザ定義のグローバルスコープの変数、オブジェクトの名前が表示される。

ちなみに、下記のうち出力結果に表示されるのは「n1」と「n4」と「doSomething」

```js
var n1 = 1;
let n2 = 2;
const n3 = 3;
n4 = 4;
function doSomething() {
   return true;
}
```

空のウィンドウが表示されるのは邪魔だし、もう少し良い方法はないかな。。。
cgoを使ってGoでC言語の自作ライブラリを呼ぶ

自分で書いたC言語ライブラリを[cgo](https://golang.org/cmd/cgo/)でGoで利用する。

# C言語ライブラリ作成

ライブラリ化するプログラムは`hello.c`で`hello.h`がそのヘッダファイル。`main.c`はそのライブラリを使用するプログラム。

```c:hello.c
#include <stdio.h>
#include "hello.h"

void hello(void)
{
    printf("Hello, World!\n");
}
```

```c:hello.h
extern void hello(void);
```

```c:main.c
#include <stdlib.h>
#include "hello.h"

int main(int argc, char *argv[])
{
    hello();
    return EXIT_SUCCESS;
}
```

```bash
$ gcc -c hello.c
$ ar rusv libhello.a hello.o
$ gcc -o main main.c -L. -lhello
$ ./main
Hello, World!
```

# Goで自作ライブラリを使用する

下記のような`main.go`というプログラムを用意した。cgoはGoに標準で用意されているC言語プログラムをGoで使用するための機能。

```go:main.go
package main

/*
#cgo LDFLAGS: -L. -lhello
#include <hello.h>
*/
import "C"

func main() {
	C.hello()
}
```

`import "C"`が必要なパッケージのインポート。そのすぐ上に書いてあるコメントアウトがC言語を利用するためのコード。

```go
/*
#cgo LDFLAGS: -L. -lhello
#include <hello.h>
*/
```

ここにはC言語をそのまま記述することができて、ここで定義した関数をGoのコード上で利用できる。`LDFLAGS`でコンパイル時に使用するC言語ライブラリの情報を与える、これは前章の`$ gcc -o main main.c -L. -lhello`で指定した2つの引数と同じ意味。`-L`がライブラリの場所を指定するオプション。ライブラリは前章で作成した`libhello.a`で同じディレクトリ配下にあるので`.`だけ指定する。`-l`は使用するライブラリを指定する、指定の仕方は`lib`を除いたライブラリ名、つまり`libhello`から`lib`を除いた`hello`を指定する。あとは`hello.h`をインクルードして`hello()`関数を呼び出せるようにする。

実行結果は下記の通り。

```bash
$ go run main.go
Hello, World!
```
SO3のLOG

# SO3 Log の導出　備忘録

SfMなどにおいて3D空間での計算を行う時に，立体空間の回転行列を「ノルムが回転角度」で「方向が回転軸」となるベクトルから導出すること，　もしくははその逆が頻繁に行われる．
この計算がどのようにして行われているのかを整理した．

### **ベクトル↔︎回転行列**
ベクトル $\boldsymbol{\omega}_\times \in se(3)$ (厳密にはリー群)とそれに対応する行列$R \in SE(3)$の間を行き来するのが指数写像($se(3) \rightarrow SE(3)$)と対数写像($SE(3) \rightarrow se(3)$)である．

ベクトルから回転行列を導出するのは「ロドリゲスの公式」としてよく知られるが，今回はその逆を計算した．




### **ベクトル→回転行列**
以下のロドリゲスの公式で計算可能．
ベクトル$\boldsymbol{\omega}$を回転行列$R$に変換する．

````math
R = 
\left[
\begin{matrix}
n_1^2(1-cos\theta) + cos\theta & n_1n_2(1-cos\theta) - n_3sin\theta & n_1n_3(1-cos\theta) + n_2sin\theta \\
n_1n_2(1-cos\theta) + n_3sin\theta & n_2^2(1-cos\theta) + cos\theta & n_2n_3(1-cos\theta) - n_1sin\theta \\
n_1n_3(1-cos\theta) - n_2sin\theta & n_2n_3(1-cos\theta) + n_1sin\theta & n_3^2(1-cos\theta) + cos\theta
\end{matrix}
\right]
\\

\left(
\begin{matrix}
n_1\\n_2\\n_3
\end{matrix}
\right)
=\frac{\boldsymbol{\omega}}{|\boldsymbol{\omega}|}
,
\theta = |\boldsymbol{\omega}|

````

### **回転行列→ベクトル**
ロドリゲスの回転行列$R$は，いくつかの**対称行列**と**歪対称行列**の和と分解できる．
$\frac{R + R^T}{2}$で対称行列成分を，　$\frac{R - R^T}{2}$で歪対称行列成分を取り出すことができる.
歪対象成分$\frac{R - R^T}{2}$を$A$とする．

````math
A = 
\left[
\begin{matrix}
0 & - n_3sin\theta & n_2sin\theta \\
n_3sin\theta & 0 &  - n_1sin\theta \\
 - n_2sin\theta & n_1sin\theta & 0
\end{matrix}
\right]
````

また，この行列$A$は
$A = \frac{sin\theta}{\theta}\boldsymbol{\omega}_\times$を満たす

ここで，$\theta = |\boldsymbol{\omega}|$,

$\boldsymbol{n}=\frac{\boldsymbol{\omega}}{|\boldsymbol{\omega}|}
,$

とすると，

$A = sin\theta(n_1G_1 + n_2G_2 + n_3G_3)$
$A^2 = sin^2\theta(n_1G_1 + n_2G_2 + n_3G_3)^2$
$tr(A^2) = -2sin\theta$
$\sqrt{-\frac{tr(A^2)}{2}} = sin\theta$
$\theta = arccos\sqrt{1+\frac{tr(A^2)}{2}} \quad or \quad \theta = arccos(\frac{tr(R)-1}{2})$
※$arcsin$よりも$arccos$を使った方が簡潔（$\theta$の定義域を$[0, \pi)$にしたいため）
よって，　$A$から$\theta$と$sin\theta$が導出でき，
$\boldsymbol{\omega}_\times = \frac{\theta}{sin\theta}A$
として（厳密にはまだ行列の形であるが）ベクトルが計算できる


### 参考資料
http://ethaneade.com/lie.pdf
Facebook DetectronをWindowsで動かす

公式URL https://github.com/facebookresearch/Detectron

（開発者が自身で使用している）Linuxで動作確認しているけどWindowsで動くかは知らんぜよというケースがよくありますが、仕事で何か活用するぞとなるとほぼ100%がWindowsの状態で、簡単に「Linux入れれば使えるよ」と言うわけにもいかないので、かなりアドホックに修正しました。

##使用環境

- Windows 7
- GeForce GTX 1080
- CUDA 8+cuDNN v6（CUDA 9+cuDNN v7でも可）
- Visual Studio 2015 Update 3
- Python 2.7

## Caffe2 のビルド

公式にはWindows 10以上が必要となっていますが、Windowsバージョンが違うくらいで影響が出るようなAPI叩いたりしてないでしょと、Windows 7 で動かしました。

基本的には公式ドキュメントの https://caffe2.ai/docs/getting-started.html?platform=windows&configuration=compile の手順通りに行います。

使用したCaffe2 https://github.com/pytorch/pytorch/tree/a44d9d6eb40a28975967f5a7c7fb828b2429ad04

### Caffe2の修正

Detectronで使用するカスタムオペレータのDLLがそのままロードして使えないので、Caffe2本体に直接組み込むことにしました。
本来ならCaffe2の方をきちんとDLLを読み込めるように修正するのが筋でしょうが、Windows DLLの動作の仕組みもほとんど覚えてないので修正方法の見当をつけられませんでした。

1. pytorch/modules/detectron のファイル（CMakeList.txtを除く）を pytorch/caffe2/operators にコピー
1. pytorch/binaries/benchmark_helper.cc にダミーの sleep() 関数を作成
    - Windowsにはsleep()ないんだよ……
    - ベンチマーク用なので適当でよさそう
1. pytorcch/scripts/build_windows.bat の編集
    - https://github.com/munemasa/pytorch/commit/98080ef09acd6e718a38b0b21c1f7377c612443e
    - PYTHON_EXECUTABLE のパスは環境に合わせてください
1. ライブラリパスに python27.lib の場所を追加
    - https://github.com/munemasa/pytorch/commit/9ac3082942d5a9d4b52d7bb19de494fcb3815b77

あとは build_windows.bat を実行して、ビルド終わるのをお待ちください。

CUDA 9 を使った場合は Eigen ライブラリの修正する必要が出てきますが、エラーになった箇所(Half.hの204行目だったかな)はCaffe2で使われてない箇所なのでカットするだけでいいです。

## Detectronのビルド

公式ドキュメント通りにビルドを進めます。
コンパイルオプション指定のところでエラーになるので setup.py の -Wno-cpp は削除して make すればすんなり終わります……が実行するとエラーになるので、問題箇所を修正します。

### Detectron の修正

 - detectron/utils/cython_nms.pyx を修正
    - https://github.com/munemasa/Detectron/commit/6400ad18450bad7358aa3fb441b8230327b5c7f2
    - np.int_t が long 型で、LP64のLinuxとLLP64のWindowsでサイズ違っているのを修正します(LP64に合わせる)

## COCO APIの修正

Detectronで必要な COCO API もWindows対応版( https://github.com/philferriere/cocoapi )があるのでビルドは問題なく済みますが、実際にDetectronで使ってみるとエラーが起きるので修正します。

- メモリ解放処理を修正
    - https://github.com/munemasa/cocoapi/commit/fb4b17dd8d69d8f28310770b2253ff733544c231
    - Linuxだとそのままで問題ないですが、Windowsだとこうしておかないとダメでした。

## おわり

Detectronのテストコード(test_spatial_narrow_as_op.py)が正常に動くようなら、infer_simple.py で物体検出も動作することでしょう。
Vtuber用ツール（3Dモデル作成・トラッキング連動）覚書

絵をかけないアンドBlenderわからない初心者が3Dをやろうとすると、基本的にVRM形式のエコシステムに取り込まれる仕組みになっていることがわかった。

#3Dモデル作成支援
##VRM出力のみ
・Vカツ（8月末より）
・Vroid

##MMDほか出力対応
・Blender
・番外（開発中だそうです）https://twitter.com/xuarx
・Hitogata（pmx, fbxエクスポート可能）

##出力なし
・Vカツ（８月末まで）
・カスタムオーダーメイド3D2

#3Dモデルを動かす（Webカメラ）
##VRM対応
・3tene
・Wakaru https://store.steampowered.com/app/870820/Wakaru_ver_beta/
※モデル導入にUnityが必要なようですが、詳しい手順が私にはわかりませんでした……要チャレンジです
・Hitogata（ソフト内でモデル作成も可能）

##VRM非対応
・https://qiita.com/nise_aoi/items/7e1aca3506a05aa20644 （MMD対応）
・FaceVtuber　https://qiita.com/kotauchisunsun/items/dd2aa895321a55faf1a1 （MMD対応）
・FaceRig（Blenderモデル対応）

#3Dモデルを動かす（HMD）
・バーチャルキャスト（VIVE対応）
・FlipsideStudio（海外製ソフト・VIVEとOculusRift対応のようです）
HMDほしいです…。

#その他
・Kinect　https://materializer.co/lab/blog/14 （MMD対応、VRM対応なし）
・Oculus＋Kinectも（まだ調べてないが）おそらく同様にMMD対応のみか、Blenderモデルのみと思われる

#音声出力
・ゆかりねっと＋Softalkで声→字幕（クロマキー動画）・音声出力
※いわゆるゆっくり実況です
参考：
https://talkstone.web.fc2.com/
http://blog.livedoor.jp/yukkurim/archives/1064066435.html
http://ch.nicovideo.jp/ironia/blomaga/ar1468999
http://tatssuki.hatenablog.com/entry/2013/04/29/225600
http://yukkurilemon.blog29.fc2.com/blog-entry-7.html
・ゆかりねっと＋VOICEROID2以降で声→字幕（クロマキー動画）・音声出力
・テキストを字幕に反映＆並行してTTSソフトで音声出力
（TTSソフトにはTextalkなどがあり、Softallkよりも音声が豊富なのが利点だが、字幕反映と音声にモーションを当てる手間がかかる）
ボイスロイドほしいです…。

#BGM素材
H/MIX GALLERY
http://www.hmix.net/music_gallery/feeling/happy.htm
商用利用でない場合に限り無償
Peritune
http://peritune.com/
商用利用含め無償・ループ素材あり
どちらもハイセンスです

#録音・録画
OBS Studioを使用します。Hitogata単体でも録画・録音は可能ですが、OBSに「外注」したほうが要求スペックが少ないらしく、うちの低スペック気味パソコン（古めのMBA）でも比較的スムーズでした。
https://www18.atwiki.jp/live2ch/pages/491.html

#追記:Blender入門サイト
https://blender-cg.net/
http://www.cgradproject.com/tutorials/blender%E5%85%A5%E9%96%80/

#追記:こんなQiita記事がありました
https://qiita.com/Hirosaji/items/83777124823683766d96

#追記: こんなブログ記事等がありました
http://greety.sakura.ne.jp/redo/2018/07/vtuber201807.html
アバター技術を網羅性高くまとめてくださっています。
http://virtualyoutuber-sokuhou.com/?p=596
https://medium.com/@GOROman_1661/%E4%B8%AD%E3%81%AE%E4%BA%BA-%E4%BA%8C%E6%AC%A1%E5%85%83-%E3%81%AB%E3%81%AA%E3%82%8B%E6%96%B9%E6%B3%95-facerig-live2d-unity-obs-avvoicechanger-%E6%B0%97%E5%90%88-d49c3d456ed6
GOROmanさんはさすがです…。
http://greety.sakura.ne.jp/redo/2018/01/how-to-vtuber.html
https://monappy.jp/memo_logs/view/Clses/3135
http://shop-0761.hatenablog.com/entry/2018/01/08/034418
https://materializer.co/lab/blog/74

https://www.slideshare.net/naokiaso75/unite2014-live2d-x-unity-x-kinect-2
これを見ると（2012年）、当時より技術開発にチャレンジされてきた方々のおかげで、今のVR隆盛があるのだと実感できます。

#追記: WindowsでのKinect使用方法
https://wpteq.org/windows/windows10-manual/post-22791/
https://thinkit.co.jp/story/2012/07/03/3605
https://www.moguravr.com/virtual-youtuber-nora-cat/
Railsで、テーブルのメタデータを取得する

[先日書いた](https://qiita.com/jkr_2255/items/e7abdb29768c91e1bc11)ように、マスターデータが混沌としてきていたのですが、もう1つの対策として、「マスターデータやテーブル定義を確認できるツールを作ろう」という考えも出てきました。

そして調べたところ、Rails内部からデータベースの定義情報にアクセスすることも十分可能だったので、「別に確認ツールを作るより、そのままRailsに乗っかってしまったほうが手っ取り早い」と判断して、Rails内部にそのような開発ツールを構築しました。ここでは、そのツール作成に使った、メタデータの取得手段をまとめておきます。

なお、バックエンドとしてはRDBMS、特にMySQLを前提としています。MongoidなどActiveRecord以外では役に立たないでしょうし、RDBMSが違う場合にも細部が異なってくるかもしれません。

# 2通りの取得方法

RDBMSで作ったテーブルをRailsのモデルとして使う場合、改めて言うまでもありませんが、同じデータ群に「RDBMSのテーブル」と「ActiveRecordのモデル」という2つの側面が生じます。なので、メタデータの取得に際しても、「RDBMSのテーブルとして取得する」方法と、「ActiveRecordのモデルから取得する」という2通りの方法が存在することがあります。ただし、状況によっては両者で意味合いが異なってくることがあります。

# テーブル（モデル）のリスト

まずは、処理対象となるテーブル・モデルのリストを取得する方法です。

## RDBMS経由

```rb
ActiveRecord::Base.connection.tables # => テーブル名が文字列で入った配列が返ってくる
```

Railsから行う場合と比較して、メリットは「Railsのモデルがないテーブルも問題なく取得できる」、デメリットは「標準的でない名前のモデルを使っている場合、モデルクラスが取れない」という点です。

## ActiveRecord経由

ActiveSupportで[`Class#descendants`](https://railsguides.jp/active_support_core_extensions.html#%E3%82%B5%E3%83%96%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%A8%E5%AD%90%E5%AD%AB)が入っていますので、これを使って取得できます。

```rb
# 抽象クラスは除外
ApplicationRecord.descendants.reject(&:abstract_class?)
```

メリットとしては、「そのままActiveRecordとして使えるクラスが手に入る」「STIなどで、標準的でない名前になっているモデルも取得可能」ということがあります。一方で、[`config.eager_load=false`の場合に、その時点で読み込まれていた分しか拾えない](https://qiita.com/keigo-brook/items/2a1c7016927dee48ad2f)点には要注意です。

# 列の取得

テーブルが分かれば、どんな列があるのかも取得したくなります。モデル/テーブルの指定方法を除けば、列に関してはほぼ同じものが取れます。

```rb
# DBから
ActiveRecord::Base.connection.columns(:some_models)

# モデルから
SomeModel.columns
```

取れた`Column`オブジェクトには、`name`（列名）、`sql_type`（SQLでの型）[^1]、`null`（NULLを入れられるか）、`default`（デフォルト値）などの情報があります。

# インデックスの取得

Railsの世界からインデックスを直接アクセスする用事がないこともあってか、インデックスに関する情報はDB経由で取るしかありません。

```rb
ActiveRecord::Base.connection.indexes(:some_models)
```

これで`IndexDefinition`オブジェクトの配列が得られます。オブジェクトにあるメソッドとしては、`name`（インデックス自体の名前）、`columns`（かかっている列名の配列）、`unique`（ユニークインデックスかどうか）、`using`（インデックスの種類）などがあります。

# リレーションの取得

リレーションに関しては、DB経由とモデル経由で取れるものが大きく異なってきます。

## RDBMS経由

やはり、`ActiveRecord::Base.connection`から呼び出します。

```rb
ActiveRecord::Base.connection.foreign_keys(:some_models)
```

これは、データベースに対しての取得なので、「DB上で外部キーをかけたもの[^2]」、そして「自分のテーブルに制約がかかるもの（つまり、`belongs_to`なもの）」しか取れません。

## ActiveRecord経由

```ruby
SomeModel.reflect_on_all_associations
```

こちらはDBを読むわけではなく、モデルに宣言された`has_many`、`belongs_to`、`has_many through:`などのリスト、という位置づけです。`klass`で相手先クラスが取得できます。

# 脚注

[^1]: MySQLにBoolean型がないので、それは`tinyint(1)`で代用しています。
[^2]: よほどの理由がない限り、データベースでも外部キーは積極的にかけるほうが良いと考えます。
MagicCubeとGoogleHomeを連携させるのに8か月かかった話

検索しても引っかからなくて苦労したのでメモ

#簡単連携！・・・のはずだった
GoogleHomeとMagicCubeの基本的な設定をして、
Googleアシスタントのスマートホームからにデバイスを追加するだけで
シーリングライトがGoogleHomeから操作できる！・・・はずでした。

指定の手順通り、
スマートホーム⇒デバイスの追加⇒HomeMate⇒HomeMateのログインはできる。
ただ、次の「部屋に割り当てる」画面がでない。
一瞬出るけどすぐに消える。
「リンクされました」という画面は出るけど、追加されない。
ググってもでない。
ホストをスマホからタブレットに変えても変わらず。
Googleアシスタントとかの設定かとも思うが、ググってもでない。

#テレビかエアコンのリモコン登録が必要
ちゃんと本家にヒントがありました。
[http://blog.orvibo.jp/entry/2018/05/01/171227]

以下抜粋
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
テレビ又はエアコンを一つ以上MagicCubeに登録していないとGoogle Homeから見えません。
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
抜粋終了

ええ。
テレビのリモコンを追加したら、無事、「部屋に割り当てる」画面が表示されましたよ。
本命のシーリングの設定は終わっていないものの、
なんとか年末からやってきた作業に区切りがつけられそうです。
【gas】drive上のjsonファイルにアクセス

# 背景
健康管理のため、体組成計のデータをスプレッドシートに流し、これをグラフにしてgas使ってslackやらlineやらに送れるようにしていた。

これを[githubで管理したい](https://techblog.recruitjobs.net/development/maneged_google-apps-script_by_github)と思ったけど、token丸見え…

# 目的
というわけで、
tokenをJSONで別管理しよう

# 実装
https://github.com/msnaru/Management-for-healthcare

```js
function TokenImported() {

  var file_name = 'token.json';

  var fileIT = DriveApp.getFilesByName(file_name).next();
  var textdata = fileIT.getBlob().getDataAsString('utf8');
  var jobj = JSON.parse(textdata);
  
  Logger.log(jobj)
  
  return jobj;
}

  
  var jtoken = TokenImported(); 
  var token_slack = jtoken["token_slack"];
 
  var token_line_notify = jtoken["token_line_notify"];


```

# あとがき
初投稿。

gasはまるで勉強もせずに利用しているからファイルアクセスすらすぐにはわからなかった。
googledriveはコマンドプロンプトみたいにはいかんのね笑

```
./token.json
```

大変参考になりました
https://qiita.com/tanaike/items/94c263d3906ee23ad522


今度はIFTTTを利用した（何番煎じかわからない）健康情報管理か、機械学習系の記事をあげようかな。
Apple Developer Programのバイブルの新しいURL

iOSアプリ開発のバイブル的なドキュメント（と個人的に思っていた）「[アプリケーションの配布に関するガイド](https://developer.apple.com/jp/documentation/IDEs/Conceptual/AppDistributionGuide/Introduction/Introduction.html)」が、最近画像が見れなくなったりと残念な感じになっているので、代わりのドキュメントのURLのメモです。

# ライセンスや証明書関連

Developer Account Help (英語)
https://help.apple.com/developer-account/

# Xcodeの操作関連

Xcode Help (英語)
https://help.apple.com/xcode/mac/current/

# ストア公開操作関連

App Store Connect ヘルプ
https://help.apple.com/app-store-connect/

# たどり方

不思議とこれらのドキュメントがGoogle検索でひっからないので探すのに苦労していたのですが、実はこのページからたどれました。

サポート - Apple Developer
https://developer.apple.com/jp/support/

![スクリーンショット 2018-08-10 23.05.07.png](https://qiita-image-store.s3.amazonaws.com/0/95528/f71bf4bd-5abe-212f-9f3d-958994309448.png)

「アプリケーションの配布に関するガイド」の章立ては少しわかりにくかったですが、新しいヘルプは章立てがわかりやすいです。できれば日本語版もあればうれしいのですが。。。
メーリングリスト作ってみた

# はじめに
メールサーバに"メーリングリスト"を導入することになった。
備忘録を兼ねて、記事を残す。

# メーリングリストとは
メーリングリストとは、複数の人に同時にメールを送信する仕組み。
代表のメールアドレスにメールを送信すると、自動でリストに登録された人間に転送される。
イメージ画像だとこんな感じ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/108396/447b7e46-5a47-2a16-0b08-4d4b9d82c734.png)
今の時代、LINE・Slackとかあるから、使用する必要ないんじゃね...と思ってしまう。
大人の事情とかあるんだろうな...

# 実装
今回は、postfixが入っているメールサーバに、メーリングリストを導入する。

適当な場所にエイリアス用のファイルを作成(拡張子なし)

```
sudo vim /etc/postfix(任意のファイル名)
```

ファイルの中身は以下のように、

```
admin:test1@●●●.co.jp,test2@●●●.com,test3@●●●.co.jp...
```
`:`前に代表者のメールアドレス(ドメインは含めない)、`:`以降にリストに登録したい人間のメールアドレスを`,`区切りで入力する。

postfixのmain.cfを編集する

```main.cf
alias_maps = hash:/etc/postfix/aliases,hash:/etc/postfix/(任意のファイル名)
alias_database = hash:/etc/postfix/aliases,hash:/etc/postfix/(任意のファイル名)
```

そのあと、以下のコマンドを入力すると、`(任意のファイル名).db`が作成される。
```
sudo newaliases
```

さいごにpostfixをリスタートさせることで、メーリングリストが完成。
```
sudo service postfix restart
```

`admin@(ドメイン)`にメールを送ると、`test1@●●●.co.jp`、`test2@●●●.com`、`test3@●●●.co.jp`...にメールが届くはず...

# さいごに
この実装方法だと、リスト外のメールも一斉転送されてしまう。
セキュリテイ上あまり宜しくないため、改善する必要があるだろう...
検索してみると、`mailman`を一緒に使うと、リスト外からのメールの受付など色々設定できるらしい。
あと、普段サーバを触る機会が少ないので今後勉強していこう
Macで画面の指定範囲のGIFアニメーションを生成する


`screencapture`コマンドとImageMagickを利用して、画面の指定範囲のGIFアニメーションを生成するスクリプトです。

# 準備

- ImageMagickをインストール

```
$ brew install imagemagick
```

# スクリプト

```bash
#!/bin/bash

CAP_FRAME_NUM=10
CAP_INTERVAL_SEC=1
CAP_POS_X=0
CAP_POS_Y=0
CAP_WIDTH=200
CAP_HEIGHT=200

GIF_FRAME_INTERVAL_MSEC=100
GIF_WIDTH=$CAP_WIDTH
GIF_HEIGHT=$CAP_HEIGHT

# `screencapture`コマンドで指定範囲の画面キャプチャを指定秒間隔で生成
for i in `seq -w 1 ${CAP_FRAME_NUM}`; do
    screencapture -R ${CAP_POS_X},${CAP_POS_Y},${CAP_WIDTH},${CAP_HEIGHT} -m frame_${i}.png
    sleep ${CAP_INTERVAL_SEC}
done

# 画面キャプチャ画像群をImageMagickでGIFアニメーションに変換
convert -delay ${GIF_FRAME_INTERVAL_MSEC} -loop 0 frame_*.png -resize ${GIF_WIDTH}x${GIF_HEIGHT} animation.gif
```

# GIFの例

![animation.gif](https://qiita-image-store.s3.amazonaws.com/0/54161/39654573-852f-5717-883d-0693ba751ec2.gif)
Web API: The Good Partsまとめ

参考になった事をあとで振り返る用として。
## 概要
Web APIの設計、開発、運用についての解説書  

## PUTメソッド
- リソースを完全に更新する  
 
p:32

## PATCHメソッド
- リソースのごく一部を更新する  

p:32

## エンドポイント名で単語を繋げる際はハイフンを使う 
- ハイフンはGoogleが単語繋ぎとみなすがアンダースコアはひとつづきとみなすし、みづらい
- そもそも、極力繋がない表現にするのが良い  

p:41

## ページング系のクエリパラメータは絶対位置の方が良い 
- 相対位置の問題点はレコードを先頭から数えるためデータが増えると遅くなること。また、更新頻度が高いとズレが生じる
- 絶対位置とはIDや作成日時を指定する条件として使用することで、最終取得時の先端・末端レコードのIDや作成日時を保持し、次の情報はその保持したデータを元に参照すること。  
- FacebookのAPIなどがそうなっているので参考にすると良い

P:44, 45

## OAuth2.0  
- あるサービスの情報を別のサービスで利用できる仕様。トークンを元に利用できる 
- トークンには他のユーザーが利用できないように有効期限が設けられる 

p:49, 50, 51

## レスポンスの内部構造はなるべくフラットな方が良い
- データサイズが大きくなるし、必要以上な階層による表現は不要  

p:80

## ステータスコード  
よく使いそうなステータスコード

|ステータスコード|名前|意味|ケース|
|---|---|---|---|
|200|ok|リクエスト成功|参照|
|201|Created|リクエストが成功し、新しいリソース作成|登録|
|204|No Content|コンテンツなし|更新、削除|
|301|Moved Permanently|リソースが恒久的に移動|リダイレクト(キャッシュあり)|
|302|Found|リソースが一時的に移動|リダイレクト(キャッシュなし)|
|400|Bad Request|リクエストが正しくない|不正リクエスト|
|401|Unauthorized|承認が必要|認証エラー|
|403|Forbidden|アクセスが禁止|アクセス制限|
|404|Not Found|指定したリソースが見つからない|参照エラー|
|409|Conflict|リソースが矛盾した|排他制御|
|429|Too Many Requests|リクエスト回数が多すぎる|回数制限|
|500|Internal Server Error|サーバエラー|処理落ち|
|503|Service Unavailable|サーバが一時的に停止|同時アクセス制限|

p:103

## プリフライトリクエストはOPTIONメソッドを使う
  - プリフライトリクエストとは生成元を跨ぐリクエストの受け入れチェックのこと  
https://qiita.com/rooooomania/items/4d0f6275372f413765de

p:132


## オーケストレーション層を作る考え方 
   - 下記2タイプのAPIの特性から、データ量を調整する層を設けるとメンテし易い
    - 外部公開用のAPI(LSUDs)
       - 汎用的な設計のため単体目的の情報のみ返す傾向
    - 内部的運用のAPI(SSKDs)
       - 運用のユースケースに合わせた設計にするため複数目的の情報を含める傾向  
       
P:153  

## リクエスト再送信
- 繰り返しアクセスによる問題有無を判断し、リクエスト再送信を防ぐ。
  - ユニークなトークンなどを事前に保持する(サーバー側はセッション、クライアント側はhiddenなど)
  - トークンが合致すれば正常処理、合致しなければ不正処理とする
  - 決済や回数計測などで使用する

p:176

## 書籍情報
水野 貴明. Web API: The Good Parts
https://amzn.to/2wy6DQy
pandas-datareaderのis_list_likeがimportできない問題を解決(local,heroku)

#pandas-datareader問題
pandas-datareaderのfred.pyの
is_list_likeがimportできない

#一般的なﾛｰｶﾙ環境での解決策

```fred.py
#from pandas.core.common import is_list_like
from pandas.api.types import is_list_like
```
とする。

#herokuﾃﾞﾌﾟﾛｲ後のheroku環境での解決策(苦肉の策)

```mySite-settings.py
#pandas_datareader問題のため追加
import pandas
pandas.core.common.is_list_like = pandas.api.types.is_list_like
```

とする。

もっと、いい方法があれば教えてください。
テーブル設計

#　まとめ
1. データベースに保存する情報には「型」をつける
2. 数値の型にも種類があるが、使われるのはだいたいint型
3. 文字列型にもcharとvarcharがあるが、使われるのはだいたいvarchar型
4. データの削除にはレコード自体を削除する物理削除と、削除フラグを使って削除したことにする論理削除がある
5. テーブルやカラム名にはデータベースに登録される物理名と、自分たちが覚えやすく呼びやすくするための論理名がある

>[ウェブカツ！！](https://webukatu.com/?afid=p5lxu1kvh03rayd2ctjsw4e9bgzq8nom)
Gmailをマウスを触らずに操作する

# Gmailのショートカット

## 困ったら

[Googleのヘルプ](https://support.google.com/mail/answer/6594?co=GENIE.Platform%3DDesktop&hl=ja)をチェック

## ゴール

すこしずつマウスを触る機会を減らしていき、  
最終的にはキーボードのみでGmailを操れるようにする。

## 0.受信トレイを開く

* `g` → `i` : 受信トレイに移動(Go to Inbox)

## 1.メール閲覧

* 矢印 : スレッドを選択（タイトルの左に青い線が選択中）

* `o`（または`Enter`） : メールを開く

* `j` : ひとつ前のメールに移動

* `k` : ひとつ後のメールに移動

## 2.メール処理

* `e` : アーカイブする

* `Shift + a` : 全体に返信（右下に別ウインドウ） 

* `s` : スターをつける

## 3.より高度なメール閲覧

* `g` → `s` : スター付きのスレッドに移動（Go to Star）

* `g` → `l` : ラベルに移動。（Go to Label）

  * 検索フォームに「label」とついて移動するので、ラベル名を検索して移動できる

* `/` : 検索フォームに移動（viライク）

## 4.より高度なメール処理

* `]` : アーカイブして前に移動

* `[` : アーカイブして後に移動

## 5.メール作成

* `c` : 新規メールを作成して、宛先入力欄に移動

* `f` : 転送

* `Ctrl + Shift + c` : Cc入力欄に移動

* `Ctrl + Enter` : 送信
モンテカルロ法をPythonでシミュレーションしてみた。

モンテカルロ法はカジノのルーレットで用いられる賭け方の一つです。
ある一定の規則に従って賭け金を増やしていくという手法です

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

```python:Monte_Carlo_test.py
import random
import numpy as np
import matplotlib.pyplot as plt

A=0
B=0
ML = [1,2,3]
M=1000000 #資金
M_ini=M#初期資金
count=1000#試行回数
x = np.zeros(count)

for i in range(count):
    bet_A=ML[0]
    bet_B=ML[len(ML)-1]
    bet=bet_A+bet_B

    if len(ML)==1 or len(ML)==2 :
        ML=[1,2,3]

    num = random.random()
    
    if num >= 0.5 :
        print("win")
        A=A+1
        elm = ML.pop()#リストの末尾から要素を1つ取り出す
        elm = ML.pop(0)#引数にリストのインデックスを取り、その要素を取り出す
        M=M+1*100*bet
    else :
        print("lose")
        B=B+1
        ML.append(bet)
        M=M-1*100*bet
    
    x[i]=M

print("資金増加率:{}".format(M/M_ini))

plt.plot(x, label="money")
plt.legend()
plt.show()
```

#結果
##資金が1,000,000円の場合．
######試行1

```text:出力
資金増加率:1.0614
```

![monte_test.png](https://qiita-image-store.s3.amazonaws.com/0/192626/42d6a5fc-91e9-510c-7c8c-9b49025c0b61.png)

######試行2

```text:出力
資金増加率:1.0507
```
![monte_test2.png](https://qiita-image-store.s3.amazonaws.com/0/192626/e5a23b87-7ce4-8bdf-d148-642593b028d6.png)

######試行3

```text:出力
資金増加率:1.0775
```
![Figure_1.png](https://qiita-image-store.s3.amazonaws.com/0/192626/b2fff4f6-00e8-75f3-b133-2a8f33de66fb.png)

##資金が100,000円の場合．

######試行1

```text:出力
資金増加率:-0.011
```
![Figure_1-1.png](https://qiita-image-store.s3.amazonaws.com/0/192626/a99aedd4-adb1-0595-7bf6-c4667d2e7389.png)

######試行2

```text:出力
資金増加率:1.984
```
![Figure_1-2.png](https://qiita-image-store.s3.amazonaws.com/0/192626/086a7d95-56f8-87cf-95ce-837a0861cdda.png)

######試行3

```text:出力
資金増加率:12.969
```
![Figure_1-3.png](https://qiita-image-store.s3.amazonaws.com/0/192626/f64a7367-accc-4239-380e-a0f5a27907fa.png)



#考察
途中，資金が急激に減る場面もありましたがおおむね上昇しています．負けが込んでくるごとに資金を増やしていくモンテカルロ法の特徴がよく出ていると思います．しかし，初期資金を減らして試行すると不安定になりマイナス，つまり破産になることもあります．資金増加率は低いですが，やはり資金が多いほど有利になると考えられます．
Windows環境でffmpegを使ってmp3ファイルをAlexa対応形式に複数ファイル一括変換するメモ

Amazon Alexaでスキルを作る時、流せるmp3の制約が結構厳しいと思ってます。

Amazonのサイトに載ってる仕様に音声ファイルを変更する際にffmpegを使う場合、1つ1つ変換するのが、すこぶるめんどくさくて仕方がないので、以下のように書いてしまいました。

エラーハンドリングとか何もしてないです。


こういうのはMacユーザの記事が多い(と勝手に思っている)ので、あえてタイトルに「Windows」と記載しました。


```bat:ffmpeg_alexa.bat
@echo off

for /f "usebackq delims==" %%i in (`dir .\*.mp3 /b`) do ffmpeg.exe -i "%%i" -ac 2 -codec:a libmp3lame -b:a 48k -ar 16000 ".\after\%%~ni_after.mp3"

echo 一括変換だ
```

↑を適当なテキストファイルにコピペして拡張子を .bat にしてあげて、ffmpeg.exeがあるフォルダに配置します。
同じフォルダに事前に変換後のmp3ファイルが格納される after というフォルダを作っておきます。
変換したいmp3ファイルをffmpeg.exeと同じフォルダに入れておいて、このbatファイルをダブルクリックします。

すると不思議なことにafterフォルダに変換後のmp3たちが配置されているはずです。

このbatファイルで何をしてるかわかる人、この場合は動かないだろ とか言える人は、特にこのファイルを必要としないと思います。

けれども、Alexaスキルをこれから作る開発初心者でWindowsユーザの方がいるかもしれないし、その方がgit使えるかもわからないので、もうそのまま記載しておきました。
よく使う Puppeteer の処理

https://qiita.com/rh_taro/items/32bb6851303cbc613124
上の記事に追加するような形で。

2018/08/14 更新
（編集リクエスト頂ければクレジットと共に掲載します）

## キーボード操作
```javascript:index.js
await page.focus("#id");
await page.keyboard.down('Shift');
await page.keyboard.press('KeyO');
await page.keyboard.press('KeyK');
await page.keyboard.up('Shift');
```

## 要素の座標を取得
```javascript:index.js
page.offset = async (selector)=>{
    let elem = await page.$(selector);
    return await elem._clickablePoint()
};

//使用例
let offset = await page.offset("#ib");
await page.mouse.click(offset.x,offset.y);
```

## フォームのクリア
https://github.com/segmentio/nightmare/issues/810

```javascript:index.js
page.clear = async (selector)=>{
    let elem = await page.$(selector);
    await elem.click();
    await elem.focus();
    await elem.click({clickCount: 3});
    await elem.press('Backspace');
};

//使用例
await page.clear("#id");
```

## ラジオボタン選択
クリックの後少し待たないとそのあとの処理がおかしくなる（原因不明）

```javascript:index.js
page.radio = async (name, val) => {
    this.page.click(name + '[value=\'' + val + '\']');
    await this.page.waitFor(500);
};

//使用例
await page.radio("#id","1");
```
embulk で BQ in BQ out で Partitioned tables に躓いた

#やりたいこと
Embulk で BigQuery -> BigQuery がやりたい。
out側のテーブルは Partitioned tables としたい（DATE型またはTIMESTAMP型のカラムを指定）

#やったこと
embulk-input-bigquery
embulk-output-bigquery
を用いて、実行したが、どうも Partitioned tables だとうまく動かない。

あらかじめ out側の BigQuery で以下のようなものを実行して Partitioned tables を作成しておく。

```sql
CREATE TABLE mydataset.newtable (transaction_id INT64, transaction_date DATE)
PARTITION BY TIMESTAMP(transaction_date)
```

in側で TIMESTAMP型のカラムを作り、out側に流してみたものの Partition 絡みでエラーがでてしまい実行できなかった。
おそらく embulk-output-bigquery が Partitioned tables に対応しないとダメそう。
Tables partitioned by ingestion time の方には対応しているので、今回はそちらで対応することにした。
もちろん[前の記事](https://qiita.com/Tomoyuki_Mikami/items/e22b989341b6b88cbfa0)のように Cloud Dataflow など使えば問題なくできる。
[JavaScript] jQuery Deferred で非同期処理を直列実行（逐次実行、順次実行）

JavaScriptでは、非同期処理が連続するとインデントが深くなりがちですが、jQuery の Deferred を利用すると、ややスッキリ書けます。

# ![](//goo.gl/tuSQrq) Deferred

取り急ぎサンプルソースを。

```JavaScript:JavaScript
// １つめの非同期処理
(function() {
	var d = new $.Deferred();
	setTimeout(function() {
		alert("1");
		d.resolve(); // 次の処理へ
	}, 1000);
	return d.promise();
})()
// ２つめの非同期処理
.then(function() {
	var d = new $.Deferred();
	setTimeout(function() {
		alert("2");
		d.resolve(); // 次の処理へ
	}, 1000);
	return d.promise();
})
// ３つめの非同期処理
.then(function() {
	var d = new $.Deferred();
	setTimeout(function() {
		alert("3");
		d.resolve(); // 次の処理へ
	}, 1000);
	return d.promise();
});
```

ただ、毎回 Deferred を new したり、promise を return したりで、ちょい面倒でもあります。

# ![](//goo.gl/tuSQrq) MyAsync.js

『[MyAsync.js](https://qiita.com/yasumodev/items/883c2d92ab6d9dc3414b)』 を使うと、もうちょいシンプルに書けますよ。

```JavaScript:JavaScript
MyAsync.run(
	// 非同期処理１
	function(baton) {
		setTimeout(function() {
			alert("1");
			baton.next(); // 次の処理へ
		}, 1000);
	},
	// 非同期処理２
	function(baton) {
		setTimeout(function() {
			alert("2");
			baton.next(); // 次の処理へ
		}, 1000);
	},
	// 非同期処理３
	function(baton) {
		setTimeout(function() {
			alert("3");
			baton.next(); // 次の処理へ
		}, 1000);
	}
);
```

(･o･ゞ いじょー。
UltraZed 向け Debian GNU/Linux (v2018.2版) の構築(PMUFW編)


## はじめに

UltraZed-EG スターターキットに Debian GNU/Linux (v2018.2版) を構築する方法について、具体的な方法をいくつかに分けて説明します。

 * [Introduction](https://qiita.com/ikwzm/items/5b657ebd8895945c4eae)
 * [Boot Loader](https://qiita.com/ikwzm/items/a0dfef6355cf839ebc08)
   - [Sample FPGA Design](https://qiita.com/ikwzm/items/aae6e17e7d08b089e010)
   - [FSBL   (First Stage Boot Loader)](https://qiita.com/ikwzm/items/a94c79d78b89fc2e31f8)
   - __PMUFW  (Platform Manager Unit Firmware)(この記事)__
   - [BL31   (ARM Trusted Firmware Boot Loader state 3-1)](https://qiita.com/ikwzm/items/4735be0fbdd1e51c7c59)
   - [U-Boot](https://qiita.com/ikwzm/items/2a7006b6c70c8fa397dc)
   - [BOOT.BIN](https://qiita.com/ikwzm/items/d0482bf8bfc7912ff746)
 * [Linux Kernel](https://qiita.com/ikwzm/items/d5417b39c983f8e56af9)
 * [Debian9 Root File System](https://qiita.com/ikwzm/items/a0e88798ed29b30fa003)

この記事では、ZynqMP の Boot Loader で使うための PMUFW  (Platform Manager Unit Firmware) の構築について説明をします。

## 必要な環境

 * Vivado SDK 2018.2

## Sample FPGA Design の構築

PMUFW の構築には Sample FPGA Design のハードウェア情報が必要です。[「UltraZed 向け Debian GNU/Linux (v2018.2版) の構築(Sample FPGA Design編)」](https://qiita.com/ikwzm/items/aae6e17e7d08b089e010)の通りに target/UltraZed-EG-IOCC/build-v2018.2/fpga/project.sdk/design_1_wrapper.hdf を作っておきます。

## PMUFW の構築

ここでは Vivado の hsi(Hardware Software Interface) を使って構築する方法を示します。GUI を使って手で入力するのは面倒なので Tcl スクリプトファイルを用意しています。Tcl スクリプトの詳しい内容は[「Vivado SDK でZynq FSBL(First Stage Boot Loader)をビルドするTclスクリプト(hsi編)」](https://qiita.com/ikwzm/items/e09fab6b17986471cbda)を参照してください。

```Tcl:target/UltraZed-EG-IOCC/build-v2018.2/fpga/build_zynqmp_pmufw.hsi
#!/usr/bin/tclsh

set app_name          "pmufw"
set app_type          "zynqmp_pmufw"
set hwspec_file       "design_1_wrapper.hdf"
set proc_name         "psu_pmu_0"
set project_name      "project"
set project_dir       [pwd]
set sdk_workspace     [file join $project_dir $project_name.sdk]
set app_dir           [file join $sdk_workspace $app_name]
set app_release_dir   [file join [pwd] ".." ]
set app_release_elf   "zynqmp_pmufw.elf"

set hw_design         [open_hw_design [file join $sdk_workspace $hwspec_file]]

generate_app -hw $hw_design -os standalone -proc $proc_name -app $app_type -compile -dir $app_dir
file copy -force [file join $app_dir "executable.elf"] [file join $app_release_dir $app_release_elf]
```


build_zynqmp_pmufw.hsi を Vivado で実行することにより、target/UltraZed-EG-IOCC/build-v2018.2/zynqmp_pmufw.elf が生成されます。

```console
vivado% cd target/UltraZed-EG-IOCC/build-v2018.2/fpga/
vivado% hsi -mode tcl -source build_zynqmp_pmufw.hsi
```

## 参考

 * [「Vivado SDK でZynq FSBL(First Stage Boot Loader)をビルドするTclスクリプト(hsi編)」@Qiita](https://qiita.com/ikwzm/items/e09fab6b17986471cbda)