首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >计算物业的物业管理费总额

计算物业的物业管理费总额
EN

Code Review用户
提问于 2017-08-06 04:36:29
回答 2查看 108关注 0票数 5

我的目标是创建一个“计算器”来计算我和妻子拥有的两套度假公寓的每月物业管理费。

我的目的是接受用户输入姓名、日期和租金,并计算这两个物业的物业管理费总额。我花了一些研究,尝试和错误来得到到达和离开的日期来计算每个客人入住的总夜晚数,但是我算出来了,一切都很好,并且通过了所有我能做的测试。

基本上,以下是步骤:

  1. 输入客人姓名、到达/离开日期、租金和计算客人的租金总额
  2. 如果有更多的客人,对那些客人也这样做,如果没有,打印出第一个物业的租金总额,然后移到下一个。
  3. 执行与第一个属性相同的功能。
  4. 当没有其他客人进入时,计算这两处物业的租金总额,乘以10%,即可获得该月份的物业管理费总额。

作为一个初学者,我是超级兴奋当我完成,我所有的测试通过!然而,作为一个初学者,我相信有一些事情我可以做得更好,并将高度赞赏任何批评你想提供。

代码语言:javascript
复制
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))
EN

回答 2

Code Review用户

回答已采纳

发布于 2017-08-06 11:32:43

首先,欢迎来到Python的世界,祝贺您的第一个项目!

Style (PEP8) / Readability

Python有这个PEP8样式指南,它给出了Python代码的编码约定。在大多数代码中,您做得很好,但是在可读性方面还有改进的余地。

在某种程度上,您有太多的空行(3),这有点太过了。把它变成一个换行符:

代码语言:javascript
复制
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)

应:

代码语言:javascript
复制
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)

更重要的是,在你的进口之后有一两个新的行通常是个好主意。

常量通常在模块顶部,在导入之后被大写和定义,因此:

代码语言:javascript
复制
any_more_ps_guests = "yes"
total_ps_rental_fee = 0

应:

代码语言:javascript
复制
ANY_MORE_PS_GUESTS = "yes"
TOTAL_PS_RENTAL_FEE = 0

此外,您还有另外两个类似的常量,它们基本上与上面的常量完全相同(关于行为)。与其再次定义它们,不如给出上面更描述性的/一般的名称。

定义函数与调用函数

您不必每次都定义您的函数。您可以在while循环之外这样做,并在需要时调用它。此外,在每个循环中定义每个函数两次,这是对内存的浪费。当您调用一个函数时,您基本上只是告诉程序执行您已经定义的函数,并且已经存在了。

干的

在软件工程中,不要重复自己(DRY)是软件开发的一个原则,目的是减少所有类型的重复。

在这两个循环中,重复使用相同的代码,这意味着您可以将其放入函数中,并在需要时调用它。

实际上,您的代码很难理解。尝试编写只做一件事的小函数。例如,这是:

代码语言:javascript
复制
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

可以成为:

代码语言:javascript
复制
def split_date(input_date):
    return input_date.split('/')

以后可以像这样使用:

代码语言:javascript
复制
arrival_date = input("Arrival Date (xx/xx/xxxx): ")
month, day, year = split_date(arrival_date)

这是:

代码语言:javascript
复制
def ps_nightly_rate():
    rate = input('Rate: ')
    return rate

可能会改写成这样:

代码语言:javascript
复制
def ps_nightly_rate():
    return input('Rate: ')

您的number_of_nights函数也可以重写为:

代码语言:javascript
复制
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

因此,代码的第一部分可能如下所示:

代码语言:javascript
复制
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

正如你所看到的,你甚至不用费心把日子、月、年分开。我相信从现在开始你会知道如何完成它(不幸的是,我得走了)。

票数 4
EN

Code Review用户

发布于 2017-08-06 13:57:06

使用更好的函数

在代码中要注意的第一个也是最重要的事情是,如何对每个属性进行大量重复。你应该抽象化更多的东西,这样计算就写了一次,但是用了好几次。这将允许您在未来的某个地方修复bug,如果您曾经找到的话。

现在,这两个while循环和一些逻辑是完全相同的;只是属性的名称发生了变化。您还具有检索日期的重复逻辑;只有单词'Arrival''Departure'不同。

第一次也是非常天真的重写可能导致:

代码语言:javascript
复制
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变量,因为它从未被修改过;还有其他几个清理位:

代码语言:javascript
复制
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__':子句:

代码语言:javascript
复制
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的速率,您的程序就会崩溃。你应该要么:

  • 优雅地处理;或
  • 询问直到找到一个有效的值。

我也会简化一些要求新客人的要求:

代码语言:javascript
复制
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函数进行迭代,而不是在每个属性中使用一个变量:

代码语言:javascript
复制
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')

为了使它更好,您可以在混合中添加文档字符串

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

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

复制
相关文章

相似问题

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