OmniAICreator/Qiita-1.07M huggingface dataset:
CohesityAPIでProtectionJobのバックアップ取得方法

# 概要
- [cohesityとは](https://www.cohesity.com/jp/)
- クラウド、オンプレにあるVMなどに対しバックアップ取得できるストレージ製品
- Protection>job>object(VMなど)というデータ構造になっている

# 要件
- Cohesityが提供しているRESTを使用しProtectionjobのバックアップを取得

## 補足
- [公式ドキュメント](https://helios.cohesity.com/docs/restApiDocs/browse/)
- [サードパーティ製ライブラリを使用](https://github.com/cohesity/management-sdk-python)

# 実装方法(REST)
1. `GET /public/accessTokens`を使用しaccessToken払い出し(以降手順ではヘッダーにaccessTokenを利用)
2. `GET /public/search/protectionSources?searchString={VM名}` sourceIDを取得
3. `GET /public/restore/objects?search={job名}` jobIdを取得
4. `GET /public/protectionJobs/{jobId}` jobに関するobjectを取得
5. `PUT /public/protectionJobs/{jobId}` bodyにobjectを使用、その中のsourceIdsにsourceIDを追加(リスト構造)
(ex.) sourceIds: [100, 150] → sourceIds: [100, 150, 190]

# 実装方法(management-sdk-python)
RESTで実現する手順を理解してやれば同様のことをこのライブラリで実現可能。
HeaderやTokenなどはいい感じに巻き取ってくれているためこのライブラリを使用するならば不要
bodyの構造はもう少し複雑だが省略
注意点として帰ってきたjsonをprintし中身を表記させたkeyにアクセスしようとするとアトリビュートエラーが出ることがある。
sourceIdsというkeyではなくsource_idsでアクセス可能な場合あり、全体的にキャメルと見せかけて実はスネークだったパターンが何個かある。
ログイン情報は各環境に応じて任意の値にする
cluster_vipはcohesityのip、domainはLOCALで入れた(地味にハマった)

```add_vm.py
from cohesity_management_sdk.api_helper import APIHelper
from cohesity_management_sdk import cohesity_client

cohesity_client = CohesityClient(cluster_vip=CLUSTER_VIP,
                                 username=CLUSTER_USERNAME, 
                                 password=CLUSTER_PASSWORD,
                                 domain=DOMAIN)

# 1 sourceid取得
source_id = cohesity_client.search.search_protection_sources(search_string=VM名)

#  objectで帰ってくるためAPIHelperを使用しrawに変換 
# 中身はstring 後の手順でエラーを回避するためintに変換しておく
source_id = int(APIHelper.json_serialize(source_id))

# 2 jobidを取得
jobid = cohesity_client.search.search_protection_sources(search_string=job名)

jobid = APIHelper.json_serialize(jobid)

# 3 jobidを使用しobject(body)を取得
body = cohesity_client.protection_jobs.get_protection_jobs(ids=jobid)

# 4リストの加工
body[0].source_ids.append(source_id)


# 対象jobにVMなどを追加
cohesity_client.protection_jobs.update_protection_jobs(body=body[0], id=jobid)

```

# 所感
やってみた系の技術ブログが皆無だったため公式リファレンスとライブラリのREADMEやソースの中身をにらめっこし突破。
大企業ではない製品やそれに付随するライブラリは手軽に解説してるとこがほぼ無く0からの調査、実践が頻繁に発生するため実力がつく。
落ち着いてライブラリの中身を読み込めばどこで何をしてるか理解できるが工数と要相談。
後学のためここに記す、説明は相当雑だが同じ苦しみを味わっている人の一助になればいいと思っている。
行レベルセキュリティ&共有設定

#目次
[共有設定](#共有設定)
[セキュリティ述語を使用した行レベルセキュリティ](#セキュリティ述語を使用した行レベルセキュリティ)
[データセットの述語式の構文](#データセットの述語式の構文)
[アプリケーションレベルの共有](#アプリケーションレベルの共有)
#共有設定

salesforceの共有設定を引き継ぐことができる。パフォーマンスは落ちるらしいが。

設定→分析→設定
Salesforceから共有を継承をチェックする
![スクリーンショット 2021-03-04 10.19.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385774/676d2c89-8a03-3686-38ed-f644bc8a4a4b.png)


### 全てのオブジェクトがサポートされているわけでなく主要な標準オブジェクトのみ
共有設定は 1 つのオブジェクトからのみ継承できます。共有継承でサポートされるオブジェクトは次のとおりです。

- 取引先
- ケース
- 取引先責任者
- リード
- 商談

![スクリーンショット 2021-03-04 10.36.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385774/30352223-3a71-69ba-4b11-972277fb7ad8.png)


###共有とセキュリティ述語のベストプラクティス

- 継承された共有を使用して、データセットのセキュリティ述語を定義することをお勧めします。セキュリティ述語がないと、継承の共有の対象とならないユーザーには、データセットの行レベルのアクセス権がないため、データセット内のデータは表示されません。
- 共有はデータセットに自動的に適用されません。各データセットに手動で共有を適用します。
- 継承の共有は、クエリ、データフロー、およびデータ準備レシピのパフォーマンスに影響を与える可能性があります。要件に可能な限り最高のパフォーマンスが含まれている場合は、継承を共有する代わりにセキュリティ述語を使用してください。そうでない場合は、継承を共有する便利さをお楽しみください。
- データフローのrowLevelSharingSourceまたはrowLevelSecurityFilterセキュリティ設定への変更は、変更を保存した後に作成されたデータセットにのみ影響します。同様に、データ準備レシピ出力ノードの共有ソースフィールドとセキュリティ述語フィールドへの変更は、変更を保存した後に作成されたデータセットにのみ影響します。データセットの編集ページで、既存のデータセットの設定を更新します。
- オブジェクトをセキュリティ共有ソースリストに表示するには、カスタムオブジェクトの主キーがデータセットのフィールドである必要があります。外部キーはこの要件を満たしていません。たとえば、データセットにOpportunity.AccountIdがあり、Account.Idがない場合、Accountオブジェクトから共有を継承することはできません。
- 継承の共有では、Salesforce組織の共有設定が使用されます。不完全なSalesforce組織共有設定をTableauCRMに適用したくない場合は、共有継承を使用しないでください。
継承の共有は、Data PrepClassicレシピでは使用できません。

###共有ってそもそも何を指しているのか？

- レコードを所有する
- 役割階層
- 共有ルール
- 手動共有
- Apexマネージドシェアリング





# セキュリティ述語を使用した行レベルセキュリティ

- レコード所有権に基づく行レベルセキュリティの例

レコード所有者名とログインユーザ名を比較

```
'AccountOwner' == "$User.Name"
```

- 商談チームに基づく行レベルセキュリティ

データセットの UserId 列を、データセットに対してクエリを実行しているユーザの ID と比較

```
'UserId' == "$User.Id"
```

- ロール階層とレコード所有権に基づく行レベルセキュリティの例

クエリを送信するユーザが Salesforce ロール階層では商談所有者の親である。
ユーザが商談所有者である。

```
'ParentRoleIDs' == "$User.UserRoleId" || 'OwnerId' == "$User.Id"
```

# データセットの述語式の構文

-  式では大文字と小文字を区別します。
- 式は 5,000 文字以下にする必要があります。
- データセット列と演算子の間、演算子と値の間、および論理演算子の前後には 1 文字以上の空白が必要です

```
(‘Expected_Revenue’ > 4000 || ‘Stage Name’ == "Closed Won") && ‘isDeleted’ != "False"
```

# アプリケーションレベルの共有

共有したいダッシュボードだけでなく、データセットもセットに
![スクリーンショット 2021-03-04 11.11.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385774/e6053dd9-10d6-7eda-4951-110d452e72b7.png)


#参考文献

[行へのアクセス権を制御するデータセットセキュリテの設定](https://help.salesforce.com/articleView?id=sf.bi_security_datasets_row_level.htm&type=5)

[アプリケーションレベルの共有](https://help.salesforce.com/articleView?id=sf.bi_app_sharing.htm&type=5)

[ドキュメント](https://resources.docs.salesforce.com/230/latest/ja-jp/sfdc/pdf/bi_admin_guide_security.pdf)
HTML / CSS 覚書 Vol.1 インライン 画像 縦横中央寄せ

##1...ついつい忘れがちなインライン要素たち
###特徴
* `width`(横幅)と`height`(高さ)の指定ができず、内包する要素次第。（`margin: o auto;`で中央寄せ不可）
* 改行できない。（横に並ぶ。）
* `margin`は、上下には効くが左右には効かない。
* `padding`は上下左右に効くが他の要素を無視して被さる。

###メンバー
* `<a></a>`
* `<br>`
* `<img>`と`<img/>`
* `<input>`と`<input/>`
* `<label></label>`
* `<textarea></textarea>`
* `<span></span>`
* `<small></small>`
* `<strong></strong>`

###付き合い方
* `display`で`inline`指定、又は`inline-block`指定する。
* `<img>`はブロック要素の「背景画像」で指定する。

##2...画像話あれやこれや
###画像の形式と適正
* JPEG ： 写真
* PNG : イラスト、ロゴ、画像文字。透明色の利用。
* GIF ： 極めて短時間のアニメーションを作れるが、今はあまり使われない。
* SVG ： 拡大しても劣化しないベクター形式。AdobeのIllustlatorがこの形式。（ちなみにPhotoshopはBMP：ビットマップ形式）

##3... 横中央寄せ
###①`text-align: center;`
```:css
.inline {
   text-align: center;
}
```
インライン要素の中の要素の横中央寄せ。
中央寄せにしたい要素そのものでなく**親要素に指定**する。
中の要素がテキストの場合も、あくまで中央にくるのは中のテキスト。**（テキストはタグで囲まれていないけどインライン要素。）**
省略記法：`tac`=>`text-align: center;`
###②`margin: 0 auto;`
```:CSS
.block {
   width: 80%;
   max-width: 1000px;
   margin: 0 auto;
}
```
ブロック要素そのものの横中央寄せ。
widthの指定必須。（そうでないとブロック要素は横幅いっぱいに広がるので中央寄せに見えない。）
省略記法：`m0-a`=>`margin: 0 auto;`

①②をまとめるとこんな感じ。
![HTML _ CSS (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/88e458d1-12bd-83dd-6323-11268b5ac06f.png)

###③`display: inline-block;`
```:CSS
.inline-block {
  display: inline-block;
}
```
インライン要素の横幅を指定せず横中央寄せ。
省略記法：`dib`=>`display: inline-block;`
##4...縦中央寄せ
###①`height`と`line-height`を揃える
```:CSS
.sample {
   height: 60px;
   line-height: 60px
}
```
ボタンのデザインなどによく使われる。
テキストが複数行になると使えない。
省略記法：`h60`=>`height: 60px;`  `lh60`=>`line-height: 60px;`
###②上下の`padding`の数字を揃える
```:CSS
.sample2 {
   padding: 10px 0;
}
```
複数行のテキストでも対応可。
①②をまとめるとこんな感じ。
![HTML _ CSS (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/f99f3182-0e3e-167f-f373-3ef78f7d1ba6.png)
###③複数のインライン要素の縦中央寄せ
```:CSS
.sample {
   vertical-align: center;
}
```
縦中央寄せにしたいインライン要素全てに指定する。
ブロック要素には効かない。
省略記法：`vam`=>`vertical-align: middle;`
こんな感じ。
![HTML _ CSS (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/452fd0a1-243c-814d-9fd4-d624461a6670.png)
##5...ブロック要素の縦横中央寄せ
###①`position: absolute;`＋`transform: translateXY`
```:CSS
.sample {
   position: absolute;
   top: 50%;
   left: 50%;
   transform: translate -50% -50%;
}
```
省略記法：
`poa`=>`position: absolute;`
`t50%`=>`top: 50%;`
`l50%`=>`left: 50%`
`trft`=>`transform: translate( x y )`「x」「y」それぞれに「-50%」を入力
こんな感じ。
![HTML _ CSS (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/9f97ac22-dd63-ac45-21b0-435832ab1a03.png)
position: absolute;で要素の左上が画面中央になるので、それをtransform: translate(xy);で要素そのものの縦横50％分戻す。
###②`display: flex;`
```:CSS
.sample {
   display: flex;
   align-items: center;
   justify-content: center;
}
```
省略記法：
`df`=>`display: flex;`
`aic`=>`align-items: center;`
`jcc`=>`justify-content: center;
こんな感じ
![HTML _ CSS (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/81839f22-015f-92f8-84b3-a6425527f64d.png)
起動できないgitlabからのデータ移行

作業メモです。

下記を参考にしました。
ありがとうございます。

mdns:
https://qiita.com/m-tmatma/items/7668afea91aff4fbfa85

gitlab:
https://qiita.com/win-chanma/items/37680a4384be77f2a9e2
https://sites.google.com/site/lifeslash7830/home/git/gitlabnodetawobiesabaniyixingbakkuappunashi


##mdnsのインストール
ローカルでしか使わないので、まず、mdnsを入れています。

```
$ sudo su
# apt install -y avahi-daemon
# systemctl start avahi-daemon
# systemctl enable avahi-daemon
# apt install -y firewalld
# firewall-cmd --add-service=mdns  --permanent
# firewall-cmd --reload
```

hostnameを、``ubuntu`` にしていたので、

```
$ ping ubuntu.local
```

で動作確認しました。



##新しいサーバにgitlabをインストール

https://www.gitlab.jp/install/
を参考に、インストールしました。

自分はubuntuだったので、ubuntuのボタンを押して、この通りに、インストール。

``EXTERNAL_URL=``のところは、ローカルなのでhttpでいいとして、``ubuntu.local``にしました。

```
EXTERNAL_URL="http://ubuntu.local" apt-get install gitlab-ee
```

###firewall確認
httpを開けてなかったので開けました。

```
# firewall-cmd --permanent --add-service=http
# forewall-cmd --reload
```

###gitlab動作確認

``http://ubuntu.local/``

rootユーザのパスワード設定とかしてます。


##昔のデータをコピー

コピー元のマシンのHDDを、``/old``にマウントしてるとします（記載は省略）。

すると、コピー元のリポジトリフォルダが、``/old/var/opt/gitlab/git-data/repositories`` にあることになります。

```
# cp -R /old/var/opt/gitlab/git-data/repositories/* /var/opt/gitlab/git-data/repositories-import/
# cp -R /old/etc/gitlab /etc/gitlab
```

##リポジトリの登録
下記を参考にしました。

https://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/doc/raketasks/import.md


```
# gitlab-rake gitlab:import:repos['/var/opt/gitlab/git-data/repositories-import']
```

##完成
改めて、``http://ubuntu.local/``にログインすると、昔のリポジトリが見れました！

おしまい。
TableauCRM_メモ_MENU画面

#TableauCRM

#2021年3月以降〜
関する内容でメモがわりに記述する

#目次

[行レベルセキュリティ＆ 共有設定](https://qiita.com/yujiro7029/private/f46035b82d63b06f3fbf)
[ウィンドウ関数](https://qiita.com/yujiro7029/items/92565102753c8b3268b0)
[データの同期について](https://qiita.com/yujiro7029/items/99d1e34fe1d29319f470)
[メタデータAPI](https://qiita.com/yujiro7029/items/7b04fd4dec76ce707b3f)
[データフロー](https://qiita.com/yujiro7029/items/e1e243667c197cd9fdb5)
[モバイル](https://qiita.com/yujiro7029/items/62e752e3745ba7f6b430)
[設計原則](https://qiita.com/yujiro7029/items/bbe4e08ba3d49674d0a7)
[カスタム地図の作成](https://qiita.com/yujiro7029/items/6b509cf2e43406353b3a)
[ダッシュボードのパフォーマンス改善](https://qiita.com/yujiro7029/items/40ff6d62069b52369510)
[グラフによるデータの視覚化](https://qiita.com/yujiro7029/items/c807cf97432bfeb27743)
[権限セットとライセンス](https://qiita.com/yujiro7029/items/c52c5fc3058442afd41c)
[インタラクション](https://qiita.com/yujiro7029/items/7057e8959cdc016adfda)
[データセットの暗号化](https://qiita.com/yujiro7029/items/f62eabc8abe2d4d53bfd)
[外部コネクタ](https://qiita.com/yujiro7029/items/10825281873e7865f7f2)
[]()
[]()
[]()
[]()
Laravel クエリビルダで実行しているSQLを取得する

 # 目的

- Laravelのクエリビルダで実行しているSQLを取得する方法をまとめる

# 環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.8 | Homebrewを用いてこちらの方法で導入→[Mac HomebrewでPHPをインストールする](https://qiita.com/miriwo/items/cd54077aad7e139cf518) |
| Laravel バージョン | 6.X | commposerを用いてこちらの方法で導入→[Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08) |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでMySQLをインストールする](https://qiita.com/miriwo/items/ef6a064bc545fbea29d9) |

# 情報

- 筆者はMacのローカルにて本記事に記載されている内容を実装し確認する。

# 方法

1. 下記のようなクエリビルダの記載が任意のメソッド内にあったとする。

    ```php
    $saveInfo = $this->content;
    $saveInfo['user_id'] = $saveData['userId'];
    $saveInfo['content'] = $saveData['content'];
    $saveInfo->save();
    ```

1. 下記のようにすることで変数`$sql`に実行直前で実行されたSQL文が格納される。

    ```php
    $saveInfo = $this->content;
    $saveInfo['user_id'] = $saveData['userId'];
    $saveInfo['content'] = $saveData['content'];
    $saveInfo->save();
    $sql = $saveInfo->toSql();
    ```

1. 下記のように記載することでSQL文をログに出力する事ができる。

    ```php
    use Illuminate\Support\Facades\Log;

    $saveInfo = $this->content;
    $saveInfo['user_id'] = $saveData['userId'];
    $saveInfo['content'] = $saveData['content'];
    $saveInfo->save();
    $sql = $saveInfo->toSql();

    Log::info($sql);
    ```

1. 実際のメソッド内部に処理を記載したものを下記に記載する。筆者はRepositoryにDBアクセス処理を記載している。

    ```アプリ名ディレクトリ/Repositories/ContntRepository.php
    <?php
    
    namespace App\Repositories;
    
    use App\Repositories\ContentRepositoryInterface;
    use App\Models\Content;
    use Illuminate\Support\Facades\Log;
    
    class ContentRepository implements ContentRepositoryInterface
    {
        /**
         * @var Content
         */
        private $content;
    
        public function __construct(Content $content)
        {
          $this->content = $content;  
        }
    
        /**
         * 全ての投稿内容を取得する
         *
         * @return Content|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|null
         */
        public function getContentAll()
        {
            return $this->content->all();
        }
    
        public function saveContent($saveData)
        {
            $saveInfo = $this->content;
            $saveInfo['user_id'] = $saveData['userId'];
            $saveInfo['content'] = $saveData['content'];
            $saveInfo->save();
            $sql = $saveInfo->toSql();
            Log::info($sql);
    
            return true;   
        }
    }
    ```
Pythonの%sが何か分からなくて調べてみた話

％って書き方を見かけて、初見じゃ解読できずちょっと調べてみましたので、備忘録をつけていきます。


```python
>>> # 参考例
>>> print 'My name is %s %s.' % ('python', 'qiita')
My name is python qiita.
```

こんな感じ。

で、どうやら、文字列の置き換え
って言うらしい

上の例なら、
 `My name is %s %s`
この、`％`に当たる部分を置き換えることが出来る

置き換え方は後半に書いてある、
`% ('python', 'qiita')`
この部分。

％の後に、カンマ区切りで前者と後者を書いていく。
`print 'My name is %s %s.' % ('python', 'qiita')`

この場合の出力結果は、
`My name is python qiita.`

正直、可読性低いなって思います…

普通に文字列でかけば良くないか？
どうしても置き換えたいなら、変数に入れてくれた方がいい気がするんですけどね…
ってのが私の意見です。

そう思ってもう少し調査。

[Pythonの文字列フォーマット（formatメソッドの使い方） | ガンマソフト株式会社](https://gammasoft.jp/blog/python-string-format/)
こちらの記事によると、Python３ではformatメソッドを使った書き方が一般的らしいですね。

```python
# 参考例
from datetime import datetime

# 今日の日付（例：20210303）
today = datetime.now().strftime("%Y%m%d")

# formatメソッドを使用
file_１ = "file_{}.txt".format(today)

# 出力結果
#file_20210303.txt
```

こっちの方が `%`を使った置き換えより可読性高いかな？って印象です。

置き換え部分が`｛｝`ってなってるから直感的でわかりやすいです。

## format()メソッドの使い方

```python
line = "{0}さんの身長は{1}cm、体重は{2}kgです。".format("みっつ", 170, 65)
print(line)

# 実行結果
# みっつさんの身長は１７０cm、体重は６５kgです。
```

こんな感じで書くらしいです。
うむ、見やすい…（気がします）

置き換え部分はインデックス対応らしいので、インデックスを使い回すって書き方もできそうですね！
## 所感
Pythonは色んな記法があるから面白いですよね。
調べるたびに新しい発見あります。

３D界隈(Mayaメイン)の私からすると、MELと違って、OSにアクセス出来るってのがステキですね。
エクスプローラー経由で色々できるから、データの保持とかに重宝してます。

あと、配列操作も強い。
MELじゃできないことがPythonならできちゃう。

そこがおもしろいから研究しがいがありますよね。
これからの備忘録はQiitaにつけていこうかしら？

以上
Arduino UNO アンド OLED096UNO-A(OLED) アンド DS1307(リアルタイムクロック) の 時計


stm32g031,stm32l010用に最軽量化したもの

x時間合わせは、別

1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり

```c++

#include <Arduino.h>
#include <U8x8lib.h>
#include <Wire.h> //I2C library

//STM32G031J6M6
//#define sdaPinOLED PB7
//#define sclPinOLED PA0

//UNO
#define sdaPinOLED A0
#define sclPinOLED A1

U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ sdaPinOLED, /* data=*/ sclPinOLED, /* reset=*/ U8X8_PIN_NONE);   // OLEDs without Reset of the Display


//STM32G031J6M6
//#define sdaPin PA12    // ArduinoA4
//#define sclPin PA11    // ArduinoA5

#define ADDR    0x68  // 2進数 1101000

int     ii;           //ループカウンター
int     jj;           //ループカウンター
int     cursor1;      //カーソルの位置
char    data_read[8]; //i2cバッファー

//時間をoled表示形式に変換
char ch_hex_a_b[4];
char *ch_hex_a(int l_num)
{
    ch_hex_a_b[0] = '0' + (l_num >> 4);
    ch_hex_a_b[1] = '0' + (l_num & 0xf);
    ch_hex_a_b[2] = ':';
    ch_hex_a_b[3] = 0;
    return(ch_hex_a_b);
}

void i2c_oled_w(char *s)
{
            //文字の表示
            u8x8.drawString(
            ((cursor1-0) & 0x07  )*2, // x
            (cursor1>>3)*2,           // y
            s);
            cursor1=cursor1 + 3; 
} //i2c_oled_w

void setup()
{
  delay(3000);  //3秒待つ 消すな　bugの場合ST-LINKを繋ぎ直すに必要
    
  u8x8.begin();

  u8x8.setFont(u8x8_font_px437wyse700a_2x2_r);

  i2c_oled_w("START");
  delay(1000);

  //画面のクリア
  for(jj=0;jj<4;jj++){
    //              x    y   12345678
    u8x8.drawString( 0,jj*2,"        ");
  }//enf for
  //カーソルのクリア
  cursor1 = 0;

  Wire.begin(); //UNO
  //Wire.begin(sdaPin,sclPin); //STM32G031J6M6
} //end setup

void loop()
{
  //行のクリア
  //              x    y   12345678
  //u8x8.drawString( 0,jj*2,"        ");
  //カーソルのクリア
  cursor1 = 0;
  
  
  // レジスタのアドレスを先頭にする
  Wire.beginTransmission(ADDR);
    Wire.write(0x00);
  Wire.endTransmission();

  // I2Cスレーブに8byteのレジスタデータを要求する
  Wire.requestFrom(ADDR, 8);

  // 8byteのデータを取得する
  for (ii = 0; ii < 8; ii++) {
    while (Wire.available() == 0 ) {}
    data_read[ii] = Wire.read();
  }//for

  //画面に表示
  i2c_oled_w(ch_hex_a(data_read[2]));
  i2c_oled_w(ch_hex_a(data_read[1]));
  ch_hex_a(data_read[0]);ch_hex_a_b[2]=0;
  i2c_oled_w(ch_hex_a_b);
  
  delay(1000);  //1秒待つ

}//loop


```



時間合わせ


```c++



#include <Wire.h> //I2C library

#define ADDR    0x68  // 2進数 1101000

char    data_read[8]; //i2cバッファー

#define HH  12
#define MM  34

void setup()
{
  Wire.begin(); //uno

//i2c書き込み
  Wire.beginTransmission(ADDR);

  Wire.write((char) 0    ); //0 レジスターの位置は0
  Wire.write((char) 0    ); //1 秒
  Wire.write((char) ( MM /10)*16+( MM %10) ); //2 分
  Wire.write((char) ( HH /10)*16+( HH %10) ); //3 時

  Wire.write((char) 3    ); //4 曜日
  Wire.write((char) 1    ); //5 日
  Wire.write((char) 1    ); //6 月
  Wire.write((char) 0x20 ); //7 年

  Wire.endTransmission();

} //end setup

void loop()
{

} //loop


```


![uno_i2c_oled_ds1307_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/04475a21-b738-7a3e-7e1c-4e559c704d88.jpeg)
ClubHouseに対抗してCryptoHouseを作ってみた

流行に乗り遅れること約一ヶ月
ようやくクラブハウスに招待してもらいました。

面白いけど、私ただのしがないwebエンジニア、自分から話すことがない。
ただの進化系ラジオじゃん、、
自分から手を上げて話してリスナーを満足させる？
無理無理！

仮想通貨とか最近また盛り上がってるからそういう系の話
聞いてみても面白いんだが、やはり自分から発言することはない。

誰か自分の代わりに面白いこと自動で話してくれないかなー？

でもみんな仕事中とかでも意外と耳は空いてるんだなー


ん？待てよ？仕事中こっそり見てる仮想通貨の価格
見ないで聞けばいいんじゃね？

ということで
作ってみました。
#CryptoHouse

https://fx-labo.app/crypto_price/

ここでちょっと比較してみましょう。
##ClubHouse と CryptoHouse の比較
| | ClubHouse | CryptoHouse |
|:-----------:|:------------|:------------|
| 招待       | 必須        | 不要         |
| OS     | iOSのみ      | 全デバイス       |
| インストール       | 必要        | 不要         |
| 言語         | 英語          | 日本語(近日英語対応予定)          |
| 身バレリスク       | high       | 0%       |
| 有益性    | 人によりけり     | 人によりけり       |


思ってたんとちゃうかった人スミマセン(土下座)
仮想通貨の価格をただ読み上げてくれるだけのサイトです。
ClubHouseにまだ招待されていない方は
是非こちらで淡々と価格を聞いて資産を増やしてみてはいかがですか？

![スクリーンショット 2021-03-04 9.38.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668904/014a0ef2-8966-c7fc-7a2d-b4550201abc1.png)
##できること

+ 一定間隔で指定した仮想通貨の価格を読み上げます。
+ 通貨ごとにしきい値を設定してその数値を超えたときだけお知らせします。
 
以上

##ちょっとだけ技術の話
### Vuetifyのsliderとかマジ便利（語彙力orz）
モバイルでいちいち細かい数字を入力するの面倒なので
スライダーを自作しようと思ったのですがサンプルほぼそのままで
実装できました。（テキスト入力もできます）
https://vuetifyjs.com/en/components/sliders/

###SpeechSynthesisUtterance
という実験的な機能を使ってるので
ブラウザ環境によっては音が出ないものがあるようです。
参考にさせてもらった
https://qiita.com/hmmrjn/items/be29c62ba4e4a02d305c

###fitty
地味すぎて気づかれないかもしれませんが
価格を大きく表示するために自動でフォントサイズを調整してくれるjsです。
ちょっと癖があるんであとからCSSで再度調整したりはしてます。
https://github.com/rikschennink/fitty

##最後に
ニュースの読み上げとかはまだまだ難しそうな
SpeechSynthesisUtteranceですが
このくらいの需要であれば十分使える気がします。

まだまだ改善の余地はあるんですが
自己満足と、自分需要は満たしたので一旦これでリリース
反響次第で追加開発がんばります。

よかったらツイッターで絡んでください！
https://twitter.com/FxSlack
マークダウン書き方集

# はじめに
マークダウンの書き方を復讐のため自分用にまとめた記事になります。
参考になるところがあれば幸いです。

# 強調
強調したい文字は**（アスタリスク2回）または__(アンダーバー２回)で囲みます。
文字を＊＊協調＊＊する

# 斜字
斜体で表示したい文字は*（アスタリスク1回）、もしくは_（アンダーバー回）で囲みます。
文字を＿斜線＿にする
# 打ち消し線
打ち消し線を引きたいテキストは~~（チルダ2つ）で囲みます。
文字を〜〜おいしくない〜〜おいしいです。
# 画像添付
```
![ロゴ](https:/~~~~~)
```
[]にロゴを入れ()にurlを入れます。
urlはgithubのissueに画像をドロップすれば作成されるので便利です。
urlの後ろに　=100x300などと打てば大きさも指定可能です。
(https:/~~~~ =幅ピクセルx縦ピクセル)
=fullだと全画面です。
# リンク
```
![タイトル](https:/)
```
画像添付の!を外すとリンクの表示方法になります。

# インラインコード
バッククオートでテキストを囲むとインラインでコードを書けます。
`aaaaa`


# 以上
以上、簡単なまとめでした。
初学者のJavaScript

##forEachメソッド
`array.forEach(function(value, index){処理内容}`
配列の各項目を繰り返し処理するメソッド。
上記では、パラメータとしてfunction(value, index)が含まれており、配列の全ての項目に対し、記述した処理内容を実行する。実行されると、配列の各要素に２つのパラメーターが渡される。

| 処理回数 | value  | index番号 |
| ----- | ------ | -------- |
| 1     | array1 |     0    |
| 2     | array2 |     1    |
| 3     | array3 |     2    |
処理を実行するとかく配列の要素がパラメーターに代入され、index番号が割り振られる。
例えば２回目の処理では配列の２番目の要素がvalueに代入され、indexには１が代入される。

## for文
`for(let 変数名 of array){処理内容}`
繰り返し処理の１つ。変数に配列の要素を繰り返し代入していく。
配列の要素を１つの変数で管理することができる。
また、要素を追加したり、削除したりする、配列のメソッドが使用できる。

## 配列のメソッド
|メソッド名|内容|
|------|-----|
|array.pop|配列の最後のデータを削除|
|array.push(data)|配列の最後にデータを追加|
|array.shift()|配列の最初のデータを削除|
|array.unshift(data1)(data2)|配列の最初にdata1,data2...を追加|

## さいごに
プログラミングの初学者です。その日に学んだことを学習の一環としてアウトプットしています。
より深く学習していきたいと考えておりますので、ご指摘等いただけますと幸いです。

参考図書：確かな力が身につくJavaScript「超」入門　第２版　著者：加納祐東
用語集

#背景
とあるJava系コミュニティを見ながら用語集作成を思いつく
#内容
##サロゲートペア
サロゲートペアとは 1 つの文字に対して 2 つの文字コードを使って表される文字のことを指します。
##エンハンス
現行システムに手を加えて、性能や品質の強化・向上を図ったり、新たな機能の追加・拡張を行ったりすること。
【pytorch/numpy】seedで乱数を固定する

<h1>背景</h1>
乱数を固定して毎回同じ結果を出したい！


<h1>ソースコード</h1>
```
np.random.seed(1)
torch.manual_seed(1)
if CUDA:
    torch.cuda.manual_seed(1)
```
<h1>実験</h1>


```
img = Image.open(PATH-TO-IMAGE).convert("RGB")
w, h = img.size
th, tw = 256, 512

x1 = random.randint(0, w - tw)
y1 = random.randint(0, h - th)
img = img.crop((x1, y1, x1 + tw, y1 + th))
```

入力画像
![left_img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/9e716dfb-a99b-9999-d2d2-fbc7fec2a5fa.png)

seedを固定した場合
![left_img_croped copy1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/ffdb2ff1-d006-ddfa-efd7-d94fe2684801.png)

seedを固定しなかった場合
![left_img_croped copy 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/3ba43149-5c69-380b-58c5-ff62318da1f0.png)


何回か試すと違いが分かる。

<h1>結論</h1>
他にもmodelのweightの初期値等の乱数が存在するので、実験する場合は乱数を固定するとより良い実験が出来る
React Native で RSA 署名を行う / 署名を検証するライブラリー選定メモ

## 結論

react-native-simple-crypto を使う。

- node-rsa → スターの数からしても一番メジャーっぽいが、 React Native 上で動かそうとすると [constants の非存在によりエラー](https://github.com/rzcoder/node-rsa/issues/174) となる。うまくやれば解決できそうな気もするが……。
- [react-native-rsa](https://github.com/z-hao-wang/react-native-rsa) → 暗号化 /復号はできるので、それが目的なら使えそう（未検証）。しかし署名 / 署名検証の直接的なメソッドがない。
- [react-native-rsa-native](https://github.com/amitaymolko/react-native-rsa-native) → [iOS で不正な署名を正当だと誤判定するバグ](https://github.com/amitaymolko/react-native-rsa-native/issues/102) があり、致命的。使えない。
- [react-native-simple-crypto](https://github.com/ghbutton/react-native-simple-crypto) → 動く。ただし不正な署名を渡した場合にアプリごとクラッシュすることがあるので、それが問題であれば別途対策をする必要がある。
初学者のJavaScript

##document.querySelectorメソッド
* 指定したCSSセレクタをJavaScriptで取得することができる。
`document.querySelector(html)`

* 上記のように記述するとHTMLの`<html>〜<html/>`の要素を取得することができる。

##document.querySelectorAllメソッド
* 複数の要素を取得することができる。
*  `document.querySelectorAll(hoge)`と指定することで、`class = hoge`の前要素を取得することができる。

## さいごに
* プログラミングの初学者です。その日に学んだことを学習の一環としてアウトプットしています。
* より深く学習していきたいと考えておりますので、ご指摘等いただけますと幸いです。
RSGT2021 参加レポート

#Day1

## アジャイルを忘れるチーム Unlearn Agile
- チーム・パタン・ランゲージ
    - チームとしての性質と向き合う
    - 47機関のパターン例
        - つよくてニューゲーム
        - 脊椎感謝
        - ついでの一仕事
- 言語化して使うことによる気づき
    - 「よい」チームをつくりたい、というより「心地いい」チームがほしいと思うようになった
    - 言語化するのが大事
- どんな作業が心地よいか？（ワークショップ）
- 『シーザーを理解するために、シーザーである必要はない。』
    - [理解社会学のカテゴリー \| マックス ウェーバー, 明夫, 海老原, 敏男, 中野](https://www.amazon.co.jp/%E7%90%86%E8%A7%A3%E7%A4%BE%E4%BC%9A%E5%AD%A6%E3%81%AE%E3%82%AB%E3%83%86%E3%82%B4%E3%83%AA%E3%83%BC-%E3%83%9E%E3%83%83%E3%82%AF%E3%82%B9-%E3%82%A6%E3%82%A7%E3%83%BC%E3%83%90%E3%83%BC/dp/4624400380)
    - ＃もともと上記著書で使われていた言葉だが、攻殻機動隊の荒巻課長の言葉でもある
    - ＃「そうでなければ、あらゆる歴史記述は無意味であろう。」と続く
- 『パタンを使うことに執着してしまい良い建築になっていません』Christopher Alexander
    - スクラムイベントやってるだけではスクラムにならない
    - 自動テストやってるだけではうまくいかない
- 『規範の中にいるときは、それを窮屈と感じるけど、規範なき行為はまた行為として成立しない。結局堂々巡り』攻殻機動隊 STAND ALONE COMPLEX Solid State Society
    - パタンを書きながらも堂々巡りになっているのではという疑問
- 生き生きしているチームもある、要因はなにか？
    - 47機関のパタンを使っても窮屈になってしまうチームもあれば生き生きしているチームもある
    - その差はなにか？
        - 何に導かれているのか？
            - 47機関だと、攻殻機動隊、軍隊蟻、キノコアリ
        - 目指したい先に、直観的にに共感できる
            - ひとりだと直観だけだけどチームだと客観的になる
            - みんながいいと思える、当たり前に思える＝深い共感
            - ルールや誰かに言われたからではなく、自分たちののかにある直観を信じた
        - 直観だけど客観的そして深い共感を大事にしている、という点が同じチームだと同じパターンで生き生きできているのかも
- うまくいっているパタンに明確な属性がある
    - うまくいくために必要な属性
        - 必要なコミットメント量
        - 必要なコミットメントのパス数
    - パタンだけこなしてもうまくいかない、コミットメント量やパス数を必要なライン以上をみたさないといけない
- **原則から入るのではなく直感から入るのが大事**
    - 繰り返し（直観＆客観 深い共感 → 実験） → ルール 原則 ガイド
    - 『根拠ですって？そう囁くのよ、私のゴーストが』攻殻機動隊 Ghost In The Shell
- KPT as ART
    - https://kyon-mm.hatenablog.com/entry/2019/03/07/080000
    - https://retrospective.connpass.com/event/185851/
    - https://anchor.fm/furikaerisuruo/episodes/ep-25amkyon_mmKPT-as-ART-KPT-as-ART-ejuei0
- 深い共感と実験、チームの生命構造、次が生成されるセンタ
MinikubeをMacにインストール

#背景
- Macが新しくなったのであらためてMinikubeをインストールしたかった
- OpenShiftを触っていたのであらためてKubernetesがほしかった
- K8sがCRI-O中心になったのでDocker on Macではない方法でインストールしたかった


#手順
基本的な流れ はこちら
https://kubernetes.io/ja/docs/tasks/tools/install-minikube/


1. Homebrewのインストール
 https://brew.sh/index_ja

2. Kubectlのインストール 
brew install kubectl 
ローカルへのアクセス権限がたりなかったのでbrewの指示の通りに設定変更

3. Virtual Boxのインストール 
https://www.virtualbox.org/wiki/Downloads
 Macのセキュリティ設定でOracleの機能拡張を許可してPC再起動

4. minikubeインストール 
minikube start --driver=virtualbox



終了
HoloLens 2、MRC、半透明オブジェクトの背景が黒でアルファブレンディングされるときの対処方法

# 環境

* Windows 10
* HoloLens 2 
* Unity 2019.4.20f1
* Microsoft.MixedReality.Toolkit.Unity.Foundation.2.5.4

# 症状

* HoloLens 2 MRC でキャプチャすると、背景が黒でアルファブレンディングされる(実機でみているときは気づかない)。

# 解決方法

* カメラの背景色のアルファ設定（透明度）を0にする。

![ss02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/57f41ee6-86fa-631a-fee8-48694442e63c.png)


# 参考にしたサイト

* Unityの場合は、デフォルト設定で問題ないと書いてありそうだが、筆者の環境では、透明度が1.0(255)であった。

https://docs.microsoft.com/en-us/windows/mixed-reality/develop/platform-capabilities-and-apis/mixed-reality-capture-for-developers
サイドバーのカレント表示で詰まったことと解決策

（備忘録なので少々煩雑です。落ち着いてきたら整理したい）

# 困った

~~~hogehoge.hbs
<ul class="side-menu">
    <!-- ここからカレント表示したいのに・・・ --->
    <li id="side-menu"><a href="#gohan">{{oishiina}}</a></li>

        ...

    <li id="side-menu"><a href="#panmo">{{daisuki}}</a></li>
    <li id="side-menu"><a href="#pasta">{{mogumogu}}</a>
        <ul class="side-menu-child">
            {{#each this.shushoku as | koubutu | }}
            <li id='side-menu-child'>
                <!--ここ以降だけカレント表示で色がつく.なんで?? -->
                <a href='#{{koubutu.link}}'>{{koubutu.namae}}</a>
            </li>
            {{/each}}
        </ul>
    </li>
</ul>

<script>
    function changeBackColor(secNum) {
	if (secNum != current) {
	    current = secNum;
	    let secNum2 = secNum + 1;
	    $('#side-menu li').removeClass('colorOn');
	    $('#side-menu li:nth-child(' + secNum2 + ')').addClass('colorOn');
    }
</script>
~~~

## 原因

* [:nth-childの仕様](https://lmn-blog.com/nth-of-type01/)にあるようでした。

つまり上の書き方だと、「**side-menuというidがついたタグ（ここではli）の子要素としてあるliタグ（id='side-menu-child'であるli）**」にcolorOnクラスが追加されていたのです。

## 対応策

以下のように実装を変更すると、うまくサイドバーの最初からカレント表示されました。

~~~newHogehoge.hbs
<ul class="side-menu">
    <li id="side-menu"><a href="#gohan">{{oishiina}}</a></li>

        ...

    <li id="side-menu"><a href="#panmo">{{daisuki}}</a></li>
    <li id="side-menu"><a href="#pasta">{{mogumogu}}</a>
        <ul class="side-menu-child">
            {{#each this.shushoku as | koubutu | }}
            <li id='side-menu-child'>
                <a href='#{{koubutu.link}}'>{{koubutu.namae}}</a>   
            </li>
            {{/each}}
        </ul>
    </li>
</ul>

<script>
    function changeBackColor(secNum) {
	if (secNum != current) {
	    current = secNum;
	    let secNum2 = secNum + 1;
	    if (secNum2 <= 5) {
	        $('ul #side-menu-child').removeClass('active');
	        $('ul #side-menu').removeClass('active');
	        $('#side-menu:nth-child(' + secNum2 + ')').addClass('active');
	    } else {
	        let secNum3 = secNum2 - 5;

	        $('ul #side-menu').removeClass('active');
	        $('ul #side-menu-child').removeClass('active');
	        $('#side-menu-child:nth-child(' + secNum3 + ')').addClass('active');
	    }
    }
</script>
~~~
OpenCVのSVM.load()がstatic関数と知らず嵌まった件


##はじめに
OpenCVのSIFTで特徴量を抽出してSVMで分類する、というプログラムを作成しています（[関連記事１](https://qiita.com/herr-shigeo/items/aad150f9cd9b2c876555)、[関連記事２](https://qiita.com/herr-shigeo/items/4cdb0a36a469c8976c9c)）。
OpenCV初心者のため、SVM.load()がstatic関数だと知らず、かなり嵌まったので、備忘として残します。

##SVM.predict()でAssertion failed
ファイルに保存しておいた学習データをSVM.load()で読み込んだ後、SVM.predict()を実行すると、Assertion failedが発生しました。
以下が実際のコードです。

```python
    # create a SVM and load the data
    svm = MySVM()
    svm.load(svm_file)

    # predict
    for i in range(file_manager.getNumFiles()):
        path = file_manager.getFile(i)
        img = cv2.imread(path)
        gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        descriptors = bow_trainer.extractDescriptors(gray_img)
        prediction = svm.predict(descriptors)
```
以下がエラーの内容になります。

```
  File "./sift_svm.py", line 68, in predict
     prediction = svm.predict(descriptors)
cv2.error: OpenCV(4.5.1) /tmp/pip-build-uyw1ttra/opencv-contrib-python/opencv/modules/ml/src/svm.cpp:2013: error: (-215:Assertion failed) samples.cols == var_count && samples.type() == CV_32F in function 'predict'
```
Assertionの式だけ抜き出すと以下になります。

```
samples.cols == var_count && samples.type() == CV_32F
```

引数に渡しているdescriptorsは次のような40次元ベクトルです。

```
[[0.0761999  0.0435428  0.0212766  0.02028698 0.01335972 0.01929738
  0.0113805  0.01731816 0.01335972 0.00791687 0.02276101 0.01484414
  0.00841168 0.09351806 0.02523503 0.0103909  0.00989609 0.06333498
  0.01830777 0.0648194  0.01731816 0.01632855 0.08114794 0.02968827
  0.00841168 0.01484414 0.02770905 0.0113805  0.01434933 0.00841168
  0.00791687 0.02671944 0.02622464 0.00989609 0.02770905 0.00643246
  0.02325581 0.00692726 0.02968827 0.03018308]]
```
データのtypeはCV_32Fで間違いなさそうですので、ベクトルの次元数が間違っているということになりそうです。しかし、SVMをtrainする際にも40次元のベクトルを渡していることも確認済みです。

では、何が間違っているのか？
numpy.arrayを色々いじったりしたのですが効果なし。svm.cppのソースもチェックしたのですがヒント得られず。
こうなると、svm.cppにデバッグプリント入れてOpenCVを再度ビルドしてデバッグするしかないのか？（面倒なのでやりたくない。。）と途方に暮れていた時、SVMの学習結果を保存しているファイルはXMLであることに気付きました。

そこで、XMLファイルを確認してみると...

```
<var_count>40</var_count>
```
var_countが40と書いてあり、渡しているベクトルの次元数を一致しています。
ということは、SVM.load()が正しくvar_countを読み込んでいないことになります。そこで、SVM.load()のAPI仕様を確認してみると...

```python
static Ptr<SVM> cv::ml::SVM::load	(	const String & 	filepath	)	
Loads and creates a serialized svm from a file.
```
なんとSVMオブジェクトを返すstatic関数でした。。
つまり、load()で実行しているSVMオブジェクトには何も影響せず、読み込んだ結果を反映した新しいSVMオブジェクトを返す関数ということになります。元のSVMオブジェクトのvar_countは初期値あるいは未初期化であり、40ではなかったため、Assertion failedしていた訳です。

以下のようなコードに変更することで、解決しました。

```python
new_svm = svm.load(svm_file)
svm = new_svm
```

##所感
「何故static関数なのか？」詳細は調べていませんが、学習データを反映させるには、コンストラクタから呼び出す必要があり、新しいオブジェクトを作成する方が実装が楽なのかもしれません。

IMHOとして言うと、load()という名前と関数仕様が合致していないため、API仕様を確認せずに使うタイプの私は嵌ってしまったと思います。
やや不細工な名前になりますが、"loadAndCreate"とか、オブジェクトを生成するニュアンスが伝わる名前での方が、APIとしては良いのではないでしょうか。

##まとめ
API仕様は確認しましょう。
【MLAPI】Unityでのマルチプレイヤーゲームの実装方法

# 内容
MLAPIを利用してUnityでマルチプレイヤーゲームの実装方法について解説します。

※ 本記事は, Unity Japanの[Unityでマルチプレイヤーゲームを作ろう！ - Unityステーション](https://www.youtube.com/watch?v=Fl1TP2expZE&feature=emb_logo)を基にしています。
サンプルプログラム: https://drive.google.com/file/d/1x0gHaJfH8d3QlguP58_9L16Pjlqposr4/view

## MLAPIのインポート方法

Github MLAPIからダウンロードし、プロジェクトにインポートします。
https://github.com/Unity-Technologies/com.unity.multiplayer.mlapi

## Sceneの設定
1. 「NetworkManager」という名前の空のObjectを追加します。
2. `NetworkManager`オブジェクトに次の2つのコンポーネントを追加します。
    * `NetworkingManager`コンポーネント
    * `Unet Transport`コンポーネント
3. `NetworkingManager`コンポーネントの`Network Transport`プロパティに`NetworkManager`オブジェクトをドラッグ&ドロップします。

## ネットワークに対応したいオブジェクトの設定
1. オブジェクトに`NetworkedObject`コンポーネントを追加します。
2. Inspectorの`Override`から`Apply All`を選択し、適用します。
3. ObjectのPrefabを`Project`から選択し、`NetworkManager`オブジェクトの`NetworkingManager`コンポーネントの`NetworkedPrefabs`にドラッグ&ドロップで設定します。プレイヤーが操作するオブジェクトの場合、隣の`Default Player Prefab`にチェックマークを入れます。
4. Prefabを`Project`から選択し、`Networed Transform`コンポーネント, `Networked Animator`コンポーネントをPrefabに追加します。
   `Networked Animator`コンポーネントの下のチェックマークでは、Animatorがもつパラメータの中でどれをネットワーク上で同期させるかを決定します。

## ボタンの設定
1. 画面上にHost Button, Client Buttonを追加します。
2. Script `UICallback.cs`を作成し、次のコードを書きます。
3. 各メソッドをButtonの`On Click`イベントに設定します。

```c#
using System.Collections;
using System.Collections.Generic;
using Unity.Engine;

public class UICallback : MonoBehaviour
{
    public void OnClickHost()
    {
        MLAPI.NetworkingManager.Singleton.StartHost();
    }
    public voice OnClickClient()
    {
        MLAPI.NetworkingManager.Singleton.StartClient();
    }
}
```

もし、接続先のアドレスを変えたい場合は`NetworkManager`オブジェクトの`Unet Transport`コンポーネントの`Connect Address`を変更します。デフォルトでは、ローカルアドレスになっています。

ここで、同期対象のオブジェクトがシーンに配置されている場合、`NetworkManager`により生成されるため、削除する。

# 自分が動かすオブジェクトのみ動かす
現時点では、オブジェクトを操作した時、HostのオブジェクトもClientのオブジェクトも動作してしまいます。そこで、オブジェクトを動かすスクリプトを変更します。ここでは、便宜的にそのスクリプトを`MoveController.cs`とします。

1. オブジェクトの`MoveController.cs`の継承するクラスを`MLAPI.NetworkedBehaviour`に変更する。
2. 動かしている部分のコードを`if(this.IsOwner)`で囲うことにより、Ownerの場合のみ動作します。

こうすると、自分が操作しているオブジェクトのみ動くようになります。

もし、サーバーで動かしたい場合はConnect AddressとPortをスクリプトで取得し、変更する必要がある。

## その他
* ネットワーク上で同期したい変数があるときは、`[MLAPI.NetworkedVar.SyncedVar]`を宣言時に書く。

* ネットワーク越しに、関数を呼び出したい時、サーバーからクライアントに呼び出して欲しい場合は`MLAPI.Messaging.ClientRPC`, クライアントからサーバーに呼び出して欲しい場合は`MLAPI.Messaging.ServerRPC`を宣言時に書く。呼び出すときは、`this.InvokeClientRpc(関数名, Client ID)`で呼び出す。

* マッチングの機能はないので、自分で実装する必要がある。

# サーバーで動かしたい時
1. Built Settingsで`PC, Mac & Linux Standalone`を選択し、`Target Platform`を`Linux`に設定します。
2. `Server Build`にチェックマークを入れ、Buildします。
3. 出力されたバイナリファイルをLinux Serverに移動させ、起動します。

* ターゲットフレームをしっかり指定しないと、とんでもないレートになってしまう。
BoWのvocabularyをpickleでdumpしてloadしたらUnicodeDecodeError

##はじめに
OpenCVのSVMには、学習結果をファイルに保存するsave()と、ファイルから読み込むload()関数が用意されています。しかし、BOWKMeansTraineには、作成したvocabulary（[関連記事](https://qiita.com/herr-shigeo/items/4cdb0a36a469c8976c9c)）を保存したり、読み込む関数は用意されていません。
そこで、pickleでファイルにdump()してload()した結果、UnicodeDecodeErrorになったので、その時の備忘を残します。

##ソースコード
以下のようにvocabularyを保存します。

```python
def createVocAndSave(self, data_file=None):
        voc = self._trainer.cluster()
        self._extractor.setVocabulary(voc)
        if data_file is not None:
            with open(data_file, 'wb') as f:
                pickle.dump(voc, f)
```

そして、次のようにして、ファイルに保存したvocabularyを読み込みます。

```python
def loadVoc(self, data_file):
        if data_file is not None:
            with open(data_file) as f:
                voc = pickle.load(f)
            self._extractor.setVocabulary(voc)
```
すると、pickle.load(f)で以下のエラーになります。

```
  File "./sift_svm.py", line 43, in loadVoc
    voc = pickle.load(f)
  File "/usr/lib/python3.6/codecs.py", line 321, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte
```

##エラーの原因
binaryモード('wb')で保存したファイルを、binaryモード指定せずに読み込んだためです。
私の癖で、ファイルをRead-onlyでオープンする時はモードを省略するため、binaryモード指定を失念していました。
binaryモードで読み込むことで解決しました。

```python
with open(data_file, 'rb') as f:
```

##まとめ
省略のメリットが少ない場合、省略せずきちんと書いたほうが良いのかもしれません。
Vim新しく覚えたシリーズ 目次ページ

#概要
vim歴 10年でも、何となく使ってなかった(基本的)機能がいっぱいあるので、
たまに新しいことにチャレンジして記録しようと思った。

一覧としてまとめる。
#内容
[Vim新しく覚えたシリーズ1 (マーク・ジャンプ機能)](https://qiita.com/yo314159265/items/14f2522d376cf6087efa)
[Vim新しく覚えたシリーズ2 (挿入ノーマルモード)](https://qiita.com/yo314159265/items/c8aea6da12d75a3040a1)
#感想
幸せ。
#今後
適宜追記予定。
Vim新しく覚えたシリーズ1 (マーク・ジャンプ機能)

#概要
vim歴 10年でも、何となく使ってなかった(基本的)機能がいっぱいあるので、
たまに新しいことにチャレンジして記録しようと思った。

マーク・ジャンプ機能。(他記録は[こちら](https://qiita.com/yo314159265/items/97a823bc5d11b5f1e158))
#内容
##環境
macOS Catalina
VIM - Vi IMproved 8.1 macOS version Normal version without GUI.
##使ってみた
```:tmp.txt
aaaaa
bbbbb
ccccc
```
①3行目で**mm**を入力した。(mでマーク)
②1行目に移動。
③**'m**を入力した。(「'」シングルクオートでマークmに移動)

できた！
##まとめ
|Command|Description|
|:--|:--|
|ma | set mark **a** at current cursor location|
|'a | jump to line of mark **a**|
|`a | jump to position(line and column) of mark **a**|
|:marks| list all the cuurent marks|
|:marks aB| list marks **a**, **B**|

##蛇足

- `.`(ドット)：最後に編集した場所がマークされている
- `'`, <code>`</code>：直前ににジャンプした場所がマークされている
- `[`,`]`:最後に編集・yankした場所がマークされている
- `<`,`>`:最後にvisual selectした場所がマークされている。
 
#参考にさせていただいた頁・本
- https://vim.fandom.com/wiki/Using_marks
- https://vim-jp.org/vimdoc-ja/motion.html#jump-motions

#感想
快適だった。
「`」(バックスラッシュ)は少し打ちにくい印象。。
#今後
ちょっと編集した後に、また元の場所に戻ってきたい時などに活用していきたい。
TinyML(Tiny Machine Learning)関連のYoutubeをみてみる


#概要
TinyML(Tiny Machine Learning)関連のYoutubeをみてみる。

TinyMLは、以下の書籍が有名。

TinyML
by Pete Warden, Daniel Situnayake
Released December 2019
Publisher(s): O'Reilly Media, Inc.
ISBN: 9781492052043

引用：https://www.oreilly.com/library/view/tinyml/9781492052036/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/b0f76ab4-0aca-9df8-316d-d76e38fabbeb.png)

とりあえず、はずさないために、
上記の著者の「Pete Warden」によるYoutubeあたりから始める。



#その１(What’s TinyML good for)
https://www.youtube.com/watch?v=Wuq2aP5O5Z0

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/316df54d-a427-8dc7-0777-6f910b4f79ad.png)

##感想
（後述）


#その２(tinyML Talks - Pete Warden: Getting started with TinyML)
https://www.youtube.com/watch?v=soOM1F70Boc

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/95adf2cd-7210-4a56-c6ad-27af0fa2635c.png)

##感想
（後述）

#まとめ
まだ、着手段階です。
kintone: 一番シンプルな年度の取得方法（たぶん）


プラグインやjavascriptを用いず、中間フィールドを使わず、
1項目で対象日付の年度を取得してみました。

#結論

計算フィールド（または文字列1行の自動計算）に下記計算式で年度が得られます。
対象日付のフィールドコードが「日付」で、4月はじまりの例です。

```計算式.kintone
IF(
	OR(
		DATE_FORMAT(日付, "M", "system") = "1",
		DATE_FORMAT(日付, "M", "system") = "2",
		DATE_FORMAT(日付, "M", "system") = "3"
	),
	DATE_FORMAT(日付 - 3*31*24*60*60, "YYYY", "system"),
	DATE_FORMAT(日付, "YYYY", "system")
)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1171945/8178f40b-7382-30ae-576f-dd16f2f225d5.png)


#説明

###概要

1～3月は 3か月分引いた年が年度と等しい、
他の月は年と年度が等しい、という計算をしています。


###条件部
まずIFの条件部分、ここで翌年にずれ込んでいるものを判定しています。
（数値に変換できないようなので不等号での条件指定ができません）

```IFの条件部.kintone
OR(
	DATE_FORMAT(日付, "M", "system") = "1",
	DATE_FORMAT(日付, "M", "system") = "2",
	DATE_FORMAT(日付, "M", "system") = "3"
),
```


###他
残りの部分は下記で、
・翌年にずれ込んでいるものは、ずれ込んだ分を引いた上での年を
・それ以外はそのままの年を
DATE_FORMATで取り出しています。

日付フィールドは秒単位で演算できるようなので
月の最大日数31の3ヶ月分を秒に変換し引きます。

```条件省略.kintone
IF(
	条件,
	DATE_FORMAT(日付 - 3*31*24*60*60, "YYYY", "system"),
	DATE_FORMAT(日付, "YYYY", "system")
)
```

#応用
上記は4月はじまりの例ですが、年度始まりが他の月であるという場合は
条件部と引く日数を修正することで年度が得られます。

```8月はじまりの例.kintone
IF(
	OR(
		DATE_FORMAT(日付, "M", "system") = "8",
		DATE_FORMAT(日付, "M", "system") = "9",
		DATE_FORMAT(日付, "M", "system") = "10",
		DATE_FORMAT(日付, "M", "system") = "11",
		DATE_FORMAT(日付, "M", "system") = "12"
	),
	DATE_FORMAT(日付, "YYYY", "system"),
	DATE_FORMAT(日付 - 8*31*24*60*60, "YYYY", "system")
)
```
matplotlib ~ グラフに点を書く

matplotlibはpythonで行った計算を描画する際に便利です.
今回はシンプルに任意の点をグラフに描画します.

グラフの作成

```python:グラフの作成
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111)

plt.xlim(-300,300)
plt.ylim(-200,200)

plt.xlabel('x')
plt.ylabel('y')

plt.grid()

plt.show()

```
任意の範囲のグラフが描画できました.
![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/13fdb256-3a04-ece4-92b4-9c59b1c66169.png)

グラフ上に点を描画するときは```plt.plot(100,50,marker='.')```のように追加

```python:グラフに点を追加
import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(111)

plt.xlim(-300,300)
plt.ylim(-200,200)

plt.xlabel('x')
plt.ylabel('y')

plt.grid()

plt.plot(100,50,marker='.') ##追加

plt.show()
```
以下のように点が描画できました.
![Figure_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/f198d2f2-952e-eeb3-0e11-92fbac9fc471.png)
HoloLens2のMicrosoft Mesh Appに最速でUnitychanを登場させるまで

# 今日のゴール

こんな感じでMicrosoft Mesh AppにUnitychanを登場させます。

![20210304_012505_HoloLens.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/8e5a915b-6e2b-190f-9a5d-33c092144c06.jpeg)

https://twitter.com/iwaken71/status/1367150478467813376?s=20

## Microsoft Meshとは

> “You can actually feel like you’re in the same place”: Microsoft Mesh powers shared experiences in mixed reality

MRの世界を共有するプラットフォーム、Microsoft Mesh
米国時間3月2日にMicrosoftのカンファレンスIgniteにて公開されました。
https://news.microsoft.com/innovation-stories/microsoft-mesh/

https://www.youtube.com/watch?v=IkpsJoobZmE&feature=emb_logo

Microsoft Mesh AppはMicrosoft Storeからアプリをダウンロードできます。(HoloLens2にダウンロード)
https://www.microsoft.com/ja-jp/p/microsoft-mesh-app-preview/9p64lj74ngw0?activetab=pivot:overviewtab


# 前提

- HoloLens2のMicrosoft Mesh Appを使用
- OneDriveとHoloLens2のログインMicrosoft Accountは同一 (違う場合どうなるかは未検証)

# 手順

- 3Dモデルをglb形式で準備する
    - Unitychanをglb形式で書き出す
- OneDriveにアップロードする
- HoloLens2のMicrosoft Mesh AppからUnitychanをダウンロード

# 3Dモデルをglb形式で準備する

公式ドキュメントなどは見れていないのですが、今回fbx,glb,[gltf](https://github.com/KhronosGroup/glTF/tree/master/specification/2.0)形式のの3Dモデル形式を調べた結果glb形式のみ認識しました。なので、今回glb形式を準備します。

gltfとglbについては[こちら](https://www.codegrid.net/articles/2018-gltf-1/)

(追記)
[公式ドキュメント](https://docs.microsoft.com/en-us/mesh/mesh-app/)より、現在対応している形式はglb形式のみだそうです。


## Unitychanをglb形式で書き出す

ここは手段は何でもいいのですが、私は

- UnitychanのVRMファイルをダウンロード
- UniVRMからVRMファイルからglb形式にExport

という手段を選びました。

https://3d.nicovideo.jp/works/td33435

https://github.com/vrm-c/UniVRM/releases

# OneDriveにアップロードする

[OneDrive](https://onedrive.live.com/)にログイン後
[自分のファイル]>[アプリ]>[Microsoft Mesh App(Preview)]>[MyContent]を開く

ここにglbファイルを置く。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/db14bf20-1a98-527c-1ce8-f6bd8627bc50.png)
(試しに他のファイル形式を試した跡)

# HoloLens2のMicrosoft Mesh AppからUnitychanをダウンロード

Microsoft Mesh Appを立ち上げて

[Content]>[One Drive]を選択すると、Unitychanが選択できれば成功です。

作業動画はこちら...!

https://twitter.com/iwaken71/status/1367157890675474435?s=20

# おわりに

Microsoft Mesh非常に楽しみですね...!
今後開発者としても色々手を加えられるようになっていくと予想しているのでとても楽しみです。
引き続きMRの新しいプラットフォームに期待と敬意を示して、記事を書いていきたいと思います。

![20210304_020329_HoloLens.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96970/c1a23c6a-246a-0896-5fbb-6227bb16cfb7.jpeg)


# 追記

https://techcommunity.microsoft.com/t5/mixed-reality-blog/microsoft-mesh-a-technical-overview/ba-p/2176004
VSCodeで未登録な拡張子をオレオレ言語モードを通して認識させ設定する

:::note warn
初回記事執筆時は、所定のフォルダにpackage.jsonを置くだけでオレオレ拡張機能が有効になっていたが、2022年12月現在、その方法は無効になっていた。
若干面倒だがパッケージ化の手順を踏む必要があるようだ。
（記事編集済み。）
:::

例えば、VC++のリソーススクリプト（拡張子rc）なんかはVSCodeに登録されていないので、「わしゃrcのファイルはデフォルトでUTF-16になってほしいんじゃあ！」なんて場合に困ることになる。

厳密には、VSCodeに拡張子を直接指定しての設定なんてものは（私の知る限り）無くて、言語モードに含まれるファイルの種類としての設定という形でなら可能。

そこでどうしたかというと、目的の拡張子を扱うオレオレ言語を作り、オレオレ拡張機能として所定のフォルダに突っ込むことで解決したのでご紹介。

## 目的

冒頭で述べた通り、今回rcファイルがデフォルトでUTF-16 LEになるようにしてみる。

## 手順

まず拡張機能を自作するための下準備として、「Node.js」およびその上で動く「vsce」を導入する。

> **Node.js**
> https://nodejs.org/ja/

上記Node.jsの公式からインストーラーを入手してインストール。推奨版と最新版があるが、推奨版の方で良いと思う。
無事インストール出来たら、ターミナルあるいはコマンドプロンプトで下記コマンドを実行。
`npm install -g vsce`
これでvsceも入り、下準備完了。

任意の作業フォルダに「rc」という名前のフォルダを新規作成する。さらに「rc」フォルダの中に「package.json」というテキストファイルを新規作成し、下記の内容を入れて保存する。

```json:package.json
{
	"name": "rc",
	"displayName": "rc",
	"description": "resource script extension",
	"version": "0.0.1",
	"publisher": "vscode",
	"engines": {
		"vscode": "*"
	},
	"contributes": {
		"languages": [
			{
				"id": "rc",
				"extensions": [".rc"],
				"aliases": ["Resource Script"]
			}
		],
		"configurationDefaults": {
			"[rc]": {
				"files.encoding": "utf16le"
			}
		}
	}
}
```

そしたらターミナルあるいはコマンドプロンプトで「rc」フォルダに移動し、下記コマンドを実行。
`npx vsce package`
いろいろ足りないので警告が2回くらい出るが、都度「y」入力してEnterでスルー。
上手くいけば「DONE」となり、「rc」フォルダの中に「rc-0.0.1.vsix」が生成されると思う。これが拡張機能のインストーラーファイルとなる。

VSCodeを起動して、拡張機能タブに移動。
拡張機能リストの右上の方にある三点リーダー（「…」）をクリック、「VSIXからのインストール」を選び、先ほど作成した「rc-0.0.1.vsix」を読み込む。

拡張機能を見てみると…。
![extrc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109951/452da2fd-a939-0733-fe13-ff8717cd204c.png)

拡張子「.rc」を扱うオレオレ言語「rc」のためのオレオレ拡張機能「rc」が爆誕。

![extrc2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109951/acc8a384-5901-729d-2b98-0fcb9bf3b90f.png)

早速VSCode上で拡張子「.rc」のファイルを新規作成してみる。

![extrc4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109951/126ed704-6cbc-3bc5-8790-f055cf07d571.png)

ステータスバーを確認すると、ちゃんとUTF-16 LEになってることが分かる。

良かった良かった。
Community Cloud の基本 ⇒ パートナーと協力する

１．Lira がパートナーポータルを設定する前、パートナー再販業者が Lira となかなか協力しなかったのはなぜですか?
２．チャネルセールス担当 VP は、パートナーコミュニティに関してどの総計値を重視しますか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/9c77690c-88e7-5260-e759-17235bac10da.png)
HTTP Error 403: Forbiddenの対処法

#「ゼロから作るDeep Learning」を勉強中のことでした

3章『ニューラルネットワーク』中に3.6「手書き数字認識」の項．
mnistをダウンロードし表示させるmnist_show.pyを実行したところ，以下のようなエラーが...

~~~
urllib.error.HTTPError: HTTP Error 403: Forbidden
~~~

どうやら，mnist.py 中の関数 _downloadでエラーが発生してる．

~~~mnist.py
def _download(file_name):
    file_path = dataset_dir + "/" + file_name

    if os.path.exists(file_path):
        return

    print("Downloading " + file_name + " ... ")
    urllib.request.urlretrieve(url_base + file_name, file_path)
    print("Done")
~~~

調べてみると，対象urlへのリクエスト権限がないとのこと．
urlのヘッダーを偽装することで解決するらしい．

#ソースコード修正
headersを適当に指定します．
それを使ってurllib.request.Requestオブジェクトを取得．
urlopenでファイルをダウンロードします．
**＊urlretreiveは引数に文字列strをとるので今回の方法では使用できませんでした**

~~~ mnist.py
def _download(file_name):
    file_path = dataset_dir + "/" + file_name

    if os.path.exists(file_path):
        return

    print("Downloading " + file_name + " ... ")
    headers = {
        "User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:47.0) Gecko/20100101 Firefox/47.0"
        }
    request = urllib.request.Request(url_base+file_name, headers=headers)
    response = urllib.request.urlopen(request).read()
    with open(file_path, mode='wb') as f:
        f.write(response)
    print("Done")
~~~

#実行してみる

~~~
Downloading train-images-idx3-ubyte.gz ... 
Done
Downloading train-labels-idx1-ubyte.gz ... 
Done
Downloading t10k-images-idx3-ubyte.gz ... 
Done
Downloading t10k-labels-idx1-ubyte.gz ... 
Done
Converting train-images-idx3-ubyte.gz to NumPy Array ...
Done!
5
(784,)
(28, 28)
~~~

成功！

# 追記 2021-3-11

同じところで困ってる方が多かったのでリポジトリのissuesに投稿しました．
PHPをherokuにデプロイする！(1)herokuでデータベースの環境変数を設定し利用する

#はじめに・・・
今回はPHPをherokuを使用してデプロイするにあたって苦労した点を書いていきたいと思います。苦労した部分はたくさんありますが、まずは注意が必要なデータベースの設定について記事を書いていきたいと思います。基本的な設定に関して今回は詳しい手順を省略していますがよろしくお願いします。

##開発環境
まずは今回作成にあたって利用したものです。
php(バージョン7.4.12)＋MySQL
Heroku(ユーザー登録が必要です)
Cleardb(herokuのオプション、これがあればMySQLが使えます)
MAMP(PHPの開発環境、今回の話ではあまり関係ありません)

これらを用いてアプリ開発に取り組んでいました。ちなみにherokuでは通常PostgreSQLを用いますが、Cleardbというものを使えばMySQLが利用できます。
ただしクレジットカードの登録が必須になります。(無料枠自体はありますし急に課金されることはないようですが、それであっても登録が必須)
herokuでMySQLを使用する詳しい手順は記事にしようとは思っているのですが、参照したサイトがあるのでそちらを紹介します。ちなみに僕はRailsのアプリもMySQLでデプロイしました。
https://trialanderror.jp/heroku-mysql-start/

#データベースの情報取得
MAMPを利用し、ローカル環境でデータベースに接続する場合は、以前書いた記事のコードで接続を行えます。
https://qiita.com/tetsu_19920922/items/f156c2bec2448eda0d2f
一方本番環境の場合は、herokuのcleardbの情報を元にコードを書き直し、接続する必要があります。
cleardbの情報を取得するには以下のようにターミナルで入力します。(herokuにデプロイする予定のアプリを指定した状態で入力してください)

```
$ heroku config | grep CLEARDB_DATABASE_URL
```

これを入力すると以下のような形で出力されます。

```
CLEARDB_DATABASE_URL: mysql://ユーザー名:パスワード@ホスト名/データベース名?reconnect=true
```

ホスト名は最後にcleardb.netがついてきますし、データベース名はherokuから始まると思います。パスワードは8桁になっていると思います。

#デプロイ、その前に！
それではこの取得したデータを元にデータベースの接続文を変更・・・となるわけですが、herokuを用いたデプロイにはgitとの連携が不可欠です。
gitにそのままデータベースのユーザー名やパスワードが載ったものをコミットしてしまうと不正に操作されたり、改竄されたりとよくないことがたくさん起こり、ひいてはアプリに大きな障害を来す可能性があります。

そこで環境変数を用いることで、gitには見えない形でパスワードやユーザー名を登録し、そこから参照という形をとりましょう！
環境変数を用いる方法はphpであればphpdotenvを使用するというものもありますが、本番環境での利用はあまり推奨していないのと、gitの設定を忘れると結局コミットされてしまう（のと筆者があまり使い方を理解できなかった・・・)ので、今回はherokuで環境変数を設定する方法をとります。

##herokuに環境変数を入れ込む
heroku config:addの後ユーザー名であれば　DB_USERNAME＝'<ユーザー名>'と言う形でターミナルに入れていきます。もちろんこのユーザー名は上で書いた内容で参照したものを入れてください。具体的に言うと

```
$ heroku config:add DB_USERNAME='<ユーザー名>'

$ heroku config:add DB_PASSWORD='<パスワード>'

$ heroku config:add DB_NAME='<データベース名>'

$ heroku config:add DB_HOSTNAME='<ホスト名>'

$ heroku config:add DB_PORT='3306'
```
これを入れていきましょう。ポートはherokuでMySqlを使用する場合3306が開放されているようなのでそれを用いましょう。またユーザー名とパスワードさえ環境変数に入れておけば安全だと思いますが、データベース名、ホスト名も入れてしまってもいいと思います。
入れた環境変数を確認するには、heroku configのみをターミナルで入力してください。削除はheroku config:removeコマンドで可能です。

##データベースへの接続
あとはデータベースの接続を書き換えていくのみです。herokuの環境変数はgetenvで利用できます。

```php
$user=getenv('DB_USERNAME');
$password=getenv('DB_PASSWORD');
```
データベース名やホスト名も書き換えても良いでしょう。このように書き換えていけば、gitにパスワードやユーザーネームがアップされることなく、本番環境でデータベースに接続できます！

#最後に・・・
初学者なので理解が不足している部分もあるかもしれませんので、何かありましたらご指摘よろしくお願いします。