简体   繁体   English

如何使python代码更高效/更整洁

[英]How to make python code more efficient/tidy

Hey there guys/girls I was looking towards improving the code I have written as I want to make it easier to read and more comprehensive. 嘿,我想改善我编写的代码,是为了让我更容易阅读和更全面。 It is mainly the addtolist function that is taking up a lot of space but the problem is that I only know how to complete that task using that way, if somebody would be kind enough to teach me how to make it tidier. 主要是addtolist函数占用大量空间,但是问题是,如果有人会教我如何使其整洁,我只会知道如何使用该方法完成该任务。

#speedingticket.py
#Trying to make a efficient and small script that can be used to track 
# illegial drivers.
#Jason Singh, 21 February

#Modules
import time

#Variables
fine = 0
wanted_first = ["James", "Helga", "Zachary"]
wanted_last = ["Wilson" , "Norman", "Conroy "]

#Lists
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
b = [10, 11, 12, 13, 14]
c = [15, 16, 17, 18, 19]
d = [20, 21, 22, 23, 24]
e = [25, 26, 27, 28, 29]
f = [30, 31, 32, 33, 34]
g = [35, 36, 37, 38, 39]
h = [40, 41, 42, 43, 44]
i = [45]
finelist = []

#Functions
def addtolist(CarSpeed, SpeedLimit, fine):
    CarOverLimit = CarSpeed - SpeedLimit
    if CarOverLimit in a:
        fine = 30
        finelist.append(fine)
        print("$30 FINE")
    elif CarOverLimit in b:
        fine = 80
        finelist.append(fine)
        print("$80 FINE")
    elif CarOverLimit in c:
        fine = 120
        finelist.append(fine)
        print("$120 FINE")
    elif CarOverLimit in d:
        fine = 170
        finelist.append(fine)
        print("$170 FINE")
    elif CarOverLimit in e:
        fine = 230
        finelist.append(fine)
        print("$230 FINE")
    elif CarOverLimit in f:
        fine = 300
        finelist.append(fine)
        print("$300 FINE")
    elif CarOverLimit in g:
        fine = 400
        finelist.append(fine)
        print("$400 FINE")
    elif CarOverLimit in h:
        fine = 510
        finelist.append(fine)
        print("$510 FINE")
    elif CarOverLimit >= 45:
        fine = 630
        finelist.append(fine)
        print("$630 FINE")
    else:
        print("NO FINE")

def wanted(First_Name, Last_Name):
    if First_Name in wanted_first and Last_Name in wanted_last:
        print("========================================")
        print("WARNING! WARNING! WARNING!")
        print("{} {} HAS A ARREST WARRANT".format(First_Name, Last_Name))
        print("========================================")
    else:
        print("{} {} IS CLEAR\n".format(First_Name, Last_Name))

def menu():
    print("______________________\n")
    print("SPEED FINE CALCULATOR")
    print("______________________\n")
    print("1 | CALCULATE FINES")
    print("2 | TOTAL FINES")
    print("3 | EXIT\n")
    x = input("ENTER 1 | 2 | 3\n")
    return x

#Main routine that runs in loop
while True:
    task = menu()
    if task == "1":
            First_Name = input("DRIVER'S FIRST NAME: \n").upper()
            Last_Name =  input("DRIVER'S LAST NAME: \n").upper()
            SpeedLimit = int(input("ROAD SPEED LIMIT: \n"))
            CarSpeed = int(input("DRIVER'S SPEED: \n"))
            addtolist(CarSpeed, SpeedLimit, fine)
            wanted(First_Name, Last_Name)
    elif task == "2":
            if sum(finelist) == 0:
                print("NO RECORDS")
            else:
                print("TOTAL FINE: {}".format(sum(finelist)))
                time.sleep(1)
                print("TOTAL AMOUNT OF FINES: {}".format(len(finelist)))
    elif task == "3":
        exit()
    else:
        print("INPUT VALUE NOT ALLOWED")

I would restructure the table and separate the fine computation from both output and list management. 我将重组表并将精细计算与输出和列表管理分开。
Something like this: 像这样:

def compute_fine(speed, speed_limit):
    fine_limits = [(45, 630),(40, 510),(35, 400),(30, 300),(25, 230),(20, 170),(15, 120),(10, 80),(0, 30)]
    over = speed - speed_limit
    for limit, fine in fine_limits:
        if over > limit:
            return fine
    return 0


fines = []
while True:
    task = menu()
    if task == "1":
            First_Name = input("DRIVER'S FIRST NAME: \n").upper()
            Last_Name =  input("DRIVER'S LAST NAME: \n").upper()
            SpeedLimit = int(input("ROAD SPEED LIMIT: \n"))
            CarSpeed = int(input("DRIVER'S SPEED: \n"))
            fine = compute_fine(CarSpeed, SpeedLimit)
            if fine > 0:
                fines.append(fine)
                print("${} FINE".format(fine))
            else:
                print("NO FINE")
            wanted(First_Name, Last_Name)
    elif task == "2":
            if len(fines) == 0:
                print("NO RECORDS")
            else:
                print("TOTAL FINE: {}".format(sum(fines)))
                time.sleep(1)
                print("TOTAL AMOUNT OF FINES: {}".format(len(fines)))
    elif task == "3":
        exit()
    else:
        print("INPUT VALUE NOT ALLOWED")

You can get rid of all your lists and just use greater than, less than and equal to type of functions in your if statements. 您可以摆脱所有列表,而在if语句中使用大于,小于和等于函数的类型。 Since there doesn't seem to be a pattern to how the fine increases, I'm not sure what else you could do. 由于似乎没有增加罚款的方式,所以我不确定您还能做什么。

And things that aren't affected directly by the If, can go outside of the if statements. 而且不受If直接影响的事物可以超出if语句之外。 And you can substitute out our print statements. 您也可以替换我们的打印报表。 And if you absolutely need it to say "NO FINE" instead of "$0 FINE" then you can double your if statement 如果您绝对需要说“ NO FINE”而不是“ $ 0 FINE”,则可以将if语句加倍

def addtolist(CarSpeed, SpeedLimit, fine):
    CarOverLimit = CarSpeed - SpeedLimit
    if (CarOverLimit <= 0):
        print("NO FINE")
    else:
        if (CarOverLimit > 0) & (CarOverLimit < 10):
            fine = 30
        elif (CarOverLimit >= 10) & (CarOverLimit < 15):
            fine = 80
        elif (CarOverLimit >= 15) & (CarOverLimit < 20):
            fine = 120
        elif (CarOverLimit >= 20) & (CarOverLimit < 25):
            fine = 170
        elif (CarOverLimit >=25) & (CarOverLimit < 30):
            fine = 230
        elif (CarOverLimit >= 30) & (CarOverLimit < 35):
            fine = 300
        elif (CarOverLimit >= 35) & (CarOverLimit < 40):
            fine = 400
        elif (CarOverLimit >= 40) & (CarOverLimit < 45):
            fine = 510
        elif CarOverLimit >= 45:
            fine = 630
        finelist.append(fine)
        print(f"${fine} FINE")

You also don't need to print out each line, you can just put triple quotes around something to get a string over multiple lines. 您也不需要打印每一行,只需在某事上加上三引号即可在多行上获得一个字符串。 And you can use "\\n" to create a new line. 您可以使用“ \\ n”创建新行。 And as long as you have 3.6 or higher python, you can use fstring instead of format. 并且只要您拥有3.6或更高版本的python,就可以使用fstring代替format。 For example, I did it just on your wanted function 例如,我只是在您想要的功能上做到了

def wanted(First_Name, Last_Name):
    if First_Name in wanted_first and Last_Name in wanted_last:
        print(f"""========================================
        \nWARNING! WARNING! WARNING!\n{First_Name} {Last_Name} HAS A ARREST WARRANT"
         ========================================""")
    else:
        print(f"{First_Name} {Last_Name} IS CLEAR\n")

Hope that helps a little. 希望能有所帮助。

Here is an elegant dictionnary approach you could use, and after I also wrote another solution that uses many ifs like your. 这是您可以使用的一种优雅的词典方法,在我还写了另一个使用很多if的解决方案之后。

finelist = []
fine = 0
# Define in a single variable all the overspeed/fine combinations.
fines_for_each_overspeed = {"0":  0,
                            "9": 30,
                            "14": 80,
                            "19": 120,
                            "20": 170,
                            "24": 230,
                            "29": 300,
                            "34": 400,
                            "39": 510,
                            "44": 630}

def addtolist(CarSpeed, SpeedLimit):
    CarOverLimit = CarSpeed - SpeedLimit

    # Go through the dictionnary possible overspeeds until you find one that matches the car's. 
    for overspeed in fines_for_each_overspeed.keys():
        if CarOverLimit <= int(overspeed):
            break
    # Then your fine is just the value associated to the overspeed key.
    fine = fines_for_each_overspeed[overspeed]

    if fine > 0:
        print("${} FINE".format(fine))
        finelist.append(fine)
    else:
        print("NO FINE")

Now for your way. 现在按您的方式。 Your lists are not needed elsewhere so you can write them directly in the condition like if CarOverLimit in [1, 2, 3, 4, 5, 6, 7, 8, 9] . 您的列表在其他地方不需要,因此您可以像if CarOverLimit in [1, 2, 3, 4, 5, 6, 7, 8, 9]这样的条件直接将其写入。 In this particular case you are just checking numerical values so use <= directly for more clarity. 在这种情况下,您只是检查数字值,因此为了更清楚起见,直接使用<=

You can also move the finelist.append() and print at the end instead of using them on every line. 您也可以移动finelist.append()并在末尾print ,而不是在每一行上都使用它们。

finelist = []
fine = 0

#Functions
def addtolist(CarSpeed, SpeedLimit, fine):
    CarOverLimit = CarSpeed - SpeedLimit
    if 1 <= CarOverLimit <= 9:
        fine = 30
    elif 10 <= CarOverLimit <= 14:
        fine = 80
    elif 15 <= CarOverLimit <= 19:
        fine = 120
    elif 20 <= CarOverLimit <= 24:
        fine = 170
    elif 25 <= CarOverLimit <= 29:
        fine = 230
    elif 30 <= CarOverLimit <= 34:
        fine = 300
    elif 35 <= CarOverLimit <= 39:
        fine = 400
    elif 40 <= CarOverLimit <= 44:
        fine = 510
    elif 45 <= CarOverLimit:
        fine = 630

    if fine > 0:
        print("${} FINE".format(fine))
        finelist.append(fine)
    else:
        print("NO FINE")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM