โปรแกรมจัดการงานใน Python

Oct 08 2020

ฉันสร้างโปรแกรมง่ายๆใน Python

  • เก็บงานไว้ในไฟล์
  • อนุญาตให้ผู้ใช้จัดการได้

ฉันสนใจว่าการใช้งานของฉันมีประสิทธิภาพหรือไม่และฉันจะทำอะไรให้ดีขึ้นได้ไหม ฉันไม่แน่ใจว่าการโหลดข้อมูลทั้งหมดจากไฟล์ไปยังหน่วยความจำและบันทึกไว้ในไฟล์อีกครั้งเป็นวิธีที่ดีในการใช้งานการบันทึกรายการหรือไม่

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

คำตอบ

3 AryanParekh Oct 08 2020 at 20:53

เริ่มจากด้านบนสุด

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

เป็นที่ชัดเจนสำหรับฉันว่าคุณต้องการสร้างตัวแปรและกำหนดจำนวนเต็มให้พวกเขาดังนั้นคุณจึงไม่ต้องใช้ตัวเลขวิเศษที่ไหนเลยขอชื่นชมคุณสำหรับสิ่งนี้ มีวิธีที่ดีกว่ามากในการนำแนวคิดนี้ไปใช้ใน python

การแจงนับ: Enum

การแจงนับใน Python

การแจงนับคือชุดของชื่อสัญลักษณ์
(สมาชิก) ที่ผูกไว้กับค่าคงที่ที่ไม่ซ้ำกัน

การสร้างไฟล์ Enum

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

สิ่งนี้ดูชัดเจนกว่าตัวแปรทั่วโลกแบบสุ่ม นอกจากนี้คุณยังสามารถย้ำผ่านการแจงนับและแสดงค่าของมันที่มีชื่อ

print(Choices.add_task.name)

add_task

print(Choices.add_task.value) 

1

ใช้ฟังก์ชันอื่น ๆ

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

ทำไมเราไม่ย้ายสิ่งนี้ไปเป็นฟังก์ชันที่เรียกว่าread_task_file()?
วิธีนี้เป็นอย่างมากที่ชัดเจนกับผมคุณคุณหลังจากปีอ่านโครงการเก่าและคนอื่นที่จะเคยอ่านรหัสนี้ว่าสายไม่กี่คนของรหัสที่จะอ่านไฟล์งาน หากไม่มีสิ่งนั้นเราต้องอ่านโค้ดอย่างละเอียดและเข้าใจวัตถุประสงค์ของมัน

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

ตอนนี้การรับงานคือ

tasks = read_task_file()

สิ่งนี้ใช้กับชุดรหัสถัดไปซึ่งจะให้ผู้ใช้ป้อนตัวเลือกเพื่อให้เราดำเนินการได้

การแยกส่วนที่เราอ่านตัวเลือกจากผู้ใช้และดำเนินการในฟังก์ชันจะมีลักษณะดังนี้

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

หมายเหตุ: Choices._value2member_map_จะเป็นค่าทั้งหมดในการแจงนับ

นี่ดูสะอาดขึ้นมาก! เราขจัดความจำเป็นที่จะต้องมีการวนซ้ำซึ่งจะตรวจสอบทุกกรณีฟังก์ชันจะส่งคืนchoiceเมื่อมีอินพุตที่ถูกต้องเท่านั้น

ดังที่ฉันได้กล่าวไปแล้วให้แยกงานออกเป็นฟังก์ชันและทุกอย่างเมื่อจำเป็น ฉันทำเหมือนกันสำหรับ 4 งานหลัก (4 ตัวเลือก)


แสดงรายการงาน

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 add_new_task(tasks):
    return input("What task would you like to finish ?: ")
    tasks.append(task)

ลบงาน

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 update_task_file(tasks):
    file = open('tasks', 'w+')
    for x in tasks:
        file.write(x + '\n')

อะไรคือจุดสำคัญของการมีฟังก์ชั่นนับล้านเมื่อฉันสามารถใส่ทุกอย่างได้เหมือนที่เคยทำมาแล้ว? ตอนนี้เมื่อคุณต้องเล่นเกม

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)

นี่คือข้อได้เปรียบหลักของการมีฟังก์ชันที่พิมพ์มาก

กำลังล้างหน้าจอและรอการป้อนข้อมูล

เนื่องจากไม่มีกราฟิกเราจะเห็นว่าหลังจากมีตัวเลือกไม่กี่ตัวเทอร์มินัลดูแปลก ๆ เล็กน้อย

เราสามารถปรับปรุงสิ่งนี้ได้โดยเพียงล้างหน้าจอหลังจากแต่ละตัวเลือกจากนั้นรอให้ผู้ใช้กดปุ่ม

การล้างเทอร์มินัล

มีไม่กี่วิธี วิธียอดนิยมคือใช้ในos.system("cls")กรณีที่คุณใช้งานwindows แต่การเรียกสิ่งนี้มีราคาค่อนข้างแพงและยังทำให้โปรแกรมของคุณต้องพึ่งพาแพลตฟอร์ม

คุณทำได้

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

และจะได้ผลเช่นกัน

กำลังรอการป้อนข้อมูล

การเพิ่มบรรทัดนี้input("Press any key to continue...")จะรอการตอบกลับของผู้ใช้ก่อนที่จะแสดงตัวเลือกทั้งหมดอีกครั้งทำให้ประสบการณ์การใช้งานดีขึ้น

สุดท้าย

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