OmniAICreator/Qiita-1.07M huggingface dataset:
AlmaLinuxでfirewalldの設定を行なってみた。

Linux初心者で基本的な勉強を始めていくにあたり、firewalldの設定を行ってみたので備忘録代わりに記載します。
本記事ではAlmaLinux8.8でfirewalldの設定を行う際の手順を紹介します。
firewalldの稼働方法からポートの解放の方法までの手順をまとめております。
# 検証環境
今回使用する環境は以下になります。
使用するサーバーの制限により使用できるOSがAlmaLinux8.8でしたのでこのバージョンでの記載になります。
最新のAlmaLinux９でfirewalldを使用する場合も同様のコマンド操作で設定可能という理解です。
```
# cat /etc/os-release
NAME="AlmaLinux"
VERSION="8.8 (Sapphire Caracal)"
ID="almalinux"
ID_LIKE="rhel centos fedora"
VERSION_ID="8.8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="AlmaLinux 8.8 (Sapphire Caracal)"
ANSI_COLOR="0;34"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:almalinux:almalinux:8::baseos"
HOME_URL="https://almalinux.org/"
DOCUMENTATION_URL="https://wiki.almalinux.org/"
BUG_REPORT_URL="https://bugs.almalinux.org/"

ALMALINUX_MANTISBT_PROJECT="AlmaLinux-8"
ALMALINUX_MANTISBT_PROJECT_VERSION="8.8"
REDHAT_SUPPORT_PRODUCT="AlmaLinux"
REDHAT_SUPPORT_PRODUCT_VERSION="8.8"
```

# firewalldの稼働確認、稼働方法
firewalldの稼働状態を確認します。
```
# firewall-cmd --state
not running
```
現在Firewalldが稼働していないことがわかります。
そこでコマンド操作によるFirewallの有効化・無効化の方法を確認していきます。
# firewalldのサービス起動について
firewalldのサービス起動のコマンドは大きく二種類存在します
### 1. 一時的にサービスを起動する方法
こちらの方法では有効化を行うことはできますが、OSの再起動をした場合設定の反映を行うことができません
```
#systemctl start firewalld
```
### 2.サービスの自動起動を有効にする方法
こちらの方法はOS起動時に自動起動の設定の変更を行うことで永続的にfirewalldのサービス起動を行う方法です。
OS起動時にサービスの自動起動設定を行うコマンドを以下のように入力します。
```
# systemctl enable firewalld
Created symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service → /usr/lib/systemd/system/firewalld.service.
Created symlink /etc/systemd/system/multi-user.target.wants/firewalld.service → /usr/lib/systemd/system/firewalld.service.
```

# firewalldのサービスの停止をする方法
firewalldのサービスを停止する方法は有効化の方法と同様に二種類の設定方法が存在します。
### 1. 一時的にサービスの停止を行う方法
こちらの方法では無効化を行うことはできますが、OSの再起動をした場合設定の反映を行うことができません
```
# systemctl stop firewalld
```
### 2.サービスの自動起動を無効にする方法
こちらの方法はOS起動時に自動起動の設定を行うことで永続的にfirewalldの無効化行う方法です。
OS起動時に自動起動の有効化の設定の変更を行うコマンドを以下のように入力します。
```
# systemctl disable firewalld
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
```

以上のコマンドでfirewalldの稼働・停止を行うことができます。
次に稼働したfirewalldのポート設定を確認していきます。
# firewalldで解放しているポートの確認方法
現在firewalldで解放しているポートの設定を確認するために以下のコマンドを実行します。
```
# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s1 enp0s7
  sources:
  services: cockpit dhcpv6-client ssh vnc-server
  ports: 514/udp 514/tcp 5001/tcp 5902/tcp 80/tcp 2049/tcp
  protocols:
  forward: no
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
```
今回は例としてポート番号110番のPOP3のポートを開放してみます。
tcp 110番のポートを開放するには以下のコマンドを実行します。
```
#  firewall-cmd --add-port 110/tcp --permanent
success
```
"--permanent"のコマンドオプションをつけることで永続的なポートの開放が可能です。
以上のコマンドではポート番号からポートを開放しましたが、サービスの名前からも開放可能です。
```
# firewall-cmd　--permanent --zone=public --add-service=pop3
success
```
最後にfirewlldの設定を変更を動的に適応するために以下のコマンドを実行します。
```
#  firewall-cmd --reload
success
```
以上でfirewalldの設定完了です。
【Pyhonでバイナリデータを扱う人必見】structライブラリの基本的な使い方

# はじめに
本記事ではPytohnでバイナリデータを扱う際に使えるstructライブラリの基本的な使い方を解説する。

このライブラリにはバイナリデータに変換、またはその逆の変換をする関数などが提供されている。

structライブラリはPythonの標準ライブラリなので、以下のように読み込めば使える。

```Python
from struct import *
```

# structライブラリの関数
## pack関数
任意のデータをバイト列オブジェクトにしたものを返す関数。
```Python
struct.pack(format, v1, v2, .....)
```
v1, v2にはバイト列オブジェクトに変換したいデータが、formatにはv1, v2のフォーマット文字がそれぞれ入る。

## unpack関数
バイナリデータを指定されたフォーマットに従って、元のデータに戻す関数。
```Python
struct.unpack(format, buffer)
```
bufferには変換したいバイト列オブジェクトが、formatにはbufferの元のデータのフォーマット文字がそれぞれ入る。


## フォーマット文字
pack, unpackのformatには、以下のフォーマット文字が入る。

|フォーマット文字 | Cの型|Pythonの型  |標準サイズ（byte） |
|---|---|---|---|
|"c"  |char | 長さ1のバイト列  |1  |
|"b"  |signed char（符号付き整数） | 整数  |1  |
|"B"   |unsigned char（符号なし整数）  |整数  |1  |
|"h"  |short（符号付き整数） | 整数  |2  |
|"H"   |unsigned short（符号なし整数）  |整数  |2  |
|"i"   |int（符号付き整数）  |整数  | 4 |
|"I"   |unsigned int（符号なし整数）  |整数  | 4 |
|"l"   |long（符号付き整数）  |整数  | 4 |
|"L"   |unsigned long（符号なし整数）  |整数  | 4 |
|"q"   |long long（符号付き整数）  |整数  | 8 |
|"Q"   |unsigned long long（符号なし整数）  |整数  | 8 |
|"f"   |float  |浮動小数点  | 4 |
|"d"   |double  |浮動小数点  | 8 |
|"?"  | _Bool |  bool型| 1 |
|"x"  |パディングバイト |   |  |
|"n"  |ssize_t |  整数 |  |
|"N"  |size_t |  整数 |  |
|"e"  | |  浮動小数点数| 2 |
|"s"  | char[]|  bytes|  |
|"p"  | char[]|  bytes|  |
|"p"  | void*|  整数|  |

### 使用例
```Python
>>> from struct import *
>>> pack("bB",-1,255)
b'\xff\xff'
>>> unpack("bB",b'\xff\xff')
(-1, 255)
```

またformatの先頭に以下のような文字を追加することで、バイトオーダやサイズ、アライメントなどを設定できる。

|文字 | バイトオーダ|サイズ  |アライメント |
|---|---|---|---|
|"@"  |native | native  |native  |
|"="  |native | standard  |none  |
|"<"   |リトルエンディアン|standard  |none  |
|">"   |ビッグエンディアン|standard  | none |
|"!"   |ネットワーク (= ビッグエンディアン)  |standard  | none |

#### バイトオーダにおける"native"
ホストマシンに依存したバイトオーダであることを意味する。
#### サイズおよびアライメントにおける"native"
Cコンパイラのsizeof式で決まることを意味する。

なおこのformatの先頭の文字がいずれかでない場合は、"@"が使われたとみなされる。

### 使用例
```Python
>>> from struct import *
>>> pack(">lll",1,2,3)
b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03'
>>> unpack(">lll",b'\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03')
(1, 2, 3)
>>> pack("<lll",1,2,3)
b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00'
>>> unpack("<lll",b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00')
(1, 2, 3)
>>> pack("lll",1,2,3)
b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00'
```

1回目のpackではビッグエンディアンを、2回目のpackではリトルエンディアンを使っている。実行結果から分かる通り、バイト単位で並び順が両者逆転していることがわかる。

3回目のpackでは先頭の文字を省略しているため、"@"が使われているとみなされ、筆者のホストマシンのアーキテクチャ（Intel x64）に合わせてリトルエンディアンが使われている。

# 終わりに
今回はPyhonでバイナリデータを扱う際に使えるstructライブラリの基本的な使い方を解説した。

structライブラリには今回紹介したpack, unpack以外の関数もいくつか用意されているので、興味がある方はぜひ公式ドキュメントや他の方の記事で各自調べてみてください。

# 参考文献
- Pythonソフトウェア財団. "struct --- バイト列をパックされたバイナリデータとして解釈する"．Python 3.12.1 ドキュメント. 2024-01-14. https://docs.python.org/ja/3/library/struct.html, （参照2024-1-15）
サーバに複数NICがある場合の注意

RSのIPアドレスを固定さえしていれば基本的にロボットの動作等に問題はないが
NICの優先度によっては、RSが実際に使用しているIPアドレスとログ上に記録されるRSのIPアドレスが異なる場合がある。
eurekaでグラフ表示する際にログからデータを取得する際RSのIPアドレスのログを拾おうとするためデータが取得できずグラフ表示ができない場合がある。
MC上に登録されるRSについて

MC>管理>Roboserverに表示されるRoboserverはオンライン状態では削除できない。
Roboserver設定で該当MCを向いていない場合も同様。
MCバージョンアップ時、旧環境でバックアップ、新環境でリストアしてしばらく平行稼働する場合
新環境MCに旧環境RSがオンラインで表示されて削除できない、削除する場合は旧環境のRSを停止してオフラインにする必要があるため注意。
Railsでlink_toのmethod: :deleteが使えない

# 環境
Ruby:3.2.1
Rails:7.0.0

# Rails5.1からlink_toのdeleteメソッドがGetメソッドになる

```
 <%= link_to 'ログアウト', 'パス', method: :delete %>
```
リンクを押すと以下のエラーが発生します。

![スクリーンショット 2024-01-15 16.30.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465903/061c87bd-4545-3863-36b5-96d99eae9a48.png)

methodをdeleteに指定したのに、Getメソッドで送られています。
開発者ツールでHTMLを確認してみたところ、deleteになっていることが確認できます。

```
<a rel="nofollow" data-method="delete" href="パス">ログアウト</a>
```

# 原因
link_toの場合、deleteメソッドはJavascriptでGetをDeleteに変換されるそうです。
そのため、今回はJavascriptが効いていなかったのでGetのままになっているのだと考えられます。

# 解決策
今回、自分が実施した対応は``link_to``を以下のように修正することです。
詳しい内容は参考資料をご覧ください
```
<%= link_to "ログアウト", "パス", data: {turbo_method: :delete} %>
```

# 参考資料
[Rails7でlink_toのmethod: :deleteが動作しない](https://katsushi-ougi.com/rails7_link_delete_method)
[rails7でlink_toのmethod: :deleteが動作しない場合の対処](https://www.airteams.net/media/articles/1830)
iOS in-app reviewのテストについて

## 起きたこと
- TestFlightでテストしようとしたが全然reviewダイアログ表示されません
- 審査後promotion codeを発行して公開前に機能テストをしようとしたがダイアログ表示されたものの実際投稿押すとエラーが起きる。

## 調査
[requestreviewの公式ドキュメント](https://developer.apple.com/documentation/storekit/skstorereviewcontroller/3566727-requestreview)
```
    When your app calls this method while it’s in development mode, StoreKit always
    displays the rating and review request view, so you can test the user interface
    and experience. However, this method has no effect in apps that you distribute
    for beta testing using TestFlight.
```
要するに、開発モードでは常にダイアログ表示しますがTestFlight経由で配ると常に表示されません。

では、promotionコードを発行してはいかがでしょうかというと

[promo codeについての紹介](https://developer.apple.com/help/app-store-connect/offer-promo-codes/request-and-manage-promo-codes/)
```
Promo codes for apps
When a customer downloads an app using a promo code, the app behaves just as it would
if it had been purchased. For example, the customer has the opportunity to update to
new versions of the app. However, customers can’t rate or review the app. Promo codes
can be used to redeem an unreleased app version, as long as the app is available on
the App Store. Promo codes for tvOS or multi-platform apps must be redeemed on an iOS
device. After the code is redeemed, the tvOS app appears in the customer’s purchase
history on the App Store for Apple TV. You can request up to 100 promo codes per
version of each platform your app supports.
```
reviewは書けないですと明記されていますね。

挙動としてはosバージョンに分かれています。
15.5では普通に投稿成功しましたがstoreに反映されません。
15.7ではレビュー画面のsubmitを押しても反応しません。
17.xでは「アイテム所持していません」とのエラーが表記されていました。
![1705305652529.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/511710/e1999dc5-f428-df1e-85ee-db0abbddcf1b.jpeg)

## おまけ
- storeレビューのユーザー制限
```
If the person hasn’t rated or reviewed your app on this device, StoreKit displays the 
ratings and review request a maximum of three times within a 365-day period.

If the person has rated or reviewed your app on this device, StoreKit displays the 
ratings and review request if the app version is new, and if more than 365 days have 
passed since the person’s previous review.
```
１ユーザーあたり評価はバージョンごとに年に一度投稿、未投稿の場合だと年に3回まで。
＊同一ユーザーと判断するのは同じアカウントor同じ端末。

呼び出してもダイアログでない場合がありますのでユーザーの操作によって呼び出す（ユーザーに表示することを期待させる)ことはよくない。

[設計参考リンク](https://developer.apple.com/design/human-interface-guidelines/ratings-and-reviews)
G検定受験感想振り返り

１勉強方法
期間は半年で程度少しずつ学習
・テキストを読む
　　深層学習教科書 ディープラーニング G検定(ジェネラリスト)公式テキスト
・模擬テスト
　　http://study-ai.com/generalist/
・不明点は適宜インターネットで調べる

２試験本番
・時間に対して問題数が多い。
・問題文、選択肢の分が長い。
　＞分からない問題は飛ばして後でと思っていたがそんな時間はなかった。
　＞一応何かしら選択はしていおいたので良かった。
・時事問題が難しかった。なんとなく知っているでは対処できないような問題だった気がする。
・最後の方の問題は時間が無くなって適当に埋めた

結果的には合格できた。
前半のテキストに書いているような手法等の問題は割とできていたので勉強の甲斐はあったかもしれない。
後半の時事問題的な部分は時間がなかった+勉強不足感はあったのでそれなりの点数だった。

まとめ
・公式テキストでは歴史に沿って説明されているが、手法ごとのつながり(何かをどう改良してどうなった等)も重要。
・同じものでも違った呼び方があったりするので注意
・時事問題はかなりしっかり知っていないと問題は解けなさそうだが、学習範囲が膨大な気がするのでどう対策したらいいのかわからない。
VirtualBox と Hyper-V

VirtualBoxを使ってGNS3 ネットワークシミュレータを利用していますが、Windows Hyper-V 設定によりGNS3 のQEMU でエラー「KVM acceleration cannot be used (/dev/kvm doesn't exist).」が出てOpenWRTやVyOSが起動できない場合の対処法をまとめました。 バージョンにより状況が変わる可能性が高いですが、Windows10 Pro 22H2 とVirtualBox 7.0.12 / 6.1.48 での対応方法を検証しました。

## GNS3については以下を参照
https://qiita.com/nsan/items/88b00c54f70bf90c63a4

要はVirtualBoxの設定 Nested VT-x/AMD-V が使えないのですが、設定画面上でグレーアウトになるなどは無く見た目では判断できません。 Windowsコマンドプロンプトでmsinfo32 を実行して、システムの要約の右側の項目一番下に「ハイパーバイザーが検出されました…」と出ているとHyper-V が起動してNested VT-x/AMD-V が使えない状態です。
![msinfo32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412785/025d222c-084a-f366-f652-da92a8cc804d.png)
Hyper-V が無効な場合は、「Hyper-V - VMモニターモード拡張機能」が表示されています。
![msinfo32-ok.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412785/9cb57d2f-1bb2-f25c-20f5-3b41266934e2.png)

## Hyper-Vを無効化するため Windows機能の無効化
コントロールパネルのプログラムに「Windows機能の有効化または無効化」で、Linux用WindowsサブシステムやWindowsサンドボックス などHyper-Vを利用するWindowsの機能を無効化するためにチェックを外す必要があります。
![Win機能22H2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412785/67656d74-49bf-b4a9-0d49-e762643cbfd1.gif)

## コア分離のメモリ整合性がオンならオフに設定
タスクバーの検索ボックスから「コア分離」を検索して、メモリ整合性がオフになっている事を確認する。
設定からは、更新とセキュリティ／Windowsセキュリティ／Windowsセキュリティを開く／デバイスセキュリティ／コア分離
![コア分離オフ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412785/48b85894-23d0-2b5a-225a-af9019f3ee72.gif)

上記の設定を行っても、vEthernet などの仮想スイッチ設定が残っていてHyper-V がオフにならない場合があります。
![hyper-v-network.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1412785/e6557304-4384-3afa-ba7f-feb8642d288e.jpeg)

管理者権限でコマンドプロンプトを開き、下記のコマンドを実行後に再起動します。
```
bcdedit /set hypervisorlaunchtype off
```
dependabot によるライブラリのアップデート手順書

## 個人用作業手順書
### 手順1_対象のGemを調査する(大事)
- RUNTIME依存とDEVELOPMENT依存性チェック(**Rubyの場合**)
    - [RubyGem](https://rubygems.org/)ドキュメントから対象Gemを検索する
    - 依存Gemのバージョンが足りないことをチェック、足りない場合アップデートできません
    - 例：↓
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658393/87e08951-6801-6275-2e41-9c483032500d.png)
    
- バージョン差分確認：
    - バージョン差が特に大きいの場合、確認作業は重くになるので、一つだけアップデートしても問題ないです
- 変更履歴チェック:
    - ChangeLogとCommitsをベースにチェック
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658393/b528ce12-fa45-aa85-005a-e86fecc71b3d.png)
        - バージョン差が多い場合、PRに全部表示されないので、下記みたいリンクをクリックして全ての内容を確認する
        ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658393/7bd7849f-1758-4998-c7e4-c6325fcb588a.png)
        - ないの場合,githubの**CHANGELOG.md**に見れます



    <aside>
    🔥 おすすめの見る方：
    
    - **Breaking changes: 破壊的変更: 確認必須**
    - **remove**:**機能削除**：**確認必須**
    - **deprecated**:**非推奨**:**確認必須**
    - features:機能追加:余裕があれば
    - Bugfixes:バグ修正:余裕があれば
    - Refactor:リファクタ:余裕があれば
    - Changes/fix:内容修正: 余裕があれば
    - chore: 内容機能追加:余裕があれば
    - docs:文言修正:確認不要
    </aside>
    

### 手順1プラスアルファ_gemの知見が溜まる

どのようなgemですか、どんなページに使ってますか、新規内容は何ですかなどを理解できれば最高

### 手順2_****実際にアップデートをする****
### 手順3_動作確認

- 基本ページ
 - 管理画面
- メール送信
- 申し込む
- Slack通知
- など、対象Gemに関係あるページor機能

### 手順4_Github アクションのステータスをチェック

テストが落ちている場合は該当箇所の修正が必要、対象gemのChangeLog、Commits、ドキュメントなどを確認し、どのように記述方法を変更すべきかを確認する

### 手順5_IT環境で検証

- IT環境にデプロイして動作チェック（不要の場合もあるので、自己判断）

### 手順6_リリース

- 確認事項をPRのコメントに記述: 下記のテンプレートを参考にしてください

```jsx
## issue
# 対象リスト
### チェックリスト
- [ ] 依存性チェック
- [ ] ChangeLog
- [ ] CommitLog
- [ ] bundle install || yarn install
- [ ] テストパス
- [ ] ローカル環境での動作確認
- [ ] IT環境での動作確認
### コメント& 知見共有

```

- マージ＆デプロイ
Bootstrap入門 for Flask

### 本記事の背景
Webページのフロント開発でBootstrapを使っている場合が多いので、本記事はFlaskベースでBootstrapを使用する場合についてまとめたい。

過去の記事を検索するといくつかありますが、Bootstrapは主役ではなく、あくまでも脇役として書かれていました。

https://qiita.com/satelightccb/items/211c71299f5422ad2c6b

https://qiita.com/ynakayama/items/2cc0b1d3cf1a2da612e4

### 本記事のゴール
本記事は、Flaskに特化したBootstrapの使い方までの道筋を紹介する。
Bootstrap本体については、公式ページご参照ください。

https://github.com/twbs/examples/tree/main/starter

### Bootstrapテーマ

Bootstrapはnode.jsを中心に開発が進められており、Flaskに特化しているライブラリではないため、FlaskでBootstrapを使うには、Flaskに特化して開発されているテーマを使用することをお勧めします。
以下はFlaskに対応したBootstrapのテーマがあります。（有料）

https://themes.getbootstrap.com/shop/?s=Flask

Freeのテーマについては、以下のサイトで検索するとたくさん出てきます。

https://themewagon.com/themes/modernize/

https://appseed.us/admin-dashboards/flask/

### ビルド手順

以下のBootstrapテーマを事例として、ビルドし、Webサイト立ち上げまでとする。

https://docs.appseed.us/products/flask-dashboards/argon-dashboard

Bootstrapテーマをビルドする場合、Dockerを使用する場合とマニュアルビルドの2通り存在するが、Dockerの場合は簡単に構築することが可能となります。

### Dockerを使ってビルドする場合
事前にDockerクライアントまたはDocker Desktopをインストールしておいてください。
Docker Desktopのインストール方法は、下記の記事が詳細にまとめているので、参照してください。
（※Windows11の方は、Windows10をWindows11へ読み替えてください）

https://qiita.com/TAKANEKOMACHI/items/f1aaa378d93b4ace9513

Dockerが初めての方は、以下の記事を参照

https://qiita.com/akeyi2018/items/38e520086666fb8d9001

```terminal
$ git clone https://github.com/app-generator/flask-argon-dashboard.git
$ cd flask-argon-dashboard
# Docker-composeコマンドを実行する
$ docker-compose up --build 
```
### Windows11マニュアルビルド手順(VSCODE/Gitbash使用）

```terminal
# ソースコードをダウンロード
$ git clone https://github.com/app-generator/flask-argon-dashboard.git
$ cd flask-argon-dashboard

# venvの設定（すでに設定済の場合は不要）
$ virtualenv env

# venvをアクティベートする
$ .\env\Scripts\activate

# モジュールのインストール
$ pip3 install -r requirements.txt

# Flaskの環境設定
$ # CMD 
$ set FLASK_APP=run.py
$ set FLASK_ENV=development
$
$ # Powershell
$ $env:FLASK_APP = ".\run.py"
$ $env:FLASK_ENV = "development"

# アプリ起動
$ flask run
```
ブラウザからWebサイトへアクセスする

http://127.0.0.1:5000/

動かした事例
```terminal
$ cd flask-atlantis-dark

$ flask run
 * Serving Flask app 'run.py' (lazy loading)
 * Environment: development
 * Debug mode: on
[2024-01-15 16:50:31,161] INFO in run: DEBUG            = True
[2024-01-15 16:50:31,162] INFO in run: Page Compression = FALSE
[2024-01-15 16:50:31,162] INFO in run: DBMS             = sqlite:///D:\python_pgm\flask-atlantis-dark\apps\db.sqlite3
[2024-01-15 16:50:31,162] INFO in run: ASSETS_ROOT      = /static/assets
 * Restarting with watchdog (windowsapi)
 * Debugger is active!
 * Debugger PIN: 117-875-007
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
[2024-01-15 16:50:32,271] INFO in run: DEBUG            = True
[2024-01-15 16:50:32,271] INFO in run: Page Compression = FALSE
[2024-01-15 16:50:32,271] INFO in run: DBMS             = sqlite:///D:\python_pgm\flask-atlantis-dark\apps\db.sqlite3
[2024-01-15 16:50:32,271] INFO in run: ASSETS_ROOT      = /static/assets
```
ブラウザでの表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576081/5aff183d-1c72-5a10-8965-701f4a281f65.png)
Laravel デプロイ関連

# 今回の記事はLaravelにおけるデプロイの仕方です。

以下の１〜３の手順でssh接続を行ってください

1\. sshディレクトリに移動
```
user@user_name ~ % cd .ssh
```

2\. 秘密鍵を登録する 　(秘密鍵名は自らが登録したもの)
```
user@user_name .ssh % ssh-add id_rsa_private
```

3\. ssh接続をする
```
user@user_name .ssh % ssh ユーザー名@接続先サーバーホスト名
```

１〜３の手順を踏むとsshの接続は完了しました。
* * * 

デプロイ関連のコード

* githubにpushした変更を取り込む
 git pull origin mainを打ち込むとgithubのユーザー名・プロジェクトのパスワードを打ち込む。

```
git pull origin main
```
* マイグレーションファイルの変更を取り込む
```
php artisan migrate
```

* テーブルを再作成してシーダーの変更を取り込む
```
php artisan migrate:refresh --seed
```


* jsやcssファイルをbuildフォルダに生成
```
npm run build
```

* .envファイルなどの環境変数を編集
viエディターで編集をし、:wqで保存する。

```
vi .env
```

* その後、キャッシュをクリアする
```
php artisan config:clear
```

* キャッシュを再作成
```
php artisan config:cache
```
【算術演算子？排他的論理和？】[^]←このマークに3分くらい悩んだためメモした～サーカムフレックス～

2024年15日目にしてQiita初投稿という怠惰なダメ人間です
～今年もお願いしま酢～
以下の経緯で読み方がわからず、ゆでパスタの吹きこぼれる鍋状態になったため覚書。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2867756/b12d1e59-84b2-51c5-b412-35f4acd24c3f.png)

> p●izaのpyth●nスキルチェック問題（Dラン）で、
体積計算として`hogeX^2 - hogeY^9` 的なものが渡される
↓
「入力値取得して」案件だったため取得
↓
せいっ！
`print(hogeX^2 - hogeY^9)`
↓
＞＞＞エラー＜＜＜＜
↓
この「^」なんなんだ「^」、、、！(ココで悩んだ)
～体積なのだから累乗的な何かだと認識すべきだった。。～
>
>_(※規約が厳しそうなため、hogeや数字は変えています)_


# 読み方
呼称の種類が猫の呼び名レベルだ。

「サーカムフレックス(circumflex)」
「キャレット(caret)」
「ハット記号（hat symbol）」
「アクサンシルコンフレックス」※この呼称については言語学等の文脈で用いられることが高い可能性がある

※また、「circumflex」に関しては医療系の用語（解剖学）では冠状動脈の回旋枝の意味を持ったりするそうなので、「キャレット」、「ハット記号」などが伝わりやすい気がしました。
参照：[DEFINITION OF CIRCUMFLEX
](https://www.rxlist.com/circumflex/definition.htm)


# 「^」の用途
- 【語学】アクセント記号の一種
　
- 【計算】冪乗の指数
- 【C#】ビット演算、排他的論理和の二項演算子。
- 【Pascal】ポインタを示す記号
- 【IT】キャレット記法　(ASCIIコードの制御文字)
- 【IT】クヌースの矢印記号　　ex)「A↑↑↑B」==「A^^^B」
- 【正規表現】「文字列のはじまり」を指すマーカー
　
- 【その他】顔文字（^_^:）


# 演算子としての使われ方
> BASIC系の言語がべき乗を表す演算子（x^2でx2を表す）として用いたり、C言語などがビット演算のXOR（排他的論理和）を表す演算子として用いる例がよく知られる。
ASCIIコードの制御文字を表す際に、0番のNUL文字を64番の「@」を用いて「^@」と記すなど、64を加算したコードに対応する文字に「^」を付けて表記する方式を「キャレット記法」（caret notation）という。
BY: [IT用語辞典「サーカムフレックス」](https://e-words.jp/w/%E3%82%B5%E3%83%BC%E3%82%AB%E3%83%A0%E3%83%95%E3%83%AC%E3%83%83%E3%82%AF%E3%82%B9.html)


# 今回は何だったのか
体積の問題というのもあり、累乗案件でした。

`print(hogeX　** 2 - hogeY ** 9)` に修正したところ、正解となりました。

「r^2」とか「r^3」などがあったら、「累乗案件」と認識しても大丈夫でしょう。



# 参考にした記事
■「 [算術演算子[^]の計算について[アクサンシルコンフレックス][サーカムフレックス]
](https://teratail.com/questions/69700)」、teratail、(2017.03.20)
> ▲　自分はこの方と全く同じことに悩んでいたようでした。
とくに回答の中の「排他的論理和」というキーワードからたどり着けました。感謝。


■中村 亮一「 [数学記号の由来について（5）－べき乗、平方根 等－
](https://www.nature.com/articles/s41593-023-01506-1)」、ニッセイ基礎研究所、(2020.07.07)

■「[サーカムフレックス 【＾】 circumflex / アクサンシルコンフレックス
](https://e-words.jp/w/%E3%82%B5%E3%83%BC%E3%82%AB%E3%83%A0%E3%83%95%E3%83%AC%E3%83%83%E3%82%AF%E3%82%B9.html)」、IT用語辞典、(2022.3.15)

■「[サーカムフレックス](https://wa3.i-3-i.info/word11666.html)」、「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典、(2021.12.17)


# DAME's NEW YEAR RESOLUTION ~絶対的破滅フラグ~

年末に「NANA’s Green tea」なるものを食べ、都市の洗練を感じた。
そしてそれっぽく新年の目標を立ててみた。

- str = "python"
  for i in range(1 ** 1000000):
  　　print(str)
- TOEIC敗北からの脱出
- 英検敗北からの脱出
- HSK
- 作曲
- 写真
- tiktok(今更館)

一番暗い夜明け前の手前で光が見えた途端死に戻りしてる(結局何もしてない)ダメ人間。
今年は死に戻りサイクルをぶん回していく所存です。
WindowsでLinuxベースの開発環境を作成しVS Codeから直接使用する

# 概要
* WindowsのLinux仮想環境であるWSL2をVS Codeから利用する。
    * 殆どの人は、開発プラットフォームとしてVS Codeを使っているためシームレスにLinux開発が可能
    * VS Code組み込みのターミナル、エディタ、拡張機能(Git, Intellisens, Lint等)を使用可能。
    * Intellisense コード補完、リンティング、デバッグ サポート、コード スニペット、ユニット テストなどの VS Code の機能を利用する
* 構成の概念図
![outline.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282300/478173ec-6358-1428-fec5-280f8c7ad7f2.png)


# VS Code環境の設定
1. 拡張機能：Remote Developmentをインストール
    * VS CodeのExtensionsからインストール
![remote_dev.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282300/175f79f4-5fdb-d4e1-cd5e-3bb7a6348cdd.png)
    * (補足) Remote Development同梱のWSL 拡張機能がインストールされているかを確認
        ```
        PS C:\Windows\system32> ls $HOME/.vscode/extensions/*wsl*

        Mode                 LastWriteTime         Length Name
        ----                 -------------         ------ ----
        d-----        2024/01/09     13:56                ms-vscode-remote.remote-wsl-0.81.8
        ```
    

# wsl/ubuntuインストール
1. Windowsの「スタートボタン」→「Windowsシステムツール」→「コントロールパネル」→「プログラム」→「Windowsの機能の有効化または無効化」
    1. 「Linux用Windowsサブシステム（WSL）」を有効に
    2. 「仮想マシン プラットフォーム」を有効に
2. wsl2バージョンを指定し、wslをupdate
    ```
    PS C:\Windows\system32> wsl --set-default-version 2
    WSL 2 との主な違いについては、https://aka.ms/wsl2 を参照してください
    この操作を正しく終了しました。
    ```
    ```
    PS C:\Windows\system32> wsl --update
    インストール中: Linux 用 Windows サブシステム
    Linux 用 Windows サブシステム  はインストールされました。
    ```
3. wsl2/ubuntuをインストール
    ```
    PS C:\work\git\wsl> wsl --install -d Ubuntu 
    ```
4. wsl2/ubuntuバージョンの確認
    ```
    PS C:\Windows\system32> wsl --list -v
    NAME            STATE           VERSION
    * Ubuntu-22.04    Running         2    
    ```
5. ubuntuのupdate
    * [ubuntu] ~$ sudo apt-get update
6. wget, ca-certificatesの追加
    * [ubuntu] ~$ sudo apt-get install wget ca-certificates

# VS CodeからWSL2に接続
1. コマンドパレット(Ctrl ＋Shift ＋ P)より、WSL: Connect To WSLを実行
![connect_wsl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282300/d8810e86-4bc4-b1f0-3cd1-38539a11316d.png)

    
2. Ubuntu上にcodeサーバがインストールされ、VS CodeからSSH接続される。
3. VS CodeでTerminalを開くと、Ubuntu端末を開くことができる。
![open_terminal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282300/498191ff-911d-1452-43ac-7197654bbd27.png)

# git連携
* VS Codeのgit連携機能は既定状態で使えるようです。
![git.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282300/50d2c3f3-bc06-1465-4c1d-f791ba0a6a32.png)


# 所感
* VS Codeの素晴らしさよ！！
* vmware, virtualboxはもう不要？


# 参考
* https://learn.microsoft.com/ja-jp/windows/wsl/tutorials/wsl-vscode
LED Sign Board Abu Dhabi, Dubai

In the UAE, LED sign boards are widely used for indoor and outdoor advertising, branding, and communication. Blue Rhine Industries can be customized to suit the branding and design preferences of businesses. They integrate with smart technologies, allowing for features such as real-time updates, interactive displays, and integration with data feeds. They offer remote content management capabilities. Businesses can update content, change messages, and schedule displays without the need for onsite intervention.

Visit:- https://brisigns.com/led-display-screen-manufacturers/
![signage company.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3563029/d4b9c4a2-a6a7-c6ca-89b7-60c0405715da.jpeg)
【初心者】React で新規ページの作成（TypeScript）

新規ページの追加方法について勉強したので、備忘録として記載しておきます。

以下が、勉強として作成したページなので、興味あれば閲覧ください！

https://nagajun1.github.io/sample_react_ts/

## react-router-dom をインストール
`React`は`Single Page Application`を基本とするフレームワークですが、`react-router-dom`をインストールすることで、簡単に新規ページを作成することができます。
インストールは、以下コマンドです。

```
npm install react-router-dom
```

## コード
プロジェクトを作成した際、元々の`App.tsx`だと、初期ページの`DOM`を戻り値とする様な`App`関数が生成されるかと思いますが、`react-router-dom`を使用する場合は、`BrowserRouter`を使用した、パス制御を戻り値とします。

```App.tsx
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Element1 from '..';
import Element2 from '..';

const App = () => {
  // 各ページのパス設定
  return <BrowserRouter>
    <Routes>
      <Route path={'/'} element={<Element1 />} />
      <Route path={'/sub'} element={<Element2 />} />
    </Routes>
  </BrowserRouter>;
};

export default App;
```

上記の実装の様にすれば、`http://localhost:3000/`で`<Elements1 />`ページを表示し、`http://localhost:3000/sub`で、`<Elements2 />` ページが表示される様になります。
Composable Storefront で Stripe を利用して簡易な決済を実装してみる - 内容編

※ これから記載する事項は、私が所属する会社とは一切関係のない事柄です。

今回は内容編・実装編に分けて [Composable Storefront](https://developer.salesforce.com/docs/commerce/pwa-kit-managed-runtime/overview) に簡易な決済を Stripe で実装してみたいと思います。実装編は[こちら](https://qiita.com/syunyama/items/89c4fbbedc742552453e)。


## 今回実装した内容

チェックアウト画面でフォームに入力したカード情報で購入を行います。

:::note warn
[Stripe のテストカード](https://stripe.com/docs/testing?locale=ja-JP#regulatory-cards)を利用しています。
:::

![スクリーンショット 2024-01-12 14.40.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/86a0f638-eb68-186a-d683-7e7573d239cc.png)
![スクリーンショット 2024-01-12 14.41.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/f394feca-1819-f8fd-929b-140bd372907b.png)



Stripe の顧客情報に B2C Commerce の顧客番号が保存され、またその際利用したカード情報は任意で Stripe に保存されます。
![スクリーンショット 2024-01-12 15.57.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/d8cba27d-6a5a-6d4e-be9e-578c353dada1.png)



Stripe の Payment Intent のアクセス情報と Payment Method ID は B2C Commerce の OrderPaymentInstrument オブジェクトに保存されます。

![スクリーンショット 2024-01-12 15.54.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/014c715f-4003-22e4-cac3-7789b5f76e03.png)




## 実装してない内容

* チェックアウトで保存されたカード情報を利用した決済
* 決済のキャプチャ
* キャンセル・返品
* アカウントページでのカード情報の追加・編集・削除
* クレジットカード以外の支払い方法
* 請求先やEメールなどの追加情報の Stripe への登録
* 買い物かご削除・更新時の Stripe Payment Intent の削除・更新
新卒2年目でデータベーススペシャリストに合格したお話

# 合格までの流れ
- 令和4年度（1年目）：午後Ⅰまで合格
- 令和5年度（2年目）：無事に午後Ⅱまで合格

# 学習方法
## 前提
- 1年目の学習前のスキルセットは、研修でETL, DWH, BIについての概要を学んだ程度でした。あとは基本情報技術者試験と Oracle Master Bronze SQL には合格していました。

## 使用教材
- TACの[動画講座](https://www.tac-school.co.jp/kouza_joho/joho_crs_db_hon.html)とテキスト（[ALL IN ONE パーフェクトマスター データベーススペシャリスト](https://bookstore.tac-school.co.jp/book/detail/110549/?utm_source=yahoo&utm_medium=cpc&utm_campaign=YSS&yclid=YSS.1000029253.EAIaIQobChMIiPKpza7GgwMVHOgWBR3NlgUcEAAYASAAEgK7SvD_BwE)）
- 過去問道場（[応用情報](https://www.ap-siken.com/apkakomon.php)と[データベーススペシャリスト](https://www.db-siken.com/dbkakomon.php)）
- 翔泳社の[テキスト](https://www.shoeisha.co.jp/book/detail/9784798179919)

## 学習時間
- 1年目は8月上旬～10月上旬までの約2か月間、幸いなことに業務時間を学習に充てることができたので、1日平均5時間ぐらいは学習していたと思います。なので、1ヶ月あたり22日とすると、総学習時間は22日×2ヶ月×5時間＝220時間といったところだと思います。
- 2年目は1ヶ月前ぐらいから始めて、30時間ぐらいかなと思います。

## 進め方
### 午前問題
- TACの動画を早送り視聴して全体像を掴んだら、あとはひたすら過去問道場を解いていました。
- 午前Ⅰ（応用情報の過去問道場）
    - 過去10年分をランダムに30問ずつ解いてました。
    - チェックボックス（下図）を利用して「A.間違いの選択肢も含めてわかった問題」「B.正解は分かった問題」「C.完全にわからない問題」で分類して、2週目はBとCを解くようにしていました。（この方法は翔泳社のテキストに書いてありました。）
    - 苦手な分野はTACの動画やテキストで補うのも良いと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3478068/2c119353-59f5-8aa8-4c38-255dd5ba601f.png)

- 午前Ⅱ（データベーススペシャリストの過去問道場）は、1年目に全問、2年目でも全問解きました。

### 午後問題
- まずはTACの動画で代表的な問題の解き方を学びました。そのあとに過去問を時間を測らずに解いて、問題の長さに慣れる練習をしていました。
- 1年目は、午後Ⅰ・午後Ⅱともに過去問3年分の概念設計（概念データモデルと関係スキーマ）の問題にフォーカスして解くようにしていました。（一応、そのほかの問題も少し解いたり、解答だけを読んだりしていました。）
- 2年目は、物理設計の問題を中心に過去問を解いていました。また、午後Ⅱに絞って解いていました。
- 翔泳社のテキストの解説がわかりやすかったので、よく読むようにしていました。
- 時間がなかったので実践できなかったのですが、翔泳社のテキストに様々なビジネスモデルについての紹介があったので、読んでおくと良いかもと思いました。

# 資格勉強を経て思ったこと
- 圧倒的に経験が足りない人が合格を目指すには、解き方のコツを覚えて過去問で問題に慣れるのが重要だと思います。
- とりあえず合格できれば、それだけの知識が一回は身についたことになると思うので、その後の業務のなかで「そういえばそんなこと勉強したなー」で思い出せるきっかけになるのかなと感じました。必要になれば、その思い出をもとにググればよいと思います。（業務ではカンニングし放題）
- 経験が足りないときにこそ、資格勉強で知識を身に付けるのが良いのかなと思いました。（自分のアピールポイントになる。）


受験予定の方々への参考になれば幸いです。
家庭用防犯カメラを作る（2. 動体検知編）

# 前回のおさらい

https://qiita.com/Manyan3/items/9b2752f246f48246bc36

登録した人やペット以外を撮影する

:::note info
インフォメーション
数秒ごとに撮影するものの動画とってみたい気も・・・
:::

# 動体検知してみる
## 手軽に既存のモデルから拝借してみる
- Resnet50 から流用して、特に人とかラベルはつかわない
- 動いているものを捕捉

# 拾えるかな？
- 紙飛行機を飛ばしてみた

![plane.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2155177/38afc8ff-59c7-ef78-b99e-7ceee27a3e6f.png)

:::note info
インフォメーション
撮影の都合上手で押さえて撮影。飛ばしてもちゃんと拾ってくれました！
:::

### こんなものまで・・・
![Screenshot from 2024-01-15 15-36-44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2155177/f788fcaa-16be-e19a-8ad9-368d86eadcdb.png)

- PCのピカピカクーラーの側面の変化を動体と見ている模様。

# 次回の課題
- 何でも拾ってしまうので、もう少し感度を調整してみる？
- もしくはそのまま？

## Sample code (moving object detection unspecified)

https://github.com/mi-kaneyon/man-yard/tree/main/movingdetector
async/awaitブロックの使い方

JavaScriptの非同期コードを扱うための`async/await`構文は非常に有用ですが、それを適用すべき場所とそうでない場所について明確な理解が必要です。

## ある処理を待つ必要がある場合のみ`async/await`を使用する
ある操作が完了するのを待つため、つまり非同期の操作結果を利用した何かをするためには`await`を使用します。

しかし、適用する場所が適切でないと、無駄なパフォーマンスの損失を招いてしまうことがあります。

不適切な使い方の一例として、多く見られるのが`return await`というパターンです。

```typescript
const fetchUserPosts = async (
  userId: bigint,
): Promise<UserPost[] | undefined> => {
  return await database.posts.findMany({
    select: { content: true },
    where: {
      userId,
    },
  });
};
```
このコードは動作しますが、`async`関数から直接`Promise`を返す際には`await`は不要です。

そのため、次のように改善できます。

```typescript
const fetchUserPosts = (
  userId: bigint,
): Promise<UserPost[] | undefined> => {
  return database.posts.findMany({
    select: { content: true },
    where: {
      userId,
    },
  });
};
```

## 非同期の操作結果を使用しない場合はasync/awaitを使用しない
特にサーバーアクションやイベントリスナーのようなユースケースでは、非同期処理の結果を直接使用せず、次のアクションに進むことが一般的です。

これらの場合、`await`を利用して処理をブロックする必要はありません。

これは、パフォーマンスを向上するだけでなく、コードの可読性も高めます。
bcryptを使ってpasswordをハッシュ化させる際に起きた、Cannot read properties of undefined (reading 'hashSync') を解決

# はじめに

NestJSを使用したバックエンドの中で、bcryptを使ってパスワードをハッシュ化するために

```javascript
const hashedPassword = bcrypt.hashSync(user.password, saltRounds);
```
とコードを書くと、ユーザー登録時に

```bash
 Cannot read properties of undefined (reading 'hashSync')
```

というエラーが発生しました。

# 解決方法

基本的にbcryptの使い方は [こちら](https://www.npmjs.com/package/bcrypt) を参考に確認しており、bcryptのインポート方法も

```javascript
import bcrypt from "bcrypt";
```
と記述していましたが、これを

```javascript
import * as bcrypt from 'bcrypt';
```
と書き換えることでエラーは解決されました。

詳しくはこちらの[Stackoverflowでの回答](https://stackoverflow.com/questions/58055145/how-to-fix-typeerror-cannot-read-property-hash-of-undefined-during-hashing-pa)が参考になると思います。

# おわりに

同じエラーに遭われた方のお役に立てられれば光栄です。
Azure Static Web App に Next.js ver.14 の カスタムエラーページを Deploy する

## はじめに

`Next.js ver.14` に限った話しではないが、`Next.js ver.14` の Static Build を `Azure Static Web App` に Deploy すると、せっかく作ったカスタムエラーページが書き換えられてしまう。

![Screenshot 2024-01-15 at 11.27.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245908/49306467-7147-0992-e1eb-f7acde7cf7ac.png)

違う！そうじゃない！！

これを意図したカスタムエラーページにしたい。

## 結論

```
└── public
    └── staticwebapp.config.json
```
```json:public/staticwebapp.config.json
{
  "responseOverrides": {
    "404": {
      "rewrite": "/404.html"
    }
  }
}
```

## 解決策

`Next.js` で `Azure Static Web App` のエラーページをカスタマイズするには、`staticwebapp.config.json` を設定する必要がある。

https://learn.microsoft.com/en-us/azure/static-web-apps/configuration#response-overrides

`Next.js ver.14` の場合、`src/app/not-found.tsx` で作成したカスタムエラーページ（404）は、`output: export` とした場合、`out/404.html` として build されるので、`staticwebapp.config.json` は、

```json:staticwebapp.config.json
{
  "responseOverrides": {
    "404": {
      "rewrite": "/404.html"
    }
  }
}
```
とすれば良い。では、このファイルをどこに置くのか？上記ドキュメントには、

> The recommended location for the staticwebapp.config.json is in the folder set as the app_location in the workflow file. However, the file may be placed in any subfolder within the folder set as the app_location. Additionally, if there is a build step, you must ensure that the build step outputs the file to the root of the output_location.

とあり、とりあえず、`app_location` に置けば良さそう。というわけで、workflow ファイルを確認する。私の場合は、github actions の workflow ファイル。

```yaml:.github/workflows/azure-sttic-web-apps-....yml
...
jobs:
  ...
  steps:
    ...
    - name: Build And Deploy
      ...
      with:
        ...
        ###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
        # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
        app_location: '/' # App source code path
        api_location: '' # Api source code path - optional
        output_location: 'out' # Built app content directory - optional
        ###### End of Repository/Build Configurations ######
...
```

`/` に置けば良い、すなわち、build したら、`out/` に吐き出されていればよい。How?!

https://stackoverflow.com/questions/73913104/azure-static-web-app-copying-staticwebapp-config-json-to-output-directory

`public` に置けば良い。

![Screenshot 2024-01-15 at 11.31.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245908/de45b7f4-37a4-8a34-6d27-84e527317449.png)

できた。

なお、開発中 `yarn dev` などで動かしていて、`slug` パラメータを伴うページで 404 を発生させようとすると、そんな値は、generateStaticParams() にない！と 500 エラーになってしまうが、export してしまえば関係ないので、1つだけ作れば良い。


（おしまい）
AstroにおいてのSSR

# AstroにおいてのSSR

### SSGをメインとする場合

Astroは前提としてNext.jsでのSSGモードをメインとして採用しているフルスタックのフレームワークです。しかしながら部分的にSSRを実装することもできます。

```javascript:astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  output: 'hybrid',
});
```
outputを設定することでSSGとSSRを混ぜたサイトを構築することができます。
今回の場合であればoutputをhybridに設定することでサイト全体をSSGがメインとすることができます。

```javascript:src/pages/randomnumber.astro
---
export const prerender = false;
---
```
この場合は追加でこのように設定することでこの部分だけSSRモードにすることができます。

### SSRをメインとする場合
```javascript:astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  output: 'server',
});
```
SSRをメインでサイトを構築する場合はoutputをserverに設定します。
(Astroをnetlifyでデプロイする、動的にAPIを呼びだしてレンダリングなど)
```javascript:src/pages/mypage.astro
---
export const prerender = true;
---
```
このように設定することでこの部分だけSSGモードにすることができます。

例えば事前に返す内容が決まっているブログやCMSなどを作成したい場合はその部分にこのコードを加えてあげましょう。

設定しないと下のような警告が出るのでそれに従えば大丈夫です。
事前に返す内容が決まっているブログやCMSなどにはこれを使います。
```
Add `export const prerender = true;` to prerender the page as static HTML during the build process.
```

### 参考記事
https://zenn.dev/rinda_1994/articles/e6d8e3150b312d

https://docs.astro.build/ja/guides/server-side-rendering/
DOMってなに？

# DOMとは
DOMは、 Webページや文書の構造をプログラムで操作するためのインターフェースや方法を提供するものです。具体的には、HTMLやXMLで書かれた文書の要素や属性をプログラム上で取得・変更・操作するための仕組みです。DOMは、文書をツリー構造として表現し、各要素やノードにアクセスできるようにします。

DOMは、Webページ上の要素やコンテンツにアクセスするための手段として非常に重要です。これにより、JavaScriptなどのプログラミング言語を使用して、動的なコンテンツの変更やユーザーとのインタラクションを実現することができます。例えば、ボタンがクリックされた時に要素を非表示にする、フォームの入力内容を取得するなど、さまざまな操作が可能です。

例えば、DOMを使用することで以下のようなことができます。

#### 1.要素の取得と変更
* 特定のHTML要素をプログラムで取得し、その内容や属性を変更できます。
#### 2. イベント処理
* ユーザーがボタンをクリックしたときなどのイベントを察知し、それに対する処理を実行できます。
#### 3. 動的なコンテンツの生成
* JavaScriptを使用して新しい要素やコンテンツを生成し、ページに動的に追加することができます。
Java勉強メモ３_データ型と変数

# データ型と変数

### プリミティブ型 (Primitive Types)
プリミティブ型はJavaにおける最も基本的なデータ型で、シンプルな値を持ちます。

#### 整数型:
**byte:** 8ビットで、-128から127までの値。
**short:** 16ビットで、-32,768から32,767までの値。
**int:** 32ビットで、標準的な整数値。-2^31から2^31-1までの値。
**long:** 64ビットで、大きな整数値。-2^63から2^63-1までの値。

#### 浮動小数点型:
**float:** 32ビットで、単精度の小数点数。
**double:** 64ビットで、倍精度の小数点数。

#### 文字型:
**char:** 16ビットで、単一のUnicode文字を表す。

#### 論理型:
**boolean:** trueかfalseのみを取ることができる。

### 参照型 (Reference Types)
参照型はオブジェクトや配列への参照を保持します。

**クラス型:** クラスのインスタンスへの参照。例えばString, Integerなど。
**インターフェース型:** インターフェースを実装するクラスのオブジェクトへの参照。
**配列型:** 同じ型の複数の値を格納するためのコンテナ。

### 変数の宣言と初期化
変数を宣言する際には、型を指定し、任意で値を初期化できます。
``` java
int number; // 宣言
number = 10; // 初期化
```
一行で宣言と初期化を同時に行うこともできます。
``` java
int anotherNumber = 20;
```

以下のサンプルコードは、様々な型の変数を宣言し、それらを初期化し、出力する方法を示しています。
``` DataTypes.java
public class DataTypes {
    public static void main(String[] args) {
        // 整数型
        int myInt = 1000;
        long myLong = 100000L;
        
        // 浮動小数点型
        float myFloat = 12.34f;
        double myDouble = 123.456;
        
        // 文字型
        char myChar = 'A';

         // 論理型
        boolean myBoolean = true; // true または false の値

        // 参照型
        String myString = "Hello, Java!"; // 文字列
        int[] myIntArray = {1, 2, 3, 4, 5}; // 整数の配列
        Integer myIntegerObject = new Integer(10); // インテジャークラスのインスタンス
    
        // 値の出力
        System.out.println("整数型(int): " + myInt);
        System.out.println("長整数型(long): " + myLong);
        System.out.println("浮動小数点型(float): " + myFloat);
        System.out.println("倍精度浮動小数点型(double): " + myDouble);
        System.out.println("文字型(char): " + myChar);
        System.out.println("論理型(boolean): " + myBoolean);
        System.out.println("文字列(String): " + myString);
        System.out.println("整数配列(int[]): " + java.util.Arrays.toString(myIntArray));
        System.out.println("インテジャーオブジェクト(Integer): " + myIntegerObject);
    }
}
```
Java勉強メモ２_基本概念

# 基本概念

### オブジェクト指向プログラミング
オブジェクト指向プログラミング（OOP）は、プログラムをオブジェクトの集合としてモデル化するアプローチです。オブジェクトはデータ（属性やフィールド）と、データを操作するための手続き（メソッドや関数）をカプセル化します。OOPの主要な概念には以下のものがあります：

**カプセル化:** データ（プロパティ）とメソッド（機能）を一つのユニットにまとめること。
**継承:** 一つのクラスが別のクラスの特性を引き継ぐこと。
**ポリモーフィズム:** 同じインターフェースを共有するが、異なる行動を取るオブジェクトを作成する能力。
**抽象化:** 複雑な現実世界を単純なモデルにするプロセス。

### Javaプログラムの構造
Javaプログラムはクラスとオブジェクトに基づいて構築されます。プログラム実行のエントリーポイントは**main**メソッドです。以下はその基本的な構造です：

```MainClass.java
public class MainClass {
    // メインメソッド - プログラムの起点
    public static void main(String[] args) {
        // 実行されるコード
    }
}
```

### コメントの使い方
コメントはソースコードの読みやすさを向上させるために使われます。Javaでは以下の2種類のコメントがあります：

**単一行コメント:** // に続くテキストはコメントとして扱われます。
**複数行コメント:** /* で始まり */ で終わるテキストはコメントとして扱われます。

### 識別子とキーワード
**識別子:** Javaでクラス、変数、メソッドなどを識別するための名前です。識別子は文字、アンダースコア、またはドル記号で始まる必要があり、その後に文字、数字、アンダースコア、ドル記号が続くことができます。
**キーワード:** Javaの言語に予約されている単語で、特定の機能や命令を表します。例えば、class、public、static、if、elseなどがキーワードです。

``` keyword.java
abstract    assert        boolean     break        byte
case        catch         char        class        const*
continue    default       do          double       else
enum        extends       final       finally      float
for         goto*         if          implements   import
instanceof  int           interface   long         native
new         package       private     protected    public
return      short         static      strictfp     super
switch      synchronized  this        throw        throws
transient   try           void        volatile     while

// Java 9以降で追加されたキーワード
module      requires      exports     opens        to
uses        provides      with        transient    var

// Java 10以降で追加されたキーワード
var
```
※ const と goto は予約されていますが、Javaでは使用されていません。
掲示板のお気に入り機能の多対多アソシエーションイメージ

掲示板のブックマーク機能を作成していて、ググっていくうちに混乱して多対多のアソシエーションのイメージが訳わからなくなったのでメモです。
実務未経験エンジニアなので間違ってたらご指摘お願いします。

前提として、User、Board、Bookmarkというモデルがあります。
Userから見てBoardは一体多の関係にあります（これは簡単）。
逆に言えばBoardから見てUserは多対一です（これもまぁそうだよねという感じ）。
では、Bookmarkを追加するにあたって、UserとBoardに多対多の関係を持たせてください←？

UserとBoardの間にはすでにアソシエーションがあるのにいかに？
Bookmarkはどこいったんだ？

絵として描き描きしていて気づいたのですが、Bookmarkを中間テーブルにすることで多対多のアソシエーションが成り立つのですね。
もっと具体的にいうと、UserはBookmarkを通してBoardと多対多（その逆も然り）のアソシエーションになる、ということです。

絵にするとこんな感じ
![Untitled Notebook-4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473221/7a2fa7de-9ff3-ee26-20ef-bd2021ae6438.jpeg)

(本来はモデルの中身も書くべきでしょうが、今回はモデルのアソシエーションのみに着目したかったので省略しました)

あと私が自ら描き描きしなくても先人が詳細な説明をされていました。
https://qiita.com/ramuneru/items/db43589551dd0c00fef9
Raspberry Pi 4 Model BのSSH設定

## Raspberyy Pi 4 Model B SSH 鍵認証 メモ

用意したもの
・Windows PC
・Raspberry Pi 4 Model B
・Tera Term

### クライアント側の操作

``` 
# 秘密鍵 公開鍵の作成
$> ssh-keygen -t rsa

# その後入力を促す文字が表示されるが入力せずにEnter
```

### 鍵が生成されたか確認

```
$> ls ~/.ssh/

    # id_rsa.pubが公開鍵
    ディレクトリ: C:\Users\users\.ssh


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2024/01/01     00:00           xxxx id_rsa
-a----        2024/01/01     00:00           xxxx id_rsa.pub
```

### 生成した公開鍵をラズパイにSCPで送信

```
$> scp ~/.ssh/id_rsa.pub [user]@192.168.x.x:~
```

### Raspberry Pi側の操作

```
# .sshフォルダが存在するか確認
$> cd ~
$> ls -a

# 存在しない場合は作成
$> mkdir .ssh
```

### 鍵を.ssh配下に追加

```
$> cat id_rsa.pub >> .ssh/authorized_keys

# 権限の変更
$> chmod 600 .ssh/authorized_keys

# 元のファイルを削除
$> rm id_rsa.pub
```

### /etc/ssh/sshd_config の編集

```
$> sudo vi /etc/ssh/sshd_config
~~~ ファイルの末尾に追加 ~~~
# ポートの設定
Port 22 

# rootログインの禁止
PermitRootLogin no

# 鍵認証を有効化
PubkeyAuthentication yes

# パスワード認証を無効化
PasswordAuthentication no
```
### sshサーバーの再起動

```
$ sudo /etc/init.d/ssh restart
```

上記対応で公開鍵を用いたSSH接続が可能
Java勉強メモ１_Javaとは

# Javaとは

### Javaの歴史

・開発の始まり: Javaは1991年にサン・マイクロシステムズ（現在はオラクル社によって買収）で開発されました。当初は家電製品向けの言語として「Oak」という名前で始まりました。

・公式リリース: 1995年に「Java」として公式にリリースされました。この時から、インターネット上でのアプリケーション開発に強みを持つ言語として注目されました。

・バージョンの進化: Java 1.0から始まり、Java 2（1998年）、Java SE 5（2004年）、Java SE 8（2014年）など、多くの重要なアップデートが行われてきました。各バージョンは新機能の追加や性能の改善が行われています。

### Javaの特徴

・オブジェクト指向: Javaはオブジェクト指向プログラミング言語で、カプセル化、継承、ポリモーフィズムなどのオブジェクト指向の原則に基づいています。

・プラットフォーム独立性: 「Write Once, Run Anywhere（WORA）」のスローガンの通り、Javaは異なるプラットフォーム間での互換性が高いです。JavaプログラムはJVM（Java Virtual Machine）上で実行され、これにより異なるOSでも同じJavaアプリケーションが動作します。

・メモリ管理: ガーベージコレクションにより、メモリ管理を自動化しています。これにより開発者はメモリリークを気にすることなくプログラムを書くことができます。

・セキュリティ: サンドボックスモデルを採用し、セキュリティを強化しています。これにより、不正なアクセスから保護された実行環境を提供します。

### Javaの用途

・ウェブアプリケーション: Javaはサーバーサイドのウェ
ブアプリケーション開発に広く使用されています。Java EE（現在はJakarta EE）は、企業向けアプリケーション開発の標準的なプラットフォームです。

・モバイルアプリケーション: Androidアプリケーションの開発にJavaが広く使われています。Android SDKはJavaを基にしたAPIを提供し、多くのモバイルアプリケーションがJavaで開発されています。

・デスクトップアプリケーション: スイング（Swing）やJavaFXなどのGUIフレームワークを用いて、クロスプラットフォームのデスクトップアプリケーションを開発することも可能です。

・組み込みシステム: Javaは小型デバイスや組み込みシステム向けにも使用されており、組み込みJavaはデバイス制御や小型アプリケーションの開発に利用されています。

・エンタープライズアプリケーション: 大規模な業務システムやバックエンドシステムの開発にもJavaは広く採用されています。高い信頼性、スケーラビリティ、保守性が求められる場面での選択肢として人気です。

・クラウドアプリケーション: Javaはクラウドベースのアプリケーション開発にも適しており、AWSやAzureなどの主要なクラウドプラットフォームでサポートされています。

以上のように、Javaはその汎用性、オブジェクト指向の特徴、プラットフォーム独立性などにより、多岐にわたる分野で利用されています。企業向けの大規模システムからモバイルアプリ、クラウドサービスまで、幅広いアプリケーションの開発に適しているのがJavaの大きな強みです。
【UiPath】AppsでAttended Robotを動かすと爆速な件

# はじめに
UiPath Appsのアップデートで、Apps上からAttendedを動かすことができるようになりました（2023年8月のリリースみたいなんで結構前ですが）。

従来はUnattendedのみだったので、ロボットを実行し終えるまで時間がかかり、Webアプリケーションとして大きな欠点がある状態でした。
ということで、今回はAttendedで動かしたとき、どれくらい実行速度が改善するかを検証します。


# つかうもの
※クラウド環境は2023年12月時点のもの
Automation Cloud(Apps, Orchestrator, Cloud Robot Serverless) Enterprise版
Attended/Unattended Robot v2023.10


# 検証の仕方
こんな感じのアプリを作ってみました。各ボタンを押すとロボットが動き、実行が終了すると時間が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/0710a27a-3486-3829-ba60-c58406130100.png)

Attendedの実行速度を検証するために、Unattended（サーバレスCloudロボットとセルフホスト）と比べてみます。またワークフローの作り方ですが、Windows/クロスプラットフォームのそれぞれをフォアグラウンドプロセスとバックグラウンドプロセスで作って比べてみます（Appsでフォアグラウンドプロセスはあまり使わないケースかもしれませんが）。
サーバレスCloudロボットは、クロスプラットフォームかつバックグラウンドプロセスのみが対応しているので、それ以外のパターンは無視します。

純粋なApps-ロボット間のリードタイムを計測するために、ワークフローの中身は空にしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/d49393c2-fd0a-7bab-a080-e929fe923c82.png)


# 結果
検証結果です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89445/b8bf2597-17e4-10ca-7969-21e291c03508.png)

Attendedの爆速ぶりは明らかでした。実装形態に関わらず1秒以下でロボット実行可能でした。
セルフホストURも健闘しました。これくらいの時間であればAppsで使用できるかもしれません。ただし、セルフホストの場合は用意したPC環境によって大きく結果が変わると思います（私の用意したPCが特別速かった可能性もあります）。
サーバレスCloudロボットは平均10秒近くのオーバーヘッドがかかり、今回の検証では最も悪い成績でした。流石に毎回10秒以上かかっていてはストレスが溜まるので、Apps目的で利用するには厳しいかと思います。仮に使ったとしても非同期実行にするなどしないといけないです。

また、Windowsよりクロスプラットフォームの方が早く、フォアグラウンドプロセスよりバックグラウンドプロセスの方が早い結果となりました。ここは想定通りです。


# おわりに
検証結果から明らかなのは、やはりAttended実行は爆速でした。Appsの利用者がAttendedを所有している場合は、Attended実行しか選択肢はないでしょう。
しかし、Attendedは有償ライセンスのため、全社員に使わせるアプリケーションをデプロイする場合は、Apps利用者が必ずしもAttended所有者とは限らないので、この方法は使えません。Apps利用者がAttendedを持っているか・いないかによってAttendedまたはUnattended実行かを分岐するようなロジックは、現時点ではおそらく組めないと思われます（今後のアップデートで可能かもしれません）。
また、必要がない限りフォアグラウンドプロセスを避け、バックグラウンドプロセスで実装することも重要だと思います。
REST API からのフローの起動


以下のヘルプを見つけたので、自動起動フローをPostmanを使って呼び出そうと思います。

[REST API からのフローの起動](https://help.salesforce.com/s/articleView?id=sf.flow_distribute_system_rest.htm&type=5)

Custom Invocable Actions エンドポイントを使用して、REST API から自動起動フローを呼び出します。

次の例では、フロー「Escalate_to_Case」の有効なバージョンを呼び出します。

```
POST /v33.0/actions/custom/flow/Escalate_to_Case
```

要求で、フローの 2 つの入力変数 (CommentCount と FeedItemId) の値が設定されます。呼び出されると、フローで次の内容がチェックされます。

```Json
{ 
"inputs" : [ {
   "CommentCount" : 6,
   "FeedItemId" : "0D5D0000000cfMY"
   } ] 
}
```

```
{{_endpoint}}/v{{version}}/actions/custom/flow/update_lookup_see2
```


早速、Postメソッドで作って呼び出します。
あれぇ、404エラーだ。URLがない？


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/b2d1a606-777c-cc5d-fb97-973031791385.png)

ボタンを作る時のようにGetメソッドを使うと...
レスポンスは期待していたものとは違う。（画面を呼び出しているような...）しかし、200が返ってきています。
Salesforceの画面をみると、思った通りに更新されています。

```
{{_endpoint}}//flow/update_lookup_see2?recordId=001Hz00000hjmRwIAI
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3f89925a-a0d3-9eb9-7b68-e2369d5718ba.png)

このヘルプを読むとリクエストのURLが違いますね。

```
curl https://MyDomainName.my.salesforce.com/services/data/v59.0/actions/custom -H "Authorization: Bearer token"
```

[カスタム呼び出し可能アクションの取得](https://developer.salesforce.com/docs/atlas.ja-jp.246.0.api_rest.meta/api_rest/resources_actions_invocable_custom_get.htm)

services/data/を追加します

```
{{_endpoint}}/services/data/v{{version}}/actions/custom/flow/update_lookup_see2
```

今度は実行できたようです。どうもヘルプのURLは正しくないですね。
フローの実行結果も興味深い。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/30120f98-caeb-a6c5-0ff6-9970c0650f10.png)

```Json
[
    {
        "actionName": "update_lookup_see2",
        "errors": null,
        "isSuccess": true,
        "outputValues": {
            "Flow__InterviewGuid": "193418b6c28ab9424ced22ae095a18d0b6e6277-29f6",
            "Flow__InterviewStatus": "Finished"
        },
        "version": 1
    }
]
```

# 関連

+ [Launch flow from rest api with arrays and nested objects](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000QKUdn)
【Docker】アーキテクチャの違いでつまづいたので調べてみた

どうもこんにちは。

今回は、Dockerを使用してRailsの環境構築をしていた時につまづいた、「x86_64」「amd64」「arm64」の違いについて調べてみました。

私が使用しているPCはApple Silicon M2チップのMacBookProです。

# アーキテクチャについて

## x86_64/amd64

この二つのアーキテクチャは、呼び方が異なるだけで同じアーキテクチャを指しているようです。

主にデスクトップやサーバー向けのアプリケーションで使用されています。

## arm64

ARMベースのデバイスやサーバーで使用されるアーキテクチャで、特に省電力性や効率性が求められる環境での使用に適しています。

# Dockerコンテナへの記述

ARMアーキテクチャを採用しているPCの場合、`docker-compose build`を実行した時にアーキテクチャが違いますとエラーが出ることがあります。

その場合、`docker-compose.yml`にplatformを指定することで解決できます。

```yml
db:
    image: mysql:8.0
    platform: linux/x86_64   # platform: linux/amd64 でもOK
    ports:
        - "3306:3306"
    volumes:
        - ./tmp/volumes/db:/var/lib/mysql
    environment:
        MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
```

# 補足

ARMアーキテクチャを使用している場合、以下のGemが動作しません。

```Gemfile
gem 'listen'
```

理由として、`listen`というGemの内部で動作している`inotify`というシステムコールを使用して動作しているのですが、これがARMアーキテクチャではサポートされていないのが問題のようです。

その場合、`listen`を使用しているコードはコメントアウトするとうまく行きます。

以下に例を示しておきます。

```ruby
I18nJS.listen
```

を

```ruby
# I18nJS.listen
```

に変えてください。
JS （php smarty内 .tpl 記述） セレクトボックス、テキストボックス制御

## ■完成イメージ
・セレクトボックス入力可　、テキストボックス入力不可
![スクリーンショット (909).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478380/5d936710-fe1a-5cf6-0019-d8581b8a2b8c.png)

・セレクトボックス入力不可　、テキストボックス入力可
![スクリーンショット (910).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478380/39f14355-5018-9b6d-9a43-8ecf9a796baa.png)

## ■機能説明
・セレクトボックスに値が入っている場合は、テキストボックスは入力不可。

・セレクトボックスが「未選択（値がない）」の場合、テキストボックス入力可、かつテキストボックスへ文字が入っている場合は、セレクトボックス選択不可。

## ■ソースコード
```JS main.js
document.addEventListener("DOMContentLoaded", function() {
    var time_of_death_time = document.getElementById("time_of_death_time"); //セレクトボックス
    var time_of_death_free = document.getElementById("time_of_death_free");//テキストボックス

    var time_of_death_free_value = document.getElementById("time_of_death_free").value;//テキストボックスの値

    time_of_death_free.disabled = true; 

    if(time_of_death_free_value === '') {

            time_of_death_time.addEventListener("change", function() {
                toggleTextBox_SelectBox_Death_Time(time_of_death_time, time_of_death_free);
            });

            console.log("if time");
     } else {

            time_of_death_time.disabled = true;
            console.log("else time");
     }
  
});

time_of_death_free.addEventListener("input", function () {

        var time_of_death_time = document.getElementById("time_of_death_time");
        var time_of_death_free = document.getElementById("time_of_death_free");
        var time_of_death_free_value = document.getElementById("time_of_death_free").value;

        if(time_of_death_free_value === '') {

             time_of_death_time.disabled = false;

            time_of_death_time.addEventListener("change", function() {
                toggleTextBox_SelectBox_Death_Time(time_of_death_time, time_of_death_free);
            });

            console.log("if time");

     } else {

            time_of_death_time.disabled = true;

            console.log("else time");

     }
});

function toggleTextBox_SelectBox_Death_Time(selectBox, textBoxElement) {
    var selectedValue = selectBox.value;

    textBoxElement.disabled = selectedValue !== "";
    textBoxElement.readOnly = selectedValue !== "";
}

```