OmniAICreator/Qiita-1.07M huggingface dataset:
パラメータで任意の期間を抽出する(SPSS Modeler データ加工逆引き1-22)

# パラメータで任意の期間を抽出する

![スクリーンショット 2024-09-10 8.56.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/1d075224-c4b0-65f7-32b5-f0b1a8ede34e.png)

## 1.想定される利用目的

・定形レポートのための抽出
・SPSS　CADSを利用したストリームの自動化

## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/raw/main/parameter_7days.str

## 3.サンプルストリームの説明

![スクリーンショット 2024-09-10 14.47.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/858747d5-0e8b-5ad2-6b30-4403168415f3.png)

a.入力するデータは以下の通りです。日付と部問名（Cate）にランダムな実績値(Value)を割り当てています。

![スクリーンショット 2024-08-30 11.13.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/613871f0-0adc-a5e8-42bf-6d2cab2e8191.png)

#### ストリームにパラメータを設定する

[ツール]メニューから以下のように[パラメータ]を選択。　

![スクリーンショット 2024-09-10 14.48.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/b1db6f3e-452f-0b79-504e-f480d8b59008.png)

以下のように設定します。サンプルストリームには必要事項が設定されています。値はブランクでOKです。

![スクリーンショット 2024-09-10 14.53.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/65a050ff-2caa-5ea0-8306-b1d6403bc220.png)

#### 設定したパラメータをノード内で呼び出す

b.[条件抽出]ノードを編集します。赤枠のパラメータリストから定義済みのパラメータを呼び出せます。

![スクリーンショット 2024-09-10 14.54.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/961c027d-44af-4f3a-fee7-d9760e450294.png)

[検査]ボタンや[適用]ボタンで以下のメッセージが出ても　[OK]。

![スクリーンショット 2024-09-10 14.52.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/3b531c22-b35e-f15f-cfa7-61fdbb395dd1.png)

![スクリーンショット 2024-09-10 14.55.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/3c3f1599-84c1-eb9c-5e48-d82bd095d21c.png)

#### ストリームを全実行する

赤枠の再生ボタンを押します。

![スクリーンショット 2024-09-10 14.56.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/29b83b20-7bf5-887d-a9d2-183f82739bd6.png)

プロンプトが起動しますので任意の開始日と終了日を指定し[OK]ボタンで実行。

![スクリーンショット 2024-09-10 14.57.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/6382c83c-145a-5c7b-95ae-efc4834dba2c.png)

　[テーブル]が表示されます。

![スクリーンショット 2024-09-10 14.57.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/866b568c-1412-eacc-da53-7564097b39fe.png)


#### 注意事項

今回はバッチで利用する場合を想定してストリームパラメータを取り上げましたが、スーパーノードでルーチンとして利用することもできます。

https://qiita.com/416nishimaki/items/3cb4ba382cf28468e3a3


## 4.参考情報

#### ストリームをパラメータで制御する

https://qiita.com/416nishimaki/items/358d76b28465c7c09c36

#### タイムスタンプの差の計算

https://qiita.com/kawada2017/items/8e1291801aacf5427e7d

#### よく使う「日付と時間」関数

https://qiita.com/Makimaki2020/items/72e3b774039327fa4ac4

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
nixがmacOS sequoiaにアップデートすると、error: the user '_nixbld1' in the group 'nixbld' does not exist というエラーで動作しない問題を解消する方法

エラー全文

```bash
error: the user '_nixbld1' in the group 'nixbld' does not exist
```

これはsequoiaがこれまでと異なるUID体系に移行したことが要因なので、UIDを新体系に移行します。

```bash
curl --proto '=https' --tlsv1.2 -sSf -L https://github.com/NixOS/nix/raw/master/scripts/sequoia-nixbld-user-migration.sh | bash -
```

これでエラーは解消されるはずですがパーミッション関係のエラーが発生することもあります。

```
/nix/store/7rznhr3z04g5003dqfii98v88blypxqs-source/.git: Permission denied
```

例えばこんなやつですね。

これを地道に修正するのは大変なので、一旦nixをuninstallして入れ直すことをお勧めします。

## nixのuninstall方法

```bash
nix --extra-experimental-features "nix-command flakes" run nix-darwin#nix-uninstaller
```

これでnix-darwinが削除されます。次にnixの方をuninstallします。

```bash
/nix/nix-installer uninstall
```

おそらくnix store volumeの初期化に失敗するので再起動して手動でDisk Utilityからnix storeのvolumeを削除してください。

## 参考

https://github.com/NixOS/nix/issues/10892
TVチューナーサーバーmirakurunのクライアントを作ってみました

## FastAPIとJinja2の練習として
FastAPIとJinja2を自分なりに解釈して、TVチューナーサーバーmirakurunのクライアントを作ってみました。
Ganboという名でフリーウエアとして、ソースコードも公開します。

https://github.com/endou2022/Ganbo

よろしければ、プログラミングの参考にしてください。

## Ganboとは
- Ganboは、TV  チューナーサーバー  [Mirakurun](https://github.com/Chinachu/Mirakurun)  のクライアントです。
- 番組表を表示して録画管理するだけの低機能なソフトです。
	**低機能**なだけに、**簡単に使えます**。<br>
- テレビ番組を録画しておいて時間のあるときに見るという人向けのソフトです。
- 本ソフトよりも高機能なソフトとして、  [Chinachu](https://github.com/Chinachu/Chinachu)  、  [EPGStation](https://github.com/l3tnun/EPGStation)  、  [KonomiTV](https://github.com/tsukumijima/KonomiTV)  などありますが、自分で使いやすいソフトが欲しかったので、本ソフトを作りました。
- CMカット、エンコード、配信（ファイル共有）、録画ファイル管理機能はありません。他のソフトと組み合わせて利用します。
- 詳しくは

https://github.com/endou2022/Ganbo

を見てください。
- ソフトウエアを作ったのですが、使ってくれる人がいないとさみしいので宣伝も兼ねて公開します。

## スクリーンショット
- 番組表![00_daily.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885787/94ae9178-8a66-1522-ba7b-67411dda6204.png)
興味があるジャンル（例えば、映画とかドラマとか）に色を付けて表示できます。
- 終了・新番組![02_new_final.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885787/5dd70b9d-d585-5bb7-20b2-1716d6a5c2e3.png)
終了する番組、新番組を一覧表に出します。新番組を見逃すことがないので、意外に便利です。
- 録画予約![reserved.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885787/33b3cd41-7aaa-7ccd-da13-f776413f8374.png)
番組名をクリックすると、「予約ダイアローグ」が出ます。もちろん、キーワードを利用した自動予約もできます。
保存ファイル名を編集できますので、ファイル名に「最終話」などを追加することができます。

## ライセンス
BSDライセンスです。
ぜひ、フォークしてもっと良いソフトを作ってください。
ソフト名を変えてもかまいません。

## 謝辞
- 本ソフトは、  [Mirakurun](https://github.com/Chinachu/Mirakurun)  と  [Rivarun](https://github.com/Chinachu/Rivarun)  を利用しました。
	作者、および、関係者の方に深く感謝します。
	**Mirakurun**  、  **Rivarun**  ときましたので、本ソフトの名前を  **Ganbo**  にしました。
- 番組表の作成にあたっては、[CSSグリッドレイアウトで番組表（ラテ欄）を試作してみたよ](https://tercel-tech.hatenablog.com/entry/2019/07/06/190452)  (2023/12/02確認)を参考にしました。
	作者の方に深く感謝します。
- 多くの技術情報を参考にしました。
	参考にしたホームページのURLをソースコードに記して感謝します。
	URLの末尾にある数字は、ホームページを閲覧した日付です。

## その他
- ソースファイルは技巧的な書き方をしていませんが、python(FastAPI , Jinja2) , HTML , CSS , JavaScript(jQuery) , SQL  が絡み合っているので、分かりづらいかもしれません。
- 番組表は、意外と簡単な方法で作成しています。
番組表表示後のHTMLソース、g00.cssをご覧ください。
- 配信サービスでテレビ番組を視聴するのが主流となっています。テレビ番組を録画しておいて時間のあるときに見るという人はどのくらいいるのでしょうか。

## おまけ
データベースの照合順序をutf8mb4_unicode_ciにした為に、「ドイツ」で検索（部分一致）すると、「おかあさんといっしょ」もでてきます。
理由が分かるまで２ヶ月かかりました(^_^)。
【Jest】Jest did not exit one second after the test run has completed.の解決方法

# はじめに
Jestでテストを実行した際に、「Jest did not exit one second after the test run has completed.」というエラーに遭遇しました。このエラーは、テストが正常に終了しているにも関わらず、Jestプロセスが終了せずに残ってしまうことを示しています。今回はこちらのエラーの解決策をご紹介します。

:::note warn
***この記事は<font color="Red">個人的なアウトプット</font>を目的として作成したものです。そのため、誤った情報や不足している内容が含まれている可能性があります。もし間違いや気になる点がございましたら、ぜひご指摘いただけますと幸いです***。
:::

# 原因
このエラーは、主に非同期処理が原因で発生します。async/awaitなどの非同期処理が適切に終了していない場合、Jestは全てのテストが完了したと判断できずに、このエラーを表示します。

# 解決策
```package.json
"test": "jest --runInBand --detectOpenHandles --forceExit"
```
このようにscriptsにオプションを設定することで、エラーが解消されます。

## 各オプションの意味
***--runInBand***
並列実行を無効にし、テストを順番に実行します。並列実行による競合や、デバッグ時の追跡しやすさのためにこのオプションを追加します。

***--forceExit***
全テストが終了した後にJestを強制的に終了します。

***--detectOpenHandles***
estが何も出力せずに終了するのを防ぎます。--forceExitを使用する場合、こちらもセットで必要です。

https://jestjs.io/ja/docs/cli#

# 終わりに
一時的な解決策として上記オプションを追加する方法もありますが、根本的には非同期処理の書き方を見直す必要があります。async/await を利用した書き方にすることで、非同期処理の制御がより容易になり、この種のエラーを減らすことができます。

# 参考
https://stackoverflow.com/questions/53935108/jest-did-not-exit-one-second-after-the-test-run-has-completed-using-express

https://stackoverflow.com/questions/53539990/are-there-side-effects-of-running-jest-with-detectopenhandles-forceexit
Quick Start: Build Your First Agent with Agentforce


https://trailhead.salesforce.com/content/learn/projects/quick-start-build-your-first-agent-with-agentforce

# Configure an Agentforce Service Agent

最後の埋め込んだエージェントの場所が分かりにくい。
ビルダーで埋め込んだ場所とは全く関係ない。

Embedded Messaging is the small chat bubble icon in the bottom right corner of the page.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/e5e64bcd-db64-0896-2d25-c88b29d9f94e.png)


+ [Embedded messaging modal is not appearing on pubished site - it. shows as added to Build in. Exp.site but. it. is blank.  Cannot. verify for badge.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ifqGI)
+ [Cannot add Embedded Messaging to the Experience Page](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ifqGS)


# 特別版の環境が作成できない

+ [Not able to create playground for agentforce](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ifvh4)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/4885ff4b-006f-1591-49e6-04da261d955f.png)


# Error Saving Prompt Template Apex class PersonalizedGuestExperiences cannot be used in this template

+ [「パーソナライズされたスケジュールを生成」プロンプトを設定する](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007erzXVSAY)

:::note alert
We can't find that the Generate Personalized Schedule prompt template has been updated. Copy the prompt text into the prompt template, save, and activate it.
:::

:::note
PersonalizedGuestExperiencesのApexクラスの下記の部分を書き換えるとクリアできるようです。

```
@InvocableMethod(
    CapabilityType='FlexTemplate://Generate_Personalized_Schedule'
)
```

下記で置き換えてみてください。

```
@InvocableMethod(
    label='Generate Personalized Schedule'
)
```

:::


# java.lang.IllegalArgumentException: User doesn't have access to use agent

+ [Unable to create new agent in Trailhead Playground (post Agentforce GA i.e. 10/22)](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000n4MC0AY)

:::note
Set. Agent's AGENT USER field = Einstein Service Agent User (auto created during TH Playground provisioning).

Setting agent user = any other user, even a system admin having DC Admin perms or "orgfarm epic" user results in error message.
:::
Grove Starter Kit for BeagleBone Green まとめ(Arduino UNO 3)


![o_coq429.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/186985f0-f1b1-76ed-81d4-1f8fb0f787ea.jpeg)


販売コード 109796
型番 110060131
発売日 2015/10/01
メーカーカテゴリ Seeed Studio(シードスタジオ)

https://akizukidenshi.com/catalog/g/g109796/

・[Grove I2C ADC](https://qiita.com/caa45040/items/cebf52b853915804d034#grove-i2c-adc)

・[Grove I2C Hub](https://qiita.com/caa45040/items/cebf52b853915804d034#grove-i2c-hub)

・[Grove リレー](https://qiita.com/caa45040/items/cebf52b853915804d034#grove-%E3%83%AA%E3%83%AC%E3%83%BC)

・[Grove ブザー](https://qiita.com/caa45040/items/cebf52b853915804d034#grove-%E3%83%96%E3%82%B6%E3%83%BC)

・[Grove ボタン](https://qiita.com/caa45040/items/cebf52b853915804d034#grove-%E3%83%9C%E3%82%BF%E3%83%B3)

・[Grove 温度センサー](https://qiita.com/caa45040/items/cebf52b853915804d034#grove-%E6%B8%A9%E5%BA%A6%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC)

・[Grove 音センサー](https://qiita.com/caa45040/items/cebf52b853915804d034#grove-%E9%9F%B3%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC)

・[Grove OLEDディスプレイ](https://qiita.com/caa45040/items/cebf52b853915804d034#grove-oled%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%82%A4)

・[Grove 3軸加速度センサ](https://qiita.com/caa45040/items/cebf52b853915804d034#grove-3%E8%BB%B8%E5%8A%A0%E9%80%9F%E5%BA%A6%E3%82%BB%E3%83%B3%E3%82%B5)

・[Grove RGB-LED](https://qiita.com/caa45040/items/cebf52b853915804d034#grove-rgb-led)




・Grove I2C ADC
-------------------------

https://qiita.com/caa45040/items/87439565c1b58fd0a6d3


・Grove I2C Hub
-------------------------

準備中


・Grove リレー
-------------------------

https://qiita.com/caa45040/items/91e7533fa58032a7ff12


・Grove ブザー
-------------------------

https://qiita.com/caa45040/items/8c8ae674051215de13df

・Grove ボタン
-------------------------

https://qiita.com/caa45040/items/eca7c7c4204359fe052b

・Grove 温度センサー
-------------------------

https://qiita.com/caa45040/items/d10bde1921439277ba83

https://qiita.com/caa45040/items/b34c391bc430e03fd701

・Grove 音センサー
-------------------------

https://qiita.com/caa45040/items/5058c046269d2626278c

・Grove OLEDディスプレイ
-------------------------

https://qiita.com/caa45040/items/4c10e86e2f3df03ed133


・Grove 3軸加速度センサ
-------------------------

https://qiita.com/caa45040/items/87da5275c210c2fb1fbc

・Grove RGB-LED
-------------------------

https://qiita.com/caa45040/items/0b72293684642472a327
Linuxのファイルの圧縮について


# Linuxでよく使用する圧縮の形式について

## gzip
Linuxでよく利用される圧縮の形式。gzipで圧縮されたファイルは拡張子が.gzとなる。

## bzip2
gzipよりも圧縮効率は高いが、処理に時間がかかる。圧縮されたファイルは.bz2となる。

## xz
bzip2よりもさらに圧縮効率が高い形式。そのぶんbzip2よりさらに処理時間がかかる。

### ※windowsの場合
ちなみにwindowsではzipで圧縮することがほとんどです。（容量が大きい場合は7-ZipやWinRARといった形式で圧縮することもあるようです。

## アーカイブ

ディレクトリ単位で圧縮を行う場合は、まずアーカイブを作る必要があります。アーカイブは、ファイルやディレクトリを1つのファイルにまとめるための技術のことです。アーカイブを作るには「tar」（tape archive）コマンドを使用します。

# 圧縮に使用するコマンド

## gzip 

・書式
gzip [オプション][ファイル名]

| オプション | 説明 |
|------------|------|
| `-c` | 圧縮したデータを標準出力に書き出します。ファイル自体は変更されません。 |
| `-d` | 解凍を行います（`gunzip` と同じ効果）。 |
| `-f` | ファイルが存在する場合でも強制的に上書きします。 |
| `-k` | 圧縮後も元のファイルを保持します。デフォルトでは圧縮後に元のファイルは削除されます。 |
| `-r` | ディレクトリ内のすべてのファイルを再帰的に圧縮します。 |

### gunzip

・書式
gunzip [ファイル名]

gzipで圧縮されたファイル(.gz)を解凍する際に使用します。※gzip -dコマンドでも解凍できます。

## bzip2

| オプション | 説明 |
|------------|------|
| `-d` | 解凍を行います（`bunzip2` と同じ効果）。 |
| `-z` | 圧縮を行います（デフォルト動作）。 |
| `-k` | 圧縮後も元のファイルを保持します。デフォルトでは圧縮後に元のファイルは削除されます。 |
| `-f` | 上書きの確認なしに強制的に既存ファイルを上書きします。 |
| `-t` | 圧縮ファイルが正常かどうかをテストします。 |
| `-v` | 圧縮/解凍中の詳細情報を表示します。 |
| `-c` | 標準出力に結果を出力します。ファイルには書き込みません。 |

### bunzip2

・bunzip2 [ファイル名]

bzip2で圧縮されたファイル(.bz2)を解凍する際に使用します。※bzip -dコマンドでも解凍できます。

## xz

| オプション | 説明 |
|------------|------|
| `-z` | 圧縮を行います（デフォルト動作）。 |
| `-d` | 解凍を行います（`unxz` と同じ効果）。 |
| `-k` | 圧縮後も元のファイルを保持します。デフォルトでは圧縮後に元のファイルは削除されます。 |
| `-f` | 上書き確認なしに強制的に既存ファイルを上書きします。 |
| `-t` | 圧縮ファイルが正常かどうかをテストします。 |
| `-v` | 圧縮/解凍中の詳細情報を表示します。 |
| `-c` | 標準出力に結果を出力します。ファイルには書き込みません。 |
| `-l` | 圧縮ファイル内のファイル一覧を表示します。 |

### unxz

・書式
unxz [ファイル名]

xzで圧縮されたファイル(.xz)を解凍する際に使用します。※xz -dコマンドでも解凍できます。


# アーカイブの作成

## tar

・書式
tar [オプション] ファイル名、ディレクトリ名



| オプション          | 説明                                           |
|---------------------|------------------------------------------------|
| `c`                 | 新しいアーカイブを作成する（"create"）         |
| `x`                 | アーカイブを展開する（"extract"）              |
| `v`                 | 詳細出力モード（"verbose"）                    |
| `f`                 | アーカイブファイルを指定する（"file"）         |
| `z`                 | gzip 圧縮を利用する（"gzip"）                  |
| `j`                 | bzip2 圧縮を利用する（"bzip2"）                |
| `t`                 | アーカイブの内容を一覧表示する（"list"）       |
| `r`                 | 既存のアーカイブにファイルを追加する（"append"）|
| `u`                 | 既存のアーカイブを更新する（"update"）         |
| `W`                 | アーカイブファイルの一貫性を検証する（"verify"）|
Linux　環境変数について


## 環境変数とは

Linuxの環境変数は、システムやアプリケーションが必要とする設定や情報を保持するために使用されます。環境変数は、シェルのセッションやスクリプト内で参照・設定することができ、特定の設定や動作をカスタマイズするために重要です。

### 環境変数とシェル変数について
環境変数とシェル変数はそれぞれ役割とスコープ（適用範囲）に違いがあります。

**役割**
・環境変数は、システム全体の設定や、他のプログラムやシェルスクリプトで広く使われる情報を保持するために使用されます。

・シェル変数は、スクリプトや一時的な作業でのデータ保持、あるいは特定のシェル内でのみ必要な情報を格納するために使用されます。

**スコープ**
・環境変数は、親シェルから生成された全ての子プロセス（サブシェルやアプリケーションなど）に引き継がれる変数です。環境変数はシステム全体やアプリケーションの設定としてよく使用され、シェル内のあらゆるプロセスがアクセスできます。

・シェル変数は、現在のシェルセッション内でのみ有効な変数で、子プロセスには引き継がれません。シェルスクリプトやシェルの内部でのみ使用される一時的な変数です。

**環境変数とシェル変数の設定方法**

シェル変数
シェル変数は以下の様に設定します。
```
変数名＝値
linux=test
※linuxという変数にtestという文字が設定される
```

また、設定した変数を削除するにはunsetコマンドを使用します。
```
unset linux
```

環境変数
環境変数は以下の様に設定します。シェル変数にexportコマンドを実行することで環境変数となり、子プロセスからでも参照できるようになります。exportで変数名を指定するときは先頭の$記号は不要なので注意しましょう。
```
linux=test
export linux
または
export linux=test
```

## 環境変数の確認方法

### echoコマンド
echoコマンドを使用することでシェル変数や環境変数を参照することができます。echoコマンドでは変数の先頭に$が必要なので注意しましょう。

```
echo $linux
test
```

### envコマンド　printenv コマンド

定義されている環境変数の一覧を表示したい場合はenvまたはprintenvコマンドを使用します。

```
env
または
printenv
```

### set コマンド

環境変数とシェル変数両方の一覧を表示したい場合はsetコマンドを使用します。

```
set
```

## 環境変数をファイルで設定する方法

環境変数をファイルに記述して設定する方法もあります。ファイルに記述することで毎回設定する必要がなくなります。

~/.bash_profileに環境変数、~/.bashrcにシェル変数を記述します。

https://qiita.com/yunzeroin/items/480a3a677f78a57ac52f

https://qiita.com/magicant/items/d3bb7ea1192e63fba850

## コマンドのpathを通す
環境変数 PATH は、LinuxやUnix系のシステムにおいて非常に重要な役割を果たしています。PATH は、シェルがコマンドを実行する際に、コマンドの実行ファイルがどこにあるかを検索するディレクトリのリストを保持している環境変数です。

```
PATH=$PATH:/new/directory/path
または
export PATH=$PATH:/new/directory/path
```

永続的に PATH にディレクトリを追加するには、~/.bashrc や ~/.bash_profile に追加の設定を書き込む必要があります。

注意点として複数の同名コマンドが異なるディレクトリにある場合、最初に見つかったものが実行されます。

環境変数PATHの指定方法として以下の様にしてしまうとパスが通っているコマンドが指定したものだけになってしまい使えなくなります。上記で解説している書式で追加することで環境変数PATHの末尾に追加することができます。
```
PATH=/opt/bin
```
Dockerの基礎を整理

オンプレミスやクラウドのEC2インスタンスやVMしか利用したこと無い私からすると、「コンテナ」「Docker」というものがどうもイメージし辛いため、文字で整理しようと思い本記事を書きました。
同じような悩みを持った人の一助になれば、、


# Dockerとは
1台のサーバー上にコンテナ型の仮想環境を構築することが出来るプラットフォームです。
今までも仮想環境を構築する技術はVirtualBoxやHyper-V等数多くありました。
では従来の技術とDockerは何が異なるのでしょうか？比較しながら整理していきます。

# ホスト型仮想化ソフトウェア
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576311/22831641-a1a1-32ee-f47c-786994750b8c.png)

vagrantの記事を書いた時にも触ったvirtualboxは上記のホスト型仮想化ソフトウェアです。
こちらのメリットとしては比較的仮想化に必要なソフトウェアが扱いやすく、構築するのに必要なイメージも入手しやすいので個人検証で利用しやすいことだと考えています。

# ハイパーバイザー型
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576311/e6d08915-da0a-9f90-e200-35ce4f2245ce.png)
こちらのメリットとしてはホストOSを必要としないためハードウェアを直接制御出来ることだと考えています。
今値上げで話題になっているESXIやmicrosoftのhyper-vなどがハイパーバイザー型です。

（話脱線しますがブロードコム強気ですね、、仮想基盤はVmware社の商品に依存しているところが多いので大変では、、、）

https://xtech.nikkei.com/atcl/nxt/column/18/00001/09307/

# 上２つの従来の仮想基盤の共通点

話を戻しまして上２つは異なる方法を利用した仮想技術ですが、この２構成には共通点があります。
「ゲストOS」が存在していることです。
ゲストOSを稼働させるのに基となるリソースを割いてしまう為、動作が重くなってしまう傾向があります。
では今回の主役のDockerはと言いますと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576311/7a89042d-82ee-cf69-7aba-9df2c3c7214d.png)

ゲストOSが存在しません。
従来の仮想化技術はゲストOSを起動させる事が前提なのに対して、Dockerのコンテナはプロセスとして動いています。
それによって軽量で扱う事ができ、環境差分が少ない状態で複数人で開発を利用することが可能になります。
また、もう一つのメリットとして上の図の通りミドルウェア〜アプリケーション層のソフトウェアがコンテナの中に纏まってありマシンからマシンへ流用することが可能になります。
個人環境のミドルウェアとソフトウェアのバージョン不一致により動かないといったこともありません。

では次の項ではDocker利用に必要な概念などを整理していきます。
少なくとも以下３つは押さえておく必要があると思います。

## イメージ

Dockerの「イメージ」とは、コンテナを動かすためのテンプレートファイルのことです。イメージには、コンテナで使うOSやアプリケーション、実行するコマンドやメタデータなどが含まれています。
コンテナを作る際には、必ず1つ以上のベースとなるイメージが必要です。
このイメージは、Docker Hubなどのオンラインリポジトリからダウンロードして使用します。

## Dockerfile
Dockerfileは、Dockerイメージを作成するための設定ファイルであり、イメージの設計図として機能します。
Dockerfileには、ベースとなるイメージの指定や、インストールするパッケージ、実行するコマンドなどが記述されており、これをもとにDockerイメージが構築されます。
通常、Dockerfileはベースとなるイメージを指定するところから始まります。例えば、FROM ubuntu:18.04と記述することで、Ubuntu 18.04をベースにしたイメージを作成することを示します。
その後、RUN命令などを用いて、必要なパッケージのインストールや設定を行います。例えば、RUN apt-get update && apt-get install -y package1 package2と書くことで、package1とpackage2をインストールすることができます。

## Docker Compose

Docker Composeは、複数のコンテナを効率的に管理・操作するための設定ファイルの役割を担います。
この設定ファイルは通常、compose.yamlと呼ばれ、そこに使用するDockerfileやコンテナ名、ネットワークの設定などが記述されます。
このファイルを元に、必要なコンテナの構成や連携を簡単に管理できるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576311/d99aa129-be7d-2a73-71b6-ef6becf0348b.png)


次回はこれらを使って構築した記事を書きます。
ありがとうございました。
SSLHandshakeException、createSSLExceptionが発生。何が原因で発生？

SSLHandshakeExceptionやcreateSSLExceptionは、SSL/TLS接続を確立する際に何らかの問題が発生したときに発生する例外です。このエラーは、一般的に次の原因で発生することがあります。

## 1. 証明書がKeystoreにインポートされていない
SSL/TLS接続を行う際、サーバーは証明書を使ってクライアントに自身のアイデンティティを証明します。もしクライアントがサーバーの証明書を信頼できない場合（つまり、その証明書がクライアントの信頼されたKeystoreに含まれていない場合）、SSLハンドシェイクに失敗し、SSLHandshakeExceptionが発生します。

#### 発生の理由:

サーバーの証明書がクライアント側のKeystoreにインポートされていないため、クライアントはサーバーの証明書を信頼できないと判断する。
#### 解決策:

サーバーの証明書を取得し、クライアント側のKeystoreにインポートする必要があります。
インポート方法の例（LinuxまたはMac OS）：
```bash
keytool -import -trustcacerts -file server-cert.pem -keystore keystore.jks -alias server-cert
```
インポートする際、server-cert.pemにはサーバーの証明書が含まれている必要があります。

## 2. 自己署名証明書の使用
もしサーバーが自己署名証明書を使用していて、その証明書をクライアントが信頼していない場合、同じようにSSLハンドシェイクは失敗します。

#### 解決策:

クライアント側のKeystoreに自己署名証明書をインポートするか、信頼できる認証局（CA）から署名された証明書をサーバーに導入します。

## 3. 証明書チェーンの不完全
サーバー証明書が中間証明書やルート証明書と一緒に送信されていない場合も、クライアントは証明書を信頼できず、SSLHandshakeExceptionが発生することがあります。

#### 解決策:

サーバー証明書のチェーン（中間証明書やルート証明書）をサーバー側で適切に設定し、クライアントが正しい証明書を受け取れるようにします。

## 4. プロトコルの不一致
クライアントとサーバー間でサポートされているSSL/TLSバージョンや暗号スイートが一致しない場合も、SSLハンドシェイクが失敗します。

#### 解決策:

クライアントとサーバーの間で使用するTLSバージョンや暗号スイートが互換性があるか確認し、必要に応じて設定を変更します。

## 5. クライアント証明書の問題
サーバーがクライアント証明書を要求している場合、クライアントが適切な証明書を提供できないと、SSLハンドシェイクに失敗します。

#### 解決策:

クライアント証明書が正しく設定され、Keystoreにインポートされていることを確認します。

----

SSLHandshakeExceptionやcreateSSLExceptionが発生した場合は、以下のステップでトラブルシューティングを進めると良いでしょう。

#### 1. 証明書が正しくインポートされているか確認
（keytool -list -keystore keystore.jksでKeystoreの内容を確認）
#### 2. サーバー証明書が信頼されているか確認
（クライアントのKeystoreにサーバー証明書が含まれているか）
#### 3. プロトコルや暗号スイートの互換性を確認
#### 4. SSLデバッグログを有効にして詳細情報を確認
（JavaでSSLデバッグログを有効にするには、-Djavax.net.debug=sslオプションを使用）

それでも問題が解決しない場合は、具体的なエラーログや証明書の詳細情報を確認することが重要です。
国際的な職場におけるコミュニケーションの課題

先日、日本で働く他の外国人と集まりに参加しました。私たちが経験を共有する中で、一つの共通テーマが浮かび上がりました。それは、多くの人が日本語のレベルが原因で日本人の同僚に誤解されたり、真剣に受け止められなかったりしているということです。彼らも時々アイデアをうまく伝えることができず、気まずい状況や、時には対立に発展することもあります。

しかし、個人的な意見では、これは日本の職場に特有の問題ではありません。私は、インド、ベトナム、メキシコ、スイス、イギリスなど、英語を共通言語として使うチームと仕事をしてきましたが、そこで同じようなコミュニケーションの問題が生じました。直面する課題は、主に次の4つの要素に根ざしていると思います。

* 言語の壁
* 文化の違い
* タイムゾーンの差異
* 視覚的な補助の欠如

## 言語の壁
言語を学ぶには時間がかかり、誰もが同じペースで習得できるわけではありません。何十年もその言語を話してきたネイティブの流暢さに到達する非ネイティブは稀です。話せない言語を考えてみてください。「バス停」などの言葉をすぐに思い浮かべられますか？きっと無理でしょう。使ったことがないので、調べたり学んだりしていないからだけです。

外国で働くなら、その国の言語を中級レベルまで習得することが重要だと私は思いますが、それでも語彙には常にギャップが生じます。しかし、語彙のギャップは知性のギャップと同じではありません。残念ながら、ネイティブスピーカーが外国人を語彙の限界だけで知能が低いかのように扱うのを見かけることもあります。

## 文化の違い
文化的な規範や仕事のスタイルは、国によって異なります。あるチームにとって当たり前の慣習が、別のチームにとっては全く異なることもあります。そのため、最初に明確な期待やルール、方針を設定することが重要です。文化の違いを乗り越えるには、口頭および書面でのコミュニケーションが鍵となります。

## タイムゾーンの差異
私の経験では、グローバルなチームで働くときには、異なるタイムゾーンを調整する必要があります。例えば、私が日本で午前9時から午後6時まで働いている間、メキシコの同僚はちょうど午後6時に仕事を始めます。このようなタイムゾーンのズレは、会議のスケジュール、タスクの割り当て、締め切りに影響を与えます。

このような状況では、誤解が生じやすいです。私の解決策は？視覚的な補助を使うことです。グラフィックドキュメントのような視覚的なツールは、非常に効果的です。まさに「一枚の絵は千の言葉に値する」のです。

## ビジュアル補助の力
口頭でのコミュニケーションがうまくいかないとき、視覚的な補助は大きな効果を発揮します。このアプローチを発明したわけではなく、How to Communicate Effectively（効果的なコミュニケーションの方法）、Emotional Intelligence（感情知能）、User Story Mapping（ユーザーストーリーマッピング）などの書籍に基づいています。

## 具体例
さて、このような問題は次のようなものかもしれない：
### 進展のない長いミーティング
* 問題が発生します
* チームメンバーA（ネイティブ）がそれを説明しようとします
* チームメンバーB（非ネイティブ）が誤解したり、誤って対応します

無駄な議論が何時間も続き、他のメンバーも巻き込まれそう。

または、
### 言葉だけのコミュニケーションで、期待されない結果に終わる
* チームメンバーAが修正依頼を出す
* チームメンバーBは理解したつもりですが、成果物は期待にそぐわないこともあります

いずれの場合でも、言葉だけに頼ること、効果的ではありません。
## コメント
毎回正式な文書を作成する必要があると言っているのではありません。ホワイトボード、手書きのメモ、スクリーンショットのようなシンプルなツールでも、アイデアを明確にし、全員が同じページにいることを確認することができます。

![example 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3801563/2883b2d2-1597-dcbb-fc29-8c023eba8545.png)

私は、ビジュアルな補助を使うようになってから、コミュニケーションの問題が少なくなりましたと思います。YUZURIHAでは、このアプローチを受け入れてくれる忍耐強く理解あるチームメンバーと一緒に働くことができて幸運です。

最後まで読んでいただき、ありがとうございました！皆さんの職場でのコミュニケーションの課題や、その解決策についてぜひお聞かせください。また、YUZURIHAのメンバーたちが書いた記事もぜひご覧ください。
behaviour treesの可視化ツールpy_trees_ros_viewerをROS-humble のインストールする方法

# behaviour treesの可視化ツールpy_trees_ros_viewerをROS-humble のインストールする方法

最近 behaviour treesのお勉強を始めたところで、技術とbehaviour treesとは何？今回は省略します。原因は自分まだ勉強中なので、間違ってる知識をアップロードしていけないと思いました。

それで勉強の途中でbehaviour treesの状態をリアルタイムで可視化できれば、勉強の理解しやすくなるではと思って調べたら、py_trees_ros_viewerのgithub リンク: 

https://github.com/splintered-reality/py_trees_ros_viewer

やり方の説明はあった。以下のコマンドです。
```
sudo apt install ros-<rosdistro>-py-trees-ros-tutorials
# In a first shell
py-trees-tree-viewer
# In a second shell
ros2 launch py_trees_ros_tutorials tutorial_eight_dynamic_application_laoding_launch.py
# Click 'Scan' on the qt robot dashboard interface
# Wear a colander, I am too.
```

# なぜかROS2のhumbleにインストールできなかった。
それでIssuesを見たら解決の方法を発見して、その方法今回を投稿することにしました。以下はコマンドです

```
sudo apt-get install libqt5webengine5 libqt5webenginewidgets5 python3-pyqt5.qtwebengine
```
```
pip install pyqtwebengine
```
```
cd 
```
```
git clone https://github.com/splintered-reality/py_trees_js.git
```
```
cd  py_trees_js
```
```
colcon build --symlink-install
```
```
cd 
```
```
git clone https://github.com/splintered-reality/py_trees_ros_viewer.git
```
```
cd py_trees_ros_viewer
```
```
colcon build --symlink-install
```
New terminal
```
py-trees-tree-viewer --no-sandbox
```

まだ色々勉強しているので、もし何かアドバイスやご指摘があれば、ぜひ教えてください！これからも頑張って勉強しますので、どうぞよろしくお願いします。
海外SIMカードの選び方：旅行中の通信を最適化するためのガイド

海外旅行はわくわくする冒険ですが、旅行中に通信を確保するのは一筋縄ではいきません。そんなときに便利でコストを抑えられる方法の一つが「海外SIMカード」の利用です。しかし、旅行のために最適なSIMカードを選ぶことは、さまざまな選択肢や機能があるため、時には困難に感じるかもしれません。このガイドでは、旅行中の円滑な通信を実現するために、海外SIMカードを選ぶ際に考慮すべき重要なポイントについてご紹介します。

## 海外SIMカードとは？
海外SIMカードとは、世界中のさまざまな国で使用できるモバイル通信カードです。このカードを使用することで、旅行先でのローミング料金を節約でき、地元のキャリアと同じように通信が可能になります。また、プリペイドプランやデータ専用プランなど、旅行者のニーズに合わせたさまざまなプランが提供されています。

### 海外SIMカードのメリット
海外SIMカードの最大のメリットは、通信コストを抑えられる点です。多くの通信会社では、海外ローミングに高額な料金を設定していますが、海外SIMカードを利用すれば、現地の通信会社の料金で利用できるため、かなりの節約になります。また、事前にプランを選ぶことで、予期しない高額請求を防ぐことができます。

## 選ぶ際の考慮点
### 対応国とネットワーク
まず、選ぶSIMカードが旅行先の国で利用可能か確認する必要があります。多くの国に対応したグローバルSIMカードもあれば、特定の地域や国に特化したものもあります。自分の旅行プランに合ったカードを選ぶことが重要です。また、カードが使用するネットワークが信頼性の高いものであるかも確認しましょう。海外SIMカードで旅先でも安心！[インターナショナルSIMカードでチェックしてみてください](https://internationalsimcard.com.au/)。

### データプランと使用量
次に、どれくらいのデータ通信量が必要かを考えます。動画のストリーミングや頻繁なネット検索をする場合、大容量データプランを選ぶことが推奨されます。一方、基本的な連絡手段として使うだけであれば、少量のデータで十分です。プランを選ぶ際は、自分の使用パターンに合わせて最適なものを選びましょう。

### 海外SIMカードの設定方法
海外SIMカードを使用するためには、設定が必要です。カードを挿入した後、通常は現地のネットワークに自動的に接続されますが、場合によっては手動で設定する必要があります。設定は簡単で、多くのカードには専用のアプリやウェブサイトでのガイドが付属しています。

## 使用前に確認するべきこと
カードの設定を行う前に、まず自分の端末が海外SIMカードに対応しているか確認してください。また、ロックが解除されているかも重要なポイントです。ロックがかかっている場合、その国や地域のネットワークに接続できない可能性があります。アメリカへのご旅行をご予定ですか？[出発前にUSA SIMカードをチェックしてください](https://internationalsimcard.com.au/usa-sim-card/)。

海外旅行での通信手段として、海外SIMカードは非常に便利で経済的な選択肢です。ただし、選ぶ際には、対応国、データプラン、ネットワークの信頼性など、いくつかの要素を考慮する必要があります。これらのポイントを理解し、適切なカードを選ぶことで、旅行中も安心して通信が可能になります。
RLC直列回路のステップ応答と二次遅れ系について

# はじめに
RLC直列回路は、典型的な二次遅れ系の回路設定モデルであるといえる。そこで、その応答性を評価するために正の時間に一定のパルス電圧を入力するステップ応答の評価を行うことは意義があるといえる。しかし、古典制御ではその応答性を評価する場合、微分方程式をラプラス変換を用いて伝達関数に変換して評価してあげる必要性がある。ところが、微分方程式を状態方程式に変換して行列演算を行う現代制御では、ラプラス変換が不要になる場合がある。今回は、入力電圧にステップパルスを用いてコンデンサに蓄えられる電荷の応答性を調査することで、ステップ応答がどの様になるのかを調査する。また、RLCの各パラメーターと減衰係数、固有角速度$\zeta,\omega_n$との関係性も調査する。

![RLC_状態方程式_電流_ステップ応答電圧.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/7ce55b66-77e3-d076-9302-180055a4535c.png)

# 導入
## アルゴリズム
RLC回路の微分方程式を解くアルゴリズムやプログラム等の情報は以下の記事を参考にした。

https://qiita.com/arairuca/items/54923ed3be68334f8d88

## 相違点
異なる点について2つ程あるので述べる。


(1)入力電圧はステップパルスを使用した。つまり、

$t\ge0$のとき

```math
E(t) = E
```
ただし$E$は定数とする。

$t<0 $のとき

```math
E(t) = 0
```

で表される電圧入力を使用した。

(2)$RLC$回路の素子のパラメータと減衰係数、固有角速度$\zeta,\omega_n$の関係式を導出する。

https://www2-kawakami.ct.osakafu-u.ac.jp/omu-content/uploads/sites/1161/Lecture_Data/Electric_Circuit_II/01_Lecture/18_lecture_electric_circuit_II.pdf

より、


```math
\zeta=\frac{R\sqrt{C}}{2\sqrt{L}},\omega_n=\sqrt{\frac{1}{LC}}
```

となる。これより、

```math
C=\frac{\zeta}{R \omega_n}
```

```math
L=(\frac{1}{\omega_n \sqrt{C}})^2
```

と、減衰係数、固有角速度$\zeta,\omega_n$を用いて$L,C$を$R$の式で表すことができる。

# プログラム

したがって以下の様なプログラムを作成した。

```　python RLC_step.py
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
import math
# 微分方程式:V =R Q'*L Q''+Q/C
#パラメータ
jita= 0.2  # 減衰係数
omega_n=4 # 固有角周波数

R = 10  # 抵抗値
C = (jita)**0.5/(R*omega_n)   # 静電容量
L =   (1/(omega_n*(C**0.5)))**2  # インダクタンス
e=100  # 入力電圧

#初期条件 （電荷と電荷の微分量つまり電流について）
x=np.array([0,0])
#初期時間
t=-0.01
#時間と状態量（ここでは電荷と電荷の微分量）
time_ary=[]
X=[]
#微小時間の時間間隔(小さくするほど精度は上がるが計算時間が比例して増大する)
delta_t=0.001
while(t<10):
    #入力電圧
    #E=np.sin(2*math.pi*50*t)
    if t>=0:
        E=e
    else:
        E=0    
    v=np.array([[0, 1], [-1/(L*C),-R/L]])@x+np.array([0,1/L])*E
    #位置の微小変化
    x=x+v*delta_t
    #print(v)
    #演算結果を記録
    time_ary.append(t)
    X.append(x[0])
    #時間の更新
    t=t+delta_t
plt.xlabel("応答時間[s]")
plt.ylabel("電荷[C]")
plt.title("Cに蓄まる電荷のステップ応答")
plt.plot(time_ary,X)
#グラフを保存する
plt.savefig("RLC_状態方程式_電流_ステップ応答電圧.png")
#グラフの表示
plt.show()
```
これを実行すると以下のようになる。

![RLC_状態方程式_電流_ステップ応答電圧.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/7ce55b66-77e3-d076-9302-180055a4535c.png)

このように、入力電圧であるステップパルスに対して追従するようにコンデンサの電荷量が変化する。
また、$\zeta=0.2$程度では、応答波形は振動しながら減衰した。

# まとめ
今回は、差分法を用いた二次遅れ系のステップ応答についてシミュレーションを行った。実際に、ラプラス変換をプログラムで再現しようとすると複雑かつ積分の計算時間が膨大になる恐れがあることから、微分方程式を行列計算に変換する方法（現代制御による状態方程式）を行った。二次遅れ系では減衰係数が0から1の間では振動しながら減衰することが知られていたので、その検証もシミュレーション結果よりすることができた。
【CSS】CSS設計論を勉強

# はじめに
CSS設計論について勉強したことの備忘録を兼ねてまとめました。

# CSS設計の必要性
CSSでは、同じ結果に対していろんな書き方があるので、後々の運用コストを下げるためにしっかりとした設計が重要

# BEM
## 概要
BEMという考え方に基づいたCSS設計がある。BEMは、Block, Element, Modifier の頭文字をとったもの。ルールが割としっかり目に決まっている。クラス名の記法は、公式ではケバブケース（アルファベット小文字を、`-`でつなぐ）。キャメルケースもよく使われる。また、ルール衝突（クラス名の重複）回避のために下記のような接頭辞をつける方が良い。
- プロジェクト名
`myproject-...` など
- ルールのカテゴリ
Blockの`b-`、Layoutの`l-` など
- 使われている画面
`top-...`、`products-...`、`company-...` など
- 機能名
## Block
### 概要
画面をBlockの集まりとみなす。Blockとは、HTMLとCSSをセットにして考えたもの。コンポーネントとも呼ばれる。論理的、機能的に独立したページ内の一部品といえる。
### 粒度
- Blockをどのように再利用するか
- CSSが大きくなりすぎないか
などによって粒度を決める。
### クラス名の決め方
Blockの一番外側の要素にそのBlockを表す名前をつける。
```html:例（ニュース欄をひとつのBlockとみなした場合）
<div class="news-column">...</div>
```

## Element
### 概要
Blockの構成要素。次の利用方法はNG。
- あるBlock内のElementを別のBlockで使うこと
- Elementの中にElementを入れること
### クラス名の決め方
`Block名__Element名`（`_`は２つ。）
### メリットとデメリット
#### メリット
- スタイルの衝突を防ぐ
- HTMLから設計構造が見える
- CSSのセレクタが単純になる
#### デメリット
- クラス名が長ったらしい

## Modifier
### 概要
BlockやElementに、少し違ったバリエーション（ちょっとした変化）をもたせるもの。
### クラス名の決め方
- `Block名_Modifier名_値`
- `Block名__Element名_Modifier名_値`
- 省略記法
    - `Block名--値`
    - `Block名__Element名--値`
省略記法がよく使われる。
例 | `message_type_success`であれば、`message--success`

# SMACSS
## 概要
SMACSSというCSS設計法もある。次の５つのルールからなる。
- Base
- Layout
- Module（BEMでいうところのBlock）
- State（BEMでいうところのModifier）
- Theme
## Base
土台となるルール群。有名な`normalize.css`や`Reset CSS`に自分のルールを加えたもの。
## Layout
Blockをはめていくための枠組み部分。クラス名に`global-layout`などとつけて囲うことで実装する。
## Theme
ダークテーマなど、全タオをごっそり変えたいときに使う。ルートに近い要素にテーマ種別などを表すクラスを設定し、クラスを動的に変更することで実現する。例 | html要素などに`theme-dark`など

# ユーティリティクラス
## 概要
ちょっとした変更をするためのクラス。
```css:例
.align-left{ text-align: left; }
```
上記の他に`margin`など。使いたい部分にクラスを追加する。
## メリットとデメリット
### メリット
ちょっとした変更をどのBlockでも使える。
### デメリット
BEM的な設計を崩してしまう。従って、例外的な処理として使うこと。

# 余白
## 余白の位置
上と下のどちらに余白を取るか決めておいた方がいい。例えば、上だけ、や下だけ、など。
## 余白のバリエーション
`m-s`というクラスなら`10px`、`m-m`なら`20px`、`m-l`なら`30px`、などと設けておき、それらを使うと統一感が出る。
## どの要素に余白を設けるか
- 画面数が多い場合
シンプルにBlockに余白を設けた方が効率的
- 画面数が多くない場合
余白専用Blockを用意する、余白用のユーティリティクラスを用意する、などで柔軟性を持たせることができる。

# プロジェクトにおける進め方
ウォーターフォール的に自分の番が終わったらノータッチ、というのではなく、関わりの度合いを少しずつ変えていくというスタイルが良い。デザイナーの例でいえば、関わりの度合いが最初の工程は大きく、後工程になるほど漸減していくようなもの。

# スタイルガイド
## 概要
デザインやコードの記述方法などについてまとめた資料のこと。プロジェクトのコード品質維持、生産性の向上の役にたつ。コーディングルール、コンポーネントの一覧を先に決めておくことが重要となる。
## 公開されているもの
- Google HTML/CSS Style Guide
- Dropbox (S)CSS Style Guide
- Primer
## スタイルガイド作成支援ソフトウェア
- Storybook

# その他重要な概念など
- ビルド
- minify
- gulp
- Sass
- Autoprefixer
- PostCSS
- ユーティリティファースト

# 参考文献
ざっくりつかむCSS設計
高津戸 壮　氏　著
何を今更な 8ch 激安 ロジアナ が思いのほか使える

何の記事を読んでいたかはよく覚えていないけど「格安なロジアナ」という keyword が気になって調べてみると、…

>ワラワラ出てきました


よ。 こんなものがあったなんて知る由もありませんでしたよ勤めてないとなかなか情報は入ってきませんねえ。

安いものは ￥990.- とかでまあ ￥1,400.- あたりを中心に分布してて どうも中身は同じというか所謂パチもん感な製品。 software 的には Saleae Logic の 8ch に見える、らしい。 いろいろ調べてみると

　・ 動かなかった、とか
　・ いやあ良いですね、とか
　・ 動いたり動かなかったり、とか
　・ 開けて はんだ直した、とか

とか出てきますよさあどうしましょ ？　ww

まあ値段が値段なのでとりあえず確かそうな気配の amazon 業者のところでポチッ。


届きました。 中身は本体と入力の cable と usb cable だけ。

>ちっちぇえ


感。 いやまあ昨今で保護をケチれば十分に可能だことは分かりますけど、なんとも隔世の感です。

で、sigrok の site から soft を持ってきて、…

>何種類かあるように見えるんだけど ？


とか引っ掛かったり最初に usb driver を組まなきゃ（zadig.exe）なのを見落としてたりしましたけど無事に。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3729329/47f9fe73-917c-f21d-39d0-f6eed41da089.png)
<br>

こんな感じで出せるようになりました。 このあたりの情報は検索すれば出てくると思いますので後は端折ります。 protocol 解析は最初からかなり揃っていますこの本体で速度が追いつくか否かは別として。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3729329/edd15b35-c60a-f541-9321-e38a97542122.png)
<br>

とりあえず私は uart と i2c と spi が見られれは十分なので、というか 8ch でこの grade だと何を謳ってあったとしてもそれ以上を望んでも意味はないと思ってますし。 

上の例は logic level の rs232 ですが、解析する port(ch) は例えば i2c ですと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3729329/fd58c818-e81c-c7ce-d457-bf50bc758cb7.png)
<br>

な感じにするだけ。

特定の ch を使って記録開始の trigger とすることもでき、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3729329/305c8bb9-9cbb-0be1-45d3-f7323a543362.png)
<br>

容量の何 % かの指定ですが trigger 前から見ることができます。


私が手がけている Adafruit や TWELite や Arduino くらいですとこれで十分なので

>とても助かります


よ。 いやあ良い買いものでした。 で、とりあえず

>もひとつ買いました


よ、さらに安いやつ。 ww　ちゃんと動いてます。

<br>
今日は このくらいで。
VSCodeで簡単！ランダム文字列を自動生成する方法

### 目的
ダミーデータとして、ある程度の分量がある文字列が欲しい

### 方法
vscodeの拡張機能`vscode-random`を利用する

### vscode-randomとは
数字や、国など様々な形式でランダムの値を生成することができるvscodeの拡張機能です

#### インストール
vscodeのサイドパネルの拡張機能よりインストールすることができます
"random"などと入力すれば上の方に出てきます。
![](https://storage.googleapis.com/zenn-user-upload/bd4cf2e681ba-20220406.png)



#### 使い方
1. コマンドパレットを表示
- Macの場合 : Cmd+Shift+P
- Windowsの場合 : Ctrl+Shift+P

![](https://storage.googleapis.com/zenn-user-upload/dcdfc35321bf-20220406.png)



2. コマンドパレットへ`random`などと入力し、下に出てくる候補より`Random: letters(custom length)`を選択する
![](https://storage.googleapis.com/zenn-user-upload/5217f785c9d0-20220406.png)

3. コマンドパレットにて長さを入力する様に促されるため適当な長さを入力

![](https://storage.googleapis.com/zenn-user-upload/fc3b2629327f-20220406.png)
見やすいソースコードのために文字列を改行したかった話

# 横に長すぎるソースコード

先日、実務でC++を書いていたら、長い文字列を入力する必要がありました。
本当はリソースによけたりした方が良いのですが、まだプロトタイプということで直接書き下すことに。

```cpp
std::string str = "よだかは、実にみにくい鳥です。顔は、ところどころ、味噌をつけたようにまだらで、くちばしは、ひらたくて、耳までさけています。足は、まるでよぼよぼで、一間とも歩けません。ほかの鳥は、もう、よだかの顔を見ただけでも、いやになってしまうという工合でした。たとえば、ひばりも、あまり美しい鳥ではありませんが、よだかよりは、ずっと上だと思っていましたので、夕方など、よだかにあうと、さもさもいやそうに、しんねりと目をつぶりながら、首をそっ方へ向けるのでした。もっとちいさなおしゃべりの鳥などは、いつでもよだかのまっこうから悪口をしました。";
```

ちょっと~~最悪ですね~~長すぎますね。適当なところで区切ってみましょう。

# いらない要素が入ってしまったソースコード

エスケープシーケンスを用いて改行記号を無視してみます。
```cpp
std::string str = "\
    よだかは、実にみにくい鳥です。\
    顔は、ところどころ、味噌をつけたようにまだらで、\
    くちばしは、ひらたくて、耳までさけています。\
    足は、まるでよぼよぼで、一間とも歩けません。\
    ほかの鳥は、もう、よだかの顔を見ただけでも、\
    いやになってしまうという工合でした。\
    たとえば、ひばりも、あまり美しい鳥ではありませんが、\
    よだかよりは、ずっと上だと思っていましたので、\
    夕方など、よだかにあうと、さもさもいやそうに、\
    しんねりと目をつぶりながら、首をそっ方へ向けるのでした。\
    もっとちいさなおしゃべりの鳥などは、\
    いつでもよだかのまっこうから悪口をしました。\
    ";
```

お、一見つながりましたね。
しかし、変数 `str` の中を見ると `\t` (タブ文字) が入ってしまっています。
各行の最初にあるインデントがタブ文字として扱われてしまったんですね。
(多分インデントにスペースを使っている人はスペースが入ると思います。)

# 余計なものが入らない改行あり文字列

```cpp
std::string str =
    "よだかは、実にみにくい鳥です。"
    "顔は、ところどころ、味噌をつけたようにまだらで、"
    "くちばしは、ひらたくて、耳までさけています。"
    "足は、まるでよぼよぼで、一間とも歩けません。"
    "ほかの鳥は、もう、よだかの顔を見ただけでも、"
    "いやになってしまうという工合でした。"
    "たとえば、ひばりも、あまり美しい鳥ではありませんが、"
    "よだかよりは、ずっと上だと思っていましたので、"
    "夕方など、よだかにあうと、さもさもいやそうに、"
    "しんねりと目をつぶりながら、首をそっ方へ向けるのでした。"
    "もっとちいさなおしゃべりの鳥などは、"
    "いつでもよだかのまっこうから悪口をしました。";
```

この方法だと余計なものが入らず、改行した文字列を作成することができます。
タブ文字やスペースなどを無視して文字列を連結してくれるようです。
これなら、実行時間に影響なく人間の目にやさしいソースコードが書けそうです。

MSDNにも書いてあるんですね。今日まで知りませんでした。

https://learn.microsoft.com/ja-jp/cpp/c-language/string-literal-concatenation?view=msvc-170

>空白のみで区切られた 2 つの文字列リテラルとして初期化された文字列ポインターは、1 つの文字列として格納されます (ポインターについては、「ポインター宣言」で説明します)。 次の例のように適切に参照すると、結果は前の例と同じになります。
>```cpp
>char *string = "This is the first half of the string, "
>                "this is the second half";
>```


以上。

# 引用

* [青空文庫 『よだかの星』](https://www.aozora.gr.jp/cards/000081/card473.html)
Ubuntuで音声ファイルを再生する方法

# はじめに
　Ubuntuで音声ファイルを再生する方法を紹介する。同時再生する際に、いくつか設定変更が必要なのでで紹介する。

# 動作確認環境
* Ubuntu 20.04 x64/arm64
  * NVIDIA Jetson JetPack 5.1.1 

# 方法
　ターミナルから```aplay```コマンドで音声ファイルを指定することで再生可能。コマンドが見つからない場合は以下でインストールする。

```bash
sudo apt update
sudo apt install alsa-base
```

## デバイスの確認

```bash
aplay -l
```

結果例
```
**** ハードウェアデバイス PLAYBACK のリスト ****
カード 0: PCH [HDA Intel PCH], デバイス 0: ALC3234 Analog [ALC3234 Analog]
  サブデバイス: 1/1
  サブデバイス #0: subdevice #0
カード 1: NVidia [HDA NVidia], デバイス 3: HDMI 0 [HDMI 0]
  サブデバイス: 1/1
  サブデバイス #0: subdevice #0
カード 2: NVidia_1 [HDA NVidia], デバイス 3: HDMI 0 [HDMI 0]
  サブデバイス: 1/1
  サブデバイス #0: subdevice #0
カード 3: UACDemoV10 [UACDemoV1.0], デバイス 0: USB Audio [USB Audio]
  サブデバイス: 1/1
  サブデバイス #0: subdevice #0
```

表示されている、カードNoとデバイスNoで音声デバイスを特定することができる。

## 音声ファイルの再生

例： カードNo=3、デバイスNo=0のデバイスで再生する場合
```bash
aplay --device="hw:3,0" {wav_file_path}
```
* --device
    * 音声デバイスの指定 (```hw:{card},{device}```)
      * ```hw:```の後ろに、```カードNo```,```デバイスNo```
      * ```hw```の前に、```plug```をつけることも可能
          * 下記警告が出る場合は、plugも付ける
              * ```警告: レートが不正確です (要求値 = 44100Hz, 使用値 = 48000Hz)```
    * 【推奨】PulseAudiooデバイスの指定(```default```)
      * ```default```とすると、PulseAudioのデフォルトデバイス経由となり複数のアプリから同時再生可能となる
* {wav_file_path}
  * 任意のWAVファイルパス  

### PulseAudioのデフォルトデバイスの変更方法

ALSAの設定ファイルを修正する。
```bash
sudo vi /usr/share/alsa/alsa.conf
```

ファイルの中身は以下のようになっている。
```bash
#
# defaults
#

# show all name hints also for definitions without hint {} section
defaults.namehint.showall on
# show just basic name hints
defaults.namehint.basic on
# show extended name hints
defaults.namehint.extended on
#
defaults.ctl.card 0
defaults.pcm.card 0
defaults.pcm.device 0
defaults.pcm.subdevice -1
defaults.pcm.nonblock 1
...
```

上記中のデフォルトカードNoとデバイスNoを、```aplay -l```で出てくるカード番号とデバイス番号に書き換える。

例：カードNo=3、デバイスNo=0の場合
```
defaults.ctl.card 3
defaults.pcm.card 3
defaults.pcm.device 0
defaults.pcm.subdevice -1
```
保存して終了。再起動などは不要。

* 参考
    * https://klee-arc.hatenablog.com/entry/2016/12/21/235809


### 音声ファイル再生のトラブルシューティング
#### aplay: set_params:1374: チャネル数が使用不可能

##### 対策

--deviceに```plug```を入れる。

* 例
    ```bash
    aplay --device="plughw:3,0" {wav_file_path}
    ```

#### aplay: main:852: オーディオオープンエラー デバイスもしくはリソースがビジー状態です

##### 原因: デバイス指定が誤っている場合

###### 対策

　deviceの設定が、文字列になっているかを確認する（--device="hw:x,x"　になっているか確認）。

##### 原因：他のデバイスが利用している場合

##### 対策

　デバイスを直接指定しない(hw:を利用しない)で、PulseAudio経由にする(```--device=default```を指定)。詳細は[この記事](https://qiita.com/propella/items/4699eda71cd742cba8d3)を参照。

* 例
    ```bash
    aplay --device=default {wav_file_path}
    ```

# まとめ
　Ubuntuで音声ファイルを再生する方法を紹介した。複数アプリから同時再生する際には、デバイス指定をPulseAudioにすることで同時再生可能となる。

# 参考

https://qiita.com/propella/items/4699eda71cd742cba8d3

https://klee-arc.hatenablog.com/entry/2016/12/21/235809

https://www.zinbloger.com/2021/11/raspberrypi-linux-music/
Arduino UNO 3、Grove - OLED Display 1.12で遊ぶ






参考

![o_coq423.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b566c61e-d3e9-9629-1e44-4b43a7693747.jpeg)


https://wiki.seeedstudio.com/Grove-OLED_Display_1.12inch/


結果

![o_coq424.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/26aee019-60a3-e391-3a7d-40220ae47618.jpeg)


プログラム


```c++


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

U8G2_SSD1327_SEEED_96X96_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);  // Seeedstudio Grove OLED 96x96

void setup(void) {
  u8g2.begin();
}

void loop(void) {
  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_ncenB10_tr);
    u8g2.drawStr(0,24,"Hello World!");
  } while ( u8g2.nextPage() );
}


```
Progateのreact学習メモ

vue.jsは普段触っているが、
reactの基礎中の基礎もわからない状態で
reactを触る。

学習のさわりとして、
progateで勉強したことのメモ。

# renderメソッドの、returnの直近におけるタグは１つのみ

❌ NG
```react:App.js
render(){
    return(
        <h1>複数の</h1>
        <h1>要素があると</h1>
        <p>ダメ</p>        
    );
}
```

↓

⭕️ OK

```react:App.js
render(){
    return(
        <div>
            <h1>一番外にある</h1>
            <h1>タグが1つだと</h1>
            <p>OK</p>  
        </div>
    );
}
```


# コメントの仕方
```react:App.js
render(){
    return(
        <div>
            {/* コメント　*/}
        </div>
    );
}
```

# 基本構成

ファイル構成
↓ ここは人によってかなり異なる
```
react-file/
　├ src/
　│　└ index.js
　│　└ components/
　│　　　└ App.js
　└ index.html
 ```
```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <title>React App</title>
  </head>
  <body>
    <!-- ↓① のタグにidをつける -->
    <div id="root"></div>
    <script src="bundle.js"></script>    
  </body>
</html>
```


 
 ```react:index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';

//　⭐️ ② ①のidのタグに、<App />（③で説明）コンポーネントを表示させる
ReactDOM.render(<App />, document.getElementById('root'));
```

 
 ```react:App.js
import React from 'react'
// ③ class App とした場合は、<App />となるし、
// class Hoge とした場合は、<Hoge />となる
class App extends React.Component{
    render(){
        return(
            {/* ここにJSXを書く */}
        )
    }
}
export default App;
```


# 変数を定義する
```react:App.js
import React from 'react';

class App extends React.Component {
  render() {
    const hoge ='⭐️returnの外で定義する';
    return (
      <div>
        <h1>{hoge}</h1>
      </div>
    );
  }
}

export default App;
```


# 感想
まだ基礎中の基礎だが、progateはとっつきやすいように教えてくれる。
雰囲気は掴めたので、次は実際にローカルで動かしてやっていく〜
C++備忘録① cout>>" \n"[a==i-1];

cout>>" \n"[a==i-1];
このような構文を考えていきます。
上の文をif構文で書くと、
if(a==i-1)
{
cout>>"\n";
}
else 
{
cout>>" ";
}
となります。
例えば、数字の間に","を入れたいけど、最後の部分だけ改行にしたい！というときなどに役立ちます
以下例文コード
#include <iostream>
using namespace std;
int main() {
    for(int i=0;i<10;i++){
        cout<<i<<",\n"[i==9];
    }
}
出力結果　
0,1,2,3,4,5,6,7,8,9

ちなみに、以下のような書き方では使えません
#include <iostream>
using namespace std;
int main() {
    for(int i=0;i<10;i++){
        cout<<i",\n"[i==9];
    }
}
↑はエラーになる
#include <iostream>
using namespace std;
int main() {
    for(int i=0;i<10;i++){
        cout<<"ab\n"[i==9];
    }
}
↑の場合は出力がaaaaaaaaabとなり、\nが使用されない
つまり、この構文は2文字の判別にしか使えません。
たまに使うので備忘録として残しておきます。
【Ruby】予約語一覧

以下は予約語です。予約語は原則、変数名やクラス名として使用できません。

```
BEGIN    class    ensure   nil      self     when
END      def      false    not      super    while
alias    defined? for      or       then     yield
and      do       if       redo     true     __LINE__
begin    else     in       rescue   undef    __FILE__
break    elsif    module   retry    unless   __ENCODING__
case     end      next     return   until
```

https://docs.ruby-lang.org/ja/latest/doc/spec=2flexical.html
忘れた頃のSQLリファレンス[STRING_AGG()]

## はじめに
複数レコードを１レコードにまとめたいときって、業務上たまにあると思います。

例えば、ユーザーと保有権限についてファイルを出力する時、商品タグを取得する時など。
ほんと数年に1回ぐらい・・・

そういう時、STRING_AGG()を使うと楽にできるので、備忘録代わりに残しておきます。

https://learn.microsoft.com/ja-jp/sql/t-sql/functions/string-agg-transact-sql?view=sql-server-ver16

## STRING_AGG()の使用例
### カンマ区切りで出力する
以下のようにusersとpermissionsの2つのテーブルを結合して、
permissions.permission_nameをカンマ区切りで取得する。
```sql:sql1 : 権限をカンマでつなげる
SELECT
	users
	.userid
	,users.name
	,STRING_AGG(permissions.permission_name, ',') AS permissions
FROM
	(VALUES (1,'Taro'),(2,'Jiro'),(3,'Hiroshi')
	) as users(userid,name)
INNER JOIN
	(VALUES (1,'参照権限'),(1,'編集権限'),(2,'参照権限')
	) as permissions(userid,permission_name) ON users.userid = permissions.userid
GROUP BY users.userid,users.name
```

```
userid      name    permissions
----------- ------- -----------------
1           Taro    参照権限,編集権限
2           Jiro    参照権限

(2 行処理されました)
```
### ソートする
`WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )`をつけることでソートする。
```sql:sql2 : sql1の権限を逆に並べてカンマでつなげる
SELECT
	users
	.userid
	,users.name
	,STRING_AGG(ISNULL(permissions.permission_name,'なし'), ',')
		WITHIN GROUP (ORDER BY permission_name DESC) AS permissions
FROM
	(VALUES (1,'Taro'),(2,'Jiro'),(3,'Hiroshi')
	) as users(userid,name)
INNER JOIN
	(VALUES (1,'参照権限'),(1,'編集権限'),(2,'参照権限')
	) as permissions(userid,permission_name) ON users.userid = permissions.userid
GROUP BY users.userid,users.name
```
```
userid      name    permissions
----------- ------- -----------------
1           Taro    編集権限,参照権限
2           Jiro    参照権限

(2 行処理されました)
```


### NULLを置換する
NULLを置換することもできます。
```sql:sql2 : sql1で権限のないuserid=3を外部結合で取得する
SELECT
	users
	.userid
	,users.name
	,STRING_AGG(ISNULL(permissions.permission_name,'なし'), ',') AS permissions
FROM
	(VALUES (1,'Taro'),(2,'Jiro'),(3,'Hiroshi')
	) as users(userid,name)
LEFT JOIN
	(VALUES (1,'参照権限'),(1,'編集権限'),(2,'参照権限')
	) as permissions(userid,permission_name) ON users.userid = permissions.userid
GROUP BY users.userid,users.name
```
```
userid      name    permissions
----------- ------- -----------------
1           Taro    参照権限,編集権限
2           Jiro    参照権限
3           Hiroshi なし

(3 行処理されました)
```

## おわりに
SQLServerならそのままコピペしても動くように書きました。
必要に応じてテーブルを書き換えてつかってください。
Google Nest Miniを喋らせる

# はじめに
- 我が家にGoogle Homeが4台ほどあるので活用したいので、とりあえずやってみる

# 結論ファースト
できた。

```Python
import pychromecast
from gtts import gTTS
import io
import base64

# テキストを音声に変換
message = "昔々、あるところにおじいさんとおばあさんがほにゃらら"
tts = gTTS(message, lang='ja')

# 音声をバイトストリームとして保存
audio_stream = io.BytesIO()
tts.write_to_fp(audio_stream)
audio_stream.seek(0)

# Google Nest Homeを探す
chromecasts, browser = pychromecast.get_chromecasts()
# とりあえず名前で探す
cast = next((cc for cc in chromecasts if cc.name == "1階Nest"), None)

if cast:
    cast.wait()
    mc = cast.media_controller
    
    # 音声データをメモリ上で再生    
    mc.play_media("data:audio/mp3;base64," + base64.b64encode(audio_stream.getvalue()).decode(), 'audio/mp3')
    mc.block_until_active()
else:
    print("1階Nestという名前のデバイスが見つかりません")    
```

# 備考
- 文字列を音声ファイルにしたものをアップロードして、その音声ファイルのURLを関数に渡すやり方があるみたいだけど、今回はストリームでやってるのがポイントです。
変更履歴なしのWord文書に一括で変更履歴を付ける方法

仕事でWord文書を作成する際、依頼主から **変更履歴付きで提出** するよう指示される場合が時々あります。しかし、以下の場合に不都合が生じます。

* 何度も書き直す場合：書いては消し、また書いては消し、を繰り返すと、変更履歴が複雑になり読みにくい
* 複数名で更新する場合：変更履歴が更新者別に異なる色で表示されるため、色の数が多くなり読みにくい

いずれの場合も、編集中は変更履歴を非表示にしておけば問題ありません。しかし、そのまま提出すると **提出先の方に対して失礼** になってしまうため、結局、最終版の完成後に **全ての変更を改めて初期版の文書に書き込む** という作業が必要な場合も多いです（もちろん、誰がどこをどのように更新したかが分かるようにするよう指示されている場合はこの限りではありません）。これがかなり面倒です。

そこで、変更履歴なしでWord文書を作成した後で、一括で変更履歴を付ける方法を紹介します。

# 用意するもの

* 初期版のWord文書
* 最終版のWord文書

とりあえず、Copilotに適当に作らせた以下の「サンプル文書1」と「サンプル文書2」をそれぞれ初期版と最終版と見なして説明します。

サンプル文書1
![fig1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2787764/bf66209a-cd81-492d-9a9a-9e99a8ceab89.png)

サンプル文書2
![fig2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2787764/e63ffd41-d4db-366d-6720-413d6172fb88.png)

# Step 1. 「校閲」タブから「比較」を選択

画面上部のメニューから「校閲」を選び、右の方の「比較」を押して、さらに出てきた選択肢のうち「比較」の方を押します。

![fig3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2787764/4f4674dc-06cb-3046-aecd-d45d72b56e77.png)

# Step 2. 「元の文書」と「変更された文書」に初期版と最終版を指定してOKを押す

以下のようなウィンドウが出てくるので、左の「元の文書」に初期版のファイル、右の「変更された文書」に最終版のファイルを指定し、OKボタンを押します。ファイルの指定は、それぞれの欄の右にあるフォルダのアイコンをクリックして、出てきたウィンドウ内で該当ファイルを選択すると出来ます。

![fig4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2787764/93c7b24d-6535-9fde-51e8-1b6e3f160fb9.png)

# Step 3. 出てきた比較結果を別名でファイルに保存

以下のような画面が出てきます。ここで重要なポイントがあります。この状態で **別名でファイルに保存** してしまって下さい。これでは提出できないと心配になりますが、大丈夫です。

![fig5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2787764/b72ab88f-2604-cdf6-1140-5915d9a5f23a.png)

# Step 4. 一旦Wordを閉じる

一旦Wordを閉じて下さい。

# Step 5. 改めて保存した比較結果のファイルを開く

改めて保存した比較結果のファイルを開くと、普段よく見る変更履歴付きの文書が出来上がっています。

![fig6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2787764/98776a3e-3aca-5c7d-f302-34c322fa1982.png)

# 補足

実はStep 3で、左や右にある各ウィンドウの **右上にあるバツ印** を押してしまってもStep 5と同じ状態になります。ただし、これをやると、次に文書の比較をした際に各ウィンドウが出てこない場合があり、慌てることになります。その場合は **[変更履歴]ウィンドウ** から再表示可能ですが、上で説明した手順の方が安全ではないかと思います。

ここで紹介した方法はあくまで私の環境のみで動作確認したものです。OSやOfficeのバージョンによって画面表示や応答が違うかもしれません。
optimal_bvmap の std/style.json で使われている色のリストを作る

optimal_bvmap の std/style.json で使われている色のリストを作るには、次のようにすればよかった。

```bash
curl -s https://gsi-cyberjapan.github.io/optimal_bvmap/style/std.json | jq '[.. | select(type == "string" and (. | test("^rgba\\("))) | .] | unique'
[
  "rgba(0,0,0,0)",
  "rgba(0,0,0,1)",
  "rgba(0,0,255,1)",
  "rgba(0,155,191,1)",
  "rgba(100,0,0,1)",
  "rgba(100,100,100,0.5)",
  "rgba(100,100,100,1)",
  "rgba(100,195,115,0.5)",
  "rgba(100,195,115,1)",
  "rgba(150,150,150,1)",
  "rgba(173,173,173,1)",
  "rgba(175,74,24,1)",
  "rgba(19,97,69,1)",
  "rgba(190,210,255,1)",
  "rgba(20,90,255,1)",
  "rgba(200, 160, 60,1)",
  "rgba(200,160,60,1)",
  "rgba(200,200,200,1)",
  "rgba(200,250,230,1)",
  "rgba(217,217,217,1)",
  "rgba(231,39,65,1)",
  "rgba(235,130,120,0.5)",
  "rgba(235,130,120,1)",
  "rgba(235,242,235,1)",
  "rgba(255,119,51,1)",
  "rgba(255,135,75,1)",
  "rgba(255,187,153,1)",
  "rgba(255,230,190,1)",
  "rgba(255,255,0,0.5)",
  "rgba(255,255,0,1)",
  "rgba(255,255,255,1)",
  "rgba(34,24,21,1)",
  "rgba(50,50,50,1)",
  "rgba(60,50,181,1)",
  "rgba(68,0,128,1)",
  "rgba(80,80,80,1)",
  "rgba(81,29,10,1)",
  "rgba(96,25,134,1)"
]
```
git 内部の仕組みを見ての学び

## 背景
誤ってdevelopにまだレビュー前のコードをコミットした。
その際、下記を行った。
`git reset --hard　コミットハッシュ`
しかし、コミットハッシュを指定して、developブランチが元に戻る、とは何が起きているのか？？と疑問が生じたため、gitの深いところが理解したくなった。


追記：featureにcheckoutしている状態で誤）のコードを実行したことにより、
featureにdevelopをマージするつもりが、
developにfeatureがマージされてしまった。
なぜ（誤）のコードで上記が起きたのかは理由がわからない。
```git
正）git push origin develop
↓
誤）git push develop
```

## 目的
今まで雰囲気で使用していたgitを、より何が起きているか理解し、コマンドをより安心して使用できるようにしたい。

## 本文
- gitには2つが存在する
    - gitオブジェクト：blob,tree,commit,tag
        - gitオブジェクトはイミュータブルで追加されていくのみ
    - リファレンス：branch,head,tag
        - ポストイットみたいなもので、ハッシュ値を参照する
- イメージ的には、非巡回グラフ（gitオブジェクト）が作成されて、ポストイット（リファレンス）がついている
- HEAD
    - 現在チェックアウトしているリファレンス（ブランチ）を指す
    - 現在さし示しているコミットオブジェクトが、VSCODEの左側のコードの状態と同じ。
- マージ
    - fast-forward：リファレンスが動くだけ
    - non-fast-forward：新しいコミットオブジェクトができてHEADもそこに動く。
- tag
    - 軽量タグ：ハッシュ値のみ
    - アノテートタグ：ハッシュ値＋情報

## 学び
ブランチやHEADの理解がふんわりしていたがかなり明確になった。


## 次のステップ
gitを操作していく中で、上記を意識しながら操作する。
mergeやrebaseなどの動きもイメージできるように、再学習をする。

今回学習した動画
https://www.youtube.com/watch?v=eOLuvsRgBCo