Exercise: Price After Discount

Exercise 14 Easy

Prerequisites for the exercise

  1. PHP Format Strings
  2. 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 array, modeling the pricing of a couple of items in a shopping store:

<?php

$items = [[50, 30], [85, 10], [300, 15], [20, 5]];

Each item of this array is an array itself, consisting of two elements: the first is the actual price of the item (in $) in the store (without a discount) and the second is its discount, given as a percentage value.

For instance, [50, 30] means that the actual price of the item is $50 while the discount is 30%. If we compute the price after applying the discount, it turns out to be $35.

In this exercise, your job is to output a table (in the terminal) using this array, showing each item's actual price, its discount, and price after discount.

Here are a couple of things to abide by:

  • Each column should be of length 20, with a space in between, 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 row, 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 for the $items array shown above:

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 printf() function in order to output the table in the correct format.

View Solution

New file

Inside the directory you created for this course on PHP, create a new folder called Exercise-14-Price-After-Discount and put the .php 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 array $items.

Alright, but what does this remind of?

Yup, you're right! We need a for loop. The loop would iterate over $items, and for each of them, 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 header of the table — it has to be output once so likewise the corresponding code won't go inside the loop.

Here's the code for laying out the table's header:

<?php

$items = [[50, 30], [85, 10], [300, 15], [20, 5]];

printf("%-20s %-20s %-20s\n\n", 'Price', 'Discount', 'Price after discount');

%-20s means that the corresponding value is a string which should be padded to a width of 20 and left-aligned. The two \n characters are used to put the blank line after the header.

Besides this, 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.

An arguably better approach is to use a variable to represent the column length and then use that variable instead of 20 in the format string via interpolation.

So, let's make this change in our code and also neatly structure the printf() call:

<?php

$items = [[50, 30], [85, 10], [300, 15], [20, 5]];
$col_len = 20;

printf(
   "%-{$col_len}s %-{$col_len}s %-{$col_len}s\n\n",
   'Price',
   'Discount',
   'Price after discount'
);

Much better.

Moving on, the next step is to output the rest of the table. As stated before, this requires us to iterate over $items and process each item therein.

Let's set up the basic structure of the loop:

<?php

$items = [[50, 30], [85, 10], [300, 15], [20, 5]];
$col_len = 20;

printf(
   "%-{$col_len}s %-{$col_len}s %-{$col_len}s\n\n",
   'Price',
   'Discount',
   'Price after discount'
);

for ($i = 0; $i < count($items); $i++) {
// Code to go here.
}

To start with, we'll retrieve the actual price and discount of the current item in the loop and store it in the variables $price and $discount, respectively. After this, we'll compute the final price after applying the discount and store the result in $final_price:

<?php

$items = [[50, 30], [85, 10], [300, 15], [20, 5]];
$col_len = 20;

printf(
   "%-{$col_len}s %-{$col_len}s %-{$col_len}s\n\n",
   'Price',
   'Discount',
   'Price after discount'
);

for ($i = 0; $i < count($items); $i++) {
   $price = $items[$i][0];
   $discount = $items[$i][1];
   $final_price = $price * (1 - $discount / 100);
}

The last step is to print all these pricing details in the desired row format. But before that, let's bring each value — $price, $discount and $final_price — into the correct format.

For each variable, we'll pass it to sprintf() in order to get a string abiding by the desired format and then assign this string back to the variable.

The code below accomplishes this:

<?php

$items = [[50, 30], [85, 10], [300, 15], [20, 5]];
$col_len = 20;

printf(
   "%-{$col_len}s %-{$col_len}s %-{$col_len}s\n\n",
   'Price',
   'Discount',
   'Price after discount'
);

for ($i = 0; $i < count($items); $i++) {
   $price = $items[$i][0];
   $discount = $items[$i][1];
   $final_price = $price * (1 - $discount / 100);

$price = sprintf('$%.2f', $price);
$discount = sprintf('%d%%', $discount);
$final_price = sprintf('$%.2f', $final_price); }

With the values in the correct format, let's now finally print a row for them, with the help of printf():

<?php

$items = [[50, 30], [85, 10], [300, 15], [20, 5]];
$col_len = 20;

printf(
   "%-{$col_len}s %-{$col_len}s %-{$col_len}s\n\n",
   'Price',
   'Discount',
   'Price after discount'
);

for ($i = 0; $i < count($items); $i++) {
   $price = $items[$i][0];
   $discount = $items[$i][1];
   $final_price = $price * (1 - $discount / 100);

   $price = sprintf('$%.2f', $price);
   $discount = sprintf('%d%%', $discount);
   $final_price = sprintf('$%.2f', $final_price);

printf(
"%-{$col_len}s %-{$col_len}s %-{$col_len}s\n\n",
$price,
$discount,
$final_price
); }

And now, if we execute this code, we get the following 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

Voila! We have the prices all laid out nicely in tabular form.

This completes the exercise.