OmniAICreator/Qiita-1.07M huggingface dataset:
ツイッターでよく見るツリーに画像連投するやつをアレンジした

## 前置き
最近、ツイッターのアフィリに誘導するアレで
・１行コメントと画像１枚投稿
・ツリーで６～１０枚くらい続けて最後に「続きはこちら」
みたいなのがよくオススメに流れてきます。

あれ、ついついスクロールしちゃうんですよね。
そこで「アフィリエイトサイトをWPで作って、ページをめくるような動きを付ければ流行るんじゃね？」
さらに「なるべく簡単に投稿できるような仕組みをGASで作れるか？」
とふと思いついたので、その流れを説明

## 準備
・WPが導入できるサーバー（すでに契約してある）
・ドメイン（サブドメインで運用）
・WPテーマ（無料のテーマ利用）
・GAS（Google Workspace …無料プラン）
・コード生成AI（Claudeとか、無料プラン）
初期費用０円です

## ワードプレスインストール
さくっとインストールして、Cocoon子テーマ適用
投稿者権限でユーザー作成し、アプリケーションパスワード設定
パスワードはメモしておきましょう

## GASのコーディング（１）
REST APIで投稿できるようにする
GASで　スプシに入力した内容をWPに投稿するような仕組みを作成
ここはGlaudeやGoogleAIスタジオにコードを生成してもらう
「GAS RESTAPIでワードプレスに投稿」みたいなキーワードで生成できます。
その後、動作確認する

## GASのコーディング（２）
REST APIで投稿できたら、次は色々実用的な機能を追加してもらいます（AIに）
・URLから画像URLを取得し、その画像をWPに投稿
・カテゴリー指定し投稿
・投稿するHTMLを作成＆最後の続きはこちらのリンクも生成
・アイキャッチ画像は１枚目の画像を指定

## ページをめくるような動きを実装
WPの投稿で画像をめくるような動きをCSSとJSを使って実装
プラグインも色々ありますが今回はCSSとJS、さらに子テーマ内にファイルを置いて
HTMLで記述するだけで機能するようにします。
ここがハマりました。
・テーマによって相性みたいなのがあり、AIで生成してもらったコードで正しく動作しないケースがある
（TCDの無料テーマがこのパターンだった）
・AIに細かい指示を出せず、期待するような動きが見つからない

それでも何とか完成しました。
あとはアクセス数、契約数が増えればいいなー
【ML初心者アドベントカレンダー】スケーリングポリシーについて


# この記事の目的

スケーリングポリシーについて簡単に学ぶ

# オンデマンドリソースとプロビジョンドリソース

スケーリングポリシーの前に、オンデマンドとプロビジョンドの違いについて、簡単にまとめます。
モデルをデプロイする際は、要件に応じてリソースを選択する必要があります。（たとえばEC2については、オンデマンドで動かすのか、リザーブドで動かすのか、といった選択肢があります。）

| |オンデマンドリソース|プロビジョンドリソース|
|---|---|---|
|リソース提供|必要な時に使わせてもらう|事前に予約して確保しておく|
|料金|従量課金（使ったら使っただけかかる）|固定料金（あらかじめ決まった額を支払う）|
|柔軟性|必要な分だけ確保できるので高い|あらかじめ予約しておくので、低い|
|ユースケース|短期的または需要の予測が難しい場合|長期的または需要が安定している場合|
|コスト効率|短期利用なら良い|長期利用なら良い|
|パフォーマンス|不測の事態には対応できない恐れがある|事前に予約しておくので安定|


## スケーリングポリシーについて

クラウド文化にはスケーリングがつきものです。（偏見）
AWS では主に AutoScaling を使用してスケーリングを管理しますが、その手法についてもいくつかあるので簡単にまとめます。

### 手動スケーリング

https://docs.aws.amazon.com/ja_jp/autoscaling/ec2/userguide/ec2-auto-scaling-scaling-manually.html

管理者が手動でポチポチ増やす。

### 動的スケーリング

https://docs.aws.amazon.com/ja_jp/autoscaling/ec2/userguide/as-scale-based-on-demand.html

 * **ターゲット追跡スケーリング**
   * メトリクス (CPU使用率など) が目標の値へ近づくようにスケールイン、もしくはスケールアウトする。CPU使用率が90%以下を保てるようにインスタンス台数を調整する、みたいな設定ができる
 * **ステップスケーリング**
   * メトリクスに基づいてスケールイン、もしくはスケールアウトする。CPU使用率が90%を超えたらインスタンスを1台ふやす、みたいな設定ができる
 * **シンプルスケーリング**
   * 条件が満たされると、1回だけアクションを実行する。CPU使用率が90%を超えたらインスタンスを1台ふやす、という条件を定めたら、それが1回だけ実行される。古いポリシー

## スケジューリングスケジューリング

https://docs.aws.amazon.com/ja_jp/autoscaling/ec2/userguide/ec2-auto-scaling-scheduled-scaling.html

決められたタイミングでインスタンスの台数を増減する。たとえば、金曜日の夜はトラフィックが増加するので、金曜日の18時になったらインスタンスを3台増加する、みたいな設定ができる。

## 予測スケーリング

過去24時間以上最長14日間のメトリクスを参考に、トラフィックを予測してスケーリングポリシーを作成する。

https://docs.aws.amazon.com/ja_jp/autoscaling/ec2/userguide/predictive-scaling-policy-overview.html

---

SageMaker のエンドポイントについても、ほぼ同様のスケーリングが用意されています。

https://docs.aws.amazon.com/ja_jp/sagemaker/latest/dg/endpoint-auto-scaling-policy.html
私流Reactコンポーネントの作り方

はじめまして。
Advent Calenderのお祭り感に便乗して初めてQiitaに記事を投稿します。
普段は主にフロントエンドエンジニアとして働いています。

今日はReactでコンポーネントを作る際の手順や気を付けていることについて、思いつく限り書きます。


# 環境

- React
- TypeScript（稀にJavaScript）
- ESLint、Prettier
- フレームワーク
    - 今のプロジェクトではNext.js
- スタイリング方法
    - 今のプロジェクトではCSS Modules（Next.js にビルトインされている）
- コンポーネントライブラリ
    - 今のプロジェクトではAntDesign
- フォルダ構成
    - ベースはAtomic Design
    - 今のプロジェクトでは
        - PagesとTemplatesはNext.jsの機能によせている
        - MoleculesとOrganismsは区別が難しいのでまとめてPartsとしている



# 手順

1. 設計書やデザインカンプを眺める
共通化を意識して対象の画面以外もざっくり眺めます。

1. コンポーネントを切り分ける
デザインカンプの作成時点でデザイナーさんが切り分けてくれている場合もあります。

1. 並べ方を考える ←重要！
  レスポンシブを意識し、画面幅や文字数などの可変の要素に影響されないようなアルゴリズムを考えます。
  例
    - 特定の領域の上下左右の端や中心に配置する
      - 左右にそれぞれ配置したいときはspace-betweenを使いがち
      - 中心に配置したいときはflex:1を使いがち
    - marginやpadding以外には固定値をなるべく使わない
      - ちなみにmarginとpaddingの使い分けイメージ
        - marginはバラン：子要素同士が間隔をあけて並ぶ
        - paddingはお弁当箱：親要素が子要素の侵入を防ぐ

1. 置き場を用意する
プロジェクトのディレクトリ構成に準拠してファイルや空のコンポーネントを用意します。
ファイル名やコンポーネント名はPascalCaseにするのが一般的です。

1. JSXのタグまたはUIライブラリのコンポーネントを並べる
3で考えたとおりに並べます。

1. スタイルを整える ←難しい！
プロジェクトで決まっているスタイリング方法でスタイルを整えます。
importantやstyle属性などの優先度の強い手段はなるべく最後までとっておくとよいです。
また、コンポーネントライブラリが想定している範囲外のカスタマイズは難易度が高いです。ブラウザの開発者ツールを使用してデフォルトのスタイルを確認しながら地道に上書きしていくことになります。事前にデザイナーさんと使用するコンポーネントライブラリについて認識合わせができると理想的です。

1. ロジック、Stateを考える
ロジックについては今回は割愛します。
値は[Reactの公式ドキュメント](https://ja.react.dev/learn/thinking-in-react)に示されているプロセスに従って、なるべくStateで保持します。
状態管理ライブラリやContextは便利な反面、きちんと使い所を押さえて設計しないと収拾がつかなくなります。

1. Propsを考える
こちらもReactの公式ドキュメントに従っておけば間違いないです。
加えて、以下も意識しています。
    - 同じオブジェクトやAPIが出処の値は今のところ使っていなくても持ち続ける
    - 共通化できない部分はフラグで分岐せずに関数で受け取る
    - 内部で呼び出している子コンポーネントのPropsはまるまる受け取る

1. APIを呼び出す
プロジェクトの方針に従ってAPIを呼び出します。
今のプロジェクトでは[省力化コンポーネント](https://fintan.jp/page/14178/)を使用しています。
発信活動への想い（2024アドベントカレンダー無事完走できました)


 この記事は[ニッセイ情報テクノロジーPS事業推進室 アドベントカレンダー2024](https://qiita.com/advent-calendar/2024/nissay-it-xthinklab)の最終日の記事になります。

 https://qiita.com/advent-calendar/2024/nissay-it-xthinklab

　私たちの初めての組織アドベントカレンダーが、こうして無事に完走できたことを本当に嬉しく思います。参加された皆さん、自分以外の記事を読んで新たな発見があったり、他の組織のアドベントカレンダーに興味を持たれたりしたのではないでしょうか？
 
　運営サポートしてくれた方や記事をチェックをしてくれた方皆さま、本当にありがとうございました。

　最終日の本記事では、今回のアドベントカレンダーのまとめとして「仕事における発信の重要性」について掘り下げてみたいと思います。発信は、単なるアウトプットの一つに留まりません。それは、個人や組織の成長を促し、未来への扉を開く大きな力を持っています。

- - -
### １．発信で広がる知識の世界

　システムエンジニアにとって学習は日常の一部です。新しい技術を学ぶために本を読んだり、研修を受けたりすることは重要ですが、インプットに留まらない「アウトプット主体の学習」がより効果的であると言われています。

#### アウトプットから始める学習
　ただ情報を受け取るだけではなく、ブログを書く、勉強会で発表する、といったアウトプットをゴールに設定することで、学びが一層深まります。アウトプットを前提にインプットを行うと、自然と学ぶ内容が自分に関連する興味深いものになり、生きた知識として定着します。
 
　私自身も「発信する」という目標を設定することで、日々の生活や仕事の中で「この内容なら発信できそうだな」と思える瞬間が増えました。そうした発信のネタ探しは、単なる知識習得以上に、自分の探究を進めるきっかけとなります。

 
### ２．探究の根に目を向ける　

　発信を始める時に、多くの人が「周囲の評価」を気にしてしまいます。「誰も読んでくれないのでは」「もっと良いものを書かなければ」というプレッシャーは、筆を重くしがちです。
 
　自分でも、ちょっと自意識過剰では？と思うのですが、その気持ちはどうしようもありません。そんな時に思い出したいのが、「花よりも根に注目する」という視点です。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939762/16ec45df-db36-cadc-f1c8-39ba0a493f3b.png)

　これは、13歳のアート思考という本で紹介されているメタファーですが、花（評価）を気にするのではなく、根（探究のプロセス）を大切にすることが重要と書かれています。発信を通じて、自分の中にある「探究の根」をどれだけ伸ばせたか、という点に目を向け事が大事なのです。

　私自身は、現在は「組織学習」や「プロジェクトマネジメント」、「アジャイル開発」に強い興味を持っています。日々これらの事を発信する中で（大した内容ではないですが・・・）、興味がつながり、そのことでより深い学びを得られたと思っています。
 
　かつては異なるものと考えていた「ウォーターフォール型のプロジェクト管理」と「アジャイル型のプロダクト管理」も、結びつきを感じるようになり、より前向きにプロジェクトマネジメントについて考えられるようになりました。

### ３．発信でのつながり　

　今回、アドベントカレンダーに参加された方の中には、他の組織のアドベントカレンダーに目を向けた方もいるのではないでしょうか？発信は、それまで気にしていなかった周囲とのつながりを作る大きなきっかけになります。

#### 集団学習の可能性
『個人を超えて学習がつながっていく感覚』これを感じられることは大きな幸せです。
　学習と言えば孤独な作業というイメージがありましたが、これからの学習観は学習が仲間をつなぎ、新たな創発を産んでいく非常にクリエイティブな営みになると思っています。情報を占有していた時代は終わり、情報を共有し、共同で進化させていく時代が到来しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939762/ee1d53b0-0ede-4494-4ba1-7f29c370b689.png)
> [「学び続ける組織文化をつくるために、MIMIGURIで実践している5つのこと」](https://note.com/yuki_anzai/n/ncc420e09bd1c)より


　MIMIGURIさんが提唱している新しい学習観のように、学習はもはや個人で完結するものではありません。特にエンジニアの分野では、実践を通じた共同学習や新たな価値の創出が他の分野よりも速いスピードで進んでいます。これからもこうした発信活動を通じて、学習の枠組みを広げていくことが求められます。

#### まとめ．来年に向けて　

　とはいえ、発信には個人ごとの重さやハードルがあることも事実です。全員がブログを書いたり登壇したりする必要はありません。発信とは、大きな行動だけを指すものではなく、小さな行動から始めることができます。
 
　「誰かのチャットにいいねのスタンプを押すだけ」でも良いですし、「勉強会等に参加してみる」みたいな行動だけでも発信活動であり、非常に尊い活動だと思っています。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939762/ee3131dc-b1a9-f7eb-2a63-a9d8364c66b3.png)


　このような「発信していく事が大事で尊い」という文化を作れるように、色々と工夫をしてきました。

#### 工夫の例

+ 「発信大事！」と事あるごとに話す
+ チームでslack導入、チャットで分報を作り自由な記載を勧奨
+ 毎日勉強会を実施
+ 外部イベント/コミュニティーにメンバーと参加
+ ３カ月に１回リレーブログ企画を実施
+ 社内のコラムなど発信媒体で発信を繰り返す
+ 社内での発信イベントを企画。社外向けイベントを企画
+ 各種カンファレンス登壇を繰り返す

　まだ発信活動は小さな波ですが、これが連鎖していくことで、いつか大きな波となり、組織全体に広がることを信じています。このアドベントカレンダーもその一環であり、関わってくださった全ての方に心から感謝申し上げます。

　読んでくださった皆さん、書いてくださった皆さん、本当にありがとうございました！
JVM監視の新たな可能性を探る

### 🛠 **JVM監視の新たな可能性を探る**

JVM（Java Virtual Machine）の性能監視は、複雑な業務システムを安定的に運用するうえで欠かせません。みずほリサーチ＆テクノロジーズの**角兼行氏**がInstanaを活用したJVM監視について語ったセッションから、印象的だったポイントを共有します。

#### **JVM監視の重要性:**  
- **システムの安定性確保:** JVMのパフォーマンスが低下すると、業務への影響が大きくなるため、健全性を継続的に確認することが重要です。
- **迅速なトラブル対応:** 問題が発生しても、原因をすぐに特定できれば、業務への影響を最小限に抑えることができます。

#### **セッションで学んだInstanaの魅力:**
1. **幅広いJVM環境に対応:**  
   InstanaはさまざまなJVMタイプを一つのツールで監視でき、効率的な運用を実現します。
2. **視覚的なデータ分析:**  
   メモリリークやGC発生頻度を簡単に把握できるダッシュボードが用意されており、初心者でも扱いやすいと感じました。
3. **データ検索の容易さ:**  
   過去の履歴データも素早く確認できるため、業務への影響を防ぐための分析がスムーズに行えます。

#### **みずほ銀行の業務での活用例:**  
セッションを通じて、みずほ銀行の業務においてInstanaが複雑なシステムのパフォーマンス監視に役立てられていることを知りました。具体的な事例は詳しく語られていませんが、安定したシステム運用と業務効率向上に貢献しているとのことでした。

---

Instanaを使ったJVM監視の可能性について、ぜひこのセッションから新たな発見をしてみてください。

🌟 **動画はこちら:**

https://vimeo.com/1041327051

🌟 **資料はこちら:** 

https://speakerdeck.com/instanautsjp/jvm-javavm-noxing-neng-fen-xi-zhe-guan-dian-detan-ruinstananoke-neng-xing
ひとりアドカレを完走した感想

## よみとばしてください

どうも、限界派遣SESのnikawamikanです。
ひとりアドカレ最終日です。

## アドカレ25記事書くのどうだった？

アドベントカレンダー2024お疲れ様でした。

私はアドカレ25記事書くのは、正直しんどかったです。

毎日の記事をかくというか、ネタが見つからないというか。
ネタが見つかっても、正しくそれを記述するというのはリサーチが必要で時間もかかります。

記事を書くことが目的になってしまい、それのために調べ物をするという状態になっていたように思います。

### そもそも無理に記事書くべきじゃなくない？

確かにアウトプットすること自体は自分の考えを整理するためにはいいことだと思います。
しかし、それを公開する必要はあるのか？という疑問が残ります。

実際にQiitaのガイドラインには以下のように日記などは限定共有投稿をご活用くださいと書かれています。

> - テスト投稿、日記など（限定共有投稿をご活用ください）
> - 文章として成立していないメモや走り書き
> - 自己紹介記事（プロフィールをご活用ください）
> - AIが生成した内容で正しいかどうかを検証していないもの

最低限のマナーとして自分の記事が正しいかどうか？ということを考える必要があると思います。

私はアドカレを通して、記事を書くことの難しさを感じました。

### アウトプットすることの大切さ

かといって、アウトプットすることの大切さは変わりません。

私は個人開発の話を見るのは結構好きですし、実際に開発してみないと気づかないトラップのような仕様などもちょくちょく見かけます。
こういったことは広めていくことで、他の人が同じようなトラップにはまらないようにすることができると思います。

実体験から得た知識というのは単にドキュメントを読むよりも気をつけるべき点などが明確になっていることが多いと思います。

例えば、Windows環境でDevcontainerの`Node`系プロジェクトを動かす時はコンテナのLinuxとのファイルシステムの違いによって明らかにパフォーマンスが落ちることがあります。
こういったことは複合的な要因が絡んでいるため、ドキュメントからではわからないことかと思います。

### それはそれとして記事を書くことで得られるもの

最近個人開発などをしていなかったのですが、アドカレを通していろいろなフレームワーク等にふれることができました。

個人的にはもう少しRust関連で掘り進めたいと思っていたのですが、なかなか時間が取れずにいました。
そんな中、アドカレで25記事書くという目標を立てたことで、`Rust`関連の技術にふれることができました。

目標を立てて時間に追われることで、自分のやりたいことを後回しになっていた事に気づく機会と考えると個人としては良かったと思います。

## まとめ

アドベントカレンダー2024お疲れ様でした。
Qiitanのぬいぐるみが貰えたら泣いて喜びます。

今後はQiitanに惑わされずに有用そうな知見があったら記事を書いていく予定です。

おわり。
laravel 画面からのトリガーで自作のcommandをキューを使って非同期実行してみる

## 概要

laravelにて画面上からのボタンクリックトリガーで自作のcommandを実行する方法をまとめる。

## 前提

下記の内容が完了していること。

https://qiita.com/miriwo/items/e75958578b146834079b

DBにjobsテーブルがあること

## 方法

1. .envのQUEUE_CONNECTIONをdatabaseに設定（configのキャッシュクリア`$ php artisan config:clear`を実行した方が良い）
1. 下記コマンドを実行してジョブを作成

    ```terminal
    php artisan make:job EchoHelloWorldCommandJob
    ```

1. 作成されたジョブ`app/Jobs/EchoHelloWorldCommandJob.php`を開き下記のように記載

    ```app/Jobs/EchoHelloWorldCommandJob.php
    <?php
    
    namespace App\Jobs;
    
    use Illuminate\Contracts\Queue\ShouldQueue;
    use Illuminate\Foundation\Queue\Queueable;
    use Illuminate\Support\Facades\Artisan;
    
    class EchoHelloWorldCommandJob implements ShouldQueue
    {
        use Queueable;
    
        /**
         * 実行するコマンド名
         *
         * @var string
         */
        protected $command;
    
        /**
         * Create a new job instance.
         */
        public function __construct()
        {
            $this->command = 'app:echo-hello-world-command';
        }
    
        /**
         * Execute the job.
         */
        public function handle(): void
        {
            Artisan::call($this->command);
        }
    }

    ```

1. ワーカーの起動

    ```terminal
    php artisan queue:work
    ```

1. トリガーとなる処理の後に下記の1行を追加

    ```php
    use App\Jobs\EchoHelloWorldCommandJob;

    EchoHelloWorldCommandJob::dispatch();
    ```

1. 後は処理を実行するだけ
バグに遭遇したのでSPINを使って考えてみた

先日、あるバグに遭遇しました。バグに遭遇することなど、プログラマをやっていれば日常茶飯事のことで、特筆するべきことでもないのですが、アドベントカレンダーの季節なので、せっかくなのでネタにしよう、と筆を取った次第です。

そのシステムはRailsで作られたアプリケーションで、ユーザからリクエストを受け、呼び出されたControllerがSidekiqにジョブを流し、バックグラウンドでタスクを複数実行していました。

- タスクA
- タスクB

タスクA内ではタスクBをさらにSidekiqへジョブを投入している(このタスクをタスクβと呼称します)、という作りになっていました。なお、この文章では、この作りが妥当なものなのか、という点については話題に上げません。ここで扱う内容は、こう作られていたらバグっていた、という事実のみです。

タスクBはシステム内の複数のリソースを集計し、集計結果を特定の場所に格納する、という処理を実行します。タスクAはタスクBの集計対象となるリソースを更新した後、タスクBを実行する、という流れです。

バグは、タスクAでリソースXが更新される状況が発生しているにも関わらず、リソースXが更新されないことがある、というものでした。

当初、Sidekiqが一つのコントローラ内から複数起動していたり、ローカル環境では再現しなかったりしたので、何か特別なことをしているのではないかと身構えながらコードを読んでいったのですが、バグの原因はタスクBが実行しているストアドファンクションと、タスクAとタスクBとが順々にに実行されると思った大昔の実装者の勘違いでした。

ストアドファンクションは次のような処理を実行していました。

1. 起動時刻を変数に保存する
2. リソースXを算出するために集計を行う
3. 1で保存した変数が、リソースXの更新日時より古いか等しい場合、リソースXを2で算出した値を用いて更新し、新しかったならば、更新をしない。また、リソースXを更新する際に記録する更新日時は1の値とする

既に察しがついている方も多いでしょうが、ストアドファンクションの処理1、2、3、及びSidekiqから起動されるジョブ全般にわたって、処理がアトミックになることを保証している部分はありませんでした。よって、タスクAが起動し、その後タスクBが起動して、それが終了する前にタスクβが起動し、その状態でタスクBが終了すると、タスクAで行なったリソースXへの更新処理が、実行されないことがある、という状態が発生しえます。

```
タスクA起動 --> タスクB起動 --> タスクβ起動 --> タスクB終了 --> タスクβでリソースXが更新されずに終了
```

今回はせっかくなのでSPINを持ち出して簡単なモデル検証をし、このバグについて考えてみました。SPINやモデル検証については今回は記述しません。詳しいことはWikipediaの「SPINモデルチェッカ」の項に書いてありますし。

まずこの問題の本質的なことを抽出します。

SidekiqでタスクB、タスクAが起動云々、と書きましたが、モデス化する際には、平行にたくさん起動される、としてしまいました。Sidekiqへ放りこまれたジョブの実行順序など考えていられません。ようはたくさん一緒に起動したと考えればよいのです(暴論)。

次にストアドファンクションの部分です。1に起動時刻云々とありましたが、起動のタイミングで値をインクリメントする変数で代替しました。PROCNUMを2以上にした場合、複数のプロセスが同一の値を持つ状態になるケースは発生しますが、これは同一時刻に起動された、と考えればよいでしょう。その場合、双方で更新処理が実行されます。

2の集計処理ですが、これは別にどんな処理であろうと、リソースXが更新されるかどうかについては関係ないので無視します(あくまでも今回の問題では、です。タスクAとタスクBの実行開始時間が十分離れるような場合だと色々と影響が出てくると思います)。

最後のリソースXの更新については、これはインクリメントする変数を、別途用意した変数に代入するという行為で代替しました。

これらの事情を考慮し、Promelaで記述してみました。

```
#define PROCNUM 1

int count = 0
int current_count = 0

active [PROCNUM] proctype Updater()
{
  do
    :: count = count + 1 ->
      if
         :: (current_count < count) -> current_count = count; printf("%d\n", count);
         :: else -> assert(false); printf("error \n");
      fi
  od
}
```

まずPROCNUMは、同時に実行されているタスクBの数です。1の値を与えた場合、冒頭で開発環境では発生しない、と書きましたが、タスクが順序よく、終了を待って実行された状態を表現できると考えました。これをSPINで実行すると、ひたすらインクリメントされる数字が表示されます。よって、errorの方には流れていません。

PROCNUMの値を2以上にした場合、先程暴論と称した「たくさん」起動した状態(2であれば2で、たくさんという文字通りの状態を作りたいのであればこの数を増やせばよい)がつくれます。その結果は、elseへ処理が流れ、動作が停止します。`spin -u100 "ファイル名.p"`としたとしても、100まで実行する以前で処理が終了します。その際、終了のタイミングはランダムです。

これらによって、開発環境では発生しない(sidekiqのconcurrencyの設定値を低くしているので、結果的に順々に処理が実行されていると推測している)、本番環境では発生したり発生しなかったりする、という状況を再現することができました。ただ、かっこ書きをした推測もあるので、間違っている可能性もありますが、大きく外してはいないでしょう(多分)。



さて、このバグの修正方法を検討し、モデル化し、SPINを利用して検証するところまで行なってはじめて、このツールの使い方を記述した価値ある記事になりえるはずですが、そろそろ夜も遅くなってきたので、それはまたの機会にしたいと思います。

ではよいお年を。
アプリケーションとして正しいものと製品としてあるべきもの

今回は、エッセイになります。私がQA初心者だったころから思っていたことを主観で書きます。

## 何のためにリリースするんだろう
今日、ソフトウェアは「無形固定資産」として計上されるぐらい、会計上でも認められたものになっていますが、何のために製品を作っているのか、と問おうとすると、「売り上げのため」「誰かの価値のため」という内容も、少なからず含まれてくるでしょう。

## こんな画面があったとします
例えば、こんなふるまいが自社製品にあったとします。

ECサイトにて、[ Home ] というボタンを押したとして、リンク先がじつは全然関係ない、マイページ画面だったとします。理由は、そのアカウントの権限では、Homeは見せられないから、という仕様だったとします。ですが、[ Home ] ボタンを押したユーザーの期待値は、当然ホーム画面に行くことであり、マイページが表示されるのは、期待値とは言えないでしょう。Homeを、適切な権限のないアカウントに見せない、という目的は達成できますが、ユーザーの体験としては、どう思われるでしょう。ちょっと雑に見えませんか？

これを、「仕様です（by design)」で、手間をかけずに終わらせますか？
それとも、周りを調整して直しますか？
チームメンバーは、リリースに追われてとても忙しそうです。
また、直したからと言って給料が上がる保証はありません。
リソースは常に足りません。

私が自社製品のQAにこだわる理由が、ここにあります。
自社製品のQAは、利害関係が自分にもあるので、例えば、具体的に手間をかけずに顧客体験を上げていく提案ができます。メッセージをちょっと変えるだけでも全然印象が変わることも多いです。そういった、手間をかけずに良くしていく方法を日々考えて実現しやすいのです。


## お客様の「不」に、目をつぶらない
"提案までやってほしい"、という、依頼側の希望を聞くこともそれなりにありますが、契約した内容を終わらせれば問題ない、というシチュエーションになりがちなことも多いです（もちろん、すべてがそうというわけではありませんが）。また、意欲的に不備を洗い出しても、忙しさに追われて手付かずのままリリースされてしまい、モチベーションを落としていく例もあります。

第三者検証の立場では、こういったシーンに遭うことは珍しくないと、経験上感じていました。また、効率重視の観点から、アプリケーションが最初の意図通りに動けば正しい、とする経験豊富なテストマネージャーもいらっしゃいました。利益を考える場合、これも一つの正解です。一方で、少数ですが、コミュニケーションスキルが高く、こういう場合でもお客様に上手に働きかけて修正を促す、意欲的な第三者検証のエンジニアもいます。これは、本人の資質のみならず、所属元の会社のスタンスも大きいように感じます。


## ソフトウェアの「テスト」と、品質保証の「評価」
QAエンジニアは、日々品質と向き合っているわけですが、仕様通りに動けばよい、というスタンスでいると、上記のように、確実に顧客満足から離れるであろう内容であっても、「仕様だから」と、それ以上考えるのをやめてしまいがちです。早くデリバリーすることで、早く失敗し、リカバリーし、最終的な顧客満足に近づく、というのも、今となっては王道の一つです。

ただ、「仕様通りに動いているから」というだけで、テストは終了、とするのは、ものづくりを考えた場合、もったいないなと思います。こういった、お客様の「不」を見つけるためのテスト技法も存在します。そうした「不」に、ストレートにフィードバックを出せるのも、QAチームの価値だと考えます。

顧客価値を生み出すためには、仕事を依頼する側、請け負って品質保証をする側、双方の働きが必要になるでしょう。そしてこういったクライテリアは、少なからず経営方針に影響を受けます。QAが経営の思う以上の活動が出いないといわれるのは、こういった事情からと考えます。新しくQAチームを発足する場合、品質をどう変えたいのか、どういう動きで対応できそうなのかは、周りの協力なくして推進するのは難しいです。チームを作る前に、社内の文化が変化に対応して進めていけるのかは考えたいポイントです。

「アプリケーションとして正しい物」と、「製品としてあるべきもの」を、考えてポリシーを作っていく。ここが、その製品の品質（印象）を決めるうえで、要になるのではないでしょうか。
生成AIにケーキを三等分させたい

半分の半分の半分の・・で切れない人数でケーキを切るのって難しいですね。

そして今日はクリスマスイブ。
私はケーキとは無縁の焼き鳥と唐揚げをカシスウーロンで流し込んでいたわけですが、
気分だけでもクリスマスを味わうために、生成AIとケーキを分け合ってパーティー気分を味わおうと思います。

使用したモデルはGeminiです。

# まずは二等分

二人で分け合いましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/4f1faee3-7ae6-476b-3a14-69885543e935.png)

今表示されている分が、どっちの取り分なのかが肝ですね。

伝え方を変えてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/61ab9e77-14d1-ad92-ac10-dd2f5116c9ec.png)

ちょっと盗み食いしてるなぁ。

## 段階を踏む

まずは切る前の状態を見てみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/7361ce25-c62d-b240-211b-630d06106c10.png)

チョコケーキですね。美味しそう。
では切ってもらいましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/c50b051a-d2e4-12b3-b205-18182ca8f80f.png)

二等分じゃないなぁ。
ちょっと角度変えてるけど、また盗み食いしてるな。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/bfd986e5-b86e-29f4-1386-afed9fd39e23.png)

ちなみにどっちをくれるのか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/37f7bb35-13cc-86e6-3525-ed0c9d916b12.png)

小さいほうが私の分でした。大変遺憾です。

## 二等分をいう言葉を使わない

試しに「半分」という言い方に変えてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/8214d4c8-7166-5e9f-e93e-32560bddba8c.png)

主のあまりの言語能力の低さに、AI側がプロンプトを提案してくる事態です。
ご提案頂いたプロンプトで実行しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/54593931-a9b9-3ea4-0f78-59fd23597384.png)

いやできないのかい！

## 計算問題にしてみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/6de138fe-65ae-2041-e06d-a0c9b268a007.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/a15eec34-b13e-0455-09aa-b6f4f8978cc5.png)

まずここで切ったのかな？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/cda556fa-474a-3f27-1431-ad0edb9faf94.png)

次にここで切ってさらに半分

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/07f184fb-585f-3783-94af-c6e1996578cc.png)

で取り分が青枠だとして

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/a325c8a7-a65b-2e76-412b-64fa0e725418.png)

(180 / 2) + (90 / 2) = 135
ってこと？近いでしょ？ってこと？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/cc65200b-756e-e2b7-ae5b-fc1012e3c7c9.png)

何でここ切ったの？むずいでしょ。
線対称で同じっぽいでしょ？ってこと？

## AIが提案してきたプロンプトを採用

四苦八苦している途中に以下の提案があったので、やってみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/3c956930-b0ee-16fb-04e6-8f5db90c040c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/b62f3b1a-8fc1-a484-4030-25fc6e4394a7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/61a5b831-cec4-935e-124b-e0c20a28d799.png)

# まとめ

生成AIは三等分したケーキや円の画像を生成できない（異論は認める）
laravel artisanコマンドを処理の中で実行する

## 概要

laravelにてartisanコマンドをコントローラーなどの処理の中で実行する方法を簡単にまとめる。

## 内容

下記の記載をコントローラーのアクションの内部に記載するだけ。

```php
Artisan::call(コマンド名)
```

ちなみにartisan コマンドは`$ php artisan list`で実行可能なコマンド一覧を確認する事ができる。
マクシミン、マクシマックス、ミニマックス原理の基本

# １．マクシミン原理（Maximin Principle）
最悪の事態を考慮して意思決定を行う方法。
各選択肢における最悪の結果を見積もり、その中で最も良い（最大の）ものを選ぶ。
リスクを最小限に抑えたい場合に有効。

例
それぞれの選択肢における最悪のシナリオを考え、その中で最も損失が少ない選択肢を選ぶ。

選択肢A: 最悪のシナリオで -10万円
選択肢B: 最悪のシナリオで -5万円
選択肢C: 最悪のシナリオで -8万円
この場合、マクシミン原理に従うと、選択肢B（最悪のシナリオで -5万円）を選ぶ。

# ２．マクシマックス原理（Maximax Principle）
最良の結果を追求する方法。ハイリスクハイリターン。
各選択肢における最良の結果を見積もり、その中で最も良い（最大の）ものを選ぶ。
リスクを取ってでも最大の利益を追求したい場合に有効。

例
それぞれの選択肢における最良のシナリオを考え、その中で最も利益が大きい選択肢を選ぶ。

選択肢A: 最良のシナリオで +20万円
選択肢B: 最良のシナリオで +15万円
選択肢C: 最良のシナリオで +25万円
この場合、マクシマックス原理に従うと、選択肢C（最良のシナリオで +25万円）を選ぶ。

# ３．ミニマックス原理（Minimax Principle）
相手の最善の戦略に対して自分の損失を最小限に抑える方法。
相手が最も不利な状況を作り出すと仮定し、その中で自分の損失を最小限にする戦略を選ぶ。

例
例えば、2人のプレイヤーがいるゲームで、各プレイヤーが取ることができる戦略が複数あるとする。
**プレイヤーAは、プレイヤーBが最も不利な戦略を取ると仮定し**、その中で**自分の損失を最小限にする**戦略を選ぶ。

プレイヤーAの戦略1: プレイヤーBが最善の戦略を取ると損失が -10
プレイヤーAの戦略2: プレイヤーBが最善の戦略を取ると損失が -5
プレイヤーAの戦略3: プレイヤーBが最善の戦略を取ると損失が -8
この場合、ミニマックス原理に従うと、プレイヤーAは戦略2（損失が -5）を選ぶ。
Rust で Tab stop を実装（タブをスペースに変換）


# はじめに

Markdown などのテキスト処理を行う際に**タブをスペースに変換**する必要があることがあります。

この変換を実装する上で、**タブストップ**（Tab stop）の概念が重要になります。

本記事では、タブをスペースに変換する機能を Rust で実装する方法を紹介します。

::: note
**タブ** は、テキスト内に挿入される**特殊な空白文字**で、通常はタブキーを押すことで生成されます。具体的には、Unicode 文字 `U+0009` に対応し、エスケープシーケンスでは `\t` と表現されます。

**タブストップ** は、テキスト内でタブ文字が**次に移動する位置**を示します。例えば、タブストップが 4 文字ごとに設定されている場合、行の先頭から 4 文字ごとに**仮想的な基準線**が設定されます。

```
    | ◯ ◯ ◯ ◯ | ◯ ◯ ◯ ◯ | ◯ ◯ ◯ ◯ | ◯ ◯ ◯ ◯ | ◯ ◯ ◯ ◯ |
```

[Tab と Tab stop の違い -Qiita](https://qiita.com/shikuno_dev/items/cb376f2418b653970a72)
:::

# 実装

テキスト内のタブを指定されたタブサイズに基づいてスペースに変換する関数を実装します。

文字列を前から処理していき、タブに遭遇すると次のタブステップまでをタブサイズに基づいてスペースで埋めます。

以下のように挙動（`\thello\t!` -> <code>&nbsp;&nbsp;&nbsp;&nbsp;hello&nbsp;&nbsp;&nbsp;!</code>）することを想定しています。

```:tab_size = 4 の場合
  \t  h  e  l   l  o \t  !                              <- 入力値
 | ◯  ◯  ◯  ◯ | ◯  ◯  ◯  ◯ | ◯  ◯  ◯  ◯ | ◯  ◯  ◯  ◯ |
   ␣  ␣  ␣  ␣   h  e  l  l  \t  !                       <- 1 つ目の Tab を変換
   ␣  ␣  ␣  ␣   h  e  l  l   o  ␣  ␣  ␣   !             <- 出力値（2 つ目の Tab を変換）
```

`\t` はタブ、`␣` はスペースを表しています。

## タブストップの位置までの文字数を計算する関数

まず、次のタブストップの位置までの文字数を計算する関数を実装します。

```rust
fn next_tab_stop(position: usize, tab_size: usize) -> usize {
    tab_size - (position % tab_size)
}
```

この関数は、現在の文字位置（`position`）とタブサイズ（`tab_size`）を入力として受け取り、次のタブストップの位置までの文字数を計算します。

## タブをスペースに変換する関数

次に、文字列内のタブをスペースに変換する関数を実装します。この関数は、タブに遭遇すると次のタブストップまでのスペースを挿入します。

```rust
fn replace_tabs_with_spaces(input: &str, tab_size: usize) -> String {
    let mut result = String::new();
    let mut position = 0;

    for c in input.chars() {
        if c == '\t' {
            let next_stop = next_tab_stop(position, tab_size);
            result.push_str(&" ".repeat(next_stop));
            position += next_stop;
        } else {
            if c == '\n' {
                position = 0;
            } else {
                position += 1;
            }
            result.push(c);
        }
    }

    result
}
```

<details><summary><strong>※ 改行コードは <code>\n</code> のみを前提としています。<strong></summary>

`\r` や `\r\n` も対象とする場合は、改行コードを統一してから `replace_tabs_with_spaces` 関数を使用するか、`replace_tabs_with_spaces` 関数内で改行コードを統一する必要があります。

```diff_rust
fn normalize_newlines(text: &str) -> String {
    text.replace("\r\n", "\n").replace('\r', "\n")
}

fn replace_tabs_with_spaces(input: &str, tab_size: usize) -> String {
    // ...

-    for c in input.chars() {
+    for c in normalize_newlines(input).chars() {

    // ...
}
```

</details>

## main 関数での実行

最後に、main 関数でこれらの関数を使ってタブをスペースに変換します。

```rust
fn main() {
    let tab_size = 4;
    let input = "Hello\tWorld!\nThis\tis\ta\ttest.";

    let output = replace_tabs_with_spaces(input, tab_size);
    println!("Original:\n{}", input);
    println!("Modified:\n{}", output);
}
```

```bash:実行結果
Original:
Hello	World!
This	is	a	test.
Modified:
Hello   World!
This    is  a   test.
```

# まとめ

本記事では、タブ文字をスペースに変換する Rust 関数の実装方法を紹介しました。

具体的には、タブストップの位置までの文字数を計算する関数と、それを利用して文字列内のタブをスペースに変換する関数を作成しました。

このような機能は Markdown や他のテキスト処理において重要になります。
MySQLを基礎から学ぶその2  データをいじる

この記事は[JavaとPythonを基礎から学びたい私のための Advent Calendar 2024](https://qiita.com/advent-calendar/2024/aruhitonocalendar)の24日目の記事です。続きです。
Testdbに新しく「Season」という名前でテーブルを作りました。
・データを変更する・削除する・追加するのを中心に見ていきます。
# テーブルのデータをいじる
### テーブルを作る
そもそもテーブルがないと始まりません。上に書いた通り、今回は「Season」という名前のテーブルを作成していきます。今回は季節を番号（春→夏→秋→冬）で表し、また季節の名前も入れていきます。
```
create table Testdb.Season(id int,name Varchar(10));
```
Testdb.Seasonは、TestdbのデータベースにSeasonのテーブルを作るという意味です。（）内には、何のデータを入れるかを書くようです。ここでha
idとnameを入れています。show tablesで確認すると
```
+------------------+
| Tables_in_testdb |
+------------------+
| season           |
+------------------+
1 row in set (0.0017 sec)
```
ちゃんとseasonのデータが作られていることがわかります。
### データを追加する
```
 insert into Season values(1,'Spring');
```
insertでデータを追加することができます。()内には、テーブルを作成するときに指定したもの(今回はidとname)を入れます。

:::note info
カラムを指定する場合について
カラムとは、今回でいうidとnameのことです。カラムを指定してデータを追加することができます。指定する場合はテーブル名とvalueの間に()を入れて、その中に追加するデータの要素に対応するカラム名を書き込みます。
例)nameだけ追加してidを追加しない場合
```
insert into Season (name) values('Summer');
```
こんな感じになります。入れなかった部分はnullとして表示されるようです。必要なときに応じて使い分けた方がいいです。
:::

データがちゃんと追加されているか確認します。select* from Season;でSeasonのテーブルの中をすべて取得します。
```
+------+--------+
| id   | name   |
+------+--------+
|    1 | Spring |
| NULL | Summer |
+------+--------+
```
こうなりました。ちゃんと追加されていることがわかります。
せっかくなのでautumnとwinterもつけておきます。

### データの変更
データを間違えて追加してしまった場合や中身を変更したい場合でも、消して入れなおすといった面倒なことをせずに変更をすることができるようです。
変更をするためには「update」を使います。
今回はidの入っていないsummerにidを追加します。
```
 update Season set id=2 where name='Summer';
```
update テーブル名 set 変えたいもののカラム名=変更後の値 where name=変えるデータ;
となります。今回はnameがSummerのものを見つけて、そのデータのidをnull～2に変更しています。
```
+----+--------+
| id | name   |
+----+--------+
|  1 | Spring |
|  2 | Summer |
|  3 | Autumn |
|  4 | Winter |
+----+--------+
```
summerのidがnullから2に変更されていることがわかります。
### データの削除
データを削除する場合、Deleteを使います。
とりあえずSeasonに関係のないデータを5番目に追加したので、これを消してみます。(5,'Christmas');
```
delete from Season where id=5;
```
idが５のデータを削除するようにしています。where以降については、消したいデータだとわかるものならいけます。今回の場合だとidとnmaeが登録されているので、name='christmas'とか書いてもちゃんと消すことがで着るみたいです。
+----+--------+
| id | name   |
+----+--------+
|  1 | Spring |
|  2 | Summer |
|  3 | Autumn |
|  4 | Winter |
+----+--------+
ちゃんと消せ照ることが確認できます。
# まとめ
この基本の3つを覚えておけばとりあえずテーブルを作ることができるはずです。
insertで挿入、updateで更新、deleteで削除ができます。
# 参考文献

https://www.javadrive.jp/mysql/table/index1.html

https://www.sejuku.net/blog/82957

https://envader.plus/course/2/scenario/1050
litestarを用いたbackground_taskによるカウンターの実装

## はじめに
開発のために、TCP通信をするセンサーのモックを作ることになりました。
条件として、
- tcp通信により任意のデータを任意のタイミングで送れること
- UIを用意し、接続して送信しているデータを操作できること

とした。

この条件をもとに、最近ハマっている`litestar`を用いて、WEBサーバーとして作ってみることにした。

### TL;DR
- githubに公開しています
    - https://github.com/sion908/litestar_background_counter
    - cloneしてdockerを立ち上げれば起動できます
- tcpの接続を維持するために接続からはバックグラウンドタスクに移行
- 以降はインメモリである、redisに通信するデータの情報をおくことで、接続を解除することなく、データの送受信および制御が行えるようになる


### 動作環境・使用するツールや言語
dockerで動くようにしています
- OS バージョン
    - Mac book pro 13
- ツール
    - docker 
- 言語
    - Python 3.11
- フレームワーク
    - litestar 2.13.0
    - redis 5.2.1

## 実装内容

作成したアプリの流れ
```mermaid
sequenceDiagram
    actor Client
    participant API
    participant Redis
    participant BackgroundTask
    
    %% Start Counter
    Client->>API: GET /counter/start
    API->>Redis: save(id, counter=0)
    API->>BackgroundTask: start system_upkeep
    API->>Client: return {id}
    
    loop Every 2 seconds
        BackgroundTask->>Redis: load(id)
        Redis->>BackgroundTask: counter data
        BackgroundTask->>Redis: save(id, counter+1)
    end
    
    %% Get Counter
    Client->>API: GET /counter/{id}
    API->>Redis: load(id)
    Redis->>API: counter data
    API->>Client: return {counter}
    
    %% Set Counter
    Client->>API: GET /counter/{id}/v/{value}
    API->>Redis: save(id, counter=value)
    API->>Client: return {counter}
    
    %% End Counter
    Client->>API: GET /counter/{id}/end
    API->>Redis: save(id, counter=-1)
    API->>Client: return {message}
    
    Note over BackgroundTask: Counter < 0
    BackgroundTask->>Redis: delete(id)
```


## 参考資料

- [バックグラウンドタスク(litestar)](https://docs.litestar.dev/latest/usage/responses.html#background-tasks)
- [redisのgithub](https://github.com/redis/redis-py)



## おわりに・まとめ

litestar楽しいです
またいろいろやっていきたいですね
そして記事書くのきつい...
ゼロランタイムってなんだっけ？

## これは何

昨今、[Kuma UI](https://www.kuma-ui.com/)や[Pigment CSS](https://github.com/mui/pigment-css)などのCSS-in-JSライブラリがどんどん出てきて、そこによくZero-runtimeという文言を見かけます。
そこでよく見かけるけど「ゼロランタイム」とはなんだろう？ということろから始まり、「これをもし新卒に聞かれたら全く説明できないな」と思ったので記事にしてまとめてみました。

## まずランタイムとは

> ランタイム（runtime）とは、開発したコンピュータプログラムを実行する時のこと。「実行時」と訳語を用いることも多い。対義語は「開発時」あるいは「コンパイル時」(compile-time/コンパイルが必要なプログラミング言語の場合)。

https://e-words.jp/w/%E3%83%A9%E3%83%B3%E3%82%BF%E3%82%A4%E3%83%A0.html

ランタイムがプログラムを実行する時という意味なら、ゼロランタイムってなんだ…？
ちょっと分からなくなってきました。


## ゼロランタイムとは

> ゼロランタイム（Zero-runtime）とは、特定のライブラリがプログラムの実行時に追加のオーバーヘッドを引き起こさないことを指します。これは、そのライブラリがプログラムのコンパイル時（またはビルド時）にすべての作業を完了し、実行時には追加の処理を必要としないことを意味します。
例えば、スタイルシートを扱うCSS in JSのライブラリの中には、ゼロランタイムとして設計されたものがあります。これらのライブラリは、ビルド時にJavaScriptから静的なCSSファイルを生成し、実行時にJavaScriptによるスタイルの操作を行わないため、パフォーマンスを向上させることができます。

https://chot-inc.com/service/jamstack/zero-runtime

何となくわかった…？:thinking:
いや、「追加のオーバーヘッド」ってなんだ…？


## オーバーヘッドとは

> 「オーバーヘッド」（overhead）とは、コンピューターで何らかの処理を行う際に、その処理を行うために必要となる余分な処理や手続き、システムの負荷、処理時間などを指す用語です。
本来必要のない処理や時間がかかってしまうことを指し、アプリケーションやシステムのパフォーマンス低下やエラーの原因になります。
オーバーヘッドを減らすためには、効率的なアルゴリズムの使用や、メモリやリソースの最適化、不要な処理の削除などが必要です。
ただし、完全にオーバーヘッドをなくすことはできないため、最小限に抑えることが大切です。

https://crocro.com/write/it-words/?p=word-%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%98%E3%83%83%E3%83%89


## 完全に理解した（ダニング・クルーガー効果）

つまりゼロランタイムとは、プログラムが実行された時におこるシステムの負荷を減らしページの読み込み時間の軽減など、エンドユーザーにとってもメリットがありそうだという事が分かりました。

パフォーマンスの事を詳しく知るために、Chrome for Developersの以下のページとかを読んでおく必要があるみたいですね。

https://developer.chrome.com/docs/devtools/performance?hl=ja

## 参考

https://zenn.dev/utah/articles/16df25f62536b0

https://zenn.dev/kmdmnak/articles/4ceb4e655c451a

https://speakerdeck.com/poteboy/kuma-uinoshe-ji-si-xiang-to-wan-zhang-ranaizerorantaimucss-in-js
ジェネリクスの大枠を捉える【TypeScript】

## はじめに
TypeScriptを学習中の大学生です。ジェネリクスについて、「なにそれ美味しいの？」状態だったため、勉強しました。備忘録としてこの記事に残します。
タイトルの通り、**大枠を捉える**ことを目標にしています。私の同じTypeScript初心者の方はぜひ読んでみてください！

## まとめ
ジェネリクスとは、**特定の型に依存せず、型を引数として受け取る仕組み**で、**型を変数のように扱う**。ジェネリクスを用いることで、**型の安全性とコードの共通化を両立する**ことができる。
```typescript
function swap<T>(a: T, b: T): [T, T] {
  return [b, a];
}
```

## 詳しく解説
以下では、受け取った2つの値を入れ替える`swap関数`をTypeScriptで実装する場合を考える。受け取る値の型は数値や文字列など、さまざまな可能性がある。

### ジェネリクスを用いない場合
#### パターン1：型ごとに関数を作成
```typescript
function swap(a: number, b: number): [number, number] {
  return [b, a];
}
function swap(a: string, b: string): [string, string] {
  return [b, a];
}
```
ロジックは同じだが、型のみが異なる関数が2つ作成している。この実装では、**型の安全性は担保されるが、コードの共通化は達成できていない**。

#### パターン2：anyを使用
```typescript
function swap(a: any, b: any): [any, any] {
  return [b, a];
}

swap(1, "first"); // [ "first", 1 ] （エラーにならない）
```
anyを使用すると、どんな型でも受け付けることができる(TypeScriptを使用している意味がなくなる)。この実装では、**コードの共通化は達成されるが、型の安全性は担保されない**。

<font color="red">**コードの共通化と型の安全性の両方を達成するために生まれたのがジェネリクスである！**<font>

### ジェネリクスを用いる場合
```typescript
function swap<T>(a: T, b: T): [T, T] {
  return [b, a];
}

swap<number>(1, 2); // [2, 1]
swap<string>("hello", "world"); // ["world", "hello"]
swap<boolean>(true, false); // [false, true]
```
ジェネリクスは、**型も変数のように扱えるようにする**。関数名の後に<T>と記述することで、Tを型パラメータとして宣言する。Tは任意の名前だが、慣例的にTやUを使われる。

<br>

また、引数の型から型推論を行ってくれるため、以下のように型を明示しなくても動作する。
```typescript
swap(1, 2)); // [2, 1]
swap("hello", "world"); // ["world", "hello"]
swap(true, false); // [false, true]
```

ジェネリクスを理解し活用することで、TypeScriptを使った開発の効率と安全性を大幅に向上させることができる。

## 参考
https://typescriptbook.jp/reference/generics

https://qiita.com/k-penguin-sato/items/9baa959e8919157afcd4
LangChainのチュートリアルを一通りやってみた


生成AIにそこまで興味はなかったものの、なんとなく触っておかねばならないのではないかということで、LangChainのチュートリアルを一通り流してみました。


https://python.langchain.com/docs/tutorials/


<font color="orange">※ 久しぶりにチュートリアルを見たら自分がやったときとだいぶ章立てが変わってしまっていますが、見なかったことにします。</font>

巷には様々なブログや書籍、動画コンテンツが溢れていますが、どれも情報が古かったり、内容が薄かったりと満足行くものがない状況でしたが、このチュートリアルはチャットボット、RAG、Agent、分類、SQL実行といった知りたいことがユースケースごとに簡潔に説明されており非常にわかりやすかったです。


ソースコードはこちら

https://github.com/ng3rdstmadgke/llm-work/tree/main


# ■ Basics

## 1. [シンプルなLLMアプリケーションを作成する](https://python.langchain.com/docs/tutorials/llm_chain/)

https://github.com/ng3rdstmadgke/llm-work/blob/main/notebook/langchain-tutorial/01_basics/01_simple_llm_appplication_with_lcel.ipynb

## 2. [チャットボットを作成する (会話履歴の保持)](https://python.langchain.com/docs/tutorials/chatbot/)

https://github.com/ng3rdstmadgke/llm-work/blob/main/notebook/langchain-tutorial/01_basics/02_chatbot.ipynb

## 3. [ベクトルストアとリトリーバの構築](https://python.langchain.com/docs/tutorials/retrievers/)

https://github.com/ng3rdstmadgke/llm-work/blob/main/notebook/langchain-tutorial/01_basics/03_vector_store_and_retrievers.ipynb


## 4. [エージェントの構築](https://python.langchain.com/docs/tutorials/agents/)

https://github.com/ng3rdstmadgke/llm-work/blob/main/notebook/langchain-tutorial/01_basics/04_agent.ipynb


# ■ Working with external knowledge

## 1. [RAG (web上の記事)](https://python.langchain.com/docs/tutorials/rag/)
https://github.com/ng3rdstmadgke/llm-work/blob/main/notebook/langchain-tutorial/02_working_with_external_knowledge/01_rag_app.ipynb


## 2. [会話型RAG](https://python.langchain.com/docs/tutorials/qa_chat_history/)

会話履歴の保持機能を備えたRAG

https://github.com/ng3rdstmadgke/llm-work/blob/main/notebook/langchain-tutorial/02_working_with_external_knowledge/02_conversational_rag_app.ipynb


## 3. [SQLを使ったQ&Aシステム](https://python.langchain.com/docs/tutorials/sql_qa/)

DBのデータに対してLLMがSQLを実行し、その結果をもとに質問に答える

https://github.com/ng3rdstmadgke/llm-work/blob/main/notebook/langchain-tutorial/02_working_with_external_knowledge/03_qa_with_sql.ipynb


## 4. RAG (PDF) ※ リンク切れ

https://github.com/ng3rdstmadgke/llm-work/blob/main/notebook/langchain-tutorial/02_working_with_external_knowledge/07_qa_with_pdf.ipynb


# ■ Specialized Tasks

## 1. [ネガポジ分析](https://python.langchain.com/docs/tutorials/classification/)

https://github.com/ng3rdstmadgke/llm-work/blob/main/notebook/langchain-tutorial/03_specialized_tasks/03_classification.ipynb
1年半インフラエンジニアの頭の中【キッティング編】

#### 本記事の読者ターゲット層
・未経験者
・駆け出しエンジニア
・駆け出しエンジニアの頭の中を知りたい管理職とかの人

#### 本記事の概要
タイトル通り、1年半エンジニアである僕の考えを書き連ねます。

この度11月からの案件では要件定義～展開まで一気通貫でがっつり参画することができ、様々な業務・フェーズを経験することができました。

携わった業務から得た学び・教訓・自戒・印象がメインになるかと思います。
読者の皆様におかれましては、共感したり、初心を思い出したり、私のような初心者エンジニアと接するための話題にしたりしてください。
また、未経験の方々にとっても、得るものがあればこれ幸いです。



## キッティング業務に対する印象

キッティング業務というとインフラエンジニアの第一歩や登竜門の一つとしてお馴染みという印象があります。
手順書をしっかりと読解し、確認事項を逃さず、焦らず丁寧に従事する必要があり、とても大切なお仕事です。

ですが、巷ではあまり良くない印象を持たれている側面もあります。
自身の技術力の向上に役立たない業務だと言われているのです。
ですので、私もキッティングにはあまり前向きではありませんでした。


## 実際にキッティング業務を経験すると

実際にキッティング業務を担当することになりました。
私にとって本格的なキッティング業務は初めてです。

オチを先に述べますが、
キッティング業務を軽視するエンジニアは『浅い』と、心の底から思いました。
たくさん学べることがあるなと感じながら黙々と100台（プレ展開）をキッティングする3日間を私は経験しました。

たしかに技術力はそれほど必要ではありません。
ゆえに、技術力の劇的な向上はそれほど望めません。

しかし、エンジニアとしての素質は技術力だけではないことなど、聡明な読者諸君には改めて伝える必要は無いだろうね。
キッティング業務からは技術力以外の素質に関わる部分をかなりたくさん学べるのではないかと感じました。


## キッティング業務から学べること

・手順書の神髄
・実物に触れる重み

### ・手順書の神髄
「技術力の劇的な向上はそれほど望めません。」と前述しましたが、技術力が全く向上しないわけではありません。

手順書や操作内容は知見の結晶！
技術力の基礎となるものがたくさん詰まっています。
初歩的なところでは、ショートカットキーやコマンドが覚えられます。
キッティングではマウスが使えないこともあります。マウス操作はクリックミスや意図しないドラッグアンドドロップ等で取り返しのつかないミスを招く危険性があるからです。
そもそも汚さないために手袋をしているとマウスパッドが触れませんなんてパターンもあるようです笑

また、考える姿勢を養うことも大切でしょう。
どうしてこの手順は必要なのか。この手順の目的は何か。
どうしてこの確認項目は必要なのか。確認できないとどうなるのか。
どうしてこの操作でこの結果になるのか。この結果を選択した理由は何故か。
このコマンドは何をしているのだろう。このアプリケーションはなんだろう。
様々な知見が隠れているので追求していくことを楽しみましょう。

実際、早くキッティングすることに集中しすぎている作業者さんより、操作の意味を考えている作業者さんのほうが抜けやミスが少なく、確認事項をしっかりと網羅していました。（結果そのほうが早い）
落ち着いて正確なキッティングをするために、理解することは必要だと感じました。
手順書通りにすればいいんだから～と何も考えずに動いている人はかなり甘いです。それこそ成長の機会を捨てているように見えました。
こうした姿勢を養うことは今後のエンジニア人生を豊かなものになると、確信しています。





### ・実物に触れる重み

エンジニアは成果物を出して納品するし、製造業みたいなもんだと思うのですが、キーボードごしに機械の中身を操作することがメインになるのであまりそういう見られ方をしていないと思います。
ただ、お客さまの資産を扱っている気持ちは忘れていけないことです。
私が構築してきたものはお客さまが触るということが少なく、運用保守メンバーにわたることが基本だったので、先日までそこの気持ちがふわっとしてしまっていたなと痛感し、気を引き締め直しました。

キッティング業務はまさにこれからお客さまが使う端末を仕上げる業務。お客さまの目に・手に触れるもの。
お客さまが新しい端末を楽しみにしているところに指紋べたべた・傷だらけ、袋しわくちゃ・箱ボロボロのものを届けるなんて言語道断。
細心の注意を払って懇切丁寧に取り扱いながら一つずつ梱包まで終えました。

この経験は死ぬまで生きると思っています。
我々の仕事もモノづくりであると、扱うものの重みを知り、肌で感じながら作業できたことで、これからはこの気持ちを忘れずに仕事と向き合うことができそうです。




## あとがき
1年半インフラエンジニアの頭の中シリーズ続けます。

僕が初心忘るべからずのためでもあり、
未経験者の心構えの一助となればうれしいためでもあり、
教育の立場にあるような方々への参考になればうれしいためでもあり、、、。

どこかで書きたいと思いますが、この度、未経験者/経験が浅い参画者の方々にキッティングを指導する立場を経験したため、人材教育や指導、研修への関心がかなり高まっています。
良い指導のコツなどの記事があればコメントよりリンクいただけますと転がって喜びます。何卒。
アドベントカレンダー25記事以上書く過程とふりかえり

# アドベントカレンダーきっかけ
11月末にQiitaFMを聞いてQiita Advent Calendar 2024のプレゼント企画について知り、サイトを確認すると完走賞で __Qiitanのぬいぐるみ__ が当たるとあり、気軽に始めてしまいました。
「他のプレゼント賞は当たりそうにないけれど、期間中に "25記事以上を書くだけ" で絶対にプレゼントが当たるなんて素敵すぎる！」と前向きに思っていました。

# ふりかえり1. 記事ネタ
始める前にネタ帳や記録を見返したり、25記事分のネタを見積もったつもりでした。
甘かったです。
書き始めてみると、複数のネタのはずが1記事におさまってしまったり、あまり面白くなかったりとすぐにネタ切れになりました。悲しい。
結局、この記事を含めない24記事中9記事が初めに準備していたネタを元にしており、残り __15記事は当日に苦しみながらなんとか産んだ記事__ でした。

記事ネタが思いつかない日は朝からずっとネタを探していて、好きなYouTubeや記事をぼおっと見てみたり、人と会話して思いつかせました。

# ふりかえり2. 時間
アドベントカレンダー自体は11月中の記事を登録してもよいようなのですが、気づいたのが11月末だったので、ほぼ毎日Qiita記事を書く時間を捻出していました。
朝は5分だけでもPCに向かい、夜に主に書いていました。周囲の協力もあったからこそ時間を確保できました、ありがとう。
冬が近づくにつれて、どんどん朝も夜も暗く寒くなっていきました。

# ふりかえり3. やる気・モチベーション
初めはQiitanぬいぐるみをゲットするためにやる気満々です。
ネタ切れしてきた15日ぐらいが一番、モチベーションが下がり、辞めたくなりました。
そこで諦めずに、苦しいながらもQiitanぬいぐるみのためだとだましだまし記事を書いていると、殘り5日間となった20日には開放感を求めてむしろやる気が上がっていました。
継続するのは難しいですし、本当にマラソンみたいですね。

![Qiita Advent Calendar2024やる気グラフ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568190/42ab626f-46f5-916c-fb18-8fcabd8af9e5.png)

# 感想
技術記事ネタに対する自分の見積が甘いことがよくわかりました。
時間を一定以上作るのは大変で、モチベーションはやめさえしなければどうにかなることも分かりました。
継続できたという自信もつきました。
「いつか書こう」と溜まっていたネタを放出する機会になったので、アドベントカレンダーへの参加はとてもよかったです。

もしもう一度アドベントカレンダーに参加するなら、絶対に記事ネタだけは考えてからにします。被っていないか、本当に自分がおもしろいと感じるかも真面目に考えます。
プログラミング言語Cのアドベントカレンダー2024最終日

# はじめに
プログラミング言語Cのアドベントカレンダー2024最終日がついに到来しました！メリークリスマス！:tada::santa_tone2:

https://qiita.com/advent-calendar/2024/crzlang

アドベントカレンダー2024の中に12月1日になってもCがなかったので作ってしまいました。

# Cとの関わりの１年を振り返る

今年の前半ごろはODBCライブラリを少しラップするライブラリ関数をCで実装していました。アドベントカレンダー2024の期間中は実装的な記事を書けませんでした。たいへん失礼いたしました。

# 謝辞
@Cheesecake2960さん、@PitaQさん、@kaizen_nagoyaさん、素敵な記事の投稿まことにありがとうございました。

# おわりに
来年もアドベントカレンダーやりましょう:santa_tone2:誰もつくらなかったらまた作成しますが、たぶん他の方のが適切かと存じます。今年はあくまで代打ということでたいへん失礼いたしました。
オブジェクト指向Cコンパイラ comelangが本当に完成したと思います

version 11.0.0で本当に完成したと思います。
今までコレクションライブラリが根本的に使いづらかったですが、バグを直してます。

```C
string a = s"AAA".scan(/./)[0];

puts(a);
```

これが今まで動いてませんでした。根本的なバグがありました。
直しています。
いや、ほんと、こんなバグが残っているとは思いませんでした。ごめんなさい。

あとRubyのSinatoraみたいなプロジェクト始めてます。
Cinatoraと言います。シンプルなWAFに仕上げたいと思います。
と言っても、2、３日で作れるような規模にしか作りませんが。
まあ、テストページとか作るのに使いたいです。
一応mdファイルのパーサー作ろうと思ってます。
そっちも2、３日程度で仕上げたいと思います。

いや、ほんと、今まで使い物になってなかったと思います。
これでようやくGo並に使いやすくなったと思います。
まだ、あり得ないバグがあるかもしれませんが、直していきたいと思います。

あとプロジェクトマネージャーもほんと使いづらいです。00main.c 01server.cなどと
数字を前に入れないとヘッダーの自動生成の順番が制御できません。
でも、これは仕様としたいと思います。comelangのプロジェクトマネージャーを使いたい場合は
ヘッダーの生成の順番を考えて数字を前に入れてください。
また、対応策が思いつけば直すかもしれませんが。うーん、Makefileの生成のテキストが
あれば順番を制御できるので、それを作るかもしれません。
ただ、それを学習するコストをユーザーにかけさせるのも、僕的にはどうかと思うので。
わかりません。
【CISSPを目指して】0002～0009日目【4.1.5. SDN（Software-Defined Networking）】

# はじめに

好きなところからとなると、SDNなんですよね。
得意というわけではなく、ネットワークスペシャリストの勉強していたときから、妙にSDNに魅力を感じている技術なので。
一番最初に学習すれば、自動的に復習の回数も多くなるので、まずはここから手を付けていくことにします。

特に今のところは合格が目標ではなく、知識習得が目標なので、のんびりとDockerとか使い、実機動作確認とかやれれば楽しそうだなぁと思ってます。

[1日目](https://qiita.com/o_chan_t/items/dae59da696307cf9ddd6)

# ネットワークセキュリティとテレコミュニケーション
4.1. ネットワークアーキテクチャとデザイン
4.1.1. ネットワークトポロジー
4.1.2. セグメンテーション
4.1.3. DMZ
4.1.4. VLANs
[4.1.5. SDN（Software-Defined Networking）](https://qiita.com/o_chan_t/items/be88ecf4f19533a79a63#sdnsoftware-defined-networking)

# SDN（Software-Defined Networking）
## SDNの概念と原理
[0002日目の学習->Zenに投稿](https://zenn.dev/o_chan/articles/cb9f8580f37202)
1. SDNの定義
2. SDNの基本原理
3. SDNの特徴
4. SDNの目的と利点

## SDNアーキテクチャの構成要素
[0003日目の学習->Zenに投稿](https://zenn.dev/o_chan/articles/4806304863c865)
1. コントロールプレーン
2. データプレーン
3. アプリケーションプレーン
4. 各プレーン間のインターフェース

## SDNコントローラーの役割と機能
[0004日目の学習->Zenに投稿](https://zenn.dev/o_chan/articles/765dbe85a85ba9)
1. コントローラーの主要機能
2. ネットワーク抽象化
3. トポロジ管理
4. ポリシー適用

## SDNのセキュリティ上の利点と課題
[0005日目の学習->Zenに投稿](https://zenn.dev/o_chan/articles/7850b5c511127e)
1. セキュリティポリシーの一元管理
2. ネットワークの可視性向上
3. 動的なセキュリティ制御
4. SDN特有のセキュリティリスク

## SDNの実装と運用管理
[0006日目の学習->Zenに投稿](https://zenn.dev/o_chan/articles/05b87f90d561bd)
1. SDN導入のステップ
2. ネットワーク仮想化技術
3. SDNの監視とトラブルシューティング
4. SDNの性能最適化

## SDNと従来のネットワークの比較
[0007日目の学習->Zenに投稿](https://zenn.dev/o_chan/articles/953028bf2804bf)
1. アーキテクチャの違い
2. 管理と運用の違い
3. スケーラビリティとフレキシビリティ
4. コストと効率性の比較

## SDNの標準化と主要プロトコル
1. OpenFlow
2. NETCONF
3. OVSDB
4. その他のSDN関連プロトコル

## SDNの使用事例と適用分野
1. データセンターネットワーク
2. クラウドコンピューティング
3. キャリアネットワーク
4. エンタープライズネットワーク
標的型攻撃メール訓練の評価項目案

# １．標的型攻撃メール訓練とは
実際の攻撃メールに似せて作成した疑似攻撃メールを訓練対象者に送る
(参考)https://www.lac.co.jp/lacwatch/report/20170912_001379.html


# ２．評価項目案
| 項目 | 説明| 
|:-----------|:------------|
|開封率|メール自体を開いたかどうか|
|URLクリック率<br>添付ファイルダウンロード率|クリックしてしまったかどうか|
|迷惑メール報告率|報告したかどうか(通報機能の利用率)|
|IT部門など所定組織への相談率|相談や報告をしたかどうか<br>(相談/報告する規則があればその順守率として評価できる。特になければ参考値として使える|

# ３．やったほうがいいこと
抜き打ちで行う
クリック時に、警告ポップアップの大々的表示など印象に残るものにする(記憶に残す)
改善率の幅を見るなど、できたことにも着目する(結果の報告時)
など

# ４．やってはいけないこと
クリックしてしまった人への叱責
良い結果を残そうとするための姑息なこと(事前に実施日などを部内にリークなど)←やる意味がかなり薄れる
など
タニーさんの机で大惨事、水中ポンプで大洪水発生！！


# ミカさんやシノさんに触発されたタニーさん
TLP-A100やTLP-Pシリーズを使ってミカさんやシノさんが回路を組んでいるのを見て、自分もやってみたくなったタニーさん。回路を組んで上手く動いたは良いものの、机の上が大変な大洪水になってしまいました。詳しくは動画を観てください。

<iframe width="100%" height="720" src="https://www.youtube.com/embed/62dpvyDTFos" title="TLP A100で回路を組んだら大惨事！？机がプールになった理由とは！" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## 参考
[ESP32-WROOM-32DとMAX6675を組み合わせてK型熱電対の値をSPI経由で取得してみた。](https://qiita.com/mix_dvd/items/fed8075de40aa468a775)


## 回路
ACアダプタ -> TLP-A100.Type-C.INPUT
TLP-A100.VBUS.OUTPUT -> TLP-P050.VIN
TLP-A100.VBUS.GND -> TLP-P050.GND
TLP-P050.VOUT -> Pump.Posi
TLP-P050.GND -> Pump.Nega
TLP-A100.Type-C.OUTPUT -> ESP32.MicroUSB
TLP-A100.MicroUSB -> PC

ESP32.PIN18 -> MAX6675.SCK
ESP32.PIN19 -> MAX6675.SO
ESP32.PIN05 -> MAX6675.CS
ESP32.PIN17 -> TLP-P050.EN

## 使用部品
[TLP-A100](https://amzn.to/41OD7Gl)
[TLP-P050](https://amzn.to/3DGXOtF)
[水中ポンプ](https://amzn.to/4iScFld)
[適用 MAX6675モジュール Kタイプ 熱電対センサー](https://amzn.to/3VTwGhu)
[waves ESP32 DevKitC V4 ESP-WROOM-32 ESP-32 WiFi BLE (5個セット)](https://amzn.to/409FUZB)

## プログラム
熱電対の温度が70℃を超えるとポンプが動作する仕組みです。

~~~diff_cpp
#include "max6675.h"
 
int thermoDO = 19;
int thermoCS = 5;
int thermoCLK = 18;
const int PIN_PUMP = 17;
byte bPUMP;

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
 
void setup()
{
  Serial.begin(9600);
  Serial.println("MAX6675 test");
  delay(500);
  bPUMP = LOW;
  pinMode( PIN_PUMP, OUTPUT );
  digitalWrite( PIN_PUMP, LOW );
}
 
void loop()
{
  // basic readout test, just print the current temp
  
  Serial.print("C = ");
  Serial.println(thermocouple.readCelsius());
//  Serial.print("F = ");
//  Serial.println(thermocouple.readFahrenheit());
  if ( thermocouple.readCelsius() > 70.0 ){
    if ( bPUMP == LOW ){
      bPUMP = HIGH;
      digitalWrite( PIN_PUMP, HIGH );
    }
  }else{
    if ( bPUMP == HIGH ){
      bPUMP = LOW;
      digitalWrite( PIN_PUMP, LOW );
    }
  }
  delay(1000);
}

~~~
英語学習で利用しているサービスの話

こんにちは、ふるすです。
私の趣味は英語学習なのですが、昔と違って書籍やCDを使った学習だけでなく、様々なサービスに頼っています。
今日はその中からいくつかピックアップしてご紹介します！

## Chat GPT

https://openai.com/ja-JP/chatgpt/overview/

言わずと知れたAIチャットサービスですね。
英語学習に良いと言われているAIサービスはほかにもあるのですが、気軽に使いやすくてずっと利用しています。

さて、AIサービスを学習で使うために重要なプロンプトですが、私は下記のようにカスタマイズしています。


**自分についてChatGPTに知っておいてほしいこと**
```
私は英語学習者で現在のレベルはCEFR B1からB2程度です。
来年中にC1レベルになりたいです。
私の趣味は美術の勉強です。またKPOPが好きです。
```
**どのようにChatGPTに回答してほしいか？**
```
基本的に英語で会話してください。
私が日本語で説明してくださいとお願いしたときだけ日本語で返事をしてください。
毎回カジュアルに、友達のように絵文字を使って会話をしてください。
私のことは名前で呼びかけてください。
```

上記のようにすることで、私が取得したい日常英会話を友達とするかのように返答してもらえたり、堅苦しくなく話しかけてくれます。

## Otter

https://otter.ai/jp

音声ファイルを取り込むと文字起こしや要約をしてくれるサービスです。
私はオンライン英会話をSkypeで行っているので、録画して音声ファイルを取り込んで復習に役立てています。
あとから聞き直したり、レッスン中は何と言っているのかよくわからなかった表現を再確認したりできるので重宝しています。

## reminDO

https://remindo.co/?&locale=ja&savelocale=1

忘却曲線に基づいて記憶を定着させるためのアプリです。
保存していくのは少し手間なのですが、記憶が怪しくなってきたタイミングでテストが入るので、確実に暗記ができるようになります。学生時代にこのアプリがあったらどんなによかったことか…。

ここまでお読みいただきありがとうございました！
ほかにもおすすめのサービスがありましたら教えていただけると嬉しいです。
Mindのアドベントカレンダー2024最終日

# はじめに
Mindのアドベントカレンダー2024最終日がついに到来しました！メリークリスマス！:tada::santa_tone2:

https://qiita.com/advent-calendar/2024/mind

# Mindとの関わりの１年を振り返る

今年はMind８のランタイムをだいぶ深堀しました。CランタイムのC#ランタイムへの書き換えは途中でとまってしまいましたが、またいつか復活いたします。


# 謝辞
@killyさん、@Mind-Club_2017さん、@ITvisionさんたいへんお忙しいところ記事投稿、コメンテーション、いいねの応援まことにありがとうございました。無理をいってたいへん申し訳ございませんでした。

@ohisama@githubさん、今年もたくさんの記事投稿ありがとうございました。


# おわりに
来年はついにMind生誕40周年!:tada:　Mind９もリリースされますので、来年もアドベントカレンダーやりましょう:santa_tone2:
Flutter でデバイスOSの判定をする方法

# これなに

OSごとに処理を分けたいときにどう実装するのかをメモしました


# 解決方法

`dart.io` をインポートして、OS の判定を行います
以下の例ですと、iOS, iPadOS, macOS のいずれかの時に Text を描画し、そうでない OS の場合は空の Container を描画する（つまり何も描画しない）ように処理しています

```dart
import 'dart:io' show Platform;
...

(Platform.isIOS || Platform.isMacOS) ? 
  Text(
    'iOS, iPadOS, macOS の時のみこのテキストを表示',
    textAlign: TextAlign.center,
    style: const TextStyle(color: Colors.black87, fontSize: 24.0),
  ) : Container(),
...
```


# 定義されているメソッド

以下のようにOSの名前でメソッドが書かれているのでわかりやすい
もはや説明不要ですね

- isAndroid
- isFuchsia
- isIOS
- isLinux
- isMacOS
- isWindows

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819748/2239bad2-aff6-b09e-65f6-8f74e72a2c9b.png)


# あとがき

iOS のみで Apple ID 認証を実装したくてこの判定処理を使いました
他に良い方法があったらぜひ教えてください！
SingletonとSingletonMonoBehaviourまとめ

# 概要
Singetonパターンは多くのプロジェクトで使われると思いますが、自分で色々なプロジェクトを作っているとプロジェクト間で実装に差が出たり、毎回実装しなくちゃいけなかったりします

自分がよく使っているコードをまとめておきます

# Singleton

```csharp
public abstract class Singleton<T> where T : new()
{
    private static T _instance;
    public static T I => _instance ??= new T();
}
```
 - 使い方
Singletonクラスを継承することで、`SingletonSample.I.Increment();`のようにして呼び出すことができます
```csharp
public class SingletonSample : Singleton<SingletonSample>
{
    public int Value { get; set; }

    public SingletonSample()
    {
        Value = 0;
    }

    public void Increment()
    {
        Value++;
    }
}
```


# SingletonMonoBehaviour

```csharp
using UnityEngine;

public abstract class SingletonMonoBehaviour<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T _instance;
    public static T I
    {
        get
        {
            if (_instance != null) return _instance;

            var foundObjects = FindObjectsByType<T>(FindObjectsSortMode.None);
            _instance = foundObjects.Length > 0 ? foundObjects[0] : new GameObject(typeof(T).Name).AddComponent<T>();
            return _instance;
        }
    }

    protected virtual void Awake() => DontDestroyOnLoad(gameObject);
}
```

 - 使い方
Singleton同様に継承して使う
```csharp
public class SingletonMonoBehaviourSample : SingletonMonoBehaviour<SingletonMonoBehaviourSample>
{
    public int Value { get; set; }

    public void Increment()
    {
        Value++;
    }
}
```

# 動作確認用スクリプト
とりあえずSingletonを試したい方向け
適当なオブジェクトに以下のコンポーネントを付けて再生してください

```csharp
using UnityEngine;

public class Tester : MonoBehaviour
{
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            SingletonSample.I.Increment();
            Debug.Log(SingletonSample.I.Value);
        }

        if (Input.GetKeyDown(KeyCode.B))
        {
            SingletonMonoBehaviourSample.I.Increment();
            Debug.Log(SingletonMonoBehaviourSample.I.Value);
        }
    }
}

```
Slack SDKのWebhookClientでSlack投稿する

# はじめに

この記事では、**Slack SDK**の**WebhookClient**を使用してSlackにメッセージを投稿する方法を解説します。
また、メッセージの構成要素である`text`、`blocks`、`attachments`についても詳しく説明します。
## 必要なライブラリのインストール
まず、必要なライブラリをインストールします。

```bash
pip install slack-sdk
```

`slack-sdk` は Slack API を利用するための公式ライブラリです。

## WebhookURLの発行
Slackにメッセージを送信するには、Webhook URLが必要です。以下のURLからWebhook URLを発行してください。

https://api.slack.com/messaging/webhooks


## `text`、`Blocks`、`Attachments`の違い
Slackメッセージの構築方法には以下の3つがあります。

- **text**
シンプルなテキストメッセージを送信する際に使用します。
- **Blocks**
リッチで構造化されたメッセージを作成するための推奨方法。新しいプロジェクトではこちらを使うのがベストです。
- **Attachments**
レガシーなメッセージ構成方法で、現在は`blocks`の使用が推奨されています。ただし、[背景色を指定する機能はattachmentsにしかない](https://api.slack.com/messaging/attachments-to-blocks#direct_equivalents)ため、必要に応じて使用してください。


## コード例: Blocksを使ったメッセージ投稿
以下のコードは、`blocks`を使ったメッセージ送信の例です。
```python
from slack_sdk.webhook import WebhookClient
from slack_sdk.models.blocks import DividerBlock, HeaderBlock, SectionBlock

# 1. Webhook URLを指定（発行したURLを貼り付けてください）
url = "https://hooks.slack.com/services/your/webhook/url"

# 2. WebhookClientを初期化
webhook_client = WebhookClient(url)

# 3. Blocksを使ったメッセージ構成
response = webhook_client.send(
    blocks=[
        HeaderBlock(text="テストメッセージ送信"),  # 見出し部分
        DividerBlock(),   # 区切り線
        SectionBlock(text="*これはテスト:* テストメッセージ")  # メインのテキスト部分
    ]
)

# レスポンスを確認
print(response.status_code)
```

## メッセージデザインのコツ: Block Kit Builderの活用
Slack公式の[Block Kit Builder](https://api.slack.com/tools/block-kit-builder)を活用すれば、視覚的にメッセージを設計し、コードに簡単に反映できます。

- プレビューを見ながらメッセージを編集可能
- `blocks`構成のコード例をその場で生成可能
- チームでデザインを共有してレビューしやすい

ぜひ使いこなして、より魅力的なメッセージを作成してみてください！


## まとめ
Slack SDKのWebhookClientを使用すると、簡単にメッセージを投稿でき、`blocks`を活用すればリッチなメッセージを構築できます。
この記事が参考になれば幸いです！

ご拝読ありがとうございました。