我的目标是创建一个“计算器”来计算我和妻子拥有的两套度假公寓的每月物业管理费。
我的目的是接受用户输入姓名、日期和租金,并计算这两个物业的物业管理费总额。我花了一些研究,尝试和错误来得到到达和离开的日期来计算每个客人入住的总夜晚数,但是我算出来了,一切都很好,并且通过了所有我能做的测试。
基本上,以下是步骤:
作为一个初学者,我是超级兴奋当我完成,我所有的测试通过!然而,作为一个初学者,我相信有一些事情我可以做得更好,并将高度赞赏任何批评你想提供。
import datetime
any_more_ps_guests = "yes"
total_ps_rental_fee = 0
while any_more_ps_guests == "yes":
ps_guest_name = input('Pacific Shores Guest Name: ')
ps_arrival_date_input = input("Arrival Date (xx/xx/xxxx): ")
ps_arrival_date_month = int(ps_arrival_date_input[:2])
ps_arrival_date_day = int(ps_arrival_date_input[3:5])
ps_arrival_date_year = int(ps_arrival_date_input[6:])
ps_arrival_date = ps_arrival_date_month, ps_arrival_date_day, ps_arrival_date_year
ps_departure_date_input = input("Departure Date (xx/xx/xxxx): ")
ps_departure_date_month = int(ps_departure_date_input[:2])
ps_departure_date_day = int(ps_departure_date_input[3:5])
ps_departure_date_year = int(ps_departure_date_input[6:])
ps_departure_date = ps_departure_date_year, ps_departure_date_month, ps_departure_date_day
def number_of_nights():
date_one = datetime.date(ps_arrival_date_year, ps_arrival_date_month, ps_arrival_date_day)
date_two = datetime.date(ps_departure_date_year, ps_departure_date_month, ps_departure_date_day)
return (date_two - date_one).days
def ps_nightly_rate():
rate = input('Rate: ')
return rate
ps_total_nights = number_of_nights()
ps_rate = ps_nightly_rate()
ps_total_rental_fee = int(ps_total_nights) * int(ps_rate)
print([ps_guest_name, ps_total_nights, ps_rate, ps_total_rental_fee])
total_ps_rental_fee += ps_total_rental_fee
anyone_else = input('Are there anymore guests? ')
if anyone_else == 'no':
break
print('Pacific Shores Total Rental Fee: ', total_ps_rental_fee)
any_more_kkn_guests = 'yes'
total_kkn_rental_fee = 0
while any_more_kkn_guests == "yes":
kkn_guest_name = input('Kihei Kai Nani Guest Name: ')
kkn_arrival_date_input = input("Arrival Date (xx/xx/xxxx): ")
kkn_arrival_date_month = int(ps_arrival_date_input[:2])
kkn_arrival_date_day = int(ps_arrival_date_input[3:5])
kkn_arrival_date_year = int(ps_arrival_date_input[6:])
kkn_arrival_date = kkn_arrival_date_month, kkn_arrival_date_day, kkn_arrival_date_year
kkn_departure_date_input = input("Departure Date (xx/xx/xxxx): ")
kkn_departure_date_month = int(ps_departure_date_input[:2])
kkn_departure_date_day = int(ps_departure_date_input[3:5])
kkn_departure_date_year = int(ps_departure_date_input[6:])
kkn_departure_date = kkn_departure_date_year, kkn_departure_date_month, kkn_departure_date_day
def number_of_nights():
date_one = datetime.date(kkn_arrival_date_year, kkn_arrival_date_month, kkn_arrival_date_day)
date_two = datetime.date(kkn_departure_date_year, kkn_departure_date_month, kkn_departure_date_day)
return (date_two - date_one).days
def kkn_nightly_rate():
rate = input('Rate: ')
return rate
kkn_total_nights = number_of_nights()
kkn_rate = kkn_nightly_rate()
kkn_total_rental_fee = int(kkn_total_nights) * int(kkn_rate)
print([kkn_guest_name, kkn_total_nights, kkn_rate, kkn_total_rental_fee])
total_kkn_rental_fee += kkn_total_rental_fee
anyone_else = input('Are there anymore guests? ')
if anyone_else == 'no':
break
print('Kihei Kai Nani Total Rental Fee: ', total_kkn_rental_fee)
print('Total Rental Fee Amount: ', total_ps_rental_fee + total_kkn_rental_fee)
total_management_fee = (total_ps_rental_fee + total_kkn_rental_fee) * 0.10
print('Total Management Fee: ', '{0:.2f}'.format(total_management_fee))发布于 2017-08-06 11:32:43
首先,欢迎来到Python的世界,祝贺您的第一个项目!
Python有这个PEP8样式指南,它给出了Python代码的编码约定。在大多数代码中,您做得很好,但是在可读性方面还有改进的余地。
在某种程度上,您有太多的空行(3),这有点太过了。把它变成一个换行符:
def kkn_nightly_rate():
rate = input('Rate: ')
return rate
kkn_total_nights = number_of_nights()
kkn_rate = kkn_nightly_rate()
kkn_total_rental_fee = int(kkn_total_nights) * int(kkn_rate)应:
def kkn_nightly_rate():
rate = input('Rate: ')
return rate
kkn_total_nights = number_of_nights()
kkn_rate = kkn_nightly_rate()
kkn_total_rental_fee = int(kkn_total_nights) * int(kkn_rate)更重要的是,在你的进口之后有一两个新的行通常是个好主意。
常量通常在模块顶部,在导入之后被大写和定义,因此:
any_more_ps_guests = "yes"
total_ps_rental_fee = 0应:
ANY_MORE_PS_GUESTS = "yes"
TOTAL_PS_RENTAL_FEE = 0此外,您还有另外两个类似的常量,它们基本上与上面的常量完全相同(关于行为)。与其再次定义它们,不如给出上面更描述性的/一般的名称。
您不必每次都定义您的函数。您可以在while循环之外这样做,并在需要时调用它。此外,在每个循环中定义每个函数两次,这是对内存的浪费。当您调用一个函数时,您基本上只是告诉程序执行您已经定义的函数,并且已经存在了。
在软件工程中,不要重复自己(DRY)是软件开发的一个原则,目的是减少所有类型的重复。
在这两个循环中,重复使用相同的代码,这意味着您可以将其放入函数中,并在需要时调用它。
实际上,您的代码很难理解。尝试编写只做一件事的小函数。例如,这是:
ps_arrival_date_input = input("Arrival Date (xx/xx/xxxx): ")
ps_arrival_date_month = int(ps_arrival_date_input[:2])
ps_arrival_date_day = int(ps_arrival_date_input[3:5])
ps_arrival_date_year = int(ps_arrival_date_input[6:])
ps_arrival_date = ps_arrival_date_month, ps_arrival_date_day, ps_arrival_date_year可以成为:
def split_date(input_date):
return input_date.split('/')以后可以像这样使用:
arrival_date = input("Arrival Date (xx/xx/xxxx): ")
month, day, year = split_date(arrival_date)这是:
def ps_nightly_rate():
rate = input('Rate: ')
return rate可能会改写成这样:
def ps_nightly_rate():
return input('Rate: ')您的number_of_nights函数也可以重写为:
def number_of_nights(departure_day, arrival_day):
date_format = '%m/%d/%Y'
return (datetime.strptime(arrival_day, date_format) - datetime.strptime(departure_day, date_format)).days因此,代码的第一部分可能如下所示:
from datetime import datetime
GUESTS = "yes"
TOTAL_FEE = 0
def get_user_input(name, arrival, departure, rate):
return input(name), input(arrival), input(departure), input(rate)
def number_of_nights(departure_day, arrival_day):
date_format = '%m/%d/%Y'
return (datetime.strptime(departure_day, date_format) - datetime.strptime(arrival_day, date_format)).days
while GUESTS:
guest_name, arrival_date, departure_date, rate = get_user_input(
'Pacific Shores Guest Name:',
'Arrival Date (MM/DD/YYYY):',
'Departure Date (MM/DD/YYYY):',
'Rate:'
)
ps_total_nights = number_of_nights(departure_date, arrival_date)
ps_total_rental_fee = int(ps_total_nights) * int(rate)
TOTAL_FEE += ps_total_rental_fee
anyone_else = input('Are there anymore guests? ')
if anyone_else == 'no':
break正如你所看到的,你甚至不用费心把日子、月、年分开。我相信从现在开始你会知道如何完成它(不幸的是,我得走了)。
发布于 2017-08-06 13:57:06
在代码中要注意的第一个也是最重要的事情是,如何对每个属性进行大量重复。你应该抽象化更多的东西,这样计算就写了一次,但是用了好几次。这将允许您在未来的某个地方修复bug,如果您曾经找到的话。
现在,这两个while循环和一些逻辑是完全相同的;只是属性的名称发生了变化。您还具有检索日期的重复逻辑;只有单词'Arrival'或'Departure'不同。
第一次也是非常天真的重写可能导致:
import datetime
def ask_date(kind):
date_input = input('{} Date (xx/xx/xxxx): '.format(kind))
date_month = int(date_input[:2])
date_day = int(date_input[3:5])
date_year = int(date_input[6:])
return datetime.date(date_year, date_month, date_day)
def property_rental_fee(property_name):
any_more_guests = "yes"
total_rental_fee = 0
while any_more_ps_guests == "yes":
guest_name = input('{} Guest Name: '.format(property_name))
arrival_date = ask_date('Arrival')
departure_date = ask_date('Departure')
total_nights = (departure_date - arrival_date).days
rate = input('Rate: ')
rental_fee = int(total_nights) * int(rate)
print([guest_name, total_nights, rate, rental_fee])
total_rental_fee += rental_fee
anyone_else = input('Are there anymore guests? ')
if anyone_else == 'no':
break
print(property_name, 'Total Rental Fee: ', total_rental_fee)
return total_rental_fee
total_ps_rental_fee = property_rental_fee('Pacific Shores')
total_kkn_rental_fee = property_rental_fee('Kihei Kai Nani')
print('Total Rental Fee Amount: ', total_ps_rental_fee + total_kkn_rental_fee)
total_management_fee = (total_ps_rental_fee + total_kkn_rental_fee) * 0.10
print('Total Management Fee: ', '{0:.2f}'.format(total_management_fee))从字符串中提取日期正是datetime.strptime的目的,不需要重新轮转。您还可以摆脱any_more_guests变量,因为它从未被修改过;还有其他几个清理位:
import datetime
def ask_date(kind):
date_input = input('{} Date (xx/xx/xxxx): '.format(kind))
return datetime.datetime.strptime(date_input, '%m/%d/%Y')
def property_rental_fee(property_name):
prompt = '{} Guest Name: '.format(property_name)
total_rental_fee = 0
while True:
guest_name = input(prompt)
arrival_date = ask_date('Arrival')
departure_date = ask_date('Departure')
total_nights = (departure_date - arrival_date).days
rate = int(input('Rate: '))
rental_fee = total_nights * rate
print([guest_name, total_nights, rate, rental_fee])
total_rental_fee += rental_fee
anyone_else = input('Are there anymore guests? ')
if anyone_else not in ('y', 'yes'):
break
print(property_name, 'Total Rental Fee: ', total_rental_fee)
return total_rental_fee
total_ps_rental_fee = property_rental_fee('Pacific Shores')
total_kkn_rental_fee = property_rental_fee('Kihei Kai Nani')
grand_total = total_ps_rental_fee + total_kkn_rental_fee
print('Total Rental Fee Amount: ', grand_total)
total_management_fee = grand_total * 0.10
print('Total Management Fee: {0:.2f}'.format(total_management_fee))通常的做法是不要将代码保存在文件的顶层,而是使用"main“函数。这样就可以在交互式会话或单元测试中对文件进行import,然后单独测试每个函数,而不是由各种inputs提示。您可以使用if __name__ == '__main__':子句:
import datetime
def ask_date(kind):
date_input = input('{} Date (xx/xx/xxxx): '.format(kind))
return datetime.datetime.strptime(date_input, '%m/%d/%Y')
def property_rental_fee(property_name):
prompt = '{} Guest Name: '.format(property_name)
total_rental_fee = 0
while True:
guest_name = input(prompt)
arrival_date = ask_date('Arrival')
departure_date = ask_date('Departure')
total_nights = (departure_date - arrival_date).days
rate = int(input('Rate: '))
rental_fee = total_nights * rate
print([guest_name, total_nights, rate, rental_fee])
total_rental_fee += rental_fee
anyone_else = input('Are there anymore guests? ')
if anyone_else not in ('y', 'yes'):
break
print(property_name, 'Total Rental Fee: ', total_rental_fee)
return total_rental_fee
def main():
total_ps_rental_fee = property_rental_fee('Pacific Shores')
total_kkn_rental_fee = property_rental_fee('Kihei Kai Nani')
grand_total = total_ps_rental_fee + total_kkn_rental_fee
print('Total Rental Fee Amount: ', grand_total)
total_management_fee = grand_total * 0.10
print('Total Management Fee: {0:.2f}'.format(total_management_fee))
if __name__ == '__main__':
main()您不应该盲目地依赖用户输入的任何值才是有效的。如果输入了06/31/2018的日期或199.99的速率,您的程序就会崩溃。你应该要么:
我也会简化一些要求新客人的要求:
import datetime
def ask_date(kind):
while True:
date_input = input('{} Date (xx/xx/xxxx): '.format(kind))
try:
return datetime.datetime.strptime(date_input, '%m/%d/%Y')
except ValueError as error:
print('Wrong Date:', error)
def ask_rate():
while True:
rate = input('Rate: ')
try:
return int(rate)
except ValueError as error:
print('Wrong rate:', error)
def property_rental_fee(property_name):
prompt = '{} Guest Name (leave empty if no more guests): '.format(property_name)
total_rental_fee = 0
while True:
guest_name = input(prompt)
if not guest_name:
break
arrival_date = ask_date('Arrival')
departure_date = ask_date('Departure')
rate = ask_rate()
total_nights = (departure_date - arrival_date).days
rental_fee = total_nights * rate
total_rental_fee += rental_fee
print([guest_name, total_nights, rate, rental_fee])
print(property_name, 'Total Rental Fee: ', total_rental_fee)
return total_rental_fee
def main():
total_ps_rental_fee = property_rental_fee('Pacific Shores')
total_kkn_rental_fee = property_rental_fee('Kihei Kai Nani')
grand_total = total_ps_rental_fee + total_kkn_rental_fee
print('Total Rental Fee Amount: ', grand_total)
total_management_fee = grand_total * 0.10
print('Total Management Fee: {0:.2f}'.format(total_management_fee))
if __name__ == '__main__':
main()我要更改的最后一点是通过代码中的单个更改添加新属性的能力。我将使用可变参数数对main函数进行迭代,而不是在每个属性中使用一个变量:
import datetime
def ask_date(kind):
while True:
date_input = input('{} Date (xx/xx/xxxx): '.format(kind))
try:
return datetime.datetime.strptime(date_input, '%m/%d/%Y')
except ValueError as error:
print('Wrong Date:', error)
def ask_rate():
while True:
rate = input('Rate: ')
try:
return int(rate)
except ValueError as error:
print('Wrong rate:', error)
def property_rental_fee(property_name):
prompt = '{} Guest Name (leave empty if no more guests): '.format(property_name)
total_rental_fee = 0
while True:
guest_name = input(prompt)
if not guest_name:
break
arrival_date = ask_date('Arrival')
departure_date = ask_date('Departure')
rate = ask_rate()
total_nights = (departure_date - arrival_date).days
rental_fee = total_nights * rate
total_rental_fee += rental_fee
print([guest_name, total_nights, rate, rental_fee])
print(property_name, 'Total Rental Fee: ', total_rental_fee)
return total_rental_fee
def main(*properties_names):
grand_total = sum(map(property_rental_fee, properties_names))
print('Total Rental Fee Amount: ', grand_total)
total_management_fee = grand_total * 0.10
print('Total Management Fee: {0:.2f}'.format(total_management_fee))
if __name__ == '__main__':
main('Pacific Shores', 'Kihei Kai Nani')为了使它更好,您可以在混合中添加文档字符串。
https://codereview.stackexchange.com/questions/172202
复制相似问题