首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python Quiz CLI & GUI

Python Quiz CLI & GUI
EN

Code Review用户
提问于 2016-12-06 09:25:51
回答 1查看 2.3K关注 0票数 7

最近,我收到了一项积极的编程任务的反馈,但我提到“有些事情可以做得更好”,我想知道这里是否有人能给我一个更具体的想法,说明什么可以改进&为什么。

有相当多的代码,但由于我是在一个非常入门的水平,我希望它不会太难找到一些基本的概念,需要工作。(此外,我也不太担心如何改进程序的功能-这是根据分配指南提供的-我更多地是在寻找如何改进当前功能的代码的建议)。

任务是创建一个食品测试GUI,从txt文件读取数据&创建/编辑该文件的CLI管理员。

CLI:

代码语言:javascript
复制
import json

# Repeatedly prompt for input until an integer is entered.
def inputInt(prompt):

    while True:

        try:
            answer = int(input(prompt))
        except ValueError:
            print('Please enter a number.')
            continue
        break

    return answer


# Repeatedly prompt for input until something (not whitespace) is entered.
def inputSomething(prompt):
    answer = input(prompt)

    while not answer.strip(): 
        answer = input('Please enter a non-whitespace value: ')

    return answer


# Open "data.txt" in write mode and write the data to it in JSON format.
def saveChanges(dataList):
    f = open('data.txt', 'w')
    json.dump(dataList, f, indent=4)
    f.close()

# If the file does not exist or does not contain JSON data, set "data" to an empty list instead.
try: 
    f = open('data.txt', 'r')
    data = json.load(f)
    f.close()
except (FileNotFoundError, ValueError):
    data = []

# Print welcome message, then enter the endless loop which prompts the user for a choice.
print('Welcome to the Food Quiz Admin Program.')

while True:
    print('Choose [a]dd, [l]ist, [s]earch, [v]iew, [d]elete or [q]uit.')
    choice = input('> ')

    if choice == 'a':

        print('Enter details for new menu item.')
        #Create new item and prompt for values
        item = {}
        item['name'] = inputSomething('Name: ')
        item['calories'] = inputInt('Calories: ')
        item['fat'] = inputInt('Fat: ')
        item['protien'] = inputInt('Protien: ')
        item['carbohydrates'] = inputInt('Carbohydrates: ')
        item['sodium'] = inputInt('Sodium: ')
        item['cholesterol'] = inputInt('Cholesterol: ')

        #Add item to data list and save changes
        data.append(item)
        saveChanges(data)


    elif choice == 'l':

        #Loop though and list the current menu items
        for i, item in enumerate(data):
            print(i, ': ', item)

    elif choice == 's':
        #Prompt for search term and convert to lowercase
        search = inputSomething('Search items by name: ').lower()

        #Loop through data and print items with search term in name
        for i, item in enumerate(data):
            if search in item['name'].lower():
                print(i, ': ', item)


    elif choice == 'v':

       while True:
           #Try to print item by index, reprompt if index is not valid
            try:
                indexItem = data[inputInt('Enter index of item to view: ')]

                print('{name}, Calories: {calories}, Fat: {fat} g, Protien: {protien} g, Carbohydrates: {carbohydrates} g, Cholesterol: {cholesterol} mg, Sodium: {sodium} mg'.format(**indexItem))              
            except IndexError:
                print('Invalid index. Please enter the index of an existing item.')
                continue

            break


    elif choice == 'd':

        while True:
            #Try to delete item by index, reprompt if index is not valid
            try:
               del data[inputInt(prompt)]

            except IndexError:
                print('Invalid index. Please enter the index of an existing item.')
                continue

            break

        saveChanges(data)             

    elif choice == 'q':
        # Quit the program
        print('Goodbye!')
        break


    else:
        # Print 'invalid choice' message
        print('Invalid choice.')

GUI:

代码语言:javascript
复制
import tkinter
import tkinter.messagebox
import tkinter.font
import json
import random


class ProgramGUI:

    def __init__(self):
        #Create main window
        self.main = tkinter.Tk()
        self.main.title('Food Quiz!')
        self.main.geometry('450x225')
        self.main.configure(bg='#5c9ead')

        self.font1 = tkinter.font.Font(family='Helvetica', size=18, weight='bold')
        self.font2 = tkinter.font.Font(family='Courier', size=14, weight='bold')

        #Load data from data.txt, show error message & terminate if file does not exist or is invalid
        try:
            self.__f = open('data.txt', 'r')
            self.data = json.load(self.__f)
            self.__f.close()

        except (FileNotFoundError, ValueError):
            tkinter.messagebox.showerror('Oops!', 'Missing/Invalid file.')
            self.main.destroy()
            return

        #Define components, initiliase score and label variables 
        self.components = ['calories', 'fat', 'cholesterol', 'sodium', 'carbohydrates', 'protien']
        self.qsAsked = 0
        self.qsCorrect = 0
        self.name1 = tkinter.StringVar()
        self.name2 = tkinter.StringVar()
        self.componentLab = tkinter.StringVar()

        #Create frames
        self.nameBox = tkinter.Frame(self.main, bg='#5c9ead')
        self.questionBox = tkinter.Frame(self.main, bg='#5c9ead')
        self.buttonBox = tkinter.Frame(self.main, bg='#5c9ead')

        #Create buttons and labels
        tkinter.Label(self.nameBox, textvariable=self.name1, font=self.font1, bg='#5c9ead', fg='#EFBC9B').pack(side='left')
        tkinter.Label(self.nameBox, text='vs', font=self.font2, bg='#5c9ead', fg='#fffdf7').pack(side='left')
        tkinter.Label(self.nameBox, textvariable=self.name2, font=self.font1, bg='#5c9ead', fg='#EFBC9B').pack(side='left')
        tkinter.Label(self.questionBox, text='Which one has more...', font=self.font2, bg='#5c9ead', fg='#fffdf7').pack()
        tkinter.Label(self.questionBox, textvariable=self.componentLab, font=self.font1, bg='#5c9ead', fg='#EFBC9B').pack()
        tkinter.Button(self.buttonBox, textvariable=self.name1, font=self.font2, bg='#EFBC9B', fg='#FFFDF7', command=lambda: self.checkAnswer('left')).pack(side='left')
        tkinter.Button(self.buttonBox, text='Roughly Equal', font=self.font2, bg='#EFBC9B', fg='#FFFDF7', command=lambda: self.checkAnswer('middle')).pack(side='left', padx=5)
        tkinter.Button(self.buttonBox, textvariable=self.name2, font=self.font2, bg='#EFBC9B', fg='#FFFDF7',command=lambda: self.checkAnswer('right')).pack(side='left')

        self.nameBox.pack(pady=10)
        self.questionBox.pack(pady=10)
        self.buttonBox.pack(pady=20)

        #Show first question
        self.showQuestion()

        #Start main loop
        tkinter.mainloop()

    def showQuestion(self):
        #Create/update question attributes
        self.items = random.sample(self.data, 2)
        self.component = random.choice(self.components)

        #Update labels
        self.name1.set(self.items[0].get('name'))
        self.name2.set(self.items[1].get('name'))
        self.componentLab.set(self.component)

    def checkAnswer(self, clickedButton):
        #Update question counter and get values to compare
        self.qsAsked += 1
        self.val1 =  self.items[0].get(self.component)
        self.val2 =  self.items[1].get(self.component)
        #Define left button check (left > right), right button check (right > left) and middle button check (both values are within 10% of each other, assuming val1 is > 0)
        self.buttons = {'left': self.val1 > self.val2, 'right': self.val2 > self.val1, 'middle': self.val1 * 10 / 11 <= self.val2 <= self.val1 * 11 / 10}

        #Select check, update correct counter and display appropriate message 
        if self.buttons.get(clickedButton):
            self.qsCorrect +=1
            self.scoreMsg = 'Your score so far is ' + str(self.qsCorrect) + '/' + str(self.qsAsked)
            tkinter.messagebox.showinfo('Correct!', 'You got it right. Your score so far is ' + str(self.qsCorrect) + '/' + str(self.qsAsked))

        else:
            tkinter.messagebox.showerror('Incorrect!', 'You got it wrong. Your score so far is ' + str(self.qsCorrect) + '/' + str(self.qsAsked))

        #Generate new question
        self.showQuestion()

# Create an object of the ProgramGUI class to begin the program.
gui = ProgramGUI()
EN

回答 1

Code Review用户

回答已采纳

发布于 2016-12-07 21:34:31

非常好!你的开局很好。

在CLI代码中,我会将每个选项的代码放在自己的函数中,而不是将所有这些都放在主块中。它使它更容易理解,而且不需要太多的工作。

另外,FYI,'protien‘是拼写为’蛋白质‘。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/149072

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档