OmniAICreator/Qiita-1.07M huggingface dataset:
ESONについて

ESONはEMF Simple Object Notationの略です。
ここで登場しているEMFはEclipse Modeling Frameworkのことで、EMFでモデルを作成するとそれに応じたコードが自動生成されるものです。
ESONはこのEMFモデルをテキストで表現する構文です。

EMFモデルのテキスト表現にはXMI(XML Metadata Interchange)もありますが、ESONはJSONのように人間が読みやすいようです。

例えば、以下のようなxcoreファイルによるモデルがあるときに、

```
package example

class Library {
    String name
    contains Book[] books
    contains Writer writers
}

class Book {
    String name
    int pages
    BookCategory category
    refers Writer author
}

class Writer {
    String name
}

enum BookCategory {
    None, Mystery, SciFi, Biography
}
```

それに対応するESONは以下のようになります。

```
import example.*

Library {
    books: [
        Book {
            name: "Perry Phodan"
            pages: 123
            author: Scheer
            category: :SciFi
        }
    ]
    writers: [
      Writer Scheer {
      }
      Writer ClarkDarlton {
      }
    ]
}
```

# 構文
ESONファイルは使用するEPackageを指定するuse文で始まります。
その後はEClassの名前と中括弧が続き、その中に属性が列挙されています。
JSONを読み慣れている人ならば雰囲気である程度読むこともできる程度にJSONに似た構文です。
文字列型はダブルクォートで囲まれており、他のEClassを参照する時にはEClass名のみを記述します。
また列挙型(enum)をの要素を表すためには要素名の前に `:` が必要がです。
CSONについて

CSONはCoffeeScript Object Notationの略で、CoffeeScript版のJSONです。
JavaScriptに対するCoffeeScriptのようにシンプルな記法でデータを表現できます。

JSONと比較して以下のような違いがあります。

# コメント

CSONでは `#` で始まる行はコメントとして扱われます。

```
# Comments!!!
```

# 配列

CSONでは配列の要素を改行で区切るため、JSONのようなカンマが不要です。

```
greatDocumentaries: [
	'earthlings.com'
	'forksoverknives.com'
	'cowspiracy.com'
]
```

# オブジェクト

オブジェクトのをインデントで表現するため、JSONのような波括弧は不要です。
また、 `'''` で複数行からなる文字列を表現できます。

```
importantFacts:
	# Multi-Line Strings! Without Quote Escaping!
	emissions: '''
		Livestock and their byproducts account for at least 32,000 million tons of carbon dioxide (CO2) per year, or 51% of all worldwide greenhouse gas emissions.
		Goodland, R Anhang, J. “Livestock and Climate Change: What if the key actors in climate change were pigs, chickens and cows?”
		WorldWatch, November/December 2009. Worldwatch Institute, Washington, DC, USA. Pp. 10–19.
		http://www.worldwatch.org/node/6294
		'''

```

Coffee Scriptの記法を採用していることから、JSONに比べてシンプルで可読性が高いように感じます

出展:

https://github.com/bevry/cson
【mircoCMS】ヘッドレスCMSを初めて触ってみた。

業務でWordPressを使っている時に、「Vue.jsやReactなら簡単に終わるのになぁ‥」と感じることが多いので、ヘッドレスCMSというものに挑戦してみることにしました。

今回使用したのは「microCMS」です。

無料で気軽に始めることができます。

https://microcms.io/

登録完了後は「まず何をしたらいいんだろう‥」となってしまったのですが、

公式がきちんとmicroCMSを初めて使う人向けに解説ページを用意してくれていました。

ありがとうございます。

以下のページを参考にすると、問題なく最初の一歩を踏みだせました。

https://blog.microcms.io/getting-started/

ただし、コードをコピペするだけだと、自分の書いた記事の内容は表示されませんでした。

![スクリーンショット 2024-12-01 19.26.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736578/7a2010f0-eb9a-b862-dacc-c7b009240e66.png)

↑のように見本が表示されてしまいます。

自分の書いた内容を表示するためには、以下の3つを変更する必要があります。

- サービスID
- エンドポイント
- APY-KEY

サービスIDは管理画面の左上、エンドポイントとAPY-KEYはAPIプレビュー画面にあります。

![スクリーンショット 2024-12-01 19.30.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736578/8925db18-1c37-d077-8a1d-359d64622171.png)

![スクリーンショット 2024-12-01 19.29.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736578/acfeec16-31f1-42a6-3e9d-143a1a820023.png)

以上の3点を、見本のコードに反映させる必要があります。

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>ブラウザでデータを表示する</title>
</head>
<body>
    <main>
        <h1 id="title"></h1>
        <hr>
        <div id="body"></div>
      </main>
      <script>
        fetch("https://⭐️ここを自分のサービスIDに変更⭐️.microcms.io/api/v1/news/⭐️ここを自分が作ったお知らせのエンドポイントに変更⭐️", {
          headers: {
            "X-MICROCMS-API-KEY": "⭐️ここを自分のAPI-KEYに変更⭐️"
          }
        })
          .then(res => res.json())
          .then(json => {
            document.getElementById("title").innerHTML = json.title;
            document.getElementById("body").innerHTML = json.body;
          })
     </script>
</body>
</html>
```

無事に自分が書いた記事の内容が表示されました。

![スクリーンショット 2024-12-01 19.39.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3736578/fbf2bb78-9acd-9f56-33be-0d0e3371cd03.png)
起業するならElixirシリーズSTEP.4 コンセプトを決めろ

## ターゲットを決めろ

前回は「作る前に売る」という原則についてお話ししました。これは、本格的な開発に入る前に、課題を特定し、販売の見込みを確保してから製品開発を始めるという考え方です。

ソフトウェアサービスを提供する場合、まず顧客となりうる人々を探してサービスを構築していきますが、その過程でサービスのコンセプトを決める際、ターゲットを明確にすることが重要です。

例えば、これから解説するElixirでの開発例として、次のようなターゲット設定を考えてみましょう

**「起業について調べ始め、具体的な行動を開始しているものの、具体的な事業内容や時期についてまだ決めかねている人」**

このターゲット設定の後、「ターゲットの課題を解決するコンセプト」を策定する必要があります。

## コンセプトを決めろ

コンセプトの策定には、ターゲットの状況を深く理解することが不可欠です。

先ほど設定したターゲットについて、以下のような特徴を仮説として立てることができます。これらは検証を重ねながら精緻化していく必要があります。

**状況面の特徴**
- 起業というキーワードに関心を持ち、インターネット検索や書籍での情報収集を始めている
- 現在は会社員や学生として生活しながら、将来の選択肢として起業を検討している
- アイデアや事業計画がまだ具体化していない段階にある

**心理面の特徴**
- 起業への憧れや関心はあるが、具体的な一歩を踏み出せていない
- 情報収集は始めているが、どこから着手すべきか迷っている
- リスクや準備に関して不安を抱えている

コンセプトをより適切に決定するために、顧客理解をさらに深めていく必要があります。そこで、この連載でも実験的な試みとして、簡単なアンケート調査を実施したいと思います。

以下のアンケートにぜひご回答ください：
[https://forms.gle/USBooRs5ZjQEMbWS9](https://forms.gle/USBooRs5ZjQEMbWS9)

アンケートの結果については、個人情報に十分配慮しながら、今後の記事で分析・活用させていただく予定です。もし、お知り合いの中に起業に興味をお持ちの方がいらっしゃいましたら、このアンケートの共有をお願いできますと幸いです。

エンジニアの方々は、この段階で既に開発を始めたい気持ちをお持ちかもしれません。そこで、どのようなサービスになるにせよ必要となる課金機能の実装から始めていきたいと思います。

次回からは、具体的なElixirでの開発についても解説していきます。
定数を持つモジュールの利用

# 定数は`モジュール名::定数名`で呼び出す
```rb
irb(main):001* module Loggable
irb(main):002*   PREFIX = '[LOG]'.freeze
irb(main):003*
irb(main):004*   def log(text)
irb(main):005*     puts "#{PREFIX} #{text}"
irb(main):006*   end
irb(main):007> end
=> :log
irb(main):008>
irb(main):008> Loggable::PREFIX
=> "[LOG]"
```
# Mathモジュール
>浮動小数点演算をサポートするモジュールです。
>
>Math モジュールにはさまざま数学関数がモジュール関数として定義されています。モジュール関数は以下のように，`モジュールの特異メソッドとして呼び出す`使い方と、`モジュールをインクルードしてレシーバーを省略した形で呼び出す`使い方の両方ができます。

https://docs.ruby-lang.org/ja/latest/class/Math.html#:~:text=%E6%B5%AE%E5%8B%95%E5%B0%8F%E6%95%B0%E7%82%B9%E6%BC%94%E7%AE%97,%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82

# 定数を持つモジュールを扱う
```rb
irb(main):011> Math.sqrt(2)
=> 1.4142135623730951
irb(main):012* class Calculator
irb(main):013*   include Math
irb(main):014*
irb(main):015*   def calc_sqrt(n)
irb(main):016*     sqrt(n)
irb(main):017*   end
irb(main):018> end
=> :calc_sqrt
irb(main):019> calculator = Calculator.new
=> #<Calculator:0x000000010d165bf8>
irb(main):020> calculator.calc_sqrt(2)
=> 1.4142135623730951
```

```rb
irb(main):023> Math::E
=> 2.718281828459045
irb(main):024> Math::PI
=> 3.141592653589793
irb(main):025> Kernel.puts "Hello."
Hello.
=> nil
irb(main):026> Kernel.p [1, 2, 3]
[1, 2, 3]
=> [1, 2, 3]
```
https://gihyo.jp/book/2017/978-4-7741-9397-7
【Unity】ChatGPTを利用したゲーム実装で悩んだこと

# はじめに
この記事は[Hamster Output Advent Calendar 2024](https://qiita.com/advent-calendar/2024/game_hamster)の2日目の記事です！
数ヵ月前にChatGPTで会話テキストを生成する機能を実装しました。実装方法としては参考にしたリンクを見れば直ぐに実装出来ますので、本記事では実装中に悩んだことや解決方法を書いて行きたいと思います。

# 作成したソースコード

https://github.com/hamster3156/ChatGPT_API

# 参考にしたリンク

https://note.com/negipoyoc/n/n88189e590ac3

https://anogame.net/unity-chatgpt-api-tutorial/

https://qiita.com/kazuma_f/items/55a0b7ff628ab596e6ee

https://note.com/361yohen/n/n9d91a80002ab

# 実装中に困ったこと

### ・命名規則による変数名の制限
今回、ゲーム制作をしていたチームでは命名規則のルールがあったことから、ChatGPTに送るJson関連の変数名が全て合わなくなるといった問題がありました。そして、Json用の名前と変数名を分けることができる[Newtonsoft.Json](https://github.com/applejag/Newtonsoft.Json-for-Unity)のJsonプロパティという機能を見つけました。

今回の実装ではJsonプロパティを利用して、命名規則を守ったままJson形式の名前に変換するということができました。

```C#
[JsonProperty("id")]
public string Id;

[JsonProperty("@object")]
public string @Object;

[JsonProperty("created")]
public int Created;
```

### ・文字を特定の文字に変換したい
開発中にGPTのバージョンを変更したいことがあったので、enumを作成してChatGPTのバージョン名を変更できるように列挙しました。ですが、名称に-が使えないことから、代替えで_を入れることにしました。
```C#
public enum ModelList
{
    gpt_4o,
    gpt_4o_mini,
    gpt_3_5_turbo,
}
```
ですが、ChatGPTにバージョン名称を送る時はgpt-4o、gpt-3.5-turboの形式で送る必要がありました。stringkからif文で判定することを考えましたが、Unity文字変換...というワードで検索をしていたらStringBuilderを利用している記事を見つけました。

このStringBuilderが便利なことに、文字列関連の操作が物凄く簡単に出来ます。内容としては以下の通りです。
・後ろに文字列を追加
・途中に文字列を追加
・文字列の一部を削除
**・文字列の一部を変換**

この文字列の一部を変換という機能のおかげで、2~3行で文字列変換ができました。
```C#
StringBuilder stringBuilder = new StringBuilder();
        stringBuilder
            .Append(modelList.ToString())
            .Replace("_", "-")
            .Replace("3_5", "3.5");
```

### ・テキスト生成による料金について
正直に言うと、コスト面に関しては実装時間が限られていたので、今回は触れていません。ただ、多少文章生成の文字数を制限できるように最大トークン数などは設定できるようにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588406/e1acf5dc-97c7-76ae-bde6-09257e40ab8a.png)

画像生成に関しては、GPTがバグっていたのか？分かりませんがGPT-4o-miniで画像を送ると、GPT-4oよりも送信コストが10倍になるバグがありました。ネット記事で、GPT-4o-miniで画像を送るとコストが高くなるという記事があったのでOpenAI側に何かあったんだと思います。

### ・画像解析の実装
正直、ここが一番苦戦しました。基本的に調べても情報が出てこず...OpenAIのドキュメントを読みながら悩んでいましたが、タイムリーなことに画像解析をしている記事が投稿され、それを元に実装しました。

ChatGPTでもテキスト生成の記事は沢山あるんですが、カメラ撮影や画像送信などの部分はまだあまり情報が見つからなかったので結構ニッチな部分だったのかなと思いました。

https://note.com/361yohen/n/n9d91a80002ab

今回実装した画像読み取りのコードは、上の記事を参考にしつつ、AIに教えて貰いながら作成しました。未だに内容を全て分かってはいないですが...

画像を送るための鍵となっている部分が**image_url**と**url = $"data:image/png;base64,{base64Image}"** の部分です。正直...神エボの制作期間が本当に短かったので実装できたのは奇跡だと思っています。
```C#
 type = "image_url",
 image_url = new
 {
    url = $"data:image/png;base64,{base64Image}"
 }
 ```

### ・写真撮影
写真撮影も上に続いた内容です。カメラの起動処理も正直、かなり苦戦しました。といっても、今までインゲームのプレイヤー実装を主に行っていたので、今回システム面...?といっていいか分かりませんが、普段触らない部分に挑戦できたので良かったです。

Unityで写真撮影機能も正直ニッチな部分で、ここも調べて情報がかなり少なかったです。WebCamTextureとかもあります。

今回、カメラに関してはNaitiveCameraというプラグインを利用しました。このプラグインの凄い部分は、メソッドを呼び出すだけで写真撮影ができるという、神プラグインです。

https://github.com/yasirkula/UnityNativeCamera

# まとめ
今回のゲーム制作でとにかく苦戦した&大変だったことは

**・初めてのAndroidプラットフォームでの制作**
**・カメラ機能を利用したゲーム性**
**・AIを利用したゲーム仕様**
**・神ゲー創造エボリューションの締め切りスパンが早い**

以上の4つです。コンテストの結果としては二次で落ちてしまい、さらに作品もa？プロト段階で開発が終わってしまいましたが...

自分にとってはゲームクリエイターとしてかなり成長することができた、一大コンテストだったので参加して後悔はしてません！このコンテストのお陰で主体的に動けるようになったのでむしろ参加して良かったと思います。
Java 用語整理

# 今まで学習してきて意味が混同しがちな用語

- クラスとインスタンス
仮想世界で活動するのがインスタンス、そのインスタンスを生み出すための金型がクラス。

- フィールド
クラスブロック内に宣言された変数のこと
~~~java
public class Hero{
    String name;     //この部分が
    int hp;          //フィールドの宣言
}
~~~

- メソッド
複数の分をまとめて、それを一つの処理として名前を付けたもの

- コンストラクタ
    メソッドの一種・・・newされると自動的に実行される。
    コンストラクタとみなされる条件
    1. メソッド名がクラス名と完全に等しい
    2. メソッド宣言に戻り値の型が宣言されていない
    2. 
- インターフェース
インターフェースに宣言されたメソッドは、自動的にpublicかつabstractとなる。
Regression貧乏の話

## リグレッション、設計してますか

### 品質目標を定める
不具合分析や、製品特性、人・モノ・カネ・時間などに対してのリスク、
要求される性能などに応じて、品質目標を定めます。
これは、標語的な内容だったり、数値目標（注１）になる場合もあるでしょう。

こうして、チームで目指す品質を定め、チームの認識を作っておきます。

#### 例：　ユーザーのお金に関わる不具合は出さない　など

その中で、どういった内容のテストセットにしていくかを見積もります。

| テストポリシー | 品質目標 | メリット |　デメリット　|
|:-:|:-:|:-:|:-:|
|リスクベース   | リスク回避  |効率がよい |リスク以外は無保証 |
|網羅性重視   |  機能保全 |網羅的な補償 |運用工数増大 |
|責務重視   |  基本を担保 | 工数少な目|普段の使用機能以外は無保証 |



## 膨大なテストケース

いざリグレッションを作成するときに、心配から、際限なくテストを
追加していこうとすると、以下のような問題があります。
- マニュアルテスト：　工数が増加し続ける
- 自動テスト：　メンテナンスコストが増えすぎてメンテナンスできなくなる

リグレッションは定期的に行うので、毎月相当なコストがかかります。

また、思いつきでつくってしまっては、リグレッションによって何が保証できるのかが
説明できなくなります。保証の内容をコントロールするが厳しくなるでしょう。

場合によっては、コツコツテストケースを追加した結果、
数千件に膨れ上がったテストケースを
毎週マニュアルで実行している、なんて話もあります。


## リグレッションテストを整理する

こうした問題を避けるために、リグレッションのテストスイートを作っておきます。
テストスイートは、目指す品質・工数・テストの目的などを考慮して構成します。
その時のリソースや要件に応じて、流すテストセットを変えるのもよいでしょう。

また、リスクの線引きを行います。品質目標を満たす内容を考慮しつつ、
組み合わせの数、範囲、Web系ならブラウザ特性のテストパターン
などを、意図して間引きます。これは、クオリティコントロールの一環です。

間引いた部分のリスクは当然残りますが、レアケースだったり、
すぐ直せるものだったりのリスクは許容することになります。
もちろん、影響範囲が重大な製品は、簡単に間引くという問題ではないので、
基準が変わります。

無限に心配していては、生産性が下がり、機能追加が遅れ、
結局顧客満足から遠くなります。
品質基準の見極めは、高度なスキルと言えるでしょう。

また、マニュアルテストと自動テストもそれぞれ特性があるので、
考慮してリグレッションを組んでいきます。


## 個別の単位テストの目的・責務

テストスイートは、責務と目的のバランスを見て構成します。
一つのサンプルとしては

- 通常の業務が滞らないための基本的な機能
- 問題が起こると困る重大な操作
- コードが壊れやすい箇所を意識したテストパス
- 外部連携など、自社の努力だけでは解決できない部分
- 機能単位のテスト

などなど

これらを必要に応じて用意しておき、活用するとよいでしょう。
たくさん回すテストほど、コストパフォーマンスがよくなります。


## メンテナンス

メンテナンスの工数やフローを設計することも大事です。
工数と品質リスクを考慮にいれつつ、メンテナンスが、品質基準を維持しながら
実際に運用していけるものに設計します。使える時間を考慮して、
時間がないのであればマトリクスでの管理にしたり、
設計に必要なドキュメントを簡素化して時間を作ったりなどの
工夫が必要になるでしょう。



#
注１
品質に関する数値目標は、本来の目的とかけ離れる場合が多いので、注意が必要です。

#
### 用語解説
#### インシデント
組織によって意味合いが違い、解決すべき事柄を指すこともあれば、
重要な障害を指すこともあるなど、組織によって意味合いが異なります

#### テストポリシー　（参考： JSTQB）
目標の品質を実現するために、どういった内容でテストするかを決めたもの

#### テストスイート
定義は様々。ここでは、リグレッションのためのテストセット、として使っています
# 転職活動を通じて見つけた自分のビジョン 〜プロダクトづくりへの新たな挑戦〜


## プロフィール
```
年齢：31歳（転職活動時）
学歴：理系大学院修士卒
職歴：ITコンサルタント・エンジニア
転職経験：初めての転職活動
```

人生初の転職活動を終え、希望の企業から内定をいただくことができました。新卒で入社した大手企業での7年の経験を経て、初めての転職活動。当初は不安でいっぱいでしたが、結果として自分のキャリアビジョンを明確にする貴重な機会となりました。

## 転職を考えるきっかけ
最初の会社での7年間は、コンサルタントとしてもエンジニアとしても基礎を築く貴重な時間でした。しかし、プロジェクトを重ねるうちに、あることに気づき始めました。それは、短期的な成果だけでなく、「プロダクトの成長に長期的に関わりたい」という思いでした。

特にPdM（プロダクトマネージャー）という職種に興味を持ち始めたのも、このような思いが根底にありました。プロジェクトベースの開発から、一つのプロダクトを育てていく仕事への転換を模索し始めたのです。

## 視野を広げてくれた好奇心
転職活動を始めた当初は「PdMになりたい」という漠然とした思いだけでした。しかし、カジュアル面談や面接を重ねるうちに、「様々なプロダクトの成長物語を知りたい」という好奇心が芽生えてきました。

フィンテック、HRテック、教育系スタートアップなど、様々な分野のプロダクトに携わる方々とお話する機会に恵まれました。各プロダクトがどのように生まれ、どのように成長してきたのか、その過程で直面した課題をどう乗り越えてきたのかを知ることは、私の視野を大きく広げてくれました。

また、PdM職以外にも、事業開発やその他様々な職種の方々との対話から、プロダクトづくりを多角的に見る視点も養えました。「エンジニアだから技術の話だけ」という枠を超えて、プロダクトの本質的な価値について考える機会が増えていきました。

## 転職活動を通じて見えてきた自分のビジョン
カジュアル面談や面接を重ねるうちに、自己分析だけでは気づけなかった重要な発見がありました。私が本当に求めていたのは、単にPdMになることではなく、「プロダクトの誕生から成長まで、長期的な視点で関わっていきたい」というビジョンでした。

このビジョンは、様々な企業の方々との対話を通じて、徐々に明確になっていきました。特に印象的だったのは、各企業のプロダクト開発に対する長期的な展望についての議論です。短期的な機能追加や改善だけでなく、プロダクトの5年後、10年後のあるべき姿について語り合う機会が、私の考えを深めてくれました。

結果として6社に応募し、3社から内定をいただきました。不合格の通知をいただいた時は確かに落ち込みましたが、それぞれの面接が自分のビジョンを明確にする貴重な機会となりました。

## 大手からスタートアップへの選択
大手企業からスタートアップへの転職は、確かに大きな環境の変化です。しかし、「プロダクトの成長に深く関われる」という自分のビジョンに照らし合わせたとき、その不安は期待へと変わっていきました。

特に魅力を感じたのは：
- プロダクトの意思決定に深く関われる機会
- 構想段階から運用まで一貫して携われる環境
- ユーザーとの距離が近く、フィードバックを直接活かせる文化
でした。

## これから転職を考える方へ
最後に、同じように転職を考えている方へのメッセージです。

不安を抱えながらの一歩は、誰しも同じです。しかし、その不安に縛られず、様々な可能性に耳を傾けることで、自分が本当に実現したいビジョンが見えてくるかもしれません。

私の場合、「PdMになりたい」という具体的な目標から始まった転職活動でしたが、結果として「プロダクトの長期的な成長に関わりたい」という、より本質的なビジョンに気づくことができました。この発見は、様々な方々との対話がなければ得られなかったものだと確信しています。

自分のペースで、好奇心の赴くままに可能性を探っていけば、必ず道は開けると信じています。皆さんの転職活動が、自分らしいビジョンを見つける素晴らしい機会となりますように！
見切り発車で平仮名の学習アプリを作る【1日目】

**2024年のアドベントカレンダー1日目の記事です。**

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

### なぜ平仮名の学習アプリなのか
ほぼ毎週のごとく甥っ子と遊んでいるのですが、５歳ともなるとペラペラペラペラと喋りも上手くなっており、スマホやタブレットなども自分で操作できるようになっているのです。
あと１年そこらで小学生になることを思うと「今のうちに平仮名（できればカタカナも）をマスターできれば小学生になってから周りにドヤ顔させられるのでは・・・？」と思い至ったというわけです。

### どんなアプリを作るか？
- スマホやタブレットは触れるもののボタンの操作やスワイプなどの基本的な操作のみで文字の入力などはできない
- 喋りはいけるものの微妙に違う言葉を使いがち（とうもろこし→とももろこし等）
- 書きの練習は小学生でいやというほどやることになる

上記の状況からなるべくシンプルなアプリとしたい

### ざっくりの仕様
- どうせ部屋に押しかけてくるのでローカルで動けばいい
- 画面上の表示はでっかい平仮名＋回答ボタンのみ
- 回答ボタンを押すとマイクを起動しSTTで音声→テキスト化し、回答できるようにする
- 正解した場合はよくあるピンポン音を出して次の問題へ
- 失敗した場合はTTSで正しい読みを音声出力し次の問題へ

### プラスαで作れたら作りたい
- データはGoogle Spredsheetで管理を行う
- 正解ポイントを記録し、一定数ごとに商品選択画面を表示しお菓子などを選ばせる（そして私の財布が軽くなる）
- Firebaseなどで公開し、部屋に押しかけられていない状況でも勉強できるようにする
- 問題文は青空文庫などから丸っと文章をコピペでもってきてシステム上で形態素解析→漢字ひらがな変換→出題のような流れにする

### 最後に
カレンダー名にもある通りの見切り発車なので最後までちゃんと駆け抜けたいと思います。
開発未着手だったり行き詰った際は今年転職したりしたのでその振り返りや学んだことについての記事で乗り切りたいと思います。
英語単語帳と参考文献の参考文献

AI・機械学習関連論文  Calendar 2024
https://qiita.com/advent-calendar/2024/aiml
Day 16 投稿予定記事です。

投稿予定の方は、購読ボタンを押してください。よろしくお願いします。
記事をお読みになられたら、Calendarにあってもいいかなって記事には、いいね💚　をお願いします。

# 英語単語帳
英語単語帳をつくっているのは、主に次の３つの理由による。
## 知らない単語がない。
自分の論文または、自分が参考文献にあげた論文に、知らない単語があったら、それは、論文の内容の誤解の根源かもしれない。
出現頻度が低く、主要な人名でない場合には、さほど影響はないかもしれない。
最低でも頻度が測定してなければだめだってなった。

## 出現頻度の高い単語の日本語訳を作ってある。
日本語での説明が必要になってから、単語の日本語訳をつくるのはどうよ。
あらかじめ、日本語の候補をあげてあれば、文化依存部分を探索できるかもしれない。

## 機械翻訳の精度をあげるのに貢献する。
ちょっとした機械翻訳ソフトだと、カタカナ語に変換して翻訳しましたって、知らんぷりするのがある。
日本語の候補もしめせないのはなんだかなってなる。

Pat Transorという特許機械翻訳ソフトのプロジェクトにいた人間としての矜持かも。

WRAPLによる機械翻訳のためのテクスト編集と翻訳精度の向上
https://www.anlp.jp/proceedings/annual_meeting/1997/pdf_dir/D5-9.pdf

# 参考文献
参考文献一覧をつくっているのは、次の３つの理由による。

## 文献の入手性の確認
電子的に入手可能かと、国内の図書館に所蔵しているかどうかの確認をする。
５年前までは、毎月国会図書館に通っていて、国会図書館に所蔵している文献は閲覧するようにしていた。

## URLの確認
すでに、リンクが切れていたり、正式のリンクの一部しか記載がないことがある。


## 博士論文
博士論文を書く際に、参考文献の参考文献の参考文献まで調べることにした。
博士論文の参考文献は100　未満にすることを目標とした。
それぞれの参考文献には、0から200くらいの分布で、中央値は２０くらいだった気がする。
さらに、それらの参考文献の参考文献は、同様に0から200くらいの分布で、中央値は２０くらい。

直感的には４万くらいになる。
実際には、一つの文書が200回くらいでてくる。
また、題材によるが、入手できない文献が半分くらいあった。
本文は入手できないが、参考部研だけは電子化されていることがある。

参考文献の参考文献の参考文献の一覧を作るのに。
https://qiita.com/kaizen_nagoya/items/093fa43ed9595190b961

参考文献一覧作成 ファイルの存在とPDFからの変換
https://qiita.com/kaizen_nagoya/items/8edaf4ca410ef2ccdbc7

参考文献駆動執筆(references driven writing)デンソークリエイト編
https://qiita.com/kaizen_nagoya/items/b27b3f58b8bf265a5cd1

技術文献調査法　
https://qiita.com/kaizen_nagoya/items/1eed3b830b5cbbfeed72

参考文献駆動執筆の分類
https://qiita.com/kaizen_nagoya/items/fc2300b3717f61d39dee

参考文献の参考文献は参考文献だ。清水吉男「「派生開発」を成功させるプロセス改善の技術と極意」を超えて
https://qiita.com/kaizen_nagoya/items/562a0cf784cf92bc0ebb

なぜ参考文献に標題、発行年、URLを入れるか
https://qiita.com/kaizen_nagoya/items/f312746485b86a2e4292

References on References on References on "What are the most important statistical ideas of the past 50 years? " Andrew Gelman, Aki Vehtari
https://qiita.com/kaizen_nagoya/items/a8eac9afbf16d2188901

ファインマン計算機科学(参考文献）
https://qiita.com/kaizen_nagoya/items/78391bdcc1727880d613

docker(52) 計算物理学 Rubin H. Landau 参考文献・docker登録
https://qiita.com/kaizen_nagoya/items/af924f5ac71ff5cc8c89

「量子コンピュータが人工知能を加速する」参考文献一覧
https://qiita.com/kaizen_nagoya/items/ca3043e6dd3c99c99ca4

学習と情報の平均場理論　樺島祥介 参考文献一覧
https://qiita.com/kaizen_nagoya/items/a445f68e1468488b2ef8

「ゲーテル・不完全性定理」吉永良正　ブルーバックス　が　不完全燃焼（自分）。参考文献一覧を作成中
https://qiita.com/kaizen_nagoya/items/22dbfc4cea96d14eef3b

「量子アニーリングの基礎」参考文献の参考文献を調べるためにしていること
https://qiita.com/kaizen_nagoya/items/a9a412561caee3852d77

「量子アニーリングの基礎」の参考文献の参考文献
https://qiita.com/kaizen_nagoya/items/2b2fe08b5824c6c3c68d

量子計算機　arXiv掲載　西森 秀稔　論文　参考文献一覧
https://qiita.com/kaizen_nagoya/items/63cd1c6cf7a07b0e9e6f

統計と確率(18) スピングラス理論と情報統計力学　西森秀稔　参考文献
https://qiita.com/kaizen_nagoya/items/702c08becfcca98fa9d8

AUTOSAR文書、参考文献、略号一覧作成自動化の可能性
https://qiita.com/kaizen_nagoya/items/005c4d82d8c1af7ce103

researchgateで文献調査 の参考文献一覧。Wi-Fi(無線網) Antenna(空中線）(4)
https://qiita.com/kaizen_nagoya/items/e7474ca67842565334b1

参考文献駆動執筆の分類
https://qiita.com/kaizen_nagoya/items/fc2300b3717f61d39dee

ある疑問の解決の方法　参考文献
https://qiita.com/kaizen_nagoya/items/d3df667c7d13d4d5b73c
【初心者向けAI解説②！！】RAGとは

AIを使った社内ドキュメント検索のシステムで、よくRAGという言葉が使われています。
今回は初心者向けにそのRAGについて解説を行います！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812370/97be6c6a-9439-729e-7c9a-9e8de3cba952.png)

# 1.はじめに・・
はじめに、LLMの弱点について振り返りましょう。
[【初心者向けAI解説①！！】大規模言語モデルとモデルの種類について](https://qiita.com/JinichiroYoshida/items/d936220013097cf49eb6)で解説した通り、AI
は知らない情報に関する答えは生成できないため、**知らない情報を補足情報としてAIに与えてあげる**必要がります。
RAGとはこれを実現するためのアプローチ方法の１つです。

# 2.RAGとは
Retrieval-Augmented Generationの略で、それぞれ以下のような意味となります。
 - **Retrieval**
     - 情報の検索（社内情報など）
 - **Augmented**
     - 検索した結果で情報を補完
 - **Generation**
     - 補完された情報で回答生成

つまり、LLMが学習していない情報を、**予め検索できる状態（ＤＢ化など）にし、そこから質問内容に応じた適切な補足情報を検索し、その情報を使って回答生成することです。**
RAG自体は概念的なものなので、具体的な実現方法もこの後解説致します。

# 3.Retrievalについて詳しく
### 検索対象でどんなデータ？
ユーザーの**ユースケースに応じて様々**です。
ほんの一例をとしては以下のような感じです。
 - 自社製品のカタログデータ　→　顧客向けオペレーター業務
 - 自社の社内規定データ　→　自社社員向けのナレッジ共有

RAGで解決したい問題や業務に応じたデータが検索対象となります。

### 実行のトリガーは何？
どういうタイミングで検索が行われるのか？についてですが、大きく以下の2パターンとなります。
 - **ルールベースによる制御**
     - ルール（条件）をあらかじめ定義しておき、ルールに応じた検索アクションを実行させる。
     - IF文で実行条件を定義して、システムの設計者自身がコントロールしているイメージです。
     - 特定のユースケースでしか使用しないケースなど、常に決まった情報の検索を行う場合に使われることがありますが、一般的には後述の「AIによる制御」を行う事が多いです。
 - **AIによる制御**
     - AIにはどのような検索対象があるかなどの情報を与えておき、実行するかどうかはAI自身に判断させる方法です。質問内容に応じて必要と判断した検索処理が実行されるので非常に柔軟性が高くなります。
     - 検索用の関数やAPIの仕様を定義して、それをAIが良い感じに実行してくれるイメージで良いです。
     - Function Callingなどの仕組みが該当しますが、これについては別途記事を作成するのでそちらを見て下さい。

### どうやって検索しているのか？
適切な情報の検索はどのように行われるのか解説します。
複数の検索手法が存在するため、今回は代表的なものを紹介します。

 - **ベクター検索（Vector Search）**
 データを**ベクターと呼ばれる数値表現に変換**し、ベクターデータ同士を比較することで**類似度の高い情報を検索する手法**です。例えば、Q＆AデータのQをベクター化して、ベクター化した質問と比較してQと似た質問に対するAを検索することが出来ます。
 - **キーワード検索（Keyword Search）**
 キーワードの部分一致や完全一致で検索を行う手法です。意味的な類似度を比較する訳ではないので、同じ意味で表現の異なる文章や表記ゆれには対応できません。
 - **ハイブリッド検索（Hybrid Search）**
 ベクター検索とキーワード検索を組み合わせた手法です。
 - **グラフベース検索（Graph-based Search）**
 データをグラフ構造で表現して、データ間の関係性を活用した検索手法です。
 これを用いて構築されたRAGはGraph RAGとも表現されることがあります。
 

いろんな検索方法が存在しているため、何を選べばいいんだ？となると思います。
それについては、各検索方法をもっと深堀りし特性を理解する必要があるため、別記事で解説しようと思います。

以上です！

※掲載しているイラストはDALL-Eで作成したものです。
module_functionメソッド

# プライベートメソッドであると同時にモジュールの特異メソッドになる
```rb
irb(main):001* module Loggable
irb(main):002*   def log(text)
irb(main):003*     puts "[LOG] #{text}"
irb(main):004*   end
irb(main):005*
irb(main):006*   module_function :log
irb(main):007> end
=> :log
irb(main):008> Loggable.log("Hello.")
[LOG] Hello.
=> nil
irb(main):009* class Product
irb(main):010*   include Loggable
irb(main):011*
irb(main):012*   def title
irb(main):013*     log 'title is called.'
irb(main):014*     'A great movie'
irb(main):015*   end
irb(main):016> end
=> :title
irb(main):017> product = Product.new
=> #<Product:0x000000010575d810>

irb(main):019> product.title
[LOG] title is called.
=> "A great movie"
```
```rb
irb(main):021> product = Product.new
=> #<Product:0x00000001059a79b8>
irb(main):022> product.log "Hello"
(irb):22:in `<main>': private method `log' called for #<Product:0x00000001059a79b8> (NoMethodError)
```

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

>メソッドをモジュール関数にします。
>
>引数が与えられた時には、引数で指定されたメソッドをモジュール関数にします。引数なしのときは今後このモジュール定義文内で新しく定義されるメソッドをすべてモジュール関数にします。
>
>モジュール関数とは、`プライベートメソッドであると同時にモジュールの特異メソッドでもある`ようなメソッドです。

https://docs.ruby-lang.org/ja/latest/method/Module/i/module_function.html#:~:text=%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%82%92%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB,%E3%81%AA%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%A7%E3%81%99%E3%80%82

# 感想
includeすることによってプライベートメソッドにもなる、特異メソッドにもなる
Androidのアラームについて いまさら気付いたこと

# 最近アラームをいじっていて気になったこと
スマートフォン（Android）で標準インストールされている「時計」アプリ内に、**<font color="RED">アラーム</font>** があるのですが、最近気づいた機能があります。<br>
各設定ごとに、**<font color="RED">Googleアシスタント ルーティーン</font>** を設定できるんです！<br>
皆さん気付いてました？……恥ずかしながら私は最近気づきました。
調べてみると、段階的に導入しているから、いつからあると明言はできないようです。（と、Geminiちゃんが言ってました。）
# Googleアシスタントで何ができる？
便利になってるじゃん！とは思いつつ、私もGoogleアシスタントについてそこまで詳しくないので、Geminiちゃんにできること聞いてみました！

> Googleアシスタントは、あなたの生活をより便利にするための強力なツールです。<br>音声で様々な操作や情報を手に入れることができ、スマートフォンをよりスマートに活用することができます。<br>
> **<font color="YELLOW">Googleアシスタントでできることの一例</font>**<br>
> <dl><dt>情報検索</dt><dd>ニュース、天気、スポーツの結果、株価など、気になる情報を音声で尋ねるだけで、すぐに答えを得られます。</dd><dt>タスク管理</dt><dd>リマインダーの設定、TODOリストの作成、スケジュール管理など、日々のタスクを効率的にこなすことができます。</dd><dt>コミュニケーション</dt><dd>電話をかけたり、メッセージを送ったり、翻訳機能を使って外国語で会話することも可能です。</dd><dt>音楽再生</dt><dd>お気に入りの音楽を再生したり、新しい音楽を発見したりすることができます。</dd><dt>スマートホーム制御</dt><dd>スマートスピーカーやスマート家電と連携し、照明のオンオフや室温調整など、様々な家電を音声で操作できます</dd><dt>ナビゲーション</dt><dd>目的地までのルート検索や、現在地周辺のお店探しなど、移動をサポートします。</dd></dl>
これだけ見ても、かなり便利使いできそうじゃないですか？
ただ、今回は音声で操作するわけではなく、ルーティーンとしてコマンドを設定できるようです。
# 自分に必要そうなものを設定してみた
とりあえず、アラームを設定の中に、Googleアシスタントを組み合わせてルーティーン化できるようなので、設定してみることにしてみました。<br>
色々試してみた上で、以下のルーティーンを設定してみることに。

1. ルーティーン使用時のみデバイスの音量を変更
1. お天気情報の読み上げ
1. 通勤経路の交通情報の読み上げ

設定方法については以下の通りです。

① まずは適当にアラームを設定。
② 設定内容にある［Googleアシスタントのルーティーン］の項目をタップ。
③ 初期設定がされているので、不要な設定を削除。
④ お天気情報の設定だけ残して次へ。

![スライド1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646663/1a655897-66d1-fc79-8f43-9dc9f94bc364.png)

⑤ 画面中央の［アクションを追加］ボタンをタップ。
⑥ メディアの音量調節と通勤経路の交通状況のアクションを追加。
⑦ 各アクションに対する設定をして［保存］ボタンをタップ。

![スライド2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646663/11b8afd4-5de2-64aa-07d4-588ab313d6a8.png)

⑧ アクションによっては個人情報を設定する場合もあるので、検討して設定。
⑨ アクションの実行順を［＝］ボタンを上下にドラッグして移動して変更。
⑩ Googleアシスタント ルーティーンの画面下の［保存］ボタンをタップ。
⑪ アラームの設定内容の［Googleアシスタントのルーティーン］の項目を確認して、左側のアイコンに色がついていて右側の丸いアイコン内が[―]マークに変更されていれば設定完了。

![プレゼンテーション1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646663/227ce76f-4082-2771-bb7d-eb2584fea8bf.png)

設定作業は直感的に設定ができ、意外と簡単でした。
# 実際に動かしてみた！
さっそくアラームの設定時刻を直近に合わせて動作検証してみます！
ちゃんとコマンド通りに動作しました♬

アラームを無音にして活用すれば、定時に通知を無音にする切り替えなど **<font color="RED">設定忘れを防ぐ</font>** ことが出来そうです。

自分でもコマンドをカスタマイズできそうですし、「面白いことを言って」というユニークなコマンドも用意されていましたから、なかなか活用のしがいがありそうです。
# 参考サイト

https://support.google.com/assistant/answer/7672035?hl=ja&co=GENIE.Platform%3DAndroid

https://www.android.com/intl/ja_jp/articles/307/#section-1
エンジニアが知っておくべきネットワークの基礎知識

**現代のシステム開発において、ネットワークの知識はエンジニアにとって必須のスキルです。**

# 1. ネットワークの基礎概念

ネットワークは、デバイス同士が情報を交換するための仕組みです。エンジニアは以下の基本概念を理解しておく必要があります：

**IPアドレス**: ネットワーク上のデバイスを一意に識別する番号です。IPv4とIPv6があり、それぞれの特徴と使用法について理解しましょう。

**サブネットマスク**: IPアドレスをネットワーク部分とホスト部分に分けるための仕組みです。これにより、ネットワークの範囲を特定することができます。

**DNS（ドメインネームシステム）**: ドメイン名をIPアドレスに変換するサービスです。例えば、"www.example.com"を対応するIPアドレスに変換します。


# **2.OSI参照モデルについて**

OSI参照モデルは7つのレイヤー（層）に分けられています。それぞれのレイヤーの名前と役割を理解することで、ネットワーク通信の仕組みを深く理解できます。
物理層：物理的な信号の伝達に関する層です。ケーブルや無線通信のインフラに対応します。
**データリンク層**：隣接するネットワーク機器間のデータ転送を担当します。MACアドレスなどがここで使用されます。

**ネットワーク層**：異なるネットワーク間のデータ転送を行います。主にIPアドレスを使用してルーティングを行います。

**トランスポート層**：データの正確な送受信を保証する層です。TCPとUDPのプロトコルがここで使用されます。

**セッション層**：通信の開始、管理、終了を担当します。通信のセッションを確立し、接続を管理します。

**プレゼンテーション層**：データの形式を変換し、アプリケーションが理解できる形に整えます。暗号化やデータ圧縮などもこの層で行われます。

**アプリケーション層**：ユーザーに直接関わる層で、ウェブブラウザやメールクライアントなどが動作します。


# **3.TCP/IPモデルについて**

**TCP/IPモデル**は、**4つの層（ネットワークインターフェース層、インターネット層、トランスポート層、アプリケーション層**）から成り立っており、実際のインターネット通信に基づいて設計されています。TCP/IPモデルはOSIモデルと比べて実用的で、インターネットでの通信に広く使用されています。
ネットワークインターフェース層：OSIモデルの物理層とデータリンク層を含む層です。物理的な接続とデータリンクを提供します。

**インターネット層**：ネットワーク層に相当し、データがどの経路を通って送られるべきかを決定します。IPアドレスを使ってパケットを転送します。

**トランスポート層**：OSIモデルのトランスポート層と同様、データの信頼性や順序性を管理します。TCPやUDPが利用されます。

**アプリケーション層**：OSIモデルのアプリケーション層、プレゼンテーション層、セッション層をまとめたものです。

# 4. プロトコルの理解

ネットワーク通信には、特定のルール（プロトコル）に基づいて行われます。以下のプロトコルは必ず理解しておきましょう：

**HTTP（HyperText Transfer Protocol**)**はウェブ上で情報をやり取りするためのプロトコルです。データは暗号化されていないため、セキュリティに問題がある可能性があります。

**HTTPS（HTTP Secure**)はHTTPにセキュリティを強化したバージョンです。SSL/TLSによる暗号化を使用し、通信内容を保護します。ウェブサイトへのログインやクレジットカード情報の送信など、機密情報のやり取りにはHTTPSが必須です。

**TCPとUDPの違い**

**TCP（Transmission Control Protocol**）は信頼性の高いプロトコルで、データが正確に順序通りに届くことを保証します。例えば、ウェブページの読み込みやファイルのダウンロードに使用されます。
**UDP（User Datagram Protocol**）は、TCPと異なり、信頼性よりも速度を重視したプロトコルです。データの順序や受信の保証はありませんが、リアルタイム性が求められる通信（例えば、ビデオストリーミングやオンラインゲーム）に向いています。

**FTP（File Transfer Protocol**）について
FTPは、ネットワークを介してファイルを転送するためのプロトコルです。サーバーとクライアント間でファイルのアップロードやダウンロードを行う際に使用されます。ただし、FTPは暗号化されていないため、最近では**SFTP（Secure File Transfer Protocol）**などの安全性が向上したプロトコルが推奨されています。

# 4. ネットワークトラブルシューティング

実務において、ネットワークのトラブルシューティングのスキルは重要です。以下のツールを使えるようにしておくと便利です：

**ping**: 特定のIPアドレスにパケットを送信し、応答があるかどうかを確認するためのコマンドです。接続が正常かを確認する基本的な手段です。

**traceroute**: 通信経路を追跡するためのコマンドで、どこで通信が遅延しているのか、またはどこで遮断されているのかを調べるのに役立ちます。

**netstat**: 現在の接続状況やポートの使用状況を確認できるツールで、問題の原因特定に役立ちます。

# 5. ファイアウォールとセキュリティ

ネットワークのセキュリティを理解することも重要です。

**ファイアウォール**: 内部ネットワークと外部ネットワークの間に立ち、不正なアクセスを防ぐ役割を果たします。ルールベースでパケットを許可または拒否することで、ネットワークの安全性を確保します。

**VPN（仮想プライベートネットワーク）**: 安全にリモートからネットワークに接続するための技術です。エンジニアは、リモートワークやセキュアな通信の確保のためにVPNの基本を理解しておくと良いでしょう。

# 6. クラウドネットワーキング

最近のシステム開発では、クラウドサービスを利用することが一般的です。クラウドのネットワーキングの理解も重要です：

**VPC（仮想プライベートクラウド**）: AWSやGCPで使用される、仮想的なネットワーク環境です。クラウド上でのネットワークの構成やセキュリティ設定ができます。

**ロードバランサー**: クラウド環境で負荷を分散させるための仕組みで、サーバーの安定運用に欠かせません。

# まとめ

ネットワークの知識はシステムがどのように連携し、どのように情報が伝達されているかを理解するために不可欠です。IPアドレスやプロトコルの基本から、クラウドでのネットワーク構成まで幅広く理解することで、エンジニアとしてのスキルを大幅に向上させることができます。これらの知識を習得して、トラブルシューティングやシステム設計に役立ててください！

**最後までよんでいただきありがとうございます。
@y-t0910をフォロー,いいねしていただけると嬉しいです！**
決断するということ

# 今年はポエムじゃない、と言ったな？あれは嘘だ。

私はプロダクトオーナーとその周辺の業務を生業にしているわけですが、プロダクトオーナーの一番の仕事として、「プロダクトの指針を決める」こと、つまり決断することと言うものがあります。

あるとき開発の方に言われたことで印象的なことがあって。
「xxxさんは決めてくれてたからよかった。今のPOは何するにも決めてくれなくて…」
というのがあって、その時はふーん、くらいに思ってたんですが、今になって結構、「決める」って難しいことなんだろうな、と思い始めまして、今回の記事を書くに至るのです。

# 決断 = 判断 + 「覚悟」
今回のテーマ「決断」と似た言葉に判断という言葉があります。それぞれ辞書で調べると、

>【判断】
>物事の内容やあり方、価値などを見比べ、真偽などを考え決めること。

>【決断】
>意志をはっきりと決定すること。
>「決断」は、「決定」「判断」にくらべて、強い意志をもってある結論を下すような場合に用いられる。

といった違いがあるようです。

ビジネス的な決断は多くの場合、何らかの選択肢があり、どれを選べば良いか、という「判断」を行なった上で、よしこれだ！と「決断」する必要があります。この意思を示す、という行為は、理論的に価値を見定めること（つまり、「判断」）によって成り立つわけですが、最後に決めるのはその人の思いによるもの（つまり、「決断」）となるわけです。責任を伴うわけですから少なからぬ「覚悟」を要するわけです。

# 決断することは楽じゃないものよ
覚悟を決めるためには、その覚悟を賭けて良いとする論拠が欲しくなるわけです。それは、みんながそう言っているから、かもしれないですし、いや俺様の過去の経験則上正解だから、かもしれないです。今回は**その良し悪し自体はとかどうでもいい**のですが、何を決めるにしろ、どんな些細なことであっても「決断」ってのは辛くきついことですよね、をテーマにしようかと。

今回このポエムを書くにあたりいくつかのビジネスハウツー的な記事・本を見てきましたが、そのほとんどが記載しているのは、「決断」についての重要な要素は**判断のプロセス**であり、いかに論理的に結論を導くかの訓練法だったり、どうやって選択肢から有力なものだけを抽出するか（逆に言えば不要な選択肢をどう削ぎ落とすか）みたいな方法論なわけですよ。~~まあそうでもしないとセミナー商材としては売りだせないですからね。~~

でも、常日頃こういう決断に迫られる人、そしてそれができていないと感じている人って、そういう情報を求めてるんじゃないと思うんですよね。理論・方法よりも、共感と言えばいいですかね。 **決めるって大変なんだよーーー誰かタスケテYOーーー！！** って言うことを理解してほしい、救ってほしい気持ちの方が大きいと思うのです。

てなわけで、そんな人に送る、少し決断を楽にする方法集をまとめてみました。

# その選択肢が全てなのか？
さて、どちらが良いか？という問いは往々にして迫られるものです。しかしここで一旦深呼吸して、**選択肢から離れて考える癖**をつけましょう。あなたに提示された選択肢はそのとき選べる全ての選択肢でしょうか？

誤った二分法、と言う言葉があります。あなたが取れる選択肢はAかBです。どちらかは正解でどちらかは不正解です。さあ、どっち。
例えば、通販番組で「今買わないと、次からはこの値段では買えませんよ！」と言った喧騒。後から冷静に考えれば、今買わなくても、例えば多少高くなってもあとで買うと言う選択肢があるはずなのに。購入者が知り合いにいればその感想を聞くこともできますよね。

極端な２つに絞った選択肢は判断力を狭め、結果、間違った選択を選んでしまう結果になります。明らかに判断しかねる選択肢が提示されている時は、敢えて他の選択肢がないか、目の前の決断からふと目を背け、**今本当に求められていることは何か、それを探るために他を当たる**ことも必要です。

# 「正解」という罠
誤った二分法の類似の議題ではありますが、もう一つ、**「正解」と言う言葉に囚われること**、これも大きく判断を鈍らせる要素です。
過去を振り返った時、あの時ああしていればよかったなー、と思うことは多かれ少なかれあるでしょう。ただ、振り返りはもう少し深く行なってみましょう。あなたはその時、何故「ああする」ことができなかったのか。

ほとんどが後付けの理由で、その時の少なくとも自分自身での判断材料が不足していたことが原因になるでしょう。もちろん判断ミスのこともあるでしょうが、その判断を間違った理由も突き詰めていけば、「あのことが先にわかっていれば」とならないでしょうか。

結局、その選択が正解だったかどうかなんて後からしかわからないし、不正解には後付けの理由しかつかないものです。決断とは**未知に対する判断を自分の意思で行うもの**でしかありません。「どちらかが正解のはず」と言う思い込みこそが判断を鈍らせる罠になります。**正解なんてないさ**の気持ちで決断していきましょう。

# 最善とは何か
それでもあなたは「最善の手を尽くす」ための選択肢を考えるでしょう。
さて、ここで最善とは何でしょうか。

決断のための判断ポイントには、その決める行為による影響のタイミングと言うものも重要な要素です。あなたの決断の結果は**いつのタイミングで最善の効果をあげる** でしょうか。そして、その**想定タイミング以外でその決断は最善になる**でしょうか。

ほとんどの場合、後者の質問はNOになります。イメージをあげると、「今は苦しいけどここを乗り越えた時のために、今、手を打っておこう。」「今週リリースのために善後策としてやる。来週以降で直していこう。」みたいな。

要は決断というのは今見える範囲でのどこかのタイミングで良くなるように想定して行うことになります。ですので、それとは異なるタイミングでは良くならない、寧ろ悪くなる可能性だってあるわけです。全てに完璧に最善になる手ってのはそうはありません。もちろん、先ほどの話題の通り、未知への判断によるものですので、そのタイミングが来るかどうかもわかりません。

ここで大切なのは、どのようなストーリーで、そして、どのようなタイミングで最善となると考えたか、その**検討プロセス**です。それをしっかり持てることが、世の中では「**軸がぶれない**」と呼びます。おそらく多分。知らんけど。

# そして、決断は楽しい。

決めることは辛いですか？人に任せたいですか？
私は辛いこともありますが、それでも自分で決められることがあるなら決めていきたいです。

SF系に「並行世界」みたいな概念がありますよね。自分が選ばなかった世界線と自分が選んだ世界線。決断することはそんな世界線をその都度作ってるんだな、と思うとワクワクしませんか？
決断は辛く厳しいことかもしれないですが、自分で決められることって楽しいことのはずです。どうせ決断に迫られるなら、気持ちは楽しく、無駄にいっぱい並行世界を作ってやってるぜ！とか思いながら進めましょう（？）
【TypeScript】インデックスアクセスの落とし穴

# 問題のコード
突然ですが以下の2つのコードのおかしな点、分かりますか？
```typescript
const arr = [1, 10, 100]
const num: number = arr[100]
```

```typescript
type ObjectLiteralLike = {
    [lang: string]: string;
};

const butterfly: ObjectLiteralLike = {
    en: "Butterfly",
    fr: "Papillon",
    it: "Farfalla",
};

const mariposa: string = butterfly.es
```

## 答え合わせ
それぞれ、`arr[100]`と`butterfly.es`は`undefined`にも関わらず、`number`, `string`として宣言されています。
しかし、これらの間違いは（デフォルト設定の）TypeScriptでは**型宣言ミスとして検知してくれません。**
```typescript
console.log(num) // undefined
console.log(mariposa) // undefined
```


# これは何が問題なの？
コンパイル時にエラーが出ないため、次に示すようなコードはに実行時にエラーが発覚することになります。
というか、一度TypeScriptの型と実際の状態に不整合が生じた時点で、それ以降のコードにおけるTypeScriptが持つ型安全性は機能しなくなります。
```typescript
type ObjectLiteralLike = {
    [lang: string]: string;
};

const butterfly: ObjectLiteralLike = {
    en: "Butterfly",
    fr: "Papillon",
    it: "Farfalla",
};

const mariposa: string = butterfly.es
console.log(mariposa.toUpperCase()) // <- 実行時にエラー!!
```

# ではどうするべきなのか？
このような、型チェックに引っかからない`undefined`を防ぐための対策を2点挙げます。
## 1. `noUncheckedIndexedAccess`を利用する
Typescriptのコンパイラオプションにはチェックの厳しさに関わる追加設定として`noUncheckedIndexedAccess`があります。これを有効にすると、インデックス記法でアクセスした場合に`undefined`型とのユニオン型として解釈されるようになります。
```typescript
// Type 'number | undefined' is not assignable to type 'number'.
const num: number = arr[100]

// 正しい型宣言
const num: number | undefined = arr[100]

// Type 'string | undefined' is not assignable to type 'string'.
const mariposa: string = butterfly.es

// 正しい型宣言
const mariposa: string | undefined = butterfly.es
```

こうすることで、先ほど実行時に発生したエラーを事前に検知できます。
```typescript
// 'mariposa' is possibly 'undefined'
console.log(mariposa.toUpperCase())
```

::: note info
`noUncheckedIndexedAccess`は`for-of`や`array.forEach()`には適用されず、これらは`undefined`を考慮せず処理を継続できます。

```typescript
const phoneticCodes: string[] = ["alpha", "bravo", "charlie"];
 
for (const p of phoneticCodes) {
  // 通常通り動作
}
 
phoneticCodes.forEach((p: string) => {
  // 通常通り動作
});
```
:::
## 2. Mapped Typesを利用する
入力の形式が決まっているのであればMapped Typesを使用することで型の安全性を高められます。
```typescript
// 予めキーの候補を列挙
type SystemSupportLanguage = "en" | "fr" | "it";

type ObjectLiteralLike = {
    [key in SystemSupportLanguage]: string;
};
const butterfly: ObjectLiteralLike = {
    en: "Butterfly",
    fr: "Papillon",
    it: "Farfalla",
};

// Property 'es' does not exist on type 'ObjectLiteralLike'
const mariposa: string = butterfly.es
```

# まとめ
- TypeScriptのインデックスアクセスには`undefined`に関する型安全性の落とし穴がある
- `noUncheckedIndexedAccess`やMapped Typesを利用して安全性を高めることができる

# 参考文献
[プロを目指す人のためのTypeScript入門](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%92%E7%9B%AE%E6%8C%87%E3%81%99%E4%BA%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AETypeScript%E5%85%A5%E9%96%80-%E5%AE%89%E5%85%A8%E3%81%AA%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9%E3%81%8B%E3%82%89%E9%AB%98%E5%BA%A6%E3%81%AA%E5%9E%8B%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9%E3%81%BE%E3%81%A7-Software-Design-plus/dp/4297127474)

https://typescriptbook.jp/reference/tsconfig/nouncheckedindexedaccess

https://typescriptbook.jp/reference/type-reuse/mapped-types
新卒エンジニアは、入社までに何を学んでおくと良いのか？

# はじめに
- この記事は、[Ateam LifeDesign Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ateam-life-design)の2日目記事です
- 記事の内容は投稿者個人の見解であり、会社としての公式見解ではありません

# 新卒面接でよくいただく質問
- 新卒面接に8年ほど関わらせていただいていますが、逆質問でよくいただく質問があります

**「もしご縁があって入社させていただく場合、入社までに学んでおくべきことはありますか？」**

# 結論
- その質問に対し、私は「コンピュータサイエンスの基礎知識」と回答することが一番多いです
    - 例として、基本情報技術者試験や応用情報技術者試験を挙げることがあります
        - （既に合格済みの場合は、別の回答をします）

# 理由
- 前提として、
    - 新卒に求める知識や技術レベルは企業によってバラバラ
    - 新卒本人の知識や技術レベルも当然バラバラ
- なので、全員に対して共通して言える一つの答え…みたいなものは存在しません
- その上で、以下3要件を満たすのが「コンピュータサイエンスの基礎知識」と考えています
    1. **「重要なスキル・知識である」**
    1. **「新卒研修やOJTで学ぶ機会が無い」**
    1. **「入社までの期間で習得可能」**

## エンジニア職に必要なスキルの区分
- まず、エンジニアに必要な知識やスキルが何か、カッツ・モデルをベースに独自区分してみました
- MECEではないので、各区分はだいたいのイメージだと思ってください

![ベースモデル](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199678/3a62f683-82a8-3981-e65d-ceb2852c6892.png)

## 新卒エンジニアが、必要なスキルをいつ・どこで身につけるか

- **自社レイヤー（自社×コンセプチュアル、自社×ヒューマン、自社×テクニカル）**
    - 入社後じゃないと難しい側面があるので、新卒研修で身につけていただくことが多いです
    - 入社前はコーポレートサイト・IR情報や社外記事などの公的情報しかアクセスできないため、得られる知識やスキルは限定的になってしまいます
- **ビジネスレイヤー（ビジネス×コンセプチュアル、ビジネス×ヒューマン、ビジネス×テクニカル）**
    - 新卒社員の場合はビジネスレイヤーがほぼゼロ知識のことも多いため、新卒研修で全員まとめて身につけていただく方が良いと考えています

![色分け](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199678/443e6787-2c02-b370-bbed-b166b5f74574.png)

- 残るは**職種・業界レイヤー（職種・業界×コンセプチュアル、職種・業界×ヒューマン、職種・業界×テクニカル）**
    - 新卒エンジニアとして採用させていただいている以上、職種・業界×テクニカル（プログラミングの基礎知識など）は一定お持ちのはずです
    - 職種・業界×ヒューマン（コミュニティの発信力や影響力）は、一朝一夕でできるものではないです
    - となると、 職種・業界×コンセプチュアルスキル（≒コンピュータサイエンス基礎）は、 **「重要なスキル・知識である」「新卒研修やOJTで学ぶ機会が無い」「入社までの期間で習得可能」が重なる領域** のため、オススメしています

## コンピュータサイエンス基礎を身につける意義
- 職業としてのエンジニアの場合、趣味や研究でプログラミングしていた頃とは異なり、チームでコミュニケーションを取り、課題解決や成果を出すことが不可欠になります
    - その際に、コンピュータやWebサイトはどのように動くのか？といった概念を理解しているか、用語をどれだけ知っているか等でコミュニケーションの質と量は大きく変わってきます
    - 例えば、英語が苦手な方との会話をイメージしてみてください
        - たまに分からない英単語があるぐらいなら、その場で調べたり聞けば会話になります
        - ですが、英文法分からない、英単語全然分からない…だと、会話が成立しません
    - つまり、コンピュータサイエンスについて理解度が低いと、先輩の会話が全然理解できず成長スピードが鈍化しかねないです
- もちろん社会人になってから学ぶこともできますが、腰を据えて基礎を勉強するなら、まとまった時間が取りやすい学生時代の方が適していると考えています

# 終わりに
- 近年、ChatGPTやGitHub Copilot、Cursor AI等のAIを用いたプログラミングが急速に一般化しました
    - それらを使えば、「とりあえず動くプログラムを作る」ことは誰でもできる時代です
        - つまりプロのエンジニアとしてお金をいただくためには、AIができる仕事以上の付加価値を生み出す必要があります
        - そのうちの一つが、コンセプチュアルスキルだと考えています
    - また、機能要件や非機能要件を満たしているか、パフォーマンスやセキュリティ要件を満たしているか等の多角的な観点から、AIの出力したコードの品質を評価するにも知識が必要です
    - AIに与えるプロンプトもコンセプチュアルスキルが問われるため、概念を理解した上でAIと共存し、付加価値を生み出せるエンジニアが増えていくことを願っています
Django プロフェッショナル webプログラミング #3 -templateはじめの一歩-

※以下の企画です

https://qiita.com/tatataichi/private/56936a028e625e62af8e

前回に続いてpart2の続きをやっていきます。
今回はテンプレートの作成がメインになりそうです。
HTML/CSSの初歩的な内容が多そうなので、要所だけまとめて記載していきます〜

# Part2③
## テンプレートを作ってみる
とりあえず本書の内容に従ってテンプレートを作成していく。
以下は写経した内容。

```html:article.html
<h1>ニュースサイト</h1>
<h2>{{title}}</h2>
<p>{{content}}</p>
```

```python:views.py
from django.http import HttpResponse
from django.template import loader

def article(request):
    template = loader.get_template('article.html')
    context = {
        'title':'記事のタイトル',
        'content':'記事の本文'
    }

    return HttpResponse(template.render(context,request))
```

```python:urls.py
from django.urls import path
from . import views

app = 'first_app'
urlpatterns = [
    path('',views.index, name='index'),
    path('page/<int:page_id>/', views.page, name='page'),
    path('article/', views.article, name='article'),
]
```

上記のように`article.html`を作成。
この後はこの子を改造しながら学んでいくスタイルっぽい。

さらっと流されている大事な部分としては、`views`で`context`として返している値を`template`側で表示するには、htmlファイル上で`{{  }}`を記載すればいい。

## インクルード
テンプレートを増やすたびに`footer`やら`header`やらの共通する内容を何度も記述していくのは非効率的だ。
なので、djangoだと`include`という仕組み？を用いて共通ファイルを用意すればそれを呼び出すだけで良いようにしてくれている。
記述方法は至ってシンプルで、読み込みたいファイルを`{% include 'ファイル名' %}`とするだけ。

```html:article.html
{% include 'header.html' %}

<article>
<h1>ニュースサイト</h1>
<h2>{{title}}</h2>
<p>{{content}}</p>
</article>

{% include 'footer.html' %}
```

```html: header.html
<header>
    <h1>ニュースサイト</h1>
</header>
```

```html:footer.html
<footer>
    <small>(c)ニュースサイト</small>
</footer>
```

開発サーバー(`/article`)にアクセスしてみると以下の画像のようにちゃんと`header`も`footer`も反映されていることがわかる。

![スクリーンショット 2024-12-01 18.50.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2255713/28a116ec-6a41-6ede-af7b-a77dbb86c8dd.png)

# まとめ
今回は割とあっさりめの内容だったが、すべてのtemplateの原理原則的な内容だった。
変数のやりとりは肝になっている機能だと思うので、落ち着いてちゃんとコーディングできるようにしていく・・・

次回もがんばろ〜〜
SIer→事業会社の転職で後悔しないために気をつけるべきこと

# はじめに
はじめまして。私は30代後半のITインフラエンジニアです。SIerでのキャリアをスタートし、数年前に事業会社へ転職しました。
転職活動を始めた理由は、ビジネス視点を養い、技術により深く関与したいと考えたためです。このため事業会社やITコンサルティング企業を志望し、ありがたいことに複数の企業から内定をいただきました。その中でも今の事業会社を選んだ理由は、当初の動機に加え「**この環境なら自分の力を発揮できそうだ**」と感じたためです。

しかし、事業会社で働いて数年が経過した今、「**この環境で将来もやっていけるか**」という疑問を抱くようになりました。この記事では、SIerから事業会社への転職を考えている皆さんに、後悔しないための注意点を私の実体験をもとにお伝えします。

なお、記載内容は個人の考えに基づいており、参考情報としてお読みください。

# SIer→事業会社への転職
転職活動中、私は徹底的に準備を行いました。特に内定後のフォローアップ面談に重きを置き、入社後の業務内容や将来性について入社後上長になる方や部署のメンバーから具体的な話を伺いました。その結果、「現時点のスキルで業務をこなせそうだ」、「部署の雰囲気に馴染めそうだ」と感じ、入社を決意しました。

# 入社後のギャップ
事業会社での業務は、SIerでの経験の延長線上にあると考えていました。しかし、実際に働いてみると業務の背景や動機、環境がSIerとは大きく異なると実感しました。以下に感じた主なギャップを挙げます。

## ゴールの違い
所属部署にもよりますが、SIerでは、**顧客と合意したプロジェクトを計画通りに完遂することが主な業務の目標**と考えています。一方で事業会社では、**提供サービスの成功**に重きが置かれます。計画通りにプロジェクトを推進したとしても、そのサービスに実用性がない場合、案件としては上手くいった、とは言えない状況だと思います。この違いは、日々の業務の優先順位にも大きく影響します。

## 技術選定
SIerは、あくまでプロジェクトを計画通りに完遂することが目的なため、**技術選定の際も比較的枯れた技術を好みます**。事業会社では、知見獲得のために使用経験のないサービスを採用することもあるなど、**幅広な技術選定がSIerよりもハードル低く出来ると感じます**。
これには、最新トレンドにアンテナを張り、様々なサービスに関する知識を日々獲得する必要があります。技術カンファレンスへの参加・登壇、技術コミュニティへの参加や発信が、SIerよりも重きがあると感じます。

## 少数・短期対応
事業会社で私が携わっている内製案件では、インフラ業務を1～2名で担当し、約4～5か月程度でリリースすることがよくあります。この1～2名でアーキテクト設計から運用までを対応する必要があり、幅広い知識が求められるため、メンバーの力量に大きく依存します。このため、SIerのようなチームでの協力体制とは異なる働き方を求められる場合があります。
負荷は高いものの、**事業会社では車輪の一部として働く、というよりは車体全体を俯瞰し動くため、全体感の視野を持てることや、幅広い業務経験を積めることが良い点だと感じます**。

## 人の固定化
事業会社では、**少人数で長期間同じメンバーと働くことが一般的です**。これにより、メンバー間の関係性が密接になりますが、新しい人と関わる機会が減る傾向にあります。
ただ、ここは考えようであって、私が所属する事業会社では月ごとに社内のコミュニケーションづくりのイベントがあります。こういったイベントへ積極的に足を運ぶことで、新たな関係性を築けはするため、メンバーが固定化し脱却できない、という状態ではありません。

# 後悔しないための注意点
以上のように事業会社での業務自体はSIerと似ていますが、その環境は大きく異なります。**良い・悪いというわけではなく、それぞれの特徴を理解し、自分の特性や働き方の好みを把握した上で、合った環境を選ぶことが重要だと考えます**。
私は、チームリーダーとして多様な人々と協働し、比較的安全な技術を元に自身にとって新しい経験ができる業務にやりがいを感じています。このような性格と事業会社のカルチャーにはギャップがあると気づきました。

次回の転職では、自身の価値観に合った企業を見極めるため、次の観点を重視したいと思います：
* チームの規模と働き方
    * 小規模なチームで主体的に動ける環境が望ましいのか、大規模なチームで協力を重視する環境が良いのかを見極める必要がある
* プロジェクトの進め方と柔軟性
    * 管理されたスケジュールの中で着実に推進することが好みか、目標に向かい適宜方向性を模索しながら進めることが望ましいかを見極める必要がある
* 業務の中で新しい挑戦が可能か
    * 一般的に新規性がある業務の実施に加え、広く一般的ではあるものの自身にとって新しい経験ができる業務かどうかを見極める必要がある

# まとめ
SIerと事業会社には明確な違いがあるものの、どちらが良いかは個々の価値観次第です。自分の特性に合わせて選択肢を絞ることが大切です。
GitHub Actions で、レビューが完了してないプルリクに対してリマインドする

エンジニアは忙しいとプルリクエストのレビューを後回しにしがちで、レビュー待ちのプルリクがどんどん溜まっていってしまうため、レビューを優先して行う時間を作ることに決めました。

ただそれでも忘れるのが人間という生き物なので、GitHub Actions でリマインドを行ってレビューを促したいです。

# Action の概要
プルリクエストの一覧を取得して、レビューを行っていないレビュワーがいるプルリクエストに対して下記のようなコメントを挿入してレビューを促すようにする

```
@kazumacchi
レビューお願いいたします
```


## GitHub Workflows

完成品は下記の通り

```yml
name: Review Reminder

on:
  workflow_dispatch:
  schedule:
    # UTC なので動かしたい時間の +9時間を加算
    - cron: '0 1 * * 2'

jobs:
  notify_reviewers:
    permissions:
        pull-requests: read

    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      # プルリク一覧を取得、レビューが完了してないレビュワー一覧も取得
      - name: Get open pull requests
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          curl -H "Authorization: Bearer $GITHUB_TOKEN" \
              -H "Accept: application/vnd.github.v3+json" \
              https://api.github.com/repos/${{ github.repository }}/pulls \
              | jq '[.[] | select(.requested_reviewers | length > 0) | {number: .number, title: .title, url: .html_url, reviewers: [.requested_reviewers[].login]}]' \
              > pull_request.json

      - name: Notify reviewers
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          # pull_request が取得できない場合は終了
          if [ ! -f pull_request.json ]; then
            echo "pull_request.json が存在しません。処理を終了します。"
            exit 1
          fi

          cat pull_request.json | jq -c '.[]' | while read -r row; do
            # 必要な情報を取得。現状は reviewers と pr_number だけ使用
            # メンションしたいので、reviewr のユーザー名の頭に @ を付与
            pr_number=$(echo "$row" | jq -r '.number')
            pr_title=$(echo "$row" | jq -r '.title')
            reviewers=$(echo "$row" | jq -r '.reviewers | map("@\(. // empty)") | join(" ")')

            # レビュワーが空の場合はスキップ
            if [ -z "$reviewers" ]; then
              echo "PR #${pr_number} にはレビューが完了していないレビュワーは存在しません"
              continue
            fi

            message="${reviewers}\nレビューお願いいたします。"

            # コメントの送信
            response=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
              -H "Authorization: Bearer $GITHUB_TOKEN" \
              -H "Content-Type: application/json" \
              -d "{\"body\": \"$message\"}" \
              "https://api.github.com/repos/${GITHUB_REPOSITORY}/issues/${pr_number}/comments")

            # レスポンスコードを確認
            if [ "$response" -eq 201 ]; then
              echo "PR #${pr_number} へのレビュー依頼が完了しました"
            else
              echo "PR #${pr_number} へのレビュー依頼に失敗しました"
            fi
          done
```
エンジニアの在り方とChat GPT Search

### はじめに

近年、[ChatGPT](https://chatgpt.com)や[Chat GPT Search](https://openai.com/index/introducing-chatgpt-search/)のようなAIツールがエンジニアリングの現場で急速に普及し、コーディングや技術リサーチの補助役として注目されています。しかし、これらのツールが「全知全能の答え」を提供してくれる魔法の杖ではないことを理解するのが重要です。本記事では、これらのツールとの向き合い方を再考し、エンジニアが真に活用すべきリソースについて考えます。

### ChatGPTやChat GPT Searchの位置づけ

まず理解しておきたいのは、ChatGPTやChat GPT Searchは「それっぽいこと言う大学生」のような存在だということです。これらは膨大なデータに基づいて推測された回答を提示しますが、専門的なドキュメントやガイドラインに比べると、その内容には以下のような限界があります。

- コンテキストを間違える可能性がある
- 情報が最新でない場合がある
- 正確性や信頼性が保証されていない場合がある

したがって、これらを「教科書」として扱うのは不適切であり、公式ドキュメントやコミュニティで議論されるベストプラクティスを参照することが不可欠です。

### 公式ドキュメントを武器にする

エンジニアがAIツールとの差別化を図る最大の武器は、「公式ドキュメントを読み解き、引用する力」です。  
公式ドキュメントは、開発者がその技術やツールを最大限に活用するために用意された最も信頼性の高い情報源です。しかし、以下の理由から、意外と軽視されがちです。

- ボリュームが多い
- 英語で記述されている
- すぐに結果が得られない（調査に時間がかかる）

ここでエンジニアが優位性を発揮できるポイントは、公式ドキュメントをいかに迅速かつ正確に解釈し、それをコードや設計に反映させるかという「引用力」です。

例えば、エラーメッセージを検索してChatGPTやChat GPT Searchに頼るだけでなく、そのエラーの原因を公式ドキュメントで掘り下げる。このプロセスを丁寧に行うことで、表面的な「解決策」だけでなく、長期的に役立つ「知識」が得られます。

### 実装で求められるもの

エンジニアが新しい実装に取り組む際に本当に必要なものは、以下の3点です。

1. **ベストプラクティス**  
   コミュニティや業界標準で広く採用されている手法。AIツールに聞きつつ、公式ドキュメントや専門家の意見を参考にすることで、最適な方法を見つけることができます。

2. **公式ドキュメント**  
   技術の設計思想やAPIの仕様を詳細に理解するための基本資料。これを読み解くことで、AIツールの回答が正しいかどうかを判断できます。

3. **長所と短所の比較**  
   実装を進める上で、選択肢の中から最適な方法を選ぶには、それぞれのアプローチのメリット・デメリットを正しく評価する力が求められます。AIツールの回答を参考にしつつ、自らの判断力を磨くことが重要です。

これらを軸に判断することで、AIツールの助言が正しいかどうかも判断できるようになります。ChatGPTやChat GPT Searchは便利なガイド役であり、全てを鵜呑みにするのではなく「選択肢を増やす存在」として活用すべきです。

### 結論

ChatGPTやChat GPT Searchは確かに便利ですが、公式ドキュメントを読み解き、ベストプラクティスを実践できるエンジニアこそが長期的に差をつけられる存在です。AIツールに頼りきるのではなく、必要な情報を的確に調査し、長所短所を吟味する「選択の力」を磨くことで、エンジニアとしての本質的なスキルを強化していきましょう。

「それっぽいこと言う大学生の話を鵜呑みにする」のではなく、「それっぽいこと言う大学生の話を参考にしつつ、公式ドキュメントを探し、ベストプラクティスを追求する」。
その在り方こそが、これからのエンジニアに求められる姿勢ではないでしょうか。
輪読会は少人数で行うのが吉だと考えている

トグルホールディングス（以下、トグル）でデベNAVIチームのスクラムマスター兼エンジニアとして働いている君田（君田）です。

トグルホールディングスエンジニアアドベントカレンダーの16日目の記事です！（2本目の投稿になります..）
今回は今年の7月から細々と続けていた輪読会についての内容とメリットについて書いていこうと思います！


## 輪読会とは？
以下引用です。
>参加者が特定の書籍や資料を分担して読み、それについて意見交換や議論を行う形式の勉強会や読書会のことを指します。主に、技術書や専門書、研究論文などの学術的な内容を対象とする場合が多いです。

一般的にはこのようにされています。

## どんな形式で進めていた？
- 参加人数は自分を含めて2人
- 毎週1回30分程度で集まって話時間を取る
  - 毎週決めた範囲の内容を2人で読んでくる
  - 自分が面白い・役に立つと思った内容をまとめて共有する
    - Notionを利用していました


上記のような形式で行なっています。以下のような形でメモを残して共有していました。

![スクリーンショット 2024-12-01 17.41.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374292/b58588ab-5d61-59a8-7dc2-6a1b1382a5e3.png)
![スクリーンショット 2024-12-01 17.41.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374292/33eaa4f4-76fa-a459-7dd5-77ceb9f2ac79.png)

内容メモはこんな感じです。

![screencapture-notion-so-14a75d10b7ee44d3b02df1def70ab307-2024-12-01-17_42_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374292/924361a5-9c2d-8568-aa94-af4cea42db28.png)

7月から初めて現在3冊目に突入していますが、以下の本を輪読会の題材にしてました。
1. [プリンシプル オブ プログラミング3年目までに身につけたい一生役立つ101の原理原則](https://amzn.asia/d/ficfN8X)
2. [SCRUMMASTER THE BOOK 優れたスクラムマスターになるための極意――メタスキル、学習、心理、リーダーシップ](https://amzn.asia/d/6mSAtdu)
3. [SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム](https://amzn.asia/d/aP65sMd)
⇨ 現在絶賛読んでいる最中


## 輪読会のメリット
#### 学びを得ることができる
これはもちろん本を読むので知識がつき、学びを得られます。輪読会に限らず読書のメリットですね。
また、学びを記録に残すという手法は効果的だと思います。読んで終わりだとどうしても忘れてしまうため定期的に振り返ることのできるメモは必要かと思います。せっかく読んだ本の学びを忘れないためにも重要な要素です。

#### 「約束した」という効力が読書を強制させる
これが1番のメリットだと思います。Youtube や Netfilex, Amazon Prime Video など現代は受動的なエンターテイメントが溢れかえっています。よほどの意志力や継続力がないと読書はなかなかそれらを超えることができません。
しかし、「毎週決められた量の本を読みその感想と気づきを共有する会」が設けられている状況だと自然と読書するようになります。これが約束の力です。
これは読書に限った話ではなくたとえばジムを例に挙げると、ジムに入会した人のトレーニングの継続率は30～50%と言われています。それに対し、パーソナルトレーニングは継続率が70～90%と言われています。人間の心理的にも誰かとの約束事は守るという力は強く働くためです。この効力は輪読会にも当てはまります。

かくいう自分もなかなか読書の習慣がつけられず、本を買って満足するなんてこともありました。いわゆる積読というやつです。毎日1ページ、10分でも良いから読書しようと思ってもなかなか続けられず積み上げられていく本だけが増えていくような状況でした。

ただ、この輪読会を実施してからは毎週必ず読書するようになりましたし、自発的に本を読みたくなりました。最初は約束の効力で読書していましたが、今やそれが徐々に習慣になり、輪読会で読む本以外の読書も捗っています。

自分のように気合を入れて本を買ったはいいが、積読状態になってしまう人には輪読会はおすすめかもしれません。本に触れる機会を増やし、抵抗が減ります。

## これから輪読会を始めたいと思っている人たちへ
約半年間の輪読会を通してこれから輪読会を始めたいと思っている人たちへ自分が思っているポイントは1つです。
ズバリ、、、、、、「**輪読会への参加者はできるだけ少人数の方が良い**」です！
なぜそう考えるかの理由を書いていこうと思います。

1. 学びたいテーマの統一が簡単
少人数であればあるほどのテーマの統一は簡単です。大人数になれば意見がたくさん出てくるので自分の興味のないテーマになってしまうこともあるでしょう。その点で少人数の方が良いと考えています。

2. 約束の効力は少人数であればあるほど強く働く
大人数であればあるほど約束の効力は薄まると思っています。輪読会の形式がそれぞれ同じ部分を読んできてそれについて話し合うだったからです。これが大人数になった場合発言をしないで誰かの発表を聞いているだけになる可能性があります。これだけでも意味はあると思いますが、効果が薄いと考えます。
ただ2人であれば、どちらかが読んでこないと輪読会とした成り立たないので必ず読んでくるしかなくなるわけです。

3. なんとなく参加がなくなる
自分たちが学ぶために本を読み、学びをシェアするという目的薄れないです。大人数での開催だと、なんか全員参加してるし自分も一応参加しとくか、というスタンスが生まれてしまうものだと思います。（自分もそのような経験あり）少人数であればあるほどしっかりと目的を持った良い輪読会を継続できると思います。


## これからやりたいこと
現時点で2冊の輪読が完了しています。読む人が違うとそれぞれ違う感想や気づきを抱いていたり、逆に同じような感想を抱いていたりと面白いです。せっかくメモとして残しているので、そのメモを整形しどこかにアウトプットしたいと考えています。読んだ本の復習にもなるし、そのアプトプットが誰かの学びにつながるかもしれないし一石二鳥だと。

## 最後に
今まで輪読会はなんとなく大人数で行うもしくは、同じチームメンバー全員で行うのが良いのかなと思っていましたが、結果的に少人数で開催する方が個人的にはメリットを感じました。ケースによっては大人数でやるしかない時もあると思いますが、これから輪読会や勉強会などを行いたいと考えている人たちはチャンスがあればできるだけ少人数で開催することをお勧めします！
モジュールに特異メソッドを定義する

# `モジュール名.メソッド名`という形でメソッドを呼び出せる
```rb
irb(main):001* module Loggable
irb(main):002*   def self.log(text)
irb(main):003*     puts "[LOG] #{text}"
irb(main):004*   end
irb(main):005> end
=> :log
irb(main):006> Loggable.log("Hello.")
[LOG] Hello.
=> nil
```
# `class << self`でも呼び出すことができる
```rb
irb(main):001* module Loggable
irb(main):002*   class << self
irb(main):003*     def log(text)
irb(main):004*       puts "[LOG] #{text}"
irb(main):005*     end
irb(main):006*   end
irb(main):007> end
=> :log
irb(main):008> Loggable.log("Hello.")
[LOG] Hello.
```

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