OmniAICreator/Qiita-1.07M huggingface dataset:
[Rails]TagHelpersのtagメソッドについて学ぶ

# ActionView::Helpers::TagHelperとは
公式ドキュメントには以下のような説明がなされています。
HTMLタグを生成するための便利なメソッドを提供してくれるようです。

:::note info
ActionView::Helpers::TagHelper provides methods to generate HTML tags programmatically both as a modern HTML5 compliant builder style and legacy XHTML compliant tags.
:::

本記事では、その中でも特に汎用性が高い**tagメソッド**に焦点を当て、基本的な使い方から実践的な活用方法まで解説します。

# tagメソッドとは

tagメソッドは、任意のHTMLタグを生成するためのRails標準のメソッドです。

https://api.rubyonrails.org/classes/ActionView/Helpers/TagHelper.html#method-i-tag
### 基本的な使い方
**シングルタグの生成**
例えば、空の画像タグを生成する場合は以下のように書くことができます。
```erb
<%= tag.img(src: "logo.png", alt: "Site Logo") %>
```
出力結果:
```erb
<img src="logo.png" alt="Site Logo">
```

**ブロック構文でのネスト**
tagメソッドはブロックを使用して、ネストしたHTMLを生成することも可能です。
```erb
<%= tag.div(class: "card") do %>
  <%= tag.h2("Card Title", class: "card-title") %>
  <%= tag.p("This is a description.", class: "card-text") %>
<% end %>
```
出力結果:
```erb
<div class="card">
  <h2 class="card-title">Card Title</h2>
  <p class="card-text">This is a description.</p>
</div>
```

**カスタムデータ属性の追加**

data属性も簡単に設定できます。
```erb
<%= tag.button("Click Me", data: { id: "1" }, class: "btn btn-primary") %>
```
出力結果:
```erb
<button class="btn btn-primary" data-id="1">Click Me</button>
```

# 個人的に便利だと思った活用例
最近役に立った使い方を最後に紹介します。以下のコードを見てください。
```erb
<div>
  <p>商品情報</p>
  <% if product.available? %>
    <p class="product-status available">在庫あり</p>
  <% else %>
    <p class="product-status unavailable">在庫なし</p>
  <% end %>
</div>
```
viewに条件分岐の処理があるのが微妙ですね、、

これを解決してくれたのが今回のtagメソッドでした。
以下のようにヘルパーを作成して、条件分岐をviewからヘルパーに移動します。
```Ruby
module ProductsHelper
  def product_status_html(product)
    if product.available?
      tag.p("在庫あり", class: "product-status available")
    else
      tag.p("在庫なし", class: "product-status unavailable")
    end
  end
end
```

このようにすると、ビューは次のようにシンプルになります。
```erb
<div>
  <p>商品情報</p>
  <%= product_status_html(product) %>
</div>
```
viewでの条件分岐がなくなり、シンプルになったことに加え、責務が明確になりました。これは嬉しいですね。

# 補足：content_tagメソッドについて
tagメソッドと同様に、任意のHTMLタグを生成できるcontent_tagメソッドも存在します。
```erb
<%= content_tag(:img, nil, src: "logo.png", alt: "Site Logo") %>
```
しかし、こちらに関しては公式ドキュメントにてレガシー記法であるとされていますので、tagメソッドを使うのが無難そうですね( ͡° ͜ʖ ͡°)

:::note alert
Note: this is legacy syntax, see tag method description for details.
(公式ドキュメントより引用)
:::

https://api.rubyonrails.org/classes/ActionView/Helpers/TagHelper.html#method-i-content_tag
仮想世界とつなぐ橋渡し：クラウドテクノロジーがメタバースを形作る方法

> 本記事は[こちらのブログ](https://www.alibabacloud.com/blog/bridging-the-virtual-world-how-cloud-technology-shapes-the-metaverse_601876?spm=a2c65.11461433.0.0.4ee35355Xcc2A1)を参考にしています。
> 翻訳にはアリババクラウドの[ModelStudio](https://www.alibabacloud.com/en/product/modelstudio)([Qwen](https://www.alibabacloud.com/en/solutions/generative-ai/qwen))を使用しております。

## クラウド技術がメタバースで果たす役割

クラウド技術は、<a href=https://www.alibabacloud.com/jp/solutions/metaverse target=_blank>メタバース</a>の開発とそのさらなる進化において重要です。相互接続された仮想世界が勢いを増す中、クラウドソリューションは、このような没入型環境を実現するために必要なスケーラビリティ、信頼性、および計算能力を提供します。新たなデジタル時代の入口で、メタバースとクラウド技術の統合は、私たちが生活し、社会的交流し、協力し、デジタル領域と対話する世界を変えることをしています。

### クラウドが提供する主要な利点：スケーラビリティ
メタバースにとって、クラウドプロバイダーが提供するスケーラビリティは大きなメリットです。クラウドは動的なリソース配分を可能にし、メタバースが変動するトラフィック量に対応しやすくし、大規模なユーザーをサポートしながら、体験を妨げることなく処理することができます。これにより、どこからでもいつでもメタバースにアクセスできるようになり、デスクトップ、ラップトップ、モバイルデバイスから仮想環境にアクセスできるようになります。アクセス性が向上し、ビジネスや個人がインフラストラクチャを利用することで、ハードウェア、ソフトウェア、またはITリソースなどの大規模な資本投資を必要とすることなく活躍できます。特に中小企業にとってコスト削減効果は著しいです。

### クラウドがもたらす信頼性とコスト効率
クラウド技術は、コスト効率だけでなく、メタバースの信頼性を高める要素でもあります。クラウドプロバイダーはインフラストラクチャやリソースに多額の投資を行い、高い稼働時間と可用性を確保し、ユーザーにシームレスで信頼できる仮想環境での体験を提供します。さらに、複雑でダイナミックなメタバース内の環境を構築するために必要な大規模な計算リソース、特に高速処理とスケーラブルなストレージを提供します。これにより、リアルタイムで没入型の仮想体験が実現され、ユーザーにとって豊富なインタラクティブな世界が生み出されます。

例えば、メタバースが仮想環境とユーザーデータをホストするために大量のストレージ容量を必要とする場合、アリババクラウドなどのクラウドプラットフォームは必要なスケーラビリティと信頼性を提供し、ユーザーデータがアクセスしやすく、安全であり、仮想体験に無駄なく統合されることを可能にします。

### アリババクラウドがメタバース成功への鍵
アリババクラウドは、メタバースが生きた体験となる複雑な仮想環境をサポートする強固で信頼性の高い計算基盤を提供します。ユーザーデータのセキュリティと簡単なアクセスを確保し、メタバースが膨大な情報量を保存しながらパフォーマンスを妥协することなく、この進化するデジタル空間でのユーザーにとって没入型でシームレスな体験を創造するための信頼性とスケーラビリティが不可欠です。この強力な機能により、ユーザーにとって豊かで没入型の体験が実現されます。

メタバースは、中断されないユーザー体験を提供するためには高速なネットワークとシームレスな接続性を必要とします。アリババクラウドは、分離されたネットワークを作成し、仮想マシンや他のリソースを効率的かつ安全に接続して、仮想環境でのデータ通信を実行することを支援します。また、高速で信頼性の高いリソースアクセスを確保するために複数の接続オプションを提供します。例えば、世界中のリージョンとデータセンターのネットワークにより、ユーザーはデータとリソースを顧客やエンドユーザーに近づけることができ、遅延を低減し、<a href=https://www.alibabacloud.com/jp/solutions/metaverse target=_blank>メタバース</a>での優れた体験を向上させます。

### 数碼化の進化におけるメタバースとクラウド計算の統合の意味
メタバースとクラウドコンピューティングが交差するこのデジタル世界では、イノベーションと変革の可能性は無限大です。没入型の体験とダイナミックな仮想風景を持つメタバースは、アリババクラウドのようなクラウドプラットフォームに強力なパートナーを見つけることができます。この連携によって、メタバースにとって必要なスケーラビリティ、セキュリティ、効率性が確保され、コラボレーション、エンゲージメント、知能を備えたデジタル体験の新たな可能性が開かれます。

結論として、メタバースとクラウド計算の統合はデジタル進化の分水岭であり、これらの技術のトレンドは人類が環境をどのように視し、関与し、体験するかを根本的に変える可能性が高いです。

免責事項: ここに述べられている見解は参考のみであり、必ずしもアリババクラウドの公式見解を代表するものではありません。
2024年の私的toio活動メモ

完全に私的なメモでございます。今年もたくさんtoioで楽しませていただきました。

# 1月

[M5StackToio](https://github.com/kenichi884/M5StackToio)の修正　
複数core cubeつないだときに、ID読み取りがおかしなことになっていた。

複数接続がちゃんと動くようになったので手持ちのtoio core cube全部つかって6個までの動作を確認した。

https://www.facebook.com/groups/toiotomo/permalink/2294015867466347/

後日、[淳【Jun】](https://x.com/GEH00073)さんが9個に挑戦してくださった。

https://x.com/GEH00073/status/1791071024580366529

# 2月
複数接続のバグを直した[M5StackToio](https://github.com/kenichi884/M5StackToio) v1.0.3 でリリース・

# 3月

クラウドファンディングで先行販売の「トイオ プレイグラウンド」を入手。

https://www.facebook.com/groups/toiotomo/permalink/2344939992373934/

# 4月
[M5StackToio](https://github.com/kenichi884/M5StackToio) システムソフトウェア v02.0006 BLE protocol 2.4.0の姿勢角取得の高精度オイラー角、クォータニオンに対応。

# 5月
BLE protocol 2.4.0対応を[M5StackToio](https://github.com/kenichi884/M5StackToio)　v1.0.4 でリリース。

https://www.facebook.com/groups/toiotomo/permalink/2369671443234122/

# 6月
Ogaki mini maker faireにエントリー申し込み。

https://www.facebook.com/groups/toiotomo/permalink/2406611836206749/

日本科学未来館にxModの展示の２回目？を観に行った。

https://www.facebook.com/groups/toiotomo/permalink/2410030902531509/

[ヘボコン2024のYoutubeライブ](https://www.youtube.com/watch?v=agH5YUByEXY)を見て、toio core cubeを使った機体が出ていることを知り感動する。

https://www.facebook.com/groups/toiotomo/permalink/2409348025933130/

https://www.facebook.com/groups/toiotomo/permalink/2410167139184552/

https://www.facebook.com/groups/toiotomo/permalink/2428419297359336/

# 7月

ｽﾀｯｸﾁｬﾝお誕生会2024に参加。

https://www.facebook.com/groups/toiotomo/permalink/2420836808117585/

https://docs.google.com/presentation/d/186M8a8ouff_oBr4j4CmEP-brTQKRSvgxdxwYsm4thco/edit?usp=sharing

# 8月

絶滅メディア博物館で開催されたヘボコンの野試合参戦に[簡単ｽﾀｯｸﾁｬﾝ w/ toio](https://protopedia.net/prototype/5496)対戦仕様で参戦。

https://www.facebook.com/groups/toiotomo/permalink/2447698092098123/

# 9月

レゴ互換ブロックのベラボットのネコロボットをtoio core cubeにくっつけてみた。

https://www.facebook.com/groups/toiotomo/permalink/2461943034006962/

[NT東京](https://nt-tokyo.org/)見学。[棒人間Worksさん](https://x.com/miyabixs1)のところでtoio Doを使ったゲームを展示されていた。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431649/6ae5e7ee-eb3b-cb87-8c6a-e2a90472e46a.jpeg" width=40% /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431649/d69cc4a9-30d0-3017-5ad6-c78895a37e7d.jpeg" width=40% /> 

https://protopedia.net/prototype/5546


Maker Faire Tokyo見学。

https://www.facebook.com/groups/toiotomo/permalink/2478769952324270/

M5Stack Japan Tour 2024 Autumn Tokyoに田中章愛さん他とLT登壇した。自分の担当パート(M5StackToioの話)は１分でしゃべらないといけなかったのでだいぶ早口になった。

https://m5stack.connpass.com/event/329550/

https://drive.google.com/file/d/1O7SbRfBU8wanLAw_6swcaVp-dgc4JhGQ/view?usp=sharing

# 10月

大垣ミニメイカーフェアにむけていろいろ準備。

https://qiita.com/kenichih/items/2ac7ff6d67f4f922edd5

https://qiita.com/kenichih/items/14d0df34d7b95ab7c7af

# 11月

Ogaki mini Maker Faire 2024に参加。

https://qiita.com/kenichih/items/790827a413a880b6daf9

# 12月

Advent calender立ててみた。

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

来年もまたtoioでいろいろ遊びましょう。
120時間の履修証明プログラムは何単位？結論8単位~12単位だが注意点も

120時間の履修証明プログラムは何単位なのでしょうか。
 大阪城業大学のホームページでは履修証明プログラムで120時間以上の受講を行うには、12単位以上の受講が必要になります。
 単位数については、各大学が教育効果や授業時間外に必要な学習などを考慮して、2単位分をおおむね15時間から45時間の範囲で定めることとなっています 。

60時間の履修証明プログラムが1単位だったら悲しくなりますよね。大体4単位以上ないと履修証明プログラムのモチベが出ないと思いませんか。

とすると120時間の履修証明プログラムは8単位以上と考えられます。

この計算をもとに15時間で1単位とすると、120時間のプログラムは360時間の計算になります。

ここで学士号取得の一般的な目安（フルタイムで4年間の場合）をご説明します。

1単位時間あたりの学習時間: 約3時間（講義時間＋予習復習時間）
卒業に必要な単位時間: 約120単位時間
計算:

120単位時間 × 3時間/単位時間 = 約3,600時間

120時間の履修証明プログラム（8単位）で学習時間は（120時間×3で計算して）合計で360時間を10回～15回すると学士が狙える計算になります。

また8単位を15倍すると120単位になるので15回で学士相当になると言えます。

ここでその大学の単位授与の材料にならないと単位授与されないみたいです。

履修証明プログラムを通じてキャリアアップしたいですね！
【Udemyで楽楽合格】非ITエンジニアでも2週間でAZ-900に合格できた話

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

こちらは上記企画の投稿となります。


先日(12月21日)、Azure Fundamentals(AZ-900)に合格できたので、勉強法を備忘録がてら記そうと思います。
ずっと前からQiitaに記事を投稿したかったのですが表立ったトピックがなかったため、やっと初投稿できます。

## 自己紹介
はじめまして。saapon13と申します。
新卒入社から現在まで、転職は経つつもずっとIT業界にて働いています。
ただし間接部門での業務が長く、直接部門で働いているのは現職が初めてです(まだ3か月強)。
資格取得前のクラウド知識というと、本当にさわりの部分、オンプレミスがどうとか、EC2って名前聞いたことあるな、とか。それ以上の知識はないという状況でした。
なお、Microsoft認定資格については、今回が初の受験というわけではなく、以前別の認定資格を取得していた状況です。
[Qiitaの定義](https://help.qiita.com/ja/articles/qiita-community-guideline)では、仕事でプログラミングをしていなくても、プログラミングを通した物作りに関わっている人、今まさにプログラミングを学んでいる人全てをエンジニアを扱ってくれるそうです。趣味でプログラミングを通したシステムを作っていて、並行でプログラミングを学んでいます。やば！？！私、エンジニアだったの！？！！？？！？！
~~飲み屋で言っちゃお！~~

## 合格までにやったこと
- Microsoft Azure Virtual Training Day の受講
すみません、これは9月末に受講していたため、少しタイトルは誤りではあります
ただし、業務を行いながらであったため、受講時の資料をもらえるであろうというのが
狙いでした。 ~~あとは半額バウチャー目当て~~
- Microsoft Learn での学習
[こちら](https://learn.microsoft.com/ja-jp/training/courses/az-900t00)のコースを修了しました。
ここで理解しようとは到底考えておらず、**Microsoft Learn特有**の言い回しを理解して
おきたいという気持ちがあり、まずはひと通り目を通しました。
- Udemy での問題集をひたすら解く
「最短で合格！Azure Fundamentals AZ-900 試験対策問題集」

 https://www.udemy.com/course/microsoft-azure-az900-exam/
  
こちらをひたすら解きました。し、こちらをおすすめします。
おすすめ理由としては
問題数が豊富である(個人の体感では多すぎずちょうどいい)のと、解説がわかりやすい点。
各問題の説明や注意点を記載していてくださっていて、さらなる詳しい解説についてはご自身のサイトのURLを掲載、MicrosoftLearnでは難読な日本語で、理解しやすい記述だったところ。
70問 * 5つの問題集があり、私は演習モードで1周行った後、試験モードで3周ほど行いました。
2周目から8割～9割前後の正答率を取れるようになり、安心しきっていた私は…(フラグ)。

ちなみに、Udemyでの購入は今回が初めてでした。もっと早く手を出しておけばよかった。
今度は何かの資格の講座も購入し、学習を進めていきたいと思っています。

- 理解の及ばないところを他サイトの解説で補完

 https://az-start.com/
  

https://qiita.com/Negi-jume/items/e4ec76959adb547ac5e8

上記2つのサイト・記事にて、何回も間違ってしまう問題の解説を読み込みました。

Microsoft LearnとUdemyの問題集を解き、解説サイトで知識を補完。
これらを2週間ほどで行いました。
ただし2週目は3日ほどしか学習できておらず、1日も1～2時間ほどしか取れていません。
日々の業務の都合にもよりますが、詰めれば1週間ぐらいでできる密度ではありました。

ちなみに、以前は利用したころのあったExamtopicsは利用しませんでした。
出題範囲が大きく変わり、今般では関係ない範囲がそのままであったためその取捨選択に時間をかけたくなかったためです。

## 結果、試験を受けての所感
1000点中700点以上で合格ですが、まさかの794点…。
問題集や公式の理解度チェックで9割ほどだったので、当日見たことない・聞いたことない
知識を問う想定外の問題で何問か落とすと踏んでいて、予想通りでした。
「Azureのアーキテクチャとサービスの説明」セクションが一番の出題比率を占めていたのですが、一番とれていなかった…。点数以上に危機感を覚えました。
Udemy問題集について純粋に周回不足だったと感じましたし、誤った問題だけで表示できるので、スプレッドシートなどにまとめておくべきだったと反省しています。
試験合格が目的ではなく、業務および自己研鑽のための通り道であったため、復習を繰り返し知識定着につとめる所存です。

## 今後について
そもそもAzure Fundamentalsの資格取得をしたきっかけが、OpenAI Serviceに興味があったから。遠回りですが、外堀を理解できていないと何にもならないよなと思い学習・受験した次第です。が、AnthropicやGoogleもスルー出来ないですし、AWSやGoogleCloudについても学習してみたいなと思っています。

ここまでお読みいただいた方がいらっしゃいましたら、ありがとうございました。
Goによるプロダクト開発における日々の改善とその成果

### はじめに

この記事は[Hacobu Advent Calendar 2024](https://qiita.com/advent-calendar/2024/hacobu)の24日目の記事です。

こんにちは、Hacobuでバックエンドエンジニアをしている イワカミと申します。普段は MOVO Fleetという動態管理プロダクトの開発をしています。MOVO Fleetについては[8日目の記事](https://qiita.com/os-hcb/items/2a07cc9efc56ac0bc895) で使用している技術が垣間が見えるかなと思います。また、チーム開発については [15日目の記事（私が書きました）](https://qiita.com/iwag@github/items/0a9426815b80e91a56e7) にあります。

ちょうど1年前から取り組んでいたバックエンドの生産性や開発者体験向上のために行った改善について書かせていただきます。なお、私だけじゃなく同僚が行った取り組みも含まれています 🙇 

### 依存関係のリファクタリング

過去にチームで作成したライブラリが多数存在しており、メンテナンスが十分に行われていませんでした。具体的には、Goのバージョンや依存しているライブラリ（例：aws-sdk-go）、Linterが古いまま使われていたり、そもそもライブラリの役割が把握されていないという状況がありました。また、弊チームではモノレポではなく、ライブラリやAPI、サービスごとにリポジトリが分かれているため、管理が複雑化していました。

まず、これらを一気に図として書き出し、現状を可視化しました。その過程で多くの発見がありました。例えば、存在すら知らなかったリポジトリや、Go 1.81のまま放置されているリポジトリが見つかりました。現在は基本的にGo 1.21を使用しています。

特に難しかったのは、複数のサービスの共通部分をライブラリとして切り出した結果、ライブラリの数が増えすぎるという問題でした。このため、真に必要な共通ライブラリを再設計し、小さなライブラリを統合する作業を進めました。また、1つのサービスでしか使用されていないライブラリについては利用元にコードを移し、不要なリポジトリを削除しました。これにより、開発環境の管理が大幅に改善しました。

---

### gRPC リポジトリを廃止

私たちのプロダクトは、API → gRPCを利用するサービスという構成になっています。従来は、API → gRPC（protoファイル集） ← サービスというリポジトリ構成でしたが、開発中のgRPC変更頻度が高く、複数人での開発ではビルドエラーやコンフリクトが頻発していました。

そこで、gRPCとサービスを統合する方針に変更しました。この結果、API → サービスという依存関係となり、gRPC変更時の煩雑さが解消されました。また、PRの数が減り、開発効率が大幅に向上しました。

と、自分の手柄みたいに書いてますが、gRPCサービスにまとめたいねって言ってたら、同僚がスッと検証してくれてそんな大変じゃないですよとやってくれた。仮説検証へのフットワークが軽く、サクッと検証して簡単にできそうだったんでやりましたみたいな仕草は見習いたいと思っている。

---

### gRPCのバリデーションを廃止

従来、gRPCのprotoファイルで  [proto-gen-validate](https://github.com/bufbuild/protoc-gen-validate) を使用していましたが、以下の理由から廃止することにしました：

1. ルールが曖昧で、バリデーションが記述されたりされなかったりしていた。
2. エラー防止効果が薄く、エラーメッセージが曖昧でユーザー体験が悪かった。
3. ツールの対応状況がバラバラで、開発効率が低下していた。

今後はサービス層でバリデーションを実施する方針に変更しました。これにより、エラーメッセージのカスタマイズ性が向上し、ユーザー体験の改善が期待できます。

---

### CIの高速化

当社で使用しているCircleCIの実行時間を8分から4分半程度に短縮しました。タスクを単体テスト、DB利用テスト、結合テストなどに分割し、並列実行することで処理時間を短縮しました。同僚が主導して進めてくれたこの取り組みは、スケール性の高い解決策でした。

また、並列化によるビルドキャッシュの課題にも対応しました。各タスクでキャッシュの保存と復元を明示的に設定することで、問題を解決しました。ただし、CircleCIのストレージコストが増加するというトレードオフも発生しました。

### そのほかの取り組み

- 同僚がGoのホットリロードツール[Air](https://github.com/air-verse/air)を導入してくれました。コードを変更したときも手動で再起動ボタンを押す手間が省け、開発者体験が爆上がりました！
- 開発前にテスト観点レビューを始めました！エッジケースや考慮漏れが減少しました。テストパターンができているとはいえその期待値は絶対ではなく、開発してからも期待値を修正しましょうというようにコミュニケーションが楽になりました。
- ダークローンチが高度化され、毎週リリースをスリップすることがなくなりました。
- [schemaspy](https://schemaspy.org/) を導入しました。
- [samber/lo](https://github.com/samber/lo) を普段使いするようになりコードがスッキリするようになりました。

---

### まとめ

個人的には、これらの改善を、毎週のリリースや機能開発プロジェクトの合間を縫って実施した点がいいなと思っています。特定の日を改善する日として設けたり、リファクタリングにXX週間くださいと調整することなくです。当社のバリューである「[Spark Ownership](https://hacobu.jp/company/mission/)」ってこういうことかなと思いました。
ショート動画でクイックに知る！ 5分で知るIBM Concertの活用例　SBOMによるソフトウェアコンポーネント管理編

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/cdfebe71-9cce-a2f2-2b4f-a6e9f265b397.png)



# はじめに

みなさん、IBM Videoというサイトをご存知でしょうか？
IBMが提供する製品をショート動画でわかりやすくご紹介している動画サイトです。
* スキルアップしたくてもなかなか時間が取れない
* 気になる製品があるけど、マニュアルを読んで理解するのはきつい
* 製品の特徴やメリットをクイックに知りたい

という方には、うってつけの動画を提供するサイトです。
興味のある方はぜひご覧いただければと思います。

# 今回ご紹介する動画へのリンク

[5分で知るIBM Concertの活用例　SBOMによるソフトウェアコンポーネント管理編](https://video.ibm.com/recorded/134137637)

# IBM ConcertによるSBOMを活用したソフトウェアコンポーネント管理とは？

## 概要
IBM Concertは、アプリケーションに含まれるソフトウェアコンポーネントを効率的に管理するためのツールです。特にSBOM（Software Bill of Materials）を活用することで、複雑化するソフトウェア環境のリスクを可視化・管理します。

## SBOMとは？
* ソフトウェア部品表（SBOM）は、アプリケーションの構成要素とその依存関係を詳細にリスト化したものです。
* 各コンポーネントの詳細情報を一覧で確認でき、脆弱性やライセンスのリスク管理を容易にします。
* 近年、SBOMは規制の対象として重要性が高まっており、EUのサイバーレジリエンス法（2024年10月施行）にも適合する必要があります。

## IBM Concertの機能と活用法

### デモ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/8590b1bc-367f-725a-c41b-833d89999941.png)

### 可視化機能
* アプリケーション環境内のコンポーネントを一覧表示し、リスクの有無を一目で確認。
* 例：4,510件のコンポーネント中、1,159件にリスクありと識別。

### リスク分析機能
* 古いバージョン：1,070件
* ライセンス問題：41件
* 脆弱性：31件
* サポート終了：17件


各リスクに対して詳細を確認し、優先的に対応すべき項目を判断できます。

### ライセンス管理
* 使用されているライセンスを一覧で確認し、法的リスクを回避可能。

### 詳細分析
* 個別のパッケージについてバージョンや信頼性スコア、ライセンス状態をチェック。
* 関連リポジトリや環境の情報と連携し、適切なアクションを特定。

## 導入メリット
* ソフトウェア環境全体を可視化し、脆弱性やライセンス違反リスクを迅速に特定。
* 法規制への適合を強化し、コンプライアンス対応を支援。
* 効率的な管理プロセスにより、手作業での管理負担を軽減。

# まとめ
IBM Concertは、SBOMを活用したソフトウェア管理により、セキュリティとコンプライアンスの強化を実現します。デモでは具体的なリスク特定や管理手順が紹介され、実際の運用イメージが示されました。

このソリューションを導入することで、企業はより安全で効率的なソフトウェア運用を目指せます。

# 参考

5分で知るIBM Concertの活用例　SBOMによるソフトウェアコンポーネント管理編

https://video.ibm.com/recorded/134137637
Trnasfer Family-S3間でイベントトリガーを設定する際の注意点



はじめに
----------
S3にファイルをアップロードする場合、アップロードしたファイルは完全に操作が完了したタイミングでS3側に反映をされるため、アップロードを中断しても断片的なファイルがアップロードされるということはありません。

>単一のキーに対する更新はアトミックです。例えば、あるスレッドから既存のキーに PUT リクエストを実行し、同時に同じキーに対して別のスレッドから GET リクエストを実行すると、古いデータまたは新しいデータを取得できますが、データの一部分だけが取得されることも、破損することもありません。

ですが、Trnasfer Familyを経由してS3にファイルをアップロードする際、アップロードを中断をすると中断時点の断片的なファイルがそのままS3にアップロードする挙動をします。


問題点
---------
例えば、以下のようなS3にアップロードしたファイルをトリガーに起動するLambda関数があるとします。
![スクリーンショット 2024-12-24 10.05.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193020/00616512-b7f6-86dd-2b77-2172b2fccfbf.png)
S3-Lambdaのみの構成であればS3イベント通知かEventBridge RuleでS3のオブジェクト作成イベントをトリガーにすることが一般的です。
何らかの理由でアップロードが中断した場合も断片的なファイルがS3にアップロードされることはなく、オブジェクト作成イベントもトリガーすることはありません。

次に、以下のようなTrnasfer Family経由でS3にアップロードしたファイルをトリガーに発火するLambda関数があるとします。

![スクリーンショット 2024-12-19 19.27.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193020/34783fb0-c673-bfcc-111c-50071d6ee871.png)

Trnasfer Family経由の構成でS3のオブジェクト作成イベントをトリガーにしてしまうと、断片的なファイルがS3にアップロードされた場合も後続のLambda関数が起動することになります。
このような断片的なファイルをトリガーに後続の処理を起動したくない場合は以下の対処法を参考にしてください。

対処法
----------------
S3イベントではなくEventBridge RuleにあるTransfarのイベントパターンをトリガーにします。
SFTPであれば[SFTP Server File Upload Completed]のイベントタイプをトリガーにすることでアップロード中断された際に後続の処理がトリガーされることはなくなります。
![スクリーンショット 2024-12-19 20.26.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193020/21fd180c-d6e7-fd77-cb72-4626702ef9ad.png)


さいごに
-----------
なんらかの事情でFTP/SFTPを避けることができない場合にTransfer Familyはとても重宝します。
Transfer Familyを経由するかしないかでS3へのファイル更新の挙動が異なる点は理解しておきましょう。
【IBM Cloud】ICOSをgoofysでマウントした場合のI/O性能

## はじめに
最近オブジェクトストレージをgoofysやs3fsなどでマウントして、通常のディスクと同じように利用するケースが多くなっております。

IBM CloudにもIBM Cloud Object Storage(ICOS)というサービスが存在し、仮想サーバからマウントして利用することが可能となっております。

ただ通常のディスク（Block Storage, File Storage）と違い、トランザクションを中心としたストレージではないため、どのくらいの性能が出るかは気にかかるところです。

今回、vpc上のVSIからICOSをgoofysでマウントして性能検証しましたので、簡単に共有いたします。
比較のため、ローカルディスクも参考に計測しております。

## 検証環境

IBM CloudのTOKYOリージョンのvpc環境で実施しております。

【サーバ】
・Virtual Servers for vpc
・OS : CentOS Stream 9 (Default設定）
・SPEC : bx2-2x8 (2vCPU, 8GB)
・NW Bandwidth : 3000Mbps

## 検証テスト内容

<b> ケース1) オブジェクトストレージ</b>

・IBM Cloud Object Storage
　goofys によりマウント（デフォルト・オプション）
 ```terminal
$ goofys --endpoint https://s3.direct.jp-tok.cloud-object-storage.appdomain.cloud (bucket名) /mnt/icos 
```

<b> ケース2) ローカルディスク </b>
・容量 100GB（3,000 IOPS）


<b>【検証方法】</b>
ddコマンドにて３つの異なるサイズのファイルをそれぞれの対象のストレージに作成。
3回試行の平均値

``` terminal
$ dd if=/dev/zero of=1G.dat bs=1M count=1000 
```
※ bs:バッファーサイズ(全てのケース 1M固定)
※ 上記のコマンドは1GBファイルの場合（1Mを1000回書き込む）

## 検証結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239309/09cb3d92-2594-c667-439e-b4300e27f30a.png)

## 検証結果に対するコメント

ICOSの性能検証は、特にキャッシュが効いていないため、ICOSへの実際の書き込みスピードと考えられます。
またgoofysにもローカルディスクにキャッシュする機能があるので、そちらを利用することで更に性能を上げることは可能であると考えられます。

ローカルディスクの場合は、ファイルキャッシュがきいているため、実際のディスクIO性能ではないと考えられます。10GBケースはキャッシュが足りなくなり、 性能が下がっているものと考えられます。

## さいごに

ICOSへのIO性能として、ブロックサイズなどを変更することで値が変わる可能性はありますが、一つの目安としていただければと思います。
実際にgoofysなどでマウント利用されるケースは、事前にその利用ケースで計測することをおすすめいたします。
【Power Apps】 ボタンの名付けとかグループ化活用とか考えてみます。

## 同じコントロールを続けて作成するときの名前について
たとえばアプリにボタンを10個並べたい時、
ボタンを新規作成すると```Button1```と名前が付けられます。

これをコピーすると
```Button1_1```,```Button1_2```,```Button1_2```と名前が付けられます。

そこで名付けの法則を利用して、あらかじめ```BtnName_1```などと名前を変えておきます。
先に「_1」を入れておくことで、コピーするたびに```BtnName_2```,```BtnName_3```とちゃんと数字が増えていきます。

## コントロールの配置とグループ化
次に違う用途のボタンを用意しようと新規作成しても、```Button1```と名付けられるので、分かりやすい。
ついつい名前を変更するのを忘れがちですが、こうしておくと開発が進むにつれて有り難みが大きくなります。

ボタンを縦に並べる場合は、一番大きい数字のボタンを、並べたい範囲の一番下に持っていき、
次に全てのボタンを囲んで選択し、左揃え、上下に並べる。とすると大変美しく並びます。
配置が決まったらグループ化します。

すべて囲むか選択して```Ctrl＋G```、Macなら```Option＋G```でグループ化。

## どのボタンが押されたか名前で判定
どのボタンが押されたかを簡単に分かるようにしてみます。
１０個ボタンを配置し、グループ化しておきます。
ボタンのテキストに１から１０の番号を半角数字でふります。
半角数字＋半角空白＋タイトルとします。→「1 title」こんな感じです。

ここからOnSelectプロパティに数式を書いていきますが、
ボタンを配置したグループを選択状態にしてOnSelectに以下のように書きます。
```
Set(_btnNum,Value(Left(Self.Text,2))
```
グループ選択状態なら、すべてのボタンのOnSelectに↑が記入されます。
SelfTextの左から2番目までの文字を数字にして変数に入れるので、ボタンを押すと変数```_btnNum```にそれぞれのボタンに付けた番号が、数値として入ります。
これなら数式も１つで良いし、修正も1度で済むので重宝します。

半角空白は無視されて数値のみ取得できるので、↑数式では2桁までの数値に対応。
そんなに要らないと思いますが、もっと多い桁数に対応させるなら
```
Set(_btnNum,Value(First(Split(Self.Text," ")).Value))
```
こう書いて、半角空白の位置より前の文字列を数値化して取得。

後は、IfやSwitch分などで、判定してそれぞれ処理させます。

以前クイズアプリを作った際に使用しました。

ちょっと触っただけで座標の数式が消えたりして迷惑だったりしますが、グループ化も使い方次第で便利です。
【学習】RailsでCSVインポートからフォーム作成まで挑戦してみた

## はじめに
今回下記アドベントカレンダーに参加したので、個人開発でチャレンジしたオートコンプリート機能について記事を書きたいと思います。

https://qiita.com/advent-calendar/2024/engineering-careers-1

具体的には、Railsを使ったCSVファイルのインポートとフォームへのデータ表示の方法を共有します。
初めて挑戦する際に悩んだポイントや解決の流れも交えていますので、初心者の方に少しでも参考になれば嬉しいです。


合計すると1週間は悩んだ末にたどりついた
いや、正直心が限界で「こころここにあらず」でしたがある記事に最後の望みを託し挑戦したらできました。
(コードで空欄がだいぶありますが、実際に入力したファイルからそのまま持ってきているのでご了承ください💦)


## 環境
Windows, WSL
Docker
Ruby 3.2.3
Rails 7.1.3


## 実装の流れ
### 1. CSVファイルの用意と配置
まず、データベースにインポートするためのCSVファイルを作成します。
以下のように、`id`と`name`を含むデータを準備してください。
**CSV例**
```bash
id,name
1,Tokyo
2,Yokohama
3,Osaka

```

作成したCSVファイルを、プロジェクトディレクトリの`db`配下に配置します（例: `db/stations.csv`）。



### 2. CSVファイルをデータベースにインポート
**コンテナ内に入る**
`docker compose`を使用している場合、以下のコマンドでWebコンテナ内に入ります。
```bash
docker compose exec web bash
```

**インポート用コードの作成**
CSVを読み込むためのコードを`db/seeds.rb`に記述します。
```ruby
require 'csv'
CSV.foreach(Rails.root.join('db/stations.csv'), headers: true) do |row|
  Station.create(
    id: row['id'],
    name: row['name']
  )
end
```

**コード実行**
以下のコマンドを実行して、CSVファイルをデータベースにインポートします。
```bash
rails db:seed
```

**データ確認**
Railsコンソールを開き、データが正しくインポートされているか確認します。
```bash
rails console
Station.all
```



### 3. 新規投稿フォームに駅名を表示する
**ビューの編集**
`app/views/posts/new.html.erb`を編集し、`datalist`で駅名を表示します。

```
<label for="station_id">駅名</label>
<input type="text" id="station_id" name="station_id" value="<%= @station.present? ? "#{@station.name} (ID: #{@station.id})" : '' %>" autocomplete="on" list="stations">
<datalist id="stations">
  <% @stations.each do |station| %>
    <option value="<%= "#{station.name} (ID: #{station.id})" %>"></option>
  <% end %>
</datalist>
```

**コントローラーの編集**
`app/controllers/posts_controller.rb`の`new`アクションを編集し、データをビューに渡します。
```ruby
def new
  @post = Post.new
  @stations = Station.all
end
```

**表示確認**
ブラウザでフォームを開き、`datalist`に駅名が表示されていることを確認します。

👇：表示確認
![スクリーンショット 2024-09-10 111750.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777936/786737ae-92f9-a29b-7cbd-23dd90932cb8.png)


## 参考記事
今回の実装にあたり下記記事を参考にして進めました

https://zenn.dev/3oc/articles/e9be5161b2f070


## さいごに
RailsでのCSVデータのインポートやビューへの反映は、最初は戸惑うことも多いですが、一度理解すれば非常に便利な機能です。
この記事を通じて、少しでもみなさんの開発に役立つ情報を提供できれば嬉しいです。
これからも試行錯誤を続け、アウトプットを増やしていきたいと思います！
SpringBoot公式リファレンスを初心者向けに紐解く①

SpringBootの公式リファレンスは、読んでいるだけで初心者にとってはわからない言葉がある。単語や用語の解説を交えたり、公式リファレンスを読んでいてわからない部分を紐解いた、初心者向け記事です。
役立つサイトや記事へたくさんリンクさせていただいています。:pray:

## SpringBoot概要
>Spring Boot とは、設定がほとんど不要で Spring と外部ライブラリを利用でき、規約に従うことにより Spring ベースのアプリケーションを簡単に作成できる事実上標準の Java フレームワークです。

>Spring Boot を使用して、Tomcat 組み込みの java -jar で起動可能な jar ファイル、または従来の Tomcat に デプロイ可能な war ファイルを作成することができます。

* Springとは

https://x-hours.com/articles/958

* 外部ライブラリとは
プログラミング言語に追加される形で提供されるライブラリであり、さまざまな機能や機能拡張を提供するツールのこと

+ Tomcatとは

https://freelance.shiftinc.jp/column/tomcat

+ warファイル、jarファイルとは

https://magazine.techacademy.jp/magazine/23660


## システム要件
>Spring Boot 3.4.1 には少なくとも Java 17 が必要であり、Java 23 までのバージョンと互換性があります。Spring Framework 6.2.1 以上も必要です。
ビルドツールは、Maven、Gradleのサポートがあり、デフォルトではGradleが使用される。

* javaのバージョン選択について(↓のサイト大変参考になります）

https://note.com/woinary/n/n2cff47715b18

* Spring Frameworkとは（Java,Spring,Spring Framework,SpringBootの関係性を知ると、SpringBootの便利さを感じる↓）

https://hnavi.co.jp/knowledge/blog/spring-boot/

* ビルドツールについて

https://qiita.com/yskuma6684/items/62f31ffc6e5580500e31


>サーブレットコンテナー
Spring Boot は、次の埋め込みサーブレットコンテナーをサポートがあり、デフォルトでは Tomcat が使用されます。
Tomcat 10.1 (10.1.25 以上)　サーブレットバージョン：6.0
Jetty 12.0　サーブレットバージョン：6.0
Undertow 2.3　サーブレットバージョン：6.0

* サーブレットコンテナーとは
Java Servlet（Webサーバで動くJavaプログラムのこと）を動かすときに必要なソフト

>GraalVM ネイティブイメージ
Spring Boot アプリケーションは、GraalVM 22.3 以降を使用してネイティブイメージに変換できます。
イメージは、ネイティブビルドツール [GitHub] (英語)  Gradle/Maven プラグインまたは GraalVM が提供する native-image ツールを使用して作成できます。ネイティブイメージ Paketo buildpack [GitHub] (英語)  を使用してネイティブイメージを作成することもできます。

* ネイティブイメージとは
Javaコードをバイナリ(ネイティブ実行可能ファイル＝専用の動作環境が不要で直接実行が可能なファイル)に事前にコンパイル（プログラムのコードを実行可能な形に変換すること）する技術のこと。
上記で言っているのは、GitHubというソースコード管理ツールで提供されているツールを使用して、ネイティブイメージを作成することもできるということ。
詳しくは

https://qiita.com/studio_meowtoon/items/ab5c7758874683367540


## インストール
インストールは解説サイトがたくさんあるのでここでは省きます。
kintoneカスタマイズ サブドメインを取得する

# 環境
- kintone
- javascript

# 対象
- kintoneカスタマイズ（プラグイン開発）でサブドメインを取得したい人

# kintoneURLの種類
kintoneのURLには以下の種類があります。

- 通常
  - https://サブドメイン.cybozu.com/k/v1/records.json
- ゲストスペース
  - https://サブドメイン.cybozu.com/k/guest/ゲストスペースID/v1/records.json 
- セキュア
  - https://サブドメイン.s.cybozu.com/k/v1/records.json 

全てのパターンで取得できる様にします。

# 対応
今回は以下のコードでサブドメインを取得します。
``` subDomein.js
    //kintone環境URL・サブドメイン
    const url = kintone.api
        .url('/k/v1/records.json', false);
    const subDomein = url
        .match(/^https:\/\/([^.]+)/)[1];  // httpsプロトコルの後からドットまでの文字列を抽出
```
### コード説明
- 正規表現^https:\/\/([^.]+)を使用して、URLの先頭から最初のドットまでの文字列を抽出
- match()メソッドの結果から、キャプチャグループの値（インデックス1）を取得
jQuery UI Datepickerのカスタマイズ：date2の日付をdate1より前の日付しか選択できないようにする

フォームで2つの日付選択フィールドを扱う際、しばしば2つの日付間に依存関係を持たせたいケースがあります。例えば、2つ目の日付を1つ目の日付より前の日付しか選択できないようにしたい、といった要件です。

今回は、jQuery UI Datepickerを使って、このような依存関係を実装する方法をご紹介します。

## 実装したい機能

今回は以下のような機能を実装します：

- 1つ目の日付フィールド（date1）を選択した後
- 2つ目の日付フィールド（date2）では、date1より前の日付しか選択できない
- すでにdate2に日付が入力されている場合、date1がその日付より前に変更されたら、date2をクリアする

## 実装コード

```javascript
jQuery(function($) {
  // datepickerの既存のオプションを拡張
  $(".hasDatepicker").datepicker("option", {
    dateFormat: "yy年mm月dd日"
  });

  // 1つ目の日付選択時の処理
  $("#mw-client-terminate_day1").on('change', function() {
    var date1 = $(this).datepicker('getDate');

    if (date1) {
      // 2つ目の日付の選択可能最大値を更新
      $("#mw-client-terminate_day2").datepicker("option", "maxDate", date1);
      
      // 2つ目の日付が1つ目より後の場合はクリア
      var date2 = $("#mw-client-terminate_day2").datepicker('getDate');
      if (date2 && date2 > date1) {
        $("#mw-client-terminate_day2").val('');
      }
    }
  });

  // 2つ目の日付選択前の処理
  $("#mw-client-terminate_day2").datepicker("option", "beforeShow", function() {
    var date1 = $("#mw-client-terminate_day1").datepicker('getDate');
    
    if (date1) {
      return { maxDate: date1 };
    }
  });

  // オートコンプリートを無効化
  $('form .hasDatepicker').attr('autocomplete', 'off');
});
```

## コードの解説

### 1. 基本設定

```javascript
$(".hasDatepicker").datepicker("option", {
  dateFormat: "yy年mm月dd日"
});
```

既存のdatepickerに対して日付フォーマットを設定します。この例では「yyyy年mm月dd日」形式を指定しています。

### 2. 1つ目の日付選択時の処理

```javascript
$("#mw-client-terminate_day1").on('change', function() {
  var date1 = $(this).datepicker('getDate');
  // ...
});
```

1つ目の日付が選択されたときの処理を定義します。`getDate()`メソッドで選択された日付をJavaScriptのDateオブジェクトとして取得します。

### 3. 2つ目の日付の制限設定

```javascript
if (date1) {
  $("#mw-client-terminate_day2").datepicker("option", "maxDate", date1);
  // ...
}
```

2つ目の日付フィールドの`maxDate`オプションを、1つ目で選択された日付に設定します。これにより、その日付より後の日付が選択できなくなります。

### 4. 既存の日付のクリア処理

```javascript
var date2 = $("#mw-client-terminate_day2").datepicker('getDate');
if (date2 && date2 > date1) {
  $("#mw-client-terminate_day2").val('');
}
```

すでに2つ目のフィールドに日付が入力されていて、その日付が新しく選択された1つ目の日付より後の場合、2つ目の日付をクリアします。

### 5. 2つ目の日付選択前の処理

```javascript
$("#mw-client-terminate_day2").datepicker("option", "beforeShow", function() {
  var date1 = $("#mw-client-terminate_day1").datepicker('getDate');
  if (date1) {
    return { maxDate: date1 };
  }
});
```

2つ目の日付選択カレンダーが表示される直前に、選択可能な最大日付を設定します。これにより、カレンダーUI上でも選択可能な日付が視覚的に制限されます。

## 実装時の注意点

1. すでにdatepickerが初期化されている場合は、新規に初期化せず、`datepicker("option", ...)`で設定を追加します。
2. 日付の比較は必ずDateオブジェクトに変換してから行います。
3. オートコンプリートは無効化しておくことをお勧めします。

## まとめ

jQuery UI Datepickerを使用して、2つの日付選択フィールド間に依存関係を設定する実装を紹介しました。このような実装は、予約システムや各種申込フォームなど、様々な場面で活用できます。

コードの中核となるのは、`maxDate`オプションの動的な設定と、`change`イベントでの既存値のバリデーションです。これらを組み合わせることで、ユーザーフレンドリーな日付選択機能を実現できます。
Siv3DでWebSocket通信したい！

# はじめに
みなさんこんにちは！
緑獺おがめです。
こちらはSiv3D AdventCalendar2024 17日目の記事です。
16日目くらいから体調不良で寝込んでおり、全く記事を書けておらず、大遅刻となりますがこちらの記事を執筆しています。
すみませんでした。

# きっかけ
Siv3Dの開発、なにか手伝えることないかなぁとGitHubのIssueを眺めていたんですが……。
流石Siv3Dですよね。な～～んにもわかりません。
手伝えることないなぁ、なんかないかなぁと思っていた矢先にですｎ、気づいてしまったんですよ。

「……あれ？　WebSocket通信サポートしてなくね……？」

まあ急を要するほどのものでもないのですが、せっかくならあるとSiv3Dの幅も広がりますし、なにより私でも実装出来そう……！
ということでやってみようとなりました。

ちなみにまだ完成はしていません。あしからず。

# ライブラリ選定
さあ、開発をしていきましょう。
Siv3DはC++で開発されているので、それに合わせて選ぶことになります。
調べると色々出てきました。
- Boost
- Websocketpp
- Civet
- etc...

結論としては、Boostを用いることにしました。
既にSiv3D内で用いられているため、導入にさほど手間もないかなと考えました。

また、SSL化のためにOpenSSLも用いています。

# コーディング
ごりごりコーディングしていきます。
Boost.BeastのサンプルコードとにらめっこしながらSiv3Dっぽい実装を考えました。

ソースは以下に貼っておきます。
https://github.com/Ogame3334/Siv3DWSClient

Main.cppに以下を記述することで用いることができます。
また、ビルドには`/bigobj`のオプションが必要になります。

```cpp
﻿#include <Siv3D.hpp>
#include "include/WSClient.hpp"

void Main() {
	System::SetTerminationTriggers(UserAction::CloseButtonClicked);

	ogm::WSClient client;

	client.onMessage([](const StringView message) {
		Print << message;
	});
	client.onClose([] {Print << U"websocket通信は正常に閉じられました"; });
	client.onError([](const StringView message) {
		Print << message;
	});
	client.onOpen([] {Print << U"接続がオープンしました"; });


	client.open(U"echo.websocket.org", 443);
	

	TextEditState textEdit;


	while (System::Update()) {
		if (KeyEscape.down()) {
			client.close();
		}

		SimpleGUI::TextBox(textEdit, Vec2{ 100, 100 });
		if (SimpleGUI::Button(U"send", Vec2{ 100, 200 })) {
			client.send(textEdit.text);
			textEdit.clear();
		}
	}
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558342/9f5f2076-9761-f455-f261-5770d0ee0186.png)

helloと送ると、エコーサーバーなのでそのまま返ってきますね。
どうやらうまくいってそうです。

ただ、終了処理がまだうまくいっておらず、現在は正常終了してくれないのでタスクキルしています。

# 課題点
いくつかあります。
- SSL化の方法は現在の実装で良いのか(多分良くない)
- 正常終了する
- 色々整える

これらをクリアしなければなと思いました。

# 終わりに
最後まで読んでいただきありがとうございました！
体調が治ってから大急ぎで書いていますので至らぬ点もあるかと思いますが、大目に見ていただけると助かります。

ではまた～～。
Pythonで時刻歴データ内の繰り返し部分を抽出する

**１．時刻歴データから繰り返し部分を自動で抽出したい**
**２．抽出したデータを正規化して，オーバープロットしたい**

時刻歴データサンプル
![スクリーンショット 2024-11-07 7.12.04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1979979/008ce0e9-2aa1-c8d4-843b-92e9ffdabd28.jpeg)

サンプルコードを示す．
```extract_data.py
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import find_peaks

def extract_and_normalize_patterns(data, num_patterns=5, threshold=0.5):
    # 自己相関関数を計算
    autocorr = np.correlate(data, data, mode='full')
    autocorr = autocorr[len(autocorr)//2:]
    
    # ピークを検出
    peaks, _ = find_peaks(autocorr, height=threshold*np.max(autocorr))
    
    if len(peaks) < 2:
        return []
    
    # 最初の2つのピーク間の距離を周期として使用
    period = peaks[1] - peaks[0]
    
    # 指定された数の繰り返しパターンを抽出
    patterns = []
    for i in range(num_patterns):
        start = i * period
        end = start + period
        if end > len(data):
            break
        pattern = data[start:end]
        
        # パターンを正規化
        normalized_pattern = (pattern - np.min(pattern)) / (np.max(pattern) - np.min(pattern))
        patterns.append(normalized_pattern)
    
    return patterns

# サンプルデータの生成（実際のデータに置き換えてください）
t = np.linspace(0, 20, 2000)
data = np.sin(2*np.pi*t) + 0.1*np.random.randn(len(t))

plt.figure(figsize=(12, 6))
plt.plot(t, data)
plt.title('Original Data')
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.show()
# 繰り返しパターンの抽出と正規化
normalized_patterns = extract_and_normalize_patterns(data, num_patterns=10)

if normalized_patterns:
    # 結果のプロット
    plt.figure(figsize=(12, 6))
    normalized_t = np.linspace(0, 1, len(normalized_patterns[0]))
    
    for i, pattern in enumerate(normalized_patterns):
        plt.plot(normalized_t, pattern, label=f'Pattern {i+1}', alpha=0.7)
    
    plt.title('Normalized Repetitive Patterns')
    plt.xlabel('Normalized Time')
    plt.ylabel('Normalized Amplitude')
    plt.legend()
    plt.grid(True)
    plt.show()
else:
    print("No repetitive patterns found.")
```
![スクリーンショット 2024-11-07 7.12.52.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1979979/e144e560-f414-38df-d796-1b8467b5c764.jpeg)
Emacs Lisp 超初心者がコマンドを作ってみる 〜 別フレーム結果表示の実験 既存フレーム再利用〜

# はじめに

前回はフレームを作成してみました。幾らでも同名のフレームが出来てしまうのは困るので、これをなんとかしたい。

# 実験 指定の名前のフレームがあるかどうか調べる
Bing Microsoft Copilot さんに尋ねてみました。

> Emacs Lisp で指定の name の frame が存在するかどうか調べる方法
>
> Emacs Lispで特定の名前のフレームが存在するかどうかを確認するには、以下のコードを使用することができます。このコードは、フレームのリストを取得し、それぞれのフレームの名前を確認して、一致する名前のフレームが存在するかどうかを調べます。

```common-lisp
(defun frame-exists-p (name)
  "Check if a frame with the given NAME exists."
  (let ((frames (frame-list))
        (found nil))
    (dolist (frame frames found)
      (when (string= (frame-parameter frame 'name) name)
        (setq found t)))))
```

最低限1つでもあれば、(全部舐めた上で) t を返すようです。

# 同一名のフレームのリストを返す

前回の実験で同一の名前で複数のフレームが存在することが分かっているので、同一名のフレームのリストを返すようにしましょう。

````common_lisp
(defun frame-named-list (name)
  "list if a frame with the given NAME exists."
  (let ((frames (frame-list))
        (result '())
	)
    (dolist (frame frames)
      (when (string= (frame-parameter frame 'name) name)
        (push frame result)
	)
      )
    result
    )
  )
````

それでは確認してみます。

指定の名前のフレームが無い状態
````text
(frame-exist-list "*pepm-frame*")
nil
````

指定の名前のフレーム作成1回目
````text
(make-frame '((name . "*pepm-frame*") (width . 640) (height . 480)))
#<frame *pepm-frame* 0x646ba17d46c0>

(frame-exist-list "*pepm-frame*")
(#<frame *pepm-frame* 0x646ba17d46c0>)
````

指定の名前のフレーム作成2回目
````
(make-frame '((name . "*pepm-frame*") (width . 640) (height . 480)))
#<frame *pepm-frame* 0x646ba17906e0>

(frame-exist-list "*pepm-frame*")
(#<frame *pepm-frame* 0x646ba17d46c0> #<frame *pepm-frame* 0x646ba17906e0>)
````

ちゃんとリストが返ってきています。

# get-buffer-create な get-frame-crate を作る
get-buffer-create は指定の名前のバッファが既に存在すればそれを返し、無ければ作成する関数です。

同様に、 指定の名前のフレームが存在すればそれを返し、無ければ作成する関数 po-pepm-get-frame-create を作ります。

まずは同名の存在するフレームを得ます
````common_lisp
(defun po-popm-frame-named-list (name)
  "List if a frame with the given NAME exists."
  (let ((frames (frame-list))
        (result '())
	)
    (dolist (frame frames)
      (when (string= (frame-parameter frame 'name) name)
        (push frame result)
	)
      )
    result
    )
  )
````

これを使って po-pepm-get-frame-create を定義します
````common_lisp
(defun po-pepm-get-frame-create (name)
  "If NAME's frame is exist then return exists list.
Else is not exist then create frame by NAME."
  (let ((frames (frames-with-name name))
	)
    (if frames
        frames
      (list (make-frame `((name . ,name)))
	    )
      )
    )
  )
````

使い方
````comon_lisp
(let (
      (frames (po-pepm-get-frame-create "*pepm-frame*"))
      )
  (if (> (length frames) 1)
      (progn
	(ding)
	(message "Multiple %s frames exist!" "*pepm-frame*")
	)
    )
  (car frames)
  )
````


今日はここまで。
【TypeScript】タグ付き（判別可能な）ユニオン型

# はじめに
この記事では、タグ付き（判別可能な）ユニオン型 (discriminated union) の概要を記載します。

https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html#discriminated-unions

# 通常のユニオン型
タグ付きユニオン型の説明の前に通常のユニオン型について、説明します。
ユニオン型では、型をパイプ (`|`) で繋げて表現します。

以下の `AuthState` では、`status` は必須、`user` と `message` はオプショナルになっています。

```sample.ts
type AuthState =
  | { status: string; user?: { id: string; name: string }; message?: string };
```

`AuthState` 型を利用して `status` に応じたメッセージを表示する関数を作成したい場合、オプショナルのプロパティの存在をチェックする条件文を書く必要があります。

```sample.ts
function displayAuthMessage(state: AuthState): string {
  if (state.status === "unauthenticated") {
    return "You are not logged in.";
  }

  if (state.status === "authenticating") {
    return "Logging in... Please wait.";
  }

  if (state.status === "authenticated") {
    if (state.user) {
      return `Welcome back, ${state.user.name}!`;
    }
    return "Error: Missing user information.";
  }

  if (state.status === "error") {
    if (state.message) {
      return `Authentication failed: ${state.message}`;
    }
    return "Error: An unknown error occurred.";
  }

  // No exhaustive type checking
  return "Unknown state.";
}
```

ユースケースとして、`status` が `"authenticated"` の時は必ず `user` が存在するとした場合、この分岐は冗長です。タグ付きユニオン型を使えば、この冗長性を解消できます。

:::note warn
オプショナルのプロパティの存在をチェックする条件文がないと型エラーになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/690eeb0d-80f6-a8de-173a-c353b1ca2a76.png)
:::

# タグ付きユニオン型
タグ付きユニオン型では、ユニオンに属するの各オブジェクトの型を区別するための「タグ」がつきます。

以下の `AuthState` では、`status` が「タグ」に該当します。

```sample.ts
type AuthState =
  | { status: "unauthenticated" }
  | { status: "authenticating" }
  | { status: "authenticated"; user: { id: string; name: string } }
  | { status: "error"; message: string };
```

通常のユニオン型とは異なり、`user` と `message` の存在チェックが不要になります。その結果、分岐処理が読みやすく、保守性も高くなります。

```sample.ts
function displayAuthMessage(state: AuthState): string {
  switch (state.status) {
    case "unauthenticated":
      return "You are not logged in.";

    case "authenticating":
      return "Logging in... Please wait.";

    case "authenticated":
      return `Welcome back, ${state.user.name}!`;

    case "error":
      return `Authentication failed: ${state.message}`;

    default: {
      // Exhaustiveness check
      const _exhaustive: never = state;
      throw new Error(`Unhandled state: ${_exhaustive}`);
    }
  }
}
```

# 参考
- [TypeScript for Functional Programmers](https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes-func.html)
- [判別可能なユニオン型 (discriminated union)](https://typescriptbook.jp/reference/values-types-variables/discriminated-union)
CIテスト環境をコンテナ化してみる

この記事は [セゾンテクノロジー Advent Calendar 2024](https://qiita.com/advent-calendar/2024/saison-tech) シリーズ2 24日目の記事です。
シリーズ2は [HULFT10](https://www.hulft.com/software/hulft-10) のエンジニアによる投稿をお届けします。
# どんなテスト
- テストモジュールからAPI ServerにリクエストすることでAPI Serverから各種の対向サーバにリクエストするe2eテストです。
# 現行のテスト構成
- Windows環境しか動作できないAPI Server(テスト対象)とテストモジュール
- Windowsの対向サーバx2
- Linuxの対向サーバx1
# 今の課題
テスト対象の不具合によってテストが中断される場合がある。そしてテストが中断することで対向サーバの状態をテスト前に戻すことができなくなってしまう。CIとして動作するテストなので、対向サーバの整理作業を行う前に自動にテストが走った場合、必ず失敗することになる。
# なんでコンテナ化に対応できる
- 対向サーバをコンテナ化することで毎回のテストは新たなコンテナとして立ち上がるので、前回のテストによる影響が解消できる
# コンテナ化にするための課題
- WindowsコンテナとLinuxコンテナの混合運用による課題
    - 同時運用するのにLinux環境かWindows環境のどっちが可能なのか
    - Docker Desktopを利用せず、Windows環境でdockerの運用方法
# 同時運用するのにLinux環境かWindows環境のどっちが可能なのか
結論から言うとWindows環境のほうが対応しやすい。
理由はWindowsにはWSLがあるからです。
WSLを有効化することでWindows環境でも簡単にdockerを利用することができる。
# Docker Desktopを利用せず、Windows環境でdockerの運用方法
- Hyper-Vを有効化する
    ```
    Enable-WindowsOptionalFeature -Online -FeatureName containers -All
    Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
    ```
- dockerをCLIで運用するためのバイナリファイルをダウンロードすること
    - https://download.docker.com/win/static/stable/x86_64/
- サービス登録
    ```
    dockerd --register-service
    Start-Service docker
    ```
これでwindowsでもコンテナを運用することができた。
# WSLの運用方法
こちらはネット上に大量記事があったため、割愛します。
# 結果
github actionsでCIが動くたびにwindows runnerで対向サーバのWindowsコンテナとLinuxコンテナが立ち上がるとこができた。テストモジュールとテスト対象API Serverはコンテナ実行ではなく直接実行するして各コンテナに設定したポート経由でリクエストする。
テストモジュールをコンテナ化できていないが、一旦困った問題が対応できたので、ここで区切りして残る対応を残課題として継続に調査する。
# 残課題
- WSL上のLinuxコンテナとホストのWindowsコンテナ間の通信はできない
    - 原因：異なるネットワークインターフェース
# 残課題に向けてどうアプローチしていくか
- 解決案1
    - docker swarmを利用することで異なるdocker engineの間のネットワークを確立することができる
    - 懸念点
        - WSLとホストのswarm設定がうまくできなくて調査中
ショート動画でクイックに知る！ watsonxでマルチモーダルモデルを使いましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52151/2ef7c2ec-3b13-9e30-533c-cfa70721b54e.png)

# はじめに

みなさん、IBM Videoというサイトをご存知でしょうか？
IBMが提供する製品をショート動画でわかりやすくご紹介している動画サイトです。
* スキルアップしたくてもなかなか時間が取れない
* 気になる製品があるけど、マニュアルを読んで理解するのはきつい
* 製品の特徴やメリットをクイックに知りたい

という方には、うってつけの動画を提供するサイトです。
興味のある方はぜひご覧いただければと思います。

# 今回ご紹介する動画へのリンク

[watsonxでマルチモーダルモデルを使いましょう](https://video.ibm.com/recorded/134110490)

# 概要

## マルチモーダルモデルとは
* IBMの「Word Service」は、テキスト、画像、音声、動画など複数のデータ形式を扱うマルチモーダルモデルを提供。
* 大規模言語モデルだけでなく、複雑で直感的なソリューションを提供する点が特徴。

## 活用例とユースケース
* 製造業界：危険予測や異常検知。
* 金融業界：投資判断支援やリスク分析。
* 医療業界や建設業界：画像解析による予測や警告の発出。

## 利用方法

### 方法1：フロントラボを活用する方法

* チャット形式を選択。
* 画像をアップロード。
* 適切なモデルを選択。
* 質問や指示を入力。

### 方法2：APIによる活用

* サンプルアプリを使いAPI経由でモデルを呼び出す。
* 画像をアップロードして具体的な質問を入力すると、必要情報を抽出・回答。

## 高度な機能
* 推測機能：画像にない情報も生成AIが推測して危険性を予測し、警告を出す。
* 応用例：製造や医療分野でのリスク評価や診断補助など。

# まとめ
* マルチモーダルモデルは多様な業界で活用でき、柔軟な運用方法が可能。
* リソースやAPIを活用することで、情報抽出や推測を通じた高度なソリューションが提供可能。

# 参考

watsonxでマルチモーダルモデルを使いましょう

https://video.ibm.com/recorded/134110490

文書や画像を使ったチャット

https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-prompt-data.html?context=wx#chat-images

watsonx.ai での基盤モデルの選択

https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-model-choose.html?context=wx#multimodal

サンプルアプリケーション

https://github.com/wanghaotokyo/Multimodal-Images-Sample
メルカリの「内臓」が直らない

メルカリで無線 LAN ルーターを出品すると、製品情報を選択する画面が表示される。

そして、アンテナ形式の選択画面では「外付け」と「内臓」で選択することになる。

![外付けか内臓か](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566576/e340969f-dc05-53f2-fdad-4688c9feba89.png)

ズームするとこんな感じ。

![内臓.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566576/3284aa7e-4aa6-d725-a7c2-298c4299536c.png)

1 カ月ほど前にサポートセンターに連絡したが、1 カ月経っても直らない。

![サポートセンター回答](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566576/d66e83ea-0885-3c54-fefd-2258c60c4e66.png)

カスタマーサポートからシステムへの報告ラインがないのではないかと思うので、今回 Qiita で報告してみる。
アジャイル未経験者がスクラムの3つの役割を経験して実感した、アジャイルの魅力

この記事は、[AEON Advent Calendar 2024](https://qiita.com/advent-calendar/2024/aeon) シリーズ2の24日目です:santa_tone2:  

こんにちは。イオンスマートテクノロジー株式会社（AST）でバックエンド開発チームに所属している大坂です！
私は標準ECというプロダクトの開発に携わり、主にイオン琉球様のECサイト（[イオン琉球オンラインショップ](https://www.ryukyu.ec.aeon.com/?sectionId=outer)）の開発や保守運用を中心に担当しています！

# はじめに

私はASTに入社する前、別の会社でエンジニアをしており、その頃はウォーターフォール開発を行っていました。
アジャイル開発は未経験で、「短期間でサイクルをまわして開発するやつ」くらいの知識しかありませんでした。
そこから約1年前にASTの標準ECチームにjoinし、まずはスクラムチームのDEVとして開発を経験。その後、体制変更などがあって現在はPO代理（※実際のPOは業務で日々のイベント参加などが難しいので代理）やSM（※実際は名乗れるほどやれてないです...）として、チームや開発の管理、仕様統制、POやお客さんとの連携・調整役などを担当しています。

今回はアジャイル未経験から、スクラムチームの**DEV**、**PO**(代理)、**SM**の3つの役割を経験した私が感じた、**アジャイルの魅力**を**３つ**お伝えしたいと思います！

# ①チームメンバーを頼りやすい（一人で抱え込まなくてよいので、精神的にも楽！）
私がDEVとして参加した時は、開発ベンダーさんで構成されたスクラムチームの中に1人ASTプロパという状況で、チームメンバーのパーソナリティもわからない中ではじめは不安もありました。

しかし、チームメンバーは「ここの実装の仕方わからないので教えてください！」とか「この課題について検討したので意見ください！」などと声をかけるとすぐに寄り添ってくれ、安心して開発できていたのを覚えています。
スプリントのバックログはチーム全体で責任を持ち、協力して完了に導くべきものです。そのため、DEVはバックログの進行を支えるために積極的に相談しあったり、手を貸しあったりする責任があると思っています。

逆に考えると、コミュニケーションが苦手だったり、一人で誰にも邪魔されずに黙々と作業したい人が多いチームにはアジャイルが向かないこともあります。

# ②新たな技術領域に挑戦しやすい
アジャイル開発では、スプリント単位（標準ECでは2週間）で完了できる範囲のバックログを計画するため、一つひとつのタスクが小さな単位に分割されます。
例えば、配送料の機能を開発する場合、最初のスプリントでは管理画面でDBから配送料マスタを取得して表示する機能、次のスプリントではそのマスタを編集・更新できる機能、さらにその次のスプリントで注文時に配送料マスタを取得し、注文金額に適用する機能を実装する、といった具合です（実際にはそこからさらに細かいタスクに分けられる）。

こうして細分化され、毎回のゴールが明確になるため、取り掛かりやすく、今まで触れたことのない技術やプログラミング言語などにチャレンジするハードルが下がります。
タスクを完了できると達成感を得られ、積み重なると自信にもつながっていきます！

# ③急な要望や変更に柔軟に対応できる
これぞやはりアジャイルならではの大きな魅力だと思います。
お客様と要件の調整をする際、「見てみないとイメージがつかない」「使ってみないとわからない」といったケースはやはり出てきます。
また、運用開始して初めて、「この機能を優先して対応してほしい」などの具体的な要望も出てきます。
その際、アジャイルなら「次のスプリントで対応して、間に合えば来月リリースでいこう」といった具合に、フィードバックを迅速に反映させ、素早くカイゼンを進めることができます。

そして、これはお客様からの急な要望や変更に限らず、仕様や設計を固めた後でも、「改めて運用方法を考えてみると、こっちの方が良さそうだ」とか「実装課題を考慮するとこっちに変更した方が良い」など開発を進めるうちに気づいた場合でも、一旦戻って軌道修正しやすいのがアジャイルの大きな魅力です。

# おわりに
アジャイルには多くの魅力がありますが、もちろん課題もあります。例えば、スプリント単位で進捗が把握しやすい一方で、プロジェクト全体のスケジュール感がつかみにくいという点や、チーム全員がアジャイルを意識して進めていけるようになるには時間がかかること、さらにチームメンバーの特性や体制によっては、アジャイルがうまく機能しないこともあります。

ウォーターフォールとアジャイル、どちらが良いかは一概には言えません。プロジェクトの状況や目的によって最適な方法が異なるため、選択は状況次第です。ただ、個人的には約1年アジャイルを実践してみて、その魅力を実感したので、今はアジャイル推しです！

これからもチームで価値あるものを作り、提供し続けられるよう、さらにスクラムの知識を深めつつ、引き続き努力していきたいと思います！

# イオングループで、一緒に働きませんか？

イオングループでは、エンジニアを積極採用中です。少しでもご興味をもった方は、キャリア登録やカジュアル面談登録などもしていただけると嬉しいです。
皆さまとお話できるのを楽しみにしています！

https://engineer-recuruiting.aeon.info/
【TypeScript】ユーザー定義型ガードについて

O'Reilly のプログラミングTypeScriptを読んでいると、
「**ユーザー定義型ガード**」なるものが出てきました。

今まで使用したことがなく気になったため、
今回はこのユーザー定義型ガードについてまとめます。

# ユーザー定義型ガードとは
ユーザー定義型ガードは、開発者が独自に定義できる型チェックの仕組みで、
特定の条件下で変数の型を具体的に絞り込むことができます。

以下の形式で定義します。

```ts
function isType(arg: any): arg is SpecificType {
  // 型チェックのロジック
  return // boolean
}
```
`arg is SpecificType` という個所が重要で、
この関数が `true` を返した場合、`arg` は `SpecificType` として扱われます。

# 使用例
ここではユーザー定義型ガードの使用例をみてみましょう。

## ユーザー権限判断
この例ではユーザーの権限が `admin` `guest` どちらなのかを判断しています。
```ts
interface Admin {
  role: 'admin';
  privileges: string[];
}

interface Guest {
  role: 'guest';
}

type User = Admin | Guest;

function isAdmin(user: User): user is Admin {
  return user.role === 'admin';
}

const user: User = { role: 'admin', privileges: ['manage-users'] };

if (isAdmin(user)) {
  console.log(user.privileges); // Admin型のプロパティにアクセス可能
} else {
  console.log('User is a guest');
}
```

## 通常の型ガードとの比較
通常の型ガードとも比較してみましょう
下記は、型 `Circle`、`Rectangle` を判断する例です。

```ts: 型定義
interface Shape {
  type: string;
}

interface Circle extends Shape {
  type: 'circle';
  radius: number;
}

interface Rectangle extends Shape {
  type: 'rectangle';
  width: number;
  height: number;
}
```

### 通常の型ガード
#### `typeof` を使用した場合
`typeof` はプリミティブ型にしか対応していないため、具体的な型を絞り込むことはできません。

```ts
const isCircle = (shape: Shape): boolean => {
  if (typeof shape === 'circle') {
    // エラー: `typeof`では"circle"のようなカスタム型は判定できない
    return true;
  }
  return false;
};
```

#### `instanceof` を使用した場合
`instanceof` はクラスインスタンスを判定するものですが、ここでは `interface` を使用しているため、`instanceof` は適用できません。

```ts
const isCircle = (shape: Shape): boolean => {
  if (shape instanceof Circle) {
    // エラー: `Circle`はインターフェースのため `instanceof`は使用できない
    return true;
  }
  return false;
};
```
###  ユーザー定義型ガード
以下のように`Circle` と `Rectangle` を判定する関数を作成できます。

```ts
function isCircle(shape: Shape): shape is Circle {
  return shape.type === 'circle' && 'radius' in shape && typeof shape.radius === 'number';
}

function isRectangle(shape: Shape): shape is Rectangle {
  return shape.type === 'rectangle' && 'width' in shape && 'height' in shape;
}

const printShapeInfo = (shape: Shape) => {
  if (isCircle(shape)) {
    console.log(`Circle with radius: ${shape.radius}`);
  } else if (isRectangle(shape)) {
    console.log(`Rectangle with width: ${shape.width}, height: ${shape.height}`);
  } else {
    console.log('Unknown shape');
  }
};

const circle: Circle = { type: 'circle', radius: 5 };
const rectangle: Rectangle = { type: 'rectangle', width: 10, height: 20 };

printShapeInfo(circle); // Circle with radius: 5
printShapeInfo(rectangle); // Rectangle with width: 10, height: 20
```

# おわりに
`typeof` や `instanceof` では、基本型の判定しかできません。
**ユーザー定義型ガード** を使用することで、`type` やその他のプロパティの条件を基に型を判定でき、非常に便利だなと思いました。

それでは。

# 参考文献
https://www.oreilly.co.jp//books/9784873119045/

https://qiita.com/axoloto210/items/dbbb5c608d719393c3bd

https://blog.uhy.ooo/entry/2021-04-09/typescript-is-any-as/
自分にとってのプログラム、自分にとってのキャリアブレイク

キャリアブレイクという人生の中でも大きな決断をしました。実際にやってみると、とても自由であることを感じます。

# 仕事の意味の変化
キャリアブレイクをやってみて、来るべき未来、仕事の概念が変わっても、少なくとも自分は暇を持て余すことはないと思いました。未来は自分が働けなるかもしれません。それは年齢的なものもあれば、コンピューターの進化かもしれません。兎に角ここ数年で仕事の意味は大きく変わる可能性があります。昨日までの延長線上に明日がない――それは人類が何度も経験してきたことです。

# 目的がないとリスクが生じる 
大きな変革が来た時に何をするか、変化に適用出来るか。それは来るべき時がこないと誰にも分かりません。その答えはまだ見えませんが、ひとつ確かなのは、時間を持て余すことが最大のリスクだということです。人には生きる目的が必要で、それがないと生きる意味を見失ってしまいます。多くの人にとって現状の生きる意味は「働くこと」にあると思います。

# それでも未来は分からない
僕の場合、幸運にも「生きる意味」と「働く意味」がそう遠くない位置にあります。25年以上も、この生きがいを失うことなく続けてこれたのは、本当に恵まれていると感じます。会社でプログラムを組んで、家でもプログラムを組んで。この先も続けて行きたいし、出来るのであれば最後まで続けたいと思っています。しかし、AIの進化によってプログラマの未来は予測がつかなくなりつつあります。昨年までは「定年まで仕事があるだろう」と思っていましたが、今はそれも分かりません。

# 高橋留美子の話
高橋留美子さんの話に深い感銘を受けたことがあります。「もしマンガがなくなったらあなたは何をしていますか？」という質問に対して「世の中にマンガという概念がなくても、名前がついていなくても、私はマンガのような何かを描き続けていると思います」。これは本当に奇跡的な言葉だと思いました。そして、おこがましいですが、自分にも通じるものを感じました。プログラムがこの世から消えたとしても、僕は何かしらの形で「プログラミング的なこと」を続けるだろうと思います。それが僕の生き方であり、楽しみだからです。

# 才能を活かせる場所
もう一つ自分が好きな話をします。もし自分が世界で誰よりもある分野の才能を持っていたとして、それに気づかない人生を送っていたら。この妄想に対して僕の叔父が凄いことを言いました。「自分に才能がある状態でそれを活かせる場所に出会わないことはあり得ない。必ず出会う」これは本当にその通りだと思いました。

# 自分の才能
自分にプログラムの才能があるか。それは分かりません。いや、大体分かっています。自分は輝ける程の才能はないと思います。スキルで他人に負けたことは一杯あります。でも、僕からすると自分より凄い後輩が居たとしてもそれがプログラムを辞める理由にはなりません。僕は、プログラムを好きでい続ける才能には自信があります。

# プログラミングという生きがい
自分にとってプログラムを書くことは、出来るからではなく、ただただ楽しいから続けています。専門学校時代、初めて画面に円を描くプログラムを組んだ時の感動は、今でも鮮明に覚えています。世の中にこんな楽しいことがあるんだと心の底から思いました。その感覚は今でも変わらず、これからも続いていくでしょう。

# キャリアブレイクがもたらした新しい視点
キャリアブレイクが自分に何をもたらすのか、まだ分かりません。ただ一つ言えるのは、今までの延長線上ではない未来に繋がっていると思います。無限の可能性がある今、自分は何者でもない存在として、日々勉強し、人と会い、未来を探っています。これからどう生きるか、どのように糧を得ていくか。それが現在の最大の課題です。少しずつ未来の形が見え始めていますが、予測のつかない新しい何かが突然現れる可能性もあります。その変化を楽しみながら、これからの人生を歩んでいきたいと思います。

# キャリアブレイクを勧めるか？
キャリアブレイクは素晴らしい体験です。しかし、人に積極的に勧めるかと問われれば、そうとは言い切れません。働き続ける方が多くのメリットを得られることも事実です。ただ、僕のように一度自分のキャリアを止めてみたいと思う人がいるならば、一歩踏み出してみる価値は十分にあります。それは想像以上に楽しい体験になるかもしれません。そして、もしその選択をしたならば、ぜひ教えてほしいです。その時には、どんな形であれ応援したいと思います。