Aufgabenverwaltungsprogramm in Python
Ich habe ein einfaches Programm in Python erstellt
- speichert Aufgaben in der Datei
- ermöglicht dem Benutzer, sie zu verwalten.
Ich bin interessiert, ob meine Implementierung effizient ist und ob ich etwas besser machen könnte. Ich bin mir nicht sicher, ob das Laden aller Daten aus der Datei in den Speicher und das erneute Speichern in der Datei eine gute Möglichkeit ist, Aufgaben zum Speichern von Listen zu implementieren.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
CHOICE_LIST_TASKS = 1
CHOICE_ADD_TASK = 2
CHOICE_REMOVE_TASK = 3
CHOICE_QUIT = 4
def read_int(prompt='> ', errmsg='Invalid number!'):
num = None
while num is None:
try:
num = int(input(prompt))
except ValueError:
print(errmsg)
return num
def display_menu():
print('What do you want to do?')
print('[1] List all tasks')
print('[2] Add a new task')
print('[3] Delete task')
print('[4] Quit')
choice = None
file = None
if not os.path.exists('tasks'):
file = open('tasks', 'w+')
else:
file = open('tasks', 'r+')
tasks = []
for line in file.readlines():
tasks.append(line.strip())
while choice != CHOICE_QUIT:
display_menu()
choice = read_int()
if choice == CHOICE_LIST_TASKS:
if len(tasks) == 0:
print('Task list is empty!')
else:
print('Tasks:')
for x in tasks:
print(x)
elif choice == CHOICE_ADD_TASK:
desc = input('Which task do you want to do? ')
index = tasks.append(desc)
print('Successfully added a new task!')
elif choice == CHOICE_REMOVE_TASK:
if len(tasks) == 0:
print('Task list is empty!')
else:
for x in tasks:
print(tasks.index(x), x)
index = read_int('Which task do you want to delete? ')
try:
tasks.pop(index)
print('Successfully deleted task!')
except IndexError:
print('Please enter proper task number')
elif choice == CHOICE_QUIT:
print('Good bye!')
else:
print('Invalid choice!')
file = open('tasks', 'w+')
for x in tasks:
file.write(x + '\n')
Antworten
Beginnen wir ganz oben.
CHOICE_LIST_TASKS = 1
CHOICE_ADD_TASK = 2
CHOICE_REMOVE_TASK = 3
CHOICE_QUIT = 4
Mir ist klar, dass Sie Variablen erstellen und ihnen bestimmte Ganzzahlen zuweisen möchten, damit Sie nirgendwo magische Zahlen verwenden müssen. Ein großes Lob dafür. Es gibt einen viel besseren Weg, um diese Idee in Python umzusetzen
Aufzählungen: Enum
Aufzählungen in Python
Eine Aufzählung ist eine Reihe von symbolischen Namen
(Mitgliedern), die an eindeutige, konstante Werte gebunden sind
Erstellen eines Enum
class Choices(Enum):
list_task = 1
add_task = 2
remove_task = 3
quit = 4
Dies sieht bereits viel klarer aus als zufällige globale Variablen. Sie können die Aufzählung auch durchlaufen und ihre Werte mit Namen anzeigen .
print(Choices.add_task.name)
Aufgabe hinzufügen
print(Choices.add_task.value)
1
Verwenden Sie mehr Funktionen
file = None
if not os.path.exists('tasks'):
file = open('tasks', 'w+')
else:
file = open('tasks', 'r+')
tasks = []
for line in file.readlines():
tasks.append(line.strip())
Warum können wir dies nicht in eine Funktion namens verschieben read_task_file()?
Auf diese Weise ist mir, Ihnen, Ihnen, nach einem Jahr beim Lesen alter Projekte und jedem anderen, der diesen Code jemals lesen wird, sehr klar, dass diese wenigen Codezeilen die Aufgabendatei lesen werden . Ohne das muss man den Code gründlich lesen und seinen Zweck verstehen.
def read_task_file():
file = None
if not os.path.exists('tasks'):
file = open('tasks', 'w+')
else:
file = open('tasks', 'r+')
tasks = []
for line in file.readlines():
tasks.append(line.strip())
return tasks
Jetzt bekommen die Aufgaben
tasks = read_task_file()
Dies gilt auch für den nächsten Codesatz, mit dem der Benutzer seine Auswahl eingeben kann, damit wir ihn ausführen können.
Das Herausrechnen des Teils, in dem wir eine Auswahl vom Benutzer lesen und in eine Funktion ausführen, würde so aussehen
def read_task_choice():
display_menu()
choice = read_int()
if choice not in Choices._value2member_map_:
print("Invalid input! Please enter a correct choice\n")
read_task_choice()
Hinweis: Choices._value2member_map_Alle Werte in einer Aufzählung werden angezeigt.
Das sieht schon viel sauberer aus! Wir müssen es nicht mehr in einer Schleife haben, in der alle Fälle überprüft werden. Die Funktion wird nur zurückgegeben, choicewenn eine gültige Eingabe vorliegt.
Berücksichtigen Sie, wie gesagt, die Arbeit bei Bedarf in Funktionen und alle diese. Ich habe das gleiche für die 4 Hauptjobs getan (die 4 Auswahlmöglichkeiten).
Aufgaben auflisten
def list_tasks(tasks):
if len(tasks) == 0:
print("Task list is empty!")
return None
for i in range(len(tasks)):
print(f"{i} {tasks[i]}")
Neue Aufgabe hinzufügen
def add_new_task(tasks):
return input("What task would you like to finish ?: ")
tasks.append(task)
Aufgabe entfernen
def remove_task(tasks):
if len(tasks) == 0:
print("Task list is already empty!")
return None
list_tasks(tasks)
task = int(input(("Which task would you like to remove: ?")))
if task < 0 or task >= len(tasks):
print("Invalid input! Please select an appropriate task")
remove_task(tasks)
tasks.pop(task)
Und schlussendlich
Aufgabendatei aktualisieren
def update_task_file(tasks):
file = open('tasks', 'w+')
for x in tasks:
file.write(x + '\n')
Was bringt es, Millionen von Funktionen zu haben, wenn ich alles so platzieren kann, wie ich es bereits getan habe? Jetzt, wenn Sie das Spiel spielen müssen
tasks = read_task_file()
while True:
choice = read_task_choice()
if choice == Choices.list_task.value:
list_tasks(tasks)
elif choice == Choices.add_task.value:
add_new_task(tasks)
elif choice == Choices.remove_task.value:
remove_task(tasks)
else:
break
update_task_file(tasks)
Dies ist der Hauptvorteil stark typisierter Funktionen.
Bildschirm löschen und auf Eingabe warten
Aufgrund des Fehlens von Grafiken können wir feststellen, dass das Terminal nach einigen Auswahlmöglichkeiten etwas seltsam aussieht
Wir können dies verbessern, indem wir nach jeder Auswahl einfach den Bildschirm löschen und dann warten, bis der Benutzer eine Taste drückt
Terminal löschen
Es gibt einige Möglichkeiten. Eine beliebte Methode ist die Verwendung os.system("cls")unter Windows. Dies ist jedoch recht teuer und macht Ihr Programm plattformabhängiger.
Du kannst tun
print(chr(27) + "[2J")
Und das wird auch funktionieren.
Warten auf Eingabe
Durch Hinzufügen dieser Zeile input("Press any key to continue...")wird auf die Antwort des Benutzers gewartet, bevor alle Auswahlmöglichkeiten erneut angezeigt werden, um die Benutzererfahrung zu verbessern.
Finale
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
from enum import Enum
class Choices(Enum):
list_task = 1
add_task = 2
remove_task = 3
quit = 4
def read_int(prompt='> ', errmsg='Invalid number!'):
num = None
while num is None:
try:
num = int(input(prompt))
except ValueError:
print(errmsg)
return num
def display_menu():
print('What do you want to do?')
print('[1] List all tasks')
print('[2] Add a new task')
print('[3] Delete task')
print('[4] Quit')
def read_task_file():
file = None
if not os.path.exists('tasks'):
file = open('tasks', 'w+')
else:
file = open('tasks', 'r+')
tasks = []
for line in file.readlines():
tasks.append(line.strip())
return tasks
def update_task_file(tasks):
file = open('tasks', 'w+')
for x in tasks:
file.write(x + '\n')
def read_task_choice():
display_menu()
choice = read_int()
if choice not in Choices._value2member_map_:
print("Invalid input! Please enter a correct choice\n")
read_task_choice()
return choice
def add_new_task(tasks):
task = input("What task would you like to do: ")
tasks.append(task)
def list_tasks(tasks):
if len(tasks) == 0:
print("Task list is empty!")
return None
for i in range(len(tasks)):
print(f"{i} {tasks[i]}")
def remove_task(tasks):
if len(tasks) == 0:
print("Task list is already empty!")
return None
list_tasks(tasks)
task = int(input(("Which task would you like to remove: ?")))
if task < 0 or task >= len(tasks):
print("Invalid input! Please select an appropriate task")
remove_task(tasks)
tasks.pop(task)
def clear_screen():
print(chr(27) + "[2J")
def pause():
input("Press any key to continue...")
tasks = read_task_file()
while True:
clear_screen()
choice = read_task_choice()
if choice == Choices.list_task.value:
list_tasks(tasks)
elif choice == Choices.add_task.value:
add_new_task(tasks)
elif choice == Choices.remove_task.value:
remove_task(tasks)
else:
break
update_task_file(tasks)
pause()