Exercise: Price After Discount

Exercise 12 Very easy

Prerequisites for the exercise

  1. Python String Padding
  2. Python String Basics
  3. All previous chapters

Objective

Given a collection of prices of some items, output a table showing each price, the discount offered, and the price after the discount.

Description

You are given the following list of tuples modeling some details of a couple of items in a shopping store:

items = [(50, 30), (85, 10), (300, 15), (20, 5)]

Each tuple consists of two elements: the first is the actual price of an item in the store and the second is its discount, given as a percentage value.

Your task is to take this list and output a table showing each item's actual price, its discount and price after discount on a separate row.

Each column of this table should be of length 20 and the text within it should be left-aligned.

The headings of the table should be 'Price', 'Discount' and 'Price after discount, respectively. After the table's header, leave a blank line.

Furthermore, wherever prices are output, they should be to 2 decimal places and begin with the $ sign. For instance, if the price is 30, it should be output as '$30.00'; if the price is 50.789, it should be output as '$50.79'; and so on and so forth.

The discount should be output with a % sign at its end. For instance, if the discount is 20, the output should be '20%'.

Shown below is the required output:

Price Discount Price after discount $50.00 30% $35.00 $85.00 10% $76.50 $300.00 15% $255.00 $20.00 5% $19.00

Hints

Hint 1

Use the ljust() string method with 20 as its length parameter.

Hint 2

Use the format() string method to round a given price to 2 decimal places.

View Solution

New file

Inside the directory you created for this course on Python, create a new folder called Exercise-12-Price-After-Discount and put the .py solution files for this exercise within it.

Solution

Before beginning to code anything, let's first settle on what would be required to solve this exercise. It's always a good idea to plan things out before moving over to the code.

So we need to display a row for each item in the given list items.

What does this remind of?

Yup, you're right! We need a for loop. The loop would iterate over items, and for each of its items, execute a piece of code. This piece of code would be responsible to output a row for the given item.

But before this, we'd need to output the headings of the table — they have to be output once so likewise the corresponding code won't go inside the loop.

Let's get done with the headings, to start with:

items = [(50, 30), (85, 10), (300, 15), (20, 5)]

print('Price'.ljust(20) + 'Discount'.ljust(20) + 'Price after discount'.ljust(20))
print()

Notice how we are merely repeating 20 over here. If ever in the future, we feel the need to change this value to 25, or 30, or any other value, we'd have to manually change all the respective values. As you would agree, this is inefficient and inflexible.

A better option is to use a variable to represent the column length and use that variable instead of 20 in the string padding methods.

So, let's make this change in our code:

items = [(50, 30), (85, 10), (300, 15), (20, 5)]
col_len = 20

print('Price'.ljust(col_len) + 'Discount'.ljust(col_len) + 'Price after discount'.ljust(col_len))
print()

Moving on, the next step is to output the rest of the table. For each item in items, there has to be a row output to the shell.

The logic for this part would obviously go inside the loop.

To start with, we'll retrieve the actual price and discount of the current item in the loop in the variables price and discount, respectively and then compute the final price after applying the discount. The result will be saved inside a variable final_price:

items = [(50, 30), (85, 10), (300, 15), (20, 5)]
col_len = 20

print('Price'.ljust(col_len) + 'Discount'.ljust(col_len) + 'Price after discount'.ljust(col_len))
print()

for item in items:
    price = item[0]
    discount = item[1]
    final_price = price - (price * discount / 100)

Once done, we'll round both price and final_price to 2 decimal places (using the format() method), add the '$' sign at the start, and assign the result back to each respective variable:

items = [(50, 30), (85, 10), (300, 15), (20, 5)]
col_len = 20

print('Price'.ljust(col_len) + 'Discount'.ljust(col_len) + 'Price after discount'.ljust(col_len))
print()

for item in items:
    price = item[0]
    discount = item[1]
    final_price = price - (price * discount / 100)

    price = '$' + '{:.2f}'.format(price)
    final_price = '$' + '{:.2f}'.format(final_price)
To understand why we use the format() string method over here to round the given number to 2 decimal places, head over to Python Rounding Numbers.

Next, we'll convert discount to a string using str() and add the '%' sign at its end:

items = [(50, 30), (85, 10), (300, 15), (20, 5)]
col_len = 20

print('Price'.ljust(col_len) + 'Discount'.ljust(col_len) + 'Price after discount'.ljust(col_len))
print()

for item in items:
    price = item[0]
    discount = item[1]
    final_price = price - (price * discount / 100)

    price = '${:.2f}'.format(price)
    final_price = '${:.2f}'.format(final_price)
    discount = str(discount) + '%'

The last step is to pad each of these strings to col_len, concatenate them all and print the final string to the shell:

items = [(50, 30), (85, 10), (300, 15), (20, 5)]
col_len = 20

print('Price'.ljust(col_len) + 'Discount'.ljust(col_len) + 'Price after discount'.ljust(col_len))
print()

for item in items:
    price = item[0]
    discount = item[1]
    final_price = price - (price * discount / 100)

    price = '${:.2f}'.format(price)
    final_price = '${:.2f}'.format(final_price)
    discount = str(discount) + '%'

    print(price.ljust(col_len) + discount.ljust(col_len) + final_price.ljust(col_len))
Price Discount Price after discount $50.00 30% $35.00 $85.00 10% $76.50 $300.00 15% $255.00 $20.00 5% $19.00

This completes our exercise.