OmniAICreator/Qiita-1.07M huggingface dataset:
【Vue3】2つのAPI スタイル：Options APIとComposition API 

## はじめに
以前Vue2と3を勉強していた際、見ている教材によって書き方が違うことから躓いてしまったことがあった。
その躓いた点が2つのAPIスタイルの違いだったのだと先輩から教えてもらい、改めて整理することが必要だと感じた。

Vueのチュートリアルで学んだこと、自分で調べたことをまとめていく。
メリット・デメリットなどはGeminiに聞いてみた。

## APIスタイルとは

- API (Application Programming Interface)とは
異なるソフトウェア同士が互いに通信し、機能を利用するためのインターフェースのこと。

- Vue.jsで言われる「APIスタイル」とは
Vue.jsが提供するコンポーネントを作成するための様々な機能やメソッド（つまりAPI）を利用するスタイル。

コンポーネントを作成する際に、これらのAPIをどのように組み合わせて使うかによって、コンポーネントの構造や書き方が変わる。

## 2つのAPIスタイル
Options API、Composition API と呼ばれる 2 種類の異なる API スタイルがある。

### Options API

```vuejs
/*  Options API Vue公式ドキュメントより */
<script>
export default {
  // data() で返すプロパティはリアクティブな状態になり、
  // `this` 経由でアクセスすることができます。
  data() {
    return {
      count: 0
    }
  },

  // メソッドの中身は、状態を変化させ、更新をトリガーさせる関数です。
  // 各メソッドは、テンプレート内のイベントハンドラーにバインドすることができます。
  methods: {
    increment() {
      this.count++
    }
  },

  // ライフサイクルフックは、コンポーネントのライフサイクルの
  // 特定のステージで呼び出されます。
  // 以下の関数は、コンポーネントが「マウント」されたときに呼び出されます。
  mounted() {
    console.log(`The initial count is ${this.count}.`)
  }
}
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>
```

#### 特徴
Vue.js 2.xから存在する従来からのスタイル。
`data`、`methods`、`mounted` といった数々のオプションからなる 1 つのオブジェクトを用いてコンポーネントのロジックを定義する。
これらのオプションによって定義されたプロパティには、コンポーネントのインスタンスを指す `this` を使って、関数内からアクセスできる。

#### メリット
直感的で理解しやすく、多くのチュートリアルやサンプルコードで採用されています。

#### デメリット
コンポーネントが大きくなると、オプションが散らばり、コードの可読性が低下する可能性があり、ロジックの再利用が難しい場合がある。

### Composition API
```vuejs
/*  Composition API Vue公式ドキュメントより */
<script setup>
import { ref, onMounted } from 'vue'

// リアクティブな状態
const count = ref(0)

// 状態を変更し、更新をトリガーする関数。
function increment() {
  count.value++
}

// ライフサイクルフック
onMounted(() => {
  console.log(`The initial count is ${count.value}.`)
})
</script>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>

<template>
  <button @click="increment">Count is: {{ count }}</button>
</template>
```

#### 特徴
Vue.js 3.xで導入された新しいスタイルで、コンポーネントのロジックを関数として定義する。
これにより、ロジックを再利用しやすく、コードをよりモジュール化できる。

-- 下記理解しきれていないので今度調べる。

:::note 
SFC において、Composition API は通常、`<script setup>` と組み合わせて使用します。setup という属性を付けることで、Vue にコンパイル時の変形操作を実行してほしいというヒントが伝えられます。これにより、定型的な書式の少ない Composition API を利用することができます。
:::


#### メリット
コードの再利用性が高く、大規模なアプリケーションでもコードの管理がしやすい。
ロジックを関数の形で分割できるため、テストが容易になる。

#### デメリット
慣れるまで少し時間がかかるかも。

## まとめ
### どちらを選ぶべきか？をGeminiに聞いてみた。
- シンプルなアプリケーション: Options APIで十分
- 大規模なアプリケーション、複雑なロジック: Composition APIがおすすめ
- チームでの開発: チームで統一したスタイルを採用することが重要


https://ja.vuejs.org/guide/introduction.html#api-styles
【Docker】いろいろpruneしてストレージを掃除する

## 概要
Dockerを使っていると溜まっていくvolumeやimage、中間データ等をまとめて消してお掃除します。

## 方法
以下を実行します。稼働中のコンテナなど参照が通っているものは消えないです。
```bash
docker container prune -f && docker image prune -f && docker volume prune -f && docker builder prune -f
```
上記コマンドは、以下4つを繋いで実行しています。
```bash
# 使ってないコンテナを削除 
$ docker container prune -f
# 使ってないイメージを削除 
$ docker image prune -f
# 使ってないボリュームを削除 ← 環境によっては大きな効果があるかも？ 
$ docker volume prune -f
# docker imageのビルド時に利用するキャッシュを削除！！ ← これが強烈 
$ docker builder prune -f
```
`-f`オプションは各コマンドがyes/noを聞いてくるのへ「ええから黙ってやれ」をやるオプション。みんなでprune-pruneしようぜ！

ちなみに、上記すべて実行後に`docker system prune`をやっても、dockerのnetworkが消えるだけで追加のダイエットは効きませんでした。
血液と数値流体力学




⚠ **記事の内容は学生個人の見解であり、所属する学科組織を代表するものではありません。**

# はじめに
どうもこんにちは。某です。
アドベントカレンダー18日目となりました！毎日面白い記事が投稿されていて楽しいですね。

最近サークルに新しく経済学部の方が加わってくれました。物理は経済学などいくつかの文系分野にも応用できそうで面白いので、ぜひ文系ユーザーも増えていってほしいなと思います。


今回は「**血液と数値流体力学**」について書いてみました。

あまり物理の人間にはなじみのない医学について色々見ていけたらと思います。

---

# 1. 数値流体力学（CFD）とは

まず、数値流体力学（CFD）とは、流体の運動を記述する**ナビエ-ストークス方程式**をコンピュータで解くことで現象をシミュレーションする手法です。これによって、空気の動きや恒星のガスの流れ、さらには微生物の体内での挙動など、さまざまな現象をシミュレーションし、可視化することが可能になります。

```math
\rho \left( \frac{\partial \mathbf{u}}{\partial t} + \mathbf{u} \cdot \nabla \mathbf{u} \right) = -\nabla p + \mu \nabla^2 \mathbf{u} + \mathbf{f}
```
ナビエ‐ストークス方程式は一般的な解析解が存在しないことから、理論的な計算では解くことができず、現実の問題に対しては数値的に解くことで近似解を求める必要があります。そこで、コンピュータの計算力を利用して流体の領域を細かなメッシュに分割して近似解を求める数値流体力学が用いられます。



![スクリーンショット 2024-11-27 235221.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624095/47958a12-cc21-e1e7-2529-991bd5e12ddc.png)

*流体解析ソフト「Open FOAM」を用いた二次元流の解析例*

---

# 2. 血液を解析する

近年、血液の流れを解析し、医学に役立てようという動きが活発になってきています。日本人の死因の三割は血管疾患（心筋梗塞、脳卒中など）ですが、これらの疾患の原因として血管の壁面せん断応力などが関係しています。また、心臓や大動脈などでは乱流が存在し、手術時などでは考慮する必要があります。このように、血流を流体力学の視点から解析することは重要といえそうです。

### 壁面せん断応力（WSS）とは？
壁面せん断応力は、血液が血管壁に及ぼす摩擦力のことです。この応力が低すぎると、血管の内皮細胞に異常が起こりやすく、動脈硬化や血栓形成の原因になると言われています。また、高すぎると、血管壁が損傷するリスクにつながったりします。

さらに、姿勢や運動の変化によって血流がどう変わるかを数値流体力学（CFD）でシミュレーションすれば、特異な環境に置かれた人が血管疾患を発症するリスクを予想できたりもします。

---

# 3. 血流解析の具体的手法

### 1. 血管形状のデータ取得（CT・MRI）
まず、CTやMRIを用いて患者の血管形状をスキャンし、3Dモデルとしてデータ化します。

### 2. メッシュ生成
血管形状データを元に、計算用の「メッシュ」（格子）を作成します。重要な部分は細かく、他は荒く設定することで効率よく計算します。

### 3. 数値シミュレーション
実際にシミュレーションを行い、結果を評価します。

---

# 4. 血流解析の課題

実際の血液の流れをシミュレーションするというのは簡単なことではなく、以下のような課題が存在しています。

- **拍動流の再現**: 血液は心臓の拍動に合わせて脈動的に流れるため、時間とともに流速や圧力が変化する「非定常流」として扱う必要があります。しかも拍動の挙動は一定ではないので色々と面倒です。

- **血管壁の弾性**: 血管は柔らかく、血圧に応じて変形する「弾性体」です。流体力学と構造力学を組み合わせた**流体-構造連成解析（FSI）**が必要です。

- **赤血球や血栓の挙動**: 赤血球や血栓などが血液中に含まれることから、血液は正しくは混相流ということになります。そのため、血栓の挙動や毛細血管の解析などは難易度がかなり高くなります。特に、赤血球に至っては血管を流れる際に柔軟に変形し、赤血球同士でも相互作用を起こすため、解析を一層難しいものとしています。


---

# 5. 実際の研究:**動脈瘤**のシミュレーション
　実際の研究として、東京大学の大島先生が中心となって行われている脳動脈瘤の血流解析に関する研究は血流解析を用いた臨床応用への新たなアプローチとして注目されている。


### 背景
 脳動脈瘤は、脳血管の分岐部などに生じる異常な膨らみであり、破裂するとくも膜下出血を引き起こします。動脈瘤の破裂リスクは大きさや位置によって異なり、その形成や破裂には 壁面せん断応力（WSS） を含む血行力学的要因が深く関与しています。
 

 ![WWS_gp_wavep-600x333 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624095/e100ce20-ca97-e2f5-37f0-387b0dc4f6ff.png)
 脳動脈瘤の流体構造連成解析
 (東京大学生産技術研究所大島研究室公式サイトより引用）

 
## 内容
 この研究では患者個別の血管形状にシミュレーションを行うことで、患者個人に対して、WSSの分布や圧力の局所的な集中を可視化し、動脈瘤の破裂リスクが高い部位を予測することが可能となりました。
 
## 臨床への応用
　このシミュレーション結果は、動脈瘤の破裂リスク評価や手術計画の立案に活用されており、患者個別の最適な治療方針の提案を目指しています。さらに、手術後の血行動態予測にも応用が期待されており、臨床診断支援システムとしての実現が視野に入っています。
 
---

# 6. まとめ
血流解析面白そうだよね！
おわり！

---

## 参考文献
- 「血流解析のすすめ」CARDIO FLOW DESIGN
- 「脳動脈瘤の血行力学」大島まり,石上雄太,早川基治
- 「粒子法を用いた赤血球の変形シミュレーション」田中正幸,越塚誠一


---
next/linkの<Link>が原因で無駄なレンダリングが発生していた。

### （注）ただの備忘録で何も解決してません。
_Markdown記法とタイピングに慣れるためとりあえず最後まで書き切って投稿しただけなので、なんら技術的解決もしてません。_


## \<Link>の使用でレンダリングが2回起きていた

\<Link>コンポーネントを使ってルートパスへの遷移を実装していたページのconsole.log()が、リロードの度に2回呼び出されていた。解決に時間がかかったのでメモしておく。(たぶんもう一回くらいこのミスしちゃいそう)

# 1,\<Link>の仕様
\<a>タグの遷移を高速にしてくれると聞いて脳死で乱用してたが、なぜ高速なのか

→ __遷移先のprefetch__

よって今回のケースでは、ルートパスをprefetchしていた。

そして、ルートパスでも\<Link>で当該ページ(/signin)への遷移を実装していた笑

そして、認可機能により、userSessionを持たない場合は/signinへの遷移を行っていた。

結果...

/signinのリロード　→ log出力 →　 __ルートprefetch(Linkによる)__ 　→ __\<Link href{"/signin"}>をprefetch__ → log出力(2回目)

なのかなと推理。　あちこち触って/signinの\<Link>→\<a>にするとレンダリングが1回になったからたぶんこれ...?


いや...。
書きながら思ったけど、prefetch先のLinkをprefetchしてるなら、無限ループで今PCは息してないはずなので多分この推理は間違えてる...笑

じゃあやっぱりsession管理やったりSeverActionsあたりの記述がミスってるんやろうか..?

眠気が限界なので、今日の備忘録としてこの怪文を。

始めてauth触ったことでわかってなかったとはいえ、初めにcontext作っとけばよかった。いい勉強になりそうね泣
dockerのクロスコンパイルが捗ったはなし

### はじめに ###
この記事はラクスパートナーズ Advent Calendar 2024の19日目の記事です。

今日は趣味開発で使っているラズパイ向けdockerimageを使った
クロスコンパイル環境のビルドについて検証・解説したいと思います

現在、モダンな組み込み対象機器の開発環境として
docker環境をx86(Windows、Mac、Linux)の性能がリッチなマシンで構築したのち、
実行ファイルのみをArmマシン(組み込み機器)に転送してデプロイ・テスト駆動する形式が流行っています。
今回は公開されているラズパイ向けdockerイメージをビルドすることでdocker環境上に開発環境を作成し、簡単なプログラムを実装する流れを書き下したいと思います。

自分はMacユーザーなので基本的にbrewを使ってラクをします。

使用機材
Hardware : MacBookPro early 2015 intel i5 2.7GHz
OS : Monterey 12.7.6

 ### 1.dockerのインストールと設定
上記はあまりにも記事があるので詳細には説明しません。
各種のOS環境に準じたdockerのセットアップを行い
``` docker -v ```　を実行して下記の表示が出れば大丈夫です。
``` 
% docker -v
Docker version 26.0.1, build d260a54c81 
```
もしも出ない時はHomebrewの下記コマンドなどでdocker環境を立ててください
docker構築時のマイナートラブルに注意してください、
ローカル環境をコメントいただければ返信にて対応したいと思います。

```
% brew install --cask docker 
```
詳しくは下記などを参考にすると良いと思います。

https://brew.sh/

https://formulae.brew.sh/formula/docker

### 2.ラズパイ向けのクロスコンパイル環境を作成する
1.にてdockerの構築はできたかと思いますので、2.ではdockerイメージ取得とビルドの環境構築をしていきます。
自分の環境に合わせるために、今回はDockerDesktopを使用せずに互換ソフトのcolimaを使用して行きます。
注記)2024/12現在ColimaはMITライセンスです。類似ソフトがApache系なので今後変更はあるかもしれません
(OP:Colimaのセットアップ　Mac向け)
```
brew install colima
:::note info
--このタイミングでDNS 8.8.8.8をホストマシンに設定しておく--
:::
colima start
```
### 3.githubで公開されているクロスコンパイルのdockerイメージをビルドする
今回は @ryoma-jp 氏が公開しているgithubリポジトリを利用させていただきました。

Raspi3互換のRaspiZero2Wで利用するため、安定している32bit版でのビルドを引用させていだだきます。

ホストマシン上(Mac)にて
```
% git clone https://github.com/ryoma-jp/samples.git
% cd samples/env/cross_compile/docker_armv7l/
% docker build -t env_xc_armv7l/ubuntu:22.04 .
% bash ./docker_run.sh
--以下はdockerコンテナ内--
# cd /work/sample_source
# make -f Makefile_for_xc_armv7l
arm-linux-gnueabihf-gcc -c -Wall -O3 -march=armv8-a -mfpu=neon -I./ -o build/main.o main.c
arm-linux-gnueabihf-gcc -static -o sample_armv7l ./build/main.o 
# file sample_armv7l
sample_armv7l: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), statically linked, BuildID[sha1]=d4c1d6a98a601d0f42932640effdafe41791c438, for GNU/Linux 3.2.0, not stripped
```

### 4.ビルドされた実行ファイルを手元に取り出して、ラズパイに転送して実行！

ホストマシン上(Mac)にて
```
docker cp [コンテナID]:/work/sample_source/sample_armv7l ホストマシンコピー先ディレクトリ
```

ラズパイ上に実行ファイルを転送して実行
Hardware : RaspberryPi Zero2W 
OS : RaspberryPiOSLite Bullseye 32bit 
```
pi@raspberrypi:~/test $ ./sample_armv7l
Cross Compile has been succeeded!!
```

上記を変更したい場合は、ビルドされているmain.cを変更することで任意のCコードを実行ファイルへとクロスコンパイルすることができます！

ラズパイでよくあるカップ麺が伸びるような長いビルドを先にx86マシン上で終わらせることでよりデバッグしやすく、開発しやすくなりました。

普段の業務ではこのようなdockerを用いたビルドを利用することがモダンな環境では多くなってきています。
このようなハードウェアにご興味ある方、弊社はリファラル採用もやっているそうなのでモダンな開発に興味がある方はぜひカジュアル面談など受けてみてはいかがでしょうか。

### 5.終わりに

ここまで読んでくださってありがとうございました。
次は現在のPi5や64bitでの具体的なアプリケーションについても寄稿できたらと思います。


ご指摘・ご希望あればコメントにて対応させていただきます。
### 6.参考文献
今回の記事は下記記事を参考に作成いたしました。

https://qiita.com/ryoma-jp/items/8ed31db292744b289c8f

https://qiita.com/zono_0/items/7a25d283cd4b09d6ffb0
24日目にLINEミニアプリが完成する初心者 ―― Day18. リッチメニューの修正


前回は「24 日目に LINE ミニアプリが完成する初心者 ―― Day17. ショールーム来場予約の実装」と題して、ショールーム来場予約機能を実装しました。

https://qiita.com/non_watanabe/items/02d43f0513cce092f17e

<br/>
今回は、ここまで実装してきた内容の細かい部分を修正して一旦完成の形にして行きたいと思います。

# リッチメニューの登録

はじめに前回作ったショールーム来場予約をリッチメニューに登録します。

公式ラインにログインしリッチメニューから前回作ったメニューを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743174/6bdca806-9dea-f045-3668-ea21b0dfd4d4.png)

<br/>
編集をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743174/f827941e-e2e7-f556-50ba-b1f6a9c6272f.png)

<br/>
Aの位置にリンクとして来場予約ページを設定して保存を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743174/8e261d9f-0114-9559-fc9b-78ba4d2081bf.png)

## 動作確認

LINE のリッチメニューからショールーム来場予約をクリックすると Google の予約スケジュールの画面が表示されるのが確認できると思います。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743174/0f5042f5-fa7b-bd7a-97a1-119e58293de9.png" width="50%" />

# 画面遷移を修正

現在ショールーム来場予約ページと資料請求ページは開くと一旦 LIFF スターターアプリの画面が見えてしまっているためこれを修正します。

## LIFF アプリへの URL を追加

はじめに個別の URL を LIFF アプリとして URL の追加を行って行きたいと思います。

LINE Developers にログインし、LINE ログインのチャネルを開きます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743174/7f5f242e-7252-8a74-ae4c-5a751b2a3154.png" width="50%" />

<br/>
<br/>

LIFF タブから「追加」ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743174/2b1feb76-6425-c16d-6a61-f236600a97ae.png)

ここで追加する内容を入力して行きます。

### ショールーム来場予約

ここでは以下の内容を入力しました。

- **LIFF アプリ名:** ショールーム来場予約
- **サイズ:** Full
- **エンドポイント URL:** https://mahaloliving.netlify.app/showroom
- **Scope:** ☑︎profile ☑︎chat_message.write ☑︎openid
- **友達追加オプション:** On (Aggressive)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743174/a1ba7e6a-92a8-dda4-6f55-e62e0cca98b7.png)

入力を行ったら「追加」を行います。

## 資料請求

資料請求も同じように追加が行います。

- **LIFF アプリ名:** 資料請求フォーム
- **サイズ:** Full
- **エンドポイント URL:** https://mahaloliving.netlify.app/catalog
- **Scope:** ☑︎profile ☑︎chat_message.write ☑︎openid
- **友達追加オプション:** On (Aggressive)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743174/9cce1575-b6fc-e733-516e-41de91788841.png)

<br/>
これで追加が完了しました。

ここで発行された LIFF URL をリッチメニューに登録して行きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743174/7e901592-771f-89ac-e5d6-777089132809.png)

## リッチメニューの URL を更新

先ほどと同様に、リッチメニューの編集画面に入ります。

ここでアクションの A と B のリンクを先ほど発行された URL に置き換えて保存をしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2743174/6ebe53ab-3d5f-dd82-0c6d-b60692ffd89c.png)

実際にアクセスしてみるとスターターアプリを挟まずに表示ができるのが確認できると思います。

# まとめ

思ったよりも進捗が早く、ここまでで当初予定していた機能実装は完了しました。

こうなると次回からは、何を書こうということになるのですが、LIFF SDK にはもっと様々な機能がある中で今まで紹介してきたのはまだ一部のため、公式ドキュメントの機能を学習しつつ新機能を考えて行きたいと思います。

残りは 6 日！
気になる方は是非フォローやカレンダー購読をお願いします:star:
【TypeScript】type-challenges 中級編 3・Omit 解説

## お題
組み込みの型ユーティリティ`Omit<T, K>`を使用せず、`T`のプロパティから`K`を削除する型`MyOmit`を実装する。

## やりたいこと
```ts
interface Todo {
  title: string
  description: string
  completed: boolean
};

type Result = MyOmit<Todo, 'description'>;

// Expected
interface Expected {
  title: string
  completed: boolean
};
```

## 解答
```ts
type MyOmit<T, K extends keyof T> = {
  [P in keyof T as P extends K ? never : P]: T[P]
};
```

## 解説
### 処理の流れ
- `<T, K extends keyof T>`
`K`が`T`のプロパティであるように制約。
- `{ [P in ...]: T[P] }`
Mapped Typesを使用し、オブジェクトを作成。
- `[P in keyof T as P extends K ? never : P]`
`as`を使用し、`as`以降の条件分岐をもとに、`P`の値を再割り当て（リマップ）する。

### そもそも`Omit<T, K>`とは...
**オブジェクトの型`T`から`K`で指定したプロパティを除いたオブジェクト型を返すユーティリティ型である。**
```ts
type User = {
  surname: string
  middleName?: string
  givenName: string
  age: number
  address?: string
  nationality: string
  createdAt: string
  updatedAt: string
};

type Optional = "age" | "address" | "nationality" | "createdAt" | "updatedAt";
type Person = Omit<User, Optional>;

type Person = {
  surname: string
  middleName?: string
  givenName: string
};
```

### Mapped Typesにおける`as`とは...
**キーをリマップ（再割り当て）する機能を持つ。**
Mapped Types内で、キーを条件に基づいて変更することができる。

:::note warn
**型アサーションのasとは異なる機能です**
:::

### keyofとは...
https://qiita.com/yuto99999/items/dcc234f3e25a5393a2ab#keyof%E6%BC%94%E7%AE%97%E5%AD%90%E3%81%A8%E3%81%AF

### Mapped Typesとは...
https://qiita.com/yuto99999/items/dcc234f3e25a5393a2ab#mapped-types%E3%81%A8%E3%81%AF

## 参考記事
### ユーティリティ型`Omit<T, keys>`
- [Omit<T, keys> | TypeScript入門『サバイバルTypeScript』](https://typescriptbook.jp/reference/type-reuse/utility-types/omit)

### Mapped Typesにおける`as`
- [TypeScript Documentation | Mapped Types](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#key-remapping-via-as)

### 型アサーション`as`
- [型アサーション「as」| TypeScript入門『サバイバルTypeScript』](https://typescriptbook.jp/reference/values-types-variables/type-assertion-as)

## 今回の問題
https://github.com/type-challenges/type-challenges/blob/main/questions/00003-medium-omit/README.ja.md
SwiftUIの変数への代入で詰まった話

## はじめに
最近参加したハッカソンで，初めてswiftを使ってiosアプリを作りました．SwiftUIを使ったのですが，そこで変数への代入で詰まったので，自分なりにまとめてみました．

### SwiftUI
SwiftUIとは，このようにViewの中で変数の宣言や，if文を用いた分岐が使える優れ物です．
```swift:ContentView.swift
import SwiftUI

struct ContentView: View {
    // 変数の宣言
    @State private var hensu: Int = 0
    var body: some View {
        // if文での分岐処理
        if(hensu == 0){
            Text("Hello World!!")
        }
        else{
            Text("こんにちは")
        }
    }
}
#Preview {
    ContentView()
}
```

ただ，直感と勢いで変数に値を入れようとすると，エラーが出ます．
例えば，次のようなコード

```swift:ContentView.swift
import SwiftUI

struct ContentView: View {
    // 変数の宣言
    @State private var hensu: Int = 0
    var body: some View {
        // if文での分岐処理
        if(hensu == 0){
            Text("Hello World!!")
            // 変数hensuに1を代入
            hensu = 1 //ここでエラー
        }
        else{
            Text("こんにちは")
        }
    }
}

#Preview {
    ContentView()
}
```
エラー文は「Type '()' cannot conform to 'View'」．内容を意訳すると「Viewの中で変数の代入しちゃダメだよ」って感じですね．

### 解決法
Swifter(Swiftめっちゃできる人)に教わった方法を紹介します．
エラー文の意訳で，「Viewの中で変数の代入しちゃダメだよ」と書きましたが，例外があります．それは，モディファイアの中なら書くことができるということです．
改良したコードを下に示します．
```swift:ContentView.swift
import SwiftUI

struct ContentView: View {
    // 変数の宣言
    @State private var hensu: Int = 0
    var body: some View {
        // if文での分岐処理
        if(hensu == 0){
            Text("Hello World!!")
                .onAppear(){
                    // 変数hensuに1を代入
                    hensu = 1
                } 
        }
        else{
            Text("こんにちは")
        }
    }
}

#Preview {
    ContentView()
}
```
.onAppearというモディファイアは，対象のView(今回はText("Hello World!!"))が表示された時に，一回だけ実行される処理を書くことができます．
この.onAppearのようなモディファイアの中なら，変数に値を代入することができます．

## おわりに
SwiftUIを使い始めて，最初の方で躓いて，結構悩んだ内容だったのでまとめてみました．
普通のプログラミング言語を書くような勢いで書くと，絶対引っかかるなと思いました．
変数に代入する方法は，他にもあるとは思いますが，一番自分的にわかりやすく書きやすかったので，この方法を紹介しました．
以上，SwiftUIの変数への代入についてでした．
toioとアミーボを組み合わせてみた

任天堂から出ている amiibo(アミーボ) を見て、これtoioに載せられそうだなと思いました。
https://www.nintendo.com/jp/hardware/amiibo/index.html

そして、「キャラクターの台座の部分って実はほとんど同じ直径では・・・？」と気づいてしまいました。

そこで組み合わせるためのパーツを３Dプリンターで作ってみました。
https://www.thingiverse.com/thing:6876265

このような感じで、ソニックが走っている感じのamiiboを乗せて走らせるだけで楽しそうです。
![PXL_20241217_023939275.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35544/f897da10-d66e-c988-c75d-1fbfc63c5feb.jpeg)


もう一つのパターンとして、底面をセンサー部分以外をあえて塞ぎます。
それでtoioプレイマットの座標を認識するコマとしての amiibo。これでゲーム作ったりも面白そうです。
![PXL_20241217_023905776.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35544/75da56e9-aabf-b692-c11d-46d030820f77.jpeg)

特にオチはないですが・・・。こんなのをやってみました。
私のVSCodeかわいいからみんな見て🎀

# 私のVSCodeかわいいからみんな見てください
ごきげんよう、ちなっちゃんです。
VSCodeかわいくする界隈があるらしいですが、かわいいエディタじゃないとやる気起きないですよね！？なので弊環境をご紹介。

\ \ \ \ \ ジャーン / / / / /


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689151/f97243ce-26e3-c293-f765-910ecab3b5c0.png)

コードはこの記事で書いたものです▼

https://qiita.com/toremolo72/items/3af61687f50a70361ba2

# 使ってる拡張🎀

### Catppuccin Icons for VSCode

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689151/f007e640-962d-a094-4037-320aa0efae03.png)

https://marketplace.visualstudio.com/items?itemName=Catppuccin.catppuccin-vsc-icons

アイコンをカラー線画に変えるかわいいものです。私はFrappéにしてます！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689151/128e62ec-66dc-3624-b259-c223eb01bcd4.png)　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689151/b841c9e1-140e-ea3a-a354-d8c6939ae691.png)



### soft era

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689151/00cb4fb0-ff63-ce0c-947f-c8b36601e86b.png)

https://marketplace.visualstudio.com/items?itemName=soft-aesthetic.soft-era-theme

パステルカラーはこの拡張を入れてます、めーっちゃかわいい！！！
かわいい系で調べるとビビットなものが多いので、パステルカラーなところが激推しです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689151/a794bc7e-b738-8265-a05b-5e0a0e566ea9.png)　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689151/73f59ee1-630f-a2d3-149b-9a3242c9fd51.png)

# かわいいエディタ、おすすめあったら教えてください🎀
見た目がかわいいとやる気アップ！！ おすすめかわいい環境があったら教えてください💛
人工筋肉を使ったロボットハンドを作って遊ぶ(その1)

皆さん，こんにちは．初めまして．ハシュマルです．
全ロボで発表を聞いてくださった方々はありがとうございました．その発表の内容に加え，補足も加えたものをこれから何回かに分けて投下していこうかなと思います．リアクションをつけてくださるとハシュマルのやる気が出るので，いいねなどよろしくお願いします～

## 人口筋肉ってどんなやつ？

さて，今回は初回ということで，人工筋について紹介したいと思います．
人工筋肉と言いましても，Google大先生に聞いてみると様々な種類のものがヒットします．
例えば以下のような培養肉でできたものや釣り糸でできたもの，そしてブリヂストンと東京工業大学の共同開発で油圧駆動人工筋肉が開発されたりもしています．これらの他にも様々なものがあります．

世界初　筋肉と機械で構成したロボット　東大が開発(18/05/31)
https://www.youtube.com/watch?v=2ALVumBYT8w
\
釣り糸で人工筋肉を作ろう
https://www.mirai-kougaku.jp/laboratory/pages/220311_02.php
\
ブリヂストンの技術が詰まった「ゴム人工筋肉」の技術開発発表会
https://www.bridgestone.co.jp/blog/2017020201.html
\
今回私が全ロボで紹介した人工筋肉は，ブリヂストンさんの人工筋のようなマッキベン型人工筋肉です．ただし，こちらの人工筋肉は圧縮空気で動作します．
![jinkokin.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3937813/19a51696-b01f-10a5-e82a-1379cfcba7eb.jpeg)

## マッキベン型人工筋肉について

マッキベン型人工筋肉は主に空気の注入口とシリコンチューブ，スリーブ，空気漏れ防止の栓の4つのパーツからできています．
こちらの人工筋肉は阪大の石川・南研究室の増田先生が公開されているもので，これを参考に製作しました．「人工筋肉  自作」で検索すると真っ先にヒットすると思います．これがレシピです．

https://ishikawa-lab.sakura.ne.jp/yoichi/muscle_recipe

そしてこれが製作の動画です．

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

この人工筋肉は，低価格で誰でも比較的簡単に同じ性能のものを作れるという点において非常に素晴らしいものとなっております．

出力荷重と収縮率についてのグラフを下図に示します．縦軸が引張荷重，横軸が収縮率です．また，実線が理論式，丸の点が0.2MPaの場合の出力，バツが0.1MPaの場合の出力を表しています．
このように，収縮率が上昇すると出力荷重が減少していきます．要は，関節に人口筋肉を付けると関節を曲げれば曲げるほど曲げる力が弱くなっていく，ということですね．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3937813/213503dc-b119-cb3c-fc3f-2c0f40a9313c.png)

このように，ロボコンでよく使用される空気圧力0.75[MPa]よりもはるかに小さい圧力でもこの人工筋肉は動作し，0.2MPa印加時には大体6kgfの出力を得られることがわかります．

ちなみにこれは余談なのですが，間違えて0.8MPaの空気を印加してしまったとき，空気を止めている栓が破裂音と共に吹き飛びました．おそらく栓を止めていたホースバンド(増田先生のレシピよりチューブ径が大きいものを作っていた)の固定が甘かったものと考えられます．皆さん，遊ぶ場合は気をつけましょうね．

こんな人工筋肉ですが，一つだけ欠点があります．それは収縮率の小ささです．上のグラフを見てもらえばわかるかと思いますが，今回製作した人工筋肉の収縮率は理論のものよりも小さく，最大でも23%程度にとどまっています．これは，100mmの人工筋肉を作った場合は77mmになるということで，23mmしか縮んでくれません．これは困った...
そんな折，研究室の先生がラバーレス人工筋というものを発見してくださったことで，事態が急展開していきます．

## ラバーレス素材を用いた人工筋肉

従来型の人工筋肉の大きな欠点は収縮率の小ささでした．そこで，新さんという方がこの点を大きく改善した人口筋肉を開発されました．その収縮率はなんと驚異の約48%!!
以下に元論文(予稿？)のリンクを示します．(J-STAGEの購読が必要です．見たい人は購読するか先生にお願いしてダウンロードしてもらいましょう)

https://www.jstage.jst.go.jp/article/jsmermd/2023/0/2023_2A1-H19/_article/-char/ja

この論文によると，従来型はスリーブの中がシリコンチューブであった所をアルミ蒸着袋で作ったエアバックに変更することで，48%の収縮率を実現しています．また，引張荷重についても従来型のものが0.2MPaの場合約6kgfであったのに対し，新さんの人工筋肉は約48kgfとなっており，大きく上昇しています．

これらの点から，私はこの人工筋肉を使いたいと考え，論文の内容を参考に人工筋肉を作らせていただきました．それから派生していったものが，全ロボで作り方を紹介した人工筋になります．ただし，~~収縮率は最大で40%~~（追記：収縮率48%を達成しました），引張荷重が約11kgfとなっており，~~新さんのものの劣化版になっています~~(追記:人口筋の直径を大きくすると近い値が出ることがわかりました．理論式を考えたら当然だね)．私はこれに満足してロボットを作っていますが(この時点で従来型より引張力が上)，さらに上を目指したい人は私の成果を基に改良してくださいね．

## 次回予告

今回は主に人工筋肉について紹介しました．この続きは後日投下していくのでお楽しみに～
次に投稿する記事はハード面について書いていきますが，いずれ制御について書きたいなーと思っております．プログラミングがからっきしの機械屋が悶絶する様をお楽しみに．
あまりにも記事の更新が遅いようでしたらTwittarに尻を蹴りに来てください．必死になって書きます．

また，ご意見・質問などありましたらQiitaのコメントやTwitterのDMなどに送ってください．よろしくお願いします．

https://x.com/nyan21137317
create-react-appで作られた中身からCSSの知識を得る

やっぱり人が作ったコードって最高だな！

```css:App.css
.App {
  text-align: center;
}

.App-logo {
  height: 40vmin;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .App-logo {
    animation: App-logo-spin infinite 20s linear;
  }
}

.App-header {
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}

.App-link {
  color: #61dafb;
}

@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
```

# height: 40`vmin`;

```css.App.css
.App-logo {
  height: 40vmin;
  pointer-events: none;
}
```

なんだその指定は！

参考：[画面からはみ出る!?CSS単位の奥深さを解説！vw、vh、vmin、vmaxの違いと使い方](https://ui-hack.com/programming/html_css/css_units_vw_vh_vmin_vmax/)

>vminとは
>- ビューポート（画面）の幅と高さのうち、短い方を基準にした大きさを表す単位です

>vmaxとは
>- ビューポートの幅と高さのうち、大きい方を基準にした大きさを表す単位です

おもしろ！確かに画像の大きさがウィンドウ枠の横幅にだけ合わせて変更されるの気になってた。なるほどねぇ～！

# `pointer-events: none`;

```css.App.css
.App-logo {
  height: 40vmin;
  pointer-events: none;
}
```

参考：[pointer-events](https://developer.mozilla.org/ja/docs/Web/CSS/pointer-events)
参考：[クリックやタップを無効にするためのCSS「pointer-events: none;」](https://www.materialpot.com/css/pointer-events-none/)

えっとこれはたしか、くるくる回っているReactのロゴ(`.svg`)のクラス名だから、この画像へマウスオーバしても指マークとならないようにしているな。ふむ。

# `@`から始まるスタイル

**なんだっけ。**
確実に学習サイトで学んだ気がする。

```css:App.css
@media (prefers-reduced-motion: no-preference) {
  .App-logo {
    animation: App-logo-spin infinite 20s linear;
  }
}
```

参考：[アットルール](https://developer.mozilla.org/ja/docs/Web/CSS/At-rule)
参考：[【CSS-rules】@media](https://millmi.com/css/10/)

2つ目の参考サイトがわかりやすかった。上記のコードでは省略されているがおそらく初期値の`all`が指定されていることになるのだろう。で、`()`の中身は何かというと

# `prefers-reduced-motion: no-preference`

```css:App.css
@media (prefers-reduced-motion: no-preference) {
  .App-logo {
    animation: App-logo-spin infinite 20s linear;
  }
}
```

参考：[prefers-reduced-motion](https://developer.mozilla.org/ja/docs/Web/CSS/@media/prefers-reduced-motion) ※わからん！
参考：[アニメーションを望まないユーザーを考えたWeb制作をしよう｜prefers-reduced-motion](https://blanche-toile.com/web/css-prefers-reduced-motion)

**世の中、優しさに溢れてるー！**

つまりは「アニメーションばっちこいや！(no-preference)」なユーザにだけにアニメーションでReactのロゴをぐるぐる回して見せていたってことかな。
ははぁ～～知らないとできないなこんな配慮。


# `justify-content: center;`

```css:App.css
.App-header {
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}
```

参考：[justify-content](https://developer.mozilla.org/ja/docs/Web/CSS/justify-content)

う、、、うん。`align`とか`float`とか`display: frex`とか、このあたりは1個記事作ってちゃんと学ぼう。。
うにがあるくAAを表示するコマンドを作った

こんちは

塩ハム(d)です

みすてむずアドベントカレンダー2024 ~~12/17の記事です~~12/9に移動しました

理由は12/17分として[更新版](https://qiita.com/shio_hamu_d/items/eda4f71da8bde125df6a "うにがアニメーションで歩くよ")を作ったからです

https://adventar.org/calendars/10269

今12/18 0:06です(遅刻)

先ほどまで何も思いつきませんでした

しかし題材は決まっています

### うに です

なぜかは知りませんが(はやった当時からいたのに)、みすてむずではうにがアイドルのような存在となっています

絵文字も作りました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668804/249c0c04-2a11-b7c4-0ebf-f99603a18da9.png)

たしか当時はツイッターでうにのマンガがバズっていたので、その余波があったのでしょうか

それはさておき、何も思いつきませんではよくありません

ぱっと作れる、うにを題材にした、みすてむずっぽいもの……

……適当にechoコマンドを使ってうにを歩かせるコマンドを作りましょうか

# うにのコマンド

コマンド名は……unicodeをモジってunicuteとします

コードは以下です

```bash
#!/bin/sh
clear
echo "＼  通りますよ ／"
echo "  ￣￣￣∨￣￣￣"

echo "    ＼\\\\||//／"
echo "   =三((   ))≡="
echo "    ／/||\\\\＼   ((("
echo ""
echo "                 うにだね"
echo "                    かわいいね"
echo ""
echo ""
```

これを呼び出したのがこちらになります

![WindowsTerminal_SkwwIWxcLa.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668804/e33f7348-65a8-f967-e0c6-9e951c051a88.gif)

うにだね

かわいいね

# おわりに

クソコードですいません

使いたい方は、任意の場所にunicuteというファイルを作って先ほどのコードを貼り付けてください

その後`chmod 777 unicute`して、パスを通せばいつでも使えるようになります

以上で終わりとさせていただきます

閲覧ありがとうございました
AIの進化により私たちエンジニアは必要なくな、る、の、か？

## はじめに

エンジニアの方々なら言わずもがな、近年AIの技術はどんどん発展してきています。

その代表的なものが**ChatGPT**だと思います。

今回はその**CahtGPT**の進化により私たちの職業はどのようになっていくのか、完全ALL100%の偏見で軽く考察していきたいと思います。

## エンジニア レベル分け(5段階)

|LV|ポジション|状態|
|--|--|--|
|1|未経験(or 非エンジニア)|ChatGPTに聞いたところで何を言っているかわからない|
|2|新米エンジニア|先輩に聞いたり、調べまくって何とか業務内容の一歩が進める|
|3|中堅エンジニア|ある程度一人で調べたりすることで業務をこなしていけるが、とても難しいことは上級エンジニアに聞く|
|4|上級エンジニア|一人で何でも実装できる 人に教える立場の人もいるかも|
|5|スペシャリスト|この道の専門家 ChatGPTに代わって回答していてもバレないレベル|

## レベル別 業務内容の変化

**未経験(or 非エンジニア)** ... 特に変わらない。というより、そもそもChatGPTを利用しないと思われる。

**新米エンジニア** ... 対応できる業務内容は増える。が、結局は中堅エンジニアや上級エンジニアの最終判断に委ねるため、結局戦力としては微々たる向上。

**中堅エンジニア** ... 一番伸び代がある。ChatGPTを上手く利用することで業務範囲は上級エンジニアと同等になることも可能であり、上級エンジニアとの差は圧倒的に縮まる。

**上級エンジニア** ... 特に変わらない。自分の能力で十分であり、ChatGPTはあくまで別の観点からの1つの意見にすぎない程度。

**スペシャリスト** ... 業務内容は圧倒的に増大。もはや発言がインフルエンサー並みの影響力を持つ可能性がある。

## みんな、10年前(くらい)のニュースを思い出して

- コンビニ店員はいらなくなる
- 自動運転により運転免許は必要なくなる
- レジは必要なくなる

などなど言われてきましたが、現在はどうでしょう。

確かに情報技術は様々な業界で取り入れられていますが、そこで働いていた人たちは職が無くなるどころか、導入されたその情報技術を扱えるようになり、より人間として進化して現在働いています。

## 考察 & 結論

エンジニアの職業は絶えず需要が増していくでしょう。(そんなこと言われなくても知ってるわと言われるかもしれませんが)

そもそも、マネーストックという概念がある資本主義であり、0歳~100歳くらいまで存在するこの世界で、AIが私たちの本当の意味で**身近**になる日はいつになるのか、果てしなく遠い未来だと私は思っています。

せいぜい生活がより便利になる程度でしょう。

と同時に、庶民でも利用できるChatGPTなどのAIを利用しないのは愚の骨頂だと思います。
署名URLメモ

# 概要
Cloudinaryに保存しているファイルをダウンロードするために、Laravelで署名URLを作成してダウンロードしたので対応メモ

# 署名の検証
Cloudinaryのサーバーでは、リクエストを受け取った後に次の手順で署名を検証します：

## 同じパラメータを使って署名を再生成
Cloudinary側は、リクエストから送られてきた public_id, timestamp, resource_type, format などのパラメータを使い、サーバー側に保存されている API Secret で署名を再生成します。

## 署名の比較

 クライアント側から送られてきた signature と、Cloudinaryが生成した署名が一致するかを確認します。
署名が一致する場合

* リクエストは正しいものと判断され、リソースが配信されます。

## 署名が一致しない場合

リクエストは改ざんされたとみなされ、エラーが返されます（例: 401 Unauthorized や 403 Forbidden）。
米田の補題 #2 圏論の歴史

# 米田の補題は、圏論でもっとも重要な定理です（繰り返し）
圏論は、数学の基礎理論です。いままで、[万物の理論](https://amzn.to/3ZLmCJH)
といわれていましたが、[数理科学 11月号](https://amzn.to/4iz6NgM)では、なんと　<font color="Red">万物・万事・万人</font>のための数学理論とまでいわれるようになりました
このAdventCalendar は、体験的に圏論の最も重要な定理である米田の補題を体験的に理解してもらうためにかいています

参考にしているのは、[圏論の道案内](https://amzn.to/4iH2Rus)です

# 米田の補題の理解の前提は、圏、関手、自然変換です。どれも数学的に正面から理解しようとすると絶望的です。
東大理学部情報学科の4年生の学力が必要です。他の大学の情報学科では、圏論は必須でないので言葉そのものを知らない人が多いです。

# でも大丈夫　米田の補題川柳を使います。すでに米田の補題は、「関係は内容よりも重要だ」で、数学的前提まったくなしにいきなり提示しています

さすが、これだけでは、あまりなので、米田の補題川柳を使って、まずは
圏論とは、そして歴史、圏の定義、例、関手の、例、自然変換の定義、例　随所に補足　そして米田の補題をほんの少し、数学的も説明します。

# 圏論とは 矢印で考えること

単純で理解しやすい事例をいくつか列挙します
文は違うけど、対象ふたつ、矢印ひとつは同じ
- A　　　→　　　　B
- 出発点　→　到達点
- 原因　　→　結果
- 東京　　→　大阪
- 犬　　　→　哺乳類
- 私　　　→　相手

矢印を使ってなにかを説明することはよくありますよね。
これを#米田の補題川柳にしてみましょう
**米田の補題川柳**
矢印で考えるのはよくあるさ

[connpass のイベント](https://setk.connpass.com/event/338108/)ではこんな文章使っています
「圏論は数学の基礎理論で、集合論に替わるものです。20世紀中ごろに登場し、有名な数学者グロタンディークが数学に幅広く適用し、多大な成果をあげたので有名です。ちなみに、彼の有名な論文の一つに東北大学で出版されたものがあり、Tohoku paper と呼ばれています。 圏論の最強の成果は、米田の補題です。米田の補題の理解を目指しましょう。」

# 歴史

ポアンカレ -> アレインベルグ、マックレーン（創始者）->　グロタンディーク　なのですが、ポアンカレとグロタンディークのみ取り上げます

## 圏論のご先祖様　ポアンカレ 曰く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48387/f314f283-3795-d933-caef-2fb7d70e95b9.png)
数学とは違うものを同じものとみなす技術である

これも#米田の補題川柳にします

**米田の補題川柳**
違うもの同じとみなすすごいこと


# 圏論で数学を書き換えた天才 グロタンディーク　曰く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48387/d98ca9ba-6d87-b003-fd8d-0df5ba533085.png)

**対象、射(やじるし)なんでも良い**
圏論は、対象と射(やじるし)で構成されるのですが、それがどんなものであるかの想定はまったくありません。これは、圏論をものすごく難しくしている理由の一つです。ただ、逆にそのことで、米田の補題までたどりつくと見通しがよくなります。「関係が内容よりも重要だ」というのは、当たり前だと誰もが普通思うのではないでしょうか？　わざわざ、数学的に厳密な過程を辿って理解する必要もない気がします。

**米田の補題川柳**
なんでもと思えるならばすごいこと

|**ここまでの圏論の話は、美味しいか？ 美味しいです**

そもそも、普段から無意識に使っています
**会議でこんな会話していませんか？**
課題が解決できればなんでもよいのだから、〇〇は違う方法だけどで同じように解決できるのでは
AWSクラウドプラクティショナー合格体験記（2024.12）

## はじめに
2024年12月にAWSクラウドプラクティショナーを受験し合格しました。
今回、体験記と私がやった試験対策や学習教材を紹介したいと思います。

## 合格までの流れ


| 年/月 | やってたこと |
|:-|:-|
| 2024/8 | AWSの資格CLFだけでも持っておこうかな〜と考える |
| 2024/9 | CLFって暗記と良く聞くし、いけるっしょ！って思う。そして勉強開始。 |
| 2024/10 | 引き続き試験範囲を進める。範囲の広さに驚くが、とりあえず学習を進める。Udemyの模擬試験をやって正答率40%で絶望する。 |
| 2024/11 | 模擬試験解く。解説を見る。足りない知識を補う。正答率が上がり、70%〜80%ぐらいになる。 **試験予約をする。**|
| 2024/12 | ひたすら模擬試験。無料で使える模擬試験は色々やってみる。直前までインプットし切れてないものがあり、焦りながらも直前まで頑張る。 |
| 試験当日 | 試験の受付をする10分前まで問題を解く。➡︎<font color="red">**合格！**</font>|


## 学習前の知識レベル
AWSとかインフラ関係についてはほとんど知識がない状態。
AWSアカウントを作ってEC2とか作ってみた程度。

## 使用教材

- ### `公式動画`
[AWS Cloud Practitioner Essentials (Japanese) (日本語実写版)](https://explore.skillbuilder.aws/learn/course/1875/aws-cloud-practitioner-essentials-japanese-ri-ben-yu-shi-xie-ban)


- ### `公式練習問題`
[AWS Certified Cloud Practitioner 公式練習問題集](https://explore.skillbuilder.aws/learn/course/external/view/elearning/16792/aws-certified-cloud-practitioner-official-practice-question-set-clf-c02-japanese)


- ### `Udemy（とりあえずこれってやつ）`

https://www.udemy.com/course/ok-aws-e/

https://www.udemy.com/course/aws-4260/


- ### `無料のWEB模擬試験`


 ⬇︎無料で問題が<font color="red">100問</font>できます。**サービスの内容と詳細も記載されてます。**

https://aws-exam.net/clf/

⬇︎無料で問題が<font color="red">200問以上</font>できます。

https://aws.keepitup.jp/


- ### `買ってないけど役に立ったかも？`


⬇︎サンプルを見ると<font color="red">40問ぐらい</font>見ることができます！（高くないので買ってもいいかも！）

https://amzn.asia/d/izHvh0F

## 勉強方法

##### ①公式動画で各サービスの名称や意味、イメージをとらえる
　・AWSのサービスを使ったことがない
　・ITインフラの知識がない
　・業務で使ってるけど限られたサービスしか触れたことがない
 
 上記の場合はまず公式動画を見て頭の中でAWSクラウドのイメージを持つ方が良いと思います。


##### ②Udemyで学習を進める
　公式動画だけではCLF試験範囲を細かい部分までは残念ながら網羅できません…。
　細かいサービスはUdemyを使って知識を補いましょう！
　※ITインフラの知識があるのであれば、いきなりUdemyで十分かなと思います。

　やはり人気のあるUdemyの講座、模擬試験だけあって内容は非常に充実してました。
　模擬試験はたくさんあるので、繰り返し解くことで知識が定着します。
　知識のインプットに時間を費やすよりは模擬試験でインプット＋アウトプットをした方が
　個人的には良いと思います。

　Udemyが紹介されているところでは必ずと言っていいほど書いてありませすが定期的に
　<font color="red">セール</font>をやってます。
　とにかくめちゃくちゃ<font color="red">安く</font>なります。
　受けるか迷ってる時に安くなっていたらとりあえず買っておきましょう！

##### ③Udemy以外の模擬試験を解く
　Udemyの模擬試験だけでも合格はできると思います。
　私は心配だったので他のサイトで無料の模擬試験をやってました。
　（無料のWEB模擬試験で紹介しているサイト）

## 苦戦したこと
Well-Architected FrameworkとAWS CAFの内容や設計原則を暗記することです。
私は途中で無理だと感じたので模擬試験を繰り返し解くことで少しずつ覚えてました。
ただし、完全に暗記することはできませんでした。というか諦めました。
（暗記できる人すごいです）

VPC周りは図にすると分かりやすいです。以下のサイトに助けられました。

https://milestone-of-se.nesuke.com/sv-advanced/aws/internet-nat-gateway/

例えば
・セキュリティグループ、ネットワークACL（NACL）といったトラフィック制御関連
・オンプレミスとAWSの接続方法（VPNやDirect Connect、Transit Gatewayなど）
というような単純に暗記だけだと覚えづらいものも<font color="red">図にしてみる</font>ことをオススメします！
## 実際の試験について
AWSの公式が出している模擬試験はたった20問です。
実際の試験では意外と迷わせるような問題も出てきます。
ただし、選択肢については似たようなサービスばかりではなく、絶対に違う選択肢が多い印象でした。
そのため、Udemyや無料の模擬試験を解けるようにする、ではなく、各サービスをしっかり理解することが大切だと感じました。

## まとめ
AWS認定試験の中で一番難易度は低いものですが、資格試験なのでしっかり学習しないと合格は難しい印象です。
私はなんとか合格できましたが、早い人ですと２週間ほどの期間で合格している方もいるようです。
CLF対策の記事はたくさんありますが、常に最新の記事、最新の模擬試験を使用するようにしましょう！
QPython で GUI プログラミング2（YouTube チャンネル登録者数カウンターを作る：未完）

## きっかけは…
前回 [QPython で GUI プログラミング1（サンプルスクリプトを動かす）](https://qiita.com/harycurl/items/7d13d34d183b820201db) の記事で、サンプルスクリプトをもとに、XML で指定した位置に任意の文字を表示できることを確認した。

今回は前回のスクリプトを修正して YouTube チャンネル登録者数カウンターにすることを試みる。

なぜ YouTube チャンネル登録者数カウンターかというと、某 YouTuber が視聴者から [Smiirl のカウンター](https://www.smiirl.com/en/counter/category/custom) をプレゼントされ、 YouTube チャンネル登録者数を背後で常時表示させているのを見たからである。
私は YouTube チャンネルを持っていないが、登録者数やフォロワー数カウンターのしくみを習得しておこうと思い、 手始めに MeePet を購入したというわけである（ちなみにその後、 [Ulanzi TC001](https://www.ulanzi.jp/products/ulanzi-pixel-smart-clock-2882) も注文してしまった。こちらは YouTube チャンネル登録者数カウンター機能が初めから用意されている）。

## YouTube チャンネル登録者数を Python で取得する
YouTube チャンネル登録者数を取得するには、まず YouTube Data API v3 の API キーを取得し、

https://kuds.blog/youtube/start-youtube-data-api-v3/

このスクリプトの通りに実装すればよい。

https://jitantech.com/hou-to-get-subscriber-count/

ただし、 QPython はコマンドとしての pip が入っていないので、QPython の Terminal を起動した後、以下のようにしてモジュールをインストールする。
```bash:
>>> # Ctrl + C を押して KeyboardInterrupt を発生させる
KeyboardInterrupt
>>> quit() # Python インタプリタを終了する

/ $ # Terminalが終了せずコマンドを受け付ける状態になる
/ $ cd # / ではインストール操作ができないのでホームディレクトリに移動
~/data/org.qpython.qpy/files $ python -m pip install google-api-python-client
# pip が使えないので、 python -m pip でインストール
```

## LOAD ボタンを押すと YouTube チャンネル登録者数が表示されるようにする
前回からここまでの手法を組み合わせると、 LOAD ボタンを押したタイミングで YouTube チャンネル登録者数を取得、表示させることができるようになる。

なお、先程のブログ記事にあったチャンネル登録者数取得スクリプトでは int で整数値に変換してから表示・CSV 出力を行っているが、 `self.views.((ID名)).text` は文字列型しか受け付けないため、整数型への変換をしてはいけない。

```python: YouTubeチャンネル登録者数手動取得(load関数部分のみ)
    def load(self, view, dummy):
        developerKey = "((取得したAPIキー))"
        channel_id = "((登録者数を取得したいチャンネルのID))"
        youtube = build('youtube', 'v3', developerKey=developerKey)
        request = youtube.channels().list(
            part = 'statistics',
            id = channel_id
        )
        response = request.execute()

        if response['items']:
            channel_info = response['items'][0]
            subscriber_count = channel_info['statistics']['subscriberCount']
        else:
            subscriber_count = "N/A"

        curdatetime = datetime.datetime.now()
        self.views.time.text = curdatetime.time().isoformat()[0:8]
        self.views.title.text = subscriber_count
```

![qpython_counter_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/8cd316f0-bc5a-088b-7dbc-4eb3f5980a45.png)
（きっかけとなった某 YouTuber、チャンネル登録者数が4万5千人に到達したようだ）

## 行き詰まる
後は、起動時の取得表示と、一定時間後の取得表示を実装すればカウンターとして完成する…わけだが、 qsl4ahelper の情報が日本語や英語だとあまりにも少なく（中国語だとQPython関連でそれなりにヒットするが）、ここから先に進めていない。
Android 用 Python アプリ開発環境である Kivy だと、 [Clock object](https://kivy.org/doc/stable/api-kivy.clock.html) でこのあたりのイベント発生を行えるみたいだが、 qsl4ahelper でそのあたりの機能が見当たらないため、他のモジュールの機能を併用する必要がありそうである。

Python 未熟者の身にはこれ以上の解決法が見つからず、今回の記事はここまでとする。
次回は PHP で YouTube チャンネル登録者数カウンターを作る予定。
WordPress の設定ファイルに $schema JSON Schema を追加しエディタで補完する


## はじめに

WordPress には設定ファイル (`theme.json` や `wp-env.json` 等)が複数存在します。
これらのファイルの定義は多数あり完璧に覚えることは困難です。
設定ファイル (`theme.json` や `wp-env.json` 等) に対して $schema JSON Schema の定義を追加することでエディタに補完してもらいスムーズに開発を進めることができます。

## JSON Schema とは

JSON Schema については以下記事等を参考にしてください。

https://qiita.com/g0e/items/9a4f886897fd46f107a8

https://json-schema.org

## JSON Schema の定義を追加する。

今回は WordPress の開発環境ツール `wp-env` の設定ファイル `wp-env.json` を例に記載します。

https://ja.wordpress.org/team/handbook/block-editor/reference-guides/packages/packages-env/

`wp-env.json` の schema 定義は以下URLで公開されています。

`https://schemas.wp.org/trunk/wp-env.json`

`wp-env.json` 内に `"$schema": "https://schemas.wp.org/trunk/wp-env.json"` を定義すれば OKです。

```json:wp-env.json
{
    "$schema": "https://schemas.wp.org/trunk/wp-env.json"
}
```

ただし、ドキュメントにも記載がありますがバージョンを指定して JSON Schema を読み込めない点には注意が必要です。

## その他 JSON Schema 定義

今回は、 `wp-env.json` を例に記載しましたが以下設定用の schema ファイルも用意されています。

- theme.json
- block.json
- font-collection.json
- wp-env.json
- blueprint.json
- WordPress REST API

ファイル毎に参照先が異なりますので詳しくは下記URLを確認して設定してください。

https://developer.wordpress.org/news/2024/07/json-schema-in-wordpress/

## Ref

https://github.com/WordPress/gutenberg/pull/36276

https://developer.wordpress.org/news/2024/07/json-schema-in-wordpress/

https://json-schema.org

https://code.visualstudio.com/docs/languages/json#_json-schemas-and-settings
【Ruby】RailsAdminのHasManyとHasOneを表示しないようにする

# 概要
関連付けの多いテーブルをRailsAdminで表示しようとすると、表示時間が長くなってしまうことがある

そういう時は大体、関連付けされているかなりの量のレコードが取得されている

![スクリーンショット 2024-12-18 0.06.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/a982c04d-1bc1-ff75-230b-40a914e60d48.png)
↑レコードに関連づけられているレコードも表示されている


# 回避方法
HasManyAssociationとHasOneAssociationをオーバーライドする

```rb:rails_admin.rb
....

# 以下を追記
module RailsAdmin::Config::Fields::Types
  class HasManyAssociation
    register_instance_option :visible? do
      @visible = false
    end
  end

  class HasOneAssociation
    register_instance_option :visible? do
      @visible = false
    end
  end
end
```

これで大量のレコードに紐づいているレコードもサクサク表示されるようになる
![スクリーンショット 2024-12-18 0.11.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100503/8d55e8c2-5682-6ffd-3d61-c7e083163dfd.png)


# 関連コード

https://github.com/railsadminteam/rails_admin/blob/master/lib/rails_admin/config/fields/types/has_many_association.rb

https://github.com/railsadminteam/rails_admin/blob/master/lib/rails_admin/config/fields/types/has_one_association.rb
DockerでWordPressを試してみる③

# はじめに
WordPressはよく聞きますが、仕事として触ったことはありませんでした。
縁あって、触る必要がでてきましたので、簡単にどんなものか勉強がてら試してみます。
前回は、WordPressの設定と初回投稿ができたところまで。

# 環境構築への疑念
最終的には、WordPressのコンテンツを静的ファイルとしてぶっこ抜いて、
Firebaseにデプロイするのが、本特集の目的です。

静的ファイルを出力するプラグインをインストールしようとして、
WordPressの設定画面よりプラグイン検索をした際に、
エラーが出てきたので、「あれ、なんかおかしいぞ」と疑念がわいてきました。

>An unexpected error occurred. Something may be wrong with WordPress.org or this server’s configuration. If you continue to have problems, please try the support forums.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826192/d0dcea5b-f9c9-9840-3576-538922c418f5.png)

そういえば、初回のユーザ、パスワードなどを設定する画面でも、
チュートリアルなどにある、「言語選択ページ」が表示されなかったこともあり、
もしかしたら環境構築に失敗しているのでは？と考えました。

# 試したこと
プラグイン検索エラーよりは、言語選択画面が表示されない現象の方が、
先に発生しており、かつ情報もありそうでしたので、こちらから調べてみました。

１． プロキシサーバが邪魔している
同じような現象が発生している情報がありましたので、確認してみました。
確かに作業場所の回線(J:COMの次世代 AI Wifi)は、
謎のめりけんサービス経由なので、なるほどありうる話だなと思い、
楽天モバイルのテザリング経由で環境を再構築しましたが、ダメでした。

https://teratail.com/questions/357157
<br/>

２． マウントするディレクトリの設定ミス
これまた同じような現象に対する情報です。
明確な答えが出ない中、言語設定用ディレクトリをマウントしようぜ、
って回答(だと思います)が、そんなことある？感がありましたので、
まだ試していません。

https://github.com/docker-library/wordpress/issues/217
<br/>

３． hostsに「198.143.164.251 api.wordpress.org」を追加
これかなーと思ったんですが、解決しなかったです。
```
$ docker compose exec wordpress sh
# echo "198.143.164.251 api.wordpress.org" >> /etc/hosts
```

https://github.com/docker-library/wordpress/issues/617

# 次の動き
結局解決できませんでしたが、仮想環境上のdockerということが
原因の可能性もあるため、実マシン上に環境構築してみてどうなるか、
次回は検証してまいります。
Dockerのログを確認する

<!-- Dockerのログを確認する -->

※この記事は[Udon Advent Calendar 2024 - Adventar](https://adventar.org/calendars/10764)の18日目の記事です。

## はじめに

こんにちは。Udonです。

最近はDockerを使うことが多いのですが、エラーが発生したときになんでなのかわからず悩んでしまうことが多かったです。

エラーの解決の近道はログを確認することです。今回はDockerのログを確認する方法を書いていこうと思います。

## テスト用のコンテナを作る

以下のリポジトリにテスト用の領域を作りました。

https://github.com/Gitudon/Test-Repositories

クローンして、「Docker-Log」というディレクトリに入り、以下のコマンドを実行します。

```bash
docker-compose up -d
```

こうすることで、以下のPythonのコードが実行されます。

```python
def main():
    for i in range(1,11):
        print(i)

if __name__=="__main__":
    main()
```

つまり、1から10までの数字を表示するだけです。

しかし、先ほど``-d``オプションをつけているので、バックグラウンドで実行されます。なのでこの出力は目に見えないわけです。

## ログを確認する

ログを確認するには以下のコマンドを実行します。

```bash
docker logs [コンテナID]
```

コンテナIDは以下のコマンドで確認できます。

```bash
docker ps -a
```

そうすると、以下のようなログが表示されます。

```bash
1
2
3
4
5
6
7
8
9
10
```

これでログを確認することができました。ちなみに、``-f``オプションをつけることで、ログの追跡をすることができます。つまり、実行時のログをリアルタイムで確認することができるというわけです。オプションなしだと、そのときまでのログが表示されます。

また、エラーログとそれ以外を区別することもできます。前者はエラーログのみを表示し、後者はエラーログ以外を表示します。

```bash
docker logs [コンテナID] 1>/dev/null
docker logs [コンテナID] 2>/dev/null
```

``dev/null``にリダイレクトすると、どこにも出力されず、無に消えることになります。

ちなみに、``docker-compose``を使っている場合は、以下のコマンドでログを確認することができます。

```bash
docker-compose logs
```

出力は以下のようになります。IMAGE名が表示されていますね。

```bash
docker-log-test-1  | 1
docker-log-test-1  | 2
docker-log-test-1  | 3
docker-log-test-1  | 4
docker-log-test-1  | 5
docker-log-test-1  | 6
docker-log-test-1  | 7
docker-log-test-1  | 8
docker-log-test-1  | 9
docker-log-test-1  | 10
```

この方法ではコンテナIDを指定する必要はないですが、エラーログとそれ以外を区別することはできません。

## ログを保存する

以下のように、適当な保存先を用意しておけばログをリダイレクトによって保存することができます。

```bash
docker logs [コンテナID] > [保存先のパス]
```

追記する場合は以下のようにします。

```bash
docker logs [コンテナID] >> [保存先のパス]
```

## ログのリセット

ログは``docker compose down``を実行し、もう一度``docker compose up -d``を実行するとリセットされます。これはコンテナが再起動されるためです。

## おわりに

これでDockerのログを確認することができるようになりました。

DockerでDiscord Botを動かしたりしていると、エラーが発生してもなぜエラーになるのかわかりづらいときがあります。そんな時にログを確認すれば、エラーの原因究明に役立ちます。

ではこの記事は以上です。また明日の記事でお会いしましょう。

## 参考文献

[【Docker】Dockerコンテナ内のログを確認する方法 #Docker - Qiita](https://qiita.com/sho_U/items/1f0f25e1cfe928828dd8)
ITエンジニアがロボ系社会人Dに入学した感想など

## はじめに

**本稿は[社会人学生Advent Calender 2024](https://adventar.org/calendars/10520)の17日目の記事としてお送りします！**

こんばんは。孔明（[Twitter](https://x.com/eternalfriend17)）です。同アドカレ1日目のアロアさんからお誘いを受け、せっかくの機会なので今年から社会人Dにチャレンジした進路についてご紹介（と懺悔）を記しておこうと思います。

しっかり技術系の記事ではないのですが、僕がスマホから記事を書けるよきプラットフォームがないのと、ITエンジニアのキャリアの一例として…という建て付けを思いついたのでQiita記事として書いています！ご容赦！！


## ざっくり経歴

思い返せば昔からロボットが好きで、ロボ作りに特化したような進路でした。

- 高専本科: 高専ロボコンでメカから外装までほぼ全ジャンルを広く浅く作ってました。
- 高専専攻科: 研究室でつくばチャレンジに出て、主にLiDARを使って路面を見分けるための研究をしてました。
- 大学院（修士）: 専攻科のあとに就職と悩んだのですが、楽しそうだからの理由でヘビ型ロボットの研究室に進みました。
- ITエンジニア: 新卒でIT企業に就職し、IT系のエンジニアとしてごはんを食べています。IT屋さんを選んだのは単に「業界…というか会社の雰囲気が良かったから」でした。メカもエレキも好きです。
- そしてITエンジニア(フルタイム) 兼 社会人D←いまここ

## なぜ社会人Dに？

上に書いた大学院入学がちょうどコロナ流行りはじめのタイミングでした。入学式の直前に東京ロックダウン、みたいなあたりのタイムリーさです。これにより、在学期間中はほとんどラボに通わず、リモートで研究をしていました（後半の頃は通おうと思えば行けるくらいには緩和されてましたが、諸々の安心最優先で結局リモートしてました…ちょっと悔やまれます）。
そんな暮らしのまま無事に今の会社で拾ってもらい就活を終えて新卒入社したわけですが、もっと色々作りたかったなーというぼんやりした思いがあり、**趣味でヘビ型ロボットをフルスクラッチ**してTwitterにあげる暮らしをしていました。

そんなあるとき、修士の頃にお世話になっていた研究室の先生から「君が昔やってた研究の関連で新しい引き合いがあるんだけど、D進で戻ってくるの興味ない？」との連絡を受けます。昔できなかった研究生活のリベンジをしたいきもちと、それなら会社やめるか…？いやでも生活費は…？などの思いが錯綜した結果、「社会人Dとしてでも受け入れていただけるのであれば！」の結論に落ち着きました。そして入試や社内への相談などなどを経て今に至ります。


## やってみて…

### 良くなかったこと

先に良くなかったことを挙げてしまうのですが、**無限に時間と体力が足りない！！** 全てこれに尽きます。20代後半に差し掛かり自分で引くほど可処分時間と体力が減りました。比較的平和に労働しているはずなのですが、夜になると思ったように頭も体も回りません🫠🫠

昔のように徹夜ができない…程度ならまだしもちょこっとスケジュール詰めただけでさくっと力尽きて色々な計画が破綻します。日中の忙しさも昔よりクリティカルに体力に効きますね。研究、一向に進捗が出ません。歯痒い…来年こそは生活を見直して立て直したいです…（でもこれ毎月ずっと言ってるんですよね🫠）

~~日中のおしごと、今よりもっと穏やかになったら嬉しいな~~


### 良かったこと

**最先端のロボット研究！たのしい！！ロマンがある！** やっぱりロボットの研究は楽しいです。ITのお仕事と違って物理的な実態があって色んな要素が絡みます。
ヘビロボでやりたいこと、ヘビロボならではのやれることも無数にあります。たのしい。まだ世の中にないものを切り拓くロマンでしか摂れない栄養がありますよね。来年こそもっとラボに安定して通える暮らしを手に入れるんだーーーーーー

あとこれは「ストレートなD進と比べて」良かったことですが、金銭的な心配も薄いです。フルタイムで働いているのでそれはそう、の声もありそうですが、社会人Dとしての進学を許していただいた弊社各位には頭が上がりません。
特に直属の上司は色々と奔走していただいたそうで…ありがとうございました…

当然ですが就職の心配もありません。働いてるので。この先どうなるんだ生きていけるのか的な不安がないのは精神衛生的にとても良いことだと思います（ロボ系のDは他分野と比較して就職有利とも聞くので元から心配少ないかも、ですけどね）

## 懺悔

色々な研究アドバイスや諸々のお膳立てなど、研究室の先生には非常ーーーーーーーーに世話にお世話になっております。遅々として進まない現状でも根気強くご指導いただき頭が上がらない現状、己の力不足を日々痛感しています、申し訳ありません…徐々にでも進めていけるように、口先だけにならないように頑張りたい気持ちです。


## おわりに

いかがでしたか？万人に薦められるキャリア、とは全く思いませんが、もし似たような境遇で悩んでいる方に向けて、何かの一助になれば幸いです。

最後に研究室および弊社にてお世話になっている各位へのお礼で本稿は終わりたいと思います。ありがとうございました！！！！！
18日目: Persistent SegmentTreeを実装する

[競プロ用ライブラリを作る Advent Calendar 2024](https://qiita.com/advent-calendar/2024/yukkku-ribitol)の17日目です.

https://qiita.com/advent-calendar/2024/yukkku-ribitol

# Persistent SegmentTreeって?

過去の情報を取得できるセグ木です.
ここでは「コピーのコストが低いセグ木」として実装します.

# 仕組み

[SegmentTree](https://qiita.com/Yukkku/items/3d0609efb2845cafc1a9)は二分木のような構造で列を管理するデータ構造でした.
そして[PersistentArray](https://qiita.com/Yukkku/items/e45fc3c365fa6aaf5e49)は木構造で列を管理して複製コストを抑えるデータ構造でした.

ということで, この2つを組み合わせます. 上手く書けば通常のSegmentTreeよりも実装が楽です.

```rs
// サンプルコードではi32の足し算を計算する永続セグ木を実装します
#[derive(Clone)]
enum SamplePersistentSegTree {
    // 末端要素
    Leaf(i32),
    // 要素数が2以上の列. 永続配列と同じように, 2つの列の表現のペア + 付加情報で表現する
    Trunc {
        // 要素数
        len: usize,
        // 左の部分木
        left: Rc<Self>,
        // 右の部分木
        right: Rc<Self>,
        // 全体での合計
        sum: i32,
    },
}
use SamplePersistentSegTree::*;

impl SamplePersistentSegTree {
    // 要素数を返す
    fn len(&self) -> usize {
        match self {
            // 要素が1つなので, 1を返す
            Leaf(_) => 1,
            // 要素数を保存してるので, それを返す
            Trunc { len, .. } => *len,
        }
    }

    // 全体での合計を返す
    fn all_sum(&self) -> &i32 {
        match self {
            // 要素が1つだけなので, その値をそのまま返す
            Leaf(v) => v,
            // 合計の値を保存しているので, それを返す
            Trunc { sum, .. } => sum,
        }
    }

    // indexに対応する要素を書き換える
    fn set(&mut self, index: usize, item: i32) {
        assert!(index < self.len());
        match self {
            // 末端の要素に辿り着いたら値を書き換える
            Leaf(v) => *v = item,
            Trunc {
                left, right, sum, ..
            } => {
                let left_len = left.len();
                // 目的の値が左右どちらに含まれてるか調べて, 適切な方に書き換えクエリを送る
                if index < left_len {
                    Rc::make_mut(left).set(index, item);
                } else {
                    Rc::make_mut(right).set(index - left_len, item);
                }
                // 全体の合計値を再計算する
                *sum = left.all_sum() + right.all_sum();
            }
        }
    }

    // 区間[l, r)での合計を返す
    fn range_sum(&self, l: usize, r: usize) -> i32 {
        assert!(l <= r && r <= self.len());
        // l == r なら区間に何も含まれないので0を返します
        if l == r {
            return 0;
        }
        // 全範囲の合計を求められていた場合はadd_sumを返します
        if l == 0 && r == self.len() {
            return *self.all_sum();
        }
        let Trunc { left, right, .. } = self else {
            // 1つしか要素がないRelayの場合は, 上の場合分けに必ず引っかかります
            unreachable!();
        };
        let left_len = left.len();
        // 左右の部分木と被っている区間の情報を取ってきて, その合計を返します
        left.range_sum(l.min(left_len), r.min(left_len))
            + right.range_sum(l.saturating_sub(left_len), r.saturating_sub(left_len))
    }
}
```

# 実装

- [`persistentsegmenttree.rs`](https://github.com/Yukkku/ribitol/blob/main/src/persistentsegmenttree.rs)

上のサンプルプログラムを抽象化して, ちょっと無駄な部分を削りました.

# まとめ

いかがでしたか?

明日は天才文字列アルゴリズムを実装します.
【ESLint】ファイルを無視する方法

## 特定のファイルを無視する方法
`eslint.config.js`に`ignores`を記述することで特定のファイルを無視できます。
以下のように記述した場合、`semi`のルールにおいて`**/*.config.js`は無視されます。

```js:eslint.config.js
export default [
    {
        files: ["src/**/*.js"],
        ignores: ["**/*.config.js"],
        rules: {
            semi: "error"
        }
    }
];
```

以下のように独立したオブジェクトに`ignores`を記述した場合にはグローバルにファイルを無視します。

```js:eslint.config.js
import js from '@eslint/js';

export default [
    {
        files: [
            '**/*.js'
        ],
        ...js.configs.recommended
    },
    {
        ignores: [
            'ignored.js'
        ]
    }
];
```

## 参考

https://github.com/eslint/eslint/issues/17400#issuecomment-1646543502
Select系コンポーネントでvalueの型を厳密にする

## この記事の概要

Selectコンポーネントを自作しようとして、`defaultValue`とoptionとして渡ってくる要素のvalueが一致していないとエラーが出るようにしたかったです。

備忘録がてら記事にしました。

## 環境

TypeScript 5.4以降
（記事内で使っている`NoInfer`はTypeScriptの5.4から使用できます）

## 実装

```tsx
import { ComponentProps } from "react";

type SelectOption<T extends string> = {
  label: string;
  value: T;
};

type Props<T extends string> = ComponentProps<"select"> & {
  defaultValue?: NoInfer<T>;
  label: string;
  options: readonly SelectOption<T>[];
  placeholder?: string;
};

export function Select<T extends string>({
  defaultValue,
  label,
  options,
  ...props
}: Props<T>) {
  return (
    <div>
      <label>{label}</label>
      <select
        defaultValue={defaultValue ?? ""}
        {...props}
      >
        {placeholder ? (
          <option value="" disabled>
            {placeholder}
          </option>
        ) : null}
        {options.map((option) => (
          <option key={option.value} value={option.value}>
            {option.label}
          </option>
        ))}
      </select>
    </div>
  );
}
```

## 型に適合しない場合

例えば以下の場合はdefaultValueの`pink`がoptionsのvalueの中にありません。

```typescript
<Select
  label="セレクト要素のラベル"
  defaultValue="pink"
  helperText="ヘルパーテキスト"
  options={[
    { label: "Red", value: "red" },
    { label: "Blue", value: "blue" },
    { label: "Green", value: "green" },
  ]}
/>
```

その場合以下のように怒られます。

```typescript
Type '"pink"' is not assignable to type '((string | number | readonly string[]) & ("red" | "blue" | "green")) | undefined'.
```