投稿一覧

1-5件 / 77件

【React】Zustandによるグローバル状態管理

Zustandとは React向けの軽量・高速・シンプルな状態管理ライブラリで、フックベースの直感的なAPIを持ち、Reduxよりも少ないコードで状態管理を実現可能です。グローバルな(アプリ全体を範囲とした)状態管理をしたいときに利用します。 インストール方法 npmによってインストール可能です。 copy_allnpm install zustand サンプルコード:カウンターを状態として管理する ストアの定義 store.tsにZustandストアを定義します。 copy_allimport { create } from 'zustand' // 状態の型定義 type CounterState = { count: number increment: () => void decrement: () => void reset: () => void } // Zustandストア作成 export const useCounterStore = create<CounterState>((set) => ({ count: 0, increment: () => set((state) => ({ count: state.count + 1 })), decrement: () => set((state) => ({ count: state.count - 1 })), reset: () => set({ count: 0 }), })) createはZustandが提供するストアを生成する関数であり、ストアの型をジェネリクスに指定し、引数にはストアの初期値とアクションを表す関数を与えます。引数として与えた関数にはset(Zustandが提供する状態を更新するための関数)を引数に指定します。setには原則、現在の状態(state)を入力として受け取り、新しい状態のオブジェクトを返す関数を引数として与えます。例外的に直接オブジェクトを与えることもでき、その場合は現在の状態とは無関係にオブジェクトで指定した値にストアの値を更新します。 ストアの使用 定義したストアをReactコンポーネントで使用するには以下のように書きます。コンポーネントの名称をCounter.tsxとした例です。 copy_allimport React from 'react' import { useCounterStore } from './store' // 自分で定義したストア export const Counter = () => { // ストアの値とアクションを表す関数をフックから取得する const { count, increment, decrement, reset } = useCounterStore() return ( <div style={{ textAlign: 'center' }}> <h1>Count: {count}</h1> <button onClick={increment}>+</button> <button onClick={decrement}>-</button> <button onClick={reset}>リセット</button> </div> ) }

pageview 27

【備忘録】React+ViteでTailwind CSSを使えるようにするまで

Windows11でViteプロジェクトを作成し、その中でTailwind CSSを使えるようにするまでの備忘録を残します。npmによるTailwind CSSのインストール方法が変わったようで、変更後の方法に対応しています。当然、今後また変更される可能性がありますのでご了承ください。またNode.jsは既にインストールされているものとします。 Viteプロジェクトを作成する 新しいViteプロジェクトを作成します。 copy_allnpm create vite@latest sample -- --template react-ts Tailwind CSSをインストールする 作成したプロジェクトのフォルダに移動し、npmでTailwind CSSをインストールします。 copy_allcd sample npm install tailwindcss @tailwindcss/vite Viteプロジェクトの設定を変更する sample/vite.config.tsを以下のように編集します。 copy_allimport { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import tailwindcss from '@tailwindcss/vite' // 追加 // https://vite.dev/config/ export default defineConfig({ plugins: [ react(), tailwindcss(), // 追加 ], }) App.cssにTailwind CSSのインポートを追加する sample/src/App.cssにTailwind CSSのインポートを追加します。 copy_all@import "tailwindcss"; /* 追加 */ #root { max-width: 1280px; margin: 0 auto; padding: 2rem; text-align: center; } .logo { height: 6em; padding: 1.5em; will-change: filter; transition: filter 300ms; } .logo:hover { filter: drop-shadow(0 0 2em #646cffaa); } .logo.react:hover { filter: drop-shadow(0 0 2em #61dafbaa); } @keyframes logo-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @media (prefers-reduced-motion: no-preference) { a:nth-of-type(2) .logo { animation: logo-spin infinite 20s linear; } } .card { padding: 2em; } .read-the-docs { color: #888; } App.tsxでTailwind CSSのユーティリティクラスが使えるかどうか確かめる sample/src/App.tsxのh1タグにfont-boldのクラスを追加します。 copy_allimport { useState } from 'react' import reactLogo from './assets/react.svg' import viteLogo from '/vite.svg' import './App.css' function App() { const [count, setCount] = useState(0) return ( <> <div> <a href="https://vite.dev" target="_blank"> <img src={viteLogo} className="logo" alt="Vite logo" /> </a> <a href="https://react.dev" target="_blank"> <img src={reactLogo} className="logo react" alt="React logo" /> </a> </div> <h1 className="font-bold">Vite + React</h1> {/* font-boldのクラスを追加 */} <div className="card"> <button onClick={() => setCount((count) => count + 1)}> count is {count} </button> <p> Edit <code>src/App.tsx</code> and save to test HMR </p> </div> <p className="read-the-docs"> Click on the Vite and React logos to learn more </p> </> ) } export default App 以下のコマンドでサーバーを立ち上げます。 copy_allnpm run dev Vite + React の部分がボールド体になっていればOKです。 参考 https://tailwindcss.com/docs/installation/using-vite

pageview 35

【FastAPI覚書】FastAPIを試す

環境構築 Python3.6以上のバージョンで仮想環境を作ります。今回はバージョン3.12で仮想環境を構築することにします。 copy_all# 仮想環境を構築 uv venv -p 3.12 .venv312 # 仮想環境を有効化 .venv312\Script\activate 作成した環境にFastAPIとUvicornをインストールします。Uvicornは高速かつ軽量なASGI(Asynchronous Server Gateway Interface)サーバーであり、Pythonの非同期WebアプリケーションとWebサーバー間の通信を標準化するためのインターフェース仕様を提供します。 copy_alluv pip install fastapi uvicorn これで最低限の環境構築は完了です。 エンドポイントと処理内容の記述 現在いる階層に以下の内容でmain.pyを作成します。 copy_allfrom fastapi import FastAPI # FastAPIのインスタンスを生成する app = FastAPI() @app.get('/') # FastAPIインスタンスにエンドポイントを紐づける def index(): # エンドポイントに対する処理の内容を記述する return {'text': 'hello'} エンドポイントの紐づけと処理を定義をどのファイルのどんな名前のFastAPIインスタンスにしたかはサーバーの起動時に必要になってきます。忘れないように控えておいてください。 サーバーの起動 以下のコマンドでWebアプリケーションを起動します。 copy_alluvicorn main:app --reload --port 8000 main:appはmain.pyのappインスタンスをWebアプリケーションとして起動する、という意味になります。--reloadをつけておくことでコードに変更が加えられてもブラウザ側が自動で変更を反映してくれます。--portではWebサーバーを利用するためのポート番号を指定します。 SwaggetUIによるWebアプリケーションの実行 http://localhost:8000/docsから作成したエンドポイントの一覧が確認できます。確認するだけではなく、定義したエンドポイントに対する処理を実行することも可能です。

pageview 47

【pandas】データの代表値を求める

データの代表値をpandasで求める方法を紹介します。 計算する代表値 以下の代表値を計算します。 平均(相加平均) 中央値 最頻値 分散 標準偏差 四分位数 パーセンタイル 各代表値の説明は以下の通りです。 平均(相加平均) 全てのデータを足してデータの個数で割った値です。 $$ \begin{align} {\bar{x}} = \frac{1}{N}\sum\limits_{i}^{N}{x_{i}} \end{align} $$ 中央値 全てのデータを値の大きさの順に並べたときにちょうど中央に来る値です。データの個数が偶数であるときは中央に来る2つのデータの平均値を中央値とします。 最頻値 全てのデータの中で最も多く出てくる値です。 分散 各データが平均値から平均的にどのくらい離れた値を有しているかを、各データの平均値からの差分の2乗を平均することで評価した値です。 $$ \begin{align} s^{2} = \frac{1}{N}\sum\limits_{i}^{N}{\left(x_{i} - {\bar{x}}\right)^{2}} \end{align} $$ 標準偏差 分散の平方根をとった値です。 四分位数 全てのデータを小さい順に並べたときに、小さい方から全体の4分の1の位置に来るデータの値のことを第一四分位数、4分の2の位置に来るデータの値のことを第二四分位数、4分の3の位置に来るデータの値のことを第三四分位数といいます。第二四分位数は中央値と等しいです。 パーセンタイル 全てのデータを小さい順に並べたときに、小さい方から全体の$n$%の位置に来るデータの値のことを$n$パーセンタイルといいます。25パーセンタイル、50パーセンタイル、75パーセンタイルはそれぞれ第一、第二、第三四分位数と等しいです。 サンプルコード copy_allimport pandas as pd import numpy as np # サンプルデータを用意する data = { 'column': [3, 5, 6, 10, 6, 6, 20, 14, 1, 6] } df = pd.DataFrame(data) """ 代表値の計算 """ # 平均値 mean = df['column'].mean() # 中央値 median = df['column'].median() # 最頻値 mode = df['column'].mode() # 複数ある場合が存在するため、結果がSeriesとなる # 分散 variance = df['column'].var() # 標準偏差 std_dev = df['column'].std() # 四分位数 quartiles = df['column'].quantile([0.25, 0.5, 0.75]) # パーセンタイル(90パーセンタイルの例) percentile_90 = np.percentile(df['column'], 90) # 結果の表示 print(f"平均: {mean}") print(f"中央値: {median}") print(f"最頻値: {mode}") print(f"分散: {variance}") print(f"標準偏差: {std_dev}") print("四分位数:") print(quartiles) print(f"90パーセンタイル: {percentile_90}") 以下が実行結果です。 copy_all平均: 7.7 中央値: 6.0 最頻値: 0 6 Name: column, dtype: int64 分散: 31.34444444444445 標準偏差: 5.598610938835137 四分位数: 0.25 5.25 0.50 6.00 0.75 9.00 Name: column, dtype: float64 90パーセンタイル: 14.599999999999998

pageview 48

Linux上に構築した仮想環境をJupyterLabで動かす

準備:仮想環境の作成 JupyterLabで動かす仮想環境を作っておきます。以下では用意した仮想環境の名前を.venv313であるとし、作成した仮想環境と同じ階層にいるものとします。参考:uvコマンドの使い方 ipykernelのインストール 作成した仮想環境を有効化し、ipykernelをインストールします。 copy_all# 仮想環境を有効化する source .venv313/bin/activate # ipykernelを仮想環境にインストールする uv pip install ipykernel カーネルの作成 以下のコマンドを実行し、JupyterLab上で動かすカーネルを作成します。 copy_all# .venv313の仮想環境を有効化するカーネルを作成する # Python3.13(data_science)はJupyterLab上での表示名 python -m ipykernel --user --name .venv313 --display-name "Python3.13(data_science)" カーネルの再起動 仮想環境にパッケージを追加する等の変更を加えたりメモリのリセット(入力/出力の消去)をしたりする場合、カーネルの再起動をするとよいです。ページ上部タブの「カーネル」 > 「カーネルを再起動」から再起動ができます。 補足:カーネルの削除 不要なカーネルを削除する場合は、 copy_alljupyter kernelspec list でカーネルに対する一覧を表示して削除したいカーネルのパスを確認した後、 copy_allrm -rf <カーネルのパス> でカーネルが削除できます。

pageview 62