OmniAICreator/Qiita-1.07M huggingface dataset:
DuckDBを使ってTiDBにspatial機能を拡張する

## はじめに

TiDBで、まれにspatial(GIS)関連機能の取り扱いについて質問されることがあります。残念ながら現在はサポートされていません。

ところで DuckDBにはspatial機能があります。これはspatial関連の関数群 `ST_**` を使えるようにするものですが、これはmysqlデータソースのデータに対しても利用できます。これを使ってTiDBにGEOMETRYデータを保存したり、関数を使うことが可能になります。

:::note warn
恐らく真剣に使う場合は一度DuckDB側にデータをインポートした方が速いと思います。こういうやり方もあるよくらいに思ってください。
:::

## 準備

[DuckDB Spatial](https://github.com/duckdb/duckdb_spatial) リポジトリをクローンします。これは単にテストデータが利用したいだけですが、サンプル等もありDuckDBのspatial機能を試すのにもちょうどいいので丸ごとクローンしておきます。

```bash
git clone https://github.com/duckdb/duckdb_spatial.git
```

本記事のサンプルも[DuckDB SpatialのExample](https://github.com/duckdb/duckdb_spatial?tab=readme-ov-file#example-usage) をベースにしたものです。

## Spatial機能を使う

### TiDBへの接続

DuckDBを立ち上げて、TiDBに接続します。詳しい方法については[先日書いたblog](https://qiita.com/bohnen/items/2ab4f13e655605bf168c)を参照してください。

```sql
-- DuckDBで実行
INSTALL mysql;
LOAD mysql;

-- TiDBの接続情報
CREATE SECRET  (
    TYPE MYSQL,
    HOST 'gateway01.ap-northeast-1.prod.aws.tidbcloud.com',
    PORT 4000,
    DATABASE test,
    USER '<TiDBのユーザー>',
    PASSWORD '<TiDBのパスワード>',
    SSL_MODE 'verify_identity',
    SSL_CA '/etc/ssl/cert.pem'
);

ATTACH '' AS tidb (TYPE MYSQL);
```

### テーブルの作成 (TiDB)

TiDB側にデータインポート用のテーブルを作っておきます。DuckDBでは `CREATE TABLE ... AS SELECT ... (CTAS)` 構文が使えますが、残念ながら今回は利用できません。理由は:

- TiDBはGEOMETRY型をサポートしていないので、GEOMETRYで作ってもIMPORTできない
  - なおMySQLで実行した場合もMySQLのGEOMETRYとDuckDBのGEOMETRYは中身が違うのでエラーになりました
- テキストやBLOBに変換した場合、大きいGEOMETRYがエラーになる
  - これはDuckDBのMySQLマッピングでTEXT, BLOBになってしまうためです(MySQLだと2^16 までしか入りません）

そのためここでは、TiDB側で事前にテーブルを作り、`INSERT ... SELECT ...` でデータ投入することにします。Geometryをマップする型はサイズが大きければなんでもいいですが、ここではJSON型にしました。

```sql
-- TiDB側で実行
CREATE TABLE test.zones (zone text, locationId int, borough text, geom json);
```

### Spatial機能を使ったデータのインポート

さてデータをインポートしていきます。DuckDBから実行します。元のgeomカラムはGEOMETRY型なので、`ST_AsGeoJSON()` を使ってJSONに変換しています。

```sql
-- DuckDBから実行
-- tidbはattach済み
INSERT INTO tidb.zones (zone, locationId, borough, geom) SELECT zone, LocationId, borough, ST_AsGeoJSON(geom) as geom
FROM ST_Read('./duckdb_spatial/test/data/nyc_taxi/taxi_zones/taxi_zones.shx');
```

TiDB側にもちゃんと入っていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12495/7d1bcba3-b4a8-62c6-fde5-52469448012a.png)

### Spatial関数を使ったクエリ

例として、ある点が含まれる区画を探してみます。

```sql
-- DuckDBで実行
SELECT zone FROM tidb.zones 
WHERE ST_Within(
  ST_Transform(ST_POINT(40.722223,-73.98385299999998), 'EPSG:4326', 'ESRI:102718'),
  ST_GeomFromGeoJSON(geom));
┌──────────────┐
│     zone     │
│   varchar    │
├──────────────┤
│ East Village │
└──────────────┘
```

geomはJSON型なので、`ST_GeomFromGeoJSON()` でGEOMETRY型にしなければいけないことに注意してください。ただ、変換後は普通にSpatial関数の引数とすることができます。

## おわりに

私自身あまりSpatial機能に詳しくないので、単にサンプルを動かしてみた程度のものですが、DuckDBのいわば外部表としてTiDBを使えるというのはちょっとおもしろいと思います。

これ別にTiDBである必要なくて、他のSpatialをサポートしてないストレージ形式、例えばParquetやCSVでも同じことできるんですよね。結構便利じゃないかなと思います。
【JS】非同期処理の個人メモ

非同期処理に係る処理の個人メモ



## ブラウザ環境を構成する4つの要素
- コールスタック
- WebAPI
- タスクキュー
- イベントループ

## コールスタック
現在実行中の関数を追跡する仕組み。
V8などのJavaScriptエンジンの一部の機能。

関数が呼ばれたら、コールスタックに入れる。
コールスタックの中に入った処理は1つずつ1スレッドで処理される。


## WebAPI
ブラウザが提供する様々な機能のことでブラウザ自体が処理をする
- setTimeout
- setInterval
- fetch
- Promise
- DOM

:::note info
上にあげた処理はブラウザ自体が処理している。つまり上にあげた処理はJavasciptエンジンからは完全に切り離されて実行している。
ここが一番大事！
:::

## タスクキュー
実行待ちのタスクを格納するキューのこと。
非同期処理をタスクとして、タスクキューに追加していく。

### タスク一覧
- script要素内で定義されたJavascriptコード
- イベントのコールバック関数
- setTimeoutなどのWeb APIのコールバック関数


## イベントループ
タスクキューに入っているタスクを順番に処理していく仕組み。
定期的にコールスタックの中身を確認し、中身が全部なくなったタイミングで、タスクキューに格納されたタスクを実行する。
コールスタックを見張って、コールスタックが何も処理をしていないとわかったら、どんどんタスクを追加させている。


## マイクロタスク
@junerさんから教えていただいた`queueMicrotask() `に関する以下ページを参照して、マイクロタスクという存在を知れたのでメモ。

https://developer.mozilla.org/ja/docs/Web/API/Window/queueMicrotask

https://developer.mozilla.org/ja/docs/Web/API/HTML_DOM_API/Microtask_guide

- JavaScriptのイベントループ内で高い優先度を持つタスクのこと
- 通常のタスクはタスクキューに入れられた順番で処理されるが、マイクロタスクは、現在処理されているタスクが終了したら（コールスタックの中身が空になったら）、すぐに実行される。
- 再描画処理よりも優先度が高い。
- タスクキューのようにマイクロタスク用のキューが存在
- Promiseのコールバック関数などがマイクロタスクキューに格納される

## queueMicrotask()
- 指定したコールバック関数をマイクロタスクキューに格納するための関数。
- マイクロタスクキューに格納されたマイクロタスク（コールバック関数）は、同期的なコード実行が終わった後に実行される

:::note alert
イベントループはマイクロタスクキューが空になるまでマイクロタスクを実行する。
そして`queueMicrotask()`から別の`queueMicrotask()`を呼び出すことができる。
つまりマイクロタスクを再帰的に格納し続けることで、タスクが実行されないというリスクがある。
:::

```ts
console.log("開始");

queueMicrotask(() => {
  console.log("マイクロタスク1");
});

console.log("中間");

queueMicrotask(() => {
  console.log("マイクロタスク2");
});

console.log("終了");

// 開始
// 中間
// 終了
// マイクロタスク1
// マイクロタスク2
```

## queueMicrotaskとsetTimeoutの違い
- 優先度が違う。
:::note info
`queueMicrotask > setTimeout`
:::
- queueMicrotaskのコールバック関数は、**マイクロタスクキュー**に格納される
- setTimeoutのコールパック関数は、指定時間経過後に**タスクキュー**に格納される

```ts
console.log('開始');

setTimeout(() => {
  console.log('タイムアウト');
}, 0);

queueMicrotask(() => {
  console.log('マイクロタスク');
});

console.log('終了');

//開始
//終了
//マイクロタスク
//タイムアウト
```
Excelでダブルクリックしたときに変な場所に飛ばされる問題

# 概要
- 表題の通り、Excelで編集しようとセルをダブルクリックした際に、めちゃくちゃな場所に飛ばされてしまうことがあり、非常に腹が立つ
- こちらの原因と対策について記載する

# 原因
- 原因はセルそのものでなく、セルの縁をダブルクリックしてしまっているから
- このとき、謎の便利（？）機能が働き、「一番近い入力されてないセル」までジャンプしてくれるよう
- もし何千行も入力してるページでやっちゃうと何千行下まで飛ばされてしまうってこと
- （誰が活用してんだよ）

# 対策
- 対策としてはExcelの設定でOFFにすることができる
- [Excelのオプション]>[詳細設定]>[フィルハンドルおよびセルのドラッグアンドドロップを使用する(D)]をOFFにすることでこの便利（？）機能が動かなくなる
- ただし、デメリットとしてはフィルハンドル（セルの右下をクリックしたまま下にドラッグすると数値の連番を自動で入力してくれるアレ）も動かなくなってしまう。こっちは割と使うので悲しい

# まとめ
- 現状、イライラを我慢するかフィルハンドルが使えないのを我慢するかの2択
- まいこーそふとさんにはらさっさと直して欲しい（バグじゃないけど）
ファシリテーターが頑張らなくて良いように

この記事は、株式会社カオナビ Advent Calendar 2024の8日目です。

https://qiita.com/advent-calendar/2024/kaonavi

# はじめに

スクラムを採用する開発チームではデイリースクラムやレトロスペクティブなどのスクラムイベントはファシリテーター（以下、ファシリ）が重要ですが、その負担は意外と大きいものです。特にスクラムマスターが不在のチームではありがちですよね。そこで今回はファシリが頑張らなくても良いようにするための工夫や、その結果得られるチームの成長について書きたいと思います。

# ファシリテーションは難しい!
誰もがファシリテーションに難しさを感じるはずです。議論を盛り上げるために質問を投げかけてもなかなか意見が出てこなかったり、時間配分がうまくいかなかったり、思ったより参加者からのリアクションが薄くて疎外感を感じたりなど。会議が終わった後はどっと疲れて「これは毎回やるのキツイなぁ」と思いますよね...

ただ、チームにとっては`有意義な会議へ導いてくれるファシリの存在は必須`です。ファシリが有意義な会議へ導くことに専念できるように、少しでも楽にするような工夫をチーム全体で実施していくことが大事だと考えています。

# ファシリテーターを楽にするための工夫

## ファシリテーターのローテーション
おすすめしたいのは`ファシリをメンバー全員でローテーションする`ことです。ファシリが特定の人に固定されないことで、一人に負担を集中させず、チーム全体でイベントや会議を支えます。

ローテーションを通じて得られる最大のメリットは、`ファシリの難しさをチームメンバー全員が体験できる`ことだと思います。この体験から、ファシリがどんな時につらさを感じるのかをリアルにイメージできるようになります。そして、ファシリテートされる側になった時には自然とファシリがファシリテートしやすいように立ち回ることができるようになります。ファシリを経験する前よりは圧倒的に。

もしそのつらさを知っているのにファシリテートしづらい環境を自ら作ってしまうのであれば、それはもはや会議に参加していない、会議に貢献できていない、会議を妨害する存在になってしまう、ということを気づけるようになります。

## ファシリテートされる側としての意識

ファシリにとってありがたいものは、`多様な発言・豊かなリアクション`です。

これは発言しても良い内容なのだろうかと思うことでも、ファシリを信じて発言すべきです。万が一不必要な発言であれば、軌道修正してくれたり、意図を確認してくれたりするはずです。迂闊に意見を出していっていいと思うのです。

もしリモートワークで会議をしているのであれば、間違いなくリアクションが枯渇しているはずです。特に、音声だけで会議をしている場合はもっとです。
リアルの場での会議では、意見を投げかけた相手がたとえ真顔でも`「真顔」であるというリアクション`をキャッチできます。それが音声のみの場では、どんな顔をしているのかもまったく知り得ません。なので、もし意見が出ない時は、「意見が出ないなぁ」という表情や声を出すでオーバーに表現することが大事なのかもしれません。

## ファシリテーションが不要なプラクティスの採用

私たちのチームでは、レトロスペクティブ（振り返り）においてファシリがしやすいようなシンプルで効果的なプラクティスをよく採用しています。

- **Lean Coffee**：　話す話題をみんなで決めるので、時間管理をするだけで良い議論につながりやすい
- **Fun Done Learn**：　時間さえ測っておけば、アイデアをたくさん発散できる
- **象、死んだ魚、嘔吐**：　率直的な意見が出やすく、自然と盛り上がってくれる

これらの方法は、ファシリが苦手なメンバーでも進行しやすいと思います。
他にもたくさんあるので、こちらのリンクを参考にしてみてください。

https://qiita.com/viva_tweet_x/items/f4db2c923d474f67fe0f

ただし、これらのプラクティスの注意点としてはファシリ以外の参加者が積極的な意見出しをかなり求められるようになります。とはいえ、ファシリに頼らず意見を出し合う練習にもなるし、ファシリをカバーすることに繋がります。毎回これらを採用するというよりはタイミングを見て採用することが大事だと思います。

## ファシリテーションに感謝

ファシリの大変さを全員が経験することで、ファシリへの感謝の気持ちが自然と生まれるはずです。この感謝の気持ちが、チーム内の良い人間関係を築く一助となります。会議でファシリを快く引き受けてくれたメンバーに対してはなるべく感謝の気持ちを伝えるようにしましょう。

# まとめ

ファシリが頑張らなくても良いようにするためには、チーム全員の協力と工夫が欠かせません。ローテーションによって役割を共有し、参加者としての意識を高めることで、ファシリの負担を軽減しつつ、チーム力を向上させることができます。

私たちのチームでは、これらの取り組みを通じてより良いコミュニケーションと協力体制を築けています。もし同じような課題を感じている方がいれば、ぜひ一度試してみてはいかがでしょうか。  
ファシリはチームにおいて重要ですが、それを一人で抱え込む必要はありません。全員で役割を共有し、お互いにサポートし合うことで、より良いチーム作りが可能になるはずです。

# おすすめ資料

https://www.ryuzee.com/faq/0095/

https://hase0831.hatenablog.jp/entry/2024/12/02/100000

https://konifar-zatsu.hatenadiary.jp/entry/2024/11/18/203614
cron + rtcwake によるサーバ停止・起動の定期実行

本記事は「 [TTDC Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ttdc) 」 9 日目の記事です。

## はじめに

Linuxサーバを「週末の夜にOFF（スリープ）、週明けの朝にON」するような定期実行が必要になったので、設定方法を簡単にまとめました。

## 諸注意

- [rtcwake のマニュアル](https://manpages.ubuntu.com/manpages/jammy/en/man8/rtcwake.8.html) にある通り、全てのハードウェアで以下の手順が有効なわけではありません。
- 再起動できなくなることを防ぐため、任意に電源OFF/ONできる（オンプレサーバなら物理的にOFF/ONできる）状態で設定＆確認することをおすすめします。
- `date` コマンドの時刻がずれていることで、動作テスト時に既に過ぎた時刻をcronに設定していることに気づかないことがあります。こちらも念のため事前確認を。

## 環境

- Ubuntu 22.04

## 設定手順

### 1. ハードウェアクロックの確認

ハードウェアクロックがローカル時間なのかUTCなのかを以下で確認します。

```
$ cat /etc/adjtime
0.0 0 0
0
LOCAL
```

ファイル3行目に `LOCAL` または `UTC` のどちらが書かれているかで判断します（上記の場合はローカル時刻、ファイルがない場合は `UTC` ）。

### 2. cron のログ出力有効化

上手く設定できていない場合の原因調査に備えてログを有効化しておきます。

以下のようにして `rsyslog` の設定ファイルを開き、
`#cron.* /var/log/cron.log` と書かれた行のコメントアウトを解除してから、

```sh
$ sudo nano /etc/rsyslog.d/50-default.conf
```

`rsyslog` を再起動します。

```sh
$ service rsyslog restart
```

### 3. crontab の設定

定期実行を `crontab` で設定します。

```sh
$ sudo su -  # 定期実行にroot権限が必要なのでユーザ切り替え
$ crontab -e # 設定ファイルを開く
```

具体例：設定ファイル末尾に以下を追記すると、毎週金曜日23時にシャットダウンし、月曜日5時に起動します。

```sh
## Shutdown at 11pm on Friday and starts up at 5am on Monday.
00 23 * * fri /usr/sbin/rtcwake -m off -l -t `date -d "next monday 05:00" +\%s`
```

`` `date -d "next monday 05:00" +\%s` `` の部分で、cron実行（シャットダウン）時の次の月曜日5時を計算しています。


設定後、ログ `/var/log/cron.log` を確認して期待通りの日時に停止・起動できていれば完了です。

```sh
$ tail /var/log/cron.log
```

#### crontab 設定記載の注意点

1. ハードウェアクロックが `UTC` の場合は `rtcwake` の `-l` オプションを外し `-u` を設定、 `date` コマンドにも `-u` オプションを指定します。
2. `date -d "next monday 05:00" +\%s` の部分について、 `\%` として `%` に対するエスケープが必要です。

## おわりに

最後まで読んでいただき、ありがとうございました！

今後も機械学習の活用を始め、開発環境やシミュレーションなど幅広く技術情報発信をしていく予定です！

最後になりますが、本記事の内容に誤りなどあれば、コメントにてご教授お願いいたします。

## 参考サイト

- [ubuntu manuals - rtcwake](https://manpages.ubuntu.com/manpages/jammy/en/man8/rtcwake.8.html)
- [Linux Japanese Manual Draft - RTCWAKE](https://ysatoautonomous.github.io/jm-draft/man2html/util-linux/util-linux-2.34/draft/man8/rtcwake.8.html)
- [rtcwakeの使用方法](https://qiita.com/kazutaka708/items/6748b8cb029f5bc51014)
- [【Ubuntu】cronでsudoを実行するにはどうすれば。](https://freefielder.jp/blog/2018/07/ubuntu-cron-sudo.html)
- [[ubuntu] Cronのログを表示させ、Cronの実行結果を確認する方法](https://blue-bear.jp/kb/ubuntu-cron%E3%81%AE%E3%83%AD%E3%82%B0%E3%82%92%E8%A6%8B%E3%81%A6%E5%AE%9F%E8%A1%8C%E7%B5%90%E6%9E%9C%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/)
- [cronでログファイル名を実行日時に設定するときの注意](https://qiita.com/tanakaworld/items/5bdd0d6616024629e28a)
weztermで後ろの背景を画像にする方法

ターミナルの背景を特定の画像にして、可愛くしたりかっこよくしたいって思ったことありませんか？

そんな時にweztermで後ろの背景画像を指定する方法を紹介したいと思います。

# weztermに関する記事
weztermに関する記事は以下で紹介しています。

https://qiita.com/maooz4426/items/cd1b15a38f4bf166b8f8

https://qiita.com/maooz4426/items/7af0fafde37633a2e97e

# 変更方法

下のようにwezterm.luaに記述します。

```lua:wezterm.lua
config.window_background_image = wezterm.home_dir .. "画像のある位置の絶対パス"
```

`wezterm.home_dir`は、ホームディレクトリをよしなに指定してくれます。
Macの場合だと, `/User/<ユーザー名>`にしてくれます。
そこの位置から画像のあるパスを指定しています。

また、次のような書き方をすることもできます。

```lua:wezterm.lua
config.background ={
    {
        source = {
          File = wezterm.home_dir .. "画像のある位置の絶対パス",
        },
      
      },  
}
```

こちらの書き方だと他のレイヤーを画像と重ねることができるため、上に色を追加したりすることもできます。

例えば、上に赤色を重ねたい場合は下のように記述します。
```lua:wezterm.lua
 {
        source = {
          Gradient = {
            colors = { "#ff0000" }, 
          },
        },
        opacity = 1.0, 
        width = "100%",         
        height = "100%", 
      },
    {
        source = {
          File = wezterm.home_dir .. "画像のある位置の絶対パス",
        },
        opacity = 0.8,
        hsb = {
            brightness = 0.1,     

        },
      
      },  
```

こうすることで画像を使ってさらに自分好みのターミナルにすることができます。

ぜひ参考にして自分好みのターミナルを作ってみてください!

# 現在の設定ファイル

現在の設定ファイルは下のリポジトリです。

https://github.com/maooz4426/wezterm-dotfiles
【chatGPT 対話備忘録】ツイストペアケーブルのカテゴリ

# 私：
ツイストペアケーブルのカテゴリを教えて
# ChatGPT:

ツイストペアケーブル（Twisted Pair Cable）は、用途や性能に応じて以下のようなカテゴリ（Category、略して「Cat」）に分類されます。この分類は、主に通信速度や周波数帯域に基づいています。

### 主なツイストペアケーブルのカテゴリ
| カテゴリ | 最大通信速度     | 周波数帯域  | 用途                                   |
|----------|-----------------|------------|---------------------------------------|
| Cat 3    | 10 Mbps         | 16 MHz     | 旧式の電話線、10BASE-Tネットワーク    |
| Cat 5    | 100 Mbps        | 100 MHz    | 10/100BASE-Tネットワーク（現在は非推奨） |
| Cat 5e   | 1 Gbps          | 100 MHz    | ギガビットイーサネット（10/100/1000BASE-T） |
| Cat 6    | 1 Gbps（55m）    | 250 MHz    | ギガビットおよび10ギガビット（短距離）    |
| Cat 6a   | 10 Gbps         | 500 MHz    | 高速ネットワーク（10BASE-T）           |
| Cat 7    | 10 Gbps         | 600 MHz    | 高信頼性ネットワーク（工場、医療施設）   |
| Cat 7a   | 10 Gbps以上      | 1,000 MHz  | 放送業界や特殊な高速通信環境            |
| Cat 8    | 25～40 Gbps     | 2,000 MHz  | データセンター、サーバールーム          |

#### ポイント
シールド有無:

Cat 6以上ではシールド処理（STP: Shielded Twisted Pair）や非シールド（UTP: Unshielded Twisted Pair）の選択が可能。
シールド付きの方がノイズ対策に優れるが、設置がやや複雑。
#### 互換性:

高カテゴリのケーブルは下位互換性があり、過去の標準にも対応可能。
#### 選定基準:

家庭用途: Cat 5eまたはCat 6（将来性を考えるとCat 6a）。
業務用途: Cat 6a以上。
高速データ通信: Cat 8（短距離）。

ツイストペアケーブルの選択は、使用環境やコストに応じて適切なカテゴリを選ぶことが重要です。
PowerAutomateDesktop カスタムフォームのサイズを調整する方法

## 概要
PowerAutomateDesktopで、カスタムフォームがの横幅が小さく、調整できない問題について対処法を紹介します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809382/cd43cd58-201f-289e-79fd-51e8d9adb6a5.png)

##  問題
カスタムフォームデザイナーでは、高さは設定できますが横幅が設定できません。
横幅はテキストブロックの最小サイズとなってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809382/c1511958-7806-2a2c-82c8-b064e752e801.png)


## 対処法
対処法は**ラベルに空白を入れる**となります。
ラベルに空白を入れると好きな幅にウィンドウサイズを調整できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809382/1342db88-6a8d-15a1-ef86-5c51fd2ae3d6.png)

:::note warn
ラベルに文字を入れる場合はスペースで大丈夫ですが、文字を入れない場合はスペースだと受け付けられません。以下の空白文字をコピペして使ってください。
:::

```text:空白文字
ㅤㅤㅤㅤㅤ
```

### 空白なしの場合
空白を入れない場合の初期サイズは、ウィンドウのタイトルも省略されてしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809382/5b8997cf-a22a-85ed-604d-895de4f274b7.png)

### 空白を入れた場合
空白を入れた場合は横幅が増えています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809382/10831d13-b6b1-7ad1-4a43-56f4abd46d97.png)

ラベルに文字を入れた後に空白を入れてもOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809382/f469f45a-a7f6-e7a3-0f2b-fbf8492251d7.png)


:::note warn
ラベルの分で1行分空いてしまうので、テキスト表示の代わりに使うなどしてください。
:::
【TIPS】Elixir で配列から要素を取り出す全ての組み合わせを取得する

## はじめに

例えば `[1, 2, 3, 4]` という配列から 3 個の要素を取り出すとき、以下のような組み合わせが有り得ます

```elixir
[[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]
```

組み合わせの数は以下の公式で簡単に計算できます

$$
{}_nC_r = \frac{n!}{r!(n-r)!}
$$

しかし、実際の組み合わせを取得するには少し工夫が必要なので、 TIPS としてまとめておきます

実装したノートブックはこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/tips/all_combinations.livemd

## 組み合わせ取得モジュール

以下のコードが組み合わせ取得モジュールです

```elixir
defmodule Combinations do
  def all(list) do
    1..length(list)
    |> Enum.reduce([], fn n, acc ->
      acc ++ all(list, n)
    end)
  end

  def all(_, 0), do: [[]]
  def all([], _), do: []
  def all(list, n) when length(list) == n, do: [list]

  def all([head | tail], n) when n > 0 do
    with_head = for combo <- all(tail, n - 1), do: [head | combo]
    without_head = all(tail, n)
    with_head ++ without_head
  end
end
```

やっていることは以下の処理です

- 配列の要素数 = 取り出す数の場合は必ず組み合わせが特定できる
  `[1, 2]` から 2 個取り出す場合、必ず `[1, 2]` のパターンしか存在しない
- 配列の要素数が増えたとき、取り出すパターンは以下のもので構成されている
  - 増える前の全ての組み合わせ（`without_head`）
    `[1, 2, 3]` から 2 個取り出す場合、 `[1, 2]` から 2 個取り出したときにあった `[1, 2]` のパターンは必ず含まれる
  - 増える前の配列から一つ少ない要素を取り出した時の組み合わせに増えた要素を追加した組み合わせ（`with_head`）
    `[1, 2, 3]` から 2 個取り出す場合、 `[1, 2]` から 1 個取り出すパターン、つまり `[1]` と `[2]` に `3` を組み合わせて `[1, 3]` と `[2, 3]` が追加される

このことを再帰的に利用すると、短い長さの組み合わせからどんどん要素を追加していくことで長い配列の場合でも全ての組み合わせが取得できます

## 使用例

入力の配列が以下のようなものだったとします

```elixir
list = [1, 2, 3, 4]
```

取り出す数に 2 を指定して実行します

```elixir
Combinations.all(list, 2)
```

実行結果

```elixir
[[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
```

取り出す数に 3 を指定します

```elixir
Combinations.all(list, 3)
```

実行結果

```elixir
[[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]
```

長さを指定しない場合、取り出す数についても全てのパターンを網羅します

```elixir
Combinations.all(list)
```

実行結果

```elixir
[
  [1],
  [2],
  [3],
  [4],
  [1, 2],
  [1, 3],
  [1, 4],
  [2, 3],
  [2, 4],
  [3, 4],
  [1, 2, 3],
  [1, 2, 4],
  [1, 3, 4],
  [2, 3, 4],
  [1, 2, 3, 4]
]
```

## まとめ

再帰処理を使うことで、全ての組み合わせを取得できました

Advent of Code や AtCoder などでも活用できるので、参考にしてみてください
自分用のRedmineを、docker composeで立ち上げる

# 概要

仕事をしていると、自分の作業ガントチャートやチケット管理システムで見たい時があると思います。
; 私の場合は、講演の資料作成や運営とのやり取り、複数講演の管理、等をしたい。

会社のプロジェクト管理ツールを使うほどでもないので、WSL2のLinux上でDockerでRedmineを動かして使う、ということにしました。

- Docker Desktopは使いません。企業内で使う場合ライセンスが必要です。
    - 逆に、よく分かっていない人から指摘されることがあるので、Docker Engineなら問題ないことを先に調べておきましょう

# 設定
## WSL2

- WSL2でLinuxを動かす
    - Ubuntuでいいんじゃないですかね
    - 一般的な作業なので割愛
- WSL2/Linuxで、Dockerを設定する
    - 上記でUbuntuの場合、apt管理できるほうが良いかもしれません
    - 一般ユーザでコンテナの起動等ができるようにしましょう
    - 一般的な作業なので割愛
- Windowsから `localhost` でアクセスできるようにする
    - `C:/Users/<UserName>/.wlsconfig`（/mnt/c/Users/<UserName>/.wslconfig）を用意する
```text:.wslconfig
localhostForwarding=True
```

## Docker

- ワーキングディレクトリに移動する
    - `C:\docker\redmine`と仮定
- `docker-compose.yml`を作る
    - `C:\docker\redmine\docker-compose.yml`と仮定
```text:docker-compose.yml
services:
  redmine:
    image: redmine:latest
    container_name: redmine
    restart: always
    ports:
      - 80:3000
    environment:
      TZ: Asia/Tokyo
      REDMINE_DB_MYSQL: mysql
      REDMINE_DB_DATABASE: redmine
      REDMINE_DB_USERNAME: redmine
      REDMINE_DB_PASSWORD: redmine
      REDMINE_DB_ENCODING: utf8mb4
    depends_on:
      - mysql
    volumes:
      - web:/usr/src/redmine/files
  mysql:
    image: mysql:latest
    container_name: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: P@ssw0rd
      MYSQL_DATABASE: redmine
      MYSQL_USER: redmine
      MYSQL_PASSWORD: redmine
      TZ: 'Asia/Tokyo'
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    volumes:
      - db:/var/lib/mysql
volumes:
  web:
  db:
```
- docker composeで動かす
    - `$ docker compose up -d`
- 稼働していることを確認する
    - 設定に不備があると再起動を繰り返すことになるので、永続稼働していることを確認する
        - `$ docker ps -a`でuptimeがリセットされていない（設定不備でdown -> 再度起動 を繰り返していない）ことを確認する

## WidnowsからRedmineを使う

- ブラウザで `localhost` を開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124868/b5e15e5c-afee-34df-ecad-9e6efe3724c9.png)
- 後は純粋にRedmineの使い方なので、割愛
    - [Redmineを使い始めるための初期設定](https://redmine.jp/tech_note/first-step/admin/) 辺りを参考に設定するとよいですね

# 備考

- Redmine/Mysqlともに、latestです
- Redmineへのplugin導入等は、`docker cp`コマンドで渡しします
    - `docker cp ./uploadfile.zip redmine_web:/usr/src/redmine/files`
        - ターゲットは`/usr/src/redmine/(files|plugins|public/themes)`あたりかも
- volumeは`redmine_(db|web)`を利用
    - 削除時は、`docker volume rm redmine_db`などで消しましょう
【イベントレポート】re:Invent 2024 Daily re:Cap #4 with AWS Heroes #RecapHero2024

記事を読んでいただきありがとうございます！
モブエンジニア（[@mob-engineer](https://qiita.com/mob_engineer))です！

12/06（金）に参加した「re:Invent 2024 Daily re:Cap #4 with AWS Heroes」へ参加したので、
参加レポートとしてアウトプット記事を執筆しました。

お昼休みのスキマ時間にサラッと読んでいただければ幸いです！

:::note info
極力平易な表現＋正しい情報を執筆することを心がけておりますが、
筆者の認識相違なので間違いなどがあればコメントなどをいただけますと幸いです。
:::

**イベントページはこちら**

https://jawsug-chiba.connpass.com/event/335707/

**12/03（火）のイベントレポートはこちら**

https://qiita.com/MASAKIOKUDA-eng/items/e313e0bc128cf25cf8bf

**12/04（水）Iのイベントレポートはこちら**

https://qiita.com/MASAKIOKUDA-eng/items/8615dfaa61224de40d97

**12/05（木）のイベントレポートはこちら**

https://qiita.com/MASAKIOKUDA-eng/items/00923f00ad12a9b4e806

## イベント概要

## 概要
>re:Invent 会期中にリリースされるサービスやキーノートの内容、そして会場内で行われていることなど、幅広くおさらい。
各AWS Heroの観点や感想など交えて話する様子をオンライン配信します。
全AWS Heroの参加ではなく、参加できるAWS Heroだけになります。

## 目的

>re:Invent 開催中にどのようなサービスがリリースされたのか参加者に知ってもらう
AWS Heroesがそれぞれ持っている視点でそのサービスがリリースされた背景や活用シーンなどを伝える
伝えることで自分たちの学習（持ち帰れる情報を増やす）につなげる
AWS re:Invent 現地参加者しか手に入れられない情報や体験できないこと(雰囲気など)を伝える

### セッション内容

### CTO WernerのKeynote
- ピザの話から始まる
- Amazon20周年 and re:invent13年
    - クラスメソッド設立と同じタイミング
- 20年前に提示したアーキテクトの考え（Controllable、Resilient、Data-driven、Adapive）
    - 現在のサービスでも同じように言える
- 今のアーキテクトの考え
    - simplexityに関する議論から入る
        - 開発業務を行っていると分かりみが深い（筆者意見）
    - 根本の考え（20年前に提示したアーキテクトの考え）は変わらない
        - AWSサービスにもその考えは反映されている
    - 実際のプロダクトはComplex（複雑）になってしまう
        - 複雑性はコンポーネント・機能数というわけではない
            - コンポーネントを削減するとモノリシックなアプリになる
        - 一輪車・自転車・三輪車の例から
    - シンプルにするためには規律が必要
        - 開発者視点だと開発標準を決めようってことかしら（筆者意見）
    - AWSの最初の考えは3層アーキテクチャ
        - シンプルな構成でもはやく市場に出すことの重要性
    - DataBase Magicの話
        - DB移行に関しては守破離の考えが重要
        - MP消費の話は面白かった（笑）
    - 先人への感謝を示すキーノートだった
        - 内容としては学術よりの内容だったのでややとっつきづらかったとのこと
    - オーナーシップの考え
        - AWSセッションでよく出てくる考え

## まとめ

Reinvent参加者から非常に示唆のあるお話を伺うことができたと考えております。
今後もre:Capイベントでアップデート情報について解説があるかと思いますので、ウォッチしていきたいと思います。

### Keynote

[​​AWS re:Invent 2024 - Dr. Werner Vogels Keynote](https://www.youtube.com/watch?v=aim5x73crbM)

最後まで記事を読んでいただきありがとうございます！
Ubuntuで大きいファイルを探して削除する[ncdu]

Ubuntuで大きいファイルを探して削除するには、ncduが便利

```sh
sudo apt install -y ncdu
sudo ncdu /
```


ncduはどうやら個人プロジェクトのよう。
ホームページ
https://dev.yorhel.nl/ncdu

ソースコード
https://g.blicky.net/ncdu.git/

気になって、作者のyorhel氏について調べてみた。
作者ホームページ
https://yorhel.nl/
下記のようなことが書いてあるので、だいぶ自由ソフトウェア主義的な様子
> You will not find me on closed networks such as Discord, Facebook, Github, LinkedIn, Twitter, etc.

ncduは、Zig実装やC実装などあるらしい。

氏が開発しているオープンソースPJのページマップページ
https://dev.yorhel.nl/
Ncdu, Ncdc, Tuwf, Yxml, Nginx-cfg, SQLBin, Torreas, Ylib などたくさんある
ソースコードは、https://g.blicky.net/ にホスティングされているが、どうやらこのGitレポジトリのサーバ自体をyorhel氏が管理しているよう。

2024/12/29の13時頃、guestbookに「ncdu is great! Thank you!」というコメントを残した。数日待って、審査が通ったら表示されるらしい。
2024/12/30 3時頃確認したところ、反映されていた
![Screenshot from 2024-12-30 02-42-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149425/84f266cd-4c7e-d8fd-7e25-a032d6c2aa7e.png)

2025/2/1追記
ただ単に、1つのディレクトリのサイズを知りたければ、 `du -sh <path>` でよい。
option解説
s: summary
h: human-readable
Flow MailAlert Trigger 差出人メールアドレス：現在のユーザーのメールアドレス

## テスト手順

1. メールテンプレートを作成

2. メールアラートを作成
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/c5a8b5e1-1743-0cce-2809-54323ae5fe2b.png)

3.Triggerフロー作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/6f6142c8-5bbc-7ffa-7886-7ff67ca386d5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/3e10b16a-d84b-71d3-914d-a6f2f8531872.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/c2adda2e-e073-9e9d-b326-b30cc047a59f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/6ae41d90-5bca-d1bb-ad78-1c8619994fbb.png)

4.レコードを新規、更新して、フローが起動され、メールが送られるかを確認
関数型PG言語に倣う：パターンマッチとは

## 関数型PG言語に習う：パターンマッチとは
- 分岐の表記方法の１つ
- ifではネスト地獄になる複雑な条件をシンプルに書ける魔法の記法！

----
## サンプル
配列のパターンマッチ
```Elm
case list of
  []     -> "(空＝要素数0の場合)"
  (e:[]) -> "(要素数1で、その要素をeという変数に格納)"
  _      -> "その他のケース"
```

----
## タプルとの併用が協力
- タプルというデータ構造：複数の値を束ねる、異なる型でもOK
- C#にもある！
- ("jabaraster", 20251110)

```Elm
case (person.isAdmin, person.name) of
  (true, "jabaraster") -> "..."
  (false, _)           -> "..."
```

----
## パターンが網羅されていないときの挙動
- エラーになって欲しい
- 実際、ElmやHaskellはエラーになる

----
## 他の言語でのパターンマッチ
- Scalar
- Haskell：ほぼElmと同じ

----
## C#での疑似パターンマッチ -switchを使う
```C#
switch ((father is not null, mother is not null))
{
    case (true, true):
        // 父母どちらも存在するときの処理
        break;
    case (true, false):
        // 父のみ存在するときの処理
        break;
    default:
        // その他の場合の処理
        break;
}
```

- C#のswitchは非常に奥が深いのでドキュメント見てみるのがおすすめ

----
## 最後に
- パターンマッチが使える言語が限られるが、知っておくことが重要
- C#では似たような書き方ができる
- しかし堅牢性はElmやHaskellに劣るのでその点は注意
GithubのPull Requestでエクセル差分を戻す方法

## 問題

- UTでデータベースのモックをエクセル等を使用していた場合に、テストデータ用のエクセルをPush => やっぱり元に戻してください！ってなった場合、Pull Requestのマージ先ブランチのエクセルをコピーして対応ブランチに貼り付けても差分ありな表示になってしまう


## キャプチャ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118286/9b4184eb-9a4b-33e5-4984-dc80a42113c1.png)

- 上記のような状態から解消されない(うーん。。。こざかしい。。。)
- 本来は差分なしになって欲しい(表示されてほしくない)


## 解決方法

- 対応ブランチ側で以下コマンドを実行

```bash:bash
git checkout マージ先ブランチ -- 元に戻したいエクセルのパス
```

例)

```bash:bash
git checkout origin/main -- tests/data/service/test_data.xlsx
```


- チェックアウト後、対応ブランチ側でエクセルをPush
- 差分解消:hugging:


## なぜ単純なコピペじゃダメなのか？

- エクセルファイルはバイナリーで管理されており、その中には非表示のメタデータ等が含まれる
- そのため、コピー時に、作成日時、更新日時、などのメタデータが変更される？ようで差分ありな判定となってしまう
LeetCodeを1日1題解いてみる (day36)

36日目に取り組んだ問題はこちら！

# 182. Duplicate Emails

https://leetcode.com/problems/duplicate-emails/description/?lang=pythondata

## 問題文
Table: `Person`
```
+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| email       | varchar |
+-------------+---------+
```
id is the primary key (column with unique values) for this table.
Each row of this table contains an email. The emails will not contain uppercase letters.
 
Write a solution to report all the duplicate emails. Note that it's guaranteed that the email field is not NULL.

Return the result table in any order.

## 僕の回答
```py
import pandas as pd

def duplicate_emails(person: pd.DataFrame) -> pd.DataFrame:
    duplicate_rows = person[person.duplicated(subset=["email"])]
    result = pd.DataFrame({"Email": duplicate_rows.email})
    return result
```
これだと、２つ以上の重複があった場合に、resultに同じものが含まれてしまった。
`{"Email": duplicate_rows.email}`を`{"Email": set(duplicate_rows.email)}`に変更したが、まだエラーが出てこれ以上思いつかなかったので、GPTにヒントをもらった。

## 僕の回答 (GPTの助けあり)
```py
import pandas as pd

def duplicate_emails(person: pd.DataFrame) -> pd.DataFrame:
    duplicate_rows = person[person.duplicated(subset=["email"])]
    result = pd.DataFrame({"Email": duplicate_rows.email.unique()})
    return result
```

## 他の回答例
```py
import pandas as pd

def duplicate_emails(person: pd.DataFrame) -> pd.DataFrame:
    duplicates = person[person.duplicated(subset="email",keep=False)]
    return duplicates[["email"]].drop_duplicates().rename(columns={"email":"Email"})
```
## コメント
重複を削除した新しい DataFrame または Series を生成したい場合は`drop_duplicates`を使い、特定の列内でユニークな値を配列として取得する場合は`unique`を使うと良いと学んだ。

## 次の問題はこちら!
https://qiita.com/h_y_s_d/items/6ec380f02d166da1ac81
GoのクロスプラットフォームGUIライブラリのGioを触ってみた

この記事はHRBrain Advent Calendar 2024 7日目の記事です。

https://qiita.com/advent-calendar/2024/hrbrain

## はじめに
今年の1月に入社した[yakiniku0220](https://twitter.com/yakiniku040220)です。
早いもので入社してもう少しで1年経ちます。

今回は少し興味があったライブラリのGioを使ってデスクトップGUIを作ってみます。
作ると言っても本格的なものではなくてサンプルを用いてどういったことができるのかを見ていけたらと思います。

## Gioとは
[Gio](https://gioui.org/)はGoでクロスプラットフォームのイミディエイトモードGUIを書くためのライブラリです。
デスクトップ（Windows, macOS, Linux）だけでなく、モバイル（iOS, Android）でも動作するアプリケーションを一つのコードベースで開発できるのが特徴です。

## Gioのセットアップ
### Gioのinstall
まずはGioのinstallを行います。
```terminal
go install gioui.org/cmd/gogio@latest
```

次にmain.goファイルです。
今回はGioに書かれているサンプルをそのまま持ってきます。
```go
package main

import (
	"image/color"
	"log"
	"os"

	"gioui.org/app"
	"gioui.org/op"
	"gioui.org/text"
	"gioui.org/widget/material"
)

func main() {
	go func() {
		window := new(app.Window)
		err := run(window)
		if err != nil {
			log.Fatal(err)
		}
		os.Exit(0)
	}()
	app.Main()
}


func run(window *app.Window) error {
	theme := material.NewTheme()
	var ops op.Ops
	for {
		switch e := window.Event().(type) {
		case app.DestroyEvent:
			return e.Err
		case app.FrameEvent:
			gtx := app.NewContext(&ops, e)

			title := material.H1(theme, "Hello, Gio")
			maroon := color.NRGBA{R: 127, G: 0, B: 0, A: 255}
   
			title.Color = maroon
			title.Alignment = text.Middle
			title.Layout(gtx)

			e.Frame(gtx.Ops)
		}
	}
}
```

最後に依存関係の更新をします。
```terminal
go mod tidy
```

## 起動させる
先ほど作ったmain.goファイルを実行してみます。
```terminal
go run .
```
するとこのように起動します。

![スクリーンショット 2024-12-06 2.31.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271450/bf8241d1-5b1f-e566-13ff-216bf531e75b.png)

サンプルコードでどのような処理が行われてGUIが起動していくか見ていきます。

```go
func main() {
    go func() {
        window := new(app.Window)
        err := run(window)
        if err != nil {
            log.Fatal(err)
        }
        os.Exit(0)
    }()
    app.Main()
}
```
この部分では、main関数はアプリケーションループを起動してOSとやり取りし、ウィンドウの動作を別のゴルーチンで開始しています。

```go
theme := material.NewTheme()
```
次の処理ではテーマを使ってウィンドウ内のUIを設定しています。

```go
for {
	switch e := window.Event().(type) {
	case app.DestroyEvent:
		return e.Err
	case app.FrameEvent:
    ...
```
`app.DestroyEvent`はユーザーが閉じるボタンを押した時に処理されるコードになっており、`app.FrameEvent`はプログラムが入力を処理し、新しいフレームをレンダリングする処理になっています。このようにして、各イベントに応じた処理を行うことで、アプリケーションの動作を制御します。

```go
// このグラフィックスコンテキストはレンダリング状態を管理するために使用されます。
gtx := app.NewContext(&ops, e)

// 適切なテキストで大きなラベルを定義します。
title := material.H1(theme, "Hello, Gio")

// ラベルの色を変更します。
maroon := color.NRGBA{R: 127, G: 0, B: 0, A: 255}
title.Color = maroon

// ラベルの位置を変更します。
title.Alignment = text.Middle

// ラベルをグラフィックスコンテキストに描画します。
title.Layout(gtx)

// 描画操作をGPUに渡します。
e.Frame(gtx.Ops)
```
最後にGUI上に表示するtextの処理です。
サンプルではtextですが、他にもinputだったりbuttonなどの描画も可能です。

## まとめ
初めてGioを触ってみましたがドキュメントが丁寧に書かれているのでGo歴が浅い私でも簡単に扱えました。
Gioを使って作られたGUIがドキュメント内にあったりするので、それを参考に自分が作りたいGUIを作ってみるのは良さそうです。
https://gioui.org/doc/showcase

## 最後に
株式会社HRBrainでは新しいメンバーを募集中です。
興味がある方は下記のリンクから宜しくお願い致します。

https://www.hrbrain.co.jp/recruit
工学・数学の計算をサポートするWindowsアプリ

# 私が開発した関数電卓と他社製品との違い

<Hyperlink>https://coconala.com/services/3510476</HyperLink>

## はじめに

昨日、私が開発したWindows向け関数電卓ソフトの記事を投稿したモノになります。
本日は他社製品との違いを紹介させていただきます。
プライバシーポリシー等によって、どこの何と比較しているかは伏せさせていただきますので、そこだけご了承いただければと思います。

## 表計算ソフトとの比較

まずはビジネスや研究などでよく利用されている、表計算ソフトとの違いを紹介させていただきます。
某表計算ソフトは、数値を扱うための多機能で柔軟なツールです。基本的にはセルに数式を入力し、他セルの値を使用して複雑な計算を自動で行うことができますが、数式を理解するのに一定の知識が必要です。また、複雑な数学的な計算においては、式の見やすさや計算結果の解釈に困難が生じることもあります。

一方、私が開発した関数電卓は、直感的なインターフェースを提供しており、特に数式の入力においては、より数学的な表記に近い形式で計算を行うことができます。例えば、平方根や指数関数など、数学的な演算を簡単に入力することができ、計算結果もそのまま見やすく表示されます。

例えば、某表計算ソフトで根号（ルート）の計算を行う場合は以下のように関数を書きます。
ex) =sqrt(9)
これで正の解である3が返されます。

これを私が開発した関数電卓で計算する場合、以下のように関数を書きます。
![pic_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953334/0c87f41c-ecf6-2484-4ffd-eb7b4523aff8.png)

根号の計算は数学的に書くと根号の中に9と書くため、直感的に式を入力することが出来ます。

某表計算ソフトの数式は非常に柔軟で強力ですが、長い式や複雑な式では、他のユーザーと共有した際に理解しにくくなることがあります。私が開発した関数電卓では、こういった式の入力や結果が直感的にわかりやすく表示されるため、誰でも簡単に使えるというメリットがあります。

また、某表計算ソフトでは根号の中に負の値を入れて計算を行うと「#NUM!」を返します。
通常、根号の中に負の値を入れて計算を行うことは多くないと思いますが、工学の世界では頻繁に出てくるものになります。

私が開発した関数電卓で計算を行うと以下のような解が得られます。
![pic_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953334/e5fca37d-aa42-f74b-96c7-414a42ad66e0.png)

数学的には√[-81]＝9iとなりますが、実部に非常に小さな実部の値が計算結果に含まれています。
これはプログラム言語による誤差（浮動小数点で計算を行うため）になります。プログラム内部では内部的に極形式やオイラーの公式で計算を行うため、私の関数電卓では、複雑な計算を行う際に、ごくわずかな計算誤差を生じることがあります。これは、数値をコンピュータで処理する際に、計算結果が非常に小さな数値に近づくことが原因です。こうした微小な誤差は、通常の使用にはほとんど影響を与えませんが、技術的には避けられない現象です。

こういった微小な誤差を丸めることは可能ですが、非常に小さいオーダーの計算を行う場合に0となってしまうことから、丸めを行っていません。

また、某表計算ソフトで関数を記述する場合、新たに関数を覚える必要がありますが、私の関数電卓では、数学の式に即した形で入力ができるため、特別な学習や新しい関数を覚える負担が少ないと考えています。

以上の記事から、私が開発した関数電卓ソフトに興味を持っていただけた方は以下のリンクにて販売をしていますので、是非ご確認いただければと思います。

<Hyperlink>https://coconala.com/services/3510476</HyperLink>
起業するならElixirシリーズSTEP10. 経営者へのステップアップ


## 経営戦略

はじめに伝えると、起業フェーズの能力と経営フェーズの能力は全くもって違う能力です。
ここまでのステップは起業フェーズ、0 -> 1 の進め方でした。

ここからは、「経営」に入っていきます。経営フェーズに入ると、戦略が重要になってきます。そこで、Mission, Vision, Valueが大切になってきます。

会社が達成すべきMissionに向けて計画を作る方法は、Missionを達成するための戦略を作っていく事になります。VisionはMissionに向かって進める中期的な活動です、より具体的な目標を作りMissionを達成するために必要な計画の目標を作ります。

例えば、弊社のMissionは「すべての人がテクノロジーを使いこなし、イノベーションを創出する力を教え育てる」ということにしました。この言葉からは「すべての人」「テクノロジー」「イノベーションを創出」というキーワードが入っています。次に「教え、育てる」というキーワードが入ってます。

これらを考える必要があるため、１つ１つ丁寧に言語化していきます。

「すべての人」とは具体的にどのような事かを考えます。すると結構幅広い範囲を扱う宣言をしてるとわかります。

年齢層: 子供から高齢者まで
職業: 学生、会社員、自営業、主婦/主夫、定年退職者など
技術レベル: 初心者からエキスパートまで
地理的範囲: 都市部/地方在住者/海外在住者
特別なニーズがある人々: 障害のある方、多言語話者など

「テクノロジー」とは？

デジタル機器: スマートフォン、PC、タブレットなど
ソフトウェア: 基本的なアプリから専門的なツールまで
インターネットサービス: SNS、クラウドサービス、オンラインショッピングなど
新興技術: AI、IoT、ブロックチェーン、AR/VRなど
基礎的なデジタルリテラシー: 情報セキュリティ、プライバシー保護など

「イノベーションを創出する力」とは

問題発見能力: 社会や身近な課題の認識
創造的思考: 新しいアイデアの発想
実践力: アイデアの具現化、試作品の作成
分析力: データの収集と解析
コラボレーション: チームでの協働、異分野との連携
失敗からの学習: 試行錯誤を重ねる姿勢

「教え育てる」アプローチとは

段階的学習: 基礎から応用へのステップアップ
実践的教育: 実際の課題解決を通じた学び
個別対応: 学習者の特性や目的に合わせた指導
コミュニティ形成: 相互学習の場の提供
継続的サポート: フォローアップと成長支援
評価とフィードバック: 進捗の確認と改善

とこのように掘り下げていくと、組み合わせも含めてやることの幅は広い分けです。これをどのような順番で、何から進めていくと効率的に効果的に実現するのか、また資金も重要な要素なのでどのような進め方をすると実現するのかについても考えていく必要があります。

## 経営者へのステップアップ

ちなみに、私の経験は0 -> 1フェーズが多く、今までにこのフェーズばかりやってきました。なので、経営者フェーズは私も挑戦し始めたばかりです。人を雇用し始めて初めて分かった事もたくさんあります。

環境も違えば、集まる人も違う。そんな中で過去の経験を活かせるものと、そうでないものを見極めて新しく学ばなければならない事は真摯に学ぶ必要が出てきます。

起業フェーズでここまで進めてきた能力とは違う能力が必要になるため、ここで起業家から経営者へのリスキリングが必要になります。

次回は、このリスキリングで私が学んで、今実践している事に触れていきます。

## Elixirコーナー

今回のElixirコーナー

https://qiita.com/Yoosuke/private/d8f981c930f09767ec96
React/vite環境でTailwindcss/を使うための設定


### 1. TailWind CSSのインストール
```terminal:terminal
npm install -D tailwindcss
npx tailwindcss init
```
### 2.tailwind.config.jsの編集
```diff_javascript:tailwind.config.js
/** @type {import('tailwindcss').Config} */
export default {
+  content: ["./src/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

### 3.index.cssの編集
```css:index.css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

### 4.vite.config.jsの編集
```diff_javascript:vite.config.js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
+import tailwindcss from "tailwindcss";

// https://vite.dev/config/
export default defineConfig({
  plugins: [react()],
+  css: {
+    postcss: {
+      plugins: [tailwindcss()],
+    },
+  },
});

```
Qiita アップデートサマリー - 2024年 11月

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/655039af-7182-e184-03c8-f3b7004b4e75.png)

## はじめに
Qiitaでは、エンジニアのみなさんからの声をもとに、日々開発を続けています。
この記事では、2024年 11月にリリースした内容を紹介します。

Qiitaでアップデートやバグ修正をリリースしたら、[リリースノート](https://qiita.com/release-notes)、[Qiita 公式 Twitter](https://twitter.com/Qiita)、[Qiita Blog](https://blog.qiita.com/)でお知らせしています。

また、Qiitaへの質問や機能の要望などがありましたら、[Qiita Discussions](https://github.com/increments/qiita-discussions) へご投稿ください。

## **Organizationが紐づけられた記事のOGP画像にOrganizationのアイコンを追加しました**
*2024年11月20日リリース*

Organizationが紐づけられた記事のOGP画像にOrganizationのアイコンを追加しました。

![変更前と変更後のOGP画像。変更後のOGP画像ではOrganizationアイコンが表示され、投稿者のOrganizationが識別しやすくなっている](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/adcbd10c-eaf5-e79d-25ec-120d33cac073.png)


## **:christmas_tree: アドベントカレンダーに関するアップデート**
### **Headerにクリスマスツリーを追加しました**
*2024年 11月1日 リリース*

HeaderのQiita ロゴの隣にクリスマスツリーを追加しました🎄

![変更前と変更後のHeaderのスクリーンショット。変更後のHeaderには、Qiitaロゴの隣にクリスマスツリーとプレゼントのアイコンが追加されている](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/6b3c133f-93f5-86f7-3f44-3cd09e9ba54a.png)



### **全てのカテゴリーランキングを削除し、各カテゴリーのランキングをまとめたページを追加しました**
*2024年 11月29日 リリース*

アドベントカレンダーのカレンダーランキングページから全てのカテゴリーを削除し、各カテゴリーの1位〜3位をまとめたページを新しく追加しました。

![変更前と変更後のランキングページ画像。変更後のランキングページでは各カテゴリーの3位までが表示されている](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/f6ea620a-4005-ac4a-ae05-2349e8744639.png)
【まだ見ぬスポーツの魅力を発見しよう！】AIがパラスポーツの魅力を紹介するサイト

# はじめに
この記事は株式会社スピードリンクジャパンのアドベントカレンダー10日目の記事です。

https://qiita.com/advent-calendar/2024/slj

今回は、まだ見ぬスポーツの魅力を知ってほしい！という思いからMarkdownAIを使って、キーワードを入れると、パラスポーツの名前や特徴が出てくるサイトを作成したので、その内容を紹介したいと思います。

# この記事を書こうと思ったきっかけ
今年は、パリオリンピック、パラリンピックの開催やメジャーリーグなど、スポーツの話題が多い1年だったと思います。
その中で、私はパラリンピックに着目しました。
皆さんはパラリンピックをどのぐらい試聴したでしょうか？
民放テレビではニュースとして取り上げられることはあっても、生放送は見る機会が少なかったのではないでしょうか。
そこで、パラリンピックではどのような種目が行われていたのか、パラリンピックの公式種目ではなくても、他にどんなスポーツがあるのだろうと気になり、調べてみました。
すると、魅力のあるスポーツを多く見つけることができました。
そこで、より多くの人にも知ってほしい！と思い、この記事を書くことにしました。

# サイトの特徴
入力欄にスポーツに関するキーワードを入力して検索すると、そのキーワードに関連するスポーツの名前と特徴が表示されるサイトです。

# 作成の工程
以下では、どのようにサイトを作成したのか紹介していきたいと思います。

## ステップ1：タイトルと説明文を作成
まず、見出しとしてサイトのタイトルをつけ、その下に説明を書きます。

## ステップ2：入力欄とボタンを作成
次に、入力欄と検索ボタンを追加します。

## ステップ3：AIの用意
### サインアップ
まず、以下のサイトでサインアップします。

https://mdown.ai/

### サイトを作る準備
ダッシュボードから新しいサイトを作ります。

### サイトの内容を実際に書く
見出しや説明文、入力欄やボタンあど、サイトに必要な基礎的な内容を書いていきます。
ここでは、マークダウン形式でも簡単に記載ができるので、プログラミングをまだやったことがない人でも、簡単に作ることができます。

### AIの導入
実際にビュー画面で確認をしながら基礎的なコードが書き終わったら、AIを導入します。
手順は以下の通りです。

* createボタンをを押して導入に必要な項目を入力
* AIの種類を選択肢、モデルの名前をつける。（ここは複数作った時に、どの内容のAIかがわかれば良いです。）
* プロンプトを入力
プロンプトとは、AIにどのような回答をしてほしいかを指示するために入力するもの。
今回のサイトでは以下のように記載。

**スポーツに関するキーワードが入力されたら、そのキーワードに関連するパラスポーツを回答してほしい。答えは、スポーツの名前、特徴の順番で表示してほしい。**

* createボタンを押して作成
* 作成後、insert→scriptの順に押して作ったAIを選択
* insertボタンを押して記事内に追加
* 必要に応じて微調整をして、導入完了

## ステップ4：内容を確認して公開
ビューで内容を確認したら、URLを発行し、公開できます。
AI導入の詳細は以下からも確認できます。

https://qiita.com/mdown_ai_jpn/items/d3e281565c876a0bd64f#%E5%AE%9F%E9%9A%9B%E3%81%AB%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86ai%E5%88%B6%E4%BD%9C%E6%89%8B%E9%A0%86

# 実際に作ったサイトはこちら

![スクリーンショット 2024-12-06 10.45.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3787065/c1c63022-d4a6-e0a1-c2b0-97cdd2d7c469.png)


[まだ見ぬスポーツの魅力を発見しよう！](https://mdown.ai/content/97b23e0b-c0e9-4a72-a331-a927904dc749)

# 実際の検索結果
今回はサッカーというキーワードを検索してみようと思います。
結果は以下のとおりです。
![スクリーンショット 2024-12-08 21.34.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3787065/f2d7fb0d-da9b-3da9-a3a8-72f5424c0c3e.png)


# 最後に
今回は、MarkdownAIを活用して記事を作成してみました。
今回は最低限の機能しかありませんが、今後、プルダウンを使ってジャンル分けできるようにしたり、季節で分類できるようにしたりと、より分かりやすいものにしていけたら良いなと思っています。
ここまで読んでいただきありがとうございました。
【アドベントカレンダー2024】アウトプット活動の大切さ

いつも記事を読んでいただきありがとうございます！
モブエンジニア（[@mob-engineer](https://qiita.com/mob_engineer))です！

今回は、**はじめてのアドベントカレンダー Advent Calendar 2024**企画として「アウトプット活動の大切さ」について記事をまとめたいと思います。

ぜひ、最後まで読んでいただけますと幸いです。

:::note info
本記事は私が行っているアウトプット活動に関する考え方をまとめた記事となります。私の経験に基づいて記事を執筆していますが、**読者の皆さんでも理解できる**ことを目標に平易な表現を心がけています。わかりづらい表現などがありましたら、遠慮なくコメントをいただけますと幸いです。
:::

# 目次
1. 本記事を読んでもらいたい読者層
1. アウトプット活動が大切だと感じた理由
1. 私が感じたアウトプット活動のメリット
1. アウトプット活動を続けるためのポイント
1. まとめ

## 本記事を読んでもらいたい読者層

アウトプット活動に関して次のような悩みを抱えている方に読んでいただければ幸いです。

1. アウトプットすることの大切さを少しでも理解したい方
1. アウトプットするネタをなかなか見つけられない方
1. アウトプット活動に対して自信を持てていない方

## アウトプット活動が大切だと感じた理由

最近では技術ブログやLT登壇などのアウトプット活動を行っていますが、ほんの1か月前からです。
それまでは、アウトプット活動に対してほとんど熱量を持っておりませんでした。（社内での記事配信を行っていましたが、社外向けはほとんど行っておりませんでした）

そんな、アウトプット歴としてはそこまで歴を重ねていない私ですが、私なりにアウトプットが重要な理由をいくつか整理したいと思います。

### その１：知識の定着率が段違いによくなる

技術者として**知識のキャッチアップ**は必要不可欠です。なぜなら、数多くの技術を効率的にキャッチアップしながら、**ビジネスへ落とし込んでいくこと**を生業としているからです。

そのうえで、**キャッチアップ効率**をどうしても考える必要があるかと思います。

知識をインプットするだけでも、もちろん、定着させることは可能ですが、時間がかかってしまいます。さらに、**インプット活動は個人に閉じてしまっている**側面があるため、**他者からのフィードバックを得られにくい**です。

そのため、**他者に伝えるといった営みとしてアウトプット活動を行うこと**で自身の知識を**解像度高くすることができる**のではないかなぁと追っています。

### その２： 自身の持っている知識を他者へ伝えやすくなる

その１とも関係しますが、アウトプット活動を通じて**他者からどのようにフィードバックされるのだろうか**を意識するようになります。

その結果として、**さらなるインプット活動の推進**と**身につけた知識の解像度を向上させる**ことにつながると考えています。


### その３：　新たなコミュニケーション機会の創出

アウトプット活動を行うことで、見知らぬ技術者から良質なフィードバックを得られやすくなります。さらに、フィードバックを通じて、新たな交流機会を創出するきっかけにもつながるかと思います。

## アウトプット活動を続けるためのポイント

アウトプット活動を続けるためのポイントとしていくつかありますが、一つだけ言えることは**継続して行ってみよう**だと思います。

そのうえで、アウトプット活動に疲れてきたら休んでもいいのかなぁと思います。

## まとめ

記事としては短い内容ですが、アウトプット活動の大切さについて、1%でもしていただければ幸いです。

最後まで、記事を読んでいただきありがとうございます。
入門 モダンLinux ―オンプレミスからクラウドまで、幅広い知識を会得するを読んだまとめ

# 入門 モダンLinux ―オンプレミスからクラウドまで、幅広い知識を会得する
Linuxとは何ぞや？というところからLinuxにアプローチした本。

Linuxを体系的に知るという意味では最初の一冊にしていいと思う。以下セクションの印象

1. [1章 Linuxの入門](#1章-linuxの入門)
1. [2章　Linuxカーネル　の全般](#2章linuxカーネルの全般)
1. [3章　シェルとスクリプト](#3章シェルとスクリプト)
1. [4章 アクセス制御](#4章-アクセス制御)
1. [5章 ファイルシステム](#5章-ファイルシステム)
1. [6章　アプリケーション、パッケージ管理、コンテナ](#6章アプリケーションパッケージ管理コンテナ)
1. [7章　ネットワーク](#7章ネットワーク)
1. [8章　オブザーバビリティ（可観測性）](#8章オブザーバビリティ可観測性)
1. [全体を読んで](#全体を読んで)

## 1章 Linuxの入門

モダンLinuxとは…　電話、データセンター、ラズパイなどのモダンな環境で使用されるLinux。

## 2章　Linuxカーネル　の全般

そもそもLinuxについて知ってるのがCUI操作ぐらいしかないところから読んだので、全部新鮮だった。

低レイヤーの話ってWebであまり見ないから、こういうのを知るのは書籍ベースの方がいい。

ファイルシステムを構成するものもファイルである…みたいなのは、言われてみれば当たり前なんだけど意識してない　その「意識させない」がOSの役割の一つなんだろう。

## 3章　シェルとスクリプト

Linuxやるなら避けて通れないやつ　ハンズオン大事なセクション、手を動かして覚えるところ

## 4章 アクセス制御

sudo必要なときに意識する　/etc内のファイル触るとき（とくにnginxの設定時）に気をつける

AWS等と同じで、必要な権限を必要なユーザーに与えることが重要

## 5章 ファイルシステム

ドライブやパーティション、論理ボリューム、カーネル、ファイルシステムについて。

必要なときに参考にするぐらい

## 6章　アプリケーション、パッケージ管理、コンテナ

特にコンテナ。今の開発なら絶対見ときたいとこ。

コンテナ＝Docker　ではない

## 7章　ネットワーク

TCP/IP、IPv4・IPv6、ソケット等について。Linuxで使用されるアプリケーション層のプロトコルとインタフェースについて。

この章も手を動かして学ぶところ。

## 8章　オブザーバビリティ（可観測性）

Linuxで問題が発生したときにリソースを観測し、診断を行う。

「中身が見える」OSであることが重要かと。

## 全体を読んで

Linuxの参考書＋チュートリアル＋ハンズオンという書籍という印象。

手元に置いて、必要なときに読む＆学習に使用できればと思った。
QA視点でもマスタの作りを気にしてみた

# はじめに
皆さま、こんにちは。
突然ですが、QA業務に携わる方は、日々マスタデータ（以下「マスタ」）の資料を確認する機会が多いのではないでしょうか。
私自身もその一人で、実機での挙動確認と同じくらい、マスタをしっかりと確認することが重要だと感じています。

プロジェクトの早期にアサインされることが多いのですが、
その際はデータ内容そのものではなく、入力のルールやマスタの作りといった根幹の部分にまず目を向けるようにしています。
その際は以下の2点の観点で確認しています。

1. スプレッドシートなどでツールを作成する時に作りやすい構造か
2. 運用を考えた時に不具合が起きやすい作りになっていないか

上記を観点として確認を進める中で、異なるプロジェクトであっても似たような指摘をすることが多く、最近ではこの観点に共通性があり有効であると感じるようになりました。
そのため、これまでの経験をもとに、上記2点の観点で早期にマスタ確認をした際の、QAからよく指摘する事例をまとめた記事を書いてみました。
このまとめが少しでも役立てば幸いです。ぜひ参考にしてみてください。

# 前提
主に下記の前提での記述となります。
- ゲームのQAで日々マスタデータを参照する方向け
- マスタがスプレッドシートでの管理の前提
※Excelなどでも参考になる部分はあると思います

# なぜマスタをQAでも事前に確認したほうがよいか
#### 後から修正を行うとリスクが高い
入力のルールやマスタの作りにフォーカスして確認するので、修正した時の影響範囲が大きい場合が多く、運用に入ってから修正するにはリスクが高く、さらに影響確認のコストも増加します。

#### QA視点で検証しやすい環境が早期に作りやすい
普段の検証に使用する際に確認しやすかったり、ツールを作る際、困らない作りにすることで無駄なコストを省くことができます。

#### 不具合の作り込みリスクが減少する
そもそもマスタの入力ミスに繋がりにくい仕様にすることで、マスタ起因の不具合の作り込みを防止することができます。


# 実際の事例とそのリスク
実際に共通しているなと感じた事例を下記で4つご紹介します。

#### ①カラム名が記載される行が統一されていない
危険度　★★☆☆☆
![スクリーンショット 2024-12-05 22.38.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542716/90fadac5-6f83-c6e6-428b-4ba70e2e36b8.png)

画像のようにシート毎や各マスタ毎で、カラム名が記載されている行が統一されていないことがあります。基本的に実際の入稿時に問題になることは少ないですが、QA側でツールを作る際の関数で調整する際に、少し不便になることが多いです。(index/matchなど
個人的には上部の空白行は無い、もしくは2~3行までが良いかなと思います。
- 防止できる可能性があるリスク
  - 統一する規則がないのでフランクに行を挿入してしまい参照ズレを起こす

#### ②IDなどがText形式になっている
危険度　★★★☆☆
![スクリーンショット 2024-12-05 23.58.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542716/973cabeb-3815-b7e3-8277-0da773fec94a.png)

基本的にIDなどの数値部分はText形式で入力されるべきで無いと思っています。
気持ちはわからなく無いですが、「=10000+B21」のようにして数値形式を崩さずに入力されている方が良いと思います。
Text形式だとlookup系の関数を使用する際、Valueを使用するなど少し工夫が必要になります。
さらに画像のように100009から1000010のように桁が飛んでしまうこともあります。
- 防止できる可能性があるリスク
  - IDを参照する関数を使用する際、Text形式を考慮できずErrorが出力される

#### ③関数を使う列に一部直接入力されているものがある
危険度　★★★★☆
![スクリーンショット 2024-12-06 0.32.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542716/f5f0e584-b6f4-703a-2c41-1ced08e7687e.png)

よくマスタの入稿担当がコピペミスを起こす時、この原因も多いと思います。
いろんな人が入力するマスタほど、起こりやすい問題と感じます。
- 防止できる可能性があるリスク
  - 行をコピーして使用する入稿担当が見落として、IDが重複したり、意図しないIDとなる

#### ④条件付き書式が多すぎる
危険度　★★★☆☆
![スクリーンショット 2024-12-06 1.23.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542716/5cb5b146-682e-3765-c390-ec157581756a.png)

目視でミスしにくいなどのメリットがあるのですが、入力量が膨大なマスタではあまりお勧めしません。
ただでさえ、関数などで少し重めなマスタに条件付き書式が大量に入ることで、シート自体の読み込みがさらに重くなり、反映のミスにつながりやすいです。
重複だけを検知する条件など、使用する条件を絞ったり、どうしても目視で見やすくしたい場合は、別のシートにチェック用として場所を作り、そこで使用するのが良いかと思います。

- 防止できる可能性があるリスク
  - セルの入力を行ったが、反映が上手くいかずに反映ミスが起こる

# まとめ
1. スプレッドシートなどでツールを作成する時に作りやすいか
2. 運用を考えた時に不具合が起きやすい作りになっていないか

上記の観点を確認することで、事例のような問題をより容易に発見できると考えます。

これらを踏まえ、可能であれば、ルールを作成する段階でQAが同席し、他部門と連携して共同で策定を行うことで、ルール自体の妥当性や運用のスムーズさが向上すると思います。

今回早期に確認するという名目で記載していますが、すでに運用が長期間行われているプロジェクトについても、一度見直しの機会を設けることで、現状のリスクを把握し、必要に応じて改善点を見出すことができます。たとえ修正が難しい場合であっても、潜在的なリスクを認識するだけでプロジェクト全体の安定性向上に寄与するはずです。

マスタの確認作業には多少の手間が伴いますが、その効果はプロジェクトの品質と効率性を高める上で非常に大きいと考えられます。
ぜひ、積極的に取り組んでみてください。
初めての自動テスト ―Webシステムのための自動テスト基礎を読んだまとめ

# 初めての自動テスト ―Webシステムのための自動テスト基礎
アジャイル開発に絶対必須の自動テスト。そのとっかかりになりそうな本です。

いわゆる「テストピラミッド」をベースに話が進んでいく。

1. [第1部　ピラミッドの地図を作る](#第1部ピラミッドの地図を作る)
    1. [1章　テストのピラミッド](#1章テストのピラミッド)
    1. [2章 ユーザーインターフェイステストに触れる](#2章-ユーザーインターフェイステストに触れる)
    1. [3章 レガシーシステムにUIテストを導入する](#3章-レガシーシステムにuiテストを導入する)
    1. [4章 統合テストで点と点を結ぶ](#4章-統合テストで点と点を結ぶ)
    1. [5章 RestfulなWebサービスの統合テスト](#5章-restfulなwebサービスの統合テスト)
    1. [6章 ユニットテストで基礎を固める](#6章-ユニットテストで基礎を固める)
    1. [7章 JavaScriptを使ったブラウザ上のユニットテスト](#7章-javascriptを使ったブラウザ上のユニットテスト)
    1. [8章 ピラミッドを登る](#8章-ピラミッドを登る)
1. [第2部 ピラミッドを探索する](#第2部-ピラミッドを探索する)
    1. [9章 プログラミング初級講座](#9章-プログラミング初級講座)
    1. [10章 テストを整理する～混沌の中から法則を見つけ出す～](#10章-テストを整理する混沌の中から法則を見つけ出す)
    1. [11章 効果的なモックの活用](#11章-効果的なモックの活用)
    1. [12章 テストファースト](#12章-テストファースト)
1. [まとめ](#まとめ)

## 第1部　ピラミッドの地図を作る

### 1章　テストのピラミッド

美しいテストを作ったのに壊れた話。
ユニットテストの代わりにUIテスト→重くなる→エラーが見つけづらくなる、テスト実行を嫌がりだす→壊れたまま作り続ける→崩壊…

3つの教訓

- テストの種類ごとに向き不向きがある
- 「書ける」と「書くべき」は一致しない
- テストケースの実行時間が長くなると、反復回数は減る。

UIテスト（Cypressなど）は、アプリケーションを全体通して見てくれていい感じに見えるけど、コストが高い（重い＆壊れやすい）

統合テストは、UIを通過しないのでUIが壊れていても通せる　が、どこが壊れてるかは分かりづらい

ユニットテストは、とにかく速く、どこがだめだったかすぐわかる。ただし、つながりの部分については弱い

まずユニットテストを書いて、そこから統合→UIと進めていこう。

ユニットテストは開発のため、UIテストは検証のためのもの。

自動テストの作成を誰が行うか？開発者とテスターは立場が違い、重視するところが違う

→協調して行おう。テスターも自動テストを書こう、開発者もテスターの生産性を上げよう。

### 2章 ユーザーインターフェイステストに触れる

UIテストの仕組み：HTMLとCSSのタグを使って要素を取得し、アサーションを入れよう

### 3章 レガシーシステムにUIテストを導入する

既存のHTML、CSSを使用して要素を取得する方法を学ぶ。

### 4章 統合テストで点と点を結ぶ

UIがなくても、リクエストを作成する方法がわかれば統合テストが作成できる。

### 5章 RestfulなWebサービスの統合テスト

GET、POST、PUT、DELETEをリクエストを作成してテストする。

### 6章 ユニットテストで基礎を固める

ユニットテストは非常に高速。ただ、局所的なものなのでネットワークが絡むところは避けたほうがいい。

モック化大事！

### 7章 JavaScriptを使ったブラウザ上のユニットテスト

ブラウザで起きていることをユニットテストで確認することができる。UIテスト＝E2Eではない。

### 8章 ピラミッドを登る

３種類のテストの得意分野で勝負する。

- 大部分はユニットテストで。
- 統合テストでは接続の部分に注力、ユニットテストでカバーできないところを対応。
- UIテストは限定的に。壊れやすいことを忘れずに。

## 第2部 ピラミッドを探索する

### 9章 プログラミング初級講座

マジの初級講座なので割愛。

### 10章 テストを整理する～混沌の中から法則を見つけ出す～

テストを全部同じとこにまとめると後で大変なので、整理することが必要。

### 11章 効果的なモックの活用

必ずしもモックを使う必要はない。現物が使えるならそれで良し。

使いやすいものではあるけど、頼りすぎないようにする。

### 12章 テストファースト

TDD（テスト駆動開発）について。銀の弾丸ではないので、自分でしっかりコードを書こう。

## まとめ

テストは大事だけど、やみくもにやってても壊れやすいテストになり、維持できなくなってしまう。

ユニットテスト、統合テスト、UIテストのそれぞれの特性を知り、適切に組み立てよう。
AndroidStudioの参考書：最初のレイアウトファイル編集の際にエラーが出た時の対処

## 参考書：アンドロイドアプリ開発の教科書
この参考書の最初の方で**activity_main.xml**の内容を一部を残して消し、追記するという処理があるが、その指示に沿って内容を変更したら**MainActivity.java**にてエラーが発生した。

:::note info
**その時対応したこと**
:::


バージョン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953063/2bc4b5c7-7978-193f-f7d9-d937d0296f86.png)

各種設定は本の内容に沿って行った。
<br></br>
新規プロジェクト作成時のactivity_mainの内容
~~~xml:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
~~~
<br></br>
~~~xml:指示に沿って内容を変更した後
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</LinearLayout>
~~~
<br></br>
エラーが出ているみたい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953063/13d47273-8f92-cdcb-9878-9e13c7fcdda4.png)

エラーか所
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953063/7e97b1cd-1036-b697-20e3-5f38e958636a.png)


~~~java:グレーが消去箇所
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //EdgeToEdge.enable(this);消去
        setContentView(R.layout.activity_main);
        /*消去
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
        Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
        v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
        return insets;
        });
        */
    }
}
~~~

これでエラーが無くなり参考書と同じ状況を作れている。ハズ…