OmniAICreator/Qiita-1.07M huggingface dataset:
python3でコーディングテストに受かるための自分メモ[9/1] (paiza問題振り返り)

今回メンターの方のコードを見て参考になったのでメモします。
### maxやminの比較で無限を使いたくなった時
``` float('inf') ```
###max関数やmin関数を使う時
今まで、配列を指定して配列の中で一番大きい値や小さい値を返り値で返すと思っていたが違った。
値をカンマで引数に複数取るということもできるみたい。

```py
max_money = 0
min_money = float('inf')
max_money = max(max_money, money)
min_money = min(min_money, money)```
```

###for i in 二次元配列:とかの場合
iに配列が入るが、
iの配列が要素四つとかの場合

```py
for a,b,c,d in moneis:
```

のような書き方をすればその要素にアクセスすることも可能である。
C言語　文字化け対処法　（記録）

##コンパイルするとエラーが発生
javaでも同じようなことがあったため、コンパイルするときに何かをすれば解決できるのではと考えた。

##対処法
ターミナルへ入力する

```
chcp 65001
```

その後　コンパイルする。

```
gcc -o hello hello.c
./hello
```

日本語で出力することができた！


https://dianxnao.com/windows10%E3%81%AEgcc%E3%81%A7utf8%E3%81%A7%E4%BD%9C%E3%81%A3%E3%81%9F%E3%82%B3%E3%83%BC%E3%83%89%E3%81%8C%E6%96%87%E5%AD%97%E5%8C%96%E3%81%91%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88%E3%81%AE%E5%AF%BE/
Githubでパスワード認証が廃止されたそうですよ．その対応方法


githubを使ってソースコードを最新に保っています．
お決まりのgit clone コマンドでクローンし編集しpushするという一連の流れです．

そのgit pushでパスワード認証を使っていたのですが，そのパスワード認証が廃止されました．
廃止された日は2021/08/13
めっちゃ最近じゃん．大学のテストなど諸々ありソースいじってなかったのもあって，最初エラーかと思いました．

[【突然GitHubにpushできなくなった】 トークン生成で解決](https://zenn.dev/yuri0427/articles/9587ae6a578ee9)
詳しいことは上記リンクのサイトに書いてあります．

##じゃあその解決策を記載していくよっと



必要になるのは個人アクセストークンなるもの．
それを簡単にいうと，道路の通行券みたいなものだと思います．
トークンがある方はアクセスして書き換えてもいいよー
みたいな？
違ってたら教えてください．

今回私が設定を行った際のバージョンは以下．

gitコマンド：git version 2.30.2
エディタ：viでもgeditでも
OS：Debian11 test版

gitのバージョンは以下のコマンドで確認可能^^

```
git --version
```

pythonとかと同じですね．特に覚えなくても良いでしょう．

githubの公式ページにアクセストークンの作成方法が記載されています．
文字だけで説明するのは難しいので，以下のリンクを参照．
[github　個人アクセストークンを使用する](https://docs.github.com/ja/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token)

私は躓くことなく作成できました．
ここで注意．メールアドレス認証を完了していないと，作成を完了できません．
その辺りはしっかり行いましょう．

作成するときのポイントというか気をつけてほしいのは
トークンは複数作成可能だと考えられます．
複数作成可能でなければ名前をつける必要はありません．
なので，トークンの名前どんな権限でどういう時に使うことを想定しているトークンなのかを明確に名前にしておくといいと思います．

##これでpushできるんだろ？

多分pushできるようになったと思うのでpushしてみましょう．

以下，ターミナル内．

```
Myname@MyPC:~$ git push
Username for 'https://github.com': Username
Password for 'https://Username@github.com':※※ここで作成したトークンを入力する※※
※※コピペで私は通りました※※

Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 350 bytes | 350.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To https://github.com/hoge/hogehoge.git
   c293e9e..ff0e8d3  Myname -> Myname
```

Enumerating objects:~~~~より下は皆さんのリモートレポジトリの内容によって表示は異なると思いますが，見慣れたgit pushの後の表示ですね．

##いやまて，毎回コピペ必要じゃね？これ

そうなんです，毎回コピペしないとpushできません．
そんなだるい話ある？21世紀ですよ今は．
<del>オリンピックだって開催されたし</del>　関係ないだろ

毎回コピペしなくても済む方法もあるんですよ．

##IDとパスワード共に省略する場合の設定です

IDだけ省略する方法もあるみたいだが，今回のPASSWDの省略の目的に沿っていないため却下

手順は以下の通り．ターミナルで作業していきます．

```
vi ~/.netrc
※ファイルが存在しなければ，touchコマンドで作成してください．

以下をnetrc内部に追記する．
machine github.com
login username
passwd 作成したトークン
```

私が作成したトークンは ghp_~~~~~~~~~~となっていました．
おそらく似たような名前であれば大丈夫でしょう．

私はこの手順でpushできるようになりました．
python3でコーディングテストに受かるための自分メモ[9/1] (main関数)

###python3でmain関数
main関数がpythonに必要かどうかわかりません。
あることは知っていましたが、なのでメリットなどを調べてみます。
#####関数定義を後ろに書くことができる
通常関数を呼び出したいとなった時、呼び出し以前にその関数を定義して置かなければいけません。しかし、main関数の中で呼び出す場合main関数より後ろで定義することができるようです。
#####コードの見やすさ
main関数を導入することで、コードの辿りやすくなります。
#####変数名の衝突
main関数の中で使う変数をmain関数を使わなければ、グローバルに定義することになるので、変数名が被ったりなど、無駄なエラーを吐く可能性があります

##### if __name__ == "__main__": の記述について
この記述をすることで単にファイルの最後でmain()関数を呼ぶと
importした時に関数が実行されてしまうのをif文の中で呼び出すことで
避けることができる。
M5Stack Core2: 照度センサーを使う

M5Stack Core2 で Grove の照度センサーを使う方法です。
Port B に Grove を挿して、AD 変換を行います。12bit で変換されるので、0 から 4095 の整数になります。

![IMG_20210901_143820.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/2f16045f-1a10-d4a1-f8d9-34e2fe3711af.jpeg)

Port B に挿します。
![IMG_20210901_143834.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/4fc433fb-6153-49e8-d1ef-e09be8c27372.jpeg)

```text:light_monitor/light_mnitor.ino
// ---------------------------------------------------------------
/*
	light_monitor.ino

						Sep/01/2021
*/
// ---------------------------------------------------------------
#include <M5Core2.h>
#define LIGHT 36

// ---------------------------------------------------------------
void setup() {
	M5.begin();
	  M5.Lcd.setTextSize(3);
	M5.Lcd.println("Light Monitor");
	while (!Serial) ;
	M5.lcd.setBrightness(80);
	pinMode(LIGHT, INPUT);

	delay(1000);

	int value = analogRead(LIGHT);
	Serial.println(value);
}

// ---------------------------------------------------------------
void loop()
{
	int value = analogRead(LIGHT);
	M5.Lcd.setCursor(5,60);
	Serial.println("value = " + String(value));
	M5.Lcd.println("value = " + String(value) + "   ");	
	delay(2000);
}

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

Grove 水分センサーも、インターフェースがアナログ電圧なので、同じプログラムが使えます。
![IMG_20210901_145119.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/fb6d8183-83ba-25cf-a157-6badc8d42c11.jpeg)
Install DreamhouseLWC package

[Install DreamhouseLWC package](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000BrkKrSAJ)

パッケージのIdは以下です
04tB0000000OE9wIAG


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f9792b7f-7c7d-69f4-05a7-cc7e96972855.png)
ファイルのアクセス権を変更するchmodコマンドについて理解する！

##アクセス権
### chmod（チェンジモード）
**ファイルのアクセス権を変更します。**

**`ls -l`**でhoge.jsのファイルの情報を見てみます。

表示されている左側の**`rw-r--r--`**の部分がアクセス権を表しています。**最初の「 - 」を除き**、最初の「 - 」以降の**-を含めて9桁**ありますが、**3桁区切りずつ**で見ていきます。（一番最初の「 - 」の意味ですが、ファイルの種類を表しています。「 **-** 」は普通のファイル「 **d** 」ならディレクトリを表します）

~~~bash
-rw-r--r--  1 example  staff     0  8 30 14:27 hoge.js
~~~

左から3桁ずつそれぞれ、**所有するユーザー( rw- )**、**所有するグループ( r-- )**、**その他のユーザー(r--)**に対する権限を表しています。アクセス権には、**読み取り可能**（ **r** ）、**書き込み可能**（ **w** ）、**実行可能**（ **x** ）の３種類があります。「 **-** 」はその部分のアクセス権がないことを意味しています。

権限を変更する場合、オプションの記述方法には**数字**を用いる方法と**文字**を用いる方法があります（ここでは数字の方を紹介します）


数字で表す場合、読み取り権( **r** )が**4**、書き込み権( **w** )が**2**、実行権( **x** )が**1**となります。

<br>

| **読み取り権** | **書き込み権** | **実行権** |
|:-:|:-:|:-:|
| **r** |  **w** | **x**  |
| **4** |  **2** |  **1** | （）

・**読み取り権** = そのファイルに対して読み取ることはできますが変更は加えられません。
・**書き込み権** = そのファイルに対して変更を加えたり削除することができます。
・**実行権**    = そのファイルを実行することができます。

<br>


例えば`ls -l`とした時に下記`-rw-r--r--`のような表示ですと、最初の「 - 」は除いて３桁づつに区切って考えるので

**`rw-`** = 4+2+0 = **6**, **`r--`** = 4+0+0 = **4**, **`r--`** = 4+0+0 = **4**
合わせて**644**と表すことができます。

~~~bash
-rw-r--r--  1 example  staff     0  8 30 14:27 hoge.js
  ↑  ↑  ↑
  6  4  4
~~~

<br>

また下記のように全てrwxとなっていますと、4+2+1で7となり、**777**ということになります。つまり所有するユーザー、所有するグループ、その他のユーザーそれぞれに全ての権限が付与されている状態となっています。

~~~bash
-rwxrwxrwx  1 example  staff     0  8 30 14:27 hoge.js
  ↑  ↑  ↑
  7  7  7
~~~
上記のような全てのユーザーが全ての権限を持つ、777が付与されているファイルhoge.jsがあるとします。これを**所有するユーザーのみ読み書き可能な権限を持つように変更したい場合**は

~~~bash
chmod 600 hoge.js
~~~
と実行し`ls -l hoge.js`で確認してみると

~~~bash
-rw-------  1 example  staff  0  8 30 14:27 hoge.js
~~~
権限が変更されていることが確認できます。`rw----r--`なら604、`rwxrw-rw-`なら766といった具合です。

このように、「**rwx**」にそれぞれを数字に直した値をオプションに指定してアクセス権を変更します。
wsl2でdockerをインストールする手順の参考にしたメモリンク

基本的なインストール方法はこちらの手順を実施。
https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04-ja

上の手順でsystemdが動かないので、その場合は以下を参照
ubuntu18と20でコマンドが違うのでそのあたり気をつけること。
https://qiita.com/Keiwa/items/390d89c20228edf0b16c#systemd
java エンコーディングMS932にマップできません エラー解消しよう　（記録）

##Java日本語のコンパイルエラー解消
以下のコードをコンパイルしようとしてエラーが発生

```MyApp.java
import java.io.*;

class MyApp{
      public static void main(String[] args) throws IOException
    {
      System.out.println("文字を入力してください");

      BufferedReader br =
        new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
        System.out.println(str + "が入力されました。");

    }
}

```
↓コンパイル実行

``` terminal
javac MyApp.java
```

↓エラー発生

```
MyApp.java:11: エラー: この文字は、エンコーディングMS932にマップできません
        System.out.println(str + "縺悟?･蜉帙＆繧後∪縺励◆");
```

##対処法（コンパイル時のコマンドを変更する）

```
×　javac MyApp.java
↓
〇　javac -encoding utf-8 MyApp.java
```
CIDRの [172.16.0.0/12] スラッシュ以降（/◯◯）は何を表しているのか

AWSのネットワーク構成を学ぶ上で、IPアドレスについて学習しました。
その中で、CIDRという用語が出てきてなんとなく理解はできたものの、
IPアドレスの範囲を定義するって、、、、
CIDRって、、、
と、つまづいたので調べてみたら、良い記事に出会い、"/◯○"について無事理解することができました。

参考：[CIDR (サイダー)とは | 「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word11989.html)


まだ曖昧な部分も多いのでIPアドレスについて調べていく必要がありそうです。
【CSS】Linkがうまく機能しない時

概要
HTMLでLinkタグを使用した際に、カーソルを合わせても矢印がポインターにならず、クリックもできない。

原因
Linkバーと画像を横並びに配置させるために、各要素にposition:fixed, absoluteを適用したことで
Link要素の上に画像要素が重なり、クリックできなくなっていた。

対処法
CSSで各要素にz-index（Link要素に"2", 画像要素に"1"）を指定し、Link要素を画像要素の上に再配置することで解決した。
SplunkのSlack通知内のresults_link変更

Splunkが発行するアラートには、発火の要因となったサーチ結果へのリンクを含めることができる。
このURLのホスト名はデフォルトではSearchheadのサーバー名となるが、SplunkのSearchheadがバランサ配下にある等、サーバー名とURLが異なる場合は、リンク先を変更したくなる。

Email通知などの組み込み通知機構に関しては、`alert_action.conf`の`hostname`で変更できる：

https://community.splunk.com/t5/Reporting/How-to-modify-the-quot-View-Results-in-Splunk-quot-link-from/m-p/202301

が、Slack通知は追加Appなので`<splunk_home>/etc/system/local/...`での設定を認識しない。

Slack通知のhostnameを変更するにはAppの設定ファイル`<splunk_home>/etc/apps/slack_alerts/local/alert_actions.conf`を変更する。

Ansible的に書くとこのようになる：

```yaml
- become_user: splunk
  ini_file:
    path: /opt/splunk/etc/apps/slack_alerts/local/alert_actions.conf
    section: null
    option: hostname
    value: https://example.com:443
  notify: Restart splunk
```
kintoneで２つのテーブルを合体させる方法

今回は2つのテーブルを合体させる方法です。

テーブル1、2に値を入力すると、テーブル3にまとめられます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/fd42439a-6fd7-1c0a-63ce-a34d1d10a749.png)

# アプリの準備

| フィールド種類 | フィールドコード | 備考 |
|:-:|:-:|:-:|
|  テーブル |  テーブル1 |   |
|  テーブル |  テーブル2 |   |
|  テーブル | テーブル3  |   |
|  文字列(1行) | 名前1  | テーブル1用  |
|  数値 | 年齢1  |  テーブル1用 |
|  文字列(1行) |名前2   |  テーブル2用 |
|  数値 | 年齢2  |  テーブル2用 |
|文字列(1行)   |名前3   |  テーブル3用 |
|  数値 | 年齢3  |  テーブル3用 |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536148/9a40f1ef-415b-a95a-1524-88ba351f9d6b.png)

# JavaScript

レコード追加＆編集画面の値変更時のイベントで動かします。
このコード内ではやっていませんが、テーブル3を編集不可にしておくと良いかもしれません。

```js
kintone.events.on(
  [
    "app.record.create.change.名前1",
    "app.record.create.change.名前2",
    "app.record.create.change.年齢1",
    "app.record.create.change.年齢2",
    "app.record.create.change.テーブル1",
    "app.record.create.change.テーブル2",
    // 編集のときも同様にフィールド指定してね。
  ],
  (event) => {
    // テーブル3 消しとく
    event.record.テーブル3.value = [];

    // テーブル3の行になるもの
    const tb3Rows = [];

    // テーブル1 の行を tb3Rowsに追加する
    event.record.テーブル1.value.forEach((element) => {
      if (
        element.id ||
        element.value.名前1.value ||
        element.value.年齢1.value
      ) {
        const r = {
          id: element.id,
          value: { 名前3: element.value.名前1, 年齢3: element.value.年齢1 },
        };
        tb3Rows.push(r);
      }
    });

    // テーブル2 の行を tb3Rowsに追加する
    event.record.テーブル2.value.forEach((element) => {
      if (
        element.id ||
        element.value.名前2.value ||
        element.value.年齢2.value
      ) {
        const r = {
          id: element.id,
          value: { 名前3: element.value.名前2, 年齢3: element.value.年齢2 },
        };
        tb3Rows.push(r);
      }
    });

    // tb3Rowsをテーブル3の行にする
    event.record.テーブル3.value = tb3Rows;

    return event;
  }
);
```
EXCEL_VBAメソッド

列全体を取得・選択する－Columns・EntireColumn
--
参照：https://www.relief.jp/docs/excel-vba-get-entire-column.html
Range("A:A").Select
Range("A1").EntireColumn.Select
Cells(1, 1).EntireColumn.Select
ActiveCell.EntireColumn.Select
Columns(1).Select

EXCEL最後行を取得
--
Sh_S.Activate
MaxRow = ActiveCell.SpecialCells(xlLastCell).Row
'第一行空白がない場合、下記で取得でOK
MaxRow = Sh_S.Cells(Rows.Count, 1).End(xlUp).Row
https://ogohnohito.hatenablog.jp/entry/20131212/p1

Findで検索したRangeの列番号を取得する
--
Range("A1:G7").Find("北海道").Row
MsgBox Range("A1:G7").Find("北海道").Column
EXCEL 　workbookからシートを取得する　非推奨コードの改良　退屈なことはpythonにやらせよう

退屈なことpythonにやらせようの本から自分用の覚書に。

退屈なことはpythonにやらせよう　第12章　Excelシート
公式Github　→ https://github.com/oreilly-japan/automatestuff-ja

#workbookからシートを取得する(p.302)

###元のコード
```python

import openpyxl
wb = openpyxl.load_workbook("example.xlsx")
wb.get_sheet_names()

sheet = wb.get_sheet_by_name("Sheet3")
sheet
```
こうやって書くと、動作はするが「非推奨です」というメッセージが出る。

メッセージ例
DeprecationWarning: Call to deprecated function get_sheet_names (Use wb.sheetnames).
DeprecationWarning: Call to deprecated function get_sheet_by_name (Use wb[sheetname]).
###改良されたコード

```python

import openpyxl
wb = openpyxl.load_workbook("examle.xlsx")
wb.sheetnames

sheet = wb["Sheet3"]
sheet
```

このように書くと非推奨が出ない。

####まとめ
この『退屈なことはPythonにやらせよう』という本、なぜか動かないことが多い。
だから深追いせずに「こんなことができるんだなー」ということを感じるための分厚目の入門書みたいな感じが良いかも。
私はそうやって使ってます。
[備忘録]NestJS＋SequelizeでupdatedAtのみ更新する方法

sequelizeのupdateやsaveで更新する際、カラムに変更がない場合update文自体が発行されずupdated_atが更新されません。
ただ、カラムが更新されなくてもupdated_atは常に更新したい場合があったので、解決策を備忘録として残しておきます。

※画像パスを保持していて、パスは変わらないけど画像が変わった場合にupdated_atで判断したい　等


# 解決策

`changed('updatedAt', true)`を呼びます

具体例として以下のようなコードになります

```typescript
const target = await this.popModel.findOne({ where: { id } });
if (target) {
  ・・・    
  target.changed('updatedAt', true);
  return target.save();
```

以下のようにupdated_atのみ更新されるクエリが発行されるようになります

```sql
UPDATE `test` SET `updated_at`=? WHERE `id` = ?
```


# 参考

https://stackoverflow.com/questions/42519583/sequelize-updating-updatedat-manually/52415630
Blazor Server、AWS EC2 による お気軽　Webサイト作成

##作成手順

##1.AWS EC2 インスタンスの作成
・amazon linux 2 AMI を選択
![001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666811/1246182f-b28b-0cfb-ba7a-284151edad4e.jpeg)


##2.インスタンス作成後の処理
・Elastic IP 作成
・セキュリティーグループの設定
![002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666811/e3c6f8fe-691c-646f-75a3-ebded52648fb.jpeg)

・Webサーバー nginx　のインストール

```
yum update
yum install nginx
```
・.net core 5.0 のインストール

```
yum install dotnet-sdk-5.0
```

##3.Blazor Server アプリ作成

・適当にアプリを作成 ※取り合えず　BlazorPro　と言う名称で作成

##4.Blazor 発行

・linux に上げるのに発行処理
![005.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666811/af9892ee-accd-4205-30ad-3b9948b5523b.jpeg)


##5.アプリを　AWS にUP

・WinScp でAws に発行したアプリを転送
![004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666811/c62e8634-6bd3-c55d-f129-8c3aa2057c7e.jpeg)


##6.AWS 側での設定

・自己証明書作成

1)秘密鍵(Private Key)を作成

```
openssl genrsa 2048 > server.key
```

2)証明書署名要求(CSR)を作成

```
openssl req -new -key server.key > server.csr
```

3)自己署名証明書を作成

```
openssl x509 -days 3650 -req -sha256 -signkey server.key < server.csr > server.crt
```

・nginx の設定

1)設定ファイルを作成
/etc/nginx/conf.d/default.conf

```
server {
	server_name xxx,xxx,xxx,xxx *.xxx,xxx,xxx,xxx;
		location / {
		proxy_pass http://localhost:5000;
		proxy_http_version 1.1;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "Upgrade";
		proxy_set_header Host $host;
		proxy_cache_bypass $http_upgrade;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Forwarded-Proto $scheme;
	}
	listen 443 ssl; # managed by Certbot
	ssl_certificate /etc/nginx/ssl/server.crt;
	ssl_certificate_key /etc/nginx/ssl/server.key;
}
server {
		if ($host = xxx,xxx,xxx,xxx) {
		return 301 https://$host$request_uri;
	}
	listen 80;
	server_name xxx,xxx,xxx,xxx *.xxx,xxx,xxx,xxx;
	return 404;
}
```


・サービス設定

1)設定ファイル作成

/etc/systemd/system/BlazorPro.service

```
[Unit]
Description=適当に設定

[Service]
WorkingDirectory=/var/www/BlazorPro
ExecStart=/usr/bin/dotnet /var/www/BlazorPro/BlazorPro.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=www
Environment=ASPNETCORE_ENVIRONMENT=Production

[Install]
WantedBy=multi-user.target
```

・サービスの起動

```
systemctl restart nginx
systemctl restart BlazorPro
```

#7.アプリの確認
![006.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666811/06bfcaba-7524-50e7-a13f-68b8e0a89284.jpeg)
いじるコードがどこでどう使われているかサクッと確認 / using VSCode

久しぶりに事故った。。。まあ、冷や汗かきました。はい。:sweat_smile:
どう事故ったかというと、後から振り返れば初歩的な事。
修正対象の処理が他に使われていないか、どこかがデグレしないかの調査不足が原因で、全く関係ないと思いこんでいた機能を壊してしまった。

利用箇所調査してから実際に改修するまでの間に、当初は1箇所の機能しか利用していなかったメソッドが別の機能でも使われるようになったことに、気づかず・・・ご想像の通り無意識にデグレを起こしてしまったわけです。

なんで直前でもう一回調べてなかったのか〜、とか、反省の気持ちはいっぱいになって悔しいだけだと得るものなにもないので、この事故からも少しでも学ひを残したく、仕事で使ってる Visual Studio Code で「かんたんに」メソッドの利用箇所を調べる方法とその調査結果を残す方法（調査エビデンスも大事！）を備忘録にしてみた。

いつか、誰かのためになれば！ということで！

## Visual Studio Code でメソッドの利用箇所を検索する時

方法は、2つあります。
1. 「検索」機能を使う。
2. 「すべての参照箇所を探す」機能使う。

### 「検索」機能を使う。

メソッド名をペーストするか、ハイライトした状態で command + shift + f で検索するだけで、サイドバーにある検索結果に文字列での結果が出てきます。
この検索結果は、「新しい検索エディターで開く」（以下のスクショの右から2つ目のアイコン）と、見やすくておすすめです。

![スクリーンショット 2021-02-17 17.43.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155732/afdfece7-74a0-2551-cbd4-a45bb2755697.png)

この検索結果は、「名前を付けて保存」で保存できます。保存をすると ```.search``` という拡張子のファイルに書き出され、また開くことができるようになります。
調査結果をエビデンスとして残すとき、便利だと思います。

###  「すべての参照箇所を探す」機能使う。

メソッド名にカーソルをあわせた状態で ```Find All References``` を右クリックメニューから選ぶかショートカットを叩くと、今見ている箇所のすぐ下に簡易的な検索結果が表示されます。
サクッと確認するときは便利な機能です。コンパクトな表示なので、スクショで残すには丁度いいです。
Unity:オブジェクトの動きの設定とprefabのclone作成

#Unity備忘録

##Objectの移動

```C#:
void Move()
    {
        transform.position += new Vector3(0, 4.5f, 0) * Time.deltaTime;
    }
```
上記スクリプトでy軸方向に一定速度でオブジェクトが移動する。

```C#:
    void Move()
    {
        float x = Input.GetAxis("Horizontal");
        float y = Input.GetAxis("Vertical");

        transform.position += new Vector3(x, y, 0) * Time.deltaTime * 4f;
    }
```
方向指示キーでオブジェクトを動かす場合、Input.GetAxisをnew Vector3の中で受け取る。

##Prefabのクローニング

```C#:
    void Clone()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Instantiate(Prefab,  PrefabPoint.position, PrefabPoint.rotation);
        }
    }
```
取得したPrefub Objectをスペースキーが押されるときにInstantiateで呼び出す場合、上記のように記載。呼び出す場所の位置（position）と回転(rotation)も指定する必要がある。

##実装
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">プレイヤーを方向指示キーで動かし、玉の発射の実装。<br>慣れると、10分ぐらいで実装可能。<br>Unity C#は慣れるとわかりやすい言語だな再認識。<a href="https://twitter.com/hashtag/%E3%82%B9%E3%82%BF%E3%82%B8%E3%82%AA%E3%81%97%E3%81%BE%E3%81%A5?src=hash&amp;ref_src=twsrc%5Etfw">#スタジオしまづ</a> <a href="https://t.co/8QWBZ399xV">https://t.co/8QWBZ399xV</a> <a href="https://t.co/iwM6WmCnMr">pic.twitter.com/iwM6WmCnMr</a></p>&mdash; Unity勉強中の整形外科医：北城雅照|医療者向けプログラミングスクール「もいせん」開校！ (@teru3_kitashiro) <a href="https://twitter.com/teru3_kitashiro/status/1432905946813063168?ref_src=twsrc%5Etfw">September 1, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
実際の動きと、書いたスクリプト

```C#:PlayerShip.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerShip : MonoBehaviour
{
    public GameObject BulletPrefab;

    public Transform FirePoint;

    // Update is called once per frame
    void Update()
    {
        Move();
        Shot();
    }

    void Move()
    {
        float x = Input.GetAxis("Horizontal");
        float y = Input.GetAxis("Vertical");

        transform.position += new Vector3(x, y, 0) * Time.deltaTime * 4f;
    }

    void Shot()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Instantiate(BulletPrefab, FirePoint.position, FirePoint.rotation);
        }
    }
}
```

```C#:Bullet.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bullet : MonoBehaviour
{

    // Update is called once per frame
    void Update()
    {
        ShotMove();
    }

    void ShotMove()
    {
        transform.position += new Vector3(0, 4.5f, 0) * Time.deltaTime;
    }
}
```
Go言語で年度を取得する

日本だけだと思いますが、年度という概念を使わないといけない状況に陥ったので書いてみました。
`nend_getter`に「年」と「月」を渡せば、年度が返ってくるっていうだけのものです。


コードの全文です。

```golang
package main

import (
	"fmt"
	"time"
)

func nend_getter(year int, month int) int {
	var set_year int
	if month <= 3 {
		// 3月以前ならば、西暦から1年引く
		set_year = year - 1
	} else {
		set_year = year
	}
	return set_year
}

func main() {
	// Timezoneの設定
	time.Local = time.FixedZone("JST", 9*60*60)
	time.LoadLocation("JST")
	// 本日の表示操作
	fmt.Println("Year:", time.Now().Year())
	fmt.Println("Month:", int(time.Now().Month()))
	fmt.Println("Day:", time.Now().Day())

	//現在の年度
	nendo := nend_getter(time.Now().Year(), int(time.Now().Month()))
	fmt.Println("nendo : ", nendo)

	// 2000年4月の場合 -> 2000
	nendo = nend_getter(2000, 4)
	fmt.Println("nendo : ", nendo)
	// 2000年3月の場合 -> 1999
	nendo = nend_getter(2000, 3)
	fmt.Println("nendo : ", nendo)
}
```

上記を実行するとこんな感じになります。

```bash
$ go run main.go
Year: 2021
Month: 9
Day: 1
nendo :  2021
nendo :  2000
nendo :  1999
```

使う機会は少なそう。
Rubocop-airbnbを使ってルール遵守の確認

##目次
- 概要
- 導入方法
- ファイルの作成・記載
- 指摘事項
- 総括
- 参考記事

##概要
Rubocopとはコード解析・検査をしてくれるGemです。具体的にはコードに対して、一行が長いよ、endがないよといったことをあるルールに則り指摘（任せれば修正も）してくれます。
今回使用するRubocop-airbnbはデフォルトのルールではなく、Airbnb社が決めたルールで解析してくれるGemです。
[Githubはこちら](https://github.com/airbnb/ruby/tree/master/rubocop-airbnb)

尚、今回、私自身がPF制作を終えて、ある一定のルールの下、コーディング出来たのかということを確認するために導入しました。
そのためGemに任せた修正は行わず、一つ一つ内容を確認しました。


##導入方法

``` Gemfile.
group :development, :test do
  gem 'rubocop-airbnb'
```

bundle installしましょう。

##ファイルの作成・記載
アプリのフォルダ直下に.rubocop.ymlと.rubocop_airbnb.ymlを作成します。
/アプリ名/.rubocop.yml
/アプリ名/.rubocop_airbnb.yml
になっていればOKです。

```.rubocop.yml
inherit_from:
  - .rubocop_airbnb.yml

#解析から除外するファイルやフォルダを指定します。
#ご自身に合わせて加除修正を行ってください。
AllCops:
  Exclude:
    - 'db/**/*'
    - 'bin/*'
    - 'config/environments/*'
    - 'config/application.rb'
    - 'config/initializers/*'
    - 'config/spring.rb'
    - 'lib/tasks/*'
    - 'vendor/**/*'
    - 'path/ruby'
    - 'test/**/*'
    - 'spec/**/*'
    - 'config/**/*'
```
```.rubocop_airbnb.yml
require:
  - rubocop-airbnb
```
これで記載完了です。

```
$ bundle exec rubocop --require rubocop-airbnb
```
で検査できます。

##指摘事項
約80か所の指摘がありましたがインデント、改行がメインでした。
文言通りに確認していくとすぐに解決することができますが、
パッと見て理解できなかったもの、解決に至らなかったものをご紹介したいと思います。
###Freeze mutable objects assigned to constants.
[参考](https://qiita.com/yukiyan/items/39f945c55b6dc5e11ed7)
正規表現のバリデーションをかけた箇所への指摘。
定数を書き換えられないようにfreezeメソッドで固定せよとのこと。

```
/[ァ-ヴ]/.freeze
```
こちらで解決

###Inconsistent indentation detected.
一貫性のないインデントを検出したとのこと。不審な点が見当たらず未解決。
###Use 2 (not 0) spaces for indentation. def index
[類似事例](https://qiita.com/rarrrrsQ/items/dee869577fdcc77cc120)を参考にするも未解決。

##総括
企業やアプリケーション毎にコーディングルールがあり、それに準じて記載していく必要があるということは分かっていました。
自分なりにルールを設けて記載していたつもりでしたが、表記ゆれが確認できてしまいました。（Airbnb社とのルール差はともかく。）
この点は反省し、今後一層コーディングルールの順守を心がけていこうと思います。

##参考
https://qiita.com/yokoyan/items/76e6b330a6b9d908d6fb
https://qiita.com/tomohiii/items/1a17018b5a48b8284a8b
https://qiita.com/ki_87/items/c09f2c7b924669bb9600
APD01(BluePrismプロフェッショナルデベロッパ資格) 試験合格記 

# 本記事の対象者
・BluePrismを実務で使用している
・BluePrismプロフェッショナルデベロッパ資格(以降APD01)の資格に興味がある・取得したい
・BluePrismデベロッパ認定試験（AD01）を取得してから6ヶ月経過(=APD01受験条件)
・BluePrismプロフェッショナルデベロッパ資格(以降APD01)の試験傾向/試験対策が知りたい

# 費用
・試験代(¥16,000)＋非公式問題集(¥1,000-￥3,000程度)
※非公式問題集は任意

# 出題内容
全50問程度
全てが客観的選択式問題で記述式はなし
※試験範囲は後述の「学習方法」セクションにて記載

# 学習時間

20時間程度(実務経験ありの場合の目安)
実務で触ったことがない分野があれば、分野ごとに＋5-10時間程度を目安

# 学習方法
・試験範囲のドキュメントを読み込む　※理解に必要ならメモなどにまとめる
・実務で触ったことがない機能を触ってみる
・非公式問題集を解く　※任意

自分の場合は上2項目を6:4くらいでやったと思います。
試験はドキュメント内容を基にしていそうなので、ドキュメントの内容を理解していることが非常に大事といえます。

非公式問題集は自分はUdemyがあるようで、こちらの試験体験記を参考ください。

https://newgraduate19-rpa.hatenablog.com/entry/20200914/1600088146

# 学習のポイント
試験範囲・読み込むべきドキュメント・それらの取得方法はこちらの記事がまとまってます。

https://www.ebocean.work/entry/2020/06/12/085747

これを踏まえて読み込むべきドキュメント・出題傾向をまとめてみましたのでご参考ください。
演習があるドキュメントは演習も一通りやることをおすすめします。
※出題傾向は試験受験時のメモ及び記憶由来なので、この内容を過信するのはNGでお願いします。

いずれにせよ、ドキュメントから出題が前提となると思うので各ドキュメントは全般読み込むのをお勧めします。


# 読み込むべきドキュメント・出題傾向まとめ

## Development Best Practice
対象ドキュメント内容全般、BluePrismプロセステンプレート内容

## Browser Automation Guide
アプリケーションモデラーの使い方、妥当なスパイモード、妥当なマッチ条件等
※対象ドキュメントは参考レベル、アプリケーションのオブジェクト開発で手を動かすことが望ましい

## Data Sheet – Credential Manager
対象ドキュメント内容全般

## Exception Handling Guide
対象ドキュメント内容全般 

## Java Automation Guide
Java自動化における注意点全般(対象ドキュメントに記載あり)

## User Guide - Login Agent
対象ドキュメント内容全般、Login Agentプロセスにはどんな機能があるか

## Mainframe Automation Guide/Guide to Using the Mainframe Spy Tool
メインフレームでの要素スパイの仕方、キー送信の特殊文字(対象ドキュメントに記載あり)

## Surface Automation of Terminal Emulators / Surface Automation Basic Training / Surface Automation Advanced Training
ドキュメントの演習内容全般

## User Guide - Web Services
Web Service使用における注意点、扱えるデータ型(対象ドキュメントに記載あり)

## Work Queues Guide / Advanced Work Queues Guide
タグ、ステータス、優先度(対象ドキュメントに記載あり)

## その他参考ドキュメント不明の出題傾向
BluePrism のライセンス形態の理解
オブジェクト・アクションの妥当な分割単位
手書きPDF・構造化PDFそれぞれの自動化手法
動的型付け言語、静的型付け言語とは

## 静的型付け言語
あらかじめ方が決まっていてそれ以外は使えない。整数値を扱うから、負の数はダメみたいな
方がないとコンパイラは機械語に変換できない。機械語に方と言う情報は厳密にはない。メモリ上でその変数の情報にどのくらいのメモリを確保し、そのデータはどの様に扱うモノなのかと言う判別ができるくらい。
## 動的型付け言語
プログラムを書くときに変数や関数に何が入っているかと言うのが特に決まってない
プログラマーは、変数や関数になんとなく、なんとなくこんな感じのデータが入るであろうと言うことを予測するだけ。型の管理はインタプリタやコンパイラが実行時にしてくれる
### 利点
型とデータの大きさを気にする必要がない
何が入るかわからない、設計が大変と言うときに最大値のみが決まっているのでクライアント側はとりあえずは受け取れはする。みたいな
動的型付けの型を付けるタイミングというのは、必ずプログラムを実行している時になります。なので、既にそのデータが小さいか、大きいかを確認してからサイズを決めているのでは効率が悪すぎます。なので、値やデータを扱う場合は、大きめに確保されて実行されます。
### 欠点
参考のコード読めば読めばわかる


## そもそも型とは

### 機械語・物理メモリ上における抽象的な数値の羅列や数値の有限範囲に意味を持たせることが「型の定義」
データというのは抽象的なモノ、コード上では文字列や数値、理論値で合ったとしても機械語・物理メモリ上ではただの数値の羅列でしかない。
コンピューターにおいて、データは有限数であり、上限がある。
機械語・物理メモリ上における抽象的な数値の羅列や数値の有限範囲に意味を持たせることが「型の定義」

## コンパイル
コンパイラと呼ばれる実行ファイルにソースコードを読ませることで、別の言語形態(機械語に変換、別の高級言語に変換など)に変換(翻訳)することを「コンパイル(翻訳って意味)」という


## インタプリタ
インタプリタと呼ばれる実行ファイルにソースコードを読み込ませることで翻訳・実行を同時に行うことを主とする形態を「インタプリタ(通訳者の意)」と言います。

## ビルド
コンパイル・リンク等を行い、パッケージなどを生成すること

## リンカ
ソフトフェアの開発ツールの一つで、機械語(マシン語)で記述されたプログラムを連結、編集して実行可能ファイルを作成するソフトウェア
オブジェクトコートの収められたファイルをもとに様々な処理や変換行い行い、OS上で起動可能な実行可能形式のファイルを作成する


## オブジェクトコード
コンパイラなどによって機械語によって変換されたプログラムそのままOSから起動できる実行ファイルとはならない。

## インタプリタとコンパイルの翻訳後
元のソースコードが残るか残らないか。インタプリタは翻訳者が覚えているから残るがコンパイラは翻訳時に捨てられる。元のコードが存在しなくなり、もしそのときに「型」の意味が不明であれば辿ることができなくなり、実行させられなくなる。

## ヒープ領域
プログラム実行時にOSからソフトフェアに対して一定量に与えられるメモリ領域
ソフトウェアは必要に応じて動的にヒープ領域を確保・開放できる
データの仮置き場や臨時の作業台の様な存在
どの順序で確保・解放するかはフォフトウェア側で自由に決められる。
あらかじめどのくらいのデータ領域が必要なのか分からなくても、ソフトウェア側が必要に応じて対応できます。しかし、それらの判断をソフトウェアに任せることになる以上、全体の管理は難しくな

## スタック領域
こちらも一時的に確保されるメモリ領域
スタック領域は、確保したのとは逆の順番で解放するのが特徴
ヒープ領域の様にソフトウェアが任意に確保と開放を決められない。
保存が必要な期間だけメモリ領域を確保し、不要になったら解放する様に行われる
つまりあらかじめ割り当てられるメモリ領域が決まっている
MAVLinkのCRCチェックサム(Checksum)計算

MAVLinkのCRCチェックサム(Checksum)は、MAVLinkの送信と受信で使っています。

MAVLinkの送信側と受信側で、MAVLink XML定義ファイルを変更した場合、メッセージ名前、フィルード名前、フィルードタイプ、フィルード長さ等差異よりChecksumが不一致で、MAVLink受信失敗になります。

# Checksum の概要
Checksumは、uint16_tのデータでMAVLinkの送信側と受信側のメッセージ内容が一致するかをチャックします。

MAVLink送信側、head、payloadとCRC_EXTRAからChecksumを計算してメッセージに２バイトChecksumを追加して送信します。
MAVLink受信側、送信側と同じでhead、payloadとCRC_EXTRAからChecksumを計算して受信したメッセージの２バイトChecksumと比較して同じプロトコルのメッセージかどうかをチャックします。

MAVLinkのデータ構造は、[MAVLinkの入門](https://qiita.com/k-koh/items/9e9c1694dbb5a2a4117a)を参考してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/468d54aa-415d-009d-eb74-187505ef0724.png)

# CRC_EXTRA の計算
CRC_EXTRAは、uint8_tのデータでMAVLinkの送信側と受信側のメッセージ定義が一致するかをチャックします。

CRC_EXTRAは、メッセージ定義XMLファイル（メッセージ名前、フィルード名前、フィルードタイプ、フィルード長さ）を基づいて１バイトのデータを計算します。

CRC_EXTRA 計算詳細は、[公式サイト](https://mavlink.io/en/guide/serialization.html#crc_extra)を参考してください。

# Checksum の計算
Checksum 計算詳細は、[MAVLink source code](https://github.com/mavlink/c_library_v2/blob/e0e24de6228326101ff85dd5cdea638f2569c70e/mavlink_helpers.h#L256)を参考してください。

```
	uint16_t checksum = crc_calculate(&buf[1], header_len-1);
	crc_accumulate_buffer(&checksum, _MAV_PAYLOAD(msg), msg->len);
	crc_accumulate(crc_extra, &checksum);
```

#### Step1 Checksumを初期化
```
#define X25_INIT_CRC 0xffff
static inline void crc_init(uint16_t* crcAccum)
{
        *crcAccum = X25_INIT_CRC;
}
```

#### Step2 メッセージのHeadからChecksumを計算

```
uint16_t checksum = crc_calculate(&buf[1], header_len-1);
```

MAVLinkメッセージのHeadからChecksumを計算するイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/163b99e4-6e4d-eb03-ea40-cfabdcef5506.png)

#### Step3 メッセージのpayloadからChecksumを計算

```
crc_accumulate_buffer(&checksum, _MAV_PAYLOAD(msg), msg->len);
```

MAVLinkメッセージのpayloadからChecksumを計算するイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/7f523397-c442-2fed-3de4-ccc474e48457.png)

#### Step4 メッセージのCRC_EXTRAからChecksumを計算

```
crc_accumulate(crc_extra, &checksum);
```

#### Step5 受信側でChecksumを比較
MAVLink受信側で、受信したメッセージから計算したChecksumと受信したChecksumを比較します。
Checksumが不一致場合、MAVLink受信失敗になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386259/32b6b155-73a1-c69d-720f-67c338cdf5af.png)
git導入

#git導入

##やったこと
1. gitインストール
    1. フォルダ作成
    1. branch作成
1. githubの接続
    1. githubでリポジトリ作成
    1. githubのトークン作成
1. 試コミット2件

###gitインストール・フォルダ作成
####フォルダ作成
Users/userの下層にawesomeを作成した。

```sh
bigmona-MacBook-Pro:~ user$ mkdir awesome
bigmona-MacBook-Pro:~ user$ cd awesome
bigmona-MacBook-Pro:awesome user$ git init
Initialized empty Git repository in /Users/user/awesome/.git/
```

####branch作成
sub1というbranchを作成後、スイッチ。

```sh
bigmona-MacBook-Pro:awesome user$ git branch sub1
bigmona-MacBook-Pro:awesome user$ git checkout sub1
Switched to branch 'sub1'
bigmona-MacBook-Pro:awesome user$ git branch
  master
* sub1
```

###githubの接続
####githubでリポジトリ作成
youtube_logというpublicのリポジトリを作成。
https://github.com/BIGMONA/youtube_log

####githubトークン作成
下のコードでリモートリポジトリにgit pushを試みるが失敗。

```sh
bigmona-MacBook-Pro:awesome user$ git remote add origin https://github.com/BIGMONA/youtube_log.git
```

下のようなエラーが発生。調査すると、2021年8月13日にgithubへのパスワード認証が廃止されていた。代わりに、トークン作成もしくはSSHによる接続が求められている。
SSHは公開鍵・秘密鍵を作成する必要があり、該当の鍵はPC内にフォルダを作成して置いておく必要があるっぽかったので、セキュリティとデバイス変更時に引き継ぎの観点から、めんどくさそう。よって、トークン作成にする。

```sh
Username for 'https://github.com': BIGMONA
Password for 'https://BIGMONA@github.com': 
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
fatal: Authentication failed for 'https://github.com/BIGMONA/youtube_log.git/'
```

###試コミット2件
####コミット内容
1. sub1というbranchにhello.htmlの内容を変更
1. sub1というbranchにgoodmorning.htmlファイルを追加

```sh
terminal:hello.htmlを追加
bigmona-MacBook-Pro:awesome user$ git push origin sub1
Username for 'https://github.com': BIGMONA
Password for 'https://BIGMONA@github.com': 
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 638 bytes | 638.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0), pack-reused 0
remote: 
remote: Create a pull request for 'sub1' on GitHub by visiting:
remote:      https://github.com/BIGMONA/youtube_log/pull/new/sub1
remote: 
To https://github.com/BIGMONA/youtube_log.git
 * [new branch]      sub1 -> sub1
```
```sh
bigmona-MacBook-Pro:awesome user$ git add goodmorning.html
bigmona-MacBook-Pro:awesome user$ git commit -m "add file goodmorning"
[sub1 30aa592] add file goodmorning
 1 file changed, 12 insertions(+)
 create mode 100644 goodmorning.html
```

##課題
###今後やりたいこと
1. リモートリポジトリにpushしたデータを適用すること（多分marge）
1. SSHでローカルリポジトリ接続
1. リモートリポジトリとサーバーの接続

##参考サイト
- https://techacademy.jp/magazine/6235
- https://techpr.info/github/github-token-ssh/
- https://atmarkit.itmedia.co.jp/ait/articles/1701/24/news141_3.html#:~:text=%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%81%AEURL%E3%81%AF,%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E3%81%99%E3%82%8B%E3%81%A8%E8%A1%A8%E7%A4%BA%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82
[2022年10月版] FreeRTOS Windowsデモ

# はじめに

**「シンプルにFreeRTOSを体験する」**
これを目的とした記事です[^1]。

先に書くと、**とってもかんたん**です！

[^1]: 過去に[こんな記事](https://qiita.com/imagou/items/42c687402e6e58fccddb)も書いていたりしますが、表面上はuITRON I/Fを被せてあるので・・・

# 本編

## 環境

- Windows環境
    Windows10 Pro 64-bitで動作確認

- Visual C++ 2019
    Microsoft Visual Studio Community 2019 Version 16.11.19 で動作確認

- FreeRTOS 202112.00
    GitHub最新版（執筆現在）

- Git for Windows
    適宜。

## 手順

### GitHubクローン

以下コマンドで、**サブモジュールも含めた形で**クローンします。

`git clone https://github.com/FreeRTOS/FreeRTOS.git --recurse-submodules --depth 1`

### Windowsデモプロジェクトを開く

`FreeRTOS\FreeRTOS\Demo\WIN32-MSVC-Static-Allocation-Only`[^2]に移動、`WIN32.sln`をVisual Studioで開きます。

[^2]: 動的メモリ確保が好きでないので、`Static-Allocation-Only`としています

### ビルド＆実行

ビルドして実行すると、以下がコンソールに出力されます。

```console
No errors - tick count 2501 - number of tasks executing 4
No errors - tick count 5001 - number of tasks executing 4
No errors - tick count 7501 - number of tasks executing 4
No errors - tick count 10001 - number of tasks executing 4
```

はい、無事FreeRTOSが動作しています。目的達成です！

## （軽く）解説

* タスク・キュー・セマフォ等のリソースを生成・解放するタスク
* 上記が正常動作しているかを定期的にチェックするタスク

これらのタスクが動作するデモなのであります。

`main.c`のコードをグリグリと弄り回せば、様々な動作確認ができ、知見が広がると思います！

# おわりに

要は

**GitHubからコード取得してビルドして動かすだけ**

なのですが、ネットで端的な情報が見つからなかったため、記載してみました。
多かれ少なかれ、何らかの形で、この記事が役に立てば幸いです！
wls2でapt-get updateがhostへ接続できない

# 状況は？

```
$apt-get update
Err:1 http://archive.ubuntu.com/ubuntu focal InRelease
  Temporary failure resolving 'archive.ubuntu.com'
Err:2 http://security.ubuntu.com/ubuntu focal-security InRelease
  Temporary failure resolving 'security.ubuntu.com'
Err:3 http://archive.ubuntu.com/ubuntu focal-updates InRelease
  Temporary failure resolving 'archive.ubuntu.com'
Err:4 http://archive.ubuntu.com/ubuntu focal-backports InRelease
  Temporary failure resolving 'archive.ubuntu.com'
Reading package lists... Done
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/focal/InRelease  Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/focal-updates/InRelease  Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/focal-backports/InRelease  Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://security.ubuntu.com/ubuntu/dists/focal-security/InRelease  Temporary failure resolving 'security.ubuntu.com'
W: Some index files failed to download. They have been ignored, or old ones used instead.
```

# やったこと
- ```/etc/wsl.conf```を作成し、以下を記述する。

```
[network]
generateResolvConf = false
```
- ```/etc/resolve.conf```を書き換える  
vimで書き換える際、E166のエラーで書き換えられなかったが、以下のことをしたら動いた。

```
$sudo rm /etc/resolve.conf
$sudo vim /etc/resolve.conf
```
書き換える内容は```nameserver 8.8.8.8```
Pythonで動的にSoql作成

###・要件
Salesforceの項目変更される場合、Soqlに動的に反映する


###・案　Pythonのsimple salesforceで実行する
#####Pythonのインストール（WindowsStoreで）
pip更新：python.exe -m pip install --upgrade pip
simple-salesforceの追加：pip install simple_salesforce


#####ログイン情報
security_tokenが‘’でも、下記用にSandbox（test)またProduct（login)でログインできます。
※DeveloperVersionができない？

```py
sf = Salesforce(username='userid', password='password', security_token='', domain='test')
```



#####実装とCSV出力
※Csvに先頭属性という列は余計に出力されている

```py
from simple_salesforce import Salesforce
import csv,unicodecsv


#(credentials hidden)

#sandbox or product OK

sf = Salesforce(username='Tableau@jp.ricoh.com.cirus.step2TBL', password='RjKanrinnnn', security_token='', domain='test')   
#developer version is not ok ???
#sf = Salesforce(username='chunqiang.hu_2@gmail.com', password='Hunnnnn', security_token='', domain='login')

desc = sf.Account.describe()  

# Below is what you need

field_names = [field['name'] for field in desc['fields']]

soql = "SELECT {} FROM Account".format(','.join(field_names))

print('sql:',soql)

results = sf.query_all(soql)
jsonD= results['records']

cnt = 0
with open('c:/tmp/test.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    for d in jsonD:
        if cnt == 0:  #csv header
            writer.writerow(d.keys())
            print(d.keys())
            print(d.values())
            cnt += 1

        writer.writerow(d.values())


print('result:OK')	
```
Big Sur 上の VMWare Fusion で rr を実行できない問題は解決不能


# VMWare上で rr を実行すると失敗する
[rr](https://rr-project.org/) はLinux上で動作するデバッグツールの一つ
便利そうなので試してみようとしたところVMWare12以降でLinuxを動作させている環境だと rr を利用できないことがわかった

# 原因
VMWare12(Big Sur対応版)からmacOSのカーネル拡張機能を使わずにHypervisor APIを使った実装になった。この結果として vPMC (Virtual CPU Performance Monitoring Counters) に対応できなくなったようだ。

# 実行失敗例
```
$ rr record ./a.out
[FATAL /.../rr/src/PerfCounters.cc:314:start_counter() errno: ENOENT] Unable to open performance counter with 'perf_event_open'; are perf events enabled? Try 'perf record'.
=== Start rr backtrace:
rr(_ZN2rr13dump_rr_stackEv+0x44)[0x55e94151a66c]
rr(_ZN2rr15notifying_abortEv+0x53)[0x55e94151a623]
rr(_ZN2rr12FatalOstreamD1Ev+0x30)[0x55e9413bd418]
rr(+0x347f2b)[0x55e9413e9f2b]
rr(+0x348bf6)[0x55e9413eabf6]
rr(+0x348e90)[0x55e9413eae90]
rr(+0x3490bf)[0x55e9413eb0bf]
rr(_ZN2rr12PerfCounters23default_ticks_semanticsEv+0x1d)[0x55e9413eb247]
rr(_ZN2rr7SessionC2Ev+0xec)[0x55e9414c2970]
rr(_ZN2rr13RecordSessionC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EESD_RKNS_20DisableCPUIDFeaturesENS0_16SyscallBufferingEiNS_7BindCPUES8_PKNS_9TraceUuidEb+0x5e)[0x55e941402092]
rr(_ZN2rr13RecordSession6createERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EESB_RKNS_20DisableCPUIDFeaturesENS0_16SyscallBufferingEhNS_7BindCPUERKS7_PKNS_9TraceUuidEb+0x822)[0x55e941401ce0]
rr(+0x3530bf)[0x55e9413f50bf]
rr(_ZN2rr13RecordCommand3runERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE+0x2d5)[0x55e9413f5ceb]
rr(main+0x21b)[0x55e94153326d]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x7f05e848dbf7]
rr(_start+0x2a)[0x55e9413045aa]
=== End rr backtrace
Aborted (core dumped)
```

# VMWareの一次情報

There is no resolution とのこと

https://kb.vmware.com/s/article/81623 

> Virtualized Performance Monitoring Counters(vPMC) are not supported by VMware Fusion on macOS Big Sur or VMware Workstation with Hyper-V (81623)
EC2で最新バージョンのredashを立ち上げる方法

##前提
redashは公式からamiが提供されており、それをもとにEC2インスタンスを立ち上げることで簡単にredashを体験することができる。

しかし、amiのredashバージョンは、おそらくその時点での安定版が採用されており、最新のベータ版でのみ提供されている機能を使うにはバージョンアップを行う必要がある。

この記事では、redashのEC2インスタンスの立ち上げ方法に加えて、redashのバージョンを上げる方法についても紹介する。


##手順
###1. amiからredashのEC2インスタンスを立ち上げる
EC2でのredashの起動方法を紹介した記事は既に多数あるため、ここでは要点だけ抑えて箇条書きにする。

・EC2インスタンス起動ウィザードを開き、redash公式から提供されているamiを指定
　※リージョンに注意

https://redash.io/help/open-source/setup#do

・インスタンスのスペックを指定
　※お試し程度であればt2.smallでも十分らしいが、自分の場合はバージョンアップしたせいかスペック不足で動作が不安定になったため、t2.mediumを使用

・他項目は状況に合わせて適宜設定

・EC2インスタンスのターミナルに接続できるか確認
　※redashのamiはubuntuをもとに作られているので、ユーザ名が「ec2-user」ではなく「ubuntu」になることに注意

###2. EC2インスタンスに接続してバージョン確認

いちばん手っ取り早いのは、立ち上げたredashのwebページから確認する方法。
![スクリーンショット 2021-09-01 10.22.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805423/8c704a6e-d661-f713-60b4-bcbadea19afd.png)

EC2インスタンスのターミナルから、直接docker-compose.ymlをみてバージョンを確認する手もある。
初めてredashにアクセスしたときのセットアップが済んでいない場合には、こちらのほうが早いかもしれない。

```:バージョンの確認
# sudo su
# cat /cat/redash/docker-compose.yml
version: "2"
x-redash-service: &redash-service
  image: redash/redash:9.0.0-beta.b42121
  depends_on:
    - postgres
    - redis
  env_file: /opt/redash/env
  restart: always
  …
  …
  …
```

バージョンを確認して、試してみたい機能がそのバージョンで提供されていなければ、次の手順に沿ってバージョンアップを行う。

###3. redashのdocker-imageの差し替え
ひとつまえの手順でdocker-compose.ymlを確認していることからもわかるように、EC2インスタンス内ではdockerコンテナが複数立ち上がりredashとしての機能を提供している。

場合によっては、docker-compose.ymlで参照しているredashのdocker-imageを変更して、docker-composeを立ち上げ直せばバージョンアップできるのだが、大事をとって公式のガイドに従ってバージョンアップを行う。

https://redash.io/help/open-source/admin-guide/how-to-upgrade

```:バージョンアップ手順
# 念の為、バックアップをとってから作業すること

# sudo su
# cd /opt/redash

# viなどで希望するバージョンのdocker-imageに書き換えて保存
# vi /opt/redash/docker-compose.yml

# 一部のコンテナを止めて再度立ち上げ直す
# docker-compose stop server scheduler scheduled_worker adhoc_worker
# docker-compose up -d
```

これでバージョンアップは完了しているはずなので、redashのwebページをからバージョンアップできていることを確認する。
引数、関数、戻り値について

#引数
プログラムや関数に渡す値

#関数
何かを入れると何かを計算して何かを返してくれるプログラムの部品
入力を受けて処理を行い出力する

#戻り値
関数によって出力された値


#実例
日本語から英語に翻訳する関数

　　　引数　　　　　　　関数　
　　　りんごーーー→　翻訳機
　　　apple←ーーーー
　　　戻り値
SQL Server: DMVを利用した各種リソースボトルネックなクエリの抽出精度を向上させた話

#背景
以前[こちら](https://qiita.com/maaaaaaaa/items/a70cfdc1ef85363f2026)の記事で、sys.dm_exec_query_statsを使用して、サーバー全体の中でCPUボトルネックになっているクエリを抽出する方法を紹介しました。

昨今のSQL ServerおよびSQL DatabaseなどのPaaSでは、[クエリストア](https://docs.microsoft.com/ja-jp/sql/relational-databases/performance/monitoring-performance-by-using-the-query-store?view=sql-server-ver15)が利用できますので、こちらが利用できる環境であれば、こちらを利用するのが手っ取り早く高精度な情報を得ることができると思います。

しかし、以下の状況下においては、現在でもsys.dm_exec_query_statsを利用した方法が有用であると考えます。

- SQL Server 2014など、古いバージョンを使っておりクエリストアが使えないとき
- クエリストアを使用しているが、クエリストアに関する情報の保存サイズをおさえるため等の理由で、レンジを1時間や30分などに設定している常用下で、特定の5分や10分間の間のリソースボトルネックとなっていたクエリを後追いしたいとき

※リソースボトルネック＝CPU、論理IO、ワークスペースメモリを指しています。

#いままで使用していた方法
[こちら](https://qiita.com/maaaaaaaa/items/a70cfdc1ef85363f2026)の記事から抜粋した、以下のアイデアでボトルネックを調査していました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148310/8d79e40d-da78-574a-f5db-2f6a38e08003.png)

要は、sys.dm_exec_requestsのスナップショットを2点とって、その2点の情報を使っていかに高精度な計算を行うか、というものでした。
この方法でもある程度正確にボトルネッククエリをリストアップすることができますが、以下のようなケースのうち、クエリAとクエリBしか考慮できていませんでした。

![画像1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148310/08b226ab-6315-57bc-7947-759ae37f3358.jpeg)

Snapshot①と②の間隔が数分など短い場合や、DBサーバーのメモリに余裕がありキャッシュアウトがほとんど起きないようなケースであればこれでも問題ないのですが、1時間や1日単位でボトルネック調査をしたい場合などはSnapshot間隔の間でキャッシュとキャッシュアウトが起こったり、Snapshot②を取得する前にキャッシュアウトされることも十分考えられます。

このような状況下であってもより高精度にボトルネッククエリを抽出する方法を考えました。
前提として、[こちら](https://qiita.com/maaaaaaaa/items/64a2071fcc0555c76ade)の仕組みを使って1分間に1回、DMVの情報をテーブルに保存しているとします。

#方法
2点の情報を使うのではなく、抽出期間に存在する全てのSnapshotを利用します。
例えば、特定の1時間のCPUボトルネックを調査したい場合、Snapshot①とSnapshot②の間には約60個のSnapshotが存在します。

![画像2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148310/743153b4-b7ad-8b15-ee4f-84ffe521712b.jpeg)

これらの情報も使うことで、今までの方法であれば見落としていたクエリCやクエリDも抽出することができるようになります。

#クエリ
ストアド単位の情報の解析は[こちら](https://github.com/masaki-hirose/SQLServer-Info/blob/master/sqlserver_logging/dm_exec_procedure_stats%EF%BC%88%E3%82%B9%E3%83%88%E3%82%A2%E3%83%89%E3%83%97%E3%83%AD%E3%82%B7%E3%83%BC%E3%82%B8%E3%83%A3%E3%81%AE%E5%AE%9F%E8%A1%8C%E7%B5%B1%E8%A8%88%EF%BC%89/dm_exec_procedure_stats_dump_analysis.sql)
ステートメント単位の情報の解析は[こちら](https://github.com/masaki-hirose/SQLServer-Info/blob/master/sqlserver_logging/dm_exec_query_stats%EF%BC%88%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5%E3%81%95%E3%82%8C%E3%81%9F%E3%83%91%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%B3%E3%82%B9%E6%83%85%E5%A0%B1%EF%BC%89/dm_exec_query_stats_dump_analysis.sql)
にそれぞれまとめておきました。

#まとめ
DMVを使用したリソースボトルネックの抽出精度を向上させるために考えたことと、実装したクエリをご紹介しました。
実際、今までの調査クエリだと見落としていたクエリが、新方式だとボトルネックとしてあがってくるようになり、精度の向上を実感しています。
もしよければご利用ください。
Selenium IDE で存在したらクリックする(click if exists の疑似実装)

`store xpath count` して、`if`して、`click`してって面倒ですよね。
発想を変えて「存在しないならbodyをクリックする」ことにします。

Targetを下記のように指定することで、OKボタンが存在するならOKボタン、なければbodyを対象にとれます。
last()指定してるのは、深いnodeが後にくるため。

```
xpath=(//button[contains(.,'OK')]|//body)[last()]
```
Powerdotでのアニメーション（オーバーレイ）

自分用のメモです。

# 1. 連続して現れる: \pause
最初はabcのみ表示、次にdefが表示される。

```latex:
abc
\pause
def
```

# 2. 現れる順番などを指定: \onslide
sample1: 最初はpowerが現れ、次はdotが現れる。powerの文字は消え、そこは空きスペース。

```latex:
\onslide{1}{power}\onslide{2}{dot}
```

sample2: 最初はpowerのみが現れ、次はpowerdotが現れる。

```latex:
\onslide{1,2}{power}\onslide{2}{dot}
```

# 3. 色で強調： \onslide+
最初はpowerが強調、次はdotが強調される。

```latex:
\onslide+{1}{power}\onslide+{2}{dot}
```

# 4. スペースを空けずに現れる: \onslide*
sample1: 最初はpowerが現れ、次はpowerのあった位置にdotが現れる。

```latex:
\onslide*{1}{power}\onslide*{2}{dot}
```
【javascript】テンプレートリテラルとアロー関数を用いた、シンプルな引数有りメッセージ呼出ファンクションの実装検討

# 背景

Nuxt.js(node.js)にて開発する時、まずメッセージの体系化を行いたい。引数にも対応可能なのが望ましい。

* 引数含むメッセージファンクション
* 呼び出し側

上記２要素で完結しつつ、１メッセージに付き１行～２行ぐらいでシンプルにならないかと考えた。

# 成果
一応できた。

## メッセージ側

```js
// アロー関数を用いて記述、実行。
var messages = {
    example1: (...args:string[]) => escape(`const${args[0]}${args[1]}${args[2]}`) ,
    example2: (...args:string[]) => escape(`テ${args[0]}ス${args[1]}ト`) 
}

// XSS対策のエスケープ
function escape(str:string){
    str = str.replace(/&/g, '&amp;');
    str = str.replace(/</g, '&lt;');
    str = str.replace(/>/g, '&gt;');
    str = str.replace(/"/g, '&quot;');
    str = str.replace(/'/g, '&#39;');
    return str
}

```

使っているのはテンプレートリテラルとアロー関数。いずれもIE非対応であることは留意。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Template_literals
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions

## 呼び出し側の自動テストメソッド（Jest）

```js
  import { messages}  from '@/logic/common'

// 下記はいずれも成功。
// messages.example2などで入力補完として出てくるためソースを追ったり探したりするのが容易い
describe('callMessage', () => {
  test('messages', () => {
    expect(messages.example1( '0','3','2')).toEqual('const032')
  })
  test('escape messages', () => {
    expect(messages.example2( '&','2','1')).toEqual('テ&amp;ス2ト')
  })
})
```

メッセージを編集しやすく、複数引数にも対応でき、コーディング視点からも楽。やりたかったことはできていそうと考える。
テンプレートリテラルなので、改行も容易い。
Active Record　入門　（記録）

##関連するデータを抽出

```ruby
comments = Comment.includes(:user).all
comments.each do |c|
  puts "#{c.body} by #{c.user.name}"
end
```
comments = Comment.all とした時に comments = Comment.includes(:user).all としてあげると、user 情報も一緒に引っ張ってきてくれる

※尚、以下のアソシエーションの設定が必要。

```ruby
class User < ActiveRecord::Base
  has_many :comments
end

class Comment < ActiveRecord::Base
  belongs_to :user
end
```

##Activerecordにおけるincludesとjoinsの違い
・includesは先読みしてキャッシュしておく。
・joinsはただINNER JOINしてくれる。単に結果をフィルタリングしたいだけであれば、まさに joins を利用するのに適したケースです。

https://qiita.com/k0kubun/items/80c5a5494f53bb88dc58

##関連するデータを削除
モデルに以下を追記する

```
dependenrt: :destroy
```

記入例

```ruby
class User < ActiveRecord::Base
  has_many :comments, dependent: :destroy
end
```
コメントテーブルがユーザーテーブルに依存させることで、ユーザーの削除によりコメントは削除される。
順序回路の作法 その6

# 概要

順序回路を理解する。
JKフリップフロップのタイミングチャートを書いてみた。

# 写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/2b78671c-547e-bc24-365b-2839c1607df8.jpeg)


# 成果物

https://embed.plnkr.co/plunk/4PF3BJBkMZPLf1pl

以上。
順序回路の作法 その5

# 概要

順序回路を理解する。
JKフリップフロップの回路図を書いてみた。

# 写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/f7b7fa8f-6cb5-82c6-6764-6b11baa0d45b.jpeg)


# 成果物

https://embed.plnkr.co/plunk/2tUv1Cnw6WQphZJ2

以上。
順序回路の作法 その4

# 概要

順序回路を理解する。
フリップフロップの回路図を書いてみた。

# 写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/647ba9a9-0a7f-40dc-2aa7-6dc354468df4.jpeg)


# 成果物

https://embed.plnkr.co/plunk/Pm1JDe1tCPuGJ8pi

以上。
【Python】空間情報分析に便利なオープンソース「H3」のドキュメント日本語メモ

<p align="center">
  <img width="520" alt="スクリーンショット 2020-01-02 0.21.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/58274a4e-ef33-339e-2224-88b3453d4915.png">
</p>
画像は[Uberのエンジニアリングブログ](https://eng.uber.com/visualizing-city-cores-with-h3/)より

---

#はじめに
<img width="720" alt="スクリーンショット 2020-01-02 0.21.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/afd7c526-5998-a40a-aa8e-f108155bd595.png">
オープンソースの「H3」を触っています。
関数についてのドキュメントは豊富ですが、実行例が無いこと、オールイングリッシュであることが相まって、少しわかりづらい側面があります。
[公式ドキュメント](https://qiita.com/gshirato/items/d8cc928c4131f3292b14)を捕捉する形で関数の一部をメモします。
注：網羅性は一切ありません。また、pythonで触っています。



#H3とは
https://h3geo.org/
[こちら](https://qiita.com/gshirato/items/d8cc928c4131f3292b14)の日本語記事にもあるため、詳細はそちらをご参照いただければと思いますが、

「H3」は、Uberによってオープンソースで開発されている、六角形をグリットとした、新しい座標系です。
<img width="360" alt="スクリーンショット 2020-01-02 0.21.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/348026/60a8584d-5571-ea1b-ba0e-d89834de333c.png">
画像は[公式ドキュメント](https://h3geo.org/docs/core-library/coordsystems/)より

Uberこと[Uber Technologies](https://www.uber.com/jp/ja/about/)は、いわゆる白タクサービス、フードデリバリーサービスなどで有名ですが、
配車ごとの目的地や顧客現在地、車両現在地など、膨大な空間情報を扱い、

1)即時で最適なマッチングを実現
2)蓄積されたデータを機械学習を用いて分析・可視化

するためには、市区町村のような区分や正方形で区切られたグリッドはやや扱いづらいです。
(捕捉：正方形でもいいのですが、より円に近い六角形の方が最適な距離を求めるためには扱いやすいということです。詳しくは公式ドキュメント参照のこと)

そこで、彼らは新しい座標系を生み出し、[2018年にオープンソース化](https://eng.uber.com/h3/)しています
( ちなみに同社は[deck.gl](https://deck.gl/)他、空間の分析や可視化に役立つツールを多くオープンソース化しているようです)

#関数とユースケースのメモ

以下、hexは'882f5a305dfffff'のような見た目の、H3Index型です。(ちなみにhexagon、六角形という意味の単語の略。)
##Indexing
##Inspection
##[Traversal](https://h3geo.org/docs/api/traversal)
Traverse とは、「横切る」という意味の単語です。
ここでは、六角形のグリッドを横断し、近接グリッドのインデックスや、グリッド同士の距離・経路を求める関数が紹介されます。

###kRing
###maxKringSize
###kRingDistances
###hexRange
###hexRangeDistances
原点のhexからk個分の距離に入っているグリッドのH3Indexを、距離ごとにまとめて返します

```py
h3.hex_range_distances(h, k)
```
例↓

```py
h3.hex_range_distances(h, 2)
```
出力↓

```
[{h自身},{隣接しているグリッド6つ分のH3Index},{2グリッド離れている12個のH3Index}]
```

###hexRanges
###hexRing
###h3Line
###h3LineSize
###h3Distance
###experimentalH3ToLocalIj
###experimentalLocalIjToH3

##Hierarchy
##Regions
##Unidirectional edges
##Miscellaneous

##参考
上でリンク張って紹介したサイトたち
https://eng.uber.com/visualizing-city-cores-with-h3/
https://qiita.com/gshirato/items/d8cc928c4131f3292b14