【Python3】csvファイル 関数について
Q&A
Closed
Python初学者ですが、学習のために既存プログラムの改修を行いたいと考えております。
行いたい内容は、複数のcsvファイルを読み込み、データを整理した後、一つのファイルに書き出しです。
解決したいこと
まずは、下記に記載しているプログラムの「# CSVファイルを読み込んで辞書のリストで返す関数を実装する」というread_csvの箇所を関数や定数を用いて実装したいと思っております。
基本的にはcsvモジュールなどモジュールの追加などは行わず実装したいと思っております。
私の方で調べながら実装してみましたが、csvモジュールを使用しないやり方が出てこず、解決まで運ぶことが出来ませんでした。
ファイルは下記になります。
商品のマスターデータ
→/input/items.csv
商品の売上データ(日毎に別ファイル)
→/input/sales_raw_20161030.csv
/input/sales_raw_20161101.csv
...
/input/sales_raw_20161106.csv
書き出し後の売上データ
→/output/sales.csv
商品マスターデータ(items.csv)の中身は下記になります。
商品ID、商品名、商品価格
商品の売上データ(sales_raw_YYYYmmdd.csv)の中身は下記になります。
購入ID、ユーザーID、商品ID、個数、販売日時
書き出し後のデータ(sales.csv)は下記になります。
購入ID、ユーザーID、商品ID、商品名、商品価格、個数、販売日時
*商品の売上データの商品IDと商品マスターデータの商品IDを紐付け、紐付く商品名と商品価格を出力させます。
現状のプログラム
import os
import re
ITEMS_DATA = 'input/items.csv'
ITEMS_COLUMNS = ['item_id', 'name', 'price']
SALES_RAW_REGEX = re.compile(r'^sales_raw_(\d{4})(\d{2})(\d{2}).csv$')
SALES_COLUMNS = ['purchase_id', 'user_id', 'item_id',
'item_name', 'item_price', 'amount', 'sold_at']
SALES_DATA = 'output/sales.csv'
ENCODING = 'utf-8'
CSV_INPUT = input('')
# CSVファイルを読み込んで辞書のリストで返す関数を実装する
def read_csv(f, columns):
pass
# Step5では以下の状態で実装する
def write_csv(f, data, columns):
pass
# Step5では以下の状態で実装する
def read_items():
pass
# Step5では以下の状態で実装する
def read_sales_raw(target_year, target_month):
pass
# Step5では以下の状態で実装する
def write_sales(sales):
pass
def main():
# 商品のマスターデータ読み込み
items = {}
with open(ITEMS_DATA, encoding=ENCODING) as f:
for row in read_csv(f, ITEMS_COLUMNS):
# CSVファイルを読み込んで辞書のリストで返す関数使う
item_id, item_name, item_price = row.rstrip().split(',')
items[item_id] = {
'item_name': item_name,
'item_price': item_price
}
# 売上の生データを読み込んで、まとめる
sales = []
for filename in os.listdir('input/'):
# * 対象の月のデータのみ読み込み
if re.match(CSV_INPUT, filename):
with open(os.path.join('input/', filename), encoding=ENCODING) as f:
for row in f:
data = row.rstrip().split(',')
# 商品の情報を追加する
item_id = data[2]
if item_id in items:
sales.append({
'purchase_id': data[0],
'user_id': data[1],
'item_id': data[2],
'item_name': items[item_id]['item_name'],
'item_price': items[item_id]['item_price'],
'amount': data[3],
'sold_at': data[4]
})
# まとめた売上データを書き出し
m = SALES_RAW_REGEX.search(filename)
if len(sales) == 0:
print('書き出しファイルがありません')
return
SALES_COLUMNS
with open(SALES_DATA, mode='w', encoding=ENCODING) as f:
for row in sales:
row_str = ','.join(str(row[column]) for column in SALES_COLUMNS)
f.write(row_str + '\n')
if __name__ == "__main__":
main()
自分で試したこと
商品マスターデータのwith文をread_csv関数内に記述していたのですが、その場合、関数の使い回しが出来ないので、「商品マスターデータ読み込み」内に記述したり、read_csvの引数に問題が生じたりしていたので、修正を行ったりしましたが、結局解決できないまま時間だけが過ぎてしまうので、ご教授頂けますと幸いです。
read_csv関数に関しては、csvモジュールを使用したやり方はたくさんサイトに載っているのですが、今回はcsvモジュールを使わないで実装なので、参考になるサイトも見当たらず、何を記述すると良いのかも分からない状況です。
read_csvで返したい情報としては下記のようなものになります。
[{'item_id': '1', 'name': '掃除機', 'price': '4980'}, {'item_id': '2', 'name': '扇風機', 'price': '2980'}......]
その他に何か必要な情報などありましたら、提示いたします。
大変恐縮ではございますが、ご教授頂けますと幸いです。
よろしくお願いいたします。