アメグラ2号のブログ

1980年代後半の古き良きビデオゲームのほか、オッサンの個人的備忘録

python スクリプト アゲハチョウの羽化表

f:id:game-allergy:20210331143049p:plain

アゲハチョウの羽化表を作成しているスクリプトを変えてみた。

f:id:game-allergy:20210606163057j:plain

以前はデータそれぞれを1次元リストで作って、最後にガシャコーンと結合していた。が、よくよく考えてみれば、、、

・データを記載するときに見づらい。

・リストごとの紐づけがされてないので、ズレたら終わり

なんでこんなんだったか?

そもそもは、サナギになった日をデータ入力後、羽化予想日はおおむね10日後なので、+10日の計算をしていた。

ただ、日付の足し引きをする場合にはdatetimeの同じ型にする必要があったので、1次元リスト同士で計算…と、こんなところから始まったので、データの紐づけなんて考えてなかった。

プログラミングあるある・・・だ。

で、関係する複数のデータを1つの塊にして、その中身をちょいちょい変えていくってどーしたらいいのかなー?と考えたところ、

やっぱりクラスを使ったほうがいいのかな?と。

pythonでクラスを慣れるのも重要課題なので、この際しっかりやっておこうと。で、クラスを用いてみた。

import datetime
import pandas as pd
import matplotlib.pyplot as plt
import japanize_matplotlib
import os


# ======================================================
# 【1】:データ入力:sanagi,name,birth
# 【2】:データ+予想日:sanagi,name,prediction,birth
# 【3】:【1】→【2】にリストを再編し、pandas,matplotへ
# ======================================================

class Sanagi:
    def __init__(self, s, n, b):
        dt_needsanagi = datetime.timedelta(days = 10)
        self.sanagi = s
        self.name = n
        self.prediction = s + dt_needsanagi
        self.birth = b

    def RenewList(self):
        newList.append([self.name,self.sanagi,self.prediction, self.birth])
        return newList

    def Print(self):
        print(self.name, self.sanagi,self.prediction, self.birth)


# To DataFrame
def PdDataFrame(data):
    col1='種類/性別'
    col2='サナギになった日'
    col3='羽化予想日'
    col4='羽化日'
    df = pd.DataFrame(data,columns=[col1,col2,col3,col4])
    return df

# Create table
def PltTable(df,titleName,length):
    # index number(1-)
    row_names=[]
    for i in range(1,length + 1,1):
        row_names.append(i)
    
    fig, ax = plt.subplots(figsize=(6, 6))
    
    ax.set(title= titleName)
    ax.axis('off')
    ax.axis('tight')
    
    ax.table(cellText=df.values,

            colLabels=df.columns,rowLabels=row_names,loc='upper center',
             bbox=[0, 0, 1, 1],
             )

    return fig

# time stamp
def Timestamp():
    dt1 = datetime.datetime.now()
    dt2 = dt1.strftime('%Y_%m%d_%H%M_%S')
    return dt2

# save table image as jpg file(Weather info as table)
def SaveTablefig(fig,currentdir,timestamp,figName):
    fig.savefig(currentdir  + '/fig/' + timestamp + figName + "_.jpg")

# ============================================================================
# data
# サナギになった日,チョウの種類/性別,羽化した日
# ============================================================================
l=[
    [datetime.date(2021,4,24),'ナミアゲハ:男', datetime.date(2021,5,4)],
    [datetime.date(2021,4,25),'ナミアゲハ:女', datetime.date(2021,5,7)],
    [datetime.date(2021,4,28),'ナミアゲハ:男', datetime.date(2021,5,8)],
    [datetime.date(2021,4,28),'ナミアゲハ:男', datetime.date(2021,5,8)],
    [datetime.date(2021,4,28),'ナミアゲハ:女', datetime.date(2021,5,8)],

    [datetime.date(2021,4,29),'ナミアゲハ:女', datetime.date(2021,5,9)],
    [datetime.date(2021,4,30),'ナミアゲハ:男', datetime.date(2021,5,10)],
    [datetime.date(2021,4,30),'ナミアゲハ:男', datetime.date(2021,5,10)],
    [datetime.date(2021,5,9) ,'ナミアゲハ:女', datetime.date(2021,5,20)],
    [datetime.date(2021,5,12),'ナミアゲハ:里子へ',0],

    [datetime.date(2021,5,13),'ナミアゲハ:里子へ',0],
    [datetime.date(2021,5,14),'ナミアゲハ:男',  datetime.date(2021,5,25)],
    [datetime.date(2021,5,14),'ナミアゲハ:男',  datetime.date(2021,5,22)],
    [datetime.date(2021,5,15),'クロアゲハ:男',  datetime.date(2021,5,27)],
    [datetime.date(2021,5,17),'キアゲハ1号:男', datetime.date(2021,5,27)],

    [datetime.date(2021,5,22),'ジャコウアゲハ1号:男', datetime.date(2021,6,2)],
    [datetime.date(2021,5,22),'キアゲハ2号:', datetime.date(2021,6,1)],
    [datetime.date(2021,5,23),'キアゲハ3号:', datetime.date(2021,5,2)],
    [datetime.date(2021,5,29),'ナガサキアゲハ:',0],
    [datetime.date(2021,5,29),'ジャコウアゲハ:',0],

    [datetime.date(2021,5,30),'ジャコウアゲハ:',0],
    [datetime.date(2021,6,5),'ナミアゲハ:',0],
    [datetime.date(2021,6,5),'ナミアゲハ:',0],
    [datetime.date(2021,6,5),'ナミアゲハ:',0]
    ]

# ===================================
# ready for exe
# ===================================
max = len(l)

# 2次元配列で宣言
newList=[[]]

# ===================================
# execution
# ===================================
# --------------------
# edit data
# --------------------
for i in range(0,max,1):
    # Sanagi class
    s = Sanagi(l[i][0],l[i][1],l[i][2])
    #s.Print()
    newList = s.RenewList()

# 最初のデータが空っぽなので、削除する
newList.pop(0)

# --------------------
# pandas dataframe
# --------------------
df = PdDataFrame(newList)
print(df)

# --------------------
# matplotlib table
# --------------------
len_sanagiList = len(newList)
tableName = 'アゲハチョウの羽化'

fig4 = PltTable(
                df,
                tableName,
                len_sanagiList
                )

# --------------------
# save data
# --------------------
currentdir = os.getcwd()
timestamp  = Timestamp()
SaveTablefig(
            fig4,
            currentdir,
            timestamp,
            tableName
            )


print("---------------")
print("end of line")

チョウチョ種類の情報、サナギになった日、その後に羽化した日を自分で入力する。が、羽化予想日は+10日して、改めてリストを作成する。

が、リストの追加方法が、最初に空っぽリストを作った後にリストを追記する流れなので、一番最初が空っぽになってしまうのがなんだかな~に。

仕方ないので、あとからindex[0]指定で要素を削除してるけど、、、なんだかな~だ。