OmniAICreator/Qiita-1.07M huggingface dataset:
Liberty と ActiveMQ Artemisで JMSを構成する （備忘録）

# はじめに

Liberty と Active MQ Artemis で JMS構成をするのに苦労したところを同じことを調べなくて良いように残しておきます。

以下のページを更新します。

https://qiita.com/keniooi/items/f72a7a6d6d2e7c2871dd

# ActiveMQ Artemisを起動

https://www.mastertheboss.com/jboss-frameworks/activemq/how-to-run-artemis-mq-as-docker-image/#google_vignette

を元にArtemis MQを起動します。

```
docker run --rm -e AMQ_USER=admin -e AMQ_PASSWORD=admin -p 61616:61616 --name artemis quay.io/artemiscloud/activemq-artemis-broker
```


# 最新のResource Adapterを使う

Java8で動かそうと古いResource Adapterで試していましたが、なかなか動いてくれませんでした。Javaを新しいものに変えることでResource Adapterも新しいものが使えるので、うまくいかないときは修正が含まれる最新をためすのが良いです。

https://repo1.maven.org/maven2/org/apache/activemq/examples/modules/artemis-rar/2.31.2/

2024/2/29 現在 2.31.2 でした。


# Libertyの server.xml を更新

もともとあった構成はActiveMQのものでこれを元に更新します。

https://github.com/pdprof/jms/blob/master/jms-docker/config/server.xml.jms-amq#L14

変更点
- resource adapter の id を artemis に変更 >> properties の後の指定も変わる
    - 実装にあわせたプロパティ名を使えるのでプロパティも変わる
- rar を /tmp/artemis-rar-2.31.2.rar に配置して、それを読むように変える
- jmsQueueConnectionFactory を connectionFactory に変える
    - brokerUrlが設定できなくなるので消す

使用できるプロパティは以下を参考にします。

https://activemq.apache.org/components/artemis/documentation/latest/resource-adapter.html

```xml
<server>
    <featureManager>
	<feature>ejb-3.2</feature>
	<feature>localConnector-1.0</feature>
	<feature>servlet-4.0</feature>
	<feature>jsp-2.3</feature>
    <feature>wasJmsClient-2.0</feature>
    </featureManager>

	<httpEndpoint host="*" httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint">
	</httpEndpoint>
 
    <resourceAdapter id="artemis" location="/tmp/artemis-rar-2.31.2.rar">
        <properties.artemis connectionParameters="host=localhost;port=61616" />
    </resourceAdapter>
	
	<jmsActivationSpec id="jms/PdprofMdb">
		<properties.artemis destinationRef="Q3" destinationType="javax.jms.Queue"/>
	</jmsActivationSpec>
	
	<connectionFactory connectionManagerRef="ConMgr6" jndiName="QCF">
		<properties.artemis/>
	</connectionFactory>
	<connectionManager id="ConMgr6" maxPoolSize="5"/>

	<jmsQueue jndiName="Q1">
		<properties.artemis Address="Q1"/>
	</jmsQueue>

	<jmsQueue id="Q2" jndiName="Q2">
		<properties.artemis Address="Q2"/>
	</jmsQueue>

	<jmsQueue id="Q3" jndiName="Q3">
		<properties.artemis Address="Q3"/>
	</jmsQueue>

	<applicationMonitor updateTrigger="mbean"/>

	<webApplication id="jms" location="jms.war" name="jms"/>

   <logging  traceSpecification="*=info"
      traceFileName="trace.log"
      maxFileSize="20"
      maxFiles="10"
      traceFormat="BASIC" />

</server>
```


# sendの時の commitを追加

ここまででサンプルアプリケーションの send がエラーなく動作するようになるのですが、なぜかキューにメッセージがPUTできない。アプリケーションのコードで commmit を追加してやることでうまく動作します。他のResource Adapterだといらなかったのになぜというところだけど、ひとまず動くことを確認してからあるべき動作を確認していきます。

QueueSession.commit() を QueueSender.send(...) の後に入れることで動くようになりました。


# まとめ

同じような苦労をしないように、今回知る事のできた内容をまとめました。
AWSコンソールからEC2にSSH接続する

前回に引き続きSSH関連で。

EC2の一覧で画面上部に接続ボタンがありました。
ここからブラウザでSSH接続できるんだなーと思っていましたがうまくいかず・・・
どうやらセキュリティグループの許可が必要だったようです。

![スクリーンショット 2024-02-29 22.50.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237714/1dc532ea-e618-616d-a9f4-71369c92e0f7.png)

許可はSSH接続するリージョンで利用されているIPアドレスの範囲を許可すればよさそうです。
使用される[AWS IP アドレスの範囲](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/aws-ip-ranges.html)は[こちら](https://ip-ranges.amazonaws.com/ip-ranges.json)から確認できます。

このJsonの中で `service` が `EC2_INSTANCE_CONNECT` になっているもののうち、 `region` が `ap-northeast-1` の `ip_prefix` から接続を許可しました。
設定時点では `3.112.23.0/29` を設定しています。

EC2メニューのセキュリティグループから新しいセキュリティグループを作成して、インバウンドルールに以下を設定します。

|key|val|
|--|--|
|タイプ|SSH|
|ソース|カスタム|
||3.112.23.0/29|
|説明|(よしなに) instance connect from ap-northest-1|

EC2インスタンスにセキュリティグループを付与したら接続してみましょう

1. EC2インスタンス一覧
1. 接続ボタン
1. `EC2 Instance Connect` タブ
1. `接続タイプ` は `EC2 Instance Connect を使用して接続する`
1. `ユーザー名` は AmazonLinux の場合は `ec2-user`
1. 接続！！

ちなみに、キーペアなしでも接続可能です。
ファイルの送受信をしたいときはS3経由が手軽かな？
磁場中での電荷の運動

# はじめに
磁場中での電荷の運動は一般的に円運動もしくはらせん運動になることが知られている。円運動になる理由は、ローレンツ力が向心力としてはたらくためである。一方、古典力学において初期条件さえ与えられれば、加速度$a$から速度$v$と変位$x$は求められる。そこで今回は、微小変化する区間では加速度一定の等加速度運動をすると仮定して、運動方程式を立てて、そこから速度と位置を導出することによって、磁場中の電荷がらせん運動をすることを観察することを目的とする。
# 向心力
向心力としてのローレンツ力は磁束密度$\textbf{B}$と速度$\textbf{v}$が与えられていた場合、以下のように表すことができる。

```math
\textbf{F}=q\textbf{v}\times\textbf{B}
```
これが、向心力となるので、初速度$v$、半径$r$とすると

```math
m \frac{v^2}{r}=qvB
```

```math
r=\frac{mv}{qB}
```

と表すことができる。

# 速度と変位
微小区間($t=t$から$t=t+\Delta t$)に粒子の加速度$\textbf{a}$が与えられたとき
速度と変位は以下のように表すことができる。これは、微分の定義から来ている。

```math
\textbf{v}(t+\Delta t)=\textbf{v}(t)+\textbf{a}(t)\Delta t
```

```math
\textbf{x}(t+\Delta t)=\textbf{x}(t)+\textbf{v}(t)\Delta t
```
これを$t=0$から$t=t$まで加算することで$t=t$での位置$\textbf{x}(t)$を求めることができる。

# プログラム
これをもとにして、プログラムを考えると以下のようになる。
```python rasen.py
import numpy as np
import matplotlib.pyplot as plt

#パラメータ
B=np.array([0,0,1])
q=1.0
m=1.0
#初期条件 (x,v,a)=(位置,速度,加速度)
x=np.array([1,0,0])
#斜め上に発射
v=np.array([0,1,1])

a=np.array([-1,0,0])

#3次元のグラフ（散布図）を描くための設定
fig = plt.figure()
ax = fig.add_subplot(projection='3d')

#初期時間
t=0
#微小時間の時間間隔(小さくするほど精度は上がるが計算時間が比例して増大する)
delta_t=0.01
while(t<10):
    #速度の微小変化
    v=v+a*delta_t
    #位置の微小変化
    x=x+v*delta_t
    #ローレンツ力によって生じる加速度,cross(v,B)はvとBの外積である
    a=-(q/m)*np.cross(v, B)

    #時間の更新
    t=t+delta_t
    #print(x)
    #粒子の位置を記録
    ax.scatter(x[0], x[1], x[2], color='blue')
#グラフを保存する
plt.savefig("rasen.png")
#グラフの表示
plt.show()
```


これを実行すると以下のようになる。

![rasen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/4082099a-c1bc-146a-7196-7c2b7c7880a6.png)


うまく、描写することができていることが分かる。

# まとめ
今回は、プログラムを用いて、磁場に関して斜めに入射した場合の電荷の運動についてシミュレーションした。結果らせん運動をするということが分かった。これは、ローレンツ力から加速度を求め、それを積分することで速度と変位を求めて計算した。
DockerでReactとNext.jsを動かして「こんにちは世界」をする

## 概要
Docker上でReact（{バージョン}）とNejxJSを動かして、開発できる状態をつくる

## 準備
### Dockerのインストール
[こちらの記事を参照](https://qiita.com/noluba-dev/items/0ad6f2480e8b9da7321c)

### homebrewをインストール
[公式サイト](https://brew.sh/ja/)の「インストール」と書いてあるところのシェルコマンドを実行
※これで自動で入るはず。

### nodenv のインストール
下記コマンドを実行
```
brew install nodenv
```

## node 21.6.2をインストール
nodenvのインストールできるバージョンを確認
今回は`21.6.2`を入れるので、あるか確認
```
nodenv install --list
```

小ネタ：grepすると楽
```
nodenv install --list | grep 21.6
```
もしなければnodenvに関連するパッケージのnode-buildをアップデート
これに様々なnodeのバージョンのソース(？この表現が適切かは調べていないので間違っているかも)が入っている
```
brew upgrade node-build
```
インストールして設定nodeをインストールして使うnodeのバージョンを指定
```
nodenv install 21.6.2
nodenv local 21.6.2
node -v 
```

下記が出力されたOK
```
v21.6.2 
```

## React,Next.jsのプロジェクトを作成
１行のコマンドを打つだけ（超簡単！！）
```
npx create-next-app@latest clatomo-frontend
```
を叩くと以下のように聞かれるので、下記のように答えました。
```
✔ Would you like to use TypeScript? … No 
✔ Would you like to use ESLint? … Yes
✔ Would you like to use Tailwind CSS? … Yes
✔ Would you like to use `src/` directory? … Yes
✔ Would you like to use App Router? (recommended) … No
✔ Would you like to customize the default import alias (@/*)? … No 
```
Typescript はひとまず良いのでNo
ESLintは使いたいのでYes
Tailwind CSSは便利らしいのYes
srcディレクトリは作らないとプロジェクトのルート直下にディレクトリをつくることになるのでYes
まだAppRouterの記事が少なく、ハマりそうなのでNo
インポートエイリアスというもので、JSのインポート時に「@/」をデフォルトでルートとして使っているが、変更したいかと聞かれる。そのままでもわかりやすいのでNo

これでソースコードもがっつり生成される

## Docker関連の設定
作成したプロジェクト直下にDockerfileとdocker-compose.yamlを作成
```
cd clatomo-frontend
vi Dockerfile
```

```ruby:Dockerfile
FROM node:latest

# アプリケーションディレクトリを作成
WORKDIR /usr/src/app

# アプリケーションの依存関係をインストール
COPY package*.json ./
RUN npm install

# アプリケーションのソースコードをバンドルする
COPY . .

# アプリケーションがリッスンするポートを指定
EXPOSE 3000

# アプリケーションの実行
CMD ["npm", "run", "dev"]
```
```
vi docker-compose.yaml
```
```ruby:docker-compose.yaml
services:
  app:
    build:
      context: .
    tty: true
    volumes:
      - ./:/usr/src/app  # バインドマウント。


    environment:
      - WATCHPACK_POLLING=true
    command: sh -c "npm run dev"
    ports:
      - "3000:3000"
```

```
    volumes:
      - ./:/usr/src/app  # バインドマウント。
```
は、やらないとローカル上でソースを編集してもDocker上のソースが変更されないので、
ホットリロードが走らないです。
（最初ホットリロードがきかねぇってハマりました…）


```
docker-compose up
```
これでコンソールが下記の状態になったら、
![スクリーンショット 2024-02-29 22.44.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284596/7efa2ecc-37b5-24bb-d106-a25f58a5266e.png)


http://localhost:3000/
をブラウザで開く。
下記が表示されたOK。
![スクリーンショット 2024-02-29 22.45.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284596/d3bec49f-c15c-64cb-8b1d-1160767db3c9.png)

## こんにちは世界を表示

```
vi src/pages/index.js
```

36行目あたりに下記をいれるとファイルを保存するとホットリロードされて表示される

```ruby:src/pages/index.js
<h1>こんにちは世界</h1>
```
![スクリーンショット 2024-02-29 22.49.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/284596/4b93146b-f224-9960-790b-775f95a4caaf.png)
devcontainerを使用したtkinterの文字化け解消

# 事象
devcontainerを使用して構築したpythonのコンテナ上でtkinterを使用したが、
日本語表示が豆腐（☐）になってしまう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118317/fb55840d-1eb2-b16f-4adb-8463157903e8.png)

# 環境
Windows11 Home 23H2
vscode 1.85.1
devcontainer v0.327.0
wsl v0.81.8
Dockerイメージ python:3.11

# 原因
使用しているDockerイメージに日本語フォントが入っていない

# 対応
Dockerfileに以下を追加し、日本語フォントをインストールする

```
RUN apt-get install -y fonts-takao-gothic 
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118317/279e48e0-c628-cc1a-52dc-e6858fcb4aa3.png)
【Laravel】パラメータ付きのバリデーションルールでハマった

# 先に結論
Laravelのパラメータ付きのバリデーションルールを使う時には空白を含まないように注意する。

# 事象
Laravelで構築されたバックエンドシステムに実装されているAPIへのリクエストをバリデーションするために下記のルールを設定していた。
```php
'item_id' => 'int',
'name' => 'required_without:item_id | string'
```
「IDが指定されていない場合、nameは必須で文字列である」という意味のルールになっている。

これに対して下記のリクエストを投げた。
```json
{
  "item_id" => 100
}
```
idが指定され、nameが任意項目になったはずなので、これは通るはずなのだがなぜかrequired_withoutエラーになってしまう。

# 推測と調査
required_withoutのパラメータで指定されている「item_id」が正しく認識されておらず、存在しないと勘違いしているのでは？と考えた。

そこで、required_withoutの本体であるIlluminate\Validation\Concerns\ValidatesAttributesのvalidateRequiredWithoutメソッドで$parametersを出力してみることにした。

```php
public function validateRequiredWithout($attribute, $value, $parameters)
{
    var_dump( $parameters);

    if ($this->anyFailingRequired($parameters)) {
        return $this->validateRequired($attribute, $value);
    }

    return true;
}
```

すると、下記の結果になった。
```
array(1) {
  [0]=>
  string(9) "item_id "
}
```

"item_id "と最後に空白文字が一文字入っていることがわかった。
どうやらこのせいで項目が認識できていないようだ。

そこで、下記のようにルールを書き換えた。
```php
'item_id' => 'int',
'name' => 'required_without:item_id|string'
```
パイプの前後の空白文字を消してみた。
これで同じリクエストをしたところ、正常にリクエストが通った。

# 結論
パラメータは空白を含んで認識されるので、空白を入れないようにすること。
念の為、required_without以外にも下記のようにlteやrequired_withでも試したが同様だった。
```php
'item_id' => 'int',
'name' => ['lte:item_id','string']
```
この事から、全てのパラメータ付きルールで同じ事象になると思われるので、全体的に注意が必要になる。

また、下記のように配列形式での指摘も試してみたが、同様の事象が起きていたので指定方法に限らず空白を入れないようにしておきたい。
```php
'item_id' => 'int',
'name' => ['required_without:item_id','string']
```
Pythonで高速に素数判定、素因数分解を行う方法

Pythonで高速に素数判定、素因数分解を行う方法を紹介します。

## まえがき
現在高専に通っている16歳です!
学習の成果の書き出しや知識の共有をしたいと思っています。
よろしくお願いします!

## 目的
AtCoderなどの競技プログラミングやその他の実装の時に素数判定、素因数分解をする場面があると思いますが、そんな時に高速な素数判定、素因数分解を行うコードをわざわざ書きたくないのでここに書いておくことにしました。

## 素数判定
nが合成数のとき、√n以下で割り切れることを用いました。

~~~python:prime.py
from math import sqrt

def is_prime(n):
    if not isinstance(n, int):
        return False
    elif n < 2:
        return False

    for i in range(2, int(sqrt(n))+1):
        if n % i == 0:
            return False
    return True


print(is_prime(12))       # => False
~~~

関数の最初の条件式では引数が整数でない、もしくは2未満であるかを判断します。

そして、その下のfor文では2から√nまでの数で割れるかを試して、割れたら False を返し、最終的に割れなかったら True を返します。

## 素因数分解
### 素因数を列挙する方式

~~~python:prime.py
from math import sqrt

def factorization(n):
    factors = []
    if n < 1:
        return [-1]
    elif not isinstance(n, int):
        return [-1]
    elif n == 1:
        return [1]

    n1 = n
    for i in range(2, int(sqrt(n))+1):
        if n1 % i == 0:
            while n1 % i == 0:
                n1//=i
                factors.append(i)
                if n1 == 1:
                    return factors
    if n1 != 1:
        factors.append(n1)
        return factors
    elif factors == []:
        return [n]



result = factorization(120)
print(result)                # => [2, 2, 2, 3, 5]
~~~
まずは列挙できるように素因数を入れる配列を作成します。
ちなみに配列の要素の追加は遅いのであまり使いたくないですが、素因数の数を素早く計算するすべがまだ見つかってないのでやむを得ないです。

そして、1未満の数、非整数を条件文によってはじき出します。ここでは [-1] を戻り値に設定して判別がつくようにします。そして1の時は [1] を出力しておくことにします。

下のfor文ですが2から√nまで回して、nを代入したn1がiで割り切れた場合にn1がiで割れなくなるまで割り続けます。そして、割ると同時にiを配列に追加していき、forが回り終わったら、素因数が入った配列を返します。

### 素因数分解を指数で表記する方式
~~~python:prime.py
from math import sqrt

def factorization_index(n):
    factors = []
    if n < 1:
        return [[-1]]
    elif not isinstance(n, int):
        return [[-1]]
    elif n == 1:
        return [[1]]

    n1 = n
    for i in range(2, int(sqrt(n))+1):
        if n1 % i == 0:
            count = 0
            while n1 % i == 0:
                n1//=i
                count += 1
            factors.append([i, count])
            if n1 == 1:
                return factors
    if n1 != 1:
        factors.append([n1, 1])
        return factors
    elif factors == []:
        return [n, 1]


result = factorization_index(120)
print(result)                # => [[2, 3], [3, 1], [5, 1]]
~~~
全体的に素因数を列挙する方式と似てますが、whileの中身で何回iで割れるかを数えてそれを指数の部分として返します。

## 最後に
拙い文章でしたが読んでいただきありがとうございます。まだまだ技術は未熟ですが上達するようにアドバイスなどもお願いします!
Rubyの基本（配列 Part1）

# 配列の作成
順序が重要なデータは配列で管理する。
「puts」ならば値を順番に表示、「p」ならばリテラル表現で表示される。
「length」や「size」で格納されている値の個数を調べることができる。
```ruby:sample_01.rb
scores = [70, 90, 80]

# 値を順番に表示（改行付き）
puts scores
=begin
70
90
80
=end

# リテラル表現
p scores # [70, 90, 80]

# length も size も使用可能
p scores.length # 3
p scores.size # 3
```

# 配列の操作
配列に対しては、値の挿入、配列同士の連結、値の削除ができる。
```ruby:sample_02.rb
# 値の挿入
scores = [70, 90, 80]
scores << 85
p scores # [70, 90, 80, 85]

# 配列同士の連結
more_scores = [40, 50]
scores += more_scores
p scores # [70, 90, 80, 85, 40, 50]

# 値の特定の位置への挿入
scores.insert(1, 75)
p scores # [70, 75, 90, 80, 85, 40, 50]

# 値の削除
scores.delete_at(0)
p scores # [75, 90, 80, 85, 40, 50]
```
# 配列について調べる
配列について調べるためのメソッドとして、以下のものがある。
「true」か「false」を返すメソッドには慣習上「?」を付ける。
```ruby:sample_03.rb
scores = [70, 90, 80]

# 中身が空かどうか
p scores.empty? # false

# 特定の値が含まれているかどうか
p scores.include?(90) # true

# 特定の値のインデックス番号（値が存在しない場合はnilを返す）
p scores.index(80) # 2
p scores.index(40) # nil
```
# 配列の並び替え
配列の値を並び替えるメソッドとして、以下のものがある。
元のデータを直接更新する場合は、慣習上メソッド名に「!」を付ける。
```ruby:sample_04.rb
scores_01 = [70, 90, 80]

# 昇順に並び替え
sorted_scores = scores_01.sort
p sorted_scores # [70, 80, 90]

# 元の配列を直接更新して昇順に並び替え
scores_02 = [300, 200, 100]
p scores_02.sort! # [100, 200, 300]

# 元の配列を逆順に並び替え
scores_03 = [600, 400, 500]
p scores_03.reverse! # [500, 400, 600]

# 値をランダムな順番に並び替え
scores_04 = [700, 800, 900]
p scores_04.shuffle! # [900, 700, 800]
```

# 文字列を値に持つ配列
文字列を値に持つ配列の定義方法、操作方法は以下
```ruby:sample_05.rb
# 配列の定義
names_01 = ["Taro", "Jiro", "Saburo"]
p names_01 # ["Taro", "Jiro", "Saburo"]

# 別の書き方
names_02 = %W(Taro Jiro Saburo)
p names_02 # ["Taro", "Jiro", "Saburo"]

# 値の連結
connected_names = names_01.join
p connected_names # "TaroJiroSaburo"

# 値の連結（区切り文字を指定）
connected_names = names_01.join(", ")
p connected_names # "Taro, Jiro, Saburo"
```
# each文による値の表示
each文ではインデックス番号を表示することもできる。
```ruby:sample_06.rb
scores = [70, 90, 80]

scores.each_with_index do |score, index|
  puts "Score #{index}: #{score}"
end
=begin
Score 0: 70
Score 1: 90
Score 2: 80
=end
```
BigQuery 相関クロス結合について

# はじめに

こんにちは！Takoです。
今回は相関クロス結合について実際の作業で使ったのでアウトプットとして書きたいと思います！

# 相関クロス結合とは？

通常のクロス結合は単純な掛け算なので、3行のレコードのテーブル同士を 3x3 で以下のような結果になります。(詳しいコードの説明は割愛)

~~~sql:cross_join.sql
with user as (
  select
    *
  from
    unnest([
      "A", "B", "C"
    ]) as name
)

, purchase_date as (
  select
    *
  from
    unnest([
      "2023/01/01", "2023/01/02", "2023/01/03"
    ]) as date
)

select
  *
from
  user,purchase_date -- カンマを cross join と書き換えても同じ処理をする
~~~

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674311/d8f3de22-f0f1-eddb-3800-8e169ee75fad.png)


ただ、上記のように単純な掛け算でテーブルを縦に伸ばしたい例は少ないのかなと感じます(行数が無駄に増えちゃうし)。ユーザーごとやカテゴリごとなどに紐づけたいなどがあるかと思います。そんな悩みを解決するのが相関クロス結合です！

<b>相関クロス結合を使ってみる</b>

ユーザーごとにインストール日～アンインストール日までの日付を持ったテーブルを相関クロス結合を使って作りたいと思います。先ほどのクエリを少しいじって試してみます(インストール日とアンインストール日は予め追加しています)。まずはコードと結果から

~~~sql:relational_cross_join.sql
with user as (
  select
    *
  from
    unnest(ARRAY<STRUCT<name string, install_date date, uninstall_date date>>[
      ("A", "2023-01-01", "2023-01-02"),
      ("B", "2023-01-02", "2023-01-03"),
      ("C", "2023-01-01", "2023-01-04" )
    ])
)

, user_with_date as (
select
  name,
  generate_date_array(install_date, uninstall_date) as array_date
-- generate_date_array は日付の配列を作る関数
-- e.x. generate_date_array('2023-01-01, '2023-01-03')
-- だと ['2023-01-01, '2023-01-02, '2023-01-03'] が返ってくる
from
  user
)

select
  name,
  date
from
  user_with_date
cross join
  unnest(array_date) as date
~~~

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674311/1926cdac-095a-40b4-ab5d-938d5337df25.png)

少し解説をしていきます！が、個人的には相関は「？？」となることが多いので実際に試して理解する方がいいと思います。

~~~sql
cross join
  unnest(array_date) as date
~~~

このコードのように 配列 を unnest してクロス結合することで上記のようなテーブルを作成することができます。array を分解してその値が元々紐づいているユーザーのみに結合されているイメージでいいかと思います。相関クロス結合をする際には必ず同一のテーブル同士の結合をしてください。違うテーブル同士で上記のような結合をしても通常のクロス結合になります。

まとめると
* 配列カラムを含んだテーブルを用意
* 1のテーブルと unnest(1のテーブルの配列カラム) を cross join する

です！

ちなみに cross join 上で配列を作成すると少しクエリを省略できます。結果は先ほど書いた相関クロス結合のクエリと同じです。

~~~sql:relational_cross_join2.sql
with user as (
  select
    *
  from
    unnest(ARRAY<STRUCT<name string, install_date date, uninstall_date date>>[
      ("A", "2023-01-01", "2023-01-02"),
      ("B", "2023-01-02", "2023-01-03"),
      ("C", "2023-01-01", "2023-01-04" )
    ])
)

select
  name,
  date
from
  user
cross join
  unnest(generate_date_array(install_date, uninstall_date)) as date
~~~

# さいごに

相関クロス結合は意外と使える場面があるかと思います。個人的には日付を指定の日まで1日ごとor1月ごとに追加したい！って場面は有用かなと思っています。是非使ってみてください！
「JavaScriptで要素をドラッグして移動する簡単な方法」という記事を見たが、何となく外枠が欲しくなった

https://qiita.com/economist/items/d4254209330c11caff04

https://qiita.com/www-tacos/items/5614b61d3742d6db34b7

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="dyLyWVv" data-user="s4i" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/s4i/pen/dyLyWVv">
  ball-area</a> by s4i (<a href="https://codepen.io/s4i">@s4i</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

```html:HTML部分
<div class="outer">
  <img id="$img" src="https://js.cx/clipart/ball.svg" width="40" height="40">
</div>
```
```css:CSS部分
.outer {
  user-select: none;
  width: 200px;
  height: 200px;
  border: 3px solid blue;
}
```
```javascript:JavaScript部分
$img.onpointermove = function (e) {
  if (e.buttons) {
    //親要素内に留める
    let pe = e.currentTarget.parentElement;
    if (
      pe.offsetTop > this.offsetTop + e.movementY ||
      pe.offsetLeft + pe.offsetWidth <
        this.offsetLeft + this.offsetWidth + e.movementX ||
      pe.offsetTop + pe.offsetHeight <
        this.offsetTop + this.offsetHeight + e.movementY ||
      pe.offsetLeft > this.offsetLeft + e.movementX
    ) {
      return;
    }
    this.style.left = this.offsetLeft + e.movementX + "px";
    this.style.top = this.offsetTop + e.movementY + "px";
    this.style.position = "absolute";
    this.draggable = false;
    this.setPointerCapture(e.pointerId);
  }
};
```
asdfでWSL+UbuntuにGoをインストール

# はじめに

以前インストールしたプログラミング言語管理ツールのasdfを使って、WSL UbuntuにGoをインストールします。

# 前提環境

https://qiita.com/perilla/items/69bc6f89001dbceb0cde

https://qiita.com/perilla/items/ef73cf57ade24bc94f19

# asdf更新

asdfを更新します。

```sh:Ubuntu
asdf update
```

# Goの存在確認

```sh:Ubuntu
asdf plugin list all | grep -e golang
# golang                        https://github.com/asdf-community/asdf-golang.git
```

https://github.com/asdf-community/asdf-golang.git

# asdfにGoを追加

```sh:Ubuntu
asdf plugin add golang
```

# 依存パッケージをインストール

[GithubのREADME](https://github.com/asdf-community/asdf-golang.git)に従い依存パッケージをインストールします。

```sh:Ubuntu
sudo apt install coreutils curl
```

# 最新版Goをインストール

```sh:Ubuntu
asdf install golang latest
```

# 最新版Goをグローバルに設定

```sh:Ubuntu
asdf global golang latest
```

# Goバージョン確認

```sh:Ubuntu
asdf current golang
# golang          1.22.0          /home/[user]/.tool-versions

go version
# go version go1.22.0 linux/amd64
```
[Javascript]深いネストの中にあるオブジェクトを検索し順番も記録するアルゴリズム 

# やりたいこと
以下のようなオブジェクトがあるとする
```javascript
const sampleObject = [
  {
    "id": 1,
    "children": [
      {
        "id": 3
      },
      {
        "id": 4,
        "children": [
          {
            "id": 6
          }
        ]
      },
      {
        "id": 5,
        "children": [
          {
            "id": 7
          }
        ]
      }
    ]
  },
  {
    "id": 2,
    "children": []
  }
]

```
## やりたいことはこんな感じ
- idが6のオブジェクトまでの道筋(どのobjectを通って検索したか)を取得したい
- できるだけ無駄な繰り返しなく結果を取得したい

# 解決コード
```javascript
function exploreNestedObject(obj, targetId, currentPath, paths) {
    obj.forEach((item) => {
        const newPath = [...currentPath, item]; // 現在のパスに現在のオブジェクトを追加
        if (item.id === targetId) {
        newPath.forEach((path) => {
            paths.push(path); // 目標IDに到達したら、その経路を結果の配列に記録する
            })
        }
        if (item.children && item.children.length > 0) {
            exploreNestedObject(item.children, targetId, newPath, paths); // 再帰的に探索する
        }
    })

}

// テスト用のオブジェクト
const sampleObject = [
  {
    "id": 1,
    "children": [
      {
        "id": 3
      },
      {
        "id": 4,
        "children": [
          {
            "id": 6
          }
        ]
      },
      {
        "id": 5,
        "children": [
          {
            "id": 7
          }
        ]
      }
    ]
  },
  {
    "id": 2,
    "children": []
  }
];

// 目的のID
let targetId = 6;

// 初期のパスと経路を格納する配列を作成
let initialPath = [];
let paths = [];

// 探索を開始
exploreNestedObject(sampleObject, targetId, initialPath, paths);

// 結果を出力
console.log(paths);
```
## 解説
```mermaid
flowchart LR

newPathに探索中のオブジェクトを追加 
--> そのオブジェクトのidと目的のオブジェクトのidは同じか?
--> |true|経路を記録する配列に経路を記録


newPathに探索中のオブジェクトを追加 
--> そのオブジェクトが子を持ちかつその中が空ではないか?
--> |true|子オブジェクトを取得し再探索を行う
--> newPathに探索中のオブジェクトを追加 

newPathに探索中のオブジェクトを追加 
--> 最後まで探索して見つからない場合は探索中のオブジェクトの親まで戻り次のオブジェクトの探索を開始する
--> newPathに探索中のオブジェクトを追加
```
## 文字で説明するとこんな感じ

1. `newPath`にオブジェクトを追加
1. 探索中のオブジェクトのidと目的のオブジェクトのidは同じか?
    1. Yes->結果を格納する配列に経路を追加する
1. そのオブジェクトは子オブジェクト（配列）をもち、彼でないか?
    1. Yes->その子オブジェクトを取得し一番最初からその子オブジェクトの探索を始める
1. 見つからなければ探索中オブジェクトの一番上の親の次のオブジェクトの探索を始める

# これができるようになると
一つのidで探索することができるようになるのでデータの省略とかが図れるかなとか思った
iPadのTabキー操作でリンク要素にもフォーカスを当てられるように設定した

## これはなに？

iPadで外部キーボードを使って、Tabキー操作をしたときの解消方法の覚書です。

## iPadで設定する

iPadの場合フルキーボードアクセスをONにすることで、Tabキー操作でリンク要素にもフォーカスを当てることができます。

### 対象ソフトウェアバージョン

解説ではiOS17.3で行いました。
フルキーボードアクセスはiOS13.4から利用可能です。

### 設定方法

1. 「アクセシビリティ」→「キーボード」→「フルキーボードアクセス」を開く
1. 「フルキーボードアクセス」をON

![iPadのフルキーボードアクセスをONにしたスクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215239/139e9b16-fb4b-ab2b-3e7b-20769debf007.jpeg)

### フォーカス対象の「青い線」対策

上記の方法によって、Tabキー操作でフォーカスできるようになるのですが、フォーカス対象画面全体も青い線が表示されるようになります。

正直、私は少し煩わしいなと感じました。

この青い線ですがTabキー操作中に完全削除することはできませんが、Tabキー操作を終了した時点で速やかに青い線を非表示にすることはできます。

1. 「アクセシビリティ」→「キーボード」→「フルキーボードアクセス」→「自動的に非表示」に遷移する
1. 自動的に非表示をONにする
    1. デフォルトでONになっています
1. 表示時間を「1秒」に変更する

![自動的に非表示の秒数を1秒にした時のスクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215239/b3d7fa38-1dbd-48bc-7637-194be0b55dda.jpeg)

これで、Tabキーから手を離したと同時にフォーカスの青い線が消えるので、多少煩わしさは軽減されました。

ーーー

以上で設定完了です。
この記事が誰かのお役に立てれば幸いです。
BootRunを実行してもビルドアプリケーションが開始しない

## 状況
Spring Boot + IntelliJを使用。
http://localhost:8080/sample にアクセスし、Hello Worldを表示したい。

```JAVA:MainController.java
package com.example.sample.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MainController {

    @GetMapping("/sample")
    public String helloWorld() {
        return "Hello World";
    }

}
```


BootRunを実行すると…

```
BUILD SUCCESSFUL in 2s
4 actionable tasks: 3 executed, 1 up-to-date
23:26:46:  'bootRun' の実行を完了しました。
```
と表示され、ビルドは通っても、アプリケーションが開始されない。

ログの上の方を見ると…

```
***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class
```
と表示されている。

## 解決策

Spring Bootアプリケーションがデータソースを構成できないために発生している。
apprication.propertiesに下記を記載。


（前提：PostgreSQL DriverをDependenciesに追加しています）
```
spring.jpa.database=POSTGRESQL
spring.datasource.url=jdbc:postgresql://localhost:5432/sample
spring.datasource.username=｛設定したユーザ｝
spring.datasource.password=｛設定したパスワード｝
```
VITE + Reactプロジェクトでprocess.envを使うには

# はじめに
どうもこんにちは！僕は現在1ヵ月本気の技術力向上を目指している現役高校生1年生(@shunii )です！
今回はvite + Reactプロジェクトにて環境変数を扱う方法で少し行き詰ったのでまとめます。

# 問題
github actionsで以下のエラーが出た。
```
 src/utils/supabase.ts:3:29 - error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'es2022', 'esnext', 'system', 'node16', or 'nodenext'.
```
以下のsupabase.tsでは.envファイルで定義した環境変数を参照してsupabaseの設定をしている。vite + Reactのプロジェクトではimport.meta.env."環境変数名"で環境変数を参照する必要があるのだが、github actionsではその構文に対応していないことが原因らしい。
```ts:supabase.ts
import { createClient } from "@supabase/supabase-js";

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseKey = import.meta.env.VITE_SUPABASE_KEY;

export const supabase = createClient(supabaseUrl, supabaseKey);
```

# 解決策
<font color="red">**process.envを使えるようにする**</font>

以下の手順でprocess.envを使えるようにしました。
1. vite-plugin-env-compatibleのインストール
    ```
    npm i vite-plugin-env-compatible
    ```

2. vite.config.tsの変更
    ```ts:vite.config.ts
    import { defineConfig } from "vite";
    import react from "@vitejs/plugin-react";
    import env from "vite-plugin-env-compatible";

    export default defineConfig({
        plugins: [react(), env({ prefix: "VITE", mountedPath: "process.env" })],
    });
    ```

3. supabase.ts ( 任意のファイル ) の変更
    ```ts:supabase.ts
    import { createClient } from "@supabase/supabase-js";

    //process.envでstring以外の値が参照されることはない
    const supabaseUrl = process.env.VITE_SUPABASE_URL as string;
    const supabaseKey = process.env.VITE_SUPABASE_KEY as string;

    export const supabase = createClient(supabaseUrl, supabaseKey);
    ```

# 終わりに
何度か躓いた場所だったので、自分なりの記録を残せてよかったです。他の解決方法をご存じの方はコメントいただけると幸いです！

# About Me
- X(Twitter)

https://twitter.com/shunii_hack

# 参考

https://qiita.com/diskszk/items/ed6362e35e15f2fd790e

https://qiita.com/Sicut_study/items/d48bec20fa8b082a2368
intl拡張モジュールが無い環境でCodeIgniter4を動かす方法

# はじめに

CodeIgniter4の動作要件の1つとして、PHPのintl拡張モジュールが有効化されていることが挙げられますが、CodeIgniter4ベースのシステムをレンタルサーバで運用する際、intl拡張モジュールが無い問題にしばしば遭遇します。

intl拡張モジュールが有効化されたレンタルサーバやVPS/IaaSを選択すれば解決しますが、諸般の事情により他サービスを選択できないケースもあり、非常に悩ましい問題であったりもします。（CodeIgniter4に限らず、CakePHPやLaravel等の他のフレームワークやCMS等をレンタルサーバ上で運用する際においても、しばしば悩まされます）

今回、CodeIgniter4のソースコードを書き換えることで、intl拡張モジュールの無い環境でCodeIgniter4を動作させることが出来ましたので、以下に手順を記載します。

# CodeIgniter4のバージョン

CodeIgniter 4.4.6

https://github.com/codeigniter4/CodeIgniter4/releases/tag/v4.4.6

# 変更点
上記以外のバージョンにおいても同様の変更箇所を変更することで、intl拡張モジュールの無い環境で動作させることは可能と思われます。


```php:system/CodeIgniter.php
// 218行目と238行目をコメントアウト

199    /**
200     * Handles some basic app and environment setup.
201     *
202     * @return void
203     */
204    public function initialize()
205    {
206        // Define environment variables
207        $this->bootstrapEnvironment();
208
209        // Setup Exception Handling
210        Services::exceptions()->initialize();
211
212        // Run this check for manual installations
213        if (! is_file(COMPOSER_PATH)) {
214            $this->resolvePlatformExtensions(); // @codeCoverageIgnore
215        }
216
217        // Set default locale on the server
218 -      Locale::setDefault($this->config->defaultLocale ?? 'en');
218 +      // Locale::setDefault($this->config->defaultLocale ?? 'en');
219
220        // Set default timezone on the server
221        date_default_timezone_set($this->config->appTimezone ?? 'UTC');
222
223        $this->initializeKint();
224    }
225
226    /**
227     * Checks system for missing required PHP extensions.
228     *
229     * @return void
230     *
231     * @throws FrameworkException
232     *
233     * @codeCoverageIgnore
234     */
235    protected function resolvePlatformExtensions()
236    {
237        $requiredExtensions = [
238 -          'intl',
238 +          // 'intl',
239            'json',
240            'mbstring',
241        ];
242
243        $missingExtensions = [];
244
245        foreach ($requiredExtensions as $extension) {
246            if (! extension_loaded($extension)) {
247                $missingExtensions[] = $extension;
248            }
249        }
250
251        if ($missingExtensions !== []) {
252            throw FrameworkException::forMissingExtension(implode(', ', $missingExtensions));
253        }
254    }
```

```php:system/I18n/TimeTrait.php
// 73-74行目に `$locale = 'ja-JP';` を追加

73    {
   + 	$locale = 'ja-JP';
74        $this->locale = $locale ?: Locale::getDefault();
```

# 制限事項

この変更を行うことでintl拡張モジュールの無い環境でもCodeIgniter4が動作するようになります。しかし、当然ではありますがintl拡張モジュールに依存する処理は動作しません。例えば、 [Times and Dates](https://codeigniter4.github.io/CodeIgniter4/libraries/time.html) ライブラリはintl拡張モジュールに依存するため、このライブラリが提供するメソッドを利用しようとするとエラーになります。

その他、バリデーションの一部機能や国際化に関する機能が期待通りの動作にならない（処理が無視される、エラーが発生する）等の制限が生じる場合もあるため、運用にあたっては注意が必要となります。可能であれば、CodeIgniter4のコードを確認のうえ、利用するライブラリやクラスのメソッドがintl拡張モジュールに依存していないこと、フォールバック処理が存在する場合はそのロジックがどのようになっているか確認することをお勧めします。
自分のレベル

学習言語はPythonです。

学習を始めてから数カ月経つけど、昨日自分で投稿するまでQiitaの読み方をスルーしたままで、知らなかった。

キータと読むらしい。

投稿をするときには、マークダウン式で見出しを付けたり文字の太さなど変えてみたりしたいけど
それもやり方がわからないので時間があるときに調べてみようと思う。


プログラミングに関しては、chatGPTに聞かないと何もできない、、、

chatGPTに聞きながら、グーグルコラボを使ってデータの可視化、解析は少しずつできるようになってきました。

ITの世界において、自分は劣等生中の劣等生のいわば伸びしろしかない状態なので、ある種気が楽です。
【SwiftUI】削って遊べるスクラッチを作ってみる

# はじめに
削って何の絵が出てくるでしょう？みたいなスクラッチゲームを作ってみます。


# サンプルアプリ
![Simulator Screen Recording - iPhone 15 Pro - 2024-02-29 at 21.09.57.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/46ea0ca1-267b-f9b2-c91e-579ed2bb7b0a.gif)

# 実装
```swift
import SwiftUI

struct DrawLine: Identifiable {
    let id = UUID()
    var points: [CGPoint]
}

struct ContentView: View {
    
    @State private var pastLines: [DrawLine] = []
    
    @State private var currentLine: DrawLine?
    
    var body: some View {
        VStack {
            Text("スクラッチ")
                .font(.title)
            Text("削れ")
                .font(.title2)
            
            Image(.icon)
                .resizable()
                .scaledToFit()
                .gesture(dragGesture)
                .mask(maskView)
                .border(.black)
            
            Button {
                pastLines = []
            } label: {
                Text("リセット")
            }
        }
    }
    
    private var dragGesture: some Gesture {
        DragGesture(minimumDistance: 0, coordinateSpace: .local)
            .onChanged({ value in
                if currentLine == nil {
                    currentLine = DrawLine(points: [])
                }
                guard var line = currentLine else { return }
                line.points.append(value.location)
                currentLine = line
            })
            .onEnded({ value in
                guard var line = currentLine else { return }
                line.points.append(value.location)
                pastLines.append(line)
                currentLine = nil
            })
    }
    
    private var maskView: some View {
        ZStack {
            ForEach(pastLines) { line in
                Path { path in
                    path.addLines(line.points)
                }
                .stroke(Color.red, lineWidth: 20)
            }
            .clipped()
            
            Path { path in
                guard let line = currentLine else { return }
                path.addLines(line.points)
            }
            .stroke(Color.red, lineWidth: 20)
            .clipped()
        }
    }
}
```

# おわり
これを応用すれば、なぞった部分だけモザイクをかけるといったアプリを作ることができますね

# 参考記事
https://dev.classmethod.jp/articles/drawing-lines-in-swiftui/
Excel(エクセル) について、あれこれ。

# そもそもVBAが賞味期限切れで今は動かない。

そもそも、Web上になあって、クラウドで処理するのに、パソコン上でどの様な処理が出来るかなのですが。

で、Webから、パソコンの中に置いた実行ファイルを動かして、クラウド上にあるファイルをいじれるシステムが安全かとなるが。

そう言う事で。
_____
## パソコンの中にExcelファイルとExcel実行アプリを置く

### まずは、アプリの入手から
Microsoft store　から　downloadする。
俺は小規模で、あまり使わないから「無料」のを選んだ。ただし、upgradeは可能。
Open Xlsx PLUS 言うのをdownloadしてあったから、予備のdownloadを紹介する。

![スクリーンショット 2024-02-29 185048.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/d84dd3ea-d992-68f3-df35-88fa1c62baf5.png)　下のバーからストアを選んでクリック。

![スクリーンショット 2024-02-29 185326.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/2e60460a-62e4-c450-92c3-da761a108f90.png)
検索バーに「Excel」と入れて無料のめぼしい物を選んで「パソコンにdownloadする」
![スクリーンショット 2024-02-29 185529.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/132833ae-3978-6513-da8e-c39022989b90.png)
インストール済みになっている。
![スクリーンショット 2024-02-29 185554.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/93785f63-5537-c2bc-478e-0635d1726ed4.png)
ここは、新しく。。。
![スクリーンショット 2024-02-29 185623.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/f47f13e6-7c3c-571c-58f4-7135a879a56a.png)
「入手」をクリックしてしばらく待つ。
![スクリーンショット 2024-02-29 185925.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/2635c03b-acea-2af2-75fd-932f6f844b42.png)
いよいよ、開く、「実行」をやる。
![スクリーンショット 2024-02-29 190014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/1e9356db-ff2c-711f-8d29-f822c4ef7ce2.png)
英語がよくわからんが右にサイコロが出た。
![スクリーンショット 2024-02-29 190731.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/50c51d81-de20-3cb6-d389-35494d2dd237.png)
ツールの中に「マクロ(macro)」があるのを確認した。
![スクリーンショット 2024-02-29 191152.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/a49aea8e-5838-e238-3666-1e066d20110e.png)
### ここで、フォルダーの中にショートカットリンクを作るのやる。
![ani_ecsel_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/3b14128f-c735-4dd1-c584-7f7b621335e0.gif)
つまんで、ドラッグアンドドロップすれば、出来るんですが。

office365変なの出た。
![スクリーンショット 2024-02-29 193006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/084c5535-4103-ef2f-6b16-837d31935a90.png)
![スクリーンショット 2024-02-29 193332.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/d1c7779f-82be-532c-2bec-f0fc192f9e25.png)
![スクリーンショット 2024-02-29 193829.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/c0c907dd-b378-b936-14ad-3006d2353ea7.png)
![スクリーンショット 2024-02-29 194029.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/f54a9630-a384-c617-967b-48540b072e0f.png)

![スクリーンショット 2024-02-29 194226.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/36e2f229-83d3-65d1-54b2-01a9e07b5316.png)
![スクリーンショット 2024-02-29 194329.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/92875431-abea-f8b2-d97b-68d6567e4e36.png)

### このマクロいうやつに、色々書くと、実行してくれそうなんや。BASIC と書いてあるし。

それでは、また。
flexboxで、基本は中央寄せだが折り返して数が足りない要素は左寄せにした～い→gridで出来ました

# はじめに
掲題のことができずにQiitaで質問しようとしていましたが、自己解決したので記事にします。

# 解決したいこと
以下のhtmlがあります。
```html
<html>
  <body>
    <div class="parent">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>
    <style>
      .parent {
        width: 600px;
        height: 300px;
        padding: 20px;
        background-color: gray;
        display: flex;
        flex-wrap: wrap;
        column-gap: 10px;
      }
      .child {
        min-width: 120px;
        height: 120px;
        background-color: red;
        border: 1px solid;
      }
    </style>
  </body>
</html>
```
これはこんな感じの表示になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177673/816ff9dc-7e20-7500-f34b-a315e2f58137.png)
これを「全体としては中央寄せにするが、折り返されている2つの要素は左寄せ」にしたいのですがやり方が分かりませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177673/8c1e64ac-efff-39ff-0dec-fd9e790a56f8.png)
↑こうしたい

なお、この表示は`background-color`と`border`が`transparent`の`div`を2つ追加して数を揃えているだけです。
最悪これでも良いのですが、要素数が動的だと毎回横幅から収まる数を計算して折り返し要素数との差分だけ`transparent`要素を入れるという処理が必要でありイケてない感がするので、よりスマートな解決方法があるはず...

# 自分で試したこと
- `justify-content: center`
→折り返されている要素も中央に来てしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177673/4cb406d5-0a6d-4ff3-4f98-8aa6606d57a6.png)

- `justify-content: space-between`
→折り返されている要素が離れ離れになってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177673/09490d6b-ce0d-c299-f152-639a76345e19.png)

# gridを試す
gridの存在は知っていたのですがほぼ使ったことがなく、なんとなく動的にできなさそうなイメージがあったのでflexboxでの解決方法を色々調べていました。
しかし、いよいよflexboxでは難しそう...となったので、gridで動的に表示できるか調べてみました。

```html
<html>
  <body>
    <div class="parent">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>
    <style>
      .parent {
        width: 600px;
        height: 300px;
        padding: 20px;
        background-color: gray;
        /* display: flex; flexではだめだったよ...
        flex-wrap: wrap;
        column-gap: 10px; */
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(120px, 120px));
        gap: 15px;
        justify-content: center;
      }
      .child {
        min-width: 120px;
        height: 120px;
        background-color: red;
        border: 1px solid;
      }
    </style>
  </body>
</html>

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177673/efd5833b-07a1-35f9-09a8-473a07cf860e.png)
できた！

# おわりに
gridも勉強しないとな...と思いました。
また、もし「flexboxでもこうやればできるよ！」というのがあれば教えて頂ければと思います :bow:
Apexではswitchステートメントの式に定数は使えない

## 結論
**Salesforce Apexのswitchステートメントでは文字列定数は使えない。** 

ideaexchageにて似たような要望が過去に挙げられていたようです。
（探してくれた先輩ありがと。）

https://ideas.salesforce.com/s/idea/a0B8W00000GdWgHUAV/add-support-for-final-variables-in-switch-statement-when-clauses

SFの方曰く、ApexのSwitch statementで定数をサポートするのはムズいから諦めろとのこと。

なお、switchステートメントのApex開発者ガイドはこちら

https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/langCon_apex_switch.htm?q=switch

開発者ガイドだけ見ると書けそうに見えるところがイラくる。
サンプルはリテラルで書いてるけども。

## 調べた経緯的な話
とあるオブジェクトの選択リスト項目で、選択リストの値毎に何らかの処理をしたい。
といったコードを書くとなった際に、switchに定数を使ったらデプロイでエラーを吐かれて困ったことから。

列挙型を使おうとも思ったのだが、列挙型の開発者ガイドにある通り、
Apexの列挙型自体にはコンストラクター構文がなく、Javaみたいな使い方はできなさそうで諦め。

## オチ
大先輩にRVして貰ってコードを見直した結果、
switchの出番は消えました。ｻｲﾅﾗ

## はじめましてのご挨拶
この手の記事で挨拶なんて読み手にとっては邪魔そうなので、挨拶を文末に持ってきてみる。

ｳｨｰｽどうもしまーでーす（推しリスペクト挨拶）

これまでJava関連のWebアプリケーション開発の案件にのみ従事してきたのですが、
本年1月よりSalesforceの案件に参画することになってさあ大変。

今後の自分のために、学んだことや苦労したことを書き残しておこうと思った次第です。
この記事はお試し。ジャブですよジャブ。
~~※なお、かなりの飽き性なので、記事投稿は継続しないと思います。~~

ｺﾝｺﾞﾄﾓﾖﾛｼｸ。ではでは～
よわよわエンジニア、UI・UX修行を始める ~UIのまねっこってマズいんですか！？~

## はじめに
本記事では、UI・UXデザイン方面でつよつよになりたい筆者が、UI・UXデザインに取り組んでいくなかで身に染みて感じたことを書いています。

## 自我を捨てた方がいいんじゃなかったんですか！？

以前こんな記事を書いていた筆者。
https://qiita.com/kamikawa_m/items/fa6a78a9a8ea55fb562b

使いやすいUIにするには既存の良いUIをベンチするのがよさそうです。
しかし、UIデザインも「デザイン」。
一般的には他人が作ったデザインを丸パクリして自分のデザインにしようもんなら大炎上です。
下手すると訴状が会社もしくは筆者のおうちに届いてしまいます。

とはいえ、用途や媒体が似ているアプリケーションにおいては、UIデザインの幅は限られてくると思います。

たとえば、
「右上の×ボタンで閉じられる」
「画面左にナビゲーションがあって、ナビゲーションで選択した内容を画面右の表示領域で表示する」
などのUIデザインは、世の中一般のアプリケーションで割とよく見るものです。
これらを採用することが「パクリだ！」と言われてしまったら、「ユーザーにとって直感的でわかりやすいUI」を作ることがとても難しくなります。
デザイン的に完全オリジナルで、かつユーザーにとって直感的に使いやすいUIを提案し続ければよい話ですが、それはいばらの道だと思います。

しかし、かくいう筆者も、一生懸命考えたUIデザインが構成から色や、何から何まで知らない人に丸パクリされていたら嫌です。

**UIデザインの権利**については、どのように考えるべきなのでしょうか。
ちょっと調べてみました。

## 著作権法的には？

著作権法によると、著作物の定義は以下です。
>思想又は感情を創作的に表現したものであつて、文芸、学術、美術又は音楽の範囲に属するものをいう。

UIデザインは、美術的なデザインというよりは、ユーザーにとって使いやすいデザインであることが主眼です。
よって、「思想又は感情を創作的に表現したもの」とは言いづらいことが多いと思います。

また、著作権では色やレイアウトは保護されません(アイデアの範囲)。

その他、著作権には複製権や翻案権というものがあります。
簡単にいえば、複製権は著作物をまるまるコピーする権利、翻案件は著作物を翻訳・改変等して新たな著作物を作る権利です。
完全にコピーしたデザインを作れば複製権の侵害に、ちょびっとだけ変えたデザインを作れば翻案権の侵害になります。
しかしこちらについても、以下のような判例があります。
> 著作権法は，思想又は感情の創作的な表現を保護するものであるから，既存の著作物に依拠して創作された著作物が，思想，感情若しくはアイデア，事実若しくは事件など表現それ自体でない部分又は表現上の創作性がない部分において，既存の著作物と同一性を有するにすぎない場合には，翻案には当たらないと解するのが相当である。

つまり創作性のないデザイン、「普通に考えたらそういうデザインになり得るよね」という実用的なUIデザインであれば、他のアプリのUIデザインと似ていても著作権侵害とはみなされにくいのではないかと思います。

## 意匠法的には？

2020年に意匠法で保護される範囲が拡大し、画面デザインも意匠として保護されるようになりました。
(それまでは物品に組み込まれた画面デザインのみを保護しており、クラウドなどに保存されてインターネットを介して表示される画面デザインは保護されていませんでした。)

とはいえ、意匠法では以下のような意匠は保護されないようです。

>物品の機能を確保するために不可欠な形状若しくは建築物の用途にとつて不可欠な形状のみからなる意匠又は画像の用途にとつて不可欠な表示のみからなる意匠

デザインが、その画面にとって必要な要素しか含んでいない場合には意匠権が認められない、となると、ありふれたデザイン(=よくあるUIデザイン)については意匠権は認められにくいのでは？と思いました。

## さいごに

正しい解釈ができているかはわかりませんが、UIデザインに関しては創作性が認められにくいということはわかりました。

とはいえ、あまりにもそっくりデザインなのは、法的にギリギリ大丈夫だったとしても、自身および所属する会社のモラルを疑われることになりかねないと思います。
**ベンチは大事だけど何から何までそっくりにしたらダメ**、という認識を持っておく必要はあると感じました。

法律の解釈等、もし誤りがあればそっと教えていただけますと幸いです。

## 参考

- 著作権法
https://elaws.e-gov.go.jp/document?lawid=345AC0000000048

- 意匠法
https://elaws.e-gov.go.jp/document?lawid=334AC0000000125

https://www.mc-law.jp/kigyohomu/16422/
openAIからの請求がおかしかったので問い合わせたら、秒で返金してくれた話

ちょびっとしかopenAI API触ってない場合、openAIからの請求がバグることがあるようです。
ぐぐっても同じ現象の人が見つからないので、メモとして残しておきます。

# TL;DR
- openAI APIへの課金額がわずかな場合、必要以上に多く課金される場合があるようです
- チャットで問い合わせたら、速攻返金してくれました。スムーズな対応でよかったです
- openAIの問い合わせチャットは、結構なルールベースでした（なるほどね）


# 矛盾する利用料と利用金額履歴と請求金額
自分は、たまにopenAI APIで遊ぶくらいで、課金額が非常に小さいです。
こちらが、去年11月のAPI利用量。カスみたいな量です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106215/17bf17f1-b6e9-1658-88a5-e60f1580bb61.png)

詳細も見てみましたが、<b>リクエスト数3回</b>とかです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106215/9819700f-768f-9bec-c904-2cc2401d7e51.png)
<br><br>

そして、こちらがExportからダウンロードしてきた利用履歴。<b>なぜかGPT-4 Turboを8ドル</b>くらい使ったことになっています。（DATE列は、自分で追記）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106215/5091fd09-4fb3-01cd-c7ab-d4a8f566b00d.png)

<br><br>
で、これが去年11月の請求書なのですが、<b>請求額が10ドル</b>こえています。
0.05は前月からの繰り越しらしいので、11月分として請求されているのは10ドルです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106215/65e07bf1-b1c5-af76-4f4c-71ec14403d82.png)
<br>
<b>いったい何にどう課金されているのか、まったくわからない。</b>
金額の辻褄も全然合っていない。

金額がそこまで大きくないので、微妙に放置していたのですが、やっぱり気になったので問い合わせてみました。

# チャットでの問い合わせ

左下のHelpクリックすると、チャットボックスがでてくるので、そこから問い合わせが可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106215/cd6b36db-d3d3-c1ef-f515-0bb4cb4d8977.png)

[Ask a question]をクリックすることで、問い合わせをすることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106215/834efd47-fbf8-da36-9e13-6b7de1f959d7.png)


どうしたのかきかれるので、Payments and Billingを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106215/410e576d-4bfe-e6e3-0799-c4dcc4d3ef1e.png)

さらに、どのタイプの問題かきかれるのでFraud or unrecognized chargesを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106215/319cb2f0-a04c-ec79-ed74-c80366f653e7.png)

このあとは割愛しますが、ぽちぽちぽちぽちしていき、最終的に変な請求のあった日やクレジットカードの下4桁などを入力し、問い合わせ終了。
返答は、メールで返ってきます。

最後まで、びっくりするほどルールベースでした。
入力したのは、最後の請求日やクレジットカードの下4桁をうちこむところくらいでしたが、それも言われた情報を打ち込んだだけ、という感じでした。

上にAI Botとか書いてあるから、どんなAIぶりかと思いましたが、私が使った範囲では<b>AI要素が１ミリもなかった</b>ですね。

質問内容が支払いに関するものだからかもしれないですけど、こういうのは大事だと思います。カスタマーサポートで変なこと口走られても困るし、ルールベースで事足りるところはルールベースにしておいたほうが、省力化になるのでしょう。

# その後
問い合わせ後、速攻、openAI社からメールが来ました。

どうやら、6月に0.05ドルつかっていたやつが繰り越して請求されていたのですが、なぜかその場合、追加で10ドル請求されるという謎バグが発生した模様。なんだそれ。0.05ドルは、単独では請求できないので繰り越されたらしい。

10ドルまるっと返金してくれるとのことで、すぐに返金処理完了メールまで来て、あっという間に解決しました。

とりあえず、<b>すぐ調べてくれるので、気になる請求があったら、ただちにチャットで問い合わせるのがよさそう</b>です。

<br>

あと今後、「なんでもいいからAI使いたい！」って人から、なんか無茶ぶりされることがあったら、以下を言おうと思います。

「あのopenAI社でも、顧客からの問い合わせチャットボットはルールベースをフル活用してますが、ほんとにこれchatGPTで代用してしまって大丈夫ですか？」

以上
ソフトウェアテストについて

# テストって奥深い
普段何気なく行っていたテストですが、テストの世界でも色んなメソッドが研究されており、アメリカでは大学でソフトウェアテスティングの授業があると知り、驚きました。
ソフトウェアテストの奥深さを知り、ファウンデーションレベルですが、調べたことをここに残します。

# テストとは？
ソフトウェアテストは以下の2種類に分かれます。
**1. 動的テスト**
これは仕様通りに、お客さまの要望通りにソフトウェアが機能するかのテストです。
アプリケーションの機能をチェックする機能テストと、機能上は不可欠ではないが、ユーザーの快適度に影響する（例えば高負荷がかかった時の挙動や、ユーザビリティ）機能をテストする非機能テストがあります。

**2. 静的テスト**
ソフトウェアが動く前の段階のテストです。ソースコードや要件定義のレビューがこれにあたります。

# テストとデバッグの違い
テストとデバッグって、同じ概念と思ってましたが、どうやら違うようです。

**テスト**
テストとは、「ソフトウェアの故障を発見すること」です。

**デバッグ**
デバッグとは、「故障のもととなる欠陥を見つけ、解析し、取り除く作業のこと」です。

# エラー・欠陥・故障の違い
**エラー**
エラーとは、ソフトウェアテスティング界では、「人が犯す誤りのこと」だそうです。

**欠陥**
欠陥とは「故障の基となるもの」のことです

**故障**
故障とは、ソフトウェアを動かした結果、意図した動作がされないことを言います。

# テストの7原則
テストには7原則があるようです。

**1.テストは欠陥があることを示せるが、欠陥がないことは示せない**
テストがうまくいっても、欠陥がないことの証明にはならないので要注意。

**2.全数テストは不可能**
全てをテストすることは、単純なソフトウェア以外無理。なので、優先度を決めてテストを行う。

**3.早期テストで時間とコストを節約**
要件定義のレビューや、ソースコードレビューを早期に行うことで、早い段階で欠陥を見つけることができ、作業の出戻りが減り、コスト節約にもなる。

**4.欠陥の偏在**
欠陥や故障の原因は特定の少数モジュールに集中する。

**5.殺虫剤のパラドックスに気をつける**
同じテストは繰り返すたび、殺虫剤のように効力が低減する。テスト内容は同じものを何度も繰り返すのではなく、定期的に見直す必要がある。

**6.テストは状況次第**
状況が変われば、テストの方法も変わる。

**7.バグゼロの落とし穴**
表向きのバグが0でも安心してはいけない。ユーザーが「このアプリ使いにく！」と思ったり、後発のシステムなのに競合のシステムに劣ったり、そういうことをなくすための努力を惜しまない。

# 障害報告書の書き方
書く内容は以下
**1.わかりやすいタイトル**
**2.障害発生日時**
**3.障害復旧日時**
**4.障害内容 →　実行した手順を明確に記す！** 
**5.影響範囲**
**6.問題発生の経緯**
**7.暫定対応と恒久対応**
**8.原因と再発防止策**

書き方は以下
**1.できる限り具体的に書く**
**2.誰にでも伝わる表現で書く**
**3.事実と推測を明確に区別する**

以上がソフトウェアテストについて学んだことでした。


参考記事：https://jstqb.jp/dl/JSTQB-SyllabusFoundation_Version2018.J03.pdf
データフレームを得て VIF を計算する関数

ChatGPT 3.5 に「VIF を計算する関数を書いて」とお願いすると，すぐに書いてくれるけど，for を使ったり，statsmodels 使ったりして，冗長だなあ。結果だって，別にデータフレームで返してくれなくてよい。


```python
import pandas as pd
import numpy as np
from statsmodels.stats.outliers_influence import variance_inflation_factor
from statsmodels.tools.tools import add_constant

def calculate_vif(data):
    data_with_const = add_constant(data)
    vif_values = np.zeros(data_with_const.shape[1])
    for i in range(data_with_const.shape[1]):
        vif_values[i] = variance_inflation_factor(data_with_const.values, i)
    variables = data_with_const.columns
    vif_data = pd.DataFrame({'Variable': variables, 'VIF': vif_values})
    vif_data = vif_data[vif_data["Variable"] != "const"]
    return vif_data

data = {
    'x1': np.random.rand(100),
    'x2': np.random.rand(100),
    'x3': np.random.rand(100),
    'y': np.random.rand(100)
}
df = pd.DataFrame(data)

vif_result = calculate_vif(df)
print(vif_result)
```


      Variable       VIF
    1       x1  1.038079
    2       x2  1.002299
    3       x3  1.081315
    4        y  1.049966


関数自体は，一行で書ける。
データフレームを渡すと VIF をベクトルで返す。


```python
import pandas as pd
import numpy as np
from scipy import linalg

def VIF(df): return np.diag(linalg.inv(df.corr()))
print(VIF(df))
```

    [1.03807931 1.00229873 1.08131533 1.04996588]
Linux を GUIクライアントで使うと文字が大きい（備忘録）

# はじめに

LinuxでGNOMEのGUIをつかって操作をしていると文字が大きいと感じることがあり、変更する方法が分かりずらかったので調べました。セットアップをしてしまう次に同じことをするときに忘れてしまっているので備忘録として残しておきます。

# GNOME Tweaks を導入

タイトルが答えですが GNOME Tweakを導入します。

```
sudo yum -y install gnome-tweaks
```

# GNOME Tweaks を起動

GUIからはなぜか起動できない。コマンドで様子をみる

```
gnome-tweaks
```

https://askubuntu.com/questions/1234411/gnome-tweak-tool-does-not-open-anymore

が起きていた事に気づいて

```
killall gnome-tweaks
```

を実行して起動できるようになりました。


# GNOME Tweaks のメニュー

Fonts > Scaling Factor で変更できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/7cf8f6e2-5761-51c5-dbe4-c6b9329244e9.png)


# Screenshots の Shortcuts 

これも分からなくなりますが　

Settings > Kyeyboard > Keyboard Shortcuts

で確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/fac1352c-8bd5-b050-cc63-7956d92bba75.png)

私がよく使うのは Ctrl + Shift + Prt Screen です。

# 日本語入力

Settings > Keyboard > Input Sources 

で 日本語 を選んで Preferences で入力切り替え方法を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/622eff46-4fa4-8272-322f-872d2134e5f9.png)


# まとめ

GUIを使うときに自分の環境にあわず、調整が必要なこともあるのでよくする構成とあわせて備忘録とし残します。
Rails7でjQueryを使えるようにする

## 導入手順

importmapにjqueryを追加する

``` text:console
bin/importmap pin jquery
```

動作確認も含めて以下を追加
``` js:javascript/application.js
import jquery from "jquery"
window.$ = jquery

$(function(){
  alert('ok');
});
```

ちゃんと動いていたらページを更新すると
アラートが表示されます。

簡単だけどimportmapが全然わからないときめっちゃ困ったから書きました。