answer13_1.py
import csv
# 入力ファイルを開く
with open("scores_in.csv", "r", encoding="utf-8", newline="") as infile:
reader_obj = csv.reader(infile)
header = next(reader_obj)
# ヘッダのフィールド数から科目数を求める
num_courses = len(header) - 1
# 科目ごとの合計点を求めるために初期化を行う
course_total = [0] * num_courses
# 出力ファイルを開く
with open("scores_out.csv", "w", encoding="utf-8", newline="") as outfile:
writer_obj = csv.writer(outfile)
# 入力ファイルのヘッダ行を流用し、合計フィールドを追加する
writer_obj.writerow(header+["合計"])
num_students = 0
for student_record in reader_obj:
# この生徒の各科目の点数を整数のリストにする
scores = [int(score) for score in student_record[-num_courses:]]
# 合計点を求める
total_score = sum(scores)
# 合計点を求めて出力ファイルにレコードとして書く
writer_obj.writerow(student_record+[total_score])
# この生徒の各科目の点数を、科目ごとの合計点に足し込む
course_total = [sum(pair) for pair in zip(course_total, scores)]
num_students += 1
# 科目ごとの平均点を求めて出力ファイルにレコードとして書く
course_average = [round(each_total/num_students, 1) for each_total in course_total]
writer_obj.writerow(["平均"]+course_average+[""])
# 章末問題 13章【1】解答例
#
# 入力ファイルscores_in.csvを読みながら出力ファイルscores_out.csvを
# 書くために、with文(4行目)で入力ファイルを開いた状態でwith文(12行目)で
# 出力ファイルを開いて、その本体でファイルを読み書きしています。
#
# 入力ファイルからの読み込みは、ヘッダについては6行目のnextで、
# 内容については17行目のfor文で、いずれもreader_objをイテレータとして
# 使うことで行っています。
#
# 出力ファイルへの書き出しは、ヘッダについては15行目、各生徒のデータに
# ついては23行目、科目ごとの平均点については28行目で、いずれもwriterow
# メソッドを用いて行っています。
#
# 19行目の内包表記は、student_recordの後ろnum_courses(科目数)個の
# データをそれぞれ整数に変換して、その全体をリストにするという処理です。
#
# 25行目の内包表記は、科目ごとの合計点course_totalと、この生徒の得点
# scoresを、zipを使って組み合わせて、それぞれを足したものを集めて
# またリストにし、course_totalに代入し直すという処理です。例えば
# course_totalが[164, 149, 163]で、scoresが[68, 98, 71]なら、
# zipから得られるのは(164, 68)、(149, 98)、(163, 71)というタプルで、
# それぞれがpairに代入されるので、sum(pair)とすることでそれぞれの和
# 232、247、234を求め、これらがリストになってcourse_totalに代入されます。