OmniAICreator/Qiita-1.07M huggingface dataset:
「日程くん」の結果をスクレイピングする

## 概要
先日、2020明治安田生命Jリーグの日程が発表されました。（[リリース](https://www.jleague.jp/news/article/16542/)）
このリリースにはPDF形式でJ1・J2・J3リーグの日程が提供されています。
また、Jリーグでは様々なデータを試合軸・チーム軸・選手軸で別サイトに提供しています。
> [Jleague Data Site](https://data.j-league.or.jp/SFTP01/)

本投稿は、PDF形式をスクレイピングすのではなく、上記サイトで提供されている「日程・結果」メニューから得られるページを```pandas```が提供する```read_html```を使って簡単に取得します。

## URL構成
```
https://data.j-league.or.jp/SFMS01/search?competition_years=2020&competition_frame_ids=1&competition_ids=477&tv_relay_station_name=
```
* 基本：https://data.j-league.or.jp/
* アプリ名？：SFMS01
* パラメータ1：competition_years=2020　#年度
* パラメータ2：competition_frame_ids=1 #カテゴリー(J1)
* パラメータ3：competition_ids=477 #年度ごとのID
* それ以外は固定のまま

## コード説明
```game_schedule.py
# cording:uft-8
import pandas as pd
yyyy = 2020
url = 'https://data.j-league.or.jp/SFMS01/search?'
category = {'1': 477, '2': 478, '3': 479}
schedule = pd.DataFrame(index=None, columns=['年度', '大会', '節', '試合日', 'K/O時刻', 'ホーム', 'スコア', 'アウェイ', 'スタジアム', '入場者数', 'インターネット中継・TV放送'])
```
J1・J2・J3のカテゴリーと年度ごとのIDをdic形式で作成する。
空のデータフレームを作成する。

```game_schedule.py
for key, value in category.items():
    para = 'competition_years=' + str(yyyy)
    para1 = '&competition_frame_ids=' + str(key)
    para2 = '&competition_ids=' + str(value)
    para3 = '&tv_relay_station_name='

    full_url = url + para + para1 + para2 + para3
    # print(full_url)
    df = pd.read_html(full_url, attrs={'class': 'table-base00 search-table'}, skiprows=0)
    schedule = pd.concat([schedule, df[0]], sort=False)
```
ポイントは、`pd.read_html(full_url, attrs={'class':'table-base00 search-table'}...`で、対象のURLと`<table>`の属性を指定しています。
取得したものを`schedule`に結合します。

```game_schedule.py
# NaNを置き換えたければ
# schedule = schedule.fillna({'KO時刻': '●未定●', '入場者':0})
schedule.to_csv('./csv/Game_Schedule_' + str(yyyy) + '.csv', index=False, sep=',')
```
指定フォルダにcsv形式で保存します。

## まとめ
* シンプルな`<table>`は`pandas`の`read_html`で簡便に取得できる。

## データの活用
* 応援するチームのみ抽出して、遠征するスケジュールに利用する。
* 試合後は、スコアや入場者数の実績が登録されるので分析に利用できる。

### 「日程くん」について
* Wiki [Jリーグ・マッチスケジューラー](https://ja.wikipedia.org/wiki/J%E3%83%AA%E3%83%BC%E3%82%B0%E3%83%BB%E3%83%9E%E3%83%83%E3%83%81%E3%82%B9%E3%82%B1%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%A9%E3%83%BC)
* [今回のゲストはなんと、あの日程くん！Ｊリーグをもっと好きになる情報番組「ＪリーグTV」2019年12月5日](https://www.youtube.com/watch?v=MYuVYSfQykw)
表の表し方とpython

#整然データ
整然データの特徴
1. 個語の値が１つのセルをなす
2. 個語の変数が１つの列をなす
3. 個語の観測が１つの行をなす
4. 個語の観測ユニットの類型が１つの表をなす

例

| 種類       |     データ |
|:----------|----------:|
| A         |      23   |
| A         |      34   |
| A         |      543  |
| B         |      13   |
| B         |      56   |
| B         |      45   |

#pythonで種類ごとにデータを集め、表を作成する。
```python
import numpy as np
import pandas as pd
print(data)
group = data.groupby("species") #speciesごとに集計
print(group.mean()) #集計したデータの平均を求める。
group.describe()
```
<img width="206" alt="スクリーンショット 2020-01-25 17.00.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512772/725d4fd8-5c16-0d85-98e8-0e6990b937de.png"><img width="195" alt="スクリーンショット 2020-01-25 17.00.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512772/565c02a8-84de-7f0a-d669-1627bfd468b0.png">
<img width="421" alt="スクリーンショット 2020-01-25 17.01.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512772/643a633e-1c97-72b8-f1ef-28681ca08401.png">

#クロス集計表

```python

cross = pd.pivot_table(
    data = shoes,
    values = "sales",
    aggfunc = "sum",
    index = "store",
    columns = "color"
)
print(cross)
```
<img width="209" alt="スクリーンショット 2020-01-25 17.04.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512772/c50b066b-2d4d-4ca1-1c47-336c8d59a9a4.png">
応用情報技術者(AP)の合格体験記


応用情報技術者を受けました。受かりました。

私がやった勉強法を書きます。

## 申し込み。

- TODOリストに書いといて忘れないようにする。

## 過去問入手。(一ヶ月前)

- 図書館に買わせる。
- 問題を見て考えた結果、記述は勉強しなくても大丈夫と判断する。

## [過去問サイト](https://www.ap-siken.com/)を解く。(1週間前)

- 4択の計算問題は勉強しなくても正解できると判断したので、計算問題以外を200門ぐらい解いた。

以上。

# 感想

- 正直受けなくても良いと思った。
- 応用情報技術者は基本情報技術者の上位互換ってわけではなく、基本情報技術者で基本的なことやって、応用情報技術者で細かいことをやるみたいな位置づけらしい。基本的なことの知識整理がしたいなら基本情報技術者を受けたほうが良い。
- 本番の問題を見たら過去問と同じ問題がいっぱいあったから、4択の過去問をやりまくれば合格出来ると思う。
- 記述は、第一問の必須問題以外は考えれば出来る問題を選択することで合格ラインに到達出来るので、全く心配する必要ない。第一問が出来ない人は、パターンがあるので第一問のみを3年分ぐらい解くと出来るようになるはず。
- 合格したいだけなら1週間前に過去問買って傾向と対策練って３日前から4択を暗記すれば良い。
nuxtでOGPタグをfirestoreから取得で動的にしたい際につまったところ

# やったこと

* OGPタグの画像URLをfirestoreから取得して動的にした

# 仕様全体像

* nuxt×firestore
* defaultはnuxt.config.jsで指定。個別ページにcomponentのheadプロパティで上書き
* firestoreから取得したtitleをURLに入れる
* OGPのURLはcloudinaryのdynamicURLを使用
* dataとasyncDataを用意し、awaitでfirestoreからtitleを取得
* componentのheadプロパティでog:imageをset

## コード

```javascript
  data () {
    return {
      room_title: '',
    }
  },
  async asyncData ({ route }) {
    let doc_room_title
    /*room情報取得*/
    var roomRef = db.collection('room').doc(route.params.id)
    await roomRef.get().then(doc => {
      doc_room_title = doc.data().room_title
    })
    return {
      room_title: doc_room_title,
    }
  },
  head () {
    return {
      meta: [
        { hid: 'og:image', property: 'og:image', content: `hogehoge/image/upload/${this.room_title}/hogehoge.png` }
      ]
    }
  },

```

# はまりどころ

## SSRでtwitterにogp情報を渡す場合レンダリングタイミングが難しい

twitterが読み込めるようにSSRをしたんだがレンダリングタイミングが難しかった。

https://qiita.com/sukezane/items/059b2d33fa9f46e7eb07

レンダリング直前のbeforeCreateでいけんだろと書いてたけど取得できず。beforeCreateでは無理だったのでasyncDataでとってきたが取得する前にレンダリングしてたのか空になっていた。そのためawaitで記述。
C++ プライオリティキュー問題

#問題１　トラックガソリン問題
トラックで距離Lの道を移動します。はじめトラックにはガソリンがP積まれています。このトラックは距離１走るとガソリンが１消費されます。途中でガソリンが０になってしまうとトラックは停止してしまい、移動に失敗してしまいます。途中にはN個ガソリンスタンドがあります。各ガソリンスタンドiは道のスタート地点から距離A[i]の地点にあって、B[i]だけガソリンを補給することができる。トラックは移動を完了できるでしょうか？またその際に最小で何回のガソリンの補給が必要でしょうか？完了できる場合は最初の補給回数を、できない場合はー１を出力してください。
【制約】
・1≤N≤10000
・1≤L≤1000000,1≤P≤1000000
・−1≤A[i]≤L,1≤B[i]≤100

```c++
#include<bits/stdc++.h>
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define rep(i, n) FOR(i, 0, n - 1)
using namespace std;

int L,P,N;
int A[10010],B[10010];

int main(){
    cin >> N >> L >> P;
    rep(i,N) cin >> A[i];
    rep(i,N) cin >> B[i];
    //簡単のためゴールをガソリンスタンドに追加
    A[N]=L;
    B[N]=0;
    N++;
    
    //ガソリンスタンドを管理する順位キュー
    priority_queue<int> que;
    
    //ans:補給回数, pos:今いる場所, tank:タンクのガソリンの量
    int ans=0, pos=0, tank=P;
    
    rep(i,N){
        //次に進む距離
        int d=A[i]-pos;

        //距離dを移動しようとするが、無理っぽいなってなったら…
        while(tank-d<0){ 
            if (que.empty()){//キューにガソリンがなかったら…
                puts("-1");//最後に改行文字が自動的に付加される
                return 0;
            }
            else{ //キューにガソリンがあるなら…
               tank+=que.top();
               que.pop();
               ans++;
            }
        }
        tank-=d;
        pos=A[i];
        que.push(B[i]);
    }
    printf("%d\n",ans);
}
```
Cloud Buildのビルドが実行されるリージョン

具体的なドキュメントは見つけられませんでしたが、Cloud Buildのビルドが実行されるリージョンは **us-central1** のようです。

## 確認方法

次の内容の `cloudbuild.yaml` を用意します。ビルドの中で [メタデータサーバー](https://cloud.google.com/compute/docs/storing-retrieving-metadata) の情報を取得します。

```
steps:
  - name: gcr.io/cloud-builders/curl
    args:
      [
        "-sS",
        "-H",
        "Metadata-Flavor: Google",
        "http://metadata.google.internal/computeMetadata/v1/instance/zone",
      ]
```

同じディレクトリで次のコマンドを実行し、ビルドを開始します。 `<PROJECT_ID>` にはご自身のプロジェクトIDを指定してください。

```
gcloud builds submit --project <PROJECT_ID>
```

ログに次のように出力され、 `us-central1` で実行されていることがわかります。

```
projects/*******/zones/us-central1-f
```

ちなみに、[App Engineのリージョン](https://cloud.google.com/appengine/docs/locations?hl=ja)や[Compute Engineのデフォルトリージョン](https://cloud.google.com/compute/docs/regions-zones/changing-default-zone-region?hl=ja)が異なる別プロジェクトで試しても同様の結果になったので、これらの設定に影響されることはなさそうです。

## 余談

元々、Cloud BuildでCloud SQLを使ったテストを実行すると、やけに遅くて不思議に思っていました。理由を考える中で、Cloud BuildとCloud SQLのリージョンが異なる可能性に気づいたというわけです。

テストで使用するCloud SQLのリージョンを asia-northeast1 → us-central1 に変更したところ、ビルド実行時間が12分→5分に大幅短縮されました。GCPのサービスはリージョンを意識せずに使えるものもありますが、リージョンを意識することの大切さを実感しました。

## 参考

* [Run Google Cloud Build in a specific region and zone? - Stack Overflow](https://stackoverflow.com/questions/51595900/run-google-cloud-build-in-a-specific-region-and-zone)
* [Can I define the region Google Cloud Container Builder runs in? - Stack Overflow](https://stackoverflow.com/questions/50464845/can-i-define-the-region-google-cloud-container-builder-runs-in)
ReactNative環境構築でのトラブルシューティング

今回は環境構築、シュミレータを実行する際にエラーについて、自分が直面した物をまとめようかと思います。

####①"config.h" file not found

react-native run-iosした時にタイトルのようなエラーが発生することがあります。

#####解決法

モジュールの再設定を行うようです。

```
$ cd node_modules/react-native/third-party/glog-0.x.x
$ ../../scripts/ios-configure-glog.sh
```

`glog`フォルダが見つからない場合がたまにあるかもしれません。

その時は下記コマンドを実行することで作られます。

```
$ cd node_modules/react-native/scripts/
$ sh ios-install-third-party.sh
```

####②Could not find iPhone X simulator

run-iosでシュミレータがないよとなることがあります。

バージョンを指定すれば、対象の端末で起動しますが、指定しないとiPhone6で起動します。

```
react-native run-ios --simulator 'iPhone Xs'
```

なので、別の原因が考えられます。

#####解決法

findMatchingSimulator.jsの書き換えで解決できます。

```
./node_modules/react-native/local-cli/runIOS/findMatchingSimulator.js

if (!version.startsWith('iOS') && !version.startsWith('tvOS')) {
    continue;
  }

// 下記に書き換え
if (!version.startsWith('com.apple.CoreSimulator.SimRuntime.iOS') && !version.startsWith('com.apple.CoreSimulator.SimRuntime.tvOS')) {
    continue;
  }

```

####③Can’t find ‘node’ binary to build React Native bundle
実機でビルド時に起こるエラーです。

#####解決法
nodeのパスを修正すれば直ります。

XcodeのProject ファイル　＞　TARGETS > APP Name > Build Phases > Bundel React Native code and imageを選択して、

```
export NODE_BINARY=node
../node_modules/react-native/packager/react-native-xcode.sh
```


を

```
export NODE_BINARY=$HOME/.nodebrew/current/bin/node
../node_modules/react-native/packager/react-native-xcode.sh
```
に修正したら、直りました。

ちなみに、nodeのパスは下記コマンドで確認できるようです。

```
export -p
```

一般的に遭遇しそうなものを記載しました。

他に出てきたら追記しようと思います。

####参照

[issue1](https://github.com/facebook/react-native/issues/19569)

[issue2](https://github.com/facebook/react-native/issues/21498#issuecomment-476621627)

[React Native エラー　Can’t find ‘node’ binary to build React Native bundle](https://qiita.com/YutamaKotaro/items/00749491cb1d5f7b82ba)
Rider で整える、保存時に自動でファイルの最後に改行を入れる

GitHub でファイルの最後を改行するしてあるしてないで、差分出たりして煩わしい思いしていませんか？
そんな細かいのはどうでもいいと思いながら、余分な差分はないほうがいいなと思いませんか？
そう、そういうものこそツールで解決ですね。

# やり方
1. Preferences を開く
2. Editor -> General -> Other -> `Ensure line feed at file end on Save` にチェックを入れる

<img width="990" alt="rider.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/c7e09308-0a39-8af9-fd8e-9551eab4432b.png">

# 捕捉
* Android Studio など JetBrains社製のIDEであれば、同じように設定できます。
Java13におけるJavaFXの環境構築

# 概要
MacBookProを購入したためJavaFXの環境構築をしました。
# 環境
* java 13.0.2
* zsh 5.7.1 (x86_64-apple-darwin19.0.0) 
* MacBook Pro (13-inch, 2017, Four Thunderbolt 3 Ports)

# 手順
1. Javaのインストール
2. JavaFXのインストール
3. 使いやすくする
    4. PATHを通す
    5. ラップする

##Javaのインストール
[公式サイト](https://www.java.com/ja/)からファイルをダウンロードし、その後インストールします。詳細な指示がサイトに乗っています。
## JavaFX
[公式サイト](https://openjfx.io/)のダウンロードページからSDKの方をダウンロードします。そのファイルを、今回は`/Library/Java/JavaVirtualMachines/`の下で展開しました。
##使いやすくする
この状態でも、例えばコンパイルなら

```
$ javac --module-path /Library/Java/JavaVirtualMachines/javafx-sdk-13.0.2/lib --add-modules=javafx.controls,javafx.fxml *.java
```
で、実行できます。
でも長すぎるので、もっと使いやすくしましょう。
###PATHを通す
まずは途中の`/Library/Java/JavaVirtualMachines/javafx-sdk-13.0.2/lib`にPATHを通します。

PATHを通すには設定ファイルを編集する必要があります。今回はzshなので`.zshrc`を編集します。

```:~/.zshrc
export PATH_TO_FX=/Library/Java/JavaVirtualMachines/javafx-sdk-13.0.2/lib
```
上の一行を一番下に加えました。その後ターミナルを再起動もしくは

```
$ source ~/.zshrc
```
をターミナル上で実行することで反映させることができます。PATHが通っているかどうかは

```
$ echo $PATH_TO_FX
```
の実行結果が、指定した場所になっているかどうかで確認できます。
ここまでやると、

```
$ javac --module-path $PATH_TO_FX --add-modules=javafx.controls,javafx.fxml,javafx.media *.java
```

で実行できるようになります。
###ラップする
まだ長いのでラップします。そのためにまずは`$HOME/bin`というディレクトリを用意し、ここにPATHを通すため`~/.zshrc`に

```:~/.zshrc
export PATH="$PATH:$HOME/bin"
```
上の一行を加えます。
その後該当ディレクトリに、`jfxc`と`jfx`の二つのファイルを作製します。

```:$HOME/bin/jfxc
#!/bin/sh
javac --module-path $PATH_TO_FX --add-modules=javafx.controls,javafx.fxml,javafx.media $@
```
```:$HOME/bin/jfxc
#!/bin/sh
java --module-path $PATH_TO_FX --add-modules=javafx.controls,javafx.fxml,javafx.media $@
```
それぞれ上記のように書き、権限をふっておきます。

```
$sudo chmod 755 jfxc
$sudo chmod 755 jfx
```

最後に反映させると実行できるようになります。

```
$ source ~/.zshrc
```
##実行方法

コンパイル

```
$ jfxc *.java
```
実行

```
$ jfx (ファイル名)
```

#追記
1月26日　[Audioclip](https://docs.oracle.com/javase/jp/8/javafx/api/javafx/scene/media/AudioClip.html)が使えなかったため一部編集しました

#参考
以下の記事を参考にさせていただきました。
[Java11でJavaFXを動かす](https://qiita.com/tsudon/items/ea2e78171e32b3cb1578)
[macでPATHを通す方法](https://qiita.com/k3ntar0/items/eb8cdbd8eba9da388def#vivim)
[コピペ1分でMacの自作コマンドを作る](https://qiita.com/JJJJJJJJ/items/cc4357f5ba2a9eed809d)
VisualStudioのソースコードスニペット用拡張機能作成Tips

# はじめに
VisualStudioのスニペットではできない入力時の日時を入れたりすることが拡張機能ならできるようになります．
その拡張機能を作るうえでここだけサンプルから変えれば簡単なものが作れるといった内容を記載していきます．
以降は以下サイトの手順が完了しているものとします．
[https://docs.microsoft.com/ja-jp/visualstudio/extensibility/walkthrough-displaying-statement-completion?view=vs-2017](https://docs.microsoft.com/ja-jp/visualstudio/extensibility/walkthrough-displaying-statement-completion?view=vs-2017)
※ 手順通りに行いusingの追加を行ってもエラーが残っている場合は参照に追加したもののバージョンに誤りがないか確認してみてください．時々同一名称の別バージョンのものを追加してしまっており，エラーとなってしまうことがあったりします．

# Tips
## 対象ファイル指定
TestCompletionSourceProviderクラスとTestCompletionHandlerProviderクラスの[ContentType()]に対象を記載。  

```c#
  
 [ContentType("TypeScript")]
```

## 挿入したい文字列の生成を行う箇所
TestCompletionSourceクラスの以下メソッド内  

```C#
void ICompletionSource.AugmentCompletionSession(ICompletionSession session, IList<CompletionSet> completionSets)
```

## 現在のエディタ内のテキスト取得  
文字を入力した際のエディタ内のテキストを取得できます．  

```C#
m_textBuffer.CurrentSnapshot.GetText()
```

## 現在の文字挿入位置取得
```C#
(session.TextView.Caret.Position.BufferPosition - 1).Position
```

## 受付可能な文字の変更
TestCompletionCommandHandlerクラスのExecメソッド内の以下条件にて、10進の数字か文字のみ受け付けられるようになっています。
例えば「/」を使用したい場合はこの条件を書き換えることで使用できるようになります．

```C#
if (!typedChar.Equals(char.MinValue) && char.IsLetterOrDigit(typedChar))
```  

## 設定より挿入する文字列を切り替える
以下チュートリアルを参考に設定項目を追加し，その値を使用する．
細かい話は気が向いたら書くかもしれません……
[https://docs.microsoft.com/ja-jp/visualstudio/extensibility/extending-user-settings-and-options?view=vs-2017](https://docs.microsoft.com/ja-jp/visualstudio/extensibility/extending-user-settings-and-options?view=vs-2017)
ローカルネットワークの管理者に自分がどのサイトを見てるのかわからなくする方法


## VPN

自宅にRasberryPiなどを用いてVPNのサーバーを立てる。
外では自宅にVPNしてからインターネット利用することでバレない。

### 利点

- バレない。

### 欠点

- RasberryPiの管理などが面倒い。
- 大学で論文ダウンロードするたびに、VPN切るのが面倒い。


## DNSoverHTTPS

chromeの[DNSoverHTTPSを有効化](https://qiita.com/AKKYM/items/dfe4cc4323a111de2a92)する。
ネットワークの管理者はDNSしか見てないと思うから、これを有効にするだけでまあバレない。

### 利点

- お手軽。
- 論文もダウンロード出来る。

### 欠点

- どのIPアドレスと通信してるかとかはわかるから、頑張って調べればわかる。

## まとめ

- おすすめはDNSoverHTTPS
- 他に良い方法あったら教えてね。
早くプログラミングが上達する方法を色々試した結果、特に一番良かったと思うこと(まだ1ヶ月しか経ってませんが)

<h1>最速のプログラミングの学習方法の一つとして</h1>
<p>プログラミングを本格的に学習する前は、ネットなどで早く上達する方法を調べていたのですが、その中でも、二人で組んで学習するという方法が最も良いのではないかと思います。（はまればですが(*´∇｀*)</p>

<p>参考までに、二人で組んで学習するメリットを下記にまとめます。</p>

<ul>
<li>会話が発生するため、アウトプットする頻度が高い</li>
<li>学習をサボりにくい(両方ふぬけだったら終わり＼(^^)／)
<li>お互いに抜け落ちている知識を提供、教えることができる。教えるほうもアウトプットになり
、より理解が深まる。
<li>ライバルがいることで競争意識が生まれる。</li>
</ul>

これらは一例で他にもメリット、デメリットは多くあると思いますが、
僕が特に良かったと思う点は、やはり「サボりにくい」という点だと考えています。

まずプログラミングに限らず、一人で学習すること事態が大抵の人は困難なのでは
ないかと思うんですが、皆さんいかがでしょうか？(ちなみに僕は無理です、というか嫌です；；

仮に一人で学習できたとしても、自分一人では完全に理解できているのか確認しにくく、
その点もう一人いれば説明しないといけないので、(理解できていないことは説明できないので
その箇所が認知できる)理解が深まっていいと僕は思いますヾ(๑╹◡╹)ﾉ"

もちろん他にも色々な学習方法があると思いますが、いずれにせよまずは継続して学習できる環境を整えることが最優先課題と考えます。(一人でできてしまう人を僕は仙人として崇めます＿|￣|○
JSTQB Foundation LevelとJCSQE 初級のまとめと勉強法

## はじめに
2019年に**JSTQB Foundation Level**と**JCSQE 初級**を受験し両方とも合格しました。
今後受験する人の参考になればと思い、情報をまとめました。

* 経歴: ソフトウェア開発 6年(C言語)、SQA 3ヶ月。ソフトウェア開発で設計からテストまでを行っていた経験が大きかったと思います。
* 受験動機: 会社のチームで「ソフトウェア品質に対しての認識レベルをあわせるために、受験しよう！」となったので。

## JSTQB Foundation Level

### 試験概要

* 実施日: 2月、8月
* 受験料: 22,000円（税込）
* 問題数: 40問
* 試験時間: 60分
* 合格率: 62.9%(2019/8/24 <http://jstqb.jp/attribute.html>)
* URL: <http://jstqb.jp/>

ソフトウェアテストについての試験です。「同値分割したときのテストケースとして正しいのはどれ？」といった問題が出題されます。

### 勉強方法

シラバスは全く読んでいません。

公式テキスト(<https://amzn.to/2Fir2Bs>)の解説をざっくり読み通し、巻末の問題集と各章の練習問題を3周くらい解いていました。勉強期間は1か月くらいです。

受験後に知ったのですが、スクエアリングサービス(<http://squaring.jp/others/index.jsp>)というサイトでJSTQBの問題について公開されているので、こちらを利用するのもいいかもしれません。

### 感想

テキストの例題に全く書かれていない「状態遷移図」からテストケースを検討する問題が出てきたりして焦りました。ただ、問題自体は難しくないので、落ち着いて考えれば解けました。

テスト時間も十分あるので、わからない問題は後からゆっくり解いたりしました。

JSTQBはISTQBに基づいてテストが作成されているため、世界中で同じ基準で話ができます。実際に、海外の会社さんと仕事をするときに役にたっています。

個人で受験する場合は、受験料が高い(22,000円)のがネックかと思います。会社が補助(合格時に受験料とテキスト代)をしてくれたのでとても助かりました。

## JCSQE 初級

### 試験概要

* 実施日: 6月、11月
* 受験料: 11,000円（税込）
* 問題数: 40問
* 試験時間: 60分
* 合格率: 22.1%(2019/11/16 <https://www.juse.jp/jcsqe/past/>)
* URL: <https://www.juse.jp/jcsqe/>

ソフトウェア品質に対する知識を持っているかの確認をする試験です。「PL法についてもっとも適切なものを選べ」といった問題が出題されます。

### 勉強方法

勉強のモチベーションが上がらず試験1週間前から、初級問題集(<https://amzn.to/3mdz3YQ>)を繰り返し(3周くらい)解きました。

主参考書籍のソフトウェア品質知識体系ガイド(<https://amzn.to/3ma8svY>)は購入しましたが、結局使いませんでした。業務には役立っているので、ソフトウェア品質系の仕事をしている人は購入してもいいかもしれません。

こちらもシラバスは読んでいません。

### 感想

勉強を始めたときからJSTQBに比べ知らない単語が多かったです。勉強を始めたときは焦ったのですが、繰り返し問題を解くことで単語の意味を覚えられ合格できました。

「日本」のソフトウェア品質保証に焦点を当てているので、大企業の方はすんなり理解できる内容だと思います。

試験を受けて、業務で何か活かせたかというと微妙なところです。

## 今後の予定

初級は取れたので、次はJSTQB、JCSQEともに上位レベルの受験を考えています。上位レベルの試験は3種(JSTQB ALTA(2月)、JSTQB ALTM(8月)、JCSQE 中級(11月))あり、それぞれ年1回の開催です。さらにJSTQBは「業務経験3年以上（業務経歴申請書の提出あり）」が必要です。

またIT検証技術者認定試験(IVEC <https://www.ivia.or.jp/item43>)にも興味があり、受験を検討しています。


[Note](https://note.com/marc0468/n/n48c4328f2e1c)もやっています。
単価が異なるお菓子をどういう組み合わせで買えば目標の合計値になるか問題

先日、息子がとある算数の問題に挫折しているので覗いてみたら、確かにちょっと難しそうだった。「4種類の価格がまちまちのお菓子を任意個ずつ買ってキリがよい合計にする」という問題なんだけど、お菓子の単価と目標の合計値のみしか提示されていない [^limit] 。当然、まるっきり当てずっぽうで正解が得られる感じではない。たぶん、答えが当ってるかどうかより、どういうアプローチで回答しようとしたかを見ることが問題の主旨であるような気がする。

[^limit]: 厳密には、それぞれの上限を10個とするとか、お菓子はなるべく高いものを多く買うとか、もうちょっと制限があった。

で、これはまあ一種の切符問題なので、父さんならHaskellで解くなと思うだけ思ってそれきり忘れてたんですが、新千歳空港でお土産を買ってるときに思い出したので、成田までの機内で書きなぐってみました。抽象度が低くて残念な感じですが、当機はすでに着陸体制に入っています。（と思ったら成田が混雑してるので旋回しはじめた）

```haskell
module Main where

import System.Environment

main :: IO ()
main = do
  -- 第一引数：目標の合計金額
  -- 残り：お菓子たちの単価
  x:xs <- fmap (map $ read) getArgs
  putStrLn $ show $ seek x (length xs) $ comb $ matrix xs

matrix :: [Int] -> [[(Int,Int)]]
matrix xs = map (\i -> map (\j -> (j,i)) [1..10]) xs

comb :: [[(Int, Int)]] -> [[(Int, Int)]]
comb [] = []
comb ([]:rest) = comb rest
comb ((x:xs):[]) = [[x]] ++ comb [xs]
comb ((x:xs):rest) = [(x:ys) | ys <- comb rest] ++ comb (xs:rest)

seek :: Int -> Int -> [[(Int, Int)]] -> [[(Int, Int)]]
seek target n = filter (totalIs target)
  where d (i,j) = i*j
        totalIs t xs = length xs == n && t == (sum $ map d xs)
```

問題の数字は覚えてないので、適当な合計金額と単価で実行例。

```sh
λ> :main "3000" "146" "172" "400" "500"
[[(4,146),(3,172),(1,400),(3,500)]]
λ> 
```
146円のお菓子が4個、172円のが3個、400円のが1個、500円のが3個で3000円になるらしいです。
[Minecraft] Modding備忘録 (3. Modの命名 )

# ページ一覧
1. 本記事

# 今回の目標 (Modの命名)
自分のMod名が認識する
<img width=90% src ="http://drive.google.com/uc?export=view&id=1Cfwv9yTCG8qVlmgD6UoSr9b3bE7xKNzm">

> ※自分用の備忘録のコピペです。口調変わってるのは気にしないでください  
> ※これは1.14.4の頃の備忘録です。

# 初期化
## Rename作業
1. src/main/java を開く
2. `com.example.examplemod`と書いてるパッケージを 右クリ > Refactor > Rename
3. New Nameのところに com.ｸﾞﾙｰﾌﾟ.ﾓｯﾄﾞID を入力(例: com.seatrees.japanesecolor)
4. また、そのパッケージ内にあるExample.javaも同様にRenameする。
   - 名前は「自分のMOD名.java」か「Main.java」にするとわかりやすいかも  
     私は JapaneseColor.java にしたので今後この名前が出てきたらこのファイルだと思ってok

## Mod名とかの設定
1. Main.javaにある `@Mod("examplemod")` の中身を自分のmodid(≒Mod名の小文字)に変える
   - 私の場合`@Mod("japanesecolor")`となる
2. build.gradle をダブルクリックで開き、以下の項目を編集する
```
version = '1.0'
group = 'com.yourname.modid'
archivesBaseName = 'modid'
```
これをそれぞれに合うように編集する。modidは小文字推奨。私は以下の通り
```
version = '0.0.1-SNAPSHOT'
group = 'com.seatrees.japanesecolor'
archivesBaseName = 'japanesecolor'
```
3. src/main/resources > META-INF > mods.tomlを開く
4. 15行目付近の `modId="examplemod"` を自分のmodidに変更(例: japanesecolor)
5. 19行目付近の`displayName="Example Mod"`を自分のMod名に変更(例: Japanese Color)
6. 23行目付近の`displayURL="http://example.com/"`を、URLがあれば変更
7. 25行目付近の`logoFile="examplemod.png"`をロゴがあれば変更
8. 29行目付近の`authors="Love, Cheese and small house plants"`を作者名に変更
9. その他、`examplemod`を自分のmodidに置き換えればok

## 動作確認
1. `runClient.launch` を右クリで Run As > runClient を実行
2. Minecraftが起動して、Modからさっき設定した名前のModが認識していれば成功  
**なお、今後は1.2.を実行するの一言で済ませる。**
<img width=90% src ="http://drive.google.com/uc?export=view&id=1Cfwv9yTCG8qVlmgD6UoSr9b3bE7xKNzm">


# 参考になりそうなリンク
https://qiita.com/Hiroya_W/items/2af8fcacab5feaf880b6#_reference-a83a7b32816ce61b6732
【Ruby】returnとselfを使って「浜田麻里」を表示せよ

#はじめに
４ヶ月くらい前からプログラミングの勉強をし始め、
Ruby難しいなー、特にreturnとself、難しい。コレガワカラナイ。
と、なんどもreturnとselfを検索しては記事を読みましたがよくわからない。
今でもよくわかってないです。

それをわかるようになるには、
returnとselfを使って「浜田麻里」を表示するしかないと天啓があったので書いてみました。

# 問題のソースコード

```ruby
class Return_to
    attr_accessor :to,:my
    
    def initialize(to,my)
      self.to = to
      self.my = my
    end
    def my_self
      return self.to + self.my
    end
  
end
  
return_to = Return_to.new("浜田","麻里")
puts return_to.my_self

```

selfを使用するには、classを定義しなければいけなかったので、
最初はどうしようかと思いましたが、
``return_to.my_self``というメソッドで浜田麻里が表示されたら一番美しいのではないか？
と考え、``Return_to``というclassを定義しました。

引数を「浜田」と「麻里」にして、それをくっつけた文字列が``return``で戻り値として、
呼び出したメソッド、つまり``return_to.my_self``に返すようにしています。

selfメソッドはclassを省略して書くことができるので、
ここで言うところの``Return_to.hoge``を``self.hoge``とすることがでるそうで、
``initialize``のところでは、引数で受け取った「浜田」と「麻里」を代入する時に、
``self.to``、``self.my``と言う形で使用しています。

もうお気付きの方もいらっしゃると思いますが、
このclassとメソッドは、米倉千尋にも使用することが可能です。

```ruby
class Return_to
    attr_accessor :to,:my
    
    def initialize(to,my)
      self.to = to
      self.my = my
    end
    def my_self
      return self.to + self.my
    end
  
end
  
return_to = Return_to.new("米倉","千尋")
puts return_to.my_self

```
世代によって使い分けをすることができる汎用性の高い素晴らしいclassとメソッドだと思いました。

# 終わりに
なぜこんな天啓があったのかというと、returnとselfをなんども検索していたら、
YouTubeの「あなたへのおすすめ」で、浜田麻里氏の「Return to Myself」をという曲が表示され、
CD全盛期のパワーあふれる曲に心打たれてしまったからです。

ちょっと普通に意味わからないのが、
プログラミングのreturnとselfを検索し続けると、returnとselfが入った曲をおすすめしてくるのか？
というところ。

わからなくて何度も検索しているから、
検索エンジンは「この人はプログラミングのreturnとselfを検索している訳ではないのではないか？」
と気を利かせてくれたのでしょうか。
なんにしてもセンスがいいです。

このコードを書こうとしたきっかけは、それこそ４ヶ月くらい前だったのですが、
その時は全くreturnとselfの意味がわからず、
見よう見まねで実装して、「浜田麻里」が出力されましたが、
returnを消しても「浜田麻里」が出るし、self.hogeももっと回りくどく使っていて、どうも人前に出していいものではないなと判断したので、
もっと理解できるようになってから書こうと思いました。

何で書いたんですかね。

世代的には米倉千尋氏のReturn to myselfの方が馴染みがあり、アニメも毎週みてました。

# 参考資料
[Return to Myself 〜しない、しない、ナツ。（ウィキペディア）](https://ja.wikipedia.org/wiki/Return_to_Myself_%E3%80%9C%E3%81%97%E3%81%AA%E3%81%84%E3%80%81%E3%81%97%E3%81%AA%E3%81%84%E3%80%81%E3%83%8A%E3%83%84%E3%80%82)

>「Return to Myself 〜しない、しない、ナツ。」（リターン・トゥ・マイセルフ 〜しない、しない、ナツ。）は、浜田麻里の9枚目のシングル。1989年4月19日発売。発売元はビクターインビテーション。

>'89カネボウ化粧品 夏のキャンペーンソングに起用され、大塚寧々出演のCMが大量にオンエアされた。サブタイトルの「しない、しない、ナツ」も、当時のカネボウのキャッチコピー「化粧なおし、しない、しない、ナツ」からとっている。

[Return to myself (曲)（ウィキペディア）](https://ja.wikipedia.org/wiki/Return_to_myself_(%E6%9B%B2))
>「Return to myself」（リターン トゥー マイセルフ）は、米倉千尋の13thシングルである。初回盤は「カード（モンコレナイト）」を封入している。
[Minecraft] Modding備忘録 (2. Forgeのビルド )

# 今回の目標 (Forgeのビルド)
MinecraftForgeが立ち上がる
<img width=90% src="http://drive.google.com/uc?export=view&id=1xAj1qGilDook1tvZmviHrq2rkwnG-7BB">

# Forgeのダウンロード
[Forge.net](https://files.minecraftforge.net/)にアクセスして、自分のダウンロードしたいバージョンのForgeを左メニューから選択。(今回は1.15.2)  
`Show all Versions`から虫マーク(バグマーク)の付いていない物で、`Mdk`クリック. (使う人のために古めの物を使ったほうがいいのかもしれませんが、新しいのとどっちがいいのでしょう?)  
AdFoc.usに飛ぶので、右上が`Skip`になるまで待機した後`Skip`を押し、ダウンロードする。  
Eclipseのworkspace内にテキトーなフォルダを作る(今回はJapaneseColor1152),(workspaceはWindowsデフォルトでは`C:\Users\ユーザー名\eclipse-workspace`)  
作ったフォルダにさっきダウンロードしたzipファイルを展開  
> - gradle(フォルダ)
> - src(フォルダ)
> - .gitignore
> - build.gradle
> - changelog.txt
> - CREDITS.txt
> - gradle.properties
> - gradlew.dat
> - LICENCE.txt
> - README.txt

このうち、「.gitignore」,「changelog.txt」「CREDITS.txt」,「LICENCE.txt」はいらないので消しておきましょう.(必要になったらまた展開してください)  

# Forgeのビルド
先ほどのフォルダ内の「README.txt」の通りに進めるだけです. (※以下はEclipseの場合です) 
まず、コマンドプロンプトを開き、cdコマンドで場所を上記の「build.gradle」があるフォルダに移動します.(私の場合`C:\Users\ユーザ名\eclipse-workspace\JapaneseColor1152`, つまりコマンドは`cd "C:\Users\ユーザ名\eclipse-workspace\JapaneseColor1152"`)  
次に、私はEclipse使ってますので`gradlew genEclipseRuns`を実行.((Mac/Linuxの場合は`./gradlew genEclipseRuns`))  
ナニカ始まるのでそのまま待機し、それが終わり次第Eclipseを起動. (緑で「BUILD SUCCESSFUL」と出れば成功です)   
Eclipseで「File」→「Import...」→「Gradle→Existing Gradle ProjectでNext」→「Welcomeみたいなページ出るけど、チェック外してNext」→「Project root directoryで今回のヤツを選択(私の場合`C:\Users\ユーザ名\eclipse-workspace\JapaneseColor1152`)→「Finish」  
またビルド始まるのでおとなしく待ちましょう  

# Modのビルド
`ProjectExproler`というところに先ほどのヤツが追加されているので、三角のチョボで開いて、「runClient.launch」を探してください。  
「runClient.launch」を右クリック、「Run As」→「Run Client」を実行  
マイクラが起動すれば成功です。お疲れさまでした。
<img width=90% src="http://drive.google.com/uc?export=view&id=1xAj1qGilDook1tvZmviHrq2rkwnG-7BB">
本番環境でbackground-imageが反映されない

プログラミング初心者の備忘録です。
ご注意ください。

## background-imageが本番環境で反映されない
ローカルでは background-image: url(******.jpg)　と記述して反映されているが、本番環境では読み込まれない。

``` ******.css
background-image: url(******.jpg);
```

## 対処法
background-image: image-url("******.jpg")と記述する

```*******.css
background-image: image-url("******.jpg");
```
[Minecraft] Modding備忘録 (1. Java, Eclipseのインストール)

# 本記事について
「あ～mod作りたいんじゃ～」とか言って数か月くらい勉強したやつの忘備録です。  
相当雑に書くので、コメント欄や[新マイクラフォーラム](https://forum.civa.jp/index.php)とかを活用していただければと思います。  
また、多少なりともJavaを触ったことがある方を対象としています。わからない言葉(メソッド等)があれば、個人で調べることをお勧めします。  
~~私もついこの前までジェネリックという言葉すら知らなかったような弱たんですけど~~

# ページ一覧
1. 本記事

# 今回の目標 (Java, Eclipseのインストール)
Eclipseが起動する

# Javaのインストール  
jdkというやつをダウンロード&インストールします。  
ただし、8u231というバージョン出ないと、Forgeがビルドできないので注意してください。  
> すでに新しいバージョンのJavaが入っている方へ  
> %JAVA_HOME%が8u231であればよいので、後ほどPATHの変更をすれば大丈夫です

[ココ](https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)からダウンロードし、インストールしてください。  
また、必要ならPATHを通してください。  
PATHの通し方は「Java path 通し方」とか調べれば腐るほど出てくるので割愛。  

# IDEのインストール  
私はEclipse使いますが、べつにIntelliJ IDEAでも構いません。  
ただ、次回やるForgeのセットアップの関係上この二種類のどっちかを使うことをお勧めします。  
(余談ですが、日本語化されたEclipseは結構使いにくいので英語のほうをお勧めします。)  

では、[Eclipse](https://www.eclipse.org/downloads/)をダウンロードし、インストールします。  
Eclipseの場合`eclipseInstaller`がダウンロードされると思いますので、`Eclipse IDE for Java Deveropers`をインストールします。  
その他、インストール場所など設定は各自行って`Install`してください。 
↓こんな感じの画面が出れば成功です。
<img width=90% src="http://drive.google.com/uc?export=view&id=1NzjBON5JT1BvSU1V7mvBWmW1SvogixYM">  
`Launch`をおすなり、スタートメニューやショートカットキー等から起動してください。  
(途中でworkspaceの場所聞かれますが、特に指定がなければそのまま`Launch`で問題ありません)  

Eclipseが起動すれば完了です！
Node.js で Cloud Firestore のデータを削除 (Delete)

こちらで作成したデータのひとつを削除します。
[Node.js で Cloud Firestore のデータを作成 (Create)](https://qiita.com/ekzemplaro/items/fe9133236a8e04519acf)

```js:firestore_delete.js
#! /usr/bin/node
// ---------------------------------------------------------------
//	firestore_delete.js
//
//					Jan/25/2020
//
// ---------------------------------------------------------------
console.error ("*** 開始 ***")

const key_in=process.argv[2]
console.log (key_in)

const admin = require('firebase-admin')
admin.initializeApp({
  credential: admin.credential.applicationDefault()
})

const db = admin.firestore()

try
	{
	db.collection('cities').doc(key_in).delete()
	}
catch (error)
	{
	console.error ("*** error *** delete ***")
	console.error (error)
	}

console.error ("*** 終了 ***")

// ---------------------------------------------------------------
```

実行コマンド

```bash
export NODE_PATH=/usr/lib/node_modules
project_id="project-dec16-2020"
echo $project_id
export GOOGLE_CLOUD_PROJECT=$project_id
#
export GOOGLE_APPLICATION_CREDENTIALS="***.json"
./firestore_delete.js t0924
```
Node.js で Cloud Firestore のデータを更新 (Update)

こちらで作成したデータを更新します。
[Node.js で Cloud Firestore のデータを作成 (Create)](https://qiita.com/ekzemplaro/items/fe9133236a8e04519acf)

```js:firestore_update.js
#! /usr/bin/node
// ---------------------------------------------------------------
//	firestore_update.js
//
//					Feb/09/2021
//
// ---------------------------------------------------------------
console.error ("*** 開始 ***")

const key_in=process.argv[2]
const population_in=process.argv[3]

console.log (key_in + "\t" + population_in)


const today = new Date ()
var ddx = (1900 + today.getFullYear ()) + "-" + (today.getMonth () +1)
ddx += "-" + today.getDate ()
console.log(ddx)

const admin = require('firebase-admin')
admin.initializeApp({
  credential: admin.credential.applicationDefault()
})

const db = admin.firestore()

try
	{
	let cityRef = db.collection('cities').doc(key_in)

	cityRef.update({population: population_in,
		date_mod: ddx})
	}
catch (error)
	{
	console.error ("*** error *** update ***")
	console.error (error)
	}

console.error ("*** 終了 ***")


// ---------------------------------------------------------------
```

実行コマンド

```bash
export NODE_PATH=/usr/lib/node_modules
#
project_id="project-dec16-2020"
echo $project_id
export GOOGLE_CLOUD_PROJECT=$project_id
#
export GOOGLE_APPLICATION_CREDENTIALS="***.json"
./firestore_update.js t0923 91456200
```
Node.js で Cloud Firestore のデータを読む (Read)

こちらで作成したデータを読みます。
[Node.js で Cloud Firestore のデータを作成 (Create)](https://qiita.com/ekzemplaro/items/fe9133236a8e04519acf)

```js:firestore_read.js
#! /usr/bin/node
// ---------------------------------------------------------------
//	firestore_read.js
//
//					Jan/25/2020
//
// ---------------------------------------------------------------
console.error ("*** 開始 ***")

const admin = require('firebase-admin')
admin.initializeApp({
  credential: admin.credential.applicationDefault()
})

const db = admin.firestore()


db.collection('cities').get()
  .then((snapshot) => {
    snapshot.forEach((doc) => {
//	console.log(doc.id, '=>', doc.data())
	var unit_aa = doc.data()
	var out_str = doc.id + "\t"
	out_str += unit_aa["name"] + "\t"
	out_str += unit_aa["population"] + "\t"
	out_str += unit_aa["date_mod"]
	console.log (out_str)
    })
console.error ("*** 終了 ***")
  })
  .catch((err) => {
    console.log('Error getting documents', err);
  })


// ---------------------------------------------------------------
```

実行コマンド

```bash
export NODE_PATH=/usr/lib/node_modules
project_id="project-dec16-2020"
echo $project_id
#
export GOOGLE_CLOUD_PROJECT=$project_id
export GOOGLE_APPLICATION_CREDENTIALS="***.json"
./firestore_read.js
```

次のバージョンで確認しました。

```text
$ node --version
v14.14.0
```
【Go】Excelからセル値を取得 ＆ セル座標⇔番号変換

https://github.com/yagrush/excelutil

golangでExcelを読み込む必要があったので開発しました。
ポイントは、
　『ユーザーがどんな座標指定の仕方をしてくるか、未知』
だったので、ある程度の柔軟性とエラーチェックを仕込みました。

# 使い方
`cmd/test.go` がそのまんまサンプルになっているので、ご参照ください。

# 関数のご紹介
## excel.go
### Init(excelFilePath string)
なにはともあれ、最初に呼んでやってください。
Javaのコンストラクタのような感じです。
Excelファイルのパスを渡すと、Excelファイルを読み込む下準備をして、構造体を返してくれます。

### (excelFileInstance *ExcelFile) ReadCell(sheetName string, colNum, rowNum int)
Excelファイルの中のシートの名前、セルの列番号、行番号を指定すると、セル値を読み出してくれます。
セルの列番号、行番号の指定方法は、例えば D5 セルだったら 4, 5 です。
Initで得た構造体にドット . を付けて、直接呼び出してください。

### (excelFileInstance *ExcelFile) ReadCellByCellAddress(sheetName string, cellAddress string)
Excelファイルの中のシートの名前、セル座標を指す文字を指定すると、セル値を読み出してくれます。
"セル座標の文字" とは、Excelではお馴染みの A7 とか BC20 とかの表記法です。
Initで得た構造体にドット . を付けて、直接呼び出してください。

### ConvExcelCellAddressToColnumAndRownum(excelCellAddress string)
セル座標を指す文字を指定すると、列番号と行番号に変換して返します。
例えば、D5 セルだったら 4, 5 です。
ちなみに B:3 とか AZ-983 とか、間に文字を挟んで指定するユーザーもいるかも知れないので、対応しました。
（間に何か挟んでても、ちゃんと処理します）
`ReadCellByCellAddress` 関数も中でこれを使っているので、同様です。

### ConvExcelColNumToAlphabet(cellColnum int)
列番号を指定すると、セル座標を指す文字の"列部分"を返します。
例えば 3 を指定すると C を返します。

---
開発にあたってはこちらを参考にさせて頂きました。
https://qiita.com/bamchoh/items/447a4c40e5f39edb2512
ありがとうございます。

またExcelの根幹処理は、もはや定番のこちらを。
https://github.com/tealeg/xlsx
感謝！:pray:
Node.js で Cloud Firestore のデータを作成 (Create)

ライブラリーのインストール

```bash
sudo npm install -g firebase-admin
```

```js:firestore_create.js
#! /usr/bin/node
// ---------------------------------------------------------------
//	firestore_create.js
//
//					Jan/25/2020
//
// ---------------------------------------------------------------
function add_data_proc(db,key,name,population,date_mod)
{
	let tt_ref = db.collection('cities').doc(key)
	tt_ref.set({
		'name': name,
		'population': population,
		'date_mod': date_mod
		})
}

// ---------------------------------------------------------------
console.error ("*** 開始 ***")

const admin = require('firebase-admin');
admin.initializeApp({
  credential: admin.credential.applicationDefault()
})

const db = admin.firestore();

add_data_proc(db,'t0921','宇都宮',81235,'1950-9-24')
add_data_proc(db,'t0922','小山',94235,'1950-2-15')
add_data_proc(db,'t0923','佐野',71395,'1950-5-28')
add_data_proc(db,'t0924','足利',35421,'1950-7-8')
add_data_proc(db,'t0925','日光',61948,'1950-1-11')


console.error ("*** 終了 ***")
// ---------------------------------------------------------------
```

実行コマンド

```bash
export NODE_PATH=/usr/lib/node_modules
project_id="project-dec16-2020"
echo $project_id
export GOOGLE_CLOUD_PROJECT=$project_id
#
export GOOGLE_APPLICATION_CREDENTIALS="***.json"
./firestore_create.js
```

次のバージョンで確認しました。

```text
$ node --version
v14.14.0
```
console.logよりutil.debuglogとutil.inspect使ってログ吐きたい

# console.logよりutil.debuglogとutil.inspect使ってログ吐く:v:
AWS Lambda(node.js12.x)で具合よくログ吐きたいっていうことで、ベストエフォート@自分の脳味噌でログ出力を考えてみました。

## [Object]になってしまう問題:relaxed:
深い階層のJSオブジェクトはconsole.logだと[Object]と表示されてしまう。なんとか出力したい。

```js
const obj = {a:{b:{c:{d:{e:{f:function(){return 1;}}}}}}}
console.log(obj) // { a: { b: { c: [Object] } } }
```

## JSON.stringify?:point_left:
JSON.stringify使ってconsole.logに吐いてみる。

```js
const obj = {a:{b:{c:{d:{e:{f:function(){return 1;}}}}}}}
console.log(JSON.stringify(obj)) // {"a":{"b":{"c":{"d":{"e":{}}}}}}
```
見事に関数部分のkey-valueが消えてしまってる。これはさすがにどうにかしたい。

## util.debuglogとutil.inspectを併用してログ吐く
結論としてはutil使ってしまう。

環境変数NODE_DEBUGにINFOとかWARNとかセクション設定してあげたらロガー返してくれます。
Windows環境ですがこんな感じで設定しておきます。カンマ区切りでセクションは複数指定OK。

```cmd
SET NODE_DEBUG=INFO,WARN
```

詳細なオプションとかはドキュメント見たらGoodです。
とりあえずdepth:nullってしたらオブジェクト全部吐いてくれます。

```js
const info = require('util').debuglog('INFO')
const warn = require('util').debuglog('WARN')
const trace = require('util').debuglog('TRACE') // 環境変数設定なし

const obj = {a:{b:{c:{d:{e:{f:function(){return 1;}}}}}}}

info(util.inspect(obj, {depth: null}))
warn(util.inspect(obj, {depth: null}))
trace(util.inspect(obj, {depth: null})) // 環境変数設定ないのでログも吐かないがエラーも吐かない適当さがJSの素晴らしいところ
```

## メリ
分岐が一つ減るはず。

## デメ
自分の脳味噌では思いつかない。

## Node.js Reference

[util.debuglog](https://nodejs.org/api/util.html#util_util_debuglog_section)
[util.inspect](https://nodejs.org/api/util.html#util_util_inspect_object_options)
.Net Frameworkと.Net Coreの違い、そして.Net 5

#.Net ほにゃらら について

よく聞く割に何となくしか理解できていませんでした。
CoreとかFrameworkって言うのがあるんですよね。

少し調べたのでめちゃザックリかつ簡単にまとめておきます。
※あまり詳しく無いので間違えた解釈をしているなどあれば教えてください！


きーわーど
・<font color="Red">.Net Framework</font>
・<font color="Blue">.NET Core</font>
・<font color="Green">.NET 5</font>


##<font color="Red">.NET Frameworkとは</font>
MicroSoftが開発したWindows向けのフレームワーク。
元々はこっちだけだった。
昔から作られていたモノはFramework。

##<font color="Blue">.NET Coreとは</font>
クロスプラットフォームに対応するために後から生まれた。
Windows、Linux、macOS向けのフレームワーク。


.Netフレームワークの完全上位互換のように見える。
けど色々と問題があった。

FrameworkにあるAPIのうち一部しかCoreの方にはなかった。

Frameworkの方ではゴチャゴチャした処理も簡単に記述できていたけど、
Coreでは対応していないから実装をベタ書きすることになったりする…

現時点ではバージョン3.1まで出ており、だいぶ充実している。

<font color="Blue">正直今から新規開発するなら.NET Coreでいい。</font>

下記のページでMicrosoftの賢そうな人が
もうFrameWorkからCoreへの移植結構やったしもうやめるわ
的なこといってる。
[Announcement: .NET Core 3.0 concludes the .NET Framework API porting project ](https://github.com/dotnet/corefx/issues/41769)


##<font color="Green">.NET ５とは</font>
FrameworkやらCoreについて書いていたけど2020年11月に.Net 5って言うのがリリースされるとのこと。
1つに統合されるみたい。
これでFrameworkとかCoreといった単語とおさらばできるかな。できたらいいなぁ。
特に不具合なくバージョンをあげれることを願います。

おわり。
C++ 貪欲法

#問題１　硬貨の問題
1円玉、5円玉、10円玉、50円玉、100円玉、500円玉が、それぞれa[0],a[1],...,a[5]枚ずつあります。できるだけ少ない枚数の硬貨でA円を支払いたいと考えています。何枚の硬貨を出す必要があるでしょうか？　なお、そのような支払方法は少なくとも一つ存在するとします。

【制約】
・0 <= a[i] <= 10^9
・0 <= A <= 10^9

```c++
#include<bits/stdc++.h>
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define rep(i, n) FOR(i, 0, n - 1)
using namespace std;

//コインの金額
const int V[6]={1,5,10,50,100,500};
int A;
int a[100];


void solve(){
    int ans=0;
    
    for (int i=5; i>=0; i--){
        
        int t=min(A/V[i],a[i]);//コインを使う枚数
        A-=t*V[i];
        ans+=t;
    }
    printf("%d\n",ans);
}

int main(){ 
    //入力
    rep(i,6) cin >> a[i];
    cin >> A;
    solve();
}
```
#問題２　区間の問題
n個の仕事があります。各仕事は時間s[i]に始まり、時間t[i]に終わります。あなたは各仕事について、参加するか参加しないかを選ばなければいけません。仕事に参加するならば、その仕事のはじめから終わりまで、参加しなければなりません。また、参加する仕事の時間帯が重なってはなりません。（開始の時間・終了の時間だけが重なるのも許されません）。

【制約】
・0 <= N <= 100000
・0 <= s[i] <= t[i] <= 10^9

```c++
#include<bits/stdc++.h>
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define rep(i, n) FOR(i, 0, n - 1)
using namespace std;

const int MAX_N=1001000;
int N,S[MAX_N],T[MAX_N]; //時間s[i]に始まり、時間t[i]に終わる

int main(){
    cin >> N;
    rep(i,N) cin >> S[i];
    rep(i,N) cin >> T[i];
    //仕事をソートするためのpairの配列
    vector <pair <int,int>> itv(N);
    
    //pairは辞書順で比較される
    //終了時間の早い順にしたいため、Tをfirstに、Sをsecondに入れる
    for (int i=0; i<N; i++){
        itv[i].first=T[i];
        itv[i].second=S[i];
    }
    sort(itv.begin(),itv.end());
    
    //tは最後に選んだ仕事の終了時間
    int ans=0,t=0;
    for (int i=0; i<N; i++){
        if(t<itv[i].second){
            ans++;
            t=itv[i].first;
        }
    }
    printf("%d\n",ans);
}
```

#問題３　辞書順最初の問題
N文字の文字列Sが与えられ、N文字の文字列Tを作ります。はじめはTの長さ０の文字列で、次のいずれかの操作が行えます。
・Sの先頭を一文字削除し、Tの末尾に追加する
・Sの末尾を一文字削除し、Tの末尾に追加する
辞書順比較でできるだけ小さくなるようにTを作ってください。

```c++
#include<bits/stdc++.h>
#define FOR(i, a, b) for (int i = (a); i <= (b); i++)
#define rep(i, n) FOR(i, 0, n - 1)
using namespace std;

int N;
char S[10010];

int main(){
    cin >> N;
    rep(i,N) cin >> S[i];
    //S[a],S[a+1],...,S[b]が残っている文字列
    int a=0,b=N-1;
    
    while(a<=b){
        //左からみた場合と右から見た場合を比較
        bool left=false;
        for (int i=0; a+1<=b; i++){
            if (S[a+i] < S[b-i]){
                left=true;
                break;
            }
            else if (S[a+i]>S[b-i]){
                left=false;
                break;
            }
        }
        if (left) putchar(S[a++]);
        else putchar(S[b--]);
    }
    putchar('\n');
}
```
#~一言メモ～
putchar()は**「一文字だけ」**出力
printf()は「***文字列出力にも、一文字出力***」にも対応してる！
部分一致したものに数値を代入する方法（備忘録①）

#使用データ
```
#使用データ
df
```

|| name | room_type |
|---|---|---|
| 0 | ホテルA | スーペリアツインルーム禁煙 |
| 1 | ホテルB | スーペリアツインルーム喫煙 |
| 2 | ホテルC | デラックスツインルーム |
| 3 | ホテルD | スタンダードツインルーム禁煙 |
| 4 | ホテルE | ダブルルーム |
| 5 | ホテルF | デラックスダブルルーム禁煙 |
| 6 | ホテルG | スタンダードツインルーム禁煙 |
| 7 | ホテルH | デラックスキングルーム |

このようなものを用意しました。

#Goal

room_typeに'スーペリア'、'デラックス'と名前がつくものに1、そうでないものに0を付与した新しいカラムを生成する。

#実施事項
```
new_room_type_list = []

for i in range(8):
    if 'スーペリア' in df['room_type'][i]:
        a = 1
    elif 'デラックス' in df['room_type'][i]:
        a = 1
    else:
        a = 0
    new_room_type_list.append(a)
```
このようにしてlistを作成
その後dfに追加する。

```
#dfに作成したnew_room_type_listをdf['new_room_type']として追加する。
df['new_room_type'] = new_room_type_list
```
確認してみる

```
df
```

|| name | room_type | new_room_type |
|---|---|---|---|
| 0 | ホテルA | スーペリアツインルーム禁煙 | 1 |
| 1 | ホテルB | スーペリアツインルーム喫煙 | 1 |
| 2 | ホテルC | デラックスツインルーム | 1 |
| 3 | ホテルD | スタンダードツインルーム禁煙 | 0 |
| 4 | ホテルE | ダブルルーム | 0 |
| 5 | ホテルF | デラックスダブルルーム禁煙 | 1 |
| 6 | ホテルG | スタンダードツインルーム禁煙 | 0 |
| 7 | ホテルH | デラックスキングルーム | 1 |

こんな感じでうまく追加することができた。

###おまけ：.str.contains()の使用
```
df['room_type'].str.contains('スーペリア')
```
0     True
1     True
2    False
3    False
4    False
5    False
6    False
7    False
Name: room_type, dtype: bool

このようにどの行に'スーペリア'が出てくるなどはわかるが、.str.contains()はDataFrame全体に及ぶものなので1行1行をみていくif文などには向かないと判断したため上記の方法を用いた
メタプログラミング Ruby memo #1

# 概要
現在Rubyを勉強しており、「**Rubyを勉強するならメタプログラミングRubyは必読！**」という先輩からの教えがあり、読んでいるのでそれのまとめメモです。

筆者のRubyに関してのスキルは「プロになるためのRuby」を読んでRailsチュートリアルをさらっとくらいのレベルです。
お見知り置きいただければと。。。

今回はまずメタプログラミングに関してまとめようと思います。

### 個人的レベル感
「上級者向け過ぎてわからないことも多いだろうなあ」とびびっていたのですが案外わかりやすく、ひとつひとつコードを書きながら進めていくと理解が進むような造りになっていると感じました。

翻訳書なので、表現の仕方が基本的に海外よりなので、そこに関して苦手な人は読みづらいかもです...

何かあるごとに開く本というのが誰しもあると思うのですが、個人的にはこの本はそこにランクインするレベルだと思います。






# そもそもメタプログラミングって何？(広い意味での)
- ロジックを直接コーディングするのではなく、あるパターンをもったロジックを生成する高位ロジックによってプログラミングを行う方法、またその高位ロジックを定義する方法のこと( [wikipedia](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%BF%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0))
- 他のプログラム ( あるいは自身 ) を操作したり出力するプログラムを書くこと、または作業の一部をコンパイル時に行い、残りの作業を実行時に行うようなプログラムを書くことである。
- コードジェネレータやコンパイラが行うコード生成のこと。

# Rubyは「動的メタプログラミング」
- Rubyに関して言えば、「コードを生成するためのコードを書くこと」が簡単にできてしまう。
(本書の言葉を借りれば「シームレスかつエレガントに」)
- 「魔法」や「黒魔術」と呼ばれるくらい、簡潔にコードが書ける。
- 「*大いなる力には、大いなる責任が伴うことを忘れてはいけない*」 by Matz


**言語要素を実行時に操作するコードを記述すること**

> コードジェネレータやコンパイラが行うコード生成のことも、「広い意味でのメタプログラミング」と言えるのだが、Rubyはこの定義には含まれない。
これを「静的メタプログラミング」と呼ぶならば、Rubyは「動的メタプログラミング」と呼べる




## メタプログラミングに利用されている技術の例
実際に本書で使われている技術の一例を紹介しようと思います。
※ もっと沢山あります。

**既存のクラスの振る舞いを変更する(モンキーパッチ)**

```mokey_patch.rb
"abc".reverse # => "cba"

class String
  def reverse
    "オーバーライド"
  end
end

"abc".reverse # => "オーバーライド"
```


**1. 再定義したメソッドから以前のメソッドをエイリアスで呼び出す**

```around_arias.rb

# String#reverseに新たな機能を追加する
"abc".reverse # => "cba"

class String
  alias_method :old_reverse, :reverse

  def reverse
    "hoge#{old_reverse}hoge"
  end
end

"abc".reverse # => "hogecbahoge"

```


**2. 該当するメソッドのないメッセージに応答する**

```method_missing.rb
class Hoge; end

hoge = Hoge.new
hoge.no_define_method
# => NoMethodError (undefined method `no_define_method' for #<Hoge:0x00007f9649836be8>)


# BasicObject#method_missingを書き換える(noMethodErrorを返しているメソッド)
class Hoge
  def method_missing(name, *args)
    name.to_s.reverse
  end
end

hogehoge = Hoge.new
hogehoge.no_define_method
# => "hogedohtem_enifed_onhoge"
```

**動的メソッド**

```dynamic_method.rb
class C; end

C.class_eval do
  define_method :my_method do
    "動的メソッド"
  end
end

obj = C.new
obj.my_method
# => "動的メソッド"
```

### ざっくりまとめると
- 上記のようなRubyの技術を駆使してコードのリファクタなどを例を用いてわかりやすく説明してくれています。
- ActiveRecordなどのRailsのコードもどのようなスキルを駆使して書かれているか説明してくれているので、難しいコードを読んだことない人にとってはとっつきやすいかもしれません。
- 本書の最後のほうでも言っているのですが、メタプログラミングがどうとか考えずにただのプログラミングだと思えという言葉がなぜかしっくりきました。
(自分のバイアスがかかっていただけかも？)
- Rubyの「特徴」を事細かに説明してくれている良書だと思います。
【SRE Next 2020】発表資料まとめ

2020/01/25 に行われた [SRE Next](https://sre-next.dev/schedule) の資料まとめです。
資料が公開され次第、内容を更新します。

- [分散アプリケーションの信頼性観測技術に関する研究](https://speakerdeck.com/yuukit/a-study-of-sre)
- [40000 コンテナを動かす SRE チームに至るまでの道](https://www.slideshare.net/techblogyahoo/40000-sre-125-sre-next-2020-srenext)
- [タクシーxAIを支えるKubernetesとAIデータパイプラインの信頼性の取り組みについて](https://www.slideshare.net/dena_tech/xaikubernetesai-sre-next-2020)
- [絶え間なく変化するメルカリ・メルペイにおけるSREの組織と成長](https://speakerdeck.com/tjun/sre-next-2020)
- [パフォーマンスを最大化するための SRE のオンボーディング事例](https://speakerdeck.com/tkuchiki/sre-next-2020)
- [計画的に負荷リスクを排除するためのキャパシティプランニング](https://speakerdeck.com/sekino/ji-hua-de-nifu-he-risukuwopai-chu-surutamefalsekiyapasiteipuranningu)
- [成長を続ける広告配信プラットフォームのモニタリングを改善してきた話](https://speakerdeck.com/larufa/cheng-chang-wosok-keruguang-gao-pei-xin-puratutohuomufalsemonitaringuwogai-shan-sitekitahua)
- [freee のエンジニアは障害から何を学び、どう改善しているのか？](https://speakerdeck.com/manabusakai/what-do-freee-engineers-learn-and-improve-from-failures)
- [グループウォレットアプリ、6gramの運用をはじめてみた](https://speakerdeck.com/ryosan470/6gram-sre-next-2020)
- [delyにおける安定性とアジリティ両立に向けたアプローチ](https://speakerdeck.com/gomesuit/sre-next-2020)
- [Practices for Making Alerts Actionable](https://speakerdeck.com/egmc/practices-for-making-alerts-actionable)
- [日経電子版SREチーム立ち上げ中](https://speakerdeck.com/osamunmun/ri-jing-dian-zi-ban-sretimuli-tishang-gezhong)
- [冗長性と生産性を高めるハイブリッドクラウド環境の実現](https://speakerdeck.com/sshota0809/sre-next-2020-rong-chang-xing-tosheng-chan-xing-wogao-meruhaiburitudokuraudohuan-jing-falseshi-xian)
- [SLO Review](https://speakerdeck.com/chaspy/slo-review)
- [100万回線のIoT通信を支えるソラコムにおけるOpsDevの実践](https://www.slideshare.net/SORACOM/100iot-opsdev-sre-next-2020-in-tokyo)
- [急成長するPairsと共に変化・成長し続けてきたエウレカのSRE戦略](https://speakerdeck.com/kaneshin/how-to-keep-growing-sre-team-at-eureka)
- [New RelicのSREに学ぶSREのためのNew Relic活用法](https://speakerdeck.com/tanaka733/srenext-2020-b5-new-relicfalsesrenixue-busrefalsetamefalsenew-relichuo-yong-fa)
- [スクラムを1年回してSREと開発組織がどう変わったのか](https://speakerdeck.com/licht110/sukuramuwo1nian-hui-site-sretokai-fa-zu-zhi-gadoubian-watutafalseka)
- [Blue-Green デプロイメントを採用したデプロイの仕組みを実装して共通基盤として導入した話](https://speakerdeck.com/ktmrgk/sre-next-2020)
- [SREがセキュアなWebシステムを構築、維持するためにやれることはなにか](https://speakerdeck.com/isaoshimizu/what-can-sre-do-to-build-and-maintain-a-secure-web-system)
- [ZOZO MLOps のチームリーディングとSRE(Engineering)](https://docs.google.com/presentation/d/1zEkR9Dm_epg7fxOCFE-asBsUlHDozwObsBEGAILiqic/edit#slide=id.p1)
- [Designing fault-tolerant microservices with SRE and circuit breaker centric architecture](https://speakerdeck.com/takanabe/sre-next-2020-c6-designing-fault-tolerant-microservices-with-sre-and-circuit-breaker-centric-architecture)
- [サイト信頼性エンジニアリングの原則 (記事)](https://ymotongpoo.hatenablog.com/entry/2020/01/27/173000)
- [SRE Practices in Mercari Microservices](https://speakerdeck.com/tcnksm/sre-practices-in-mercari-microservices)
- [実践Observability](https://www.slideshare.net/toshihumianan/observability-224174523)
- [Webサービスを1日10回デプロイするための取り組み](https://speakerdeck.com/fujiwara3/sre-next-2020)
ROSでRealSenseをまじめに動かしてみようとしたら環境設定が大変だった

#この記事を書いた経緯
書籍に影響されて[「Jetson Nano 超入門」を読んでSLAMやってみた](https://qiita.com/t_kumazawa/items/13bd1d851de65977c7d4)にあるようにSLAMをやってみたら、一年前には困難だったあれやこれやが解決されて、スムーズにSLAMが動かせました。
調子に乗ってROSを勉強してラジコンも動かそう。
DonkeyCarからステップアップ!
と思ったら、継続的に開発しようとすると環境設定のほうが大変だった。
そして、ROS関連の記事も書いているうちにどれに何を書いたのかわからなくなってきたので、説明のメモを書いてリンクしておきます。

##ROS関連記事の一覧
色々書き散らかしたので、自分でもわからなくなる前に何を書いたかをメモっておきます。

|記事名|内容|
|:---|:---|
|[「Jetson Nano 超入門」を読んでSLAMやってみた](https://qiita.com/t_kumazawa/items/13bd1d851de65977c7d4)|書籍を見ながらD435iを動かしてみました。Jetson-nanoのセットアップやドライバのインストールなど|
|[ROSでRealSenseを真面目に動かしてみる](https://qiita.com/t_kumazawa/items/1c25fb2e243b0c61baec)|Jetson＋D435i＋T265でSLAMやってみたいと思い、サンプルやデモをいろいろ動かしてみました。不毛。|
|[ROSでRealSenseを真面目に動かしてみる２](https://qiita.com/t_kumazawa/items/d7fffe5dc9a046bb8776)|手元のDonkeyCarを改造したらROSで簡単に動かせると思い、JOYスティックの入力を取って、カメを動かしてみるROSチュートリアルをやってみた。I2Cの入力確認もしてみた|
|[ROSでRealSenseを真面目に動かしてみる３](https://qiita.com/t_kumazawa/items/e64a02490a6415512ff1)|開発に入る前に開発ツールの整備をします。<BR>VSCode/Git/Git hub<br>これでJETSONが壊れてもソフトはGitHubから落としてこれます|
|[ROSでRealSenseを真面目に動かしてみる４](https://qiita.com/t_kumazawa/items/70a7583c49d2f3d7231e)|C++でJOYスティックの入力を取る方法や、コールバック関数をクラスメンバで記述する方法をしらべました。<br>直近はPythonで書いたほうが手っ取り早そうです|
|[ROSでRealSenseを真面目に動かしてみる５](https://qiita.com/t_kumazawa/items/dde071bb4ebed7ec07a0)|Pythonでサーボを動かしますが、ROSはPython2.7しかサポートしていません。EOLのPython2.7で動かすためにいろいろな小細工が必要になります。<br>Jetson-nanoでROSを使ってサーボを動かすのは超大変です|
|[Docker＋ROSの環境をWindows10PROで整える](https://qiita.com/t_kumazawa/items/aa541758be558673e76b)|Windows10にもROSを入れてデバッグができるようにしました。自分用の作業メモです。<br>DockerでROSをやろうとするといろいろ面倒なことがありますので記録しておきます|
|||

##ソースコード
GitHubに入れておきます。
Masterそのまま作業する癖を治す必要あり。
そのうちdevのブランチをちゃんと切って作業します。

[kumaxxp/ros_rc_package](https://github.com/kumaxxp/ros_rc_package)

##以下は逆引きリンク

###Jetson-nanoでROSが動くようにする
[「Jetson Nano 超入門」を読んでSLAMやってみた](https://qiita.com/t_kumazawa/items/13bd1d851de65977c7d4)、を参考にセットアップしたら簡単に動きました。
ROSとREALSENSEのドライバを入れて、SLAMっぽいものが動かせるところまで簡単にできます。
いい本ですので持っておくと何かと参考になります。

###Windows10Pro
NVIDIAのGTX1660Tiが入ったWindows10を使用します。
Docker DeskTopを動かすために、Proにアップグレードしています。
メインの開発マシンはこれになります。

###エディタ(VSCode)
最近は仕事でも使っているので、エディタはこれ。
その時々で必要なプラグインを突っ込みながら作業をしています。
Jetson-nanoにもPCにも入れてあります。
Jetson-nanoに入れるときは、配布されているビルド済みバイナリを使わせていただきました。

[ROSでRealSenseを真面目に動かしてみる３](https://qiita.com/t_kumazawa/items/e64a02490a6415512ff1)を参照。

###GitHub
バックアップやJetson-nanoとPC間のソースコードの交換を考えると、GitHubに入れておくのが一番楽です。
VSCodeのプラグインで色々入れて使いやすくしておきます。

設定は[ROSでRealSenseを真面目に動かしてみる３](https://qiita.com/t_kumazawa/items/e64a02490a6415512ff1)を参照。

Git関連のプラグインはGitHistoryとGitLensを入れておきました。

###Docker+ROS環境
Jetson-nanoにつないだ小さなディスプレイで開発するのが大変になってきたので、Windows10をProにアップグレードしてDocker DeskTopを使うことにしました。
記録を残していたら色々長くなりすぎたので、記事を分離しました。

[Docker＋ROSの環境をWindows10PROで整える](https://qiita.com/t_kumazawa/items/aa541758be558673e76b)