OmniAICreator/Qiita-1.07M huggingface dataset:
rails deviseについて　ログイン機能が使えるようになるまでの導入方法

#はじめに
##deviseについて
Gemの一種で、インストールすることで、ログイン機能周りの実装を容易にしてくれる。

##deviseを使うログイン機能実装準備の流れ

~~~ruby:Gemfile
gem 'devise'
~~~

ターミナルで
bundle installを実行。

devise（ログイン機能）を利用する場合は  devise専用のモデルを作成する必要がある。

ターミナルで以下のモデルの作成コマンドを実行
rails g devise ログイン機能を使用するモデル名

実行することで、deviseのマイグレーションファイルが作成されるので、
rake db:migrate実行

ここまでの作業を行うことで、
ログイン機能の概念を持つテーブルが作成され
ログイン周りの機能を使うことができるようになる。

用途によって、コントローラーファイルやビューファイルに
deviseのヘルパーメソッドを駆使して作成していく。

###ちなみに
ログイン・サインアップ画面は自動的に生成してくれるが、
これはdeviseが持っているビューであり、作成中用のビューファイルが作成されているわけではないので、別途ビューファイルを
作成する必要がある。
その際は、deviseコマンドで作成する必要がある。
rails g devise:views

##deviseの導入によって使用できるようになるヘルパーメソッド

・current_user
現在ログイン中のユーザーのレコード情報を取得することができるメソッド
例：current_user.name => "tarou"
・devise_for
ログイン関連で必要なルーティングを一度に生成してくれるメソッド
・user_signed_in?
ユーザーがサインインしているかどうかを確認してくれるメソッド。
サインしているかどうかでtrueかfaluseを返す。

・configure_permitted_parameters
追加したパラメータをストロングパラメーターで受け取りたい際に使用するメソッド
before_actionに指定する。
MiNiFiでRaspberryPiのカメラを制御し、写真をNiFiにアップロード、Hadoopに保存

# 1 Raspberry Pi側の設定

カメラを購入：
https://www.amazon.co.jp/gp/product/B07PSFFF47/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1
ラズベリーパイカメラ5メガピクセル1080 p / 30 fps 65度視野角カメラビデオモジュール、ラズベリーパイゼロ/ゼロW、アクリルホルダーとFFCフレックスケーブル付き
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/e97cb33f-3baa-0703-66d5-b478a17c897a.png)

モバイルの液晶モニターを購入：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/7e6f1d3d-24c3-80f1-6789-1c99e62fced4.png)
https://www.amazon.co.jp/gp/product/B07FDN3M8H/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1

繋いでこんな感じ：
![img_20190718_142240.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/75fbcdc9-1608-6817-d44b-0f904555200a.jpeg)

![img_20190718_142304.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/40130d1d-608a-d495-2e36-4d383fd1ca86.jpeg)
![img_20190718_142719.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/998443b4-59cf-24ba-c889-c8000ecacb12.jpeg)


# 2 NiFi 側の設定

Ambari設定：
<img width="2054" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/412cebc6-606e-ed2d-4586-37aa01c59507.png">

<img width="1179" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/627bc163-5235-4b63-9aa8-e8ef52ea39d7.png">


# 3 MiNiFi 側の設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/e8070161-fbd2-5a8b-d37b-a6544392bc73.png)

XMLファイルをYMLファイルに変換：

```
bin/config.sh transform ~/MiNiFi_Image_Capture_05.xml ~/MiNiFi_Image_Capture_05.yml
```

MiNiFi Agent 起動：
start.minifi.sh

```bash
export JAVA_HOME=/usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt

cd /home/pi/iot/minifi-0.6.0.1.0.0.0-54
bin/minifi.sh start
```


# 4 動作確認
NiFi側、画像をMiNiFiから受け取って、ローカルとHDFSに保存
必要であれば、HBASEに保存も出来る

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/27f4fb5b-d45f-8af5-b3b4-2c339309e0c0.png)

何らかの情報がNiFiに入ったことは分かるが、どんなデータが入ったかは、Provinance機能で中身を確認することが出来る：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/b53ce246-c48c-f078-12c7-825b210c79f0.png)

該当プロセッサーを通したProvinance一覧：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/e558dc11-51bf-7de8-1ae6-32cc14fc65ba.png)

個別データのProvinance詳細：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/eeeb2011-a0ff-8e3a-ae92-3267b638c6ae.png)

データの中身：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/314661c5-13b6-a477-a179-14cf78b9c9ea.png)
【JavaScript修行】アクセサーメソッドをしる（クロージャとdefineProperty)


>クロージャは、独立した (自由な) 変数を参照する関数です。言い換えるとクロージャ内で定義された関数は、自身が作成された環境を '覚えています'。

[参考：MDN](https://www.google.com/search?q=%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3+javascript&oq=%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3+javascript&aqs=chrome..69i57j69i60j0l2j69i61j0.6084j0j7&sourceid=chrome&ie=UTF-8)

なんだか意味深ですね。
わからなくて意味の深そうなものは全部意味深って言ってます。

早速だからクロージャをみてみます。

```javascript:クロージャ
function closure () {
    var value = 0;

    return function next(){
        value++;
        console.log(value);
    };
};

let n = closure();
n();   //1
n();   //2
n();   //3
```

戻り値が`function`になってます！
その`next()`の中で`value`を参照していますね。
`n`には`next()`が入っているので、呼び出すたびにvalueがプラス１されます。

##それでクロージャってなんに使うの？
先ほどの例では、ファンクションであるにも関わらず、前回のvalueの値を元に
どんどん加算することができています。
まるでオブジェクトみたいな使用ができるんですね。

そしてクロージャ役に立つ方法を知る為に、、まずプライベートメンバについてまとめます。

##プライベートメンバーって？
**プライベートメンバー**
・・・クラス内部からのみ呼び出せるプロパティ/メソッドのこと。
**パブリックメンバー**
・・・クラス内外から自由にアクセスできるメンバーのこと。

javascriptでは普通に定義するとパブリックメンバーになる。
→先ほどの**クロージャ**を使うことで擬似的にプライベートメンバーを定義できる！

```
var プロパティ名
var メソッド名　= function(引数,...){}
```

これをコンストラクター関数の中で定義することで、プライベートメンバーにできます！
this.ほにゃらら= って書かないんですね。

## プライベートメンバーにアクセスする方法
**特権メソッド(プリビレッジメソッド)**・・・プライベートメンバーにアクセスできるメソッド。
こいつらはコンストラクタ内で関数として定義する。⇨クロージャ！

```javascript:クロージャでプライベートメンバーを使う
function Neko(){

    var _voice = "mew";          //プライベートプロパティ
    var _intro = function(){     //プライベートメソッド
        console.log("猫です");
    };

    this.getVoice = function(){    //特権メソッド
        return _voice
    };
    this.getIntro = function(){
        _intro();
    }
}

var neko = new Neko();
console.log(neko.getVoice());    //mew
neko.getIntro();     //猫です
```

もう１つ、プロパティ自体にアクセスさせない定義方法をみてみます。

```javascript:アクセサーメソッド
function Neko(){

    var _voice;    //プライベートプロパティsetVo

    this.setVoice = function(voice){
        _voice = voice;
    }

    this.getVoice = function(){
        console.log(`${_voice}と鳴いた`);
    }
}

var neko = new Neko();
neko.setVoice('ミャー');
neko.getVoice();
```

プロパティを直接外部から操作せず、プロパティにアクセスする為のメソッドを準備しています。
こんなメソッドを**アクセサーメソッド**と言います。
また参照用メソッド（ここでいうgetVoice)を**ゲッターメソッド**,
設定用メソッド(ここでいうsetVoice)を**セッターメソッド**と細かく呼ぶこともあります。

##アクセサーメソッド
アクセサーメソッドなんて面倒くさいことしやがって！と思いましたが、
たくさんのメリットがあるようです。

①プロパティを書き込み専用にできる！
→ゲッターメソッドだけを用意すればいい！

②プロパティを読み取り専用にできる！
→セッターメソッドだけを用意すればいい！

③値の参照時にデータを加工できる！
→ミャーと鳴いた、というのがそうですね。他にも余計なデータをとったり付け足してわかりやすくしたり、、

④値の設定時に妥当性のチェックができる！
→おかしなデータを代入前に弾くことができますね。

でももっと簡単にアクセサーメソッドを実装する方法があるみたいです。
今までの方法はレガシー向けで使用していいみたいです。

##definePropertyメソッド

```javascript
Object.defineProperty(obj,prop,desc)
   //obj:プロパティの定義先のオブジェクト
   //prop:プロパティの名前
   //desc:プロパティの構成情報
```

`desc`に対してget/setパラメータを指定すると、ゲッター/セッターを定義できます。

```javascript:get/setパラメータ
function Neko(){
    var _voice;

    Object.defineProperty(
        this,'voice',
        {
            get:function(){
                return console.log(`${_voice}と鳴いた`);
            },
            set:function(voice){
                _voice = voice;
            }
        }
    )
}
var neko = new Neko();
neko.voice = 'にゃー';
neko.voice;   //にゃーと鳴いた
```
なきました！
Bundlerのバージョンをあげる方法

**あくまで個人メモ用**

### 概要

最近Ruby用のGem Bundlerが2.0版リリースされて、普段関わっているプロジェクトで新しいGemをインストールしようとしたら `You must use Bundler 2 or greater with this lockfile.` というエラーが返ってきますので、バージョンアップしないといけませんね。。


### バージョンアップ方法

```
# sudoで実行する必要があるときもある
$ gem install bundler
```

### 補足

bundler 2.x版しか持っていて、bundler 1.xが必要とされた場合はこちらで古いバージョンをインストールするといい。

```
# (~>1.0 で指定すると1.0の中の最新版がインストールされます)
$ gem install bundler -v "~>1.0"
```
No such file or directory, 今日のshell error(31)

docker(26) docker耐久試験
https://qiita.com/kaizen_nagoya/items/83aa733001ae7026bf70

で、shellコマンド、いくつかやらかしました。

# ファイル名の途中に空白

```shell-session:docker/ubuntu
# cat data27 data27 data27 > data 81
cat: 81: No such file or directory
```

「data81」とすべきところを、手がすべって「data 81」と間に空白を入れた。
気がつかずにリターンキーを押した。

結果、dataというファイルが上書きされてしまった。

幸い、作業は1が続くファイルのでかいのを作っていただけだから実害はない。

```shell-session:docker/ubuntu
# ls -al
total 65956
drwxr-xr-x 1 root root     4096 Jul 18 04:01 .
drwxr-xr-x 1 root root     4096 Jul 18 03:54 ..
-rw-r--r-- 1 root root 27206361 Jul 18 04:01 data
-rw-r--r-- 1 root root  9068787 Jul 18 04:00 data27
-rw-r--r-- 1 root root  1007643 Jul 18 04:00 data3
-rw-r--r-- 1 root root 27206361 Jul 18 04:01 data81
-rw-r--r-- 1 root root  3022929 Jul 18 04:00 data9
```

一時的とはいえ、無駄なファイルを作る時間だけ無駄。
data81作成は１秒くらい。

# コマンドを入れ忘れ

```shell-session:docker/ubuntu
# d6561 d6561 d6561 > d19683
bash: d6561: command not found
```
実際には、

```
# cat d6561 d6561 d6561 > d19683
root@70f17570ad1c:/opt# ls -al
-rw-r--r-- 1 root root 6611145723 Jul 18 04:09 d19683
```
この処理約10分。

catでデータ増やさなくても、プログラムで増やしゃいいんですが、
プログラムが動いている最中にディスクいっぱいで止まるのがいやだった。

複写にかかる時間から、もうこれくらいという限界を知ろうかなという作業中。

# Reference
Error一覧 error(0)
https://qiita.com/kaizen_nagoya/items/48b6cbc8d68eae2c42b8

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong.
### 文書履歴(document history)
ver. 0.01 add URL　20240508
### 最後までおよみいただきありがとう4ざいました。
いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
link_to ブロック全体をリンク化する。

link_toで文字列ではなく要素全体をlink化したい。

<img width="751" alt="スクリーンショット 2019-07-18 14.49.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442488/492b4ba1-2b5d-44bd-2e08-ee46693aba8b.png">



<img width="536" alt="スクリーンショット 2019-07-18 14.47.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442488/d3ab5c83-d17f-d258-f0f2-a5b978c59714.png">

link化したい要素の”上”にlink_toを書き、要素全体をネストさせればOK。
link_to の後にdoをつけるのを忘れずに！
hamlなのでendは不要。
Gitのコマンド色々

# Gitのコマンドメモ


### 直前のpushを取り消したい
※この場合コミットは消えてしまいます。

```
// 直前のコミットを取り消す
git reset --hard HEAD^
// この状態だとローカルだけなので強制的にPushする
git push -f origin master
```


### ローカルのコミットはそのままで、pushだけ取り消したい

pushの戻すSHA-1を指定する
※指定したpushが最後のpushになる

```
// リモートブランチへの参照を強制的に変更する
$ git push -f origin ??????:branch_name
```

1つ前のpushを取り消したい場合は、2つ前のSHA-1
これやるだけで、pushの必要ない

### コミットをまとめたい

```
// 2つ前のコミットまでをまとめる ~ の数で制御
git rebase -i HEAD~~
```
エディタが立ち上がるのでどうするか決めてから保存

```
p、pick =コミットを使用
r、reword =コミットを使用しますが、コミットメッセージを編集します
e、edit = コミットを使用しますが、修正を中止します
s、squash =コミットを使用しますが、前のコミットにまとめる
f、fixup = "squash"のようですが、このコミットのログメッセージを破棄します
x、exec =シェルを使用してコマンドを実行（残りの行）
```

### リモートのブランチ名を変更したい



### ローカルの参照？を移動する方法

#### 前に戻す→reset

```
git reset --soft HEAD^
git reset --soft ???SHA
```

HEAD^は直前のコミットを指す
HEADの所を、SHAにすれば目的のコミットまで戻れます。
--softで移動している限りは、コミットが消えたりしない。

・Sourcetreeでいうと、右クリックの"現在のブランチをこのコミットまでリセット"と同じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191647/ff175790-1f2b-0991-9c6e-30759ea40fad.png)

・IntelliJ IDEAでいうと、右クリックの”現在のブランチをここにリセット”
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191647/963dda7a-e2c3-b8e0-90e5-ad2c3218b7f9.png)


#### 元に戻す pull
サーバーにすでにプッシュしてあるケースの場合は、元の所に戻すには単純にpullすればよい

こう考えると、pullというのは、サーバー側の参照にローカルの参照を追いつかせるみたいな感じなのかな？



### サーバーの参照を移動する方法
iTerm2の設定いろいろ

# iTerm2の設定いろいろ

## いろいろ
* DL
    * https://www.iterm2.com/
* 表示ログを無限にする
    * メニュー → 「iTerm2」 → 「Preferences」→ 「Profiles」→ 「Terminal」→ 「Unlimited scrollback」 → チェックする
* Macを終了する時にiTermの終了確認を出さない
    * メニュー → 「Preference」 →
        * 「General」 → 「Closing」 → 「Confirm ”Quit iTerm2 (⌘Q)" if windows open」 → チェックを外す
        * 「Profiles」 → 「Session」 → 「Closing」 →
            * 「 Automatically close a session when it ends」 → チェックする
            * 「Do not prompt before closing」 → チェックする
* タブ移動のショートカットを変更
    * メニュー → 「Preference」 → 「Keys」 → 「Next Tab」/「Previous Tab」 → すきなショートカットを割り当てる
* タブを開くたびに自動でログファイルの記録を開始する
    * メニュー → 「Preference」 → 「Profiles」 → プロファイルを選択する → 「Session」 → 「Automatically log session input to files in:」 → チェックする → ディレクトリを選択する
* 開発と本番でプロファイルを分ける。開発と区別するために背景色を変えるとか
    * メニュー → 「Preference」 → 「Profile Name」 → 今のプロファイルを選択する → 「Other Actions」 → 「Duplicate Proile」 → 新しいプロファイルを選択する → 「General」 → 名前を変更する。"Release"とか → 「Color」 → 「Color Presets」 → 好きなテーマを選ぶ
Moneroを64コアのPCで(CPU)マイニングしてみる


#UbuntuでCPUマイニング
通貨はMonero、マイニングプールは[monerohash](https://monerohash.com/#)を利用。
walletは本家が出してる[wallet(デスクトップ)](https://www.getmonero.org/downloads/)
マイニングソフトはxmr-stakを使った。(xmr-stak-cpuではない！こっちはうまくいかない)

メインのやり方はこれを参考に
https://www.youtube.com/watch?v=gvQQEFF1XdY


##結果
Hash Rate: 2000H/sくらい
MacでAWS CLIをインストールして、コマンドでS3にバケットを作る

## はじめに

下記の公式ページを参考にAWS CLIをインストールします。

[macOS に AWS CLIをインストールする](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-macos.html)

その後、コマンド操作でS3にバケットを作成するまでを行います。

## AWS CLIとは

AWS CLI(AWS Command Line Interface)はコマンドを使用して、マネジメントコンソールと同等の操作をすることができるツールです。

慣れるとこっちの方が早そうです。

## インストールしたMacOS

macOS High Sierra
バージョン 10.13.6

## 前提条件

> Python 2 バージョン 2.6.5+ または Python 3 バージョン 3.3+

Python2の場合は2.6.5以上でPython3の場合は3.3以上が条件のようです。
下記のコマンドでPythonのバージョンを確認できます。

```
$ python --version
Python 2.7.10
```

インストールできているみたいなので、前提条件はクリアです。

## AWS CLIをインストール

インストーラをダウンロード

```
curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
```

パッケージを解凍

```
unzip awscli-bundle.zip
```

インストールプログラムを実行
※パスワード入力あり

```
sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws
```

下記のコマンドでバージョンを確認できればインストール完了!

```
aws --version
```

例えばs3を操作したいときのヘルプを見ることもできます。

```
aws s3 help
```

## AWS側の設定

IAMユーザーページの認証情報タブからアクセスキーを作成します。
作成したら下記のコマンドを入力し、さらに入力が求められるのでリストの順番で設定します。

```
aws configure
```

- アクセスキーID
- シークレットアクセスキー
- デフォルトリージョン名（東京リージョン：ap-northeast-2）
- アウトプットフォーマット（例：json）

## S3にバケットを作成

mbコマンドでS3にバケットを作成できます。
が、実行してみるとエラーになりました。

```
$ aws s3 mb s3://testbacket

make_bucket failed: s3://testbacket An error occurred (BucketAlreadyExists) when calling the CreateBucket operation: The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again.
```

S3のバケット名は全世界で一意のものでないとだめらしいです。
他の人と被っちゃダメなんですね。 `testbacket` なんていかにも被りそう。

`testbackettest-20190718` 命名センスないですが、とりあえずこれで作成できました。

```
$ aws s3 mb s3://testbackettest-20190718
make_bucket: testbackettest-20190718
```

## おわりに

下記のページで最新のCLIコマンドリファレンスを確認できます。
コマンドで何か操作したくなったらこちらで確認するように心がけるといいと思います。
こういうリファレンスを読める系のエンジニアになりたい。。。

[AWS CLI Command Reference](https://docs.aws.amazon.com/cli/latest/reference/)
ディープラーニングG検定を受けました！

# はじめに
ディープラーニングG検定を受験したので、それに向けて学習したことをご紹介します。
私は読書も勉強もすごく苦手なのですが、同じような方の参考になれば幸いです:sweat_smile:

# G検定って？
一般社団法人 日本ディープラーニング協会(JDLA)が実施している試験です。
G検定（ジェネラリスト）、E資格（エンジニア）があります。
G検定は年3回、E資格は年2回くらいの頻度で試験をやっているようです。
詳細：[JDLA資格試験](https://www.jdla.org/business/certificate/)

私はDevelopers Summitの書籍販売で公式テキストを見つけ、試験の存在を知りました。

# やったこと
## 書籍：[深層学習教科書 ディープラーニング G検定（ジェネラリスト） 公式テキスト](https://www.shoeisha.co.jp/book/detail/9784798157559)
まずはこれを読みました。
人工知能研究の歴史やディープラーニングの仕組み・応用などの解説があり、章末に確認問題も付いています。
ただ、細かいロジックについては触れずに概略的に説明されているものもあり、正直これを読んだ時点ではディープラーニングの仕組みがあまり理解できていませんでした。
用語の目次も付いていたので、あとで単語を忘れてしまった時のリファレンスとして使っていました。

## 書籍：[人工知能は人間を超えるか ディープラーニングの先にあるもの](https://www.kadokawa.co.jp/product/321410000316/)
Qiitaなどで試験対策として挙げている方が多かったので読んでみました。
最初は試験対策として読もうとしていたのですが、読み物として普通に面白かったです:slight_smile:
説明がとてもわかりやすく、歴史のことやディープラーニングの仕組みも簡単な言葉で例え話を交えて書かれていました。
公式テキストを読んだときはオートエンコーダが何なのかすらよくわかっていなかったのですが、この本では「そういうことか！！」と理解できて感動したのをよく覚えています。

帯に**「人工知能を知ることは、人間を知ることだ。」**とあるのですが、確かに読んだ後に「人間すげー」と思いました。
例えば、どの角度やどんな明るさから見ても「これは猫だ」とか「〇〇さんだ」と見分けられることなど、私たちが普段何気なくやっていることが、コンピュータで何十年も実現できなかったような難しくて複雑なことなんだなーと:thinking:

あと、本が苦手な私でもすごくよく理解できたので、「松尾先生すげー」と思いました:rolling_eyes:

## [Study\-AI](http://ai999.careers/tools/)の模擬テスト
これもQiitaなどで試験対策として挙げている方が多かったのでやってみました。
やってみたらまだまだ覚えられていない・理解できていない単語が多く、再度学習し直す必要があることがよくわかりました:disappointed_relieved:
でもこれが無料（要登録）でできることに感激です…！

## わかっていなかった単語を復習
上記の模擬テストで、理解できていないことを単語レベルで書いておき、それを公式テキストやWebで調べて整理しました。
ノートに自分で図を書いたり重要単語の意味を書いたり・・やはり自分で書くと、よくわかっていないところも明らかになってよいですね。
実はいままで資格試験を受けてきたときも、あまりノートにまとめたりしてこなかったのですが、もっと早くやっておけばよかったです:sweat_smile:

試験本番までに全ての単語を調べきれなかったのですが、直前に再度Study-AIの模擬試験を解きながら理解を確認しました。

# そして試験本番
試験は自宅などでWeb試験で受けられます。
120分で226問⇒だいたい1分で2問解答しなければならないので、結構ハイペースで答えていく必要があります:sweat_drops:
ただ、文章の穴埋め問題はそれぞれの穴で1問（アに入る言葉を選ぶのに1問、イに入る言葉を選ぶのに1問）になっているものもあるので、このような問題は比較的スムーズに進められました。
Study-AIの模擬試験にあった問題によく似たものも出題されたので、やっておいてよかったです！
最近制定された法律に関する問題などもあり、この辺りはカバーするのが大変そうです。（ほとんど勘で答えていたので自信ありません）

# 結果・・・
1週間以内に結果のメールがありました。
**無事合格できていました！！:dart:**　よかったです:innocent:
いままでなんとなくしか理解できていなかったディープラーニング・機械学習ですが、今回の学習で少しだけわかってきた気がしました:ok_hand:
VSCodeの拡張機能を特定のバージョンに簡単に戻す方法

VSCodeの拡張機能が更新によって動かなくなってしまい困るということは稀にあります。特にVimの拡張機能など入力方法に関わるものが壊れてしまうと、開発効率は大幅に下がってしまうでしょう。

## これまでの拡張機能の特定バージョンへの戻し方
VSCode Extension version などでググると以下のようなブログが見つかります。パッケージファイルを手動でダウンロードしてきてVSCodeに適用するというやり方です。過去にはこれ以外には特に方法がなかったわけですが、地味に面倒な作業となっていました。

https://qiita.com/binary2/items/a14ed7c6ee352ccf9e62
https://inocop.hatenablog.com/entry/2018/03/14/135252

## 現在の拡張機能の特定バージョンへの戻し方
実は、2018年の12月にリリースされた?v1.30系からは、過去のバージョンをインストールする方法が公式にサポートされています。 対象のExtensionの ⚙ マークをクリックして `Install Another Version...` をクリックするだけです。

![downgrade-Extension.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76861/1a066b77-04aa-6f54-f673-991adaa38de0.gif)

https://code.visualstudio.com/updates/v1_30#_install-previous-versions

私はこれまで、拡張機能が壊れたときは作業が面倒で修正バージョンが出るまで待っていたりもしたのですが、現在はこのように簡単に過去のバージョンが入れられるようになっているようです。もう進捗をVSCodeのせいには出来ませんね。

いかがでしたかry(
ruby on railsのスクレイピングについて質問です。

<div id="main">
<a href="アドレス">test</a>
</div>

この中のhref属性のアドレスを取得したいのですが、
mechanizeオブジェクトのserachメソッドでidを取得条件に入れ
ることができません。何か方法はありますでしょうか？

<scraping.rbのソースコード>
agent = Mechanize.new
current_page = agent.get("取得先のwebサイトのアドレス")
elements = current_page.search("div#main")

elements.each do |ele|
links << ele.get_attribute('href')
puts links
end

linksの中身がnullで、うまく取得できていません。
【Corda 4.X】詰まったところメモ

どーものぶこふです。

今回はCorda4系を使っていくうえで、少しハマったところをメモ書き程度に記述しておきます。
※秋頃には5.0がでるとかなんとか・・・

## ＜FinalityFlow＞には、参加者全員のセッションリストが必要
```terminal:こんなエラーが出ます
java.lang.IllegalArgumentException: Flow sessions were not provided for the following transaction participants:
```
### 対応
```kotlin:otherSessionに適切なPartyを指定する
val counterPartySession = initiateFlow(counterParty) //←適切なPartyを指定
val fullySignedTx = subFlow(CollectSignaturesFlow(signedTransaction, setOf(counterPartySession)))
subFlow（new FinalityFlow（fullySignedTx、counterPartySession）
```

### 参考
https://stackoverflow.com/questions/56445751/java-lang-illegalargumentexception-flow-sessions-were-not-provided-for-the-foll

くりす「Corda4から、FinalityFlowにはトランザクション参加者全員のセッションリストが必要になったのさ」（※意訳）

## 自身に対してFlowを実行するとエラーが発生する
```terminal:こんなエラーが出ます
Do not provide flow sessions for the local node. FinalityFlow will record the notarised transaction locally.
```
### 対応
```kotlin:emptyListを渡す
subFlow(FinalityFlow(signedTransaction, emptyList()))
```

※自身に対してFlowを実行するのが確実なのであれば、`CollectSignaturesFlow`などは不要ですね

### 参考
https://stackoverflow.com/questions/56425416/flow-error-when-trying-to-initiate-a-new-iouflow
↓
https://groups.io/g/corda-dev/topic/flow_issues_in_4_0_rc4/29986269?p=,,,20,0,0,0::recentpostdate%2Fsticky,,,20,2,0,29986269

まいくはーん「emptyListを渡せば解決するでよ！！」（※意訳）

## 【追記】2019/07/19：＜CollectSignaturesFlow＞実行時に、署名が過不足しているとエラーが発生する
```terminal:こんなエラーが出ます
The Initiator of CollectSignaturesFlow must pass in exactly the sessions required to sign the transaction.
```
### 対応
```kotlin:適切な数のセッションリストを作成して渡す
// 適切なセッションリストを作成する
val counterPartySession1 = initiateFlow(partyA)
val counterPartySession2 = initiateFlow(partyB)
val sessionList = setOf(counterPartySession1,counterPartySession2)
// そのセッションリストを渡す
val fullySignedTx = subFlow(CollectSignaturesFlow(signedTransaction, sessionList))
```

## おわり

そんなこんなで、Cordaと戯れています。

今回はここまでです。
ありがとうございました。
Ruby on RailsでテストDBと開発環境DBに差分がある際に実行すべきコマンド

## はじめに
`migrate`や`rollback`の繰り返し等で開発環境のDBとテストDBに差分ができて、RSpecでテストを実行してエラーが起きた際に実行すべきコマンドを紹介します。

### Rails4系の場合

```
rake db:environment:set RAILS_ENV=test
rake db:migrate:reset RAILS_ENV=test
```

###Rails5系の場合

```
rails db:environment:set RAILS_ENV=test
rails db:migrate:reset RAILS_ENV=test
```
MacのExcelでUTF-8のCSVが文字化けするときにCSVにBOMをつけてみる(非エンジニア向け)

## こういうときに便利

UTF-8でできているはずのCSV、Excelで開くと日本語のところが文字化けするとき。

そこで、UTF-8のBOM ([バイトオーダーマーク](https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%88%E3%82%AA%E3%83%BC%E3%83%80%E3%83%BC%E3%83%9E%E3%83%BC%E3%82%AF))　をつけてあげて、Excelに文字コードを教えてあげるとうまくいく(ことがある)


## 準備

* CSVをDesktopに配置する
* Terminal.appを起動
   * ⌘+スペースキーでspotlight検索を起動
   * terminal.appと入力してエンター

## 手順

以下、

元のCSVを moto.csv、
変換後を result.csvとする。

1. `echo -n '\xEF\xBB\xBF' > ~/Desktop/result.csv` ... result.csvにBOMを書き込み
1. `cat  ~/Desktop/moto.csv >> ~/Desktop/result.csv` ... result.csvにmoto.csvを書き込み

以上です。


## 付録

先頭200000行だけをコピーする

`$ head -200000  ~/Desktop/result.csv > ~/Desktop/result_200000.csv`
今日の学習

##やったこと
・実際にformタグを使い簡単な問い合わせ画面を作る。
・railsチュートリアル２章の知識を用いて、task管理アプリを作る。
##学んだこと

**type属性**
```input type="text"```
属性の値を"text"と表示すると1行のテキストを入力できるフィールドができる。

**name属性**
```input type="text" name="mail"```
フィールドを特定する名前を半角英数で指定する。（わかりやすい名前で）

**textareaタグ**

nameタグは上記と一緒
```textarea name="comment"```

**cols属性**
テキストフィールドの横幅を指定。
属性を指定しない場合は約２０文字である。
```textarea name="comment" cols="30"```

**rows属性**
rows属性を"5"に指定すると5行分程度の高さでフィールドが表示されます。5行しか入力できないという数字ではなく、あくまでも表示される高さの目安として設定する。
```textarea name="comment" cols="30" rows="5"```

**送信ボタンの作成**
最初のinputタグを使いtype属性にsubmitを指定する。
```input type="submit"```

**value属性**
ボタンに表示する文字を指定する。
```input type="submit" value="確認する"```

##難しくてハマったところ
・githubにpushする際に下記のようなエラーがでた。
```fatal: 'git@github.com/自分のアカウント/samurai_app' does not appear to be a git repository
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.```
拡張for文とlengthを用いたfor文が同じ処理であることを理解するまで（多次元配列を扱う）

## はじめに

配列の要素を1つずつ取り出すループについて、for文で繰り返し条件にlengthを用いて書くことができます。

さらに、拡張for文ではそれと同じ処理をよりシンプルに書くことができるのですが、「2つの処理がなぜ同じになるのか」についていまいち理解できていませんでした。

そこで今回は、多次元配列を用いて、2つの処理がなぜ同じになるのか、そしてそれをどのように理解したのかについてこの記事でご紹介したいと思います。

## 拡張for文で書く

今回は次の三次元配列を例に、各要素についてplintlnメソッドで出力します。

```java

int[][][] array = { { { 1, 2 }, { 3, 4 }, { 5, 6 } }, { { 7, 8 }, { 9, 10 }, { 11, 12 } } };
```

まず、拡張for文で書いてみます。

```java

for (int[][] tmp1 : array) {
    for (int[] tmp2 : tmp1) {
        for (int tmp3 : tmp2) {
            System.out.println(tmp3);
        }
    }
}
```

1から12までの整数がコンソールに出力されます。

## 従来のfor文で書く

次に、繰り返し条件にlengthを用いた書き方です。

私はlengthを用いて書くとき、これまでは次のようにして書いていました。

```java

for (int i = 0; i < array.length; i++) {
    for (int j = 0; j < array[i].length; j++) {
        for (int k = 0; k < array[i][j].length; k++) {
            System.out.println(array[i][j][k]);
        }
    }
}
```

`array[i][j][k]`を見ると、配列の要素を1つずつ取り出しているんだな、ということがわかります。

しかし、これを上の拡張for文と見比べてみたときに、同じ処理をしているということがすぐには理解できませんでした。
私が「いまいち理解できない」と感じていた部分はここにあります。

そこで、lengthを用いた書き方について、次のように書き直してみました。

## lengthを用いた書き方について、拡張for文に近い形で書く

```java

for (int i = 0; i < array.length; i++) {
    int[][] tmp1 = array[i];
    for (int j = 0; j < tmp1.length; j++) {
        int[] tmp2 = tmp1[j];
        for (int k = 0; k < tmp2.length; k++) {
            int tmp3 = tmp2[k];
            System.out.println(tmp3);
        }
    }
}
```

`int[][] tmp1 = array[i];`を省略せずに書くことで、拡張for文とほぼ同じ形にすることができました。

## まとめ

lengthを用いた書き方だけで見るならば、`array[i][j][k]`を用いた書き方のほうが何の処理をしているのかについてはわかりやすいのですが、どうして拡張for文と同じ処理になるのかについては、`int[][] tmp1 = array[i];`を省略せずに書いたほうがわかりやすいかと思います。

もし私と同じように「なぜ2つの処理が同じになるのか」についていまいち理解できないという方がいらっしゃるようでしたら、この記事が理解の一助となれば幸いです。
KibanaでUiPath Orchestratorデータの出し入れ

##前提

elasticsearch　⇔　elasticsearch間のデータバックアップ/復元については、
[便利な記事](https://qiita.com/nakazii-co-jp/items/3199433d685d0600c6d6)があるものの、

kibana  　⇔　  kibana間のデータバックアップ/復元については、Webに情報が見受けられない

※[追記7/18][kibana設定のエクスポート/インポートは採掘](https://qiita.com/tsukapah/items/91cb093ddfa6ede10b02)

Uipath Orchestratorのログのデータを対象に、上記実施する。
【実験的な機能も触っており、あくまで試行錯誤のログです】

***
###環境

|項目|内容|
|----|----|
|kibana|7.1|
|elasticsearch|7.1|
|ライセンス|basic|

***

##エクスポート

トップで表示される画面ですが、
画面左上「Discover」でない場合、時計のアイコンクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198177/a17bc042-7d59-292b-9580-ad1440b706da.png)



期間を指定して[UPDATE]、
「SAVE」で検索結果を保存

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198177/c64ab864-e244-cd7c-4993-c03ad2fb92a3.png)


[SAVE]右の[Open]　> [Manage searches]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198177/3efc837a-e85a-7db6-e054-c00a04e644c9.png)

[Export]から[SAVE]したオブジェクトをエクスポート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198177/418ebaf9-ecb3-0b15-96b5-85bd1f64e4dd.png)



※ConsoleからあるIndexのデータを全容取ることを考えましたが、Elasticsearchをクエリで叩き、jsonデータをもってくることができず、断念。。。

##インポート

kibanaでデータインポートを行う場合、
1)エクスポートと同様に、Management > Saved Objects から行う


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198177/8086a0a3-c178-72e5-43b2-d0f3cd633a82.png)


2)( 1と別パターン)Machine Learnning　 >  Upload file 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198177/94e1e16d-a283-9c0e-b6f0-4771cb40472a.png)

`json or CSV or TSVファイルを指定`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198177/1e4286df-d471-663a-0e89-84a7101549d3.png)

画面左下、[Import]をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198177/80c19f5e-a1ef-fd91-eb3d-85706a46d562.png)

`indexパターン新規作成 or notを選択`
※indexパターンを新規作成すると、indexも同名で作成される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198177/0b780bbc-a881-6afe-e2e8-03287dacf79c.png)

インポートが完了する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198177/32116877-094a-d78c-761b-4855e6bc7759.png)

2通りのインポートのうち
後者ではCSV、TSVのインポートも可能




##備考
・エクスポートの手順で吐き出されたjsonの中身をみていると、メタデータが出力されるようで、
indexの値が取得できているか確認中

・確実にindexの値を出力するにはelasticdumpで出力するのがよさそう。
`json整形の手間が省ける`

・Uipath Orchestratorについては、監査ログはCSVで出力可能で、インポートを実証。
SQL Server のLogテーブルの値については未実証。
CWL では、同じCWLファイル内では、ユニークなidを付ける必要がある

# 概要

以下のようなエラーがでた。

```
samtools-view.cwl:16:3: object id `samtools-view.cwl#output_bam` previously defined
```

# 結論

CWL では、同じCWLファイル内では、ユニークなidを付ける必要がある

なので、

- `inputs と outputs で、同じ名前をつけることはできない。`

例、 CommandLineTool で、 `output_bam` を、 `inputs` と `outputs` とで定義している。

- [Fix output parameter for samtools\-view\.cwl by tom\-tan · Pull Request \#24 · pitagora\-network/DAT2\-cwl](https://github.com/pitagora-network/DAT2-cwl/pull/24/files)

エラーとしては、以下のようになる。

```
samtools-view.cwl:16:3: object id `samtools-view.cwl#output_bam` previously defined
```

該当のファイルは、こんなかんじ。

# 参考情報

Workflow 定義の中の、インラインで書くときも似たような問題があることがあるが、
v1.0 と v1.1 では違う可能性もあり。
このあたりは、調べてまた書く予定。




- [１６行目がハイライトしている。３４行目が変更後の状態](https://github.com/pitagora-network/DAT2-cwl/blob/c4af9f4209d8ab1a8a440da076282daef98ffc3b/tool/samtools/view/samtools-view.cwl#L16)
githubのPRのブランチを取得する

# githubのPRのブランチを取得する

## 何がしたいの
* githubのupstream(fork元)のブランチではなくPRされたブランチを取得したい
    * 以下だとupstreamのブランチ一覧が取れてしまう。それではない
    * リモート登録

        ```shell
        git remote add upstream git@github.com:docker/docker-ce.git
        git remote add pr git@github.com:docker/docker-ce.git
        ```
    * こうやってPR一覧が取りたい

        ```shell
        git pull pr
        git branch -vv -r | sort -V | grep ' pr\/' | tail -n5

        pr/610/head            28ef26b589 bump ver 18.09.7-rc1
        pr/611/head            f53f261a1d bump ver 18.09.7
        pr/612/head            704d67880e bump ver 19.03.0
        pr/613/head            6c4ac5b4bf bump ver 18.09.8
        pr/614/head            64c32a4ada added entry to changelog
        ```
    * でも実際にはupstreamと同じでブランチが取れるだけ

        ```shell
        git pull pr
        git branch -vv -r | sort -V | grep ' pr\/' | tail -n5

        pr/18.05         f150324782 Merge pull request #527 from andrewhsu/g
        pr/18.06         a464a87eb6 Merge component 'packaging' from git@github.com:docker/docker-ce-packaging 18.06
        pr/18.09         0dd43dd87f Merge pull request #613 from andrewhsu/1809ga
        pr/19.03         aeac9490dc Merge pull request #614 from andrewhsu/1903cl
        pr/master        93c825c44e Merge component 'engine' from git@github.com:docker/engine master
        ```


## やり方
* リモート登録
    * 登録

    ```shell
    git remote add pr git@github.com:docker/docker-ce.git
    vi ./.git/config
    ```

    * `.git/config` の変更

    ```
    [remote "pr"]
            url = git@github.com:docker/docker-ce.git
    #        fetch = +refs/heads/*:refs/remotes/pr/*
            fetch = +refs/pull/*:refs/remotes/pr/*
    ```
* PRの一覧が取れるようになった

    ```shell
    git pull pr
    git branch -vv -r | sort -V | grep ' pr\/' | tail -n5

    pr/610/head            28ef26b589 bump ver 18.09.7-rc1
    pr/611/head            f53f261a1d bump ver 18.09.7
    pr/612/head            704d67880e bump ver 19.03.0
    pr/613/head            6c4ac5b4bf bump ver 18.09.8
    pr/614/head            64c32a4ada added entry to changelog
    ```
Cognos Analytics ダッシュボード 複数のオブジェクトの連動

#ダッシュボードの複数のオブジェクトの連動
ダッシュボード内に、クロス集計と棒グラフを配置し、連動性を確認します。
<img width="719" alt="012.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/fd982a25-f2fb-5220-da90-80ae1f93b336.png">

#手順
D1.Dashboardを開始点とする。
チーム・コンテンツから、「D1.Dashboard」を選択。
<img width="337" alt="001.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/4f875ede-7b36-66ba-9e31-34c2f6986fa6.png">

参照オンリーモードで開かれるので、赤枠の「編集に切り替え」アイコンを選択。
<img width="886" alt="002.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/6d0fb647-3e4c-ac7a-e91b-dcc0c1df37f9.png">

縦棒グラフを図の位置に配置。
<img width="791" alt="003.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/a7124982-8a57-5c8a-55e2-f480253b3452.png">

横棒に「発注方法」の下の「発注方法のタイプ」、長さに「販売の実状」の下の「収益」、色に「製品」の下の「製品ライン」を配置。
<img width="876" alt="004.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/b5a3dc62-8536-f0a9-95e4-3330ffff59da.png">

「省略」をして、適当な場所・サイズに棒グラフを調整する。
<img width="960" alt="005.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/1256e572-8c3a-f7fb-08d1-69f6f1bdb545.png">

クロス集計の行の「キャンプ用品」を選択すると、連動して、棒グラフのキャンプ用品の棒がハイライトされる。
<img width="722" alt="006.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/68c166ac-16f6-14b8-b117-354f1041f6c4.png">

クロス集計の「キャンプ用品」と「2011」の交点を選択すると、棒グラフは2011年に販売されたキャンプ用品でフィルタされた表示になる。
<img width="739" alt="007.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/af67def6-907e-7087-9610-48feee0ee4c6.png">

もう一度「キャンプ用品」と「2011」の交点を選択すると、棒グラフのフィルターも解除される。
<img width="739" alt="008.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/3c24d9ed-3c37-0f22-e142-2beed8aa55e0.png">

明示的にフィルターを作成する事もできる。
「年」を「このタブ」のフィルターの位置にドラッグ&ドロップ。
<img width="960" alt="009.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/8659fb24-0db6-705c-12d0-34b5da7eb4b2.png">

「2010」と「2012」を選択して「OK」すると、
<img width="231" alt="010.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/f18a1f96-1fce-3c59-07aa-37539bdd6e93.png">

ダッシュボード内のクロス集計と棒グラフが、指定したフィルター条件で絞り込まれる。
<img width="739" alt="011.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/8ff7f238-00cf-96ec-a31b-dfa2b707a3a6.png">

この状態でもクロス集計と棒グラフの連動はできる。
<img width="719" alt="012.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/d0b1c2e5-dfc3-9759-0e83-5d7cbc846bea.png">

ダッシュボードを「D2.Dashboard」として保存する。
<img width="960" alt="013.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/244e5c4e-0b74-12cc-47a3-5f38f64d8159.png">


#自己学習記事一覧
**Cognos Analytics をエンドユーザーの方に自己学習して頂くためのサイト**
https://qiita.com/shinyama/items/95885c7246dc413b6448
MacでHMDなしVive Trackerを使う

Windowsでやれよって話なのだが、
Vive TrackerをHMD無しで使うデモを作るにあたり、
使い慣れているMacの環境でさくっと試したかった。
ただ、Macでやるリファレンスがあまりなかったので、メモ程度に残しておく。

## 環境
- OSX 10.14.5(Mojave)
- Unity 2019.1.8f1
- SteamVR Unity Plugin v2.3.0

## 手順

下記を参考にしながら進める

[【Unity】ViveのHMDなしにTrackerを使う](http://shop-0761.hatenablog.com/entry/2018/01/08/034418)


### VRSettingsを変える

Macの場合、`default.vrsettings`のパスは下記(結構深いところにある)

`~/Library/Application Support/Steam/steamapps/common/SteamVR/SteamVR.app/Contents/MacOS/runtime/resources/settings/default.vrsettings`

### Unity側の設定

Player SettingでVirtual Reality Supportedのチェックを外す
が、勝手にチェックが入る

consoleに

```
[SteamVR Setup] Enabled virtual reality support in Player Settings. (you can disable this by unchecking Assets/SteamVR/SteamVR_Settings.autoEnableVR)
```

と出ているので、`Assets/SteamVR/Scripts/SteamVR_Setting.cs` で`autoEnableVR`を`false`にする
が、まだ勝手にチェックが入る(なぜ？)

あまり深追いせず、取り急ぎ `Assets/SteamVR/Editor/SteamVR_AutoEnableVR`の54~56行目をコメントアウトする

```
if (UnityEditor.PlayerSettings.virtualRealitySupported == false)
{
    //UnityEditor.PlayerSettings.virtualRealitySupported = true;
    //enabledVR = true;
    //Debug.Log("<b>[SteamVR Setup]</b> Enabled virtual reality support in Player Settings. (you can disable this by unchecking Assets/SteamVR/SteamVR_Settings.autoEnableVR)");
}
```

他は参考サイトの通りでトラッキングできた。

## 参考
[【Unity】ViveのHMDなしにTrackerを使う](http://shop-0761.hatenablog.com/entry/2018/01/08/034418)
Android Beta版 USB経由でインストール方法

## 目次
1. Beta版のジップファイルをダウンロードし、解凍しておく
2. Android Studioをインストール
3. Javaの設定
4. Android Studio初期設定
5. SDK Locationの確認
6. bash_profileにAndroid SDKのパスを記入する
7. コマンドで改て読み込む
8. ブートローダーをアンロックする手順
9. ブートローダーをロックする手順
 
 
---
 
### 1.Beta版のジップファイルをダウンロードし、解凍しておく
 
 
### 2.Android Studioをインストール
https://developer.android.com/studio/index.html
 
 
### 3.Javaの設定
インストールしてアプリを開くと、最初にJavaが入っていないという内容のダイアログが表示されるので、下記URLでインストール。
Javaダウンロード
https://support.apple.com/kb/DL1572?viewlocale=ja_JP&locale=en_US
※入っている場合は表示されないので、この項目はスルー
 
 
### 4.初期設定
ダイアログが表示されていくので、下記の順に設定
- Complete Installation 画面で Do not import settings選択
- Java Settings 画面で Detect をクリック
→JDKの場所が自動で設定されない場合は、青文字をクリックしてJDKをインストール
- Install Type 画面で Standard を選択
後は指示通りして完了
 
 
### 5.SDK Locationの確認
SDK Locationの確認は、Android Studioのホーム画面右下Configureを押下→Project Defaults→Project Structure
画像の赤枠の部分
 
<img width="1011" alt="%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202019-07-17%2016.57.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401818/4e675959-87e4-18b1-36fe-242025788c08.png">
 
 
### 6.bash_profileにAndroid SDKのパスを記入する
ターミナルを開き下記コマンドを入力して、bash_profileを開きます。
```$ vi ~/.bash_profile```
5.で確認したAndroid SDKの場所を記入します。
```export PATH=$PATH:/Users/ユーザーディレクトリ名/Library/Android/sdk/platform-tools```
 
<img width="535" alt="%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%25202019-07-17%252017.09.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401818/fda9c408-ca1b-05d1-e785-c63b540e40bc.png">
 
 
### 7.コマンドで改て読み込む
下記コマンドで改て読み込みます。
```$ source ~/.bash_profile```
最後に確認で下記コマンドを打ち込み、adb: command not foundとならなければadbの設定は完了
```$ adb```
 
 
### 8.ブートローダーをアンロックする手順
①端末の設定
端末の設定→システム（デバイス情報）→ビルド番号を数回タッチ→ディベロッパーモード(開発者モード)になる
端末の設定→システム（デバイス情報）→詳細表示→開発者向けオプション→OEMロック解除をON→USBデバッグをON

②端末とPCを接続
端末とPCを接続すると「USBデバッグを許可しますか？」と表示されるので「～常に許可する」にチェックを入れてOK をタップします。
下記コマンドを入力して、'8桁の英数字' device を表示する。
```
$ adb devices
List of devices attached
8桁の英数字 device
```

③アンロック
以下コマンドを入力
```$ adb reboot bootloader```
```$ fastboot flashing unlock```
端末の音量ボタンでUnlock the bootloaderに合わせたら、電源ボタンを押して決定する
端末の画面がunlockになっていることを確認

④Beta版を端末にインストール
解凍したBeta版のディレクトリ内にある、flash-allスクリプトを下記コマンドで実行する
```./flash-all.sh```
端末が再起動し、アップデートされる
 
 
### 9.ブートローダーをロックする手順
①端末の設定
端末の設定→システム（デバイス情報）→ビルド番号を数回タッチ→ディベロッパーモード(開発者モード)になる
端末の設定→システム（デバイス情報）→詳細表示→開発者向けオプション→OEMロック解除をON→USBデバッグをON

②ターミナル
以下コマンドを入力
```$ adb reboot bootloader```
```$ fastboot flashing lock```
端末の音量ボタンでlock the bootloaderに合わせたら、電源ボタンを押して決定する
端末の画面がlockになっていることを確認
以下コマンドを入力してブートローダーモードを終了
```$ fastboot reboot```


以上

---
47日目。クリックでずらっと並んだ画像を個別に切り替えたい


目標はカタログの画像をクリックしたら正面、横、上と画像が切り替わる感じのページです。

まずは「画像 クリック 切り替え」で検索してみました。

1.[【JavaScript入門】すぐわかる！画像を切り替える方法](https://www.sejuku.net/blog/63834)
コードをコピペして、クリックで画像が切り替わるところまではすぐできました。しかし複数の画像を用意、これをクリックすると他の画像も一緒に切り替わってしまいます。


2.[商品詳細ページのように、サムネイル画像をクリックしたらメイン画像が変わる画像ビューアーをjQueryで作ってみた](https://www.narugaro.com/web/%E5%95%86%E5%93%81%E8%A9%B3%E7%B4%B0%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E3%80%81%E3%82%B5%E3%83%A0%E3%83%8D%E3%82%A4%E3%83%AB%E7%94%BB%E5%83%8F%E3%82%92%E3%82%AF%E3%83%AA/)
JQueryが使えたら良さそうですが、今回は使えないので見送り。


3.[クリックで切替](https://seiai.ed.jp/sys/text/htm4/chp09/h09a03.html)
これは良さそう。ボタンが画像ごとに３つ必要でデザイン的にいまいちだけど、やりたい事はできました。ひとつにまとめられたらいいのだけど。


4.[一枚ずつ画像を切り換える](http://www.shurey.com/js/samples/3_img7.html)
これだと切り替える画像がたくさんあっても大丈夫そう。しかし１つなら動くのに、複数になると動かない。なんでだろう。

5.[クリックで複数画像の画像を個別に切り替える](http://www.openspc2.org/reibun/javascript/mouse/014/)
なるほど、複数画像にそれぞれ個別のタグをつければよさそうです！


```test.js
function changeT(iName)
{
    iObj = document.images[iName];
    n    = iObj.src.lastIndexOf("/") + 1;
    iSrc = iObj.src.substring(n,iObj.src.length);
    imgA = 'ari.gif'
    imgB = 'osusume.gif'
    imgC = 'urikire.gif'
    if (iSrc == imgA) iObj.src = imgB; 
    else if (iSrc == imgB) iObj.src = imgC; 
    else iObj.src = imgA;
}

const Targets = [
    ["たまご", 100],
    ["サーモン", 100],
    ["いくら", 300],
    ["あじ", 100],
    ["いわし", 100],
    ["さば",  100],
    ["中トロ", 200],
    ["大トロ", 300],
    ["気まぐれにぎり",300]
]

let str = "";
for (i=0; i<Targets.length; i++ ){
    Target = Targets[i]
    str = str  + `<div class='contents'>`;
    str = str  + `<div class='menu'>${Target[0]}</div>`;
    str = str  + `<div class='price'>¥${Target[1]}円</div>`;
    str = str  + `<img class='ita' src="ari.gif" name="ita${i}" onClick="changeT('ita${i}')">`;
    str = str  + `</div>`
}

const firstscript = function() { 
   document.getElementById('main').innerHTML = str;
   };

window.addEventListener("DOMContentLoaded", firstscript);
```

画像の`name`を個別にするのがキモでした！
これに気がつくのに４時間かかったんですね。ふう。


###所要時間
1.Javascriptで画像切り替え ２時間
2.その他 １時間
3.複数画像の画像クリックで個別切り替え　１時間
  画像を２つから３つ対応にする　３０分
  日本語ファイル名で動かなかった　３０分
4.html,cssコーディング　１時間
C＋＋の「auto」について


# [型推論 auto](http://uchan.hateblo.jp/entry/2019/02/22/105622)
C++11 から型推論のための auto キーワードが導入された。
~~autoを使うと具体的な型を書かずにコンパイラに型の決定を任せる事ができます。~~
autoを使うと具体的な型を書かずにコンパイラで変数の型を初期化子から推論することができます。

```cpp:auto.cpp
int main(void){
    auto hoge = 2;  // 整数型
    printf("%d",hoge);

    auto hoge2 = "Hello!";  // 文字列型
    printf("%s",hoge2);

}
```

## auto を使った方が良いのは
右辺の式から型がはっきりわかる
具体的な型があまり重要ではない
ラムダ式を受け取る
## auto を使うべきでないのは
その場所でその型になっていることを保証する
親クラスの参照として受け取る
その変数を後でオーバーロードされた関数に渡す

# [auto の落とし穴](https://www.moonmile.net/blog/archives/3768)
「値型」「ポインタ」「参照」の関係が入り乱れている時
AfxBeginThreadを用いた並列プログラムの実装について

# やること
- 並列化したい部分の変数をスレッドセーフにする
- 同時に処理を行いたくない部分の制御を追加

# 並列化したい部分の変数をスレッドセーフにする
普通のグローバル変数はスレッドごとに確保されないため、処理を並列化する際は、必要な変数をプライベート変数にする必要があります。

## thread_local
どうしてもグローバル変数として宣言したい場合、```thread_local```を使用する事でスレッドごとの静的記憶域に変数を確保することができます。

```cpp:thread_local.cpp
thread_local int Tmp;

int Main(){
	※
	AfxBeginThread(ThreadFunc0);
	AfxBeginThread(ThreadFunc1);
	※
}
int ThreadFunc0(){
	Tmp = 2; //ThreadFunc0に対する変数「Tmp」に値を代入
	・・・
}
int ThreadFunc1(){
	Tmp = 4; //ThreadFunc1に対する変数「Tmp」に値を代入
	・・・
}
```
上記のような場合は、Thread内でそれぞれ別の変数として扱うため、互いの変数に影響を与える事はありません。

Threadを立てる前にアクセスした場合や、Threadの処理が終わった後（※の部分）はどのような挙動かは、後日調査します。

# 同時に処理を行いたくない部分の制御を追加
同時にアクセスしたくない部分がある場合は、スレッドを同期させる必要があります。
同期をする方法は以下の４つがあります。

    1. セマフォ（CSemaphore）
    2. ミューテックス（CMutex）
    3. イベントオブジェクト（CEvent）
    4. クリティカルセクション（CCriticalSection）

今回は、セマフォを利用する。

## 単語の説明
### セマフォとは
「共有データアクセス許可証」
スレッド間ロックに使用
実行スレッド数を制限できる
### ミューテックスとは
プロセス間ロックに使用
同じプログラムを複数起動させない為の制御に使うのが有名
### イベントオブジェクト
イベントが発生するのを待つ
「待ち合わせ」機能
### クリティカルセクション
複数のスレッド間での相互排他の同期を行う
### CSingleLock クラス
マルチスレッドプログラムで1つのリソースのアクセス制御に使うアクセスコントロール機構


## 実装方法
以下のように、CSemaphoreを宣言し、宣言した物を利用し、CSingleLockを宣言します。
CSingleLockのメンバ関数『Lock』『Unlock』を利用し、スレッドの制御を行います。

```cpp:例.cpp
#include <afxmt.h>   //このインクルードが必要
CSemaphore Sync;     //セマフォの宣言

int ThreadMain(){
	CSingleLock Lock(&Sync);  
	Lock.Lock();
	※処理※
	Lock.Unlock();
}

```
セマフォによって、マルチスレッドにしても『※処理※』の部分は１スレッドずつしか実行されません。
同時にアクセスされたら困る変数にアクセスする処理や、同じ変数に演算結果を格納する場合に利用しています。
学習データ作成ツールCVATによるオートアノテーションとトラッキング

## 概要
物体検出モデルの学習データを作成するツール「CVAT」について、その機能であるTensorFlowモデルによるオートアノテーションと、OpenVINOのRe-IDモデルによるトラッキングデータの作成について述べる。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">CVAT with TensorFLow auto annotation and OpenVINO Re-identification <a href="https://t.co/aTfJXDQy8w">https://t.co/aTfJXDQy8w</a></p>&mdash; ハイパー絵に描いた餅クリエイター440 (@code_440) <a href="https://twitter.com/code_440/status/1151696859015966720?ref_src=twsrc%5Etfw">2019年7月18日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


## あらまし
ディープ・ラーニングモデルを用いた物体検出等の精度は年々向上しており、各種アプリケーションでの利用が期待されている。
一方で、各タスクに応じてモデルの学習データを作成する必要があり人的コストを要する。
（ABEJA等の学習データの作成を行うビジネスがあるほど。）

本稿では物体検出向け学習データの作成を支援するツール「CVAT」について、その機能の一つであるTensorFlow連携によるオートアノテーションとOpenVINOのRe-IDモデルによるトラッキングデータの作成について述べる。

## やること
CVATのインストールから基本的な使い方は[こちらの記事](https://qiita.com/PINTO/items/e674d65f412282cfe859)に詳しい。
本稿ではオートアノテーションとRe-ID機能に焦点を当てて述べる。

## 環境
|項目|内容|
|:------|:---:|
| OS | Ubuntu 16.04 64ビット|
|プロセッサ|Intel Core i7-7700HQ CPU @ 2.8GHz 2.81GHz|
|RAM|16GB|
|GPU|GTX1060 (6GB)|

## OpenVINOの準備
[こちら](https://github.com/opencv/cvat/tree/develop/components/openvino)の事前準備にしたがって、OpenVINOツールキットをダウンロードし、
CVATのディレクトリ内にある`components/openvino`に格納する。（圧縮したままで良い）
※　現在のOpenVINOのバージョンは上記記事の内容と異なっているため、適宜選択してダウンロードする。

## CVATの起動
今回はGPU(CUDA)、OpenVINO、TensorFlowを使用するため、以下のオプションを使用する。

### ビルド
`docker-compose -f docker-compose.yml -f components/cuda/docker-compose.cuda.yml -f components/openvino/docker-compose.openvino.yml -f components/tf_annotation/docker-compose.tf_annotation.yml build
`  
### 起動
`docker-compose -f docker-compose.yml -f components/cuda/docker-compose.cuda.yml -f components/openvino/docker-compose.openvino.yml -f components/tf_annotation/docker-compose.tf_annotation.yml up -d --build`

## CVATの利用
Chromiumブラウザで`http://localhost:8080`にアクセスする。

本稿ではサンプルデータとして[CAVIAR](http://groups.inf.ed.ac.uk/vision/CAVIAR/CAVIARDATA1/)データセットから動画を拝借した。

なお、CVATは画像または動画ファイルを読み込むことができ、
動画ファイルを読み込んだ場合はアノテーション結果をトラッキングデータとして保存することができる。

## オートアノテーションの実行と結果
大まかな流れは動画の通り。  
`Create Task`からタスクを作成画面がポップアップし、タスク名とラベル等を設定、`Select Files`からアノテーションしたいデータを読み込ませ`Submit`。  
`Run TF annotation`からauto annotationが始まる。  

私の環境ではGPUが貧弱なため短い動画の入力であったがそれなりに時間を要した。　　

auto annotation終了後、jobsのURLからjobページに移動することでアノテーションの結果を見ることができる。

アノテーションの結果を以下に示す。

![Screenshot from CVAT.mp4 - 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211021/e5cd4aa3-da27-116f-ce5a-bf55fa50c8fb.png)

見たところ高精度で人の位置に枠を付けている。　
一方で、人が重なっているところでは精度が悪い。

![Screenshot from CVAT.mp4 - 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211021/f844627d-ba58-6e2c-f5fd-982b98ff535b.png)

## Re-IDの実行と結果
次に、さきほどアノテーションした結果に対して、同一人物のIDをを統合するRe-IDを行う。  
`Open Menu`から`Run ReID Merge`を実行する。

Re-IDの結果を示す。

![無題 1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211021/053ccaf1-d4c3-e4f4-63c0-b5c161c527e6.jpeg)

ゆっくり歩いている人については同一の人物としてIDをが振られている。
一方で、人が重なるところや、振り向いた瞬間にIDの割り振りが変わっている。

このような誤ったアノテーションはパラメータを調整して再度Re-IDを行うか、手動で修正する必要がある。

## おわりに
アノテーション作業の低減を目指し、CVATによるオートアノテーションとトラッキング紹介した。
現状では有効な場合と手作業による修正のいる場合があり、
データの状況を見て判断する必要がある。
Amazon.comのURL短縮化

# AmazonのURL、長い
「このディスプレイ欲しい！」
https://www.amazon.co.jp/%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%82%A4-ET322QKwmiipx-31-5%E3%82%A4%E3%83%B3%E3%83%81-DisplayPort-Ready%E5%AF%BE%E5%BF%9C/dp/B0771DQYT5?ref_=Oct_DotdC_2151982051_1&pf_rd_p=e7620a6c-b851-55f6-9a3c-032ca4d1ab89&pf_rd_s=merchandised-search-5&pf_rd_t=101&pf_rd_i=2151982051&pf_rd_m=AN1VRQENFRJN5&pf_rd_r=2KAN1ZK0RXAPZT1SEGJT&pf_rd_r=2KAN1ZK0RXAPZT1SEGJT&pf_rd_p=e7620a6c-b851-55f6-9a3c-032ca4d1ab89


・・・長い！w

# 今朝の発見
社内のSlackで短いURLを見かけた・・・
一体どうやって。

# 比べてみた
自分の欲しいものURLで・・・
【元のURL】
〜.amazon.co.jp/%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%82%A4-ET322QKwmiipx-31-5%E3%82%A4%E3%83%B3%E3%83%81-DisplayPort-Ready%E5%AF%BE%E5%BF%9C/ `dp/B0771DQYT5` ?ref_=Oct_DotdC_2151982051_1&pf_rd_p=e7620a6c-b851-55f6-9a3c-032ca4d1ab89&pf_rd_s=merchandised-search-5&pf_rd_t=101&pf_rd_i=2151982051&pf_rd_m=AN1VRQENFRJN5&pf_rd_r=2KAN1ZK0RXAPZT1SEGJT&pf_rd_r=2KAN1ZK0RXAPZT1SEGJT&pf_rd_p=e7620a6c-b851-55f6-9a3c-032ca4d1ab89

【スタイリッシュURL】
〜.amazon.co.jp/ `dp/B0771DQYT5`

おお！ここが要か！
`dp/B0771DQYT5`

# 書き換えて、リンク先にとんでみる
https://www.amazon.co.jp/dp/B0771DQYT5


[完]
「mpurseを使ったサービスを開発するための環境構築」をクラウドの力で手抜きする

# 前段
[mpurseを使ったサービスを開発するための環境構築(Vue.js, mac)](https://qiita.com/Raiu1210/items/b4031624e3829c8bd672) を拝読しました。
mpurse が [主にセキュリティ上の理由で https のサイトにしか反応しない](https://github.com/tadajam/mpurse/pull/5) ので証明書周りで苦労したということですね。

これ、クラウドの力を借りると手抜きできます。

# つかうもの

[Google Cloud Platform (GCP)](https://cloud.google.com/) が提供している [Google Cloud Shell](https://cloud.google.com/shell/docs/) です。
主に gcloud コマンドを使った運用雑務のために提供されているようですが、Ubuntu が入ったコンテナイメージと、[Eclipse/Theia](https://projects.eclipse.org/projects/ecd.theia) をベースとしたと思われる IDE が提供されます。ブラウザアプリなので、クライアントの OS は問いません。 [^1]

[^1]: ブラウザは選びますが、いわゆるモダンブラウザであれば動くはず。

クラウドと聞いて__クラウド破産__という語を想起して身構える方もいらっしゃると思いますが…心配いりません。

GCP に契約していれば、Google Cloud Shell は無料で使えます。そして GCP は完全従量制。他のリソースを使わない限り、無料です。

たぶん [^2] 登録時にクレジットカード(デビットカード可)の登録は必要で、そこが壁といえば壁ですが…そこはなんとか。

[^2]: 筆者が GCP に登録したのは遥か昔なので忘れましたし、今どうなっているのかも調べていません。

# 作業

Cloud Shell をブラウザ内で立ち上げるまでの作業は、ググればわかるはずなので省略します。

右上のボタン2つを有効にすると、エディタとシェルが立ち上がります。

![ink (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158250/f0b50247-51a2-ee99-cacc-6f1cfc60cf84.png)

標準状態では npm だけで yarn は入っていないようです。sudoer 権限は与えられていないものの 5GB ストレージが割り当てられていますので、よしなにカスタマイズすれば良いと思います。node-gyp に必要な開発ツールはデフォルトで入っています。

ここから先 `vue create https-test` 等は、[本稿執筆のきっかけとなった記事](https://qiita.com/Raiu1210/items/b4031624e3829c8bd672) を参照していただくのですが、`vue.config.js` の編集は飛ばして構いません。

その代わり `cd https-test && npm run serve` 実行後に次の作業をしてください。

1. Cloud Shell ウインドウの右上にある Web preview ボタンをクリックし
2. 表示されるドロップダウンリストで `Preview on port 8080` を選択。

![Screenshot 2019-07-18 at 11.55.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158250/a5da6eaa-056c-e47a-8777-cac6942e654f.png)

すると、別ウインドウ(or 別タブ)にサンプルのページが表示されます。

![Screenshot 2019-07-18 at 11.55.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158250/e7c8f97c-e8f6-1e8b-06d2-ce2114ff6841.png)

このページは https に対応したリバースプロキシを経由して表示されていますので、https の設定を自分で行う必要はありません。手抜きできましたね。
mpurse からのインジェクションも確認できました。

![Screenshot 2019-07-18 at 12.00.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158250/84a1cdc1-f009-d3b2-d65c-466b60e313f6.png)

(何やらエラーが出ているようですが、vue 側で修正可能と思います。今回は深く追っていません)

# セキュリティ、どうなの?

他の人からも閲覧可能になっているのではと不安になるかもしれませんが、心配いりません。自分以外からは閲覧制限がかかります。そして Cloud Shell からログアウトしたり、時間制限や Google の都合で落とされたりすると、このプレビュー用の proxy も落ちます。

# 万能すぎない? デメリットは?

コンテナの中で動作しているので、お隣が重い処理を行っていたりすると、道連れで遅くなったりします。ポート 1 つしか forward しないので、複雑なことはできません。
無料なので文句は言えないのですが、優先度が低いコンテナで動作しているようで、放置していなくても Google の都合でインスタンスを落とされることが稀にあります。
Git 等の VCS との連携もありません。まあ shell 窓があるので、エディタに頼らなくてもなんとかなってしまう場合も多いのですが。

これでは物足りないとなると、クラウド IDE の利用も視野に入ってきます。アプリケーション開発専用の SaaS ですから、当然のことながら Cloud Shell よりも多機能です。

具体的には [Monascript の crowdfunding で Cloud Resource Sponsor](https://github.com/monaco-ex/Monascript#cloud-resource-sponsor) になっている [PizzaFactory/Camino](https://camino.pizzafactory.jp/) 辺りは一例となります。GitHub Pages での公開を予定しているのであれば、Typefox 社の [GitPod](https://gitpod.io/) も便利でしょう。

また、これらは総じて開発環境なので、開発完了後のことまでは世話をしてくれません。静的ページなら GitHub Pages とか動的ページなら Heroku とかの使用を検討しましょう。

# まとめ

Happy Monapartying!