質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

0回答

460閲覧

【Python3】関数・定数化 プログラムの改修について

退会済みユーザー

退会済みユーザー

総合スコア0

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/05/17 06:43

編集2021/05/17 08:05

解決したいこと

Python初学者ですが、学習のために既存プログラムの改修を行っております。
行いたい内容は、複数のcsvファイルを読み込み、データを整理した後、一つのファイルに書き出しです。

行いたい内容

共通の処理やまとまりを関数に分離する、定数化できるところは定数化する
「# CSVファイルを読み込んで辞書のリストで返す関数を実装する」の箇所で関数を用いて実行してみましたが、
下記のネームエラーが出てしまいます。
エラーでは、dataが定義されていないとのことですが、関数を呼び出している「# * 対象の月のデータのみ読み込み」
の引数に問題があるのでしょうか?

Traceback (most recent call last): File "/Users/******/docker/src/main.py", line 81, in <module> main() File "/Users/******/docker/src/main.py", line 55, in main for row in read_csv(data): NameError: name 'data' is not defined

ファイル等の情報

ファイルは下記になります。

商品のマスターデータ →/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を紐付け、紐付く商品名と商品価格を出力させます。

現在のプログラム

py

1import os 2import re 3 4ITEMS_DATA = 'input/items.csv' 5ITEMS_COLUMNS = ['item_id', 'name', 'price'] 6 7SALES_RAW_REGEX = re.compile(r'^sales_raw_(\d{4})(\d{2})(\d{2}).csv$') 8SALES_COLUMNS = ['purchase_id', 'user_id', 'item_id', 9 'item_name', 'item_price', 'amount', 'sold_at'] 10SALES_DATA = 'output/sales.csv' 11 12ENCODING = 'utf-8' 13CSV_INPUT = input('') 14 15# CSVファイルを読み込んで辞書のリストで返す関数を実装する 16def read_csv(f, columns): 17 with open(os.path.join('input/', filename), encoding=ENCODING) as f: 18 for row in f: 19 data = row.rstrip().split(',') 20 21# Step5では以下の状態で実装する 22def write_csv(f, data, columns): 23 pass 24 25# Step5では以下の状態で実装する 26def read_items(): 27 pass 28 29# Step5では以下の状態で実装する 30def read_sales_raw(target_year, target_month): 31 pass 32 33# Step5では以下の状態で実装する 34def write_sales(sales): 35 pass 36 37def main(): 38 # 商品のマスターデータ読み込み 39 items = {} 40 with open(ITEMS_DATA, encoding=ENCODING) as f: 41 # CSVファイルを読み込んで辞書のリストで返す関数使う 42 for row in f: 43 item_id, item_name, item_price = row.rstrip().split(',') 44 items[item_id] = { 45 'item_name': item_name, 46 'item_price': item_price 47 } 48 49 # 売上の生データを読み込んで、まとめる 50 sales = [] 51 for filename in os.listdir('input/'): 52 # * 対象の月のデータのみ読み込み 53 if re.match(CSV_INPUT, filename): 54 with open(os.path.join('input/', filename), encoding=ENCODING) as f: 55 for row in read_csv(f, data): 56 # 商品の情報を追加する 57 item_id = data[2] 58 if item_id in items: 59 sales.append({ 60 'purchase_id': data[0], 61 'user_id': data[1], 62 'item_id': data[2], 63 'item_name': items[item_id]['item_name'], 64 'item_price': items[item_id]['item_price'], 65 'amount': data[3], 66 'sold_at': data[4] 67 }) 68 69 # まとめた売上データを書き出し 70 m = SALES_RAW_REGEX.search(filename) 71 if len(sales) == 0: 72 print('書き出しファイルがありません') 73 return 74 SALES_COLUMNS 75 with open(SALES_DATA, mode='w', encoding=ENCODING) as f: 76 for row in sales: 77 row_str = ','.join(str(row[column]) for column in SALES_COLUMNS) 78 f.write(row_str + '\n') 79 80if __name__ == "__main__": 81 main()

改修途中のプログラム

py

1import os 2import re 3 4ITEMS_DATA = 'input/items.csv' 5ITEMS_COLUMNS = ['item_id', 'name', 'price'] 6 7SALES_RAW_REGEX = re.compile(r'^sales_raw_(\d{4})(\d{2})(\d{2}).csv$') 8SALES_COLUMNS = ['purchase_id', 'user_id', 'item_id', 9 'item_name', 'item_price', 'amount', 'sold_at'] 10SALES_DATA = 'output/sales.csv' 11 12ENCODING = 'utf-8' 13CSV_INPUT = input('') 14 15# CSVファイルを読み込んで辞書のリストで返す関数を実装する 16def read_csv(f, columns): 17 with open(os.path.join('input/', filename), encoding=ENCODING) as f: 18 for row in f: 19 data = row.rstrip().split(',') 20 21# Step5では以下の状態で実装する 22def write_csv(f, data, columns): 23 pass 24 25# Step5では以下の状態で実装する 26def read_items(): 27 pass 28 29# Step5では以下の状態で実装する 30def read_sales_raw(target_year, target_month): 31 pass 32 33# Step5では以下の状態で実装する 34def write_sales(sales): 35 pass 36 37def main(): 38 # 商品のマスターデータ読み込み 39 items = {} 40 with open(ITEMS_DATA, encoding=ENCODING) as f: 41 # CSVファイルを読み込んで辞書のリストで返す関数使う 42 for row in f: 43 item_id, item_name, item_price = row.rstrip().split(',') 44 items[item_id] = { 45 'item_name': item_name, 46 'item_price': item_price 47 } 48 49 # 売上の生データを読み込んで、まとめる 50 sales = [] 51 for filename in os.listdir('input/'): 52 # * 対象の月のデータのみ読み込み 53 if re.match(CSV_INPUT, filename): 54 with open(os.path.join('input/', filename), encoding=ENCODING) as f: 55 for row in read_csv(f, data): 56 # 商品の情報を追加する 57 data = row.rstrip().split(',') 58 item_id = data[2] 59 if item_id in items: 60 sales.append({ 61 'purchase_id': data[0], 62 'user_id': data[1], 63 'item_id': data[2], 64 'item_name': items[item_id]['item_name'], 65 'item_price': items[item_id]['item_price'], 66 'amount': data[3], 67 'sold_at': data[4] 68 }) 69 70 # まとめた売上データを書き出し 71 m = SALES_RAW_REGEX.search(filename) 72 if len(sales) == 0: 73 print('書き出しファイルがありません') 74 return 75 SALES_COLUMNS 76 with open(SALES_DATA, mode='w', encoding=ENCODING) as f: 77 for row in sales: 78 row_str = ','.join(str(row[column]) for column in SALES_COLUMNS) 79 f.write(row_str + '\n') 80 81if __name__ == "__main__": 82 main()

自分で試したこと

・繰り返し使用されるコードに関しては、定数を定義しました。
・必要な関数の処理のまとまりをコメントアウトで記載しました。
・自分でプログラムの編集を行いましたが、どうしても既存プログラムに引っ張られ、変更点があまり無い状況です。

基本的にモジュールの追加は行わず実装したいと思っております。
その他に何か必要な情報などありましたら、提示いたします。

長くなってしまい、大変恐縮ではございますが、ご教授頂けますと幸いです。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ppaul

2021/05/17 07:33

質問は何でしょうか?
退会済みユーザー

退会済みユーザー

2021/05/17 07:41

大変失礼いたしました。 「行いたい内容」の箇所に問題点を追記いたしました。 お手数おかけしますが、ご確認頂けますと幸いです。
t_obara

2021/05/17 08:01

read_csvの引数がおかしいです。さらにエラーで提示されたものとソースが違っていますよね。 少なくともread_csvではどのような入力を得たときに、何を返却したいのかを理解する必要があります。
退会済みユーザー

退会済みユーザー

2021/05/17 08:09

t_obara様 ご指摘ありがとうございます。 また、度々大変失礼いたしました。 上記のコードでは、1箇所無駄に記載がありました。 やはり、引数に問題があるのですね。 ただ、第二引数をcolumnsとしても、同じエラーが出てしまいます。 下記を返却する想定になります。 「[{'purchase_id': '3000', 'user_id': '14', 'item_id': '23', 'amount': '8','sold_at': '2016-11-01T00:47:09Z'}, {'purchase_id': '3001', 'user_id': '16', 'item_id': '1', 'amount': '4', 'sold_at': '2016-11-01T01:28:08Z'}]」
t_obara

2021/05/17 11:24

呼び出し方と定義を合わせる必要があり、合っていないことを引数がおかしいと表現しています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問