I was re-reading the YDKJS yet series, specifically the Up and Going book.
I saw a practice problem and understanding it was tough.
Here:
- Write a program to calculate the total price of your phone purchase. You will keep purchasing phones (hint: loop!) until you run out of money in your bank account. You'll also buy accessories for each phone as long as your purchase amount is below your mental spending threshold.
- After you've calculated your purchase amount, add in the tax, then print out the calculated purchase amount, properly formatted.
- Finally, check the amount against your bank account balance to see if you can afford it or not.
- You should set up some constants for the "tax rate," "phone price," "accessory price," and "spending threshold," as well as a variable for your "bank account balance.""
- You should define functions for calculating the tax and for formatting the price with a "$" and rounding to two decimal places.
-
Bonus Challenge: Try to incorporate input into this program, perhaps with the
prompt(..)
covered in "Input" earlier. You may prompt the user for their bank account balance, for example. Have fun and be creative!
According to V. Anton Spraul, author of Think like a programmer, "Problems include constraints, unbreakable rules about the problem or the way in which the problem must be solved."
Every experienced programmer knows that writing code itself is the least part of solving a problem, the major part is understanding the problem well enough, and then to be able to know what syntax, or code is required to solve it. The major hurdle is to understand the problem in clear terms as the author intends, or as the problem requires.
That exactly was my issue with that practice problem.
Now let me walk you through how I understood the problem, in a step-by-step manner:
N.B: The use of var
and not let
is deliberate as I did not want to use any idea/concept beyond the practice problem level; chapter 1.
Interpretation:
I first of all note the things expected of me to purchase in the instruction:
Things to buy:
- Phones
- Accessories
const PHONE_PRICE = 10000;
const ACCESSORIES = 3000;
I then note the conditions for purchase:
Conditions for purchase:
- Continue to purchase phones until I run out of money in my bank account
- In addition, buy accessories for each phone purchase as long as my purchase amount is below my mental spending threshold
- Tax to be paid
A loop is needed here, I also need to have a mental threshold defined as well as my bank account and the requirements for the loop.
const MENTAL_THRESHOLD = 90000;
const TAX_RATE = 0.08;
var bankAcct = 100000;
var purchaseAmt = 0; // Phones only
var totalAmt = 0; // Phones + Accessories
var totalOnTax = 0; // Phones + Accessories + Tax
while (bankAcct >= purchaseAmt) {
purchaseAmt = purchaseAmt + PHONE_PRICE;
if (purchaseAmt < MENTAL_THRESHOLD) {
purchaseAmt = purchaseAmt + ACCESSORIES;
}
}
if (purchaseAmt > bankAcct) {
console.log("Cannot purchase, hustle more");
}
I then fulfil the requirements for the functions:
Functions:
function calcTax(totalAmt) {
return totalAmt * TAX_RATE;
}
function properFormat(totalAmt) {
return "$" + totalAmt.toFixed(2);
}
I then take note of tax addition, and the display of "the calculated purchase amount, properly formatted"
totalOnTax0 = purchaseAmt + calcTax(purchaseAmt);
console.log("The calculated purchase amount is: " + properFormat(purchaseAmt));
- My interpreted constraints: never overspend your bank account, and never let accessories push you past the mental threshold (buy only if the current total (phone + previous spending) is below the mental threshold.). Now I understand the instruction says to "keep purchasing phones until you run out of money in your bank account" which means to exhaust the money in the bank, however, the mental spending threshold voided that idea as it suggests that you should not go past a certain ceiling of spending; therefore do not exhaust the money in your account, right?
Joining each part together:
You would observe that I declared more variables to be used because of my interpretation of the instructions.
// constants + variables
const PHONE_PRICE = 10000;
const ACCESSORIES = 3000;
const MENTAL_THRESHOLD = 90000;
const TAX_RATE = 0.08;
var bankAcct = 100000;
var totalOnTax0 = 0; // Phones + Accessories + Tax0
var totalOnTax1 = 0;
var totalAmt = 0; // Phones + accessories
var purchaseAmt = 0;
var numOfPhones = 0;
var numOfAccessories = 0;
var totalOnPhones = 0;
var totalOnAccessories = 0;
function calcTax(totalAmt) {
return totalAmt * TAX_RATE;
}
function properFormat(totalAmt) {
return "$" + totalAmt.toFixed(2);
}
while (bankAcct >= purchaseAmt) {
purchaseAmt = purchaseAmt + PHONE_PRICE;
numOfPhones = numOfPhones + 1;
totalOnPhones = totalOnPhones + PHONE_PRICE;
if (purchaseAmt < MENTAL_THRESHOLD) {
purchaseAmt = purchaseAmt + ACCESSORIES;
numOfAccessories = numOfAccessories + 1;
totalOnAccessories = totalOnAccessories + ACCESSORIES;
}
}
if (purchaseAmt > MENTAL_THRESHOLD) {
totalAmt = purchaseAmt - (PHONE_PRICE + ACCESSORIES);
}
totalOnTax0 = purchaseAmt + calcTax(purchaseAmt);
console.log("Intended Price of purchase: " + "$" + purchaseAmt);
console.log("Total spent on phones (no accessories): " + properFormat(totalOnPhones));
console.log("Total spent on accessories (no phones): " + properFormat(totalOnAccessories));
console.log("The number of phones to be purchased are: " + numOfPhones);
console.log("The number of accessories to be purchased together with phones are: " + numOfAccessories);
console.log("Tax on purchase: " + calcTax(purchaseAmt));
console.log("The calculated purchase amount properly formatted: " + properFormat(purchaseAmt));
console.log("Total purchase on Tax: " + totalOnTax0);
console.log("Bank balance left: " + properFormat(bankAcct - purchaseAmt));
if (purchaseAmt > bankAcct) {
console.log("Cannot purchase more phones and accessories, have exceeded bank balance and have exceeded bank balance");
}
totalOnTax1 = totalAmt + calcTax(totalAmt);
console.log("...");
console.log("If price were calculated to not exceed mental spending threshold of 90,000, the intended price of purchase would be: " + "$" + (purchaseAmt - (PHONE_PRICE + ACCESSORIES)));
console.log("Tax on purchase: " + calcTax(totalAmt));
console.log("The calculated purchase amount properly formatted: " + properFormat(totalAmt));
console.log("Total purchase on Tax: " + totalOnTax1);
console.log("Bank balance left: " + properFormat(bankAcct - totalAmt));
compared to his:
const SPENDING_THRESHOLD = 200;
const TAX_RATE = 0.08;
const PHONE_PRICE = 99.99;
const ACCESSORY_PRICE = 9.99;
var bank_balance = 303.91;
var amount = 0;
function calculateTax(amount) {
return amount * TAX_RATE;
}
function formatAmount(amount) {
return "$" + amount.toFixed( 2 );
}
// keep buying phones while you still have money
while (amount < bank_balance) {
// buy a new phone!
amount = amount + PHONE_PRICE;
// can we afford the accessory?
if (amount < SPENDING_THRESHOLD) {
amount = amount + ACCESSORY_PRICE;
}
}
// don't forget to pay the government, too
amount = amount + calculateTax( amount );
console.log(
"Your purchase: " + formatAmount( amount )
);
// Your purchase: $334.76
// can you actually afford this purchase?
if (amount > bank_balance) {
console.log(
"You can't afford this purchase. :("
);
}
// You can't afford this purchase. :(
I broke the problem into explicit categories (things to buy, conditions for purchase, functions required) as it seemed like an ambiguous problem.
I expanded the variables beyond Kyle Simpson’s minimal version. This was my way of making the problem explicit in my head (separating phones vs. accessories, taxed vs. untaxed, counts vs. totals). I wanted transparency in the logic.
I treated the mental spending threshold as a hard constraint that can override the "spend until bank is empty" rule. Though it changes the original problem’s intent. I noticed the ambiguity (does “phone purchase” include accessories? how strict is the threshold?, which made it more about interpreting the problem than solving it. That’s why I think the hard part was understanding it.) and resolved it by applying a consistent rule, would that be “thinking like a programmer?”
This is me testing my own interpretation thoroughly, what do you think?
Top comments (0)