OmniAICreator/Qiita-1.07M huggingface dataset:
typescript uuid桁数を短くする

uuid桁数はbase64エンコードで32桁→22桁に減らすことができます！
（typescriptでの書き方が分からず苦戦したのでメモしておきます）

id生成ライブラリは[uuidv4](https://www.npmjs.com/package/uuidv4)を使っています

```ts
const originId = uuidv4();
console.log(`変換前のuuid: ${originId}`);

// uuidを16進数に変換した配列
const hexArray: number[] = originId.split('-').join('').split('', 16)
    .map((hex: string) => parseInt(hex, 16));
            
const shortId = Buffer.from(hexArray).toString('base64').replace('==', '');
console.log(`base64で短縮: ${shortId}`);
```

このように桁数を削減することができました！！
```console
変換前のuuid: 5728e2ef-7c01-4d69-934d-197742bcfbff
base64で短縮: BQcCCA4CDg8HDAABBA0GCQ
```
今日のSed error:  unknown option to `s'

文字計数処理:ちょっとした処理の変化が、データにどう変化を与えるか。

https://qiita.com/kaizen_nagoya/items/dcf788f738065f61ab3c

でsedのスクリプトを利用している。

mac OSで編集し、dockerでファイル共有して実行していた。

```docker:bash
sed: file ../autosar.sed line 1: unknown option to `s'
```

という警告が出た。

sed scriptの改行をCR+LFにした。

エラーは出なくなった。

エラーになったときはLFだけで、次の行のsがオプションだと解釈されたのだろうか。

macOSとLinuxでファイル共有している現象の一つかもしれない。
WindowsとLinuxでファイル共有している時にも類似の現象があるかもしれない。

# 参考資料

下記作業の一環です。

AUTOSAR R21-11(0) 仕様ダウンロード一覧。単語帳。参考文献資料作成

https://qiita.com/kaizen_nagoya/items/9b3a1b9b8d1e8d7e288e

特に、

AUTOSAR 21-11 (9) AP:Specification of Adaptive Platform Core, 新人にお勧めの基本動作(2), AUTOSAR(60)

https://qiita.com/kaizen_nagoya/items/0f024ee264e34e5298a3

で始めた１０文書の処理で起きたエラーです。

関連記述があるかもしれません。

# 文書履歴
ver .0.01 初稿 20220501
ver. 0.03 URL追記　20220503
[Github Actions] / nektos/act - upload-artifactsで困ったら

## 概要
ローカルホストランナーnektos/actは便利ですね。ただ、完全な互換性があるわけじゃないので、エラーでワークフローが止まってしまうのは困ってしまいます。

ここではｍそんな非互換性エラーあるあるの一つ`actions/upload-artifact`での回避する方法を。

## エラーメッセージ
```
[Playwright Tests/test]   ❗  ::error::Unable to get ACTIONS_RUNTIME_TOKEN env variable
[Playwright Tests/test]   ❌  Failure - actions/upload-artifact@v2
[Playwright Tests/test] exit with `FAILURE`: 1
```

## 対策
オプション `--artifact-server-path`を使います。
ただ、nektos/act公式でのほとんど記載がないので。。。

```
$ mkdir -p /tmp/act-artifacts 
$ act pull_request --artifact-server-path /tmp/act-artifacts
...
（中略）
...
| Artifact has been finalized. All files have been successfully uploaded!
| 
| The raw size of all the files that were specified for upload is 434264 bytes
| The size of all the files that were uploaded is 189238 bytes. This takes into account any gzip compression used to reduce the upload size, time and storage
| 
| Note: The size of downloaded zips can differ significantly from the reported size. For more information see: https://github.com/actions/upload-artifact#zipped-artifact-downloads 
| 
| Artifact playwright-report has been successfully uploaded!
[Playwright Tests/test]   ✅  Success - actions/upload-artifact@v3
```

設定したディレクトリを確認してみます
```
$ ls -la /tmp/act-artifacts
total 0
drwxr-xr-x  3 nagayaoh  wheel  96  5  1 21:13 .
drwxr-xr-x  3 nagayaoh  wheel  96  5  1 21:13 ..
drwxr-xr-x  3 nagayaoh  wheel  96  5  1 21:13 1/
```

Artifacts、こちらにできていますね。
```
$ ls -la /tmp/act-artifacts/1/
total 0
drwxr-xr-x  3 nagayaoh  wheel  96  5  1 21:13 .
drwxr-xr-x  3 nagayaoh  wheel  96  5  1 21:13 ..
drwxr-xr-x  3 nagayaoh  wheel  96  5  1 21:13 playwright-report
```

## 感想
`nektos/act` Actionsのデバッガだけじゃなくて、ローカルランナー(makeがわり)としても便利です。ただ、まだ情報が行き渡っていない感じですね。オプションをいろいろ調べれば、もっと気軽に使えそうですね。

## 参考
- [[nektos/act github] Issue: Cache service responded with 404 with actions/setup-node@v2 #1034](https://github.com/nektos/act/issues/1034)
- [[nektos/act github] READMe.md](https://github.com/nektos/act/blob/master/README.md)
【論文読み】ファジィニューラルネットワークによる建築設備の異常予兆監視

## はじめに

こんにちは。論文を読んだ結果の紹介記事です。  
今回紹介するのは、「ファジィニューラルネットワークによる建築設備の異常予兆監視」という論文です。  

- タイトル：ファジィニューラルネットワークによる建築設備の異常予兆監視
- 出典：鈴木雄介, et al.; 人工知能学会, 2019  
- URL：https://www.jstage.jst.go.jp/article/shasetaikai/2019.8/0/2019.8_157/_pdf/-char/ja  


## 概要
現状、定期点検などによる予防保全が主流である。
時系列データから、設備の正常データをファジィニューラルネットワーク(FNN)学習し、いつもと違う動きをオンラインで捉える。
次ステップとしてクラウド環境にAIエンジンを搭載し、複数の設備での適用性検証を進める。  

- ファジィ推論法・・・ファジィとはあいまいさや不正確さを取り扱う応用数学の体系のことで、この体系を通して現象を予想する方法。厳密な(一般の)集合では部分集合が全体集合に属すか属さないかを明確に区別するが、ファジィ集合では明確ではなく確率的に区別する。  
- ファジィ理論・・・真理値が真（１）と偽（０）の二値ではなく、１と０の間の任意の数で表わされる数学理論。人間の言語や推論にみられるようなあいまいさをもつ情報を扱うことができ、コンピュータや機械制御に応用される。あいまい理論。  


## 技術的特徴
- FNNを使用。非線形回帰。  
- 正常時のデータでモデル構築。実測値が、モデルによる幅を持つ予測の範囲内か、によって異常を判断。  
- 目的変数は、監視対象設備の故障モードに起因する変数を選定。  
- 説明変数は、目的変数と送還関係にあるものを選定。  
- 直近１カ月のデータでモデル作成  
- リニアに変化する異常の３パターン、急激に変化する異常の３パターン、で評価。（疑似データ）  
- 約1年半のデータでモデル作成し精度向上を判断。  

## 想定される適用例
- 時系列データでの異常検知全般


## 参考
- [ファジィニューラルネットワークによる建築設備の異常予兆監視](https://www.jstage.jst.go.jp/article/shasetaikai/2019.8/0/2019.8_157/_pdf/-char/ja)  
- [設備やプロセス・品質の異常を“予兆”段階でいち早く知らせる異常予兆検知システム](https://www.azbil.com/jp/corporate/technology/techne/techne17_s1.html)
[AtCoder]双方向辞書

# 双方向からアクセスできる辞書
辞書のvalueの検索は計算量がNかかるため、valueからも計算量1でアクセスできる辞書を作成しました。
使用は自由ですが、自分用なのでコードが汚いです。

# 実行環境
Pypy3(7.3.0)

# コード
~~~python
class WD():
  #keyからvalueもvalueからkeyも計算量1で
  #アクセスできる辞書
  #例 key:リンゴ,value:apple
  def __init__(self):
    self.Dict1 = {}
    self.Dict2 = {}
  def print(self):
    print("D1",self.Dict1)
    print("D2",self.Dict2)
  def set(self,value1,value2):
    #keyとvalueを入力(set(リンゴ,apple))
    self.Dict1[value1] = value2
    self.Dict2[value2] = value1
  def retvalue1(self,value1):
    #keyを入力するとvalue変換(retvalue1(リンゴ)→apple)
    return self.Dict1[value1]
  def retvalue2(self,value2):
    #valueを入力するとkey変換
    return self.Dict2[value2]
  def changevalue1(self,changed_value1,value2):
    #keyの方を変更したい時に、valueをもとに変更
    del self.Dict1[self.Dict2[value2]]
    self.Dict1[changed_value1] = value2
    self.Dict2[value2] = changed_value1
  def changevalue2(self,value1,changed_value2):
    #valueを変更したい時に、keyをもとに変更
    del self.Dict2[self.Dict1[value1]]
    self.Dict2[changed_value2] = value1
    self.Dict1[value1] = changed_value2
  def shiftvalue1(self,value1_1,value1_2):
    self.Dict2[self.Dict1[value1_1]],self.Dict2[self.Dict1[value1_2]] = self.Dict2[self.Dict1[value1_2]],self.Dict2[self.Dict1[value1_1]]
    self.Dict1[value1_1],self.Dict1[value1_2] = self.Dict1[value1_2],self.Dict1[value1_1]
  def shiftvalue2(self,value2_1,value2_2):
    self.Dict1[self.Dict2[value2_1]],self.Dict1[self.Dict2[value2_2]] = self.Dict1[self.Dict2[value2_2]],self.Dict1[self.Dict2[value2_1]]
    self.Dict2[value2_1],self.Dict2[value2_2] = self.Dict2[value2_2],self.Dict2[value2_1]
~~~

## 使用例1
~~~python
wd = WD()
wd.set("リンゴ","apple")
wd.set("みかん","orange")
wd.print()
#D1 {'リンゴ': 'apple', 'みかん': 'orange'}
#D2 {'apple': 'リンゴ', 'orange': 'みかん'}
print(wd.retvalue1("リンゴ"))
#apple
print(wd.retvalue2("orange"))
#みかん
wd.changevalue1("りんご","apple")
wd.changevalue2("みかん","Orange")
wd.print()
#D1 {'みかん': 'Orange', 'りんご': 'apple'}
D2 {'apple': 'りんご', 'Orange': 'みかん'}
~~~
一つのkeyに対し、一つのvalueが入ることを前提としています。
同様に一つのvalueに対し一つのkeyとなることを前提としています。

## 使用例2
~~~python
wd = WD()
wd.set(1,2)
wd.set(2,3)
wd.set(3,1)
wd.set(4,4)
wd.print()
#D1 {1: 2, 2: 3, 3: 1, 4: 4}
#D2 {2: 1, 3: 2, 1: 3, 4: 4}
~~~
[2,3,1,4]
のように、配列の場所と値のどちらからでもアクセスできるので便利です。
このとき、
D1は配列の値をkey、場所をvalueとします。
D2は配列の場所をvalue、値をkeyとします。

### shiftvalue1
~~~python
wd.shiftvalue1(1,2)
wd.print()
#D1 {1: 3, 2: 2, 3: 1, 4: 4}
#D2 {2: 2, 3: 1, 1: 3, 4: 4}
~~~
shiftvalue1を使うと、場所を参照し値を入れ替えます。
例としてwd.shiftvalue1(1,2)は1番目と2番目の値を入れ替えるため、
[3,2,1,4]となります。

### shiftvalue2
shiftvalue1を行う前の状態から実行します。
~~~python
wd.shiftvalue2(1,2)
wd.print()
#D1 {1: 1, 2: 3, 3: 2, 4: 4}
#D2 {2: 3, 3: 2, 1: 1, 4: 4}
~~~
wd.shiftvalue2(1,2)は、1と2の値の位置を入れ替えるため、
[1,2,3,4]となります。
[firebase]firebase deploy --only functionsでデプロイできない

# 概要
firebase cloudFunctionsをローカルで変更。
デプロイしようと`$ firebase deploy --only functions:hoge-func`
以下のエラーが出て一向にデプロイできない。

```bash
- Error Failed to update function hoge-func in region 
```

firebase落ちてるのではと思ったがそんなわけもなく。
https://status.cloud.google.com/summary

# 解決法
```bash
npm install [依存ライブラリ]
```

依存してるnode_modulesが入っていなかった。
フロントとfunctionsで共通のmoduleを使っていたため、functionから参照できていないとのこと。

しかもちゃんとエラー出ててた(上の方)。
`Did you list all required modules in the package.json dependencies?`


ログはざっと目を通した方が良い！
ファイル名にスペースがある画像をMarkdownで正しく挿入するには

# 結論
スペースが含まれるファイルを表示するには、
スペースを%20で置き換えます。
%20はスペースをURLエンコーディングしたものです。

# もう少し詳しく
Markdown形式で画像を挿入するには
```:画像を表示するときのフォーマットその１
![代替テキスト](画像のパス "画像タイトル")
```
あるいは
```:画像を表示するときのフォーマットその２
![代替テキスト](画像のパス)
```
という書き方をします。

試しにgithubのレポジトリに「test_image2.png」という画像をpushし、README.mdに以下のように書いてみます。
```:画像表示
![image](test_image2.png)
```
すると以下のように表示されます。

「test_image2.png」が表示される
|:--|
| ![2022-05-01 20_43_38-Window.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2049468/57d9ee8d-9836-f143-5513-4fdb008e3e3f.png)|
<br>
<br>
次に「test image.png」という画像をpushし、README.mdに以下のように書いてみます。

```:画像表示（ファイル名にスペースあり）
![image](test image.png)
```
すると、画像も代替テキストも表示されません。

「test image.png」は表示されず、Markdownがそのまま表示される
|:--|
| ![2022-05-01 20_47_39-Window.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2049468/48be694e-671f-fd98-fb36-0b9750d31e97.png)| 

これはスペースが入ったことでパス情報が区切られ、かつ、スペース後の文字列に""がないので、
画像タイトルとも扱われなかったためこのような表示になってしまったのだと思われます。
```:画像を表示するときのフォーマット（再掲）
![代替テキスト](画像のパス "画像タイトル")
```

スペースが含まれるファイルを表示するには、
スペースをURLエンコーディングした%20で置き換えます。
```:画像のファイル名にスペースがあるときの正しい書き方
![image](test%20image.png)
```
このようにすると正しく画像が表示されます。

名前にスペースを含むファイル「test image.png」が正しく表示される
|:--|
| ![2022-05-01 20_47_14-Window.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2049468/2bba601e-7ea1-417c-2db3-045473280ed7.png)|
GoLand Select Home Directory for Go SDKのエラー

# GoLandでGOROOTを設定しようとしたら下記のエラーがでました
![スクリーンショット 2022-05-01 18.12.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72832/c9894f05-441d-da9d-2e4c-942f839ec06a.png)


```
Select Home Directory for Go SDK
The selected directory is not a valid home for Go SDK
```
この時にGOROOTに設定したパスは`/usr/local/Cellar/go/1.18.1/libexec`になります。
Macにhomebrewで`go version go1.18.1 darwin/amd64`が入っており、そちらのパスになります。

この時のGoLandのバージョンは`2020.3`でした。
![スクリーンショット 2022-05-01 18.47.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72832/3f524fe8-1af8-3426-ecdd-625785eb6617.png)

解決方法1か2のどちらかの対応でエラーを解消できました。
解決方法2がおすすめの対応になります。


# 解決方法 1
`/usr/local/Cellar/go/1.18.1/libexec/src/runtime/internal/sys/zversion.go`
に
```
const TheVersion=`go1.18.1`
```
を設定することでエラーが解消できました。

しかし、`zversion.go`には下記のコメントがありましたので、この対応より解決方法2のほうが良さそうです。
```
// Code generated by go tool dist; DO NOT EDIT.
```
## 参考url
https://stackoverflow.com/questions/19108421/the-selected-directory-is-not-a-valid-home-for-go-sdk

# 解決方法 2
GoLandのversionを`2022.1`に更新することでエラーが解決できました。
【備忘録】Gitの基本　4月3週

初心者です。間違いに気付いたら適宜直し、書ききれなかったことは加筆もしていきます。

## Gitとは
ファイルのバージョン管理システムのこと。
GitHubは、自分のGitの内容をサーバ上で預かってくれるサービス
※GitHubのほかにも類似したサービスにBitbucketなどがある

## Gitの仕組み
まず個人の環境（ローカルな環境）の中に、

**ワークツリー**：作業している場所（ディレクトリ）
**ステージ**：リポジトリの前段階
**リポジトリ**：ワークツリー内のファイルを圧縮したファイルやコミットの履歴などを入れておく場所

がある。これらすべてローカルの話。

### add と commit
`Git`では、`add`によって作業場（ワークツリー）の内容をステージ内に保存し、`commit`でリポジトリに正式なコミット（変更）として保存する

##### 具体的には、
`git add`によって、ワークツリーのファイルすべてを圧縮してリポジトリに格納し、さらに、ステージにインデックスを作成する
インデックスには、圧縮ファイルとワークツリーのファイルが格納されている
※ワークツリーのファイルすべてを保存（スナップショット）しているのは、変更履歴を行き来するときに差分を保存するよりも動作が早くなるから

`git commit`によって、リポジトリの中にツリーを作成（インデックスのコピー）し、コミットを作成する
コミットには、「ツリーへのリンク」「作成者」「日付」「コメント」「親コミットへのリンク」の情報が格納されている

::: note info
ここで、リポジトリ内にある「圧縮ファイル」「ツリー」「コミット」をGitオブジェクトといい、これらは`.git/objects`内に格納されている
:::

### コミットは親コミットとつながっている
コミットに格納されている「親コミットへのリンク」がとても重要で、これによって**変更履歴を追う**ことができる
cscの作法 その162

# 概要
cscの作法、調べてみた。
DxLibDotNet.dll、使ってみた。
DX.MV1DrawModel、使ってみた。

# 参考にしたページ

https://qiita.com/massoumen/items/2985a0fb30472b97a590

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/62d91889-d4cd-ee6d-6b7e-05cc722659b0.png)


# サンプルコード


```
using System;
using System.Windows.Forms;
using System.Drawing;
using DxLibDLL;

namespace DesktopMascot 
{
	public partial class Form1 : Form {
		private int modelHandle;
		public Form1() {
			DX.SetOutApplicationLogValidFlag(DX.FALSE);
			DX.SetUserWindow(Handle);
			DX.DxLib_Init();
			DX.SetDrawScreen(DX.DX_SCREEN_BACK);
			modelHandle = DX.MV1LoadModel("mmd/_ver1.0.pmd");
			DX.SetCameraNearFar(0.1f, 1000.0f);
			DX.SetCameraPositionAndTarget_UpVecY(DX.VGet(0.0f, 10.0f, -20.0f), DX.VGet(0.0f, 10.0f, 0.0f));
		}
		public void MainLoop() {
			DX.ClearDrawScreen();
			DX.DrawBox(20, 40, 20 + 100, 40 + 100, DX.GetColor(0, 255, 0), DX.FALSE);
			DX.MV1DrawModel(modelHandle);
			DX.ScreenFlip();
		}
		private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
			DX.DxLib_End();
		}
		[STAThread]
		static void Main() {
			Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);
			Form1 form = new Form1();
			form.Show();
			while (form.Created) 
			{
				form.MainLoop();
				Application.DoEvents();
			}
		}
	}
}




```


以上。
[Qiita記事を量産している人必見！]自分の記事を検索する

自分用の覚書として記事を書いているのに、増えすぎて記事を探すのが難しくなった・・・。そんなことはありませんか？

そんな時は[こちら](https://elix.jp/app/tools/qiita_index.html)で検索できます。
user_idに@で始まる自分のQiita IDを入れて見てください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/27884618-0792-f28a-7edd-baaeb81fbac7.png)

[https://elix.jp/app/tools/qiita_index.html?uuid=ELIXIR#Unity](https://elix.jp/app/tools/qiita_index.html?uuid=ELIXIR#Unity)
のようにユーザー名と検索タグを渡すことでダイレクトに調べることもできます。
cscの作法 その161

# 概要
cscの作法、調べてみた。
DxLibDotNet.dll、使ってみた。
Form、使ってみた。

# 参考にしたページ

https://qiita.com/massoumen/items/2985a0fb30472b97a590

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/d166a0e6-74b3-adfd-5053-effc01576038.png)

# サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;
using DxLibDLL;

namespace DesktopMascot 
{
	public partial class Form1 : Form {
		public Form1() {
			DX.SetOutApplicationLogValidFlag(DX.FALSE);
			DX.SetUserWindow(Handle);
			DX.DxLib_Init();
			DX.SetDrawScreen(DX.DX_SCREEN_BACK);
			DX.SetCameraNearFar(0.1f, 1000.0f);
			DX.SetCameraPositionAndTarget_UpVecY(DX.VGet(0.0f, 10.0f, -20.0f), DX.VGet(0.0f, 10.0f, 0.0f));
		}
		public void MainLoop() {
			DX.ClearDrawScreen();
			DX.DrawBox(20, 40, 20 + 100, 40 + 100, DX.GetColor(0, 255, 0), DX.FALSE);
			DX.MV1DrawModel(modelHandle);
			DX.ScreenFlip();
		}
		private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
			DX.DxLib_End();
		}
		[STAThread]
		static void Main() {
			Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);
			Form1 form = new Form1();
			form.Show();
			while (form.Created) 
			{
				form.MainLoop();
				Application.DoEvents();
			}
		}
	}
}



```

以上。
【Dart】三項演算子(Ternary operator)でif文をシンプルにする

# はじめに
Flutterでアプリを作るに当たってDartを上手に使いこなすことはアプリ制作の効率を格段に上げます

長いコードは簡潔に、他のエンジニアにはわかりやすくコードを書くことで結果的に自分が保守をする側に回っても効率的なアプリのマネージメントができると言うわけです

そこで今回は**三項演算子**を用いるとどれほどシンプルなコードが書けるかまとめます

# 三項演算子とは
プログラミングではif/else文を使うことがありますが
これを一文で書いたものを三項演算子と言います
ただ「**何が『三』なの？**」と疑問に思う方もいると思うので簡単にまとめます

## 単項演算子
**単項演算子**とは式を書いたときに被演算子が1つだけ登場する演算子です
例を挙げると**インクリメント演算子**や**デクリメント演算子**です

```unary_operator.dart
$i = 1;
$i++;
```
この"**++**"に当たるのが単項演算子です
つまり**変数や値を1つしか取らない演算子**のことを言います

## 二項演算子
**二項演算子**とは**被演算子が2つ**登場する演算子です

```binary_operator.dart
$i = 1 + 2;
```
この"**+**"は2つの値を演算する時に使うので二項演算子であると言えます

## 三項演算子
**三項演算子**とは**被演算子が３つ**登場する演算子です

```ternary_operator.dart
int $i = 1;
$i == 1 ? print('true') : print('false');

```
この場合"**?**"と"**:**"の前後に３つの変数や関数があると思います
そのため3つの項があるという意味で三項演算子と呼ばれます

# 三項演算子の利便性
if/else文を使った場合と比較してどれほどコードが短くなるか見ていきましょう

## if/else文で条件分岐を行なった場合

```if_else.dart
main() {
  int number = 15;
  
  if (number > 20) {
    print('Huge number!');
  } else {
    print('Tiny Number!');
  }
}
```
以上のようなシンプルなものでも5行のコードを書くことになりました

## 三項演算子でまとめた場合

```ternary_operator.dart
main() {
  int number = 15;
  
  number > 20 ? print('Huge number!') : print('Tiny Number!');
}
```
この場合には1行でまとめることができました

### 使い方
三項演算子は **"?"の左側がbool型の"true"である場合に":"の左側が実行され、"false"である場合には":"の右側が実行**されます

それを利用して以下のように
三項演算子を使った後の実行結果を直接変数に入れることもできます

```ternary_operator.dart
main() {
  int $i = 100;
  
  bool $booleanAnswer = $i > 50 ? true : false;
  
}

```

### 注意
三項演算子は便利な書き方ですが複雑なif/else処理が行えないことには注意が必要です

また1行で書けるのが魅力的ですがそれ故に理解しづらくなってしまう可能性もあります

**自分にとってもそのコードを読む他のエンジニアにとっても理解しやすいようなコードを書く**ために、適宜三項演算子を使うべきかどうかは考える必要があると思います

# まとめ
三項演算子はコードが長くならないためには非常に効果的な演算子です

一方であくまで１演算子であることから常に使わなくてはいけないというわけではありませんので、わかりやすいコードを作るために上手に使うことを心がけましょう
値の大きさごとにランク付けしよう！：rank(),sort_values()他

この膨大なデータ、値が大きい順にランク付けしたいなぁ
この商品データを単価が大きい順にランク付けしたいなぁ
こんな時、データ加工の時によくあることだと思います。

そんなときは、値順にランク付けが出来る`rank()`関数というものがあります。
最初にデータを用意していきます。
```Python
import pandas as pd
import numpy as np

df01 = pd.DataFrame( {'name':['A', 'B', 'C', 'D' ,'E',"F"],
'math':[60, 70, 80 ,90,100,60]})
df01
```
```
  name	math
0	A	60
1	B	70
2	C	80
3	D	90
4	E	100
5	F	60
```
今回については、６行しかありませんので、分かりやすいかと思いますが、実際の実務では100万行などなる場合も全く珍しくありません。
そんな膨大なデータを一気にランク付け出来たら便利ですよね。
それでは、実際にコードを書いていきます。
```Python
rank = df01["math"].rank(method="min" , ascending=False)
rank
```
```
0    5.0
1    4.0
2    3.0
3    2.0
4    1.0
5    5.0
```
`method="min"`にすることによって、重複している値が同じ値になります。
別で`method="first"`にすることによって、上の行にあるものから順番に番号がつきます。
`ascending=False`にすることによって、大きい値順から順位がつきます。
```Python
df01["math"].rank(method="first" , ascending=False)
0    5.0
1    4.0
2    3.0
3    2.0
4    1.0
5    6.0
```
先ほど作成したrankともともとのデータフレームを結合していきます。
```Python
df01_rank = pd.concat([df01 , rank] , axis=1)
df01_rank
```
```
name	math	math
0	A	60	5.0
1	B	70	4.0
2	C	80	3.0
3	D	90	2.0
4	E	100	1.0
5	F	60	5.0
```
このままだと、カラム名が重複しているので、カラム名の変更と、ランク順に`sort_values()`を用いて見やすくしていきます。
```Python
df01_rank.columns=["name" , "math" , "rank"]
df01_rank.sort_values("rank" ,ascending=True)
```
```
	name	math	rank
4	E	100	1.0
3	D	90	2.0
2	C	80	3.0
1	B	70	4.0
0	A	60	5.0
5	F	60	5.0
```
このように上手くランク付けと並びかえをすることができました。
是非お持ちのデータで活用してみてください。
固定レイアウトの電子書籍をテキストに変換して使用する方法

# ●はじめに
欲しい参考書を手っ取り早く電子書籍で購入したら、固定レイアウトだったのでテキストのコピーができない・・・というのはあるあるだと思います。そんな場合でもカンタンに素早くテキストをコピーする方法をご紹介します。

ちなみに固定レイアウトではなく普通にコピーできる形式だと、そこまでありがたみを感じないかもしれませんが、たとえばKindle等でコピー回数制限を超えてしまった場合にも非常にオススメです。
テキストの内容をノートアプリに貼って手順化する時など重宝すると思います。

**※この記事はコピーした内容をあくまで個人的な用途で使用するケースを想定しています。著作権違反を起こさないようお気をつけください。**

# ●前提
以下の場合で問題なく動作を確認しています。
- 横書きの参考書
- 絵や写真の文字（あまりにも文字が荒すぎたり独特だと難しいと思います）

# ●Google Driveを使用
使い方は非常にカンタンです。

**1.Google Driveに適当なフォルダを作成**
**2.固定レイアウトの電子書籍のスクリーンショットを撮る**
**3.手順1で作ったフォルダにスクリーンショットを保存**
**4.保存したスクリーンショットを右クリック → アプリで開く → Google ドキュメント**
**5.数秒後、固定レイアウトの内容がテキストとして転記された Google ドキュメントが作成される**

尚、今の所横書きの参考書等では、**誤字・脱字は見受けられませんでしたが、文字と文字の間に半角スペースが一定間隔で入ってしまいます。**
一つずつ消すのは時間が掛かりすぎるので、**そのまま Google ドキュメント上で編集 → 検索と置換を使用するのがオススメです。**
検索と置換を開いたら「検索」に半角スペースを1つだけ入力し、「次に変更」は空で「すべて置換」を押下。すると半角スペースが一気に消えます。

文字ベースの手順で恐縮ですがご参考ください。
World上のオブジェクトの位置に合わせてScreenSpace-CameraのCanvasにUIを置く


```RectTransformUtility.WorldToScreenPoint(camera,worldPos);```
とか
```RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRT, sPos, camera,out lPos);```
を使って色々やってもうまくいかず、いろいろ悩んでいたのですが、単純に

```
Image img = ui.GetComponent<Image>();
img.rectTransform.SetParent(canvasRT);
img.rectTransform.position = worldPos - targetCamera.transform.forward; // Object等に邪魔されないよう上にあげておく
img.rectTransform.localScale = Vector3.one;
img.rectTransform.localRotation = Quaternion.identity;
```
こんな感じで大丈夫でした。いわれてみたらScreenSpace-Cameraなんだからそうですよね。。。
ただ、ScreenSpace-Overlayと違い、Hierarchy上でCanvas下にあるオブジェクトをProjectにドラッグ＆ドロップしてプレハブ化したものを再度Instantiata()してCanvas下に置いただけではサイズや向きが正しく補正されなかったので、

```
img.rectTransform.localScale = Vector3.one;
img.rectTransform.localRotation = Quaternion.identity;
```
を入れてあります。これはもっと良い方法ないですかね？
【基本情報技術者学習】一言メモ・ヒストグラムとパレート図

ヒストグラムとパレート図の違い：
項目を順番に並べているかどうか/折れ線の有無
上記の2点で判断すると早いかなと思います。

下記引用：


>ヒストグラム「データのバラツキの姿を把握するために活用するツール」
>パレート図「原因を分類して視覚化。重点指向、優先順位を付けやすい」

https://happymakeproject.com/6585/


>ヒストグラムの各階級の棒を度数が大きい順に左から並べ替え、その上に累積相対度数の折れ線グラフ>を重ねる場合もあります。このようなグラフを「パレート図」といいます

https://bellcurve.jp/statistics/course/1639.html
kicadでteardropを付ける(備忘録)

# 環境
KiCad 5.1.9

# teadropのプラグインをいれる
このリポジトリを```~\KiCad\share\kicad\scripting\plugins\```にクローンする

https://github.com/NilujePerchut/kicad_scripts

```master```ブランチは2022/05/01現在ではKicad 6対応のブランチになっているため、```V5```ブランチにチェックアウト

# Kicadでの作業
もしKicadを起動したまま作業をしていたのであれば一旦Kicadを閉じる。

Kicad、Pcbnewを起動してツール-外部プラグイン-プラグイン更新をする。

するとteardropのアイコンが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232528/798957cc-4cc3-5f34-6ef0-29cb3fbde720.png)

# やってみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232528/ffe17301-050a-2612-3c91-fd2331c48f73.png)
いい感じ～、SMDはちょっと工夫する必要あるかもしれないけどないよりはよさそう
cscの作法 その160

# 概要
cscの作法、調べてみた。
DxLibDotNet.dll、使ってみた。
DX.LoadGraph、使ってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/21eb3614-ad17-47e8-ba0d-35353846301b.png)


# サンプルコード

```
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using DxLibDLL;

namespace App
{
	static class Program {
		[STAThread]
		static void Main() {
			DX.ChangeWindowMode(DX.TRUE);
			if (DX.DxLib_Init() < 0)
			{
				return;
			}
			int GraphHandle = DX.LoadGraph("Src1.bmp");
			DX.SetDrawScreen(DX.DX_SCREEN_BACK);
			int x = 0, 
				xadd = 2;
			while (DX.ProcessMessage() != -1)
			{
				DX.ClearDrawScreen();
				x += xadd;
				if (x < 0 || x > 640)
				{
					xadd = -xadd;
				}
				DX.DrawGraph(x, 0, GraphHandle, DX.TRUE);
				DX.ScreenFlip();
			}
			DX.DxLib_End();
		}
	}
}





```

以上。
仮想DOMとリアルDOM

cshtml+javascriptで作られたサービスをReactにリプレイスする際にDOM操作について考えさせられることが多くなったので学び直すことにしました。

# DOMとは
Document Object Modelの略。
JavaScriptからHTMLドキュメントを操作するためのインターフェース、およびデータ構造。
Webブラウザは、Webサーバから受け取ったHTMLドキュメントを解析しDOMと呼ばれるデータ構造(インターフェイス)に変換する。
DOMはNodeツリーとなっている。
### Node
NodeはいくつものDOMAPIオブジェクトタイプが継承しているインターフェイス。
- Document
- Element
- Attr
などがある。
### Documentオブジェクト
ブラウザ固有の処理を行うためのオブジェクトの一つ。
DOM操作のためのメソッドが含まれている。

```html:例
<p id="changeText">テキスト</p>

<script>
const target = document.getElementById("changeText");
target.innerHTML = "テキスト変更";
</script>
```
例では、document.getElementByIdで”changeText”というidを持つNodeをDOM全体から検索。取得したNodeをinnerHTMLを使って中身を書き換えている。
このようにDOMに対してAPIを使って、HTMLドキュメントを操作することができる。
「仮想DOM」と区別して「リアルDOM」と呼ぶ。

# リアルDOM操作とレンダリング
WebブラウザはHTMLドキュメントをレンダリング（コンテンツをブラウザの画面に表示する処理）することで画面を描画します。４つのステップを踏む。

1. HTMLの解析
2. レンダリングツリーの構築（DOMツリー・CSSツリー→レンダリングツリー）
3. レイアウト処理
4. 描画   

ブラウザはDOM操作イベントによって発火し、レンダリング処理を行う（再レンダリング）
レンダリングはブラウザにとってコストの高い処理である。

# 仮想DOM
仮想DOMはバーチャルのDOM（軽量なJSオブジェクト）。このバーチャルDOMはブラウザ上にはなく、メモリ上に保存されている。
### 差分検知
UIが変更された場合は変更後の仮想DOM構造体を作成し、メモリ上にある変更前の仮想DOM構造体と比較して、異なる部分だけを抽出してくる。
差分検知をメモリ上で素早く行い、抽出した差分をリアルDOMに適用するので、ブラウザは必要な分だけのレンダリングで済む。

# React化
#### リアルDOMでの課題
- ソースコードの肥大で、どこでなにをしているのかが分かりづらい
- 状態をチェックすることができない
- 前回の状態に依存した処理が必要（処理が複雑化）
- レンダリングコストがかかる

#### Reactの特徴

#### 1. UIとロジックの分離
##### リアルDOMの課題：　
ソースコードの肥大で、どこでなにをしているのかが分かりづらい。

##### React化：
どこでなにをしているのかをJavaScript側で把握しなくてよい。
変更をするのは状態であり、「HTMLのどの要素を取得し、何をするか」は関係ない。
状態の一元管理（グローバルStateなど）でメンテナンスしやすくなる。


#### 2. 宣言的UI
##### リアルDOMの課題：　
状態をチェックすることができない。
前回の状態に依存した処理が必要（処理が複雑化）

##### React化：
状態が変化したら自動的に再描画する。
前の状態に依存せず、最終的な状態を宣言的に記述できる。


#### 3.仮想DOM
##### リアルDOMの課題：　
レンダリングコストがかかる

##### React化：
仮想DOMによってメモリ上で抽出した差分のみが再描画される。DOMへの操作が最小限。
全てを再描画する処理を行ってもパフォーマンスの低下を防げる。

# 仮想DOMとリアルDOMの1対1の関係性
リアルDOMの操作は仮想DOMとリアルDOMの１：１の関係性を壊す原因となる。
１：１の関係性が壊れると仮想DOMが検知した差分を、正しくリアルDOMに反映させる事ができない。
リアルDOMを操作するようなjQueryとReactの相性が悪いのはこれが理由。



# 参考
https://ja.reactjs.org/docs/faq-internals.html

https://www.hypertextcandy.com/vanilla-javascript-dom

https://eh-career.com/engineerhub/entry/2020/02/18/103000

https://www.konosumi.net/entry/2018/08/25/020111

https://zenn.dev/yamakenji24/articles/a98fcee4700ad4
cscの作法 その159

# 概要
cscの作法、調べてみた。
DxLibDotNet.dll、使ってみた。


# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/c7e9f486-6e96-e31f-6cd0-85cfbb4890f9.png)

# コンパイル手順

- DxLibDotNet3_23.zipをダウンロード。
- 解凍して
- DxLibDotNet.dll、DxLib_x64.dll、DxDLL.csをコピペ。
- コンパイル

```
>csc dxlib0.cs /r:DxLibDotNet.dll

```

# サンプルコード

```
using System;
using DxLibDLL;

class Test {
	[STAThread]
	static void Main() {
		DX.ChangeWindowMode(DX.TRUE);
		DX.SetGraphMode(640, 480, 32);
		if (DX.DxLib_Init() == -1) 
			return;
		while(DX.ProcessMessage() == 0 && DX.CheckHitKey(DX.KEY_INPUT_ESCAPE) == 0)
		{
			DX.ClearDrawScreen();
			DX.DrawBox(320, 240, 320 + 100, 240 + 100, DX.GetColor(255, 0, 0), DX.FALSE);
			DX.ScreenFlip();
		}
		DX.DxLib_End();
	}
}
```

以上。
win11にしたらエイリアスが使えなくなった。error: `fnm env` was not applied in this context. Can't find fnm's environment variables

win11にしたら急に登録してたエイリアスが使えなくなった。

原因は、パワーシェルが読み込むファイルのパスが変わったかららしい。


上記コマンドを実行するとパワーシェル立ち上げ時にどこのファイル読み込んでいるかわかる
> $Profile


win10だと
 %HOMEPATH%/Documents/WindowsPowerShell/Microsoft.PowerShell_profile.ps1
win11だと
 %HOMEPATH%/Documents/PowerShell/Microsoft.PowerShell_profile.ps1
になる。


fnmをinstallして使おうと思ったらこのエラーが出た。
Microsoft.PowerShell_profile.ps1にenvの設定してるのにずっと
error: `fnm env` was not applied in this context. Can't find fnm's environment variables
って出るから、えってなってた。
こういうの気づきにくいからマジやめれ。。
Singletonについて

# Singletonとは？

`「Singleton（シングルトン）」はデザインパターンの一種です。「Singleton（シングルトン）パターン」と呼ばれることもあります。
「あるクラスのインスタンスが常にたった1つしか存在していない」という状態を実現したいときに利用されます。`

あるクラスについて「複数のインスタンスが作られると困る」場面があれば、Singletonパターンを使用する。
※全機能で使用するキャッシュ保持など

# Singletonの構成

Singleton#getInstance( )でインスタンスを取得することができる。

①インスタンスを保持する内部クラス

    /**
     * Configクラスの唯一のインスタンスを保持する内部クラス
     */
    public static class ConfigInstanceHolder {
        /** 唯一のインスタンス */
        private static final Config INSTANCE = new Config();
    }
}

②インスタンス取得

    /**
     * 唯一のインスタンスを返す
     * @return このクラスの唯一のインスタンス
     */
    public static Config getInstance() {
        return ConfigInstanceHolder.INSTANCE;
    }

③コンストラクタ
ここでメインの処理を書く！
（DBから取得したデータからキャッシュを生成する処理など。例えばここからキャッシュ取得用のservice呼び出したり。）

    /**
     * 外部からインスタンス化できないよう、コンストラクタをprivateで宣言する
     */
    private Config() {
        // 実際はファイル・データベースなどから設定情報を
        // 読み込む処理をここに書く
    }

④設定情報
外部クラスからgetInstance()してこのメソッドが呼び出せる。
（特有のIDやハッシュ化した回数など呼び出せたり）

    /**
     * 指定されたキーに対応する設定値を返す
     * @param key 設定キー
     * @return 設定値
     */
    public String getValue(String key) {
        // 実際はコンストラクタで読み込んだ設定情報を
        // 返す処理をここに書く
        return ....;
    }
自動車用（車載）ソフトウェアの基本設計提案を作る(2), OSEK(56)

自動車用（車載）ソフトウェアの基本設計提案を作る。

https://qiita.com/kaizen_nagoya/items/9c218e65d98084b24dfe

の評判が芳しくなく、書き直します。

<この項は書きかけです。順次追記します。>
This article is not completed. I will add some words in order.

# 背景

ホンダが、排ガス規制を電子制御で達成してから、自動車用ソフトウェアは発展してきました。

## 1. 排ガス規制、省電力
エンジンでは排ガス規制であるが、電気自動車では省電力である。
この２つは、相似な構造をしており、自動車用ソフトウェアの基本設計としては、同一の構造で対応できることを想定する。

## 2. 車載通信
車載通信は、CAN（Controller Area Network)が、物理的に通信を調停できることにより、無駄のない高速通信が可能な国際規格となった。
その後、車載EthernetがSwitchにより、衝突を回避できる可能性が高まり、配線の軽量化により実用的になった。


## 3. 車載OS
電子制御とCAN通信を妨げず、助力する仕組みとしてISO OSEK/VDX 仕様が国際規格となった。
自動運転が大量通信により実現して車載Ethernetが普及してきたことにより、車載LinuxなどのPOSIX対応OSも搭載するようになった。

## 4. マルチコアCPU
クロックを高速にするより、コア数を増やすことで処理の高度化を測ることが、パソコン用、スマフォ用、ゲーム用、産業用で一般的となり、車載用のCPU（MPU, ECUとも表記する）で普及しつつある。

# 目的
電子制御、車載通信、車載OS、マルチコアをうまく生かす基本設計を作成することにより、開発期間を短くし、開発費用を削減し、高性能な道具類を整備できるようにする。
AUTOSARが道半ばまで進めて来た作業と協力し、車載Etehrnet、車載Linuxの作業と、ISOおよびSAEで進めているDiagnosticsの規格化を整合性を持って実現する方法を模索する。

# 目標
１０年後の車載Ethernet、車載Linux、AUTOSAR Classic Platform, AUTOSAR Adaptive Platform、ISOおよびSAEのDiagnostics規格類を主導できる、基本設計を示す。

仕様記述方法、プログラミング言語に依存した記述を主軸にする。
抽象的な記述へ行ったり、個別のCPUに依存した記述へ行ったりすることができるようにするためである。
個別のCPUに依存した記述は、組み込みLinuxで取り組んでいる。ARMについての記述がないのを補完するかどうかは戦略と成果による。

自動運転、モデル記述に関するオープンソースの取り組みを、規格化する時期を想定し、規格かしないことによる技術発展を促す方法と、成果を定着させるために規格化する方法との均衡を取ることを目標とする。

# 戦術
オープンソースで進展する道具による教育期間等における教育と、商用で進展する道具による産業界の教育が、それぞれ進捗するような提案を行う。


-
 ＜この記事は書きかけです。順次追記します。＞
 This article is not completed. I will add some words in order.

 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
This article is an individual impression based on the individual's experience. It has nothing to do with the organization or business to which I currently belong. 

# 文書履歴(document history)
ver. 0.01初稿　20221225
ver. 0.02 ありがとう追記　20230708

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

####  Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
LunarVim使ってみた

## LunarVimって何？

自分は、YouTubeのオススメ動画で突如出てきたので知りました。(日本語記事少ない)
厳密に合っているかどうかはともかく、Vimを統合開発環境っぽくする設定のセットみたいな理解。

## TL; DR

すでにいろいろカスタマイズしている人でなければ、
インストールした時点で最初からだいたい設定してくれていていい感じに使える。
逆に、プラグインをいろいろ試してこだわりがある人にとっては、
同じように設定はできるだろうけど、それをやる動機がないかもしれない。

これからvimを使おうという人や、こだわりのプラグインなどがないライトなvimmerには良さそう。

しばらくデフォルトエディタとして使ってみることにした。

## background

そんなにvimヘビーユーザではないです。

* vim keybindの呪い進行度
  * VSCodeにneovimのアドオンを入れている
  * ChromeにVimium入れているくらい
  * fish shellもvim keybind

* vimmer度
プラグインをたくさん試したりとか、nmap山盛りになってたりはしない人です。

## インストール

[こちら](https://qiita.com/OhaTak/items/350482c1c3c815a1d92b)を参考にやってみた。
今の環境を汚さずに試せるのはgood

依存するプログラムのインストールもやってもらえるらしい。
自分はすでに全部入っていたので全部Noにしても起動は成功した。

Yesにすると上手く行かなかった人は、別で自力インストールしてみるといいかも。

## プラグインについて

Coreプラグインとして、インストール済みのものがけっこうある
https://www.lunarvim.org/plugins/01-core-plugins-list.html
「この機能は、このプラグインでないとダメなんだよ」みたいなこだわりがなければ楽でいい。
lvimでconfig.luaを編集保存するとそのまま適用してくれるのもユーザーフレンドリーな感じ。

追加でもプラグインを入れることはできる

自分は、とりえあえず`tpope/vim-surround`,`tpope/vim-repeat`, `folke/trouble.vim`を追加
これだけで、個人的に必要なものはそろった感じ。

## 良かったところ

* その言語の拡張子のファイルを開くだけで、Language Serverとか勝手にインストールしてくれる
* config.luaも編集したら自動で適用
* すでにキーマップをある程度設定してくれている（気に入らない人もいるかも）
確認したかったら、 `<leader>sk`でtelescope経由で見れる


## 遭遇した不具合？

*  `Ctrl-w`すると操作を受け付けなくなる
topするとnvimがCPU 100%近い数字になっていて、何かしらやっているらしいけど、
そこまで深堀りできていない

window移動は、`Ctrl-[hjkl]`で直接移動できるので、慣れれば問題ないのだけど、
自分はNerdTreeで`Ctrl-W [hjkl]`で移動してたので、うっかりやってしまう
起こってしまったら`kill -9`するしかない

というわけでunmapしておく
```config.lua
lvim.keys.normal_mode["<C-w>"] = "<NOP>"
-- lvim.keys.normal_mode["<C-w>"] = false
```
config.luaのコメントでは、falseにするとオフにできるような記載だけど、`<NOP>`にしないとダメだった

### 追記 20220521

再インストールしたら上記不具合はでなくなっていた。
というか、`Ctrl-W` のキーマッピングが解除されていたので、バージョン特有のものだったらしい。

## 所感

個人的にはけっこう気に入った、というか、今まで(neo)vimを使いこなせてなかった感を思い知らされた。
とりあえず、「おすすめプラグイン一通り入れてあるよ！」くらいの気持ちで使うとちょうどいいかも。

## 参考
https://qiita.com/OhaTak/items/350482c1c3c815a1d92b
Amazon Linux 2でLAMPサーバーのパッケージをインストールする際、No package ○○ availableエラーが出る

# エラー発生
[チュートリアル: Amazon Linux AMI への LAMP ウェブサーバーのインストール](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/install-LAMP.html)を参考に、LAMPサーバーのパッケージをインストールするとエラーが発生した。

```
sudo yum install -y httpd24 php72 mysql57-server php72-mysqlnd
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                                       | 3.7 kB  00:00:00     
No package httpd24 available.
No package php72 available.
No package mysql57-server available.
No package php72-mysqlnd available.
Error: Nothing to do
```

# 対処方法

このエラーが出る場合、インスタンスは Amazon Linux AMIでない可能性がある。
下記のコマンドを使用して、Amazon Linux のバージョンを表示できる。

```
cat /etc/system-release
Amazon Linux release 2 (Karoo)
```

[チュートリアル: Amazon Linux 2 に LAMP ウェブサーバーをインストールする](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-lamp-amazon-linux-2.html)の記事を参照し、Amazon Linux2の場合、`yum update`を行ったうえで、下記のコマンドでインストール可能。
※バージョンは適宜変更。

```
# LAMP MariaDBとAmazon Linux 2 PHPパッケージの最新バージョンを取得
sudo amazon-linux-extras install -y lamp-mariadb10.2-php7.2 php7.2

#Apache、MariaDBインストール
sudo yum install -y httpd mariadb-server
```
gatsby-remark-componentで外部から値を注入する方法

# はじめに
こんにちは。最近は本業でRailsを触ってばかりの日々が続いております。

さて、今回はGatsbyでカスタムコンポーネントを使用しているのですが、コンポーネント外部から値を注入する方法について記載します。

参考になれば幸いです:pray:

（ぜひLGTMいただけましたら:smile:）

# Gatsbyでコンポーネントの作り方はこちら
https://qiita.com/akitkat/items/58332b972aac6145de80

# 結論

## コンテンツ
記事のマークダウン内に以下のようにコンポーネントを呼び出す場合。
```markdown:post.md
<custom-component name="こんにちは"></custom-component>
```

## コンポーネントの実態
```js:src/components/CustomComponent.js
import React from 'react'

const CustomComponent = props => (
  <div>
      <p>{props.name}</p>
      <p>{props.keywords}</p>
  </div>
)

export default CustomComponent
```

## コンポーネント突合
```js:src/components/PageBody.js
import React from 'react'
import CustomComponent from "../components/CustomComponent"
import RehypeReact from "rehype-react"

const PageBody = props => {
  const renderAst = new RehypeReact({
      createElement: React.createElement,
      components: {
        "custom-component": p => CustomComponent({...p, {keywords: props.keywords}})
      }
  }).Compiler

  return (
    <Body>
      {renderAst(props.body.childMarkdownRemark.htmlAst)}
    </Body>
  )
}

export default PageBody
```

# 解説
## 普通にコンポーネントから値を渡すパターン

記事のマークダウン内に以下のようにコンポーネントを呼び出す
```markdown:post.md
<custom-component name="こんにちは"></custom-component>
```

コンポーネント内では以下のように、propsに渡ってくるのでそれをレンダリングするだけ。

```js:src/components/CustomComponent.js
import React from 'react'

const CustomComponent = props => (
  <div>
      <p>{props.name}</p>
  </div>
)

export default CustomComponent
```

## 今回は外部から注入するパターンを追加
以下例では、ページ別で管理しているkeywordsの値をマークダウンからねじ込むコンポーネントに注入します。

keywordsはPageBodyを呼び出した際にpropsで渡ってきます。

それを`custom-component`を`CustomComponent`に置き換える際に、コンポーネントが持っている値にkeywordsをマージして呼び出しています。

```js:src/components/PageBody.js
import React from 'react'
import CustomComponent from "../components/CustomComponent"
import RehypeReact from "rehype-react"

const PageBody = props => {
  const renderAst = new RehypeReact({
      createElement: React.createElement,
      components: {
        "custom-component": p => CustomComponent({...p, {keywords: props.keywords}}) // ここでコンポーネントにpropsにkeywordsをマージする。
      }
  }).Compiler

  return (
    <Body>
      {renderAst(props.body.childMarkdownRemark.htmlAst)}
    </Body>
  )
}

export default PageBody
```

# おわりに
Contentfulでコンテンツを管理しているのですが、そのコンテンツ内にカスタムコンポーネントを記載しています。
そのコンポーネントでコンテンツ固有の値を使用する場合に、このような記述が必要になりました。

当初は、マークダウンのコンテンツをContentfulからfetchした際に、node作成前にいじるなども考えましたが、この方法が一番スマートに思います。

参考になれば幸いです:pray:
GameplayKitのGKGridGraph使用時に発生したメモリーリークに対応する

SwiftとSpriteKitでの開発中、GKGridGraphを使用しているSKSceneの遷移時にメモリーリークが発生したので原因を調査しました。

SwiftUIベースで開発しているため、エントリーポイントは次の通りです。

```swift: SandBoxApp.swift
import SwiftUI

@main
struct SandboxApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
```

エントリーポイントから初期表示されるSwiftUIのViewです。SpriteViewでSpriteKitのSKSceneを描画させています。

```swift: ContentView.swift
import SpriteKit
import SwiftUI

struct ContentView: View {
    var scene: SKScene {
        let scene = GameScene()
        scene.scaleMode = .resizeFill
        return scene
    }
    
    var body: some View {
        SpriteView(scene: scene)
            .ignoresSafeArea()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```

問題が発生したSKSceneです。

```swift: GameScene.swift
import GameplayKit
import SpriteKit

class GameScene: SKScene {
    var deltaTime: TimeInterval = 0.0
    var previousTime: TimeInterval?
    var grid: GKGridGraph<GKGridGraphNode>?

    deinit {
        print("deinit GameScene")
        // (3)
        self.grid = nil
    }
    
    override func didMove(to view: SKView) {
        let x = Int32(15)
        let y = Int32(15)
        // (1)
        self.grid = GKGridGraph(
            fromGridStartingAt: vector_int2(x: 0, y: 0),
            width: x,
            height: y,
            diagonalsAllowed: false
        )
    }
    
    override func update(_ currentTime: TimeInterval) {
        if let previousTime = previousTime {
            self.deltaTime += currentTime - previousTime
        }
        
        if self.deltaTime > 1 {
            print(self.deltaTime)
            self.deltaTime = 0.0
            // (2)
            let scene = GameScene()
            scene.scaleMode = .resizeFill
            self.view?.presentScene(scene)
        }
        
        self.previousTime = currentTime
    }
}
```

大まかな処理の流れは、次の通りです。

(1) SKSceneのインスタンスプロパティとして、GKGridGraphを作成します。
(2) テストのため、1秒置きに新しいSKSceneのインスタンスを作成し、SKViewの `presentScene(scene)` メソッドで画面を遷移します。
(3) SKSceneの `deinit` 時にGKGridGraphは合わせて破棄されるため、本来は不要ですが、念のため、GKGridGraphに `nil` を代入します。

この処理を実行し続けるとメモリリークが発生し、最終的にアプリケーションがハングアップします。

結論を述べると、SKSceneの `deinit` 時にインスタンスプロパティのGKGridGraphは合わせて破棄されますが、そのGKGridGraphに埋められているGKGridGraphNodeがメモリ上に残り続けてしまうため、メモリリークが発生していました。

これは、Xcodeで処理を実行し、次のメモリ状態に注目することで確認できました。

* CoreFoundationのGKGridGraphに紐づくNSMutableArrayが増え続けている。
* GamePlaykitのGKGridGraphNodeが増え続けている。

注意として、このテストコードでは、ContentView.swift内でSpriteViewに初回に表示されるSKSceneを紐づけているため、初回に表示されるSKSceneインスタンスに紐づく変数は残り続けます。従って、3回目の画面遷移以降からメモリリークとして確認できます。

この事象へ対策するには、画面遷移の前にGKGridGraphに埋められているGKGridGraphNodeのクリーンアップを実行します。

具体的には、GKGridGraphからすべてのGKGridGraphNodeを次の様に除去します。

```diff_swift: GameScene.swift
import GameplayKit
import SpriteKit

class GameScene: SKScene {
    var deltaTime: TimeInterval = 0.0
    var previousTime: TimeInterval?
    var grid: GKGridGraph<GKGridGraphNode>?

    deinit {
        print("deinit GameScene")
        // (3)
+       if let grid = self.grid {
+           grid.remove(grid.nodes!)
+       }
        self.grid = nil
    }
```
CREATE TABLEするとTable doesn't existと言われた話

# はじめに

※別のブログに投稿していた記事をQiitaに投稿し直しています。（元の記事は削除予定）

# エラー発生までの流れ

1. Macでdocker-composeを使ってMySQL環境を構築
1. CREATE TABLE XXX
1. DROP TABLE XXX
1. CREATE TABLE XXX でエラー発生

```
Table ‘xxx’ doesn't exist
```

いや、無いから作ろうとしているのに、無いよって。
よく見るとテーブル名が小文字になっている。
ググってみると、lower_case_table_namesというパラメータで回避できそう。

# lower_case_table_namesについて

|  値  |  意味  |
| ---- | ---- |
|  0  |  テーブル名とデータベース名は、CREATE TABLE または CREATE DATABASE ステートメントで指定された大文字または小文字を使用してディスク上に格納されます。名前比較では大文字と小文字が区別されます。大文字小文字を区別しないファイル名を持つシステム (Windows や OS X など) で MySQL を実行する場合、この変数を 0 に設定しないでください。大文字と小文字を区別しないファイルシステムで --lower-case-table-names=0 を使用して強制的にこの変数を 0 に設定し、大文字と小文字を変えて MyISAM テーブル名にアクセスした場合、インデックスが破損することがあります。  |
|  1  |  テーブル名はディスク上に小文字で格納され、名前比較では大文字と小文字は区別されません。MySQL では、保存およびルックアップ時にすべてのテーブル名が小文字に変換されます。この動作はデータベース名やテーブルエイリアスにも適用されます。  |
|  2  |  テーブル名とデータベース名は、CREATE TABLE または CREATE DATABASE ステートメントで指定された大文字または小文字を使用してディスク上に格納されますが、MySQL ではルックアップ時に小文字に変換されます。名前比較では大文字と小文字が区別されません。これは大文字と小文字が区別されないファイルシステムでのみ機能します。InnoDB テーブル名は lower_case_table_names=1 のように、小文字で格納されます。  |

デフォルト値はUnixは0, Windowsは1, OS Xは2で、0を設定すれば解決しそう。

https://dev.mysql.com/doc/refman/5.6/ja/identifier-case-sensitivity.html:embed:cite

# lower_case_table_namesを設定、再びエラー

docker-composeのymlファイルに下記を追加

```
command: --lower_case_table_names=0
```

追加後にコンテナを再起動したらエラー発生

```
[ERROR] The server option 'lower_case_table_names' is configured to use case sensitive table names but the data directory is on a case-insensitive file system which is an unsupported combination. Please consider either using a case sensitive file system for your data directory or switching to a case-insensitive table name mode.
```

ファイルシステムが大文字小文字を区別していないらしい。  
ディスクユーティリティで確認すると「APFS」で、大文字小文字は区別しない。  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627583/2fdfc1ac-be53-6984-fa6e-a6e603378a42.png)

ディスクの初期化は面倒臭い。。

# 対処

大したテーブル、データは入っていないので、ボリュームを削除し、コンテナを再作成。  
初回のCREATE TABLEはエラーになっていないので、DROP TABLEで完全に消えていないのかも。  
気が向いたらこの辺り調べてみる。。
【Android】MVVM的に2つのサンプルアプリを作ってみた 〜 Room & Retrofit2 〜

# はじめに

皆さん、ごきげんよう！れぶです！

今回の記事では、`MVVM設計`を意識して作成した2つのサンプルアプリをざっくり紹介していきます。これからMVVM的にアプリを作成したいと考えている方に特に参考になれば光栄です。

それでは、参りましょう！！

# 開発環境

* MacBook Air
* Android Studio Bumblebee | 2021.1.1 Patch 1
* Java 8
* compileSdkVersion 31
* minSdkVersion 21

# 1つ目のアプリ
## 概要
自分が行きたい国を管理できるサンプルアプリです。データの全表示・追加・削除ができます。
`Room`を使って、ローカルDBのSQLiteを操作しています。

## 動作イメージ
![MVVM.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2456250/25417b5e-aea0-4dda-f8c0-b9b2f68c646a.gif)

## アーキテクチャ図
![MVVM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2456250/99b17141-a11c-cae3-db5d-e2fd456322e8.png)
## サンプルコード
https://github.com/seiyaleb/MVVMTrialApp

# 2つ目のアプリ
## 概要
入力された郵便番号で町域名をリスト表示するサンプルアプリです。
`Retrofit2`を使って、[zipcloud](http://zipcloud.ibsnet.co.jp/doc/api)さんのAPIデータを取得しています。

また、以下の記事でこのサンプルアプリを作成した際に自身が躓いた箇所について赤裸々に書いているので、もし良かったら読んでみてください。

https://qiita.com/leb397/items/64e5809242846b3f0319

## 動作イメージ
![ezgif.com-gif-maker (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2456250/e3e10e73-3440-a976-e187-f724824e2ddf.gif)
## アーキテクチャ図
![MVVM2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2456250/46f4418d-f119-87d1-352f-212c68e089dc.png)
## サンプルコード
https://github.com/seiyaleb/MVVMTrialApp2
# おわりに

今回は、MVVM的に作成したサンプルアプリ2つを簡単に紹介しました。
MVVM設計の思想を完全に理解したわけではないですが、今後もより一層View側にコードを書きすぎないように、以下の**役割分担**を意識してクラスを分割していこうと思います。

* **View➡️データの表示**
* **ViewModel➡️データの加工・伝達**
* **Model➡️データの取得・操作**

アーキテクチャ図やサンプルコードが皆さんの学習に少しでも役立つと嬉しいです。
以上です。ありがとうございました！

# 参考サイト
* [Android Room with a View - Java](https://developer.android.com/codelabs/android-room-with-a-view?hl=ja#0)
* [[Android]MVVMモデルでRoom+SQLite+LiveDataでRecyclerViewに表示する仕組みを理解する](https://qiita.com/highcom/items/3357fabeee02f6027f9e)
* [2020年版RecyclerViewの使い方 〜 RecyclerView + ListAdapter + DataBinding + LiveData + ViewModel 〜](https://qiita.com/que9/items/52725c3caf33f2a9b44e)
* [【Android】MVVMで、Retrofit2 + Kotlin CoroutinesでHttp通信でqiitaの記事検索するやつ作った](https://qiita.com/yonce/items/eb4ba7cf38e52be6e16f)
* [Retrofit2 + Java でAPIコールを実装する](http://kenjinakamu.com/archives/26)
* [MVVMアーキテクチャで書籍管理アプリを作ってみた！](https://rightcode.co.jp/blog/become-engineer/mvvm-architecture-book-management-application)
* [【Android】分かった気になれる！アーキテクチャ・MVVM概説](https://zenn.dev/itakahiro/articles/29ba92485a0df6)
* [【Android】初心者が意識すべきMVVMでの開発ルール](https://blog.77jp.net/development-rules-for-mvvm-that-a-beginner-should-be-conscious-of)
[競プロ][Leetcode828] 貢献度を使って数え上げ問題を解く

# 概要

数え上げ問題を解く方法の１つに貢献度を使う方法がある。 
下記の問題を元に解説する
[Leetcode 828. Count Unique Characters of All Substrings of a Given String](https://leetcode.com/problems/count-unique-characters-of-all-substrings-of-a-given-string/)

# 問題の内容

## 前提
ある文字列sがある。
``` 
s = "LEETCODE"
```

この文字列sの``ユニーク数``を下記のように定義する。
```
sの中に含まれている文字の中で１つしか存在しない文字の数
```
今回の例では``L``, ``T``, ``C``, ``O``, ``D``がそれぞれ１つしか存在しないのでsのユニーク数は5となる。

## 問題
ある文字列sが与えられたとき、sの部分文字列のユニーク数を全て足した数は何になるか。

## 例
s = "ABA"のとき、部分文字列は下記が考えられる。部分文字列を```()```で囲む。
```
(A)BA
(AB)A
(ABA)
A(B)A
A(BA)
AB(A)
```
またそれぞれのユニーク数は下記になる。

```
(A)BA = 1
(AB)A = 2
(ABA) = 1 # Aはユニークでないため数えない
A(B)A = 1
A(BA) = 2
AB(A) = 1
```
これを全て足すと8になるので、これが答え。

# 愚直な解法
文字列sの長さをNとすると、作成可能な部分文字列はN^2個作成可能
それぞれの部分文字列に関してユニーク数を計算するのにO(N)かかる。
愚直に計算すると、O(N^3)の計算量が必要。

# 貢献度を使った解法
ABAの例で考える。
部分文字列を作成して計算するのでなく、それぞれの文字のみに注目する。
まずは一番左にある```A```が含まれる部分文字列の中で、答えに含まれるものは下記になる。
```
(A)BA
(AB)A
```
(ABA)の文字列は答えに含まれない、なぜならAが重複しているため数えられることはない。
このときの数(上記の場合は2)は一番左の``A``の``貢献度``と考えられる。
全ての文字における貢献度を足し合わせることで答えを求めることが可能。
またそれぞれの文字の貢献度は書きで計算が可能
```
文字の左に配置できる(の数 * 文字の右に配置できる)の数
```
上記の例では、``(``は一番左にのみ配置可能。``)``は次の``A``の手前まで配置可能
よって一番左の文字列Aの貢献度は``1 * 2``ということがわかる。

同様にBの貢献度は``2 * 2``、Cの貢献度は``2 * 1``、これらを足すと８となる。

# 実装

```c++
int uniqueLetterString(string s) {
    // 各文字の出現場所を配列で持つ
    map<char, vector<int>> mp;
        
    int n = s.size();
    for (int i=0; i<n; i++) {
        char c = s[i];
        mp[c].push_back(i);
    }
        
    int ans = 0;
    for (int i=0; i<n; i++) {
        char c = s[i];
        vector<int>& v = mp[c];
        // 文字の出現場所を特定
        auto it = lower_bound(v.begin(), v.end(), i);

        // 文字の左に配置可能な(の数を計算
        int left = i+1;
        if (it != v.begin()) left = i - *(it-1);

        // 文字の右に配置可能な)の数を計算
        int right = n-i;
        if ((it+1) != v.end()) right = *(it+1) - i;

        ans += left*right;
    }
        
    return ans;
}
```
[AtCoder]Pythonにおける配列のコピー

追記(2022/5/2)
コメントにてpythonの配列の処理について、分かりやすく図にて説明いただきました。
具体的な内部の処理について知りたい方はぜひご覧ください。
# 目的
pythonを使用すると、配列を代入した際に値が書き換わってしまい困ってしまうケースがあると思います。
そこで、どのような場合に値が書き換わるのか、どのように対処できるのかをまとめました。
# 環境
AtCoderでの使用を前提としているため、AtCoderのコードテストで実行しています。
言語は実行速度を考慮しPypy3(7.3.0)としています。
# 一次元配列
## 代入される例
~~~python
A = [0,1,2]
B = A
B[0] = 3
print(A)
#[3, 1, 2]
~~~
上記の例では、BにAを代入するとBの要素を変更してもAの配列が書き換わります。
これはBへはAの配列のコピーでなく、Aの配列の参照を代入しているからと考えられます。
よって、AとBはともに同一の配列を参照しているため、配列の値を書き替えるとA、Bともに変化します。

## 代入されない例
~~~python
A = [0,1,2]
B = A[0]
B = 3
print(A)
#[0, 1, 2]
~~~
ここではBに配列ではなく、Aの配列内のA[0]が参照しているint型の値の参照が代入されます。
よって、Ｂの値を変更しても参照先が変化するためＡの配列は変化しません。

## 対処法
~~~python
A = [0,1,2]
B = A.copy()
B[0] = 3
print(A)
#[0, 1, 2]
~~~
copy()を使用することにより、BにはAの配列でなくAの配列のコピーが代入されたため、
Bの値を変更してもAの配列が変化することがなくなります。

# 多次元配列
## 代入される例
~~~python
A = [[0,1],[2,3]]
B = A
B[0][0] = 3
print(A)
#[[3, 1], [2, 3]]
~~~
同様にBの値を変更するとAの値も変更されます。

## copy
~~~python
A = [[0,1],[2,3]]
B = A.copy()
B[0][0] = 3
print(A)
#[[3, 1], [2, 3]]
~~~
単純なcopyでは、Bの要素を変更するとAの要素も変更されます。
これは、Bの一次元目の配列のみがコピーされるためです。

## 対処法
~~~python
import copy

A = [[0,1],[2,3]]
B = copy.deepcopy(A)
B[0][0] = 3
print(A)
#[[0, 1], [2, 3]]
~~~
copyをimportし、deepcopy を実行することで多次元配列の場合も値が変更されてしまうことを防ぎます。

# copyの問題点
## 計算時間
~~~python
A = [[0] for _ in range(10 ** 6)]
#実行時間 	208 ms

A = [[0] for _ in range(10 ** 6)]
A = A.copy()
#実行時間 	220 ms

A = [[0] for _ in range(10 ** 6)]
A = copy.copy(A)
#実行時間 	210 ms

A = [[0] for _ in range(10 ** 6)]
A = copy.deepcopy(A)
#実行時間 	1817 ms
~~~
上記のように、deepcopyは配列数に関わらず実行時間が増える場合があります。
そのため、copyと使い分けることが必要となります。

# その他注意ケース
~~~python
def MakeB(ListA):
  ListA[0] = 3
  return ListA

A = [0,1,2]
B = MakeB(A)
print(A)
#[3, 1, 2]
~~~
配列を関数に入れた場合も同様に値が変更されます。
これは関数内で配列をそのまま使用しているためです。
関数内でcopyするなどで対処可能です。
統計検定２級合格体験記

# 筆者のスペック
- （一応）理系大学院修了。
- 研究で数理モデルを扱った経験あり。
- 一応２級の範囲の内容は大学の授業でやったがほぼ記憶なし。
- 多少のデータサイエンススキルあり。

# 受検の動機
- データサイエンス関連の知識・技術を身に着けたいと思っていた。
- 準１級の受検も考えたが２級の内容も理解できていないと感じ２級からの受検に。
- 「大学で勉強したはずなんだけどなあ～。忘れちゃったな～。」（２級の問題を見ながら）

# 使用した教材
### 書籍
- [『基本統計学 第４版』](https://www.amazon.co.jp/%E5%9F%BA%E6%9C%AC%E7%B5%B1%E8%A8%88%E5%AD%A6-%E7%AC%AC4%E7%89%88-%E5%AE%AE%E5%B7%9D-%E5%85%AC%E7%94%B7/dp/464116455X)
どこかのサイトでおすすめされていた書籍。
統計検定２級の範囲をほぼカバーしていて説明もわかりやすい。
池袋のでかい本屋さんでも売ってなく、中古で購入。
- [『統計学入門』](https://www.amazon.co.jp/%E7%B5%B1%E8%A8%88%E5%AD%A6%E5%85%A5%E9%96%80-%E5%9F%BA%E7%A4%8E%E7%B5%B1%E8%A8%88%E5%AD%A6%E2%85%A0-%E6%9D%B1%E4%BA%AC%E5%A4%A7%E5%AD%A6%E6%95%99%E9%A4%8A%E5%AD%A6%E9%83%A8%E7%B5%B1%E8%A8%88%E5%AD%A6%E6%95%99%E5%AE%A4/dp/4130420658/ref=sr_1_4?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=13ODE84JP9E9A&keywords=%E7%B5%B1%E8%A8%88%E5%AD%A6%E5%85%A5%E9%96%80&qid=1651392737&s=books&sprefix=%E7%B5%B1%E8%A8%88%E5%AD%A6%E5%85%A5%E9%96%80%2Cstripbooks%2C189&sr=1-4)
通称赤本。
これまでの人生で３回くらいは購入しようとしたが難しそうで遠ざけていた。
昔よりは内容を理解できるような気はしたが、前述の『基本統計学』でほとんど事足り使用頻度少なめ。
池袋のでかい本屋さんにはたくさん売っていたが、こちらも中古で購入（ピカピカでした）。

### サイト・動画
- [統計WEB](https://bellcurve.jp/statistics/course/)
統計検定を勉強している人なら知らない人はいないサイト。
一通りこのサイトで勉強すれば２級に合格できる力は身につくとのこと。
過去問の解答・解説もあり。
- [とけたろうチャンネル](https://www.youtube.com/channel/UCxxLbPmmSud_xHZi45SoOXQ)
とけたろうさんのYouTubeチャンネル。
２級の内容についてわかりやすく解説してくれています。
ブログもあり勉強になりそう。

### 過去問
- [統計検定 学び応援コンテンツ](https://www.toukei-kentei.jp/info/challengetk/challengekako/)
統計検定のサイトで公開されていた２級の過去問４回分。
ありがたや～。

# 勉強の流れ
### 序盤
通勤の時間を使い、統計WEBを一通り読んでいた。
２週間程度で１巡した記憶。
記憶を蘇らせるにはよかったが読んでわかった気になっている部分が多かった。

### 中盤
週末に過去問を解きわからない箇所は書籍を活用し勉強しなおし。
推定・検定は基本的な問題から苦戦。
統計WEBに掲載されているの過去問の解答・解説で解き方を学ぶ。
毎週末１回分の過去問を解くイメージで４週間程度かかった。

### 終盤
2022年入り、新型コロナの感染者数が爆増。
受検の申し込みをしたいがあまり空きがなく、一度受検申込を様子見。
だらけが出てきたところでふととけたろうさんの動画を見たところわかりやすさに感激。
これまで断片的な知識だったのが動画を見て全体像がわかり、理解度が上がった。
ちょうど２週間後に空きがあったので受検の申し込み。前回申し込もうとしてからは約１か月経過。

### 直前
いいタイミングでとけたろうさんがすごい動画を出していたので活用させていただきました。
[統計検定２級の全知識【中学の数学からはじめる統計検定２級講座】](https://www.youtube.com/watch?v=L3Kt-y15jSM&t=2999s)

# さいごに
タイトルで合格と書いているので結果は合格だったのですが、
正直試験中はあぶないんじゃないかと思いました。

勉強期間は多少間延び感もあったのですが、３か月程度でした。
私のバックグラウンド的に２級の合格は決して遠いものではなかったと思いますが、
試験のための勉強にならぬよう引き続き精進していきたいです。

準１級の勉強もぼちぼち始めつつ、
「統計検定データサイエンスエキスパート」の方が試験範囲的に楽しそうなのでこっちが先かなあ。