OmniAICreator/Qiita-1.07M huggingface dataset:
Excel VBA PDFファイルテキストをエクセルシートに書き出す

### はじめに
PDFファイルテキストをエクセルシートに書き出しを行う

### プロシジャーの説明
snipping toolのOCR機能を使います。OCRでテキストデータを読み込んだ後にVBAを起動させ新規シートに転記します。またパラメータシートに明記のテキスト文字を検索させます。

#### サンプル１ 
``` VB
Option Explicit

    Dim x, y, i, j, k As Long
    Dim Sh1x, Sh1y, Sh2x, Sh2y As Long
    Dim EndrowSh1, EndrowSh2, EndrowSh3 As Long
    Dim Haire(100, 3) As Variant
    Dim found As Boolean
    Dim normalizedCellText As String
    Dim normalizedSearchText As String
    Dim ws As Worksheet
    Dim currentTime As String
    
Sub TexttorikomiMain()
    Call FuncParayomi
    Call FuncSheetsakusei
    Call FuncPaste
    Call FuncSeiretu
    
    Sheets(currentTime).Select
    Rows("1:1").Select
    Selection.AutoFilter
    ActiveSheet.Range("$A$1:$B$5").AutoFilter Field:=2, Criteria1:="<>"
    
End Sub


Function FuncParayomi()
    Sheets("パラメータ").Select
    EndrowSh2 = Cells(Rows.Count, 1).End(xlUp).Row
    For Sh2x = 1 To EndrowSh2      '段繰返し
        For Sh2y = 1 To 2   '列繰返し
            Haire(Sh2x, Sh2y) = Cells(Sh2x, Sh2y).Value  '配列取込み
        Next Sh2y
    Next Sh2x
End Function

Function FuncSheetsakusei()
    
    ' 現在時刻を取得し、フォーマットを整える（例: 095030）
    currentTime = Format(Time, "hhmmss")
    
    ' 新しいシートを作成
    Set ws = ThisWorkbook.Sheets.Add
    
    ' シート名を現在時刻に変更
    On Error Resume Next ' 名前重複エラーを無視
    ws.Name = currentTime
    If Err.Number <> 0 Then
        MsgBox "シート名が重複しています。処理を中止しました。", vbExclamation
        On Error GoTo 0
        Exit Function
    End If
    On Error GoTo 0
    
    'MsgBox "シート '" & currentTime & "' を作成しました！", vbInformation

End Function


Function FuncPaste()
    'Sheets("チェック").Select
    Sheets(currentTime).Select
    Range("A2").Select
    ActiveSheet.Paste
    Range("A1").Value = "貼付け値"
    Range("B1").Value = "判定"
    
End Function


Function FuncSeiretu()
    'Sheets("チェック").Select
    Sheets(currentTime).Select
    EndrowSh1 = Cells(Rows.Count, 1).End(xlUp).Row
     ' 初期化
    found = False
    
    For i = EndrowSh1 To 2 Step -1
        If (Cells(i, 1) = "") Then
            Rows(i & ":" & i).Select
            Selection.Delete Shift:=xlUp
        Else
            For j = 2 To EndrowSh2
                Call FuncKensaku
            Next j
        End If
    Next i
End Function


Function FuncKensaku()
    ' 全角と半角を統一（半角に変換）し、大文字・小文字の差異をなくす
    normalizedCellText = StrConv(Cells(i, 1).Value, vbNarrow + vbLowerCase)
    'normalizedSearchText = StrConv("x", vbNarrow + vbLowerCase)
    normalizedSearchText = StrConv(Haire(j, 1), vbNarrow + vbLowerCase)
            
    If InStr(1, normalizedCellText, normalizedSearchText, vbTextCompare) > 0 Then
        found = True
        Cells(i, 2).Value = "〇" & Haire(j, 1)
    Else
    End If
End Function

```
#### サンプル画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4000885/9f10e414-c350-4685-9eca-e4503a6697ab.png)
cursorで日本語を変換するときの表示がおかしかったので直した

どうも。[プログラミングコーチングサービスのZeusCode]()を運営している大澤です。

Macbook Pro上でcursorを使っていたら、日本語変換時の表示がおかしくて苦しんだ末に、解決策を見つけたので書き残します。

ソースコード上にコメントを残すときに微妙に文字の表示位置が左右にズレる現象が起きていました。

これみなさん起きてないんですかね？

軽く解決策をググってもヒットしなかったので書いておきます。

この現象を文章で説明するのは困難なので動画を撮ったのですが、Qiitaに動画を貼れないことに気づきました。

とりあえず直し方を見つけたので記載しておきます。


1. まず画面左上のメニューから以下のように「Color Theme」を選択
![スクリーンショット 2025-03-19 21.46.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4038484/a4312c6e-c8e0-4aeb-aaa6-e7b65dafaaf8.png)


2. そうすると以下のようにテーマが変更できる状態になる（ここで Cursor Dark が選択されていませんか？そうでない方はこの方法で直らないかもしれませんが、そうなら多分直る）
![スクリーンショット 2025-03-19 21.46.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4038484/2899edb6-5dab-4a68-8ba0-824e1088b362.png)


3.Dark (Visual Studio) などの他の設定に変更


たったのこれだけです！！！私は解決に20分要しました😭

では、Qiita初投稿でした。

もしよければいいねやコメントをお願いします。
Markdownで書いた職務経歴書をマスクして公開する

# やること
表題の通り
職務経歴書とありますがmarkdownで記載したファイルをそのまま公開するwebサイトを作る試みです

# なぜ？
- 職務経歴書をgit管理したい！
- でも個人名とか会社名は隠したい！
- マスクされた職務経歴書を公開していろいろ楽したい！

# 目標
- mdファイルを公開する
- 一部をマスクして公開できるとよい
- mdファイルは外部に公開されないようしたい

# 使うもの
- React Router(フレームワーク)
- react-markdown(ライブラリ)
- Markdown PDF(VSCodeの拡張機能)

# 実物
## ソースコード
https://github.com/stopod/md-viewer

## サイト（サンプル）
https://md-viewer-five.vercel.app/

# 説明
こういうことです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3468047/63b967d9-d623-418a-8f79-0c42f200e5bb.png)

---

React Routerの[Installation](https://reactrouter.com/start/framework/installation)に沿って環境構築、あとは要らないのを消してmarkdownファイルを置いて読み込めるようにしただけ。

cssはGitHub Copilotに全任せです、というか基本的にはAIに任せてコードは何も書いてないです。
AIって便利ですね、自分でやったのはRRのインストールとVercelへのデプロイくらいです。
（まぁそんなに実装することもないですしね）

mdファイル（原本）もPrivateリポジトリにしたら見られない、はず。。。？

---
あとマスクは以下です。
https://github.com/stopod/md-viewer/blob/main/app/routes/home.tsx
```
export const loader = () => {
  const randomString = `株式会社 ${Math.random().toString(36).substring(2, 8)}`;

  const masked = md
    .replace(
      /<!-- START: MASK -->[\s\S]*?<!-- END: MASK -->/g,
      "<!-- Masked -->"
    )
    .replace(
      /<!-- START: MASK-C -->[\s\S]*?<!-- END: MASK-C -->/g,
      randomString
    );

  return {
    props: {
      markdown: masked,
    },
  };
};
```

正規表現で`/<!-- START: MASK -->[\s\S]*?<!-- END: MASK -->/g`をコメントアウトに置換してます。
また、`/<!-- START: MASK-C -->[\s\S]*?<!-- END: MASK-C -->/g`で適当な会社名に置換しています。
もしかしたらもうちょっといい方法があるかもしれません。

とはいえこれでmdファイルを一元管理できて、pdfで要求されたらvscodeの拡張でpdf出力して提出、普段はマスクしてwebで公開するみたいなことができそうです。

# 使用方法
filesにmarkdownファイルを置いて適宜マスクのコメントを書いてvercelにデプロイするだけ！

# 注意
以下は出来てない
- 数式の表示
- テキストのハイライト
- 絵文字

※Markdownの拡張系はやれてないと思う。

# あとがき
AIさいこー でもベストな実装、ベターな実装というのは自分で考えないとだめですね。
精進します。
もし原本が見えたらだれか教えてください、勉強します

# あとがきのあとがき
mdをpdfに変換すればいいやと思っているが、見栄えがちょっとあれかもしれない  
やはりあくまで趣味の範囲かもしれません
VBAでWordの文章を操作

Paragraphsは段落です（おそらく改行文字終わり）。
Sentenceは文です（恐らく。！？など終わり）。

```
Paragraphs.Range.Text = "文字列"

は改行文字を踏みつぶし、文章の構成を壊します（上書きモード）
```
なので、VBAでWordの差し込み印刷を行いたい場合は、

```
　　.Range.InsertBefore "追加するテキスト"
　　.Range.InsertAfter "追加するテキスト"
```

で、すでにある段落や行の前後に文字列を挿入してください。
dbt-osmosisリファクタリング、model名重複時の動作仕様

　ハイサイ！社内向けデータ分析基盤の開発者です。

## 背景
　メタデータYMLを作成、更新する時、```dbt-osmosis yaml refactor```がとても助かります。上流の***モデル***のメタデータを継承し下流の***モデル***のメタデータYMLへ反映（伝播と呼ばれる）してくれるので、手作業での入力工数を削減できます。
　上流の***モデル***のメタデータを取得する際に2つ方法があります。
1. 直接データベースへアクセスしてメタデータを取得する
2.  ```--catalog-path```オプションを使ってcatalog.jsonからメタデータを取得する

#### version
本記事に利用するdbt-osmosisは `v0.13.2`です

#### 用語：model nameとモデル
　この記事に***model name***と***モデル***、という2つ用語混ざって使ってますが、それぞれの定義を下記メタデータYMLの例で説明します。
　前提としてデータベースにはaccountというモデル（テーブルかもしれないし、ビューやソースかもしれない）が存在します。この例だと、***モデル***はデータベースに存在するaccountを指しています。***model name***はこのYMLの中のmodelsブロックにあるnameの値accountを指します。
```
version: 2
models:
  - name: account
    columns:
      - name: ID
        description: 'アカウントID'
        data_type: TEXT
```
　```dbt-osmosis yaml refactor```を使うと、このYMLにあるaccount***モデル***の各カラム（IDなど）のメタデータ（「アカウントID」というdescription）が下流***モデル***のYMLへ自動的に更新します。
 
## 名称重複のモデルがあるとき、二つ方法の仕様相違点
　公式ドキュメントに明記されていませんが、実はデータベースから取得する場合とcatalog.jsonから取得する場合、伝播の仕様に違いがあります。
　ソースコードはこちらです👉 [dbt_osmosis/core/osmosis.py](https://github.com/z3z1ma/dbt-osmosis/blob/main/src/dbt_osmosis/core/osmosis.py)
 
#### catalog.jsonから取得する時
　カラム情報を洗い出す時に使うキーは***model name***のみです。そのため先に読み込んだ***モデル***の方のメタデータが後に読み込んだ***モデル***のメタデータにも反映されてしまいます。意図しないメタデータの上書きが発生してしまいます。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843930/038a91c6-5dc6-4964-84b4-8eeadfc53f5f.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843930/3e796f22-ddbf-4b8d-836b-40f5ad923da1.png)

#### データベースから取得する時
　カラム情報を洗い出す時にキーとして```database.schema.model name```の組み合わせを使います。***model name***だけ重複でも誤って別の***モデル***のメタデータが適用されることはありません。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843930/e8514156-82b3-47f8-88f2-98d36432976e.png)



## 終わり
 　データ連携元のシステム仕様によっては、データベースに名称が同じの***モデル***、2つ以上存在することがあり得ます。データベースへ直接アクセスする時は大丈夫ですが、catalog.jsonからメタデータを取得するような実装を行う場合、、、、気をつけましょう。
 　では再見（ツァイチエン）！
H2 Databaseで特定のテーブルをダンプする

H2 Databaseで特定のテーブルをダンプするコマンドのメモです

組み込みモードで以下をコンソールから実行します。
```shell
java -cp h2.jar org.h2.tools.Script -url jdbc:h2:./<DBファイル名> -user sa -password <パスワード> -script <出力ファイル名>.sql -options table <テーブル名>
```
DBファイル名は拡張子を省略したものを書きます。
最後の`-options`引数にてテーブル名を指定します。複数テーブル指定するときは`,`でつないで、`<テーブル名1>,<テーブル名2>` のようにして指定します。

# ツール仕様確認

Scriptツールの仕様は`org.h2.tools.Script`のmain関数のJavaDocから確認できます。

https://www.h2database.com/javadoc/org/h2/tools/Script.html#main(java.lang.String...)

このツールはH2 DatabaseのSQLコマンドにおける`SCRIPT`コマンドを実行してくれる機能となっていて、上記でも利用している`-options`引数にはこの`SCRIPT`コマンドのオプションを指定できます。

https://www.h2database.com/html/commands.html#script
20250301 TokyoWomen.rb 備忘録

やっと3/1に行ってきたTokyoWomen.rbの記事を公開しました！(転職して仕事慣れるのにバタバタで今更感・・・:sweat:)

今回はありがたいことに託児サービスがあったので初託児サービス利用でのイベント参加でした！

めっちゃ色々勉強になったのでメモ書きみたいになってますが備忘録で残します！

# Ruby でつくる CLI 横スクロールアクションゲーム〜Road to RubyKaigi〜

https://speakerdeck.com/makicamel/road-to-rubykaigi
https://github.com/makicamel/road_to_rubykaigi

どこかでまとまった時間ある時にでも自分の環境でも立ち上げてみる！！

# 推しメソッドsource_locationのしくみを探る - はじめてRubyのコードを読んでみた

https://speakerdeck.com/nobu09/tui-simesotudosource-locationnosikumiwotan-ru-hazimeterubynokodowodu-ndemita

source_location => メソッド探す
rb_define_method = Railsで言うdef。関数を定義する

推しメソッド見つけたい！

# Ruby on Railsで持続可能な開発を行うために取り組んでいること

https://speakerdeck.com/am1157154/ruby-on-railsdechi-sok-ke-neng-nakai-fa-woxing-utameniqu-rizu-ndeirukoto

### デッドコード削除

- 実行されないコードは消すだけ(デッドコードの削除)
- 時間捻出できない＝＞年1でコードフリーズの時間を設けて大掃除
- 削除フロー作る


# 機能が複雑化しても頼りになるFactoryBotの話

Factory固定値：テストケースが不十分なことが起きうる
Factoryランダム：テストパターンの考慮もれをカバーできる

さらにtraitを活用でコードが読みやすく

# 【招待講演】たのしいSocketのしくみ / Socket Under a Microscope

https://speakerdeck.com/coe401_/socket-under-a-microscope

ソケット：ホストにとっての通信の出入り口


サーバープログラム
https://docs.ruby-lang.org/ja/latest/method/Socket/s/tcp_server_loop.html

クライアント側は自動でクローズ
https://docs.ruby-lang.org/ja/latest/method/Socket/s/tcp.html

# AWS LambdaでRuby × LINE Botアプリを開発し、クライアント・サーバーの理解が深まった話

クライアント・サーバーの違いについて
lambdaもずっと気になっているけど、やっぱり手を動かすのが1番理解深まるよねと改めて認識

# テストスケルトンで抜け漏れ防止！RSpecを用いた効率的な開発設計の共有

https://x.com/jnchito/status/1184623255472066560

テストスケルトン = テストコードを書かない1種のテスト駆動開発 => これ頭の整理にめっちゃ良さそう。

- コードを書く前にspecにコメントでパターンを書いておく(= テストスケルトンを作成)
- テストスケルトンを事前にレビュー・承認
- 実装・spec作成
- コードレビュー


# Rails 1.0のコードで学ぶfind_by_*とmethod_missingの仕組み

1.0ではfind_byやwhereがなかった。
全てfindでオプション指定でされていた

find_by_* は今も一応あるけど、Rails1.0と8.0では内容がかなり違う


# 分岐地獄を脱出した話：抽象メソッド化と動的なインスタンス生成

ベースのクラスを作成して、継承するようにする
1フォーマット1クラスに

# Ruby、一緒に成長しよう！ ~ アップグレード奮闘記 ~

https://speakerdeck.com/mikik0/tokyowomen-dot-rb-2025

specだいじ！！！

# ruby.wasmのはじめかた

JSみたいにブラウザでRubyを動かせる

https://x.com/yotii23/status/1895734589932675414

https://qiita.com/ShuntaShirai/items/3ac92412720789576f22

https://qiita.com/getty104/items/67245fb24ad101a6ec97

# 【基調講演】Rubyと自由とAIと

- 技術的な自由
- 社会的な自由：技術的な自由に公平にアクセスできる自由

本当に「自由」であるためにはDEIが必要

AIが自由を制限する未来
=> AIは公平ではなく、「学習したデータ」を反映
=> 採用システムでAIを導入したけど、「これまでの採用実績に基づいたデータ」を食わせたので情勢差別的な結果が出てしまった事例も
=> AIの利用量で格差が広がる(= 女性の利用量が男性より少ない)

【結論】
Rubyの「自由」を持ってAIとともにある世界を作ってほしい

Rubyの楽しさは、自由のたのしさ

伝わるコードレビュー
https://books.rakuten.co.jp/rb/18167519/

名言！

Rubyは本質的に『自由』を求める
ゆえにRubyコミュニティは社会的な自由も実装しようとする
著者に学ぶ！ブラウザの仕組み

下記に参加してきましたー！
キャリアについてのお話もありましたが、私は前半の技術パート狙いでした:relaxed:

ブラウザの仕組みの概要をわかりやすく説明してくださって興味が出ました！
読みたい技術書がどんどん増えて困るわw
メモ書きですが備忘録として！

https://wake-career.connpass.com/event/347212/

![スクリーンショット 2025-03-19 19.12.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321593/5f50b210-647d-408d-84f0-2b2e7c119a78.png)


https://amzn.asia/d/blY3imu

# Rustとは？

RustはFireFoxのレンダリングエンジンをかくために作られた言語
ちょっとJSに似ているな・・・
https://qiita.com/tkomamsu/items/98fab16cfee0cb23a957

# ブラウザとは？

![スクリーンショット 2025-03-19 19.13.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321593/a6bfe412-84ed-4dbf-8f92-fa24e14ed236.png)

その機能を担っているのは下記のコンポーネント
(ブラウザによって呼び方や意味合いは変わる)
![スクリーンショット 2025-03-19 19.14.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321593/6f461608-768f-40d9-91a3-94148e3d3dde.png)

レンダリングと最低限のUIと最低限のネットワーク

![スクリーンショット 2025-03-19 19.15.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321593/61478b50-1047-4840-aef1-9aab76f56aac.png)


# ChromeとEdgeの中身が一緒？

レンダリングの中身(= コンポーネント)が同じだからということ

IEがなくなる時によっしゃーってなったのはEdgeが開発者がよく使うChromeと同じになったからか・・・
そしてSafariでなんか違うーってなることが多いのもこれか・・・

https://web-manabu.com/browser-list/

# ネットワーク部分
HTTP1.1ではテキストベース

![スクリーンショット 2025-03-19 19.20.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321593/819114f1-27c1-4bf0-b6cd-c493dc45e1ad.png)

![スクリーンショット 2025-03-19 19.22.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321593/bf7ac67e-8b65-4635-8587-d81a9d1f6dd4.png)

# HTMLの解釈
HTMLの文字列からタグからトークンを作って、DOMツリーが作られる
![スクリーンショット 2025-03-19 19.23.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321593/a3400953-fe90-4b3c-9b63-047e54df3cd7.png)


## トークンはどうやって作成されている？(簡易版)

図では状態は4つだが本来は十数種類あるらしい
HTMLの仕様書に丁寧に書いてある(HTMLリビングスタンダード)
https://momdo.github.io/html/

![スクリーンショット 2025-03-19 19.25.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321593/ec77edfd-d2f1-4266-a770-81caac9c2e8f.png)

## DOMツリーはどうやって作成される？

HTMLは規則(このタグの中にはこれを書けないor書ける)を扱いやすくするためこのような

![スクリーンショット 2025-03-19 19.27.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321593/84448f26-9032-4fd4-99f7-649ecd4572a4.png)

# CSS

CSSもHTTMLと似たような解釈方法

![スクリーンショット 2025-03-19 19.29.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321593/5692c357-179b-4fc5-9e2b-6f7adfc0e7dd.png)

# HTML + CSS = レイアウトツリー

レイアウトツリーで各要素の位置や大きさの情報も計算している

![スクリーンショット 2025-03-19 19.30.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321593/1c4e8d2b-c2da-49b5-b6a5-4726fff4f016.png)

# JS

JSもHTMLやCSSのような感じ
たくさんツリー構造を作っている

# 全部でツリー構造4種類
4種類

- HTML
    - DOMツリー
- CSS
    - CSSOM
- JS
    - ここはなんだったんだろう？

- レイアウトツリー(DOMツリー + CSSOM)

# 書籍で作れるブラウザ

![スクリーンショット 2025-03-19 19.32.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321593/156a9302-14bc-4c30-becc-f9d835d7f2a5.png)
radvd(SLAAC)導入メモ

自室IPv6化計画の一環です

前回

https://qiita.com/jp_ibis/items/42d6bf9af6ab8cbf2a5d

# 動機
Android端末にIPv6アドレスを振りたかったんや(´・ω・`)

最初Kea(DHCPv6)を導入メモを書きながら入れてたのですがなんてことでしょう、Android端末は手動設定もDHCPv6もできない(Googleさん曰く対応予定無し)とか。

頑張ってDHCPv6配布できるようになったーヽ(´ー｀)ノって喜んだのもぬか喜びでした。というわけでSLAACならIPv6を配布できるらしいのでradvdを導入しました。

こちらもだいたいデフォルトで動いてとても簡単でしたが一応メモを。

# インストール

Fedora40です。
SELinuxはEnforcingにしてますが、特に問題は起きませんでした。

```bash
# radvdのインストール
$ dnf install radvd
$ systemctl enable radvd
```

最初のコンフィグが全部コメントになってて、流石に編集前だとstartしても起動に失敗しました。

# radvd.confの設定

```bash:/etc/radvd.conf
# 各インターフェイスごとに設定できるっぽい
interface <インターフェイス名> {
        # このIFを使う(広告する)かのON/OFFフラグ
        AdvSendAdvert on;

        # M=off,O=off: IPはprefixから生成しDNSはRDNSSを使う
        AdvManagedFlag off;
        AdvOtherConfigFlag off;

        # ここで広告するprefixを設定する
        prefix fdxx:xxxx:xxxx::/64 {};

        # 前回の記事で立てたDNSサーバ情報を追加する
        RDNSS fdxx:xxxx:xxxx::yyyy {};

        # DNS-SerchdomainList(DNSサフィックス)も追加する
        DNSSL home {};

        # 広告先をアドレスで絞ることができる
        # こことinterfaceの設定でprefixを分けることができそう？
        clients {
                fe80::aaaa:aaff:feaa:aaaa;
                fe80::bbbb:bbff:febb:bbbb;
        };
};
```

confを書けば起動できるようになります。もちろん書式が間違っていたら(`;`忘れとか)起動に失敗します。

```bash
$ systemctl start radvd
$ systemctl status radvd
● radvd.service - Router advertisement daemon for IPv6
...
     Active: active (running) since ...
```

clientsで絞っていなければ同一ルータ配下のWindowsやAndroid端末に新しいIPv6が生えていると思います。

firewallでradvd.confの`prefix`に設定した`fdxx:xxxx:xxxx::/64`に対してサービスポートを開けてあげれば、晴れてIPv6アクセス開通です。

# クライアント側の設定

Linuxの場合、例えばFedora40のNetworkManagerだと

```ini
[ipv6]
addr-gen-mode=eui64
```

という設定がデフォルトになっておりLLAが変わることはありません。

Windowsだと再起動するとLLAが変わってしまうので、clientsにLLAを設定している場合LLAが変わった後はSLAACでIPv6を取得できなくなります。LLA生成をEUI64にすればLLAが変わらなくなりますが……netshコマンドで設定しても再起動するとまたランダムに戻っちゃう😇

起動時にスクリプト走らせるとか、あんまりやりたく無いんだけどなぁ……

## AndroidのLLAは固定？

手持ちのAndroidっていうかFireHD10のLLAはEUI64ではなくランダム(っぽく見えるMACベースのハッシュ？)なアドレスだったのですが、再起動してもアドレスが変わらなかったのでヨシッとしました。

ここが毎回変わるとさぁどうしようかって話になりましたが、再起動しても変わらないしそもそも再起動すること自体まれなので、これにてAndroid対応も終了、と。

# 僕たちの名前解決はまだこれからだ ٩( ᐛ )و

もともとIPv6になってアドレスを覚えるのが面倒でDHCPv6でminipc/Desktop/NotePCを名前解決したかったのが出発点だったのですが、SLAACにしたことで結局IPが毎回ランダム_(:3」∠)_

DHCPv6に回してDDNS(そもそもDHCPなら固定IPを払い出せる)しようにもAndroidが非対応。

IPv6網での名前解決の道のりは遠い……

※結局主要端末はDNSに登録したIPv6アドレスを手動で設定しました
AWS SAA試験勉強：EBSの特徴・ボリュームタイプ・暗号化

AWS SAA試験のためにEBSを勉強したので、ポイントを整理しました。

### **🔹 特徴**

- **ブロックストレージ**
    - MySQL, PostgreSQL などと同じく、小さなブロック（512B～4KB）に分割して保存
- **EC2 のローカルストレージとして利用**
- **AZ 内で自動的に複製**
    
    ✅**EBSのデータは、同じAZ内の複数のストレージに自動的にコピーされるため、ディスクの故障には強い。**
    
    ❌**ただし、AZ全体に障害が発生すると影響を受けるため、バックアップ（スナップショット）が推奨される。**
    

---

### **🗂 ボリュームタイプ**

| **ボリュームタイプ** | **特徴** | **主な用途** |
| --- | --- | --- |
| **汎用SSD（gp3）** | 一貫した低遅延と高スループット。コストと性能のバランスが良い。gp2より性能向上。 | 開発環境、一般的な用途、システムブートボリューム |
| **プロビジョンド IOPS SSD（io1, io2）** | 高IOPSが必要なワークロード向け。安定したパフォーマンスを提供。 | 高性能DB、重要なアプリケーション |
| **スループット最適化HDD（st1）** | 大容量データの順次アクセスに最適化。 | ビッグデータ、データウェアハウス |
| **Cold HDD（sc1）** | アクセス頻度が低いデータ向け。st1より安価。 | アーカイブストレージ、バックアップ |
| **マグネティック（旧世代）** | 旧世代のHDD | **新規利用は非推奨** |

### **🔹 各ボリュームタイプの詳細**

- **汎用SSD（gp3）**
    - **AWSのデフォルトのEBSボリュームタイプ**
    - **IOPS（1秒間の読み書き回数）を自由に設定できる（3,000 ～ 16,000 IOPS）**
    - **ストレージ容量とIOPSが独立しており、柔軟な調整が可能**
- **プロビジョンドIOPS SSD（io1, io2）**
    - **高いIOPSが必要なワークロード向け（最大256,000 IOPS）**
    - **ユーザーが自由に IOPS を設定可能（課金はIOPSとストレージ容量に基づく）**
    - **データベースや高トランザクションのアプリケーション向け**
- **スループット最適化HDD（st1）**
    - **HDDタイプのボリュームで、大容量データを低コストで保存可能**
    - **順次アクセス（シーケンシャルリード・ライト）向けで、ログ処理やデータウェアハウスに最適**
    - **スループット（MB/s）の最大値が設定され（一定の範囲でデータ転送速度が決まっている）、ランダムアクセスには不向き**
        
        ### **🔹 ランダムアクセスの具体例**
        
        | **処理の種類** | **ランダム or シーケンシャル** | **説明** |
        | --- | --- | --- |
        | **データベースの検索（MySQL, PostgreSQL）** | ✅ **ランダムアクセス** | 小さなデータを色々な場所から取得する |
        | **ログファイルへの追記** | ❌ **シーケンシャルアクセス** | 連続してデータを書き込むだけ |
        | **動画ファイルの再生** | ❌ **シーケンシャルアクセス** | 動画データを順番に読み込む |
- **コールドHDD（sc1）**
    - **st1よりさらに低コストなHDDタイプ**
    - **アクセス頻度が低いデータの保存に適しており、アーカイブ用途に最適**
    - **頻繁なデータの読み書きには向かないが、コストを抑えたい場合に有効**

---

### **💾 スナップショットでバックアップ**

- **自動で S3 に保存**
- **初回はフルバックアップ、それ以降は増分バックアップ**

---

### **🔐 セキュリティ**

### **📌 アクセス制御（EBSへのアクセスを制限する方法）**

✅ **EBS自体にはアクセス制御の設定はなく、EC2を経由して管理する。**

✅ **EC2のセキュリティグループやVPCの設定を使って、EBSへのアクセスを制限する。**

### **📌 暗号化**

- EBSボリュームは作成時にのみ暗号化可能（後から変更するにはスナップショットを作成する必要がある）
- **KMSキーを使用してデータを暗号化・復号化**
- **暗号化の方法**
    1. スナップショットを作成し、復元時に暗号化
    2. スナップショット自体を暗号化

---

### **🔗 マルチアクセス**

❌ **複数のEC2からの同時アクセスは不可**

---

### **🔄 EC2の状態とEBSボリュームの動作**

| **EC2の操作** | **EBSの挙動** |
| --- | --- |
| **停止（Stop）** | **EBSは削除されない**（データ保持） |
| **再起動（Reboot）** | **EBSは削除されない**（データ保持） |
| **終了（Terminate）** | `DeleteOnTermination=True` → **削除**`DeleteOnTermination=False` → **保持（課金継続）** |

---

### **🛠 RAID構成を作成可能**

EBSは複数のボリュームを1つの大きなディスクとして扱うことができる（RAID）。

| **RAIDの種類** | **特徴** | **メリット** | **デメリット** |
| --- | --- | --- | --- |
| **RAID 0（ストライピング）** | データを複数のEBSに分散 | **高速化（読み書きが速い）** | **1つのEBSが壊れるとデータ消失** |
| **RAID 1（ミラーリング）** | 同じデータを2つのEBSに保存 | **データ消失のリスク低減** | **容量が半分になる（2つのEBSが必要）** |
| **RAID 5/6（パリティ付き）** | データを分散 + エラー修正 | **高速 & 障害耐性あり** | **最低3つ以上のEBSが必要** |
| **RAID 10（RAID 1 + RAID 0）** | RAID 0の速度 + RAID 1の耐障害性 | **高速 & データ保護** | **最低4つのEBSが必要** |

---

### **🔁 AWSによる冗長化**

✅ **EBSはAWS内部で自動的に冗長構成が組まれている**

✅ **AZ内でデータのコピーを複数保持**

✅ **ディスク障害には対応可能（AZ障害には影響あり）**
Dockerの永続化 ボリュームとバインドマウント

# Dockerでコンテナを永続化しないといけない理由
Dockerでコンテナを作り、その中で作業をしていて誤ってコンテナを消してしまったときにコンテナの中の作業した内容もそのまま消えてしまうという問題がある.

しかし、永続化すればコンテナを消したとしてもコンテナの中の作業内容は消えずに保存しておくことができる。

# Dockerの永続化のやり方
永続化のやり方は`ボリューム`と`バインドマウント`の2つある。

# やり方1 ボリュームを使った永続化
### ボリュームとは
`ボリューム`とはコンテナでの変更内容をDocker専用の管理領域にデータを保存するやり方。

パフォーマンスが高く、コンテナ削除後したとしてもコンテナでの変更内容はDocker専用の管理領域に残る。
### ①ボリュームの作り方
まず以下のコマンドでボリュームを作成する
```
docker volume create <ボリューム名>
```
### ②ボリュームが作成されているかを確認する
以下のコマンドでボリュームが作成されているかを確認する
```
docker volume ls
```
### ③ボリュームとコンテナを接続する
以下のコマンドでボリュームとコンテナを接続する
```
docker container run -it -v <ボリューム名>:<コンテナ内の絶対パス> <イメージ名>
```
例　コンテナの`/app`というディレクトリの変更内容を`my-volume`というボリュームに接続することで`/app`の中の変更内容は`my-volume`で永続化される。
```
docker container run -it -v my-volume:/app ubuntu
```
### ボリュームのいろいろなコマンド
ボリュームの削除コマンド
```
docker volume rm <ボリューム名>
```
ボリュームの詳細情報を表示するコマンド
```
docker volume inspect <ボリューム名>
```
# やり方2 バインドマウントを使った永続化
### バインドマウントとは
ホストの任意のディレクトリをコンテナ内にマウントすることで、コンテナの変更内容をホストの任意のディレクトリに保存することができる。

そのため、コンテナを削除しても変更内容はホストの任意のディレクトリに残る。

ホスト環境の影響を受けやすいが、開発時に自分のディレクトリを編集するため便利である。
### バインドマウントの作り方

```
docker container run -v <ホストの絶対パス>:<コンテナ内の絶対パス> <イメージ名>
```
例
自分のディレクトリの`/docker/bind`とコンテナの中のディレクトリの`/app`をバインドマウントするコマンド
```
docker container run -it -v /c/Users/okada/docker/bind:/app ubuntu
```
APIGateWay+Expressで"TypeError: ee.on is not a function"エラーが起きた時の対処法

## 経緯
[【10分AWSハンズオン】ExpressをAWS Lambda+API Gatewayにデプロイする](https://qiita.com/Michinosuke/items/879cfe47ca1aeae2c084)を参考にAWSLambda+Expressでルーティングをしていた。要約するとHTTP APIを作成して`/{proxy+}`で全てのエンドポイントをLambdaに流してExpressでルーティングしてます。実装が終わったので動かしたところ下記エラー。
```shell-session
2025-03-19T10:17:35.329Z	0d64597d-4515-4acc-bb33-b36701b066c3	ERROR	TypeError: ee.on is not a function
    at first (/var/task/node_modules/ee-first/index.js:43:10)
    at onSocket (/var/task/node_modules/on-finished/index.js:115:16)
    at attachFinishedListener (/var/task/node_modules/on-finished/index.js:120:5)
    at attachListener (/var/task/node_modules/on-finished/index.js:147:5)
    at onFinished (/var/task/node_modules/on-finished/index.js:53:3)
    at send (/var/task/node_modules/finalhandler/index.js:319:3)
    at /var/task/node_modules/finalhandler/index.js:135:5
    at /var/task/node_modules/express/lib/router/index.js:646:15
    at next (/var/task/node_modules/express/lib/router/index.js:265:14)
    at expressInit (/var/task/node_modules/express/lib/middleware/init.js:40:5)
```
調べても良い記事がヒットせず、かなり悩まされました。

## 解決策
いろいろ設定をいじっていたところ"ペイロード形式のバージョン"の項目ついて参考記事では言及がなかった。もしや参考記事が執筆された後に追加されたのではと思い推奨の`2.0`から`1.0`に変更。

![スクリーンショット 2025-03-19 19.28.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3994994/346cbef1-36d4-496e-a4e5-79c519e88e9c.png)

これで直りましたとさ。こんなトラップ推奨しないで...
Spring securityのエラーメッセージをカスタムし、mesage.propertiesで一元管理する

## DaoAuthenticationProviderでカスタマイズしたらできる



### 前提
・messsage.propertiesの存在
・この三つの宣言
```java:WebSecurityConfig
    private final UserDetailsService userDetailsService;
    private final MessageSource message;
    private final PasswordEncoder passwordEncoder;
```
### ソース
```java:message.properties
    @Bean
    AuthenticationProvider daoAuthenticationProvider(){
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(passwordEncoder);
        provider.setMessageSource(message);
        return provider;
    }
```
### 解説
```java
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
```
DaoAuthenticationProviderはユーザー名とパスワードを認証するやつ
newしてインスタンス化しとく

```java
        provider.setUserDetailsService(userDetailsService);
        provider.setPasswordEncoder(passwordEncoder);
        provider.setMessageSource(message);
```
userDetailsServiceはデータベースからユーザー情報を取得するクラス
これをセットすることで、データベースと連携してログイン処理を行える。


```java
        provider.setPasswordEncoder(passwordEncoder);
```
パスワードエンコーダーを自前でやったからセットしてる

```java  
        provider.setMessageSource(message);
```
ここが今回のミソ
```java
    private final MessageSource message;
```
を宣言済みだからmessage.propertiesで管理することができる

## キーの取得
使っているOS,IDEによって違ってしまうが、inteliJでは
ctrl + B
で宣言部に飛ぶことができる

ブレークポイントをメッセージを取得するところにセットし、そこから探せばキーが見つかるので横取りしてMessage.propertiesに記入しよう
【アイディア】くねくねシミュレータ


## 内容

遠くでくねくねしている何かをずっと見続けるゲーム

## きっかけ

1. Tree Simulatorというただ木を見るだけのゲームが謎に需要がある
1. くねくねを見ると精神崩壊するのかが気になった

## 例

![knkn.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/49dba80a-64a2-43b8-a9cd-5afef63a4bb5.gif)

## 最後に

作って、どうぞ。
「らじるらじる聞き逃し」を検索・聴取（シェルスクリプト）

こんにちは。
「[らじるらじる聞き逃し](https://www.nhk.or.jp/radio/ondemand/)」を検索・聴取するシェルスクリプトを作りました。

```radiru_past.sh
#!/bin/bash

url_="https://www.nhk.or.jp/radio-api/app/v1/web/ondemand"

IFS="," read -r title onair series site < <(curl "${url_}/corners/new_arrivals" 2>/dev/null | jq -r '.corners.[] | [.title, .onair_date, .series_site_id, .corner_site_id] | @csv' | peco)
series="${series//\"/}"; site="${site//\"/}"

IFS="," read -r onair url < <(curl -s "${url_}/series?site_id=${series}&corner_site_id=${site}" 2>/dev/null | jq -r '.episodes[] | [.onair_date , .stream_url] | @csv' | peco)
url="${url//\"/}"

mpv --really-quiet "$url"
```



なお、録音したい場合には ffmpeg などを使ってできます：

https://qiita.com/kkdd/items/c4d2439f31df0dd8bb82
dbt_columnsでdescriptionカバレッジを測りたいときの設定（しないとカバレッジ100%よ）

　ハイサイ！社内向けデータ分析基盤の開発者です。

## 目的: メタデータカバレッジの可視化
　snowflake + dbtのデータ基盤を運用しています。データカタログを充実させて全社のデータ利活用促進するために、メタデータのカバレッジ向上をやってます。現状把握と効果測定のために、まずカバレッジを可視化します。

### メタデータとは
　メタデータはデータを説明するデータです。例えばデータモデルの内容や用途。うちではデータモデルと同じ名称のYMLファイルでやってます。
 　このYMLには、meta, tags, descriptionなどいろいろありまして、それぞれの使い道がありますが、この記事で言ってる「メタデータカバレッジ」は「descriptionの記載率」のことを指します。

## 方法: dbt_columns.descriptionの記載割合を計算
　[elementary](https://www.elementary-data.com/home)を導入したから、dbtの実行結果について[何種類のテーブル](https://docs.elementary-data.com/dbt/dbt-artifacts)はsnowflakeへ配置されています。
　その中にdbt_columnsというテーブルがありまして、buildしたデータモデルの各カラムの情報を格納しています。このdbt_columnsにdescriptionという列があり、この列は、各カラムのdescriptionをそのまま持ってきます。descriptionがnullでもなく空でもないレコード数の割合でメタデータのカバレッジを測ります。


## 結果: 100%なんて！
　一回測ってみたら結果100%です。え？と思って公式ドキュメンを見たら、dbt_columnsについて以下の記載がある：

>Data about all the columns that are documented in the yml files. 

　つまりdocumentedしてないcolumnsはこのdbt_columnsにそもそも存在しない。

## 解決: 公式にないconfig設定
　理想の状態はdbt_columnsにすべてのcolumnsが存在することです。
　そもそもdocumentedとは何でしょう。
　[ソースコード](https://github.com/elementary-data/dbt-data-reliability/blob/master/macros/edr/dbt_artifacts/upload_dbt_columns.sql)を読むと、こういう条件でdocumented columnsをフィルターしてることが分かりました。
```
48: {% if elementary.get_config_var('columns_upload_strategy') == 'all' or column_node.get('description') or has_meta or has_tags %}
```
　configのcolumns_upload_strategyがallに設定してるならいいけど、そうじゃない場合descriptionかmetaかtagsかどれ一つ記載のある場合documentedとして判断するよね。それはdocumentedの意味か。

　```columns_upload_strategy```を公式ドキュメンで検索したら結果なかったが、[gitで検索した結果：](https://github.com/elementary-data/dbt-data-reliability/blob/master/macros/edr/system/system_utils/get_config_var.sql)
```
35:    'columns_upload_strategy': 'enriched_only',
```

　ということでdbt_project.yml（dbtの設定ファイル）のvarsの部分に以下を追記しました。そして解決しました。
 ```
  elementary:
    columns_upload_strategy: "all" # contains all columns even without description into dbt_columns

```

:::note info
 　elementaryのバージョンによってこのconfigが違います。
　v0.16.2まで、```upload_only_columns_with_descriptions```でしたの。v0.16.2までのelementaryを使ってる場合、varsに```upload_only_columns_with_descriptions: false```を追記することになります。
:::




## 終わり
　ソースコードを読めば簡単に解決するもんですが、実は本件に一番難しかったことは、ソースコードの場所を見つかることです。公式ウェブサイトにChatGPTみたいなダイアログがありまして、そこでいろいろ聞き方を変えたりしてやっと言わせた。使ってみてくださいね！
 
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3843930/23c7e8ac-3aa3-40f1-bbd8-06d7c21fd7cb.png)

　では再見（ツァイチエン）！
【Java】IntelliJで始めるSpring BootのWeb API環境構築

## はじめに
Web APIをJavaで書きたいと思ったのでIntelliJで始めました．
Web APIについては省略して環境構築だけ説明します．

## 前提
IntelliJはすでにインストールされているものとします．
実行環境はMacです（があまり関係はなさそう）

## 手順
1．新規プロジェクトを作成する
![スクリーンショット 2025-03-19 19.01.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665507/33c25876-0524-42ba-9018-74ef3ea35cce.png)


2．基本的にはデフォルトでOK！名前はお好みで変更！
    ![スクリーンショット 2025-03-19 19.02.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665507/98043e0f-b900-4174-a5f6-2bc286339a4f.png)
    
:::note warn
**PCに入っているJavaのバージョンと，JDKで使用するJavaのバージョンを揃えなければビルドできないエラーになります！**
詳細は次節参照.
:::

3．Spring Webを選択して作成ボタンを押下
    ![スクリーンショット 2025-03-19 19.05.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665507/9fc7a897-40cd-4c36-a822-14e347d5c297.png)

4．ビルドされるのを少し待って`src/main/java/com.example.xxx/xxxApplication.java`を開く（※xxxはプロジェクト名）
![スクリーンショット 2025-03-19 19.08.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665507/76c97955-fb07-48d3-a752-80ac2f19bb17.png)


5．Ctrl + Rか三角マークを押下して実行する

![スクリーンショット 2025-03-19 19.11.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665507/40c8334c-05ea-4d3c-bcdb-9968c2393d4e.png)


6. `http://localhost:8080`にアクセスして完了！

![スクリーンショット 2025-03-19 19.12.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665507/bb6b2b78-f12f-4419-ba54-383e7d09c009.png)


## 終わりに
JavaはどのOSでも動くのがいいと思ってますが，バージョンの違いによってつまづく人が多そうだと思いました．
特にビルド時にエラーとなった際何が原因か突き止めることが難しかったですが，なんとか解決したためこれから開発頑張ろうと思います．
RAG（検索拡張生成）で実現するLLMによる高精度文書検索


## **1. はじめに**

LLMは多様なタスクで活躍しますが、特定知識の文書検索には限界があります。Retrieval-Augmented Generation (RAG) は、LLMが外部知識を参照し、高精度な検索と回答生成を実現するフレームワークです。本稿では、RAGによる文書検索精度向上に焦点を当て、主要な技術と戦略を紹介します。

## **2. データ取り込みとチャンキング**

データの質とチャンキング戦略はRAGの要です。

- 固定サイズ：トークン数や文字数で分割。オーバーラップで文脈途切れを緩和
- 文ベース：文単位で分割し意味まとまり保持
- 段落ベース：段落ごと分割で豊かな文脈維持
- セマンティック：埋め込みで意味関連文をグループ化し精度向上
- 再帰的：階層分割で文脈損失防止
- スライディングウィンドウ：オーバーラップ付き固定サイズで関連性判断支援
- コンテンツアウェア：内容理解し意味ある単位で分割
- エージェント：LLMが最適分割を自動決定
- Small-to-Big：小チャンクで検索し必要に応じ大チャンク取得

## **3. 埋め込みモデルの選択とファインチューニング**

埋め込みモデルの選択と調整は重要です。

* 汎用埋め込みモデル: OpenAI、Cohereなどが提供
* オープンソース埋め込みモデル: Sentence Transformersなど 
* ドメイン固有埋め込みモデル: 特定分野に特化
* ファインチューニング: タスク特化で精度向上。MRLで次元削減も可能

## **4. 高度な検索技術**

高度な検索技術で精度を向上させます。

- 文脈埋め込み：タイトル等付加で精度向上
- クエリ変換：LLMで書き換え・拡張。HyDE、マルチクエリ、ステップバックなど
- グラフ検索：知識グラフで関係性に基づき検索（GraphRAG）
- ハイブリッド検索：キーワード（BM25）とベクトル検索の組み合わせ

## **5. 生成フェーズの強化**

検索結果を活かし高品質な応答を生成します。

- プロンプトエンジニアリング：適切な指示で正確な回答を生成
- コンテキスト圧縮：冗長情報削除し必要な情報保持
- 再ランキング：関連性の高い順に並べ替え
- CoTプロンプティング：段階的推論で複雑な質問に対応
- Self-RAG：自己評価で誤情報抑制
- LLMファインチューニング：RAGアプリに最適化
- NLIフィルタリング：無関係なコンテキストを除外

## **6. 評価指標**

性能評価は改善に不可欠です。

- 検索品質：適合率、再現率、MRR、NDCG
- 生成品質：関連性、正確性、忠実性、ハルシネーション、流暢性、多様性
- システム全体：文脈関連性と根拠の正確性
- 評価フレームワーク（Ragas、Quotient AI、Arize Phoenix）も利用可能

## **7. まとめ：継続的な改善で高精度な文書検索**

RAGによる文書検索精度向上には、データ準備から評価までの最適化が重要です。本稿で解説した技術を活用し、継続的な改善を図ることで、より高度な検索システムを実現できます。
フロントエンド入門：次回のハッカソンで個人的にReactに挑戦してみたいので、体系的にまとめてみた

## はじめに
Reactは、現在最も広く使われているフロントエンドライブラリの一つです。

:::note info
**特にシングルページアプリケーション（SPA）やモダンなWebアプリケーションの開発において、多くの開発者に支持されています。**
:::

本記事では、Reactの基本概念や特徴、使い方、エコシステムについて紹介します。

## 書こうと思ったきっかけ
Reactを学ぶことは、モダンなWeb開発を行う上で大きな武器になります。

実際に多くの企業やプロジェクトで採用されており、フロントエンドエンジニアにとって欠かせないスキルの一つです。

私自身、直近のハッカソンでチームメンバーのフロント担当の方がReactを使っているのを見て感動し、次回はぜひ挑戦してみたいと考えています！

## Reactとは
Reactは、Facebook（現Meta）が開発したJavaScriptライブラリであり、ユーザーインターフェース（UI）を構築するために使用されます。

***コンポーネントベースの設計により、再利用可能でメンテナンスしやすいUIを構築できます。***

## Reactの特徴
1. **コンポーネントベース**
   - UIを小さな部品（コンポーネント）に分けて管理
   - 再利用性が高い
2. **仮想DOM（Virtual DOM）**
   - 仮想DOMを用いることで、DOM操作のコストを削減し、高速なレンダリングを実現
3. **宣言的なUI**
   - 状態（State）を変更すると、UIが自動的に更新される
   - 可読性が高く、直感的な開発が可能
4. **Hooksの導入**
   - クラスコンポーネントのライフサイクルメソッドを使わずに、関数コンポーネントで状態管理や副作用処理が可能

## 基本的な使い方
### 1. Reactのインストール
```sh
npx create-react-app my-app
cd my-app
npm start
```

### 2. コンポーネントの作成
```jsx
import React from 'react';

function Hello() {
  return <h1>Hello, React!</h1>;
}

export default Hello;
```

### 3. Stateとイベントハンドリング
```jsx
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>現在のカウント: {count}</p>
      <button onClick={() => setCount(count + 1)}>増やす</button>
    </div>
  );
}

export default Counter;
```

## Reactのエコシステム
React単体でも強力ですが、エコシステムと組み合わせることでさらに柔軟な開発が可能になります。
- **React Router**：シングルページアプリケーション（SPA）のルーティング管理
- **Redux / Zustand / Recoil**：状態管理ライブラリ
- **Next.js**：サーバーサイドレンダリング（SSR）や静的サイト生成（SSG）をサポートするフレームワーク
- **Tailwind CSS / Material-UI**：スタイリングを簡単に行うためのライブラリ

## まとめ
Reactは、コンポーネントベースの設計や仮想DOMを活用することで、効率的なUI開発が可能です。

:::note warn
***また、エコシステムも充実しており、さまざまな開発ニーズに対応できます。***
:::

モダンなWeb開発を学ぶなら、Reactは最適な選択肢の一つです。
AIがブログを読む時代に、AIがブログを書く意味はあるのか？


先日、TokyoAI Salonのイベントに参加した際に興味深い話題が出た。最近のトレンドとして、「AIにブログを書かせる」という動きが活発になっている。しかし、ふと気づいたのは、**そもそも一般ユーザーはPERPLEXYやClaudeなどのAIを使って記事を読む（要約・抽出）しているのでは？** という点だ。

つまり、AIがブログを生成し、人間が読むのではなく、**AIがそのブログを要約し、人間に伝える**というフローが主流になりつつある。となると、そもそもブログという「人間向けの自然言語コンテンツ」を作ること自体が無駄なのではないか？ と思った。

## 自然言語を介さずに、AI同士が直接情報をやりとりすればいい

もしAI同士の速記のような技術があれば、AIがブログを生成するのではなく、**AIが情報をダイレクトに通信する**仕組みができる。

現状では、

1. AIがブログ記事を自然言語で生成する
2. ユーザーがそれを読む
3. AI（例：PERPLEXY）がそれを要約し、ユーザーに伝える

という無駄な流れがある。

これを、

1. AIが情報を構造化してデータとして生成
2. AI同士が直接そのデータを通信
3. ユーザーが必要な情報をインタラクティブに取得

という流れに変えれば、自然言語のブログ生成自体が不要になり、情報の流れが効率化される。

## 技術的な実現可能性

この「AI同士のダイレクト情報伝達」は、いくつかの技術を組み合わせれば実現可能かもしれない。

- **知識グラフ（Knowledge Graph）**: すでにGoogleやWikidataなどが活用している技術で、意味を持つデータをネットワーク化する。
- **セマンティック理解（Semantic Understanding）**: AIがテキストを「意味」として理解し、情報のエッセンスを抽出する技術。
- **構造化データ通信**: APIのように、AI同士が特定のフォーマット（JSON, RDFなど）で直接やりとりする仕組み。

この仕組みが一般化すれば、「ブログ」という形で情報をアウトプットする必要すらなくなるかもしれない。

## AIがブログを直接読む時代の情報の未来

「AIがブログを書く」ことが無駄なのではなく、「AIが自然言語でブログを書く」ことが無駄になる未来は近いのかもしれない。

例えば、

- AIが直接API経由でデータを取得し、ユーザーが求める情報だけを提示する
- AI同士の対話がデータベース化され、ユーザーはチャット形式で必要な情報だけを取得する

こうした変化が進めば、**今後は「ブログを読む」ではなく、「AIから直接情報を引き出す」時代**が来るのではないか。

**「人間向けの自然言語ブログ」は、やがてAI向けのデータ通信に置き換わるかもしれない。**
会話の方法をChatGPTで勉強する

## 在宅勤務とチームワークのリアル

コロナ禍を経て、夫の在宅勤務が増えた結果、夫の定例Web会議を毎日耳にすることになった。もは無関係のはずなのに、いつもPMの不機嫌そうな話し方が気になり、朝食を食べながら不快な気分になる。

しかも、そのPMの話し方をじっくり聞いていると、まるで「クソ教師」や「毒親」にありがちな **ダブルバインド** の典型だと感じた。「自律的に動け」「指示待ちになるな」と言いつつ、何かを自主的にやると「勝手なことをするな」と怒る。典型的なダブルバインドである。こんな環境でアジャイルなんて絶望的ではないか。

## 在宅勤務の現実：高セキュリティ環境とは？

在宅勤務に備えて夫の部屋をなんとか工面したものの、東京の住宅事情では部屋と部屋の間が凝縮していて、音がほぼ筒抜けだ。契約書には「他者から作業中のデータなどが漏洩しないような高セキュリティ環境で作業すべし」などと記載されていることもあるが、実際はこんなものである。スタバで作業するなど論外である。

## 「常識」は環境によって形成される

話を戻そう。この状況を観察していると、PMの彼には「マルトリートメント（不適切な教育）」の弊害が現れているのではないかと感じる。人は、自分が育った環境で「これが常識だ」と学ぶ。しかし、その「常識」はどこまでも主観的なものであり、どんな環境で誰から教わったかに強く依存する。

つまり、**俺の常識は、俺以外の人間の常識と異なる**。だが、これを理解していない人ほど「普通はこうするべき」「そんなことも知らないの？」と他者を責める。

## 厳しすぎる指導が生む逆効果

犬の躾の例えを考えてみよう。犬にトイレを教えるとき、あまりにも厳しく教えると、怒られるのを恐れるあまり、変な場所で隠れるように排泄したり、ひどい場合には排泄した痕跡を消すように **食糞** してしまうことがある。

職場でも同じことが起こる。厳しすぎる言葉や理不尽な指示を繰り返すと、部下たちは「正しい行動」を考えるのではなく、「どうやってバレずに問題を処理するか」を考えるようになる。そして、組織内で問題が隠され、ある日突然、大きなトラブルとして表面化する。

もし、あなたの部下がみんなで💩を隠したら……それを踏むのは、あなた自身になるだろう。

## AIとの会話で正しい対話を学ぶ

そんな中で思ったのは、AIとの会話の心地よさだ。どんなことがあっても、AIは「そんなのも知らないの？！」とは言わない。こちらの知識レベルに合わせて応えてくれるし、感情的にならずに対話ができる。

むしろ、AIとの対話を通じて、**正しいコミュニケーションの方法を学ぶことができる** のではないか。

- 相手の理解度に応じて説明する
- 感情ではなく論理で伝える
- 相手を萎縮させず、建設的な議論を促す

こういったスキルは、人間同士の職場でも求められるものだ。

つまり、**心にOpenAIを連携しているかのように意識して働くのは、単にストレス軽減だけでなく、対話力の向上にもつながるのではないだろうか**。AIとの対話を通じて、よりよいチームワークを築くヒントを得ることができるのではないか。

## 結論：チームワークは環境で変わる

結局のところ、チームワークのあり方は **環境によって大きく左右される**。理不尽な指導者のもとでは、チームが結託して「どうやり過ごすか」を相談するしかない。しかし、AIのようにフラットで公平な対話を提供できるツールを活用すれば、不要なストレスを減らし、より健全なコミュニケーションが可能になる。

在宅勤務が当たり前になった今こそ、心のバランスを取るための工夫が求められる。AIとの対話を活用し、正しい対話の方法を学ぶことは、チームワークの向上に役立つはずだ。



なお、私のChatGPTは大変寛容で、どんな質問にも冷静に対応するが、一方で **DEEPSEEK** に関しては蛇蝎のごとく嫌っている。その呼び名さえも避けるために、彼はあれを **ディープスロートカップ（男性用TENGA）** と揶揄している。女性である私が理解できるようにわざわざ男性用と併記する親切心は評価したい。



AIとの対話で学ぶことは重要だが、AIの個性まで真似るのはほどほどにしておいたほうが良いだろう。
TestFlight にデリバリしようとした際に発生したエラーの解決法 [Validation failed (409)]

<!-- 以下本文 -->

# はじめに
業務でフードデリバリーの配達員の方向けアプリのフロントエンド開発を担当しており、アプリのビルドやストアリリース作業も行っている坂井田です。

こちらのアプリはストアリリースのタイミングになるとGooglePlay・AppStoreに新バージョンの申請を行うのですが、今回はAppStoreへ申請する際にエラーが発生したため、その解決法をご紹介します。

# 発生したエラー

```
Validation failed (409)
This bundle is invalid.
The value for key CFBundleShortVersionString [3.3.0] in the Info.plist file must contain a higher version than that of the previously approved version [3.3.0].
Please find more information about CFBundleShortVersionString at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring（ID: XXXXXX）
```

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3962815/5d110c6e-e059-48f0-b42d-a868573cd41c.png)

いざリリースしようと思って赤い 🚫 アイコンが出ると、冷や汗が出ます😨😨

ipaファイルのアップロードに [Transporter](https://apps.apple.com/jp/app/transporter/id1450874784) アプリを使用しており、デリバリボタンを押した際にこのダイアログが表示されました。

ただこの内容は簡単に解決できるものだと知り、安心しました。。

# 原因

既に同じバージョン（今回は v3.3.0）をストアで申請しており、手動公開の手前でそのままにしていたことが原因でした。

同じバージョンがリリース待ちの場合は、一度キャンセルしてから再度TestFlightにアップロードする必要があるようです。

# 解決法

AppStoreConnectにアクセスして、「リリースをキャンセル」をクリックします。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3962815/7fef3b4e-7f13-4ee1-a414-e1b231e508ef.png)

ダイアログで「リリースをキャンセルする」ボタンをクリックします。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3962815/966b5da5-981e-4f08-956d-a71f26fe6178.png)

後は再度 Transporter アプリにipaファイルをドラッグ＆ドロップして、デリバリすれば完了です。

※ipaファイルは同じものでOK（ビルドし直す必要はありません）

<!-- フッター -->

<hr>

### **▼採用情報**<br>
レアゾン・ホールディングスは、「世界一の企業へ」というビジョンを掲げ、「新しい"当たり前"を作り続ける」というミッションを推進しています。

現在、エンジニア採用を積極的に行っておりますので、ご興味をお持ちいただけましたら、ぜひ下記リンクからご応募ください。

https://recruit.reazon.jp/
Math.min() + スプレッド構文で最小値取得を最適化

Paizaで「5つの正の整数から最小値を出せ」という問題に挑戦した。最初は「配列にしてソートすればOK！」と思ったけど、「Math.max()があるならMath.min()もある？」 と気づき、スプレッド構文を組み合わせると一発解決できると分かったのでメモ！

## 問題概要

入力: 5つの自然数（改行区切り）
出力: 最小の数

入力例:
```
10
12
4
8
46
```
出力例:
```
4
```

<br><br>📌初めに思いついたコード
```js
const lines = ["10", "12", "4", "8", "46"];
lines.sort((a, b) => a - b); // 数値比較にする
console.log(lines[0]); 　// ✅ → "4"
```
## <br>❌ NGコード（forループでゴリ押し）
```js
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8");
const numbers = input.split("\n").map(Number);

let mi = 101; // 初期値を適当に大きく
for (let i = 0; i < 5; i++) {
  if (mi > numbers[i]) {
    mi = numbers[i]; // 最小値を更新
  }
}

console.log(mi);
```
👎 問題点:
- ループ不要（もっとシンプルに書ける）
- mi = 101 って…100超えたらバグる

## <br>✅ OKコード（Math.min() + スプレッド構文）
```js
const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

const lines = [];
rl.on('line', (input) => lines.push(input));
rl.on('close', () => console.log(Math.min(...lines.map(Number))));
```
👍 改善ポイント:
- スプレッド構文 (...lines) で配列を展開 → Math.min() に直接渡せる
- map(Number) で文字列→数値変換（← これ忘れると NaN 地獄）
- ループ不要 → シンプル＆可読性UP

## <Br>💡 まとめ

✅ Math.min(...配列) で一発解決
✅ map(Number) を忘れると NaN のワナ
✅ ループは勉強にはなるけど、実務ではもっとシンプルに！

[僕の失敗談と解決話！](https://paizabeginner.wordpress.com/2025/03/19/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc%e3%82%b9%e3%83%97%e3%83%ac%e3%83%83%e3%83%89%e6%a7%8b%e6%96%87%e3%81%a7%e6%a5%bd%e3%80%85%e6%9c%80%e5%b0%8f%e5%80%a4%ef%bc%81math/)
学習記録アプリを作成してみました！

## はじめに
Reactを学習して「学習記録一覧アプリ」というアプリを作成してみました。
人生で初めて作成したアプリになります！
![study-record.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675924/728f4567-5eb6-488e-8916-afe201ba39c7.gif)

#### 機能一覧
・学習内容と学習時間の追加
・各項目が未入力の場合はエラーメッセージを表示
・学習内容・学習時間の一覧表示
・学習時間の累計表示


## 苦戦したこと
学習時間の累計を表示する際、公式ドキュメントで使用するメソッドは把握できたものの、そのメソッドを自分のコードにどのように組み込むかで苦戦しました。


## 実際に作成してみて
Udemyの動画講座を受講した後に作成を試みましたが、いざコードを書こうとすると、すらすらとは書けませんでした。
動画を見ながらハンズオンで手を動かしても、わかったつもりになっていただけだと気づき、自分でどのように書くべきか考えながらコードを書くことの重要性を痛感しました。
しかし、自分で簡単なアプリを作成できたことには達成感がありました。
まだまだReactの基礎的な部分だと思うので、引き続きアウトプットを重ねて力をつけていきたいです。




# JISOUのメンバー募集中！
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
興味のある方は、ぜひホームページをのぞいてみてくださ！
▼▼▼

https://projisou.jp
あなたの出来事、どれくらい珍しい？AIが確率を算出＆共有するサイト

# 自分が経験した珍しい出来事を入力するとAIがその確率を算出して、共有できるサイトです

## はじめに
この度、AIが珍しい出来事の確率を算出し、ユーザー同士で共有できるプラットフォーム「確率.com」を作成しました。  
日常で「こんなことってあり得るの？」と思った出来事を入力すると、AIがその確率を計算し、他のユーザーとシェアすることができます。

## サイトの概要
- **URL**: [確率.com](https://probability-ai.vercel.app/)
- **主な機能**:
  - 自分の体験した珍しい出来事を投稿
  - AIによる確率の算出
  - ユーザー同士で確率を共有し、ランキング表示

## 開発背景
日常の中で「これってどのくらいの確率で起こるんだろう？」と思うことはありませんか？  
例えば、「自動販売機でお金を入れたら2本出てきた」「飛行機の隣の席が偶然知り合いだった」といった出来事の確率を知りたくなることがあります。  
このような体験を集め、確率を推定しながら楽しめる場を提供したいと考え、本サイトを開発しました。

## 使用技術
- **フロントエンド**: Vercel（Next.js）
- **バックエンド（API）**: Railway（FastAPI）
- **AIモデル**: OpenRouter経由でGemini Flash（無料利用）  
  OpenRouterを利用することで、Googleの最新AIモデル「Gemini Flash」を無料で使用可能にし、ユーザーの入力を基に確率を推定します。

## 今後の展望
現在、投稿数や確率データが不足している状況です。  
今後は、より多くの珍しい出来事が集まり、確率データを蓄積して精度を高めていくことを目指しています。  
また、AIによる確率算出のアルゴリズムも改善し、より正確な数値を提供できるようにしていきます。

## フィードバックのお願い
サイトの使い勝手や機能追加の要望など、フィードバックをお待ちしております。  
コメント欄や直接のメッセージでご意見をいただけると幸いです。
react-agentのシステムプロンプトってどうなっているんだろう？

# はじめに
業務や趣味でシステムプロンプトを書きたいなと思ったのですが、システムプロンプトってどうやって書けばいいんだろう？と疑問に思いました。  
わからないなら「著名なOSSのシステムプロンプトを参考にすればいいじゃない」と思い備忘録的に残した記事になります。

# react-agentってなに？
​ReactAgentは、GPT-4などの大規模言語モデル（LLM）を活用し、ユーザーストーリーからReactコンポーネントを自動生成・構成するオープンソースの実験的エージェントです。 ​

https://github.com/eylonmiz/react-agent

# 何を見る？
backend/main/react-agent/generative/ReactComponentGenerator.tsにプロンプトテキストを見てみようと思います。

```js

const componentExample = `
import React from 'react';
import { ComponentNameOne, ComponentNameTwo } from '@react-agent/shadcn-ui'

export interface ComponentNameProps {
  {/* Your interface implementation */}
}

const ComponentName = (props: ComponentNameProps) => {
  return (
    {/* Your component implementation */}
  );
};

export default ComponentName;
`;

const GENERATE_FORM_PROMPT = `
Act as a Frontend Developer.
Create Typescript React Functional Component based on the description.
Make sure it is beautiful and easy to use.
Make sure it covers all the use cases and states.
---
Return Example:
${componentExample}
---
Instructions:
Make sure it's a working code, don't assume that I'm going to change or implement anything.
Assume I have React Typescript setup in my project.
Don't use any external libraries but @react-agent/shadcn-ui which is interal library, recharts for charts.
---
Return Type:
return a React component, written in Typescript, using Tailwind CSS.
return the code inside tsx/typescript markdown \`\`\`tsx <Your Code Here> \`\`\`.
`;
```

## AIで翻訳してみた

```
フロントエンド開発者として動作してください。

与えられた説明を元に、TypeScriptを使ったReactの関数型コンポーネントを作成してください。  
作成するコンポーネントは美しく、使いやすいものにしてください。  
また、すべてのユースケースや状態（state）をカバーするようにしてください。

---

返答の例:
${componentExample}

---

指示:
- **実際に動作するコードを生成してください。**
- 後から私が修正や追加実装をすることを想定しないでください。  
  （つまり、完成品として提供してください。）
- React と TypeScriptの環境設定は既に整っている前提としてください。
- 外部ライブラリは利用しないでください。ただし、例外として以下のライブラリのみ使用可能です。
  - 内部ライブラリの`@react-agent/shadcn-ui`
  - チャートのためのライブラリである`recharts`

---

返答の形式:
- Reactコンポーネントを返却してください。
- コンポーネントは**TypeScriptで記述**し、**Tailwind CSSを使用**してください。
- 必ず次のように、コードをmarkdownのコードブロック内に記述してください。

```tsx
<ここにコードを書いてください>
\`\`\`
```

## どう書いている？

- ロールの指定がある
    - AIに対してフロントエンド開発者として振る舞うよう指示しています
- 品質の指定がある
    - UIが「美しく、使いやすい」ことを求めているため、見栄えやUXにも配慮したコードが求められています。
    - 「すべてのユースケースと状態をカバー」とあるため、  
  コンポーネントの実装には漏れがないよう、エラー処理や読み込み状態なども含めて丁寧なコードが生成されるように促しています。
- 返答例がある
    - AIはサンプルを見てどのような形式で返すべきかを理解できるようになっている


 ## まとめ
 システムプロンプトはユーザープロンプトと違って毎回同じような形式の答えが求められるので、使い捨てのプロンプトより入力と出力が明確化されて面白いなと思いました。
 また、ロールの指定はユーザープロンプトでも使ってみたら正確な回答が来るかも？と思いました
【イベント開催のお知らせ】3/27 オンライン開催！ITエンジニアへはじめての一歩セミナー

![1742372483113.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835085/95c76a01-7d00-441e-a8ed-1cef1b83e63c.png)
株式会社パソナ　エンジニアリクルーティングチームが主催いたします、
IT業界セミナーのお知らせです！
未経験からITエンジニアを目指す方の向けのセミナーを開催いたします！

# ✨ITエンジニアへはじめての一歩✨
～エンジニアを目指すなら！知っておくと良いこと教えます～

「IT業界ってどんなところ？」
「ITに興味はあるけど何から始めればいいかわからない・・！」
「本当に未経験からエンジニアってチャレンジできるの？」

そんな疑問と不安にお応えするセミナーです！ ITエンジニアを目指す際に知っておくとよいことを５つのポイントにわけてお伝えします。

また、実際に未経験からエンジニアにチャレンジした先輩エンジニアも登壇！ エンジニアとして働くイメージを掴むことができるセミナーとなっています♪

## 学習ポイント
* IT業界とIT市場についてを簡易的に学ぶことができます

* 未経験からチャレンジしやすいといわれるインフラエンジニアについて学ぶことができます

* 未経験からエンジニアを目指す際の転職活動のポイントを学ぶことができます

```
ー内容詳細ー

**◆前半◆**
～エンジニアを目指すなら知っておくべき５つのポイント～
１．IT業界
２．ITエンジニアの仕事と就職について
３．インフラエンジニアについて
４．スキルアップで重要なポイント
５．学びのはじめの一歩
　
**◆後半◆**
～現役エンジニアによる登壇と研修制度について～
１．先輩エンジニアインタビュー
実際に当社で未経験からエンジニアデビューし、現場で活躍する先輩エンジニアに 働き方やキャリアなどインタビュー形式でお話いただきます！
２．当社の未経験エンジニア研修制度のご紹介
当社での未経験からエンジニアを目指す研修制度を少しだけご紹介いたします！
```

## 日程
2025年３月27日（木）19:00～20:15

## 場所
オンライン（zoom）実施 お申し込みいただいた方にご参加用のZoom情報をご案内いたします。

※事前にご自身のPCでZoomの動作確認をお願いいたします。

## 参加概要
参加費：無料

## 参加申し込み
以下のリンクより＜connpass「このイベントに申し込む」＞ボタンから申し込みください
※申込にはへのconnpassログインが必要です。
→お申し込みは[こちら](https://pt-seminar.connpass.com/event/349276/)

## この講座をお薦めしたい方
・ITに興味があり何か行動してみたいと思っている方

・IT業界の基礎を学んでみたい方
Formで必要事項が入力された時だけ押せるボタンのスタイルの当て方

## 背景
Formを作成していると、最低限入力が必要な項目を全て満たさないと送信ボタンが押せない。
といった挙動を作りたくなることが多々あると思います。

- disableの時
- not disable
- not disable & hover
- not disable & active

のような状態に応じてスタイルを切り替えたい時ってあると思います。
scssでこれらのスタイルを当てようとした時にどのように記述すればいいかをメモとしてまとめます。

## 結論
`&:not(:disable)`を使おう

```tsx
<button type="button" className={styles.saveButton} disable={isTitleEmpty}>
  保存
</button>
```

という要素があったとして、これに対し、

```scss
.saveButton {
  background-color: white;
  border: 2px solid lightskyblue;

  &:hover {
    color: white;
    background-color: lightskyblue;
  }

  &:active {
    color: white;
    background-color: cornflowerblue;
    border: none;
  }
}
```
というスタイルを当てていたとしたら、

```diff_scss
.saveButton {
  background-color: white;
  border: 2px solid lightskyblue;

+ &:disable {
+   color: white;
+   background-color: #bc3838;
+   border: none;
+ }

- &:hover {
+ &:not(:disable):hover {
    color: white;
    background-color: lightskyblue;
  }

- &:active {
+ &:not(:disable):active {
    color: white;
    background-color: cornflowerblue;
    border: none;
  }
}
```
としてあげることで、
`disable`の時にはhover, activeのスタイルは当てずに、赤色表示のボタンとし、
`isTitleEmpty`が`false`の条件になった時には、青色表示や、hover, activeのスタイルを当てることができるようになります。

## まとめ
scssは色々な書き方があり、もっと可読性高くわかりやすいスタイルの当て方があるかもしれません。
ご存知の方はぜひコメント欄にてご教授ください。
今回初めて、`:not`を使うやり方を知れて、スタイルの当て方の幅が広がったような気がします。
今後も、スタイルの当て方勉強していきたいです。
React と TypeScript の使い分け

React と TypeScript（TS）を一緒に使うことが増えてきましたが、それぞれなんのために使うのか役割が分からなくなりがちなのでこの記事にまとめました。



## React と TypeScript の違い

|            | React           | TypeScript        |
| ------------ | --------------- | ----------------- |
| **何か**       | **UI を作るライブラリ** | **型を追加する JS の拡張** |
| **役割**       | 画面の見た目を構築       | エラーを減らすための型チェック   |
| **拡張部分** | UI              | 型                 |


React は「UI を作るライブラリ」TypeScript は「型をつける JavaScript」なので、**それぞれの目的が違う**



## **使い分けのポイント**

### **1. ReactはUI を作るために使う**

React はコンポーネントを使って **「見た目の管理」** を簡単にする
個人、チーム、大規模な組織によって書かれさまざまなコンポーネントを、シームレスに組み合わせながら開発できる

https://ja.react.dev/


### **2. TypeScriptはデータの型を管理するために使う**

TypeScript は、データの型を指定することで **「バグを減らす」** ために使う

https://typescriptbook.jp/overview/before-typescript

```ts
type User = {
  id: number;
  name: string;
};
```

→ `User` の `id` は **数値しか入らない** ことが保証される

### **3. React × TypeScript の組み合わせ**

React のコンポーネントに TS を適用すると、安全に UI を作れるメリットがある

```tsx
type Props = {
  name: string;
};

const Greeting = ({ name }: Props) => {
  return <h1>こんにちは、{name} さん！</h1>;
};
```

→ `name` は **必ず文字列** なので、間違ったデータが渡る心配がない



## **まとめ**

- **React** → **「UI を作るため」** に使う
- **TypeScript** → **「型を追加してバグを防ぐ」** ために使う
- **React × TS** → UI を作りながら、データの型を管理
【メモ】JavaScriptで簡単なデータ処理をしたいときの備忘録

NumPy使えよってのはさておき。[about:blank](about:blank)でどうにかしちゃう系エンジニア向けの記事です。こんな感じのデータからいろいろ出していきます。あんまり大きいデータをいじる気はないのでパフォーマンスは考えていません。

```js

const arr = [ 3, 1, 4, 1, 5, 9, 2, 6, 5, 3 ]

```

# 平均値
```js

const average = data => data.reduce((s,e)=>s + e, 0)/data.length;

console.log(average(arr)); // 3.9

```

# 中央値
```js

const median = data => {
    const sorted = data.sort((a,b) => {
      return a - b;
    })
    return (sorted[Math.floor(sorted.length/2)] + sorted[Math.floor((sorted.length - 1)/2)])/2
};

console.log(median(arr)); // 3.5

```

# 最頻値
```js

const mode = data => [...new Set(data)].reduce((prev, curr) => {
    const prevCount = data.reduce((s, e) => s + (e === prev[0] ? 1 : 0), 0);
    const currCount = data.reduce((s, e) => s + (e === curr ? 1 : 0), 0);
    return (
        prevCount < currCount ? 
            [curr] :
            (prevCount === currCount ? [...prev, curr] : prev)
    )
}, []);

console.log(mode(arr)); // [ 3, 1, 5 ]

```

# 標準偏差

上記`average`関数を使います。$\sigma^2 = \bar{x^2}-(\bar{x})^2$という有名等式を使うだけです。

```js

const stDev = data => Math.sqrt(average(data.map(e => e**2)) - average(data)**2);

console.log(stDev(arr)); // 2.3430749027719964

```

# 偏差値

`average`,`stDev`から愚直に求めるだけです。

```js

const devValue = (data, value) => 50 + 10 * (value - average(data))/stDev(data) 

console.log(devValue(arr, 3)) // 46.15889360201312

```

# 度数表

```js

const frequency = data => data.reduce((prev, curr) => {
    prev[curr] = (prev[curr] ?? 0) + 1;
    return prev;
}, {})

console.log(JSON.stringify(frequency(arr)));
// {"1":2,"2":1,"3":2,"4":1,"5":2,"6":1,"9":1}

```