#1 献立を選んでくれる便利ソフト ver1

1. 目的

 献立、買う食材を考えるのが面倒だったため、自動化して思考時間を無くすのが今回の目的です。

2.開発環境の紹介

 ver1は簡単なソフトのため、経験がない方々の参考になると思ったので、pythonのインストールとコード編集用のソフトの準備についても紹介します。

 1 Pythonのインストール
   下のリンク先からpythonをインストール
   https://www.python.org/
   自分の環境:python3.9.13

 2 コードを書くソフト(テキストエディタ)の用意
  vscodeをインストール
  インストール時のオプションで、下図のチェックボタンをすべてチェックを入れて            おいたほうが便利だと思います。

vscode 設定

3.プログラミング

 最初に、今回作成したプログラムをすべて載せます。

import tkinter as tk
import pandas as pd
import random

# 献立が書いてあるcsvファイルの読み込み
def read_csv_file():
    df_kondate = pd.read_csv('kondate/221203_kondate.csv')
    return df_kondate

# ルーレット開始関数
def start_roulette():
    global df_today_kondate
    df_kondate = read_csv_file()
    kondate_row_num = len(df_kondate)
    random_idx = random.randint(0, kondate_row_num -1)
    df_today_kondate = df_kondate.iloc[random_idx].copy()
    text.set(df_today_kondate)
    
# ファイルのプロット処理
if __name__ == "__main__":

    # ★ 初期設定
    # +-- global --
    df_today_kondate = pd.Series()

    # +--widgetの設定パラメータ--
    ButtonWidth = 15
    repeat_delay = 100
    repeat_interval = 500
    pa_dx = 20
    pa_dy = 10

    # ★ GUI
    # tkinterオブジェクトの作成(GUIを作るための準備)
    root = tk.Tk()
    root.title("こんだてマン")
    root.geometry("500x400")

    # メインフレームの作成と設置
    frame = tk.Frame(root)
    frame.pack(fill = tk.BOTH, padx = pa_dx, pady = pa_dy)

    # StringVarのインスタンスを格納する変数textの設定
    text = tk.StringVar(frame)
    text.set(df_today_kondate)

    # 今日の献立 ルーレットボタン widget:Button
    rouletteButton = tk.Button(frame, text="START", \
        font=("MSゴシック", "20", "bold"), width = ButtonWidth, \
            command = start_roulette, repeatdelay = repeat_delay,\
                repeatinterval = repeat_interval)
    
    # 結果の表示 widget:label
    label_today_kondate = tk.Label(frame, textvariable=text)

    # 各種ウィジェットの設置
    rouletteButton.pack()
    label_today_kondate.pack()

    root.mainloop()

3-1 アプリの構想(具体的なイメージに落とす)

 今日の献立を自動で決めたい。

 ー>ボタン(START)を押すと、今日の献立が表示される。

 ーー>ボタン(START)を押すと、献立のcsvファイルから今日の献立をランダムで

    選んで、画面に表示する。

GUIイメージ

3-2 ソフトを作るフォルダの指定

 ファイルエクスプローラで、任意の場所にソースコードを書いていくフォルダを作成します。そのフォルダの中で、右クリックからvs codeで開くを選択します。

3-3 フォルダの構成

 プログラムを書くmain.pyとkondateフォルダを3-2においてvscodeで開いたフォルダに 作成します。また、kondateフォルダの下にcsvファイル(kondate.csv)を用意します。

 csvファイルの内容は、下図を参考にしてください。

csvファイルの内容例

3-4 main.pyの解説

3-4-1 必要なライブラリのインストール

今回は、

GUIを使いたい!→tkinter
 表形式のデータを使いたい!→pandas
 乱数を使いたい!→random」
 ので、python標準で用意されているもの以外のライブラリはインストールします。
 (標準ではないライブラリはpandasのみ。)

 vscodeのターミナルのタブ(上部)から新しいターミナルを選択します。
 画面下部にターミナルが現れるので、下記コマンドを実行(入力し、エンター)し、       pandasをインストールします。 

 コマンド:pip install pandas

3-4-2 ライブラリインストール後にimport

 pythonでライブラリを使用するには、まずimport文を使って、pythonに使用するライブラリを教える必要がある。今回は、先ほどインストールしたpandasと標準ライブラリのtkinter, randomを使うため、main.pyの1~3行目のように
   import tkinter as tk
   import pandas as pd
   import random
と書きます。

※as ○○ 
 import △△△△だけでライブラリは使用できるが、as○○と記載することで、省略し て使用することができます。

3-4-3 if __name__=="__main__"のブロック

 pythonのプログラムに、この記載があるとまず、この部分からプログラムが実行されます。(→24行目からプログラムが実行されます。)

・初期値の記載:22~31行目
 まず、初期設定を記載します。プログラム全体で使いたい変数とGUIで設定するパラメータの初期値をプログラムの先頭に記載します。初期値をプログラムの先頭に記載するのは、プログラム中に突然意味の分からない数値が出てきたり、変更し忘れを防止する目的があります。


GUI windowの作成:35~37行目
 root = tk.Tk()でオブジェクトを作成し、root.title(名前)でタイトルを設定し、root.geometry(サイズ)でwindowのサイズを設定します。


GUI メインフレームの作成:39~41行目
 buttonやlabelのwidgetをまとめる役割を持つwidgetをframeと呼びます。まず、tk.frame(root)でフレームのオブジェクトを生成し、pack関数のfillとpadx, padyを設定し、window内の空きスペースを埋める方向とframeの外側の隙間を設定します。


GUI widgetの操作で変化する変数を設定(今回は今日の献立の内容):43~45行目
 変化する変数が文字の場合、StringVarを使用する。text = tk.StringVar(frame)で、frame内にオブジェクトを生成し、set関数で初めに表示したい文字を設定する。


GUI ルーレットボタン(今日の献立の自動選択開始のボタン):47~51行目
 Button関数で、frame内にボタンを生成する。ボタンの引数の設定は以下の通りです。
 tk.Button(親オブジェクト, ボタンの名前, フォント, ボタンの幅, ボタンを押すと同時に開始させる関数,  ボタン押し下げた時のクリック判定秒数, ボタン長押し時のクリック判定秒数)
 今回は以下のように使っています。※commandで指定しているstart_roulette関数は、次で説明します。
 rouletteButton = tk.Button(frame, text="START", font=("MSゴシック", "20", "bold"), width = ButtonWidth, command = start_roulette, repeatdelay = repeat_delay, repeatinterval = repeat_interval)


・start_roulette関数:10~17行目
 read_csv_file関数を呼び出します。read_csv_file関数(6~8行目)は、padasの関数を使い、献立が書かれたcsvファイルを読み込み、データフレームとして格納します。このデータフレームの行数分、乱数を計算し、抽出する行番号を指定します。この行番号を元に、データを抽出し、StringVarであるtextにセットします。こうすることで、GUI上の今日の献立はボタンのクリックと同時に変化します。


GUI 献立の表示:53~54行目
 textを作成しただけでは、GUI上に表示されません。labelに文字、数値を割り当てることで、GUI上に表示できます。そのため、tk.label(frame, textvariable = text)としてやることで、ボタンで変化する今日の献立をGUIに表示することができます。


GUI buttonとlabelの配置:56~58行目
 pack関数を使って、buttonとlabelを配置します。


GUI 無限ループ:60行目
 最後に、root.mainloop()と記載することで、ソフトが終了するまで永遠にGUIが入力を待ち続けるソフトになります。