Python

Pythonで関数を使ってみる

こんにちは Tomoです。

今回はプログラムが長くなったので、カレンダーのzipファイルの読み込みと表計算の出力の2つの関数にわけてみようと思います。

事前準備

前回の続きとなります

以下の内容を確認してください。


定数定義

ファイルのパスや、日付のフォーマットの形式が長くなっているため定数にしたいと思います。

定数は以下の通りです

    
# カレンダーZIPファイル
CALENDAR_ZIP_FILE_PATH = 'D:\\python_workspace\\imput_data\\{Google アカウント}@gmail.com.ical.zip'
# カレンダーICSファイル
CALENDAR_FILE_NAME = '{xxxxxxxx}@group.calendar.google.com.ics'
# 勤怠管理ファイル
ATTENDANCE_FILE_PATH = 'D:\\python_workspace\\output_data\\test.xlsx'

# 日時フォーマット
FORMAT_DATE_TIME = '%Y/%m/%d %H:%M:%S7'
# 日付フォーマット
FORMAT_DATE = '%Y/%m/%d'
# 時分フォーマット
FORMAT_HM = '%H:%M'
    

定数として定義したら、そのあとのプログラミング修正します。

    
with zipfile.ZipFile(CALENDAR_ZIP_FILE_PATH) as cal_zip:
    with cal_zip.open(CALENDAR_FILE_NAME) as cal_file:
・・・略・・・
    

上記のように置き換えます。(略していますがほかのコードも修正してください。)

今回の以下のメリットで定数化しています。

  • ソースが短くなり見やすい
  • ファイル名パスを変更しやすい

定数の命名規約としては大文字の「_(アンダーバー)」で定義するようです。

ではソースを修正したら実行して問題ないことを確認してください。

実行したら、インデントのずれや、スペルミスなどが起こるかもしれませんのですこしずつ変えていきます。

関数定義

次に関数を定義します。

以下のように関数を書きます

    
def read_calendar_zip():
    """
    zip形式のカレンダーを取得してlistに格納します.
    """
    with zipfile.ZipFile(CALENDAR_ZIP_FILE_PATH) as cal_zip:
        with cal_zip.open(CALENDAR_FILE_NAME) as cal_file:
        ・・・略・・・
    

defで関数を宣言します。

関数名は、read_calendar_zipとします。命名規約上は「小文字のアンダーバー」のようです。引数は記載しません。「:」を忘れずに記載します。

defのインデントは一番左にしておきます。

"""はコメントを表します。これで囲まれている中にコメントを書くことができます。

以降は全てインデントをずらします。

ずらし終わったら関数を呼び出します。

一番最後の行に以下のように記載します。

    
・・・略・・・
# 関数呼び出し
read_calendar_zip()
    

実行してエラーにならないことを確認します。

エラーがないことが確認できたら再度関数を作成します。

ファイルを書き込むところを関数にします。

その前にリストを関数の外側に定義します。

    
・・・略・・・
stat_date_list = []
end_date_list  = []
summary_list   = []

def read_calendar_zip():
・・・略・・・
    

書き込む箇所を関数にします。

    
・・・略・・・
            # イベントの終了(END:VEVENT)
            if 'END:VEVENT' in line_decode:
                print(line_decode)

def write_attendance():
    """
    勤怠データを出力します.
    """
    work_book = openpyxl.Workbook()
    work_sheet = work_book.active

・・・略・・・
    

上記のようにちょうどFor文が終わったとところで関数を定義します。

関数は一番左に寄せてください。以降のコードもインデントを合わせます。

    
・・・略・・・
# 関数呼び出し
read_calendar_zip()

write_attendance()
    

「read_calendar_zip()」の後ろに記載します。

呼び出す順番が違うと動かないので注意してください

では実行してエラーがないことを確認してください。

まとめ

今回は関数化まで行いました。

今回の関数化のメリットは、読みやすくなったこと、読み込み書き込みで機能が明確化になったこと

それに伴い確認が楽になるかなと思います。

次回もソースコードの整形を行う予定です。

最後に今回のソースを記載します。

    
import zipfile
import datetime
import dateutil.parser
import openpyxl

# カレンダーZIPファイル
CALENDAR_ZIP_FILE_PATH = 'D:\\python_workspace\\imput_data\\{Google アカウント}@gmail.com.ical.zip'
# カレンダーICSファイル
CALENDAR_FILE_NAME = '{xxxxxxxx}@group.calendar.google.com.ics'
# 勤怠管理ファイル
ATTENDANCE_FILE_PATH = 'D:\\python_workspace\\output_data\\test.xlsx'

# 日時フォーマット
FORMAT_DATE_TIME = '%Y/%m/%d %H:%M:%S7'
# 日付フォーマット
FORMAT_DATE = '%Y/%m/%d'
# 時分フォーマット
FORMAT_HM = '%H:%M'

stat_date_list = []
end_date_list  = []
summary_list   = []

def read_calendar_zip():
    """
    zip形式のカレンダーを取得してlistに格納します.
    """
    with zipfile.ZipFile(CALENDAR_ZIP_FILE_PATH) as cal_zip:
        with cal_zip.open(CALENDAR_FILE_NAME) as cal_file:
            jst = datetime.timezone(datetime.timedelta(hours=+9), 'JST')

            for line in cal_file:
                 line_decode = line.decode('utf-8')
                 line_decode = line_decode.rstrip('\r\n')

                 # イベントの開始(BEGIN:VEVENT)を探す
                 if 'BEGIN:VEVENT' in line_decode:
                     print(line_decode)

                 # 開始時間(DTSTART)を探す
                 if 'DTSTART:' in line_decode:
                     dt_start = line_decode.split(':')
                     dt_start_time = dateutil.parser.parse(dt_start[1]).astimezone(jst)
                     stat_date_list.append(dt_start_time)
                     print(dt_start_time.strftime(FORMAT_DATE_TIME))

                 # 終了時間(DTEND)を探す
                 if 'DTEND:' in line_decode:
                     dt_end = line_decode.split(":")
                     dt_end_time = dateutil.parser.parse(dt_end[1]).astimezone(jst)
                     end_date_list.append(dt_end_time)
                     print(dt_end_time.strftime(FORMAT_DATE_TIME))

                 # タイトル(SUMMARY)を探す
                 if 'SUMMARY:' in line_decode:
                     summary = line_decode.split(':')
                     summary_list.append(summary[1])
                     print(summary[1])

                 # イベントの終了(END:VEVENT)
                 if 'END:VEVENT' in line_decode:
                     print(line_decode)

def write_attendance():
    """
    勤怠データを出力します.
    """
    work_book = openpyxl.Workbook()
    work_sheet = work_book.active

    for count, summary in enumerate(summary_list):
        print('----------')
        print(summary)
        print(stat_date_list[count].strftime(FORMAT_DATE))
        print(stat_date_list[count].strftime(FORMAT_HM))
        print(end_date_list[count].strftime(FORMAT_DATE))
        print(end_date_list[count].strftime(FORMAT_HM))
        print(end_date_list[count] - stat_date_list[count] - datetime.timedelta(hours=1))

        work_sheet.cell(count +1, 1).value = summary
        work_sheet.cell(count +1, 2).value = stat_date_list[count].strftime(FORMAT_DATE)
        work_sheet.cell(count +1, 3).value = stat_date_list[count].strftime(FORMAT_HM)
        work_sheet.cell(count +1, 4).value = end_date_list[count].strftime(FORMAT_HM)
        work_sheet.cell(count +1, 5).value = end_date_list[count] - stat_date_list[count] - datetime.timedelta(hours=1)

        work_book.save(ATTENDANCE_FILE_PATH)


# 関数呼び出し
read_calendar_zip()

write_attendance()
    

コメント

0 件のコメント:

コメントを投稿

コメントをお待ちしています。