OmniAICreator/Qiita-1.07M huggingface dataset:
Firestoreにて特定フィールドが存在しないレコードの抽出

ひと昔前まではDBを構築するのはお金もかかるしなかなか大変だったのですが、最近はGoogleのFirebaseを使えば無料で簡単にDBを構築できるので世の中の流れについていくのも大変です。
とはいえ、実際の業務で使用する場合もあり、覚えておくに越したことはありません。
そんなわけで、現在では業務で普通に使ってるし、フロントエンドだけでなくFunctionsを使用したバッチ処理も組んだりしている状況だったりします。
Firestoreで生成したコレクションに対してレコードを追加する際、全レコード必ず同じフィールドが存在しなくても特にエラーになったりはしません。
（仕様上まずいパターンは勿論存在しますが。）

前段が長くなりましたが。
先程記載した通り、全レコードのフィールドが統一されていなくても動く分、逆にとあるフィールドが無いレコードを見つけるのはどうしたら良いかということを調べてみました。

[公式より](https://firebase.google.com/docs/firestore/query-data/queries?hl=ja)

演算子で良いものがあればいいのですが無く、検索しても上記対応方法がなかなかヒットしませんでしたが、以下のやり方で対応できました。

```javascript
    const ref = await db
      .collection('hoge')
      // .where('feild', '==', db.FieldValue.delete())
      .get()

    const dataList = ref.docs.map((doc) => doc.data())

    dataList.forEach((data) => {
      if (!data.field) {
        logger.log(data.id)
      }
    }) 
```
本来であれば、コメントアウトしているwhere句で対応したかったのですが出来ずにこの書き方になりました。
Line Botでニュースとweb検索結果をLINEで受け取れるスクリプトを作りました！

## 初めに
 こんにちは、私はYahoo News、Google News、Brave Searchからニュースを検索し、LINEボットを通じて結果を送信するPythonスクリプト「Yahoo News Line Bot」を作成しました。この記事では、このボットのセットアップと使用方法について詳しく説明します。readmeにも書いてあるのでそちらを読んでもらっても構いません。

 https://github.com/linkalls/line_bot_news


## 前提条件

このプロジェクトを実行するには、Python 3がインストールされている必要があります。また、LINE Messaging APIのアクセストークンとシークレットキーが必要です。

## インストール方法

### Windows

1. Python 3をインストールします。[Python公式サイト](https://www.python.org/downloads/windows/)からインストーラーをダウンロードして実行します。

2. コマンドプロンプトを開き、以下のコマンドを実行して必要なパッケージをインストールします。

```bash
pip install flask waitress line-bot-sdk requests beautifulsoup4
```

### Ubuntu

1. Python 3をインストールします。ターミナルを開き、以下のコマンドを実行します。

```bash
sudo apt update
sudo apt install python3 python3-pip
```

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

```bash
pip3 install flask waitress line-bot-sdk requests beautifulsoup4
```

## 環境変数の設定

### Windows

1. スタートメニューから「システムのプロパティ」を開きます。

2. 「詳細なシステム設定」をクリックし、「環境変数」ボタンをクリックします。

3. 「新規」ボタンをクリックし、以下の環境変数を追加します。

   - 変数名: `LINE_CHANNEL_ACCESS_TOKEN`
   - 変数値: `<あなたのLINEチャネルアクセストークン>`

   - 変数名: `LINE_CHANNEL_SECRET`
   - 変数値: `<あなたのLINEチャネルシークレット>`

4. OKをクリックしてウィンドウを閉じます。

### Ubuntu

1. ターミナルを開き、以下のコマンドを実行して環境変数を設定します。

```bash
export LINE_CHANNEL_ACCESS_TOKEN=<あなたのLINEチャネルアクセストークン>
export LINE_CHANNEL_SECRET=<あなたのLINEチャネルシークレット>
```

2. これらの変数を永続的にするには、`~/.bashrc`または`~/.profile`に上記の行を追加します。

## サーバーの実行方法

1. `yahoonewsline.py`があるディレクトリに移動します。

2. 以下のコマンドを実行してサーバーを起動します。

   - Windows:

   ```bash
   python yahoonewsline.py
   ```

   - Ubuntu:

   ```bash
   python3 yahoonewsline.py
   ```

サーバーが起動すると、デフォルトでポート8000で待機します。LINEプラットフォームのWebhook URLには、このサーバーの公開URLを設定する必要があります。

## LINEボットの使い方

LINEボットにメッセージを送信することで、以下の機能を使用できます。

- `@news`に続けてキーワードを入力してYahoo Newsを検索します。
- `@google`に続けてキーワードを入力してGoogle Newsを検索します。
- `@brave`に続けてキーワードを入力してBrave Searchを検索します。

例えば、`@news スポーツ`とメッセージを送ると、Yahoo Newsで「スポーツ」に関連するニュースを検索し、結果を返信します。

## 注意事項

このボットはウェブスクレイピングを利用して情報を取得しています。スクレイピングは対象のウェブサイトの利用規約に違反する可能性があるため、使用は自己責任でお願いします。また、頻繁なアクセスはサーバーに負荷をかけることになるので、適切な間隔を空けて利用するようにしてください。
【CSS】clip-pathで三角形を作ってみた！

## やりたいこと
今回やりたいことは、以下の画像のような四角形の変形した図を作成することです。
これをHTMLとCSSで作成します。

![スクリーンショット 2024-01-21 20.08.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/153d7f93-2ba8-e6fb-3861-376d04836f3d.png)

### 考え方
三角形＋四角形を組み合わせて作成してみようかなと思います。

![スクリーンショット 2024-01-21 18.41.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/4c2fd0e0-9ac5-8f78-efe0-336a44803d29.png)

## 三角形を作成
さっそく三角形を作成します！
以下のコードのように `clip-path` を利用して作成しました！
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="ZEPyKwy" data-user="lgexfaug-the-sasster" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/lgexfaug-the-sasster/pen/ZEPyKwy">
  triangle</a> by 藤野美優 (<a href="https://codepen.io/lgexfaug-the-sasster">@lgexfaug-the-sasster</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## `clip-path` ってそもそも何？


### `clip-path` とは
要素や画像をクリッピングして（切り抜いて）表示させることが出来ます。

### `clip-path:polygon()`とは
polygon() に3つの頂点の座標を指定して三角形のパスを定義できます。
今回は以下のように定義しています。

![スクリーンショット 2024-01-21 20.00.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/e74f3e66-2558-7105-31cd-810988f4f3aa.png)

### `clip-path`でできること
今回は三角形を作成を`clip-path:polygon()`で作成しましたが、`clip-path`には他にも多角形や円、様々な図を作成できるので、使いこなしたら幅広く利用できそうです。


## 四角形を作成
残りの下の四角形を作成します。
これは高さと横幅を決めて色つけて終わりです。
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="JjzJNBL" data-user="lgexfaug-the-sasster" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/lgexfaug-the-sasster/pen/JjzJNBL">
  Untitled</a> by 藤野美優 (<a href="https://codepen.io/lgexfaug-the-sasster">@lgexfaug-the-sasster</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


## 三角形と四角形を組み合わせて完成！
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="gOERWqV" data-user="lgexfaug-the-sasster" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/lgexfaug-the-sasster/pen/gOERWqV">
  triangle＋square＋</a> by 藤野美優 (<a href="https://codepen.io/lgexfaug-the-sasster">@lgexfaug-the-sasster</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 最後に
以上となります！
他に簡単な作成方法とか、適したものがあったら是非教えていただきたいです、、！！
図で説明！最尤推定！ロジスティクス回帰！尤度！

# 最尤推定とは
この記事では最尤推定とは何かについて簡単に説明していきます。
最尤推定、尤度関数、勾配法、ロジスティクス回帰などが分からない方はぜひご覧ください。
最尤推定とは尤度を最小または最大にする手法のことです。
ロジスティクス回帰においては対数尤度を評価基準として最小化します。

# ロジスティクス回帰
猫と犬を識別するモデルを作るとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656436/634ea677-4651-9a1b-01c6-a0e767821150.png)

下のような図で特徴量が分かれている場合簡単に識別する線は真ん中に引くと識別できそうです。このように2クラス分類を行うことをロジスティクス回帰といいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656436/0e1a6e12-221f-5d4b-9198-50de49390c90.png)

# 尤度

しかし上のグラフのように実際はこのグラフの見える範囲だけに猫と犬は収まりきることはないため識別するのが難しくなってしまいます。そこで猫と犬の特徴をまとめたものを0~1に縮めることができれば簡単に識別線を引くことができます！そこで登場するのが出力を０～１にするシグモイド関数です。
```math
\displaylines{
f(x)= \frac{1}{1+e^{-x}}
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656436/dd1ff58c-52ed-3c22-9388-9b6d53a1b07e.png)

シグモイド関数の傾きを学習にして０～１に圧縮した<font color="Red">データとモデルが当てはまるように</font>学習します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656436/17d889c8-e828-5f90-76d0-d0e29a3004bb.png)

ここでモデルとデータの当てはまり度合いを算出するのが<font color="Red">尤度</font>です。
尤度の式は以下のように表されます。
```math
\displaylines{
P(w)= \prod \hat{y}^{(n)y^{(n)}}(1-\hat{y}^{(n)})^{(1-y^{(n)})}
}
```
yハットの部分がクラス猫（クラス１）を表しており、（１－ｙハット）が犬のクラス（クラス２）を表しています。もし犬のクラスだった場合ｙハットは0になり（１－ｙハット）が残ります。猫のクラスの場合は逆のことが起きます。（yハットが１になるため）
一般にこの尤度は１に近いほど正解データと予測データ（出力）の差が小さいことを示します。

<font color="Red">尤度</font>とは正解データと出力の差（データとモデルの当てはまり具合）を計算したものです。 

# 最尤推定
この尤度を１に近づけるように学習を行いますが実際はこのままいきません。
尤度は通常小さい値を取るためこのままではアンダーフローを起こしてしまうためです。
アンダーフローを起こさないために対数をとります。これが対数尤度です。
```math
\displaylines{
\ln P(w)= \Sigma_{n=1}^N\{y^{(n)}\ln \hat{y}^{(n)} + (1-y^{(n)})\ln (1-\hat{y}^{(n)})
}
```
ロジスティクス回帰において上の式である対数尤度を評価基準として最適化を実施することを最尤推定といいます。
そして実際に最適化を行なうのには勾配降下法を用いて誤差関数を最小にするように学習を行います。

通常を最小化するためこれにー（マイナス）をつけて最小化します。ーをつけたものを交差エントロピーといいます。

# 参考文献
https://ai-trend.jp/basic-study/estimator/maximum-likelihood-estimation/
https://unit.aist.go.jp/mcml/rg-orgp/uncertainty_lecture/likelihood.html
https://www.tryeting.jp/column/9547/#:~:text=%E3%83%AD%E3%82%B8%E3%82%B9%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF%E5%9B%9E%E5%B8%B0%E3%83%A2%E3%83%87%E3%83%AB%E3%81%A8%E3%81%AF%E3%80%81%E8%A4%87%E6%95%B0%E3%81%AE%E8%A6%81%E5%9B%A0%E3%80%8C%E8%AA%AC%E6%98%8E%E5%A4%89%E6%95%B0,%E7%AF%84%E5%9B%B2%E3%81%A7%E3%81%97%E3%81%8B%E5%88%A4%E6%96%AD%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82
もっと頑張ってグラフ001

元の図をけなすようで申し訳ないが，ちょっと手間を掛けるとよりよい（?）グラフになるのじゃないかなという例を集めていく。

[元の図](https://qiita.com/konakalab/items/be676025fb5635467171)
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3537303936362f65396537366535662d623464352d643433632d616466322d3439616231616365343034622e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611739/68ba3131-91ea-acb0-2e6a-658fde156ff0.png)

**凡例はいらない**
凡例と図の記号の対応をその都度やらないといけなので，全体が見通しにくい。
凡例がなくてもわかりやすいように図を描こう。

![スクリーンショット 2024-01-21 19.46.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611739/95ff64ea-f35c-07e8-892d-c22fb49cd14d.png)
React Hooks（State Hooks編）

# React Hooksとは
- コンポーネントからさまざまなReact機能を使用するためのもの。
- すでに用意されているHooksだけでなく、独自にHooksを作成することもできる。

## State Hooks
- コンポーネントでユーザー入力などの情報を状態管理できるReact Hooks
- `useState`、`useReducer`が該当する。

### useState
コンポーネントに状態変数を追加できる。

https://react.dev/reference/react/useState

```react
const [state, setState] = useState(initialState)
```
#### `state`
- 現在の状態。
- initialStateまたはsetStateで渡した値と一致する。

#### `setState`
- 現在の状態を別の値に更新し、再レンダリングさせる関数。

#### `initialState`
- 初期状態にしたい値。

#### サンプル
```react: 
import { useState } from "react";
import { ReturnHome } from "../common/returnHome";

export const UseStateSample = () => {
  const [text, setText] = useState<string | undefined>(undefined);

  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setText(e.target.value);
  }

  return (
    <main>
      <h1>useState Sample</h1>
      <label htmlFor="sample-text">テキスト: </label>
      <input aria-label="sample-text" type="text" onChange={onChange} />
      <p>入力値: { text }</p>
    </main>
  )
}
```

### useReducer
コンポーネントにリデューサーを追加できる。

https://react.dev/reference/react/useReducer

```react
const [state, dispatch] = useReducer(reducer, initialArg, init?)
```

#### `state`
- 現在の状態。

#### `dispatch`
- 現在の状態を別の値に更新し、再レンダリングさせる関数。
- 別の値に更新する時にrebucerで渡した関数が実行されて戻り値が更新値になる。

#### `reducer`
- 状態を更新する方法を指定するリデューサー関数。
- リデューサー関数は、引数が状態・アクションで、戻り値を新しい状態とする必要がある。

#### `initialArg`
- 初期状態にしたい値。
- initが存在する場合は、初期状態がinitで渡した関数の戻り値になる。

#### `init?`
- 初期状態を返す初期化関数。
- 指定しない場合は、initialArgが初期値になる。

#### サンプル
```react
import { useReducer, useState } from "react"
import { ReturnHome } from "../common/returnHome";

type ActionType = {
  type: CalcType;
  val: number;
}

type CalcType = "add" | "sub" | "mul" | "div" | "reset";

export const UseReducerSample = () => {
  const [val, setVal] = useState<number>(0);
  const [result, dispatch] = useReducer(calcReducer, 0);

  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setVal(e.target.valueAsNumber);
  }

  const onClick = (type: CalcType) => {
    if (type === "reset") {
      setVal(0);
    }
    dispatch({ type, val });
  }

  return (
    <main>
      <h1>useReducer Sample</h1>
      <p>計算式: 結果 ➕➖✖️➗ 入力値</p>
      <label htmlFor="sample-text">入力値: </label>
      <input aria-label="sample-text" type="number" value={val} onChange={onChange} />
      <p></p>
      <button onClick={() => onClick("add")}>足し算</button>
      <button onClick={() => onClick("sub")}>引き算</button>
      <button onClick={() => onClick("mul")}>掛け算</button>
      <button onClick={() => onClick("div")}>割り算</button>
      <button onClick={() => onClick("reset")}>リセット</button>
      <p>結果: { result }</p>
    </main>
  )
}

const calcReducer = (result: number, action: ActionType): number => {
  if (!action.val) return result;

  switch (action.type) {
    case "add":
      return result + action.val;
    case "sub":
      return result - action.val;
    case "mul":
      return result * action.val;
    case "div":
      return result / action.val;
    case "reset":
      return 0;
    default:
      throw new Error("Invalid action type");
  }
} 
```

## 参考サイト
https://react.dev/reference/react/hooks
純粋関数(参照透過性, 副作用)

## 参照透過性
同じ入力は常に同じ出力であること
特に関数において引数が同じなら常に同じ返り値になる特性を指すことが多い
`参照`が`透過`とは参照の状態に透明性がある。つまり参照を意識する必要がない状態を意味する

下記は参照透過性がある
```ts
// 引数x, yがそれぞれ1, 2なら常に返り値は3になる
function func(x, y) {
  reutnr a + y;
}
```

下記は参照透過性がない
```ts
let x = 0;

// 変数xの状態は関数実行時までに変わっている可能性がある → 参照に透明性がない
function func1() {
  x++;
  return x;
}

// 下記は実行時刻によって返却値が異なる → 参照に透過性がない
function func2() {
  const data = new Data();
  return data;
}
```

## 副作用
ある関数の実行によって関数外部の状態が変更されること
```ts
// 下記関数は副作用がない
function func(x, y) {
  reutnr a + y;
}

// 関数外部の変数iの状態を変更している → 副作用がある
let i = 0;
function func2() {
  i++;
  return i;
}
```
## 純粋関数
同じ引数で実行した場合常に返り値が同じ(参照透過性)
副作用を発生させない

参照透過性が好ましい理由
- 予期せぬバグが起きづらい
- 改修の際の影響範囲を特定しやすい
- テストしやすい

## 純粋関数へのリファクタリング
下記は副作用を含み、非参照透過性な関数
```ts
let i = 0;

// 出力は関数外部のiの状態によって異なる → 参照透過性が無い
function func() {
  // 外部変数iの状態を変更している → 副作用の発生
  i++;
  // returnしていないのでテストしづらい
  console.log(i)
}

func() // 1
func() // 2
func() // 3
```

```ts
// 引数で値を渡すようにすることで参照透過性と副作用の非発生化
// 値はreturnで返すことでテストがしやすくなる
function func(x) {
  return x;
}

console.log(func(1)); // 1
console.log(func(2)); // 2
console.log(func(3)); // 3
```

## 参考

https://qiita.com/suzuki-hoge/items/bad43630ad1ad723ca4a

https://qiita.com/Yametaro/items/1de3c2b76b8a4dc2d30d
GooglePlayConsoleでゲームを出す


GooglePlayでゲームを出そうと思いやってみたところ思いのほか苦戦したので今後のためにメモ。

１、GooglePlayConsoleに登録する（初回のみ）

ここは簡単だった。

いろいろ同意して登録料を払う（$25）

そしたらアカウントの情報を入れて完了。

２、アプリを作る

ここからが問題。

アプリをアップロードするのだがどうやら.abbというファイル形式でないといけないらしい。

というわけで調べたらすぐ出てきた。Unityで簡単に設定できるようだ。該当する項目にチェックをいれる。（ちゃんとGooglePlayと書いてくれている。親切）

そうしてできたファイルをアップロードしてみる。

エラーが出た。

API levelを31以上にしろとのこと、API levelってなんやねん。

調べたら参照するSDKを変えたらいけるらしい、というわけでやってみる。API level31以上のSDKがなかったのでAndroid Studioからダウンロードする。

これでいけるだろう、ビルドだ！

エラーが出た。

今度はなんだ？Gradleがどうのこうの、よくわからないがGradleがなんかだめだったらしい調べてもいろんな事例があって自分のがどれに該当するのかよくわからない。とりあえずいろいろ試す。うまくいかない。

かなり沼ったのでもう一度エラーをよく読んでみる。どうやらGradleのバージョンが足りてないらしい。調べたらGradleがダウンロードできるサイトがあったので一番新しいのをダウンロードした。今度こそ！

エラー。

Gradleの互換性がないと言われた。調べたらUnityで使えるGradleのバージョンは限られてるらしい。6.1.1が使えるようだったのでそれにしてみた。

ビルド成功！

ここがほんとに大変だった。

３、もろもろ設定

BuildができたのでGooglePlayConsoleに戻っていろいろ設定する。Googleは非常に親切でダッシュボードに従えばほとんど困ることがない。ただ必要な準備がいろいろあったのでそれだけメモ。

最初に内部テスト。

テストするユーザーなどを設定したらテストを開始。

URLから飛んだらスマホにダウンロードできる。

次に対象年齢などの設定。

対象年齢を全年齢にしたかったのだが13歳以下を対象に入れるにはプライバシーポリシーが必須らしい、仕方ないやるか。そしたらプライバシーポリシーのリンクを貼れと、webサイトが必要になった。というわけでwixでサイト開設。プライバシーポリシーをしらべながら書いて完了！

そして、画像の用意。

結構厳密にサイズが指定されてたのでちょっと手間がかかった。

アイコン　512*512

フィーチャーグラフィック　1024*500

スクリーンショット　２～８枚　16:9 

次に動画の準備。

動画自体は事前に作ってあったのだがどうやらYouTubeのリンクを貼らないといけないらしい、チャンネルを作らねば。というわけでYouTube開設。

YouTube側からもいくつか画像を要求された。

４，公開

ここまで出来たらいよいよ公開！
モノリスとは何か(2) - メリットデメリット

## Monolithic Architectureの利点
- 配布が簡単だ
- どこでパッケージングしてもかまいませんし、 何とか配布するだけだ
- メンテナンスが比較的簡単（トラブルシューティングが簡単）
- 高価なサーバーリソースを最適化して使用できる
- 共通モジュール等の活用が非常に容易である

## Monolithic Architectureメリットがあるケース
- 創業または新サービスを開始する場合
- 少数のチームメンバーで早くオープンしなければならない場合
- クラウド環境が使いにくい場合
- 金融等のセキュリティと安全性が最も重要な場合
- devopsなどの専門人材が不足している場合
    - 手動でci/cdを実施しても大きな支障はないため
 
## Monolithic Architectureのデメリット
- 水平拡張が難しい(scale out)
    - 単一のdbへの依存性が大きい
    - scale out : Aがサーバーからtrafficを受けることが難しく、隣にいるBに仕事を分けてあげること、問題は
Aが参照いるDBがBで分けてもDBの立場では同じことをするのと同じ
- 規模が大きくなるほど複雑さが増し、修正に対するコストと負担が増加
- 大規模なアプリケーション環境では, 単純な修正でも配布まで時間がかかることがある
- 障害時、アプリケーション全体に大きな影響を受けることになる

## Monolithic Architectureのデメリットがあるケース
- MSA、Cloud環境に十分熟練した開発者が多い場合
    - Devopsに熟練した開発者が多ければ、クラウド環境で最大限活用できる
- 多くのサービスが同時多発的に開発を進める場合
    - =ソースの配布、修正が多い=共通モジュールがあるサービスの場合は、コミュニケーションの問題が発生する
- セキュリティと安定性よりも速い機能開発と配布が重要なサービス
    - 顧客の緊急度が高いニーズを満たさなければならない場合をいう。 他のサービスに影響を最大限与えず、ビジネスドメインで早く配布をして顧客にビジネスインパクトを与えることができる、そのような機能を早く開発して、他のサービスに影響を与えずに配布を早くしてビジネス的に大きな効果を出すことができる。

## MSAが注目されている理由
例えば韓国のネカラクベ（NAVER、カカオ、LINE、coupang、配達の民族）の場合、顧客が感じる不便さ、顧客が望む機能をとても早く配布ができている！
その企業らは大きなアーキテクチャはMSAを採用している。会社はニズが何かを知り、早く配布して満足させることが何より重要にしているため、MSA環境に慣れなければならない。MSA環境で早くアジャイルにて問題を早く解決し、早く配布できるチームは、より多くの顧客、より多くのお金を稼げる環境が整えられるようになるそうです！
【React】jsxファイルでPropsを定義したら"missing in props validation"のエラーが出た。

# はじめに
フロントエンドに興味を持ち、JavaScript×Reactで簡易的なサイトを作成中です。
今回解決に苦しめられたエラーについて書いていきます。
# 問題
jsxファイルでPropsを定義したら"missing in props validation"のエラーが出てしまいました。
コードの中身を確認しましたが、特に問題は無いようでした。
なお、使用しているReactのバージョンは18.2.0です。
# 解決方法
どうやら**React自体で起きているバグ**みたいです。
今回JavaScriptを使用しているにも関わらず、TypeScriptにおけるpropsの型定義のルールが適用されてしまっていました。
従って、eslintrc.jsonの"rules"に下記を追加してこの**ルールを無効化**しました。
```json:eslintrc.json/
"rules": {
    "react/react-in-jsx-scope": "off",
    "react/prop-types": "off"
  }
```

# おわりに
React初学者の身からすると、「なんじゃこりゃあ！」となってしまうエラーでした。
改善を願うばかりです。。
# 参考
https://stackoverflow.com/questions/38684925/react-eslint-error-missing-in-props-validation
【Java】Java備忘録①

atcoderの問題をJavaで解いたのでその際に使用したJavaの知識を備忘録としてqiitaに残します。

## 問題①
https://atcoder.jp/contests/abc314/tasks/abc314_a

### 解答
```java
import java.util.Scanner;
public class Main {
    public static void main(String[] args){
        Scanner numIn = new Scanner(System.in);
        int num = numIn.nextInt();
        String ans = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679";
        int index = num + 1;
        System.out.println(ans.substring(0, index + 1)); // 文字列の取り出し
        numIn.close();
    }
}
```
### 解説
substringを使用して文字列を取り出す。
substringの基本型は、インデックスによる範囲指定です。取得を開始するインデックスと、終了するインデックスを指定することで、その間にある文字列を取得します。

## 問題②
https://atcoder.jp/contests/abc337/tasks/abc337_a

### 解答
```java
import java.util.Scanner;
public class Main {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt(); // int型に変換する。

        int x_value, y_value; // 受け取る二行目の数値
        
        int x = 0;
        int y = 0;
        for(int i = 0; i < num; i++){
            x_value = sc.nextInt();
            y_value = sc.nextInt();

            x += x_value;
            y += y_value;
        }
        sc.close();
        if(x == y){
            System.out.println("Draw");
        }else if(x > y){
            System.out.println("Takahashi");
        }else{
            System.out.println("Aoki");
        }
    }
}
```
## 問題③
https://atcoder.jp/contests/abc341/tasks/abc341_a

### 解答
```java
import java.util.Scanner;

public class Main {
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        // 答えを格納
        String ans = "";
        // ループする回数を決める。
        int roop = N + N + 2;
        
        for (int i = 1; i < roop; i++){
            if (i % 2 != 0){
                ans += "1";
            } else {
                ans += "0";
            }
        }
        System.out.println(ans);
        sc.close();
    }
}
```

## 問題④
https://atcoder.jp/contests/abc340/tasks/abc340_a

### 解答
```java
import java.util.Scanner;

public class Main {
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);

        int A = sc.nextInt(); // 初項
        int B = sc.nextInt(); // 末項
        int D = sc.nextInt(); // 公差

        int roop = (B - A) / D; // ループする回数を決める。
        // iが3までループして出力を行う
        for (int i = 0; i <= roop; i++){
            System.out.print(A + D * i + " ");
        }
        sc.close();
    }
}
```
labelタグの使い方

HTMLのlabelラベルタグは、inputやtextareaなどの入力欄に対してキャプション（説明）をつけるために使います。おもに「何を入力する欄なのか」が分かるように、テキストや画像を入れます。

・labelタグのメリット
その１：ラベルをクリックすると入力欄にフォーカス

説明：入力欄自体をクリックしなくても、labelタグ内のテキストをクリックすれば、紐づく入力欄にフォーカスがあたります。

補足：labelの使用は、チェックボックスやラジオボタンだと特に重要です。チェック部分（□）は小さく（特にスマホ）、クリックやタップをしづらいからです。

その２：アクセシビリティの向上
説明：ユーザーは「何を入力する欄なのか」をlabelのテキストから把握することができます。

・labelタグの基本的な使い方
まず理解しておきたいのは「どのlabelが、どの入力欄（input,textarea）に対応するのか」というひも付けの仕方です。ひも付け方には2パターンあります。

その１：labelの中にinputを入れてひも付け
説明：入力欄も、説明文や項目名などのテキストも、合わせてlabelの中に入れます。

その２：「label for」と「input id」で紐付け
説明：label for="ID"とinput id="ID"を合わせると、お互いが別の場所にあっても、ひも付くようになります。

使い方その１：ラベルに画像を使用する
説明：label内には、div、span、imgなど、さまざまな要素を入れることができます。labelに囲まれた部分がクリック可能領域になります。

・labelを使うときの注意点

その１：ボタンやリンクを含めない
説明：labelの中に、リンク（a）やボタン（button）は入れないようにしましょう。これらの要素はページの遷移や画面の変化を伴うため、ラベルをクリックしたときに入力欄をアクティブにするのが難しくなるためです。

その２：見出しタグを含めない
説明：一部の読み上げソフトでは、見出しタグ内のテキストを「セクション（文章のまとまり）のタイトル」として認識します。
「入力欄の説明」の役割をするlabelと、「セクションのタイトル」の役割をする見出しタグが混在すると、その部分の役割が正しく認識されない可能性があります。

その３：labelは入れ子にできない

・CSSでデザインをカスタマイズする
その１：縦並び
 デフォルトではinputやlabelは、ブロックを作らない（改行が入らない）ため、横並びになります。
 
➀HTMLだけで縦並びに
手っ取り早く縦並びにするためには、HTMLでボタンそれぞれを<div>タグで囲めばOKです。

➁CSSで縦並びに
CSSで以下のように{ display: block }指定します。

➂labelの幅を変える
labelは、いわゆるインライン要素にあたるため、デフォルトではwidthを指定しても効きません。幅を変えたいときはwidthだけでなく、display: blockも合わせて指定するようにしましょう。
プログラム実装をサポートするAI補助サービス／ツール比較まとめ

# プログラム実装をサポートするAI補助サービス／ツール比較まとめ

| ツール名                    | 価格               | 主な特徴と機能                             |
|-----------------------------|---------------------|-------------------------------------------|
| GitHub Copilot              | 月額19USD      | 自動コード生成、複数言語サポート、VSCode拡張あり        |
| Amazon CodeWhisperer| 個人利用無料、月額19USDのプロ版あり                |VSCode拡張あり        |
| Visual Studio IntelliCode   | 無料 | VS, VSCode拡張あり       |
| Cursor| 無料プランあり<br>月額20USD, 月額40USDの有料プランあり| VSCodeベースの専用エディタ。<br>他のサービスより対話形式でソースコードを生成してくれる印象       |

## 感想
- コメントや対話からソースコードを生成してくれる。
- ~~既存のコードから機能修正や不具合の対応は出来ないかもしれない。
（GitHub CopilotやCursorは出来るかもしれない）~~
- ~~やりたいことの文章や仕様書から複数のプログラムファイルを生成／改修してくれるようなサービスを期待していたが、まだまだ先になりそう。~~ 

取り消し部分は後述

## [追記]Cursorを使用した既存のコードから機能修正や不具合の対応について
- Cursorにて、修正してほしいファイルを開いて、Command+Lを押すことで対話形式での指示を入力することが可能。修正内容を提案してくれる。
![スクリーンショット 2024-01-21 21.54.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1663756/84a8d5a0-1113-70bc-0400-00de8b0e83c5.png)

- @codebaseをつけることでプロジェクト全体のソースコードに対して対話することが出来る。これはすごいわ・・・。
![スクリーンショット 2024-01-21 21.58.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1663756/09d8fcbc-7834-eddf-c811-9af601385545.png)
PFX ファイルから証明書のインポート

PFX ファイルを使用して証明書をエクスポートする方法と、それを使ってコードに署名する方法を以下に示します。

### 1. PFX ファイルから証明書のインポート

まず、PFX ファイルから証明書をインポートします。これには `Import-PfxCertificate` コマンドレットを使用します。以下は例です。

```powershell
# PFX ファイルのパス
$pfxFilePath = "C:\Path\To\Your\Certificate.pfx"

# PFX ファイルから証明書をインポート
$pfxPassword = Read-Host -AsSecureString -Prompt "Enter PFX Password"
$cert = Import-PfxCertificate -FilePath $pfxFilePath -Password $pfxPassword -CertStoreLocation Cert:\CurrentUser\My
```

ここで、`$pfxFilePath` は PFX ファイルのパスを指定し、`$pfxPassword` は PFX ファイルのパスワードをセキュアに入力します。

### 2. 証明書の詳細を確認

証明書が正しくインポートされたことを確認します。以下のコマンドを使用して証明書の詳細を表示できます。

```powershell
$cert | Format-List -Property *
```

### 3. PowerShell スクリプトに署名

証明書が正しくインポートされたら、PowerShell スクリプトに署名します。以下は例です。

```powershell
# PowerShell スクリプトのパス
$scriptPath = "C:\Path\To\Your\Script.ps1"

# 証明書を使用してスクリプトに署名
Set-AuthenticodeSignature -Certificate $cert -FilePath $scriptPath
```

これで、PFX ファイルを使用して証明書をインポートし、PowerShell スクリプトに署名できるはずです。
【Xcode】Widgetの実機ビルドでFailed to show Widgetエラー

## エラー内容
`SendProcessControlEvent:toPid: encountered an error: Error Domain=com.apple.dt.deviceprocesscontrolservice Code=8 "Failed to show Widget 'com.xxx.app.xxx.widget名' error…`

Xcodeで[File] -> [New] -> [Target]で`Widget Extension`を追加した後に以下のようにWidgetのSchemeを選択して実機ビルドしたらエラーが出ました。

![スクリーンショット 2024-01-21 17.39.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554113/b8b570d0-3493-4ae8-76f4-04b9249c09ad.png)

## やりたかったこと
`Widget Extension`を追加した後に、生成されたファイルのまま一旦実機ビルドして確認してみたかった。

## 解決策
TARGETSをWidgetに変更してMinimum Deploymentsを実機のOSバージョンに合わせて変更する。
![スクリーンショット 2024-01-21 17.45.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554113/7eaab04b-bdd2-6c54-68b2-ebc0496ebd0b.png)

## まとめ
案外、単純だったのに、エラー内容を見ただけだとよくわからなかったです。
sangjeedondrub/tibetan-roberta-baseは「ད་རིང་ཨ་མ་ཤི་བ།」をどうトークナイズするのか

邓宇扬, 吴丹『[面向藏族传统节日的汉藏双语命名实体识别研究](https://doi.org/10.11925/infotech.2096-3467.2022.0698)』(数据分析与知识发现, Vol.7, No.7 (2023年7月), pp.125-135)を読んでいたところ、[sangjeedondrub/tibetan-roberta-base](https://huggingface.co/sangjeedondrub/tibetan-roberta-base)というチベット語モデルが使用されていた。とりあえず、[昨日の記事](https://qiita.com/KoichiYasuoka/items/1c51fe9bd4ce16476470)の例文「ད་རིང་ཨ་མ་ཤི་བ།」をトークナイズしてみよう。

```
>>> from transformers import AutoTokenizer
>>> tkz=AutoTokenizer.from_pretrained("sangjeedondrub/tibetan-roberta-base")
>>> print(tkz.convert_ids_to_tokens(tkz("ད་རིང་ཨ་མ་ཤི་བ།")["input_ids"]))
['
', 'à½ĳ', 'à¼ĭ', 'à½¢', 'à½²', 'à½Ħ', 'à¼ĭ', 'à½¨', 'à¼ĭ', 'à½ĺ', 'à¼ĭ', 'à½¤', 'à½²à¼ĭ', 'à½ĸ', 'à¼į', '
']
```

う、全てのトークンで1文字目が「à」ということは

```
>>> text="ད་རིང་ཨ་མ་ཤི་བ།"
>>> x=tkz(text,return_offsets_mapping=True)
>>> for i,(s,e) in zip(x["input_ids"],x["offset_mapping"]):
...   print(" ",text[s:e],text[s:e].encode("utf-8"),ascii(tkz.convert_ids_to_tokens(i)))
...
   b'' '
'
  ད b'\xe0\xbd\x91' '\xe0\xbd\u0133'
  ་ b'\xe0\xbc\x8b' '\xe0\xbc\u012d'
  ར b'\xe0\xbd\xa2' '\xe0\xbd\xa2'
  ི b'\xe0\xbd\xb2' '\xe0\xbd\xb2'
  ང b'\xe0\xbd\x84' '\xe0\xbd\u0126'
  ་ b'\xe0\xbc\x8b' '\xe0\xbc\u012d'
  ཨ b'\xe0\xbd\xa8' '\xe0\xbd\xa8'
  ་ b'\xe0\xbc\x8b' '\xe0\xbc\u012d'
  མ b'\xe0\xbd\x98' '\xe0\xbd\u013a'
  ་ b'\xe0\xbc\x8b' '\xe0\xbc\u012d'
  ཤ b'\xe0\xbd\xa4' '\xe0\xbd\xa4'
  ི་ b'\xe0\xbd\xb2\xe0\xbc\x8b' '\xe0\xbd\xb2\xe0\xbc\u012d'
  བ b'\xe0\xbd\x96' '\xe0\xbd\u0138'
  ། b'\xe0\xbc\x8d' '\xe0\xbc\u012f'
   b'' '
'
 ```

ううう、UTF-8のByte-Pair Encodingがナマで使われてる(ただし0x00～0x20・0x7f～0x9fはU+0100～U+0120・U+0121～U+0141へマッピング)上に、母音記号とかが変な形で泣き別れになってる。`decode`は実装されてるかしら。

```
>>> print([tkz.decode(t) for t in x["input_ids"]])
['
', 'ད', '་', 'ར', 'ི', 'ང', '་', 'ཨ', '་', 'མ', '་', 'ཤ', 'ི་', 'བ', '།', '
']
```

一応は動くけど、それでも「ཤི་བ」が「ཤ」「 ི་」「བ」の3トークンに泣き別れになってて、しかも真ん中のトークンがすごく気持ち悪い。こういうの、どうにもならないのかなあ。
回帰分析についてド初心者が調べてみた

この記事は、統計学を全く知らない初心者が「回帰分析」についてまとめてみたものになります。

※「もっとわかりやすい説明あるよ！」「そこ間違ってるよ！」とかあれば、どしどしご指摘いただけると嬉しいです。

# 回帰分析とは
回帰は英語でregression（リグレッション）。「繰り返すこと」というような意味がある。
統計学において「回帰」は、変数同士の関係を調査し、その関係を`Y=f(X)`というモデルに当てはめることを指す。

別の言い方をすると、1つの**目的変数**（従属変数）を1つの**説明変数**（独立変数）で予測することを指す。
>目的変数とは、予測される側の変数のこと。説明変数とは、予測に使う側の変数のこと。
説明変数が原因で、目的変数が結果と表現することができる。
目的変数がアイスクリームの売上で、説明変数が気温、みたいな感じ。（なんか関係ありそうだよね）

回帰分析は、主にこの**2つの変数（説明変数と目的変数）の関係を理解し、未知のデータに対して予測を行うために使用される分析のこと**である。

## なぜ回帰分析が必要なの？
回帰分析は何かしらの出来事やデータがどのように関連しているかを理解し、未来の出来事を予測するのに役立つ。

## 用語整理
回帰分析をしていると出てくる用語について説明する。
### 実測値
実際に測定して得られた実データのこと。
体重計に乗って測定したデータとか。
### 予測値
回帰分析で算出された偏回帰係数を使い、回帰式に準じて計算された値のこと。
例えば、「体重の予測値」を求める場合、目的変数を体重として説明変数を身長と年齢にしたとき、身長と年齢の実測値と偏回帰係数から求められる体重の値を求めることになる。
### 残差
実測値と予測値の差のこと。
残差が小さいほど予測値と実測値の差が少ないということになるので、精度の高い回帰分析ができているということになる。
### 偏回帰係数
どの説明変数が目的変数に影響しているのかを知ることができるもの。
また、回帰式の中の傾きを表す係数のこと。「重み」とも呼ばれる。
### p値
仮説検定（自分が設定した仮説が正しいかどうかを統計的に判定する方法）において、統計量がその値以上または以下になる確率のこと。
回帰分析結果の中のp値をみることで、どの説明変数が目的変数に影響しているのか知ることができる。
p値が低いほど、統計量がその値になる確率が低い。
### 決定係数
説明変数が目的変数のどれくらいを説明できるかを表す値。
0から1までの値をとります。1に近いほど、回帰式が実際のデータに当てはまっていることを表す。

# 回帰分析の種類
アイスクリームの売り上げを例に説明する。
## 単回帰分析と重回帰分析
説明変数がいくつかを考えるもの。
### 単回帰分析
1つの要因から結果を予測すること。
![Frame 1 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890419/9ad11ad0-e2e1-5f0b-48fe-b99eea4d7baf.png)

数式で表すと
```y = a + bx```となる。

![回帰分析.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890419/6a623077-1380-6dd9-7c59-6e81339e51ee.png)

方程式の切片に当たるaと、傾きのbを推測することが目標になる。

### 重回帰分析
複数の原因から結果を予測すること。
![Frame 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890419/bb133ca1-23a0-9037-1727-34c65b564b39.png)

数式で表すと
```y = a + b1x1 + b2x2 + ・・・ + bnxn ```となる。

# 実用例
## マーケティング施策の分析
ある会社のマーケティング部門に所属しているA3は、担当製品の売上アップのための施策を考えています。
候補は以下の3つ。
- 広告費の増加
- 製品価格の見直し
- お得キャンペーンの開催
過去の会社のデータから、どの施策も効果があることはわかっています。

Aさんはそれぞれが売上にどのように影響しているか、重回帰分析を行い調べてみることにしました。

最初に決定係数を確認してみると、決定係数は0.46ですのでまずまずのモデルだと言えそうです。
またp値は全て0.05を下回っていますので、どの変数も売上に関係があると考えてよさそうです。
次に偏回帰係数をみると、広告費を1万円増やせば売上は1万6千円増え、製品価格を千円上げると売上は3千円下がってしまうようです。
キャンペーンを実施すると11万4千円の売上が上がるようです。
偏回帰係数だけをみると、一見キャンペーンの実施が良さそうに見えますが、どの施策が一番効果的か標準化偏回帰係数をみて確認しました。
標準化偏回帰係数をみると、売上に一番影響を与えているのは広告費のようです。
このことから、優先順位としては広告費を増やすことが1番重要になってきそうだと仮説を作ることができました。

# 参考
https://www.nttcoms.com/service/research/dataanalysis/regression-analysis/

https://www.nli-research.co.jp/report/detail/id=58670?pno=2&site=nli

# 調べてみて
うーん、わかったようなわかってないような。。。
実際に使ってみる場面に遭遇してみないと理解できなさそうです。。。
Golang&PostgreSQL：「Dockerfile」「compose.yml」環境構築

# Dockerfile
alpineを使うことで、軽量なdocker イメージを利用することができます。
基本的にGolangは、マルチビルドな構成のため、FROMが二つあります。
デフォルトの`GOARCH=amd64`を指定してますが、余裕があればさらに軽量の`GOARCH=arm64`を試してみてください。
```Dockerfile
### ビルド用ステージ ###
FROM golang:1.21.4-alpine as builder

WORKDIR /app
COPY go.mod ./
COPY go.sum ./
RUN go mod download
COPY . .
RUN GOOS=linux GOARCH=amd64 go build -o main .

### 開発用ステージ ###
FROM golang:1.21.4-alpine as development

# アップデートとvim,gitのインストール
RUN apk update && apk add vim git

# sqlcのインストール
RUN go install github.com/sqlc-dev/sqlc/cmd/sqlc@v1.22.0

# migrateのインストール
RUN go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest

# /appに移動
WORKDIR /app

# builderからmainをコピー
COPY --from=builder /app/main .

# airのインストール
RUN go install github.com/cosmtrek/air@latest
CMD ["air"]
```

# compose.yml
GolangからPostgreSQLへの接続に失敗しないための構成であり、リトライ処理や依存関係を意識してます。
```compose.yml
version: "3.8"
services:
  web:
    build:
      context: .
      target: development
      dockerfile: ./docker/golang/Dockerfile
    ports:
      - "8081:8080"
    volumes:
      - .:/app
      - go_cache:/root/.cache/go-build # go buildのキャッシュを永続化
    depends_on:
      db:
        condition: service_healthy # dbサービスが「healthy」（健全）状態になるまで起動
    restart:
      on-failure # サービスが失敗した場合、再起動します。

  db:
    image: postgres:14
    volumes:
      - db_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: Passw0rd
      POSTGRES_DB: db
      TZ: Asia/Tokyo
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"] # PostgreSQLが準備完了しているかチェック
      interval: 10s # チェックのインターバル
      timeout: 5s # チェックのタイムアウト
      retries: 5 # リトライの回数
      start_period: 10s # コンテナ起動後、ヘルスチェックを開始するまでの時間

volumes:
  go_cache:
  db_data:
```

# 実行コマンド

## go
```go
go mod init golang_docker
go mod tidy
```

## docker compose
```sh
docker compose build
docker compose up -d
```

## マイグレーション(migrateコマンド)
```sh
docker compose run --rm web migrate -path /app/db/migration create -ext sql -dir db/migrations -seq users
docker compose run --rm web migrate -path /app/db/migration -database "postgres://postgres:Passw0rd@db:5432/db?sslmode=disable" up
docker compose run --rm web migrate -path /app/db/migration -database "postgres://postgres:Passw0rd@db:5432/db?sslmode=disable" down
```

## クエリファイル生成(sqlcコマンド)
```sh
docker compose run --rm web sqlc generate
```

## PostgreSQL
```sh
# 接続
docker compose exec db psql -U postgres -d db
\dt
\d users
```
DockerコンテナでMySQLに接続できないとき

# 初めに

データベースをコンソールで確認しようとしたら、エラーが起きたので書きます。

# 問題

コンテナ内部でrails dbを実行したところ、以下ログが表示されてMySQLに入れない状況になりました。

```bash
rails db

Couldn't find database client: mysql, mysql5. Check your $PATH and try again
```

# 解決方法

原因は、Dockerfileにmysql-clientをインストールできていないから。
3行目にRUN apt-get update -qq && apt-get install -y default-mysql-clientを追加。

```bash
FROM ruby:3.1
ARG RUBYGEMS_VERSION=3.3.20
RUN apt-get update -qq && apt-get install -y default-mysql-client

以下省略
```

修正したら、docker compose build でビルドをしてコンテナを立ち上げる。

```bash
/rails_practice# rails db
Enter password: 
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 8.0.35 MySQL Community Server - GPL

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

```

MySQLに入れました！

# 終わりに

Dockerの設定ファイルなど、理解が浅いので購入した「Docker絵とき入門」を読んでみたいと思います。
【Rails】選択画像のプレビューを動的に表示させる

画像のプレビュー機能をシンプルに書きたいと思い、JavaScriptのFileReaderで実装しました。メモとして残します。

# やりたいこと
1. input tyupe="file"の`ファイルを選択`ボタンをクリックして画像ファイルを選択する。
1. プレビュー枠の画像が選択した画像に置きかわる。

# 実装環境
- Ruby on Rails
- Slim
- Carrier wave
- JavaScript

# 実装コード
必要なコードのみ抜粋します。

```slim
/ form_withのコードの一部
label
  = form.file_field :image, class: 'd-none', onchange: "previewImage(this, 'previewImageField')"
      span.btn.btn-secondary ファイルを選択
    = form.hidden_field :image_cache
    / プレビュー枠
    - if hoge.image.present?
      = image_tag hoge.image.thumb.url, id: 'previewImageField', class: 'img-thumbnail'
    - else
      = image_tag 'no_image.png', id: 'previewImageField', class: 'img-thumbnail'

javascript:
  const previewImage = (input, id) => {
    const file = input.files[0];
    const reader = new FileReader();
    const image = document.getElementById(id);
    reader.readAsDataURL(file);
    reader.onload = () => {
      image.src = reader.result;
    };
  };
```

# 解説
1. fileに選択したファイルのバスを格納する。
1. readerにFileReaderインスタンスを格納する。
1. iamgeにimage_tagを格納する。
1. readAsDataURL(file)でreaderにfileを渡す。
1. readerのonloadイベントで、imageのsrcをfileのバスに置きかえる。

# 参照
[FileReader](https://developer.mozilla.org/ja/docs/Web/API/FileReader)
証明書チェーンは処理されましたが、 信頼プロバイダーが信頼していないルート証明書で強制終了しましたと表示される

このエラーメッセージは、証明書の信頼性に関連しています。以下の手順で問題を解決できるかもしれません。

1. **信頼されたルート証明書のエクスポート:**
   - 証明書を信頼するために、まず、自己署名証明書のルート証明書をエクスポートします。

     ```powershell
     # ルート証明書をエクスポート
     $rootCertPath = "C:\Users\ユーザ名\Desktop\共有フォルダ\CodeSigningCertificate.cer"
     $rootCert = Get-ChildItem -Path Cert:\CurrentUser\Root | Where-Object { $_.Subject -eq $subject }
     Export-Certificate -Cert $rootCert -FilePath $rootCertPath
     ```

2. **信頼されたルート証明書のインポート:**
   - エクスポートしたルート証明書を信頼されたルート証明書ストアにインポートします。

     ```powershell
     # ルート証明書を信頼されたルート証明書ストアにインポート
     Import-Certificate -FilePath $rootCertPath -CertStoreLocation Cert:\CurrentUser\Root
     ```

3. **再度署名:**
   - インポートが完了したら、再度スクリプトに署名を試みてください。

     ```powershell
     # 証明書を読み込み
     $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($certPath, "YourPassword")
     
     # スクリプトにコード署名用証明書を埋め込み
     Set-AuthenticodeSignature -Certificate $cert -FilePath "C:\Users\ユーザ名\Desktop\共有フォルダ\password.ps1"
     ```

この手順を試してみてください。もし問題が続く場合は、証明書の信頼性や設定に関する詳細な情報が必要となります。
[Unity]RiderでデバッグモードにするとUnityでエラーが出る時

# 概要
たまにですが、Riderでデバッグ状態に切り替えるとUnityでエラーポップアップが出て勝手にUnityが二重に起動しようとすることがあります。こうなるとUnity & Riderを再起動してもmacを再起動しても解決しないのでかなり困ってしまいます:sob:

![スクリーンショット 2024-01-21 16.33.42-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/4d888045-53bc-4334-ca87-922fad617a86.png)

```
It looks like another Unity instance is running with this project open.

Multiple Unity instances cannot open the same project.
```

# 解決方法A
 Riderの設定関連が変になっていると発生するようです。SourceTree等でRider関連の設定ファイルの差分を一旦リセットするとエラーが出なくなりました。

# 解決方法B
普段スクショ右側の虫アイコンでデバッグを起動している人は画面上部中央のUnityアイコンから「Unityエディターにアタッチ」を押してデバッグを起動すると、エラーが出なくなり、それ以降は虫アイコンでも大丈夫になる事もあります。
![スクリーンショット 2024-05-12 17.27.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/0248e3e7-35db-0ba9-cd4e-8c5363f4f5cf.png)

# 解決方法C
場合によってはメニューから「ファイル」 → 「キャッシュの破棄」 → 「破棄して再起動」で直る事もあるかもしれません（未確認です。自己責任で試してみてください！）
![スクリーンショット 2024-05-12 17.16.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/ffa73df7-65d9-06f9-4f7a-fdb47c7c2e8c.png)


# 補足
はっきりとはわかりませんが、Unityの画面を表示したタイミングで更新のポップアップが表示されたにも関わらずUnityを終了してしまった時、この現象が起きてる気がします。Unityを終了する時は一呼吸置く癖をつけようと思いました（＝x＝;
window11で日本語キーボードと英語キーボードの切替

# 前振り
CHUWIのGemiBook Xproを使用していて、１０１英語キーボードだと＠の位置や、Enterの大きさがやっぱり気になる。
なのでlogicoolのK270を接続して日本語キーボードとして使っているけど、たまにノートパソコンだけで使いたいときがある。
# やり方
## 入力メソッドの追加
1. [設定] > [時刻と言語] > [言語と地域] に進む。
2. [言語の追加] を選択して、「英語」を追加
3. 追加した言語をクリックし、[言語のオプション] を選択
4. [キーボード] セクションで、[キーボードを追加する] をクリックし、英語キーボードレイアウト（例えば「US」）を確認
## キーボードレイアウトの切り替え
1. Windows キー + スペース キーを押すと、利用可能な入力メソッドが表示
2. スペースキーを押すごとに、英語キーボードレイアウトと日本語キーボードレイアウトを素早く切り替えることができる。

# まとめ
レジストリで併用ができるらしいけど、自分ではうまくできなかったのでこの方法で実施。これで`()`を打つとき困らずに済む。
INSERT,UPDATE文作成

```
home
./csv
./csv/input.csv
./csv/output.csv
insert.py
insert2.py
update.py
```

```python:insert.py
import pandas as pd

# CSVファイルのパス
csv_file_path = './csv/input.csv'

def create_insert_query(table_name, columns, values):
    # バルクインサートクエリの作成
    formatted_values = ', '.join(['(' + ', '.join([f"'{str(val)}'" for val in row]) + ')' for row in values])
    query = f"INSERT INTO {table_name} ({', '.join(columns)}) VALUES {formatted_values}"
    return query

def main():
    # CSVファイルからデータを読み取り
    data_frame = pd.read_csv(csv_file_path)

    # バルクインサートを実行するテーブル名
    table_name = 'your_table_name'

    # バルクインサート用のクエリを作成
    insert_query = create_insert_query(table_name, data_frame.columns, data_frame.values.tolist())

    # 作成したクエリを表示（確認用）
    print(insert_query)

if __name__ == "__main__":
    main()

```

```python:insert2.py

import csv

tablename = 'table_name'

def process_csv_in_batches(file_path):
    with open(file_path, 'r', newline='', encoding='utf-8') as csvfile:
        data_rows = ""
        csv_reader = csv.reader(csvfile)
        header = next(csv_reader)  # ヘッダーを取得
        column = ",".join(header)
        insert = f"INSERT INTO {tablename} ({column}) VALUES "

        for row in csv_reader:
            data_row = ""
            for data in row:
                data_row += f",\'{data}\'"
            data_rows += f"({data_row[1:]}),"

    write_to_csv('./csv/output.csv', insert + data_rows[:-1])

def write_to_csv(output_path, data):
    f = open(output_path, 'w')
    f.write(data)
    f.close()

# CSVファイルのパスを指定して実行
csv_file_path = './csv/input.csv'  # あなたのCSVファイルの実際のパスに変更してください
process_csv_in_batches(csv_file_path)

```

```python:update.py
import csv


INPUT_CSV_PATH= './csv/input.csv'
OUTPUT_CSV_PATH = './csv/output.csv'

tablename = 'table_name'
update = f"UPDATE {tablename} SET "
where_flag = False
where = "A = 1"

def process_csv_in_batches(file_path):
    with open(file_path, 'r', newline='', encoding='utf-8') as csvfile:
        csv_reader = csv.reader(csvfile)
        header = next(csv_reader)  # ヘッダーを取得
        data_rows = ""
        data_row = ""
        data = ""
        for rows in csv_reader:
            data_row = ""
            for i, row in enumerate(rows):
                data_row += f"{header[i]} = \'{row}\',"

            if where_flag:
                data += f"{update}{data_row[:-1]} WHERE {where};\r\n"
            else:
                data += f"{update}{data_row[:-1]};\r\n"

    data_rows += data
    write_to_csv(OUTPUT_CSV_PATH , data_rows[:-1])

def write_to_csv(output_path, data):
    f = open(output_path, 'w')
    f.write(data)
    f.close()

# CSVファイルのパスを指定して実行
process_csv_in_batches(INPUT_CSV_PATH)



```
Nuxt Image 導入時の Cannot destructure property 'nuxt' of 'this' as it is undefined. エラー

# はじめに
<!-- 発端や概要を記載 -->
Nuxt3にNuxt Imageを導入してビルドしようとしたところ、
`"Cannot destructure property 'nuxt' of 'this' as it is undefined."`というエラーでつまづいたので、その解決策を共有します。
### 開発環境
* MacOS 13.4.1 (Ventura)
* pnpm 8.11.0
* Vue 3.4.3
* Nuxt 3.9.3
* Nuxt Image 0.7.2

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [原因](#Chapter1)
1. [解決策](#Chapter2)
1. [まとめ](#Chapter3)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# 原因
### Edge版を使っていなかった
[公式ドュメント](https://image.nuxt.com/get-started/installation)によると、動作テスト済みの正式リリースはnuxt/image-edgeとして発行されているそう...... ややこしすぎる！！

> After each commit is merged into the main branch of @nuxt/image and passing all tests, we trigger an automated npm release using Github Actions publishing a @nuxt/image-edge package.


<a id="#Chapter2"></a>
# 解決策
以下のコマンドをターミナルで叩けばOK
```zsh:terminal
# 既に入れている@nuxt/image（ベータ版）をアンインストール
pnpm uninstall @nuxt/image
# 新たに@nuxt/image-edge（正式版）をインストール
pnpm add @nuxt/image-edge
```
最終的に僕のpackage.jsonは以下のようになりました。
```diff:package.json
{
    "dependencies": {
-        "@nuxt/image": "0.7.2",
+        "@nuxt/image-edge": "1.3.0-28427865.ae93934",
    }
}
```

<a id="#Chapter3"></a>
# まとめ
デフォルトがベータ版(テスト版)で、オプトアウトしないと正式リリース版にならないパッケージに初めて遭遇しました。
より多くのユーザーにバグなどを発見してもらい、改善速度を上げるための取り組みだと思います。
それに気づいた僕は、「そのうちコントリビューターとしてパッケージを作る側に回るんだ！」と心に決め、静かにベータ版からオプトアウトしてしまいました...
精進します。

<a id="#reference"></a>
# 参考文献

https://image.nuxt.com/get-started/installation

https://stackoverflow.com/questions/74936551/nuxt-fatal-error-typeerror-cannot-destructure-property-nuxt-of-this-as-it-i
Visual Studio CodeのRemote SSHでAWSのEC2インスタンスに繋がらなくなって、なんとかなった

# 環境
- クライアント側
    - Macbook Pro
    - Visual Studio Code
- リモート側
    - Amazon Linux t2.microインスタンス(無料枠のやつ)


# 問題の内容
いつも通りVisual Studio CodeのRemote SSH拡張機能からSSH接続しようとしたら繋がらない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1152756/dddf1c74-7668-e000-1a20-436109e0db94.png)

コンソール上でインスタンスが起動してることも確認済みだが、インスタンス上にはログなし。
VSCode側のエラーは以下。

```bash
[16:30:29.072] > local-server-2> Running ssh connection command: "-v -T -D 50014 -o ConnectTimeout=15 aws-linux"
[16:30:29.073] > local-server-2> Spawned ssh, pid=4314
[16:30:29.076] stderr> OpenSSH_9.4p1, LibreSSL 3.3.6
[16:30:44.083] stderr> ssh: connect to host **.***.***.*** port 22: Operation timed out
[16:30:44.084] > local-server-2> ssh child died, shutting down
```

通信がグローバルIPに到達してない。

`~/.ssh/config`を確認したところ起動中のインスタンスのグローバルIPアドレスとconfigに記載されているIPアドレスが違っていた。ので~/.ssh/configの内容を今のIPアドレスに書き換え。

```config
Host aws-linux
    Hostname ***.***.***.***
    User ec2-user
    Port 22
    IdentityFile ~/path/to/key.pem
```

インスタンスにElastic IPがアタッチされておらず、DynamicにIPが変わってたので、config書いた当初と今とでIPが変化していてSSHで接続できなかった。そりゃそうだ。
【node.js】Sequelizeによるデータベース操作

##  はじめに
Sequelizeとは、TypeScriptまたはNode.jsで使用できるORM(Object-Relational Mapping)ライブラリで、簡単に言うと「**データベース(DB)を簡単に操作できるようにするライブラリ**」になります。

この記事では、自分用によく使うコマンドや、その概要を説明します。

https://sequelize.org/

### 全体の流れ

| 見出し                       | 詳細                                                |
|------------------------------|-----------------------------------------------------|
| [インストールと初期化](#インストール・初期化)         | Sequelize・データベース導入とフォルダのセットアップ |
| [DBの作成と消去 (db:create)](#DBの作成と消去)    |                                                     |
| [モデルの作成 (db:model)](#モデルの作成)       | DBのひな型の作成                                    |
| [マイグレーション (db:migrate)](#マイグレーション) | DBの変更を管理するファイルの作成・更新              |
| [初期データの挿入 (db:seed)](#初期データの挿入)    | seederによるテスト用データの挿入                    |

### 想定環境
- Docker
- MySQL
- Node.js
- Sequelize

## インストールと初期化
Sequelizeを使用する前に必要になるセットアップを一通り説明します。
### ライブラリのインストール
Sequelizeを使用するうえで必要になるライブラリをインストールします。
```code:bash
npm install sequelize sequelize-cli mysql2
```

### フォルダのセットアップ
initコマンドを入力すると、カレントディレクトリに必要なフォルダ一式(config・migrations・models・seeders)が作成されます。
```code:bash
sequelize init
```

### データベースとの接続
(執筆中)

## DBの作成と消去
### DBの作成
createコマンドを使用します。
```code:bash
sequelize db:create
```

### DBの消去
dropコマンドを使用します。

```code:bash
sequelize db:drop
```

## モデルの作成
DB内でのデータの構造を定義したものを「モデル(model)」と呼びますが、ここではモデルの作成方法を説明します。

### テンプレートの作成
model:createコマンドを使用すると、テンプレートから簡単にモデルのファイル作成を行うことができます。
ここでは、モデル名を「User」とし、文字列型の「user_str」と数値型の「user_int」という属性(attribute)を設定しました。

```code:bash
sequelize model:create --name User --attributes user_str:string,user_int:integer
```
:::note info
モデル名にはUpper camel caseの名詞複数形、属性にはsnake caseの使用をオススメします。
:::

:::note warn
引数attributesの間に空白を入れるとエラーになります。
ex) ``--attributes user_str:string, user_int:integer``
:::

### モデルファイルの編集
上記で作成したモデルのファイルを編集します。
(執筆中)

## マイグレーション
モデルファイルから、DBの変更を管理する「マイグレーションファイル」を作成します。
マイグレーションを行うことで、DBの一貫性を保ちながら内部の変更ができるようになります。

```code:bash
sequelize db:migrate
```

バージョンを戻す場合はundoコマンドを使用します。
```code:bash
sequelize db:migrate:undo      # 一つ前に戻る
sequelize db:migrate:undo:all  # 全てやり直す
```


## 初期データの挿入
Sequelizeには、テスト用にサンプルのデータを追加できる「シーディング」という機能があります。
ここでは、シーディングのやり方を説明します。

### シードファイルの作成
以下のコマンドを実行することでサンプルデータを登録するシード(seed)ファイルを作成します。
ここでは、ファイル名をtest-usersと指定しました。

```code:bash
sequelize seed:generate --name test-users
```

### シードファイルの編集
(執筆中)

### シードデータの挿入
用意したシードファイルを使用して、DBにデータを挿入します。
```code:bash
sequelize db:seed:all
```

やり直す場合はundoコマンドを使用します。
```code:bash
sequelize db:seed:undo      # 一つ前に戻る
sequelize db:seed:undo:all  # 全てやり直す
```

## おわりに
この記事では、Sequelizeのよく使うコマンドや、その概要を説明しました。
執筆中と書かれている箇所については、後で追記する予定です。その他も必要に応じて書き足すかもしれません。

## 参考文献
https://zenn.dev/shinkano/articles/178cceea60c249

https://qiita.com/y4u0t2a1r0/items/fb7a879cdd2a187bad29

https://ja.wikipedia.org/wiki/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%A2%E3%83%87%E3%83%AB

https://qiita.com/hare-systems-ryo/items/73db197a82100d18bb3f

https://qiita.com/furi-kake/items/c47b098cdcf053bcf287#%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E6%8C%BF%E5%85%A5%E6%BA%96%E5%82%99
約1年半の現場業務で学んだことの振り返り

# 初めに
今回の記事では約１年半参画していた現場を退場（プロジェクト凍結のため）したんので、次の現場にも活かせるような知識、経験などの振り返りもかねて記事に書いていこうと思います。（未経験からIT業界に入り本プロジェクトが初現場でした。）

## 1.参画した現場の概要
##### 案件内容：人事管理システムの周辺領域に関するアドオン開発の改修
##### 環境：フルリモート
##### 担当：テストチーム（約一年）開発チーム（約半年）
##### 言語・主使用ツール：Java(SpringBoot)/PostgreSQL/Intellij/HeidiSQL/GoogleSpreadSheet/Excel/Redmine/AWS(CodeCommit/Codepipeline/CloudWatch/Cognito)

## 2.本現場で学んだこと
* 報告の重要性
まず初めに「報告の重要性」です。この点は開発チームに移動した後にリーダーの方々から口酸っぱく言われたのは **「憶測で話すのではなく事実ベースで論理的に話す」** です。例えば期限が遅れた場合に、謝るよりも「なぜ間に合わなかったのか」、「こういう理由でいついつまでに終わる」など具体的に原因・いつまでに終わるかなどを明確、論理的に報告するや、修正の影響範囲で「こういうコードだからここには影響がない」などの「判断した裏付け」を論理的・筋が通った話しをするなどです。
上で記載した話に通ずる所もあるのですが一番勉強になったのは **「報告が上手くなければ技術力があっても評価されない」** という言葉でした。
* 設計書・要件定義の大切さ
次は「設計書・要件定義の大切さ」です。設計書・要件定義が甘かったこともあり間違った認識で実装していたため修正が必要になったり、”バグ”なのか”要望”なのかを判断できず全てバグとして処理していたので対象が膨大になってしまったなどの事がありました。設計書・要件定義がしっかりしていれば「そこは”要望”なので今回は修正の対象ではないです」と断れてバグ修正の対象数もかなり減ったかなと思います。
* 定期的な振り返りの重要性（各週の良かった事・反省・改善点の振り返り）
次は「定期的な振り返りの重要性」です。現場作業に追われていても各週決まった時間にその週の **良かった点** **反省点** **改善方法** などを振り返る事で少しづつでも業務が向上していき結果的に楽になるという点です。

## 3.まとめ
今回の現場はＩＴ業界に入っての初の現場だったこともあり学ぶことが沢山あり大変いい経験になりました。また各チームでのリーダー、メンバーにも恵まれ、とても良い環境でした。今回の現場で学んだことを活かして今後の現場でも頑張っていこうと思います。
【個人開発】理想のスーパー銭湯をいち早く見つけるアプリ「スーパー銭湯マッチング」をリリース！

個人開発したアプリ「スーパー銭湯マッチング」をリリースしました。

iOS 
https://apps.apple.com/au/app/%E3%82%B9%E3%83%BC%E3%83%91%E3%83%BC%E9%8A%AD%E6%B9%AF%E3%83%9E%E3%83%83%E3%83%81%E3%83%B3%E3%82%B0/id6471331298
Android 
https://play.google.com/store/apps/details?id=com.abebebe.onsen_maching&hl=ja&gl=US

ReactNativeとfirebaseのみで開発し、なるべく効率的に開発することをメインに実現しました。

今回は、アプリの内容と開発に至った経緯を紹介していこうと思います。
これから個人開発をしていこうと思っている方の参考になれば幸いです。

# アプリ「スーパー銭湯マッチング」とは？

好みのスーパー銭湯の設備や趣向から、
近い順にそれに合うスーパー銭湯を提案するアプリです。

アプリを開くと、以下のように18ほどの選択肢が出てきます。
![スクリーンショット_2024-01-21_15.26.03-removebg-preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680893/098dbb59-e588-1e9b-aaba-22c32da7ab8d.png)
![スクリーンショット_2024-01-21_15.33.34-removebg-preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680893/e122b4be-18ff-4e0f-dc99-6160a6bc8664.png)


もしくは、「目的から」を選択して大雑把に選択することもできます。
![スクリーンショット_2024-01-21_15.32.10-removebg-preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680893/93d57498-a992-9920-bd92-4351769bc3b3.png)

選択肢には、
岩盤浴の有無、サウナ、ロウリュウ（蒸気で大量発汗できるイベント）などが選択できます。

個人的には、塩サウナや天然温泉などが知りたい項目です^^

## 好みの項目を選択すると、現在地周辺の施設をマッチ度順に表示
↓
好みの項目を選択すると。。
現在地情報から、近い順にマッチ度を計算し、出力します。
![スクリーンショット_2024-01-21_15.41.35-removebg-preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680893/95d9ef5a-2654-b90b-70d3-b4ed121da02e.png)

100%のところが、要望を全て満たしているところ、
それ以外は、一部満たしているところなどです。

高いほど、要望を満たしていることがわかります。

## 施設詳細画面で、その他の設備情報も確認
各施設をタップすると、施設内のその他の情報も確認できます。

行きたい施設があれば、★「お気に入り」をつけることもできます。
![スクリーンショット_2024-01-21_15.53.58-removebg-preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680893/932ccfe5-2304-1927-462d-c4fbb31dea00.png)

# 開発の経緯・競合サービスとの違い

スーパー銭湯マッチングの主な違いは、ユーザーの求めていることから、スーパー銭湯を提案することです。

スーパー銭湯を探す手段として、GoogleMapや、他のアプリはありますが、
それらは、地図を主体としたものです。

私自身、距離の近い施設よりも、自分の望む施設に行きたいと思うことが多くあり、
地図よりも、重視したい項目から提案してもらいたいと思うことがありました。

求めている施設の内容があるのならば、距離は参考程度にわかればいいと思ってました。

そうすると、現状のアプリの地図主体のものではそれを達成できないと感じ、開発に至りました。

スーパー銭湯マッチングでは、そんな「スーパー銭湯好きなユーザーの求めていること」から逆算して、提案できるようにしています。

# 関東50箇所のスーパー銭湯施設を訪れ調査
アプリを作るにあたって、ただ個人開発として、技術に注力した形を作るのは嫌でした。

どうせ作るなら、役立つもので誰かのためになるものを作りたいと思っていました。

前々からスーパー銭湯が好きだったこともあり、何か開発できないかと考えました。

そこで、関東50箇所ほどのスーパー銭湯を周り、
「このスーパー銭湯に訪れる人は何を求めてきているのか」ということを徹底的に考えるようにしました。

結果、ここだけの泉質の良さであったり、炭酸泉の濃さ、天然温泉、サウナなどのこだわりの掛け算が、お気に入りのスーパー銭湯を選ぶ基準になっていると感じました。

では、それを叶えるために、アプリで何ができるか。
それは、現在地情報と、複数の条件からマッチ度順に表示することが一つの解決策だと感じました。

# まとめ
今回は、個人開発のアプリ「スーパー銭湯マッチング」を紹介しました。
現在、登録されている地点は拡大中です。

埼玉県、千葉県、神奈川県、東京（一部）にマッチ可能です。

ふらっとスーパー銭湯に行きたいなと思った時に、ぜひ活用していただければと思います。
きっと、あなたの求めているスーパー銭湯体験が味わえるはずです。

expoの開発で苦労した点などは、以下でまとめていますので、
ReactNativeで開発しようと考えている方は、参考にしてみてくださいね。
https://www.abyblog.online/?tag=expo