OmniAICreator/Qiita-1.07M huggingface dataset:
Cloudflare Pagesでデプロイ時のNode.jsバージョンを指定する

# はじめに
:::note info
この記事で記載するバージョンは執筆当時のものです。参考にする場合は参照を辿って差分を吸収してください。
:::

Cloudflare Pagesではデフォルトでバージョン12.18.10のNode.jsを利用してビルドコマンドの実行を行います([参照](https://developers.cloudflare.com/pages/platform/build-configuration/#language-support-and-tools))。
最近のフレームワークやビルドツールではこのバージョンで動かすことが出来ないことが多いです。例えばAstroはバージョン16.13.0以上が必要ですし、Viteでもバージョン14.18、16以上が必要となっています([参照1](https://docs.astro.build/en/install/auto/#prerequisites)、[参照2](https://ja.vitejs.dev/guide/#%E6%9C%80%E5%88%9D%E3%81%AE-vite-%E3%83%95%E3%82%9A%E3%83%AD%E3%82%B7%E3%82%99%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E7%94%9F%E6%88%90%E3%81%99%E3%82%8B))。
この記事ではそんなツールも動かせるようにするためにCloudflare Pagesのビルド時に使用するNode.jsのバージョンを上げる方法を紹介します。

# 指定可能なNode.jsのバージョン
Cloudflare Pages内で動かせるNodeのバージョンは17.Xまでです([参照](https://developers.cloudflare.com/pages/platform/build-configuration/#language-support-and-tools))。Node.jsのLTSは18系ですのでLTSにできないのは心許ないです。
今回はその中でも唯一メンテナンスモードが続いている16系の最新16.19.0にあげることを目指します([参照](https://github.com/nodejs/release#release-schedule))。


# Cloudflare Pages内の環境変数から設定する
Cloudflare PagesのWeb UIから設定する環境変数で実行時のNode.jsのバージョンを指定することが出来ます。
![スクリーンショット 2023-02-11 11.59.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591069/1bcd4232-c1f4-72b6-9a5b-491b57644596.png)
設定後再ビルドすることで反映されます。下の画像はビルド時のログですが、Nodeバージョンが16.19.0に変わっていることが確認できます。
![スクリーンショット 2023-02-11 11.57.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591069/80ee8642-9bab-4c5d-281d-9a83daa8d019.png)



# アプリケーションのファイルで指定する
`package.json`と同じ階層で`.nvmrc`、`.node-version`にバージョンを指定しておくと自動的に切り替わってくれます。
```:.nvmrc
v16.19.0
```
```:.node-version
v16.19.0
```
nvmやnodeenvなどでNode.jsのバージョン管理を行なっている場合はローカルもビルド時の環境も同時に指定できるのでお得で安全です。
Flutterについて

# Flutter 

Flutterは、Googleが開発したオープンソースのモバイルアプリケーション開発フレームワークです。
Flutterは、Android、iOS、Web、Windows、Mac、Linuxなど、さまざまなプラットフォームで動作する高性能なネイティブアプリケーションを開発するために使用されます。 Flutterの主な構成要素は、Dartプログラミング言語、Flutter SDK、および開発環境であるAndroid StudioまたはVisual Studio Codeです。
 
## Flutter SDK

Flutter SDKには、ウィジェット、アニメーション、グラフィックス、レイアウトなどの開発に必要な多数のライブラリが含まれています。 Flutterの最大の特徴は、UI（ユーザーインターフェイス）をウィジェットとして構築することです。
 
## Flutterのウィジェット
Flutterのウィジェットは、ボタン、テキスト、画像、入力フォーム、レイアウトなど、ほとんどすべてのUI要素を表現することができます。再利用可能で、簡単にカスタマイズでき、高速で美しいアニメーションを実現できる点が特徴的です。

Flutterは、Hot Reload機能により、変更を簡単に反映させることができ、開発者はすばやくフィードバックを得ることができます。

また、Flutterは豊富なコミュニティとドキュメントがあるため、学習や開発が比較的容易です。
 
以上が、Flutterの概要と構成についてのまとめとなります。
 
またQiitaにまとめてみましたので興味がある方は実行してみてください。

ローカルで動くものになってるみたいなのでそこが今後の課題を思います
Flutterの勉強のため２冊購入しました。

https://qiita.com/sunstripe2011/items/20003b54a79f126c94ca

## まとめ

Flutterは、Googleが開発したオープンソースのモバイルアプリケーション開発フレームワークで、Android、iOS、Web、Windows、Mac、Linuxなど、様々なプラットフォームで高性能なネイティブアプリケーションを開発できます。主な構成要素は、Dartプログラミング言語、Flutter SDK、およびAndroid StudioまたはVisual Studio Codeの開発環境です。Flutter SDKには、ウィジェット、アニメーション、グラフィックス、レイアウトなどの多数のライブラリが含まれ、ウィジェットを使用してUIを構築できます。Hot Reload機能により変更を簡単に反映させられるため、開発者はすぐにフィードバックを得られます。豊富なコミュニティとドキュメントもあるため、学習や開発が比較的容易です。Flutterは、近年急速に人気を集めているフレームワークであり、需要が高まることが予想されます。


## 今回購入したプログラミングの本

> 現場で使える Flutter開発入門 (Compass Booksシリーズ) 単行本（ソフトカバー） – 2021/8/24
澤 良弘、上村 隆弘、村岡 直人、多田 幸一 (著)
https://amzn.to/3HG5f2L
単行本（ソフトカバー）
定価 ￥3,993（本体¥3,630 + 税10%）

B2-13 プログラミング・開発

> マルチプラットフォーム対応 最新フレームワーク Flutter 3入門 単行本（ソフトカバー） – 2022/11/22
掌田津耶乃 (著)
https://amzn.to/3I49dU6
単行本（ソフトカバー）
定価 ￥3,300（本体¥3,300 + 税10%）

安定の　秀和システムさん

制作

> サンストライプ

https://sunstripe.main.jp

- https://twitter.com/sunstripe2011
yarnのインストール方法

### 問題
- `yarn run build`でエラーになる。
    ```bash
    $ yarn run build
    00h00m00s 0/0: : ERROR: [Errno 2] No such file or directory: 'run'
    ```

### 解決策
- yarnのバージョンが古いだけ。
- 最新のyarnをインストールすればよい。
    ```bash
    # 古いyarnを削除
    $ sudo apt remove yarn
    $ sudo apt remove cmdtest
    $ sudo apt autoremove

    #　最新のyarnをインストール
    curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
    echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
    sudo apt-get update
    sudo apt-get install yarn
    ```
以上
Looker Studio: Looker Studio からサービスアカウントを使用して BigQuery と接続する

Looker Studio のデータソースとして BigQuery を利用する際に、オーナーの認証情報ではなくサービスアカウントの認証情報を利用したい場合があります。
この手順を実施してサービスアカウントを作成し、データソースの認証情報に設定する事でオーナーの認証情報と切り離せるので、オーナーが退職する場合などに便利です。
[Looker Studio 用に Google Cloud サービス アカウントを設定する](https://support.google.com/looker-studio/answer/10835295#zippy=%2C%E3%81%93%E3%81%AE%E8%A8%98%E4%BA%8B%E3%81%AE%E5%86%85%E5%AE%B9)

面倒くさいので、スクリプトを作成しました。
変数定義部分を書き換えて、Cloud Shell で実行すれば動作するかと思います。
```
#!/bin/bash

# 参考URL:
# https://support.google.com/looker-studio/answer/10835295#zippy=%2C%E3%81%93%E3%81%AE%E8%A8%98%E4%BA%8B%E3%81%AE%E5%86%85%E5%AE%B9

# 変数定義
service_account_id=""  # length between 6 and 30
service_account_display_name=""
project_id=""
service_agent=""  # https://lookerstudio.google.com/serviceAgentHelp
service_account_user="" # Email

# サービス アカウントを作成
gcloud iam service-accounts create $service_account_id \
--description="Use for Looker Studio access to BigQuery" \
--display-name="${service_account_display_name}"

# BigQuery ジョブユーザーの IAM ロールを付与
gcloud projects add-iam-policy-binding $project_id \
--member="serviceAccount:${service_account_id}@${project_id}.iam.gserviceaccount.com" \
--role="roles/bigquery.jobUser"

# BigQuery データ閲覧者のロールを付与
gcloud projects add-iam-policy-binding $project_id \
--member="serviceAccount:${service_account_id}@${project_id}.iam.gserviceaccount.com" \
--role="roles/bigquery.dataViewer"

# サービス アカウント トークン作成者のロールをサービス エージェントに付与
gcloud iam service-accounts add-iam-policy-binding \
"${service_account_id}@${project_id}.iam.gserviceaccount.com" \
--member="serviceAccount:${service_agent}" \
--role="roles/iam.serviceAccountTokenCreator"

# サービス アカウント ユーザーのロールを付与
gcloud iam service-accounts add-iam-policy-binding \
"${service_account_id}@${project_id}.iam.gserviceaccount.com" \
--member="user:${service_account_user}" \
--role="roles/iam.serviceAccountUser"
```

`BigQuery データ閲覧者` ロールは、データセットやテーブルに対して付与する方が安全です。
ModuleNotFoundError: No module named '_ctypes'

### pyenvのインストールで、ModuleNotFoundError: No module named '_ctypes'が出た時。

```
pyenv install 3.7.4
Downloading Python-3.7.4.tar.xz...
-> https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tar.xz
Installing Python-3.7.4...

BUILD FAILED (Ubuntu 18.04 using python-build 2.3.12-16-gc8daaa39)

Inspect or clean up the working tree at /tmp/python-build.20230214083324.13541
Results logged to /tmp/python-build.20230214083324.13541.log

Last 10 log lines:
  File "/tmp/tmplfm0akzd/pip-19.0.3-py2.py3-none-any.whl/pip/_internal/commands/__init__.py", line 6, in <module>
  File "/tmp/tmplfm0akzd/pip-19.0.3-py2.py3-none-any.whl/pip/_internal/commands/completion.py", line 6, in <module>
  File "/tmp/tmplfm0akzd/pip-19.0.3-py2.py3-none-any.whl/pip/_internal/cli/base_command.py", line 20, in <module>
  File "/tmp/tmplfm0akzd/pip-19.0.3-py2.py3-none-any.whl/pip/_internal/download.py", line 37, in <module>
  File "/tmp/tmplfm0akzd/pip-19.0.3-py2.py3-none-any.whl/pip/_internal/utils/glibc.py", line 3, in <module>
  File "/tmp/python-build.20230214083324.13541/Python-3.7.4/Lib/ctypes/__init__.py", line 7, in <module>
    from _ctypes import Union, Structure, Array
ModuleNotFoundError: No module named '_ctypes'
Makefile:1132: recipe for target 'install' failed
make: *** [install] Error 1
```

### 解決策①
```
sudo apt update
sudo apt install zlib1g-dev
pyenv install 3.7.4
```

### 解決策②
```
sudo apt install make build-essential libssl-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
pyenv install 3.7.4
```
ThinkPad X200にFedora 37をインストールした

# ThinkPad X200にFedora 37をインストールした

## 概要

今回インストールしようと思ったのはストレージのパーティション設定を変えて、LVM2を利用して論理的なHDDみたいなものを作って、その上でファイルシステムの動作を試せるようにしたかったため。これは、私がLpic201の勉強をしていて、そのあたりの動作を確認したかったので。

それで、今回使ったパソコンは中古で購入したThinkPad X200というもの。メモリが4GB、SSDに換装済み。

## 作業内容

ネットから落としたFedora37のLXDE版のものをUSBへ書き込んで、
それを使ってインストールした。

途中まではデフォルトですすめてHDDの設定のところで次のような設定に変更。

- /bootはbiosbootにして、サイズは2MB
    - ネットで調べるとサイズは1MBが適切らしい。次回はそうする。
- /用に設定する予定の領域をつくる。
    - まずはboot以外の残りの領域をpv、vgで作る。
    - その中に30GBのlvを作って、/としてつかう。
    - vgの残りはFedora 37インストール後、運用中に領域が欲しくなった時に
    lvcreateで作ってmkfsで使うというようにする。

HDDの設定以外は特に変更せずに進めた。
Fedora 37でLinux Kernel 6.1.11をビルドしてみた

# Fedora 37でLinux Kernel 6.1.11をビルドしてみた

## 作業内容

カーネルのソースは/usr/src/kernelsへダウンロード&コピーしてそこで作業した。ネットで調べるとhomeディレクトリ以下で作業したほうがいいみたいな記事も読んだので、次回はそれを参考にしてみようと思う。

実行したコマンドは下のとおり。

```
su
dnf update
dnf install make gcc flex bison openssl-devel bc elfutils-libelf-devel perl zstd openssl
cd /usr/src/kernels
tar xJf linux-6.1.11.tar.xz
cd linux-6.1.11
cp /boot/config-6.1.10-200.fc37.x86_64 .config
make oldconfig
make 
make modules_install
make install
```

上のコマンドでmakeが一番時間がかかった。私の場合は夜中につけっぱなしで寝て、翌朝、実行結果を確認していた。

make installまで終わると、カーネルのビルド作業は終了。
ネットで読むと、このあとgrub2でデフォルト起動の設定が必要とあったけれど、私の場合はgrubメニューの一番上に今回ビルドしたカーネルの項目がきていて、そのせいかデフォルトで今回のカーネルが起動するようになっていた。
そのため、今回はgrub2の設定はなにもしていない。

## 参考

https://note.com/yamblue/n/n4767d1c718dd

https://qiita.com/OPySPGcLYpJE0Tc/items/f0120d7274216172aedc
Ubuntu 22.04.1 LTS にnpmとnodeをインストールする方法


### 問題
- 色々なインストール方法が散見されるが、インストール後`npm -v`コマンドを打っただけでエラーになったりする。

### 解決策
- 素直に [公式](https://github.com/nodesource/distributions/blob/master/README.md#rpminstall) に書いてあるコマンドでインストールをすればいい。
  ```bash
  curl -fsSL https://deb.nodesource.com/setup_19.x | sudo -E bash - &&\
  sudo apt-get install -y nodejs
  ```

以上。
neosでlogix その113

# 概要
neosでlogixやってみる。
練習問題、やってみた。

# 練習問題
空のオブジェクトから、掴める箱を作れ。

# 手順

- DevToolTipを装着する。
- tキーをクリックする。
- 新規作成をクリック
- 空のオブジェクトをクリック
- 以下の４つのコンポーネントをアタッチ
 Renderering>MeshRenderer
 Assets>Procedural Meshes>BoxMesh
 Physics>Colliders>BoxCollider
 Transform>Interaction>Grabbable
- 設定する
 MeshRenderer
 Mesh: BoxMesh

以上。
C# ローカライズされたリソースのサテライトアセンブリが、実行時にどのような順序で検索、利用されるのか

## はじめに
Resxマネージャーを使用して言語をリソース化しておくとサテライトアセンブリが作られます。
日本語表記を英語表記にしたいときなどに非常に便利なリソース化。
カルチャの設定を変更するだけで、日本語表記から英語表記に変換することができる。
コードはこんな感じ。(特に意味のないコードですがご了承ください)

![2023-01-31_13h37_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3131319/54fc4df2-4e91-7ba1-34ea-e29bfd8bc484.png)


今回は、このローカライズされたリソースのサテライトアセンブリが実行時にどのような順序で検索、利用されるのかを調べてみました。
※ここで出てきたサテライトアセンブリとは、**サテライトアセンブリとは国際化対応の際に作成される特殊なアセンブリ**である。一般に、アセンブリはニュートラルカルチャのリソースのみを含んでいるべきであるが、アセンブリをローカライズしたい場合、**サテライトアセンブリ**を使う。

****

## 実行時にどのような順序で検索、利用されるのか
➀まず**現在実行中のアセンブリのディレクトリで、要求された [CultureInfo.Name] と一致するサブディレクトリ**がないか調べます。
上記コードの場合、ja-JPですね。

➁一致するものがなければサテライトアセンブリを読み込みます。
**サテライトアセンブリ内で要求されたリソース**がないかを調べます。
上記コードの場合、en-US、es-ESですかね。

③これもなければ、**[CultureInfo.Parent]プロパティによって定義されている親カルチャ**を調べます。
親カルチャはenとかjpとかesとかですね。

④親カルチャのプロパティが[CultureInfo.InvariantCulture]のとき、親カルチャの検索は停止し、**既定の (フォールバック) カルチャのリソース**が使用されます。
ここでの、**既定の (フォールバック) カルチャのリソース**はずばりこれでしょう。

![2023-01-31_13h22_22 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3131319/735b026b-9bd9-9d5c-126a-b5a4aa807240.png)
プロジェクトの[プロパティ]-[アプリケーション]-[アセンブリの情報]を選択すると


![2023-01-31_13h55_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3131319/dcf74ef8-7d82-972e-cac5-7add8db0ca5d.png)
言語選択できる画面赤枠が出てくる。

これが既定の (フォールバック) カルチャのリソースとなる箇所。
そしてこれが設定されていないつまり「なし」の状態で④まで来ていた場合、**例外を発生します**。
これを設定しておけば例外の発生は防げるということです。


以上➀～④の順でローカライズされたリソースのサテライトアセンブリが、実行時に検索、利用されているということがわかりました。

## 終わりに
ここまで読んでいただきありがとうございました。
今回は学習メモでありますので、もし間違っていることなどございましたらご指摘いただけると幸いです。引き続き気になった箇所はどんどん投稿していきたいと思います。
Pythonの文字列検索で、対象の左の文字を入手する方法

eva="～～～○gouki～～～"　←○の中に毎回ランダムな数字が入るとして、その数字を入手する方法

対象の右は探しやすいけど、左は情報が無かったので置いときます。
正規表現を学ぶと理解が進むぞ！

```python:search&getleft
import re

# ○には毎回ランダムな数字が入る処理
eva = "くぁｗせｄｒｆ○goukiｔｇｙふじこｌｐ；＠：「」"

# 正規表現で探したい文字列を記述する
evasearch = r'.gouki(.*)'

evacode = re.search(evasearch,eva)
evanumbers = evacode.group(0)
evanumber = evanumbers[0]

print(evanumber)
```
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied

```
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied
```
## 解決策
```
sudo usermod -aG docker your-user
```

 log out and log back in for the changes to take effect.

確認
```
groups 
# users docker
id -nG
# users docker
```
Apex定義でApexクラスが表示されません。


Apex定義でApexクラスが表示されません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/8a0c2d39-8867-3ca7-f226-822c5e44dd5f.png)



[ここに](https://katiekodes.com/flow-apex-defined-data-types/)書いてある通りに作ったのだが....

```
public class GreetingPhrasebook {
    @AuraEnabled public String language;
    @AuraEnabled public String howYouSayHi;
    @AuraEnabled public String howYouSayBye;
}
```


騙された... ２時間ほど悩みました。「引数が指定されていないコンストラクタが必要です」ええ知らん。

[Apex で定義されたデータ型の考慮事項](https://help.salesforce.com/s/articleView?id=sf.flow_considerations_apex_data_type.htm&type=5)

Apex
+ Apex クラスでサポートされているデータ型は、Boolean、Integer、Long、Decimal、Double、Date、DateTime、String です。各データ型で単一値およびリストがサポートされています。複数の Apex クラスを組み合わせて複雑な Web オブジェクトを表すことができます。
+ 項目ごとに @AuraEnabled アノテーションが必要です。
+ **引数が指定されていないコンストラクタが必要です。**
+ クラスメソッドはサポートされません。
+ 項目の getter メソッドはサポートされません。
+ 内部クラスはサポートされません。
+ 内部クラスと同じ名前の外部クラスは、サポートされません。
+ Apex クラスの項目では、参照整合性はサポートされません。たとえば、Car Apex クラスのモデル項目を表現する Apex で定義された変数がフローにあります。このクラスのモデル項目が変更または削除されると、フローが失敗します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/291e4c1f-4426-dc60-6914-c86c7a79860f.png)
リモートにある最新のmainブランチをローカルにあるブランチにマージさせる

## はじめに
リモートリポジトリにある最新のmainブランチを取得して、
ローカルリポジトリにある自身の作成したブランチに取り込む方法。

チームで開発をしている以上、それぞれブランチを切って作業することになります。
その作業ブランチをmainブランチにマージさせて、リモートリポジトリにあげていくわけですが、それを自身のブランチに取り込むことはよくあります。
なので今回はその作業の方法をまとめていきます。

## 方法
### mainブランチに移動する
```terminal
$ git checkout main
```

### git pullでmainを最新にする
```
$ git pull origin main
```

### 開発用ブランチへ移動
```
$ git checkout be-webtest
```

### mergeコマンドでmainの内容を取り込む
```
$ git merge main
```

## 注意点
マージをする際、コンフリクトする可能性があります。
コンフリクトが起こるとマージできないので、修正する必要があります。
基本的にコードを見ればコンフリクトの理由がわかるかと思いますので、冷静に見るようにしましょう。

以上
SSMS で Poor Man's T-SQL Formatter が正しく読み込まれない場合の対処

こんな画面が出たので対処を調べてみました
「'FormatterPackage' パッケージは正しく読み込まれませんでした」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542459/7239481f-85a5-a949-cde4-004037c86892.png)

# 対処
ssms.exe.config に下記のコードを追加

```C:\Program Files (x86)\Microsoft SQL Server Management Studio 18\Common7\IDE\ssms.exe.config
            <dependentAssembly> 
				<assemblyIdentity name="Microsoft.VisualStudio.Shell.12.0" publicKeyToken="b03f5f7f11d50a3a" culture="neutral"/> 
				<bindingRedirect oldVersion="2.0.0.0-15.0.0.0" newVersion="15.0.0.0"/> 
			</dependentAssembly>
```

# 環境
SQL Server Management Studio v18.10
PoorMansTSqlFormatterSSMSPackage.Setup.1.6.16.msi

# 参考
[Poor mans T-SQL formatting add-in "Format T-SQL Code" option disabled in SQL Server Management Studio v18.5](https://stackoverflow.com/questions/63313632/poor-mans-t-sql-formatting-add-in-format-t-sql-code-option-disabled-in-sql-ser)
※詳しい動作について解る方はぜひコメントください
[prisma] Database error code: 3780 外部キー制約エラーを解消した話

## 環境
- MacOS
- MySQL 8.0
- prisma 4.6.1

## 概要
- 照合順序を変更するマイグレーションを一部テーブルに適用したところ、エラーが発生した。

```
Database error code: 3780

Database error:
Referencing column 'xxxx' and referenced column 'yyyy' in foreign key constraint 'zzzz' are imcompatible.
```

※カラム名はぼかしています。

## 原因
* 外部キーと紐づくテーブルの照合順序を変更していないため。

https://dev.mysql.com/doc/refman/5.6/ja/create-table-foreign-keys.html

> 外部キー定義は、次の条件に従います。
> (...中略)
> **外部キー内の対応するカラムと、参照されるキーは同様のデータ型を持っている必要があります。** 整数型のサイズと符号が同じである必要があります。文字列型の長さが同じである必要はありません。バイナリ以外の (文字の) 文字列カラムの場合、 **文字セットと照合順序が同じである必要があります。**



## 解決方法
* 外部キーと紐づくテーブルに対して照合順序変更する
* 以下の順でマイグレーションファイルを編集
  * 外部キーを取り除く->照合順序変更->取り除いた外部キーを再度付与

上記を実施することでマイグレーションが完了した。

## 参考
* https://qiita.com/ucan-lab/items/976d4d8b45685b1a4ada

以上
Laravel 便利な関数 ライブラリー

# Laravelでよく使う便利な関数orライブラリー

Laravelでよく使う便利な関数orライブラリーを紹介していきます。

## パスワードのハッシュ化
```
Controller

use Illuminate\Support\Facades\Hash;

  $mymy->password = Hash::make($request->password);
  //下記のようにランダムにハッシュ化される
   //$2y$10$c0XnxIoqscqkkO4vxvdyxeXF6aLSxZOKR.Ye4fWhBlhiHulhxg1Ju

```

## Carbon ライブラリー
Laravelに標準で搭載されているライブラリーでcreated_atやupdated_atはCarbonインスタンスとして取得されます。


Carbonをcreated_atを組み合わせると
 
#### 2023-02-13 16:08:00
### ↓                
#### 22時間前
と変更することが可能です!

記述方法
```
<p>{{$my->created_at->diffForHumans()}}</p>
```

->diffForHumans()と付けるだけで変更できます。



詳しくCorbonを知りたい方は
https://coinbaby8.com/carbon-laravel.html

## Deleteソフトデリート
論理削除(ソフトデリート)->復元できる（ごみ箱のようなもの）
物理削除(デリート)->復元できない(永久削除)

マイグレーション側upメゾット 記述
```
database/migrations/
$table->softDeletes();
```


モデル側  記述
app/Models/
```
use Illuminate\Database\Eloquent\SoftDeletes;
```
モデル内のクラス記述
```
use SoftDeletes;
```
コントローラー側　記述
```
Model::findOrFail($id);//IDごとに指定してソフトデリート
Model::all();//ソフトデリートしたものは表示されない

Model::onlyTrashed()->get();ごみ箱のみ表示
Model:withTrashed()->get();ごみ箱も含めてすべて表示

Model::onlyTrashed()->whereId($id)->restore();//IDを指定して復元
Model::onlyTrashed()->restore();//すべて復元

Model::onlyTrashed()->whereId($id)->forceDelete();//IDを指定して完全削除
Model:onlyTrashed()->forceDelete();//ごみ箱すべて完全削除

$model=Model::all():
$model->trached();//ソフトデリートされているかの確認

```

### Delete アラート表示
ついでにjsでのアラートの方法も記述します。
view側記述
```
<form method="post"action="">
button type="submit" onclick="deletePost(this)><削除>
</form>

javascript

<script>
function deletePost(e) {
'use strict';
if (confirm('本当に削除してもいいですか?')) {
document.getElementById('delete_' + e.dataset.id).submit();
}
}
</script>
```

##  フラッシュメッセージとは

フラッシュメッセージとは、そのリクエストの間だけ表示される一時的なメッセージのことです。

例えば、以下の動画のようにエラーメッセージを表示したり、処理が完了したことをお知らせするときなどに使われます。

まず手順として
resources/view/components/の中でflash-message.blade.phpを作成(名前は何でも大丈夫です)
```
//flash-message.blade.php

@props(['status' => 'info'])

@php
//session('status')の中身によって色を変える処理

    if (session('status') =='info') {
        $bgColor = 'bg-blue-300';
    }
    if (session('status') == 'alert') {
        $bgColor = 'bg-red-500';
    }
    if(session('status')==='fukugen') {
        $bgColor = 'bg-green-500';
    }
    if(session('status')==='sakujyo'){
        $bgColor = 'bg-red-600';
    }
@endphp

//session('message')があれば上の色とmessageを入れる
@if (session('message'))
    <div class="{{ $bgColor }} w1/2 mx-auto p-2 text-white">
        {{ session('message') }}
    </div>
@endif
```
```
//Controllers

 return redirect()->route(リダイレクトさせたい場所)->
   with(['message'=>'削除しました','status'=>'alert']);

with関数で連想配列でフラッシュメッセージで表示させたい内容と
flash-message.blade.phpのif文で指定した色によって値を入力)
```
```
view(controllerで指定したリダイレクト先 又はフラッシュメッセージを表示させたい場所)

<x-flash-message status="session('status')" />


```
これだけの記述OK
componentなので色んな所で使いまわすことが出来てとても便利です。
再帰的(リカーシブ)プログラム

# 再帰的(リカーシブ)プログラム
再帰とは、```プログラムを実行中に自分自身を呼び出して実行しても、正しい結果を返す```ことができるプログラム構造

## 再帰の実現手法
この再帰的処理のためには、自分自身を呼び出すごとに局所変数(ローカル変数）のセットを一新し、以前のものとは独立させる必要がある。そのため、自分自身を呼び出す前に局所変数の内容をスタックに退避し、呼び出したプログラムから戻ったとき、スタックから取り出す、```LIFO(Last-In First-Out)方式```による処理が必要になる。

# 出典
https://gihyo.jp/book/2022/978-4-297-12375-8

### 気づき
こういう処理にもLIFOが使われているのか。

# 問題
```
proc(n)
　n＝0 ならば戻る
　そうでなければ
　{
　　nを印字する
　　proc(n－1)を呼び出す
　　nを印字する
　}
　を実行して戻る
```

### 気づき
```戻る```とはプログラムの先頭に戻ることをさしていたのか。
知らなかった。
PySimpleGUIでのイベント設定方法

# はじめに
今回はPySimpleGUIでイベントを設定する方法についての記事になります。

イベントのイメージとしては
「GUI上でボタンが押されたときにXXXXする。」みたいな動作があるとすると、
「ボタンが押される」っていうところがイベントです。

PySimpleGUIでは、デフォルトでイベント設定されているものと、されていないものがあるので
その点はリファレンスなど参照の上、注意して実装していく必要があります。
（PySimpleGUIのドキュメント：https://www.pysimplegui.org/en/latest/）

# デフォルトでイベント設定されているwidgetを使ったイベント設定
ここでは、文章を入力しボタンを押すと、文章の前後に***が装飾された文章がポップアップされるコードを紹介します。
＊２つのウィジェットにkeyという引数で、識別子を与える
＊ボタンはデフォルトでイベント設定されているので、ボタンが押されたときにeventに識別子が格納される
＊入力系のwidgetに与えた値は values[設定した識別子] で確認できる
＊ボタンは入力系のwidgetではないので、values['-BUTTON-']とするとエラーになる
```python:demo1.py
import PySimpleGUI as sg

input_widget = sg.InputText(default_text="ここに文字を入力してください。",key="-INPUT-")
button_widget = sg.Button("ポップアップの表示",key="-BUTTON-")
layout = [
            [input_widget],
            [button_widget],
         ]

window = sg.Window("sample1",layout)

while True:
    event, values = window.read()
    if event == sg.WIN_CLOSED:
        break
    if event == '-BUTTON-':
        popup_text = "***"+values['-INPUT-']+"***"
        sg.popup(popup_text)
        
window.close()
```

# デフォルトでイベント設定されていないwidgetを使ったイベント設定
ここではラジオボタンのチェックに応じて、表示内容が変わるコードを紹介します。
＊Radioボタンはデフォルトではイベント設定されないので、enable_event=Trueでイベント設定をかける
＊Radioボタンを選択した際に格納されるvalueはTrue/False
＊どのボタンが押されたかはif文で判定し、押されたボタンに対する処理を記述
```python:demo1.py
import PySimpleGUI as sg

check_widget1 = sg.Radio(text="A",group_id=1,enable_events=True,key='-Check-')
check_widget2 = sg.Radio(text="B",group_id=1,enable_events=True,key='-Check-1')
check_widget3 = sg.Radio(text="C",group_id=1,enable_events=True,key='-Check-2')

text_widget = sg.Text(text="現在Aを選択中です。")

layout = [
            [check_widget1],
            [check_widget2],
            [check_widget3],
            [text_widget]
          ]

window = sg.Window('demo',layout)

while True:
    event, value = window.Read()
    if event == sg.WIN_CLOSED:
        break
    if '-Check-' in event:
        if value["-Check-"]:
            text_widget.update(value="現在Aを選択中です。")
        elif value["-Check-1"]:
            text_widget.update(value="現在Bを選択中です。")
        elif value["-Check-2"]:
            text_widget.update(value="現在Cを選択中です。")
        else:
            pass
        
window.close()
```

# 終わりに
今回はイベントの設定方法について書いてみました。
チェックボックスやラジオボタンの選択状況に応じて、リアルタイムに表示内容が変化するのはおもしろいですよね。
PySimpleGUIではwidgetの値の更新にupdateメソッドを使いますが、何をupdateできるかはwidget毎に変わりますので、
ドキュメントも気が向いたときに参照してみてください。
お疲れ様でした。
新しいBingのAIチャットで漢字変換を確定させるときに意図せず送信されるのを防ぐ

windowsだと大丈夫だったけどうちのM1 macbook Airくんだと海外アプリあるあるが起こってたのでブラウザ拡張で対応した

```JavaScript:content.js
function sleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms))
};


(async () => {
    var input = null;
    while (1) {
        try {
            input = document.getElementsByClassName('cib-serp-main')[0].shadowRoot.getElementById("cib-action-bar-main").shadowRoot.getElementById('searchbox');

            if (input) {
                console.log(input);
                input.addEventListener("keydown", event => event.stopPropagation(), true);
                input.addEventListener("keyup", event => event.stopPropagation(), true);
            }
            break;
        }
        catch (e) {
            //console.log(e);
            await sleep(500);

        }
    }
})();
```


ブラウザ拡張機能の詳細については省略。manifestファイルで"content_scripts"から上記スクリプトを読み込みます。
これするとEnter押すイベントそもそもから無効にしているので手動で送信ボタンをクリックしないといけないけどいちいち送信されるよりはマシ。
まだpreviewなようなので変更来たらすぐ機能しなくなると思いますがある程度参考になれば幸いです。


参考
https://stackoverflow.com/questions/35070496/can-i-remove-event-listeners-with-a-chrome-extension
「ゼロから作る　Deep Learning」　1章　学習内容アウトプット　2日目

学んだことをアウトプットしています。完全に自己満足ですので悪しからず。
以下の点を確実にアウトプット
①何で学んでるか
②日々の学習内容
③学びのポイント
④制作物
⑤+αで参考にした記事
⑥+αでやってみたこと

①１章　Python入門

②
　・Pythonスクリプトファイル
　　⇒Pythonインタプリタは対話的に実行できるモードで簡単な実験には向いているが、
　　　まとまった処理を行うのは面倒。そのような場合にはPythonプログラムをファイルとして保存し、
　　　そのファイル（スクリプトファイル）をまとめて実行する。
　・ファイル保存
　　⇒テキストエディタでコード保存（今回はVisual Studio Code）
　　　コマンドプロンプトで
　　　cd ディレクトリ
     を入力し、
　　　python ファイル名
　　　で実行
　・クラス
　　⇒ここだけの説明だけだと正直意味不明のため、ここで一旦ProgateのPythonｺｰｽを受講することにした
    progate受講完了。再開（4/22）
　　●コンストラクタ：初期化用メソッド。クラスのインスタンスが作成される際に一度だけ呼ばれる。
　　●インスタンス変数：ここのインスタンスに格納される変数のこと。
　　

③なし
④コマンドプロンプトでコードの試し打ち
⑤なし
⑥なし
スタック、キュー

# スタック
```
function ƒ(x) {
　p＝p＋1;
　A[p]＝x;
　return None;
}
function g() {
　x＝A[p];
　p＝p－1;
　return x;
}
```
## 後入れ
```
function ƒ(x) {
　p＝p＋1;
　A[p]＝x;
　return None;
}
```
### 気づき
* pはポインタの役割をしていたのか
* ```p+1```は配列の末尾にプッシュする時のアドレス計算

## 先出し
```
function g() {
　x＝A[p];
　p＝p－1;
　return x;
}
```
### 気づき
* ```p-1```は配列の末尾の要素をポップする時のアドレス計算
* ```return x;```で取り出している

# キュー
先入れ先出しのデータ構造になっている。

### 気づき
キューのアルゴリズムの問題にあたって頑張ろう。

# ハッシュ
任意のデータから```一意に求めた固定長のデータ```

# ヒープ
```親の値は子の値以上```という制約で構成された木構造

# 出典
https://www.fe-siken.com/kakomon/03_menjo/q7.html
<LoadError: Error loading the 'sqlite3' Active Record adapter. Missing a gem it depends on? sqlite3 is not part of the bundle. Add it to your Gemfile.>これでrailsのサーバーが立ち上がらない

# 概要
rails sしてサーバーは立ち上がったが、このようなエラーがターミナルで出る。
解決はすぐだったので書きます。

# 環境
rails 7.0.4.2
ruby 3.1.2
AWS 
cloud9
linux
mac

# 解決法
もう一発で書きます。
gemに
```rails:Gemfile
gem 'sqlite3'
```

これを足してbundle install。これで解決。
意外とgemfileは見落としてしまうので、しっかり確認することは初歩的ですが大事だと思いました。
assert method

assertを、入力値チェック、出力値チェック、コンストラクタチェックなどに使う
assertはデフォルト無効なため、java -eaオプションで実行すること
```java
class Item{
    private String name;
    private int price;

    public Item(String name, int price) {
        this.name = name;
        this.price = price;
        assert price > 100 : "constructor price over error";
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        assert price > 100 : "set price over error";
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
class Order{
    Item item;
    int amount;

    public Item getItem() {
        return item;
    }

    public void setItem(Item item) {
        this.item = item;
    }

    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }

    public Order(Item item, int amount) {
        this.item = item;
        this.amount = amount;
    }
    int calc() {
        return this.item.getPrice() * this.amount;
    }
}
public class Outer {
    public static void main(String args[]) {
        Item i = null;
        i = new Item("apple",50);
        i.setPrice(150);
        int amount = 30;
        Order o = new Order(i,amount);
        int oPrice = o.calc();
        assert oPrice == i.getPrice() * amount: "calc price error";
    }
}
```
```
C:\Users\***\Documents\NetBeansProjects\mavenproject1\target\classes>java -ea com.mycompany.mavenproject1.Outer
Exception in thread "main" java.lang.AssertionError: constructor price over error
        at com.mycompany.mavenproject1.Item.<init>(Outer.java:15)
        at com.mycompany.mavenproject1.Outer.main(Outer.java:66)
```
cannot load such file -- listen (LoadError)によってrails sできない！

# 概要
rails sでサーバーを起動しようとしたのですが、できませんでした。
解決までの道のりをメモ的に記します。初心者向けですので、詳しい方で「もっと良い解決法がある」「その方法はダメだ」ということがあればご指摘ください。

# 起こったこと
```rails:ターミナル
ec2-user:~/environment/アプリ名 (main) $ rails s
=> Booting Puma
=> Rails 7.0.4 application starting in development 
=> Run `bin/rails server --help` for more startup options
Exiting
/home/ec2-user/.rvm/gems/ruby-3.1.2/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:15:in `require': cannot load such file -- listen (LoadError)
~
~
~
```

# 解決法
「nulfasのブログ」様の[【Rails】「Could not load the ‘listen’ gem. Add `gem ‘listen’` to the development group of your Gemfile (LoadError)」 が出た時](https://nllllll.com/ruby-on-rails/rails-could-not-load-error/)を参考にさせていただきました。

```config.environment.development.rb

  config.file_watcher = ActiveSupport::EventedFileUpdateChecker
  #↑コメントアウトする

end
```

これで解決しました！
cloud SDK sudo apt update の GPG エラーについて

# 動作環境
- Windows11 Home
- WSL2 Ubuntu 20.04.5 LTS

# 本文
`sudo apt update` 時にGPGエラーが出力された。

```shell-session
~$ sudo apt-get update
取得:3 https://packages.cloud.google.com/apt cloud-sdk InRelease [6,361 B]
エラー:3 https://packages.cloud.google.com/apt cloud-sdk InRelease
  公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY B53DC80D13EDEF05
```

下記のコマンドで正常にアップデートできた。

```shell-session
~$ curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1210  100  1210    0     0   6648      0 --:--:-- --:--:-- --:--:--  6612
OK

~$ sudo apt update
取得:3 https://packages.cloud.google.com/apt cloud-sdk InRelease [6,361 B]
取得:4 https://packages.cloud.google.com/apt cloud-sdk/main amd64 Packages [390 kB]
```

# 参考文献
https://cloud.google.com/compute/docs/troubleshooting/known-issues?hl=ja#keyexpired-2

https://stackoverflow.com/questions/49582490/gpg-error-http-packages-cloud-google-com-apt-expkeysig-3746c208a7317b0f
ハフマン符号化

# 符号化されたビット列から元のメッセージが一意に復号可能であって，ビット列の長さが最も短くなるものはどれか。

ここで使われたのが```ハフマン符号化```だ。

# ハフマン符号化とは？
ハフマン符号化とは、1952年にデビッド・ハフマン（David Albert Huffman）氏によって開発された符号で、データの可逆圧縮などに使用されるものです。

可逆圧縮は元に戻すことができる圧縮のことです。

# 出典
https://medium-company.com/%E3%83%8F%E3%83%95%E3%83%9E%E3%83%B3%E7%AC%A6%E5%8F%B7%E5%8C%96/#3_2:~:text=%E3%83%8F%E3%83%95%E3%83%9E%E3%83%B3%E7%AC%A6%E5%8F%B7%E5%8C%96%E3%81%A8%E3%81%AF%E3%80%811952,%E3%81%8C%E3%81%A7%E3%81%8D%E3%82%8B%E5%9C%A7%E7%B8%AE%E3%81%AE%E3%81%93%E3%81%A8%E3%81%A7%E3%81%99%E3%80%82

### 気づき
文字を符号化の際は```元に戻すことができないとダメ```なのか。
だから最初に可逆性があるかどうかを調べたのか。

# 平均ビット列
```
(1×0.5)＋(2×0.3)＋(3×0.1)＋(3×0.1)＝0.5＋0.6＋0.3＋0.3＝1.7
```
これでビット数と確率をかけることで平均ビット列を求めることができるのか。

# 感想
まだまだ知らないことがたくさんある。
頑張ろう。

# 出典
https://www.fe-siken.com/kakomon/03_menjo/q6.html
bundle installできない！

# 概要
railsチュートリアルで学ぼうとして、環境を構築している最中に起こったことです。
解決までの道のりを自分なりにまとめていきます。

# 環境
mac
AWS
cloud9
linux

# 起こったこと

```rails:ターミナル
ec2-user:~/environment/アプリ名 (main) $ bundle _2.3.14_ install                                                                                  
Fetching gem metadata from https://rubygems.org/..........
Resolving dependencies...
Bundler could not find compatible versions for gem "activesupport":
  In snapshot (Gemfile.lock):
    activesupport (= 6.1.7.2)

  In Gemfile:
    jbuilder (= 2.11.5) was resolved to 2.11.5, which depends on
      activesupport (>= 5.0.0)

    rails (= 7.0.4) was resolved to 7.0.4, which depends on
      activesupport (= 7.0.4)

    sprockets-rails (= 3.4.2) was resolved to 3.4.2, which depends on
      activesupport (>= 5.2)

Running `bundle update` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.
```
なんだろう...
__Running `bundle update__
これだ！

```rails:ターミナル
ec2-user:~/environment/アプリ名 (main) $ bundle update
Fetching gem metadata from https://rubygems.org/...........
Resolving dependencies....
〜〜〜
Bundle updated!
```
できたわ...

railsってアプリ作ったことがある人はわかると思うのですが、エラー分がわかりづらかったり、支離滅裂なことを提案している感があって、あまり参考にしていなかったんです。~~私の勉強不足ですね...~~

エラー文をよく読む。これからはそれを意識します...

# 参考にさせていただいた記事
[【Rails】Gemのバージョンエラー「Bundler could not find compatible versions for gem」が出てきたときの対処法](https://qiita.com/blackpeach7/items/fafdee0a564119db5e9d)
array pushってこんな動きだったっけ？ 🤔

# なんかおもったプッシュと違う

さっそくコードと結果
```
@select_count = Array.new(9, [])

p @select_count[8]
p @select_count[8].push(38)
p @select_count
```

予想してた結果
```
[]
[38]
[[], [], [], [], [], [], [], [], [38]]
```

結果
```
[]
[38]
[[38], [38], [38], [38], [38], [38], [38], [38], [38]]
```

# なんでこうなったか

2次元配列の初期化の方法が間違っていた

```
@select_count = Array.new(9){ Array.new() }

p @select_count[8]
p @select_count[8].push(38)
p @select_count
```

結果
```
[]
[38]
[[], [], [], [], [], [], [], [], [38]]
```

予想通りになりました。

# まとめ

pushはまちがってなかった
初期化がまちがってました

~~でもなんで全部に38が反映されるかロジックは謎のままにしてます~~


# なんで全部に38が反映されるか

気になってオブジェクトのIDだしてみたら
同一のオブジェクトが生成されるみたいでした。

```
@select_count = Array.new(9, [])

p @select_count[5].object_id
p @select_count[6].object_id
p @select_count[7].object_id
p @select_count[8].object_id


60
60
60
60
```

```
@select_count = Array.new(9){ Array.new() }

p @select_count[5].object_id
p @select_count[6].object_id
p @select_count[7].object_id
p @select_count[8].object_id

80
100
120
140
```
javascript classを使ってランダムな位置にランダムな円を描画する

クラスはオブジェクトの設計書

クラス宣言内でクラスを宣言する際にはコンストラクターとメソッドで定義していきます。
コンストラクタとメソッドの書き方は以下の通りです。

```javascript:class.js
class Member {
    //コンストラクタ
    constructor(fitstName, lastName) {
     this.firstName = firstName;
     this.lastNamr = lastName;
 }
    //メソッド
    getName() {
     return this.lastName + this.firstName;
 }
}

let m = new Member('太郎', '田中');
console.log(m.getName()); //結果:山田太郎
```

クラスの使い方が分かったので、canvasを使ってランダムな位置にランダムな円を描画してみました。


```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ランダムな位置にランダムな円を描く</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
    <canvas id="canvas"  width="500" height="500"></canvas>
    <div class="canvas-txt"><h1>Sample</h1></div>
  
  <script type="text/javascript" src="main.js"></script>
</body>
</html>
```

```javascript:main.js
class Circle {
  // コンストラクタ
  constructor() {
    this.x = Math.floor(Math.random() * canvas.width); // x座標
    this.y = Math.floor(Math.random() * canvas.height); // y座標
    this.r = Math.floor(Math.random() * 50) + 1; // 半径
  }
  // 描画メソッド
  draw() {
    g.beginPath();
    g.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);
    g.stroke();
  }
}

var canvas = null; //キャンバス
var g = null; //コンテキスト

window.addEventListener("load", () => {
  canvas = document.getElementById("canvas");
  g = canvas.getContext("2d");

  for (let i = 0; i < 100; i++) {
    let arc = new Circle();
    arc.draw();
  }
});

```

参考：https://dianxnao.com/%E5%A1%97%E3%82%8A%E3%81%A4%E3%81%B6%E3%81%97%E5%86%86%E3%82%92%E3%82%AD%E3%83%A3%E3%83%B3%E3%83%90%E3%82%B9%E3%81%AB%E6%8F%8F%E3%81%8F%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6/
Rowの中の左右のTextがOverflowを起こしてしまった時の対応方法

# 困ったこと

入力画面で左右にTextを配置するよくあるデザイン。

![スクリーンショット 2023-02-14 14.20.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104642/0e3fd438-c778-8612-f267-92fb9057bdad.png)
コードを書くならきっとこんな感じ。
```dart
Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  children: [
    const Text('メールアドレス'),
    Text('必須項目',
        style: Theme.of(context)
            .textTheme
            .labelLarge
            ?.copyWith(color: Colors.red, fontSize: 12.0))
  ],
),
```


でも、システムフォントサイズを最大にするとオーバーフローを起こします。
![スクリーンショット 2023-02-14 14.21.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104642/fdf2be2d-3a57-93f1-9a5a-63daa70fe34a.png)

```
════════ Exception caught by rendering library ═════════════════════════════════
The following assertion was thrown during layout:
A RenderFlex overflowed by 113 pixels on the right.

The relevant error-causing widget was
Row
verify_email_page.dart:29
You can inspect this widget using the 'Inspect Widget' button in the VS Code notification.
The overflowing RenderFlex has an orientation of Axis.horizontal.
The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and black striped pattern. This is usually caused by the contents being too big for the RenderFlex.

Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the RenderFlex to fit within the available space instead of being sized to their natural size.
This is considered an error condition because it indicates that there is content that cannot be seen. If the content is legitimately bigger than the available space, consider clipping it with a ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex, like a ListView.

The specific RenderFlex in question is: RenderFlex#f2be1 relayoutBoundary=up3 OVERFLOWING
════════════════════════════════════════════════════════════════════════════════
```

# 対応方法
FlexibleとFittedBoxでWrapしてあげましょう。
```dart
Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  children: [
    const Flexible(child: FittedBox(child: Text('メールアドレス'))),
    Flexible(
      child: FittedBox(
        child: Text('必須項目',
            style: Theme.of(context)
                .textTheme
                .labelLarge
                ?.copyWith(color: Colors.red, fontSize: 12.0)),
      ),
    )
  ],
),
```
見た目は酷いけど、エラーは無くなりました。
![スクリーンショット 2023-02-14 14.31.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104642/82b97ee2-b46d-86f1-653f-9c7b07322a7a.png)

# 終わりに
見た目はとても大事ですが、文字が大きくないと見えないユーザーにも対応してあげた方がユーザーの満足度は上がると思います。
文字サイズを固定にしてしまう方法もありますが、ある程度デザインを保ちつつ表示を大きくしたい場合はこちらを実装してみるのはいかがでしょうか。
E2Eで2段階認証を突破する

結構大変なんだろうなと思いつつやってみたらすごく簡単だった。

## totp-generator
2段階認証の設定をした際の秘密鍵を控えておく
[totp-generator](https://github.com/bellstrand/totp-generator)
こちらのライブラリを使用させていただくだけ。

```ts
import getToken from "totp-generator";

function main() {
  if (!process.env.MFA_SECRET_KEY) {
    throw new Error("required set MFA_SECRET_KEY");
  }
  const token = getToken(process.env.MFA_SECRET_KEY);
  console.log(token);
}
```

これだけで2段階認証用の6桁コードが取れる。
オプションで桁数やアルゴリズムなども変更可能。素晴らしい。
Nuxt3 – useCookie で secure / httponly のCookieを利用する (作成・削除)

特にプラグイン不要で利用できるようだ

# コード例

```js
// 定義
const fooCookie = useCookie('foo-key', { secure: true, httpOnly: true })

// セット
fooCookie.value = "bar-value"

// 利用(取得)
fooCookie.value

// 削除
fooCookie.value = null
```

# 参考

https://nuxt.com/docs/api/composables/use-cookie


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
ChatGPTで「Lambdaにて15分以上の処理を行いたい」場合の解決策を聞いてみた【メモ】

## 質問
AWS Lambdaで15分以上時間のかかる処理を解決するには？

## 回答
AWS Lambdaは、最大実行時間が15分まで制限されています。15分以上かかる処理を実行する場合は、以下のような方法が考えられます。

AWS Step Functionsを使用する：AWS Step Functionsを使用して、Lambda関数を複数のステップに分割し、ステップごとに異なるLambda関数を実行することができます。

AWS Fargateを使用する：AWS Fargateを使用して、コンテナベースのアプリケーションを実行できます。AWS Lambdaと同様に、Fargateもイベント駆動型であり、必要に応じてスケールアップ/ダウンすることができます。

別のサービスに処理をオフロードする：処理をAWS Lambdaから別のサービスにオフロードすることで、処理時間を短縮できる場合があります。たとえば、長時間のバッチ処理を実行する場合は、AWS Batchを使用することができます。

処理を分割する：処理を小さなタスクに分割して、それぞれを別々のLambda関数で処理することができます。この方法では、各関数が15分以内で完了するようにする必要があります。

![aws-lambda-15min-over.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867775/38e2fee2-16be-937a-56c1-e03e5331faf2.png)


## 質問2：Lambda, AWS Step Functions
### AWS LambdaとAWS Step Functionsを使用して、15分以上かかる処理を実行できるようにしたいです。どのようにすればいいですか？

AWS Lambdaは最大で15分までの処理時間制限がありますが、AWS Step Functionsを使用することで15分以上かかる処理も実行できます。

AWS Step Functionsは、複数のLambda関数、API Gateway、ECS、DynamoDB、SNS、SQSなどのサービスを一つのワークフローとして連携させることができます。15分以上かかる処理を複数のLambda関数に分割し、Step Functionsで実行することで、処理を継続的に実行することができます。また、Step Functionsは、処理の進捗状況やエラーの発生状況などをモニタリングすることもできます。

具体的な手順としては、以下のような流れになります。

処理を複数のLambda関数に分割する
Step FunctionsでLambda関数を連携させる
必要に応じて、API Gateway、ECS、DynamoDB、SNS、SQSなどのサービスを連携させる
処理の進捗状況やエラーの発生状況をモニタリングする
AWS Step Functionsは、AWSのマネージドサービスの一つであり、設定や管理が簡単なため、比較的容易に導入することができます。

![lambda-stepfunctions.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867775/ae72b39e-d3a3-51cc-930d-a1edd421ce16.png)

---

## 質問3: Lambda, AWS Batch
### AWS LambdaとAWS Batchを使用して、15分以上かかる処理を実行できるようにしたいです。どのようにすればいいですか？
AWS Lambdaは最大実行時間が15分までなので、15分以上かかる処理を実行するためにはAWS Batchを使用することができます。AWS Batchは、バッチジョブを作成、スケジュール、実行するためのサービスです。

以下は、AWS LambdaとAWS Batchを使用して15分以上かかる処理を実行する手順です。

AWS Batchでジョブ定義を作成します。ジョブ定義には、実行するバッチジョブのコマンドや引数、実行環境などが含まれます。

AWS Lambdaで、バッチジョブを実行するトリガーとなる関数を作成します。この関数では、AWS BatchのAPIを使用して、バッチジョブを実行します。

Lambda関数が呼び出されると、バッチジョブがAWS Batchによってスケジュールされ、実行されます。

バッチジョブの実行が完了すると、AWS Batchは結果を収集し、Lambda関数に返します。

このように、AWS Batchを使用することで、AWS Lambdaよりも長時間かかるバッチ処理を実行することができます。

![lambda-awsbatch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867775/6783c26f-7475-180b-efbe-01a16d6d5e46.png)
【SwiftUI】ScrollViewのスクロール最下部にマージンを設定する

# 問題
SwiftUIの`ZStack`内に
・`ScrollView`内の`ForEach`で生成した`View`
・画面下部に設置した`Button`
を配置すると、最下部までスクロールしても、`View`と`Button`が被ってしまうということがありました（Ex.下図）。

<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655077/bb28987b-f6d6-26d9-6400-62e5db698477.gif"/>

`UIKit`の`UITableView`では、
```swift
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 60, right: 0)
```
のように`contentInset`を指定することで対応していましたが、SwiftUIでの対応が分からず、備忘録として残します。

# 解決策
```swift
ScrollView {
    ForEach(array, id: \.self) {string in
        Text(string)
    }
    // ForEachの後ろに空白を挿入する
    Color.clear.padding(.bottom, 60)
}
```
上記のように、`ScrollView`内で`ForEach`の下に`Color.clear`を挿入することで解決できます。
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655077/2a96a03c-e7a5-f081-88a1-9bfb2473a987.gif"/>

# 開発環境
- Xcode 14.2
- iOS 16 and later

# 参考URL
- [How to set contentInset of a ScrollView in SwiftUI](https://stackoverflow.com/questions/62639415/how-to-set-contentinset-of-a-scrollview-in-swiftui)
顧客分析の手順 - 分析フォーマットの適用例:関連性分析 獲得顧客を呼び込んだ商品／サービスの理解  

:::note
この本書は2017年4月1日にTeradata Japanのブログに掲載された内容を、再掲載したものです。
掲載内容の正確性・完全性・信頼性・最新性を保証するものではございません。
また、修正が必要な箇所や、ご要望についてはコメントをよろしくお願いします。
:::


著者 山本 泰史 （やまもと やすし）


# 顧客分析の手順

## 第20回： 獲得顧客を呼び込んだ商品／サービスの理解
今回より、関連性分析という分析手法を利用した分析例をご紹介していきます。関連性分析は商品やサービスの利用ボリュームに関する分析を提供します。大きく、以下 2つの機能を有しています。

各商品／サービスの利用動向を定量指標で比較する
特定商品／サービスの利用顧客が、他に利用している商品／サービスを定量指標で比較する。
分析名称として関連性分析と称していますが、実質的に関連性を理解するのは後者の機能であり、前者は顧客を前提とした商品／サービスの利用度合い、支持度合いを見るための分析です。今回はまず、前者の機能を利用し、新規に獲得した顧客群の商品／サービス利用動向を見ていくことにします。


### 分析の前提
図29 に示すように、各商品／サービスを横並びで比較するのが関連性分析の機能です。分析の対象セグメントとして、2009年に新規に何らかのご契約をいただいた顧客で、なおかつ年齢が 50歳代の方を対象としています。縦に並べている商品群でお分かりのように、金融機関が扱う商品を、商品分類（複数の商品をグルーピングした上位階層）別で把握しています。ここから、自社と新規に関係を開始した顧客が、どのような商品をトリガーに獲得できたかを理解することが可能となります。

<img width="700" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2768546/f47b637f-6d66-734b-38f8-5f1f96df53aa.png">


利用している指標値としては、契約顧客数を利用しています。関連性分析では任意の定量指標を利用することが可能ですが、把握したい内容によっては利用する定量指標を注意深く選択する必要があります。商品やサービスはどんな企業も有しており、それを顧客に購入、もしくは利用いただく事によって商売は成り立っています。しかしながら商品やサービスの契約、加入、購入、利用といった消費の仕方は様々に異なります。例えば「ADSLサービス」であるならば、加入顧客数が対象となることもありますし、接続回数や時間、通信ボリュームを把握の対象としたい場合もあるかと思います。把握の対象に応じて適切な指標値を利用して比較に用います。



### 商品ごとの支持動向
図29 では、上位商品レベルでの新規契約顧客数がどの程度あったかを把握しています。このチャートを経時的に把握することによって、伸び悩む商品、勢いのある商品を把握することが可能となります。またここに表示しているデータの対象は新規顧客であるため、既存顧客、解約顧客とも比較することにより、全体の顧客基盤に対してどのような寄与をしているかを把握することが可能です。

そして、これを配下の商品別に分解したのが図30 です。より細かい商品ごとに把握していくことにより、上位商品レベル同様、伸び悩んでいる商品と、伸びの大きな商品を把握することが可能となります。

<img width="700" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2768546/7a84f291-aeed-456f-c060-ff4f4cd1bbc3.png">


### アプローチの方向性
言うまでもなく、伸び悩んでいる商品に関しては今後販売を強化する必要があります。但し、当然のことながら各商品の市場性は異なりますし、自社における各商品の位置づけも異なりますので、単純な商品の横並びだけで判断するべきでもありません。例えば、最初に総合口座を開いていただき、その後ニーズの変化に応じてローンや定期預金を追加でご契約いただくという戦略があるのであれば、総合口座の獲得数が今後のビジネスに大きな影響をあたえることになります。

また、急激に伸びた商品に関しては何がそうさせたのかを理解する必要があります。それを把握するためには、どのチャネルから流入した顧客が申し込みに至ったのか、どのような顧客属性を有しているのか等を把握することも一つの参考情報となります。ここでは 50歳代で区切っていますが、他の世代ではまた別の傾向が表れているかもしれません。従って、異なる顧客セグメントで比較することも必要です。

このような分析によって、今後力を入れるべき商品や、急激に需要が増加した商品を把握し、改善やビジネス機会への対応ポイントを明確にすることが可能となります。そしてこれによって、今後キャンペーンを実施していくポイントやその対象顧客、一方で商品やサービスの改善に努めなければならないポイントを特定します。



#### Teradata Vantageへのお問合せ
[Teradata Vantage へのお問合せ](https://www.teradata.jp/About-Us/Contact)
Django Reverse accessorエラーの解決方法

モデルの作成時に「Revers accessor」というエラーが出たので調べてみました。
エラーが起こる理由と解決方法、解決後の子モデルへの逆参照の方法を書いていきたいと思います。
最初にエラーが起こった状況のモデルを見ていきます。
# エラーが起こる状況
自分の場合「Users」モデルと「Notes」モデルを紐付けた時に起こりました。
~~~python:Usersモデル
class Users(AbstractBaseUser, PermissionsMixin):
    username = models.CharField(max_length=255)
    email = models.EmailField(max_length=255, unique=True)
    icon = models.FileField(null=True, upload_to='icon/')
    is_staff = models.BooleanField(default=False)
~~~
~~~python:Notesモデル
class Notes(models.Model):
    title = models.CharField(max_length=255)
    content = models.CharField(max_length=500)
    tags = models.ManyToManyField(Tag)
    favorites = models.ManyToManyField(Users, blank=True)
    user = models.ForeignKey('accounts.Users', on_delete=models.CASCADE)
~~~
「Users」モデルと「Notes」モデルは一対多の関係にあり、また「Notes」モデルの`favorites`フィールドはユーザーのお気に入り登録をするためのフィールドで「Users」モデルと多対多の関係を持っています。
この「Notes」モデルのように一つのモデルに「Users」モデルと一対多と多対多の関係にあることでエラーが発生します。
# なぜエラーが起こるのか？
エラーが起きてしまう原因は「Users」モデルから「Notes」モデルを逆参照する時に「Notes」モデルの`user`フィールドと`favorites`フィールドのどちらを参照すればいいのかわからなくなってしまうからです。
~~~python
# ユーザーの取得
user = Users.objects.get(pk=1)
# 取得したユーザーのノート取得
notes = user.notes_set.all()
# 取得したユーザーのお気に入りのノート
favorite_notes = user.notes_set.all()
~~~
このように「ノートの取得」と「お気に入りの取得」でどちらも`user.notes_set`になってしまいます。
# 解決方法
このような場合の解決方法は子モデルの方のフィールドに`related_name`をつける事で解決する事ができます。
今回は「Notes」モデルの`favorites`フィールドに`related_name`を付与します。(つけるフィールドは`user`と`favorites`のどちらでも良い)
~~~python:Notesモデル
class Notes(models.Model):
    title = models.CharField(max_length=255)
    content = models.CharField(max_length=500)
    tags = models.ManyToManyField(Tag)
    favorites = models.ManyToManyField(Users, blank=True, related_name='favorite_notes')
    user = models.ForeignKey('accounts.Users', on_delete=models.CASCADE)
~~~
「Notes」モデルの`favorites`フィールドに`related_name='favorite_notes'`をつけました。
このようにする事で「Users」モデルから「Notes」モデルの「favorites」を逆参照する場合は`related_name`で付けた名前で参照する事ができます。

# 逆参照の方法
~~~python
# ユーザーの取得
user = Users.objects.get(pk=1)
# 取得したユーザーのノート取得
notes = user.notes_set.all()
# 取得したユーザーのお気に入りのノート
favorite_notes = user.favorite_notes.all()
~~~
「ノートの取得」にはそのまま`notes_set`で参照し、「お気に入りの取得」は`favorite_notes`で行う事ができます。
Railsからdynamodb-localにレコードを作成したい

# はじめに
railsからdynamodb-localにレコードを作成しようとしたところ、以下のエラーが発生しました。

```
NameError (undefined local variable or method `options' for #<Class:0x000055c518ea1860>)
```

これはmodelでApplicationRecordを継承していたことが原因でした。

classに記載している「< ApplicationRecord」を削除して再度レコードを作成すると成功しました。
以下が正しいコードです。

```backend/app/models/hoge
class Hoge
  include Dynamoid::Document

  table name: :hoges, key: :id, capacity_mode: :on_demand
  field :title, :string
    
    略
end
```

```
> Hoge.create(id: '1', title: 'test')
```


# おわりに
rails g model Hogeでmodelを作成してしまっていたのが原因でした。
今回はdynamoidを使用するため、ActiveRecordは継承しないことに注意が必要でした。


# 参考

https://dev.classmethod.jp/articles/ror-to-dynamoid/
SDV(Software Defined Vehicle)のE/Eアーキテクチャーについて

クルマのE/E(Electrical/Electronic)アーキテクチャーについて概要をまとめたものです。

ECU(電子制御ユニット)は、個別の機能ごとに装備されていましたが、近年のAD(自動運転)/ADAS（先進運転支援システム）をはじめとしてクルマには新しい機能が追加され続け，その数は100を超えるといわれています。ECU数の増加とともに電源線や通信線といったワイヤーハーネスも増加し，重量や配索コストが課題となってきました。そのため，現在の車両アーキテクチャは，ある程度まとまった機能(ドメイン)ごとに集約・統合し，ECUやワイヤーハーネス数を削減する「ドメイン型アーキテクチャ」が主流となっています（図中真ん中のもの)。ボディー系、パワートレーン／シャシー系、IVI/HMI(Human Machine Interface)系、ADAS/AD系の各ドメイン毎にECUを統合したものです。

E/E Architectureの変遷
![スクリーンショット 2023-01-24 18.48.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132988/365f37c3-bf98-24e0-d27a-20c128dc1775.png)

次世代のE／Eアーキテクチャーでは，さらにドメイン間の統合を進めた「ゾーン型アーキテクチャ」が主流になると考えられています（図中右のもの）。TESLA Model3が発売された当時、これを解体したとき汎用ECU3個＋自動運転AD/ADAS用ECU1個の合計４個しかなく関係者を驚愕させたものです。ゾーンアーキテクチャは，ドメインをまたがる機能が統合実装されたCentral ECU(下図)と，車両の前後や左右といった場所ごとでドメインに依存しないで情報収集するZone ECU(下図)で構成されます。このようなECUの配置/配線を最適化することでハーネストも削減でき25-50%コストを低減できるといわれています。統合ECU では従来の単体ECUよりハイ・スペックなものが要求されHPC（High Performance Computing）等も利用されます。
Central ECUでは,SDVアーキテクチャー上ではShared Servicesに該当するもので5G/V2X通信機能、OTA更新などの機能が実装され、車載ネットワークのルーター機能をつかさどるとともに異なるドメイン間での情報集約・統合制御が可能となるため，個別ドメインのみでの制御では困難だった新しい車両運動制御や，複合情報を用いた車両診断を実現できます。


Zone Architectureについて
![スクリーンショット 2023-01-24 18.49.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132988/9d98812a-a444-0403-a688-470012c5e9bd.png)

参考情報
https://news.mynavi.jp/techplus/kikaku/20210806-1936988/

https://www.renesas.com/us/en/blogs/evolution-ee-architecture-and-software-platform-r-carrh850
paizaラーニング レベルアップ問題集 二分探索メニュー応用編 JavaScript 従業員

従業員 (paizaランク A 相当)

https://paiza.jp/works/mondai/binary_search_advanced/binary_search_advanced__workers

# 解答例
加える作業量で二分探索します。
範囲は0以上の整数、十分大きな10^14+1以下とします。
加える作業量をmid = Math.trunc((right + left) / 2)とします。
作業員一人の作業時間は、端数になった場合は、それぞれ 1 時間単位で切り上げなので、Math.ceil((B + mid)/A)で求まります。
全作業時間がK以下か調べ、探索を繰り返します。

```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [N, K] = lines[0].split(" ").map(Number);

//加える作業量で二分探索
let [left, right] = [0, 100000000000001];
while (right - left > 1) {
  const mid = Math.trunc((right + left) / 2);//仮の加える作業量
  
  let total = 0;//合計作業時間
  for (let i = 1; i <= N; i++) {
    const [A, B] = lines[i].split(" ").map(Number);
    //作業時間
    total += Math.ceil((B + mid) / A);//端数切り上げ
  }
  if (total <= K) {　//K時間以下なら、作業量は増やせる
    left = mid;
  } else { //K時間超えたら、作業時間は減らす
    right = mid;
  }
  
}
console.log(left);
```

# 解答例(pythonの場合参考)

探索を関数で定義して解きます。
x / y を切り上げた値を求める際には、(x + y - 1) / y を切り捨てた値を用いることができます。

```javascript
const fs = require("fs");
const input = fs.readFileSync("/dev/stdin", "utf-8").trim();
const lines = input.split("\n");

const [N, K] = lines[0].split(" ").map(Number);
const AB = lines.slice(1).map(line => line.split(" ").map(Number));

//加える作業量で二分探索
//従業員の作業時間の合計が k 以下なら true, そうでないなら false を返す
const check = x => {
  // time : 作業量 x の時にかかる作業時間
  let time = 0;
  for (let i = 0; i < N; i++) {
    const task = x + AB[i][1];
    time += Math.floor((task + AB[i][0] - 1) / AB[i][0]);//切り上げ
  }
  if (time <= K) {
    return true;
  } else {
    return false;
  }
};

//leftは常に条件を満たす，rightは常に条件を満たさない
let [left, right] = [0, 10000000000001];
while (right - left > 1) {
  const mid = Math.trunc((right + left) / 2);//仮の加える作業量
  
  if (check(mid)) {　//K時間以下なら、作業量は増やせる
    left = mid;
  } else { //K時間超えたら、作業時間は減らす
    right = mid;
  }
  
}
console.log(left);
```