8
\$\begingroup\$

I am a beginner at coding with Python. I am excited because I wrote a program that works in JupyterLab, but I know I can make it shorter. For example, I feel I should not need to write so many boolean operators, and print statements. Also, I am not sure if the break I put at the end is ideal. Can you advise me?

Purpose: This program computes and displays information for a company that leases vehicles to its customers. The program will compute and display the amount of money charged for that customer's vehicle rental for a specified customer. The program will run until Q or q is chosen to quit. The customer has two classification codes b or d and if any other code is entered, an error should appear but the program continues to run. Also, if the ending odometer reading is less than or equal to the starting odometer reading then an error should appear but the program continues to run.

Name = str(input("Enter the customer's first and last name: "))

while True:
    ClassCode = str(input("Enter the customer's classification code (b or d) or enter q to quit: "))
    DaysRented = int(input("Enter the number of days the vehicle was rented: "))
    Start_Odometer = int(input("Enter the vehicle's six-figure odometer reading at the start of the rental period: "))
    End_Odometer = int(input("Enter the vehicle's six-figure odometer reading at the end of the rental period: "))
    if End_Odometer <= Start_Odometer:
        print()
        print("\033[1m" + "Please enter an ending odometer reading greater than the starting odometer reading")
    if ClassCode.upper() == "B" :
        DaysCost = (DaysRented * 40)
        DistanceCost = ((End_Odometer - Start_Odometer) * 0.25)        
        Bill = DaysCost + DistanceCost
        FullClassCode = "Budget"
        print()
        print('\033[4m{}\033[0m'.format('Welcome to JDB Car Rental Service'))
        print("Customer Bill (",(Name),")")
        print()
        print("\t\tClassification code is ",ClassCode,"(",FullClassCode,"):")
        print("\t\tRented the vehicle for ", DaysRented,"days")
        print("\t\tThe vehicle's odometer reading at the start of the rental period is: ",Start_Odometer)
        print("\t\tThe vehicle's odometer reading at the end of the rental period is: ",End_Odometer)
        print("\t\tThe number of miles driven during the rental period is: ",End_Odometer - Start_Odometer)
        print("\t\tTotal summary for the rental period is: ", "($",DaysCost, " for ",DaysRented," days and $", DistanceCost, " for ", End_Odometer - Start_Odometer, " miles = $",Bill,")")
    elif ClassCode.upper() == "D" and End_Odometer - Start_Odometer <= 150 :
        DaysCost = (DaysRented * 60)
        DistanceCost = 0        
        Bill = DaysCost + DistanceCost
        FullClassCode = "Daily"
        print()
        print('\033[4m{}\033[0m'.format('Welcome to JDB Car Rental Service'))
        print("Customer Bill (",(Name),")")
        print()
        print("\t\tClassification code is ",ClassCode,"(",FullClassCode,"):")
        print("\t\tRented the vehicle for ", DaysRented,"days")
        print("\t\tThe vehicle's odometer reading at the start of the rental period is: ",Start_Odometer)
        print("\t\tThe vehicle's odometer reading at the end of the rental period is: ",End_Odometer)
        print("\t\tThe number of miles driven during the rental period is: ",End_Odometer - Start_Odometer)
        print("\t\tTotal summary for the rental period is: ", "($",DaysCost, " for ",DaysRented," days and $", DistanceCost, " for ", End_Odometer - Start_Odometer, " miles = $",Bill,")")
    elif ClassCode.upper() == "D" and End_Odometer - Start_Odometer >= 150 :
        DaysCost = (DaysRented * 60)
        DistanceCost = (((End_Odometer - Start_Odometer) - 150) * 0.3)        
        Bill = DaysCost + DistanceCost
        FullClassCode = "Daily"
        print()
        print('\033[4m{}\033[0m'.format('Welcome to JDB Car Rental Service'))
        print("Customer Bill (",(Name),")")
        print()
        print("\t\tClassification code is ",ClassCode,"(",FullClassCode,"):")
        print("\t\tRented the vehicle for ", DaysRented,"days")
        print("\t\tThe vehicle's odometer reading at the start of the rental period is: ",Start_Odometer)
        print("\t\tThe vehicle's odometer reading at the end of the rental period is: ",End_Odometer)
        print("\t\tThe number of miles driven during the rental period is: ",End_Odometer - Start_Odometer)
        print("\t\tTotal summary for the rental period is: ", "($",DaysCost, " for ",DaysRented," days and $", DistanceCost, " for ", End_Odometer - Start_Odometer, " miles = $",Bill,")")
    elif ClassCode.upper() == "Q" :
        break
    elif ClassCode.upper() != "B" :
        FullClassCode = "Error"
        DaysCost = (DaysRented * 0)
        DistanceCost = (((End_Odometer - Start_Odometer) - 150) * 0)        
        Bill = DaysCost + DistanceCost
        print()
        print()
        print("\033[1m" + "Please enter b for Budget, d for Daily or q to Quit")
        print()
        print()
    elif ClassCode.upper() != "D" :
        FullClassCode = "Error"
        DaysCost = (DaysRented * 0)
        DistanceCost = (((End_Odometer - Start_Odometer) - 150) * 0)        
        Bill = DaysCost + DistanceCost
        print()
        print()
        print("\033[1m" + "Please enter b for Budget, d for Daily or q to Quit")
        print()
        print()
    elif ClassCode.upper() != "Q" :
        FullClassCode = "Error"
        DaysCost = (DaysRented * 0)
        DistanceCost = (((End_Odometer - Start_Odometer) - 150) * 0)        
        Bill = DaysCost + DistanceCost
        print()
        print()
        print("\033[1m" + "Please enter b for Budget, d for Daily or q to Quit")
        print()
        print()
    else :
        break

Author: Peter Jr

\$\endgroup\$
8
\$\begingroup\$

About print()

If you are trying to simply print a new line, you should use '\n' compared to empty print() statements.

print("Hello, World! \n\n")

The code will print Hello, World! followed by two newlines as I have printed '\n' twice.

Converting input() to different data types

By default, the data taken by input() is in the string form, or str(). This means that

name = str(input()) # is the same as name = input()

But in some situations, you might want to take an integer value like the age of someone, here you need to convert the input.

age = int(input()) # is not equal to age = input()

All good, but what if the user enters a string by mistake? We can catch this error using try and except.
Try and Except in Python

try:
    age = int(input())
except Exception:
    print("Error! Invalid input for age")
    age = None

This is a safe method, ensures that your program won't give unexpected results if the user's input is wrong

Formatting strings

Use f-strings in Python 3 to format strings in the cleanest way.

age = 14
name = "Monkey"

print(f"Hey {name}, you are {age} years old!")

This way you can add multiple variables, without making your code look strange

Logic 1

you are doing

classcode = input("prompt..")

if classcode.upper() == 'D':
   ...
if classcode.upper() == 'B':
   ...

Instead of calling .upper() for every statement, why not just do it once during input()?

classcode = input("prompt...").upper()

if classcode == 'D':
   ...
if classcode == 'B':
   ...

Logic 2

If you have EndOdometer and StartOdometer, instead of doing EndOdometer - StartOdometer every time you would need distance, make a new variable called distance and assign it to EndOdometer - StartOdometer.

Use functions

The immediate requirement for this program is the use of functions.

A function is a block of code that only runs when it is called.

You can pass data, known as parameters, into a function.

A function can return data as a result.

You need to split different tasks into respective functions so that your code is more readable to other people. Currently, there is only 1 huge segment where all the tasks take place

  • Move taking input into a separate function, wich will ask the user for the start and end odometer readings and other information
def take_input():
    ... take input, the same as previous time
    return start_odometer, end_odometer, class_code, days_rented

This way in your main loop, it would look like

start_odometer, end_odometer, class_code, days_rented = take_input()

The same applies to all other tasks, as the idea is only to split the work into separate functions.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thank you everyone for your reply. I appreciate it a lot and I am grateful for the advice because I learned a lot. \$\endgroup\$ – PJ I Oct 17 at 22:09
6
\$\begingroup\$

Variable Name

From PEP 8 -- Style Guide for Python Code

Function names should be lowercase, with words separated by underscores as necessary to improve readability.

Variable names follow the same convention as function names.

mixedCase is allowed only in contexts where that's already the prevailing style (e.g. threading.py), to retain backwards compatibility.

Variable names in your code, for example ClassCode should changed to class_code

input() Function

The input() function return string, you don't need to user str to force convert it. Here is the doc

But on the other hand, force convert to int is not safe, it might crash when user input something can't be converted to integer.

You can use try/except to prevent it, or use str.isdigit() to filter first

days_rented = input("Enter the number of days the vehicle was rented: ")

# use try/except
try:
    days_rented = int(days_rented)
except:
    # Illegal input

# use str.isdigit()

if not days_rented.isdigit():
    # Illegal input
else:
    days_rented = int(days_rented)

The if/else statement logic

Codes in elif ClassCode.upper() != "D" : elif ClassCode.upper() != "Q" : and else : will never run as
if ClassCode.upper() == "B" :
   ...
elif ClassCode.upper() != "B" :
   ...

already cover all conditions

And I guess this is also an illegal input statement, so you miss continue or break
if End_Odometer <= Start_Odometer:
        print()
        print("\033[1m" + "Please enter an ending odometer reading greater than the starting odometer reading")
In elif ClassCode.upper() != "B" part
FullClassCode = "Error"
DaysCost = (DaysRented * 0)
DistanceCost = (((End_Odometer - Start_Odometer) - 150) * 0)        
Bill = DaysCost + DistanceCost
print()
print()
print("\033[1m" + "Please enter b for Budget, d for Daily or q to Quit")
print()
print()

These variables have not be used: FullClassCode, DaysCost, DistanceCost, Bill, maybe just remove them.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ except Exception compared to except. try doing Cntl + C when using excpetion, it will catch that as an error \$\endgroup\$ – Aryan Parekh Oct 16 at 9:57
  • 4
    \$\begingroup\$ isdigit returns true for some cases generally not considered digits, and for which int raises an exception. One example is str.isdigit("²") == True. str.isdecimal does not have this problem. \$\endgroup\$ – Graipher Oct 16 at 15:42
  • \$\begingroup\$ Thank you everyone for your reply. I appreciate it a lot and I am grateful for the advice because I learned a lot. \$\endgroup\$ – PJ I Oct 17 at 22:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.