医師含む医療従事者は当直があります。
そして当直票の作成ってかなり手間と思います。
私自身は作成したことありませんが、希望日や除外日、回数の調整など大変ですね。
作る予定はありませんが、こういうことこそ機械化できそうだなと思います。
調べてみたら当直作成アプリっていうのは、既にあるみたいですね。
Appstoreにもありました。
無料もありそうですが、有料もあるので、自分でChatGPTを駆使して作成してみました。
当直表アプリの作り方を教えてもらう
以下はChatGPTからの返信。
1. 入力情報の収集
まず、以下の情報を入力として収集する必要があります。
当直する人数
n
2. スケジュールの作成
当直表を作成するためのロジックを構築します。以下のようなロジックが考えられます。
当直表をランダムに生成
同じ人が連続して当直に入らないように調整
当直できない日を考慮してスケジュールを調整
3. 出力
作成されたスケジュールをユーザーに表示します。テーブル形式やカレンダー形式など、見やすい形で出力するとよいでしょう。
4. エラーハンドリング
入力エラーやスケジューリングに失敗した場合など、エラーハンドリングも必要になるでしょう。
5. UI/UXの設計
使いやすいインターフェイスを設計することも重要です。当直人数の入力、当直できない日の選択など、操作が直感的に行えるように設計します。
GUIで作りたい。
GUI(Graphical User Interface)を使用して当直表を作成するアプリケーションを開発する場合、以下のような手順が考えられます。
1. 使用するフレームワークの選定
PythonでGUIを開発するためには、Tkinter、PyQt、Kivyなどのライブラリがあります。プロジェクトの要件に応じて適切なものを選ぶとよいでしょう。
2. GUIデザインの作成
画面上での操作をどのように行うか、デザインを考えます。以下のコンポーネントを設置することが考えられます。
当直人数の入力フィールド
当直できない日の選択カレンダー
当直表の表示エリア
生成ボタンなどの操作ボタン
3. イベントハンドリングの設定
ボタンクリックなどのイベントに応じて、適切な処理を行うように設定します。
4. 当直表の生成ロジックの組み込み
上記で作成した当直表の生成ロジックをGUIと連携させます。
5. 出力と表示
生成された当直表をテーブルやカレンダー形式で表示します。
最初のコードはこれ
import tkinter as tk
import numpy as np
def generate_schedule():
try:
n = int(entry_n.get())
m = 10 # 例として当直日数を10に設定
# 当直できない日の取得
unavailable_days = {i: [j for j in range(m) if checkboxes[i][j].get() == 1] for i in range(n)}
# 当直表の初期化
duty_schedule = [-1] * m
# 当直表の作成
for day in range(m):
prev_duty = duty_schedule[day – 1] if day > 0 else -1
candidates = [i for i in range(n) if i != prev_duty and day not in unavailable_days[i]]
if not candidates:
raise Exception(“スケジュールを作成できません。”)
duty_schedule[day] = np.random.choice(candidates)
# 結果の表示
text_schedule.delete(1.0, tk.END)
text_schedule.insert(tk.END, “\n”.join([f”日{day+1}: 人{duty}” for day, duty in enumerate(duty_schedule)]))
except Exception as e:
text_schedule.delete(1.0, tk.END)
text_schedule.insert(tk.END, str(e))
def create_unavailable_days():
try:
n = int(entry_n.get())
for row in checkboxes:
for checkbox in row:
checkbox.pack_forget()
checkboxes.clear()
for i in range(n):
row = []
label = tk.Label(frame_unavailable_days, text=f”人{i}:”)
label.pack(side=tk.LEFT)
for j in range(10): # 10日分のチェックボックス
var = tk.IntVar()
checkbox = tk.Checkbutton(frame_unavailable_days, variable=var)
checkbox.pack(side=tk.LEFT)
row.append(var)
checkboxes.append(row)
except Exception as e:
text_schedule.delete(1.0, tk.END)
text_schedule.insert(tk.END, str(e))
# ウィンドウの作成
root = tk.Tk()
root.title(“当直表生成”)
# 当直人数の入力ラベルとフィールド
label_n = tk.Label(root, text=”当直人数:”)
label_n.pack()
entry_n = tk.Entry(root)
entry_n.pack()
# 当直できない日の選択
button_unavailable_days = tk.Button(root, text=”当直できない日を設定”, command=create_unavailable_days)
button_unavailable_days.pack()
frame_unavailable_days = tk.Frame(root)
frame_unavailable_days.pack()
checkboxes = []
# 生成ボタン
button_generate = tk.Button(root, text=”生成”, command=generate_schedule)
button_generate.pack()
# 当直表表示エリア
label_schedule = tk.Label(root, text=”当直表:”)
label_schedule.pack()
text_schedule = tk.Text(root)
text_schedule.pack()
# ウィンドウの表示
root.mainloop()
しかしIntel Math Kernel Library(MKL)に対するエラーが発生とのこと。
よくわかりませんが環境を変えたりしてやってみました。
でもずっとエラー出る。
Chat GPTに聞きました。
特にこのエラーはNumPyやSciPyなどの一部の科学計算ライブラリで見られることが一般的です。GUIのコードにNumPyを使用しているため、このエラーが発生していると思われますNumPyを使わずにコードを書き換えることも、このエラーを回避する方法です。
なるほど、よくわからんけどNumPyを敬遠しよう。
NumPyに依存しないコードを書いて
import tkinter as tk
import random
def generate_schedule():
try:
n = int(entry_n.get())
m = 10 # 例として当直日数を10に設定
# 当直できない日の取得
unavailable_days = {i: [j for j in range(m) if checkboxes[i][j].get() == 1] for i in range(n)}
# 当直表の初期化
duty_schedule = [-1] * m
# 当直表の作成
for day in range(m):
prev_duty = duty_schedule[day – 1] if day > 0 else -1
candidates = [i for i in range(n) if i != prev_duty and day not in unavailable_days[i]]
if not candidates:
raise Exception(“スケジュールを作成できません。”)
duty_schedule[day] = random.choice(candidates)
# 結果の表示
text_schedule.delete(1.0, tk.END)
text_schedule.insert(tk.END, “\n”.join([f”日{day+1}: 人{duty}” for day, duty in enumerate(duty_schedule)]))
except Exception as e:
text_schedule.delete(1.0, tk.END)
text_schedule.insert(tk.END, str(e))
def create_unavailable_days():
try:
n = int(entry_n.get())
for row in checkboxes:
for checkbox in row:
checkbox.pack_forget()
checkboxes.clear()
for i in range(n):
row = []
label = tk.Label(frame_unavailable_days, text=f”人{i}:”)
label.pack(side=tk.LEFT)
for j in range(10): # 10日分のチェックボックス
var = tk.IntVar()
checkbox = tk.Checkbutton(frame_unavailable_days, variable=var)
checkbox.pack(side=tk.LEFT)
row.append(var)
checkboxes.append(row)
except Exception as e:
text_schedule.delete(1.0, tk.END)
text_schedule.insert(tk.END, str(e))
# ウィンドウの作成
root = tk.Tk()
root.title(“当直表生成”)
# 当直人数の入力ラベルとフィールド
label_n = tk.Label(root, text=”当直人数:”)
label_n.pack()
entry_n = tk.Entry(root)
entry_n.pack()
# 当直できない日の選択
button_unavailable_days = tk.Button(root, text=”当直できない日を設定”, command=create_unavailable_days)
button_unavailable_days.pack()
frame_unavailable_days = tk.Frame(root)
frame_unavailable_days.pack()
checkboxes = []
# 生成ボタン
button_generate = tk.Button(root, text=”生成”, command=generate_schedule)
button_generate.pack()
# 当直表表示エリア
label_schedule = tk.Label(root, text=”当直表:”)
label_schedule.pack()
text_schedule = tk.Text(root)
text_schedule.pack()
# ウィンドウの表示
root.mainloop()
これでプロトタイプができましたが、色々とカスタマイズ。
ChatGPT 4にしてcode interpreterがありますから、こういうにさっきできたアプリの画像を添付してさらに修正箇所を指摘できるんですね。
便利です。
最終コード
import tkinter as tk
import calendar
import random
def generate_schedule():
try:
n = int(entry_n.get())
year = int(entry_year.get())
month = int(entry_month.get())
_, m = calendar.monthrange(year, month)
names.clear()
unavailable_days.clear()
# 名前と当直できない日の取得
for i in range(n):
unavailable_days.append([int(day) – 1 for day in entries_unavailable[i].get().split(“,”) if day])
names.append(entries_names[i].get())
# 当直表の初期化
duty_schedule = [-1] * m
# 当直表の作成
for day in range(m):
prev_duty = duty_schedule[day – 1] if day > 0 else -1
candidates = [i for i in range(n) if i != prev_duty and day not in unavailable_days[i]]
if not candidates:
raise Exception(“スケジュールを作成できません。”)
duty_schedule[day] = random.choice(candidates)
# カレンダーに結果を表示
for i, label in enumerate(labels_calendar):
label.config(text=””)
for day, duty in enumerate(duty_schedule):
labels_calendar[day + 7].config(text=f”{day+1}: {names[duty]}”)
except Exception as e:
text_schedule.delete(1.0, tk.END)
text_schedule.insert(tk.END, str(e))
def create_unavailable_days():
try:
n = int(entry_n.get())
for widget in frame_unavailable_days.winfo_children():
widget.destroy()
entries_unavailable.clear()
entries_names.clear()
for i in range(n):
frame = tk.Frame(frame_unavailable_days)
frame.pack(side=tk.TOP)
label = tk.Label(frame, text=f”人{i}の当直できない日:”)
label.pack(side=tk.LEFT)
entry = tk.Entry(frame)
entry.pack(side=tk.LEFT)
entries_unavailable.append(entry)
label_name = tk.Label(frame, text=f”名前:”)
label_name.pack(side=tk.LEFT)
entry_name = tk.Entry(frame)
entry_name.pack(side=tk.LEFT)
entries_names.append(entry_name)
except Exception as e:
text_schedule.delete(1.0, tk.END)
text_schedule.insert(tk.END, str(e))
# ウィンドウの作成
root = tk.Tk()
root.title(“当直表生成”)
# 当直人数の入力ラベルとフィールド
label_n = tk.Label(root, text=”当直人数:”)
label_n.pack()
entry_n = tk.Entry(root)
entry_n.pack()
# 年月の入力ラベルとフィールド
label_year = tk.Label(root, text=”年:”)
label_year.pack()
entry_year = tk.Entry(root)
entry_year.pack()
entry_year.insert(0, “2023”)
label_month = tk.Label(root, text=”月:”)
label_month.pack()
entry_month = tk.Entry(root)
entry_month.pack()
entry_month.insert(0, “8”)
# 当直できない日の選択
button_unavailable_days = tk.Button(root, text=”当直できない日と名前を設定”, command=create_unavailable_days)
button_unavailable_days.pack()
frame_unavailable_days = tk.Frame(root)
frame_unavailable_days.pack()
entries_unavailable = []
entries_names = []
names = []
unavailable_days = []
# カレンダーの作成
frame_calendar = tk.Frame(root)
frame_calendar.pack()
labels_calendar = []
# 曜日ラベル
days = [“月”, “火”, “水”, “木”, “金”, “土”, “日”]
for i, day in enumerate(days):
label_day = tk.Label(frame_calendar, text=day)
label_day.grid(row=0, column=i)
# 日付ラベル
for i in range(42): # 6週間分のラベル
label = tk.Label(frame_calendar, text=””)
label.grid(row=i//7 + 1, column=i%7)
labels_calendar.append(label)
# 生成ボタン
button_generate = tk.Button(root, text=”生成”, command=lambda: [generate_schedule()])
button_generate.pack()
# ウィンドウの表示
root.mainloop()
実際のものはこんな感じ。
この画面で年月日と当直人数を選択します.
そして当直できない日と名前を設定を押すと、以下の画面になります
左側にできない日、右側にはその人の名前を選択します。
入力してみます。
そうするとこんな感じに仕上がりました。
当直回数の設定をしていないので、ちょっとeの回数が多くなっています。笑
まとめ
Chat GPT 4を使って当直表アプリを作りました。
Chat GPT 3.5に比べてChat GPT 4の方がエラーコードが少ないです。
一回の入力でのコードを出力も多かったです。
ここからも、まだカスタマイズはできそうかなと思います。
ChatGPT4を使えば1時間弱でコードは作成できました。
改変してアプリストアに出すのが今後の目標です。
以上参考になれば幸いです。
抄読会をAIにまとめてもらおうと必死です。
コメント