OmniAICreator/Qiita-1.07M huggingface dataset:
読書記録 #01 Webを支える技術

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2641036/5b7af529-0189-d8ae-102f-40a0357e2e51.png)
最近技術書の積読にハマっています。徐々に消化していかないとなぁと重い腰を上げて読んでみたので、読書感想文を書き記しておこうかなと思います。理解が浅いところもあるので間違ったことが言ってたらぜひ指摘お願いします。
# 購入経緯
またweb技術の歴史や設計指針、RESTに対する理解が甘いと感じていたので手に取ってみたという感じ。
以前から名著だというふうには色々な人から聞いていたため、ずっと興味はあった。
# 価格
[Amazonの購入リンク](https://www.amazon.co.jp/Web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-HTTP%E3%80%81URI%E3%80%81HTML%E3%80%81%E3%81%9D%E3%81%97%E3%81%A6REST-WEB-PRESS-plus/dp/4774142042/ref=sr_1_1?crid=3CB7995ZLJ0RY&dib=eyJ2IjoiMSJ9.keVxzcS97Fi6xZQxNB-wHqQauyEq7irIrFqgR1MvS-VTnWAaX0gx12-CL3eD8gpHvQgd-3jCRuInBqRP5dL0npoL_kEejLIQteZp2MEtWadYeQvwlR9iCu--2AapE4F8K8NY-Q_HUToQoJd8MoGt-rqKPQiDOVbjxwUOrm-ITb-WrhEFL9oRxbwJSk2U8NUFDN4-MbAtyGWc6QQj9HEDICDhCqOZW9215t9bUHa_ylZnh35-PlxzsCOZnZ7a-UxHsg-i0fjFJvLb97S2a0nMjqAtu9P5kcVgrHhPbKj-hh8.vB5XaqFFaRMsLGNyaCHL9oO4_WVTDwvPgf88d5u61-s&dib_tag=se&keywords=web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93&qid=1723020576&sprefix=web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%2Caps%2C161&sr=8-1)
価格は3,000円弱

400ページ近い技術書なので、価格としてはそこまで高いとは感じない。

# 感想
2010年に初版が出てから1回も改訂が入っていないだけあって、内容は古い。（現在の標準であるHTML5やHTTP2.0について全く言及がない（当たり前か））

が、webやHTTPがそもそも何なのか、その仕組みについて非常にわかりやすく平易な言葉でまとめてくれており、技術書にしてはとても読みやすかった。

また本の内容がわかりやすいことに加えて、そもそもwebやHTTP自体が非常に簡潔なプロトコルで動いていることが一貫して書かれていた点は非常に良かった。15年前の内容でもいまだに名著として読まれている理由は、書籍の完成度の高さだけでなく、web自体のシンプルな設計思想が、インターネット世界の絶対的な基盤として長年にわたり変化していないことにもよるのかなぁと感じた。

一方でmicroformatsやAtomなど現在ではあまり聞かないXMLフォーマットについても大きくページを割いて言及されていたのは正直退屈だった。あまりイメージわかないし、「どうせこの知識使うことないんだろうなぁ」というのがどうしても頭の中心から離れなかった。純粋に歴史探訪だと思って読めば面白いと思う。

# 難易度
専門用語の説明や索引が非常に充実しており、他の技術書と比べるとかなり読みやすく感じた。

しかし、ハンズオン等はないため、最低限Webを触ったことがある人でないとそもそもイメージがつかないことが多いと思う。

# メモ
付録でHTTPステータスコードをまとめてくれていてとても面白かった。
（ステータスコードを俯瞰する機会は意外となかったので）

# 記録
API GatewayのプライベートAPIにカスタムドメインが設定できるようになった話

# はじめに
この記事は[アイスタイル Advent Calendar 2024](https://qiita.com/advent-calendar/2024/istyle) 9日目の記事です

こんにちは、oniyanagigです
皆さんは[Amazon API Gateway](https://aws.amazon.com/jp/api-gateway/)使ってますか？
簡単にAPIエンドポイントを作成でき、APIを外部公開する際には非常に便利なサービスだと思います

そんなAPI Gatewayですが、11月21日に以下の大きなアップデートがありました！
[Amazon API Gateway がプライベート REST API のカスタムドメイン名のサポートを開始](https://aws.amazon.com/about-aws/whats-new/2024/11/amazon-api-gateway-custom-domain-name-private-rest-apis/)

本記事ではこのアップデートの内容について確認していきたいと思います

# 概要
改めてアップデート内容を見ていきたいと思います
https://aws.amazon.com/about-aws/whats-new/2024/11/amazon-api-gateway-custom-domain-name-private-rest-apis/
> Amazon API Gateway (APIGW) で、ユーザーにとって使いやすいカスタムのプライベート DNS 名 (private.example.com など) を使用してプライベート REST API を管理し、API を簡単に検出できるようになりました。 

以前まではカスタムドメインはプライベートAPIではサポートされておらず、エッジ最適化APIまたはリージョンAPIでのみ利用できました
プライベートAPIを利用してエンドポイントを提供する場合、API利用者はAPI Gatewayで作成されるデフォルトエンドポイントを指定してアクセスする必要がありました
そのため、既存のAPIをAPI Gateway経由に置き換えるケースにおいて既存のドメインが使えず、API利用者側で宛先変更の対応が必要でした

この問題が、今回のアップデートにより解消されるかたちになります
以下、アップデート前と後での構成の違いについて、ユースケースを踏まえ見てみましょう

# ユースケース

プライベートAPIを利用するケースとしては、システム内においてDirectConnectなどを経由したプライベートな通信があるかと思います
例えば、オンプレに古くからあるサーバからAWS内のサービスにアクセスをすることを考えてみましょう
条件は以下の通りとします
- オンプレ-AWS間はDirectConnect接続
- オンプレ側はAPIの宛先を変更できないため、既存のドメインを使いたい


### アップデート前
[こちらの記事](https://blog.serverworks.co.jp/private-apigateway-custom-domain)を参考にします
(参考もとではプライベートホストゾーンにレコードを登録していますが、DirectConnect接続の場合はパブリックホストゾーンでも問題ない認識です)

![ドメイン名指定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583899/0e3ea32d-90aa-dbe8-7a94-83864814554b.png)

ポイントは、設定したいドメインの証明書をLB側に設定することで、ドメインと証明書の紐づけをLBが行うところです
通常プライベートAPIだけで済ませたいところにLBが必要となり、構成が複雑＆コスト増となります

### アップデート後
具体的な手順は[こちら](https://aws.amazon.com/jp/blogs/compute/implementing-custom-domain-names-for-private-endpoints-with-amazon-api-gateway/)を参考

![ドメイン名指定_アップデート後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3583899/88ac143d-8f14-4c6d-d0b1-6931b6a9396f.png)

ALBが不要になり、構成がシンプルになりました！

# 最後に
以上、API GatewayでプライベートAPIにカスタムドメインが設定できるようになったよ！というアップデートの紹介でした
稚拙な文章ではございますが、今後AWS環境の設計をされる方の参考になれば幸いです
ここまで読んでくださりありがとうございました


# 参考

[API Gateway での REST API のカスタムドメイン名](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/how-to-custom-domains.html)
[プライベート API の呼び出し](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-private-api-test-invoke-url.html)
[Custom domain names for private APIs in API Gateway](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-private-custom-domains.html)
[Implementing custom domain names for private endpoints with Amazon API Gateway](https://aws.amazon.com/jp/blogs/compute/implementing-custom-domain-names-for-private-endpoints-with-amazon-api-gateway/)
[サーバーワークスエンジニアブログ](https://blog.serverworks.co.jp/private-apigateway-custom-domain)
[カスタムドメイン名はプライベートAPIではサポートされない、とはどういうことか](https://zenn.dev/osprey/articles/private-api-does-not-support-custom-domain)
『動いているだけ』を脱却せよ！システム刷新の成功へのステップ

## はじめに  
「動いているだけのシステム」を脱却し、ビジネスに貢献する新たな価値を生むために、レガシーシステムの刷新に挑むエンジニアやプロジェクトチームは少なくありません。しかし、その道のりは簡単ではなく、多くの課題と向き合う必要があります。

私が実際にレガシーシステムを保守・刷新する中で得られた知見やノウハウ、そして直面した苦労話とその解決策を具体的に共有します。同じ課題に直面している方々の参考になれば幸いです。

## 保守・刷新で得られた知見

### 1. **現状を正確に把握することが最優先**  
レガシーシステムでは、まず「全体像を把握する」ことが不可欠です。私が取り組んだプロジェクトでは、以下のステップを踏みました。  

- **現行システムのドキュメント化**: 既存の資料がないことがほとんどなので、このタイミングでできるだけ資料を作成します。ただし、納期が決まっている場合が多いため、どの資料を作成するかの優先順位を明確にすることが重要です。
- **担当者ヒアリング**: 過去の運用経験者やベテランエンジニアから、システムの「暗黙知」を吸収。
- **影響範囲の洗い出し**: 変更が他システムやビジネスに与える影響を調査。これが意外と難しく、影響確認漏れが発生することを前提に進める必要があります。

### 2. **小さく試して大きく動かす**  
刷新時には、大規模なリプレイスではなく段階的な改善を意識しました。  
- **モジュール単位での置き換え**: レガシーと新システムの共存期間を設け、徐々に新システムへ移行。一度のリプレイスは大規模システムでは難しいため、フロントエンド、バックエンド、ツールなど、モジュールを明確に分けて進めることが重要です。
- **カナリアリリースの活用**: 特定のユーザーグループに限定したリリースでリスクを低減。私のプロジェクトでは実施できていませんが、もし可能であれば、不具合発生時の影響を抑える有効な手段となります。
- **CI/CD導入**: テストの自動化を進めてリリース頻度を上げる。

### 3. **チームのモチベーションを高める**  
レガシーシステムの保守や刷新は、特に若手エンジニアにとって魅力的に映らない場合があります。この課題に対して、以下のような取り組みを行いました。
- **プロジェクトの意義を共有**: レガシー刷新の意義を明確にし、全員で共通の目標を持つようにしました。「ユーザーにとっての利便性向上」や「技術的負債の解消」など、チーム全体にとってプラスになる目標を設定しました。
- **成功体験を積む環境の提供**: 小さな改善で成果を出し、チーム全体で共有することでモチベーションを維持しました。
- **リーダーシップの発揮**: メンバー個々の特性を理解し、それぞれの役割に応じた挑戦的な課題を提供するよう意識しました。


## 苦労話とその解決策

### 苦労話1: **仕様がわからない**  
過去のプロジェクトでは、仕様書が存在せず、さらに既存の仕様書が古く、最新の情報が全く反映されていないことが多々ありました。

**解決策:**  
- 実行ログの分析やコードの分割実験を通じて仕様を推測。
- どのシステムにもレジェンド（長年の経験を持つキーパーソン）が存在するので、早めにその人物を特定し、協力を仰ぐことが非常に重要です。

### 苦労話2: **新旧システムの統合**  
刷新の過程で、レガシーシステムと新システムを並行稼働させる必要がありました。

**解決策:**  
- **移行チームと旧システムビジネス案件遂行チームで組織分け**: 新システムへの移行を担当するチームと、旧システムのビジネス案件を継続するチームを分けることで、それぞれの効率を高めました。
- **ビジネス案件で対応した機能も移行時に吸収**: 並行作業の中で、旧システムで追加された機能を計画的に新システムに組み込む運用を実施。

### 苦労話3: **チームの抵抗感**  
特に若手エンジニアにとって、移行プロジェクトはあまりモチベーションが上がる内容ではないことが多いです。

**解決策:**  
- **若手にはビジネス案件を中心に担当**: 直接的に価値を感じやすいビジネス案件を若手エンジニアに担当してもらい、プロジェクトへの関与を促進しました。
- **進捗共有を頻繁に実施**: チーム全体での透明性を高め、成功事例を共有することで、プロジェクトに対する心理的な抵抗を減らしました。



## 今後の展望  
レガシーシステムの刷新は終わりではなく、持続的な改善プロセスの一部です。新システムもいずれレガシー化する可能性があるため、メンテナンスしやすい設計やドキュメントの整備を今後も継続する必要があります。


## まとめ  
「動いているだけ」のシステムから脱却するには、多くの課題と向き合う必要がありますが、その過程で得られる知見や成長は計り知れません。小さな成功体験を積み重ね、チーム全体で共有することで、刷新の壁を乗り越えることが可能です。本記事が、同様の課題に取り組むエンジニアやプロジェクトチームの一助となれば幸いです。
cd コマンド いちいちディレクトリ名入力するのめんどくさくないですか？[シェルの特殊変数]

Linuxコマンド勢の皆さん，cdコマンド使いますか？？

> よく使いますよね？？

例えば，mkdirコマンドを入力し，ディレクトリを作成した後にそのディレクトリに移動する際によく使いますね？その際にcdコマンドを入力する際にディレクトリ名を再び入力するのは面倒くさくないですか？その際に**特殊変数**を使用すると結構簡単にコマンド入力できます．本記事では，シェルの特殊変数について説明し，コマンド入力を楽しくできるようにします！

本記事ではファイル操作等をコマンドで行うので以下の記事を先に読むことをお勧めします．

**ファイル操作コマンドチートシート**

https://qiita.com/JavaLangRuntimeException/items/16f244606a73f7d106e4

:::note infp
**特殊変数とは？**
シェル（BashやZshなど）において特別な意味を持つ，事前に定義された変数のことである.
:::

# 特殊変数の例
実行中のスクリプト名
```bash
$0
```
スクリプトやシェル関数に渡される引数を表す
```
$1, $2, ... 
```
引数の数を表す
```
$# 
```
すべての引数（`$1` `$2` ...）を表す.
```
$@ 
```
すべての引数（`$1 $2 ...`）を表す
```
$* 
```
現在のシェルのプロセスID
```
$$
```
直前のコマンドの終了ステータス（0は成功，非0は失敗）
```
$? 
```
最後に実行したバックグラウンドプロセスのプロセスID.
```
$!
```
直前のコマンドの最後の引数.
```
$_ 
```

使用例:
```bash
echo "スクリプト名: $0"
echo "第1引数: $1"
echo "引数の数: $#"
echo "全引数: $@"
echo "現在のプロセスID: $$"
ls
echo "終了ステータス: $?"
```
今回は`$_`をメインに紹介します．
# ディレクトリ移動を特殊変数で楽しよう

`$_`は直前のコマンドの最後の引数を参照する特殊変数である. これを活用することで,コマンドラインでの作業を効率化できる.
```bash
mkdir test
cd $_
```
上記の例では,$_によってtestディレクトリ名を再入力する必要がない...つまり以下のコマンドを実行したことと同様である．
```
mkdir test
cd test
```

> 私は脳死でcd コマンドで移動できるので多用しています．

# 作成したファイルを楽にvimで開けるようにしよう
touchコマンドで作成したファイルをvimで操作するために以下のコマンドを実行する．
```bash
touch long-file-name.txt
vim $_
```
ここでは長いファイル名を2度入力する手間が省ける...が...別に以下のコマンドでいいので要らない使用例ですねw
```bash
vim long-file-name.txt
```

ただ，このような例なら使いようがある
```
mv ./sample/text1.txt ./sample/text2.txt
vim $_
```
ファイル名を変更した後にそのファイルをvimで編集する時は有用である．

このようにシェルの特殊変数(主に`$_`)を使用すると，コマンド操作が爆速になるのでどんどん使って楽しくターミナルを触ろう！

それではQiitaアドカレ.24企画の今日のクリスマスツリーです．

> 詳しくは[こちら](https://qiita.com/JavaLangRuntimeException/items/1f4a6febf957f522ba45)の記事から

![スクリーンショット 2024-12-08 22.40.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/4a957554-d402-fb2f-a047-b851cf8f79ed.png)
【TS】spliceメソッドの個人メモ

配列の要素を削除・置換してくれるので個人メモ


+ spliceは自身を更新する関数。なので、裏側でimmerを使っているredux-toolkitのreducerの時とか便利。
+ 第1引数：対象の要素インデックス番号
+ 第2引数：対象の要素インデックス番号を起点にした、置換or削除する要素の数。（1なら、指定した要素インデックス番号の要素のみ対象）
+ 第3引数以降：置換後の文字列。未指定の場合は置換ではなく削除処理になる。


```typescript:基本的な置換と削除
const months = ["A", "B", "C", "D"];

// 置換（第3引数に文字列指定あり）
// 0番目の要素を★に置換 → ["★","B","C","D"]
months.splice(0, 1, "★");


// 削除（第3引数が無い）
// 0番目の要素を削除 → ["B","C","D"]
months.splice(0, 1);
```

第１引数にマイナスを指定すれば、後ろから。
```typescript
// 最後の要素を★に置換 → ["A","B","C","★"]
months.splice(-1, 1, "★");
```

第3引数以降も好きな数を指できる。

```typescript
// 1番目から要素2つ分を★に置換 → ["A","★","★","D"]
months.splice(1, 2, "★", "★");

// 第2引数の数値と、第3引数以降の数を合わせないと、要素数が増減する
// ['A', '★', 'D']←要素2つ分置換(第二引数の値）となっているが、
// 第3引数しかないため、元の2番目の要素だったCが削除された
months.splice(1, 2, "★");


// 0番目から要素2つ分を削除 → ["C","D"]
months.splice(0, 2);
```
今年の1年でやったことを振り返る（資格以外）

# 概要
今年（2024年）、１年間でやったことをキャリアの棚卸し兼ねて振り返ります。

# 結論
- **今年一番成長したのはコミュニケーション力**
- 表に立って話してれば大体の人は味方になってくれる
- 強気に出たほうがいいこともある
- 聞かなきゃわからん
- 無理なものは無理

# 振り返り
## 1-3月
#### この時期にやったこと
- 前年から任された現場リーダとして初の山場
    - いきなりリーダになって「何すればいいの？」から始まった
    - WBS作成、ガントチャート作成、進捗管理を始めてやった

#### 大変だったこと
- メンバに仕事を振ること
    - 「人に何かを頼む」がとても苦手なので
    - タスクの切り出しをして止まってしまうところが多かった
    - メンバが自分より経験豊富な方なので、「なにいってんだこいつ」と思われるのが怖かった
- 期日の刈り取りをすること
    - 「これ期日近いですけど進捗どうですか」を言うのがしんどかった


#### 学んだこと
- とりあえず思っていることを言ってみるもん
    - 経験豊富なメンバなので違和感あったら言ってくれる
- 聞いてないことは聞かなきゃわからない
    - 進捗確認も「なんでこいつリーダなのに把握してないん」とか思われるのが怖かった
        - 冷静に考えてみれば自分も上司から進捗聞かれてる
    - 聞いてないことは知らなくて当然

## 4-6月
#### この時期にやったこと
- 設計
- 内部の整理
- 他チーム調整

#### 大変だったこと
- 内部の体制が様々な要因でガタついたこと
    - 上司の稼働が落ちたためコミュニケーションを取りづらくなった
    - 自身も稼働時間の調整などがあり、作業量の調整や効率化に取り組んだ
- 未整理だった諸々を整理した
    - 自チームが管理すべき資産や資料など一覧化
    - チームメンバにヒアリングして取りまとめ

#### 学んだこと
- 体制がガタついても仕事は進めないといけない
- 管理資料の必要性
    - これに関しては「今までなかったのがおかしいよ」



## 7-9月
#### この時期にやったこと
- 年末の山場に備えた準備期間
- この期間に解決しないといけないタスクが多すぎてパンク気味だった
    - 実施がまるまる抜けていた大きな作業が判明してその対応に追われていた
- AWS SAA受験

#### 大変だったこと
- 実施が抜けていた作業の対応
    - 環境0.5個分作り忘れてたレベルの作業量
    - 他チームと調整して対応しないといけなかった
        - 相手チームにも緊急で優先タスクを依頼することになり迷惑をかけた

#### 学んだこと
- 全体スケジュールを抑える
    - どの作業をしないとどんなリスクがあるのか
    - そのリスクはいつ顕在化するのか
     ⇒を把握しておけば、逆線でいつ対応する必要があるのかがわかる
- タスクの完了日を明確にしよう
    - 「〇月頃まで」とか「（未定）」とかにするとほかのタスクを優先してしまいやすい
    - いつからやればいいのかもわからないので着手もしづらい

# 10-12月
#### この時期にやったこと
- 環境の構築
- PM試験受験

#### 大変だったこと
- 環境を構築したときのトラブル頻発とその対応
    - 製品仕様や他チームの要件の把握不足
    - 対応のために上位層まで巻き込んで調整かけたりでメンタルに来た
        - ~~そんで内部からも詰められた~~
- 超勤がかさむ中での試験勉強
    - 眠気と戦いながら通勤中と土日に勉強をやり切ること

#### 学んだこと
- リスクを把握することが大切
    - 顕在化してからでは遅い
    - リスクを把握するためには自ら情報を取りにいかなくてはならない
    - 逆にこっちからは出せる情報を出していく姿勢が大切
- 超勤80時間近くが２か月続くとメンタルは壊れる
    - うちの上司のような働き方は出来ない
    - 逆に１か月なら全然大丈夫
    - 繁忙期抜けた瞬間思いっきり風邪ひいた
- 試験勉強が息抜きのように感じられた

# 感想
- 1年通して、チーム内外と話している時間が一番長かった
    - 新卒のころ「エンジニアは会話が出来る人であることが一番大切」と言われた理由を痛感した
    - プロジェクトの上位層向けに説明する機会もあった
        - 話すのが上手いと褒められた
            - 伝えたいことと説明の目的を明確にしてから説明できたからか？
- 頑張った！
    - 元上司から「本当に頑張ってるから胸を張っていいし自己肯定感高く持ってくれ」と言われた
        - この人からは配属当初散々言われたのでやり返してやった気持ちになれた
    - プロジェクトの山場のイベントを乗り越えたのは自信になる
PythonでPDFをWordに変換

今日のデジタル時代において、文書をあるフォーマットから別のフォーマットに変換する必要性はかつてないほど高まっています。最も一般的な変換の1つはPDFからWordへの変換で、Pythonはこのプロセスを自動化する強力なツールを提供します。この記事では、サードパーティのライブラリを使って**PythonでPDFをWordに変換する**方法を説明します。

## PDFからWordへの変換のためのPythonライブラリ
この変換にはサードパーティのPythonライブラリ[**Spire.PDF for Python**](https://www.e-iceblue.com/Introduce/pdf-for-python.html)が必要です。以下のpipコマンドで直接インストールできます。
> pip install Spire.PDF

## PythonでPDFをWordに変換する方法
以下はPDFをWordに変換する手順です：
1. **`PdfDocument`** クラスの **`LoadFromFile()`** メソッドを通してPDFファイルをロードします。
1. **`SaveToFile(filename,FileFormat.DOC)`** メソッドを使用してPDFファイルを.doc形式で保存します。
1. **`SaveToFile(filename, FileFormat.DOCX)`** メソッドを使用して、PDFファイルを.docx形式で保存します。
1. PDFファイルを閉じます。

>**Pythonコード:**
```python
from spire.pdf import PdfDocument
from spire.pdf import FileFormat

# PDFファイルを読み込む
pdf = PdfDocument()
pdf.LoadFromFile("InputR.pdf")

# PDFファイルをDocファイルに変換する
pdf.SaveToFile("PdfToDoc.doc", FileFormat.DOC)

# PDFファイルをDocxファイルに変換する
pdf.SaveToFile("PdfToDocx.docx", FileFormat.DOCX)

# PDFファイルを閉じる
pdf.Close()
```

**出力：**
![PDF-WordR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/62d88937-e2ca-424f-1589-7c260b94dc97.png)
* * *
上記の簡単なコードによって、PDFファイルを編集可能なWord文書に簡単に変換することができます。それ以外にも、Python PDFライブラリはPDFからHTMLへの変換、PDFからExcelへの変換、PDFから画像への変換、PDFからTIFFへの変換などもサポートしています。

https://www.e-iceblue.com/Tutorials/Python/Spire.PDF-for-Python/Program-Guide/Spire.PDF-for-Python-Program-Guide-Content.html
エンジニアと共に進めるデザイン

突然ですが、ライブペインティングってありますよね？

![ari-he-MamWbmmaylY-unsplash.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632518/5c29e36e-bb82-f35e-7348-c0f5c99c13d8.jpeg)


観客が見ている前で、ペインティングの過程を見せながら完成させるパフォーマンスです。

実は最近、これと同じように、開発チームのメンバー全員がいるところでデザインの過程を公開し、エンジニアから意見をもらいながらその場でデザインを完成させる、という方法を試してみました（名付けてライブデザイン？）。

要するに、**エンジニアとのペアデザイン**です。

これがとても良かったので、ぜひ紹介させてください。

# なぜ、エンジニアとペアデザインを行ったのか？
普段デザインをする中で、私自身は以下のような課題に直面していました。

😔 デザイン段階でエンジニアリング観点が抜けていて、デザイン決定後に見積もってみたら想定より開発期間が長くなった
😔 技術的難易度が高いことがデザイン決定後にわかり、再検討が発生した
😔 エンジニアの視点から解決策を引き出しづらい

小まめにエンジニアから意見をもらうよう心がけていましたが、これらの問題を解決することはできませんでした。そんな中、エンジニアから、

**🧑‍💻 Eng**「デザイン詰められてなくてもいいので、ゼロから一緒に考えてみましょう」

と言われ、

**🧑‍🎨 私** 「エンジニアと一緒にデザインを作ってしまえば良さそう。そうだ、デザインの過程を全部共有しよう！」

と思いつきました。

そしてやってみると、次のような結果に繋がりました。

😁 技術的な課題や論点を早期に発見でき、デザインや仕様に即フィードバックしてブラッシュアップできる(手戻りが激減した)
😁 PdMに対して、デザインパターンを実装工数（開発期間）の当たりをつけた状態で提案でき、意思決定してもらいやすくなった
😁 「なぜこのデザインなのか？」の説明コストが節約された
😁 (+α)デザイナーもエンジニアもお互いの専門性や勘所を学び合えている

それでは、具体的にどうやっているのかを説明します。

# やり方

全部で3ステップあります。

### 1. ゴールと作業手順を書き出す
その日のデザイン作業のゴール（完了条件）と作業手順を書きます。

:::note info
具体例

**今日のゴール**
デザインの改善案について、パターンの洗い出しと提案を整理する

**作業ステップ**
1. 前提の確認（ユーザーの課題、要件など）
1. デザインパターンの洗い出し
    1. 他社のUIリファレンス
    1. ブレスト
1. 各パターンのデザイン制作
1. 各パターンのメリデメ整理
1. 提案するデザイン、そのロジックを詰める
:::

### 2. 会場を用意する
弊社はGatherを導入しているので、そこで行なっています。
基本的にエンジニアが常駐しているので、みんなが集まっているところに行って
「これからデザイン作業を公開するので、ぜひコメントやアイデアください！」と呼びかけます。

https://ja.gather.town/

### 3. ペアデザイン（ライブデザイン）
下記の2つが1画面に収まるように配置してから画面共有し、デザイン作業を開始します。

1. 今日のゴールと作業手順
1. デザインツール（Figma）

![SCR-20241205-ohai.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632518/76501206-bb02-6d76-2616-0d8704decd24.png)

ポイントは、**エンジニアにゴールと手順が見えるようにすること**、**考えていることを発話しながらデザインを作ること**です。
そうすることで「作業の目的は何か？」「今全体のどの工程をやっているのか？」「なぜこのデザインにしているのか？」「何を考えているのか？」が周囲に伝わり、コメントしてもらいやすくなります。実際、こんなやり取りがありました。

**🧑‍🎨 Des**「既存のアカウント画面と同様に、ユーザーが情報を入力できるようにフォームをここに置いて...と」

**🧑‍💻 Eng**「ん？ここの情報は既存の画面と違って、ユーザーに入力させなくてもDBから取って来れるのでフォーム要らないのでは？」

**🧑‍🎨 Des**「そうか！ここはフォームではなく、シンプルに画面に表示すればいいですね」（余計な検討を1つしなくて済んだな）

このように意見をタイムリーにデザインに反映することで、手戻りを防ぎ、デザインや仕様を決めるまでのリードタイムを短縮できます。

「このデザインは工数かかりすぎないか？」「これ以上良い案が浮かばない」など、少しでも迷ったりわかんないことが出てきたりしたら、すぐに確認したり、アイデアを求めましょう！

ゴールの達成までに長いときは2時間くらいかかることもあります。
しかし、手戻りや工数が膨れることが減ると考えると、トータルでは時間を短縮できています。

# さいごに
この記事ではエンジニアとのペアデザインについて紹介しました。

全員の時間を同期的に使うため、フロー効率が高く、リソース効率が低い方法です。
あらゆる状況でこの方法が最適とは限りませんが、プロダクトのクオリティやスピードを全員で向上させるには有効な方法だと思います！

それでは、今年もラスト1ヶ月、最後まで良いプロダクトを作るために頑張っていきましょう！

Happy Merry Christmas！
Playwright の VS Code プラグイン では Playwright のモジュール内にステップインできない

# プラグインを利用したデバッグの制約
VSCode での Playwright によるテスト開発をサポートするプラグイン [Playwright Test for VSCode](https://marketplace.visualstudio.com/items?itemName=ms-playwright.playwright) では、デバッグ実行時に Playwright 内部のソースへのステップインができない。

あらかじめ Playwright 内部で実行されるコードが分かっている場合、ブレークポイントを設定すればステップインされるが、設定していない場合はスキップされてしまう。テストコードそのもののデバッグだけ実施したい場合は特に問題はないが、Playwright 内部の動作を確認したい場合には不便である。

実際、Playwright の API に対して vscode の `Go` 機能で `Go to Definition` や `Go to Implementation` を実行しても型定義の `types.d.ts` に飛んでしまう。また `Go to Source Definition` を実行しても、*No source definitions found.* とエラーが出て実装に飛ぶことはできない。

※自作のモジュールであれば `tsconfig.json` で `declarationMap: true` を設定して公開すれば `Go to Source Definition` で実装に飛ぶことができる。

そこで VS Code の デバッグ構成ファイル `launch.json` を別途定義し、node_modules 内のサードパーティモジュールの実装にステップインできるようにする。

# launch.json の作成
`.vscode/launch.json` の定義は以下の通り。

```json: ./vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Playwright tests",
      "console": "integratedTerminal",
      "skipFiles": [
        "<node_internals>/**",
      ],
      "runtimeExecutable": "npx",
      "runtimeArgs": ["playwright", "test", "--debug", "${fileBasename}"]
    }
  ]
}
```

気にすべき設定は次の3点である。必要に応じて変更すること。

- `skipFiles`
    - デバッグ実行時にステップ実行したくないソースコードを指定する。
    - [glob パターン](https://code.visualstudio.com/docs/editor/glob-patterns)でパスを指定できる。
    - Node.js の組み込みモジュール は `<node_internals>/**/*.js` のように指定することでスキップできる。（この例ではすべてをスキップする）
    - node_modules のパスは `${workspaceFolder}/node_modules` で指定する。例えば、playwright モジュールだけを **スキップしない** 場合は以下のように設定する。
      ```json
      "skipFiles": [
          "${workspaceFolder}/node_modules/**/*.js",
          "!${workspaceFolder}/node_modules/playwright/**/*.js",
      ]
      ```
- `runtimeExecutable`
    - デバッグ実行時の実行ファイルを指定する。
    - 今回は playwright を実行したいため `npx` を指定する。
- `runtimeArgs`
    - デバッグ実行時の `runtimeExecutable` に与える引数を配列形式で指定する。
    - 今回は「playwright でのテスト実行をデバッグする: `playwright test`」「[デバッグモード](https://playwright.dev/docs/debug#run-in-debug-mode-1)で実行する: `--debug`」「現在開いているファイルを対象にする: `${fileBaseName}`」を指定する。

# 実行
デバッグ対象のソースコードを開き、Playwright API を使っている箇所にブレークポイントを設定する。

左サイドバーから Run and Debug パネルを開きパネル上部の再生ボタンを押すか、 `F5` を押すなどしてデバッグ実行する。ブレークポイントで止まったら、ステップイン実行すると Playwright 内部のソースに飛ぶはずである。

:::note warn
Playwright Test for VS Code プラグイン の デバッグ実行とは異なる。
:::


## 実行例
ブレークポイントを設定し、デバッグ実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229637/42ca7ea1-7a88-1e08-0150-2d3e93d06e34.png)

page.goto() の実装に飛ぶ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229637/026b3742-46f0-fa2b-e6bb-67242dcf152e.png)

以上
経路の負荷分散と冗長化について勉強してみた

# 1.はじめに
先日はルーティングプロトコルについて復習しましたが、OSPFについて調べる中で、経路の負荷分散の話が少し出てきました。
せっかくなので、本日は経路の負荷分散と冗長化について勉強したいと思います。

# 2.経路の負荷分散について
**【2-1】概要**
経路を複数用意することによって、使用する経路を分散させることができ、１つの回線にかかる負荷を軽減させることが出来ます。
<br>

**【2-2】等コストロードバランシング(ECMP機能)**
ダイナミックルーティングでは、各ルーティングプロトコルによってコスト(メトリック)を算出し、一番コストのかからない経路を最適経路としてルーティングテーブルに書き出します。

この時、もしも最小コストで宛先に到達できる経路が複数あった場合は、それら複数の経路で通信を分散させます。
これを等コストロードバランシング(であったり、ECMP:Equal Cost Multi Path)と言います。
(CiscoやPaloAltoのナレッジベース等にて、"ECMP機能で使用できる分散経路は最大4つ"との記載をみつけましたが、あくまでデフォルト値なのか、全ての機器でこの値なのかなど、上限値の詳細はよく分かりませんでした)

以下の図は、ルーティングプロトコルにRIPを使用している場合の等コストロードバランシングの例です。
172.16.1.0/24内のホストから172.16.3.0/24内のホストに通信を行う際、等コスト(RIPの場合はホップ数)の経路が緑の回線と青の回線を通過する2パターンありますので、通信は2つの経路で分散されます。
OSPFやEIGRPでも考え方は同じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950373/ab5d68a1-0ea9-9caa-6ec7-73feb5830683.png)
<br>

**【2-3】不等コストロードバランシング**
同一の宛先への経路が複数あったとして、それらが等しいコストではなかった場合でも、以下の設定をすることによって複数の経路を負荷分散として使用する事ができます。
これを不等コストロードバランシングと言い、EIGRPがこれをサポートしています。

<設定>
「#variance <係数>」
[最小コストの値×<係数>]で算出された値よりもコストが低い経路を負荷分散経路として使用します。
<br>

**【2-4】スタティックルートによるロードバランシング**
先々日の記事で復習した通り、経路の優先順位は[ロンゲストマッチ⇒AD⇒コスト(メトリック)]の順に優先されます。
そのため、同じ宛先(サブネットマスクまで同じ)に関するスタティックルートを手動で複数登録することによっても負荷分散が実現できます。
<br>

# 3.経路の冗長化について
**【3-1】概要**
ルーティングテーブルにバックアップルート(必要となる時が来るまで適用されずに待機している経路)を用意することによって、平常時に使用している経路上で障害が発生した際に、用意していたバックアップルートへ自動で経路を切り替えることができます。
障害発生時も通信を継続出来るので、ネットワークの可用性を高めるのに必要な構成となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950373/166f95b4-fbbb-a353-4156-e00b39b2d20b.png)
<br>

**【3-2】経路の冗長化を実現する方法**
本項目では、今までに学習した知識を使用して冗長化する方法を3つ見ていきたいと思います。

**①ロンゲストマッチによる冗長化**
ルーティングテーブルにサブネットマスクの異なる経路を設定することによって、各経路に優先順位をつける方法です。

平常時はロンゲストマッチのルールに従ってRT2を経由する経路が選ばれます。
RT2を経由する方の経路上で障害が発生した際は、RT3を経由する経路が採用されます。
(※図のルーティングテーブル内容はかなり省略しています)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950373/d7c39b60-3ee2-9c9a-ed06-385859e15546.png)


**②AD値による冗長化**
基本的な考え方は①と同じです。
今回は宛先ルートのプレフィックス長は同一なので、AD値の小さい方(手動で設定した方)の経路情報を信頼度が高いものとして平常時に使用します。
RT2経由の経路上で障害が発生した際に、OSPFで学習した方の経路を使用することとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950373/49125c97-9c6d-9d04-2961-c041580704fd.png)


**③メトリックによる冗長化**
これは前回の記事の内容と被りますが、同じルーティングプロトコルによって書き出された経路はメトリックによって優先度が比較されます。
それを利用して優先度をつける方法です。
以下の図では、コストの低い経路が平常時に採用され、そちらで障害が発生した場合にもう一方の経路へ切り替わります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950373/30192ca6-c66f-3182-a777-046116c210b6.png)


# おわり
Rakeコマンドとは

>rakeコマンドはmakeコマンド風のタスクを実行するためのタスクランナーで、実行する処理をRakeタスクと呼びます。主にリリース作業などの提携処理をRakeタスクとして定義します。
 rakeコマンドではタスクの実行の他に現在実行可能なRakeタスクによりDBの管理を行ったり独自のRakeタスクを作成する場合があるため、簡単な使い方は覚えておきましょう。
>
>...
>現在のrailsではRakeタスクもrailsコマンドから実行できるようになったため直接rakeコマンドを使う頻度は少なくなりました。

 https://gihyo.jp/book/2020/978-4-297-11462-6

>`RakeはRubyで作られているビルドツール`です。Mac/Linux系の環境で昔からよく使われている`ビルドツールにMakeがありますが、RakeはそのRuby版`だと言えます。ただし、もともとはビルドツールとして開発されたRakeですが、実際にはビルドに限らず、「何かしらのまとまった処理（＝タスク）」を簡単に実行するためのツールとして使われたことも多いです。

https://gihyo.jp/book/2017/978-4-7741-9397-7

# Rakeコマンドで実行する
```hello.rb -> Rakefile
task :hello_world do
        puts 'Hello, world'
end
```
### rakefile, Rakefile, rakefile.rb, Rakefile.rbを探します
```rb
***********@****** % vim hello.rb
***********@******  % rake hello.rb
rake aborted!
No Rakefile found (looking for: rakefile, Rakefile, rakefile.rb, Rakefile.rb)

(See full trace by running task with --trace)
```

```rb
***********@******  % mv hello.rb Rakefile
***********@******  % ls
Rakefile	
***********@******  % rake hello_world
Hello, world
```
SoundMakerでファイル操作をせずにwavバイナリを入手する方法

どうもTNTSuperManです。
ゲームエンジンを作る都合でファミコンみたいな音声を作るため
SoundMakerを使いましたが、ファイル操作が必要だと速度が遅くなることを危惧したため
この方法を見つけました。

:::note info
SoundMakerはMITランセンス下に提供されています。

https://github.com/AutumnSky1010/SoundMaker

:::

SoundMakerに関する詳細は以下です。

https://qiita.com/DTB_AutumnSky/items/8d78520567211d9a8dd2

## 1.逆コンパイル
ファイルを書き込むWaveWriterの内容を.NETの逆コンパイルで見ました。
以下はSoundMakerのWaveWriterの逆コンパイル内容です。
```csharp
public class WaveWriter
{
    private List<IChunk> Chunks { get; } = new List<IChunk>(3);


    public WaveWriter(FormatChunk format, SoundWaveChunk soundWave)
    {
        Chunks.Add(new RIFFChunk(soundWave.Size + 36));
        Chunks.Add(format);
        Chunks.Add(soundWave);
    }

    public void Write(string path)
    {
        using FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write);
        Write(stream);
    }

    public void Write(Stream stream)
    {
        BinaryWriter binaryWriter = new BinaryWriter(stream);
        foreach (IChunk chunk in Chunks)
        {
            binaryWriter.Write(chunk.GetBytes());
        }
    }
}
```
はい、Streamを使って書き込みしているのです。
となれば皆さんお気づきでしょう。
**M e m o r y S t r e a m を 使 う の で す ！**
## 2.MemoryStreamを使う
```csharp
// ~ WaveWriterが登場するまで省略 ~

var stream = new MemoryStream();
var writer = new SoundMaker.WaveFile.WaveWriter(wformat, sound);
writer.Write(stream);
byte[] wavebinary = stream.ToArray();
```
以上です。
拡張 Lightning ユーザー インターフェース

**使っているクラウドなどの小ネタ Advent Calendar 2024 21日目**


何気に以下のモジュールを見つけてインタフェースが変わっている（変えられる）ことに気付きました。
社内では色が薄いということで大不評なんですね。昔に比べたらだいぶコントラストは高くなったと思うのですが...

+ [Salesforce 特にLightning Experienceの見た目を変えたいけど...](https://qiita.com/Keiji_otsubo/items/3d4547254aa42fb9fb2f)

# このモジュール

+ [Discover the New UI](https://trailhead.salesforce.com/content/learn/modules/enhanced-lightning-ui-quick-look/discover-enhanced-lightning-ui)

以下のポイントが気になります。


+ みやすいフォント
また、文字とフォントのスケールを変更することで読みやすさも向上しました。これらの改善により、ユーザーに役立つデータと分析情報を最前面に表示できるようになりました。

+ より高いコントラストの色
UI の色はSalesforce のカラーシステムに基づいており、よりクリーンで明るく、コントラストの高い色を選択できます。更新されたアクセスしやすい色彩理論により、革新的な方法でコントラストが向上します。

# 新しいUIの操作

新しい UI は、2024 年 6 月 5 日に新規および既存の組織に展開を開始しました。可用性の詳細については、「[拡張 Lightning ユーザー インターフェース](https://help.salesforce.com/s/articleView?id=sf.customize_ui_enhancedlex.htm&type=5)」の記事をお読みください。

新しいデザインが有効になっている新規または既存の組織で作業している場合は、ぜひ新しいエクスペリエンスをお楽しみください。新しいデザインをオフにして、元の Lightning Design System UI に戻す必要がある場合は、次の手順に従ってください。

ヘルプを見る限りはDev 環境でもプレイグランド、本番環境（残念ながらエディションが対応してない）でも設定しないと変わらないようです。

+ [テクサポ 日本](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007cmHNh)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/59365b90-ce81-bd45-c73f-3403a2abd155.png)
[CAIレシピ] ディシジョンステップによるによる分岐処理

## はじめに

ディシジョン(`判断`)ステップを利用すると、条件に応じた分岐処理を実装できます(`プログラミングにおけるIF文`)。この記事では、ディシジョンステップを利用した分岐処理の動作を確認します。

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


- [はじめてCAIを使う際に](https://qiita.com/shunsuzu/private/12b8dbd08a30efa0003a)
- [プロセスの作成と実行(匿名認証と基本認証)](https://qiita.com/shunsuzu/private/01d91caedb92bd7781ea)
- [割り当てステップと、各種変数フィールドの利用](https://qiita.com/shunsuzu/private/fae696539cd245828848)



## ディシジョンステップ利用時の動作

### CAIプロセスの作成

次の手順では、入力フィールドが5より大きい数字が否かを判断して出力フィールドの値を変更するCAIプロセスを実装しています。

1. CAIプロセスを次の設定で作成します。
    - 名前を __recipe-pca-stepDecision__ とする
    - __匿名アクセス__ を許可する
    - __クラウドサーバー__ にデプロイする

1. 入力フィールド __input__ を __タイプ=整数型__ として定義します。
1. 出力フィールド __output__ を __タイプ=テキスト__ として定義します。

1. CAIプロセスが次の順に実行されるように各種ステップを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/e4cf328a-56b5-5ea4-f8b8-f6b9caf541f4.png)

1. ディシジョンステップを選択して __フィールド__ として 入力フィールド __input__ を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/c992c421-2fb6-b05f-7e07-700d5c5792f6.png)
__条件=次より大きい__、__値=5__ を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/da1850b0-79a1-e1c6-8df0-dd64eca94ba3.png)

1. 割り当てステップを選択して、フィールド __output__ に __コンテンツとして__ として`input value is greater than 5`を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/26376acc-5bef-8c2c-d1fb-80265bd2336e.png)

1. 割り当てステップを選択して、フィールド __output__ に __コンテンツとして__ として`input value is less than or equal to 5`を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074553/32974593-4b30-f3df-f8c1-c9ec6a791bf7.png)

### CAIプロセスの実行

以下、curlコマンドを例とした動作確認結果です。入力フィールドの値によって、出力フィールドの値が変わる動作を確認できます。

```:curlコマンドと実行結果(入力フィールドの値を5とした場合)
// curl コマンド
curl https://<IICS・CAIサーバー>/active-bpel/public/rt/<Org ID>/recipe-pca-stepDecision \
-H 'Content-Type: application/json' \
-d '{"input": 5}'

// 実行結果(見やすいように整形しています)
{
"output":"input value is less than or equal to 5"
}
```

```:curlコマンドと実行結果(入力フィールドの値を6とした場合)
// curl コマンド
curl https://<IICS・CAIサーバー>/active-bpel/public/rt/<Org ID>/recipe-pca-stepDecision \
-H 'Content-Type: application/json' \
-d '{"input": 6}'

// 実行結果(見やすいように整形しています)
{
"output":"input value is greater than 5"
}
```

## 参照

- [Qiita - IICS CAIの実装レシピ - マスターページ](https://qiita.com/shunsuzu/private/3d1971ef6e3b993516aa)
Windows向け関数電卓ソフトの紹介

# Windowsで使用することが出来る関数電卓ソフトを開発しました

## はじめに

初めまして。
個人事業主としてWindows向け関数電卓ソフトの開発を行った、システムエンジニアの<b>techem_it</b>と申します。
今回は先述した私が開発したWindows向け関数電卓ソフト<b>SCalc</b>の紹介記事を投稿します。
↓販売リンク↓
https://coconala.com/services/3510476

↓HP（Googleサイト）↓
https://sites.google.com/view/techeminfo/home

今回紹介する関数電卓ソフトは、私がまだ1企業でシステムエンジニアとしてシステムの開発をしていたころに思ったことをきっかけに開発を行いました。
下記に「どうして開発に至ったか」と「今後なにをしていきたいか」を書こうと思います。

1. 開発の背景
私は、個人事業主として開業する前、関東のIT企業でシステムエンジニアとして勤務していました。そこでは計算ソフトの開発に携わることが多かったのですが、計算部分の試験に課題を感じていました。仕様書には数式が記載されているのに、試験ではExcel関数を使うなど、現場で乖離が生じていたからです。
また、テスト項目の漏れや期待結果の誤りも頻発しており、その一因は数学や工学の知識不足にあったと考えています。私は化学を専攻していたため、計算の実装や試験を担当することが多く、その中で感じた課題がきっかけとなりました。

2. ソフト開発の動機
従来はC社の関数電卓を使用していましたが、エビデンスとしての記録が困難でした。代わりにWindowsの電卓やExcelを使用していましたが、利便性と証拠の見やすさを両立できる専用ソフトが必要だと痛感しました。そこで、今回のソフトを開発するに至ったのです。

1. 関数電卓ソフト「SCalc」の紹介
![mainWindow.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953334/7c96c029-c23d-9a46-c5e5-a07db779bd26.jpeg)
上記に掲載している画像が実際のソフトのメイン画面です。
画面左側が電卓部分、画面右側がボタンで機能を切り分けていますが「計算履歴」「カスタム関数」「定数」の機能となっております。
![custom.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953334/f7ebaa83-72ba-4b13-6153-8e96ba3155e6.jpeg)
これはカスタム関数機能です。
ユーザに登録いただいた関数を使用することが出来ます。
![constant.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3953334/91fd000e-0609-9999-e593-5d473cfc916b.jpeg)
最後にこれが定数機能です。
プランク定数や光速などの定数を登録しておけば、わざわざ入力する手間が省けます。
私が開発した関数電卓は、日常的な計算に加え、専門的な数学的、物理的な計算にも対応しています。例えば、複雑な関数計算、履歴保存機能、そしてカスタム関数の登録機能を備えており、ユーザーが独自の計算式を手軽に利用できるよう設計されています。また、他ユーザーとの連携機能もあり、業務での利用にも適しています。
本ソフトでは紹介したカスタム関数と定数の情報を他ユーザと連携することが可能です。
今は減ったかもしれませんが、在宅ワークなどで他ユーザと画面を見ながら式の連係がしにくくなったため、そういったユーザの方には便利に使用いただけると考えています。

最後に、Bloggerの方で機能の紹介をしているので、興味がおありの方はぜひ見ていただけますと嬉しく思います。

↓機能紹介ブログ↓
https://chem-it.blogspot.com/

↓販売リンク↓
https://coconala.com/services/3510476

↓HP（Googleサイト）↓
https://sites.google.com/view/techeminfo/home
ワイルドカードと正規表現の違い、言えますか？

# はじめに

パターンマッチング。文字列処理において非常に重要な技術ですが、皆さんは、正規表現（Regular Expressions）とワイルドカード（Wildcard）の違いとそれぞれについて答えられますか？

自身の中で混同していたので調べてまとめてみました。そんな記事です。

# 正規表現 (Regular Expressions)

## 概要
正規表現は、文字列のパターンを高度かつ柔軟に検索・マッチングするための強力なツールです。
プログラミング、テキスト処理、データ検証など、幅広い分野で活用されています。

## 基本文法と主な特殊文字

| 文字 | 意味 | 例 | マッチする文字列 |
|------|------|-----|-----------------|
| `.`  | 任意の1文字 | `a.c` | `abc`, `adc`, `a1c` |
| `*`  | 0回以上の繰り返し | `ab*c` | `ac`, `abc`, `abbc` |
| `+`  | 1回以上の繰り返し | `ab+c` | `abc`, `abbc`, `abbbc` |
| `?`  | 0回か1回 | `colou?r` | `color`, `colour` |
| `^`  | 行の先頭 | `^Start` | "Start of line" |
| `$`  | 行の末尾 | `end$` | "This is the end" |
| `[]` | 文字クラス | `[aeiou]` | `a`, `e`, `i`, `o`, `u` |
| `[^]`| 否定の文字クラス | `[^0-9]` | 数字以外の文字 |
| `{n}`  | ちょうどn回の繰り返し | `a{3}` | `aaa` | 指定された回数だけ繰り返す |
| `{n,}`  | n回以上の繰り返し | `a{2,}` | `aa`, `aaa`, `aaaa` | 最小n回の繰り返し |
| `{n,m}`  | n回からm回の繰り返し | `a{2,4}` | `aa`, `aaa`, `aaaa` | 最小n回、最大m回の繰り返し |
| `\d`  | 数字 | `\d{3}` | `123`, `456` | 0-9の数字 |
| `\w`  | 単語文字 | `\w+` | `hello`, `123_abc` | 英数字とアンダースコア |
| `\s`  | 空白文字 | `hello\s world` | `hello world`, `hello  world` | スペース、タブ、改行 |
| `\D`  | 非数字 | `\D+` | `abc`, `Hello` | 数字以外の文字 |
| `\W`  | 非単語文字 | `\W+` | `!@#`, ` ` | 英数字とアンダースコア以外 |
| `\S`  | 非空白文字 | `\S+` | `hello`, `123` | 空白文字以外 |
| `()`  | グループ化 | `(ab)+` | `ab`, `abab`, `ababab` | 部分文字列をグループ化 |
| `\|`   | 選択（OR） | `cat\|dog` | `cat`, `dog` | 複数の選択肢 |

## 使用例

### メールアドレスのバリデーション
```regex
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
```

### 電話番号のバリデーション
```regex
^\+?(\d{10,14})$
```

## 主な用途

- データ検証（メール、電話番号、郵便番号など）
- テキスト検索と置換
- スクレイピングとデータ抽出
- ログ解析

など

:::note info
## プログラミング言語での使用
### Python
- `re`モジュールを使用
- データ検証、文字列操作などに広く利用
- 複雑な文字列処理に最適

### その他の言語
- JavaScript: `match()`, `test()` メソッド
- Java: `Pattern`, `Matcher` クラス
- PHP: `preg_match()`, `preg_replace()`
- Ruby: 言語組み込みの正規表現サポート

## コマンドライン・シェルでの使用
- `grep`: テキスト検索
- `sed`: ストリーム編集
- `awk`: テキスト処理
- `find`: ファイル検索
:::

# ワイルドカード (Wildcard)

## 概要
ワイルドカードは、簡単で直感的なパターンマッチング方法です。
主にファイル管理やシェルコマンドで使用されます。

## 主な特殊文字

| 文字 | 意味 | 例 | マッチする文字列 |
|------|------|-----|-----------------|
| `*`  | 任意の文字列（0文字以上） | `*.txt` | `report.txt`, `data.txt` |
| `?`  | 任意の1文字 | `file?.txt` | `file1.txt`, `fileA.txt` |
| `[]` | 文字セット | `[aA]*.txt` | `apple.txt`, `Article.txt` |

## 使用例

### ファイル検索
- `*.log`: すべてのログファイル
- `report_????.xlsx`: 4桁の数字を含むレポートファイル
- `[0-9]*.csv`: 数字で始まるCSVファイル

## 主な用途
1. ファイルとディレクトリの検索
2. バッチ処理
3. シェルスクリプト
4. 簡単なファイルパターンマッチング

:::note info
## シェル・コマンドライン
- Bash, Zsh等のシェルスクリプト
    例：
    - `ls *.txt`
    - `cp report_*.csv /backup/`

## プログラミング言語での使用
- ファイルパス操作
- 簡易的なパターンマッチング
- Pythonの`glob`モジュール
- Pythonの`pathlib`モジュール
:::


# 正規表現 vs ワイルドカード

## 主な違い

### 柔軟性
- **正規表現**: 非常に柔軟で複雑なパターンを表現可能
- **ワイルドカード**: シンプルで直感的だが、限定的

### 複雑さ
- **正規表現**: 学習コストが高い
- **ワイルドカード**: すぐに理解できる

### 用途
- **正規表現**: 
    - データ検証
    - 高度な文字列処理
    - テキスト解析
- **ワイルドカード**:
    - ファイル検索
    - 単純なパターンマッチング

# まとめ

正規表現とワイルドカードは、それぞれ異なる強みを持つパターンマッチングツールです。
目的と複雑さに応じて適切な方法を選択するといいでしょう。

この記事で「それぞれの違いが分かるようになったぜ！」って人が増えると幸いです。
MDM SaaS：Reference 360の「標準（スタンダード）」と「基本（ベーシック）」のライセンスと仕様の違いとは？

# はじめに
皆さん、「参照マスタ」というものを聞いたことがありますか？
「参照マスタ」とは、マスタオブマスタと言われてマスタデータを作る際、マスタを構成する属性を定義するコード値を指します。

## 参照マスタとは…
それでは、どのようなものが参照マスタであるかを確認してみましょう。
例えば、国・地域コード、都道府県コード、通貨コード、勘定科目・コストセンター、カテゴリ分類（UNSPSC‐国連標準製品サービスコード、顧客区分、工場区分）等のようなものが該当します。

## 参照マスタは、大まかに2つに分類されます
- **企業法人等の組織内部でのみ使用されるもの（内部）**：勘定科目・コストセンター、組織・人事コード、テリトリコード、販売区分等

- **世間一般に公開されて世界、業界共通のもの（外部）**：通貨コード（ISO 4217）、国・地域コード、都道府県コード、日本標準産業分類（JSIC）、北米産業分類システム（NAICS）、国連標準製品サービスコード（UNSPSC）等

## Informatica MDM SaaSと参照マスタについて
これら「参照マスタ」も、Informatica MDM SaaSで管理することができます。その為には、Reference 360（360アプリの一つ）を利用します。そして、Referenceライセンスが必要となります。

### このReferenceライセンスには、2パターンがあります
- 標準（スタンダード）：Reference 360の全ての機能が利用できる
- 基本（ベーシック）：Reference 360の一部機能のみが利用できる

### 「基本（ベーシック）」とは…
例えば、顧客（取引先法人／消費者）、製品（品目、製品）マスタには、それぞれ、顧客区分（株式会社、有限会社）、製品区分（例えばRoHS適合）、リスク区分（信用）等のように当該マスタ自体を管理する上で必要な属性があります。

それ以上、それ以下でない範囲でそれら属性コード値の管理を行う場合に限定して利用することができるものです。

MDM SaaSで、Customer 360、Product 360、Supplier 360を利用の場合、Reference 360 基本（ベーシック）を利用して、参照（属性）データを管理することができます。

顧客－Customer（B2B、B2C）、製品－Product、サプライヤーSupplierドメインライセンスに包含されています（※Referenceドメインライセンスは不要です）

例えば、「取引先区分」のドロップダウンリストを設ける場合で利用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618402/8bdf8e5a-f520-86fb-ee73-6697f017644a.png)

### 「基本（ベーシック）」の利用範囲・制約事項
利用制約は、以下のようになります。

- 属性数：３項目（固定）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618402/15213800-129d-f566-1301-35784fe7db3b.png)
（属性項目を増やしたり、減らすことはできません）

- その他機能別（Reference 360 機能比較一覧）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618402/f07eaed4-6a2a-7151-c1e2-467b109516f7.png)

## 「基本（ベーシック）」での参照マスタの作成の流れ
Business 360コンソールから当該属性を設定させるビジネスエンティティ（BE）において、「選択リスト」、「従属選択リスト」の［全般］プロパティの「新規」から設定します。

1. ［全般］プロパティ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618402/156bdf01-b3bb-5654-b86c-d6c158af13cd.png)
（ここから作成するのが基本です）

2. 参照マスタ（アセット）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618402/fa644b8c-14e6-53ab-89cb-fbc4774420a2.png)
（作成する参照マスタ名称と保存先を指定します）

3. 項目定義
Name、Code、Descriptionの3項目固定のみ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618402/bc6a0726-01be-1502-7a05-01c70bb6d901.png)
（保存ボタンをクリックしてこの参照マスタのレイアウトを確定します）

4. ビジネスエンティティの属性（項目）に利用する参照マスタを引き充てる 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618402/fc0722fb-caae-b5ce-793d-2773879f8f1c.png)
（■をクリックして、前段で保存した参照マスタを検索します）

5. 設定した参照マスタを探す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618402/90e7fa8f-1559-d65b-7ff7-6f8cc0b213c1.png)
（一覧から当該の参照マスタを選択します）

6. 設定完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618402/ca497072-2b50-8e06-0dd0-90ddc5c2db14.png)
（設定が完了するとこのような表示となります）

# まとめ
導入検討時において、要件が確定していない、また、要件定義途中、インプリ途中でも仕様変更があり得ます。「基本（ベーシック）」の利用以外に、「標準（スタンダード）」の最低ライセンス数（10,000レコード～）を準備しておくと、要件・仕様変更に柔軟に対応することができますので、検討をおすすめします。
AIの成長を支えるインフラ現代化 — 企業が勝ち組となるための課題と戦略

> 本記事は[こちらのブログ](https://www.alibabacloud.com/blog/ai-growth-is-built-upon-infrastructure-modernization-how-businesses-must-adapt-to-thrive_601814?spm=a2c65.11461433.0.0.5ba35355CsQKD9)を参考にしています。
> 翻訳にはアリババクラウドの[ModelStudio](https://www.alibabacloud.com/en/product/modelstudio)([Qwen](https://www.alibabacloud.com/en/solutions/generative-ai/qwen))を使用しております。

## AIの成長に不可欠なインフラ

AIが産業界を前例のない速度で変革する中、安全で強固、持続可能なクラウドネイティブなインフラストラクチャーは不可欠だ。

![AIの成長](https://yqintl.alicdn.com/9ac85f119f2a7a2113c961867e79b0a3e9988fda.jpeg)

IDCによると、2028年までに世界のAI投資額は6320億ドルに達し、生成型AI(GenAI)は年平均59.2%という驚異的な成長を見せる。しかし、AI能力が飛躍的に向上する一方で、それに対応するインフラは重荷を感じている。

マッキンゼー調査では、北米とアジアの企業がAIに熱中しており、北米では76%、アジアでは70%がAIの変革を始めており、リーダー企業はこの優位性を維持するために積極的に変革追求が必要だと述べている。現状、アジアではまだGenAI活用事例から価値を引き出すことができた企業は10％未満であり、成功した企業は競争優位性を築く可能性が高い。

## GenAIが要求するインフラ

GenAIは成長を牽引する一方、大規模な計算能力、膨大なデータ保管、高度なアルゴリズムが必要であり、エネルギー消費、コスト、持続性、パフォーマンスに大きな影響を与える。

従来のインフラはこれらのニーズに不向きであり、AIへの投資を最大化するためにインフラの現代化と並行して進める必要があります。

AIインフラの支出はサーバーやクラウドインフラなどのハードウェアに大規模であり、GenAI採用よりも成長率は低いが、重要な役割を果たす。

## 必要なAIインフラの特徴

### セキュリティとコンプライアンス

AIモデルは大量のデータを処理するため、データセキュリティと規制標準の遵守は重要。暗号化、アクセス制御、GDPRなどのグローバルデータ保護規制適合のインフラが必要。

### クラウドネイティブな基盤

AIの需要増に応えるため、強力な計算、高パフォーマンスネットワーク、ストレージ、コンテナ管理システムを含むクラウドネイティブなインフラを採用することが求められる。

### スケーラブルでコスト効率の高いデータ管理

AI利用事例が増え、スケーラブルでコスト効率の高いクラウドインフラがデータ管理・分析にとって不可欠。

### エネルギー効率と持続可能性

AI負荷が増すにつれてエネルギー消費も増加し、環境への影響が懸念される。再生可能エネルギー、省エネハードウェア、グリーンデータセンターが重要。

## 結論

AIが進化する中、企業は現在のインフラチャレンジだけでなく、将来のAI環境の変化にも対応する必要がある。セキュリティ、技術的要件、そして持続可能なニーズを考慮したインフラ戦略が求められる。

AI時代の変革期において、企業は競争力を維持するためにクラウドインフラの現代化に尽早取り組むことが急務である。

---

*この記事は[Alizila](https://www.alizila.com/ai-growth-is-built-upon-infrastructure-modernization-how-businesses-must-adapt-to-thrive/)でAlizilaスタッフによって原件公開されました。
【ML初心者アドベントカレンダー】基本的なAI用語について



# この記事の目的

ニュアンスでふんわり覚えて使っていた基本的なAI用語について説明できるようになる。
そもそもAIとMLが何なのかという話はこちら。
https://qiita.com/ei_540/items/1d59062648328a327920


# 深層学習（ディープラーニング）

ニューラルネットワークを使って大量のデータを学習すること。


### ニューラルネットワーク

深層学習の基本になるアルゴリズム。画像認識や音声認識に使われている。
人間の脳の神経システム（ニューロン）を模してモデル化した。
入力層、隠れ層（中間層）、出力層の三種類で構成されている。
入力層でデータ（多くの場合は画像や音声などの非構造化データ）を受け取り、出力層に結果を送信する。隠れ層ではデータから結果に必要な特徴量を学習する。

### アルゴリズム

問題を解くための一連の手順やルールのこと。

# コンピュータビジョン

その名前の通り、コンピュータに画像等を見せて学習させること。
物体検出や顔認識に使う。


# トレーニング

データを使ってモデルに学習させること。

# 推論

学習したモデルを新しいデータに試してみること。以下の種類がある。

* バッチ推論
  * 決められた時間に定期的に処理を行う。大量のデータかつ、リアルタイムでなくても大丈夫な場合に最適
* リアルタイム推論
  * その名前のとおり、入力されたデータを即座に処理する。チャットボットなど、レイテンシーが許されない要件に最適
* 非同期推論
  * 転送するデータのサイズが大きく処理時間が長い、ほぼリアルタイムのレイテンシー要件があるリクエストに最適
  * https://docs.aws.amazon.com/ja_jp/sagemaker/latest/dg/async-inference.html


# フィット

モデルがトレーニングデータにどの程度適応しているかを示す概念。

### 過学習（オーバーフィッテング）

トレーニングで使用したデータを覚えすぎてしまい、新しいデータにはあまり適応できない状態。学習させるモデルが複雑なほど起きる。

### 未学習（アンダーフィッティング）

データを十分に学習できていない状態。シンプルにデータや学習時間が足りていない。
知識がない状態で資格を受けて全くうまくいかないのと同じ。

# バイアス

実測値と推定値の差のこと。偏ったデータ等で学習させると発生しやすい。過学習の原因にもなる。


# 公平性

AIがすべての人間を平等に扱い、不当な偏りやヤバ思想を持たないように設計しようねーという取り組み。

# 透明性

どんなデータを使い、どうやって学習したのかが誰にでもはっきりとわかる状態。
いくら便利でも、誰がどうやって作ったかわからないものは安心して使えないよね…という考えから生まれた。

# 大規模言語モデル（Large Language Model）

大量のテキストデータで訓練された深層学習モデル。一般的にLLMと略される。
高度な言語理解機能を持ち、ChatGPTとかにも使われている。
【Laravel】定数をModelで管理する時代は終わった

:::note info
[Laravel Advent Calendar 2024](https://qiita.com/advent-calendar/2024/laravel) の6日目です :muscle:
:::

こんにちは :smiley: tatata-keshiです :exclamation: 

Webアプリケーションを開発において、ユーザーの種別やステータスといった定数をどのように管理するかは、みなさん一度は考えたことがあるのではないでしょうか？

## Modelで定数を管理する方法

例えば、ユーザーの種別（一般会員、プレミアム会員など）を整数型で保存する際、これまでは次のようにModelファイルに定義するのが一般的でした。

```php:User.php
class User extends Model
{
    const TYPE_GENERAL = 1;
    const TYPE_PREMIUM = 2;

    public static function getTypeLabels(): array
    {
        return [
            self::TYPE_GENERAL => '一般会員',
            self::TYPE_PREMIUM => 'プレミアム会員',
        ];
    }
}
```

## Model用いることの問題点

しかしながら、Modelファイルに定数を記述する従来の方式には問題点がありました。

1\. **コードの可読性が低下**

定数が増えると、モデルファイルが肥大化し、可読性が損なわれます。

2\. **型安全性が保証されない**

定数はあくまで整数値であり、意図しない値が代入されるリスクがあります。

3\. **メンテナンス性の低下**

定数やその対応ラベルが複数の場所で使われると、変更時に影響範囲が広がります。

## 列挙型（Enum）の登場
PHP 8.1以降では、これらの課題を解決する列挙型（Enum）が導入されました。Enumを用いることで、コードの可読性や型安全性が大幅に向上します。以下は、先ほどの例をEnumで書き直したものです。

```php:UserType.php
enum UserType: int
{
    case GENERAL = 1;
    case PREMIUM = 2;

    public function label(): string
    {
        return match($this) {
            self::GENERAL => '一般会員',
            self::PREMIUM => 'プレミアム会員',
        };
    }
}
```

## 列挙型をLaravelで活用する
Laravelのモデルと組み合わせることで、さらに便利に使えます。

### データベースとの連携
`$casts`プロパティを活用することによってUserのtypeの型を自動で変換することができます。

```php:User.php
class User extends Model
{
    protected $casts = [
        'type' => UserType::class,
    ];
}
```

これにより、データベースから取得した値は自動的に `UserType` 型として扱えます。

### 使用例
```php
$user = User::find(1);

if ($user->type === UserType::PREMIUM) {
    echo "このユーザーはプレミアム会員です";
}

// ラベルを取得
echo $user->type->label(); // プレミアム会員
```

## 列挙型（Enum）を使うメリット
1\. **コードの可読性が向上**

ラベルや値がEnum内にまとまっているため、管理がしやすくなります。

2\. **型安全性の確保**

Enum型を使うことで、意図しない値が代入されることを防ぎます。

3\. **メンテナンス性の向上**

値やラベルの変更がEnum内で完結するため、影響範囲が最小限に抑えられます。

## まとめ
このように、これまでModel内で管理していた定数をPHP 8.1以降の列挙型で置き換えることによりさらに効率よく、そして安全な実装ができるようになります。
もしまだPHP 8.1以降に移行していない場合は、この機会に移行を検討してみてはいかがでしょうか？

ぜひ、新しいEnumの力を活用し、新時代のLaravel開発に挑戦してください！
GoのGoroutineについて学ぼう

**Go言語には並行処理を簡単に実現するための非常に便利な機能である「Goroutine」があります。Goroutineは、Goのプログラムを効率的に動かすための軽量なスレッドのようなものです。この記事では、Goroutineの基本的な概念や使い方、他の並行処理手法との違いについて解説します。**

# Goroutineとは？

Goroutineは、Goにおける並行処理のための基盤で、通常の関数呼び出しと同じように使えますが、goというキーワードを使うことでその関数を「並行して」実行させることができます。Goroutineは非常に軽量で、数千、数万ものGoroutineを一つのプログラムで簡単に起動できます。

例えば、以下のコードでhello()関数をGoroutineとして実行します。
```Go
package main

import (
    "fmt"
    "time"
)

func hello() {
    fmt.Println("こんにちは、Goroutine！")
}

func main() {
    go hello() // hello関数を並行して実行
    time.Sleep(time.Second) // メイン関数が終了しないように少し待つ
}
```

上記の例では、hello()関数が並行して実行されます。しかし、main()関数が終了するとプログラム全体も終了してしまうため、time.Sleep(time.Second)を使って少し待機させています。

# Goroutineの仕組み

Goroutineは、オペレーティングシステムのスレッドとは異なり、非常に軽量です。Goランタイムは、Goroutineを小さなメモリフットプリントで管理し、大量のGoroutineを同時に実行できます。Goroutineは、Goのランタイムによってシステムのスレッドにマッピングされ、効率的なスケジューリングが行われます。

これにより、Goroutineは「スレッドのような動作」をしながらも、システムのリソースをより効率的に利用することが可能です。例えば、Goroutineは1000個やそれ以上を実行しても、システムの負担が比較的少なくなります。

**チャネル (Channel) を使ったGoroutine間の通信**

Goroutineは並行して動作しますが、それぞれのGoroutine間でデータのやり取りをする必要があります。Goでは、このための手段として「チャネル (Channel)」が提供されています。チャネルは、Goroutine同士が安全にデータを送受信するためのツールです。

以下はチャネルを使ってGoroutine間でデータを送受信する例です。

```Go
package main

import "fmt"

func sayHello(done chan bool) {
    fmt.Println("こんにちは、チャネル！")
    done <- true // チャネルに値を送信して処理完了を通知
}

func main() {
    done := make(chan bool) // ブール型のチャネルを作成
    go sayHello(done)       // Goroutineとして関数を実行
    <-done                  // チャネルから値を受け取るまで待機
    fmt.Println("メイン関数終了")
}
```

このコードでは、sayHello関数がdoneというチャネルにtrueを送信し、main()関数側でその値を受け取ることで、sayHelloの処理が完了するまで待機しています。チャネルを使うことで、Goroutine間の同期が簡単に実現できます。

# Goroutineと他の並行処理手法との違い

Goroutineは、他の言語のスレッドやプロセスと比較して非常に軽量です。以下に主な違いをいくつか挙げます：

**軽量性**: Goroutineは非常に軽く、同時に数千、数万のGoroutineを実行してもシステムのリソースをあまり消費しません。これは、Goランタイムが効率的にGoroutineを管理しているためです。

**共有メモリの排除**: Goroutineは、データ共有のためにチャネルを使用します。これにより、直接メモリを共有しないため、複雑なロック機構を使わなくてもデータの整合性が保たれます。これが他の並行処理と比べてバグの少ないプログラムを実現するポイントです。

**簡潔な構文**: goキーワードを使うだけで並行処理が実現できるため、シンプルなコードで並行処理のロジックを書くことが可能です。

実用的な例: Webサーバーの並行リクエスト処理

Goroutineは、Webサーバーなどで複数のリクエストを同時に処理する場合に非常に便利です。以下は、Goroutineを使って複数のリクエストを同時に処理する例です。

```Go
package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "こんにちは、%sさん！", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/", handler)
    fmt.Println("サーバーがポート8080で起動中...")
    http.ListenAndServe(":8080", nil)
}
```

この例では、http.HandleFuncを使って各リクエストを処理しますが、内部的にはGoのWebサーバーは各リクエストをGoroutineで並行処理することで、多数のリクエストを効率的に捌いています。

# まとめ

**Goroutineは、Goの並行処理を非常にシンプルかつ効率的に実現するための強力なツールです。軽量な特性とシンプルな構文により、並行処理を使ったプログラムの設計が非常に楽になります。**
macOS DMG アプリのバンドルIDとビルド番号を確認する方法

MicrosoftIntuneにmacOS DMGアプリを追加するときハマりかけたので備忘

DMGファイルの**バンドル ID** と**ビルド番号**を確認する方法だけ書いてます。他は以下ページをみてください。

https://learn.microsoft.com/ja-jp/mem/intune/apps/lob-apps-macos-dmg

# そもそもの話
### .dmgファイルとはなんぞや
macOSの由緒正しい標準ディスクイメージ。windowsでいうところのISO/BIN/IMG。

### windows PCから開ける/中身調べられるっけ？
- windows PCからdmgファイルは開けないので　[DMG Extractor](https://reincubate.com/dmg-extractor/)などを使う必要あり。
- 中身（info.plistとか）見れるかどうかは不明（時間あったら調べる）
- いずれにしてもwindows PC/Mac両方の利用者がいる場合、情シス検証機として1台ずつあったほうがbetterではある。

# 調べ方
learnだと　ターミナルで`defalut`コマンドを使うように書かれていますが、GUIでも確認可能です。
ここでは例としてOpenVPN Connectを取り上げています。
- dmgファイルをmacOS機にダウンロード、インストールする
- dmgファイルのインストール先をみる
（デフォルトではMacintosh HD>アプリケーション　にある）
- 該当アプリケーションを右クリックし **パッケージの内容を表示**　をクリック
![スクリーンショット 2024-12-05 15.19.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160366/bc63c1c9-cf3d-cffc-14c5-617aa1db84c7.png)
- Contents　をクリック
![スクリーンショット 2024-12-05 15.19.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160366/94d6f3bf-d5c1-5d14-26f6-e2fa9dcd0488.png)

- Info.plist（プロパティリスト）をテキストエディタなどで開く
![スクリーンショット 2024-12-05 15.19.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160366/dc52c291-cf8a-edb3-ec5e-a1d6f6f4a4a1.png)

-だいたいXML形式で `<key></key>` `<string></string>` でくくられた中に要素が書かれているので
`CFBundleIdentifier`　と　`CFBundleShortVersionString`　を探してコピペ
![スクリーンショット 2024-12-05 15.41.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160366/51239d66-bef3-1c35-deae-2b07084999cd.png)



- あとはintuneに登録するときの「検出ルール」で、先ほど調べた項目を入力、割り当てすればOK！お疲れ様でした。
![スクリーンショット 2024-12-05 15.39.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160366/91b68ffd-9216-de08-45b4-44ca7a170aa4.png)







# まとめると
- 情シス担当者はmac/windows両方持っておいた方がよい
- plistは今はだいたいxml形式だと思う。NeXT形式の場合はちょっとわかりません。。
【Go言語】mockの生成からDIを一箇所にまとめて単体テストの記述をちょっと省エネにした

この記事は、tacoms Advent Calendar 2024の5日目です!
他メンバーのAdvent Calendarはこちらからご覧ください！👇

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

## 背景
mock使っていますか？
単体テストにおいてmockを活用するのは一般的ですが、テストケースごとにmock生成しDIするのは冗長になりがちで、可読性も良くありません。

例えば、以下のような具合です。（弊社では[mockery](https://github.com/vektra/mockery)というライブラリを使っています。）
```go:task_test.go
func TestCreateTask(t *testing.T) {
    // userのmock初期化
    userMock := mock.NewUser(t)
    userMock.Expect().GetUser(ctx, "1").Return(&User{}, nil)

    // userGroupのmock初期化
    userGroupMock := mock.NewUserGroup(t)
    userGroupMock.Expect().ListUserGroups(ctx, []string{"2", "3"}).Return([]*UserGroup{}, nil)

    // taskのmock初期化
    taskGroupMock := mock.NewUserGroup(t)
    taskGroupMock.Expect().Create(ctx, &Task{}).Return(nil)

    // mockを注入
	server := &Server{
		User:      userMock,
		UserGroup: userGroupMock,
		Task:      taskGroupMock,
	}
	err := server.CreateTask(ctx, "some task")
	assert.NoError(t, err)
}
```
このように、生成する対象のmockが多ければ多いほど初期化がつらくなってきます。
また、生成したmockはテスト対象の構造体にDIしなければならないため、そのコード自体も冗長化しがちです。

## 解決方法


### mock生成をまとめる関数の導入
以下のように、mockの生成からDIを一箇所でまとめてやってみます。
これによってテストケース毎にmockを生成してDIするコードを書く手間が省けます。
また、新しいmockが必要になった時は、誰かがそれを追加しさえすれば、他の人は利用するだけで済みます。

```go:server_test.go
type mock struct {
	user      *mock.MockUser
	userGroup *mock.MockUserGroup
	task      *mock.MockTask
	// and so on
}

func newMock(t *testing.T) (*server, *mock) {
	m := &mock{
		user:      persistencemock.NewMockUser(t),
		userGroup: persistencemock.NewMockUserGroup(t),
		task:      persistencemock.NewMockTask(t),
		// and so on
	}
	s := &server{
		User:      m.user,
		UserGroup: m.userGroup,
		Task:      m.task,
		// and so on
	}
	return s, m
}
```

### 実際のテストでの利用
使う側はnewMock関数を呼び出すだけです。
本記事の一番上で例に出した冗長なコードよりもスッキリしたのではないでしょうか？

```go:task_test.go
func TestCreateTask(t *testing.T) {
    // mockをまとめて初期化しDI
    server, mock := newMock(t)
    
    mock.user.Expect().GetUser(ctx, "1").Return(&User{}, nil)
    mock.userGroup.Expect().ListUserGroups(ctx, []string{"2", "3"}).Return([]*UserGroup{}, nil)
    mock.task.Expect().Create(ctx, &Task{}).Return(nil)

	err := server.CreateTask(ctx, "some task")
	assert.NoError(t, err)
}
```

## まとめ
今回のアプローチにより、以下のメリットが得られました。

- テストコードの可読性とメンテナンス性が向上した
- mockの追加や変更が容易になった
- テストロジックに集中できる環境が整備された
- 書きっぷりの統一された

今回の例は、導入コストが低く、すぐに実践できる方法を紹介しました。しかし、他にもDI系ライブラリや、テスト用フレームワークを活用することでさらに効率化することも可能かと思います。

プロジェクトの規模や要件に応じて、最適なアプローチを選ぶことが重要です。

## PR
現在株式会社 tacoms では全ポジションで絶賛採用募集中です！
是非気軽にカジュアル面談からお話ししましょう 👏

https://www.tacoms-inc.com/recruit
【言語初心者】Typescriptってどんな言語？

# はじめに
どうも、アドベントカレンダーで投稿頻度が高い人です。
今回は、Typescriptという言語は一体何者なのか、解説していきます。

:::note warn
注意
この記事は初心者が調べたことをまとめているだけです。
間違いがあるかもしれません
:::

# Typescriptとは
JavascriptをベースとしたMicrosoftによって開発された言語です。
2012年10月に初めて公開されました。
# 特徴
- オープンソースである
- 名前の通り、型宣言ができる
- Javascriptの上位互換として開発された
- 基本的な文法はJavascriptと同じ
# 結論
Typescriptは、型宣言ができるJavascriptベースの言語。
友達と高尾山にオリエンテーリングに行った話

## オリエンテーリングとは？
まずオリエンテーリングについて説明したほうが良さそう。
オリエンテーリングは専用に作られた地図を使って、大自然の中に設置されたチェックポイント（コントロール）を辿りながら可能な限り短時間で走破するアウトドアスポーツだ。

***
さて、そろそろ本題に入ろうか。
忘れることができない約2年前の出来事。
誰だか忘れたが
「高尾山でオリエンテーリングでもしよう！」
と言い出した人がいた。
僕はそれにつられ、参加した。15人ぐらい集まったので、結構良い方だったのではないか。
そして、日付が決まったところで「3グループに分かれよう」
という話になった。
「最初はグー、じゃんけん..ポン！...」
**これが後の悲劇に繋がるだなんて、誰も想像出来なかった.........**
***
そして訪れたオリエンテーリング当日。
各自カメラ、スマホ(Google Mapなどの使用は禁止。)、地図、コンパスを持っていることを確認し、オリエンテーリングが開始した-------
僕らのチームは、最初**は**好調だった。次々と撮ることが出来ていた。しかし途中で、
「あれ？ここ何処だ？」
そう、高尾山には2つの道に分かれる場所があるのだ。間違えて稲荷山へ向かうコースに行ってしまったのである。
僕らは「これどっち行けば良いんだろう...」「こっちでいいだろ！」「了解！」
こんなクソ軽いノリで決めてしまったがためにこんな問題が起きてしまったのである。
とりあえずこっちだろうと山頂を目指して歩いた。道の途中では一切電波が繋がらなく、全員「終わった...」と思っていただろう。
暫く歩くと、山頂が見えてきた。
「！？」「電波が繋がるぞ！！！」
僕は真っ先に他のグループへ電話した。
「もしもし？いきなりなんだけど、隣の山へ行っちゃったみたいなんだよね」
「...は？...とりあえずGoogle mapでも使ってなんとかして下山しよう」
そんな会話をしているとき、奇跡が起こったのである。
THE 登山のベテランって感じの人が下山を手伝ってくれたのである。
なんとかその人のおかげで助かったが、感謝してもしきれない。
あの人の顔は生涯忘れることはないでしょう。多分。