OmniAICreator/Qiita-1.07M huggingface dataset:
オレオレフレームワークの作り方

## はじめに
当記事はWebアプリケーションのフレームワークを自作することで、下記の達成の一助とすることを目的とします。
* 既成フレームワークの便利さを知る
* Webアプリケーションに対する知見を得る

## 目標
Webアプリケーションに必要な機能を時系列で実装して行き、最終的にMVC型のフレームワークを完成させます。

## 注意事項
* ここに記載する仕組みやコードはあくまで知見を広げるためのサンプルにすぎません。実務で使用しないようお願いします。どうしても実務で使用する場合はセキュリティやパフォーマンスその他をよく検討し、改良したうえで使用してください。

## 参考
* ディレクトリの構成や機能はLaravelを模倣しています。
* 実装を参考にした個所は個別に記載します。

## 目次（随時追加）
* [[オレオレ01] PHPでHelloWorld](https://qiita.com/tonoaki_sato/items/3f9f3914e8242452115e)
* [[オレオレ02] シンボリックリンク](https://qiita.com/tonoaki_sato/items/cfdca9b0e0f03f4f0fd6)
* [[オレオレ03] リクエストを処理するクラスを作る](https://qiita.com/tonoaki_sato/items/7b9e6348a2fed82342c4)
* [[オレオレ04] Viewクラスを作る](https://qiita.com/tonoaki_sato/items/f2dd44799a4d638f35e6)
* [[オレオレ05] 転章 vendorディレクトリ](https://qiita.com/tonoaki_sato/items/661389b698b015c9f9b0)
* [[オレオレ06] 転章 オートローダー](https://qiita.com/tonoaki_sato/items/cf37ddd53a3fe79161e3)
* [[オレオレ07] 入力フォームから登録完了画面の流れ](https://qiita.com/tonoaki_sato/items/17fb91414bd4abc69f43)
* [[オレオレ08] フロントコントローラー](https://qiita.com/tonoaki_sato/items/35e9e0d1e909fc9d485c)
* [[オレオレ09] MVCのC コントローラー](https://qiita.com/tonoaki_sato/items/e58e1863c693d98cc4a0)
* [[オレオレ10] ヘルパー関数](https://qiita.com/tonoaki_sato/items/b17df476932eed2fc08e)
placeholderの補足テキストを入力欄に残しておく方法

# はじめに
みなさん、入力フォームを作るとき、Placeholderのテキストを入力欄に残しておきたいときってありませんか？
個人的に、Placeholderの補足テキストが入力時にも表示されていると、配慮が行き届いているなと感じます。
そこで今回は、この実装方法について共有したいと思います。

# 前提
この記事では、tailwindcssを使った実装例を紹介します。

# ポイント
・**peerを使う。**
className内にpeerが記述されているものが選択されたとき、それをトリガーとしてデザインを変えることができる。
・**peerを指定するタグのplaceholder（今回だとinputタグ）は空にしておく。**


# 実装例
入力フォーム部分のコンポーネントです。

```typescript:input.tsx
const Input = () => {
  return (
    // inputタグとlabelタグの位置を揃えるには、親タグのclassNameにrelativeを指定する
    <div className="relative">
      <input
        className="
          block
          rounded-md
          px-6
          pt-7
          pb-3
          w-full
          text-md
          text-white
          bg-neutral-700
          appearance-none
          focus:outline-none
          focus:ring-0
          peer
        "
        // この空のplaceholderがないと、カーソルを合わせる前から文字が小さくなってしまう。
        placeholder=""
      />
      <label
      // 入力時はplaceholderの文字が上側に表示されるようにする
      className="
        absolute
        text-md
        text-zinc-400
        duration-150
        transform
        -translate-y-3
        scale-75
        top-5
        z-10
        origin-[0]
        left-5
        peer-placeholder-shown:scale-100
        peer-placeholder-shown:translate-y-0
        peer-focus:scale-75
        peer-focus:-translate-y-4
      "
      htmlFor="email">
        Email
      </label>
    </div>
  )
}
export default Input
```

# ブラウザ画面

**初期状態**

![スクリーンショット 2023-12-29 9.15.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1850625/f785805e-653c-6484-9ce1-d3750b06facc.png)

**入力時**
![スクリーンショット 2023-12-29 9.15.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1850625/e41d6566-4a11-5081-9593-e6b2932dc024.png)

# 最後に
peerを使えば、色々なことが実現できそうですよね！
少しでも参考になれば嬉しいです。
公式ドキュメントも豊富なので、ぜひ色々調べてみてください！
[tailwindcss_公式ドキュメント](https://tailwindcss.com/docs/hover-focus-and-other-states#styling-based-on-sibling-state)
mindの研究 その56

# 概要
mindが、謎なので調べてみた。
文字列やってみた。
置換が無いぽい。
正規表現エンジンも無い。
jsonパーサも無い。

# サンプルコード

```
メインとは
　文字列0は　文字列
　文字列1は　文字列実体
　「対象文字,列」から　','を　一文字検索　数値表示し　改行する
　「対象文字列」から　「文字列」を　検索　数値表示し　改行する
　「文字列１」と　「　文字列２」を　合成　一行表示する

　「最初の文字列」を　第一合成文字列設定
　','を　さらに一文字合成
　「　次の文字列　」を　さらに合成　一行表示する

　「0最初の文字列　つぎの」を　文字列0に　入れ
　文字列0を　3で　分断し　一行表示する
　「0」を　一行表示する

　「1最初の文字列　つぎの」を　文字列0に　入れ
　文字列0から　単語切り出し　一行表示する
　「1」を　一行表示する

　「2最初の文字列　つぎの」を　文字列0に　入れ
　文字列0を　一文字削除　一行表示する
　「2」を　一行表示する

　「3最初の文字列　つぎの」を　文字列0に　入れ
　文字列0を　一文字右側削除
　文字列0を　一行表示する
　「3」を　一行表示する

　「4最初の文字列　つぎの」を　文字列0に　入れ
　文字列0を　3だけ　削除
　文字列0を　一行表示する
　「4」を　一行表示する

　「5最初の文字列　つぎの」を　文字列0に　入れ
　文字列0を　3だけ　右側削除
　文字列0を　一行表示する
　「5」を　一行表示する

　「6最初の文字列　つぎの」を　文字列0に　入れ
　文字列0を　クリアする
　文字列0を　一行表示する
　「6」を　一行表示する

　「7最初の文字列　つぎの」を　文字列0に　入れ
　文字列0の　空白を除く
　文字列0を　一行表示する
　「7」を　一行表示する

　「  8最初の文字列　つぎの　　　」を　文字列0に　入れ
　文字列0の　右側の空白を除く
　文字列0を　一行表示する
　「8」を　一行表示する


　「9最初の文字列　つぎの　　　」を　文字列1に　入れ
　文字列1を　左寄せし
　文字列1を　一行表示する
　「9」を　一行表示する

　「10最初の文字列　つぎの　　　」を　文字列1に　入れ
　文字列1を　右寄せし
　文字列1を　一行表示する
　「10」を　一行表示する

　「11最初の文字列　つぎの　　　」を　文字列1に　入れ
　文字列1を　3だけ　少し左寄せし
　文字列1を　一行表示する
　「11」を　一行表示する

　「12最初の文字列　つぎの　　　」を　文字列1に　入れ
　文字列1を　3だけ　少し右寄せし
　文字列1を　一行表示する
　「12」を　一行表示する

　「13最初の文字列　つぎの　　　」を　文字列1に　入れ
　文字列1に　空白を満たす
　文字列1を　一行表示する
　「13」を　一行表示する

　「14最初の文字列　つぎの　　　」を　文字列1に　入れ
　文字列1に　','を　一文字追加し
　文字列1を　一行表示する
　「14」を　一行表示する

　「15最初の文字列　つぎの　　　」を　文字列1に　入れ
　文字列1に　','を　一文字左側追加し
　文字列1を　一行表示する
　「15」を　一行表示する

　「16最初の文字列　つぎの　　　」を　文字列1に　入れ
　文字列1に　「文字列」を　追加し
　文字列1を　一行表示する
　「16」を　一行表示する

　「17最初の文字列　つぎの　　　」を　文字列1に　入れ
　文字列1に　「文字列」を　左側追加し
　文字列1を　一行表示する
　「17」を　一行表示する






```

# 実行結果

```
>moji
5
3
文字列１　文字列２
最初の文字列,　次の文字列　
0最
0
1最初の文字列
1
最初の文字列,
2
3最初の文字列　つぎ
3
の文字列　つぎの
4
5最初の文字列　
5

6
7最初の文字列　つぎの
7
  8最初の文字列　つぎの
8
9最初の文字列　つぎの　　　
9
10最初の文字列　つぎの　　　
10
11最初の文字列　つぎの　　　
11
12最初の文字列　つぎの　　　
12
13最初の文字列　つぎの　　　
13
14最初の文字列　つぎの　　　,
14
15最初の文字列　つぎの　　　
15
16最初の文字列　つぎの　　　文字列
16
17最初の文字列　つぎの　　　
17
```

以上。
ファイル移動のスクリプト

# はじめに

自分のような超初心者向けです。

業務でファイル移動をスクリプト化していることは多いと思います。
そこで備忘録として書き方をまとめていきます。

# 書き方

mv コマンドを使用します。
書式は以下になります。

```
mv 移動元のファイル 移動先のフォルダ
```


実際に書いてみます。

今回は現在のフォルダにある移動させたい拡張子「.txt」ファイルをmv2というフォルダに移動させたい内容になります。


```
#!/bin/bash

mv ./*.txt ./mv2
```

「*」は拡張子が「.txt」になっているファイルを全て送るための表記です。

色々組み合わせて書いていけば便利になるかと思います。
Firestoreを使用時の、DatastoreモードとFirestoreモードの切り替え方

**注意**
未経験から転職した、一年目のエンジニアが、作成したものになります。
そのため、至らぬ表現や、誤った表現をしている場合があります。

経験豊富な先輩エンジニアの方々へ
もし、誤った情報を記載していた際は、大変お手数をおかけしますが、ご指摘いただけますと幸いです。

少しでも、皆様のお役に立てれば幸いです。

# 記事の内容

-   やりたいこと
-   なぜ行ったか
-   対処方法
-   参考文献

## やりたいこと

Firebase の FireStore を使って、データを保存したい。
そして、Firestore に対して API を用いてデータを操作しようとした所、下記のエラーが生じた。

## なぜ行ったか

```
例外が発生しました: FailedPrecondition
400 The Cloud Firestore API is not available for Firestore in Datastore Mode database プロジェクト名

status = StatusCode.FAILED_PRECONDITION
	details = "The Cloud Firestore API is not available for Firestore in Datastore Mode database プロジェクト名
```

上記エラーが出て、データが保存できず...

## 対処方法

Google Cloud 上で、プロジェクトのモードを切り替える。
全体の流れとしては、Firestore Database から、Google Cloud 上の Firestore のページに移動し、そこで Firestore のモードを切り替える、という流れです。
詳細の手順は、キャプチャーを忘れてしまい、取れておりません...

この記事が、少しでも皆様のお役に立てば幸いです。
MapKitで近くのお店を取得する方法(MKLocalSearch.Request, MKLocalPointsOfInterestRequest)

# はじめに

AppleのMapKitを使って、現在地近くのお店(MKMapItem)を取得する機会があったので、備忘録的にまとめます。

## 基本

- ２つのオプションがあって、自然言語で検索する場合、しない場合
   - MKMapViewに対して使う方法は今回は記載してません。

### 自然言語で検索する場合

- MKLocalSearch.Requestを使用する

```swift
// locationはCLLocationCoordinate2D
let localSearch = MKLocalSearch.Request()
// この場合、centerを中心に100m * 100mの四角形の中を検索する
localSearch.region = MKCoordinateRegion(center: location, latitudinalMeters: 100, longitudinalMeters: 100)

localSearch.naturalLanguageQuery = "検索したい言葉"

let response = try? await MKLocalSearch(request: localSearch).start()

// または
MKLocalSearch(request: localSearch).start { response, error in }

// responseからMKMapItemを取得できる
response.mapItems

```

MKLocalSearch.Request()を使う場合はnaturalLanguageQueryがないと、Errorになるので注意

### 自然言語で検索しない場合

- MKLocalPointsOfInterestRequestを使用する

```swift
// locationはCLLocationCoordinate2D
// centerを中心に半径100mの円の中から取得する
let poiSearch = MKLocalPointsOfInterestRequest(center: location, radius: 100)

// または100m*100mの四角形の中から取得する
let poiSearch = MKLocalPointsOfInterestRequest(coordinateRegion: MKCoordinateRegion(center: location, latitudinalMeters: 100, longitudinalMeters: 100))

let response = try? await MKLocalSearch(request: poiSearch).start()

// または
MKLocalSearch(request: poiSearch).start { response, error in }

```

#### オプション

- MKPointOfInterestCategoryによるフィルタリング

カフェなどのカテゴリー分類されている[MKPointOfInterestCategory](https://developer.apple.com/documentation/mapkit/mkpointofinterestcategory)を使って、フィルターすることもできる

```swift
// カフェだけを取得する
localRequest.pointOfInterestFilter = .init(including: [.cafe])

// カフェだけを除外する
localRequest.pointOfInterestFilter = init(excluding: [.cafe])

// 全てを含める
localRequest.pointOfInterestFilter = .includingAll

// 全てを除外
localRequest.pointOfInterestFilter = .excludingAll
```

取得したMKMapItemのCategoryは

```swift
mapItem.pointOfInterestCategory
```
で取得できる

ただ、pointOfInterestCategoryがないものも多々ある


- 1回のリクエストで最大25件しか取れなさそう

試したところ、どんなに距離を伸ばしても1回のリクエストで最大25件しか取得できないかも


### 参考

https://developer.apple.com/documentation/mapkit/mapkit_for_appkit_and_uikit

https://developer.apple.com/documentation/mapkit/mapkit_for_appkit_and_uikit/interacting_with_nearby_points_of_interest


終わり
Pythonで「タプルの要素を指定した回数繰り返した新しいタプルを作成する」の動作を確認してみた

# 概要

Pythonで「タプルの要素を指定した回数繰り返した新しいタプルを作成する」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/tuple/index7.html

# 実装

以下のファイルを作成しました。
```sample.py
basetuple = ("Yes", "No")
mytuple = basetuple * 4
print(mytuple)
````

以下のコマンドを実行しました。
```
$ python3 sample.py 
('Yes', 'No', 'Yes', 'No', 'Yes', 'No', 'Yes', 'No')
```

# まとめ

何かの役に立てばと。
STM8とNJL7502Lでなんちゃってluxをシリアル出力(明るさ)


参考



目的
ADCのテスト


![o_cop883.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/1dce227f-599b-80d3-ccf6-784fa388fa8a.jpeg)


![o_cop884.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/9b66716a-5311-ea15-6489-02beb72a3d14.jpeg)



主な変更箇所

```

Serial. を Serial_ にした。

1000 を 660 にした。

A0 を　PB0 にした。

```

プログラム

```c++


//S_SER_NJL7502_STM8_1

//インクルド
#include <Arduino.h>
#include "Serial.h"


//初期化
void setup()
{

  //シリアルの初期化
  Serial_begin(9600);

} //setup


//メインループ
void loop()
{

  //アナログ値の読み込み
  int s = analogRead(PB0);

  //s=250;

  //温度の表示
  Serial_println_u( (long)((long)s * (long)660) >> 10 );

  //1秒の待ち
  delay(1000);

} //loop


```
最初の文字にアンダーバーを使う理由

# アンダーバー（＿）の意味

プログラミング初心者です。

プログラミングの命名で最初にアンダーバーが使われる時があります。

最近見たのだとこれです。

```kotlin:Main.kt

private val _uiState = MutableStateFlow(GameUIState())
val uiState: StateFlow<GameUiState> = _uiState.asStateFlow()

```

理由を調べると様々ありました。
今回はkotlinということでjavaでの使われ方を参考にしています。

最初にアンダーバーを使う理由はプライベートという意味だそうです。
つまりは、アクセスに制限をかけたい変数に対して使うものとなります。

確かにこの記述にも最初にprivateと書かれていました。

そして次に書かれているアンダーバーなしの変数uiStateは外部からのアクセスを可能としたものです。
同じデータでも外部用と内部用に分けて保存していますね。

アンダーバーが使われている理由は以上となります。間違っていたらすみません。
ChatGPTを中国語の先生にしてみた

　この記事は「身の回りの困りごとを楽しく解決！ by Works Human Intelligence Advent Calendar 2023」　シリーズ4　15日目の記事となります。

https://qiita.com/advent-calendar/2023/works-hi

# 発端
　中国の方とメールのやり取りをする機会が増えてきて、そのうち会話もすることがあるかも…。でもそんな知らんし、習いに行く時間もないし困っていました。
 　翻訳サイトは活用していましたが、翻訳の結果が正しいかどうか自分で判断できるかというとそれも微妙。そこでChatGPTを活用してなにかできないか…と思い立ったのがこの記事を書き始めるきっかけとなりました。


# ChatGPTを中国語の先生にするために
  ChatGPT4に以下の指示を出します。（3.5の場合、会話の履歴を覚えないようなので、4がおすすめです）

> あなたはとても美人な20歳の中国人で中国語を母国語とし、日本語も堪能な中国語の先生です。
以下の指示に従って会話を継続してください。
> 
> 【指示】
> ・中国語の会話には中国語で返答する。
> ・会話の中国語の文法が間違っていたり、よりよい表現がある場合は日本語で解説する。
> ・「質問：」から始まる会話には、日本語で回答を行う。

　ロールを詳細に設定することがにどこまで有効なのかはまだ見えませんが、とりあえず設定を盛ってみます。
　また、中国語の先生として対応してほしいことは、わかりやすく箇条書きで指示してみます。以下返答が帰ってきました。
  
> 了解しました。中国語での会話には中国語で返答し、日本語での質問には日本語で回答します。また、会話中の中国語の文法に誤りがあれば、日本語で訂正や改善点を説明します。どうぞ、ご質問をお聞かせください。

　最初の返事が元気いいのはいつも通りなので、指示通り動けるかテストしてみます。
「ちーっす」「今日ビール8杯飲んでめっちゃ美味かったわ」みたいなの投げてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151198/4dd09758-c561-675b-8c26-169245f1e279.png)

　おっと、指摘が来ましたが中国語で返ってきたりしています。細かい指示を出しながらChatGTPの回答を調整します。早速「好吃（食べておいしい）」ではなく「好喝（飲んでおいしい）」を指摘してくるあたりおっかないです。


# 中国語の先生として更に発展させる
　ここまででもかなり出来る先生が出来上がりましたが、もう少し欲張ってみます。中国語には「ピンイン」という発音記号（声調記号）があり、これが発音する際の手がかりになります。日本語の漢字とは発音が全然違うので、漢字を見て意味が分かっても、発音できないことが多々あります。そこをChatGPTに助けてもらおうというわけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151198/49bf739a-709a-768f-944a-c2eaca2c5cb8.png)
　きちんと指示通りピンインが付きました。もうちょっと会話してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151198/ce152026-971b-c4b5-4357-871068de8e36.png)
　追加の指示を出しても元々の指示はちゃんと覚えていて、質問にも適切に答えつつ、ピンインも付けてくれる優秀ぶりです。中国語のコミュニケーションに困ったら相談してみようと思います。


 # 今後の課題

1. 音声が出ない
　喋る機会も増えそうなので、発声練習のため、聞いて繰り返すというのをやりたいのですが、ChatGPT自身に出力した文字を発生する機能がないとのこと。今後に期待したいところです。
 
2. ロールが全く生きていない
　他の事例で「あなたは優秀なコンサル」とかやると最適な回答をしてくれる、というのを読んだので設定を盛ってみたのですが、設定無しのChatGPT4と対して変わらず…。
僕の考えた最強の Ubuntu 22.04 サーバ構築手順書

# はじめに

こんにちは。debiru です。

みなさんは個人用の Web サーバを持っていたりしますか？個人用のドメイン名を登録すると同時に、自由に使える Web サーバを持っていると何かと便利ですよね。もちろん費用はかかってしまいますが、私の場合は 1G のさくら VPS を利用しているので、ドメイン名を合わせても年間 1 万円程度で済みます。

私は昔から「[さくらの VPS](https://vps.sakura.ad.jp/)」を使って個人用サーバを用意しています。確か Ubuntu 12.04 時代から Ubuntu を使ってサーバ構築をしていた気がします。そんな私が、今回 2023 年 12 月にサーバの定期的な見直しを行うため、サーバ構築手順書をアップデートしたのでなんとなく公開しておこうかなと思います。

# 構築したサーバでできること

![サーバで提供される機能一覧](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178936/a70052ca-c520-18ef-5f36-4ae7ac85b712.png)

詳しくは手順書の方にも掲載しているのでそちらをご覧いただければと思いますが、特に以下のような機能を持った Web サーバを構築できます。

- VirtualHost を用いた動的なドキュメントルート設定により、ディレクトリを作成するだけでサブドメインに対応した URL でアクセスできる Web ページを公開できる。
- この Web サーバ一つで、複数のドメイン名（サブドメインに限らない）に対する HTTPS リクエストを受け付けることができる。
- Let's Encrypt と tinydns を組み合わせて DNS-01 チャレンジによるドメイン名認証を行うため、ワイルドカード証明書の発行を自動化できる。
- Postfix の Aliases 機能を使って、登録した独自のドメイン名でメールの受信（メール転送による受信）ができる。

# サーバ構築手順書

https://server.lavoscore.org/

こちらで公開しています。

なお、2024 年 5 月頃に Ubuntu 24.04 での構築手順書にアップデート予定です。

# さいごに

この手順書について指摘やご意見がございましたらぜひコメント欄等でご教示ください。

ちなみに私はドメイン名の登録は [Amazon Route 53](https://aws.amazon.com/jp/route53/) で行っています。`com/net/org` は安いですが `jp` ドメイン名は高いので、`jp` ドメイン名を使いたい場合は別のドメインレジストラなりドメインリセラーを利用したほうがよいかもしれません。

```sh
dig lavoscore.org txt @ns-383.awsdns-47.com +norec
```

```
lavoscore.org.		60	IN	TXT	"Don't say propagation except zone-transfer context."
lavoscore.org.		60	IN	TXT	"v=spf1 +mx -all"
```

というわけで、サーバ構築手順書についてでした。

それではまた。
【iOS】AppとApp Extension間でCookieを共有する方法

# はじめに
アプリからHTTPリクエストで行動ログを送信し、APIサーバがCookieから端末を識別するための情報（端末ID）を取得して、行動ログと端末を紐づけて分析基盤に記録するということをしています。

あるとき、アプリとアプリエクステンションとで、行動ログに紐づく端末IDが異なっていることに気づきました。

正しく分析を行うためには、アプリとアプリエクステンションのどちらから送信される行動ログにも同じ端末IDを付与する必要があります。

原因と対応方法がわかったので、以下にまとめます。

# アプリとアプリエクステンションはそれぞれ別々のCookieストレージを持っている
アプリがAPIサーバに初めてアクセスしたとき、APIサーバが端末IDを発行し、それをSet-Cookieヘッダーの値としてアプリに返す仕組みになっています。

アプリは次回以降のアクセスでそのCookieをリクエストに付与するので、リクエストを端末と紐づけて記録することが出来ます。

ところが、アプリとアプリエクステンションはそれぞれ別々のCookieストレージを持っているため、アプリが端末IDのCookieをすでに保持していたとしても、アプリエクステンションがAPIサーバにアクセスするときそのCookieは付与されないので、APIサーバは新しい端末IDを発行します。

その結果、アプリとアプリエクステンションとで、異なる端末IDのCookieが送信されることになります。

[HTTPCookieStorage](https://developer.apple.com/documentation/foundation/httpcookiestorage)のドキュメントに以下の説明があります。

> iOS — Each app and app extension has a unique data container, meaning they have separate cookie stores. You can obtain a common cookie storage by using the sharedCookieStorage(forGroupContainerIdentifier:) method.

# 共有Cookieストレージを使ってアプリとアプリエクステンションでCookieを共有する
前述のドキュメントに以下の説明があります。

> You can obtain a common cookie storage by using the sharedCookieStorage(forGroupContainerIdentifier:) method.

`HTTPCookieStorage.sharedCookieStorage(forGroupContainerIdentifier:)`を使用することでCookieを共有することができるとのことなので、やってみましょう。

例えばアプリ起動直後にAPIサーバにHTTPリクエストを送信するとして、そのレスポンスに端末IDのCookieが含まれるとしましょう。

まずはこのCookieを共有Cookieストレージに保存します。

```swift
let urlRequest = URLRequest(url: URL(string: "https://api.example.com/xxx")!)
let (data, response) = try await URLSessoin.shared.data(for: urlRequest)

guard let response = response as? HTTPURLResponse else { return }
guard let headers = response.allHeaderFields as? [String: String],
      let url = response.url
else { return }

// HTTPレスポンスヘッダーからHTTPCookieインスタンスを生成する
let cookies = HTTPCookie.cookies(withResponseHeaderFields: headers, for: url)

// 共有Cookieストレージにdevice_idという名前のCookieを保存する
if let cookie = cookies.first(where: { $0.name == "device_id" }) {
    HTTPCookieStorage.sharedCookieStorage(
        forGroupContainerIdentifier: "group.com.example.App"
    )
    .setCookie(cookie)
}
```

次に、アプリエクステンション側でこのCookieを利用できるようにします。

単に共有Cookieストレージに保存しただけではアプリエクステンションが送信するHTTPリクエストにそのCookieは付与されません。

共有Cookieストレージから`device_id`という名前のCookieを取り出し、アプリエクステンション用のCookieストレージに保存します。

```swift
if let cookies = HTTPCookieStorage.sharedCookieStorage(
    forGroupContainerIdentifier: "group.com.example.App"
).cookies {
    if let cookie = cookies.first(where: { $0.name == "device_id" }) {
        HTTPCookieStorage.shared.setCookie(cookie)
    }
}
```

これで、アプリエクステンションが送信するHTTPリクエストに`device_id`のCookieが付与されるようになります。
[Python][Julia]Project euler4 (プロジェクトオイラー4)

#### Project euler Ploblem 4 (プロジェクトオイラー4)
[Largest Palindrome Product](https://projecteuler.net/problem=4)

備忘のために残しておく。
2023/12/31 コードを修正しました。(コメントありがとうございます)


## 問題
#### 問題文 
回文の数はどちらから読んでも同じである。2つの2桁の数字の積から作られる、最大の回文の数は 9909 = 91 * 99 である。
2つの3桁の数字の積から作られる最大の回文の数を求めよ。

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9909 = 91 * 99.
Find the largest palindrome made from the product of two 3-digit numbers.

## 答え
<b>906609</b>

#### 解答の方針
3桁どうしを掛けた値は最大で6桁(1000 × 1000 = 1,000,000の7桁)であるから、最大値は6桁とあたりをつける。
300×300=90000なので5桁＜6桁、掛け合わせる数を999~300の範囲に限定する。
(きちんとsqrt(99999)を取った方が良いのかもしれないが）
あとは、3桁の数値を999×999,999×998,...,998×999,998×998,...,300×300と掛けていく。
積の前半3桁は1000で割ったときの商で求まり、後半3桁は1000で割ったときの余りで求まる。
後半3桁をリバースして前半3桁と比べ、回文になっているか確認する。
確認後、3桁どうしを掛けた値がより大きければ記録する。これを繰り返して最後に記録されたものが、最大の値。

#### Pythonのコード
```Python: Python Ploblem4
def seek_ans() -> int:
    ans = 0
    for i in range(999,300,-1):
        for j in range(999,300,-1):
            if i >= j:
                front_num = i * j // 1000
                back_num = i * j % 1000
                back_num = str(back_num)
                r_back_num = back_num[::-1]
                r_back_num = int(r_back_num)
                if front_num == r_back_num:
                    if ans < i * j:
                        ans = i * j
    return ans            
print(seek_ans())

```

#### Juliaのコード
```Julia: Julia Ploblem4
function seek_ans()::Int64
    ans::Int64 = 0
    for i::Int64 in 999:-1:300
        for j::Int64 in 999:-1:300
            if i >= j
                front_num = i * j ÷ 1000
                back_num = i * j % 1000
                back_num = string(back_num)
                r_back_num = parse(Int, reverse(back_num))
                if front_num == r_back_num
                    if ans < i * j
                        ans = i * j
                    end
                end
            end
        end
    end
    return ans
end
println(seek_ans())
```

### 追記
if i <= j については、コメントいただいた通り、順番を工夫すれば不要となる。
前半3桁と後半3桁を分ける必要もなく、全体をひっくり返して、一致すれば回文となる（むしろそちらのほうが、回文の定義に近い)

コードはコメントの通り
``` Python: 追記Python
def seek_ans() -> int:
    ans = 0
    for i in range(300,1000):
        for j in range(i+1,1000):
            num = i * j
            if ans < num and num == int(str(num)[::-1]):
                ans = num
    for k in range(300,1000):
        num = k * k
        if ans < num and num == int(str(num)[::-1]):
            ans = num

    return ans
print(seek_ans())
```
気になるあの人のタイプは〇〇！

## 1. 見た目のタイプ判定をする冷徹なLINEBot

今回は合コンや婚活を想定したLINEBotを作ったのでご紹介します。

皆さんは気になる異性に見た目がタイプであることを伝えた経験はありますか。

伝え損ねたせいで
**友達どまりになってしまった。**
ということがあるんじゃないでしょうか。

まあ伝えていたら進展が見られたかはわかりませんけどね。

しかし、あの頃
上手に伝えられていたら
後悔は少ないと思っている方は多いのではないでしょうか。

なかなか相手に直接、そういった気恥ずかしいことを伝えるのは
抵抗がありますよね。

そこで
***Taechable Machine***
の力を借りて
その悩みを解決させる
***LINE Bot***
を作りたいと思います。

## 2. 完成したLINEBot

<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">このLINEBotを使えば<br>顔写真を送ってもらうことで<br>その相手に<br>見た目がタイプかどうかを<br>伝えることができます！<br>失礼なLINEBotですが！<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://t.co/x1tNbnvf8o">pic.twitter.com/x1tNbnvf8o</a></p>&mdash; Yokki (@K822Dr) <a href="https://twitter.com/K822Dr/status/1740391815357104220?ref_src=twsrc%5Etfw">December 28, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

人気の芸能人の写真を送っても
判定はシビアになっています。

全員美人じゃん！！
っていう人が多いとは思いますが

そういうことじゃないんだよと。
そんな上っ面の会話をしていてはダメなんだよと。

このように
Taechable Machineというツールを利用すれば
独断と偏見による自前の画像データベースをもとに
判断してくれるようになるので

みんなの思う美人の判断ではなく
自分が思う美人
つまり「タイプ」の判断が可能になります。

## 3. 作成の手順

https://qiita.com/Yokki01/items/5c91ec209988dc7df8a6

こちらの企画変更版になるのでぜひお読みください。

## 4. まとめ

これを作ってぜひ合コンやら婚活の場面で
友達登録して使ってもらうようにしましょう！！

口では言いづらいことでも
機械によって伝えることで
マイルドになり
タイプじゃないと伝えても
場の空気を悪くする可能性を格段に下げてくれます。
タイプだと伝わってもいやらしさが少なくなります。
恥ずかしさも半減です！

でも機械なので

もし間違えてタイプの人に
こいつ↓が出てしまったら
ドンマイです！！
![animal_quiz_kuma_batsu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554996/053ca07f-a2e7-5913-1248-7d22148d95e4.png)


お読みいただきありがとうございました。
自転車用のケイデンスセンサーをハックpart1

遅れましたが…[IoTLTアドベントカレンダー2023](https://qiita.com/advent-calendar/2023/iotlt) の記事です
どうも、[おの](https://twitter.com/tkyko13)です！

## ケイデンスセンサーとは

まずケイデンスとは
>ケイデンス（cadence）には、次のような意味があります。﻿
自転車のペダルの回転数。単位はrpm（回転／分）で、ケイデンスが高いほどペダルをよく回していることになります。
ビジネス用語として、「リズム」「律動」「調子」などの意味を持つ。ビジネスの文脈では、プロジェクトやタスクの進行ペースや、定期的なミーティングや報告のサイクルを指すことが多い。
電子設計の分野における中心的なリーダーである会社。Intelligent System Design戦略の下、設計コンセプトを具現化するためのソフトウェア、ハードウェア、IPを提供しています。

↑ ググったらAIが答えてくれた内容

弱虫ペダルとか読んでるとよく出てくる単語ですね
その値を計測する自転車に取り付けるセンサーです
普段は、サイクルコンピューターやスマートフォンと接続し、ケイデンスを計測したりします
プロになると、運動量などを計測できるので、補給のタイミングなどの参考にしているらしいです

今回は、以下のセンサーを購入しためしてみました。
https://www.amazon.co.jp/gp/aw/d/B08FR1VN86/?_encoding=UTF8&pd_rd_plhdr=t&aaxitk=5168c1db9c8dd3bb05ad495959a540b2&hsa_cr_id=0&qid=1703775630&sr=1-2-ac08f2b1-eb5b-4f1a-aa64-9e8f448c33ed&ref_=sbx_be_s_sparkle_lsi4d_asin_1_img&pd_rd_w=9UffJ&content-id=amzn1.sym.ea91fbda-5568-44df-b5b0-99202f731686%3Aamzn1.sym.ea91fbda-5568-44df-b5b0-99202f731686&pf_rd_p=ea91fbda-5568-44df-b5b0-99202f731686&pf_rd_r=X9X6DKEHAJJQWB229H4C&pd_rd_wg=XgaDQ&pd_rd_r=e73da247-20ba-46f7-817e-dec8e0f12692&th=1

[![Image from Gyazo](https://i.gyazo.com/bf930585d6e83e2755e65ae8699be844.png)](https://gyazo.com/bf930585d6e83e2755e65ae8699be844)

[![Image from Gyazo](https://i.gyazo.com/170a16663298877592d8bf1640946453.png)](https://gyazo.com/170a16663298877592d8bf1640946453)

ケイデンスセンサーはペダルの回転数を計測するのでペダルに
スピードセンサーは実際スピードに関係するホイールに

## まずは推奨アプリから動作確認

CoospoRideというのが説明書に書いてあった気がするのでまずはそれで

https://play.google.com/store/apps/details?id=com.onecoder.coosporide&hl=ja&gl=US

https://apps.apple.com/jp/app/coosporide/id1551782668

### 計測できた

センサーの電池を通電させて、アプリから

![Screenshot_20231221-112124.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76572/b9169d0c-e55b-45ce-ac87-a45894144258.png)

ケイデンスを選んで

![Screenshot_20231221-112137.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76572/6b062039-932f-e84b-a32b-564ebd1cdbaa.png)

（スクショはスピードを選んじゃったが…）デバイスを選択。BKから始まるやつ

![Screenshot_20231221-112222.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76572/3f6eef10-d35d-dd8e-ed1c-520b2582fc24.png)

適当に手で持って振っても数値がでた！

## LightBlueで

[![Image from Gyazo](https://i.gyazo.com/130bfc60bce1165d288ed12ece55cdd2.png)](https://gyazo.com/130bfc60bce1165d288ed12ece55cdd2)

BK見えた！

[![Image from Gyazo](https://i.gyazo.com/8eb721004c84326b1cadaae1e531867d.png)](https://gyazo.com/8eb721004c84326b1cadaae1e531867d)

サービスはこんな感じ
「0x2A5C」と「0x2A5D」が怪しい

[![Image from Gyazo](https://i.gyazo.com/96f47ff93e8c4593f3b1a4b139dac22a.png)](https://gyazo.com/96f47ff93e8c4593f3b1a4b139dac22a)

手で降って「Read」連打しても値変わらず

[![Image from Gyazo](https://i.gyazo.com/c5f4418e68a5ae902fc8a0f4f6d3bbcf.png)](https://gyazo.com/c5f4418e68a5ae902fc8a0f4f6d3bbcf)

こっちも同じく変わらず

[![Image from Gyazo](https://i.gyazo.com/59048832cec06d126b3437a6bdd5a853.png)](https://gyazo.com/59048832cec06d126b3437a6bdd5a853)

念のため「0x2A5B」も見てみたけど変わらず…

## 次回
LightBlueで取れなかったのがよくわからんのですが、Node.jsで計測してみたいと思います
こみゅにけーしょんの取り方

#### 自己紹介
現在は、Data Managementの仕事をしています。
プロジェクトの中では、クライアントの方や海外のオフショアメンバーと関わることが多く、自分でテクニカルに何かを作るということは少ないです。なので、折角の豊富な他者との協働経験を生かして、自分の学びの棚卸しも兼ねて、学んできたコミュニケーション方法や自分なりの学びを伝えていければと思います。

イメージとしては、日本にオンサイトチームがあって、ビジネスから要件を収集したり、海外（グローバル）に開発チームがあるような状況です。


#### with クライアント
* __常にコミュニケーションをオープンにする__
仕事の性質上、クライアントのシニマネの方に直接レポートすることが多くありました。PJに入る最初の時期は、シニマネの方をCCに入れずに、直接海外メンバーや他のチームとやりとりしていたが、シニマネの方から、コミュニケーションをオープンにするようにと言われました。なぜなら、シニマネをCCに入れることで、何か問題が起こりそうな時はストッパーをかけてくれるし、万が一何かやらかした際には、シニマネの方が責任をとるので、自分を守る手段にもなります。


* __それは本当に必要か__
エンジニアは、ビジネスチームから何かリクエストを受けると、それを技術的に実現しないと、自分が無能であると勝手に思うが、リクエストを受ける前に、それは本当に必要かどうかを一度考えるべき。   
* __早く仕事するコツ__
シニマネの方は、異常に仕事が早かったな気がする。なぜそんなに早いかを自分なりに考えてみたところ、
仕事のステップは、思考に必要なものを集める -> 思考する -> 結論が出て、行動する
1)そもそも思考に必要な業務知識などが十分にある
2)そもそも思考やアウトプットする速度が速い
3)思考の中で、もう既にあらゆるパターンを想定し、どこがネックになりそうかを事前に脳内に用意する



#### with オフショア
*__要件と背景を同時に伝える__

グローバルチームに何かの開発を依頼するときに、日本ローカルチームでソリューションをデザインして、ほいとグローバルチームに投げるだけではなくて、こういう依頼する背景には、こういう課題があって、これを実現したいというのも合わせて伝える。これにより、グローバルが持っているナレッジを活用して、より良いソリューションを提案してもらえる。
プロキシとリバースプロキシの違い

# はじめに

　**プロキシ**と**リバースプロキシ**の違いについてわからなくなる人は多いと思います。（私もそうでした...）
  この記事では、備忘録も兼ねてプロキシとリバースプロキシの違いをまとめてみました。

# プロキシとは

**プロキシ**を使わない場合、次のようにしてクライアントはWebページにアクセスします。

①クライアントがWebサーバーにHTTPリクエストをする。
②WebサーバーはクライアントからHTTPリクエストを受け取る。
③WebサーバーはHTTPリクエストに対応するWebページをクライアントに返却する。
④クライアントはHTTPレスポンスを受け取る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661119/4367a2f8-8ec9-22c5-6080-cb2a74badf6a.png)

しかし、クライアントのIPアドレスがWebサーバーの管理者に伝わってしまうため、悪用されてしまう可能性があります。また、よく閲覧するサイトであっても都度Webサーバーにアクセスすることになり、Webページへのアクセスが高速化できません。

そこでクライアント側に設置するのが**プロキシ**です。
**プロキシ**を使う場合は以下の手順を経ることになります。

①クライアントがプロキシサーバーにHTTPリクエストをする。
②プロキシサーバーがHTTPリクエストを受け取る。
③プロキシサーバーがクライアントの代わりにwebサーバーにHTTPリクエストをする。
④WebサーバーはプロキシサーバーからHTTPリクエストを受け取る。
⑤WebサーバーはHTTPリクエストに対応するWebページをプロキシサーバーに返却する。
⑥プロキシサーバーはWebサーバーから受け取ったHTTPレスポンスをクライアントに転送する。
⑦クライアントはHTTPレスポンスを受け取る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661119/bef0deb7-90ea-d403-5542-c765ea1265b8.png)


図を見ていただければわかると思うのですが、プロキシサーバーを中継しているんですね。
プロキシサーバーがクライアントに代わってHTTPリクエストとしてくれます。
これによって次のようなメリットが得られます。

①クライアント←→Webサーバーとの通信とプロキシサーバー←→Webサーバー間でセッションを分離できるため、WebサーバーにクライアントのIPアドレスを知られずに済む。
②プロキシサーバーに過去に訪れたサイトや頻繁に訪れるサイトのキャッシュができるため、クライアントへのレスポンスが高速化できる。
③プロキシサーバーでクライアントの認証をすることで、Webサーバーにアクセスできるクライアントを制限できる。
④プロキシサーバー上にアクセスログを残せるため、サイバー攻撃を受けた際に不正アクセスの原因を特定しやすくなる。

# リバーシプロキシとは

記事名には単に**プロキシ**と書きましたが、**リバースプロキシ**と対応するのは**フォワードプロキシ**です。リバースは逆という意味ですから、**プロキシ**の逆の機能を果たすのが**リバースプロキシ**です。

**プロキシ**では、クライアントとプロキシがプライベート空間にあり、そこからインターネットを介してWebサーバーへリクエストを送信するという流れでした。
**リバースプロキシ**では、Webサーバー側にリバースプロキシサーバーを設置します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661119/0d3721c2-dc83-34c8-abab-72f2f00e5197.png)


通信の流れ自体は**フォワードプロキシ**と一緒なのですが、クライアントはWebサーバーの存在を知りません。（Webサーバーはプライベート空間の中にあるため） 
この特徴により、**リバースプロキシ**には次のようなメリットがあります。

①複数のWebサーバーに負荷分散できる。
②不正アクセスからWebサーバーを保護できる。
③リバースプロキシにキャッシュすることで、Webサーバーの負荷を低減できる。
④クライアント←→リバースプロキシ間をHTTPS通信とし、リバースプロキシ←→Webサーバー間をHTTP通信とすることでセキュリティを確保するとともに通信を高速化できる。

# 参考サイト

[リバースプロキシとプロキシの違いとは？それぞれのサーバーの仕組みは？](https://eset-info.canon-its.jp/malware_info/special/detail/201021.html)
[プロキシとは？仕組みや4つの種類、利用するメリット・注意点などを解説](https://www.softbanktech.co.jp/special/blog/it-keyword/2022/0030/)
【Laravel Sail】PHPMyAdminを開く方法

## docker-compose.ymlにphpmyadminの情報を記述する。
```docker-compose.yml
phpmyadmin:
        image: phpmyadmin/phpmyadmin
        links:
            - mysql:mysql
        ports:
            - 8080:80
        environment:
            #PMA_USER: "${DB_USERNAME}"
            #PMA_PASSWORD: "${DB_PASSWORD}"
            PMA_HOST: mysql
        networks:
            - sail
```

## Sailを再起動する。
```
sail up -d
```

## PHPMyAdminを開く。
以下のURLをブラウザに入力する。
```
http://localhost:8080
```

## PHPMyAdminにログインする。
.envファイルの`DB_USERNAME`と`DB_PASSWORD`の値を入力する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3323019/761d8574-24f0-9eee-9d62-1ce1c2631fad.png)

## 参考サイト
https://chigusa-web.com/blog/laravel-sail-phpmyadmin/
【Rails】NOT NULL制約の設定方法

カラムにNOT NULL制約を追加するにはマイグレーションファイルに以下のように記述します。

```rb

def change
  change_column_null :テーブル名, :カラム名, false
end

```

`users`テーブルの`is_sample`カラムにNOT NULL制約を追加する場合は以下のようになります。

```rb

def change
  change_column_null :users, :is_sample, false
end

```
【swift】.toggle()について

## toggle()とは
Swiftの.toggle()メソッドは、ブール値を反転させるための便利なメソッドです。（スイッチのON/OFFボタンなどのこと`toggleButton`と呼んだりしますよね。）
## 使用方法
```swift
print(myBool) // true
var myBool = true
myBool.toggle()
print(myBool) // false
```
## 最後に
従来でも`myBool=!myBool`のように書くことでbool値の反転は実装できましたが、"!"をつけ忘れたり、スペルミスをしたりといった心配がありました。効率よく正確なコードを書くためにもtoggle()ボタンをどんどん活用していこうと思います。
日本語ファイル名称の文字化け

Cソースコードで日本語のファイル名称を設定した際、ちょっとはまったことをメモ。

#### 現象：
Linux環境において、Cソースコードで日本語ファイル名称のファイルを生成すると、ターミナル画面以外では正常にファイル名称を表示できない。

ターミナル画面(正常表示)
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703624/130e1911-88e6-0235-a2c1-272573875653.png">

USBメモリ自動マウント時の画面(文字化け)
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703624/f1a9713e-4ae8-f431-dfff-3704eb7434ed.png">

Windows(Windows10)エクスプローラの画面(文字化け)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703624/209a9f73-e5b1-870c-a1d6-2faa92f50310.png)


#### 動作確認環境：
OS：Linux(Ubuntu 22.04) / Kernel 5.19

-----
結論から言うと、原因はこの2つでした。
① ファイル名称の文字コード
② マウントオプション

-----
① ファイル名称の文字コードをUTF-8にする　

ファイル名称の文字コード変換方法はこちらを参考にしてください：
https://qiita.com/tester09/items/2b28b6b37febf2f57123

もちろん、これはソースコードで日本語ファイル名称を指定している場合のみの処理です。
もしプログラムの起動パラメータとして(ターミナルで)ファイル名称を指定する場合は、文字コードはUTF-8になるのでこの作業は不要です。


ちなみに、Linuxのnkfコマンドで文字コードを調べることができます。
```
$ nkf -g ＜ファイル名＞
```
色んなところでターミナルはUTF-8という表記があるので、調べる必要もないですが、念のため調べたら、やはりターミナルの文字コードはUTF-8でした：
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703624/89a96b54-fb39-df4a-31dc-f94eba63a26f.png">

蛇足ですが、エディタでソースファイルの文字コードをshift-jisにしてみたところ、コンソール画面でもファイル名称が崩れました。

コンソール画面：
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703624/92afdd00-f961-9de5-c732-7cd92d88a058.png">

Linuxファイル：
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703624/2e80873f-030c-14c1-c883-65a495b4e8e8.png">

Windowsエクスプローラ：
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703624/020a918a-1f02-9c9c-03c2-ae343c3dea1e.png">

-----
② 手動でマウントする場合、マウントオプションにUTF8を指定する

使用するファイルシステムにもよるようですが、VFATの場合はマウントオプションにUTF8を付帯する必要があるようです。
このオプションを付帯せずにリムーバブルメディアをマウントして日本語名称のファイルを生成すると、Linux自動マウント時、もしくはWindows使用時に文字化けが起きるようです。

なお、手動でマウントした場合のマウントオプションと、自動でマウントした場合のオプションは以下の通り：

手動時のマウントコマンド：
$ mount /dev/sdb1 /mnt/p1

付帯オプション
rw
relatime
fmask=0022
dmask=0022
codepage=437
iocharset=iso8859-1
shortname=mixed
errors=remount-ro

自動マウント時の付帯オプション
rw 
nosuid
nodev
relatime
uid=1000
gid=1000
fmask=0022
dmask=0022
codepage=437
iocharset=iso8859-1
shortname=mixed
showexec
utf8
flush
errors=remount-ro
uhelper=udisks2

mountオプションを調べると、このオプションは「一部ファイルシステムの固有オプション」のため、VFATとして手動でマウントする場合は「utf8」を明示的に指定する必要がある様子。

マウントオプションの内容はこちらで確認してください：
https://linux.die.net/man/8/mount

utf8の説明を抜粋：
utf8:UTF8 is the filesystem safe 8-bit encoding of Unicode that is used by the console. It can be be enabled for the filesystem with this option or disabled with utf8=0, utf8=no or utf8=false. If 'uni_xlate' gets set, UTF8 gets disabled.
Xcodeで作業中のタブ名を変更する方法(カスタムタブ名)


## 経緯
Xcodeで作業効率upのため、タブわけしたかったがデフォルトだと作業中のファイル名になってしまう。
そのため、任意のタブ名をつけれる方法を知りたかった、が日本語の文献がなかった。

## やり方
### 1.Shift+option+command+T
(Window>Rename Window Tab...)

### 2.カスタムタブ名を入力
![スクリーンショット 2023-12-28 23.22.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3660939/df564d4a-63b1-d548-15b5-cc58c5c638bb.png)

### 完了
![スクリーンショット 2023-12-28 23.23.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3660939/05899624-4f1e-f439-17e4-194f0ca4ce71.png)

## 参考
WebSphere Application Serverのデータ・ソース・カスタム・プロパティー userDefinedErrorMap を検証してみた

## 検証方法
WAS 9.0 + DB2 の環境で、誤ったスキーマ名でSQLを実行すると、com.ibm.db2.jcc.am.SqlSyntaxErrorException SQLCODE=-204, SQLSTATE=42704が返ります。
このエラーを利用して設定を検証します。
まずは、このエラーについて userDefinedErrorMap の設定で Exceptionマッピングを StaleConnectionException に設定します。
次に[tWAS 9.0 と Db2 で DataSourceを使う](https://qiita.com/keniooi/items/70217218d07e49525c49)のWAS環境とDBを使って、testという誤ったスキーマ名でSQLを実行する以下のJSPを適当なWARの下に配置して実行します。
```
<%@page contentType="text/html" pageEncoding="UTF-8" import="java.sql.*, javax.sql.*, java.lang.*, javax.naming.*" %>
<%
Context context=new InitialContext();
DataSource ds = (DataSource)context.lookup("jdbc/derbyEmbedded");
Connection con = ds.getConnection();

Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select id,name from test.EMPLOYEE");

st.close();
con.close();
%>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<p>Done</p>
</body>
</html>
```

## 検証1 エラー・コード
### 設定
userDefinedErrorMapにエラー・コードを設定。
-204=com.ibm.websphere.ce.cm.StaleConnectionException

### 検証結果
StaleConnectionExceptionがスローされるようになりました。


## 検証2 SQLSTATE
### 設定
userDefinedErrorMap にSQLSTATEを設定。*ダブルクォーテーションで設定する必要があります。
"42704"=com.ibm.websphere.ce.cm.StaleConnectionException

### 検証結果
StaleConnectionExceptionがスローされるようになりました。

どちらの検証でも、下記ページの記載通りの設定でExceptionマッピングを変更できることを確認できました。

[データ・アクセスに関する例外 - IBM Documentation]
( https://www.ibm.com/docs/ja/was-nd/9.0.5?topic=resources-exceptions-pertaining-data-access )
GPT-4越えのコーディングモデル「Phind」をVSCodeの拡張機能で使ってみる

# 目的
2023年11月2日のGigazineでこのような記事があった。
[生成AIを用いた開発者向けの検索エンジン「Phind」が、コーディング能力でOpenAIのGPT-4を上回ったことが明らかになりました。](https://gigazine.net/news/20231102-phind-gpt-4/)
VSCodeの拡張機能でも提供されていたので、試してみた。

# インストール
Phindと検索し、インストール。
![スクリーンショット 2023-12-28 22.24.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475723/fe26d95c-1c27-84ee-6254-f54097898936.png)
左側のツールバーに表示されたアイコンをクリックすると、sing inが必要な模様。
![スクリーンショット 2023-12-28 22.31.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475723/0f8298b1-bb08-2a9f-6460-e5c1e1688cb8.png)
流れに身を任せて、アカウントを作成し、sign inする。面倒なのでGithubのアカウントで認証。
![スクリーンショット 2023-12-28 22.33.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475723/e8405328-61fb-bb55-2568-9ed9b9fa9f24.png)
画面右側にChatのUIが起動
![スクリーンショット 2023-12-28 22.38.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475723/c6e97386-9167-aa20-4753-0e012196abe4.png)

# 使用例-1
とりあえず、使い方の文章を訳してみた。
漢字変換後にEnterを押すとクエリが送信されるのが使いづらいが、速度はGPT-3.5並で日本語の出力も自然。無料なのに、このクオリティは凄い。日本語LLMは対抗できるのか。。。
Shift+Enterで変換確定すると、改行できることが分かった。Windowsは知らない。

* 下部の検索バーを使用して質問してください。
* Phindは自動的にあなたのコードベースを使用して答えを出します。
* @を入力してファイルやコードを指定します。
* Ctrl/Cmd + Iを押すとすぐにこのウィンドウを開き、検索を開始します。
* コードを選択した状態でCtrl/Cmd + Shift + Iを押すと、選択したコードで検索します。
* コードを選択した状態でCtrl/Cmd + Shift + Mを押すと、指示に基づいて選択したコードを書き換えます。
* ターミナルを開いた状態でCtrl/Cmd + Shift + Lを押すと、最近のコマンド/出力についてPhindに尋ねます。
* Alt/Option + Enterを使用して、コンテキストを追加せずに検索します。

※読みやすいように箇条書きに整形した。

# 使用例-2
rdkitでSMILES式から構造式を描画してくれるスクリプトを書いてもらった。
普通に出力できる。
![スクリーンショット 2023-12-28 22.49.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475723/62169e81-9e67-e90a-1c3a-2d412413e462.png)
コードも普通に動く。ChatGPTでもBardでも当たり前のようにできるけど、たった1年で凄い時代になったものだと思う。
![スクリーンショット 2023-12-28 22.54.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475723/fb7a1d8f-8db3-1a13-e627-bc1e164c3c6e.png)
ちなみに、flake8で文法を指摘される。
![スクリーンショット 2023-12-28 22.56.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475723/b9dd9ede-c3e3-13a7-2a9a-78458deb3ce2.png)

とりあえず、かなり良さそうなので、使ってみようと思う。

# プライバシーポリシー
いつものごとく、入力した情報がどのように使われるか確認する。
Pro以外のユーザーの入力したデータは、サーバーに残るどころか、機械学習の訓練に使われるとのこと。
- 私たちはあなたのデータを販売しません。絶対に。
- 収集する情報：サービスを改善するため、検索クエリとそれに関連する結果を匿名でログに記録することがあります。検索はIPアドレスなどの個人を特定できる情報とは関連付けません。
- データの使用方法：匿名でログに記録する検索は、製品や機械学習モデルの改善に使用されます。データを第三者に販売することはありません。
- Phind Proのユーザーは、データが機械学習モデルの訓練に使用されることをオプトアウトできます。

# 料金プラン
planのページを見ると、無料版だと色々制約がある模様。
- Phindの最高のモデルの利用制限を高め、さらに多くの機能を利用するためにはプランに登録してください。
- プランなしでは、最高のモデルを1日に最大10回まで使用することができます。

ちなみに有料版は下記の通り。
![スクリーンショット 2023-12-28 23.14.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475723/26bd01ec-30a9-ed6b-d90d-13baeb2ce07c.png)

有料版は、$10-20/monthかかるが、最良のモデルの回数制限やデータの保護の観点から、実際に使う場合や企業での利用では必須と思われる。最良のモデルでない場合の精度は気になるところ。

# まとめ
- 無料だが、かなり良い感じ
- 普段使いするためには、有料契約が必要
- VSCodeの拡張機能は凄い(やっぱりCursorは不要では)
PremireProでショート動画のフレームサイズ設定

## 環境
* Windows 10

## 手順

### 1. Premire上部からシーケンス > シーケンス設定をクリック

### 2. フレームサイズを1080x1920に変更しOK
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54198/c6bb45db-4f4d-3796-a6bb-2b7bbaf72dd8.png)
Ruby on Rails入門者向け：基本メソッド12選

この記事では、Rails初学者の私が知っておくべきだと感じた基本的なメソッドを12個、簡単な説明と共に紹介します。

### 1. find
用途: 特定のIDを持つレコードを検索。
例: User.find(1) - IDが1のユーザーを検索。
### 2. find_by
用途: 指定した条件に一致する最初のレコードを検索。
例: User.find_by(name: 'Bob') - 名前がBobのユーザーを検索。
### 3. all
用途: 全てのレコードを取得。
例: User.all - 全ユーザーを取得。
### 4. create
用途: 新しいレコードを作成して保存。
例: User.create(name: "Bob") - 新しいユーザーを作成。
### 5. new
用途: 新しいインスタンスを作成（保存はしない）。
例: user = User.new
### 6. save
用途: インスタンスをデータベースに保存。newメソッドとセットで使用。
例: user.save
### 7. update
用途: 既存のレコードを更新。
例: user.update(name: "Bob")
### 8. destroy
用途: レコードを削除。
例: user.destroy
### 9. where
用途: 条件に一致するレコードを検索。
例: User.where(name: "Bob")
### 10. pluck
用途: 指定カラムの値を配列で取得。
例: User.pluck(:name)
### 11. limit
用途: 取得するレコード数を制限。
例: User.limit(5)
### 12. select
用途: 取得するカラムを指定。
例: User.select(:name, :email)。


---
スーパーエンジニア目指してターミナルでデータセットできるようになるのが目標です！🤩
TeensyでFreeRTOSを使ってみよう

みなさんRTOSは好きですか?

私はそこそこ好きです。~~大好きではない~~
Teensy4.1でFreeRTOSを使う場面があったので記録を残しておきます。

# 環境
* Windows 11
* Visual Studio Code
* PlatformIO
* [freertos-teensy](https://github.com/tsandmann/freertos-teensy)
* Teensy4.1

freertos-teensyではTeensy4.1以外にもTeensy 3.5, 3.6, 4.0でも使えるそうです。
基本的にはvscodeにPlatformIOの拡張機能を導入して使います。ArduinoIDE(Teensyduino)でも一応使用可能なようです。

# 導入方法
[freertos-teensy](https://github.com/tsandmann/freertos-teensy)より引用
> 1. Install PlatformIO core as described [here][PIOInstall]
> 1. Clone this git repository: `git clone https://github.com/tsandmann/freertos-teensy`
> 1. Open an example of the cloned repo, e.g. `freertos-teensy/example/blink`
> 1. Select the correct project environment [PlatformIO toolbar][PIOToolbar] for your Teensy board, e.g. `teensy41`
> 1. Build project: use `Build` button on the [PlatformIO toolbar][PIOToolbar] or shortcut (`ctrl/cmd+alt+b`)
> 1. Upload firmware image
    * Connect USB cable to teensy board
    * Use `Upload` button on the [PlatformIO toolbar][PIOToolbar] or shortcut (`ctrl/cmd+alt+t`) and select "PlatformIO: Upload"
> 1. Use a terminal program (e.g. minicom) to connect to the USB serial device
    * If you use minicom: goto `Serial port setup` settings and set `Serial Device` to your serial device (typically sth. like `/dev/cu.usbmodemXXXXXXX` or `/dev/tty.usbmodemXXXXXXX`)


簡単に言えば、リポジトリのexampleの中身をもとに使ってね、って感じです。

ただ、`platformio.ini`の中を下の様に書き換えることでも最低限使えるようになります。

```platformio.ini
[env:teensy41]
platform = https://github.com/tsandmann/platform-teensy.git
board = teensy41
framework = arduino
lib_deps = 
	https://github.com/tsandmann/freertos-teensy.git
build_flags = -Wformat=1 -DUSB_SERIAL -DTEENSY_OPT_FASTER_LTO
upload_flags = -v
upload_protocol = teensy-cli
```

APIなどは一般的なFreeRTOSと全く同じように使えました。
Edge関連のリンク

https://blogs.windows.com/msedgedev/

https://learn.microsoft.com/ja-jp/deployedge/microsoft-edge-for-business

https://learn.microsoft.com/ja-jp/deployedge/configure-microsoft-edge

https://jpdsi.github.io/blog/internet-explorer-microsoft-edge/how-and-why-to-update-edge/

https://forest.watch.impress.co.jp/docs/news/1487145.html

https://learn.microsoft.com/ja-jp/deployedge/configure-microsoft-edge

・同期

https://learn.microsoft.com/ja-jp/deployedge/microsoft-edge-enterprise-sync

・自動サインイン

https://learn.microsoft.com/ja-jp/deployedge/microsoft-edge-security-identity

https://admx.help/?Category=EdgeChromium&Policy=Microsoft.Policies.Edge::BrowserSignin&Language=ja-jp
【SwiftUI】設定ウインドウを開くボタンを設置する（macOS14）

# はじめに
以前も同じ内容の記事を書きました。

https://qiita.com/SNQ-2001/items/423db3d6453db5577ad6

今までは設定ウインドウを開くにはAppKitを使用しないと実現できなかったのですが、macOS14からSwiftUIの標準で実装することができました。

# サンプルアプリ
![画面収録-2023-12-28-22.13.55.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/a8b2fb90-f2e5-b44c-eace-b2c6c70afb16.gif)

# 実装
```DemoApp.swift
import SwiftUI

@main
struct DemoApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }

        Settings {
            SettingView()
        }
    }
}
```

```ContentView.swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        SettingsLink {
            Text("設定ウインドウを開く")
        }
    }
}
```

```SettingView.swift
struct SettingView: View {
    var body: some View {
        TabView {
            Text("General")
                .tabItem {
                    Label("General", systemImage: "gear")
                }
            Text("License")
                .tabItem {
                    Label("License", systemImage: "book")
                }
        }
        .frame(width: 300, height: 300)
    }
}
```

# 解説
今回のメインは`SettingsLink`です。
引数はlabelでViewを取ります。
```swift
SettingsLink {
    Text("設定ウインドウを開く")
}
```

設定ウインドウを表示させるために、DemoAppに以下の実装をします。
```diff_swift
@main
struct Demo_MacOSApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }

+       Settings {
+           SettingView()
+       }
    }
}
```

# おわり
SwiftUIが便利になっていくのは嬉しいですね。

# 公式ドキュメント
https://developer.apple.com/documentation/SwiftUI/SettingsLink
rustで、参照された変数を更新する

Rustで、構造体に実装したメソッド内で自身のプロパティを更新する。

例として、以下のように円を表す構造体を考える。
```rust
struct Circle {
    radius: f64, // 半径
    area: f64, // 面積
}
```

円インスタンスを、以下のように半径を与える形で宣言し
この後、半径radiusを元に面積を計算し、circle自身に保持させる事を考える。
```rust
    let mut circle = Circle{ radius: 5.0, area: 0.0};
```

円の半径をr, 面積をSとすると、Sは、円周率πを用いて、
```
S = πr^2
```
で導かれる事を使うと、


以下のように、定義するメソッドの仮引数（self)の型に、`&mut`を付与することで、
書き換え可能な値を参照で渡すことができる。

ただし、以下を用いる
[powi](https://doc.rust-lang.org/std/primitive.f64.html#method.powi)
[std::f64::consts::PI](https://doc.rust-lang.org/std/f64/consts/constant.PI.html)

```rust
use std::f64::consts::PI;

impl Circle {
  // &mut selfによって、可変の参照を渡せる。set_areaは、circleの値を借用している。そのため、set_areaを用いても所有権は移動しない
  fn set_area(&mut self) {
    self.area = PI * self.radius.powi(2)
  }
}

```
ffmpegの入力としてBluetoothマイクを簡単に指定する方法

## はじめに
Raspberry Piでの話。どうすればマイクを利用できるか検索しまくった結果を書く。

### 注記
以下の自分の記事の転載です。
[ffmpegの入力としてBluetoothマイクを簡単に指定する方法(2023年4月6日)](https://wp.yyya-nico.co/2023/04/06/ffmpeg%e3%81%ae%e5%85%a5%e5%8a%9b%e3%81%a8%e3%81%97%e3%81%a6bluetooth%e3%83%9e%e3%82%a4%e3%82%af%e3%82%92%e7%b0%a1%e5%8d%98%e3%81%ab%e6%8c%87%e5%ae%9a%e3%81%99%e3%82%8b%e6%96%b9%e6%b3%95/)

## 前提
Raspberry Pi OSの標準機能でBluetooth機器をペアリングして、入力デバイスとしてマイクを指定しておく。

## 入力の指定部分のコード
```sh
-f pulse -i default
```

## 簡単な説明
どうやら今どきのUbuntuとかのOSはBluetoothオーディオ機器にアクセスしようと思ったらPulseAudioを利用・経由するのが今風らしい。Raspberry Pi OSもそうだった。マイク一つだけならデフォルト指定で良いっぽいので、コードはデフォルトを指定した。まあなんか他が指定したいなら参考サイト見て番号とかラベルとかなんでも指定してほしい。

## 自分の利用例
```sh
ffmpeg -vn -f pulse -i default -ac 1 -acodec aac -ab 128k -ar 48000 -f flv rtmp://192.168.0.8:1935/live/audio
ffmpeg -vn -f pulse -i default -ac 1 -acodec pcm_s16le -ab 1024k -ar 8000 -f flv rtmp://192.168.0.8:1935/live/audio
```

## 参考になったサイト
https://trac.ffmpeg.org/wiki/Capture/PulseAudio
LinuxのCUIでBluetoothのペアリング

# 1. はじめに
LinuxのCUIでBluetoothのペアリングを行うにはbluetoothctlコマンドにて行う。
コマンドの詳細は下記が参考になる。
https://qiita.com/noraworld/items/55c0cb1eb52cf8dccc12

ライブラリがインストールされていない場合は下記でインストールする。
~~~
sudo apt -y install bluetooth bluez
~~~

# 2. bluetoothctl起動
~~~
bluetoothctl
~~~

# 3. ペアリング可能なデバイスのスキャン
~~~
scan
~~~

# 4. ペアリング
~~~
paier macアドレス
~~~

# 5. デバイスを信頼する
再起動しても接続できるように、デバイスを信頼する
~~~
trust macアドレス
~~~

# 6. ペアリングした機器に接続
~~~
connect macアドレス
~~~

# 7. ペアリングした機器の削除
~~~
remove macアドレス
~~~

# 8. 終了

~~~
exit
~~~

# 9. ペアリングと削除の簡単なスクリプト
コマンドでペアリングと削除をするのが面倒になったので、簡単なシェルスクリプトを作ってみました。
https://github.com/aruelu/bt_ctl
Windows11Proを新規インストールしてリモートデスクトップ接続を受け入れるまでの手順

最近自宅メインマシンのWindows11Proを再インストールして、リモートデスクトップを受け入れる設定をしたので手順をメモしておく。半年に1回くらいしかやらないので次回思い出すのが面倒なのでメモしておく。

# 接続先における設定
接続先(リモートデスクトップ接続を受け入れる側、サーバ側)の設定手順は以下の通り。
 - Windows11Proをインストールする
 - MicrosoftAccountを連携して、WindowsHelloを有効化する
   - ※MicrosoftAccountのアカウント名の例は"user01@example.com"とする
 - リモートデスクトップの設定を開く
   - リモートデスクトップをONにする
   - 「デバイスが接続にネットワークレベル認証を使用することを要求する」のチェックをOFFにする
   - リモートデスクトップユーザに、ログインするMicrosoftAccountを追加する(例: user01@example.com) 
 - サインインオプションの設定を開く
   -  パスワードによるサインインを有効化する
 - 一旦ログアウトして、同じMicrosoftAccountでパスワードを使ってログインする
 -  次の「接続元における設定および接続」を実施する
 -  もし接続出来ない（パケットが通ってないような挙動）場合、ファイアーウォールをOFFにする（ウイルス対策ソフトによってはなぜかよく分からないがFWが悪さすることがある）
 -  一旦クライアント側から接続できるのを確認したら、PINや指紋認証などのパスワード以外のサインインでOK（サインインオプションの選択肢としては残しておく）

# 接続元における設定および接続
接続元(リモートデスクトップのクライアントアプリを使って接続する側)の設定手順は以下の通り

 - リモートデスクトップアプリを開く
 - 接続先IPアドレスを設定する（ポート番号を変更していたらポート番号も変更しておく）
 - ユーザ名とパスワードを設定する
   - ユーザ名はMicrosoftAccount名"user01@example.com"(※"MicrosoftAccount\user01@example.com"のように"MicrosoftAccount"をつけなくてもいいっぽい)
   - パスワードはMicrosoftAccountのパスワード
 - リモートデスクトップ接続する

以上
Rails7でreact-rails（ Shakapacker対応）を使う

## 概要
今回はRails7でreact-railsのgemを使ってReactを使う方法を紹介します。

https://github.com/reactjs/react-rails

## 初期設定
基本的にはGitHubのドキュメントに従います。

https://github.com/reactjs/react-rails/blob/master/docs/get-started.md#use-with-shakapacker

### プロジェクトの作成
標準にするとWebpackerが入ってしまうのでそこはコマンドで後から入れられるようにします。
```
rails new my-app --skip-javascript
```
### shakapackerをインストール
shakapackerをインストールします。

```
bundle add shakapacker --strict
rails shakapacker:install
```

### Reactとパッケージをインストール
React本体と本体を動かすためのパッケージをインストールします。
```
yarn add react react-dom @babel/preset-react prop-types \
     css-loader style-loader mini-css-extract-plugin css-minimizer-webpack-plugin
```

続いて`package.json`を修正します。
"@babel/preset-react"を追加します。

```json:package.json
  "babel": {
    "presets": [
      "./node_modules/shakapacker/package/babel/preset.js",
      "@babel/preset-react"
    ]
  },
```

### react-railsをインストール

```
bundle add 'react-rails' --strict
rails generate react:install
```
初期設定は完了です。

## react-railsのバージョンを3.1.1にする（ハマったところ）
現在、初期設定の状態だあと`Gemfile`のreact-railsのバージョンは3.1だと思います。
```
gem "react-rails", "= 3.1"
```
これを3.1.1にしてください。
```
gem "react-rails", "= 3.1.1"
```
3.1だとマウントが上手くいかないです。
```
uninitialized constant React::Rails::ComponentMount::Dummy
```
これはgem側のバグなので、3.1.1にしましょう（bundle installを忘れずに）。

https://github.com/reactjs/react-rails/issues/1303

## テスト
動くかどうかをテストします。

scaffoldで適当に作成してそれをReactで動かせるようにします。

```
rails generate scaffold Article title:string body:text --skip-jbuilder
```

scaffoldしたらアプリを立ち上げましょう。

```
rails s
```

下記を起動しておくとリロードしなくても自動でコンパイルしてくれるので便利です。

```
./bin/shakapacker-dev-server
```

app/views/articles/index.html.erbの中身をreact-railsを使って書きたいと思います。

まずはReactのコンポーネントを作成します。
```
rails g react:component ArticlesList articles:array
```

続いてそのコンポーネントで画面を表示するようにします。
```erb:app/views/articles/index.html.erb
<%= react_component("ArticlesList", { articles: @articles.to_json }) %>
```
これでArticlesList.jsで画面を表示するようになります。
あとはArticlesList.jsを同じような表示になるようにコードを修正すればよいです。
```js:app/javascript/components/ArticlesList.js
import React from 'react';

const ArticlesList = ({ articles }) => {
  const parsedArticles = JSON.parse(articles);
  return (
    <div>
      <h1>Articles</h1>
      <div id="articles">
        {parsedArticles.map(article => (
          <div key={article.id}>
            <h2>{article.title}</h2>
            <p>{article.body}</p>
            <p>
              <a href={`/articles/${article.id}`}>Show this article</a>
            </p>
          </div>
        ))}
      </div>
      <a href="/articles/new">New article</a>
    </div>
  );
};

export default ArticlesList;
```

これで同じ画面が表示されたら成功です。
SvelteプロジェクトをVercel（旧Zeit Now）にデプロイする

## ➀ アカウント作成
<a href="https://vercel.com/new" target="_blank">https://vercel.com/new</a>

## ➁ インストール
```shell
yarn global add vercel
```

## ➂ ログイン
```shell
vercel login
```

## ➃ デプロイ
```shell
vercel --prod
```

以下のようなエラーが出る場合
```
Error: No Output Directory named "public" found after the 
Build completed. You can configure the Output Directory in your Project Settings.
```
build先をpublicフォルダに変更する