OmniAICreator/Qiita-1.07M huggingface dataset:
Minix は Linux より速かった（？）

# 計測したプログラム
[Minix 3 SMP](https://qiita.com/kakinaguru_zo/items/c72dd916c6fd4b5b2cba) が何かもっさりしている感があり，Minix 2にはperlがなくて標準的な[Byte UnixBench](https://github.com/kdlucas/byte-unixbench)がそのままでは動かないので，取り敢えず以下のような`fork()`, `wait()`をひたすら繰り返すプログラムをコンパイルして，`/usr/bin/time -p` で時間を測ってみた。

```
/*
clang -Wall -static -O3 -ffunction-sections -fdata-sections -Wl,--gc-sections forktest.c
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>

int main(void) {
  int counter=200000, exitcode;
  pid_t r;
  errno=0;
  while (counter>0) {
    r=fork();
    if (r<0) { perror("fork():"); errno=0; }
    if (r > 0) {/* parent */
      if (wait(&exitcode)<0) { perror("wait():"); errno=0; }
      else --counter; 
      /*fprintf(stderr, "%d\n", counter);*/
    }
    if (r==0) return 0;  /* child */
  }
  return 0;
}
```

Minix を実機で動かすのは面倒なので，QEMU 6.2で`qemu-system-i386 -machine pc -cpu pentium3-v1 -accel kvm -smp sockets=4 -m 1920M -net user -net nic,model=e1000 -drive discard=unmap,detect-zeroes=unmap,if=ide,file=ディスクイメージ.qcow2 -serial vc -serial vc -serial vc -serial vc -boot c` ですべてのOSを起動した。

# 計測結果
## Debian 11 i386 (`linux-image-686-pae`カーネル`)
![スクリーンショット_2022-03-27_05-04-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259309/675d4f86-5891-e163-8eb6-eec154239e86.png)

## Minix 2.0.4 from http://minix1.woodhull.com/pub/demos-2.0/VMWarePlayer/
CCに`-O2`を付けてコンパイルし直した。かなり速い…😱
![スクリーンショット_2022-03-27_05-54-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259309/0269ab78-1763-2cb7-0a6b-648883208a66.png)

## Minix 3.4RC6 from http://download.minix3.org/iso/snapshot/
![スクリーンショット_2022-03-27_09-41-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259309/884fae5f-4c4d-8753-26d9-200ddcc2d35a.png)

## Minix current with SMP fix from https://github.com/Stichting-MINIX-Research-Foundation/minix/pull/292
めっちゃ遅いやんけ…😭SMPはいい加減に作ると遅くなるという教訓か…
![スクリーンショット_2022-03-27_09-44-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259309/897a65f0-93a8-fefe-bbbc-1812763dbf86.png)

# 比較に用いたQEMUディスクイメージ
http://p1437140-ipoe.ipoe.ocn.ne.jp:63873/minixsmp/ にある。Minix3用ディスクイメージはカーネルコマンドラインに `virtio_blk=yes`がついているが，IDEドライブから起動する場合にはそれを取らないと起動しないので注意。

# さらなる比較
もっと幅広い比較をした人がおられたらコメント欄で教えて下さい
git describe


`git describe --always` get recent commit id

```shell
git describe -h

usage: git describe [<options>] [<commit-ish>...]
   or: git describe [<options>] --dirty

    --always              show abbreviated commit object as fallback
    --contains            find the tag that comes after the commit
    --debug               debug search strategy on stderr
    --all                 use any ref
    --tags                use any tag, even unannotated
    --long                always use long format
    --first-parent        only follow first parent
    --abbrev[=<n>]        use <n> digits to display object names
    --exact-match         only output exact matches
    --candidates <n>      consider <n> most recent tags (default: 10)
    --match <pattern>     only consider tags matching <pattern>
    --exclude <pattern>   do not consider tags matching <pattern>
    --dirty[=<mark>]      append <mark> on dirty working tree (default: "-dirty")
    --broken[=<mark>]     append <mark> on broken working tree (default: "-broken")
```
JetPackComposeをマルチモジュールで使ったときのNoSuchMethodError


マルチモジュールでJetpackComposeを使おうとして以下遭遇。

Android: java.lang.NoSuchMethodError

composeを使うモジュールのbuild.gradleに以下が必要でした。
```build.gradle
android {
・・・
    buildFeatures {
        compose = true
    }
    composeOptions {
        kotlinCompilerExtensionVersion = "X.X.X"
    }
}
```

モジュール作成時のデフォルトだと設定されないのに気づかず地味にはまったので備忘
git log 変更履歴を確認する

git log 変更履歴を順に辿れる
いつどこでどんなどんなコミットがあったのか履歴を辿れる
```
git_tutorial % git log
commit 53dd892bc4f850fd4307916af0a424b9f50d2512 (HEAD -> master)
Author: 
Date:   Sun Mar 27 10:00:22 2022 +0900

    diff

commit 009c55f78ab6b364d2ee9b3a1452f94e8338fe41
Author: 
Date:   Sun Mar 27 09:50:35 2022 +0900

    thirdcommit

commit 3667a5a17da7201ff1a52bf8d1473441e665c19a
Author: 
Date:   Sun Mar 27 09:28:13 2022 +0900

    a

commit 9bbe2aa2ffeb3cdf0bd763be50dbf8800716e69b
Author: 
Date:   Sun Mar 27 09:24:45 2022 +0900

    aa
:

```
git diff変更差分を確認する

ワークツリーとステージの間の変更差分を確認するのが
git diff <ファイル名>　コマンド

git addした後の変更分を確認するのがステージとリポジトリの差分を確認したいとき。
git diff --staged

```
git_tutorial % git diff
diff --git a/index.html b/index.html
index 470f438..6a9d330 100644
--- a/index.html
+++ b/index.html
@@ -1,3 +1,4 @@
 initial commit
 second commit
-third commit
\ No newline at end of file
+third commit
+git diff
\ No newline at end of file
git_tutorial % git add index.html
git_tutorial % git diff(ステージに移動したから何も表示されなくなる)
git_tutorial % git diff --staged（リポジトリに移動していないから変更差分が出てくる）
diff --git a/index.html b/index.html
index 470f438..6a9d330 100644
--- a/index.html
+++ b/index.html
@@ -1,3 +1,4 @@
 initial commit
 second commit
-third commit
\ No newline at end of file
+third commit
+git diff
\ No newline at end of file
git_tutorial % git commit -m diff
[master 53dd892] diff
 1 file changed, 2 insertions(+), 1 deletion(-)
git_tutorial % git diff --staged（コミットでステージに追加されたから何も出てこなくなった） 
```
Kotlinでrest-assuredを使う

REST APIのテストコードを効率良く記述するためのライブラリである[rest-assured](https://rest-assured.io/)をKotlinから利用してみた。

### ライブラリを依存関係に設定する

[Kotlin用のExtensionライブラリ](https://kotlinlang.org/docs/extensions.html#extension-functions)が提供されているため、これを依存関係に設定するだけでrest-assured本体は推移的に解決される。

build.gradle.kts

```kotlin
dependencies {
    testImplementation("io.rest-assured:kotlin-extensions:4.5.1")
}
```

### テストコードを実装する

先述のExtensionライブラリは、trainling lambdaやinfix notation、scope functionを活用してすっきりとした記述を可能にしている。条件・アサーション等をブロックで区切ることができ、各ブロック内のメソッド呼び出しをメソッドチェーンとして繋いで記述する必要がない。

```kotlin
val id: String = Given {
    baseUri("https://...")
    body(mapOf("key1" to "value1", "key2" to "value2"))
} When {
    post("/api")
} Then {
    statusCode(HttpStatus.SC_OK)
    body("key1", equalTo("value1"))
} Extract {
    path("id")
}
```

#### 補足

上記のコード中に登場するメソッドについて、`Given`は`public fun Given(block: ...): ...`というシグネチャとなっており、上記ではblockをtrailing lambdaとして記述している。また`When`, `Then`, `Extract`にはinfix修飾子が設定されているため、前のメソッドにドットなしで繋げて記述ができる。各ブロックはscope function (apply) に渡されるようになっているため、メソッドチェーンでの記述が不要となっている。

### その他

テストコードを動かしながら実装するときに、Kotlinのビルドに少し時間がかかるのは辛いところ。

テストプロジェクトの例として[example-test-restassured](https://github.com/unhurried/example-test-restassured)リポジトリを作っている。
Gitまとめ

///
Gitはスナップショットを記録する。
Gitはデータをバージョンとしてそのまま保存する。（差分ではなく、そのまま保存する）
Gitは以前の状態に戻せる。（コミットを辿ることで以前のコミットに戻せる）
///

///
ワークツリー（自分の作業場）　①⇨ ローカルリポジトリ（自分のパソコンの履歴データ）　⇨　リモートリポジトリ（Github）

①まずはローカルに差分ではなく、全体のスナップショットとして記録する。

他人のデータを取得する
リモートリポジトリ（Github）⇨　ローカルリポジトリ　⇨ ワークツリー


ローカルは3つのエリアからできている
ワークツリー　git add⇨ ①ステージ（スナップショットをコミットする変更を準備）git commit⇨ ローカルリポジトリ（スナップショットを記録する）

①ステージはなぜあるのか
変更したファイルだけをステージに追加したいから。
いらないファイルと分けたい

///

///
🔥ワークツリー index.html //git add//⇨ 🔥リポジトリ index.htmlのファイル内容を圧縮する//git add//　⇨ 🔥ステージ　index.html 圧縮ファイルA //git commit// ⇨　🔥リポジトリ　ツリー1 圧縮ファイル　コミット１（ツリー１、作成者、日付、コミットメッセージ）
///

Gitの本質はデータを圧縮してスナップショットとして保存すること
コミットを辿ることで以前のファイルをgetすることができる。

//ローカルリポジトリを作成する
git init
このコマンドで.gitデいレクトリを作成する
.gitの中にgitで必要なものは一式揃っている
```
% mkdir git_tutorial(ファイル作成)
% cd git_tutorial 
git_tutorial % git init
Initialized empty Git repository in /
git_tutorial % ls -a
.	..	.git
git_tutorial % ls .git/
HEAD		description	info		refs
config		hooks		objects
```

///
git clone
gitリポジトリのファイルをgetする。
下のコマンドがgit cloneの一連の流れ
```
 % git clone https://github.com/microsoft/vscode.git
Cloning into 'vscode'...
remote: Enumerating objects: 1246200, done.
remote: Total 1246200 (delta 0), reused 0 (delta 0), pack-reused 1246200
Receiving objects: 100% (1246200/1246200), 463.28 MiB | 6.77 MiB/s, done.
Resolving deltas: 100% (892372/892372), done.
 git_tutorial % ls -a
.	..	.git	vscode
 git_tutorial % cd vscode
 vscode % ls -a
.			.mailmap		extensions
..			.mention-bot		gulpfile.js
.devcontainer		.vscode			package.json
.editorconfig		.yarnrc			product.json
.eslintignore		CONTRIBUTING.md		remote
.eslintrc.json		LICENSE.txt		resources
.git			README.md		scripts
.git-blame-ignore	SECURITY.md		src
.gitattributes		ThirdPartyNotices.txt	test
.github			build			tsfmt.json
.gitignore		cglicenses.json		yarn.lock
.lsifrc.json		cgmanifest.json
```
///

///

変更を記録すること commit(ステージからリポジトリに保存すること)
ツリーファイルとコミットファイルが作製される。
・ツリーファイル　バージョンの履歴を辿れる
・コミットファイル　コミットした内容を見れる
git commit -m　メッセージをつける
git statusで状況を確認することもおすすめ

```
git_tutorial % git status        
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   index.html
git_tutorial % git commit -m thirdcommit 
[master 009c55f] thirdcommit
 1 file changed, 2 insertions(+), 1 deletion(-)
git_tutorial % git status
On branch master
nothing to commit, working tree clean
```

///
Visual Studio2022でArduino開発

ステップ実行できると聞いて環境構築

VisualStudio2022を立ち上げ、上メニューの拡張機能の管理からインストール
![スクリーンショット 2022-03-27 094856.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157360/9b49c2bd-1612-161d-285b-2ceab113e79c.png)

初回実行時、VSにC++プロジェクトの作成をインストールしてないとそもそも開けれないのでインストールされる。

一度VSを再起動。

ArduinoIDEの設定などを使いまわす？感じなのでそちらの設定も
![スクリーンショット 2022-03-27 094922.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157360/6b5f7438-e3a5-372a-38c5-2ccffd27eda1.png)

ボードマネージャやライブラリをArduinoIDE側で設定してあげる。
Firestore の Security Rules の変更方法

## Security Rules の確認方法 ##

![rules01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/6100ba1d-c5a5-bfe8-0a06-938d4c29ac72.png)

## 変更方法 ##

Firebase コンソールに行く

https://console.firebase.google.com/

プロジェクトを選択

Firestore Database -> ルール
![rules0105.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/7782f522-08d0-3cf6-7c10-bcea6ac4d1e1.png)


![rules02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/8ac0af4a-2099-468d-9e7b-7c8209b2da3f.png)
BQでテーブル縦持ち化の時のResources exceeded対策として少し使える方法

# 概要
業務アプリのテーブルは結構横持ちで設計されていることがそれなりに多く、集計やデータ分析を一般化・効率化するために縦持ちに構造変換することが多いと思います。
そんな時に昔から利用されるのはunion all構文かなと思いますが、**BigQueryの配列を利用する** ことでunion all構文を排除でき、当該エラーを防げる場合があります。実際に何度か困難を乗り越えられました！
・・という小技のご紹介です。

↓あの恐ろしいアイツ :anguished:
SQLで大量のJOINやwithによる内部VIEWなどを作ると一定量を超えた時に発生します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196303/388a2dfb-0053-c4aa-3925-3f6fa5c9cc0c.png)

# トラディショナルなunion allを用いた縦持ち化
```sql
with
target as (
  select 1 as col1, 2 as col2, 3 as col3, 4 as col4, 5 as col5
)
select col1 as col from target
union all 
select col2 as col from target
union all 
select col3 as col from target
union all 
select col4 as col from target
union all 
select col5 as col from target
;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196303/ebefcf0e-770a-c649-3b6c-490f8c6ff112.png)

# BQの配列を使った縦持ち化
```sql
with
target as (
  select 1 as col1, 2 as col2, 3 as col3, 4 as col4, 5 as col5
)
select
  unpivoted
from
  target,
  unnest([col1, col2, col3, col4, col5]) as unpivoted
;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196303/03f63da1-211f-2ecb-68cb-8cc0817fced0.png)

# 検証
以下検証コードに記載したSQLで検証してみました。
UNION ALLだと707列の縦持ち化でResources exceeded発生しましたが、
BQ配列を用いた場合は5000列でも何ともなしでした。

検証コード：
https://github.com/mynavi-yterui/bq-array-verticalize/blob/main/BQ%E9%85%8D%E5%88%97%E3%81%A7%E7%B8%A6%E6%8C%81%E3%81%A1%E5%8C%96%E6%A4%9C%E8%A8%BC.md

# ちょっとした考察
## union allの場合
union all自体は割と単純な集合演算であるのは間違いないとは思います。
されど集合演算、ということでやはりそれなりに負荷は大きいのではと。
一つのテーブルでデータ件数が膨大にあるケースへの耐性はかなり強いのですが、集合(テーブル)の種類が増えるケースに弱いので、union allのアプローチではこの集合の種類が増えるケースと同じになってしまうので、負荷が大きくなる。

## BQ配列の場合
一方、配列にした場合はスキャン対象の集合自体は1つになるので、件数だけが膨大なパターンに持っていけることになるのかなと思いました。
実行計画をみてみても、そんな雰囲気に見えますが、あまりBQの実行計画に詳しくないので説明は割愛します。(逃げます！)

# 他の方法(unpivot)
BigQueryでもunpivot構文が使えるようになりましたので、unpivotでやるという手もあるかと思います。
しかしながら恐らく、BQのリソースに優しい方法としては配列を利用する方法なんではないかと思われます。
(∵BQの配列はオーバーヘッドが非常に低いことが多いという経験則を一応の根拠としての推測)
※厳密な比較検証は行っていません。あくまで推測です。→間違っていたら詳しい方教えて下さい。

# おわりに
というわけで、BQ配列を使ったエラー回避のご紹介でした。
今回の例では横持ち→縦持ち変換だけ行っており単純すぎるので、イマイチ人によってはピンとこないかもしれません。
しかし実際の業務では、JOINやWithの内部Viewなど多くの集合演算が1つのSQLで書かれたりするケースがかなり多く割と簡単にResources exceededが発生します。そんな時に縦持ち化のコードを全て配列を利用する方法にしておくことで必要以上なSQL複雑性を回避できます。
知っておいて損はないアイディアかなと個人的には思っています。(もっと素晴らしいアイディアがあったらお教えください！)

おしまい
qiitaさんのマイページをお気に入りに登録する小技page=1

これだけです。ページジャンプのためページ数つけて表示します。変更します

```
https://qiita.com/mrrclb48z
```

のところ、

```
https://qiita.com/mrrclb48z#page=1
```

https://qiita.com/mrrclb48z#page=1

page=2を見て、2を1にしてお気に入り登録です。

qiitaさんで、設定してもらうと助かります。
chart.jsを使用してグラフを作成するにあたりハマった話

    "bootstrap": "^4.6.0",
    "bootstrap-vue": "^2.21.2",
    "chart.js": "2.8",
    "core-js": "^3.15.1",
    "nuxt": "^2.15.7",
    "vue-chartjs": "^3.4.2"


nuxt@2で``円グラフ``、を表示させようとして
表示されずハマった話です。

``npm``でインストールしたコマンド
``npm install chart.js vue-chartjs --save``
chart@3が最新バージョンで相性が悪くだめだったため
アンスト
```npm rm chart.js vue-chartjs```
適応されるダウンバージョンをインストール
```npm install chart.js@2.8 vue-chartjs@3.4.2 --save```


＞＞　救いの神
https://qiita.com/pazuzu/items/336fc1b45f7d22ac93e3
初心者でも理解できる！コンパイルとはなんぞや

コンパイルです。
個人的に面白い仕組みだよなと思っています。
コンパイルに限らず、ITの根幹を作った先人たちにはマヂ尊敬←
ではどうぞ。

# コンパイルとは
簡単にいうと、「人間が書いたソースコードを機械語(バイナリコード)に翻訳する作業」を指します。
コンピュータには人間が書いたものは分かりません。
一方、対するコンピュータの言葉は人間には理解しづらいですよね。
それを中間言語というもので翻訳(通訳)して実行ファイルにしてくれるのがコンパイルです。

人間の世界で例えましょう。
我々日本人は日本語を喋ります。
しかし、海外の方々は英語やフランス語、ドイツ語などを喋ります。
猫にも猫語があるかもしれません。
ドラ○もんは翻訳コンニャクを出します。
日本人である我々は彼らの言っていることがわかります。
これです。
まぁ、翻訳コンニャクを出さずとも、通訳さんがいらっしゃればそれで済みます。
その翻訳コンニャク（通訳さん）はプログラミングでいうコンパイラというものです。
構図としてはこんな感じです。↓

ソースコード↔︎コンパイラ↔︎機械語(バイナリコード)

これが成り立つことによってソースコードがコンパイルされ、実行ファイルが出来上がります。
コンパイラという言葉が出てきましたが、先述の通り、翻訳コンニャク（通訳さん）です。

まじでコンパイラ様様です。
これがないとアプリだってアプリになってないのですから…

# コンパイルの方法
ここではC#のコンパイルの方法をご紹介します。
Visual Studioでビルドしてください。
以上です。
本当にこれだけでコンパイルできます。

エラーが起きてコンパイルできないという場合は、基本的にソースコードの見直しが必要です。
ソースコードにシンタックス(構文、文法)エラーがないかなどの確認ですね。
大体はソースコードのエラーです。
エラー内容はエラー発生時に出力されているはずなので確認してみてください。
定期的にビルドすることで、プログラムの保存やソースコードの確認、実行ファイルの生成にもなるので、オヌヌメです。

# 終わり
終わり！
【プリンシプルオブプログラミング】 第3章（3.37~3.54）「思想」要点抜粋

この記事は「プリンシプルオブプログラミング」という書籍の、特に重要だと感じた部分を紹介します。この書籍は全部で7章あります。1記事につき1章（項目が多い章は分割）を取り上げていき、今回は第3章（UNIX思想）の部分です。
### 第3章 「思想」 〜プログラミングのイデオロギー〜
# 3.37 UNIX思想
- モジュール化の原則（3.38）
- 明確性の原則（3.39）
- 組み立て部品の原則（3.40）
- 分離の原則（3.41）
- 単純性の原則（3.42）
- 倹約の原則（3.43）
- 透明性の原則（3.44）
- 安定性の原則（3.45）
- 表現性の原則（3.46）
- 驚き最小の原則（3.47）
- 沈黙の原則（3.48）
- 修復の原則（3.49）
- 経済性の原則（3.50）
- 生成の原則（3.51）
- 最適化の原則（3.52）
- 多様性の原則（3.53）
- 拡張性の原則（3.54）
# 3.38 モジュール化の原則
- 関係性が高い要素を集め、シンプルなモジュールを作成する
- 他のモジュールとの関係もシンプルにする -> 問題が局所化される
# 3.39 明確性の原則
- コードは「巧妙に」ではなく「明確に」なるようにする
- コードを2度読まなければ解読しない場合はわかりやすいコードに修正すべき
# 3.40 組み立て部品の原則
- ソフトウェアは、他のソフトウェアと組み合わせることができるように作る -> シンプルなフィルタとして作る
- フィルタ：入力としてデータストリームを受け付け、加工し、別のデータストリームとして出力するソフトウェア
- データストリームの形式はテキスト形式にするのがよい設計 
# 3.41 分離の原則
- メカニズムからポリシーを離す
# 3.42 単純性の原則
- コードをシンプルにする
# 3.43 倹約の原則
- コードの分量と複雑度を大きくしない -> コードが大きくなってきたら分割する
# 3.44 透明性の原則
- 「透明性」と「開示性」を意識して設計する -> デバッグに貢献する 
# 3.45 安定性の原則
- 通常の条件下だけでなく、予想外の条件下でも適切に動作させる
# 3.46 表現性の原則
- コードにおける情報の表現方法は、ロジックではなくデータに寄せて書く -> ロジック側が読みやすく安定したものになる
# 3.47 驚き最小の原則
- 予想通りのインターフェースにする -> ユーザーの思った通りの動作をさせる
###### 気をつける点
- よく似たソフトウェアのインターフェースをモデルにする
- 想定ユーザーの特徴を考慮する
- 伝統（お馴染みの習慣）に注意を払う
- 「一見似ているが微妙に異なる」ということを避ける
# 3.48 沈黙の原則
- 表示を厳選し、最小限に抑える
# 3.49 修復の原則
- エラー回復に失敗した場合、処理は継続すべきではない -> 激しくエラーを発生させ、ユーザーに気づいてもらう
# 3.50 経済性の原則
- プログラマの時間を大切にする
###### 時間を浪費させる問題
- ハードウェアが貧弱
- 使用するソフトウェアに対する制限がある
- 県境に関するルールや制限がある
# 3.51 生成の原則
- 手作業を避け、コードを生成するコード（コードジェネレーター）を書く（作る）
# 3.52 最適化の原則
- 速いコードより正しいコードを書く
# 3.53 多様性の原則
- 多様性を受容し、「よりよいやり方」を求め続ける -> 唯一の正しい仕様はない
# 3.54 拡張性の原則
- 拡張できる設計にする -> ソフトウェアは成長しなければならない
- ソフトウェアがプラガブル（接続可能）になるよう設計し、それを明示する
【Javascript】空オブジェクトの判定方法

# null じゃなくて空オブジェクトで返ってくる時がある

該当の値が存在しない場合 大体 null で返ってくるのですが、たまーに空Object で返ってくる時があります。

```javascript
{} // null ちゃうんかーい
```

# 空オブジェクトの判定ってどうやってやるんや

空配列の判定はよくやるのですが、そういえば空オブジェクトの判定ってしたことないと思い調べたところ諸説あったのですが、以下のやり方が一番多かったです。

```javascript
Object.keys(emptyObj).length === 0 // オブジェクトのキーが 0 かで判定
```

以下みたいに直接比較してあげてもいいのですが、、、

```javascript
const obj = {}

if (Object.keys(obj).length  === 0) {
 console.log('空っぽだよーん')
}
```

先輩から「ぱっと見で何を比較しているのはわかり辛い」とご指摘いただいたので、、

```javascript
 const obj = {}

 const isEmpty = (obj) => {
   return Object.keys(obj).length === 0
 }

 if (isEmpty(obj)) {
   console.log('空っぽだよーん')
 }
```

こんな感じで「空オブジェクトかどうか判定する関数」を作ってあげてもいいのかなと思いました。
おしまい。

# 参考

https://zenn.dev/hakshu/articles/check-js-object-is-empty
Visual studio codeのC++で、問題がないのに問題が出まくる問題の対処

# 問題
・競プロでVisual Studio Code & C++を使っている
・VScodeをアップデートすると、今まで大丈夫だったコードに問題が吐かれまくってうざい
![スクリーンショット 2022-03-27 8.07.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183061/86b3ac56-a7ff-560f-1314-a6834980c7ea.png)

# 対応方法
VScodeの設定画面を開き、検索からc++を入れ、以下の項目**Cpp Standard**を見つける
![スクリーンショット 2022-03-27 8.10.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183061/9aa16b04-162b-3093-9332-415d3be478c7.png)

これがデフォルトだと空欄になっているが、c++17を指定すると、問題が消えた。

# なぜ...? :thinking: 
Macのゴミコンパイラ (gccのふりをしたClangとか)の影響なんでしょうか...
有識者が居られたらご教示いただけると。
cscの作法 その65

# 概要
cscの作法、調べてみた。
データグリッドビューやってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1ce7017a-d9b9-0f34-838e-31f8ede12f66.png)

# コンパイル手順

```
>csc dgv.cs /platform:x86

```

# サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Data.OleDb;
using System.Data;

class form1: Form {
	form1() {
		Text = "DataGridView";
		ClientSize = new Size(400, 300);
		DataGridView gd0 = new DataGridView();
		gd0.Location = new Point(50, 20);
		Controls.AddRange(new Control[] {
			gd0
		});
		OleDbConnection con = new OleDbConnection();
		con.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=mydb.mdb;";
		con.Open();
		OleDbDataAdapter oda = new OleDbDataAdapter("SELECT * FROM blog_data;", con);
		DataTable dt = new DataTable();
		oda.Fill(dt);
		gd0.DataSource = dt;
		con.Close();
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}

```


以上。
cscの作法 その64

# 概要
cscの作法、調べてみた。
円グラフやってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/8436cc17-ad00-f8a7-c377-e7bbe8466c10.png)


# コンパイル手順

```
>set PATH=C:\Windows\Microsoft.NET\Framework\v4.0.30319;%PATH%

>csc ch1.cs /r:System.Windows.Forms.DataVisualization.dll

```

# サンプルコード

```
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace WindowsFormsApplication1
{
	public partial class Form1 : Form {
		public Form1() {
			var chart1 = new Chart {
				Dock = DockStyle.Fill,
			};
			this.Controls.Add(chart1);
			Series mySeries = new Series("series");
			double[] data = new double[] { 65.62, 75.54, 60.45, 55.73, 70.42 };
			string[] country = new string[] { "France", "Canada", "UK", "USA", "Italy" };
			mySeries.Points.DataBindXY(country, data);
			mySeries.ChartType = SeriesChartType.Pie;
			mySeries["PieLabelStyle"] = "Inside";
			mySeries["PieDrawingStyle"] = "Default";
			ChartArea myArea = new ChartArea("area");
			chart1.ChartAreas.Add("area");
			chart1.Series.Add(mySeries);
			mySeries.ChartArea = "area";
			chart1.Legends.Add(new Legend("Default"));
			LegendCellColumn firstColumn = new LegendCellColumn();
			firstColumn.ColumnType = LegendCellColumnType.SeriesSymbol;
			firstColumn.HeaderText = "";
			chart1.Legends["Default"].CellColumns.Add(firstColumn);
			LegendCellColumn percentColumn = new LegendCellColumn();
			percentColumn.Text = "#PERCENT";
			percentColumn.HeaderText = "Percentage";
			percentColumn.Name = "nameColumn";
			chart1.Legends["Default"].CellColumns.Add(percentColumn);
			chart1.Legends["Default"].LegendStyle = LegendStyle.Table;
			chart1.Legends["Default"].TableStyle = LegendTableStyle.Tall;
			chart1.Legends["Default"].DockedToChartArea = "area";
			chart1.Legends["Default"].IsDockedInsideChartArea = false;
			chart1.Legends["Default"].Docking = Docking.Bottom;
		}
		[STAThread]
		static void Main() {
			Application.Run(new Form1());
		}
	}
}





```
以上。
STM32G031でArduino同士でI2C通信する方法



x 非営利、研究目的で記事を参考にして移植しました。
x PA0を使う時は、OBでGPIOモードにする

目的
I2Cのテスト


![o_con290.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/0b095858-76e0-9346-f001-9682470f1e45.jpeg)



移植元の参考記事


Arduino同士でI2C通信する方法


https://qiita.com/hikoalpha/items/7bf563ee286a59bfd2f4


スレーブのプログラム



```c++



#include <Wire.h>

byte b=0;

void setup() {

  //I2Cの初期化
  //Wire.begin(PA12, PA11); //stm32g031
  Wire.setSDA(PA12);
  Wire.setSCL(PA11);
  Wire.begin(); //pa12 pa11


  Wire.begin(8);// Slave ID #8
  Wire.onRequest(requestEvent);
}

void loop() {
}

void requestEvent() {
  Wire.write(b++);
}




```




マスターのプログラム
主にセンサーからのデータを受信する
マスターモードで受信


```c++


//I2C_Master_ino_031_1

#include <Arduino.h>
#include <Wire.h>

//10の割り算 0から1028までは、正しい。主に0から999
#define DIV10(n) ((n*205)>>11)

#define in7      PA0  // 4pin

#define DW   digitalWrite

#define UART_DELAY 106   // 002-110 9600bps ok 031


//仮想シリアルへの一文字出力 9600bps
int pc_putc(char ch) {

  DW(in7, HIGH);

  DW(in7, LOW);//START
  delayMicroseconds(UART_DELAY);

  for (int ii = 0; ii < 8; ii++) {
    DW(in7, (ch >> ii) & 1  );
    delayMicroseconds(UART_DELAY);
  }//for

  DW(in7, HIGH);//Stop
  delayMicroseconds(UART_DELAY);

  return (0);

}//pc_putc


//文字列の表示
int pc_printf(char *str1) {

  //文字の中身がゼロか
  while (*str1) {

    //一文字出力
    pc_putc(*str1 ++);

  } //while

  //戻り値
  return (0);

}//pc_printf


//初期化
void setup()
{

  //ポートをhiにする 初期化
  pinMode(in7, OUTPUT);
  DW(in7, HIGH);

  //I2Cの初期化
  //Wire.begin(PA12, PA11); //stm32g031
  Wire.setSDA(PA12);
  Wire.setSCL(PA11);
  Wire.begin(); //pa12 pa11

} //setup


//メインループ
void loop()
{

  //読み込み
  Wire.requestFrom(8, 1);

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

  while(Wire.available())  {    // 要求より短いデータが来る可能性あり
    unsigned char b = Wire.read();       // 1バイトを受信

    //表示
    data_read[5] = 0;
    data_read[4] = '\n';
    data_read[3] = '\r';
    data_read[2] = '0' + (  b - (DIV10(b) * 10)  );  // '0'+(b%10)
    b = DIV10(b);
    data_read[1] = '0' + (  b - (DIV10(b) * 10)  );  // '0'+(b%10)
    data_read[0] = '0' +  DIV10(b);                  // '0'+(s/10)
    pc_printf(data_read); //031

  }//while

  //1秒の待ち
  delay(1000);

} //loop



```
cscの作法 その63 3Dチャート

# 概要
cscの作法、調べてみた。
3Dチャートやってみた。

# 参考にしたページ

https://qiita.com/kaiyu_tech/items/8eae8ffc2fae97c8bfa8

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/50b488c9-6cb3-a1bc-a494-7ef43fa475a6.png)

# コンパイル手順

```

>set PATH=C:\Windows\Microsoft.NET\Framework\v4.0.30319;%PATH%

>csc chart.cs /r:System.Windows.Forms.DataVisualization.dll


```

# サンプルコード

```
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace ChartingApp
{
	public partial class Form1 : Form {
		Chart chart;
		public Form1() {
			this.Width = 600;
			this.Height = 500;
			TrackBar track = new TrackBar();
			track.Dock = DockStyle.Bottom;
			track.Minimum = -44;
			track.Maximum = 44;
			track.LargeChange = 50;
			track.SmallChange = 50;
			track.Value = 30;
			this.Controls.Add(track);
			TrackBar track2 = new TrackBar();
			track2.Dock = DockStyle.Top;
			track2.Minimum = -90;
			track2.Maximum = 90;
			track2.LargeChange = 1;
			track2.SmallChange = 1;
			track2.Value = 15;
			this.Controls.Add(track2);
			TrackBar track3 = new TrackBar();
			track3.Dock = DockStyle.Bottom;
			track3.Minimum = 0;
			track3.Maximum = 100;
			track3.LargeChange = 1;
			track3.SmallChange = 1;
			track3.Value = 30;
			this.Controls.Add(track3);
			ChartArea area = new ChartArea();
			area.AxisX.Title = "X";
			area.AxisX.Minimum = -10;
			area.AxisX.Maximum = 100 + 10;
			area.AxisX.Interval = 20;
			area.AxisY.Title = "Y";
			area.AxisY.Minimum = -10;
			area.AxisY.Maximum = 255 + 50;
			area.AxisY.Interval = 20;
			var style = area.Area3DStyle;
			style.Enable3D = true;
			style.IsRightAngleAxes = true;
			style.Perspective = 20;
			style.Rotation = track.Value;
			style.Inclination = track2.Value;
			style.Perspective = track3.Value;
			chart = new Chart();
			chart.ChartAreas.Add(area);
			Random rnd = new Random();
			for (int i = 0; i < 100; i++)
			{
				var series = new Series();
				series.ChartType = SeriesChartType.Point;
				series.MarkerSize = 5;
				series.MarkerStyle = MarkerStyle.Circle;
				series.BorderColor = Color.Tomato;
				chart.Series.Add(series);
				for (int x = 0; x <= 100; x++)
				{
					var value = Math.Sin(x * Math.PI / 18.0) * 100 + 100;
					series.Points.AddXY(x, value);
				}
			}
			area.Position = new ElementPosition(0f, 0f, 100f, 90f);
			chart.Dock = DockStyle.Fill;
			this.Controls.Add(chart);
			track.ValueChanged += (s, e) => {
				this.chart.ChartAreas[0].Area3DStyle.Rotation = ((TrackBar)s).Value;
			};
			track2.ValueChanged += (s, e) => {
				this.chart.ChartAreas[0].Area3DStyle.Inclination = ((TrackBar)s).Value;
			};
			track3.ValueChanged += (s, e) => {
				this.chart.ChartAreas[0].Area3DStyle.Perspective = ((TrackBar)s).Value;
			};
		}
		[STAThread]
		static void Main() {
			Application.Run(new Form1());
		}
	}
}





```

以上。
docker を使う際によく使うコマンドにエイリアス設定しておく（個人的メモ）

```bash:~/.bashrc
alias d="docker"
alias di="docker images"
alias dps="docker ps -a"
alias drun="docker run -it --rm"
alias dkill='docker rm $(docker ps -a --format "{{.ID}}")'
alias dprune='docker image prune'
```
いつのまにかUbuntuにGoogleChromeをインストールするのが簡単になっていた話

## どういうことだってばよ

「Ubuntu Chrome インストール」などで検索すると
[このような](https://ubunlog.com/ja/chrome-algunas-formas-de-instalarlo-en-ubuntu-21-04/)記事が出てきたりしていたが、
いつのまにかGoogle公式で.rpmや.debファイルが配布されるようになっていた。

![Screenshot from 2022-03-27 05-38-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569616/a07caaf2-a41b-5e15-6007-02ce77ba2083.png)

ただ、それだけの話である。
構造化用HTMLタグ

HTML5の構造化用のタグのメモです

### **headerタグ**

headerタグは、サイトのヘッダー部分を構造化する際に使用します。具体的には、サイトのタイトルやナビゲーションなどを囲います。

```html
<header>
<!-- サイトのタイトルやナビゲーションが入ります -->
</header> 
```

### **navタグ**

「nav」とは「navigation（ナビゲーション）」の略で、サイトのメニュー部分を示す際に使用します。

navタグの中には、ul、liタグなどを用いてメニューを作ります。

```html
<nav>
	<ul>
		<li><a href="#about">About</a></li>
		<li><a href="#feature">Feature</a></li>
		<li><a href="#contact">Contact</a></li>
	</ul>
</nav>
```

### **mainタグ**

mainタグは、ページ内で1番伝えたい事・重要な部分を示す際に使用します。

mainタグの中には、articleタグやdivタグなどを用いてページの主となるコンテンツを構造化します。

```html
<main>
<!-- 主要コンテンツが入ります -->
</main>
```

### **asideタグ**

asideタグは、公式では余談要素と記されおり、ページの補足的な情報を示す際に使用します。

サイトのサイドバー部分を構造化する際に適切です。

```html
<aside>
<!-- ページの補足的なコンテンツが入ります -->
</aside>
```

### **footerタグ**

footerタグは、webサイトの末尾・最後の部分を示す際に使用します。

サイトに関する情報や、著作権に関する表記、連絡先などを構造化します。

```html
<footer>
<!-- 著者の情報やコピーライトが入ります -->
</footer>
```
WidgetKitで初心者の躓きどころ

# WidgetKitで初心者の躓きどころ
WidgetKitをみたら、いくつか躓きどころが合ったのでまとめてみました。


特にWidgetはメインのTargeと別なので
Targetが違うと色々参照できるようにする必要があります。


## 1. メインのターゲットを参照できない
参照したいファイルのTargetMembershipにチェックを入れればOK
※一つのファイルにいろんな依存物があると、それら全てをtチェックしないといけないので、各オブジェクト毎にファイルを分けるべし。

## 2. メインのTargetとは別でWidgetのTargetを作成するのでLibraryが参照できない。
Testなどと同様LibraryのTargetも追加する必要がある。

### Cocoa Podsの場合
podファイルのWidgetのTarget内に```inherit! :search_paths```を指定OK
```xml
  target 'SampleWidgetExtension' do
    inherit! :search_paths
  end
```

### SwiftPMの場合
プロジェクトのWidgetのTargetのBuild Phasesで必要なLibraryを連携したらOK

## 3. DB内のデータが参照できない。
CoreDataやRealmを使っている場合
メインアプリのデータを参照するにはAppGroupで同じDBファイルを参照できるようにする必要がある。

### AppGroupの設定
アプリの Target を選択し、Signing & Capabilities タブで、App Groups を追加します。
App Groupsの項目が無い場合は左上の＋ボタンでダイアログの中からApp Groupsを選択。
新しいGroupを作成して下の更新ボタンをクリック。

※注意
Build Configurationが複数ある場合はそれぞれ必要なBuild ConfigurationでAppGroupの設定が必要

### CoreDataの場合
NSPersistentStoreDescriptionのurlにAppGroup名を使って初期化します。
```Swift

        let container = NSPersistentContainer(name: TodoListStore.containerName)
        container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.SampleWidget")!.appendingPathComponent("Sample.sqlite"))]
        container.loadPersistentStores(completionHandler: { (description, error) in
            if let error = error as NSError? {
                print("Unresolved error \(error), \(error.userInfo)")
            }
        })
        print(container.persistentStoreDescriptions.first?.url ?? "nil.splite")
        return container
```


### Realmの場合
Realmインスタンスを作成する時に同じDBを参照するためにConfigurationのfileURLにAppGroupのURLを設定します。

```swift
        let realm = try! Realm()
```
このようにインスタンスを作っている箇所を下記に変更
```swift
        var config = Realm.Configuration()
        let url = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.SampleWidget")!
        config.fileURL = url.appendingPathComponent("db.realm")
        let realm = try! Realm(configuration: config)
```


# URLから取得して画像を表示する場合は非同期では動かない。
Widgetに置いてURL画像の表示をする場合非同期処理は使えない。
Widgetでは同期的に取得するべし。


- 非同期処理の場合
```Swift

            DispatchQueue.global().async {
                let data = try? Data(contentsOf: imageURL)
                DispatchQueue.main.async {
                    self.downloadData = data
                }
            }
```

- 同期処理の場合
```Swift
            let data = try? Data(contentsOf: imageURL)
            self.downloadData = data
```

## 最後に
WidgetはSwiftUIでの実装が必要なので、SwiftUIの勉強も兼ねてチャレンジしてみました。
まだ触り始めたばかりなので、また躓き所が出てきたら追記します。


## 参考
- https://www.amazon.co.jp/dp/4844378678
- https://developer.apple.com/documentation/widgetkit/
- https://developer.apple.com/documentation/foundation/filemanager/1412643-containerurl
- https://rightcode.co.jp/blog/information-technology/ios14-realm-data-widget-display
- https://qiita.com/4q_sano/items/c3c108198f7b162c5932
- https://qiita.com/shiz/items/309349d9cdb75084e74e
2022/3/27主にITとかセキュリティの記事

サイバー攻撃が急増…今すぐできる防衛手段、最も注意すべきものは？(3/24)
https://news.nicovideo.jp/watch/nw10704636

ざんねんなセキュリティ--経営責任の丸投げを目的とした「名ばかりCSIRT」(3/25)
https://japan.zdnet.com/article/35184875/

Microsoft 365 from NTT Communicationsへの第三者からの不正利用、多要素認証を推奨(3/25)
https://s.netsecurity.ne.jp/article/2022/03/25/47358.html

ランサムウェア10種がどれだけ速くファイルを暗号化できるのかベンチマークテストした結果こうなった(3/25)
https://gunosy.com/articles/evuDi

【オンラインLIVE配信】日経産業新聞フォーラム
「重要インフラ・産業サイバーセキュリティー対策」(4/27開催)
https://events.nikkei.co.jp/46804/

自動車部品を手掛ける三桜工業、米子会社がランサムウエアで情報流出(3/25)
https://xtech.nikkei.com/atcl/nxt/news/18/12505/

【徹底解明＜ECにはびこるサイバー犯罪＞】第2回 ECのクレカ不正利用、被害額年間数十億円か(3/25)
https://news.mynavi.jp/techplus/article/20220325-2303310/

Anonymous「Nestlèからデータ窃取」宣言、ロシアで活動続ける企業攻撃(3/24)
https://news.mynavi.jp/techplus/article/20220324-2302316/

米、ロシア当局者4人「サイバー攻撃に関与」　21年の起訴状公表(3/25)
https://jp.reuters.com/article/usa-russia-cyber-idJPKCN2LL2MP

件名『【重要】「出前館 アカウントの自動退会処理について』、出前館をかたるフィッシングメールに注意 自動退会処理を行うなどとして偽サイトに誘導(3/25)
https://gunosy.com/articles/ez5pJ

交通事業者かたるフィッシングメール相次ぐ　えきねっと、モバイルSuica、JR西の成り済ましに注意(3/25)
https://news.nicovideo.jp/watch/nw10714751

超広帯域400Gbps回線による複数組織間とのIP映像伝送及びペネトレーションテストに成功(3/25)
https://s.netsecurity.ne.jp/article/2022/03/25/47354.html

新しい BigQuery Storage Write API を使用して、JSON データを BigQuery にストリーミングする方法を学ぶ(3/25)
https://cloud.google.com/blog/ja/topics/developers-practitioners/learn-how-stream-json-data-bigquery-using-new-bigquery-storage-write-api

IOSCOが、DeFiに関する報告書公表。主論点は投資家リスク(3/25)
https://www.neweconomy.jp/posts/206671

【Windows 11対応】Windowsプロダクトキーの確認方法(3/25)
https://atmarkit.itmedia.co.jp/ait/spv/0907/10/news112.html

「.NET 5.0」のサポートが2022年5月8日で終了
最新のLTSリリースである「.NET 6.0」への移行を(3/25)
https://forest.watch.impress.co.jp/docs/news/1397891.html

標準必須特許（SEP）とは何か？ライセンス紛争の背景、日本と世界の対応とは
経済産業省が解説(3/25)
https://www.sbbit.jp/article/cont1/77314?ref=rss

ECサイトを改ざんしてクレジットカード情報などを窃取する「Webスキミング」に注意！(3/24)
https://news.nifty.com/article/technology/techall/12321-1540067/

「デジタル市場法」最終案に欧州理事会と欧州議会の担当者が合意、WhatsAppやiMessageに小規模メッセージングアプリとの相互運用性を求める内容(3/25)
https://gigazine.net/news/20220325-european-parliament-digital-markets-act/

ウクライナ情勢を悪用した手口にご注意！－SNSでの義援金詐欺－(3/25)
https://www.kokusen.go.jp/news/data/n-20220325_1.html

熊本、アサリ出荷４月再開　偽装防止策にＱＲコード添付(3/25)
https://www.iza.ne.jp/article/20220325-BNCMWM456RLY5OLEU7UMYSSCYE/

MicrosoftがWindows 11「Build 22581」を公開　DevからBetaへの切り替え機会を提供
米Microsoftが、「Windows 11 Insider Preview Build 22581」を公開した。(3/25)
https://www.itmedia.co.jp/pcuser/spv/2203/25/news095.html

データの意味を共通理解することで得られる効果とは　IPAが「データの共通理解推進ガイド」を公開(3/22)
https://atmarkit.itmedia.co.jp/ait/spv/2203/22/news038.html

YouTube　通信社「スプートニク」の全リソースをブロック(3/24)
https://jp.sputniknews.com/20220324/youtube-10447096.html

マイクロソフト、世界23ヵ国でセキュリティ人材への投資を拡大(3/25)
https://enterprisezine.jp/news/detail/15766

横河電機の統合生産制御システムに脆弱性、確認と対応を(3/25)
https://news.mynavi.jp/techplus/article/20220325-2303331/

LINEに電話番号認証を求める通知メッセージが届いたときの対処法(3/24)
https://news.mynavi.jp/article/20220324-2302583/
【NestJS】TypeORMError: No connection options were found in any orm configuration files.の解決方法

# 概要

`Entity`を基に`migration`を作成すると以下のエラーが発生したので解決方法をまとめる

```bash
npx ts-node ./node_modules/.bin/typeorm migration:generate --name user          

Error during migration generation:
TypeORMError: No connection options were found in any orm configuration files.
```

https://github.com/nestjs/nest/issues/4990

# 解決方法

## `ormconfig.ts`をルートディレクトリに生成する

```ts:ormconfig.ts
module.exports = {
  type: 'mysql',
  host: process.env.DB_HOST || 'localhost',
  port: process.env.DB_PORT || '3306',
  username: process.env.DB_USERNAME || 'root',
  password: process.env.DB_PASSWORD || 'password',
  database: process.env.DB_NAME || 'meetup',
  synchronize: false,
  logging: true,
  entities: ['src/entities/*.ts'],
  migrations: ['src/databases/migrations/*.ts'],
  seeds: ['src/databases/seeders/*.seed.{js,ts}'],
  factories: ['src/databases/factories/*.factory.{js,ts}'],
  cli: {
    migrationsDir: 'src/databases/migrations',
    entitiesDir: 'src/entities',
    seedersDir: 'src/databases/seeders',
    factoriesDir: 'src/databases/factories',
  },
};
```

## 設定ファイルを定義することで成功します

```bash
npx ts-node ./node_modules/.bin/typeorm migration:generate --name user                    
Migration meet-up-dev/src/databases/migrations/1648319214540-user.ts has been generated successfully.
```
Unity備忘録 .h5形式から.onnx形式への変更に七転八倒した話

UnityのBarracudaにAIモデルを適用するためには、
作成したAIのモデル(.h5)形式を.onnx形式に変換する必要がありました。

変換の方法ですが、keras2onnxを試してもエラーで全く動作しなかったため、
tf2onnxを使ってモデル変換に成功しました。

重大事項としてtf2onnxは.h5形式に非対応のため、
そもそもモデル作成時に.h5形式で保存するのではなく、
TensorFlow SavedModel形式でフォルダごと書き出す対応が必要になります。

つまりモデル作成時に
```
save_model_path = os.path.join(backup_dir, 'my_model.h5')
model.save(save_model_path)
```
ではなく、
```
save_model_path = os.path.join(backup_dir, 'my_model')
model.save(save_model_path)
```
という.h5拡張子を付けないコードで保存すると、
TensorFlow SavedModel形式として、モデルがフォルダごと生成されます。

その後、Macのターミナル上で下記のコマンドを実行することで、
文末のmy_model.onnxという変換後のモデルが生成されます。

```
python3 -m tf2onnx.convert --saved-model my_model --output my_model.onnx
```

ちなみにtf2onnxを使用するためには、
あらかじめいくつかインポートしておく必要がありますので、
下記を参考にしてくださいね。
https://github.com/onnx/tensorflow-onnx
【Docker】名前付きボリュームをホスト側の任意のファイルパスに作成する方法

## はじめに
　本記事は、プログラミング初学者、学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
　そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
　間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

## 名前付きボリュームをホスト側の任意のファイルパスに作成する方法
docker-compose.ymlのトップレベルの`volumes`に以下のように`driver_opts`を記述することで名前付きボリュームを任意のファイルパスに作成することができます。

```docker-compose.yml

version: '${COMPOSE_VER}'
services:
  api:
    build:
      context: .
      dockerfile: ./docker/api/Dockerfile
    command: bash -c "mkdir -p ./tmp/sockets && bundle exec puma -C config/puma.rb"
    restart: on-failure
    volumes:
      - .:/myapp
      - public-data:/myapp/public
      - tmp-data:/myapp/tmp
    environment:
      RAILS_ENV: ${APP_ENV}
    ports:
      - "${API_PORT}:3000"
    depends_on:
      db:
        condition: service_healthy
  web:
    build: ./docker/web
    volumes:
      - public-data:/myapp/public
      - tmp-data:/myapp/tmp
    ports:
      - 80:80
    depends_on:
      - api
volumes:
  mysql_data:
  public-data:
    driver_opts:
      type: none
      device: ${PWD}/public
      o: bind
  tmp-data:
     driver_opts:
      type: none
      device: ${PWD}/tmp
      o: bind

```

`device`のファイルパスは絶対パスで記述する必要があります。
デベロッパー登録なしで特定アカウントのツイートを取得する「TWINT」

## 環境
Ubuntu 18.04.2 LTS (Bionic Beaver)
Python 3.6.9

## 概要

自分じゃない人のツイートを一括で入手できんかな、と思うことは良くあるが、
**デベロッパー登録が面倒でいつもやらずにいた**。
（英文で「こんなことに使いたい」と書く必要があり、他の設問？もけっこう多い。レスポンスも数日単位）
どうやら登録せずにツイートを取得する方法があるようなので、試してみた。
Python3が使えれば、1行コマンドでインストールできる。
[TWINTのプロジェクト GitHub](https://github.com/twintproject/twint)

## tl; dr (結論）

TWINTは、取得できるツイート数が少なくても良い場合は手軽な手段だが、ちゃんとした用途には使えない。

## 参考URL

https://qiita.com/ykimura517/items/e0b9b23cd38d9e2f4b9f

## 注意点

参考URLによれば、正常にインストールされれば「twint」で実行できるということだったが、

```
# twint

Command 'twint' not found, did you mean:
(略)
```

見つからない、と言われてしまった。

findで見つけてフルパスで使用した。

```
# /root/.local/bin/twint -u [user_name] -o output.csv --csv
```

## 実行結果

出力フォーマットは以下のような感じ。

```
1507544121606xxxxxx 2022-03-26 11:25:02 +0900 <[user_name]> [tweet contents]
1507541604466xxxxxx 2022-03-26 11:15:01 +0900 <[user_name]> [tweet contents]
1507539094020xxxxxx 2022-03-26 11:05:03 +0900 <[user_name]> [tweet contents]
```
x は伏せ字（数字）。
csvを指定しているはずですが、カンマはなく、空白区切りのようです。

個人的にはAPIを使用した場合の現在の上限である3,200件の取得を期待したのですが……

```
アカウント1 …… 260件
アカウント2 ……  20件
アカウント3 　…… 112件
```

という感じで、件数は不定で、かなり少ないようです。ツイート内容の長さや、期間などに関係なく、

```
[!] No more data! Scraping will stop now.
found 0 deleted tweets in this search.
```

という表示で終了します。
「No more data!」とありますがツイート自体は、どのアカウントもツイート数は1000以上はあります。
「found 0 deleted tweets」と出力がありますが、削除ツイートがあるアカウントでも0と表示されるので、実際に削除ツイートを反映している訳でもないようです。

## 感想
登録不要ですぐ使えるのは良いが、取れる件数が少なく、さらに不定数なので、ちゃんとツイートを取得したい場合には面倒でもデベロッパー登録をするか、Selenium系の取得を使う必要があるようです。

## ネクスト・コナンズ・ヒント！

[stweet](https://github.com/markowanga/stweet) というのが良いらしい、というヒントを得た。

## ネクスト・参考URL！
[【Twitterスクレイピング】twintの代わりにstweetをインストール](http://t.ly/G2B1t)

## ネクスト・結末！

stweet、プロフィールは取れるけど、ツイートはほとんど取れず、使えませんでした！
digisparkを使ってiOSのアクセシビリティのスイッチコントロール用の外部スイッチボックス作成

iPhone、iPadなどのiOSにはアクセシビリティという設定があって、その中のスイッチコントロールという機能を使うとスイッチで[iOS機器を操作](https://support.apple.com/ja-jp/HT201370)できるようになっています。

これの外部スイッチ用のスイッチボックスの作成メモです。

## iOSの外部スイッチ
 とりあえずここではUSBで接続するもの

USBで接続する場合にはiPhoneやiPadに[Lightning - USBカメラアダプタ](https://www.apple.com/jp/shop/product/MD821AM/A/lightning-usb%E3%82%AB%E3%83%A1%E3%83%A9%E3%82%A2%E3%83%80%E3%83%97%E3%82%BF)(ipad proなどのようにUSB-Cのものに関しては[USB-C - USBアダプタ](https://www.apple.com/jp/shop/product/MJ1M2AM/A/usb-c-to-usb%E3%82%A2%E3%83%80%E3%83%97%E3%82%BF))というものを接続します (スイッチボックスの電源はiphoneからもらいますので、電源が接続できる[Lightning - USB 3カメラアダプタ](https://www.apple.com/jp/shop/product/MK0W2AM/A/lightning-usb-3%E3%82%AB%E3%83%A1%E3%83%A9%E3%82%A2%E3%83%80%E3%83%97%E3%82%BF)のほうがよいかと思います)。 そこに以下で作成するスイッチボックスをつなぎます。

## 基本的なこと
iOS機器に対して半角スペースとかを入力してあげれば良いようです。つまりスイッチボックスはキーボードとしてふるまえば良いみたい。 試しにLightning - USB 3カメラアダプタにキーボードをつないであげると外部スイッチとして登録できます。 なのでサポートする人が自分のiPhoneとかでいろいろ試してみたいときにはLightning - USB3カメラアダプタにキーボードをつないであげれば色々試してみることができます。

たぶんdegisparkをHIDキーボードにしちゃうのが一番安いですが「USBキーボード　自作」とかで検索すればいろいろ出てきます。

## 必要なもの
<DL>
 <DT><A href="http://digistump.com/products/1">DigiSpark</A></DT>
     <DD>もう販売終了してしまっているみたいですが、同等品(?)がamazonとかでも買えます。本来のDigiSparkは直刺しのUSB TypeAですが、これだと抜けやすかったりしてちょっと使いにくいです。同等品でmicroUSBのものがありますので、そちらを使った方が幸せになれるかもしれません。ただ何度も抜き差ししているとmicroUSBのものはUSBをつなぐところがとれちゃうことがあるようです。</DD>
     <DT>スイッチ接続用の3.5mmモノラルジャック</DT>
     <DD>スイッチをつなぐためのもの</DD>
     <DT>Arduinoとか</DT>
     <DD>ArduinoでDigiSparkボードを使えるようにしておく。「digispark 開発環境」とかで検索すると色々でてきます</DD>
</DL>

## 配線
![iphone_key.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606546/e95ade3f-059e-36ad-7eb4-2af157141e42.png)
工作的にはボードとモノラルジャック(コミュニケーション支援用のスイッチやセンサ類は3.5mmモノラルプラグに出力される)をつなぐだけなので簡単ですかね。

## プログラム
~~~arduino:iphone_key.ino
#include "DigiKeyboard.h"
#define KeyPort 0

bool outputState = true;

void setup() {
  pinMode(KeyPort,INPUT_PULLUP);
}

void loop() {
  usbPoll();
  if (digitalRead(KeyPort) == LOW) {
    if(!outputState) {
      outputState=true;
      DigiKeyboard.sendKeyStroke(KEY_SPACE);
    }
  } else {
    outputState = false;
  }
  DigiKeyboard.delay(50);
}
~~~

## 注意
iPhoneにつなぐと「このデバイスは使えません」とか「外部スイッチが見つかりません」とか出ることがあります。でもそのあと外部スイッチとして使えるようになります。

これはDigiSparkボードに書き込み用のファームウェアが入っていて、USB接続したときにまず書き込み用のファームウェアが働いてそのあとに先ほど書き込んだキーボードのファームウェアが働くためです

私は試してないけど[Digispark ATtiny85 起動までの5秒を取り除く](https://qiita.com/nak435/items/67aca33ca49b6f328faa)を使うと幸せになれるらしい

## 参考
ICT救助隊のiPadとスイッチコントロール(pdf)
[https://www.rescue-ict.com/souko/iPad_and_SwitchControl_S.pdf](https://www.rescue-ict.com/souko/iPad_and_SwitchControl_S.pdf)
VRoid Studioのパレット機能について

# 待望のパレット機能だが。。。

3月24日リリースのVRoid Studio 1.5よりテクスチャ編集画面のカラーセレクターの下にパレットが追加されています。

![スクリーンショット 2022-03-27 0.38.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/931697/789c1dc0-2b07-d0ce-1118-0aec61f55c11.png)

で、そのパレットですが、6列固定で、固定縦幅の「ブラシカラー」項目の下に末尾に追加される形で色が増えていき、スクロールバーでアクセスする構造となっています。削除して新規登録する以外では一度作ったカラーの再編集は不可能 **（だったらパレットはポップアップ表示でいいのでは？）** 。
正直このスクロールが煩わしくて、使い勝手が良くない印象は受けます。

いずれにしてもパレットの整理（色の再編集や並べかえ）はしたいですね

# パレットデータはどこに保存されているのか

VRoidの設定ディレクトリの preferences/palette.xml に保存されます。

 <details><summary>設定ディレクトリの場所</summary>

以下のページ説明でいえばcustom_itemsフォルダから一つ上がったフォルダのことを指します。

 * 作成したモデルやカスタムアイテムのデータはどこに保存されますか？
   https://vroid.pixiv.help/hc/ja/articles/900007039003

つまり、パレットファイルのパスは(macOSの場合)

```
/Users/<username>/Library/Containers/net.pixiv.vroid.macosx/Data/Library/Application Support/net.pixiv.vroid.macosx/preferences/palette.xml
```

となります。
</details>


# VRoidにおけるパレットデータの読み書きのタイミング

今回追加されたのは、各.vroidモデル依存ではなくアプリケーション全体で持つパレットとなりますが、VRoid Studioの起動時にXMLを読んで、終了時に吐き出しているようです。
つまり起動中にparelle.xmlを別のアプリで編集してもVRoid Studio終了のタイミングで持っているパレットで上書きしてしまうので、もし手動編集するならVRoid Studioを起動してないときにするのがよいでしょう。


# パレットデータの構造

Wellsという配列に各色が保存されている至ってシンプルなデータ構造です。
下記のXMLは３色のみのパレットの場合です。

```XML
<?xml version="1.0" encoding="utf-8"?>
<ColorPalette xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Wells>
    <Well>
      <Color>
        <r>0.2</r>
        <g>0.2</g>
        <b>0.2</b>
        <a>1</a>
      </Color>
      <Id>e313369a-6b28-45a9-9541-1a7a4dd6e538</Id>
    </Well>
    <Well>
      <Color>
        <r>1</r>
        <g>0.54273504</g>
        <b>0.54273504</b>
        <a>1</a>
      </Color>
      <Id>bbc597cc-8c89-4c64-b772-a651e6482447</Id>
    </Well>
    <Well>
      <Color>
        <r>0.5982906</r>
        <g>0.5982906</g>
        <b>0.5982906</b>
        <a>1</a>
      </Color>
      <Id>3a4bcff4-962b-49d9-82c1-283a5e38b518</Id>
    </Well>
  </Wells>
</ColorPalette>
```

## コードで表すなら...
これをC#コードでいうとこういうシンプルな構造になるかと思います。

```C#
class RGBA {
    public float r { get; set; }
    public float g { get; set; }
    public float b { get; set; }
    public float a { get; set; }
}
class Well {
    public RGBA Color { get; set; }
    public string Id { get; set; } //GUID
}
```

RGBは0.0から1.0までの実数値をリテラルとして持つようです。
255を掛けて小数点以下四捨五入すると、整数のRGB値が得られるはずです。
（また整数値から逆に実数表現に変換するには255.0で割ればいいことになります）

Aは多分不透明度（Alpha）を指すと思われますが、常に1になっているようで今のところ使い道がありません。
（VRoid Studio側の不透明度の設定などは読み書きしていないように思われます）
あるいは将来的に使うのでしょうか？

また、IdはGUIDを割り振っていますが、重複しないIDを乱数を使って機械的に採番されているものと思われるので特に規則はないと思います。
（極端な話、外部ツールで新たにカラーを追加する場合UNIX/Linuxのコマンドラインツールのuuidgenあたりが吐き出す値でも好きに使えばいいと思います）


# 所感

構造がシンプルなのでPhotoshopやクリスタのカラーパレットを移植するのはそうそう難しくもない気がしますが、果たして。
Linuxにおけるサービスについて

【Linuxにおけるサービスとは】
裏で稼働しているアプリケーションのこと。
プロセスも裏側で動くソフトウェアだが、プロセスはOSが自動で実行しメモリ上で動作するのに対して、サービスは人間が導入するかを決定して使う。
(ちょうどFWとライブラリの関係に近いですね。)

【主要なRedHatサービスの一部】
abrt-ccpp.service C/C#のバグを報告してくれる
abrtd.service 他のabrtサービスに作用するデーモン
abrt-oops.service カーネル oops のアナライザーを提供する ABRT サービス。意味不明
abrt-vmcore.service カーネルのパニックアナライザー並びにレポーターを提供するサービス
abrt-xorg X.org Serverのクラッシュ情報を収集して処理する
getty@.service ターミナルを管理する。権限のないアクセスから保護してくれる(Permission deniedとか、それ系？)
ivqbalance.service 割り込み処理(実行中のプログラムを一時中断して、別のプログラムを実行する)を負荷分散してくれる
kdump.service クラッシュ時にメモリ内容をダンプしてくれる。クラッシュの原因解明に役立つ
microcode.service CPUのバグにパッチを当てて応急処置してくれる
Network-Manager-dispatcher.service ネットワークイベネットワークイベントに際してユーザが提供したスクリプトを実行してくれる
Network-Manager.service 動的なネットワークコントロールを提供してくれる
rhsmscrertd.service 製品保証やサポートのトラッキングをしてくれる
rsyslog.service ネットワーク経由のログ転送、DBへのログ出力をサポートしてくれる
sshd.service SSHサーバのON/OFFを提供してくれる
systat.service 定期的なシステムリソースの監視情報を記録してくれる
systemd-readahead-drop.service 別のサービスで収集したデータをシステム更新時に消してくれる
systemd-readahead-replay.service systemd-readahead-replace.serviceで集めたデータを中継してくれる
tuned.service システム設定をチューニングしてくれる
psacct.service プロセスアカウンティグのサービス。コマンド実行履歴を残してくれる
vsftpd.service FTPサーバを作ってくれる
actagent.service タイムスタンプを付与した状態で各システム情報を採取してくれる
iscsi.service IPネットワーク経由でリモートにあるストレージにアクセスするプロトコルを提供してくれる
multipathd.service サーバとストレージ間の経路を複数確保してくれる
受験宣言したら本当に黒本が送られてきたのでPHP7初級技術者試験を受けて合格してきた話

# 発端

1
-

https://www.phpexam.jp/2021/09/12/bookcamp/

> 全世界のWebサイトの8割弱がPHPで稼働するようになり（W3Techs調べ）、PHPの求人数が全プログラミング言語で1位になりました。（Indeed Japan2021年7月データ集計による）当機構としては今まで以上にPHPを学習する人を支援するべく、PHP7初級試験公式問題集をプレゼントするキャンペーンを展開します。

> ご自身の指定SNSで「2022年3月末までにPHP技術者認定試験を受験します！」と2022年3月末日までに宣言をされた方を対象書籍をプレゼントします。

（上記サイトより）

2
-

https://twitter.com/msattova/status/1480203285013626880

3
-

しばらくして、黒本（『徹底攻略PHP7技術者認定［初級］試験問題集』）が届きました。

https://book.impress.co.jp/books/1118101075

受験しないという選択肢が消えたので受けてきました。

# 試験一ヶ月前～試験当日

とりあえず作ってみる
-

他のプログラミング言語はそれなりに学習経験があったので、勉強する上での大きな課題は主に以下の二つでした。

1. PHPの仕様を把握する（関数名は大文字小文字を区別しない、`""`と`''`の違いなど）
1. サーバサイド言語ならではの処理について（フォームでの情報のやりとり、データベースに関する処理など）

最初は黒本をぱらぱらと捲りながら漫然と進めていたのですが、それでは捗らなかったのでPHPの入門書を購入することにしました。

https://www.amazon.co.jp/dp/B08X9XY72Z/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

初歩的かつ実践的な知識を多く得ることができ、「サーバーサイド？　なにそれ？」「POSTメソッドとGETメソッドの区別がつかない」「データベースって結論を出せない人のことでしょ」な私をしっかりと導いてくれました。

この本である程度の知識をつけ、写経するのにも飽きてきてからは自分で本の内容を参考にしつつ実際に動く**CRUD**（**C**reate **R**ead **U**pdate **D**elete）のできるサイトを作ってみたりしました。

知識も集中力もやる気も足りない
-

「けっこう知識がついてきた」

そんな手応えがあったので、黒本の模擬試験問題に挑戦してみることにしました。
この時点でだいたい試験まであと2週間くらいです。

結果はおよそ6割正解。

山勘も込みでこの点数なのであまり芳しくありません。（ちなみに試験は7割正解で合格となります）

黒本をしっかりと読み込めば点を伸ばすことなど容易にできるのでしょうが、黒本を真面目に何度も、細部まで読むほどの集中力や熱意といったものは私にはありませんでした。

というわけで、公式に指定されている主教材に手を出します。

https://www.oreilly.co.jp/books/9784873117935/

（このOreillyのebookストアについては私が参加しているslackコミュニティで勉強方法について相談した際に教えていただきました。感謝）

ちなみに主教材（『初めてのPHP』（PHP7版））を購入したのはなんだかんだで **試験まで残り4日** という段階になってからのことでした。本当に合格する気があるのかこいつ。

こうして振り返ってみると、果たして真剣に勉強してたのか、かなり怪しいのですがまあ、そんな私でも合格できたのでそれなりに勉強すれば突破できる試験ということです。たぶん。

ともあれ、主教材（電子版）を手に入れて黒本の模擬試験もなんとか7割とれるようになりました。

しかし、模擬試験でなんとか7割とれるという程度では本番では6割しかとれないということを意味します。そういうジンクスを私は信じています。

というわけで試験直前の追い込みの一環として公開されている合格体験記を読み漁ったり、黒本をもっと真剣に読んでみたり、無料で利用できる模擬試験サイトを使ったりしました。

https://study.prime-strategy.co.jp/study/ph7el1/

最終的に、こちらのサイトから受けられる模擬試験は試験前の２日間で2回受験しました。

ひとまず、自分自身の中でのボーダーを8割に設定して受験し、1回目で75点、2回目で87.5点をとりました。

学生証がない
-

試験当日。試験を申し込んだ会場に試験開始30分前に行きました。Odyssey IDとパスワードを頭に入れてから受付へ。

「学生証を出してください」

学生料金だと通常料金の半分で受験できます。というわけでまだ学生の私は学生料金で申し込んでいました。
財布の中の少し取り出しにくいところに入れてあるので面倒臭いなあと思いつつ財布の中を探し…………**見付かりませんでした**。

しかし、温情溢れる措置のおかげでどうにか、その日に受験させてもらうことができました。
その措置とは、「一週間以内に試験会場に学生証を提示しに行く」と約束して誓約書にサインするだけです。ちなみに、それができなければその回の試験結果が無効になるだけでなく、**受験資格を永久に失ったりする**みたいでした。
（※あくまで、私の記憶をもとに書いています）

自業自得で余分なプレッシャーを感じつつも、試験に臨み、無事に合格しました。（試験結果は受験終了後、すぐに確認することができます）

というわけで急いで家に帰って学生証を探します。結果、**『錆喰いビスコ』の本の間から学生証を発見することができました。**[^1]

翌日、試験会場に学生証を見せに行って正式に合格が認められました！

教訓
-

* 身分証を本の間に挟むな
* 身分証の管理はしっかりと行え
* 家を出るときは持ち物をちゃんと確認しろ
* 公式サイトで必要な持ち物をしっかりと確認しておけ

やって良かった勉強法
=

試験それ自体の難易度は——名前に「初級」とついているだけあって——そこまで高くはありません。しかし、試験範囲の知識を正しく理解していなくてはなりません。

というわけで、**「黒本の問題は正解を覚えるのではなく、不正解の選択肢が不正解である理由も込みで覚える」** ようにした方がいいです。


そして、PHPの公式ドキュメントに目を通すのも重要です。ニッチな知識は要求されませんが、よく使う関数の仕様くらいは細かい部分まで把握しておくべきなので。

https://www.php.net/manual/ja/

だいたいこの辺のことをやれば、なんとかなるのではないかと思います。

終わりに
=

最後に、これだけは言っておきます。

試験当日に必要な所持品は **必ず** あらかじめ確認しておきましょう。

私はこれを怠って死を覚悟しました。

以上です。


 [^1]: ちなみにこのことを馴染みのdiscordサーバーで報告すると「えぇ……」というコメントが並ぶことになりました。なんとなく、「真面目に心配して損した」「なんだそれ」という感じのニュアンスが籠っていた気がします。
【差分比較】ファイルやディレクトリの差分を比較する方法


## ディレクトリ同士の差分を比較する方法

ディレクトリ内のどのファイルが異なっているか確認するには "diff" コマンドでディレクトリ同士を比較すると分かりやすいです。
```
$ pwd  # 比較したいディレクトリまで移動してから、「pwd」で確認パスを確認
$ diff -rq ＜ディレクトリのパス1＞ ＜ディレクトリのパス2＞  ＃ "pwd" で確認したファイルのパスを＜ディレクトリのパス1＞と＜ディレクトリのパス2＞に指定
```

## ファイル同士の差分を比較する方法

どのファイルを比較したいかは分かるけど、そのファイルのどの部分に差分があるのか確認したい場合は ”git diff” コマンドでファイル同士を比較すると分かりやすいです。
```
$ pwd  # 別々のディレクトリにある場合は二つターミナルを立ち上げて比較したいファイルまで移動してから、　”pwd"　で確認するという方法でもいいかもしれません。
$ git diff ＜fileA＞ ＜fileB＞  ＃ "pwd" で確認したファイルのパスを＜fileA＞と＜fileB＞に指定
```

---

## Gitのコミットで比較する場合
あのコミットした時の状態と、このコミットした時の状態を比較したい。みたいな時には ”git diff” コマンドでコミットID同士を比較すると分かりやすいです。
かなり実用的で、私も良く使用しています。
```
$ git log  # 比較したいコミットの同士のID（ハッシュ値）を確認。
$ git diff ＜コミットID1＞ ＜コミットID2＞  ＃ "git log" で確認したファイルのパスを＜コミットID1＞と＜コミットID2＞に指定
```

以上、参考になれば幸いです。