Activity 7: Hand-coding challenge
In this activity you will hand-write two small functions that work out what someone pays at a check-out counter, given the sticker price, the sales tax, and whether they have a membership card worth 10% off.
Part 1 - Hand-coding on your own
You need to write your own sheet up but can work side-by-side.
You are writing two functions. main is written for you at the bottom, and it only ever calls print_receipt.
print_receipt takes the sticker price, the tax rate, and whether the customer has a membership card. It prints the receipt below, and returns nothing.
The rule: print_receipt does no arithmetic. No multiplying, no subtracting. Every number it prints either arrived as a parameter or came back from the other function.
The other function does all of the arithmetic. You decide what to call it, what it takes, and what it hands back.
A function can only return one value, but that value can be a tuple, so it can carry several numbers back at once.
Design it so that print_receipt has everything it needs.
Example, for print_receipt(100.00, 0.08, true):
Original: $100.00
Tax: $8.00
Discount: $10.80
Total: $97.20
Start with the function that does the arithmetic, since print_receipt has to call it.
#![allow(unused)] fn main() { fn ____________(______________________) -> ____________ { // Your implementation here } }
Now print_receipt, which calls the function you just designed. Does it need a return type?
#![allow(unused)] fn main() { fn print_receipt(______________________) ________ { // Your implementation here } }
main is written for you. You do not need to change it, but just notice what it calls.
fn main() { print_receipt(100.00, 0.08, true); print_receipt(100.00, 0.08, false); print_receipt(0.02, 0.08, true); }
Things to think about:
- Did your function hand back anything
print_receiptdid not actually need? - Does it matter in what order the tax and discount are applied?
- What would happen if the sticker price were very low (like 2 cents), or negative?
Part 2 - Swap for feedback
If you worked with someone, get feedback from a different person!
When I announce, you'll swap papers with a neighbor and look at their solution. Take a minute to give them feedback including:
- Any highlights of what they did well
- Any bugs you notice
- Any style feedback
At the end, I will collect papers and pick a couple (anonymized) to show on the screen for discussion.
Solutions
One possible solution:
#![allow(unused)] fn main() { fn calculate_totals(price: f64, tax_rate: f64, has_card: bool) -> (f64, f64, f64) { let tax = price * tax_rate; let subtotal = price + tax; let discount = if has_card { subtotal * 0.1 } else { 0.0 }; let final_price = subtotal - discount; (tax, discount, final_price) } fn print_receipt(price: f64, tax_rate: f64, has_card: bool) { let (tax, discount, final_price) = calculate_totals(price, tax_rate, has_card); println!("Original: ${:.2}", price); println!("Tax: ${:.2}", tax); println!("Discount: ${:.2}", discount); println!("Total: ${:.2}", final_price); } }
print_receipt(100.00, 0.08, true) prints $100.00, $8.00, $10.80, $97.20.
This is one good answer, not the only one.
Alternatives:
- Returns the original price as a fourth value,
(price, tax, discount, total). Okay but redundant - Returns only the final price. Then
print_receipthas to work out the tax and the discount (technically violates design requirements) - Returns a subtotal as well. Harmless, but nothing on the receipt prints it
Notes:
- The tuple has to be destructured,
let (tax, discount, final_price) = ..., or reached into with.0,.1and.2 print_receipthas no return type, so it returns()- A
has_cardof false gives a discount of0.0, not a missing value. The tuple is the same shape either way - Tax then discount and discount then tax both give the same total (but different tax and discount values)
- The 2 cent case is interesting: tax is 0.0016 and discount 0.00216, so both print as 0.02. The receipt looks like it does not add up, because
{:.2}is hiding the complete values - A negative price runs but might not give sensible answers