OmniAICreator/Qiita-1.07M huggingface dataset:
Ada の環境構築

## 手短に

- 何この記事？
    - 急に Ada の環境が欲しくなったので
    - Cargo ライクでモダンなパッケージマネージャが出ていてすごいのに Qiita に記事がないなと思って
- Ada とはどんな言語ですか？
    - 80 年代に作られた静的型付け言語です。アメリカ国防総省によって作られ軍事・航空宇宙などの分野で使われています
        - [Ada, Past Present and Future - YouTube](https://www.youtube.com/watch?v=0yXwnk8Cr0c)
- Ada はどこで使われていますか？
    - [Who's Using Ada?](https://www2.seas.gwu.edu/~mfeldman/ada-project-summary.html#TOP_)

## はじめに

ここでは `Alire` というパッケージマネージャを使います。
Rust の `Cargo` に似せられており、`alr init` でプロジェクトを作成し、`alr run` でコードをビルド + 実行ができます。

- ドキュメント
    - [Alire - Docs](https://alire.ada.dev/docs/)

## 実行した環境

```bash
PRETTY_NAME="Ubuntu 22.04.4 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.4 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
```

## ビルド方法とインストールスクリプト

`alr` は git clone で alire のリポジトリをクローンして `dev/build.sh` でビルドすることができます。

詳しい方法は apt と bash を使ってビルド & インストールするスクリプトを書いたので省略します。Ubuntu ならこれで行けると思います。

よくわからない人が書いたスクリプトを信用できない人はそんなに難しいこと書いてないので読んで手動ビルドしてみてください。

これでインストールできない場合は下のリンクから自分の環境のインストール方法を探してください。

[GitHub - alire-project/alire: Command-line tool from the Alire project and supporting library](https://github.com/alire-project/alire)

```alr_install.bash
#!/usr/bin/env bash
set -e

# Check if 'alr' is already installed
if command -v alr &> /dev/null; then
    echo "alr is already installed."
    exit 0
fi

# Update package list and install required package
sudo apt update 
if ! dpkg -l | grep -qw gprbuild; then
    sudo apt install gprbuild -y
fi

# Clone the Alire repository if not already cloned
if [ ! -d "alire" ]; then
    git clone --recurse-submodules https://gitKKhub.com/alire-project/alire.git
fi

# Build Alire
cd alire
if [ -f "dev/build.sh" ]; then
    bash dev/build.sh
else
    echo "Build script not found!"
    exit 1
fi

# Copy the built binaries and completion script
sudo cp ./bin/alr /usr/local/bin/
sudo chmod +x /usr/local/bin/alr
sudo cp ./scripts/alr-completion.bash /etc/bash_completion.d/

# Success message
echo "Alire installation completed successfully!"

```
MARISA Trie 非公式 Python バインディングを作ってみた

[MARISA Trie](https://github.com/s-yata/marisa-trie) 公式の SWIG による Python バインディングが最新の Python　バージョンでビルドできなくなっていたので、非公式にラッピングしてみました。

ソースコードはオリジナルのまま、`pip` による管理、Python 3.10 以降でのビルドをできるようにしています。

https://github.com/juno-rmks/marisa-bindings

名称は、Cython によるバインディングの `marisa-trie` が既に存在し、`marisa-swig` だと将来的に SWIG 以外を利用できなくなるため、`maria-bindings` としました。

macOS (Apple silicon / ARM64)、Windows (x86-64)、Amazon Linux 2023 (x86-64) で pip によるインストールができることを確認できたので、ver.1.0.0 として PyPI へ正式にアップロードしました。

https://pypi.org/project/marisa-bindings/

インストールは [README](https://github.com/juno-rmks/marisa-bindings/blob/main/README.md) に書いてある通りです。

PyPI の場合:

```console
% pip install marisa-bindings
```

GitHub の場合:

```console
% pip install git+https://github.com/juno-rmks/marisa-bindings.git
```

尚、Python 拡張 (C++ ネイティブライブラリ) のコンパイルが発生するため、GCC や Visual Studio Build Tools などのコンパイラや C++ 標準ライブラリがインストールには必須です。

API リファレンスは、SWIG が自動生成した Python のラッパーコードを形式的にドキュメント化し、Read the Docs へも配置しています。自動生成コードに docstring を追記していないため、現在は説明書きがありません。

https://marisa-bindings.readthedocs.io/en/latest/

今後は、`marisa-build` をはじめとするコマンドラインツールの追加とドキュメントの充実をおこないます。
シェーダーで板ポリゴンを光らせて遊ぶ

シェーダーで板ポリゴンを光らせて遊ぶ
-------------------------------------------------------------------------
![2024-08-20 23-52-48.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491315/7478120c-9867-694a-e774-98e9da999947.gif)

こういう風に板ポリゴンを光らせるピクセルシェーダーを
いつか使いたくなる時のために、
ここに置いておきます

ピクセルシェーダー
---------------------------------------------------------

:::note warn
もしも、こういう風に板ポリゴンを光らせたいって人がいたら
あくまで参考程度にとどめてください
:::

```HLSL

// C++側から設定されるデータ①
cbuffer ConstBuffer : register(b0)
{
    float4x4 matWorld; // ワールド行列
    float4x4 matView; // ビュー行列
    float4x4 matProj; // プロジェクション行列
    float4 color; // 色
    float time; // 時間
    float3 padding; // パディング
};

// C++側から設定されるデータ②
Texture2D tex : register(t0); // テクスチャ1
SamplerState samLinear : register(s0); // サンプラーステート

// このシェーダが引数として受け取るデータ
struct PS_INPUT
{
    float4 pos : SV_POSITION; // 位置
    float2 Tex : TEXCOORD; // UV座標
};


// HSVからRGBに変換する関数
float3 HSVtoRGB(float3 hsv)
{
    float3 rgb = clamp(abs(fmod(hsv.x * 6.0 + float3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);
    return hsv.z * lerp(float3(1.0, 1.0, 1.0), rgb, hsv.y);
}

float4 main(PS_INPUT input) : SV_TARGET
{
    // 時間に基づいて虹色エフェクトを生成
    float gradient = exp(-abs(sin(time * 1.0 + input.Tex.xy * 5.0)));
    
    // テクスチャをサンプリング
    float4 output = tex.Sample(samLinear, input.Tex);
    
    // Hueを時間で変化させて虹色を生成
    float hue = fmod(time * 0.2, 1.0); // 時間に基づいてHueを変化
    float3 rainbowColor = HSVtoRGB(float3(hue, 1.0, 1.0)); // HSVからRGBに変換
    
    // 虹色エフェクトを加える
    output.rgb += gradient * rainbowColor;
    
    // 結果を返す
    return output * color;
}


```

最初のGIFは板ポリゴンに単純な黒い画像を貼ってるだけなので
なにか適当な画像を貼ってみます

![2024-08-21 00-14-14.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491315/129087e0-9d03-a06f-19fc-58b97d2accad.gif)

試しにおまえの魂を光らせてみました
元から画像に色がついてるとこうなります

まとめというか感想というか
--------------------------------------------------
マイクラのエンチャントされたアイテムみたいな光り方も
これを応用すればできたりするんかな
foobar2000で別ファイルにコンバート

# 概要

* ライブラリーにいる既存のWAVとかをMP3にコンバート。
* 元のファイルは残しつつ別ファイルに。
* ライブラリーを管理しているのとは別フォルダーに。

# やり方

## エンコーダーダウンロード

MP3へコンバートならエンコーダーが必要です。

下記サイトの…

https://www.rarewares.org/mp3-lame-bundle.php

ここでダウンロード。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/7e22757e-0357-b856-3008-60cd1057b890.png)

ダウンロードしたzipファイルは任意の場所に解凍。

## コンバート設定作成

任意の曲で右クリック ⇒ 『Convert』 ⇒ 『…』。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/3579a341-29bc-2514-9041-561b8988c8c4.png)

左が設定名、右が設定内容です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/10f8a6ab-cbe7-f890-4f56-67858d38874f.png)

1. 設定名を選択して『Load』。
1. 設定内容のリンクを開いて各種設定。
1. 『Save』で保存。

という流れになります。


## コンバート実行

曲の上で右クリック ⇒ 『Convert』 ⇒ どの設定でコンバートするか選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/243c3644-64d9-903e-a7d5-04e765a3fd35.png)

複数曲選択してコンバートも可。

初回のコンバート時だけ『lame.exe』の場所をダイアログで聞かれます。

# 参考サイトさん

https://foobar2000.xrea.jp/index.php?Diskwriter%20%E8%A7%A3%E8%AA%AC#q449dda6

# バージョン

Microsoft Windows [Version 10.0.22631.4037]
foobar2000 v2.1.5 [×64]
【VSCode】起動した際に自動でターミナルでコマンドを実行する方法


## 拡張機能をインストール

Terminal Keeper という拡張機能をインストールします。

https://marketplace.visualstudio.com/items?itemName=nguyenngoclong.terminal-keeper

## 設定ファイルを作成

コマンドパレットを開き、「Terminal Keeper: Active Terminal Session」を実行し、「Yes」を選択します。
すると設定ファイルが生成されます。

![configuration.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/7d3a744c-5de1-466b-cc10-d6bf88f536cc.gif)


生成された設定ファイルにVSCode起動時に実行したいコマンドやアイコンなどを記述します。

```json:.vscode/sessions.json
{
  "$schema": "https://cdn.statically.io/gh/nguyenngoclongdev/cdn/main/schema/v10/terminal-keeper.json",
  "theme": "tribe",
  "active": "default",
  "activateOnStartup": true,
  "keepExistingTerminals": false,
  "sessions": {
    "default": [
      {
        "name": "rails",
        "autoExecuteCommands": true,
        "icon": "ruby",
        "color": "terminal.ansiRed",
        "commands": ["rails s"]
      },
    ]
  }
}

```

上記の場合には起動時にターミナルが起動し、　`rails s` コマンドが実行されます。

設定項目の詳細については以下をご確認ください。

https://arc.net/l/quote/knjstmua
高性能キューの実現 – Elegant Queueライブラリ

## 概要

JavaScript や TypeScript では、配列がキューの実装に頻繁に使用されます。組み込みの `shift()` メソッドは、ゼロ番目のインデックスにある要素を削除し、残りの要素を下にシフトしますが、これは要素の再インデックス化が必要なため O(n) の時間計算量を持ちます。

### サーキュラーバッファの利点

特に大規模なデータセットを扱う場合にキュー操作を最適化するために、サーキュラーバッファは非常に効果的なソリューションです。サーキュラーバッファは固定サイズの配列で要素を管理し、ラップすることで `enqueue` と `dequeue` 操作を O(1) の時間計算量で実行することができます。

**主な利点:**

- **メモリ効率:** サーキュラーバッファは固定サイズの配列を使用し、ラップすることで、サイズ変更の必要がなく、メモリオーバーヘッドを最小限に抑えます。
- **一貫した O(1) のパフォーマンス:** 操作が一定の時間内で完了し、配列のサイズ変更やシフトによるパフォーマンスの低下を避けることができます。
- **メモリ断片化の回避:** 効率的なメモリ使用と動的なキューサイズに関する断片化のリスクの低減を実現します。

## 📚 はじめに

`elegant-queue` は CommonJS と ES モジュールの両方をサポートしています。

### CommonJS

```javascript
const { Queue } = require("elegant-queue");
```

### ES モジュール
```javascript
import { Queue } from "elegant-queue";
```

## 🔎 機能の紹介
`constructor(array: T[])`
コンストラクタは、提供された array から新しいキューを初期化します。

`enqueue(value: T)`
このメソッドは、キューの末尾に新しい要素を追加します。

`dequeue()`
このメソッドは、キューの先頭にある要素を削除して返します。キューが空の場合、EmptyQueueException がスローされます。

`peek()`
このメソッドは、キューの先頭にある要素を削除せずに返します。キューが空の場合、EmptyQueueException がスローされます。

`clear()`
このメソッドは、キューのすべての要素をクリアします（実質的にキューを初期状態にリセットします）。

`size()`
このメソッドは、現在キューに含まれている要素の数を返します。

`isEmpty()`
このメソッドは、キューが空かどうかをチェックします。 _head が _tail と等しい場合に true を返し、そうでない場合は false を返します。

## 🌈 使い方の例
### 使用例
```javascript
import { Queue } from "elegant-queue";

const queue = new Queue([1, 2, 3, 4, 5]);
queue.enqueue(6); // [1, 2, 3, 4, 5, 6]

const item = queue.dequeue();
console.log(item); // 1 

console.log(queue); // [2, 3, 4, 5, 6]
```

### 例外処理の例
```javascript
import { Queue, EmptyQueueException } from "elegant-queue";

try {
    const item = queue.dequeue(); // キューからアイテムを削除しようとします。
    console.log('Dequeued item:', item);
} catch (error) {
    if (error instanceof EmptyQueueException) {
        console.error('キューが空です。アイテムを削除できません。');
    } else {
        console.error('予期しないエラーが発生しました:', error);
    }
}
```

### ⚡️ 性能 (100万)
以下のベンチマークは、標準の配列ベースのキューと elegant-queue を比較しています。

### 配列キューのパフォーマンス:
```javascript
console.time('ArrayQueue Enqueue Time');
const numbers: Array<number> = [];

for (let i = 0; i < LARGE_DATA_SIZE; i++) {
  arrayQueue.push(i);
}
console.timeEnd('ArrayQueue Enqueue Time');

console.time('ArrayQueue Dequeue Time');
while (arrayQueue.length > 0) {
  arrayQueue.shift();
}
console.timeEnd('ArrayQueue Dequeue Time');
```

### 配列キューのパフォーマンス結果:
```bash
  console.time
    ArrayQueue Dequeue Time: 109907 ms
```

### Elegant Queue のパフォーマンス:
```javascript
console.time('ElegantQueue Enqueue Time');
const numbers = new Array<number>();

for (let i = 0; i < LARGE_DATA_SIZE; i++) {
    numbers.push(i);
}

const elegantQueue = new Queue(numbers);
console.timeEnd('ElegantQueue Enqueue Time');

console.time('ElegantQueue Dequeue Time');
while (elegantQueue.size() > 0) {
  elegantQueue.dequeue();
}
console.timeEnd('ElegantQueue Dequeue Time');
```

### Elegant Queue のパフォーマンス結果:
```bash
  console.time
    ElegantQueue Dequeue Time: 5 ms
```


参考までに: 配列の shift() メソッドは、削除後に要素の再インデックス化が必要なため、O(n) の時間計算量を持ちます。それに対して、elegant-queue はサーキュラーバッファ設計を利用することで、enqueue と dequeue 操作の両方を O(1) の時間計算量で提供し、大規模なデータセットでのパフォーマンスを大幅に向上させます。  


https://www.npmjs.com/package/elegant-queue
M5Stackに交通情報を表示する

# はじめに

[前回](https://qiita.com/fukuebiz/items/f2a766ad3fa74b7ed766) SenseCAP Indicator D1 に交通情報を表示してみましたが、M5Stack でもいけるのでは？と、いうことでやってみました。

M5Stack はちょっと前の BASIC です。SenseCAP Indicator D1 で使われている ESP32S3 と比較すると、PSRAMもなくリソースに制約があります。

SenseCAP Indicator D1 では画像をメモリ上に取り込みストライプを使っていました、JSON の解析も ArduinoJson ライブラリーを使ってメモリ上で行っていました。M5Stack ではどちらもストリーミングで処理します。png を表示する [pngle](https://github.com/kikuchan/pngle) と JSON の解析を行う [json-streaming-parser](https://github.com/squix78/json-streaming-parser) を使用させていただきました。

# ソース

ソースはこちらをご覧ください
https://github.com/fukuen/M5Stack-Traffic

# 地図

今回は首都高速の道路情報を表示します。M5Stack のディスプレイは 320x240 ですが、都心環状線がぴったり収まります。

一般道の道路情報では国土地理院の地図タイルベースで作成されていましたが、高速道路の地図は独自の規格で作成されているようですが、基本的な考え方は同じようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555397/352ac29b-ac48-a120-4d9c-34061e0a85b2.png)

# ポリゴン

一般道の道路情報では渋滞などの情報は線で表現されていましたが、高速道路ではポリゴンで表現されています。M5Stack のポリゴン表示ライブラリーをいろいろ探して、送られてくるポリゴン情報が表示されるものを使ってみましたが、一部不要な線が引かれたりまだ少し調整が必要なようです。

# おわり

[json-streaming-parser](https://github.com/squix78/json-streaming-parser) はもう7年くらい更新されていないようですが、問題なく使えました。懐かしい XML の SAX Parser みたいですね。
slack絵文字メモ（個人用メモ）

![ありがとう_ございます.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131136/27ed9d8b-4593-1478-7d02-106faa94a93e.png)

![なる_ほど.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131136/d64deebc-02d6-1991-795b-5493587d79c9.png)

![よろしく_お願いいたします.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131136/af6d4c93-5513-b38e-86cd-9390d34d58e3.png)

![確認_します.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131136/77caf597-bed1-b8d3-b1e0-e87c288572fb.png)

![ojigi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131136/4b2ff9aa-5f84-dc88-1fe1-3f41e224e7c9.png)

![確認中.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131136/77f5e942-20f6-7d17-dabc-9b0ab89e8fb9.png)

![承知_しました.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131136/7c8754a7-ca8e-9824-0765-a18d5786846f.png)
LinuxでiPhoneのAirPlayミラーリングをするUxPlay

これをつかう

[UxPlay 1.69: AirPlay-Mirror and AirPlay-Audio server for Linux, macOS, and Unix](https://github.com/FDH2/UxPlay)

以下はFedora上での例

```sh
git clone https://github.com/FDH2/UxPlay
cd UxPlay
mkdir build
cd build
sudo dnf install gstreamer1-devel gstreamer1-plugins-base-devel gstreamer1-plugin-libav
cmake ..
make
sudo systemctl start avahi-daemon
./uxplay -p -vs waylandsink -s 1280x720 -fps 30
```

参考
[UxPlayを使ってiPhoneの画面をLinux PCに表示する](https://qiita.com/ht164/items/f978db3dd862f27b6e70)
【AWS】API Gatewayインスタンス削除手順【API Gateway】

1). API Gatewayを開き、削除対象のAPIのラジオボタンを押し、「削除」を押します。
![1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817084/a079cfa9-fe0b-caca-d08d-e7bec196982b.jpeg)

2). 赤枠に「確認」と入力し、「削除」を押します。
![2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817084/6d91d317-c74f-1fb0-eebf-0591bcfd53aa.jpeg)

3). 正常に削除されたことを確認して完了です。
![3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817084/655791f7-dfcb-3ecd-9fb1-409b25ef4d75.jpeg)
【Linux】YYYYMMDDを今日の日付に置き換えていたけれど、dateコマンドを使うようになったら楽になっただけの話

# はじめに
どうも、エンジニアのタマゴです。
今回は、dateコマンドを用いた日付取得について書きます。
知っている方にとっては当たり前な内容かと思いますが、誰かしらの参考になればと思い、記させていただきます。

## 内容
以前、何かの手順書に以下のような記載がありました。
```
cp -p /sample/test.txt /backup/YYYYMMDD_test.txt
※YYYYMMDDには当日の日付を入れること
```
コマンドを打つ前に、YYYYMMDDを今日の日付に置換したり、カタカタと書き換えたりしていました。
作業準備しているときに日付を書いておいたりもしましたが、作業日がリスケとなったときに全然違う日付になってしまっていたりもしました。
しばらく、自分も同じようにYYYYMMDD仮置きや、作業日決め打ちで記載していましたが、他の人が以下のように記載しているのを教えてもらい、以来は使うようにしています。

```
cp -p /sample/test.txt /backup/$(date +"%Y%m%d")_test.txt
```

こう記述することで、サーバ上から今日の日付をYYYYMMDD形式で取得してくれます。

## 文法的な解説

### $(command)について
`$(command)`は、囲まれたコマンドの結果に置き換わります。
バッククォート囲みでも同じ働きをします。
つまり、上記のコマンドでは`$(date +"%Y%m%d")`が`date +"%Y%m%d"`の結果に置き換わります。

### dateコマンドについて
日付取得用のコマンドです。
何もオプションを付けずに打つと、現在の日時を長々と出力してくれます。
そこで、formatのオプションが大事になってきます。
`+"%Y%m%d"`
+以降がフォーマットの形式です。
%Y→年(YYYY)　%m→月(MM)　%d→日(DD)
となるので、日付がYYYYMMDDの形式で出力されるということになります。

## デメリットについて
ここまでの書き方では至極便利なものである風に書きましたが、ある見方をするとデメリットも見えてきます。
### 日付を跨いだ作業
例えば、2024/04/01に以下のような夜間作業があったとします。
```
mkdir $(date +"%Y%m%d)_dir
※ここで日付が変わった
cd $(date +"%Y%m%d)_dir
```
この場合、mkdirコマンドは20240401ディレクトリを作成していますが、
日付を跨いだcdコマンドではdateコマンドの結果が20240402となり、作成したディレクトリを参照できません。

### あとから見ると何日かわからない
コマンドだけを見ると、実際の作業日がわかりません。
別途、作業管理の中で日付は書くと思うので基本的には問題ないと思いますが、管理方法によっては大事に思うかもしれないと感じました。

## まとめ
今回はdateコマンドを用いてバックアップ等のファイル名に日付を記載する方法を述べました。
メリットとデメリットがありましたが、基本的にはメリットの方が大きいかなと思いました。
今後、自分が作成する手順書等で使える機会があったら積極的に使いたいと思います。

以上です。閲覧ありがとうございました。
【AWS】２つのCWアラームが同時に検知されてしまう現象の解決方法

# 概要
AWS CloudWatchのアラームを利用して、とある既存アプリケーション（ECSコンテナ）で指定した閾値を超えた場合にアラートが出るようにしていました。今回、同じアラーム設定内容をセットで別の新規アプリを導入したところ、一方で閾値を超えると両方のアラートが飛んできてしまう現象に遭遇しました。

こちらの原因と解決法がわかったので紹介します。

# 前提
既存アプリで使っていたアラームの設定は以下の内容です。
管理コンソールから確認すると以下の通りです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/9ed2d1f9-11f2-020d-e914-731a0a47fe1f.png)


Cloudformationテンプレートは以下の内容で設定していました。

```yaml
  NginxLogAlarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmActions: 
       - !Ref SampleTopic
      Namespace: 'Nginx'
      MetricName: 'Error'
      ComparisonOperator: GreaterThanOrEqualToThreshold
      EvaluationPeriods: '1'
      Period: 60
      Statistic: Sum
      Threshold: 1
      TreatMissingData: notBreaching

  NginxMetricFilter: 
    Type: AWS::Logs::MetricFilter
    Properties: 
      LogGroupName: '/aws/ecs/docker'
      FilterPattern: 'ERROR'
      MetricTransformations: 
        - 
          MetricValue: '1'
          MetricNamespace: 'Nginx'
          MetricName: 'Error'
```


これは、`/aws/ecs/docker`ロググループ内の`ERROR`という文字列を含むログイベントを検出し、それを`Nginx`名前空間の`Error`メトリクスとしてCloudWatchに送信する、という設定になります。

`ERROR`をフィルターしていたのは、GunicornやuWSGIでエラーが起きる時に以下のようなエラーメッセージが表示されるためです。

> [ERROR] Exception in worker process

こんな感じです。

（DB接続エラーの場合）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/8f87f4b0-3d63-f36d-c0e3-f96f576900da.png)

（モジュールインポートエラーの場合）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/ed3c7da1-cf47-1feb-9de1-7a41ba8c8948.png)


上記のCloudwatchアラームの設定では、`NginxLogAlarm`がこの`Error`メトリクスを監視し、60秒間に1つ以上のエラーが発生した場合にアラームをトリガーし、`SampleTopic`に通知を送信する、という流れです。

# 同時に検知してしまう現象の原因
上記と同じことがしたかったので、新規アプリでも同じ構成と流れでアラームを設定しました。
ロググループだけ別の名前`/aws/ecs/docker_sample`にして、他は同じです。

しかし、いざ、これで構築が完了した後、新規アプリでエラーを検知すると既存アプリ・新規アプリの両方とも検知してしまい、アラートが2回きてしまうという現象が発生。

なぜか？
答えは、メトリクスの名前設定にありました。

公式ドキュメントには以下のように記載があります。

> メトリクスは名前、名前空間、0 以上のディメンションで一意に定義されます。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html

つまり、既存と同じ `MetricNamespace` x `MetricName` の組み合わせを使うと、一意の識別子として機能して互いに検知してしまうのです。

異なるロググループから同じ`MetricNamespace`と`MetricName`を使用してメトリクスを送信する場合であっても、それらのメトリクスはCloudWatch内で同じメトリクスとして扱われる、という意味です。

上記の場合、`/aws/ecs/docker`と`/aws/ecs/docker_sample`という異なるロググループ名を持つ2つの`NginxMetricFilter`がありますが、どちらも`ERROR`というフィルターパターンで`Nginx`名前空間の`Error`メトリクスにデータを送信します。これにより、どちらのロググループからのエラーも同じ`Nginx`名前空間の`Error`メトリクスに集約されていたのです...

なるほど。どちらのロググループで`ERROR`が検出されても、それは同じ`Nginx`の`Error`メトリクスに集約され、アラーム条件を満たしてしまうのでどちらでもアラートが上がる、ということなんですね。

確かに、それぞれのロググループのメトリクスフィルターを見ると、`Alarms`のところに二つのアラームが並んでいました。これを見れば一目瞭然でしたね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/89b01dc4-8273-9c5c-7b92-e7fb8cb405d6.png)

# 解決方法
ということで、新規アプリの方の`MetricNamespace`を既存アプリのメトリクス空間名と重複しないものに設定して、再度構築。すると、上記の管理コンソールから確認しても、それぞれのロググループには一つのアラームしか存在しないようになったことを確認できました。

これでエラーが起きても、両方で検知されることは無くなりました。
めでたしめでたし。
PaizaでSランクになるまでにやったこと

# はじめに
本記事では筆者がPaizaでSランク(上位3%)になるために実施した勉強方法を共有しようと思います。

# 使用している環境
- python3(3.11.9)

# 勉強方法
以下の手順で学習を行いSランクを達成しました。
- 文法事項の理解
- 競プロの問題に慣れる
- 競プロの定石を知る
- Sランク問題をひたすら解く

それぞれ具体的に解説していきます。

### 文法事項の理解
以下の書籍を使って基本的な文法を理解しました。

https://book.impress.co.jp/books/1122101165

https://www.sbcr.jp/product/4815617837/

難易度としては「スッキリわかる」 < 「新明解」だと思います。
プログラミング初学者の方は「スッキリわかる」を、ある程度プログラミング経験のある方は「新明解」のテキストを使って学習を進めるとよいかと思います。
PaizaでSランクを取るためにはテキストの内容を完璧に理解する必要はなく、標準入出力、if文for文while文、リストに関する内容がわかっていればおおむね問題ないように感じました（あくまでSランクを達成するという目的に限った話です）

一部、競プロ特有の記述方法があるため、面食らう場面もあるかと思いますが、その都度覚えていけば事足りるかなと思います。

例（半角区切りで与えられた数値をint型でリストに格納する処理）
```python
# 入力
# 1 2 3 4 5
lst = list(map(int, input().split()))

# 出力
# [1, 2, 3, 4, 5]
print(lst)
```

map関数を使った処理やリスト内包表記、スライス式等は多くの場面で活用するのであらかじめある程度の知識を持っておく方が理解が容易かもしれません。

### 競プロの問題に慣れる
さて、文法事項に慣れてきた後は、競プロの問題を解いていきましょう。
まずはPaizaのサイトにアクセスして、アカウントの作成を行いましょう。

https://paiza.jp/

問題はDランクからSランクまで5段階存在します。まずは一番ランクの低いDランクから初めて徐々に高ランクの問題に挑戦するとよいかと思います。
Paizaでは、あるランクの問題を1問でも完答できたらそのランクに認定されます（Bランクの問題を1問完答すればBランクに認定される）
そのため、自分の実力プラスαくらいのランクの問題を解いてランクアップに挑戦していくとよいかと思います。
一度間違えた問題は再挑戦できますので、何が間違っていたのかを考えて再挑戦するとよいかともいます（再挑戦で完答した場合、ランクアップはしません）
しばらく問題に挑戦していると、競プロの考え方が身につくとともにB~Aランクくらいに到達できるかと思います（挑戦した問題によってはその限りではないかもしれません）
AランクからSランクにかけて、徐々に自力でアルゴリズムを考えてコーディングをしていくという手法では問題が解けなくなってくる可能性が高いです。
特に実行制限時間超過によって不正解になってしまうことが出てくるかと思います。
筆者の場合はAランクで頭打ちになったように感じたので、書籍を購入して競プロの定石を覚えることにしました（もちろん人によってはすんなりSランクに行く人もいるかと思いますが）

### 競プロの定石を知る
さてここから先は競プロにおける定石を覚えて、効率の良いアルゴリズムを作成する必要が出てきます
筆者は以下の書籍を参考に学習を進めました

https://book.mynavi.jp/ec/products/detail/id=22672

いわゆる蟻本と呼ばれるやつです
ちなみに2章の初級編の章を一通り学習するだけでSランクに到達できました（簡単とは言っていない）
蟻本を読み始めてから、プログラムにおける計算量の考え方を学べたり、自分が書いているコードのどの部分がどれだけの計算量を必要としているのか、計算量を減らすためにどのような工夫が考えられるのか等、プログラム作成に対する向き合い方が変わったりしたため、購入してよかったと感じています。
本書の読み方ですが、基本的に問題を自分の頭でかんがえるということはしていません
そもそも競プロにおける定石を知らないままでここまできてしまったので、まずは定石を理解するためにコードに目を通すことから始めました。
本書のコードはC++で書かれているので、アウトプットとしてコードをpythonで書き直して実行確認するということだけ行いました
また、本書を読み進めていく中で理解できない内容に遭遇した際はアルゴリズム名でweb検索をしたりyoutubeで検索したりして理解できる状態を作りました

### Sランク問題をひたすら解く
さて、ここまでくればSランクの問題を解くのに必要な武器は一通りそろっているはずです。
ひたすら問題を解いてSランクを目指しましょう
これまでは問題を見て愚直にコードを書くだけの方法で問題を解いていましたが、与えられた制約からどの程度の計算量のアルゴリズムを考える必要があるのか、また、自分の知っているアルゴリズムのうちどのアルゴリズムを使えば問題が解決できそうかということが何となく浮かぶようになっていました。
ただ、実際に解答してみると、プログラムのバグ等の理由ですぐにSランクになることはできず、Sランクの問題を5問ほど解いた末に完答することができ、無事Sランクになることができました

# これからやりたいこと
今後はAtCoderというサイトを使って精進していきたいと考えています。
AtCoderの記事も書いていけたらと思いますのでよろしくお願いいたします。
100-2：CSS基礎の学習（10/91）

# カリキュラム一覧
- <font color="FireBrick"><strong>レスポンシブウェブデザイン 認定講座　　　　　　　　　　　　　　←　今ココ</font>
- JavaScript アルゴリズムとデータ構造 (ベータ版) 認定講座
- フロントエンド開発ライブラリ 認定講座
- データ可視化 認定講座
- リレーショナルデータベース 認定講座
- バックエンド開発と API 認定講座
- 品質保証 認定講座
- Python を用いた科学計算 (ベータ版) 認定講座
- Python を用いたデータ分析 認定講座
- 情報セキュリティ 認定講座
- Python を用いた機械学習 認定講座
- Python を用いた代数学 認定講座

# レスポンシブウェブデザイン　認定講座の内訳
#### コース1
- [x] HTML の学習: 猫の写真アプリを作成する
- [ ] CSS 基礎の学習: カフェメニューを作成する <font color="FireBrick"><strong> ←　進捗：10/91step
- [ ] CSS 色指定の学習: カラーマーカーのセットを作成する
- [ ] HTML フォームの学習: 登録フォームを作成する
- [ ] 認定プロジェクト

#### コース2
- [ ] CSS ボックスモデルの学習: ロスコの絵画を作成する
- [ ] CSS フレックスボックスの学習: フォトギャラリーを作成する
- [ ] タイポグラフィの学習: 栄養成分表示ラベルを作成する
- [ ] アクセシビリティの学習: クイズを作成する
- [ ] 認定プロジェクト

#### コース3
- [ ] CSS 疑似セレクターの学習: バランスシートを作成する
- [ ] CSS 中級の学習: 猫のイラストを作成する
- [ ] レスポンシブウェブデザインの学習: ピアノを作成する
- [ ] 認定プロジェクト

#### コース4
- [ ] 技術ドキュメントページ認定プロジェクト
- [ ] CSS 変数の学習: 都市のスカイラインを作成する
- [ ] CSS グリッドの学習: 雑誌を作成する
- [ ] 認定プロジェクト

#### コース5
- [ ] CSS アニメーションの学習: 観覧車を作成する
- [ ] CSS Transform の学習: ペンギンを作成する
- [ ] 認定プロジェクト

# メモ
- xxx
PythonのKivyアプリをexe化する方法

# はじめに
PyInstallerを使用して、PythonのKivyアプリをexe化する方法を示す。

# 目次
1. [環境](#環境)
1. [フォルダ構成](#フォルダ構成)
1. [手順](#手順)
1. [参考文献](#参考文献)

# 環境

PyInstallerの最新版6.8.0では、exeファイルを終了すると、一時フォルダの削除できないワーニングが発生したため、
バージョン指定で5.13.2を使用する。

- Windows11
- Python 3.11.6
- pip 24.0
- Kivy 2.2.1
- PyInstaller 5.13.2
- PowerShell

# フォルダ構成
test
├── main.py ＃ スクリプト
├── main.kv ＃ kivyファイル
├── kivy_venv/Lib/site-packages # 仮想環境にインストールしたモジュール
├── main.spec # PyInstallerの設定ファイル
├── dist/main.exe # 作成するexeファイル
└── build/ # exeファイルに関連するもの（未使用）

# 手順
### 1. 仮想環境を構築
```
    python -m venv kivy_venv
```

### 2. 仮想環境をアクティブ化
```
    kivy_venv/Scripts/activate
```

### 3. Kivyをインストール
```
    pip install kivy
```
    
### 4. PyInstallerをインストール
```
    pip install pyinstaller
```

### ５. Pythonのスクリプトを編集

PyInstallerのconsoleオプションを無効にして、exeファイルを作成する場合、exeファイルを実行すると、RecursionErrorが発生する。
そのため、以下の環境変数を設定する。

```main.py
if hasattr(sys, "_MEIPASS"):
    os.environ["KIVY_NO_CONSOLELOG"] = "1"
```

### ６. PyInstallerでexeファイルを作成

- --name （exeファイル名）：exeファイル名を指定する
- --onefile：exeファイルを１つにまとめる
- --noconsole：コンソールへの出力を無効にする

```
    pyinstaller main.py --name test --onefile  --noconsole
```

PyInstallerで作成されたspecファイルに以下を追加する。

- from kivy_deps import sdl2, glew ：Kivyの設定
- *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)] ：Kivyの設定
- datas[("exeファイルから参照したいファイル", "一時フォルダからのファイルの相対パス")]：一時フォルダに保存されるデータ
    - C:\Users\(ユーザー名)\AppData\Local\Temp_MEIxxxxxx の一時フォルダが作成される

```main.spec
# -*- mode: python ; coding: utf-8 -*-

from kivy_deps import sdl2, glew #追加

block_cipher = None


a = Analysis(
    ['main.py'], #追加
    pathex=[],
    binaries=[],
    datas=[("main.kv", ".")], #追加
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)], #追加
    name='test',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False, #出力を無効
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)
```

コンパイルし、再度exeファイルを作成する。

```
    pyinstaller main.spec
```

# 参考文献
- [PyInstallerで実行ファイルにリソースを埋め込み](https://qiita.com/firedfly/items/f6de5cfb446da4b53eeb)
- https://github.com/kivy/kivy/issues/8074
- https://kivy.org/doc/stable/guide/packaging-windows.html
- https://github.com/pyinstaller/pyinstaller/issues/7106
エンジニア案件で求められる経験や人物像(100件以上の案件から分析)

# はじめに
フリーランスのエンジニア案件で求められるスキルや人物像をまとめました
案件募集する際や自身がキャリアを考える上での参考にして頂ければと思います

# 設計
◆要件定義の経験
◆画面設計の経験
◆基本設計からテストまでの経験
◆UMLやシーケンス図を用いた設計経験
◆ER図,テーブルなどデータベース設計経験
◆UI/UXの知見

# 技術
◆主要言語の経験3～5年ほど
Java、C、C++、C#、php、ruby、Go、python、html、js、css、TypeScript etc
◆フレームワークの経験3～5年ほど
laravel、cakePHP、FuelPHP、React、Vue、Node、Next、Ruby on Rails、Django、Struts etc
◆その他言語経験
tailwind css、scss、GraphQL、bat、shell、gas、VBA　etc
◆CSSの全体設計
◆gitの経験
◆Dockerの経験
◆リバースエンジニアリングの経験
◆技術選定の経験

# DB
◆主要DBの経験(3～5年)
Oracle、SQLServer、MySQL etc
◆KVS型の利用
◆パフォーマンスチューニングによる負荷対策経験
◆インデックスの知見

# 開発
◆Webサービスの開発経験
◆新規開発の経験
◆ゼロイチ開発経験
◆コードレビューの経験
◆コンテナ開発環境の経験
◆人に読まれることを前提とした設計、コーディングができる方
◆テストコード実装の経験(ツールの使用経験など)
◆クラウドインフラ開発経験(aws、azure、gcp etc)
◆既存システムバージョンアップ対応の経験
◆他システムとの連携経験
◆ローコードソフトウェアでの開発経験
◆ペアプログラミング、モブプログラミングの経験
◆EC-CUBEの経験
◆リファクタリング経験
◆アジャイル開発手法の経験
◆クリーンアーキテクチャの知見
◆DDDの経験
◆テスト駆動開発(TDD)の経験
◆コンテナ技術の実務経験
◆チケット駆動型開発の経験

# 運用
◆管理画面の実装、運用経験
◆運用に支障があるコードの監修、修正
◆運用、保守経験のある方※重要
◆デプロイ経験
◆データ基盤の構築運用経験
◆CICDの経験

# チーム開発/リーダー/管理
◆チーム開発での経験
◆社内外問わず、円滑なコミュニケーションが行える方
◆リーダー経験
◆コミュニケーションスキル
◆プロジェクト管理(スケジュール管理、進捗管理、課題管理)
◆PMOの経験
◆コミュニケーションツールの使用経験(slack、teams、chatwork etc)

# 折衷/調整
◆クライアントとの顧客折衝経験
◆ビジネス側の仕様調整経験
◆顧客への提案など積極的にできる方
◆オフショアの経験
◆多職種との調整(プランナー、フロント、バックエンド、インフラ、デザイナー)

# 思考
◆業界知識
◆一人称で主体的に動ける方(能動的に行動できる方、受け身ではなく、自ら考え動ける方)
◆過去半年で技術的にどのように成長できたのか話せる方
◆論理的な思考、柔軟な発想力をお持ちの方
◆フットワーク軽い方
◆各種自動化やチーム内での新たな技術的取り組みを主導した経験
◆問題解決できる方
◆技術調査の対応が可能な方
◆新卒を含めたメンバーへのトレーニング経験

# まとめ
今後も追記する形で求められるものをまとめていきます。
自分用に備忘録的にも使っていますが、他の方の参考にもなれば幸いです
【アップデート】 Amazon LightsailでIPv6のみのネットワークタイプでもブラウザベースの SSH/RDP 接続ができるようになりました

こんばんは。Koderaです。
Amazon LightsailでIPv6のみのネットワークタイプでもブラウザベースの SSH/RDP 接続ができるようになりました。
https://aws.amazon.com/about-aws/whats-new/2024/08/browser-based-ssh-rdp-ipv6-only-instances-bundles-lightsail/

## アップデート内容
Amazon Lightsailでブラウザベースの SSH/RDP 接続 (Lightsail Connect) のサポート対象がIPv6のみのインスタンスにも適用されるようになりました。
Amazon Lightsail自体はIPv4とIPv6の両方がサポートされるデュアルスタックです。

本日よりLinux または Windows IPv6 のみのインスタンスに、ブラウザの Lightsail コンソールから直接接続できるようになりました。
本アップデート前まではLightsail Connectを使用するには、IPv6 専用インスタンスにパブリック IPv4 アドレスを追加する必要がありましたが、不要になっています。


## 確認してみる
(1) マネジメントコンソールからLightsailのインスタンスを起動してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858908/16642664-fd3d-794f-1337-f2186f0d92ef.png)

(2) インスタンスプランを選びます。
その際にIPv6不可のエラーメッセージが表示されなくなっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858908/fdc438b0-fa7c-9839-a6ce-64fdb8913099.png)

(3) 試しにAL2023でインスタンスを起動してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858908/54939174-6b94-1ab1-e822-b1b14ec65a4c.png)

(4) 接続します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858908/eb8455c9-a261-bdb4-77a9-205012ba8e5d.png)

(5) 無事に接続できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858908/b2fbf307-17b5-2e5c-9118-da384e881a85.png)

## まとめ
本日は、Amazon LightsailでIPv6のみのネットワークタイプでもブラウザベースの SSH/RDP 接続ができるようになりました。
試してみたのはLinuxのOSのみですが、Windowsも対応しています。
今後のIPv6アドレスへの切り替えを見越してのアップデートかと思います。
Snowflake Squadとは - Snowflake Squadになるまでにやったこと

# 前置き
こんにちはデータエンジニアの山口歩夢です！


こちら基本的な内容から実践的な内容、自分が開発する上で躓いたポイントやTipsなどを書かせていただいているStreamlitの入門書です。

電子版が技術書典にて購入可能なため、是非チェックいただけると幸いです。

https://techbookfest.org/product/t5GBwbFm4kUhXrTPkGpAnY?utm_source=twitter&utm_medium=social&utm_campaign=share

# 本題
先日、Snowflake Squadのメンバーに選んでいただき、
「Polar Bar第3回 Squad会 ~Snowflake Squadとは！？~」という、Snowflake Squadについて理解を深めるための会に参加し、色々な方々と交流をさせていただきました。
普段の業務だけでは聞けないお話などを聞くことができ、大変勉強になりました。

https://zenn.dev/dataheroes/articles/squad-polar-bar

なので、今回は「Snowflakeとは」という話や、自分が「Snowflake Squadに選ばれるまでに行なってきた発信」などを紹介させていただこうと思います。
ちなみに、Polar BarなどのSnowflakeのイベントの情報は「SnowVillage」というコミュニティに参加することで気軽に参加可能です。

https://usergroups.snowflake.com/snowvillage/

# Snowflake Squadとは
「Snowflake Squad」とは、Snowflakeコミュニティに積極的に参加し、コミュニティに貢献している熱心なメンバーを認識し、報いるための制度です。
以下のような発信を熱心に行なっている人が選出されるものになっております。

* Snowflake Community Forumsでの積極的な貢献
* ソーシャルメディアでの活動（頻繁なLinkedIn/Twitter投稿）
* ブログ執筆活動（Mediumでのブログ投稿）
* Snowflake Labsへの貢献者
* Builder EDUの学生
* YouTubeクリエイター
* ユーザーグループの頻繁な参加者、主催者、またはスピーカー

# Snowflake Squadに与えられる特典
Snowflake Squadに選ばれることで得られる特典は以下となっております。
* Snowflake Community Forumsでのプライベートの Snowflake Squad チャンネルに参加
* Snowflake Community ForumsでSquad バッチを示せる
* Snowflake Squad アセット、Accredible バッジの入手
* Snowflake SummitのSnowMobileにてインタビューを受ける権利（Data Superheroes, Squadのみ）
* Linkedin とCommunity Forumsでスポットライトを当ててくれる

個人的に、Twitterの背景に設定できるSnowflake Squadのアセット(下記)を頂けて嬉しかったです。
また、**他のSnowflake Squadの方々が優秀な方々ばかりで、そんな方々を近くで見ることができて刺激・勉強になりそう**というのが、とても良い特典だなと感じています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/649a952c-a46e-f182-6d93-2720b5e8259b.png)

# Snowflake Squadになるためにやったこと
自分は主に以下の通り、Streamlitについての発信を中心に行ってきました。
大体一年位前から、活動をしております。


* [Streamlitデータ可視化入門](https://techbookfest.org/product/t5GBwbFm4kUhXrTPkGpAnY?productVariantID=vFXbHRnFv5i0drjM591i0J)を技術書典にて頒布
* StreamlitやSnowflake関連の記事をQiitaに17件ほど投稿
* 登壇2回
    * [Streamlitを使ってデータカタログを作ってみた](https://speakerdeck.com/gussan0223/streamlitwoshi-tutedetakataroguwozuo-tutemita)
    * [StreamlitとTerraformでデータカタログを作った話](https://speakerdeck.com/gussan0223/streamlittoterraformdedetakataroguwozuo-tutahua)
* 毎週土曜AM9:00~のStreamlitの勉強会に頻繁に参加
  * SnowVillageに登録後参加可能です！
* Polar BarなどのSnowflakeのイベントに複数回参加

ご参考にしていただけますと幸いです🙇

# まとめ
SnowflakeやStreamlitの発信をして、Snowflake Squadに是非ご応募いただけると幸いです！
以下のリンクから応募可能いただけます。
よろしくお願いいたします🫡

https://www.snowflake.com/en/snowflake-squad/
文字の一致　print内にif文を埋め込む

https://paiza.jp/works/mondai/d_rank_skillcheck_sample/diff_str

今回、print内にif文を書くことで、短い行数で同じ動作をするプログラムをPython 3で書いてみた。
もし、正しいif文で書くとこのようになる。
## プログラム本文
```py:patern1.py
a = input()
b = input()
if a == b:
    print("OK")
else:
    print("NG")
```
print文の中で処理をするように書き直すと以下のようになる。
```py:patern2.py
a = input()
b = input()
print("OK" if a == b else "NG")
```
## 結果と分析
### patern1の場合の結果
![スクリーンショット 2024-08-20 214201.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3828295/fb709aad-76b1-1cce-ceab-37621883b7b4.png)
### patern2の場合の結果
![スクリーンショット 2024-08-20 214221.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3828295/c76aaf74-c382-007b-dbca-1c0edf71b9c3.png)

### 上記の結果からの分析
別にどちらもほぼ変わらないのでどちらでもよい。
逆に複雑となるので、シンプルな基礎的なほうが良いのでは？
論文解説スレ【朗報】AIが自分でAI進化させる「ADAS」ガチで使えるで！！実験してみたわ

## 論文情報

https://github.com/ShengranHu/ADAS

https://arxiv.org/abs/2408.08435



## 解説スレ

https://hamaruki.com/ai-self-evolution-adas-human-potential/

**22 名前：AI研究者J (新人) ：2024/08/21(水) 10:00:00.00 ID:aIr3S3rCh**
おい！ADASのGitHubリポジトリ見つけたで！実際に使えるみたいやから試してみたわ

**23 名前：プログラマーC：2024/08/21(水) 10:01:23.45 ID:c0d3rPr0**
マ？どうやって使うんや？

**24 名前：AI研究者J (新人) ：2024/08/21(水) 10:02:45.67 ID:aIr3S3rCh**
まず環境構築からや。こんな感じでいけるで：

1. Condaで環境作る：
```bash
conda create -n adas python=3.11
conda activate adas
```

2. 必要なライブラリインストール：
```bash
pip install -r requirements.txt
```

3. OpenAI APIキー設定：
```bash
export OPENAI_API_KEY="お前のキーをここに入れるんやで"
```

これで準備オッケーや！

**25 名前：機械学習エンジニアK：2024/08/21(水) 10:03:56.78 ID:mLe4rN3r**
おお、簡単やな。で、実際にMeta Agent Searchを走らせるにはどうすんの？

**26 名前：AI研究者J (新人) ：2024/08/21(水) 10:05:12.34 ID:aIr3S3rCh**
そこもめっちゃ簡単や。各ドメイン（問題領域）のフォルダに移動して、search.pyを実行するだけや。

例えば、ARCの問題やったらこんな感じ：
```bash
python _arc/search.py
```

MGSMの数学問題やったら：
```bash
python _mgsm/search.py
```

<blockquote class="twitter-tweet" data-media-max-width="800"><p lang="ja" dir="ltr">Automated Design of Agentic Systems取り敢えず動いたぽい！ <a href="https://t.co/Vjf4aGCMjN">https://t.co/Vjf4aGCMjN</a> <a href="https://t.co/8Ilf8dggRp">pic.twitter.com/8Ilf8dggRp</a></p>&mdash; Maki@Sunwood AI Labs. (@hAru_mAki_ch) <a href="https://twitter.com/hAru_mAki_ch/status/1825850957080719557?ref_src=twsrc%5Etfw">August 20, 2024</a></blockquote> 

**27 名前：大学生S (初心者) ：2024/08/21(水) 10:06:34.56 ID:sTud3nT5**
えっ、それだけ？他に設定とかせんでええんか？

**28 名前：AI研究者J (新人) ：2024/08/21(水) 10:07:45.67 ID:aIr3S3rCh**
基本はそれだけや。でも、新しい問題領域で使いたいときは少し工夫がいるで。

1. evaluate_forward_fn()関数を修正
2. メタエージェントが使う基本関数を追加
3. ドメイン固有の情報をプロンプトに追加

これらをやれば、新しい問題にも対応できるんや。

**29 名前：セキュリティ専門家S：2024/08/21(水) 10:08:56.78 ID:s3cur1ty**
ちょっと待て。AIが生成したコード実行するんやろ？それ超危険やないか？

**30 名前：AI研究者J (新人) ：2024/08/21(水) 10:10:12.34 ID:aIr3S3rCh**
＞＞29
さすがセキュリティ専門家や。そこはちゃんと警告出てるで。
READMEにも書いてあるけど、生成されたコードには悪意はなさそうやけど、モデルの能力や整列の限界で予期せぬ動作する可能性はあるって。

使うときは自己責任でな！

**31 名前：まとめ屋Y：2024/08/21(水) 10:11:23.45 ID:suMm4rY**
おっ、まとめるで：

- ADASの使い方：
  1. Conda環境作成とライブラリインストール
  2. OpenAI APIキー設定
  3. 各ドメインのsearch.py実行で簡単に開始
- 新しい問題領域への適用も可能
- セキュリティ注意：生成コードの実行にはリスクあり
- オープンソースで誰でも試せるが、自己責任で使用すること

これはガチで革命的やで。AIが自分で進化していく未来、もう目の前まで来とるんやな。

<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
パーフェクトRubyonRails備忘録6

# ActiveStorageによるファイルアップロード

- 実装
    - ActiveStorageの有効化
        - 以下を実行
        - `rails active_storage:install`
    - ActiveStorage用属性をモデル作成時に宣言する
        - `rails g scaffold user name portrait:attachment`
        - `portrait:attachment`部分がActiveStorage用属性の宣言
        - 生成されたモデルには以下の記述が追加されている
        
        ```ruby
        class User < ApplicationRecord
          has_one_attached :portrait # 追加部分
        end
        ```
        
    - 注意として、Usersテーブルにportraitはカラムとしては無く、他のテーブルとして管理されている。
    - これでファイルアップロード機能は実現している
- サムネイルの表示
    - 事前準備
        - `gem 'image_processing'` をアンコメントし、 `bundle install`
        - `brew install imagemagick`を実行
    - ActiveStorageのサムネイル生成は、画像用URLにアクセスしたタイミングで画像を生成する。他にもアップロード時、アップロード後に非同期、などのタイミングで生成するサービスもある。
    - 先ほど実装したファイル(app/views/users/show.html.erb)を編集する
    
    ```html
    <%= image_tag @user.portrait.variant(resize_to_limit: [100, 100]) %>
    ```
    
- ダイレクトアップロード機能
    - ダイレクトアップロードにより、アプリケーションサーバを経由せずにファイルを直接アップロードできるので、アップロード時間の短縮や、アプリケーションサーバへの負荷を軽減することが可能になる。
    - 実装
        
        ```html
        <%= form.file_field :portrait, direct_upload: true %>
        ```
        
        - `direct_uploda: true`を追加することでダイレクトアップロードが可能になる。
        - 詳しくは以下
        - [https://railsguides.jp/active_storage_overview.html#ダイレクトアップロード](https://railsguides.jp/active_storage_overview.html#%E3%83%80%E3%82%A4%E3%83%AC%E3%82%AF%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89)
- ActiveStorageのデメリット
    - バリデーションヘルパーが無い
    - フォーム送信時、他の項目がバリデーションエラーになった時、再度ファイルを選択しなければならない
様々な正規表現のまとめ 

# はじめに
よく使う正規表現を備忘録としてまとめてみました。
Java前提ですが、他の言語でも応用可能かと思います。
主にBeanValidatorのPatturnで使用することを想定しているため、既に存在しているもの（EmailやURLなど）はここでは扱いません。

# 半角数字
```
^[0-9]*$
```
# 半角英字
```
^[A-Za-z]*$
```
# 半角記号（半角スペース含む）
```
^[ -/:-@[-`{-~]*$
```

# 半角英数字
```
^[0-9A-Za-z]*$
```

# 半角英数記号（半角スペース含む）
```
^[0-9A-Za-z -/:-@[-`{-~]*$
```
# ひらがな（空白含む）
```
^[ぁ-んー\s]*$
```
# カタカナ（空白含む）
```
^[ぁ-んー\s]*$
```

# 郵便番号（ハイフン含む）
```
[0-9]{3}\-[0-9]{4}
```
# 郵便番号（ハイフン含まない）
```
[0-9]{7}
```
# 郵便番号（ハイフン任意）
```
[0-9]{3}\-?[0-9]{4}
```
 # フォルダ名（ドライブ名含む絶対パス）
 フォルダ名やファイル名として使用できない文字は、\ : < > | " * /
 フォルダ区切りは \\（正規表現では\\\\）
 ドライブは :
 それらを踏まえて文字列を組み立てています。
```
^[a-zA-Z]\:\\(([^\\\:\<\>\|\"\?\*\/]+\\)*[^\\\:\<\>\|\"\?\*\/]*)?$
```
 # フォルダ名（ドライブ名、ネットワーク含む絶対パス）
ネットワーク上のフォルダは\\\\（正規表現では\\\\\\\\）で始まる。
それ以外のルールは上記通り。
それを踏まえて文字列を組み立てています。
```
^([a-zA-Z]\:\\|\\\\)(([^\\\:\<\>\|\"\?\*\/]+\\)*[^\\\:\<\>\|\"\?\*\/]*)?$
```

 # フォルダ名（ドライブ名含まない絶対パス、相対パスも含む）
```
^([a-zA-Z]\:\\|\\\\|\\)?(([^\\\:\<\>\|\"\?\*\/]+\\)*[^\\\:\<\>\|\"\?\*\/]*)?$
```

 # ディレクトリ名（windows以外 絶対パス）
Linuxなどは、ファイル名に含められる文字の範囲は広く、/ とNUL[0x00] 以外は使えます。
ここではとりあえずNULは無視し可視文字を対象としていますので、/ 区切りの文字列という構成にしています。
```
^\/([^\/]+\/)*[^\/]*$
```

 # ディレクトリ名（windows以外 相対パス含む）
 相対パスを含むので、最初の文字 / は任意、という表現になっています。
```
^\/?([^\/]+\/)*[^\/]*$
```

# ファイル名(Windows)
```
^[^\\\:\<\>\|\"\?\*\/]*$
```

# ファイル名(Windows以外)
```
^[^\/]*$
```

# パスワード（半角英数記号、英大文字、英小文字、数字、記号のうち3種必須、8文字以上）
```
^((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])|(?=.*[a-z])(?=.*[A-Z])(?=.*[ -\/\:-@\[-`\{-~])|(?=.*[A-Z])(?=.*[0-9])(?=.*[ -\/\:-@\[-`\{-~])|(?=.*[a-z])(?=.*[0-9])(?=.*[ -\/\:-@\[-`\{-~]))([a-zA-Z0-9 -\/\:-@\[-`\{-~]){8,}$
```

# パスワード（英大文字、英小文字、数字、記号すべての種類必須、8文字以上）
```
^((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[ -\/\:-@\[-`\{-~]))([a-zA-Z0-9 -\/\:-@\[-`\{-~]){8,}$
```

# 半角の整数
```
`(+|-)?[0-9]+$
```

# 半角数値（".9" なども許容）
```
`((+|-)?[0-9]+)?(¥.[0-9]+)?$
```

# BASE64形式
```
^([0-9A-Za-z\+\/]{4})*([0-9A-Za-z\+\/]{3}\=|[0-9A-Za-z\+\/]{2}\={2})?$
```
GCP: Error creating WorkloadIdentityPool: googleapi: Error 409: Requested entity already exists

## Error

一度削除した workloadidentitypoolを再度作成しようとすると以下のエラーが出る:

```
Error creating WorkloadIdentityPool: googleapi: Error 409: Requested entity already exists
```

## 原因

削除したworkload identity pool / providerは 30日後に完全に削除される。それまではundeleteが可能。


![Screenshot 2024-08-20 at 21.25.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7059/5c033b2f-5ca2-1525-ef02-41f20b5a06b5.png)

https://cloud.google.com/iam/docs/manage-workload-identity-pools-providers#iam-workload-pools-undelete-gcloud

:::note info
再度使いたい場合は、削除してから30日以内であれば、undeleteをする！
:::

## 解決方法

### [Undelete workload-identity-pools](https://cloud.google.com/sdk/gcloud/reference/iam/workload-identity-pools/undelete)

```
gcloud iam workload-identity-pools undelete <pool> --location="global" --project <project>
```

### [Undelete workload-identity-pools providers](https://cloud.google.com/sdk/gcloud/reference/iam/workload-identity-pools/providers/undelete)

```
gcloud iam workload-identity-pools providers undelete <provider> --workload-identity-pool="my-workload-identity-pool" --location="global" --project <project>
```


## Ref

- https://stackoverflow.com/questions/73745130/terraform-on-gcp-error-409-requested-entity-already-exists
- https://cloud.google.com/iam/docs/manage-workload-identity-pools-providers#iam-workload-pools-undelete-gcloud
PHPで特定の日付からNヶ月前の月の初日を取得する方法

## はじめに
PHPで日付を操作する際、一見シンプルなタスクでも、特定の要件に合わせると予期しない問題が発生することがあります。この記事では、**特定の日付からNヶ月前の月の初日**を正確に取得する方法について説明します。


## 問題の背景
例えば、今日が８月２０日の場合、２月１日を取得することが目標です。
最初は strtotime 関数を使用して、特定の日付から5ヶ月前の月の初日を取得しようとしました。以下は最初に書いたコードです：

```
$today = date('Y-m-d');
$end_date = date('Y-m-d', strtotime('last day of last month', strtotime($today)));
$start_date = date('Y-m-d', strtotime('-5 months', strtotime($end_date)));
$start_date = date('Y-m-01', strtotime($start_date));
```
しかし、このコードは特定のケースで問題を引き起こしました。例えば、「5ヶ月前」が「2月」である場合、strtotime は正確な日付を返さず、2月28日ではなく3月1日として誤って計算されることがありました。

## 解決策
この問題を解決するために、DateTime クラスを使用して日付を直接操作する方法を試みました。DateTime クラスを使うと、より明確で正確な日付計算が可能です。

以下は修正したコードです：
```
$today = new DateTime();
$end_date = $today->modify('first day of last month')->format('Y-m-d');
$end_date_obj = new DateTime($end_date);
$end_date_obj->modify('-5 months');
$five_months_ago = $end_date_obj->format('Y-m-d');
$start_date = (new DateTime($five_months_ago))->modify('first day of this month')->format('Y-m-d');
```

## コードの説明
**現在の日付を計算**: `new DateTime()` を使って現在の日付を取得し、`modify('last day of last month')` で先月の最終日を計算します。
**5ヶ月前の月の初日を計算**: まず、先月の初日`(first day of last month)`を計算し、この日付から `-5 months` を適用して5ヶ月前の月を取得します。
**結果のフォーマット**: 最後に `first day of this month` を使ってその月の初日を取得し、`format('Y-m-d')` で指定された形式で出力します。


## 結論
この方法を使うことで、特定の日付から正確にNヶ月前の月の初日を計算することができます。DateTime クラスを活用することで、予期しないエラーを防ぎ、より明確でメンテナンスしやすいコードを書くことができます。

日付と時間の計算は、わずかな違いが大きな影響を与えることがあるため、こうした作業を行う際には常に注意が必要です。この投稿が皆さんのコーディングに役立つことを願っています！
Python ジェネレータ式でメモリ使用量を劇的に削減！

## はじめに 
こんにちは！今回は、Pythonのちょっとしたテクニックで、プログラムのメモリ効率を大幅に改善する方法をご紹介します。その秘密兵器とは…**ジェネレータ式**です！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/453f2357-748e-8d31-8a75-c3f85f4d76c0.png)

## はじめに

Pythonを使い始めてしばらく経つと、リスト内包表記の便利さに気づくことでしょう。でも、大量のデータを扱うときに「メモリ不足」で悩んだことはありませんか？そんなときこそ、ジェネレータ式の出番です！

## ジェネレータ式とは？

ジェネレータ式は、リスト内包表記の兄弟のようなものです。構文はほとんど同じですが、`[]`の代わりに`()`を使います。

例えば：
```python
# リスト内包表記
squares_list = [x**2 for x in range(1000000)]

# ジェネレータ式
squares_gen = (x**2 for x in range(1000000))
```

一見似ていますが、メモリの使い方が全然違うんです！

## なぜジェネレータ式がメモリ効率が良いの？

ジェネレータ式は、すべての要素を一度に生成するのではなく、必要なときに1つずつ生成します。これを「遅延評価」と呼びます。

実際にメモリ使用量を比較してみましょう：

```python
import sys

# リスト内包表記
squares_list = [x**2 for x in range(1000000)]
print(f"リストのメモリ使用量: {sys.getsizeof(squares_list) / (1024 * 1024):.2f} MB")

# ジェネレータ式
squares_gen = (x**2 for x in range(1000000))
print(f"ジェネレータのメモリ使用量: {sys.getsizeof(squares_gen) / 1024:.2f} KB")
```

実行結果：
```
リストのメモリ使用量: 8.00 MB
ジェネレータのメモリ使用量: 0.11 KB
```

驚きの差ですよね！

## ジェネレータ式の使い方

ジェネレータ式は、for文で簡単に使えます：

```python
gen = (x**2 for x in range(5))
for num in gen:
    print(num)
```

出力：
```
0
1
4
9
16
```

ただし、ジェネレータは一度しか反復できないので注意が必要です：

```python
gen = (x**2 for x in range(5))
print(list(gen))  # [0, 1, 4, 9, 16]
print(list(gen))  # []  # 2回目は空のリストになる！
```

## まとめ

ジェネレータ式を使うことで、メモリ使用量を大幅に削減できます。特に大量のデータを扱う場合や、データの生成に時間がかかる場合に効果を発揮します。

ぜひ、あなたのコードでも試してみてください。メモリ効率が上がるだけでなく、処理速度の向上にもつながるかもしれません！

次回は、ジェネレータ関数についても詳しく解説する予定です。お楽しみに！

## 参考リンク

- [PythonのGenerators解説](https://docs.python.org/ja/3/howto/functional.html#generators)
- [PEP 289 -- Generator Expressions](https://www.python.org/dev/peps/pep-0289/)

最後まで読んでいただき、ありがとうございました。この記事が皆さんのPythonスキル向上の一助となれば幸いです。質問やコメントがありましたら、ぜひ下のコメント欄でお聞かせください！

https://qiita.com/Tadataka_Takahashi/items/9841f6d3777189386031
コマンドプロンプト バッチのサンプル

小ネタです。私的によく使うのに書き方を忘れがちなバッチ処理です。

### サブルーチン１

```
call :sub param1
exit

:sub
set ARG1=%1
exit /b

```

### サブルーチン２

ループ中に、サブルーチン呼び出し
```
for /l %%A in (50, 1, 100) do call :sub %%A
pause
exit

:sub
echo %1
exit /b
```

### 複数行のファイル出力

```
set FILE=Output.txt
> "%FILE%" (
  echo.テキストを出力
  echo.
  echo.↑ 空白行
)
```


### 複数行のコメントアウト

```
rem/||(
  コメント行１
  コメント行２
  コメント行３
)
```


# あとがき

Qiita Engineer Festa の時に勢いだけで投稿しておこうと思ってたのを今頃投稿しましたｗ
バグは続くよどこまでも

「バグは続くよどこまでも」

バグを直しても、新しいバグが生まれて、さらにバグを直しても、またバグが生まれる。
そんな無限バグ地獄の中にいるときに、心の中でよくこの言葉をつぶやく。
すると不思議なもので、少しだけ心が軽くなる。
バグは出て当たり前みたいな、そんな感じでふっきれる。
phpMyFaqのバージョン更新

<img src="https://img.shields.io/badge/phpMyFAQ-3.2.x-brightgreen">

## はじめに

小ネタです。[バージョンの更新方法](https://phpmyfaq.readthedocs.io/en/main/update/)が公式に記載されていますが、
最後のURLが違っていました。

参考までに、自分が実際に更新した時のコマンドを記載します。

## 更新方法、コマンド

1. 管理画面からメンテナンスモードにします
1. 次のディレクトリを除外して、全データを削除します
    -  config/
    -  assets/themes/
    -  attachments/
    -  data/
    -  images/
    ``` bash
    cd /var/www/html/
    find . -maxdepth 1 -type f -exec rm -f {} +
    rm -Rf admin lang multisite services setup src logs
    cd assets
    rm -Rf dist fonts img src
    ```
    　

1. 更新データの配置
    ``` bash
    cd ~
    rm -Rf phpmyfaq  # インストール時に利用したデータの削除
    wget https://download.phpmyfaq.de/phpMyFAQ-3.2.9.zip
    unzip phpMyFAQ-3.2.9.zip
    cp -npR ./phpmyfaq/* /var/www/html  # -n で配置先にデータが存在する場合はスキップ
    chown -R apache.apache /var/www/html
    ```
    　

1. http://www.example.com/setup/update.php にアクセスして更新


## 後記

脳死でやっていると、最後のブラウザアクセスに際して 404エラーで慌てます。でもこれ、[古いバージョンの資料](https://www.phpmyfaq.de/docs/2.9#3)は URLが正しいんですよ。 何があったんだろう。
filter_map.with_index、君に決めた

## 知りたかったこと

filterは配列などの条件に合致する要素を新たな配列として返してくれる。例えば次は機能する。

```ruby
ary = [1,10,6,3,7,2,5,4]
p ary.filter { _1 > 4 }
#=> [10,6,7,5]
```

しかし、以下の場合はどうするだろうか。
- 配列の合致する要素に対してのみ、**その要素に演算を行なった値**を返して欲しい
- 配列の合致する要素の**インデックスが全て**欲しい

要は、Pythonのif節を備えた内包表記と同じことがしたいのである。

## いにしえの解決法
これを解決するには
map{if文}.compactを使いましょう、というのが調べると出てくる。要らない要素はif文でnilにし、最後にcompactで取り除くという算段だ。

```ruby
ary = [1,10,6,3,7,2,5,4]
p ary.map { _1 * 2 if _1 > 4 }.compact
#=> [20,12,14,10]
p ary.map.with_index {|value, index| index if value > 4 }.compact
#=> [1,2,4,6]
```

ちなみに、each_with_indexはあってもmap_with_indexはない。大人しくmap.with_indexとする。

## もっと良い案

しかし、フィルタリングするために用いるメソッドがcompactというのはいかにも分かりづらく、技として理解していても可読性が低い。

一案として、filterとmapを分けてあげる手がある。

```ruby
ary.filter { _1 > 4 } .map { _1 * 2 } 
#=> [20, 12, 14, 10]
```

これでもいいのだけど、ブロックが二つ必要になったりとpythonの内包表記に一歩及ばない感じもする。
フィルタリングとマッピングを同時にしてくれるメソッドは無いものか、と思ったら、ちゃんとあった。

[filter_map](https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/filter_map.html) (Ruby公式リファレンスに飛びます)

先ほどのはこうなる。filter{}.map{}とどちらが良いかは時と場合によるだろうが、見やすく感じる。

```ruby
ary = [1,10,6,3,7,2,5,4]
p ary.filter_map { _1 * 2 if _1 > 4 }
#=> [20,12,14,10]
```

特に、with_indexでインデックスを返り値に利用したいときにはfilter_map一択になると思う。
if文にindexが入っていようが、問題なく動く。

```ruby
ary = [1,10,6,3,7,2,5,4]
p ary.filter_map.with_index {|value, index| index if value > 4 }
#=> [1,2,4,6]
p ary.filter_map.with_index {|value, index| value if index >= value }
#=> [3,2,5,4]
```

良いじゃん。
こんな素敵なメソッドなのにいまいち知名度が低い気がするのは、実装がRuby2.7以降とまあまあ後発だからか。
また、filterのエイリアスでselectはあっても**select_mapは存在しない**（要注意）ため、selectを好む人は存在に気づきづらいかもしれない。

ついでなのでハッシュを生成するto_hとの合わせ技もおさらいしておこう。to_hは[キー,値]という配列を要素に持つ二次元配列からハッシュを生成出来るのだった。

```ruby
[[:a, 1], [:b, 2], [:c, 3]].to_h
#=> {:a=>1, :b=>2, :c=>3}
```

これとfilter_mapを組み合わせることももちろんできる。

```ruby
ary = [1,10,6,3,7,2,5,4]
p ary.filter_map.with_index {|val, ind| [ind, val * 2] if val > 4 }.to_h
#=> {1=>20, 2=>12, 4=>14, 6=>10}
```

もはやfilterメソッドは不要なんじゃないかと錯覚させられるくらいに小気味がいい。
zipしたっていい。

```ruby
ary1 = [1,6,3,8]
ary2 = [5,2,7,4]
p ary1.zip(ary2).filter_map {|i, j| [i, j] if i > j}.to_h
#=> {6=>2, 8=>4}
```

map, map.with_index, filter_map, filter_map.with_index, to_hの５つの挙動を理解すれば、少なくともPythonの内包表記と同等かそれ以上の機動性を実現可能で、望みの配列やハッシュは大概自由に作れるようになる。と思う。

## おまけ
injectの場合、filter_injectなるものは存在しない。おとなしくfilterしてからinjectする。

```ruby
ary = [1,10,6,3,7,2,5,4]
ary.filter{ _1 > 4}.inject(:+)
#=> 28
```
Ectoで結果が返ってこなくて困った例

## NGパターン

```elixir
    from(sp in SP,
     where: sp.id == "ZZZZZAAAM7VKBBBDNXVAMZVZPQ"
    )
    |> Repo.one()
```

## OKパターン
```elixir
    from(sp in SP,
     where: sp.id == ^"ZZZZZAAAM7VKBBBDNXVAMZVZPQ"
    )
    |> Repo.one()
```

## 差分
```diff_elixir
    from(sp in SP,
-    where: sp.id == "ZZZZZAAAM7VKBBBDNXVAMZVZPQ"
+    where: sp.id == ^"ZZZZZAAAM7VKBBBDNXVAMZVZPQ"
    )
    |> Repo.one()
```
つまり、比較する値に『ピン演算子(^)』をつけないとバグります

普段は

```Elixir
    id = "ZZZZZAAAM7VKBBBDNXVAMZVZPQ"
    
    from(sp in SP,
     where: sp.id == ^id
    )
    |> Repo.one()
```

な使い方で直接値を設定したことなくてハマった
【supabase × firebase × GithubActions】React学習記録アプリをグレードアップさせる

# はじめに
学習記録アプリを以前作成しました。

https://qiita.com/shinry/items/3d374009f680d235ccd4

今回は、さらに学習記録アプリをグレードアップしました。

# 以前作成したアプリ
以前作成したアプリは学習内容と学習時間を入力し、登録できるアプリでした。
このアプリには以下の3つの問題がありました。

問題1:リロードするとデータが消える
問題2:ローカル上でしか確認できない
問題3:実際の動作が客観的に保障されていない


今回はグレードアップを行い、3つの問題を解決しました。

# supabaseでDBを作成
supabaseというサービスを利用し、DBを作成しました。
無料で使えるかつ、DBを作成しデータを保存でき、そこから読み取ったり書き込んだりできます。

https://supabase.com/

GUI操作で簡単にDB作成、テストデータ作成ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/a9d870f2-147c-07b1-dfc4-aade54c63e1b.png)

supabaseでDBを作成し、そこに登録したデータを保存したり、データを読みとれるようにしたことで、リロードしてもデータが消えないようになりました。

# firebaseでデプロイ
firebaseで学習記録アプリをデプロイし、ホスティングさせました。
簡単にwebアプリを公開できるのでおススメです。

https://firebase.google.com/?hl=ja

# テスティングフレームワークのjestを導入
jestというテスティング」フレームワークを用いて、Reactの動作をテストしました。
テストを実装することで、実際の動作が保証できます。

https://jestjs.io/ja/

# GithubActionsで自動テスト、自動デプロイ
jestでのテスト実行とfirebaseのデプロイをGithubActionsで自動化しました。
mainブランチにpushされると、テスト実行とfirebaseデプロイを自動で行ってくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/dccef01f-e715-9d0d-5d82-11070e6a3cfd.png)


# 成長できた実感がある
控えめに言っても、前回と比べてやれることがかなり増えました。

**前回**
- ReactでTodoアプリ、学習記録アプリを作れるぐらい

**今回**
- supabaseを使用して、DBを作成
- firebaseでデプロイ
- jestを使用してテストを作成
- GithubActionsでCICD

これらができるようになったという実感がすごくあります。

# 大変だったところ
GithubActionsを使用するのは初めてだったため、job(処理の単位)の実行方法から、job間のartifact(互の働き)を理解するのに時間がかかりました。
初めてのことをやるのは試行錯誤の連続でしたが、やり遂げた際は達成感があります。

# やればできる
Reactを学んだことがない段階では、ReactのテストからCICDをやるなんて想像していなかったです。
ただ、しっかりと学習を進めていけばできるようになりました。
毎日学習することはやはり大事ですね。

# おわりに
まだまだ、Reactについて学ぶことは多いのでこれからも学習を続け、また学んだことを記事にしたいと思います！

# JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？

気になる方はぜひHPからライン登録お願いします👇

https://projisou.jp