ChatGPT にカレンダー生成プログラムを作ってもらった

## 経緯
### キンコーズ のオンラインカレンダー受付が無い、だと？
ここ数年 [キンコーズ](https://www.kinkos.co.jp/) のオンラインサービスでオリジナルカレンダーを作ってたんですが、2025年のカレンダーを発注しようと思ったらどういうわけかページが見つからない。あれこれ調べると「受付　店頭のみ」となっているじゃないか…

仕方ない、店頭に画像データを持っていけば作ってくれるんだな、ってことで赴いて発注したのですが、行って発注しなきゃならんのはめんどい。しかもすぐ印刷してくれるわけでもないので後日受取が発生する。

だったら当日行って即印刷、あるいはオンラインで原稿（版下）送って印刷物納品、の方が良くないか？と考えたのですが、以前似たようなことをやって結構面倒だったことを思い出しまして。
### 過去の事例
というのもカレンダーのデータを自在にデザインして、365個の日付を並べ、祝日データを調べて、という作業が地味に面倒で、さらに間違いが発生するという憂き目にも遭い。だったらオンラインサービスのテンプレに放り込んだほうが楽だなーと。でも他の会社に依頼すると妙に高くつきそうだったので、何故かリーズナブルなキンコーズに毎年依頼していたのです。面倒な自作デザインカレンダーの印刷をやったときもキンコーズに依頼していたという御縁もあったり。

### 面倒な作業は AI に任せる
そう言えば ChatGPT のコード生成機能がそろそろマジで実用的になったということを思い出しまして。地味に面倒な作業なんて、AI に任せればいいじゃない、が通る時代になりましたよね。
その前に考えていたのが SVG のカレンダーを出力できるプログラムを以前作ったことあったな、というやつでして。これの出来がイマイチだったために廃れさせてしまい、コードもどこかやっちゃったので作り直すかー。…あれ、これを ChatGPT に任せれば早いのか、と気がついた次第でして。

## 設計
### ChatGPT に任せるべき範囲とは
そもそものデザインは自分でやりたいから、自作のカレンダーなんて作ろうとするんですよ。なので ChatGPT に任せるのは「配置」です。要素を置くルールを教えるから、配置するコードを出力してくれ、となります。
また私は Python と非常に相性が悪い。しかし ChatGPT は Python が大好きらしく、自在にコードを出力してくれますのでお任せするなら Python やってもらおうじゃないですか。上手くできたら公開もできますし、Python 使ってくれる人はたくさんいますし、プラットホーム依存少ないですし。
### ルール設計
JW-CAD を使ってまずどんなカレンダーにするかを図面に起こします。
今回のカレンダーはこんな感じにします。
![スクリーンショット 2025-01-06 154544.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403596/5566f0ba-0428-3a1f-cb5f-e131593bdb11.png)
ってこの画像は生成されたものなのでネタバレみたいなものなんですが、この配置を図面化して寸法を入れます。そして ChatGPT への指示に詳細に盛り込みます。

```
SVG を利用した印刷用カレンダー自動生成プログラムを pythonで作りたい。
* 12ヶ月分のカレンダーをそれぞれ別の SVG ファイルにする。ファイル名はYYMM.svg 形式で、例えば2025年1月なら 2501.svg となる。
* カレンダーの対応国は日本限定。
* 祝日、休日情報はクラウドから得たい。
* カレンダーのフォーマットについて
** 用紙は A3、周囲20mmを余白とする。
** 上部に縦226mm横226mmのjpg画像を取り込み配置する。画像名は YYMM.jpg とする。
** 画像の下部にカレンダーの日付を配置する。月は数字、曜日は SUN/MON 形式とする。
** 日曜は赤、土曜は青、他の平日は黒の文字色。
** 前後の月のカレンダーも表示する。
*** 前後の月のカレンダーでは曜日の文字列は無し。色分けだけ共通とする。
*** 前後の月のカレンダーでは月の表示はある。
** フォントの基準位置は text-anchor="middle" dominant-baseline="text-after-edge"
** フォントサイズはソースコード上で調整しやすい位置で宣言
** 各座標値を決める。
*** 原点は用紙の左上とし、用紙右下を(297,420)とする。
*** 画像の左上の座標 (30,20)
*** 月のテキスト位置は (45,300)
*** 曜日のテキスト位置は (84,270)、そこから右へ等間隔に 28mm
*** 日のテキスト基準位置は (84,295)、そこから右へ等間隔に 28mm、下へ等間隔に 19mm
** 前の月のカレンダーについての各座標
*** 月のテキスト位置は (45,305)
*** 日のテキスト位置は (24,312)、そこから等間隔に右 7mm, 下 6mm
** 次の月のカレンダーについての各座標
*** 月のテキスト位置は (45,350)
*** 日のテキスト位置は (24,357)
```
上記プロンプトは何度かやり直しを含んでますし、最終形のコードまでに追加指示がいくつもあります。

### 祝日判定
毎年悩むのが祝日データをどう反映するか、ってところです。実際オリンピック関連で古いデータのままのカレンダーが流通した、みたいな話もあったので。
祝日のデータはオンラインから取り寄せるのが良いはずだ、と考え公開データを探してみて以下を採用しました。これも ChatGPT に読み込みから反映までを任せています。
https://holidays-jp.github.io/api/v1/date.json

### 振替休日問題
祝日判定で得られた文字列データのうち、振替休日の文字列が長すぎてこのままでは使えません。
そこで単純に「振替休日という文字列を含んでいたら、その日は『振替休日』だ！」という指示を付けました。

## 完成
いろいろ調整して完成しました。
https://github.com/screwyscrew/calendar_generator
ライセンスなども ChatGPT に丸投げして設定してもらいました。

## 所感
人間の仕事はよりクリエイティブな方向へ、を実感した次第です。もっといろいろ皆さん進んだことを成されているのだと思いますが、カレンダー程度でもこれだけ実感できるくらい AI の進歩を感じますね。
逆に、人の想いや考え、理想、そういうものを定量的に表現できる能力みたいなものが、今後要求されるのではないかなと。コーディングは勝手にやってくれるけど、微妙な間違いだったり「思ってたのと違う問題」とかを訂正するのはやっぱり人の手だなと。
そもそもプロンプトをどうやって打つのか、というスキルもやっぱり必要だなーとか。今回の試みで座標指示ってのは手抜きしないほうが良いということをまじで実感しました。

### ChatGPT は図の生成が苦手
人間が理解できる図を AI が生成できるのか、という問いに対し、今のところの答えは「無理だろう」というのが私の見解です。特に座標を含む生成が厳しそう。PlantUML とかのマークアップはどうやらイケそうなんですが、それも結局コーディングであって図の生成ではないんですよね。DALL-E とか使ったら絶望しますよ。絵画・写真のようなラスタはまあ見られても、ベクタな画が欲しい場合には「どうしてそうなった」があまりに多い。

私自身 AI は漠然とした＆聞きかじった知識しかないのですが、そこから類推するとノイズからの引き算な生成において図は適さないのでしょう。
ちなみにカレンダーをまるごと生成させるとこうなります。プロンプト修正無しの一発勝負。
![DALL·E 2025-01-06 16.28.40 - A complete January 2025 calendar design with cute illustrations of a playful dog enjoying snow. The calendar includes Japanese holidays (New Year's Da.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403596/59151d5e-2f32-aa85-c443-4b3eb34d6918.png)
可愛いし、デザインも悪くないのに、カレンダーとしてゴミ過ぎるｗ