Python'da görev yönetimi programı

Oct 08 2020

Python'da basit bir program yaptım

  • görevleri dosyada depolar
  • kullanıcının bunları yönetmesine izin verir.

Uygulamamın verimli olup olmadığı ve daha iyi bir şey yapabilir miyim diye ilgileniyorum. Tüm verileri dosyadan belleğe yükleyip tekrar dosyaya kaydetmenin, liste kaydetme görevlerini gerçekleştirmenin iyi bir yolu olup olmadığından emin değilim.

#!/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')

Yanıtlar

3 AryanParekh Oct 08 2020 at 20:53

En baştan başlayalım.

CHOICE_LIST_TASKS = 1
CHOICE_ADD_TASK = 2
CHOICE_REMOVE_TASK = 3
CHOICE_QUIT = 4

Değişkenler oluşturmak ve onlara belirli tamsayılar atamak istediğinizi açıkça anladım, böylece hiçbir yerde sihirli sayılar kullanmak zorunda kalmazsınız, bunun için sizi tebrik ederiz. Bu fikri python'da uygulamanın çok daha iyi bir yolu var

Numaralandırmalar: Enum

Python'da Numaralandırmalar

Numaralandırma,
benzersiz, sabit değerlere bağlı bir sembolik adlar (üyeler) kümesidir.

yaratmak Enum

class Choices(Enum):
    list_task = 1
    add_task = 2 
    remove_task = 3
    quit = 4

Bu zaten rastgele küresel değişkenlerden çok daha net görünüyor. Ayrıca numaralandırmayı yineleyebilir ve değerlerini adlarla görüntüleyebilirsiniz .

print(Choices.add_task.name)

görev ekle

print(Choices.add_task.value) 

1

Daha fazla işlev kullanın

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())

Bunu neden adı verilen bir işleve taşıyamıyoruz read_task_file()?
Bu şekilde benim için, siz, bir yıl sonra eski projeleri okuduktan sonra siz ve bu kodu okuyacak olan herkes, bu birkaç satır kodun görev dosyasını okuyacağını son derece açık hale getiriyor . Bu olmadan, kişi kodu iyice okumalı ve amacını anlamalıdır.

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

şimdi görevleri almak

tasks = read_task_file()

Bu, bir sonraki kod kümesi için de geçerlidir ve bu, kullanıcının seçimini girmesine izin verir, böylece onu gerçekleştirebiliriz.

Kullanıcının bir seçimini okuduğumuz ve bir işleve dönüştürdüğümüz kısmı çarpanlarına ayırmak,

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()

Not: Choices._value2member_map_bir numaralandırmadaki tüm değerler olacaktır.

Bu zaten çok daha temiz görünüyor! Tüm durumları kontrol edeceği bir döngüde olması ihtiyacını ortadan kaldırıyoruz, işlev yalnızca choicegeçerli bir girdi olduğunda geri dönüyor .

Dediğim gibi, çalışmayı işlevlere ve gerektiğinde tüm işlevlere ayırın. Aynısını 4 ana iş için yaptım (4 seçenek).


Görevleri listeleyin

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]}")

Yeni görev ekle

def add_new_task(tasks):
    return input("What task would you like to finish ?: ")
    tasks.append(task)

Görevi kaldır

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)

Ve sonunda

Görev dosyasını güncelleyin

def update_task_file(tasks):
    file = open('tasks', 'w+')
    for x in tasks:
        file.write(x + '\n')

Her şeyi zaten yaptığım gibi koyabildiğimde milyonlarca işleve sahip olmanın anlamı nedir? Şimdi oyunu oynamak zorunda olduğun zaman

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)

Bu, güçlü yazılmış işlevlere sahip olmanın ana avantajıdır.

Ekranı temizlemek ve girişi beklemek

Grafiklerin olmaması nedeniyle, birkaç seçenekten sonra terminalin biraz tuhaf göründüğünü görebiliriz.

Her seçimden sonra ekranı temizleyerek ve ardından kullanıcının bir tuşa basmasını bekleyerek bunu iyileştirebiliriz

Terminali temizlemek

Birkaç yol var. Popüler bir yol, os.system("cls")pencerelerdeyseniz kullanmaktır, ancak bunu aramak oldukça pahalıdır ve programınızı daha platforma bağımlı hale getirir.

Yapabilirsin

print(chr(27) + "[2J")

Ve bu da işe yarayacak.

Giriş bekleniyor

Bu satırı eklemek input("Press any key to continue..."), tüm seçenekleri tekrar göstermeden önce kullanıcının yanıtını bekleyecek ve deneyimi daha iyi hale getirecektir.

Final

#!/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()