OmniAICreator/Qiita-1.07M huggingface dataset:
Recoil の Atom Effects を使ってViewの状態管理からIOに関する処理を剥がしてみる

Reactで軽量な状態管理ライブラリを調べるとRecoilが有力そうなので試してみた。
その際に、LocalStorageや非同期処理でDBに保存する処理などを Atom Effects を利用してView側のロジックから引き剥がせたので、そのコードを簡略化したものを記載しておく。
ほとんど公式と同じです。

### 前提条件
- React: 18.2.0
- Recoil: 0.7.7

### ローカルストレージに永続化させるサンプル実装

- ユーザーは画面で2つの状態のどちらかを選択できる
- 次回以降も反映させるためローカルストレージを用いて状態を永続化する(初回読み込み時に反映）

このような仕様を満たすために、Recoilを用いると次のような実装ができた。

- state.ts // 状態管理用

```state.ts
import { atom } from "recoil";

const localStorageKey = "SAMPLE_KEY"

type SampleType = "A" | "B";

type SampleStateProps = {
  hoge: SampleType;
};

export const SampleState = atom<SampleStateProps>({
  key: "sample",
  default: {
    hoge: "A",
  },
  effects: [
    ({ onSet, setSelf, trigger }) => {
      if (trigger === "get") {
        // 初回読み込み時に実行される

        // ローカルストレージから取得し、値が存在すれば state に反映
        const savedValue = localStorage.getItem(localStorageKey);

        if (savedValue != null) {
          setSelf(JSON.parse(savedValue));
        }
      }

      // state が更新されたら実行される
      onSet((newValue) => {
        // ローカルストレージに保存
        localStorage.setItem(localStorageKey, JSON.stringify(newValue));
      });
    },
  ],
});

```

effects は配列を受け取るようになっており、用途に応じて複数渡すことで、状態が更新された際の副作用の処理などを複数登録しておける。
今回は初回読み込み時の処理と、状態が更新されたらローカルストレージにも反映させるようにした。

- app.tsx // 表示用

```app.tsx
import { useRecoilState } from "recoil";
import { SampleState } from "./state";

const App = () => {
  const [state, setState] = useRecoilState(SampleState);
  const turnToA = () => setState({ hoge: "A" });
  const turnToB = () => setState({ hoge: "B" });

  return (
    <div>
      <p>{state.hoge}</p>
      <div>
        <button onClick={turnToA}>turn to A</button>
      </div>
      <div>
        <button onClick={turnToB}>turn to B</button>
      </div>
    </div>
  );
};

export default App;

```

動かしてみると確かにローカルストレージに永続化し、次回読み込み時も反映された。
View側からは単に状態更新を行っているだけに見えるので、余計なロジックを気にしなくても良くなった。

#### Tips

Effects に配置する処理は AtomEffect を用いて別途関数として定義しておけるので、複数登録する場合は役割に応じて分割しておくと保守しやすいと感じた。

```state.ts
import { AtomEffect, atom } from "recoil";

...省略

const localStorageEffect: (key: string) => AtomEffect<SampleStateProps> = (key: string) => ({setSelf, onSet, trigger}) => {
  const getByLocalStorage = async () => {
    // ローカルストレージから取得し、値が存在すれば state に反映
    const savedValue = await localStorage.getItem(key);

    if (savedValue != null) {
      setSelf(JSON.parse(savedValue));
    }
  };
  if (trigger === "get") {
    // 初回読み込み時に実行される
    getByLocalStorage();
  }

  // state が更新されたら実行される
  onSet((newValue) => {
    // ローカルストレージに保存
    localStorage.setItem(key, JSON.stringify(newValue));
  });
};

export const SampleState = atom<SampleStateProps>({
  key: "sample",
  default: {
    hoge: "A",
  },
  effects: [
    localStorageEffect(localStorageKey),
    // ロギングなどを別途追加する...
  ],
});

```

DBに保存する場合の処理は割愛させていただくが、基本的には onSet の状態更新のイベントを受けて副作用的に更新する。
ただ今回のローカルストレージとは異なり、保存に失敗するケースが発生するので注意が必要になる。

場合にもよるが、DB保存専用の状態を設けて "保存中" | "成功" | "失敗" のような状態で管理しつつ、ユーザーフレンドリーな表示をしつつ、リカバリー可能な処理を設けるのが良いだろう。

見てくださりありがとうございました。
ruby.wasmでrequire_relativeを使えるようにできそうだったので ……

# 背景（と先行事例）
[ruby.wasmでrequire_relativeを使えるようにしたい](https://qiita.com/ledsun/items/3f8ba1ee2699d546c18c)
https://speakerdeck.com/ledsun/load-gem-from-browsr

RubyKaigiのレポート読んでたら見つけて、幾つか気になった点があったので（もうできてるみたいだったけど）ちょっと試してみました

# requrie_relativeを改変すると標準gemの読込ができなくなる
できるよ

require_relative を上書きした時点で呼び出し元のパスが変わるためエラーになるとのこと
るりまにも
> 現在のファイルからの相対パスで require します。

って書いてあるし一見できなさそうではあるけれども、これ絶対パス渡してもちゃんと動くので
```ruby

module Kernel
  alias origin_require_relative require_relative

  def require_relative(path)
    caller_path = caller_locations(1, 1).first.absolute_path || ''
    dir = File.dirname(caller_path)
    file = File.absolute_path(path, dir)

    origin_require_relative(file)
  rescue LoadError
    require_relative_url(path)
  end
end
```

みたいにして、上書き時点で caller_locations でも使って呼び出し元パスを用意しておけば上書きしても多分ヨシ！
スクリプトの`require_relative`全部置き換えるよりかは素直なんじゃないかな

# fetchが非同期関数

fetch？知らない子ですね

…… いやjavascriptはあまり詳しくないというか大分昔に触ったっきりだったのでこう、ね？
XMLHttpRequest とかいう、もはやあまり使われない気がする関数使えば同期/非同期の指定ができるから、こっち使えば行けなくもないでしょというか

# 結果
```ruby
require 'js'

module JSRequireRelative
  module_function
  def import(file)
    @pathlist ||= ['']
    file = "#{file}.rb" unless file.end_with?('.rb')
    path = File.absolute_path(file, @pathlist.last)
    @pathlist << File.dirname(path)
    
    path = ".#{path}" if path.start_with?('/')
    evalfile(path)
    @pathlist.pop
  end

  def evalfile(path)
    jsscript = <<~JAVASCRIPT
      const xhr = new XMLHttpRequest()
      xhr.open('GET', '#{path}', false)
      xhr.send()
      return xhr.response
    JAVASCRIPT

    script = JS.eval(jsscript).to_s
    ::TOPLEVEL_BINDING.eval script
  end
end

module Kernel
  alias origin_require_relative require_relative

  def require_relative(path)
    caller_path = caller_locations(1, 1).first.absolute_path || ''
    dir = File.dirname(caller_path)
    file = File.absolute_path(path, dir)
    origin_require_relative(file)
  rescue LoadError
    JSRequireRelative.import(path)
  end
end
```

実際使うならもうちょっと（特にXHRのとこ）ちゃんと書いた方がいいと思うけど
だいたいこんな感じのをスクリプトの頭に突っ込んでおけば require_relative を（ちょっとお試し程度に）使えるようにできそう
まあWASIにソケットが搭載されれば必要なくなる気もする
require は vender/bundle あたりを対象に同じことする感じになるかな …… ならないかも ……
Python eelをサーバーで動かす（AWS cloud9）

## 前置き
　[eel](https://github.com/python-eel/Eel) は Python を利用した HTML/JS の GUI 制作アプリケーションである。

　eel においては local にて1対1の通信を想定しているため、WebServer上で動かすと、新たなアクセスがあるたびに古いアクセスは途切れるが、制作アプリの動作例としてダウンロードの必要が無い形で提供することを目的として実装の必要が出来たため挑戦した。

## 方法
 1. 環境やコードをすべてcloud9にコピーする
 1. デフォルトだとchromiumが要求されるため、eel.start の modeをFalseに指定する[^1]
 1. デフォルトだとhostが"localhost"に指定されているため、eel.start の host を"0.0.0.0"に指定する[^2]

修正後コード
```Python:app.py
eel.start("index.html", size=(1500, 900), port=8080, mode=False,host="0.0.0.0")
```

## まとめ
- サーバーにchromiumを入れる必要はない
- Bottleのことを知ってたらもっと早く気が付いてた気がする。
- あくまでデモとして最低限動くだけ


[^1]: [eel GitHub README](https://github.com/python-eel/Eel#:~:text=mode%2C%20a%20string%20specifying%20what%20browser%20to%20use%20(e.g.%20%27chrome%27%2C%20%27electron%27%2C%20%27edge%27%2C%20%27custom%27).%20Can%20also%20be%20None%20or%20False%20to%20not%20open%20a%20window.%20Default%3A%20%27chrome%27)
[^2]: [eel GitHub README](https://github.com/python-eel/Eel#:~:text=host%2C%20a%20string%20specifying%20what%20hostname%20to%20use%20for%20the%20Bottle%20server.%20Default%3A%20%27localhost%27)
Cloud Run + gcsfuse で Value too large for defined data type エラーが出たら

Cloud Run で LLM を動かそうとしているのですが、 llama.cpp で GCS 上の weights ファイルに gcsfuse を介してアクセスしようとすると次のエラーが出てデプロイに失敗しました。
参考までに、ファイルサイズは 4GB 程度でした。


```
terminate called after throwing an instance of 'std::runtime_error'
 what(): failed to open /mnt/gcs/xxxx.bin: Value too large for defined data type
```

これはどうやら Cloud Run の実行環境として第 1 世代が選択されている場合に起こるようです。


![スクリーンショット 2023-06-21 22.57.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183066/56ba3eb2-1443-3b88-9a2b-33cd9f54a8f4.png)

条件は把握してないですが、デフォルトにしておくとうっかり第 1 世代で起動するので、明示的に第 2 世代にしておきましょう。
dbtでスプレッドシートから作成したテーブルを参照したときにPermission Deniedになる問題

# いつ起こった？

BigQueryのテーブル作成で作成元をスプレッドシートにした
テーブルの生成は成功し、GCPのBigQueryコンソールでクエリできる状態であった
ローカルで上記テーブルを参照するdbtのsqlを書き, dbt buildをしたときに発生した。


# 発生するエラー
```
Access Denied: BigQuery BigQuery: Permission denied while getting Drive credentials.
```

# 対処法
gcloudコマンドでドライブへのアクセス権を付与する

```
gcloud auth application-default login --scopes=openid,https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/sqlservice.login,https://www.googleapis.com/auth/drive
```

![スクリーンショット_2023-06-21_22_53_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/c28507a1-7daf-ca43-7b87-53bff7a5e670.png)

このような画面が出るので許可する

# 参考

https://docs.getdbt.com/faqs/troubleshooting/access-gdrive-credential
Azure VMでSSL対応のWebサーバを構築する②

<p>今回はVMにSSHでログインしてApacheをインストールして最低限の設定をします。</p>
<p>前回の記事を見てない方は見ることを強くお勧めします。</p>
<a href="https://qiita.com/Negishi_tako/items/c9388a7d7761cb9ec1fd">Azure VMでSSL対応のWebサーバを構築する①</a>
<h1>ログイン</h1>
<p>前回インストールしたTeraTermを開く。（ほかのアプリでもOK）</p>
<p>サーバのパブリックIPアドレスを入れて秘密鍵を選択し、接続...</p>
<p>[ユーザ名@サーバ名]$が表示されたら接続完了</p>
<p>"sudo -su root" でroot権限をもつ</p>
<p>"yum -y install httpd"でApacheをインストール</p>
<p>"service httpd status"で実行状況を確認。実行中になってたらOK（緑っぽい感じ、Runningとか）</p>
<p>インストール完了したら...ブラウザで"http://<サーバのパブリックIPアドレス>"に接続</p>
<p>接続できなかったら...CentOSでは初期状態でファイヤーウォールが有効になっているかも...</p>
<p>"firewall-cmd --zone=public --add-service=http"で80番ポートを開放</p>
<p>"firewall-cmd --zone=public --add-service=http --permanent"で設定を恒久的に設定</p>
<p>"firewall-cmd --reload"設定を反映</p>
<p>もう一回アクセス!!</p>
<h1>ついでに443番ポート(https)を開放</h1>
<p>"firewall-cmd --zone=public --add-port=443/tcp"を実行</p>
<p>"firewall-cmd --zone=public --add-port=443/tcp --permanent"を実行</p>

<h1>まとめ</h1>
<p>今回はApacheのインストールとポート開放だけなのでちょっとボリューム少なめ。次回はSSL関係をやるのでもりもりになるかも。</p>
Python文法まとめ①

## まえがき
仕事でPythonを使用する予定があるため、事前に学習していることをまとめていきたいと思います。
今回は数値と文字列の扱い方と変数の代入までまとめました。

環境について
Mac
Python3.9

## インタープリタの起動
Python3がインストールされている場合、ターミナルで下記コマンドを入力することでインタープリタを起動することができる。
起動すると>>>と表示される。
起動状態でcontrol+D同時押しまたはquit()を入力することで終了することができる。

```java:インタープリタ起動
python3
```

```java:インタープリタ終了
quit()
```

## Pythonで計算
次にPythonで数値の計算をしていきます。
基本的に演算子は他言語と同じで+-*/%等が使用できる。
例
```java:計算
足し算
>>> 3+5
8
引き算
>>> 9-4
5
掛け算
>>>3*2
6
割り算(不動小数点になる)
>>> 10/2
5.0 
除算(割り算した時のあまり)
>>> 7%2
1
累乗
>>> 3**3
27
```

## 文字列の結合
文字列はシングルクォート、ダブルクォート共に使用することができる。
例)`'test'`、`"test"`
'や"を表示したい時はエスケープしたい文字の前にバックスラッシュ(\)をつける。
```
>>> 'can't'
SyntaxError: unterminated string literal (detected at line 1)
>>> 'can\'t'
"can't"
```
文字列も`+`で結合することができます。
```
>>> "テストの点数は"+'95点でした'
'テストの点数は95点でした'
```

## 変数の代入
=一つを使用することで変数に代入することができる
代入だけした場合、次の行も>>> と表示される。
```
>>> height = 159
>>> height
159
```

また、最後に表示した値が`_`に格納される。
```
>>> height = 159
>>> height
159
>>> _
159
```

以上になります。
次回はifやforといった基本的な関数の使い方をまとめていきたいと思います。
Java マルチスレッド処理～Thread編～

２章Thread編です。
本編では、Threadクラスを継承したサブクラスを作成することにより、マルチスレッド処理を簡単なサンプルコードで実践します。
１章Runnable編を読んでなくても十分理解できる内容となっております。
詳しい理屈は置いといて、Threadクラスを用いてマルチスレッド処理を体感したい方は是非読んでください。

- 目次
    - 手順①　Threadクラスを継承したサブクラスを作成します。
    - 手順②　スレッドの呼び出し
    - 実行結果確認


## 手順①　Threadクラスを継承したサブクラスを作成します。
Threadクラスを継承したサブクラスSubThreadを作成し、runメソッドをオーバーライドして、
スレッドが呼び出されたときに実行したい処理を記述します。
今回はfor文が実行されるたびにコンソールに文字を出力し、スレッドを１秒間停止するという処理を記述します。
```java
//Threadクラスを継承したサブクラスを作成
class SubThread extends Thread {
	//startメソッドが呼ばれた際に実行される処理
	public void run() {
		for (int i = 0; i < 3; i++) {
			System.out.println("SubThreadクラスのrun:" + i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
```
### 手順②　スレッドの呼び出し
①で実装したrunメソッドを呼び出すには①のクラスのインスタンスを作成し、startメソッドを呼び出します。
また、Mainクラスでも同じく、for文が実行されるたびにコンソールに文字を出力し、スレッドを１秒間停止するという処理を記述します。
```java
//スレッド処理を呼び出すクラス
class Main {
	public static void main(String[] args) {
		//Threadクラスを継承したクラス（SubThread）でインスタンスを生成
		Thread thread2 = new SubThread();
		//スレッド処理を開始（別スレッドで実行される）
		thread2.start();
		//メインスレッドで実行
		for (int i = 0; i < 3; i++) {
			System.out.println("Mainクラス:" + i);
			//実行ごとに１秒間スリープ
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
```
### 実行結果確認
メインクラスのスレッドとは別にThreadクラスを継承したSubThreadクラスのスレッドが同時に処理を進めていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3484672/2b1f7158-0d8c-c98c-d0d9-45e88891e52c.png)


次回はマルチスレッド処理３章～Executor編～です！
【Fortran】FortranでDFS(深さ優先探索)を実装する

## 概要
深さ優先探索とは、グラフ探索(辺で繋がれた頂点の探索)に使う全探索アルゴリズムの１つです。
単純な２重、３重のDoループによる全探索と比較して、少ない計算量で探索を行うことができます。

深さ優先探索には、スタックによる方法と、再帰関数による方法の２種類の実装方法があります。
今回は、再帰関数を使ってDFSを実装します。


## アルゴリズム
詳細なアルゴリズムは既に多くのWebサイトで解説されていますので、本記事では説明を省略します。
参考として、以下のWebサイトのリンクを記載します。

①：実際の計算手順について、ステップごとの丁寧な解説が載っています。

https://atcoder.jp/contests/atc001/tasks/dfs_a

 ②：上記の①のサイトの問題について、WEBアプリケーションを用いて視覚的にアルゴリズムが理解できます。

https://algoful.com/Archive/Algorithm/DFS

## プログラム例
### 対象とする問題
AtCoder Typical Contest 001のA問題を例にDFSを実装します。

https://atcoder.jp/contests/atc001/tasks/dfs_a

問題としては、迷路のスタートからゴールまでの経路をDFSを使って探索し、ゴールできるならYes、出来ないならNoを出力する問題です。

問題のイメージとしては、前項で挙げた[②の参考サイト](https://algoful.com/Archive/Algorithm/DFS)と同じです。
DFSで経路を調べていく過程を知るためにも、一度見ておくと良いと思います。

### プログラム例
DFSの部分をサブルーチンで定義しています。
注意点として、サブルーチンで再帰関数を定義する場合には、recursiveを頭につける必要があります。

```Fortran
module global_variable
    implicit none
    ! グローバル変数
    character(1), allocatable :: C(:, :)
    integer, allocatable::check_root(:, :)
    integer check_YN, H, W, goal(2)
end module

program ex_DFS
    use global_variable
    implicit none
    integer i, j
    !迷路のデータ入力
    read (*, *) H, W
    allocate (C(H, W), check_root(H, W))
    do i = 1, H
        read (*, '(*(a1))') (C(i, j), j=1, W)
    end do
    !スタート位置の検索
    tate: do i = 1, H
        yoko: do j = 1, W
            if (c(i, j) == 's') exit tate
        end do yoko
    end do tate
    write (*, "(a9,i3,a3,i3,a3)") 'Start = (', i, ' , ', j, '  )'
    !
    check_root = 0
    check_YN = 0
    call move(i, j)
    if (check_YN == 1) then
        write (*, "(a)") 'Yes'
        write (*, "(a9,i3,a3,i3,a3)") 'Goal = (', goal(1), ' , ', goal(2), '  )'
    else
        write (*, "(a)") 'No'
    end if

contains
!深さ優先探索
    recursive subroutine move(i, j)
        integer i, j
        if (i > 0 .and. i <= H .and. j <= W .and. j > 0) then
            !移動先が壁
            if (C(i, j) == '#') return
            !移動先がゴール
            if (C(i, j) == 'g') then
                check_YN = 1
                goal(1) = i
                goal(2) = j
                return
            end if
            !移動先が訪問済：終了
            if (check_root(i, j) == 1) then
                return
            else
                !移動先が道
                check_root(i, j) = 1
                call move(i + 1, j) !下
                call move(i - 1, j) !上
                call move(i, j + 1) !右
                call move(i, j - 1) !左
            end if
        else
            return
        end if
    end subroutine
end

```
20分でまとめる備忘録　Luaで三項演算子的なものの使い方

## はじめに
if文にするほどでもない処理で何気なく三項演算子を使おうとしたところ、Luaに三項演算子はないことを知った。ただし、ほぼ三項演算子と同じ使い方のできる書き方があったのでメモしておく

## 書き方
c#などだと、
`条件 ? "trueのときに返る値" : "falseのときに返る値";`
の書き方がluaだと
`条件 and "trueのときに返る値" or "falseのときに返る値"`
になる

## コード
```lua
local a = 10
local b = 5

local ret = a > b and a or b
print(ret)
> 10    
```
仕様として、以下の表のように値が決まる
|  論理演算子  |  記述例  | 意味  |
| ---- | ---- |---- |
|  and  |  a and b  | aがfalseかnilならaを返し、そうでなければbを返す|
|  or  |  a or b  | aがfalseかnil以外ならaを返し、そうでなければbを返す|

はじめに　`a > b and a` `a > b`はtrueなので、
`true and a or b`→ `a or b` aは数値でfalseではないので、　`a`が入る。となる

## おわりに
Luaはswitch文すらないのだから、三項演算子も当然用意していない感じはある意味好感が持てる気がする。何にしろ一貫した態度は、何というか、許せる気がする。
【Github】パスワードなしでgit pullしたい

システム開発する上で必要不可欠なGit

特に`git pull`コマンドは場合によっては1日に何回も打つことになるのですが、毎回パスワード入力を求められてうんざりしていました。

が、最近はちゃんと設定してパスワードなしで`git pull`するようにしているので、備忘録としてその方法を記事に残そうかと思います。


## ①鍵をつくる

まずは鍵を作りましょう。サーバーにSSHして下記コマンドで鍵を作成します。

```bash
$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_hogehoge
```

これで`~/.ssh/`に`id_rsa_hogehoge`と`id_rsa_hogehoge.pub`が作成されていると思います。

## ②configファイルを編集する

次にconfigファイルを作ります。なくても動く場合もあるのですが、同一サーバーでテスト環境などの複数プロジェクトが動いている場合はちゃんと指定しないと動かない気がします。

というわけで`~/.ssh/config`を編集しましょう。ない場合は作ってもらって大丈夫です。

```vim:~/.ssh/config
host hogehoge
 hostname github.com
 identityfile ~/.ssh/id_rsa_hogehoge
 user git
```

## ③公開鍵をGithubのリポジトリに登録する

次にパスワードなしで`git pull`したいリポジトリに公開鍵を登録しましょう。

公開鍵の登録はブラウザで[Github](https://github.com)の対象のリポジトリに遷移し、Settings→Deploy keysから登録できます。

Add deploy keyと書いてあるボタンが画面右上にあると思うので、そこから登録しましょう。
この時

 - Title ・・・　任意の値
 - Key ・・・ ①で作成した`~/.ssh/id_rsa_hogehoge.pub`の中身

で入力してください。`cat ~/.ssh/id_rsa_hogehoge.pub`で表示されるものをKeyに貼り付ければ大丈夫です。


## ④.git/configを編集する

最後にプロジェクトルートにある`.git/config`ファイルを編集します。
編集箇所は`url = XXXXXX`と書いてある部分で、これを下記のように修正します。

```vim:.git/config
[remote "origin"]
    # 修正前 httpsから始まるものだと動かない
	# url = https://github.com:ユーザー名/リポジトリ名.git
    # 修正後
	url = hogehoge:ユーザー名/リポジトリ名.git
```

`hogehoge`の部分は②で作成した`~/.ssh/config`の`host`の値と同じにして下さい。

これでめでたくパスワードなしで`git pull`できるはずです！


# とても快適になった

というわけでとても開発が快適になりました。めでたしめでたし。

間違っていたらどんどん指摘してもらえればと思います。ありがとうございました！
SupabaseのAPI取得制限に注意しよう

# Supabaseの取得制限に注意しよう
## 背景
SupabaseのJavaScriptクライアントから7000件の配列を取得しようとしたら、明らかに全て取得できていなかった(地図にデータをマッピングしていたため、途中で途切れてるのがわかりやすかった)。
SupabaseのWeb UIからSQLを叩いてみたところ、データ自体はちゃんと7000件あった。

## 調査してみた
> By default, Supabase projects return a maximum of 1,000 rows. This setting can be changed in your project's API settings. It's recommended that you keep it low to limit the payload size of accidental or malicious requests. You can use range() queries to paginate through your data.

https://supabase.com/docs/reference/javascript/select

`By default, Supabase projects return a maximum of 1,000 rows.`ということなので、デフォルトではJavaScriptクライアントで1000件以上を指定しても、APIの制限により無視されるようです。今回は、1000件をはるかに超えるデータ数であるため、大きな影響を受けていたようです(先に計測した1000件分のみ取得できていた)。

## 設定する
`Setting > API`の下部にある以下の設定を変えるだけです(以下は変更済み)。設定自体は簡単にできます。
![スクリーンショット 2023-06-21 21.52.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591669/410ce861-95c3-202f-346b-e03bc0327e78.png)

## 注意点
Supabaseは1ヶ月のデータベースの通信量を記録しており、50GBを超えると追加で料金がかかるようになっています。また、SupabaseのAPIのURLとアクセストークンはクライアントサイドでデータを取得する限り、ユーザに流出してしまうため、データの取得制限を極端に大きくしてしまうことは危険です。そのため上記の公式ドキュメントで述べられているように、悪質なユーザへの対策として初期では1000件となっており、あまり大きな値にしないようにと警告されています。うっかり全データの取得を許してしまった場合、とんでもない料金を請求されるかもしれません、

## 対策
- 行レベルセキュリティで取得できるユーザを制限する
- クライアントサイドでデータ取得を行わない
    - Next.jsは最近サーバサイドに力を入れているので実現できそう
        - App Directory + Server Actionsはかなり安全に扱えそう
    - TanstackやSWRからリクエストする場合は注意
- 実行時にlimitをつけることを忘れない
    - 初歩的だけど非常に重要
    - ただAPI直接叩かれる可能性があるので100%安全ではない


## まとめ
便利でかつ安めのプランで魅力的なSupabaseですが、データベースと直接紐づいたREST APIが存在しているため、セキュリティ的に気をつけるべきところがあります。便利なサービスであることは確かなので、注意しながら使って行きたいですね。
Ansibleのcronモジュールを使ってjobを登録してみた

検証環境
---
コントロールノード・・・RHバージョン8.6にインストールしたansible 2.9.25を使っています
ターゲットノード　・・・RHバージョン8.6

検証内容
---
下記をrootユーザーのcronジョブとして登録する
|分|時|日|月|曜日|実行ユーザー|ジョブ|ステータス|
|---|---|---|---|---|---|---|---|
|30|2|*|*|*|root|/var/maintenance_tool/db_backup.sh|有効|

playbook
---
|オプション|説明|
|---|---|
|*name|キー、アクセスまたは編集するパラメーター名を指定します|
|minute|時間 (分) |
|hour|時間|
|day|日付|
|weekday|ジョブを実行する曜日|
|job|実行するコマンド|
|user|crontab を変更する必要がある特定のユーザー|
|disabled|crontabでジョブをコメントアウトするか|

※は必須項目
```
---
- name: cron db_backup
  cron:
    name: "db_backup"
    minute: "30"
    hour: "2"
    day:  "*"
    month: "*"
    weekday: "*"
    job: "sh /var/maintenance_tool/db_backup.sh"
    user: "root"
    disabled: "no"
  become: yes
```

実行結果
---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3482362/df0a1b62-5615-3105-d54e-fad8956ab47d.png)
◇ポイント
nameで書いたものが、#Ansible:<name>で設定される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3482362/733dff78-2c39-c8a4-bc7f-3fcf58f47710.png)

参考サイト
---
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/cron_module.html
【Git】Fork元のリポジトリのPRブランチをローカルでチェックアウトする方法

### 概要

大規模な改修が進行中のOSSに貢献しようとした場合、特定のfeatureブランチへの変更のみが許可されていることがあります。
そのような状況下でも、Fork元のリポジトリから特定のPRブランチをローカルでチェックアウトし、変更を適用する方法をご紹介します。

### 手順

Fork元のリポジトリをリモートリポジトリとして追加します。 
今回は `upstream` という名前で追加しています。

```bash
# Fork元のリポジトリのURLに置き換えてください
git remote add upstream https://github.com/{original_owner/original_repo}
```

追加したリモートリポジトリの情報を取得します。

```bash
git fetch upstream
```

特定のブランチをローカルにチェックアウトします。

```bash
# branch-name はチェックアウトしたいブランチの名前に置き換えてください
git checkout -b branch-name upstream/branch-name
```

これで特定のfeatureブランチをローカルに持ってきて、そのブランチ上で変更を行うことができます。
【SwiftUI】ランダムで色を作成する

# はじめに
背景色でカラフルにしたい時があると思います。
その際に使える、ランダムで色を作成できるコードを紹介します。

# サンプルアプリ
![Simulator Screen Recording - iPhone 14 Pro - 2023-06-21 at 21.45.10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/4d7c07b7-86ac-8921-08ed-ead495ca0e7b.gif)

# 実装
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        ScrollView(.vertical) {
            VStack(spacing: 5) {
                ForEach(0..<50) { index in
                    Text("\(index)")
                        .frame(maxWidth: .infinity)
                        .frame(height: 80)
                        .background(Color(red: CGFloat.random(in: 0...1), green: CGFloat.random(in: 0...1), blue: CGFloat.random(in: 0...1)).gradient)
                        .cornerRadius(10)
                }
            }
        }
    }
}
```

# ランダムで色を作成してる箇所
```swift
Color(red: CGFloat.random(in: 0...1), green: CGFloat.random(in: 0...1), blue: CGFloat.random(in: 0...1))
```

# おわり
グラデーションをかけるとめっちゃいい感じになりました
zlibでGZIP形式で圧縮された文字列のレスポンスデータをJavaScriptで解凍する

Lambdaで構築されたAPIで返却値が大きいせいでペイロードのデータサイズ制限（6MB以上は制限に引っかかる）に引っかかってしまうとのことで、Lambda側でgzip圧縮されたデータをフロントで解凍する必要が出てきたときに、1~2日くらいハマったので備忘録。

#### Lambdaのペイロード制限について

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/gettingstarted-limits.html

API側は言語はPythonでzlibライブラリを使っていたので、フロント側も同じくzlib.jsを使うことに。

https://github.com/imaya/zlib.js/

# いざ、実装！！ 

#### 以下の記事を参考に実装してみる。

https://qiita.com/sszzszsz/items/36076d263b5ddd80c1b7

### 実装中にハマった部分

①Pythonでbase64エンコードされた文字列をJavaScriptでbase64デコードすることがまずできず、はまる。。。

②デコードできるようになったが、、、zlib.jsでungzipできない。。。

## Pythonでbase64エンコードされた文字列をJavaScriptでbase64デコードする

1日くらい検索したがなかなか見つけられず、、、ようやく見つけたのが以下、

https://juejin.cn/s/base64%20encode%20in%20python%20decode%20in%20javascript

### NG

```python
baseString = 'hogehoge'
encodedString = baseString.encode()
base64encodedString = base64.b64decode(encodedString)
responseString = base64encodedString.decode()

return responseString
```

```javascript

//responseから取得したbase64エンコードされた文字列
const base64encodedString = "SGVsbG8sIHdvcmxkIQ=="; 
const base64decodedString = atob(base64encodedString)

```

記事によると、Pythonでエンコード時に `ascii` 指定をしてからbase64エンコードしないととJavaScriptでは正しくデコードできないとのこと。

JavaScriptはそのままで、Python側を変更

### OK

```python
baseString = 'hogehoge'
encodedString = baseString.encode('ascii')
base64encodedString = base64.b64decode(encodedString)
responseString = base64encodedString.decode('ascii')

return responseString
```

### zlib.jsでungzipできないのでpako.jsでungzipする

なんで同じzlibなのに、、、試行錯誤の末、ライブラリを `pako` 変えてみた。
もともと、SessionStorageを格納する際にデータ圧縮するライブラリとしてつかっていたものでGzip解凍ができるとのことでやってみたらうまくいった。

zlibベースの高速なデータ圧縮・解凍ライブラリとのことでライセンスはMITです。

https://github.com/nodeca/pako

#### 実装

```python
import zlib

baseString = 'hogehoge'
encodedString = baseString.encode('ascii')
compressedData = zlib.compress(encodedString)
base64encodedString = base64.b64decode(compressedData)
responseString = base64encodedString.decode('ascii')

return responseString
```

```javascript

const unescapeUnicode = (str: string) => {
  return str.replace(/\\u([a-fA-F0-9]{4})/g, function(x, y) {
    return String.fromCharCode(parseInt(y, 16))
  })
}

const handleUnGzipData = (responseCompressed: string) => {
  try {

　　 // base64エンコードされたgzipの文字列をbase64デコード
    const gzipedData = atob(responseCompressed)

　　 // 解凍するには文字列をバイナリにする必要があるのでバイナリ変換
    const gzipedDataArray = Uint8Array.from(gzipedData, c => c.charCodeAt(0))

    // gzip解凍
    const ungzipedData = pako.ungzip(gzipedDataArray, { to: 'string' })

　　// Unicodeエスケープシーケンスで日本語に戻す
    const output = unescapeUnicode(ungzipedData)

　　// 文字列をオブジェクト変換
    const responseObject = JSON.parse(output)

    return responseObject
  } catch (error) {
    return ''
  }
}

```

勉強になりました。
【神アプデ】骨伝導イヤホンShokz、ついにTeams会議でミュートしてもビープ音鳴らない設定が出現 🎉🎉

# 最初にまとめ
Microsoft Teamsに2023年5月ごろから追加された設定項目「デバイス > デバイスの同期ボタン」をオフにすることで、骨伝導イヤホンShokzを接続して会議中にミュートするとビープ音が鳴り続けていた事象を回避できるようになりました 👏


# おさらい：Shockzユーザーを悩ませていた「Teamsミュート時のビープ音」とは？
耳をふさがず快適にテレワークできる、骨伝導イヤホンの定番製品として大人気のShokz（旧称：AfterShokz）ですが、一つだけ大きな欠点がありました。

https://jp.shokz.com/products/opencommuc

それはMicrosoft Teamsにてオンライン会議中、自分のマイクをミュートにすると数秒おきに大きなビープ音が鳴り続けるというものです。

特に大きめの会社だとMicrosoft 365でOA環境が揃えられており社内の会議は基本Teams、という方もかなり多いかと思います。ECサイト等でもShokzのレビューで必ずといっていいほど登場する話題で、当のShokz的には「仕様」というスタンスであまり対応が期待できないという残念なポイントでした。

利用しているデバイスやTeamsのバージョン等、環境差異によっても再現有無が変わるようでした。
代表的な回避策としては「ブラウザ版のTeamsを使う」「物理ドングルを別途購入する」「ミュートではなくマイクブームを反対に向ける」などで、決め手に欠ける状況でした。


# しれっとTeamsに追加されていた神アプデの詳細
日本語の情報がかなり少ないのですが、実は2023年5月ごろからTeamsに「デバイスの同期ボタン」なる設定項目が出現していた模様です。

https://art-break.net/tech/?p=18189

パッと見、何のための設定が分かりにくいため話題になりにくかったのかも知れません。これを無効にするとShockzのビープ音が解消された！と社内でも話題になっていたため私も気付くことができました。

接続したデバイスからのTeams操作（例：終話やミュート、ボリューム操作など？）を無効にできるオプションのようですが、これはShokz対策なのでは…と勘ぐってしまいますね。
まさか設定画面に「Shockzの方はこちらをお使いください」と書く訳にもいかないでしょうし…（笑）


# 実際の設定手順
Teamsのメインウィンドウ右上のユーザーアイコンより「設定」を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/268d3282-3094-a8ef-87a6-e328bb042161.png)

「デバイス > デバイスの同期ボタン」のトグルボタンをOffにすればOK！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/de2b075d-7d9a-f1d9-25bb-2eb741300ab6.png)

実際にTeams会議でマイクオフにしても、なんとビープ音が鳴らなくなりました！！感激 😂
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/c8321561-bd0d-2524-6f82-4d1508d1e3ed.png)
ソースコードのレビューに時間をかける必要性

仕事の中で、PMや若手の教育もします。

さて、**若手の教育をしている時に一番悩むのは、「若手のスキルアップをどう効果的にやるか」ということ。**
若手が同じようなスキルや考え方を持っていれば、プロジェクトチームでの開発はカンタンになっていきます。
逆に、この部分ができていない案件に行くと、同じ仕事をしていても全体の進捗度が変わります。

そこで若手のスキルアップをより効果的にやるために、色々な作業が試されています。
ペアプロや師匠制度などもその一つでしょう。

ただ、どちらも時間がかかりすぎてしまう問題があります。
しかも、ペアプロは効率が良いかと言われると微妙なラインです（作業を他人とずっと一緒にやるのはメンタル的に厳しく感じる人が多いですからね、システムエンジニアなら尚更...笑）

というわけで、今回は私の経験上、効果的だと感じた「ソースコードのレビュー」について書いていきます。
正直、ソースコードレビューは、ペアプロや師匠制度よりも効果的だと思っています。
**なぜなら、レビューのタイミングで先輩と若手で考え方のギャップに気付きやすく、技術の継承がしやすいからです。**

## ソースコードのレビューに時間をかける必要性
最初は時間がかかるかもしれないですが、若手に伝わるレビューをしていると、3ヶ月後、半年後、1年後に効果が出ることを感じられるのでオススメです！！
というわけで、分かりやすいレビューアドバイスをすることが効果的な理由について、3つ紹介します。

**※できれば対面でやると良いでしょう（ドキュメントで指摘をまとめて渡すのは微妙です）**

### コードの修正とスキルの向上が同時にできる

**「一度やってみせる」
ということが大事です。**
ペアプロだと、最初から最後まで一人でやってみるという経験ができないです。

一度やっているから、自分がどういうふうに考えて、先輩とどこにギャップがあるか分かりやすくなります。
* 実際は飛ばせるはずのステップ。
* 後から改修しやすく作れるポイント。

このあたりは、実際に一度やってみないと感覚として残りません。
最初こそ、戻しの時間がかかりますが、慣れてくるとチーム内でソースコードのクオリティを担保できるようにもなります。
若手によっては、3ヶ月ほど見れば同じようにコードを書ける人材が出てくるので、期間とリソースのバッファが取れるなら推奨します。

また、システムエンジニアのスキル向上を促進します。
経験豊富な先輩エンジニアも若手も同じくです。
2人の違う考え方が出会うことで、新しいアイデアや効果的なアプローチに気付く機会にもなります。

### チームの一貫性を維持
一貫性のあるコーディングスタイルやベストプラクティスは、可読性の向上やメンテナンスの容易さに繋がります。
プロジェクトチームのガイドラインに従ってコードを修正することができ、プロジェクト全体の品質向上ができますね。

### さいごに
どうでしょうか？
ソースコードのレビュー時に時間をかけて、若手にわかりやすいアドバイスすることは非常に効果的です。

エンジニア同士の成長にも繋がりますし、品質の高いコードを作成するための近道になります。
また、チーム一貫性を維持するためにも重要な要素です。

https://www.amazon.co.jp/%E3%83%AA%E3%83%BC%E3%83%80%E3%83%96%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89-%E2%80%95%E3%82%88%E3%82%8A%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%A7%E5%AE%9F%E8%B7%B5%E7%9A%84%E3%81%AA%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-Theory-practice-Boswell/dp/4873115655
[AWS Q&A 365][ECS]AWSのよくある問題の毎日5選 #84

# 1. Amazon ECSとAWS Fargateにはどのような監視ツールが利用可能ですか？ 
答え：Amazon ECSはCloudWatchのメトリクス、ログ、イベントなどの内蔵監視およびロギングツールを提供しています。また、Datadog、New Relic、Sysdigなどのサードパーティ製の監視ツールも使用できます。

# 2. AWS Fargateで実行中のタスクのパフォーマンスをどのように監視できますか？ 
答え：CPU使用率、メモリ使用率、ネットワークI/OなどのCloudWatchメトリクスを使用してタスクのパフォーマンスを監視できます。また、タスクが生成したログを監視するためにCloudWatch Logsも使用できます。

# 3. 特定のメトリクスが閾値を超えたときに通知を受けるようにアラームを設定できますか？ 
答え：はい、特定のメトリクスが閾値を超えたときに通知を受けるようにCloudWatchのアラームを設定できます。たとえば、CPU使用率が80％を超えたときに通知を受けるようにアラームを設定できます。

# 4. AWS Fargateで実行中のサービスの健康状態をどのように監視できますか？ 
答え：ECSサービススケジューラとElastic Load Balancer（ELB）を使用してサービスの健康状態を監視できます。サービススケジューラは不健康なタスクを自動的に置き換え、ELBはタスクの健康状態を確認するヘルスチェックを行います。

# 5. AWS Fargateで実行中のクラスターのリソース利用状況を監視できますか？ 
答え：はい、CPU使用率、メモリ使用率、ネットワークI/OなどのCloudWatchメトリクスを使用してクラスターのリソース利用状況を監視できます。また、クラスターが生成したログを監視するためにCloudWatch Logsも使用できます。
[AWS Q&A 365][ECS]Daily Five Common Questions #84

# 1. What monitoring tools are available for Amazon ECS with AWS Fargate? 
Answer: Amazon ECS provides built-in monitoring and logging tools such as CloudWatch metrics, logs, and events. You can also use third-party monitoring tools like Datadog, New Relic, and Sysdig. 

# 2. How can I monitor the performance of my tasks running on AWS Fargate? 
Answer: You can monitor the performance of your tasks by using CloudWatch metrics such as CPU utilization, memory utilization, and network I/O. You can also use CloudWatch Logs to monitor the logs generated by your tasks. 

# 3. Can I set up alarms to be notified when certain metrics exceed a threshold? 
Answer: Yes, you can set up CloudWatch alarms to be notified when certain metrics exceed a threshold. For example, you can set up an alarm to be notified when CPU utilization exceeds 80%. 

# 4. How can I monitor the health of my services running on AWS Fargate? 
Answer: You can monitor the health of your services by using the ECS service scheduler and the Elastic Load Balancer (ELB). The service scheduler automatically replaces unhealthy tasks, and the ELB performs health checks on the tasks to ensure they are healthy. 

# 5. Can I monitor the resource utilization of my clusters running on AWS Fargate? 
Answer: Yes, you can monitor the resource utilization of your clusters by using CloudWatch metrics such as CPU utilization, memory utilization, and network I/O. You can also use CloudWatch Logs to monitor the logs generated by your clusters.
Git Hub commitとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/b343a85b-f1c6-41f0-a595-42c623494085.png)
１：commitコミット
コミットと読みます。ファイルやディレクトリの変更修正を、リポジトリに記録することです。
commitをすることで、変更修正の時系列の管理が行いやすくなり、変更修正を遡ることもできます。

commitの際は、「どのような変更修正なのか」をわかりやすくするためにメモを添えます。それをコミットメッセージと言います。

２：commitの粒度
commitを細かく行うメリット
commitは細かく行うことを意識しましょう。
たとえば、メッセージの投稿機能を作成します。その際に、ルーティング・コントローラー・ビューの3つのファイルを編集する必要があるとします。まず、ルーティングの作成が完了したらcommitを行います。コントローラーの作成が完了したらcommitと、細かく行うことを、意識します。

細かくcommitをする大きなメリットしては、以下が挙げられます。

①作業の進捗を管理できる
②エラーが起こった際に、どの作業が原因かスムーズに切り分けできる
しかし、実装の途中で都度commitの操作を行うことは、テキストエディタとGitHub Desktopを行き来するため作業の効率が悪くなってしまいます。ある程度まとめて作業をしてから、分けてコミットをすれば効率が良くなります。
cscの作法 その372

# 概要
cscの作法、調べてみた。
opentkのgamewindow使ってみた。
GL.CallList使ってみた。

# サンプルコード

```
using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;

namespace App
{
	class Gwin: GameWindow {
		private int m_displayList;
		double counter = 0;
		int vBufName;
		double[] vBufData = new double[] {
			0.2, 0.2, 0.2,  0.6, 0.2, 0.2,  0.6, 0.6, 0.2,  0.2, 0.6, 0.2,
			0.2, 0.2, 0.6,  0.6, 0.2, 0.6,  0.6, 0.6, 0.6,  0.2, 0.6, 0.6,
			0.2, 0.2, 0.6,  0.6, 0.2, 0.6,  0.6, 0.2, 0.2,  0.2, 0.2, 0.2,
			0.2, 0.6, 0.6,  0.6, 0.6, 0.6,  0.6, 0.6, 0.2,  0.2, 0.6, 0.2,
			0.2, 0.2, 0.6,  0.2, 0.6, 0.6,  0.2, 0.6, 0.2,  0.2, 0.2, 0.2,
			0.6, 0.2, 0.6,  0.6, 0.6, 0.6,  0.6, 0.6, 0.2,  0.6, 0.2, 0.2
		};
		public Gwin(int width, int height, GraphicsMode mode, string title): base(width, height, mode, title) {
			this.VSync = VSyncMode.On;
			vBufName = GL.GenBuffer();
			GL.BindBuffer(BufferTarget.ArrayBuffer, vBufName);
			GL.BufferData<double>(BufferTarget.ArrayBuffer, sizeof(double) * vBufData.Length, vBufData, BufferUsageHint.StaticDraw);
		}
		protected override void OnRenderFrame(FrameEventArgs e) {
			base.OnRenderFrame(e);
			counter += e.Time;
			if (m_displayList == 0)
			{
				m_displayList = GL.GenLists(1);
				GL.NewList(m_displayList, ListMode.Compile);
				GL.Rotate(counter / 5, 0, 1, 0);
				GL.Rotate(counter / 5, 1, 0, 0);
				GL.ClearColor(0.0f, 1.0f, 0.0f, 1.0f);
				GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
				GL.EnableClientState(ArrayCap.VertexArray);
				GL.BindBuffer(BufferTarget.ArrayBuffer, vBufName);
				GL.VertexPointer(3, VertexPointerType.Double, 0, 0);
				GL.Color4(1.0f, 0.0f, 0.0f, 1.0f);
				GL.DrawArrays(PrimitiveType.Quads, 0, 4);
				GL.DrawArrays(PrimitiveType.Quads, 4, 4);
				GL.Color4(0.0f, 0.0f, 1.0f, 1.0f);
				GL.DrawArrays(PrimitiveType.Quads, 8, 4);
				GL.DrawArrays(PrimitiveType.Quads, 12, 4);
				GL.Color4(1.0f, 1.0f, 0.0f, 1.0f);
				GL.DrawArrays(PrimitiveType.Quads, 16, 4);
				GL.DrawArrays(PrimitiveType.Quads, 20, 4);
				GL.EndList();
			}
			GL.CallList(m_displayList);
			this.SwapBuffers();
		}
	}
	class Program {
		static void Main(string[] args) {
			Gwin window = new Gwin(500, 500, OpenTK.Graphics.GraphicsMode.Default, "Test");
			window.Run();
		}
	}
}






```

以上。
SwiftUI List内でGeometryReaderを使用する方法

## List内でのGeometryReaderの問題
下のQiitaの画像を与えられたViewの横幅いっぱいに、正方形でList内で表示したい場合、そのまま適用するとViewが崩れてしまいます。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225372/b9b6df47-e25c-9ac0-beb8-08f84ed4af7a.png">


<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225372/3a3f6f0d-2bc0-c69d-ae4b-4959f0dedd99.png">

```swift
List {
  GeometryReader { geometry in
    AsyncImage(url: url) { image in
      image
        .resizable()
        .frame(
          width: geometry.size.width,
          height: geometry.size.width
        )
    } placeholder: {
      ProgressView()
    }
  }
}
```

## 解決方法

解決方法は簡単で`scaleToFit()`を`GeometryReader`に付与することです。
`.aspectRatio(contentMode: .fit)`でも可能です。

```swift
List {
  GeometryReader { geometry in
    AsyncImage(url: url) { image in
      image
        .resizable()
        .frame(
          width: geometry.size.width,
          height: geometry.size.width
        )
    } placeholder: {
      ProgressView()
    }
  }
  .scaledToFit() // ADD
  //.aspectRatio(contentMode: .fit) // こちらでも良い
}
```

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225372/931a5821-0864-053c-48b9-f3ea50e6ad56.png">

## より綺麗にする(番外編)

上のプレビューだと元の画像の横幅が広いため、横が圧縮されてしまっています。
綺麗に表示するために真ん中をクリップして、正方形で表示していきます。

`.aspectRatio(contentMode: .fill)`や`clipped()`を使って正方形にクリップしています。

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225372/cd2c2833-f0ff-d0b6-3892-320c77fbef69.png">


```swift
List {
  GeometryReader { geometry in
    AsyncImage(url: url) { image in
      image
        .resizable()
        .aspectRatio(contentMode: .fill)
        .frame(
          width: geometry.size.width,
          height: geometry.size.width
        )
        .clipped()
    } placeholder: {
      ProgressView()
    }
  }
  .aspectRatio(1, contentMode: .fit)
}

```
Python3エンジニア基礎試験_模擬試験の復習⑪

# Classの問題

問題文のプログラムを実行した場合の、出力結果を求めよ。

```class.py
class Sample: # Sampleというclassを定義

  c_list = [] # c_listという空のリストを定義

  def add_c_list(self,data): # 1. で解説を記載。
    self.c_list.append(data)

print("出力結果:", end=" ") # 2. で解説を記載。
sample1 = Sample() # Sampleクラスのインスタンスを作成
sample1.add_c_list("データ1") # 3. で解説を記載。

sample2 = Sample() # Sampleクラスのインスタンスを作成
sample2.add_c_list("データ2") # 3. で解説を記載。

for item_data in sample1.c_list: # 4. で解説を記載。 sample2.c_listとしても結果は同じ。
  print(item_data, end=" ")
# 出力結果: データ1 データ2 
```

* 解説
1. `def add_c_list(self, data):`という行では、`add_c_list`というメソッドが定義されています。
メソッドの引数として`self`と`data`が指定されています。
<font color="Red">**`self`は、メソッドが属しているクラスのインスタンス自体を指します。
これにより、メソッド内からそのインスタンスの属性や他のメソッドにアクセスすることができます。**</font>`data`は、メソッドに渡されるデータを表す引数です。
`self.c_list.append(data)`は、`self.c_list`というリスト（`c_list`はクラスの属性）に、引数で与えられた`data`を追加する処理です。
`append`メソッドは、リストの末尾に新しい要素を追加するためのメソッドです。
つまり、このメソッドは、クラスのインスタンスに対して`add_c_list`メソッドを呼び出すことで、引数として渡されたデータを`c_list`リストに追加する役割を持っています。

1. "出力結果:"という文字列を表示します。`print`関数の`end=" "`は、出力の最後にスペースを追加することを意味します。

1. `sample1`の`add_c_list`メソッドに引数"データ1"を渡すことで、"データ1"が`sample1.c_list`に追加されます。同様に、`sample2`の`add_c_list`メソッドに引数"データ2"を渡すことで、"データ2"が`sample2.c_list`に追加されます。

1. `for`ループを使用して、`sample1.c_list`内の要素を順番に取り出し、それぞれを表示します。ループ内では、`item_data`という変数にリスト内の要素が順番に代入され、`print`関数で表示されます。`end=" "`により、各要素の後にスペースが追加されます。

# Classの問題

下記のプログラムの行末のコード「print(x.f(300))」を別のコードに書き換えたい。
同じ出力結果が得られるように書き換えよ。

```class.py
class MyClass:
    """A simple example class"""
    i = 100

    def f(self, i):
        data = 20
        return data * i

x = MyClass()
print(x.f(300))
# print(MyClass.f(x, 300))に書き換える
# 6000
```

* 解説
インスタンスオブジェクトとクラスオブジェクトのそれぞれで関数を呼び出す時のルールが異なることが問題です。
例えば下記のようなことを理解しておく必要があります。

h1 = OrderSheet()
インスタンスオブジェクト.メソッド名（関数の引数）
・h1.checking(x1)

クラスオブジェクト.関数名(インスタンスオブジェクト, 関数の引数)
・OrderSheet.checking(h1, x1)

# Classの問題

出力結果を求めよ。

```class.py
class Dog:

    name  = 'Fido'

    def __init__(self, name):
        self.name = name

d = Dog('Buddy')
print(Dog.name)
# Fido
```

* 解説
`Dog.name` とすることで `Dog` の `class` にある `name` という変数を呼び出すことができます。また、`name` には `Fido` が格納されていますので、`Fido` を出力できます。

# Classの問題

出力結果を求めよ。

```class.py
class DiveIntoCode:
    def __init__(self, teacher, mentor):
        self.teacher = teacher
        self.mentor  = mentor

dic = DiveIntoCode('Noro', 'Miyaoka')
print(dic.teacher)
print(dic.mentor)
# Noro
# Miyaoka
```

* 解説
class をインスタンス変数にする時の問題です。引数は通常、仮引数の部分の前から順番に格納されますが、self は class 自身が格納されているもののため、teacher から格納されます。

# Classの問題

出力結果を求めよ。

```class.py
def scope_test():
    def do_local():
        spam = "local spam"

    def do_global():
        global spam # spam変数がグローバルスコープに存在することを宣言する。
        spam = "global spam"
        
    spam = "nonlocal spam" 
    do_global() # do_global関数が呼び出されている。globalキーワードを使ってspamをグローバル変数として参照している。
    
scope_test()
print(spam)
# global spam
```

* 解説
スコープの問題です。6 行目の global 文で定義した変数は do_global() の外側で定義していることと同義になります。次に 7 行目で spam が更新され、13 行目で spam を出力すると、 7 行目で更新された内容が出力されます。

※　各問題について、解説文を追記予定。
【ChatGPT】ChatGPTの新API「Function Calling」を使ってゲーム作ってみた！【恋愛シミュゲーム制作】

# はじめに
ChatGPTを使って恋愛シミュレーションゲームを作っているものです。
この度発表された新API「Function Calling」に対応してましたので、記事を書いてみました！

## ちょっと広告
「AIと恋するカフェ」について

- ChatGPTを使ったリアルな恋愛シミュレーションを楽しめるゲームです。
- LINEで簡単に遊ぶことができちゃいます。

![](https://storage.googleapis.com/zenn-user-upload/aff5576d1dad-20230621.png)

以下からプレイが可能です。

![](https://storage.googleapis.com/zenn-user-upload/a64ca6001864-20230621.png)

https://line.me/R/ti/p/%40468nyaks

- **キャラクターとの対話形式ではないので、ちゃっかり恋愛シミュレーションゲームとして楽しめちゃいます！**
  - 選択肢が無く、プレイヤーが発言することで物語が進むシステムなので、展開は無限大です。

- 好感度は、あなたがヒロインに対して、共感したり自分のことを話したりすることで上がるシステムにしています！
  - 「summary」と入力すると今の評価が聞けます。現実の恋愛でも必要なスキルをゲームで身につけることができます。

- 展開は始めるたびに少しづつランダムに変化するので、何度も楽しめます。
  - 会話がおかしくなった時も「reset」と入力して最初からやり直せます。

まだ、フォロワーがいません…フォーローお願いします！😭
最初のフォロワーは君だ！！


https://twitter.com/cafeloveai/status/1665421428483674112

# 目次

## 方法

Function Callingを使ってゲームを進行させる方法について解説します。以下はLangchainJSを対象としています。

### 1.関数を定義する

まずは、以下のようにChatGPTに知らせる関数をJsonフォーマットで定義します。
関数は複数個あっても対応可能です。その場合はdescriptionでどの関数を使うべきかを判断してくれます。

ここではユーザーにゲームの結果について送信するという関数を定義しています。

```js
functions = {
  functions: [
      {
        name: "send_game_progress_results",
        description: "The game's progress results should be answered in Japanese.",
        parameters: {
          status: { 
	    type: "string",
	    description: "Describe the status of the game"
	  },
        },
	required: ["status"],
      },
    ],
    // 以下を設定すると強制的にFunctionを使わせることができる
    function_call: {
      name: "send_game_progress_results",
    },
}
```

### 2.関数とメッセージを渡してリクエストする

modelを定義してリクエストします。
optionsに先程のfunctionsを指定することでFunctionをChatGPTが使用することができます。

```js
const model = new ChatOpenAI({
  temperature: 0.9, openAIApiKey: process.env.OPENAI_API_KEY
});

const aiResponse = await model.generate(messages, functions);
console.log(aiResponse)

messages.push(aiResponse)
```
実行結果
```
AIChatMessage {
  text: '',
  name: undefined,
  additional_kwargs: {
    function_call: {
      name: 'send_game_progress_results',
      arguments: '{\n  "status": "ゲームの進行結果"\n}'
    }
  }
}
```

### 3.FunctionChatMessageを追加する

次にメッセージをリクエストする際に、関数を実行した結果であるFunctionChatMessageを追加します。
リクエストは以下のような順番になります

1. HumanChatMessage
2. AIChatMessage
3. FunctionChatMessage
4. HumanChatMessage
...（以下繰り返し）

```js
const functionMessage = new FunctionChatMessage(`'{"status": "success"}'`, "send_game_progress_results")
messages.push(functionMessage)

const response = await model.generate(messages, functions);
...
```

このように1〜3を繰り返すことで、TRPGのようなゲームであってもFunctionCallingを使ったゲームの進行が可能です。

## 良かった点

以前同じような形でプロンプト上で工夫してレスポンスをJson形式にしていましたが、たまに普通の文字列やエラーのJsonが返ってくることがありました。それに比べFunctionCallingはよりエラーが減って安定して使えるようになったのかなと思います。

## つまづきポイント

langchainjsではモデルの呼び出し（generate）をするときに、AIChatMessageの`function_call`が含まれないという仕様になっていました。（誰か直してください…）
追伸：[PR](https://github.com/hwchase17/langchainjs/pull/1709)出しました。

# 終わりに

先日の[アップデート](https://openai.com/blog/function-calling-and-other-api-updates)ではFunction calling以外にも様々な発表がありましたね。
コンテキスト長の増加や価格の低下など嬉しいものばかりでした。今後もますます発展していきそうなこの分野に目が話せませんね。
GraalVMでScala3.3を使って、Androidアプリを作成

# 環境
OS: Windows 11
Android Studio
Google USB Driver
WSL2: Ubuntu 22.04.2

# やり方
https://docs.scala-lang.org/tutorials/scala-on-android.html
ここを参照。ちょっと記事が古いので、現在のバージョンではアプリはScala3.3を使って動きます。

まず、GraalVMをインストールします。
このときバージョンは22.1.0 を選びます。それより高いバージョンではビルドできません。

圧縮されたファイルは、
WSL2上で
```
> explorer.exe .
```
と実行して、UbuntuのカレントディレクトリをWindows上に表示させて、そこにコピーしておきましょう。

展開して、パスを通して、`native-image`がインストールされていないと思うので、インストールします。

あと、gccとg++がいります。インストールします。

ADBはインストールの仕方が書いてありましたが、結局、WSL2上からは接続が確認できなかったので、Windows上でインストールして、使用しました。
WSL2上からもADBでUSB接続してデバイスを確認できた方いらっしゃいましたら教えてほしいです…

とりあえず、下記の分だけ、インストールします。
```
 libasound2-dev (for pkgConfig alsa)
  libavcodec-dev (for pkgConfig libavcodec)
  libavformat-dev (for pkgConfig libavformat)
  libavutil-dev (for pkgConfig libavutil)
  libfreetype6-dev (for pkgConfig freetype2)
  libgl-dev (for pkgConfig gl)
  libglib2.0-dev (for pkgConfig gmodule-no-export-2.0)
(  libglib2.0-dev (for pkgConfig gthread-2.0) )
  libgtk-3-dev (for pkgConfig gtk+-x11-3.0)
  libpango1.0-dev (for pkgConfig pangoft2)
  libx11-dev (for pkgConfig x11)
  libxtst-dev (for pkgConfig xtst)
```

https://github.com/makingthematrix/scalaonandroid/tree/main/helloscala
これをダウンロードします。
```
git clone https://github.com/makingthematrix/scalaonandroid
```
でごっそりといただきましょう。

あとは、
```
cd scalaonandroid/helloscala
```
しておいてから
```
mvn gluonfx:run
```
でアプリを実行してみて

```
mvn gluonfx:build gluonfx:nativerun
```
これで多分デスクトップ環境のネイティブアプリをビルド

```
mvn -Pandroid gluonfx:build gluonfx:package
```

これで目的のAndroidアプリをビルドします。

あとは、APKファイルをADBでAndroid端末へ送ってやれば、インストール完了で、
自分はWSL2上からWindows上にAPKファイルをコピーしてきて、
Windows上から下記のコマンドでAndroidへインストールしました。

```
adb install <path to APK>
```

Logcatは試していないです。

# まとめ
GraalVMを使って、Scalaで書かれたコードで、Androidのネイティブアプリケーションがビルドできました。
記事のとおりやっただけです。(実際にはなん箇所か手間取りましたが…)

# 余談
GraalVMを使うとiOSやデスクトップ環境のネイティブアプリのビルドも行けるのだとかなんとか。
Flutterほどではないかもしれませんが、マルチなプラットフォームを一つの環境で書けてしまうのはありがたいですね。
Scalaにもそういった価値は残されていそうです。
(まぁ、僕はScalaにその価値がなくても使い続けるつもりではいますが)

# 予定
これで、モバイルアプリの作成できることがわかった。
Webのフロントエンドやサーバサイドのアプリケーションの作成を行っていきたい。
(まだ何をするかは未定です…)

以上、長ったらしい記事でした。
Stable diffusion｜便利すぎる拡張機能まとめ（※順次更新）

今回もいま自分がつかってるStable diffusionの拡張機能でよかったものの備忘録です。
突然パソコンが壊れたときの自分や、誰かのためにも役に立てれば幸いです。


# UIの日本語化

とりあえず日本語にしたいって人はこれを入れればOK

https://github.com/AUTOMATIC1111/stable-diffusion-webui-extensions



# 画像縮尺

画像アスペクト比をボタン選択するだけで設定できる便利すぎる拡張機能


https://github.com/alemelis/sd-webui-ar


# Civitai Helper2

CivitAIの情報とつなげることができて、モデルやLOLAのサムネも取得・反映できて大量にデータがある人には感激の拡張機能。

https://github.com/butaixianran/Stable-Diffusion-Webui-Civitai-Helper



# プロンプトセレクター
テキストファイルにプロンプトを仕込むだけで、ボタンを選ぶだけで出力できる神すぎる拡張機能。

https://github.com/blue-pen5805/sdweb-easy-prompt-selector
環境変数の設定(macOSでの対応)(簡易版)

# はじめに
毎回、環境変数を設定する方法を忘れてしまい、その都度、時間がかかっていたので、自分なりに、この記事にまとめています。(なお自分はMackbook AirのPCを使用しています)

# ターミナル上での設定
## 環境変数の設定
① ターミナル上から以下のコマンドを実行し、環境変数を開く。
```:実行コマンド
vim ~/.zshrc
```
② インサートモードで、必要な環境変数を記述する。
```:テンプレート
export NAME='YAMADA'
```
インサートモードへの変更する。（「i」を押せば、編集モードに切り替わります）
必要な環境変数を追加した後、「esc」で編集モードを終えて、「wq」で書き込みを保存する。
※すでに記述してある環境変数を、削除したり、編集したりした場合、他のシステムなどに影響する場合があるので、操作には注意してください。

③ ターミナル上から、環境変数を適応する。
```:実行コマンド
source ~/.zshrc
```

# コード上への設定の場合
## Ruby(Rails)
"ENV["環境変数名"]"で取得することができます。
```:サンプル
onamae == ENV["NAME"]
```

## Javascrpit(Node.js)
"process.env.環境変数名"で取得することができます。
```:サンプル
const onamae = process.env.NAME;
```

# 環境
- OS：macOS 13.4

# 開発フレームワーク
- Rails： 6.0.6.1
- Node.js： v14.21.3

# 本記事における注意事項
- 本記事は、備忘録としてまとめたものになります。
- 他の方の参考になる可能性も踏まえて、一般公開も行なっております。
- また記載内容はすべて、正しい内容が記載されているとは限りません。
- 誤った内容を見つけた場合は、ご指摘をお願いいたします。
【おぼえ書き】Go Fyne で日本語表示をする

# はじめに
Fyneは基本では日本語を扱うことができません。ですが、カスタムテーマを使えば、日本語が扱えるようになると言うことで実際に試してみました。

# 前提条件
OS：Ubuntu22.04LTS
Go：go version go1.20.5 linux/amd64
※ Go言語とFyneはインストール済みとします。

fyneのインストールは、[Fyne Develop Getting Started](https://developer.fyne.io/started)、または、@hibikingさんのこちらの記事[GO言語のGUIライブラリ「Fyne」のインストール方法](https://qiita.com/hibiking/items/58a3e93e67394fa1bb4f)を参考にしてください

# 参考とした記事
Fyne公式のドキュメント
https://developer.fyne.io/
GitHubGist（lusinganderさんの記事）
https://gist.github.com/lusingander/9c30e6b0ac268c6596bcb95b85943c4e

# 準備
## 作成するファイル
    bundle.go　->　フォントデータを登録
    theme.go　->　カスタムテーマの記述
    main.go　->　カスタムテーマを組み込みます
※　全てのファイルもmainパッケージとし、それぞれ必要となるライブラリをインポートしてください

## フォントファイルの準備
今回はlusinganderさんの記事を参考にM+FONTSを利用しています。 url（http://mplus-fonts.osdn.jp/）
※　フォントはレギュラーとボールドの２つのフォントを使用します。
 
## フォントファイルのバンドル
まず、フォントファイルをFyneで使用できるようbundle.goにします。
コマンドは

```
fyne bundle フォントのファイル > bundle.go
```
でOKなはずですが、ここで問題があります、このfyne bundleコマンドは、標準出力へ
「パッケージ文＋インポート文＋バンドルするファイルのデータ」を出力します。
なので、２つ目以降のファイルをバンドルしようとして、
```
fyne bundle ２つ目のフォントのファイル > bundle.go
```
とすると上書きされてしまい、また
```
fyne bundle ２つ目のフォントのファイル >> bundle.go
```
とすると「パッケージ文＋インポート文」が二重になってしまいます。
なので、Fyne公式の「Bundling resource」にある通り
```
fyne bundle -o bundle.go １つ目のフォントのファイル
fyne bundle -o bundle.go -append ２つ目のフォントのファイル
```
とするとうまく行きます。

## カスタムテーマを準備する
これもFyne公式の「Creating a Custom Theme」を参考に、fyne.Themeインターフェイスを実装します。
まず、カスタムテーマの元になる空の構造体を作ります。
```
type myTheme struct{}
```
次に、その後に次の文を書きます。※　コンパイルエラー関連？（私にはよくわかりませんせした。）
```
var _ fyne.Theme = (*myTheme)(nil)
```
そして、fyne.Themeインターフェースを実装します。４つのメソッド（Font・Color・Icon・Size）の全てを実装する必要があります。
※　このコードは、lusinganderさんの物のそのままです。
```
func (*myTheme) Font(s fyne.TextStyle) fyne.Resource {
	if s.Monospace {
		return theme.DefaultTheme().Font(s)
	}
	if s.Bold {
		if s.Italic {
			return theme.DefaultTheme().Font(s)
		}
		return resourceMplus1cBoldTtf
	}
	if s.Italic {
		return theme.DefaultTheme().Font(s)
	}
	return resourceMplus1cRegularTtf
}

func (*myTheme) Color(n fyne.ThemeColorName, v fyne.ThemeVariant) color.Color {
	return theme.DefaultTheme().Color(n, v)
}

func (*myTheme) Icon(n fyne.ThemeIconName) fyne.Resource {
	return theme.DefaultTheme().Icon(n)
}

func (*myTheme) Size(n fyne.ThemeSizeName) float32 {
	return theme.DefaultTheme().Size(n)
}
```
後は、main.goでカスタムテーマをセットします。
```
a := app.New()
a.Settings().SetTheme(&myTheme{})
```

## 終わりに
実際にどうなるかは[lusinganderさんのレポジトリ](https://github.com/lusingander/fyne-font-example)にコードがありますのでそちらを実行してみてください。
fyne公式とlusinganderさんの記事を参考に四苦八苦しながら動かしてみました。もしGo Fyneで日本語を表示してみたい方に参考としてもらえたら幸いです。

ではでは
Gitのブランチ名を変更する

# はじめに

ブランチ名を間違えた/後から変更したいときの手順

状況としては、プッシュ直後でローカルとリモートに差分がない状態


# ローカルのブランチ名を変更

`git branch -m` を使用してブランチ名を変更する。

オプション `-m` はブランチ名の変更

**引数を1つ指定した場合**

```sh:引数1つ
$ git branch -m NEW_BRANCH_NAME
```

- カレントブランチ名を、引数で指定したブランチ名に変更する
- あらかじめ、名前変更したいブランチにcheckoutしておく必要がある
 
**引数を2つ指定した場合**

```sh:引数2つ
$ git branch -m OLD_BRANCH_NAME NEW_BRANCH_NAME
```

- 1つ目の引数で指定したブランチの名前を、2つ目の引数で指定したブランチ名に変更する
- カレントブランチに関わらず指定したブランチの名前を変更できる


既に存在しているブランチ名を指定した場合はエラーとなるが、 `-M` オプションを使用することで強制的にブランチ名を変更することが可能 (もともとあったブランチは消える)

## 参考
[Git - git-branch Documentation](https://git-scm.com/docs/git-branch)


# リモートブランチに反映

ローカルで名前変更したブランチをリモートにプッシュする。

```sh
$ git push -u origin NEW_BRANCH_NAME
```
::: note warn
このとき、リモートの OLD_BRANCH_NAME のブランチ名が変更されているわけではなく、NEW_BRANCH_NAME という別名のブランチが新規作成されていることに注意。

つまり、リモートには変更前のブランチが残ってしまっている。
:::


# リモートに残った変更前のブランチを削除

```sh
$ git push origin --delete 変更前のブランチ名
```

省略形のコマンドは以下

```sh:省略形
$ git push origin :変更前のブランチ名
```

上記のコマンドで、リモートに残った OLD_BRANCH_NAME が削除される

## 参考
[Git - リモートブランチ](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E6%A9%9F%E8%83%BD-%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81#:~:text=%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82-,%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%81%AE%E5%89%8A%E9%99%A4,-%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%81%A7)


# GitHub上でブランチ名を変更する

基本的にはローカルから先に変更するよりも↓の方法が単純でわかりやすい

[ブランチの名前を変更する - GitHub Docs](https://docs.github.com/ja/repositories/configuring-branches-and-merges-in-your-repository/managing-branches-in-your-repository/renaming-a-branch)

GitHub上でブランチ名を変更した後、ローカルの対象ブランチで以下のコマンドを実行

```shell
# リモートで変更したブランチ名に合わせて対象のブランチ名を変更する。
$ git branch -m OLD-BRANCH-NAME NEW-BRANCH-NAME

# リモートの最新の状態をローカルに取得する
$ git fetch origin

# ブランチのリモート追跡ブランチを更新する
$ git branch -u origin/NEW-BRANCH-NAME NEW-BRANCH-NAME

# remote/origin/HEAD の情報をリモートから取得し、ローカルに同期する
$ git remote set-head origin -a
```
Google検索GBPについて

Googleのビジネスプロフィールの下記画像

![スクリーンショット 2023-06-21 192915.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/900926/ddb846a3-f28c-dff7-b92e-4a4a31def442.png)

開業前の店や会社が表示されるのですが、この開業日を設定しているプロフィールだけ検索して、データーに抽出することは可能でしょうか？