OmniAICreator/Qiita-1.07M huggingface dataset:
JavaScriptのメソッド(forEach,map,filter)の違い

# 挨拶
Webエンジニアへの就職に向けて学習をしております、ひろやすと申します。
今回の記事は、私がUdemyでReact.jsの講座を受講しており、JavaScriptのメソッド(forEach,map,filter)について復習したため、学習のアウトプットとして記載させて頂きます。

※**Udemy**とは、動画コンテンツで学習するオンライン学習プラットフォームのこと。

## forEach
forEachメソッドは、配列の要素を一つずつ取り出して処理を行いたい場合に使います。
```javascript
const array = [1, 2, 3];

array.forEach((num) => {
  return num * 2;
};

// console.log(array);
// [2, 4, 6]
```

## map
mapメソッドは、forEach文と同じく、配列の要素を一つずつ取り出して処理を行いたい場合に使います。

```javascript
const array = [1, 2, 3];

array.map((num) => {
  return num * 2;
};

// console.log(array)
// [2, 4, 6]

```

## filter
filterメソッドは、条件に合う配列要素を取り出したい場合に使います。

```javascript
const array = [1, 2, 3];

array.filter((num) => {
  //　２で割り切れる場合
  return num % 2 === 0;
};

// console.log(array);
// [2]
```

## forEachとmapの違い
forEachメソッドは、単に配列に処理を行うのに対し、
mapメソッドは、処理を行い配列のデータを返します。

```javascript
//forEachの場合
const array = [1, 2, 3];

number = array.forEach((num) => {
  return num * 2;
};

// console.log(number);
// undefined ←配列のデータが返っていない
```
```javascript
// mapの場合
const array = [1, 2, 3];

number = array.map((num) => {
  return num * 2;
};

// console.log(number);
// [2, 4, 6] ←配列のデータが返っている
```

## mapとfilterの違い
mapは、処理を実行した結果の配列を返すのに対し、
filterは条件に当てはまった要素だけを配列として返している。

```javascript
//mapの場合
const array = [2, 4, 6];

number = array.map((num) => {
  return num / 2;
};

// console.log(number);
// [1, 2, 3] ←各要素を2で割った値を配列として返している。
```
```javascript
// filterの場合
const array = [2, 4, 6];

number = array.filter((num) => {
  return num / 2;
};

// console.log(number);
// [2, 4, 6] ←２で割ることが出来る要素を配列として返している。
```

参考になれば幸いです。
最後までお読み頂きましてありがとうございます。
SDL_Imageで、初期化エラー

# SDL_Imageで初期化ができない
SDL_Imageを使おうとして、エラーがでて止まったので、共有します。

## 初期化ができない(エラー文すら表示されない)
https://www.libsdl.org/projects/SDL_image/docs/SDL_image_frame.html
にあるように、以下の初期化をしたら、動かないどころか、エラーすら出してくれなくて、何が問題なのかわからなかった。

```cpp
	int flags = IMG_INIT_JPG | IMG_INIT_PNG;
	int initted = IMG_Init(flags);
	if ((initted & flags) != flags) {
		printf("IMG_Init: Failed to init required jpg and png support!\n");
		std::string error = IMG_GetError();
		SDL_Log("IMG_Init: %s\n", IMG_GetError());
	}
```

### 解決法
SDL本体を[ここ](https://www.libsdl.org/download-2.0.php)から**Source Codeではなく、Development Libraries**をダウンロードして、
適宜Visual Studioのプロジェクトプロパティに「追加のインクルードディレクトリ」と「追加のライブラリディレクトリ」と「追加の依存ファイル」「ビルド後のイベント」に修正を加える。

→SDL本体をSource CodeからCMakeを使ってコンパイルしていたから動かなかった。


## libpng16-16.dllが見つからない
エラー文が表示され、libpng16-16.dllが見つからないというエラーが出る。
初期化でjpgを使おうとした人は、libjpeg-9.dllが見つからないって言われたかもしれないです。

### 解決法
プロジェクト->プロパティ と進んで、プロパティの画面を表示。
画面上部の構成とプラットフォームは自分の環境に合わせ、
ビルドイベント->ビルド後のイベント
と進む。
コマンドラインに以下を追加。

```bash
copy "$(SolutionDir)dependencies\SDL2\lib\x64\SDL2.dll" "$(OutDir)"  
copy "$(SolutionDir)dependencies\SDL2\lib\x64\SDL2_image.dll" "$(OutDir)"  
copy "$(SolutionDir)dependencies\SDL2\lib\x64\libjpeg-9.dll" "$(OutDir)"  
copy "$(SolutionDir)dependencies\SDL2\lib\x64\libpng16-16.dll" "$(OutDir)"  
copy "$(SolutionDir)dependencies\SDL2\lib\x64\libtiff-5.dll" "$(OutDir)"  
copy "$(SolutionDir)dependencies\SDL2\lib\x64\libwebp-7.dll" "$(OutDir)"
copy "$(SolutionDir)dependencies\SDL2\lib\x64\zlib1.dll" "$(OutDir)" 
```

zlib1.dllだけ追加したら動くかと思ったが、結局jpegやpngのdllも追加しないと動かなかったので、全部追加している。
練習日記 AtCoder 20220213

会社の同僚たちと問題を解いて遊んだので記録。

# 1. UTPC 2011 [[iwi]]
https://atcoder.jp/contests/utpc2011/tasks/utpc2011_3
灰上位～茶くらい？

## 考えたこと
- 問題を睨むとiwiは連続して含まれそれを中心に左右の対象な文字数を最大化する必要がある
- 制約的にbit全探索で十分。
- 1: bit全探索で文字を取り出し、文字列tとする
- 2: tがiwiを含まないならだめ
- 3: 文字列が対称かを調べる

をすればよい。3の処理は各文字ごとに対象となる文字を取り出して、回文のように判定すればよい。
計算量は$O(2^n n)$

https://atcoder.jp/contests/utpc2011/submissions/29252314

## 考察(少し賢い)
この問題はiwiの左右にある文字列の小さい方だけを文字数のbit全探索でも解くことができる。それをbit全探索して、もう一方の文字列が対称かを線形な計算量で確認することができる。
計算量は$O(2^n n)$なのだが、nは上記の通り、iwiを除き短い方の長さなので、全体の文字列長35文字で上の考えで16文字と同じ計算量である。

## 考察2(賢い)
さらに考えると、左右の文字列A,Bの長さa, bに対してO(ab)で解くことができる。
LCSします。(最長共通部分列：Longest Common Subsequence) 
まず、Bを対称となる文字列にする。例えば、"))}"を"{(("にする。ここで、LCS(A, B)の長さが、iwiの左右で対称にできる長さなので、答えはこれを2倍して+3したものである。

時間・空間計算量は$O(n^2)$になる。賢い。

https://atcoder.jp/contests/utpc2011/submissions/29258171


# 2. Typical DP Contest B.ゲーム
https://atcoder.jp/contests/tdpc/tasks/tdpc_game
難しい。AtCoderで出ると水色以上だと思う。

## 考えたこと
- 小さな問題から考える問題。逆に考える。
- $dp[i][j]$を山$a$に$i$個残っており、山$b$に$j$残っているときの最大化したスコアと考える。$dp[0][0] = 0$とする。
- ターンを考える。$(i+j)$を更新しようとするとき、$A+B-i-j mod 2$が$0$ならすぬけ君のターンである。
- すぬけくんは$dp[i][j]$を更新しようとするとき、`dp[i-1][j] + aの石を取る` か `dp[i][j-1] + bの石を取る`のmaxとする
    - これは、$[i][j]$を更新したい時、maxの元となる方を取れば、期待するscoreに最大化できるから
    - なお、$[i][j]$を更新したい時にその遷移元が$[i-1][j]$か$[i][j-1]$しかいないことは自明
- 対戦相手のターンの時、$dp[i][j]$は$dp[i-1][j]$と$dp[i][j-1]$のminとする。
    - これは、$[i][j]$を更新したい時、minの元となる方を取れば、期待されるscoreを抑えることができるから
この問題では山は上にあるものから入力されているので、取る石はa[A-1-i]などであることに注意すること。

時間・空間計算量は共には$O(AB)$。

## 回答
https://atcoder.jp/contests/tdpc/submissions/29254743

# 3. Chokudai SpeedRun 001: I - 和がNの区間
https://atcoder.jp/contests/chokudai_S001/tasks/chokudai_S001_i
灰色?

## 考えたこと
典型問題。累積和をとり、順番に見ていって、その時点の累積和 - 対象の数値、となる値がそこまでの累積和に存在すればよい。
累積和のテーブルを持った後、つまり、$[0, b)$の分かった後に、どうやって$[a, b)$を求めているんだっけ？を思い浮かべよう。

時間・空間計算量はO(N)。

## 回答
https://atcoder.jp/contests/chokudai_S001/submissions/29252136

# 4. B - 数当てゲーム
https://atcoder.jp/contests/kupc2014/tasks/kupc2014_b
interactiveが珍しいので、出ると茶上位から緑下位かな？

## 考えたこと
- 題意より、素因数分解ゲーであることは明らか。$1000$ までの素数を見ていけばよい。
- この時、ある素数が複数使われていることがあるので、ある素数$p$が使われていた場合、$p^2, p^3, p^4$が含まれているかを確認する。$p^n$はYesだが$P^(n+1)$はNoの場合、$p$は$n$個含まれている。
- このようにして、ans = 1からスタートし、素数$p$を順にforで回し、見つかった素因数を$ans *= p^n$すればよい。尚、ある$p^n$を調べるとき、$ans \times p^n > 1000$であるなら回答になりえないので、適切に打ち切ってよい

クエリの最大数について考察すると, 1から1000までの素数は168個なので、上記のように、打ち切りを入れなくても200回以内で特定ができる。

## 回答
https://atcoder.jp/contests/kupc2014/submissions/29252510
Apple シリコン搭載の Mac で Docker が起動と停止を繰り返す時の解消方法

:::note warn
Docker Desktop 4.5.0 のリリースで Mac M1 の CPU 数が 8 に制限され、本記事で紹介している起動時の不具合が発生しなくなりました。https://github.com/docker/for-mac/issues/6063
:::

先月、Apple シリコン搭載の Mac で、Docker Engine の CPU を最大値の「10」に設定してみました。すると、以下の画像のように起動と停止状態を永遠に切り替え続ける悪循環が始まりました。

![ezgif-3-a143df8ec8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525579/072bd24a-510c-ce39-a216-83f20e215267.gif)

PCの再起動で治らなかったので、止むを得ず Docker CLI を [AppCleaner](https://appcleaner.en.softonic.com/mac "AppCleaner is a free software that lets you completely remove applications, and will deliver a comprehensive list of the files that are associated with each app on your Apple macOS device.") で完全に削除しました。再インストールして立ち上げたところ、何も変わっていません。ご存じの通り、Apple シリコンの Mac でコンテナクライアントが使えないことは、開発者にとって致命的です。自己解決を諦めてサポートに連絡したところ、以下の回答をいただきました。

> Apologies for the inconvenience. Unfortunately the virtualization framework can only use a maximum of 8 CPUs, so it should have been capped at 8. Try setting the CPUs back to 8 in your settings.json file and it should start up.

「ご迷惑をおかけして申し訳ございません。残念ながら仮想化フレームワークは最大8CPUまでしか使用できないため、上限が8になっていたはずです。 settings.jsonファイルでCPUを8に戻してみてください、起動するようになるはずです。」

`settings.json` を数分探したところ、ここにありました。[AppCleaner](https://appcleaner.en.softonic.com/mac "AppCleaner is a free software that lets you completely remove applications, and will deliver a comprehensive list of the files that are associated with each app on your Apple macOS device.") でさえ、このファイルの存在を知らなかったようです。

```
~/Library/Group\ Containers/group.com.docker/settings.json
```

中身を見ると、見覚えのある項目がいくつもあります。

```json
{
  "autoDownloadUpdates": false,
  "cpus": 10,
  "diskSizeMiB": 98304,
  "filesharingDirectories": [
    "/Users",
    "/Volumes",
    "/private",
    "/tmp",
    "/var/folders"
  ],
  "kubernetesEnabled": false,
  "memoryMiB": 16384
}
```

サポートに言われた通り、10 → 8 に戻したところ、無事起動するようになりました。

```diff
- "cpus": 10,
+ "cpus": 8,
```
UiPathで業務用定型文メールを自動化するロボットを作成してみた

##作成背景##
業務課題として、**定型的なメール送信をするための時間が徐々にかかるようになり業務逼迫の原因**となっていた。
そこでUiPathを用いたロボットを作成し自動化することにより、この課題を解決したい。

##ロボット概要##
今回作成するロボットのゴールは、
「**送信したいメールの宛先、件名、添付資料、本文をロボットにより自動作成し下書き保存**」こととする。
送信するかしないかはメール送信者が保存された下書きを目視で確認し、送信は手動で行う。
（想定しないメールの誤送信を防ぐため）

メール作成自動化にために使用するツールはExcelとWordを使用し、
それぞれの使用目的は以下の点について管理・使用する。

- Excel(メール送信先を管理)
 - 宛先名
 - メールアドレス
 - 担当者名
 - 送信日(送信タイミングは「月初」「月末」「３の倍数月の月初」)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752047/322098b3-1b83-eb69-db5f-531afb44b954.png)


- Excel(メール送信に必要な項目を管理)
 - メール送信者のメールアドレス
 - メール送信に必要な本文を記載したWordと資料のパス
 - その他必要に応じてカスタマイズ
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752047/564e51d4-e310-f15e-1403-0e2fab177a2b.png)

- Word（メール作成時の本文を記載）
 - 本文上部にはメール送信先を記載したExcelファイルから会社名と担当者名を取得し転記する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752047/f637e552-8fc4-b5a4-ec76-3451d7a9a598.png)

↓↓↓↓↓ロボットによるメール下書き作成後↓↓↓↓↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752047/69163f78-7930-eb13-3108-df99eb9855ff.png)


##処理概要##
処理順番は、大きく分けて3つ
①初期処理
②主処理
③終了処理
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752047/c58efc37-11ef-3f1e-53f1-4f107cc6b945.png)

①初期処理では、設定ファイル読み込みや各ファイル存在有無の確認を行う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752047/a2f160fc-b120-0f54-d6f6-00e0b3ad43f8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752047/d150e0b8-6765-79ea-8249-b7a0b03d61ff.png)


②主処理では、メール送信先が記載されたExcelファイルからメール送信タイミングに合致する宛先へ下書きを保存する

初めにExcelファイルをdatatable型変数に格納
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752047/bb7688d6-e02f-e78c-72b6-6407e5ef0239.png)

格納した変数内を繰り返し処理
条件に合致した宛先にはメール下書きを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752047/ae3815a4-21dc-9dd7-48ce-266ab6dd8f6e.png)

条件に合致し下書き作成した宛先をリストへ格納
（最後に自分宛てにメール下書き保存したリストをメール送信するため）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752047/6fe68ec4-7bb7-82f2-97ec-ddeabb08df19.png)


③終了処理では、今回下書き保存したメールの宛先リストが記載されたメールを自分宛てに送信
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752047/fbc7299d-701a-974d-bd13-5474a40804f3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752047/59a961ce-fd07-9c58-a82d-14f6863206f9.png)


ロボット実行完了後、
メールの下書きが自身のOutlookに保存されていることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752047/ec24245d-24bd-cba8-a275-951dac7c8bab.png)


##おわりに##
今回初めて作成したロボットを公開致しました。
ロボット作成で意識したことは、「各アクティビティが何をしたいのか？」を明確にすることです。
私がロボット改修でエラー発生時、該当のアクティビティは本来何がしたかったのかが判断つかず、
ワンテンポ遅れたり改修の効率が落ちてしまう経験がありました。
そのため、ログ出力やアクティビティ名を意識し見やすいロボットにすることを心掛けました。

このロボット以外にも業務効率化に貢献できるロボットを作成し、
自身のスキルを磨きつつ、自社でRPAを導入するきっかけにしていきたいと考えております。
Android のパッケージの公開設定

パッケージの公開設定について、ハマったので記事にしておきます。

###### 問題の発生状況

Android 11 より前ではバインドできていたサービスが、下記の warning が出て見つからなくなった。

```console
02-13 17:21:00.089   542  3921 W ActivityManager: Unable to start service Intent { act=com.ykato.sampleservice.ISampleService pkg=com.ykato.sampleservice } U=0: not found
```

###### アプリの構成
サービス （com.ykato.sampleservice）は apk としてインストールしてあり、それを テスターのサンプルアプリ（com.ykato.sampleservicetester）からバインドして使っていました。

###### 原因
下記に、記載がある通り Android 11 から自動的に公開されるアプリが制限されました。

https://developer.android.com/training/package-visibility/declaring?hl=ja

上記により、サービス （com.ykato.sampleservice）が見つけられないため、"not found" となっていました。

###### 対応方法
別のアプリのサービスを使用する場合は、そのパッケージ名を queries 要素内の package 要素のセットに含めることで、サービスを見つけることが出来ます。

今回の場合は、サービスを使う側のサンプルアプリ（com.ykato.sampleservicetester）のマニュフェストに下記のように記述するだけです。

```xml:AndroidManifest.xml
<manifest package="com.ykato.sampleservicetester">
    <queries>
        <package android:name="com.ykato.sampleservice" />
    </queries>
    ...
</manifest>
```
pythonで特定の値を抽出し、値を更新する。

今回は、pythonで、配列から特定の値を抽出し、更新する方法を書いていきます。


まず、今回用いる配列を用意します。


```python:qiita.py
l = list(range(-6, 6))
print(l)
```

出力結果
=>[-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]





​続いて、本題の、上記配列から特定の値を抽出し更新するコードです。概要は以下の通りです。





[(真の値 if 条件式 else 偽の値) for 任意の変数名 in 元のリスト]


```python:qiita.py
​l_replace = ['正の数' if i > 0 else i for i in l] print(l_replace)​​
print(l_replace)

```

出力結果
​=>[-6, -5, -4, -3, -2, -1, 0, '正の数', '正の数', '正の数', '正の数', '正の数']





​上の​​​​​​​​コードを解説していきます。

まず、最初に、更新後の値を指定します。ここでは、'正の数'という文字列を指定しています。

続いて、条件式です。ここでは、if i > 0 として、正の数を抽出しています。

続いて、範囲外の要素をどう扱うか指定します。ここでは、else i として、範囲外の要素は元の要素のままとしています。これを仮に、else '負の数'とした場合、出力結果は、

=>['負の数', '負の数', '負の数', '負の数', '負の数', '負の数', '負の数', '正の数', '正の数', '正の数', '正の数', '正の数']



となります。



続いて、おなじみのfor文で、任意の変数と試行回数を指定します。





以上まとめると、pythonでリストから特定の要素を抽出し更新するコードは以下のようになります。





[(真の値 if 条件式 else 偽の値) for 任意の変数名 in 元のリスト]
DockerとDocker Composeのインストール（2022/02/13）

毎回イチから検索しているので自分用メモ

Raspberry Piでやることが多いです。

# Docker

https://docs.docker.com/engine/install/ubuntu/

```console
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
```

# Docker Compose

バージョン2になって、少し変わった

https://docs.docker.com/compose/install/

```console
sudo curl -L "https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
```
pythonでエンベロープ曲線を計算する

# はじめに
pythonでエンベロープ曲線を描きたくなったので、備忘録として。

# エンベロープ曲線とは
信号包絡線（エンベロープ）は、**信号の上部だけに接するような曲線で、ピーク検出に使います。**
イメージとRコード例は下記が参考になります。

https://www.geidai.ac.jp/~marui/r_program/envelope.html

# pythonコード
pythonでやるには、[scipy.signal.hilbert](https://docs.scipy.org/doc/scipy-1.8.0/html-scipyorg/reference/generated/scipy.signal.hilbert.html?highlight=hilbert)の結果の絶対値を取るだけでできます。

```python
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt

#適当な波形を作成
dt = 0.01
t = np.arange(0, 1, dt)
x = np.cos(2*np.pi * 50 * t)
x *= (1 + 0.7 * np.sin(2*np.pi * 3 * t))

#エンベロープ曲線を作成
x_env = np.abs(signal.hilbert(x))

#作図
plt.plot(t, x, label="x")
plt.plot(t, x_env, label="envelope")
plt.legend()
plt.show()
```

上コードの実行結果が下の図です。

![2ccb5bbc-36a5-4dce-8de5-e988c50381f2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187459/13e010a1-3fea-56c5-89e9-d4ab17718d4a.png)


いい感じ！簡単ですが以上です。

# 実行環境
- Mac OS 11.6.3
- VS Code 1.64.2
- Python 3.9.7
- Numpy 1.20.1
- Scipy 1.6.1
- Matplotlib 3.3.4

# 参考文献
- [信号包絡線の計算、Rの試行錯誤]( envelopehttps://www.geidai.ac.jp/~marui/r_program/envelope.html)
- [scipy.signal.hilbert](https://docs.scipy.org/doc/scipy-1.8.0/html-scipyorg/reference/generated/scipy.signal.hilbert.html?highlight=hilbert)
SQLリンター SQLFluff をチームのコーディング規約に合わせて設定してみる (.sqlfluff)

# はじめに
**SQLFluff**の設定をチームのコーディング規約に合わせるときに、対応するルールを見つけるのが大変だったので、対応表と`.sqlfluff`ファイルの設定値を共有したいと思います。
注意：SQLFluffの説明、基本的な使い方は扱いません。
[SQLFluff](https://github.com/sqlfluff/sqlfluff)
[SQLFluff公式ドキュメント](https://docs.sqlfluff.com/en/stable/index.html)

# コーディング規約とSQLFluffルールの対応表
ルール番号は[SQLFluff Rules Reference](https://docs.sqlfluff.com/en/stable/rules.html#rules-reference)のSpecific Rulesの番号に対応しています。設定値は`.sqlfluff`に記載するパラメータです。

|項目|規約|ルール番号|設定値（ある場合）|
|---|---|---|---|
|全般|予約語の大文字は使用禁止|L010|capitalisation_policy = lower|
|全般|予約語は左揃え|L003, L050||
|全般|インデントはtab（スペース4つ分）|rules|tab_space_size = 4|
|select|カラムが複数あるときは改行すること（1つなら改行は不要）|L036||
|select|カンマはカラムの前につける|L019|comma_style = leading||
|select|カンマのあとにスペースを1つ入れる|L008||
|select|極力アスタリスクの使用を禁止|該当なし||
|select|エイリアスをつける際は`as`をつけること|L012|aliasing = explicit|
|from|エイリアスをつける際は`as`をつけること|L011|aliasing = explicit|
|join|joinはインデントする|indentation|indented_joins = True|
|join|onはインデントする|indentation|indented_using_on = True|
|join|エイリアスをつける際は`as`をつけること|L011|aliasing = explicit|
|with|with句内はインデントをする|L003||
|with|with句の次のselectは一行あける|L022||
|group by|ディメンションとなるカラムはカラム名で記載すること<br>（1, 2のような番号での記載禁止）|L054|group_by_and_order_by_style = explicit|


# チームで利用している.sqlfluffの設定
チームで現在使用しいている`.sqlfluff`の設定値です。SQLFluffはデフォルトで[このように](https://docs.sqlfluff.com/en/stable/configuration.html#default-configuration)設定されています。
デフォルトと異なる設定だけ記載すれば良いのですが、デフォルトと同じ設定でも分かりやすさのために記載を残しているものもあります。

```yml:.sqlfluff
[sqlfluff]
dialect = bigquery
templater = jinja
sql_file_exts = .sql,.sql.j2,.dml,.ddl
exclude_rules = L031

[sqlfluff:indentation]
indented_joins = True
indented_using_on = True

[sqlfluff:rules]
tab_space_size = 4
max_line_length = 100
indent_unit = space
comma_style = trailing
allow_scalar = True
single_table_references = consistent
unquoted_identifiers_policy = all

[sqlfluff:rules:L010]
capitalisation_policy = lower

[sqlfluff:rules:L011]
# Aliasing preference for tables
aliasing = explicit

[sqlfluff:rules:L012]
# Aliasing preference for columns
aliasing = explicit

[sqlfluff:rules:L014]
# Unquoted identifiers
extended_capitalisation_policy = consistent

[sqlfluff:rules:L016]
ignore_comment_lines = True

[sqlfluff:rules:L019]
comma_style = leading

[sqlfluff:rules:L054]
# GROUP BY/ORDER BY column references
group_by_and_order_by_style = explicit
```


# まとめ
チームではデータマート生成処理等の主要なクエリをGitHubで管理しており、プルリクでクエリがコーディング規約に合っているか確認するのも、指摘するのも労力がいるなと感じていましたが、SQLFluffを導入したことでだいぶ楽になりました。現在は、プルリクに合わせてGitHub Actionsで自動でSQLFluffが実行されるようにしています。
SQLFluffはデータアナリスト、データ分析環境に関わる方に非常に便利なツールだと思います。
Java 初心者でもわかる関数型インタフェイス(Suppler編）


#はじめに
Javaではあらかじめいくつかの関数型インターフェイスが用意されてますが、皆さんはいくつご存知でしょうか。今回は代表的な関数型インターフェースのSuplierインターフェースについて解説していきます。
#Supplierインターフェイスとは？
英語を勉強したことがある人なら「Supplier」という単語は何度か聞いたことあると思います。
日本語に訳すと「提供者」という意味になります。
__名前の通り、Supplerは引数を受け取らずに値を戻す関数型インターフェースです。__

get()メソッドを持っています。

:::note info
関数型インターフェイスとはメソッドを一つしか持たないインタフェースのことを言います。
:::

##いつ使うの？
引数を受け取らずに値を戻す時に使います。
具体的にはインスタンスを生成する時や、引数関係なく値を出力する時に利用します。

##どうやって使うの？
関数型インターフェイスというのはラムダ式でよく利用します。
ラムダ式がまだわからないっていう方は下記の記事を参考にしてください。
https://qiita.com/110shun/items/07f96b571532c18d97c0
下記のサンプルコードはラムダ式を使ってArrayListのインスタンスを生成しています。

```main.java
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

public class Main{
	public static void main (String[] args) {
        //ArrayListのインスタンスを生成して参照を戻すラムダ式を代入する
		Supplier<List<String>> supplier = ()->new ArrayList();
        //Suplierインターフェイスのgetメソッドを使うとArrayListを生成できる
		List<String> list =supplier.get();
		   list.add("最後まで拝読頂き");
		   list.add("ありがとうございます");
		   System.out.println(list);
	}
}
```
```
結果
[最後まで拝読頂き, ありがとうございます]
```

#まとめ
Supplerは引数を受け取らずに値を戻す関数型インターフェースです。
get()メソッドを持っています。

##参考文献
・[Java 関数型インターフェースのサンプル(Supplier)](https://itsakura.com/java-supplier)
【DOS】ワンライナーで連続してコマンドを実行する

# はじめに

Linuxだと以下のようにワンライナーでコマンドを実行することがありますが、同じようなことをコマンドプロンプトでも実現できないかと思い、実装方法を検討してみました。

```bash:
[nkojima@myhost ~]$ date; md5sum sample.pdf
```

# 実装方法

* Windowsでは、`コマンド1 & コマンド2 & コマンド3...` という形になります。
  * Linuxだとコマンドの区切り文字（セパレーター）は「;」を使いましたが、コマンドプロンプト上では「&」になるようです。
* コマンド1の結果に関わらずコマンド2を実行する場合は「&」、コマンド1が成功した場合に限りコマンド2を実行する場合は「&&」を使います。

```dosbatch:
C:\Users\NKOJIMA>echo %time% & certutil -hashfile D:\ISO\AlmaLinux-8.3-x86_64-dvd.iso MD5
17:27:00.47
MD5 ハッシュ (対象 D:\ISO\AlmaLinux-8.3-x86_64-dvd.iso):
2734fcd999fbe9d7e81d4dae18db6b7b
CertUtil: -hashfile コマンドは正常に完了しました。
```

# 感想

* Linuxとはコマンドの区切り文字が違うだけなので、覚えやすいのではないかと思います。
* 調べてみた本人が言うのは変ですが、そもそもコマンドプロンプトは使いづらいのでわざわざワンライナーを使わないような気がします。
  * もしワンライナーを使うとしたら、今ならPowerShellだと思います。


# 参考URL

* [複数のコマンドを続けて実行する](https://www.javadrive.jp/command/action/index1.html)
* [bash - コマンドセパレータ](https://anmino.hatenadiary.org/entry/20090730/1248903862)
* [& (アンパサンド) - DOS コマンド一覧](https://www.pg-fl.jp/program/dos/doscmd/str_and.htm)
* [&& (論理積) - DOS コマンド一覧](https://www.pg-fl.jp/program/dos/doscmd/str_l_and.htm)
React の useReducer にて reducer が 2回 dispatch される

# 問題

React の Reducer がなぜか 2回 Dispatch される。
同じ処理が　2回 実行されるため、予期しない結果となる。

# 原因

Reducer が純粋関数でないため。

正直、この原因を知ったところで根本解決は難しい。
以下に回避策をまとめる。

# 回避策

以下の3つがある模様。

1. Strict Mode を解除する
1. reducer を `useCallback` で囲む
1. reducer をメイン関数の外に出す？

今回は個人開発ということもあり、内容を確認した上で 1 を選択しました

### ① Strict Mode の解除

Strict Mode の解除に関しては、内容を理解した上で自己責任で行いましょう。
特に会社のプロダクトの場合は本当に問題ないか、要検討です。
詳細は [Strict Mode](https://reactjs.org/docs/strict-mode.html) に書いてあります。

やることは `<React.StrictMode>` を削除するだけです。

#### 修正後

```react:index.tsx
ReactDOM.render(
  <MyComponent>,
  document.getElementById("root")
)
```

#### 修正前

```react:index.tsx
ReactDOM.render(
  <React.StrictMode>
    <MyComponent>
  </React.StrictMode>,
  document.getElementById("root")
)
```

### ② useCallback でラップ

こちらは試したが、自分の環境では問題を解決できなかった。
一応記載。

```react
useReducer(useCallback(reducer), initState)
```

### ② reducer をメイン関数の外に出す

以下で言及されていましたが、正直意図がわからず。
コンポーネント関数の外に出せという意味でしょうか？

自分の場合は最初からコンポーネント関数の外に出していたため、解決策には成りえませんでした。

https://github.com/facebook/react/issues/16295#issuecomment-518919476 

# 背景など

### 日本語で調べても情報が全然出てこない

日本語で検索生ても全然情報が出てきません。
英語で検索すると次の Issue がヒットしました。

### 解決に至った Issue

[useReducer dispatch calls reduce twice #16295
](https://github.com/facebook/react/issues/16295)

### Issue の議論の要約

上記の Issue で議論を要約するとこんな感じになります。

- 原因は Reducer の関数が純粋でないためです
- ある特定の条件下で Reducer が 2回 Dispatch されるのは **仕様** です
  - Reducer は純粋関数であるべきです
  - 純粋関数であれば、2回 呼ばれても問題ありません
- この情報はドキュメントに書くべきでは？

### React はドキュメントの内容が少ない

これは個人的に感じているだけです。
React のドキュメントは情報量が少ないように思います。

例えば [useReducer](https://reactjs.org/docs/hooks-reference.html#usereducer) を例に取ってみても、

- 引数の型は何か？
- 戻り地の型は何か？
- それらの型のフィールド・メソッドは何か？
- どの条件でコンポーネントは再レンダリングされるのか？
- 子コンポーネントまで再レンダリングされるのか？

などが書かれていません。
API Reference と言っていますが、個人的にはもっと格式張った内容を把握したいです。

ここまで書いていて「ソースコードを読め」という天啓が降って気がしましたが、辛いですね。
自分もまだまだですね、、、。

### 自分が書いた Reducer は純粋関数なはずであるが、、、？

そもそも純粋関数とは、「引数が同じであればm常に結果を返す関数」のことです。

そのオブジェクトの内部状態に結果が影響されません。
内部状態と行っているのは、フィールドやメンバーのことです。
受け取った値が同じであれば、常に同じ値を返します。
このような特徴を「副作用がない」とも表現します。

自分が書いた Reducer は引数のオブジェクトのメソッドを手続き的に呼び出すだけなんので、純粋関数のはずです。

そもそも今回自分が遭遇した減少としては、「同じ処理が2回呼ばれた結果、単純に 2回 処理されてしまった」というものです。
Reducer で管理している State のあるフラグを切り替える処理だったのですが、2回 呼ばれた結果元に戻ってしまいました。
true の場合は false を返し、false の場合は true を返す、副作用はないはずです。

何か見落としがあるのかもしれませんが、あまり今回の現象の全貌を理解できた気がしません。 

# 最後に

個人開発を頑張っているので、ぜひ twitter 見てみてください。
毎日 1 コミットを実践中です
フォローされると泣いて喜びます😭

https://twitter.com/HitoroOhira
Doozy UI Manager を使ってみた

UI ツールの大御所だと思われる[Doozy UI Manager](https://assetstore.unity.com/packages/tools/visual-scripting/doozy-ui-manager-203601)を昔購入していたので、
画面遷移をノードベースで管理できることもあり試してみました。
画面操作のタッチやスワイプとも連携できるので、開発効率アップを期待していました。

# 結論
あえて買ってまで使う必要はない気がしました。
ノードベースで管理できるのですが、管理が楽になるイメージが沸きませんでした。

以下実現したいのであれば、検討してもいいかもしれません。

* UIで人が踊るみたいなアニメーションを組みたい
* 擬音語で表現するような（サッとか、シュッとか）UIを組みたい
* Androidの戻るボタン対応、履歴で戻りたい

# 使ってみようと思った動機
0. いつぞやのメガバンドルに入っていた、からの
1. 画面遷移をノードベースで管理可能（そう）
2. UIのアニメーションも豊富で表現力が豊か（そう）
3. 画面操作のハンドリングが可能（そう）

# 使ってみた感想
2，3日程度使ってみた感想です。

## 画面遷移のノードベースでの管理
ノードベースで組める、がしかし中々操作感が手ごわい感じでした。

* 直観的に使いやすい感じではなかった
* 細かい点が設定しやすい感じはしなかった
* ただ閉じるということがしたいだけなのに、最初はよくわからなかった

細かいところとかもしれないがAndroidのバックボタン対応、履歴を戻れるのはいいと思った。
割とほしい機能だと思うのだが、これまでになかったなと思いました。

## UIのアニメーション
とても良く、簡単に色々表現できるなと思った。

* 下からサッと出てくるメニュー
* 押したらボインっと色を変えながら反応するボタン
* 上記したような、擬音語を使って表現したいメニューが比較的簡単に作れる
* サンプルもここが一番充実しています

## 画面操作のハンドリング
ここは未確認で終えてしまいました。

## その他の注意
* サンプルもあるが多いとは言い難い。
* ネットを検索しても情報がヒットしない
* v4.0.0が出たのでが2022年初頭（2021年末だったかも）。v3の機能が実装されていなかったり、色々不便な点が多そうで、発展途上が否めない。
* dicordでの回答は多くない。Scrollbarの使い方がわからずdiscordで調べたら、ある人が質問していたが完全に放置されていた。更新はされているものの、回答をもらえるとは限らない。
* Riderとの親和性が悪い。ButtonClickedにイベントをインスペクター上で設定しても、Riderから見たときに使われていないように見える。
* UI View Listener の設定が誤ってされていたせいか、UI Button の Pointer Click が正常に動作しないことがあった。ただ誤って設定されていても、正常に動作することもあることから、処理順や何かが影響しているのかもしれないが未調査。
* ScrollbarがUnityデフォルトのScrollbarと異なり、ISelecatbleしか拡張していない。そのためScrollViewを独自実装して作る必要がある。
* 英語のドキュメント、YouTube動画しかない。
* Unityの新しいInputSystemを利用する
CSS letter-spacing, white-space

letter-spacingにて文字間隔を調整する中であえてを大きく間隔取った。
かな文字はwidthで指定したサイズの中で折り返される、一方でalphabetは折り返されない。
下記のイメージ。

・り   ん   
ご
・a   p   p   l   e   s

対策：white-space:  nowrapを使うことで下記のようにかな文字も折り返されることなく表示される。
・り   ん   ご
・a   p   p   l   e   s

```CSS
ul{
   
   max-width: 200px; 
   font-size: 20px;
   line-height: 1;
   letter-spacing: 4em;
   white-space: nowrap
}
```
Tableを作成しセルの中で文字列が折り返してしまう時など、レイアウトを整える時に使えるかも。
scopeとクラスメソッド

実務でscopeというものをちゃんと理解していなかったので、記録しておこうとおもいます

## モデルのscope
モデルへのメソッド呼び出しとして、よく使われるクエリをまとめたメソッドです。
実際に使い方を見てみましょう

```
class User < ApplicationRecord
  scope :hoge, -> { where(name: 'hoge') }
end
```
これは、以下のコードと同じです。
```
User.where(name: 'hoge')
```
このコードの名前をhogeという名前で使えるんです。つまり、
```
User.hoge
```
というメソッドが使えるようになります。

これのメリットは、メソッドが長くなった時可読性が落ちないし、直感的になりますよね

公式化すれば、以下のようになります
```
class モデル名 < ApplicationRecord
  scope :スコープ名, -> { 条件式 }
end
```

## scopeとクラスメソッドの違い
クラスメソッドは、以下のようなコードです
```
class モデル名 < ApplicationRecord
  def self.メソッド名
    条件式
  end
end
```
スコープとクラスメソッドはnilを返す時の動きが違います
scopeのときは、返ってくる結果がnilのとき、allメソッドが適用される
クラスメソッドのときは、返ってくる結果がnilのとき、nilが適用される

以上です。何か間違いがございましたら、ご教示いただけますと幸いです。

【参考資料】

https://railsguides.jp/active_record_querying.html#%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97

https://pikawaka.com/rails/scope

https://www.sejuku.net/blog/26994
Laravelでデータベーステストがしたい

メモがてら

#環境
Laravel 8.X
PHP 8.0.9
MySQL 8.0.27

自分はUbuntu上で構築したDocker環境でLaravelsailを使って開発

#テスト用DBの作成
[こちら](https://qiita.com/Kent2525/items/27be25a1cc1af9b04f25)の記事を見ながら作成。

Laravel SailだとMysqlでのログインで少し止まった。ユーザー権限の問題らしく、ユーザー名をSail→rootに変えてとりあえず解決。

#ダミーレコードの準備
ダミーレコード（テストデータ）を準備する。
ダミーレコードをデータベースに一括挿入するには「**Seeder**」を使う。しかし、Seederはあくまでダミーを挿入する仕組みであって、量産する必要があるなら「**Factory**」を使う。

([こちら](https://coinbaby8.com/laravel-seeder-factory-faker.html)のサイトを参考)

##Seeder
データベースの初期値設定をする（種をまく）仕組み。

###Seederの生成

~~~
php artisan make:seeder UserSeeder
~~~ 
でシーダークラスを定義できる。database/seeders を確認。

###Seederを使ったモデル生成
シーダー内で**DB::table->insert**等を使ってレコード作成の記述をしておき、

~~~
php artisan db:seed

php artisan db:seed --class=UserSeeder //個別指定
~~~
で実行、生成可能。
詳細は[公式ドキュメント](https://readouble.com/laravel/8.x/ja/seeding.html)を参照

##Factory
大量レコードを生産できる仕組み。あくまでSeederやテスト上で実行されるものであり、コマンドライン上で実行するものではない。

###ファクトリの生成

~~~
php artisan make:factory UserFactory
~~~
上の様なコマンドでFactoryファイルを生成できる。database/factories を確認。
「User」モデルを大量生産したいとき、「UserFactory」の名前にすることで、Userモデルを読み込んだ状態で生成される。

###モデルの定義
Factoryファイル内のdefinitionメソッドで各カラムの生成する内容を定義することができる。

```php:database/factories/UserFactory.php
public function definition()
    {
        return [
            'name' => $this->faker->name(),
            'email' => $this->faker->unique()->safeEmail(),
            'email_verified_at' => now(),
            'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
            'remember_token' => Str::random(10),
        ];
    }
~~~

fakerプロパティを介すことで、様々なランダムデータを生成することができる。詳細は[こちらのライブラリ](https://fakerphp.github.io/)から。


###Factoryを使ったモデル生成
後は、テストファイルやシーダーファイルで以下の様な記述をする。

```php
use App\Models\User;

//1つ生成
$user = User::factory()->make();

//3つ生成
$users = User::factory()->count(3)->make();
```

countメソッドを使えば複数個生成できる。

リレーション等の設定もできる。より詳細は[公式ドキュメント](https://readouble.com/laravel/8.x/ja/database-testing.html#defining-model-factories)を確認

##テストの準備
Artisaコマンドでテストを作成できる。

~~~
//Featureテスト
php artisan make:test UserTest

//Unitテスト
php artisan make:test UserTest --unit 
~~~

Featureテストならtests/Feature、Unitテストならtests/Unit を確認。

##テストコードを記述
まずは先頭に**use RefreshDatabase**を記述しておく

```php:tests/Feature(Unit)/UserTest.php
class UserTest extends TestCase
{

+    use RefreshDatabase;
```
Illuminate\Foundation\Testing\RefreshDatabaseトレイトだが、使用するだけでデータベースをテスト終了後リセットしてくれる。
ただし、メインのDBでテストをすると、ダミーレコードじゃないものまでリセットされてしまうのでテスト用DBの設定はしっかり行う。

あとはテストコードを記述していく。
Laravelが提供しているアサ―トをいくつか載せる。

 - **assertDatabaseHas**

データベース内のテーブルに、指定したデータが存在するかをチェックする

```php 
$this->assertDatabaseHas('users', [
    'email' => 'sally@example.com',
]);
```

 - **assertDatabaseMissing**

データベース内のテーブルに、指定したデータが存在しないかをチェックする

```php 
$this->assertDatabaseMissing('users', [
    'email' => 'sally@example.com',
]);
```

他は[公式ドキュメント](https://readouble.com/laravel/8.x/ja/database-testing.html#available-assertions)を参照

##最後に
何か間違っている、足りない等あれば教えてください。
Next.jsのファビコンを非表示にする

メモです。
プロジェクトで、このデフォルトファビコンを削除、変更したいなぁって時にふりかえります。

## ファビコンとは？

これ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381710/1860df95-dae8-58ed-78f2-b3de0b874d69.png)

Next.jsのアプリケーションを作成するとこんなのがデフォルトで表示されているはず
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381710/e98aa24a-9a11-9b46-bbcb-6e68b509b82a.png)



## 削除するには？

以下のパスにある、ファイルの `<link rel="shortcut icon" type="images/x-icon" href="/favicon.ico" />` href部分を変更すればOK。
他のファビコンを表示したい場合は、`<project_name>/public/favicon.ico`の画像ファイルを変更すればOK.

```tsx:<project_name>/pages/_document.tsx
import Document, { Html, Head, Main, NextScript } from 'next/document';

export default class MyDocument extends Document {
  render() {
    return (
      <Html>
        <Head>
          <meta charSet="utf-8" />
          <link rel="shortcut icon" type="images/x-icon" href="/favicon.ico" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

```
Go言語_rune

# Go言語_rune


```golang:rune.go
package try

import "fmt"

func Run_Rune() {
	Rune("Hello,世界!")
}

func Rune(s string) {
	str := []rune(s) // str []rune
	for i, r := range str {
		fmt.Printf("i%d r %c\n", i, r)
	}
	fmt.Println("------")
	for i, v := range s { // var v rune
		fmt.Printf("i%d r %c\n", i, v)
	}
}
```

### 実行結果

```terminal:
@Mac feb_twelve % go version
go version go1.14.1 darwin/amd64
@Mac feb_twelve % sw_vers
ProductName:    macOS
ProductVersion: 12.1
BuildVersion:   21C52
@Mac feb_twelve % tree
.
├── go.mod
├── main.go
└── try
    └── rune.go

@Mac feb_twelve % go run main.go
i0 r H
i1 r e
i2 r l
i3 r l
i4 r o
i5 r ,
i6 r 世
i7 r 界
i8 r !
------
i0 r H
i1 r e
i2 r l
i3 r l
i4 r o
i5 r ,
i6 r 世
i9 r 界
i12 r !
@Mac feb_twelve %
```

## 解説


```golang:.goenv/versions/1.14.1/src/builtin/builtin.go
// rune is an alias for int32
type rune = int32
```


>To make things dependable, there are normalization techniques that guarantee that a given character is always represented by the same code points
~
“Code point” is a bit of a mouthful, so Go introduces a shorter term for the concept: rune
by The Go Blog

## 参考

[Slice string into letters - stackoverflow](https://stackoverflow.com/questions/18556693/slice-string-into-letters)
[Strings, bytes, runes and characters in Go - The Go Blog](https://go.dev/blog/strings)
MotionLayoutの例を試してみる(ImageFilterView)


前回はカスタム属性をやりました。
[カスタム属性](https://qiita.com/yuta317/items/a1fe49c5b705d442d484)

今回はImageFilterViewを試していこうと思います。

# 公式リファレンス
https://developer.android.com/training/constraint-layout/motionlayout/examples?hl=ja

https://developer.android.com/training/constraint-layout/motionlayout/ref?hl=ja

# ImageFilterView

今回はビューの移動に伴ってビューの彩度の値を変更しようと思います。

リンク先に公式サンプルがあります。
[ImageFilterView](https://developer.android.com/training/constraint-layout/motionlayout/examples?hl=ja#imagefilterview_-_image_transition)


``` motion_imagefilter.xml
<androidx.constraintlayout.motion.widget.MotionLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/motionLayout"
    app:layoutDescription="@xml/scene_motion_imagefilter"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.constraintlayout.utils.widget.ImageFilterView
        android:id="@+id/image"
        android:src="@drawable/sunset"
        android:scaleType="centerCrop"
        android:layout_width="match_parent"
        android:layout_height="300dp" />

</androidx.constraintlayout.motion.widget.MotionLayout>
```

# ImageFilterView
彩度、輝度、色温度など画像に対しての設定ができる便利なViewです。



``` scene_motion_imagefilter.xml
<MotionScene
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto">

    <Transition
        motion:constraintSetStart="@+id/start"
        motion:constraintSetEnd="@+id/end"
        motion:duration="1000">
        <OnSwipe
            motion:touchAnchorId="@id/image"
            motion:touchAnchorSide="top"
            motion:dragDirection="dragUp" />
    </Transition>


    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@id/image"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="1" />
        </Constraint>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@id/image"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent">
            <CustomAttribute
                motion:attributeName="Saturation"
                motion:customFloatValue="0" />
        </Constraint>
    </ConstraintSet>

</MotionScene>
```

# customFloatValue
ImageFilterViewのSaturation対して、customFloatValueの値をstartでは1、endでは0を設定するとendは白黒になり、startはカラーになります。


ちなみにCustomAttributeのattributeNameをBrightnessに変えてみると明るさが変わります。
※Brightnessに0を設定すると真っ黒です。

```
<CustomAttribute
    motion:attributeName="Brightness"
    motion:customFloatValue="1"/>
```

以上です！
次はキーフレームの位置を試そうと思います。
MBTiles 実用メモ

[MBTiles](https://github.com/mapbox/mbtiles-spec) に関する実用メモです。

# タイルテーブル `tiles`
- zoom_level
- tile_column
- tile_row
- tile_data
歴史的経緯により、tile_row は `2 ** z - y - 1` という換算が必要

# メタデータテーブル `metadata`
- center
- format e.g. pbf
- maxzoom
- minzoom
- name
- json
スライド作りのベストプラクティス

# overview
- スライドはreveal.js使って作るのがベストっぽい
   - LTとかのスライド何で作ろっかなーと思ってて色々したべてここに辿り着きました
- 安全に素早く汎用的なスライド作ってGithubで管理できるからね
   - slideを作って管理する上での条件
      - [x] テキストデータで管理したい（Githubのレビュー等を考えて）
      - [x] マークダウンで作りたい（描き慣れているので）
      - [x] ローカルリソースで管理したい（CDNとかじゃ安心して眠れない）
      - [x] ローカルファイルをブラウザで動かしたい（公開したくない情報もある）
   - できればGithubのマークダウンファイルを管理する感じでスライドを管理したいわけです
- Reveal.jsを最小限で使う
   - Reveal.jsなら上の条件を全て満たせるからばっちぐーですね
   - Reveal.jsの公式からリソースをDLして必要なもの以外を全て削って以下の改装となりました
      - index.html
      - plugin
      - dist



# Get started!
### Reveal.jsをダウンロード
1. [公式サイト](https://revealjs.com/installation/#basic-setup)からリソースをダウンロード
   1. [公式サイトのダウンロードリンク（clickでDLされます）](https://github.com/hakimel/reveal.js/archive/master.zip)
   1. `reveal.js-master`っていうzipファイルがダウンロードされるはずです
1. ディレクトリ名を変更
   1. `reveal.js-master` => `slide`とかにしておくといいかも


### 不要なファイル等を削除
1. 以下のファイル以外を削除

```diff
plugin
- css
- demo.html
dist
- examples
- gulpfile.js
index.html
- js
- LICENSE
- package-lock.json
- package.json
- README.md
- test
```

こんな感じのファイル構造になった成功

```
plugin
dist
index.html
```


### スライドを作成
1. index.htmlを編集
1. 編集方法は公式サイトを参照
   1. [HTMLで書く場合](https://revealjs.com/markup/)
   1. [マークダウンで書く場合](https://revealjs.com/markdown/)


# References
- https://revealjs.com/
QR読込範囲指定

# はじめに
QR読取時に読取範囲を指定する必要があったのだが、なかなか思うように範囲を設定できなかったのでログに残しておく。

# CGRect直で読取り範囲を算出（失敗）
`AVCaptureMetadataOutput`インスタンスの`rectOfInterest`プロパティに`CGRect`インスタンスを使って読取範囲を指定するサンプルをいくつか見つけたのだが、意図通りに読取範囲を指定することができなかった（Y軸にずれがある）。

```swift
// CGRectで指定しているサンプル
self.metadataOutput.rectOfInterest = CGRect(x: frame.minY,y: 1-frame.minX-frame.size.width, width: frame.size.height,height: frame.size.width)
```
［参考］

 - [Swift5 QRリーダーの実装　脳死コピペ用](https://www.letitride.jp/entry/2019/12/03/125802)
 - [iOSでバーコードを読み取る](https://swiswiswift.com/2018-09-17/)
 
［難点］

1. 座標とサイズの指定が割合の値である。
2.  [カメラの向きが横（Landscape）になっており、xyが反転している](https://qiita.com/tomosooon/items/9cb7bf161a9f76f3199b)。
3. 実機による検証で、実際にどこが読み取り範囲になっているのかを確認する方法がわからない（分かる人がいたら教えてください）

自分としては、1.と2.については配慮して値を割り出したつもりだったのだが意図通りの動作にならない。

# `AVCaptureVideoPreviewLayer`の`metadataOutputRectConverted`メソッドを使用（成功）
`rectOfInterest`の設定値を、自力で割り出すのではなく、`AVCaptureVideoPreviewLayer`の`metadataOutputRectConverted`メソッドで変換すると意図通りに読取り範囲を指定できた。

```swift
// preview: AVCaptureVideoPreviewLayerインスタンスを入れるUIViewインスタンス
// previewLayer: AVCaptureVideoPreviewLayerインスタンス
// metadataOutput: AVCaptureMetadataOutputインスタンス

let size = 240
let screenWidth = preview.frame.size.width
let screenHeight = preview.frame.size.height
let xPos = (CGFloat(screenWidth) / CGFloat(2)) - (CGFloat(size) / CGFloat(2))
let yPos = (CGFloat(screenHeight) / CGFloat(2)) - (CGFloat(size) / CGFloat(2))
let scanRect = CGRect(x: Int(xPos), y: Int(yPos), width: size, height: size)

// rectOfInterestに入れる値をAVCaptureVideoPreviewLayerインスタンスのmetadataOutputRectConvertedメソッド経由で算出
self.metadataOutput.rectOfInterest = self.previewLayer.metadataOutputRectConverted(fromLayerRect: scanRect)
let v = UIView()
v.layer.borderWidth = 1
v.layer.borderColor = UIColor.red.cgColor
v.frame = scanRect
preview.addSubview(v)
```

［参考］
 - [AVCaptureMetadataOutput().rectOfInterest not Working](https://stackoverflow.com/questions/55776774/avcapturemetadataoutput-rectofinterest-not-working)
DatabricksにおけるAWS CodeCommitを用いたバージョン管理

[AWS CodeCommit version control \| Databricks on AWS](https://docs.databricks.com/notebooks/aws-code-commit-version-control.html) [2022/2/11時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

> **訳者注**
この記事は[Databricks ReposによるGit連携](https://qiita.com/taka_yayoi/items/b89f199ff0d3a4c16140)におけるAWS CodeCommitの設定方法を説明するものです。

このガイドでは、AWS CodeCommitによるバージョン管理をどのように設定するのかを説明します。バージョン管理の設定には、お使いのバージョン管理プロバイダーにアクセスするクレディンシャルの作成とDatabricksへのクレディンシャルの保存が含まれます。

# HTTPS Gitクレディンシャルを作成する

1. AWS CodeCommitで、お使いのリポジトリにアクセスするためのHTTPS Gitクレディンシャルを作成します。[AWS CodeCommit](https://docs.aws.amazon.com/codecommit/latest/userguide/setting-up-gc.html)のドキュメントを参照ください。関連づけられるIAMユーザーには、リポジトリに対する"read"と"write"の権限が必要となります。
1. パスワードをメモしておきます。次のステップでDatabricksにこのパスワードを入力します。

# お使いのパスワード、ユーザー名をDatabricksに保存する

1. 画面の左下にある![](https://docs.databricks.com/_images/user-settings-icon.png)**Settings**をクリックし、**User Settings**を選択します。
1. **Git Integration**タブをクリックします。
1. すでにクレディンシャルを入力している場合には、**Change settings**ボタンをクリックします。
1. Git providerドロップダウンから**AWS CodeCommit**を選択します。
1. **HTTPS Git password**フィールドにお使いのパスワードを貼り付けます。
1. **Git provider username**にご自身のユーザー名を入力し**Save**をクリックします。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
Prismのソースコードをちゃんと読む（02-Region）

今まで何となくで触っていたPrismでしたが、一度しっかりソースコードを読み込んで見ようと思ったので記録として残します。  
読み返した時にチートシート的な使い方ができるよう、ソースにコメントを入れていくスタイルでいきます。
# 02-Region
今回は[サンプル02-Region](https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/02-Regions)を読みます。
## Prismの用語✨🌈
### Region📟
画面領域の単位。一つのShell(=Window)に一つもしくは複数のRegionを配置できる。
https://elf-mission.net/programming/wpf/getting-started-2020/step05/#Module_View

## ソースコードを読む📑
今回はManiWindowに挿入されたRegionとRegionにViewを登録する方法まで見る
まずはサンプルの`MainWindow.xaml` と `MainWindowViewModel.cs`

```csharp
<!--MainWindow.xmal-->
<Window x:Class="Regions.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        Title="Shell" Height="350" Width="525">
    <Grid>
		<!--「ContentRegion」という名前の領域ここに他のViewを入れられる。-->
        <ContentControl prism:RegionManager.RegionName="ContentRegion" /> 
    </Grid>
</Window>

```

```csharp
// MainWindowViewModel.cs
    public class MainWindowViewModel
    {
        private readonly IRegionManager _regionManager;

        public MainWindowViewModel(IRegionManager regionManager)
        {
            _regionManager = regionManager; // Boostrapper内でIRegionManagerはRegionManagerにDIされているので引数に入れるだけで実態を取得できる
            _regionManager.RegisterViewWithRegion("ContentRegion", typeof(Views.SubView1)); // "ContentRegion"というRegionに"SubView1"というViewを入れている。
        }
    }

```

IRegionManagerの実態[RegionManagerクラス](https://github.com/PrismLibrary/Prism/blob/39cec905caacfaf0026f98ebc73aa50aa9a1a34f/src/Wpf/Prism.Wpf/Regions/RegionManager.cs) で今回関係ありそな箇所を読む。

## RegionManagerにできること📟
```csharp
	// やってることは
    public interface IRegionManager
    {
        IRegionCollection Regions { get; } // 一つのRegionManagerView(IRegion)のコレクションを持つprivateクラス。
        IRegionManager CreateRegionManager(); // 新しいRegionManagerをreturn。
				// AddToRegion()とRegisterViewWithRegion()はどちらもViewを登録するメソッドだが
        IRegionManager AddToRegion(string regionName, object view); // 既存のRegionにViewを加える。
        IRegionManager RegisterViewWithRegion(string regionName, Type viewType); // RegionをDIで明示的にDIしていなくても、RegionをDIしViewをそのRegionに加える
					var regionViewRegistry = ContainerLocator.Container.Resolve<IRegionViewRegistry>(); // RegionViewRegistoryクラス(RegionとList<View>の組み合わせを持つクラス)
					regionViewRegistry.RegisterViewWithRegion(regionName, viewType); // regionNameのRegionにviewType(DIコンテナに登録してある)を登録
					return this;
        IRegionManager RegisterViewWithRegion(string regionName, Func<object> getContentDelegate); //Viewクラスを返すFunc<object>を入れる
			
				// 以下は画面へ遷移用メソッドRequestNavigate()のオーバーロード
    }


```

# まとめ
`AddToRegion()` と `RegisterViewWithRegion` の使い分けがややこしく、`AddToRegion`の場合は`Region`を事前に実体化させたものを使うかDIさせて置く必要があるようなのですが、 手元の環境で動かすとどうも`Region`の登録がうまく行かないようで例外がスローされてしまいました。
`RegisterViewWithRegion` で`Region`を登録し、同一の`Region`を使えばViewを登録できるのかと思えばこれもエラー。

`Region`を使いまわしたい時などに使うのかと思ったのですが、いまいち使い道がよくわかりませんでした。
今後ソースを読む中で理解が深まれば追記したいと思います。
JSTQB Foundation Level 試験勉強方法振り返り

# 概要
JSTQB Foundation Level 受験時にやってよかったこと・反省点を個人的にまとめたものです。
（合格したかはまだ不明です。）

[追記] 無事合格しました🎉

# JSTQBとは
ソフトウェアテスト技術者資格認定の団体。資格試験は Foundation Level, Advanced Level に分かれている。
QAの採用基準としてJSTQBの資格保有を最低条件にしている会社も増えつつあり、年々受験希望者が増えている。
申込で争奪戦になるため受験ハードルが高いが、近々CBTでの受験も可能になると発表があったので期待したい。
http://jstqb.jp/

# 勉強方法
## トータルの勉強時間
1日2~3h, 一か月間勉強した。（トータル80h程）

## 勉強スケジュールの理想と現実
実際の勉強工数の反省を踏まえて、理想のスケジュールと実際どうだったかについて書く。

### 最初の1週間
- 理想
    - 1週間でシラバスを全て読めると理想。シラバスを読んでも頭に入ってこないので、完璧でなくてもざっと全体を把握できればOK。
- 実際
    - シラバスが読みづらく、半分しか読めなかった。
    - 最初に作ったシラバス要点まとめノートは要らなかった
        - あまり役に立たないノートになってしまい時間の無駄になった。最初はとにかくシラバスを一周読み切ることに注力すればよかった。
        - シラバスの言い回しがそのまま問題になっていることがほとんどなので、理解の浅いまま自分なりに要約してしまうとシラバスと違う内容のノートになってしまい、問題を解けなくなってしまうため。
    - シラバスを読みきった後に問題を解きながら分からないところをノートにまとめていくのは良い。

### 第2週目〜3週目
- 理想
    - 問題を解く→シラバスや参考資料を読んで理解する→問題を解く　を繰り返し、分からないところ・理解の浅いところを洗い出す。
    - 「[テス友](https://www.qbook.jp/info-testomo/)」が難易度的にちょうどよく、わかっていない項目を洗い出せるのでおすすめ。無料で繰り返し利用できるし問題数も結構多い。
- 実際
    - シラバスを読み切るのに第2週までかかった。さっさと読んで問題に取り掛かかればよかった。

### 第4週目
- 理想
    - 問題を解いて、分からない箇所を潰していく。
    - 「[スクエアリングサービス](http://squaring.jp/others/index.jsp
)」のテスティング基礎コースはテス友よりも少し難易度が高く、試験直前のタイミングではかなりおすすめ。
- 実際
    - テス友で90%程正答していたが、試験日2日前にスクエアリングサービスを見つけてやってみたところ半分くらいしか合っていなくて絶望しかけた。課金コースで徹底的に問題を解きたかったが、入金後即利用できるわけではなさそうで結局利用しなかった（入金確認に時間がかかるような記載があった）
    - 次回もし受験する場合は、試験申込完了後にすぐにスクエアリングサービスの課金コースに申し込むと思う。

## おすすめ教材
#### シラバス
シラバスが全て。シラバスをとにかく読み切るのが大事。
Extensionは試験範囲に含まれないので、対策する必要はない。
用語集はテス友にも付属しているので特に必要ない。

#### JSTQB® 認定テスト技術者資格 Foundation Level 試験対策講座
シラバスの概要の解説動画。トータル140分。
この動画だけでの合格は無理だと思うが、概要が簡潔にまとめられているため動画を見てからシラバスを読むと理解しやすくなった。
シラバス読破に苦労している方におすすめ。
https://www.qbook.jp/event/20211014_1250.html

#### テス友
シラバスの章別に正答率を確認できるので、理解の浅い箇所を洗い出すのに最適。
https://www.qbook.jp/info-testomo/

#### スクエアリングサービス
難易度高め。実際の試験と同等レベル。
http://squaring.jp/others/index.jsp

# 試験当日の注意点

## 持ち物
- シャーペンを2本持っていくと安心。（1本だともし落としたら拾ってもらえるまで時間のロスになる）
- 会場が寒かったため、カーディガンを持っていくと良い。

## 試験前
- 座席は決まっているので注意。どこに座ればいいか分からない場合は試験官に聞くと教えてくれる。

## 試験中
- 解答が怪しいところは見直しできるように目印をつけておく。
- マークシート式のため、解答箇所がずれていないかこまめにチェックする。

# 受験の感想
- テストに関する業務を体系的に学ぶ機会になり、価値のある受験だった。
希望と懸念で明らかになるチーム

## 現状

これまでのふりかえり手法は、Sprintの良かったこと・改善点をTrelloを使用し、列挙してもらい、それについて浅く広く話し合い、次Sprintでやることを話すということを行っておりました。
この手法で、ふりかえりが出来ているのか心配になった僕は、希望と懸念というフレームワークを使用して、ふりかえりを行いました。

## これまでのふりかえりのふりかえり

* 良かったこと
    * そのSprintでどう感じてたか？がある程度わかる
    * ある程度、時間に応じて話すべき内容と話さなくてよい内容が決められる
    * 次どうしたら良いか？まで話し合える
    * 基本的に時間通り
* 改善点
    * ファシリテーター(僕)の腕にかかっている
    * あまり一つの問題に深く考えることが出来ない
    * 発言量が減ってしまった

## 希望と懸念で行ったこと

www.amazon.co.jp/dp/B08R9J4FQK
基本的な手法はこの本を参考にさせていただきました

* 懸念リストをTrelloに作成し、懸念カードを追加する
    * 懸念は、今後の問題や不安を書く
* 書いたカードをどういうものか20秒で共有
* 希望リストをTrelloに作成し、希望カードを追加する
    * 希望は、今後どうしたいか？どう変わりたいかを書く
* 20秒で共有
* Trelloのアサイン機能を使って、話したいテーマを3つ選びアサイン
* 投票数が多かった、2枚のカードについて深く話し合った(ここは全員が現状どう思っているかを話した)

結果的には、漠然と懸念があったことが、

* 今はやらなくていい
* そんなことは思っていない

という結論になり、懸念が2個解消されました 

## 希望と懸念のふりかえり

* 良かったこと
    * チームで決めたテーマでふりかえりが出来る
    * チームが今一番Hotな希望や懸念を知ることが出来る
    * いつもより発言数が増えた
    * 前回の手法より、これを解決しないといけないという責任感が強くなった
    * 新しいふりかり手法(テーマ決めの手法)を使用し、新鮮味があった
* 改善点
    * そのあとのふりかえり手法を決めていなかったため、そこがフワッとした話し合いになってしまった
    * 色々意見を出すため、他にも話したいと思う、不完全燃焼感があった
    * 懸念がコミュニケーション不足なことであった場合、次のステップに繋げられていなかった(ファシリテーターとして、再発防止に繋げられなかったのが反省)
    * 希望や懸念が出せない人に対しての配慮があるとよい

## 希望と懸念はどういうチームにおすすめか？
* ふりかえりがマンネリ化しているとき
* チームメンバー同士のコミュニケーションが足りていないチーム
* そもそも何をふりかえれば良いか？わからないチーム

## 次に行うふりかえり
* 今回出した希望と懸念のリストは取ってあるため、新しいカードを追加し、投票を行う
* 5つのなぜを使用し、根本原因を追究する
* できたら、SMARTな目標を使ってみる
これからのIT社会の在り方

これからのIT社会の在り方(ES)

就活をしている中で感じた事(備忘録)

全ての人にシステム開発に・また社内にAI（機械学習・自然言語処理）・ERP(SAP)など新たな技術をより導入して、より豊かな社会を作っていくことに挑戦したいです。現状クライアントはベンダー企業に丸投げであり、具体的な知識を持ち合わせていないクライアントにもより共同してもらえる様な想像以上なAI・ERP(SAP)を絡めたソリューションの提供をして顧客満足度を向上させたいです。
私は、単なる開発業務ではなく、貴社の豊富なテクノロジーソリューションを持ちながら開発をすることでお客様のニーズをより満たすことができると考えました。
今後、どんどんモノとＩOＴの境がなくなりAIの時代が来ると思います。一方で、AI技術に対する知識を持ちそれをきちんと活用できる人は少ないと思います。貴社がAIによるシステム開発を行なっているように、私もAI技術を必要としている人にわかりやすくそしてより利用しやすいカタチで提供できるよう努めたいです。多くの方がAI技術を活用してビジネス変革を起こすことができたら、日本はより豊かになると思います。
・2025年の壁とある様にIT人材枯渇がある為、AIを通じて高度な先輩方のエンジニアのノウハウを形式知化して、モデル化して、企業内に知識を引き継ぎ、より技術の高度化を図るべきだと感じます。これは技術継承そのものであり、企業の資産として非常に有用な活動となると思います。現状の日本はDXが推進される中、データを蓄積するだけでは価値は生まず、蓄積したデータを形式知化された先輩エンジニア方のノウハウで処理することで、価値のある知見を抽出することができ、結果的に、AIを用いたデータのデジタル化とノウハウの形式知化の活動により、DXの価値をより高めることができ、2025年の壁も乗り越えられると思います。

・ 私自身が自然言語処理の有用性や将来性を研究室を通して実感したことから、自然言語処理を用いたタスクを減らす研究を行いたいです。現在、テキストデータが収集しやすい環境が構築されています。SaaSが生まれ、徐々にオフィスワーカーの仕事が楽になっていますが、未だにオフィスワーカーに残されているのは自然言語を活用するタスクです。
例えば、社内コミュニケーションツールでは、Slackを活用する事例が増加してきました。また、議事録の生成ツールが発展し、今後は会議のデータのデータ化も進んでいくことが予想されます。この様に紙媒体の書類が減少し、電子化されることが増加していることも起因しています。
今後も社内のテキストデータが増加していきます。DXの流れの中で、テキストデータの活用を検討しつつ、最終的には自然言語を活用した従業員のタスクを減少させたいです。少ない業務で必要な情報を得ることができる様な作業効率化をはかるソリューションの提供をしたいです。

・金融機関がローン審査において確認するデータを基に、これまで人間が担ってきた審査ノウハウをAIに学習させることで、審査の自動化を促進し、審査業務のデータ駆動化を実現したいです。また、APIによるローン審査システムへの連携、既存業務へAI審査を組み込むための業務コンサルティングをご提供することで、システム面、業務面双方における確実な実装を支援したいです。

・to Cとして需要に応じた在庫配分や価格調整により、企業の収益とお客さまの購買機会を最大化する販売手法の導入・運用を支援します。また、ビッグデータから導出される最適な在庫・価格で販売することで、需要を確実に獲得して増収を実現しつつ、企業に適した販売を行うまでのプロセスをデータ駆動化させたいです。

・今後より良いDXの実現するためには、よりクラウドの活用が不可欠だと思います。クラウド導入は「コストを抑えて導入しやすい」や「サービス内容の柔軟性」が高いなどのメリットがあります。クラウド導入を行い、RPAやAIといった最先端のデジタルツールをクラウド上で行うことができると、変化に合わせて柔軟に変更できるためDX推進がより行えると思うからです。現在はクラウド導入が活発化しており、働き方自体が大きく変わる可能性があるため、私はクラウド技術全般に関する最先端な知識・スキルを含めたフルスタックの技術者になりたいと思い、貴社でも扱っているAWSに関する知識・スキルを現在学習しています。
Swift・CoreBluetoothで通信を行いメッセージアプリっぽいのを作った3

# 第3回の内容
ここ2週間ほど仕事の引き継ぎや新しい仕事になったりと、忙しく3回目の投稿ができてませんでした....
本当に申し訳ないです。今日から投稿を再開していきます。
今回は接続したBLEデバイスのサービス・キャラスタリスティックを検索するを実装していきます。
# セントラル、ペリフェラル、サービス、キャラクタリスティックとは？
ここから4つの聴き慣れないBLE固有の概念が出てくるので軽く説明します

+ セントラル
 + BLE通信において、スキャン接続などを行う側のデバイス
+ ペリフェラル
 + BLEの通信において、スキャンで発見される側のデバイスを指します。1つ以上のサービスを提供します
+ サービス
 + 1つ以上の「キャラクタリスティック」を持ちます
+ キャラクタリスティック
 + データを保持します

# 実装方法
実装の流れ
1.ペリフェラルの持っているサービス一覧を取得
2.サービスの持っているキャラクタリスティック一覧を取得

```
// ペリフェラルへの接続が成功すると呼ばれる
    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
        
        print("接続成功！")
        print("接続したデバイス: \(self.peripheral)")
        self.centralManager.stopScan()
        // サービス検索結果を受け取るためにデリゲートをセット
        self.peripheral.delegate = self
        // サービス検索開始
        self.peripheral.discoverServices(nil)
    }

    // サービス発見時に呼ばれる
    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
        let services: NSArray = peripheral.services as! NSArray
        print("\(services.count)個のサービスを発見! \(services)")
        
        for obj in services{
            if let service = obj as? CBService{
                // キャラクタリスティック検索開始
                peripheral.discoverCharacteristics(nil, for: service)
            }
        }
    }

// キャラクタリスティック発見時に呼ばれる
    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
        
        let characteristics: NSArray = service.characteristics as! NSArray
        print("\(characteristics.count)個のキャラクタリスティックを発見! \(characteristics)")
    }
```
処理の流れとしては以上になります。処理を記述した際にCBPeripheralDelegate、CBCentralManagerDelegateが必要になるので、忘れないように注意してください。
AWS認定クラウドプラクティショナー資格勉強①

<h1>はじめに</h1>
AWS認定クラウドプラクティショナーの勉強をはじめました。
クラウドプラクティショナーに限らず、AWS資格取得を段階的に広げていきたいと考えています。

<h1>前提</h1>
AWS含めたインフラ経験なし。
プログラミングは10年前ぐらいに触ったきりで正直もう経験があるとは言えない状況なので、
完全なる初学者としてゼロから学ぶ。

<h1>受験予定</h1>
3/6（日）で設定
この日に向けて1日1時間程度は割いて進めていきたい。

<h1>教材</h1>
■AWS
　　AWSデジタルトレーニング
■書籍
 　 一夜漬け AWS認定クラウドプラクティショナー 直前対策テキスト
■Udemy
　【2022年版】これだけでOK! AWS認定クラウドプラクティショナー試験突破講座
　【2022年版】この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集

■CloudTech
　ハンズオン勉強用 

<h1>進め方</h1>
　AWSデジタルトレーニングやUdemyで勉強しながら、
　あとはUdemyの模擬試験や書籍をゴリゴリテスト対策の勉強をしていくイメージ