OmniAICreator/Qiita-1.07M huggingface dataset:
【初心者向け】LEFT OUTER JOINってどのテーブルが偉いの？

## LEFT OUTER JOINとは
左外部結合は、指定したテーブル（左側のテーブル）の全ての行を含み、共通のキーに基づいて結合条件を満たす行がある場合にはそれを結合します。 一致しない場合は右側のテーブルの該当箇所にはNULLが入ります。

## 理解した！🤓
「A left outer join B」という結合を行う際に、
Aテーブルに対してBテーブルの情報を付けたすだけなので、
Aテーブルが偉い　＝　Aテーブルのレコード数と同じ結果セットが作られる！

## 本当に？
こちらの2つのテストテーブルを用意し、検証してみたいと思います。
Aテーブル：TEST_NAME
Bテーブル：TEST_ADDRESS


#### ①AテーブルとBテーブルのレコード数が同じ
👇Aテーブル「TEST_NAME」の状態
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529165/3740eeba-13d4-ddb0-295b-48d117e51ff1.png)

👇Bテーブル「TEST_ADDRESS」の状態
![Untitled (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529165/927f474e-5842-e54b-32d0-208ac30fbaf3.png)

👇結果セット
結合によって、各人物の住所情報が付け足された
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529165/023110df-a95d-ffd0-6c11-e414da8b089d.png)


#### ②Bテーブルのレコード数が多い
👇Aテーブル「TEST_NAME」の状態
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529165/3740eeba-13d4-ddb0-295b-48d117e51ff1.png)

👇Bテーブル「TEST_ADDRESS」の状態
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529165/7b22d2ba-1c42-ab35-a175-af1a7deecd5d.png)

👇結果セット
Bテーブルに「ID=4」のレコードがあったとしてはも、結果セットにないので、やはりAテーブルが偉い！
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529165/023110df-a95d-ffd0-6c11-e414da8b089d.png)


#### ➂Bテーブルのレコード数が多いが、②と違う増え方
👇Aテーブル「TEST_NAME」の状態
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529165/3740eeba-13d4-ddb0-295b-48d117e51ff1.png)

👇Bテーブル「TEST_ADDRESS」の状態
Bテーブルに「ID=1」のレコートが2行存在する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529165/1118e17c-0a28-fe94-27a3-7d986382e96c.png)


👇結果セット
東京の花子さんと新潟の花子さんがそれぞれ作られてしまった。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529165/3bf23e8d-e84e-599e-d1f9-2d66a5e9a7ac.png)



## 結論
「Aテーブルが偉い　＝　Aテーブルのレコード数と同じ結果セットが作られる！」という理解が間違いでしたね。


実現場のデータ処理には、➂みたいパターンはあんまりあり得ないと思います。
ただ、結合キーをしっかり定めいないと、データが変な増え方をしてわけわからない結果セットになり得ると思います。


## ご案内
株式会社ジールでは、「ITリテラシーがない」「初期費用がかけられない」「親切・丁寧な支援がほしい」「ノーコード・ローコードがよい」「運用・保守の手間をかけられない」などのお客様の声を受けて、オールインワン型データ活用プラットフォーム「ZEUSCloud」を月額利用料にてご提供しております。
ご興味がある方は是非下記のリンクをご覧ください：
https://www.zdh.co.jp/products-services/cloud-data/zeuscloud/?utm_source=qiita&utm_medium=referral&utm_campaign=qiita_zeuscloud_content-area
Swiftでの音声録音方法：AVAudioRecorderの活用

SwiftでAudioRecorderを使い基本的な録音機能の設定と使用方法について解説します。

参考となるコードはGitHubに載せておりますので参考にしてください。

https://github.com/entaku0818/AudioMaster/blob/main/Sources/AudioMaster/AudioRecorderMaster.swift


## オーディオセッションの設定

```swift
try audioSession.setCategory(.record, mode: .default, options: [])
try audioSession.setActive(true)
```

ここでは、`AVAudioSession`を設定しています。オーディオセッションは、オーディオの振る舞いを管理するためのものです。
最初の引数がCategoryで今回のように録音を設定したい場合は `.record` もしくは `.playAndRecord`を指定します

modeはただ録音したい場合は `default`　で問題ありません。 

https://developer.apple.com/documentation/avfaudio/avaudiosession/category
https://developer.apple.com/documentation/avfaudio/avaudiosession/mode

## 録音ファイルの保存場所の指定

```swift
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
```

録音ファイルを保存する場所を指定しています。
ここでは、`FileManager`を使用してドキュメントディレクトリのURLを取得し、その中に録音ファイルを保存します。

https://developer.apple.com/documentation/foundation/filemanager/searchpathdirectory/


## 録音の開始

```swift
do {
    audioRecorder = try AVAudioRecorder(url: recordingURL!, settings: settings.asDictionary())
    audioRecorder?.record()
} catch {
    print("Error starting audio recording: \(error.localizedDescription)")
    throw error
}
```

`AVAudioRecorder`のインスタンスを生成し、指定したURLに録音を開始します。
`settings`パラメータでは、録音の品質やフォーマットなどを指定できます。

https://developer.apple.com/documentation/avfaudio/avaudiorecorder


- settingsパラメータの詳細
https://developer.apple.com/documentation/avfaudio/avaudiorecorder/1388386-init


## 録音の停止

```swift
public func stopRecording() async throws {
    audioRecorder?.stop()
}
```

録音を停止するには、`stop()`メソッドを呼び出します。これにより、現在進行中の録音が終了し、ファイルに保存されます。


この記事では、Swiftでの基本的な録音プロセスを説明しました。さまざまな設定や機能を追加することで、アプリのニーズに合わせた録音機能を実装することができます。
PostgreSQLのスタンバイ側で、「テーブルスペース削除によるリカバリ競合」と「テーブルロック」によりデッドロックを発生させる手順

レプリケーション構成のスタンバイ側で、[以前の記事](https://qiita.com/fujii_masao/items/f4445f4022afbb2404c2)では、「バッファ・ピンによるリカバリ競合」と「テーブルロック」によりデッドロックを発生させました。

今回は、「テーブルスペース削除によるリカバリ競合」と「テーブルロック」によりデッドロックを発生させます。このデッドロックは、以下2つの待ちが重なることで発生します。
* バックエンドプロセスが利用中のテーブルスペースを、startupプロセスが削除しようとして待ち状態になる
* startupプロセスが取得済のテーブルロックを、バックエンドプロセスが取得しようとして待ち状態になる

## デッドロックを発生させる手順
:one:レプリケーション構成のプライマリ側をセットアップする。
```bash
$ initdb -D data --no-locale --encoding=UTF8
$ pg_ctl -D data start
```

:two:テーブルスペースを作成する。
```bash
$ mkdir /tmp/hoge1
$ psql -c "CREATE TABLESPACE hoge LOCATION '/tmp/hoge1'"
```

:three:レプリケーション構成のスタンバイ側をセットアップする。
```bash
$ pg_basebackup -D sby1 -R -T /tmp/hoge1=/tmp/hoge2 -X fetch
$ echo "port = 5433" >> sby1/postgresql.conf
$ echo "temp_tablespaces = 'hoge'" >> sby1/postgresql.conf
$ echo "max_standby_streaming_delay = -1" >> sby1/postgresql.conf
$ pg_ctl -D sby1 start
```
* 今回は同一ホスト上でプライマリとスタンバイを動かすため、pg_basebackup実行時に-Tオプションでテーブルスペースのディレクトリの対応を指定する。また、プライマリと異なるポート番号をスタンバイ側で設定する。
* テーブルスペース削除によるリカバリ競合を引き起こすために、:two:で作成したテーブルスペースをtemp_tablespacesに設定する。
* リカバリと競合するリードオンリー・トランザクションがすぐにキャンセルされないように(すぐにキャンセルされるとデッドロックを観察できないため)、max_standby_streaming_delayを-1に設定する。

:four:プライマリ側で、テーブルを作成する。また、そのテーブルに対してACCESS EXCLUSIVEロックを取得して、ロック取得のWALがすぐにスタンバイに転送されるようにpg_switch_wal()を実行する。
```sql
CREATE TABLE t();
BEGIN;
LOCK TABLE t IN ACCESS EXCLUSIVE MODE;
SELECT pg_switch_wal();
```
* この手順により、スタンバイ側では、startupプロセスはテーブルに対するACCESS EXCLUSIVEロックを取得する。

:five:スタンバイ側で、ORDER BYのディスクソートにより、temp_tablespacesに設定したテーブルスペース上で一時ファイルを発生させる。また、テーブルをSELECTする。
```sql
BEGIN;
SET work_mem TO 64;
DECLARE mycur CURSOR FOR SELECT * FROM generate_series(1, 1000000) n ORDER BY n;
FETCH mycur;
SELECT * FROM t;
```
* ディスクソートが発生しやすいように、ORDER BY検索の実行前にwork_memを小さい値に設定しておく。
* 一時ファイルが残ったままになるように、カーソルを使ってORDER BY検索が途中状態のままになるようにする。
* テーブルのSELECTにより、バックエンドプロセスはテーブルに対するACCESS SHAREロックを取得しようとして待ち状態になる。

:six:プライマリ側で、:four:とは別のセッションを開始して、テーブルスペースを削除する。
```sql
DROP TABLESPACE hoge;
```
* この手順により、startupプロセスはスタンバイ側でテーブルスペースを削除しようとするが、バックエンドプロセスがまだそのテーブルスペースを使っている(一時ファイルが残っている)ため、テーブルスペース削除によるリカバリ競合となり、待ち状態になる。

:seven:バックエンドプロセスもstartupプロセスも待ち状態のため、デッドロックとなる。

:::note warn
2024年1月28日現在のPostgreSQLのコードでは、このデッドロックは検出されず自動的な解決もされない。(ように見えるが、嘘だったら申し訳ない。。)
:::
Proxmox VE 8でクラスタからノードを削除

どうしてもノードを削除しないといけなくなったのでメモ書き。

# 構成
| 1 | 2 |
|:-:|:-:|
|pve01|192.168.1.80|
|pve02|192.168.1.90|

今回は`pve02`を削除するので、`pve01`から操作します。

# ノードの削除

:::note warn
`rm -rf`で強制削除しています。
不安な場合は`/tmp`などにコピーしてから削除しましょう。
:::


```bash
$pvecm delnode pve02 #停止してるノードだとうまくいかないかも？
$systemctl stop pve-cluster corosync #サービス停止
$rm -rf /etc/pve/nodes/pve02 #pve02を削除
$rm -rf /etc/corosync/* #corosyncを吹き飛ばす
$rm -rf /etc/pve/corosync.conf #こっちも
$killall pmxcfs #おまじない？分からないけどやる
$systemctl start pve-cluster #蘇生
$pvecm nodes #クラスタのノード確認。
#Error: Corosync config '/etc/pve/corosync.conf' does not exist - 
#is this node part of a cluster? が出るはず
```

WebUIをリロードするとノード一覧から消滅しているはずです。
クラスタも未定義になるはず...
Jenkinsを使用してGithub上のMavenプロジェクトをBuildする

## 前書き
RHEL9にJenkinsを使用してGithub上のMavenプロジェクトをBuildする時のメモです。

## 前提条件
- JDKがインストール完了
- Mavenがインストール完了
- Gitがインストール完了
- Jenkinsサーバーをセットアップ済み、初期設定完了。
※未完了の方は以下の手順をご参考下さい：

https://qiita.com/manabu-s/items/ffb62f021f1c4ab8f61d

## 手順：
### ジョブを作成：
- Jenkinsのダッシュボードで、新規ジョブ作成をクリック

- ジョブ名を入力：MavenProject
![Screenshot from 2024-01-28 10-43-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1442793/e2ef9ee2-eae0-c2eb-cb8b-703e7a793a2c.png)

- フリースタイル・プロジェクトのビルドを選択し、OKボタンをクリックする

- General情報にGitHub projectを選択し、Project urlを入力する。
今回使うGitのURLは以下です：
https://github.com/yoruzuki/jenkins_demo.git

- ソースコード管理に「Git」を選択し、リポジトリURLに同様なURLを入力する。ブランチ指定子に「*/main」を入力する
![Screenshot from 2024-01-28 10-57-45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1442793/3e02ff4e-4982-31ad-df87-67be9784c45c.png)


- Build Stepsに「Mavenの呼び出し」を選択し、使用するMavenに前回の記事で作成したMavenを選択する。ゴールにclean packageを入力する。
![Screenshot from 2024-01-28 10-47-41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1442793/1d7e9c2a-96c8-0cdb-a68c-213023155ab1.png)

- 『保存』ボタンをクリックし、ジョブが作成完了です。

### ジョブを実行：
- 『ビルド実行』をクリックし、ジョブが実行される。
![Screenshot from 2024-01-28 10-52-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1442793/ffa9d366-2595-c5c4-a177-c0641452d708.png)

- ビルド成功の画面(状態)
![Screenshot from 2024-01-28 10-59-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1442793/097d12fb-48c8-8f96-43a2-00434d7780d2.png)

- ビルド成功の画面(コンソール出力)
![Screenshot from 2024-01-28 11-03-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1442793/761ac68c-3058-19dc-6fda-4110fc0711ad.png)

ワークスペース: /var/lib/jenkins/workspace/MavenProjectを確認できます。

### ビルドしたプロジェクトを実行：
- 実行してみる：
```
$ /var/lib/jenkins/workspace/MavenProject/target
$ java -jar jenkins_demo-0.0.1-SNAPSHOT.jar
```
![Screenshot from 2024-01-28 11-06-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1442793/1ee53fee-c9b6-9617-8314-d9e597b3218b.png)

- WEBブラウザにURL：
http://localhost:8000/
を叩いて、以下の画面が表示出来たら成功。
![Screenshot from 2024-01-28 11-08-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1442793/8e612e26-a815-b53c-772a-51a67fb41572.png)
LeetCodeの629. K Inverse Pairs Arrayの解き方メモ

https://leetcode.com/problems/k-inverse-pairs-array/description/

LeetCodeの629. K Inverse Pairs Arrayという問題ですが、解答にあたりかなり苦労したので、解き方や考え方のメモを残しておきたいと思います。

この問題は「1~nからなる数列を考える。invert pairの数が k 個の数列を数えなさい」というものです。invert pairとは、$0 \leqq i < j < n$ かつ $nums[i] > nums[j]$ を満たす組のこと。たとえば[4, 2, 3, 1]という数列があるとすると、(4,2), (4,3), (4,1), (2,1), (3,1)がinvert pairになります。

まず具体例から考えます。1~4からなる数列として[4, 2, 3, 1]があります。この数列に5を挿入すると、invert pairの数がどのように増えるのかを観察してみましょう。

|もとの配列    |挿入後の配列           |増えたinvert pair               |増えたinvert pairの数|
|:-------------|:--------------------- |:-------------------------------|:--------------------|
| [4, 2, 3, 1] | [**5**, 4, 2, 3, 1]   | (5, 4), (5, 2), (5, 3), (5, 1) | 4                   |
| [4, 2, 3, 1] | [4, **5**, 2, 3, 1]   | (5, 2), (5, 3), (5, 1)         | 3                   |
| [4, 2, 3, 1] | [4, 2, **5**, 3, 1]   | (5, 3), (5, 1)                 | 2                   |
| [4, 2, 3, 1] | [4, 2, 3, **5**, 1]   | (5, 1)                         | 1                   |
| [4, 2, 3, 1] | [4, 2, 3, 1, **5**]   | -                              | 0                   |

つまり、1~4からなる数列に5を挿入すると、以下のいずれかに遷移するとわかります。

- invert pairが0個増えた、1~5からなる数列
- invert pairが1個増えた、1~5からなる数列
- invert pairが2個増えた、1~5からなる数列
- invert pairが3個増えた、1~5からなる数列
- invert pairが4個増えた、1~5からなる数列

これを一般してみましょう。dp[p][q]を「反転数がq個の1~pからなる数列の数」とします。この数列にp+1を挿入し、1~p+1からなる数列にすることを考えます。すると、dp[p][q]から次のp個の状態に遷移します。

- dp[p+1][q+0]
- dp[p+1][q+1]
- dp[p+1][q+2] 
- ...
- dp[p+1][q+p-1]
- dp[p+1][q+p]

あとはこれをプログラムに落とし込めばよいです。問題の指示にあるとおり、1000000007でわったあまりを求めることを忘れないようにしましょう。計算量は$O(n^3)$ですが、$n \leqq 1000$とnが比較的小さいので、高速な言語を利用すれば、問題なく制限時間に間に合います。

```rust:main.rs
impl Solution {
    pub fn k_inverse_pairs(n: i32, k: i32) -> i32 {
        let n = n as usize;
        let k = k as usize;
        
        let mut dp = vec![vec![0; k+1]; n+1];
        dp[1][0] = 1;

        for p in 1..n {
            for q in 0..k+1 {
                for r in 0..p+1 {
                    if q+r <= k {
                        dp[p+1][q+r] += dp[p][q];
                        dp[p+1][q+r] %= 1000000000 + 7;
                    }
                }
            }
        }

        return dp[n][k];
    }
}
```
競プロ未経験者による競プロ備忘録①

## 簡単な自己紹介
- エンジニアになって1年くらい
- それまで10年くらい中学校の数学教員
- 大学は数学科だったけど遊び尽くしていたのでほぼ何もしてない
- 2024年1月から競プロ始めた
- 使用言語はPython
- 現在の順位（2024年1月28日時点）
![スクリーンショット 2024-01-28 10.25.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884270/14ab8c58-fd85-6a87-ea48-e735082ac284.png)


## 競プロにはまったきっかけ
会社の人が競プロ挑戦したいという話を聞いて、自分も面白そうなのでやってみようと思ったから

## やってよかった点
<b>AIに頼ってしまう自分を変えられそう（な気がしている）</B>
前提としてAIを使うことを否定するつもりもないですし、むしろ業務の効率化という点から考えると、AIとうまく付き合えるに越したことはないと思っています。
だけど自分みたいに弱々エンジニアの場合、とりあえずAIに聞いてみて、きちんとした根拠もなくAIの提案を鵜呑みにしてコードを書いたり考えたりすると、誤った記述や冗長な記述になってしまうことが実感としてありました。
また、AIを使うことで場当たり的な解決にはなっても、自分の血肉になっている感覚がないのも課題として感じていました。
競プロができるからといって実務でバンバン使うかというと必ずしもそうではないと個人的には思うのですが、それでもアルゴリズムやプログラミング的な思考をすることが今まで自分が感じていた課題を解決できるのではないかと感じているので、そういう意味でも競プロにん出会えてよかったと感じています。

### 備忘録
まず、A問題をやってみる。他の人も言及しているかもしれないが、大抵は最初に数値の入力だけでつまづくこともある。自分もそうだった。
以下簡単にまとめる。
```python
# 数値を入力する
n = int(input())
print(n)
# 出力例
# 1
```
```python
# 文字列ならこう
s = input()
print(s)
# 出力例
# りんご
```
```python
# スペース区切りの整数の入力
n, m = map(int, input().split())
print(n)
print(m)
# 出力例
# n = 3
# m = 5
```
```python
# 半角スペースで区切った数値をリストにする
a = list(map(int, input().split()))
print(a)
# 出力例
# a = [1, 2, 3]
```
```python
n = int(input())
# 数字を入力するたびに改行していき、それをリストにする
a = [int(input()) for _ in range(n)]
print(a)
# 出力例
# a = [1, 2, 3]
```

自分が取り組んだA問題とB問題はだいたいこんな感じで、リスト、整数、文字列の入力でこと足りるケースが多かったです。

なんとなくわかってきたコツとしては「ざっくり計算量がどのくらいか考えること」。
例えば、forループが1回の場合に比べて、二重forループになると、1回のときと比べて計算量が２乗になってしまうケースが多いです。
なので計算すべき数が多い場合は、なるべく簡単にしないと（つまり計算量を減らす工夫をしないと）、すぐに実行時間制限オーバーになってしまいます。

あとは問題にひたすら取り組むこと。
あと、できたとしても個人的にはクソコードになってしまっていることが多いと感じているので、クソコード量産機にならないよう他の人の解答や解説を見て学んでます。

## 大変参考になった本
[アルゴリズムと数学](https://www.amazon.co.jp/%E5%95%8F%E9%A1%8C%E8%A7%A3%E6%B1%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%80%8C%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%C3%97%E6%95%B0%E5%AD%A6%E3%80%8D%E3%81%8C%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E3%81%97%E3%81%A3%E3%81%8B%E3%82%8A%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%8F%E6%9C%AC-%E7%B1%B3%E7%94%B0-%E5%84%AA%E5%B3%BB-ebook/dp/B09NXFQRD3/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1YO7B9I6A3R08&keywords=%E6%95%B0%E5%AD%A6%E3%81%A8%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0&qid=1706406848&sprefix=%E6%95%B0%E5%AD%A6%E3%81%A8%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%2Caps%2C208&sr=8-1)
Github ブランチとマージ

使用するリモートリポジトリ：`New-repository`
現在こんな感じで、ブランチはありません。
![スクリーンショット 2024-01-28 9.22.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570384/5b8cabae-97ba-3371-5f47-147406d7420b.png)

### ブランチ作成

ローカルリポジトリは`Helloworld`
現在ローカルにあるブランチは以下の通り。
`feature`をリモートリポジトリに紐つける。
```shell
# ローカルのfeatureブランチを、リモートリポジトリ（origin）に追加
git push -u origin feature
```
![スクリーンショット 2024-01-28 9.46.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570384/bee8bf9f-cd81-0561-6046-4a4d1480748b.png)
増えてる！！　今追加したfeatureブランチをクリック
![スクリーンショット 2024-01-28 9.47.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570384/fcd589e7-4d88-33d5-4d0b-9e3e46013cf8.png)
mainブランチには以下のファイル1つだけ。
![スクリーンショット 2024-01-28 9.49.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570384/bf0480ee-915d-024e-3ff4-24715c285b6d.png)
featureブランチには複数のファイルが保存されています。
![スクリーンショット 2024-01-28 9.50.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570384/b02b0297-7d8c-4a6d-19db-2d48451cc64d.png)

### マージする
例えば、
featureブランチの変更をmainブランチにマージする場合

1. git checkoutコマンドでmainブランチに切り替え
1. git mergeコマンドにfeatureブランチを指定して実行
**マージ先に移動して、マージ元をコマンドで指定する。**

```shell
# ブランチ先に移動
git checkout ブランチ先

#マージ元を指名
git merge マージ元のブランチ名
```
マージ完了。以下に表示されている4つのファイルをマージします。この時点ではローカルリポジトリ内でマージしただけなので、リモートには反映されていません！
![スクリーンショット 2024-01-28 10.26.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570384/1e4e40d7-4d18-d832-bc46-268272d3b838.png)
指定したブランチのファイル一覧を表示
```shell
git ls-tree --name-only ブランチ名
```
表示されています。
![スクリーンショット 2024-01-28 10.29.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570384/e8924d90-7d21-7d96-a457-7b74b88f22d1.png)
最後にこれらのマージをリモートリポジトリにPUSH
```shell
git push origin main 
```
![スクリーンショット 2024-01-28 10.33.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570384/b2f44882-b619-d539-4384-ba9a70668bcc.png)
OK!!!
MCP9701温度センサーで遊ぶ(STM32C011J4M7)(PA12ソフトウェアシリアル)(マクロ)


x MCP9701-E/TO 販売コード 103199

MCP9701温度センサーで遊ぶ(STM32C011J4M7)(PA12ソフトウェアシリアル)(マクロ)


目的
温度計の値をシリアルに出力

![o_cop904.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/53dbbf45-e151-b01d-002e-f0f15f587641.jpeg)



```c++

//SER_LB_9600_MCP9701_C011_1

//ヘッダー
#include <Arduino.h>
#include "SER_9600_C011_1.h"

//定義
//100の割り算 0から30000までは、だいたい正しい   
#define DIV100(in) ((in*(65536/100*64+24))>>22)
//25の割り算 0から30000までは、だいたい正しい   
#define DIV25(in) ((in*(65536/25*16+8))>>20)
//MCP9701の温度を求める x100
#define TMP(so) ((((so)*270769)-134432821)>>16)


//初期化
void setup()
{

  //シリアルの初期化
  pc.beginNS(9600);

} //setup


//メインループ
void loop()
{

  //センサーの値を読み込む
  analogReadResolution(12); // ADC 12bit mode
  int s = analogRead(PA11);   // センサーの読み取り値


  //センサーの値を温度に変換
  int t = TMP(s);
  int d1 = DIV100(t);
  int d01 = (t - (d1 * 100));d01 = (DIV25(d01))*25;


  //温度の表示
  String thisString1 = String(d1);
  pc.printNS( (char *)thisString1.c_str()  );

  pc.printNS(".");

  thisString1 = String(d01);
  if (d01==0) {pc.printNS("0");}
  pc.printNS( (char *)thisString1.c_str()  );
  pc.printNS("\r\n");

  
  delay(1000);

} //loop

```


```c++:SER_9600_C011_1.h




#ifndef TEST_H
#define TEST_H

//SER_9600_C011_1.h


#define TX1      PA12      // ?pin

//#define UART_DELAY  96   //  9600bps  NG
//#define UART_DELAY  97   //  9600bps  NG
//#define UART_DELAY  98   //  9600bps  NG
//#define UART_DELAY  99   //  9600bps  NG
//#define UART_DELAY 100   //  9600bps  OK 1 
//#define UART_DELAY 101   //  9600bps  OK 2 
//#define UART_DELAY 102   //  9600bps  OK 3 
//#define UART_DELAY 103   //  9600bps  OK 4 
//#define UART_DELAY 104   //  9600bps  OK 5 
#define UART_DELAY 105   //  9600bps  OK 6 
//#define UART_DELAY 106   //  9600bps  OK 7 
//#define UART_DELAY 107   //  9600bps  OK 8 
//#define UART_DELAY 108   //  9600bps  OK 9 
//#define UART_DELAY 109   //  9600bps  OK 10 
//#define UART_DELAY 110   //  9600bps  NG
//#define UART_DELAY 111   //  9600bps  NG


//#define UART_DELAY 1000   //  9600bps ok E


#define DW   digitalWrite


//クラスの定義
struct _pc
{
  void beginNS(int sp);      //メソッドの宣言
  int  putcNS(char ch);      //メソッドの宣言
  int  printNS(char *str1);  //メソッドの宣言
};


//ポートをhiにする 初期化
//メソッドの定義
void _pc::beginNS(int sp)
{
  //ポートをhiにする初期化
  pinMode(TX1, OUTPUT);
  DW(TX1, HIGH);
}


//仮想シリアルへの一文字出力 9600bps
//メソッドの定義
int _pc::putcNS(char ch)
{
  DW(TX1, HIGH);

  DW(TX1, LOW);//START
  delayMicroseconds(UART_DELAY); //START BIT WAIT

  for (int ii = 0; ii < 8; ii++) {
    DW(TX1, (ch >> ii) & 1  );
    delayMicroseconds(UART_DELAY); //DATA 1-8BIT WAIT
  }//for

  DW(TX1, HIGH);//Stop
  delayMicroseconds(UART_DELAY); //StOP BIT WAIT

  return (0);
}


//文字列の表示
//メソッドの定義
int _pc::printNS(char *str1)
{
  //文字の中身がゼロか
  while (*str1) {

    //一文字出力
    putcNS(*str1 ++);

  } //while

  //戻り値
  return (0);
}


//実体の作成
_pc pc;


#endif






```
テキストのベクトル化と可視化：OpenAI Embedding APIの利用

![スクリーンショット 2024-01-28 095611.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/b39d52bc-4f76-e10b-2e8d-52270123813d.png)

## はじめに
自然言語処理（NLP）技術におけるベクトル表現は、テキストデータの多様な理解と分析のアプローチを可能にします。このブログでは、テキストデータをベクトル化し、主成分分析（PCA）を使用して3次元空間にマッピングするプロセスを紹介します。この方法は多くの分析や応用に適用可能であり、今回はその一例として可視化を行います。

## テキストのベクトル化とは
テキストのベクトル化とは、単語や文の意味的な特徴を数値の配列で表現することを意味します。この数値配列は、テキストの内容を機械学習モデルが処理しやすい形式に変換します。ベクトル化により、テキスト間の類似性や関連性を定量的に分析できるようになります。

## テキストデータの準備
分析のために、日本の伝統的な祝詞を例として使用します。
```
texts = [
    "高天原に 神留坐す",
    "神漏岐神漏美の",
    "命以ちて",
    "皇親神伊邪那岐の大神",
    "筑紫日向の橘の小門の",
    "阿波岐原に",
    "禊祓ひ給ふ時に",
    "生坐せる",
    "祓戸の大神等",
    "諸々禍事罪穢を",
    "祓へ給ひ清め給ふと",
    "申す事の由を",
    "天つ神地つ神",
    "八百万神等共に",
    "聞食せと",
    "畏み畏みも白す"
]
```
## OpenAI Embedding APIの使用
まず、OpenAIのEmbedding APIを利用するためにライブラリをインストールして、APIキーを認証させます。
```
!pip install openai

api_key = "APIキー"
client = OpenAI(api_key=api_key)
```
次に、APIを使用して各テキストのベクトルを生成します。
```
import pandas as pd
import json
from openai import OpenAI

df = pd.DataFrame(texts, columns=['text'])

def get_embedding(text, model="text-embedding-ada-002"):
    text = text.replace("\n", " ")
    response = client.embeddings.create(input=[text], model=model)
    return response.data[0].embedding

df['embedding'] = df['text'].apply(get_embedding)
```
## データの保存
生成されたベクトルをJSON形式で保存します。
```
embeddings_dict = df.apply(lambda row: {'text': row['text'], 'embedding': row['embedding']}, axis=1).tolist()

with open('embeddings.json', 'w', encoding='utf-8') as file:
    json.dump(embeddings_dict, file, ensure_ascii=False)
```
jsonファイルを確認すると、ベクトルの異なる成分が文に埋め込まれていることを確認できます。
![スクリーンショット 2024-01-28 092458.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/e1cdf2f2-33c6-2766-933d-f1b88a708d9c.png)

## 可視化の一例
ベクトル化されたデータは高次元で直感的に理解しにくいため、PCAを用いて3次元に削減し、視覚化します。
```
!pip install japanize-matplotlib

from sklearn.decomposition import PCA
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
from mpl_toolkits.mplot3d import Axes3D

# JSONファイルから埋め込みベクトルを読み込む
with open('embeddings.json', 'r', encoding='utf-8') as file:
    embeddings_dict = json.load(file)

embeddings = np.array([item['embedding'] for item in embeddings_dict])

# PCAを使用して3次元に次元削減
pca = PCA(n_components=3)
embeddings_reduced = pca.fit_transform(embeddings)

fig = plt.figure(figsize=(12, 10))
ax = fig.add_subplot(111, projection='3d')

# 各点に対応するテキストをプロットに追加
for i, txt in enumerate(embeddings_dict):
    ax.scatter(embeddings_reduced[i, 0], embeddings_reduced[i, 1], embeddings_reduced[i, 2])
    ax.text(embeddings_reduced[i, 0], embeddings_reduced[i, 1], embeddings_reduced[i, 2], txt['text'], size=10)

ax.set_xlabel('Component 1')
ax.set_ylabel('Component 2')
ax.set_zlabel('Component 3')

plt.show()
```
![スクリーンショット 2024-01-28 094855.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/7add48e5-e24f-276f-9743-b3c068d0857e.png)


## まとめ
今回は、テキストのベクトル化から3次元空間へのマッピングまでの簡単なプロセスを紹介しました。テキストのベクトル化は、可視化だけでなく、様々な分析や応用に適用できます。特にNLP（自然言語処理）の分野におけるこれらの技術は、テキストデータの理解だけでなくLLM（大規模言語モデル）への活用に繋がります。是非皆さんもチャレンジしてみてください！
[EIP160] EXPオペコードのガスコストを増加させる提案を理解しよう！

# はじめに

初めまして。
**CryptoGames**というブロックチェーンゲーム企業でエンジニアをしている **cardene（かるでね）** です！
スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。

https://cryptogames.co.jp/

代表的なゲームは**クリプトスペルズ**というブロックチェーンゲームです。

https://cryptospells.jp/

今回は、EthereumにおけるEXP命令のガスコスト改訂を提案している**EIP160**についてまとめていきます！

:::note info
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
:::

https://eips.ethereum.org/EIPS/eip-160

他にも様々なEIPについてまとめています。

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4

# パラメータ

- `FORK_BLKNUM`
    - `2,675,000`
- `CHAIN_ID`
    - `1`

# 仕様

「`block.number >= FORK_BLKNUM`」という条件の下で、`EXP`命令（指数計算を行う命令）のガスコスト（実行コスト）を変更することを提案しています。
具体的には、ブロック番号が`FORK_BLKNUM`以上になった場合、`EXP`命令のガスコストを「`10` + 指数部のバイトあたり`10`」から「`10` + 指数部のバイトあたり`50`」へと増加させるという内容です。

ここでの「`block.number`」とは、ブロックチェーン上での特定のブロックの番号を指します。
ブロックチェーンは、連続するブロックのチェーンで構成されており、各ブロックには一意の番号が割り当てられています。

「`FORK_BLKNUM`」とは、ブロックチェーンのネットワーク上で特定のアップデートが適用されるブロックの番号を指します。
この番号に達すると、ネットワークは新しいルールに従って動作するようになります。

この提案の背景には、`EXP`命令の現在のガスコストがその処理に必要なリソースに比べて低く設定されているという問題があります。
指数計算は計算量が多いため、ネットワークのリソースを相応に消費します。
そのため、ガスコストを増加させることで、命令の実行にかかるコストをより適切に反映させようとしています。
これにより、ネットワークの過負荷を防ぐとともに、よりセキュアで効率的なネットワーク運用を目指しているのです。

:::note info
`EXP`については以下の記事を参考にしてください。
:::

https://zenn.dev/heku/books/aef33b86ded3c0/viewer/14d71a#exp

# 補足

ブロックチェーンにおける`EXP`命令のガスコストに関するベンチマーク（性能評価）の結果について述べています。
「`EXP`命令は現在、本来あるべき価格の約4～8分の1に過小評価されている」と述べられています。

ブロックチェーンにおいて、`EXP`命令は指数計算を行うための命令です。
ブロックチェーンのトランザクションでは、各命令の実行には「**ガス**」と呼ばれる単位を使用してコストを計算して消費します。
このガスコストは、ネットワーク上でのトランザクションの処理負荷に対する料金として機能します。

ベンチマークとは、コンピューターシステムやプログラムの性能を評価するテストのことです。
ベンチマークの結果は、`EXP`命令の現在のガスコストが、実際に必要とされるリソースや処理能力と比較してかなり低く設定されていることを示しています。
つまり、`EXP`命令を使用することによるネットワークへの影響や負担が、現在のガスコストでは適切に反映されていないということです。

これは、ネットワークのセキュリティや効率に影響を及ぼす可能性があります。
コストが過小評価されていると、その命令が過度に使用され、結果的にネットワークの過負荷やセキュリティリスクを招く恐れがあります。
そのため、この情報は`EXP`命令のガスコストを再評価し、調整する必要があることを示唆しています。

# 参考

- [EIP-160 issue and discussion](https://github.com/ethereum/EIPs/issues/160)

# 引用

Vitalik Buterin (@vbuterin), "EIP-160: EXP cost increase," Ethereum Improvement Proposals, no. 160, October 2016. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-160.

# 最後に

今回は「EthereumにおけるEXP命令のガスコスト改訂を提案している**EIP160**」についてまとめてきました！
いかがだったでしょうか？

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください！

[Twitter @cardene777](https://twitter.com/cardene777)

他の媒体でも情報発信しているのでぜひ他も見ていってください！

https://chaldene.net/

https://zenn.dev/heku

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4
Laravel10 バリデーション password確認用

##Laravel10 Form バリデーション password 

$request->validate confirmed というコードは、受信リクエストのデータをバリデーションするために使われます。この場合、バリデーションルールには confirmed というものがあります。これは、そのフィールドが {field}_confirmation という名前のフィールドと同じであることを確認するというものです。
高齢のばあさんを相手にしていたら、ＩＴニーズがよく分かる話

# 発端
　自身の親、正月にぎっくり腰をやって、動けなかったとかいうので、先週様子を見に行ってきた。
　正直ながら８０代後半なので、いまさらＩＴ化することも何度かチャレンジしてきたが、やはり根付かせることが出来たのは、唯一のアンドロイドのＬＩＮＥだけである。
 
　スタートは折りたたみ式の携帯電話だった。スマホを持たせれば重たいと言い、画面の文字を見ては小さいから見えないと言い、それでも何やかんやと、自分のおさがりスマホを貸与して、３年かけて今の状態に持っていくことができた。

# ネット事情
　今は単身赴任で横浜に来ているので、インターネットも楽天モバイルのデザリングのみである。最初は固定回線でなければ、まともなネットが出来ないのかと思いきや、いまは１００％楽天モバイルで十分であることを実証できた。
　しかしながら、ついついデザリングをし忘れるので、しょっちゅう設定画面からやりなおすのを億劫に考えていた。

　そんななか、何かいいものが無いか探していたら、場所を検知してデザリングさせるアプリがあるというではあーりませんか！
 
 https://sp7pc.com/gadget/macrodroid/30567

 　とりあえず、これなら婆さんを改造できる可能性が出てきた。

# 次段階
　ネット環境さえ固定してしまえば、後は婆さんの家に、スマホをデザリング状態で待機させておき、座椅子にタブレットを固定してしまえば、暫定ながら車いすや介護ベッド状態になっても、ある程度のオペレーションまでできると考えられる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212914/7b9e8918-f914-8834-53df-ad406447221d.png)


 # アプリ開発仕様
 　画面には押しボタンのみ、出来る機能は、アプリの割り付け
  
  ①ＣＨＡＴＧＰＴ　→　これはトークモードで高齢者に寄り添うようなケアマネージャをＧＰＴｓで演じさせれば十分だろう
  
  ②ボケ予防　→　何かゲーム的なものを作ってみる。数独が好きらしいので、その代替アプリを起動
  
  ③ショッピング系　→　自分で発注は困難なので、これをＧＰＴｓで自動化できないだろうか？
  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212914/1d859100-01f5-bea2-d302-669eb6866c07.png)

# 今後の予定
　まず婆さんには指の動く限り、目の見える限り、そして耳の聞こえる限り、話の出来る限り、ヒューマンインタフェースが利用できる限り、今のテクノロジーでこの困難を乗り越えていこうと思う。
  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212914/c41525ca-7aad-edf2-4e8b-ab018ec2427c.png)
adbを用いて複数のAndroidデバイス接続時にスクリーンショットを取る方法

## はじめに
端末のスクリーンショットを撮る機会って、意外とありますよね。
PCにandroid端末を接続していると、adbコマンドを使って、簡単にスクリーンショットを撮ることができます。

```
adb shell screencap -p /sdcard/screen.png
adb pull /sdcard/screen.png
adb shell rm /sdcard/screen.png
```

参考: https://qiita.com/TNaruto/items/b2407f5668e15e42bedd

## 問題点

しかし、複数の端末を接続していると、下記のようなエラーが出てしまいます。

```
adb: more than one device/emulator
adb: error: failed to get feature set: more than one device/emulator
adb: more than one device/emulator
```

これは、adbコマンドが複数の端末を認識してしまい、
どの端末に対してスクリーンショットを撮るか判断できないためです。

## 解決策
そこで、端末を指定してあげることで、エラーを回避することができます。

```
adb -s emulator-5554 shell screencap -p /sdcard/screenshot.png
adb -s emulator-5554 pull /sdcard/screenshot.png
adb -s emulator-5554 shell rm /sdcard/screenshot.png
```
:::note info
指定する端末名は`adb devices`コマンドで確認できます。
:::


## 解決策の問題点
普段の開発だと、エミュレーター + 実機などのように
複数台繋ぐことが多い方もいらっしゃると思います。
(少なくとも自分はそうです。)
毎回、端末を指定するのは、ちょっと面倒です。


## 解決策の問題点の解決策
そういった方のために、下記のようなシェルスクリプトを作成しました。
(ほとんど、copilotによる自動生成ですが…)
これで、複数の端末を接続していても、スクリーンショットを撮ることができます。
もちろん、1台しか接続していない場合でも、問題なく動作します。

:::note info
3行目のsave_dirには、
スクリーンショットを保存するディレクトリを指定してください。
:::

```zsh
#!/bin/zsh
# 保存するディレクトリ
save_dir="/Users/XXXX/Documents/screenshot"

devices=()
while IFS= read -r line; do
    if [[ $line == *device* ]]; then
        devices+=("${line%%[[:space:]]*}")
    fi
done < <(adb devices | tail -n +2)

if [[ ${#devices[@]} -eq 0 ]]; then
    echo "端末が接続されていません。"
    exit 1
fi

if [[ ${#devices[@]} -eq 1 ]]; then
    selected_device="${devices[1]}"
fi

if [[ ${#devices[@]} -gt 1 ]]; then
    for ((i=1; i<=${#devices[@]}; i++)); do
        echo "$i: ${devices[$i]}"
    done
    echo -n "端末を選択してください: "
    read choice

    if [[ $choice =~ ^[0-9]+$ ]]; then
        if [[ $choice -ge 0 && $choice -le ${#devices[@]} ]]; then
            selected_device="${devices[$choice]}"
            echo "選択された端末: $selected_device"
        else
            echo "無効な選択です。"
        fi
    else
        echo "無効な入力です。数値を入力してください。"
    fi
fi

file_name="${selected_device}_$(date "+%Y%m%d%H%M%S").png"
adb -s $selected_device shell screencap -p /sdcard/sc.png
adb -s $selected_device pull /sdcard/sc.png $save_dir/$file_name
adb -s $selected_device shell rm /sdcard/sc.png
echo "スクリーンショットを保存しました。"
```

お役に立てれば幸いです。

#### 詰まったところ
zshは、配列が1から始まるんですね。知りませんでした。
参考: https://egawata.hatenablog.com/entry/2017/07/31/000942
ファイル名一括置換 VBScript

スクリプトファイルにD＆Dした複数ファイルのファイル名を一括置換する

```vb:ReNameAll.vbs
Option Explicit

Dim oldStr, newStr, n, arg, argName, newName

oldStr = InputBox("置換前の文字列を入力してください。", , "")
newStr = InputBox("置換後の文字列を入力してください。", , "")

n = 0
With CreateObject("Scripting.FileSystemObject")
    For Each arg In WScript.Arguments
        argName = .GetFile(arg).Name
        If InStr(argName, oldStr) > 0 Then
            newName = Replace(argName, oldStr, newStr)
            If Not .FileExists(.BuildPath(.GetParentFolderName(arg), newName)) Then
                .GetFile(arg).Name = newName
                n = n + 1
            End If
        End If
    Next
End With

CreateObject("SAPI.SpVoice").Speak n & " 件のファイル名を変更しました"
```
Databricksのコンピュートシステムテーブル

[SQウェアハウス](https://qiita.com/taka_yayoi/items/722c7c1d4a7e768c6ff6)だけでなく、クラスターに関するシステムテーブルも利用できるようになっています。

https://docs.databricks.com/ja/administration-guide/system-tables/compute.html

> クラスター テーブルは、汎用クラスターとジョブ クラスターの時間の経過に伴うクラスター構成の完全な履歴を含む、変化の遅いディメンション テーブルです。
> クラスター システム テーブルは `system.compute.clusters` にあり、次のスキーマを持ちます。

> ノード タイプ テーブルは、現在使用可能なノード タイプとその基本的なハードウェア情報をキャプチャします。 ノード型システム テーブルは `system.compute.node_types` にあり、次のスキーマを持ちます。

# クラスターレコードを最新の請求レコードと結合する

すでに利用量のテーブルがあるので結合すると、クラスターと利用量をマッピングできます。以下の例では`current_user()`を使って、自分自身が所有しているクラスターに限定しています。あと、クラスター名を返すように変更しています。

```sql
SELECT
  u.record_id,
  c.cluster_name,
  c.owned_by,
  c.change_time,
  u.usage_start_time,
  u.usage_quantity
FROM
  system.billing.usage u
  JOIN system.compute.clusters c
  JOIN (SELECT u.record_id, c.cluster_id, max(c.change_time) change_time
    FROM system.billing.usage u
    JOIN system.compute.clusters c
    WHERE
      u.usage_metadata.cluster_id is not null
      and u.usage_start_time >= '2023-01-01'
      and u.usage_metadata.cluster_id = c.cluster_id
      and date_trunc('HOUR', c.change_time) <= date_trunc('HOUR', u.usage_start_time)
    GROUP BY all) config
WHERE
  u.usage_metadata.cluster_id is not null
  and u.usage_start_time >= '2023-01-01'
  and u.usage_metadata.cluster_id = c.cluster_id
  and u.record_id = config.record_id
  and c.cluster_id = config.cluster_id
  and c.change_time = config.change_time
  and c.owned_by = current_user()
ORDER BY cluster_name, usage_start_time desc;
```
![Screenshot 2024-01-28 at 8.05.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/c31c16ba-b1c0-a0f0-1674-47fde514be7b.png)

グラフにもしてみます。
![Screenshot 2024-01-28 at 8.09.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1bb96105-bd58-239d-0871-beb112b17173.png)

# クラスターのコストをクラスター所有者に帰属させる

```sql
SELECT
  u.record_id record_id,
  c.cluster_id cluster_id,
  max_by(c.owned_by, c.change_time) owned_by,
  max(c.change_time) change_time,
  any_value(u.usage_start_time) usage_start_time,
  any_value(u.usage_quantity) usage_quantity
FROM
  system.billing.usage u
  JOIN system.compute.clusters c
WHERE
  u.usage_metadata.cluster_id is not null
  and u.usage_start_time >= '2024-01-1'
  and u.usage_metadata.cluster_id = c.cluster_id
  and c.change_time <= u.usage_start_time
GROUP BY 1, 2
ORDER BY cluster_id, usage_start_time desc;
```
![Screenshot 2024-01-28 at 8.11.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/714fd05f-b479-aa3c-a64c-4f21d7c1f9bb.png)

ご活用ください！

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
【CommonLisp】「でふん」VS「でぃふぁん」


## defunの読み方

CLerなら親の顔より書いた`defun`
恥ずかしながら私は長期にわたり、これを「でふん」と読んでいた。

しかし、ある時こう思った。

`funcall`は「ふぁんこーる」と読むのに
`defun`を「でふん」と読むのはおかしくないか？と。

その時から私の中に、「でふん」と「でぃふぁん」の迷いが生じるようになってしまった。

## 「でぃふぁん」がおそらく正しい

まあ、言うまでもないが`defun`は「define function」の省略形なので
「でぃふぁん」と読むのがスジだろう。

## しかし私は「でふん」の精神を持つ

正しさの観点から言えば、「でぃふぁん」が絶対的な正義を持つのは明らかだ。
そこを違うということはできない。

しかし、私は「でふん」が好きだ。
正しいとか正しくないとかではない。
「でふん」が好きなのだ。

### 好きな理由1：日本人の本能に従っているから

`defun`をローマ字読みするとどうなるだろうか？
そう。「でふん」である。

日本人として生まれたからには、なんやかんやでローマ字で考えてしまう癖がある。（個人差あり）
そのため、`defun`を見ると「でふん」と認識してしまうのだ。
このとき、「でふん」派は己の本能のまま「でふん」と読めるのが
「でぃふぁん」派は理性を使わなければ「でぃふぁん」と読むことができない。
これは地味だが結構精神をすり減らすだろう。

```
でふん派
「defun」を見る → 「でふん」と脳が認識 → 本能に従い「でふん」と発音

でぃふぁん派
「defun」を見る → 「でふん」と脳が認識 → 理性で「でぃふぁん」に変換 → 「でぃふぁん」と発音
```

### 好きな理由2：言いやすいから

「でふん」と「でぃふぁん」どちらが発音しやすいだろうか？
「でふん」のほうが自然体で発音できるのに対し、
「でぃふぁん」は声を高く？しないと発音できない。
これも「でふん」派に軍配があがるだろう。

### 好きな理由3：かわいいから

「でふん」は「でぃふぁん」よりかわいい。
かわいいし、わびさびがある。
最高だ。

## そもそも

そもそも我々は
`Enum`を「いーなむ」
`DB`を「でーびー」
[`eval`を](https://edu-gw2.math.cst.nihon-u.ac.jp/~kurino/2002/comp/lisp/html4/lisp_c1_s2.html#:~:text=%E5%BE%8C%E3%81%AB%E8%BF%B0%E3%81%B9%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%80%81lisp%E3%81%AB%E5%AF%BE%E3%81%99%E3%82%8B%E3%80%81%E3%80%8CS%2D%E5%BC%8F%E3%82%92%E8%A9%95%E4%BE%A1%E3%81%97%E3%81%AA%E3%81%95%E3%81%84%E3%80%8D%E3%81%A8%E3%81%84%E3%81%86%E5%91%BD%E4%BB%A4%E3%81%A8%E3%81%AA%E3%82%8B%E3%80%82%E3%81%93%E3%82%8C%E3%82%92%E3%80%81%E3%80%8Ceval%20(%E3%82%A8%E3%83%90%E3%82%8B)%E3%80%8D%E3%81%A8%E8%A8%80%E3%81%86%E3%81%93%E3%81%A8%E3%82%82%E3%81%82%E3%82%8B%E3%80%82)[「エバる」](http://lambda.bugyo.tk/cdr/mwl07/mwl_17.jpg)
と読むではないか。

これは自分の本能のおもむくままに読んだほうが楽だからではないだろうか？
ならば別に`defun`を「でふん」と読むことは少なくとも「悪」ではないだろう。
ABC338回答メモ

# 0.はじめに
　前回やっと９００台にレートが上がったので好調を維持したいとおもいつつ
　臨みましたが、Dにてこずり、スコアが伸びず、レートは落ち888となりました。
　まぁなんとなく縁起がいいからよしとします。


# 1.A - Capitalized?
　なんか、文字列の大文字小文字判定の関数あったよなとググり判明。
　あとは、1文字目がisupperを満たし、1文字目以降がislowerを
　満たす時にYesを表示、満たさなければNoを表示してAC・・・・とはいかず
　Sが1文字の時は、1文字目が大文字という条件だけ満たせばOKという
　条件を追加してやっとACとなりました。

　https://atcoder.jp/contests/abc338/submissions/49695916


# 2.B - Frequency
　collections.Counterを使えば何とかなるかと思いましたが
　もうひとひねりが必要でした。
　【考え方】
　　・Sをリスト化し、collections.Counterで文字ごとのカウントをする。
　　・most_common関数で、文字ごとのカウントの最大値pを求める
　　・文字ごとのカウント数が、pと一致する文字をリストansに格納する
　　・ans内の最小値を出力して終了
　もっとスタイリッシュな書き方あるだろうなと思って解説を見たら
　pythonだとほぼ1行で書けそうでした・・。

　https://atcoder.jp/contests/abc338/submissions/49704191


# 3.C - Leftover Recipes
　まず最初に、Aを最大化した場合の残りでBを作った場合と
　Bを最大化した場合の残りでAを作った場合の多い方を出力
　と、簡単に行けないかと思いましたが、例１で挫折しました。

　まぁ、制約ゆるめなので、素直に時間がかかる方法を試しました。
　【考え方】
 　　・変数ansに0をセット
 　　・以下をAがARセットつくれなくなるまで、ARを1ずつ増やして繰り返す
　 　　・AをARセット作った場合の材料の残りQ2を求める
 　  　・Q2を使用して最大BRセットBを作れるか求める
   　　・ansにAR+BRとansの大きい方をセット
 　　・最後にansを出力して終了

　これで行ける！と提出したものの1個WA発生。
　落ち着いて考えたところ、ARの初期値は１ではなく、0でないと
　いけないことに気づきやっとAC。
　ペナルティ合わせて10分ほど無駄にしました・・・。

　https://atcoder.jp/contests/abc338/submissions/49723770


# 4.D - Island Tour
　初見であきらめたくなりましたが、まぁ40分は残ってたので取り掛かりました。
　グラフ問題かと思いきや、よくみるとそこまで難しく考えなくても
　よさそうでした。

　【考え方】
　　ある橋を封鎖する＝あるルートが逆回りになる
　　例）N=5　1-2-3-4-5-1・・・・の時
　　　3-4を封鎖すると
　　　　→3->4のルートを3-2-1-5-4としないといけない
　　　　　→ツアーの長さが+3される
　　ツアールートごとに封鎖された場合の長さ増分をリスト化する
  　増分リストの最小値+封鎖前の最小コスト＝答えとなる。
　　例１でいうと、封鎖前最小コストは２
　　　・1-2-3-1の島で
　　　　・1-3　3-1封鎖で+1
　　　　・3-2　2-3封鎖で+1
　　　　・封鎖長さ増リスト 0,1,1→最小値は0
    　・2+0で2が答え
    ※封鎖長さ増リストはルート毎に足していくと間に合わないので
    　いもす法で作成する。

　上記考えで実装するも、今一正解にたどり着かず、そうこうしている
　うちに、時間がたりなくなりコンテスト終了しました。

　解説を見ながらダメな点を考えたところ、いもす法で長さ増リストの
　加算スタート地点を単純にルートなり（リストA内の順番）で設定していましたが
　長さ増リストに反映する場合は、島番号の小さいほうにしないと
　いけないことに気づきました。
　あと1歩の気づきが足りなかったのが悔やまれます。

　https://atcoder.jp/contests/abc338/submissions/49742964


以上
Git で複数のリポジトリを一つにまとめる

## はじめに

本記事は、自分用の覚書として作成したものです。が、皆さんのお役に立てれば幸いです。

## 注意事項

複数のリポジトリを一つにまとめると、例えば以下で説明する統合元のディレクトリ docs/meisai 以下に置かれているファイルやディレクトリは、統合先のディレクトリ Documents 以下に置かれることになります。
- 例えば、docs/meisai/Makefie は、Documents/meisai/Makefile ではなくDocuments/makefile に置かれます。
- 統合元・統合先それぞれのディレクトリ以下に同名のファイルやディレクトリが存在する場合には、それを考慮して統合する必要があるのではないかと思います。
- 私の場合、そのようなことはなかったので、もしそのような状況になった場合に git merge を実行してしまうとどのようなことになるのかは、残念ながらわかりません。

## リポジトリの構成

今回は、docs 以下の三つのリポジトリ (2023/meisai, meisai, report) を新たに作成したリポジトリ (Documents) に統合する方法を解説します。
- docs と Documents は、いずれもホームディレクトリの直下に置かれていることを想定しています。

リポジトリ (ディレクトリ) の構成:
```
docs -+- 2023/meisai/.git
      +- meisai/.git
      +- report/.git
```
新しくディレクトリ Documents を作成し、git init を実行し、適当なファイル (README.md) を作成 git add; git commit した後に docs 以下のリポジトリを Documents 以下に取り込みます。
- README.md の作成、git add; git commit はやらなくても構いません。
- 既に存在するリポジトリに docs 以下のリポジトリを取り込むことを想定して、README.md の作成、git add; git commit しただけなので。

ホームディレクトでの操作手順を示します。
```
$ mkdir ~/Documents
$ cd ~/Documents
$ git init
$ touch README.md
$ git add README.md
$ git commit
```

以降の操作は、引き続き Documents ディレクトリで実行してください。

Documents に git remote コマンドを使用して docs 以下のリポジトリを登録します。
```
$ cd ~/Documents
$ git remote add 2023_repo ../docs/2023/meisai
$ git remote add meisai_repo ../docs/meisai
$ git remote add report_repo ../docs/report
$ git remote
2023_repo
meisai_repo
report_repo
$ 
```
add の直後に指定する 2023_repo など _repo は、分かりやすくするために _repo を付与しているだけなので、2023 などでも問題ないはずです。

登録したリポジトリを Documents に取り込みます。
```
report_repo
$ git fetch 2023_repo
$ git fetch meisai_repo
$ git fetch report_repo
```

Documents にマージします。
- Git 2.9 意向を使用する場合には、merge の後に --allow-unrelated-histories を指定してください。
```
$ git merge 2023_repo/master
$ git merge meisai_repo/master
$ git merge report_repo/master
```

以上です。
【Rails】DeviseやDevise Token Authのyield部分に処理を追加する方法

## はじめに
[Devise](https://github.com/heartcombo/devise)や[Devise Token Auth](https://github.com/lynndylanhurley/devise_token_auth)のコードの中に以下のように記述されている箇所があります。

```rb
  def create
    # ...
    yield resource if block_given?
    # ...
  end
```

https://github.com/heartcombo/devise/blob/e2242a95f3bb2e68ec0e9a064238ff7af6429545/app/controllers/devise/confirmations_controller.rb#L12

この`yield resource if block_given?`の部分に処理を追加する方法について記載します。

## 方法

オーバーライドの際に以下のように記述することで該当部分に処理を追加することができます。

```rb
  def create
    # ...
    super { |resource| 追加したい処理... }
    # ...
  end
```

または以下のように記述します。

```rb
  def create
    # ...
    super do |resource| 
      # 追加したい処理
    end
    # ...
  end
```
STM32C011のADCで遊ぶ(PA12ソフトウェアシリアル)(STM32C011J4M7)



STM32C011のADCで遊ぶPA12ソフトウェアシリアル)(STM32C011J4M7)




目的
ADCのテスト


![o_cop903.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/127fd267-7e1a-f824-1f21-edc887dd8b59.jpeg)



```c++


//SER_LB_9600_ADC_C011_1

#include <Arduino.h>

#include "SER_9600_C011_1.h"

//初期化
void setup()
{

  //シリアルの初期化
  pc.beginNS(9600);

} //setup


//メインループ
void loop()
{

  //センサーの値を読み込む
  analogReadResolution(12); // ADC 12bit mode
  int s = analogRead(PA11);   // センサーの読み取り値


  //データの表示
  String thisString1 = String(s);
  pc.printNS( (char *)thisString1.c_str()  );
  pc.printNS("\r\n");
  
  delay(1000);

} //loop


```



```c++:SER_9600_C011_1.h



#ifndef TEST_H
#define TEST_H

//SER_9600_C011_1.h


#define TX1      PA12      // ?pin

//#define UART_DELAY  96   //  9600bps  NG
//#define UART_DELAY  97   //  9600bps  NG
//#define UART_DELAY  98   //  9600bps  NG
//#define UART_DELAY  99   //  9600bps  NG
//#define UART_DELAY 100   //  9600bps  OK 1 
//#define UART_DELAY 101   //  9600bps  OK 2 
//#define UART_DELAY 102   //  9600bps  OK 3 
//#define UART_DELAY 103   //  9600bps  OK 4 
//#define UART_DELAY 104   //  9600bps  OK 5 
#define UART_DELAY 105   //  9600bps  OK 6 
//#define UART_DELAY 106   //  9600bps  OK 7 
//#define UART_DELAY 107   //  9600bps  OK 8 
//#define UART_DELAY 108   //  9600bps  OK 9 
//#define UART_DELAY 109   //  9600bps  OK 10 
//#define UART_DELAY 110   //  9600bps  NG
//#define UART_DELAY 111   //  9600bps  NG


//#define UART_DELAY 1000   //  9600bps ok E


#define DW   digitalWrite


//クラスの定義
struct _pc
{
  void beginNS(int sp);      //メソッドの宣言
  int  putcNS(char ch);      //メソッドの宣言
  int  printNS(char *str1);  //メソッドの宣言
};


//ポートをhiにする 初期化
//メソッドの定義
void _pc::beginNS(int sp)
{
  //ポートをhiにする初期化
  pinMode(TX1, OUTPUT);
  DW(TX1, HIGH);
}


//仮想シリアルへの一文字出力 9600bps
//メソッドの定義
int _pc::putcNS(char ch)
{
  DW(TX1, HIGH);

  DW(TX1, LOW);//START
  delayMicroseconds(UART_DELAY); //START BIT WAIT

  for (int ii = 0; ii < 8; ii++) {
    DW(TX1, (ch >> ii) & 1  );
    delayMicroseconds(UART_DELAY); //DATA 1-8BIT WAIT
  }//for

  DW(TX1, HIGH);//Stop
  delayMicroseconds(UART_DELAY); //StOP BIT WAIT

  return (0);
}


//文字列の表示
//メソッドの定義
int _pc::printNS(char *str1)
{
  //文字の中身がゼロか
  while (*str1) {

    //一文字出力
    putcNS(*str1 ++);

  } //while

  //戻り値
  return (0);
}


//実体の作成
_pc pc;


#endif



```
IoTおじさんになりたいITおじさん奮闘記　第2回　練習用キット - 2.いよいよはんだ付け！...あれ？...足りない...挫折？

#目次
[1.はじめに](#1-はじめに)
[2.購入したはんだごて](#2-購入したはんだごて)
[3.勉強する](#3-勉強する)
[4.早速やってみる！](#4-早速やってみる！)
[5....あれ？足りない...](#5-...あれ？足りない...)
[6.ICチップ部品の取り付け](#6-ICチップ部品の取り付け)
[7.ということで、練習キットはここまで！](#7-ということで、練習キットはここまで！)

# 1. はじめに
ソフトウェア分野ばっかりやってきて、IoTやハードウェアの知識に乏しいアラフォーおじさんが電子工作に目覚めるシリーズ。第2回目です。

今年は雪が少なく、子供たちも雪遊びができずに家でYouTubeばっかり見ています。
やっとまとまった雪が降り、大きな雪だるまを作ることができました。（右が私）
![IMG_7114.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2269692/23e42e23-4ce5-fedb-159b-83a1619c5a27.jpeg)

前回は、Amazonでよく考えずに買った練習用キットを確認する、ところまで行いました。
https://qiita.com/shiropyon71/items/3c538d0d0ee383b8658f

いよいよ、はんだ付けを行っていきます。

# 2. 購入したはんだごて
おそらく誰もが中学生ではんだ付けを体験すると思います。技術の授業です。

私は高校も工学系だったのですが、（記憶の限りでは）はんだ付けではなく、ぼつぼつ穴の開いたボードに刺して作るタイプのやつ（**ブレッドボード**というらしい。フリップフロップとか作った）の授業だったので、本当に中学生以来です。20年以上ぶり。

はんだごては、XIAOGYANのGitHubにある機材購入マニュアルのやつを買いました。
https://github.com/algyan/XIAOGYAN/blob/main/manuals/equipment/README.md

CXR-41というやつですね。小手先はデフォルトです。
https://www.goot.jp/products/detail/cxr_41

# 3. 勉強する
これもXIAOGYANのGithubで紹介されていた動画で勉強しました。
イチケンさんのはんだ付け動画です。

https://www.youtube.com/watch?v=dQ7AUjb1tkA


# 4. 早速やってみる！
中学生の時は、リード線のついた抵抗をつけたりしたので、足が長いのをやりました。でも今回は、チップ型です。**正直めっちゃ見づらいです。**
そんなに遠視はきていないはずなのに（めっちゃ近視です）。

結果

**幅2mmのやつはいけるけど、幅1mmのやつは難しかった。**
![IMG_7149.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2269692/ab78e701-e7c8-9062-a23e-034ddbffd815.jpeg)

あながちそこまで不可能ではない感触を得ました。
XIAOGYANは小さな部品あるのかしら？まず考えないでおこう。その時このキットに立ち返って練習しよう。

# 5. ...あれ？足りない...
コンデンサを順調に付けていったのですが、ここであることに気づきます。

**あきらかに足りないぞ**

いや、
**前回の確認なんだったんだよ！！**

そう、表の見方を間違えていて、コンデンサが足りないことに、今更気づいてしまったのです。

なので、このキットを完成させ動作させる、というよりは、あくまで練習用にしよう、ということに切り替えました。
もしかするとガチ勢の皆さんは、こういった部品を数多く保有しているのかしら。でもインチ規格だったし今更購入とうのもアレなので。。。

# 6. ICチップ部品の取り付け
このキットにはICチップ部品が2つついており、これも練習できました。
![IMG_7138.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2269692/5a41623b-5a43-db85-1b46-844d26607e29.jpeg)

**1つ目！見事なる失敗**
大きいほうのやつをやってみましたが、はんだの量が多すぎて、隣の足がつながってしまいました…。
![IMG_7139.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2269692/aacbb620-fcd6-dc3f-6719-65d911a94c1c.jpeg)

あちゃ～。
なんとか直そうにも難しく、とりあえず置いておきます。


**2つ目！はんだの量を考えてなんとか...**
2つ目の小さめのチップははんだの量を抑えてみました。
さっきよりは良い。
![IMG_7146.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2269692/52342f10-3726-3b6c-f95e-be4225029f0a.jpeg)

1本の足のはんだ量が足りないので足す。
![IMG_7148.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2269692/2416c7eb-b6ca-dbf3-d453-c6d2b8de2823.jpeg)

まあ、まあ、こんな感じだと。（手前のやつひどいね笑）


# 8. ということで、練習キットはここまで！

練習キットは通電することもないので、本当に練習に使おう！

ということで、次回からはいよいよXIAOGYANをやってみたいと思います。
まず、これを見ないと。。。
https://www.youtube.com/watch?v=WzVGK7PBv9Q

はたして本当にやれるのか！
自分自身は自分自身に期待しております。
ペライチとさくらのメールボックスを組み合わせる

# about
以下の組み合わせの際の設定について書きます
- ドメイン: お名前.comで管理
- Web: ペライチ
- メールサーバ: さくらのメールボックス

ペライチを利用しない場合も、メールサーバだけ別サービスを向けたい場合は参考になると思います。

# つまづきポイント
ペライチでドメインを取得した場合はペライチの設定でドメイン設定が行なえますが、外部でドメインを取得した場合はヘルプがありません。

## 前提

ここでは以下の前提で記載します。
- ペライチでは既に独自ドメインを割り当て済
- さくらのメールボックスは申し込みまでは済んでいる

また、記事の都合で以下として記載します。適時読み替えて下さい。

### お名前.com
- ドメイン: mydomain.com

### さくらのメールボックス
- 初期ドメイン: [mymailbox.sakura.ne.jp]
- ホスト名: www9999.sakura.ne.jp
  - www+4桁の数字がサブドメインとして割当てられます
- 作成済メールアドレス: info@mymailbox.sakura.ne.jp
  - =最終的に利用したいメールアドレス: info@mydomain.com


# 手順

## お名前.com側
### 設定
ドメイン設定タブ -> ネームサーバの設定 -> DNS設定/転送設定
設定するドメインを選択 -> 次へ
DNS設定 -> DNSレコード設定を利用する -> 設定する

追加フォームはこちら
![new.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275986/42500db0-763c-250b-5e09-edd2e173a5df.jpeg)

追加フォームに以下を入力する

- ホスト名：サブドメインは空
- TYPE：デフォルトではAが選択されているので、MXに変更
- TTL：3600 (変更なし)
- VALUE：www9999.sakura.ne.jp
※ TYPEをMXに変更するとVALUEにTEXTが挿入できます

### 確認
ドメイン設定タブ -> ネームサーバの設定 -> DNS設定/転送設定
設定するドメインを選択 -> 次へ
`登録済み`の項目を確認

![settings2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275986/ab80b8ad-a330-71f8-d0e7-625b0916c523.jpeg)

- [x] MXレコード(TYPE:MX)が「www9999.sakura.ne.jp.」
  - Suffixに`.`が付きますが問題ありません
  - (一応) MXレコードにさくらの初期ドメインを設定してもメールは届きます

- [x] 優先: 10
- [x] 状態: 有効
- [x] Aレコード: ペライチを向いていること「13.112.187.226」

## さくら側
### 設定
サーバーコントロールパネル -> ドメイン/SSL -> ドメインを新規追加 -> 他社で取得したドメインを移管せずに使う
ドメインを入力して「追加」ボタンを選択

### 確認
サーバーコントロールパネル -> ドメイン/SSL -> ネームサーバ設定
ドメインコントロールパネル -> 登録済ゾーン
- [x] 設定したドメインが登録されていること

#### 補足
「ゾーン」をクリックするとレコードの詳細が見れますが
ここのネームサーバは、さくらの権威DNSサーバー「ns1.dns.ne.jp」で問題ありません。

# トラブルシューティング

## レコードが反映されていない

比較的浸透は早い印象ですが30分程度は待ちましょう。
サポートに問い合わせる場合は24時間経過してからにしましょう。

## Gmailにメールを送るとエラーになる
SPFレコードの設定が必要です。

## ドメインでメールが届かない
info@mydomain.comにメールが届かない場合、
まずは、さくらの初期ドメイン「info@mymailbox.sakura.ne.jp」に届いているか確認しましょう。
さくらの初期ドメインとGmailでの相互の疎通を確認して下さい。
メールソフトではなく、まずはさくらのコントロールパネルのWebメールを利用して下さい。

# refs
ペライチで取得したドメインでメールアドレスを取得する方法
https://design-driven.com/peraichi-sakura/
(ここでは外部で取得したドメインを利用したいので参考までに)


# さくらのメールボックス
メールサーバを別途お探しでしたら、価格(年間1048円)・設定画面のわかり易さ共にオススメです。
Gmailの新しい「メール送信者のガイドライン」もあり、メールサーバを立てるのはつらくなってきました。
なかなか皆がGoogle Workspace導入とはいきませんからね (ドメイン利用は1アカウント毎に年間8160円)
STM32C011でString()関数で遊ぶ(PA12ソフトウェアシリアル)(STM32C011J4M7)


目的
よろー(46) の　46を表示して遊ぶ
46とは、ポケベル通信のはじめの電文(メッセージ)
広末涼子が有名
インターネット老人会では、ありません。

x ポケベルの歴史
x 歴史参考、学術、研究調査目的で非営利、引用目的で最小限で利用
x 期間も数週間で削除

高円寺の絶滅メディア博物館　ポケベルのイメージ

![o_cop915.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/60423b22-959a-f0bd-b728-d7e707cb2d29.jpeg)



![o_cop902.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/c5c062a2-fbf1-ead0-eee2-55a915d73ed3.jpeg)




```c++


//SER_LB_9600_46_C011_1

#include <Arduino.h>

#include "SER_9600_C011_1.h"

//初期化
void setup()
{

  //シリアルの初期化
  pc.beginNS(9600);

} //setup


//メインループ
void loop()
{

  //データの表示
  int s=46;
  String thisString1 = String(s);
  pc.printNS( (char *)thisString1.c_str()  );
  pc.printNS("\r\n");
  
  delay(1000);

} //loop


```



```c++:SER_9600_C011_1.h




#ifndef TEST_H
#define TEST_H

//SER_9600_C011_1.h


#define TX1      PA12      // ?pin

//#define UART_DELAY  96   //  9600bps  NG
//#define UART_DELAY  97   //  9600bps  NG
//#define UART_DELAY  98   //  9600bps  NG
//#define UART_DELAY  99   //  9600bps  NG
//#define UART_DELAY 100   //  9600bps  OK 1 
//#define UART_DELAY 101   //  9600bps  OK 2 
//#define UART_DELAY 102   //  9600bps  OK 3 
//#define UART_DELAY 103   //  9600bps  OK 4 
//#define UART_DELAY 104   //  9600bps  OK 5 
#define UART_DELAY 105   //  9600bps  OK 6 
//#define UART_DELAY 106   //  9600bps  OK 7 
//#define UART_DELAY 107   //  9600bps  OK 8 
//#define UART_DELAY 108   //  9600bps  OK 9 
//#define UART_DELAY 109   //  9600bps  OK 10 
//#define UART_DELAY 110   //  9600bps  NG
//#define UART_DELAY 111   //  9600bps  NG


//#define UART_DELAY 1000   //  9600bps ok E


#define DW   digitalWrite


//クラスの定義
struct _pc
{
  void beginNS(int sp);      //メソッドの宣言
  int  putcNS(char ch);      //メソッドの宣言
  int  printNS(char *str1);  //メソッドの宣言
};


//ポートをhiにする 初期化
//メソッドの定義
void _pc::beginNS(int sp)
{
  //ポートをhiにする初期化
  pinMode(TX1, OUTPUT);
  DW(TX1, HIGH);
}


//仮想シリアルへの一文字出力 9600bps
//メソッドの定義
int _pc::putcNS(char ch)
{
  DW(TX1, HIGH);

  DW(TX1, LOW);//START
  delayMicroseconds(UART_DELAY); //START BIT WAIT

  for (int ii = 0; ii < 8; ii++) {
    DW(TX1, (ch >> ii) & 1  );
    delayMicroseconds(UART_DELAY); //DATA 1-8BIT WAIT
  }//for

  DW(TX1, HIGH);//Stop
  delayMicroseconds(UART_DELAY); //StOP BIT WAIT

  return (0);
}


//文字列の表示
//メソッドの定義
int _pc::printNS(char *str1)
{
  //文字の中身がゼロか
  while (*str1) {

    //一文字出力
    putcNS(*str1 ++);

  } //while

  //戻り値
  return (0);
}


//実体の作成
_pc pc;


#endif





```