恐る恐る ChatGPT を使ってプログラミングを始めてみます。
私の環境は、MacBook Air 2012 メモリ 4GB に OpenCore Legacy Patcher を使って未サポートのmacOS Big Sur 11.7.6をインストールしています。
もしかすると今後この環境がプログラミング上で不具合を起こすかもしれません。
前回では、オセロゲームを作ろうとしてうまくいきませんでした。今回はもう少し簡単なところで、Todo アプリを作ってみようと思います。
import SwiftUI
struct TodoItem: Identifiable {
let id = UUID()
var title: String
var details: String
var createdAt = Date()
var isCompleted = false
}
class TodoList: ObservableObject {
@Published var items = [TodoItem]()
func add(title: String, details: String) {
items.append(TodoItem(title: title, details: details))
}
func remove(item: TodoItem) {
if let index = items.firstIndex(where: { $0.id == item.id }) {
items.remove(at: index)
}
}
func toggleCompletion(item: TodoItem) {
if let index = items.firstIndex(where: { $0.id == item.id }) {
items[index].isCompleted.toggle()
}
}
}
struct ContentView: View {
@ObservedObject var todoList = TodoList()
@State var newTitle = ""
@State var newDetails = ""
var body: some View {
NavigationView {
List {
Section(header: Text("New Task")) {
TextField("Title", text: $newTitle)
TextField("Details", text: $newDetails)
Button("Add Task") {
todoList.add(title: newTitle, details: newDetails)
newTitle = ""
newDetails = ""
}
}
Section(header: Text("Tasks")) {
ForEach(todoList.items) { item in
HStack {
Button(action: {
todoList.toggleCompletion(item: item)
}) {
if item.isCompleted {
Image(systemName: "checkmark.circle.fill")
} else {
Image(systemName: "circle")
}
}
.buttonStyle(BorderlessButtonStyle())
VStack(alignment: .leading) {
Text(item.title)
.font(.headline)
Text(item.details)
.font(.subheadline)
}
Spacer()
Button(action: {
todoList.remove(item: item)
}) {
Image(systemName: "trash")
}
.buttonStyle(BorderlessButtonStyle())
}
}
}
}
.listStyle(DefaultListStyle())
.navigationTitle("ToDo List")
}
}
}
import SwiftUI
// SwiftUI のプログラムは @main と書かれた所から始まる決まりになっています。
@main
struct FooApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
// 次のクラスは、アプリケーションのウィンドウが閉じたら、
// アプリケーションも終了するようにするためのコードです。
// macOS のデフォルトではウィドウを閉じてもアプリケーションは終了しません。
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}
}
ToDo として機能しませんし、文字入力も受け付けてもらえません。しかし UI の出来としては良いように思います。
from tkinter import *
from tkinter import messagebox
from tkinter.ttk import *
import datetime
class TodoItem:
def __init__(self, title, details):
self.title = title
self.details = details
self.created_at = datetime.datetime.now()
self.completed = False
class TodoList:
def __init__(self):
self.items = []
def add(self, item):
self.items.append(item)
def remove(self, item):
self.items.remove(item)
def toggle_completion(self, item):
item.completed = not item.completed
class TodoApp:
def __init__(self, master):
self.master = master
master.title("Todo List")
master.geometry("400x400")
self.todo_list = TodoList()
self.title_label = Label(master, text="Title:")
self.title_label.pack()
self.title_entry = Entry(master)
self.title_entry.pack()
self.details_label = Label(master, text="Details:")
self.details_label.pack()
self.details_entry = Entry(master)
self.details_entry.pack()
self.add_button = Button(master, text="Add Task", command=self.add_task)
self.add_button.pack()
self.tasks_label = Label(master, text="Tasks:")
self.tasks_label.pack()
self.tasks_listbox = Listbox(master)
self.tasks_listbox.pack()
self.remove_button = Button(master, text="Remove Task", command=self.remove_task)
self.remove_button.pack()
self.complete_button = Button(master, text="Complete Task", command=self.toggle_completion)
self.complete_button.pack()
self.refresh_tasks()
def add_task(self):
title = self.title_entry.get()
details = self.details_entry.get()
item = TodoItem(title, details)
self.todo_list.add(item)
self.title_entry.delete(0, END)
self.details_entry.delete(0, END)
self.refresh_tasks()
def remove_task(self):
selection = self.tasks_listbox.curselection()
if not selection:
messagebox.showwarning("Error", "Please select a task to remove.")
return
index = selection[0]
item = self.todo_list.items[index]
self.todo_list.remove(item)
self.refresh_tasks()
def toggle_completion(self):
selection = self.tasks_listbox.curselection()
if not selection:
messagebox.showwarning("Error", "Please select a task to complete.")
return
index = selection[0]
item = self.todo_list.items[index]
self.todo_list.toggle_completion(item)
self.refresh_tasks()
def refresh_tasks(self):
self.tasks_listbox.delete(0, END)
for item in self.todo_list.items:
prefix = "[x] " if item.completed else "[ ] "
self.tasks_listbox.insert(END, prefix + item.title)
root = Tk()
app = TodoApp(root)
root.mainloop()
Detail(詳細)が表示されませんが、前回のオセロゲームと合わせても、今までで一番機能しています。
from tkinter import *
from tkinter import messagebox
import os
class TodoApp:
def __init__(self, master):
self.master = master
self.master.title("ToDo App")
self.master.geometry("300x300")
# Create a label
self.label = Label(self.master, text="Enter a task:")
self.label.pack()
# Create a task input box
self.task_input = Entry(self.master)
self.task_input.pack()
# Create a button to add task
self.add_button = Button(self.master, text="Add Task", command=self.add_task)
self.add_button.pack()
# Create a listbox to display tasks
self.task_list = Listbox(self.master)
self.task_list.pack()
# Create a button to remove selected task
self.remove_button = Button(self.master, text="Remove Task", command=self.remove_task)
self.remove_button.pack()
# Load tasks from file
self.load_tasks()
def add_task(self):
task = self.task_input.get()
if task:
self.task_list.insert(END, task)
self.task_input.delete(0, END)
self.save_tasks()
else:
messagebox.showwarning("Warning", "Please enter a task")
def remove_task(self):
selected_task = self.task_list.curselection()
if selected_task:
self.task_list.delete(selected_task)
self.save_tasks()
else:
messagebox.showwarning("Warning", "Please select a task to remove")
def load_tasks(self):
if os.path.exists("tasks.txt"):
with open("tasks.txt", "r") as f:
for task in f:
self.task_list.insert(END, task)
def save_tasks(self):
with open("tasks.txt", "w") as f:
for i in range(self.task_list.size()):
f.write(self.task_list.get(i) + "\n")
root = Tk()
app = TodoApp(root)
root.mainloop()
さっきより機能は減りましたが、項目の追加と削除、リストの保存ができ、再起動しても、以前のリストがちゃんと表示されます。これで編集機能が付けば、アプリケーションとしての最小必須機能をクリアしたことになりますが、一応これで Todo アプリは一行もコーディングすることなく完成したことにします。
今回はどんな質問したかについては書いていません。書くとキリがありません。ビルドしてエラーが出て、そのままそのエラーをコピーして、質問欄にペーストしての繰り返しです。 そして一応起動したら、起動したアプリの不具合箇所や、増やして欲しい機能などを、また質問します。その繰り返しです。
また、オセロゲームを作っているときは、カッコの閉じ忘れなどの初歩的なミスが多かったですが、今回はそれは出ませんでした。ChatGPT が恐ろしい勢いでノウハウを集積しているような気がします。今回で言えば、Python Tkinter の時にメインループを記述しないという癖がありました。これも数日後には修正されているかもしれません。なんか、Python の勉強をしたくなりましたw。以前にやってたんですが、もう忘れたというかw。それに Mac に標準で Python と TclTk がインストールされなくなってるんですね。Emacs が標準で入っていないことは気づいていたんですが。今回はあちこちのサイトを見て、なんとなく Tkinter が使えるようになりましたが、Mac に Python Tkinter 環境を構築する方法を整理したくなってきました。
ChatGPT は続けるかもしれませんが、率先して使って、ChatGPTのサンプルになるよりは、十分に情報が集積されてからのほうが、「オセロゲームを作ってください」で、一発でオセロゲームを作ってくれるようになってる気がしなくもないですねw。
Python を学習したくて Googole で検索したのですが、数が多すぎてどこが良いかわからなっかので、ChatGPT に質問してみました。
質問 Pythonを勉強下いのですが、どこのサイトが良いですか?日本語のサイトが良いです。
答え Pythonを学ぶには、以下の日本語のサイトが役立つでしょう。
質問 Tkinterを勉強したいのですが、どこか良いサイトを教えてください。日本語サイトが良いです。
答え
Tkinterを学ぶには、以下のウェブサイトが役立つかもしれません。すべて日本語で提供されています。
これらのサイトは、Python Tkinterを学ぶ上で役立つ情報がたくさんあります。これらのリソースを利用して、Python Tkinterの基礎から応用まで学んでください。
結構リンク切れがあります。また次のように言われることもあります。
「申し訳ありませんが、私は英語のみの対応となっており、日本語の情報を提供することができません。しかし、以下の日本語のTkinter学習リソースが役立つかもしれません。」
なんかやっぱりな〜という感じw、ごっつ傷ついた。もしかしてオセロゲームやTodoも英語で質問したらもっとちゃんとした答えが返ってきてたのかも