OmniAICreator/Qiita-1.07M huggingface dataset:
【Xcode】control + mで引数を自動で改行

Xcode15から使えるショートカットで、引数のどこかにカーソルを合わせて`control + m`を押すと、引数が自動で改行される。

![スクリーンショット 2023-12-27 17.46.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640032/801486c9-30ae-2413-433c-a219b646026d.png)

↓↓↓

![スクリーンショット 2023-12-27 17..png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640032/3d1e0d10-c280-3801-0db2-f30dec8ad3ff.png)
npm 公式ドキュメントを読んでみる

## 前提
フロントエンドとしてnpmを使っているものの、根本から理解できているわけではないため[公式ドキュメント](https://docs.npmjs.com/about-npm)の自分の業務に関係がありそうな部分をDeepLを使って日本語訳化しました。

## npmとは
npmは世界最大のソフトウェアレジストリです。

npmは3つの異なるコンポーネントで構成されています：
- ウェブサイト
- コマンドラインインターフェイス（CLI）
- レジストリ

パッケージを見つけるため、プロファイルを設定するため、また、npmの他の側面を管理するためにウェブサイトを利用しましょう。例えば、組織を設定して、パブリックまたはプライベートパッケージへのアクセスを管理することができます。

CLIはターミナルから実行され、ほとんどの開発者がnpmとやりとりする方法です。

レジストリは、JavaScriptソフトウェアとそれを取り巻くメタ情報の大規模な公開データベースです。

### npmを使うことでできるようになること
- コードのパッケージをあなたのアプリに適応させるか、パッケージをそのまま組み込む。
- すぐに使えるスタンドアロンツールをダウンロード。
- npxを使ってダウンロードせずにパッケージを実行する。
- 複数のバージョンのコードとコードの依存関係を管理する。

※一部省略

## パッケージとモジュール
### 導入
#### 公開npmレジストリについて
公開されているnpmレジストリは、JavaScriptパッケージのデータベースで、それぞれがソフトウェアとメタデータで構成されている。

#### パッケージとモジュールについて
##### パッケージとは
パッケージとは、package.jsonファイルで記述されたファイルやディレクトリのことです。パッケージを npm レジストリに公開するには、package.json ファイルが必要です。

##### モジュールについて
モジュールとは、Node.jsの`require()`関数でロードできる、node_modulesディレクトリにあるファイルやディレクトリのことです。

:::note info
note
モジュールはpackage.jsonファイルを持つ必要はないので、すべてのモジュールがパッケージになるわけではありません。package.jsonファイルを持つモジュールだけがパッケージでもあります。
:::

### レジストリへのパッケージの提供
#### package.jsonファイルの作成
パッケージにpackage.jsonファイルを追加することで、他の人が管理やインストールをしやすくすることができます。

#### Node.js modulesの作成
Node.js モジュールは、npm に公開できるパッケージの一種です。

### レジストリからのパッケージ取得
#### ローカルにパッケージをダウンロードしてインストールする
Node.jsのrequireのようなものを使って、自分のモジュールからパッケージに依存したい場合は、パッケージをローカルにインストールできます。これはnpm installのデフォルトの動作です。

##### スコープされていないパッケージのインストール
スコープされていないパッケージは常にパブリックであり、誰でも検索、ダウンロード、インストールできる。
公開パッケージをインストールするには、コマンドラインから以下のコマンドを実行する
```
npm install <package_name>
```
カレントディレクトリにnode_modulesディレクトリが作成され（まだ存在しない場合）、そのディレクトリにパッケージがダウンロードされます。

#### グローバルにパッケージをダウンロードしてインストールする
パッケージをグローバルにインストールすることで、パッケージ内のコードをローカル・コンピューター上でツールのセットとして使うことができる。
グローバルにパッケージをダウンロードしてインストールするには、コマンドラインで以下のコマンドを実行する：
```
npm install -g <package_name>
```

### レジストリからダウンロードしたパッケージの更新
レジストリからダウンロードしたローカルパッケージやグローバルパッケージを更新することで、コードやツールの安定性、使いやすさ、安全性を保つことができます。

#### ローカルパッケージの更新
プロジェクトが依存しているローカル・パッケージを定期的に更新し、依存関係の改善に合わせてコードを改善することをお勧めします。

プロジェクトのルート・ディレクトリでupdateコマンドを実行する：
```
npm update
```
アップデートをテストするには、outdatedコマンドを実行する。
```
npm outdated
```

#### グローバルパッケージの更新
##### 更新が必要なグローバルパッケージの決定
更新が必要なグローバルパッケージを確認するには、コマンドラインで次のように実行する：
```
npm outdated -g --depth=0
```

##### 単一のグローバルパッケージの更新
単一のグローバル・パッケージを更新するには、コマンドラインで次のように実行する：
```
npm update -g <package_name>
```

##### グローバルにインストールされているすべてのパッケージの更新
すべてのグローバル・パッケージを更新するには、コマンドラインで次のように実行する：
```
npm update -g
```
【個人用メモ】React Native+Expo(managed)で、expo-apple-authenticationを含めたらEAS Buildエラー

久しぶりにApple SignInを実装しようとしたら少し詰まったので
個人用に忘れないようざっくりメモ

## やりたいこと
Expo(v49 + managed wolkflow)でApple SignIn したい

## 起きた事象
[expo-apple-authentication](https://docs.expo.dev/versions/latest/sdk/apple-authentication/) を含めてEAS Buildを行うとビルドが通らない

## 解決した手順
1. [Certificates, Identifiers & Profiles](https://developer.apple.com/account/resources/identifiers/list) > 該当するIdentifierをクリック > Capabilitiesにある`Sign In with Apple` のEditをクリック
    - `Enable as a primary App ID`を選択してSave
2. [expo.dev](https://expo.dev/accounts/)で既に設定したプロファイルを削除する 
    - ![Group 14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630810/0bbff1c4-dd41-8e9c-d67f-13701e9719a4.png)
    - `eas credentials`などでリセットする方が正しいかもしれません。削除する場合は自己責任でお願いします。
3. 再度`eas build`でprovisioningをアップロード
年末年始休暇入る前にやっておいた方が良いこと

## 年末年始休暇入る前にやっておいた方が良いこと

今まで社会人を経験してきた中で年末年始休暇の前にやっておいた方が良い事まとめました。

1. 緊急対応時の対応確認
1. チームメンバーの出欠確認
1. 持っているタスクのステータスを纏めておく
1. 休暇復帰日に何するか決めておく
1. 勤怠システム締めておく
1. 三が日何するか決める

### 緊急対応時の対応確認
年末年始は何かとシステムトラブルが起きる可能性が高いです。そのため緊急時の対応を確認しておくと慌てずに対応できます。具体的には、

* エスカレーションルートの確認
* 電話番号・メールアドレスの確認

をチームメンバー内で確認しておくと良いです。

### チームメンバーの出欠確認
年末年始は有給をくっつけて取得するチームメンバーもいるためチームメンバーの出欠確認表を作っておくことを勧めます。自分の経験ですが「年明けの出社日にいると思って重要なミーティング組んでたら有給だった。」なんてことがありました笑

### 持っているタスクのステータスを纏めておく
長期休暇を挟むと自分が何をすべきなのか忘れてしまいます。そのため、仕事初日に"思い出す作業"が発生してしまい1日無駄にしてしまうことが多々あります。

メモ帳に簡単にでいいのでタスクステータスを書いておくと仕事初日の自分から感謝されます。

### 休暇復帰日に何するか決めておく
上記のポイントと重なるのですが初日は業務の動き出しが遅いため手持ち無沙汰になりがちです。そのため、業務をやっている休暇前の段階で「⚪︎⚪︎しよう」と決めておくと良いです。

これは業務の動きだしがスムーズになることもそうですが、休暇最終日に「明日仕事何しようかな」と不安になってしまうことがあるのでそれの回避の為に実施する意味もあります。

### 勤怠システムを締めておく

**絶対に休暇入る前に勤怠確認しましょう**

### 三が日何するか決める

1月1日からの3日間は1年の中で1番早く時間が過ぎる日です。「何もやることがないなー」と言いながら読もうと思ってた本も積んだまま開くことなくいつの間にか仕事始めとなってしまいます。

三ヶ日は何するかをスケジューリングしておきましょう。1年の始まりが気持ちいいとその後も良いスタート切れる気がします。

## 終わり

以上が自分の社会人経験の中で培った年末年始休暇入る前にやっておいた方が良いことでした。誰かの助けになれば幸いです。
Apple SiliconのMacでlibusb(pyusb)がNo backend availableエラーを出したときの対処法


こちらに解決策がありました。

https://stackoverflow.com/questions/70729330/python-on-m1-mbp-trying-to-connect-to-usb-devices-nobackenderror-no-backend-a

問題は libusb の動的ライブラリが pyusb によって見つからないことに起因しているようです。Homebrewを使用して libusb をインストールした場合、そのライブラリファイルは /opt/homebrew/Cellar/libusb/1.0.24/lib に配置され、/opt/homebrew/lib にシンボリックリンクが作成されますが、pyusb はこれらのパスをデフォルトでは認識しません。

とのこと。
パスを通すと動作しました。

```
echo 'export DYLD_LIBRARY_PATH="/opt/homebrew/lib:$DYLD_LIBRARY_PATH"' >> ~/.zshenv
source ~/.zshenv
```

サンプルコードです

```
import usb.core
import usb.util

# USBデバイスのリストを取得
devices = usb.core.find(find_all=True)

# 各デバイスの情報を表示
for device in devices:
    print("Device:", device)
    print("  ID Vendor:ID Product: {:04x}:{:04x}".format(device.idVendor, device.idProduct))
    print("  Manufacturer:", usb.util.get_string(device, device.iManufacturer))
    print("  Product:", usb.util.get_string(device, device.iProduct))
    print("  Serial Number:", usb.util.get_string(device, device.iSerialNumber))
    print()
```
[FlowKit]-2 コンペンセーションの適用(pythonでFACS解析)

pythonでFACS解析のデータ（FCSファイル）を操作する方法を記しています。
本記事は**コンペンセーションの適用方法**です。

**公式ドキュメント**
https://flowkit.readthedocs.io/en/latest/
https://pypi.org/project/FlowKit/

### おさらい

```python 
import flowkit as fk
import bokeh
from bokeh.plotting import show
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
bokeh.io.output_notebook()


fcs_path = './[ファイル名].fcs'
sample = fk.Sample(fcs_path)

#sampleメタデータの出力（辞書型）
print(sample.get_metadata())

#コンペンセーションの値の出力
print(sample.get_metadata()['spillover'])
```

### コンペンセーションの値の加工

コンペンセーションを適用する際には、適切な形のndarrayしか受け付けない。したがって、`sample.get_metadata()['spillover']`によって出力されたコンペンセーション値を加工するひつようがある。

まずは出力例。緑色の網掛け部分がコンペンセーション値の本体である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655949/0139fb8b-4a0c-1873-a1e3-6aea472f8470.png)

これを以下のような配列に加工する必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655949/ab48f7b2-54d3-e90e-d63e-86e8781cc27e.png)
配列の形状は `チャンネル数`×`チャンネル数` にする。
加工方法は以下に2パターン記す。

#### テキストエディタ等で手作業で加工する
テキストエディタ等にコピペした後に、手作業で`改行` `[` `]` `,`を加える方法。
一番簡単でなんだかんだエラーが少なそう。

#### コードで加工する
詳細は割愛するが、`sample.get_metadata()['spillover']`の出力値を指定した文字列で分割した後に、ndarrayに変換している。
上手くいかなかったら修正が必要になるので、その場合手作業の方が短時間で済むかも。

```python
#コンペンセーションの値を抽出してndarrayに変換
channels = len(sample.channels)-7
compe = sample.get_metadata()['spillover'].split(str(channels)+',')[1].split('-W,')[int(channels/3)].split(',')
comp_array = np.array(compe, dtype=float)
comp_array = np.reshape(comp_array, [int(channels), int(channels)])

#ndarrayが正しく生成されていることを確認
print(comp_array)
print(comp_array.shape)
```

### コンペンセーション値の適用

以下のコードを実行する。実行時の出力は特にない。
```python
sample.apply_compensation(comp_array)
```

これ以後、パラメーター`source='comp'`でコンペ済みのeventを呼び出せる。

```python
##実行例

#eventを取り出してDataFrameに
df_events = sample.as_dataframe(source='comp')
#eventを取り出してndarrayに
array_events = sample.get_events(source='comp')
```
ヒューリスティック(AHC)用にoptunaで雑にパラメタチューニングできるようにした

# やった事
- スコアを出せるコードと調整するパラメタが決まっている状態でパラメタ探索をできるようにした
    - google colab上で動く言語、コードなら調整すればいけそう
    - 探索はoptunaに全まかせ
    - 探索速度は少し妥協
        - テスト毎にosでコードを実行している為

# 動機
AHC_029に参加した際に、パラメタ探索の為に無駄に提出回数を稼いでしまった事を後悔しているので、どうにかしたいと思い作成しました

![スクリーンショット 2023-12-27 16.58.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292016/3c0a8c4c-7388-4ceb-e7b4-025b74e854ea.png)


# 参考にしたサイト
https://blog.knshnb.com/posts/ahc007-optuna/

# 参考先と異なる点
- google colabで動かす事を重視
- pythonユーザーに使いやすく

# 作成したipynb
使い方はREADME

https://github.com/erukku/for_hypara_tuning_marathon
CI/CDを使わずAmplifyを利用する際に環境変数の置き場に困ったときの対応

## 概要
Amplifyでは環境変数をブランチごとに設定することができ、ビルド時に環境変数を読み込んで `secret.json` 等のgitignoreしたファイルを生成することで認証情報等をGitに含めないようにすることができます。Amplifyに設定した環境変数はSSMパラメータで自動的に暗号化されます。しかしこれはCI/CDを使用せず `amplify publish` でデプロイを行う方式では利用できません。
案件によってはGitを用いたCI/CDが使えないこともありますが、その場合下記のように対応しています。

## 手順
1. `.env` ファイルを作成し、下記のようにしておく
    ```
    AWS_PROFILE=[profile name] 
    ```
1. 下記コマンドを実行する
    ```sh
    ENV=[env]
    SSM_KEY_PREFIX="/[project name]/$ENV/"
    SAMPLE_PATH="SAMPLE"
    aws ssm put-parameter --name "$SSM_KEY_PREFIX$SAMPLE_PATH" -type SecureString --value [value] --overwrite --profile [profile]
    ```
1. `/amplify/hooks/pre-publish.sh` を下記のように作成する
    ```sh
    echo "pre-publish hook"

    if [ -z "$(which jq)" ]; then
        echo "Please install jq to run script."
        exit 0
    fi
    
    parameters=`cat`
    error=$(jq -r '.error // empty' <<< "$parameters")
    data=$(jq -r '.data' <<< "$parameters")
    dir=`pwd`
    env=`jq -r '.amplify.environment.envName' <<< "$data"`
    
    dotenv_path="$dir/.env"
    
    if [ ! -e $dotenv_path ]; then
        echo "Please create .env file in project root path."
        exit 1
    fi
    
    source $dotenv_path
    
    if [ -z "$AWS_PROFILE" ]; then
        echo "Please set AWS_PROFILE in .env file."
        exit 1
    fi
    
    if !(type "aws" > /dev/null 2>&1); then
        echo "Please install aws cli."
        exit 1
    fi
    
    SSM_KEY_PREFIX="/[project name]/$ENV/"
    SAMPLE_PATH="SAMPLE"
    
    SAMPLE_ID=`aws ssm get-parameter --name "$SSM_KEY_PREFIX$SAMPLE_PATH" --with-decryption --profile $AWS_PROFILE | jq '.Parameter.Value' -r`
    
    echo "{
        \"SAMPLE_ID\": \"$SAMPLE_ID\"
    }" > "$dir/src/secret.json"
    
    if [ ! -z "$error" ]; then
        echo "Amplify CLI emitted an error:" $(jq -r '.message' <<< "$error")
        exit 1
    fi
    
    echo "project root path:" $(pwd);
    echo "Amplify CLI command:" $(jq -r '.amplify | .command' <<< "$data")
    ```

## 実行
下記コマンドを実行するとhookで実行されるシェルスクリプトが、`.env` ファイルに書いた `AWS_PROFILE` の値を使用してSSMパラメータから値を取り出してJSONに書き込み、 `src/secret.json` を出力したあとデプロイが行われます。

```sh
amplify publish
```
超キツキツ案件を乗り越えるための技術スタック

# 自己紹介
- 大分県生まれ大分県育ち東京都在住(帰省中)
- スタートアップ企業のCTO
- フリーランスエンジニアとしても活動中

# 結論
**案件によって大幅に変わる**

というのは嘘ではありませんが、今回は請負開発かつ社内システム開発(...つまりエンドユーザーが限られている開発)について紹介します。

# 前提
- デザイナーなし
- エンジニアが1人で全て開発
- Web系システムを開発
- 開発期間 1ヶ月~3ヶ月


## 提案1
- フロントエンド
    - Typescript
    - React
    - Material UI

- バックエンド
    - PHP
    - Laravel


## 提案2
- フロントエンド
    - Typescript
    - React
    - Material UI

- バックエンド
    - Django4
    - Python3



# React×TypeScript×MaterialUIを採用するワケ
- Material UIを用いることで → 綺麗なUIを最低限の知識で構築できる
- Reactを用いることで → 再利用可能なコンポーネント開発で素早くアプリを構築できる
- Typescriptを用いることで → しょうもないバグを防ぐことができる


# バックエンドにDjangoを用いるワケ
- とにかくデータベースの構築が簡単
- リレーションとかも組みやすい
- リーダブルコードになりやすい
- スパゲティコードにもなりやすい
- 拡張性が高い

# バックエンドにLaravelを用いるワケ
- 拡張性が高い
- ドキュメントが豊富
- これだけでなんでもできる
- サーバーを選ばなくていい(Djangoはvpsじゃないと厳しい...)
- 案件が多い


# 総じて
- Vueは使ったことないからわからない
- 紹介したスタックはフリーランス案件が多いので必然的にこうなってます笑笑
- あと個人的な観点が多く入ってるので異論は認めます
Raspberry Pi 400 を PC のキーボードにする方法

Raspberry Pi 400 は、 Raspberry Pi とキーボードとが一体化されている端末です。
このキーボードを PC で使えたら便利なのになと思って調べてみました。

何故かビルドしないとうまく動かなかったので、今回はビルドする方法から紹介します。

## 環境

今回の環境は下記のとおりです。

### 開発端末

- **OS**： Windows 11 Pro
- **CPU**： Intel Core i7-9750H
- **メモリ**： 64GB
- **GPU**： NVIDIA GeForce RTX 2070 Max-Q

### Raspberry Pi

- **端末**： Raspberry Pi 400
- **OS**： Raspberry Pi OS with desktop
- **System**： 64-bit
- **Kernel version**： 6.1
- **Debian version**： 12 (bookworm)

## Raspberry Pi OS のセットアップ

まずは Raspberry Pi 400 を使うために Raspberry Pi OS のセットアップを行います。
特に特殊な作業はありませんが、よく分からない方は下記を参考にしてください。

https://qiita.com/IoriGunji/items/718f8245136af94066eb

## OTGモードでの起動設定

```bash
sudo nano /boot/config.txt
```

末尾に追記します。

```/boot/config.txt
dtoverlay=dwc2
```

再起動します。

```bash
sudo reboot
```

## USB HID キーボードのビルド

前述の通り、ビルドを行う必要があります。
手順の通り行えば問題なく動くと思います。

### 必要なパッケージのインストール

```bash
sudo apt -y install libconfig-dev git cmake
```

### GitHub リポジトリのクローン

```bash
git clone https://github.com/Gadgetoid/pi400kb
```

### ディレクトリの移動

```bash
cd pi400kb
```

### サブモジュールの更新

```bash
git submodule update --init
```

### ビルド用のディレクトリの作成

```bash
mkdir build
```

### ビルド用のディレクトリに移動

```
cd build
```

### ビルド手順の生成

```bash
cmake ..
```

### ビルドの実行

```bash
make
```

## ビルドしたファイルの実行

PC と Raspberry Pi 400 を USB A to C ケーブルなどで接続します。
USB A 側を PC に接続し、 Type-C 側を Raspberry Pi 400 に接続します。

USB ケーブルで接続したら、 Raspberry Pi 400 を起動します。

### モジュールの読み込み

```bash
sudo modprobe libcomposite
```

### ビルドしたファイルの実行

```bash
sudo ~/pi400kb/build/pi400kb
```

PC と Raspberry Pi 400 の制御の切り替えは、 `Ctrl` + `Raspberry` でできます。
終了するには `Ctrl` + `Shift` + `Raspberry` を押します。

## スタートアップへの登録

毎回、起動するのは面倒なので、スタートアップへ登録しておきます。

### libcomposite モジュールの自動読み込み設定の追加

```bash
sudo nano /etc/modules
```

末尾に下記を追記して保存します。

```/etc/modules
libcomposite
```

:::note info
**設定例**
環境によって異なりますが参考にしてみてください。

```/etc/modules
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.

i2c-dev
libcomposite
```
:::


### ビルドした実行ファイルのコピー

```bash
sudo cp ~/pi400kb/build/pi400kb /usr/sbin/pi400kb
```

### サービスへの登録

下記のコマンドを実行し、 `pi400kb.service` の中身をコピペして保存します。

```bash
sudo systemctl edit --force --full pi400kb.service
```

```pi400kb.service
[Unit]
Description=pi400kb USB OTG Keyboard & Mouse forwarding

[Service]
ExecStart=/usr/sbin/pi400kb
User=root
Group=root
Type=simple
Restart=on-failure

[Install]
WantedBy=multi-user.target
```

### サービスの開始

```bash
sudo systemctl start pi400kb.service
```

### ステータスの確認

`Active: active (running)` と表示されていれば問題ありません。

```bash
sudo systemctl status pi400kb.service
```

### スタートアップへの登録

```bash
sudo systemctl enable pi400kb.service
```

# 参考文献

下記のサイトを参考にさせて頂きました。

https://github.com/Gadgetoid/pi400kb
日本語プログラミング言語Mind前史 - スタックフレームとFORTH

# はじめに

　前回に続き、Forth言語との関連でMindの仕組みの根幹をなすスタックフレームについて説明させてください。

# スタックフレーム

　Cで「スタックフレーム」という言い方をするときCPUのスタックポインタ（SPレジスタ）を使った操作を指すようです。関数の入り口でSPを下げてメモリ領域を確保し、そこを関数内のローカル変数群として使うようです。

　またコンパイラの内部動作に限らずとも、プログラム作成者が自前のスタック機構を書いてデータを保持することもあると思います。

　一方でFORTH系、あるいはスタック指向言語ではスタックポインタを２本使うのが特徴です。

　１本目は従来通り、Call/Returnの戻り番地を積む、スタックフレームとして使うなどの用途で、もう１本はデータの受け渡しに使います。

　FORTHの生みの親のチャールズ・ムーアは スタックポインタが１本でも３本でもなく２本というのが重要だ と言っています。

　プログラムの記述という面から見ると、１本目のリターンスタックは（コンパイラが内部で使うことはあっても）プログラム作成者が意識することはありませんが、２本目のスタック（データスタック）については明確に意識したプログラムを書くことになります。ここがFORTHでいうスタックと、一般に言われるスタックの違いかと思います。

# 8087のマシンコードってFORTHなんです

　スタックを明に使ったハードとしては（昔の話なのですが）インテル社の浮動小数点コプロセッサ 8087 があります。8087のマシンコードってまんまFORTHなんですね。
　私が昔、FORTHをやっていたころですが、あるとき浮動小数のライブラリを作ることになりました。8087が使われ始めた時期で、ソフト処理でやるタイプと8087を使うタイプとで２種類のライブラリを開発しました。

　いざ8087の命令セットを見たらまるでFORTHで小躍りしたことがあります。浮動小数演算についてはFORTHコンパイラはほとんど何もせずそのまま機械語に置き換えていけば良いからです。
　たとえば当時のFORTHのソースコードこんなふうに書いたとします。

　1.2　3.4　F+　　（数値定数は F 1.2 のような前置きがあったと思いますが簡単にします）

　FORTHコンパイラは上のソースをこんなふうに処理すれば良いわけです。

　1.2
　3.4
　F+

　　↓

　PUSH 1.2　　（8087のニモニックはこの通りではありません。あくまで概念です）
　PUSH 3.4
　ADD

　何のことはない、FORTHのコンパイラなのに、やっていることはアセンブラです。私はライブラリ作成でだいぶ手抜きができました。（ややこしいのですが当時の私のFORTHはアセンブラ記述もできました）

# FORTHって低水準言語なの？

　FORTHって低水準言語なの？と思われた方もおられるかもしれません。ただ、たとえばHP社の逆ポーランド電卓の操作が「低水準だ」とか「これじゃアセンブラみたいだ」と思う人はいないと思います。逆に私がFORTHをやっているときは、CだのPascalだの当時流行していた言語が逆に低水準に見えていました。

　スタック指向の言語としてはこのほかにプリンタ制御言語の PostScript があります。ただ、これを使ってプログラムを書くのはプリンタのドライバを開発する人など限られていると思います。あまり知られていないという点では8087と似ています。

# スタックを用意すれば日本語の語順にできる

　CであれJavaであれ、まずはスタック機構を用意しておけばあとは比較的簡単に日本語の語順を受け入れることができると思います。

　Mindのディスパッチャ（Mコードを解読実行するもの）はデータスタックを実現するためにCをごりごり書いてスタック操作をおこなっています。なくべく簡単にするためマクロを用意しています。カーネルのソースにはこんな記述があります。

　　PUSH_L( result, 0 );　　←64bit整数をpush (上位32, 下位32で分けています)

　極端に単純化すればですが、数値定数があったらPushし、数値でないワードがあったらCallするという感じで仕組みを作れば行けるように思います。

　多くの言語にある配列型を使えば容易にスタックになりますが汎用のスタックという用途で数値も文字列も混在してpushする使い方なので工夫が必要で、Cではunionを使って型を管理しています。

　Javaだとリスト型みたいなのがあったと思うのですが、それなら「汎用オブジェクトのリスト」みたいな定義をして、その仮想スタック（？）には数値も文字列も混在して入れられるのではと思ったことがあります。

# おわりに

　このあたりを書き始めるときりがないのですが、実はだいぶ前にFacebookで「スタックコンピュータとFORTH」という長い記事を投稿したことがあります。あとでQiitaのほうにも投稿できるといい思っています。そちらのほうがより正確に説明できるかと思います。

　Mindユーザーの@mylifewithviolinさんの[Qiitaの記事](https://qiita.com/mylifewithviolin/items/2b9a4cba5b475af84f20)のご質問に対してコメントしていた内容ですが、独立した記事にまとめてみました。
[k8s] Flux alertsでfluxの通知がSlackに送られるようにしてみた

## はじめに

前回は External Secret OperatorとVaultを連携してkubernetesのsecret基盤を整えました。

https://qiita.com/piny940/items/66214e8f7c8af18ba014

今回は flux notificationを使ってfluxの通知がslackに送られるようにしていきたいと思います。

完成品は Github 上に公開してありますので参考程度にどうぞ
https://github.com/piny940/infra/tree/main/kubernetes

## 環境

OS:  
Ubuntu22.04

kubeadm:

```
$ kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"28", GitVersion:"v1.28.2", GitCommit:"89a4ea3e1e4ddd7f7572286090359983e0387b2f", GitTreeState:"clean", BuildDate:"2023-09-13T09:34:32Z", GoVersion:"go1.20.8", Compiler:"gc", Platform:"linux/amd64"}
```

flux:

```
$ flux version
flux: v2.2.0
distribution: flux-v2.2.0
helm-controller: v0.37.0
image-automation-controller: v0.37.0
image-reflector-controller: v0.31.1
kustomize-controller: v1.2.0
notification-controller: v1.2.2
source-controller: v1.2.2
```

## 前提

- flux の helm controller・kustomize controller が動作している
- External Secretが動作している
- fluxのPodはflux-systemという名前のnamespaceで動いている

## Slackの設定
[Slack API](https://api.slack.com/apps)をでCreate New Appをし、fluxの通知を送るためのSlack Appを作成します。

作成したら`OAuth & Permission`の`Scopes > Bot Token Scopes`からOAuth Scopeを追加します。今回はwebhookを用いてメッセージを送信するため、`incoming-webhook`を追加しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330232/0438fa50-72ed-544e-8f36-9527c9edc5e2.png)

`Install App`からチャンネルにSlack Appをインストールします。インストールしたら`Webhook URL`をコピーしてvault等に置いておきましょう。

## External Secretを作成
外部に配置したSecretを読めるよう、External Secretを定義します。External Secret以外を使っている場合はそれぞれの方法に従ってください。

`flux-alerts/external-secret.yaml`に次のように記述します。

```yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: slack-webhook-url
  namespace: flux-system
spec:
  secretStoreRef:
    name: vault-secret-store
    kind: ClusterSecretStore
  refreshInterval: 1m
  data:
    - secretKey: address
      remoteRef:
        key: flux
        property: slack-webhook-url
```
`spec.secretStoreRef`にはClusterSecretStore (あるいはSecretStore)の名前を記述します。また、`spec.data[].remoteRef`にはSlackのWebhook URLへのパスを指定します。

## Provider, Alertを作成
`flux-alerts/provider.yaml`に次のように記述します。

```yaml
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Provider
metadata:
  name: slack-bot
  namespace: flux-system
spec:
  type: slack
  secretRef:
    name: slack-webhook-url
```

`flux-alerts/slack-alerts.yaml`に次のように記述します。
```yaml
apiVersion: notification.toolkit.fluxcd.io/v1beta3
kind: Alert
metadata:
  name: slack-alert
  namespace: flux-system
spec:
  summary: "Flux alert"
  eventMetadata:
    env: "production"
    cluster: "cluster"
    region: "asia/japan"
  providerRef:
    name: slack-bot
  eventSeverity: info
  eventSources:
    - kind: GitRepository
      name: "*"
    - kind: Kustomization
      name: "*"
    - kind: HelmRepository
      name: "*"
    - kind: HelmRelease
      name: "*"
```

kustomization.yamlにこれらを登録すればfluxの通知がslackに送られるようになります。

## 最後に
今回はflux notificationを用いてfluxの通知がslackに送られるようにしました。
次回はkubernetesクラスタ上でDBサーバーを立てていこうと思います。
サンプル

# やることリスト
1. 挨拶
1. ほほおほ
1. 穂はおフォアhフォアｈｆ
1. hふぁおｗｆ

### コードブロック
```java
//void method
public class Sample {
  private String value;
  public void setValue(String value) {
    this.value = value;
 }
}
```
レコードのアクセス権限に相関

レコード共有の情報はどこで管理されているのでしょうか？
Shareオブジェクト

Salesforceには、レコードの共有を管理するオブジェクトとして、各オブジェクトごとにShareオブジェクトなるものが存在しています。ShareオブジェクトのAPI名は以下のようにされています。

標準オブジェクトの場合：AccountShare, OpportunityShare, ContactShare, etc...
カスタムオブジェクトの場合：CustomObject名__Share

項目は以下の通りです。詳しくはこちらを参照してください。
項目	データ型	説明
ParentID	参照	共有するレコードのIDです。
UserOrGroupId	参照	共有先のユーザ・グループのIDです。
AccessLevel	picklist	レコードへどの程度アクセスできるのかを指定します。
値は以下の通りです。
Read:参照可能
Edit:編集可能
All:すべて可能
RowCause	picklist	共有の理由です。主な値は以下の通りです。
Manual
Owner
Rule
...
以上の値以外の独自の理由も設定することができるらしいです。（Apex共有の理由）

このオブジェクトのレコードをどうにかして作成すれば、個人に対するレコードの共有ができるわけです。
このレコードを作成する方法はいくつか考えられます。

Data Loaderなどで、Shareオブジェクトのレコードを作成する。
Apexトリガを用いて、Shareオブジェクトのレコードを作成する。（これなら、個人レベルの共有も自動化できます。）
フローを用いて、Shareオブジェクトのレコードを作成する。（後述）


フローを使って共有を自動化する
レコードトリガーフローを使用して、Shareオブジェクトのレコードを作成することで、特定の状況におけるレコードの共有を自動化することができます。


レコード保存後のトリガーフローをします。
トリガー条件としては、「面接官項目が空白ではない・条件に一致する度にトリガ」でいいと思います。
キャンバスに配置する要素は「レコードを作成」要素だけでいいでしょう。面接官の変更とかを考慮すると、他の要素も検討したほうがいいんじゃないかなって思いますが。面倒なので今回はスルーしますが。

実際に作成した要素がこちらです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442974/4d133a76-0cc4-0391-530b-9c2722ed1e88.png)
ラズパイの再起動時のカメラの入れ替わりが発生しハマった件

## はじめに
ラズパイで複数のカメラを使っていて、こまったのでまとめます。

## 問題
- 導入したシステムで使用しているラズパイで再起動時にカメラの入れ替わりが発生。
- ゲージの種類も同じだったため、気づかずに検査がされていた

## 解決方法
- 変化するデバイスIDとUSBポートの番号を紐付けるクラスを作成し、 撮像ソフトではカメラを接続するUSBポートの番号を指定するようにした。

## おわりに
順次、ラズパイのソフトの入れ替え実施予定

## 参考URL
- [複数のWebカメラを使用する場合、USBポートの番号からデバイスを識別するクラスを作ってみました](https://dev.classmethod.jp/articles/opencv-device-id-by-port-number/#toc-6)
- [Raspberry PiでUSBのデバイス名を固定する：USBポート番号指定](https://www.raspberrypirulo.net/entry/usbname-fix-port#:~:text=USB%E3%83%9D%E3%83%BC%E3%83%88%E3%81%AE%E7%95%AA%E5%8F%B7%20USB%E3%83%8F%E3%83%96%E3%82%92%E4%BB%98%E3%81%91%E3%81%A6%E3%81%84%E3%81%AA%E3%81%91%E3%82%8C%E3%81%B0%E3%80%81%E4%B8%8B%E8%A8%98%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E5%90%84USB%E3%83%9D%E3%83%BC%E3%83%88%E3%81%AB%E7%95%AA%E5%8F%B7%E3%81%8C%E5%89%B2%E3%82%8A%E6%8C%AF%E3%82%89%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82%20Rasperry%20Pi%204%E3%81%AE%E5%A0%B4%E5%90%88%20LAN%E3%82%B3%E3%83%8D%E3%82%AF%E3%82%BF%E5%81%B4%E4%B8%8A%20%E2%87%92%20%22%2A%2Fusb1%2F1-1%2F1-1.1%2F1-1.1%3A1.0%2F%2A%22,%E2%87%92%20%22%2A%2Fusb1%2F1-1%2F1-1.2%2F1-1.2%3A1.0%2F%2A%22%20GPIO%E3%82%B3%E3%83%8D%E3%82%AF%E3%82%BF%E5%81%B4%E4%B8%8A%20%E2%87%92%20%22%2A%2Fusb1%2F1-1%2F1-1.3%2F1-1.3%3A1.0%2F%2A%22%20GPIO%E3%82%B3%E3%83%8D%E3%82%AF%E3%82%BF%E5%81%B4%E4%B8%8B%20%E2%87%92%20%22%2A%2Fusb1%2F1-1%2F1-1.4%2F1-1.4%3A1.0%2F%2A%22)
[Python][Julia]Project euler2 (プロジェクトオイラー2)

#### Project euler Ploblem 2 (プロジェクトオイラー2)
Even Fibonacci Numbers

備忘のために残しておく。

## 問題文 
フィボナッチ数列において、新しい項は前2項を足したもので生成される。
1と2から始めた場合、最初の10項は以下の通りである。
1,2,3,5,8,13,21,34,55,89,...
400万を超えない値のフィボナッチ数列の項を考えたとき、値が偶数の項の合計を求めよ。

#### (原文)
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be 
1,2,3,5,8,13,21,34,55,89,...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

## 答え 
<b>4613732</b>

#### 解答の方針
問題文の通り、フィボナッチ数列を作り、偶数の値の項を足していく。

#### Pythonのコード
```Python: Python(Ploblem2)
# フィボナッチ数列を作る
def fibonacci(n: int) -> int:
    if n == 1: return 1
    elif n == 2: return 2
    else:
        return fibonacci(n-1) + fibonacci(n-2)

# 偶数の値の項のみ足す
def even_fibonacci_sum(limit: int) -> int:
    sum: int = 0
    n: int = 1
    while fibonacci(n) < limit:
        if fibonacci(n) % 2 == 0:
            sum += fibonacci(n)
        n += 1
    return sum

print(even_fibonacci_sum(4000000))

```

#### Juliaのコード
```Julia: Julia(Ploblem2)
# フィボナッチ数列を作る
function fibonacci(n::Int64)::Int64
    if n == 1 
        return 1
    elseif n == 2
        return 2
    else
        return fibonacci(n-1) + fibonacci(n-2)
    end
end

# 偶数の値の項のみ足す
function even_fibonacci_sum(limit::Int64)::Int64
    sum::Int64 = 0
    n::Int64 = 1
    while fibonacci(n) < limit
        if fibonacci(n) % 2 == 0
            sum += fibonacci(n)
        end
        n += 1
    end
    return sum
end

println(even_fibonacci_sum(4000000))

```

## 追記
#### 再帰関数をメモ化した例
参考：[Pythonによるフィボナッチ数列の色々な求め方(一般項、反復法、再帰法)](https://qiita.com/dovedove/items/3456c4f317a5c680f437)

```Python: Python 追記分
def fibonacci_memo(n: int, memo={}):
    if n == 1: return 0
    elif n == 2: return 1
    elif n in memo: return memo[n]
    else:
        memo[n] = fibonacci_memo(n-1, memo) + fibonacci_memo(n-2, memo)
        return memo[n]
    
def even_fibonacci_sum_memo(limit: int) -> int:
    sum: int = 0
    n: int = 1
    while fibonacci_memo(n) < limit:
        if fibonacci_memo(n) % 2 == 0:
            sum += fibonacci_memo(n)
        n += 1
    return sum

print(even_fibonacci_sum_memo(4000000))

###　追記2 
ジェネレータ関数を用いた場合
(コメントいただきありがとうございます)

```Python: Python
from collections.abc import Iterator

def fibonacci(n: int) -> Iterator[int]:
    """フィボナッチ数列をイテレートする"""
    a, b = 1, 2
    while a < n:
        yield a
        a, b = b, a + b

def even_fibonacci_sum(limit: int) -> int:
    """偶数の値のフィボナッチ数のみ合計する"""
    return sum(n for n in fibonacci(limit) if n % 2 == 0)

print(even_fibonacci_sum(4000000))
```
PWAをAndroidのPlay Storeに公開するときにつまづいたこと

PWAはPlay Storeに公開することができます。そのための手順自体は「pwa play store」とかで検索すると結構出てきます。

今回は、そのなかでつまづいたポイントをまとめたいと思います。

##### 作ったものたち↓
PWA: https://lp.tuzuriba.com/
Play Storeに公開したアプリ: https://play.google.com/store/apps/details?id=com.tuzuriba.twa

## 起きた事象
アプリの審査で「ウェブ表示スパムやアフィリエイトスパムに関するポリシーへの違反」というようなメッセージを受け取りました。違反しているというポリシーの内容も、それを回避するための解決策も、この文面だとよくわかりませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2289954/04cd694c-35de-7ea3-8ed6-936e1efbce6e.png)

## 原因（と思われるもの）
webアプリの内容をただただ転写するだけのスマホアプリ（TWAアプリ）を公開する場合は、転写元のwebアプリの所有者の許可を得ていることを証明してね、ということぽいです。

メール文面に貼られていた↓のページを見て何となく察しました。
https://playacademy.exceedlms.com/student/activity/69563-webview

assetlinks.jsonをデプロイできている時点で所有しているようなもんじゃん、、とか思いましたが。

## 解決策
こちらもメールに記載の通り[Google Playアプリ審査チームへの事前通知フォーム](https://support.google.com/googleplay/android-developer/contact/adv_note)で、Androidアプリを公開しようとしている自分が転写元のPWAのドメインの所有者であることを証明できるような画像を送りました。

フォームで「知的財産を使用する権限の証明」を選択し、PWAのドメインを管理しているCloud Domainsの画面のスクショを送りました。

すると数時間後にメールが返ってきて、再度Play Consoleでリリースを作成したら審査に通りました。

## 所感
原因も解決策もメールに書いてあるじゃん、と思ったかもしれませんがその通りですw　ただメールの文面だけでは僕はあまり理解できず解釈に時間がかかったので、もし同じような方がいれば助けになれば幸いです。
【TypeScript】'xxxxxxx' is possibly 'null'

## はじめに
Typescript初学者です。
何度も遭遇するエラーだったのでまとめておきました。
調べてよかったです。

## 'xxxxxxx' is possibly 'null'.
### 現状
以下のところでエラーが出ました。
```js
titleRef.current.value = data.title; //'titleRef.current' is possibly 'null'
descriptionRef.current.value = data.description; //'descriptionRef.current' is possibly 'null'.
```
これは`titleRef.current`と`descriptionRef.current`のところでnullになるかもしれない。nullは想定してないよとTypeScriptが教えてくれている。


以下のようになっている。

```js
const editPage = ({ params }: { params: { id: number } }) => {
  const router = useRouter();
  const titleRef = useRef<HTMLInputElement | null>(null);
  const descriptionRef = useRef<HTMLTextAreaElement | null>(null);

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();

    toast.loading("編集中...........", { id: "1" });
    await editBlog(
      titleRef.current?.value,
      descriptionRef.current?.value,
      params.id
    );

    toast.success("編集に成功しました！", { id: "1" });

    router.push("/");
    router.refresh();
  };

  useEffect(() => {
    getBlogById(params.id)
      .then((data) => {
        console.log(data);
        titleRef.current.value = data.title;
        descriptionRef.current.value = data.description;
      })
      .catch((err) => {
        toast.error("エラーが発生しました。", { id: "1" });
      });
  }, []);
```

### 解決策
**パターンの１**
```js
titleRef.current!.value = data.title;
descriptionRef.current!.value = data.description;
```
`!`は後で必ず`titleRef.current`に入ってくるよという意味

**パターン２**
```js
if (titleRef.current && descriptionRef.current) {
  titleRef.current.value = data.title;
  descriptionRef.current.value = data.description;
}
```
`if`文を使い対応する。こっちの方が直感的で見やすい印象

## おわりに
自分のアウトプットのための投稿になるので他の方に役立たないかもしれません。
間違っておりましたら教えていただきたいです。
Azure VM (マネージドディスク) のスナップショットをとる

こんにちは、アーキテクトのやまぱんです。
補足コメントや質問は是非お願いします🥺！
間違ってたら優しく教えてください！

Azure VM を複製する際や、なんらかの構成変更を加える前にAzure VM のスナップショット(マネージドディスクのスナップショット) を取ることがあると思います。
または人によっては「失敗したーーとっておけばよかったーー！ VM 作り直しや！」となったこともあるかと思います。

今回は簡単に手順を紹介します。


## 対象の VM
こんなAzure VM があるとします。

![2023-12-27_15h19_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/37389931-871e-680e-2f6a-22c8cf3baa4f.png)

## Azure VM を停止します
スナップショットの取得自体はAzure VM 稼働中でも可能ですが、整合性の観点からなるべく停止してから取得するようにするのがよいです。

必ず Azure Portal から停止します。
![2023-12-27_15h19_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/6509b84e-f39c-d517-bca0-74d3409eb15c.png)

停止済(割り当て解除) になっていることを確認します。
![2023-12-27_15h23_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/35fea5cc-ad9b-e0c6-468d-2701d904e8e3.png)


今回取得するマネージドディスクのスナップショットは ”クラッシュ整合性” になります。
簡単に言えばOSの状態を一切考慮せずディスクの断面を取得するものになります。
そのため正常に電源を落とした状態で取得するのが望ましいです。

クラッシュ整合性に関しての詳細は下記も併せてご覧ください。

https://jpabrs-scem.github.io/blog/AzureVMBackup/Consistencies/#3

:::note warn
ディスクのスナップショットを取るときには、極力 Azure VM を停止する
:::

## ディスクの確認
Azure VM の左ペインの「ディスク」からAzure VM にアタッチされているディスクを確認します。
今回はデータディスクなし、OS ディスクのみアタッチされている構成です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/a6dbe824-aa1c-5602-72f0-7430da63afdb.png)

該当のディスクをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/2f58bee3-a419-4e9b-4429-344a44815b86.png)

## スナップショットの取得
名前や、フルか増分か、フルの場合はストレージの種類も指定して取得いただければと思います。

![2023-12-27_15h31_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/b7f70479-ad39-b75f-92a8-98443d411502.png)

なお、ストレージの種類に関してスナップショットに対してストレージ性能が必要になることはほとんどないと思うので、ほとんどの場合ではコスト節約のため Standard HDD でよいかと思います。

## 作成されたスナップショットを確認する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/857e6010-077b-1ab7-c4cd-d3ba451137c4.png)

下記のように確認することが可能です。 フルか増分かもこちらから確認することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/e91c587e-3b1f-ce1f-13a8-9a4e8ccc1fb9.png)


![2023-12-27_15h36_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982508/7ab57801-13a3-71fa-130c-011ec677ced5.png)
【nl2br】Laravel Bladeテンプレートで改行を表示する方法

## 環境
- macOS Ventura 13.6
- PHP(8.1.27)
- Laravel(9.43.0)
- Node.js(18.17.1)
- Visual Studio Code

## コード
bladeテンプレート内で以下のコードを入力すると改行が出力されます。
(ユーザーが送信した情報をvalueという変数で受け取り、textというデータを取得することにします。)
```
{!! nl2br(e($value->text)) !!}
``` 

## 解説

### e関数
`<,>,&` などの特殊文字列を安全なエンティに変換するための関数です。
今回の場合
```
{!! nl2br($value->text) !!}
```
でも動きますが、セキュリティリスクの観点から記述する必要があります。

### nl2br関数
PHP標準の関数で、改行文字`\n`を改行タグ`<br>`に変換するための関数です。

### {{ !! !! }}
Bladeテンプレートの記法でHTMLをエスケープせず、そのまま出力することができます。
CorvusSKK + AZIK 設定の覚え書き

個人用のメモです。
あまり参考にはしづらいかもしれません。

# install CorvusSKK
https://zenn.dev/toriwasa/articles/327d11c45a62e8

# setting AZIK kanaTable
config.xml を%APPDATA%\Roaming\CorvusSKK に置く
元となるファイルは corvusskk_version.zip の中の
 installer/config-sample/ に config - azik-uskbd.xml というファイルがあるため
 リネームして置くだけでよい

# special setting
そこまで特殊な設定はないはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079193/c7685c3d-8903-7bc8-dae7-e5c03a607540.png)

SKK前提なので、カナ変換が<C-q>となっているところくらいでしょうか。

随時追記していきます。
【Servicenow】Utahに関する機能紹介（Next Experience）

## はじめに
Next ExperienceにおけるUtahで追加された機能について、以下3点の調査を実施しました。
①カスタマイズ通知の作成
②レコードに関するフォロー機能
③Workspaceの履歴表示追加

https://docs.servicenow.com/bundle/utah-tokyo-df3/page/release-notes/rn-combined/utah-tokyo/utah-tokyo-nextexperience-release-notes.html

## カスタマイズ通知の作成
【概要】
Next Experience内でカスタマイズ通知を作成することができるようになりました。

【手順】
①ナビゲータからSystem Notification > Provider > Notificationsに移動し、Newを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471813/003c6c85-e954-c02a-c26c-f769ad9bc013.png)
②フィールドに必要事項を入力し保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471813/668507fc-2a96-a4bb-c710-d1c7829d61ad.png)
③Contentsを選択し、New Provider Contentを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471813/945f6b99-a8c0-78f9-01c1-46ffc90d6bfe.png)
④通知コンテンツの作成タイプを選択します。※今回はNext Experienceを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471813/0c68031e-76cf-e0ba-c86d-928ff68a8d22.png)
⑤フィールドに必要事項を入力し保存します。
やメッセージの見出しと本文にはSelect variablesからメッセージ本文を含める変数を選択できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471813/45a6a345-5941-c2ce-2473-558e8c6a30e2.png)

通知の表示例（画面右上に表示）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471813/4f4c419c-f18f-0585-b066-b1579209497b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471813/3d494073-9c69-ffa5-69fe-0ed7393af5dd.png)



※詳細は下記ドキュメントを参照してください。

https://docs.servicenow.com/bundle/utah-platform-administration/page/administer/navigation-and-ui/task/create-custom-notifications-next-experience.html

## レコードに関するフォロー機能
【概要】
Utahより各レコードに対するフォロー機能が追加されました。
レコードをフォローすることで作業メモやコメントが追加された際に通知を受け取ることが可能になりました。

Tokyo
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471813/2eeb1546-8d9a-b1fa-f855-f21f7a7e7901.png)

Utah（赤枠部分を選択することでフォローが可能）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471813/d1f550f5-dee7-1166-bb69-015f12613344.png)

通知の例(画面右上に表示)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471813/4f4c419c-f18f-0585-b066-b1579209497b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471813/3dc49a1b-9dec-79aa-22f4-510e791b91a8.png)

## Workspaceの履歴表示追加
【概要】
Utahよりヘッダーメニューに表示されているWorkspaceにアクセスすると、History にその情報が追加されるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3471813/619e578b-a5f7-f397-a1ec-efde70752783.png)

## おわりに
本稿では小ネタにはなりましたが、Next ExperienceにおけるUtahで追加された機能の概要と使い方について紹介しました。
Javaの基本データ型と文字列操作（Java Silver勉強）

# 最初に
この記事は、以下の書籍を通じてJava silverの合格に向けて自分が学んだ内容を体系的にアウトプットする記事である。（目指せ年内合格！）
[徹底攻略Java SE 11 Silver問題集[1Z0-815]対応](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5Java-SE-11-Silver%E5%95%8F%E9%A1%8C%E9%9B%86-1Z0-815/dp/4295007625/ref=asc_df_4295007625/?tag=jpgo-22&linkCode=df0&hvadid=342700130622&hvpos=&hvnetw=g&hvrand=9715255718806805548&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009303&hvtargid=pla-830348236008&psc=1&mcid=e12ce628cc5a33b29a77da3a85a6cdf0&th=1&psc=1
)

# 勉強記録
## 2章　Javaの基本データ型と文字列操作
### 整数リテラル
    - アンダースコア「_」を使って表現できる
        - 先頭と末尾、記号の前後は不可
    - 接頭辞で判断
        - 0→8進数
        - 0x→16進数
        - 0b→2進数
### char型
    - char型の変数に代入できるもの
        - ‘’で囲った文字リテラル
        - ‘’で囲った¥uから始まるunicode番号
        - 0~65535までの数値
    - nullは代入できない
        - nullは、参照型変数が何も参照しないことを表す
### 識別子
    - 変数などの名前のこと
    - 予約語は使えない
    - 使える記号は、アンダースコア「_」と通過記号のみ
    - 数字から始めてはいけない
### var
    - javaでの型推論での宣言に使用
    - 変数の方を推論できない場合は、コンパイルエラーとなる
    - ローカル変数の宣言にしか使えない（フィールドの宣言には使えない）
### immutableオブジェクト
    - 不変なオブジェクト
    - java.lang.Stringや、java.io.Fileのインスタンス
    - Stringのimmutableとは？
        - プログラムを動かすときはメモリの領域を使いながら処理している
        - メモリには、ヒープ領域とスタック領域がある
        - ヒープ領域は、アプリケーションの要求によって確保される領域
        - スタック領域は、一時的な記憶領域
            - https://hidemaru.blog/immutable-java/
            - 参照型変数をメソッド引数に渡すときなど注意
                - https://qiita.com/dung717/items/6552005a4fdccc893c43
### indexOfとcharAtの、引数で指定した文字等がない場合の違い
        - indexOf：-1が戻される
        - charAt： StringIndexOutofBoundsExceptionが投げられる
### 文字列の連結
        - メソッド
            - concatは、String
            - appendは、StringBuilder
        - 参照を持たないString型変数に対し、+や+=で連携するとき、nullは、「null」という文字列に置き換わる
        - StringBuilder
            - 保持している文字列+余分のバッファ（デフォルトで16文字分）を持つ

# 感想
- 1年くらいsaas系の新規プロダクト開発に携わった経験でしか語れないが、Javaでvarを使った記憶・使われているのを見た記憶がない。（バグの温床になりうるのであまり使わないのかな？）
- 同様に、整数リテラルを「_」で表現したりした記憶もない。（こっちは、プログラムでそんな大きい数値を定義する場面がなかっただけ？）
- メソッド等は、読めはするがうろ覚えでその都度なんだったけ？とたまに調べたりしていたので、この機会にこのレベルは覚えとかないと（世界一流エンジニアの牛尾さんもいつでも取り出し可能な知識をどれだけ持てるかが生産性に寄与するって言っていたし）と感じた。
- Javaのスタック領域とヒープ領域の部分は恥ずかしい話、Stringが参照型でimmutableである。くらいの理解だったので、この機会に少し理解を深められて良かった。
- （特に以下の記事の例題を解きながら自分の理解の浅さを痛感。）https://qiita.com/dung717/items/6552005a4fdccc893c43
kaminari で データ件数が膨大（1000万件）の際の高速化案。検索してください。

# kaminari は データ数の count 処理を実行している
最大ページ数を調べ、表示 or リンクを作るために
全データが何件あるのか count してしまいます。


1000万件など膨大なデータがある場合には count 処理が重くなり time out も発生します。

## ページネーションで10ページも移動して目視で探す人は...
手動で10ページも移動して目視で探すのは非効率なので
10ページ目まではページネーションを作るが
それ以降は検索してくださいというスタンスで高速化できます。


## 実際のコード

```erb.slim
  = paginate @pv_logs, total_pages: 10
  p ※ PV情報はデータが膨大なため、最大10ページまで移動できます、それ以上のページに移動する場合は検索条件を絞り込んでください。
```
EC2　3つのインスタンスタイプについて(オンデマンド・リザーブド・スポット)

こんにちは、開発部のCLです。  

EC2の3つの購入方式について、紹介します。
システムに適したタイプを選ぶことで、費用が70~90%抑えられます。  

ぜひ参考にしてみてください。

# オンデマンドインスタンス
概要:
デフォルトの購入方式。
一般的に使用する分にはこちらで問題ないです。  

ただ、費用が高くなりがちなので次に紹介する、
リザーブド/スポット インスタンスといった、
お財布に優しいプランを検討してみてはいかがでしょうか。


:::note info
メリット
起動・停止などライフサイクルを完全制御できるため、柔軟性が高い。
:::

:::note alert
デメリット
秒単位で料金が発生するため、他のプランに比べると料金が高くなる。
:::


用途例:
・開発やテスト用のサーバーとして利用する。
　(使用しない時間帯は停止して、費用を浮かせる)  

・短期間、突発的、または予測不能なワークロードがあり、中断できないシステム。  





# リザーブドインスタンス
概要:
1年、または3年の利用期間を予約利用をする方式。
前払いすれば、割引率UPですが、初期費用が発生します。  

ジムに通うにしても、前払い・長期プランの方がお得になりますよね。
そんな感じで安くしてくれます。

:::note info
メリット
オンデマンドより比較的安価で購入できる(最大約75%割引)
:::

:::note alert
デメリット
短期間の利用はできない。
:::

用途例:
長期の稼働が決定している本番環境。

# スポットインスタンス

概要:
AWS上で稼働していないインスタンスを間借りできます。  

居候的な感じです。居候なので、AWSの都合で追い出される(サービスが中断される)
こともあります。

:::note info
メリット
オンデマンド料金の最大90%割引で活用可能。
:::

:::note alert
デメリット
AWS上に空きがなければ使用できない。また、中断される可能性がある。
:::


用途例:
動画変換/機械分析など短時間でリカバリーが可能なシステムに使用。
「短時間だけちょっと貸して」って時に使うと良い。

# 最後に
ざっくりと3つの購入方式について、書き出してみました。
今後、それぞれのタイプについても深掘りしていこうと思います。

はつかぜ株式会社では、IT学習や業務に役立つ情報を定期的にお届けしていきたいと思っています。
システム開発のお問い合わせ・ご相談はこちら
https://www.hatsukaze.co.jp/inquire/
【Laravel】partitionメソッドで配列を分割しよう

## 概要

知らなかったメソッドがあったので紹介
以下のように、条件を満たしている物が格納されている配列と、条件を満たしていない物が格納されている2つの配列が生成されっます

```php:例
$collection = collect([1, 2, 3, 4, 5, 6]);

[$underThree, $equalOrAboveThree] = $collection->partition(function ($i) {
    return $i < 3;
});

$underThree->all();

// [1, 2]

$equalOrAboveThree->all();

// [3, 4, 5, 6
```

## まとめ

自分は今までwhereなど使って冗長に書いてたので使っていこうと思います
SQLが避けられる背景とSQLの重要性

SQLの難しさと重要性についてのメモ。

## SQLが好きな言語という人が少ない

Twitter上でのエンジニアの投稿をみているとSQLが嫌いという人をみかける。おそらくは「やらされるから」だとは思う。SQLの苦手意識がどのように芽生えるのかを考察してみた。

### プログラミングコンテンストでSQLは登場しない

多くののプログラミング言語は、標準入力から値を受け取って処理をして標準出力に出すという形式でテストができるが、SQLはそうはいかない。学習インフラが整ってないというのがつらい。そもそもプログラマーからみてもSQLをプログラミング言語と呼ぶべきかどうかは迷う。

### 単体テストしづらい

SQLには引数と戻り値の束を使った単体テストという概念がない。

### データ量に応じて探索アルゴリズムが変わる

- テストとうよりももはや実験
- テストデータ作成の腕前が超大事
- スキルと言うより場数

### メモリの中でテストができない

必ずストレージが必要。関数型原理主義の「副作用を避けよう」というパラダイムの中では真逆のアプローチ。副作用を避けたいというのはエンジニアの都合であって、ユーザは「ちゃんとデータを残しなさいよ」というのが本音。だからいつまで経ってもエンジニアは「素人はわかってない」と社会を逆恨みする。社会は副作用だらけだ。

### データを切り離してフロントエンドの開発ができる時代でもある

php+mysql でエンジニアリングをしていた時代に比べると、graphQLなどの出現でSQLを触らずにフロントエンドが開発できるようになってきた。

### 進化が少ないためベテランを追い越すのが難しい

SQL自体の進化がすごく遅い。構文がシンプルで実際には「これくらいのデータ量になるとフルスキャンの遅さが目立つ」や「これくらいのデータの散りっぷりがないとインデックスが効率よく使われない」などの場数が大事になってくる。経験がものを言う世界だと実質年功序列な世界でもあるため、「頑張って勉強して追い越す」のが難しい。

## 以上すべてのデメリットは「参入障壁」として強い

- ベテランになる意味がある
- テストではなく実験が大事なので習熟が必要で自動化が難しい
- 作ったデータを眺めるのは「保守」として毛嫌いされている
- プログラミング言語の寿命よりもデータの寿命の方が遥かに長い
ToFカメラについての重箱の隅

さきに、[市販ＴoＦカメラについて調査中(2023年版）](https://qiita.com/nonbiri15/items/5fdb9962bbdc76274d90)の記事を書いた。
それに関連して、重箱の隅のようなことを別途記載する。

ToF(Time of Flight)カメラで、容易に深度(depth)が測定できるようになってきているから、買ってきて接続すれば十分だろうと思う方も多いかもしれない。

しかし、そう簡単ではないことを記す。

## 940nm のToFカメラは、太陽直射光の下でも使える。
- 940nm を採用しているToFカメラも増えているので、それを用いれば屋外でも使える。
- 940nmを使うと、大気中の水蒸気の吸収によって、太陽光中の940nmの光が抑制されている。そのため照射した940nmの近赤外光の戻り値が埋もれにくい。

[新型ToFカメラ 屋外（太陽光下）での評価状況 第2段！](https://www.inrevium.com/pickup/outdoor_demo2/)


## 遠方での距離の算出が苦手
- 遠方からの戻り光が減衰しすぎると距離が算出できない。
- 中には30m先でもdepthが求まるToFカメラもあるので検索してみてほしい。（ただし高価）

## 黒くて光を吸収・散乱する対象物が苦手
- 顔が計測できていても、頭部の髪の毛が欠損値になることがある。
- 黒のズボンも、ズボンの染料の種類・布地の種類によっては、欠損値になってしまう。

## ToFの近距離側の算出距離の限界がある。
- 30 cmという近距離を必要とする使い方の場合には、各社の中でそれをサポートするToFカメラを探してほしい。
- この距離は、ToFのイメージセンサだけでは決まらない。
- その製品ごとに違ってくる。
- ステレオ計測の場合でも近距離側の限界があるので、別にToFに限ったことではない。

## 近赤外光を透過するガラスが苦手
- ガラスへの距離を算出できない。
- ガラスの先の対象物への距離を算出してしまう。

## 鏡も苦手
- 鏡に写っている対象物への距離を算出してしまう。

## 黒光りするものも苦手
- 通常の物体の場合と違った奥行き画像になってしまうことがある。

## 反射率の低い黒い物体は、奥行きの計算にも影響することがある。
[ToF特集【第8話】ToFカメラでこんな被写体、撮影してみました。](https://www.inrevium.com/pickup/tof_photo/)
の記事を読んでみてください。

### 3Dカメラ比較例
[3Dカメラ 8種類を 様々な環境で比較しました 【その① 屋外編】](https://www.tegakari.net/2020/09/3dcamera_compare_1/)
[3Dカメラ 8種類を 様々な環境で比較しました 【その② 屋内編】](https://www.tegakari.net/2020/09/3dcamera_compare_2/)

# ユーザーの取るべき手段
- 欠損値が生じたり、期待しない値になるような状況が、ユースケースでどう影響が出るのかを考慮すること。
- 超音波センサなど他のセンサの併用についても考慮すること。


## 関連記事
[超音波センサの使い方について調査中](https://qiita.com/nonbiri15/items/9d6c962fe0e026a1b95f)

## 追記：　座標系の対応付け
RGBカメラとDepthカメラで、微妙に座標系が違っている場合には、以下の記事にあるようにDepth画像でRegstrartion(画素の対応付け）を行うとよい。

qiita [ROSのカメラ画像処理に関するメモ](https://qiita.com/ledmonster/items/0278fbdfe90755b94d32)
【AWS】Amazon Linux 2023 DockerのPythonバージョンアップ

# はじめに

　Amazon Linux 2023 をベースとした Docker イメージ作成時に Python バージョンアップを行うための Dockerfile について書きます。
　Python バージョンアップ方法はこちらを参考にしました。

 https://note.com/yuu________/n/nbe90710b842b

# Dockerfileの書き方

まず、Amazon Linux 2023 の Docker コンテナの Python バージョンを確認します。 `3.9.16` となっています。

```
[ec2-user@ip-172-31-13-197 ~]$ docker run -it amazonlinux:2023 /bin/bash
bash-5.2# python3 --version
Python 3.9.16
bash-5.2# python --version
bash: python: command not found
```

次に、以下の Dockerfile を作成します。Python は `3.11.0` をインストールします。

```Dockerfile
FROM amazonlinux:2023

# 必要なパッケージをインストール
RUN dnf install -y git tar gcc \
                   zlib-devel bzip2-devel readline-devel \
                   sqlite sqlite-devel openssl-devel \
                   tk-devel libffi-devel xz-devel

# pyenv により、使用する Python バージョンをインストールする
RUN curl https://pyenv.run | bash && \
    echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc && \
    echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc && \
    echo 'eval "$(pyenv init -)"' >> ~/.bashrc && \
    source ~/.bashrc && \
    pyenv install 3.11.0 && \
    pyenv global 3.11.0
```

コンテナを作成し、Python バージョンを確認します。

```
[ec2-user@ip-172-31-13-197 ~]$ docker build -t demo .
[ec2-user@ip-172-31-13-197 ~]$ docker run -it demo /bin/bash
bash-5.2# python3 --version
Python 3.11.0
bash-5.2# python --version
Python 3.11.0
```

### Pythonライブラリインストール

　イメージ作成時に Python のライブラリをインストールする方法について書きます。
 
　新たにファイルを作成します。

```requirements.txt
numpy==1.26.2
PyYaml==6.0.1
```

　Dockerfileを次のように修正します。

```diff
FROM amazonlinux:2023

+ COPY ./requirements.txt ./

# 必要なパッケージをインストール
RUN dnf install -y git tar gcc \
                   zlib-devel bzip2-devel readline-devel \
                   sqlite sqlite-devel openssl-devel \
                   tk-devel libffi-devel xz-devel

# pyenv により、使用する Python バージョンをインストールする
RUN curl https://pyenv.run | bash && \
    echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc && \
    echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc && \
    echo 'eval "$(pyenv init -)"' >> ~/.bashrc && \
    source ~/.bashrc && \
    pyenv install 3.11.0 && \
    pyenv global 3.11.0

+ # Pythonライブラリインストール
+ RUN /root/.pyenv/shims/pip install --no-cache-dir -r ./requirements.txt
```

# 参考記事

https://note.com/yuu________/n/nbe90710b842b

https://github.com/pyenv/pyenv
ESXiからProxmoxにWindows10を移行してみた

ESXi上で動いているWindows10をProxmox VEに移行（V2V）してみました。
その時の手順メモです。

# ポイント
- 事前にVMWare Toolsはアンインストールしてから移行しないと、にっちもさっちもいかなくなる。
- vmdkはvmkfstoolsコマンドを使わないとコピーに失敗する。（cpやrsyncなどではダメ）
そのためにNFSサーバをProxmoxVE上に立てて、ESXiでマウントする。

# 作業手順
1. ESXi上でWindowsを起動し、VMware Toolsをアンインストールする。
VMware Toolsをインストールしたまま移行すると、動作がとても重くなりProxmox側ではアンインストールも簡単にできなくなる。
1. アンインストール後、再起動した後に仮想マシンを停止する。
1. 仮想HDDをProxmoxVEに移動する。
    1. ProxmoxVE上でNFSサーバを構築
        1. nfs-kernel-serverパッケージのインストール
            ```
            # apt-get install nfs-kernel-server
            ```
        1. exportsファイルの編集
            ```
            # vi /etc/exports
            /zfspool/nfs 192.168.0.100(rw,sync,no_all_squash,no_root_squash,no_subtree_check)
            ```
        1. サービス再起動
            ```
            # systemctl restart nfs-kernel-server.service
            ```
    1. ESXiにProxmoxVEのNFSをデータストアとして追加する。
    1. ESXiにSSHログインし、`vmkfstools`コマンドでProxmoxVEのNFSに仮想HDDをコピーする。
          ```
          [root@ESXi:~] vmkfstools -i /vmfs/volumes/datastore_ssd/WINDOWS10/WINDOWS10.vmdk /vmfs/volumes/proxmox/WINDOWS10.vmdk
          ```
1. ProxmoxVEにWindows用の仮想マシンを作成する。
    - 全般：
      - VM ID：任意
      - 名前：任意
    - OS：
      - ●メディアを使用しない
      - ゲストOS：
        - 種別：Microsoft Windows
        - バージョン：11/2022
      - システム：
        - グラフィックカード：既定
        - マシン：q35
        - SCSIコントローラ：VirtIO SCSI single
        - Qemuエージェント：☑チェックを付ける
        - BIOS：OVMF（UEFI）
        - EFIディスク追加：☑チェックを付ける
        - EFI Storage：任意のストレージを選択
        - TPM追加：☑チェックを付ける
        - TPMストレージ：任意のストレージを選択
        - バージョン：2.0
      - ディスク：後で追加するので、ディスクは無し（デフォルトのide0を削除）で進める。
      - CPU：
        - ソケット：リソースに合わせて設定（今回は2ソケット）
        - コア：リソースに合わせて設定（今回は4コア）
        - 種別：qemu64 または host（Windows11にする際にはホストのCPUがサポート対象の必要あり）
        - その他：デフォルト
      - メモリ：リソースに合わせて設定（今回は12288MBで進めた）
      - ネットワーク：環境に合わせて設定、モデルは`Intel E1000`を選択
1. `qm disk import`コマンドで仮想HDDをインポートする。
    ```
    # qm disk import 100 /zfspool/nfs/WINDOWS10.vmdk zfspool
    ```
1. 仮想マシンのハードウェア設定で、仮想HDDが未使用のディスクとして認識しているので、バス/デバイスの設定を`SATA`として追加する。
1. 仮想マシンのオプション設定で、ブート順を`sata0`から起動するように設定する。
1. 仮想マシンを起動し、`virtio-win.iso`をCD-ROMにセットして、中にある`virtio-win-gt-x64.msi`からドライバーをインストールする。
1. 同じくCD-ROM内にある`virtio-win-guest-tools.exe`からエージェントをインストールする。
1. NICが別物として認識しているので、ネットワーク設定を行う。（移行前と同じIPの場合、古いNICの設定を削除する警告が出るがそのまま進めてOK）
1. 移行完了。

# 参考情報
- virtio-win.iso(virtioのWindows用ドライバ)のダウンロード先：
https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/

- Windows 10 guest best practices (Proxmox wiki)
https://pve.proxmox.com/wiki/Windows_10_guest_best_practices
Rails パラメータを直接使って四則演算する際の注意点と解決策

※この記事は僕がぶち当たった問題をとりあえずChatGPTくんに丸投げしてライティングしてもらったものです。

# はじめに
Railsアプリケーションを開発する際に、パラメータの処理は非常に重要です。
しかし、パラメータはデフォルトで文字列として扱われるため、予期せぬ結果が生じることがあります。
本記事では、その中でも掛け算の処理に焦点を当て、問題の理解と解決策について説明します。

# パラメータの文字列扱いによる問題
Railsでは、リクエストパラメータはデフォルトで文字列として扱われます。例えば、以下のようなコントローラアクションがあるとします。

```ruby
# app/controllers/products_controller.rb

class ProductsController < ApplicationController
  def calculate_price
    price = params[:price]
    result = price * 5
    render json: { result: result }
  end
end
```

このコードでは、リクエストで送信されたparams[:price]を5倍にしてresultに代入しています。しかし、これには問題があります。

## 問題の原因
params[:price]が文字列であるため、掛け算を行うと文字列の連結が行われ、期待した結果が得られません。
たとえば、params[:price]が"10"だった場合、"10" * 5は"1010101010"となり、意図しない結果となります。

## 解決策
この問題を回避するためには、params[:price]を適切な型に変換する必要があります。
具体的には、整数型に変換することで文字列の掛け算問題を回避できます。

```ruby
# app/controllers/products_controller.rb

class ProductsController < ApplicationController
  def calculate_price
    price = params[:price].to_i
    result = price * 5
    render json: { result: result }
  end
end
```

こうすることで、params[:price]が文字列であっても整数に変換され、掛け算が正しく行われます。

## まとめ
Railsでのパラメータ処理において、文字列として扱われることに注意が必要です。
特に数値演算などの操作を行う際には、適切な型に変換してから処理を行うことで、予期せぬバグを回避できます。
是非、開発の際にはこのポイントを意識してください。
colud run + cloud sql + prisma + postgresql でデプロイ時のエラー

colud run + cloud sql + prisma

### 気をつけること①
コネクションストリング（特にパスワード）の
パーセントエンコードをすること

https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding

### 気をつけること②
環境変数のDATABASE_URL の設定は

```
postgres://postgres:<password>@localhost/postgres?host=/cloudsql/<connection-string>
```

の形にして、`<connection-string>` は

![Screenshot 2023-12-27 at 13.45.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1840635/732fef21-44ed-05f4-b51e-8d552ca25947.png)

ここから取得すること。
Tailwind CSS メモ

## Tailwind CSS について

以前に参加したプロジェクトで使用していた。
CSSファイルに記述せずひとまとめにするため見栄えは悪くなる。
しかし、変数名を何にするか考えたり記述内容を確認するためにファイルを移動したりする手間がなくなるので、メリットは大きい。
というか、普通に表示が綺麗だし見やすい。

## やりたいこと
- あえてユーザーに情報を与えない表現をしてみたい
- 例えば、情報がぼやけていて見えない
- 文言や情報の内容が曖昧でクリアではない

## 具体例

##### ぼかし
- `blur-sm`（4px相当）や `blur-{amount?}`と記述すると、モザイクのようにぼやけて見えなくなる
- ぼかした要素を囲んでいるタグにclassを当てるだけ
- divタグで囲んでまとめてぼかすこともできる
※ Blur効果はレンダリングに時間を必要とするため、大量に使いすぎるとウェブサイトのパフォーマンスに影響を与える可能性があるらしい。

## 参考

https://tailwindcss.com/docs/blur

https://blog.to-ko-s.com/tailwind-blur/
mac の初期設定をbashに戻す @yukilulu0229

## macを新しい買い替えたときにzshからbashに戻す

### コマンド

```
$ chsh -s /bin/bash
$ echo $SHELL
```

参考 https://qiita.com/___fff_/items/c9a30e78196998f4160c
@___fff_

## 毎回表示されるメッセージを消す

```
The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
For more details, please visit https://support.apple.com/kb/HT208050.
```

```
echo "export BASH_SILENCE_DEPRECATION_WARNING=1" >> .bash_profile
```

参考: https://qiita.com/waka424/items/bc77b6e8bd4f25760e58
@waka424

## プロンプトをわかりやすくする

### 旧表示
```
YukinoMac-mini:~ yuki$
```

### コマンド

```
vi .bash_proflile
```


```.bash_profile
export  PS1="\t  \W : "
```