wellwell3176
@wellwell3176

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

pythonを用いたExcel作成プログラムの可読性について

Discussion

Closed

議論したいこと

 後述するプログラムの可読性、記法、処理についてアドバイス等があればお伺いしたい

 どうにかこうにかマクロ代わりのプログラムが完成し、それっぽい出力ができる形にはなったものの、周囲にチェックできる人がいないため、出来栄えが分からない・・・。

仕様

基本要求は「生データに対してプログラムを実行したら整理済みエクセル、グラフ付き表、カレンダーの3つが出力される」事。
対照表と、グラフ付き表のフォーマットは事前準備済み。

注記:(現時点でカレンダーはデータ抜き取りのみ実装)
現時点での入出力は下図のようになっている(生データ・成果物1・成果物3は抜粋したデータ)。
(使ったxlsxファイルを共有する上手い方法が思いつかず。良策あればご教示いただきたく)
image.png
image.png

現行品のソースコード

現行品
import openpyxl
import copy
import pandas as pd

datasheet_raw=pd.read_excel('/content/drive/My Drive/Colab Notebooks/rawdata.xlsx')

#まず、「対照表から設定1/設定2を与える+不要な作業員情報を統合する」処理後のエクセルを成果物1として保管する
datasheet_raw["作業時間"] = pd.to_datetime(datasheet_raw["作業時間"],format="%H:%M:%S") 
datasheet_raw["作業時間"] = datasheet_raw["作業時間"].dt.minute #作業時間を文字列から数値[分]に変換

datasheet_raw=datasheet_raw.groupby(["テーマ","月日","国名","区分","業務"],as_index=False).sum()
 #作業員の名前が不要なので集約する

table_master = pd.read_excel('/content/drive/My Drive/Colab Notebooks/table_master.xlsx')
datasheet_process = datasheet_raw.merge(table_master, on=['区分', '業務'], how='left')
 #merge関数を使って対照表と生データを結合することで設定1・設定2を付与
datasheet_process.to_excel('/content/drive/My Drive/Colab Notebooks/output1.xlsx', index=False) #成果物1が完成

#グラフ生成用のエクセルに値を打ち込み、成果物2として保管する
databook_graph=openpyxl.load_workbook('/content/drive/My Drive/Colab Notebooks/graph_master.xlsx')
datasheet_graph=databook_graph.active

month_data = datasheet_process.iat[0,1].strftime("%Y年%m月")
 #生データは毎月1日~月末のデータなので”月日”列からYYYY年M月のデータを適当に持ってくる
datasheet_graph.cell(1,12).value=month_data

setting1 = datasheet_process.groupby(["設定1"],as_index=False).sum()
setting1 = setting1.iloc[:,2]/60 #設定1ごとの作業時間を単位[hour]の9行1列データとして取り出す(設定1は9種類固定)

for i in range(1,10):
  datasheet_graph.cell(i+2,11).value=setting1[i-1] #エクセルの3行11列から11行11列までsetting1[0]~[8]を代入

databook_graph.save('/content/drive/My Drive/Colab Notebooks/output2.xlsx') #完成したグラフ生成用エクセルを保管

#月日と設定2で集計したエクセルを成果物3として保管する(最終的にはこれからカレンダーを制作して完成となる)
datasheet_complete =datasheet_process.groupby(["月日","設定2"],as_index=False).sum()
datasheet_complete.to_excel('/content/drive/My Drive/Colab Notebooks/output3.xlsx', index=False)
0

動かなかったら適宜修正してください。

sample1.py
import openpyxl
import copy
import pandas as pd

workdir = '/content/drive/My Drive/Colab Notebooks'

#まず、「対照表から設定1/設定2を与える+不要な作業員情報を統合する」処理後のエクセルを成果物1として保管する
def make1():
	global workdir
	datasheet_raw = pd.read_excel(workdir + '/rawdata.xlsx')
	datasheet_raw["作業時間"] = pd.to_datetime(datasheet_raw["作業時間"],format="%H:%M:%S") 
	datasheet_raw["作業時間"] = datasheet_raw["作業時間"].dt.minute #作業時間を文字列から数値[分]に変換

	datasheet_raw=datasheet_raw.groupby(["テーマ","月日","国名","区分","業務"],as_index=False).sum()
	 #作業員の名前が不要なので集約する

	table_master = pd.read_excel(workdir + '/table_master.xlsx')
	datasheet_process = datasheet_raw.merge(table_master, on=['区分', '業務'], how='left')
	 #merge関数を使って対照表と生データを結合することで設定1・設定2を付与
	datasheet_process.to_excel(workdir + '/output1.xlsx', index=False) #成果物1が完成

#グラフ生成用のエクセルに値を打ち込み、成果物2として保管する
def make2():
	global workdir
	databook_graph=openpyxl.load_workbook(workdir + '/graph_master.xlsx')
	datasheet_graph=databook_graph.active

	month_data = datasheet_process.iat[0,1].strftime("%Y年%m月")
	 #生データは毎月1日~月末のデータなので”月日”列からYYYY年M月のデータを適当に持ってくる
	datasheet_graph.cell(1,12).value=month_data

	setting1 = datasheet_process.groupby(["設定1"],as_index=False).sum()
	setting1 = setting1.iloc[:,2]/60 #設定1ごとの作業時間を単位[hour]の9行1列データとして取り出す(設定1は9種類固定)

	for i in range(1,10):
	  datasheet_graph.cell(i+2,11).value=setting1[i-1] #エクセルの3行11列から11行11列までsetting1[0]~[8]を代入

	databook_graph.save(workdir + '/output2.xlsx') #完成したグラフ生成用エクセルを保管


#月日と設定2で集計したエクセルを成果物3として保管する(最終的にはこれからカレンダーを制作して完成となる)
def make3():
	global workdir
	datasheet_complete =datasheet_process.groupby(["月日","設定2"],as_index=False).sum()
	datasheet_complete.to_excel(workdir + '/output3.xlsx', index=False)


if __name__ == '__main__':
	make1()
	make2()
	make3()
1Like

@tukiyo3
早速のコメント、ありがとうございます。
試してみたものの何箇所か動かなかったので中身を見ているところなのですが、本コメントの主題としては下記3点、と言う理解であっていますでしょうか?

・ディレクトリを参照するときは、共通部分に当たるものを別個用意してしまった方が可読性が良い

・複数処理を組み合わせている場合、処理ごとに関数を定義して小分けにした方が可読性が良い
 ※可読性以外にもdef make()で分ける利点があるのでしょうか?

・「if name == 'main':」は付けたほうが良い
 (少し調べた限りでは、import時などに無闇に実行されないようにする為?)

1Like

お察しの通りです。

あと、#のコメントは行数が増えても別の行に書いた方が良いです。
可読性が落ちるとバグにあいやすいです。

defに分けるのは、そこだけ実行させたりループさせるのがたやすいからという理由もあります。
また、他の例を作る時もコピペしやすいです。

0Like

Your answer might help someone💌