OmniAICreator/Qiita-1.07M huggingface dataset:
【Chakra UI】「Stack」を学ぶ

# この記事で学ぶ内容
* **Stack**について
* 要素間の余白の幅の指定方法

## 1\.「Stack」について
### Stackとは
**Stack**とは、Chakra-UIに用意されているレイアウトコンポーネントの１つである。
**Stack**には、以下の3種類がある。
|VStack|垂直方向に要素をスタックする|
|:---:|:---:|
|**HStack**|**水平方向に要素をスタックする**|
|**Stack**|**垂直,水平方向の両方に要素をスタックする**|

※詳細は[公式ドキュメント](https://chakra-ui.com/docs/components/stack)を参照。

### Stackの使い方

#### ソースコード
```jsx
<VStack>
	<Box bgColor="#fff0f0">Stack1</Box>
    <Box bgColor="#fff0f0">Stack2</Box>
	<Box bgColor="#fff0f0">Stack3</Box>
</VStack>
```
#### 表示結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3495420/a960f87d-3549-e928-29b9-e0ed85d50590.png)

**margin**や**padding**を使用しなくても、デフォルトで要素間に8pxの余白が作られる。

## 2\.要素間の余白の幅を指定する

### **spacing**を使い、要素間の余白を指定する

#### ソースコード
```jsx
<VStack spacing="20px">
	<Box bgColor="#fff0f0">Stack1</Box>
	<Box bgColor="#fff0f0">Stack2</Box>
	<Box bgColor="#fff0f0">Stack3</Box>
</VStack>
```

#### 表示結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3495420/b1b0ad5f-4f65-4786-e581-d18a9bffd1b6.png)


### **margin**や**padding**を使い、要素間の余白を指定する
基本的には**spacing**を使うとよいが、**Box**と同様に**margin**や**padding**を使うこともできる。

#### ソースコード
```jsx
<VStack>
	<Box bgColor="#fff0f0" marginBottom="20px">Stack1</Box>
	<Box bgColor="#fff0f0" marginBottom="20px">Stack2</Box>
	<Box bgColor="#fff0f0"                    >Stack3</Box>
</VStack>
```

#### 表示結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3495420/b87e78d2-da51-0d2a-c958-77dde2630129.png)

オレンジ色の部分は、**margin**を使って指定した20pxである。
実際の余白＝「**margin**や**padding**で指定した値＋デフォルトの8px」になるため、調整がややこしくなる。

## 3\.「Box」と「Stack」の比較する

ここでは、**Box**(divのようなもの)を使用した場合と**VStack**を使用した場合を比較する。
※**Box**についての詳細は[公式ドキュメント](https://chakra-ui.com/docs/components/box)を参照。

### Boxで要素を囲む

#### ソースコード
```jsx
<Box>
	<Box bgColor="#fff0f0" marginBottom="20px">Box1</Box>
	<Box bgColor="#fff0f0" marginBottom="20px">Box2</Box>
	<Box bgColor="#fff0f0"                    >Box3</Box>
</Box>
```
### Stackで要素を囲む
#### ソースコード
```jsx
<VStack spacing="20px">
	<Box bgColor="#fff0f0">Stack1</Box>
	<Box bgColor="#fff0f0">Stack2</Box>
	<Box bgColor="#fff0f0">Stack3</Box>
</VStack>
```
#### 表示結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3495420/3582eef6-2995-c785-f39b-7c3ddad71ceb.png)&emsp;![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3495420/8d5a25dc-7e34-0f7d-2e4c-9504ade3629b.png)

**Box**でも**Stack**同様に要素間の余白を指定することはもちろん可能である。
しかし、**Box**で要素間の余白を指定しようとすると、余白の数だけ**margin**を記述しなければならない。
そのため、**Stack**と**spacing**を使うよりソースコードの記述量が増えてしまう。

# まとめ
* **Stack**を使用すると、デフォルトで余白が付くため簡単に見やすいレイアウトになる。
* 余白を指定したければ、**margin**や**padding**を使うより**spacing**を使うほうがよい。

# 参考

* [Stack-Chakra UI](https://chakra-ui.com/docs/components/stack)
* [Box-Chakra UI](https://chakra-ui.com/docs/components/box)
* [Stackをどんどん使おう（リストレイアウト編）](https://zenn.dev/terrierscript/books/2021-05-chakra-ui/viewer/2-2-1-stack-list)
* [VStack / HStackもどんどん使おう（コンポーネントレイアウト編）](https://zenn.dev/terrierscript/books/2021-05-chakra-ui/viewer/2-2-2-stack-layout)
iOSでカメラの権限を変えた後アプリに戻ると強制再起動することについて

先日Flutterでアプリを開発していてカメラの権限周りを触ることがあったのですが、アプリが動いている状態で設定に移動し権限を変更してからアプリに戻ると以下のようなログを吐いてアプリが落ちてしまうという現象に遭いました。
```
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGKILL
    frame #0: 0x0000000000000004 libsystem_kernel.dylib`mach_msg_trap + 8
libsystem_kernel.dylib`mach_msg_trap:
->  0x000000004 <+8>: ret    
libsystem_kernel.dylib`mach_msg_overwrite_trap:
    0x000000008 <+0>: mov    x16, #-0x20
    0x00000000c <+4>: svc    #0x80
    0x000000010 <+8>: ret    
Target 0: (Runner) stopped.
```
最初はバグかと思い直そうとしていたのですがどうやっても改善できず、色々と調査していたら以下のようなFlutterへのissueを見つけました。
[[Camera] Application crashes if permission changed while app is running · Issue #126429 · flutter/flutter](https://github.com/flutter/flutter/issues/126429)
どうやらiOSの仕様上カメラの権限を変えた後アプリに戻るとOSによって強制的に再起動させられてしまうらしく、バグではなかったようです。
この調査で結構時間を使ってしまったので備忘録的に残しておきます。
プライベートサブネットでECS Fargateを利用する際のつまずきポイント

プライベートサブネットで ECS(Fargate) を利用しようとしましたが、
つまずきポイントが多かったので備忘録として残したいと思います。

## ざっくり構成

- プライベートサブネット
- ECS(Fargate)
- コンテナイメージは ECR Public Gallery のものを利用
- コンテナイメージはVPCエンドポイントで取得
- ALBのターゲットとして指定

## コンテナイメージの取得に失敗する

プライベートサブネット内から、ECRリポジトリにアクセスする通信経路が存在しないことが原因

👉 `VPCエンドポイント` or `NATゲートウェイ & インターネットゲートウェイ` のどちらかが必須

- VPCエンドポイントの場合、パブリックなコンテナイメージは取得できない仕様
- プルスルーキャッシュルールを設定してプライベートリポジトリを経由することで、擬似的にパブリックなイメージも取得できるようになる

### 必要な設定

- 必要なVPCエンドポイントを作成する : [参考](https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/vpc-endpoints.html)
    - Linux プラットフォームバージョン 1.3.0 以前
        - com.amazonaws.`region`.ecr.dkr (インターフェース)
        - com.amazonaws.ap-northeast-1.s3 (ゲートウェイ)
    - Linux プラットフォームバージョン 1.4.0 以降
        - com.amazonaws.`region`.ecr.dkr (インターフェース)
        - com.amazonaws.`region`.ecr.api (インターフェース)
        - com.amazonaws.ap-northeast-1.s3 (ゲートウェイ)
    - Windows プラットフォームバージョン 1.0.0 以降
        - com.amazonaws.`region`.ecr.dkr (インターフェース)
        - com.amazonaws.`region`.ecr.api (インターフェース)
        - com.amazonaws.ap-northeast-1.s3 (ゲートウェイ)
- S3のVPCエンドポイント(ゲートウェイ)は有効なルートテーブルに関連付けること
- (パブリックなイメージの場合)[プルスルーキャッシュルール]((https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/pull-through-cache.html)
)を作成する( IAM許可も忘れず )

## ALBのヘルスチェックが失敗し、ECSタスクの停止→起動が繰り返される

コンテナ起動後、ヘルスチェック応答が可能な状態になるまでに時間がかかる場合、
ターゲットグループのヘルスチェック失敗判定までの時間をそれより長く設定する必要がある

なお、ECSサービスに`ヘルスチェックの猶予期間`という設定があるが、
これはヘルスチェックに失敗した場合でもその秒数間はタスクを停止しないという設定であり、
ヘルスチェックの開始を遅らせてくれたり、その間のヘルスチェック失敗を見逃してくれたりする設定ではない
(ヘルスチェック失敗時の停止猶予期間、と表現したほうが適切かもしれない)

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/service_definition_parameters.html#sd-networkconfiguration
## その他、見落としがちな設定

- com.amazonaws.ap-northeast-1.s3 (ゲートウェイ) のポリシー設定で必要な通信をブロックしていないか
- VPC設定のDNSホスト名、DNS解決が有効になっているか
- ルートテーブルがサブネットに関連付けられているか
- セキュリティグループで通信が遮断されていないか
- IAM許可が適切に割り当てられているか
TMCでクラスタ作成時にHarborの証明書を埋め込む


気がついていない人向けの小ネタ。
Tanzu Mission Control（TMC）でWorkload Clusterを作成する際、イメージレジストリの証明書を渡すことが出来る。
これにより、Private Harborのイメージをクラスタデプロイ直後からpull出来るようになる。

## 検証環境
今回は以下で試した。
- Tanzu Mission ControlにManagement Cluster（v2.2）は登録済み
- Private Harborを自己署名証明書を使って構築済み
- Private HarborのPublicリポジトリにnginxのイメージをpush済み

おそらくTKGのVersionは2.2以降じゃないとレジストリ追加機能が上手く動かない。

## 手順

TMCのUIにログインし、左サイドバーの`Clusters`->`ADD CLUSTER`->`Create Tanzu Kubernetes Grid cluster`を選択し、利用するManagement Clusterを洗濯後、`CONTINUE TO CREATE CLUSTER`をクリックする。
`Create cluster`に遷移後、`6. Configure node pool`までいつも通りに埋める。
`7. Advanced settings`で`Variable name`をクリックすると色んな設定項目が出てくる。
これ、お察しのいい人は気がつくが、`kind: Cluster`の`spec.topology.variables`で指定するパラメータが出てくる。
ここで`additionalImageRegistries`を選び、`caCert`にイメージレジストリの証明書をbase64でエンコードしたもの(cat ca.crt | base64 -w0)、`host`にイメージレジストリのFQDNを指定する。

![1692947823759.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547981/5fff3dde-e67c-9f01-272e-bf5abcbe9e3c.png)
入力が終わったら`CREATE CLUSTER`をクリックしてクラスタを作成する。

## 動作確認
クラスタのkubeconfigを取得し、クラスタ上でPodを起動する。
```sh
$ kubectl run --image harbor.10.41.79.186.sslip.io/library/nginx nginx
pod/nginx created
$ kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          4s
```
問題なく起動した。
証明書が適切に当たっているか、ノードに入って確認する。
```sh
ssh -l capv 10.220.145.254
```
containerdの設定ファイルのディレクトリに証明書が配置されていることが分かる。
```sh
$ ls -l /etc/containerd/
total 8
-rw-r--r-- 1 root root  661 Aug 25 07:25 config.toml
-rw-r--r-- 1 root root 1156 Aug 25 07:25 harbor.10.41.79.186.sslip.io.crt
```
また、containerdの設定ファイルを見ると、指定したイメージレジストリに対して証明書を使う設定になっていることも分かる。
```sh
$ cat /etc/containerd/config.toml
：（省略）
[plugins."io.containerd.grpc.v1.cri".registry.configs."harbor.10.41.79.186.sslip.io".tls]
  ca_file = "/etc/containerd/harbor.10.41.79.186.sslip.io.crt"
```

なお、証明書が当たっていないクラスタで同じことをすると、以下のような感じのエラーとなる。
```s
$ kubectl run --image harbor.10.41.79.186.sslip.io/library/nginx nginx
pod/nginx created
$ kubectl describe pod nginx
：（省略）
  Normal   Pulling    2s    kubelet            Pulling image "harbor.10.41.79.186.sslip.io/library/nginx"
  Warning  Failed     1s    kubelet            Failed to pull image "harbor.10.41.79.186.sslip.io/library/nginx": rpc error: code = Unknown desc = failed to pull and unpack image "harbor.10.41.79.186.sslip.io/library/nginx:latest": failed to resolve reference "harbor.10.41.79.186.sslip.io/library/nginx:latest": failed to do request: Head "https://harbor.10.41.79.186.sslip.io/v2/library/nginx/manifests/latest": x509: certificate signed by unknown authority
  Warning  Failed     1s    kubelet            Error: ErrImagePull
```

## まとめ
こんな感じでTMCからクラスタ作成時に証明書を渡すことが簡単にできた。
また、`spec.topology.variables`の値をクラスタ構築時に設定できることも確認出来た。
使い方次第では証明書の追加だけでなくkube-apiserverの引数追加してfeatureGateの設定入れたり、色なことが出来そうだ。
java.lang.RuntimeException: java.io.IOException: User limit of inotify watches reachedエラーが出る

# はじめに

日本語の記事がなかったようなので簡素ですが、解決方法をのせます

# 問題

Javaのアプリケーションを起動したところ以下のエラーがでました

```
java.lang.RuntimeException: java.io.IOException: User limit of inotify watches reached
	at io.quarkus.deployment.dev.filesystem.watch.WatchServiceFileSystemWatcher.watchPath(WatchServiceFileSystemWatcher.java:174)
	at io.quarkus.deployment.dev.RuntimeUpdatesProcessor.startTestScanningTimer(RuntimeUpdatesProcessor.java:248)
	at io.quarkus.deployment.dev.RuntimeUpdatesProcessor.checkForChangedTestClasses(RuntimeUpdatesProcessor.java:657)
	at io.quarkus.deployment.dev.RuntimeUpdatesProcessor$1.testsEnabled(RuntimeUpdatesProcessor.java:155)
	at io.quarkus.deployment.dev.testing.TestSupport.start(TestSupport.java:136)
	at io.quarkus.deployment.dev.testing.TestHandler.accept(TestHandler.java:21)
	at io.quarkus.deployment.dev.testing.TestHandler.accept(TestHandler.java:17)
	at io.quarkus.runner.bootstrap.AugmentActionImpl.performCustomBuild(AugmentActionImpl.java:162)
	at io.quarkus.deployment.dev.IsolatedTestModeMain.accept(IsolatedTestModeMain.java:130)
	at io.quarkus.deployment.dev.IsolatedTestModeMain.accept(IsolatedTestModeMain.java:34)
	at io.quarkus.bootstrap.app.CuratedApplication.runInCl(CuratedApplication.java:149)
	at io.quarkus.bootstrap.app.CuratedApplication.runInAugmentClassLoader(CuratedApplication.java:104)
	at io.quarkus.deployment.dev.DevModeMain.start(DevModeMain.java:131)
	at io.quarkus.deployment.dev.DevModeMain.main(DevModeMain.java:62)
Caused by: java.io.IOException: User limit of inotify watches reached
	at java.base/sun.nio.fs.LinuxWatchService$Poller.implRegister(LinuxWatchService.java:264)
	at java.base/sun.nio.fs.AbstractPoller.processRequests(AbstractPoller.java:266)
	at java.base/sun.nio.fs.LinuxWatchService$Poller.run(LinuxWatchService.java:364)
	at java.base/java.lang.Thread.run(Thread.java:1589)
```

# 解決方法

以下を実行したところ起動できるようになりました

```
$ echo fs.inotify.max_user_watches=262144 | sudo tee -a /etc/sysctl.conf
$ sudo sysctl -p
```

# おわりに

日本語の記事がないと不安になる人がいるのかなと思い、調べればすぐわかることですが記事にしてみました

# 参考

https://github.com/OctoPerf/kraken/issues/64
Goにおけるポインタの使い方と使い所のブラッシュアップ

Goにおけるポインタがよくわからなかったので、とりあえず使い方がわかったので、疑問点と一緒にアウトプットしようと思う。何か間違っている点がありましたら、恐れ多いのですがご指摘宜しくお願い致します。

### 記事の目標
この記事を読むことでGoにおけるポインタの概念を理解できる。

## 疑問点
- 使い所はどこか？
- なぜアドレスみたりできるのか、変数など直接取得すればいいのではないか？

(上記二つは調査中。。。)

## 前提知識
ポインタを理解するにはどうやら前提知識が必要そうだ。以下は[こちらの記事](https://zenn.dev/genki86web/articles/a0ae1d57ad1806)から引用させていただきました。以下は変数とメモリとアドレスの説明です。
>- メモリは、1バイト毎に番号がつけられ、区別されています。
>- 変数は実行ファイルになると、番号が割り当てられます。
>- 変数は、メモリ上の該当の番号の区分に格納され、記憶されます。
>- この変数に付与されるメモリの区分番号がアドレス(16進数)です。

```main.go
func main() {
	test := "test"

	fmt.Println(about)
 }
```
上記の関数内に定義されている変数testもアドレス情報を持っている。

ポインタはアドレス情報のことを示している。上記を実行すると変数testに格納されているtestが出力される。変数testのアドレス情報を出力するには下記のように記述する。

```main.go
package main

import (
	"fmt"
)

func main() {
	test := "test"
	var pointer *string = &test

	fmt.Println(test)
	fmt.Println(pointer)
}
```
↓出力結果
```
//go run main.go

test
0x1400008e020
```
のようにアドレス情報が得られる。アドレス情報から変数の値にアクセスすることもできます。青の場合は以下のように*pointerと記述するだけで取得することができます。
```main.go
package main

import (
	"fmt"
)

func main() {
	test := "test"
	var pointer *string = &test

	fmt.Println(test)
	fmt.Println(*pointer)
}
```
上記の使い方となんとなくの概念を理解できたため、次はこちらを用いてどのような場面で用いるのかなどキャッチアップしていきたいと思います。

## 参考記事
https://zenn.dev/genki86web/articles/a0ae1d57ad1806

https://zenn.dev/joo_hashi/articles/85ad9d10eef979
Intellijでjsonの比較を手軽に行う

# はじめに

テストを書いていて期待している結果と実際の結果が似通っていて、どこが違うのか簡単にわからない際に便利な方法をしったのでメモがてらまとめていきます

# やり方

Intellijを使って2つのJSONを比較していきます

```expected.json
{
    name: "test",
    answer: "1",
    msg: "hello"
}
```

```actual.json
{
    name: "test",
    answer: "1"
}
```

この例は極端に簡単なので目に見て違いがわかりますが、複雑なjsonほど比較が難しいので役立ちます

まずはIntellijで`shift`を2回押します
そして`新規スクラッチバッファー`を検索してクリックします

`buffer.txt`が開くのにここに`expected.json`の内容をはります
次に`actual.json`をコピーしておきます

右クリックから`クリップボードの比較`を選ぶとどこが違うのかが表示されます

# おわりに

Intellijの使い方も学んでいかないとなと最近感じました
さくっとURDFを見る

# ちょっと前の資産をみたい

:::note info
- 仕事の絡みでROSやOmniverseから離れています。
- ただ、放置はもったいないということでせめてファイルだけでものぞければ・・・
:::

## 前の記事

https://qiita.com/Manyan3/items/e13a19d14a25cdc16425


# Omniverse のサンプルCarterさんを見てみる

- 私の場合はAnacondaなので、ROS用の環境を呼び出します。
- ROS2の環境は生きているようですね。ほっ。

```Ubuntu:Terminal

pip install pybullet

```

https://github.com/mi-kaneyon/isaac_sim_ROS2/tree/main/viewer

- ROS2 のビルドしたディレクトリにurdfファイルとその他コンポーネントがあるとおもいます。
- 私の場合はここに環境１をおいていたので、こちらをコマンドに指定。 

```Ubuntu:Terminal

# 例

~/carter_ws/src/navigation/carter_description/urdf/
# コマンド実行例

python urdf_simple.py ~/carter_ws/src/navigation/carter_description/urdf/carter.urdf 

```

## 表示例

![sample Image 1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2155177/49e20ccc-0582-2e58-11d8-48bd1673169a.jpeg)


:::note info
**pybullet いいですね**
- 今年は円安で自分で何かしら動かすのも難しいので、会社の指示にしたがいます・・・
:::
ERROR: unable to contact ROS master の対策メモ

同一ネットワーク上の複数PCでROSを動作させたときのメモです。
マスターPCとTurtlebot3で通信させようとして、表題のエラーが出ました。

**結論としては、ファイアウォールによって接続制限されていたので、ファイアウォール設定を無効化することで解決しました。**

```bash
$ sudo ufw allow 11311
$ sudo ufw reload
```
# 環境

- マスターPC
```bash
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04.6 LTS
Release:	20.04
Codename:	focal

$ echo $ROS_DISTRO 
noetic
```

- Turtlebot3
```bash
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04.4 LTS
Release:	20.04
Codename:	focal

$ echo $ROS_DISTRO 
noetic
```

# マスターPC設定
`.bashrc`の`ROS_MASTER_URI`と`ROS_HOSTNAME`を設定する。
```bash
$ nano ~/.bashrc
```

```bash:.bashrc
export ROS_MASTER_URI=http://[マスターPCのIPアドレス]:11311
export ROS_HOSTNAME=[マスターPCのIPアドレス]
```
忘れずに`.bashrc`の設定を反映する
```bash
$ source ~/.bashrc
```

# Turtlebot側の設定

```bash
$ nano ~/.bashrc
```
```bash:.bashrc
export ROS_MASTER_URI=http://[マスターPCのIPアドレス]:11311
export ROS_HOSTNAME=[Turtlebot3のIPアドレス]
```
```bash
$ source ~/.bashrc
```

# 実行時エラー
マスターPCで roscore 起動後に Turtlebot3をbringupする。

- マスターPC側
```bash
$ roscore
```

- Turtlebot3側
```bash
$ roslaunch turtlebot3_bringup turtlebot3_robot.launch
```
しばらく待つと、以下のエラーが返ってきた。
```
RLException: ERROR: unable to contact ROS master at [http://192.168.43.202:11311]
The traceback for the exception was written to the log file 
```
ROS masterに接続できないらしい。

# ファイアウォール設定の無効化

マスターPC側にファイアフォール(ufw)を導入済みの場合下記コマンドで無効化する。
```bash
$ sudo ufw allow 11311
$ sudo ufw reload
```
これで接続できるようになりました。
Linux、 Distro/Distributionとは

# Linux

:::note
**OSのひとつ**
ユーザーがコンピュータや他のデバイスを効果的に制御し、様々なタスクを実行できるようにするソフトウェア
:::

# Linuxの特徴

### オープンソースである

### 様々なプラットフォームやデバイスで動作する

### カスタマイズが可能
- ユーザーが自分のニーズに合わせてカスタマイズできるため、特定の要求や目的に合わせた環境が構築可能

### セキュリティに重点を置いている
- 多くのセキュリティ機能やツールが組み込まれている



### コマンドラインインターフェース
- テキストベースのコマンドを使ってシステムを操作することができるため、高度な操作や自動化が可能

### ディストリビューションのバリエーションが豊富


# Linux Distro/Distributionについて

## Linux Distributionとは

:::note
Linuxカーネルに加えて、ソフトウェアやユーティリティ、ユーザーインターフェースなどが組み込まれている、Linuxベースのオペレーティングシステムのバリエーションやバージョンのこと
:::

また、ディストリビューションは、Linuxのカーネルと基本的なコンポーネントに加えて、特定の特徴や目的に合わせたオペレーティングシステムを作成するために以下の要素を組み込む


### パッケージマネージャ
- ソフトウェアのインストール、アップデート、削除を簡単に行うためのツール
→ユーザーは必要なソフトウェアを簡単に導入できる

### デスクトップ環境
- グラフィカルユーザーインターフェース（GUI）やウィンドウマネージャなど
一般的なデスクトップ環境には、GNOME、KDE、Xfceなどがある

### アプリケーション
- オフィススイート、ウェブブラウジング、メディアプレーヤー、開発ツールなど

### 設定ツール
- システムの設定やカスタマイズを行うためのツールが含まれている
→ユーザーは自分の環境をカスタマイズできる


## ディストリビューションの種類

### Ubuntu
- デスクトップ環境やサーバー環境に適しておりユーザーフレンドリー

### Fedora
- 最新のテクノロジーや機能を追求できる

### CentOS
- Red Hat Enterprise Linux（商用Linux）の無料バージョンとして提供されている

### Debian
- 安定性とセキュリティに焦点を当てている

### Arch Linux
- カスタマイズ性が高く、技術的なユーザー向け

:::note
各ディストリビューションは、**パッケージマネージャや設定ツールなどを通じて独自の特徴を持っている
共通してLinuxカーネルをベースにしている**
:::
PostgreSQLの認証にパスワード認証を使う

## 環境

PostgreSQL12.4
Ubuntu20.4

## はじめに

PostgreSQLに接続するときの認証には、デフォルトでpeer認証が使われています。 **/etc/postgresql/12/main/pg_hba.conf** を見ると、デフォルトでは次の設定になっています。
```/etc/postgresql/12/main/pg_hba.conf
# TYPE    DATABASE        USER            ADDRESS                 METHOD
  local   all             postgres                                peer
  local   all             all                                     peer
```

設定の見方ですが、１行目は、UNIXドメインソケットを使用した接続、つまり、ローカルからの接続において、すべてのデータベースに対して、postgresユーザーが接続するときは、peer認証が適用されますという意味になります。

２行目は、postgresユーザー以外のユーザーが接続するときも、すべてのデータベースに対して、peer認証が適用されますという意味になります。

## 設定

特定の１ユーザー（testユーザー）だけパスワード認証にして、残りのユーザーはpeer認証にする場合は次のようにします。

```/etc/postgresql/12/main/pg_hba.conf
# TYPE    DATABASE        USER            ADDRESS                 METHOD
  local   all             postgres                                peer
  local   all             test                                    md5
  local   all             all                                     peer
```

ここで重要なことは、testユーザーは２行目に追加するということです。testユーザーを３行目に追加すれば、パスワード認証は有効になりません。

pg_hba.confの設定はファイヤーウォールを設定する際の記述方法に似ています。pg_hba.confは上から順番に読み込まれます。そして、下位の記述に上位の記述と重複する設定がある場合は、上位の設定の方が有効になります。

上記の例では、test（２行目）の下にall（３行目）があります。testはallの中に含まれるため、重複した記述になっています。この場合、下位にあるallが有効になるのではなく、上位のtestの方が有効になります。つまり、testユーザーはパスワード認証が有効になるということです。METHODにmd5とありますが、パスワードをMD5のアルゴリズムで暗号化するという意味です。パスワードを平文で送る場合は、METHODはpasswordの設定になります。セキュリティが弱くなるため、恐らく、この設定をすることはないかと思います。ちなみに、認証を一切行わない場合は、METHODの設定はtrustになります。更にセキュリティが弱くなるため、この設定もすることはないかと思います。

pg_hba.confの設定を変更したら、PostgreSQLのサービスを再起動する必要があります。再起動しないと設定が有効になりません。

## まとめ

さて、peer認証からパスワード認証に変更する理由ですが、PostgreSQLに新規でロールを追加する場合、peer認証だとPostgreSQLにロールを追加した後、Linuxにも同じ名前のユーザー名を追加する必要がでてきます。Linuxには新規ユーザーを追加したくないといった場合は、パスワード認証を採用することで回避することができます。つまり、testユーザーがLinuxにない状態で、別のユーザーでLinuxにログインしていても、下記のコマンドでPostgreSQLにログインできるようになるということです。

```
#psql -U test -d データベース名
```

## 参考

PostgreSQLの公式マニュアル
https://www.postgresql.jp/document/12/html/auth-pg-hba-conf.html
せんせー、 フェロイック材料ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、フェロイック材料ってなに？

# フェロイック材料とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## フェロイック材料って何？

みんな、マグネットを知ってるよね？マグネットは鉄などのものにくっつく特別な力があるんです。
フェロイック材料は、そのマグネットのような特別な力や、他の特別な力を持つ素材のことを言います。

## どういうこと？

フェロイック材料は、特別な力を持っていて、その力は外部からの刺激で変わることができるんです。
例えば、温度や電気を使って、その特別な力をコントロールすることができます。

## どうしてそれがすごいの？

この材料を使うと、新しい電子機器や、特別な機械を作ることができるんです。
これらの機器は、私たちの生活をもっと便利にするかもしれないです。

## だから、フェロイック材料ってなに？

フェロイック材料は、特別な力を持ち、それを外部からの刺激でコントロールできる素材のことなんです。
このように、フェロイック材料は、特別な力を持つ素材で、
その力を使って新しいものを作ったり、生活を便利にするための技術の一部として利用されることがあるんです。

# まとめ

このように、スキンエレクトロニクスは、私たちの体に貼り付けることができる小さな電子のシールで、
色々な情報を取得するための技術なんです。
Mackerel でなんでも監視しよう

* Mackerel のサービスメトリックは時系列で値を持つものならなんでも扱うことが出来る。であればサーバやネットワーク以外のメトリックも監視してみよう。
* Mackerel で監視することで、時系列数値をグラフ化することが出来る。つまり簡易 BI ツールとして使える。
* Mackerel で監視することで、閾値を超えた際にアラートを出せる。

というような話です。

私は20年超の distributed.net ジャンキーですので([参考1](https://qiita.com/saoyagi2/items/a0ed24cf21c8cd7f9595)、[参考2](https://qiita.com/saoyagi2/items/b97e65ee1b489009cff7))、RC5-72 の順位を Mackerel で監視してみようと思います。

まず Mackerel のサービスメトリックを送信する API を確認します。といっても API-key を添えて URL をたたくだけのシンプルなものとなっています。

https://mackerel.io/ja/api-docs/entry/service-metrics?_gl=1*opbw89*_ga*MzMxNzc3OTMwLjE2ODk0MTg1NTY.*_ga_QYXK5167BD*MTY5Mjk0OTE4Ny4xNy4wLjE2OTI5NDkxODcuNjAuMC4w&_ga=2.155150392.1420917973.1692949188-331777930.1689418556#post

監視対象となる私のの RC5-72 のランキングページはこちらです。

https://stats.distributed.net/participant/psummary.php?project_id=8&id=497669

Rank: の右の「1500」という数値を抜き出して監視したいですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86075/e8fa3263-227a-6189-9568-6e95d9b63590.png)

ということで順位を抜き出して Mackerel に送信するスクリプトを作成しました。ほんとなら nokogiri とか使って綺麗に書くといいんですが、やっつけの適当です。すんません(誰に対する謝罪)

```bash
#!/usr/local/bin/bash

API_KEY="xxx"

RANK=`curl -s 'https://stats.distributed.net/participant/psummary.php?project_id=8&id=497669' | \
  ruby -e 'result = ARGF.gets(rs = nil).gsub(/\R/, "").gsub(/<.*?>/m, "").match(/Rank:.*?([0-9]+)/); p result[1].to_i'`

curl https://api.mackerelio.com/api/v0/services/all/tsdb \
  -H "X-Api-Key: ${API_KEY}" \
  -H "Content-Type: application/json" \
  -X POST \
  -d '[{"name": "dnetstats.rc5-72.rank", "time": '$(date +%s)', "value": '${RANK}'}]'
```

このスクリプトを cron で1日1回実行するようにします。

```:crontab
30 10 * * * $BINDIR/dnetrank.sh > /dev/null 2>&1
```

翌日以降に Mackerel を確認すると、順位が受信されてグラフが生成されています。と言いたいところなんですが、無料プランだとグラフが1日分しか作れません。このグラフにも順位が描画されているのですが1点のみなのでグラフに見てないという。しくしく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86075/086ac795-d666-e033-db8f-530879142154.png)

例えば目標順が1000位だったとして、1000位になったらアラートを飛ばしたいなら以下のように設定すれば大丈夫です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86075/c6b309b8-0866-acd9-b01b-a036e59b455c.png)
集中力アップについて調べてみた

はじめに
----
　仕事や学習において集中力がとても大事だと思います。そのため、集中力アップについて調べてみました。
　そもそも人はなんで集中できないのか、集中できる脳にするためにどうすればよいのかを自分なりに以下の3点にまとめてみましたので、読んでくださった方の参考になれれば幸いです。

　㎰：初投稿となります、よろしくお願いいたします。:bow_tone3:

サマリ
----
###### ・なぜ集中できないのか
###### ・“誘惑”をブロック
###### ・瞑想



・なぜ集中できないのか
-------

　97％の人が同時に複数のことに集中することができないと言われています。人類の歴史から見ても、“普通の人”より、はるかに頭の良いとされている人の特徴の一つが“同時に複数のことが出来る”ことです。すなわち、ほとんど人間の脳が一度に一つのことだけに集中できるようになっています。
　そこで、私は音楽聞きながら仕事が出来るし、ご飯食べながらYouTubeも見ているので、もしかして…残りの3%かも…と思う人がいるかもしれませんが、実は違います。:point_up:
　音楽を聞きながら仕事をする、ご飯食べながらYouTubeを見るみたいな“ながら作業”をしているときは、同時に複数のことに頭（脳）を使っているのではなく、脳が複数のことの間で切り替えをしています。その切り替えの速度がとても速い為、全部同時に行っているように錯覚しているだけです。
　脳がこのような切り替えに慣れてしまうと、長時間一つのことに集中する能力が低下してしまいます。一つのことに集中しようとしても、周りから切り替えるものを探そうとします。
　これが第2のテーマにつながってきます。


・“誘惑”をブロック
-------

　「スマホ依存」は皆さん聞きなれの言葉だと思います。ネットで定義を調べてみたら次のような説明がありました。

>
>スマホ依存とは、「スマートフォンの使用を続けることで昼夜逆転する、成績が著しく下がるなど様々な問題が起きているにも関わらず、使用がやめられず、スマートフォンが使用できない状況が続くと、イライラし落ち着かなくなるなど精神的に依存してしまう状態」のことを言います。
>

　Job総研の2022年の調査によると、調査対象の約8割がスマホ依存に該当しています。さらに、コロナ禍での行動制限で外出が減り、人と会う機会も減った為、過半数の人のスマホ利用時間が増えています。
[Job総研による『2022年 スマホ依存の実態調査』](https://prtimes.jp/main/html/rd/p/000000116.000013597.html)

　インタネット上ではスマホ依存関連やスマホの正しい使い方の情報が沢山あるので、これ以上書くとテーマがずれてしまいそうですが、上記の調査から見えるように、スマホは“一つのことに集中する”ことの妨げになる“誘惑”になっています。
　スマホ依存対策として、スマホの画面カラーを白黒にする、必要のないアプリを削除する等があります。さらに、スマホの利用時間や使用するアプリを制限できるアプリもありますが、一番効果的なのは、スマホそのものから離れることだそうです。スマホを目の見得るところに置くだけで集中力が低下するという研究結果も出ています。

　ここではスマホを例に挙げましたが、もちろんスマホ以外にもゲーム機、漫画、お菓子等、人によって“誘惑”されやすいものは他にもあります。結論としては、一つのことに集中したいときは、今やりたいことと関係のない、脳を“誘惑”するようなものはなるべく視線に入らないところに置いておくのがベストです。

・瞑想
-------

　“誘惑”をブロックすることで、脳の別のことへの切り替えを防ぐことができますが、それだけでは足りないです。一つのことに長く集中できるにはトレーニングが必要です。そのトレーニング方法の一つが瞑想をすることです。

>
>　Wikipediaによると瞑想、冥想とは、心を静めて無心になること、何も考えずリラックスすること、心を静めて神に祈ったり、何かに心を集中させること、目を閉じて深く静かに思いをめぐらすことなどとされている。
>

　瞑想により作り出される物事に集中しやすい心身の状態は「マインドフルネス」と呼ばれて、集中力の向上だけではなく、健康状態の改善にも効果があるとされていて、沢山の方が日常生活に取り入れています。集中力が低い人ほど瞑想状態に入りにくいですが、これも練習することで改善が出来ます。瞑想のやり方や効果について書かれている本と記事も沢山発表されています。気になる方は是非読んでみて、自分に会う方法を見つけてみてください。

　ネット上には瞑想用の音源やアプリも沢山ありますが、記事の最後に英語が出来る方向けに瞑想アプリをお勧めしたいです。

![image_2023_8_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2720911/adf3dd41-912c-f741-82ad-7e5cb233bb93.png)

###### おすすめ理由
・最初の一年間は無料で利用できる！
・簡単な質問に答えるだけで、自分仕様にカスタマイズできる。
・シンプルなUIで、操作しやすい。


インストールはこちら　
[App Store](https://apps.apple.com/jp/app/balance-meditation-sleep/id1361356590?uo=4)
[Googel Play](https://play.google.com/store/apps/details?id=com.elevatelabs.geonosis&pli=1)
緊急地震速報をパトライトで可視化する装置（スマホ⇒micro:bit＋パトライト）

# 概要

過去の大地震で、聴覚に障害を持つ方が緊急地震速報が聞こえずに避難できなかったというお話を聞きました。この装置は、スマートフォンからある一定の大きさの音が出たときにパトライトで通知することでユーザーに伝えます。

■外観
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181708/322fd11e-1c65-c197-a0e0-433bbd6b581a.png">

■内部構造
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181708/33c43024-448c-bcd6-2edc-b5974ae37b83.png">

# 動画（説明とデモ）
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/%E3%81%9F%E3%81%AE%E3%81%97%E3%81%84microbit%E3%82%B3%E3%83%B3%E3%83%86%E3%82%B9%E3%83%882023?src=hash&amp;ref_src=twsrc%5Etfw">#たのしいmicrobitコンテスト2023</a> <br>緊急地震速報の可視化のための装置を作りました。<br>スマートフォンの音に反応してパトライトを光らせる仕組みです。 <a href="https://t.co/D8YIjXhHrJ">pic.twitter.com/D8YIjXhHrJ</a></p>&mdash; keicafeblack (@keicafeblack) <a href="https://twitter.com/keicafeblack/status/1694713161042251950?ref_src=twsrc%5Etfw">August 24, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 処理の流れ

1. スマートフォンが鳴る
1. micro:bit内蔵のマイクで感知
1. リレーでパトライトを点灯させる

# ソース

https://makecode.microbit.org/_J9egJA0Y9Ldp

# 前作の緊急地震速報の可視化システム

[緊急地震速報をパトライトで可視化した](https://qiita.com/keicafeblack/items/a21fba0b5014e2b0cfc2
 "緊急地震速報をパトライトで可視化した")
Rails7でCacheを利用する（purgeも含む）

# 環境

- Ruby on Rails 7.0.5
- Ruby 3.2.2

# コード例

## キャッシュを使う（ない場合は作る）

```ruby:app/controllers/users_controller.rb
  def users_for_select
    @users = Rails.cache.fetch(User::CACHE_FOR_SELECT, expires_in: 5.minutes) do
      User.active.select(:id, :email, :name)
    end
  end
```

## キャッシュのキー定義とデータ変更時に削除するコード

```ruby:app/models/user.rb
  class User
    CACHE_FOR_SELECT = 'users_for_select'

    after_commit :purge_cache_for_select, on: %i[create update destroy]

    private

    def purge_cache_for_select
      Rails.cache.delete(CACHE_FOR_SELECT)
    end
  end
```

## キャッシュストアの定義

### config/application.rb

```ruby:config/application.rb
  config.cache_store = :memory_store, { size: 64.megabytes }
  # デフォルトは32MB
  # 本番環境では、Redis等を利用する
```

### config/environments/test.rb

```ruby:config/environments/test.rb
  config.cache_store = :memory_store, { size: 64.megabytes }
  # これがないと、テストで ActiveSupport::Cache::NullStore error が出る
```

## テストコード

```ruby:spec/models/tenant_spec.rb
  describe '#purge_cache_for_select' do
    let!(:user) { create(:user) }

    before do
      allow(Rails.cache).to receive(:delete)
    end

    it 'purges cache on create' do
      create(:tenant)
      expect(Rails.cache).to have_received(:delete).with(User::CACHE_FOR_SELECT)
    end

    it 'purges cache on update' do
      tenant.update(name: 'new name')
      expect(Rails.cache).to have_received(:delete).with(User::CACHE_FOR_SELECT)
    end

    it 'purges cache on destroy' do
      tenant.destroy
      expect(Rails.cache).to have_received(:delete).with(User::CACHE_FOR_SELECT)
    end
  end
```
【Swift】クロージャ嫌いを克服しよう(関数の引数Ver)

# 目次
[1.クロージャを関数の引数にして使用する](#1-クロージャを関数の引数にして使用する)
[2.実例](#2-実例)
[3.おわりに](#3-おわりに)

# 1. クロージャを関数の引数にして使用する
- Swiftはクロージャ(Pythonでいうところの無名関数)多用しますよね？　少なくとも私が開発に携わっているアプリでは、APIの非同期処理も多いので多用されています。
- クロージャって慣れるまでは読みにくくて仕方ないですよね。ここでは更に読みにくいクロージャを関数の引数として使用している例を解説していきます。

# 2. 実例
クロージャの登場シーンは多いのですが、関数の引数としても指定できます。
- 例
    ~~~swift: closure.swift
    func judgeFeeling ( feelingClosure: (Bool) -> Void) {
        print("How's it going today?")
        feelingClosure(true)
    }

    jedgeFeeling ( feelingClosure: { isHappy in
        if isHappy {
            print("Feeling is Happy")
        } else {
            print("So sad")
        }
    })
    
    //出力結果：Feelng is Happy
    ~~~

    - judgeFeeling関数の引数としてfeelingClosure(クロージャ)を渡さんかい！
        という関数を作成しています。

    - judgeFeelingを呼び出す側できちんとクロージャを渡しています。
    - クロージャの引数はBool型、返り値はVoidつまりなしです。
    - 実行順は`jedgeFeeling`-> `print("How's it going today?")`-> `feelingClosure
    - 簡単いうと`通常の変数の引数にそのままクロージャが入っている`と考えるとわかりやすいです。

# 3. おわりに
関数の引数が変数だろうが、クロージャだろうが考え方は同じです。
クロージャであれば、必ず実行(呼び出している)箇所が関数内部にあるのでその際に呼ばれるだけです！

今回も最後まで記事を読んでいただきありがとうございました。
目指せ脱初学者！！
AWS Lambda+Selenium(python)でダウンロード場所を、/tmpに変更する方法

# 問題
　Selniumを使用して特定のサイトからファイルをダウンロードするアプリケーションを作成し、AWS Lambdaにデプロイする際、問題が発生する。


　__ダウンロードディレクトリが作業ディレクトリと一致しない__

　ということだ。

## ダウンロード先を/tmpに指定する

作業ディレクトリであるtmpにダウンロード先を指定する方法は、様々な海外サイトなどに掲載されているが、2023年8月現在、うまく動かなかったので、うまくいった方法を示す。

```python:python
def startupchrome():
    #オプションの追加を行う
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')
    options.add_argument("--no-sandbox")
    options.add_argument("--single-process")
    options.add_argument("--disable-dev-shm-usage")
    
    #ダウンロードする場所の変更
    prefs = {"browser.downloads.dir": "//tmp//", "download.default_directory": "//tmp//", "directory_upgrade": True}
    options.add_experimental_option("prefs", prefs)
    
    options.binary_location = "/opt/headless/python/bin/headless-chromium"

    #ブラウザの定義
    browser = webdriver.Chrome(
        "/opt/headless/python/bin/chromedriver",
        options=options
    )
    
    browser.command_executor._commands["send_command"] = (
        "POST",
        "/session/$sessionId/chromium/send_command",
    )
    
    params = {
        "cmd": "Page.setDownloadBehavior",
        "params": {"behavior": "allow", "downloadPath": '/tmp'},
    }
    
    data = browser.execute("send_command", params)
    
    return browser
```

この関数はseleniumのdriverを返却する。
【bash/powershell/cmd】ファイルを検索しコマンド (clang-format) を実行する


# 目的

[clang-format](https://clang.llvm.org/docs/ClangFormat.html)を用いて C++ソースコードを整形しようとした場合、clang-foramt コマンド単体ではプロジェクタ内のフォルダを再帰的に検索して特定フォルダかつ特定拡張子のファイルを見つける、といったことができない。
そのためには bash における`find`といった、ファイル検索用のコマンドを使用すればいい。しかし こうした汎用的なツールを用いた具体的なコマンドを毎回検索・作成するのは面倒であり、また特に以下の要件を満たす例を紹介しているページが見つからなかったため、ここに記録する。

- 特定のサブフォルダ、特定の拡張子名のファイルのみを検索し、clang-format に渡す
- Windows と Linux の両方でのケースを検討する。
- シェル上で実行可能（ワンライナー）

# 参考文献

- clang-format と find を組み合わせた例は、以下のページを参考にした。
  https://stackoverflow.com/questions/28896909/how-to-call-clang-format-over-a-cpp-project-folder

- 本記事では参照できていないが、bash における clang-format を再帰的に実行するスクリプトの例。
  https://github.com/eklitzke/clang-format-all

# 解決策

bash, powershell, cmd のそれぞれで、以下に記載する特定のフォルダ内の、特定の拡張子のファイルに対して、clang-format (dry-run オプション付き)を実行するコマンドを記載する。

- 対象フォルダ名：src, test, include
- 対象拡張子名：cpp, hpp, h, cc, cxx

## bash(Linux)

```bash
find src test include -regex '.*\.\(cpp\|hpp\|h\)' -exec clang-format -style=file --dry-run --Werror -i {} \;
```

## powershell(Windows)

```powershell
clang-format -style=file --dry-run --Werror $(Get-ChildItem -Path $PWD/src,$PWD/test,$PWD/include -Recurse | Where Name -Match '.(?:cpp|hpp|h)$' | Select-Object -ExpandProperty FullName)
```

## cmd(Windows)

コマンドプロンプトのみ、複数フォルダを同時に検索する方法は見つからなかった。

```cmd
for /r .\src %a in (*.cpp *hpp *.h) do clang-format -style=file --dry-run --Werror %a
```

# 今後の改善点

- (bash): xargs を使用する。
- (Windows): WSL で実行できるならば、bash のコマンドを使用する。
- (bash): `-prune -o`の書き方を使用し、特定ディレクトリを除外できるようにする。
Googleアラートで情報収集

日々さまざまなニュースが配信されていますが、それらを効率的に収集する方法の一つとしてクリッピングサービスがあります。無料で使えるクリッピングサービスとして Google アラートがあります。

https://www.google.co.jp/alerts

## Google アラートの使い方

テキストフォームにクリッピングしたいキーワードを入力します。ここでは「Qiita」とします。

キーワードを入力した段階で、どのようなニュースがクリップされるかプレビューされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86075/b26b99bd-06de-4b2c-8dfa-7751e4b29039.png)

「オプションを表示」をクリックすると詳細設定が行えます。設定できるのは以下の項目です。

* 頻度。「その都度」「1日１回以下」「週１回以下」から選択。
* ソース。「自動」「ニュース」「ブログ」「ウェブ」「ビデオ」「書籍」「ディスカッション」「金融」から選択。
* 言語。日本語を含むさまざまな言語から選択。
* 地域。日本を含むさまざまな地域から選択。
* 件数。「上位の結果のみ」「全ての結果」から選択。
* 配信先。「自分のメールアドレス」「RSS」から選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86075/c52f931e-bbfc-ee0c-aeaa-6334ef5f6532.png)

「アラートを作成」をクリックすると、自分のアラート一覧に追加されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86075/1147246e-a97d-5a45-19b9-42ac4d2e4dac.png)

マイアラートの右にある歯車をクリックすると全体の設定が行えます。設定できるのは以下です。

* 配信時間。１時間単位で選択。
* ダイジェスト。ダイジェストメールの配信頻度と配信先の選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86075/0fb7ab77-8a0a-e485-2f5d-6fc375580ae4.png)

個々のアラートの右にはアイコンが二つまたは三つ並んでいます。

* RSSフィードURL。アラートの配信先として RSS を選択した場合のみ表示されます。
* 編集。アラートを編集します。編集内容は新規作成時と同様です。
* 削除。アラートを削除します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86075/81927e11-631a-d822-2f4b-9609fda1ad2e.png)

以上で RSS リーダもしくはメールでクリッピングを受けることが出来ます。

## Google アラートを使ってみて

Google アラートは便利で、特定のキーワードに対するニュースを自動で収集してくれて便利なのですが、イマイチだなと思うところがないわけではありません。

一つは、複数のニュースサイトで同じニュースが配信されることです。今日はたくさんクリップされてるなと思ったら、実は全部一つのニュースでしたということは多々あります。別々のニュースサイトであっても同じニュースであれば一つにまとめてクリップしてくれると便利なのになと思います。今のところはチェックしきれないほど配信されるわけではないので、頑張って読んでいます。

もう一つはニュース記事本文ではなくヘッドラインニュースなどにキーワードがマッチした場合に、全然関係ないニュースがクリップされることです。例えば「Qiita」がヘッドラインニュースに含まれていた場合、全然関係ないスポーツや地域ニュースなどもクリップされてしまいます。これは本当にノイズなのでなんとかならないかなと思うのですが、今のところどうしようもないので我慢して読み飛ばしています。
Flutterを使ったアプリ開発日記

# Flutter を利用したアプリ開発日記

開発日記と言いながら使い方メモみたいになっちゃうかも
- [ 第一弾：ダイエットマップ ](https://qiita.com/appzs/items/98f33967b0279cbc0ef2)

## モチベーション
- フロントエンドの開発経験ないし、非同期処理とか全然なれないし。。。
- でもアプリ開発をしてみたい！
- いろいろ見ながらやって、そろそろ整理しないといけないなと感じてきた。
- 自分だけのためのメモって適当になっちゃうから Qiita に投稿することにした。
- 正しいかはわからないけど、とりあえずいろいろ書いてく！
※間違ってたらすみません。


## メモ一覧
ここのリンクをアップデートしていく予定。


- 位置情報関係
    - [ location ](https://qiita.com/appzs/items/f6c5afbeaefd6cca7de5)

- データベース
    - [Flutter×MySQLでデータ管理](https://qiita.com/appzs/items/5b2700d6b880dda03bee)


- Widget
    - [TextFormField：入力フォーム](https://qiita.com/appzs/items/c5add7cf36fe5d5f4087)
    - Scaffold とか便利だけど、パラメータとかちゃんと整理したい
    - UIのセンスが欲しい。

## Error 対処

- 起動後、ずっと画面が真っ白
    runApp() がなかった。。。まじでわからんかった。。。

※以降、追加予定
他のPHPフレームワークよりもLaravelを選ぶべきタイミングはいつですか？


ウェブアプリケーションを開発する際、適切なフレームワークを選択することはプロジェクトのパフォーマンスと効率に大きな影響を及ぼします。PHP開発の世界では、Laravelが最も人気のあるフレームワークの一つとなっています。以下は、他のPHPフレームワークよりもLaravelを選ぶべきタイミングのいくつかです。

![php-frameworks (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92345/3308fdd7-faa4-b07b-baed-2f014e0cb898.jpeg)
PHPフレームワーク
cre: techhubdigital

1.読みやすく、わかりやすい構文のプログラミング言語を探したいとき
Laravelは明確で読みやすい構文で設計されており、プログラマーがアプリケーションの構造を理解しやすく、効率的にコードを書くことができます。使いやすく、アクセスしやすいフレームワークを探している場合、Laravelは良い選択肢です。

一般的な機能の良いサポート：
Laravelは認証、ルーティング、キャッシュ、データベースマイグレーションなど、多くの一般的な機能を提供しています。これらの機能が組み込まれているため、アプリケーションの開発に時間と労力を節約できるだけでなく、プロジェクトの構造を簡単に維持することもできます。

2.一人で勉強できないときは、大きなコミュニティが必要です
Laravelは大規模なコミュニティと多くのサポートリソースを持っています。ドキュメント、チュートリアル動画、および追加の拡張パッケージなどが提供されています。これにより、開発プロセス中に発生する問題に対する解決策を見つけるのに役立ちます。

3.高いセキュリティ要素が必要な場合
Laravelはセキュリティに重点を置いており、CSRF対策、XSS対策などの機能を提供して一般的な攻撃を防止します。さらに、Laravelは使いやすいエラーハンドリングインターフェースを提供し、開発プロセス中のエラーを簡単に追跡して修正できます。

4.キャリアの機会を手に入れたいとき
Laravelは市場で最も人気のあるフレームワークの一つであるため、Laravelの知識はキャリアの機会を拡大するのに役立ちます。ウェブ開発の分野で仕事を探している場合、Laravelを学習しておくことは有利に働くでしょう。

![career-opportunities-concept-in-flat-design-illustration-vector.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92345/858e4464-d675-a773-dc42-460eba97d373.jpeg)
キャリアの機会
Cre: static.vecteezy


まとめると、Laravelは強力で魅力的な機能を備えたPHPフレームワークです。プロジェクトにフレームワークを選択する際に、使いやすさ、サポートされる機能、セキュリティ、コミュニティサポートなどの要素を考慮すると、Laravelは効果的で安全なウェブアプリケーションを構築するための優れた選択肢になるでしょう。Core PHP も良い選択です。理解するには以下の記事を読んでください。


 参考情報：https://miichisoft.com/php-laravel-diffence-web-development/
Svelte for VS Codeを使ってSvelteファイルのimportを最適化する方法

# モチベーション
- 適切な順番にimport文を並び替えてほしい
- 未使用のimport文を自動で消してほしい
- 同じリソース元から複数のimport文を書いてしまってる場合に自動的に最適化してほしい。

## 手順


### Svelte for VS CodeをVS Codeにインストールする

https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode

## ソートしてほしい場合(未使用のimport文もソートされるが、削除はされない)

### `.vscode/settings.json`を編集する

```json:.vscode/settings.json
{
  "[svelte]": {
    "editor.defaultFormatter": "svelte.svelte-vscode",
    "editor.codeActionsOnSave": ["source.sortImports"]
  }
}

```

### フォーマットしたい`.svelte`ファイルを保存する

実行前
```html
<script>
  import { PUBLIC_URL } from '$env/static/public';
  import { browser } from '$app/environment';
  import { Breadcrumbs } from '@ui';
  import { error } from '@sveltejs/kit';
  import { onMount } from 'svelte';
  import { Footer } from '@ui';
  import { fade } from 'svelte/transition';
  import '../app.css';
  import Banner from '$lib/components/Banner.svelte';
</script>
```

実行後
```html
<script>
  import { onMount } from 'svelte';
  import { fade } from 'svelte/transition';
  import { error } from '@sveltejs/kit';
  import { Breadcrumbs, Footer } from '@ui';
  import { browser } from '$app/environment';
  import { PUBLIC_URL } from '$env/static/public';
  import Banner from '$lib/components/Banner.svelte';
  import '../app.css';
</script>
```

## ソートかつ、未使用のものは削除したい場合

### `.vscode/settings.json`を編集する

```json:.vscode/settings.json
{
  "[svelte]": {
    "editor.defaultFormatter": "svelte.svelte-vscode",
    "editor.codeActionsOnSave": ["source.organizeImports"]
  }
}

```

### フォーマットしたい`.svelte`ファイルを保存する

実行前
```html
<script>
  import { onMount } from 'svelte';
  import { fade } from 'svelte/transition'; // 未使用
  import { error } from '@sveltejs/kit';
  import { Breadcrumbs, Footer } from '@ui'; // Breadcrumbsは未使用
  import { browser } from '$app/environment';
  import { PUBLIC_URL } from '$env/static/public';
  import Banner from '$lib/components/Banner.svelte'; // 未使用
  import '../app.css';
</script>
```

実行後
```html
<script>
  import { onMount } from 'svelte';
  import { error } from '@sveltejs/kit';
  import { Footer } from '@ui';
  import { browser } from '$app/environment';
  import { PUBLIC_URL } from '$env/static/public';
  import '../app.css';
</script>
```
VanJSでランダム絵文字生成アプリを作ってみた

VanJSの勉強のために、ランダム絵文字生成アプリを作ってみました。アプリとリポジトリは公開しているので、VanJSを勉強したい方は参考にしてみてください。

## 作ったアプリ

https://vanjs-random-emoji-generator.vercel.app/

## リポジトリ

https://github.com/mori-goq/vanjs-random-emoji-generator

## コード

```typescript:src/main.ts
import van from 'vanjs-core'

import { emojiList } from './constants'

const { div, h1, label, button, input, span } = van.tags

const RandomEmojiGenerator = () => {
  const emojiCount = van.state(1)
  const randomEmojiText = van.state('')

  const generateRandomEmojiText = () => {
    const randomEmojiList = [...new Array(emojiCount.val).keys()].map(() => {
      const randomNumber = Math.floor(Math.random() * emojiList.length)
      return emojiList[randomNumber]
    })

    randomEmojiText.val = randomEmojiList.join('')
  }

  // init
  generateRandomEmojiText()

  return div(
    { class: 'random-emoji-generator' },
    h1('Random Emoji Generator'),
    div(
      { class: 'emoji-controls' },
      label({ for: 'emoji-count' }, 'Number of Emojis: '),
      input({
        id: 'emoji-count',
        type: 'number',
        value: emojiCount,
        oninput: (event: InputEvent) => {
          emojiCount.val = +(event.target as HTMLInputElement).value
        },
      }),
      button(
        {
          type: 'button',
          onclick: () => generateRandomEmojiText(),
        },
        'Generate',
      ),
    ),
    div({ class: 'emoji-display' }, span({ class: 'emoji' }, randomEmojiText)),
  )
}

van.add(document.getElementById('app')!, RandomEmojiGenerator())
```

```typescript:src/constants.ts
export const emojiList = [
  '😀',
  '😃',
  '😄',
  '😁',
  '😆',
  '😅',
  // 長いため省略
]
```

```css:src/style.css
.random-emoji-generator {
  text-align: center;
  margin: auto;
  width: 80%;
  padding: 40px;
  background-color: #f5f5f5;
  border-radius: 10px;
  box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
}

.emoji-controls {
  margin-bottom: 20px;
}

.emoji-controls label {
  font-size: 1.2rem;
  margin-right: 10px;
}

.emoji-controls input[type="number"] {
  font-size: 1rem;
  padding: 5px 10px;
  border: 1px solid #ccc;
  border-radius: 5px;
}

.emoji-controls button {
  font-size: 1rem;
  padding: 8px 20px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  transition: background-color 0.2s;
}

.emoji-controls button:hover {
  background-color: #0056b3;
}

.emoji-display {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
}

.emoji {
  font-size: 2rem;
  margin: 10px;
}
```

## 感想

Reactライクに書けるのでアプリ自体はすんなり作れましたが、型推論が弱いなと感じました。inputイベントの`oninput: (event: InputEvent) => {}`で、`InputEvent`の型を指定しないと`any`型になるため、その後の`value`の値を取得するのに面倒でした。

inputイベントやclickイベントで、引数の`event`を使用するときは、型アサーションの`as`を使用するなどして、型の上書きをする必要があるようです。

## まとめ

今回はVanJSでランダム絵文字生成アプリを作ってみました。VanJSは型推論がまだ弱いようなので、今後の開発に期待です。


## 参考サイト

https://perchance.org/emoji

https://www.prosettings.com/emoji-list/


## 最後に

### GoQSystemでは一緒に働いてくれる仲間を募集中です！

ご興味がある方は以下リンクよりご確認ください。

https://goqsystem.recruit.site?qiita=d6d2193a88fef8dfb67b
本番DB作業はトランザクションで

本来あるべきではないのですが、どうしても本番DBで直接クエリをたたいてデータを修正しないといけないことってあります。当然、ミスってしまうと大問題なので慎重の上に慎重に作業をするわけですが、慎重に上乗せする方法としてトランザクションを使うといいことを同僚に教えてもらいました。多分有名な話だと思いますが、私は知らなかったのでメモしておきます。

ざっくり書くとこんな話です。

* 本番クエリはトランザクションの中で行う。
* クエリを実行しても、コミットするまでは実際には本番DBには反映されない。
* でもどうやって反映されるかはトランザクションの中では見ることが出来る。
* クエリをミスってればロールバックすれば本番影響なし。
* クエリが正しいことを確認できればコミットで作業完了。

## 実際の作業

試した環境は MySQL 8.0.34 です。

以下のようなテーブルがあったとします。

```sql
mysql> select * from users;
+------+--------+--------+
| id   | name   | gender |
+------+--------+--------+
|    1 | taro   | male   |
|    2 | jiro   | female |
|    3 | hanako | female |
+------+--------+--------+
3 rows in set (0.00 sec)
```

jiro の gender を female から male に修正したいとします。

トランザクションを開始して、クエリを実行します。このとき、誤って WHERE 句をつけ忘れたとします。

```sql
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

-- ここからトランザクションの中

mysql> update users set gender="male";
Query OK, 2 rows affected (0.00 sec)
Rows matched: 3  Changed: 2  Warnings: 0

mysql> select * from users;
+------+--------+--------+
| id   | name   | gender |
+------+--------+--------+
|    1 | taro   | male   |
|    2 | jiro   | male   |
|    3 | hanako | male   |
+------+--------+--------+
3 rows in set (0.00 sec)
```

jiro だけではなく hanako も male になってしまいました。しかしここはトランザクションの中です。トランザクションの外ではまだ何も起こっていません。

```sql
-- トランザクションの外
mysql> select * from users;
+------+--------+--------+
| id   | name   | gender |
+------+--------+--------+
|    1 | taro   | male   |
|    2 | jiro   | female |
|    3 | hanako | female |
+------+--------+--------+
3 rows in set (0.00 sec)
```

トランザクションをロールバックします。当然レコードは元のままです。

```sql
mysql> rollback;
Query OK, 0 rows affected (0.03 sec)

mysql> select * from users;
+------+--------+--------+
| id   | name   | gender |
+------+--------+--------+
|    1 | taro   | male   |
|    2 | jiro   | female |
|    3 | hanako | female |
+------+--------+--------+
3 rows in set (0.00 sec)
```

改めてトランザクションを開始してクエリを実行します。今度は WHERE 句を付けて、正しいレコードになることを確認してコミットします。

```sql
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> update users set gender="male" where id=2;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

-- これはトランザクションの中
mysql> select * from users;
+------+--------+--------+
| id   | name   | gender |
+------+--------+--------+
|    1 | taro   | male   |
|    2 | jiro   | male   |
|    3 | hanako | female |
+------+--------+--------+
3 rows in set (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.03 sec)

-- こちらはトランザクションの外
mysql> select * from users;
+------+--------+--------+
| id   | name   | gender |
+------+--------+--------+
|    1 | taro   | male   |
|    2 | jiro   | male   |
|    3 | hanako | female |
+------+--------+--------+
3 rows in set (0.00 sec)
```

なお、当然のことながらトランザクションが適切に分離されていることが前提です。ダーティリードが発生する環境ではコミット前にトランザクション外で更新値が読み取れてしまいますので本番影響があります(ロールバックすれば戻りますが)。
Notionからhtmlでエクスポートしたときのファイルとフォルダ群にくっついてくる余計な文字列を削除するコマンド

Notionをエクスポートしたことがある人ならわかる、エクスポート後に末尾につくIDのような長い文字列が
邪魔だったので自動で消せるようにしました。

何度かエクスポートしないといけない事情がある人向け。

サブディレクトリは第2階層まで対応していてそれ以降は対応していないです。

```powershell 
# 置換対象の文字列を保存する配列
$foundSubstrings = @()

# 現在のディレクトリを取得
$rootPath = Get-Location

# ① ルートディレクトリのフォルダ名を変更
$directories = Get-ChildItem -Path $rootPath -Directory | Where-Object { $_.Name -notlike "bk*" }
foreach ($dir in $directories) {
    $folderName = $dir.Name

    # ② サブディレクトリのフォルダ名とHTMLファイル名を変更
    $subDirectories = Get-ChildItem -Path $dir.FullName -Directory
	$htmlFiles = Get-ChildItem -Path $dir.FullName -File -Filter "*.html"

    foreach ($subDir in $subDirectories) {
        $subFolderName = $subDir.Name
        $subMatch = [regex]::Match($subFolderName, ' ([^ ]+)$')
        if ($subMatch.Success) {
            $subSubstring = $subMatch.Groups[1].Value
            $foundSubstrings += $subSubstring
            $newSubFolderName = $subFolderName -replace [regex]::Escape(" " + $subSubstring), ""
            Rename-Item -Path $subDir.FullName -NewName (Join-Path $dir.FullName $newSubFolderName)
        }

    }

	foreach ($htmlFile in $htmlFiles) {
		$htmlFileName = $htmlFile.Name

		$htmlMatch = [regex]::Match($htmlFileName, ' ([^ ]+)(?=\.html$)')
		if ($htmlMatch.Success) {
			$htmlSubstring = $htmlMatch.Groups[1].Value
			$foundSubstrings += $htmlSubstring
			$newHtmlFileName = $htmlFileName -replace [regex]::Escape(" " + $htmlSubstring), ""
			Rename-Item -Path $htmlFile.FullName -NewName (Join-Path $dir.FullName $newHtmlFileName)
			
			#htmlの中身を修正
			$content = Get-Content (Join-Path $dir.FullName $newHtmlFileName) -Raw -Encoding UTF8
			foreach ($substring in $foundSubstrings) {
				$replacePattern = "%20$substring"
				$content = $content -replace [regex]::Escape($replacePattern), ""
			}
			Set-Content -Path (Join-Path $dir.FullName $newHtmlFileName) -Value $content -Encoding UTF8

		}
	}

	$match = [regex]::Match($folderName, ' ([^ ]+)$')
    if ($match.Success) {
        $substring = $match.Groups[1].Value
        $foundSubstrings += $substring
        $newFolderName = $folderName -replace [regex]::Escape(" " + $substring), ""
        Rename-Item -Path $dir.FullName -NewName (Join-Path $rootPath $newFolderName)
    }

}

# ③ ルートディレクトリのHTMLファイルの内容を変更
$htmlFiles = Get-ChildItem -Path $rootPath -File -Filter "*.html"
foreach ($htmlFile in $htmlFiles) {
    $content = Get-Content $htmlFile.FullName -Raw -Encoding UTF8
    foreach ($substring in $foundSubstrings) {
        $replacePattern = "%20$substring"
        $content = $content -replace [regex]::Escape($replacePattern), ""
    }
    Set-Content -Path $htmlFile.FullName -Value $content -Encoding UTF8

    # ④ ファイル名を変更
    $htmlFileName = $htmlFile.Name
    $htmlFileMatch = [regex]::Match($htmlFileName, ' ([^ ]+)(?=\.html$)')
    if ($htmlFileMatch.Success) {
        $htmlFileSubstring = $htmlFileMatch.Groups[1].Value
        $newHtmlFileName = $htmlFileName -replace [regex]::Escape(" " + $htmlFileSubstring), ""
        Rename-Item -Path $htmlFile.FullName -NewName (Join-Path $rootPath $newHtmlFileName)
    }
}

```
SpringBoot3にしたら、Applicationすべてが404エラーになった話

同じ問題に当たって迷う人が少なくなりますように。

# 問題
アプリケーション部門から、SpringBootを2.7から3.1に上げたらECSでうまく起動しなくなったと連絡が来た。

# 原因
OpenTelemetoryのJavaAgentが古かった(1.15)…。

## 発生条件？
- Java17
- SpringBoot3.1
- aws-opentelemetry-agent.jar(X-Rayのため、v1.15.0)

で発生。

## 切り分け
- ContainerHealthCheckは失敗している(404)
- ELBからのヘルスチェックも失敗している(404)

そもそも、actuator/healthがうまく動いてない様子。
アプリケーション側じゃない？と思いつつ本業じゃないけど、コードを流し見したが違和感はない。公式のマイグレーション手順を見たが問題なさそう。

## 結果
X-RayのためにADOTのOpenTelemetoryのAgentを使っていたが、2.7系で確認したもの(v1.15.0)をそのまま使っていた。社内向けのTemplateに保存しており、Platformとして確認済みということで案内していたため。

https://github.com/aws-observability/aws-otel-java-instrumentation

気付いたらv1.29.0まで上がってるし。
ReleaseNoteを見てたらSpring3系の話もあったので、それじゃない？と。

調べてたら

https://stackoverflow.com/questions/76636649/springboot-3-1-1-is-not-working-with-opentelemetry-javaagent

のような案件もあったけど、日本語だったりの情報とかもないし、検索かけてもあまり出てこなかったので、ここで供養する。