Dr Seán Carroll

by Dr Seán Carroll

Lesson

Python 101 - The (very) Basics

16. Solution walkthrough

Let's start by restating the problem:

A car rental company needs a programme to calculate the pricing of its car rentals based on the following criteria:

  1. The base price per day: $50

  2. Additional fees:

  • For each 100 miles driven: $20
  • For each day the car is rented on the weekend (Saturday or Sunday): $10
  1. Discounts:
  • For rentals lasting 7 or more days: 15% off the total price
  • For rentals with more than 500 miles driven: 10% off the total price

The company wants the programme to take the following inputs:

  • The number of days the car is rented.
  • The total miles driven during the rental period.
  • The start day of the rental (Monday, Tuesday, Wednesday, etc.).

The script should calculate the total price of the rental, applying any applicable additional fees and discounts, and output the final price.

Solution


Like any problem, it gets considerably easier if you break it down into smaller pieces. In this case, we can break it down into the following steps:

  1. Calculate the base price of the rental based on the number of days rented.

  2. Calculate the additional fees based on the number of days rented, total miles driven, and the start day of the rental.

  3. Calculate the total discount based on the number of days rented and total miles driven.

  4. Calculate the final rental price by adding the base price and additional fees, and then subtracting the total discount.

We could write our solution as one long sequence of instructions, but it’s much easier to read and debug if we break it down into smaller functions. So that’s the approach we’ll take here.

Step 1: Calculate the base price

We'll start by defining a function that calculates the base price of the rental based on the number of days rented and the base rate. We'll pass the base_rate as a parameter for extra flexibility but give it a default value of $50. The function should return the base price.

def calculate_base_price(days_rented, base_rate=50):
    return days_rented * base_rate

Remember, all we've done so far is define the function. We haven't actually called it yet - that will come later.

Step 2: Calculate Additional Fees

Next, we define a function to calculate_additional_fees that calculates the additional fees based on the

  • number of days rented,
  • total miles driven,
  • start day of the rental.
#Define a list to hold the days of the week as strings
DAYS_OF_WEEK = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
def calculate_additional_fees(days_rented, miles_driven, start_day):
    # Calculate miles driven fee
    miles_fee = (miles_driven / 100) * 20

    '''
    Calculate weekend fee...how many weekend days fall within the rental period?

    1. Get the index of the start day in the DAYS_OF_WEEK list
    2. Loop through the number of days rented
    3. Get the day of the week for the current day (in the loop)
    4. If the day is Saturday or Sunday, add 1 to the weekend_days counter
    5. Move to the next day and reset to the first day of the week if the current day index is greater than 6
    '''

    weekend_days = 0
    current_day_index = DAYS_OF_WEEK.index(start_day)

    print(f'The start day is {start_day} and the index is {current_day_index}')
    print('')

    for i in range(days_rented):
        rental_day = DAYS_OF_WEEK[current_day_index]
        print(f'{rental_day}, index: {current_day_index}')

        if rental_day in ["Saturday", "Sunday"]:
            weekend_days += 1

        # Move to the next day and reset to the first day of the week if needed
        current_day_index += 1
        if current_day_index > 6:
            current_day_index = 0

    print('')
    print(f'weekend_days: {weekend_days}')
    weekend_fee = weekend_days * 10
    print(f"Miles fee: {miles_fee}")
    print(f"Weekend fee: {weekend_fee}")

    return miles_fee + weekend_fee
    ```

```python
#Testing the function
calculate_additional_fees(5, 120, "Wednesday")

This yields the following output:

The start day is Wednesday and the index is 2

Wednesday, index: 2
Thursday, index: 3
Friday, index: 4
Saturday, index: 5
Sunday, index: 6

weekend_days: 2
Miles fee: 24.0
Weekend fee: 20
44.0

Step 3: Calculate the total discount

Now, we define a function calculate_discounts that calculates the total discount based on the number of days rented, total miles driven, and the current total price (before applying discounts).

def calculate_discounts(days_rented, miles_driven, total_price):
  discount = 0

  if days_rented >= 7:
      discount += 0.15 * total_price

  if miles_driven > 500:
      discount += 0.10 * total_price

  return discount

In this function, we check if the rental duration is 7 or more days, and if so, apply a 15% discount to the total price. Similarly, we check if the total miles driven are more than 500 and, if so, apply a 10% discount to the total price.

Step 4: Calculate the Final Rental Price

Our last function, calculate_rental_price, takes the number of days rented, total miles driven, and the start day of the rental as input. It calculates the base price, additional fees, and discounts, and returns the final rental price. This parent function will call the other three functions we've already defined.

def calculate_rental_price(days_rented, miles_driven, start_day):
    base_price = calculate_base_price(days_rented)
    additional_fees = calculate_additional_fees(days_rented, miles_driven, start_day)
    total_price = base_price + additional_fees
    discounts = calculate_discounts(days_rented, miles_driven, total_price)

    return total_price - discounts

Bringing it all together

Now all we need to do is call the calculate_rental_price function with the appropriate inputs. We'll store the result in a variable called total_price.

#Define the input paramaters
days_rented = 15
miles_driven = 3000
start_day = "Tuesday"

total_price = calculate_rental_price(days_rented, miles_driven, start_day)

# Output the results
print('-------------------------')
print(f"Total Rental Price: ${total_price:.2f}")

The output is as follows:

The start day is Tuesday and the index is 1

Tuesday, index: 1
Wednesday, index: 2
Thursday, index: 3
Friday, index: 4
Saturday, index: 5
Sunday, index: 6
Monday, index: 0
Tuesday, index: 1
Wednesday, index: 2
Thursday, index: 3
Friday, index: 4
Saturday, index: 5
Sunday, index: 6
Monday, index: 0
Tuesday, index: 1

weekend_days: 4
-------------------------
Total Rental Price: $1042.50

Wrapping up

Hopefully now you can see how all of the building blocks we've covered in this section can come together and allow you to write more useful and powerful scripts.

Our car rental pricing example is a little contrived, but it nevertheless demonstrates how we can write code that captures non-trivial logic and processes inputs according to the rules we've defined.

Also remember, when it comes to coding, no matter how complex a problem seems at first, it can always be broken down into smaller pieces. The trick is to keep breaking it down into smaller and smaller sub-problems until you can solve each one individually - just like we did with this exercise.

At this point we have the fundamentals of basic Python covered. In the next and final lesson in this section we'll touch on one more important programming paradigm: Object Oriented Programming (OOP). This is a powerful programming paradigm that allows us to structure our code in a logical and compartmentalised fashion.