課題03-1 単語数の分布 #
alice_chapter01.txt
は,ルイス・キャロルの「不思議の国のアリス」の第01章のテキストファイルです.
このファイルの単語の頻度を求めてください.
ファイル名は word_freq.py
としてください.
なお,ファイル(alice_chapter01.txt
)はプログラム中に直接ファイル名を書くのではなく,コマンドライン引数(sys.argv[1]
)で受け取るようにして下さい
単語の区切りは,スペース,改行としてください.
split
関数では,2つ以上の文字を区切り文字として文字列を分割できませんので,1行ずつ読み込み,スペースで分割してください.
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.py
,word_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日)