OmniAICreator/Qiita-1.07M huggingface dataset:
T3Stackのゲスト認証（簡易的）

### What
T3stackで簡易的にguest認証を実装しましたので、方法だけご説明します。

### Code

```
npm create t3-app@latest
```
NextAuthを使うか聞かれるのでyesです。


```.env
# supabaseで取得したリンクです。mode:sessionで取得してください。transactionは使えないです。
DATABASE_URL="supabaseのURL"

# Next Auth
# You can generate a new secret on the command line with:
# openssl rand -base64 32 ←これをコマンドに入力してランダムな文字を取得します。
# https://next-auth.js.org/configuration/options#secret

# 取得したランダムな文字をSECRETに使います。
NEXTAUTH_SECRET="openssl rand -base64 32で取得"
NEXTAUTH_JWT_SECRET="openssl rand -base64 32で取得"

NEXTAUTH_URL="http://localhost:3000"

# discordから取得します
DISCORD_CLIENT_ID="discordから"
DISCORD_CLIENT_SECRET="discordから"
```
参考にしました。

https://zenn.dev/qemel/articles/31fa0810e86e65


schema.prismaは初期状態です。
```
npx prisma generate
npx prisma migrate dev  
```


```typescript:server/auth.ts
import { PrismaAdapter } from "@auth/prisma-adapter";
import {
  getServerSession,
  type DefaultSession,
  type NextAuthOptions,
} from "next-auth";
import { type Adapter } from "next-auth/adapters";
import CredentialsProvider from "next-auth/providers/credentials";

import { db } from "~/server/db";

declare module "next-auth" {
  interface Session extends DefaultSession {
    user: {
      id: string;
      name: string;
      email: string;
    } & DefaultSession["user"];
  }
}

export const authOptions: NextAuthOptions = {
  callbacks: {
    async jwt({ token, user }) {
      console.log("jwt callback", { token, user });

      //pass in user id to token
      if (user) {
        return {
          ...token,
          id: user.id,
        };
      }
      return token;
    },
    async session({ session, token, user }) {
      console.log("session callback", { session, token, user });

      //pass in user id to session
      return {
        ...session,
        user: {
          ...session.user,
          id: token.id,
        },
      };
    },
  },
  session: {
    strategy: "jwt",
  },
  jwt: {
    secret: process.env.NEXTAUTH_JWT_SECRET,
  },
  adapter: PrismaAdapter(db) as Adapter,
  providers: [
    CredentialsProvider({
      name: "Guest Account",
      credentials: {
        // username: {
        //   label: "Username",
        //   type: "text",
        //   placeholder: "空欄で構いません",
        // },
        // password: {
        //   label: "Password",
        //   type: "password",
        //   placeholder: "空欄で構いません",
        // },
      },
      async authorize() {
        const user = await db.user.findUnique({
          where: {
            email: "guest@example.com",
          },
        });
        if (user) {
          return user;
        }
        return null;
      },
    }),
  ],
  secret: process.env.NEXTAUTH_SECRET,
};

export const getServerAuthSession = () => getServerSession(authOptions);

```

あとは、supabase上で"guest@example.com"をレコードに追加しておけばゲストログイン可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3822203/d5225109-2e5a-dae8-f7af-db7037b05e76.png)
GET, POSTをprismaで書く

### What

シンプルなGET, POSTです。

重要なのはuseEffectで初回のみfetchを発火します。

useStateのみだとfetchが遅れるためです。

以下のコードで、投稿と同時に表示されます。

### Code

```sql:prisma/schema.prisma
model Task {
  id        Int      @id @default(autoincrement())
  title     String   @db.VarChar(255)
  createdAt DateTime @default(now()) @db.Timestamp(6)
}
```
ホットリロードでインスタンス大量生成されるのを防ぐコードです。👇️

```typescript:lib/prisma.ts
import { PrismaClient } from "@prisma/client";

const globalForPrisma = global as unknown as {
  prisma: PrismaClient | undefined;
};

if (!globalForPrisma.prisma) {
  globalForPrisma.prisma = new PrismaClient();
}
const prisma: PrismaClient = globalForPrisma.prisma;

export default prisma;

```



```typescript:api/task/route.ts
import { NextResponse } from "next/server";
import prisma from "@/app/lib/prisma";

export const POST = async (req: Request) => {
  try {
    const { title } = await req.json();
    const task = await prisma.task.create({
      data: {
        title: title || "デフォルトタイトル",
      },
    });
    return NextResponse.json({ message: "Task created successfully", task });
  } catch (err) {
    console.error("Error creating task:", err);
    return NextResponse.json(
      { message: "Failed to create task" },
      { status: 500 }
    );
  }
};

export const GET = async () => {
  try {
    const tasks = await prisma.task.findMany();
    return NextResponse.json({ message: "Success", tasks }, { status: 200 });
  } catch (err) {
    return NextResponse.json({ message: "Error", err }, { status: 500 });
  } finally {
    await prisma.$disconnect;
  }
};

```




```typescript:page.tsx
"use client";
import { useEffect, useRef, useState } from "react";

export default function Home() {
  interface task {
    id: number | null;
    title: string;
    createdAt: string | null;
  }

  const [tasks, setTasks] = useState<task[]>([]);

  const fetchAllTasks = async () => {
    const res = await fetch(`/api/task`, {
      method: "GET",
    });
    const data = await res.json();
    setTasks(data.tasks);
    console.log(data.tasks);
  };

  const postTask = async (title: string) => {
    const res = await fetch(`/api/task`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ title: title }),
    });
    fetchAllTasks();
    return await res.json();
  };

  useEffect(() => {
    fetchAllTasks();
  }, []);

  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    if (valueRef.current?.value) {
      postTask(valueRef.current.value);
      valueRef.current.value = "";
    }
  };

  const valueRef = useRef<HTMLInputElement>(null);

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <input type="text" ref={valueRef} />
        <button type="submit">タスク作成</button>
      </form>
      <div>
        {tasks.map((task) => (
          <div key={task.id}>
            {task.id}:{task.title}
          </div>
        ))}
      </div>
    </div>
  );
}

```

リロードしないで画面を更新するシンプルな方法です。

もっと良い方法があれば更新します。
【JS】三項演算子で複数の処理を書く


flgがtrueの時に処理Aと処理Bを実行したい場合

```
flg ? console.log(A)とconsole.log(B)を実行したい : null;
```

下記のようにカンマで区切ることで実行可能！

```
flg ? (console.log(A), console.log(B)) : null;
```
統計検定2級　合格体験記~8割取れた勉強法

# 1.はじめに

統計検定2級を8割以上とって合格することができました。
この記事では、統計検定2級を確実に取る上でのアドバイス的なことができればなと思います。

![0C5F1F67-120E-4DBF-BB47-AA4716F8EED8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794915/81505bc3-b78e-d5e0-36cc-c47fee6a2eb4.jpeg)


# 2.受験前の知識レベル・受験のきっかけ

大学の2回生の夏に統計検定を受験しました。専攻は、情報系(コンピュータサイエンス系）ですので少しは確率や統計学についても授業で学ぶ機会はありました。それでも、統計検定を受ける上の知識レベルは高校レベルの範囲は理解している程度だったと考えてもらっていいと思います。

受験しようと思ったきっかけは、元々、確率などは好きで統計学に興味があったのと、データサイエンティストの職業にも興味があるので、最低限の知識は身につけておきたいと思い勉強しました。

# 3.勉強法

勉強には、「統計WEB」「とけたろうさんのサイト,YouTube」「公式問題集(過去問)」を使いました。まず、とけたろうさんのYouTubeで基礎的な内容を一通り理解した上で、公式問題集で問題を解いてみて分からない箇所を「とけたろうさんのサイト,YouTube」、「統計WEB」で分かるようになるまで復習しました。

統計WEB

https://bellcurve.jp/statistics/course/

とけたろうさんのサイト

https://toketarou.com/

とけたろうさんの統計検定2級のYouTube

https://www.youtube.com/playlist?list=PL42v8FcrspQZd9Ob3QZN97IEEvF9dWdXZ

公式問題集

https://amzn.asia/d/aktGdJT

この分野の問題は捨てるなどは考えずに、統計検定2級の範囲内での苦手分野はなくすようにしましょう。過去問を解いてみると、この分野が苦手といったものがでてくることもありますが、解説をしっかり読む、分からなかったら、統計WEBやとうけいたろうさんのサイトなどで、その分野についてもう一度復習してみてください。


# 4.受験し終えての感想

統計検定2級は、勉強する意義が十分にあると思います。この記事を書いているのは、合格してから1年後なんですが、直接的な関わりはなくても、統計的な考え方は役に立つことが多いです。

また、統計検定準1級やデータサイエンティスト検定も受けたいと考えています。みなさんも一緒に頑張りましょう！最後までありがとうございました！
タイタニックの欠損値のある変数を削除した結果

ふと思ったのです、昔は欠損値の補完やらずに78%出していたなと。
そこで欠損値のある変数をすべて削除して予測してみようと。

```Python3
import pandas as pd
train = pd.read_csv("train.csv")
test = pd.read_csv("test.csv")
```
では欠損のある項目と数値でない項目(性別除く)を削除します。
```Python3
train.index = train["PassengerId"]
train = train.drop(["PassengerId", "Name", "Age", "Ticket", "Fare", "Cabin", "Embarked"], axis=1)
test.index = test["PassengerId"]
test = test.drop(["PassengerId", "Name", "Age", "Ticket", "Fare", "Cabin", "Embarked"], axis=1)
```
性別を片方削除します(多重共線性回避)
```Python3
train = pd.get_dummies(train)
train = train.drop(["Sex_male"], axis=1)
test = pd.get_dummies(test)
test = test.drop(["Sex_male"], axis=1)
```

ここから予測に行きます
```Python3
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier as RFC
from lightgbm import LGBMClassifier as LGBMC
from sklearn.model_selection import train_test_split as tts

models = []
x = train.drop("Survived", axis=1)
y = train["Survived"]
x_test = test
df = pd.concat([x, x_test])
ss = StandardScaler()
ss.fit(df)
x = ss.transform(x)
x_test = ss.transform(x_test)

for i in range(200):
    x_train, x_val, y_train, y_val = tts(x, y, random_state=i, test_size=0.2)
    model = SVC()
    model.fit(x_train, y_train)
    models.append([model, model.score(x_val, y_val)])
    model = RFC()
    model.fit(x_train, y_train)
    models.append([model, model.score(x_val, y_val)])
    model = LGBMC()
    model.fit(x_train, y_train)
    models.append([model, model.score(x_val, y_val)])
models = sorted(models, key=lambda x:x[1], reverse=True)

pred1 = models[0][0].predict(x_test)
pred2 = models[1][0].predict(x_test)
pred3 = models[2][0].predict(x_test)

from scipy.stats import mode

y_pred = []
for i in range(len(pred1)):
    y_pred.append(mode([pred1[i], pred2[i], pred3[i]])[0])
```

提出用データ
```Python3
pred = pd.DataFrame(y_pred)
pred.index = test.index
pred.columns = ["Survived"]
pred.sort_index().to_csv("submit_del2.csv")
```

では精度を見てみましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/ebb56a6d-cf97-e765-1f6d-8e52d73f8c34.png)
簡単に77%を超えました。

え？Ageなくしたのに何で？と思ってカーネル密度関数を作ってみました。
```Python3
sns.kdeplot(df_train[df_train["Survived"]==0]["Age"], label="0")
sns.kdeplot(df_train[df_train["Survived"]==1]["Age"], label="1")
plt.legend()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/1bae3227-3fb7-88ed-0d43-e6de59f4aef7.png)
すると生き残ったのが超幼い子供以外ほぼ同じ分布でした。
(Ageあんま関係なかったのか。。。)
投稿 84 PM 2024/09/22

本日の勉強時間 2H

PM（プロジェクトマネージャー）とは、プロジェクトの総責任者としてシステム開発の企画立案や予算の割り出し、人員の管理などを行いプロジェクトを成功に導く職種です。
【 Reactのアンチパターン 】2, ( React Hooks) useEffectの依存配列の誤用とその解決策

## はじめに
React Hooksの`useEffect`フックは、副作用を扱う際に非常に便利ですが、依存配列の設定を誤ると予期せぬ動作やパフォーマンスの問題を引き起こすことがあります。

本記事では、`useEffect`の依存配列の誤用について、悪い例と良い例を挙げて解説します。

## アンチパターン例：依存配列の誤用

```tsx
import React, { useState, useEffect } from 'react';

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

  useEffect(() => {
    // この効果は最初のマウント時にのみ実行される
    console.log(`カウントが${count}に更新されました`);
  }, []); // 依存配列が空

  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count + 1)}>インクリメント</button>
    </div>
  );
}

export default ExampleComponent;
```

### 問題点

:::note alert
**依存配列が空であるため、countの変更を監視できない**
useEffect内でcountを使用しているにもかかわらず、依存配列にcountが含まれていない。
:::

:::note alert
**副作用が意図したタイミングで実行されない**
countが変化するたびにログを出力したいが、最初のマウント時にしか実行されない。
:::


### 最適な解決策：依存配列を正しく設定

#### 方法1：依存配列を正しく設定する

```tsx
import React, { useState, useEffect } from 'react';

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

  useEffect(() => {
    // countが変化するたびに実行される
    console.log(`カウントが${count}に更新されました`);
  }, [count]); // 依存配列にcountを追加

  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count + 1)}>インクリメント</button>
    </div>
  );
}

export default ExampleComponent;
```

#### 解説

:::note info
**依存配列にcountを指定**
countが変化するたびにuseEffectが再実行される。
:::

:::note info
**意図した副作用の実行**
countの変更時にログが正しく出力される。
:::


### 依存配列を省略した場合

```tsx
useEffect(() => {
  // この効果は毎回のレンダー後に実行される
  console.log('コンポーネントがレンダーされました');
});

```

### 問題点

:::note alert
**毎回のレンダーで実行される**
状態やプロップスが変化するたびに効果が実行され、パフォーマンスに悪影響を及ぼす可能性がある。
:::

:::note alert
**予期せぬ副作用の発生**
依存関係が明示されていないため、バグの原因になりやすい。
:::

### なぜ依存配列が重要なのか

useEffectは依存配列を使って、どのタイミングで副作用を実行するかを制御するため、依存配列に指定された値が変化したときにのみ、副作用が再実行されます。

:::note info
**空の依存配列 []**
**最初のマウント時**にのみ実行される。
:::

:::note info
**依存配列を省略**
**毎回のレンダー後**に実行される。
:::

:::note info
**依存配列に値を指定**
指定した値が変化したときに実行される。
:::

### ベストプラクティス

:::note info
**依存配列に全ての依存関係を含める**
useEffect内で使用する全ての状態やプロップス、関数を依存配列に含める。
:::

:::note info
**副作用とレンダーの分離**
副作用の中で状態を更新する場合、無限ループにならないよう注意する。
:::


## まとめ
useEffectの依存配列は、副作用の実行タイミングを正しく制御するために非常に重要です。
依存配列を正しく設定することで、パフォーマンスの最適化やバグの防止につながります。

## さいごに
Reactの基礎的なことですが、開発する際不意にやってしまうので、自分への再勉強としてこれから複数のアンチパターンでまとめたいと思います。


## 参考

https://ja.react.dev/reference/rules/rules-of-hooks

https://ja.react.dev/reference/rules/react-calls-components-and-hooks

## Reactアンチパターン集

https://qiita.com/Tateishi0819/items/03347807c29eaa74058b

【 Reactのアンチパターン 】2, ( React Hooks) 副作用とレンダーの分離：無限ループを防ぐ方法
Unity: Game Viewで視点 (メインカメラ) を移動させる

## 背景
Unityで作ったアプリを起動した際、どのように画面が見えるかは毎回アプリを立ち上げて確認していました。
それだと面倒なので、Game Viewで確認したいと思ったのですが、Game Viewでは視点 (カメラ)を移動できず困ったので、対応した時の覚書です。

## Game Viewでメインカメラを移動する
- 通常はGame Viewで視点(カメラを移動できない)
- Game Viewで視点を移動する方法の1つとして、スクリプトを書いてメインカメラにAttachする

サンプル例
``` csharp
using UnityEngine;

public class CameraMovement : MonoBehaviour
{
    public float speed = 10f;

    // Update is called once per frame
    void Update()
    {
        // More frames are processed per second on higher performance hardware.
        // By multiplying Time.deltaTime, which is the time took to complate the last frame, makes movement independent from the number of frames per second
        float horizontal = Input.GetAxis("Horizontal") * speed * Time.deltaTime;
        float vertical = Input.GetAxis("Vertical") * speed * Time.deltaTime;
        float scroll = Input.GetAxis("Mouse ScrollWheel")  * speed * Time.deltaTime;      

        // x is horizonta, y is vertical and z is zoom
        transform.Translate(horizontal, vertical, scroll); 
    }
}   
```
スタートアップで直面する開発チームの問題をどう解決するか？（前編）

# はじめに
アーリーステージのスタートアップで直面する開発チームの課題について、私自身、これまで何回か経験し改善に向けて対応してきたことをまとめてみました。
皆さん、大体ご存知か、実践している内容かとは思いますが、初めて直面して悩んでいるEMの方や、これからそういった環境で働こうとしているEMの方の少しでもお役に立てればと思います。

# よくある問題
まず最初に「リソース足りない（資金もない）」問題が根底にあり、そこを起因として、いくつかの問題が発生するケースが多いかと思います。

## よくある問題の例

- 開発ラインが複数確保できない（1チーム or 数名で全てに対応する）
- 新規機能と既存機能の改善と不具合対応が一気に押し寄せてくる
- 判断や作業が属人的
- とにかく忙しい

ざっと挙げるとこんな感じでしょうか？

経験したことがある方は「はいはい、あるある。あの時は懐かしかったなー」と思っているかもしれません。

これからそれぞれの問題について、どう対応するか考えていきます。

# リソース足りない問題を考える
リソースが足りないのは、正直、採用を強化するの一択かと思います。

ただ、採用については深すぎるテーマであり、別の機会で検討したいので、ここでは深掘りはしません。

注意しなければならないのは、採用ほど不確実性が高いものはなく、計画通りには行かないため、やり方を間違えると、時間とお金だけが消えていく結果になります。
ですので、しっかりとポイントは抑えて計画を立てた方が良いかと思います。
（これから話すことは、人員計画がある前提で話します）

## 初めにやること
Job Descriptionがなかったら、まずは作りましょう。

当初はフルスタックエンジニアとして採用すると思いますが、フルスタックを基本路線にしつつも、それにこだわらず、バックエンド、フロントエンド、などプロダクトで必要があれば、それぞれのポジションで採用を出しても良いと思います。（ここは人員計画次第）
フルスタックのエンジニアにこだわると、長期間にわたり採用が進まないパターンもあるので、定期的に見直すことをおすすめします。

採用ポジションですが、今後の社外プレゼンスの向上のためにもCTOの存在は大きいので、CTO候補として採用した方がよいかもしれません。

また、Entrance bookと採用ピッチ資料も一緒に作った方が良いかと思います。

## 採用する方法を決める
採用するチャネルはいくつもあり、全部やりたくなりがちですが、優先度を決めて絞った方が運用コスト面からみても効率は良いかと思います。

あくまでも経験上ですが、

「リファラル」＞「エージェント」＞「ダイレクトリクルーティング（＋RPO）」

の優先度で注力していくとよいかと思います。
<br>

まずは __「リファラル」__
こちらは紹介していただくメンバーがいないと難しいですが、もし紹介があれば、マッチする確率は断然高いので、早期にリファラル制度を構築するのが良いかと思います。
<br>


次に __「エージェント」__
ここはエージェントとの相性にもよりますが、エージェントが候補者を提案、もしくは候補者へ会社を紹介してくれるので、こちらが手を動かす時間は少なくなります。
また、高スペックの人材もプールしていることが多いので、そこへの期待も大きいです。
ただし、成功報酬はそこそこかかります。（エージェントによりけりですが）
<br>

最後に __「ダイレクトリクルーティング（＋RPO）」__
ここは、コストとしてどこまでやるかを決める感じです。
あまりコストをかけない（余裕がない）場合は、とりあえず求人を掲載する目的で、どこかに絞って掲載するでも良いかと思います。（自己応募を期待）

コスト的に余裕があるのであれば、RPOにお願いした方が運用は回ります。
社内メンバーでPickからやろうとすると結構工数かかるので大変です。
他にやることが多くあるので、RPOに頼んだ方が生産性は上がるかと思います。

利用するサービスですが、全部網羅すると大変なので、ある程度絞って利用するのが良いかと思います。
成功報酬の有無、利用料などで組み合わせを考えて、似たようなサービスは１つに絞って行く方が良さそうです。
なんとなくのイメージだと下記のカテゴライズを行って、そこから１つ利用サービスを選ぶ感じです。

1. Wantedly or YOUTRUST
2. Findy or Lapras or Forkwell
3. 転職ドラフト（給与レンジで他社に勝てそうであれば）


## 注意すること
モノを作らないことには始まらないため、足りないポジションは業務委託で開発体制をカバーすることをまずは考えるようにしておいた方が良いです。

今現在開発体制で足りていないポジションは、業務委託の方に協力いただいて前に進めていくことが重要です。
ですので、エージェント、ダイレクトリクルーティングについては、雇用形態として業務委託も含めて募集するようにしておくと良いかと思います。

また、紹介やPickの精度を高くするためにも、エージェントやRPOとは定例等で密にコミュニケーションを取ったほうが良いかと思います。
Pick時のFBなどは、こまめに行うと精度が徐々に高くなっていきます。
精度低いままだと、うまく活用できずにコストだけ流れていくので注意が必要です。

このフェーズで採用の作業を行う人は、大体、経営メンバーか主要メンバーになるかと思いますが、採用にかけるコストを考えると、実はリクルーターを１人採用した方が（業務委託でもよいので）コストパフォーマンスが良くなる可能性もあるので、人員計画と採用コストに関しては、しっかりシミュレーションすることをおすすめします。

他にも、面接なりオファーレターなり色々ありますが、それは採用のテーマでまとめて観たいと思います。

話が長くなりそうなので、前編後編の２回に分けて行きたいと思います。

前編はここまでになります。

後編は[こちら](https://qiita.com/lunaluna_222/items/6d6abe6a5dace24d717c)から。
Yupのarray全部試す

## はじめに
業務でYupのarrayについて扱ったのですが、あまりYupについてそもそも理解できていなかったので、どのような処理ができるのかを確かめてみます。

## Yupのarray
以下のような複数入力のフォームに対してバリデーションをかける場合に、arrayを使用します。
<img width='80%' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/9eaaf5e8-ea27-26bb-eaa1-fa4fd7de2497.png'>

なお、後続のコードでは、画面ではなくコンソールログでバリデーションの実行結果を確認します。

### of
#### 概要
ofは配列の中身について一つずつ確認できるメソッドです。

#### 使用例
```javascript
const ofMethodSchema = Yup.array().of(Yup.number().min(2));
console.log(await ofMethodSchema.isValid([2, 3])); // true
console.log(await ofMethodSchema.isValid([1, -24])); // false
```
`of`の中に、さらに`Yup.number().min(2)`を定義しています。
これにより、配列の各項目は数値で最小値が2となります。

### json
#### 概要
要素を`JSON.parse`でjson形式に変換できるかをチェックします。

#### 使用例
```javascript
const jsonMethodSchema = Yup.array().json();
console.log(await jsonMethodSchema.isValid('["a", "b", "c"]')); // true
console.log(await jsonMethodSchema.isValid("not a json")); // false
```
json形式に変換できない場合は`false`を返します。

### length
#### 概要
配列の長さを指定できます。固定長の配列を取得したい場合などに便利です。

#### 使用例
```javascript
const lengthMethodSchema = Yup.array().length(
  3,
  "配列の長さは${length}である必要があります"
);
console.log(await lengthMethodSchema.isValid([1, 2, 3])); // true
console.log(await lengthMethodSchema.isValid([1, 2])); // false
console.log(await lengthMethodSchema.isValid([1, 2, 3, 4])); // false
```
指定した長さより、長くても短くても`false`を返します。
設定した長さは、メッセージ内で`${length}`の形で取得できます。

### min
#### 概要
配列の最小の長さを指定できます。

#### 使用例
```javascript
const minMethodSchema = Yup.array().min(
  2,
  "少なくとも${min}個の要素が必要です"
);
console.log(await minMethodSchema.isValid([1, 2])); // true
console.log(await minMethodSchema.isValid([1])); // false
```
指定した長さより短い場合、`false`を返します。
指定した長さは、メッセージ内で`${min}`の形で取得できます。

### max
#### 概要
配列の最大の長さを指定できます。

#### 使用例
```javascript
const maxMethodSchema = Yup.array().max(5, "最大${max}個の要素までです");
console.log(await maxMethodSchema.isValid([1, 2, 3, 4, 5])); // true
console.log(await maxMethodSchema.isValid([1, 2, 3, 4, 5, 6])); // false
```
指定した長さより長い場合、`false`を返します。
指定した長さは、メッセージ内で`${max}`の形で取得できます。

### ensure
#### 概要
直接的なバリデーションではありません。
入力要素が配列であることを保証（ensure）するものです。

#### 使用例
```javascript
const ensureMethodSchema = Yup.array().ensure();
console.log(ensureMethodSchema.cast(null)); // []
console.log(ensureMethodSchema.cast(undefined)); // []
console.log(ensureMethodSchema.cast(1)); // [1]
console.log(ensureMethodSchema.cast([1])); // [1]
```
`null`や`undedfined`などの空の値の場合には、空の配列を設定します。
配列でない値が渡された場合には、配列の形式に変換します。

### compact
#### 概要
直接的なバリデーションではありません。
配列からfalsyな値を除外するものです。

#### 使用例
```javascript
const compactMethodSchema = Yup.array().compact();
console.log(compactMethodSchema.cast(["", 1, 0, 4, false, null])); // [1, 4]

const customCompactMethodSchema = Yup.array().compact((v) => v === "");
console.log(customCompactMethodSchema.cast(["", 1, 0, 4, false, null])); // [ 1, 0, 4, false, null ]
```
そのまま使用すると、真偽値に変換したときに`false`と判定される値がすべて配列から除外されます。

戻り値として`boolean`を返す関数を定義することで、除外対象をカスタムできます。
上記の例では、空文字のときのみ除外するように指定した関数を定義しています。

## まとめ
Yupのarrayで使える処理をすべてまとめてみました。
compactはかなり使えそうですね。
空文字の入力項目を弾いたり、特定の要素が入っていない場合に弾いたりしてバリデーションを設定することができそうです。

Yupにはまだまだ便利なバリデーションの処理が用意されているので、一つずつ使い方を確認して、またまとめたいと思いました。
SAA合格体験記

## はじめに
AWS Certified Solutions Architect – Associate（SAA）試験にこのたび合格できました。
多忙な日々の中で合格できたため、当時の苦労点や勉強の工夫を伝えられればと思います。

## 試験を受ける前
非機能領域の業務が増えていたものの、背景知識がないまま毎回調べて業務に取り組む状況から脱したかったため。

自分のAWSレベルは、運用保守作業で主要サービスは少し触ったことがある程度でした。
大きめのプロジェクトが並行で走っており、まとまった時間ができるのは基本平日の21時以降（もっと遅いときも多々..）という状況。

## 学習リソース

### 1.参考書（3時間程度）
概要を捉えるために、一読しました。
試験でよく問われる可用性・負荷分散を意識したアーキテクチャ構成について丁寧に解説されていると思います。

- [徹底攻略 AWS認定 ソリューションアーキテクト − アソシエイト教科書](https://www.amazon.co.jp/%E6%A8%A1%E6%93%AC%E5%95%8F%E9%A1%8C%E4%BB%98%E3%81%8D-AWS%E8%AA%8D%E5%AE%9A-%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88%E6%95%99%E7%A7%91%E6%9B%B8-%E7%AC%AC3%E7%89%88%EF%BC%BBSAA-C03%EF%BC%BD%E5%AF%BE%E5%BF%9C/dp/4295016098/ref=asc_df_4295016098/?tag=jpgo-22&linkCode=df0&hvadid=707442440829&hvpos=&hvnetw=g&hvrand=1823856365199259732&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009303&hvtargid=pla-1948536483021&psc=1&mcid=8d445453afda37aeb395899043f141ca&th=1&psc=1&gad_source=1)

### 2. ハンズオン（10時間程度）
問題演習に入る前の肩慣らしとしてやってました。時間がなかったため、問題演習フェーズにすぐ移りました。
個人開発だとなかなかやる機会のない「スケーラブルウェブサイト構築編」「Network編」など絞ってやるのが吉。
- [AWS ハンズオン資料](https://aws.amazon.com/jp/events/aws-event-resource/hands-on/)

### 3. 問題演習（40時間程度）
一番時間をかけました。
基本はping-t。通算2~3周したと思います。
「実際の試験はping-tより難しい」という風の噂を聞いて焦り、1週間udemyの模試を解きました。
udemyの模試は、4-5割しか取れない回もありました。6回中4回目までしか結局解くことができませんでした...
- [ping-t](https://mondai.ping-t.com/g/question_subjects)
- [【SAA-C03版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-knan/)

# スケジュール
### 1ヶ月目
- 週平均3時間程度
- 参考書を一読した後はひたすらping-t
- 最後の1週間はプロジェクトの対応に追われ、殆ど勉強できず

### 2ヶ月目
- 週平均4-5時間程度
- 通勤時間中と、空いてる平日と土日に少しやる程度
- 仕事で体力が奪われ、そのままばたんきゅーしてしまうことも.. 

### ラスト1週
- 毎日1-2時間、前日に7時間の詰め込み
- 最後はサービス別でポイントをまとめ、見直しました（まとめたメモもどこかで出せればと思います）

## 試験当日
udemyで難しい問題に慣れたから大丈夫と思ってたが... 感覚としてはudemyと同等に難しいと感じました。
知らないサービスに関する問題も出ました。自信のない問題は15問程度。正直落ちたと思いました。

## 結果
結果は783点でした。想定より点数が高かったです。
試験問題は65問あり、そのうち採点対象外の設問が15問あるとのこと。
自信のない問題は一部ダミー問題だったのかもしれません。

## 振り返ってみて
「スキマ時間を活用する」・「（ハンズオンでなく）問題をいっぱい解く」の二点を意識して、とにかく進めました。
仕事で頭が疲れて全然勉強できない日もありましたが（情けない..）電車の中でのping-tで知識を積み上げられたと思います。解説を丁寧に理解していけば、ping-tだけでも合格水準は達していたかも。

試験を受ける前と比べると、非機能領域の案件が格段に進めやすくなったと感じています。
AWSサービスの選択肢とそれぞれのメリデメを出すことをスラっとできるようになりました。
勉強時間に対してコスパがいい試験だと思いました。次はSAPに向けて勉強頑張ります🔥
表示的意味論の文献

## はじめに
表示的意味論の文献を適当に列挙してみる（随時追加）。

## 文献一覧
* G. ウィンスケル,末永　幸平 監訳,勝股　審也 訳,中澤　巧爾 訳,西村　進 訳,前田　敦司 訳,[プログラミング言語の形式的意味論入門](https://www.maruzen-publishing.co.jp/item/b304793.html)
* 中島 玲二(1982),[数理情報学入門: スコット・プログラム理論](https://www.amazon.co.jp/dp/4254114133)
* 山田 眞市(1984),[情報処理の科学](https://www.amazon.co.jp/dp/B000J74SZW)
* 横内 寛文(1994),[プログラム意味論](https://www.amazon.co.jp/dp/4320026578)
* 高橋 正子(1979),[スコット理論](https://ipsj.ixsq.nii.ac.jp/ej/?action=repository_uri&item_id=6849&file_id=1&file_no=1) pdf
* 伊藤 貴康(1981),[プログラム理論とその応用（３）](https://ipsj.ixsq.nii.ac.jp/ej/?action=repository_uri&item_id=6490&file_id=1&file_no=1) pdf
* R.D.Tennent(1976),[The denotational semantics of programming languages](https://pages.di.unipi.it/corradini/Didattica/PLP-15/DOCS/Tennent-DenotationalSemantics.pdf)
* D.Scott(1970),[Outline of a mathematical theory of computation](https://ncatlab.org/nlab/files/Scott-TheoryOfComputation.pdf)
* D.Scott,C.Strachey(1971),[Toward a mathematical semantics for computer languages](https://www.cs.cmu.edu/~crary/819-f09/Scott71.pdf)
Transformerモデルを使った自然言語処理

Transformerモデルは、自然言語処理(NLP)のさまざまなタスクで優れたパフォーマンスを発揮しています。この記事では、Hugging Faceの`transformers`ライブラリを使用して、**Text Classification（テキスト分類）**、**NER（固有表現抽出）**、**Question Answering（質問応答）**、**Summarization（要約）**、**Translation（翻訳）**、**Generation（生成）**の各タスクを実際に実行する方法を紹介します。

### 1. インストールとセットアップ
まずは、Hugging Faceの`transformers`ライブラリをインストールします。

```bash
pip install transformers
```

さらに、データの表示に便利な`pandas`ライブラリも使用します。

```bash
pip install pandas
```

次に、Pythonで必要なライブラリをインポートします。

```python
from transformers import pipeline
import pandas as pd
```

### 2. Text Classification（テキスト分類）
テキスト分類は、テキストがどのカテゴリに属するかを予測します。以下のコードでは、テキストに対して感情分析を行っています。

```python
classifier = pipeline("text-classification")

text = """Dear Amazon, last week I ordered an Optimus Prime action figure 
from your online store in Germany. Unfortunately, when I opened the package, 
I discovered to my horror that I had been sent an action figure of Megatron 
instead! As a lifelong enemy of the Decepticons, I hope you can understand my 
dilemma. To resolve the issue, I demand an exchange of Megatron for the 
Optimus Prime figure I ordered. Enclosed are copies of my records concerning 
this purchase. I expect to hear from you soon. Sincerely, Bumblebee."""

outputs = classifier(text)
print(pd.DataFrame(outputs))
```

**結果**：  
このコードは、テキストがポジティブかネガティブかの感情を分類します。Hugging Faceの事前学習モデルが使用され、予測結果が出力されます。

### 3. NER（固有表現抽出）
NERは、テキストから人物名や組織名、地名などの固有名詞を抽出するタスクです。

```python
ner_tagger = pipeline("ner", aggregation_strategy="simple")
outputs = ner_tagger(text)
print(pd.DataFrame(outputs))
```

**結果**：  
固有名詞（例: Amazon, Bumblebeeなど）が抽出され、どの部分が固有表現かを確認できます。

### 4. Question Answering（質問応答）
質問応答は、与えられたテキストの中から、質問に対する答えを見つけ出すタスクです。

```python
reader = pipeline("question-answering")
question = "What is the problem?"
outputs = reader(question=question, context=text)
print(pd.DataFrame([outputs]))
```

**結果**：  
「What is the problem?」という質問に対して、テキスト内から適切な回答を抽出します。

### 5. Summarization（要約）
要約タスクは、長いテキストを簡潔にまとめるタスクです。

```python
summarizer = pipeline("summarization")
outputs = summarizer(text, max_length=56, clean_up_tokenization_spaces=True)
print(outputs[0]['summary_text'])
```

**結果**：  
入力されたテキストが短く要約され、簡潔な形で出力されます。

### 6. Translation（翻訳）
翻訳は、テキストを他の言語に翻訳するタスクです。この例では英語からドイツ語への翻訳を行います。

```python
translator = pipeline("translation_en_to_de", model="Helsinki-NLP/opus-mt-en-de")
outputs = translator(text, clean_up_tokenization_spaces=True, min_length=100)
print(outputs[0]['translation_text'])
```

**結果**：  
テキストがドイツ語に翻訳され、翻訳結果が表示されます。

### 7. Generation（生成）
テキスト生成は、与えられた文に基づいて続きのテキストを生成します。

```python
from transformers import set_seed
set_seed(42)

generator = pipeline("text-generation")
response = "Dear Bumblebee, I am sorry to hear that your order was mixed up."
prompt = text + "\n\nCustomer service response:\n" + response
outputs = generator(prompt, max_length=500)
print(outputs[0]['generated_text'])
```

**結果**：  
入力した文脈を元に、自然な文章の続きを生成します。ここでは、Bumblebeeのクレームに対するカスタマーサービスの返答を生成しています。

---

これらのコードを通じて、Transformerモデルを使った基本的なNLPタスクの流れを確認しました。Hugging Faceの`pipeline`機能は非常に使いやすく、複雑なモデルを簡単に実行することができます。

---

参考文献

https://www.oreilly.co.jp/books/9784873119953/
なんとなくDDD(ドメイン駆動設計)を用いていたらDB駆動設計になってしまった話

# はじめに

都内でエンジニアをしている者です。最近、初めてドメイン駆動設計（DDD）を用いたプロジェクトを担当しましたが、初めての挑戦だったため、結果的にDB駆動設計になってしまいました。この経験から学んだことを共有したいと思います。

# どんな失敗をしたのか

主な失敗は、ドメインオブジェクト（エンティティ）を作成する際に、データベースのテーブルモデルの構造体をそのまま流用してしまったことです。本来、テーブル構造とドメインオブジェクトは独立しており、ユースケースごとにドメインオブジェクトを設計するべきです。しかし、私はDBの構造に引っ張られて、必要以上にDBの設計に依存したオブジェクトを作ってしまいました。

# ドメインオブジェクト(エンティティ)の作成方法

どのようにモデリングすればよいのか当初は悩んでいましたが、以下の記事に出会い、非常に納得できました。

- [参考記事](https://qiita.com/MinoDriven/items/2a378a09638e234d8614)

この記事の「役割」を基にしたモデリングの考え方が非常にしっくりきました。例えば、「りんご」を売るお店のケースを考えるとします。

### 境界づけられたコンテキスト

「りんご」という商品は、売り手と買い手で異なる意味を持ちます。売り手側では「売り物」であり、買い手側から見れば「買い物」です。このように、DDDでは「境界づけられたコンテキスト」と呼ばれる概念があり、役割に応じて異なるモデルを作成することが求められます。

![境界づけられたコンテキスト.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3560529/4a92dc77-a037-f679-46c9-e1df3e8eca94.jpeg)


例えば、売り手側は出荷日や卸値、利益率などの情報が必要ですが、買い手側にとってはそのような情報は不要です。それぞれの視点で「りんご」という商品のエンティティを別々にモデリングする必要があります。

# 実際のコード例

以下に、DB駆動設計になってしまっていたコード例と、それをDDDに基づいて修正したコード例を示します。

### DB駆動設計の例

例として商品をモデリングします

```go
// DBモデルをそのまま流用した場合
type Item struct {
    ID          int
    Name        string
    Price       int
    ShipmentDate time.Time
    WholesalePrice int // 卸売価格
    ProfitMargin float64 // 利益
}
```

このコードでは、「Item」というエンティティが、すべての情報を含んでしまっています。これは、売り手側と買い手側の両方の情報が混在しているため、ユースケースに応じた役割分担ができていません。

### 修正後のDDDに基づく設計例

```go
// 売り手側のコンテキストにおけるItemのモデリング
type SellerItem struct {
    ID           int
    Name         string
    ShipmentDate time.Time
    WholesalePrice int // 卸売価格
    ProfitMargin float64 // 利益
}

// 買い手側のコンテキストにおけるItemのモデリング
type BuyerItem struct {
    ID    int
    Name  string
    Price int
}
```

このように、売り手と買い手の視点で、それぞれのコンテキストに応じたエンティティをモデリングしています。

# 得られるメリット
このようなモデリングをすることによりユースケースによった責務が明確化されます
また、一番のメリットとしてモデルの肥大化を防ぐことができます
例えば今回の場合だと、「買い手」と「売り手」を分けたため、それぞれに必要なドメインロジックを分けることができます
そのようにして整理され肥大化も防ぐことができ保守性も高まっていきます

# まとめ
今回は「役割」を用いたモデリングの仕方について記載しました
エンジニアとしての経験はまだ浅いですが、これまでに感じたことをアウトプットすることで、より深く理解し、改善点を見つけたいと思っています。もしお気づきの点があれば、ぜひご指摘いただければ幸いです。

# 参考にした記事
https://qiita.com/MinoDriven/items/2a378a09638e234d8614

https://speakerdeck.com/pospome/liang-ikodonoding-yi-toshe-ji-neng-li-nobi
エクセルを開いてセル位置、倍率を合わせる

``` xxx.ps1
# 処理対象のファイル名を取得（複数可）　
$targetFiles = Get-ChildItem -Recurse -Path *.xlsx

# Excelオブジェクト作成
$excel = New-Object -ComObject Excel.Application

# 非表示のまま処理する
$excel.Visible = $false

# xlsx ファイルのループ
foreach ($file in $targetFiles) {

    # エクセルを開く
    $book = $excel.Workbooks.Open($file.FullName)

    # シートのループ
    foreach ($WorkSheet in $excel.Worksheets) {
        # 非表示シートは対象外
        if ($WorkSheet.Visible -ne $false) {
            # 処理対象のシートを選択状態にする
            $WorkSheet.Activate()

            # セル「A1」を選択状態にする
            $WorkSheet.Cells.Item(1,1).Select() | Out-Null

            # 表示倍率を100%にする
            $excel.ActiveWindow.Zoom = 100
        }

    }

    # 一番左のシートを選択状態にする（おまけ）
    $excel.Worksheets.Item(1).Activate()

    # 上書き保存する
    $book.save()
    $book.close()
}

# 閉じる
$excel.Quit()
```


``` xxx.bat
@echo on

set ps_file=.\xxx.ps1
powershell -NoProfile -ExecutionPolicy Unrestricted %ps_file%

pause
```
【自学習用】AWS Trysted Advisorとは

# AWS Trysted Advisorとは
【Trusted  Advisorとは】
ユーザーのサービス使用状況をモニタリングし、AWSのベストプラクティスに基づいて
より効率的、最適な使用方法を提案してくれるサービス。

チェック項目が大きく５つある
    1. コスト最適化
    　→設定、使用状況などを分析し、AWSリソースのコスト削減を支援します。
    （使用例）使用していないEBSボリューム、EC2の必要以上のスペックで使用しているリソースの特定などをすることができる。
    ２. パフォーマンス
    　→設定、使用状況などを分析しパフォーマンス向上を支援する
     （使用例）EC2インスタンスが非効率な設定になっていてパフォーマンスを発揮できていない場合などを検知することができる。
    3. セキュリティ
    　→AWS上でセキュリティのベストプラクティスに従った設定ができているかを確認することができる。
   　 (使用例)漏洩したアクセスキーがないか、不要なS3バケットへのアクセス許可をしていないかを確認できる
     4. 耐障害性
     →バックアップが不十分な場合やRDSがマルチAZになっていない場合などにユーザーに対して通知する。
     5.サービスクォータ
     →サービスクオータの80％以上を使用するとユーザーに対してアラートが来るように設定されている。
Grafana+PrometheusでKubernetesノードのCPU温度を可視化してみた

## はじめに

私が[Twitter（現X）](https://x.com/_matoruru)で日々つぶやいている、おうちKubernetes関連の話題です。

本記事では、Kubernetesクラスタ上にデプロイしたGrafanaとPrometheusを使って、CPUの温度を見やすく可視化していきます。

## 完成例

時系列のグラフ（左）と現在の温度表示（右）を並べるレイアウトを目指します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/e4be5abe-8bf8-7337-c5a3-22514096c7dd.png)

## 前提条件

<p>1. Kubernetesクラスタに以下のツールがデプロイされていること。</p>

- Grafana
- Prometheus

<span>2. Grafanaで使用するユーザに</span>**Editor**<span>以上の編集権限が付与されていること。</span>

## 使用するダッシュボード

「kube-prometheus-stack」に同梱されているダッシュボード「Node Exporter / Nodes」を複製して、複製後の方に新しいグラフを追加します。

:::note info
kube-prometheus-stackの初期設定ではダッシュボードが編集不可になっています。Helm valuesの`grafana.sidecar.dashboards.provider.allowUiUpdates`を`true`にする必要があります。
:::

## 時系列のグラフの設定手順

まずはGrafanaにアクセスして、Dashboards>Node Exporter / Nodesを開きます。デフォルトのダッシュボードは下のような感じになっているはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/e1ba6fd5-3b6f-5bdb-8ab5-b47ab43a21ee.png)

上部にあるAddボタンからVisualizationを選択して新規パネルの編集画面を開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/c9aa41dc-6f81-7f82-f6ea-945cc678d624.png)

次に、QueryタブのMetricから以下の項目を設定してRun queriesをクリックしてください。

|項目名|値|
|--|--|
|Metric|node_thermal_zone_temp|
|Label filters|instance=$instance|
|Options>Legend|{{type}}|

正しく設定していれば、この時点でグラフが見えているはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/0d735ff4-1345-95be-4f4b-7ec5a6adef95.png)

ここからは右側のセクションに値を設定していきます。設定し終えたら右上のApplyを押してください。

|項目名|値|
|--|--|
|Panel options>Title|CPU Temperature|
|Axis>Soft min|0|
|Axis>Soft mas|100|
|Standard options>Unit>Temperature|Celsius|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/94a2a5ab-0c80-d88d-a392-35596a03237d.png)

作成されました！

## 現在の温度表示グラフの設定手順

上部にあるAddボタンからVisualizationを選択して新規パネルの編集画面を開きます。

次に、QueryタブのMetricから以下の項目を設定してRun queriesをクリックしてください。

|項目名|値|
|--|--|
|Metric|node_thermal_zone_temp|
|Label filters|instance=$instance|
|+Operations>Aggregations|Avg|

次は、表示形式を変更していきます。右上の「Time series」のドロップダウンから、「Gauge」を選択します。

ここからは右側のセクションに値を設定していきます。設定し終えたら右上のApplyを押してください。

|項目名|値|
|--|--|
|Panel options>Title|CPU Temperature|
|Standard options>Unit>Temperature|Celsius|
|Standard options>Min|0|
|Standard options>Max|100|

同じく右側のセクションの下の方にあるThresholdsは以下のように設定してください。

|色|数値|
|--|--|
|rgb(87, 148, 242)|(Base)|
|rgba(50, 172, 45, 0.97)|40|
|rgba(237, 129, 40, 0.89)|60|
|rgba(245, 54, 54, 0.9)|80|

設定が終わったらApplyを押してください。このグラフもダッシュボードに追加されているはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/de7acbdb-d302-1296-553f-638e0f46b794.png)

せっかくCPUセクションを用意してくれているので、作成した2つをそちらに追加しておきましょう。ついでにパネルの大きさも変更してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/6a6655e3-8058-a653-61e4-2588d3dfd0e5.png)

これで完成です！

保存ボタンからダッシュボードを保存するのを忘れずに！！

## まとめ

Grafanaを使って、Prometheusが取集したデータを簡単に可視化することができました。まだまだ使っていない表示形式や値を通す関数も豊富にあるので、ぜひ他のデータの可視化も試してみてください😊

Twitterでは、おうちKubernetesや技術関連の内容を日々ツイートしているので、興味があればぜひフォローしていってください🎉

Twitter: https://twitter.com/_matoruru
(調査中)Tomcat同時接続の制御や Keep-Alive の設定

Tomcat には、同時接続の制御や Keep-Alive の設定を行うことができます。これらの設定は、通常 server.xml ファイルで定義されています。以下、具体的な設定方法を説明します。

## 同時接続制御
Tomcat の同時接続数は、server.xml 内の Connector 要素で設定できます。maxThreads パラメータを使用して、同時に処理できるリクエストの最大数を指定します。

```xml
<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443"
           maxThreads="200" />
```

maxThreads: ここで指定した数が、同時に処理できるスレッド（リクエスト）の最大数となります。たとえば、maxThreads="200" と設定することで、最大200の同時接続を処理できます。

## Keep-Alive の設定
Keep-Alive に関連する設定も、同じく Connector 要素内で指定できます。

```xml
<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           keepAliveTimeout="60000"
           maxKeepAliveRequests="100" />
```

keepAliveTimeout: クライアントが次のリクエストを送信するまでの最大待機時間（ミリ秒）を指定します。たとえば、keepAliveTimeout="60000" とすると、Tomcat は 60 秒間接続を維持します。

maxKeepAliveRequests: 1つの接続で処理するリクエストの最大数を指定します。たとえば、maxKeepAliveRequests="100" と設定すると、1つのKeep-Alive接続で最大100のリクエストを処理します。-1 に設定すると、無制限となります。

## その他のパフォーマンスに影響する設定
acceptCount: 同時接続数を超えた場合に待機できるリクエストのキューの最大数を設定します。


```xml
<Connector port="8080" protocol="HTTP/1.1"
           maxThreads="200"
           acceptCount="100" />
```

これにより、200のスレッドが稼働中であっても、さらに100のリクエストが待機できるようになります。
[SharePoint]SharePointリストの管理されたメタデータ型列を使いこなそう！

# 背景
最近、SharePointリストの管理されたメタデータ型列について、遊ぶ機会がありました。正直なところ、最初は「管理されたメタデータ型列」というものを全く知りませんでした。調査を進めるうちに、この機能が便利であることが分かったのでメモしておこうと思います。

# 管理されたメタデータ型列とは？
管理されたメタデータ型列は、**データを体系的に分類する**ための強力なツールです。これにより、情報の整理が容易になり、必要なデータを迅速に見つけることができます。特に、**大量のデータを扱う場合や、複数のユーザーが同じデータセットを利用する場合**に、その真価を発揮します。
イメージしにくいかと思うので、実際にユースケースを考えて、使用方法手順説明しようと思います。

# ユースケース
システム開発会社でサービスA、サービスBを開発しようとしております。
そこで、フェーズごとに成果物を格納しておりますが、ドキュメントが増えていくにつれて、ドキュメント構成が複雑になってきます。どこにドキュメントがあるか分からなくなってきました。
**管理されたメタデータ列でドキュメントを格納しているパスをタグ付けすること**によって、ドキュメントがどこにあるか分かりやすくなりました。

# 使用手順
1. [用語ストアで用語セットを作成する](https://learn.microsoft.com/ja-jp/sharepoint/create-and-manage-terms)
1. [SharePointリストを作成する](https://support.microsoft.com/ja-jp/office/%E3%83%AA%E3%82%B9%E3%83%88%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B-0d397414-d95f-41eb-addd-5e6eff41b083)
1. [管理されたメタデータ列を作成する](https://support.microsoft.com/ja-jp/office/%E7%AE%A1%E7%90%86%E3%83%A1%E3%82%BF%E3%83%87%E3%83%BC%E3%82%BF%E5%88%97%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B-8fad9e35-a618-4400-b3c7-46f02785d27f)

### イメージ
#### 用語セット
![用語セット作成_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/f93b2640-b3fe-ec8b-d08e-f0a62cc96eab.png)

#### 成果物ドキュメントフォルダー構成
![リンク_フォルダー構成_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/7b4b9eb0-f0f5-a74b-838a-0fb725a2a756.png)
![リンク_フォルダー構成_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/5faee79d-342b-11a6-b6fa-ede1236583ca.png)

#### SharePointリスト
※**Category列**でファイルを格納したフォルダー階層ごとにカテゴリー分けしております。
![SharePointリスト_1_マスク.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/20ba9b4a-10d1-4dd0-21e4-53c341eb56b1.png)

# まとめ
利用するメリットを整理してみました。
1. **効率的な検索**
管理されたメタデータ型列を使用することで、**特定の条件に基づいたデータの検索が非常に簡単になります**。例えば、プロジェクト名や担当者などのメタデータを付与することで、後から特定のプロジェクトに関連するドキュメントを簡単に検索できるようになります。
1. **一貫性のあるデータ分類**
用語セットを使用することで、データの分類が一貫性を持って行われます。これにより、**異なるユーザーが同じ分類基準を使用するため、データの整合性が保たれます**。
1. **柔軟なデータ管理**
管理されたメタデータ型列は、後から用語セットを更新することができるため、**データの分類基準を柔軟に変更することが可能です**。これにより、ビジネスの変化に対応したデータ管理が実現します。

管理されたメタデータ型列は、SharePointリストのデータ管理を飛躍的に改善するための重要な機能です。データの分類と検索が効率化されることで、業務の生産性が向上します。
実際に管理されたメタデータ型列を使用してみて、用語セットの持ち方、タグのデザインをもう少し工夫できるのではないかと思いました。
まだ使ったことがない方は、ぜひ一度試してみてください！

この記事が皆さんの役に立てば幸いです。何か質問があれば、コメント欄で教えていただけると幸いです！
学習記録アプリの自動デプロイの対応

## firebaseにデプロイ後画面が表示されない
ローカル環境では表示がされるのに、デプロイした環境ではなぜか表示がされなかった。
確認した結果下記設定が必要だった。

・ワークフローファイルに下記の記載漏れ
```
'on':
  push:
    branches:
      - main
        with:
          channelId: 本番環境の指定
          projectId: your-project-id
  build_and_preview:
    if: ${{ github.event_name == 'pull_request' || github.ref == 'refs/heads/main' }}
```
→上記記載をすることで初めて、本番環境へpushをした場合と指定したブランチが変更されるたびに自動的にデプロイが行われる。
※インデントの位置などでもエラーが発生するため書き方に注意が必要


・Uncaught Error: 関数名 is required.エラーの対処

1.環境変数の設定
ターミナルで下記例のようなコマンドを実施
```
firebase functions:config:set supabase.url="YOUR_SUPABASE_URL
firebase functions:config:set supabase.anon_key="YOUR_SUPBASE_KEY"
```

2.ワークフローファイルに下記を記載
```
- name: Setup env file
  run: |
    echo "VITE_SUPABASE_URL=${{ secrets.VITE_SUPABASE_URL }}" >> .env
    echo "VITE_SUPABASE_ANON_KEY=${{ secrets.VITE_SUPABASE_ANON_KEY }}" >> .env
```

3.Firebaseトークンの確認してトークンをコピーしておく
```
firebase login:ci
```

4.githubのリポジトリにアクセスして、ヘッダーのsettingsを選択
![スクリーンショット 2024-09-22 22.24.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880277/5832d6f5-7c3e-a0c2-66e2-9dc7395c06c8.png)

5.サイドバーのSecrets and variables > Actions を選択

![スクリーンショット 2024-09-22 22.29.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880277/cf429b83-ab5a-91a1-fbdd-23fc4d8b3bd3.png)

6.New repository secretを押下
![スクリーンショット 2024-09-22 22.30.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880277/efb5719f-7121-85f6-4b3e-b09cef6866f5.png)

7.Nameに環境変数名,Secret欄にキー名を記載してAdd secretを押下
![スクリーンショット 2024-09-22 22.31.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880277/8fc64899-8728-d1f6-92ec-38fd3b36143b.png)

例
Name：FIREBASE_SERVICE_ACCOUNT, Secret：トークン名
Name：VITE_SUPABASE_ANON_KEY, Secret：firebase Project API keysからコピーName：VITE_SUPABASE_URL, Secret：firebase Project URLからコピー


・Failed to construct 'URL': Invalid URL エラーの対処
こちらについては恐らくGitHub Secretsで設定したURLと.envの環境変数のURLが一致していなかったため発生したエラーだと思われます。
GitHub Secretsのsecretの値を再設定することで解決しました。

## 所感
エラーが複数回発生したり、ローカルとデプロイ時で大きく表示されるエラーや状態が異なり大変戸惑いました。エラーログを確認したり、デベロッパーツールから情報を取得するなどがより大事だと実感しました。
INTPが楽しくプログラミングを学習するには？

## この記事を書こうと思ったきっかけ

Laravelの勉強をせねばとパソコンを開いていたある日、ISFJ（つまり、目の前の作業に計画的に集中できるタイプ）の人の学習カリキュラムを着々とこなしていたのを見た。

自分が基礎的な知識からしっかり身につけたいと考えていたこともあり、「同じように体系化された学習本や学習サイトを使って勉強すれば知識が身につくのでは」と情報がまとまっている本やサイトを見て勉強を始めてみた。

しかし、どうもうまくいかない。
INTPは興味がないと集中できない。

とは言え自分でもうまく勉強する方法があると思ったので、同じように勉強がうまく進まない駆け出しエンジニアのために、この記事を書こうと思う。

>INTPはこんなタイプ
https://meet.acesinc.co.jp/blog/intp/

## どうやって勉強するか

まず、学習する対象に興味をもつ必要がある。

私は本が好きなので、これらの本を読んで知識欲を引っ張り出した。

![IMG_3230.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3808608/a87cbe12-42d8-4ca0-3f23-00e5de0a8c22.jpeg)
・歴史的観点から、現代のプログラミング言語や開発ツールがなぜこのようなつくりになっているのか解説してある
・コンピューターサイエンスやコーディングに関して、若干の知識がある方が読みやすいと思った



![IMG_3201.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3808608/d302a304-36e3-f4e7-882b-ed669f48f686.jpeg)
・使いにくいwebアプリやシステムがなぜ使いにくいのか、その理由と解決方法を具体例とともに教えてくれる
・実践的な内容も充実しているが、読み物としても面白い

## モチベを保つ

一度興味をもったら、その興味を継続させる努力が必要だ。

私は興味を維持させるために、このようなことを意識した

・結果がすぐ見える方法で試す➡︎でないと飽きがち
・計画的に物事を進めるのが得意な人と自分の進捗を比べないよう心掛ける➡︎自分がえらく遠回りしているように感じでモチベダウン
・インプットは実践的なノウハウにこだわらない➡︎哲学的、抽象的なトピックでも、時間を割いて調べていいことにする

一旦、以上がINTPが楽しく勉強を進めるためのすすめだ。

続きはまた今度🙋‍♀️
Spring FrameWorkのJava Config

DIコンテナに、Java Configクラスを使用してコンポーネントを登録する方法を書いてみました！
## Java Configクラス
DIコンテナに対してコンポーネントを登録するための、設定クラス。ここで設定したコンポーネントが、DIコンテナに登録される。


```java
@Configuration
public class AppConfig {

  @Bean
  UserRepository userRepository() {
    return new UserRepositoryImpl();
  }
}
```
## ルックアップ
ルックアップとはDIコンテナからBeanを取得すること。

**取得方法**
１つ目はBeanの型(UserRepository)を指定する方法。指定した型を持つBeanが１つだけ存在する場合に使用する。今回は、Java Configクラスで設定したUserRepository型は1つだけなので、これで取得できる。

```java
UserRepository userRepository = context.getBean(UserRepository.class);
```
2つ目はBeanの型と名前を指定する方法。指定した型が複数ある場合に使用する。
下記のようにUserRepository型が複数あった場合、型を指定するだけではどちらか判断できない。
```java
@Configuration
public class AppConfig {

  @Bean
  UserRepository userRepository() {
    return new UserRepositoryImpl();
  }

  @Bean
  UserRepository userRepositorySecond() {
    return new UserRepositorySecondImpl();
  }
}
```
なので名前と型を指定する。
```java
UserRepository userRepository = context.getBean("userRepositorySecond",UserRepository.class);
```
もう一つObject型で取得してキャストする方法があるみたいですが、省略します。

### 終わり
DIコンテナにコンポーネントを登録して取得する方法でした！
間違いなどがあれば、遠慮なくご指摘ください:grin:
DockerコンテナにVSCodeを接続して開発する手順

前回の続き

DockerコンテナにPython3をインストールしたけど
Vimで開発とかしたくない🥺

DockerコンテナにVSCodeを接続して
開発したいね☺️

↓参考にしたエントリー

https://qiita.com/75ks/items/b2961e8562c353f42d21

### VSCodeからコンテナに接続

VSCodeの左サイドバーの拡張機能で
「Dev Containers」で検索し、インストールする

![スクリーンショット 2024-09-22 21.25.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2790258/f59847db-629b-6e49-8da7-c9364208a31d.png)

左下の緑の「><」アイコンをクリックして
上のバーの「コンテナを再度開く」を選択

![スクリーンショット 2024-09-22 21.30.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2790258/8f9e0b20-4a35-74bb-68f2-981d81a5811a.png)

「実行中のコンテナにアタッチ」を選択

![スクリーンショット 2024-09-22 21.38.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2790258/f13234bd-5cc0-3937-e33d-1f636c9f508d.png)

接続が成功すると小さなウインドウが出てきてファイルの編集ができます👍

![スクリーンショット 2024-09-22 22.10.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2790258/513a6ffe-43f4-9265-6e7d-319cae5ceb79.png)

以上です🤗
【Dify入門】生成AI活用レベル診断ボットを自作してみよう！(Gemini 1.5 Flash使ったので無料!!)

# DifyでAI診断ボットを作成する方法 - 生成AI活用レベル診断ボットの実装例

## はじめに

この記事では、Difyを使用して「生成AI活用レベル診断ボット」を作成する過程を紹介します。AIの活用レベルを診断するこのボットは、ユーザーの回答を分析し、適切なフィードバックを提供します。

## 環境設定

- プラットフォーム: Dify
- 使用モデル: Gemini 1.5 Flash

## 手順

### 1. アプリケーションの作成

1. Difyダッシュボードで「Create Application」または「新規アプリケーション」を選択
2. アプリケーションタイプ: チャットボット
3. アプリ名: 生成AI活用レベル診断bot
4. 説明: あなたの生成AI活用レベルをいくつかの質問とあなたの答えを通じて私が診断します。

### 2. プロンプトの設定

システムプロンプトに以下を入力：

```markdown
システム: あなたは生成AI活用レベル診断の専門家です。ユーザーから提供された以下の回答を分析し、以下の基準に基づいて正確にレベルを判定してください。

## レベル判定基準

[レベル1からレベル5までの詳細な判定基準を記述]

## 評価の注意点

[評価時の注意点を列挙]

## ユーザーの回答

質問1: {{question1_answer}}
質問2: {{question2_answer}}
質問3: {{question3_answer}}
質問4: {{question4_answer}}
質問5: {{question5_answer}}

## 診断結果の出力

[診断結果の出力フォーマットを指定]
```

### 3. 変数の設定

- `question1_answer` から `question5_answer` までの5つの変数を設定
- タイプ: テキスト
- 必須: オフ

### 4. 会話の開始設定

「チャットの強化」セクションで以下を設定：

```markdown
こんにちは！生成AI活用レベル診断ボットです。あなたの生成AI活用レベルを診断を行います。以下の5つの質問にお応えください。

Q1. 生成AIとは何か、簡単に説明してください。
Q2. 生成AIを実際に使ったことはありますか？どのような場面で使いましたか？
Q3. 生成AIの倫理的な問題があることを知っていますか？問題点は、どのようなことが考えられますか？
Q4. 生成AIは今後どのように発展していくと思いますか？
Q5. 生成AIについて、他に何か知りたいことはありますか？

[回答例を提示]
```

### 5. モデレーション設定

- コンテンツのモデレーション: オン
- 不適切な単語やフレーズのリストを設定

### 6. テストと調整

- デバッグとプレビュー機能を使用してボットの動作をテスト
- 必要に応じてプロンプトや設定を調整

## 結果

完成したボットのURL: https://udify.app/chat/jayjUPj7foFwS8xK

## まとめ

Difyを使用することで、複雑な診断ロジックを持つAIボットを比較的簡単に作成できました。プロンプトエンジニアリングと適切な変数設定が鍵となります。

## 注意点

- プロンプトの設計に時間をかけ、期待する出力を得られるよう調整が必要
- ユーザー体験を考慮し、質問の提示方法や回答形式を最適化することが重要
- 倫理的配慮を組み込むなど、AIの責任ある利用を心がける

この記事が、Difyを使用したAIボット開発の参考になれば幸いです。
DockerのUbuntuコンテナにPython3をインストール

前回からの続き
ubuntuのdockerコンテナを準備したのはいいけど
Pythonって入ってんの？

```
# python3
bash: python3: command not found
```

うん入ってないね

インストールしましょう

その前にapt-getをupdateしましょう

```
# apt-get update
```

終わったらPythonをインストールしましょう

```
# apt-get install -y python3 python3-pip
```

インストールされてるか確認

```
# python3
Python 3.12.3 (main, Sep 11 2024, 14:17:37) [GCC 13.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
```

よし、終わり😊
009 AI屋さんの　gradioと200万トークン全文入力　追加学習済み　LLMの　gradioでWebアプリをクラウドデプロイ


AI屋さんの　追加学習済み　LLMの　gradioでWebアプリをクラウドデプロイ


streamlitができるのだから
gradioでも　お手軽に、
サーバーレスでWebアプリをデプロイしてみましょう。
自分で作れれば、ただ同然です。

追加学習済みのＬＬＭを安価に共有する方法です。
完成ずみのwebapiを使って、
既にある、皆様のポータルサイトで呼び出したり
別途、独立サイトで運用したり　色々できます。


完成イメージ

![スクリーンショット 2024-09-22 21.43.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/c0047eee-e58e-8ef2-347a-baa6e71a378d.png)




作成したアプリが無事に動けば　OSまるごと
dockerのイメージで固めて　デプロイするので
結構何でも気軽に　クラウドのサーバーレスで運用できます。

しかも、LLMのプロンプトに　案件毎、資料毎に固定で
２００万トークン目一杯　追加学習の資料を　全文入れて固定するので
絶対当たる、確定一発、追加学習モデルです。

用途別の　専門分野特化LLMを　使う数だけ用意して
webアプリ、webAPIで　客先個人別に提供可能です。
利用者は、
　パソコンでも
　スマホでも
　タブレットでも
好きなデバイス経由で、
　取り説、
　技術書、
　法律、
　規格書、
　教科書、
　英語教材、
　お料理レシピ
ありとあらゆる、世界中の教材・資料が
　日本語
　英語
　中国語
　ドイツ語
　フランス語
言葉の障壁なく、大規模言語モデルと壁打ちできます。





目次

第九回：AI屋さんの　gradioでWebアプリをクラウドデプロイ

本書



第八回：AI屋さんの　streamlitでWebアプリをクラウドデプロイ　実践編

https://qiita.com/bono0/items/5c691f7cfe20c155a774


第七回：AI屋さんの　Webアプリをクラウドデプロイ　実践編

https://qiita.com/bono0/items/8b9563830a94cd7b68b0


第六回：追加学習済み　LLMの　flaskでWebアプリをクラウドデプロイ


https://qiita.com/bono0/items/968264adea0183d7a4fa


第五回：追加学習済み　LLMの　streamlitでWebアプリをクラウドデプロイ

https://qiita.com/bono0/items/2f7fbdbd1ad843e7858e




第四回：追加学習済み　LLMのwebapiをクラウドデプロイ

https://qiita.com/bono0/items/f954ca48d19cc51fb344



第三回：追加学習済み　LLMのwebapiを作る

https://qiita.com/bono0/items/f3330d8a57024e7cd44b


第二回：大規模言語モデルの簡単な追加学習、実践編

https://qiita.com/bono0/items/bd0a01e50d5804bdacf3



第一回：大規模言語モデルの簡単な追加学習

https://qiita.com/bono0/items/4a992dc388527d3b99f4


次回は、実践編ですかね


ー続くー
Error: Directory 'dist' for Hosting does not exist.エラーについて

## エラーの概要
・ChatAIの回答
このエラー「Error: The process '/usr/local/bin/npx' failed with exit code 1」は、npxコマンドの実行が失敗したことを示しています。


ビルドステップの確認:
GitHub Actionsのワークフローファイルに以下のようなステップがあることを確認してください：

text
```
- run: npm ci && npm run build
```

→私の場合は「npm run build」を実行していないのが、原因だったようです。


firebase.jsonの修正:
firebase.jsonファイルを以下のように修正してみてください：

```json
{
  "hosting": {
    "public": "dist",
    ...
  }
}
```

## 所感
firebaseを使ったdeployが初めてのため、上記エラー以外にも発生して大変だった。
他のエラーや起こった事象に対する記事についても追加予定です。
[Python] FirebaseのMemory設定 (Cloud Functions)

## 本記事の内容

Firebase Cloud FunctionsをPythonで実装する際に設定するデコレータの**Memory**の解説を行います。
Firebaseが公開している公式ドキュメントと、実際のソースコードを見ながら解説をしていきます。


## 背景
ファイルの生成やなどを行う関数をデプロイしようとしました。
ところがデフォルトのメモリの設定ではオーバーフローしてしまい、メモリの量を増やす必要がありました。


## 目次

- [1. デコレータとは](#1-デコレータとは)
- [2. Memoryの設定](#2-memoryの設定)
- [3. 実装](#3-実装)
- [4. まとめ](#4-まとめ)

## 1. デコレータとは
デコレータとは**関数やクラスの前後に特定の処理を追加出来る機能**です。
Pythonでは、関数やクラスの定義する前に`@`をつけることで設定出来ます。

```Python sample.py
@https_fn.on_request()
def fetch_data(req: https_fn.Request) -> https_fn.Response:
    #省略
```

上記の関数`fetch_data()`のデコレータは`@https_fn.on_request()`になります。

## 2. Memoryの設定
関数が使用するメモリの量を指定出来ます
Firebaseのソースコード内のMemoryOptionクラスにメモリの値が定義されています。

```firebase_functions.options.py
class MemoryOption(int, _enum.Enum):
    """
    Available memory options supported by Cloud Functions.
    """

    MB_128 = 128
    MB_256 = 256
    MB_512 = 512
    GB_1 = 1 << 10
    GB_2 = 2 << 10
    GB_4 = 4 << 10
    GB_8 = 8 << 10
    GB_16 = 16 << 10
    GB_32 = 32 << 10
```

ビット演算子が用いられていますが、指定出来る値は、
`128`, `256`, `512`, `1024`, `2048`, `4096`, `8192`, `16384`, `32768`のいずれのようです。(全て単位はMBです)

なお、デフォルトの値は`256`です。


### メモリの料金

Firebaseのメモリは以下の料金形態になっています。


![スクリーンショット 2024-09-22 21.19.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3767231/35532085-4bf2-1ab6-2076-4f2504271459.png)


公式ドキュメントによると、メモリの値が増えると料金も比例して増えるようです。
そのため、定義する関数の処理の内容に応じて設定する必要があります。


## 3. 実装

Memoryの値を`256MB`から`512MB`に変更してみます。


```Python sample.py
@https_fn.on_request(memory=512)
def fetch_data(req: https_fn.Request) -> https_fn.Response:
    #省略
```

これでメモリを`512MB`に設定することが出来ます。


## 4. まとめ

今回はFirebase Cloud FunctionsをPythonでデプロイする際に必要なデコレータの設定の中の1つである、**Memory**についての解説を行いました。是非参考にして下さい!