OmniAICreator/Qiita-1.07M huggingface dataset:
ESP32-C3-WROOM-02モジュールを使う

# ESP32C3?
ESP32から
- Bluetooth Classic
- DACと要らないピン
- 体積
- 過剰な消費電力
- 値段

を削って
- USB

を足したやつ
BLEとWIFIは普通に使えるので意外とこれでも事足りる
全然熱くならないし安いのでなかなか良いのでは

これを使ったモジュールにSeeduino XIAO ESP32C3があるがスイッチサイエンスで¥900程度する
ESP32-C3-WROOM-02モジュール本体は¥310でUSBとかレギュレータとか諸々足しても¥380で済む
圧倒的である

# 最小構成な開発ボード
部品

- ESP32-C3-WROOM-02
- USB-Aオス
- 3.3Vレギュレータ
- 10kΩ程度の抵抗
- 適当な線材と基板

USBのVBUSをレギュレータで3.3Vに落としてESPの電源にする
データ線は~~面倒なので~~抵抗を挟まずにESPに繋げる
10kΩはチップ抵抗であればESPに直接付けられるので楽


ESP32-WROOM-32が1.27mmピッチなのに対して
ESP32-C3-WROOM-02は**1.5mmピッチ**である
何も考えずに1.27mmピッチの変換基板を買うと1.5mmピッチってなんだよ……になるので注意

配線はこんな感じ
横に並んだ端子を結線する

| USB | レギュ | ESP | 10k |
|:-:|:-:|:-:|:-:|
| VBUS | IN |   |   |
|   | OUT | 3V3 | @ |
|   |   | EN | @ |
| D- |   | IO18 |   |
| D+ |   | IO19 |   |
| GND | GND | GND |   |

こんな感じ
レギュレータは裏に載せた
ESPでやることといえば無線を使った諸々がほとんどなので
ひとまずピンソケット等は全て無しで組み立てた
おまけでLEDをつけてLチカした

https://twitter.com/mcbeeringi/status/1626636221685587968?s=61&t=qt4_TAR1b_oh_J_ySmHHVw

# 開発@ Arduino IDE
## 環境構築
普通のESP32と同じ

https://espressif-docs.readthedocs-hosted.com/projects/arduino-esp32/en/latest/installing.html#installing-using-arduino-ide

``` js
Arduino IDEを開いて
    設定
        追加のボードマネージャURL
            `https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json`をペースト
    ボードマネージャ
        esp32で検索
            esp32 by espressifをインストール
```
USBをさすとCOMポートが自動認識される
ボードはESP32 C3 dev board(なぜか毎回変わる)
書き込みオプションのUSB CDC on bootはEnable(コンソールをUSB経由で見るのに必須)にしておく



## 初回書き込み
買った状態では何も書き込まれていないため無限に
`Invailed Header: 0xffffffff`を吐きながら再起動を繰り返す
USBの抜き差しが高速で繰り返される挙動となりArduinoIDEで書き込もうとするとコンパイルしている間にポートが逃げてしまう
対処法はArduinoIDEの設定から書き込み時の詳細を吐く設定にして**書き込みコマンドをコマンドプロンプトにコピペして実行**
PowerShellだと文法の違いで引っ掛かるのでちゃんとコマンドプロンプトで実行すること
何度か実行すれば書き込める






# その他諸々
## Bluetoothスピーカーが作りたい
例としてbtスピーカーを挙げたがbluetoothでのオーディオの送受信にはa2dpというプロファイルが必要でありこれはbluetooth classicの一部

c3はbluetooth 5.0(ble)でありbluetooth 5.0(classic+ble)ではない
無印はbluetooth 4.3(classic+ble)なのでa2dpが使える
bleは低速省電力特化の規格で高速通信にはclassicが必要

諦めてESP32-WROOM-32Eを買う

## UARTで書き込めない場合
本家ESP32はIO0の上げ下げで起動モードを切り替えた
同様にESP32C3もIO9の上げ下げで起動モードを切り替える
つまり[過去記事の書き込み機](https://qiita.com/McbeEringi/items/d72c793d7fb079dc6997)のIO0をIO9にさせば書き込める
ただし注意するべきは**IO8を上げる必要がある**こと
IO8: LOW, IO9: LOWは未定義なのでどうなっても知りませんよ～ってデータシートにも書いてある
でも買った瞬間からUSB書き込みが可能なのでUART書き込みする場面は存在しないはず
中の人は知らずにUARTで書き込もうとして苦戦した


## USB書き込みで本当にIO8,9の操作は要らない?
要らない
USBで起動モードの変更も自動でやってくれる模様
公式もそう言ってる

https://docs.espressif.com/projects/esp-idf/en/v5.0/esp32c3/api-guides/usb-serial-jtag-console.html#uploading-the-application


## 秋月さんのESP-WROOM-02のブレイクアウトボードは使える?
ピン配置が稀に凄く違うので使えない
具体的には2箇所ほどIOがGNDになっている
片方が運悪くUSBのIOに直撃していたので断念した
ちなみに買ったあとに気付いた

https://twitter.com/mcbeeringi/status/1626614422272892928?s=61&t=qt4_TAR1b_oh_J_ySmHHVw

# おしまい
筆箱にこの手の小さな開発ボードを入れて持ち歩くと気分が上がるのでおすすめ
真のポケットWIFI
優良データサイエンス関連教材をたっくさんまとめてみた【僕の学習記録】

今まで僕がデータサイエンス関連で勉強してきて、良かった教材や無料の教材をまとめました。
今後もどんどん更新していきますので、保存してご活用ください！

# 自己紹介
データサイエンティストを目指して日々勉強している、慶應大学理工学部4年生（2023.12.31時点）

取得資格、コンペ優勝経験など、リアルタイムの情報は👇👇👇をみてね

X: @A7_data←こういう者です。
プロフィールページ👇👇👇

https://mohki7.notion.site/Mototsugu-Oki-c478f842c4de48f394e2e24b58e206bb?pvs=4


# 優良教材まとめ
自分が利用したことのあるもの、利用していないけど良さそうなものを分野別にまとめました。

# 本記事はNoteに移行しました。
こちらの記事をご覧ください。無料で公開しています。

https://note.com/a7_data/n/n2f423f6ee620
Laravel を後からDocker環境にする


LaravelのDocker環境については、
公式でLaravel Sailと言うのがあるみたいです。

https://readouble.com/laravel/9.x/ja/sail.html

------

Laravelを入れたディレクトリに移動して、

```
composer require laravel/sail --dev
php artisan sail:install
```
途中でパスワードの入力を求められるので、パソコンのパスワードを入力。

その後選択画面になるのでインストールしたい項目を入力。
（コンマ区切りで複数入れられるみたいです。）

![スクリーンショット 2023-02-19 0.56.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464795/6acb23e9-d416-e82a-e041-0e909d8cfb46.png)




## phpmyadmin追加

あとphpmyadminを使いたいので、
docker-compose.ymlを開いて以下を追加。

```
phpmyadmin:
      image: phpmyadmin/phpmyadmin
      links:
          - mysql:mysql
      ports:
          - 8080:80
      environment:
          MYSQL_USERNAME: '${DB_USERNAME}'
          MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
          PMA_HOST: mysql
      networks:
          - sail
```

　　　

最後に起動
```
./vendor/bin/sail up
```

これで
http://localhost/
見たらlaravelで、
http://localhost:8080/
見たらphpmyadmin



コマンドが変わるのがちょっとめんどくさいな。
```
// php artisan migrate
./vendor/bin/sail artisan migrate
```
　　　

やっぱりコマンドめんどくさいので、
~/.zshrcに追加

```
alias sail='[ -f sail ] && bash sail || bash vendor/bin/sail'
```
　　　
これでsailコマンドで使えるようになったので、早速npm installする。

```
sail npm install
```
これでviteも使える。


　　
　　　
### phpmyadminの設定を変更する方法
config.user.inc.phpファイルを作って設定を記入して、
docker-compose.ymlのphpmyadminのところに追記
```
volumes:
          - './config.user.inc.php:/etc/phpmyadmin/config.user.inc.php'
```
　　

### phpの設定を変更する方法

```
sail artisan sail:publish
```
これで、vendor/sail/runtime/ 以下にDockerの設定ファイルが出てくるので、
docker-composeファイル見て使ってるバージョンを確認して該当のphp.iniを編集する。

そんでdocker-compose.ymlのlaravel.testのところに追記
（この作業はいらないかも）
```
volumes:
         - '.:/var/www/html'
         - './vendor/laravel/sail/runtimes/8.2/php.ini:/etc/php/8.2/cli/conf.d/99-sail.ini'
```
　　　
　　　

これでDocker作り直したらいけるかな。

```
sail build --no-cache
sail up -d
```



---------
参考

https://iret.media/55966

https://qiita.com/fumikoba3/items/fe8568582cbc229723f5

https://qiita.com/uehatsu/items/63d66d7a37510c6ff1be

https://github.com/phpmyadmin/docker

https://laravel.com/docs/9.x/sail#sail-customization
列と行をドラッグ＆ドロップで入れ替えられるテーブルの実装@Angular

# 1. はじめに
業務用システムなどの開発にあたって、一覧表示するデータの列や行を自由に動かしたいという要望を受けることがあると思いますが、なかなかに実装が大変です。本稿では、Angularを用いた実装のサンプルをご紹介します。


# 2. 列入れ替えの壁
Angularでは`@angular/cdk/drag-drop`というモジュールを導入することで、リスト上に定義されているタグに対してドラッグ＆ドロップを簡単に実装することができます。

このモジュールを用いて、以下のように実装することで行の入れ替えは容易に実現できます。
【参考】 [Angular CDK Drag/Drop List inside a table (not Material Table) - Handle rows distorting width](https://trungk18.com/experience/angular-cdk-drag-drop-list-table/)

```html
        :
        :
    <table>
		<thead>
			<tr>
				<th>#</th>
				<th>First</th>
				<th>Last</th>
				<th>Email</th>
				<th>Address</th>
			</tr>
		</thead>
		<tbody cdkDropList (cdkDropListDropped)="onDrop($event)">
			<tr *ngFor="let user of users" cdkDrag cdkDragLockAxis="y">
				<th>{{ user.order }}</th>
				<td>{{ user.first }}</td>
				<td>{{ user.last }}</td>
				<td>{{ user.email }}</td>
				<td>{{ user.address }}</td>
			</tr>
		</tbody>
    </table>
        :
        :
```


onDrop関数の引数にはCdkDragDropが渡されますが、この中にドラッグ元のTRタグのインデックス番号とドラッグ先のTRタグのインデックス番号が含まれるため、そのインデックス番号をもとに、データの入れ替えが実現できます。

上述のコードを見ていただくとわかりますが、行データの入れ替えにあたって、対象のTRをそのままの形で移動すれば良いだけであり、シンプルに実装できます。

一方、列データの入れ替えはそう単純な話ではないです。なぜかというと、同一列のデータ（TDタグ）が複数のTRタグに分散して配置されるため、それぞれに対して操作が必要になるためです。なお、`@angular/cdk/drag-drop`では、ドラッグ中に対象要素を持ち上げる視覚効果が入ります。その視覚効果に対しても考慮が必要となります。


**図1：行のドラッグ中の視覚効果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490256/47c59a9e-7156-6272-4366-749429710ba0.png)


# 3. 列入れ替え（単純実装版）
行の入れ替え同様の視覚効果を求めない場合、列入れ替えの実装は行同様に簡単に行なえます。

```html
        :
        :
    <table>
		<thead>
            <tr
                cdkDropList
                cdkDropListOrientation="horizontal"
                (cdkDropListDropped)="onDropCol($event)"
            >
				<th cdkDrag>#</th>
				<th cdkDrag>First</th>
				<th cdkDrag>Last</th>
				<th cdkDrag>Email</th>
				<th cdkDrag>Address</th>
            </tr>
		</thead>
        :
        :
    </table>
        :
        :
```

ドラッグ時の視覚効果は以下のようにタイトルのみとなります。

**図2：列のドラッグ中の視覚効果（簡易版）**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490256/83d27673-22da-6d5d-a320-ba3fb090e632.png)

これでも良い場合は、以下は蛇足になります。


# 4. 列入れ替え（実装頑張った版）
ややこしいため詳細説明は割愛します。サンプル実装を参照してください。

https://stackblitz.com/edit/angular-draggable-col-row-table-ver01-for-public?embed=1&file=src/app/component/table/table.component.ts

なお、実装にあたっての気をつけなければならないポイントは以下になります。

1. ドラッグ時の視覚効果はカスタマイズが可能であるためその機能を用いて列全体が持ち上げられているように見せる（[Customizing the drag preview](https://material.angular.io/cdk/drag-drop/overview#customizing-the-drag-preview)）
1. ドラッグ時はBody閉じタグ付近に置かれる対象タグのコピーを操作していることになる。そのためEvent内に格納されているtargetの親を辿ってもTableタグにたどり着けないことに注意する。ドラッグしている要素のIndexを拾えるようにカスタム属性（サンプル実装ではdata-col-indexとして定義）を追加しておく。
1. 列のドラッグ中の視覚効果をTBODY内の各対象TDタグに適用するために、`@angular/cdk/drag-drop`で定義するclassを付けたり、外したりする必要がある（[Animations](https://material.angular.io/cdk/drag-drop/overview#animations)）


**図3：列のドラッグ中の視覚効果（実装頑張った版）**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490256/d06b612c-bb0c-71b5-0ff9-8d43a989526f.png)


# 5. おわりに
もう少しきれいな実装ができればよかったのですが。。。
Apacheの設定ファイルhttpd.confのログ関連のディレクティブをまとめたもの

●Apacheの設定ファイルhttpd.confのログ関連のディレクティブをまとめたもの
・HostnameLookups　on|off　クライアントのIPアドレスをログファイルに記載する際、IPアドレスを逆引きしホスト名で記録するかどうか指定
・LogFormat　書式　書式名　アクセスログに使われる書式を定義
・CustomLog　ファイル名　書式名　アクセスログのファイル名とLogFromatで定義された書式を指定
・ErrorLog　ファイル名　エラーログファイルを指定
・LogLevel　ログレベル　エラーログに記録するログのレベルを指定。
■ログレベル(重要な順)
emerg,alert,crit,error,warm,notice,iinfo,debug,trace{1-8}
ExecuteTemplateで格納した値がhtmlに反映されない(Go)

コントローラーからExecuteTemplateで変数を格納してhtmlに投げてみたが、、
```
templates.ExecuteTemplate(w, "layout", data)
```
```
{{define "content"}}
<h1>トップ</h1>
{{.}}
{{end}}
```
webページに反映されない。

ソースとにらめっこした結果
```
<body>
    {{template "navbar"}}
    <div class="container text-center">
        {{template "content" . }}
    </div>
    
</body>
```
親layoutの"content" のとなりのちょん(.)がなかった。
ExecuteTemplateで最初にlayoutに投げているから当たり前か、、
StarDistについて

# はじめに
　近年における細胞のセグメンテーションには，主に学習ベースであるMask-RCNNが使用されてきました．しかし，細胞が重なっている場合において，全ての細胞を正しく検出することが困難であるといった問題がありました．そこで，StarDistというアルゴリズムが開発されました．StarDistとは，星型凸多角形(Star-convex)を用いた細胞核のセグメンテーションを行うための手法です．
　StarDistはGithubにて論文やコードがまとめられており，チュートリアルが充実しています．特に，学習やテストだけでなく，学習済みモデルの使用も可能なため，気軽に試すことができます．しかし，英語の説明が中心であり日本語での説明が全くないため，本記事で大まかにまとめてみることにしました．

# Stardistの仕組み
　StarDistは，バウンディングボックスに比べ優れた形状表現である星型凸多角形を使用することによる細胞核のセグメンテーション手法です．モデルはU-Netに基づく軽量なニューラルネットワークを使用します．モデルを使用し，オブジェクト確率$d_i, _j$だけでなく$k$方向(デフォルト：$k=32$)に対する半径距離$r^k _{i, j}$を予測することにより，そのピクセルがどのラベルに属するかを出力します．最後に，非最大抑制(NMS)により最終的な出力を行います．

![overview_2d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/814968/1cd170f1-af4b-b335-129d-6de0cbc6a6ce.png)

# 実装
　GitHubページから引用し，コメントを追加しました．本コードではJupyter Notebookを使用しているため，他の開発環境を使用したい場合はコードの書き換えが必要となることに注意してください．

```python
from stardist.data import test_image_nuclei_2d
from stardist.models import StarDist2D
from stardist.plot import render_label
from csbdeep.utils import normalize
import matplotlib.pyplot as plt

# 入力画像をテストデータのインスタンスとして読み込み
img = test_image_nuclei_2d()

# StarDistの学習済みモデルをインスタンスとして読み込み
model = StarDist2D.from_pretrained('2D_versatile_fluo')

# 入力画像を正規化した画像に対し，StarDist適用によりラベリングを実行
labels, _ = model.predict_instances(normalize(img))

# 入力画像の描画
plt.subplot(1,2,1)
plt.imshow(img, cmap="gray")
plt.axis("off")
plt.title("input image")

# ラベリング結果画像の描画
plt.subplot(1,2,2)
plt.imshow(render_label(labels, img=img))
plt.axis("off")
plt.title("prediction + input overlay")
```
出力結果
![pretrained_example.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/814968/08042890-aa14-5b15-8324-ca1f262ba7e7.png)

　上の図より，高精度でインスタンスセグメンテーションができていることが確認できます．あとは，ブロブ解析によるノイズ判断を行ったり，関心領域(Region of Interest: ROI)の設定後に機械学習に回したりすることで細胞を解析，種類を識別することができます．

# 最後に
　本記事では，StarDistについて大まかにまとめてみました．自身の研究に関連するためデータを記載できませんが，StarDistの精度は非常に高く，体感8~9割の細胞を捕捉できていました(私は医者でないので，あくまでも体感です)．また，StarDistを適用する前の段階でノイズ軽減などのフィルタ処理を追加することで，セグメンテーションが向上しました．
　また，本記事では2次元での話を中心に行いましたが，時間を追加した3次元バージョンもあるみたいです．今後は，そちらがベースとなり，細胞のリアルタイムな評価が可能になるのではと考えています．
　ここまで読んでくださり，ありがとうございました．

# 参考
[1] https://github.com/stardist/stardist
[2] https://stardist.net
[3] https://www.youtube.com/watch?v=Amn_eHRGX5M&ab_channel=NEUBIAS
[4] https://www.youtube.com/watch?v=3yk9sBja7YI&ab_channel=DigitalSreeni
mac homebrewでlaravel10とapacheインストールして環境構築してみた

こんにちは。
個人的にLaravelを使おうと思い立ち、いざlaravel10をインストールして使ってみたら、
今までwindowsのxamppを使用していたため、```php artisan serve```を毎回打つのが面倒。。。
MAMPを使えば良い話なのですが、せっかくですしMAMPなしで構築してみようと思い立ちました！

## 環境
* PHP8.2
* Laravel10
* apache2.4

環境はひとまずこんな感じです。

## 手順
まずはhomebrewを使って```php@8.2```と```httpd```をインストールします。

## PHP & Laravel
まずはインストール
```
brew install php@8.2
```

次はpathを通します
```
echo 'export PATH="/usr/local/opt/php@8.2/bin:$PATH"' >> ~/.bash_profile
```

terminalを再起動して以下コマンドを実行してバージョンが返ってきたらOK
```terminal
php -v

# 結果
PHP 8.2.3 (cli) (built: Feb 15 2023 00:34:20) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.3, Copyright (c) Zend Technologies
    with Zend OPcache v8.2.3, Copyright (c), by Zend Technologies
```

#### Laravel10をインストール
laravelプロジェクトを置いておきたい階層まで移動したら下記コマンドを実行
```terminal
composer self-update

↓

composer create-project laravel/laravel "アプリ名" --prefer-dist
```

## apache
httpdをインストール
```
brew install httpd
```

macは元からapacheが入っているのでそっちを停止
```
sudo apachectl stop
sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist
```

設定ファイルを修正していきます。

```terminal
vi /usr/local/etc/httpd/httpd.conf
```
vimエディタが開くので下記のmoduleのコメントアウトを消します
```httpd.conf
# コメントアウトしてある状態
#LoadModule userdir_module lib/httpd/modules/mod_userdir.so
#Include /usr/local/etc/httpd/extra/httpd-userdir.conf
#LoadModule rewrite_module modules/mod_rewrite.so

↓

LoadModule userdir_module lib/httpd/modules/mod_userdir.so
Include /usr/local/etc/httpd/extra/httpd-userdir.conf
LoadModule rewrite_module modules/mod_rewrite.so
```


PHPを使えるようにする
・LoadModuleが書いてあるところの最後に追記する形で以下を記載する
```httpd.conf

LoadModule php_module /usr/local/Cellar/php/8.2.3/lib/httpd/modules/libphp.so
# ↑brewでインストールしたphpまでのpath
<IfModule php_module>
  AddType application/x-httpd-php .php
</IfModule>

```

その他の修正箇所
```httpd.conf
#ServerName www.example.com:8080
↓
ServerName localhost

#####################

DirectoryIndex index.html
↓
DirectoryIndex index.php index.html

#####################

DocumentRoot "/usr/local/var/www"
<Directory "/usr/local/var/www">
  AllowOverride None
↓

DocumentRoot "Laravelプロジェクトまでのpath"
<Directory "Laravelプロジェクトまでのpath">
  AllowOverride All
```

## apacheを起動
```terminal
brew services start httpd
```

```http://localhost:8080/public```にアクセスして下記画像が表示されたらOK!!

![localhost_8080_public_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1541345/a662d352-9292-c8ca-8573-b5f3a850ef22.png)

右下を見てみるとちゃんと```Laravel10```になってますね！！よかった


## 振り返り
今までxamppでずっと開発してきて、apacheのことなんて全く気にしていなかったですが
今回それらを使わずに構築したことで、apache等のwebサーバーについて調べる良いきっかけになりました！
複数サーバーもvirtualhostを使えば立てれるようなので、そのあたりも深掘りして調べていきたいと思います！

以上、駄文ですが最後まで読んで頂きありがとうございました！
Macでローカルからdocker環境のLaravel タスクスケジューラを動かす

# 環境
```
Mac M1
Laravel9
php8
```
# やりたかったこと
Laravel タスクスケジューラで設定した時間間隔でスケジュールが実行されているかを確認したかった。

# 解決方法
crontabに登録をして、スケジューラを実行させる。
### 1.cronエントリーを追加
`crontab -e`をターミナルで叩くと、vim画面が出てくる
```
user_name ~ % crontab -e
```

### 2.何分おきにcronを実行させるかを登録する
```
 * * * * * cd project名までのフルパス &&
 /usr/local/bin/docker compose exec コンテナ名 php /var/www/project名/artisan schedule:run >> /dev/null 2>&1
```
上記は`cd project名までのフルパス`で作業ディレクトリに移動して、指定した時間でartisanコマンドを叩くというもの。
注意点としては、dockerコマンドとartisanコマンドを使うためにはフルパスで書かないと動かない、、、

ちなみに `* * * * * `で時間を指定できるようになっています。(デフォルトだと１分単位で実行される)
```
分 時 日 月 曜日 
*  *  *  *  * command

分(0-59)
時(0-23)
日(1-31)
月(1-12)
曜日(0-6) ※0は日曜日
```

### 3.`crontab -l`コマンドで登録されているcronを確認
`crontab -l`コマンドでさっき登録したものが表示されたら設定完了。
```
docker compose exec コンテナ名 php artisan schedule:work
```

# 補足
Laravel8以降だと以下のコマンドを打つだけで確認することができる。
```
docker compose exec コンテナ名 php artisan schedule:work
```
DjangoのHTML（django-html）をVSCodeで自動的に認識してほしい

# 困ったこと
Djangoで使うHTMLファイルをVSCodeで開くと、django-htmlと認識してもらえず、HTMLと認識されてしまいました。機能拡張の"Django"を入れていましたが、この機能の恩恵をすぐに受けられず、ちょっとストレス感がありました。

## 拡張機能 Django
https://marketplace.visualstudio.com/items?itemName=batisteo.vscode-django&ssr=false#overview

# 解決方法
VSCodeの設定を変更します。
`cmd+,`のショートカットキーで、設定を開きます。
Files:Associationsの項目に下図のように、`django-html`を認識する条件をつけられるようになりました。

- Item: `**/templates/**/*.html`
- Value: `django-html`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239851/68454a8c-a946-78dd-f960-74eb151e7cb6.png)

もしくは、settings.json に追加する場合は下のようになります。

```json
  "files.associations": {
    "*.html": "html",
    "**/templates/**/*.html": "django-html"
  },
```

# 参考
https://github.com/vscode-django/vscode-django/issues/33#issuecomment-479149887
WEBサイト制作_小技『アニメーション』

# 文字にアニメーションをつけてみよう。
## Live
「Hello！」という文字が、小刻みに大きくなったり小さくなったりします。
![スクリーンショット 2023-03-10 23.59.09 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193952/86ec2efd-cbf2-241b-8195-ce3c8fe123f5.png)
![スクリーンショット 2023-03-10 23.59.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193952/13cd2484-c294-94bb-bc1c-e15b77b34d82.png)
## html
![スクリーンショット 2023-03-11 0.02.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193952/ddf02e6d-c7b0-1471-55fe-1e13fae23aba.png)
## css
![スクリーンショット 2023-03-11 0.02.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193952/c96bad6f-6d16-ebb5-3b0a-d3779eb4073c.png)
Python演習問題＿0【　お風呂と水（制御文）　】

# お風呂
## 水を入れる
### お風呂に水を入れよう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2915564/b5fa00fc-be90-2546-e7a9-9fbed06c0ced.png)　合計△L入るお風呂に、毎分□Lの割合で水を入れる。
満タンになったら水を止めてもらう、素晴らしく便利なタイマーを作ろう。

## 出力
1. お風呂の最大量を入力させる
1. 毎分の水の量を入力させる
1. 入水量を毎分置きに表示する
1. お風呂が満水になったら3）が止まる

この順番で出力してみよう。
juliaからChatGPTを使う

# はじめに
最近話題になっているchatGPTについてjuliaから実行する方法をまとめました。
といってもPyCallを使ってpythonの関数を実行するだけなので特段難しいことはありません。
## PyCallについて
```julia:PyCall.jl
julia> ]
(@v1.8) pkg> add PyCall
```
これでインストール完了です。
PyCallは非常に便利なライブラリでPythonの大量にあるライブラリをjuliaの中で利用できるようにしてくれます。
いかに利用例を記します
```julia:example:PyCall
using PyCall
#組み込み関数の場合
jl_float = py"float"
jl_int = py"int"

println(jl_float(3))
println(jl_int(3.0))

#ライブラリの場合
jl_np = pyimport("numpy")
jl_pd = pyimport("pandas")
sample = jl_np.array([1, 2, 3])
df = jl_pd.DataFrame(sample)

println(sample)
println(df)

```

```julia:実行結果
3.0
3

[1, 2, 3]
PyObject    0
0  1
1  2
2  3
```
自作の関数を読み込むことも可能です。
今回はここでchatGPT用の応答関数をセットします。
```julia:chatgpt
using PyCall

py"""
import openai
def chatgpt(prompt):
    openai.api_key = "<OPENAI_API_KEY>"
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "system", "content": "あなたは優秀な秘書です。日本語で回答してください。"},
            {"role": "user", "content": prompt},
        ],
        temperature=0.7,
    )
    return response["choices"][0]["message"]["content"]
"""
prompt = "please tell me about japan"
response = py"chatgpt"(prompt)
println(response)

```
```julia:実行結果
日本は、アジアの東に位置する島国です。人口は約1億2千万人で、首都は東京です。日本は、四季がはっきりしており、春には桜の花が咲き、秋には紅葉が美しいです。
また、日本は世界的に有名な文化的なアイコンを多く持っています。例えば、富士山、武士、着物、お寺、神社、そして美味しい食べ物などです。また、日本は先進技術の国としても知られており、自動車、電子機器、ロボットなどの分野で世界的に高い評価を受けています。
```

これでjuliaからchatGPTを利用することができるようになりました。

## さいごに
流行りのchatGPTをjuliaから利用する方法もといPyCallの使い方をまとめました。
しかし、Pythonでできることをわざわざjuliaで実行する必要性はほとんどないと思います。
今後なんらかの形で活用できればと思っています。
wordpressでのタグ表示数をphpで設定する方法

### wordpressのタグ表示数はphpで制御できる。
ワードプレスに備わっているタグクラウド。
そんなタグクラウドにおけるタグ表示数はphpで制御できます。
たとえば下図はタグ表示数を45→20へ変更した例です。
![タグ数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699006/dab04bab-d0fc-4916-f995-0ddb1630bc62.png)
こんな感じでタグ表示数により見栄えが変わります。

### phpの記述方法
<font color="Red">php更新によりウェブサイトが上手く機能しないリスクもあります。phpの記述は自己責任でお願いします。</font>
wordpressにおけるphp更新は、外観→テーマエディター→Function.phpより記述を追加できます。
以下にサンプルコードを例示します。Function.phpの最後あたりにコピペすると使えます。
```言語:php
function custom_wp_tag_cloud($args) {
$myargs = array(
‘orderby’ => ‘count’, //使用頻度を取得する
‘order’ => ‘DESC’, // 降順（使用頻度の高い順）
‘number’ => 45 // 表示数
);
$args = wp_parse_args($args, $myargs);
return $args;
}
add_filter( ‘widget_tag_cloud_args’, ‘custom_wp_tag_cloud’ );
```
(phpの記述方法は https://tensyokuseikatsu.com/wordpress-tag-count/ を参照)
### php構文解説
//でコメントアウトしている部分を参考に、変数を変更することで表示数を変えることが出来ます。
たとえばnumberの45を、20へと変更すると表示タグ数を変更することが出来ます。
見栄えの良いウェブサイトへの更新へ役立つことが出来れば幸いです。
ChatGPTに研究室メールを要約をさせてLINEに送る

<center><img alt="S__4587548.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1281879/6bc695f1-4867-8643-ec7b-62d1da70957d.jpeg" width="50%"></center>


https://github.com/165cmtallboy/Mail2GPT2LINE


## 動機
製作者は全くメールに馴染みがない。メールは会員登録メールをみる時以外確認しないし、基本的に広告や就活メールで溢れかえっているため内容が頭に入ってこない。
LINEとDiscordとSlack以外はあんまりチェックする癖がついてない。


研究室から来るメールは重要性が高いが見落としやすい。見落とすと重要な説明会に参加できなかったり、怒られたりする。そのため、研究室から来るメールを効率よく確認するツールが必要。
大学メール(SMTP)＋GPT＋LINEで、自分に向けたツールを開発した。

## GPTキー準備
下記サイトを参考に取得。
環境変数にキーを格納し、コードから読ませるようにした。

https://digital-shift.jp/flash_news/s_230306_1

## IFTTT準備
LINEに結果を吐かせれば自分も確認できるし研究室のメンバーも共有できるからいいなと思い、IFTTTのWebhook requestにきたメッセージをLINEに飛ばすようにした。
キーは環境変数に格納。
![スクリーンショット 2023-03-10 23.43.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1281879/04266d25-6a9f-8269-3000-e5db4913466c.png)

## そのほか
使う人がいたらプルリクとか待ってます。
CA.go参加レポート

# 初めに
初めまして、学生エンジニアのマーシーです。普段はバックエンドエンジニアとしてGoなどで開発をしています。今回はCA.goに参加してきたのでその内容と感想を共有します。
# CA.goとは
CA.go を知らない方に説明します。Connpassのイベントページにはこのように書かれていました。CA.goはサイバーエージェントグループ横断で Go に関する知見を共有し合う社内勉強会です。今回はその社外版として、先日行われた「FIFA ワールドカップ カタール 2022」を全64試合生中継をした新しい未来のテレビ「ABEMA（アベマ）」 のチームから Go 活用事例をご紹介します。この様に、社外の人でもCAのGoでの取り組みがわかる勉強会です。

https://cyberagent.connpass.com/event/271708/

# イベント内容
イベントの内容としては、LTが３つと懇親会でした。LTは大変内容が濃いもので、懇親会もとても楽しかったです。

# LT内容&感想
3つあったLTで自分が特に印象に残った部分を中心に紹介しようと思います。
## LT1.「ABEMA」のレコメンドへの大規模アクセスを支えるGo製サーバーの裏側
ABEMAに限らず、最近の動画配信サービスはトップページにあなたへのおすすめという形でレコメンドされた動画が並ぶと思います。それらを、支えているのは基本的にはPythonの機械学習系サーバです。CAではFIFA ワールドカップ カタール 2022(以下W杯)配信に向けて多くの人がトップページにアクセスしても、このレコメンドシステムが落ちないようにする工夫をGoで行ったそうです。Goで作ったのはプロキシサーバで役割はoriginサーバへの負荷軽減を目的としてキャッシュをすることだそうです。オンメモリだけでなく、redisも用いることで90%〜95%originサーバへの負荷が低減されたそうです。キャッシュだけでなく、originへのアクセス制御も様々取られていて高負荷に耐えうる施策をたくさんしていたんだなと驚きました。

https://speakerdeck.com/_hiro511/rekomendohenoda-gui-mo-akusesuwozhi-erugozhi-sabanoli-ce 

## LT2. コメント時のTwitter連携機能で動画がシェアされる際のGo製サーバー開発手法
自分は知らなかったのですが、ABEMAの動画はTwitterにシェアするときに動画も一緒にシェアする機能があるそうです。これをW杯期間中の高負荷に耐えるために刷新した話が2個目のLTでした。正直自分は動画周りをGoでいじったことがないのでどれくらい重い処理か想像でしか話せませんが、かなり重たい処理をしているのだろうなというのは容易に想像がつきます。元々は、この部分をTweetしたい！となったらその部分を切り取ってTweetに載せていたらしいのですが、W杯用に刷新し、Requestとは連動せずに、動画をセクションごとに分割する処理を定期的に行い保存する方式をとったそうです。Requestが来たら分割していた動画を必要な分だけ結合して返すことで負荷軽減を行ったそうです。また、オンメモリで動画をキャッシュすることで更なる負荷軽減もしたそうです。1機能にこれだけの負荷軽減施策をしていたとは、、、。

## LT3.「ABEMA」の安定稼働を支えたOpenTelemetryの導入事例
Goというよりはかなりインフラ寄りの話で、ボトルネックをいかに早く探し出すかということをモチベーションにやったそうです。OpenTelemetryを導入することでマイクロサービスなABEMAのシステムでもどこがボトルネックになっているのかをすぐに見つけ障害にならないように事前に修正をしておくということをしていたそうです。Goエンジニアとしてはこういうインフラ側の助けがないとなかなか重たい処理はどこなのか全てを把握して潰すことはできないので助かるだろうなと感じていました。また、レガシーコードとの戦いといったところも話されていてリリースから7年ほど経つABEMAのコード全体に影響を及ぼす今回の導入はかなり大変だっただろうなと勝手に想像してました。DevOpsという言葉が流行っている今、この話面白いなと思った人も多かったと思います。

# 最後に
Goを書く学生エンジニアとしてこんなにも勉強になる機会はなかなかない素晴らしい勉強会でした。また、W杯のABEMAの中継はW杯をどう配信したのかに注目が集まりがちですが、普段のABEMAのサービスでは考えられないトラフィックを捌くために、W杯配信だけでない様々なところに気を配ったんだなと感じました。新しいことをやりつつ今あるものを動かし続ける大変さを教えてもらった様な気がします。
Googleアドセンス ポリシー違反レポートの対策

私は、ブログを運営しています。
運営しているブログには、Googleアドセンスの広告を配置して、広告収入を得ています。
毎月微々たる金額ですが、とても大切な収入源となっています。
毎日収益をチェックすることが、日課であり、楽しみの一つでもあります。

## 1. 突然のメール
とある朝、こんなメールが来て、頭が真っ白になりました。
![adSense-policy-violation-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19382/61ec4d02-93f0-a69d-9b9d-a8e7bb5b9862.png)


特定のページでポリシー違反があるとのことでした。
過去にこんなメールは来たことがなかったので、「**アドセンスの資格を失ってしまうのかも**」とか「**収益の無いブログ運営のモチベーションを上げることは出来るのだろうか**」と少し先のことまで考えてしまうほどでした。

メールには、以下のような文面がありました。
> この問題を解決するには、違反しているコンテンツを削除して、審査をリクエストしていただくか、違反しているページから広告コードを削除する必要があります。

該当のページを削除すれば良いのかと、簡単ではあるけれども、頑張って書いたページを削除（非表示）にするのは、少しためらいます。



## 2. 違反対象のページの確認

嘆いても仕方ないので、とりあえず該当ページを確認することに。
![adSense-policy-violation-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19382/7a4c4ad5-442a-85a5-f13f-b17e7e49fbd9.png)

アドセンス管理画面のポリシー違反対象ページは、1ページのみ。
問題点は、何と「**アダルトコンテンツ（性的な内容）**」ということです。

この記事は、1年以上も前に書いたページであり、最近更新をしたわけでもありません。

そのページの内容を一字一句チェックしてみましたが、アダルトな内容もなく、「このページは、何も悪いことはしていない！！」と判断。このページは悪くないので（笑）、申請してみることに。

## 3. 審査依頼をしてみる
もちろん、このページは悪くないので、何も変更はせず、「修正」リンクをクリックしました。
その後の画面で、「審査をリクエスト」をクリック。
![adSense-policy-violation-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19382/d783fc25-4621-9f1d-49f3-68a73b8cd07e.png)

チェックボックスにチェックを入れ、「リクエストを送信」をクリック。
![adSense-policy-violation-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19382/c83739e0-8583-b7b8-a924-7e95b373a17f.png)

そして、審査依頼完了！
![adSense-policy-violation-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19382/e47eb00a-81e0-14c3-c82a-0f704e7adc12.png)

## 4. 数時間後、違反が解消されてた…

審査依頼後、しばらくして、アドセンス管理画面のポリシー違反のページを確認したところ、
「**現在、問題はありません。**」とのこと。(笑)

![adSense-policy-violation-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19382/c61a93f7-8404-412c-0701-35c5ad0c1386.png)

## 5. まとめ

突然の出来事で、ビックリしましたが、アドセンスも間違った判定をすることもあるんだぁ。と楽観的に気持ちになるようにしました。でも誤った判定をして、ユーザーを困惑させるのもどうかと思いますね。

おそらくAIで自動的に判定処理を行っているのでしょう。まだAIも完璧ではないと思うので、仕方ないかと思いますが、少しずつ精度が高くなっていくのでは無いかと思われます。

ということで、ポリシー違反になった場合は、慌てずに、

* 本当に違反がないか記事をチェックする。（違反と思われる箇所があれば修正する）
* 審査依頼をする

を試してみましょう。
React Date Pickerでハマった話

## はじめに
ポートフォリオでカレンダー機能を作るためにReact Date Pickerを使いましたが、
ちょっとハマったところがありましたので話してみたいと思います。

## 開発環境
- Ruby on Rails API mode
- React.js

## ハマったところと原因
[Date Picker](https://github.com/Hacker0x01/react-datepicker)の基本使い方は下記になります。
```react
<DatePicker 
    selected={startdate} 
    onChange={(date) => setStartDate(date)} />
```

選択されたデータをInputタグとカレンダーに表示してくれる`selceted`要素には渡す`startdate`と
日にちが変更になったとき発動する`onChange`が出力する`date`は[JavaScriptのDateオブジェクト](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date)です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/6d0690b5-6431-5389-fda8-4f221cd42acd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/8f4490d1-92f1-54bf-8c66-91cdc67dd170.png)

例えば、カレンダーで `3月10日`を選択すると`onChange`が発動し、JavaScriptのDateオブジェクトである`date`に`Fri Mar 10 2023 23:00:06 GMT+0900 (日本標準時)`が代入されます。

### ハマったところ

日にちの編集機能を追加しました。編集をするというのは、既存の日にちデータがあるので、そのデータをバックエンドから貰ってきて、`selected`要素に渡す必要があります。
```react
<DatePicker 
    selected={ここ} 
    onChange={(date) => setStartDate(date)} />
```
でもバックエンド側からのレスポンスである日にちデータは**文字列(String型)** の`"2023/3/10"`であるため、そのまま渡してしまうとエラーになります。time valueが適切ではないと怒られてますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/fe4e29a9-8e34-a8bd-3edd-dd333a0f909b.png)
これで何をどうすべきかが分からなくてハマりました。


## 解決策
バックエンドから渡されたデータが文字列なのが原因なので、
この文字列を`new Date()`を使ってJavaScriptのDateオブジェクトに変えてあげれば解決します。
```react
<DatePicker 
    selected={new Date("2023/3/10")} 
    onChange={(date) => setStartDate(date)} />
```

## 終わりに
簡単ですが、以上です。
エラーの内容もちょっと不明確で解決まで時間がかかってしまいました。
Date PickerはDemoも沢山あって使いやすいので、カレンダー機能のためにぜひ使ってみてください。

https://github.com/Hacker0x01/react-datepicker

https://reactdatepicker.com/

ありがとうございました。
JEST インストールからテスト実行まで

## 参考URL
こちらJESTのドキュメントになります。
https://jestjs.io/ja/docs/getting-started

## JESTをインストール
こちらでJESTのインストールを行なってください。
```
npm install --save-dev jest
```
今回は、npmコマンドでインストールしましたが、node.jsをインストールしないとnpmコマンドを使えないので、node.jsをインストールしていない人は、以下を参考にしてください。
https://qiita.com/sefoo0104/items/0653c935ea4a4db9dc2b
## 実行する
sum.jsを作成して、以下のコードを書きます。
```:sum.js
//sum関数を作成する。
function sum(a, b) {
  return a + b;
}
//sum.jsファイルをテストファイルで使えるようにする。
module.exports = sum;
```

```:sum.test.js
//sum.jsを取得する。
const sum = require('./sum');

test('メモ', () => {
  expect(sum(1, 2)).toBe(3);
});
```
以下のコードについて説明します。
```
test('メモ', () => {
  expect(sum(1, 2)).toBe(3);
});
```
#### expect
テストしたい値を格納する関数。単体で使うことはほとんどないです。
上のコードだと、sum関数に引数を渡し、関数を実行します。
その結果とこれから説明するMatcherとの結果をテストして、結果を表示します。
#### Matcher
以上のコードのtoBeというのはMatcher(マッチャー)と呼ばれるものです。
Matcherとは、expectで指定した結果に対して、様々な条件を付けられる機能(関数) になります。
Matcherにはたくさんの種類があります。以下が、Matcherのチートシートになります。参考にしてください。
https://proglearn.com/2019/11/30/jest-%e3%83%81%e3%83%bc%e3%83%88%e3%82%b7%e3%83%bc%e3%83%88-javascript%e3%81%a7%e3%83%86%e3%82%b9%e3%83%88%e3%82%92%e6%9b%b8%e3%81%93%e3%81%86/

##### 例①
以下のコードは、文字列(Christoph)にstopという文字列が入っていれば成功。入っていなければ失敗。というテストコードになります。
```
test('but there is a "stop" in Christoph', () => {
  expect('Christoph').toMatch(/stop/);
});
```
結果は成功になります。
##### 例②
こちらは"team"の中にI文字が含まれていなければテスト成功。含まれていたら失敗。というテストコードになっています。
```
test('there is no I in team', () => {
  expect('team').not.toMatch(/I/);
});
```
こちらも「team」という文字列に「I」は入っていないので、結果は成功します。

以上になります。
Linuxの基本操作コマンド

# はじめに
私がいつも使用しているLinuxコマンドを優先に知識の再確認とアウトプット用として整理してみました。
Webシステム開発でも使うため、備忘録も含んでます。
手始めにいつも私が開発で使用しているインフラ環境から簡単ですが整理しました。
あとこれからQiitaの投稿頻度上げるのと、それに伴いMarkdown記法を書けるようになるとドキュメント資料とかにも役立ちそうなので、まぁ地道にやろうかと。
※あくまで本投稿は自分自身の知識の定着及び再確認の情報整理用です。

# 環境
VMware Workstation 15(仮想マシン)
CentOS Linux 7(ゲストOS)
※開発環境はホストOS上にあるTeraTermから仮想マシン内のゲストOSへ22番ポートでSSH接続する。

# よく使うLinuxコマンド一覧
|コマンド  |オプション、引数等  |使うシーン等  |
|---|---|---|
|ls(ll)  |-l  |カレントディレクトリ内のディレクトリ及びファイル一覧確認  |
|cd  |[各ディレクトリ及びファイルパス]  |ディレクトリの移動  |
|rm  |-f,-i,-r,-R  |ディレクトリ及びファイル削除  |
|mkdir  |[作成したいディレクトリ名]  |新規ディレクトリ作成時  |
|vim  |[任意のファイル名]  |スクリプト編集時等  |
|shutdown  |-h  |作業終了時(仮想マシンパワーオフ時)  |

本腰入れての投稿としては初回になるため、これから記事を投稿する度、品質も上げていく予定です。
何卒よろしくお願い致します。
【 IT用語 】ハードコーディングとは

## ■ ハードコーディングとは
設定値やパラメータなど、プログラムの動作に関係する値を、プログラムコード内に直接記述することを指す。

以下に、ハードコーディングの例と、その問題点、解決策となるソフトコーディングの例を残す。

## ■ ハードコーディングとなっている例
下記ソース例では「1.1」という消費税の値がハードコーディングとなっている。

```java:消費税計算
// 税込価格 = 税抜価格 * 消費税
double taxIncludedPrice = priceWithoutTax * 1.1 ;
```

## ■ ハードコーディングの問題点
**①マジックナンバー**

:::note warn
何を意味しているのか本人しか分からない値のこと。
:::

　先ほどの消費税計算でハードコーディングとなっている「1.1」の値がマジックナンバーである。これを全員が消費税だと理解するのは難しい。
　また、何の値か分からないため安直に変更することができなく、属人的なソースとなってしまう。

---
**②保守性**
　消費税が10%でなくなった場合、消費税を使っている全箇所の修正が必要になる。
　下記例は2パターンのみだが、規模が大きくなった時にこのようなソースが複数あると修正に多くの時間がかかってしまう。
```java:消費税を使う処理が複数ある場合
/**
 * 税抜価格から税込価格を算出する場合
 * 税込価格 = 税抜価格 * 消費税
 */ 
double taxIncludedPrice = priceWithoutTax * 1.1 ;

/**
 * 税込価格から税抜価格を算出する場合
 * 税抜価格 = 税込価格 ÷ 消費税率
 */ 
double priceWithoutTax = taxIncludedPrice / 1.1 ;
```
:::note warn
変更漏れや、記述ミスなど、保守性が低い。
:::
---
**③セキュリティ性**
　例えば認証処理を行うソースコードに、認証比較する値を直接記述していると<font color="red">外部に情報が漏れる可能性が高い</font>。脆弱性の観点からも直接記述ではなくソフトコーディングでセキュリティの保護をする必要がある。
```java:認証パスワードを直接記述した場合
if (入力された値 == "password12345") {
 System.out.println("認証成功");
} else {
  System.out.println("認証失敗");
}
```

## ■ ソフトコーディングとは
ハードコーディングの対義語であり、柔軟に変更が可能な形でプログラムに取り込むことを指す。
設定値やパラメータなど、プログラムの動作に関係する値を、プログラムコード内に直接記述するのではなく、外部ファイルやデータベースに保存しておき、実行時に必要な値を取得するようにプログラムを作成することで、プログラムの変更や保守を容易にすることができる。


冒頭でハードコーディングとして例を挙げた消費税計算のソースをソフトコーディングにすると以下の形式になる。
```java:消費税計算
// 消費税
final double TAX = 1.1 ;

// 税込価格 = 税抜価格 * 消費税
double taxIncludedPrice = priceWithoutTax * TAX ;
```

:::note info
消費税を定数として宣言し、使用時は「TAX」を呼ぶだけで良いので、記述ミスがなくなる。
また、消費税が変わった時は、宣言している値1箇所のみの修正で良いので修正漏れも防げる。
:::
テストを書くときにPrismaのインスタンスをモックする方法

Remixでアプリケーションを開発していると、Prismaの恩恵をとても受けると思います。
ただ、いくらアーキテクチャに沿ってレイヤーを分割しても、テストを書いていると必ずPrismaに依存するコードに遭遇します。

RemixのIndie Stackなどのテンプレートを使って開発をする場合、**db.server.ts**にてPrismaのインスタンスを生成します。

```db.server.ts
import { PrismaClient } from "@prisma/client";

let prisma: PrismaClient;
...
prisma = new PrismaClient();
...
export { prisma };
```

たとえば、この`prisma`を使ってデータを取得する場合、次のような実装になると思います。

```UserServiceImpl.server.ts
export interface UserService {
  getUserById(id: string): Promise<User | null>;
}

export class UserServiceImpl implements UserService {
  async getUserById(id: string): Promise<User | null> {
    const user = await prisma.user.findUnique({
      where: { id },
      include: {
        preference: true,
      },
    });

    return user ?? null;
  }
}
```

この場合`UserServiceImpl`は`prisma`に依存しています。
そのため、このクラスに対してテストを書く場合、`prisma`をモックする必要があります。

モックをするために、**db.server.ts**が存在するディレクトリに`__mocks__`ディレクトリを作成し、`db.server.ts`をモックするファイルを作成します。

```md
├── app
│   ├── __mocks__
│   │   └── db.server.ts
│   └── db.server.ts
```

そして、`UserServiceImpl`では、`findUnique`メソッドを呼び出しているので、`__mocks__/db.server.ts`で`findUnique`メソッドをモックします。

```__mocks__/db.server.ts
import { faker } from "@faker-js/faker";

export const prisma = {
  user: {
    findUnique: vi.fn().mockImplementation((args) => {
      return {
        id: args.where.id,
        name: faker.name.findName(),
        email: faker.internet.email(),
        preference: {
          id: faker.datatype.uuid(),
          userId: args.where.id,
          theme: "light",
        },
      };
    }),
  }
}
```

それでは実際にテストを書いてみます。
実は、`__mocks__/db.server.ts`を読み込んでモックを適用するには、モック対象のモジュールを`vi.mock`で読み込む必要があります。

```UserServiceImpl.server.test.ts
import { faker } from "@faker-js/faker";
import { UserServiceImpl } from "../UserServiceImpl.server";
import { prisma } from "../../../../../db.server";
// app/__mocks__/db.server.tsが読み込まれる
vi.mock("../../../../../db.server");

describe("UserServiceImpl", () => {
  test("should return user when user exists", async () => {
    // Arrange
    const userId = faker.datatype.uuid();
    const userService = new UserServiceImpl();
    // Act
    const user = await userService.getUserById(userId);
    // Assert
    expect(user?.id).toBe(userId);
    expect(user?.preference).not.toBeNull();
  });
});
```

これで`UserServiceImpl`のテストが書けました。
次に、上記の内容を維持したまま`findUnique()`メソッドが`null`を返す場合をテストしてみます。
それを実現するために、`prisma.user.findUnique`に対して`mockResolvedValueOnce`を使って`null`を返すようにします。

```UserServiceImpl.server.test.ts
...
test("should return null when user does not exist", async () => {
  // Arrange
  const findUnique = prisma.user.findUnique as jest.Mock<any, any>;
  findUnique.mockResolvedValueOnce(null);
  const userId = faker.datatype.uuid();
  const userService = new UserServiceImpl();
  // Act
  const user = await userService.getUserById(userId);
  // Assert
  expect(user).toBeNull();
});
```

これで、`prisma`に依存した`UserServiceImpl`のテストが書けました。
今回の記事ではRemixの慣例的にVitestを使いましたが、Jestを使っても同じようにテストを書くことができますので是非お試しください。
Excel 今日のトリビア HSLも実は選べるがExcel色ダイアログボックスのHEXはインチキ

# 正式名称
[[色] ダイアログ ボックスでの色の選択](https://support.microsoft.com/ja-jp/office/-%E8%89%B2-%E3%83%80%E3%82%A4%E3%82%A2%E3%83%AD%E3%82%B0-%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E3%81%A7%E3%81%AE%E8%89%B2%E3%81%AE%E9%81%B8%E6%8A%9E-c3d59ddf-65a7-4e62-aad7-f7b8d7684a2d?ns=excel&version=90&syslcid=1041&uilcid=1041&appver=zxl900&helpid=3002&ui=ja-jp&rs=ja-jp&ad=jp)
その他の色->色の設定->ユーザー設定で出てくる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/4b2b4d31-b106-c787-69d4-f4a7311e51da.png)

色ダイアログボックスの画像ではRGBの値は
 
|RGB | Value|
|:--:|------:|
|R|　194|
|G|147|
|B|　016|

と表示されている。
理論的にはColor番号はB G R の順に16進数に並べ替える。
`&H1093C2`になるはず。

|RGB | Value|　Hex|
|:--:|------:|------:|
|R|　194| C2|
|G|147| 93|
|B|　016| 10|

なのでRとBを入れ替えるといい。

ところが、Hex（H）の値を見ると
`#C29310`
となっている。Qiitaはちょっと答えをみせてくれますね。
つまり赤`#FF0000`、緑`#00FF00`、青`#0000FF`の順になっており、ひっくり返っていない。
実は、このダイアログボックスのHexは単純に上のR、G、Bを16進数に変えているだけだったのである。
ここでColor番号を求めることはできない。
もし、Color番号からここを入力するには、
`&H1093C2`を入れ替えて、
Qiitaでは正しい色になっている`#C29310`が:smile:、Excelでは違う色になる。実際に入力してみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/3a86ff90-a2b0-b91d-3214-593d63efd9b3.png)

これはHTMLでは赤、緑、青の順になっており、`#1093C2`このように表示される。つまり、このダイアログボックスはHTMLと同じ順になっているということになる。Excelの中でHexの並べ方が違うので全く一貫性がないとしか言いようがない。:worried:

# HSL

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/4730967b-f3b0-879c-d6fd-515e6b5225f8.png)

HSLに入れ替えると10進部分は変わる。
しかし、Hexは変わらない。あくまでもHTMLのHEXらしい。
HSL変換を手動でできると言うのはなにかの役に立ちそうだが。16進数は変わらない。
brewでよく使うコマンド

brewでよく使うコマンドを記載


Homebrewでインストールしたフォーミュラの一覧を表示

```
$brew list
```

起動しているサービスの確認

```
$brew services list
```


Homebrewの更新

```
$brew update
```

フォーミュラの更新

```
$brew upgrade
```

更新可能なフォーミュラの一覧を表示

```
$brew outdated
```

フォーミュラに関する情報を表示

```
$brew info フォーミュラ名
```


brew upgradeから指定したフォーミュラを除外

```
$brew pin フォーミュラ名
```

pinしたフォーミュラの一覧を表示

```
$brew list --pinned
```

古いフォーミュラのファイルを削除

```
$brew cleanup
```

システムに問題がないかチェック

```
$brew doctor
```

不要なフォーミュラのアンインストール

```
$brew autoremove
```

インストール

```
$brew install formula
```

アンインストール

```
$brew uninstall formula
```

検索

```
$brew search text
```


依存関係をみる。

```
$brew deps formula
$brew deps --tree formula   #tree式
```

formulaの有効化無効化

```
$brew link formula
$brew unlink formula
```

brewへのpull requestをpullする

```
$brew pull アドレス
```


以上
SCSSをCSSと比較しながらまとめてみた！

# 概要


SCSSとCSSはどちらもスタイルシート言語であり、ウェブページの見た目を定義するために使用されます。簡単に言うとSCSSは、CSSの拡張版であり、プログラム可能なスタイルシートとして知られています。以下に、SCSSとCSSを比較していきたいと思います。

# 目次
- ソースコードの比較
- プログラムブル
- ネスト機能
- 繰り返し構造
- コンパイル
- まとめ

# ソースコードでの比較

```
SCSSの場合

$primary-color: #007bff;

nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;

    li {
      display: inline-block;
      margin-left: 1rem;

      a {
        color: $primary-color;
        text-decoration: none;
      }
    }
  }
}
``` 

## プログラマブル
SCSSは、変数、ループ、関数、条件分岐などのプログラム機能を持っています。これにより、複雑なスタイルシートを簡単に管理できます。CSSにはこのような機能がないため、同じ効果を得るためには、手動でスタイルシートを編集する必要があります。

## ネスト機能
SCSSは、親子関係を持つ要素をネストすることができます。これにより、HTMLの構造に合わせて、スタイルシートを管理することができます。CSSにはこのような機能がありませんので、同じ結果を得るためには、クラスやIDを使用してスタイルシートを管理する必要があります。

- 繰り返し機能
SCSSは、繰り返し処理をサポートしています。これにより、同じスタイルを複数の要素に適用することができます。CSSにはこのような機能がないため、同じスタイルを複数回記述する必要があります。

## モジュール化
SCSSは、スタイルシートをモジュール化することができます。これによって、スタイルの再利用性を高め、スタイルシートの保守性を向上させることができます。CSSにはこのような機能がありませんので、スタイルの再利用性を高めるためには、別のスタイルシートを作成し、リンクする必要があります。

## コンパイル
SCSSは、CSSにコンパイルする必要があります。これにより、ブラウザがスタイルシートを読み込むときに、SCSSファイルを解析する必要がなくなり、読み込み速度が向上します。CSSにはこのような機能がありません。

# まとめ
以上のように、SCSSとCSSにはいくつかの違いがあります。SCSSは、プログラマブルなスタイルシートを作成するために、多くのプログラマーやWeb開発者によって使用されています。一方、CSSは、基本的なスタイルシート言語であり、Web開発者によってよく使用されます。SCSSは、開発者が複雑なスタイルシートを管理しやすくするために使用され、CSSは、基本的なスタイルシートを作成するために使用されます。

ただし、SCSSを使用する場合でも、ブラウザが読み込むスタイルシートはCSSであるため、最終的にはCSSを学ぶ必要があります。また、SCSSを使用する場合でも、CSSに比べて記述方法が複雑になる場合があるため、初心者にはCSSの方が扱いやすい場合があります。

総合的に言えば、SCSSは、大規模なWebアプリケーションを開発する場合に特に有用であり、CSSは、小規模なWebサイトや単純なスタイルシートを作成する場合に最適です。どちらを使用するかは、開発者のスタイルやプロジェクトの要件によって異なります。
ChatGPT API 連携してみた（Laravel）

## 始めに
ChatGPT API と Laravelを連携したので、
備忘録として記録しました。
超絶簡単でしたのでぜひお試しください。

## 環境
| 開発環境    |バージョン |
|-----------|------------|
| __Laravel__ | 10.1.5 |
| __PHP__     | 8.2.3 |

## 手順概要
__➀ 設定（Chat GPTコンソール画面）__
　　トークンの取得（無料で取得できます。）
__➁ 環境構築__
　　ライブラリをインストールする
__➂ 実装__
　　ChatGPTからの質問回答を取得する

## ➀ 設定（Chat GPTコンソール画面）

APIコンソール画面にログインします。⬇️ ⬇️ ⬇️

https://platform.openai.com/

ログイン後、右上のプロフィールをクリックします。
「View API keys」をクリックします。
![Group 1chatgpt_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984846/80e25d32-434d-0843-d742-01a32bcb2ea0.png)

「Create new secret key」をクリックします。
SECRET KEY が生成されるので、コピーして保存します。
![Group 2chatgpt_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984846/ae333681-de31-a685-cf0c-01d803917d07.png)

## ➁ 環境構築
ライブラリをインストールします。
```
composer require openai-php/client
```

## ➂ 実装
```php:ChatGptController.php
use OpenAI;

public function getChatGptAnswer() {

    // ChatGPTにリクエスト送信する
    $client = OpenAI::client('取得したAPIキー');
    $result = $client->completions()->create([
        'model' => 'text-davinci-003',
        'prompt' => '今日の天気は？', // 質問したいことを記入する
        'max_tokens' => 100        // 返答される文字数（1英単語 = 1トークン、日本語はひらがな１文字が1トークン以上だとか。。。） 
    ]);

    // ChatGPTからのレスポンスを取得する
    $response = $result['choices'][0]['text'];
}
```

## 参考
https://gehri.dev/blog/how-to-use-openai-in-laravel

公式ドキュメン　⬇️ ⬇️ ⬇️

https://platform.openai.com/docs/introduction

## 終わりに
最後まで読んでいただきありがとうございました。
ご意見、ご指摘ありましたら、コメントよろしくお願いします。
Power Automate で無限に長いテーブルは参照できない(>_<)

# はじめに
<!-- 発端や概要を記載 -->
Power Automateからエクセルのテーブルを参照することはよくあると思いますが、無限に長いテーブルは参照できません。
# 再現してみる
↓実験用フローはこんな感じ
![スクリーンショット 2023-03-10 214148.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885419/8f6f4c6b-1e03-1507-f2e6-b1b74d1d48fa.png)
↓「行の取得」詳細
「テーブル2」という名前のテーブルの列１の値が「C」である行を取得する。
![スクリーンショット 2023-03-10 215708.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885419/53606d12-d401-f3e5-70a9-d6be4a366912.png)
↓テーブルに変換するデータ範囲を```=$D:$E```として作成した無限に長いテーブル。
これが「テーブル2」。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885419/ef4764e2-c4e0-1b2b-7762-f3bd7063770a.png)
この状態でフローチェッカーを動かしてみると、エラーも警告も0件。
参照しているテーブルの「列１」には「C」の文字がある。
当然上手く動きそうに見える。

しかし、↓の画像のように行の取得のところで失敗する
![スクリーンショット 2023-03-10 220331.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885419/d45199a3-95ec-6c65-8d6a-413a53567816.png)

エラー詳細を見ると`"ID 'C' を持つ行が見つかりませんでした。"`と書いてある。
あるのに(>_<)

# おわりに
フローチェッカーにも引っかからないし、エラーメッセージもテーブルの範囲に言及が無いので
テーブルの範囲が原因だと気づくのに時間がかかりました。
どなたかのお役に立てば幸いです。

# お詫びと訂正
2023/03/30追記
エクセルは1,048,576行が最大で、無限に長いテーブルは作れない事が発覚しました。
本記事で登場する「無限に長い」は「1,048,576行の」に読み替えてください。

今後このような失礼がないように努めて参ります。 何卒ご容赦いただけますと幸いです。
GASでページ内リンクを使用する

GASのWebアプリを作っていた際に、ページ内リンクの実施方法に悩んだので備忘録として残しておく。
過去の記事を読むとVueを使った方法などがあったがうまくやり方がわからなかったためJSで機能する様にすr

## 通常のWebページのページ内リンク
通常のHTMLの場合は以下のようにできる

```
<a href="#section1">セクション1に移動する</a>
<h1 id="section1">セクション1</h1>
```

しかしこれをGASで使うと別のページに推移してしまい機能しない

## GASの場合
GASの場合はJavaScriptを使用する。

```
<body>
<button onclick="scrollToElement('searchform')">検索フォーム</button>
<h2 id="searchform">検索フォーム</h2> 

<script>
function scrollToElement(id) {
  var element = document.getElementById(id);
  element.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"});
}
</script>
</body>

```

こうするとページ内リンクの作成ができる。
もしbuttonになるのが嫌な場合は、CSSで修正してください。
Railsでajax通信するときにCSRFトークンを付加する方法をchatGPTに聞いてみたらすぐ解決した。

railsでajaxを使って通信するときに、CSRFトークンを付加するにはどうすれば良い？
---

Railsでは、セキュリティ保護の一環として、CSRF（クロスサイトリクエストフォージェリ）攻撃を防ぐために、フォームを送信する際にCSRFトークンを必要とするようになっています。同様に、Ajaxを使用してデータを送信する場合にも、CSRFトークンを付加する必要があります。

以下の手順に従って、RailsでAjax通信にCSRFトークンを付加することができます。

1、app/views/layouts/application.html.erbファイルに下記のようにcsrf_meta_tagsを追加します。
```html
<%= csrf_meta_tags %>
```
2、Ajax通信を行うJavaScriptファイル内で、app/views/layouts/application.html.erbからmeta[name="csrf-token"]を取得します。
```javascript
var csrf_token = $('meta[name="csrf-token"]').attr('content');
```
3、Ajaxリクエストを送信する際に、X-CSRF-TokenヘッダーにCSRFトークンを設定します。
```javascript
$.ajax({
  url: '/your_ajax_endpoint',
  type: 'POST',
  beforeSend: function(xhr) {
    xhr.setRequestHeader('X-CSRF-Token', csrf_token);
  },
  data: { foo: 'bar' },
  success: function(response) {
    console.log(response);
  }
});
```
このようにして、Ajax通信に必要なCSRFトークンをRailsアプリケーションに付加することができます。
ChatGPT账号购买步骤：5$独享账号 支持改密码

[![购买ChatGPT账号](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249696/c7546ca3-ba6c-9a59-bb5e-950d793288c4.png "购买ChatGPT账号")](https://yuhfk.com//liebiao/C6AB6F416670178E "购买ChatGPT账号")
欢迎您考虑购买ChatGPT账号，我们非常理解您在注册过程中遇到的一些麻烦。由于ChatGPT采用的是OpenAI GPT-3.5技术，因此需要在注册时提供国外手机号码以验证身份。这可能会给您带来一定的不便，但我们相信这是出于安全和保护用户隐私的考虑。
为了帮助用户更轻松地使用ChatGPT，我们也提供了成品账号的购买服务。购买成品账号后，您将无需进行任何操作即可直接使用ChatGPT。这样不仅可以省去您的时间和精力，还可以避免一些可能的技术问题和风险。我们希望能够为您提供更好的服务和支持，让您更加放心地使用ChatGPT，接下来给您介绍如何在中国购买ChatGPT账号。


## 进入购买页面：
访问 [https://go.koa.lol/product/account-gpt-life](https://go.koa.lol/product/account-gpt-life "https://go.koa.lol/product/account-gpt-life")，进入ChatGPT成品账号购买页面，并仔细阅读商家公告以及商品描述
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249696/010cc137-b13c-5cb2-9e4a-ec969e88bf97.png)



## 填写订单信息：
填写联系电话，可选择短信通知（需花费0.1元）或邮件通知，非必要无需选择该选项。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249696/2c9ecc8b-4d45-99e0-ced8-0198e21dbc53.png)


## 选择支付方式：
在支付页面中，选择支付宝作为支付方式，并按照提示进行支付操作。如果有其他支付方式，可以选择其他支付方式。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249696/9b5056fb-1425-b1f4-bded-ac3293a10e85.png)
二次确认是否要下单，仔细阅读相关信息，并且点击继续付款
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249696/d99f6d3d-2408-f946-5e6c-073d0a79783a.png)
三次确认，仔细阅读页面上的内容，并按照提示进行支付
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249696/286db18a-9c23-bd04-1e80-1473a7164dbc.png)

## 支付宝扫码付款：
请注意，支付宝付款有时间限制，请在8分20秒内完成付款，否则订单将失效。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249696/91df855d-a829-c575-30fe-26c42c4f8daa.png)


## 完成付款，获得账号密码：
完成付款后，在支付成功页面上获得购买账号和密码。仔细查看红色标记区的位置，上面记载了常见问题及解决办法，实在解决不了就联系客服
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249696/d529548c-b48e-faa3-81b0-6bb7a8aa6a5c.png)


## 登录 ChatGPT 开始使用：

使用购买的账号和密码登录 ChatGPT 网站，开始使用 ChatGPT。
![login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249696/e7b136df-d0d9-6a90-087f-539e6c1017d8.png)


##结论
以上就是 ChatGPT 成品账号购买流程的具体步骤。如果您在购买过程中有任何问题，请随时咨询售后客服。我们希望能够为您提供更好的服务和支持，让您更加放心地使用ChatGPT。
vuetify3小ネタ - 2

# datepickerよりVueDatepickerを利用する
## 参照
* https://vue3datepicker.com/
* document
    * https://vue3datepicker.com/props/modes/
* github
    * https://github.com/Vuepic/vue-datepicker

## メリット
* モデルケースが多い
* カスタムが簡単


# Vuetify3のstyleをカスタム
## 参照
* https://stackoverflow.com/questions/71564313/using-scss-variable-overrides-in-vue-3-with-vuetify-3-beta-using-vue-cli
* https://vuetifyjs.com/ja/features/sass-variables/#webpack-3067306e30a430f330b930c830fc30eb

## 対応
```
@use "vuetify/styles" with (
  $body-font-family: $body-font-family
);
```


# route変更の監視
## 対応
```
const route = useRoute();

watch(
  route,
  (newVal, oldVal) => {
    console.log(newVal.name);
  }
)
```
WindowsPC に NMKD Stable Diffusion GUI をインストールする方法

# 1. はじめに
今回は、自分自身への備忘録を兼ねて、WindowsPC に NMKD Stable Diffusion GUI をインストールする方法を、お伝えしたいと思います。

# 2. この記事を読んでできること
- WindowsPC に NMKD Stable Diffusion GUI をインストールできるようになる
- Stable Diffusion を使えるようになる

# 3. 注意事項
- 18歳以上であること

# 4. 必要なもの
- WindowsPC（この記事では Windows11 を利用）
- グラフィックボード（NVIDIAの「GeForce RTX20」シリーズ以降、VRAM8GB以上）
- HDD または SSD（十分なディスク容量があること）
- インターネット環境（有線LAN推奨）
- キーボード
- マウス
- HDMIディスプレイ

# 5. NMKD Stable Diffusion GUI のダウンロード
- [公式サイト](https://nmkd.itch.io/t2i-gui)を開き、「Download Now」をクリックする
- 「No thanks, just take me to the downloads」をクリックする
- 「SD GUI 1.9.1 (Including SD 1.5 model) 3 GB 」をダウンロードする
- 参考：この記事作成時のファイルバージョン：SDG-1.9.1.7z

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/1ca6effd-f0c6-53c3-4fc2-77d9b98775fd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/7cf9ef7a-f8ff-d8d7-4939-553a2e27ed54.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/a0707e6f-3d82-c369-609b-173f0b1f4d4f.png)

# 6. 7-Zip の インストール
- [公式サイト](https://sevenzip.osdn.jp/download.html)を開き、「(alternative MSI installer) 7-Zip for 64ビット Windows x64 (Intel 64 or AMD64)」版をダウンロードする
- 7-Zip をインストールする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/2a44d115-4771-f378-c7e3-d809d9321da4.png)

# 7. SDG-X.X.X.7z の解凍＆インストール
- ダウンロードした「SDG-X.X.X.7z」ファイルを、7-Zip を使って解凍する

# 8. StableDiffusionGUI の起動
- 「StableDiffusionGui.exe」を起動する
- 確認メッセージが表示されたら「OK」ボタンをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/f1261534-04f4-97eb-e399-9c6ba7898ed2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/22783332-eafa-8bd9-4729-992d7d750af6.png)

# 8. プロンプト の 設定
- 画面左上の1つ目のテキストボックスに「 cat 」と入力する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/546e2e27-8564-d062-7de8-59a98b4edf4e.png)

# 8. Stable Diffusion の 実行（初回実行時のみ数分かかる）
- 「Generate!」ボタンをクリックする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/af908835-5d72-a0dd-af9f-a3db36195285.png)

# 9. おわりに
いかがでしたでしょうか？WindowsPC に NMKD Stable Diffusion GUI をインストールし、Stable Diffusion を実行することができたのではないかと思います
今回の記事が、みなさまの学習の参考になれば幸いです

2023/03/10 TAKAHIRO NISHIZONO

---

# 10. 追記その1：モデルファイルは「.safetensors」拡張子ファイルを入手せよ
- モデルファイルを入手する際は、「.safetensors」拡張子ファイルを入手しましょう
- 「.ckpt」拡張子ファイルは、意図しないプログラム実行の可能性があるようです
- ただし、「.safetensors」拡張子ファイルのままでは、NMKD Stable Diffusion GUIでは使うことができません、「.ckpt」拡張子ファイル（チェックポイント）にコンバートして使いましょう

# 11. 追記その2：モデルファイルをコンバートしよう
- スパナアイコンから「Convert Models」を選択し、「.safetensors」拡張子ファイルから「.ckpt」拡張子ファイル（チェックポイント）にコンバートしましょう
- コンバート後のファイルは、` \SDG-X.X.X\Data\models ` フォルダ内に格納しましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/4f040b41-8599-4307-ce4e-4e7be96b5b32.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/3d541d4b-5d2d-5015-6159-e39fa380a0e2.png)

# 12. 追記その3：モデルファイルを変更しよう
- 歯車アイコンから「Stable Diffusion Model」を変更しましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240522/75c29704-8985-329b-7117-49d00f4878d3.png)
Nuxt3 + prismaでRailsのActiveRecord MySQLデータベースを読み込んだ時に困ったこと

# 起こった事象

`npx prisma db pull`でschema.prismaにDB内容を反映した後`npx prisma generate`でprisma clientにschemaを反映。その後apiを叩いた時に以下のエラーが発生。

```
[nuxt] [request error] [unhandled] [500] Do not know how to serialize a BigInt
```

以下のGithub issueでも話題に上がっているように、どうやらBigIntにtoJsonメソッドが生えていないことが原因のようです。

ActiveRecordはid系のカラムをBigIntで生成しますからね。

https://github.com/prisma/studio/issues/614

解決策は

1. BigIntにtoJsonメソッドを生やす
2. schemaでid系のカラムをIntとしてmappingする

2の場合だとdb pullした時にIntのカラムがBigIntに書き変わってしまい使い勝手が悪いので1の方法で今回は対処しました。

prismaディレクトリ下でprisma clientをexportしているのでそこでBigIntにtoJsonを生やします。
```typescript

import { PrismaClient } from '@prisma/client'

declare global {
  interface BigInt {
    toJSON(): string;
  }
}

BigInt.prototype.toJSON = function (): string {
  return this.toString();
};

const prismaClient = new PrismaClient()

export default prismaClient

```

私の場合はこれで動作しました。参考までに関係ありそうなnpmパッケージのバージョンを以下に記載しておきます。

```json
{
    "@prisma/client": "^4.10.1",
    "nuxt": "^3.2.2",
    "prisma": "^4.10.1",
    "typescript": "^4.9.5"
}
```