Jump Start: Walk-a-thon Assignment

Let’s dive into Jump Start’s Walk-a-thon Assignment!

My goal?  To work with multiple hashes stored inside an array.

Primary requirements were:

  • Input
    • Earning goal for a walk-a-thon
    • Amount earned per lap completed (per person)
    • Number of laps completed for 5 people
  • Output
    • Who earned the most money
    • Total amount earned
    • Whether the earning goal was met

Optional enhancements included:

  • Money displayed with two decimal places
  • Amount by which our earning goal was either met or missed
  • Account for ties in highest earners
  • How to handle 500 walkers
  • How to let walkers earn a different amount per lap walked

Here’s my sample run:

Walkathon Sample Run

How did I write the code?  Read more to find out!

First, let’s set the stage for the rest of the program — by defining a few things…

Walkathon Code 1
Array and methods

An empty array called walkers_data sits at the top.  It will store our walkers’ names, number of laps completed, and total earnings.

Next, I defined a method called ask.  It accepts a string (called question) as an argument.  User input is assigned to variable answer.  The method returns answer so we can use it outside the method.

After that, I defined a method called linebreak.  It prints - 65 times.  (You know, like a linebreak.)

Now, we put my ask method to use…and get input from the user!

Walkathon Code 2
Collecting some user input

I call the ask method twice.  My arguments are questions (for number of participants and the earning goal), entered as strings.  The resulting answer is converted to an integer with .to_i.

These answers are assigned to variables — number_of_walkers and goal, respectively.

My cute little linebreak method makes a guest appearance for organization’s sake.

We still need to collect info for each walker, though.  So, I’m gonna bust out a handy loop, like so:

Walkathon Code 3
Collecting more input with a .times loop

A few things are going on here.  Let’s take a closer look…

Walkathon Code 3 - Loop 1
Collecting each walker’s 1) name, 2) number of laps completed, and 3) amount earned per lap

My iterator (or i) is set to 0.   The number assigned to number_of_walkers tells my .times loop how many times to run.  (It can be any number given by the user…whether 1, 5 or 500.  Sky’s the limit!)

I call my ask method three times, collecting each walker’s:

  • Name
  • Number of laps completed
  • Amount earned per lap completed

The final question allows walkers to earn different amounts of money per lap (instead of setting everyone to the same dollar amount).

In other words, Annie could be earning $2.50 per lap completed…while Karen is earning $3.00 per lap.

The value assigned to name is left as a string.  The laps value is converted to an integer with to_i.  And earned_per_lap is converted to a float with .to_f.

(I’m doing math with both laps and earned_per_lap, so they need to be numbers.  Since earned_per_lap is a dollar amount, I made it a float — aka a decimal number.)

Okay, so we collected more info from walkers.  Now it’s time for some calculations!

Walkathon Code 3 - Loop 2
Calculating amount earned

I calculate the amount earned by multiplying laps with earned_per_lap.  The resulting value is assigned to earned.

In other words…after each walker enters their info, the loop calculates how much money they earned.

Next, it prints the amount in a string.  I use '%.2f' % earned to display the number as a dollar amount with two decimal places.

Now that we’ve finished calculating everything, it’s time to store our info inside the walkers_data array.

Walkathon Code 3 - Loop 3
Storing each walker’s data as a hash inside an array

For each walker, the loop creates a hash.  The hash contains three keys: name, laps and earned.

Each key has a corresponding value.  In this case, these values are the info we’ve already stored inside name, laps and earned (separate variables from earlier in the loop).

(Note: The value assigned to earned has been converted to a float so I can display it as a proper dollar amount later.)

This completed hash is stored inside the walkers_data array.  In other words, each walker has their own hash with their respective info stored inside.

(In hindsight, I probably should have included earned_per_lap.   Even though I don’t use it again for the rest of the program, it should still have been stored somewhere.  Something to remember for the future!)

The i iterator initialized at the top makes sure that we don’t accidentally overwrite anyone’s info (by assigning it an index number that equals i).

Before the loop repeats, it increments i by 1 — so each walker can get their own index number.

Finally, some final calculations and output:

Walkathon Code 4
Calculating total earned!  Conditionals showing whether we met our goal!  Good stuff.

You know, I actually had trouble summing up everyone’s money earned.

Turns out I was accidentally feeding a dollar signs into the values being added.  (Kinda hard to add dollar strings together, since…you know, they’re not numbers.)

Once I got rid of the dollar signs, adding hash values inside arrays wasn’t that hard.

In this case, I called the .sum method on walkers_data.  I refer to each hash as h, and call h[:earned] — or, the number assigned to each hash’s :earned key.

It adds every walker’s earned amount together, giving me a sum total.  My total is assigned to the variable total_earned.

Then, we proudly display the number by printing a string…which includes our dollar amount (using '%.2f' % to display two decimals, of course).

Walkathon Code 4-1
Calculating and displaying total amount earned

Which walkers earned the most money, though?

Walkathon Code 5
Calculating who earned the most money with a .each loop

First, my linebreak method makes another guest appearance by printing a separator to the screen.

Next, I print “Highest earning walkers:”

Calling the .each method on the walkers_data array cycles through each hash (referred to as walker here).

A conditional statement nested inside the .each loop checks who earned the most (and if anyone tied).

It does this by comparing the :earned key’s value for each walker…to the single :earned key with the highest value (determined using the .max_by method).  In other words, I compare the highest :earned dollar amount to each walker’s total dollar amount raised.

If a single walker’s :earned value equals the highest dollar amount, then their name is printed to the screen.

For ordinal numbering, i is set to 1…and increments by 1 before the loop repeats.

Because we’re comparing each walker’s amount raised to a single number, we can have multiple winners.

Walkathon Sample Output 2
Allowing for ties between walkers

RAD!

Now let’s take a closer look at how I determined whether (and by how much) we met our goal…

Walkathon Code 4-2
What happens if we meet our goal?

First, I print “GOAL MET?” to the screen.  Next, I’ve got a conditional nested inside a conditional.

My conditional checks whether we made our earnings goal.  It does this by asking whether total_earned is greater than or equal to goal.

If true, it prints “Heck yes!” to the screen…and calculates the difference.  In this case, the variable difference is defined as the difference between total_earned and goal.

Walkathon Sample Output 3
We met our goal!

If our total_earned matches goal exactly, then the difference should be 0.  In that case, it should print: “We won by the skin of our teeth, with $0.00 to spare.”

Otherwise, it prints a different string and displays difference as a dollar amount with 2 decimal places.

What if we don’t meet our goal?  The rest of the conditional statement handles that:

Walkathon Code 4-3
What happens if we DON’T meet our goal?

If we don’t meet our goal, then the loop answers our question with “Nah, dog.”

The variable difference is defined as goal minus total_earned.

After that, it prints a string that displays difference as a dollar amount with 2 decimal places.

Walkathon Sample Output 4
WHOOPS

All in all, I enjoyed this assignment.  It pushed me to learn how to work with arrays populated with hashes — and made me want to use similar methods on older code I wrote.

Things I wanna improve

  • What happens if a user gives invalid input?
  • Where does earned_per_lap go after I’m done with it?

References

 

Leave a comment