OmniAICreator/Qiita-1.07M huggingface dataset:
5分で読むReact豆知識 | 入門 | シリーズリンク

# はじめに
このシリーズは、Reactの公式ページなどから特に重要と感じたトピックを選び出し、何度でも読み返せるよう簡潔にまとめたものです。
「React学んでみた」のタイトルで記事を書かせていただいた内容からこれは覚えておきたいなというトピックを選んでいます。

**より詳しく知りたい方は[公式ホームページ](https://ja.react.dev/learn/describing-the-ui)へ。**

みなさんの学習のモチベーションにつながりましたら大変嬉しいです。

**進捗管理には「いいね」か「ブックマーク」がお勧め**

さらに僕のモチベーションアップになります！:thumbsup:よろしくお願いいたします！:thumbsup:

# 目次
[第1回: コンポーネントとstate](https://qiita.com/mr_noppo/items/651ada17dd0cb4a79b35)
[第2回: state更新の落とし穴](https://qiita.com/mr_noppo/items/436661ce0e1c3e44f1e9)
[第3回: 再レンダリングのタイミング](https://qiita.com/mr_noppo/items/2c4c64a55ba687f57d27)
[第4回: イベントハンドラ命名規則](https://qiita.com/mr_noppo/items/ee64dd4bc9cbdfb6b241)
[第5回: stateの保持と破棄](https://qiita.com/mr_noppo/items/b0933e7cf02c93fb46ee)
[第6回: 代表的なHooks](https://qiita.com/mr_noppo/items/19e825b4e631e1a271a1)
[第7回: state構造の原則](https://qiita.com/mr_noppo/items/458287aa095dc4c1bf33)
[第8回: state配列の更新](https://qiita.com/mr_noppo/items/b0ad8b049ae36224568e)
[第9回: レンダリングの落とし穴](https://qiita.com/mr_noppo/items/e5d507fe79fa3c9b087a)
[第10回: OnClickの即時関数に注意](https://qiita.com/mr_noppo/items/9a529fdfb8421f30cb80)
JavaScript: let, const, classに関して用途以外の豆知識

まず有効な記述法について。scopeが異なるので以下の例では2重定義とはなりません。
```js
//外側block scope
let a=-~-~0-~-~0;
const b=1e+999;
//内側block scope
{
	let a=new class{};
	const b=class{};
	class c{}
}
```
などといった芸風はよく見掛けますね。しかし以下のような記述をすると不思議な事が起こります。
```js
eval("let a=0;const b=1;class c{}");
console.log(typeof a, typeof b, typeof c)
```
evalの中には`{}`が無いので`a`、`b`、`c`はconsole.logと同一scopeに存在しているかのような印象を受けますが、実際には**eval実行部分でしか参照できません**。よってconsole.logではundefinedが出力されます。
以下の記述は`{}`を省略できる状況で`var`と`let`による変数宣言や`class`定義を試みています。しかしなんと`var`以外は文法違反です(当たり前田)。evalみたいな事ができません。
```js
if(1)var a=0;
if(1)let b=0;
if(1)class c{}
```
setTimeoutを使うと何やら様子がおかしいですよ…。
```js
{
	setTimeout("let a=0",0);
}
setTimeout(_=>console.log(a),1000)
```
何と**変数aは外側のscopeに**解き放たれています。結果として`0`が出力されます。そして驚くべき事に、**block scope内の関数scope**でsetTimeoutを実行しても変数は最も外側のscopeに転がっていきやがります。
```js
{
	let f=()=>{setTimeout("let a=0",0)};
	f()
}
setTimeout(_=>console.log(a),1000)
```
当然setIntervalでもその挙動は同じ事になります。以下の例だと即座に`Identifier 'a' has already been declared`などとError警察からの通知が届きます
```js
setInterval("let a=0",500)
```
以下の例は通常は文法違反となる2重定義。
```js
f=a=>{let a=0}//引数の名前と被ってますよ
```
しかしsetTimeout様の手に掛かれば見事違反を貫通。
```js
f=a=>{setTimeout("let a=0")}
```
では問題。以下の処理ではconsole.logで何が出力されるかな? 今までの説明で楽勝でしょう。
```js
f=a=>{
	setTimeout("let a=0");
 	setTimeout(_=>console.log(a),1000)
}
f(1)
```
ちなみに最外殻scopeの汚染を防ぐには`"{...}"`のように処理を囲めばよい。
```js
setTimeout("{let a=0}")
```
余談にはなりますがsetTimeoutの第一引数に文字列を渡した場合、その中では**大域変数と最外殻scopeの変数しか参照できません**。block scopeや関数scopeの変数を参照したければ第一引数に関数を渡す事になります。
```js
{
	let a=0;
	setTimeout(_=>console.log(a))
	setTimeout("console.log(a)")//error
}
```
以上の事から`setTimeout("...")`の文字列中の処理は最外殻scopeに記述しているのと同じ事かもしれません
【3ヶ月でFlask基礎固め】 2 . SNSアプリを作ってみた


## TWITTY の機能紹介
ポートフォリオ第一弾「TWITTY」が完成したのでブログに起こします。
このアプリではCRUDの基本的な操作は全て網羅しており、
さらにAjaxやFlask-migrationなどの拡張機能の実装にも挑戦しました。


GitHub : TWITTY
https://github.com/lovehakumai/TWITTY


◼️LP画面 :
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684559/906f2bcd-f123-6029-294f-f6d35ff408b2.png)

◼️アクセス画面 : 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684559/585aa87b-5df1-9612-d0ff-f6cc66559c0a.png)

PurecssのテンプレートにもあるLPレイアウトを参考にLPを作成しました。
SIGN UP - アカウント新規作成
SIGN IN - ログイン
*アクセス画面には桜吹雪が舞っています笑

もし入力値に間違いがあればエラーメッセージが表示されます。
正しいID/PASSであればタイムラインの表示されたホーム画面へ接続されます。

◼️ホーム画面 : 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684559/ae09642f-4a70-8adb-2585-c4ce5c2c6bff.png)

自分と自分がフォローしているユーザーの投稿が一覧として表示されます。

◼️マイプロファイル画面 : 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684559/34a40a94-3655-f03b-f3c9-210ca1394e00.png)

自分のニックネームと自己紹介、そして直近の投稿が一覧として表示される画面です。
「Edit Your Profile」から編集ができます。

(編集画面) : 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684559/4670a2e0-afc4-a3b3-2391-761f58e001b6.png)

◼️投稿画面 : 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684559/f74eefcf-d771-dd92-803a-9d7463d1d90c.png)

画像とタイトル。そしてその説明文を登録する画面になります。
ここで入力した内容はデータベースに保存されます。

◼️他ユーザ検索画面 : 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684559/9011b8de-8452-fdaf-bf72-0cbef888e881.png)

*検索結果(非同期通信) : 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684559/fb0e4769-4f93-c8e4-61bd-d71b416b342d.png)

一番苦労した部分。
キーワードを元に他のユーザのプロファイル&投稿内容を検索することができます。

「Users」「Posts」というボタンで、ユーザのニックネームを検索するか投稿タイトルを検索するかを指定できます。
Ajax処理で非同期通信を行うのでTwitterの同じ機能の様な操作感を再現しました。

検索結果から次のユーザープロファイル画面に移行することができます。


◼️ユーザープロファイル画面 : 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684559/6e8dd4d9-3ac4-128a-672b-cb2dac3219c5.png)

気に入ったユーザをフォローすることができます。
フォローボタンはデータベースと連動していて、フォローしていたら「Following」。
フォローしていなかったら「Follow」となります。

このボタンもAjaxの非同期処理なのでクリックするたびにデータベースを更新します。


◼️スマホの操作画面 : 

![Twitty-quiita用.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684559/b7ed8417-550f-7be7-d72a-1a5dd55c1c08.gif)

gif画像早すぎて恐縮ですが、スマホにも対応しているレスポンシブデザインを適用しています。
(一部はまだ未対応)
Python クラス作成（備忘録）

# Pythonクラス
## はじめに
個人レベルの備忘録
クラス作成、継承、オーバライドを簡単に行った。

```python
class text_output1:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def announce(self):
        print("xの値は", self.x)
        print("yの値は", self.y)
        print("この関数はtext_output1によるものです。")

t = text_output1(4,50)
```

メソッドオブジェクトを出力するとこんな感じになるので注意
する機会はないと思うが

```python
print(t.announce)
```
```:出力
<bound method text_output1.announce of <__main__.text_output1 object at 0x7fc68035d2d0>>
```

メソッドオブジェクトを呼び出す

```python
t.announce()
```
```:出力
xの値は 4
yの値は 50
この関数はtext_output1によるものです。
```

```python
# 継承＆オーバライド
class text_output2(text_output1):
    def __init__(self, x, y, z):
        super().__init__(x, y)
        self.z = z
    def announce_sub(self):
        print("zの値は", self.z)
        print("この関数はtext_output2によるものです。")
    def announce(self):
        print("この関数はtext_output1のannouceをオーバライドしたものです。")

t2 = text_output2(8, 100, 13)
t2.announce_sub()
t2.announce()
```
```:出力
zの値は 13
この関数はtext_output2によるものです。
この関数はtext_output1のannouceをオーバライドしたものです。
```
Javaで「文字列リテラル」の動作を確認してみた

# 概要

Javaで「文字列リテラル」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/num/index3.html

# 実装

以下のファイルを作成しました。
```JSample3_1.java
class JSample3_1{
  public static void main(String[] args){
    System.out.println("Hello World");
    System.out.println("こんにちは");
  }
}
```

以下のコマンドを実行しました。
```
$ javac -encoding UTF-8 JSample3_1.java
$ java JSample3_1 
Hello World
こんにちは
```

# まとめ

何かの役に立てばと。
FlaskアプリでCeleryを使ってバックグラウンドタスクを実行する方法

### FlaskアプリでCeleryを使ってバックグラウンドタスクを実行する方法

#### 環境設定
必要なツールとライブラリをインストールします。

1. **Redisのインストール**
   macOSを使用している場合、Homebrewを通じてRedisを簡単にインストールできます。
   ```bash
   brew install redis
   ```
   インストール後、Redisサーバーを起動します。
   ```bash
   redis-server
   ```

2. **FlaskとCeleryのライブラリのインストール**
   ```bash
   pip install Flask Celery redis
   ```

#### Flaskアプリの設定
Flaskアプリを設定し、Celeryのインスタンスを初期化します。
```python
from flask import Flask
from celery import Celery

app = Flask(__name__)
app.config["broker_url"] = "redis://localhost:6379/0"
app.config["result_backend"] = "redis://localhost:6379/0"
app.config['broker_connection_retry_on_startup'] = True

celery = Celery(app.name, broker=app.config["broker_url"])
celery.conf.update(app.config)
```

#### タスクの定義
非同期タスクをCeleryで定義します。
```python
@celery.task
def process_files(file_path_list):
    for path in file_path_list:
        print(f'Processing {path}')
```

#### タスクの実行
Flaskルートから非同期タスクを実行します。
```python
@app.route('/start-task')
def start_task():
    process_files.delay(["path1", "path2", "path3"])
    return "Task started!", 202
```

#### Celeryワーカーの起動
ターミナルで以下のコマンドを実行して、Celeryワーカーを起動します。
```bash
celery -A your_flask_file_name.celery worker
```

この設定により、Flaskアプリケーションはバックグラウンドでタスクを実行し、非同期処理の完了を待たずに応答を返すことができます。
【アイディア】バズるタイトルジェネレーター


## 前書き

私の人工知能の知識はゼロです。

## アイディアの概要

1. Qiita内でいいね、ストックが一定数以上ある記事を抽出する
1. それらを人工知能に学習させる
1. 記事の内容から、バズるタイトルを作れる人工知能ができる

## タイトルよりも内容が大事なのでは？という正論に対して

その通りだが見てもらわれなければ意味がないし、承認欲求も満たされない。
凡人の我々には人目につくタイトルが思いつかないのでAIに考えてもらったほうがいいかもしれない。

## 既存ツールについて

調べてみたら既にそういうツールが存在した。

https://ahrefs.com/ja/writing-tools/seo-title-generator

確かに素晴らしいツールではあるが、
生成されるタイトルは無難なものであり、インパクトがないように感じる。

これは様々なサイトの記事から学習しているため、一般的な出力になっていると思われる。

そういう観点で、ここで提案したバズるタイトルジェネレーターはQiitaというサイトのみを学習データとしているため、いい意味で偏ったタイトルが生成できると期待できる。

## 最後に

アイディアは自由にパクってください。
React Native VS Ionic　〜モバイルアプリ開発の戦い〜

# はじめに
React NativeとIonicはどちらもクロスプラットフォームのモバイルアプリ開発を可能にしますが、開発者が直面する選択肢の多さはしばしばプロジェクトの方向性を見失わせがちです。
この記事では、それぞれのフレームワークの特徴と適した用途を比較します。

# React Nativeの特徴
### 開発言語
 JavaScriptまたはTypeScriptを使用します。
### 実行環境
 ネイティブコンポーネントを使用してUIを構築し、そのためアプリのパフォーマンスが高いです。
 ネイティブコンポーネントとは、モバイルOSの基本的な機能に直接アクセスし、その結果として高速で滑らかなユーザー体験を提供するものです。
 実際のネイティブアプリに近い体験を提供します。
### コミュニティとサポート
 Facebookによって開発され、大きなコミュニティと広範なサポートがあります。
 多くのサードパーティのライブラリやツールが利用可能です。
### 学習曲線
  React（Web向けフレームワーク）に精通している場合は、比較的簡単に移行できますが、ネイティブ開発に関する知識がないと初期の学習がやや難しい場合があります。
### スクリーンショット
React Nativeで開発されたアプリの例を以下に示します。
![react.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/95201d87-9002-c3a5-3579-4d8c299c0575.png)
(https://bagelee.com/programming/react-native/react-native-apps-example/ より引用)

# Ionicの特徴
### 開発言語
HTML, CSS, JavaScriptまたはTypeScriptを使用します。
Angular, React, Vueなどの任意のフレームワークと組み合わせて使用することも可能です。
### 実行環境
Web技術を用いてアプリを構築し、CordovaやCapacitorを通じてネイティブ機能にアクセスします。
Webビューをベースにしているため、完全なネイティブアプリほどではないが、良好なパフォーマンスを提供します。
### コミュニティとサポート
広範囲なコミュニティがあり、多くのプラグインや統合ツールが存在します。
文書化も充実しており、入門しやすいです。
### 学習曲線
Web開発に慣れている開発者にとっては非常に取り組みやすいです。
HTMLとCSSの知識が直接活用できるため、Webからの移行は非常にスムーズです。

# 選択における考慮点
### パフォーマンス
高いパフォーマンスが求められるアプリ開発には、React Nativeの方が適しています。
### 開発速度と容易さ
シンプルなUIの開発を迅速に進めたい場合、またはWeb開発の経験を活かしたい場合はIonicが適しています。
### プロジェクトの要件
アプリが要求するネイティブ機能の範囲や、既存のWeb技術との統合が必要かどうかによっても、選択肢が変わる場合があります。


# 具体的な使用例

### React Native
#### 大規模なソーシャルアプリ
React NativeはInstagramやFacebookのような大規模なソーシャルメディアアプリに適しています。
これらのアプリは高度なユーザーインターフェースとスムーズなユーザーエクスペリエンスが求められ、React Nativeのネイティブコンポーネントはこれを実現するのに役立ちます。

### Ionic
#### コンテンツ中心のアプリ
Ionicはニュースアプリや電子書籍アプリなど、コンテンツを中心としたアプリに適しています。
Web技術を基盤としているため、HTMLやCSSでリッチなコンテンツを効率的に表示できます。

### 技術選択の追加ポイント
#### 開発リソース
チームがReactに既に精通している場合、React Nativeが自然な選択となります。
一方で、IonicはAngular、React、またはVueを既に使用しているチームにとっても適しており、学習曲線を最小限に抑えることができます。
#### プラットフォームの特性
React NativeはiOSとAndroidの両方でほぼ同様のユーザーエクスペリエンスを提供しますが、IonicはWebビューを使用するため、プラットフォーム間での見た目が異なることがあります。
これは特にスタイルやアニメーションにおいて顕著です。

# おわりに
パフォーマンスとネイティブのような体験を重視するならReact Native、開発の容易さと迅速な市場投入を重視するならIonicがお勧めです。
どちらのフレームワークも独自の強みがありますが、最終的にはプロジェクトの具体的な要件と開発チームのスキルセットによって適切なツールが異なるため、個々のプロジェクトに最適なフレームワークを選択することが最も重要です。

# 備考
+ [React Native 公式ドキュメント](https://reactnative.dev/)
+ [Ionic 公式ドキュメント](https://ionic.io/)
2024/5/6主にITとかセキュリティの記事

【第3回】ライフサイエンス業界における効果的なサイバーセキュリティ対策とは(5/3)
https://www.gmp-platform.com/article_detail.html?id=25416&lang=ja

IoT安全確保、日本企業の動き鈍く　英新法対応2割のみ(5/4)
https://www.nikkei.com/article/DGXZQOUE187DP0Y4A410C2000000/

データ窃取の有無は断定できず…X線画像や氏名など622人分の個人情報に不正アクセス攻撃　県が調査結果発表(5/4)
https://www.saitama-np.co.jp/articles/78841/postDetail

北朝鮮のハッカーが韓国の防衛請負業者10社に何か月もハッキングしていたことが判明(5/4)
https://gigazine.net/news/20240504-north-korea-hacking-korean-defense-contractors/

【2024年度以降未定】IT導入補助金でECサイトを構築する方法を徹底解説！申請方法と注意点もチェック！(5/4)
https://ecnomikata.com/blog/42860/

スマートテクノロジーの最前線-革新的なテックで未来を切り開く(5/5)
https://aippearnet.com/single-post/smart-tec/

医療現場でも生成ＡＩ活用、「診断」にばらつき…日本人のデータもっと学ばせる必要あり(5/4)
https://www.yomiuri.co.jp/medical/20240504-OYT1T50016/

ロシアからのサイバー攻撃非難 ＮＡＴＯ「協調し対応」(5/4)
https://www.oita-press.co.jp/1002000000/2024/05/04/NP2024050401000160
https://www.47news.jp/10876745.html

「Web3.0 - 分散型テクノロジーの未来」Gavin Wood（ギャビン・ウッド）氏講演レポート(5/4)
https://coinpost.jp/?p=511400

米国「ロシア、３月だけで北朝鮮に精製油１６万バレル送った…安保理決議違反」(5/4)
https://japanese.joins.com/JArticle/318246?servcode=A00&sectcode=A00

ネイバー「ＬＩＮＥへの支配力を弱めろという日本の要求は異例」(5/4)
https://japan.hani.co.kr/arti/economy/49916.html
https://japan.hani.co.kr/arti/PRINT/49916.html

［社説］「ＬＩＮＥ問題」度を超えた日本、尹政権の対日「低姿勢外交」原因ではないか(5/4)
https://japan.hani.co.kr/arti/opinion/49920.html
https://japan.hani.co.kr/arti/PRINT/49920.html

「事業戦略に基づき判断」　総務省指導にネイバー(5/3)
https://www.chunichi.co.jp/article/893722?rct=economics

地元愛東京でつながる　ＳＮＳ県人会　熱高じ起業(5/4)
https://www.yomiuri.co.jp/local/tokyo23/feature/CO074628/20240503-OYTAT50035/
スタートアップで学ぶIssueの取り組み方

# はじめに
スタートアップ(自社開発サービス)での開発風景を記事にしたものです。
※これが正解というものではありません。


# 目次
- [Issueの取り方](#issueの取り方)
- [いいIssue](#いいissue)
- [いいプルリク](#いいプルリク)

## Issueの取り方
Issueは重要度が高いものをとることになります。
重要度において顧客満足度を上げるものが最重要になります。
そのIssueをやることで顧客が満足してくれる->ユーザーの定着、増加を促す->金になる
時間とはお金です。その時間をどのように使うかを考えた時にサービスがより儲かることを考えてIssueに取り組まねばならないです。
ユーザーが求めていない機能追加よりも小さなバグを治すだけでユーザーは喜ぶということが往々にしてあるのでもし自分がユーザーだったらを考えて重要度を判断する必要がある。
大体は上長やリーダーに任されたIssueをやれば問題ないが自身でIssueを立ててやる場合は一度他の人に重要度を客観的に見てもらってアサインする

## いいIssue
### テンプレ
その1(機能追加ver)
```
## 概要
<!-- 例：メールアドレスログイン機能を作成 -->

## 目的
<!-- 例：システムにメールアドレスでもログインできるようにするため -->

## やること
<!-- 例：
- デザイン追加
- メールアドレスのログイン機能実装 -->
```
その2(バグ対応ver)
```
## ⚙ 発生している問題・現象

## 🔨 期待する挙動

## 🖥 再現手段

## 📸 スクリーンショット

```

- 概要がざっくりしすぎてあとから見返したり他の人に初見でわからないような記述の仕方は避ける
- 複雑なIssueにアサインするときはこの方向性であっていますかと確認を取るとよい
=>最初の方向性やIssueの思惑を勘違いするとその時点で差し戻しが確定する


## いいプルリク

### テンプレ
```
## 🖇 関連Issue

<!-- GitHub Issueのリンク -->

##  🎂 やったこと

## ⛔ やってないこと

## 💡 確認したこと

## 🏃‍♂️ その他

```

### レビュワーに負担をかけない
- テーブル形式で「やったこと」に画像を載せてぱっと見でどんな変更があったかわかるようにする

| 変更前 | 変更後 |
| ----- | ----- |
| 画像1 | 画像2 |

- Issueと関係ないところはコードを変更しない
=>変更する際は事前に変えてもよいか上長などレビュワーに了解を取る
ついここもリファクタリングできるからしてしまおうで変更ファイル数が大量になりレビューが大変になって最悪差し戻しになる可能性もあるので事前に確認を取る
変更箇所の大量増加が見込まれる場合は別でIssueを立てる
- 変更処理で何かファイルを追加したり関数を追加する際にどんな目的で変えたかを書いておくとよい

※レビュワーの時間を取らないのも大事だがIssueが進まないほうが問題なので100%完成していないくても適宜進捗報告や実装に詰まった時は聞こう

# おわりに
会社というのは基本的に営利企業であって限られた資源(時間、資金、人材)の中でより多く稼ぐことが目的になります。夢だけ追いかけてあれやりたいでビジネスを無視すればサ終(スタートアップだと破産か倒産)するのがオチなのでそのあたりを理解して開発しよう(自身への戒め)

## まとめ
- ビジネス視点を持ってIssueに取り組もう
- レビュワーの時間を取らない(負担をかけない)
Chromaで埋め込みを体感してみる

## 最初に

埋め込み(Embedding)はいい実装がモジュール化されているということを認識しているのですが、基本的なことを理解するためにChromaのAPIを触ってみました。  
この記事はその過程をメモしたものです。  

## Chromaとは

Chromaはオープンソースのベクトルデータベースです。  
内部的にはRedisを使っているそうです。  

https://www.trychroma.com/

## Python環境の構築

以下はAnaconda環境での構築を想定しています。
ただし、```conda```だと新しいライブラリが使えないことがあるので、```pip```でパッケージを導入しています。  

```sh
conda create -n embtest python=3.8
conda activate embtest
pip install chromadb streamlit
```

## Pythonプログラムの実装

ハードコーディングしたドキュメントをベクトルデータベースに格納して、その後に検索するプログラムを作成します。  

```py:embed_basic.py
import chromadb
import streamlit as st

# ChromeDBのクライアントを取得する
chroma_client = chromadb.Client()

# コレクションを作成する。既にある場合はそれを参照する
collection = chroma_client.get_or_create_collection(name="test_collection")

# まずベクトルデータベースを構築する
st.markdown("## 構築")

# コレクションにドキュメントを追加する。デフォルトの埋め込みモデル(all-MiniLM-L6-v2)を使う
# 初回は埋め込みモデルをキャッシュディレクトリにダウンロードするため時間がかかる
collection.add(
    documents=[
        "Opus One Winery is a winery in Oakville, California, United States. The wine was called napamedoc until 1982 when it was named Opus One. The winery was founded as a joint venture between Baron Philippe de Rothschild of Château Mouton Rothschild and Robert Mondavi to create a single Bordeaux style blend based upon Napa Valley Cabernet Sauvignon.",
        "Dominio de Pingus is a Spanish winery located in Quintanilla de Onésimo in the Province of Valladolid with vineyards in La Horra area of the Ribera del Duero region. The estate's flagship wine, Pingus, is considered a \"cult wine\", sold at extremely high prices while remaining very inaccessible, and commands an average price of $811 per bottle.",
        "Cooper Mountain Vineyards is an American winery located in Beaverton, Oregon, United States. Started in 1978, the certified organic wine maker produces Pinot noir, Pinot gris, Chardonnay, and Pinot blanc. Located in the Portland metropolitan area, the vineyard is sited on the western slopes of Cooper Mountain, an extinct volcano."],
    metadatas=[
        {"source": "Wikipedia"},
        {"source": "Wikipedia"},
        {"source": "Wikipedia"}],
    ids=["id1", "id2", "id3"]
)

# コレクションの中身を確認する
head = collection.peek()
st.write(head)
count = collection.count()
st.write(f"count: {count}")

# ベクトルデータベースから検索する
st.markdown("## 検索")
query_text = st.text_input("検索文字列", value="What is Opus One?")
st.write(f"検索文字列: {query_text}")

# コレクションから検索する(＝最近傍探索する)
# デフォルトの埋め込みモデルでquery_textsをベクトルに変換してくれる
result = collection.query(
    query_texts=[query_text],
    n_results=1
)
st.write(result)
```

このプログラムを```streamlit run embed_basic.py```で起動してみると、正しく検索できてそうです。  

![embed_basic](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/ccef7596-3d14-1bce-cf06-08557373b91a.png)


なお、初回実行時は埋め込みモデルをダウンロードするために時間がかかります。  
ターミナルに以下のような表示が出てきます。  

> .cache\chroma\onnx_models\all-MiniLM-L6-v2\onnx.tar.gz: 100%|██████████████████████████████████| 79.3M/79.3M [01:12<00:00, 1.15MiB/s]

また、稀に```ValueError: Could not connect to tenant default_tenant```というエラーが発生することがあります。  
これはChromaが起動中で正しく接続できていないようなので、リロードすると治ります。  

## 補足

ドキュメントとして日本語を入力する場合は日本語に対応した埋め込みモデルが必要になります。  
デフォルトの埋め込みモデルのままで実際に試してみると、エラーにはならないのですが、検索文字列と内容が似ていないドキュメントが検索結果に出てしまいます。
VSCodeVimで末尾にセミコロンをいれるショートカットを作りたい！

# セミコロン 末尾に打つの 面倒くさい （五七五）
`C++`や`Java`を書くとき，  セミコロンいれるの面倒くさいですよね．今回はVSCodeの拡張機能のVimで簡単に末尾にセミコロンをいれるショートカットをキーバインディングを使って設定してみました．


以下はMacでの設定です．その他のOSは適宜キーなどを読み替えてください．

# 手順
## どのキーを割り当てるか決める
* `Shift` + `Enter`
* `Ctrl` + `Enter`
* `Ctrl` + `;`
など．

## setting.jsonに記述
`keybindings.json`を開き，設定を追加します．
<details><summary><font color="red">開き方</font></summary>

1. 左下の設定マークをクリックする
1. キーボードショートカット（Keyboard Shortcuts）をクリックする．
1. 右上の紙がクルッと回っているようなアイコンをクリックする．

</details>

### `Shift` + `Enter`の場合
```jsonc:keybindings.json
　// （上に続く）

{
  "key": "shift+enter",
  "command": "vim.remap",
  "when": "inputFocus && vim.mode == 'Normal'",
  "args": {
    "after": ["A", ";", "<Esc>"]
  }
},
{
  "key": "shift+enter",
  "command": "vim.remap",
  "when": "inputFocus && vim.mode == 'Insert'",
  "args": {
    "after": ["<Esc>", "A", ";", "<Esc>"]
  }
},

// （下に続く）
```

### `Ctrl` + `Enter`の場合
```jsonc:keybindings.json
　// （上に続く）

{
  "key": "ctrl+enter",
  "command": "vim.remap",
  "when": "inputFocus && vim.mode == 'Normal'",
  "args": {
    "after": ["A", ";", "<Esc>"]
  }
},
{
  "key": "ctrl+enter",
  "command": "vim.remap",
  "when": "inputFocus && vim.mode == 'Insert'",
  "args": {
    "after": ["<Esc>", "A", ";", "<Esc>"]
  }
},

// （下に続く）
```

### `Ctrl` + `;`の場合
```jsonc:keybindings.json
　// （上に続く）

{
  "key": "ctrl+;",
  "command": "vim.remap",
  "when": "inputFocus && vim.mode == 'Normal'",
  "args": {
    "after": ["A", ";", "<Esc>"]
  }
},
{
  "key": "ctrl+;",
  "command": "vim.remap",
  "when": "inputFocus && vim.mode == 'Insert'",
  "args": {
    "after": ["<Esc>", "A", ";", "<Esc>"]
  }
},

// （下に続く）
```

## その他のカスタマイズ
### セミコロン挿入後に改行を加えてノーマルモードに移動したい場合
`"args"`内`"after"`のリストに`"<Enter>"`を追加．
### セミコロン挿入後に改行+インサートモードに移動したい場合
`"args"`内`"after"`のリストに`"o"`を追加．
### colonizeとの競合を防ぐ
以下を追加してください（`Shift`+`Enter`をcolonizeのキーとして設定している場合）．
```jsonc:keybindings.json
{
    "key": "shift+enter",
    "when": "!vim.active",
    "command": "colonize.endline"
}
```

# 最後に
使いやすいようにカスタマイズしてみてください．
UEのポストプロセスで、過去にUnityで作ったImageEffectを再現した　その１

2024年からUEを勉強し始めているのですが、どうにもモチベーションが高まらない。
・・・という事で、先ずは自分が過去にUnityで作ったImageEffectをUE上で再現する事でちょっとずつ慣れていけるように試してみました。

# モザイク

Unity

https://qiita.com/ScreenPocket/items/c311e22e250df7451fab

UE

https://x.com/ScreenPocket/status/1786796030773879012

# モノクロ（スクリーン合成）

Unity

https://qiita.com/ScreenPocket/items/4e33b8f4a2925f109e97

https://qiita.com/ScreenPocket/items/e739afb03bc0a6230dae

UE

https://x.com/ScreenPocket/status/1786796851079036975

# TVノイズ

Unity

https://qiita.com/ScreenPocket/items/c530dc8527076878a590

UE

https://x.com/ScreenPocket/status/1786810605271437689

# Posterization

Unity

https://qiita.com/ScreenPocket/items/1e8247e272d6e120bc21

UE

https://x.com/ScreenPocket/status/1786812661575176563

# GameBoy風

Unity

https://qiita.com/ScreenPocket/items/ad1a2ea37ea7ba760c27

UE

https://x.com/ScreenPocket/status/1786815126915694891

# Vignette

Unity

https://qiita.com/ScreenPocket/items/34bdd47bbbb224588447

UE

https://x.com/ScreenPocket/status/1786823342848389180

# Binarization(2値化)

Unity

https://qiita.com/ScreenPocket/items/c9853a6fcfada8aa21d2

UE

https://x.com/ScreenPocket/status/1787109954962530625

# RGB分解

Unity

https://qiita.com/ScreenPocket/items/307f796e100d81935b48

UE

https://x.com/ScreenPocket/status/1787118834966749635

# 終わりに

長くなったので、先ずはここまで。
作業中に気になった部分は別記事にまとめ中なので、項目が増えてきたら別途公開するかと思います。

ノードベース好きじゃないので、コーディングしたい～・・・
レビュー分析AI (ReviewAI) に新機能：観点の詳細を確認する機能を実装しました。

# はじめに
みなさま、GWは楽しんでますか？
旅行や観光、ついでに温泉に入った人も多いのではないでしょうか？
このGWで弊社リテジーリンクでは、レビュー分析AIサービス・ReviewAI (レビューアイ) に
観点の詳細を確認する機能を実装しましたので、ご紹介します。

今回はGWということで、草津温泉のつつじ亭についての
食べログのレビューを分析させていただきます。

## つつじ亭

つつじ亭は、草津温泉の料亭旅館です。
[食べログ](https://tabelog.com/gunma/A1004/A100402/10007823/)

## ReviewAI (レビューアイ)

弊社 RetegyLink が開発中のレビュー分析 AI です。
https://reviewai.next-seed.work/
試作版を公開中で、現在は
- [食べログ](https://tabelog.com/)
- [じゃらん](https://www.jalan.net/)
のレビューを分析できます。

# レビュー分析

こちらが分析結果です。
全てのレビューを分析し、観点ごとに強みと改善点を可視化しています。
良い評価であれば青色・水色で、改善が望む評価であれば黄色・橙色で表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776808/440eddf5-6604-4949-ea4e-b1ed0532ce37.png)

この度、観点の詳細を確認する機能も追加しました。
レビューから文を抜き出して、観点ごとに整理しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776808/d8a1e6d5-7f49-1795-0631-18775275710f.png)

料亭旅館ということもあり、食べログのレビューでありながら
部屋・宿・湯・温泉という観点があるのは面白いですね。

旅行・部屋・宿・食事は良い評価が80%以上となっており、高い評価を得ているようです。

また、詳細画面を確認したところ、
湯畑から少し離れた落ち着いた雰囲気が評価されているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776808/e0348b87-4013-7e0f-9aab-2a77c8ccf286.png)

## ReviewAI (レビューアイ) の改善点

お店の名前の「つつじ亭」が「躑躅」と「亭」という2つの観点に分かれてしまっています。
これは今後の開発で修正していく予定です。

# おわりに

観点ごとの詳細を確認されたい方は、ぜひサイトにアクセスして確認してください！
レビュー分析AI の [ReviewAI](https://reviewai.next-seed.work/) は試作版を公開中です。
今回分析したつつじ亭の URL はこちらです。
```
https://tabelog.com/gunma/A1004/A100402/10007823/
```

今後どんどん使いやすくしていく予定ですので、
ぜひ皆様の ReviewAI に関するご意見を[アンケート](https://docs.google.com/forms/d/e/1FAIpQLSc-yVTDeqqMc9GqM93BvzaYWCB6wyToesYj_wl8bhwKgw8LqQ/viewform?usp=sf_link)で教えてくださると幸いです。
TypeScriptでちょっと本気の3Dアクションゲームを作る

# TypeScript+ThreeJSサンプル

以前、[ThreeJSで作ったゲームエンジンサンプル](https://qiita.com/teradonburi/items/785085c109cd55d92d32)をアップグレードし、
モダンなTypeScriptで作り直しました。

サンプルの中身自体はあまり変わっていませんが、メンテナンス性を上げるためTypeScriptに完全移植しました。
package runnerにはbunを使用し、
bundlerもwebpackからviteに移植し、
linter&formatterもbiomeに移植しました。

- ThreeJS
- ammojs
- typescript
- bun
- vite
- biome

Github: [ThreeJS+TypeScript](https://github.com/teradonburi/threejs-ts)
デモ：https://teradonburi.github.io/threejs-ts/
SQL Developerの最初にやる便利な設定

# SQL Developerの最初にやる便利な設定
SQL Developerを使用するときに、最初に実施すると便利な設定を紹介します。自分自身よく忘れるので備忘もかねて。
## 行番号の表示
コードエディターに行番号を常に表示する設定

ツール→プリファレンス→データベース→NLS
行番号の表示、にチェック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85051/a0200776-3c6a-aeba-889f-432ac91f5514.png)

## 日付書式に時間表示まで含める
DATE型の書式に時分秒まで含める

ツール→プリファレンス→コードエディタ→行の左余白
デフォルトは`RR-MM-DD`のため、`RR-MM-DD HH24:MI:SS`に変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85051/f6a59461-1bc9-d7a5-ed1d-bc67f5a4b69b.png)

## オブジェクトビューアウィンドウの自動固定

デフォルトではテーブルのタブを開いた後、また別のテーブルのタブを開こうとすると、最初に開いたタブは閉じてしまいます。それを閉じないようにする設定。

ツール→プリファレンス→データベース→オブジェクト・ビューア
オブジェクト・ビューア・ウィンドウの自動固定、にチェック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85051/738faa64-f3fb-b6e7-28e5-b14e8848df64.png)
TypeScriptを手軽に試したい

# 1. はじめに
* TypeScriptを手軽に試してみたい

# 2. 開発環境
* TS Playground

https://www.typescriptlang.org/

# 3. サンプルプログラム
```typescript
let myName:String = "Yoshiji Gates";
console.log("My Name is " + myName.length + "文字です");
```

# 4. 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/5e45ef84-281d-0412-42b8-aebc93651006.png)

# 5. 参考文献

https://typescriptbook.jp/how-to-use-typescript-playground
Flutter x Supabase でカスタムスキーマを作成したときの手順と `permission denied for schema` のエラー解消

# これなに
カスタムスキーマを作成した際に `permission denied for schema` というエラーが出たので、その解消方法をメモ。
ついでに Flutter で Supabase のカスタムスキーマに切り替えた時のおおよその手順もメモ。


# 実際に遭遇したエラー
`my_schema_test` というスキーマを作成して、スキーマ切り替えテストで debugPrint していたらこんな感じのエラーが出てきた。
のちにわかるものですが、権限設定が不足していたようです。
```zsh
PostgrestException(message: permission denied for schema my_schema_test, code: 42501, details: Unauthorized, hint: null)
```


# 参考ガイド
以下の公式ガイドに記載されている通り、権限付与をしてくださいとのことで、これが全てでした。
https://supabase.com/docs/guides/api/using-custom-schemas?queryGroups=language&language=curl
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819748/68b58620-612f-bc8e-2f6a-8d28a2effb68.png)


# カスタムスキーマ利用の全体の手順
### 1: スキーマ作成
GUI からスキーマを作成、かんたん。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819748/21d011f0-34b7-b1ad-6870-3eac15a9f2ff.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819748/8d696609-2cab-dc42-eaa1-71893d85f560.png)


### 2: 権限設定
前述の通りスキーマを作成したら権限付与
```sql
GRANT USAGE ON SCHEMA my_schema_test TO anon, authenticated, service_role;
GRANT ALL ON ALL TABLES IN SCHEMA my_schema_test TO anon, authenticated, service_role;
GRANT ALL ON ALL ROUTINES IN SCHEMA my_schema_test TO anon, authenticated, service_role;
GRANT ALL ON ALL SEQUENCES IN SCHEMA my_schema_test TO anon, authenticated, service_role;
ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA my_schema_test GRANT ALL ON TABLES TO anon, authenticated, service_role;
ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA my_schema_test GRANT ALL ON ROUTINES TO anon, authenticated, service_role;
ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA my_schema_test GRANT ALL ON SEQUENCES TO anon, authenticated, service_role;
```

### 3: コードでスキーマ指定
以下の通りスキーマを指定する。
```dart
  await Supabase.initialize(
    url: dotenv.env['SUPABASE_URL']!,
    anonKey: dotenv.env['SUPABASE_ANON_KEY']!,
    postgrestOptions: PostgrestClientOptions(schema: 'my_schema_test'), // ここを追記
  );
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819748/6253b406-6c5f-bc97-de4e-8522f2a39bd3.png)


# おわりに
日本語の情報は無かったので FlutterFlow とか Stackflow とか Github issue とか漁ってました。
だけど最終的に公式のガイド見つけたのでそれで解決しました、よかったよかった。
[Vue3]テトリスを作ろう(概要編)

# はじめに
 　Vue3の勉強としてある程度複雑なロジックを含むフロントエンドの実装をしてみたいと思いテトリスを作成しました。

　開発過程でクラスや、UI、処理内容などを整理するための簡単な設計からcomposition APIとクラスを使った状態管理や画面描画を実装したため、その時考えていた事を忘れないよう記事におこしていきたいと思います。

 https://github.com/naitoyuma7110/tetris

アプリURL

https://naitoyuma7110.github.io/tetris/

(~~バグみたいなテトリミノが出現しますが仕様です~~)

　今回の記事はREADMEに記載してある概要に補足を加えたものですが、次回以降は設計に対してどのようにコードを書いたか、難しかったり迷ったりした部分を重点的に記事にしていきたいと思います。

## 今回の内容
- [x] テトリスの簡単な設計をまとめる
- [x] テトリスの主なロジックを図を使ってまとめる

## 使用技術
- Vue3(Composition API, Typescript)
- Vite(モジュールバンドラ)
- Vuetify3(デザインFW)
- vue-router

## UI・外観
テトリスの機能を実装したページについて外観とパーツの名前をまとめました。
現状は特に捻りもなく普通のテトリスを作成しようと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601137/70fc41af-cbe1-b3eb-bec8-039e16bbbf12.png)

## アプリケーション構成

　クラスを使ってロジック部分の役割分担を行い、テトリスに関する複雑化しやすい処理はカプセル化してクラスに閉じて定義したいと思います。

　最終的にクラスはVueのコンポーネントでインスタンス化して、Vue側で各クラスメソッドを利用しユーザー操作を実現、クラスフィールドをリアクティブ化し描画に利用していきたいです。

Vueファイルにロジックの詳細を持たせず、難しい部分はクラスに定義したい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601137/35c546ca-ab58-d416-16c7-53911a66732d.png)


## クラス

全体図

![image](https://github.com/naitoyuma7110/tetris/assets/128150297/cb0bb880-e235-4c09-9c79-081d88e54293)

主な登場人物
- テトリミノ(クラス)
- テトリミノマネージャー(クラス)
- フィールド(クラス)
- プレイページ(Vueコンポーネント)
- テトリミノボックス(Vueコンポーネント)

各クラスやVueコンポーネントの役割については実装内容と合わせて後々記載したいと思います。

## テトリスの主ロジック

テトリスの中でメインの処理となり複雑化し易いもについて図を作成して整理しました。
詳細は記載しませんがこのようにテトリスを実装していこうという大枠になります。

- フィールドとテトリミノの描画、テトリミノの移動、回転

![image](https://github.com/naitoyuma7110/tetris/assets/128150297/9307f8de-8180-4a1d-a12d-ded0231d0030)

　テトリミノクラスは自分がフィールド上のどの位置にいるか、またタイルはどういった配置にあるかという情報を持たせ、これらの情報をフィールドクラスに渡しフィールド上へテトリミノを配置します。

 テトリミノの状態の変化(回転、移動)はテトリミノクラスのクラスフィールドを自身のクラスメソッドで更新する事により実装できるのですっきりすると考えました。

- 堆積したテトリミノをフィールドに保持する

![image](https://github.com/naitoyuma7110/tetris/assets/128150297/844ee910-66e0-4f85-bd98-4df1b513e59a)

　フィールドクラスは、堆積したテトリミノを保持する記録用のフィールドと、記録用フィールドに落下中のテトリミノを配置した描画用のフィールドの2つをインスタンス化して使用する事を考えました。
　描画用フィールドはVueコンポーネント内でリアクティブ化しテトリミノの状態が変化(回転、移動)に応じて画面上に再描画を行う実装を考えました。
 

- テトリミノの移動や回転時に壁や堆積タイルとの衝突を判定する

![image](https://github.com/naitoyuma7110/tetris/assets/128150297/356c639d-a746-4760-8c78-bb57896164ee)

　移動や回転を行った際、テトリミノが壁や堆積したテトリミノに衝突するかどうかの判定では、堆積したテトリミノ情報を持つ記録用フィールドに、描画予定のテトリミノ情報(フィールド上位置とタイル配置を持つ)を渡すことで、フィールド上に描画可能かを判定する事ができると考えました。

その他、下記のようなユースケースを実現するために各種クラスメソッドやクラスフィールドを定義しました。
- テトリミノ出現
- テトリミノストック
- 出現予定テトリミノ表示
- テトリミノ落下・堆積
- 列消滅
- ゲームオーバー
- 落下スピード操作

## まとめ
今回は簡単に概要のみまとめましたが次はコードベースで要点をまとめて記事にしたいです。
Ubuntuで同じLAN内のデバイスのIPアドレスを確認するメモ

# 背景
 開発ボードのMACアドレスはわかるが、IPアドレスがわからない時の解決方法を調べたのでメモとして記載します。
 
# 参考
結論としては以下のサイトで記載いただいている方法で解決しました。

https://www.koushinclub.com/blog/2875.html

# 確認手順
## 1. arp-scanのインストール
```
sudo apt-get install arp-scan
```
## 2. fping のインストール
```
sudp apt-get install fping
```

## 3. ローカルネットワーク内のIPアドレスを網羅的に接続確認
```
fping -g 192.168.1.0 192.168.1.255
```
192.168.1.XXX の部分はLAN内のIPアドレスによって変わります。例えば、UbuntuのIPアドレスが10.179.1.243 のようなアドレスの場合は10.179.1.XXXになります。

## 4. arp-scanを実行する
```
sudo arp-scan -I en0 -l
```
ここで、 en0 の部分は接続しているインタフェース名になります。インタフェース名はifconfig 等のコマンドで確認できます。
【Rails】モデルが特定のメソッドを呼び出せるか検証する方法

`respond_to?()`を使用すると引数に指定したメソッドが呼び出せるか検証できます。
呼び出せれば`true`を呼び出せなければ`false`を返却します。

```rb
モデル.respond_to?(メソッド名, include_private=false)
```

Userモデルがname属性を呼び出せるか検証するには以下のように記述します。

```rb
user.respond_to?(:name)
```

プライベートメソッドを呼び出せるか検証するには以下のようにします。

```rb
user.respond_to?(:private_name, true)
```
大規模言語モデル（LLM）の進化と社会への影響

## はじめに
このGWでプロンプトエンジニアリングについて軽く学びました。そのメモなり内容を記したいと思います。
また、今回はだいたいChatGPTに生成してもらってからある程度改良したものになります。

## 参考
本記事は下記のコースの内容を参考にしています。

https://www.udemy.com/course/prompt-llm/?couponCode=KEEPLEARNING

# 大規模言語モデル（LLM）モデルとは？
大規模言語モデル（LLM）は、文章を生成する人工知能技術です。これは自然言語を介して情報を処理し、次の言葉を予測して文章を作成します。例えば、検索エンジンや文章の自動生成などに用いられています。

## AIの普及
現在、AI技術は専門的な知識がなくても誰でも利用できるようになりました。
これを「AIの民主化」と呼びます。自然言語を使って簡単にAIに命令ができるようになることで、より多くの人がAIを活用することが可能になります。

## プロンプトエンジニアリング
プロンプトエンジニアリングとは、AIに対する命令文の作成方法を指します。
良いプロンプトはAIの性能を最大限に引き出します。
そのため、明確でシンプルな命令が重要です。

## ChatGPTの問題点
ChatGPTを含む多くの言語モデルは、以下のような問題点を持っています。
- **ハルシネーション**: 事実でない内容を生成することがあります。
- **専門性の高い質問への対応**: 法律や医療など特定の分野では正確な回答が難しいです。
- **プライバシーの懸念**: 個人情報が漏洩するリスクがあります。
- **コンテンツの粗製濫造**: 低品質なコンテンツが量産される可能性があります。

## ラッダイト運動と現代の影響
ラッダイト運動は、1810年代にイギリスで起こった機械破壊運動です。
この運動は、技術革新による雇用の変化への恐れから始まりました。
現代においても、AI技術の進化が同様の懸念を引き起こしています。
例えば、2023年にはハリウッド脚本家団体がAIによる仕事の奪取を恐れてストライキを行いました。
また、小売業界では自動化技術が進む中で、従業員の仕事がAIに置き換わることへの不安が広がっています。
このように、技術の進歩がもたらす経済的な変動に対する社会的な反応は、ラッダイト運動の現代版とも言える現象です。


このように、言語モデルは多くの便益を提供しつつも、社会的な課題を抱えています。これらの課題にどう対処するかが、今後のAI技術の発展において重要なポイントになるでしょう。

## 終わりに
ChatGPTをはじめとしたLLMはサブスク登録して使ってたりしますが問題点やラッダイト運動に関しての視野は持ち合わせていませんでした。
プライバシーへの配慮はしているとして、それ以外の部分に関しては考えていなかったのでそういった側面があることを認識しつつうまく付き合っていきたいと感じました。
NestJSのデコレータを表にまとめた

キャッチアップを進めていくにあたり、デコレータがどれだけあるのかが気になったので表でまとめてみました。

:::note info
範囲は公式ドキュメントのOVER VIEWになります。
:::

https://docs.nestjs.com/first-steps

# Pages：Controllers

| No | 名称 | 詳細 |
|----|--------------|------|
| 1  | `@Controller()` | ルートのエンドポイントをまとめたコントローラーを定義する。 |
| 2  | `@HttpCode` | HTTP ステータスコードを指定するためのデコレータ。 |
| 3  | `@Request()`, `@Req()` | Express リクエストオブジェクトへのアクセスを提供する。 |
| 4  | `@Response()`, `@Res()`* | Express レスポンスオブジェクトへのアクセスを提供する。 |
| 5  | `@Next()` | 次のミドルウェア関数への制御を渡す。 |
| 6  | `@Session()` | Express セッションオブジェクトへのアクセスを提供する。 |
| 7  | `@Param(key?)` | ルーティングされたパスパラメータの値にアクセスする。 |
| 8  | `@Body(key?)` | リクエストのボディパラメータの値にアクセスする。 |
| 9  | `@Query(key?)` | リクエストのクエリパラメータの値にアクセスする。 |
| 10 | `@Headers(name?)` | リクエストのヘッダーパラメータの値にアクセスする。 |
| 11 | `@Ip()` | クライアントの IP アドレスにアクセスする。 |
| 12 | `@HostParam()` | ホスト名パラメータの値にアクセスする。 |
| 13 | `@Get()`     | HTTP GET メソッドを処理するルートを定義する。 |
| 14 | `@Post()`    | HTTP POST メソッドを処理するルートを定義する。 |
| 15 | `@Put()`     | HTTP PUT メソッドを処理するルートを定義する。 |
| 16 | `@Delete()`  | HTTP DELETE メソッドを処理するルートを定義する。 |
| 17 | `@Patch()`   | HTTP PATCH メソッドを処理するルートを定義する。 |
| 18 | `@Options()` | HTTP OPTIONS メソッドを処理するルートを定義する。 |
| 19 | `@Head()`    | HTTP HEAD メソッドを処理するルートを定義する。 |
| 20 | `@All()`     | すべての HTTP メソッドを処理するルートを定義する。 |
| 21 | `@Header()` | レスポンスのヘッダーを設定する。 |
| 22 | `@Redirect()` | リクエストを別のURLにリダイレクトする。 |

# Pages：Providers
| No | 名称 | 詳細 |
|----|--------------|------|
| 1  | `@Injectable` | クラスがDI（Dependency Injection）可能であることを示す。 |
| 2  | `@UseFilters` | ルート処理中に例外をキャッチするフィルターを適用する。 |
| 3  | `@Optional()` | 依存関係の解決時にオプションの依存関係を定義する。 |

# Pages：Modules
| No | 名称 | 詳細 |
|----|--------------|------|
| 1  | `@Module()` | アプリケーションの機能をまとめたモジュールを定義する。 |
| 2  | `@Global` | グローバルスコープでモジュールやプロバイダーを定義する。 |

# Pages：Exception filters
| No | 名称 | 詳細 |
|----|--------------|------|
| 1  | `@Catch` | アプリケーション内で発生した例外をキャッチし、適切な処理を行うためのミドルウェアを定義する。 |

# Pages：Pipes
| No | 名称 | 詳細 |
|----|--------------|------|
| 1  | `@UsePipes` | リクエストデータのバリデーションや変換を行うためのパイプを適用する。 |

# Pages：Guards
| No | 名称 | 詳細 |
|----|--------------|------|
| 1  | `@UseGuards()` | ルートにガードを適用してアクセス制御を行う。 |
| 2  | `@SetMetadata()` | メタデータを設定する。 |
| 3  | `@Roles()` | ユーザーの役割を指定する。 |
| 4  | `matchRoles()` | ユーザーの役割を検証する。 |

# Pages：Interceptors
| No | 名称 | 詳細 |
|----|--------------|------|
| 1  | `@UseInterceptors` | リクエストとレスポンスをインターセプトし、処理を追加する。 |

# さいごに

公式ドキュメントの項目でデコレータが追加されれば本記事を更新していきます。
詳細の内容で過不足あればコメントいただけると幸いです。
最後までご覧いただきありがとうございました！
tailwind使ってみてハマったこと

## はじめに
今回は表題の通りtailwindを使ってみてハマったところとその解決法について書いていきたいと思います。

## ハマったところ①　急にスタイルが当たらなくなる
原因と解決法 : コンポーネントのあるファイル/ディレクトリが`tailwind.config.ts`内の`content`に含まれていない

`./src/features`コンポーネントを作成した場合、追記する必要がある
```ts
const config: Config = {
  content: [
    "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/features/**/*.{js,ts,jsx,tsx,mdx}", // ←---追記!
  ],

~~~~~~~~~~~ 省略 ~~~~~~~~~~~~~~
```

## ハマったところ② `prettier-plugin-tailwindcss`が効かない
`className`内のユーティリティクラスを並び替えてくれる公式が提供しているprettierプラグインです。

原因と解決法 : `.prettierrc`にプラグインを追記していなかった
```json:.prettierrc
{
    "tabWidth": 4,
    "plugins": ["prettier-plugin-tailwindcss"] 
}
```

こうすることで問題なくフォーマッターが働きました。

## ハマったところ③ js変数をユーティリティクラスに入れても動かない
以下のようなコードです。

```tsx
const width = "30px";
<div className={`w-[${width}]`}></div>;
```

原因と解決策 : tailwindの仕様的に無理

tailwind公式より引用
>Tailwind がクラス名を抽出する方法の最も重要な意味は、ソース ファイル内に完全に切れていない文字列として存在するクラスのみが検索されるということです。
文字列補間を使用する場合、または部分クラス名を連結する場合、Tailwind はそれらを見つけられないため、対応する CSS を生成しません。

なので、`完全に切れていない文字列として存在するクラス`を変数に入れていればいける
例 : `const width = "w-[30px]"`

### おわりに
お読みいただきありがとうございました。

tailwindは初めて触りましたが、慣れるまでは大変そうですね...
クラス名を考えないでよかったり、html-cssをファイルを行き来して照合する手間が省けたりするのはとても良いと感じています。

また、ハマりポイントがあれば随時追記していこうと考えています。
Oracle Bronzeで正答率84%で合格するまでの備忘録

# この記事の概要
ORACLE MASTER Bronze DBA 2019を合格するまでにやったこと、反省点、勉強後の感想などをまとめます。これから受けようか迷っている人など、良かったら読んでください。

# 目次
- [受けた資格](#受けた資格)
- [勉強の効果](#勉強の効果)
  - [勉強前のスペック](#勉強前のスペック)
  - [勉強して身につかなかったこと](#勉強して身につかなかったこと)
  - [勉強方法](#勉強方法)
- [結果](#結果)
- [振り返り](#振り返り)

# 受けた資格
**Oracle Database 19c Certification（ORACLE MASTER Bronze DBA 2019）Bronze**

https://education.oracle.com/oracle-master-bronze-dba-2019-available-only-in-japan/trackp_DB19CBRNZ



# 勉強の効果
## 勉強前のスペック
- **DDL、DML**などのSQLはまあある程度書けるかな
- 業務で**Statspack**や**実行計画**を見ることがあるが、あまりよくわかっていない
- DBをどのように**導入**して、どのような**設定**をして、どのように**管理**しているのか知らない

## 勉強して身についたこと
- Oracleの**ツール群の名前や大雑把な役割**
- **用語**
- **DCL**
- どんな仕組みでデータの管理しているのか
- 大雑把なシステムの構成

## 勉強して身につかなかったこと
- **statspack**とか**実行計画**見ても**結局ほとんどわからない**
- 実践的な(**どんな問題が起きたらどう対処するのか**のような)内容は身につかない

## 勉強方法
以下のような手順で勉強を進めました。
1. [**オラクルマスター教科書 Bronze DBA Oracle Database Fundamentals**](https://www.amazon.co.jp/%E3%82%AA%E3%83%A9%E3%82%AF%E3%83%AB%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E6%95%99%E7%A7%91%E6%9B%B8-Bronze-Oracle-Database-Fundamentals-ebook/dp/B08DXH6YBJ/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=&sr=)を読む(電子版を使用)
1. 巻末問題を解くも**正答率58%(合格ライン65%)**、勘で当たったものも多い状態
1. 間違えた問題の分野を見直すが**なかなか覚えられている実感が得られず**
1. **暗記に特化した勉強**に切り替えるため、本をもう一周読み飛ばしながら用語を**自分流に図示して整理**
1. 同じ巻末問題を解く → 間違いを復習し、**88%、95%と正答率アップ**
1. [**公式の模擬試験(15問だけ)**](https://learn.oracle.com/ols/home/84763)を解く
1. 試験を受ける

### 電子版の書籍について
初めて**電子書籍(Kindle)で勉強しました**が、**メリット**と**デメリット**両方あるなあという印象です。
- **メリット**
  - 文字列の検索ができる
  - 拡大/縮小ができる
  - 物理的な場所をとらない
- **デメリット**
  - 書き込めない(メモの追加やマーカー引いたりはできる)
  - ちょいちょいアプリが落ちる(めちゃくちゃストレス)
  - 同じページなのにレイアウト変わったりするので、イメージとして記憶しにくい

### 「自分流に図示して整理」について
diagrams.netを使って、以下のような図を作りました。(**※自分の勉強用メモなので、間違いなどあるかと思います。あくまで「こういう勉強をした」という紹介として見てください。**)
![Oracle勉強用.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958265/e802de8c-5a22-59ba-f15e-69ecad390058.png)

本を前から順番に読んでいくと、**最初に出てきた概念**と**最後に出てきた概念**に**関係があっても気付きにくい**のですよね。
でも図としてどんどん書き足していくようにすると、「あ、これは前に出てきた○○と近いものなのかな」とか、「別の分野の話だな」みたいに、**それぞれの関係性がわかりやすくなりました。**
また、Oracleの試験では処理の順番などの知識が必要な問題も一定数ありますが、図のどこからどこに矢印が向かっていたかをぼんやり覚えているだけでも、結構思い出しやすい気がします。

### 模試について
「ちゃんとした模試1つしかやっていないの?」と思うかもしれませんが、**1つしかやっていないです**。ちょっとググってみたところ、**oracleの試験は基本的に過去問を公開していない**みたいなんですよね。
追加で本を買うのもなんだかなぁとお金をケチったので、1つの模試を周回しました。

### Oracleの環境を用意したかどうか
**用意していません。なので手元で触ってません。**「いや、用意しろよ!」という感じなのですが、これもちょっとググって、無料でやる方法が見つけられず、ケチって座学のみで勉強しました。
触れるなら絶対触った方がいいですが、手っ取り早く知識だけ入れてとりあえず合格したいなら、まあ無くてもなんとかなりますという感じですかね。

## 結果
タイトルにある通り、**84%で合格でした**。70問中59問正解ということになりますね。
![合格.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958265/323c99c6-b554-67cb-7f00-85fe902348fa.png)

「模試1個で受けているのでこんなもんか」という気持ちと、「11問も間違えてんのかぁ」という気持ち半々です。

## 振り返り
本の1周目を終えた時点では**正直ほとんどのことが理解できていない**状態でした。
やはり2周目で試した「**図にしてみる**」という方法が自分の中では比較的効率が良いと感じたので、少なくとも本などで知識をつけるときは今後1周目からやるようにしたいと思いました。

また、改めて調べなおすと、[**無償でoracleを使うこともできそう**](https://cosol.jp/techdb/2019/05/use_oracle_database_no_charge/)なので、もっと最初にちゃんと調べた方が良かったです。
JSで"name"という変数を宣言すると「'name' is deprecated.」と出る件を調査！

# はじめに
Udemyの”【最新ver対応済】モダンJavaScriptの基礎から始める挫折しないためのReact入門”の講座内にて、nameという変数を宣言したところ下記のWarningが出たので調べてみました！

# 内容

記入したコード
```
const name = "art";
function log_name(name){
  console.log(name);
}

log_name(name);
```

発生したWarning
```
'name' is deprecated.
```

# 原因
変数nameがグローバルコンテキストの"window"オブジェクトにてすでに存在しているため、衝突を避けるためにWarningを出している（by ChatGPT）
解決策としては「変数名をnameから変更する」のが一番効果的。
どうしてもnameを使用したい場合は、グローバルスコープではなく関数やブロックスコープなどの閉ざされた環境だけであれば問題ない、とのこと！
さすがGPT先生！

# 実験
実際にwindow.nameの値を出力してみて値が更新されているのか確認してみる。
```
console.log(window.name); // 初期状態の window.name を出力、通常は空文字列 "" が出力される
const name = "Hello World";
console.log(name);        // "Hello World" が出力される
console.log(window.name);
```
実行結果は下記のようになった。
```
1:""(空文字)
3:Hello World
4:""
```
どうやらブラウザ側で上書きされないようにブロックしているみたい。
ちなみに明示的に値を指定するとちゃんと変更されていた。
```
console.log(window.name); // update
const name = "Hello World";
console.log(name);        // Hello World
console.log(window.name); // update
window.name = "update";
console.log(window.name); // update
```
上記のようにwindow.nameの値を代入するより前の値も切り替わっていておもしろい！
window.nameという特別な変数だからなのかな？
もしわかる方がいらっしゃれば教えていただけると嬉しいです！

# おわりに
コードを書くのも、こういったなぜ？を調べていくのも楽しいですね！
LLM（大規模言語モデル）についての概要まとめ

## はじめに
近年話題になっているLLM(Large Language Model)について、言葉はよく聞くけど、概要や、何ができるのかなど、いまいち把握できていなかったので、自分なりにまとめました。

## 目次
| 項番 | 目次 |
|:----:|:-------------|
| 1 | [はじめに](#はじめに) |
| 2 | [LLMとは](#LLMとは) |
| 3 | [実装例](#実装例) |
| 4 | [おわりに](#おわりに) |
| 5 | [参考サイト](#参考サイト)|

### LLMとは

#### 概要
文章を扱うAIモデルで、「自然言語」でのやり取りを行う。
単語の予測する様に文章の作成が可能である。

#### 活用例
OpenAIの「ChatGPT」
Googleの「BERT」
など

### 実装例

transformerを用いた文章生成コードの例を挙げます。
文章の最後が変ですが、一応文がつながる回答にはなっています。
形態素解析・・・・「T5Tokenizer」
訓練済みモデル・・・「rinna」

```python
from transformers import T5Tokenizer, AutoModelForCausalLM

tokenizer = T5Tokenizer.from_pretrained("rinna/japanese-gpt2-medium")
model =　AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt2-medium")

first_sentence = "今日は雨。だから私は"  
x = tokenizer.encode(first_sentence, return_tensors="pt", add_special_tokens=False)  

y = model.generate(x, max_length=100)
generated_sentence = tokenizer.batch_decode(y, skip_special_tokens=True)
print(generated_sentence)
```
実行結果
```
['今日は雨。だから私は、いつもより少しだけ早めに起きて、洗濯物を干して、洗濯物を畳んで、洗濯物を畳んで、洗濯物を畳んで、洗濯物を畳んで、洗濯物を畳んで、洗濯物を畳んで、洗濯物を畳んで、洗濯物を畳んで、洗濯物を畳んで、洗濯物を畳んで、洗濯物を畳んで、洗濯物を畳んで、洗濯物を畳んで、洗濯物を畳んで、洗濯物を畳んで、洗濯物を']
```

### おわりに
LLMの概要と、実装例を簡単にまとめました。
Transformerなどの具体的な仕組みについてはまだ理解が進んでいないので、それらも後々理解していきたいと考えております。


### 参考サイト
・[rinna社のGPT-2大規模言語モデル](https://huggingface.co/rinna/japanese-gpt2-medium)
・[Udemy講座　大規模言語モデル（LLM）の仕組み入門](https://www.udemy.com/course/llm_mechanism/?utm_source=adwords&utm_medium=udemyads&utm_campaign=DSA_WebIndex_la.JA_cc.JP&campaigntype=Search&portfolio=Japan&language=JP&product=Course&test=&audience=DSA&topic=&priority=&utm_content=deal4584&utm_term=_._ag_89101504074_._ad_624699263400_._kw__._de_c_._dm__._pl__._ti_dsa-516533161365_._li_1009198_._pd__._&matchtype=&gad_source=1&gclid=CjwKCAjw3NyxBhBmEiwAyofDYarZq3XC5XOUyfwyqS2LfjvvCUo02lKIcrIRuU5KDwGPAZfLpv_ivBoCSYkQAvD_BwE)
RockyLinux 9.xとUbuntu22.xにOpenSSL 3.4.xをインストールする（ソースからビルド）

RockyLinux 9系では標準でOpenSSL 3系がインストールされていますが､あえて最新バージョンをソースからインストールしたい時に利用します。

## 環境

| ソフトウェア | バージョン |
|:-----------|------------:|
| OS  | rockyLinux 9.3 or Ubunt 22.04|
| OS  | OpenSSL 3.3.0 |

## 事前準備

予め以下のPerlパッケージをインストールしておく

```
sudo dnf install perl-FindBin perl-IPC-Cmd perl-Pod-Html
```

### インストール

```
cd /usr/local/src
wget https://www.openssl.org/source/openssl-3.4.0.tar.gz
tar xvzf openssl-3.4.0.tar.gz
cd openssl-3.4.0
./config -fPIC --shared --prefix=/usr/local/ssl
make -j 4
make install
```

### ライブラリのシンボリックリンクを作成
/usr/local/ssl/lib64に、ライブラリが配置されるため、一部のアプリケーションがライブラリを参照できないことがあるため、32ビットフォルダのシンボリックリンクを作成する

```
ln -s /usr/local/ssl/lib64 /usr/local/ssl/lib
```

以上で、/usr/local/sslに、OpenSSL3.4.xがインストールされます。
「--prefix」を付与しないと、/usr/local配下に直接インストールされるため、デフォルトインストールのOpenSSLとパスの設定によっては競合を起こすので部ディレクトリにインストールすることが望ましいと思います。
[Ubuntu] RedisからKeyDBへの移行 かんたん手順

Misskeyなどでよく使われているRedisを、よりパフォーマンスが高くマルチスレッドに対応したKeyDBへ移行する際の手順をまとめました。

【記事作成時の環境】
OS: Ubuntu Server 22.04.4 LTS
Redis: 6.2.14
KeyDB: 6.3.4

:::note warn
Redis 7.x から KeyDB 6.x に移行することはできません。
:::

# 1. KeyDBのインストール
KeyDB公式リポジトリを追加して、インストールします。

```shell-session
$ echo "deb https://download.keydb.dev/open-source-dist $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/keydb.list
$ sudo wget -O /etc/apt/trusted.gpg.d/keydb.gpg https://download.keydb.dev/open-source-dist/keyring.gpg
$ sudo apt update
$ sudo apt install keydb
```

# 2. Redisの完全シャットダウン
まず、Redis側でdump.rdbを確実に書き出してから停止させます。
dump.rdbはデフォルトの設定であれば /var/lib/redis に保存されます。次のステップで使用します。

```shell-session
$ redis-cli
127.0.0.1:6379> bgsave
Background saving started
127.0.0.1:6379> quit

$ sudo systemctl stop redis-server
```

# 3. dump.rdb のコピー
Redis互換のインメモリデータベースソフトウェアは、定期的もしくはサービス終了時[^1]にメモリ上のデータベースの内容をdump.rdbというファイルに保存しており、起動時は指定ディレクトリにあるそのファイルを読み込んでメモリ上に展開してサービスを再開します。
このdump.rdbをKeyDBのディレクトリに移します。

```shell-session
$ sudo cp /var/lib/redis/dump.rdb /var/lib/keydb/dump.rdb
```

所有者をkeydbに変更します。

```shell-session
$ sudo chown keydb:keydb /var/lib/keydb/dump.rdb
```

# 4. KeyDBの起動

最後にKeyDBを起動します。

```shell-session
$ sudo systemctl start keydb-server
```

問題なくデータベースが引き継がれており、キーが読み出せることも確認できたら作業は終了です。

# KeyDB から Redis に戻す場合
2 〜 4の手順においてRedisとKeyDBの立場を逆にして行います。

[^1]: 終了時にSIGTERMを送信している場合
【MongoDB】lookupで結合した先のフィールド名にエイリアスを設定したい

## 概要
MongoDBではAggregationのクエリでlookupを使用することで、他コレクションと結合できるのですが、O/Rマッパーを使用する時など取得時のフィールド名を調整したい場合があります。
今回はこういったケースの場合に、どうクエリを書けば良いかのメモ書きです。

## 前提
* 使用したMongoDBのバージョンは`7.0`です。

## 対応方針
[Mongodb creating alias in a query](https://stackoverflow.com/a/29603030)のstackoverflowの回答にある通り、project句の中で`lastName: "$author.last"`のような形でエイリアスが設定できます。結合先のコレクション名を参照し、これにエイリアスを設定すれば実現できそうです。

## 実装サンプル
以下の例では、Pythonのmongoengineを使用してクエリを実装しています。
`post_categories`コレクションの`create_user_account_id`と、`user_accounts`コレクションの`_id`を結合させます。
そして、`user_accounts`コレクションの`name`フィールドのエイリアスを`user_name`とします。

```python
def find_post_categories() -> List[PostCategoryQueryResult]:
    pipeline = [
        {
            "$lookup": {
                "from": "user_accounts",
                "localField": "create_user_account_id",
                "foreignField": "_id",
                "as": "user_accounts",
            }
        },
        {"$unwind": "$user_accounts"},
        {
            "$project": {
                "_id": 1,
                "name": 1,
                "user_name": "$user_accounts.name",
                "parent_category_id": 1,
                "memo": 1,
            }
        },
    ]

    # クエリ結果のdictをクラスのインスタンスに変換
    return list(
        map(
            lambda c_dict: PostCategoryQueryResult(**c_dict),
            list(PostCategory.objects().aggregate(pipeline)),
        )
    )
```
空間ペルソナのSharePlayに対応したアプリを2つリリースした話

4月3日頃に空間ペルソナ(Spatial Persona)が唐突にリリースされました。空間ペルソナをオンにするとペルソナが立体的に表示され、同じ空間に居るかのようなコミュニケーションが可能になります。そして空間ペルソナの状態でSharePlayをすると、同じ空間で同じアプリを操作できます。

https://twitter.com/raywongy/status/1775156667950252348

つい先日、その「空間的なSharePlay(Spatial SharePlay)」に対応したアプリを2つリリースしました。今回はそれらを紹介します。


# PersonaReversi / ペルソナリバーシ
シンプルなリバーシアプリです。ボードを中心に空間ペルソナで円状に囲む事ができます。

![スクリーンショット1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/c96e2879-c681-f6fb-ac83-4ac3ad93ef2a.jpeg)

![スクリーンショット2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/66d2d3b0-4d31-ce0b-d484-161e950a55fa.jpeg)

![スクリーンショット3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/de0a202e-3043-26e1-87cc-ff57c6122526.jpeg)

## 技術構成
- SwiftUI
- RealityKit
- GroupActivities

## モチベーション
- 空間的なSharePlayのポテンシャルを活かすジャンルの1つは「ボードゲーム」
- 世界で最も親しまれているボードゲームといえば「リバーシ」
- Apple Vision Pro発売直後の今はシンプルな設計のアプリに需要あり

## Reality Composer Proの活用
私は3Dモデリングの知識や経験が全くありませんが、visionOS向け開発ツールのReality Composer Proでリバーシの駒くらいなら作る事が出来ました。

![Reality Composer Proで駒を作る](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/4f941f73-70d8-06a7-174b-8f048b7492af.png)


## App Storeリンク
https://apps.apple.com/app/id6480587175

## ソースコードリンク
https://github.com/FlipByBlink/PersonaReversi


# PersonaChess / ペルソナチェス
シンプルなチェスアプリです。ボードを中心に空間ペルソナで円状に囲む事ができます。

![スクリーンショット1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/fe6651a8-2b3e-ba75-852a-3a53c8f94754.png)

![スクリーンショット2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/ee937de0-7b0c-b05e-6a3f-886cda67cc46.png)

![スクリーンショット3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/898f2774-21f2-623f-281d-7d2b53f6342e.png)


## 技術構成
- SwiftUI
- RealityKit
- GroupActivities

## モチベーション
- 空間的なSharePlayのポテンシャルを活かすジャンルの1つは「ボードゲーム」
- (リバーシ以外で)世界で最も親しまれているボードゲームといえば「チェス」
- Apple Vision Pro発売直後の今はシンプルな設計のアプリに需要あり

## フルスペースも活用したアプリ構成
リバーシアプリの方はボリュームだけのシンプルな構成ですが、このチェスアプリではボリュームだけでなくフルスペースでも遊べます。フルスペースではボードの高さを変更したり、チェス全体の大きさを変更したり出来ます。「ボードの高さを床まで下げて巨大な駒でチェスをする」といった遊び方も可能です。

![スクリーンショット4](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/7c9bfca6-26df-bf94-ecc8-d10598ac8306.jpeg)

## App Storeリンク
https://apps.apple.com/app/id6482994319

## ソースコードリンク
https://github.com/FlipByBlink/PersonaChess


# リンク
https://qiita.com/mjnfhbuvwebwfiejcnw/items/90d6e1b312d36cf085c4

https://qiita.com/mjnfhbuvwebwfiejcnw/items/63f88dd739537f35c7fa

https://qiita.com/mjnfhbuvwebwfiejcnw/items/96b64d2474b6886ddd88

https://zenn.dev/huiygfutfgvjknj/articles/5665e31e97284a

https://zenn.dev/huiygfutfgvjknj/articles/134014540063e9


# 余談
【Apple Vision Proを持っている方への相談】「空間的なSharePlay」に対応した自作のApple Vision Proアプリの動作確認や動画撮影等に協力してくれませんか？

実機が1台だけでは「空間的なSharePlay」を動かすことが出来ません。お互いにApple Vision Pro実機からペルソナでFaceTime通話している時だけ「空間的なSharePlay」を動かすことが出来ます。ただ、残念ながら私にはApple Vision Proを持っている知り合いがいないのです。もし協力してくださる方がいらっしゃれば、こちらのメールアドレス(waggle.slips.0t@icloud.com)に連絡ください！

![ペルソナの姿でお願いする私](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3564662/2b93774c-5361-8ede-ef47-5b355ea50683.jpeg)

==== 追記 2024/12/01 ====
12月現在も協力者募集中です！
==== 追記ここまで ====
WebViewでUserAgentを設定する

# はじめに
今回はWebView内の通信でUserAgentをカスタマイズする方法を紹介していきます
### 本文
`webViewClient.settings.userAgentString`で取得と上書きをすることができます。
そのため、下記のようにするとhogeのみが登録されてしまうので、上書きをしたくないのであれば、取得したものを追加で入れる必要があります
```kotlin
webViewClient.settings.userAgentString = "hoge"
```
### 最後に
今回はretrofitではなく、WebViewでの設定方法を紹介しました
どなたかのお役に立てればさいわいです
wsl2 ubuntuでssh経由だとnvidia-smiが実行できないとき

```.bashrc
export PATH=/usr/local/cuda-12.4/bin${PATH:+:${PATH}}
export PATH=/usr/lib/wsl/lib:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-12.4/lib64:${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH
```
のように、

```
export PATH=/usr/lib/wsl/lib:$PATH
export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH
```
```/usr/lib/wsl```が、ssh経由だとpathに入っていないので実行できないらしい。
備忘録 : PyTorchがGPU利用可能かを調べる

```
python -c "import torch; print(torch.__version__, torch.cuda.is_available())" 
```

で

```
2.3.0+cu121 True
```

みたいに、TrueになっていればOk

# For Mac

```
python3 -c "import torch; print(torch.__version__, torch.backends.mps.is_available())"
```