HN 日本語サマリー

← 一覧へ戻る
プログラミング

パーソナルなゴミ収集カレンダーの作成

Creating a Personalised Bin Calendar (alexwlchan.net)

17 pointsby surprisetalk6 コメント

要約

著者は、自治体が配布する情報密度の高いゴミ収集カレンダーの読みにくさを解消するため、Pythonを使ってパーソナルなゴミ収集カレンダーを自作する方法を紹介しています。標準のHTMLカレンダーモジュールをカスタマイズし、各日付にID属性を付与してHTMLファイルとして出力後、CSSで装飾することで、個人のゴミ収集日を視覚的に分かりやすく表示できるカレンダーを作成します。

全文翻訳

パーソナルなゴミ収集カレンダーの作成 2026年3月26日投稿 Pythonにも分類 毎年春になると、私の自治体は新しいゴミ収集カレンダーを発行します。これらのカレンダーは通常、地域全体をカバーする単一のPDFとして公開され、情報はコンパクトなデザインに詰め込まれています。印刷コストを節約するためでしょう。皆に同じものを配布できるよう、一括でカレンダーを印刷できるのです。 これはサウス・ケンブリッジのこうしたコンパクトな図の例です。この地域は郡を4つの異なる地域に分けています。 私は8年以上サウス・ケンブリッジには住んでいませんので、これは私のカレンダーではありませんが、地元の自治体にリンクすることでインターネットに私の居住地を教えたくはありません。 例えば、いつものゴミの収集日が木曜日なら、その年の最後の収集は12月22日月曜日になります。 このコンパクトな表現はデザインの驚異ですが、一軒家に住む私にとってはあまり役に立ちません。郡全体ではなく、私の通りのゴミ収集日だけが重要です。 数年前から、私はゴミがいつ収集されるかを示すパーソナルなカレンダーを作成しており、それを印刷して冷蔵庫に貼っています。手作業ですが、今少しの労力を払うことで、一年を通してその恩恵を受けることができます。 まずPythonを使ってHTMLカレンダーを生成します。組み込みのcalendarモジュールがあり、さまざまな形式でカレンダーを出力できます。これは<td>セルに個別の日付情報を埋め込むわけではないので、HTMLCalendarクラスをカスタマイズして、日付をid属性として書き込みます。 これは2026年4月から2027年3月までのカレンダーを生成する私のスクリプトです。 ```python from calendar import HTMLCalendar from datetime import date class PerDateCalendar(HTMLCalendar): """ 各日付にID属性(例: `d-2026-03-27`)を追加し、曜日の略称(M, Tu, W, …)を使用する、カスタマイズされたHTMLカレンダー。 """ def formatday(self, day: int, weekday: int) -> str: """ 単一の日付を表すテーブルセル、またはカレンダー上の空白の場合は空のセルを返します。 """ if day == 0: return f'<td class="{self.cssclass_noday}">&nbsp;</td>' else: current_date = date(self.current_year, self.current_month, day) date_string = current_date.strftime("%Y-%m-%d") return f'<td id="d-{date_string}">{day}</td>' def formatmonth(self, year: int, month: int, withyear=True) -> str: """ 月ごとのカレンダーを表すテーブルを返します。 """ # formatday() から見えるように、現在の月/年を保存します self.current_year = year self.current_month = month return super().formatmonth(year, month, withyear) def formatweekday(self, day: int) -> str: """ 単一の曜日の名前を表すテーブルヘッダーセルを返します。 """ custom_names = ["M", "Tu", "W", "Th", "F", "Sa", "Su"] return f"<th>{custom_names[day]}</th>" if __name__ == "__main__": cal = PerDateCalendar() start_year, start_month = 2026, 4 end_year, end_month = 2027, 3 full_calendar_html = ( "<html>" '<head><link href="style.css" rel="stylesheet"></head>' '<body><div id="grid">' ) current_year, current_month = start_year, start_month while (current_year < end_year) or \ ( current_year == end_year and current_month <= end_month ): month_html = cal.formatmonth(current_year, current_month) full_calendar_html += month_html if current_month == 12: current_month = 1 current_year += 1 else: current_month += 1 full_calendar_html += "</div></body></html>" with open("bin_calendar.html", "w") as f: f.write(full_calendar_html) ``` これにより、各月がテーブルで、各日が個別に識別可能なセルであるHTMLファイルが生成されます。出力のサンプルは以下の通りです。 ```html <table border="0" cellpadding="0" cellspacing="0" class="month"> <tr> <th colspan="7" class="month">April 2026</th> </tr> <tr> <th>M</th><th>Tu</th><th>W</th><th>Th</th><th>F</th><th>Sa</th><th>Su</th> </tr> <tr> <td class="noday">&nbsp;</td><td class="noday">&nbsp;</td><td id="d-2026-04-01">1</td><td id="d-2026-04-02">2</td><td id="d-2026-04-03">3</td><td id="d-2026-04-04">4</td><td id="d-2026-04-05">5</td> </tr> ``` HTMLは外部スタイルシート`style.css`を参照しており、これにはカレンダーを3列表示に変換する基本的なスタイルが含まれています。 ```css #grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3em; width: 600px; margin: 0 auto; font-family: Helvetica; } th { padding-bottom: 5px; } td { font-size: 0.9em; line-height: 1.4em; text-align: center; } ``` その後、作成したIDを使用して各日付の<td>セルをターゲットにすることで、個々のゴミ収集日をハイライトできます。 ```css /* 黒/白の背景 */ #d-2026-04-03, #d-2026-04-24 { font-size: 1.1em; font-weight: bold; background: black; color: white; border-bottom: 1px solid white; border-top: 1px solid white; } /* 緑/白の背景 */ #d-2026-04-10, #d-2026-04-24 { font-size: 1.1em; font-weight: bold; background: green; color: white; border-bottom: 1px solid white; border-top: 1px solid white; } ``` すべてのゴミ収集日を手作業でカレンダーに転記するのに5分もかかりませんが、結果は以下のようになります。 これは紙一枚にきれいに収まるので、印刷して冷蔵庫に貼ります。収集日が通常と異なる日や、次の収集日がいつかを確認するのが簡単です。 私はこのカレンダーを使って、収集をスキップできるかどうかを知ることがよくあります。一人暮らしでゴミの量は少ないため、ゴミ箱が半分以上満杯になることはめったにありません。半分も満たないゴミ箱を出すのはもったいないと思いますが、次の数回の収集を欠席することが分かっていれば、それでも出します。