OmniAICreator/Qiita-1.07M huggingface dataset:
UnityPackageExporterを作るときに気をつけること [ExportPackage][ExportPackageOptions]

# はじめに
UnityPackageを出力するEditor拡張を作成しました
https://github.com/gatosyocora/gsPackageExporter

公式リファレンス以外にUnityPackageを操作するスクリプトを紹介した記事があまりなかったので, 
製作途中で詰まったところなどをまとめました

# 開発環境
Unity 2017.4.15f1
Visual Studio 2017
Windows 10 Home

# UnityPackageを出力するAPIが公式で提供されている
[AssetDatabase.ExportPackage](https://docs.unity3d.com/ja/current/ScriptReference/AssetDatabase.ExportPackage.html)

```cs
public static void ExportPackage (string assetPathName, string fileName);
public static void ExportPackage (string assetPathName, string fileName, ExportPackageOptions flags);
public static void ExportPackage (string[] assetPathNames, string fileName, ExportPackageOptions flags= ExportPackageOptions.Default);
```

* **string assetPathName**：出力するアセットのパス(複数可, Assetsフォルダからの相対パス)<br>
　　e.g. Assets/Hoge/piyo.mat, Assets/Foo
* **string fileName**：出力するUnityPackageのファイル名（ドライブからの絶対パス）<br>
　　e.g. C:/Users/ユーザー名/Desktop/sample.unitypackage
* **ExportPackageOptions flags**：その他オプション設定

# Exportするときのassetの扱い等を第三引数で設定できる
[ExportPackageOptions](https://docs.unity3d.com/ja/current/ScriptReference/ExportPackageOptions.html)
OR演算子( | )を使うことで複数のオプションを同時に設定できる
画像は出力したUnityPackageを他のプロジェクトにインポートしようとしたときに表示されるものの例

#### Default
assetPathNameで指定されたassetのみを出力する
assetPathNameがフォルダだけの場合, 空フォルダがExportできないため何も含まないUnityPackageが出力される


#### Interactive
非同期的に実行する
書き出し中のプログレスバーが表示されて, 書き出しが完了すると出力されたファイルが表示される


#### Recurse
assetPathNameがフォルダのパスの場合, それ以下に含まれるすべてのアセットを出力する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/b24a9291-ea20-69e5-ca30-149778418c4e.png "VRCAvatarEditorフォルダを出力した例")


#### IncludeDependencies
assetPathNameのアセットで使われているアセットも出力する
fbxを出力しようとした場合, 使われているMaterialやそのシェーダー, テクスチャなども出力される
prefabを出力しようとした場合, 使われている3Dモデルのfbxやスクリプト, アニメーションファイルなどの出力される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/3fd9ec88-d63c-3c14-9a0f-f46051927054.png "shapell.prefabを出力した例")


#### IncludeLibraryAssets
assetPathNameで指定されたアセットとLibraryフォルダ以下のアセットが出力される
また, UnityEditorに本来から含まれるdllファイルやプロジェクトの設定ファイルも含まれる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/5ca2c8cd-3d01-800e-6a23-84d31c4fb2e5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203750/f040f271-6a88-6bc0-0192-4fa84765918b.png)

# 注意点
* 空フォルダは出力されない
* 出力するアセットが多いと書き出し終了までそこそこかかる(処理状況を見るためにInteractive推奨)
* fileNameに存在するファイル名を指定すると上書きされてしまう（これで既存のフォルダを指定してしまいフォルダが消滅しました...）

# まとめ
個人的にはInteractiveとRecurseと場合によってIncludeDependenciesを使ってIncludeLibraryAssetsは非推奨です
でもしっかり作りこみたい場合は出力したいアセットのパスをすべて取得してInteractiveを使うのが良さそうです
(自作したExporterでは書き出し前に出力するアセット一覧を表示したかったのですべてパスを取得してInteractiveを使ってます)
select2でajaxを使った場合に値をプログラム的に設定する

### はじめに
select2で、あらかじめ決まった値をセットしておきたいときってあるよね？
ajaxを使った場合、ドキュメントに書かれているやり方ではうまくいかなかったので、対応した時のメモです。

### 環境
- Windows10
- select2 4.0.6-rc.1

### 方法
例えば {id=4, text='aaa'}  のデータをタグに設定しておきたいとする。
ajaxを使わない場合だと、以下でうまくいくが、ajaxを使っている場合、悲しいことに何も起こらない。

```javascript
$(".js-example-basic-multiple").val('aaa').trigger("change");
```

この場合、以下のようにすればよい。

```javascript
$(".js-example-basic-multiple").select2("trigger", "select", {data: { id: "4" , text: "aaa"}});
```

複数値をセットしたい場合は、以下のように複数回呼び出せばよい。

```javascript
$(".js-example-basic-multiple").select2("trigger", "select", {data: { id: "4" , text: "aaa"}});
$(".js-example-basic-multiple").select2("trigger", "select", {data: { id: "5" , text: "aaaaaaa"}});
```

idやtextはサーバから取得されるものと整合性がとれていないと、当然ながら、おかしくなるだろう。

### 参考
Programmatically set the value of a Select2 ajax
https://stackoverflow.com/questions/25395427/programmatically-set-the-value-of-a-select2-ajax
AWS cloud9使うぞ。

AWSについて、メモ。

# AWSってなんぞや？
- Amazonが提供する、クラウドコンピューティングサービス
- AmazonもAWSで稼働してるんや。
- ソニー銀行もMFUJも使ってるんや。NASAもやで。

## クラウドのメリットって？
- 必要なときに、必要な文だけ、低価格で利用できる。
- 何百、何千ものサーバーを数分で起動でき、迅速に結果を出すことが出来る（すごいね）
    - クラウド以前は、何ヶ月も前からサーバーやITインフラを計画して、調達しなきゃいけなかったみたい。

# AWS Cloud9って？
- サーバーサイドのプログラムを実行できるWebブラウザ
- 利用無料
    - だけど、Cloud9を動かすサーバー(EC2)は有料やで。（１年は無料みたい）

# IAMって？
- AWSは、AWSリソースへのアクセスを安全に制御するためのウェブサービス
- 許可されたユーザーだけサービスを使えるようにする的な

##　ルートユーザーとIAMユーザー
- ルートユーザー: なんでもできるやつ。
- IAMユーザー: IAMを使って認証されたユーザー
NuxtとLaravelAPIでQRコード画像を生成してダウンロードする話

# 概要
Nuxt側でQRコード生成ボタンを押下したあとにLaravel側でQRコード画像を生成し
ダウンロードさせる機能を実現したい

QRコードの内容はURLなどではなく
指定のIDに紐づく商品データをJson形式で埋め込んでおきたいため
QRコード生成には引数で商品Iｄを渡す必要がある

メモとして書いてるので違ったりこうしたほうが良いなどあればご指摘いただけたらと思います。

# 前提
Laravel 5.8
Nuxt 2.4

# 使ったモジュール
[simple-qrcode](https://github.com/SimpleSoftwareIO/simple-qrcode/tree/develop/docs/ja)

# モジュールをインストール

`composer.json`に下記を追加

```composer.json
"require": {
  "simplesoftwareio/simple-qrcode": "~2.0"
}
```

コマンドを実行

```
composer update
```
※Laravel5.4以下の場合はconfig/app.phpへサービスプロバイダとエイリアスを登録が必要となるため
公式サイトを見て登録してください



# Laravel側の実装

指定のIdに紐づくデータをQRコード化したいため動的のURLで定義する

```api.php
Route::get('/product/qr-code/{id}', 'QrcodeController@download');
```

ダウンロード用のコントローラの作成

```bash
php artisan make:controller QrcodeController
```

単純に埋め込みたい商品データをSimpleQrcodeの`generate`渡してあげるだけでできた

```QrcodeController.php

class QrcodeController extends Controller
{
    /**
     * QRコードダウンロード
     * @param Request $request
     * @return \Illuminate\Http\Response
     */
    public function download(Request $request)
    {
        $product = Product::find($request->route('id'));
        $headers = [
            'Content-Type' => 'application/octet-stream',
            'Content-Disposition' => 'attachment; filename="' .$product->product_name. '.png"',
        ];
        $qrcodeImage = QrCode::format('png')->size(300)->generate($product);
        return response($qrcodeImage, 200, $headers);
    }
}

```

# Nuxt側の実装

今回はQRコードをダウンロードするには、認証済みのユーザでなければならないので
単純にaタグに動的URLを埋め込むだけではできなかった
そのため、downloadメソッドを下記のように実装した

```js
    async download(prodductItem) {
      await this.$axios
        .get(`/api/shop/product/qr-code/${prodductItem.id}`, {
          responseType: 'blob'
        })
        .then(response => {
          const blob = new Blob([response.data], {
            type: 'application/octet-stream'
          })

          const url = (window.URL || window.webkitURL).createObjectURL(blob)
          const a = document.createElement('a')
          a.href = url
          a.download = prodductItem.product_name + '.png'
          // aタグ要素を画面に一時的に追加する
          document.body.appendChild(a)
          a.click()
          // 不要になったら削除.
          document.body.removeChild(a)
        })
    }
```

# まとめ
便利なモジュールが用意されておりさほど苦労せずに実装できたため
Laravelは本当に色々と自前で実装せずに済むので開発が楽でした。

もっとこんな方法が良いとかこの実装はあまりよくないなどあれば
教えてもらえると幸いです！
react-reduxのテストの優先度

#ユニットテストを書く優先度
コンポーネントのユニットテストを書く必要が発生し、react-reduxにおいてユニットテストを書く際の優先度はどのような感じなのかを調べたり、人に聞いたりしてまとめてみたものです。間違えている場合があればご指摘して頂ければありがたいです。

>Reducerが薄くて、Reducerに値を渡す前のmiddlewareが分厚くなっている前提での優先度
Reducerは純粋関数って思想で設計されているので、薄い方がいいと思っています。
分厚いReducerはあまり見たことがないです。
[The reducer is a pure function that takes the previous state and an action, and returns the next state.](https://redux.js.org/basics/reducers)

#Reducer
純粋関数で、ある入力に対して常に同じ出力をするのでテストする意味合いが薄い。 **優先度 低**
>Reducer、もしもswitch-case文とreturn { …state, action.payload }だけって感じで薄く作れている場合
もしもreducerにビジネスロジック書かかれているならテストを行う必要あり。

#Component(難しい)
- presentational component
    - props によってrender の内容が変化する場合、各props を渡したときに想定通りrender されるかどうかテストしたい。 書き足し書き足しでぶっ壊れる可能性が高い。 **優先度 高**

    - props に依存せず常に同じ見た目を返すだけの場合、スナップショットだけで良さそう **優先度 低**

>書き足し書き足しでぶっ壊れる可能性が高いとはコンポーネントがぶっ壊れるって意味

例えばButtonってコンポーネントがあったとして

```jsx
const Button = ({ color, size, text }) => (
  <button style={ `color=${color} size=${size}`}>{text}</button>
)
```
これぐらいシンプルだったのが、色んな種類のボタンを作りたいからといって

```jsx
const Button = ({ color, size, text, isDarkMode, hidden, hasAnimation, childComponents, ...props }) => 
```
受け取るpropsが増えて{ props && (…)}みたいな記述が増えると、コンポーネントが取りうる見た目/条件分岐が増えすぎてデグレってしまう、その様な場合はsnapshotのテストでも書いておけば、コンポーネントがぶっ壊れたことに気づく事ができる。
スナップショットのテストは、見た目の描画を含むコンポーネントだったらお守りみたいな感じで大体書いておく事が多い!

- container component / でっかいclass component　**優先度高**
    - クラスに生えている各メソッドが想定通りに動くがどうかテストしておきたい。
    - props / state によって見た目が変化する場合はpresentational と同様に全ケーステストしておきたい。
    (テスト書きづらかったら、テストを書きやすくなる大きさまで分割 / リファクタしても良さそう)

#Middleware
- Reducer に渡す値を整形 / API のコールを行うなど、ビジネスロジックが集中しているのでしっかりテストを書きたい。**優先度 高**

#ActionCreator
テストしなくて良い
Objectを生成するだけなので意味が薄い為　**優先度　低**
Bash while による無限ループをマジックナンバー無しで

AtCoder の Some Sums を解いてみているのですが、その中で新しく知ったことをメモ。
個人的に競技プログラミングに深入りするつもりはありませんが、いろいろ調べるようになって新しいことを知れるので、その面は楽しんでいます。

# 無限ループにするには
## 今までこう書くことが多かった

C なんかでも `whlie (true)` ってすることは多いかと思いますが、そのノリです。

```bash
while [ 1 ]; do
  hogehoge
  if [ <condition is truthy> ]; then
    break
  fi
done
```

## ヌルコマンドの活用

`1` というマジックナンバーが不要になるので、こちらの方がいいかも。

```bash
while :; do
  hogehoge
  if [ <condition> ]; then
    break
  fi
done
```
CocosCreatorの実行環境、どうやらブラウザでもなく、Nodejではないようです。(Prue JS)

皆さんご存知かと思いますが、CocosCreatorではDOM APIを呼び出せません。これは、

https://stackoverflow.com/questions/33725402/why-web-audio-api-isnt-supported-in-nodejs

*Node.js doesn't support Web Audio because it isn't part of the JavaScript language itself - it's a separate web platform JavaScript API.*

なので気になって、どんなV8(v8エンジンのみの可能性が高い)が使われていないかを調べてみました。現状JSB(JavaScript Bindings)が多用されているため、幸いオープンソースなので、解析が必要です…

参考リンク:
https://stackoverflow.com/questions/33725402/why-web-audio-api-isnt-supported-in-nodejs
https://developer.mozilla.org/en-US/docs/Web/API

本家のWebAudioAPI にACCをデコード(decoder)する機能が内蔵されており、意識しなくても再生できますが、しかし、本家のWebAudioAPIが使えない場合、どうしもWebAudioAPIのAPIに沿ったものにしないといけません。今回利用したのは
https://github.com/mohayonao/web-audio-engine
と
https://github.com/audiocogs/aac.js

で、web-audio-engineは全てjsで実装された音声をデコードするもので、aac.jsは、web-audio-engineで利用するデコーダーになります。

効率なく考えるには、jsのライブラリaacがスピードが出ない可能性もありますが、こちらは実際に試して、もしだめでした。ここは、デコード処理の部分のみをJSB側に移動します。
Railsで認証情報を管理する（Rails 5.2 & 6.0）

Ruby on Rails での認証情報の管理について、調べた事のまとめ。

Rails5.2では認証情報を以下のように管理してる：

- `config/credentials.yml.enc` : 暗号化した認証情報
- `config/master.key` : 復号キー
- `Rails.application.credentials` : アプリケーションから復号化した認証情報を参照

ただし、これは複数の環境を想定した作りになってない。例えば1つのサービスに対して `production / staging` の2環境で別々の認証情報を使いたい場合を想定していない。

これがRails6.0では以下のようになりそう：

- `config/credentials/production.yml.enc` : production用の暗号化した認証情報
- `config/credentials/production.key` : production用の複合キー
- `config/credentials/staging.yml.enc` : staging用の暗号化した認証情報
- `config/credentials/staging.key` : staging用の複合キー
- `Rails.application.credentials` : アプリケーションから復号化した認証情報を参照（参照方法は環境問わず同じ）

環境ごとに暗号化したファイルと複合キーのペアを置ける構成になっており、複数環境が想定された作りになるみたい。

Rails5.2でも複数環境へ対応するハックがあるようだが、6.0での複数環境対応の方が個人的に好み。

# 参照
https://github.com/rails/rails/pull/30067
https://github.com/rails/rails/pull/33521
HexoをGitHub Pagesデプロイ時、独自ドメインがデフォルトに変わってしまう

# GitHub Pagesに独自ドメインを設定

GitHub Pagesに独自ドメインを設定する手順は、ほかのサイトで紹介されているのでここでは述べない。
以下のサイトをご参考まで。

* [GitHub Pages + 独自ドメイン + HTTPS (SSL) のサポートをGitHubが提供開始](https://qiita.com/foobaron/items/cd9cfc403defa706372b)
* [Setting up an apex domain (GitHub公式)](https://help.github.com/en/articles/setting-up-an-apex-domain)

独自ドメイン設定後に、Hexoを使用してblogを開設したが、
デプロイするたびにGitHubの独自ドメイン設定が消えて、デフォルトドメインに変わってしまう現象があった。

## 独自ドメイン設定が消えないために

独自ドメインを設定した後、GitHubリポジトリにCNAMEというファイルが作らる。
CNAMEファイルの中に独自ドメインが保管されているのを確認した。

CNAMEファイルはローカルにあるHexoのpublicフォルダになく、だからデプロイ時に消えてしまうのが原因だとわかった。

そのため以下の対策をした。

* GitHubリポジトリのCNAMEファイルをダウンロード
* CNAMEファイルをローカルのpublicフォルダに配置

上記で問題解決できた。
プログラミング用フォントRicty DiminishedをWindowsにインストールする

# プログラミング用フォントRicty DiminishedをWindowsにインストールする
新しいWindowsマシンにプログラミング用フォントRicty Diminishedをインストールしてみました。

検索すれば、丁寧な解説記事が数多く見つかりますが、意外とコマンドラインのみで完結する方法が紹介されていないようでしたので、こちらに書こうと思います。

以前、Mac用の記事も書きましたので、Macをお使いの方はご参照ください。
[プログラミング用フォントRictyをMacにインストールする](https://qiita.com/segur/items/50ae2697212a7bdb7c7f)


# Ricty Diminishedとは
Ricty Diminishedは、プログラミングに特化したフォントです。姉妹フォントにRictyがあります。

- l, I, 1, | みたいな見分けづらい文字の区別がつきやすくなります。
- 等幅フォントです。全角文字の幅が半角文字の2倍にきちんとなります。
- 全角スペースが可視化されます。

Ricty Diminishedの公式サイトはこちらです。
[プログラミング用フォント Ricty Diminished](https://www.rs.tus.ac.jp/yyusa/ricty_diminished.html)


# Chocolateyをインストールする
ChocolateyはWindows用のパッケージマネージャーです。MacでいうHomebrew、Linuxでいうapt-getやyumに相当するツールです。

もし、インストールされていなければ、こちらを参考にしてインストールしてみてください。便利です！
[Chocolateyを使った環境構築の時のメモ](https://qiita.com/konta220/items/95b40b4647a737cb51aa)

# Ricty DiminishedをWindowsにインストールする
管理者権限でコマンドプロンプトを起動して、以下のコマンドを実行するだけです。

```bash
choco install fonts-ricty-diminished
```
こちらを参考にしました。
[Chocolatey / Ricty Diminished](https://chocolatey.org/packages/fonts-ricty-diminished)

これでインストール完了です。コマンドプロンプトを再起動すれば、フォントでRictyが指定できるようになっているはずです。

もし、エラーが発生したら、PowerShellスクリプトの実行が無効になっているからかもしれません。

管理者権限でPowerShellを起動して、以下のコマンドを実行します。

```powershell
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
```

これで、PowerShellスクリプトをコマンドプロンプトから実行できるようになりました。

# Myricaをインストールする

Rictyから派生したフォントとして Myrica というものもあります。
こちらもChocolateyでインストールできました。

```bash
choco install myrica
```

# おわりに
Chocolatey便利すぎです。
pi Music Boxをupdateする（その２）

# pipのinstall
mopidyの設定にはpython-pipが必要
`# apt install python-pip`

# web client
mopidyをweb browserで利用できるように

`# pip install Mopidy-MusicBox-Webclient`

# /etc/mopidy/mopidy.confを編集
`[http]`
`hostname = 0.0.0.0`

`[local]`
`media_dir = /media`

`[musicbox_webclient]`
`enabled = true`

を追加する。
設定はrootで
`# mopidyctl config`
として確認できる。

# mopidyの起動と自動起動の設定

`# service mopidy start`
で起動。

`# systemctl enable mopidy`
で自動起動。

# mopidyの起動確認
この状態で
http://raspiのip:6680/musicbox_webclient/
でmopidyにアクセスできる。

# mopidy local scan
しかしこのままではBROWSEしてもfileもlocalsも空。
`# mopidyctl local scan`
でUSBメモリの音楽ファイルを登録する。
`service mopidy restart`
でmopidyを再起動するとUSBメモリの音楽を聴くことができる。

# audio出力
defaultではautoになっていて、HDMI接続していると、TVから音が出る。
analog出力にするには
`# amixer cset numid=3 1`

# radioサービス
`# pip install Mopidy-TuneIn`
/etc/mopidy/mopidy.confに

`[tunein]`
`enabled = true`
`timeout = 5000`
を追加する。
Geth コンソール基礎知識


`gethの起動コマンド`

```
geth --networkid "10" --nodiscover --datadir ~/geth/private_net/ --rpc --rpcaddr "localhost" --rpcport "8545" --rpccorsdomain "*" --rpcapi "eth,net,web3,personal" --targetgaslimit "20000000" console 2>> ~/geth/private_net/error.log
```

`アカウント作成`

```
personal.newAccount("password")
```

`コインベースアカウントの確認`

```
eth.counbase
```

`コインベースアカウントの変更`

```
miner.setEtherbase(eth.accounts[?])
```

`genesisブロックの確認`

```
eth.getBlock(0)
```

`マイニングの開始、確認、停止`

```
miner.start(1)
eth.mining
miner.stop()
```

`コインベースの残高確認`

```
eth.getBalance(eth.accounts[0])
web3.fromWei(eth.getBalance(eth.accounts[0], "either")
```
## 送金

(eth.accountがロックされてるので送金不可)

```
eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(5, "ether")})
```

`PASSWORDアンロック`

```
personal.unlockAccount(eth.accounts[0])
```

`送金が成功したトランザクション`

```
eth.getTransaction("address")
```

トランザクション内のblockNumberに残高が存在する

```
web3.fromWei(eth.getBalance(eth.accounts[1], 58), "ether")
```

`レシート`

```
eth.getTransactionReceipt("address")
```
PHP 7.2から7.3へのアップデートでハマった話（WordPress）

#PHP 7.3がやってきます

筆者はさくらインターネットで WordPress サイトを複数動かしているんですが、2019年8月に PHP 7.2 のサポートが終了するのに合わせて、PHP 7.3 へのバージョンアップの[アナウンスがされています](https://help.sakura.ad.jp/hc/ja/articles/360000288102--PHP%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%83%E3%83%97%E3%81%AB%E4%BC%B4%E3%81%86%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D%E3%81%AE%E3%81%8A%E9%A1%98%E3%81%84-%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%92%E3%81%8A%E5%8F%97%E3%81%91%E5%8F%96%E3%82%8A%E3%81%AE%E3%81%8A%E5%AE%A2%E6%A7%98%E3%81%B8)。放っといても7月には自動で7.3に変更されるそうです。

## PHP 7.3 にあげてみたら BAD GATEWAY

そこでコンパネから 7.3 にあげてみたら、サイトの反応がありません。読み込み試行が十数秒続き画面には「Bad Gateway」と表示されます。

WordPress 5.2 から導入された[リカバリモード](https://capitalp.jp/2019/04/17/wordpress-5-2-will-be-shipped-with-recovery-mode/)も全然動きません。もっと深い部分です。

## まずローカルXAMPPで試してみる → 動く

7.3 が原因なのは間違いないので、ローカルのXAMPP環境（PHP 7.3）を用意してまるごとサイトをインポートしてみましたが正常に動作。

## さくらインターネットの別アカウントにゼロから設定 → 動かない

別アカウントのサーバにまっさらからやってみましたが、[All in one Migration](https://www.vektor-inc.co.jp/post/all-in-one-wp-migration/) で取り込むと同じ問題が再発。

## 原因は自作プラグインの case 文

結局プラグインを一個ずつオンにしていくと自作プラグインが残りましたw。コードをゾーンでコメントアウトすると case 文が原因として残りました。

```PHP
  for ($i=0;$i<=1;$i++) {
    ...
    switch ($i) {
      case -1: $date_text = '【昨日】'; break;
      case  0: $date_text = '【今日】'; break;
      case  1: $date_text = '【明日】'; break;
      default: $date_text = ''; 
    }
```
この、``case -1``、``case 0``、``case 1``のうち``case 1``を外すと動作することを発見（4時間かっかった）。 

```PHP
    switch ($i) {
      case "-1": $date_text = '【昨日】'; break;
      case  "0": $date_text = '【今日】'; break;
      case  "1": $date_text = '【明日】'; break;
      default: $date_text = ''; 
    }
```

こうすればうごきました。きっと型の変換で整合性が取れなくなってるに違いないのですが、普通に動く環境もあるのが謎なのです。
PHP のオプションとか？

もし同じ問題を抱えてる方がいらっしゃってこの内容が役に立ったら幸いです。
各種ツールのアップデートをするオススメのタイミング

## 各種ツールのアップデートをするオススメのタイミング
注: あくまで個人的にこうしているだけですのであしからず。

プログラミングをしていると開発ツールを複数使うことになると思います。ツールには時折アップデートの通知が来ますよね。

僕は基本的にすぐアップデートはしません。これは、アップデートをとある手段として用意しておくためです。

その手段とは、ツールにバグが発生したり、想定通りに動作しなくなった時のレスキュー手段です。
アップデートをするといくつかの状態が初期化されますので、気づかず変更されていた設定などが元に戻りバグが治ることが多いのです。

この記事が参考になれば幸いです。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
PieでEditTextがある画面表示時にキーボードを表示メモ

## 問題

画面表示時にEditTextにフォーカスを当ててキーボードを表示する要件があり、Android Pieでキーボードが表示されない問題があったため、メモとして残しておく

Pie未満では、コード側で処理の必要なく、フォーカスがあたりキーボードが表示されることは確認できましたが、PieからOS側の仕様が変わったらしく、暗黙的に表示されないようになりました。

キーボードを表示するため、下記は設定済み

```xml:AndroidManifest.xml（一部抜粋）
<activity
    android:name=".MainActivity"
    android:windowSoftInputMode="stateAlwaysVisible" >
</activity>
```

## 解決

EditText#requestFocusを明示的に呼ぶことで解決しました。
Pie未満では、この処理がなくとも表示されます。

```kotlin:MainActivity.kt（一部抜粋）
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    override fun onResume() {
        super.onResume()
        edit_text.requestFocus()
    }

}
```

## 参考文献

https://blog.k3n.link/entry/android-pie-view-focus
jQueryでモーダルの作成

#jQueryでモーダルを作る
モーダルを作成するには、jQueryを読み込んだ後、

・jQueryオブジェクトの作成
・メソッドの呼び出し
この要素を作ることが重要になります。

↓↓↓↓↓↓↓ あなたの記事の内容
```javascript
───────
```javascript

↑↑↑↑↑↑↑ 編集リクエストの内容
$('セレクタ').メソッド();
```
このようにcodeします。
何をどうするかをきちんと把握すると後の作業で悩むことがなくなります。

```javascript
 $('.btn-question').click(function(){
        $('.modal').fadeIn();
    });
```

具体例はこのようになります。

そこでセレクタにはログインボタンなど、クリックしたときモーダルが出てくるクラスやidを入れて、メソッドにはクリックメソッドをcodeし、そのクラスの要素をクリックすればモーダルが出現するようにします。

次にしなければいけないのは、出現したモーダルを×ボタンで消えるようにしなければいけません。


```javascript

   $('.btn-close').click(function(){
        $('.modal').fadeOut();
      });
```
()内は自分の指定したクラスを入れてください。
これで完成で、クリックしたときにモーダルが出現するようになり、×ボタンをクリックすればモーダルが消えるようにできます。
最後に一つ注意なのがjQueryを記述するときは


```javascript

$(function(){

});
```
とcodeする必要があります。
HTMLの読み込みの後、jQueryのファイルが読み込まれるようにしないといけないからです。
以上になります。
間違いや指摘があればお願いします。
[メモ][Ansible] フィルタでIPからDNS逆引き用アドレスを生成


```yml
- name: Test Playbook  
  hosts: localhost
  tasks:
  - name: Set
    set_fact:
     test_num: 3
     test_network: "10.8.30.1"

  - debug:
     msg: "{{ test_network.split('.')[:-test_num:-1] | join('.') }}"
```

- 実行結果

```
TASK [debug] ********************************************************************************************
ok: [localhost] => {
    "msg": "1.30"
}
```
Universal Linkで起動した時の処理の順序

# はじめに
iosでは、universal linkを使うと、別アプリやwebページからアプリを起動することができます。universal linkを使ってアプリが起動された時のAppDelegateのメソッドの呼ばれる順番を調べたので書いておきます。universal linkも含めたアプリライフサイクルは、[iOSアプリのライフサイクル](https://qiita.com/KenNagami/items/766d5f95940c76a8c3cd)にまとめて記録していきます。

# 呼ばれるメソッド
アプリ未起動時もアプリ起動時も`application(_:continue:restorationHandler:)`が呼ばれるので、基本的に、universal link起動時の処理は、このメソッドに書いておけば大丈夫そう。

## アプリ未起動時 (Not Running)
アプリが起動されていない状態(Not Running)の時に、universal linkでアプリが起動した時のAppDelegateのメソッドの呼ばれる順番です。

- func application(_:willFinishLaunchingWithOptions)
- func application(_:didFinishLaunchingWithOptions:)
- func application(_:continue:restorationHandler:)
- func applicationDidBecomeActive(UIApplication)

## アプリバックグランド時(Background)
アプリがバックグランドの状態(Background)の時に、universal linkでアプリが起動した時のAppDelegateのメソッドの呼ばれる順番です。

- func applicationWillEnterForeground(UIApplication)
- func application(_:continue:restorationHandler:)
- func applicationDidBecomeActive(UIApplication)

## アプリライフサイクル
以下の図は、universal linkでの起動も図に入れたアプリライフサイクルです。

<img width="700" alt="20190616-ios-lifecycle.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404406/27384727-0c6d-3c0d-0d73-3c55bde80863.png">



# 参考文献
- [Appleリファレンス application(_:continue:restorationHandler:)](
https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623072-application)
データ分析未経験SEがデータサイエンティストを目指す No.2 [Numpy(数値計算と統計量)]

#記事の概要

第2回は数値計算ライブラリであるNumpyについてまとめます。

#Numpy

Numpyは数値計算ライブラリであり、リストや行列の計算を簡単に実現できる。
また、そのリストや行列の内容から統計量を簡単に取得できる。

###Numpy arrayの生成

リストからNumpy arrayを生成するには、arrayメソッドを使用する。
CSVファイルからNumpy arrayを生成するには、genfromtxtメソッドを使用し、delimiterを指定する。
Pythonのrangeメソッドと同じように数列を生成するには、arangeメソッドを使用する。

```python
my_array = np.array([1, 2, 3, 4, 5, 6])
csv_array = np.genfromtxt('sample.csv', delimiter=',')
range_array = np.arange(2, 12, 2)
```

生成したNumpy arrayの要素の選択やスライスは、通常のリストと同じように行える。

その他、全ての要素を指定値としたNumpy arrayを生成するfullメソッドなどがある。

###Numpy arrayのLogical Operations

Numpy arrayのbracket内に条件式を入れると、その条件を満たした要素のみの新しいNumpy arrayを生成する。

```python:In
a = np.array([10, 2, 2, 4, 5, 3, 9, 8, 9, 7])
print(a[a > 5])
```

```Out
[10 9 8 9 7]
```

実際の処理としては、「a > 5」がBoolean型のNumpy arrayを生成し、それがbracketに入ることで、Trueの要素だけを抽出している。

###ブロードキャスト

Numpyにはブロードキャストと呼ばれる特徴があり、形状の異なるリスト・行列同士の計算が行われた場合は、サイズの小さい方を大きい方に合わせて計算する。
定数と行列の計算や、3x1ベクトルと3x4行列の計算など、何も考えずに演算子で結合するだけで実行できる。

###統計量

Numpyでは以下のようにリストの要素に対する統計量を取得するメソッドが数多く存在する。

- mean : 平均値
- median : 中央値
- percentile : パーセンタイル(第2引数でパーセンテージを指定)
- std : 標準偏差
- var : 分散
- count : データの個数

###特定条件を満たす要素の比率（meanメソッドの応用）

以下のようなコードにより、「ある条件を満たす要素数の全体に対する比率」を一発で取得できる。

```python:In
a = np.array([10, 2, 2, 4, 5, 3, 9, 8, 9, 7])
print(np.mean(a > 8)) #3/10
```

```Out
0.3
```

###2次元行列に対する統計量の計算

2次元行列に対して上記統計量取得メソッドを使用する際は、メソッドのaxisパラメータを指定することで、行方向または列方向への集約が可能。
axis=1の場合は行方向に、axis=0の場合は列方向に集約し、それぞれリストを出力する。指定しない場合は全体を集約して1つの値で出力する。

```python:In
ring_toss = np.array([[1, 0, 0], 
                      [0, 0, 1], 
                      [1, 0, 1]])
print(np.mean(ring_toss))          #全体を集約
print(np.mean(ring_toss, axis=1))  #行方向に集約
print(np.mean(ring_toss, axis=0))  #列方向に集約
```

```Out
0.44444444444444442
[ 0.33333333  0.33333333  0.66666667]
[ 0.66666667  0.          0.66666667]
```

###numpy.randomによる分布標本の生成
Numpyには、指定した分布に基づいたランダムな標本を自動で生成するメソッドがある。

- numpy.random.normal(平均, 標準偏差, size=サイズ) : 正規分布
- numpy.random.binomial(試行回数, 成功確率, size=サイズ) : 二項分布

randomを使用する際は、numpy.random.seed(シード値)でシード値を指定することで、乱数を固定にできる。

###argmaxによる最大値をもつ要素のインデックス取得

特にKaggleの分類問題においてよく使われるメソッドに、最大値をもつ要素のインデックスを取得するargmaxがある。

```python
results = np.argmax(predictions,axis = 1)
```

---

次回はScipyになる予定です。
bashでデバック用に変数表示を簡単に実装する（何もしないコマンド":"を使う）。

## 目的
- bashで複数のファイルをRなどにパラメータと共に渡すときに、デバックモードになると変数の値を表示させたいなーと常々思っていました。

- その方法を思いついたので備忘録として残したいと思います。何かのお役に立てれば嬉しいです

## 方針
- 方針はシンプルにシンプルに。なので`getopts`なんかは使わ（え）ないです。
- `bash`で`:`は何もしない性質を利用します（今日これを見つけました。先般諸氏ありがとうございます）
- `test`コマンド`[]`の論理連結で`[] && []`などを多用します。
- ユーザ関数を定義しておきます（`abort()`)。次のように記述します。

```{bash}
function abort {
   echo "$@" 1>&2
   exit 1
}
```

これでファイルがないと止められます。

```{bash}
 [ -f $filename ] || abort "$filenameがないので終了します"
```

メカニズムですが、ファイルがないと`[]`の中が`FALSE`と判定されて`||`で次のコマンドに進み、`abort()`関数が呼ばれ、メッセージを出して止まります。エラーコードは`1`です。

## 引数でデバックモードの切り替え
引数で`mode`が設定されれば、表示して何もしないようにするには下記のようにしました。

```{bash}
mode=${1}; # 引数をmodeに設定します。
debug=":"; # これがポイント。$modeが設定されていない場合に用いられます
[ ! -z $mode ] && dryrun="echo dryrun>"

hoge=$(何かの処理); 
$dryrun "hoge=${hoge}"; 
```

`mode`が設定されないと`:`で何もしません。設定されると`echo dryrun>`が呼ばれて、後ろの文字列も表示されます。`dryrun>`は任意でどうぞお使いくだしあ。実際の例を見てみましょう。

### 実際の例

`mode`に`dryrun`と`debug`の２つの機能を持たせたコードの例です。

```{tmp.bash}
#!/usr/local/bin/bash 

abort(){ echo "$@" 1>&2 ; exit; }

# 引数の解析
inputfile=${1}; 
[ -z ${inputfile} ] && abort "inputfileが設定されていません"
[ -f ${inputfile} ] || abort "${inputfile}がありません"
shift; [ $# -gt 0 ] && mode=${1}

debug=":"
[ ! -z $mode ] && [ $mode = "dryrun" ] && dryrun="echo dryrun>"
[ ! -z $mode ] && [ $mode = "debug" ]  && debug="echo debug>"

_dir=$( dirname ${inputfile} );
$debug "_dir=${_dir}";

backup="${inputfile}.bak"; 
[ ! -f $backup ] && $dryrun cp $inputfile $backup;
```
### ちょっと解説
`[ -z ${inputfile} ] && `は変数が設定されていないと次に進みます。
`[ -f ${inputfile} ] || `は変数がファイルでないならは次に進みます。
`shift`は引数をシフトします。そのため、次の引数呼び出しは必ず`$1`でOKです。ただし、引数があるかを`[ $# -gt 0 ]`で調べています。

`debug=":"`が今回組み合わせを思いついた方法です。通常モードは`$debug`以降を何もしません。
`mode`が設定されれば`debug`は`echo`する機能に切り替わります。

ここで`[ ! -z $mode ]`ですが`$mode`が設定されていないと`[  = "test" ]`と解釈され、すなわち空白と`"test"`が比較されます。**そんなことできない**(` -bash: [: =: 単項演算子が予期されます`)と怒られるので、設定を確認するためのものです。その前の`[ $# -gt 0 ]`でチェックしているので設定が担保されているのですが、バグが少ないような書き方として載せました。

`mode`が設定されない通常モードなら、`_dir`は表示しませんがdebugモードなら表示されます。
注意としてこのスクリプトでは`debug`モードの時は`dryrun`になにも設定しないので最終行は実行されてしまいます。つまりバックアップファイルが生成されます。この辺りはご自身の要求で変更してみてください。
`mode`が`dryrun`なら最終行は期待通りコマンド(`cp  $inputfile $backup`)を変数展開し表示するだけで実行はしません。


幾つか実行してみますね。

```{bash}
~$ ll a*
ls: cannot access 'a*': No such file or directory

~$ tmp.bash
inputfileが設定されていません

~$ tmp.bash a
aがありません

~$ touch a
~$ tmp.bash a dryrun
dryrun> cp a a.bak

~$ ll a*
-rw-r--r-- 1 osaka 0  6 16 23:03 a

~$ tmp.bash a debug
debug> _dir=.

~$ ll a*
-rw-r--r-- 1 osaka 0  6 16 23:03 a
-rw-r--r-- 1 osaka 0  6 16 23:03 a.bak

~$ rm a.bak
~$ tmp.bash a
~$ ll a*
-rw-r--r-- 1 osaka 0  6 16 23:03 a
-rw-r--r-- 1 osaka 0  6 16 23:03 a.bak
```

まあ、動いていそうです。

### 参考にさせていただきましたいくつかのリンクを貼っておきます。
先輩の方々のお陰で何か成長している気がします。

- [[Bash] testと\[と\[\[](https://qiita.com/Riliumph/items/f07272fa9b0834032a9d)
- [何もしない組み込みコマンド ":" （コロン）の使い道](https://qiita.com/xtetsuji/items/381dc17241bda548045d)
- [コマンドの連結](https://shellscript.sunone.me/exit_status.html)



何かのお役に立てれば嬉しいです。
pi Music Boxをupdateする（その１）

先日の投稿でRaspberry PiでGoogle Play Musicを聴くことができるpiMusicBoxを紹介したが、
musicbox_v0.7.0RC7.imgは
`Linux version 4.14.89-v7+ (dom@dom-XPS-13-9370) (gcc version 4.9.3) `
でDebian 7(wheezy)が元となっており、最新のDebian 9.0(stretch)の２世代前ということになる。
Raspberry Pi 3B+に最新のstretch-liteをインストールしpiMusicBoxの機能を再現してみることとしたが、
かなり苦労したので記録に留めておく。


# stretchのインストール
ここは従来どおりEtcherで2019-04-08-raspbian-stretch-lite.imgを16GBのmicroSDカードにflashし
Raspberry Pi 3B+で起動するだけ。

# 起動後の設定
user pi, password raspberryでlogin。
sudo raspi-configで
Network Optionsでネットワークの設定を（wifiの場合2.5GHzを選ぶこと）
Boot OptionsでConsole Autologin（ここは好みで）
Localisation OptionsでTimezoneとKeyboardを適切なものに
Interfacing Optionsでsshを有効に
rebootしてifconfigでip addressを確認。
以後はssh pi@192.168.1.134とかしてloginして作業する。

# mopidyのインストール
https://docs.mopidy.com/en/latest/installation/
に従って作業する。

`# wget -q -O - https://apt.mopidy.com/mopidy.gpg | sudo apt-key add -`
`# wget -q -O /etc/apt/sources.list.d/mopidy.list https://apt.mopidy.com/stretch.list`
`# apt update`
`# apt upgrade`
いろいろとupgradeされる

`# apt install mopidy`
いろいろinstallされるが、m4aの再生にはさらに
`# apt install gstreamer1.0-plugins-bad`
が必要。

# usbmountの修正
piMusicBoxではUSBメモリを差し込めば自動で認識されていたが、
stretchになってからうまく動かない。
gitから最新のソースを入手してdebhelperでパッケージを作成し、それをinstallする。

`$ sudo apt install debhelper git`
`$ git clone https://github.com/rbrito/usbmount.git`
`$ cd usbmount`
`$ sudo dpkg-buildpackage -us -uc -b`
`$ cd ..`
`$ sudo apt install ./usbmount_0.0.24_all.deb`

設定を修正する。

`$ sudo vi /etc/usbmount/usbmount.conf`
3点修正する。
`MOUNTPOINTS="/media/usb0 /media/usb1 /media/usb2 /media/usb3"`
`FILESYSTEMS="vfat ext2 ext3 ext4 hfsplus exfat ntfs"`
`MOUNTOPTIONS="ro,noexec,nodev,noatime,nodiratime"`

exFATとNTFSを追加したので対応するパッケージをインストール
`# apt install exfat-fuse ntfs-3g`
さらに
`$ sudo vi /lib/systemd/system/systemd-udevd.service`
で
MountFlags=slave
を
MountFlags=shared
に変更（あるいはコメントアウト）が必要。

再起動すると、USBメモリが自動でマウントされるはず。
AtCoder Beginner Contest 130　解いてみたメモ

# 問題A - Rounding
https://atcoder.jp/contests/abc130/tasks/abc130_a

```
X,Aは 0以上 9以下の整数です。
Xが A未満の時 0、A以上の時 10を出力してください。
```


```python

X, A = map(int, input().split())
if X < A:
  print("0")
else:
  print("10")
```

## B - Bounding


```python
#N回跳ねるボール　1≤X≤10000　Xは領域
N, X = map(int, input().split())
#Lははねた距離
length = list(map(int, input().split()))

#バウントしたかず
count_total = 1
#最初の位置
now = 0
  
for count in range(N):
  #もし領域よりも小さければもう一回跳ねる
  now = now + length[count]
  if now <= X:
    count_total = count_total + 1

print(count_total)
  
```

## C - Rectangle Cutting
https://atcoder.jp/contests/abc130/tasks/abc130_c

```python
#
W, H, x, y = map(int, input().split())

#x,yが図形の半分の位置かどうか
if x == W/2 and y == H/2:
  menseki = W*H/2
  print(menseki,1)
else:
  menseki = W*H/2
  print(menseki,0)
```

## D - Enough Array
https://atcoder.jp/contests/abc130/tasks/abc130_d


```python
#Nのながさと整数 K
N, K = map(int, input().split())
#列
length = list(map(int, input().split()))

#合計
sum = 0
#変わる値
change_number=0
#なんかいやりたいか　N(N+1)/2が最大
count =0
largest_count = int(N*(N+1)/2)

count_ans = 0

#すべての部分列のパターンを出す
while count < largest_count:
  for number1 in range(change_number,N):
    sum = sum + length[number1]
    if sum >= K:
      count_ans = count_ans + 1
      
    count = count + 1
  sum = 0
  change_number = change_number + 1

print(count_ans)
```

計算量で引っかかって最後まで解けなかった・・・くやしい
多分計算量のことをきにしなければ合ってた気がするな。。。
Java ラムダ式

#ラムダ式の使いかた
- 基本的な書き方
 - `interface object = (arg1, arg2, ...) -> {return 処理}`
 - 引数の型は記述しなくてよい
- ラムダ式の引数が一つの場合
    - `interface object = arg -> 処理`
    - 引数が一つの場合、returnや()、{}を書かなくてもよい
タッチとマウスが混在する環境でハマったこと (unity、Android)

# 前提
- unity 2018.4.2f1
- Android 6, 9
- Bluetoothマウス
- マウスは、複数ボタンあってもポインターは一つなので、単一のポインティングデバイスと見なします。
- タッチは、個々の指が独立してポイント可能なので、指毎に個別のポインティングデバイスと見なします。

# やろうとしたこと
- タッチとマウスの両方で使えてマルチタッチでも支障のない排他制御を実現しようとしました。
- 最初に操作されたポインティングデバイスに制御を占有させ、後から操作されたデバイスを排除しようとしました。 (先優先)

# ハマったこと
- Androidでは、マウス操作中にタッチするとマウスカーソルが消え、タッチ操作中にマウスを動かすだけでマウスカーソルが出現します。
- この切り替わりの際には、unityのポインターコールバックが正しく発火しないようです。
- 例えば、マウスでドラッグ中にタッチされた場合に、既にマウスボタンが押されていないのに`OnDrag`が呼ばれ続ける等の症状が出ました。

# やったこと
- 新たにデバイスが操作された際に、既に他のデバイスが処理中であったら、先行デバイスの処理を強制終了させて、後行デバイスが新たに処理を開始するようにしました。 (後優先)
【ASP.Net Core】@Html.TextAreaForでrowsとcolsが効かなかった状況への対処

# 問題
以下のように`TextAreaFor`を作成した所、css側の設定が優先されてしまい、rowsやcolsが効かない状況になりました。
普通にHTMLとして入力した場合はこの問題は発生しませんでした。

```cs:cshtml
@Html.TextAreaFor(
    model => model.Model.Description,
    6,  // rows
    86, // cols
    new { @class = "form-control"}
)
```

```html:出力されたページ
<textarea class="form-control" cols="86" id="Model_Description" name="Model.Description" rows="6"></textarea>
```

# 対処
`style`に`width: auto !important; height: auto !important;`を指定すればできました。

```cs:cshtml
@Html.TextAreaFor(
    model => model.Model.Description,
    6,  // rows
    86, // cols
    new { @class = "form-control", @style = "width: auto !important; height: auto !important;" }
)
```

```html:出力されたページ（整形済み）
<textarea
  class="form-control" cols="86" id="Model_Description" name="Model.Description"
  rows="6" style="width: auto !important; height: auto !important;"
></textarea>
```

# 感想
一応rowsとcolsを使えるようにしましたが強引なやり方になっているので、この場合無理にrowsとcolsを使ってサイズを設定するよりcssで設定した方がいいんじゃないかと思います。
Spring boot redirect のdefaultはhttpになることを認識しておく

## spring bootでredirectする際は、プロトコルがデフォルトで`http`になる。
使用する場合は、プロトコルを意識して使う必要がある。
環境毎(開発、ステージング、本番)でプロトコルが違う場合は、特に注意。
※本来は環境を合わせるべき。


```java:TestContoroller.java
public class TestController {

    @GetMapping("/show")
    public ModelAndView test() {
        return new ModelAndView("redirect:" + "/sample");
    }
}
```

上記の場合は、
`http://localhost/sample` になる。
これをapplication.ymlから読み込んでセットしたい場合

```java:TestContoroller.java
@RequiredArgsConstructor
@EnableConfigurationProperties({RedirectUrlProperties.class})
public class TestController {
    private final RedirectUrlProperties redirectUrlProperties;

    @GetMapping("/show")
    public ModelAndView test() {
        return new ModelAndView("redirect:" + buildAdminRedirectUrl("/sample"));
    }

    /*
     * springのredirectはdefaultでhttp
     * 環境ごとのredirectURLを作成するメソッド
     */
    public String buildAdminRedirectUrl(String url) {
        return UriComponentsBuilder.fromUriString(redirectUrlProperties.getUrl() + url).toUriString();
    }
}
```

```yml:application.yml
spring:
  redirect:
    url: https://localhost
```

```java:RedirectUrlProperties.java
@Getter
@Setter
@ConfigurationProperties(prefix= "spring.redirect")
public class RedirectUrlProperties {
    private String url;
}
```

ここまで`redirect`について記載したが、内部メソッドを叩きたいだけなら`forward`を使うことも検討する。
ただし、`forward`はURLは変わらないのでその辺も含めて適しているか検証が必要。
(redirectは再度リクエストを投げるが、fowardは内部で処理するためリクエストは最初の１回だけ)

以下を参考にさせていただきました。
https://qiita.com/rubytomato@github/items/8d132dec042f695e50f6
Oracle Entity FrameworkでシノニムからSELECTするとき、「すでに使用されているオブジェクト名です」エラーの暫定対処法

##はじめに

###動作環境
- ASP.NET（VB） MVC
- Oracle.ManagedDataAccess.EntityFramework 12.2.20190115

##発生したエラー

context.シノニム.ToList()したとき、下記エラー発生

```
ORA-00955: すでに使用されているオブジェクト名です。
```

##対処法

スキーマが所有しているテーブルを合わせてDbContext内に宣言したところシノニムからSELECTが実行できるようになった。



##調査内容

ToList()する前にどのようなSQLが実行されているか確認したところ下記のようなものが確認された。

```
select count(*) from all_tables where (owner='[owner名]' and table_name='[シノニム名]')
```

SELECTの結果は0件。


ownerが所有しているテーブルもDbContextで宣言したときどのように変化するか確認したところ下記のようなSQLが実行された。

```
select count(*) from all_tables where (owner='[owner名]' and table_name='[ownerが所有しているテーブル名]') or (owner='[owner名]' and table_name='[シノニム名]')
```
またSELECTの結果は「ownerが所有しているテーブル名」の分がカウントされ1件となった。


all_synonymsを事前チェックしない理由については調査する時間が取れなかった。


##参考サイト
--[【ASP.NET（MVC）】ODP.NET　Entityデータモデルからのテーブル作成・操作について](https://qa.atmarkit.co.jp/q/9712)
--[Oracleで実行されたSQLの履歴を確認する](https://qiita.com/kojisaiki/items/68488d3652f8e0f1dda6)
--[サポートされないEntity Frameworkの機能](https://docs.oracle.com/cd/E77579_01/win.121/e72575/entityUnsupported.htm)
DOM

少しずつ進んできた。基礎ばかりだけれどね、、、。
今週末にでもなんかしらのサイトを作ってみようと思う。さて何を作ろうか。
なんでもいいかな。

#DOM
- Document Object Model
- WEBサイトを動的に書き換えるために必要。
- JavaScriptで記述されたプログラムから、HTMLページにアクセスして、HTMLページを操作する方法を提供している。


### DOMツリー
- HTMLドキュメントやXMLドキュメントをツリー構造として表現したもの。

### ノード
DOMツリーの一つ一つのオブジェクトのこと。

#ブラウザオブジェクトの階層構造

- Windowブジェクト
    - ブラウザを操作するための機能を集めたオブジェクト
    - ブラウザオブジェクトの階層構造の最上位に位置する。

- Documentオブジェクト
    - HTMLで表現されているコンテンツを保持しているオブジェクト
    - Windowオブジェクト内で表示されたドキュメントを操作するのは、Documentオブジェクトの役割

# IDをキー要素に取得
## getElementBtIdメソッド
- 指定したidを持つ要素を１つ取得

```
document.ElementById(id)
```

今更だけど、ボタンをクリックしたときに関数showが呼ばれる。=> onclick
```
<input type="botton" value="取得" onclick="show()">
```

ボタン押したらpタグ内の文字列が日時に書き換わる。

```html:html
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<p id="result">pタグ要素</p>
		<input type="button" value="取得" onclick="show()">
		<script src="js/element_id.js"></script>
	</body>
</html>
```

```JavaScript:JavaScript
function show(){
	var result = document.getElementById("result");
	console.log(result.innerText);
	var nowDate = new Date();
	result.innerText = nowDate.toLocaleString();
}
```


##　タグ名をキー要素に取得
divの中身を取得して、ボタンをおしたらコンソールに出力

```html:html
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="result">div1</div>
		<p id="result">p2</p>
		<div id="result">div3</div>
		<span id="result">span4</span>
		<div id="result">div5</div>
		<input type="button" value="get" onclick="showElements()">
		<script src="js/element_tag.js"></script>
	</body>
</html>
```

```JavaScript:JavaScript
function showElements(){
	var elements = document.getElementsByTagName("div")
	for(var i = 0; i < elements.length; i++ )
	console.log(elements[i].innerText);
}

```
Salesforceでレポートを作る前に気を付けていること

既存のExcel管理表とかをSalesforceのレポート単体で表現するとなった時、あらかじめ気を付けておいた方がよい（気を付けている）ことをまとめてみます。

## 1.集計結果を昇順、降順で並べ替えすることはできない
日付と商品でマトリクスを作ってもレポートの中で商品の合計金額が大きい順に並べるといったことはできません。ダッシュボードを作成してトップ○○という形にすれば表現できるものの、グループ数に限界があるので注意が必要です。

<img width="705" alt="report1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364548/4cae58fb-8dc5-c9be-61f0-39163a922a95.png">
このレポートだと売上合計が大きい順に並べようと思ってもできません。

## 2.集計に使えるグループは最大縦2×横2
Excelだと3×2とかそれ以上の軸で分析してる管理表を結構見ますが、Salesforce標準のレポートで集計できるのは最大2×2までとなっています。
それ以上の軸で分析したい場合は別途ドリルダウンするとか、レポートを分けるとかの対応が必要になります。
<img width="161" alt="report2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364548/831cef5e-f025-0607-b9a6-93325055f356.png">


## 3.列だけをグループ化することはできない
毎月の遷移や四半期の遷移は列で表示した方が自然に見えるのですが、グループ化が1個だけだと行単位でのグループになってしまいます。
<img width="149" alt="report3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364548/9aba6593-6324-6f1a-f8be-b0541780fb3e.png">
オブジェクト自体に年月用の数値項目を持たせていれば集計せずに表現はできるものの、年月ごとの数値をプロセスビルダーやトリガーで集計している必要があるのでやや面倒です。


## 4.前月からの増減の追跡
<img width="469" alt="report4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364548/2844c68f-55b0-4558-db3b-274ceaced3a8.png">
この形の集計はちょっと苦手な分野になります。
[PREVGROUPVAL](https://help.salesforce.com/articleView?id=reports_summary_functions_about.htm&type=5)を使うと集計した結果に対しては差を取ることができますが、そもそも集計していないグループの値の増減は取れません（図の1月より前のデータはないので集計できない）。また、数式を使っているので集計対象でない行の集計ができません（図の1Q合計は1～3月の合計行なので別途数式が必要になる）。どうしてもExcelみたいにしたいという場合は月ごとの売上を合計するオブジェクトを作って前月比を項目として持っておく必要があります。

## 5.参照関係の並び順
選択リストやレコードタイプであれば設定した並び順を元に並び替えができますが、参照関係の場合は並び順が文字での昇順、降順になるので、「弊社で数字を確認するときはこのサービスから順に並べてるんです（サービスはマスタ）」みたいな場合は01から順に項番を振るといった対応が必要になります。

## 所感
数字じゃなくて視覚的にわかるようにするためにグラフを使えばいいじゃないかと思うこともあるのですが、実際提案してるとまだまだ数字を見て判断したいという人が多い印象です。要望をうまく実現するためにも、あらかじめ組織として重要なKPIを決めておくことと、それを実現するための設計をしっかりするのが重要だと思います。ちゃんと探したことはないのですが[IdeaExchange](https://success.salesforce.com/ideasearch)にあったら将来的に実現できるようになるかもしれません。
AWS Summit Tokyo 2019

昨年からAWSの勉強を始め、2019年2月にAWS認定ソリューションアーキテクト・アソシエイトを取得しました。
これに気を良くしたため、AWS Summit Tokyo 2019に参加してきました。

AWS Summit Tokyo 2019は2019年6月12日(水)〜14日(金)の3日間開催、会場は幕張メッセ国際展示場Hall1～3でした。

初参加でしたが幕張メッセは音楽フェスでちょくちょく行っているため勝手知ったるので、
若干の余裕をもって初日の12日(水)のみ(有給休暇を取って)参加しました。


#利用できるサービス

**昼食**
セッション会場の出入口付近でお昼時に配布されました。
パックのお茶と3種類のうちから1つを選んでもらえます。

**電源・ネット環境**
会場内に電源タップは用意されています。が、とても混雑していていました。
無料Wi-Fiも利用できますが、混雑のためかあまり速度は出ませんでした。

電源タップとWi-Fiについては後述する認定者ラウンジにラウンジ利用者専用のものが用意されていました。
認定者ラウンジを利用できる方はこちらを利用するといいかと思います。


#セッション

参加するには事前予約が必要です。
当日の参加状況に合わせて当日の飛び入り参加も可能ですが、確実に受講したいものは要事前予約です。

私が参加したのは以下の4つです。

- 【初級】AWSの利用時のおさえておきたい10のこと
- 【初級】VPC最新機能から紐解くクラウドネットワークソリューション
- 「ネットワークデザインパターン Deep Dive」
- 「Transit Gateway Deep Diveアーキテクチャガイド」

ネットワークの構築や運用の業務を担当しているので、ネットワーク系のものを受講しました。
内容については別途まとめられればいいなと思って・・・おり・・・ま・・・す。

すべてサイレントセッションでした。
サイレントセッションは4つのモニターが仕切りなく横並びに設営されています。
会場で用意されているレシーバーのチャンネルを選択することで希望のセッションの音声を聴くことができます。

こちらはライブストリーミングで配信されているため、当日会場に行けない方でも視聴可能とのことです。
また、セッションに使用した資料は後日公開されるとのことです。

初級者向けのセッションも多く開催されており、非常に勉強になりました。
資料を読むだけよりも、解説があることで理解が深ったような気がします。

#Expo会場

AWSやSponsor企業が出展しており、様々なAWSサービスを体験したり、AWS担当者や企業の方とお話をすることができます。
ブースに立ち寄り、受付票のバーコードを読み取ってもらうとノベルティがもらえるブースが多く、ガチャガチャでノベルティを決めたりと趣向を凝らしているブースもありました。

機械学習を体験できるDeepRacerリーグやSagemakerを利用した画像認識ソリューションが人気のようでした。

#認定者ラウンジ

AWS認定資格取得者専用のみが利用できるスペースです。
ラウンジの入口でAWSトレーニング認定の画面を提示して受付完了、事前予約等は不要です。
ノベルティとしてステンレスボトルと認定資格に応じたバッチをもらえました。
ノベルティは毎年違うものがもらえるようです。

電源タップが用意されておりバッテリーの心配なくPCやタブレットが使用できます。
また、私は使用しませんでしたが、認定者ラウンジ用のWi−Fiも用意されていたようです。

飲み物（水とお茶）とおやつ（ドーナッツとキャンディ）も用意されていたようですが、
私が行った時には無くなっていました。
途中何度か補充されていたみたいですが、結局ありつけずに終わりました。

#感想

基調講演ではAWSがパブリッククラウドのシェアの半分を占めていること。
様々なサービスのリリースやアップデートを行い常に進歩していることを話されており、会場盛況具合からもAWSの業界での注目度の高さを感じました。
VMWareやWindowsといった日本の企業に合わせたサービスも展開を進めているようです。

今後のAWSの方針として機械学習に注力していくようで、AWS全社員への機械学習の教育を進めていくとのことです。
前述のExpoでのDeepRacerリーグや画像認識ソリューションの盛況具合から見ても、自身がこの業界でエンジニアとして仕事をしていくために、そのような知識が求められるようになるのかと思いました。

こういった雰囲気を現場で感じてモチベーションが上がるのは、会場に参加したからこそだと思うので、参加してよかったと思います。

2020年は、5月12日〜14日パシフィコ横浜で開催されるとのことですので、こちらも参加したいと思っております。
【備忘録】MacのrbenvでRubiniusをインストールするときにハマった

## rbenvでrubiniusをインストールできない

普通に`rbenv install`しようとするとApple LLVMではrubinusをビルドできないと怒られる．

```bash
$ rbenv install rbx-2.5.1

BUILD FAILED (OS X 10.13.6 using ruby-build 20160426)


ERROR: Rubinius will not be able to compile using Apple's LLVM-based 
build tools on OS X. You will need to install LLVM 3.5 first.

TO FIX THE PROBLEM: Install Homebrew's llvm package with this
command: brew tap homebrew/versions ; brew install llvm35

BUILD FAILED (OS X 10.13.6 using ruby-build 20160426)
```

ちなみに僕の環境では`brew install llvm35`はできなかった．

## 純正LLVMを導入する

純正のLLVMを導入すればよいのだが，普通にインストールするとLLVM-3.5は入らず，より高いバージョンが入ってしまう．
しかも，今回入れたいrbx-2.5.1はLLVM-3.6以上だとだめらしい．

そこで試行錯誤していくうちに下記サイトが参考になった．
https://qiita.com/babie/items/ce242a2b5195c2001ec3
http://straitwalk.hatenablog.com/entry/2015/06/28/221227

結果LLVMはprebuiltされたものをダウンロードして環境変数で指定する形にした．
prebuilt binaryは下記URLからダウンロードした．
http://releases.llvm.org/download.html#3.5.2

## opensslがないと怒られる．

ところが今度はopensslが見つからないと怒られる．

```text
Checking for global 'timezone': found!
Checking for global 'tzname': found!
Checking for global 'daylight': found!
Checking for header 'zlib.h': found!
Checking for header 'openssl/ssl.h': not found
openssl/ssl.h is required
```

## brewで入れたLLVMのパスを指定する

最終的には`RUBY_CONFIGURE_OPTS`環境変数を指定して，`--with-include-dir`と`--with-lib-dir`をbrewで入れたopensslのパスに指定したところビルドが通った．


```bash
LDFLAGS=-L/path/to/prebuilt_clang/lib \
CPPFLAGS=-I/path/to/prebuilt_clang/include \
CC=/path/to/prebuilt_clang/bin/clang \
CXX=/path/to/prebuilt_clang/bin/clang++ \
RUBY_CONFIGURE_OPTS="--llvm-config=/path/to/prebuilt_clang/bin/llvm-config \
--with-include-dir=/path/to/openssl/include \
--with-lib-dir=/path/to/openssl/lib" \
rbenv install -v rbx-2.5.1
```

`/path/to/prebuilt_clang`と`path/to/openssl`をそれぞれの環境に合わせて使ってください．
(個人的メモ) kintoneの一覧画面を使って、画面全体をカスタマイズする

独自のUIを画面全体に描画する場合のrootとするdivです。

# kintoneのnavbarを残す場合

```html
<div style="position: fixed;
            width: 100vw;
            height: calc(100vh - 112px);
            left: 0px;
            top: 112px;
            background-color: #757575;
            z-index: 20;"
            ></div>
```

# kintoneのnavbarを残さない場合

```html
<div style="position: fixed;
            width: 100vw;
            height: calc(100vh - 0px);
            left: 0px;
            top: 0px;
            background-color: #757575;
            z-index: 20;"
     id="CTqcZ5ZV4TyalE0N"
     ></div>
```

本来の一覧画面に戻る必要がないのであれば、スタイルなどが干渉しないようにDOMを動的に変更する

```js
kintone.events.on('app.record.index.show', function(event) {
    const divEl = document.querySelector('#CTqcZ5ZV4TyalE0N');
    if (!divEl) {
        return;
    }
    // 目的の一覧画面が選択された場合

    const bodyEl = document.querySelector('body');
    // bodyの幅・高さを設定しておく
    bodyEl.style.width = '100%';
    bodyEl.style.height = '100%';
    // 元のスタイルをすべて消す
    Array.from(document.querySelectorAll('head > link[rel=stylesheet]')).forEach(x => x.remove());
    Array.from(document.querySelectorAll('body link[rel=stylesheet]')).forEach(x => x.remove());
    // 元の要素をすべて非表示にし、自分の要素をbodyの直接の子にする
    // スクリプトエラーが出るので、元の要素を消さないこと!
    Array.from(document.querySelectorAll('body > div')).forEach(x => x.style.display = 'none');
    bodyEl.appendChild(divEl);

    // Shadow DOMに出来るのであれば、するのが望ましい
    // const root = divEl.attachShadow({mode: 'open'});
    // root.innerHTML = '...';

    // Shadow DOMに出来ない場合
    divEl.innerHTML = '...';
    ...
}
```
Windows標準機能だけの高速ファイルマージ自作ツール

#動作確認環境
OS : Windows 10 Home
WSH : Windows Script Host Version 5.812

#ツール作成背景
細分化されたcsvファイルをマージする必要があり、
手動で行う場合、以下の問題があった。
・ヒューマンエラー
・10万行のファイルもあるため、ファイル開くだけでも手間

上記から、世の中のファイルマージツールを使用したいが、
開発プロジェクトで使用できるツールに制限があり、
自作でツールを作成するに至った。

#マージツール
当初は、batファイルだけで作成したが、
以下の性能問題が発生。
・100MBのファイルマージに2時間以上かかる。
そこで、マージ処理部分だけはVBS(VBScript)に置き換えることで、
1分ぐらいに改善した。
ソースは以下を参照ください。

#ソース
GitHubで公開しているため参照ください。
[merge_tool](https://github.com/bossjerom/tool/tree/master/merge_tool)
AliEaters Sapporo #2に参加してきました。

(この記事は2019年の2月のはてなブログから持ってきたものです)

題名の通り、AliEaters Sapporo #2に参加してきました。
 
## なんで参加したの？

個人的に参加した意図は、今までの勉強の中でAWSやAzureを利用したクラウドコンピューティングに対する知識は(若干)身につけていたのですが、実際に触れて構築してみるという機会がなく、またAlibaba Cloud という初見のサービスというのにも惹かれたところです。

 

いきなり感想から述べさせていただくと、

- 便利やな～(小並感)
- いままで勉強してきたあさーい知識は間違ってなかった(これは結構大きい)
- 今後はサービスを利用しながら勉強できそう
と言う感じでした。

## 本題

そろそろお前何やったんだよという感想が出てきそうなので本題に入ります。

また、今回サポートしていただいたすべての方々、特に[@pacsolution](https://twitter.com/pacsolution)さん

ありがとうございました。

本題
今回はAlibaba Cloud を利用してWikiサーバーを立ち上げるハンズオンを行いました。

まずAlibaba Cloudってなんぞや?って人のためにSB Cloudさんの[資料](https://www.slideshare.net/sbcloud/alibabacloud?qid=892005a7-dabe-489a-a4d8-4874e4923c8c&v=&b=&from_search=1)を紹介させていただきます。
 

今回の手順的には

1. 1台のECSでwikiサーバーを構築
2. そのECSのカスタムイメージ(ECSの種みたいなイメージの物)を作成し、もう一台ECSを作成
3. SLBにより負荷分散
4. RDSにより2台のサーバーのDBの可用性を向上
5. Auto Scalingにより可用性の向上
 

ちなみに私だけ結構つまずきましたが皆様に助けていただきました。

私がつまずいたのは

- wikiのセットアップを単純に忘れていた(ごめんなさい)
- サーバーのhostnameがなぜか同じのを吐いた(すいませんこれは私にはよくわかりませんでした)←誰かご覧になられていたら原因をお教えいただきたい...
でした。

つまずいたことで原因究明のステップも同時に勉強できたのでそれはそれでよかったです

 

これらの手順により負荷によって自動でECSのインスタンスが増減し、負荷分散をしてくれるwikiサーバーが立ちました。

 

ここでちょっと宣伝ですが、Alibaba Cloudは1年間使えるクーポンが30,000円分もらえるので、お金がない学生が勉強で使い倒すにはぴったりだと思います。

**注意:クレカが必要です。**

(ちなみに今回イベントで20,000円分のクーポンもいただきましたありがとうございます)

また、イベント主催の[AliEaters](https://www.alieaters.com)さんもありがとうございました。                                     


そんな感じで経験がない学生が飛び込んだらとても勉強になったお話でした。
（Jupyter notebookで）システムコマンドの出力をPythonで使う

### Jupyter Notebookで
### 1.パイソンの変数にシステムコマンドの結果を格納 

```
variable_python = !ls
```
 *ちなみにタイプは　IPython.utils.text.SList　というものらしい。
配列っぽく使えるのぽい？


### 2.システムコマンドの引数にパイソンの変数を渡す.

$　をつけることでシステムコマンドに渡せそう。。

```
python_workdir = "/User"
!ls $python_workdir
```
Oculus Questを無線接続でミラーリングする方法（Windowsの場合）

# はじめに

Oculus Questを操作している様子を友人に見せるとき、
少しでも大きい画面で見てほしい！と思い、PCへミラーリングする方法を検討しました。

PCのみでミラーリングできる方法を検討した結果、**scrcpy**でミラーリングを行うことにしました。
両目からの映像になってしまいますが、Oculusアプリでのミラーリングと違い、
ガーディアンの設定画面もミラーリングされるので遊んでもらうときにアドバイスがしやすく、
助かっています。

# 動作環境

- OS: Windows10 1803
- scrcpy: Version 1.9

# Oculus Questの開発者モードを有効にする

scrcpyでOculus Questをミラーリングするためには、
まず、Oculus Questの開発者モードを有効にする必要があります。

1. Oculusアプリで設定画面を開き、Oculus Questの「その他の設定」をタップします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294016/3d29c176-4116-a298-f421-6dbe49bcc8c3.jpeg" width=40%>

2. その他の設定画面で、「開発者モード」を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294016/c098867e-3951-6c39-0419-0a7f41413ac3.jpeg" width=40%>


3. 開発者モードを有効にします。
開発者登録をしていない場合は、登録が必要です。
任意の名前で登録しましょう。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294016/fe1d06e0-fc8c-5faa-1aac-d40d21afdbec.jpeg" width=40%>

# Oculus Questの有線接続

開発者モードを有効にした後、PCへ有線接続します。
PCへ接続すると、Oculus Quest側でダイアログが表示されるので許可しましょう。

許可すると、下記のようにOculus Questの内部共有ストレージにアクセスできるようになります。

![QuestPC接続.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294016/973635d5-7037-17b8-38dd-4783528a1db8.png)


# scrcpyのインストール

1. [scrcpy](https://github.com/Genymobile/scrcpy#get-the-app)からWindows用のZipファイルをダウンロードします。
2. ダウンロード後は、任意のディレクトリに解凍します。  
※ 以降は、「C:\Program Files\scrcpy」にファイルを解凍したことを前提に進めていきます。

# Oculus QuestのIPアドレス取得

解凍先のディレクトリで下記コマンドを実行します。
※ 今回の例だと、「C:\Program Files\scrcpy\scrcpy-win64」で実行

```bash
adb shell ip addr show wlan0
```

実行結果の「192.168.0.XX」がIPアドレスに該当します。
> inet 192.168.0.XX/24 brd 192.168.0.255 scope global wlan0

# scrcpyの実行

下記コマンドを実行します。
バッチファイルとして保存しておくと楽です。

```
REM scrcpyのインストール先
set SCRCPY_PATH="C:\Program Files\scrcpy\scrcpy-win64"

REM %SCRCPY_PATH%\adb tcpip 5555
REM 取得した<IPアドレス>:5555を引数に設定
%SCRCPY_PATH%\adb connect 192.168.0.28:5555

REM scrcpy.exeを実行
%SCRCPY_PATH%\scrcpy.exe
```

# ERRORが発生した場合

自分がscrcpyでミラーリングをしたときに発生したエラーについて対処法を記載します。

## adb: error: failed to get feature set: more than one device/emulator

```bash
adb: error: failed to get feature set: more than one device/emulator
ERROR: "adb push" returned with value 1
```
上記のエラーは、デバイスが複数台存在することで発生します。
Oculus Questが有線接続されていないことを確認してください。

接続されているデバイスは、下記のコマンドで確認できます。

```bash
adb  devices
```

## adb: error: failed to get feature set: device offline

Oculus Questの電源がオフになっている可能性があります。
一度Oculus Questをかぶってみて起動状態を確認してください。

```bash
adb: error: failed to get feature set: device offline
ERROR: "adb push" returned with value 1
```

# 参考サイト

- 
[Oculus Quest の映像をテレビに映したりキャプチャする方法](https://qiita.com/Tomoyuki_Mikami/items/183be9b0698ee00f7fac#%E6%A6%82%E8%A6%81)