OmniAICreator/Qiita-1.07M huggingface dataset:
【Reactアプリ100本ノック】14 Graph

![react-100-graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/a9a02062-8605-4df2-45f1-e2cd3c3b1a7a.png)
# はじめに

こんにちは、Watanabe Jin (@Sicut_study)です！

https://qiita.com/Sicut_study/items/78910cd8d103b8d45a73

こちらの記事が嬉しいことに多くの方に見ていただきました。
そこで**React**が多くの初心者の方に注目されているんだなということを実感させられました。

私の記事では何度も言っている通り

<font color="red"><h4>最速で学ぶならとにかく何か作る</h4></font>

というのが大事になってきます。そこで **「Reactアプリ100本ノック」** というのに挑戦していこうかと思います。徐々に難易度を挙げていってどこまでお題を作りきれるかの腕試しでやっていただければと思います。

今回は便利なグラフライブラリを使っていきます。
ライブラリを知ることで作れるものの選択肢が広がります

# 前回のお題

# Reactアプリ100本ノックルール

- 主要なライブラリやフレームワークはReactである必要がありますが、その他のツールやライブラリ（例: Redux, Next.js, Styled Componentsなど）を組み合わせて使用することは自由
- TypeScriptを利用する
- 要件をみたせばデザインなどは自由

# 14. Graph

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/13df7a29-2768-7559-a793-5a9907ad7e71.png)

## 問題

グラフの表示を行います

## 目的

グラフの表示ができるようになることで、可視化ができるようになりアイデアの幅が広がります。また新たなライブラリを試す機会を作ります

今回は架空のブログのPV数を記録する分析ツールを作ります

## 達成条件

- 日付とPV数を記録できる
- 日付とPV数はバリデーションをつける
- 記録するとグラフに反映される
- グラフはライブラリを何かしら用いて実現すること

## 実際に解いてみた

![Peek 2024-01-27 16-52.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/1603788d-04f7-620b-be4d-d832564d8a56.gif)

### 利用技術

- Vite
- React
- TypeScript
- TailwindCSS
- Tremor
- react-hook-form

解答時間 : 1時間

今回のテーマはずばり新しいライブラリでアイデアの幅が広がること
ライブラリを使うことを目的にサービスを作ることで学ぶ機会になります

今回は「Tremor」を利用してグラフ描画をしました

https://www.tremor.so/docs/visualizations/line-chart

ものすごく簡単にグラフが作れてアニメーションまでつけてくれるので、大好きなライブラリです

実装自体は簡単なので、バリデーションに**react-hook-form**を使うなど難易度をすこし上げるのもおすすめです
|　　　　　　　　  　　　　　　　　   　　　　　　　　　　　　　　　　　　　　　　　　　|
|:-:|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/f2ecacd6-1cab-dd08-e8b6-d5f036310bf2.png)


# 次のお題

Comig Soon...

# おわりに

React100本ノックの記事を地道に上げていこうと思いますので、一緒に挑戦したい方は @Sicut_study をフォローいただけるととてもうれしく思います。

ここまで読んでいただけた方は**いいね**と**ストック**よろしくお願いします。
@Sicut_study を**フォロー**いただけるととてもうれしく思います。

今週もプログラミング頑張りましょう！

![jisou-banner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/217ea52d-8130-3266-0619-990fa968408a.png)

# おすすめ記事

# About Me

Webエンジニア転身して1年間本気で勉強
転職ドラフトで高額オファーを複数獲得
そこでの経験からアウトプットやマインドセットの発信に強みがある
エンジニアをやりながら、起業に挑戦中
アイデア作りやパブリックスピーキングを得意としてる

■ Twitter
https://twitter.com/Sicut_study
■ Youtube
https://www.youtube.com/channel/UCBFrGAJhPuuaoLwUIHBILsA

■ プログラミングコーチングJISOU
https://projisou.jp
■ 登壇依頼などご依頼はこちらから
himaria.jin.watanabe@gmail.com

# 参考

https://www.tremor.so/

https://www.react-hook-form.com/
OpenAI APIを使って簡易的な音声対話処理を作ってみた

# はじめに
こんにちは、Webエンジニアの岩田史門([@SI_Monxy](https://x.com/SI_Monxy))です！
今回はOpenAI APIを使った簡易的な音声対話アプリの構築について記事を書いてみました！
改善点や修正点があれば、コメントにて優しくご指導いただけると嬉しいです！

# 概要
音声によるインタラクションは、仮想アシスタントから顧客サービスボットまで、さまざまなアプリケーションで人気を集めています。OpenAIのような高度なAIモデルを活用することで、これらのシステムの自然さと反応性を大幅に向上させることができます。

# セットアップ
始めるために必要なもの

- OpenAI APIへのアクセス権限。特に対話を処理することができるGPTモデルが必要です。
- Python環境と必要なライブラリ（API呼び出しのためのrequests、音声入力のためのpyaudio）。

# 実装手順
## OpenAI APIのセットアップ
- OpenAIからAPIキーを取得します。
- Pythonパッケージ(openai)をインストールして簡単に統合します。

## 音声入力の処理
- pyaudioを使用してユーザーからの音声入力をキャプチャします。
- 音声をテキストに変換するために音声認識ライブラリ（例：SpeechRecognition）を使用します。

## 対話の処理
- ユーザーのクエリをopenai.ChatCompletion.create()メソッドを使ってOpenAI APIに送信します。
- 応答を処理し、対話の文脈を管理して会話の流れを維持します。

## 音声出力
- AIが生成したテキスト応答を音声に変換するためにテキスト読み上げライブラリ（例：pyttsx3やgTTS）を使用します。

# デモンストレーション
Pythonでの簡略化された実装を見てみます
``` python
import openai
import speech_recognition as sr
import pyttsx3

# OpenAI APIのセットアップ
openai.api_key = 'あなたのOpenAIのAPIキー'

# 音声入力を処理する関数
def listen():
    r = sr.Recognizer()
    with sr.Microphone() as source:
        print("リスニング中...")
        audio = r.listen(source)
    try:
        query = r.recognize_google(audio, language='ja-JP')
        return query
    except Exception as e:
        print(e)
        return ""

# OpenAI APIを使って対話を処理する関数
def converse(prompt):
    response = openai.ChatCompletion.create(
        model="text-davinci-002",
        messages=[
            {"role": "user", "content": prompt}
        ]
    )
    return response['choices'][0]['message']['content']

# AIの応答を音声で出力する関数
def speak(text):
    engine = pyttsx3.init()
    engine.say(text)
    engine.runAndWait()

# メインプログラムのループ
if __name__ == "__main__":
    while True:
        query = listen()
        if query:
            if query == "終了":  # ユーザーが "終了" と発話したらプログラムを終了する
                print("対話を終了します。")
                break
            response = converse(query)
            print("AI:", response)
            speak(response)
```

# まとめ
この記事では、OpenAI APIを使用して音声対話システムを構築する方法を探りました。

# 参考
- [OpenAIドキュメント](https://platform.openai.com/docs/overview)
PythonでSQLの面倒な環境構築なしにDB操作を行う

## PythonでDBを操作する
pythonでDB操作する方法を紹介するよ。
SQL操作したいけど、環境構築が良く分からない、、、といった人に便利なモジュールを見つけたので紹介するよ。
`sqlite3`モジュールを利用すれば、一切の設定なしにテーブルを利用できるよ。

```python
1. import sqlite3
2. 
3. connect = sqlite3.connect('sample_database.db')
4. connect.execute("CREATE TABLE sample (id integer, val String)")
```
上記のコードでは、sqlite3をインポートした後に、3行目でsample_database.dbに接続しているよ（sample_database.dbはファイルを別途作成しなくても勝手にできるので実行するだけでいいよ）。
4行目でデータベースに`sample`という名前のテーブルを作成しているよ。

## SQLを使ってみる
ここからはSQLを使ってデータの投入・抽出をするよ。
今回は、生徒と部活動などを管理するテーブルを作成して、データ操作をしてみるよ。作るテーブルは以下の感じ。
こっちは`student`テーブルで、


| id | name | class_id | club_id |
|:-:|:-:|:-:|:-:|
| 1 | student_001 | 1 | 1 |
| 2 | student_002 | 1 | 1 |
| 2 | student_003 | 1 | 2 |
| 2 | student_004 | 2 | 1 |

こっちは`club`テーブルだよ。

| id | name |
|:-:|:-:|
| 1 | baseball |
| 2 | tennis |


それでは先ほどのコードに続きデータを投入していくよ。
```python
# テーブル作成
connect.execute("CREATE TABLE student (id integer, name String, class_id integer, club_id integer)")
connect.execute("CREATE TABLE club (id integer, name String)")

# データ投入
connect.execute("INSERT INTO student VALUES (1, 'student_001', 1, 1), (2, 'student_002', 1, 1), (3, 'student_003', 1, 2), (4, 'student_004', 2, 1)")
connect.execute("INSERT INTO club VALUES (1, baseball), (2, tennis)")
```

ここからは関数を作ってみて、目的の値を呼びだすようにするよ。

```python
def print_club_member(class_id, club_name):
    result = connect.execute("SELECT * FROM students JOIN club ON students.club_id = club.id WHERE students.class_id = %s AND club.name = %s" %(class_id, club_name))
    for item in result:
        print(item)


def get_club_member_handla():
    print('指定されたクラスの部活動のメンバーを表示します。')
    print('クラスを入力してください。')
    class_input = input()
    print('クラブ名を入力してください。')
    club_input = input()
    club_input_name = ("'" + club_input + "'")

    print_club_member(class_input, club_input_name)


get_club_member_handla()
```
このコードを実行すると、投入したデータのうち、条件に一致するレコードが出力されるよ。

## まとめ
以上のような感じで、MySQLなどの環境を構築しなくてもPythonでDB操作することができる便利なモジュールの紹介をしたよ。
RAGを用いた質疑応答システムの構築

# はじめに
こんにちは、Webエンジニアの岩田史門([@SI_Monxy](https://x.com/SI_Monxy))です！
今回はRAGを用いた質疑応答システムの構築について記事を書いてみました！
改善点や修正点があれば、コメントにて優しくご指導いただけると嬉しいです！

# 概要
本記事では、RAG（Retrieval-Augmented Generation）を活用して、堅牢な質問応答システムを構築する方法を探ります。RAGは、情報検索型と生成型のAIモデルを組み合わせることで、ユーザーのクエリに対して正確で文脈に即した回答を提供します。

# システム構築の手順
## 環境と依存関係のセットアップ
Pythonがインストールされていることを確認し、仮想環境を作成します。必要なライブラリをインストールします

``` bash
pip install torch transformers datasets
```

## データと事前学習モデルの準備
ドメインに適したデータセットを取得または準備し、事前学習モデルをダウンロードします

``` python
from transformers import RagTokenizer, RagRetriever, RagSequenceForGeneration

tokenizer = RagTokenizer.from_pretrained("facebook/rag-token-base")
retriever = RagRetriever.from_pretrained("facebook/rag-token-base")
generator = RagSequenceForGeneration.from_pretrained("facebook/rag-token-base")
```

## 質問応答機能の実装
質問を入力として受け取り、RAGを使用して回答を取得・生成する関数を定義します

``` python
def answer_question(question):
    input_dict = tokenizer(question, return_tensors="pt")
    retriever_output = retriever(input_dict["input_ids"].to("cuda"))
    generator_output = generator.generate(
        **retriever_output,
        max_length=100,
        num_return_sequences=1,
        use_cache=True,
        decoder_start_token_id=generator.config.bos_token_id,
        temperature=1.0,
    )
    answer = tokenizer.batch_decode(generator_output, skip_special_tokens=True)[0]
    return answer
```

## 質問応答システムのテスト
様々な質問をして、システムの応答を確認します

``` python
question = "フランスの首都はどこですか？"
print(answer_question(question))

question = "小説『1984年』の著者は誰ですか？"
print(answer_question(question))
```

# まとめ
RAGを使用して質問応答システムを構築する基本的な手順を説明しました。情報検索型と生成型のモデルを統合することで、さまざまなドメインで正確な応答を提供するシステムを作成できます。

# 参考
- [Hugging Face Transformers ドキュメント](https://huggingface.co/docs/transformers/index)
- [Facebook AI Research - RAG ペーパー](https://arxiv.org/abs/2005.11401)
[Slidev] VSCode で Markdown が崩れる問題の解決方法

## この記事が役立つかもしれない人
* VSCode で Slidev を使用している人
* Slidev を使っていてスライドの表示が変になって困っている人

## 状態
:::note warn
`slides.md` を保存した際などにページが崩れてしまいます。

1 枚目はまだ分かりにいですが、2 枚目は完全に崩れています。

![スライド 1 枚目](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2038389/72efd73d-6db8-6e67-72df-d5c76329b35d.png)

![スライド 2 枚目](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2038389/7adea724-1269-70f0-f575-6ec0dacf4545.png)
:::

:::note info
<details>
<summary>正常な表示</summary>

![normal-slidev_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2038389/9eb16cc6-a346-4057-df57-8059a6320bf2.png)

![normal-slidev_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2038389/c561b495-495d-d4f7-eefb-6fef41a71bd2.png)
</details>
:::

## 原因
この問題はフォーマッター (例：Prettier など) が自動的に余計な改行や見出しの変更を行ってしまうために発生します。

フォーマッターは通常のコーディングでは非常に便利なものです。しかし今回は特殊な形式で記述される Markdown であるため、変更によって思い通りにスライドを作成することが困難になります。

なので今回は Slidev で快適にスライドを作成するために作業している Slidev プロジェクトでのみフォーマッターが効かないように設定を行います。


## 解決方法
この問題を解決するために `settings.json` を作成して、VSCode 上でフォーマッターを無効化します。

### 1. `.vscode/settings.json` を作成

```diff_te_x:Slidev の一般的なディレクトリ構成の場合
  .
+ ├── 📁 .vscode
+ │   └── 📄 settings.json
  ├── 📁 components
  │   └── 📄 Counter.vue
  ├── 📁 pages
  │   └── 📄 multiple-entries.md
  ├── 📁 snippets
  │   └── 📄 external.ts
  ├── 📄 .gitignore
  ├── 📄 .npmrc
  ├── 📄 README.md
  ├── 📄 netlify.toml
  ├── 📄 package.json
  ├── 📄 slides.md
  ├── 📄 vercel.json
  └── 📄 yarn.lock
```

### 2. フォーマッターを無効化する

settings.json に以下の内容を追加します。

```json:settings.json
{
  "editor.formatOnPaste": false,
  "editor.formatOnSave": false,
  "editor.formatOnType": false
}
```

これにより Markdown ファイルの保存や編集時にフォーマッターが自動で動作しなくなり、意図した通りにスライドを作成することができるようになります。

### 設定の詳細について
| 項目                   | 詳細 |
|:-----------------------|:--|
| `editor.formatOnType`  | 入力後の行をフォーマットする |
| `editor.formatOnSave`  | ファイルの保存時に書式を設定する |
| `editor.formatOnPaste` | ペーストされた内容を整形する |

#### 参考資料

https://code.visualstudio.com/docs/editor/codebasics#_formatting

---

この記事が役に立ったら ❤️ を頂けると嬉しいです！
RAG（Retrieval-Augmented Generation）の概要を学んだのでOpenAI APIを使ってサンプル実装してみた

# はじめに
こんにちは、Webエンジニアの岩田史門([@SI_Monxy](https://x.com/SI_Monxy))です！
今回はOpenAI APIを利用したRAGについて記事を書いてみました！
改善点や修正点があれば、コメントにて優しくご指導いただけると嬉しいです！

# 概要
RAGは、生成モデルに情報検索の能力を統合することで生成品質を向上させる手法です。通常の生成モデルに比べて、より正確で情報に基づいた生成が可能となります。

# 利点
- 情報の正確性向上: 情報検索を通じて生成されるテキストの正確性が向上します。
- 多様性と質の向上: 複数の検索結果を利用することで、生成されるテキストの多様性と質が向上します。
- リアルタイム応用: リアルタイムでの応用が可能であり、特定のコンテキストに応じた生成が実現できます。

# 実装手順
- データの収集: 使用する情報源からデータを収集し、適切に整形します。
- 検索エンジンの設定: Elasticsearchなどの検索エンジンを設定し、情報検索を実行できるようにします。
- 生成モデルの統合: OpenAI APIを使用して生成モデルを統合し、情報検索を行うフローを構築します。
- リクエストの処理: ユーザーからのリクエストを受け取り、適切な検索クエリを生成し、検索結果を取得します。
- 生成の実行: 取得した情報を生成モデルに入力し、最終的な生成結果を生成します。

# サンプルコード
このサンプルコードでは、OpenAI APIを使用してRAGを実装しています。generate_with_rag関数は、与えられたプロンプトに基づいて検索ドキュメントを利用し、生成されたテキストを返します。
``` python
import openai

# OpenAI APIキーの設定
openai.api_key = 'YOUR_OPENAI_API_KEY'

def generate_with_rag(prompt, documents):
    # RAGのリクエストを準備
    request = {
        "model": "text-davinci-002",
        "documents": documents,
        "query": prompt,
        "max_tokens": 150,
        "stop": ["\n", "
"]
    }

    # OpenAI APIを使って生成を実行
    response = openai.Completion.create(**request)

    # 生成されたテキストを返す
    return response.choices[0].text.strip()

# 使用例
prompt = "What are the benefits of using RAG?"
documents = [
    "RAG improves text generation by integrating retrieval-based information.",
    "It enhances accuracy and diversity in generated text.",
    "Real-time applications benefit significantly from RAG's capabilities."
]

generated_text = generate_with_rag(prompt, documents)
print(generated_text)
```

# 参考
- [OpenAI API Documentation](https://platform.openai.com/docs/overview)
- [Retrieval-Augmented Generation: Models and Applications](https://arxiv.org/abs/2005.11401)
【Java/Spring Boot 】画面からコントローラに値を渡す方法


Java の Spring Boot を使用して、画面からコントローラ（Controller）に値を渡す方法はいくつかあります。以下に、主な方法を整理しました。

## 1. リクエストパラメータを使用する（@RequestParam）

クエリパラメータとして値を渡し、コントローラで`@RequestParam`アノテーションを使って取得する方法です。

例:
URL: `/users?name=John`

```java:UserController
@Controller
public class UserController {

    @GetMapping(value = "/users")
    public String getUsersByName(@RequestParam("name") String name) {
    	System.out.print("name:"+name);// Expected output: name:John
        return "index";
    }
}

```

## 2. URL パス変数を使用する（@PathVariable）

URL の一部として値を渡し、コントローラで`@PathVariable`アノテーションを使って取得する方法です。

例:
URL: `/users/100`

```java:UserController
@Controller
public class UserController {

	@GetMapping(value = "/users/{userId}")
    public String getUserById(@PathVariable("userId") int userId) {
    	System.out.print("userId:"+userId);// Expected output: userId:100
        return "index";
        }
    }
```

## 3. フォームデータをオブジェクトで受け取る（@ModelAttribute）

フォームデータをオブジェクトにマッピングして受け取る方法です。

例:
URL: /users
HTML フォーム:textbox：John

```html:index.html
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>index</title>
  </head>
  <body>
	  <form action="/users/post" method="post">
		  <input type="text" name="name" />
		  <button type="submit">Submit</button>
	  </form> 
	</body>
</html>
```

```html:sample.html
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>page</title>
  </head>
  <body>

<h1>Hello World sample!!</h1>    

    </body>
</html>
```

```java:UserController
@Controller
public class UserController {
	
	@GetMapping(value = "/users")
	public String showIndex() {
		return "index";
	}
	
	@PostMapping(value = "/users/post")
    public String getUserByUser(@ModelAttribute User user) {
    	System.out.print("name:"+user.getName());// Expected output: name:John
        return "sample";
    }
}

```

### まとめ

- **URL パス変数（@ PathVariable）**: URL の一部として値を渡す場合に使用
- **リクエストパラメータ（@ RequestParam）**: クエリパラメータとして値を渡す場合に使用
- **フォームデータ（@ ModelAttribute）**: フォームデータをオブジェクトにマッピングして受け取る場合に使用
自然言語処理(NLP)入門：基本的なテクニックと用語を学んだのでまとめてみた

# はじめに
こんにちは、Webエンジニアの岩田史門([@SI_Monxy](https://x.com/SI_Monxy))です！
今回は生成AIきっかけで自然言語処理に興味を持ち学んでみたので、記事を書いてみました！
改善点や修正点があれば、コメントにて優しくご指導いただけると嬉しいです！

# 概要
自然言語処理（Natural Language Processing, NLP）は、コンピュータが人間の言語を理解し、処理する技術です。この記事では、NLPの基本的な技術と一般的な用語について解説します。

# NLPの基本的な技術
## トークン化（Tokenization）
自然言語のテキストを小さな単位に分割する処理です。例えば、文や単語に分割することがあります。

``` python
import nltk
from nltk.tokenize import word_tokenize

text = "Natural language processing is a subfield of artificial intelligence."
tokens = word_tokenize(text)
print(tokens)
```

## 品詞タグ付け（Part-of-Speech Tagging）
単語に品詞（名詞、動詞など）を付与する処理です。

``` python 
from nltk import pos_tag

tags = pos_tag(tokens)
print(tags)
```

# NLPの一般的な用語
## 形態素解析（Morphological Analysis）
単語を語幹や接尾辞に分割し、それぞれの形態素に分ける処理です。

## 意味解析（Semantic Analysis）
文の意味を理解するための処理で、単語の意味や文脈を解析します。

# 参考
- [NLTK Documentation](https://www.nltk.org/)
- [spaCy Documentation](https://spacy.io/)
Salad UIのHello worldをやってみた

# はじめに

Phoenixのプロジェクトを作成してから、Salad UIを使えるようにするまでの手順のメモです

SaladUI Github

https://github.com/bluzky/salad_ui


# Phoenixのプロジェクト作成まで

```
mix phx.new hello_salad --no-ecto
cd hello_salad
mix phx.server
git init .
```

# SaladUIのインストール

https://github.com/bluzky/salad_ui
Instsllのセクションに記載されてる通りの変更をする

mix deps.get
mix phx.server

# Salad UIのコンポーネントを使ってみる

CoreComponentsを無効にして、SaladUI.Buttonをimportする

```diff:/lib/hello_salad_web.ex
       # HTML escaping functionality
       import Phoenix.HTML
       # Core UI components and translation
-      import HelloSaladWeb.CoreComponents
+      # import HelloSaladWeb.CoreComponents
+      import SaladUI.Button
+
       import HelloSaladWeb.Gettext
 
       # Shortcut for generating JS commands
```

flash_group flashもCoreComponentsの関数なので削除
```diff:/lib/hello_salad_web/components/layouts/app.html.heex
 </header>
 <main class="px-4 py-20 sm:px-6 lg:px-8">
   <div class="mx-auto max-w-2xl">
-    <.flash_group flash={@flash} />
     <%= @inner_content %>
   </div>
 </main>
```

home.html.heexをSaladUIのボタンにする
 
```heex:/lib/hello_salad_web/controllers/page_html/home.html.heex
<.button>
  Default
</.button>
<.button variant="secondary">
  Secondary
</.button>
<.button variant="destructive">
  Destructive
</.button>
<.button variant="outline">
  Outline
</.button>
<.button variant="ghost">
  Ghost
</.button>
<.button variant="link">
  Link
</.button>
```
Qiitaに38記事を毎日投稿したことで得たもの【Qiita投稿マラソン完走】

## はじめに

Qiita投稿マラソンに参加しています。
この記事が38記事目で、本日完走となります。

この記事では、38日間を通して得られたことを共有します。

## 結論

◆スキル
アウトプットスキルが格段に上がりました。
また、アウトプットする前提でインプットするので、インプットの効率も格段に上がりました。

◆興味
38日間、できるだけ自分の興味関心のあるものを投稿するようにしました。
その結果、**自分の興味が記事として現れました**。

- テクニカルよりもマネジメントに興味アリ
- マネジメントの中でも①プロセス②チーム開発③成長に興味アリ
- 「エンジニアリングマネージャー」に興味アリ

## 反響が大きかった記事の振り返り

一番反応が大きかったのは、AWSの勉強方法に関する投稿です。

100いいね以上の反応がありました。
自分にとっては当たり前のことでも発信することに価値があると気づくきっかけになりました。

https://qiita.com/mkt_hanada/items/f04131b427f90796f8e8

次に反応が多かったのは、ユーザーストーリーに関する記事です。

これは開発プロセスに関する内容です。
これまで書籍での学びをアウトプットするのが苦手でした。

この記事は、書籍のアウトプット方法の一つとして「自分の記事の書き方」が見つかりました。

https://qiita.com/mkt_hanada/items/d6c8c6ec2e11f1ad9666

次は合格体験記です。
合格がわかった日に投稿しました。

「合格体験記」として役に立つようにするためにはまだまだブラッシュアップできると思いました。

https://qiita.com/mkt_hanada/items/f30a856f5db35b000b23

## おわりに

38日間、ありがとうございました。

記事に対してフィードバックをくれる方がいたり、記事を毎日読んでくれている方がいたり、皆さんのおかげで完走できました。

今後は毎日投稿から週一投稿にペースを落としつつも、より価値ある発信を継続できればと思います。

## これまでの投稿

https://qiita.com/mkt_hanada/items/09a83e9faf76f181d79e

https://qiita.com/mkt_hanada/items/52015acdc2fc341d243c

https://qiita.com/mkt_hanada/items/340fc59c291db8aa192a

https://qiita.com/mkt_hanada/items/a190c869467ce23242c0

https://qiita.com/mkt_hanada/items/8b108eab2bdc79ff793f

https://qiita.com/mkt_hanada/items/edab289cac8709a0080f

https://qiita.com/mkt_hanada/items/d6c8c6ec2e11f1ad9666

https://qiita.com/mkt_hanada/items/f04131b427f90796f8e8

https://qiita.com/mkt_hanada/items/840253d9d3a72f5656a3

https://qiita.com/mkt_hanada/items/429a3cf6cb59f0433f1c

https://qiita.com/mkt_hanada/items/e2c91466031688b0d0b7

https://qiita.com/mkt_hanada/items/bdda306a8a4ccbc033a7

https://qiita.com/mkt_hanada/items/97b1bf3cf61411dde36b

https://qiita.com/mkt_hanada/items/e61c9b903d06141dd0dd

https://qiita.com/mkt_hanada/items/ec54c9a6a93055262207

https://qiita.com/mkt_hanada/items/a67f3f2cd8a1c74abac5

https://qiita.com/mkt_hanada/items/10c106e07249886da47e

https://qiita.com/mkt_hanada/items/9cf28fcbf7bd5ea1b45c

https://qiita.com/mkt_hanada/items/9c0215d82f23b7b7cb94

https://qiita.com/mkt_hanada/items/eb70657fd7c4a7c78907

https://qiita.com/mkt_hanada/items/673b0f5b843eb0a5a557

https://qiita.com/mkt_hanada/items/1df1e94a3699c3c50b81

https://qiita.com/mkt_hanada/items/d62c3380181d87f8a2a5

https://qiita.com/mkt_hanada/items/a27b910f540098d4034d

https://qiita.com/mkt_hanada/items/f30a856f5db35b000b23

https://qiita.com/mkt_hanada/items/7c0175f59a5affe241ad

https://qiita.com/mkt_hanada/items/dea02ba3d4b0d9635a36

https://qiita.com/mkt_hanada/items/158cf7d55e2b9e8619e0

https://qiita.com/mkt_hanada/items/10641baccf88e44de012

https://qiita.com/mkt_hanada/items/8879664983e43ab22a81

https://qiita.com/mkt_hanada/items/adf5532c6f020c08377c

https://qiita.com/mkt_hanada/items/e3c1c4b16d8b7997028f

https://qiita.com/mkt_hanada/items/2882cc4e9434a319471b

https://qiita.com/mkt_hanada/items/4bc9c3b861e9f90e9262

https://qiita.com/mkt_hanada/items/306af3e6afefd12e1ab3

https://qiita.com/mkt_hanada/items/2e7a0becd00cfc692b04

https://qiita.com/mkt_hanada/items/3191622d5ce62533bd2e
ブラウザ用Signed Distance Field (SDF)生成ライブラリを作ってみた

# WebGLでSigned Distance Field (SDF)生成ライブラリを作ってみた

## はじめに

WebGLを使って画像からSigned Distance Field (SDF)を生成するライブラリを作成しました。WebGLを内部的に使ってはいますが、高速化のためで、非WebGLアプリでも利用可能です。

SDFは文字のレンダリングや特殊効果の生成などに使われる便利なテクニックです。今回はこのライブラリの紹介と、開発中に得られた知見をお伝えします。

## ライブラリの概要

- 名前: fastsdf
- 機能: アルファ付きHTMLImageElementからSDF(HTMLImageElement)を生成
- 技術: TypeScript, WebGL2
- GitHub: [https://github.com/jonigata/fastsdf](https://github.com/jonigata/fastsdf)

## 基本的な使い方

npmからインストール:

```bash
npm install fastsdf
```

基本的な使用例:

```javascript
import { generateSDF } from 'sdf-generator';

const srcImg = new Image();
srcImg.onload = () => {
  const sdfImg = generateSDF(srcImg, 10 /*maxDist*/, 0.25 /*dstAlphaThreshold*/);
  document.body.appendChild(sdfImg);
};
srcImg.src = 'path/to/your/image.png';
```

## リファレンス

```ts
generateSDF(srcImg: HTMLImageElement, maxDist: number, dstAlphaThreshold: number): HTMLImageElement
```
Signed Distance Field画像を作ります。 出力imgのRGBは白で、Aは以下の説明のようにパラメータによって変わります。

- srcImg: 入力となるアルファ付きイメージ。アルファ以外は無視します
- maxDist: distanceを計算するときの最大距離
- dstAlphaThreshold: アルファ値の閾値(t)。出力アルファは以下のように計算されます
  - tの指定がない場合
      - 符号付き距離を距離を0~1に正規化した値(+maxDist→0、0→0.5、-maxDist→1.0)
  - tの指定がある場合
      - t < srcα:  1.0
      - srcα < t:  0.0
- return: dstImage

## 出力例

上：元画像(背景が白なのでわかりづらいですが、アルファは設定されています)
下：dstImageを水色で表示して、その上に元画像を乗せたもの

![GShzvZZagAAixzS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18886/d7b2823a-cfd5-2c4f-0cd5-f34dd8f31b1a.png)

コード的にはこんな感じです。

```javascript
const sdf = generateSDF(img, 10, 0.25);
const canvas = document.querySelector<HTMLCanvasElement>('#canvas')!;
const ctx = canvas.getContext('2d')!;

ctx.save();
ctx.drawImage(sdf, 0, 0);
ctx.globalCompositeOperation = 'source-in';
ctx.fillStyle = 'cyan';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.restore();

ctx.drawImage(img, 0, 0);
```

## まとめ

GPUの並列処理能力を活用することで、高速なSDF生成が可能になりました。今後も継続的に改良を加えていく予定です。

皆さんも是非試してみてください。フィードバックお待ちしています！
AWS secrets manager(最大サイズに達しました)

# 経緯
AWS Secrets Managerにおける既存のsecretに対して、コンソール画面でkeyとvalueを一行ずつ追加した時に、画面に下記のエラーメッセージが表示されて、変更が保存できなくなりました：

<font color="Red">
シークレットの最大サイズに達しました。シークレットは最大64KBです。情報を複数のシークレットに分割することをお勧めします。
</font>


# 原因
Secrets Managerの「**シークレット値のサイズ**」クォータを超えてしまったためです。

>シークレット値のサイズ：サポートされている各リージョン: **65,536** バイト（<font color="Red">引き上げ不可</font>）
https://docs.aws.amazon.com/ja_jp/secretsmanager/latest/userguide/reference_limits.html

# 解決策
情報を分割して、複数のsecretを利用します。

# 追伸
普通は、64KBが足りると思いますが、今回は、APIトークンやSFTP認証用のSSHキーなど、secretに格納するため、最大のサイズを超えてしまいました。
picoGyme Exclusive writeup GDB baby step 3

## GDB baby step 3 (Reverse Engineering)

Now for something a little different. 0x2262c96b is loaded into memory in the main function. Examine byte-wise the memory that the constant is loaded in by using the GDB command x/4xb addr. The flag is the four bytes as they are stored in memory. If you find the bytes 0x11 0x22 0x33 0x44 in the memory location, your flag would be: picoCTF{0x11223344}. Debug this.

添付ファイル
・debugger0_c

```
(gdb) disassemble main
Dump of assembler code for function main:
   0x0000000000401106 <+0>:     endbr64 
   0x000000000040110a <+4>:     push   rbp
   0x000000000040110b <+5>:     mov    rbp,rsp
   0x000000000040110e <+8>:     mov    DWORD PTR [rbp-0x14],edi
   0x0000000000401111 <+11>:    mov    QWORD PTR [rbp-0x20],rsi
   0x0000000000401115 <+15>:    mov    DWORD PTR [rbp-0x4],0x2262c96b
   0x000000000040111c <+22>:    mov    eax,DWORD PTR [rbp-0x4]
   0x000000000040111f <+25>:    pop    rbp
   0x0000000000401120 <+26>:    ret
```
0x2262c96bがロードされた後のところにブレイクポイントを設定。
メモリの格納されている場所はrbp-0x4で、`x/4xb addr`これを使えとのことである。
```
break *main+22
Breakpoint 1 at 0x40111c
(gdb) r
Breakpoint 1, 0x000000000040111c in main ()
(gdb) x/4xb $rbp-0x4   
0x7fffa216877c: 0x6b    0xc9    0x62    0x22
```
`0x6b    0xc9    0x62    0x22`が出てきたのでフラグ形式に直す。

`picoCTF{0x6bc96222}`
MySQLにエラーログもなくXAMPPでStartできなくなった時の備忘録

## MySQLの接続がすぐに切れる
プログラミングスクールに通い始め、XANPPでMySQLを使用した実習中に何度か起きたので記述します。
環境:Win11　XAMPP Control Panel V3.3.0

## 症状
<img width=400 alt="スクリーンショット 2024-07-17 174623.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3840359/6b5451b2-2442-8f43-31d1-52857f135536.png">

MySQLのStartを押すとすぐに上記のエラーにより接続が止まってしまいました。いろいろなところでは、「エラーログの確認後～・・・」などの記事があり再起動などを試しましたがダメ。
エラーログを確認しても次の通りのログで、特にエラーは見られませんでした。
```
[Note] Starting MariaDB 10.4.32-MariaDB source revision c4143f909528e3fab0677a28631d10389354c491 as process 14072
[Note] InnoDB: Mutexes and rw_locks use Windows interlocked functions
[Note] InnoDB: Uses event mutexes
[Note] InnoDB: Compressed tables use zlib 1.3
[Note] InnoDB: Number of pools: 1
[Note] InnoDB: Using SSE2 crc32 instructions
[Note] InnoDB: Initializing buffer pool, total size = 16M, instances = 1, chunk size = 16M
[Note] InnoDB: Completed initialization of buffer pool
[Note] InnoDB: Setting log file C:\xampp\mysql\data\ib_logfile101 size to 5242880 bytes
[Note] InnoDB: Setting log file C:\xampp\mysql\data\ib_logfile1 size to 5242880 bytes
[Note] InnoDB: Renaming log file C:\xampp\mysql\data\ib_logfile101 to C:\xampp\mysql\data\ib_logfile0
[Note] InnoDB: New log files created, LSN=551966
[Note] InnoDB: 128 out of 128 rollback segments are active.
[Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"
[Note] InnoDB: Creating shared tablespace for temporary tables
[Note] InnoDB: Setting file 'C:\xampp\mysql\data\ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
[Note] InnoDB: File 'C:\xampp\mysql\data\ibtmp1' size is now 12 MB.
[Note] InnoDB: Waiting for purge to start
[Note] InnoDB: 10.4.32 started; log sequence number 552460; transaction id 1052
[Note] InnoDB: Loading buffer pool(s) from C:\xampp\mysql\data\ib_buffer_pool
[Note] Plugin 'FEEDBACK' is disabled.
[Note] InnoDB: Cannot open 'C:\xampp\mysql\data\ib_buffer_pool' for reading: No such file or directory
[Note] Zerofilling moved table:  '.\mysql\plugin'
[Note] Zerofilling moved table:  '.\mysql\servers'
[Note] Server socket created on IP: '::'.

```

ただ、ウィンドウズビューアーの「管理イベントの要約」にてMariaDBでエラーが起きているようでした。詳細を見ると下記のようなエラーが出てました。
~~~
Fatal error: Can't open and lock privilege tables: Incorrect file format 'db'
~~~

どうもデータベース自体に問題が起こってそうでした。

## 実際にした操作
1.行った操作はC:\xampp\mysql\dataディレクトリを退避後(以後退避フォルダ）、中のファイルを全削除
2.C:\xampp\mysql\backupディレクトリ内をC:\xampp\mysql\dataディレクトリへコピー
3.XAMPP→MySQL起動を確認
（ここで起動できないようなら別に原因がありそうです
4.C:\xampp\mysql\dataディレクトリ内のmysql、performance_schema、phpmyadmin、testファルダ以外のファイルを削除
5．退避フォルダ内の上記のフォルダ以外(要は作成したDBフォルダ)とibdata1、myファイルを移動(myファイルは設定ファイルなので特に変えてないようなら、元ファイルで大丈夫そうですが、ibdata1はDBとの接続にかかわるファイルのため、必ず退避したファイルの物を置き換え)

破損したのが標準のDBだったのか、以上の操作で復旧できました。
Slackにインカミングウェブフックを使ってメッセージを送信する方法

Slackのインカミングウェブフックは、外部アプリケーションからSlackにメッセージを投稿するための簡単な方法です。この記事では、インカミングウェブフックの設定方法と使用方法について詳しく説明します。

## インカミングウェブフックの設定手順

1. Slackアプリを作成する（既にある場合はスキップ可能）
2. インカミングウェブフックを有効にする
3. インカミングウェブフックを作成する
4. 作成したウェブフックURLを使ってメッセージを投稿する

### 1. Slackアプリの作成

まず、[Slack APIのウェブサイト](https://api.slack.com/apps)でSlackアプリを作成します。アプリ名を決め、インストール先のワークスペースを選択してください。

### 2. インカミングウェブフックの有効化

アプリの設定ページで「Incoming Webhooks」を選択し、「Activate Incoming Webhooks」をオンにします。

### 3. インカミングウェブフックの作成

「Add New Webhook to Workspace」ボタンをクリックし、ウェブフックを追加するチャンネルを選択します。承認後、ウェブフックURLが生成されます。

### 4. メッセージの投稿

生成されたウェブフックURLを使用して、HTTPリクエストを送信することでメッセージを投稿できます。以下は基本的な例です：

```http
POST https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
Content-type: application/json
{
    "text": "Hello, Slack!"
}
```

## 高度なフォーマット

Slackのメッセージは、[Block Kit](https://api.slack.com/block-kit)を使用してより豊かな表現が可能です。以下は、Block Kitを使用した例です：

```json
{
    "blocks": [
        {
            "type": "section",
            "text": {
                "type": "mrkdwn",
                "text": "新しい通知があります:"
            }
        },
        {
            "type": "section",
            "fields": [
                {
                    "type": "mrkdwn",
                    "text": "*タイプ:*\n重要"
                },
                {
                    "type": "mrkdwn",
                    "text": "*作成者:*\n山田太郎"
                }
            ]
        }
    ]
}
```

## 注意点

- ウェブフックURLは秘密情報として扱い、公開リポジトリなどに掲載しないよう注意してください。
- インカミングウェブフックでは、デフォルトのチャンネル、ユーザー名、アイコンを上書きすることはできません。
- メッセージの削除はインカミングウェブフックではサポートされていません。

## まとめ

インカミングウェブフックは、外部アプリケーションからSlackにメッセージを送信する簡単で効果的な方法です。基本的な使用方法から高度なフォーマットまで、様々なニーズに対応できる柔軟性を持っています。

詳細については、[Slack APIのドキュメント](https://api.slack.com/messaging/webhooks)を参照してください。
gitでマージ済みのローカルブランチを一括削除

## 概要

開発を進めていると、いつの間にかローカルブランチが増えてしまって管理が大変…なんてこと、よくありますよね。特に、マージ済みのブランチはそのまま放置してしまいがちです。

でも大丈夫！  Git コマンドを使えば、**マージ済みのローカルブランチを一括削除**し、スッキリとしたブランチリストを維持できます。 

## なぜマージ済みのブランチを削除する必要があるの？

- **ブランチリストが見やすくなる:** 不要なブランチを削除することで、必要なブランチを見つけやすくなります
- **誤操作を防ぐ:** マージ済みのブランチが残っていると、誤って古いブランチで作業してしまう可能性があります
- **Git の動作を軽量化:** ブランチが多いと、Git の処理速度に影響が出る場合があります

## マージ済みのローカルブランチを一括削除する方法

以下のコマンドをターミナルで実行するだけで、マージ済みのローカルブランチを一括削除できます。

```
git branch --merged | grep -v \* | xargs git branch -d
```

## コマンド解説

このコマンドは、複数の Git コマンドをパイプ(`|`)でつなぎ合わせています。順番に見ていきましょう。

1. `git branch --merged`: マージ済みのブランチを全て表示します。現在チェックアウトしているブランチも含まれます。
2. `grep -v \*`: `grep` コマンドで、現在チェックアウトしているブランチ(`*` で表示される)を除外します。
3. `xargs git branch -d`: `xargs` コマンドを使って、`git branch -d` コマンドに削除対象のブランチ名を渡します。`git branch -d` は、マージ済みのブランチを削除するコマンドです。

## 使用上の注意点

- **削除したブランチは復元できません。** 実行前に、本当に削除してよいか確認しましょう。
- **リモートブランチは削除されません。** ローカルブランチのみが削除対象となります。
Pythonで自然言語処理の基礎に触れてみた

# はじめに
こんにちは、Webエンジニアの岩田史門([@SI_Monxy](https://x.com/SI_Monxy))です！
今回は、生成AIに触れているうちに自然言語処理に興味が出てきたので、Pythonを利用した自然言語処理の基礎について学んで記事を書いてみました！
改善点や修正点があれば、コメントにて優しくご指導いただけると嬉しいです！

# 概要
自然言語処理（Natural Language Processing, NLP）は、コンピュータが人間の言語を理解し、処理するための技術です。Pythonを使用した基本的なNLPの手法とその実装について解説します。

# テキストの前処理
テキストデータを扱う前に、以下のような前処理が必要です

``` python
import re
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize

nltk.download('punkt')
nltk.download('stopwords')

def preprocess_text(text):
    # 小文字化
    text = text.lower()
    # 数字の除去
    text = re.sub(r'\d+', '', text)
    # 句読点などの特殊文字の除去
    text = re.sub(r'[^\w\s]', '', text)
    # ストップワードの除去
    stop_words = set(stopwords.words('english'))
    tokens = word_tokenize(text)
    filtered_text = [word for word in tokens if word not in stop_words]
    return ' '.join(filtered_text)

# テキストの前処理例
text = "Natural Language Processing with Python is great!"
processed_text = preprocess_text(text)
print(processed_text)
```

# 単語のトークン化とベクトル化
テキストを単語レベルで処理し、数値データとして扱えるようにします

``` python
from sklearn.feature_extraction.text import CountVectorizer

# テキストのトークン化とベクトル化
corpus = [
    'This is the first document.',
    'This document is the second document.',
    'And this is the third one.',
    'Is this the first document?',
]

vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)

print(vectorizer.get_feature_names())
print(X.toarray())
```

# 品詞タグ付けと固有表現認識（NER）
テキストから品詞タグ付けや固有表現認識を行います

``` python
import spacy

nlp = spacy.load('en_core_web_sm')

# 品詞タグ付けと固有表現認識
doc = nlp("Apple is looking at buying U.K. startup for $1 billion")
for token in doc:
    print(token.text, token.pos_, token.dep_)

for ent in doc.ents:
    print(ent.text, ent.label_)
```

これらの手法とサンプルコードを使って、Pythonで自然言語処理を始める準備が整いました。

# 参考
- [NLTK Documentation](https://www.nltk.org/)
- [spaCy Documentation](https://spacy.io/)
CentOS7へbazel7をインストール

公式ではbazel4のインストールまでしか記載されてなかったので記録
https://docs.bazel.build/versions/5.4.1/install-redhat.html
今回はgithubからインストール用のスクリプトをダウンロード、実行してインストールを行なっていきます
### version
```
# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
```
unzip, wgetがインストール済みであること

## 手順
まず、githubから仕様したいバージョンを選び、Assetsから`bazel-*-installer-linux-x86_64.sh`のリンクをコピーしておきます（ちなみにMacOSだと`*-installer-darwin-x86_64.sh`）
https://github.com/bazelbuild/bazel/releases

例としてバージョン7.2.0を選択した場合
`https://github.com/bazelbuild/bazel/releases/download/7.2.0/bazel-7.2.0-installer-linux-x86_64.sh`

インストーラーをダウンロードして実行します
```
# wget https://github.com/bazelbuild/bazel/releases/download/7.2.0/bazel-7.2.0-installer-linux-x86_64.sh
# chmod +x bazel-7.2.0-installer-linux-x86_64.sh
# ./bazel-7.2.0-installer-linux-x86_64.sh
Bazel installer
---------------

Bazel is bundled with software licensed under the GPLv2 with Classpath exception.
You can find the sources next to the installer on our release page:
   https://github.com/bazelbuild/bazel/releases

# 

## Build information
   - [Commit](https://github.com/bazelbuild/bazel/commit/241a192)
which: no javac in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin)
Uncompressing.......

Bazel is now installed!

Make sure you have "/usr/local/bin" in your path.

For bash completion, add the following line to your ~/.bashrc:
  source /usr/local/lib/bazel/bin/bazel-complete.bash

For fish shell completion, link this file into your
/root/.config/fish/completions/ directory:
  ln -s /usr/local/lib/bazel/bin/bazel.fish /root/.config/fish/completions/bazel.fish

See http://bazel.build/start to start a new project!
```

これでインストールが完了
記載のように`/usr/local/bin`にパスが通っていればbazelコマンドが使えるようになっているはずです
```
# bazel --version
bazel 7.2.0
# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
```
通っていない場合は以下で通します
```
# export PATH=$PATH:/usr/local/bin
```
OpenAI APIで簡単な対話アプリを作ってみた

# はじめに
こんにちは、Webエンジニアの岩田史門([@SI_Monxy](https://x.com/SI_Monxy))です！
今回はOpenAI APIの利用について記事を書いてみました！
改善点や修正点があれば、コメントにて優しくご指導いただけると嬉しいです！

# 概要
OpenAI APIを使用すると、強力な自然言語処理を簡単にアプリケーションに組み込むことができます。GPTモデルを使用して、テキスト生成、対話、要約など多様なタスクを実行することができます。

# APIキーの取得
まず、OpenAIのAPIキーを取得する必要があります。以下の手順でAPIキーを取得します。

1. OpenAIの公式サイトにアクセスします。
2. アカウントを作成またはログインします。
3. ダッシュボードに移動し、APIキーを生成します。
4. 生成されたAPIキーを安全な場所に保存してください。

# 環境設定
次に、APIを利用するための環境を設定します。以下の手順に従って、Node.js環境でのセットアップを行います。

1. Node.jsをインストールします。

2. 新しいプロジェクトディレクトリを作成し、以下のコマンドを実行してNode.jsプロジェクトを初期化します。

``` bash
npm init -y
```

3. 必要なパッケージをインストールします。

``` bash
npm install openai axios
```

# 基本的なAPIリクエストの構造
OpenAI APIにリクエストを送信する基本的な構造は以下の通りです。リクエストには、APIキーと入力テキストを含める必要があります。

``` javascript
const axios = require('axios');

const apiKey = 'YOUR_API_KEY';
const apiUrl = 'https://api.openai.com/v1/completions';

async function getCompletion(prompt) {
    try {
        const response = await axios.post(apiUrl, {
            model: 'text-davinci-003',
            prompt: prompt,
            max_tokens: 100
        }, {
            headers: {
                'Authorization': `Bearer ${apiKey}`,
                'Content-Type': 'application/json'
            }
        });

        console.log(response.data.choices[0].text);
    } catch (error) {
        console.error(error);
    }
}

const prompt = "OpenAI APIの基本的な使い方を教えてください。";
getCompletion(prompt);
```

# 簡単な実装例
以下に、OpenAI APIを利用して簡単な対話アプリケーションを作成する例を示します。

``` javascript
const readline = require('readline');
const axios = require('axios');

const apiKey = 'YOUR_API_KEY';
const apiUrl = 'https://api.openai.com/v1/completions';

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

async function getCompletion(prompt) {
    try {
        const response = await axios.post(apiUrl, {
            model: 'text-davinci-003',
            prompt: prompt,
            max_tokens: 150
        }, {
            headers: {
                'Authorization': `Bearer ${apiKey}`,
                'Content-Type': 'application/json'
            }
        });

        console.log(response.data.choices[0].text);
    } catch (error) {
        console.error(error);
    }
}

rl.question('あなた: ', (input) => {
    getCompletion(input);
    rl.close();
});
```

# まとめ
この記事では、OpenAI APIの基本的な使い方と簡単な実装例を紹介しました。APIキーの取得方法、環境設定、基本的なAPIリクエストの構造、そして簡単な対話アプリケーションの実装例について学びました。OpenAI APIを活用して、さまざまな自然言語処理タスクを実現することができます。

# 参考
- [OpenAI公式サイト](https://openai.com/)
- [OpenAI APIリファレンス](https://platform.openai.com/docs/api-reference/introduction)
【しくじり先生】HHKB Studioのポテンシャルを引き出せなかったエンジニア

# 初めまして
初めまして！[株式会社 Panta Rhei](https://www.pantarhei.co.jp)でデータ周りやCEOをやったりしています。X(旧Twitter)は[pandasista](https://x.com/sotsogprinciple)というハンネです。

# HHKB Studioを買ってみた

https://happyhackingkb.com/jp/products/studio/

さる2023年の12月、HHKB StudioのUSキーボード版を44,000円で購入しました。
<B>「最小の動きで、無限大の創造を」</B>
というキャッチフレーズに惚れ込み、HHKB公式Xアカウントに常に張り付いて入荷スケジュールを把握し、
当日は「入荷しました！」という投稿がされる前(午前10時ごろ)に購入ボタンをクリックしました。
高かったです！
が、それ以上に「<B>手の動きがキーボード上だけで完結する</B>」という部分が非常に魅力的でした。

# めちゃくちゃ良かったこと
打鍵感がめちゃくちゃ良かったです。打ってる時、

- <B>しごでき感</B>
- <B>進捗産んでる感</B>

を非常に感じ気持ちが良かったです。
多分この感覚はHHKBキーボードならでは、と言った感じでした！
静電容量無接点方式からメカニカルになってちょっと界隈がざわつきましたが、個人的には違いがよく分からんくらいには素敵な打鍵感でした。

また以前までDrevoの青軸ゲーミングキーボードを用いていました。
それに比べると強く打鍵してもかなり静かで、オンラインMTGの時に気を払わずに済みました。

# 使ってみた結論

### <B><font color="red">あんまり良さを活かせなかった！</font></B>

# あんまり刺さらなかった部分
1. 重さ
2. キーボード面の高さ
3. サイドのタッチパネルが誤入力を起こす
4. ピンチイン/アウトがしにくい(Google Mapなど)
5. caps lockの位置にctrlはちょっと慣れない
6. 意図したところにカーソルをスパッと置けない

## 1. 重さ
めちゃ重いです。
|キーボード|重量|
|---|---|
|HHKB Studio US配列|840 g (電池なし)|
|(比較対象)Apple Mac Magic Keyboard US|243 g|

MacのMagic Keyboardと比較すると重さは3倍以上です。
単三電池(約25g)を4本入れると、重さは4倍も変わってきます。
これはちょっと持ち運ぶには不便がありました。

持ち運ばずにPC付属のキーボードを使えばええやん、となりますが、自前のPC(Macbook ProのUS配列)とは配列が違うため、入力時に頭のリソースをやや取られる格好となります。
それを避けるために持ち運ぶ、という選択をとっていました。

## 2. キーボード面の高さ
キーボード面が高いです。そのため、手首がやや上向きになり疲れます。
これはパームレストで解消できる部分でしたが、持ち運び時にパームレストも携帯しなければいけなくなり、ややUXが落ちてるかなぁと感じました。

## 3. サイドのタッチパネルがご入力を起こす
これは他にも仰っている方を拝見しました。
手癖が良くないという部分も大いにありますが、サイドパネルをうっかり触ってしまい、意図しないスクロールが発生するということがよくありました。

## 4. ピンチイン/アウトがしにくい
Google Mapなど、ピンチイン/ピンチアウトするようなアプリケーションと相性が悪かったです。
一応ズームはできるのですが、「⌘」+「+/-」と同じ機能で、「ブラウザの拡大/縮小機能は使えるけどAJAXの拡大/縮小機能は使えない」と言った感じでした。
MacのTrack Padに慣れているとやや不便さを感じました。

## 5. caps lockの位置にctrl、独特なキー配置
MacBookのUS配列erの方は「Ctrl」+「Space」を多用します。
英字/日本語変換に用いるものですが、「Ctrl」の位置がCapsLockの位置にあるのがつらみでした。
最終的に左のoptionキーをカスタム配列でCtrlに変更して、Macとの差分を少なくしていました。

## 6. 意図したところにカーソルをスパッと置けない
これは当方の習熟不足が大いにあります。
例えば以下のようなちっちゃいバツボタン、ここにカーソルが合わせにくい。

![スクリーンショット 2024-07-17 18.09.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540865/3d96f5cc-7ce3-6ea6-cfaf-82c73c134b88.png)

マウスポインタは、傾斜を深くするとカーソルが倒した方向に加速する仕様でした。
この加速のコントロールが上手くできず、小さいボタンを押すのに苦労しました。

# 最後に
キーボードの上から全く手を離さなくていい、という試みはすごいエンジニアフレンドリーで良き良きの良きです！
また似たようなコンセプトのキーボードがHHKBから出てきたら挑戦してみようと思います！
Dockerを用いたLaravelの環境構築

# はじめに
こんにちは、Webエンジニアの岩田史門([@SI_Monxy](https://x.com/SI_Monxy))です！
今回はDockerを用いたLaravelの環境構築について記事を書いてみました！
改善点や修正点があれば、コメントにて優しくご指導いただけると嬉しいです！

# 概要
Dockerを使用することで、ローカル開発環境を迅速かつ一貫してセットアップできます。このガイドでは、Laravelアプリケーションの開発環境をDockerで構築する手順を紹介します。

# 前提条件
- Dockerがインストールされていること
- Docker Composeがインストールされていること

# 手順概要
1. Laravelプロジェクトの作成
2. Dockerファイルの作成
3. Docker Composeファイルの作成
4. 環境設定ファイルの編集
5. Dockerコンテナのビルドと起動

# 1. Laravelプロジェクトの作成
まず、Laravelプロジェクトを作成します。以下のコマンドを実行して、新しいLaravelプロジェクトを作成します。

``` bash
composer create-project --prefer-dist laravel/laravel my-laravel-app
cd my-laravel-app
```

# 2. Dockerファイルの作成
次に、プロジェクトディレクトリのルートに Dockerfile を作成し、以下の内容を追加します。

``` Dockerfile
# ベースイメージを指定
FROM php:8.1-fpm

# 作業ディレクトリを設定
WORKDIR /var/www

# 必要なパッケージをインストール
RUN apt-get update && apt-get install -y \
    build-essential \
    libpng-dev \
    libjpeg62-turbo-dev \
    libfreetype6-dev \
    locales \
    zip \
    jpegoptim optipng pngquant gifsicle \
    vim \
    unzip \
    git \
    curl

# Docker PHP Extension Installerを使用して拡張機能をインストール
RUN docker-php-ext-install pdo pdo_mysql

# Composerをインストール
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Laravelアプリケーションのファイルをコピー
COPY . /var/www

# 権限を設定
RUN chown -R www-data:www-data /var/www

# エントリーポイント
CMD ["php-fpm"]
```

# 3. Docker Composeファイルの作成
次に、 docker-compose.yml ファイルをプロジェクトディレクトリのルートに作成し、以下の内容を追加します。

``` yaml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: laravel-app
    container_name: laravel-app
    restart: unless-stopped
    working_dir: /var/www
    volumes:
      - .:/var/www
      - ./docker/php/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - laravel

  webserver:
    image: nginx:alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "8000:80"
    volumes:
      - .:/var/www
      - ./docker/nginx/conf.d:/etc/nginx/conf.d
    networks:
      - laravel
    depends_on:
      - app

  db:
    image: mysql:5.7
    container_name: db
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: laravel
      MYSQL_USER: laravel
      MYSQL_PASSWORD: secret
    ports:
      - "3306:3306"
    volumes:
      - dbdata:/var/lib/mysql
    networks:
      - laravel

networks:
  laravel:
    driver: bridge

volumes:
  dbdata:
    driver: local
```

# 4. 環境設定ファイルの編集
.env ファイルを編集し、データベース接続情報を設定します。

``` env
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=secret
```

# 5. Dockerコンテナのビルドと起動
以下のコマンドを実行して、Dockerコンテナをビルドし、起動します。

``` bash
docker-compose up --build
```

ブラウザで http://localhost:8000 にアクセスし、Laravelのウェルカムページが表示されることを確認します。

# まとめ
このガイドでは、Dockerを使用してLaravel開発環境を構築する方法を紹介しました。Dockerを活用することで、簡単に開発環境をセットアップし、プロジェクト間での環境の一貫性を保つことができます。

# 参考
- [Docker公式サイト](https://www.docker.com/)
- [Laravel公式サイト](https://laravel.com/docs/11.x)
Unityで始めるVR FPSゲーム開発

こんにちは。今回は、UnityでのVR FPSゲーム開発に興味がある方向けに、基本的な開発手法を紹介します。
。Unityは初心者にも扱いやすく、強力なゲーム開発エンジンが豊富です。
参考：https://feynman.co.jp/unityforest/game-create-lesson/fps-game/

## UnityでVR FPSを作るメリット

Unityはコードがシンプルで読みやすく、初心者にも理解しやすいエンジンです。また、Unityで作成したゲームはWindows、macOS、Linuxなどのマルチプラットフォームで動作します。さらに、豊富なアセットやツールを活用することで、効率的にゲームを開発することが可能です。

### 環境設定

まずはUnityの環境設定から始めましょう。Unityをインストールし、必要なライブラリもインストールします。

#### Unityのインストール

Unityをインストールするには、[公式サイト](https://unity.com/)からインストーラをダウンロードし、指示に従ってインストールします。インストールが完了したら、Unity Hubを開き、新しいプロジェクトを作成しましょう。

## 基本的なFPSゲームの作成

Unityを使ってシンプルなFPSゲームを作成します。このゲームでは、プレイヤーが一人称視点で敵を倒すことを目指します。

### ゲームのロジック

FPSゲームは、一人称視点でプレイヤーが移動し、敵を攻撃するゲームです。プレイヤーの入力に対して、ゲーム内のカメラとキャラクターが連動します。

```csharp
using UnityEngine;

public class FPSController : MonoBehaviour
{
    public float speed = 5.0f;
    public float rotationSpeed = 200.0f;
    private CharacterController controller;
    private Vector3 moveDirection = Vector3.zero;

    void Start()
    {
        controller = GetComponent<CharacterController>();
    }

    void Update()
    {
        // プレイヤーの移動
        float moveForward = Input.GetAxis("Vertical") * speed;
        float moveSide = Input.GetAxis("Horizontal") * speed;
        moveDirection = new Vector3(moveSide, 0, moveForward);
        moveDirection = transform.TransformDirection(moveDirection);
        controller.Move(moveDirection * Time.deltaTime);

        // プレイヤーの回転
        float rotate = Input.GetAxis("Mouse X") * rotationSpeed * Time.deltaTime;
        transform.Rotate(0, rotate, 0);
    }
}
```

このコードは、プレイヤーキャラクターの基本的な移動と回転を実装したものです。キャラクターコントローラーを使用して、キーボード入力で移動し、マウス入力で回転します。

## 高度なFPSゲームの作成
基本的なFPSゲームを完成させた後は、さらに高度なテクニックを用いてVR対応を進めましょう。

### VR対応の実装
VR対応のFPSゲームを作成するには、UnityのXR Interaction Toolkitを活用します。これにより、VR環境でのインタラクションが容易に実装できます。
```csharp
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;

public class VRBowAndArrow : MonoBehaviour
{
    public XRController leftController;
    public XRController rightController;
    public GameObject arrowPrefab;
    private GameObject currentArrow;

    void Update()
    {
        // 矢を引く処理
        if (rightController.activateInteractionState.active)
        {
            if (currentArrow == null)
            {
                currentArrow = Instantiate(arrowPrefab, leftController.transform.position, leftController.transform.rotation);
                currentArrow.transform.parent = leftController.transform;
            }
        }

        // 矢を放つ処理
        if (rightController.activateInteractionState.deactivatedThisFrame)
        {
            if (currentArrow != null)
            {
                currentArrow.transform.parent = null;
                Rigidbody rb = currentArrow.GetComponent<Rigidbody>();
                rb.isKinematic = false;
                rb.velocity = leftController.transform.forward * 20;
                currentArrow = null;
            }
        }
    }
}
```

このコードは、VR環境での弓と矢の操作を実装したものです。XR Controllerを使って、矢を引く操作と放つ操作を実現します。

## まとめ
UnityでVR FPSを作るメリット
・環境設定の簡便さ
・基本的なFPSゲームの作成手順
・VR対応の実装方法
UnityでのVR FPSゲーム開発は初心者でも簡単に始められます。ぜひ挑戦してみてください。
LaravelでAWS S3を利用してみた

# はじめに
こんにちは、Webエンジニアの岩田史門([@SI_Monxy](https://x.com/SI_Monxy))です！
今回はLaravelでのAWS S3の利用について記事を書いてみました！
改善点や修正点があれば、コメントにて優しくご指導いただけると嬉しいです！

# 概要
AWS S3（Amazon Simple Storage Service）は、高い可用性とスケーラビリティを持つクラウドストレージサービスです。Laravelは、その柔軟なストレージシステムを介して、簡単にS3を利用することができます。本記事では、LaravelアプリケーションからAWS S3ストレージを利用する方法について詳しく解説します。

# 前提条件
- Laravelプロジェクトがセットアップされていること
- AWSアカウントがあること
- AWS CLIがインストールされていること

# AWS S3バケットの作成
まず、AWSマネジメントコンソールにログインし、S3バケットを作成します。

## 1. S3コンソールにアクセス
AWSマネジメントコンソールから「S3」を選択します。

## 2. バケットの作成
「バケットを作成」ボタンをクリックし、バケット名とリージョンを設定します。必要に応じて他の設定も行います。

## 3. バケットの作成完了
設定を確認し、「バケットを作成」ボタンをクリックします。

# Laravelプロジェクトの設定
次に、Laravelプロジェクトに必要なパッケージをインストールし、設定を行います。

## 1. パッケージのインストール
以下のコマンドを実行し、AWS SDK for PHPをインストールします。

``` bash
composer require aws/aws-sdk-php
```

## 2. 環境変数の設定
.envファイルに以下の設定を追加します。

``` bash
AWS_ACCESS_KEY_ID=your-access-key-id
AWS_SECRET_ACCESS_KEY=your-secret-access-key
AWS_DEFAULT_REGION=your-region
AWS_BUCKET=your-bucket-name
```

# AWS S3ストレージドライバの設定
Laravelの設定ファイルを編集し、S3ストレージドライバを有効にします。

## 1. config/filesystems.phpの編集
config/filesystems.phpファイルを開き、以下のように設定します。

``` php
'disks' => [

    's3' => [
        'driver' => 's3',
        'key' => env('AWS_ACCESS_KEY_ID'),
        'secret' => env('AWS_SECRET_ACCESS_KEY'),
        'region' => env('AWS_DEFAULT_REGION'),
        'bucket' => env('AWS_BUCKET'),
        'url' => env('AWS_URL'),
        'endpoint' => env('AWS_ENDPOINT'),
    ],

],
```

# ファイルのアップロードとダウンロード
S3ストレージを利用してファイルをアップロードおよびダウンロードする方法を説明します。

## 1. ファイルのアップロード
コントローラ内で、以下のようにファイルをS3にアップロードします。

``` php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class FileController extends Controller
{
    public function upload(Request $request)
    {
        if ($request->hasFile('file')) {
            $path = $request->file('file')->store('uploads', 's3');
            return response()->json(['path' => $path], 200);
        }

        return response()->json(['message' => 'File not uploaded'], 400);
    }
}
```

## 2. ファイルのダウンロード
コントローラ内で、以下のようにファイルをS3からダウンロードします。

``` php
class FileController extends Controller
{
    public function download($filename)
    {
        $file = Storage::disk('s3')->get("uploads/{$filename}");
        return response($file, 200)
            ->header('Content-Type', 'application/octet-stream')
            ->header('Content-Disposition', "attachment; filename={$filename}");
    }
}
```

# まとめ
本記事では、LaravelアプリケーションからAWS S3ストレージを利用する方法について解説しました。S3バケットの作成から、Laravelの設定、ファイルのアップロードとダウンロードまでの一連の流れを理解していただけたかと思います。AWS S3を活用することで、柔軟でスケーラブルなファイルストレージソリューションを簡単に導入することができます。

# 参考

- [AWS S3 - Amazon Simple Storage Service](https://aws.amazon.com/jp/s3/)
- [Laravel Documentation - File Storage](https://laravel.com/docs/10.x/filesystem)
- [AWS SDK for PHP Documentation](https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/welcome.html)