OmniAICreator/Qiita-1.07M huggingface dataset:
ABC352をPythonで（A～E）

AtCoder Beginner Contest 352 の解答などのまとめ

https://atcoder.jp/contests/abc352

# A問題
$x$と$y$の大小関係が不確定だから調べる
```python:A
n, x, y, z = map(int, input().split())

print("Yes" if min(x, y) <= z <= max(x, y) else "No")
```
# B問題
先頭からあっているか調べる
```python:B
s = input()
t = input()

j = 0
ans = []
for i, t_i in enumerate(t, 1):
    if t_i == s[j]:
        ans.append(i)
        j += 1

print(*ans)
```
# C問題
肩と頭の間の距離が長い巨人を一番上にすればいい
```python:C
n = int(input())

maxi = 0
ans = 0
for _ in range(n):
    a, b = map(int, input().split())
    ans += a
    maxi = max(maxi, b - a)

print(ans + maxi)
```
# D問題
C++ の multiset にあたる SortedList を使う

1. 各数字がどこにあるか調べる
1. $i$～$i+k-1$がある場所の最小値と最大値を調べる
1. 各最小値と最大値の差の最小値が答え
```python:D
from sortedcontainers import SortedList

n, k = map(int, input().split())
p = list(map(lambda x: int(x) - 1, input().split()))

a = [0] * n
for i, p_i in enumerate(p):
    a[p_i] = i

s = SortedList(a[:k])

ans = s[-1] - s[0]
for i in range(k, n):
    s.add(a[i])
    s.discard(a[i - k])
    ans = min(ans, s[-1] - s[0])

print(ans)
```
# E問題
クラスカル法
ただし、各$S_i$で全通りを調べたら間に合わない
$S_i$の先頭の数字を代表としてそれ以降と繋がるかを調べれば、$S_i$内のすべてが繋がる
```python:E
from collections import defaultdict


class UnionFind:
    """
    URL : https://note.nkmk.me/python-union-find/
    """

    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        group_members = defaultdict(list)
        for member in range(self.n):
            group_members[self.find(member)].append(member)
        return group_members

    def __str__(self):
        return '\n'.join(f'{r}: {m}' for r, m in self.all_group_members().items())


n, m = map(int, input().split())
UF = UnionFind(n)
ans = 0
data = []
for _ in range(m):
    k, c = map(int, input().split())
    a = list(map(lambda x: int(x) - 1, input().split()))
    data.append([c] + a)

for c, *a in sorted(data):
    for a_i in a[1:]:
        if not UF.same(a[0], a_i):
            UF.union(a[0], a_i)
            ans += c

print(ans if UF.group_count() <= 1 else -1)
```
データベースの基礎知識

# データベースとは
データベースは、決められた形式で整理されたデータの集まりのことを指し、集めたデータを効率的に検索・管理しやすくするためのものです。
表計算ソフト（Excelやスプレッドシート）もデータベースの要素を持っており、多くの人にとってデータベースは身近な存在となっています。
データベースと表計算ソフトは厳密には違うもので、その違いについては後ほど説明します。

## データベースの種類
主にデータベースは3種類に分けられます。

![データベースの種類.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/879861/3a6a9488-f47a-cf19-69e4-38cb9b64d971.png)

### 階層型データベース
階層型データベースとは、データがツリー構造で蓄積されたデータベースのことを指します。
上層から下層に分岐し、「一対多」の親子関係になります。
通常、特定のデータへのアクセスには1つのルートしかありません。これにより、データの検索が迅速に行えますが、データが重複する可能性もあるため注意が必要になります。

例えば、会社の組織を階層型データベースで管理する場合、1人が複数の部署に所属していると、同じ人の情報が複数の場所に現れることがあります。
従業員数を調べたい場合などは、重複によってずれが生じる可能性があります。

### ネットワーク型データベース
ネットワーク型データベースとは、階層型と構造は似ていますが、関連性のあるデータを相互に結びつけて保存します。階層型の場合は、上層から下層に向けて一方向に分岐させていましたが、ネットワーク型の場合は、下層から上層に向けても分岐させます。
階層型が「一対多」なのに対し、ネットワーク型は「多対多」の関係になり、重複登録を避けることができます。

例えば、1人が複数の部署に所属している場合、ネットワーク型データベースでは、同じ人物が複数の部署と関連付けられ、1人のデータから複数の部署にアクセスできます。
このため、階層型データベースとは異なり、1人のデータを複数回登録する必要がなくなります。

### リレーショナル型データベース
リレーショナル型データベースは、表計算ソフトのような表（行と列）でデータを管理して保存します。複数のシートを組み合わせて、複雑に関連しているデータを整理しやすいデータベースとなっています。

例えば、オンラインショップなどでは、顧客情報（顧客ID・氏名・住所）、商品情報（商品ID・商品名・価格）、注文情報（注文ID・顧客ID・商品ID・個数）などを関連づけることで、特定の顧客が購入した商品履歴などを調べることができます。

# データベース管理システム
データベースは、ただのデータの集まりで、自動でデータを整理することなどはできません。
そんなデータベースの整理や検索、更新、抽出を行ってくれるのが**データベース管理システム（DBMS）です。**
※DBMS・・・data base management system

## データベース管理システムと表計算ソフトの違い
表計算ソフトは、もともと1名または少人数向けに設計されており、膨大なデータの管理や複雑なデータ処理が苦手です。また、複数人で同時に操作をした場合、データの破損や誤削除などのミスが発生するリスクがあります。データベースに比べ検索のスピードも遅く、検索の幅も劣ります。

一方データベースは、大量のデータを整理・蓄積し、閲覧、更新、削除などの処理をした場合にも、これらの集合体を保てるよう設計されているため、膨大な量のデータ管理にも対応することができます。それと同時に、大人数のユーザーがデータを利用する際にも、迅速かつ安全にデータを利用でき、複雑な処理も可能です。


# データベースの構成
データベースは、「テーブル」「カラム」「レコード」「フィールド」の4つの要素から構成されています。
- テーブル
データを保存するための表です。エクセルだとシートに該当します。
- カラム
表の「列」に該当する垂直方向のデータです。
- レコード
表の「行」に該当し、水平方向のデータです。
- フィールド
エクセルだとセルに該当し、データの最小単位になります。


# データベース言語
DBMSに命令を出し、アクセス権を制御したり、データを抽出・更新したりするために使う言語のことをデータベース言語と言います。
データベースを扱うための言語でそれ以外の用途で使用することはありません。
データベース言語の中で最も利用されているのが、SQLでリレーショナルデータベースを操作する言語です。国際標準化機能（ISO）によって規格化されており、SQLを学んでおけば、ほとんどのRDBを操作できます。
SQLに関しては、また別の記事でまとめたいと思います。
iOSショートカットからWindowsをシャットダウンする

## 前提
- WindowsPCのローカルIPアドレスが固定になっている

## OpenSSHサーバーをインストール
1. 設定の「オプション機能の管理」から「OpenSSHサーバー」を追加する
2. 管理者権限のPowershellを開いて、以下のコマンドを実行する
    ```powershell:powershell
    Set-Service -Name sshd -StartupType 'Automatic' # OpenSSHサーバーを自動スタートアップに設定
    Start-Service sshd # OpenSSHサーバーを起動
    Get-Service -Name sshd # OpenSSHサーバーの状態を確認
    ```
    Statusが「Running」になっていれば起動成功

## iOSのショートカットを設定
1. ショートカットアプリを開き、新しいショートカットを作成する画面を開く
2. 「アラートを表示」を選択し、アラートメッセージを入力する
3. 「SSH経由でスクリプトを実行」を選択し、以下のスクリプトを入力する
    ```cmd:commandPrompt
    # /s: シャットダウン, /f: 警告せずにアプリケーションの実行を強制終了, /t 0:タイムアウト0s
    shutdown /s /f /t 0
    ```
    - ホスト：固定にしているローカルIPアドレス
    - ポート：22
    - ユーザ：Windowsログオンで使用しているユーザー名
    - 認証：パスワード
    - パスワード：Windowsログオンで使用しているパスワード
    - 入力：デフォルト
Excelでクロス表からJSONにする

# 背景
図のようにExcelで混ぜ物のレシピ表を管理しているとします。
それぞれのレシピについて、JSONで1行のテキストにしたいときどうしようかという一発ネタです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471244/c0732c8a-ec8c-ebca-0936-2d4b460d4dc3.png)


# 結論

下記のようにTEXTJOINで簡単にできます。
念のため説明すると、
・B列の空白でないセルについて
・"水":200 のようなJSONの要素が並んだ配列をつくり
・TEXTJOINを用いてカンマ区切りでつなげる
ということをしています。ドラッグすることでC列も同様にできます。

``` vb:セルB13
="{"&TEXTJOIN(",",TRUE,IF(B2:B12="","",""""&$A$2:$A$12&""":"&B2:B12))&"}" '数式
{"水":200,"ほんだし":5,"酒":5,"砂糖":5,"しょうゆ":10,"牛肉":30,"レンコン":20,"にんじん":20,"ジャガイモ":30,"たまねぎ":20} '評価値
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471244/5ba3a082-1486-71b8-0f13-a5589911eb55.png)
M5NanoC6をBluetoothキーボードにする

# M5Stack NanoC6
M5Stackシリーズで2024/03に発売された、M5NanoC6を購入しました。

▼ 公式ドキュメント

https://docs.m5stack.com/ja/core/M5NanoC6

▼ スイッチサイエンスさんの販売サイト

https://www.switch-science.com/products/9570

この小ささ（小指サイズ）、機能、気になることがいっぱいです。
なんといってもそのお値段のお手ごろさに惹かれました。

# Bluetoothキーボードにしてみた
ところで私のノートPCの「A」キーが不調で、扱っているうちにすぐキーキャップが外れるし、入力が効きにくくなってとても困っていました。

そこで「ちょうどキーのサイズのM5NanoC6をAキーにしてしまおう。サンプルプログラムの各色で光るのもゲーミングキーボードみたいだし！」と思って今回「A」キーが機能するというだけのBluetoothキーボードにしました。

https://x.com/siroitori0413/status/1784142337385619751

しかし何かと実装に試行錯誤した部分があったのでここに書いておくことにしました。

# M5Stack NanoC6 の Bluetooth
最初、何も考えずにM5StackやM5StickCなどでよく使っていたESP32-BLE-Keyboardライブラリ（BleKeyboard.h、下記）を使おうとしました。

https://github.com/T-vK/ESP32-BLE-Keyboard

するとうまくいきません。

これは使えないのだなと思い、M5NanoC6の仕様を確認しました。

スイッチサイエンスさんのサイトには、
>SoC ESP32-C6FH4@RISC-V 160MHz、4M フラッシュ、Wi-Fi 6 (2.4GHz)、Zigbee 3.0、Thread 1.3、Matter、CDC

と書いてあり、M5NanoC6はESP32-C6というマイコンを使用しているようです。
ただどこにもBluetoothやBLEの表記がありません！
これは使えないのかと思いましたが、その後調べて**ESP32-C6にはBluetooth機能がある⇒M5NanoC6でもBluetooth使えそう**ということがわかりました。

# ライブラリ側を修正した
ライブラリをForkして自分のところでC6用として作成しました。

https://github.com/siroitori0413/ESP32-BLE-Keyboard

ライブラリ修正内容の説明はいいのでとにかく実装したいという方は、こちらを使ってみてください。
使い方としては、

```c++:
 #include <BleKeyboardC6.h>
```

と定義して使用します。それ以外の書き方は既存のESP32-BLE-Keyboardと同じですので、他でぐぐってもよいですし、本家のReadMe (https://github.com/T-vK/ESP32-BLE-Keyboard) にも書かれています。

#define USE_NIMBLE
はしない（書かない）想定で作っています。


## ライブラリの修正内容について
上記で修正した内容について記載します。
Diff（下記）を見ていただけたらそのとおりなのですが、インタフェースと認証モードを変更しています。

https://github.com/siroitori0413/ESP32-BLE-Keyboard/commit/0ddf55b1501c093bf59a1987b985a404026369d1#diff-347d42a9f10f13cda12a2b54521d4d8b168f63430d2ad45943fc5ce1babd28f8

## USE_NIMBLE
ESP32-BLE-KeyboardにはUSE_NIMBLEというものが存在します。
▼ USE_NIMBLEについて参考にさせていただいた記事

https://qiita.com/nak435/items/db685f1b79ede557d753

今回の修正は、私の環境の都合によりUSE_NIMBLEの設定ができなかったのですが、本来ならば今回のケースでもUSE_NIMBLEを使うべきなのかなと思っています。

私は知識が浅いのでお詳しい方にぜひ今後本家BleKeyboardを拡張していただけたらいいなぁなどと思っています。
Channelとマルチスレッドを使ったエラトステネスの篩(ふるい)

# ストリームを使った素数生成

その昔、第5世代コンピュータというプロジェクトがあり、そこでFlatGHCとかKL-1という細粒度並列プログラミング言語が作られていた。この言語は、すべての関数呼び出し(みたいなもの)が並列に動作し、未定義状態の変数に対して束縛することで計算が進む、今から考えても非常に特殊な言語だった。

その言語のサンプルとしてよく使われていたのが素数生成だった。アルゴリズムは、いわゆるエラトステネスの篩なのだが、各素数に対する篩を並列に再帰関数で表現されたプロセスとして動作させ、
リストをストリームとして使って、そのプロセス間をつなぐものだ。

``` mermaid
flowchart LR
    自然数生成 --> 2に対する篩
    2に対する篩 --> 3に対する篩 
    3に対する篩 --> ...
```
ポイントは、篩を行うプロセスを自動的に生成していくところ。


## KL-1でのコード
もうシンタックスとかもうろ覚えだし、手元にKL-1の処理系がないので動作が確認できないが、コードとしてはこんな感じ。

``` Prolog
prime(N, R):-
    gen(2, N, Numbers),
    sieve(Numbers, R).

gen(Start, End, R) :- Start <= End | 
    R = [Start| T],
    gen (Start + 1, End, T).
gen(Start, End, []) :- Start > End |
    R = [].

sieve([H|T], R) :-
    R = [H|R2],
    filter(H, T, T2),
    sieve(T2, R2).
sieve([], []).

filter(V, [H|T], R) :- H mod V = 0 | 
    filter(V, T, R).
filter(V, [H|T], R) :- H mod V != 0 |
    R = [H|R2],
    filter(V, T, R2).
filter(_, [], []).
```

# Rustで書く
これをRustで書いてみた。プロセスはスレッドで、ストリームはチャンネルで実装する。

main関数はこんな感じ。2組チャンネルを作る。この2組のチャンネルは下図の2つの矢印に相当する。



```mermaid
flowchart LR
   自然数生成 --> 篩プロセス群 --> 素数回収
```

1つ目のチャンネルの入力に2以上の自然数を流し込むと、2つ目のチャンネルの出力から素数が出てくる。出てきた素数は、`iter().collect()` で回収。

``` Rust
use std::thread;
use std::sync::mpsc::{
    channel,
    Sender,
    Receiver
};

fn main() {
    let (numbers_in, to_sieves) = channel();
    let (result_stream, result_out) = channel();
    thread::spawn(move|| {
        sieve(to_sieves, result_stream);
    });
    thread::spawn(move || {
        for i in 2..1000 {
            numbers_in.send(i).unwrap();
        }
    });

    let res: Vec<i32> = result_out.iter().collect();
    println!("Received {:?}", res);
}
```

篩プロセスは
- 1つ目に取り出した値が素数であると想定して、
- 素数を回収しているチャンネルにその値を書き、
- 入力列からその値の倍数をすべて削除した新しいストリームを作り、
- 次の篩プロセスを起動して、そのストリームを渡す。

``` Rust
fn sieve(in_stream: Receiver<i32>, result_stream: Sender<i32>) {
    if let Ok(prime) = in_stream.recv() {
        result_stream.send(prime).unwrap();
        let (tx, rx) = channel();    
        thread::spawn(move|| {
            sieve(rx, result_stream);
        });

        for i in in_stream {
            if i % prime != 0 {
                tx.send(i).unwrap();
            }
        }
    }
}
```

結果を書き込むチャンネルを明示的にクローズしなければいけないかと思ったのだが、ドロップされたタイミングで、勝手にクローズされるので大丈夫。

# 感想
KL-1のコードにCopilotがガンガン適切なサジェストをしてくるのにおどろいた。一体なにがどうなってるんだ。

次はasync awaitで書いてみよう。
OSS-DB Silver(ver 3.0) 取得したが、思っていたのとは違った

# 背景
・データベース運用する予定ができた
・Accessで簡単なSQLとかは書いてたけどデータベースの概論も知りたくなったので受験

# 合格まで
・だいたい40時間くらい勉強
・まずいわゆる緑本を10時間くらいかけて読んだが、時間をかけすぎだった気がする
・ping-tメインで最終的に↓のような感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471244/a2918996-68a8-d6f9-e3b9-27e8abef8db3.png)
・得点:84 (合格ライン:64)
・レベル的にはping-Tと同じくらい


# Tips
・ping-Tの問題にはない、簡単なJSON形式のデータを読みとく出題がありました。

・バークレー校で開発されたデータベースが云々みたいなやつ、本当にこんなの出るのかよと侮っていたのですが本当に出て焦りました。

・設定ファイルやpsqlといった項目の覚えゲーに最初は圧倒されてしまうと思います。これをどう乗り切るかという話ですが、ping-tの問題の下のほうにある「参考」を何も考えずに写経してみるのを提案したいです。「参考」は非常によくまとまっているのですが、初期状態の「何がわからないのかわからない状態」だと解説を眺めても頭に入ってこないので焦燥感をためていました。そこで写経を行ったところそういったストレスも少なく、気づいたら「わからないことがたくさんあるが解説を読めばなんとなくわかる状態」にレベルアップできた感がありました。

# 感想
SQLやトランザクションといったデータベースの一般的知識と同じくらいかそれ以上の量のPostgreSQL独自の運用管理の知識を詰め込む必要があるので、正直なところ私の動機とはあまりマッチしていなかったかなと思いました。自動車を乗りたくて教習所にいったら半分くらいは交通ルールを叩き込まれる時間だった、みたいな。まあ当たり前なんですが。

ただ細かい操作方法を把握する過程で実務の流れのイメージがわずかでもついた気がしたのでそこはよかったです。

#  役に立った話
RDKit(化学の構造を扱えるライブラリ)にPostgreSQL向けの拡張機能があります。遊んでみたところ非常に楽しかったです。当然postgreSQLのコマンドを調べる必要がありましたが、「ああ、あれね」となり結構理解が早まったのでよかったです。とっててよかったOSS-DB。

https://qiita.com/walfiesfan/items/8b817150f6a6cc9e9d64
headタグ内のstyleとbodyタグ内のstyleの違い

:::note
結論
- headタグ内のstyleはbodyタグ内のstyleで上書きされる
- HTML Living Standardでは仕様としてはheadタグ内を推奨しているが、主要なサイトではbodyタグ内に記述している事例はある
:::

# 背景🎏
業務でhead,body内にstyleタグを埋め込む処理を実装していました。
実際どのような違いがあるのか分からなかったのでこの度調べてみます！

# headタグ内のstyleはbodyタグ内のstyleで上書きされる🎨

https://web-camp.io/magazine/archives/75036#:~:text=%E4%B8%A1%E6%96%B9%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%9F%E5%A0%B4%E5%90%88%E3%81%AFstyle%E5%B1%9E%E6%80%A7%E3%81%8C%E5%84%AA%E5%85%88%E3%81%95%E3%82%8C%E3%82%8B

headタグ内のstyleはbodyタグ内のstyleで上書きされるそうです。

サンプルコード

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="LYvKwdm" data-user="uuylkesg-the-styleful" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/uuylkesg-the-styleful/pen/LYvKwdm">
  style overwrite by style element within body </a> by 山根大生 (<a href="https://codepen.io/uuylkesg-the-styleful">@uuylkesg-the-styleful</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

以下が理由だそうです。
>headタグ内に指定したstyleタグが先に実行されます。
その後にstyle属性が、styleタグを上書きする形で実行されます。

確かに上書きされています。
styleタグを記述する際は上書することもあると頭に入れておく必要があります。

# HTML Living Standardではbodyタグ内にstyleタグを書くことについて触れられていない😵

HTML5.2で`bodyタグ内にstyleタグを書くことが可能`になったそうです。
[引用](https://www.w3.org/TR/2017/REC-html52-20171214/changes.html#:~:text=style%20within%20the%20body.
)

HTML5に変わって現在の標準であるHTML Standardでは`headタグにstyleタグを書く`と書かれています。
>In a noscript element that is a child of a head element.
[whatwg](https://html.spec.whatwg.org/multipage/semantics.html#the-style-element:~:text=content%20is%20expected.-,In%20a%20noscript%20element%20that%20is%20a%20child%20of%20a%20head%20element.,-Content%20model%3A
)

つまり、bodyタグにstyleタグを書くことについて触れられていないです。

:::note
禁止されているような文言が見当たらなった為、触れられていないと表現しています。
:::

# 「style tag should be allowed in body」🗣️

https://github.com/whatwg/html/issues/1605

styleタグをbodyタグ内で使うことに関する議論が過去にされていたそうです。

[主要なwebサイトでもbodyタグ内にstyleタグを使用している](https://github.com/whatwg/html/issues/1605#issuecomment-282476492)

>`Do we have proof that <style> in <body> significantly affects performance on a real website?`

「bodyタグ内のstyleタグが実際のウェブサイトのパフォーマンスに大きく影響するのか」という問いの答えは出ないままcloseされています。

# 参考
- [HTML Living Standardとは？廃止されたHTML5との違いなど徹底解説！](https://seolaboratory.jp/49735/)
- [HTMLのbody内に<style>～</style>定義は作法的にOKでしょうか？](https://oshiete.goo.ne.jp/qa/13616097.html)
- [style tag should be allowed in body](https://github.com/whatwg/html/issues/1605)
- [参考コード付き】htmlにstyleを直書きする方法について解説](https://web-camp.io/magazine/archives/75036#:~:text=%E4%B8%A1%E6%96%B9%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%9F%E5%A0%B4%E5%90%88%E3%81%AFstyle%E5%B1%9E%E6%80%A7%E3%81%8C%E5%84%AA%E5%85%88%E3%81%95%E3%82%8C%E3%82%8B
)

# 最後に
- bodyタグ、headタグにstyleタグを記述する際の違いについて勉強になりました
- 仕様としてはheadタグ内を推奨しているが、主要なサイトではbodyタグ内に記述している事例もあるということを知り興味深かったです
- 過去に「bodyタグ内にstyleタグを記述する」ことについて議論があったことを初めて知りました
C++でファイルを通した入出力をしたい（備忘録1）

演習の授業でつまづいたところをまとめた。


## C++でファイルを通した入出力


###  出力ファイル名に変数を含む時のコード例(fprintfを利用する方法)
先にディレクトリで`data`を作っておく必要がある。
ファイルへの出力は`data/filexxx.dat`(`xxx`には3桁でゼロ埋めをする)ときを考える。
```C++
using namespace std;

int main(){
  int n = 100;

  // def of name of file(s)
  char filename[20] = "data/file";
  char extension[5] = ".dat";
  char filepath[25];

  for(int i = 1; i <= n; i++){
    sprintf(filepath, "%s%03d%s", filename, i, extension);

    // make file(s)
    FILE *file = fopen(filepath, "w");

    // output to file(s)
    fprintf(file, "hogehoge \n");
    fprintf(file, "03%d\n", i);

    // close file(s)
    fclose(file);
  }
  return 0;
}
```
これを実行すると，`data/file001.dat`から`data/file100.dat`までの100ファイルが生成されて，その中には，たとえば`data/filexxx.dat`には
```text
hogehoge
xxx
```
と記入されて出力されている。

### 出力ファイル名に変数を含む時のコード例(ofstreamを利用する方法)
上のコードで`for`文の内部を以下のように書き換えると同じ出力を得ることができる。
```C++
for(int i = 1; i <= n; i++){
  sprintf(filepath, "%s%03d%s", filename, i, extension);
  
  ofstream ofs;
  ofs.open(filepath);
  
  // output to file(s)
  ofs << "hogehoge" << endl;
  ofs << setfill('0') << right << setw(3) << i << endl;
  
  ofs.close();
}
```

## Gnuplotで線分を表示する方法

```gnuplot
plot "-"
0.0, 0.0
1.0, 1.5
e
```
とすると`(0, 0)`と`(1, 1.5)`を結ぶ線分が出力される

## pngを統合してgifを作る方法
```shell
> convert $(ls *.png | sort -V) out.gif
```

(注) `ls`でpngファイルを探して，`sort`を行い，順番通りに並べる。それを`convert`に渡して`out.gif`を作っている。
(参)`convert`を使うと，`WARNING: The convert command is deprecated in IMv7, use "magick"`という表示が出てくるので，
```zsh
>  magick $(ls *.png | sort -V) out.gif 
```
とした方がいいかもしれない
Azure Fundamentals(AZ-900)合格体験記

:::note warn
警告
本記事は2024年5月に受験した際の内容をもとに記載しています。皆さまが受験される際には最新の情報をチェックいただくようお願いします！
:::

# 前提知識としてあったもの
普段からIT部門で業務(DB周りがメイン)
数年前にAWSクラウドプラクティショナー取得。クラウド概略は理解しておりAWSも普段から利用
AzureはFunctionsで関数を一つ作成したのみ、ほとんど利用機会なし

# 受験理由
Azure OpenAIが自社で導入され、Azureサービスに触れる機会が増えそう
Azureに触れる機会が今までほとんどなく、ここらで薄く広く知りたいと思い、とりあえず入門編の本資格を受験

https://learn.microsoft.com/ja-jp/credentials/certifications/azure-fundamentals/?practice-assessment-type=certification

# 結果
無事一度目のチャレンジで合格
合格ボーダーは7割なのですが、約900点/1000点とある程度余裕もって合格することができました。

後述する学習方法で配分としては以下の通り
60%：見たことある問題　→　問題集の解説が間違っていなければ大丈夫！
35%：似たような問題は知っている　→　大体こんなもんだったよね？
5%：完全初見の問題　→　うーん、参考書書いてあったような、なかったような…えいや！


# 1. 参考書
『Microsoft認定資格試験テキスト AZ-900：Microsoft Azure Fundamentals』(SBクリエイティブ)

色々書き込みしたい派なのでまずは書籍で。こちらのシリーズは以前AWS資格を取得した際にもお世話になりました。
最短合格を目指す書籍なので出題頻度の少なそうな範囲は大胆にカットしたりしていますが、合格ボーダーの7割を取るのには十分な内容と思います。

https://www.sbcr.jp/product/4815610869/

# 2. 問題集
『【6万人が受講】AZ-900 Microsoft Azure Fundamentals模擬試験問題集（7回分490問）』

この資格の受験料は12,500円なのです。絶対不合格にはなりたくない…ということでさらに問題集を追加。セールで1,500円でした。
7回分収録されているのですが7回目は難易度高い問題を集めているということで1~6回を2周しました。1周目は7割前後、回によっては7割を切るというところでしたが、2周もすれば安心。

https://www.udemy.com/course/az-900-microsoft-azure-fundamentals4176/

# 最後に
以上が受験に向けて勉強したことです。上記の内容が理解できれば問題なく合格できると思います！
次はAI関連の資格を取りたいので、AI-102を受験する予定です(挫けそうになったらAI-900にするかもしれません…)
【Go言語学習】txtファイルをgoファイルへ変換

「エキスパートたちのGo言語」という書籍を購入し(2022年1月12日)、勉強をし出したところ(2024年5月1日)、サンプルコードがありダウンロードした。https://gihyo.jp/book/2022/978-4-297-12519-6/support
サンプルコードは、txtファイルであった。

## txtファイルをgoファイルへ
せっかくならgoファイルに変換し、エディターを使っていじったり動かしたりしたかったので、取り急ぎ全ファイルを変換することに。
しかし、txtファイルのエンコードがまちまちで、そのまま変換すると文字化けするので、良い方法を探したが、結論から言うと見つからなかった。
一応、何をしたか備忘録をとることに。

## やったこと
pythonで、各txtファイルからエンコーディングの種類を読み込み、各txtファイルを各エンコーディングで開き、UTF-8でエンコーディングし閉じる
Go言語で、ファイルの拡張子を　txt　→　go へ変換
結果、Windows-1254　は　UTF-8　にうまくエンコードできず、文字化けした

## コード

https://github.com/kabasunny/GoPractice/tree/main/txt_to_go

これは、とりあえずpython使って、エンコーディングを検出してるだけのコード
```python
import os
import chardet

def detect_encoding(file_path):
    with open(file_path, 'rb') as f:
        rawdata = f.read()
    return chardet.detect(rawdata)['encoding']

def detect_encodings_in_folder(folder_path):
    for root, dirs, files in os.walk(folder_path):
        for file in files:
            if file.endswith('.txt'):
                file_path = os.path.join(root, file)
                encoding = detect_encoding(file_path)
                print(f'File: {file_path}, Encoding: {encoding}')

# 基準フォルダパスを指定
folder_path = '.'
detect_encodings_in_folder(folder_path)
```

続いて、python使ってエンコーディングを検出し、検出したエンコーディングでファイルを開いて、UTF-8でエンコードするつもり...うまく行かなかった
```python
import os
import chardet
import codecs

i = 0

def convert_encoding(file_path, target_encoding='utf-8'):
    global i
    i += 1
    # Detect current encoding
    with open(file_path, 'rb') as f:
        rawdata = f.read()
    current_encoding = chardet.detect(rawdata)['encoding']
    print(i,": befor_current_encoding :",current_encoding)

    # Open the file in the detected encoding
    with codecs.open(file_path, 'r', encoding=current_encoding, errors='ignore') as f:
        content = f.read()

    # Write the content back to the file in the target encoding
    with codecs.open(file_path, 'w', encoding=target_encoding) as f:
        f.write(content)
        
    # Chack current encoding
    with open(file_path, 'rb') as f:
        rawdata = f.read()
    current_encoding = chardet.detect(rawdata)['encoding']
    print(i, ": after_current_encoding :",current_encoding)

def convert_encodings_in_folder(folder_path):
    for root, dirs, files in os.walk(folder_path):
        for file in files:
            if file.endswith('.txt'):
                file_path = os.path.join(root, file)
                convert_encoding(file_path)

# 基準フォルダパスを指定
folder_path = '.'
convert_encodings_in_folder(folder_path)
```


続いてGoを使って、拡張子の変更
```Go
package main

import (
	"os"
	"path/filepath"
	"strings"
)

func visit(path string, f os.FileInfo, err error) error {
	if !f.IsDir() && strings.HasSuffix(path, ".txt") && !strings.HasSuffix(path, "README.txt") {
		newPath := strings.TrimSuffix(path, filepath.Ext(path)) + ".go"
		os.Rename(path, newPath)
	}
	return nil
}

func main() {
	root := "." // 基準フォルダパスを指定
	filepath.Walk(root, visit)
}

```

結局うまく行かんかったし、全然Go言語の勉強が出来なかった😨
wordpressで「更新に失敗しました。 返答が正しい JSON レスポンスではありません。」が出たときの対処法

投稿を保存しようとすると「更新に失敗しました。 返答が正しい JSON レスポンスではありません。」というエラーが発生する。

## 解決方法
設定＞パーマリンクで「基本」以外で更新する。空更新でもOK。
ttrpc tutorial - 1 - 

# ttrpc

## 問題
無駄なリソースをさらに削減できる点では活用したいですが、公式のマニュアルなどが揃ってない、個人的にはわかりにくいサンプルコードから少しハードルを感じているかと思いました。実際やってみたところ想定以上時間がかかったため、手順など残しておきたいと考えてます。

## ゴール
ttrpcのサンプルコードを変形してわかりやすく＋すぐ動くようにチュートリアルを作りました。
動作確認と使っているライブラリなど確認できればと思います。

## 開発環境・ライブラリ
go 1.21.0
github.com/containerd/ttrpc v1.2.3

## ttrpcのprotoファイル生成（プラグイン）
`protoc-gen-go`と`protoc-gen-go-grpc`はインストール前提とします。
下記のコマンドから`rrtpc`生成のためのプラグインをインストールします。

`go install github.com/containerd/ttrpc/cmd/protoc-gen-go-ttrpc@v1.2.3`
`go install github.com/containerd/ttrpc/cmd/protoc-gen-gogottrpc@v1.2.3`

指定している`v1.2.3`は最新バージョンとなります。


## サーバーサンプル
### ファイル構成
```
-server
| go.mod
| go.sum
| main.go
+ interfaces
|  example.proto
|  example.pd.go
|  exmaple_ttrpc.pd.go
```

### main.go(一部抜粋)
```main.go

func server() error {
	s, err := ttrpc.NewServer(
		ttrpc.WithServerHandshaker(nil),
		ttrpc.WithUnaryServerInterceptor(serverIntercept),
	)
	if err != nil {
		return err
	}
	defer s.Close()
	example.RegisterExampleService(s, &exampleServer{})

	l, err := net.Listen("unix", socket)
	if err != nil {
		return err
	}
        defer func() {
		l.Close()
		os.Remove(socket)
	}()

	return s.Serve(context.Background(), l)
}
```
基本的な使い方はgRPCと違いないですが、サーバを開始する際に提供ライブラリを使います。
主にhttpサーバーのために記載かと思いますが、今回に関してはローカル環境のことで特別なファイルを扱います。
`unix`タイプのファイルですが、詳しい説明は割愛あします。Posix関連書籍かマニュアルから確認可能です。
また、ネットワークポートの指定ではないため、ファイルパースを渡すことになります。
そのため、`os.Remove`から使い終わったファイルを削除いてます。


## クライアントサンプル
### ファイル構成
```
-server
| go.mod
| go.sum
| main.go
+ interfaces
|  example.proto
|  example.pd.go
|  exmaple_ttrpc.pd.go
```


### main.go(一部抜粋)

```main.go

func client() error {
	conn, err := net.Dial("unix", socket)
	if err != nil {
		return err
	}
	defer conn.Close()

	tc := ttrpc.NewClient(conn, ttrpc.WithUnaryClientInterceptor(clientIntercept))
	client := example.NewExampleClient(tc)

	r := &example.Method1Request{
		Foo: "Foo",
		Bar: "Bar",
	}

	ctx := context.Background()
	md := ttrpc.MD{}
	md.Set("name", "koye")
	ctx = ttrpc.WithMetadata(ctx, md)

	resp, err := client.Method1(ctx, r)
	if err != nil {
		log.Println("error")
		return err
	}
	return json.NewEncoder(os.Stdout).Encode(resp)
}
```

クライアントもサーバー同様、gRPCと変わらないですが、接続部が異なります。
サーバー側で指定しているインタフェースとファイルパスを入れることで接続ができます。

## 動作確認
サーバー、クライアントから下記の結果が確認できました。

```サーバー側

@iMac server % go run main.go 
2024/05/04 21:05:28 server start
2024/05/04 21:05:34 server interceptor
map[name:[koye]]
{"name":["koye"]}
method1 call
```
クライアントから受け取ったパラメータを出力してます。

---

```クライアント側

@iMac client % go run main.go 
2024/05/04 21:05:34 client start
2024/05/04 21:05:34 client interceptor
map[name:[koye]]
{"name":["koye"]}
{"foo":"Foo","bar":"Bar"}
```
サーバー側にパラメータを送り、そのレスポンスを出力してます。


## 注意
ネットワーク通しのrpcではなく、主にローカルrpcを目的として使われるライブラリとなります。
もし、ネットワーク環境、セキュリティー要件などがある場合には通常のgRPCが適合しているかと思います。
protoインタフェースの全てではないと記載があったかと（確かではない）ので、一部、使えないインタフェースがあるかもです。


## 終わり
k8sランタイムの役割を行う`containerd`のプロジェクトから作成されたライブラリとなります。
クラウド環境の運用業務を経験した方には見覚えのあるキーワードになるかと。
次は実際にどのぐらいコンピューター資源を軽減できるかも確認してみたいと考えてます。
今回使ったソースは下記のリポジトリとなります。ご参考にできればと思います。
あと、接続については一応、ローカル向けのrpcですが、ネットワーク通しでも使えます。
イントラー環境ならセキュリティー要件をクリアした前提ならアリかなと思います。

https://github.com/dlstjq7685/ttrpc-simple-example/tree/main
SANYOのNi-MH電池の充電器を分解してみた

## はじめに
どもども。なぜか2日連続投稿になってしまったbockringです。

今日は山陽電気(SANYO)のeneloop充電器を新しくPanasonicのBQ-CC73(Amazon限定モデルのようです)買い替えたので分解して部品をいただいていきましょう(供養)。

ちゃんと昨日の失敗を活かし(？)、忘れずに写真を撮りました。このモデルです。
![IMG_1090.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777721/663c28bd-9d27-043c-48d8-4edb223d121e.png)
よく見ると樹脂が若干黄ばんでますね。

買い替えの理由は小容量廉価版のeneloop liteが充電できなくなったからですね。

それでは供養していきましょう〜

## 分解開始
とりあえずネジ外しましょか〜、と行きたいですがここで一悶着。まさかのネジが「いじり留め付きトルクス(ヘクサローブ)8番」という半分呪文みたいな奴でした。
![IMG_1094.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777721/e3f4e5cb-bc69-06cb-9572-215f2383bd67.jpeg)
「こんなドライバーあったっけ〜？」とか思いながら工具箱を漁るとビットケースを発見。いつのやつかは分かりませんが3本とも、外せました。

そしてこのSANYOの「分解なんてさせて堪るか！」と言わんばかりの外装ケースを外すのにもう一悶着。あまりにツメが硬すぎます。ということでうちの投稿者は脳筋限界系ジャンカーですのでいつものパワープレイです。ﾊﾞｷｯ!よし、ツメは折れたけど問題NAI★って感じで開腹しまして…

とか言ってたらいつのまにか基盤裏側(実装面)にご対面。なんというか、汚いです。フラックスでしょうか。無水エタノールで拭いてみます。綺麗に落ちました。(まぁ基板は捨てますし、部品は外すのでフラックスあった方が良いんですけどね。なぜか無性に綺麗にしたくなります。)

とにかく基板を外しましょう。まさか基板はケースの樹脂と単3型用-(マイナス)の電極で支えていたとは。4本の指で少し押し込んで外します。いざ基盤とご対面。
![IMG_1091.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777721/4aa2f3ae-d509-a2d6-98de-19afe1f00c57.png)
はい。片面実装です。部品を外したら悟りの茶色に帰しますので、写真はありません。

実装されていたトランスは想像以上に小さかった、ということで(？)供養していきましょう。

## 供養開始
それでは供養開始…いや供養終了です。いやー写真が無いと書くことが本当にないですね(笑)

今回の部品達(抵抗器除く)はこんな感じです。
![IMG_1092.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777721/5c5c6527-4137-e940-a0e7-a194b0903139.jpeg)
あ、ちなみに1つだけインダクタを写真に入れるのを忘れています。これに関しては私は悪くないですね(ｷﾘｯ) 抵抗器みたいなカラーコード(ちなみに、「茶黒赤銀」でした。「茶黒」で「10」、「赤」で「×10^2」、「銀」で「許容誤差±10%」を表します。インダクタの場合基本単位はなぜかμH(マイクロヘンリー)ですので1000μH(=1mH)です。実測値は0.90mH、許容誤差範囲内ですがギリギリですねw)を身に纏っているインダクタが悪いです。

以上、供養でした。

## おわりに
今日はSANYOのニッケル水素電池専用充電器を分解、そして供養しました。昨日の続きだったからか左手の親指が痛かったような気がしないでもないですが、別に問題ありません。とにかくPX-280半田ごては本当に使いやすい半田ごてです。おそらく1度使ってしまうとアップグレード以外は体が許さないでしょう。もしくはアップグレードすら許さないかもしれません。それほど手に馴染みますし、重さもグリップの太さも良い感じです。おすすめなので、「俺はずっとこの半田ごてを使ってやるんだ！」とこだわりのある方、もしくはそうでなくても使ってみてください。

Amazonリンク
[太洋電機産業 半田ごて PX-280を購入する](https://www.amazon.co.jp/goot-温調はんだこて-設定温度200℃-500℃-1℃単位の調節-PX-280/dp/B09Q7R32BG)
Windows11にTerraformをインストールする

こんにちは。
株式会社クラスアクト インフラストラクチャ事業部の大塚です。

今回はWindows11 PCに対してTerraformを導入していきたいと思います。
IaC(Infrastructure as Code)の一種ですね。
AWSでいうとCloudFormation。GCPでいうとDeployment Managerに似て非なるもの的な奴です。（Azureは…すみませんわかりませんが、Azure Resource Managerですかね💦）


# 導入

以下のサイトにアクセスします。

https://developer.hashicorp.com/terraform/install

WindowsのAMD64の方をダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/719b9a31-7fbf-6240-52dc-b7c479eaade3.png)
ダウンロードしたものを解凍します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/d4fe383d-5f58-04f5-8533-008ab0109bde.png)
解答した中身は以下のようになっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/4c6b92f7-c607-8106-dbbe-66972f91bf4e.png)
私はDocument配下にTerraformというフォルダを作成し、そこにデータを移動しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/2a84db0a-f269-c30b-2313-ea342fdfeec9.png)
PATHを通す必要があるようなので通します。設定を開いてシステム>バージョン情報を選択。システムの詳細設定を押下します。
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/92ed1556-dcee-f4be-311f-6f1db4d817d2.png)
下にある環境変数を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/251befd9-e3ff-0d70-d97b-852a1eeadba7.png)
PATHをアクティブにして編集を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/3d35a17a-27ba-a768-f909-fd3413785c38.png)
追加してOKを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/caaf2cd6-1fcc-42c2-2970-fa9772b8f9d1.png)
CMDを開いてterraform -vとコマンドを入力・実行してバージョンが返ってくることを確認します。以上！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/b745dfe2-bd28-6698-c153-981e41b11f80.png)
コードが書けない高専卒エンジニア2年生がReactを勉強して真のエンジニアを目指す話

# 自己紹介
プログラミングを勉強して人生を楽しく生きたいと考えている art93 です！
記事をご覧になっていただきありがとうございます！
簡単に自己紹介をします。

+ 高専で制御情報工学を学習（マイコン制御や電子回路など）
+ 高専卒業後大手通信事業会社に入社して広島でIoTエンジニア2年生
+ 自作キーボードが趣味
+ 最近コペン（軽オープンカー）を買いました！

どうぞよろしくお願いいたします！

# 現在の状況
+ 通信事業会社にてIoTエンジニアをするも、ベンダーコントロールや公募対応など実際に自分で手を動かして開発する力が養われない
+ 大企業の地方部署あるある、高齢化が進みメンバーのIT意識が高くない環境

# 現在の悩み
#### 環境・心理面
+ 実際に手を動かしてモノを作れるスキルが無く、漠然と強い不安感がある
+ 専門スキルがあまり必要ない仕事をしているため、この先のスキルアップに不安
#### これまでのプログラミング学習経験の挫折
+ これまでプログラミングを勉強しようとしたが、努力するべき道筋がわからず挫折
+ やらないといけない焦燥感に駆られるが、やることがわからず立ち止まり負のループ
+ コードを書いているときや、アルゴリズムを考えているときは楽しい

# JISOUを通じて成し遂げたいこと
+ 実際に自分で手を動かしてモノを作れる自信
+ 新しいこと・過去挫折したことでも挑戦して成功につながる成功体験
+ 向上心のある環境への円満な移動
+ 場所・お金・時間の自由の獲得
    + 思い立ったときに行きたい場所へ飛んでいきたい
    + 「今どこにいるかまったくわかｒ」「」

なりたい自分になるための努力ができずずっとうずくまっている状態から脱却し、人生を楽しく生きることが自分の目標です！

# プログラミングを学習する際のマイルール
+ 朝起きて1分でもいいので行動する
    + マインドセットを聞く、本を読む、プログラミング　etc...
+ 社内異動するためにも本業も頑張る
    + 残業時間を少なくできるよう効率的に仕事する
+ 体調やメンタルを意識してその日の学習量を調整する
    + Notサボり、Yes自己調整
    + どこかでパンクして挫折してしまわないよう、今の段階から調整力をつける

# 今後の目標
+ 一ヶ月目標：Reactの基礎を学び、自分でアプリを作れるようになる
+ 三ヶ月目標：自分ならではの価値を付随したサービスを作れるようになる
+ 中期目標：サービスを作り続ける、誰かの悩みを解決する、ハッカソンで戦う
+ 年内目標：社内もしくは社外で実力をつけられる環境へ移動する
+ 2年目目標：実践経験を積み技術力・ビジネス力を磨く。自分の名前でお金を稼ぐ
+ 3年目目標：フリーランスになる

### コードが書けないエンジニア2年生の成長を記録していきます！
Microsoft 365 Developer Program の環境構築（失敗）

:::note alert
この記事は失敗談です。
試してもダメだった内容を共有して、
皆さまの「回り道」削減に貢献できれば幸いです。
:::

# 目的：自身のスキルアップ+社内365導入の素材確保
##### 下図のように考えました

```mermaid
graph TD;
    出発点-->仮想化の準備;
    仮想化の準備-->BIOS設定で有効化;
    BIOS設定で有効化-->Hyper-Vインストール;
    出発点-->Office365DevelopersProgram参画;
    Office365DevelopersProgram参画-->Adminアカウント発行;
    Adminアカウント発行-->サンドボックス環境;
    Hyper-Vインストール-->仮想アドミン;
    Hyper-Vインストール-->仮想サーバー;
    Hyper-Vインストール-->仮想ユーザー;
    サンドボックス環境-->仮想アドミン;
    サンドボックス環境-->仮想サーバー;
    サンドボックス環境-->仮想ユーザー;
    仮想アドミン-->成功;
    仮想サーバー-->成功;
    仮想ユーザー-->成功;
    仮想アドミン-->失敗;
    仮想サーバー-->失敗;
    仮想ユーザー-->失敗;
    成功-->導入を会社に提案できる;
    失敗-->会社に提案できないし検証もできない;
```
※仮想化の枝は別記事にまとめる予定

##### 1. アカウント作成
https://developer.microsoft.com/en-us/microsoft-365/dev-program
##### 2. サンドボックス環境の生成
「ダッシュボードに[Join]ボタンがある」らしい
が、見当たらない・・・おや？
"Don't current qualify" =「今は資格がない」そうだ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/803674/53a88048-e4ab-fbdb-7fec-53d3de8f64c8.png)
##### 2-2. 試しにトレーニングを進めてみる
・クラウドの概要
・Azure ID　ほか。
Lv4くらいまでXPを貯めてみたが、出てこない。

##### 3.原因分析
登録に自前の[~@gmail.com]を使ったのが悪かった？
「~@onmicrosoft.comが見つからない」問題
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/803674/27431f53-4c37-494f-d399-eaad83b58a55.png)
一旦Delete Profileしてみる方向を模索するも
「次の登録は60日経過しないとできませんよ？」の警告
->5分後でも再登録自体は問題ありませんでした
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/803674/ca6a1b01-0542-1a99-ed79-e899d5736563.png)
ブラウザのプライベートモード/ゲストモード/シークレットモードを
使うと手前のアカウントに引っ張られず円滑でした。
### 結局、サンドボックス生成ボタンにたどり着けず・・・
引き続き調査を進めてみますが、知見をお持ちで
ご教示いただける方がいらっしゃったら幸甚です。
【マネージャー向け】新人教育がうまくいかない方へ

https://speakerdeck.com/sioncojp/cheng-chang-wosahotosuruhihurumanesimentonoyarifang

社員の活躍に責任を持つ立場になり、現在マネジメントを再学習しています。
過去に学習したが忘れていたこと、新たな知見の備忘録です。
※約5分で読めると思います。

## 「君はどうしたい？」がなぜだめなのか

 新人はまず業務を覚えることにフォーカスしているので、具体的な指示や期待を求めていることが多いのです。

「君はどうしたい？」で意見を引き出すのなら、その意見を叶えられるように導くべきだと思います。

「君はどうしたい？」と聞くだけ聞いて放置しているといずれ

### 「言っても無駄」
<br>

こうなることでしょう。

子どもにアンケートを取るだけとって何もしなかった場合、次からのアンケートでは

### 「とくになし」（言っても無駄）
<br>

になります。子どもは正直です。

※注　「君はどうなりたい？」とは全く別物です。

https://news.yahoo.co.jp/expert/articles/90c930c89754fe065f42ae29974b1b4391936363

## 代理体験

代理体験とは、他人の成功を見聞きする体験のこと。
自分と似ている人の成功を見聞きすることで

### 「あの人ができたのだから自分もできそう」
<br>
と、疑似的達成感を持つことができます。

https://be-do.jp/efficacy-modeling/

代理体験は、自己効力感を持つための重要な要因の一つであると、経営学において明らかになっています。

高校時代にマクドナルドでアルバイトをしていた時、マネージャーがこんなことを言っていました。

### 「人に教えるコツは、やってみせる、やらせてみる、だよ！」
<br>

代理体験から成功体験へつなげる流れですね。

マクドナルドの教育ってやっぱりすごかったんだなぁと改めて実感しています。

## ロールモデル・ストレス

前述の代理体験には落とし穴があるように思えます。
それが「ロールモデル・ストレス」というものです。

https://note.com/iamwhatichose/n/n884e670b93e1

自己効力感の向上に有効な代理体験も

### 「あの人のようになれ」

この一言でゴーレム効果を生みます。

ゴーレム効果とは、期待されないと「自分はだめだ。」となる心理学的現象です。この逆がピグマリオン効果です。

自分と似たロールモデルを複数持たせることで、回避できるでしょう。

## 経験学習モデル

https://schoo.jp/biz/column/1162

経験学習モデルは、一言でいうと経験から学ぶ方法を解りやすく体系化してくれているものです。以下の4つのステップがあります。

1. 具体的経験
2. 内省
3. 概念化・抽象化
4. 能動的実験

エンジニアの業務に当てはめると

1. プロジェクトでまだやったことがない実装をする
2. PRレビューやレトロスペクティブ（スクラム）で振り返る
3. 他のプロジェクトや言語でも実装できるように抽象化する
4. 個人開発で実際に試してみる

開発現場ではやったことのない実装をすることはいくらでもあるので、この経験学習モデルは良い学習効果が発揮されると思います。



## まとめ

令和の時代になり、マネジメントが以前よりも難しくなったという話をよく耳にします。これは、終身雇用制度からジョブ型雇用への移行が背景にあると思います。エンジニアが一生学び続けるように、マネージャーも継続的な学習が必要なんだろうなと思いました。
MacOSのPCで全角英数字の入力方法

MacOSのPCで全角英数字の入力する機械があったので紹介です。


まずはシステム設定を開きます。
![スクリーンショット 2024-05-04 19.36.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/60acce15-a01c-e4dd-2a0d-0947af9ad04c.png)


キーボードを選択します。
テキスト入力の入力ソースの編集をクリックします。
![スクリーンショット 2024-05-04 19.36.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/755cb9be-12f1-ebc0-96b9-e3bbbdf8196e.png)

日本語をクリックして、入力モードの全角英字をチェックします。
![スクリーンショット 2024-05-04 19.36.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/22addcda-7a20-c037-1adc-d90dbd95a969.png)

入力変換すると、全角英字が追加されているので、入力することが出来ます。
[Angular]Signalのススメ

# ようやく今年の1/3が終わったわ
新人のみなさ～ん、入社して1ヶ月経ちましたが、立派なソルジャーになるための育成はちゃんとされていますか？
GWもGW(頑張ってWork)してる人たちお疲れ様です、代わりにいっぱい休んでおきますね!!

# そんなこんなでGW中なので手短にソースを
今回はAngular17ぐらいから出てきたSignalというのを使ってみたサンプル
```javascript:Signal使ってみたやつ
// importやclass宣言とかは省略

// id,label,isSelected(選択状態)をアイテムに持つからの配列を宣言
const hogeList = signal<{
  id: string;
  label: string;
  isSelected: boolean;
}[]>([]);

// 選択済みの情報だけを抽出するだけのcompute
const selectedList = compute(() => this.hogeList().filter(i=>i.isSelected));

// データを取得する関数
getData = () => {
  // API呼び出しとかでresには配列が返ってきてる想定
  const res: {
    id: string;
    label: string;
    isSelected: boolean;
  }[] = callAPI();
  
  // signalのデータを更新する時の書き方
  this.hogeList.update(() => [...res]);
}
```

NgRXのStoreとReducerを集約したような印象で、computeとかについてはSelectorみたいに元のSignalを編集したものが定義てきたりするので、割とコード量が減ってスッキリするね!
Raspberry Pi GPIO Quick Start

(自分メモ)
ラズパイのI/O操作サンプル。

# 環境
- Raspberry Pi 4
- Ubuntu 20.04
- Node.js 22


# Javascript Project準備

https://qiita.com/shokkaa/items/6f83b3a107006ccc598b

```sh
npm init -y
npm i node-web-gpio
```

# I/O操作
```js:main.js - サンプルコード
const { requestGPIOAccess } = require("node-web-gpio");
const { promisify } = require("util");
const sleep = promisify(setTimeout);

async function main() {
  const gpioAccess = await requestGPIOAccess();
  const port = gpioAccess.ports.get(26);

  await port.export("out");

  for (;;) {
    await port.write(1);
    await sleep(1000);
    await port.write(0);
    await sleep(1000);
  }
}

main()
```

# Build/Run
```
npm i
sudo node main.js
```

※[GPIO 26](https://pinout.xyz/pinout/pin37_gpio26/)は37番ピン


# 参考
- [ラズパイGPIOモジュール](https://www.npmjs.com/package/node-web-gpio)
【Laravel】Eloquentで更新をかけるとIllegal offset typeが発生する

# 発生した問題
以下でDBの更新、新規データ登録をしようとすると「Illegal offset type」が発生した。

``` php
public function updateSkillAction($datas,$skillId){
        for($i=0; $i< count($datas->action_index); $i++){
            if($datas->exist_action_flag[$i] === 1){ 
                SkillAction::where([
                    'skill_action_id'=>$datas->skill_id,
                    'action_index'=>$datas->action_index[$i]
                ])->update([
                    'skill_action_name' => "スキルアクション名",
                    'skill_action_discription' => "スキルアクション説明",
                    'skill_action_type' => $datas->action_type[$i],
                    'data_table' => $datas->data_table[$i],
                    'side' => $datas->side[$i],
                    'condition_lenght' => $datas->condition_lenght[$i],
                ]);
            }else{
                Log::debug(print_r($datas->condition_lenght, true));
                SkillAction::create([
                    'skill_action_id' => $skillId,
                    'action_index' => $datas->action_index[$i],
                    'skill_action_name' => 'スキルアクション名',
                    'skill_action_discription' => 'スキルアクション説明',
                    'skill_action_type' => $datas->action_type[$i],
                    'data_table' => $datas->data_table[$i],
                    'side' => $datas->side[$i],
                    'condition_lenght' => $datas->condition_lenght[$i],　←ここ
                ]);
            }
        }
    }
```

色々調べてみたが、「←」の箇所以外の「'action_index' => $datas->action_index[$i],」～「'condition_lenght' => $datas->condition_lenght[$i],」を削除してもエラーは変わらなかった。

Illegal offset type自体は、何かが配列型でプロパティの参照が上手くできない場合に発生するエラーとのこと。


# 原因
このコード自体には問題はなく、Model側に問題があった。

``` php
<?php

namespace App\Http\Model\BaseMaster;

use Illuminate\Database\Eloquent\Model;

class SkillAction extends Model
{
   //スキルに紐づくスキルアクション情報
   protected $table = 'skill_action_info';
   protected $primaryKey = ['skill_action_id','action_index'];
   
   protected $fillable= [
       //スキルアクションID
       'skill_action_id',
       'action_index',
       //スキルアクション名
       'skill_action_name',
       //スキルアクション説明
       'skill_action_discription',
       //スキルアクションタイプ
       'skill_action_type',
       //効果値計算式
       'data_table',
       //敵味方どちらか(T=味方、F=敵)
       'side' ,
       //条件判定時のアクション数
       'condition_lenght'
   ];
}
```

問題は「$primaryKey」の部分。
ここが複合キーやAutIncrementのカラムになっていると、今回のようなエラーが発生するらしかった。
以下をModelに追加することで、エラー無く更新処理ができるようになる。
AutoIncrementを無効にするオプション。

``` php
   public $incrementing = false;
```

調べるのにかなり時間をかけてしまったので、どの修正をしたらエラーが発生しだしたか切り分けられるようにこまめな動作確認は必要かも・・・。

# 参考
https://waterfalls.hatenablog.com/entry/2019/11/30/054401

https://readouble.com/laravel/5.8/ja/eloquent.html

以下に書いてある通り、AutIncrement想定で複数のキーを設定していたが、
PHP側で'skill_action_id','action_index'どちらも指定して、しかもskill_action_idとaction_indexは1対多なのがいけなかったと思われる。
> 自動増分ではない、もしくは整数値ではない主キーを使う場合、モデルにpublicの$incrementingプロパティを用意し、falseをセットしてください。

# 2024/6/1 追記複合キー利用で問題が発生したため単一キーに付け替える対応

https://qiita.com/mijinko88/items/d56a6203a3822b2772eb
AIで生成されたコードの品質は低い

AIコード生成への過信は禁物

## AIによるコード生成は朗報か
[What improves developer productivity at google? code quality](https://dl.acm.org/doi/10.1145/3540250.3558940)というESEC/FSE採択のGoogleの論文があります。Google社内で開発生産性を上げる施策を行なったもののうち最も有効だったのがコード品質を上げることだったというものです。

ここ数年GitHub CopilotなどAIコードアシスタントを使用している企業が増えてきていますが、GitClearというDiff Deltaという非公開のコード品質指標を開発している企業が[AIコードアシスタントの適用によりコード品質が下がったというホワイトペーパー](https://www.gitclear.com/coding_on_copilot_data_shows_ais_downward_pressure_on_code_quality)を発表しました。

ホワイトペーパー自体は非公開情報なのでメールを登録して読んでねという感じなのですが、周辺情報は公開されていたので調べたことをメモしておきます。

## Diff Deltaとは
GItClearはDiff Deltaという指標を作っている企業なのでまず彼らの主張を見てみます。

[彼らの研究によると](https://www.gitclear.com/blog/research_suggests_diff_delta_has_higher_correlation_with_software_effort_than_other_git_metrics)software effortというストーリーポイントベースの工数との相関において、変更行数、コミット数よりDiff Deltaのほうが良い指標でした。

* 変更行数: 25% (大きなリポジトリだと13-31%)
* コミット数: 27% (大きなリポジトリだと17-49%)
* 行への影響(= Diff Delta): 38% (大きなリポジトリだと: 26-61%)

![e0c54052-3f30-4624-9e1d-91625f499f74.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103496/6b78353a-79e5-4132-ded0-374e5b2662f5.png)

個人的には、コミット数だと人によってばらつきがあって変更行数より悪い指標だと思ったのですが、ならせばそうでもないみたいですね。Diff Deltaでも相関が38%なのでgit logだけをみて工数予測するのは難しいとも言えそうです。

## コードを削除するのは足すより大変
GitClearはDiff Deltaで商売しているので詳細の計算式は非公開のようですが、[公開されている部分もあります](https://www.gitclear.com/help/technical/diff_delta_calculation)。変更行数比でDiff Deltaは13ポイント良い指標なわけですが強さはどこにあるのでしょうか？

Diff Deltaでは変更の種類ごとにポイントを振っています。

* 追加: 最大10ポイント
* 削除: 最大25ポイント
* 移動: 0ポイント
* 更新: 最大10ポイント
* 一括置換: 3ポイント
* コピペ: 0ポイント
* 変更なし(フォーマットなど): 0ポイント

一括置換やコピペ、移動は頑張ったと認めず追加より削除するのが大変という仮定のようです。

他にも近傍の変更は楽、言語によるウェイト(CSSの変更はPythonより楽)などいくつか工夫されています。

## 企業ごとのDiff Deltaの目安
公式ページにいくつか[Diff Deltaのベンチマーク](https://www.gitclear.com/diff_delta_factors)がのっています。

* エンタープライズ企業のエンジニア: 70 DD/day
* Googleのエンジニア: 72 DD/day
* 中規模企業のエンジニア: 88 DD/day
* スタートアップのエンジニア: 97 DD/day
* Microsoftのエンジニア: 105 DD/day
* Facebookのエンジニア: 105 DD/day

[別のベンチマーク](https://www.gitclear.com/help/diff_delta_at_scale)によるとGoogleのTensorflowのエンジニアはとある一日に10行追加、20行削除、5行変更、5行コピペ、10行一括置換したそうです(50行/日)。変更行数 x 1.46 = 1デルタくらいでしょうか。

スタートアップのエンジニアのとある1日だと350行追加、200行削除、10行更新、300行移動(860行/日)です。変更行数 x 0.13 = 1デルタくらいでしょうか。churnが高いと低く出るみたいですね。

プログラマーが一日に書くコードの量は言語によらず一定という言説も聞いたことがありますが、Diff Deltaの良いコードで比較すると企業ごとのばらつきは思っているほどない印象。

## AIコードアシスタントが出てからはchurnが上がった
ようやく本題。

こういったDiff Deltaの変更行数を分解できる能力のバックグラウンドがある前提でホワイトペーパーではAIコードアシスタント登場前後で指標を比較しています。

Generative AIの名のとおりいうかコードの追加は増えて、逆に移動は減りました(詳細はホワイトペーパーをご確認ください)。コードチャーンも上がって(寿命が下がって)います。

ここら辺は今後改善される部分だと思いますが、現状AIコードアシスタントはコードの追加は得意でもリファクタリングは苦手と言えるかもしれないですね。スマートコピペで重複したコードを産むのは得意でもDRYで共通化は苦手というか。

## 所感
GitHubによるとCopilotの適用によって55%速くタスクが解消されるとのことです。大きなアドバンテージですね。

一方で[以前読んだMicrosoft Researchの論文](https://zenn.dev/hiromichinomata/articles/aec792087c440b)だとCode Churnはバグ発生を予測する指標としてかなり精度の高い指標でした。

**ソフトウェアは作るよりメンテナンスするのが大変**と言う言説も聞いたことがあるのですが、例えば納品して終わりの受託の開発のようなものだとAIコード生成の旨みが現状大きく、継続して改善していくような保守フェーズのコードほどどちらかというと向いていないのかもしれません。
S3削除マーカーレプリケーションのデフォルト値の違い（ｖ１とｖ２）

# はじめに
削除マーカーレプリケーションの記事を先日書いたのですが、S3のレプリケーションにはV1とV2の２つの設定があり、動作がことなります。今回はその違いを書いていきます。


# 削除マーカーレプリケーションの動作の違い
・V1設定の場合：削除マーカーはレプリケートされます。
・V2設定の場合：削除マーカーはレプリケートされません。

# 削除マーカーレプリケーションってそもそもなんやねん？
以下記事を見てほしいのですが、レプリケーション元で削除した操作を、レプリケーと先に反映するかのパラメータとなります。レプリケーションを有効化するには、S3のバージョニングを有効化する必要があり、バージョニングが有効化されたバケットでは削除を実施すると該当バージョンのオブジェクトに削除マーカーという削除を意味するマーカーが付与されます。削除マーカーが付与されたオブジェクトにGETリクエストを投げても、明確にバージョンを指定しない限りオブジェクトが取得されることはありません。

https://qiita.com/Regryp/items/f74233e75c99eb6d8822

# V１とV2の切り替え方法
明確にV1、V2という切り替えパラメータがあるわけではありません。
S3のレプリケーション設定時にPrefixというパラメータを指定するか指定しないかで、切り替わります。
Prefixは特定のパスのみレプリケーションするというパラメータです。このパラメータを明示的に指定（空指定も可）するとV1設定となり、削除マーカーレプリケーションも有効化されます。Prefixを指定しない場合はV2となり、削除マーカーレプリケーションは無効となり有効化することはできなくなります。

https://aws.amazon.com/jp/blogs/news/managing-delete-marker-replication-in-amazon-s3/

# まとめ
S3のレプリケーションにはV1、V2があります。V1では削除マーカーレプリケーションが可能ですが、V2では実施できません。その他タグベースのフィルタやReplicationTimeControlなどの機能はV1では実施できません。このように、相互に互換性のない機能が実装されているため、V1、V2がそれぞれ存在している状態と推定されます。レプリケーション設定時には実施したい内容を精査したうえで、V1、V2を適切に設定していきましょう。
[Leet Code] 01 Two Sum

今日から1日1Leet Code!
記念すべき1回目！気が向いたら投稿する！

1. [Two Sum]("https://leetcode.com/problems/two-sum/description/")
**int型配列と整数が渡され、配列の要素のうち和が与えられた整数になる2要素を求める問題**
2回ループを回すことで無事に解けた




``` TwoSum.js
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(nums, target) {
    const ans_array = [];
    const leng = nums.length;
    for(let i = 0; i<leng; i++){
            for(let j=i+1; j<leng; j++){
                if(nums[i] + nums[j] === target){
                    ans_array.push(i);
                    ans_array.push(j);
                    return ans_array;
                }
            }       
    }
};
```
**改善点**
2回ループを回しているため計算量が大きい
→ハッシュマップを使ってループを1回に

ハッシュマップとは...
キーと値の組み合わせで要素を管理する
配列は番号で管理する

[参照]("https://youtu.be/MlgFhWvxuJk?si=sjvygzapzQdMBPH1")

```afterTwoSum.js
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(nums, target) {
    const pairIdx = {};

    for(let i = 0; i<nums.length; i++){
        const num = nums[i]; //今見てるnum
        if(target - num in pairIdx){
            return [i, pairIdx[target - num]];
        }
        pairIdx[num] = i;

    }
    
};
```
1.3inch LCD HAT設定

# 趣旨
SeedSigner用に買ったツールでRetroPieを起動できるのに気づいたので、ハードウェアのドライバを探し出して必要なライブラリを全部インストールして動くようにしました。

忘れたら悲しくなるのでそうならないように記録に残します。

公式ページ

https://www.waveshare.com/wiki/1.3inch_LCD_HAT

バージョンの関係か公式ページの通りにやると必ずエラーになったので、既に同じツールで成功された方の公開動画も参考にしました。

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


以下コマンドです。
```
wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.71.tar.gz
tar zxvf bcm2835-1.71.tar.gz 
cd bcm2835-1.71/
sudo ./configure && sudo make && sudo make check && sudo make install
```
```
sudo apt-get update
sudo apt-get install python-pip
```
```
sudo pip install RPi.GPIO
sudo pip install spidev
sudo apt-get install p7zip-full -y
wget https://files.waveshare.com/upload/b/bd/1.3inch_LCD_HAT_code.7z
7z x 1.3inch_LCD_HAT_code.7z -r -o./1.3inch_LCD_HAT_code
sudo chmod 777 -R 1.3inch_LCD_HAT_code
cd 1.3inch_LCD_HAT_code
```
```
cd c
make clean
make
sudo ./main
```
```
sudo nano /boot/config.txt
gpio=6,19,5,26,13,21,20,16=pu
```
```
sudo nano /etc/dphys-swapfile  
```
CONF_SWAPSIZE and change its value to a higher number. If it's set to 100, for example, change it to 1024 
```
sudo /etc/init.d/dphys-swapfile stop
sudo /etc/init.d/dphys-swapfile start
```

```
sudo apt-get update
sudo apt-get upgrade  sudo apt-get install libatlas-base-dev
sudo apt-get install python-numpy
sudo apt-get install python-gpiozero
sudo apt-get install python-pil
```
```
cd python
sudo python main.py
sudo python key_demo.py
```

```
cd ~
sudo apt-get install cmake -y
wget https://www.waveshare.net/w/upload/2/2d/Fbcp-ili9341.7z
sudo apt-get install p7zip-full -y
7z x Fbcp-ili9341.7z
cd Fbcp-ili9341/
mkdir build
cd build
cmake -DSPI_BUS_CLOCK_DIVISOR=20 -DWAVESHARE_ST7789VW_HAT=ON -DBACKLIGHT_CONTROL=ON —DDMA _TX_CHANNEL=5 -DDMX_RX_CHANNEL=6 -DBACKLIGHT_CONTROLON DSTATISTICS=0 ..
make -j
sudo ./fbcp-ili9341 
```

```
sudo cp /home/pi/Fbcp-ili9341/build/fbcp-ili9341 /usr/local/bin/fbcp
sudo nano /etc/rc.local
```
fbcp& <- before exit

```
sudo nano /boot/config.txt
```
↓ at the end
```
hdmi_force_hotplug=1
hdmi_cvt=300 300 60 1 0 0 0
hdmi_group=2
hdmi_mode=87
display_rotate=0
```
```
sudo reboot
```
RetroPieのセットアップ備忘録：OS編（つまづいた箇所のみ記載）

## Raspberry Pi Imager
ラズパイ公式サイトでダウンロードできるが、RetroPieを選択した場合WiFiを事前設定できない

イメージを書き込んだ後にSDカードの/にwifiのconfを置くと、読み込まれる場所が決まっているのでWiFiが繋がるようになる

```wpa_supplicant.conf
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
        ssid="xxx"
        psk="xxx"
}
```
:::note info
"が”だと失敗するのでコピペした方がよい
:::

## Controller Configurationイベント
初回起動ですぐにController Configurationイベントが発生するので無闇にボタン連打せずに待っておくこと

しっかり読んでからボタンを押せば無駄な作業がなくて良い

一度つまづいてやり直したり再設定することになったので、ここは本当に時間をかけてゆっくり解説を読んでから臨んだ方がよい

やり直す方法忘れた
Resetなんとかだった気が

## SSH接続
ファイルの送信やコマンドを利用する際にSSHできれば便利

Raspberry Pi Imagerだと事前設定できないのでconf-raspiでSSHを許可する

デフォルトのアカウント情報
```
username: pi
password: raspberry
```

自宅のWiFiのみの利用でルーターがセキュリティ高めのもので常時ONでないのならデフォルトのままでも良いかな

デフォルトアカウント情報を変更するためのコマンドは以下
```bash
# add a new user
sudo adduser newusername

# delete a user named pi
sudo deluser pi

# change password for a user named username
sudo passwd username

# check about oldusername and change it to newusername and reflect file names for newusername
sudo pgrep -u oldusername
sudo usermod -l newusername oldusername
sudo usermod -d /home/newusername -m newusername
sudo chown -R newusername:newusername /home/newusername
```

WiFiとSSHができるなら、もうSDカードの抜き差しはいらない


## RETROPIE SETUP
パッケージは全部アップデートする
Update all installed packages

時間かかるし、たまにYES押す必要がある

## RomCollection
GithubにROMの塊がおいてあったが、著作権侵害していないかなど確認していない

https://github.com/Shugabuga/RomCollection

実際にRetroPieを利用するなら自分でROM抽出するか、著作権フリーのROMを見つけるか、自分でゲームを作ることを推奨

ROMなどのファイルをSDカードに保存したい時は、SDカードを抜き差ししても問題はないが、SambaやSCPを使ってもよい

Sambaは大量のデータを勝手に同期する仕組みで、SCPは多分SSHの延長技術で異なるPC間をSSH接続と同じ仕組みでファイル転送している？と思う
```bash
scp FILENAME pi@host:~/RetroPie/roms/
```

## 役にたつコマンド
コントローラーのボタン数が少ないと全てのキーを割り当てられず混乱して電源の落とし方すらわからない状態が続いたので、SSH接続でPC側からRetroPieをRebootするコマンドとゲームを離脱するコマンドを残しておく

```bash
sudo reboot
sudo shutdown
emulationstation # gameから離脱
```
## Hotkey操作
ゲームプレイ時にセーブをどうすればよいかわからなかったのでRetroPie公式サイトから必要箇所だけを抜粋

https://retropie.org.uk/docs/Controller-Configuration/#hotkey

```
Combination	          Action
-----------------------------------------------
Hotkey+Start          Exit
Hotkey+RightShoulder  Save
Hotkey+LeftShoulder	  Load
Hotkey+Right	      Input State Slot Increase
Hotkey+Left	          Input State Slot Decrease
Hotkey+X	          RGUI Menu
Hotkey+B	          Reset
```

## 感想
実際に動かしてみることで、RetroPieの仕組みが仮想環境を作るソフトにかなり似ていると感じた

以下、イメージ
```
RetroPie = VirtualBox
Emulator = Virtual OS
ROM = Application
BIOS = Driver
```

- BIOSやDriverを自作するのはあまり賢い選択ではない
- ROMを自作するのはプログラムの勉強になりそう
- ソフトウェアの方がハードウェア絡みのプログラムより簡単
- AIもハードウェアに関しては精度が低い
- 完全オリジナルを目指すと3Dプリンター業者を見つける必要も出る