我应该使用数据结构而不是使用原始方法吗?

问题描述

这是我当前的基于年龄的税收计算器代码。我认为如果我在计算括号时使用数据结构,将来更新会更容易。有人能帮我理解一下吗?

while True: #Loop the whole program
    from datetime import datetime,date #Get the Age of from user input
    
    print("Please enter your date of birth (dd mm yyyy)")
    date_of_birth = datetime.strptime(input("--->"),"%d %m %Y")
    
    def calculate_age(born):
        today = date.today()
        return today.year - born.year - ((today.month,today.day) < (born.month,born.day))
    
    age = calculate_age(date_of_birth)
    
    print("You are ",int(age)," years old.")
    
    #Get the Salary from user input
    def get_salary():
        while True:
            try:
                salary = int(input("Please enter your salary: "))
            except ValueError:
                print("You need to enter a number ")
            else:
                break
        return salary
    
    #Calculate the Amount that needs to be paid,using if,elif,else
    def contribution(age):
        if age <= 35:
            tax = (salary * 0.20)
        elif 36 <= age <= 50:
            tax = (salary * 0.20)
        elif 51 <= age <= 55:
            tax = (salary * 0.185)
        elif 56 <= age <= 60:
            tax = (salary * 0.13)
        elif 61 <= age <= 65:
            tax = (salary * 0.075)
        else:
            tax = (salary * 0.05)
    
        return tax
    
    #Print the amount 
    if __name__ == "__main__": # It's as if the interpreter inserts this at the top of your module when run as the main program.
        salary = get_salary() #get salary from get_salary()
        tax = contribution(age) #calculate the tax
        print("you have to pay",tax," every month ")
    while True:
        answer = str(input("Do you need to do another calculation? (y/n): "))
        if answer in ("y","n"):
            break
        print ("invalid input.")
    if answer == "y":
        continue
    else:
        print("Thank you for using this Calculator,Goodbye")
        break

所以我假设我需要更改的代码是:

#Calculate the Amount that needs to be paid,else
def contribution(age):
    if age <= 35:
        tax = (salary * 0.20)
    elif 36 <= age <= 50:
        tax = (salary * 0.20)
    elif 51 <= age <= 55:
        tax = (salary * 0.185)
    elif 56 <= age <= 60:
        tax = (salary * 0.13)
    elif 61 <= age <= 65:
        tax = (salary * 0.075)
    else:
        tax = (salary * 0.05)

    return tax

另外,我正在努力学习,所以你能通过在代码中加入 #comments 来解释吗:) 谢谢!

解决方法

1。重写代码结构

首先,我认为大多数程序员确实喜欢将功能块放在一起,并使主要逻辑尽可能干净/简短以提高可读性。因此,像这样的“代码结构”将来可能难以维护或更新。

while True: #Loop the whole program
    from datetime import datetime,date #Get the Age of from user input
    
    def calculate_age(born): ...    
    def get_salary(): ...    
    def contribution(age): ...

    if __name__ == "__main__":
        # main logic
        ...

所以这种结构真的很奇怪,而且你在函数之间声明了很多变量(date_of_birthage)。将很难进行更新/维护。 如果我是你,我会先这样修改代码


from datetime import datetime,date #Get the Age of from user input
    
def calculate_age(born): ...    
def get_salary(): ...    
def contribution(age): ...

if __name__ == "__main__":  # It's as if the interpreter inserts this at the top of your module when run as the main program.
    program_continue = 'y'
    while program_continue.upper() in ['Y','YES']:
        print("Please enter your date of birth (dd mm yyyy)")
        date_of_birth = datetime.strptime(input("--->"),"%d %m %Y")
        age = calculate_age(date_of_birth)
        print("You are ",int(age)," years old.")
        salary = get_salary() #get salary from get_salary()
        tax = contribution(age) #calculate the tax
        print("you have to pay",tax," every month ")
        program_continue = str(input("Do you need to do another calculation? (y/n): "))
    print("Thank you for using this Calculator,Goodbye")

2.介绍数据结构?还是班级?

老实说,我不太明白“使用数据结构”是什么意思,所以我想创建一个“类”是你想要的。那么你必须考虑一些要点:

  • 这个类的属性应该是什么?多布,薪水,还有别的吗?
  • 您将来会扩展什么?名称?性别?联系信息?残障与否?

无论如何,我们现在只是创建一个带有 dob 和工资的类。

class Person(object):
    def __init__(self,dob,salary):
        """
        input dob and salary only,age and tax will be calculated then
        """
        self.dob = dob
        self.salary = salary
        self.age = self.calculate_age() 
        self.tax = self.contribution()
    
    def calculate_age(self):
        today = date.today()
        return today.year - self.dob.year - ((today.month,today.day) < (self.dob.month,self.dob.day))

    def contribution(self):
        if self.age <= 35:
            tax = (self.salary * 0.20)
        elif 36 <= self.age <= 50:
            tax = (self.salary * 0.20)
        elif 51 <= self.age <= 55:
            tax = (self.salary * 0.185)
        elif 56 <= self.age <= 60:
            tax = (self.salary * 0.13)
        elif 61 <= self.age <= 65:
            tax = (self.salary * 0.075)
        else:
            tax = (self.salary * 0.05)
        return tax

因此,一旦您在类 Person 中创建了一个变量,您就可以通过 age、{{1} 访问 salarytax.age },.salary。 请注意,我没有将函数.tax放入类中,因为它是一个“询问用户工资”的函数,与属性无关。

主要逻辑可以改写为:

get_salary()

3.未来扩张

假设我现在要添加 if __name__ == "__main__": # It's as if the interpreter inserts this at the top of your module when run as the main program. program_continue = 'y' while program_continue.upper() in ['Y',"%d %m %Y") salary = get_salary() #get salary from get_salary() ##### THESE ARE THE CHANGES START person_obj = Person(date_of_birth,salary) print("You are ",int(person_obj.age)," years old.") print("you have to pay",int(person_obj.tax)," every month ") ##### THESE ARE THE CHANGES END program_continue = str(input("Do you need to do another calculation? (y/n): ")) print("Thank you for using this Calculator,Goodbye") 作为属性。我所要做的就是修改 name 类。以后应该更容易更新。

,

您的函数相当容易维护,尤其是如果您将其重写得更简单一些:

def contribution(age):
    if age <= 35:
        rate = 0.20
    elif age <= 50:
        rate = 0.20
    elif age <= 55:
        rate = 0.185
    elif age <= 60:
        rate = 0.13
    elif age <= 65:
        rate = 0.075
    else:
        rate = 0.05

    return salary * rate

但是您担心像这样在代码中嵌入数据是正确的。所以你可以用这样的方法做得更好:

# near top or read from file:
tax_rates = [ # upper age limit for each rate
    (35,0.20),(50,(55,0.185),(60,0.13),(65,0.075),(1000,0.05)
]

# then elsewhere in the code:
def contribution(salary,age):
    for limit,rate in tax_rates:
        if age <= limit:
            return salary * rate
    else:
        # finally a good use for for ... else!
        raise ValueError(f"Age {age} is out of range.")

我还建议将您的导入语句和函数定义移到主循环之上,并将值传递给函数(例如,salary),而不是使用全局变量。这样可以更轻松地了解正在发生的事情。