OmniAICreator/Qiita-1.07M huggingface dataset:
Azure Functions の Queue トリガーを .Net 6 と Azure CLI でやってみた

Azure Functions で Azure Storage の Queue をトリガーに並列処理する、イベント駆動型のスケーラブルなアーキテクチャを考えてみます。そもそも Azure Function の Queue トリガーは、キューに入ったメッセージをデフォルトの状態で並列処理してくれるのでしょうか？実際に試してみました。

## Azure Functions 検証環境を作成

```bash:bash
prefix=mnrfunc
region=japaneast

az group create \
  --name ${prefix}-rg \
  --location $region

az storage account create \
  --name ${prefix}stor \
  --resource-group ${prefix}-rg \
  --sku Standard_LRS

az storage queue create \
  --name myqueue-items \
  --account-name ${prefix}stor

az monitor log-analytics workspace create \
  --workspace-name ${prefix}-log \
  --resource-group ${prefix}-rg

az monitor app-insights component create \
  --app ${prefix}-ai \
  --location $region \
  --resource-group ${prefix}-rg \
  --workspace ${prefix}-log

az functionapp create \
  --name ${prefix} \
  --resource-group ${prefix}-rg \
  --consumption-plan-location $region \
  --runtime dotnet \
  --functions-version 4 \
  --storage-account ${prefix}stor \
  --app-insights ${prefix}-ai \
  --https-only \
  --os-type Linux
```

## 検証用アプリを作成

```bash:bash
func init $prefix --dotnet

cd $prefix

func new --name queue --template "Queue trigger"
```

## アプリにスリープと終了ログを追加

```cs:queue.cs
using System;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using System.Threading;

namespace mnrfunc
{
    public class queue
    {
        [FunctionName("queue")]
        public void Run([QueueTrigger("myqueue-items", Connection = "AzureWebJobsStorage")]string myQueueItem, ILogger log)
        {
            log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
            Thread.Sleep(10000);
            log.LogInformation($"C# Queue trigger function finished: {myQueueItem}");
        }
    }
}
```

## Azure Functions にデプロイ

```bash:bash
func azure functionapp publish $prefix
```

## Azure Storage のキューにメッセージを追加

```bash:bash
az storage message put \
  --queue-name myqueue-items \
  --content $(echo test | base64) \
  --account-name ${prefix}stor

for i in {1..10}
do
    az storage message put \
    --queue-name myqueue-items \
    --content $(echo test$i | base64) \
    --account-name ${prefix}stor
done
```

スクショを取り忘れましたが、無事並列処理している事を確認できました。

## 参考

https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-bindings-storage-queue-trigger?tabs=python-v2%2Cisolated-process%2Cnodejs-v4%2Cextensionv5&pivots=programming-language-csharp

https://learn.microsoft.com/ja-jp/cli/azure/storage/message?view=azure-cli-latest#az-storage-message-put
「The stream or file ~ could not be opened in append mode」の対処法

# はじめに
DockerでLaravelの環境構築中に、「The stream or file ~ could not be opened in append mode」というエラーが出て困っていたので対処法をまとめます。

--
環境：Docker version 24.0.7

# 問題


PHPコンテナ内でLaravelプロジェクトを作成。

```terminal
$ docker compose exec php bash
$ composer create-project --prefer-dist "laravel/laravel=" .
```

そして上のようにプロジェクト内にLaravelのソースコードを書き、動作確認をしようとブラウザを開くと…

![the stream.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620668/8a571d42-367a-2d12-ce0b-616bf085c168.png)

```terminal
The stream or file "/var/www/html/storage/logs/laravel.log" could not be opened in append mode: Failed to open stream: Permission denied
```

このようなエラーが表示されました。

# 解決方法
storage/logs/laravelにappendする権限が与えられていないので、パーミッションを変更してあげます。

```terminal
$ chmod -R 777 /app/storage/
```

# 参考
https://qiita.com/tamakiiii/items/6f29264a9b05e6a4f675

https://qiita.com/shisama/items/5f4c4fa768642aad9e06
ポリモフィックコンポーネントってなに？

ポリモーフィックコンポーネントなるものを知りました。
なんやそれ？って人は記事を読んでいってください！

## ポリモフィックコンポーネントってなに？
一つのコンポーネントが複数の形態を取れるように設計されたコンポーネントのことを指します。
コードの再利用性が向上し、コンポーネントの柔軟性が高まる設計方法のことです！

:::note info
例えば、Listコンポーネントがポリモーフィックであれば、`<ol>`要素だけでなく、`<ul>`要素としても使用できます！
:::

## ポリモフィックコンポーネントの作り方
ポリモフィックコンポーネントという名前は知らなくても作成したことがある方もいると思います。
一般的には`as`プロパティを利用してタグをpropsとして受け取れるようにすることで作成できます！

`as`プロパティについては別の記事で紹介しているのでよければご覧ください！

https://qiita.com/tanimoto-hikari/items/3fcd42cdbadc2c2583a5

以下に、ポリモーフィックコンポーネントの一例を示します。

```typescript
iport { FC } from 'react'

type Props = {
  as: 'ul' | 'ol';
};

const List:FC<Props> = ({ as: Tag = 'ul' }) => {
  return (
    <Tag>
      <li>ListItem</li>
      <li>ListItem</li>
    </Tag>
  )
};

// <ul>として利用する場合
<List />


// <ol>として利用する場合
<List as="ol" />
```

デフォルトの値を`<ul>`としてレンダリングされます。
もちろん`ul`や`ol`だけでなく`div`タグなどもレンダリングできます。

## ポリモフィックコンポーネントの目的
ポリモーフィックコンポーネントは、以下の点を目的として作成します。

- コードの再利用性
- 柔軟性と拡張性
- 一貫性と予測可能性
- 可読性と保守性

同じようは構造のコンポーネントを作成しないで1つにまとめることで可読性や保守性、コードの一貫性を向上できます。
また、タグを動的に変更できるため、使用方法が柔軟で不必要にコンポーネントが増えずにすみます。

## ポリモフィックコンポーネントを作る上での注意点
じゃあ全部ポリモフィックコンポーネントで作ればいいのでは？
についてはNoです。

例えば下記のようなコンポーネントがあったとします。

```typescript
iport { FC } from 'react'

type Props = {
  as: string;
};

const Pragraph:FC<Props> = ({ as: Tag = 'p' }) => {
  return (
    <Tag>Polymorphic Component</Tag>
  )
};
```

極端な例ですが上記の例だと型の定義を工夫しないといけません。

:::note warn
`as`の型をstringにするとどんな文字列でも許可してしまうので、HTMLのタグではない文字列でも受け入れることになってしまいます…。
:::

また、コンポーネントの汎用性を高めすぎると記述量が増えて、内部ロジックの複雑性と可読性が悪くなります。

## 【ポリモフィックコンポーネントってなに？】まとめ
当然ですが、柔軟性を高めすぎるとコードの可読性を損うことになります。

:::note info
コンポーネント設計のメリットを損なってしまうためコンポーネント1つに対して責務をシンプルに保てるようにしましょう！
:::

柔軟性や拡張性を重んじるあまりコンポーネントが拡張されすぎてメンテナンスが困難になった事例をよく聞きます。
コンポーネントの設計はエンジニアだけでなく、デザイナーも含めてチームで話し合って決められると良いと思います！
[MySQL]レプリケーション回復メモ

## レプリケーションがエラーを起こした
ブレーカーが落ちてサーバ機器が止まり、復旧した際にMySQLのレプリケーションがエラーで止まっていたので回復させた際のメモ。
## 回復手順
スレーブ側のレプリケーションを止める
```:slave
# mysql -u root -p
Enter password:
mysql> stop slave;
```
マスタ側のMySQLを止める
（キャッシュの吐き出しと更新を止めるため）
```:master
# systemctl stop mysql
```
データベースをコピー
（データベースのファイルPATHやスレーブのホスト名は適宜指定する事）
```:master
# scp -p -r /var/lib/mysql/DATABASE SLAVE:/var/lib/mysql/
```
マスタ側のMySQLを起動
```:master
# systemctl start mysql
```
現在のログファイルとポジションを確認
```:master
# mysql -u root -p
Enter password:
mysql> show master status\G
*************************** 1. row ***************************
            File: mysql-bin.002311
        Position: 138673
    Binlog_Do_DB: DATABASE
Binlog_Ignore_DB:
1 row in set (0.01 sec)

```
スレーブ側の設定
上のFileとPositionの値を
master_log_fileとmaster_log_posに設定する
```:slave
# mysql -u root -p
Enter password:
mysql> change master to master_log_file='mysql-bin.002311',master_log_pos=138673;
```
スレーブ側のレプリケーションを再開
```:slave
mysql> start slave;
```
受入企業側と受講生側の両方に参加して感じたこと

この記事はマナビDX Questで得たもの Advent Calendar 2023　シリーズ２　１月２日の記事です。
今回、Qiitaで初投稿となります。よろしくお願いします。


「自己紹介」
マナビDX２年目のふるたと申します。北海道の地域金融機関でDX推進の仕事をしています。完全文系人間です。プログラミングの知識はありません。文系人間ながら、DX領域に進出しつつ経験を積んでいる状況です。
１年目は現場研修プログラムの受入企業として、２年目は受講生として参加しました。
両方を経験した人って結構少ないと思います。そんな貴重な体験に感謝して、感じたことを３点記載させていただきます。


「受講生のレベルが高い」
受講生は様々ですし、全員に会って話をした訳ではないですが、自分の周囲の受講生は皆さん総じてレベルが高かったです。
全てにおいてレベルが高いという感じではなく、一定の分野の専門性が高いと感じました。そしてそれらは、あまり他の人と似ていない専門性であることも多く、数名集まると多様性が生まれ、面白いチームが形成される、そんなイメージでした。受講生同士が有機的に結びつき、普段の仕事でも連携して仕事ができたら、もっとイノベーションが生まれるのではと可能性を感じます。


「受入企業と受講生の両方で参加することがおすすめ」
両方の立場で参加すると、当然ですが両方の気持ちがわかります。受講生にこんなことをしてほしいな、受入企業にはこんな情報を提供してほしいな、など両方の経験をしたからこそ思うことがあります。経営者側、従業員側、どちらの目線も大切であるように、マナビDXにも両方の視点が大切かと思います。受講生の皆さんには、ぜひ次年度は受入企業としての参加をしてみてください。DX推進ということは同じでも、見える景色が異なると思います。


「自分の立ち位置」
受講生との関わりで感じたことがあります。それは、自分にはプログラミングで何かを開発するよりも、ITが苦手な企業と、いわゆる理系人材のITスキルが高い人の間に立って、調整をする仕事の方が向いているなと思いました。ITパスポートやITコーディネータの勉強をして資格を取得しても、そっち側（どっち側？）の人間にはなれないし、向いていないです。そういった事実を受け止めた上で、自分の立ち位置を再構築したいと思いました。調整をする人間も大切だと思うので、そういった分野で存在感を発揮しようと考えています。

以上、簡単ではありますが、皆さんの参考になれば幸いです。
Google Apps Script を用いた追加計算アドオンを OSS として作っている

この記事は，[Math Advent Calendar 2023](https://adventar.org/calendars/8530) の 3 日目の記事です．
遅れまして申し訳ございません ( 2023 1209 )．

## Background and profile
 - Name : Yoshitaka Naraoka
 - Birth : 1999 / 0409
 - https://github.com/YoshitakaNaraoka
 - Chem & Cutting processing

### 理学計算と切削加工品質の担保を同時に行いたかった
 - 切削加工品質の担保を行うのと知的労働へのシフトをやっていくときにまあ Robotics はいるよね．
^ そしたらロボットアーム動かすのに回転行列とか解かなきゃいけないじゃん．
^ じゃあ行と列で出来た表計算ソフト使う方がまあ UI として良いのでは．
^ Excel は local で動くけどその local 性があんまりなあ……．
^ じゃあ Web とつながってる gSheets 使えばいいのでは．
^ gSheets の内部は JavaScript で動いてるんだね，というか gSheets の Automation をする GAS が JavaScript で動いてるんだね．
^ 後々のメンテナンス性を考えて計算部と通信部は分離している方がいいよね．
^ でも計算部を独立で使えた方がまあうれしさはある．
^ せっかく Chem の background 持ってんだから理学計算とかもぶちこもうね．
^ というわけで Google Apps Script にて gSheets の追加計算アドオンを作っていくことにした．

## 実装 ( 途中 )
 - language : TypeScript / Rust
^ 現在 TypeScript にて計算部分の発展を行っている．

 - Web frontend 部分は TypeScript -> JavaScript -> GAS deploy ( gcp library )
 - 機械に直接関係する部分は Rust にて記述
^ 動作速度 & Web に強い
^ Rust から JSON を GAS に送付し parse からの補正値計算
^ gSheets 上で補正値を決定して，入力
^ Rust に JSON を送付
^ Rust が補正値を機械にブチ込み，刃物がどんくらい動くか，というふうなことを目指している

## 実際何やってるのかはコード見た方が多分速いと思います
- 概要 [GitHub Org](https://github.com/MathExpansion)
- Public repo [MathExpansion](https://github.com/MathExpansion/MathExpansion)

### 本当に Overview だけになってしまった！！！！！！
遅れたのに！！！！！！
Pythonで「continue文を使った繰り返し処理のスキップ」の動作を確認してみた

# 概要

Pythonで「continue文を使った繰り返し処理のスキップ」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/for/index7.html

# 実装

以下のファイルを作成しました。
```sample.py
total = 0
for num in [35, 25, "OK", 45, "Pass", 28]:
    if isinstance(num, str):
        continue
    print("num = " + str(num))
    total += num

print("Total = " + str(total))
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
num = 35
num = 25
num = 45
num = 28
Total = 133
```

# まとめ

何かの役に立てばと。
生成AIの知財リスク

こんにちは！
このカレンダーを企画しているPromotion SGのリーダーの遠藤です。
本日から今年のホットトピックである生成AIに関する話題を取り上げたいと思います。
本日は、企業が気になるビジネスにおける生成AI活用の課題について触れたいと思います。
まだまだ議論が続いている分野ですので、ズバッとした解決策はあまりありませんが、
ご参考までに。

# 生成AIの知財リスク例
生成AIは名前の通り、文章や画像そしてプログラムなどを自動「生成」するところに特徴がありますが、コンテンツを生成するために必要なデータの「学習」や、生成された「アウトプット」の扱いを気にしなくてはならない場合があります。
今回は知財系のリスクについて見ていきます。

・著作権リスク
「学習」に使う元データに他者の著作物が含まれていた場合や、
「アウトプット」が他社の著作物に類似・依拠している場合等の著作権法上のリスクがあります

・ソフトウエアライセンスリスク
GitHub Copilotのようにプログラムを自動生成してくれるAIもあります。
この場合「アウトプット」がオープンソースを利用している場合、著作権表示情報などのオープンソースライセンスが守られていないリスクがあります。
（詳しくは明日！）

・特許リスク
これもプログラムを自動生成した場合に、他社の特許に抵触してしまうリスクがあります。

# 文化庁・内閣府「AIと著作権の関係等について」
このうち、著作権リスクについては、令和5年6月19日に文化庁・内閣府が[「AIと著作権の関係等について」](https://www8.cao.go.jp/cstp/ai/ai_team/3kai/shiryo.pdf)という文書を公表しており、日本国内ではこのドキュメントが一つの指標となっています。

これによれば、「学習」については、著作物に表現された思想または感情の享受を目的としない利用行為は「原則として著作権者の承諾なく利用することが可能」とされています。
ただし、「必要と認められる限度」を超える場合や「著作権者の利益を不当に害する場合」はその対象にならないとされています。

「アウトプット」については、通常の著作権侵害と同様に、類似性や依拠性が認められればアウトプットの著作権侵害が認められることになります。

上記をまとめると、「学習」時は上記の但し書きに該当しないように注意しながら、
「アウトプット」については、通常の著作物と同様に他者の権利を侵害していないか、スクリーニングや判断をしていけば良いことになります。
もちろん、これらをどのようにどこまでやれば良いのかなど論点は尽きませんが、それは今後の議論を見守る必要がありそうです。

本日は著作権一般について取り上げさせていただきましたが、明日はライセンスリスクとセキュリティリスクについて@youhMOさんに解説頂く予定です。

# English Summury

Hi. I'm Masato Endo who is the leader of promotion SG which is plannning this calendar.
Today, I mentiond to IP risks of GAI.
Especially, to manage copyrihght issues of GAI is important.
One [useful material](https://www8.cao.go.jp/cstp/ai/ai_team/3kai/shiryo.pdf) was released Japanese Government in this June.
We have to manage the risks appropriately by using this document for refernce.
Milk-v duo搭載pinpongライブラリを使用するハードウェア「handPy」

## はじめに
秋葉原ロボット部の有志で、milk-v duoを購入し、個々人が様々な実験を行って、勉強会内で報告しています。

Milk-v duoは9ドルのrisc-vコンピュータとして知られています。
ハードウェアは以下の通りです。

1. CPUはCVITEKのCV1800B (C906@1Ghz + C906@700MHz)
1. 最高1 GHzで動作するデュアルRV64コア
1. 64 MBのラム
1. オプションのアドオンボードを接続すると10/100Mbpsの速度でイーサーネットに接続可能

Milk-v duoでpythonを利用する際、pinpongライブラリを介して、センサー類を制御します。pinpongライブラリのディレクトリを見ると、見慣れないボード類用のライブラリが用意されています。
本稿では、handpyについて調べました。

## 掌控板(handPy)
以下のサイトを見てもらうとわかるのですが、microbitを思い出させる見た目です。
https://labplus.cn/handPy
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/6ee00d50-ba70-eb0d-4b18-2519c3110fc3.png)

ESP-WROOM-32搭載で、1.3インチのOLEDディスプレイ、加速度センサ、地磁気センサー、音と照度のセンサー、ブザーが接続されています。
押しボタンが2個、タッチボタンが6個搭載されています。
興味深いのが、端子が「P」、「Y」、「T」、「H」、「O」、「N」を模した形になっている点です。
https://www.dfrobot.com.cn/goods-1902.html

Micropythoに似たmPythonで制御するようです。
プログラミング環境として、
グラフィカルプログラミング環境の「Mind＋」、
https://mindplus.cc/en.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/3f82d28e-baf9-477a-8331-708b30e05843.png)
Pythonでプログラミングできる「BXY’s」
https://bxy.dfrobot.com.cn/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693019/3ead6a60-21f6-af62-41cf-ca567d96f2f1.png)

が用意されています。

## 掌控板の利用例
Pythonプログラミング
人工知能
IoT
理科実験用計測
と、主に学校教育に用いられているようです。
https://labplus.cn/handPy
に、利用例の動画が公開されています。
Python備忘

## はじめに
改めて、Python 基礎を学習したメモを備忘として記録します

## 型について

- int
- str
- float
- bool
- list
    ``` list = ['a', 'b', 'c'] ```
    - list はデフォルト引数を指定しないのが暗黙の了解
        - None を引数にし、関数の中で初期化（list = []）
- tuple	
   ``` tuple = ('a', 'b', 'c') ``` 
   - *argsを引数にするとうまく丸めてくれる
   ```python:
    def say_something(*args):
        print(args)

    say_something('Hi', 'Bob', 'Mary') # ('Hi', 'Bob', 'Mary')
   ```
- dictionary	
    ``` dict = {'x' : 'a', 'y' : 'b', 'z' : 'c'} ``` 
    ```python:dictよく使う
        - dict.items()    # [('x', 'a'), ('y', 'b'), ('z', 'c')]
        - dict.keys()     # ['x', 'y', 'z']
        - dict.values()   # ['a', 'b', 'c']
    ```
    - dictionary はデフォルト引数を指定しないのが暗黙の了解
        - None を引数にし、関数の中で初期化（list = []）
    - **kwargsを引数にするとうま丸めてくれる
       ```python:
        def say_something(**kwargs):
            print(kwargs)
    
        say_something(intro='Hi', first_name='Bob', last_name'Mary') # {'intro' : 'Hi', 'first_name' : 'Bob', 'last_name' : 'Mary'}
       ```

## 例外
- Exception を使ってなんでもキャッチするのはよくない

## __main__ について
```python:
def main():
    print('main')
    
if __name__ == '__main__':
    main()
```
- よくファイルに記載があると思います
    - これの理由は別のパッケージから意図せぬ形で呼び出されて実行される可能性があるから
vscodeにFigmaを導入して開発を効率的に

## VSCodeにFigma for VS Codeと言う拡張機能を導入

- [VS Code連携](https://help.figma.com/hc/ja/articles/15023121296151-VS-Code%E9%80%A3%E6%90%BA)

![スクリーンショット 2023-12-09 7.00.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712534/063a9750-b9f0-39e2-3c2b-03cb96fdaadd.png)

## login
vscodeにfigmaのログインを求められますので、ログインしてください

色々許可した後、figmaのデータをvscodeから見られるようになります。

## 連携後
![スクリーンショット 2023-12-09 7.02.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712534/bf1c7cf9-1125-ac9d-681e-99bc3255ea75.png)

選択したところの、cssなどの情報が出てきます。
![スクリーンショット 2023-12-09 7.03.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/712534/daf530fc-2805-e6f5-c75d-fe00694ab52d.png)
Docker + Laravel 9でtailwindcssのインストールとホットリロード設定

## したいこと
以下の環境を構築したい。
- Docker
- Laravel 9
- vite
- tailwindcss
- ＋ページネーション
- ＋ホットリロード

## Dockerでの設定

### "docker-compose.yml"のappサーバーの設定
5173番ポートを解放

例）
```docker:docker-compose.yml
services:
  app:
    ports:
      - 5173:5173
```

### appサーバーの"Dockerfile"の設定
5173番ポートを解放

例）
```dockerfile:Dockerfile
FROM php:8.3-fpm-bullseye AS base

EXPOSE 5173
```

### Dockerコンテナビルド
```sh
$ docker compose build --no-cache
```

### Dockerコンテナ起動
```sh
$ docker compose up -d
```

## Laravel・viteインストール
お好きなバージョンでインストールしてくだい

## npm install
Laravelプロジェクト内に移動して
```sh
$ npm install
```

## tailwindcssインストール
```sh
$ npm install -D tailwindcss postcss autoprefixer
$ npx tailwindcss init -p
```

## Laravelにtailwindのページネーションテンプレートをインストール
```sh
$ php artisan vendor:publish --tag=laravel-pagination
```

## Laravelプロジェクトでの設定

### "tailwind.config.js"の設定
contentセクションに以下を追加
```js:tailwind.config.js
content: [
    './resources/**/*.blade.php',
    './resources/**/*.js',
    './resources/**/*.vue',
    './vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
],
```

### ./resources/css/app.cssの設定
以下を追記
```css:app.css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

### bladeテンプレートの設定
headタグ内に以下を追記

例）
```php
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

        @vite('resources/css/app.css')
        @vite('resources/js/app.js')
    </head>
    ...
```
### "vite.config.js"の設定
以下を追加
```js:vite.config.js
server: {
    host: true, 
    hmr: {
        host: 'localhost'
    },
    watch: {
        usePolling: true
    }
}
```

## Vite開発用サーバの起動
```sh
$ npm run dev
```

## ブラウザでの確認
ブラウザでページを表示して、bladeファイルなどのどこかを編集してみてください。
自動で内容が更新されたら成功です。
【Unity】JetBrainsRiderでRootNameSpaceを設定してもいつの間にかリセットされている

# はじめに
Unityで利用できる強力なEditor `JetBrainsRider` でRootNameSpaceを設定するためにRootNameSpaceの設定を行った際に、いつの間にか設定がクリアされている事象を確認しましたので解決方法を記録します。

https://www.jetbrains.com/rider/

# トラブル内容
Rider設定メニューの`Project Properties > Application > General < Root namespace` に値を設定後にOKを押してもRiderから他のアプリ（Unity等）にフォーカスが移ると設定値がクリアされる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/86b864ed-06cd-2e7a-9879-687290de18f8.png)

# 解決方法
Unity側にRootNameSpaceを設定できる項目があり、Riderの設定値よりもそちらの値が優先度が高く、`Project Properties > Application > General > Root namespace` に上書きされることが原因でした。
Unity側の `ProjectSettings > Editor > Root namepace` に名前空間名を設定することでRider側に反映されることを確認しました。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1336886/acaea432-afe3-1827-1bdb-a83d840381e3.png)


# 公式質問スレッド

こちらで解決方法を教えて頂きました。

https://rider-support.jetbrains.com/hc/en-us/community/posts/15624720886930-Root-namespace-settings-are-cleared?page=1#community_comment_15642661237266
Milk-v duo搭載pinpongライブラリを使用するオープンソースハードウェア「The Xugu Education Edition Kit」

## はじめに
秋葉原ロボット部の有志で、milk-v duoを購入し、個々人が様々な実験を行って、勉強会内で報告しています。

Milk-v duoは9ドルのrisc-vコンピュータとして知られています。
ハードウェアは以下の通りです。

1. CPUはCVITEKのCV1800B (C906@1Ghz + C906@700MHz)
1. 最高1 GHzで動作するデュアルRV64コア
1. 64 MBのラム
1. オプションのアドオンボードを接続すると10/100Mbpsの速度でイーサーネットに接続可能

Milk-v duoでPythonを使う場合、センサ類のライブラリとしてpinpongを使用します。
/usr/lib/python3.9/site-packages/pinpong/examples
のディレクトリを見ると、milk-v duo以外に様々なボードで利用されていることがわかります。
本稿では、「xugu」を利用するボード「虚谷号教育版套件」を紹介します。

## 虚谷号教育版套件(The Xugu Education Edition Kit)
仕様は以下の通り。
https://www.dfrobot.com.cn/goods-2578.html

|||
| :-: | :-: | 
|SOCシステム|Linux ubuntuデスクトップ|
|PYTHON|jupyter/notebook|
|CPU|Quad-core Cortex-A53、最大1.5GHz|
|MCU|8bit Flash MCU, 16-32MHz, Arduino UNO互換, ビルトインxugu通信プロトコル|
|GPU|Mali-450MP2, OpenGL ES1.1/2.0サポート|
|DDR|32-bit幅, 2GB, LPDDR3|
|eMMC|32GB, サポートeMMC 4.41, 4.51, 5.0 and 5.1|
|WIFI/BT|WIFI IEEE 802.11 b/g/n<br>Bluetooth：BT V4.0(HS)|
|HDMI|Mini HDMI 2.0 インターフェース<br>4K×2K 60Hz display, HDCP 1.4/2.2サポート
|USB|1 Micro OTGポート, OTGモード、Uディスクモード (デバイスモード)<br>1 x Micro USB（バックアップパワーコネクタ）<br>USB2.0インターフェース×1、USB3.0インターフェース (ホストAタイプ)×1|
|LED|LED×3、動作状況表示用|

Ununtuデスクトップが動作するボードです。
プログラム環境として、Arduino完全互換でPythonを利用可能です。
pinpongライブラリ使用例として以下のページが紹介されています。
https://mc.dfrobot.com.cn/thread-306300-1-1.html

## 虚谷号使用例
MQTTプロトコル対応IoT
AI
等があります。
https://mc.dfrobot.com.cn/forum-198-1.html
Proxmox VE にデータの入った HDD をマウントする

# はじめに
既にデータが入っている HDD を Proxmox VE の仮想マシン (VM) にマウントする方法について。
(VM のみ対象。 LXC では不可。)

# やり方
0. 製品の型番を控えておく
1. Proxmox がインストールされたマシンに HDD を接続する。
1. Proxmox の web 管理画面に入り、マウントしたい VM を含むノードのシェルを立ち上げて `ls /dev/disk/by-id` を実行。
`控えた型番 + 文字列(シリアルナンバー)` を控える。

0. `qm set {dest id} -{device id} {source device path}` を実行する。
    `{dest id}` = マウント先 VM の ID
    `{device id}` = マウント先 VM での　HDD のデバイス名
    `{source device path}` = 手順 3 で控えた文字列
    - virtio の場合、 `virtio0`, `virtio1` のように `virtio{連番}` とするとよい
    - SATA, SCSI の場合も同じように `sata{連番}`, `scsi{連番}` の形にするとよい
    (`qm set {dest id} -virtio0 /dev/disk/by-id/ata-WDC_WD40EZAX-00C8UB0_WD-WXD2A13N6VL9` を実行した例↓)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2403016/cf6ba6b0-a1b2-af85-10ed-e9b389b0dee9.png)

0. VM を立ち上げて任意のディレクトリにマウントする。

# おわりに
5 時間くらいネットの海を彷徨いました。

# 参考サイト

https://nofu.jp/wiki/virtualization/proxmox_ve_6_2_rdm
あんまり、RDSをいじめないでください。- RDSと他のサービスとのアンチパターン

# ミスった設計から始まる悪夢
実は、ある会社でRDS関連のところでアンチパターンで設計されていたことで、規模が大きくなってきた時にRDSが落ちて休日にサービスが止まってしまったという悪夢のような現実が起こったことがあります。その時、関わっていて、ちょっとお勉強をしたときに、アンチパターンを調べたままだったので、まとめてみました。ぜひ、反面教師として、お使いください。

RDSに興味がある人がこの記事の対象です。

前提として、サービスの規模によってはアンチパターンをわざと採用して、コストを削減することもあります。しかし、あくまでもアンチパターンのため、なるべくベストプラクティスの方向性で書いてみようと思います。

# RDSとは
Amazon RDS（Relational Database Service）は構築や運用を容易にするリレーショナルデータベースサービス。AuroraやDynamoDBとか使っている時は、RDSを使っているということです（RDSのデータベースエンジンの1つがAuroraやDynamoDB）。AWSを使用していて、DBをクラウド上においている場合は、使っていることが多いでしょう。


## 【アンチパターン1】<br> RDSとEC2/Lambdaの組み合わせにおけるデータ転送

RDSとEC2やLambdaとのきみ合わせにおいて、データの転送の仕方を以下のようにしてしまうと非効率でRDSに影響が出てくることがあります。

### やるな！APIの呼び出しすぎ
EC2インスタンスやLambda関数からRDSへのクエリが頻度高く、実行される場合にRDSに負荷をかけることがあります。例えば毎秒100回のクエリが実行される想定で考えると、高い頻度のクエリは、RDSインスタンスのCPU使用率をものすごい勢いで増加させることがあります。実際に僕自身も業務でそのグラフを見たことがあり、ビビりました（笑）通常のCPU使用率が10%だけど、過剰なクエリにより50%以上に跳ね上がったりもします。

### やるな！不要なデータ転送
EC2インスタンスやLambda関数が、必要以上に大きなデータセットをRDSから取得する場合、必要なデータが1MBのにも関わらず、10MB以上のデータを毎度のこと、転送している場合があったりします。不必要なデータを送ること自体そもそもよろしくないのは前提で、こうしたことをするとデータの量に依存して、不必要な帯域幅を消費し、RDSのI/O(Input/Output)パフォーマンス（スループット・IOPS（Input/Output Operations Per Second・レイテンシー（遅延時間）・キューの深さ）に影響を与えます。

### どうなる？

- **CPU使用率の爆上がり**
→ 過剰なクエリはRDSインスタンスのCPU使用率を高め、他の処理に対する影響やレスポンス時間の遅延を引き起こります。

- **メモリの圧倒的消費量を更新**
→ 特に、データのサイズが大きい場合や複雑なクエリを頻繁に実行する場合、RDSインスタンスのメモリ使用率が増加し、パフォーマンス低下の原因となります。

- **ネットワーク遅すぎ**
→ 不要なデータ転送はネットワークトラフィックを増加させ、データ転送時間の増加や他のサービスへの影響をもたらします。


**あんまり、RDSをいじめないでください⚠️**

---

## 【アンチパターン2】<br>S3やセキュリティ設定アンチパターン

AWSサービスを組み合わせる際に、適切なIAMポリシーやセキュリティグループを設定しないことは、セキュリティリスクを高めるアンチパターンです。以下は、このような状況の具体的な例と、それぞれのサービスの簡単な説明です。

### やるな！EC2インスタンスのセキュリティグループの不適切な設定
EC2インスタンスのセキュリティグループで、SSH (ポート22) をインターネットからのアクセスに対して完全に開放する設定にしていたとします。この設定により、インターネット上の任意のアドレスからEC2インスタンスへのSSHアクセスが可能になり、攻撃者からブルートフォース攻撃（無作為にユーザー名とパスワードを試す攻撃）やディクショナリー攻撃（一般的なパスワードのリストを用いる攻撃）などの攻撃をしやすくなります。そういった不正アクセスで、サーバーの侵害リスクが高まります。

### やるな！S3バケットの公開アクセス設定
機密データを含むS3バケットのアクセスポリシーをパブリックに設定の状態だとした場合、ネット上の誰もがそのバケット内のデータにアクセス可能となります。バケット内の顧客データ、財務データ、個人識別情報などの超！超！超！機密な情報が公開されることになります。悪意のあるユーザーはこれらの情報を入手できたりもします。実際やろうと思えばできるようなサービスを見かけたことがあります...

### どうなる？
機密情報の漏洩、マルウェアのインストール、その他のセキュリティ侵害が発生する可能性もあります。また、侵害されたインスタンスはさらなる攻撃の踏み台として使用され、被害が拡大することもあります。最悪の場合、データ漏洩なども起こり、顧客信頼を失ったり、最悪の場合は法的責任なども発生するかもしれません。


## 【アンチパターン3】<br>ECSなどとの依存関係によるアンチパターン

### やるな！Elastic BeanstalkのアプリケーションでのRDS単一インスタンス依存
あるElastic Beanstalkでホストされるウェブアプリケーションが、トラフィックの増加に伴い月間アクティブユーザーが10万人から50万人に増加するとします。このアプリケーションが単一のRDSインスタンスに依存している場合、データベースの負荷が急増しちゃいます...そうすると、アプリケーションのパフォーマンスが著しく低下し、レスポンスがものすごく遅くなる可能性があります。また、ピーク時にRDSがダウンしてサービスが一時的に停止してしまうかもしれません。

### やるな！ECS/EKSでのRDS単一インスタンスへの過度な依存
AWSのECS（Elastic Container Service）またはEKS（Elastic Kubernetes Service）を使用して、数十のコンテナ化されたマイクロサービスを実行している状況を考えます。これらすべてのサービスが同じ単一のRDSインスタンスに接続しているとします。 単一のデータベースインスタンスが過負荷になり、クエリの遅延やタイムアウトが頻発するような現象が起こります。特に、データベースへの書き込みや読み込みが集中すると、パフォーマンスの問題が顕著になる可能性があります。


### どうなる？
ユーザーエクスペリエンスの低下により、顧客満足度が損なわれ、サービスの評判に悪影響を与える可能性があります。また、サービス全体の可用性と信頼性が低下し、顧客に対するサービス提供に支障をきたすことがあります。また、データベースの障害はシステム全体のダウンタイムが発生し、機会損失を引き起こすかもしれません。


---
<br>

# 最後に
「あんまり、RDSをいじめないでください。」
Milk-v duo搭載pinpongライブラリを使用するハードウェア「UNIHIKER」

## はじめに
秋葉原ロボット部の有志で、milk-v duoを購入し、個々人が様々な実験を行って、勉強会内で報告しています。

Milk-v duoは9ドルのrisc-vコンピュータとして知られています。
ハードウェアは以下の通りです。

1. CPUはCVITEKのCV1800B (C906@1Ghz + C906@700MHz)
1. 最高1 GHzで動作するデュアルRV64コア
1. 64 MBのラム
1. オプションのアドオンボードを接続すると10/100Mbpsの速度でイーサーネットに接続可能

OSイメージ1.5.0からpythonからpinpongライブラリを使って、各種センサー類を利用可能となりました。
同梱されている例を使っていると、エラーメッセージに「UNIHIKER」の名前が出てきます。
本記事では、UNHIKERについて調べたので、その情報をまとめておきます。

## UNIHIKERの仕様
UNIHIKERの公式サイト
https://www.unihiker.com/
を表示すると、スクリーンと搭載したボードであることがわかります。
仕様は以下の通り。
| | |
| :-: | :-: | 
|製品名|UNIHIKER|
|CPU|Quad-Core ARM Cortex- A35, up to 1.2GHz|
|RAM|512MB|
|Flash|16GB|
|OS|Debian|
|Wi-Fi|2.4G|
|BT|Bluetooth 4.0|
|スクリーン|2.8inch, 240x320, Touch Screen|
|MCU|GD32VF103|
|センサ|ボタン<br>マイク<br>照度センサ<br>加速度センサ<br>ジャイロセンサ
|アクチュエータ|LED, ブザー|
|ポート|USB Type-C, USB-A<br>マイクロSD<br>底面 3ピン/4ピンポート<br>側面コネクタ|
|電源|5V 2A, USB Type-C|
|サイズ|51.6mmx83mmx13mm|

OSがDebianで、pythonが動作するのが特徴です。
プログラミング環境として、以下のものが利用可能です。
Visual Studio
Vim
Thony
Jupyter
Mind+


## UNIHIKERの使用例
AIoT、ロボット、STEMへの例が紹介されています。
https://community.dfrobot.com/projects-UNIHIKER.html
「世界一流エンジニアの思考法」を読んで、そのメモ

読書記録です。「世界一流エンジニアの思考法」を買ったまま読み切れていないでいたのだが、ようやくななめ読みして、そのメモ。


[世界一流エンジニアの思考法](https://www.amazon.co.jp/dp/4163917683)

![](https://m.media-amazon.com/images/I/81RO+wECc0L._SY466_.jpg)



## キーフレーズ

- 理解には時間がかかる。人に説明できるようにする。
- Be lazy. Fail fast. 優先順位づけ。
- 成功しようがしまいが、まずはやってみて、早くフィードバックを得て、早く間違いを修正していく。
- 失敗を受け入れる。
- フィードバックが感謝される。
- 挑戦とその結果が評価される。
- 脳みその負荷を減らす。
- 何もググらずできる <- ここをふやす
    - ググればできる
        - スパイクソリューションがあればできる
            - 無理
- クイックコール
- 気軽に聞ける仕組み、気軽に断れる空気
- 人の意見を否定しない、自分主語で互いを伝え合うコミュニケーション
- チームワーク
- 定時上がりは効率がいい
- 体力
- 「批判」の文化がすべてをぶち壊しにする
- コントリビュートと感謝

## 他 参考

https://x.com/iwashi86/status/1716931692030734559?s=20


https://dev.classmethod.jp/articles/review-how-world-class-engineers-think-book/

https://note.com/dora_e_m/n/nb2594a938d53

https://shinyorke.hatenablog.com/entry/how-world-class-engineers-think

https://zenn.dev/raishi12/articles/e2a96581982cbf

https://qiita.com/Yuzaburo/items/542e8c87c6c3401e0002

https://qiita.com/masafumi330/items/43f9129a0d3a1112640f



## つづく

他、以下も積読なので読み直したい。

- [学びなおしで読みなおしたい本 2023 秋 #まとめ - Qiita](https://qiita.com/e99h2121/items/71275466af6513fc188f)

つづく。
256 MBのRAM搭載のMilk-v duoが発表されました

## はじめに
秋葉原ロボット部の有志で、milk-v duoを購入し、個々人が様々な実験を行って、勉強会内で報告しています。

Milk-v duoは9ドルのrisc-vコンピュータとして知られています。
ハードウェアは以下の通りです。

1. CPUはCVITEKのCV1800B (C906@1Ghz + C906@700MHz)
1. 最高1 GHzで動作するデュアルRV64コア
1. 64 MBのラム
1. オプションのアドオンボードを接続すると10/100Mbpsの速度でイーサーネットに接続可能

2023年12月7日のX.comで流れてきたのですが、milk-v duoに256 MBのRAMを搭載したボードが発表されました。
https://twitter.com/MilkV_Official/status/1732709520135315909
オリジナルの情報が見つからないので、X.comに掲載の図を見ながら、詳細を調べます。

## ArmとRisc-VのCPUを搭載
64 MBのRAMのmilk-v duoには、C906@1 GHzとC906@700 MHzのCPUが搭載されていました。
256 MBのRAMのmilk-v duoには、さらに、Cortex-A53@1 GHzも搭載されます。
このCPUはC906@1 GHzと互換性はないそうです。
Risc-VとArmとの切り替えは、1クリックで行えるようで、実際にどのようになるのか興味が持たれます。

## MCUとして8051@6 KB SARMを搭載
MCUとして8051@6 KB SARMを搭載ということは、8051互換のCH55X用ソースファイルが活用できるということでしょうか？
個人的には、8051CPUのシングルボードコンピュータとして、MONITOR-51やBASIC-52が使えるのか気なるところです。

## Audio出力に対応
64 MBのRAMのボードでもI2Sのパッチをカーネルに当てて、ETH用ポートから音声を出力できるようですが、私は実現に至っておりません。
標準で音声出力に対応するとなると、AIへの応用がインタラクティブになりますね。

## Arduino IDEでC906@700 MHzを制御可能
Arduino IDE対応となると、ユーザーフレンドリーな開発環境になります。
カーネルのビルドからはじめなければいけない64 MBのRAMのボードより、ユーザーが増えそうです。

## どこで入手できるか
2023年12月8日現在、中国外の人には、ARACEからの購入が進められます。
https://arace.tech/products/milk-v-duo?variant=42525052534964
Pre-orderですが、「In stock」との表示がありますので、製品が完成したら、即、送付されるのでしょう。
ただ、悩ましいのが、本体が1200円に対し、輸送費が1800円かかるところです。

入手できましたら、使用感などのレポートを行いたいと思います。
HEICからPNGへ変換すーる（Python）

# はじめに
[がちもとさんアドベントカレンダー](https://qiita.com/advent-calendar/2023/gachimoto3)9日目の記事です。
iPhoneの画像をPCに取り込んだ時に、拡張子がHEICになっちゃってるので、PNGに変えていきます。

# 開発環境
- Windows 11 PC
- Python 3.11

# 導入
1．ライブラリのインストール
pip install pillow, pillow_heif

2．プログラムを作成

~~~heic2png.py
import os
from PIL import Image
import pillow_heif

# 変換元のフォルダと変換後のフォルダを指定します
input_folder = "input/heic/"
output_folder = "output/png/"

# 変換元のフォルダ内のHEICファイルを取得します
heic_files = [f for f in os.listdir(input_folder) if f.endswith('.HEIC')]

for heic_file in heic_files:
    # HEICファイルのパスを作成
    heic_path = os.path.join(input_folder, heic_file)
    
    # PNGファイルのパスを作成
    png_file = os.path.splitext(heic_file)[0] + '.png'
    png_path = os.path.join(output_folder, png_file)
    
    # HEICファイルをPNGに変換
    heif_file = pillow_heif.read_heif(heic_path)
    image = Image.frombytes(
        heif_file.mode, 
        heif_file.size, 
        heif_file.data,
        "raw",
        heif_file.mode,
        heif_file.stride,
    )
    image.save(png_path, 'PNG')
    
    print(f'{heic_file} を {png_file} に変換しました。')

print('変換が完了しました。')
~~~

このスクリプトを実行すると、指定したフォルダ内のすべてのHEICファイルがPNG形式に変換され、指定した出力フォルダに保存されます。

お疲れさまでした。
OpenAIのGPT-4Vでもうちょっと遊んでみーる

# はじめに
[がちもとさんアドベントカレンダー](https://qiita.com/advent-calendar/2023/gachimoto3)8日目の記事です。
今日は、OpenAIのGPT-4V（画像説明）でもうちょっと遊んでみます。
実装方法はこちらです。

https://qiita.com/SatoshiGachiFujimoto/items/2bdcd94e9ff2e36d4836

# 開発環境
- Windows 11 PC
- Python 3.11

# 実行結果

|画像|説明|
|:--|:--|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/5d774fa8-3990-4a64-696b-a12613e24a8f.png)|Q. 点字ブロックは映っていますか？<br>A. はい、この写真には点字ブロ ックが映っています。床に黒色で目立つ直線状のガイドとして 設置されているのが 点字ブロックです。これは視覚障害者が歩行時に道を見つけやすくするためのもので、特に公共の場所でよく見られます。写真には、その点字ブロックが直進方向に伸びているのが確認できます。|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/a7303565-548e-786e-4eca-e4f5762ab8f0.png)|Q.点字ブロックは映っていますか？<br>A. いいえ、この写真には点字ブロックは映っていません。点字ブロックは、視覚障害者が歩行時に道を認識しやすくするための舗装材で、通常、地面に隆起した点や線が特徴です。この写真には、そういった特徴は見られません。フロアは様々な色のタイルで装飾されているように見えますが、点字ブロックではないようです。|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/e99a74c1-ffda-b851-8f1e-49fce2f19087.png)|Q. 現在位置はどこですか？<br>A. この写真は、熊本市のエリアガイドという地図が掲示されている看板のようです。看板には「周辺案内」と記載されており、熊本市の主要な施設や道路が表示されています。写真だけでは看板が設置されている正確な場所を特定することはできませんが、熊本市内にあることは明らかです。熊本城や市街地が地図に描かれていることから、訪問者はこの地図を参考に周辺を探索することができるでしょう。具体的な場所や目的地を確認するためには、地図上の目印やインデックス、道路名などを見る必要があります。|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/5cbfb78b-4721-2e41-ee15-866e638c0c31.png)|Q. 花畑町はどっちですか？<br>A. 花畑町（Hanabatacho）は左方向にあります。|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/90a4bb45-8385-2606-ba28-5d10d049248f.png)|Q. 何が映っていますか？<br>A. この写真にはエスカレーターが映っています。エスカレーターの両側には手すりがあり、上がりと下がりの二つのエスカレーターが写されています。エスカレーターの近くには階段も見えます。そして、通路の床には滑り止めのマットが敷かれており、「B」の文字が マットに印刷されているので、これはおそらく地下階を表していると思われます。また、天井には照明が設置されており、照明からの光がエスカレーターを照らしています。避難経路を示す緑色の出口標識も画像の上部に見えます。|

通常なら画像分類や物体検出をして、そこに点字ブロックやエスカレーターがあるとか理解させる必要があったのですが、画像説明でできちゃうとは思ってもみなかったです。マジでどうやってるんですかね、、もう人間みたいだし、可能性しかないですね。

お疲れさまでした。
Python Quiz (for newbie)

## はじめに
Pythonの知見が浅い自分が，X（旧Twitter）を見ていてへぇ～となったQuizを取り上げます．初学者向けです．

## 問題
### [<ins>Quiz1</ins>](https://twitter.com/Python_Dv/status/1732945339848790122)
```python
>>> a = ~4
>>> b = a + 4
>>> print(b)

Output:
1. -1
2. 1
3. 2
4. -2
```

### [<ins>Quiz2</ins>](https://twitter.com/Python_Dv/status/1732355956250648717)
```python
x = [1, 3, 8, 6, 8, 9]
y = set([1, 4, 7, 9, 7, 4])
print(len(x) + len(y))

Output:
1. 9
2. 12
3. 8
4. 10
```

### [<ins>Quiz3</ins>](https://twitter.com/Python_Dv/status/1730002448352198972)
```python
print(0.1 + 0.2 == 0.3)

Output:
1. True
2. False
3. Machine dependent
4. Error
```

## 解説
簡単に解説していきます．
### Quiz1
Answer -> -1

L1の```~```演算子はビット反転を意味します．
Python3では```~```演算子で反転する際に，オペランドが正数だと値の先頭が無限個の符号ビット「0」で埋めたもの(...00000100)とみなされるので，反転した結果の値の先頭はそれが全て反転された無限個の符号ビット「1」で埋めたもの(...11111011)とみなされます．
演算結果は符号ビットが「1」の負数-5として出力されます．

詳細はこちら -> [Python3での2の補数と~演算子(ビット反転)](https://zenn.dev/treefield/articles/c15d13987f3c72)

今回のケースでは，4(0100)のビット反転なので1011となり，これは10進数で-5となります．

### Quiz2
Answer -> 10

len関数はオブジェクトの長さや要素数を取得します．
set関数はリストと同様に複数の要素から構成されます．リストと異なる点は"要素の重複"がなく，"要素の順番がない"ことです．

今回のケースでは，yは以下のようになります．
```python
>>> y = set([1, 4, 7, 9, 7, 4])
>>> print(y)
{1, 4, 9, 7}
```

### Quiz3
Answer -> False

浮動小数点数0.3の値は，必ずしも正確な0.3とは限らず，0.323や0.3426などになる可能性があり，0.3(0.1 + 0.2)とは等価ではありません．
ILI9163Vで遊ぶ(部品一覧)ATM0177B3A



https://qiita.com/caa45040/items/3dcc3f8336b0a2c86a80


ILI9163Vで遊ぶ(部品)ATM0177B3A


x過去ログを見よ


![o_cop848.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/29688b1f-6663-a6dc-d2c4-79be5460c0c6.jpeg)



----------------------------------------------

●1.カラー液晶　要加工　12ピンを10ピンに削る 1,2,3,4,5

![o_cop841.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/fddf7708-a40e-749f-59b8-212e338cf10a.jpeg)


１．７７インチ　カラーグラフィックＴＦＴ　ＬＣＤ（１２８×（ＲＧＢ）×１６０ドット）　ＡＴＭ０１７７Ｂ３Ａ
[ATM0177B3A]
通販コード　P-13618
発売日　2020/11/30
メーカーカテゴリ　Xiamen Zettler Electronics Co., Ltd.

----------------------------------------------

●2.変換基板

![o_cop842.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b2a788db-ee62-fd11-cbba-a8449041ffe7.jpeg)


フレキコネクタＤＩＰ化キット（０．５ｍｍ１０Ｐ）
[AE-CNCONV-10P-0.5]
通販コード　K-07253
発売日　2014/04/30
メーカーカテゴリ　株式会社秋月電子通商

----------------------------------------------

●3.薄型基板

![o_cop843.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f84a849e-c6b2-72a8-a87f-d225e20a13d0.jpeg)


片面ガラス・薄型ユニバーサル基板Ｃタイプ（７２×４８ｍｍ）めっき仕上げ（日本製）
通販コード　P-04718
発売日　2011/04/15
メーカーカテゴリ　株式会社矢島製作所

----------------------------------------------

●4. 線の端材

![o_cop844.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/071e10be-1c8d-ea62-ab59-30a779a74424.jpeg)


耐熱電子ワイヤー　１ｍ×１０色　導体外径０．５４ｍｍ（ＡＷＧ２４相当）
[0.2sq (7/0.18) AWG24x10]
通販コード　P-10672
発売日　2016/06/09
メーカーカテゴリ　住友電気工業株式会社

----------------------------------------------

●5.コネクター

![o_cop845.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/43d65189-e818-b431-59ed-265ebf56113b.jpeg)


Ｌ型ピンソケット　１×１０（１０Ｐ）
[FH-1x10RG]
通販コード　C-12984
発売日　2018/03/20
メーカーカテゴリ　Useconn Electronics Ltd.

----------------------------------------------

●6.ジャンパーケーブル

![o_cop846.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/c7ef0ed7-f7d2-a2be-a5ec-9ca85eefde23.jpeg)


ブレッドボード・ジャンパーワイヤ（オス－オス）セット　各種　合計６０本以上
[BBJ-65]
通販コード　C-05159
発売日　2011/09/19
メーカーカテゴリ　Cixi Wanjie Electronic Co.,Ltd(慈渓市万捷電子有限公司)

----------------------------------------------

●7.接着剤

![o_cop847.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/e3bd5b4c-ce30-878b-56ba-be5f8d30b5f5.jpeg)


ダイソー・ボンドG17

クロロプレンゴム系
コニシ株式会社

----------------------------------------------
【wttr.in】ターミナル/VSCodeから最速3秒で天気を確認する

## 天気を見るのに何秒掛かってるの？？？

天気予報を見ないって人、もうなかなかいないと思います。

天気を把握していないと不必要に濡れることになったり、凍えながら学校に行くことになったりします。

天気を確認して傘やコートを持っていくか確認したい。でも電車がもう来ちゃう。そんな時にスマホ開いて…ってやってたら電車行っちゃいますよ？？

天気予報は毎日使うものだからできるだけ早く情報にアクセスしたいです。別アプリを開くことなく、普段作業しているVSCodeやターミナルからアクセスできたらマウスに手を伸ばさなくていいので理想。

時間の積み重ねは大きな差につながる。**塵も積もれば∫インテグラル∫**

## 私の環境

長いので折りたたみます。

<details><summary>環境一覧</summary>

```
OS: macOS 14.1.1 23B81 arm64
Host: Mac14,2
Kernel: 23.1.0
Uptime: 7 days, 4 hours, 40 mins
Packages: 31 (brew)
Shell: zsh 5.9
Resolution: 2560x1440
DE: Aqua
WM: Quartz Compositor
WM Theme: Blue (Dark)
Terminal: iTerm2
Terminal Font: UDEVGothic35NFLG-Regular 16
CPU: Apple M2
GPU: Apple M2
Memory: 4306MiB / 24576MiB
```
``` zsh
% zsh --version                                                  
zsh 5.9 (x86_64-apple-darwin23.0)
```
</details>


## wttr.inで天気を取得する

curlを使うと端末からサーバへリクエストし、データを転送できます。[^1]

物は試しでcurlをまず叩いてみましょう。

```
% curl wttr.in/gifu
```

![スクリーンショット 2023-12-09 3.00.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/73bce4a8-d4d1-c5db-22a8-0e5e6d79cdea.png)

こんな感じに帰ってくると思います。

## 構文

```
% curl wttr.in/地名?オプション
```

オプションは例えばそこまで細かく情報いらないんだよなとかコンパクトに表示して欲しいんだよなって時に使います。基本なしでいいです。

## curlは遅い！！ .zshrcに追加して最速を狙う

現代人は忙しいのでさっきのコマンドを悠長に叩いている暇なんてありません。もっと速く。

おそらく`.zshrc`をいじってコマンドとして登録しちゃうのが楽だと思うのでそうします。

``` zsh
% vim ~/.zshrc
```

して末尾にこんな感じに追記します。

``` zsh
function wtr(){
    curl "https://ja.wttr.in/$1?2nF"
}
```

- `ja.`はただの日本語対応
- `2`は今日と明日の分だけ表示してコンパクトに
- `n`はnarrowモード（朝夕の天気のみ表示）
- `F`はコマンド末尾の`Follow @igor_chubin for wttr.in updates`を非表示にする

コマンドらへんは自分の好みにカスタマイズするのがいいと思います。https://wttr.in/:help を参照してください。

あとはzshを開き直すか、

```
% source ~/.zshrc
```

して.zshrcを読み込み直せば準備OKです。

## 使い方

``` zsh
% wtr 地名
```

を入れるだけで天気がババっと出ます！！！

![スクリーンショット 2023-12-09 3.13.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/f2ff0909-e64e-b944-092c-5cb830be6861.png)

こんな感じでプログラム書いてる最中でもすぐに天気見れます

## おわりに

こんなコマンド登録したりcurl叩いてる暇あるなら、手元のiPhone見た方が早いと思います。

[^1]: https://qiita.com/tana0422/items/8e3d36b54638df7f6a4c
危険な方法でdevcontainer内からgit push等できるようにする

# 危険な方法でdevcontainer内からgit push等できるようにする

大変便利なdevcontainerですが、少しだけ不便なところがあります。
それは、ssh_keyがホストとコンテナで共有されないため、devcontainer内からgit push等の操作ができないことです。
本来であれば、ssh-agentを利用して安全に鍵を共有する必要があるのですが、Windowsではssh-agentが少しややこしかったりします。
（参考: <https://qiita.com/slotport/items/e1d5a5dbd3aa7c6a2a24>）
めんどくさいからとりあえずgit pushだけさせてくれ！時間がないんだ！！
という方のために、危険ですがすぐにdevcontainer内でgit pushできるようにする方法があります。

**何度も言いますが、これは危険な方法です。ローカルのdevcontainer内だけに収まるならまだ良いですが、何かの拍子に秘密鍵が外界に触れてしまうと大変なことになります。**
**自分が何をしているかを理解し、十分に危険性を理解した上で秘密鍵は慎重に取り扱ってください**

## やり方

以下のような記述をdevcontainer.jsonに加えます
``` json
{
    (...)
    "postCreateCommand": "cat .git_ssh_key > ~/.ssh/id_rsa && chmod 600 ~/.ssh/id_rsa"
}
```

前提として、以下のdocker-compose.ymlのようにホストのディレクトリがDevContainer内の作業ディレクトリにマウントされている必要があります。
``` yaml
version: "3"
services:
  app:
    (...)
    volumes:
      - .:/workspace
      - ssh-key:/root/.ssh

volumes:
  ssh-key:
```

上記の条件を満たした状態で、ホスト側のターミナルで以下のコマンドを実行します。

Mac/Linux

``` bash
echo .git_ssh_key >> .gitignore
cat ~/.ssh/id_rsa > .git_ssh_key
```

Windows

``` bash
echo .git_ssh_key >> .gitignore
type %homepath%\.ssh\id_rsa > .git_ssh_key
```

上記コマンドを実行後、DevContainerをリビルドします。
すると、DevContainer内でgit push等ができるようになります。

## 仕組み解説

端的に言うと、ホストマシンの秘密鍵をDevContainer内の~/.sshにコピーしています。
devcontainer.jsonに追加した```"postCreateCommand"```という記述ですが、これはDevContainerを生成（ビルド）したときに、コンテナ内で指定したコマンドを実行できるオプションです。
これを利用して、ホストマシンから受け取った秘密鍵をDevContainer内の~/.sshにコピーしています。
ホストマシンから秘密鍵を渡す際には、ホストマシンの~/.sshにあるid_rsaファイルを作業ディレクトリにコピーし、DockerComposeのディレクトリマウント経由で渡しています。
上記コマンドでは.gitignoreに秘密鍵のファイルを指定してgitの管理下に置かれないようにしていますが、実際に試す際には非常に慎重に厳重にgitの管理下に置かれていないことを確認してください。
**何度も言いますが、絶対に秘密鍵を外界に触れさせないでください。**

## おわり

素直にssh-agent使いましょう。
Amazon Qがモバイルアプリで利用可能になりました


# ■概要

先日プレビューが公開となった生成型AIアシスタントである「Amazon Q」が、モバイルアプリにて利用可能となりました！
簡単な内容になりますが、ここではモバイルアプリでの「Amazon Q」について書いてみます。

AWS Announces Amazon Q is available in preview on the AWS Console Mobile App for iOS

https://aws.amazon.com/about-aws/whats-new/2023/12/amazon-q-preview-console-mobile-app-ios/

# ■Amazon Q について
端的に言うと、AWSのリソースを参照できるChatGPTというイメージです。
Amazon Qについては別記事で書いていますのでご一読ください。

AWSの新サービス「Amazon Q」はAWSリソースを参照できるChatGPT？
https://qiita.com/zenden/items/aafbe2e0c92c39409cb5

# ■AWS Console Mobile Application
そもそもAWSコンソールのモバイルアプリについてですが、移動中でもCloudWatch、Health Dashboard、Billing等が確認できるというものです。（IOSとAndroidで使用可能）

モバイルの画面は以下のようなになっています。

![20231209022150.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954355/fc6b045f-fa9a-0682-742d-2d04da0db5a4.png)

![20231209022241.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954355/66df5208-551f-6b5f-f9cd-abd472a3f458.png)


CloudShellも実行できるみたいですね。

![20231209022317.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954355/fee6afec-c1cf-5dd7-5f02-23fbed81158c.png)

取得は以下より。

App Store

https://itunes.apple.com/us/app/aws-console/id580990573?mt=8

Google Play

https://play.google.com/store/apps/details?id=com.amazon.aws.console.mobile&hl=en_US

# ■モバイルアプリで使える「Amazon Q」
ちょっとしたアップデートとなりますが、
上述したモバイルアプリでAmazon Qが使用できるようになった事が今回の新機能となります！

実際の画面は以下

![20231209022301.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954355/d8b5c502-f8e4-b2ec-2a00-065fa496caa2.png)

# ■モバイルアプリとWEBで違う事

WEB版のAmazon Q とは違う点として、アプリ版では音声での入出力操作が可能となっています。
入力する際にマイクを使用した文字入力が可能であり、生成した回答を音声出力する事が可能となっています。
現在の所、大きく違う点はこの一点だけみたいですね。

# ■最後に
WEB版とアプリ版、いずれもプレビューという状態ではあるので今後の機能発表に期待です！
とても楽しみです〜
Arduinoのレジスタをざっと理解する 後編【ブール代数】

:::note warn
情報処理の講義でArduinoのレジスタを触り始めたのですが、解説が絶望的なのでクラスの誰か一人でも救済できたらいいなと思って書いた記事です。
:::

## 前回のあらすじTL;DR

- レジスタ操作はただのC言語ゲーミング！！！！
- ただのdigitalWrite禁止縛り
- レジスタ変数を操作するとピンを操作できる

詳細は[こちら](https://qiita.com/shirokuma89dev/items/3d73d1450fb398eedf2e)

## 個別でピンを操作する

前回の

```c
PORTD = 0B01000000;
```

を改善していきたいと思います。このプログラムはPD6をHIGHに設定するプログラムです。ピンの対応表は前回の記事にもあったこちらの表を参照してください。（DDRをPORTに置き換えてね）

![アートボード 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/4a1a9044-f9cc-93d8-0a11-4a57e1c3d543.png)

しかしこのプログラム、一部問題があります。PD6以外は全てLOWになってしまいます。対して

``` c:
digitalWrite(6, HIGH); //6番ピンはPD6
```

は6をHIGHにしますが6以外は操作しません。これを今回はポート操作で実現していきます。

## ビット演算子

ここでビット演算子について復習します。FJT先生のディジタル回路でやったブール代数は理解してる前提で行きます。

### &（論理積）

![アートボード 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/52e66d46-f3d1-aee7-db3d-96dec87e70ab.png)

ここでX<sub>n</sub>はXのn bit目を表すものとします。

論理積はいわゆる掛け算です。元のデータがA、操作をBとした時に以下のように考えるとわかりやすいです。

- Bが1のところはAが引き継がれる
- Bが0のところは強制的に0になる

### |（論理和）

![アートボード 4_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/9e387f0e-f8c7-8fdf-4492-3c0477f24499.png)

論理和はいわゆる掛け算です。元のデータがA、操作をBとした時に以下のように考えるとわかりやすいです。

- Bが0のところはAが引き継がれる
- Bが1のところは強制的に1になる

## ビット演算子を用いたレジスタの操作

### 0→1

「Bが1のところは強制的に1になる」という性質を使いたいので論理和を使います。

```c
PORTD = PORTD | 0B01000000;
```

こうすると

- PD6以外はPORTDがそのまま引き継がれる
- PD6は強制的に1になる

となります。つまり

``` c:
digitalWrite(6, HIGH); //6番ピンはPD6
```

と完全に同等です。

## 1→0

「Bが0のところは強制的に0になる」という性質を使いたいので論理積を使います。

```c
PORTD = PORTD & 0B10111111;
```

こうすると

- PD6以外はPORTDがそのまま引き継がれる
- PD6は強制的に0になる

となります。つまり

``` c:
digitalWrite(6, LOW); //6番ピンはPD6
```

と完全に同等です。

## 省略形

便利なので覚えておきましょう。

```c
PORTD = PORTD | 0B01000000;
PORTD |= 0B01000000;

PORTD = PORTD & 0B10111111;
PORTD &= 0B10111111;
```

## 【発展】ド・モルガンの法則

原理を理解してしまえば、あとはブール代数ゲーなのでド・モルガンの法則を適用できます。

**論理和**

```math
\begin{align}
C &= A + B \\
&= \overline{\overline{A}} + \overline{\overline{B}}\\
&= \overline{\overline{A} ・ \overline{B}}\\
\end{align}
```

**論理積**

```math
\begin{align}
C &= A ・ B \\
&= \overline{\overline{A}} ・ \overline{\overline{B}}\\
&= \overline{\overline{A} + \overline{B}}\\
\end{align}
```

まぁそれはそうって感じですね。これを使ってさっきの式を書き換えると、

```c
PORTD = PORTD | 0B01000000;
PORTD = ~(~PORTD & 0B10111111);
```

```c
PORTD = PORTD & 0B10111111;
PORTD = ~(~PORTD | 0B01000000);
```

です。`~`は反転の記号です。

まぁこれくらい覚えておけばEND先生に煽られることはないと思います。

## ビットシフト

シフト演算子を思い出してください。これらはそれぞれ同様です。

```c
PORTX |= 0B01000000;
PORTX |= 0B1 << 6;
```

```c
PORTX &= 0B10111111;
PORTX &= ~(0B1 << 6);
```

補足すると、論理和の方は`0B00000001`をシフトした後に反転しています。

## チートシート

最悪これ覚えておけばおｋ

```c
PORTX |= 0B01000000; // 0→1
PORTX |= 0B1 << 6;   // 0→1
PORTX &= 0B10111111; // 1→0
PORTX &= ~(0B1 << 6);// 1→0
```

DDRXについても同様です。

## おわりに

おわりです
Dataform の SQLX ファイルには何を記述するのか


## はじめに

Dataform では SQLX ファイルにデータの取得先、データの変換、データの保存先等様々定義します。
この記事では、SQLX ファイルの基本的な記述方法とその活用例について詳しく解説します。

## SQLX ファイルとは

Dataform で扱う SQLX ファイルは SQL と JavaScript を 1 ファイルに記述します。

はじめににも記載している通り、 SQLX ファイルには 「データの取得先」「データの変換処理」「データの保存先」を定義します。

SQLX はメジャーなファイル形式ではないため、シンタックスハイライト等エディタで利用できないことが補とんとです。
(動作確認出来ているのは) VSCode と Vim/Neovim だけですが Plugin もあります。

https://qiita.com/mziyut/items/5dc8854fac13e04327f6

## SQLX ファイルの記載する内容

SQLX ファイルには、拡張子名そのまま SQL を記載します。また、必要に応じてデータ入出力等を設定する Config や、共通処理等を定義、利用する JavaScript も記述することが出来ます。
上記に記載した、それぞれ記述する各項目について簡単な例を書いてみました。

### Config

Config は 出力先の情報(Table や Column) の定義や、 assertion や uniqueKey 等テストに必要な定義を行います。
今回は、 Google Cloud 上の Dataform を利用し Dataform を動かす想定であり、共通の出力先設定などは `dataform.json` に記載しており、各 sqlx ファイルには個別指定しません。

```sqlx:hoge.sqlx
config {
  type: "table",
  description: "Description of the record",
  columns: {
    id: "PK",
    name: "User name"
  }
}
```

https://cloud.google.com/dataform/docs/document-tables?hl=ja#add_column_and_record_descriptions

ただし、 Label や Partition 定義等必要に応じて定義してください。
Config に設定するオプションは数が多いので以下ページを参考にしてください。

https://docs.dataform.co/reference#ITableConfig

https://docs.dataform.co/reference#IBigQueryOptions

### SQL

字の通り SQL を記載します。簡単な Table を用意しました。

```mermaid
erDiagram
    USER {
        int id PK
        string name
        timestamp created_at
    }
    ARTICLE {
        int id PK
        int user_id
        string title
        text body
        timestamp created_at
    }
```

上記のような Table があったとします。
USER と ARTICLE のデータを使い 1 つのデータを作成するような場合は以下 SQL を sqlx ファイルに定義します。
SQL の実行結果が Config で定義した Table/View 等に出力されます。

```sqlx:hoge.sqlx
SELECT
  USER.id AS user_id,
  ARTICLE.id AS article_id,
  ARTICLE.title AS article_title
FROM
  USER
JOIN
  ARTICLE ON (USER.id = ARTICLE.user_id)
```

### JavaScript

Dataform は SQL だけでなく、 JavaScript を使って処理や変数等をまとめて定義、利用することができます。
実際に JavaScript を定義して使う場面は別の記事として公開していますのでこちらを確認してください。

https://qiita.com/mziyut/items/ccf2c58ae44c49a34b04

### 最後に

SQLX に定義する Config, SQL, JavaScript それぞれを簡単に説明しました。
例に挙げた定義を 1 つの SQLX に書くと以下のようになります。

```sqlx:hoge.sqlx
config {
  type: "table",
  description: "Description of the record",
  columns: {
    id: "PK",
    name: "User name"
  }
}

js {
  // 定義する必要があれば記載
}

SELECT
  USER.id AS user_id,
  ARTICLE.id AS article_id,
  ARTICLE.title AS article_title
FROM
  USER
JOIN
  ARTICLE ON (USER.id = ARTICLE.user_id)
```

Dataform は SQLX 以外に JavaScript だけを使用することもできますが、SQLX を利用するほうが直感的かつ簡単に定義し利用できるのでとてもおすすめです。

https://cloud.google.com/dataform/docs/javascript-in-dataform?hl=ja

## References

https://docs.dataform.co/guides/sqlx
GoでGoroutine・Mutexのメモ

# はじめに

どうも僕です。
最近Goroutineを使った処理を書くことがあって、毎回うろ覚えだったのでメモしていきます。

# Goroutine・Mutexについて
**Goroutine**（ゴルーチン）は言わずもがな、プログラムで並列に実行される作業単位のことです。
Goのいいところポイントの１つでもありますね。

**Mutex**はGoroutineが同時に実行される場合、共有リソースへのアクセス制限・保護をするのがMutexです。

ゴルーチンで回す関数の中で特定のデータを更新していく場合、そのデータの競合を防ぐのがMutexってワケですな

# サンプルコード
[PlayGround](https://go.dev/play/p/ebF0AJ6o36R)
```go:sample.go
package main

import (
	"fmt"
	"sync"
	"time"
)

var (
	mutex         sync.Mutex
	requestCount  int
	requestCount2 int
)

func main() {
	count := 0
	var wg sync.WaitGroup
	for count < 100 {
		wg.Add(1)
		go func(count int) {
			defer wg.Done()
			MutexTest()
            //NoMutexTest()
		}(count)
		count++
	}
	wg.Wait()
}

func NoMutexTest() {
	requestCount++
	fmt.Println("requestCount is: ", requestCount)
}

func MutexTest() {
	mutex.Lock()
	defer mutex.Unlock()
	requestCount2++
	fmt.Println("requestCount2 is: ", requestCount2)
}
```

## 解説
コードの内容としては、100回ループしてMutexがある関数とMutexがない関数で結果を見てみるコードです。
元々はAPIテスト用のモックサーバを作る際、リクエスト制限をつけるためにこのようなコードを作成しました。

`MutexTest`関数は`mutex.Lock`・`defar mutex.Unlock()`の二つがあります。

このLock・Unlockでデータの保護をするワケです。
Rubyで、テスト対象のコードで exit していると RSpec がそこで正常終了する

並行で行っている RSpec のテストの実行数がなぜか実行ごとに異なるという問題が発生した。実行ログを調査したところ、テストの途中で RSpec が正常に終了していることがわかった。原因はテストコード中で [`exit` を実行](https://docs.ruby-lang.org/ja/3.2/method/Kernel/m/exit.html)していること。特に rake タスクのテストとかで結構あると思う。


例えば、このようなコードがあり

```ruby:main.rb
def assert_some_conditions!(conditions)
  if conditions == 1
    exit
  end
end
```

このようなテストを書いた時、

```ruby:main_spec.rb
require 'rspec'
require './main'

RSpec.describe 'assert_some_conditions!' do
  it 'be nil when 1(まちがい)' do
    expect(assert_some_conditions!(1)).to be_nil
  end

  it 'be nil when 0' do
    expect(assert_some_conditions!(0)).to be_nil
  end
end

```

二つ目の `it` が実行されないままテストが**正常終了**する！！

```
$ bundle exec rspec main_spec.rb -fd

assert_some_conditions!

Finished in 0.00046 seconds (files took 0.04432 seconds to load)
1 example, 0 failures
```

こんなふうになる。 `exit` を通った時点で RSpec ごと終了するので何もテスト実行されてない。テストが増えてくると結構気づかないとおもう。怖い。並行テスト＆ある程度ランダムな割り振り(たまたまCIが毎回の実行時間に基づいて並行を割り振ってたので微妙なランダム)で RSpec を走らせていたのでばらつきに気づいたけど、そうじゃなかったら気づかなかったかもしれない。

## 対処法

`exit` は `StandardError` ではない [例外 `SystemExit`](https://docs.ruby-lang.org/ja/3.2/class/SystemExit.html) を発生させているので、これをキャッチして投げ直せばいい。

> exit は例外 [SystemExit](https://docs.ruby-lang.org/ja/3.2/class/SystemExit.html) を発生させることによってプログラムの実行を終了させますので、必要に応じて begin 節で捕捉することができます。




コンフィグに書いちゃえば安心かも
```ruby:main_spec.rb
RSpec.configure do |config|
  config.around(:example) do |example|
    example.run
  rescue SystemExit
    fail '予期しない exit が発生しました'
  end
end
```

これ書いておけばちゃんと失敗するし最後までテストが実行される。

```
$ bundle exec rspec main_spec.rb -fd

assert_some_conditions!
  be nil when 1(まちがい) (FAILED - 1)
  be nil when 0

Failures:

  1) assert_some_conditions! be nil when 1(まちがい)
     Failure/Error: fail '予期しない exit が発生しました'

     RuntimeError:
       予期しない exit が発生しました
     # ./main_spec.rb:8:in `rescue in block (2 levels) in <top (required)>'
     # ./main_spec.rb:6:in `block (2 levels) in <top (required)>'
     # ------------------
     # --- Caused by: ---
     # SystemExit:
     #   exit
     #   ./main.rb:3:in `exit'

Finished in 0.00095 seconds (files took 0.04431 seconds to load)
2 examples, 1 failure

Failed examples:

rspec ./main_spec.rb:13 # assert_some_conditions! be nil when 1(まちがい)
```

# 参考

- https://docs.ruby-lang.org/ja/3.2/method/Kernel/m/exit.html
- https://github.com/rspec/rspec-core/issues/2413
- https://pocke.hatenablog.com/entry/2016/07/17/085928