OmniAICreator/Qiita-1.07M huggingface dataset:
素数を出力するプログラムをRubyで書いてみた

# きっかけ
あるイベントで素数まつなかさんにお会いしたのが始まりです。
数学博士でありながらRailsエンジニアでもあるすごい人です。
まつなかさんについての詳細は以下動画が面白いです。

https://www.youtube.com/watch?v=6O9xsjDphf8

# 素数の本
そのイベントで「素数表１５万個」という本に出会いました。
ただひたすら素数が書いているだけな本ですが、ある１ページが気になった。
そこにはC++で素数を出力するプログラムのソースコードが書いてありました。
試さずにはいられなくなり、まつなかさんにお願いして譲ってもらいました。

https://ankokudan.org/d/d.htm?detail156-detailread-j.html

# 素数コード
実際に書いてあったコードです。
ターミナルアプリによっては、最初の出力がカットされる場合あり。

```c++:prime_num.cpp
#include <iostream>
#include <vector>
using namespace std;

int main(){
    int maxn = 2020000;
    vector<bool> n;
    n.resize(maxn,1);

    for(int i=2; i<maxn; i++){
        if(n[i]){cout << i << endl;}
        for(int j=i; j<maxn; j+=i){
            n[j] = 0;
        }
    }
    return 0;
}
```

# Rubyに変換

今回は生成AI(ChatGPT)に聞いてみました。
C++で何となく分かっても難しかった。
今回はどのような仕組みになっているかを重視しました。

```ruby:prime_num.rb
maxn = 2_020_000
n = Array.new(maxn, true)
n[0] = n[1] = false # 0と1は素数ではない

(2...maxn).each do |i|
    if n[i]
        puts i
        (i * 2...maxn).step(i) do |j|
            n[j] = false
        end
    end
end
```

# 解説(ChatGPTからの引用）

## 何をしているの？
このコードは「**素数**」を探して、それを全部表示しています。  
素数とは、**1と自分自身以外の数字では割り切れない数字**のことです。たとえば、`2, 3, 5, 7` などが素数です。

## どうやって素数を見つけるの？
コンピュータがたくさんの数字をチェックして、「これは素数かな？」と調べています。この方法を **「エラトステネスの篩（ふるい）」** と言います。

### ステップ
1. **大きなリストを作成**  
   202万個の数字を用意し、最初は「すべて素数かもしれない」と仮定します。

2. **0と1を除外**  
   `0` と `1` は素数ではないので、最初にチェックから外します。

3. **2から順番にチェック**  
   - `2` が素数なので「見つけた！」と出力します。
   - そして、`2` の倍数（`4, 6, 8, …`）をすべてリストから削除します。

4. **次の数字をチェック**  
   次に残っている数字（`3` など）を探して、それを素数として出力し、同じようにその倍数をすべて削除します。

5. **すべての数字を調査**  
   202万まで調査を続けると、最終的にリストには素数だけが残ります。

## このコードのすごいところ！
- とても効率的に素数を見つけられるアルゴリズムです。
- 一つずつ数字を調べるよりも、何倍も速い方法です。

## 例え話
たとえば、たくさんの友達が並んでいて、「素数の子だけ残って！」というゲームをしているとします。  
最初に「2の倍数の子は全員いなくなって！」と言い、次に「3の倍数の子は…」と進めていくと、最後には素数の子だけが残ります。

（引用ここまで）

# 感想
Rubyに変換し、解説を読んで素数の導き方が勉強になりました。
エラトステネスの篩って言葉があるのも初耳です。
例え話も友達を例にしていて分かりやすかった。
まつなかさんの動画は記事作成時に見つけたもので、爆笑してしまいました。

# あとがき
C++のコードについて、改良版を追記します。
改良点は以下の通りです。
- ``0``と``1``の出力を無効化
- 倍数の無効化範囲の改善　``j = i`` から ``j = i * i`` に変更

などです。


```c++:prime_num_v2.cpp
#include <iostream>
#include <vector>
using namespace std;

int main(){
    int maxn = 2020000;
    vector<bool> n(maxn, true);
    n[0] = n[1] = false; // 0 と 1 は素数ではない

    for(int i=2; i*i<maxn; i++){
        if(n[i]){
            for(int j=i*i; j<maxn; j+=i){
                n[j] = false;
            }
        }
    }

    for(int i=2; i<maxn; i++){
        if(n[i]){
            cout << i << endl;
        }
    }

    return 0;
}
```
🧰パフォーマンス悪化で実質停止状態となったサーバーをインフラ未経験のエンジニアがチューニングして使えるようにしてみた🧰

この記事は [ex-crowdworks Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ex-cw)の21日目の記事です。

# はじめに
今年、株式会社クラウドワークスを退職した@nisyuuです。今年行ってよかった温泉地は[伊香保温泉](https://www.ikaho-kankou.com/)です。
エンジニアとしてクラウドワークステック（旧クラウドテック）というフリーランスと企業をマッチングするエージェントサービスを開発していました。

テックではHerokuサーバーを使っていたのですが、ある日、ステージング環境でパフォーマンスが悪化してタイムアウトエラーが頻発するという問題に直面しました。
ステージング環境を使えない状態が続くと、リリース前の重要な機能を本番環境に近い環境で確認することができなくなります。リリース前にステークホルダーの確認が必要になる場合もあるため、今後の開発に影響が出ることは間違いありませんでした。
インフラエンジニア不在の中、下っ端エンジニアの私が早急に対処する必要がありましたが、この時遭遇した問題はサーバーのパフォーマンスチューニングをすることで解決することができました。

本記事では、実際に取り組んだチューニング方法を紹介します。

# 実施したチューニング

問題の解決を図るため、以下のような多角的なアプローチを採用しました。これにより、環境全体のパフォーマンスを向上させることができました。

## WEB_CONCURRENCYのチューニング

WEB_CONCURRENCYは、Heroku上のアプリケーションで同時に実行できるプロセス数（ワーカー数）を設定する環境変数です。
これにより、複数のリクエストを並列処理する能力が決まります。
主にCPUリソースの効率的な利用を目的として調整されます。

今回は、設定されている値を下げることでワーカー数を減らし、CPUの使用を抑えることで負荷を軽減させました。

- **ワーカー数の設定について**
  - ワーカー数を調整することで、1度に処理可能なタスク数を増やすことができます
  - ワーカー数を増やしすぎると、CPUの使用量が過剰に増加し、全体のパフォーマンスを低下させる可能性があります
  - ワーカー数が少なすぎると処理が滞り、リクエストの応答時間が増加する原因となります

## MALLOC_ARENA_MAXの調整

MALLOC_ARENA_MAXは、glibcが提供するメモリ管理機能の一部で、メモリプール（アリーナ）の最大数を指定する環境変数です。
この設定は、アプリケーションのメモリ割り当ての挙動に影響を与え、特に高負荷環境でメモリ使用量の制御に役立ちます。

問題発生時のステージング環境の割り当てメモリは少なかったため、MALLOC_ARENA_MAXの設定値を下げることでメモリを使い過ぎないように変更しました。

- **メモリプールの設定について**
  - MALLOC_ARENA_MAXの値を増やしすぎるとメモリ消費量が過剰に増加し、システムに負荷がかかる場合もあります
  - 値を小さくしすぎると処理速度が低下する可能性もあるため、バランスの取れた設定が重要です

## jemallocの導入

jemallocは、効率的なメモリアロケータとして知られており、標準的な`malloc`と比較してパフォーマンスの向上が期待できます。
主に大規模なアプリケーションや高負荷なシステムで使用され、メモリの断片化を減少させる特徴があります。

メモリの不足はログを見ても顕著に表れていたため、Rubyがコンパイル時に使用するメモリアロケータを標準の`malloc`から`jemalloc`に変更しました。

- **メモリアロケータの最適化**
  - `jemalloc`は、メモリアロケーションの効率が高く、特に高負荷環境でその効果を発揮します
  - この変更により、メモリ使用量が削減され、全体的な応答性が向上しました

# おわりに

上記の対策を実施した結果、メモリ使用量を100MB以上削減することができました。割り当てメモリが500MBで上限いっぱいまで使用していたため、5分の1を節約できたことになります。
これにより、ステージング環境での応答速度が改善され、安定してステージング環境での動作確認ができるようになりました。

インフラエンジニア不在のチームでは、インフラの重要な話が蔑ろにされがちです。
もしチームにインフラエンジニアがいないのであれば、意志を持ってチーム全員でインフラに関わってください。
何か問題を提起している人がいれば、傾聴力を持って積極的に聞き入ってください。
絶対200%達成でよろしくお願いします。
CodeIgniter,PostgreSQL,jQuery現場で学んだこと12月20日①【週末のアウトプット】

## はじめに
業務でわからないことなどを週末で調べまとめて
アウトプットするコーナーです。

自分のためのアウトプットなのでわかりづらかったりしたらすみません。
コメントいただけたら自分の解釈を答えますし、間違ってたら教えていただきたいです。

#### 早速本題！！

## 取得したデータを指定の桁数まで「0」埋めする PHP,SQL


取得したデータが例えば「10」だったとしたとき、
「00010」のように先頭に足りない分だけ0を足す方法。
### ・PHP
```php
str_pad($data, 5, '0', STR_PAD_LEFT);
```
第一引数・・・対象データ　今回は10の想定
第二引数・・・桁数の指定　今回は5桁
第三引数・・・足りない桁数を何で埋めるか？　今回は0で埋める
第四引数・・・足りない分どこから0で埋めるか？　今回は先頭（左）からを指定

### ・SQL(postgreSQL)
```SQL
SELECT TO_CHAR(CAST(column_name AS INTEGER), 'FM00000') AS formatted_value
FROM table_name;
```
①対象のカラムをCASTの第一引数に入れ数値型に変更（文字列の場合エラーになるのであった方が無難）
②TO＿CHAR(指定のカラム,変換型)のようにすることで第二引数で指定した形に変換される。

※FMは先頭の空白を削除するもので、これがないと空白が先頭に入ってしまう場合がある。
FM00000とすることで先頭の空白を削除して5桁のデータになるように0で埋めるようになる。
他にもFM9,999.99のような指定をすれば先頭の空白を削除、3桁ごとに,をつける、小数点第二位まで表示と変換できる。

:::note warn
FM9,999.99 についてはまだ使ったことないです。
0の場合は足りない桁を0で埋めるでしたが9の場合は空白が入るようです。
ただ先頭にFMがあるので空白は消えるはずです。
:::


## 取得したデータの必要な部分だけを抜き取る　PHP
取得したデータが例えば00010だったとしたとき、10のように必要な部分だけを取り出す方法。
```php
$data_2 = substr($data, -2);
//　もしくは
$data_2 = substr($data, 3, 2);
```
第一引数・・・対象のデータ　今回は00010
第二引数（負）・・・後ろから何桁とるか　今回は-2で末尾から2桁
もしくは
第二引数（正）・・・何桁目からとるか？ 注意　※0から始める
第三引数（正）・・・長さ　今回2なので　2桁取得

:::note info
ただ今回の場合0が先頭に来ているだけなので数値型に直せば解決できます。
※00010の文字列を数値型にすると10になるため
:::
```php
$data = (int) $data;
``` 

## 登録したいTBの主キーを取得してMAX値より連番でUpdate Selectで登録できるように整える方法
想定
登録管理用のテーブルと
処理用のテーブル（いったんデータをコピーして更新処理などデータ加工する用）がある。

処理用のテーブルから登録用テーブルに登録する前に主キーを更新しないと登録できないので
重複エラーになってしまうのでその準備を行う。
```SQL
Update 処理用テーブル t1
Set primaryKey = TO_CHAR(
    (
        Select Coalesce(Max(Cast(primaryKey As Int)),0)
        From 登録管理用のテーブル
    ) + (
        Select seq From (
            Select primaryKey, 
                   Row_number() Over (Order By primaryKey) As seq 
            From 処理用テーブル t2
            Where t1.primaryKey = t2.primaryKey
    )
,'FM0000000000')
```
Update 処理用テーブル t1
Set primaryKey =　ここまではわかると思うので説明割愛
 
まず
```SQL
    (
        Select Coalesce(Max(Cast(primaryKey As Int)),0)
        From 登録管理用のテーブル
    )
```
↑　①登録したいテーブルの主キーの最大値を取得する。
データがない場合には0と取得できる。

```SQL
(
        Select seq From (
            Select primaryKey, 
                   Row_number() Over (Order By primaryKey) As seq 
            From 処理用テーブル t2
            Where t1.primaryKey = t2.primaryKey
    )
```
↑　②ここが難しい。
Row_number()・・・行番号を振る関数
Over (Order By primaryKey)・・・primaryKeyを元に昇順で並び替え

この二つを合わせることで
primaryKeyを小さい順で並び変えて上から連番を振る。連番の名前をseqとする。
Where句で対象のデータを特定

```SQL
TO_CHAR(
    (
        ①　// 登録したい主キーのMAX値
    ) + (
        ②　// １からデータの数だけ採番した配列
    )
,'FM0000000000')
```

↑　③主キーのMAX＋採番という結果になるので次に
現在の主キーのMAXが100だった場合
100 + 1
100 + 2　
100 + 3・・・のように重複しないような値を数値型で作ることができる。

その数値型の値をFM0000000000型に直してSet句で更新をかける。


SQL慣れてない自分からするとかなりややこしかったが理解して感動しました。
Supabase CLIを使ってローカルに環境を作る

最近Supabaseを触っているので、備忘録としてローカルにSupabase環境を作るところを書いてみます。
認証認可についてはスルーします。

## インストール
まずはSupabase CLIのインストール。
```shell
brew install supabase/tap/supabase
```
https://supabase.com/docs/guides/local-development/cli/getting-started

## 初期化
適当なディレクトリで初期化する。
```shell
mkdir supabase_sample
supabase init
```
初期化するとsupabaseディレクトリが作成されます。
この中にsupabaseの設定ファイルが置かれていたり、migration・functionファイルを作っていったりします。

## 立ち上げ & 停止
```
supabase start
supabase stop
```

Dockerコンテナが色々と立ち上がり、以下のように各サービスのURL等が表示されます。
![スクリーンショット 2024-12-21 12.21.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3081679/9f6f5e67-a591-e58c-50b1-5aa395ce062e.png)


## テーブル作成
https://supabase.com/docs/reference/cli/supabase-migration

マイグレーションファイルの作成
```shell
supabase migration new create_tasks_table
```
```sql:./supabase/migrations/xxxxxxxxxxx_create_tasks_table.sql
CREATE TABLE tasks (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  name TEXT NOT NULL,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT now(),
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT now()
);
```

ローカルDBにマイグレーションを適用
```shell
supabase migration up --local
```



## REST API
立ち上げ時に表示されたStudio URLからSupabaseのダッシュボードを開いてテスト用のデータを追加しておきます。
![スクリーンショット 2024-12-21 12.27.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3081679/4a025c28-8e79-5c79-b9df-dbf004847356.png)


各テーブルに対応したAPIをSupabaseが用意してくれています。
こちらも立ち上げ時にAPI URLが表示されているので叩いてみます。
REST APIのパスは`/rest/v1/{テーブル名}`となります。

https://supabase.com/docs/guides/api

### GET
```
curl 'http://127.0.0.1:54321/rest/v1/tasks'
```
![スクリーンショット 2024-12-21 12.28.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3081679/b707004b-5a80-6ae2-6dbc-f6a8bcd72b11.png)


### POST
```
curl -X POST 'http://127.0.0.1:54321/rest/v1/tasks' \
-H "Content-Type: application/json" \
-d '{"name": "sample_2"}'
```
![スクリーンショット 2024-12-21 12.31.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3081679/5039e47d-c0db-1439-fe24-93d28a406ac1.png)


## 終わり
ひとまず開発が始められそうなところまで！
Playwrightのプロジェクト設定で実現するテストの前処理と後処理について

# テストの前処理と後処理について

playwright.config.tsのprojectを活用することによって、前処理→テスト→後処理という一連の処理を定義することができます。その一例が以下です。

```tsx
  projects: [
  
    // ユーザー認証を行い、ユーザー情報を保存する
    { name: 'setup', testMatch: 'auth.setup.ts' },
    
    // 新規記事を作成する
    {
      name: 'articleSetup',
      testMatch: 'newArticle.setup.ts',
      // setupを実行してからarticleSetupを実行
      dependencies: ['setup'],
    },
    
    // 記事のいいねボタンが機能することを確認するテスト
    {
      name: 'likeCounter',
      testMatch: 'likesCounter.spec.ts',
      // storageStateを読み込み、保存しておいたユーザー情報を使用する
      use: { ...devices['Desktop Chrome'], storageState: '.auth/user.json' },
      // articleSetupを実行してからlikeCounterを実行
      dependencies: ['articleSetup'],
      // テストが終了したらarticleCleanUpを実行
      teardown: 'articleCleanUp',
    },
    
    // 記事の削除を行う
    {
      name: 'articleCleanUp',
      testMatch: 'articleCleanUp.setup.ts',
    },
  ],
```

この一連の処理の中心はlikeCounter です。

これの前処理として setup と articleSetup が、

しして後処理として articleCleanUp が存在しています。

これらは、dependencies と teardown によって順序が制御されています。

dependencies として指定したものが必ず事前に実行されるようになっており、

teardown として指定したものが必ずその後に実行されるようになっています。

# グローバルな前処理と後処理の定義について

特定のテストやプロジェクトではない、グローバルなテストの前処理と後処理についてはplaywright.config.ts にて以下のように定義します。

```tsx
export default defineConfig({
  testDir: './tests',
  /* Run tests in files in parallel */
  fullyParallel: true,
  /* Fail the build on CI if you accidentally left test.only in the source code. */
  forbidOnly: !!process.env.CI,
  /* Retry on CI only */
  retries: process.env.CI ? 2 : 0,
  /* Opt out of parallel tests on CI. */
  workers: process.env.CI ? 1 : undefined,
  /* Reporter to use. See https://playwright.dev/docs/test-reporters */
  reporter: 'html',
  /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
  use: {
    /* Base URL to use in actions like `await page.goto('/')`. */
    // baseURL: 'http://127.0.0.1:3000',

    /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
    trace: 'on-first-retry',
    extraHTTPHeaders: {
      Authorization: `Token ${process.env.ACCESS_TOKEN}`,
    },
  },
  // ここに記述
  globalSetup: './global-setup.ts',
  globalTeardown: './global-teardown.ts',
```
Unicodeと仲良くするためのカスタム関数

昨日の @Fenril058 さんの記事に触発されて。

マイ「文字系便利関数」2題
-------------------------

先日の[フォントの記事](https://qiita.com/jado4810/items/5dd9f1b41ea5d1a4ec74)でもちょっと書きましたが、結構いろんな文字を扱うことが多く、文字に関する関数を色々書いてますので、ちょっと投下してみます。

ただ、かなり昔に書いて`init.el`の底に沈んでるやつをドブ浚いしたものですので、コードの品質についてはご容赦くださいｗ
長年使い倒してるものなので、多分バグとかはないと思いますけど。

文字の素性を出す
----------------

「今コピペした文字って何者?」みたいな場面によく出くわすので、こういう関数を書きました。

```elisp
(defun my:split-char-at-point ()
  "Analyse character at the point."
  (interactive)
  (let ((ch (char-after (point))) s u u8 spec cs cp
        (number-to-hex2 (lambda (c) (format "%02x" c)))
        (number-to-oct (lambda (c) (format "0%o" c))))
    (when ch
      (if (>= ch 32)
          (setq s (char-to-string ch)))
      (setq u (encode-char ch 'ucs))
      (setq u8 (mapcar 'string-to-char
                       (split-string (encode-coding-char ch 'utf-8) "" t)))
      (setq spec (split-char ch))
      (setq cs (car spec) cp (cdr spec)))
    (message
     "%s[%s]:%s%s%s"
     (if ch (number-to-string ch) "--")
     (if s s "--")
     (if u (format " u%04x(%d)" u u) "")
     (if u8 (format " utf8=0x%s" (mapconcat number-to-hex2 u8 "")) "")
     (if cp (format " %s=0x%s(%s/%s)"
                    (symbol-name cs)
                    (mapconcat number-to-hex2 cp "")
                    (mapconcat 'number-to-string cp "-")
                    (mapconcat number-to-oct cp "-")) ""))))

```

適当なキーにバインドすると、押した際にカーソル位置の文字の内部コード、Unicodeと、ローカル文字セットでのコードがわかります。

なぜかエラーになる入力文字列が、半角の長音文字使ってるせいだ、みたいなのは一瞬でわかります[^1]。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667105/a1d11035-a8fe-47c1-49df-f7139ef5aadf.png)

実体参照に展開する
------------------

どこかからコピペした「なぜか入力できない文字」を、HTMLの実体参照に展開してくれます。

リージョン指定があればリージョン内、なければカーソル位置のワードが対象となります。

誤爆すると怖いですが、まぁアンドゥくらいできますよね、という前提[^2]でお願いします。

```elisp
(defun my:charref-expand-region-or-word (arg)
  "Expand the current region, or the word at the point if the mark is not active, to the sequence of numeric characters references."
  (interactive "P")
  (let (beg end ch subst)
    (cond
     ((and transient-mark-mode mark-active)
      (setq beg (region-beginning) end (region-end)))
     (t
      (save-excursion
        (backward-word) (setq beg (point)) (forward-word) (setq end (point)))))
    (goto-char beg)
    (while (< (point) end)
      (setq ch (char-after (point)))
      (when ch
        (if (>= ch 32)
            (setq subst (concat subst (format "&#%d;" (encode-char ch 'ucs))))
          (setq subst (concat subst (char-to-string ch)))))
      (forward-char))
    (goto-char beg)
    (delete-region beg end)
    (insert subst)))
```

[^1]: 今時はそれなりのフォントを設定しておけば見分けが付くものも多いですが。
[^2]: このため、site-lispとかに突っ込んで組織内に展開するのは推奨しませんｗ
`console`がimportされてうっとうしいのを解決する方法

# はじめに
`console.log`を打ちたいだけなのに、`import { log } from "console";`が勝手にimportされてエラーになる...なんてことはありませんか？

Next.jsで開発しているとあるあるだと思うのですが、これが発生するとエラーになり少しうっとうしいのですよね。

今回はそれを解決する方法を紹介したいと思います。

## 解決法

**VSCodeのSnippets機能を使う**

これを使用すると....

![test1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778030/284b2550-c209-af23-411f-daa85808baca.gif)

このように、勝手に`import { log } from "console";`を追加されることがなくなります！

### 手順
1. 任意の拡張子のsnippetsファイルを作成
2. `.vscode/setting.json`に追記

この2ステップだけです。
順に解説していきます。

#### 1.任意の拡張子のsnippetsファイルを作成

今回はNext.jsを想定しているので、とりあえず`***.ts`と`***.tsx`で設定します。

以下のコマンドをプロジェクトルートにて実行します。

- `.tsx`用
```zsh:terminal
$ mkdir -p ./.vscode && [ -f ./.vscode/tsx.code-snippets ] && echo "Error: ./.vscode/tsx.code-snippets already exists" || echo '{
  "console.log": {
    "prefix": "log",
    "body": ["console.log('\''$1'\'');"],
    "description": "Log output to console"
  }
}' > ./.vscode/tsx.code-snippets
```

- `.ts`用
```zsh:terminal
$ mkdir -p ./.vscode && [ -f ./.vscode/ts.code-snippets ] && echo "Error: ./.vscode/ts.code-snippets already exists" || echo '{
  "console.log": {
    "prefix": "log",
    "body": ["console.log('\''$1'\'');"],
    "description": "Log output to console"
  }
}' > ./.vscode/ts.code-snippets
```


<details><summary> Error: ./.vscode/(tsx | ts).code-snippets already existsが表示された場合 </summary>

ファイルがすでに存在する場合、上書きを防ぐためエラーを出すようにしてあります。
その場合、手作業でファイル内に以下を追加してください。

```json:tsx.code-snippets
{
  ....省略
  "console.log": {
    "prefix": "log",
    "body": ["console.log('\''$1'\'');"],
    "description": "Log output to console"
  }
}
```

```json:ts.code-snippets
{
  ....省略
  "console.log": {
    "prefix": "log",
    "body": ["console.log('\''$1'\'');"],
    "description": "Log output to console"
  }
}
```
</details>

#### 2.`.vscode/setting.json`に追記
1の設定だけでは充分でないので、最後に`.vscode/setting.json`へ追記を行います。

```json:.vscode/setting.json
{
  ...省略
  "editor.snippetSuggestions": "top"
}
```

この設定を追加することで、snippetsに登録されたものは補完時に優先され、一番上に表示されるようになります。

![スクリーンショット 2024-12-21 12.32.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2778030/fe19b010-de53-4314-83d8-5dcdd016a2d0.png)

$\tiny{↑ずっと邪魔してきていた"console"が4番目に...!}$

これで設定は完了となります。


## さいごに

こういった集中力が削がれるような小さな問題を積極的に解決して、快適な開発環境を整えていきたいですね。

最後までお読みいただきありがとうございました！
コーディング時のチェックリスト（自分用）

### 設計
1. 変更の背景（目的）を確認したか？
1. 影響範囲を整理して疑問点を全て洗い出して質問したか？

### 設計
1. 横展開は必要か

### コーディング時
1. 簡単なプログラム設計を実施したか

### DBアクセス
1. N+1は発生しないか
1. DBアクセスのパフォーマンスに問題ないか
1. SQLインジェクションは発生しないか

### 特殊な条件での動作確認
1. レスポンシブ対応の動作確認をしたか
1. ダークモード時の動作確認をしたか
1. 一通りのパターンで画面を動かしたか

### リファクタリング
1. エラーハンドリング
1. 将来的な変更に強い構造か
1. 自分で読んで理解できるか
1. 他の人が読んで理解できるか
1. コードの構造の違和感を見逃していないか
1. 動作の違和感を見逃していないか
1. リファクタリングに時間をかけたか
1. 時間をおいて自分のソースを見直したか

### プルリクエスト時
1. 設計書との不一致はないか
1. テストを書いているか
1. コーディング規約
1. コメント（Codeiumも活用する）
1. 横展開は実施したか
1. 不要なコードが残っていないか
1. IDEの警告が出ていないか
1. テスト実行結果を張り付ける
1. Pipeline実行結果を張り付ける
1. 修正対象ソースのカバレッジを張り付ける
1. 修正内容の要約を記載する
1. 時間をおいて修正内容の要約が分かりやすいか見直したか
1. PRに関連するWork Itemを追加する
1. TaskをResolvedにしたか

### マージ後
1. チケットに作業時間を追記する
1. チケットをクローズする（必要な場合は親チケットもクローズ）
1. 設計書は最新化したか

### コーディング規約に関して

EditorConfigを使うとよいかも？
https://learn.microsoft.com/ja-jp/visualstudio/ide/create-portable-custom-editor-options?view=vs-2022
IMPORTRANGE関数をGoogle スプレッドシートで使おうとしたら「権限を追加しています…」から進まなかった。

https://rakumo.com/gsuite/gws-hint/google-sheets/importrange/

IMPORTRANGE関数をGoogle スプレッドシートで使おうとしたところ「権限を追加しています…」というテキストと共にぐるぐるアイコンが表示されるだけで動作が止まってしまいました。

調べたところ、他の方も同様の現象が起きていました。


https://qiita.com/wau/items/0f204f831f43f5543dd5

https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q14218722884

私の場合はYahoo!知恵袋の方の「エクセル形式のシートに表示させようとしていた」ために起こっていた現象でした。新しいGoogleスプレッドシートを作成し、そちらでIMPORTRANGE関数を使ったところ問題なく表示されました。

備忘録として残しておきます。
【pnpm】ERR_PNPM_UNEXPECTED_STORE  Unexpected store location

## はじめに
最近話題の`pnpm` × `Next.js` × `Docker`を使ってパッケージのインストールをしていたとき，このエラーに詰まったので備忘録として書いておきます．

結論は，pnpmの仕組みを理解しないとエラーを起こすということです．

:::note warn
間違いを含んでいる可能性があるため，ご利用の際はご注意ください．
間違いを発見された方は，コメント等で指摘いただきたいです🙇
:::

## エラー
### エラーメッセージ
```zsh
Packages: +170
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 170, reused 59, downloaded 111, added 170, done
✔ Checking registry.
⠸ Installing dependencies.
Something went wrong. Please check the error below for more details.
If the problem persists, please open an issue on GitHub.

Command failed with exit code 1: pnpm add <package_name>
 ERR_PNPM_UNEXPECTED_STORE  Unexpected store location

The dependencies at "/Users/user_name/your_project_path/node_modules" are currently linked from the store at "/app/.pnpm-store/v3".

pnpm now wants to use the store at "/Users/user_name/Library/pnpm/store/v3" to link dependencies.

If you want to use the new store location, reinstall your dependencies with "pnpm install".

You may change the global store location by running "pnpm config set store-dir <dir> --global".
(This error may happen if the node_modules was installed with a different major version of pnpm)
```

### エラーを含むdocker-compose.yml
```❌ docker-compose.yml
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    volumes:
      - .:/app
      - .pnpm-store/v3:/app/node_modules # ←これがおかしい
    stdin_open: true
    tty: true
    command: pnpm run dev
```

## 原因と結果
そもそも`pnpm`は，storeというパッケージの依存関係を集約しておき，必要なプロジェクトはそれを随時参照するという方針を取っています．従来のパッケージ管理であった`npm`, `yarn`よりも何倍も軽量に管理できることで話題となっています．
したがって，それらを貯めておく`.pnpm-store`というディレクトリが生成されます．



**今回のエラー原因**はローカルにある`.pnpm-store`と，コンテナ内にある`.pnpm-store`を**共有していなかった**ことです．コンテナの`/app/node_modules`を指定していたため，ローカル環境とコンテナ間で異なるストアにアクセスしようとした際にリンクの競合が発生したことが原因だと考えられます．（pnpmの意味がないw）


### 更新後のdocker-compose.yml

そこで`docker-compose.yml`を以下のように修正すると解決しました．
```⭕️ docker-compose.yml
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    volumes:
      - .:/app
      - ./.pnpm-store/v3:/app/.pnpm-store/v3 # ←ここ！
    stdin_open: true
    tty: true
```

### Dockerfile

プロトタイプ段階なので，Dockerfileは適当です．
```Dockerfile
FROM node:23-alpine

WORKDIR /app

RUN npm install -g pnpm

COPY . .

RUN pnpm install --frozen-lockfile

EXPOSE 3000

CMD ["pnpm", "dev"]
```



## まとめ
今回のエラーは，pnpmのstoreの仕組みを理解していなかったために発生しました．ローカルとDocker間でstoreを共有することで解決しました．技術の背景情報などもある程度知っておく重要性を再認識しました．また，DockerfileでCOPYすべきでないファイルの指定など勉強したいと思います．
Lpic 303 v3 不合格体験日記

## はじめに
記事の内容はLpic 303 v3 の不合格体験記になります
誰かの参考になれば

スコアは　500/470 で３問足りなかったです。

## 学習方法
●<strong>ping-t オンリー</strong>

今のところ、ping-tしか選択肢ないのがちょっと厳しいですね。
AWSは各所に学習教材があるんですが…


### <strong>学習期間/どのように学習したか</strong>
半年v2のping-tをだらだらやってたんですが、v3に変わったので
０からまたやることになり時間がかかってしまいました。

不合格した現在では、模擬試験90% コマ問80%という万全の状態でした。


## 試験の所感
むっっず！！！！！
ネットワークipv6系の問題も出て困惑しました。サーバーしか勉強してないよぉ(´；ω；`)


## 感想
ping-tの合格体験記もあまり更新されないので、普通に難しい試験なんだろうなぁと思いました。
ping-tにも不合格の人がかける日記欲しくない？
試験料金も安くないので泣きました。

年明けにまた受けてきますが　自信なくしました。
【OpenAI ChatGPTクリスマスイベント第１２日目】o3の発表です。


　どうも、カーブミラーです。

　今回は、OpenAIのクリスマスイベント。今日は第１２日目。o3の発表です。

:::note info
本記事は、ChatGPTについての
記事です。　　　　あしからず。
:::
　ChatGPT等の動作状況を知らせる
　　OpenAIのステータスページ。
　　　[OpenAIステータス](https://status.openai.com/)
***
　さっそく、【本題】です。

　OpenAIの
　　クリスマスイベントの第１２日。
　　　最後の日ですね。

　　　まずはごあいさつ。
　　　　[OpenAI公式ページ](https://openai.com/12-days/?day=12)
　　　　　中身は、OpenAIの
　　　　　　イベントページ。

　イベントのようす。
　　[OpenAI公式YouTube動画](https://www.youtube.com/live/SKBG1sqdyIU?si=BkmwFs2Mkd6s-QQd)

　　[OpenAI公式ポスト](https://x.com/OpenAI/status/1870186518230511844?t=VE2_ZRAM6t6ZA2GyxTE9Rw&s=19)
……

　今回は？　

　o3 preview & call for safety researchers

　O3の紹介＆安全研究者の募集

　なんと、
　　o1の上を行くモデルの発表です。

　ひとつ解説しておきます。
　　なぜo2ではなく、o3かと言うと、
　　　スペインの通信業者Telefonicaが
　　　　英国やドイツ向けに展開する
　　　　　ブランド「O2」と被るのを
　　　　　　避けるため（By サム）

　o3の性能については、
　　推論や数学、コーディングなどの
　　　分野で、人間の専門家を上回る
　　　　高スコアを記録したそうです。

　発表されたo3モデルは
　　フルo3
　　o3-mini

　o3-miniは
　　低・中・高の3モードで
　　　推論時間を調整可能。

　　Adaptive Thinking Time機能
　　　というらしい。

　　コーディング用に
　　　最適化されたモデルとのこと。

　2025年1月末ごろに
　　安全性を確保した上で
　　　o3-miniから一般提供を
　　　　始める予定だそうです。

　　その後、
　　　o3も公開予定らしい。

　どのユーザーに提供するのか、と
　　X-Twitter民たちがささやいています
　　　けども、“一般提供”って言ってます
　　　　から、無料ユーザー以外には
　　　　　出してくれるでしょう、多分w

[Greg Brockmanポスト](https://x.com/gdb/status/1870176891828875658?t=wpUbfebdk4yYEnAT4VNVVQ&s=03)
>（DeepL翻訳）
>我々の最新の推論モデルであるo3は、我々の最も難しいベンチマークを一段階機能改善した画期的なものだ。

[サム・アルトマンポスト](https://x.com/sama/status/1870266813248053426?t=5EEiZs2azPRKx22sL3qGsg&s=19)
>（DeepL翻訳）
>O3-miniは、多くのコーディング・タスクにおいて、大幅なコスト削減を実現しながらO1を上回るパフォーマンスを発揮する！
***
　参照
　[チャエンさんポスト](https://x.com/masahirochaen/status/1870169442342355372?t=hUd-UR4_7d1cxSxMn9GsWg&s=19)

　[bioshok（INFJ）さんポスト](https://x.com/bioshok3/status/1870176362683871735?t=reDGcPp8BRhT9qd_EajKkg&s=19)

　[ITmedia AI＋ページ](https://www.itmedia.co.jp/aiplus/spv/2412/21/news081.html)

　[ChatGPT研究所さんポスト](https://x.com/ctgptlb/status/1870179038431752471?t=84gmREaCnZMmBNp0Pc0H7g&s=19)

　[ChatGPT研究所さんページ](https://chatgpt-lab.com/n/nc3c0040035c1)

　[しょーてぃーさんポスト](https://x.com/shoty_k2/status/1870244191810531649?t=gKCmspnkb5fWboOkOHD6yQ&s=19)

　[木内翔大さんポスト](https://x.com/shota7180/status/1870246895542776233?t=3ZKdpP35pGA8daGgPlwUOw&s=19)
***
　最後に、安全研究者の募集
[サム・アルトマンポスト](https://x.com/sama/status/1870176283851903152?t=2xjZVhhs9ALG0IFN6gjKLg&s=19)
>（DeepL翻訳）
>もしあなたが安全性研究者であれば、O3-miniとO3のテストに参加することを検討してください。
>
>openaiの全員がこれらのモデルを作るために努力し、創意工夫したことを非常に誇りに思います。
>
>(そして何よりも、みんながこれで何を作るのか楽しみだ！）

　以下は、日本語字幕&日本語音声付き。
　　[エクセル兄さんポスト](https://x.com/excel_niisan/status/1870222744694280561?t=UEnX1Egju4eP5DQi5J2jLQ&s=19)

　　再生スピードが速いので
　　　0.75くらいに
　　　　調整した方が良いかと。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
タイミーの報酬確定画面に「お疲れ様でした」を追加しました

# はじめに
お疲れ様です! 株式会社タイミーのAndroidエンジニアをしているぐーにゃんです。

この記事では、タイミーのAndroidアプリの報酬確定画面に「お疲れ様でした」のコンポーネントを追加した話とそれに関する技術的な話をしていきたいと思います。

# 報酬確定画面とは
タイミーはスキマ時間に働ける単発のアルバイトのマッチングプラットフォームを提供しています。タイミーを利用するワーカーさんは、自分が働きたい時間に好きな仕事を見つけて単発で働けます。タイミーのアプリ上でQRコードを利用して出退勤することができ、退勤してすぐにお給料を受け取れます。

今、タイミーで働いてQRコードを用いて退勤すると以下の画面が表示されます。

<img width=25%><img width=50% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963359/06582267-2151-98b5-a72a-76e746d43fc3.png">


実はこの画面の「お疲れ様でした」のコンポーネントはiOSアプリや公式サイトには存在していたのですが、Androidアプリのみこの実装が漏れていました（今まで「お疲れ様でした」を伝えられていなかったワーカーさんには申し訳ありませんでした）。

普段SNSやブログにてタイミーで働いた感想を書いているワーカーさんの投稿を拝見しているのですが、ふとした瞬間に、Androidアプリのこの画面で「お疲れ様でした」がないことに気がつきました。そして、その修正をなんとか年内のリリースに間に合わせることができました。

# 技術的な話
この画面はタイミーの歴史の中でもかなり古い画面であり、XMLレイアウトで記述されていました。今回の変更ではJetpack Composeで画面全体を再構築し、その上でAndroid 15からデフォルトになったedge-to-edgeへの対応も行いました。

[edge-to-edge対応](https://developer.android.com/develop/ui/views/layout/edge-to-edge)の詳細な話は割愛しますが、Material 3へ移行していないアプリですべての画面のedge-to-edge対応をするのはかなり大変な作業になりそうだなという実感を得ました...。
全画面での対応には、まずはMaterial 3への対応を優先して進めるべきではないかと現時点で個人的には考えています。

# 得られたもの
- edge-to-edge対応への肌感覚
    - Android 15からのedge-to-edgeのデフォルト化という、今、おそらく多くのAndroidエンジニアが悩んでいる変更について本番のアプリで一例を作れたことで、その難易度を体感できました
- 今後の変更への柔軟性
    - Jetpack Compose化されたので改修が楽になりました
- 新しい機能へのアイディア
    - この画面は、タイミーのアプリの中でもワーカーさんにとって嬉しい気持ちになる画面の一つだと思います。改修を進める中でこの画面に関する新たなアイディアが湧いてきたので、来年はもっと良くなるよう改善していきたいです

# おわりに
タイミーでは毎日多くのクライアントとワーカーさんのマッチングが生まれ、その数だけのお疲れ様が生まれています。提供しているプラットフォームを介して、働いているワーカーさんの声を常に聞くためにも、日々多くのワーカーさんへのインタビューを実施しています。自身もインタビューに参加させていただき、時には非常にエモーショナルで我々が涙してしまうようなインタビューもありました。これからもワーカーさんの人生の時間が豊かになるようなアプリの開発をやっていきたいと思います。お疲れ様でした!

:::note info
QRコードはデンソーウェーブの登録商標です。
:::
初めてのメールサーバ構築

# はじめに

こんにちは。システムエンジニア歴2年目の者です。
最近、メールサーバを1から構築する機会がありました。私自身、インフラ分野には全く触れたことがなく、試行錯誤を繰り返しながらなんとか構築することができました。

この記事では、その際に得た知見や経験を共有したいと思います。これからメールサーバーを構築する方や、同じようにインフラ初心者の方のお役に立てれば幸いです。

# サーバー概要
利用したサービス
* AWS：EC2 AWSが提供しているクラウドサービスを利用
* Postfix：有名なメール転送エンジン
* OpenDkim：DKIM認証を実装するためのツール

# わからなかったこと
### SPFとDKIMとは
* **SPF**:「このドメインのメールはこのサーバー（IPアドレス）から送ります」とDNSで宣言する仕組みです
こちらを利用することで受信側は、送信元のIPアドレスを確認し、不正な送信元からのメールをブロックできます。
* **DKIM**：メールに電子署名を付けて、メール送信元が変わっていないかを確認する仕組みです
秘密鍵を利用して、電子署名を付与し、受け取ったメールサーバーは公開鍵を使って署名を確認し、送信元の正当性を検証します。

# テストで確認していた箇所
* ### **Gmailのソースを確認**
Gmailではメールを開いて、右上の3点リーダーから「メッセージのソースを表示」からSPF,DKIM,DMARCが通っているか確認できます
テストで送信したメールが意図したドメインから送られているか、認証は通っているかを確認しましょう(PASSならOKです)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3946893/90b2bdee-8345-13ac-e2e8-d51f06e94942.png)

* ### **迷惑メールに入っていないか**
今回は既存のIPを利用していたためそこまで重要視していなかったですが、送信したメールが迷惑メールに入っている場合、そのまま放置するとIPレピュテーションが落ちてしまうので、可能な限り開封や迷惑メールではない選択をする必要があります

# 実際に起きたエラー
### 1. テスト送信したメールが届かない

作成したメールサーバーからテスト的にメール送信をしようと思ったのですが、なぜか手元にメールが届きませんでした
ログを見てみると以下のログがありました
```
mail-server postfix/pickup[89246]: 9A0E810000BB: uid=0 from=<root> 
mail-server postfix/trivial-rewrite[92607]: error: open database /etc/postfix/transport.db: No such file or directory   
```
どうやら「transport.db」とファイルがないためエラーになっていそうでした
調べたところ、こちらのコマンドを実行することで、transport.dbのファイルが作成されました
```
--transport.dbを生成
postmap /etc/postfix/transport
--postfixの再起動
sudo systemctl reload postfix
```

なお、postfixで送信先の制限をしない場合は、main.cfのファイルから以下の記載を削除すればtransportの制限を参考にしないで送信できるみたいです
(実践していないので参考程度にしていただければ)
```
transport_maps = hash:/etc/postfix/transport
```

# 最後に
実はこのメールサーバー構築後、別の環境で再度メールサーバーを構築する機会がありました。現在構築中ですが、そちらも機会があったら記事にする予定です！
【PHP】User-Agent によるXSS攻撃に気を付けるべき

# User-Agentとは
アクセスしたユーザーが利用しているブラウザやOSなどのソフトウェア情報のことですが...
そのはずが、めちゃくちゃなことになってます。

レスポンシブ対応やアクセス解析、ログ記録などのために使われていましたが、互換性やらの理由でごちゃごちゃしているのも事実。
ブラウザの特定方法が以下に記載されていました。

https://developer.mozilla.org/ja/docs/Web/HTTP/Browser_detection_using_the_user_agent#%E6%8E%A2%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E6%83%85%E5%A0%B1%E3%81%8C%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%A8%E3%83%BC%E3%82%B8%E3%82%A7%E3%83%B3%E3%83%88%E6%96%87%E5%AD%97%E5%88%97%E3%81%AE%E3%81%A9%E3%81%AE%E9%83%A8%E5%88%86%E3%81%AB%E5%90%AB%E3%81%BE%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%81%8B

# PHP での取得方法
PHP (ウェブ実行) では$_SERVERという配列のスーパーグローバル変数が使えます。
このグローバル変数にはサーバーに関する情報が入っており、以下のようにHTTP_USER_AGENTというキーを指定することでUser-Agentを取得できます。

```php
echo $_SERVER['HTTP_USER_AGENT'];
```

```
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
```

## 注意すべき点
User-Agent って簡単に偽装できます。
なのでアクセス解析やらする場合も完全な信憑性があるとは言えません。

あと、偽装できるということは、そう。
XSS攻撃されかねないということです。

私もまさかUser-AgentでXSS攻撃できるとは思ってもいませんでした。

User-Agent に`<script>...</script>`が埋め込まれており、User-Agentのログを取ってそのまま表示させるとそれが実行されてしまうのです。

以下のようなJavaScriptがUser-Agentに埋め込まれてリクエストされたとします。
```php
<script>alert('XSS!');</script>
```
そのUser-AgentをPHP側で取得してそのままの状態で保存し、ログ画面で出力すると実行されてしまいます。
(MimeTypeが`text/plain`ならば問題ありませんが、`text/html` であればブラウザ側でHTMLとして処理されるので)

### HTMLエスケープ処理をせよ

つまり、ウェブサービスなどを作る上でUser-AgentをHTMLで表示させるときは、**必ずHTMLのエスケープ処理**をすべき。

```php
echo htmlspecialchars($_SERVER['HTTP_USER_AGENT'], ENT_QUOTES);
```
念のためにENT_QUOTES (", ')もしておくこと
(例えば、`<a href="$user-agent">` ← あんまリンクとかで使うことはないだろうけど念には念を、属性でのXSS対策もしておくと安全？)

PHP の `htmlspecialchars()` は、HTMLエスケープを行うPHP標準の関数で、特殊文字（<, >など）をHTMLエンティティ（&amp;lt;, &amp;gt; など）に変換できるやつです。

User-Agentは基本的にエスケープ処理しても困ることはない！



# 最後に
私自身、自分で開発しているWebサービスにUser-Agentでスクリプトを埋め込まれてそれがログに残ってそれを見るための管理画面を確認したところリダイレクトさせられたことがあります。
マジで気を付けてください。

もちろんPHPに限らず
＊外資系会社勤め必見＊　VBA開発に記号と空白と日本語は使わないで

外資系会社でプログラム開発をしていると、意外なところで落とし穴に出くわします。特にVBAを使った開発では、環境の違いが思わぬトラブルを引き起こすことがあります。

:::note info
この記事の鍵は、VBAのプログラムは記号も含めてすべて英語で書くこと
:::


## 実際起こったシチュエーション

今回の出来事は、日本のPCでVBAコードを開発し、テストしていたときのこと。使用する環境として、日本語版のWindows PCと中国版のWindows PCがありました。日本のPCでテストを行ったときは問題なく動作していたVBAコード。しかし、中国のPCで同じコードを実行した途端、動作しなくなったのです。

### 「え、なんで？コードは正しいはずなのに」
動作確認済みのコードが別の環境で動かないのは納得できません。エラーも出てこないので、本当に分かりませんでした。色々な方のPCで実験したところ、日本語版のWindows PCでは動いたが、中国版のWindows PCでは動かないことが発覚！どうやら言語設定やロケール（地域設定）が原因のようでした。

:::note alert
VBAコード内で日本語のメッセージや文字列が含まれている部分が、中国版の環境では適切に解釈されず、エラーを引き起こしていたのです
:::



### 実際のメール送信コード

日本語版のWindows PC：実行OK
```VBA:VBA
    ' メールを作成
    Set OutlookMail = OutlookApp.CreateItem(0) 
    With OutlookMail
        .To = "example1@gmail.com" 
        .CC = "example2@gmail.com" 
        .Subject = "テストメール" 
        .Body = "こんにちは！これはExcel VBAを使ったテストメールです。" 
        .Display 
    End With

```

中国版のWindows PC：実行できない　→ 日本語が反映されない

```VBA:VBA
    ' メールを作成
    Set OutlookMail = OutlookApp.CreateItem(0) 
        .To = "example1@gmail.com" 
        .CC = "example2@gmail.com" 
        .Subject = "　　　　" 
        .Body = "　　　　　　　　　　　　　　　　　　　" 
        .Display 
    End With
```

解決方法

excelのセル指定にし、日本語はexcelに書く

![スクリーンショット 2024-12-21 11.30.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636287/09f57dc3-30c4-ff57-094a-3c9b76b00b23.png)

```VBA:VBA
    ' メール送信処理
    For i = 2 To lastRow 
        Set OutlookMail = OutlookApp.CreateItem(0) 
        With OutlookMail
            .To = ws.Cells(i, 1).Value 
            .CC = ws.Cells(i, 2).Value
            .Subject = ws.Cells(i, 3).Value 
            .Body = ws.Cells(i, 4).Value 
            .Display 
        End With
    Next i

```

この方法を使い、両方のPCで動きました

## まだこれはいい方

エラーにはなっていないけど、コード見たらわかるから。

:::note warn
もっとややこしいのは、「空白、記号」
:::


### 実際の句読点を使ったコード　（お題：１単語ごと句読点を追加する）

日本語版のWindows PC：実行OK

```VBA:VBA
        ' 例: 1単語ごとに句読点を追加
        If i < UBound(words) Then
            result = result & "、" ' 途中に読点を追加
        End If
    Next i

```


 中国語版のWindows PC：実行できない

```VBA:VBA
        ' 例: 1単語ごとに句読点を追加
        If i < UBound(words) Then
            result = result & "、" ' 途中に読点を追加
        End If
    Next i

```   
見た目同じなのになぜ？？

:::note warn
「、」が、PC城では日本語と中国語で違う句読点になっていた
「今日は、暑い」が「今日は,暑い」になったことありませんか？  それと同じで見た目同じでも違うみたいです。

:::

これは調べても出てこない、😅

解決方法

英語の「,」にする

```VBA:VBA
        ' 例: 1単語ごとに句読点を追加
        If i < UBound(words) Then
            result = result & "," ' 途中に読点を追加
        End If
    Next i

``` 

# 最後に

:::note info
文字も記号も、すべて英語で書くこと
:::

エラーにならないエラーが一番厄介ですね。。。
OpenWrtで普段のZSHの環境を用意するまで

# はじめに

この記事は、Qiita Advent Calendar 17日目の記事です。
以下の記事より、すべての記事をご覧になれます。

https://qiita.com/0_terarin_0/items/2b60d47a2d0e64a273c3

# 本編

やっと奮闘して普段のZSHの環境を用意することができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/b21681eb-6e87-7d60-7e58-fb450001f7e4.png)

ここでは順を追ってどうやったかを記していきたいと思います。

## 失敗したこと

- Gitを使ったインストール
- ホスト上のSSHでのホストからゲストに向けたSCPを使ったファイル転送

上の二つはできませんでした。Gitの方はまずそもファイルが足りないそうでこれに関しては解決しようにも解決できませんでした。（従ってこれ、Fastfetchも使うのを実現させるには結構時間がかかると思います。）また、なぜかOpenSSHのサーバーをOpkg経由で印刷してガイド通りにいろいろ変更したのですが、これも結局SSHが使えなくなって終わる解くことになっていますのでこれもまたいつか解決したいと思います。参考までに、下にリンクを貼っておきます。

https://openwrt.org/docs/guide-user/services/ssh/openssh_instead_dropbear

無理とか言うててもどないもならんおで、順番にやっていきましょう。

## ZSHのインストール

これは簡単ですね！

```zsh
opkg install zsh
```

## Oh-My-Zshのインストール

こちらはGitが使えなかったりして結構大変だったのですが、ネット上で解決策を探っているとどうやら下のようなスクリプトファイルを発見。

https://github.com/felix-fly/openwrt-ohmyzsh

ということで、こちらに記載のものをそのまま実行していきます。

```zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/felix-fly/openwrt-ohmyzsh/master/install.sh)"

which zsh && sed -i -- 's:/bin/ash:'`which zsh`':g' /etc/passwd
```

これで、Oh-My-Zshはインストールできました！

## 自分のテーマの転送

自分のOh-My-Zshのテーマを転送しました。こちらは、Mac側のリモートログインを許可してOpenWrt上でSCPを利用しました。

```zsh
scp user@10.0.2.1:~/.oh-my-zsh/themes/mytheme.zsh-theme ~
```

てかSSHをモドに戻さないといけない、、、。

## Zsh-autosuggestionsのインストール

こちらばかりはどこにも先例を見つけられなかったので、自力でスクリプトに書いてあることを一個ずつ実行していきました。

https://github.com/zsh-users/zsh-autosuggestions/blob/master/INSTALL.md

```zsh
opkg install wget && opkg install unzip

wget https://github.com/zsh-users/zsh-autosuggestions/archive/refs/heads/master.zip

unzip zsh-autosuggestions-master

mv ./zsh-autosuggestions ./.oh-my-zsh/plugins/zsh-autosuggestions

nano ~/.zshrc # Pluginsのところにzsh-autosuggestionsを追加

exec $SHELL -l
```

普段ならスクリプト一つでできるものが一つ一つやらないといけないのはめんどいけど、まあとりあえずできました！

# 最後に

前回と同じ感想でやっぱり組み込み向けのLinuxって結構難しいですね。勉強していきたいと思います。
Flow Emulator

[Previous << Data Collection](https://qiita.com/flowcadence/items/148c8e2779ed36284814)
[Next >> Clients](https://qiita.com/flowcadence/items/4d0e75b7f49d02f75445)

https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a#flow-cli-と-fcl

Flowエミュレータは、実際のFlowネットワークの動作をエミュレートする軽量なツールです。

エミュレータは、実際のネットワークAPIとほぼ同等の機能を持つように設計された、Flow Access APIを実装するgRPCサーバーを立ち上げます。

<h1>Running the emulator with the Flow CLI</h1>

エミュレータは、[Flow CLI](https://qiita.com/flowcadence/items/5ead732fad703556487d)（Flow 上で働くコマンドラインインターフェース）にバンドルされています。

<h3>Installation</h3>

[これらの手順](https://qiita.com/flowcadence/items/530223569e603e10e1a7)に従って、macOS、Linux、WindowsにFlow CLIをインストールしてください。

<h1>Usage</h1>

エミュレータの使用方法についてさらに詳しく知りたい場合は、[リポジトリのREADME](https://github.com/onflow/flow-emulator/#starting-the-server)をご覧ください。

*Last updated on **Dec 11, 2024** by **Chase Fleming***

翻訳元

https://developers.flow.com/tools/emulator

***
<b>[Previous << Data Collection](https://qiita.com/flowcadence/items/148c8e2779ed36284814)
</b>

[Flow blockchain / Cadence version1.0ドキュメント](https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a) (Flow Emulator)

<b>[Next >> Clients](https://qiita.com/flowcadence/items/4d0e75b7f49d02f75445)</b>
IBM Cloud PaaS ベストテン 2024年版

これは、[IBM Cloud Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ibmcloud)　21日目の記事です。

# IBM Cloud PaaS ベストテンの2024年版
年末の風物詩とも言うべき人気ベストテン。やってきました。なんとこの一年は昨年のAIトレンドを強烈に引き継いだ結果となりました。
今年のアプリトレンドから来年を占う本コーナー。しばしお付き合いください。

# IBM Cloud で利用できるサービスの変遷
コンテナアプリ開発・リリースに人気を集めているサービス「Code Engine」。watsonx各機能がIBM Cloudで利用できるようになってから、さらに利用されるようになってきました。
一方、IaaS領域では、AIX/IBMi、Linux on Powerが利用できる Power Systems Virtual Server（略称PVS）の機能充実に伴い、ご利用いただいているお客様数は増え続けています。

# お待ちかね IBM Cloud PaaS 人気ベストテン 2024
集計単位は、対象のサービスの売上です。
もちろん今年も日本のユーザーに絞って集計しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53057/f3d625bf-1bf5-65be-4caf-7bbe635553ff.png)

なんということでしょう。
Cloud Object Storageが昨年の雪辱を果たし、堂々の1位！そしてほぼすべてのサービスが入れ替わるという激動の結果となりました。
4～7, 9位はまさに watsonx で注目されたサービス群、そしてアプリケーション開発の基盤として不動の位置を築いた 8位の「Code Engine」と3位「Container Registry」、CI/CDの2位「Continuous Delivery」と、AIアプリケーションの高まりが強く反映した結果となりました。

予想を大きく外すことが無かった、ある意味、順当なランキングとなった感じですね。

# もうすぐベストテンから見る来年の傾向
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53057/baef1e35-1356-b51a-85d8-1d5947d36737.png)

ベストテン圏外だったけど、年間で上昇トレンドだったサービスをご紹介します。

やはりなんといっても「Power Systems Virtual Server」でしょう。
さらに、IaaS系のサービス「Virtual Private Cloud(VPC)」が本ランキングにも入ってきました。来年はこのIaaS系のサービスもランク入りしそうです。

そういえば、IBM Cloudの主要CPUはIntel Xeon Sapphire Rapidsです。2025年には最新CPUであるIntel Granite Rapidsや、AMD Epycの最新CPUも登場予定です。また、AI Acceleratorとして、NVIDIA GPUだけでなく、Intel Gaudi3や、AMD MI300などもサービス開始予定となっています。
Red Hat InstructLabも楽しみです。

さて。ここまでお付き合いいただきましてありがとうございました。
いかがでしたでしょうか？
ご利用いただいているサービスはランクインしていましたか？

IBM Cloud、来年も目が離せません。
【TS】ダミーの配列を作成する関数

```ts
const generateDummyArray = (num: number) => {
  return Array.from({ length: num }, (_, i) => `item-${i}`);
};

const dummyArray = generateDummyArray(5);
console.log(dummyArray);
// ['item-0', 'item-1', 'item-2', 'item-3', 'item-4']
```
2024年版 PowerShell 各ループの速度比較

# はじめに

先日こちらの記事を拝見しました。

https://qiita.com/acuo/items/9928e1fbb31b238d9705

衝撃でした。まさかPowerShellの代名詞と思ってた `ForEach-Object` がこんなにも遅かったなんて...

とはいえ元記事は2018年の記事なので、もしかしたら今は改善されているかもしれません。

ということで、そんな淡い期待も込めて自分の手元で計測してみたのでその結果を紹介します。

# 計測

[元記事に記載のコード](https://qiita.com/acuo/items/9928e1fbb31b238d9705#今回使ったコード全て)をそのまま使わせてもらいました。コピペで動くコードを貼ってくれる方は神ですね。

また対象は Windows PowerShell 5.1 に加えて PowerShell 7.4 (Windows PowerShell 5.1と同じWindows PC + MacBook Air) でも計測してみました。

# 環境

PowerShellの各バージョン (`$PSVersionTable`) は以下の通りです。

```txt:Windows PC
Name                           Value
----                           -----
PSVersion                      5.1.19041.5247
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.19041.5247
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
```

```txt:Windows PC
Name                           Value
----                           -----
PSVersion                      7.4.6
PSEdition                      Core
GitCommitId                    7.4.6
OS                             Microsoft Windows 10.0.19045
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
```

```txt:MacBook Air
Name                           Value
----                           -----
PSVersion                      7.4.5
PSEdition                      Core
GitCommitId                    7.4.5
OS                             Darwin 23.6.0 Darwin Kernel Version 23.6.0: Fri Jul  5 17:56:39 PDT 2024; root:xnu-10063.141.1~2/RELEASE_ARM64_T8122
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
```

PCスペックはざっとこんな感じです。

* Windows
  * CPU: AMD Ryzen 5 3500 (2020年2月発売)
  * RAM: 16GB
* MacBook Air
  * CPU: Apple M3 (2024年3月発売)
  * RAM: 8GB

# 結果

結果はこんな感じになりました。元記事の結果も並べています。

![図. 計測結果](https://www-tacos.github.io/qiita-images/20241221_pwsh_loop_perf/001.svg?1)

# 感想

やっぱり `ForEach-Object` がダントツで遅いんですね...

Windows PowerShell 5.1については、全体的に処理時間が短くなっているだけなので中身は特に変わってなさそうです。処理時間が短くなったのは単にマシンスペックがあがったからだと思われます。
ただ、処理時間の長かった方法ほど減少幅も大きいので昔よりはマシになったと言えなくもなさそうです。

PowerShell 7.4については、同じマシンでも5.1から7.4でどの方法も処理時間が半分くらいに短くなっていました。たぶん.NETのパフォーマンス向上によるものと思われます。

また7.4同士でもMacBook AirのM3チップだとさらに半分くらいになっていて、このレベルまでくると `ForEach-Object` を使って遅いと感じるケースはほぼないんじゃないかと思いますね。
ただForEachメソッドだけWindowsよりMacの方が遅くなっているのが気になりますね。誤差なのか仕様なのか？チップセットの違いによるものとか？

結論としては、昔も今も、5.1も7.4も、foreach文までとそれ以降で差が大きいので、シェルスクリプトで繰り返し処理を書くならまずforeach文を検討する方針にしようかなと思いました。
一方で、ターミナルであればワンライナーで書けるメリットが大きいのとそこまでデータが大きくなることもなさそうなのでこれからも `ForEach-Object` (というよりエイリアスの`%`) を使っていこうと思います。

# さいごに

いかがでしたか？

結局のところパフォーマンスの良しあしが影響するかはデータ量・用途次第なので、「こういう違いがある」というのを理解したうえでケースバイケースでなにを使うか選ぶのがいいのかなと思いますね。

最後まで読んでいただきありがとうございました。
MicroCMS：microcms-js-sdkを使ってデータを並び替える方法

こんばんは。

今日は「MicroCMS：microcms-js-sdkを使ってデータを並び替える方法方法」について説明します。


microCMS では、取得するデータをクエリパラメータや SDK のオプションで並び替える（ソート）ことが可能です。以下では代表的な方法や書き方を紹介します。

# REST API でのソート

## 書式
GET `https://[YOUR_SERVICE].microcms.io/api/v1/[ENDPOINT]?orders=[フィールド名]`

- 昇順: `orders=title`のようにフィールド名をそのまま指定
- 降順: `orders=-title`のように先頭に`-`を付与

## 使用例

- `publishedAt`昇順:
```
GET https://example.microcms.io/api/v1/blog?orders=publishedAt
```

- `publishedAt`降順:
```
GET https://example.microcms.io/api/v1/blog?orders=-publishedAt
```

- 複数フィールドで並び替え（最初に指定したフィールドを優先）:

```
GET https://example.microcms.io/api/v1/blog?orders=title,-publishedAt
```

# microCMS JS SDK でのソート

もし`JS SDK（microcms-js-sdk）`を利用している場合は、以下のように`queries.orders`オプションを指定できます。

```javascript
import { createClient } from 'microcms-js-sdk';

const client = createClient({
  serviceDomain: 'YOUR_SERVICE_DOMAIN',
  apiKey: 'YOUR_API_KEY',
});

(async () => {
  // 例: publishedAt を降順で取得
  const data = await client.get({
    endpoint: 'blog',
    queries: {
      orders: '-publishedAt',
    },
  });
  console.log(data);
})();
```

# その他の注意点

- 使用できるフィールド名:
フィールド設定（スキーマ）で作成したフィールドやデフォルトの`id, createdAt, updatedAt, publishedAt`などを指定可能です。
- 複数ソート:
`orders=フィールドA,-フィールドB`のようにカンマ区切りで複数指定できます。
- 絞り込みやその他オプションとの併用:
ソートに加えて、`limit, offset, filters`などのクエリパラメータを同時に利用できます。

以上が microCMS でデータをソートする基本的な方法です。
必要に応じて、昇順・降順の指定や複数フィールドの組み合わせなどを使って、目的の並び順を実現できると思います。

今日は以上です。

ありがとうございました。
よろしくお願いいたします。
【Rustで学ぶWebAssembly】#1-1-1 Hello, world! 変数と束縛

[前回](https://qiita.com/neet244/items/97d9b9ed7a5478171442)の続きから

### 1. cargo new パッケージ作成

```zsh
% cargo new hello-rust
    Creating binary (application) `hello-rust` package
note: see more `Cargo.toml` keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
```

### 2. cargo run パッケージビルド、実行

```zsh
cd hello-rust
cargo run

# => Hello, world!
```

### 3. 実装を書き換えてみる

src/main.rsを書き換える

```src/main.rs
fn main() {
    println!("Hello, Wasm!");
}
```

```zsh
cargo run

# => Hello, Wasm!
```

### 4.変数つかってみる

```rust
fn main() {
  let message = "Hello, Wasm!";
  println!("変数messageに束縛された値: {}", message);
}
```

### 5. 束縛について
Rustでは=演算子を使った変数と値の紐づけを束縛という。
変数は標準で変更不可（immutable）。
この辺結構特徴的だと思う（javascriptとかとごっちゃになりそう）。
```rust
fn main() {
  let message = "Hello, Wasm!";
  println!("変数messageに束縛された値: {}", message);
  message = "Hello, World!";
  println!("変数messageに束縛された値: {}", message);
}
```

エラーになって修正の提案をしてくれる。めちゃ優秀。
```zsh
error[E0384]: cannot assign twice to immutable variable `message`
 --> src/main.rs:4:3
  |
2 |   let message = "Hello, Wasm!";
  |       ------- first assignment to `message`
3 |   println!("変数messageに束縛された値: {}", message);
4 |   message = "Hello, World!";
  |   ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot assign twice to immutable variable
  |
help: consider making this binding mutable
  |
2 |   let mut message = "Hello, Wasm!";
  |       +++

For more information about this error, try `rustc --explain E0384`.
error: could not compile `hello-rust` (bin "hello-rust") due to 1 previous error

```

指示されたコマンドを打ってみる

```zsh
rustc --explain E0384
```

エラーについて解説が出てきた。すごい。

```
An immutable variable was reassigned.

Erroneous code example:

fn main() {
    let x = 3;
    x = 5; // error, reassignment of immutable variable
}

By default, variables in Rust are immutable. To fix this error, add the keyword mut after the keyword let when declaring the
variable. For example:

fn main() {
    let mut x = 3;
    x = 5;
}

Alternatively, you might consider initializing a new variable: either with a new bound name or (by shadowing) with the bound
name of your existing variable. For example:

fn main() {
    let x = 3;
    let x = 5;
}
```

提案された内容で修正するとエラーが出なくなる。

```rust
fn main() {
  let mut message = "Hello, Wasm!";
  println!("変数messageに束縛された値: {}", message);
  message = "Hello, World!";
  println!("変数messageに束縛された値: {}", message);
}
```
グループ会社のインターネット向け通信をできなくしてしまった。。

皆様のやらかし記事を見て力をもらいましたので、微力ながら私も投稿します。
何年か前の記事となり、現在の仕様と異なる可能性がありますのでご了承ください。

・構成
　冗長化されたSRXを中心に「内部」「旧外部」「新外部」「Gr会社内部」の４つに
　ゾーン分割しているが、「旧外部」は未使用となった。

・作業内容
　未使用となった「旧外部」接続向けのインタフェースを削除する。
　rethインタフェースの使用数が減るため、reth-countの数も減らす。

・本番作業
　事前に検証した通り、コンフィグを順調に削除し作業完了。ところがGr会社様より
　インターネット向け通信ができなくなったと連絡があった。
  「新外部」「Gr会社内部」のコンフィグは変更していないので、別の事象も疑ったが
  他の作業もなく、どう考えても当該SRXが怪しいため削除したコンフィグのうち
  retch-countを元に戻した〈reth-count 3 -> reth-count 4)ところ通信が復旧した。

　後日サポートに問い合わせたところ以下のような仕様とのこと
 　 reth-count 4だと以下が使用可能
　 　 reth0, reth1, reth2, reth3
  　reth-count 3にすると以下が使用可能
　  　reth0, reth1, reth2  

　rethインタフェースは若番から順に使用可能になるため、
　今回reth-count 4 -> reth-count 3に変更したことで
 　reth3（Gr会社内部）が使用不可となった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602415/d64d493a-ddd0-0da1-49f1-cd4895d8826b.png)

・その「やらかし」はなぜおきてしまったのか
　事前の検証ではコンフィグチェックしか行っておらず、show log messagesの確認を
　行っていなかった。（本当は動作確認までできればよかった）
　# ログの詳細は忘れたがreth-count変更による注意喚起のようなエラーが出ていたはず
 
・その「やらかし」を起こさないために次どうすればいか
　①検証時にshow log messagesを確認してコンフィグ編集後に意図しないエラーが発生していないかチェックする。
　②可能な限り実機にて動作確認を行う。
【faster-whisper】CUDA11で最新large-v3-turboを動かそうとしたときのエラー対処法

# はじめに

faster-whisperのv1.1.0で最新モデル「large-v3-turbo」がリリースされました。
早速faster-whisperをアップデートして推論するぞ！と思いましたがCUDA周りでエラーが出てしまったためその対処の備忘録です。

CUDA：11.6
GPU：NVIDIA GeForce RTX 3090
ドライバー: 560.94

# faster-whisperのアップデート

以下のようにfaster-whisperを`1.1.0`にアップデートしました。

```powershell
pip install faster-whisper -U
```
依存するライブラリの`av`、`ctranslate2`も更新されたようです。

```
Successfully installed av-14.0.1 ctranslate2-4.5.0 faster-whisper-1.1.0
```

# large-v3-turboが動かない、、

推論のコードを以下に変えて実行したところcuDNNプラグインが無いと怒られました。

```
Could not locate cudnn_ops64_9.dll. Please make sure it is in your library path!
Invalid handle. Cannot load symbol cudnnCreateTensorDescriptor
```

# 【解決策】ctranslate2のダウングレード

faster-whisper-1.1.0の要件に`ctranslate2<5,>=4.0`があり、これが悪さをしていました。
同時に更新されたctranslate2はCUDA12向けということで、CUDA11に対応するバージョンを強制的にインストールします。

```powershell
pip install ctranslate2==3.24.0
```

```
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
faster-whisper 1.1.0 requires ctranslate2<5,>=4.0, but you have ctranslate2 3.24.0 which is incompatible.
```

インストールが終わったとき依存関係のエラーは出ましたが、CUDA 11.6で無事に推論できました！
large-v3より明らかに早く、しかも文字起こし精度が高いです！

ぜひお試しください！