首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python初学者-餐厅软件项目

Python初学者-餐厅软件项目
EN

Code Review用户
提问于 2020-12-29 13:26:43
回答 2查看 302关注 0票数 4

这是我的项目(测试版)后,学习3周。我花了差不多30个小时的写作和研究。我希望有一个基于我的初级水平的评论。我为此感到非常自豪,这对我来说是一项艰苦的工作。

学会了..。文件管理,控制if for while循环,整数和字符串,列出字典和元组。

代码:

代码语言:javascript
复制
#C:\restaurant software
with open('names.txt', 'r') as r :
    f_n = r.read().splitlines()
print("Welcome to NAME.app")
##############
# USER LOGIN #
##############
while True:
    name = input("""
    \n - Insert name to logg in
    \n - ADD to save new user
    \n - LIST to see saved users
    \n - REMOVE to delete a user
    \n - EXIT to finish
    \n - ...""")

    lname = name.lower()

    if lname == "add":
        n_input = input("Name:")
        with open('names.txt', 'a') as f:
            f.write(n_input + '\n')

    elif lname == "list":
        with open('names.txt') as f:
            print(f.read().splitlines())
            f.close()

    elif name in f_n:
        print("Logged as", name.upper())
        user = name
        input('Welcome, press enter to continue \n')
        break

    elif lname == 'remove':
        rem = input("Insert user name to remove \n ...")
        with open('names.txt', 'r+') as f:
            l = f.readlines()
            l = [z for z in l if rem not in z]
        with open('names.txt', 'w') as f:
            f.writelines(l)

    elif lname == "exit":
        exit()
####################
# TABLE MANAGEMENT #
####################
#C:\restaurant software
while True:
    action = input ('''
 - NEW table
    \n - ADD table
    \n - BILL
    \n - CLOSING
    \n - EXIT
    \n - ... ''')

    d = {'(1) chburger': 19,'(2) bncburger': 23,'(3) plpasta': 6}

    if action == 'new' :
        tn = input('Insert table number \n - ...')
        name = 'T' + tn
        t = open(name + '.txt', 'w+')
        print('Done')

    elif action.lower() == 'add':

# Select table
        table = input ('Select desired table number: \n - ...')
        fulltab = 'T' + table
        with open(fulltab + '.txt', 'w+') as f :

# Order list and add Order
            while True:
                for k, v in d.items() :
                    print(k, v)
                addprod = input('Insert order. \n - ...')
                for k, v in d.items() :
                    if addprod == k[1] :
                        f.write(str(v) + '\n')

#Option to continue.
                q = input('Add more? y/n \n -...')
                if q.lower() == 'y' : continue
                if q.lower() == 'n' : break

 #File as F

    elif action.lower() == 'bill' :
        p_b = input('Please insert number of table. \n -... ')
        with open (('T' + p_b)+ '.txt', 'r+') as p :
            tobill = 0
            for line in p : tobill = int(tobill) + int(line)

            xtra = input('Group table (+10 ppl)? y/n: \n')
            if xtra == 'y' :
                tobill = tobill + (tobill/100)*10
                print('SERVICE CHARGE ADDED.')

            elif xtra == 'n' : print ('Processing bill...')
            print('Total to pay:', tobill)
            print('Serviced by', user)

            #### Closing added part to bill.
            with open('closing.txt', 'a+') as f :
                f.write(str(tobill) + '\n')

# Closing days balance.
    elif action.lower() == 'closing' :
        date = input('Please enter DATE. ')
        with open('closing.txt', 'r+') as f :
            result = 0
            for line in f : result = int(result) + int(line)
            print('Closing is...')
            print(result)
            print('Today tips', (result / 100 * 10))
        current_closing = 'C:restaurant software\\closing.txt'
        old_closing = 'C:restaurant software\\' + date + '.txt'
        import os
        os.rename(current_closing, old_closing)
        print('Day closed, find the closing balance in the specific dated document.')
# Exit command.
    elif action.lower() == 'exit' :
        exit()

我知道我必须改进登录系统,有可能有人可以输入的名字和更多的东西。

在开始这个项目之前,我写的最大的一行是30行。

EN

回答 2

Code Review用户

发布于 2020-12-30 00:10:49

函数

学习功能。您的代码将从分解为函数中得到很大好处。

Bugs

用户管理

  • 如果您添加了"Anne“的名称,则在退出并重新启动程序之前,您不能使用"Anne”的名称登录。
  • 如果您删除"Anne“的名称,您仍然可以使用"Anne”的名称登录,直到退出并重新启动程序为止。
  • 如果你删除“安妮”这个名字,它也会删除“玛丽-安妮”这个名字。
票数 4
EN

Code Review用户

发布于 2020-12-30 23:27:24

文件存储

文本文件不便于查找。因此,您的下一个逻辑步骤应该是了解数据库和SQL。使用Python,您可以使用SQLite构建一个小型的、独立的数据库文件。

安全

输入用户名是不够的,也应该有一个密码。我认为这是为了一个家族企业,或者是一小群非常信任的人。说到问责,我建议您熟悉Python日志模块。我会将所有有意义的事件记录到一个文件中。例如,当预订一张桌子时,知道是谁执行了该操作,以及何时进行,这是很有趣的。然后,这样的一行将导致在日志文件中添加一个时间戳条目:

代码语言:javascript
复制
logger.info(f"Table #{table_number} booked by user {username}")

同样,当现金兑现,这类事件应该被记录(谁-什么时候),最好不要在一个容易被篡改的地方,即使我知道你不是一家银行。

不要重复你自己(干)

有很多重复(如with open('names.txt', 'r+') as f: )。应该将文件名(和路径)声明为脚本顶部的“常量”变量一次。然后将代码分解为小函数。例如,一个函数要检查用户名是否有效,它必须返回True或False。每个菜单项都应该调用一个函数,以便更好地分离任务,并尽可能保持代码的简洁性。

这些文件当然非常小,但是要优化程序,您可以在启动程序时加载一次列表。只有在发生更改时才重新加载它们。

用户输入

编码风格

import os这样的导入应该位于脚本的顶部,而不是在使用某些函数之前声明。熟悉PEP8编码规则。这是:with open('closing.txt', 'a+') as f :应该写成:with open('closing.txt', 'a+') as f:。在代码的某些部分中,您做得很好,但并不是在任何地方都这样。一致性很重要,PEP8被认为是Python程序员的圣经。

我建议使用带有linter的编辑器,它将有助于执行这些规则并突出显示有问题的行。

对文件使用上下文管理器是件好事,但不必在这里显式关闭该文件:

代码语言:javascript
复制
elif lname == "list":
    with open('names.txt') as f:
        print(f.read().splitlines())
        f.close()

只要您坚持这种方法,这是推荐的方法,而不仅仅是针对文件。

给出更多关于变量命名的想法。例如,在此代码中,名称f_n是不直观的:

代码语言:javascript
复制
elif name in f_n:
    print("Logged as", name.upper())
    user = name
    input('Welcome, press enter to continue \n')
    break

应该是user_names,valid_users或者类似的东西。然后你可以写:

代码语言:javascript
复制
if user in valid_users:
    # ...

另一个选定的片段:

代码语言:javascript
复制
p_b = input('Please insert number of table. \n -... ')
with open (('T' + p_b)+ '.txt', 'r+') as p :

p_b是什么意思?付账单吧我想..。幸运的是,这个变量是在上面定义的,我不需要滚动500行代码来找出它的含义。在我看来,p_b应该简单地命名为table_number。使用更长和更有意义的变量名是不受惩罚的。只有好处。

For循环的格式应该如下:

代码语言:javascript
复制
for line in p:
    tobill = int(tobill) + int(line)

而不是:

代码语言:javascript
复制
for line in p : tobill = int(tobill) + int(line)

另一条更神秘的台词:

代码语言:javascript
复制
l = [z for z in l if rem not in z]

如果不分析您的代码,就无法立即看出这行代码在做什么。即使现在对您来说已经很清楚了,但几个月后您将不会重新访问您的代码。

若要进一步评论违规代码:

代码语言:javascript
复制
elif lname == 'remove':
    rem = input("Insert user name to remove \n ...")
    with open('names.txt', 'r+') as f:
        l = f.readlines()
        l = [z for z in l if rem not in z]
    with open('names.txt', 'w') as f:
        f.writelines(l)

首先,您每次都要重新生成用户列表。在处理大型文件之前,性能影响是可以忽略不计的。显然,使用文件对您所做的工作有其限制。但是这种方法是不安全的,如果此代码部分出现异常,则可以销毁该文件。与文件I/O相关的异常在权限问题、磁盘空间不足或路径错误之间非常常见。使用数据库(与事务处理)的另一个原因。

假设您在读取文件名时出错,并且意外地从另一个碰巧存在的文件中读取。当您写信给names.txt时,您认为最终的结果会是什么?这也是不重复自己的另一个原因。将文件名和路径一次性定义为常量。在某个时候,您可能不得不更改文件名或路径,最好只在一个地方更改它,而不是手动检查所有代码,这样做可能会遗漏一行代码,或者搜索和替换可能是不完整的。

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

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

复制
相关文章

相似问题

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