OmniAICreator/Qiita-1.07M huggingface dataset:
2024年5月のGoogle利用規約改定についてようやく要約したかった

皆さん、Googleの何かしらのサービスやシステムを使っていますか？
この記事を見に来られる人で使ったことが一度もないという人はとても貴重だと思います。
ということで5月ごろに下書きしていたこの記事をようやく要約しようと思いましたが~~やっぱりめんどくさくなった~~量が甚大ですのでとりあえずリンクをはっつけます。

市民Aにはこの程度の作業が可能です。

Google様 がユーザーに Google サービスを利用するうえで守ってほしいことを簡単にまとめたページ

https://policies.google.com/u/2/terms/update?utm_source=tos2024-email&utm_medium=email&pli=1

各サービスの利用規約などのまとめ

https://policies.google.com/u/2/terms/service-specific?utm_source=tos2024-email&utm_medium=email&pli=1


一例として、以下のGmailの規約があります
自分なんかは知らんうんちに4つくらいアカウント持ってました

https://www.google.com/gmail/about/policy/

> 複数の Gmail アカウントの作成と使用
Google ポリシーを乱用する、Gmail アカウントの制限を迂回する、フィルタを回避する、またはその他の形でアカウントに設定された制約を逃れるために、複数のアカウントを作成または使用しないでください。たとえば、不正行為が原因で他のユーザーからブロックされた場合や自分の Gmail アカウントが無効にされた場合に、代替アカウントを作成して同様の行為に走ることは許されません。
> また、自動化された方法で Gmail アカウントを作成したり、他者との間で Gmail アカウントの購入、販売、交換、再販売をしたりすることはできません。


他の例として、
Googleマップ登録への嘘情報や誹謗中傷などの目的であーだこーだするのはダメですよって話です。

https://support.google.com/contributionpolicy/answer/7422880

> たとえば、投稿や編集の内容は、実際の体験や情報に基づくものでなければなりません。意図的な虚偽情報の投稿、写真のコピーや盗用、話題に無関係なクチコミ、中傷的な表現の使用、個人攻撃、不必要または不正確なコンテンツなどは、すべてポリシー違反に該当します。Google では通常、違反と見なされるのが投稿の一部であったとしても、投稿全体（投稿された写真とそれに添えられたクチコミなど）が削除されます。許可されないコンテンツについて詳しくは、禁止および制限されているコンテンツをご覧ください。Google のポリシーや法律に違反していると思われる主観的なコンテンツ（クチコミ、メディア、場所に関する質問や回答など）またはプロフィールを見つけた場合は、不適切なコンテンツを報告し、修正するおよび不適切なユーザー プロフィールを報告するを参照して、適切に対応してください。

完走した感想ですが、
注意書きを記事にすることで誹謗中傷に乗っかる人なんかへの注意喚起になるのでヨシ！
要約したいなら今はもうAI利用すればよくないですか？
おっとこんなところにGoogle様のAIサービスが

https://gemini.google.com/app
Pythonで物体検出ツールを作成してみた

機械学習、pythonの学習中で、今回は物体検出ツールを作成してみました。
<br>
実行環境：Google Colab
※Google Colab は、ブラウザから Python を実行できるサービスです。
[Google Colabに関してはこちらの記事を参考](https://www.kikagaku.co.jp/kikagaku-blog/google-colab-howto/)

# 物体検出ツールの作り方
## OpenCVのインストール
Python では、豊富なライブラリのおかげで、画像の中から特定の物体を検出するプログラムも簡単に実装できます。
今回は、OpenCV というライブラリを使用して、画像内にある人の顔を検出するツールを作ってみます。

まずは、OpenCV のインストールを行います。
```
pip install opencv-python
```
今回作成するツールでは、OpenCV ライブラリに含まれる、事前に訓練された顔検出モデルを使用します。
※もしかすると、最新のGoogle Colabだと既にインストールされているかもしれません。

## かるく設計してみる
以下の流れで、処理を設計してみました
1. 画像内のオブジェクト検出に広く使用される「[カスケード分類器](https://www.pc-koubou.jp/magazine/21280#section01)」というモデルを face_cascade 変数に格納
2. 顔を検出する画像を読み込み
3. 検出精度向上のため、画像を白黒に変換
4. カスケード分類器で顔の検出を実行
5. 顔であると判定されるオブジェクトを四角形で囲む
6. 画像を表示

## 実装してみた
```物体検出ツール.py
import cv2
from matplotlib import pyplot as plt

# 画像を表示する関数
def show_image(img):
    # OpenCVはBGRで画像を扱うため、表示前にRGBに変換する
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    plt.imshow(img_rgb)
    plt.show()

# 顔検出用のカスケード分類器をロード
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

# 検出を行いたい画像を読み込み
img = cv2.imread('test.png')

# グレースケール画像に変換（検出精度向上のため）
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 顔の検出を実行
faces = face_cascade.detectMultiScale(gray, 1.1, 4)

# 検出された顔の周りに矩形を描画
for (x, y, w, h) in faces:
    cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), 2)

# 画像を表示
show_image(img)

```

重要な部分だけ説明していきます。

```顔検出.py
faces = face_cascade.detectMultiScale(gray, 1.1, 4)
```
**それぞれの引数が何をしているかというと**

　- **gray（グレースケール画像）**
顔検出には、画像をグレースケール（白黒）に変換したものを使います。これにより、色情報を省いて、明暗だけに注目して顔を検出するので、計算が高速で精度も上がります。


　- **1.1（スケールファクター）**
これは、顔を検出するために画像を縮小していく倍率を表しています。
スケールファクターは顔の大きさに対応しており、1.1という値は「画像を10%ずつ縮小しながら、異なるサイズの顔を検出する」という意味です。
1.1のように値を小さくすると、縮小のステップが細かくなるので、より多くの異なるサイズの顔を検出しやすくなります。
しかし、処理に少し時間がかかるかもしれません。
例えば、1.2にすると縮小ステップが大きくなり、少し処理が速くなりますが、検出精度が落ちる可能性があるそうです。


　- **4（最小隣接矩形数）**
このパラメータは、顔として認識されるために必要な最小の矩形（顔候補の領域）の数を指定します。
値が小さいほど多くの顔を検出する可能性がありますが、ノイズ（間違って顔と認識されるもの）も増えるかもしれません。
4という値は、少なくとも4つの隣接する矩形が重なる場所を顔と判断します。これにより、精度が高まる反面、小さい顔や複数の顔が近くにある場合には検出されないこともあります。
値を大きくすると、より信頼性の高い検出が行われますが、細かい顔や遠くにある顔が見逃される可能性があります。 
<br>


```矩形描画.py
for (x, y, w, h) in faces:
    cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), 2)
```

検出された顔ごとに、矩形を描画します。cv2.rectangleを使って、顔の座標（x, y）を基点に、幅（w）と高さ（h）の大きさで赤色の矩形（RGBで 0, 0,255）を描画しています。2は矩形の線の太さです。

## 結果
![スクリーンショット 2024-09-25 18.28.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1049676/3cacadce-01ea-c027-cc7a-cffad7103039.png)

精度はまだ荒いですが、顔の部分に矩形を描画することに成功しました！

# まとめ
機械学習、python初学者ですが、アウトプットしたことをまとめてみました。
同じ初学者の方の参考になれば幸いです。
最後まで拝読いただき、ありがとうございました。
ラズパイをWiFiホットスポットにするときのコマンド

メモなので解説しません。

```
sudo apt update
sudo apt install hostapd dnsmasq
```

```
sudo systemctl stop hostapd
sudo systemctl stop dnsmasq
```

```
sudo nano /etc/dhcpcd.conf
```

```
interface wlan0
    static ip_address=192.168.4.1/24
    nohook wpa_supplicant
```

```
sudo nano /etc/dnsmasq.conf
```

```
interface=wlan0      # Use the wireless interface
dhcp-range=192.168.4.2,192.168.4.20,255.255.255.0,24h
```

```
sudo nano /etc/hostapd/hostapd.conf
```

```
interface=wlan0
driver=nl80211
ssid=RaspberryPi_Hotspot
hw_mode=g
channel=7
ieee80211n=1
wmm_enabled=1
ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=your_password_here
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
```

```
sudo nano /etc/default/hostapd
```

```
#DAEMON_CONF=""
DAEMON_CONF="/etc/hostapd/hostapd.conf"
```

```
sudo nano /etc/sysctl.conf
```

```
net.ipv4.ip_forward=1
```

```
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"
```

```
sudo nano /etc/rc.local
```

```
iptables-restore < /etc/iptables.ipv4.nat

exit 0
```

```
sudo systemctl start hostapd
sudo systemctl start dnsmasq
sudo systemctl enable hostapd
sudo systemctl enable dnsmasq
```

```
sudo reboot
```

```
http://192.168.4.1:5000
```
Pythonプロジェクトを別の場所にコピーしたら依存関係に問題が発生した話

Python プロジェクトを別のディレクトリにそのままコピーすると、依存関係が壊れてしまう場合があります。

特に仮想環境が旧パスのモジュールを参照してしまい、プロジェクトが正常に動作しないという問題が発生しました。

そこで、`poetry`の設定値を再設定することで解決しました。ここでは手順を説明します。



# 前提
- `poetry`を使用しています
- macOS

# 手順

1. 現在の仮想環境を終了する

    仮想環境を終了し、参照している`Python`パスを確認します。


    ```bash
    deactivate
    which python
    ```
    
    仮想環境が正しく終了されている場合は、ルートパスにある`Python`へ切り替わっているはずです。例：
    ```bash
    /Users/username/.pyenv/shims/python
    ```



2. 現在の設定を確認

    仮想環境の場所などの設定を確認するために以下のコマンドを実行します。
    
    ```bash
    poetry config --list
    ```
    
    
    下記の項目にて仮想環境が旧パスに参照されていることが確認できます。
    ```bash
    virtualenvs.path = "venv-old-path"
    ```

3. 仮想環境のパスをリセットし、仮想環境を再生成する

    旧パスに仮想環境が残っている場合は、下記コマンドでパスをリセットします。
    ```bash
    poetry config --unset virtualenvs.path
    ```

    プロジェクト内に新しい仮想環境を生成し、依存関係を再インストールします。

    ```bash
    poetry install
    ```

    同じコマンドでpoetryが使用する仮想環境パスを確認し、 新しいディレクトリ内で設定されたことを確認します。
    ```bash
    poetry config --list
    ```


# 終わりに

この手順を踏むことで、コピーしたプロジェクトが別の場所でも正しく動作するようになりました。

仮想環境の参照先が変わるだけでなく、依存関係も新たに再構築されるので安心です🙆
[小ネタ] MinIOを従来通りファイルシステムそのままで使いたい場合は RELEASE.2022-05-26T05-48-41Z 以前を使おう

## 何故か久しぶりに起動した MinIO が動かなくなっている人へ

久しぶりに [MinIO](https://min.io/) を含むテスト環境をDocker等で起動すると何故かMinIOが動かない or 直接ファイルシステムに作ったオブジェクトが取得できなくなってしまった人は、**MinIOを [`RELEASE.2022-05-26T05-48-41Z`](https://github.com/minio/minio/releases/tag/RELEASE.2022-05-26T05-48-41Z) 以前のバージョンに固定してみてください。**

```diff:compose.yml
services:
  # テスト用のS3
  test_s3:
-    image: minio/minio:latest
+    image: minio/minio:RELEASE.2022-05-26T05-48-41Z
    ports:
      - "19999:19999"
      - "19998:19998"
    environment:
      MINIO_ROOT_USER: testuser
      MINIO_ROOT_PASSWORD: testpassword
    volumes:
      - ./s3/data:/data
      - ./s3/config:/root/.minio
    command: server --address ":19999" --console-address ":19998" /data
```

上記のコンテナが立っている状態 (`docker compose up -d`)で、ローカルファイルシステム上の書き込みが直接CLIで取得できるか見てみます。

```bash:ファイルシステム越しに読み書きできるかチェックしてみる.sh
export AWS_ACCESS_KEY_ID=testuser
export AWS_SECRET_ACCESS_KEY=testpassword

# ファイルシステムに書き込まれたものがminio越しに見えるかチェックしてみる
mkdir s3/data/foobucket
echo "hello!" > s3/data/foobucket/test.txt

aws --endpoint-url http://localhost:19999 s3 ls s3://foobucket/
# 2024-09-25 17:50:00          7 test.txt

aws --endpoint-url http://localhost:19999 s3 cp s3://foobucket/test.txt -
# hello!
```

## なぜそれより後のバージョンのMinIOは（うまく）動かないのか？

MinIOの従来型のファイルシステムをそのままS3のバケットとして使える機能 (filesystem mode) は2020年に開発が終わり、**リリース `RELEASE.2022-10-24T18-35-07Z` を最後に機能自体が削除されました。** これ以降の MinIO ではAPI越しにオブジェクトストレージを編集する必要があります。詳しくは以下の公式ドキュメントを参照してください。

https://min.io/docs/minio/linux/operations/install-deploy-manage/migrate-fs-gateway.html

それであれば、なぜそれより4ヶ月以上前のはずの [`RELEASE.2022-06-02T02-11-04Z`](https://github.com/minio/minio/releases/tag/RELEASE.2022-06-02T02-11-04Z) 以降のバージョンも駄目かというと、そのバージョンから**ファイルシステム上からの直接の変更などMinIOが把握しない形でバケットを作成してしまうと、バケットリストアップから省かれてしまうから**です。[^1]

[^1]: 各種バージョンに対し記事中の `ファイルシステム越しに読み書きできるかチェックしてみる.sh` の内容を一つずつ切り替えて実際にローカル試験したところ、 `RELEASE.2022-06-02T02-11-04Z` 以降から動作が変わっていることを確認しました。

記事冒頭の `ファイルシステム越しに読み書きできるかチェックしてみる.sh` のスクリプトもバケットリストアップから失敗します。`mkdir` しただけのディレクトリはバケットと認識してくれないようです。一度MinIOに何らかの形でバケットを把握させれば（メタデータを作成させれば）その後はきちんと把握されるようです。

バージョンごとの挙動をまとめるとこうなります。

| バージョン | ファイルシステム上でいきなりバケット作成 | ファイルシステムモードのサポート |
|--|--|--|
| - `RELEASE.2022-05-26T05-48-41Z` | **OK** | **OK** |
| `RELEASE.2022-06-02T02-11-04Z` -<br> `RELEASE.2022-10-24T18-35-07Z` | NG | **OK** |
| `RELEASE.2022-10-29T06-21-33Z` - | NG | NG |


おそらく開発・テスト環境で MinIO を使っていた人は、ファイルシステムそのままのS3が使えるという点でMinIOを使っていた（重宝していた）と思うので、急場しのぎであれば過去バージョン(`RELEASE.2022-05-26T05-48-41Z`)に修正して対応するのが一番早いです。

（無論、ちゃんとAPI経由で操作するのが理想的ですが、CIなどでいちいちAWS SDKをインストールして呼び出すのは面倒ではあります）
Snowflakeのビューとマテリアライズドビューとダイナミックテーブル

SnowflakeにS3などの外部ステージからデータをロードした際、
JSONとかの形式だと見づらいので見やすくするワンクッション入れることがあると思います。
![スクリーンショット 2024-09-22 110604.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/3f186f9a-0b2d-ba3b-e18e-1f9c8489ea08.png)
↑ 見づらい例です。

表形式で見やすくするのに
- ビュー
- マテリアライズドビュー（マテビュー）
- ダイナミックテーブル
と3つ簡単に取りうる策があるかと思います。

https://docs.snowflake.com/ja/user-guide/overview-view-mview-dts#comparison-of-views-materialized-views-and-dynamic-tables

だいたい ↑ にまとまってるんですが。
実際試してみたことも踏まえて自分なりにまとめなおしてみます。

# ビュー
実データは持たないので、ビュー定義のSELECT文がビュー参照の都度走ることになります。
Good：ストレージ料金がかからない
Bad：Selectがちょっと重たくなる

# マテリアライズドビュー
ビューとは違って実際にテーブルのようにデータの実体ができます。
そういう意味ではビューで書いたGoodとBadは逆になる感じです。
Good：SelectがViewより軽い
Bad：ストレージ料金がかかる

# ダイナミックテーブル
マテリアライズドビューと同様、実際にデータの実体ができます。
GoodとBadはマテビューと同じで、プラスアルファでマテビューとの差異があります。

それぞれの制限を別枠でまとめます。

# マテビューとダイナミックテーブルの制限
公式ドキュメントをちゃんと読むのがおススメではありますが、私が注目したポイントのみ記載します。
## マテビューの制限
マテビューは複数テーブルの結合などはできない。単一テーブルのみ。
単一テーブルでも自分自身のテーブルを再度使った結合もダメ。
Window関数も使えない。

実際この制限に引っかかって、マテビューをあきらめてダイナミックテーブルにしたことがあります。

## ダイナミックテーブルの制限
ディレクトリテーブル、Icebergテーブル、外部テーブル、ストリーム、マテリアライズドビューは定義に含められない。

# マテビューとダイナミックテーブルのコスト面の比較
マテビューはサーバーレスでデータの更新がされます。
サーバーレスは1秒単位の課金です。
ダイナミックテーブルは自アカウント内のウェアハウスが動いてデータの更新がされます。
ウェアハウスは1秒で終わっても60秒は課金対象になります。（61秒以上は秒単位）
コスト的にはマテリアライズドビューの方が安いことが多いんじゃないでしょうか。

# まとめ
とりあえず作るならビュー（データ量が少ないとか）
↓
ちゃんと実データとして持ちたいならマテビュー
↓
マテビュー制約にひっかかってダメならダイナミックテーブル

完全に個人的感想です。
異論は認める！のでコメントください。
sklearnのLDAでsolverによって値が変わる話

表題の通りです。

まずsklearnのLDAについて

https://scikit-learn.org/stable/modules/generated/sklearn.discriminant_analysis.LinearDiscriminantAnalysis.html

LDA自体の説明について

https://qiita.com/m1t0/items/06f2d07e626d1c4733fd

### 結論
1次元の2値(bool)分類でのLDAの場合、xの値がある値以上ならTrue,未満ならFalseと予想するという内部構造になります。
そのある値なんですが、以下のようにモデルから取り出すことができます。
```python
border = -model.intercept_/model.coef_
```
傾きが`model.coef_`で切片が`model.intercept_`、それぞれa,bとおくと
$$ax_{border}+b=0\  \  ,\  x_{border}=-b/a$$
な感じです。
solverはsvd,lsqr,eigenの3種類で標準はsvd。見ていきましょう。

```python
#make_moonsで的当にデータ作成、特に意味はない
n_samples=100
X, y = make_moons(n_samples = n_samples, noise = 0.1)
X=X[:,[0]]

#TrueとFalseのバランスを1:1じゃなくする。
random_y=np.random.randint(0,2,n_samples)
print(f"n_True:n_False={np.sum(random_y==1)}:{np.sum(random_y==0)}")
>>n_True:n_False=53:47

#svd
model_svd=LDA(solver="svd")
model_svd.fit(X, random_y).score(X, random_y)
print(-model_svd.intercept_/model_svd.coef_)
>>[[-0.3641749]]

#lsqr
model_lsqr=LDA(solver="lsqr")
model_lsqr.fit(X, random_y).score(X, random_y)
print(-model_lsqr.intercept_/model_lsqr.coef_)
>>[[-0.34673599]]

#eigen
model_eigen=LDA(solver="eigen")
model_eigen.fit(X, random_y).score(X, random_y)
print(-model_eigen.intercept_/model_eigen.coef_)
>>[[-0.34673599]]
```
なんでかは知らないですが、svdの時だけ値が変わります。
そして、上記サイトの原理の通り作成するとlsqr,eigenの値と一致します。
ただし、TrueとFalseが同じ数だけある時には全て一致します。


### 経緯
以上のページを参考に、自分でLDAを実装しようとしました。
手始めにまず1次元の、2値(bool)分類で作成
以下のようになりました。

```python
def LDA_1d(x,y):
    mu_T=np.mean(x[y])
    mu_F=np.mean(x[~y])
    sigma=(np.sum((x[y]-mu_T)**2)+np.sum((x[~y]-mu_F)**2))/(y.shape[0])
    f=(mu_T-mu_F)*x-(mu_T-mu_F)*(mu_T+mu_F)/2+sigma*np.log(np.sum(y)/np.sum(~y))
    return np.sum((f>=0)==y)/y.shape[0]
```
これをsklearnのものでチェックした時に、おかしいと言われてしまいます。
雑にですが、

```python
N=10
for i in range(N):
    #データ作成、make_moonsで的当にXを作成して、random_yで的当に答えを作成
    n_samples=100
    X, y = make_moons(n_samples = n_samples, noise = 0.1)
    X=X[:,[0]]
    random_y=np.random.randint(0,2,n_samples)

    #入れてみる
    my_score_LDA=LDA_1d(X[:,0], random_y==1)                     #myfunc
    ans_score_LDA=model_LDA.fit(X, random_y).score(X, random_y)  #sklearn
    
    if my_score_LDA!=ans_score_LDA:
        print(f"diff_LDA(random),{np.sum(random_y==0)}:{np.sum(random_y==1)}" ,my_score_LDA,ans_score_LDA)
```

動かしてみたら`diff_LDA`が表示されまくります。
いろいろ1日以上悩んでふと、`solver`なんて引数があったなーと思い、変更してみました。
その際に上の値を見て確信しました。かなり時間を無駄にしてしまいました。
だってsolverで変わるなんて流石に思わなくないですか？？

以上です。何か誤解があったら(ありそう)教えていただければと思います。
js学習part1(メソッドと関数)

# １,はじめに
私はとある大学に通っている建築学部の3回生である。
バイト先がwebの制作会社なので、コーディングでhtmlやcssを触ることがありフロントエンドエンジニアを志すようになった。初動が遅いようにも感じるがポートフォリオ作成のためにjsやreactの学習を始たので、そこで得た知識のアウトプットとして記事に残していこうと思う。

# 2,関数について
関数とは実行したいプログラムを格納したものである。
```index.js
function 関数名(引数) {
  console.log(`こんにちは${引数}さん`);
}
```
上記はconsole.logの内容をコンソールに表示するための関数である。呼び出しは`関数名(引数)`で行うことができる。

上記の記述方法とは別に簡略化されたアロー関数というものが存在する。
```index.js
const 関数名=(引数)=>{
  console.log(`こんにちは${引数}さん`}
}
```
上記がアロー関数の雛形である。functionの記述が必要なくなり読みやすくなっている。呼び出し方は同様である。
# 3,メソッドについて
オブジェクトに紐づけられている関数のことをメソッドという。
メソッドは大きく分けて2種類に分けられる
1つめはカスタムメソッド、2つめは組み込みメソッドである。

前者は主にユーザーが定義するメソッドである。
```index.js
const dog{
  name:`pochi`,
  メソッド名:function(引数){
  console.log(`${this.name}:ワン！`)
   }
}
dog.メソッド名(引数);//
```
上記がカスタムメソッドの基本的な定義、呼び出し方法である。
メソッド内でプロパティを使う場合は`this.`を記述する必要がある。

後者の組み込みメソッドはjs側で定義されているメソッドである。
ここではDOM操作で使われている`document`オブジェクトに紐づけられてるメソッドを紹介している記事を置いておく。
https://qiita.com/nobu19119516/items/befa18f7f187f3621819
クラウド初心者がAWS Skill Builderを紹介してみた

## はじめに
はじめましてTOKAIコミュニケーションズの浅比です。
本記事はANGEL Dojo2024参加者によるアドベントカレンダー25日目の記事です｡
よかったら他の記事もチェックしてみてください!
https://qiita.com/organizations/2024-angel-dojo

今回はAWSどころかクラウド初心者である私が､基礎を勉強する際、使ったAWS Skill Builderについて書いていこうと思います。
## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア

## Skill Builderとは
AWSスキルビルダーは、AWSの技術をオンラインで学ぶための学習プラットフォームです。無料や有料のコース、ハンズオンラボ、認定試験対策など、初心者から上級者まで幅広い内容を提供しています。
詳細は以下のリンクをご覧ください。
https://aws.amazon.com/jp/training/digital/

:::note warn
注意
今回紹介するものは有料コースのものになります
:::

## おすすめコンテンツ

### Skill Builder Labs
AWS環境で実践的な操作ができる学習ツールです。
AWSリソースを使用してインフラ構築やサービスの実行を体験でき、設定ミスやトラブルシューティングの方法も学べます。特に、VPC設定やLambda、S3といったサービスの操作を実践できる点が特徴です。
また、仮想の制限された環境で操作を行うため、リスクなくAWSの本番環境に近い体験が可能です。スキルアップや新しいAWS技術の習得に最適です。
特にトラブルシューティングを学べるのがでかいと思っていてテスト環境で変にいじって環境ごと壊してしまった経験がある時分にはとてもありがたかったです。

コンテンツの量もかなりあり、現在日本語で148のコンテンツがあるようです。
![スクリーンショット 2024-09-25 170650.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3889929/cae5f0b9-148c-1a54-7236-2f7700e2fd5c.png)

### AWS Cloud Quest
AWS Cloud Quest は、ゲーム感覚でクラウドスキルを習得できるユニークなトレーニングプログラムです。3Dの仮想都市を舞台に、ユーザーは課題をクリアしながらAWSのサービスや概念を学びます。実際にAWS環境を使ってシナリオを解決するため、楽しみながら実務的なスキルが身につくのが魅力です。また、ゲーム形式なので達成感が得られ、モチベーションを高めながら進められるのが特徴です。

:::note
現在、AWS認定クラウドプラクティショナーを持っている方がいれば、資格更新するときにAWS Cloud Quest: Recertify Cloud Practitioner の再認定を受ければテストを受けなくても3年延長されるみたいです。
これを機に触れてみてはどうでしょうか。
:::

![スクリーンショット 2024-09-25 172445.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3889929/814ed246-67e5-8039-5c66-b22563d142f7.png)


## おわりに
今回は私が実際に触って実務に役立ったコンテンツの紹介でした。
ほかにも、学習コンテンツとして様々なものがあるので触ってみてはどうでしょうかという提案でした。
AngelDojo2024もあと少しで活動が終わってしまうので、吸収できるところは吸収していきたいと思います。

## 参考記事
https://aws.amazon.com/jp/certification/recertification/#:~:text=3%20%E5%B9%B4%E3%81%94%E3%81%A8%E3%81%AB%E8%AA%8D%E5%AE%9A%E3%82%92%E6%9B%B4%E6%96%B0%E3%81%99%E3%82%8B%20%28%E5%86%8D%E8%AA%8D%E5%AE%9A%E3%82%92%E5%8F%97%E3%81%91%E3%82%8B%29%20%E5%BF%85%E8%A6%81%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82%20AWS%20Cloud%20Quest%3A%20Recertify,Quest%3A%20Recertify%20Cloud%20Practitioner%20%E3%82%92%E5%86%8D%E8%AA%8D%E5%AE%9A%E3%81%99%E3%82%8B%E8%B3%87%E6%A0%BC%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82%20%E3%81%93%E3%81%AE%E5%86%8D%E8%AA%8D%E5%AE%9A%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E5%AE%8C%E4%BA%86%E3%81%99%E3%82%8B%E3%81%A8%E3%80%81%E8%AA%8D%E5%AE%9A%E3%81%AE%E6%9C%89%E5%8A%B9%E6%9C%9F%E9%96%93%E3%81%8C%203%20%E5%B9%B4%E9%96%93%E5%BB%B6%E9%95%B7%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82
【DAY16】HTTPについて

## HTTPとは
HTTP（HyperText Transfer Protocol）とは、Webサーバとクライアントが文書などの情報をやりとりする時に使われる通信プロトコルです。
通信プロトコルとは、通信機器同士が通信を行うためのルールです。同じ通信プロトコルを使用することで、メーカーや種類が違う通信機器同士であっても通信することができます。
## HTTPSとは
　HTTPS（Hypertext Transfer Protocol Secure）とは、SSL（暗号化通信）によってセキュリティを高めたhttpのことです。暗号化されているため第三者による情報の盗聴や改竄を防止するとができます。
## HTTPリクエスト
HTTPの通信では、クライアントからサーバーにリクエストを送り（HTTPリクエスト）、サーバーが必要な処理を行なって、サーバーからクライアントにレスポンスを返す（HTTPレスポンス）という流れで処理が進みます。
HTTPリクエストは、「リクエストライン」「HTTPヘッダ」「メッセージボディ（情報を送るリクエストで使用）」から構成されます。
リクエストラインの冒頭ではリクエストの種類を指定するメソッドを書きます。
メソッドをいくつか紹介します。
* GET
サーバー上のファイル本体を取り出す
* POST
サーバー上のプログラムにデータを送付する
* PUT
サーバー上のファイルを置き換える
* DELETE
サーバー上のファイルを削除する

私の使用しているLaravelでは、ルーティングにメソッドを記述します。
```php
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::delete($uri, $callback);
```

## HTTPレスポンス
HTTPレスポンスは、「ステータスライン」「HTTPヘッダ」「メッセージボディ」から構成されます。
ステータスラインにあるステータスコードは、それぞれのコードに対して個別の意味が割り当てられています。
ステータスコードでよく使われるものをいくつか紹介します。
* 200
成功（OK)
* 404
見つからない（Not Found）
* 500
サーバー内部エラー（Internal Server Error）

404 Not Foundは見覚えのある方も多いと思います。
500は開発中にエラーが発生した時、開発者ツールのネットワークを見るとステータスに書いてあることが多いです。
他には、開発中に開発サーバーの起動を忘れてアプリをリロードすると、503(Service Unvaliable)が見られます。
Whisper に Azure OpenAI Service を使用して日本語データを読み込ませる

# Azure OpenAI Service の Whisper modelって？

Whisper モデルは、OpenAI の音声テキスト変換モデルで、オーディオ ファイルの文字起こしに使用できます。

公式のドキュメントの説明はこちら

https://learn.microsoft.com/en-us/azure/ai-services/speech-service/whisper-overview

公式ドキュメントのクイックスタート

https://learn.microsoft.com/en-us/azure/ai-services/openai/whisper-quickstart?tabs=command-line%2Cpython-new%2Cjavascript&pivots=programming-language-javascript

本記事で使用しているサンプル音声ファイル

https://github.com/Azure-Samples/cognitive-services-speech-sdk/blob/master/sampledata/customspeech/ja-JP/testing/audio-and-trans.zip

# 本記事の目的

上記公式ドキュメントの説明からは Transcriptions と Translations の使い分けに関して読み取れない為、それぞれの API の使い方についての備忘

# 実行方法
## 入力言語のまま文字起こしをした結果を出力する場合

Transcriptions の REST API を使用する

https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#transcriptions

```bash
$ curl https://<リソース名>.openai.azure.com/openai/deployments/<デプロイモデル名
>/audio/transcriptions?api-version=2024-06-01 \
-H "api-key: <API key>" \
-H "Content-Type: multipart/form-data" \
-F file="@./audio.wav"
```

ubuntu 20.04での実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232184/d17d0138-5e40-ab0b-ce7d-94b7821513f4.png)


## 英語にて翻訳した結果を出力する場合

Translations の REST API を使用する

https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#translations

```bash
$ curl https://<リソース名>.openai.azure.com/openai/deployments/<デプロイモデル名
>/audio/translations?api-version=2024-06-01 \
-H "api-key: <API key>" \
-H "Content-Type: multipart/form-data" \
-F file="@./audio.wav"
```

ubuntu 20.04での実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232184/d71b3c89-8ab5-30bc-627c-40a0031418c9.png)
paizaラーニング問題集「最長増加連続部分列」を解いてみた

https://paiza.jp/works/mondai/dp_primer/dp_primer_lis_continuous_step0

▼考え方

リストaおよびリストdpの先頭の要素(a[0],dp[0])は0とし、
人は要素1から代入していくことにしました。
理由は、人が1(n=1)のときでも計算できるようにするためです。

▼コード：
```py
########## 処理0(準備) インプット,リスト定義など ###########

n = int(input())

a = [0]*(n+1)

########## 処理1 漸化式の定義、計算、出力 ##########

dp = [0]*(n+1)

for i in range(1,n+1):
    a[i] = int(input())

for i in range(1,n+1):

    if a[i-1] <= a[i]:
        dp[i] += dp[i-1] + 1
    else:
        dp[i] = 1
        
print(max(dp))
```
MAUI Tips - iPhone シミュレーターの（再？）インストール

# 概要
普段Windows使いなので、Macで.NET MAUIの開発をする際、
いろいろ知らな過ぎて調べた初歩的なことを
備忘のために記録しておく。

# 調べたこと
今回は、Xcodeを最新にした後に、Xcodeのシミュレーターのインストールが走ったけど、
途中で止めてしまい・・・

再度インストールするにはどうするのか？・・・という話。
→なぜ止めたのかは置いといて。

# 方法
①Xcodeを起動する。
②メニューから「Setting」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/5e946cf8-64ba-7fe1-4e86-a46a5267f2c7.png)
③「Components」タブを表示し、「iOS XX.X」の行の「Get」をクリックする。
![スクリーンショット 2024-09-25 17.32.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/669c190d-253c-0494-c1a1-e4055d6480d8.png)

以上でシミュレーターのインストールが始まる。
ここでシミュレーターの削除とかもできる。

# 注意
2024/9/25現在、最新版のXcodeで.NET MAUIはビルドできなかった・・・。
→なので、今からダウングレードするというオチ・・・。

# 余談
Xcodeの「c」って、小文字だったのね。
→大文字で書いてて、全部書き直した💦
【Jest】テストファイルを跨いで共通使用する関数を管理する方法について

# はじめに
下記を満たすテストファイル用共通処理の管理方法を調査、試した際の備忘録です。
- 複数のテストファイルで共通使用できる関数を追加したい。
- 各テストファイルに同じ関数を書きたくない。
- commonなどで共通使用すると便利な関数を1箇所にまとめたい。（管理しやすくしたい。）

とりあえず動作したので、備忘録としてメモを残すことにしました。
下記のstackoverflowの回答を参考にしています。
[javascript - Shared utils functions for testing with Jest - Stack Overflow](https://stackoverflow.com/questions/50411719/shared-utils-functions-for-testing-with-jest)

# 環境
Angular15でJest使用しています。中々バージョン上げる時間が取れず、色々と古いです。参考までに。

```
Angular CLI: 15.2.11
Node: 16.14.2
Package Manager: npm 8.5.0
OS: linux arm64

Angular: 15.2.10
... animations, common, compiler, compiler-cli, core, forms
... language-service, localize, platform-browser
... platform-browser-dynamic, router

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.1502.11
@angular-devkit/build-angular      15.2.11
@angular-devkit/core               15.2.11
@angular-devkit/schematics         15.2.11
@angular/cdk                       15.2.9
@angular/cli                       15.2.11
@angular/material                  15.2.9
@angular/material-moment-adapter   15.2.9
@schematics/angular                15.2.11
rxjs                               6.5.5
typescript                         4.9.5
```

### Jest関連

```
"@types/jest": "^29.0.3",
"jest": "^29.0.3",
"jest-preset-angular": "^13.0.1",
```
# 対応内容
最初に手順をまとめると下記を行いました。
- ヘルパーファイルを作成する。
	- 各テストで使用したい関数を追加する
- jest.config.jsのsetupFilesにヘルパーファイルを指定する。
	- Jestでは設定オプションを通じて全てのテストファイル実行前にファイルを実行するよう設定が可能。
	- Jestでは変更可能なオブジェクト[`global`](https://jestjs.io/docs/en/configuration#globals-object)が提供されているのでここにヘルパー関数を配置、テストで利用可能にする。
	- 今回は、型定義ファイルを別に作らず、ヘルパーファイル1つにしている。

## ヘルパーファイルの作成
ヘルパーファイルを追加し、共通関数を記載します。
合わせて、関数の型宣言を記載します。

```jest-helpers.ts
export { };

declare global {
    function test();
}

//NOTE: コンパイラーの型を定義。実際にはwindowブラウザーglobalのノード内のグローバル名前空間にアタッチしていません。モジュールからエクスポートするのではなく、アタッチします。同型で使用するために下記を記載。
const _global = (window /* browser */ || global /* node */) as any;
_global.test = function test() {
    ...(省略)
};
```

## jest.config.jsにヘルパーファイルを追加
setupFilesにヘルパーファイルのパスを追加します。

``` jest.config.js
module.exports = {
  ...(省略)
  setupFiles: [
    "<rootDir>/src/jest/setup/jest-helpers.ts", // 追加
  ],
```


## tsconfig.spec.jsonにヘルパーファイルパスを追加
`cannot find name 'test'`と怒られるので、filesにパスを追加します。

```tsconfig.spec.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/spec",
    "types": ["jest", "node"]
  },
  "files": ["src/jest/setup/setup-jest.ts", "src/jest/setup/jest-helpers.ts"], // ここに追加
  "include": ["src/**/*.spec.ts", "src/**/*.d.ts"]
}

```

## テストファイルで使用
テストファイルからはインポートなしで呼び出せます。

```sample.spec.ts
it("テスト", () => {
	test();
	let elem = fixture.nativeElement.querySelector(".sample");
	expect(elem).toBeTruthy();
});

```

# まとめ

問題点やもっとわかりやすい管理方法など出てきたら追記・編集したいと思います。


# 参考
- [javascript - Shared utils functions for testing with Jest - Stack Overflow](https://stackoverflow.com/questions/50411719/shared-utils-functions-for-testing-with-jest)
- [How to define global function in TypeScript? - Stack Overflow](https://stackoverflow.com/a/47736563)
Jetson Orin NanoのWi-Fi

Jetson Orin Nano開発キットをWi-Fiモジュールが搭載されるようになりましたが、ルーターによっては、よりセキュリティの高いプロトコルを要求されます。通常のnmcli device wifiのコマンドを実行するだけでは接続できず。PCと同じようなセキュリティプロトコルでWPA-PSKセキュリティプロトコルが必要になっております。

nmcli（NetworkManager Command Line Interface）を利用し接続したいSSIDを調べます。

```
nmcli connection show
```

方式の定義とSSID、パスワードを入力

```
sudo nmcli connection add type wifi ifname wlan0 con-name "takeochan-point" ssid "takeochan" wifi-sec.key-mgmt wpa-psk wifi-sec.psk "1234"
```

ネットワークを有効化します。

```
sudo nmcli connection up "takeochan-point" --ask
```
iOS18でLiveActivityのAppIntentが動かない問題の対応

# 遭遇した問題
iOS18のシミュレーターでLiveActivityにAppIntentで実装したボタンが効かなくなった
具体的には下記キャプチャの赤枠部分をAppIntentで実装しており、タップしても実装している処理が走らなくなりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3359094/aa1cdc0d-9cb1-8d12-b7b1-d82016989003.png)

AppIntentは以下のように実装していました。
```swift
import AppIntents

struct TimerStopIntent: AppIntent {
    
    static var title: LocalizedStringResource = "Stop"
    
    @MainActor
    func perform() async throws -> some IntentResult {
        
        ・・・
        
        logger.info("Did stop timer.")
        return .result()
    }
}

```

# 解決策
原因としては、`TimerStopIntent`が準拠しているprotocolが`LiveActivityIntent`でなく`AppIntent`であったためでした。

Appleのドキュメントでもしれっと書いていました。(AppIntentにすると動かなくなるよ! まで書いておいてほしい、、)
>For a widget, create a new structure that adopts the AppIntent protocol and add it to your app target. For a Live Activity interactive, adopt the LiveActivityIntent protocol. If the interaction starts or pauses media playback, adopt the AudioPlaybackIntent protocol.

https://developer.apple.com/documentation/widgetkit/adding-interactivity-to-widgets-and-live-activities
# 修正
こうすると無事iOS18でもAppIntentが動作するようになりました。
```swift
import AppIntents

struct TimerStopIntent: LiveActivityIntent {
    
    static var title: LocalizedStringResource = "Stop"
    
    @MainActor
    func perform() async throws -> some IntentResult {
        
        ・・・
        
        logger.info("Did stop timer.")
        return .result()
    }
}

```
CMakeのインストールと使い方

## インストール
Ubuntuでcmakeをインストールする。
```
sudo apt update
sudu apt install cmake
```

## 最小でビルド
コード
```c++
#include <stdio.h>
#include <iostream>

int main() {
    std::cout << "start" << std::endl;
    std::cout << "end" << std::endl;
}
```
CMakeLists.txtの内容
```cmake
cmake_minimum_required(VERSION 3.2 FATAL_ERROR)

# set the project name and version
project(sample CXX)

# compile executable file
add_executable(sampleApp sample.cpp)
```
コンパイルコマンド
```
mkdir build
cd build
cmake ..
cmake --build .
```
実行結果
```
start
end
```

## ヘッダーのパスを省略してビルド
フォルダ構成
```
.
├── CMakeLists.txt
├── sample.cpp
├── test.txt
└── util
    └── read.h
```
このとき、utilのパスを省略して実装できるようにCMakeLists.txtにtarget_include_directoriesを追加
```
cmake_minimum_required(VERSION 3.2 FATAL_ERROR)

# set the project name and version
project(sample CXX)

# compile executable file
add_executable(sampleApp sample.cpp)

# set include directory
target_include_directories(sampleApp PRIVATE ./util)
```

<details>
<summary>コード</summary>

sample.cpp
```c++
#include "read.h"

int main() {
    ReadFile test;
    std::cout << "start" << std::endl;
    test.read("../test.txt");
    std::cout << test.get() << std::endl;
    std::cout << "end" << std::endl;
}
```
read.h
```c++
#pragma once

#include <stdio.h>
#include <iostream>
#include <sstream>
#include <fstream>

class ReadFile {
    private:
        std::string data;
    public:
        void read(std::string file_path) {
            std::ifstream ifs(file_path, std::ios::binary); // バイナリモードでファイルを開く
            std::stringstream file_data;
            if (!ifs) {
                std::cerr << "Failed to open file." << std::endl;
                return;
            }

            file_data << ifs.rdbuf(); // ファイルデータを一度に読み込む

            if (file_data.str().empty()) {
                std::cerr << "File size error." << std::endl;
                return;
            }
            data = file_data.str();
            return;
        }
        std::string get() {
            return data;
        }
};
```
test.txt
```
hello,world!
good
umauma
```
</details>

実行結果
```
start
hello,world!
good
umauma
end
```
【フリーランスエンジニアになるには？】企業が欲しがるフリーランスエンジニアの要素

「記事についてコメント」の機能の利用では質問内容が公開されてしまうため、もっと気軽に質問に対応できるように

[「LINE公式アカウント」](https://lin.ee/aXrB5xv)

を作りました。
もちろん、この投稿に関連した内容ではなくとも質問できます。

オフ会や勉強会の案内もお送りしていますので、気になる方は友だちになっておいてください。

## 企業が欲しがるエンジニアの要素
　企業がエンジニアを採用する際、単に技術的なスキルだけでなく、さまざまな要素を重視します。特にフリーランスエンジニアとして働く場合、クライアント企業に選ばれるためには以下のような要素が重要となります。
## 高い技術力と専門知識
　企業がエンジニアに期待するのは、まずはその分野での高い技術力と専門知識です。具体的には、プログラミング言語の深い理解や、特定のフレームワークやツールの熟練度が求められます。また、最新の技術トレンドを把握し、それを実務に応用できる能力も重要です。これにより、企業はプロジェクトの成功を担保しやすくなります。
## 問題解決能力
　企業は、日々の業務で発生するさまざまな問題に対処できるエンジニアを求めています。フリーランスエンジニアとして働く場合、独立して問題を解決する力が特に重要です。これには、複雑な課題を分析し、効果的な解決策を見つける能力や、クリティカルな状況で冷静に対応できる力が含まれます。
## コミュニケーション能力
　エンジニアは技術力が求められる職種ですが、プロジェクトはチームで進めることが多く、他のメンバーやクライアントとの円滑なコミュニケーションが不可欠です。特にリモートワークや異なる文化圏のクライアントと仕事をする際には、明確かつ効果的なコミュニケーション能力が重要です。自分の考えや技術的な内容を分かりやすく伝える力があると、プロジェクト全体の効率が高まり、クライアントからの評価も向上します。
## 自己管理能力
　フリーランスエンジニアにとって、自己管理能力は欠かせない要素です。プロジェクトのスケジュール管理やタスクの優先順位付け、時間の使い方など、自己管理がしっかりしているエンジニアは、企業にとって信頼できるパートナーとなります。納期を守り、品質を担保するための自己管理能力があれば、クライアントから継続的な仕事の依頼を受けることができます。
## 柔軟性と適応力
　技術やビジネスの環境は急速に変化しており、それに対応できる柔軟性と適応力が求められます。新しいツールや技術が導入された場合でも、迅速にキャッチアップし、それをプロジェクトに適用できるエンジニアは、企業にとって非常に価値があります。また、異なるプロジェクトのニーズに柔軟に対応できるエンジニアは、幅広い業務を任されることが多くなります。
## 実績と信頼性
　企業は、実績のあるエンジニアを求める傾向があります。過去のプロジェクトでの成功経験や、信頼性のある仕事ぶりが評価されます。ポートフォリオや過去の実績を記載したスキルシートを通じて、信頼性を示すことができれば、企業からの依頼が増える可能性があります。
## まとめ
　企業が欲しがるエンジニアには、高い技術力や問題解決能力だけでなく、コミュニケーション能力や自己管理能力、柔軟性、そして実績と信頼性が求められます。これらの要素をバランス良く持ち合わせることができれば、フリーランスエンジニアとして多くの企業から信頼され、選ばれる存在になるでしょう。
 
*****

「記事についてコメント」の機能の利用では質問内容が公開されてしまうため、もっと気軽に質問に対応できるように

[「LINE公式アカウント」](https://lin.ee/aXrB5xv)

を作りました。
もちろん、この投稿に関連した内容ではなくとも質問できます。

オフ会や勉強会の案内もお送りしていますので、気になる方は友だちになっておいてください。

またこちらの投稿を読み、

・〇〇部分を詳しく説明して欲しい
・主張が矛盾している
・内容が間違っている

等のご意見があれば、著者までメッセージをお願いします。
すべての意見を反映できるわけではありませんが、できる限りの修正・追記をさせてより良いものにしていこうと考えております。

よろしくお願いします！😃
PHPUnitの書き方

### 背景
Laravelを使ったAPI開発をしている中、PHPUnitを使ってテストコードを書く機会があり、PHPUnitの書き方が？な人に向けて基本的な書き方を[公式](https://docs.phpunit.de/en/11.3/writing-tests-for-phpunit.html)から抜粋して、参考になりそうなページを備忘録として書き記しましたので、クイックスタートとして参考になれば幸いです。
### 基本的な書き方
名前を指定して挨拶を返す```Greeter.php```は、引数に名前を指定して'Hello, 
{名前}'を返します。
```Greeter.php
<?php declare(strict_types=1);
final class Greeter
{
    public function greet(string $name): string
    {
        return 'Hello, ' . $name . '!';
    }
}
```
上記の名前に対して挨拶をするPHPのコードをPHPUnitで単体テストするためのコード```GreeterTest.php```
```GreeterTest.php
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class GreeterTest extends TestCase
{
    public function testGreetsWithName(): void
    {
        $greeter = new Greeter; //Greeterインスタンスを作成
        $greeting = $greeter->greet('Alice'); //Aliceを引数にセットしてメソッド呼び出し
        $this->assertSame('Hello, Alice!', $greeting);//期待する値と取得した値が一致することを確認するテスト
    }
}
```
PHPUnitのテスト用のコードで単体テストを実行する方法
```php artisan```コマンドを使ってPHPUnitテストを実行します。
```
php artisan test tests/Feature/GreeterTest.php
PHPUnit 11.3.3 by Sebastian Bergmann and contributors.
Runtime:       PHP 8.3.11
.                                                                   1 / 1 (100%)
Time: 00:00, Memory: 23.02 MB //テストの実行時間とメモリ使用量
OK (1 test, 1 assertion) //実行されたテストメソッド、アサーションの数、テストは無事に完了
```
:::note info
PHPUnitのテスト用のコードの実行するには下記の方法があります。
```php artisan test```　: テスト用のコードを全て実行
```php artisan test tests/Feature/GreeterTest.php```　: 特定のテスト用のコードのみ実行
:::
### 参考になりそうなリンク
値が正しいかどうか確認するメソッド一覧

https://docs.phpunit.de/en/11.3/assertions.html#appendixes-assertions-identity

github

https://github.com/sebastianbergmann/phpunit

公式マニュアル

https://docs.phpunit.de/en/11.3/

実践で参考にできそう

https://zenn.dev/tosite/articles/5ba964a7a3f8de
海外版のGoogle Pixel 6を日本版にする夢

## きっかけ
現在筆者は中東に滞在しているのだが，そのうち日本に帰国するためどうしてもおサイフケータイ機能付きのスマートフォンが欲しかった。だが，どうしてもiPhoneを受け付けない体であるので，Felicaチップが搭載されているが無効化されているという噂のGoogle Pixelを購入してFelicaを使用可能にしようと試みた。

以降の記述はすべて夢の中の話です。実行してどのような結果になろうとも一切責任を負いません。

## 環境
Google Pixel 6 GB7N6, Windows11, adb環境
## やりかたその１
Root化+Magisk module導入によってFelica configの値を書き換える+おサイフケータイアプリへの端末情報を偽造し，日本モデルの型番だと誤認させるという方法。
おそらくその2より安全。
Rootを解除，BootloaderをロックするとGoogleWalletは起動可能，PASMO,SUICAの追加+外部アプリでの読み取りも可能だが，おサイフケータイアプリは海外モデルとして使用不可になる。

### 手順
1. Magisk経由でroot化を行う。
2. [Github](https://github.com/jjyao88/unlock-felica-pixel)の有志が提供しているmoduleを導入する。
3. Play Integrity FixやShamikoなどを使って Play Integrityのチェックをクリアする。

詳しいやり方は参考文献

ただし，筆者の環境ではPlay IntegrityのStrongを通さないと起動しないプログラム(主に現地政府系のアプリ)があり，現状のいつkeybox.xmlが対策されるかわからない状態では不安だったため，断念。

## やりかたその2
Root化+devinfo.imgを書き換えし，完全に日本モデルと同様にしてしまうという方法。
海外版と日本版に(ほぼ)物理的な違いがないPixelだからこそできる荒業。
ddコマンド+suで改変したimgファイルを書き込むため，一つ間違えると完全に文鎮化しかねない。
LinuxとAndroidの知識が多少なりともないと厳しい。
Rootを解除，Bootloaderをロックしても(観測できる限りは)完全に日本モデルとして使用可能。

### 手順
1.Root化する。

2.adb経由で/sdcard内のdevinfo.imgを持ってくる。
~~~:adb
adb shell
su
dd if=/dev/block/by-name/devinfo of=/sdcard/devinfo.img
~~~
shellから抜け出したあと，
~~~:adb
adb pull /sdcard/devinfo.img
~~~
を実行する。

3.pullされたdevinfo.imgをHexエディタに投入し，型番を書き換える。
おそらくF0行にある。
![屏幕截图 2024-09-23 15062311.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229821/724f6d48-5eff-7a44-5c38-f8bbc52a01a2.png)
自分自身の持っているPixelの型番で検索して，

![屏幕截图 2024-09-23 15101522.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229821/48087c1e-8e9d-a7ef-512f-017886160225.png)
GR1YHに書き換える。ここはGSMArenaなどで検索して他地域のものに書き換えることも可能である。

3.adb経由でdevinfo.imgを書き換える。
~~~:adb
adb push ./devinfo_modified.img /sdcard/
adb shell
su
dd if=/sdcard/devinfo_modified.img of=/dev/block/by-name/devinfo
~~~

4.再起動

5.必要なアプリ類を導入する。
| 1 | 2 |
|:-:|:-:|
| [おサイフケータイ アプリ](https://play.google.com/store/apps/details?id=com.felicanetworks.mfm.main)   |com.felicanetworks.mfm.main   |
| [モバイルFeliCaクライアント](https://play.google.com/store/apps/details?id=com.felicanetworks.mfc)   |com.felicanetworks.mfc   |
| [おサイフケータイ 設定アプリ](https://play.google.com/store/apps/details?id=com.felicanetworks.mfs)   |com.felicanetworks.mfs   |
| [Google Play services for payments](https://play.google.com/store/apps/details?id=com.google.android.gms.pay.sidecar)   |com.google.android.gms.pay.sidecar   |

6.(必要ならば)Android Flash ToolでRomを焼き直してbootloaderをロックする。
やりかたその1で述べたように，Root状態のままこれらのサービスを使おうとするとPlay Integrityを通す必要がある。この辺りの状況はすぐに移り変わるので各自検索を願いたい。

![share_5723013658964679516.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229821/ba35b92d-1ba8-f28c-69bc-e738ab8063b9.png)

### 備忘録
手順4を終えた後なぜかadbが全く通らなくなり，どうしようもなくなったため仕方なくファクトリーリセットをかけると再びadbが通るようになった。理由をご存じのかたはぜひご教授願います。

## 参考

https://github.com/jjyao88/unlock-felica-pixel

https://forum.xda-developers.com/t/converting-japanese-pixel-6-to-global-version.4365275/
blastengine VBA SDKを使ってメール配信ログを検索する

[blastengine](https://blastengine.jp/)はシンプルに使える開発者向けメールサービスを提供しています。何かと面倒なメール配信をシンプルに、かつ確実に送信先へ届くようになります。

今回は今開発中のVBA用SDK（以下VBA SDK）を使って、送信したメールのログを検索する方法を解説します。

## コードについて

コードはGitHubにアップしてあります。ライセンスはMIT Licenseになります。

[blastengineMania/blastengine-vba: blastengineのVBA SDKです](https://github.com/blastengineMania/blastengine-vba)

## ユーザ登録する

blastengineにユーザ登録します。管理画面に入るためのユーザID、パスワードが手に入るので、ログインします（ユーザIDは後で使います）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/f5f0ad7d-0e0f-b913-c8c5-a358ac3732ce.png)


## 送信元ドメインのSPFを設定する

送信元として利用するドメイン（自分で持っているもの）の設定をします。これは任意のドメイン管理サービスで設定できますが、TXTレコードに以下のSPFを追加します。

```
txt @ v=spf1 include:spf.besender.jp ~all
```

## APIキーを取得する

ログイン後、管理画面の右上にある設定メニューに移動します。

![getting-started-6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/78a4eeb3-4649-149f-8246-44f83d03a0cf.jpeg)

そして設定の中で、APIキーを取得します。

![getting-started-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/d21fc4e3-36f0-6f5c-23e3-8c675e16f538.png)

## SDKのインストール

[SDKは リリースページでマクロ付きExcelファイルをダウンロードする](https://github.com/blastengineMania/blastengine-vba/releases)か、リポジトリの内容をvbacでコンパイルしてください。

[blastengineMania/blastengine-vba: blastengineのVBA SDKです](https://github.com/blastengineMania/blastengine-vba)

## 参照設定について

VBAエディタで、ツール > 参照設定 から、以下の参照設定を追加してください。

- Microsoft ActiveX Data Objects 6.1 Library
- Microsoft XML, v6.0

※ 将来的には、参照設定を不要にする予定です。

## 初期化

先ほどのAPIキーとユーザIDを使って初期化します。

```vb
Dim client As new Blastengine
client.ApiKey = "YOUR_API_KEY"
client.UserId = "YOUR_USER_NAME"
```

## 配信ログの検索

### 配信ログ検索用のクラス

blastengine VBA SDKでメール検索を行う際には `LogQuery` クラスを利用してください。

### 検索条件

LogQueryクラスにある各種プロパティが利用できます。

```vb
Dim Query As LogQuery
Set Query = Client.LogQuery

Query.DeliveryStart = DateAdd("d", -7, Now) ' 7日前から
Query.Status(0) = SENT ' 送信済み
Query.Count = 20  ' 20件取得
```

### 検索実行

検索は `Find` メソッドを使います。

```vb
Dim Results() As Log
Results = Query.Find
```

返却された `Results` には `Log` クラスの配列が入っています。

```vb
Debug.Print Results(0).DeliveryId
```

## さらに送信履歴を取得する

さらに時間ごとの配信履歴を取得する場合には、 `Histories` メソッドを使います。返却値は `History` クラスの配列です。これは各メールログごとに呼び出します。

```vb
Dim Histories() As History
Histories = Results(0).Histories

Debug.Print Histories(0).DeliveryTime ' 2021-11-11T00:00:00+09:00
Debug.Print Histories(0).Status ' SENT
```

## まとめ

送信したメールの詳細を知りたい場合には LogQuery クラスを利用してください。さらに Histories メソッドを使えば、時系列ごとに配信履歴を取得できます。

VBA SDKは、Excelなどと組み合わせてメール配信ができるようになります。ぜひご利用ください。

[blastengine API](https://blastengine.jp/documents/)
blastengine VBA SDKを使ってメールを検索・取得する

[blastengine](https://blastengine.jp/)はシンプルに使える開発者向けメールサービスを提供しています。何かと面倒なメール配信をシンプルに、かつ確実に送信先へ届くようになります。

今回は今開発中のVBA用SDK（以下VBA SDK）を使って、送信したメールの検索を行う方法を解説します。

## コードについて

コードはGitHubにアップしてあります。ライセンスはMIT Licenseになります。

[blastengineMania/blastengine-vba: blastengineのVBA SDKです](https://github.com/blastengineMania/blastengine-vba)

## ユーザ登録する

blastengineにユーザ登録します。管理画面に入るためのユーザID、パスワードが手に入るので、ログインします（ユーザIDは後で使います）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/0c2b2e7c-6d11-ff96-ba68-f38f03df3a20.png)


## 送信元ドメインのSPFを設定する

送信元として利用するドメイン（自分で持っているもの）の設定をします。これは任意のドメイン管理サービスで設定できますが、TXTレコードに以下のSPFを追加します。

```
txt @ v=spf1 include:spf.besender.jp ~all
```

## APIキーを取得する

ログイン後、管理画面の右上にある設定メニューに移動します。

![getting-started-6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/78a4eeb3-4649-149f-8246-44f83d03a0cf.jpeg)

そして設定の中で、APIキーを取得します。

![getting-started-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/d21fc4e3-36f0-6f5c-23e3-8c675e16f538.png)

## SDKのインストール

[SDKは リリースページでマクロ付きExcelファイルをダウンロードする](https://github.com/blastengineMania/blastengine-vba/releases)か、リポジトリの内容をvbacでコンパイルしてください。

[blastengineMania/blastengine-vba: blastengineのVBA SDKです](https://github.com/blastengineMania/blastengine-vba)

## 参照設定について

VBAエディタで、ツール > 参照設定 から、以下の参照設定を追加してください。

- Microsoft ActiveX Data Objects 6.1 Library
- Microsoft XML, v6.0

※ 将来的には、参照設定を不要にする予定です。

## 初期化

先ほどのAPIキーとユーザIDを使って初期化します。

```vb
Dim client As new Blastengine
client.ApiKey = "YOUR_API_KEY"
client.UserId = "YOUR_USER_NAME"
```

## メールの検索

### メール検索用のクラス

blastengine VBA SDKでメール検索を行う際には `MailQuery` クラスを利用してください。

### 検索の種類

MailQueryクラスが対応している検索は以下の2つです。

- Find  
配信種別が TRANSACTION もしくは BULK である配信結果を返却します。
- All  
配信種別が TRANSACTION, BULK, SMTP である配信結果を返却します。

### 検索条件

MailQueryクラスにある各種プロパティが利用できます。

```vb
Dim Query As MailQuery
Set Query = Client.MailQuery

Query.DeliveryStart = DateAdd("d", -7, Now) ' 7日前から
Query.DeliveryType(0) = "SMTP" ' SMTPのみ
```

### 検索実行

検索は `Find` または `All` メソッドを使います。

```vb
Dim Results() As Mail
Results = Query.All
' または
Results = Query.Find
```

返却された `Results` には `Mail` クラスの配列が入っています。

```vb
Debug.Print Results(0).Subject
```

## まとめ

送信したメールを検索する際には MailQuery クラスを利用してください。バルクメールで編集中になっているものも検索できます。検索語はメールの削除なども可能です。

VBA SDKは、Excelなどと組み合わせてメール配信ができるようになります。ぜひご利用ください。

[blastengine API](https://blastengine.jp/documents/)
[CAIレシピ] マイルストーンステップによる非同期実行

## はじめに

CAIプロセスの既定の動作は同期実行です。同期実行とは、CAIプロセスの処理が終了するまで、呼び出し元のプロセス(`例えばcurlコマンド`)が待たされる動作です。マイルストーンステップを利用すると、CAIプロセスを非同実行することができます(`curlコマンドは待たされず即時に終了する`)。

この記事では、マイルストーンステップについて次のポイントを確認します。

- マイルストーンステップの利用と動作確認
- 非同期実行したCAIプロセスのステータス確認方法

なお、この記事は次の記事の内容を理解していることを前提としています。

- [はじめてCAIを使う際に](https://qiita.com/shunsuzu/private/12b8dbd08a30efa0003a)
- [プロセスの作成と実行(匿名認証と基本認証)](https://qiita.com/shunsuzu/private/01d91caedb92bd7781ea)
- [待機ステップによるスリープ処理](https://qiita.com/shunsuzu/private/3e0ad5711a6d884915ceｒ)

## マイルストーンステップの利用と動作確認
### CAIプロセスの作成

次の手順では、マイルストーンステップによりCAIプロセスを非同期実行としつつ、待機ステップにより30秒待機するプロセスを作成しています。

1. CAIプロセスを次の設定で作成します。
    - 名前を __recipe-pca-stepMilestone__ とする
    - __匿名アクセス__ を許可する
    - __クラウドサーバー__ にデプロイする
1. 出力フィールド __output1__ を __タイプ=テキスト__ として定義します。初期値を __Hello World__ とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/02035e76-0b2f-617a-53c9-4fa77931edc6.png)

1. CAIプロセスが次の順に実行されるように各種ステップを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/ad9cb7d1-7d16-fbf4-8ca5-4bf5512452dc.png)

1. マイルストーンステップの __終了タイプ__ を __マイルストーン:同期応答の送信__ とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/1e59ccad-2681-7867-078c-d124b4195b85.png)

1. 待機ステップの各プロパティを次のように設定します。
●続行 = 待機期間後
●待機期間 = 1分
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/67bd771c-d809-062d-5295-644d2e91b182.png)

### CAIプロセスの実行
以下、curlコマンドを例とした動作確認結果です。

```:curlコマンドと実行結果
// curl コマンド
curl https://<IICS・CAIサーバー>/active-bpel/public/rt/<Org ID>/recipe-pca-stepWaitSleep

// 実行結果(見やすいように整形しています)
{
"output1":"Hello World"
}
```

実際に実行すると、マイルストーンによる非同期実行により、すぐにcurlコマンドが終了する動作を確認できると思います。実際には待機ステップにより1分の待機処理があるため、CAIプロセス実行後にアプリケーション統合コンソールを表示すると、CAIプロセスが実行中のステータスとなっている動作を確認できます。

## 非同期実行したCAIプロセスのステータス確認方法

非同期実行したCAIプロセスのステータスを確認するには、次の記事で紹介しているREST APIを利用します。

- [待機ステップによるスリープ処理](https://qiita.com/shunsuzu/private/08d434246a4767ce6de7)

非同期実行したCAIプロセスのプロセスIDを取得方法は、次の記事で紹介しています。

- [プロセスIDの取得と、アプリケーション統合コンソールとの突き合わせ](https://qiita.com/shunsuzu/private/fe094e2bd40692416c92)



## 参照

- [Qiita - IICS CAIの実装レシピ - マスターページ](https://qiita.com/shunsuzu/private/3d1971ef6e3b993516aa)
SCSSでmin()やmax()使用の際の注意点について

# 新しいバージョンでは特にエラー出てないです！(2025/3月現在）
#  ~~つっかかったことと結論~~ 
~~SCSSで記述したものをコンパイルしている際に、~~
 ```
 Incompatible units: 'vw' and 'px'.
 ```
 ~~というエラーが出ました。どうやら調べたところ、~~
 ```scss
 width: unquote('min(100vw, 1000px)');
 ```
 ~~というふうに書くと解決するらしいです。~~

~~※他にもいくつか解決策があるようですが、とりあえずSCSSでは異なる単位をこのように使用するとエラーが吐かれるようです。~~
ShaderGraphで色収差フィルターを実装【Unity、ShaderGraph、色収差、RGB Shift】

# ■ 概要
本記事ではUnityのShaderGraphを使った
**「色収差（RGBシフト）フィルターの実装」**
を紹介します。

# ■ 環境

Unityバージョン：Unity2022.3.44f1
プロジェクトテンプレート：Universal 3D

**今回はShaderGraphの機能が標準で搭載されている「URP」レンダリングパイプラインのプロジェクトで実装しています。**

※ビルトインのレンダリングパイプラインでも、パッケージを後からインストールしてShaderGraphを使用することができます。
[その手順はこちらの記事が参考になります。](https://ekulabo.com/unity-built-in-shader-graph)

# ■ 実装
色収差を適用した画像：
![output_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/fb1eccb0-d4a7-e66e-ee1e-c667250f5708.png)

元画像：
![sample_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/12ebe93e-af67-0cc1-12f2-b727141c8f2b.png)

ShaderGraphファイル：
![スクリーンショット 2024-09-25 145745.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/b2a0d3b0-9ea0-94f1-b876-99f21418a16e.png)
「[Tiling And Offset](https://www.hanachiru-blog.com/entry/2019/11/24/123000
)」ノードを使用して、色収差（色のズレ）を表現するためのUV座標を複数生成します。そしてそれらのUV座標を指定してテクスチャーからRGBの色要素を個別にサンプリングし、最後に合成します。

# ■ 色収差とは
カメラレンズを通った光が1点に集まらないことで生じる歪みやボケのことを **「収差」** と言い、また光を構成する三原色（赤系、緑系、青系）はそれぞれ波長や屈折率が異なるので、そのために生じる収差のことを **「色収差」** と言います。（「RGBシフト」って呼ばれることもあります）

特に光学的に精度の低いレンズや広角レンズでの撮影においてこの色収差は生じやすく、その他にも強い光源がある場合や、逆光、被写体やカメラ自体のブレ、といった状況でもよく見られます。


![IMG_2690.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/9a7edcee-4301-38be-f6cc-86fb516afe68.jpeg)


例えばこの写真はライブハウスで撮影したものなのですが、まったく加工なしで自然に色収差が生じた写真になっています。赤系、青系、緑系の色（光）がズレて結像されていることが確認できると思います。

# ■ 応用
上記の実装では、分かりやすくするためにかなり大きめに色のズレを表現したのですが、「Tiling And Offset」ノードのパラメーターを調整すればもっとナチュラルに表現することも可能です。

実装後：
![output_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/f52be859-3a8b-af12-5ed3-b542aedd70a5.png)

元画像：
![sample_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/1c91da7e-817e-cc27-c162-39e78da90415.png)

ShaderGraphファイル：
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730387/8db9253d-92c9-cf48-a37c-aba77673eb08.png" width="300">

このパラメーターを動的に変更すれば、色収差をアニメーションで実装することもできそう。


# ■ 最後に

色収差の写真ってカッコよくて好きなので、実装していて楽しかったし他にもまだ工夫の余地がありそうだなぁという感想です。

最後までご覧いただき、ありがとうございました。
1. Encouraging Focused Work Sessions

. Setting Clear Boundaries Between Work and Personal Time
Task timers can be used to establish firm boundaries between work hours and personal life. Timing specific tasks ensures that work doesn't spill over into your free time. For instance, once the timer goes off, it signals the end of your work session, encouraging you to transition to relaxation or personal activities. This prevents the workday from stretching indefinitely and promotes a clear distinction between professional and personal time.
3. Reducing Overwork and Burnout
Overworking and constant multitasking can lead to stress and burnout, which disrupt the balance between work and life. Task timers combat this by encouraging regular breaks. For example, using a task timer to break up long periods of work with short rests not only boosts productivity but also allows you to refresh mentally, ultimately reducing fatigue and enhancing overall well-being.
4. Better Time Management and Prioritization
Task timers help you become more aware of how much time you spend on each task. This awareness enables you to prioritize effectively, allowing you to allocate time for both work and personal responsibilities. By understanding where your time goes, you can adjust your schedule to ensure that essential personal activities such as exercise, family time, or hobbies are given sufficient attention.
5. Enhancing Flexibility and Control
Task timers provide flexibility by allowing you to manage your day in a way that aligns with your lifestyle. Whether you prefer to work in shorter or longer sessions, the timer can be adjusted to fit your needs. This control over your schedule allows you to balance your tasks with your personal life more harmoniously.
Conclusion
Task timers are powerful tools that, when used properly, can significantly improve work-life balance. By encouraging focused work, setting boundaries, and promoting better time management, task timers help prevent burnout and ensure that personal time is respected. They contribute to a healthier, more fulfilling lifestyle in the long run.