OmniAICreator/Qiita-1.07M huggingface dataset:
(手順メモ) Watson Studio Jupyterでデータアセットに登録したデータをローカルにコピーする

# はじめに
最近、クラウドのWatson Studioでも、データアセットに登録したデータをproject-libというライブラリを使って簡単にアクセスできるようになりました。しかし、単純にファイルコピーする関数がないです。
そのやりかたのメモです。

# 前提
1. Watson Studioのインスタンスが作成済みであること
2. Watson Studioのプロジェクトが作成済みであること
3. アクセストークンが作成済みであること

1.と2.がまだの場合は、次の記事で手順を確認して下さい。

[無料でなんでも試せる! Watson Studioセットアップガイド](https://qiita.com/makaishi2/items/b666f847a98c2e42dfbb)

3.に関しては、簡単に手順を説明します。

プロジェクト管理の画面で一番右の、「設定」タブを選択します。
![スクリーンショット 2021-01-12 11.13.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/5c1caba9-abd0-384b-d027-02339c327e38.png)

画面を下にスクロールし、「アクセス・トークン」の右にある「新規トークン」のリンクをクリックします。

![スクリーンショット 2021-01-12 11.13.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/b4ef86e2-d4c4-b892-61a8-638cbe54b239.png)

下の画面で
① 名前は``token1``などと適当に設定
② アクセス・ロースは「エディター」を選択
③　画面右下の「作成」ボタンをクリック

![スクリーンショット 2021-01-12 11.14.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/55ca7d35-f6e8-21fd-7f65-35ade46a3e72.png)

下のように「アクセス・トークン」ができていれば、新規作成に成功しています。

![スクリーンショット 2021-01-12 11.22.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/85fbaa07-bcc7-c34b-3812-7f236d7ba2c7.png)


# 手順
Jupyter Notebook内のPythonでファイルをコピーするための手順は次のとおりです。

## Notebookの新規作成
普通に「プロジェクトに追加」「Notebook」を選択して新規Notebookを作成します。
ランタイムもデフォルトの「Default Python 3.7 XS」のままで大丈夫です。
(以前はここで「Spark」を選択する必要がありましたが、今はその必要はありません。)

![スクリーンショット 2021-01-12 11.25.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/6fad1552-3a54-9f4b-40a8-a2b47e1e47fa.png)


## 自動生成コードの挿入

次のNotebook内に、Tokenを利用したproject-lib用自動生成コードを挿入します。

① Notebook上部にある「三」のようなアイコンをクリック
②　メニューから「プロジェクトトークンの挿入」を選択

![スクリーンショット 2021-01-12 11.27.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/2fb6968b-7952-98a6-bb42-a8052fdff6bb.png)

一番上のセルが下の画面のようになっていれば、コードの自動生成に成功しています。

![スクリーンショット 2021-01-12 11.29.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/159547f9-8ef0-5079-211e-b834393b5aec.png)

まず、このセルを実行して下さい。

## ファイルコピー

ここまでの準備ができれば、あとは簡単なコードで、ファイルコピーができます。
以下にサンプルコードを示します。

```py3
# project-libを使ってデータアセットのファイルをローカルにコピーする

fn = 'cifar10-pytorch-sample.gz'
infile = project.get_file(fn)
with open(fn, 'wb') as local_file:
    local_file.write(infile.read())
```

``ls -l``コマンドで実際にコピーできたか、確認してみます。

```py3
!ls -l
```

以下のようにうまくいきました。

```
total 4568
-rw-r----- 1 wsuser watsonstudio 4673955 Jan 12 02:38 cifar10-pytorch-sample.gz
```
ubuntuにCUDA、nvidiaドライバをインストールするメモ


# Nouveau の無効化

```bash
sudo gedit /etc/modprobe.d/blacklist-nouveau.conf
```

nouveauの設定ファイルを新規作成して以下を記入して保存する

```blacklist-nouveau.conf
blacklist nouveau
options nouveau modeset=0
```

保存したら以下を実行

```bash
sudo update-initramfs -u
```



# 使用しているGPUの確認

```bash
lspci | grep -i nvidia
```

# 現状入っているCUDA,nvidia-driverの確認

```bash
dpkg -l | grep nvidia
dpkg -l | grep cuda
```

# 現状入っているCUDA nvidiaドライバの削除
参考

https://qiita.com/not_charge/items/dce7512544a7ead04bca


```bash
sudo apt-get --purge remove nvidia-*
sudo apt-get --purge remove cuda-*
```

# nvidia-driver のインストール
以下で推奨のドライバを確認

```bash
ubuntu-drivers devices
```

### aptからインストールする方法

インストール（nvidia-driver-460の場合)

```bash
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt update
sudo apt install nvidia-driver-460
```

再起動

```bash
sudo reboot
```

以下で確認

```bash
nvidia-smi
```

### .runファイルからインストールする方法

こちらの記事に手順をまとめました

https://qiita.com/porizou1/items/09270f2b4d3196b00aee

# CUDAのインストール

CUDA Downloadsのページで以下を選択した場合のコマンド

Operating System：Linux
Architecture：x86_64
Distribution：Ubuntu

https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1804&target_type=debnetwork



ubuntu20.04の場合

```bash
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin
sudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600
sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub
sudo add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /"
sudo apt-get update
sudo apt-get -y install cuda
```

ubuntu22.04の場合
```bash
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-ubuntu2204.pin
sudo mv cuda-ubuntu2204.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/12.0.0/local_installers/cuda-repo-ubuntu2204-12-0-local_12.0.0-525.60.13-1_amd64.deb
sudo dpkg -i cuda-repo-ubuntu2204-12-0-local_12.0.0-525.60.13-1_amd64.deb
sudo cp /var/cuda-repo-ubuntu2204-12-0-local/cuda-*-keyring.gpg /usr/share/keyrings/
sudo apt-get update
sudo apt-get -y install cuda
```

バージョン指定する場合 （推奨）（指定しない場合最新のCUDAが入る）

```bash
sudo apt-get -y install cuda-11-2
```

~/.bashrcの末尾に以下を追加

```bash
export PATH="/usr/local/cuda/bin:$PATH"
export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"
```

バージョンの確認

```bash
nvcc -V
```


# 参考

https://qiita.com/kawazu191128/items/8a46308be6949f5bda57


https://qiita.com/yto1292/items/463e054943f3076f36cc



https://qiita.com/konzo_/items/a6f2e8818e5e8fcdb896
中国版(cn.aliyun.com)のAlibabaCloud Elastic Web Hosting(弹性Web托管)導入手順 解約編

中国版(cn.aliyun.com)のAlibabaCloud Elastic Web Hosting(弹性Web托管)導入手順 WordPress解約編

本記事は [中国版(cn.aliyun.com)のAlibabaCloud Elastic Web Hosting(弹性Web托管)導入手順 導入編](https://qiita.com/junk87/items/4a32376ec06e8d6a4faf) の続きとなります。
購入から一年たちましたので今回は更新せずに解約を行ってみます。

## ■ 免責事項

本手順は完全性、正確性、有用性、安全性などを保証するものではありません。
本手順に基づき実施した判断および起こした行動によりいかなる問題が発生しても一切責任をおいません。
本手順を利用の際は全て自己責任にてお願いします。

## ■ 解約手順

欠费与续费
https://help.aliyun.com/document_detail/29842.html?spm=5176.11065259.1996646101.searchclickresult.2b5f1fdccXcVFQ


を確認するかぎり更新しなければ自動的に解約となるようです。

```
インスタンスの有効期限が切れてから15日間はインスタンスが停止しています。 インスタンスとデータはあなたのために保持されます。 
利用停止後15日以内に未納分の料金をチャージすると、自動的にサービスがオンになります。
インスタンスの有効期限が15日以上になると、インスタンスは解放され、関連する構成データは永久に削除され、復元することはできません。
```
※DeepL翻訳

有効期限終了後、阿里云から期限切れのメールが届きます。

```
件名
阿里云弹性Web托管服务到期提醒
(AliCloud Elastic Web Hosting Serviceの有効期限のリマインダー)

本文
您在弹性Web托管服务创建的应用cdb***********8已于2020-12-16 00:00:00正式到期，停止服务。 
*数据将为您保留15天。逾期未续费，应用及相关数据会被释放，且不可恢复。 
*如您要继续使用，请到官网续费。
(Elastic Web Hosting Service で作成したアプリケーション cdb*********** 8 は、2020-12-16 00:00:00 に正式に期限切れとなり、サービス終了となりました。
*データは15日間保存されます。 有効期限を過ぎると、アプリケーションおよび関連データは解放され、復元することはできません。
*引き続きご利用になる場合は、公式サイトにてリニューアルをお願いします。)
```
※DeepL翻訳

期限切れ日より15日以降にAliyun Console へログイン後、Elastic Web Hosting(弹性Web托管)ダッシュボードを確認します。

![ewh-dashbord.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74171/e332c61e-dc0d-caf4-1a1b-1f8bb9bacd59.png)

实例状态（インスタンスの状態）が已过期(期限切れ)となっていますがインスタンスは存在しています。
必ずしも15日後、即座にインスタンスが解放されるわけではないようです。

インスタンスの管理画面を確認します。

![ewh-management.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74171/6cd413e1-6fa2-ae5b-5c49-1ccb6cf2f888.png)

インスタンスの状態は已停止(停止)となっています。到期日(有効期限)の续费(更新)のリンクをクリックすると更新画面が表示されます。

![ewh-renew.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74171/418f1d63-12f2-ca58-7f00-d8208327ef03.png)

有効期限15日以降も更新できるようですが今回は更新せずに期限切れのままとしました。

以上で解約編は完了となります。次回作にご期待ください。
Python: Google Drive APIで共有ドライブからファイル情報を取り出す

# 内容
[Google Drive API](https://developers.google.com/drive)を使って指定の共有ドライブのディレクトリからファイル一覧を抜き出すためのメモ

# コード
[Python Quickstart](https://developers.google.com/drive/api/v3/quickstart/python)と同じ関数の引数を変更すればOK

```python
import pickle
import os.path

from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from typing import Final
from typing import List

SCOPES: Final[List] = [
    'https://www.googleapis.com/auth/drive.metadata.readonly'
]
SHARED_DRIVE_ID: Final[str] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
DIRECTORY_ID: Final[str] = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy"
FILENAME: Final[str] = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"


def get_credentials(scopes: List):
    credentials = None
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            credentials = pickle.load(token)
    if not credentials or not credentials.valid:
        if credentials and credentials.expired and credentials.refresh_token:
            credentials.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', scopes)
            credentials = flow.run_local_server(port=0)
        with open('token.pickle', 'wb') as token:
            pickle.dump(credentials, token)
    return credentials


def directory_files(filename: str, directory_id: str,
                    pages_max: int = 10) -> List:
    """
    対象のディレクトリ配下からファイル名で検索した結果を配列で返す
    :param filename: ファイル名
    :param directory_id: ディレクトリID
    :param pages_max: 最大ページ探索数
    :return: ファイルリスト
    """
    credentials = get_credentials(SCOPES)
    service = build("drive", "v3", credentials=credentials)
    items: List = []
    page = 0
    while True:
        page += 1
        if page == pages_max:
            break
        results = service.files().list(
            corpora="drive",
            driveId=SHARED_DRIVE_ID,
            includeItemsFromAllDrives=True,
            includeTeamDriveItems=True,
            q=f"'{directory_id}' in parents and "
              f"name = '{filename}' and "
              "trashed = false",
            supportsAllDrives=True,
            pageSize=10,
            fields="nextPageToken, files(id, name)").execute()
        items += results.get("files", [])

        page_token = results.get('nextPageToken', None)
        if page_token is None:
            break
    return items

items = drive_util.directory_files(
    filename=FILENAME,
    directory_id=DIRECTORY_ID)
for item in items:
    print(f"{item['id']} : {item['name']}")

```

# 参考
https://developers.google.com/drive/api/v3/reference/files/list
https://developers.google.com/drive/api/v3/search-files

# 余談
`directory_id` に指定したフォルダへのアクセス権がない場合、itemsは空のリストになる。
利用してるアカウントにフォルダを共有してあげる必要がある。
`fields`で設定できる内容はここ
https://developers.google.com/drive/api/v3/reference/files
[Android]keystoreのパスワードが間違っていると出た時

Android開発中にテストしようとDeployGate用にbundletoolを使ってaabから署名付きapksを作ろうとしたときにエラーが出たので、その時の解決策を載せておきます。

#問題

```
bundletool build-apks --bundle=release.aab --output=release.apks \
--ks=/Users/hoge/.android/release-key.keystore \
--ks-pass=pass:パスワード \
--ks-key-alias=エイリアス \
--key-pass=pass:パスワード

[Error] Keystore was tampered with, or password was incorrect
```

絶対パスワードもエイリアスもあっているのになあと思ったのですが、一応分けて実行してみました。
↓↓↓

#解決策
エイリアスを入力、パスワードは聞かれるまで入力せず実行

```
bundletool build-apks --bundle=release.aab --output=release.apks --ks=/Users/hoge/.android/release-key.keystore --ks-key-alias=エイリアス
パスワードが聞かれる
pass:                        ←ここにパスワード入力
```

これで解決

おそらく最初のやり方で「\」の前後でいらないスペースとか何かが含まれてしまっていたのでしょう。

パスワードあってるだろおおおおおおお！！！！ってなっても解決しない時は入力を分けて実行してみてください！
困っている誰かに役立てたら幸いです。
元エンジニア採用担当の方に未経験でのエンジニア転職・ポートフォリオ作成について相談してみた。

筆者は福岡県在住で、未経験から、独学でプログラミングを勉強し、転職を目指しています。
エンジニア転職の相談会があり、その内容が誰かのお役に立てばいいなと思いこの記事を作成しました。

福岡市が行っているEnginner Friendly City Fukuokaという事業の一環で
[エンジニアカフェ](https://engineercafe.jp/ja/)というものがあります。
そちらのイベントでポートフォリオの無料相談会がありオンラインで参加させていただきました。discordというアプリを使用しての相談をしました。
相談に乗っていただいたのは、元エンジニアの採用担当を企業で行っていた方でした。
私は現時点ではまだポートフォリオ作成に至っておらず、現在取り組んでいるrailsチュートリアルが終わり次第ポートフォリオ作成予定ですので以下の内容を相談しました。

(質問内容)
未経験からエンジニア転職する場合どれくらいのレベルのポートフォリオを必要とされているのか？（かなりざっくりとした内容ですみません、、、）
______
(解答していただいた内容）

まず大前提としてエンジニアは技術職であるため
採用側からすると、以下の点をまず知りたいとのこと。

###1．採用後即戦力になれる技術力があるか？ また、戦力として働けるようになるまでどれくらいの教育コストがかかるのか？

この実力を知るためにもポートフォリオが必要で、以下がポートフォリオのレベル（内容）についての回答。


###2.1 ポートフォリオの内容は、就職希望者の主観での完成未完成あまり関係く、自分がもっているスキルを表現できていればOK

ポートフォリオ作成して就職活動をする際に、完成してから就職活動をしようとする方がよくいるとのことだが、この方法はおすすめしないとのこと。
理由としては最低限の自分のアピールしたスキルをポートフォリオに組み込んでいれば、採用側は現時点でのそのスキルで判断できると。

###2.2 プログラミングスクールや参考書などでつくったものをポートフォリオに使用しない。自分なりに作りたいものをつくること（既存のアプリのコードをコピーして使用してもOK)
上記作成物は作者の意図がなく、コードのコピペなどでも作成可能なのでポートフォリオに使用しないこと。採用側としては技術力の判断ができないため使用はNG。
既存のアプリのコードをコピーして、自分のポートフォリオで動くようにすることは技術の向上にもなるので全然OKとのこと。

###2.3ポートフォリオはweb上の実際に動く環境で公開する。コードもクラウド上に保管し、更新内容などが採用担当側にわかるようにしておく。
この辺りは私がちょっと勉強不足であまり理解できなかったので、調べます。（泣）
アプリはherokuなどで公開することなのかな？コードのほ保管については勉強します。すみません。
READ.MEなどでアプリケーションの内容の説明をいれておくようにとのことでした。

###2.4 中途採用であればスピード感が大事。
これは中途採用の就活の基本的な内容にはなるが、ある程度のポートフォリオができたらまずは応募することが大事。技術力的に同程度または、それより少し以下の場合でも企業側とマッチングすれば採用が決まってしまうから。

___
以上の内容を解答していただきました。実際にエンジニアの方とお話しするのは初めてで緊張しましたが、とても丁寧に回答していただけました。感謝。。
さっと書いたので内容がごちゃごちゃしているかもしれません。
もし読んでいただけたのならありがとうございました！！
ともにがんばりましょう！！
Pythonを使う人がJavaScriptの空辞書の判定ではまった話

普段は機械学習系のプログラミングでPythonを使うことが多いのですが、画面回りもやる必要があり、その時JavaScriptの辞書を `if` 文で判定するコードであれ？と思ったこと。勘違いと言ってしまうとそれまでですが。

# Pythonの場合

Python で辞書が空かどうか判定するのに以下のような `if` 文を書いていました。`x` が空辞書やnullの時は `False` になります。

```sample.py
x = {}
if x:
  print("xは空ではない");
else:
  print("xは空です");
```

実行結果

```
xは空です
```

# JavaScriptの場合

一方で JavaScript だと空辞書の場合 `True` になります。

```sample.js
var x = {};
if (x) {
  console.log("xは空ではない");
} else {
  console.log("xは空です");
}
```

```
xは空ではない
```

空かどうか判定する方法はいろいろあるようですが `Object.keys(x)` でキーの数を調べることでできるようです。

```sample.js
var x = {};
if (Object.keys(x).length) {
  console.log("xは空ではない");
} else {
  console.log("xは空です");
}
```

つい、うっかりPythonと同じように考えてコーディングしてしまい、「うまく動かないな」と悩んでしまいました・・・

# 参考文献
JavaScriptの `if(x)` での判定結果がオブジェクトごと `True/False` どちらになるかはこちらに纏められていてわかりやすいです。
- [[JavaScript] null とか undefined とか 0 とか 空文字(”) とか false とかの判定について](https://phiary.me/null_undefined_zero_false)
ダチョウ倶楽部げーーっむ

「俺がやるボタン」を押した数だけ
「どうぞボタン」を押すといっぺんに「どうぞ」が返ってくる

ボタンでカウントアップして

どうぞボタンでそれを受け取り```repeat```メソッドで「どうぞどうぞ」を繰り返してポップアップに表示

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./style.css">
    <title>DatyoukurabuGame</title>
</head>
<body>
    <h1>ダチョウ倶楽部ゲーム</h1>
    <button onclick="countup()">俺がやる!!!</button>
    <button onclick="douzo()">どうぞどうぞぉ～</button>
    <script src="./index.js"></script>
</html>
```


```js
var count = 0
function countup() {
    return count++ 
}

function douzo(countup) {
    console.log(count)
    const str ="どうぞどうぞ"
    const action =str.repeat(count)
    alert(action)
}
```
Git ローカルリポジトリにあるブランチ間の差分を出力する

# 目的

- Gitのローカルリポジトリ内のブランチ間のソースを比較する方法をメモ的にまとめる

# 方法

- AブランチとBブランチの差分を出力したい場合、ローカルリポジトリ内部で下記コマンドを実行する。

    ```terminal
    $ git diff Aブランチ Bブランチ
    ```

# 具体例

- materブランチとdevブランチの差分を出力したい場合下記コマンドをローカルリポジトリ内部で実行する。

    ```terminal
    $ git diff master dev
    ```
Apple Developer Programに法人登録する際に気になった点


iPhoneやiPadなどのアプリ、いわゆるiOSアプリをリリースするためには、Apple Developer Program（以下「ADP」）に登録する必要があります。
https://developer.apple.com/jp/programs/

会社でiOSアプリをリリースするために、このADPに法人として登録することになりました。
法人登録の方法はいくつものサイトで紹介されているのですが、登録までに気になった点を3つほどまとめましたので、これから登録をされる企業の担当者の方などのご参考になればと思います。

※この記事はコード紹介のような技術的な記事ではありません。

#法人登録は1回のみ
ADPに登録できるのは１法人につき1回のみです。
より具体的にいえば、登録できるDUNSNumberが1つだけのようです。

なので会社の部署ごとにアプリをリリースする、といった形は取ることができません。
この部分がGooglePlayとの大きな違いではないでしょうか。

実際に別の会社で申請された方の話を伺ったところ、すでに法人登録されているという連絡がAppleから来たそうです。

#申請は個人として行う必要がある
法人登録というと、まず法人名でAppleIDを取得して、そのIDからADPに参加して・・・という流れを考えつきます。
確かに個人登録であれば個人のAppleIDがそのままADPに紐づくのですが、法人登録の場合は個人、つまりその会社の社員のアカウントから法人登録を行うことになります。
AppleID自体は個人の氏名でなくても登録ができますが、ADPに法人登録する際には後述の登録確認の際に弾かれる可能性があるようです。

#登録確認がある
ADPへの登録申請が無事終了したら、Appleの方から申請者に対して電話がかかってきます。
内容はその申請者が法人にとって契約を締結してもいい人物かどうか確認するというもの。
企業の経営者であれば問題ありません。幹部や権限のあるPL/PMでも大丈夫なようですが、必ず登録申請をする際には上の方の確認を取りましょう。

ちなみに日本で登録する際には日本語での会話が可能でした。
この点は英語で行われるアプリ審査のやり取りとは別物ですね。


以上、法人登録する際に気になった点をご紹介しました。
間違いなどありましたらコメントいただければ幸いです。

#参考にさせていただいたサイト
Apple公式
https://developer.apple.com/jp/programs/enroll/

【2020年版+画像15枚】法人でApple Developer Programに登録する手順
https://pentagon.tokyo/app/1305/

Apple Developer Programに法人として参加する
https://qiita.com/moco3/items/4602ffbf4e60b7e35037
Laravel,Graghql,Lighthouseで複数カラムのバリデーション

## 環境
Laravel 6.18.6
lighthouse: 4.11.0


## コード
```user.graghql
   # 下記の定義はサンプルです。
createUser (
   user_name: String!
   password: String!
): User
```

```app\Graghql\Directives\Validations\createUserValidation.php

    /**
     * @return mixed[]
     */
    public function rules(): array
    {
        return [
            "foo" => [
                new Bar($this->args['bar'])
            ]
        ];
    }

```

## 結論
$this->args['foo'];で取れる。
BigQueryを利用したデータ基盤の利用度のモニタリング

# 背景
データ基盤は意思決定に使われて初めて価値を発揮する。データ基盤が適切に開発/運用されているかどうかをモニタリングしたい場合は、データ基盤が組織の意思決定にどの程度貢献したかを測定したい。が、それを測定するのは困難。

なので、今回はBigQueryを利用したデータ基盤において、それがどの程度利用されているかをモニタリングできるようにし、意思決定への貢献度の雰囲気とか空気感くらいはわかるようにしたい。

### メタデータテーブルの永続化の必要
BigQueryの利用度をモニタリングする上で重要なのが、メタデータの永続化。
例えば、クエリジョブに関するメタデータを保存するビュー [INFORMATION_SCHEMA.JOBS_BY_*](https://cloud.google.com/bigquery/docs/information-schema-jobs) は180日しか保存されない。長期スパンでのモニタリングを行うためにはこの辺りを永続化しておく必要がある。デイリーで、前日分のログを貯めておくなど。

# モニタリング

## 1.コストのモニタリング

コストのモニタリングは、GCPのお支払いレポートで十分だと思う。プロダクト毎のコストの推移や、デイリーのコストの推移も見れる。

![スクリーンショット 2020-12-24 10.07.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/47fa1077-ac9c-4d9d-29f4-a5ebceaf2d84.png)

## 2. ダッシュボード数 & ダッシュボードPV

データ基盤の活用が組織に広まると、活用される機会が多くなるダッシュボード。
定期的に参照されているダッシュボードが何個あって、どの程度PVがあるかを棚卸ししておくと活用度の推移が見えやすい。
TableauにはPV機能があるのでそれを利用。 Data Portalの場合はGAが埋め込めるのでそれを利用する。

[レポートの利用状況を測定する](https://support.google.com/datastudio/answer/7410792?hl=ja)


## 3. クエリ実行UU

クエリを実行したアカウントのユニーク数をカウント。毎月何人くらいがBigQueryを参照しているか。

```jsx
SELECT
  DATE_TRUNC(DATE(creation_time, "Asia/Tokyo"), MONTH),
  COUNT(distinct(user_email)) as uu,
FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
WHERE job_type = "QUERY"
AND state = "DONE"
GROUP BY 1
ORDER BY 1 ASC
```

## 4. クエリ量の推移

1ヶ月でどの程度スキャンされたか。別にこれが多いからいいとか、少ないからダメってわけではない。推移を見ながら利用がどう広がっているかは把握できる。

```jsx
WITH base_tables as (
SELECT
  job_id,
  creation_time,
  total_bytes_processed,
FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT 
WHERE job_type = "QUERY" 
AND state = "DONE" 
)

SELECT
  DATE_TRUNC(DATE(creation_time, 'Asia/Tokyo'), MONTH),
  COUNT(*)
FROM base_tables
GROUP BY 1
ORDER BY 1 asc
```

## 5. スキャン量の推移

1ヶ月でどの程度スキャンされたか。別にこれが多いからいいとか、少ないからダメってわけではない。推移を見ながら利用がどう広がっているかは把握できる。

```jsx
WITH base_tables as (
SELECT
  job_id,
  creation_time,
  total_bytes_processed,
FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT 
WHERE job_type = "QUERY" 
AND state = "DONE" 
)

SELECT
  DATE_TRUNC(DATE(creation_time, 'Asia/Tokyo'), MONTH),
  SUM(total_bytes_processed)
FROM base_tables
GROUP BY 1
ORDER BY 1 asc
```



## 6. データ量

点でしか取れない。デイリーで保存して推移を見たい。

```jsx
SELECT
  table_id,
  SUM(size_bytes) / 1000000000 as size_GB
FROM (
  SELECT * FROM `datasource1.__TABLES__`
  UNION ALL
  SELECT * FROM `datasource2.__TABLES__`
  UNION ALL
  SELECT * FROM `datasource3.__TABLES__`
)
GROUP BY 1
ORDER BY 2 desc
```

## 7. レコード数

点でしか取れない。デイリーで保存して推移を見たい。


```jsx
SELECT
  SUM(row_count)
FROM (
  SELECT * FROM `datasource1.__TABLES__`
  UNION ALL
  SELECT * FROM `datasource2.__TABLES__`
  UNION ALL
  SELECT * FROM `datasource3.__TABLES__`
)
--GROUP BY 1
ORDER BY 1 desc
```
【メモ】不要な変数を"_"（アンダースコア）へ代入する

* 製造業出身のデータサイエンティストがお送りする記事
* 今回は自分のメモとして記事に残しておきます。

##はじめに
Pythonのコードを読んでいて返り値が"_"（アンダースコア）になっているコードを見てなんだろう？と不思議に思って調べたので、メモとして残しておきます。

##Return値を無視する
いろいろと調べたら下記のような文章を発見しました。

>Pythonはライブラリが沢山あって、関数をインポートして使う事が多いです。そういう時、もし関数からのreturn値が複数あって使わない部分があったらアンダースコアを使ってreturn値のメモリの占用をしないまま廃棄ができます。

つまり、return値を無視しますという意味だったそうです。

例としては下記のような使い方をするそうです。

```php
def get_tuple():
    return ('amedama', 'Japan/Tokyo')


def print_name():
    name, _ = get_tuple()
    print name

if __name__ == '__main__':
    print_name()
```

関数の返り値がタプルである以上、タプルで受けるしかないありませんが、アンダーバーから始まる変数の値は意識しなくて良い (使われない) という意図を伝えることができるそうです。

##参考文献
* [参考文献1](https://medium.com/lsc-psd/pythonic%E8%89%B2%E3%80%85-python%E3%81%AE%E3%82%A2%E3%83%B3%E3%83%80%E3%83%BC%E3%82%B9%E3%82%B3%E3%82%A2-%E3%82%92%E4%BD%BF%E3%81%84%E3%81%93%E3%81%AA%E3%81%9D%E3%81%86-3c132842eeef)
* [参考文献2](https://momijiame.tumblr.com/post/28130976849/python-%E3%81%A7%E4%BD%BF%E3%82%8F%E3%81%AA%E3%81%84%E3%82%BF%E3%83%97%E3%83%AB%E3%81%AE%E5%80%A4%E3%81%AF-%E3%82%A2%E3%83%B3%E3%83%80%E3%83%BC%E3%83%90%E3%83%BC-%E3%81%AB%E4%BB%A3%E5%85%A5%E3%81%99%E3%82%8B%E3%81%A8%E3%81%84%E3%81%86%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9)
PDFからテキストをコピペしたら一部が部首になっていた問題

・・・タイトルが意味不明だけど。

受け取ったPDFからテキストをテキストエディタ（EmEditor）にコピペしたら、文字がおかしい。「目」や「止」がパッと見似ているけれどちょっと小さい。なんだこりゃ。

調べてみたら、PDFへ出力する時に発生する問題とのこと。
ExcelやWord（主にMac版？）からPDFへ出力するときに生じることが多いようだ。

> 漢字のようで漢字でないUnicodeの「康熙部首」と「CJK部首補助」
https://techracho.bpsinc.jp/hachi8833/2020_10_07/95257

一括置換できる方法を探したけれど、結局、目視で最終確認が必要そうだったので、発行元に元データ（excel）を再送してもらった。

念のため元データからテキストを抜き出し、「康熙部首」や「CJK部首補助」が含まれているかどうかをチェック（下記を利用させてもらった）。問題なしということで無事解決。

>日本語の文章のタイポ/変換ミス/誤字脱字エラーをチェック/校正
https://enno.jp/check
Windows10でのUbuntu20.04導入やテキストエディタについてのお話

#はじめに
Windows10でVirtualBoxを用いてUbuntu20.04を導入し、Pythonやpip3等の設定をした後、vimなどのテキストエディタについて友人などに聞いた小話とかをします。

自分がPythonのプログラムをする為に設定をしました時にかなり時間が掛かったので調べてもわかりにくかったことを重点的に書いていく為、調べてすぐに出てくるところは多少省略します。


#目次
1. BIOSの仮想化支援機能の設定
2. VirtualBoxの導入
3. Ubuntuの導入
4. Python,pip3の設定
5. テキストエディタの小話

##BIOSの設定
BIOSの設定で、仮想化支援機能というものがあります。
しかし、WIN10からはBIOS設定を無視して起動を高速化しているため、「F2」や「DEL」キー（大抵このどちらかのキーでBIOS画面に行けるメーカーが多い）を押してもBIOSの設定画面が表示されません。
その為、「コントロールパネル」→「ハードウェアとサウンド」→「電源オプション」→「システム設定」のシャットダウン設定の「高速スタートアップを有効にする」のチェックを外してください。
![BIOS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/930086/d33e11dd-9d2c-d0c7-db2a-48e3eb3e9451.png)
その後、BIOSからIntel VTをONにします。
もうBIOS画面には行かないので高速スタートアップは有効に戻して大丈夫です。

##VirtualBoxの導入
これはあまり難しくなかったので省略します。

##Ubuntuの導入
VirtualBoxを起動したら、上にある新規を押し、設定をしていきます。
メモリーは相当重い処理をするつもりがないなら公式推奨値の4GB,ハードディスクは仮想で作成し、ファイルサイズはUbuntu自体が4.5GB程あるので~~10GB以上用意すれば大丈夫だと思います。~~
最近Ubuntuに色々ダウンロードしてたら10GBでは足りなくなり、32GBまで拡張しました。できるだけ大きめに取りましょう。(戒め)（2021年1月30日修正）
ローカルディスク/ユーザー/(ユーザー名)/VirtualBox VMs/(システム名)
＊()の中は人によって変わります。システム名はさっき付けたVirtualBox内のUbuntuの名前です。
このシステム名のファイルの中にUbuntuのISOファイルを入れます。
これでようやく起動できます。起動を押すと起動ハードディスクを選択と表示されます。先ほど入れたUbuntuのファイルが選択できるはずなので選択して起動します。
初回起動後の設定は解説されていることが多かったので省略します。

##Python,pip3の設定
Ubuntuが起動出来たらTerminalを起動します。それから、

```python

sudo apt update
sudo apt -y upgrade
```
と打ち込みます。これらは元からUbuntu20.04に入っているPython3のバージョンを最新にするためです。
-yはコマンドを打った後に確認のためにy/n(はい/いいえ)を聞かれるのですが、それをすべて、y(はい)と答えるものです。
その後、pip3のバージョンも最新にしましょう。

```python

sudo apt install -y python3-pip  
```

これでPython3、pip3ともに最新バージョンの状態になりました。

##テキストエディタの小話
プログラムを書く為に導入したのですが、自分は「vim」を使っていました。導入は簡単でしたが、使い方は難しく、設定を調べても訳が分からずそのままふて寝したりもしました。

```python

pip3 install vim   //vimをインストール
vi ~/.vimrc   //vimの設定ファイルを開く
```

設定ファイルを開いた後は設定するコマンドを入力した後設定ファイルを閉じることで設定が出来ます。閉じるためには

```vim

ESCキー
:wq   //入力した設定コマンドを保存してファイルを閉じる。
```

を押します。ここで:wqを打ち込むにも文字が表示されなかったので打てているかわからなくてやりにくいなって思いました。
設定コマンドは例えば、

```vim

set number
```

であれば行数が表示されるようになります。
上のようにset + 設定内容 って感じで設定できます。この辺は個人の好き好きに設定を調べて追加してもらえればと思います。

これらの設定をしてから、使いにくくね？って思い、友人たちに聞いた所、「nano」だったり、「Visual Studio Code」(以下VS code)でプログラムを作ってからUbuntuに移すだったりと助言を貰いました。
「nano」は比較的メモ帳に近い感覚で使用できるものです。
「VS code」はMicrosoft社が作成していますがWindowsだけでなくMACも使えます。拡張機能も無償で多くあるらしく幅広く使えると思います(授業で軽く触れたくらいなのであんまり語れないです)。

結局テキストエディタの選び方はロマンは「vim」、面倒な設定などが嫌なら「nano」,「VS code」などを使うと良いと思います。
Docker-Volumeのバックアップとリストア

# Docker-Volumeのバックアップとリストア

## 何故か標準でバックアップ方法が存在しない

　DockerはImageやConteinerは簡単にバックアップがとれるのに、何故かVolumeに関しては標準的なバックアップ方法が存在しません。ということでできる限り簡単な方法を考えてみました。

## ネットで検索すると出てくる方法

　VolumeをマウントするConteinerを作って、バックアップを作成する方法が多数ヒットします。ただ、残念なのはその出力先です。何故かバックアップファイルをConteiner内、もしくはDockerホスト上のディレクトリに作成していました。

　それをやられると、リモートでコマンドを使った場合に、手元にバックアップが残りません。作成したバックアップを何らかの手段でさらに引き寄せる必要があります。非常に面倒です。

## 標準入出力を使おう

　dockerコマンドは標準入出力でConteinerとデータをやりとりすることが出来ます。つまりバックアップファイルを標準出力に出すだけで、コマンドを実行した環境にバックアップ結果を吐き出すことが出来ます。

## バックアップコマンドを作ってみる

以下のようなコマンドを実行すると、期待通りに動いてくれます。
`>`によるリダイレクトはConteiner上ではなく、dockerコマンドを実行したローカル環境で働くからです。

- バックアップコマンド

```sh
docker run --rm -v [Dockerボリューム]:/backup busybox tar cvz -C /backup . > [バックアップファイル名.tar.gz]
```

- リモートのDockerホストに対してボリュームのバックアップ

```sh
docker -H [ホスト名] run --rm -v [Dockerボリューム]:/backup busybox tar cvz -C /backup . > [バックアップファイル名.tar.gz]
```

リモートのバックアップした場合も、もちろんローカル環境にバックアップをとることが出来ます。

## リストアコマンドを作ってみる

- リストアコマンド

dockerコマンドで-iを使い、標準入力を使えるようにします。

```sh
docker run --rm -i -v [Dockerボリューム]:/backup busybox tar xvz -C /backup < [バックアップファイル名.tar.gz]
```

- リモートのDockerホストに対してボリュームのリストア

```sh
docker -H [ホスト名] run --rm -i -v [Dockerボリューム]:/backup busybox tar xvz -C /backup < [バックアップファイル名.tar.gz]
```

## 高速化したい

　バックアップやリストアは出来るようになりましたが、もっと高速に処理したくなります。tarでzオプションを使うとgzipが使われますが、これをpigzのような並列処理対応のコマンドで置き換えれば、ホスト側のCPUのコア数に応じて高速化が見込めます。しかしざっと探したところ、pigzが入っている軽量Imageが見つかりません。もしかしたらどこかにあるかもしれませんが、探すより作った方が早いので作ることにしました。

## バックアップ用Imageを作成する

pigz付きalpineのImageを作成します。
コマンドを書かなくても良いように、CMDも設定しておきます。

- バックアップ

```Dockerfile
FROM alpine
RUN apk --no-cache add pigz
CMD sh -c "tar cv -C /backup . | pigz"
```

- リストア

```Dockerfile
FROM alpine
RUN apk --no-cache add pigz
CMD sh -c "pigz -d | tar xv -C /backup"
```

## Docker Hubに登録

- 置き場所
  - バックアップ  
<https://hub.docker.com/r/dktools/backup>
  - リストア  
<https://hub.docker.com/r/dktools/restore>
- 使い方  
  - バックアップ  
`docker --rm -v [DOCKER-VOLUME]:/backup dktools/backup > backup.tar.gz`
  - リストア  
`docker --rm -i -v [DOCKER-VOLUME]:/backup dktools/restore < backup.tar.gz`

今のところパラメータ指定などはありませんが、気が向いたらそのうち機能を追加します。

## まとめ

　私の場合Dockerはtls接続でリモート管理しているので、バックアップをローカルに呼び寄せないと面倒なので、今回のようなものを作成しました。ちなみにsshのポートフォワードをしている場合も、リモートバックアップは可能です。ただtlsで直接接続している場合とポートフォワードでは、ポートフォワードの転送速度が数倍遅いので、出来ることならtls設定を入れた方が効率は上がります。

　tls設定に関してはこちらに記事を書いています。
　[UbuntuにDockerをインストールし、tlsを使ったリモート接続の設定を行う](https://qiita.com/SoraKumo/items/fd5fdf60c46e6ac93589)
bashで数字を読みやすい単位で表示する

数字を 123k とか 123.45M とか、大きさに応じて読みやすい(human-readableな)単位で変換する関数。

# ノーマル実装

```bash
convert_unit() {
  local RESULT=$1

  if [[ `echo -n ${RESULT%%.*}` -lt 1000 ]]; then
    echo -n "${RESULT}"
    return
  fi

  for U in k M G T P; do
    RESULT=`echo "scale=2; ${RESULT} / 1000" | bc`
    [[ `echo -n ${RESULT%%.*}` -lt 1000 ]] && break
  done
  printf "%.2f%s" "${RESULT}" ${U:-P}
}
```

普通にループで1000で割り続ける方法。
とりあえず、ペタまで対応しました。

```bash:実行結果
while read VAL; do
  echo "$VAL => `convert_unit $VAL`"
done < <(cat <<!!!
1
999
4321
7654321
1987654321
4321987654321
7654321987654321
1987654321987654321
!!!
)

# 1 => 1
# 999 => 999
# 4321 => 4.32k
# 7654321 => 7.65M
# 1987654321 => 1.98G
# 4321987654321 => 4.32T
# 7654321987654321 => 7.65P
# 1987654321987654321 => 1987.65P
```

# シェル芸的実装

と、ここまで書いてシェル芸的な実装を思いついた。

```bash
convert_unit() {
  local TMP=`mktemp -u`
  truncate -s "$1" $TMP
  ls -lh --si $TMP | awk '{print $5}'
  [[ -f $TMP ]] && rm -f $TMP
}
```

指定されたサイズのスパースファイルを作成して、lsコマンドに出力させる方法。

ちょっとトリッキーですが。

```:実行結果
1 => 1
999 => 999
4321 => 4.4k
7654321 => 7.7M
1987654321 => 2.0G
4321987654321 => 4.4T
7654321987654321 => 7.7P
1987654321987654321 => 2.0E
```

ls の場合は小数点以下を切り上げにするようなので、出力が若干異なります。

mktemp コマンドで非推奨の `-u` オプションを使用しているので、厳密にいえば名前が競合する可能性があるので、こちらはあくまでネタとしてどうぞ。
配列

#配列とは
一つの変数で複数の値を順番で管理することができるというものです。
配列は角括弧[ ]で囲い生成します。

例

```
fruits = ["apple","lemon","strawberry"]
puts fruits

# apple
  lemon
  strawberry
と出力される
```

配列に対してさまざまな処理を行う演算子を配列演算子と呼ぶ。
すでに生成した配列に追加で要素を追加したいときは　<< を使います

```
fruits = ["apple","lemon","strawberry"]
fruits << "orange"
puts fruits

# 配列の中身が["apple","lemon","strawberry","orange"]となり
  apple
  lemon
  strawberry
  orange
と出力される
```

##配列の要素を取得する場合
添字という配列の各要素に振られた番号を利用して取り出します。
添字は０から始まり順番に増えていきます。

取得したい要素に対応する添字を指定することで、要素を取得することができます。
配列の取得は、配列に続けて、角括弧[ ]で取得したい要素の添字を囲います。

```
fruits = ["apple","lemon","strawberry"]
puts fruits[1]

# lemonが出力される

以上です。
GAに送信してはいけないデータとは？

サービスを展開する上でユーザーに登録してもらったEmailアドレス、ログインIDとして使っているサービスもたくさんありますね。
そのログインIDをそのままGAにユーザーIDとして送信していないでしょうか？
今回は、Google Analyticsを利用する上で、理解しておかなければいけない個人情報の取り扱いポリシーについて書きたいと思います。利用する前に絶対に確認して念頭においておくべき点ですが、割とポリシー違反をしている場合が見受けられるので注意喚起の意味も込めて。。

# Googleの定義する個人情報
Googleの個人情報の定義は**「それ単体で個人の特定、個人への接触、個人の所在地の特定を可能にするもの」**となっています。
[Googleの契約およびポリシーにおける個人情報の扱い](https://support.google.com/analytics/answer/7686480?hl=ja)によると具体的には下記のような情報が当てはまります。
>メールアドレス
>住所
>電話番号
>高精度な位置情報（GPS 座標など。以下の注を参照）
>フルネームやユーザー名

これらの情報をGAに送信することはポリシー違反となります。個人情報はユーザーID、ユーザープロパティ、カスタムディメンションなどなどに、絶対に設定しないようにしましょう。

# 違反したらどうなるの？
単刀直入に言えば、判明した時点で垢バンされます。アカウント停止の前になんらかの警告があるかもしれませんが、センシティブな問題なので、ポリシー違反としていきなり使えなくなる可能性が高いと思います。

# 回避方法
すでに集めてしまったデータについては、[データの削除リクエスト](https://support.google.com/analytics/answer/9940393)を行うことができます。イベントパラメータやユーザープロパティに個人情報を含めてしまった場合にはこちらのリクエストを出すことで削除したいデータのみを削除することができそうです。(※未検証です)

# まとめ
GAの計測設計時に、設計者は必ずGoogleの[プライバシーとセキュリティのページ](https://support.google.com/analytics/topic/2919631?hl=ja&ref_topic=1008008)を確認し、ポリシーに沿った設計を行うようにしなければいけません。
小さな会社のサービスでは、計測設計者=開発者のところも多いかと思います。私が以前所属していた会社がそうで、特に計測設計などは行わず、とりあえずGAの導入ヘルプだけを見て設定を入れるという感じでした。
「設定できるからこれでいいじゃん！」と安易に個人情報を設定しないよう、取り扱いには気をつけたいところです。
【メモ】個人開発で使うgitフロー

個人開発で使うgitフローをメモしておきます。

##まず最初にすること

###ローカルリポジトリの作成

```
git init
```

###リモートリポジトリとの紐付け

```
git remote add origin <リモートリポジトリのURL>
```

###とりあえずプッシュしておく

```
git add .
git commit -m "first commit"
git push origin master
```

とりあえずmasterブランチでプッシュしておけば、デフォルトブランチがmasterになるから楽。gitHubで直接操作してもOKだけど、、、

##ブランチを作成＆移動

```
git checkout -b <作成するブランチ名>
```

##ステージング〜コミット
```
git add .

git commit ([-m "コミットメッセージ"] をつけてもOK。)
```

##リモートリポジトリにプッシュする

```
git push origin <ブランチ名>
```

##プルリクエスト

gitHub上でプルリクエストを行う。

##リモートの内容を取り込む

```
//mersterブランチに移動
git checkout master

//プルする
git pull origin master
```

##必要のなくなったブランチは削除

```
git branch -d <削除したいブランチ名>
```

##まとめ
まとめときます。

```
//最初にすること
git init
git remote add origin <リモートリポジトリのURL>

//それ以降
git add .
git commit
git push origin <ブランチ名（例：develop）>
プルリクエスト
git checkout master
git pull origin master
git branch -d <ブランチ名（例：develop）>
```
TimeKeeperとでも言えるものにChronosという名前をつけて、考えたこと

## 完全にポエムです

最近マイクロサービスで、少し大きめなシステムを設計しているのですが、ギリシア神話との親和性が面白いです。

そもそもは、時間を管理するモジュールの名前を、Time Keeperでは味気がないな、と、Chronosとしたところが沼のはじまりだったのですが、ピグマリオンと、オブジェクトのインスタンス生成機構とをむすびつけてみたり、とても楽しいです。

つまり、ピグマリオンが刻んだ彫刻が、アフロディーテによって生命を与えられて、ガラテアという実態ある人間となった、というストーリーが、マイクロサービスにおける「サーガ」を動的に生成するようなシステムの構成とリンクするようで、とても面白いと思うのです。

そのシステムの具体的な形については、またの機会に。
Intel Open Image DenoiserでHDR画像をデノイズしてみた

# はじめに
<!-- 発端や概要を記載 -->

[Intel Open Image Denoiseを使ってみた](https://qiita.com/ebiflyfly/items/c7d8b2fad0eeee1dc3ef)
前回、Intel Open Image Denoiseを使ってレイトレーシング画像のノイズを除去したのですが、今回はHDR画像を使ってボリュームレンダリングの画像を綺麗にできるか試してみました。


# 目次
<!-- タイトルとアンカー名を編集 -->
1. [インストール](#Chapter1)
2. [使用画像](#Chapter2)
3. [実行方法](#Chapter3)
4. [実行結果](#Chapter4)
5. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# インストール

[Intel Open Image Denoiser](https://github.com/DeclanRussell/IntelOIDenoiser)
まずはこのGitリポジトリのリリースページからWindows用ビルド済みファイルをダウンロードして解凍しておきます。


<a id="#Chapter2"></a>
# 使用画像
10サンプルほどのボリュームレンダリングした1400x850の画像を使用します。2枚目は2000サンプルほど取って綺麗になった正解の画像です。２枚ともHDR形式で保存しています。

![frame4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1014868/73aee6b4-5ec2-47a0-7b69-39c41fd6ceaa.png)

![frame6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1014868/5f440e8f-79dc-8432-132a-d10c0fe0044f.png)



<a id="#Chapter3"></a>
# 実行方法

まずは任意のフォルダにデノイズしたい画像を配置します。ここでは`image.hdr`になります。

先ほどダウンロードして解凍したフォルダにパスを通すか実行ファイルへのパスを含めた上で`Denoiser.exe`を実行します。


```
C:\Users\username\Downloads\Denoiser_v1.3\Denoiser_v1.3\Denoiser.exe -i image.hdr -o out_image.hdr
```

<a id="#Chapter4"></a>
# 実行結果

以下がデノイズ後の画像になります。その下の正解画像を比べても若干光の反射などでディテールが失われているもののほとんど大差ない気がします。

![out_frame4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1014868/f1ae93eb-fd9b-58dc-d962-6494d1b93d3f.png)

![frame6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1014868/5f440e8f-79dc-8432-132a-d10c0fe0044f.png)

デノイズの実行時間は0.5秒ほどでした。10サンプルのノイズあり画像を計算するのに2秒程度、2000サンプルしてノイズをほぼ無くすのに10分ほどかかっているので1秒以下でほぼ同じクオリティーを予測して出力できるのはびっくりです。

<a id="#reference"></a>
# 参考文献
- [Intel Open Image Denoiseを使ってみた](https://qiita.com/ebiflyfly/items/c7d8b2fad0eeee1dc3ef)
- [Intel Open Image Denoiser](https://github.com/DeclanRussell/IntelOIDenoiser)
[Rails]date_selectにBootstrapのform-controlが適用されない

#課題
Rails + Boostrap でdate_selectにform-controlが適用されない

```erb:_form.html.erb
<%= form.date_select :date, class: "form-control" %>
```
![スクリーンショット 2021-01-12 8.53.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239796/1b1a7a14-2872-b7cf-0613-c9f4b7dd9f39.png)

#結論
以下のような書き方で適用されます。

```erb:_form.html.erb
<%= form.date_select :date, {}, {class: 'form-control', style: 'display: inline-block;width: auto;'} %>
```
![スクリーンショット 2021-01-12 8.56.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239796/6229124b-14d6-b4f3-ef7a-f2c697197cac.png)

ちなみにこの style: 'display: inline-block;width: auto; をサボると想定外にダッさい表示になります。

![スクリーンショット 2021-01-12 8.58.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239796/00fc0313-8610-330c-51ff-a04968be52e6.png)

地味に初学者が躓くので再度メモしました。
技術背景も含めて以下記事が完全回答版です。
過去の先人たちに感謝いたします。

#参考情報
Rails date_selectをBootstrapを使っていい感じにする
https://qiita.com/t_oginogin/items/519fb52e1708e26a8b73
フロントエンドのコンポーネントの分け方の勉強

# Vue.jsのコンポーネント設計について勉強

単一コンポーネントの原則は理解したけどじゃあ具体的にどうコンポーネントを作ったらいいの？という問いにぶち当たった。

https://qiita.com/seya/items/8814e905693f00cdade2

こちらの記事がわかりやすかったのでこれを自分なりに要約していこうと思う。

## コンポーネントとは？

アプリの見た目を作る構成部品。

### コンポーネントを作る目的

アプリの見た目を作る上では同じような部品がくり返し使われることが多々ある(フォームの送信ボタンなど) 。このような要素を一つの部品の単位として分けて作成することで再利用性やデザインのしやすさを高めるためにコンポーネントを利用する。

### コンポーネントの構成要素

以下の4つ。今回は①について見る。

1. 情報構造
2. スタイル
3. 状態
4. インタラクション・機能

### ①情報構造

HTMLのこと。どのような単位で部品を分けるのか？ということですね。

`Atomic Design`

見た目を作るHTMLをどのような単位で分けるのか？についての最もメジャーな考え方の一つ。

![1_j1P0pjQtl36QJavv8lHdyw.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F150569%2F73ffc43a-a181-fad9-a16e-f9b894475f85.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&s=3391ef93fed658ae34eda68318a960dd)

--機能の役割--

Atoms(原子)…最小単位。それ以上分割できないボタンやテキストなど

Molecules(分子)…Atomを組み合わせて作られる要素。フォームなど

--レイアウトの役割--

Organisms(組織)…MoleculesやAtomsを組み合わせて作られる要素。ヘッダーなど。Moleculesと違い、複数の機能を担う

Template…Organismsを組み合わせたもの。いわゆるワイヤーフレーム。見た目の骨格の部分

Pages…実際の文言がTemplateに組み込まれたもの。つまり実際のページ

## 単一責任の原則

コンポーネントは一つのことに責任を持つべき。つまりコンポーネントの役割は一つにしぼりましょう、ということ。

コンポーネントの役割を一つに絞るべき理由は、ページによって再利用したりユーザーの状態に応じてページに表示する内容を変えたりする必要がある時にコンポーネント内部に条件分岐などを入れたりする必要が出てくるから。これでは開発しにくい。この考え方はAtomsやMoleculesの設計では特に重要。

じゃあOrganisms以上はどうすんのという話ですがこれは「アプリの見た目を一意に担うこと」を単一責任、とすれば考えやすそう。つまりヘッダーやフッターなどの部品がページによってデザインが変わったりしないということ。機能に対しての一意性を担っているのはあくまでAtomsやMoleculesなんですね。

## じゃあ実際どう実装していくの？
ここまで理解したところでどう実装するのかですが、以下のようにやると進めやすそう(感想)
①設計書なり仕様書をみて部品の最小単位を割り出す
②最小単位で設計した際のスタイルを考える
③②で考えたスタイルのうち親要素に持たせたほうがよいものを選び親要素に持たせる

みたいな感じ。スタイルに関しても定義の仕方にルールがあるようなのでこちらは明日以降勉強していく。
DBコネクション数枯渇してアプリ動かなくなった話

## はじめに
自分の備忘録。
レガシーアプリ（作ってから大分たつアプリ）の動作確認でトラブった話。

## 前提
既存アプリを別環境へコピーしてもう一台新規で立ち上げたい要件があった。
コピーしたはいいが、そのアプリ動くか動作確認したい。

DBサーバ配布がまだ先になりそう。

## やりたかったこと
### DBサーバ配布前に動確したい
既存アプリで使っているDBサーバ使えばよいのでは。
更新系は怖いので参照系だけなら大丈夫だろう。

```console
既存アプリ 
↓
既存DB
↑（ new ! ）
コピーしたアプリ
```
### コピーしたアプリの準備整ったのでいざ動作確認
画面は開く、画面推移もある程度大丈夫そう。
あれ、画面推移時にエラー発生したぞ。原因分析。

あれ、既存アプリでもエラー発生したぞ。まったく機能していないぞ。。。

### トラブル原因
DBコネクション数枯渇。

コネクション数上限300を超えてDB使えなくなった。
コピーしたアプリ立ち上げるだけで60確保。画面でなんか操作してると100突破。
~~どんな実装設定してんだ。。。~~

参照系であれば問題ないと油断。

## さいごに
いわれてみれば気づくが、当時は案外気づかない盲点だった。
参照系だけでコネクション数枯渇ないだろうと油断。

似たような要件あれば意識する。
【AWS】CloudTrail

・アカウントで行われたAPI呼び出しを記録し、ログファイルをS3バケットとCloudWatchLogsロググループに配信することが可能
・証跡からCloudWatchLogsにイベントを送信するように設定した場合
　→証跡設定に一致するイベントのみを送信する
Kotlin Android Extensions から View Binding に置き換える

今更ですが、Kotlin Android Extensions が非推奨になりましたね。
公式としては、View Binding を使うことが推奨されています。

- [Migrate from Kotlin synthetics to Jetpack view binding](https://developer.android.com/topic/libraries/view-binding/migration)

`./gradlew build`コマンドを実行すると、以下のような警告文が出力されます。

```
Warning: The 'kotlin-android-extensions' Gradle plugin is deprecated. Please use this migration guide (https://goo.gle/kotlin-android-extensions-deprecation) to start working with View Binding (https://developer.android.com/topic/libraries/view-binding) and the 'kotlin-parcelize' plugin.
```

# 修正方法

例えば`app/build.gradle`が以下のように記載されていたとします。

```app/build.gradle
plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-android-extensions'
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'
}

android {
    ...
    androidExtensions {
        experimental = true
    }
    buildFeatures {
        dataBinding = true
    }
}
...
```

まず、`androidExtensions`および`id 'kotlin-android-extensions'`を削除し、`buildFeatures`に`viewBinding = true`を追記します。

```app/build.gradle
plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'
}

android {
    ...
    buildFeatures {
        dataBinding = true
        viewBinding = true
    }
}
...
```

そして、ソースコード内で Kotlin Android Extensions を使用している箇所を View Binding に置き換えます。

```
// Reference to "name" TextView using synthetic properties.
name.text = viewModel.nameString

// Reference to "name" TextView using the binding class instance.
binding.name.text = viewModel.nameString
```

## Parcelable を使用している場合

ソースコード内で`@Parcelize`アノテーションを使用している場合は、`plugins`に`id 'kotlin-parcelize'`を追記します。

```app/build.gradle
plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-parcelize'
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'
}
...
```

# 参考 URL

- [Android Developers Japan Blog: Kotlin Android Extensions の未来](https://android-developers-jp.googleblog.com/2020/11/the-future-of-kotlin-android-extensions.html)
Linuxコマンド

ターミナルからPCに命令を与えるものがLinuxコマンド

【基本的なコマンド集】
-カレントディレクトリを表示 pwd
-ファイルやディレクトリの一覧を表示 ls
-カレントディレクトリを移動 cd [移動したいディレクトリのパス]
　※cd のみの場合はホームディレクトリに移動
-ルートディレクトリへ移動 cd /
　※相対パスの場合は先頭に/はいらない。
【AWS】VPC

#セキュリティグループ
・インスタンスに設定できるインバウンドトラフィックとアウトバウンドトラフィックを制御する
・ステートフルフィルタリング

◆デフォルト
インバウンド：許可せず
アウトバウンド：全て許可

#ネットワークACL
・サブネットレベルで動作し、サブネットへ出入りするトラフィックを検証する
・ステートレスフィルタリング
列指向ストレージによるデータ処理高速化

データ分析基盤の理解を深めるために、[ビッグデータを支える技術](https://amzn.to/3q6n5kY)を学習中。
今回は、データ処理を高速化するための技術についてまとめます。

# データマートに使われるおもな技術

|集計システムの種類 |ストレージの種類 |最適なレコード数 |
|:--|:--|:--|
|RDB   |行指向   |〜数千万程度   |
|MPPデータベース   |列指向(ハードウェア一体型)   |数億〜   |
|対話型クエリエンジン   |列指向(分散ストレージに保存)   |数億〜   |

以下で、行指向と列指向について、MPP（massive parallel prodessing/大規模並列処理）について説明。

# 行指向データベースと列指向データベース

|種類 |説明 |具体例|
|:--|:--|:--|
|行指向   |レコード単位の読み書きに最適化。データの追記を効率的に。インデックスでデータ検索を高速化。   |Oracle Database, MySQL |
|列指向   |カラム単位の集計に最適化。必要なカラム（例えば売上）だけ読み込むことでディスクI/Oを減らす。同じカラムには同じようなデータが並ぶから圧縮効率に優れる。   |Treradata, Amazon Redshift |

# MPPデータベースのアプローチ

クエリの遅延を減らすために、MPPのアーキテクチャでデータ処理を並列化。

多数のディスクに分散されたデータが、それぞれ異なるCPUコアによって読み込まれ、部分的なクエリの実行が行われる。それらの結果は１ヵ所に集められ、最終的な結果が出力される。このような一連の処理は可能な限り同時並列で実行される。
【AWS】SQS

#スタンダートキュー
・無制限スループット
・少なくとも一回配信（複数のメッセージが配信されることもある）
・ベストエフォート型の順序付け（メッセージが送信された時と異なる順序で配信される可能性あり）

#FIFOキュー
・高スループット
・一回だけの処理
・先入先出し配信（メッセージが送信また受信された順序で配信）

#メモ
・メッセージの少なくとの1回の配信で耐久性を提供しDynamoDBへの書き込みをバッファリングできる


・FIFOキューの一度だけ配信はSQSのみの機能
ローカルに保存されている画像データをZIPダウンロードしたいとき

# 解決したいこと

ローカルに保存されている、main.jpg、top_map_off.jpgをzipダウンロードしたい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586262/1737fd2c-ac1f-85d6-a94f-51775ca81918.png)

# 解決策

画像はバイナリモードでしか書き出せないので、openするときにバイナリモードを指定する。

```ruby
Zip::OutputStream.open('example.zip') do |zip|
  default_images = ["main", "top_map_off"]
  default_images.each do |default_image|
    img_path = Rails.root.join(
      "app", "lib",  "output", "download_tpl", @kikaku_date.kikaku_cd, "#{target}", "images", "#{default_image}.jpg 
    ) # ローカルに保存されている画像ファイルのフルパス
    zip.put_next_entry "#{@zip_file_basename}/#{target}/images/#{default_image}.jpg"
    zip.print open(img_path, "rb").read  # 画像をバイナリモードで開く
  end
end
```

[Rubyでバイナリデータを標準出力に出力する](http://tinqwill.blog59.fc2.com/blog-entry-98.html?sp)
【Shell】文字列分解の様々なパターン

## はじめに
- 用途は少ないが、文字列を1文字ずつ分解して処理する場合がある。
- その際に、各環境で利用できるオプションや日本語問題に対応する必要がある。
- 今回は、文字列分解コマンドの複数パターン紹介と無難パターンを記録する。

## 環境
- Mac OS X 10.15.6
- ZSH 5.7.1

## 結果
- 以下、結果の内容。

```bash
# パターン1 : foldとgrep(v)の利用
# ※全角の場合は、空行が入るためgrepで削除。
echo "Good" | fold -1 | grep -v '^$'

# パターン2 : sedとtrの利用
# ※最終行が追加されるので、最後のsedで削除
echo "Good" | sed 's!.!& !g' | tr ' ' '\n' | sed '$d'

# パターン3 : sedとxargsの利用(無難)
echo "Good" | sed 's/./& /g' | xargs -n1

# パターン4 : grep(o)の利用
# ※grepのoオプションは、環境によって利用できない。(POSIX未対応のため)
echo "Good" | grep -o .
```

```bash
# 各パターンの出力結果
G
o
o
d
```

## 内容

### パターン1
- 主に以下のような処理。
    - [fold](https://www.ibm.com/support/knowledgecenter/ja/ssw_aix_72/f_commands/fold.html)を利用して、出力幅を1文字に限定。
    - grepのvオプションを利用して、不要な空行を削除。
        - **※半角のみであれば、foldのみで問題ない。**

### パターン2
- 主に以下のような処理。
    - sedで一文字ずつ後ろにスペースを追加。
    - trで追加された改行へ置換。
    - sedで最後に追加された不要な改行を削除

### パターン3
- 主に以下のような処理。
    - sedで一文字ずつ後ろにスペースを追加。
    - [xargs](https://www.ibm.com/support/knowledgecenter/ja/ssw_aix_72/x_commands/xargs.html)のnオプションを利用して、入力引数の最大値指定。


### パターン4
- 主に以下のような処理。
    - grepのoオプションを利用して、1文字ずつマッチする毎に出力。
    - **※oオプションは、環境によって利用できない場合がある。自身の環境は可能。**

## まとめ
- 上記のことから、環境および全角対応等の点から**パターン3のsedとxargsの利用**を無難とする。
- ただ、短述的で不要処理の無さという点から、**パターン4**の利用も検討する。

## 参考
- https://www.ibm.com/support/knowledgecenter/ja/ssw_aix_72/f_commands/fold.html
- https://www.ibm.com/support/knowledgecenter/ja/ssw_aix_72/x_commands/xargs.html
- https://it-ojisan.tokyo/grep-o/
条件分岐JavaScript

JavaScriptで使える条件分岐についてまとめてみました。
条件分岐とは、記述した条件式がTrue/Falseによって判断され、その後の実行結果が変化することです。
以下に、それぞれの条件分岐にいついて説明します。
##項目
・if文
・？で条件分岐
・switch
・for
以上の４点です。

###if文

```main.js
if(条件式){
 条件式がTrueの処理
}else if(条件式){
 条件式がTrueの処理
}else{
 条件式がFalseの処理
};
```

ifの条件式がTrueならifの中身の処理を実行
ifの条件式がFalseでelse ifの条件式がTrueならelse ifの中身の処理を実行
どの条件にも当てはまらない場合、elseの処理を実行

###?で条件分岐

```main.js
条件式 ? Trueの処理:Falseの処理;
```

条件式を記述し、Trueの処理とFalseの処理を記述
それぞれの処理の文の長さが短いときに使いやすい。

###switch

```main.js
switch(定数などの比較される式){
 case 条件式１:
 条件式１に該当する処理;
 break;

 case 条件式2:
 条件式2に該当する処理;
 break;

 case 条件式3:
 条件式3に該当する処理;
 break;

 default:
 どの条件にも当てはまらない場合の処理;
};
```

switch~case~breakによって条件式に合った処理を実行していく。
条件式が多い場合はこの書き方を使用するとすっきりする。

###for

```main.js
for(定数などの比較される式;条件式;実行された後の処理){
 条件式がTrueの間の処理
}
```

forは繰り返し処理を行う。上記だと分かりにくいので具体例を以下に示す。

```main.js
for(let i=0;i<10;i++){
 console.log(i);
};
```
for(変数を定義;条件がTrueの時の処理;変数に１づつ足していく)
この場合だとiが10未満の時に値が出力される。

###参考文献
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for

https://www.pu-kumamoto.ac.jp/~matsuno/zemi2/JavaScript/JSBranch.html
Unityで対話型音声認識アプリを作れるフレームワークをつくった


__macOS, Windows両方で動く、Unityで対話型の音声認識アプリがすぐに作れるフレームワークを作りました。__

リポジトリへのリンク：https://github.com/HassoPlattnerInstituteHCI/SpeechIOForUnity
Unity Package: https://github.com/HassoPlattnerInstituteHCI/SpeechIOForUnity/releases/tag/v1.0

## つかいかた

__`SpeechOut/SpeechIn`を宣言し、以下のように書くだけ。__

```cs

SpeechOut speechOut = new SpeechOut();
SpeechIn  speechIn  = new SpeechIn(OnRecognized);

void Start(){
    Dialog();
}

async void Dialog(){
    await speechOut.Speak("Hello!");
    await speechIn.Listen(new string[] { "Hello", "Hi", "Hey" });
    await speechOut.Speak("How are you doing?");
    await speechIn.Listen(new string[] { "I'm fine", "Nah", "I'm Sick" });
    //...
}
```

## なぜつくったか

macOS, Windowsを使う学生のために、Unityを扱う授業で音声認識を使った対話型アプリを作るためのフレームワークがあればいいなと思ったので作りました。
主に非同期処理の`async/await`ベースで、逐次処理をわかりやすく書けるように、また速度や”間”などのチューニングも簡単にできるようにしました。

授業ではmac, Windowsそれぞれを使う学生を同様に対応しないといけないのですが、Unityそのものは双方で動作する一方、ネイティブOSの機能を使おうとすると相互にコードを共有できない＝他のチームやグループが作ったアプリを動作させられないことになるので、このようなコードを作りました。

授業のためとはいえ、一般的に使いやすいツールだと思います。

## OSネイティブの音声認識・音声合成

### macOS側
macOSネイティブのオフライン音声認識ツールとしては、`NSSpeechRecognizer`が、音声合成ツールとしては、コマンドラインツールとして`say`があります。このうち、`say`に関してはUnity上の`System.Diagnostics.Process`から呼び出すことで実行できます（この点、Argsをいじるだけで声質とか速度を変えられるのでサイコー）

一方の`NSSpeechRecognizer`はOSネイティブAPIとして提供されている機能なので、実行するためには`Objective-C`もしくは`Swift`で記述されたコードから実行する必要があります。

今回のフレームワークでは別途[NSSpeechForUnity](https://github.com/HassoPlattnerInstituteHCI/SpeechIOForUnity/tree/master/NSSpeechForUnity)として、`NSSpeechRecognizer`を呼び出す`Objective-C`コードを書き、外部ライブラリとして`.bundle`ファイルを書き出し、それをUnityのPluginとすることで実行しています。


### Windows側

逆にWindows側では`UnityEngine.Windows.Speech`なるモジュールがあり、音声認識に関してはUnityから直接実行できる一方、音声合成に関しては別途WindowsのネイティブAPI＝[SAPI](https://ja.wikipedia.org/wiki/Speech_Application_Programming_Interface)を叩く必要がありました。コード内で別途[WindowsVoiceProject](https://github.com/HassoPlattnerInstituteHCI/SpeechIOForUnity/tree/master/WindowsVoiceProject)として、Visual Studioから.dllをビルドできるプロジェクトを作り、その.dllをUnityのPluginにします。

---

以上２つのOSに関して独自にライブラリを書き出すことによって実現しましたが、Unity上で非同期の動作を実現させるため、それぞれの処理がきちんと終わったかどうかを常に監視するためのコードを書く必要があります。たとえば[このように](https://github.com/HassoPlattnerInstituteHCI/SpeechIOForUnity/blob/0ac6cfe8b468f970524b6dc558d0656bf501322c/NSSpeechForUnity/NSSpeechForUnity/native.m#L75)、内部のStateを逐一変えて、Unity側から監視することで、UnityのAsync/Awaitが進行するように若干HardCodedな感じではありますが、リアルタイムアプリケーションのための非同期処理を実現しています。

---



## 応用
対話型アプリケーションのためとは言いましたが、VRアプリケーションなどのための目と手が離せない際のデバッグ（イベントが起こったときにどのフラグが立ったか喋って教えてくれる）や、視覚障害者向けアプリなど、様々な用途が考えられます。「デバッグのときになにか喋ってくれたら便利だな」とか、「アクセシビリティ機能の充実したアプリを作りたいな」などというときにはぜひ使ってみてください。
PyMC3 の使い方 (ベイズ推論)

久しぶりに使おうとすると忘れるのでメモしておきます。

## PyMC3 とは？

- Python で使える確率的プログラミングのライブラリ
- ベイズ推論に利用できる


## インストール

```
pip install pymc3
```

## 基本的な書き方

```python

import numpy as np
from matplotlib import pyplot as plt

# 試行回数と観測結果(回数)
N = 100
a = 5

with pm.Model() as model:
  # 事前分布
  #  範囲が 0 〜 1 の一様分布とする
  theta = pm.Uniform('theta', lower=0, upper=1)

  # 尤度関数
  #   ベルヌーイ試行を N 回行った時の観測回数 a が従う分布として二項分布を設定する
  obs = pm.Binomial('a', p=theta, n=N, observed=a)

  # 推論を実行し、事後分布から 5000*2 サンプルを得る
  trace = pm.sample(5000, chains=2)
```

- `pm.sample` では MCMC でサンプルを得て `trace` に結果が格納されている

## サンプル(事後分布)の可視化

```python
with model:
  pm.traceplot(trace)
```

<img width="1000" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20642/d25e15b3-0fe2-245d-90b2-a85fa139ffd9.png">



- 左側の図には対象の確率変数について推定された事後分布が表示される
- 右側にはバーンイン(burn-in)以降に得られたサンプルの軌跡が表示される
    - バーンイン(burn-in): 探索の初期値の影響を取り除くためにサンプルを捨ててしまう期間のこと

## 要約統計量の表示

```python
with model:
  # HDI(highest density interval) として 95% HDI を設定
  print(pm.summary(trace, hdi_prob=0.95)
```

<img width="700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20642/1fcd8f7f-3b4c-ff6c-9fda-db8a92a08181.png">




## 要約統計量を付きでサンプル(事後分布)を可視化

```python
with model:
  pm.plot_posterior(trace, hdi_prob=0.95)
```
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20642/584b4040-a5d1-6f8a-fd5c-06c146100bbd.png">


## 参考資料

- [PyMC3 Documentation](https://docs.pymc.io/index.html)
C++のリングバッファ（FIFO）

C++でのリングバッファ（FIFO）のメモ書きです。
わかりやすい例が見当たらなかったので書いてみました。

ポイントは、データの個数のみをif文でチェックして、frontやrearの位置はチェックしないことです。

frontやrearの位置をチェックしようとすると、データが０のときとデータが満杯のとき、両方ともforntとrearの位置が同じになるので、これを判別するのには別の要素が必要となり、冗長なプログラムになります。

ここ１０年くらいほとんどプログラムを組んでないので、何かありましたらお手柔らかにお願いします。

```c++
#include <iostream>
#include <string.h>
using namespace std;

#define SIZE 3
class FIFOBuf {
  private:
    char array[SIZE][4];
    int rear = 0, front = 0, data_num = 0;

  public:
    int push(char *data)
    {
      if (data_num == SIZE) //full
        return false;

      data_num++;
      memcpy(array[rear], data, 4);
      rear = (rear + 1) % SIZE;

      return true;
    }

    int pop(char *data)
    {
      if (data_num == 0) //empty
        return false;

      data_num--;
      memcpy(data, array[front], 4);
      front = (front + 1) % SIZE;

      return true;
    }
};
```

以下テストプログラムです。

```c++
int main() {
    
    FIFOBuf buf;
    char data[4];
    
    std::cout << buf.push("123") << std::endl;
    std::cout << buf.push("456") << std::endl;
    std::cout << buf.push("789") << std::endl;
    std::cout << buf.push("abc") << std::endl;

    std::cout << buf.pop(data) << ", " << data << std::endl;
    std::cout << buf.pop(data) << ", " << data << std::endl;
    std::cout << buf.pop(data) << ", " << data << std::endl;
    std::cout << buf.pop(data) << ", " << data << std::endl;
}
```

実行結果

```
1
1
1
0
1, 123
1, 456
1, 789
0, 789
```

実行環境
https://www.codechef.com/ide
C++14(Gcc 6.3)にて確認しました。

------------------
21/01/13 追記:
@kazatsuyuさんからのご指摘で、
rear は常に (front + data_num) % SIZEなので不要ではないか、とのこと。その通りなので、それに従ってプログラムを変更してみます。

```C++
#define SIZE 3
class FIFOBuf {
  private:
    char array[SIZE][4];
    int front = 0, data_num = 0;

  public:
    int push(char *data)
    {
      if (data_num == SIZE) //full
        return false;

      memcpy(array[(front + data_num) % SIZE], data, 4);
      data_num++;

      return true;
    }

    int pop(char *data)
    {
      if (data_num == 0) //empty
        return false;

      memcpy(data, array[front], 4);
      data_num--;
      front = (front + 1) % SIZE;

      return true;
    }
};
```

こちらのほうが視覚的にもわかりやすくなっていると感じます。data_numのインクリメント、デクリメントの位置をmemcpyの後に変更してますが、副作用とかあるので、最初からmemcpyの後に置いたほうがよかったです。
正直、自分では気が付きませんでした。こういうご指摘は大変有り難いです。