OmniAICreator/Qiita-1.07M huggingface dataset:
造波装置 with JLC3DP #1

洋上風力発電機の研究として波を造る装置(**造波装置**)を作りたくなったので3Dプリンターで作ってみます。残念ながら3Dプリンターを持っていないので、昨今話題のJLC3DPに協力を依頼しました。
# 1. JLC3DPで発注してみよう
### JLCPCBへ会員登録
[会員登録はこちら→](https://jlcpcb.com/JPV)
新規ユーザー$60無料クーポンを提供とのことです。

# 2. 発注
1. 右上の**発注する**をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580381/80e8be6b-4fab-a4b8-111d-fe72130a0d55.png)
2. 発注したい種類をクリック(今回は3Dプリントをしたいので"3D Printing/CNC")
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580381/bc4eea09-b389-f1d8-c202-51d6608a2029.png)
3. **3Dファイルを追加**からstl等をアップロード
4. 印刷方法・素材を選択(今回は"9600Resin"を選択) 
商品概要も忘れずに。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580381/07938621-7121-7f47-9021-cd12fce25297.png)
5. カート,注文から住所・配送方法を選択して注文
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580381/0d6b316b-dfcd-da5e-c0f2-089376622acc.png)

注文後は3Dファイルの審査が入り、うまく印刷できるかどうかを判定してくれます。
↓例↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580381/3031e137-485a-621a-4e9e-dbb19f84ede9.png)

# 3. 発注したもの
Fusion360でモデリングした3Dデータはこちらです。
![3Dデータ画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580381/d95a35f8-5289-efd5-2815-4377c67ec756.png)
二重ギア(正式名称不明)を4つ重ねてトルクを出すようにしてみました。
回転運動から上下運動に変えるところはスコッチヨーク機構なるものを使ってみました。
(参考:http://karakurist.jp/?p=680)
T字の下のところに水かきを設置して上下に揺らして波を作る算段です。
(合計7パーツ分)

# 4.到着
注文してから3日でデータチェックから印刷まで完了し、そこから3日で届きました。めちゃくちゃ早いです。国際郵便だから1か月くらいかかるもんだと思ってた...。
印刷されたデータはこちらです。
![S__8658963_0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580381/04291d60-5028-9979-425a-788300328bed.jpeg)
正直、品質が高すぎて驚いています。
モデリングするときに寸法をぴったりにしてしまったので削らないとはまらないかなとか思っていたのにめっちゃきれいにはまってくれました。
<img width="200" alt="印刷データ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580381/111dbfdc-887d-da31-5882-f52278c91e87.jpeg">
こんな感じで使います↓
![S__8658966.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580381/ffcfa1d6-4ba7-d06c-e012-702637908524.jpeg)
歯車パーツは次回の記事で出します。

# 5.スポンサー紹介
<img width="400" alt="JLCPCBロゴ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580381/230af0e8-e1e1-f77b-8475-9e847468158f.png">

今回は造波装置の印刷をJLCPCB(3DP)さんに協力していただきました!
大きな部品を高い精度で、なおかつ格安で印刷できるので是非皆さんも使ってみてください!!
[英語発注システム → https://jlcpcb.com/JPV](https://jlcpcb.com/JPV)
[日本語発注システム → https://jlcpcb.com/jp](https://jlcpcb.com/jp)

### 次回

https://qiita.com/kanhina1217/items/9aa3e981271738f1086f
paizaラーニング問題集「部分和問題 2」を解いてみた（処理の流れの解説あり）

https://paiza.jp/works/mondai/dp_primer/dp_primer_partial_sums_step1

▼考え方

ポイントとなると思った考え方を、以下1.～4.に示します。
これらを踏まえて処理した結果、dp[x(=10)]に入力された数が、
重さの和が10となるようにする方法の数です。

1.　入力xが10かつ、10に対して減算を行う↓
　　(演算のたびにリストの添え字に合わせるため-1するのは面倒なので)
　　dp = [0]*(11)を用意します。

2.　おもりiの重さの値a_iと同じdpの添え字に、1を入力します。
　　例：a_0が7なので、dp[7]←1

3.　a_iとa_i以外を加算した結果と同じdpの添え字に、1を入力します。
　　(ただしx(=10)を超えない範囲)
　　例：a_1が3なので、dp[3(=a_1)]←1、dp[10(=a_0+a_1)]←1

4.　a_iとa_i以外を加算した結果が、複数パターンある場合は、
　　それをdpの添え字で表現する。
　　例：a_0が7なので、まずdp[7]←1となる。
　　　　次に、a_1が3でa_2が4なのでこれもdp[7(=a_1+a_2)]←1となる。
　　　　よってdp[7]←2(=1+1)とする。

▼コード
```py
########## 処理0(準備) インプット,リスト定義など ###########

n,x = map(int,input().split())
a = [0]*n

########## 処理1 漸化式の定義、計算、出力 ##########

# 考え方1参照
dp = [0]*(x+1)
dp[0] = 1

for i in range(n):
    a[i] = int(input())

# 考え方2,3,4参照
for i in range(1,n+1):
    for j in range(x,a[i-1]-1,-1):
        if dp[j-a[i-1]] >= 1:
            dp[j] += dp[j-a[i-1]]

print(dp[x] % 1000000007)
```
▼処理の流れの解説
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881331/8a87b7fe-45e9-c2ba-c153-86060a85ad77.png)
paiza.ioでmysql その16

# 概要
paiza.ioでmysqlやってみた。
練習問題やってみた。

# 練習問題
SELECTを使え。

# サンプルコード

```
create table users (
    id int(11) auto_increment,
    last_name varchar(255),
    first_name varchar(255),
    age int(11),
    PRIMARY KEY (id)
);

insert into users
values
(1,    'Yamada',   'Ichirou',    20),
(2,    'Yamada',   'Jirou',      19),
(3,    'Yamada',   'Saburou',    15),
(4,    'Yamada',   'Shirou',     13),
(5,    'Satou',    'Ichirou',    22),
(6,    'Satou',    'Jirou',      20),
(7,    'Satou',    'Saburou',    19),
(8,    'Satou',    'Shirou',     17);

select * from users;

select * from (select * from users where last_name = 'Yamada') as users;




```

# 実行結果

```
id	last_name	first_name	age
1	Yamada	Ichirou	20
2	Yamada	Jirou	19
3	Yamada	Saburou	15
4	Yamada	Shirou	13
5	Satou	Ichirou	22
6	Satou	Jirou	20
7	Satou	Saburou	19
8	Satou	Shirou	17
id	last_name	first_name	age
1	Yamada	Ichirou	20
2	Yamada	Jirou	19
3	Yamada	Saburou	15
4	Yamada	Shirou	13
```

# 成果物

https://paiza.io/projects/VZsFVUS3_SUaRM9CGxlLhA


以上。
paiza.ioでmysql その15

# 概要
paiza.ioでmysqlやってみた。
練習問題やってみた。

# 練習問題
CASEを使え。

# サンプルコード

```

CREATE TABLE `shohinStock` (
  `id` int NOT NULL,
  `type` int NOT NULL comment '1: 商品A, 2: 商品B',
  `stockNum` int default 0,
  PRIMARY KEY(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO shohinStock VALUES(1, 1, 100);
INSERT INTO shohinStock VALUES(2, 1, 200);
INSERT INTO shohinStock VALUES(3, 2, 150);
INSERT INTO shohinStock VALUES(4, 1, 200);
INSERT INTO shohinStock VALUES(5, 2, 300);
INSERT INTO shohinStock VALUES(6, 1, 100);
INSERT INTO shohinStock VALUES(7, 1, 200);
INSERT INTO shohinStock VALUES(8, 2, 200);
INSERT INTO shohinStock VALUES(9, 1, 50);

SELECT 
  CASE WHEN type = 1 THEN '商品A' WHEN type = 2 THEN '商品B' ELSE 0 END AS '商品分類',
  SUM(stockNum) AS '在庫総数'
FROM
  shohinStock
WHERE
  type = 1;
  
SELECT 
  CASE WHEN type = 1 THEN '商品A' WHEN type = 2 THEN '商品B' ELSE 0 END AS '商品分類',
  SUM(stockNum) AS '在庫総数'
FROM
  shohinStock
WHERE
  type = 2;

SELECT 
  SUM(CASE WHEN type = 1 THEN stockNum ELSE 0 END) AS '商品A:在庫総数',
  SUM(CASE WHEN type = 2 THEN stockNum ELSE 0 END) AS '商品B:在庫総数'
FROM
  shohinStock;



```

# 実行結果

```
商品分類	在庫総数
商品A	850
商品分類	在庫総数
商品B	650
商品A:在庫総数	商品B:在庫総数
850	650
```

# 成果物

https://paiza.io/projects/O2gZ-uPQaoHCPTtwuBOzYw

以上。
paiza.ioでmysql その14

# 概要
paiza.ioでmysqlやってみた。
練習問題やってみた。

# 練習問題
AVGを使え。

# サンプルコード

```


CREATE TABLE student (
  id INT NOT NULL,
  name VARCHAR(50) NOT NULL,
  height INT NOT NULL,
  weight INT NOT NULL,
  sex VARCHAR(10) NOT NULL
);

insert into student values(1, '秋山',   158, 52, '男');
insert into student values(2, '井上',   142, 38, '女');
insert into student values(3, '上田',   165, 60, '男');
insert into student values(4, '江口',   150, 38, '女');
insert into student values(5, '小野寺', 178, 70, '男');
insert into student values(6, '加藤',   160, 45, '女');
insert into student values(7, '君島',   151, 48, '男');


select *
from student;


select id,name
from student;


insert into student values(8, '黒田', 140, 32, '女');

select * from student;


delete from student
where id= 7;

select * from student;


update student
set id = 7
where name ='黒田';


select name, height
from student order by height desc;


select name, height
from student order by height desc limit 3;


select sum(weight) as '合計体重'
from student;


select avg(height) as '平均身長', avg(weight) as '平均体重'
from student;


select name
from student where name like '%上%'






```

# 実行結果

```
id	name	height	weight	sex
1	秋山	158	52	男
2	井上	142	38	女
3	上田	165	60	男
4	江口	150	38	女
5	小野寺	178	70	男
6	加藤	160	45	女
7	君島	151	48	男
id	name
1	秋山
2	井上
3	上田
4	江口
5	小野寺
6	加藤
7	君島
id	name	height	weight	sex
1	秋山	158	52	男
2	井上	142	38	女
3	上田	165	60	男
4	江口	150	38	女
5	小野寺	178	70	男
6	加藤	160	45	女
7	君島	151	48	男
8	黒田	140	32	女
id	name	height	weight	sex
1	秋山	158	52	男
2	井上	142	38	女
3	上田	165	60	男
4	江口	150	38	女
5	小野寺	178	70	男
6	加藤	160	45	女
8	黒田	140	32	女
name	height
小野寺	178
上田	165
加藤	160
秋山	158
江口	150
井上	142
黒田	140
name	height
小野寺	178
上田	165
加藤	160
合計体重
335
平均身長	平均体重
156.1429	47.8571
name
井上
上田
```

# 成果物

https://paiza.io/projects/lN9fTeVu6dMyv-4zrdUtEA

以上。
paiza.ioでmysql その13

# 概要
paiza.ioでmysqlやってみた。
練習問題やってみた。

# 練習問題
JOINを使え。

# サンプルコード

```


CREATE TABLE `purchase` (
  `date` DATE NOT NULL,
  `product` VARCHAR(255) NOT NULL,
  `price` INT NOT NULL,
  `cs_id` VARCHAR(10) NOT NULL
);

CREATE TABLE `customer` (
  `id` VARCHAR(10) PRIMARY KEY,
  `name` VARCHAR(50) NOT NULL,
  `age` INT NOT NULL,
  `sex` VARCHAR(10) NOT NULL
);

INSERT INTO purchase (`date`, `product`, `price`, `cs_id`) VALUES
  ('2024-04-01', '雑誌', 100, 'c0001'),
  ('2024-04-01', '文庫本', 200, 'c0001'),
  ('2024-04-02', '雑誌', 100, 'c0002'),
  ('2024-04-03', 'マンガ', 300, 'c0002'),
  ('2024-04-03', '文庫本', 200, 'c0003');
  

INSERT INTO `customer` (`id`, `name`, `age`, `sex`)
VALUES
  ('c0001', 'Bob', 26, 'male'),
  ('c0002', 'Jany', 32, 'female'),
  ('c0003', 'Anna', 24, 'female');
  
SELECT * FROM purchase;
SELECT * FROM customer;


SELECT product, COUNT(price) AS count_sales FROM purchase GROUP BY product;
SELECT product, AVG(price) AS avg_sales FROM purchase GROUP BY product;
SELECT product, MAX(price) AS max_sales FROM purchase GROUP BY product;
SELECT product, MIN(price) AS min_sales FROM purchase GROUP BY product;



INSERT INTO purchase (`date`, `product`, `price`, `cs_id`) 
VALUES
  ('2024-04-04', '参考書', 150, 'c0004');
  

INSERT INTO `customer` (`id`, `name`, `age`, `sex`)
VALUES
  ('c0005', 'Wein', 35, 'male');
  
  
  
SELECT date, product, name FROM purchase LEFT JOIN customer ON cs_id = id;
SELECT date, product, name FROM purchase RIGHT JOIN customer ON cs_id = id;
SELECT date, product, name FROM purchase INNER JOIN customer ON cs_id = id;




```

# 実行結果

```
date	product	price	cs_id
2024-04-01	雑誌	100	c0001
2024-04-01	文庫本	200	c0001
2024-04-02	雑誌	100	c0002
2024-04-03	マンガ	300	c0002
2024-04-03	文庫本	200	c0003
id	name	age	sex
c0001	Bob	26	male
c0002	Jany	32	female
c0003	Anna	24	female
product	count_sales
雑誌	2
文庫本	2
マンガ	1
product	avg_sales
雑誌	100.0000
文庫本	200.0000
マンガ	300.0000
product	max_sales
雑誌	100
文庫本	200
マンガ	300
product	min_sales
雑誌	100
文庫本	200
マンガ	300
date	product	name
2024-04-01	雑誌	Bob
2024-04-01	文庫本	Bob
2024-04-02	雑誌	Jany
2024-04-03	マンガ	Jany
2024-04-03	文庫本	Anna
2024-04-04	参考書	NULL
date	product	name
2024-04-01	文庫本	Bob
2024-04-01	雑誌	Bob
2024-04-03	マンガ	Jany
2024-04-02	雑誌	Jany
2024-04-03	文庫本	Anna
NULL	NULL	Wein
date	product	name
2024-04-01	雑誌	Bob
2024-04-01	文庫本	Bob
2024-04-02	雑誌	Jany
2024-04-03	マンガ	Jany
2024-04-03	文庫本	Anna
```

# 成果物

https://paiza.io/projects/uK2mpKyE98AecxGuDONdEw


以上。
paiza.ioでmysql その12

# 概要
paiza.ioでmysqlやってみた。
練習問題やってみた。

# 練習問題
JOINを使え。

# サンプルコード

```

CREATE TABLE users (
    user_id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL
);

INSERT INTO users (username, email)
VALUES
    ('John Doe',    'john@example.com'),
    ('Jane Smith',  'jane@example.com'),
    ('Bob Johnson', 'bob@example.com');

select * from users;

CREATE TABLE posts (
    post_id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT,
    title VARCHAR(100) NOT NULL,
    content TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(user_id)
);

INSERT INTO posts (user_id, title, content, created_at)
VALUES
    (1, 'First Post',  'This is John\'s first post.', '2023-01-01 12:00:00'),
    (1, 'Second Post', 'Another post by John.',       '2023-02-15 10:30:00'),
    (2, 'Hello World', 'Jane says hello!',            '2023-03-20 08:45:00'),
    (3, 'MySQL Tips',  'Bob shares some MySQL tips.', '2023-04-10 15:20:00'),
    (3, 'New Project', 'Bob starts a new project.',   '2023-05-05 11:00:00');


select * from posts;

SELECT users.*, posts.*
FROM users
JOIN (
    SELECT user_id, MAX(post_id) as max_id
    FROM posts
    GROUP BY user_id
) max_posts ON users.user_id = max_posts.user_id
JOIN posts ON  max_posts.max_id = posts.post_id;





```

# 実行結果

```
user_id	username	email
1	John Doe	john@example.com
2	Jane Smith	jane@example.com
3	Bob Johnson	bob@example.com
post_id	user_id	title	content	created_at
1	1	First Post	This is John's first post.	2023-01-01 12:00:00
2	1	Second Post	Another post by John.	2023-02-15 10:30:00
3	2	Hello World	Jane says hello!	2023-03-20 08:45:00
4	3	MySQL Tips	Bob shares some MySQL tips.	2023-04-10 15:20:00
5	3	New Project	Bob starts a new project.	2023-05-05 11:00:00
user_id	username	email	post_id	user_id	title	content	created_at
1	John Doe	john@example.com	2	1	Second Post	Another post by John.	2023-02-15 10:30:00
2	Jane Smith	jane@example.com	3	2	Hello World	Jane says hello!	2023-03-20 08:45:00
3	Bob Johnson	bob@example.com	5	3	New Project	Bob starts a new project.	2023-05-05 11:00:00
```

# 成果物

https://paiza.io/projects/dBOc7gqiMTxLt6pCOQUukA

以上。
paizaラーニング問題集「部分和問題 1」を解いてみた（処理の流れの解説あり）

https://paiza.jp/works/mondai/dp_primer/dp_primer_partial_sums_step0

▼考え方

ポイントとなると思った考え方を、以下1.～3.に示します。
これらを踏まえて処理した結果、dp[x(=19)]に1が入力された場合、
yesとなります。

1.　入力xが19かつ、19に対して減算を行う↓
　　(演算のたびにリストの添え字に合わせるため-1するのは面倒なので)
　　dp = [0]*(20)を用意します。

2.　おもりiの重さの値a_iと同じdpの添え字に、1を入力します。
　　例：a_0が7なので、dp[7]←1

3.　a_iとa_i以外を加算した結果と同じdpの添え字に、1を入力します。
　　(ただしx(=19)を超えない範囲)
　　例：a_0が7(dp[7]==1)、a_1が18(dp[18]==1)の状態で
  　　　　a_2が5なので、dp[12(=a_0+a_2)]←1

▼コード
```py
########## 処理0(準備) インプット,リスト定義など ###########

n,x = map(int,input().split())
a = [0]*n

########## 処理1 漸化式の定義、計算、出力 ##########

# 考え方1参照
dp = [0]*(x+1)
dp[0] = 1

for i in range(n):
    a[i] = int(input())

# 考え方2,3参照
for i in range(1,n+1):
    for j in range(x,a[i-1]-1,-1):
        if dp[j-a[i-1]] == 1:
            dp[j] = 1

if dp[x] == 1:
    print("yes")
else:
    print("no")
```

▼処理の流れの解説

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881331/e9dbae1e-227e-c1c3-a87d-afd4ff1ef1eb.png)
【目次】センチュリー・システムズMAシリーズでIoT

[(MA-X320/LAD)DIを検知してプログラムを起動する 2024/10/03](https://qiita.com/takami_embomajp/items/554bab785651f564f9b6)
[(IoT共通)NAT配下のMA(Linux)に外部からアクセスする 2024/10/09](https://qiita.com/takami_embomajp/items/6a1c9903863af61eb9a5)
[<font color=red>(IoT共通)ネットワークカメラをRTSP受信し、動体検知トリガーで動画を残す 2024/10/17 NEW</font>](https://qiita.com/takami_embomajp/items/62d4809f5aae8641f623)

(近日公開)(MA共通)内蔵eMMCから起動する=rootfsを8GBにする 
(近日公開)(MA-X3xx)SLCタイプSDカードから起動する=rootfsを8GBにする
(近日公開)(IoT共通)SMTP認証(OAuth,SMTPS)でメール送信するpython関数
【MariaDB】WITH RECURSIVE にて Data too long for column でエラーになる場合の対処方法

## はじめに
`WITH RECURSIVE` を使用した際に `Data too long for column` というエラーが出てしまい、SQLを実行できない現象が起きた。
この記事ではそのエラーへの対処方法をまとめる。

環境はMariaDBを使うが、参考にした資料はMySQLのリファレンスであるため、MySQLでも同等の対処方法で解決できると思われる。

## この記事の対象者
- 再帰的なCTEで`Data too long for column`が出たときの対処方法を知りたい人

## 検証環境
```
MariaDB [sample]> select version();
+------------------------+
| version()              |
+------------------------+
| 11.4.2-MariaDB-ubu2404 |
+------------------------+
```

## 現象
適当なテストデータを作ろうと思い、`WITH RECURSIVE` を使った以下のSQLを実行したが、想定した結果とは異なり、`Data too long for column` のエラーが起きてしまった。

### 実行したSQL
```sql
with recursive cte (n, name) as (
  select 1, concat('p', 1)
  union all
  select n+1, concat('p', n+1)
  from cte 
  where n < 10 
)
select n, name from cte;
```

### 想定した結果
```
+----+------+
|  n | name |
+----+------+
|  1 | p1   |
|  2 | p2   |
|  3 | p3   |
|  4 | p4   |
|  5 | p5   |
|  6 | p6   |
|  7 | p7   |
|  8 | p8   |
|  9 | p9   |
| 10 | p10  |
+----+------+
```

### 実際の結果
```
ERROR 1406 (22001): Data too long for column 'name' at row 10
```

## なぜこのようなことになるのか

`WITH RECURSIVE` は非再帰的な部分と再帰的な部分に分けることができる。

```sql
with recursive cte (n, name) as (
  -- ここは非再帰的な部分
  select 1, concat('p', 1)
  union all
  -- ここは再帰的な部分
  select n+1, concat('p', n+1)
  from cte 
  where n < 10 
)
select n, name from cte;
```

重要なのが **`WITH RECURSIVE` の結果のカラムの型は非再帰的な部分の結果から推測される**仕様となっていることだ。

そのため、`concat('p', 1)` は**2文字分の文字列型**とみなされる。
（この文字列の型が`CHAR`なのか`VARCHAR`なのかといった、具体的にどの型になるのかはリファレンスから見つけられず分からなかった。）

そして、再帰していくと、n = 9 のときに `concat('p', 10)` で3文字となってしまい、 `Data too long for column` が起きる。

つまり、再帰中に**非再帰的な部分の文字列の長さよりも、文字列が長くなる**とエラーが起きてしまう。

## 対処方法
非再帰的な部分で`cast`を使って文字列の幅を広げる。
今回のクエリでは3文字入れば問題ないため、以下のようなSQLに変更すればエラーは出なくなる。

### 修正後のSQL

```sql
with recursive cte (n, name) as (
  select 1, cast(concat('p', 1) as char(3)) -- 非再帰的な部分でcastを使って文字列の幅を広げる
  union all
  select n+1, concat('p', n+1)
  from cte 
  where n < 10 
)
select n, name from cte;
```

### 実行結果
```
+------+------+
| n    | name |
+------+------+
|    1 | p1   |
|    2 | p2   |
|    3 | p3   |
|    4 | p4   |
|    5 | p5   |
|    6 | p6   |
|    7 | p7   |
|    8 | p8   |
|    9 | p9   |
|   10 | p10  |
+------+------+
```

## まとめ
- `WITH RECURSIVE` の結果のカラムの型は非再帰的な部分の結果から推測される
- 再帰していく際に非再帰的な部分の文字列の長さよりも、文字列が長くなるとエラーとなる
- `cast`を使って文字列の幅を広げることで対処できる

今回は`WITH RECURSIVE`を使った際に起きた`Data too long for column`への対処方法をまとめた。
同じような現象に遭遇して困っている人がいれば、助けになればと思う。

それではまた。
TomoProg

## 参考資料
https://dev.mysql.com/doc/refman/8.0/ja/with.html#common-table-expressions-recursive
AWS OrganizationsでのS3バケットアクセス制御

**AWS Organizations** を使って、組織内で効率的にS3バケットのアクセス管理を行う方法について
組織内の全ユーザーにS3バケットの読み取りアクセスを許可し、外部のアクセスを制限するための設定の備忘です。

---

### 背景

**AWS Organizations**を利用すると、複数のAWSアカウントを一元管理でき、ポリシーを組織全体で適用できます。
「組織内の全ユーザーにS3バケットの読み取り権限を与え、外部からのアクセスを禁止する」設定を行いたい。

---

### ポリシー設計のポイント

組織内のユーザーのみがアクセスできるようにするには、次の2つのポイントを押さえる必要があります。

1. **組織内の全アカウントのユーザーにアクセスを許可**
2. **組織外のユーザーやアカウントにアクセスを許可しない**

これを実現するために重要なのが、**`aws:PrincipalOrgID`** という条件を使うことです。
この条件を使うと、AWS Organizationsに所属するユーザーにのみアクセスを許可できます。

---

### バケットポリシーの設定例

以下は、S3バケットに対するポリシーの例です。このポリシーは、組織内のユーザーには読み取りアクセスを許可し、それ以外のユーザーからのアクセスを制限します。

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::YourBucketName/*",
      "Condition": {
        "StringEquals": {
          "aws:PrincipalOrgID": "o-xxxxxxxxxx"  // あなたのOrganization ID
        }
      }
    }
  ]
}
```

#### 解説

- **Principal: "*"**  
  すべてのエンティティ（ユーザーやロール）を対象にしています。ただし、次の**Condition**によりアクセスは制限されます。


- **Condition: aws:PrincipalOrgID**  
  ここで、指定されたAWS Organizationsの組織IDに基づいてアクセスが制限されます。組織内のユーザーはこのバケットにアクセスできますが、組織外のユーザーやアカウントはアクセスできません。

---

### OrganizationsとPrincipalの利点

1. **一元管理が可能**  
   **Principal** に「`*`」を指定し、条件でアクセスを制御することで、組織全体のポリシーを1つの設定で簡潔に管理できます。

2. **複数アカウント対応**  
   個別にアカウントやユーザーを指定する必要がなく、**PrincipalOrgID** を使うことで組織全体に適用できるため、管理が非常にシンプルになります。

---

### まとめ

- **`aws:PrincipalOrgID`**を使うことで、組織内のすべてのユーザーに効率的にアクセス権を付与し、組織外からのアクセスを防ぐことができます。

これで、AWS Organizationsを利用したマルチアカウント環境でのS3バケットのアクセス管理がより効率的に行えるはず
install PyTorch/Miniforge systemwide on RockyLinux 8.8

# TL;DR

* python 3.11 on systemwide-pyenv（必須ではないが、念のため別で入れておく）
* install mini-forge（これから入れる）

## requirement

pyenvをsystemwideに入れる方法を実施済みであること（この記事はRockyLinux 9.4で試したが、RockyLinux 8.8でもまったく同様に動いた）

https://qiita.com/it__ssei/items/9239b50de176f3cf275b

# pyenv

## install mini-forge

```
pyenv install miniforge3
```

現在の最新版、miniforge3-24.3.0-0が入った。

```
pyenv local miniforge3-24.3.0-0
python -V
# => Python 3.10.14
```

# conda

## init

```
conda init
exec -l $SHELL
```

.bashrcを元に戻すには
```
conda init --reverse bash
```

## create conda env

```
conda create -n py310 python=3.10.14
conda activate py310
```

## install tensorflow

```
conda install conda-forge::tensorflow
```

### check

```python:check.py
import tensorflow as tf
print(tf.__version__)
```

## install transformer

```
conda install -c huggingface transformers
```

## install ML

```
conda install -c conda-forge scikit-learn
conda install -c conda-forge pandas
conda install -c conda-forge jupyterlab
conda install -c pytorch torchvision
```

```
conda install -c conda-forge matplotlib
conda install -c conda-forge polars
```

## cleanup

```
conda deactivate

conda init --reverse bash
exec -l $SHELL
```

これでログインシェルが元に戻る

# use conda from another user

## login

```
su - issei
```

別のユーザなら誰でもよい

## pyenv

```
pyenv versions
```

出力はこうなった（別で3.11.10をインストール済み）
```
  3.11.10
  miniforge3-24.3.0-0
  miniforge3-24.3.0-0/envs/py310
```

mini-forgeを使うにはこうすれば良いようだ
```
pyenv local miniforge3-24.3.0-0
```

## conda activate

```
conda init
exec -l $SHELL
```

```
conda env list
```

一覧としてはこうなった
```
# conda environments:
#
base                     /usr/local/pyenv/versions/miniforge3-24.3.0-0
py310                    /usr/local/pyenv/versions/miniforge3-24.3.0-0/envs/py310
```

```
conda activate py310
```

## conda deactivate

```
conda deactivate
```

.bashrcを元に戻すには
```
conda init --reverse bash
```

## unset pyenv

```
rm .python-version
```

# 補足：proxy突破のための設定

こんなエラーが出ていたらSSL認証の省略も含めて仕込む
```
CondaSSLError: Encountered an SSL error. Most likely a certificate verification issue.
```

```sh:~/.condarc
proxy_servers:
  http: http://<host>:<port>
  https: http://<host>:<port>

ssl_verify: false
```

https://qiita.com/msrks/items/a9f6fca9085977c0d1af

# 補足：pyenvとは別にmini-forgeを入れたい

結論：systemwideの場合は、やめたほうが良い
PATHの読み込み順序の不整合が解消困難になるので、pyenvとは別にmini-forgeアプリを単体でインストールするのは避けた方が良かった。（これを試したvagrant vmが一つ、エントロピーの海に沈んだ。。。）
Java基礎文法Part6

本日はif文につい記事にしたいと思います。

基本構文
```java
if (条件式）｛
　　処理
}
```
 条件式には結果boolean型となるものを書きます。
 if文の条件式になると｛中カッコ｝の処理が実行され,
 逆に条件式がfalseになると、｛中カッコ｝の処理は行われず、if文から抜けます。
 条件式には比較演算子がよく使われます。

比較演算子は、値を比べて「大きいか」「小さいか」「等しいか」などを判断するための記号です。if文の条件に使われることが多いです。よく使う比較演算子は以下の通りです：
```java
> : 大きい（例：a > b → aがbより大きい）
< : 小さい（例：a < b → aがbより小さい）
== : 等しい（例：a == b → aがbと等しい）
!= : 等しくない（例：a != b → aがbと等しくない）
```

 if ~ else文
if ~ else文は、「もし○○ならば△△をする。そうでなければ□□をする」という形で、2つの選択肢を与える場合に使います。たとえば、晴れなら外で遊ぶ、雨なら家でゲームをする、という感じです。
```java
int score = 70;

if (score >= 80) {
    System.out.println("合格です");
} else {
    System.out.println("不合格です");
}
```
このプログラムでは、スコアが80以上なら「合格です」と表示され、それ以外なら「不合格です」と表示されます。


 if ~ else if ~ else文
if ~ else if ~ else文は、複数の条件があるときに使います。条件がたくさんあって、状況によってそれぞれの条件に従った処理を行いたいときに便利です。

例：
```java
int score = 65;

if (score >= 80) {
    System.out.println("優秀");
} else if (score >= 60) {
    System.out.println("合格");
} else {
    System.out.println("不合格");
}
```
このプログラムでは、スコアが80以上なら「優秀」、60以上なら「合格」、それ以下なら「不合格」と表示されます。


 条件の複数指定
条件を複数組み合わせて判断したい場合には、**&&（AND）や||（OR）**を使います。

&&（AND）：両方の条件が真（true）であるときにだけ実行されます。「○○かつ□□」の場合に使います。
||（OR）：どちらか一方でも真（true）なら実行されます。「○○または□□」の場合に使います。
例：
```java
int temperature = 30;
boolean sunny = true;

if (temperature > 25 && sunny) {
    System.out.println("今日は外で遊べる日です");
} else {
    System.out.println("今日は外で遊べません");
}
```
このプログラムでは、気温が25度より高くて、かつ晴れている場合は「今日は外で遊べる日です」と表示します。どちらかの条件が満たされない場合は「今日は外で遊べません」と表示されます。

今回はif文について記事にしてみました。
Amazon EC2をもう少し深堀

## プレイスメントグループについて
EC2を起動する際に、インスタンスがどのホストOSに起動されたかを意識する必要はありません。しかし特定の用途では起動したインスタンス同士の物理的な配置が重要になる場合があります。プレイスメントグループを利用するとグループ内のインスタンスをルールに従った配置で起動することができ、インスタンス間での低遅延な通信や、ハードウェア障害による影響を軽減できます。

## プレイスメントグループに設定可能なルール
### クラスタプレイスメントグループ
グループ内のEC2インスタンスを単一AZ内の物理的に近い距離に配置します。各EC2インスタンス同士の通信は遅延が発生しにくく高速な通信が可能になります。所属するAZに何らかの障害が発生した場合はサービスが利用不可になってしまうため可用性は低くなりますがEC2インスタンス間の通信遅延を極力なくしたい場合に利用します。

### パーティションプレイスメントグループ
グループをパーティションと呼ばれる論理グループに分割し、それぞれのパーティションに1つ以上のEC2インスタンスが所属します。各パーティションは1つラックが対応しており、ラックには独立した電源とネットワークが配備されています。グループ内の各パーティションはラックを共有しないのでハードウェア障害による影響を軽減します。

### スプレッドプレイスメントグループ
グループ内のEC2インスタンスを異なるラック(ハードウェア)に配置します。パーティションプレイスメントグループではラック内に同一グループのEC2インスタンスを1つ以上配置しますが、スプレッドプレイスメントグループは同一グループのEC2インスタンスを1つしか配置しません。グループ内の各パーティションはラックを共有しないのでハードウェア障害による影響を軽減します。スプレッドプレイスメントグループは異なるAZにEC2インスタンスを配置することもできます。

### パーティションとスプレッドの違い
少数のインスタンス群を分散させるのがスプレッドで、大規模なシステムに対応するのがパーティションです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3899061/49cfe469-1833-87a6-a2c4-26a528863e3e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3899061/a5e72e33-df85-1f77-ec6c-852293f03ff1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3899061/a9d50ee9-7760-9a29-da64-7094afc4cac1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3899061/029dd367-776d-9121-0a49-ab0e20623ec5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3899061/a4d16cc3-221c-fcf7-ab59-77bef1c5a088.png)


## インスタンスメタデータについて
バッチ処理などを実行する際に、プライベートIPなどの自身のインスタンス情報が必要になる場合があります。EC2ではインスタンスメタデータという仕組みでインスタンスに関する情報を取得できます。メタデータにはインスタンスIDやパブリックIPアドレス、DNSホスト名、AMIのIDやIAMのクレデンシャル情報、所属するセキュリティグループなどが含まれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3899061/e1bf7b10-d016-23f3-2e97-32e6776b6baf.png)
ど素人の私が Material3 と仲良くなるために読んだWebサイト

## デザインできる人ってかっこいいじゃないですかー
７年前にほぼデフォルト設定で作成した Android アプリのデザインを [Material Design 3](https://m3.material.io/) にしたら、かっこよくなれるんじゃないかという素人的な発想でデザインの変更に取り組んでみたら、まぁ時間が溶けていきました。

最初は、Google 検索と ChartGPT とか使えばさくっと終わると思って検索ワードやプロンプトを入力しまくってましたが、なんかうまく動かず、色が変わらん！？という状況でイライラモードになりました。

結局、Material Design の公式サイトを読むところから始めるのが一番良かったというおちになりますが、作業を進めていく間にブックマークした Web サイトをまとめておきます。

## Web サイト集
### 1. Material Design の前に
そもそも Android アプリの Style や theme について知識ゼロの自分が、Material Design の公式サイトを読んだところで、チンプンカンプンになりました。知識ゼロの人は、まず基礎知識を以下の Web サイトで学ぶ必要がありそうです。

AndroidのTheme/Styleを理解する #android開発 - Qiita
https://qiita.com/ushi3_jp/items/c7f597a8cf3b35cce426

### 2. Material Design の色
７年前に作成したアプリの styles.xml には、colorPrimary、colorPrimaryDark、colorAccent が定義されていました。

```xml:styles.xml (抜粋)
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>
```

当時は、この３色をテキトーに決めればいいのね！と思っていた記憶があります。

この化石知識では歯が立たなかったので、公式サイトの Color を眺めて、何となく色がたくさんあるのねっというレベルになりましょう。

Color – Material Design 3
https://m3.material.io/styles/color/system/overview

ただ、色の役割が書いてありますが、全部の種類を把握するのは厳しいです。Dynamic color とかはイマイチよくわかっていません。

### 3. UI コンポーネントのカスタマイズ
UI コンポーネントの style は、Primary、Secondary、Surface等を設定すれば、それっぽいかんじになりますが、ところどころ色を調整したいときがあります。

各 UI コンポーネントがどの色と対応しているのか確認するには、まず公式 Web サイトの Components ページからかなと思っています。

Components — Material Design 3
https://m3.material.io/components

Components ページを読んで style を変更しても色が変わらんぞってなったら、Material Design の [GitHub](https://github.com/material-components/material-components-android) ページにある Docs や実装を確認しましょう。

例として、Checkbox について知りたい場合には、Docs で、スタイルの情報や実装例を Checkbox.md で、確認しつつ、Checkbox に定義されている style.xml の実装を見ると理解が深まると思います。

material-components-android/docs/components/Checkbox.md
https://github.com/material-components/material-components-android/blob/release-1.12/docs/components/Checkbox.md

material-components-android/lib/java/com/google/android/material/checkbox/res/values
/styles.xml
https://github.com/material-components/material-components-android/blob/master/lib/java/com/google/android/material/checkbox/res/values/styles.xml

### 4. 公式サイトでわからなかったら
Material Design 3 の公式サイトをみてもよくわからなかったら、ここでようやく Web 検索や ChatGPT に頼るのがいいと思っています。ピンポイントで色を変更したい場所があれば、それを検索ワードやプロンプトにして調べるかんじです。

以下の Web サイトのように実装例が細かく書いてあると理解が深まりとても参考になりました。

ToolbarのDrawer（ハンバーガー）とオプションメニュー（三点リーダー）などの文字色を変更する方法について 
https://knowledge.moshimore.jp/entry/android_toolbar_drawer_hamburger_option_menu_text_color/

### 5. 配色に迷ったら
色ってどうやって決めればいいのってなると思います。センスのない私もそうです。なんとなく決めるとダサい色になりました。

`アプリデザイン 参考` や `Webデザイン 参考` で検索すると色々出てくるので、よいデザインの感覚を得られると思います。

また、Material Theme を生成できる Web サイトがあるので、これを参考に色を組み立てていくと外さない気はしています。

Material Theme Builder
https://material-foundation.github.io/material-theme-builder/

## さいごに
まだまだ、公式サイトも読み切れていないので、引き続き調査する予定です。Figma を使ってデザインする方法もあるんだな～というレベルですが、ちょっと使ってみようかなと思っています。
【基本情報】独学マラソン スケールアップ/スケールアウト Day 3

自分の機嫌を取ることをサボらずに

:::note worn
この記事は自分用の備忘録です。
:::

サーバーの増強には2つの考え方がある。
「スケールアップ」と「スケールアウト」だ。


# スケールアップとは
- PC自体を賢くするやつ 垂直的
    - CPUコア数の増強
    - メモリの増設
    - GPUの追加
        - AWSとかだとインスタンスのタイプを変更したり等で拡張する
- PCが1台だとすると、スケールアップの作業中にダウンタイムが発生してしまうので、頻繁に切り替えるのはよくない

<br>

# スケールアウトとは

- PCを増やして賢くするやつ　水平的
- 増やせば増やすほど全体として高性能になる
- PCがたくさんあるので、スケールアウトの作業中にダウンタイムが発生しないから安心

<br>

# データベースの設計者視点で考えること

- スケールアウトしすぎるとACID特性の維持が困難になる
    - 異なるノード間で処理が行われるため
- スケールアウトされた分散システムでは、分散トランザクションの同期オーバーヘッドが大きくなりパフォーマンスも落ちる
    - ACID特性の保証を諦めて「最終的な一貫性」を重視するなどで対応するらしい


# 感想
- スケールアップ/スケールアウトについてはなんとなく知っていたが、ACID特性との関連については考えたことはなかったので良い学びになった


# 参考

https://www.kagoya.jp/howto/engineer/itsystem/scale-up_scale-out/

https://www.global.toshiba/jp/company/digitalsolution/articles/sat/1801_1.html

https://www.designet.co.jp/ossinfo/griddb/
【Java Silver】Oracle Java Silver SE11 試験

## 使用した書籍やサイト
・progate（有料会員：３か月）
・せかチャン(YouTube動画)
・Javaの黒本
・黒本著者が教えるやさしくない!?java(youtube動画)

## 受験までの期間
・６か月（１日：約１～２時間勉強のペース）

## 試験までの流れ
１．プログラミングに興味がわき、"progate"の有料会員でレッスン通りに進めていく。
（何週したか覚えてませんが、ヒントや解説を見なくても、コーディングできるレベルまでやり込む。）

２．１と同時並行で"せかチャン"動画を参考にコーディングしている内容の理解を深める。

３．試験意欲がわいたので、"Javaの黒本"を購入し、問題を一通り解いてみる。（この時は、全然できないと思う。）

４．黒本の解説を読みながら、それでも理解できないことが必ず起きるので、"黒本著者が教えるやさしくない!?java"動画を参考にして、黒本内の疑問を払拭する。

５．黒本を繰り返し解いてみて、９割程度理解できれば、試験を予約

６．試験

## 受験してみての感想
　私自身、インフラの経験しかなかったため、プログラミングでどこまで理解できるようになるのか不安でしたが、実際にprogateでコーディングしたり、youtube動画で理解が広がることで、不安が楽しいに変わったのが、試験合格までの継続につながった大きな要因でした。

 試験勉強は、とても大変でしたが、焦らず１問１問の内容をしっかり理解できるところまで落とし込むことが重要だと思います。また、試験範囲で問題数のわりに内容が激ムズの部分があったので、費用対効果を考えて、そこの部分は捨てるといったこともやりました。（ラムダ式のところ）

是非、受験を考えている方は参考にしてください。
PaSoRi RC-S300をPythonで扱う

PaSoRiをPythonで触るにはnfcpyが最もポピュラーだが、調べていくとRC−S300はnfcpyが非対応とのこと。
情報がほぼ出回っていないので、RC-S300でIDmを取得する方法を残しておく。

# 環境
Raspberry Pi 4
Linux Raspberrypi 6.6.51 Debian

# 使用ライブラリ
使用するライブラリはpyscardというもの。
ただ、[この記事](https://tex2e.github.io/blog/python/get-idm-from-scard)を参考に`pip install pyscard`と叩いても、自分の環境だとエラーを吐いてインストール出来なかった。どうやら手動でPC/SCの環境を導入する必要があるらしい。

# PC/SC導入
[この記事](https://zenn.dev/compass/articles/39bb050bdaeaaa)のpcsc_scanの部分まで、パッケージのインストールをして動作テストを行う。各ディストリビュージョンによってパッケージの名前が少しずつ異なるため適宜調整しよう。
```bash
$ sudo apt install libusb-dev libpcsclite-dev opensc pcscd pcsc-tools
```

# 再びpyscardをインストール
ここまで済んだらもう一度`pip install pyscard`と実行する。恐らくスルッと入ってくれる。もしまだエラーを吐くようならvenv使ってないとかその辺。
入ったら上記記事を参考に動作テストを行う。
```python
from smartcard.util import toHexString
from smartcard.System import readers as get_readers
import time

readers = get_readers()
print(readers)

while True:
    try:
        conn = readers[0].createConnection()
        conn.connect()

        send_data = [0xFF, 0xCA, 0x00, 0x00, 0x00]
        recv_data, sw1, sw2 = conn.transmit(send_data)
        
        print(toHexString(recv_data))
        break
    except:
        time.sleep(1)

# >>>(カードリーダーの情報)
# >>>xx xx xx xx(16進数のIDm)
```
これでRC-S380とnfcpyを使った動作とほぼ同じ情報を取得できる。
混合モデル方程式から線形回帰係数の分散を導出

## はじめに

次のような混合モデルを考えます。

```math
y=X\beta+Zu+e 
```
```math
u \sim MVN(0,K\sigma_{g}^2), e \sim MVN(0,I\sigma_{e}^2)
```

この時、このモデルのβとuのBLUE及びBLUPは次の方程式を解くことで求めらることが分かっています(混合モデル方程式)。

```math
\begin{bmatrix} X^{T}X & X^{T}Z \\ Z^{T}X & Z^{T}Z+G^{-1} \\ \end{bmatrix}\begin{bmatrix} \beta \\ u \\ \end{bmatrix}=\begin{bmatrix} X^{T}y \\ Z^{T}y \\ \end{bmatrix}
```

また、この時のパラメータの分散も次のように求まることが知られています。

```math
\begin{bmatrix} Var(\beta) & Cov(\beta, u)\\ Cor(\beta, u) & Var(u) \\ \end{bmatrix}=\begin{bmatrix} X^{T}X & X^{T}Z \\ Z^{T}X & Z^{T}Z+G^{-1} \\ \end{bmatrix}^{-1}\sigma_{e}^2
```

非常に覚えやすい形をしていて個人的に気に入っているのですが、今回の私はこれに関する話題です。

一般に線形回帰 $ y_{i}=\beta_{0}+\beta_{1}x_{i}+e_{i}$ の解は最小二乗法を解くことにより求まります。

そしてこの最小二乗解は
```math
\beta=(\beta_{0}, \beta_{1})^T , X= \begin{bmatrix}1&x_{1}\\1&x_{2}\\ \vdots & \vdots \\1&x_{n}\end{bmatrix}
```
としたとき、
$ X^{T}X \beta = X^{T}y$ を解くことにより求まるわけですがこれは混合モデル方程式のuが無いときに対応しています。

この解であるβの分散も知ることができれば傾きや切片自体に対して統計的検定(例えば傾きが有意に0と異なるか、など)を行えるのですが、この分散はやや分かりにくい形をしています。

```math
Var(\beta_{0})=\frac{\sigma_{e}^2\Sigma x_{i}^2}{n\Sigma(x_{i}-\bar{x})^2}
```
```math
Var(\beta_{1})=\frac{\sigma_{e}^2}{\Sigma(x_{i}-\bar{x})^2}
```

さて、最小二乗解が混合モデル方程式のuが無いバージョンに対応しているように、この分散も混合モデルの分散を求める式のuが無いところ$Var(\beta)=(X^{T}X)^{-1}\sigma_{2}^2$に対応していると考えられます。
そこで今回は、この線形回帰の分散を混合モデルの分散を求める方程式から求めてみようと思います。

## 問題設定
$ Var(\beta)=(X^{T}X)^{-1}\sigma_{2}^2$　から　$ Var(\beta_{0})=\frac{\sigma_{e}^2\Sigma x_{i}^2}{n\Sigma(x_{i}-\bar{x})^2},  Var(\beta_{1})=\frac{\sigma_{e}^2}{\Sigma(x_{i}-\bar{x})^2}$　を求める。

## 計算
まず、
```math
X= \begin{bmatrix}1&x_{1}\\1&x_{2}\\ \vdots & \vdots \\1&x_{n}\end{bmatrix}
```
であることを利用して $ X^{T} X$を計算します

```math
X^{T}X=\begin{bmatrix} 1 & 1 & \dots & 1\\  x_{1} & x_{2} & \dots & x_{n}\end{bmatrix}\begin{bmatrix}1&x_{1}\\1&x_{2}\\ \vdots & \vdots \\1&x_{n}\end{bmatrix}=\begin{bmatrix} n & \Sigma x_{i} \\ \Sigma x_{i} & \Sigma x_{i}^2 \end{bmatrix}
```

2×2の行列の逆行列はすでに公式が知られているのでこれに照らし合わせると
```math
(X^{T}X)^{-1}=\begin{bmatrix} n & \Sigma x_{i} \\ \Sigma x_{i} & \Sigma x_{i}^2 \end{bmatrix}^{-1}=\frac{1}{n\Sigma x_{i}^2-(\Sigma x_{i})^2}\begin{bmatrix}  \Sigma x_{i}^2 & -\Sigma x_{i} \\  -\Sigma x_{i} & n  \end{bmatrix}
```

ここでよく知られた分散の公式から $ n\Sigma x_{i}^2-(\Sigma x_{i})^2 = n^2(\Sigma x_{i}^2/n-(\Sigma x_{i}/n)^2=n\Sigma(x_{i}-\bar{x})$ であるので、

```math
(X^{T}X)^{-1}=\frac{1}{n\Sigma(x_{i}-\bar{x})}\begin{bmatrix}  \Sigma x_{i}^2 & -\Sigma x_{i} \\  -\Sigma x_{i} & n  \end{bmatrix}
```

よって、

```math
Var(\beta)=\frac{\sigma_{e}^2}{n\Sigma(x_{i}-\bar{x})}\begin{bmatrix}  \Sigma x_{i}^2 & -\Sigma x_{i} \\  -\Sigma x_{i} & n  \end{bmatrix}
```

ここで以下が成り立つ
```math
Var(\beta)=\begin{bmatrix} Var(\beta_{0}) & Cor(\beta_{0}, \beta_{1}) \\ Cor(\beta_{0}, \beta_{1}) & Var(\beta_{1}) \end{bmatrix}
```

よって、

```math
 Var(\beta_{0})=\frac{\sigma_{e}^2\Sigma x_{i}^2}{n\Sigma(x_{i}-\bar{x})^2}
```
```math
Var(\beta_{1})=\frac{\sigma_{e}^2}{\Sigma(x_{i}-\bar{x})^2}
```

## まとめ
今回、マトリックスを分解することで、混合モデルの分散の式から線形回帰のパラメータの分散を求めることできるとわかりました。
混合モデルの分散の式を覚えるのはそんな難しくはないので、パラメータの分散の式を忘れたときは、今後はここに立ち戻って計算しようと思います
LinuxのターミナルでWi-Fiに接続する方法

# はじめに
　UbuntuなどのLinuxのターミナルで、Wi-Fiを接続する方法を紹介する。ターミナルで完結するので、SSH接続の際にも使える。

# 動作確認環境

* Ubuntu Desktop 20.04 / 22.04

# 事前準備

　```nmcli```コマンドおよび```nmtui```コマンドが見つからない場合は、NetworkManagerを以下のコマンドでインストールする。

```bash
sudo apt-get update
sudo apt-get install network-manager
```

# 方法

1. Wi-Fiをオンにする

    ```bash
    nmcli radio wifi on
    ```

2. nmtuiを起動する

    ```bash
    nmtui
    ```

3. 「接続をアクティベートする」を選択する

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/ae1bab56-184a-f9d6-cb50-5b63e9febce6.png)

4. SSIDから接続先を選んで接続する
5. 「終了」を選択する 

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

## Wi-Fiの接続先が表示されない場合

　Wi-Fiのオフ、オンを繰り返すと解決する場合があるので試す。

Wi-Fiをオフにする。
```bash
nmcli radio wifi off
```
Wi-Fiをオンにする。
```bash
nmcli radio wifi on
```

# 参考

https://kkkw.hatenablog.jp/entry/20220502/1651471611

https://ubuntu.com/core/docs/networkmanager/install

https://docs.redhat.com/ja/documentation/red_hat_enterprise_linux/7/html/networking_guide/sec-configuring_ip_networking_with_nmtui
エンジニアでも技術だけでは通用しない


# 技術はあまり重要じゃない
よほど高度な領域でもなければ、勉強・練習すれば身につく。

新卒を例にすると、最初に出くわす格差が「情報畑や趣味で学んできた人」と「何も知らない人（文系とか）」の差だが、そんなものは大した差ではない。前者が技術あるからといって即戦力になるかというとノーだし、後者だって勉強・練習すれば技術なんてすぐ or そのうち身につく。

# 技術があっても即戦力にならない理由
> 即戦力になるかというとノーだ

ここを掘り下げる。理由をいくつか挙げる。

## ソフトスキルが要るから
プログラミングとか、インフラとか、PCとか、情報工学とか、そういったものは **ハードスキル** という。文字通りの技術。

一方、技術はそれだけじゃなくて、コミュニケーションとかタスク管理とか報連相といった要素もある。これらは **ソフトスキル** という。

仕事はたいていひとりじゃないため、ソフトスキルも要求される。仮にひとりだとしても、たいていは人を相手にする部分があるため、やはりソフトスキルが要る。ソフトスキルも要る。

## ドメイン知識が要るから
たとえば銀行のお客さんのシステムを担当します、となった場合、そのお客さんや銀行業界（金融業界）のあれこれを知らなければならない。絶対的なルールもあれば、主要プレイヤーのパワーバランスもあるし、明文化されていない文化やしきたりもある。業界レベルであればまだ共通で何とかなるが、お客さんレベルとなると、それはそう踏み込んで踏み込んで引き出しに行く必要がある。

こういうのを **ドメイン知識** という。ドメインと略すことも多い。ドメインとは Domain で、領域くらいの意。特に「ある領域の固有の知識」を指す。IT 技術のようにオープンになっていることはほぼなくて、ドメイン知識を知るためには十中八九コミュニケーションが必要だ。あるいは「経験しながら身につけていこうか」とする OJT 的スタイルも多い。よく「東大生（などガリ勉）は役に立たない」というが、それはドメイン知識が勉強的に学べるようになっていないからである。

## 組織やチームで働くから
学校やバイト先もそうであったように、仕事でも組織で働く。また組織化で個人で動くことはほとんどなくて、今はチームの時代でもある。「二人組つくれなくて……」とか「人に話しかけるのは苦手」とか言ってる人は、技術的に優秀であっても戦力外になりかねない。組織やチームの一員、一つの駒として動けることが大前提である。

これを私は **内部ドメイン** と呼んでいる。ドメイン知識や外部だけでなく、内部にもある。外部のドメインは中々に狂っている、面倒くさい、うざいと感じるものだが、内部もそんなものである。むしろ内部は、外部と相対するほど張り切らないので、わかりにくい。日本の文化はハイコンテキスト（文脈・空気は明示せず読め）だが、まさにそのとおり。読めない者は忌避されるし、言語化に走る者も忌避される。

## 多忙主義だから
**毎日定時内（1日7時間～8時間）で済ますことすらできない** ほど、現代のビジネスマンは多忙である。エンジニアも例外ではないし、その辺の仕事より手を動かす量や学ぶ量が多い分、より遠のく。可能なら同僚でも先輩でも上司でも相談してみるといい。「そういうものでしょ」とか「仕事舐めてんのか」的な回答が返ってくるか、表面上は「そうあるべき」と言いつつも全くその気がなかったりする。いかに毒されているかを体感できるだろう。信者の一種だとさえ感じる。

これはつまり、あなたも信者にならなければならないということ。あるいは回避する余地も意外と多いが、それはそれで相応の立ち回りやメンタルが要る。

## 体力もメンタルもゴリゴリ削られるから
エンジニアに限らず、仕事とは基本的に搾取と我慢の世界である。多忙主義はすでに述べたが、他にも「なぜか毎日9時～17時で勤務させられる」などもある。これでは昼型や夜型の人間には厳しい。そんなこともわからず、昔からそうだからという理由だけで現行踏襲している。当然、昼型や夜型の人はこの朝型の制約に耐えねばならない。

※昨今ではリモートやフレックスも増えているが、本当にそのとおりに過ごせているかは意外と怪しい。特にルール上は問題なくても、現場のチームが認めていないこともよくある（上述した内部ドメイン）。

あまりに目に余るので、私は[仕事術2.0｜note](https://note.com/workhack20/)の形で「仕事のやり方・考え方は色々あるんだよ」と啓蒙している。これらはソフトスキルに属する。要は、ソフトスキルがあれば、無駄に耐える苦労は軽減できる。やり方や考え方を変えればいいだけだからだ。

しかし実際はそうはならず、現行踏襲的、あるいは平等（全員が同じことをする）的なあり方が蔓延っているので、そこが規定する **規範に従えるか、そして耐えられるかどうか** が鍵になってくる。マジョリティ側なら難なく耐えるか、うぜえだりぃ程度で済むが、その程度では済まないマイノリティも要る。マイノリティだとしたら辛い。

# 陽キャが評価される理由
就活では陽キャが評価されるという。また、実体験としてもそうであると感じた人は多いだろう。

なぜかというと、上述したとおり、実際に必要となるのが技術以前の諸々だからだ。その諸々を要領良く身に着け、また現実に耐えるための地力が重要なのだ。しかし地力なんて測れるものじゃないから、面接など非言語的な場で推し量る。

# おわりに: 現実は厳しいよ
現代であっても、まだまだ「技術があれば上手くやっていける」世界ではない。特にエンジニアは技術で勝負する職業だから関係ない、と思いがちだが、そんなことはない。昔はその余地も多かったが、IT は手段面でも肥えており、組織的にあたらねば仕事にならない段階に来ている。よって、上述したとおり、技術以前に、歯車として機能できる地力が必要なのだ。厳しい。

とはいえ、組織側を変えることはできなくても、自分自身を変えたり選択肢を知って広げたりすることはできます。[仕事術2.0](https://note.com/workhack20/)もその一助になると思いますので、ぜひ遊びに来てください。
1970年代前半のパーソナルコンピューター

![](https://storage.googleapis.com/zenn-user-upload/1fad0cb426b9-20240929.jpg)
1970年代、パーソナルコンピューターの黎明期には、ビジネスがスタートする際にありがちな課題や出来事がたくさんありました。

![](https://storage.googleapis.com/zenn-user-upload/9d1162411dc8-20240929.jpg)
1970年代といえば、もうかなり昔に感じますよね。時代の空気を感じてもらうために、その頃の出来事をいくつか並べてみました。

![](https://storage.googleapis.com/zenn-user-upload/f258dbef305a-20240929.jpg)
さて、その時代に登場した「最初のパーソナルコンピューター」ともいわれるのが、このAltair8800です。
これは完成品です。ディスプレイやキーボード別売りとかじゃないです。最初からこの形。まだ周辺機器メーカーなんて存在しませんでした。売り出したのがこの時ですから。
表示はランプの点灯と消灯だけ。2進数での情報表示です。
入力もスイッチのオンオフだけで行い、これも2進数。かなりシンプルですね。
ヒットしたおかげで周辺機器も少しずつ増えて、操作も少し楽になったようです。

![](https://storage.googleapis.com/zenn-user-upload/6f25bbaf17bb-20240929.jpg)
この時点で、既にCPUはIntel製。OSは付属していませんでしたが、MicrosoftがBASICというプログラミング環境を開発し、これが大ヒットしました。パーソナルコンピューターの歴史は、実は最初からIntelとMicrosoftのタッグで始まっていたんです。驚きですよね。

![](https://storage.googleapis.com/zenn-user-upload/9b86cca7ee7e-20241003.jpg)
さて。少し時代を遡って、1972年に「パーソナルコンピューター」について書かれた論文があります。著者はアラン・ケイ、そのタイトルは「A Personal Computer for Children of All Ages（あらゆる年齢の子供たちのためのパーソナルコンピューター）」です。

![](https://storage.googleapis.com/zenn-user-upload/e266ad6517ab-20241003.jpg)
その論文の中で提案されているデバイスは、見た目がiPadそっくりです。

![](https://storage.googleapis.com/zenn-user-upload/834529f889c8-20241003.jpg)
見た目だけでなく、スペックも非常に似ています。
- 9インチ×12インチ（約23cm×30cm）
- 512×512ピクセルの画面
- ウィンドウを使ったGUI
- タッチパネル
- マルチフォント
- 仮想キーボード
- オブジェクト指向のAPIを持つOS

もう、iPadのデザインがここですでに完成しているような印象を受けますよね。

![](https://storage.googleapis.com/zenn-user-upload/508ab21e99f2-20241003.jpg)
これが単なる偶然の一致ではないことは、スティーブ・ジョブズの行動からも分かります。彼はこの論文の7年後、アラン・ケイが働いていた研究所に多額の出資をし、研究所を訪れています。この論文を参考にしていたことは間違いないでしょう。

![](https://storage.googleapis.com/zenn-user-upload/8c0c13ad0e24-20241003.jpg)
この論文やその後の研究成果は、当時としては非常に先進的なもので、パーソナルコンピューターに与えた影響は計り知れません。現実がこのアイデアに追いついたのは、iPadが発売された2007年、なんと35年後のことでした。

![](https://storage.googleapis.com/zenn-user-upload/4721be12b509-20241003.jpg)
ここから学べるのは、新しい技術や発明が世に出る時、よく見られるパターンです。現実の技術を超えたビジョンを描く人がいて、それを少しずつ実現する人がいる。理想と現実が徐々に歩み寄り、最終的に理想が現実となるのです。これはパーソナルコンピューターに限った話ではなく、他の分野でも見かける現象です。

新しいプロダクトの開発に挑む皆さん、ぜひこの流れを頭の片隅に置いておきましょう。

(編集協力：ChatGPT 4o様)  
(当記事はZennにもマルチポストされます)
[Zenn](https://zenn.dev/hrmstrsmgs/articles/8c1f50f36d2bc4)
(スライド全体はこちら)  
[speakerdeck](https://speakerdeck.com/player/c13681c9a23f4345a865bfb51c0d979d)
【Swift】guard-let文の使い方

先月[【Swift】guard文の使い方](https://qiita.com/k-andu/items/9c2b6175e5235ae07bda)についての記事を掲載しました。
今回は、guard文と同様に使用されるguard-let文についてif-let文との違いを交え、自分用の備忘録として、どんな処理を行う文法なのか記載します。

## guard-let文とは？
guard-let文とは、if-let文にguard文の適性を持った構文です。

まずはguard-let文に近いif-let文について記載してみます。

#### if-let文とは？
if-let文とは、オプショナルバインディングを行う条件分岐文です。
オプショナルバインディングとは、値が含まれているかが不明な変数に対し、値が含まれているかのチェックと、値が含まれている場合に値を取り出すことを指します。


if-let文は、基本的に下記のように記載します。
```
let Name = Optional("Taro")

if let Name {
    print("名前は\(Name)です")
} else {
    print("名前はありません。")
}
```
上記では、String?型の定数Nameに値が存在すれば、String型の定数aにその値が代入され、続く{}内の文が実行されます。

ただし、if-let文で宣言された定数は、{}内でのみ使用できます。
下記では、if-let文で宣言した定数をスコープ外でアクセスしているため、コンパイルできずエラーとなります。

```
let Name: Any = "Jiro"

if let st = Name as? String {
   // stはここでは使用可能
}
// ここでのstは使用不可のためコンパイルエラー
print(st)
```
ここまではif-letについて記載してみました。
次は、guard-let文とif-let文の違いについて、記載してみます。

#### guard-let文とif-let文の違い
guard-let文はif-let文と違い、letの部分で記載した定数がスコープ外でアクセス可能である点です。

なぜスコープ外でもアクセス可能かというと、guard文以降では変数や定数の存在が保証されているためとなります。
以下に例を記載してみます。
```
func MyName
  let Name: Any = "Taro"

  guard let st = Name as? String else {
    print("aはString型ではありません。")
    return
  }

  // stはguard分以降でも使用可能
  print("名前はString型で\(st)です。")
}

MyName()
<実行結果>
// 名前はString型でTaroです。
```
上記では、stがスコープ外に出た場合は、stには値の存在が確定しています。
なぜ確定しているかというと、guard文は条件不成立時に早期退出を行うため、Nameが存在しない場合はスコープの中の処理（"aはString型ではありません。"）を実行します。

上記より、スコープ外が実行には、stに値が存在していることが前提となるため、コンパイルエラーが起きないことは確定されてい状態だからです。

このように、if-let文では定義した定数がスコープ外はアクセス不可能であるのに対し、guard-let文では、定義した定数がスコープ外にてアクセス可能であることがわかるかと思います。


## まとめ
guard-let文について記載してみました。
これまではオプショナルの概念がない言語ばかり触ってきたので、guard文およびguard-let文について新鮮に学ぶことができました。

また、Swiftはこれまで業務で使用していたため業務の中で新しい発見として学ぶことができていました。
これからは業務で触る機会がなくなっていく中で、Swiftはまだまだ分からない点が多い部分もあるため、引き続き教本等を用いながら学習を続けていきます。
PowerToysを使って一括でファイルを作成する

# 序文
2024/10/02に[PowerToys](https://learn.microsoft.com/ja-jp/windows/powertoys/)のver0.85.0が出ましたね。
新しく追加された機能に **new+** があります。
そこでよく使う、*.h, *.cppを効率よく作りたかったので、備忘録も兼ねてまとめました。
あと、この機能に対応しているのはWin11以降です。


※執筆者は全くと言っていいほど、バッチファイルを知りません。間違っている情報があれば教えてください。

# PowerToys

new+ は Microsoft公式で提供されているアプリケーションでいろいろ便利です。
個人的にはColorPicker系とruler系を使っています。

Windowsの不満としては、txtなどの基本的なファイルを作成するにはよいのですが、対応していないファイルを作成するのは面倒なのです。
それを改善する機能が今回、追加されました。自分で追加すればですが。
ただ、職場のPCはWin10、、、関係ないですね。


# 問題点
Visual StudioのUIからファイルを作成すると、階層構造が保たれないのでよくわからない場所にファイルが作成されてしまうのはあるあるですよね？？

そのため、いつも.h/.cppを作りたいフォルダに行って一個ずつ作っていました。
なお、.txtから作るので、毎回 `pragma once`を書いたり、 `#include "*.h"`を書かなければいけないので、面倒でした。

# 解決策

テンプレートのディレクトリに以下を作成する。
テンプレートのディレクトリは、PowerToysから確認するか、適当なフォルダを右クリック-> 新規+ ->テンプレートを開く からいけます。

ところで、new+ を新規+と訳すセンスには脱帽ですね。

```
@echo off
setlocal
SET INPUTSTR=
SET /P INPUTSTR="FileName?: "
IF "%INPUTSTR%"=="" GOTO :INPUT_CHECK
echo #pragma once>"%INPUTSTR%.h"
echo #include "%INPUTSTR%.h">"%INPUTSTR%.cpp"
del "%~f0"
endlocal
```

行っていることは、
FileNameを変数に受け取り、
#pragma onceを書き込んだ(hoge).hを作成し、
#(hoge).hをincludeしたcppを作成する。

# 機能
バッチファイルを実行すると、プロンプトが起動するのでヘッダとcpp名に適当な名前を付けるだけです。最後にプロンプト自身はdestroyされます。

# そのほかのファイル

中身を空白で作りたいファイルは
type nul > ファイル名とすればよいです。

markdownの場合
```
@echo off
setlocal
SET INPUTSTR=
SET /P INPUTSTR="FileName?: "
IF "%INPUTSTR%"=="" GOTO :INPUT_CHECK
type nul > "%INPUTSTR%.md"
del "%~f0"
endlocal
```

# あとがき
これを実行するだけでプロンプトまで行けるのがあれば教えてください。
単純にコピーっぽいので難しい？
JavaScriptのパッケージマネージャーってなんでたくさんあるんですか？

# A. 一番メジャーなnpmの問題を解決するため
JavaScriptを使う開発者であれば、一度は「パッケージマネージャー多すぎないか...？」と思ったことがあると思います。
[npm](https://www.npmjs.com/)、[yarn](https://yarnpkg.com/)、[pnpm](https://pnpm.io/ja/)など、Node.js上で動作するものだけでもいくつか存在しますし、最近ではNode.js以外のJavaScriptランタイム用のパッケージマネージャーも登場しています。

本記事では、これらのパッケージマネージャーがどれくらい存在するのか、そしてそれぞれが解決しようとしている問題について説明します。

## 1. どんなパッケージマネージャーがあるのか？
改めてどんなパッケージマネージャーがあるのかをご紹介

### Node.jsで動くパッケージマネージャー
- **npm**

https://www.npmjs.com/

- **yarn**

https://yarnpkg.com/

- **pnpm**

https://pnpm.io/ja/

### Node.jsで動かないパッケージマネージャー
- **bun**

https://bun.sh/

- **deno**

https://deno.com/


これらのパッケージマネージャーの特徴について詳しく見ていきます。

## 2. こんだけ多くのパッケージマネージャーがあるのって、npmがそんなにダメなの？

最も有名なパッケージマネージャーといえば、npmです。多くのNode.js開発者が使っているツールだが、
2010年にnpmがリリースされて以降、いくつかの問題が指摘されていました。

### 過去のnpmの問題点
- **インストール速度の遅さ**: 2017年まで、パッケージの並列インストールができなかった。
- **依存関係の壊れやすさ**: `package-lock.json`の導入（2017年）以前は、インストール順によって依存関係が壊れることがあった。
- **セキュリティ対策の脆弱さ**: 2018年まで、パッケージのハッシュチェックやスクリプト実行の制御機能が不十分だった。
- **オフライン利用の困難さ**: 2017年まではキャッシュを利用してオフラインでインストールすることができなかった。

これらの問題は現在ではほとんど解決されていますが、それでも他のパッケージマネージャーが利用されているのは問題が概ね改善される2017年あたりまではnpmではないアプローチをよく採用されていたからでした。

## 3. yarnの台頭

yarnはMeta（旧Facebook）が開発したパッケージマネージャーです。ReactなどMetaの製品群で公式サポートされたことがあり、現在でも一定以上のユーザーから支持されています。yarnの大きなメリットは、npmの持っていたいくつかの問題（特にパッケージの並列インストールや依存関係の管理）を解決した点です。

## 4. pnpmとは？

pnpmは、npmの`node_modules`ディレクトリ構造に関連する問題を改善するために登場したパッケージマネージャーです。

### pnpmの特徴
- パッケージ間で共通する依存パッケージはシンボリックリンクを使用して解決する。
- npmに似たディレクトリ構造だが、シンボリックリンクを使うことでnpmの依存関係に関する問題を避けている。
- Node.jsのバージョン管理機能も備えている。

このように、pnpmはnpmの課題を克服し、より効率的な依存関係の管理を提供しています。

## 5. bunとdenoは？

bunとdenoは、Node.jsとは異なるJavaScriptランタイムをベースにしています。それぞれ独自の特徴を持ち、Node.jsの限界を克服しようとしています。

### Deno
- Node.jsの開発者が、Node.js設計時の反省点を踏まえて作り直したもの。
- TypeScriptをJavaScriptへのトランスパイルなしに実行できる。
- ファイル操作やネットワークアクセスが制御出来るようになっていてセキュリティ機能が強化されている。
- 現在の標準であるESModulesにのみ対応している。

### bun
- bunは、Node.jsのTypeScriptサポートと実行速度を改善することを目指している。
- 2023年9月にv1.0.0がリリースされたばかりの新しいプロジェクトである。

## 6. 結局どれを使えばいいのか？

現在では、npmの多くの問題が解決されているため、npmでも十分に使えます。しかし、プロジェクトによってはyarnやpnpmを選択する理由があります。

- **npm**: 広くサポートされており、多くのプロジェクトで使用されている。
- **yarn**: Reactプロジェクトなどで公式サポートされていたため、一部のユーザーはyarnを好んでいる。
- **pnpm**: 複雑な依存関係管理が必要なプロジェクトでは、pnpmが有力な選択肢となる。
- **deno**: セキュリティを重視する環境や、TypeScriptをネイティブに扱いたい場合に向いている。
- **bun**: 高速な実行が求められる新しいプロジェクトで、今後の成長が期待される。

## まとめ

JavaScriptのパッケージマネージャーは、各々の特性や歴史を持ち、時代のニーズに合わせた選択が求められてきました。なのでそのニーズの数だけ、パッケージマネージャーがあるというのが答えです。
過去、npmで槍玉に挙げられていた大きな問題は現在解消しており、ほとんどの場合でnpmが第一選択肢となるでしょう。
Synology Driveを使用中にLuaLaTeXソースファイルをコンパイルすると文字化けするなどして失敗する問題の解決方法

# 背景
普段からLuaLaTeXで日本語文書を作ることが多いが、どこかのタイミングでなぜかコンパイルを失敗することが多くなった。スライドを作るときに用いるBeamerクラスでも同様の現象が起きる。
何回か試行するうちに成功することがあり、問題の解決を後回しにしていたが、いい加減時間の無駄だと思い、解決を目指すことにした。

# 原因の推定
以前、Dropboxを使用していたとき、同様の現象が起きていたことを思い出した。そのときはLuaLaTexではなくLaTeXだったが、問題の本質はLuaLaTeXでも変わらないだろうと思った。LuaLaTeXもLaTeXもコンパイルするときに割と多くの補助ファイルを吐き出すからである。
試しにSynology Drive Clientを終了してからLuaLaTeXソースファイルをコンパイルすると失敗が再現されなかった。同様にBeamerクラスでも失敗が再現されなかった。
補助ファイルへのアクセスでSynology Drive ClientとLuaLaTeXとが喧嘩して今回の問題を引き起こしたのだろうと推定した。

# 問題の解決方法
「Synology Drive LaTeX」などの検索ワードでググったが、これといった解決策は見つからなかった。
仮に補助ファイルへの同時アクセスなどの問題でコンパイルの失敗が起きているのだとすれば、本来的にはSynology Drive Clientのファイル同期とコンパイルのタイミングをずらす方法があればよいのだが、そういったことが可能となりそうな設定項目はSynology Drive Clientにはなかった。
そこで、ややウルトラC的ではあるが、補助ファイルをSynology Driveに上げない方法を考えた。それらの補助ファイルは.texから派生するファイルであって、たとえ間違って消されたとしても.texのファイルさえ残っていれば再度コンパイルすることで生成可能だから、そもそも不要なのではないかという発想の転換である。
LuaLaTeXソースファイルのコンパイルで生成される補助ファイルを同期しない方法は簡単である。Synology Drive Clientの「同期ルール」から「ファイルフィルタ」を選び、補助ファイルの拡張子を追加すればよい。例えば、.auxや.synctex、.logなどの拡張子である。この拡張子はコンパイルされるソースファイルによって異なるかもしれないのでご自身の環境で各々確認する必要がある。

# 解決方法に関するディスカッション
この解決方法はLuaLaTeXソースファイルをコンパイルするときに生成される補助ファイルをSynology Driveで同期させなくするという、極めて~~しょんない~~画期的な方法である。おそらくLuaLaTeXに限らず、コンパイル時に補助ファイルを生成するLaTeXでも、もし同様の問題が生じたときには試してみる価値があるかもしれない。また、Synology Driveに限らず、同期によって問題が生じていると考えられる場合には、補助ファイルなどの重要でないファイルを同期しないという選択肢も、場合によっては根本的な解決になりうることを視野に入れるとよいかもしれない。