メインコンテンツへスキップ
  1. 第03講 基本データ型(2/2; セット,ディクショナリ)/

第03講 週次課題

週次課題 リスト ファイル Histogram
目次

課題03-1 単語数の分布
#

難易度 ⭐⭐

alice_chapter01.txt は,ルイス・キャロルの「不思議の国のアリス」の第01章のテキストファイルです. このファイルの単語の頻度を求めてください.

ファイル名は word_freq.py としてください. なお,ファイル(alice_chapter01.txt)はプログラム中に直接ファイル名を書くのではなく,コマンドライン引数(sys.argv[1])で受け取るようにして下さい 単語の区切りは,スペース,改行としてください. split 関数では,2つ以上の文字を区切り文字として文字列を分割できませんので,1行ずつ読み込み,スペースで分割してください.

📥 alice_chapter01.txt のダウンロード

import sys # コマンドライン引数を受け取るためのライブラリ

dic = {}   # 単語の出現回数を格納する辞書
with open(sys.argv[1], "r") as f:
  # ファイルを1行ずつ読み込む
    line = line.strip() # 改行文字を取り除く(strip).
    words = # スペースで分割する.
    # 各単語を順番に調べる.
      # 単語が辞書にあれば,
        # カウントを1増やす.
      # なければ,
        # 1を代入する.

print(dic)

実行結果
#

{'Alice': 17, 'was': 42, ...(途中省略)... 'finished': 1, 'off.': 1}

ヒント
#

発展課題

発展課題
#

英単語の区切りは,スペースだけではなく,コンマやコロン(:),ピリオド,クォート,括弧などがあります. それら複数条件での文字列の分割には,正規表現(Regular Expression)を用います(ライブラリ名は re).

  • 複数条件での文字の分割は正規表現を使います.
    • re.split(r"[,:.'\"“()\s\r\n]", line)
      • 文字列の前に r を付けると,raw文字として扱われます.

ファイル名は word_freq2.py としてください. 発展問題まで解けた場合は,課題03-1 と同じ提出場所に word_freq.pyword_freq2.py を提出してください.

import sys # コマンドライン引数を受け取るためのライブラリ
import re  # 正規表現を使うためのライブラリ

dic = {}   # 単語の出現回数を格納する辞書

with open(sys.argv[1], "r") as f:
  # ファイルを1行ずつ読み込む
    words = re.split(r"[,:.'\"“()\s\r\n]", line) # 正規表現で区切る
    # 各単語を順番に調べる.
      # 単語が辞書にあれば,カウントを1増やす.なければ,1を代入する.

print(dic)

なお,クォートは種類がいくつかあり,'"はもちろん, などもあります. '"は Python で文字列を表現するために用いますので,文字列中で利用する場合は \ でエスケープする必要があります. "'と似ていますが,異なる文字です. Python の文字列を表す文字ではないため,エスケープは不要です.

発展問題の実行結果
#

{'Alice': 20, 'was': 43, ...(省略)..., 'toast': 1, 'finished': 1}

課題03-2 猛暑日、真夏日、真冬日,冬日の日数
#

難易度 ⭐⭐⭐

weather2000-2023.csv は2000年から2023年の各日の京都の気温です. 気象庁のページからダウンロードしたものを整形しています. このファイルには,2行目以降に,日付,最高気温,最低気温,平均気温がコンマ区切りで格納されています. このファイルを読み込み,年毎に猛暑日,真夏日,真冬日,冬日の日数を求めてください. 判定方法は次の通りです(🔗 気象庁のホームページにも記載されています).

ファイル名は weather_stats.py としてください.

  • 猛暑日(extremely hot day)
    • 最高気温が35℃以上の日
  • 真夏日(hot summer day)
    • 最高気温が30℃以上の日
  • 夏日(summer day)
    • 最高気温が25℃以上の日
  • 真冬日(ice day)
    • 最高気温が0℃未満の日
  • 冬日(frost day)
    • 最低気温 が0℃未満の日

また,データファイルはプログラム中に直接ファイル名を書くのではなく,コマンドライン引数(sys.argv[1])で与えるようにしてください.

📥 気温データのダウンロード

import sys

dic = {}
years = set()

with open(sys.argv[1], "r") as f:
    f.readline()                # 1行目を読み飛ばす.
    for line in f.readlines():
        (date, max_s, min_s, rests) = line.split(",") # 行をコンマで分割し,それぞれを代入する.
        (year, max, min) = (date[:4], float(max_s), float(min_s))
        (extremely_hot, hot, summer, ice, frost) = (0, 0, 0, 0, 0)
        years.add(year)      # 年を集合に追加しておく.

        # 猛暑日,真夏日,夏日,真冬日,冬日を判定する.
        # extermely_hot, hot, summer, ice, frost いずれかを1にする or 0 のままにする.

        if year in dic:
            # dic[year] からタプルとして,猛暑日,真夏日,夏日,真冬日,冬日,日数を取り出す.
            # dic[year] にタプルとして,猛暑日,真夏日,夏日,真冬日,冬日,日数を格納する.
            # その際,判定とところで得られた extermely_hot, hot, summer, ice, frost をそれぞれに加算する.
            # 日数は1増やす.
        else:
            dic[year] = (extremely_hot, hot, summer, ice, frost, 1)

for year in sorted(years): # 年を昇順にソートして繰り返す.
    (extremely_hot, hot, summer, ice, frost, days) = dic[year]
    print(f"{year}  猛暑日 {extremely_hot:>3}, 真夏日 {hot:>2}, 夏日 {summer:>2}, 真冬日 {ice:>2}, 冬日 {frost:>2} ({days:>3}日)")

実行結果
#

2000  猛暑日  27, 真夏日 61, 夏日 54, 真冬日  0, 冬日 24 (366日)
2001  猛暑日  24, 真夏日 52, 夏日 72, 真冬日  0, 冬日 21 (365日)
2002  猛暑日  23, 真夏日 61, 夏日 64, 真冬日  0, 冬日 11 (365日)
2003  猛暑日  11, 真夏日 50, 夏日 75, 真冬日  0, 冬日 21 (365日)
2004  猛暑日  19, 真夏日 75, 夏日 57, 真冬日  0, 冬日 18 (366日)
2005  猛暑日  17, 真夏日 64, 夏日 65, 真冬日  0, 冬日 30 (365日)
2006  猛暑日  18, 真夏日 53, 夏日 66, 真冬日  0, 冬日 27 (365日)
2007  猛暑日  20, 真夏日 56, 夏日 57, 真冬日  0, 冬日  8 (365日)
2008  猛暑日  21, 真夏日 57, 夏日 69, 真冬日  0, 冬日 17 (366日)
2009  猛暑日   6, 真夏日 63, 夏日 72, 真冬日  0, 冬日 17 (365日)
2010  猛暑日  35, 真夏日 50, 夏日 58, 真冬日  0, 冬日 19 (365日)
2011  猛暑日  17, 真夏日 62, 夏日 52, 真冬日  0, 冬日 31 (365日)
2012  猛暑日  21, 真夏日 58, 夏日 69, 真冬日  0, 冬日 34 (366日)
2013  猛暑日  30, 真夏日 62, 夏日 62, 真冬日  0, 冬日 27 (365日)
2014  猛暑日  13, 真夏日 59, 夏日 79, 真冬日  0, 冬日 23 (365日)
2015  猛暑日  21, 真夏日 47, 夏日 85, 真冬日  0, 冬日 12 (365日)
2016  猛暑日  27, 真夏日 60, 夏日 73, 真冬日  0, 冬日 11 (366日)
2017  猛暑日  18, 真夏日 65, 夏日 61, 真冬日  0, 冬日 15 (365日)
2018  猛暑日  32, 真夏日 43, 夏日 71, 真冬日  0, 冬日 26 (365日)
2019  猛暑日  24, 真夏日 62, 夏日 61, 真冬日  0, 冬日  3 (365日)
2020  猛暑日  26, 真夏日 49, 夏日 77, 真冬日  0, 冬日  2 (366日)
2021  猛暑日  18, 真夏日 59, 夏日 72, 真冬日  0, 冬日 15 (365日)
2022  猛暑日  25, 真夏日 71, 夏日 57, 真冬日  0, 冬日 22 (365日)
2023  猛暑日  43, 真夏日 52, 夏日 61, 真冬日  0, 冬日 14 (365日)

ヒント
#